Skip to content

Commit

Permalink
usb: musb: Fix suspend and resume issues for PHYs on I2C and SPI
Browse files Browse the repository at this point in the history
As the USB PHYs typically are on I2C or SPI bus for the 2430 glue layer,
we need configure the PHYs early for suspend.

The musb glue layer we need to suspend only after musb_suspend() in
suspend_late.

Fixes: 62d472d ("usb: musb: Add missing PM suspend and resume functions for 2430 glue")
Reported-by: Andreas Kemnade <[email protected]>
Signed-off-by: Tony Lindgren <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
tmlind authored and gregkh committed Jul 27, 2021
1 parent afcff6d commit 68d9f95
Showing 1 changed file with 38 additions and 5 deletions.
43 changes: 38 additions & 5 deletions drivers/usb/musb/omap2430.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct omap2430_glue {
struct device *control_otghs;
unsigned int is_runtime_suspended:1;
unsigned int needs_resume:1;
unsigned int phy_suspended:1;
};
#define glue_to_musb(g) platform_get_drvdata(g->musb)

Expand Down Expand Up @@ -458,8 +459,10 @@ static int omap2430_runtime_suspend(struct device *dev)

omap2430_low_level_exit(musb);

phy_power_off(musb->phy);
phy_exit(musb->phy);
if (!glue->phy_suspended) {
phy_power_off(musb->phy);
phy_exit(musb->phy);
}

glue->is_runtime_suspended = 1;

Expand All @@ -474,8 +477,10 @@ static int omap2430_runtime_resume(struct device *dev)
if (!musb)
return 0;

phy_init(musb->phy);
phy_power_on(musb->phy);
if (!glue->phy_suspended) {
phy_init(musb->phy);
phy_power_on(musb->phy);
}

omap2430_low_level_init(musb);
musb_writel(musb->mregs, OTG_INTERFSEL,
Expand All @@ -489,7 +494,21 @@ static int omap2430_runtime_resume(struct device *dev)
return 0;
}

/* I2C and SPI PHYs need to be suspended before the glue layer */
static int omap2430_suspend(struct device *dev)
{
struct omap2430_glue *glue = dev_get_drvdata(dev);
struct musb *musb = glue_to_musb(glue);

phy_power_off(musb->phy);
phy_exit(musb->phy);
glue->phy_suspended = 1;

return 0;
}

/* Glue layer needs to be suspended after musb_suspend() */
static int omap2430_suspend_late(struct device *dev)
{
struct omap2430_glue *glue = dev_get_drvdata(dev);

Expand All @@ -501,7 +520,7 @@ static int omap2430_suspend(struct device *dev)
return omap2430_runtime_suspend(dev);
}

static int omap2430_resume(struct device *dev)
static int omap2430_resume_early(struct device *dev)
{
struct omap2430_glue *glue = dev_get_drvdata(dev);

Expand All @@ -513,10 +532,24 @@ static int omap2430_resume(struct device *dev)
return omap2430_runtime_resume(dev);
}

static int omap2430_resume(struct device *dev)
{
struct omap2430_glue *glue = dev_get_drvdata(dev);
struct musb *musb = glue_to_musb(glue);

phy_init(musb->phy);
phy_power_on(musb->phy);
glue->phy_suspended = 0;

return 0;
}

static const struct dev_pm_ops omap2430_pm_ops = {
.runtime_suspend = omap2430_runtime_suspend,
.runtime_resume = omap2430_runtime_resume,
.suspend = omap2430_suspend,
.suspend_late = omap2430_suspend_late,
.resume_early = omap2430_resume_early,
.resume = omap2430_resume,
};

Expand Down

0 comments on commit 68d9f95

Please sign in to comment.