aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-shmobile/Makefile2
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c19
-rw-r--r--arch/arm/mach-shmobile/board-armadillo800eva.c6
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c32
-rw-r--r--arch/arm/mach-shmobile/common.c24
-rw-r--r--arch/arm/mach-shmobile/cpuidle.c39
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h14
-rw-r--r--arch/arm/mach-shmobile/include/mach/pm-rmobile.h35
-rw-r--r--arch/arm/mach-shmobile/include/mach/r8a7740.h6
-rw-r--r--arch/arm/mach-shmobile/include/mach/r8a7779.h12
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h18
-rw-r--r--arch/arm/mach-shmobile/pm-r8a7740.c42
-rw-r--r--arch/arm/mach-shmobile/pm-r8a7779.c71
-rw-r--r--arch/arm/mach-shmobile/pm-rmobile.c33
-rw-r--r--arch/arm/mach-shmobile/pm-sh7372.c233
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7740.c27
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7779.c5
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c69
-rw-r--r--drivers/base/platform.c2
-rw-r--r--drivers/base/power/domain.c244
-rw-r--r--drivers/base/power/main.c35
-rw-r--r--drivers/base/power/power.h36
-rw-r--r--drivers/clocksource/sh_cmt.c71
-rw-r--r--drivers/clocksource/sh_mtu2.c41
-rw-r--r--drivers/clocksource/sh_tmu.c112
-rw-r--r--include/linux/clockchips.h8
-rw-r--r--include/linux/device.h7
-rw-r--r--include/linux/pm.h2
-rw-r--r--include/linux/pm_domain.h92
-rw-r--r--kernel/power/Kconfig4
-rw-r--r--kernel/time/clockevents.c24
-rw-r--r--kernel/time/timekeeping.c2
32 files changed, 946 insertions, 421 deletions
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 0df5ae6740c6..fe2c97c179d1 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5# Common objects 5# Common objects
6obj-y := timer.o console.o clock.o common.o 6obj-y := timer.o console.o clock.o
7 7
8# CPU objects 8# CPU objects
9obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o 9obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index f172ca85905c..5168a0338cf4 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -1229,6 +1229,15 @@ static struct i2c_board_info i2c1_devices[] = {
1229#define USCCR1 0xE6058144 1229#define USCCR1 0xE6058144
1230static void __init ap4evb_init(void) 1230static void __init ap4evb_init(void)
1231{ 1231{
1232 struct pm_domain_device domain_devices[] = {
1233 { "A4LC", &lcdc1_device, },
1234 { "A4LC", &lcdc_device, },
1235 { "A4MP", &fsi_device, },
1236 { "A3SP", &sh_mmcif_device, },
1237 { "A3SP", &sdhi0_device, },
1238 { "A3SP", &sdhi1_device, },
1239 { "A4R", &ceu_device, },
1240 };
1232 u32 srcr4; 1241 u32 srcr4;
1233 struct clk *clk; 1242 struct clk *clk;
1234 1243
@@ -1461,14 +1470,8 @@ static void __init ap4evb_init(void)
1461 1470
1462 platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); 1471 platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices));
1463 1472
1464 rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc1_device); 1473 rmobile_add_devices_to_domains(domain_devices,
1465 rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc_device); 1474 ARRAY_SIZE(domain_devices));
1466 rmobile_add_device_to_domain(&sh7372_pd_a4mp, &fsi_device);
1467
1468 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sh_mmcif_device);
1469 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi0_device);
1470 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi1_device);
1471 rmobile_add_device_to_domain(&sh7372_pd_a4r, &ceu_device);
1472 1475
1473 hdmi_init_pm_clock(); 1476 hdmi_init_pm_clock();
1474 fsi_init_pm_clock(); 1477 fsi_init_pm_clock();
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
index cf10f92856dc..28e6e1d0d511 100644
--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
+++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
@@ -1181,10 +1181,10 @@ static void __init eva_init(void)
1181 1181
1182 eva_clock_init(); 1182 eva_clock_init();
1183 1183
1184 rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &lcdc0_device); 1184 rmobile_add_device_to_domain("A4LC", &lcdc0_device);
1185 rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &hdmi_lcdc_device); 1185 rmobile_add_device_to_domain("A4LC", &hdmi_lcdc_device);
1186 if (usb) 1186 if (usb)
1187 rmobile_add_device_to_domain(&r8a7740_pd_a3sp, usb); 1187 rmobile_add_device_to_domain("A3SP", usb);
1188} 1188}
1189 1189
1190static void __init eva_earlytimer_init(void) 1190static void __init eva_earlytimer_init(void)
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 7ea2b31e3199..d1e8fe83588c 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1409,6 +1409,22 @@ static struct i2c_board_info i2c1_devices[] = {
1409#define USCCR1 0xE6058144 1409#define USCCR1 0xE6058144
1410static void __init mackerel_init(void) 1410static void __init mackerel_init(void)
1411{ 1411{
1412 struct pm_domain_device domain_devices[] = {
1413 { "A4LC", &lcdc_device, },
1414 { "A4LC", &hdmi_lcdc_device, },
1415 { "A4LC", &meram_device, },
1416 { "A4MP", &fsi_device, },
1417 { "A3SP", &usbhs0_device, },
1418 { "A3SP", &usbhs1_device, },
1419 { "A3SP", &nand_flash_device, },
1420 { "A3SP", &sh_mmcif_device, },
1421 { "A3SP", &sdhi0_device, },
1422#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
1423 { "A3SP", &sdhi1_device, },
1424#endif
1425 { "A3SP", &sdhi2_device, },
1426 { "A4R", &ceu_device, },
1427 };
1412 u32 srcr4; 1428 u32 srcr4;
1413 struct clk *clk; 1429 struct clk *clk;
1414 1430
@@ -1623,20 +1639,8 @@ static void __init mackerel_init(void)
1623 1639
1624 platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices)); 1640 platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices));
1625 1641
1626 rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc_device); 1642 rmobile_add_devices_to_domains(domain_devices,
1627 rmobile_add_device_to_domain(&sh7372_pd_a4lc, &hdmi_lcdc_device); 1643 ARRAY_SIZE(domain_devices));
1628 rmobile_add_device_to_domain(&sh7372_pd_a4lc, &meram_device);
1629 rmobile_add_device_to_domain(&sh7372_pd_a4mp, &fsi_device);
1630 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usbhs0_device);
1631 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usbhs1_device);
1632 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &nand_flash_device);
1633 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sh_mmcif_device);
1634 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi0_device);
1635#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
1636 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi1_device);
1637#endif
1638 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi2_device);
1639 rmobile_add_device_to_domain(&sh7372_pd_a4r, &ceu_device);
1640 1644
1641 hdmi_init_pm_clock(); 1645 hdmi_init_pm_clock();
1642 sh7372_pm_init(); 1646 sh7372_pm_init();
diff --git a/arch/arm/mach-shmobile/common.c b/arch/arm/mach-shmobile/common.c
deleted file mode 100644
index 608aba9d60d7..000000000000
--- a/arch/arm/mach-shmobile/common.c
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 */
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <mach/common.h>
19
20void __init shmobile_init_late(void)
21{
22 shmobile_suspend_init();
23 shmobile_cpuidle_init();
24}
diff --git a/arch/arm/mach-shmobile/cpuidle.c b/arch/arm/mach-shmobile/cpuidle.c
index 7b541e911ab4..9e050268cde4 100644
--- a/arch/arm/mach-shmobile/cpuidle.c
+++ b/arch/arm/mach-shmobile/cpuidle.c
@@ -16,51 +16,38 @@
16#include <asm/cpuidle.h> 16#include <asm/cpuidle.h>
17#include <asm/io.h> 17#include <asm/io.h>
18 18
19static void shmobile_enter_wfi(void) 19int shmobile_enter_wfi(struct cpuidle_device *dev, struct cpuidle_driver *drv,
20 int index)
20{ 21{
21 cpu_do_idle(); 22 cpu_do_idle();
22} 23 return 0;
23
24void (*shmobile_cpuidle_modes[CPUIDLE_STATE_MAX])(void) = {
25 shmobile_enter_wfi, /* regular sleep mode */
26};
27
28static int shmobile_cpuidle_enter(struct cpuidle_device *dev,
29 struct cpuidle_driver *drv,
30 int index)
31{
32 shmobile_cpuidle_modes[index]();
33
34 return index;
35} 24}
36 25
37static struct cpuidle_device shmobile_cpuidle_dev; 26static struct cpuidle_device shmobile_cpuidle_dev;
38static struct cpuidle_driver shmobile_cpuidle_driver = { 27static struct cpuidle_driver shmobile_cpuidle_default_driver = {
39 .name = "shmobile_cpuidle", 28 .name = "shmobile_cpuidle",
40 .owner = THIS_MODULE, 29 .owner = THIS_MODULE,
41 .en_core_tk_irqen = 1, 30 .en_core_tk_irqen = 1,
42 .states[0] = ARM_CPUIDLE_WFI_STATE, 31 .states[0] = ARM_CPUIDLE_WFI_STATE,
32 .states[0].enter = shmobile_enter_wfi,
43 .safe_state_index = 0, /* C1 */ 33 .safe_state_index = 0, /* C1 */
44 .state_count = 1, 34 .state_count = 1,
45}; 35};
46 36
47void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv); 37static struct cpuidle_driver *cpuidle_drv = &shmobile_cpuidle_default_driver;
38
39void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv)
40{
41 cpuidle_drv = drv;
42}
48 43
49int shmobile_cpuidle_init(void) 44int shmobile_cpuidle_init(void)
50{ 45{
51 struct cpuidle_device *dev = &shmobile_cpuidle_dev; 46 struct cpuidle_device *dev = &shmobile_cpuidle_dev;
52 struct cpuidle_driver *drv = &shmobile_cpuidle_driver;
53 int i;
54
55 for (i = 0; i < CPUIDLE_STATE_MAX; i++)
56 drv->states[i].enter = shmobile_cpuidle_enter;
57
58 if (shmobile_cpuidle_setup)
59 shmobile_cpuidle_setup(drv);
60 47
61 cpuidle_register_driver(drv); 48 cpuidle_register_driver(cpuidle_drv);
62 49
63 dev->state_count = drv->state_count; 50 dev->state_count = cpuidle_drv->state_count;
64 cpuidle_register_device(dev); 51 cpuidle_register_device(dev);
65 52
66 return 0; 53 return 0;
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index 45e61dada030..eb89293fff4d 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -14,8 +14,10 @@ extern int shmobile_clk_init(void);
14extern void shmobile_handle_irq_intc(struct pt_regs *); 14extern void shmobile_handle_irq_intc(struct pt_regs *);
15extern struct platform_suspend_ops shmobile_suspend_ops; 15extern struct platform_suspend_ops shmobile_suspend_ops;
16struct cpuidle_driver; 16struct cpuidle_driver;
17extern void (*shmobile_cpuidle_modes[])(void); 17struct cpuidle_device;
18extern void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv); 18extern int shmobile_enter_wfi(struct cpuidle_device *dev,
19 struct cpuidle_driver *drv, int index);
20extern void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv);
19 21
20extern void sh7367_init_irq(void); 22extern void sh7367_init_irq(void);
21extern void sh7367_map_io(void); 23extern void sh7367_map_io(void);
@@ -86,8 +88,6 @@ extern int r8a7779_boot_secondary(unsigned int cpu);
86extern void r8a7779_smp_prepare_cpus(void); 88extern void r8a7779_smp_prepare_cpus(void);
87extern void r8a7779_register_twd(void); 89extern void r8a7779_register_twd(void);
88 90
89extern void shmobile_init_late(void);
90
91#ifdef CONFIG_SUSPEND 91#ifdef CONFIG_SUSPEND
92int shmobile_suspend_init(void); 92int shmobile_suspend_init(void);
93#else 93#else
@@ -100,4 +100,10 @@ int shmobile_cpuidle_init(void);
100static inline int shmobile_cpuidle_init(void) { return 0; } 100static inline int shmobile_cpuidle_init(void) { return 0; }
101#endif 101#endif
102 102
103static inline void shmobile_init_late(void)
104{
105 shmobile_suspend_init();
106 shmobile_cpuidle_init();
107}
108
103#endif /* __ARCH_MACH_COMMON_H */ 109#endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h
index 5a402840fe28..690553a06887 100644
--- a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h
+++ b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h
@@ -12,6 +12,8 @@
12 12
13#include <linux/pm_domain.h> 13#include <linux/pm_domain.h>
14 14
15#define DEFAULT_DEV_LATENCY_NS 250000
16
15struct platform_device; 17struct platform_device;
16 18
17struct rmobile_pm_domain { 19struct rmobile_pm_domain {
@@ -29,16 +31,33 @@ struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d)
29 return container_of(d, struct rmobile_pm_domain, genpd); 31 return container_of(d, struct rmobile_pm_domain, genpd);
30} 32}
31 33
34struct pm_domain_device {
35 const char *domain_name;
36 struct platform_device *pdev;
37};
38
32#ifdef CONFIG_PM 39#ifdef CONFIG_PM
33extern void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd); 40extern void rmobile_init_domains(struct rmobile_pm_domain domains[], int num);
34extern void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd, 41extern void rmobile_add_device_to_domain_td(const char *domain_name,
35 struct platform_device *pdev); 42 struct platform_device *pdev,
36extern void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd, 43 struct gpd_timing_data *td);
37 struct rmobile_pm_domain *rmobile_sd); 44
45static inline void rmobile_add_device_to_domain(const char *domain_name,
46 struct platform_device *pdev)
47{
48 rmobile_add_device_to_domain_td(domain_name, pdev, NULL);
49}
50
51extern void rmobile_add_devices_to_domains(struct pm_domain_device data[],
52 int size);
38#else 53#else
39#define rmobile_init_pm_domain(pd) do { } while (0) 54
40#define rmobile_add_device_to_domain(pd, pdev) do { } while (0) 55#define rmobile_init_domains(domains, num) do { } while (0)
41#define rmobile_pm_add_subdomain(pd, sd) do { } while (0) 56#define rmobile_add_device_to_domain_td(name, pdev, td) do { } while (0)
57#define rmobile_add_device_to_domain(name, pdev) do { } while (0)
58
59static inline void rmobile_add_devices_to_domains(struct pm_domain_device d[],
60 int size) {}
42#endif /* CONFIG_PM */ 61#endif /* CONFIG_PM */
43 62
44#endif /* PM_RMOBILE_H */ 63#endif /* PM_RMOBILE_H */
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h
index 7143147780df..59d252f4cf97 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7740.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h
@@ -607,9 +607,9 @@ enum {
607}; 607};
608 608
609#ifdef CONFIG_PM 609#ifdef CONFIG_PM
610extern struct rmobile_pm_domain r8a7740_pd_a4s; 610extern void __init r8a7740_init_pm_domains(void);
611extern struct rmobile_pm_domain r8a7740_pd_a3sp; 611#else
612extern struct rmobile_pm_domain r8a7740_pd_a4lc; 612static inline void r8a7740_init_pm_domains(void) {}
613#endif /* CONFIG_PM */ 613#endif /* CONFIG_PM */
614 614
615#endif /* __ASM_R8A7740_H__ */ 615#endif /* __ASM_R8A7740_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h
index b07ad318eb2e..7ad47977d2e7 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7779.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h
@@ -347,17 +347,9 @@ extern int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch);
347extern int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch); 347extern int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch);
348 348
349#ifdef CONFIG_PM 349#ifdef CONFIG_PM
350extern struct r8a7779_pm_domain r8a7779_sh4a; 350extern void __init r8a7779_init_pm_domains(void);
351extern struct r8a7779_pm_domain r8a7779_sgx;
352extern struct r8a7779_pm_domain r8a7779_vdp1;
353extern struct r8a7779_pm_domain r8a7779_impx3;
354
355extern void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd);
356extern void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd,
357 struct platform_device *pdev);
358#else 351#else
359#define r8a7779_init_pm_domain(pd) do { } while (0) 352static inline void r8a7779_init_pm_domains(void) {}
360#define r8a7779_add_device_to_domain(pd, pdev) do { } while (0)
361#endif /* CONFIG_PM */ 353#endif /* CONFIG_PM */
362 354
363#endif /* __ASM_R8A7779_H__ */ 355#endif /* __ASM_R8A7779_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index b59048e6d8fd..40beb796d020 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -478,21 +478,15 @@ extern struct clk sh7372_fsibck_clk;
478extern struct clk sh7372_fsidiva_clk; 478extern struct clk sh7372_fsidiva_clk;
479extern struct clk sh7372_fsidivb_clk; 479extern struct clk sh7372_fsidivb_clk;
480 480
481#ifdef CONFIG_PM
482extern struct rmobile_pm_domain sh7372_pd_a4lc;
483extern struct rmobile_pm_domain sh7372_pd_a4mp;
484extern struct rmobile_pm_domain sh7372_pd_d4;
485extern struct rmobile_pm_domain sh7372_pd_a4r;
486extern struct rmobile_pm_domain sh7372_pd_a3rv;
487extern struct rmobile_pm_domain sh7372_pd_a3ri;
488extern struct rmobile_pm_domain sh7372_pd_a4s;
489extern struct rmobile_pm_domain sh7372_pd_a3sp;
490extern struct rmobile_pm_domain sh7372_pd_a3sg;
491#endif /* CONFIG_PM */
492
493extern void sh7372_intcs_suspend(void); 481extern void sh7372_intcs_suspend(void);
494extern void sh7372_intcs_resume(void); 482extern void sh7372_intcs_resume(void);
495extern void sh7372_intca_suspend(void); 483extern void sh7372_intca_suspend(void);
496extern void sh7372_intca_resume(void); 484extern void sh7372_intca_resume(void);
497 485
486#ifdef CONFIG_PM
487extern void __init sh7372_init_pm_domains(void);
488#else
489static inline void sh7372_init_pm_domains(void) {}
490#endif
491
498#endif /* __ASM_SH7372_H__ */ 492#endif /* __ASM_SH7372_H__ */
diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c
index 893504d012a6..21e5316d2d88 100644
--- a/arch/arm/mach-shmobile/pm-r8a7740.c
+++ b/arch/arm/mach-shmobile/pm-r8a7740.c
@@ -21,14 +21,6 @@ static int r8a7740_pd_a4s_suspend(void)
21 return -EBUSY; 21 return -EBUSY;
22} 22}
23 23
24struct rmobile_pm_domain r8a7740_pd_a4s = {
25 .genpd.name = "A4S",
26 .bit_shift = 10,
27 .gov = &pm_domain_always_on_gov,
28 .no_debug = true,
29 .suspend = r8a7740_pd_a4s_suspend,
30};
31
32static int r8a7740_pd_a3sp_suspend(void) 24static int r8a7740_pd_a3sp_suspend(void)
33{ 25{
34 /* 26 /*
@@ -38,17 +30,31 @@ static int r8a7740_pd_a3sp_suspend(void)
38 return console_suspend_enabled ? 0 : -EBUSY; 30 return console_suspend_enabled ? 0 : -EBUSY;
39} 31}
40 32
41struct rmobile_pm_domain r8a7740_pd_a3sp = { 33static struct rmobile_pm_domain r8a7740_pm_domains[] = {
42 .genpd.name = "A3SP", 34 {
43 .bit_shift = 11, 35 .genpd.name = "A4S",
44 .gov = &pm_domain_always_on_gov, 36 .bit_shift = 10,
45 .no_debug = true, 37 .gov = &pm_domain_always_on_gov,
46 .suspend = r8a7740_pd_a3sp_suspend, 38 .no_debug = true,
39 .suspend = r8a7740_pd_a4s_suspend,
40 },
41 {
42 .genpd.name = "A3SP",
43 .bit_shift = 11,
44 .gov = &pm_domain_always_on_gov,
45 .no_debug = true,
46 .suspend = r8a7740_pd_a3sp_suspend,
47 },
48 {
49 .genpd.name = "A4LC",
50 .bit_shift = 1,
51 },
47}; 52};
48 53
49struct rmobile_pm_domain r8a7740_pd_a4lc = { 54void __init r8a7740_init_pm_domains(void)
50 .genpd.name = "A4LC", 55{
51 .bit_shift = 1, 56 rmobile_init_domains(r8a7740_pm_domains, ARRAY_SIZE(r8a7740_pm_domains));
52}; 57 pm_genpd_add_subdomain_names("A4S", "A3SP");
58}
53 59
54#endif /* CONFIG_PM */ 60#endif /* CONFIG_PM */
diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c
index a18a4ae16d2b..d50a8e9b94a4 100644
--- a/arch/arm/mach-shmobile/pm-r8a7779.c
+++ b/arch/arm/mach-shmobile/pm-r8a7779.c
@@ -183,7 +183,7 @@ static bool pd_active_wakeup(struct device *dev)
183 return true; 183 return true;
184} 184}
185 185
186void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd) 186static void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd)
187{ 187{
188 struct generic_pm_domain *genpd = &r8a7779_pd->genpd; 188 struct generic_pm_domain *genpd = &r8a7779_pd->genpd;
189 189
@@ -199,43 +199,44 @@ void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd)
199 pd_power_up(&r8a7779_pd->genpd); 199 pd_power_up(&r8a7779_pd->genpd);
200} 200}
201 201
202void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd, 202static struct r8a7779_pm_domain r8a7779_pm_domains[] = {
203 struct platform_device *pdev) 203 {
204{ 204 .genpd.name = "SH4A",
205 struct device *dev = &pdev->dev; 205 .ch = {
206 206 .chan_offs = 0x80, /* PWRSR1 .. PWRER1 */
207 pm_genpd_add_device(&r8a7779_pd->genpd, dev); 207 .isr_bit = 16, /* SH4A */
208 if (pm_clk_no_clocks(dev)) 208 },
209 pm_clk_add(dev, NULL); 209 },
210} 210 {
211 211 .genpd.name = "SGX",
212struct r8a7779_pm_domain r8a7779_sh4a = { 212 .ch = {
213 .ch = { 213 .chan_offs = 0xc0, /* PWRSR2 .. PWRER2 */
214 .chan_offs = 0x80, /* PWRSR1 .. PWRER1 */ 214 .isr_bit = 20, /* SGX */
215 .isr_bit = 16, /* SH4A */ 215 },
216 } 216 },
217}; 217 {
218 218 .genpd.name = "VDP1",
219struct r8a7779_pm_domain r8a7779_sgx = { 219 .ch = {
220 .ch = { 220 .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */
221 .chan_offs = 0xc0, /* PWRSR2 .. PWRER2 */ 221 .isr_bit = 21, /* VDP */
222 .isr_bit = 20, /* SGX */ 222 },
223 } 223 },
224 {
225 .genpd.name = "IMPX3",
226 .ch = {
227 .chan_offs = 0x140, /* PWRSR4 .. PWRER4 */
228 .isr_bit = 24, /* IMP */
229 },
230 },
224}; 231};
225 232
226struct r8a7779_pm_domain r8a7779_vdp1 = { 233void __init r8a7779_init_pm_domains(void)
227 .ch = { 234{
228 .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */ 235 int j;
229 .isr_bit = 21, /* VDP */
230 }
231};
232 236
233struct r8a7779_pm_domain r8a7779_impx3 = { 237 for (j = 0; j < ARRAY_SIZE(r8a7779_pm_domains); j++)
234 .ch = { 238 r8a7779_init_pm_domain(&r8a7779_pm_domains[j]);
235 .chan_offs = 0x140, /* PWRSR4 .. PWRER4 */ 239}
236 .isr_bit = 24, /* IMP */
237 }
238};
239 240
240#endif /* CONFIG_PM */ 241#endif /* CONFIG_PM */
241 242
diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c
index a8562540f1d6..d37d368434da 100644
--- a/arch/arm/mach-shmobile/pm-rmobile.c
+++ b/arch/arm/mach-shmobile/pm-rmobile.c
@@ -134,7 +134,7 @@ static int rmobile_pd_start_dev(struct device *dev)
134 return ret; 134 return ret;
135} 135}
136 136
137void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) 137static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
138{ 138{
139 struct generic_pm_domain *genpd = &rmobile_pd->genpd; 139 struct generic_pm_domain *genpd = &rmobile_pd->genpd;
140 struct dev_power_governor *gov = rmobile_pd->gov; 140 struct dev_power_governor *gov = rmobile_pd->gov;
@@ -149,19 +149,38 @@ void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
149 __rmobile_pd_power_up(rmobile_pd, false); 149 __rmobile_pd_power_up(rmobile_pd, false);
150} 150}
151 151
152void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd, 152void rmobile_init_domains(struct rmobile_pm_domain domains[], int num)
153 struct platform_device *pdev) 153{
154 int j;
155
156 for (j = 0; j < num; j++)
157 rmobile_init_pm_domain(&domains[j]);
158}
159
160void rmobile_add_device_to_domain_td(const char *domain_name,
161 struct platform_device *pdev,
162 struct gpd_timing_data *td)
154{ 163{
155 struct device *dev = &pdev->dev; 164 struct device *dev = &pdev->dev;
156 165
157 pm_genpd_add_device(&rmobile_pd->genpd, dev); 166 __pm_genpd_name_add_device(domain_name, dev, td);
158 if (pm_clk_no_clocks(dev)) 167 if (pm_clk_no_clocks(dev))
159 pm_clk_add(dev, NULL); 168 pm_clk_add(dev, NULL);
160} 169}
161 170
162void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd, 171void rmobile_add_devices_to_domains(struct pm_domain_device data[],
163 struct rmobile_pm_domain *rmobile_sd) 172 int size)
164{ 173{
165 pm_genpd_add_subdomain(&rmobile_pd->genpd, &rmobile_sd->genpd); 174 struct gpd_timing_data latencies = {
175 .stop_latency_ns = DEFAULT_DEV_LATENCY_NS,
176 .start_latency_ns = DEFAULT_DEV_LATENCY_NS,
177 .save_state_latency_ns = DEFAULT_DEV_LATENCY_NS,
178 .restore_state_latency_ns = DEFAULT_DEV_LATENCY_NS,
179 };
180 int j;
181
182 for (j = 0; j < size; j++)
183 rmobile_add_device_to_domain_td(data[j].domain_name,
184 data[j].pdev, &latencies);
166} 185}
167#endif /* CONFIG_PM */ 186#endif /* CONFIG_PM */
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c
index 792037069226..5cafd35cc411 100644
--- a/arch/arm/mach-shmobile/pm-sh7372.c
+++ b/arch/arm/mach-shmobile/pm-sh7372.c
@@ -21,6 +21,7 @@
21#include <linux/irq.h> 21#include <linux/irq.h>
22#include <linux/bitrev.h> 22#include <linux/bitrev.h>
23#include <linux/console.h> 23#include <linux/console.h>
24#include <asm/cpuidle.h>
24#include <asm/io.h> 25#include <asm/io.h>
25#include <asm/tlbflush.h> 26#include <asm/tlbflush.h>
26#include <asm/suspend.h> 27#include <asm/suspend.h>
@@ -71,20 +72,7 @@
71 72
72#ifdef CONFIG_PM 73#ifdef CONFIG_PM
73 74
74struct rmobile_pm_domain sh7372_pd_a4lc = { 75#define PM_DOMAIN_ON_OFF_LATENCY_NS 250000
75 .genpd.name = "A4LC",
76 .bit_shift = 1,
77};
78
79struct rmobile_pm_domain sh7372_pd_a4mp = {
80 .genpd.name = "A4MP",
81 .bit_shift = 2,
82};
83
84struct rmobile_pm_domain sh7372_pd_d4 = {
85 .genpd.name = "D4",
86 .bit_shift = 3,
87};
88 76
89static int sh7372_a4r_pd_suspend(void) 77static int sh7372_a4r_pd_suspend(void)
90{ 78{
@@ -93,39 +81,25 @@ static int sh7372_a4r_pd_suspend(void)
93 return 0; 81 return 0;
94} 82}
95 83
96struct rmobile_pm_domain sh7372_pd_a4r = { 84static bool a4s_suspend_ready;
97 .genpd.name = "A4R",
98 .bit_shift = 5,
99 .suspend = sh7372_a4r_pd_suspend,
100 .resume = sh7372_intcs_resume,
101};
102
103struct rmobile_pm_domain sh7372_pd_a3rv = {
104 .genpd.name = "A3RV",
105 .bit_shift = 6,
106};
107
108struct rmobile_pm_domain sh7372_pd_a3ri = {
109 .genpd.name = "A3RI",
110 .bit_shift = 8,
111};
112 85
113static int sh7372_pd_a4s_suspend(void) 86static int sh7372_a4s_pd_suspend(void)
114{ 87{
115 /* 88 /*
116 * The A4S domain contains the CPU core and therefore it should 89 * The A4S domain contains the CPU core and therefore it should
117 * only be turned off if the CPU is in use. 90 * only be turned off if the CPU is not in use. This may happen
91 * during system suspend, when SYSC is going to be used for generating
92 * resume signals and a4s_suspend_ready is set to let
93 * sh7372_enter_suspend() know that it can turn A4S off.
118 */ 94 */
95 a4s_suspend_ready = true;
119 return -EBUSY; 96 return -EBUSY;
120} 97}
121 98
122struct rmobile_pm_domain sh7372_pd_a4s = { 99static void sh7372_a4s_pd_resume(void)
123 .genpd.name = "A4S", 100{
124 .bit_shift = 10, 101 a4s_suspend_ready = false;
125 .gov = &pm_domain_always_on_gov, 102}
126 .no_debug = true,
127 .suspend = sh7372_pd_a4s_suspend,
128};
129 103
130static int sh7372_a3sp_pd_suspend(void) 104static int sh7372_a3sp_pd_suspend(void)
131{ 105{
@@ -136,18 +110,80 @@ static int sh7372_a3sp_pd_suspend(void)
136 return console_suspend_enabled ? 0 : -EBUSY; 110 return console_suspend_enabled ? 0 : -EBUSY;
137} 111}
138 112
139struct rmobile_pm_domain sh7372_pd_a3sp = { 113static struct rmobile_pm_domain sh7372_pm_domains[] = {
140 .genpd.name = "A3SP", 114 {
141 .bit_shift = 11, 115 .genpd.name = "A4LC",
142 .gov = &pm_domain_always_on_gov, 116 .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
143 .no_debug = true, 117 .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
144 .suspend = sh7372_a3sp_pd_suspend, 118 .bit_shift = 1,
119 },
120 {
121 .genpd.name = "A4MP",
122 .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
123 .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
124 .bit_shift = 2,
125 },
126 {
127 .genpd.name = "D4",
128 .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
129 .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
130 .bit_shift = 3,
131 },
132 {
133 .genpd.name = "A4R",
134 .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
135 .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
136 .bit_shift = 5,
137 .suspend = sh7372_a4r_pd_suspend,
138 .resume = sh7372_intcs_resume,
139 },
140 {
141 .genpd.name = "A3RV",
142 .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
143 .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
144 .bit_shift = 6,
145 },
146 {
147 .genpd.name = "A3RI",
148 .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
149 .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
150 .bit_shift = 8,
151 },
152 {
153 .genpd.name = "A4S",
154 .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
155 .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
156 .bit_shift = 10,
157 .gov = &pm_domain_always_on_gov,
158 .no_debug = true,
159 .suspend = sh7372_a4s_pd_suspend,
160 .resume = sh7372_a4s_pd_resume,
161 },
162 {
163 .genpd.name = "A3SP",
164 .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
165 .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
166 .bit_shift = 11,
167 .gov = &pm_domain_always_on_gov,
168 .no_debug = true,
169 .suspend = sh7372_a3sp_pd_suspend,
170 },
171 {
172 .genpd.name = "A3SG",
173 .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
174 .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
175 .bit_shift = 13,
176 },
145}; 177};
146 178
147struct rmobile_pm_domain sh7372_pd_a3sg = { 179void __init sh7372_init_pm_domains(void)
148 .genpd.name = "A3SG", 180{
149 .bit_shift = 13, 181 rmobile_init_domains(sh7372_pm_domains, ARRAY_SIZE(sh7372_pm_domains));
150}; 182 pm_genpd_add_subdomain_names("A4LC", "A3RV");
183 pm_genpd_add_subdomain_names("A4R", "A4LC");
184 pm_genpd_add_subdomain_names("A4S", "A3SG");
185 pm_genpd_add_subdomain_names("A4S", "A3SP");
186}
151 187
152#endif /* CONFIG_PM */ 188#endif /* CONFIG_PM */
153 189
@@ -312,7 +348,8 @@ static int sh7372_do_idle_core_standby(unsigned long unused)
312 return 0; 348 return 0;
313} 349}
314 350
315static void sh7372_enter_core_standby(void) 351static int sh7372_enter_core_standby(struct cpuidle_device *dev,
352 struct cpuidle_driver *drv, int index)
316{ 353{
317 sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc)); 354 sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc));
318 355
@@ -323,52 +360,61 @@ static void sh7372_enter_core_standby(void)
323 360
324 /* disable reset vector translation */ 361 /* disable reset vector translation */
325 __raw_writel(0, SBAR); 362 __raw_writel(0, SBAR);
363
364 return 1;
326} 365}
327 366
328static void sh7372_enter_a3sm_pll_on(void) 367static int sh7372_enter_a3sm_pll_on(struct cpuidle_device *dev,
368 struct cpuidle_driver *drv, int index)
329{ 369{
330 sh7372_enter_a3sm_common(1); 370 sh7372_enter_a3sm_common(1);
371 return 2;
331} 372}
332 373
333static void sh7372_enter_a3sm_pll_off(void) 374static int sh7372_enter_a3sm_pll_off(struct cpuidle_device *dev,
375 struct cpuidle_driver *drv, int index)
334{ 376{
335 sh7372_enter_a3sm_common(0); 377 sh7372_enter_a3sm_common(0);
378 return 3;
336} 379}
337 380
338static void sh7372_cpuidle_setup(struct cpuidle_driver *drv) 381static struct cpuidle_driver sh7372_cpuidle_driver = {
339{ 382 .name = "sh7372_cpuidle",
340 struct cpuidle_state *state = &drv->states[drv->state_count]; 383 .owner = THIS_MODULE,
341 384 .en_core_tk_irqen = 1,
342 snprintf(state->name, CPUIDLE_NAME_LEN, "C2"); 385 .state_count = 4,
343 strncpy(state->desc, "Core Standby Mode", CPUIDLE_DESC_LEN); 386 .safe_state_index = 0, /* C1 */
344 state->exit_latency = 10; 387 .states[0] = ARM_CPUIDLE_WFI_STATE,
345 state->target_residency = 20 + 10; 388 .states[0].enter = shmobile_enter_wfi,
346 state->flags = CPUIDLE_FLAG_TIME_VALID; 389 .states[1] = {
347 shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_core_standby; 390 .name = "C2",
348 drv->state_count++; 391 .desc = "Core Standby Mode",
349 392 .exit_latency = 10,
350 state = &drv->states[drv->state_count]; 393 .target_residency = 20 + 10,
351 snprintf(state->name, CPUIDLE_NAME_LEN, "C3"); 394 .flags = CPUIDLE_FLAG_TIME_VALID,
352 strncpy(state->desc, "A3SM PLL ON", CPUIDLE_DESC_LEN); 395 .enter = sh7372_enter_core_standby,
353 state->exit_latency = 20; 396 },
354 state->target_residency = 30 + 20; 397 .states[2] = {
355 state->flags = CPUIDLE_FLAG_TIME_VALID; 398 .name = "C3",
356 shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_on; 399 .desc = "A3SM PLL ON",
357 drv->state_count++; 400 .exit_latency = 20,
358 401 .target_residency = 30 + 20,
359 state = &drv->states[drv->state_count]; 402 .flags = CPUIDLE_FLAG_TIME_VALID,
360 snprintf(state->name, CPUIDLE_NAME_LEN, "C4"); 403 .enter = sh7372_enter_a3sm_pll_on,
361 strncpy(state->desc, "A3SM PLL OFF", CPUIDLE_DESC_LEN); 404 },
362 state->exit_latency = 120; 405 .states[3] = {
363 state->target_residency = 30 + 120; 406 .name = "C4",
364 state->flags = CPUIDLE_FLAG_TIME_VALID; 407 .desc = "A3SM PLL OFF",
365 shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_off; 408 .exit_latency = 120,
366 drv->state_count++; 409 .target_residency = 30 + 120,
367} 410 .flags = CPUIDLE_FLAG_TIME_VALID,
411 .enter = sh7372_enter_a3sm_pll_off,
412 },
413};
368 414
369static void sh7372_cpuidle_init(void) 415static void sh7372_cpuidle_init(void)
370{ 416{
371 shmobile_cpuidle_setup = sh7372_cpuidle_setup; 417 shmobile_cpuidle_set_driver(&sh7372_cpuidle_driver);
372} 418}
373#else 419#else
374static void sh7372_cpuidle_init(void) {} 420static void sh7372_cpuidle_init(void) {}
@@ -389,17 +435,14 @@ static int sh7372_enter_suspend(suspend_state_t suspend_state)
389 unsigned long msk, msk2; 435 unsigned long msk, msk2;
390 436
391 /* check active clocks to determine potential wakeup sources */ 437 /* check active clocks to determine potential wakeup sources */
392 if (sh7372_sysc_valid(&msk, &msk2)) { 438 if (sh7372_sysc_valid(&msk, &msk2) && a4s_suspend_ready) {
393 if (!console_suspend_enabled && 439 /* convert INTC mask/sense to SYSC mask/sense */
394 sh7372_pd_a4s.genpd.status == GPD_STATE_POWER_OFF) { 440 sh7372_setup_sysc(msk, msk2);
395 /* convert INTC mask/sense to SYSC mask/sense */ 441
396 sh7372_setup_sysc(msk, msk2); 442 /* enter A4S sleep with PLLC0 off */
397 443 pr_debug("entering A4S\n");
398 /* enter A4S sleep with PLLC0 off */ 444 sh7372_enter_a4s_common(0);
399 pr_debug("entering A4S\n"); 445 return 0;
400 sh7372_enter_a4s_common(0);
401 return 0;
402 }
403 } 446 }
404 447
405 /* default to enter A3SM sleep with PLLC0 off */ 448 /* default to enter A3SM sleep with PLLC0 off */
@@ -425,7 +468,7 @@ static int sh7372_pm_notifier_fn(struct notifier_block *notifier,
425 * executed during system suspend and resume, respectively, so 468 * executed during system suspend and resume, respectively, so
426 * that those functions don't crash while accessing the INTCS. 469 * that those functions don't crash while accessing the INTCS.
427 */ 470 */
428 pm_genpd_poweron(&sh7372_pd_a4r.genpd); 471 pm_genpd_name_poweron("A4R");
429 break; 472 break;
430 case PM_POST_SUSPEND: 473 case PM_POST_SUSPEND:
431 pm_genpd_poweroff_unused(); 474 pm_genpd_poweroff_unused();
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 78948a9dba0e..11bb1d984197 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -673,12 +673,7 @@ void __init r8a7740_add_standard_devices(void)
673 r8a7740_i2c_workaround(&i2c0_device); 673 r8a7740_i2c_workaround(&i2c0_device);
674 r8a7740_i2c_workaround(&i2c1_device); 674 r8a7740_i2c_workaround(&i2c1_device);
675 675
676 /* PM domain */ 676 r8a7740_init_pm_domains();
677 rmobile_init_pm_domain(&r8a7740_pd_a4s);
678 rmobile_init_pm_domain(&r8a7740_pd_a3sp);
679 rmobile_init_pm_domain(&r8a7740_pd_a4lc);
680
681 rmobile_pm_add_subdomain(&r8a7740_pd_a4s, &r8a7740_pd_a3sp);
682 677
683 /* add devices */ 678 /* add devices */
684 platform_add_devices(r8a7740_early_devices, 679 platform_add_devices(r8a7740_early_devices,
@@ -688,16 +683,16 @@ void __init r8a7740_add_standard_devices(void)
688 683
689 /* add devices to PM domain */ 684 /* add devices to PM domain */
690 685
691 rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif0_device); 686 rmobile_add_device_to_domain("A3SP", &scif0_device);
692 rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif1_device); 687 rmobile_add_device_to_domain("A3SP", &scif1_device);
693 rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif2_device); 688 rmobile_add_device_to_domain("A3SP", &scif2_device);
694 rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif3_device); 689 rmobile_add_device_to_domain("A3SP", &scif3_device);
695 rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif4_device); 690 rmobile_add_device_to_domain("A3SP", &scif4_device);
696 rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif5_device); 691 rmobile_add_device_to_domain("A3SP", &scif5_device);
697 rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif6_device); 692 rmobile_add_device_to_domain("A3SP", &scif6_device);
698 rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif7_device); 693 rmobile_add_device_to_domain("A3SP", &scif7_device);
699 rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scifb_device); 694 rmobile_add_device_to_domain("A3SP", &scifb_device);
700 rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &i2c1_device); 695 rmobile_add_device_to_domain("A3SP", &i2c1_device);
701} 696}
702 697
703static void __init r8a7740_earlytimer_init(void) 698static void __init r8a7740_earlytimer_init(void)
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index e98e46f6cf55..2917668f0091 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -251,10 +251,7 @@ void __init r8a7779_add_standard_devices(void)
251#endif 251#endif
252 r8a7779_pm_init(); 252 r8a7779_pm_init();
253 253
254 r8a7779_init_pm_domain(&r8a7779_sh4a); 254 r8a7779_init_pm_domains();
255 r8a7779_init_pm_domain(&r8a7779_sgx);
256 r8a7779_init_pm_domain(&r8a7779_vdp1);
257 r8a7779_init_pm_domain(&r8a7779_impx3);
258 255
259 platform_add_devices(r8a7779_early_devices, 256 platform_add_devices(r8a7779_early_devices,
260 ARRAY_SIZE(r8a7779_early_devices)); 257 ARRAY_SIZE(r8a7779_early_devices));
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index 838a87be1d5c..a07954fbcd22 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -1001,21 +1001,34 @@ static struct platform_device *sh7372_late_devices[] __initdata = {
1001 1001
1002void __init sh7372_add_standard_devices(void) 1002void __init sh7372_add_standard_devices(void)
1003{ 1003{
1004 rmobile_init_pm_domain(&sh7372_pd_a4lc); 1004 struct pm_domain_device domain_devices[] = {
1005 rmobile_init_pm_domain(&sh7372_pd_a4mp); 1005 { "A3RV", &vpu_device, },
1006 rmobile_init_pm_domain(&sh7372_pd_d4); 1006 { "A4MP", &spu0_device, },
1007 rmobile_init_pm_domain(&sh7372_pd_a4r); 1007 { "A4MP", &spu1_device, },
1008 rmobile_init_pm_domain(&sh7372_pd_a3rv); 1008 { "A3SP", &scif0_device, },
1009 rmobile_init_pm_domain(&sh7372_pd_a3ri); 1009 { "A3SP", &scif1_device, },
1010 rmobile_init_pm_domain(&sh7372_pd_a4s); 1010 { "A3SP", &scif2_device, },
1011 rmobile_init_pm_domain(&sh7372_pd_a3sp); 1011 { "A3SP", &scif3_device, },
1012 rmobile_init_pm_domain(&sh7372_pd_a3sg); 1012 { "A3SP", &scif4_device, },
1013 1013 { "A3SP", &scif5_device, },
1014 rmobile_pm_add_subdomain(&sh7372_pd_a4lc, &sh7372_pd_a3rv); 1014 { "A3SP", &scif6_device, },
1015 rmobile_pm_add_subdomain(&sh7372_pd_a4r, &sh7372_pd_a4lc); 1015 { "A3SP", &iic1_device, },
1016 1016 { "A3SP", &dma0_device, },
1017 rmobile_pm_add_subdomain(&sh7372_pd_a4s, &sh7372_pd_a3sg); 1017 { "A3SP", &dma1_device, },
1018 rmobile_pm_add_subdomain(&sh7372_pd_a4s, &sh7372_pd_a3sp); 1018 { "A3SP", &dma2_device, },
1019 { "A3SP", &usb_dma0_device, },
1020 { "A3SP", &usb_dma1_device, },
1021 { "A4R", &iic0_device, },
1022 { "A4R", &veu0_device, },
1023 { "A4R", &veu1_device, },
1024 { "A4R", &veu2_device, },
1025 { "A4R", &veu3_device, },
1026 { "A4R", &jpu_device, },
1027 { "A4R", &tmu00_device, },
1028 { "A4R", &tmu01_device, },
1029 };
1030
1031 sh7372_init_pm_domains();
1019 1032
1020 platform_add_devices(sh7372_early_devices, 1033 platform_add_devices(sh7372_early_devices,
1021 ARRAY_SIZE(sh7372_early_devices)); 1034 ARRAY_SIZE(sh7372_early_devices));
@@ -1023,30 +1036,8 @@ void __init sh7372_add_standard_devices(void)
1023 platform_add_devices(sh7372_late_devices, 1036 platform_add_devices(sh7372_late_devices,
1024 ARRAY_SIZE(sh7372_late_devices)); 1037 ARRAY_SIZE(sh7372_late_devices));
1025 1038
1026 rmobile_add_device_to_domain(&sh7372_pd_a3rv, &vpu_device); 1039 rmobile_add_devices_to_domains(domain_devices,
1027 rmobile_add_device_to_domain(&sh7372_pd_a4mp, &spu0_device); 1040 ARRAY_SIZE(domain_devices));
1028 rmobile_add_device_to_domain(&sh7372_pd_a4mp, &spu1_device);
1029 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif0_device);
1030 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif1_device);
1031 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif2_device);
1032 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif3_device);
1033 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif4_device);
1034 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif5_device);
1035 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif6_device);
1036 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &iic1_device);
1037 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma0_device);
1038 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma1_device);
1039 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma2_device);
1040 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usb_dma0_device);
1041 rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usb_dma1_device);
1042 rmobile_add_device_to_domain(&sh7372_pd_a4r, &iic0_device);
1043 rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu0_device);
1044 rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu1_device);
1045 rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu2_device);
1046 rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu3_device);
1047 rmobile_add_device_to_domain(&sh7372_pd_a4r, &jpu_device);
1048 rmobile_add_device_to_domain(&sh7372_pd_a4r, &tmu00_device);
1049 rmobile_add_device_to_domain(&sh7372_pd_a4r, &tmu01_device);
1050} 1041}
1051 1042
1052static void __init sh7372_earlytimer_init(void) 1043static void __init sh7372_earlytimer_init(void)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index a1a722502587..d51514b79efe 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -22,6 +22,7 @@
22#include <linux/pm_runtime.h> 22#include <linux/pm_runtime.h>
23 23
24#include "base.h" 24#include "base.h"
25#include "power/power.h"
25 26
26#define to_platform_driver(drv) (container_of((drv), struct platform_driver, \ 27#define to_platform_driver(drv) (container_of((drv), struct platform_driver, \
27 driver)) 28 driver))
@@ -948,6 +949,7 @@ void __init early_platform_add_devices(struct platform_device **devs, int num)
948 dev = &devs[i]->dev; 949 dev = &devs[i]->dev;
949 950
950 if (!dev->devres_head.next) { 951 if (!dev->devres_head.next) {
952 pm_runtime_early_init(dev);
951 INIT_LIST_HEAD(&dev->devres_head); 953 INIT_LIST_HEAD(&dev->devres_head);
952 list_add_tail(&dev->devres_head, 954 list_add_tail(&dev->devres_head,
953 &early_platform_device_list); 955 &early_platform_device_list);
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index ba3487c9835b..12ad070c244f 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -53,6 +53,24 @@
53static LIST_HEAD(gpd_list); 53static LIST_HEAD(gpd_list);
54static DEFINE_MUTEX(gpd_list_lock); 54static DEFINE_MUTEX(gpd_list_lock);
55 55
56static struct generic_pm_domain *pm_genpd_lookup_name(const char *domain_name)
57{
58 struct generic_pm_domain *genpd = NULL, *gpd;
59
60 if (IS_ERR_OR_NULL(domain_name))
61 return NULL;
62
63 mutex_lock(&gpd_list_lock);
64 list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
65 if (!strcmp(gpd->name, domain_name)) {
66 genpd = gpd;
67 break;
68 }
69 }
70 mutex_unlock(&gpd_list_lock);
71 return genpd;
72}
73
56#ifdef CONFIG_PM 74#ifdef CONFIG_PM
57 75
58struct generic_pm_domain *dev_to_genpd(struct device *dev) 76struct generic_pm_domain *dev_to_genpd(struct device *dev)
@@ -75,6 +93,12 @@ static int genpd_start_dev(struct generic_pm_domain *genpd, struct device *dev)
75 start_latency_ns, "start"); 93 start_latency_ns, "start");
76} 94}
77 95
96static int genpd_start_dev_no_timing(struct generic_pm_domain *genpd,
97 struct device *dev)
98{
99 return GENPD_DEV_CALLBACK(genpd, int, start, dev);
100}
101
78static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd) 102static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd)
79{ 103{
80 bool ret = false; 104 bool ret = false;
@@ -256,6 +280,18 @@ int pm_genpd_poweron(struct generic_pm_domain *genpd)
256 return ret; 280 return ret;
257} 281}
258 282
283/**
284 * pm_genpd_name_poweron - Restore power to a given PM domain and its masters.
285 * @domain_name: Name of the PM domain to power up.
286 */
287int pm_genpd_name_poweron(const char *domain_name)
288{
289 struct generic_pm_domain *genpd;
290
291 genpd = pm_genpd_lookup_name(domain_name);
292 return genpd ? pm_genpd_poweron(genpd) : -EINVAL;
293}
294
259#endif /* CONFIG_PM */ 295#endif /* CONFIG_PM */
260 296
261#ifdef CONFIG_PM_RUNTIME 297#ifdef CONFIG_PM_RUNTIME
@@ -436,7 +472,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
436 not_suspended = 0; 472 not_suspended = 0;
437 list_for_each_entry(pdd, &genpd->dev_list, list_node) 473 list_for_each_entry(pdd, &genpd->dev_list, list_node)
438 if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev) 474 if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev)
439 || pdd->dev->power.irq_safe || to_gpd_data(pdd)->always_on)) 475 || pdd->dev->power.irq_safe))
440 not_suspended++; 476 not_suspended++;
441 477
442 if (not_suspended > genpd->in_progress) 478 if (not_suspended > genpd->in_progress)
@@ -578,9 +614,6 @@ static int pm_genpd_runtime_suspend(struct device *dev)
578 614
579 might_sleep_if(!genpd->dev_irq_safe); 615 might_sleep_if(!genpd->dev_irq_safe);
580 616
581 if (dev_gpd_data(dev)->always_on)
582 return -EBUSY;
583
584 stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL; 617 stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL;
585 if (stop_ok && !stop_ok(dev)) 618 if (stop_ok && !stop_ok(dev))
586 return -EBUSY; 619 return -EBUSY;
@@ -629,7 +662,7 @@ static int pm_genpd_runtime_resume(struct device *dev)
629 662
630 /* If power.irq_safe, the PM domain is never powered off. */ 663 /* If power.irq_safe, the PM domain is never powered off. */
631 if (dev->power.irq_safe) 664 if (dev->power.irq_safe)
632 return genpd_start_dev(genpd, dev); 665 return genpd_start_dev_no_timing(genpd, dev);
633 666
634 mutex_lock(&genpd->lock); 667 mutex_lock(&genpd->lock);
635 ret = __pm_genpd_poweron(genpd); 668 ret = __pm_genpd_poweron(genpd);
@@ -697,6 +730,24 @@ static inline void genpd_power_off_work_fn(struct work_struct *work) {}
697 730
698#ifdef CONFIG_PM_SLEEP 731#ifdef CONFIG_PM_SLEEP
699 732
733/**
734 * pm_genpd_present - Check if the given PM domain has been initialized.
735 * @genpd: PM domain to check.
736 */
737static bool pm_genpd_present(struct generic_pm_domain *genpd)
738{
739 struct generic_pm_domain *gpd;
740
741 if (IS_ERR_OR_NULL(genpd))
742 return false;
743
744 list_for_each_entry(gpd, &gpd_list, gpd_list_node)
745 if (gpd == genpd)
746 return true;
747
748 return false;
749}
750
700static bool genpd_dev_active_wakeup(struct generic_pm_domain *genpd, 751static bool genpd_dev_active_wakeup(struct generic_pm_domain *genpd,
701 struct device *dev) 752 struct device *dev)
702{ 753{
@@ -750,9 +801,10 @@ static int genpd_thaw_dev(struct generic_pm_domain *genpd, struct device *dev)
750 * Check if the given PM domain can be powered off (during system suspend or 801 * Check if the given PM domain can be powered off (during system suspend or
751 * hibernation) and do that if so. Also, in that case propagate to its masters. 802 * hibernation) and do that if so. Also, in that case propagate to its masters.
752 * 803 *
753 * This function is only called in "noirq" stages of system power transitions, 804 * This function is only called in "noirq" and "syscore" stages of system power
754 * so it need not acquire locks (all of the "noirq" callbacks are executed 805 * transitions, so it need not acquire locks (all of the "noirq" callbacks are
755 * sequentially, so it is guaranteed that it will never run twice in parallel). 806 * executed sequentially, so it is guaranteed that it will never run twice in
807 * parallel).
756 */ 808 */
757static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd) 809static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
758{ 810{
@@ -777,6 +829,33 @@ static void pm_genpd_sync_poweroff(struct generic_pm_domain *genpd)
777} 829}
778 830
779/** 831/**
832 * pm_genpd_sync_poweron - Synchronously power on a PM domain and its masters.
833 * @genpd: PM domain to power on.
834 *
835 * This function is only called in "noirq" and "syscore" stages of system power
836 * transitions, so it need not acquire locks (all of the "noirq" callbacks are
837 * executed sequentially, so it is guaranteed that it will never run twice in
838 * parallel).
839 */
840static void pm_genpd_sync_poweron(struct generic_pm_domain *genpd)
841{
842 struct gpd_link *link;
843
844 if (genpd->status != GPD_STATE_POWER_OFF)
845 return;
846
847 list_for_each_entry(link, &genpd->slave_links, slave_node) {
848 pm_genpd_sync_poweron(link->master);
849 genpd_sd_counter_inc(link->master);
850 }
851
852 if (genpd->power_on)
853 genpd->power_on(genpd);
854
855 genpd->status = GPD_STATE_ACTIVE;
856}
857
858/**
780 * resume_needed - Check whether to resume a device before system suspend. 859 * resume_needed - Check whether to resume a device before system suspend.
781 * @dev: Device to check. 860 * @dev: Device to check.
782 * @genpd: PM domain the device belongs to. 861 * @genpd: PM domain the device belongs to.
@@ -937,7 +1016,7 @@ static int pm_genpd_suspend_noirq(struct device *dev)
937 if (IS_ERR(genpd)) 1016 if (IS_ERR(genpd))
938 return -EINVAL; 1017 return -EINVAL;
939 1018
940 if (genpd->suspend_power_off || dev_gpd_data(dev)->always_on 1019 if (genpd->suspend_power_off
941 || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))) 1020 || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
942 return 0; 1021 return 0;
943 1022
@@ -970,7 +1049,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
970 if (IS_ERR(genpd)) 1049 if (IS_ERR(genpd))
971 return -EINVAL; 1050 return -EINVAL;
972 1051
973 if (genpd->suspend_power_off || dev_gpd_data(dev)->always_on 1052 if (genpd->suspend_power_off
974 || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))) 1053 || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
975 return 0; 1054 return 0;
976 1055
@@ -979,7 +1058,7 @@ static int pm_genpd_resume_noirq(struct device *dev)
979 * guaranteed that this function will never run twice in parallel for 1058 * guaranteed that this function will never run twice in parallel for
980 * the same PM domain, so it is not necessary to use locking here. 1059 * the same PM domain, so it is not necessary to use locking here.
981 */ 1060 */
982 pm_genpd_poweron(genpd); 1061 pm_genpd_sync_poweron(genpd);
983 genpd->suspended_count--; 1062 genpd->suspended_count--;
984 1063
985 return genpd_start_dev(genpd, dev); 1064 return genpd_start_dev(genpd, dev);
@@ -1090,8 +1169,7 @@ static int pm_genpd_freeze_noirq(struct device *dev)
1090 if (IS_ERR(genpd)) 1169 if (IS_ERR(genpd))
1091 return -EINVAL; 1170 return -EINVAL;
1092 1171
1093 return genpd->suspend_power_off || dev_gpd_data(dev)->always_on ? 1172 return genpd->suspend_power_off ? 0 : genpd_stop_dev(genpd, dev);
1094 0 : genpd_stop_dev(genpd, dev);
1095} 1173}
1096 1174
1097/** 1175/**
@@ -1111,8 +1189,7 @@ static int pm_genpd_thaw_noirq(struct device *dev)
1111 if (IS_ERR(genpd)) 1189 if (IS_ERR(genpd))
1112 return -EINVAL; 1190 return -EINVAL;
1113 1191
1114 return genpd->suspend_power_off || dev_gpd_data(dev)->always_on ? 1192 return genpd->suspend_power_off ? 0 : genpd_start_dev(genpd, dev);
1115 0 : genpd_start_dev(genpd, dev);
1116} 1193}
1117 1194
1118/** 1195/**
@@ -1186,8 +1263,8 @@ static int pm_genpd_restore_noirq(struct device *dev)
1186 if (genpd->suspended_count++ == 0) { 1263 if (genpd->suspended_count++ == 0) {
1187 /* 1264 /*
1188 * The boot kernel might put the domain into arbitrary state, 1265 * The boot kernel might put the domain into arbitrary state,
1189 * so make it appear as powered off to pm_genpd_poweron(), so 1266 * so make it appear as powered off to pm_genpd_sync_poweron(),
1190 * that it tries to power it on in case it was really off. 1267 * so that it tries to power it on in case it was really off.
1191 */ 1268 */
1192 genpd->status = GPD_STATE_POWER_OFF; 1269 genpd->status = GPD_STATE_POWER_OFF;
1193 if (genpd->suspend_power_off) { 1270 if (genpd->suspend_power_off) {
@@ -1205,9 +1282,9 @@ static int pm_genpd_restore_noirq(struct device *dev)
1205 if (genpd->suspend_power_off) 1282 if (genpd->suspend_power_off)
1206 return 0; 1283 return 0;
1207 1284
1208 pm_genpd_poweron(genpd); 1285 pm_genpd_sync_poweron(genpd);
1209 1286
1210 return dev_gpd_data(dev)->always_on ? 0 : genpd_start_dev(genpd, dev); 1287 return genpd_start_dev(genpd, dev);
1211} 1288}
1212 1289
1213/** 1290/**
@@ -1246,6 +1323,31 @@ static void pm_genpd_complete(struct device *dev)
1246 } 1323 }
1247} 1324}
1248 1325
1326/**
1327 * pm_genpd_syscore_switch - Switch power during system core suspend or resume.
1328 * @dev: Device that normally is marked as "always on" to switch power for.
1329 *
1330 * This routine may only be called during the system core (syscore) suspend or
1331 * resume phase for devices whose "always on" flags are set.
1332 */
1333void pm_genpd_syscore_switch(struct device *dev, bool suspend)
1334{
1335 struct generic_pm_domain *genpd;
1336
1337 genpd = dev_to_genpd(dev);
1338 if (!pm_genpd_present(genpd))
1339 return;
1340
1341 if (suspend) {
1342 genpd->suspended_count++;
1343 pm_genpd_sync_poweroff(genpd);
1344 } else {
1345 pm_genpd_sync_poweron(genpd);
1346 genpd->suspended_count--;
1347 }
1348}
1349EXPORT_SYMBOL_GPL(pm_genpd_syscore_switch);
1350
1249#else 1351#else
1250 1352
1251#define pm_genpd_prepare NULL 1353#define pm_genpd_prepare NULL
@@ -1393,6 +1495,19 @@ int __pm_genpd_of_add_device(struct device_node *genpd_node, struct device *dev,
1393 return __pm_genpd_add_device(genpd, dev, td); 1495 return __pm_genpd_add_device(genpd, dev, td);
1394} 1496}
1395 1497
1498
1499/**
1500 * __pm_genpd_name_add_device - Find I/O PM domain and add a device to it.
1501 * @domain_name: Name of the PM domain to add the device to.
1502 * @dev: Device to be added.
1503 * @td: Set of PM QoS timing parameters to attach to the device.
1504 */
1505int __pm_genpd_name_add_device(const char *domain_name, struct device *dev,
1506 struct gpd_timing_data *td)
1507{
1508 return __pm_genpd_add_device(pm_genpd_lookup_name(domain_name), dev, td);
1509}
1510
1396/** 1511/**
1397 * pm_genpd_remove_device - Remove a device from an I/O PM domain. 1512 * pm_genpd_remove_device - Remove a device from an I/O PM domain.
1398 * @genpd: PM domain to remove the device from. 1513 * @genpd: PM domain to remove the device from.
@@ -1455,26 +1570,6 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
1455} 1570}
1456 1571
1457/** 1572/**
1458 * pm_genpd_dev_always_on - Set/unset the "always on" flag for a given device.
1459 * @dev: Device to set/unset the flag for.
1460 * @val: The new value of the device's "always on" flag.
1461 */
1462void pm_genpd_dev_always_on(struct device *dev, bool val)
1463{
1464 struct pm_subsys_data *psd;
1465 unsigned long flags;
1466
1467 spin_lock_irqsave(&dev->power.lock, flags);
1468
1469 psd = dev_to_psd(dev);
1470 if (psd && psd->domain_data)
1471 to_gpd_data(psd->domain_data)->always_on = val;
1472
1473 spin_unlock_irqrestore(&dev->power.lock, flags);
1474}
1475EXPORT_SYMBOL_GPL(pm_genpd_dev_always_on);
1476
1477/**
1478 * pm_genpd_dev_need_restore - Set/unset the device's "need restore" flag. 1573 * pm_genpd_dev_need_restore - Set/unset the device's "need restore" flag.
1479 * @dev: Device to set/unset the flag for. 1574 * @dev: Device to set/unset the flag for.
1480 * @val: The new value of the device's "need restore" flag. 1575 * @val: The new value of the device's "need restore" flag.
@@ -1505,7 +1600,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
1505 struct gpd_link *link; 1600 struct gpd_link *link;
1506 int ret = 0; 1601 int ret = 0;
1507 1602
1508 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)) 1603 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)
1604 || genpd == subdomain)
1509 return -EINVAL; 1605 return -EINVAL;
1510 1606
1511 start: 1607 start:
@@ -1552,6 +1648,35 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
1552} 1648}
1553 1649
1554/** 1650/**
1651 * pm_genpd_add_subdomain_names - Add a subdomain to an I/O PM domain.
1652 * @master_name: Name of the master PM domain to add the subdomain to.
1653 * @subdomain_name: Name of the subdomain to be added.
1654 */
1655int pm_genpd_add_subdomain_names(const char *master_name,
1656 const char *subdomain_name)
1657{
1658 struct generic_pm_domain *master = NULL, *subdomain = NULL, *gpd;
1659
1660 if (IS_ERR_OR_NULL(master_name) || IS_ERR_OR_NULL(subdomain_name))
1661 return -EINVAL;
1662
1663 mutex_lock(&gpd_list_lock);
1664 list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
1665 if (!master && !strcmp(gpd->name, master_name))
1666 master = gpd;
1667
1668 if (!subdomain && !strcmp(gpd->name, subdomain_name))
1669 subdomain = gpd;
1670
1671 if (master && subdomain)
1672 break;
1673 }
1674 mutex_unlock(&gpd_list_lock);
1675
1676 return pm_genpd_add_subdomain(master, subdomain);
1677}
1678
1679/**
1555 * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain. 1680 * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
1556 * @genpd: Master PM domain to remove the subdomain from. 1681 * @genpd: Master PM domain to remove the subdomain from.
1557 * @subdomain: Subdomain to be removed. 1682 * @subdomain: Subdomain to be removed.
@@ -1704,7 +1829,16 @@ int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td)
1704} 1829}
1705EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks); 1830EXPORT_SYMBOL_GPL(__pm_genpd_remove_callbacks);
1706 1831
1707int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state) 1832/**
1833 * pm_genpd_attach_cpuidle - Connect the given PM domain with cpuidle.
1834 * @genpd: PM domain to be connected with cpuidle.
1835 * @state: cpuidle state this domain can disable/enable.
1836 *
1837 * Make a PM domain behave as though it contained a CPU core, that is, instead
1838 * of calling its power down routine it will enable the given cpuidle state so
1839 * that the cpuidle subsystem can power it down (if possible and desirable).
1840 */
1841int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
1708{ 1842{
1709 struct cpuidle_driver *cpuidle_drv; 1843 struct cpuidle_driver *cpuidle_drv;
1710 struct gpd_cpu_data *cpu_data; 1844 struct gpd_cpu_data *cpu_data;
@@ -1753,7 +1887,24 @@ int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
1753 goto out; 1887 goto out;
1754} 1888}
1755 1889
1756int genpd_detach_cpuidle(struct generic_pm_domain *genpd) 1890/**
1891 * pm_genpd_name_attach_cpuidle - Find PM domain and connect cpuidle to it.
1892 * @name: Name of the domain to connect to cpuidle.
1893 * @state: cpuidle state this domain can manipulate.
1894 */
1895int pm_genpd_name_attach_cpuidle(const char *name, int state)
1896{
1897 return pm_genpd_attach_cpuidle(pm_genpd_lookup_name(name), state);
1898}
1899
1900/**
1901 * pm_genpd_detach_cpuidle - Remove the cpuidle connection from a PM domain.
1902 * @genpd: PM domain to remove the cpuidle connection from.
1903 *
1904 * Remove the cpuidle connection set up by pm_genpd_attach_cpuidle() from the
1905 * given PM domain.
1906 */
1907int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd)
1757{ 1908{
1758 struct gpd_cpu_data *cpu_data; 1909 struct gpd_cpu_data *cpu_data;
1759 struct cpuidle_state *idle_state; 1910 struct cpuidle_state *idle_state;
@@ -1784,6 +1935,15 @@ int genpd_detach_cpuidle(struct generic_pm_domain *genpd)
1784 return ret; 1935 return ret;
1785} 1936}
1786 1937
1938/**
1939 * pm_genpd_name_detach_cpuidle - Find PM domain and disconnect cpuidle from it.
1940 * @name: Name of the domain to disconnect cpuidle from.
1941 */
1942int pm_genpd_name_detach_cpuidle(const char *name)
1943{
1944 return pm_genpd_detach_cpuidle(pm_genpd_lookup_name(name));
1945}
1946
1787/* Default device callbacks for generic PM domains. */ 1947/* Default device callbacks for generic PM domains. */
1788 1948
1789/** 1949/**
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 0113adc310dc..57f5814c2732 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -57,20 +57,17 @@ static pm_message_t pm_transition;
57static int async_error; 57static int async_error;
58 58
59/** 59/**
60 * device_pm_init - Initialize the PM-related part of a device object. 60 * device_pm_sleep_init - Initialize system suspend-related device fields.
61 * @dev: Device object being initialized. 61 * @dev: Device object being initialized.
62 */ 62 */
63void device_pm_init(struct device *dev) 63void device_pm_sleep_init(struct device *dev)
64{ 64{
65 dev->power.is_prepared = false; 65 dev->power.is_prepared = false;
66 dev->power.is_suspended = false; 66 dev->power.is_suspended = false;
67 init_completion(&dev->power.completion); 67 init_completion(&dev->power.completion);
68 complete_all(&dev->power.completion); 68 complete_all(&dev->power.completion);
69 dev->power.wakeup = NULL; 69 dev->power.wakeup = NULL;
70 spin_lock_init(&dev->power.lock);
71 pm_runtime_init(dev);
72 INIT_LIST_HEAD(&dev->power.entry); 70 INIT_LIST_HEAD(&dev->power.entry);
73 dev->power.power_state = PMSG_INVALID;
74} 71}
75 72
76/** 73/**
@@ -408,6 +405,9 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
408 TRACE_DEVICE(dev); 405 TRACE_DEVICE(dev);
409 TRACE_RESUME(0); 406 TRACE_RESUME(0);
410 407
408 if (dev->power.syscore)
409 goto Out;
410
411 if (dev->pm_domain) { 411 if (dev->pm_domain) {
412 info = "noirq power domain "; 412 info = "noirq power domain ";
413 callback = pm_noirq_op(&dev->pm_domain->ops, state); 413 callback = pm_noirq_op(&dev->pm_domain->ops, state);
@@ -429,6 +429,7 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
429 429
430 error = dpm_run_callback(callback, dev, state, info); 430 error = dpm_run_callback(callback, dev, state, info);
431 431
432 Out:
432 TRACE_RESUME(error); 433 TRACE_RESUME(error);
433 return error; 434 return error;
434} 435}
@@ -486,6 +487,9 @@ static int device_resume_early(struct device *dev, pm_message_t state)
486 TRACE_DEVICE(dev); 487 TRACE_DEVICE(dev);
487 TRACE_RESUME(0); 488 TRACE_RESUME(0);
488 489
490 if (dev->power.syscore)
491 goto Out;
492
489 if (dev->pm_domain) { 493 if (dev->pm_domain) {
490 info = "early power domain "; 494 info = "early power domain ";
491 callback = pm_late_early_op(&dev->pm_domain->ops, state); 495 callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -507,6 +511,7 @@ static int device_resume_early(struct device *dev, pm_message_t state)
507 511
508 error = dpm_run_callback(callback, dev, state, info); 512 error = dpm_run_callback(callback, dev, state, info);
509 513
514 Out:
510 TRACE_RESUME(error); 515 TRACE_RESUME(error);
511 return error; 516 return error;
512} 517}
@@ -570,6 +575,9 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
570 TRACE_DEVICE(dev); 575 TRACE_DEVICE(dev);
571 TRACE_RESUME(0); 576 TRACE_RESUME(0);
572 577
578 if (dev->power.syscore)
579 goto Complete;
580
573 dpm_wait(dev->parent, async); 581 dpm_wait(dev->parent, async);
574 device_lock(dev); 582 device_lock(dev);
575 583
@@ -632,6 +640,8 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
632 640
633 Unlock: 641 Unlock:
634 device_unlock(dev); 642 device_unlock(dev);
643
644 Complete:
635 complete_all(&dev->power.completion); 645 complete_all(&dev->power.completion);
636 646
637 TRACE_RESUME(error); 647 TRACE_RESUME(error);
@@ -722,6 +732,9 @@ static void device_complete(struct device *dev, pm_message_t state)
722 void (*callback)(struct device *) = NULL; 732 void (*callback)(struct device *) = NULL;
723 char *info = NULL; 733 char *info = NULL;
724 734
735 if (dev->power.syscore)
736 return;
737
725 device_lock(dev); 738 device_lock(dev);
726 739
727 if (dev->pm_domain) { 740 if (dev->pm_domain) {
@@ -834,6 +847,9 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
834 pm_callback_t callback = NULL; 847 pm_callback_t callback = NULL;
835 char *info = NULL; 848 char *info = NULL;
836 849
850 if (dev->power.syscore)
851 return 0;
852
837 if (dev->pm_domain) { 853 if (dev->pm_domain) {
838 info = "noirq power domain "; 854 info = "noirq power domain ";
839 callback = pm_noirq_op(&dev->pm_domain->ops, state); 855 callback = pm_noirq_op(&dev->pm_domain->ops, state);
@@ -917,6 +933,9 @@ static int device_suspend_late(struct device *dev, pm_message_t state)
917 pm_callback_t callback = NULL; 933 pm_callback_t callback = NULL;
918 char *info = NULL; 934 char *info = NULL;
919 935
936 if (dev->power.syscore)
937 return 0;
938
920 if (dev->pm_domain) { 939 if (dev->pm_domain) {
921 info = "late power domain "; 940 info = "late power domain ";
922 callback = pm_late_early_op(&dev->pm_domain->ops, state); 941 callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -1053,6 +1072,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
1053 goto Complete; 1072 goto Complete;
1054 } 1073 }
1055 1074
1075 if (dev->power.syscore)
1076 goto Complete;
1077
1056 device_lock(dev); 1078 device_lock(dev);
1057 1079
1058 if (dev->pm_domain) { 1080 if (dev->pm_domain) {
@@ -1209,6 +1231,9 @@ static int device_prepare(struct device *dev, pm_message_t state)
1209 char *info = NULL; 1231 char *info = NULL;
1210 int error = 0; 1232 int error = 0;
1211 1233
1234 if (dev->power.syscore)
1235 return 0;
1236
1212 device_lock(dev); 1237 device_lock(dev);
1213 1238
1214 dev->power.wakeup_path = device_may_wakeup(dev); 1239 dev->power.wakeup_path = device_may_wakeup(dev);
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index eeb4bff9505c..0dbfdf4419af 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -1,12 +1,32 @@
1#include <linux/pm_qos.h> 1#include <linux/pm_qos.h>
2 2
3static inline void device_pm_init_common(struct device *dev)
4{
5 if (!dev->power.early_init) {
6 spin_lock_init(&dev->power.lock);
7 dev->power.power_state = PMSG_INVALID;
8 dev->power.early_init = true;
9 }
10}
11
3#ifdef CONFIG_PM_RUNTIME 12#ifdef CONFIG_PM_RUNTIME
4 13
14static inline void pm_runtime_early_init(struct device *dev)
15{
16 dev->power.disable_depth = 1;
17 device_pm_init_common(dev);
18}
19
5extern void pm_runtime_init(struct device *dev); 20extern void pm_runtime_init(struct device *dev);
6extern void pm_runtime_remove(struct device *dev); 21extern void pm_runtime_remove(struct device *dev);
7 22
8#else /* !CONFIG_PM_RUNTIME */ 23#else /* !CONFIG_PM_RUNTIME */
9 24
25static inline void pm_runtime_early_init(struct device *dev)
26{
27 device_pm_init_common(dev);
28}
29
10static inline void pm_runtime_init(struct device *dev) {} 30static inline void pm_runtime_init(struct device *dev) {}
11static inline void pm_runtime_remove(struct device *dev) {} 31static inline void pm_runtime_remove(struct device *dev) {}
12 32
@@ -25,7 +45,7 @@ static inline struct device *to_device(struct list_head *entry)
25 return container_of(entry, struct device, power.entry); 45 return container_of(entry, struct device, power.entry);
26} 46}
27 47
28extern void device_pm_init(struct device *dev); 48extern void device_pm_sleep_init(struct device *dev);
29extern void device_pm_add(struct device *); 49extern void device_pm_add(struct device *);
30extern void device_pm_remove(struct device *); 50extern void device_pm_remove(struct device *);
31extern void device_pm_move_before(struct device *, struct device *); 51extern void device_pm_move_before(struct device *, struct device *);
@@ -34,12 +54,7 @@ extern void device_pm_move_last(struct device *);
34 54
35#else /* !CONFIG_PM_SLEEP */ 55#else /* !CONFIG_PM_SLEEP */
36 56
37static inline void device_pm_init(struct device *dev) 57static inline void device_pm_sleep_init(struct device *dev) {}
38{
39 spin_lock_init(&dev->power.lock);
40 dev->power.power_state = PMSG_INVALID;
41 pm_runtime_init(dev);
42}
43 58
44static inline void device_pm_add(struct device *dev) 59static inline void device_pm_add(struct device *dev)
45{ 60{
@@ -60,6 +75,13 @@ static inline void device_pm_move_last(struct device *dev) {}
60 75
61#endif /* !CONFIG_PM_SLEEP */ 76#endif /* !CONFIG_PM_SLEEP */
62 77
78static inline void device_pm_init(struct device *dev)
79{
80 device_pm_init_common(dev);
81 device_pm_sleep_init(dev);
82 pm_runtime_init(dev);
83}
84
63#ifdef CONFIG_PM 85#ifdef CONFIG_PM
64 86
65/* 87/*
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 98b06baafcc6..a5f7829f2799 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -33,6 +33,7 @@
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/pm_domain.h> 35#include <linux/pm_domain.h>
36#include <linux/pm_runtime.h>
36 37
37struct sh_cmt_priv { 38struct sh_cmt_priv {
38 void __iomem *mapbase; 39 void __iomem *mapbase;
@@ -52,6 +53,7 @@ struct sh_cmt_priv {
52 struct clock_event_device ced; 53 struct clock_event_device ced;
53 struct clocksource cs; 54 struct clocksource cs;
54 unsigned long total_cycles; 55 unsigned long total_cycles;
56 bool cs_enabled;
55}; 57};
56 58
57static DEFINE_RAW_SPINLOCK(sh_cmt_lock); 59static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
@@ -155,6 +157,9 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
155{ 157{
156 int k, ret; 158 int k, ret;
157 159
160 pm_runtime_get_sync(&p->pdev->dev);
161 dev_pm_syscore_device(&p->pdev->dev, true);
162
158 /* enable clock */ 163 /* enable clock */
159 ret = clk_enable(p->clk); 164 ret = clk_enable(p->clk);
160 if (ret) { 165 if (ret) {
@@ -221,6 +226,9 @@ static void sh_cmt_disable(struct sh_cmt_priv *p)
221 226
222 /* stop clock */ 227 /* stop clock */
223 clk_disable(p->clk); 228 clk_disable(p->clk);
229
230 dev_pm_syscore_device(&p->pdev->dev, false);
231 pm_runtime_put(&p->pdev->dev);
224} 232}
225 233
226/* private flags */ 234/* private flags */
@@ -451,22 +459,42 @@ static int sh_cmt_clocksource_enable(struct clocksource *cs)
451 int ret; 459 int ret;
452 struct sh_cmt_priv *p = cs_to_sh_cmt(cs); 460 struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
453 461
462 WARN_ON(p->cs_enabled);
463
454 p->total_cycles = 0; 464 p->total_cycles = 0;
455 465
456 ret = sh_cmt_start(p, FLAG_CLOCKSOURCE); 466 ret = sh_cmt_start(p, FLAG_CLOCKSOURCE);
457 if (!ret) 467 if (!ret) {
458 __clocksource_updatefreq_hz(cs, p->rate); 468 __clocksource_updatefreq_hz(cs, p->rate);
469 p->cs_enabled = true;
470 }
459 return ret; 471 return ret;
460} 472}
461 473
462static void sh_cmt_clocksource_disable(struct clocksource *cs) 474static void sh_cmt_clocksource_disable(struct clocksource *cs)
463{ 475{
464 sh_cmt_stop(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE); 476 struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
477
478 WARN_ON(!p->cs_enabled);
479
480 sh_cmt_stop(p, FLAG_CLOCKSOURCE);
481 p->cs_enabled = false;
482}
483
484static void sh_cmt_clocksource_suspend(struct clocksource *cs)
485{
486 struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
487
488 sh_cmt_stop(p, FLAG_CLOCKSOURCE);
489 pm_genpd_syscore_poweroff(&p->pdev->dev);
465} 490}
466 491
467static void sh_cmt_clocksource_resume(struct clocksource *cs) 492static void sh_cmt_clocksource_resume(struct clocksource *cs)
468{ 493{
469 sh_cmt_start(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE); 494 struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
495
496 pm_genpd_syscore_poweron(&p->pdev->dev);
497 sh_cmt_start(p, FLAG_CLOCKSOURCE);
470} 498}
471 499
472static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, 500static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
@@ -479,7 +507,7 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
479 cs->read = sh_cmt_clocksource_read; 507 cs->read = sh_cmt_clocksource_read;
480 cs->enable = sh_cmt_clocksource_enable; 508 cs->enable = sh_cmt_clocksource_enable;
481 cs->disable = sh_cmt_clocksource_disable; 509 cs->disable = sh_cmt_clocksource_disable;
482 cs->suspend = sh_cmt_clocksource_disable; 510 cs->suspend = sh_cmt_clocksource_suspend;
483 cs->resume = sh_cmt_clocksource_resume; 511 cs->resume = sh_cmt_clocksource_resume;
484 cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); 512 cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
485 cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; 513 cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
@@ -562,6 +590,16 @@ static int sh_cmt_clock_event_next(unsigned long delta,
562 return 0; 590 return 0;
563} 591}
564 592
593static void sh_cmt_clock_event_suspend(struct clock_event_device *ced)
594{
595 pm_genpd_syscore_poweroff(&ced_to_sh_cmt(ced)->pdev->dev);
596}
597
598static void sh_cmt_clock_event_resume(struct clock_event_device *ced)
599{
600 pm_genpd_syscore_poweron(&ced_to_sh_cmt(ced)->pdev->dev);
601}
602
565static void sh_cmt_register_clockevent(struct sh_cmt_priv *p, 603static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
566 char *name, unsigned long rating) 604 char *name, unsigned long rating)
567{ 605{
@@ -576,6 +614,8 @@ static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
576 ced->cpumask = cpumask_of(0); 614 ced->cpumask = cpumask_of(0);
577 ced->set_next_event = sh_cmt_clock_event_next; 615 ced->set_next_event = sh_cmt_clock_event_next;
578 ced->set_mode = sh_cmt_clock_event_mode; 616 ced->set_mode = sh_cmt_clock_event_mode;
617 ced->suspend = sh_cmt_clock_event_suspend;
618 ced->resume = sh_cmt_clock_event_resume;
579 619
580 dev_info(&p->pdev->dev, "used for clock events\n"); 620 dev_info(&p->pdev->dev, "used for clock events\n");
581 clockevents_register_device(ced); 621 clockevents_register_device(ced);
@@ -670,6 +710,7 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
670 dev_err(&p->pdev->dev, "registration failed\n"); 710 dev_err(&p->pdev->dev, "registration failed\n");
671 goto err1; 711 goto err1;
672 } 712 }
713 p->cs_enabled = false;
673 714
674 ret = setup_irq(irq, &p->irqaction); 715 ret = setup_irq(irq, &p->irqaction);
675 if (ret) { 716 if (ret) {
@@ -688,14 +729,17 @@ err0:
688static int __devinit sh_cmt_probe(struct platform_device *pdev) 729static int __devinit sh_cmt_probe(struct platform_device *pdev)
689{ 730{
690 struct sh_cmt_priv *p = platform_get_drvdata(pdev); 731 struct sh_cmt_priv *p = platform_get_drvdata(pdev);
732 struct sh_timer_config *cfg = pdev->dev.platform_data;
691 int ret; 733 int ret;
692 734
693 if (!is_early_platform_device(pdev)) 735 if (!is_early_platform_device(pdev)) {
694 pm_genpd_dev_always_on(&pdev->dev, true); 736 pm_runtime_set_active(&pdev->dev);
737 pm_runtime_enable(&pdev->dev);
738 }
695 739
696 if (p) { 740 if (p) {
697 dev_info(&pdev->dev, "kept as earlytimer\n"); 741 dev_info(&pdev->dev, "kept as earlytimer\n");
698 return 0; 742 goto out;
699 } 743 }
700 744
701 p = kmalloc(sizeof(*p), GFP_KERNEL); 745 p = kmalloc(sizeof(*p), GFP_KERNEL);
@@ -708,8 +752,19 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev)
708 if (ret) { 752 if (ret) {
709 kfree(p); 753 kfree(p);
710 platform_set_drvdata(pdev, NULL); 754 platform_set_drvdata(pdev, NULL);
755 pm_runtime_idle(&pdev->dev);
756 return ret;
711 } 757 }
712 return ret; 758 if (is_early_platform_device(pdev))
759 return 0;
760
761 out:
762 if (cfg->clockevent_rating || cfg->clocksource_rating)
763 pm_runtime_irq_safe(&pdev->dev);
764 else
765 pm_runtime_idle(&pdev->dev);
766
767 return 0;
713} 768}
714 769
715static int __devexit sh_cmt_remove(struct platform_device *pdev) 770static int __devexit sh_cmt_remove(struct platform_device *pdev)
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
index d9b76ca64a61..c5eea858054a 100644
--- a/drivers/clocksource/sh_mtu2.c
+++ b/drivers/clocksource/sh_mtu2.c
@@ -32,6 +32,7 @@
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/pm_domain.h> 34#include <linux/pm_domain.h>
35#include <linux/pm_runtime.h>
35 36
36struct sh_mtu2_priv { 37struct sh_mtu2_priv {
37 void __iomem *mapbase; 38 void __iomem *mapbase;
@@ -123,6 +124,9 @@ static int sh_mtu2_enable(struct sh_mtu2_priv *p)
123{ 124{
124 int ret; 125 int ret;
125 126
127 pm_runtime_get_sync(&p->pdev->dev);
128 dev_pm_syscore_device(&p->pdev->dev, true);
129
126 /* enable clock */ 130 /* enable clock */
127 ret = clk_enable(p->clk); 131 ret = clk_enable(p->clk);
128 if (ret) { 132 if (ret) {
@@ -157,6 +161,9 @@ static void sh_mtu2_disable(struct sh_mtu2_priv *p)
157 161
158 /* stop clock */ 162 /* stop clock */
159 clk_disable(p->clk); 163 clk_disable(p->clk);
164
165 dev_pm_syscore_device(&p->pdev->dev, false);
166 pm_runtime_put(&p->pdev->dev);
160} 167}
161 168
162static irqreturn_t sh_mtu2_interrupt(int irq, void *dev_id) 169static irqreturn_t sh_mtu2_interrupt(int irq, void *dev_id)
@@ -208,6 +215,16 @@ static void sh_mtu2_clock_event_mode(enum clock_event_mode mode,
208 } 215 }
209} 216}
210 217
218static void sh_mtu2_clock_event_suspend(struct clock_event_device *ced)
219{
220 pm_genpd_syscore_poweroff(&ced_to_sh_mtu2(ced)->pdev->dev);
221}
222
223static void sh_mtu2_clock_event_resume(struct clock_event_device *ced)
224{
225 pm_genpd_syscore_poweron(&ced_to_sh_mtu2(ced)->pdev->dev);
226}
227
211static void sh_mtu2_register_clockevent(struct sh_mtu2_priv *p, 228static void sh_mtu2_register_clockevent(struct sh_mtu2_priv *p,
212 char *name, unsigned long rating) 229 char *name, unsigned long rating)
213{ 230{
@@ -221,6 +238,8 @@ static void sh_mtu2_register_clockevent(struct sh_mtu2_priv *p,
221 ced->rating = rating; 238 ced->rating = rating;
222 ced->cpumask = cpumask_of(0); 239 ced->cpumask = cpumask_of(0);
223 ced->set_mode = sh_mtu2_clock_event_mode; 240 ced->set_mode = sh_mtu2_clock_event_mode;
241 ced->suspend = sh_mtu2_clock_event_suspend;
242 ced->resume = sh_mtu2_clock_event_resume;
224 243
225 dev_info(&p->pdev->dev, "used for clock events\n"); 244 dev_info(&p->pdev->dev, "used for clock events\n");
226 clockevents_register_device(ced); 245 clockevents_register_device(ced);
@@ -305,14 +324,17 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev)
305static int __devinit sh_mtu2_probe(struct platform_device *pdev) 324static int __devinit sh_mtu2_probe(struct platform_device *pdev)
306{ 325{
307 struct sh_mtu2_priv *p = platform_get_drvdata(pdev); 326 struct sh_mtu2_priv *p = platform_get_drvdata(pdev);
327 struct sh_timer_config *cfg = pdev->dev.platform_data;
308 int ret; 328 int ret;
309 329
310 if (!is_early_platform_device(pdev)) 330 if (!is_early_platform_device(pdev)) {
311 pm_genpd_dev_always_on(&pdev->dev, true); 331 pm_runtime_set_active(&pdev->dev);
332 pm_runtime_enable(&pdev->dev);
333 }
312 334
313 if (p) { 335 if (p) {
314 dev_info(&pdev->dev, "kept as earlytimer\n"); 336 dev_info(&pdev->dev, "kept as earlytimer\n");
315 return 0; 337 goto out;
316 } 338 }
317 339
318 p = kmalloc(sizeof(*p), GFP_KERNEL); 340 p = kmalloc(sizeof(*p), GFP_KERNEL);
@@ -325,8 +347,19 @@ static int __devinit sh_mtu2_probe(struct platform_device *pdev)
325 if (ret) { 347 if (ret) {
326 kfree(p); 348 kfree(p);
327 platform_set_drvdata(pdev, NULL); 349 platform_set_drvdata(pdev, NULL);
350 pm_runtime_idle(&pdev->dev);
351 return ret;
328 } 352 }
329 return ret; 353 if (is_early_platform_device(pdev))
354 return 0;
355
356 out:
357 if (cfg->clockevent_rating)
358 pm_runtime_irq_safe(&pdev->dev);
359 else
360 pm_runtime_idle(&pdev->dev);
361
362 return 0;
330} 363}
331 364
332static int __devexit sh_mtu2_remove(struct platform_device *pdev) 365static int __devexit sh_mtu2_remove(struct platform_device *pdev)
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index c1b51d49d106..0cc4add88279 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -33,6 +33,7 @@
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/pm_domain.h> 35#include <linux/pm_domain.h>
36#include <linux/pm_runtime.h>
36 37
37struct sh_tmu_priv { 38struct sh_tmu_priv {
38 void __iomem *mapbase; 39 void __iomem *mapbase;
@@ -43,6 +44,8 @@ struct sh_tmu_priv {
43 unsigned long periodic; 44 unsigned long periodic;
44 struct clock_event_device ced; 45 struct clock_event_device ced;
45 struct clocksource cs; 46 struct clocksource cs;
47 bool cs_enabled;
48 unsigned int enable_count;
46}; 49};
47 50
48static DEFINE_RAW_SPINLOCK(sh_tmu_lock); 51static DEFINE_RAW_SPINLOCK(sh_tmu_lock);
@@ -107,7 +110,7 @@ static void sh_tmu_start_stop_ch(struct sh_tmu_priv *p, int start)
107 raw_spin_unlock_irqrestore(&sh_tmu_lock, flags); 110 raw_spin_unlock_irqrestore(&sh_tmu_lock, flags);
108} 111}
109 112
110static int sh_tmu_enable(struct sh_tmu_priv *p) 113static int __sh_tmu_enable(struct sh_tmu_priv *p)
111{ 114{
112 int ret; 115 int ret;
113 116
@@ -135,7 +138,18 @@ static int sh_tmu_enable(struct sh_tmu_priv *p)
135 return 0; 138 return 0;
136} 139}
137 140
138static void sh_tmu_disable(struct sh_tmu_priv *p) 141static int sh_tmu_enable(struct sh_tmu_priv *p)
142{
143 if (p->enable_count++ > 0)
144 return 0;
145
146 pm_runtime_get_sync(&p->pdev->dev);
147 dev_pm_syscore_device(&p->pdev->dev, true);
148
149 return __sh_tmu_enable(p);
150}
151
152static void __sh_tmu_disable(struct sh_tmu_priv *p)
139{ 153{
140 /* disable channel */ 154 /* disable channel */
141 sh_tmu_start_stop_ch(p, 0); 155 sh_tmu_start_stop_ch(p, 0);
@@ -147,6 +161,20 @@ static void sh_tmu_disable(struct sh_tmu_priv *p)
147 clk_disable(p->clk); 161 clk_disable(p->clk);
148} 162}
149 163
164static void sh_tmu_disable(struct sh_tmu_priv *p)
165{
166 if (WARN_ON(p->enable_count == 0))
167 return;
168
169 if (--p->enable_count > 0)
170 return;
171
172 __sh_tmu_disable(p);
173
174 dev_pm_syscore_device(&p->pdev->dev, false);
175 pm_runtime_put(&p->pdev->dev);
176}
177
150static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta, 178static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta,
151 int periodic) 179 int periodic)
152{ 180{
@@ -203,15 +231,53 @@ static int sh_tmu_clocksource_enable(struct clocksource *cs)
203 struct sh_tmu_priv *p = cs_to_sh_tmu(cs); 231 struct sh_tmu_priv *p = cs_to_sh_tmu(cs);
204 int ret; 232 int ret;
205 233
234 if (WARN_ON(p->cs_enabled))
235 return 0;
236
206 ret = sh_tmu_enable(p); 237 ret = sh_tmu_enable(p);
207 if (!ret) 238 if (!ret) {
208 __clocksource_updatefreq_hz(cs, p->rate); 239 __clocksource_updatefreq_hz(cs, p->rate);
240 p->cs_enabled = true;
241 }
242
209 return ret; 243 return ret;
210} 244}
211 245
212static void sh_tmu_clocksource_disable(struct clocksource *cs) 246static void sh_tmu_clocksource_disable(struct clocksource *cs)
213{ 247{
214 sh_tmu_disable(cs_to_sh_tmu(cs)); 248 struct sh_tmu_priv *p = cs_to_sh_tmu(cs);
249
250 if (WARN_ON(!p->cs_enabled))
251 return;
252
253 sh_tmu_disable(p);
254 p->cs_enabled = false;
255}
256
257static void sh_tmu_clocksource_suspend(struct clocksource *cs)
258{
259 struct sh_tmu_priv *p = cs_to_sh_tmu(cs);
260
261 if (!p->cs_enabled)
262 return;
263
264 if (--p->enable_count == 0) {
265 __sh_tmu_disable(p);
266 pm_genpd_syscore_poweroff(&p->pdev->dev);
267 }
268}
269
270static void sh_tmu_clocksource_resume(struct clocksource *cs)
271{
272 struct sh_tmu_priv *p = cs_to_sh_tmu(cs);
273
274 if (!p->cs_enabled)
275 return;
276
277 if (p->enable_count++ == 0) {
278 pm_genpd_syscore_poweron(&p->pdev->dev);
279 __sh_tmu_enable(p);
280 }
215} 281}
216 282
217static int sh_tmu_register_clocksource(struct sh_tmu_priv *p, 283static int sh_tmu_register_clocksource(struct sh_tmu_priv *p,
@@ -224,6 +290,8 @@ static int sh_tmu_register_clocksource(struct sh_tmu_priv *p,
224 cs->read = sh_tmu_clocksource_read; 290 cs->read = sh_tmu_clocksource_read;
225 cs->enable = sh_tmu_clocksource_enable; 291 cs->enable = sh_tmu_clocksource_enable;
226 cs->disable = sh_tmu_clocksource_disable; 292 cs->disable = sh_tmu_clocksource_disable;
293 cs->suspend = sh_tmu_clocksource_suspend;
294 cs->resume = sh_tmu_clocksource_resume;
227 cs->mask = CLOCKSOURCE_MASK(32); 295 cs->mask = CLOCKSOURCE_MASK(32);
228 cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; 296 cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
229 297
@@ -301,6 +369,16 @@ static int sh_tmu_clock_event_next(unsigned long delta,
301 return 0; 369 return 0;
302} 370}
303 371
372static void sh_tmu_clock_event_suspend(struct clock_event_device *ced)
373{
374 pm_genpd_syscore_poweroff(&ced_to_sh_tmu(ced)->pdev->dev);
375}
376
377static void sh_tmu_clock_event_resume(struct clock_event_device *ced)
378{
379 pm_genpd_syscore_poweron(&ced_to_sh_tmu(ced)->pdev->dev);
380}
381
304static void sh_tmu_register_clockevent(struct sh_tmu_priv *p, 382static void sh_tmu_register_clockevent(struct sh_tmu_priv *p,
305 char *name, unsigned long rating) 383 char *name, unsigned long rating)
306{ 384{
@@ -316,6 +394,8 @@ static void sh_tmu_register_clockevent(struct sh_tmu_priv *p,
316 ced->cpumask = cpumask_of(0); 394 ced->cpumask = cpumask_of(0);
317 ced->set_next_event = sh_tmu_clock_event_next; 395 ced->set_next_event = sh_tmu_clock_event_next;
318 ced->set_mode = sh_tmu_clock_event_mode; 396 ced->set_mode = sh_tmu_clock_event_mode;
397 ced->suspend = sh_tmu_clock_event_suspend;
398 ced->resume = sh_tmu_clock_event_resume;
319 399
320 dev_info(&p->pdev->dev, "used for clock events\n"); 400 dev_info(&p->pdev->dev, "used for clock events\n");
321 401
@@ -392,6 +472,8 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev)
392 ret = PTR_ERR(p->clk); 472 ret = PTR_ERR(p->clk);
393 goto err1; 473 goto err1;
394 } 474 }
475 p->cs_enabled = false;
476 p->enable_count = 0;
395 477
396 return sh_tmu_register(p, (char *)dev_name(&p->pdev->dev), 478 return sh_tmu_register(p, (char *)dev_name(&p->pdev->dev),
397 cfg->clockevent_rating, 479 cfg->clockevent_rating,
@@ -405,14 +487,17 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev)
405static int __devinit sh_tmu_probe(struct platform_device *pdev) 487static int __devinit sh_tmu_probe(struct platform_device *pdev)
406{ 488{
407 struct sh_tmu_priv *p = platform_get_drvdata(pdev); 489 struct sh_tmu_priv *p = platform_get_drvdata(pdev);
490 struct sh_timer_config *cfg = pdev->dev.platform_data;
408 int ret; 491 int ret;
409 492
410 if (!is_early_platform_device(pdev)) 493 if (!is_early_platform_device(pdev)) {
411 pm_genpd_dev_always_on(&pdev->dev, true); 494 pm_runtime_set_active(&pdev->dev);
495 pm_runtime_enable(&pdev->dev);
496 }
412 497
413 if (p) { 498 if (p) {
414 dev_info(&pdev->dev, "kept as earlytimer\n"); 499 dev_info(&pdev->dev, "kept as earlytimer\n");
415 return 0; 500 goto out;
416 } 501 }
417 502
418 p = kmalloc(sizeof(*p), GFP_KERNEL); 503 p = kmalloc(sizeof(*p), GFP_KERNEL);
@@ -425,8 +510,19 @@ static int __devinit sh_tmu_probe(struct platform_device *pdev)
425 if (ret) { 510 if (ret) {
426 kfree(p); 511 kfree(p);
427 platform_set_drvdata(pdev, NULL); 512 platform_set_drvdata(pdev, NULL);
513 pm_runtime_idle(&pdev->dev);
514 return ret;
428 } 515 }
429 return ret; 516 if (is_early_platform_device(pdev))
517 return 0;
518
519 out:
520 if (cfg->clockevent_rating || cfg->clocksource_rating)
521 pm_runtime_irq_safe(&pdev->dev);
522 else
523 pm_runtime_idle(&pdev->dev);
524
525 return 0;
430} 526}
431 527
432static int __devexit sh_tmu_remove(struct platform_device *pdev) 528static int __devexit sh_tmu_remove(struct platform_device *pdev)
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index acba894374a1..8a7096fcb01e 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -97,6 +97,8 @@ struct clock_event_device {
97 void (*broadcast)(const struct cpumask *mask); 97 void (*broadcast)(const struct cpumask *mask);
98 void (*set_mode)(enum clock_event_mode mode, 98 void (*set_mode)(enum clock_event_mode mode,
99 struct clock_event_device *); 99 struct clock_event_device *);
100 void (*suspend)(struct clock_event_device *);
101 void (*resume)(struct clock_event_device *);
100 unsigned long min_delta_ticks; 102 unsigned long min_delta_ticks;
101 unsigned long max_delta_ticks; 103 unsigned long max_delta_ticks;
102 104
@@ -156,6 +158,9 @@ clockevents_calc_mult_shift(struct clock_event_device *ce, u32 freq, u32 minsec)
156 freq, minsec); 158 freq, minsec);
157} 159}
158 160
161extern void clockevents_suspend(void);
162extern void clockevents_resume(void);
163
159#ifdef CONFIG_GENERIC_CLOCKEVENTS 164#ifdef CONFIG_GENERIC_CLOCKEVENTS
160extern void clockevents_notify(unsigned long reason, void *arg); 165extern void clockevents_notify(unsigned long reason, void *arg);
161#else 166#else
@@ -164,6 +169,9 @@ extern void clockevents_notify(unsigned long reason, void *arg);
164 169
165#else /* CONFIG_GENERIC_CLOCKEVENTS_BUILD */ 170#else /* CONFIG_GENERIC_CLOCKEVENTS_BUILD */
166 171
172static inline void clockevents_suspend(void) {}
173static inline void clockevents_resume(void) {}
174
167#define clockevents_notify(reason, arg) do { } while (0) 175#define clockevents_notify(reason, arg) do { } while (0)
168 176
169#endif 177#endif
diff --git a/include/linux/device.h b/include/linux/device.h
index 52a5f15a2223..86529e642d6c 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -772,6 +772,13 @@ static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
772 dev->power.ignore_children = enable; 772 dev->power.ignore_children = enable;
773} 773}
774 774
775static inline void dev_pm_syscore_device(struct device *dev, bool val)
776{
777#ifdef CONFIG_PM_SLEEP
778 dev->power.syscore = val;
779#endif
780}
781
775static inline void device_lock(struct device *dev) 782static inline void device_lock(struct device *dev)
776{ 783{
777 mutex_lock(&dev->mutex); 784 mutex_lock(&dev->mutex);
diff --git a/include/linux/pm.h b/include/linux/pm.h
index f067e60a3832..44d1f2307dbc 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -510,12 +510,14 @@ struct dev_pm_info {
510 bool is_prepared:1; /* Owned by the PM core */ 510 bool is_prepared:1; /* Owned by the PM core */
511 bool is_suspended:1; /* Ditto */ 511 bool is_suspended:1; /* Ditto */
512 bool ignore_children:1; 512 bool ignore_children:1;
513 bool early_init:1; /* Owned by the PM core */
513 spinlock_t lock; 514 spinlock_t lock;
514#ifdef CONFIG_PM_SLEEP 515#ifdef CONFIG_PM_SLEEP
515 struct list_head entry; 516 struct list_head entry;
516 struct completion completion; 517 struct completion completion;
517 struct wakeup_source *wakeup; 518 struct wakeup_source *wakeup;
518 bool wakeup_path:1; 519 bool wakeup_path:1;
520 bool syscore:1;
519#else 521#else
520 unsigned int should_wakeup:1; 522 unsigned int should_wakeup:1;
521#endif 523#endif
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index a7d6172922d4..7c1d252b20c0 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -114,7 +114,6 @@ struct generic_pm_domain_data {
114 struct mutex lock; 114 struct mutex lock;
115 unsigned int refcount; 115 unsigned int refcount;
116 bool need_restore; 116 bool need_restore;
117 bool always_on;
118}; 117};
119 118
120#ifdef CONFIG_PM_GENERIC_DOMAINS 119#ifdef CONFIG_PM_GENERIC_DOMAINS
@@ -139,36 +138,32 @@ extern int __pm_genpd_of_add_device(struct device_node *genpd_node,
139 struct device *dev, 138 struct device *dev,
140 struct gpd_timing_data *td); 139 struct gpd_timing_data *td);
141 140
142static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, 141extern int __pm_genpd_name_add_device(const char *domain_name,
143 struct device *dev) 142 struct device *dev,
144{ 143 struct gpd_timing_data *td);
145 return __pm_genpd_add_device(genpd, dev, NULL);
146}
147
148static inline int pm_genpd_of_add_device(struct device_node *genpd_node,
149 struct device *dev)
150{
151 return __pm_genpd_of_add_device(genpd_node, dev, NULL);
152}
153 144
154extern int pm_genpd_remove_device(struct generic_pm_domain *genpd, 145extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
155 struct device *dev); 146 struct device *dev);
156extern void pm_genpd_dev_always_on(struct device *dev, bool val);
157extern void pm_genpd_dev_need_restore(struct device *dev, bool val); 147extern void pm_genpd_dev_need_restore(struct device *dev, bool val);
158extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, 148extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
159 struct generic_pm_domain *new_subdomain); 149 struct generic_pm_domain *new_subdomain);
150extern int pm_genpd_add_subdomain_names(const char *master_name,
151 const char *subdomain_name);
160extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, 152extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
161 struct generic_pm_domain *target); 153 struct generic_pm_domain *target);
162extern int pm_genpd_add_callbacks(struct device *dev, 154extern int pm_genpd_add_callbacks(struct device *dev,
163 struct gpd_dev_ops *ops, 155 struct gpd_dev_ops *ops,
164 struct gpd_timing_data *td); 156 struct gpd_timing_data *td);
165extern int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td); 157extern int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td);
166extern int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state); 158extern int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state);
167extern int genpd_detach_cpuidle(struct generic_pm_domain *genpd); 159extern int pm_genpd_name_attach_cpuidle(const char *name, int state);
160extern int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd);
161extern int pm_genpd_name_detach_cpuidle(const char *name);
168extern void pm_genpd_init(struct generic_pm_domain *genpd, 162extern void pm_genpd_init(struct generic_pm_domain *genpd,
169 struct dev_power_governor *gov, bool is_off); 163 struct dev_power_governor *gov, bool is_off);
170 164
171extern int pm_genpd_poweron(struct generic_pm_domain *genpd); 165extern int pm_genpd_poweron(struct generic_pm_domain *genpd);
166extern int pm_genpd_name_poweron(const char *domain_name);
172 167
173extern bool default_stop_ok(struct device *dev); 168extern bool default_stop_ok(struct device *dev);
174 169
@@ -189,8 +184,15 @@ static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd,
189{ 184{
190 return -ENOSYS; 185 return -ENOSYS;
191} 186}
192static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, 187static inline int __pm_genpd_of_add_device(struct device_node *genpd_node,
193 struct device *dev) 188 struct device *dev,
189 struct gpd_timing_data *td)
190{
191 return -ENOSYS;
192}
193static inline int __pm_genpd_name_add_device(const char *domain_name,
194 struct device *dev,
195 struct gpd_timing_data *td)
194{ 196{
195 return -ENOSYS; 197 return -ENOSYS;
196} 198}
@@ -199,13 +201,17 @@ static inline int pm_genpd_remove_device(struct generic_pm_domain *genpd,
199{ 201{
200 return -ENOSYS; 202 return -ENOSYS;
201} 203}
202static inline void pm_genpd_dev_always_on(struct device *dev, bool val) {}
203static inline void pm_genpd_dev_need_restore(struct device *dev, bool val) {} 204static inline void pm_genpd_dev_need_restore(struct device *dev, bool val) {}
204static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, 205static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
205 struct generic_pm_domain *new_sd) 206 struct generic_pm_domain *new_sd)
206{ 207{
207 return -ENOSYS; 208 return -ENOSYS;
208} 209}
210static inline int pm_genpd_add_subdomain_names(const char *master_name,
211 const char *subdomain_name)
212{
213 return -ENOSYS;
214}
209static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, 215static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
210 struct generic_pm_domain *target) 216 struct generic_pm_domain *target)
211{ 217{
@@ -221,11 +227,19 @@ static inline int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td)
221{ 227{
222 return -ENOSYS; 228 return -ENOSYS;
223} 229}
224static inline int genpd_attach_cpuidle(struct generic_pm_domain *genpd, int st) 230static inline int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int st)
225{ 231{
226 return -ENOSYS; 232 return -ENOSYS;
227} 233}
228static inline int genpd_detach_cpuidle(struct generic_pm_domain *genpd) 234static inline int pm_genpd_name_attach_cpuidle(const char *name, int state)
235{
236 return -ENOSYS;
237}
238static inline int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd)
239{
240 return -ENOSYS;
241}
242static inline int pm_genpd_name_detach_cpuidle(const char *name)
229{ 243{
230 return -ENOSYS; 244 return -ENOSYS;
231} 245}
@@ -237,6 +251,10 @@ static inline int pm_genpd_poweron(struct generic_pm_domain *genpd)
237{ 251{
238 return -ENOSYS; 252 return -ENOSYS;
239} 253}
254static inline int pm_genpd_name_poweron(const char *domain_name)
255{
256 return -ENOSYS;
257}
240static inline bool default_stop_ok(struct device *dev) 258static inline bool default_stop_ok(struct device *dev)
241{ 259{
242 return false; 260 return false;
@@ -245,6 +263,24 @@ static inline bool default_stop_ok(struct device *dev)
245#define pm_domain_always_on_gov NULL 263#define pm_domain_always_on_gov NULL
246#endif 264#endif
247 265
266static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
267 struct device *dev)
268{
269 return __pm_genpd_add_device(genpd, dev, NULL);
270}
271
272static inline int pm_genpd_of_add_device(struct device_node *genpd_node,
273 struct device *dev)
274{
275 return __pm_genpd_of_add_device(genpd_node, dev, NULL);
276}
277
278static inline int pm_genpd_name_add_device(const char *domain_name,
279 struct device *dev)
280{
281 return __pm_genpd_name_add_device(domain_name, dev, NULL);
282}
283
248static inline int pm_genpd_remove_callbacks(struct device *dev) 284static inline int pm_genpd_remove_callbacks(struct device *dev)
249{ 285{
250 return __pm_genpd_remove_callbacks(dev, true); 286 return __pm_genpd_remove_callbacks(dev, true);
@@ -258,4 +294,20 @@ static inline void genpd_queue_power_off_work(struct generic_pm_domain *gpd) {}
258static inline void pm_genpd_poweroff_unused(void) {} 294static inline void pm_genpd_poweroff_unused(void) {}
259#endif 295#endif
260 296
297#ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP
298extern void pm_genpd_syscore_switch(struct device *dev, bool suspend);
299#else
300static inline void pm_genpd_syscore_switch(struct device *dev, bool suspend) {}
301#endif
302
303static inline void pm_genpd_syscore_poweroff(struct device *dev)
304{
305 pm_genpd_syscore_switch(dev, true);
306}
307
308static inline void pm_genpd_syscore_poweron(struct device *dev)
309{
310 pm_genpd_syscore_switch(dev, false);
311}
312
261#endif /* _LINUX_PM_DOMAIN_H */ 313#endif /* _LINUX_PM_DOMAIN_H */
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index a70518c9d82f..5dfdc9ea180b 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -263,6 +263,10 @@ config PM_GENERIC_DOMAINS
263 bool 263 bool
264 depends on PM 264 depends on PM
265 265
266config PM_GENERIC_DOMAINS_SLEEP
267 def_bool y
268 depends on PM_SLEEP && PM_GENERIC_DOMAINS
269
266config PM_GENERIC_DOMAINS_RUNTIME 270config PM_GENERIC_DOMAINS_RUNTIME
267 def_bool y 271 def_bool y
268 depends on PM_RUNTIME && PM_GENERIC_DOMAINS 272 depends on PM_RUNTIME && PM_GENERIC_DOMAINS
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 7e1ce012a851..30b6de0d977c 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -397,6 +397,30 @@ void clockevents_exchange_device(struct clock_event_device *old,
397 local_irq_restore(flags); 397 local_irq_restore(flags);
398} 398}
399 399
400/**
401 * clockevents_suspend - suspend clock devices
402 */
403void clockevents_suspend(void)
404{
405 struct clock_event_device *dev;
406
407 list_for_each_entry_reverse(dev, &clockevent_devices, list)
408 if (dev->suspend)
409 dev->suspend(dev);
410}
411
412/**
413 * clockevents_resume - resume clock devices
414 */
415void clockevents_resume(void)
416{
417 struct clock_event_device *dev;
418
419 list_for_each_entry(dev, &clockevent_devices, list)
420 if (dev->resume)
421 dev->resume(dev);
422}
423
400#ifdef CONFIG_GENERIC_CLOCKEVENTS 424#ifdef CONFIG_GENERIC_CLOCKEVENTS
401/** 425/**
402 * clockevents_notify - notification about relevant events 426 * clockevents_notify - notification about relevant events
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 34e5eac81424..312a675cb240 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -773,6 +773,7 @@ static void timekeeping_resume(void)
773 773
774 read_persistent_clock(&ts); 774 read_persistent_clock(&ts);
775 775
776 clockevents_resume();
776 clocksource_resume(); 777 clocksource_resume();
777 778
778 write_seqlock_irqsave(&tk->lock, flags); 779 write_seqlock_irqsave(&tk->lock, flags);
@@ -832,6 +833,7 @@ static int timekeeping_suspend(void)
832 833
833 clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL); 834 clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL);
834 clocksource_suspend(); 835 clocksource_suspend();
836 clockevents_suspend();
835 837
836 return 0; 838 return 0;
837} 839}