<snip> > > > > #ifdef CONFIG_PM > > > > +static struct musb_context_registers musb_context; > > + > > +void musb_save_context(struct musb *musb) > > +{ > > > > Could you add one more parameter to this function call, which would > select either if we want to save the musb_platform context or not? > I m working at the moment on turning off the musb when cable unplugged > and turning it on with restoring context after cable re-connect. > In this case I don't need to restore the the musb_platform_context since > I just set them before calling this one. > > Same apply for restore. > > what do you think? > I could also modify slightly this implementation after it is ready and > submit it. I think you want to add the parameter in musb_platform_save_context() and not in musb_save_context. If so then where do you restore them? {As you said before calling this} I think if the requirement is generic and suits for all other platforms Using musb then we can add it. -Ajay > > > + int i; > > + void __iomem *musb_base = musb->mregs; > > + > > + if (is_host_enabled(musb)) { > > + musb_context.frame = musb_readw(musb_base, MUSB_FRAME); > > + musb_context.testmode = musb_readb(musb_base, > MUSB_TESTMODE); > > + } > > + musb_context.power = musb_readb(musb_base, MUSB_POWER); > > + musb_context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE); > > + musb_context.intrrxe = musb_readw(musb_base, MUSB_INTRRXE); > > + musb_context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE); > > + musb_context.index = musb_readb(musb_base, MUSB_INDEX); > > + musb_context.devctl = musb_readb(musb_base, MUSB_DEVCTL); > > + > > + for (i = 0; i < MUSB_C_NUM_EPS; ++i) { > > + musb_writeb(musb_base, MUSB_INDEX, i); > > + musb_context.index_regs[i].txmaxp = > > + musb_readw(musb_base, 0x10 + MUSB_TXMAXP); > > + musb_context.index_regs[i].txcsr = > > + musb_readw(musb_base, 0x10 + MUSB_TXCSR); > > + musb_context.index_regs[i].rxmaxp = > > + musb_readw(musb_base, 0x10 + MUSB_RXMAXP); > > + musb_context.index_regs[i].rxcsr = > > + musb_readw(musb_base, 0x10 + MUSB_RXCSR); > > + > > + if (musb->dyn_fifo) { > > + musb_context.index_regs[i].txfifoadd = > > + musb_read_txfifoadd(musb_base); > > + musb_context.index_regs[i].rxfifoadd = > > + musb_read_rxfifoadd(musb_base); > > + musb_context.index_regs[i].txfifosz = > > + musb_read_txfifosz(musb_base); > > + musb_context.index_regs[i].rxfifosz = > > + musb_read_rxfifosz(musb_base); > > + } > > + if (is_host_enabled(musb)) { > > + musb_context.index_regs[i].txtype = > > + musb_readb(musb_base, 0x10 + > MUSB_TXTYPE); > > + musb_context.index_regs[i].txinterval = > > + musb_readb(musb_base, 0x10 + > MUSB_TXINTERVAL); > > + musb_context.index_regs[i].rxtype = > > + musb_readb(musb_base, 0x10 + > MUSB_RXTYPE); > > + musb_context.index_regs[i].rxinterval = > > + musb_readb(musb_base, 0x10 + > MUSB_RXINTERVAL); > > + > > + musb_context.index_regs[i].txfunaddr = > > + musb_read_txfunaddr(musb_base, i); > > + musb_context.index_regs[i].txhubaddr = > > + musb_read_txhubaddr(musb_base, i); > > + musb_context.index_regs[i].txhubport = > > + musb_read_txhubport(musb_base, i); > > + > > + musb_context.index_regs[i].rxfunaddr = > > + musb_read_rxfunaddr(musb_base, i); > > + musb_context.index_regs[i].rxhubaddr = > > + musb_read_rxhubaddr(musb_base, i); > > + musb_context.index_regs[i].rxhubport = > > + musb_read_rxhubport(musb_base, i); > > + } > > + } > > + > > + musb_writeb(musb_base, MUSB_INDEX, musb_context.index); > > + > > + musb_platform_save_context(&musb_context); > > +} > > + > > +void musb_restore_context(struct musb *musb) > > +{ > > + int i; > > + void __iomem *musb_base = musb->mregs; > > + void __iomem *ep_target_regs; > > + > > + musb_platform_restore_context(&musb_context); > > + > > + if (is_host_enabled(musb)) { > > + musb_writew(musb_base, MUSB_FRAME, musb_context.frame); > > + musb_writeb(musb_base, MUSB_TESTMODE, > musb_context.testmode); > > + } > > + musb_writeb(musb_base, MUSB_POWER, musb_context.power); > > + musb_writew(musb_base, MUSB_INTRTXE, musb_context.intrtxe); > > + musb_writew(musb_base, MUSB_INTRRXE, musb_context.intrrxe); > > + musb_writeb(musb_base, MUSB_INTRUSBE, musb_context.intrusbe); > > + musb_writeb(musb_base, MUSB_DEVCTL, musb_context.devctl); > > + > > + for (i = 0; i < MUSB_C_NUM_EPS; ++i) { > > + musb_writeb(musb_base, MUSB_INDEX, i); > > + musb_writew(musb_base, 0x10 + MUSB_TXMAXP, > > + musb_context.index_regs[i].txmaxp); > > + musb_writew(musb_base, 0x10 + MUSB_TXCSR, > > + musb_context.index_regs[i].txcsr); > > + musb_writew(musb_base, 0x10 + MUSB_RXMAXP, > > + musb_context.index_regs[i].rxmaxp); > > + musb_writew(musb_base, 0x10 + MUSB_RXCSR, > > + musb_context.index_regs[i].rxcsr); > > + > > + if (musb->dyn_fifo) { > > + musb_write_txfifosz(musb_base, > > + musb_context.index_regs[i].txfifosz); > > + musb_write_rxfifosz(musb_base, > > + musb_context.index_regs[i].rxfifosz); > > + musb_write_txfifoadd(musb_base, > > + musb_context.index_regs[i].txfifoadd); > > + musb_write_rxfifoadd(musb_base, > > + musb_context.index_regs[i].rxfifoadd); > > + } > > + > > + if (is_host_enabled(musb)) { > > + musb_writeb(musb_base, 0x10 + MUSB_TXTYPE, > > + musb_context.index_regs[i].txtype); > > + musb_writeb(musb_base, 0x10 + MUSB_TXINTERVAL, > > + musb_context.index_regs[i].txinterval); > > + musb_writeb(musb_base, 0x10 + MUSB_RXTYPE, > > + musb_context.index_regs[i].rxtype); > > + musb_writeb(musb_base, 0x10 + MUSB_RXINTERVAL, > > + > > + musb_context.index_regs[i].rxinterval); > > + musb_write_txfunaddr(musb_base, i, > > + musb_context.index_regs[i].txfunaddr); > > + musb_write_txhubaddr(musb_base, i, > > + musb_context.index_regs[i].txhubaddr); > > + musb_write_txhubport(musb_base, i, > > + musb_context.index_regs[i].txhubport); > > + > > + ep_target_regs = > > + musb_read_target_reg_base(i, musb_base); > > + > > + musb_write_rxfunaddr(ep_target_regs, > > + musb_context.index_regs[i].rxfunaddr); > > + musb_write_rxhubaddr(ep_target_regs, > > + musb_context.index_regs[i].rxhubaddr); > > + musb_write_rxhubport(ep_target_regs, > > + musb_context.index_regs[i].rxhubport); > > + } > > + } > > + > > + musb_writeb(musb_base, MUSB_INDEX, musb_context.index); > > +} > > + > > static int musb_suspend(struct device *dev) > > { > > struct platform_device *pdev = to_platform_device(dev); > > unsigned long flags; > > struct musb *musb = dev_to_musb(&pdev->dev); > > + u8 reg; > > > > if (!musb->clock) > > return 0; > > @@ -2179,15 +2322,23 @@ static int musb_suspend(struct device *dev) > > spin_lock_irqsave(&musb->lock, flags); > > > > if (is_peripheral_active(musb)) { > > - /* FIXME force disconnect unless we know USB will wake > > - * the system up quickly enough to respond ... > > + /* System is entering into suspend where gadget would > not be > > + * able to respond to host and thus it will be in an > unknown > > + * state for host. Re-enumeration of gadget is required > after > > + * a resume. So we force a disconnect. > > */ > > + reg = musb_readb(musb->mregs, MUSB_POWER); > > + reg &= ~MUSB_POWER_SOFTCONN; > > + musb_writeb(musb->mregs, MUSB_POWER, reg); > > + > > } else if (is_host_active(musb)) { > > /* we know all the children are suspended; sometimes > > * they will even be wakeup-enabled. > > */ > > } > > > > + musb_save_context(musb); > > + > > if (musb->set_clock) > > musb->set_clock(musb->clock, 0); > > else > > @@ -2209,6 +2360,8 @@ static int musb_resume_noirq(struct device *dev) > > else > > clk_enable(musb->clock); > > > > + musb_restore_context(musb); > > + > > /* for static cmos like DaVinci, register values were preserved > > * unless for some reason the whole soc powered down or the USB > > * module got reset through the PSC (vs just being disabled). > > diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h > > index 969287c..38de1be 100644 > > --- a/drivers/usb/musb/musb_core.h > > +++ b/drivers/usb/musb/musb_core.h > > @@ -462,6 +462,45 @@ struct musb { > > #endif > > }; > > > > +#ifdef CONFIG_PM > > +struct musb_csr_regs { > > + /* FIFO registers */ > > + u16 txmaxp, txcsr, rxmaxp, rxcsr; > > + u16 rxfifoadd, txfifoadd; > > + u8 txtype, txinterval, rxtype, rxinterval; > > + u8 rxfifosz, txfifosz; > > + u8 txfunaddr, txhubaddr, txhubport; > > + u8 rxfunaddr, rxhubaddr, rxhubport; > > +}; > > + > > +struct musb_context_registers { > > + > > +#if defined(CONFIG_ARCH_OMAP34XX) > > + u32 otg_sysconfig, otg_forcestandby; > > +#endif > > + u8 power; > > + u16 intrtxe, intrrxe; > > + u8 intrusbe; > > + u16 frame; > > + u8 index, testmode; > > + > > + u8 devctl, misc; > > + > > + struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; > > +}; > > + > > +#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430) > > +extern void musb_platform_save_context(struct musb_context_registers > > + *musb_context); > > +extern void musb_platform_restore_context(struct musb_context_registers > > + *musb_context); > > +#else > > +#define musb_platform_save_context(x) do {} while (0) > > +#define musb_platform_restore_context(x) do {} while (0) > > +#endif > > + > > +#endif > > + > > static inline void musb_set_vbus(struct musb *musb, int is_on) > > { > > musb->board_set_vbus(musb, is_on); > > diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h > > index 473a94e..8ca8f23 100644 > > --- a/drivers/usb/musb/musb_regs.h > > +++ b/drivers/usb/musb/musb_regs.h > > @@ -321,6 +321,26 @@ static inline void musb_write_rxfifoadd(void > __iomem *mbase, u16 c_off) > > musb_writew(mbase, MUSB_RXFIFOADD, c_off); > > } > > > > +static inline u8 musb_read_txfifosz(void __iomem *mbase) > > +{ > > + return musb_readb(mbase, MUSB_TXFIFOSZ); > > +} > > + > > +static inline u16 musb_read_txfifoadd(void __iomem *mbase) > > +{ > > + return musb_readw(mbase, MUSB_TXFIFOADD); > > +} > > + > > +static inline u8 musb_read_rxfifosz(void __iomem *mbase) > > +{ > > + return musb_readb(mbase, MUSB_RXFIFOSZ); > > +} > > + > > +static inline u16 musb_read_rxfifoadd(void __iomem *mbase) > > +{ > > + return musb_readw(mbase, MUSB_RXFIFOADD); > > +} > > + > > static inline u8 musb_read_configdata(void __iomem *mbase) > > { > > musb_writeb(mbase, MUSB_INDEX, 0); > > @@ -376,6 +396,36 @@ static inline void musb_write_txhubport(void > __iomem *mbase, u8 epnum, > > qh_h_port_reg); > > } > > > > +static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) > > +{ > > + return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, > MUSB_RXFUNCADDR)); > > +} > > + > > +static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) > > +{ > > + return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, > MUSB_RXHUBADDR)); > > +} > > + > > +static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) > > +{ > > + return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, > MUSB_RXHUBPORT)); > > +} > > + > > +static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) > > +{ > > + return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, > MUSB_TXFUNCADDR)); > > +} > > + > > +static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) > > +{ > > + return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, > MUSB_TXHUBADDR)); > > +} > > + > > +static inline u8 musb_read_txhubport(void __iomem *mbase, u8 epnum) > > +{ > > + return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, > MUSB_TXHUBPORT)); > > +} > > + > > #else /* CONFIG_BLACKFIN */ > > > > #define USB_BASE USB_FADDR > > @@ -455,6 +505,22 @@ static inline void musb_write_rxfifoadd(void > __iomem *mbase, u16 c_off) > > { > > } > > > > +static inline u8 musb_read_txfifosz(void __iomem *mbase) > > +{ > > +} > > + > > +static inline u16 musb_read_txfifoadd(void __iomem *mbase) > > +{ > > +} > > + > > +static inline u8 musb_read_rxfifosz(void __iomem *mbase) > > +{ > > +} > > + > > +static inline u16 musb_read_rxfifoadd(void __iomem *mbase) > > +{ > > +} > > + > > static inline u8 musb_read_configdata(void __iomem *mbase) > > { > > return 0; > > @@ -500,6 +566,30 @@ static inline void musb_write_txhubport(void > __iomem *mbase, u8 epnum, > > { > > } > > > > +static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) > > +{ > > +} > > + > > +static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) > > +{ > > +} > > + > > +static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) > > +{ > > +} > > + > > +static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) > > +{ > > +} > > + > > +static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) > > +{ > > +} > > + > > +static inline void musb_read_txhubport(void __iomem *mbase, u8 epnum) > > +{ > > +} > > + > > #endif /* CONFIG_BLACKFIN */ > > > > #endif /* __MUSB_REGS_H__ */ > > diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c > > index 83beeac..15a3f27 100644 > > --- a/drivers/usb/musb/omap2430.c > > +++ b/drivers/usb/musb/omap2430.c > > @@ -255,6 +255,22 @@ int __init musb_platform_init(struct musb *musb) > > return 0; > > } > > > > +#ifdef CONFIG_PM > > +void musb_platform_save_context(struct musb_context_registers > > + *musb_context) > > +{ > > + musb_context->otg_sysconfig = omap_readl(OTG_SYSCONFIG); > > + musb_context->otg_forcestandby = omap_readl(OTG_FORCESTDBY); > > +} > > + > > +void musb_platform_restore_context(struct musb_context_registers > > + *musb_context) > > +{ > > + omap_writel(musb_context->otg_sysconfig, OTG_SYSCONFIG); > > + omap_writel(musb_context->otg_forcestandby, OTG_FORCESTDBY); > > +} > > +#endif > > + > > int musb_platform_suspend(struct musb *musb) > > { > > u32 l; > > -- > > 1.6.2.4 > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > > the body of a message to majordomo@xxxxxxxxxxxxxxx > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html