aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile/pm-sh7372.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-11-27 07:11:36 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2011-12-01 15:47:08 -0500
commitd5e4cbfe2049fca375cb19c4bc0cf676e8b4a88a (patch)
tree51dfa4b178a53e884d310faad496aed07eee565b /arch/arm/mach-shmobile/pm-sh7372.c
parentb930c26416c4ea6855726fd977145ccea9afbdda (diff)
PM / Domains: Make it possible to use per-device domain callbacks
The current generic PM domains code requires that the same .stop(), .start() and .active_wakeup() device callback routines be used for all devices in the given domain, which is inflexible and may not cover some specific use cases. For this reason, make it possible to use device specific .start()/.stop() and .active_wakeup() callback routines by adding corresponding callback pointers to struct generic_pm_domain_data. Add a new helper routine, pm_genpd_register_callbacks(), that can be used to populate the new per-device callback pointers. Modify the shmobile's power domains code to allow drivers to add their own code to be run during the device stop and start operations with the help of the new callback pointers. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Magnus Damm <damm@opensource.se>
Diffstat (limited to 'arch/arm/mach-shmobile/pm-sh7372.c')
-rw-r--r--arch/arm/mach-shmobile/pm-sh7372.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c
index 34bbcbfb1706..6777bb1be059 100644
--- a/arch/arm/mach-shmobile/pm-sh7372.c
+++ b/arch/arm/mach-shmobile/pm-sh7372.c
@@ -156,7 +156,10 @@ static void sh7372_a4r_suspend(void)
156 156
157static bool pd_active_wakeup(struct device *dev) 157static bool pd_active_wakeup(struct device *dev)
158{ 158{
159 return true; 159 bool (*active_wakeup)(struct device *dev);
160
161 active_wakeup = dev_gpd_data(dev)->ops.active_wakeup;
162 return active_wakeup ? active_wakeup(dev) : true;
160} 163}
161 164
162static bool sh7372_power_down_forbidden(struct dev_pm_domain *domain) 165static bool sh7372_power_down_forbidden(struct dev_pm_domain *domain)
@@ -168,15 +171,44 @@ struct dev_power_governor sh7372_always_on_gov = {
168 .power_down_ok = sh7372_power_down_forbidden, 171 .power_down_ok = sh7372_power_down_forbidden,
169}; 172};
170 173
174static int sh7372_stop_dev(struct device *dev)
175{
176 int (*stop)(struct device *dev);
177
178 stop = dev_gpd_data(dev)->ops.stop;
179 if (stop) {
180 int ret = stop(dev);
181 if (ret)
182 return ret;
183 }
184 return pm_clk_suspend(dev);
185}
186
187static int sh7372_start_dev(struct device *dev)
188{
189 int (*start)(struct device *dev);
190 int ret;
191
192 ret = pm_clk_resume(dev);
193 if (ret)
194 return ret;
195
196 start = dev_gpd_data(dev)->ops.start;
197 if (start)
198 ret = start(dev);
199
200 return ret;
201}
202
171void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd) 203void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd)
172{ 204{
173 struct generic_pm_domain *genpd = &sh7372_pd->genpd; 205 struct generic_pm_domain *genpd = &sh7372_pd->genpd;
174 206
175 pm_genpd_init(genpd, sh7372_pd->gov, false); 207 pm_genpd_init(genpd, sh7372_pd->gov, false);
176 genpd->stop_device = pm_clk_suspend; 208 genpd->dev_ops.stop = sh7372_stop_dev;
177 genpd->start_device = pm_clk_resume; 209 genpd->dev_ops.start = sh7372_start_dev;
210 genpd->dev_ops.active_wakeup = pd_active_wakeup;
178 genpd->dev_irq_safe = true; 211 genpd->dev_irq_safe = true;
179 genpd->active_wakeup = pd_active_wakeup;
180 genpd->power_off = pd_power_down; 212 genpd->power_off = pd_power_down;
181 genpd->power_on = pd_power_up; 213 genpd->power_on = pd_power_up;
182 __pd_power_up(sh7372_pd, false); 214 __pd_power_up(sh7372_pd, false);