static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n, unsigned long action, void *hcpu) { int hotcpu = (unsigned long)hcpu; struct cpuidle_device *dev = per_cpu(cpuidle_devices, hotcpu); if (dev && cpuidle_get_driver()) { switch (action) { case CPU_ONLINE: case CPU_ONLINE_FROZEN: cpuidle_pause_and_lock(); cpuidle_enable_device(dev); cpuidle_resume_and_unlock(); break; case CPU_DEAD: case CPU_DEAD_FROZEN: cpuidle_pause_and_lock(); cpuidle_disable_device(dev); cpuidle_resume_and_unlock(); break; default: return NOTIFY_DONE; } } return NOTIFY_OK; }
int acpi_processor_cst_has_changed(struct acpi_processor *pr) { int ret = 0; if (boot_option_idle_override) return 0; if (!pr) return -EINVAL; if (nocst) { return -ENODEV; } if (!pr->flags.power_setup_done) return -ENODEV; cpuidle_pause_and_lock(); cpuidle_disable_device(&pr->power.dev); acpi_processor_get_power_info(pr); if (pr->flags.power) { acpi_processor_setup_cpuidle(pr); ret = cpuidle_enable_device(&pr->power.dev); } cpuidle_resume_and_unlock(); return ret; }
int acpi_processor_hotplug(struct acpi_processor *pr) { int ret = 0; if (disabled_by_idle_boot_param()) return 0; if (!pr) return -EINVAL; if (nocst) { return -ENODEV; } if (!pr->flags.power_setup_done) return -ENODEV; cpuidle_pause_and_lock(); cpuidle_disable_device(&pr->power.dev); acpi_processor_get_power_info(pr); if (pr->flags.power) { acpi_processor_setup_cpuidle_cx(pr); ret = cpuidle_enable_device(&pr->power.dev); } cpuidle_resume_and_unlock(); return ret; }
int acpi_processor_hotplug(struct acpi_processor *pr) { int ret = 0; struct cpuidle_device *dev; if (disabled_by_idle_boot_param()) return 0; if (nocst) return -ENODEV; if (!pr->flags.power_setup_done) return -ENODEV; dev = per_cpu(acpi_cpuidle_device, pr->id); cpuidle_pause_and_lock(); cpuidle_disable_device(dev); acpi_processor_get_power_info(pr); if (pr->flags.power) { acpi_processor_setup_cpuidle_cx(pr, dev); ret = cpuidle_enable_device(dev); } cpuidle_resume_and_unlock(); return ret; }
/** * cpuidle_unregister_device - unregisters a CPU's idle PM feature * @dev: the cpu */ void cpuidle_unregister_device(struct cpuidle_device *dev) { struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); if (!sys_dev) { pr_err(" ERR get_cpu_sysdev returned NULL\n"); return; } if (dev->registered == 0) return; if (!sys_dev) return; cpuidle_pause_and_lock(); cpuidle_disable_device(dev); cpuidle_remove_sysfs(sys_dev); list_del(&dev->device_list); wait_for_completion(&dev->kobj_unregister); per_cpu(cpuidle_devices, dev->cpu) = NULL; cpuidle_resume_and_unlock(); module_put(cpuidle_curr_driver->owner); }
/** * cpuidle_unregister_device - unregisters a CPU's idle PM feature * @dev: the cpu */ void cpuidle_unregister_device(struct cpuidle_device *dev) { struct device *cpu_dev; struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); if (!dev) return; cpu_dev = get_cpu_device((unsigned long)dev->cpu); if (!cpu_dev) return; if (dev->registered == 0) return; cpuidle_pause_and_lock(); cpuidle_disable_device(dev); cpuidle_remove_sysfs(cpu_dev); list_del(&dev->device_list); wait_for_completion(&dev->kobj_unregister); per_cpu(cpuidle_devices, dev->cpu) = NULL; cpuidle_coupled_unregister_device(dev); cpuidle_resume_and_unlock(); module_put(cpuidle_driver->owner); }
int acpi_processor_cst_has_changed(struct acpi_processor *pr) { int cpu; struct acpi_processor *_pr; struct cpuidle_device *dev; 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 (pr->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; dev = per_cpu(acpi_cpuidle_device, cpu); cpuidle_disable_device(dev); } /* Populate Updated C-state information */ acpi_processor_get_power_info(pr); 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) { dev = per_cpu(acpi_cpuidle_device, cpu); acpi_processor_setup_cpuidle_cx(_pr, dev); cpuidle_enable_device(dev); } } put_online_cpus(); cpuidle_resume_and_unlock(); }
int s5p6442_setup_lpaudio(unsigned int mode) { struct cpuidle_device *device; int ret = 0; cpuidle_pause_and_lock(); device = &per_cpu(s5p6442_cpuidle_device, smp_processor_id()); cpuidle_disable_device(device); switch (mode) { case NORMAL_MODE: device->state_count = 1; /* Wait for interrupt state */ device->states[0].enter = s5p6442_enter_idle_normal; device->states[0].exit_latency = 1; /* uS */ device->states[0].target_residency = 10000; device->states[0].flags = CPUIDLE_FLAG_TIME_VALID; strcpy(device->states[0].name, "IDLE"); strcpy(device->states[0].desc, "ARM clock gating - WFI"); break; case LPAUDIO_MODE: device->state_count = 1; /* Wait for interrupt state */ device->states[0].enter = s5p6442_enter_idle_bm; device->states[0].exit_latency = 1; /* uS */ device->states[0].target_residency = 5000; device->states[0].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_CHECK_BM; strcpy(device->states[0].name, "DEEP IDLE"); strcpy(device->states[0].desc, "S5P6442 idle2"); break; default: printk(KERN_ERR "Can't find cpuidle mode %d\n", mode); device->state_count = 1; /* Wait for interrupt state */ device->states[0].enter = s5p6442_enter_idle_normal; device->states[0].exit_latency = 1; /* uS */ device->states[0].target_residency = 10000; device->states[0].flags = CPUIDLE_FLAG_TIME_VALID; strcpy(device->states[0].name, "IDLE"); strcpy(device->states[0].desc, "ARM clock gating - WFI"); break; } cpuidle_enable_device(device); cpuidle_resume_and_unlock(); 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; if (pr->id == 0 && cpuidle_get_driver() == &acpi_idle_driver) { cpuidle_pause_and_lock(); get_online_cpus(); for_each_online_cpu(cpu) { _pr = per_cpu(processors, cpu); if (!_pr || !_pr->flags.power_setup_done) continue; cpuidle_disable_device(&_pr->power.dev); } acpi_processor_setup_cpuidle_states(pr); 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(); }
/** * cpuidle_unregister_device - unregisters a CPU's idle PM feature * @dev: the cpu */ void cpuidle_unregister_device(struct cpuidle_device *dev) { struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); if (dev->registered == 0) return; cpuidle_pause_and_lock(); cpuidle_disable_device(dev); cpuidle_remove_sysfs(dev); list_del(&dev->device_list); per_cpu(cpuidle_devices, dev->cpu) = NULL; cpuidle_coupled_unregister_device(dev); cpuidle_resume_and_unlock(); module_put(drv->owner); }