diff options
| -rw-r--r-- | Documentation/admin-guide/pm/intel_idle.rst | 11 | ||||
| -rw-r--r-- | drivers/base/power/wakeirq.c | 11 | ||||
| -rw-r--r-- | drivers/cpuidle/cpuidle.c | 10 | ||||
| -rw-r--r-- | drivers/cpuidle/governors/haltpoll.c | 4 | ||||
| -rw-r--r-- | drivers/cpuidle/governors/menu.c | 2 | ||||
| -rw-r--r-- | drivers/cpuidle/governors/teo.c | 6 |
6 files changed, 30 insertions, 14 deletions
diff --git a/Documentation/admin-guide/pm/intel_idle.rst b/Documentation/admin-guide/pm/intel_idle.rst index ed6f055d4b14..188d52cd26e8 100644 --- a/Documentation/admin-guide/pm/intel_idle.rst +++ b/Documentation/admin-guide/pm/intel_idle.rst @@ -260,6 +260,17 @@ mode to off when the CPU is in any one of the available idle states. This may help performance of a sibling CPU at the expense of a slightly higher wakeup latency for the idle CPU. +The ``table`` argument allows customization of idle state latency and target +residency. The syntax is a comma-separated list of ``name:latency:residency`` +entries, where ``name`` is the idle state name, ``latency`` is the exit latency +in microseconds, and ``residency`` is the target residency in microseconds. It +is not necessary to specify all idle states; only those to be customized. For +example, ``C1:1:3,C6:50:100`` sets the exit latency and target residency for +C1 and C6 to 1/3 and 50/100 microseconds, respectively. Remaining idle states +keep their default values. The driver verifies that deeper idle states have +higher latency and target residency than shallower ones. Also, target +residency cannot be smaller than exit latency. If any of these conditions is +not met, the driver ignores the entire ``table`` parameter. .. _intel-idle-core-and-package-idle-states: diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c index c0809d18fc54..aab843f6dfcc 100644 --- a/drivers/base/power/wakeirq.c +++ b/drivers/base/power/wakeirq.c @@ -273,8 +273,10 @@ EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse); * otherwise try to disable already disabled wakeirq. The wake-up interrupt * starts disabled with IRQ_NOAUTOEN set. * - * Should be only called from rpm_suspend() and rpm_resume() path. - * Caller must hold &dev->power.lock to change wirq->status + * Should be called from rpm_suspend(), rpm_resume(), + * pm_runtime_force_suspend() or pm_runtime_force_resume(). + * Caller must hold &dev->power.lock or disable runtime PM to change + * wirq->status. */ void dev_pm_enable_wake_irq_check(struct device *dev, bool can_change_status) @@ -306,7 +308,8 @@ enable: * @cond_disable: if set, also check WAKE_IRQ_DEDICATED_REVERSE * * Disables wake-up interrupt conditionally based on status. - * Should be only called from rpm_suspend() and rpm_resume() path. + * Should be called from rpm_suspend(), rpm_resume(), + * pm_runtime_force_suspend() or pm_runtime_force_resume(). */ void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable) { @@ -332,7 +335,7 @@ void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable) * enable wake IRQ after running ->runtime_suspend() which depends on * WAKE_IRQ_DEDICATED_REVERSE. * - * Should be only called from rpm_suspend() path. + * Should be called from rpm_suspend() or pm_runtime_force_suspend(). */ void dev_pm_enable_wake_irq_complete(struct device *dev) { diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index c7876e9e024f..65fbb8e807b9 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -359,6 +359,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev, int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, bool *stop_tick) { + /* + * If there is only a single idle state (or none), there is nothing + * meaningful for the governor to choose. Skip the governor and + * always use state 0 with the tick running. + */ + if (drv->state_count <= 1) { + *stop_tick = false; + return 0; + } + return cpuidle_curr_governor->select(drv, dev, stop_tick); } diff --git a/drivers/cpuidle/governors/haltpoll.c b/drivers/cpuidle/governors/haltpoll.c index 663b7f164d20..b367d10279c8 100644 --- a/drivers/cpuidle/governors/haltpoll.c +++ b/drivers/cpuidle/governors/haltpoll.c @@ -50,9 +50,7 @@ static int haltpoll_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, bool *stop_tick) { - s64 latency_req = cpuidle_governor_latency_req(dev->cpu); - - if (!drv->state_count || latency_req == 0) { + if (cpuidle_governor_latency_req(dev->cpu) == 0) { *stop_tick = false; return 0; } diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index c6052055ba0f..899ff16ff1fe 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -281,7 +281,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, data->bucket = BUCKETS - 1; } - if (drv->state_count <= 1 || latency_req == 0 || + if (latency_req == 0 || ((data->next_timer_ns < drv->states[1].target_residency_ns || latency_req < drv->states[1].exit_latency_ns) && !dev->states_usage[0].disable)) { diff --git a/drivers/cpuidle/governors/teo.c b/drivers/cpuidle/governors/teo.c index 80f3ba942a06..bec0142377b8 100644 --- a/drivers/cpuidle/governors/teo.c +++ b/drivers/cpuidle/governors/teo.c @@ -338,12 +338,6 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, */ cpu_data->sleep_length_ns = KTIME_MAX; - /* Check if there is any choice in the first place. */ - if (drv->state_count < 2) { - idx = 0; - goto out_tick; - } - if (!dev->states_usage[0].disable) idx = 0; |
