aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb
diff options
context:
space:
mode:
authorHema HK <hemahk@ti.com>2011-02-17 01:37:22 -0500
committerFelipe Balbi <balbi@ti.com>2011-02-17 14:11:46 -0500
commit207b0e1f1655bd7008b7322cdc3f84fb171c546d (patch)
tree1fbc66d4fe420cff2065dde94481eb670afc9b73 /drivers/usb/musb
parentad1adb89a0d9410345d573b6995a1fa9f9b7c74a (diff)
usb: musb: Using runtime pm APIs for musb.
Calling runtime pm APIs pm_runtime_put_sync() and pm_runtime_get_sync() for enabling/disabling the clocks, sysconfig settings. Enable clock, configure no-idle/standby when active and configure force idle/standby and disable clock when idled. This is taken care by the runtime framework when driver calls the pm_runtime_get_sync and pm_runtime_put_sync APIs. Need to configure MUSB into force standby and force idle mode when usb not used Signed-off-by: Hema HK <hemahk@ti.com> Cc: Tony Lindgren <tony@atomide.com> Cc: Kevin Hilman <khilman@deeprootsystems.com> Cc: Cousson, Benoit <b-cousson@ti.com> Cc: Paul Walmsley <paul@pwsan.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r--drivers/usb/musb/musb_core.h2
-rw-r--r--drivers/usb/musb/omap2430.c81
2 files changed, 24 insertions, 59 deletions
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 2c8dde6d23e0..5216729bd4b2 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -360,7 +360,7 @@ struct musb_context_registers {
360 360
361#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ 361#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
362 defined(CONFIG_ARCH_OMAP4) 362 defined(CONFIG_ARCH_OMAP4)
363 u32 otg_sysconfig, otg_forcestandby; 363 u32 otg_forcestandby;
364#endif 364#endif
365 u8 power; 365 u8 power;
366 u16 intrtxe, intrrxe; 366 u16 intrtxe, intrrxe;
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index a3f12333fc41..bb6e6cd330da 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -33,6 +33,8 @@
33#include <linux/io.h> 33#include <linux/io.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
36#include <linux/pm_runtime.h>
37#include <linux/err.h>
36 38
37#include "musb_core.h" 39#include "musb_core.h"
38#include "omap2430.h" 40#include "omap2430.h"
@@ -40,7 +42,6 @@
40struct omap2430_glue { 42struct omap2430_glue {
41 struct device *dev; 43 struct device *dev;
42 struct platform_device *musb; 44 struct platform_device *musb;
43 struct clk *clk;
44}; 45};
45#define glue_to_musb(g) platform_get_drvdata(g->musb) 46#define glue_to_musb(g) platform_get_drvdata(g->musb)
46 47
@@ -216,20 +217,12 @@ static inline void omap2430_low_level_exit(struct musb *musb)
216 l = musb_readl(musb->mregs, OTG_FORCESTDBY); 217 l = musb_readl(musb->mregs, OTG_FORCESTDBY);
217 l |= ENABLEFORCE; /* enable MSTANDBY */ 218 l |= ENABLEFORCE; /* enable MSTANDBY */
218 musb_writel(musb->mregs, OTG_FORCESTDBY, l); 219 musb_writel(musb->mregs, OTG_FORCESTDBY, l);
219
220 l = musb_readl(musb->mregs, OTG_SYSCONFIG);
221 l |= ENABLEWAKEUP; /* enable wakeup */
222 musb_writel(musb->mregs, OTG_SYSCONFIG, l);
223} 220}
224 221
225static inline void omap2430_low_level_init(struct musb *musb) 222static inline void omap2430_low_level_init(struct musb *musb)
226{ 223{
227 u32 l; 224 u32 l;
228 225
229 l = musb_readl(musb->mregs, OTG_SYSCONFIG);
230 l &= ~ENABLEWAKEUP; /* disable wakeup */
231 musb_writel(musb->mregs, OTG_SYSCONFIG, l);
232
233 l = musb_readl(musb->mregs, OTG_FORCESTDBY); 226 l = musb_readl(musb->mregs, OTG_FORCESTDBY);
234 l &= ~ENABLEFORCE; /* disable MSTANDBY */ 227 l &= ~ENABLEFORCE; /* disable MSTANDBY */
235 musb_writel(musb->mregs, OTG_FORCESTDBY, l); 228 musb_writel(musb->mregs, OTG_FORCESTDBY, l);
@@ -309,21 +302,6 @@ static int omap2430_musb_init(struct musb *musb)
309 302
310 omap2430_low_level_init(musb); 303 omap2430_low_level_init(musb);
311 304
312 l = musb_readl(musb->mregs, OTG_SYSCONFIG);
313 l &= ~ENABLEWAKEUP; /* disable wakeup */
314 l &= ~NOSTDBY; /* remove possible nostdby */
315 l |= SMARTSTDBY; /* enable smart standby */
316 l &= ~AUTOIDLE; /* disable auto idle */
317 l &= ~NOIDLE; /* remove possible noidle */
318 l |= SMARTIDLE; /* enable smart idle */
319 /*
320 * MUSB AUTOIDLE don't work in 3430.
321 * Workaround by Richard Woodruff/TI
322 */
323 if (!cpu_is_omap3430())
324 l |= AUTOIDLE; /* enable auto idle */
325 musb_writel(musb->mregs, OTG_SYSCONFIG, l);
326
327 l = musb_readl(musb->mregs, OTG_INTERFSEL); 305 l = musb_readl(musb->mregs, OTG_INTERFSEL);
328 306
329 if (data->interface_type == MUSB_INTERFACE_UTMI) { 307 if (data->interface_type == MUSB_INTERFACE_UTMI) {
@@ -386,7 +364,7 @@ static int __init omap2430_probe(struct platform_device *pdev)
386 struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; 364 struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
387 struct platform_device *musb; 365 struct platform_device *musb;
388 struct omap2430_glue *glue; 366 struct omap2430_glue *glue;
389 struct clk *clk; 367 int status = 0;
390 368
391 int ret = -ENOMEM; 369 int ret = -ENOMEM;
392 370
@@ -402,26 +380,12 @@ static int __init omap2430_probe(struct platform_device *pdev)
402 goto err1; 380 goto err1;
403 } 381 }
404 382
405 clk = clk_get(&pdev->dev, "ick");
406 if (IS_ERR(clk)) {
407 dev_err(&pdev->dev, "failed to get clock\n");
408 ret = PTR_ERR(clk);
409 goto err2;
410 }
411
412 ret = clk_enable(clk);
413 if (ret) {
414 dev_err(&pdev->dev, "failed to enable clock\n");
415 goto err3;
416 }
417
418 musb->dev.parent = &pdev->dev; 383 musb->dev.parent = &pdev->dev;
419 musb->dev.dma_mask = &omap2430_dmamask; 384 musb->dev.dma_mask = &omap2430_dmamask;
420 musb->dev.coherent_dma_mask = omap2430_dmamask; 385 musb->dev.coherent_dma_mask = omap2430_dmamask;
421 386
422 glue->dev = &pdev->dev; 387 glue->dev = &pdev->dev;
423 glue->musb = musb; 388 glue->musb = musb;
424 glue->clk = clk;
425 389
426 pdata->platform_ops = &omap2430_ops; 390 pdata->platform_ops = &omap2430_ops;
427 391
@@ -431,29 +395,32 @@ static int __init omap2430_probe(struct platform_device *pdev)
431 pdev->num_resources); 395 pdev->num_resources);
432 if (ret) { 396 if (ret) {
433 dev_err(&pdev->dev, "failed to add resources\n"); 397 dev_err(&pdev->dev, "failed to add resources\n");
434 goto err4; 398 goto err2;
435 } 399 }
436 400
437 ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); 401 ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
438 if (ret) { 402 if (ret) {
439 dev_err(&pdev->dev, "failed to add platform_data\n"); 403 dev_err(&pdev->dev, "failed to add platform_data\n");
440 goto err4; 404 goto err2;
441 } 405 }
442 406
443 ret = platform_device_add(musb); 407 ret = platform_device_add(musb);
444 if (ret) { 408 if (ret) {
445 dev_err(&pdev->dev, "failed to register musb device\n"); 409 dev_err(&pdev->dev, "failed to register musb device\n");
446 goto err4; 410 goto err2;
447 } 411 }
448 412
449 return 0; 413 pm_runtime_enable(&pdev->dev);
414 status = pm_runtime_get_sync(&pdev->dev);
415 if (status < 0) {
416 dev_err(&pdev->dev, "pm_runtime_get_sync FAILED");
417 goto err3;
418 }
450 419
451err4: 420 return 0;
452 clk_disable(clk);
453 421
454err3: 422err3:
455 clk_put(clk); 423 pm_runtime_disable(&pdev->dev);
456
457err2: 424err2:
458 platform_device_put(musb); 425 platform_device_put(musb);
459 426
@@ -470,8 +437,8 @@ static int __exit omap2430_remove(struct platform_device *pdev)
470 437
471 platform_device_del(glue->musb); 438 platform_device_del(glue->musb);
472 platform_device_put(glue->musb); 439 platform_device_put(glue->musb);
473 clk_disable(glue->clk); 440 pm_runtime_put(&pdev->dev);
474 clk_put(glue->clk); 441 pm_runtime_disable(&pdev->dev);
475 kfree(glue); 442 kfree(glue);
476 443
477 return 0; 444 return 0;
@@ -480,13 +447,11 @@ static int __exit omap2430_remove(struct platform_device *pdev)
480#ifdef CONFIG_PM 447#ifdef CONFIG_PM
481static void omap2430_save_context(struct musb *musb) 448static void omap2430_save_context(struct musb *musb)
482{ 449{
483 musb->context.otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG);
484 musb->context.otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY); 450 musb->context.otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY);
485} 451}
486 452
487static void omap2430_restore_context(struct musb *musb) 453static void omap2430_restore_context(struct musb *musb)
488{ 454{
489 musb_writel(musb->mregs, OTG_SYSCONFIG, musb->context.otg_sysconfig);
490 musb_writel(musb->mregs, OTG_FORCESTDBY, musb->context.otg_forcestandby); 455 musb_writel(musb->mregs, OTG_FORCESTDBY, musb->context.otg_forcestandby);
491} 456}
492 457
@@ -498,7 +463,10 @@ static int omap2430_suspend(struct device *dev)
498 omap2430_low_level_exit(musb); 463 omap2430_low_level_exit(musb);
499 otg_set_suspend(musb->xceiv, 1); 464 otg_set_suspend(musb->xceiv, 1);
500 omap2430_save_context(musb); 465 omap2430_save_context(musb);
501 clk_disable(glue->clk); 466
467 if (!pm_runtime_suspended(dev) && dev->bus && dev->bus->pm &&
468 dev->bus->pm->runtime_suspend)
469 dev->bus->pm->runtime_suspend(dev);
502 470
503 return 0; 471 return 0;
504} 472}
@@ -507,13 +475,10 @@ static int omap2430_resume(struct device *dev)
507{ 475{
508 struct omap2430_glue *glue = dev_get_drvdata(dev); 476 struct omap2430_glue *glue = dev_get_drvdata(dev);
509 struct musb *musb = glue_to_musb(glue); 477 struct musb *musb = glue_to_musb(glue);
510 int ret;
511 478
512 ret = clk_enable(glue->clk); 479 if (!pm_runtime_suspended(dev) && dev->bus && dev->bus->pm &&
513 if (ret) { 480 dev->bus->pm->runtime_resume)
514 dev_err(dev, "faled to enable clock\n"); 481 dev->bus->pm->runtime_resume(dev);
515 return ret;
516 }
517 482
518 omap2430_low_level_init(musb); 483 omap2430_low_level_init(musb);
519 omap2430_restore_context(musb); 484 omap2430_restore_context(musb);