Commit 8f2279d5 authored by Tony Lindgren's avatar Tony Lindgren

usb: musb: omap2430: Fix regression caused by driver core change

Commit ddef08dd ("Driver core: wakeup the parent device before trying
probe") started automatically ensuring the parent device is enabled when
the child gets probed.

This however caused a regression for MUSB omap2430 interface as the
runtime PM for the parent device needs the child initialized to access
the MUSB hardware registers.

Let's delay the enabling of PM runtime for the parent until the child
has been properly initialized as suggested in an earlier patch by
Grygorii Strashko <grygorii.strashko@ti.com>.

In addition to delaying pm_runtime_enable, we now also need to make sure
the parent is enabled during omap2430_musb_init. We also want to propagate
an error from omap2430_runtime_resume if struct musb is not initialized.

Note that we use pm_runtime_put_noidle here for both the child and parent
to prevent an extra runtime_suspend/resume cycle.

Let's also add some comments to avoid confusion between the
two different devices.

Fixes: ddef08dd ("Driver core: wakeup the parent device before
trying probe")
Suggested-by: default avatarGrygorii Strashko <grygorii.strashko@ti.com>
Reviewed-by: default avatarGrygorii Strashko <grygorii.strashko@ti.com>
Acked-by: default avatarFelipe Balbi <balbi@ti.com>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 1bd5dfe4
...@@ -391,9 +391,20 @@ static int omap2430_musb_init(struct musb *musb) ...@@ -391,9 +391,20 @@ static int omap2430_musb_init(struct musb *musb)
} }
musb->isr = omap2430_musb_interrupt; musb->isr = omap2430_musb_interrupt;
/*
* Enable runtime PM for musb parent (this driver). We can't
* do it earlier as struct musb is not yet allocated and we
* need to touch the musb registers for runtime PM.
*/
pm_runtime_enable(glue->dev);
status = pm_runtime_get_sync(glue->dev);
if (status < 0)
goto err1;
status = pm_runtime_get_sync(dev); status = pm_runtime_get_sync(dev);
if (status < 0) { if (status < 0) {
dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status); dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
pm_runtime_put_sync(glue->dev);
goto err1; goto err1;
} }
...@@ -426,6 +437,7 @@ static int omap2430_musb_init(struct musb *musb) ...@@ -426,6 +437,7 @@ static int omap2430_musb_init(struct musb *musb)
phy_power_on(musb->phy); phy_power_on(musb->phy);
pm_runtime_put_noidle(musb->controller); pm_runtime_put_noidle(musb->controller);
pm_runtime_put_noidle(glue->dev);
return 0; return 0;
err1: err1:
...@@ -626,7 +638,11 @@ static int omap2430_probe(struct platform_device *pdev) ...@@ -626,7 +638,11 @@ static int omap2430_probe(struct platform_device *pdev)
goto err2; goto err2;
} }
pm_runtime_enable(&pdev->dev); /*
* Note that we cannot enable PM runtime yet for this
* driver as we need struct musb initialized first.
* See omap2430_musb_init above.
*/
ret = platform_device_add(musb); ret = platform_device_add(musb);
if (ret) { if (ret) {
...@@ -675,11 +691,12 @@ static int omap2430_runtime_resume(struct device *dev) ...@@ -675,11 +691,12 @@ static int omap2430_runtime_resume(struct device *dev)
struct omap2430_glue *glue = dev_get_drvdata(dev); struct omap2430_glue *glue = dev_get_drvdata(dev);
struct musb *musb = glue_to_musb(glue); struct musb *musb = glue_to_musb(glue);
if (musb) { if (!musb)
omap2430_low_level_init(musb); return -EPROBE_DEFER;
musb_writel(musb->mregs, OTG_INTERFSEL,
musb->context.otg_interfsel); omap2430_low_level_init(musb);
} musb_writel(musb->mregs, OTG_INTERFSEL,
musb->context.otg_interfsel);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment