Skip to content

Commit 0f6e2cb

Browse files
committed
Merge back cpuidle changes for v5.11.
2 parents c39de53 + 670c90d commit 0f6e2cb

7 files changed

Lines changed: 81 additions & 34 deletions

File tree

drivers/base/power/domain.c

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,41 +1363,60 @@ static void genpd_complete(struct device *dev)
13631363
genpd_unlock(genpd);
13641364
}
13651365

1366-
/**
1367-
* genpd_syscore_switch - Switch power during system core suspend or resume.
1368-
* @dev: Device that normally is marked as "always on" to switch power for.
1369-
*
1370-
* This routine may only be called during the system core (syscore) suspend or
1371-
* resume phase for devices whose "always on" flags are set.
1372-
*/
1373-
static void genpd_syscore_switch(struct device *dev, bool suspend)
1366+
static void genpd_switch_state(struct device *dev, bool suspend)
13741367
{
13751368
struct generic_pm_domain *genpd;
1369+
bool use_lock;
13761370

13771371
genpd = dev_to_genpd_safe(dev);
13781372
if (!genpd)
13791373
return;
13801374

1375+
use_lock = genpd_is_irq_safe(genpd);
1376+
1377+
if (use_lock)
1378+
genpd_lock(genpd);
1379+
13811380
if (suspend) {
13821381
genpd->suspended_count++;
1383-
genpd_sync_power_off(genpd, false, 0);
1382+
genpd_sync_power_off(genpd, use_lock, 0);
13841383
} else {
1385-
genpd_sync_power_on(genpd, false, 0);
1384+
genpd_sync_power_on(genpd, use_lock, 0);
13861385
genpd->suspended_count--;
13871386
}
1387+
1388+
if (use_lock)
1389+
genpd_unlock(genpd);
13881390
}
13891391

1390-
void pm_genpd_syscore_poweroff(struct device *dev)
1392+
/**
1393+
* dev_pm_genpd_suspend - Synchronously try to suspend the genpd for @dev
1394+
* @dev: The device that is attached to the genpd, that can be suspended.
1395+
*
1396+
* This routine should typically be called for a device that needs to be
1397+
* suspended during the syscore suspend phase. It may also be called during
1398+
* suspend-to-idle to suspend a corresponding CPU device that is attached to a
1399+
* genpd.
1400+
*/
1401+
void dev_pm_genpd_suspend(struct device *dev)
13911402
{
1392-
genpd_syscore_switch(dev, true);
1403+
genpd_switch_state(dev, true);
13931404
}
1394-
EXPORT_SYMBOL_GPL(pm_genpd_syscore_poweroff);
1405+
EXPORT_SYMBOL_GPL(dev_pm_genpd_suspend);
13951406

1396-
void pm_genpd_syscore_poweron(struct device *dev)
1407+
/**
1408+
* dev_pm_genpd_resume - Synchronously try to resume the genpd for @dev
1409+
* @dev: The device that is attached to the genpd, which needs to be resumed.
1410+
*
1411+
* This routine should typically be called for a device that needs to be resumed
1412+
* during the syscore resume phase. It may also be called during suspend-to-idle
1413+
* to resume a corresponding CPU device that is attached to a genpd.
1414+
*/
1415+
void dev_pm_genpd_resume(struct device *dev)
13971416
{
1398-
genpd_syscore_switch(dev, false);
1417+
genpd_switch_state(dev, false);
13991418
}
1400-
EXPORT_SYMBOL_GPL(pm_genpd_syscore_poweron);
1419+
EXPORT_SYMBOL_GPL(dev_pm_genpd_resume);
14011420

14021421
#else /* !CONFIG_PM_SLEEP */
14031422

drivers/clocksource/sh_cmt.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ static void sh_cmt_clocksource_suspend(struct clocksource *cs)
658658
return;
659659

660660
sh_cmt_stop(ch, FLAG_CLOCKSOURCE);
661-
pm_genpd_syscore_poweroff(&ch->cmt->pdev->dev);
661+
dev_pm_genpd_suspend(&ch->cmt->pdev->dev);
662662
}
663663

664664
static void sh_cmt_clocksource_resume(struct clocksource *cs)
@@ -668,7 +668,7 @@ static void sh_cmt_clocksource_resume(struct clocksource *cs)
668668
if (!ch->cs_enabled)
669669
return;
670670

