Re: [PATCH 1/2 v2] musb: Add context save and restore support
Adding support for MUSB register save and restore during system suspend and resume. Changes: - Added musb_save/restore_context() functions - Added platform specific musb_platform_save/restore_context() to handle platform specific jobs. - Maintaining BlackFin compatibility by adding read/write functions for registers which are not available in BlackFin Tested system suspend and resume on OMAP3EVM board. Signed-off-by: Anand Gadiyar gadi...@ti.com Signed-off-by: Ajay Kumar Gupta ajay.gu...@ti.com will we have another version of this patch ?? Yes, I need to resubmit this patch after fixing review comments. -Ajay -- balbi -- -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2 v2] musb: Add context save and restore support
Hi, On Thu, Nov 26, 2009 at 07:39:59AM +0100, ext Ajay Kumar Gupta wrote: Adding support for MUSB register save and restore during system suspend and resume. Changes: - Added musb_save/restore_context() functions - Added platform specific musb_platform_save/restore_context() to handle platform specific jobs. - Maintaining BlackFin compatibility by adding read/write functions for registers which are not available in BlackFin Tested system suspend and resume on OMAP3EVM board. Signed-off-by: Anand Gadiyar gadi...@ti.com Signed-off-by: Ajay Kumar Gupta ajay.gu...@ti.com will we have another version of this patch ?? -- balbi -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2 v2] musb: Add context save and restore support
--- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2167,21 +2167,163 @@ static int __devexit musb_remove(struct platform_device *pdev) #ifdef CONFIG_PM +static struct musb_context_registers musb_context; + +void musb_save_context(void __iomem *musb_base) +{ + int i; + + musb_context.faddr = musb_readb(musb_base, MUSB_FADDR); + 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.frame = musb_readw(musb_base, MUSB_FRAME); Not necessary for gadget + musb_context.index = musb_readb(musb_base, MUSB_INDEX); + musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE); Not sure if it is necessary for gadget. + 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); + musb_context.index_regs[i].rxcount = + musb_readw(musb_base, 0x10 + MUSB_RXCOUNT); + 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].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 MUSB_CONFIGDATA_DYNFIFO is not set then saving FIFO address and sizes are probably not necessary. Not sure if they are detrimental as well. + + 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); + } If we are in gadget mode, do we have to save this? + + musb_writeb(musb_base, MUSB_INDEX, musb_context.index); + + musb_platform_save_context(musb_context); +} Similar for restore. 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; spin_lock_irqsave(musb-lock, flags); + musb_save_context(musb-mregs); + 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-enumemation of gadget is required after +* resume to make the gadget functional thus doing a force +* disconnect. */ + reg = musb_readb(musb-mregs, MUSB_POWER); + reg = ~MUSB_POWER_SOFTCONN; + musb_writeb(musb-mregs, MUSB_POWER, reg); After this softdisconnect when we subsequently get reconnected followed by a reset we could have changed our speed (LS,FS, HS). In your resume routine we are writing back our previous
RE: [PATCH 1/2 v2] musb: Add context save and restore support
Hi, -Original Message- From: Dasgupta, Romit Sent: Thursday, November 26, 2009 2:33 PM To: Gupta, Ajay Kumar Cc: linux-...@vger.kernel.org; linux-omap@vger.kernel.org; felipe.ba...@nokia.com; Gadiyar, Anand Subject: Re: [PATCH 1/2 v2] musb: Add context save and restore support --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2167,21 +2167,163 @@ static int __devexit musb_remove(struct platform_device *pdev) #ifdef CONFIG_PM +static struct musb_context_registers musb_context; + +void musb_save_context(void __iomem *musb_base) +{ + int i; + + musb_context.faddr = musb_readb(musb_base, MUSB_FADDR); + 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.frame = musb_readw(musb_base, MUSB_FRAME); Not necessary for gadget + musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE); Not sure if it is necessary for gadget. Right! ..so we can all #ifdefs to save/restore gadget or host only registers. + musb_context.index = musb_readb(musb_base, MUSB_INDEX); snip + musb_read_txfifosz(musb_base); + musb_context.index_regs[i].rxfifosz = + musb_read_rxfifosz(musb_base); If MUSB_CONFIGDATA_DYNFIFO is not set then saving FIFO address and sizes are probably not necessary. Not sure if they are detrimental as well. We can add it within DYNFIFO check. + + musb_context.index_regs[i].txfunaddr = + musb_read_txfunaddr(musb_base, i); + musb_context.index_regs[i].txhubaddr = snip. */ + reg = musb_readb(musb-mregs, MUSB_POWER); + reg = ~MUSB_POWER_SOFTCONN; + musb_writeb(musb-mregs, MUSB_POWER, reg); After this softdisconnect when we subsequently get reconnected followed by a reset we could have changed our speed (LS,FS, HS). I didn't get it completely. I think as a peripheral USB speed will remain same after resume for the gadget driver it was before suspend? If we intend to change the gadget driver then we may have support for a different speed but it would anyways happen after resume is completed. Regards, Ajay In your resume routine we are writing back our previous speed. I am not sure here but is it not possible that we have reset the controller and then restored back the old speed overwriting the new speed? -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 1/2 v2] musb: Add context save and restore support
snip. */ + reg = musb_readb(musb-mregs, MUSB_POWER); + reg = ~MUSB_POWER_SOFTCONN; + musb_writeb(musb-mregs, MUSB_POWER, reg); After this softdisconnect when we subsequently get reconnected followed by a reset we could have changed our speed (LS,FS, HS). I didn't get it completely. I think as a peripheral USB speed will remain same after resume for the gadget driver it was before suspend? If we intend to change the gadget driver then we may have support for a different speed but it would anyways happen after resume is completed. The host side might change, but that shouldn't affect us. This bit is used to tell MUSB (acting as a peripheral) if it should attempt to enumerate at HS or not - it will always fall back to FS if the host does not support it. So Ajay is correct in restoring this register. - Anand -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2 v2] musb: Add context save and restore support
Adding support for MUSB register save and restore during system suspend and resume. Changes: - Added musb_save/restore_context() functions - Added platform specific musb_platform_save/restore_context() to handle platform specific jobs. - Maintaining BlackFin compatibility by adding read/write functions for registers which are not available in BlackFin Tested system suspend and resume on OMAP3EVM board. Signed-off-by: Anand Gadiyar gadi...@ti.com Signed-off-by: Ajay Kumar Gupta ajay.gu...@ti.com --- Changes from previous version: - Cleanups as Felipe suggested - Removed save/restore of interrupt status registers intr[r/t]x and intrusb drivers/usb/musb/musb_core.c | 148 +- drivers/usb/musb/musb_core.h | 39 +++ drivers/usb/musb/musb_regs.h | 90 + drivers/usb/musb/omap2430.c | 16 + 4 files changed, 291 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 3a61ddb..0fd4105 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2167,21 +2167,163 @@ static int __devexit musb_remove(struct platform_device *pdev) #ifdef CONFIG_PM +static struct musb_context_registers musb_context; + +void musb_save_context(void __iomem *musb_base) +{ + int i; + + musb_context.faddr = musb_readb(musb_base, MUSB_FADDR); + 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.frame = musb_readw(musb_base, MUSB_FRAME); + musb_context.index = musb_readb(musb_base, MUSB_INDEX); + musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE); + 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); + musb_context.index_regs[i].rxcount = + musb_readw(musb_base, 0x10 + MUSB_RXCOUNT); + 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].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); + + 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(void __iomem *musb_base) +{ + int i; + void __iomem *ep_target_regs; + + musb_platform_restore_context(musb_context); + + musb_writeb(musb_base, MUSB_FADDR, musb_context.faddr); + 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); +