Skip to content

Commit 68d9f95

Browse files
tmlindgregkh
authored andcommitted
usb: musb: Fix suspend and resume issues for PHYs on I2C and SPI
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 <andreas@kemnade.info> Signed-off-by: Tony Lindgren <tony@atomide.com> Link: https://lore.kernel.org/r/20210727104134.52800-1-tony@atomide.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent afcff6d commit 68d9f95

1 file changed

Lines changed: 38 additions & 5 deletions

File tree

drivers/usb/musb/omap2430.c

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ struct omap2430_glue {
3535
struct device *control_otghs;
3636
unsigned int is_runtime_suspended:1;
3737
unsigned int needs_resume:1;
38+
unsigned int phy_suspended:1;
3839
};
3940
#define glue_to_musb(g) platform_get_drvdata(g->musb)
4041

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

459460
omap2430_low_level_exit(musb);
460461

461-
phy_power_off(musb->phy);
462-
phy_exit(musb->phy);
462+
if (!glue->phy_suspended) {
463+
phy_power_off(musb->phy);
464+
phy_exit(musb->phy);
465+
}
463466

464467
glue->is_runtime_suspended = 1;
465468

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

477-
phy_init(musb->phy);
478-
phy_power_on(musb->phy);
480+
if (!glue->phy_suspended) {
481+
phy_init(musb->phy);
482+
phy_power_on(musb->phy);
483+
}
479484

480485
omap2430_low_level_init(musb);
481486
musb_writel(musb->mregs, OTG_INTERFSEL,
@@ -489,7 +494,21 @@ static int omap2430_runtime_resume(struct device *dev)
489494
return 0;
490495
}
491496

497+
/* I2C and SPI PHYs need to be suspended before the glue layer */
492498
static int omap2430_suspend(struct device *dev)
499+
{
500+
struct omap2430_glue *glue = dev_get_drvdata(dev);
501+
struct musb *musb = glue_to_musb(glue);
502+
503+
phy_power_off(musb->phy);
504+
phy_exit(musb->phy);
505+
glue->phy_suspended = 1;
506+
507+
return 0;
508+
}
509+
510+
/* Glue layer needs to be suspended after musb_suspend() */
511+
static int omap2430_suspend_late(struct device *dev)
493512
{
494513
struct omap2430_glue *glue = dev_get_drvdata(dev);
495514

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

504-
static int omap2430_resume(struct device *dev)
523+
static int omap2430_resume_early(struct device *dev)
505524
{
506525
struct omap2430_glue *glue = dev_get_drvdata(dev);
507526

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

535+
static int omap2430_resume(struct device *dev)
536+
{
537+
struct omap2430_glue *glue = dev_get_drvdata(dev);
538+
struct musb *musb = glue_to_musb(glue);
539+
540+
phy_init(musb->phy);
541+
phy_power_on(musb->phy);
542+
glue->phy_suspended = 0;
543+
544+
return 0;
545+
}
546+
516547
static const struct dev_pm_ops omap2430_pm_ops = {
517548
.runtime_suspend = omap2430_runtime_suspend,
518549
.runtime_resume = omap2430_runtime_resume,
519550
.suspend = omap2430_suspend,
551+
.suspend_late = omap2430_suspend_late,
552+
.resume_early = omap2430_resume_early,
520553
.resume = omap2430_resume,
521554
};
522555

0 commit comments

Comments
 (0)