diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap1/pm_bus.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-omap2/gpio.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/serial.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-ap4evb.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/board-mackerel.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh7372.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/sh7372.h | 29 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/pm-sh7372.c | 160 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/pm_runtime.c | 22 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/setup-sh7372.c | 11 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/omap_device.h | 9 | ||||
-rw-r--r-- | arch/arm/plat-omap/omap_device.c | 53 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/shmobile/pm_runtime.c | 6 |
14 files changed, 297 insertions, 22 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9adc278a22ab..e04fa9d7637c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -642,6 +642,7 @@ config ARCH_SHMOBILE | |||
642 | select NO_IOPORT | 642 | select NO_IOPORT |
643 | select SPARSE_IRQ | 643 | select SPARSE_IRQ |
644 | select MULTI_IRQ_HANDLER | 644 | select MULTI_IRQ_HANDLER |
645 | select PM_GENERIC_DOMAINS if PM | ||
645 | help | 646 | help |
646 | Support for Renesas's SH-Mobile and R-Mobile ARM platforms. | 647 | Support for Renesas's SH-Mobile and R-Mobile ARM platforms. |
647 | 648 | ||
diff --git a/arch/arm/mach-omap1/pm_bus.c b/arch/arm/mach-omap1/pm_bus.c index 334fb8871bc3..943072d5a1d5 100644 --- a/arch/arm/mach-omap1/pm_bus.c +++ b/arch/arm/mach-omap1/pm_bus.c | |||
@@ -32,7 +32,7 @@ static int omap1_pm_runtime_suspend(struct device *dev) | |||
32 | if (ret) | 32 | if (ret) |
33 | return ret; | 33 | return ret; |
34 | 34 | ||
35 | ret = pm_runtime_clk_suspend(dev); | 35 | ret = pm_clk_suspend(dev); |
36 | if (ret) { | 36 | if (ret) { |
37 | pm_generic_runtime_resume(dev); | 37 | pm_generic_runtime_resume(dev); |
38 | return ret; | 38 | return ret; |
@@ -45,24 +45,24 @@ static int omap1_pm_runtime_resume(struct device *dev) | |||
45 | { | 45 | { |
46 | dev_dbg(dev, "%s\n", __func__); | 46 | dev_dbg(dev, "%s\n", __func__); |
47 | 47 | ||
48 | pm_runtime_clk_resume(dev); | 48 | pm_clk_resume(dev); |
49 | return pm_generic_runtime_resume(dev); | 49 | return pm_generic_runtime_resume(dev); |
50 | } | 50 | } |
51 | 51 | ||
52 | static struct dev_power_domain default_power_domain = { | 52 | static struct dev_pm_domain default_pm_domain = { |
53 | .ops = { | 53 | .ops = { |
54 | .runtime_suspend = omap1_pm_runtime_suspend, | 54 | .runtime_suspend = omap1_pm_runtime_suspend, |
55 | .runtime_resume = omap1_pm_runtime_resume, | 55 | .runtime_resume = omap1_pm_runtime_resume, |
56 | USE_PLATFORM_PM_SLEEP_OPS | 56 | USE_PLATFORM_PM_SLEEP_OPS |
57 | }, | 57 | }, |
58 | }; | 58 | }; |
59 | #define OMAP1_PWR_DOMAIN (&default_power_domain) | 59 | #define OMAP1_PM_DOMAIN (&default_pm_domain) |
60 | #else | 60 | #else |
61 | #define OMAP1_PWR_DOMAIN NULL | 61 | #define OMAP1_PM_DOMAIN NULL |
62 | #endif /* CONFIG_PM_RUNTIME */ | 62 | #endif /* CONFIG_PM_RUNTIME */ |
63 | 63 | ||
64 | static struct pm_clk_notifier_block platform_bus_notifier = { | 64 | static struct pm_clk_notifier_block platform_bus_notifier = { |
65 | .pwr_domain = OMAP1_PWR_DOMAIN, | 65 | .pm_domain = OMAP1_PM_DOMAIN, |
66 | .con_ids = { "ick", "fck", NULL, }, | 66 | .con_ids = { "ick", "fck", NULL, }, |
67 | }; | 67 | }; |
68 | 68 | ||
@@ -71,7 +71,7 @@ static int __init omap1_pm_runtime_init(void) | |||
71 | if (!cpu_class_is_omap1()) | 71 | if (!cpu_class_is_omap1()) |
72 | return -ENODEV; | 72 | return -ENODEV; |
73 | 73 | ||
74 | pm_runtime_clk_add_notifier(&platform_bus_type, &platform_bus_notifier); | 74 | pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier); |
75 | 75 | ||
76 | return 0; | 76 | return 0; |
77 | } | 77 | } |
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 9a46d7773a48..2765cdc3152d 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c | |||
@@ -119,6 +119,8 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) | |||
119 | return PTR_ERR(od); | 119 | return PTR_ERR(od); |
120 | } | 120 | } |
121 | 121 | ||
122 | omap_device_disable_idle_on_suspend(od); | ||
123 | |||
122 | gpio_bank_count++; | 124 | gpio_bank_count++; |
123 | return 0; | 125 | return 0; |
124 | } | 126 | } |
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 1ac361b7b8cb..466fc722fa0f 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
@@ -805,6 +805,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) | |||
805 | WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n", | 805 | WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n", |
806 | name, oh->name); | 806 | name, oh->name); |
807 | 807 | ||
808 | omap_device_disable_idle_on_suspend(od); | ||
808 | oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); | 809 | oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); |
809 | 810 | ||
810 | uart->irq = oh->mpu_irqs[0].irq; | 811 | uart->irq = oh->mpu_irqs[0].irq; |
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 803bc6edfca4..b473b8efac68 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
@@ -1408,9 +1408,14 @@ static void __init ap4evb_init(void) | |||
1408 | 1408 | ||
1409 | platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); | 1409 | platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); |
1410 | 1410 | ||
1411 | sh7372_add_device_to_domain(&sh7372_a4lc, &lcdc1_device); | ||
1412 | sh7372_add_device_to_domain(&sh7372_a4lc, &lcdc_device); | ||
1413 | sh7372_add_device_to_domain(&sh7372_a4mp, &fsi_device); | ||
1414 | |||
1411 | hdmi_init_pm_clock(); | 1415 | hdmi_init_pm_clock(); |
1412 | fsi_init_pm_clock(); | 1416 | fsi_init_pm_clock(); |
1413 | sh7372_pm_init(); | 1417 | sh7372_pm_init(); |
1418 | pm_clk_add(&fsi_device.dev, "spu2"); | ||
1414 | } | 1419 | } |
1415 | 1420 | ||
1416 | static void __init ap4evb_timer_init(void) | 1421 | static void __init ap4evb_timer_init(void) |
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 3802f2afabef..5b36b6c5b448 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c | |||
@@ -1582,8 +1582,13 @@ static void __init mackerel_init(void) | |||
1582 | 1582 | ||
1583 | platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices)); | 1583 | platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices)); |
1584 | 1584 | ||
1585 | sh7372_add_device_to_domain(&sh7372_a4lc, &lcdc_device); | ||
1586 | sh7372_add_device_to_domain(&sh7372_a4lc, &hdmi_lcdc_device); | ||
1587 | sh7372_add_device_to_domain(&sh7372_a4mp, &fsi_device); | ||
1588 | |||
1585 | hdmi_init_pm_clock(); | 1589 | hdmi_init_pm_clock(); |
1586 | sh7372_pm_init(); | 1590 | sh7372_pm_init(); |
1591 | pm_clk_add(&fsi_device.dev, "spu2"); | ||
1587 | } | 1592 | } |
1588 | 1593 | ||
1589 | static void __init mackerel_timer_init(void) | 1594 | static void __init mackerel_timer_init(void) |
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index c0800d83971e..91f5779abdd3 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c | |||
@@ -662,6 +662,7 @@ static struct clk_lookup lookups[] = { | |||
662 | CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]), | 662 | CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]), |
663 | CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]), | 663 | CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]), |
664 | CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]), | 664 | CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]), |
665 | CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]), | ||
665 | }; | 666 | }; |
666 | 667 | ||
667 | void __init sh7372_clock_init(void) | 668 | void __init sh7372_clock_init(void) |
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index df20d7670172..ce595cee86cd 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #define __ASM_SH7372_H__ | 12 | #define __ASM_SH7372_H__ |
13 | 13 | ||
14 | #include <linux/sh_clk.h> | 14 | #include <linux/sh_clk.h> |
15 | #include <linux/pm_domain.h> | ||
15 | 16 | ||
16 | /* | 17 | /* |
17 | * Pin Function Controller: | 18 | * Pin Function Controller: |
@@ -470,4 +471,32 @@ extern struct clk sh7372_fsibck_clk; | |||
470 | extern struct clk sh7372_fsidiva_clk; | 471 | extern struct clk sh7372_fsidiva_clk; |
471 | extern struct clk sh7372_fsidivb_clk; | 472 | extern struct clk sh7372_fsidivb_clk; |
472 | 473 | ||
474 | struct platform_device; | ||
475 | |||
476 | struct sh7372_pm_domain { | ||
477 | struct generic_pm_domain genpd; | ||
478 | unsigned int bit_shift; | ||
479 | }; | ||
480 | |||
481 | static inline struct sh7372_pm_domain *to_sh7372_pd(struct generic_pm_domain *d) | ||
482 | { | ||
483 | return container_of(d, struct sh7372_pm_domain, genpd); | ||
484 | } | ||
485 | |||
486 | #ifdef CONFIG_PM | ||
487 | extern struct sh7372_pm_domain sh7372_a4lc; | ||
488 | extern struct sh7372_pm_domain sh7372_a4mp; | ||
489 | extern struct sh7372_pm_domain sh7372_d4; | ||
490 | extern struct sh7372_pm_domain sh7372_a3rv; | ||
491 | extern struct sh7372_pm_domain sh7372_a3ri; | ||
492 | extern struct sh7372_pm_domain sh7372_a3sg; | ||
493 | |||
494 | extern void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd); | ||
495 | extern void sh7372_add_device_to_domain(struct sh7372_pm_domain *sh7372_pd, | ||
496 | struct platform_device *pdev); | ||
497 | #else | ||
498 | #define sh7372_init_pm_domain(pd) do { } while(0) | ||
499 | #define sh7372_add_device_to_domain(pd, pdev) do { } while(0) | ||
500 | #endif /* CONFIG_PM */ | ||
501 | |||
473 | #endif /* __ASM_SH7372_H__ */ | 502 | #endif /* __ASM_SH7372_H__ */ |
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c index 8e4aadf14c9f..933fb411be0f 100644 --- a/arch/arm/mach-shmobile/pm-sh7372.c +++ b/arch/arm/mach-shmobile/pm-sh7372.c | |||
@@ -15,16 +15,176 @@ | |||
15 | #include <linux/list.h> | 15 | #include <linux/list.h> |
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/pm_runtime.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/delay.h> | ||
18 | #include <asm/system.h> | 21 | #include <asm/system.h> |
19 | #include <asm/io.h> | 22 | #include <asm/io.h> |
20 | #include <asm/tlbflush.h> | 23 | #include <asm/tlbflush.h> |
21 | #include <mach/common.h> | 24 | #include <mach/common.h> |
25 | #include <mach/sh7372.h> | ||
22 | 26 | ||
23 | #define SMFRAM 0xe6a70000 | 27 | #define SMFRAM 0xe6a70000 |
24 | #define SYSTBCR 0xe6150024 | 28 | #define SYSTBCR 0xe6150024 |
25 | #define SBAR 0xe6180020 | 29 | #define SBAR 0xe6180020 |
26 | #define APARMBAREA 0xe6f10020 | 30 | #define APARMBAREA 0xe6f10020 |
27 | 31 | ||
32 | #define SPDCR 0xe6180008 | ||
33 | #define SWUCR 0xe6180014 | ||
34 | #define PSTR 0xe6180080 | ||
35 | |||
36 | #define PSTR_RETRIES 100 | ||
37 | #define PSTR_DELAY_US 10 | ||
38 | |||
39 | #ifdef CONFIG_PM | ||
40 | |||
41 | static int pd_power_down(struct generic_pm_domain *genpd) | ||
42 | { | ||
43 | struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd); | ||
44 | unsigned int mask = 1 << sh7372_pd->bit_shift; | ||
45 | |||
46 | if (__raw_readl(PSTR) & mask) { | ||
47 | unsigned int retry_count; | ||
48 | |||
49 | __raw_writel(mask, SPDCR); | ||
50 | |||
51 | for (retry_count = PSTR_RETRIES; retry_count; retry_count--) { | ||
52 | if (!(__raw_readl(SPDCR) & mask)) | ||
53 | break; | ||
54 | cpu_relax(); | ||
55 | } | ||
56 | } | ||
57 | |||
58 | pr_debug("sh7372 power domain down 0x%08x -> PSTR = 0x%08x\n", | ||
59 | mask, __raw_readl(PSTR)); | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static int pd_power_up(struct generic_pm_domain *genpd) | ||
65 | { | ||
66 | struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd); | ||
67 | unsigned int mask = 1 << sh7372_pd->bit_shift; | ||
68 | unsigned int retry_count; | ||
69 | int ret = 0; | ||
70 | |||
71 | if (__raw_readl(PSTR) & mask) | ||
72 | goto out; | ||
73 | |||
74 | __raw_writel(mask, SWUCR); | ||
75 | |||
76 | for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) { | ||
77 | if (!(__raw_readl(SWUCR) & mask)) | ||
78 | goto out; | ||
79 | if (retry_count > PSTR_RETRIES) | ||
80 | udelay(PSTR_DELAY_US); | ||
81 | else | ||
82 | cpu_relax(); | ||
83 | } | ||
84 | if (__raw_readl(SWUCR) & mask) | ||
85 | ret = -EIO; | ||
86 | |||
87 | out: | ||
88 | pr_debug("sh7372 power domain up 0x%08x -> PSTR = 0x%08x\n", | ||
89 | mask, __raw_readl(PSTR)); | ||
90 | |||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | static int pd_power_up_a3rv(struct generic_pm_domain *genpd) | ||
95 | { | ||
96 | int ret = pd_power_up(genpd); | ||
97 | |||
98 | /* force A4LC on after A3RV has been requested on */ | ||
99 | pm_genpd_poweron(&sh7372_a4lc.genpd); | ||
100 | |||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | static int pd_power_down_a3rv(struct generic_pm_domain *genpd) | ||
105 | { | ||
106 | int ret = pd_power_down(genpd); | ||
107 | |||
108 | /* try to power down A4LC after A3RV is requested off */ | ||
109 | genpd_queue_power_off_work(&sh7372_a4lc.genpd); | ||
110 | |||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | static int pd_power_down_a4lc(struct generic_pm_domain *genpd) | ||
115 | { | ||
116 | /* only power down A4LC if A3RV is off */ | ||
117 | if (!(__raw_readl(PSTR) & (1 << sh7372_a3rv.bit_shift))) | ||
118 | return pd_power_down(genpd); | ||
119 | |||
120 | return -EBUSY; | ||
121 | } | ||
122 | |||
123 | static bool pd_active_wakeup(struct device *dev) | ||
124 | { | ||
125 | return true; | ||
126 | } | ||
127 | |||
128 | void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd) | ||
129 | { | ||
130 | struct generic_pm_domain *genpd = &sh7372_pd->genpd; | ||
131 | |||
132 | pm_genpd_init(genpd, NULL, false); | ||
133 | genpd->stop_device = pm_clk_suspend; | ||
134 | genpd->start_device = pm_clk_resume; | ||
135 | genpd->active_wakeup = pd_active_wakeup; | ||
136 | |||
137 | if (sh7372_pd == &sh7372_a4lc) { | ||
138 | genpd->power_off = pd_power_down_a4lc; | ||
139 | genpd->power_on = pd_power_up; | ||
140 | } else if (sh7372_pd == &sh7372_a3rv) { | ||
141 | genpd->power_off = pd_power_down_a3rv; | ||
142 | genpd->power_on = pd_power_up_a3rv; | ||
143 | } else { | ||
144 | genpd->power_off = pd_power_down; | ||
145 | genpd->power_on = pd_power_up; | ||
146 | } | ||
147 | genpd->power_on(&sh7372_pd->genpd); | ||
148 | } | ||
149 | |||
150 | void sh7372_add_device_to_domain(struct sh7372_pm_domain *sh7372_pd, | ||
151 | struct platform_device *pdev) | ||
152 | { | ||
153 | struct device *dev = &pdev->dev; | ||
154 | |||
155 | if (!dev->power.subsys_data) { | ||
156 | pm_clk_init(dev); | ||
157 | pm_clk_add(dev, NULL); | ||
158 | } | ||
159 | pm_genpd_add_device(&sh7372_pd->genpd, dev); | ||
160 | } | ||
161 | |||
162 | struct sh7372_pm_domain sh7372_a4lc = { | ||
163 | .bit_shift = 1, | ||
164 | }; | ||
165 | |||
166 | struct sh7372_pm_domain sh7372_a4mp = { | ||
167 | .bit_shift = 2, | ||
168 | }; | ||
169 | |||
170 | struct sh7372_pm_domain sh7372_d4 = { | ||
171 | .bit_shift = 3, | ||
172 | }; | ||
173 | |||
174 | struct sh7372_pm_domain sh7372_a3rv = { | ||
175 | .bit_shift = 6, | ||
176 | }; | ||
177 | |||
178 | struct sh7372_pm_domain sh7372_a3ri = { | ||
179 | .bit_shift = 8, | ||
180 | }; | ||
181 | |||
182 | struct sh7372_pm_domain sh7372_a3sg = { | ||
183 | .bit_shift = 13, | ||
184 | }; | ||
185 | |||
186 | #endif /* CONFIG_PM */ | ||
187 | |||
28 | static void sh7372_enter_core_standby(void) | 188 | static void sh7372_enter_core_standby(void) |
29 | { | 189 | { |
30 | void __iomem *smfram = (void __iomem *)SMFRAM; | 190 | void __iomem *smfram = (void __iomem *)SMFRAM; |
diff --git a/arch/arm/mach-shmobile/pm_runtime.c b/arch/arm/mach-shmobile/pm_runtime.c index 2d1b67a59e4a..6ec454e1e063 100644 --- a/arch/arm/mach-shmobile/pm_runtime.c +++ b/arch/arm/mach-shmobile/pm_runtime.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/pm_runtime.h> | 16 | #include <linux/pm_runtime.h> |
17 | #include <linux/pm_domain.h> | ||
17 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
18 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
19 | #include <linux/sh_clk.h> | 20 | #include <linux/sh_clk.h> |
@@ -28,31 +29,38 @@ static int default_platform_runtime_idle(struct device *dev) | |||
28 | return pm_runtime_suspend(dev); | 29 | return pm_runtime_suspend(dev); |
29 | } | 30 | } |
30 | 31 | ||
31 | static struct dev_power_domain default_power_domain = { | 32 | static struct dev_pm_domain default_pm_domain = { |
32 | .ops = { | 33 | .ops = { |
33 | .runtime_suspend = pm_runtime_clk_suspend, | 34 | .runtime_suspend = pm_clk_suspend, |
34 | .runtime_resume = pm_runtime_clk_resume, | 35 | .runtime_resume = pm_clk_resume, |
35 | .runtime_idle = default_platform_runtime_idle, | 36 | .runtime_idle = default_platform_runtime_idle, |
36 | USE_PLATFORM_PM_SLEEP_OPS | 37 | USE_PLATFORM_PM_SLEEP_OPS |
37 | }, | 38 | }, |
38 | }; | 39 | }; |
39 | 40 | ||
40 | #define DEFAULT_PWR_DOMAIN_PTR (&default_power_domain) | 41 | #define DEFAULT_PM_DOMAIN_PTR (&default_pm_domain) |
41 | 42 | ||
42 | #else | 43 | #else |
43 | 44 | ||
44 | #define DEFAULT_PWR_DOMAIN_PTR NULL | 45 | #define DEFAULT_PM_DOMAIN_PTR NULL |
45 | 46 | ||
46 | #endif /* CONFIG_PM_RUNTIME */ | 47 | #endif /* CONFIG_PM_RUNTIME */ |
47 | 48 | ||
48 | static struct pm_clk_notifier_block platform_bus_notifier = { | 49 | static struct pm_clk_notifier_block platform_bus_notifier = { |
49 | .pwr_domain = DEFAULT_PWR_DOMAIN_PTR, | 50 | .pm_domain = DEFAULT_PM_DOMAIN_PTR, |
50 | .con_ids = { NULL, }, | 51 | .con_ids = { NULL, }, |
51 | }; | 52 | }; |
52 | 53 | ||
53 | static int __init sh_pm_runtime_init(void) | 54 | static int __init sh_pm_runtime_init(void) |
54 | { | 55 | { |
55 | pm_runtime_clk_add_notifier(&platform_bus_type, &platform_bus_notifier); | 56 | pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier); |
56 | return 0; | 57 | return 0; |
57 | } | 58 | } |
58 | core_initcall(sh_pm_runtime_init); | 59 | core_initcall(sh_pm_runtime_init); |
60 | |||
61 | static int __init sh_pm_runtime_late_init(void) | ||
62 | { | ||
63 | pm_genpd_poweroff_unused(); | ||
64 | return 0; | ||
65 | } | ||
66 | late_initcall(sh_pm_runtime_late_init); | ||
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index cd807eea69e2..79f0413d8725 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c | |||
@@ -841,11 +841,22 @@ static struct platform_device *sh7372_late_devices[] __initdata = { | |||
841 | 841 | ||
842 | void __init sh7372_add_standard_devices(void) | 842 | void __init sh7372_add_standard_devices(void) |
843 | { | 843 | { |
844 | sh7372_init_pm_domain(&sh7372_a4lc); | ||
845 | sh7372_init_pm_domain(&sh7372_a4mp); | ||
846 | sh7372_init_pm_domain(&sh7372_d4); | ||
847 | sh7372_init_pm_domain(&sh7372_a3rv); | ||
848 | sh7372_init_pm_domain(&sh7372_a3ri); | ||
849 | sh7372_init_pm_domain(&sh7372_a3sg); | ||
850 | |||
844 | platform_add_devices(sh7372_early_devices, | 851 | platform_add_devices(sh7372_early_devices, |
845 | ARRAY_SIZE(sh7372_early_devices)); | 852 | ARRAY_SIZE(sh7372_early_devices)); |
846 | 853 | ||
847 | platform_add_devices(sh7372_late_devices, | 854 | platform_add_devices(sh7372_late_devices, |
848 | ARRAY_SIZE(sh7372_late_devices)); | 855 | ARRAY_SIZE(sh7372_late_devices)); |
856 | |||
857 | sh7372_add_device_to_domain(&sh7372_a3rv, &vpu_device); | ||
858 | sh7372_add_device_to_domain(&sh7372_a4mp, &spu0_device); | ||
859 | sh7372_add_device_to_domain(&sh7372_a4mp, &spu1_device); | ||
849 | } | 860 | } |
850 | 861 | ||
851 | void __init sh7372_add_early_devices(void) | 862 | void __init sh7372_add_early_devices(void) |
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h index e4c349ff9fd8..ee405b36df4b 100644 --- a/arch/arm/plat-omap/include/plat/omap_device.h +++ b/arch/arm/plat-omap/include/plat/omap_device.h | |||
@@ -44,6 +44,10 @@ extern struct device omap_device_parent; | |||
44 | #define OMAP_DEVICE_STATE_IDLE 2 | 44 | #define OMAP_DEVICE_STATE_IDLE 2 |
45 | #define OMAP_DEVICE_STATE_SHUTDOWN 3 | 45 | #define OMAP_DEVICE_STATE_SHUTDOWN 3 |
46 | 46 | ||
47 | /* omap_device.flags values */ | ||
48 | #define OMAP_DEVICE_SUSPENDED BIT(0) | ||
49 | #define OMAP_DEVICE_NO_IDLE_ON_SUSPEND BIT(1) | ||
50 | |||
47 | /** | 51 | /** |
48 | * struct omap_device - omap_device wrapper for platform_devices | 52 | * struct omap_device - omap_device wrapper for platform_devices |
49 | * @pdev: platform_device | 53 | * @pdev: platform_device |
@@ -73,6 +77,7 @@ struct omap_device { | |||
73 | s8 pm_lat_level; | 77 | s8 pm_lat_level; |
74 | u8 hwmods_cnt; | 78 | u8 hwmods_cnt; |
75 | u8 _state; | 79 | u8 _state; |
80 | u8 flags; | ||
76 | }; | 81 | }; |
77 | 82 | ||
78 | /* Device driver interface (call via platform_data fn ptrs) */ | 83 | /* Device driver interface (call via platform_data fn ptrs) */ |
@@ -117,6 +122,10 @@ int omap_device_enable_hwmods(struct omap_device *od); | |||
117 | int omap_device_disable_clocks(struct omap_device *od); | 122 | int omap_device_disable_clocks(struct omap_device *od); |
118 | int omap_device_enable_clocks(struct omap_device *od); | 123 | int omap_device_enable_clocks(struct omap_device *od); |
119 | 124 | ||
125 | static inline void omap_device_disable_idle_on_suspend(struct omap_device *od) | ||
126 | { | ||
127 | od->flags |= OMAP_DEVICE_NO_IDLE_ON_SUSPEND; | ||
128 | } | ||
120 | 129 | ||
121 | /* | 130 | /* |
122 | * Entries should be kept in latency order ascending | 131 | * Entries should be kept in latency order ascending |
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 49fc0df0c21f..2526fa312b8a 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c | |||
@@ -537,6 +537,7 @@ int omap_early_device_register(struct omap_device *od) | |||
537 | return 0; | 537 | return 0; |
538 | } | 538 | } |
539 | 539 | ||
540 | #ifdef CONFIG_PM_RUNTIME | ||
540 | static int _od_runtime_suspend(struct device *dev) | 541 | static int _od_runtime_suspend(struct device *dev) |
541 | { | 542 | { |
542 | struct platform_device *pdev = to_platform_device(dev); | 543 | struct platform_device *pdev = to_platform_device(dev); |
@@ -563,13 +564,55 @@ static int _od_runtime_resume(struct device *dev) | |||
563 | 564 | ||
564 | return pm_generic_runtime_resume(dev); | 565 | return pm_generic_runtime_resume(dev); |
565 | } | 566 | } |
567 | #endif | ||
566 | 568 | ||
567 | static struct dev_power_domain omap_device_power_domain = { | 569 | #ifdef CONFIG_SUSPEND |
570 | static int _od_suspend_noirq(struct device *dev) | ||
571 | { | ||
572 | struct platform_device *pdev = to_platform_device(dev); | ||
573 | struct omap_device *od = to_omap_device(pdev); | ||
574 | int ret; | ||
575 | |||
576 | if (od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND) | ||
577 | return pm_generic_suspend_noirq(dev); | ||
578 | |||
579 | ret = pm_generic_suspend_noirq(dev); | ||
580 | |||
581 | if (!ret && !pm_runtime_status_suspended(dev)) { | ||
582 | if (pm_generic_runtime_suspend(dev) == 0) { | ||
583 | omap_device_idle(pdev); | ||
584 | od->flags |= OMAP_DEVICE_SUSPENDED; | ||
585 | } | ||
586 | } | ||
587 | |||
588 | return ret; | ||
589 | } | ||
590 | |||
591 | static int _od_resume_noirq(struct device *dev) | ||
592 | { | ||
593 | struct platform_device *pdev = to_platform_device(dev); | ||
594 | struct omap_device *od = to_omap_device(pdev); | ||
595 | |||
596 | if (od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND) | ||
597 | return pm_generic_resume_noirq(dev); | ||
598 | |||
599 | if ((od->flags & OMAP_DEVICE_SUSPENDED) && | ||
600 | !pm_runtime_status_suspended(dev)) { | ||
601 | od->flags &= ~OMAP_DEVICE_SUSPENDED; | ||
602 | omap_device_enable(pdev); | ||
603 | pm_generic_runtime_resume(dev); | ||
604 | } | ||
605 | |||
606 | return pm_generic_resume_noirq(dev); | ||
607 | } | ||
608 | #endif | ||
609 | |||
610 | static struct dev_pm_domain omap_device_pm_domain = { | ||
568 | .ops = { | 611 | .ops = { |
569 | .runtime_suspend = _od_runtime_suspend, | 612 | SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume, |
570 | .runtime_idle = _od_runtime_idle, | 613 | _od_runtime_idle) |
571 | .runtime_resume = _od_runtime_resume, | ||
572 | USE_PLATFORM_PM_SLEEP_OPS | 614 | USE_PLATFORM_PM_SLEEP_OPS |
615 | SET_SYSTEM_SLEEP_PM_OPS(_od_suspend_noirq, _od_resume_noirq) | ||
573 | } | 616 | } |
574 | }; | 617 | }; |
575 | 618 | ||
@@ -586,7 +629,7 @@ int omap_device_register(struct omap_device *od) | |||
586 | pr_debug("omap_device: %s: registering\n", od->pdev.name); | 629 | pr_debug("omap_device: %s: registering\n", od->pdev.name); |
587 | 630 | ||
588 | od->pdev.dev.parent = &omap_device_parent; | 631 | od->pdev.dev.parent = &omap_device_parent; |
589 | od->pdev.dev.pwr_domain = &omap_device_power_domain; | 632 | od->pdev.dev.pm_domain = &omap_device_pm_domain; |
590 | return platform_device_register(&od->pdev); | 633 | return platform_device_register(&od->pdev); |
591 | } | 634 | } |
592 | 635 | ||
diff --git a/arch/sh/kernel/cpu/shmobile/pm_runtime.c b/arch/sh/kernel/cpu/shmobile/pm_runtime.c index 64c807c39208..bf280c812d2f 100644 --- a/arch/sh/kernel/cpu/shmobile/pm_runtime.c +++ b/arch/sh/kernel/cpu/shmobile/pm_runtime.c | |||
@@ -256,7 +256,7 @@ out: | |||
256 | return ret; | 256 | return ret; |
257 | } | 257 | } |
258 | 258 | ||
259 | static struct dev_power_domain default_power_domain = { | 259 | static struct dev_pm_domain default_pm_domain = { |
260 | .ops = { | 260 | .ops = { |
261 | .runtime_suspend = default_platform_runtime_suspend, | 261 | .runtime_suspend = default_platform_runtime_suspend, |
262 | .runtime_resume = default_platform_runtime_resume, | 262 | .runtime_resume = default_platform_runtime_resume, |
@@ -285,7 +285,7 @@ static int platform_bus_notify(struct notifier_block *nb, | |||
285 | hwblk_disable(hwblk_info, hwblk); | 285 | hwblk_disable(hwblk_info, hwblk); |
286 | /* make sure driver re-inits itself once */ | 286 | /* make sure driver re-inits itself once */ |
287 | __set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags); | 287 | __set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags); |
288 | dev->pwr_domain = &default_power_domain; | 288 | dev->pm_domain = &default_pm_domain; |
289 | break; | 289 | break; |
290 | /* TODO: add BUS_NOTIFY_BIND_DRIVER and increase idle count */ | 290 | /* TODO: add BUS_NOTIFY_BIND_DRIVER and increase idle count */ |
291 | case BUS_NOTIFY_BOUND_DRIVER: | 291 | case BUS_NOTIFY_BOUND_DRIVER: |
@@ -299,7 +299,7 @@ static int platform_bus_notify(struct notifier_block *nb, | |||
299 | __set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags); | 299 | __set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags); |
300 | break; | 300 | break; |
301 | case BUS_NOTIFY_DEL_DEVICE: | 301 | case BUS_NOTIFY_DEL_DEVICE: |
302 | dev->pwr_domain = NULL; | 302 | dev->pm_domain = NULL; |
303 | break; | 303 | break; |
304 | } | 304 | } |
305 | return 0; | 305 | return 0; |