diff options
Diffstat (limited to 'drivers/cpuidle/cpuidle.c')
-rw-r--r-- | drivers/cpuidle/cpuidle.c | 80 |
1 files changed, 16 insertions, 64 deletions
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index d75040ddd2b3..a55e68f2cfc8 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -118,11 +118,9 @@ int cpuidle_idle_call(void) struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); struct cpuidle_driver *drv; int next_state, entered_state; + bool broadcast; - if (off) - return -ENODEV; - - if (!initialized) + if (off || !initialized) return -ENODEV; /* check if the device is ready */ @@ -144,9 +142,10 @@ int cpuidle_idle_call(void) trace_cpu_idle_rcuidle(next_state, dev->cpu); - if (drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP) - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, - &dev->cpu); + broadcast = !!(drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP); + + if (broadcast) + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); if (cpuidle_state_is_coupled(dev, drv, next_state)) entered_state = cpuidle_enter_state_coupled(dev, drv, @@ -154,9 +153,8 @@ int cpuidle_idle_call(void) else entered_state = cpuidle_enter_state(dev, drv, next_state); - if (drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP) - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, - &dev->cpu); + if (broadcast) + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); @@ -228,45 +226,6 @@ void cpuidle_resume(void) mutex_unlock(&cpuidle_lock); } -#ifdef CONFIG_ARCH_HAS_CPU_RELAX -static int poll_idle(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index) -{ - ktime_t t1, t2; - s64 diff; - - t1 = ktime_get(); - local_irq_enable(); - while (!need_resched()) - cpu_relax(); - - t2 = ktime_get(); - diff = ktime_to_us(ktime_sub(t2, t1)); - if (diff > INT_MAX) - diff = INT_MAX; - - dev->last_residency = (int) diff; - - return index; -} - -static void poll_idle_init(struct cpuidle_driver *drv) -{ - struct cpuidle_state *state = &drv->states[0]; - - snprintf(state->name, CPUIDLE_NAME_LEN, "POLL"); - snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE"); - state->exit_latency = 0; - state->target_residency = 0; - state->power_usage = -1; - state->flags = 0; - state->enter = poll_idle; - state->disabled = false; -} -#else -static void poll_idle_init(struct cpuidle_driver *drv) {} -#endif /* CONFIG_ARCH_HAS_CPU_RELAX */ - /** * cpuidle_enable_device - enables idle PM for a CPU * @dev: the CPU @@ -296,8 +255,6 @@ int cpuidle_enable_device(struct cpuidle_device *dev) if (!dev->state_count) dev->state_count = drv->state_count; - poll_idle_init(drv); - ret = cpuidle_add_device_sysfs(dev); if (ret) return ret; @@ -358,12 +315,10 @@ static void __cpuidle_unregister_device(struct cpuidle_device *dev) module_put(drv->owner); } -static int __cpuidle_device_init(struct cpuidle_device *dev) +static void __cpuidle_device_init(struct cpuidle_device *dev) { memset(dev->states_usage, 0, sizeof(dev->states_usage)); dev->last_residency = 0; - - return 0; } /** @@ -385,13 +340,12 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) list_add(&dev->device_list, &cpuidle_detected_devices); ret = cpuidle_coupled_register_device(dev); - if (ret) { + if (ret) __cpuidle_unregister_device(dev); - return ret; - } + else + dev->registered = 1; - dev->registered = 1; - return 0; + return ret; } /** @@ -410,9 +364,7 @@ int cpuidle_register_device(struct cpuidle_device *dev) if (dev->registered) goto out_unlock; - ret = __cpuidle_device_init(dev); - if (ret) - goto out_unlock; + __cpuidle_device_init(dev); ret = __cpuidle_register_device(dev); if (ret) @@ -448,7 +400,7 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device); */ void cpuidle_unregister_device(struct cpuidle_device *dev) { - if (dev->registered == 0) + if (!dev || dev->registered == 0) return; cpuidle_pause_and_lock(); @@ -516,7 +468,7 @@ int cpuidle_register(struct cpuidle_driver *drv, #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED /* - * On multiplatform for ARM, the coupled idle states could + * On multiplatform for ARM, the coupled idle states could be * enabled in the kernel even if the cpuidle driver does not * use it. Note, coupled_cpus is a struct copy. */ |