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 commit772aed45b6
"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 motivated772aed45b6
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>
This commit is contained in:
parent
afb76df140
commit
c04352a590
|
@ -1904,7 +1904,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
|
||||||
|
|
||||||
if (!musb->isr) {
|
if (!musb->isr) {
|
||||||
status = -ENODEV;
|
status = -ENODEV;
|
||||||
goto fail3;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!musb->xceiv->io_ops) {
|
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;
|
musb->xceiv->io_ops = &musb_ulpi_access;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pm_runtime_get_sync(musb->controller);
|
||||||
|
|
||||||
#ifndef CONFIG_MUSB_PIO_ONLY
|
#ifndef CONFIG_MUSB_PIO_ONLY
|
||||||
if (use_dma && dev->dma_mask) {
|
if (use_dma && dev->dma_mask) {
|
||||||
struct dma_controller *c;
|
struct dma_controller *c;
|
||||||
|
@ -2023,6 +2025,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
|
||||||
goto fail5;
|
goto fail5;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
pm_runtime_put(musb->controller);
|
||||||
|
|
||||||
dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
|
dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
|
||||||
({char *s;
|
({char *s;
|
||||||
switch (musb->board_mode) {
|
switch (musb->board_mode) {
|
||||||
|
@ -2047,6 +2051,9 @@ fail4:
|
||||||
musb_gadget_cleanup(musb);
|
musb_gadget_cleanup(musb);
|
||||||
|
|
||||||
fail3:
|
fail3:
|
||||||
|
pm_runtime_put_sync(musb->controller);
|
||||||
|
|
||||||
|
fail2:
|
||||||
if (musb->irq_wake)
|
if (musb->irq_wake)
|
||||||
device_init_wakeup(dev, 0);
|
device_init_wakeup(dev, 0);
|
||||||
musb_platform_exit(musb);
|
musb_platform_exit(musb);
|
||||||
|
|
|
@ -333,6 +333,7 @@ static int omap2430_musb_init(struct musb *musb)
|
||||||
|
|
||||||
setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
|
setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
|
||||||
|
|
||||||
|
pm_runtime_put_noidle(musb->controller);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err1:
|
err1:
|
||||||
|
@ -478,7 +479,6 @@ static int __devexit omap2430_remove(struct platform_device *pdev)
|
||||||
|
|
||||||
platform_device_del(glue->musb);
|
platform_device_del(glue->musb);
|
||||||
platform_device_put(glue->musb);
|
platform_device_put(glue->musb);
|
||||||
pm_runtime_put(&pdev->dev);
|
|
||||||
kfree(glue);
|
kfree(glue);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue