Hi, Yu.
Thnaks for updating the patches while you're off.

I applied your patch with some style fixes and tried xenpm.
(I attached the fixed patch. Please confirm I didn't breake them.)
Then I got the followings. (NOTE: I added cpufreq=xen to xen boot option)
Doesn't xenpm work on ia64? Or is there another way to test them?

# xenpm 
Xen cpuidle is not enabled!
failed to get max P-state

thanks,

On Sat, Sep 27, 2008 at 10:11:29AM +0800, Yu, Ke wrote:
> This patchset add cpufreq support for ia64 platform. The logic is borrowed 
> from linux kernel and ported to xen. The common cpufreq infrastructure is 
> already in xen and works in x86 side, so this patchset reuse the common 
> infrastructure and add ia64 specific driver and cpufreq notify hypercall.
> 
> Hypervisor side:
> 1. px-xen-ipf-driver: add cpufreq ia64 driver
> 2 .px-xen-ipf-hypercall: implement ia64 cpufreq notify hypercall
> 
> Dom0 side:
> 1. px-dom0-add-ia64-hypercall.patch: add ia64 cpufreq notify hypercall
> 
> Signed-off-by:  Liu Jinsong <[EMAIL PROTECTED]>
>                 Yu Ke <[EMAIL PROTECTED]>
> 
> BTW, this patchset depends on the xen-unstable tree 
> (http://xenbits.xensource.com/staging/xen-unstable.hg) cset 18550, 18551, 
> 18552, and linux xen tree (http://xenbits.xensource.com/linux-2.6.18-xen.hg) 
> cset 681, which restructure the common cpufreq code for ia64. so ia64 tree 
> need to sync before applying this patchset.
> 
> 
> _______________________________________________
> Xen-ia64-devel mailing list
> Xen-ia64-devel@lists.xensource.com
> http://lists.xensource.com/xen-ia64-devel
> 

-- 
yamahata
[IA64] Add cpufreq ia64 driver

For IA64 Platform, add cpufreq driver for ia64 cpu, implementing
cpufreq_driver->init()/ exit()/ verify()/ target()/ get()

Signed-off-by: Yu, Ke <[EMAIL PROTECTED]>
Signed-off-by: Liu, Jinsong <[EMAIL PROTECTED]>

diff -r e82909f42732 xen/arch/ia64/xen/cpufreq/cpufreq.c
--- a/xen/arch/ia64/xen/cpufreq/cpufreq.c	Thu Oct 02 15:32:54 2008 +0900
+++ b/xen/arch/ia64/xen/cpufreq/cpufreq.c	Thu Oct 02 16:52:51 2008 +0900
@@ -1,8 +1,311 @@
+/*
+ * arch/ia64/kernel/cpufreq/acpi-cpufreq.c
+ * This file provides the ACPI based P-state support. This
+ * module works with generic cpufreq infrastructure. Most of
+ * the code is based on i386 version
+ * (arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c)
+ *
+ * Copyright (C) 2005 Intel Corp
+ *      Venkatesh Pallipadi <[EMAIL PROTECTED]>
+ *
+ * Sep 2008 - Liu Jinsong <[EMAIL PROTECTED]>
+ *      porting IPF acpi-cpufreq.c from Linux 2.6.23 to Xen hypervisor
+ */
 
+#include <xen/types.h>
 #include <xen/errno.h>
+#include <xen/delay.h>
+#include <xen/cpumask.h>
+#include <xen/sched.h>
+#include <xen/timer.h>
+#include <xen/xmalloc.h>
+#include <asm/bug.h>
+#include <asm/io.h>
+#include <asm/config.h>
+#include <asm/processor.h>
+#include <asm/percpu.h>
+#include <asm/pal.h>
 #include <acpi/acpi.h>
-#include <acpi/cpufreq/processor_perf.h>
-#include <public/platform.h>
+#include <acpi/cpufreq/cpufreq.h>
+
+static struct acpi_cpufreq_data *drv_data[NR_CPUS];
+
+static struct cpufreq_driver acpi_cpufreq_driver;
+
+static int
+processor_get_pstate (u32 *value)
+{
+	u64 pstate_index = 0;
+	s64 retval;
+
+	retval = ia64_pal_get_pstate(&pstate_index,
+			PAL_GET_PSTATE_TYPE_INSTANT);
+	*value = (u32) pstate_index;
+
+	if (retval)
+		printk("Failed to get current freq\n");
+
+	return (int)retval;
+}
+
+static unsigned int
+extract_clock (unsigned value)
+{
+	unsigned long i;
+	unsigned int cpu;
+	struct processor_performance *perf;
+
+	cpu = smp_processor_id();
+	perf = &processor_pminfo[cpu]->perf;
+
+	for (i = 0; i < perf->state_count; i++) {
+		if (value == perf->states[i].status)
+			return perf->states[i].core_frequency;
+	}
+	return perf->states[i-1].core_frequency;
+}
+
+static void
+processor_get_freq (void *data)
+{
+	unsigned int *freq = data;
+	int ret = 0;
+	u32 value = 0;
+	unsigned int clock_freq;
+
+	ret = processor_get_pstate(&value);
+	if (ret) {
+		*freq = 0;
+		return;
+	}
+
+	clock_freq = extract_clock(value);
+	*freq = (clock_freq*1000);
+	return;
+}
+
+static unsigned int
+acpi_cpufreq_get (unsigned int cpu)
+{
+	unsigned int freq;
+
+	if (!cpu_online(cpu))
+		return 0;
+
+	if (cpu == smp_processor_id())
+		processor_get_freq((void*)&freq);
+	else
+		smp_call_function_single(cpu, processor_get_freq,
+					 (void *)&freq, 0, 1);
+
+	return freq;
+}
+
+static void
+processor_set_pstate (void *data)
+{
+	u32 *value = data;
+	s64 retval;
+
+	retval = ia64_pal_set_pstate((u64)*value);
+
+	if (retval)
+		*value = 1;
+	else
+		*value = 0;
+}
+
+static int
+processor_set_freq (struct acpi_cpufreq_data *data,
+		struct cpufreq_policy *policy, int state)
+{
+	u32 value = 0;
+	unsigned int cpu = policy->cpu;
+
+	if (!cpu_online(cpu))
+		return -ENODEV;
+
+	if (state == data->acpi_data->state) {
+		if (unlikely(policy->resume)) {
+			printk(KERN_INFO
+			       "Called after resume, resetting to P%d\n",
+			       state);
+			policy->resume = 0;
+		} else {
+			printk(KERN_DEBUG"Already at target state (P%d)\n",
+			       state);
+			return 0;
+		}
+	}
+
+	value = (u32) data->acpi_data->states[state].control;
+
+	if (cpu == smp_processor_id())
+		processor_set_pstate((void *)&value);
+	else
+		smp_call_function_single(cpu, processor_set_pstate,
+				(void *)&value, 0, 1);
+
+	if (value) {
+		printk(KERN_WARNING "Transition failed\n");
+		return -ENODEV;
+	}
+
+	cpufreq_statistic_update(cpu, data->acpi_data->state, state);
+
+	data->acpi_data->state = state;
+
+	return 0;
+}
+
+static int
+acpi_cpufreq_target (struct cpufreq_policy *policy,
+		unsigned int target_freq, unsigned int relation)
+{
+	struct acpi_cpufreq_data *data = drv_data[policy->cpu];
+	unsigned int next_state = 0;
+	unsigned int result = 0;
+
+	result = cpufreq_frequency_table_target(policy,
+			data->freq_table, target_freq, relation, &next_state);
+	if (result)
+		return (result);
+
+	result = processor_set_freq(data, policy, next_state);
+
+	return (result);
+}
+
+static int
+acpi_cpufreq_verify (struct cpufreq_policy *policy)
+{
+	struct acpi_cpufreq_data *data = drv_data[policy->cpu];
+	struct processor_performance *perf =
+		&processor_pminfo[policy->cpu]->perf;
+
+	if (!policy || !data)
+		return -EINVAL;
+
+	cpufreq_verify_within_limits(policy, 0,
+			perf->states[perf->platform_limit].core_frequency * 1000);
+
+	return cpufreq_frequency_table_verify(policy, data->freq_table);
+}
+
+static int
+acpi_cpufreq_cpu_init (struct cpufreq_policy *policy)
+{
+	unsigned int i;
+	unsigned int cpu = policy->cpu;
+	unsigned int result = 0;
+	struct acpi_cpufreq_data *data;
+
+	data = xmalloc(struct acpi_cpufreq_data);
+	if (!data)
+		return -ENOMEM;
+	memset(data, 0, sizeof(struct acpi_cpufreq_data));
+
+	drv_data[cpu] = data;
+
+	data->acpi_data = &processor_pminfo[cpu]->perf;
+
+	/* capability check */
+	if (data->acpi_data->state_count <= 1) {
+		printk(KERN_WARNING "P-States\n");
+		result = -ENODEV;
+		goto err_unreg;
+	}
+
+	if ((data->acpi_data->control_register.space_id !=
+				ACPI_ADR_SPACE_FIXED_HARDWARE) ||
+			(data->acpi_data->status_register.space_id !=
+			 ACPI_ADR_SPACE_FIXED_HARDWARE)) {
+		result = -ENODEV;
+		goto err_unreg;
+	}
+
+	data->freq_table = xmalloc_array(struct cpufreq_frequency_table,
+			(data->acpi_data->state_count + 1));
+	if (!data->freq_table) {
+		result = -ENOMEM;
+		goto err_unreg;
+	}
+
+	/* detect transition latency */
+	policy->cpuinfo.transition_latency = 0;
+	for (i=0; i<data->acpi_data->state_count; i++) {
+		if ((data->acpi_data->states[i].transition_latency * 1000) >
+				policy->cpuinfo.transition_latency) {
+			policy->cpuinfo.transition_latency =
+				data->acpi_data->states[i].transition_latency * 1000;
+		}
+	}
+	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+	policy->cur = acpi_cpufreq_get(policy->cpu);
+	printk(KERN_INFO "Current freq of CPU %u is %u\n", cpu, policy->cur);
+
+	/* table init */
+	for (i = 0; i <= data->acpi_data->state_count; i++) {
+		data->freq_table[i].index = i;
+		if (i < data->acpi_data->state_count) {
+			data->freq_table[i].frequency =
+				data->acpi_data->states[i].core_frequency * 1000;
+		} else {
+			data->freq_table[i].frequency = CPUFREQ_TABLE_END;
+		}
+	}
+
+	result = cpufreq_frequency_table_cpuinfo(policy, data->freq_table);
+	if (result)
+		goto err_freqfree;
+
+	data->acpi_data->state = 0;
+	policy->resume = 1;
+
+	return result;
+
+err_freqfree:
+	xfree(data->freq_table);
+err_unreg:
+	xfree(data);
+	drv_data[cpu] = NULL;
+
+	return result;
+}
+
+static int
+acpi_cpufreq_cpu_exit (struct cpufreq_policy *policy)
+{
+	struct acpi_cpufreq_data *data = drv_data[policy->cpu];
+
+	if (data) {
+		drv_data[policy->cpu] = NULL;
+		xfree(data->freq_table);
+		xfree(data);
+	}
+
+	return 0;
+}
+
+static struct cpufreq_driver acpi_cpufreq_driver = {
+	.verify     = acpi_cpufreq_verify,
+	.target     = acpi_cpufreq_target,
+	.get        = acpi_cpufreq_get,
+	.init       = acpi_cpufreq_cpu_init,
+	.exit       = acpi_cpufreq_cpu_exit,
+};
+
+static int __init cpufreq_driver_init(void)
+{
+	int ret = 0;
+
+	if (cpufreq_controller == FREQCTL_xen)
+		ret = cpufreq_register_driver(&acpi_cpufreq_driver);
+
+	return ret;
+}
+__initcall(cpufreq_driver_init);
 
 int get_cpu_id(u8 acpi_id)
 {
[IA64] implement ia64 cpufreq notify hypercall

This patch implement the ia64 cpufreq hypercall to get dom0 cpufreq ACPI info.

Signed-off-by: Yu Ke <[EMAIL PROTECTED]>
Signed-off-by: Liu Jinsong <[EMAIL PROTECTED]>

diff -r 9db62718c197 xen/arch/ia64/linux-xen/acpi.c
--- a/xen/arch/ia64/linux-xen/acpi.c	Thu Oct 02 16:28:57 2008 +0900
+++ b/xen/arch/ia64/linux-xen/acpi.c	Thu Oct 02 16:29:23 2008 +0900
@@ -219,6 +219,32 @@
 	return 0;
 }
 
+#ifdef XEN
+
+#define MAX_LOCAL_SAPIC 255
+static u16 ia64_acpiid_to_sapicid[ MAX_LOCAL_SAPIC ] =
+		{[0 ... MAX_LOCAL_SAPIC - 1] = 0xffff };
+
+/* acpi id to cpu id */
+int get_cpu_id(u8 acpi_id)
+{
+	int i;
+	u16 apic_id;
+
+	apic_id = ia64_acpiid_to_sapicid[acpi_id];
+	if ( apic_id == 0xffff )
+		return -EINVAL;
+
+	for ( i = 0; i < NR_CPUS; i++ )
+	{
+		if ( apic_id == ia64_cpu_to_sapicid[i] )
+			return i;
+	}
+
+	return -1;
+}
+#endif
+
 static int __init
 acpi_parse_lsapic(struct acpi_subtable_header * header, const unsigned long end)
 {
@@ -232,6 +258,10 @@
 #ifdef CONFIG_SMP
 		smp_boot_data.cpu_phys_id[available_cpus] =
 		    (lsapic->id << 8) | lsapic->eid;
+#endif
+#ifdef XEN
+        ia64_acpiid_to_sapicid[lsapic->processor_id] =
+            (lsapic->id << 8) | lsapic->eid;
 #endif
 		++available_cpus;
 	}
diff -r 9db62718c197 xen/arch/ia64/linux-xen/entry.S
--- a/xen/arch/ia64/linux-xen/entry.S	Thu Oct 02 16:28:57 2008 +0900
+++ b/xen/arch/ia64/linux-xen/entry.S	Thu Oct 02 16:29:23 2008 +0900
@@ -1524,7 +1524,7 @@
 	data8 do_ni_hypercall		/* do_set_callbacks */
 	data8 do_ni_hypercall		/* do_fpu_taskswitch *//*  5 */
 	data8 do_sched_op_compat
-	data8 do_ni_hypercall
+	data8 do_platform_op
 	data8 do_ni_hypercall		/* do_set_debugreg */
 	data8 do_ni_hypercall		/* do_get_debugreg */
 	data8 do_ni_hypercall		/* do_update_descriptor * 10 */
diff -r 9db62718c197 xen/arch/ia64/xen/Makefile
--- a/xen/arch/ia64/xen/Makefile	Thu Oct 02 16:28:57 2008 +0900
+++ b/xen/arch/ia64/xen/Makefile	Thu Oct 02 16:29:23 2008 +0900
@@ -15,6 +15,7 @@
 obj-y += fw_emul.o
 obj-y += hpsimserial.o
 obj-y += hypercall.o
+obj-y += platform_hypercall.o
 obj-y += hyperprivop.o
 obj-y += idle0_task.o
 obj-y += irq.o
diff -r 9db62718c197 xen/arch/ia64/xen/cpufreq/cpufreq.c
--- a/xen/arch/ia64/xen/cpufreq/cpufreq.c	Thu Oct 02 16:28:57 2008 +0900
+++ b/xen/arch/ia64/xen/cpufreq/cpufreq.c	Thu Oct 02 16:29:23 2008 +0900
@@ -305,20 +305,10 @@
 
 	return ret;
 }
+
 __initcall(cpufreq_driver_init);
-
-int get_cpu_id(u8 acpi_id)
-{
-    return -1;
-}
-
-int xenpf_copy_px_states(struct processor_performance *pxpt,
-                         struct xen_processor_performance *dom0_px_info)
-{
-    return -ENOSYS;
-}
 
 int cpufreq_cpu_init(unsigned int cpuid)
 {
-    return -ENOSYS;
+	return cpufreq_add_cpu(cpuid);
 }
diff -r 9db62718c197 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c	Thu Oct 02 16:28:57 2008 +0900
+++ b/xen/arch/ia64/xen/domain.c	Thu Oct 02 16:29:23 2008 +0900
@@ -2160,6 +2160,7 @@
 	snprintf(si->magic, sizeof(si->magic), "xen-3.0-ia64");
 	si->nr_pages     = max_pages;
 	si->flags = SIF_INITDOMAIN|SIF_PRIVILEGED;
+	si->flags |= (xen_processor_pmbits << 8) & SIF_PM_MASK;
 
 	printk("Dom0: 0x%lx\n", (u64)dom0);
 
diff -r 9db62718c197 xen/arch/ia64/xen/platform_hypercall.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/ia64/xen/platform_hypercall.c	Thu Oct 02 16:29:23 2008 +0900
@@ -0,0 +1,87 @@
+/******************************************************************************
+ * platform_hypercall.c
+ * 
+ * Hardware platform operations. Intended for use by domain-0 kernel.
+ * 
+ * Copyright (c) 2002-2006, K Fraser
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/lib.h>
+#include <xen/sched.h>
+#include <xen/guest_access.h>
+#include <xen/acpi.h>
+#include <public/platform.h>
+#include <acpi/cpufreq/processor_perf.h>
+
+DEFINE_SPINLOCK(xenpf_lock);
+
+extern int set_px_pminfo(uint32_t cpu, struct xen_processor_performance *perf);
+extern long set_cx_pminfo(uint32_t cpu, struct xen_processor_power *power);
+
+int xenpf_copy_px_states(struct processor_performance *pxpt,
+        struct xen_processor_performance *dom0_px_info)
+{
+    if (!pxpt || !dom0_px_info)
+        return -EINVAL;
+    return  copy_from_guest(pxpt->states, dom0_px_info->states,
+                    dom0_px_info->state_count);
+}
+
+long do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
+{
+    long ret = 0;
+    struct xen_platform_op curop, *op = &curop;
+
+    if ( !IS_PRIV(current->domain) )
+        return -EPERM;
+
+    if ( copy_from_guest(op, u_xenpf_op, 1) )
+        return -EFAULT;
+
+    if ( op->interface_version != XENPF_INTERFACE_VERSION )
+        return -EACCES;
+
+    switch ( op->cmd )
+    {
+    case XENPF_set_processor_pminfo:
+        spin_lock(&xenpf_lock);
+        switch ( op->u.set_pminfo.type )
+        {
+        case XEN_PM_PX:
+            ret = set_px_pminfo(op->u.set_pminfo.id,
+                    &op->u.set_pminfo.perf);
+            break;
+
+        case XEN_PM_CX:
+            /* Place holder for Cx */
+            ret = -ENOSYS;
+            break;
+
+        default:
+            ret = -EINVAL;
+            break;
+        }
+        spin_unlock(&xenpf_lock);
+        break;
+
+    default:
+        printk("Unknown platform hypercall op 0x%x\n", op->cmd);
+        ret = -ENOSYS;
+        break;
+    }
+
+    return ret;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
+
IA64: add ia64 cpufreq notify hypercall

