23 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/types.h>
34 #include <asm/xen/hypercall.h>
36 #define DRV_NAME "xen-acpi-processor: "
38 static int no_hypercall;
48 static unsigned int nr_acpi_bits;
52 static unsigned long *acpi_ids_done;
54 static unsigned long __initdata *acpi_id_present;
56 static unsigned long __initdata *acpi_id_cst_present;
63 .u.set_pminfo.id = _pr->
acpi_id,
71 dst_cx_states = kcalloc(_pr->
power.count,
76 for (ok = 0, i = 1; i <= _pr->
power.count; i++) {
77 cx = &_pr->
power.states[
i];
81 dst_cx = &(dst_cx_states[ok++]);
85 dst_cx->
reg.bit_width = 8;
86 dst_cx->
reg.bit_offset = 0;
87 dst_cx->
reg.access_size = 1;
92 dst_cx->
reg.bit_offset = 2;
93 dst_cx->
reg.bit_width = 1;
95 dst_cx->
reg.access_size = 0;
107 kfree(dst_cx_states);
115 _pr->
flags.power_setup_done;
120 ret = HYPERVISOR_dom0_op(&op);
124 for (i = 1; i <= _pr->
power.count; i++) {
125 cx = &_pr->
power.states[
i];
131 }
else if (ret != -
EINVAL)
138 kfree(dst_cx_states);
152 dst_states = kcalloc(_pr->
performance->state_count,
158 for (i = 0; i < _pr->
performance->state_count; i++) {
217 .u.set_pminfo.id = _pr->
acpi_id,
227 xen_copy_pct_data(&(_pr->
performance->control_register),
229 xen_copy_pct_data(&(_pr->
performance->status_register),
232 dst_states = xen_copy_pss_data(_pr, dst_perf);
233 if (!IS_ERR_OR_NULL(dst_states)) {
237 if (!xen_copy_psd_data(_pr, dst_perf))
241 pr_warn(
DRV_NAME "ACPI CPU%u missing some P-state data (%x), skipping.\n",
248 ret = HYPERVISOR_dom0_op(&op);
257 pr_debug(
" %cP%d: %d MHz, %d mW, %d uS\n",
258 (i == perf->
state ?
'*' :
' '), i,
261 (
u32) perf->
states[i].transition_latency);
263 }
else if (ret != -
EINVAL)
270 if (!IS_ERR_OR_NULL(dst_states))
284 if (_pr->
flags.power)
285 err = push_cxx_to_hypervisor(_pr);
288 err |= push_pxx_to_hypervisor(_pr);
293 static unsigned int __init get_max_acpi_id(
void)
301 unsigned int i, last_cpu, max_acpi_id = 0;
306 ret = HYPERVISOR_dom0_op(&op);
312 for (i = 0; i <= last_cpu; i++) {
314 ret = HYPERVISOR_dom0_op(&op);
317 max_acpi_id =
max(info->
acpi_id, max_acpi_id);
338 unsigned long long tmp;
341 acpi_io_address pblk = 0;
352 acpi_id =
object.processor.proc_id;
353 pblk =
object.processor.pblk_address;
366 if (acpi_id > nr_acpi_bits) {
368 nr_acpi_bits, acpi_id);
375 (
unsigned long)pblk);
397 if (!acpi_id_present)
401 if (!acpi_id_cst_present) {
402 kfree(acpi_id_present);
411 if (!bitmap_equal(acpi_id_present, acpi_ids_done, nr_acpi_bits)) {
417 (
void)upload_pm_data(pr_backup);
420 kfree(acpi_id_present);
421 acpi_id_present =
NULL;
422 kfree(acpi_id_cst_present);
423 acpi_id_cst_present =
NULL;
426 static int __init check_prereq(
void)
446 #define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007
447 #define USE_HW_PSTATE 0x00000080
449 cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
450 if ((edx & USE_HW_PSTATE) != USE_HW_PSTATE)
459 static void free_acpi_perf_data(
void)
470 static
int __init xen_acpi_processor_init(
void)
474 int rc = check_prereq();
479 nr_acpi_bits = get_max_acpi_id() + 1;
485 if (!acpi_perf_data) {
487 kfree(acpi_ids_done);
491 if (!zalloc_cpumask_var_node(
525 (
void)upload_pm_data(_pr);
527 rc = check_acpi_ids(pr_backup);
544 free_acpi_perf_data();
545 kfree(acpi_ids_done);
548 static void __exit xen_acpi_processor_exit(
void)
552 kfree(acpi_ids_done);
558 free_acpi_perf_data();
562 MODULE_DESCRIPTION(
"Xen ACPI Processor P-states (and Cx) driver which uploads PM data to Xen hypervisor");