diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-shmobile/pm_runtime.c | 140 |
1 files changed, 9 insertions, 131 deletions
diff --git a/arch/arm/mach-shmobile/pm_runtime.c b/arch/arm/mach-shmobile/pm_runtime.c index 30bbe9a99ae1..2d1b67a59e4a 100644 --- a/arch/arm/mach-shmobile/pm_runtime.c +++ b/arch/arm/mach-shmobile/pm_runtime.c | |||
@@ -21,70 +21,6 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | 22 | ||
23 | #ifdef CONFIG_PM_RUNTIME | 23 | #ifdef CONFIG_PM_RUNTIME |
24 | #define BIT_ONCE 0 | ||
25 | #define BIT_ACTIVE 1 | ||
26 | #define BIT_CLK_ENABLED 2 | ||
27 | |||
28 | struct pm_runtime_data { | ||
29 | unsigned long flags; | ||
30 | struct clk *clk; | ||
31 | }; | ||
32 | |||
33 | static struct pm_runtime_data *__to_prd(struct device *dev) | ||
34 | { | ||
35 | return dev ? dev->power.subsys_data : NULL; | ||
36 | } | ||
37 | |||
38 | static void platform_pm_runtime_init(struct device *dev, | ||
39 | struct pm_runtime_data *prd) | ||
40 | { | ||
41 | if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) { | ||
42 | prd->clk = clk_get(dev, NULL); | ||
43 | if (!IS_ERR(prd->clk)) { | ||
44 | set_bit(BIT_ACTIVE, &prd->flags); | ||
45 | dev_info(dev, "clocks managed by runtime pm\n"); | ||
46 | } | ||
47 | } | ||
48 | } | ||
49 | |||
50 | static void platform_pm_runtime_bug(struct device *dev, | ||
51 | struct pm_runtime_data *prd) | ||
52 | { | ||
53 | if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) | ||
54 | dev_err(dev, "runtime pm suspend before resume\n"); | ||
55 | } | ||
56 | |||
57 | static int default_platform_runtime_suspend(struct device *dev) | ||
58 | { | ||
59 | struct pm_runtime_data *prd = __to_prd(dev); | ||
60 | |||
61 | dev_dbg(dev, "%s()\n", __func__); | ||
62 | |||
63 | platform_pm_runtime_bug(dev, prd); | ||
64 | |||
65 | if (prd && test_bit(BIT_ACTIVE, &prd->flags)) { | ||
66 | clk_disable(prd->clk); | ||
67 | clear_bit(BIT_CLK_ENABLED, &prd->flags); | ||
68 | } | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static int default_platform_runtime_resume(struct device *dev) | ||
74 | { | ||
75 | struct pm_runtime_data *prd = __to_prd(dev); | ||
76 | |||
77 | dev_dbg(dev, "%s()\n", __func__); | ||
78 | |||
79 | platform_pm_runtime_init(dev, prd); | ||
80 | |||
81 | if (prd && test_bit(BIT_ACTIVE, &prd->flags)) { | ||
82 | clk_enable(prd->clk); | ||
83 | set_bit(BIT_CLK_ENABLED, &prd->flags); | ||
84 | } | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | 24 | ||
89 | static int default_platform_runtime_idle(struct device *dev) | 25 | static int default_platform_runtime_idle(struct device *dev) |
90 | { | 26 | { |
@@ -94,87 +30,29 @@ static int default_platform_runtime_idle(struct device *dev) | |||
94 | 30 | ||
95 | static struct dev_power_domain default_power_domain = { | 31 | static struct dev_power_domain default_power_domain = { |
96 | .ops = { | 32 | .ops = { |
97 | .runtime_suspend = default_platform_runtime_suspend, | 33 | .runtime_suspend = pm_runtime_clk_suspend, |
98 | .runtime_resume = default_platform_runtime_resume, | 34 | .runtime_resume = pm_runtime_clk_resume, |
99 | .runtime_idle = default_platform_runtime_idle, | 35 | .runtime_idle = default_platform_runtime_idle, |
100 | USE_PLATFORM_PM_SLEEP_OPS | 36 | USE_PLATFORM_PM_SLEEP_OPS |
101 | }, | 37 | }, |
102 | }; | 38 | }; |
103 | 39 | ||
104 | static int platform_bus_notify(struct notifier_block *nb, | 40 | #define DEFAULT_PWR_DOMAIN_PTR (&default_power_domain) |
105 | unsigned long action, void *data) | ||
106 | { | ||
107 | struct device *dev = data; | ||
108 | struct pm_runtime_data *prd; | ||
109 | |||
110 | dev_dbg(dev, "platform_bus_notify() %ld !\n", action); | ||
111 | |||
112 | switch (action) { | ||
113 | case BUS_NOTIFY_BIND_DRIVER: | ||
114 | prd = kzalloc(sizeof(*prd), GFP_KERNEL); | ||
115 | if (prd) { | ||
116 | dev->power.subsys_data = prd; | ||
117 | dev->pwr_domain = &default_power_domain; | ||
118 | } else { | ||
119 | dev_err(dev, "unable to alloc memory for runtime pm\n"); | ||
120 | } | ||
121 | break; | ||
122 | case BUS_NOTIFY_UNBOUND_DRIVER: | ||
123 | prd = __to_prd(dev); | ||
124 | if (prd) { | ||
125 | if (test_bit(BIT_CLK_ENABLED, &prd->flags)) | ||
126 | clk_disable(prd->clk); | ||
127 | 41 | ||
128 | if (test_bit(BIT_ACTIVE, &prd->flags)) | 42 | #else |
129 | clk_put(prd->clk); | ||
130 | } | ||
131 | break; | ||
132 | } | ||
133 | 43 | ||
134 | return 0; | 44 | #define DEFAULT_PWR_DOMAIN_PTR NULL |
135 | } | ||
136 | |||
137 | #else /* CONFIG_PM_RUNTIME */ | ||
138 | |||
139 | static int platform_bus_notify(struct notifier_block *nb, | ||
140 | unsigned long action, void *data) | ||
141 | { | ||
142 | struct device *dev = data; | ||
143 | struct clk *clk; | ||
144 | |||
145 | dev_dbg(dev, "platform_bus_notify() %ld !\n", action); | ||
146 | |||
147 | switch (action) { | ||
148 | case BUS_NOTIFY_BIND_DRIVER: | ||
149 | clk = clk_get(dev, NULL); | ||
150 | if (!IS_ERR(clk)) { | ||
151 | clk_enable(clk); | ||
152 | clk_put(clk); | ||
153 | dev_info(dev, "runtime pm disabled, clock forced on\n"); | ||
154 | } | ||
155 | break; | ||
156 | case BUS_NOTIFY_UNBOUND_DRIVER: | ||
157 | clk = clk_get(dev, NULL); | ||
158 | if (!IS_ERR(clk)) { | ||
159 | clk_disable(clk); | ||
160 | clk_put(clk); | ||
161 | dev_info(dev, "runtime pm disabled, clock forced off\n"); | ||
162 | } | ||
163 | break; | ||
164 | } | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | 45 | ||
169 | #endif /* CONFIG_PM_RUNTIME */ | 46 | #endif /* CONFIG_PM_RUNTIME */ |
170 | 47 | ||
171 | static struct notifier_block platform_bus_notifier = { | 48 | static struct pm_clk_notifier_block platform_bus_notifier = { |
172 | .notifier_call = platform_bus_notify | 49 | .pwr_domain = DEFAULT_PWR_DOMAIN_PTR, |
50 | .con_ids = { NULL, }, | ||
173 | }; | 51 | }; |
174 | 52 | ||
175 | static int __init sh_pm_runtime_init(void) | 53 | static int __init sh_pm_runtime_init(void) |
176 | { | 54 | { |
177 | bus_register_notifier(&platform_bus_type, &platform_bus_notifier); | 55 | pm_runtime_clk_add_notifier(&platform_bus_type, &platform_bus_notifier); |
178 | return 0; | 56 | return 0; |
179 | } | 57 | } |
180 | core_initcall(sh_pm_runtime_init); | 58 | core_initcall(sh_pm_runtime_init); |