ACPI: Fix broken extctnl mechanism. Fn arch_acpi_processor_init_extcntl need to be called before any acpi_processor init stuff, otherwise many special paths for xen-cpu-idle & xen-cpu-freq can't get executed. So keep arch_acpi_processor_init_extcntl call in processor_extcntl_init and call it very early, move other stuff of processor_extcntl_init into a new fn processor_extcntl_prepare. Signed-off-by: Wei Gang diff -r d25b46565529 drivers/acpi/processor_core.c --- a/drivers/acpi/processor_core.c Wed Jul 23 14:21:58 2008 +0100 +++ b/drivers/acpi/processor_core.c Fri Jul 25 19:02:25 2008 +0800 @@ -526,6 +526,7 @@ static int acpi_processor_start(struct a acpi_status status = AE_OK; struct acpi_processor *pr; + processor_extcntl_init(); pr = acpi_driver_data(device); @@ -579,7 +580,7 @@ static int acpi_processor_start(struct a acpi_processor_power_init(pr, device); - result = processor_extcntl_init(pr); + result = processor_extcntl_prepare(pr); if (result) goto end; diff -r d25b46565529 drivers/acpi/processor_extcntl.c --- a/drivers/acpi/processor_extcntl.c Wed Jul 23 14:21:58 2008 +0100 +++ b/drivers/acpi/processor_extcntl.c Fri Jul 25 19:02:25 2008 +0800 @@ -105,13 +105,28 @@ int processor_notify_external(struct acp } /* + * 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. + */ +void processor_extcntl_init(void) +{ + if (!processor_extcntl_ops) + arch_acpi_processor_init_extcntl(&processor_extcntl_ops); +} + +/* * 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 __cpuinit processor_extcntl_init(struct acpi_processor *pr) +int processor_extcntl_prepare(struct acpi_processor *pr) { /* parse cstate dependency information */ if (processor_pm_external()) @@ -120,18 +135,6 @@ int __cpuinit processor_extcntl_init(str /* Initialize performance states */ if (processor_pmperf_external()) processor_extcntl_get_performance(pr); - - /* - * 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. - */ - if (!processor_extcntl_ops) - arch_acpi_processor_init_extcntl(&processor_extcntl_ops); return 0; } diff -r d25b46565529 include/acpi/processor.h --- a/include/acpi/processor.h Wed Jul 23 14:21:58 2008 +0100 +++ b/include/acpi/processor.h Fri Jul 25 19:02:25 2008 +0800 @@ -351,7 +351,8 @@ static inline int processor_pmthr_extern extern int processor_notify_external(struct acpi_processor *pr, int event, int type); -extern int processor_extcntl_init(struct acpi_processor *pr); +extern void processor_extcntl_init(void); +extern int processor_extcntl_prepare(struct acpi_processor *pr); extern int acpi_processor_get_performance_info(struct acpi_processor *pr); extern int acpi_processor_get_psd(struct acpi_processor *pr); void arch_acpi_processor_init_extcntl(const struct processor_extcntl_ops **); @@ -365,7 +366,8 @@ static inline int processor_notify_exter { return 0; } -static inline int processor_extcntl_init(struct acpi_processor *pr) +static inline void processor_extcntl_init(void) {} +static inline int processor_extcntl_prepare(struct acpi_processor *pr) { return 0; }