This patch adds ia64 notify hypercall to pass cpufreq ACPI information to
hypervisor, and get cpufreq statistic data from hypervisor.

Signed-off-by: Yu Ke <[EMAIL PROTECTED]>
Signed-off-by: Liu Jinsong <[EMAIL PROTECTED]>

diff -r fc1b82ca1e6a arch/ia64/kernel/Makefile
--- a/arch/ia64/kernel/Makefile	Mon Sep 29 10:07:48 2008 +0100
+++ b/arch/ia64/kernel/Makefile	Thu Oct 02 16:43:42 2008 +0900
@@ -16,6 +16,9 @@
 
 ifneq ($(CONFIG_ACPI_PROCESSOR),)
 obj-y				+= acpi-processor.o
+ifneq ($(CONFIG_PROCESSOR_EXTERNAL_CONTROL),)
+obj-$(CONFIG_XEN)		+= processor_extcntl_xen.o
+endif
 endif
 
 obj-$(CONFIG_IA64_PALINFO)	+= palinfo.o
diff -r fc1b82ca1e6a arch/ia64/kernel/processor_extcntl_xen.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/ia64/kernel/processor_extcntl_xen.c	Thu Oct 02 16:43:42 2008 +0900
@@ -0,0 +1,164 @@
+/*
+ * processor_extcntl_xen.c - interface to notify Xen
+ *
+ *  Copyright (C) 2008, Intel corporation
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/acpi.h>
+#include <linux/pm.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <acpi/processor.h>
+#include <asm/hypercall.h>
+#include <asm/xen/xencomm.h>
+#include <xen/interface/platform.h>
+
+static int xen_cx_notifier(struct acpi_processor *pr, int action)
+{
+	printk(KERN_WARNING "Cx is not supported yet\n");
+
+	return -EINVAL;
+}
+
+static int xen_px_notifier(struct acpi_processor *pr, int action)
+{
+	int ret = -EINVAL;
+	xen_platform_op_t op = {
+		.cmd			= XENPF_set_processor_pminfo,
+		.interface_version	= XENPF_INTERFACE_VERSION,
+		.u.set_pminfo.id	= pr->acpi_id,
+		.u.set_pminfo.type	= XEN_PM_PX,
+	};
+	struct xen_processor_performance *perf;
+	struct xen_processor_px *states = NULL;
+	struct acpi_processor_performance *px;
+	struct acpi_psd_package *pdomain;
+	struct xencomm_handle *states_desc;
+
+	if (!pr || !pr->performance)
+		return -EINVAL;
+
+	perf = &op.u.set_pminfo.perf;
+	px = pr->performance;
+
+	switch(action) {
+		case PROCESSOR_PM_CHANGE:
+			/* ppc dynamic handle */
+			perf->flags = XEN_PX_PPC;
+			perf->platform_limit = pr->performance_platform_limit;
+
+			ret = HYPERVISOR_platform_op(&op);
+			break;
+
+		case PROCESSOR_PM_INIT:
+			/* px normal init */
+			perf->flags = XEN_PX_PPC |
+				XEN_PX_PCT |
+				XEN_PX_PSS |
+				XEN_PX_PSD;
+
+			/* ppc */
+			perf->platform_limit = pr->performance_platform_limit;
+
+			/* pct */
+			xen_convert_pct_reg(&perf->control_register,
+					    &px->control_register);
+			xen_convert_pct_reg(&perf->status_register,
+					    &px->status_register);
+
+			/* pss */
+			perf->state_count = px->state_count;
+			states = kzalloc(
+				px->state_count * sizeof(xen_processor_px_t),
+				GFP_KERNEL);
+			if (!states){
+				ret = -ENOMEM;
+				break;
+			}
+			xen_convert_pss_states(states, px->states,
+					       px->state_count);
+			set_xen_guest_handle(perf->states, states);
+			states_desc = xencomm_map_no_alloc(
+					xen_guest_handle(perf->states),
+					sizeof(*xen_guest_handle(perf->states)));
+			set_xen_guest_handle(perf->states,
+					     (xen_processor_px_t*)states_desc);
+
+			/* psd */
+			pdomain = &px->domain_info;
+			xen_convert_psd_pack(&perf->domain_info, pdomain);
+			if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL)
+				perf->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+			else if (pdomain->coord_type ==
+				 DOMAIN_COORD_TYPE_SW_ANY)
+				perf->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+			else if (pdomain->coord_type ==
+				 DOMAIN_COORD_TYPE_HW_ALL)
+				perf->shared_type = CPUFREQ_SHARED_TYPE_HW;
+			else {
+				ret = -ENODEV;
+				kfree(states);
+				break;
+			}
+
+			ret = HYPERVISOR_platform_op(&op);
+			kfree(states);
+			break;
+
+		default:
+			ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int xen_tx_notifier(struct acpi_processor *pr, int action)
+{
+	return -EINVAL;
+}
+static int xen_hotplug_notifier(struct acpi_processor *pr, int event)
+{
+	return -EINVAL;
+}
+
+static struct processor_extcntl_ops xen_extcntl_ops = {
+	.hotplug		= xen_hotplug_notifier,
+};
+
+void arch_acpi_processor_init_extcntl(const struct processor_extcntl_ops **ops)
+{
+	unsigned int pmbits = (xen_start_info->flags & SIF_PM_MASK) >> 8;
+
+	if (!pmbits)
+		return;
+
+	if (pmbits & XEN_PROCESSOR_PM_CX)
+		xen_extcntl_ops.pm_ops[PM_TYPE_IDLE] = xen_cx_notifier;
+	if (pmbits & XEN_PROCESSOR_PM_PX)
+		xen_extcntl_ops.pm_ops[PM_TYPE_PERF] = xen_px_notifier;
+	if (pmbits & XEN_PROCESSOR_PM_TX)
+		xen_extcntl_ops.pm_ops[PM_TYPE_THR] = xen_tx_notifier;
+
+	*ops = &xen_extcntl_ops;
+}
+EXPORT_SYMBOL(arch_acpi_processor_init_extcntl);
diff -r fc1b82ca1e6a arch/ia64/xen/xcom_hcall.c
--- a/arch/ia64/xen/xcom_hcall.c	Mon Sep 29 10:07:48 2008 +0100
+++ b/arch/ia64/xen/xcom_hcall.c	Thu Oct 02 16:43:42 2008 +0900
@@ -284,6 +284,15 @@
 	return xencomm_arch_hypercall_sched_op(cmd, desc);
 }
 EXPORT_SYMBOL_GPL(xencomm_hypercall_sched_op);
+
+int xencomm_hypercall_platform_op(struct xen_platform_op *arg)
+{
+	return xencomm_arch_hypercall_platform_op(
+			xencomm_map_no_alloc(arg,
+			sizeof(struct xen_platform_op))
+			);
+}
+EXPORT_SYMBOL_GPL(xencomm_hypercall_platform_op);
 
 int
 xencomm_hypercall_multicall(void *call_list, int nr_calls)
diff -r fc1b82ca1e6a arch/ia64/xen/xcom_privcmd.c
--- a/arch/ia64/xen/xcom_privcmd.c	Mon Sep 29 10:07:48 2008 +0100
+++ b/arch/ia64/xen/xcom_privcmd.c	Thu Oct 02 16:43:42 2008 +0900
@@ -193,6 +193,31 @@
 		set_xen_guest_handle(kern_op.u.physinfo.cpu_to_node,
 		                     (void *)desc);
 		break;
+
+	case XEN_SYSCTL_get_pmstat:
+		if (kern_op.u.get_pmstat.type == PMSTAT_get_pxstat) {
+			struct pm_px_stat *getpx =
+				&kern_op.u.get_pmstat.u.getpx;
+			desc = xencomm_map(
+				xen_guest_handle(getpx->trans_pt),
+				getpx->total * getpx->total *
+				sizeof(uint64_t));
+			if (xen_guest_handle(getpx->trans_pt) != NULL &&
+			    getpx->total > 0 && desc == NULL)
+				return -ENOMEM;
+
+			set_xen_guest_handle(getpx->trans_pt, (void *)desc);
+
+			desc1 = xencomm_map(xen_guest_handle(getpx->pt),
+				getpx->total * sizeof(pm_px_val_t));
+			if (xen_guest_handle(getpx->pt) != NULL &&
+			    getpx->total > 0 && desc1 == NULL)
+				return -ENOMEM;
+
+			set_xen_guest_handle(getpx->pt, (void *)desc1);
+		}
+		break;
+
 	default:
 		printk("%s: unknown sysctl cmd %d\n", __func__, kern_op.cmd);
 		return -ENOSYS;
diff -r fc1b82ca1e6a drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig	Mon Sep 29 10:07:48 2008 +0100
+++ b/drivers/acpi/Kconfig	Thu Oct 02 16:43:42 2008 +0900
@@ -370,7 +370,7 @@
 
 config PROCESSOR_EXTERNAL_CONTROL
 	bool
-	depends on X86 && XEN
+	depends on (X86 || IA64) && XEN
 	default y
 endif	# ACPI
 
diff -r fc1b82ca1e6a include/asm-ia64/hypercall.h
--- a/include/asm-ia64/hypercall.h	Mon Sep 29 10:07:48 2008 +0100
+++ b/include/asm-ia64/hypercall.h	Thu Oct 02 16:43:42 2008 +0900
@@ -437,6 +437,7 @@
 
 /* Use xencomm to do hypercalls.  */
 #define HYPERVISOR_sched_op xencomm_hypercall_sched_op
+#define HYPERVISOR_platform_op xencomm_hypercall_platform_op
 #define HYPERVISOR_event_channel_op xencomm_hypercall_event_channel_op
 #define HYPERVISOR_callback_op xencomm_hypercall_callback_op
 #define HYPERVISOR_multicall xencomm_hypercall_multicall
diff -r fc1b82ca1e6a include/asm-ia64/xen/xcom_hcall.h
--- a/include/asm-ia64/xen/xcom_hcall.h	Mon Sep 29 10:07:48 2008 +0100
+++ b/include/asm-ia64/xen/xcom_hcall.h	Thu Oct 02 16:43:42 2008 +0900
@@ -36,6 +36,8 @@
 
 extern int xencomm_hypercall_sched_op(int cmd, void *arg);
 
+extern int xencomm_hypercall_platform_op(struct xen_platform_op *arg);
+
 extern int xencomm_hypercall_multicall(void *call_list, int nr_calls);
 
 extern int xencomm_hypercall_callback_op(int cmd, void *arg);
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel

Reply via email to