Skip to content

Commit cbda56d

Browse files
committed
cpuidle: Introduce cpuidle_driver_state_disabled() for driver quirks
Commit 99e98d3 ("cpuidle: Consolidate disabled state checks") overlooked the fact that the imx6q and tegra20 cpuidle drivers use the "disabled" field in struct cpuidle_state for quirks which trigger after the initialization of cpuidle, so reading the initial value of that field is not sufficient for those drivers. In order to allow them to implement the quirks without using the "disabled" field in struct cpuidle_state, introduce a new helper function and modify them to use it. Fixes: 99e98d3 ("cpuidle: Consolidate disabled state checks") Reported-by: Len Brown <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 85f6a17 commit cbda56d

File tree

4 files changed

+35
-3
lines changed

4 files changed

+35
-3
lines changed

arch/arm/mach-imx/cpuidle-imx6q.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@ static struct cpuidle_driver imx6q_cpuidle_driver = {
6262
*/
6363
void imx6q_cpuidle_fec_irqs_used(void)
6464
{
65-
imx6q_cpuidle_driver.states[1].disabled = true;
65+
cpuidle_driver_state_disabled(&imx6q_cpuidle_driver, 1, true);
6666
}
6767
EXPORT_SYMBOL_GPL(imx6q_cpuidle_fec_irqs_used);
6868

6969
void imx6q_cpuidle_fec_irqs_unused(void)
7070
{
71-
imx6q_cpuidle_driver.states[1].disabled = false;
71+
cpuidle_driver_state_disabled(&imx6q_cpuidle_driver, 1, false);
7272
}
7373
EXPORT_SYMBOL_GPL(imx6q_cpuidle_fec_irqs_unused);
7474

arch/arm/mach-tegra/cpuidle-tegra20.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ void tegra20_cpuidle_pcie_irqs_in_use(void)
203203
{
204204
pr_info_once(
205205
"Disabling cpuidle LP2 state, since PCIe IRQs are in use\n");
206-
tegra_idle_driver.states[1].disabled = true;
206+
cpuidle_driver_state_disabled(&tegra_idle_driver, 1, true);
207207
}
208208

209209
int __init tegra20_cpuidle_init(void)

drivers/cpuidle/driver.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,3 +389,31 @@ void cpuidle_driver_unref(void)
389389

390390
spin_unlock(&cpuidle_driver_lock);
391391
}
392+
393+
/**
394+
* cpuidle_driver_state_disabled - Disable or enable an idle state
395+
* @drv: cpuidle driver owning the state
396+
* @idx: State index
397+
* @disable: Whether or not to disable the state
398+
*/
399+
void cpuidle_driver_state_disabled(struct cpuidle_driver *drv, int idx,
400+
bool disable)
401+
{
402+
unsigned int cpu;
403+
404+
mutex_lock(&cpuidle_lock);
405+
406+
for_each_cpu(cpu, drv->cpumask) {
407+
struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
408+
409+
if (!dev)
410+
continue;
411+
412+
if (disable)
413+
dev->states_usage[idx].disable |= CPUIDLE_STATE_DISABLED_BY_DRIVER;
414+
else
415+
dev->states_usage[idx].disable &= ~CPUIDLE_STATE_DISABLED_BY_DRIVER;
416+
}
417+
418+
mutex_unlock(&cpuidle_lock);
419+
}

include/linux/cpuidle.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ extern int cpuidle_register_driver(struct cpuidle_driver *drv);
149149
extern struct cpuidle_driver *cpuidle_get_driver(void);
150150
extern struct cpuidle_driver *cpuidle_driver_ref(void);
151151
extern void cpuidle_driver_unref(void);
152+
extern void cpuidle_driver_state_disabled(struct cpuidle_driver *drv, int idx,
153+
bool disable);
152154
extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
153155
extern int cpuidle_register_device(struct cpuidle_device *dev);
154156
extern void cpuidle_unregister_device(struct cpuidle_device *dev);
@@ -186,6 +188,8 @@ static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
186188
static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
187189
static inline struct cpuidle_driver *cpuidle_driver_ref(void) {return NULL; }
188190
static inline void cpuidle_driver_unref(void) {}
191+
static inline void cpuidle_driver_state_disabled(struct cpuidle_driver *drv,
192+
int idx, bool disable) { }
189193
static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { }
190194
static inline int cpuidle_register_device(struct cpuidle_device *dev)
191195
{return -ENODEV; }

0 commit comments

Comments
 (0)