aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/omap2430.c
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2010-12-02 05:44:40 -0500
committerFelipe Balbi <balbi@ti.com>2010-12-10 03:21:29 -0500
commitc20aebb92796cf54ae8171ad7f53a8fa7c61d2d8 (patch)
tree74ec7c7b0887d706dd50718db81eb80a996b20f4 /drivers/usb/musb/omap2430.c
parente6326358a43a9ac23f6df69ed1f4707c0d1ac473 (diff)
usb: musb: omap2430: use dev_pm_ops structure
instead of using musb_platform_suspend/resume, we can use dev_pm_ops and let the platform_device core handle when to call musb_core's suspend and glue layer's suspend. Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/musb/omap2430.c')
-rw-r--r--drivers/usb/musb/omap2430.c146
1 files changed, 87 insertions, 59 deletions
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index ef0f7fe92f13..5939823990c9 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -42,6 +42,7 @@ struct omap2430_glue {
42 struct platform_device *musb; 42 struct platform_device *musb;
43 struct clk *clk; 43 struct clk *clk;
44}; 44};
45#define glue_to_musb(g) platform_get_drvdata(g->musb)
45 46
46static struct timer_list musb_idle_timer; 47static struct timer_list musb_idle_timer;
47 48
@@ -176,8 +177,6 @@ static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
176 musb_readb(musb->mregs, MUSB_DEVCTL)); 177 musb_readb(musb->mregs, MUSB_DEVCTL));
177} 178}
178 179
179static int omap2430_musb_resume(struct musb *musb);
180
181static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode) 180static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode)
182{ 181{
183 u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); 182 u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
@@ -188,6 +187,33 @@ static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode)
188 return 0; 187 return 0;
189} 188}
190 189
190static inline void omap2430_low_level_exit(struct musb *musb)
191{
192 u32 l;
193
194 /* in any role */
195 l = musb_readl(musb->mregs, OTG_FORCESTDBY);
196 l |= ENABLEFORCE; /* enable MSTANDBY */
197 musb_writel(musb->mregs, OTG_FORCESTDBY, l);
198
199 l = musb_readl(musb->mregs, OTG_SYSCONFIG);
200 l |= ENABLEWAKEUP; /* enable wakeup */
201 musb_writel(musb->mregs, OTG_SYSCONFIG, l);
202}
203
204static inline void omap2430_low_level_init(struct musb *musb)
205{
206 u32 l;
207
208 l = musb_readl(musb->mregs, OTG_SYSCONFIG);
209 l &= ~ENABLEWAKEUP; /* disable wakeup */
210 musb_writel(musb->mregs, OTG_SYSCONFIG, l);
211
212 l = musb_readl(musb->mregs, OTG_FORCESTDBY);
213 l &= ~ENABLEFORCE; /* disable MSTANDBY */
214 musb_writel(musb->mregs, OTG_FORCESTDBY, l);
215}
216
191static int omap2430_musb_init(struct musb *musb) 217static int omap2430_musb_init(struct musb *musb)
192{ 218{
193 u32 l; 219 u32 l;
@@ -205,7 +231,7 @@ static int omap2430_musb_init(struct musb *musb)
205 return -ENODEV; 231 return -ENODEV;
206 } 232 }
207 233
208 omap2430_musb_resume(musb); 234 omap2430_low_level_init(musb);
209 235
210 l = musb_readl(musb->mregs, OTG_SYSCONFIG); 236 l = musb_readl(musb->mregs, OTG_SYSCONFIG);
211 l &= ~ENABLEWAKEUP; /* disable wakeup */ 237 l &= ~ENABLEWAKEUP; /* disable wakeup */
@@ -250,63 +276,12 @@ static int omap2430_musb_init(struct musb *musb)
250 return 0; 276 return 0;
251} 277}
252 278
253static void omap2430_save_context(struct musb *musb)
254{
255 musb->context.otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG);
256 musb->context.otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY);
257}
258
259static void omap2430_restore_context(struct musb *musb)
260{
261 musb_writel(musb->mregs, OTG_SYSCONFIG, musb->context.otg_sysconfig);
262 musb_writel(musb->mregs, OTG_FORCESTDBY, musb->context.otg_forcestandby);
263}
264
265static int omap2430_musb_suspend(struct musb *musb)
266{
267 u32 l;
268
269 /* in any role */
270 l = musb_readl(musb->mregs, OTG_FORCESTDBY);
271 l |= ENABLEFORCE; /* enable MSTANDBY */
272 musb_writel(musb->mregs, OTG_FORCESTDBY, l);
273
274 l = musb_readl(musb->mregs, OTG_SYSCONFIG);
275 l |= ENABLEWAKEUP; /* enable wakeup */
276 musb_writel(musb->mregs, OTG_SYSCONFIG, l);
277
278 omap2430_save_context(musb);
279
280 otg_set_suspend(musb->xceiv, 1);
281
282 return 0;
283}
284
285static int omap2430_musb_resume(struct musb *musb)
286{
287 u32 l;
288
289 otg_set_suspend(musb->xceiv, 0);
290
291 omap2430_restore_context(musb);
292
293 l = musb_readl(musb->mregs, OTG_SYSCONFIG);
294 l &= ~ENABLEWAKEUP; /* disable wakeup */
295 musb_writel(musb->mregs, OTG_SYSCONFIG, l);
296
297 l = musb_readl(musb->mregs, OTG_FORCESTDBY);
298 l &= ~ENABLEFORCE; /* disable MSTANDBY */
299 musb_writel(musb->mregs, OTG_FORCESTDBY, l);
300
301 return 0;
302}
303
304static int omap2430_musb_exit(struct musb *musb) 279static int omap2430_musb_exit(struct musb *musb)
305{ 280{
306 281
307 omap2430_musb_suspend(musb); 282 omap2430_low_level_exit(musb);
308
309 otg_put_transceiver(musb->xceiv); 283 otg_put_transceiver(musb->xceiv);
284
310 return 0; 285 return 0;
311} 286}
312 287
@@ -314,9 +289,6 @@ static const struct musb_platform_ops omap2430_ops = {
314 .init = omap2430_musb_init, 289 .init = omap2430_musb_init,
315 .exit = omap2430_musb_exit, 290 .exit = omap2430_musb_exit,
316 291
317 .suspend = omap2430_musb_suspend,
318 .resume = omap2430_musb_resume,
319
320 .set_mode = omap2430_musb_set_mode, 292 .set_mode = omap2430_musb_set_mode,
321 .try_idle = omap2430_musb_try_idle, 293 .try_idle = omap2430_musb_try_idle,
322 294
@@ -421,10 +393,66 @@ static int __exit omap2430_remove(struct platform_device *pdev)
421 return 0; 393 return 0;
422} 394}
423 395
396#ifdef CONFIG_PM
397static void omap2430_save_context(struct musb *musb)
398{
399 musb->context.otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG);
400 musb->context.otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY);
401}
402
403static void omap2430_restore_context(struct musb *musb)
404{
405 musb_writel(musb->mregs, OTG_SYSCONFIG, musb->context.otg_sysconfig);
406 musb_writel(musb->mregs, OTG_FORCESTDBY, musb->context.otg_forcestandby);
407}
408
409static int omap2430_suspend(struct device *dev)
410{
411 struct omap2430_glue *glue = dev_get_drvdata(dev);
412 struct musb *musb = glue_to_musb(glue);
413
414 omap2430_low_level_exit(musb);
415 otg_set_suspend(musb->xceiv, 1);
416 omap2430_save_context(musb);
417 clk_disable(glue->clk);
418
419 return 0;
420}
421
422static int omap2430_resume(struct device *dev)
423{
424 struct omap2430_glue *glue = dev_get_drvdata(dev);
425 struct musb *musb = glue_to_musb(glue);
426 int ret;
427
428 ret = clk_enable(glue->clk);
429 if (ret) {
430 dev_err(dev, "faled to enable clock\n");
431 return ret;
432 }
433
434 omap2430_low_level_init(musb);
435 omap2430_restore_context(musb);
436 otg_set_suspend(musb->xceiv, 0);
437
438 return 0;
439}
440
441static struct dev_pm_ops omap2430_pm_ops = {
442 .suspend = omap2430_suspend,
443 .resume = omap2430_resume,
444};
445
446#define DEV_PM_OPS (&omap2430_pm_ops)
447#else
448#define DEV_PM_OPS NULL
449#endif
450
424static struct platform_driver omap2430_driver = { 451static struct platform_driver omap2430_driver = {
425 .remove = __exit_p(omap2430_remove), 452 .remove = __exit_p(omap2430_remove),
426 .driver = { 453 .driver = {
427 .name = "musb-omap2430", 454 .name = "musb-omap2430",
455 .pm = DEV_PM_OPS,
428 }, 456 },
429}; 457};
430 458