diff options
-rw-r--r-- | drivers/usb/musb/musb_core.h | 2 | ||||
-rw-r--r-- | drivers/usb/musb/omap2430.c | 81 |
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 @@ | |||
40 | struct omap2430_glue { | 42 | struct 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 | ||
225 | static inline void omap2430_low_level_init(struct musb *musb) | 222 | static 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 | ||
451 | err4: | 420 | return 0; |
452 | clk_disable(clk); | ||
453 | 421 | ||
454 | err3: | 422 | err3: |
455 | clk_put(clk); | 423 | pm_runtime_disable(&pdev->dev); |
456 | |||
457 | err2: | 424 | err2: |
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 |
481 | static void omap2430_save_context(struct musb *musb) | 448 | static 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 | ||
487 | static void omap2430_restore_context(struct musb *musb) | 453 | static 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); |