On 11/29/2016 05:16 PM, Bin Liu wrote:
> Hi,
> 
> On Mon, Nov 28, 2016 at 05:26:20PM +0100, Alexandre Bailon wrote:
>> On da8xx, VBUS is not maintained during suspend when musb is in host mode.
>> On resume, all the connected devices will be disconnected and then will
>> be enumerated again.
>> This happens because MUSB_DEVCTL is cleared during suspend.
>> Add a quirk to preserve MUSB_DEVCTL during a suspend.
> 
> Will preserving MUSB_DEVCTL prevent the device getting disconnected?
Yes. Preserving MUSB_DEVCTL keeps VBUS on though the PHY is off during
suspend.
Note that in device mode, the disconnect still happen but I think it's
the expected behavior.
> This doesn't happen on am335x. The PHY is off during suspend, during
> resume, PHY gets on, MUSB generates MUSB_CONNECT interrupt, then
> re-enumeration happens.
I haven't been able to try on the BBB. I don't know if my config is
incorrect or if some patches are missing but I was not able to
suspend it.

Regards,
Alexandre
> 
> Regards,
> -Bin.
> 
>>
>> Signed-off-by: Alexandre Bailon <abai...@baylibre.com>
>> ---
>>  drivers/usb/musb/musb_core.c | 13 +++++++------
>>  drivers/usb/musb/musb_core.h |  1 +
>>  2 files changed, 8 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
>> index 9e22646..7e2cd98 100644
>> --- a/drivers/usb/musb/musb_core.c
>> +++ b/drivers/usb/musb/musb_core.c
>> @@ -1040,14 +1040,15 @@ static void musb_enable_interrupts(struct musb *musb)
>>  
>>  }
>>  
>> -static void musb_generic_disable(struct musb *musb)
>> +static void musb_generic_disable(struct musb *musb, bool suspend)
>>  {
>>      void __iomem    *mbase = musb->mregs;
>>  
>>      musb_disable_interrupts(musb);
>>  
>>      /* off */
>> -    musb_writeb(mbase, MUSB_DEVCTL, 0);
>> +    if (!suspend || !(musb->io.quirks & MUSB_PRESERVE_DEVCTL))
>> +            musb_writeb(mbase, MUSB_DEVCTL, 0);
>>  }
>>  
>>  /*
>> @@ -1106,7 +1107,7 @@ void musb_stop(struct musb *musb)
>>  {
>>      /* stop IRQs, timers, ... */
>>      musb_platform_disable(musb);
>> -    musb_generic_disable(musb);
>> +    musb_generic_disable(musb, false);
>>      musb_dbg(musb, "HDRC disabled");
>>  
>>      /* FIXME
>> @@ -2310,7 +2311,7 @@ musb_init_controller(struct device *dev, int nIrq, 
>> void __iomem *ctrl)
>>  
>>      /* be sure interrupts are disabled before connecting ISR */
>>      musb_platform_disable(musb);
>> -    musb_generic_disable(musb);
>> +    musb_generic_disable(musb, false);
>>  
>>      /* Init IRQ workqueue before request_irq */
>>      INIT_DELAYED_WORK(&musb->irq_work, musb_irq_work);
>> @@ -2486,7 +2487,7 @@ static int musb_remove(struct platform_device *pdev)
>>      musb_gadget_cleanup(musb);
>>      spin_lock_irqsave(&musb->lock, flags);
>>      musb_platform_disable(musb);
>> -    musb_generic_disable(musb);
>> +    musb_generic_disable(musb, false);
>>      spin_unlock_irqrestore(&musb->lock, flags);
>>      musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
>>      pm_runtime_dont_use_autosuspend(musb->controller);
>> @@ -2663,7 +2664,7 @@ static int musb_suspend(struct device *dev)
>>      unsigned long   flags;
>>  
>>      musb_platform_disable(musb);
>> -    musb_generic_disable(musb);
>> +    musb_generic_disable(musb, true);
>>      WARN_ON(!list_empty(&musb->pending_list));
>>  
>>      spin_lock_irqsave(&musb->lock, flags);
>> diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
>> index a611e2f..22961ef 100644
>> --- a/drivers/usb/musb/musb_core.h
>> +++ b/drivers/usb/musb/musb_core.h
>> @@ -172,6 +172,7 @@ struct musb_io;
>>   */
>>  struct musb_platform_ops {
>>  
>> +#define MUSB_PRESERVE_DEVCTL        BIT(7)
>>  #define MUSB_DMA_UX500              BIT(6)
>>  #define MUSB_DMA_CPPI41             BIT(5)
>>  #define MUSB_DMA_CPPI               BIT(4)
>> -- 
>> 2.7.3
>>

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to