On 11.10.2013 10:38, Sebastian Andrzej Siewior wrote: > I have am335x-evm with one port running in OTG mode. Since commit > fe4cb09 ("usb: musb: gadget: remove hcd initialization") the loaded > gadget does non pop up on the host. All I see is > |usb 4-5: new high-speed USB device number 52 using ehci-pci > |usb 4-5: device descriptor read/64, error -110 > > Since a later commit 2cc65fe ("usb: musb: add musb_host_setup() and > musb_host_cleanup()) the gadget shows up on the host again but only > in OTG mode (because we have the host init code running). It does not > work in device only mode. > If running in OTG mode and the gadget is removed and added back (rmmod > followed by modprobe of a gadget) then the same error is pops up on the > host side. > > This patch ensures that the gadget side also executes musb_start() which > puts the chip in "connect accept" mode. With this change the device > works in OTG & device mode and the gadget can be added & removed > multiple times. > A device (if musb is in OTG mode acting as a host) is only recognized if > it is attached during module load (musb_hdrc module). After the device > unplugged and plugged again the host does not recognize it. We get a > buch of errors if musb running in OTG mode, attached to a host and no > gadget is loaded. Bah. > This is one step forward. Host & device only mode should work. I will > look at OTG later. I looked at this before commit fe4cb09 and OTG wasn't > working there perfectly so I am not sure that it is a regression :) > > Cc: Daniel Mack <zonque@xxxxxxxxx> > Cc: Peter Korsgaard <jacmet@xxxxxxxxxx> > Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx> Looks good to me - successfully tested on my host-only board. Tested-by: Daniel Mack <zonque@xxxxxxxxx> I'll rebase my suspend patches on top of them, address the port reset details and repost. Thanks, Daniel > --- > drivers/usb/musb/musb_core.c | 46 +++++++++++++++++++++++++++++++++++++++++ > drivers/usb/musb/musb_core.h | 1 + > drivers/usb/musb/musb_gadget.c | 2 ++ > drivers/usb/musb/musb_virthub.c | 46 ----------------------------------------- > 4 files changed, 49 insertions(+), 46 deletions(-) > > diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c > index 5b4fa79..60dbeba 100644 > --- a/drivers/usb/musb/musb_core.c > +++ b/drivers/usb/musb/musb_core.c > @@ -922,6 +922,52 @@ static void musb_generic_disable(struct musb *musb) > } > > /* > + * Program the HDRC to start (enable interrupts, dma, etc.). > + */ > +void musb_start(struct musb *musb) > +{ > + void __iomem *regs = musb->mregs; > + u8 devctl = musb_readb(regs, MUSB_DEVCTL); > + > + dev_dbg(musb->controller, "<== devctl %02x\n", devctl); > + > + /* Set INT enable registers, enable interrupts */ > + musb->intrtxe = musb->epmask; > + musb_writew(regs, MUSB_INTRTXE, musb->intrtxe); > + musb->intrrxe = musb->epmask & 0xfffe; > + musb_writew(regs, MUSB_INTRRXE, musb->intrrxe); > + musb_writeb(regs, MUSB_INTRUSBE, 0xf7); > + > + musb_writeb(regs, MUSB_TESTMODE, 0); > + > + /* put into basic highspeed mode and start session */ > + musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE > + | MUSB_POWER_HSENAB > + /* ENSUSPEND wedges tusb */ > + /* | MUSB_POWER_ENSUSPEND */ > + ); > + > + musb->is_active = 0; > + devctl = musb_readb(regs, MUSB_DEVCTL); > + devctl &= ~MUSB_DEVCTL_SESSION; > + > + /* session started after: > + * (a) ID-grounded irq, host mode; > + * (b) vbus present/connect IRQ, peripheral mode; > + * (c) peripheral initiates, using SRP > + */ > + if (musb->port_mode != MUSB_PORT_MODE_HOST && > + (devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) { > + musb->is_active = 1; > + } else { > + devctl |= MUSB_DEVCTL_SESSION; > + } > + > + musb_platform_enable(musb); > + musb_writeb(regs, MUSB_DEVCTL, devctl); > +} > + > +/* > * Make the HDRC stop (disable interrupts, etc.); > * reversible by musb_start > * called on gadget driver unregister > diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h > index 65f3917..1c5bf75 100644 > --- a/drivers/usb/musb/musb_core.h > +++ b/drivers/usb/musb/musb_core.h > @@ -503,6 +503,7 @@ static inline void musb_configure_ep0(struct musb *musb) > extern const char musb_driver_name[]; > > extern void musb_stop(struct musb *musb); > +extern void musb_start(struct musb *musb); > > extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src); > extern void musb_read_fifo(struct musb_hw_ep *ep, u16 len, u8 *dst); > diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c > index b19ed21..07bf4df 100644 > --- a/drivers/usb/musb/musb_gadget.c > +++ b/drivers/usb/musb/musb_gadget.c > @@ -1858,6 +1858,8 @@ static int musb_gadget_start(struct usb_gadget *g, > musb->xceiv->state = OTG_STATE_B_IDLE; > spin_unlock_irqrestore(&musb->lock, flags); > > + musb_start(musb); > + > /* REVISIT: funcall to other code, which also > * handles power budgeting ... this way also > * ensures HdrcStart is indirectly called. > diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c > index a523950..d1d6b83 100644 > --- a/drivers/usb/musb/musb_virthub.c > +++ b/drivers/usb/musb/musb_virthub.c > @@ -44,52 +44,6 @@ > > #include "musb_core.h" > > -/* > -* Program the HDRC to start (enable interrupts, dma, etc.). > -*/ > -static void musb_start(struct musb *musb) > -{ > - void __iomem *regs = musb->mregs; > - u8 devctl = musb_readb(regs, MUSB_DEVCTL); > - > - dev_dbg(musb->controller, "<== devctl %02x\n", devctl); > - > - /* Set INT enable registers, enable interrupts */ > - musb->intrtxe = musb->epmask; > - musb_writew(regs, MUSB_INTRTXE, musb->intrtxe); > - musb->intrrxe = musb->epmask & 0xfffe; > - musb_writew(regs, MUSB_INTRRXE, musb->intrrxe); > - musb_writeb(regs, MUSB_INTRUSBE, 0xf7); > - > - musb_writeb(regs, MUSB_TESTMODE, 0); > - > - /* put into basic highspeed mode and start session */ > - musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE > - | MUSB_POWER_HSENAB > - /* ENSUSPEND wedges tusb */ > - /* | MUSB_POWER_ENSUSPEND */ > - ); > - > - musb->is_active = 0; > - devctl = musb_readb(regs, MUSB_DEVCTL); > - devctl &= ~MUSB_DEVCTL_SESSION; > - > - /* session started after: > - * (a) ID-grounded irq, host mode; > - * (b) vbus present/connect IRQ, peripheral mode; > - * (c) peripheral initiates, using SRP > - */ > - if (musb->port_mode != MUSB_PORT_MODE_HOST && > - (devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) { > - musb->is_active = 1; > - } else { > - devctl |= MUSB_DEVCTL_SESSION; > - } > - > - musb_platform_enable(musb); > - musb_writeb(regs, MUSB_DEVCTL, devctl); > -} > - > static void musb_port_suspend(struct musb *musb, bool do_suspend) > { > struct usb_otg *otg = musb->xceiv->otg; > -- 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