Revert "cpuidle: Single/Global registration of idle states"
Dan Willemsen [Sun, 25 Mar 2012 20:10:52 +0000 (13:10 -0700)]
This reverts commit 46bcfad7a819bd17ac4e831b04405152d59784ab.

We aren't yet prepared to handle this commit - we need some sort of
per-cpu idle state. At least for statistics, maybe for the states
themselves (but that may be able to be handled in our driver)

Conflicts:

arch/arm/mach-omap2/cpuidle34xx.c
drivers/acpi/processor_driver.c
drivers/idle/intel_idle.c

13 files changed:
arch/arm/mach-at91/cpuidle.c
arch/arm/mach-davinci/cpuidle.c
arch/arm/mach-exynos/cpuidle.c
arch/arm/mach-kirkwood/cpuidle.c
arch/sh/kernel/cpu/shmobile/cpuidle.c
drivers/acpi/processor_idle.c
drivers/cpuidle/cpuidle.c
drivers/cpuidle/driver.c
drivers/cpuidle/governors/ladder.c
drivers/cpuidle/governors/menu.c
drivers/cpuidle/sysfs.c
include/acpi/processor.h
include/linux/cpuidle.h

index a851e6c..d76a600 100644 (file)
@@ -34,7 +34,6 @@ static struct cpuidle_driver at91_idle_driver = {
 
 /* Actual code that puts the SoC in different idle states */
 static int at91_enter_idle(struct cpuidle_device *dev,
-                       struct cpuidle_driver *drv,
                               int index)
 {
        struct timeval before, after;
@@ -66,29 +65,27 @@ static int at91_enter_idle(struct cpuidle_device *dev,
 static int at91_init_cpuidle(void)
 {
        struct cpuidle_device *device;
-       struct cpuidle_driver *driver = &at91_idle_driver;
+
+       cpuidle_register_driver(&at91_idle_driver);
 
        device = &per_cpu(at91_cpuidle_device, smp_processor_id());
        device->state_count = AT91_MAX_STATES;
-       driver->state_count = AT91_MAX_STATES;
 
        /* Wait for interrupt state */
-       driver->states[0].enter = at91_enter_idle;
-       driver->states[0].exit_latency = 1;
-       driver->states[0].target_residency = 10000;
-       driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
-       strcpy(driver->states[0].name, "WFI");
-       strcpy(driver->states[0].desc, "Wait for interrupt");
+       device->states[0].enter = at91_enter_idle;
+       device->states[0].exit_latency = 1;
+       device->states[0].target_residency = 10000;
+       device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+       strcpy(device->states[0].name, "WFI");
+       strcpy(device->states[0].desc, "Wait for interrupt");
 
        /* Wait for interrupt and RAM self refresh state */
-       driver->states[1].enter = at91_enter_idle;
-       driver->states[1].exit_latency = 10;
-       driver->states[1].target_residency = 10000;
-       driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
-       strcpy(driver->states[1].name, "RAM_SR");
-       strcpy(driver->states[1].desc, "WFI and RAM Self Refresh");
-
-       cpuidle_register_driver(&at91_idle_driver);
+       device->states[1].enter = at91_enter_idle;
+       device->states[1].exit_latency = 10;
+       device->states[1].target_residency = 10000;
+       device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+       strcpy(device->states[1].name, "RAM_SR");
+       strcpy(device->states[1].desc, "WFI and RAM Self Refresh");
 
        if (cpuidle_register_device(device)) {
                printk(KERN_ERR "at91_init_cpuidle: Failed registering\n");
index a30c7c5..8a1ffcc 100644 (file)
@@ -79,7 +79,6 @@ static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
 
 /* Actual code that puts the SoC in different idle states */
 static int davinci_enter_idle(struct cpuidle_device *dev,
-                               struct cpuidle_driver *drv,
                                                int index)
 {
        struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
@@ -111,7 +110,6 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev)
 {
        int ret;
        struct cpuidle_device *device;
-       struct cpuidle_driver *driver = &davinci_idle_driver;
        struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
 
        device = &per_cpu(davinci_cpuidle_device, smp_processor_id());
@@ -123,33 +121,32 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev)
 
        ddr2_reg_base = pdata->ddr2_ctlr_base;
 
+       ret = cpuidle_register_driver(&davinci_idle_driver);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register driver\n");
+               return ret;
+       }
+
        /* Wait for interrupt state */
-       driver->states[0].enter = davinci_enter_idle;
-       driver->states[0].exit_latency = 1;
-       driver->states[0].target_residency = 10000;
-       driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
-       strcpy(driver->states[0].name, "WFI");
-       strcpy(driver->states[0].desc, "Wait for interrupt");
+       device->states[0].enter = davinci_enter_idle;
+       device->states[0].exit_latency = 1;
+       device->states[0].target_residency = 10000;
+       device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+       strcpy(device->states[0].name, "WFI");
+       strcpy(device->states[0].desc, "Wait for interrupt");
 
        /* Wait for interrupt and DDR self refresh state */
-       driver->states[1].enter = davinci_enter_idle;
-       driver->states[1].exit_latency = 10;
-       driver->states[1].target_residency = 10000;
-       driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
-       strcpy(driver->states[1].name, "DDR SR");
-       strcpy(driver->states[1].desc, "WFI and DDR Self Refresh");
+       device->states[1].enter = davinci_enter_idle;
+       device->states[1].exit_latency = 10;
+       device->states[1].target_residency = 10000;
+       device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+       strcpy(device->states[1].name, "DDR SR");
+       strcpy(device->states[1].desc, "WFI and DDR Self Refresh");
        if (pdata->ddr2_pdown)
                davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
        cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]);
 
        device->state_count = DAVINCI_CPUIDLE_MAX_STATES;
-       driver->state_count = DAVINCI_CPUIDLE_MAX_STATES;
-
-       ret = cpuidle_register_driver(&davinci_idle_driver);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to register driver\n");
-               return ret;
-       }
 
        ret = cpuidle_register_device(device);
        if (ret) {
index 4ebb382..045cb02 100644 (file)
@@ -18,7 +18,6 @@
 #include <asm/proc-fns.h>
 
 static int exynos4_enter_idle(struct cpuidle_device *dev,
-                       struct cpuidle_driver *drv,
                              int index);
 
 static struct cpuidle_state exynos4_cpuidle_set[] = {
@@ -40,7 +39,6 @@ static struct cpuidle_driver exynos4_idle_driver = {
 };
 
 static int exynos4_enter_idle(struct cpuidle_device *dev,
-                               struct cpuidle_driver *drv,
                              int index)
 {
        struct timeval before, after;
@@ -64,23 +62,22 @@ static int __init exynos4_init_cpuidle(void)
 {
        int i, max_cpuidle_state, cpu_id;
        struct cpuidle_device *device;
-       struct cpuidle_driver *drv = &exynos4_idle_driver;
-
-       /* Setup cpuidle driver */
-       drv->state_count = (sizeof(exynos4_cpuidle_set) /
-                                      sizeof(struct cpuidle_state));
-       max_cpuidle_state = drv->state_count;
-       for (i = 0; i < max_cpuidle_state; i++) {
-               memcpy(&drv->states[i], &exynos4_cpuidle_set[i],
-                               sizeof(struct cpuidle_state));
-       }
+
        cpuidle_register_driver(&exynos4_idle_driver);
 
        for_each_cpu(cpu_id, cpu_online_mask) {
                device = &per_cpu(exynos4_cpuidle_device, cpu_id);
                device->cpu = cpu_id;
 
-               device->state_count = drv->state_count;
+               device->state_count = (sizeof(exynos4_cpuidle_set) /
+                                              sizeof(struct cpuidle_state));
+
+               max_cpuidle_state = device->state_count;
+
+               for (i = 0; i < max_cpuidle_state; i++) {
+                       memcpy(&device->states[i], &exynos4_cpuidle_set[i],
+                                       sizeof(struct cpuidle_state));
+               }
 
                if (cpuidle_register_device(device)) {
                        printk(KERN_ERR "CPUidle register device failed\n,");
index 7088180..53d6049 100644 (file)
@@ -33,7 +33,6 @@ static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device);
 
 /* Actual code that puts the SoC in different idle states */
 static int kirkwood_enter_idle(struct cpuidle_device *dev,
-                               struct cpuidle_driver *drv,
                               int index)
 {
        struct timeval before, after;
@@ -70,29 +69,28 @@ static int kirkwood_enter_idle(struct cpuidle_device *dev,
 static int kirkwood_init_cpuidle(void)
 {
        struct cpuidle_device *device;
-       struct cpuidle_driver *driver = &kirkwood_idle_driver;
+
+       cpuidle_register_driver(&kirkwood_idle_driver);
 
        device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id());
        device->state_count = KIRKWOOD_MAX_STATES;
-       driver->state_count = KIRKWOOD_MAX_STATES;
 
        /* Wait for interrupt state */
-       driver->states[0].enter = kirkwood_enter_idle;
-       driver->states[0].exit_latency = 1;
-       driver->states[0].target_residency = 10000;
-       driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
-       strcpy(driver->states[0].name, "WFI");
-       strcpy(driver->states[0].desc, "Wait for interrupt");
+       device->states[0].enter = kirkwood_enter_idle;
+       device->states[0].exit_latency = 1;
+       device->states[0].target_residency = 10000;
+       device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+       strcpy(device->states[0].name, "WFI");
+       strcpy(device->states[0].desc, "Wait for interrupt");
 
        /* Wait for interrupt and DDR self refresh state */
-       driver->states[1].enter = kirkwood_enter_idle;
-       driver->states[1].exit_latency = 10;
-       driver->states[1].target_residency = 10000;
-       driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
-       strcpy(driver->states[1].name, "DDR SR");
-       strcpy(driver->states[1].desc, "WFI and DDR Self Refresh");
+       device->states[1].enter = kirkwood_enter_idle;
+       device->states[1].exit_latency = 10;
+       device->states[1].target_residency = 10000;
+       device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+       strcpy(device->states[1].name, "DDR SR");
+       strcpy(device->states[1].desc, "WFI and DDR Self Refresh");
 
-       cpuidle_register_driver(&kirkwood_idle_driver);
        if (cpuidle_register_device(device)) {
                printk(KERN_ERR "kirkwood_init_cpuidle: Failed registering\n");
                return -EIO;
index 6d62eb4..6f2430b 100644 (file)
@@ -25,7 +25,6 @@ static unsigned long cpuidle_mode[] = {
 };
 
 static int cpuidle_sleep_enter(struct cpuidle_device *dev,
-                               struct cpuidle_driver *drv,
                                int index)
 {
        unsigned long allowed_mode = SUSP_SH_SLEEP;
@@ -65,19 +64,19 @@ static struct cpuidle_driver cpuidle_driver = {
 void sh_mobile_setup_cpuidle(void)
 {
        struct cpuidle_device *dev = &cpuidle_dev;
-       struct cpuidle_driver *drv = &cpuidle_driver;
        struct cpuidle_state *state;
        int i;
 
+       cpuidle_register_driver(&cpuidle_driver);
 
        for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
-               drv->states[i].name[0] = '\0';
-               drv->states[i].desc[0] = '\0';
+               dev->states[i].name[0] = '\0';
+               dev->states[i].desc[0] = '\0';
        }
 
        i = CPUIDLE_DRIVER_STATE_START;
 
-       state = &drv->states[i++];
+       state = &dev->states[i++];
        snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
        strncpy(state->desc, "SuperH Sleep Mode", CPUIDLE_DESC_LEN);
        state->exit_latency = 1;
@@ -87,10 +86,10 @@ void sh_mobile_setup_cpuidle(void)
        state->flags |= CPUIDLE_FLAG_TIME_VALID;
        state->enter = cpuidle_sleep_enter;
 
-       drv->safe_state_index = i-1;
+       dev->safe_state_index = i-1;
 
        if (sh_mobile_sleep_supported & SUSP_SH_SF) {
-               state = &drv->states[i++];
+               state = &dev->states[i++];
                snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
                strncpy(state->desc, "SuperH Sleep Mode [SF]",
                        CPUIDLE_DESC_LEN);
@@ -103,7 +102,7 @@ void sh_mobile_setup_cpuidle(void)
        }
 
        if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) {
-               state = &drv->states[i++];
+               state = &dev->states[i++];
                snprintf(state->name, CPUIDLE_NAME_LEN, "C3");
                strncpy(state->desc, "SuperH Mobile Standby Mode [SF]",
                        CPUIDLE_DESC_LEN);
@@ -115,10 +114,7 @@ void sh_mobile_setup_cpuidle(void)
                state->enter = cpuidle_sleep_enter;
        }
 
-       drv->state_count = i;
        dev->state_count = i;
 
-       cpuidle_register_driver(&cpuidle_driver);
-
        cpuidle_register_device(dev);
 }
index 0e8e2de..7079709 100644 (file)
@@ -732,13 +732,11 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
 /**
  * acpi_idle_enter_c1 - enters an ACPI C1 state-type
  * @dev: the target CPU
- * @drv: cpuidle driver containing cpuidle state info
  * @index: index of target state
  *
  * This is equivalent to the HALT instruction.
  */
-static int acpi_idle_enter_c1(struct cpuidle_device *dev,
-               struct cpuidle_driver *drv, int index)
+static int acpi_idle_enter_c1(struct cpuidle_device *dev, int index)
 {
        ktime_t  kt1, kt2;
        s64 idle_time;
@@ -773,11 +771,9 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
 /**
  * acpi_idle_enter_simple - enters an ACPI state without BM handling
  * @dev: the target CPU
- * @drv: cpuidle driver with cpuidle state information
  * @index: the index of suggested state
  */
-static int acpi_idle_enter_simple(struct cpuidle_device *dev,
-               struct cpuidle_driver *drv, int index)
+static int acpi_idle_enter_simple(struct cpuidle_device *dev, int index)
 {
        struct acpi_processor *pr;
        struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
@@ -850,13 +846,11 @@ static DEFINE_RAW_SPINLOCK(c3_lock);
 /**
  * acpi_idle_enter_bm - enters C3 with proper BM handling
  * @dev: the target CPU
- * @drv: cpuidle driver containing state data
  * @index: the index of suggested state
  *
  * If BM is detected, the deepest non-C3 idle state is entered instead.
  */
-static int acpi_idle_enter_bm(struct cpuidle_device *dev,
-               struct cpuidle_driver *drv, int index)
+static int acpi_idle_enter_bm(struct cpuidle_device *dev, int index)
 {
        struct acpi_processor *pr;
        struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
@@ -873,9 +867,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
                return -EINVAL;
 
        if (!cx->bm_sts_skip && acpi_idle_bm_check()) {
-               if (drv->safe_state_index >= 0) {
-                       return drv->states[drv->safe_state_index].enter(dev,
-                                               drv, drv->safe_state_index);
+               if (dev->safe_state_index >= 0) {
+                       return dev->states[dev->safe_state_index].enter(dev,
+                                               dev->safe_state_index);
                } else {
                        local_irq_disable();
                        acpi_safe_halt();
@@ -970,15 +964,14 @@ struct cpuidle_driver acpi_idle_driver = {
 };
 
 /**
- * acpi_processor_setup_cpuidle_cx - prepares and configures CPUIDLE
- * device i.e. per-cpu data
- *
+ * acpi_processor_setup_cpuidle - prepares and configures CPUIDLE
  * @pr: the ACPI processor
  */
-static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr)
+static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
 {
        int i, count = CPUIDLE_DRIVER_STATE_START;
        struct acpi_processor_cx *cx;
+       struct cpuidle_state *state;
        struct cpuidle_state_usage *state_usage;
        struct cpuidle_device *dev = &pr->power.dev;
 
@@ -990,62 +983,10 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr)
        }
 
        dev->cpu = pr->id;
-
-       if (max_cstate == 0)
-               max_cstate = 1;
-
-       for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
-               cx = &pr->power.states[i];
-               state_usage = &dev->states_usage[count];
-
-               if (!cx->valid)
-                       continue;
-
-#ifdef CONFIG_HOTPLUG_CPU
-               if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
-                   !pr->flags.has_cst &&
-                   !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
-                       continue;
-#endif
-
-               cpuidle_set_statedata(state_usage, cx);
-
-               count++;
-               if (count == CPUIDLE_STATE_MAX)
-                       break;
-       }
-
-       dev->state_count = count;
-
-       if (!count)
-               return -EINVAL;
-
-       return 0;
-}
-
-/**
- * acpi_processor_setup_cpuidle states- prepares and configures cpuidle
- * global state data i.e. idle routines
- *
- * @pr: the ACPI processor
- */
-static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
-{
-       int i, count = CPUIDLE_DRIVER_STATE_START;
-       struct acpi_processor_cx *cx;
-       struct cpuidle_state *state;
-       struct cpuidle_driver *drv = &acpi_idle_driver;
-
-       if (!pr->flags.power_setup_done)
-               return -EINVAL;
-
-       if (pr->flags.power == 0)
-               return -EINVAL;
-
-       drv->safe_state_index = -1;
+       dev->safe_state_index = -1;
        for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
-               drv->states[i].name[0] = '\0';
-               drv->states[i].desc[0] = '\0';
+               dev->states[i].name[0] = '\0';
+               dev->states[i].desc[0] = '\0';
        }
 
        if (max_cstate == 0)
@@ -1053,6 +994,8 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
 
        for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
                cx = &pr->power.states[i];
+               state = &dev->states[count];
+               state_usage = &dev->states_usage[count];
 
                if (!cx->valid)
                        continue;
@@ -1063,8 +1006,8 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
                    !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
                        continue;
 #endif
+               cpuidle_set_statedata(state_usage, cx);
 
-               state = &drv->states[count];
                snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i);
                strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN);
                state->exit_latency = cx->latency;
@@ -1077,13 +1020,13 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
                                state->flags |= CPUIDLE_FLAG_TIME_VALID;
 
                        state->enter = acpi_idle_enter_c1;
-                       drv->safe_state_index = count;
+                       dev->safe_state_index = count;
                        break;
 
                        case ACPI_STATE_C2:
                        state->flags |= CPUIDLE_FLAG_TIME_VALID;
                        state->enter = acpi_idle_enter_simple;
-                       drv->safe_state_index = count;
+                       dev->safe_state_index = count;
                        break;
 
                        case ACPI_STATE_C3:
@@ -1099,7 +1042,7 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
                        break;
        }
 
-       drv->state_count = count;
+       dev->state_count = count;
 
        if (!count)
                return -EINVAL;
@@ -1107,7 +1050,7 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
        return 0;
 }
 
-int acpi_processor_hotplug(struct acpi_processor *pr)
+int acpi_processor_cst_has_changed(struct acpi_processor *pr)
 {
        int ret = 0;
 
@@ -1128,7 +1071,7 @@ int acpi_processor_hotplug(struct acpi_processor *pr)
        cpuidle_disable_device(&pr->power.dev);
        acpi_processor_get_power_info(pr);
        if (pr->flags.power) {
-               acpi_processor_setup_cpuidle_cx(pr);
+               acpi_processor_setup_cpuidle(pr);
                ret = cpuidle_enable_device(&pr->power.dev);
        }
        cpuidle_resume_and_unlock();
@@ -1136,72 +1079,10 @@ int acpi_processor_hotplug(struct acpi_processor *pr)
        return ret;
 }
 
-int acpi_processor_cst_has_changed(struct acpi_processor *pr)
-{
-       int cpu;
-       struct acpi_processor *_pr;
-
-       if (disabled_by_idle_boot_param())
-               return 0;
-
-       if (!pr)
-               return -EINVAL;
-
-       if (nocst)
-               return -ENODEV;
-
-       if (!pr->flags.power_setup_done)
-               return -ENODEV;
-
-       /*
-        * FIXME:  Design the ACPI notification to make it once per
-        * system instead of once per-cpu.  This condition is a hack
-        * to make the code that updates C-States be called once.
-        */
-
-       if (smp_processor_id() == 0 &&
-                       cpuidle_get_driver() == &acpi_idle_driver) {
-
-               cpuidle_pause_and_lock();
-               /* Protect against cpu-hotplug */
-               get_online_cpus();
-
-               /* Disable all cpuidle devices */
-               for_each_online_cpu(cpu) {
-                       _pr = per_cpu(processors, cpu);
-                       if (!_pr || !_pr->flags.power_setup_done)
-                               continue;
-                       cpuidle_disable_device(&_pr->power.dev);
-               }
-
-               /* Populate Updated C-state information */
-               acpi_processor_setup_cpuidle_states(pr);
-
-               /* Enable all cpuidle devices */
-               for_each_online_cpu(cpu) {
-                       _pr = per_cpu(processors, cpu);
-                       if (!_pr || !_pr->flags.power_setup_done)
-                               continue;
-                       acpi_processor_get_power_info(_pr);
-                       if (_pr->flags.power) {
-                               acpi_processor_setup_cpuidle_cx(_pr);
-                               cpuidle_enable_device(&_pr->power.dev);
-                       }
-               }
-               put_online_cpus();
-               cpuidle_resume_and_unlock();
-       }
-
-       return 0;
-}
-
-static int acpi_processor_registered;
-
 int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
                              struct acpi_device *device)
 {
        acpi_status status = 0;
-       int retval;
        static int first_run;
 
        if (disabled_by_idle_boot_param())
@@ -1238,26 +1119,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
         * platforms that only support C1.
         */
        if (pr->flags.power) {
-               /* Register acpi_idle_driver if not already registered */
-               if (!acpi_processor_registered) {
-                       acpi_processor_setup_cpuidle_states(pr);
-                       retval = cpuidle_register_driver(&acpi_idle_driver);
-                       if (retval)
-                               return retval;
-                       printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n",
-                                       acpi_idle_driver.name);
-               }
-               /* Register per-cpu cpuidle_device. Cpuidle driver
-                * must already be registered before registering device
-                */
-               acpi_processor_setup_cpuidle_cx(pr);
-               retval = cpuidle_register_device(&pr->power.dev);
-               if (retval) {
-                       if (acpi_processor_registered == 0)
-                               cpuidle_unregister_driver(&acpi_idle_driver);
-                       return retval;
-               }
-               acpi_processor_registered++;
+               acpi_processor_setup_cpuidle(pr);
+               if (cpuidle_register_device(&pr->power.dev))
+                       return -EIO;
        }
        return 0;
 }
@@ -1268,13 +1132,8 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
        if (disabled_by_idle_boot_param())
                return 0;
 
-       if (pr->flags.power) {
-               cpuidle_unregister_device(&pr->power.dev);
-               acpi_processor_registered--;
-               if (acpi_processor_registered == 0)
-                       cpuidle_unregister_driver(&acpi_idle_driver);
-       }
-
+       cpuidle_unregister_device(&pr->power.dev);
        pr->flags.power_setup_done = 0;
+
        return 0;
 }
index 59f4261..6e0a300 100644 (file)
@@ -62,7 +62,6 @@ static int __cpuidle_register_device(struct cpuidle_device *dev);
 int cpuidle_idle_call(void)
 {
        struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
-       struct cpuidle_driver *drv = cpuidle_get_driver();
        struct cpuidle_state *target_state;
        int next_state, entered_state;
 
@@ -86,18 +85,18 @@ int cpuidle_idle_call(void)
 #endif
 
        /* ask the governor for the next state */
-       next_state = cpuidle_curr_governor->select(drv, dev);
+       next_state = cpuidle_curr_governor->select(dev);
        if (need_resched()) {
                local_irq_enable();
                return 0;
        }
 
-       target_state = &drv->states[next_state];
+       target_state = &dev->states[next_state];
 
        trace_power_start(POWER_CSTATE, next_state, dev->cpu);
        trace_cpu_idle(next_state, dev->cpu);
 
-       entered_state = target_state->enter(dev, drv, next_state);
+       entered_state = target_state->enter(dev, next_state);
 
        trace_power_end(dev->cpu);
        trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu);
@@ -165,8 +164,7 @@ void cpuidle_resume_and_unlock(void)
 EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock);
 
 #ifdef CONFIG_ARCH_HAS_CPU_RELAX
-static int poll_idle(struct cpuidle_device *dev,
-               struct cpuidle_driver *drv, int index)
+static int poll_idle(struct cpuidle_device *dev, int index)
 {
        ktime_t t1, t2;
        s64 diff;
@@ -186,9 +184,12 @@ static int poll_idle(struct cpuidle_device *dev,
        return index;
 }
 
-static void poll_idle_init(struct cpuidle_driver *drv)
+static void poll_idle_init(struct cpuidle_device *dev)
 {
-       struct cpuidle_state *state = &drv->states[0];
+       struct cpuidle_state *state = &dev->states[0];
+       struct cpuidle_state_usage *state_usage = &dev->states_usage[0];
+
+       cpuidle_set_statedata(state_usage, NULL);
 
        snprintf(state->name, CPUIDLE_NAME_LEN, "POLL");
        snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE");
@@ -199,7 +200,7 @@ static void poll_idle_init(struct cpuidle_driver *drv)
        state->enter = poll_idle;
 }
 #else
-static void poll_idle_init(struct cpuidle_driver *drv) {}
+static void poll_idle_init(struct cpuidle_device *dev) {}
 #endif /* CONFIG_ARCH_HAS_CPU_RELAX */
 
 /**
@@ -226,13 +227,13 @@ int cpuidle_enable_device(struct cpuidle_device *dev)
                        return ret;
        }
 
-       poll_idle_init(cpuidle_get_driver());
+       poll_idle_init(dev);
 
        if ((ret = cpuidle_add_state_sysfs(dev)))
                return ret;
 
        if (cpuidle_curr_governor->enable &&
-           (ret = cpuidle_curr_governor->enable(cpuidle_get_driver(), dev)))
+           (ret = cpuidle_curr_governor->enable(dev)))
                goto fail_sysfs;
 
        for (i = 0; i < dev->state_count; i++) {
@@ -273,7 +274,7 @@ void cpuidle_disable_device(struct cpuidle_device *dev)
        dev->enabled = 0;
 
        if (cpuidle_curr_governor->disable)
-               cpuidle_curr_governor->disable(cpuidle_get_driver(), dev);
+               cpuidle_curr_governor->disable(dev);
 
        cpuidle_remove_state_sysfs(dev);
        enabled_devices--;
@@ -301,6 +302,26 @@ static int __cpuidle_register_device(struct cpuidle_device *dev)
 
        init_completion(&dev->kobj_unregister);
 
+       /*
+        * cpuidle driver should set the dev->power_specified bit
+        * before registering the device if the driver provides
+        * power_usage numbers.
+        *
+        * For those devices whose ->power_specified is not set,
+        * we fill in power_usage with decreasing values as the
+        * cpuidle code has an implicit assumption that state Cn
+        * uses less power than C(n-1).
+        *
+        * With CONFIG_ARCH_HAS_CPU_RELAX, C0 is already assigned
+        * an power value of -1.  So we use -2, -3, etc, for other
+        * c-states.
+        */
+       if (!dev->power_specified) {
+               int i;
+               for (i = CPUIDLE_DRIVER_STATE_START; i < dev->state_count; i++)
+                       dev->states[i].power_usage = -1 - i;
+       }
+
        per_cpu(cpuidle_devices, dev->cpu) = dev;
        list_add(&dev->device_list, &cpuidle_detected_devices);
        if ((ret = cpuidle_add_sysfs(cpu_dev))) {
index 284d7af..3f7e3ce 100644 (file)
 static struct cpuidle_driver *cpuidle_curr_driver;
 DEFINE_SPINLOCK(cpuidle_driver_lock);
 
-static void __cpuidle_register_driver(struct cpuidle_driver *drv)
-{
-       int i;
-       /*
-        * cpuidle driver should set the drv->power_specified bit
-        * before registering if the driver provides
-        * power_usage numbers.
-        *
-        * If power_specified is not set,
-        * we fill in power_usage with decreasing values as the
-        * cpuidle code has an implicit assumption that state Cn
-        * uses less power than C(n-1).
-        *
-        * With CONFIG_ARCH_HAS_CPU_RELAX, C0 is already assigned
-        * an power value of -1.  So we use -2, -3, etc, for other
-        * c-states.
-        */
-       if (!drv->power_specified) {
-               for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++)
-                       drv->states[i].power_usage = -1 - i;
-       }
-}
-
-
 /**
  * cpuidle_register_driver - registers a driver
  * @drv: the driver
@@ -58,7 +34,6 @@ int cpuidle_register_driver(struct cpuidle_driver *drv)
                spin_unlock(&cpuidle_driver_lock);
                return -EBUSY;
        }
-       __cpuidle_register_driver(drv);
        cpuidle_curr_driver = drv;
        spin_unlock(&cpuidle_driver_lock);
 
index b6a09ea..38cb4ba 100644 (file)
@@ -60,11 +60,9 @@ static inline void ladder_do_selection(struct ladder_device *ldev,
 
 /**
  * ladder_select_state - selects the next state to enter
- * @drv: cpuidle driver
  * @dev: the CPU
  */
-static int ladder_select_state(struct cpuidle_driver *drv,
-                               struct cpuidle_device *dev)
+static int ladder_select_state(struct cpuidle_device *dev)
 {
        struct ladder_device *ldev = &__get_cpu_var(ladder_devices);
        struct ladder_device_state *last_state;
@@ -79,17 +77,15 @@ static int ladder_select_state(struct cpuidle_driver *drv,
 
        last_state = &ldev->states[last_idx];
 
-       if (drv->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID) {
-               last_residency = cpuidle_get_last_residency(dev) - \
-                                        drv->states[last_idx].exit_latency;
-       }
+       if (dev->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID)
+               last_residency = cpuidle_get_last_residency(dev) - dev->states[last_idx].exit_latency;
        else
                last_residency = last_state->threshold.promotion_time + 1;
 
        /* consider promotion */
-       if (last_idx < drv->state_count - 1 &&
+       if (last_idx < dev->state_count - 1 &&
            last_residency > last_state->threshold.promotion_time &&
-           drv->states[last_idx + 1].exit_latency <= latency_req) {
+           dev->states[last_idx + 1].exit_latency <= latency_req) {
                last_state->stats.promotion_count++;
                last_state->stats.demotion_count = 0;
                if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) {
@@ -100,11 +96,11 @@ static int ladder_select_state(struct cpuidle_driver *drv,
 
        /* consider demotion */
        if (last_idx > CPUIDLE_DRIVER_STATE_START &&
-           drv->states[last_idx].exit_latency > latency_req) {
+           dev->states[last_idx].exit_latency > latency_req) {
                int i;
 
                for (i = last_idx - 1; i > CPUIDLE_DRIVER_STATE_START; i--) {
-                       if (drv->states[i].exit_latency <= latency_req)
+                       if (dev->states[i].exit_latency <= latency_req)
                                break;
                }
                ladder_do_selection(ldev, last_idx, i);
@@ -127,11 +123,9 @@ static int ladder_select_state(struct cpuidle_driver *drv,
 
 /**
  * ladder_enable_device - setup for the governor
- * @drv: cpuidle driver
  * @dev: the CPU
  */
-static int ladder_enable_device(struct cpuidle_driver *drv,
-                               struct cpuidle_device *dev)
+static int ladder_enable_device(struct cpuidle_device *dev)
 {
        int i;
        struct ladder_device *ldev = &per_cpu(ladder_devices, dev->cpu);
@@ -140,8 +134,8 @@ static int ladder_enable_device(struct cpuidle_driver *drv,
 
        ldev->last_state_idx = CPUIDLE_DRIVER_STATE_START;
 
-       for (i = 0; i < drv->state_count; i++) {
-               state = &drv->states[i];
+       for (i = 0; i < dev->state_count; i++) {
+               state = &dev->states[i];
                lstate = &ldev->states[i];
 
                lstate->stats.promotion_count = 0;
@@ -150,7 +144,7 @@ static int ladder_enable_device(struct cpuidle_driver *drv,
                lstate->threshold.promotion_count = PROMOTION_COUNT;
                lstate->threshold.demotion_count = DEMOTION_COUNT;
 
-               if (i < drv->state_count - 1)
+               if (i < dev->state_count - 1)
                        lstate->threshold.promotion_time = state->exit_latency;
                if (i > 0)
                        lstate->threshold.demotion_time = state->exit_latency;
index 3d6c2ae..994e14b 100644 (file)
@@ -188,7 +188,7 @@ static inline int performance_multiplier(void)
 
 static DEFINE_PER_CPU(struct menu_device, menu_devices);
 
-static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev);
+static void menu_update(struct cpuidle_device *dev);
 
 /* This implements DIV_ROUND_CLOSEST but avoids 64 bit division */
 static u64 div_round64(u64 dividend, u32 divisor)
@@ -234,10 +234,9 @@ static void detect_repeating_patterns(struct menu_device *data)
 
 /**
  * menu_select - selects the next idle state to enter
- * @drv: cpuidle driver containing state data
  * @dev: the CPU
  */
-static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
+static int menu_select(struct cpuidle_device *dev)
 {
        struct menu_device *data = &__get_cpu_var(menu_devices);
        int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
@@ -247,7 +246,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
        struct timespec t;
 
        if (data->needs_update) {
-               menu_update(drv, dev);
+               menu_update(dev);
                data->needs_update = 0;
        }
 
@@ -292,8 +291,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
         * Find the idle state with the lowest power while satisfying
         * our constraints.
         */
-       for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
-               struct cpuidle_state *s = &drv->states[i];
+       for (i = CPUIDLE_DRIVER_STATE_START; i < dev->state_count; i++) {
+               struct cpuidle_state *s = &dev->states[i];
 
                if (s->target_residency > data->predicted_us)
                        continue;
@@ -330,15 +329,14 @@ static void menu_reflect(struct cpuidle_device *dev, int index)
 
 /**
  * menu_update - attempts to guess what happened after entry
- * @drv: cpuidle driver containing state data
  * @dev: the CPU
  */
-static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
+static void menu_update(struct cpuidle_device *dev)
 {
        struct menu_device *data = &__get_cpu_var(menu_devices);
        int last_idx = data->last_state_idx;
        unsigned int last_idle_us = cpuidle_get_last_residency(dev);
-       struct cpuidle_state *target = &drv->states[last_idx];
+       struct cpuidle_state *target = &dev->states[last_idx];
        unsigned int measured_us;
        u64 new_factor;
 
@@ -392,11 +390,9 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
 
 /**
  * menu_enable_device - scans a CPU's states and does setup
- * @drv: cpuidle driver
  * @dev: the CPU
  */
-static int menu_enable_device(struct cpuidle_driver *drv,
-                               struct cpuidle_device *dev)
+static int menu_enable_device(struct cpuidle_device *dev)
 {
        struct menu_device *data = &per_cpu(menu_devices, dev->cpu);
 
index 3fe41fe..41daed0 100644 (file)
@@ -320,14 +320,13 @@ int cpuidle_add_state_sysfs(struct cpuidle_device *device)
 {
        int i, ret = -ENOMEM;
        struct cpuidle_state_kobj *kobj;
-       struct cpuidle_driver *drv = cpuidle_get_driver();
 
        /* state statistics */
        for (i = 0; i < device->state_count; i++) {
                kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL);
                if (!kobj)
                        goto error_state;
-               kobj->state = &drv->states[i];
+               kobj->state = &device->states[i];
                kobj->state_usage = &device->states_usage[i];
                init_completion(&kobj->kobj_unregister);
 
index 8cf7e98..2a2d3ab 100644 (file)
@@ -330,7 +330,6 @@ extern void acpi_processor_throttling_init(void);
 int acpi_processor_power_init(struct acpi_processor *pr,
                              struct acpi_device *device);
 int acpi_processor_cst_has_changed(struct acpi_processor *pr);
-int acpi_processor_hotplug(struct acpi_processor *pr);
 int acpi_processor_power_exit(struct acpi_processor *pr,
                              struct acpi_device *device);
 int acpi_processor_suspend(struct acpi_device * device, pm_message_t state);
index 712abcc..815d346 100644 (file)
@@ -23,7 +23,6 @@
 struct module;
 
 struct cpuidle_device;
-struct cpuidle_driver;
 
 
 /****************************
@@ -47,7 +46,6 @@ struct cpuidle_state {
        unsigned int    target_residency; /* in US */
 
        int (*enter)    (struct cpuidle_device *dev,
-                       struct cpuidle_driver *drv,
                        int index);
 };
 
@@ -86,10 +84,12 @@ struct cpuidle_state_kobj {
 struct cpuidle_device {
        unsigned int            registered:1;
        unsigned int            enabled:1;
+       unsigned int            power_specified:1;
        unsigned int            cpu;
 
        int                     last_residency;
        int                     state_count;
+       struct cpuidle_state    states[CPUIDLE_STATE_MAX];
        struct cpuidle_state_usage      states_usage[CPUIDLE_STATE_MAX];
        struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX];
 
@@ -97,6 +97,7 @@ struct cpuidle_device {
        struct kobject          kobj;
        struct completion       kobj_unregister;
        void                    *governor_data;
+       int                     safe_state_index;
 };
 
 DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
@@ -120,11 +121,6 @@ static inline int cpuidle_get_last_residency(struct cpuidle_device *dev)
 struct cpuidle_driver {
        char                    name[CPUIDLE_NAME_LEN];
        struct module           *owner;
-
-       unsigned int            power_specified:1;
-       struct cpuidle_state    states[CPUIDLE_STATE_MAX];
-       int                     state_count;
-       int                     safe_state_index;
 };
 
 #ifdef CONFIG_CPU_IDLE
@@ -169,13 +165,10 @@ struct cpuidle_governor {
        struct list_head        governor_list;
        unsigned int            rating;
 
-       int  (*enable)          (struct cpuidle_driver *drv,
-                                       struct cpuidle_device *dev);
-       void (*disable)         (struct cpuidle_driver *drv,
-                                       struct cpuidle_device *dev);
+       int  (*enable)          (struct cpuidle_device *dev);
+       void (*disable)         (struct cpuidle_device *dev);
 
-       int  (*select)          (struct cpuidle_driver *drv,
-                                       struct cpuidle_device *dev);
+       int  (*select)          (struct cpuidle_device *dev);
        void (*reflect)         (struct cpuidle_device *dev, int index);
 
        struct module           *owner;