diff options
author | Grazvydas Ignotas <notasas@gmail.com> | 2012-02-04 18:43:51 +0100 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-04-10 18:11:43 +0200 |
commit | c04352a590538123f8c93bd87ef1d4bb9e3a64c7 (patch) | |
tree | b4c4b1881f1168e2e82b33fe8af357fed5085392 | |
parent | usb: musb: fix oops on omap2430 module unload (diff) | |
download | linux-c04352a590538123f8c93bd87ef1d4bb9e3a64c7.tar.xz linux-c04352a590538123f8c93bd87ef1d4bb9e3a64c7.zip |
usb: musb: fix some runtime_pm issues
When runtime_pm was originally added, it was done in rather confusing
way: omap2430_musb_init() (called from musb_init_controller) would do
runtime_pm_get_sync() and musb_init_controller() itself would do
runtime_pm_put to balance it out. This is not only confusing but also
wrong if non-omap2430 glue layer is used.
This confusion resulted in commit 772aed45b604 "usb: musb: fix
pm_runtime mismatch", that removed runtime_pm_put() from
musb_init_controller as that looked unbalanced, and also happened to
fix unrelated isp1704_charger crash. However this broke runtime PM
functionality (musb is now always powered, even without gadget active).
Avoid these confusing runtime pm dependences by making
musb_init_controller() and omap2430_musb_init() do their own runtime
get/put pairs; also cover error paths. Remove unneeded runtime_pm_put
in omap2430_remove too. isp1704_charger crash that motivated
772aed45b604 will be fixed by following patch.
Cc: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r-- | drivers/usb/musb/musb_core.c | 9 | ||||
-rw-r--r-- | drivers/usb/musb/omap2430.c | 2 |
2 files changed, 9 insertions, 2 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 0f8b82918a40..239214626ec5 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1904,7 +1904,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (!musb->isr) { status = -ENODEV; - goto fail3; + goto fail2; } if (!musb->xceiv->io_ops) { @@ -1912,6 +1912,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) musb->xceiv->io_ops = &musb_ulpi_access; } + pm_runtime_get_sync(musb->controller); + #ifndef CONFIG_MUSB_PIO_ONLY if (use_dma && dev->dma_mask) { struct dma_controller *c; @@ -2023,6 +2025,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) goto fail5; #endif + pm_runtime_put(musb->controller); + dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n", ({char *s; switch (musb->board_mode) { @@ -2047,6 +2051,9 @@ fail4: musb_gadget_cleanup(musb); fail3: + pm_runtime_put_sync(musb->controller); + +fail2: if (musb->irq_wake) device_init_wakeup(dev, 0); musb_platform_exit(musb); diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 11b571ec22f2..3dfd122266f4 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -333,6 +333,7 @@ static int omap2430_musb_init(struct musb *musb) setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); + pm_runtime_put_noidle(musb->controller); return 0; err1: @@ -478,7 +479,6 @@ static int __devexit omap2430_remove(struct platform_device *pdev) platform_device_del(glue->musb); platform_device_put(glue->musb); - pm_runtime_put(&pdev->dev); kfree(glue); return 0; |