Re: [PATCH] usb: musb: start musb on the udc side, too

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux