# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1209635526 -3600
# Node ID 3da869d5095b191050f1527b896d87f3afab3f27
# Parent 9f9b4214bec8c82f835b43554b798e107371749f
Add basic interface to allow ACPI processor events revealed to
external control logic like VMM.
Signed-off-by: Tian Kevin <kevin.tian@xxxxxxxxx>
Signed-off-by: Wei Gang <gang.wei@xxxxxxxxx>
---
drivers/acpi/Kconfig | 5 +
drivers/acpi/Makefile | 3 +
drivers/acpi/processor_extcntl.c | 111 +++++++++++++++++++++++++++++++++++++++
include/acpi/processor.h | 72 +++++++++++++++++++++++++
4 files changed, 191 insertions(+)
diff -r 9f9b4214bec8 -r 3da869d5095b drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig Thu May 01 10:35:30 2008 +0100
+++ b/drivers/acpi/Kconfig Thu May 01 10:52:06 2008 +0100
@@ -367,6 +367,11 @@ config ACPI_PV_SLEEP
bool
depends on X86 && XEN && ACPI_SLEEP
default y
+
+config PROCESSOR_EXTERNAL_CONTROL
+ bool
+ depends on X86 && XEN
+ default y
endif # ACPI
endmenu
diff -r 9f9b4214bec8 -r 3da869d5095b drivers/acpi/Makefile
--- a/drivers/acpi/Makefile Thu May 01 10:35:30 2008 +0100
+++ b/drivers/acpi/Makefile Thu May 01 10:52:06 2008 +0100
@@ -34,6 +34,9 @@ ifdef CONFIG_CPU_FREQ
ifdef CONFIG_CPU_FREQ
processor-objs += processor_perflib.o
endif
+ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
+processor-objs += processor_extcntl.o
+endif
obj-y += sleep/
obj-y += bus.o glue.o
diff -r 9f9b4214bec8 -r 3da869d5095b drivers/acpi/processor_extcntl.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/acpi/processor_extcntl.c Thu May 01 10:52:06 2008 +0100
@@ -0,0 +1,111 @@
+/*
+ * processor_extcntl.c - channel to external control logic
+ *
+ * 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 <acpi/processor.h>
+
+/*
+ * External processor control logic may register with its own set of
+ * ops to get ACPI related notification. One example is like VMM.
+ */
+struct processor_extcntl_ops *processor_extcntl_ops;
+
+int processor_notify_external(struct acpi_processor *pr, int event, int type)
+{
+ int ret = -EINVAL;
+
+ if (!processor_cntl_external())
+ return -EINVAL;
+
+ switch (event) {
+ case PROCESSOR_PM_INIT:
+ case PROCESSOR_PM_CHANGE:
+ if ((type >= PM_TYPE_MAX) ||
+ !processor_extcntl_ops->pm_ops[type])
+ break;
+
+ ret = processor_extcntl_ops->pm_ops[type](pr, event);
+ break;
+ case PROCESSOR_HOTPLUG:
+ if (processor_extcntl_ops->hotplug)
+ ret = processor_extcntl_ops->hotplug(pr, type);
+ break;
+ default:
+ printk(KERN_ERR "Unsupport processor events %d.\n", event);
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * External control logic can decide to grab full or part of physical
+ * processor control bits. Take a VMM for example, physical processors
+ * are owned by VMM and thus existence information like hotplug is
+ * always required to be notified to VMM. Similar is processor idle
+ * state which is also necessarily controlled by VMM. But for other
+ * control bits like performance/throttle states, VMM may choose to
+ * control or not upon its own policy.
+ *
+ * Such ownership is unlikely to be switched in the fly, and thus
+ * not sure unregister interface is required or not. Being same reason,
+ * lock is not forced now.
+ */
+int processor_register_extcntl(struct processor_extcntl_ops *ops)
+{
+ if (!ops)
+ return -EINVAL;
+
+ if (processor_extcntl_ops &&
+ (processor_extcntl_ops != ops))
+ return -EBUSY;
+
+ processor_extcntl_ops = ops;
+ return 0;
+}
+
+int processor_unregister_extcntl(struct processor_extcntl_ops *ops)
+{
+ if (processor_extcntl_ops == ops)
+ processor_extcntl_ops = NULL;
+
+ return 0;
+}
+
+/*
+ * This is called from ACPI processor init, and targeted to hold
+ * some tricky housekeeping jobs to satisfy external control model.
+ * For example, we may put dependency parse stub here for idle
+ * and performance state. Those information may be not available
+ * if splitting from dom0 control logic like cpufreq driver.
+ */
+int processor_extcntl_init(struct acpi_processor *pr)
+{
+ return 0;
+}
diff -r 9f9b4214bec8 -r 3da869d5095b include/acpi/processor.h
--- a/include/acpi/processor.h Thu May 01 10:35:30 2008 +0100
+++ b/include/acpi/processor.h Thu May 01 10:52:06 2008 +0100
@@ -275,4 +275,76 @@ static inline void acpi_thermal_cpufreq_
}
#endif
+/*
+ * Following are interfaces geared to external processor PM control
+ * logic like a VMM
+ */
+/* Events notified to external control logic */
+#define PROCESSOR_PM_INIT 1
+#define PROCESSOR_PM_CHANGE 2
+#define PROCESSOR_HOTPLUG 3
+
+/* Objects for the PM envents */
+#define PM_TYPE_IDLE 0
+#define PM_TYPE_PERF 1
+#define PM_TYPE_THR 2
+#define PM_TYPE_MAX 3
+
+/* Processor hotplug events */
+#define HOTPLUG_TYPE_ADD 0
+#define HOTPLUG_TYPE_REMOVE 1
+
+#ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
+struct processor_extcntl_ops {
+ /* Transfer processor PM events to external control logic */
+ int (*pm_ops[PM_TYPE_MAX])(struct acpi_processor *pr, int event);
+ /* Notify physical processor status to external control logic */
+ int (*hotplug)(struct acpi_processor *pr, int event);
+};
+extern struct processor_extcntl_ops *processor_extcntl_ops;
+
+static inline int processor_cntl_external(void)
+{
+ return (processor_extcntl_ops != NULL);
+}
+
+static inline int processor_pm_external(void)
+{
+ return processor_cntl_external() &&
+ (processor_extcntl_ops->pm_ops[PM_TYPE_IDLE] != NULL);
+}
+
+static inline int processor_pmperf_external(void)
+{
+ return processor_cntl_external() &&
+ (processor_extcntl_ops->pm_ops[PM_TYPE_PERF] != NULL);
+}
+
+static inline int processor_pmthr_external(void)
+{
+ return processor_cntl_external() &&
+ (processor_extcntl_ops->pm_ops[PM_TYPE_THR] != NULL);
+}
+
+extern int processor_notify_external(struct acpi_processor *pr,
+ int event, int type);
+extern int processor_register_extcntl(struct processor_extcntl_ops *ops);
+extern int processor_unregister_extcntl(struct processor_extcntl_ops *ops);
+extern int processor_extcntl_init(struct acpi_processor *pr);
+#else
+static inline int processor_cntl_external(void) {return 0;}
+static inline int processor_pm_external(void) {return 0;}
+static inline int processor_pmperf_external(void) {return 0;}
+static inline int processor_pmthr_external(void) {return 0;}
+static inline int processor_notify_external(struct acpi_processor *pr,
+ int event, int type)
+{
+ return -EINVAL;
+}
+static inline int processor_extcntl_init(struct acpi_processor *pr)
+{
+ return -EINVAL;
+}
+#endif /* CONFIG_PROCESSOR_EXTERNAL_CONTROL */
+
#endif
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|