671-
pm_genpd_syscore_poweron(&ch->cmt->pdev->dev);
671+
dev_pm_genpd_resume(&ch->cmt->pdev->dev);
672672
sh_cmt_start(ch, FLAG_CLOCKSOURCE);
673673
}
674674

@@ -760,7 +760,7 @@ static void sh_cmt_clock_event_suspend(struct clock_event_device *ced)
760760
{
761761
struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
762762

763-
pm_genpd_syscore_poweroff(&ch->cmt->pdev->dev);
763+
dev_pm_genpd_suspend(&ch->cmt->pdev->dev);
764764
clk_unprepare(ch->cmt->clk);
765765
}
766766

@@ -769,7 +769,7 @@ static void sh_cmt_clock_event_resume(struct clock_event_device *ced)
769769
struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
770770

771771
clk_prepare(ch->cmt->clk);
772-
pm_genpd_syscore_poweron(&ch->cmt->pdev->dev);
772+
dev_pm_genpd_resume(&ch->cmt->pdev->dev);
773773
}
774774

775775
static int sh_cmt_register_clockevent(struct sh_cmt_channel *ch,

drivers/clocksource/sh_mtu2.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,12 +297,12 @@ static int sh_mtu2_clock_event_set_periodic(struct clock_event_device *ced)
297297

298298
static void sh_mtu2_clock_event_suspend(struct clock_event_device *ced)
299299
{
300-
pm_genpd_syscore_poweroff(&ced_to_sh_mtu2(ced)->mtu->pdev->dev);
300+
dev_pm_genpd_suspend(&ced_to_sh_mtu2(ced)->mtu->pdev->dev);
301301
}
302302

303303
static void sh_mtu2_clock_event_resume(struct clock_event_device *ced)
304304
{
305-
pm_genpd_syscore_poweron(&ced_to_sh_mtu2(ced)->mtu->pdev->dev);
305+
dev_pm_genpd_resume(&ced_to_sh_mtu2(ced)->mtu->pdev->dev);
306306
}
307307

308308
static void sh_mtu2_register_clockevent(struct sh_mtu2_channel *ch,

drivers/clocksource/sh_tmu.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ static void sh_tmu_clocksource_suspend(struct clocksource *cs)
292292

293293
if (--ch->enable_count == 0) {
294294
__sh_tmu_disable(ch);
295-
pm_genpd_syscore_poweroff(&ch->tmu->pdev->dev);
295+
dev_pm_genpd_suspend(&ch->tmu->pdev->dev);
296296
}
297297
}
298298

@@ -304,7 +304,7 @@ static void sh_tmu_clocksource_resume(struct clocksource *cs)
304304
return;
305305

306306
if (ch->enable_count++ == 0) {
307-
pm_genpd_syscore_poweron(&ch->tmu->pdev->dev);
307+
dev_pm_genpd_resume(&ch->tmu->pdev->dev);
308308
__sh_tmu_enable(ch);
309309
}
310310
}
@@ -394,12 +394,12 @@ static int sh_tmu_clock_event_next(unsigned long delta,
394394

395395
static void sh_tmu_clock_event_suspend(struct clock_event_device *ced)
396396
{
397-
pm_genpd_syscore_poweroff(&ced_to_sh_tmu(ced)->tmu->pdev->dev);
397+
dev_pm_genpd_suspend(&ced_to_sh_tmu(ced)->tmu->pdev->dev);
398398
}
399399

400400
static void sh_tmu_clock_event_resume(struct clock_event_device *ced)
401401
{
402-
pm_genpd_syscore_poweron(&ced_to_sh_tmu(ced)->tmu->pdev->dev);
402+
dev_pm_genpd_resume(&ced_to_sh_tmu(ced)->tmu->pdev->dev);
403403
}
404404

405405
static void sh_tmu_register_clockevent(struct sh_tmu_channel *ch,

drivers/cpuidle/cpuidle-psci-domain.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,8 @@ struct device *psci_dt_attach_cpu(int cpu)
327327
if (cpu_online(cpu))
328328
pm_runtime_get_sync(dev);
329329

330+
dev_pm_syscore_device(dev, true);
331+
330332
return dev;
331333
}
332334

drivers/cpuidle/cpuidle-psci.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/of_device.h>
2020
#include <linux/platform_device.h>
2121
#include <linux/psci.h>
22+
#include <linux/pm_domain.h>
2223
#include <linux/pm_runtime.h>
2324
#include <linux/slab.h>
2425
#include <linux/string.h>
@@ -52,8 +53,9 @@ static inline int psci_enter_state(int idx, u32 state)
5253
return CPU_PM_CPU_IDLE_ENTER_PARAM(psci_cpu_suspend_enter, idx, state);
5354
}
5455

55-
static int psci_enter_domain_idle_state(struct cpuidle_device *dev,
56-
struct cpuidle_driver *drv, int idx)
56+
static int __psci_enter_domain_idle_state(struct cpuidle_device *dev,
57+
struct cpuidle_driver *drv, int idx,
58+
bool s2idle)
5759
{
5860
struct psci_cpuidle_data *data = this_cpu_ptr(&psci_cpuidle_data);
5961
u32 *states = data->psci_states;
@@ -66,15 +68,25 @@ static int psci_enter_domain_idle_state(struct cpuidle_device *dev,
6668
return -1;
6769

6870
/* Do runtime PM to manage a hierarchical CPU toplogy. */
69-
RCU_NONIDLE(pm_runtime_put_sync_suspend(pd_dev));
71+
rcu_irq_enter_irqson();
72+
if (s2idle)
73+
dev_pm_genpd_suspend(pd_dev);
74+
else
75+
pm_runtime_put_sync_suspend(pd_dev);
76+
rcu_irq_exit_irqson();
7077

7178
state = psci_get_domain_state();
7279
if (!state)
7380
state = states[idx];
7481

7582
ret = psci_cpu_suspend_enter(state) ? -1 : idx;
7683

77-
RCU_NONIDLE(pm_runtime_get_sync(pd_dev));
84+
rcu_irq_enter_irqson();
85+
if (s2idle)
86+
dev_pm_genpd_resume(pd_dev);
87+
else
88+
pm_runtime_get_sync(pd_dev);
89+
rcu_irq_exit_irqson();
7890

7991
cpu_pm_exit();
8092

@@ -83,6 +95,19 @@ static int psci_enter_domain_idle_state(struct cpuidle_device *dev,
8395
return ret;
8496
}
8597

98+
static int psci_enter_domain_idle_state(struct cpuidle_device *dev,
99+
struct cpuidle_driver *drv, int idx)
100+
{
101+
return __psci_enter_domain_idle_state(dev, drv, idx, false);
102+
}
103+
104+
static int psci_enter_s2idle_domain_idle_state(struct cpuidle_device *dev,
105+
struct cpuidle_driver *drv,
106+
int idx)
107+
{
108+
return __psci_enter_domain_idle_state(dev, drv, idx, true);
109+
}
110+
86111
static int psci_idle_cpuhp_up(unsigned int cpu)
87112
{
88113
struct device *pd_dev = __this_cpu_read(psci_cpuidle_data.dev);
@@ -170,6 +195,7 @@ static int psci_dt_cpu_init_topology(struct cpuidle_driver *drv,
170195
* deeper states.
171196
*/
172197
drv->states[state_count - 1].enter = psci_enter_domain_idle_state;
198+
drv->states[state_count - 1].enter_s2idle = psci_enter_s2idle_domain_idle_state;
173199
psci_cpuidle_use_cpuhp = true;
174200

175201
return 0;

include/linux/pm_domain.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,11 @@ static inline int dev_pm_genpd_remove_notifier(struct device *dev)
280280
#endif
281281

282282
#ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP
283-
void pm_genpd_syscore_poweroff(struct device *dev);
284-
void pm_genpd_syscore_poweron(struct device *dev);
283+
void dev_pm_genpd_suspend(struct device *dev);
284+
void dev_pm_genpd_resume(struct device *dev);
285285
#else
286-
static inline void pm_genpd_syscore_poweroff(struct device *dev) {}
287-
static inline void pm_genpd_syscore_poweron(struct device *dev) {}
286+
static inline void dev_pm_genpd_suspend(struct device *dev) {}
287+
static inline void dev_pm_genpd_resume(struct device *dev) {}
288288
#endif
289289

290290
/* OF PM domain providers */

0 commit comments

Comments
 (0)