Re: [PATCH 3/3] usb: dwc3: Support option to disable USB2 LPM

2018-11-12 Thread Roger Quadros
On 12/11/18 13:03, Felipe Balbi wrote:
> 
> Hi,
> 
> Roger Quadros  writes:
>>>> Also can we have some consistency in usage of '-' vs '_'?
>>> Right.. I agree. I've been using '-' as it is the preferred syntax as
>>> most of the properties, but some old properties use '_'. Do you have any
>>> suggestion?
>>
>> I'd keep it consistent to "snps,usb3_lpm_capable" so we avoid mistakes
>> when writing the DT.
>> Felipe?
> 
> _ are not really accepted in DT, except for legacy properties. What we
> can do is rename usb3_lpm_capable to usb3-lpm-capable and change code to
> try with _ if - fails. Then we can introduce the new property using -
> 

I agree. This is a better approach.

cheers,
-roger

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


Re: [PATCH 3/3] usb: dwc3: Support option to disable USB2 LPM

2018-11-12 Thread Roger Quadros
Thinh,

On 12/11/18 07:29, Thinh Nguyen wrote:
> Hi Roger,
> 
> On 11/9/2018 3:58 AM, Roger Quadros wrote:
>> Hi,
>>
>> On 08/11/18 04:10, Thinh Nguyen wrote:
>>> Support the option to disable USB2 LPM. Set xhci "usb2-lpm-disable"
>>> property via "snps,usb2-lpm-disable" property.
>>>
>>> Signed-off-by: Thinh Nguyen 
>>> ---
>>>  drivers/usb/dwc3/core.c | 2 ++
>>>  drivers/usb/dwc3/core.h | 2 ++
>>>  drivers/usb/dwc3/host.c | 5 -
>>>  3 files changed, 8 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>>> index a4068a7b95dd..f6b80a545a78 100644
>>> --- a/drivers/usb/dwc3/core.c
>>> +++ b/drivers/usb/dwc3/core.c
>>> @@ -1248,6 +1248,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>>> _threshold);
>>> dwc->usb3_lpm_capable = device_property_read_bool(dev,
>>> "snps,usb3_lpm_capable");
>>> +   dwc->usb2_lpm_disable = device_property_read_bool(dev,
>>> +   "snps,usb2-lpm-disable");
>> Can we use the same logic as usb3_lpm instead?
>> i.e. enable USB2 LPM only if "snps,usb2_lpm_capable" is present in DT.
>> This is because older platforms that are not tested for usb2 lpm
>> might break if you enable it by default.
> 
> I follow the same logic as usb-xhci property. The usb2-lpm-disable
> property from xHCI has been around for awhile. Do you suggest to change
> the property for xHCI then?

No.
I see it now that you are just setting the XHCI property and not
doing any change in the dwc3 functionality itself.
I think your patch is correct.

>> Also can we have some consistency in usage of '-' vs '_'?
> Right.. I agree. I've been using '-' as it is the preferred syntax as
> most of the properties, but some old properties use '_'. Do you have any
> suggestion?

I'd keep it consistent to "snps,usb3_lpm_capable" so we avoid mistakes
when writing the DT.
Felipe?

cheers,
-roger
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


Re: [PATCH 3/3] usb: dwc3: Support option to disable USB2 LPM

2018-11-09 Thread Roger Quadros
Hi,

On 08/11/18 04:10, Thinh Nguyen wrote:
> Support the option to disable USB2 LPM. Set xhci "usb2-lpm-disable"
> property via "snps,usb2-lpm-disable" property.
> 
> Signed-off-by: Thinh Nguyen 
> ---
>  drivers/usb/dwc3/core.c | 2 ++
>  drivers/usb/dwc3/core.h | 2 ++
>  drivers/usb/dwc3/host.c | 5 -
>  3 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index a4068a7b95dd..f6b80a545a78 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -1248,6 +1248,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>   _threshold);
>   dwc->usb3_lpm_capable = device_property_read_bool(dev,
>   "snps,usb3_lpm_capable");
> + dwc->usb2_lpm_disable = device_property_read_bool(dev,
> + "snps,usb2-lpm-disable");

Can we use the same logic as usb3_lpm instead?
i.e. enable USB2 LPM only if "snps,usb2_lpm_capable" is present in DT.
This is because older platforms that are not tested for usb2 lpm
might break if you enable it by default.

Also can we have some consistency in usage of '-' vs '_'?

>   device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd",
>   _thr_num_pkt_prd);
>   device_property_read_u8(dev, "snps,rx-max-burst-prd",
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index 5bfb62533e0f..ca7b5f46e1f0 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -971,6 +971,7 @@ struct dwc3_scratchpad_array {
>   * @setup_packet_pending: true when there's a Setup Packet in FIFO. 
> Workaround
>   * @three_stage_setup: set if we perform a three phase setup
>   * @usb3_lpm_capable: set if hadrware supports Link Power Management
> + * @usb2_lpm_disable: set to disable usb2 lpm
>   * @disable_scramble_quirk: set if we enable the disable scramble quirk
>   * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk
>   * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk
> @@ -1146,6 +1147,7 @@ struct dwc3 {
>   unsignedsetup_packet_pending:1;
>   unsignedthree_stage_setup:1;
>   unsignedusb3_lpm_capable:1;
> + unsignedusb2_lpm_disable:1;
>  
>   unsigneddisable_scramble_quirk:1;
>   unsignedu2exit_lfps_quirk:1;
> diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
> index 1a3878a3be78..f55947294f7c 100644
> --- a/drivers/usb/dwc3/host.c
> +++ b/drivers/usb/dwc3/host.c
> @@ -46,7 +46,7 @@ static int dwc3_host_get_irq(struct dwc3 *dwc)
>  
>  int dwc3_host_init(struct dwc3 *dwc)
>  {
> - struct property_entry   props[3];
> + struct property_entry   props[4];
>   struct platform_device  *xhci;
>   int ret, irq;
>   struct resource *res;
> @@ -93,6 +93,9 @@ int dwc3_host_init(struct dwc3 *dwc)
>   if (dwc->usb3_lpm_capable)
>   props[prop_idx++].name = "usb3-lpm-capable";
>  
> + if (dwc->usb2_lpm_disable)
> + props[prop_idx++].name = "usb2-lpm-disable";
> +
>   /**
>* WORKAROUND: dwc3 revisions <=3.00a have a limitation
>* where Port Disable command doesn't work.
> 

cheers,
-roger
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


Re: usb: dwc3: dwc3 errors while video streaming with uvc-gadget

2018-11-05 Thread Roger Quadros

-Paul Eaves
+Paul Elder

On 03/11/18 23:07, Terence Neill wrote:

Hi folks,

Thanks for the replies, I really appreciate them.  I've made some progress
on this.  I'm new to USB so apologies if the following text is incorrect or
is just bizarre!:

1. The problem with streaming_maxpacket set to 2048 seemed to be caused by
not enough requests being queued with the dwc3 driver at one time, resulting
in request starvation at higher bandwidths.  Increasing the value of the
UVC_NUM_REQUESTS macro from 4 to 16 (in drivers/usb/gadget/function/uvc.h)
seemed to fix this problem.

2. It looks like the problem that was happening with max_packet set to 3072
was caused by the isochronous transfer being queued for a microframe number
in the past (the assumption is that there is the code just wasn't getting
the first microframe queued in time).  To get around this problem, I changed
the DWC3_ALIGN_FRAME() macro to add an offset of one video frame (the video
is running at 10fps so about 800 microframes).  This fixed the startup
problem at high bandwidth. At the moment, the objective of the investigation
is to prove throughput, so some latency can be accommodated.

With these two changes, the video streams at higher bandwidth but freezes
sporadically.  This problem seems to be caused by the following (there's a
bit of guesswork going on in this explanation):

a. The video stream that is being transmitted has less bandwidth than
available on the USB link (1280x720@10fps uncompressed).  It looks like
about 150Mbps versus the 192Mbps for the USB link.
b. The video is not transmitted evenly and, at the end of each video frame
time there are a number of microframes where there is no data to transmit.
c. When the next video packet is queued with the dwc3 driver after the gap
in transmission, the driver generates a string of missed isoc events (it
looks like a missed isoc event for every previous microframe that has been
missed).  These events come as a burst into the driver (after every new
frame is queued into the dwc3).
d. This is reported back to the f_uvc driver via the uvc_video_complete()
function call.  The f_uvc tidies up it's queues based on the callback, but
the dwc3 driver hasn't transmitted any data (it is reporting the missed isoc
from previously).  This seems to cause the video to freeze (dumping frames
before they are transmitted).

As a quick hack, I changed uvc_video_complete() so that it requeued the
request on receipt of the  -EXDEV.  This has fixed the freezing video but
there is video corruption (not surprised as the fix was just to prove that
the freezing was caused by the missed isocs).  I think that this tallies
with what you are saying Laurent about the handling of missed isocs.

 From reading some more about USB, it looks like isochronous transfers may
have the option sending zero length packets whenever there is no data to
send?  Is this true?  If so, would this be a possible option to move forward
with this issue - eliminating the need to handle missed isocs at the f_uvc
layer?

In addition, I've moved on to testing at superspeed (with the same video
source 1280x720@10fps uncompressed).  At the moment, with the superspeed
link set to a burst size of 16 and an interval of 8, the dwc3 driver will
not stream at all, it continuously reports missed isoc events for all
microframes despite having the delay added in (2) above.  Has anyone any
experience using isochronous transfers with the dwc3 driver at superspeed?

I was reading the summary of the dwc3 driver features at
https://github.com/torvalds/linux/blob/master/Documentation/driver-api/usb/d
wc3.rst and point 7 mentions support for "Superspeed Bulk Streams" but I was
unsure if this meant that ONLY bulk streams were supported or whether
isochronous streams were also supported?

Thanks again for the help,

Regards,

Terry Neill


-Original Message-
From: Laurent Pinchart 
Sent: 02 November 2018 11:49
To: Roger Quadros 
Cc: Terence Neill ; linux-usb@vger.kernel.org;
Eaves, Paul 
Subject: Re: usb: dwc3: dwc3 errors while video streaming with uvc-gadget

Hello,

On Friday, 2 November 2018 11:50:47 EET Roger Quadros wrote:

On 15/10/18 19:34, Terence Neill wrote:

Hi Felipe,

I am having some issues when attempting to stream 1280x720
uncompressed video @ 10fps over a USB 2.0 High-Speed link.

The system setup is:

WebCam --- USB 2.0 link --->  x86 Linux Machine running uvc-gadget
 USB 2.0 link ---> x86 Host Machine running Windows 10.

When running this setup, I am experiencing the following:

1. With streaming_maxpacket set to 2048 (2 transactions per
microframe) the video will stream for approximately one minute
before terminating with "VS request completed with status -18" reported

in the kernel logs.


2. With streaming_maxpacket set to 3072 (3 transactions per
microframe) the video does not stream at all with "VS request
completed with status -18" reported in the error logs.


There were some updat

Re: usb: dwc3: dwc3 errors while video streaming with uvc-gadget

2018-11-02 Thread Roger Quadros

Hi Terry,

On 15/10/18 19:34, Terence Neill wrote:

Hi Felipe,

I am having some issues when attempting to stream 1280x720 uncompressed video @ 
10fps over a USB 2.0 High-Speed link.

The system setup is:

WebCam --- USB 2.0 link --->  x86 Linux Machine running uvc-gadget  USB 2.0 
link ---> x86 Host Machine running Windows 10.

When running this setup, I am experiencing the following:

1. With streaming_maxpacket set to 2048 (2 transactions per microframe) the video will 
stream for approximately one minute before terminating with "VS request completed 
with status -18" reported in the kernel logs.

2. With streaming_maxpacket set to 3072 (3 transactions per microframe) the video does 
not stream at all with "VS request completed with status -18" reported in the 
error logs.


There were some updates pushed recently to the uvc-gadget utility [1].
Could you please try with that and see if this issue still persists? Thanks.

[1] http://git.ideasonboard.org/uvc-gadget.git



 From trying to analyse what is going on (looking at traces), it looks like the 
dwc3 driver is initially forwarding video buffers as expected. Because the 
bandwdith of the USB link is greater than the bandiwidth of the video being 
transmitted, at some point the dwc3 driver looks for more buffers to transmit 
and there aren't any.  At this point, it seems to enter a state that is not 
recovered from whenever a new buffer becomes available to transmit.

I have included a trace and register dump as requested for further analysis.

In terms of hardware/software versions for the test setup:

Linux machine - Intel n4200 - running Ubuntu 18.04 - kernel version 
4.19.0-041900rc8-generic (I updated to this version this morning to make sure I 
was using the latest dwc3 driver, the same problem exists (with a different 
error code -104) with the stock Ubuntu 18.04 kernel).

Windows machine - Core i5-4570 - Windows 10 Enterprise.

Any help with further investigation of this problem would be appreciated?  
Could this problem be caused by the configuration setup that I'm using for the 
uvc gadget?

Thanks in advance for your help,

Regards,


Terry



cheers,
-roger

--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


Re: [PATCH 3/3] mfd: omap-usb-host: Drop support for non-DT probe

2018-09-12 Thread Roger Quadros
On 12/09/18 11:30, Laurent Pinchart wrote:
> Hi Roger,
> 
> On Wednesday, 12 September 2018 10:57:31 EEST Roger Quadros wrote:
>> On 11/09/18 18:06, Laurent Pinchart wrote:
>>> Now that all platforms using OMAP USB host devices have been converted
>>> to DT, drop support for legacy non-DT probe from the driver.
>>>
>>> Signed-off-by: Laurent Pinchart 
>>> ---
>>>
>>>  drivers/mfd/omap-usb-host.c| 153 ++--
>>>  include/linux/platform_data/usb-omap.h |   4 -
>>>  2 files changed, 13 insertions(+), 144 deletions(-)
>>>
>>> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
>>> index b731026541f5..ce28e0fda55e 100644
>>> --- a/drivers/mfd/omap-usb-host.c
>>> +++ b/drivers/mfd/omap-usb-host.c
> 
> [snip]
> 
>>> @@ -541,31 +424,28 @@ static const struct of_device_id
>>> usbhs_child_match_table[] = {
>>>  static int usbhs_omap_probe(struct platform_device *pdev)
>>>  {
>>> struct device   *dev =  >dev;
>>> -   struct usbhs_omap_platform_data *pdata = dev_get_platdata(dev);
>>> +   struct usbhs_omap_platform_data *pdata;
>>> struct usbhs_hcd_omap   *omap;
>>> struct resource *res;
>>> int ret = 0;
>>> int i;
>>> boolneed_logic_fck;
>>>
>>> -   dev_info(>dev, "%s\n", __func__);
>>> -   if (dev->of_node) {
>>> -   /* For DT boot we populate platform data from OF node */
>>> -   pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
>>> -   if (!pdata)
>>> -   return -ENOMEM;
>>> +   /* Populate platform data from OF node */
>>> +   if (!dev->of_node) {
>>> +   dev_err(dev, "Missing OF node\n");
>>> +   return -ENODEV;
>>> +   }
>>>
>>> -   ret = usbhs_omap_get_dt_pdata(dev, pdata);
>>> -   if (ret)
>>> -   return ret;
>>> +   pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
>>> +   if (!pdata)
>>> +   return -ENOMEM;
>>>
>>> -   dev->platform_data = pdata;
>>> -   }
>>> +   ret = usbhs_omap_get_dt_pdata(dev, pdata);
>>> +   if (ret)
>>> +   return ret;
>>>
>>> -   if (!pdata) {
>>> -   dev_err(dev, "Missing platform data\n");
>>> -   return -ENODEV;
>>> -   }
>>> +   dev->platform_data = pdata;
>>
>> Do we still need to set dev->platform_data?
>>
>> This driver can access it via
>>  struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
>>  omap->pdata;
> 
> Unfortunately we still do, as the ehci-omap driver accesses the omap-usb-host 
> device platform data (through the ehci-omap device's parent).

Ah, you're right.
Seems like it uses it only to get the nports, and port_mode[].

For this patch.

Acked-by: Roger Quadros 

> 
>>> if (pdata->nports > OMAP3_HS_USB_PORTS) {
>>> dev_info(dev, "Too many num_ports <%d> in platform_data. Max 
>>> %d\n",
>>>
>>> @@ -798,13 +678,6 @@ static int usbhs_omap_probe(struct platform_device
>>> *pdev)
>>> goto err_mem;
>>> }
>>> -   } else {
>>> -   ret = omap_usbhs_alloc_children(pdev);
>>> -   if (ret) {
>>> -   dev_err(dev, "omap_usbhs_alloc_children failed: %d\n",
>>> -   ret);
>>> -   goto err_mem;
>>> -   }
>>> }
>>> 
>>> return 0;
> 
> [snip]
> 

cheers,
-roger

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


Re: [PATCH 2/3] ARM: OMAP2+: Remove legacy USB initialization code

2018-09-12 Thread Roger Quadros
On 11/09/18 18:06, Laurent Pinchart wrote:
> Several legacy USB-related functions, structures and macros are not used
> anymore after conversion to DT. Remove them.
> 
> Signed-off-by: Laurent Pinchart 

Acked-by: Roger Quadros 

cheers,
-roger

> ---
>  arch/arm/mach-omap2/common.h|  2 -
>  arch/arm/mach-omap2/omap_phy_internal.c | 96 
> +
>  arch/arm/mach-omap2/usb.h   | 71 
>  3 files changed, 2 insertions(+), 167 deletions(-)
>  delete mode 100644 arch/arm/mach-omap2/usb.h
> 
> diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
> index 129455e822e4..7b561e07571e 100644
> --- a/arch/arm/mach-omap2/common.h
> +++ b/arch/arm/mach-omap2/common.h
> @@ -40,8 +40,6 @@
>  #include "i2c.h"
>  #include "serial.h"
>  
> -#include "usb.h"
> -
>  #define OMAP_INTC_START  NR_IRQS
>  
>  extern int (*omap_pm_soc_init)(void);
> diff --git a/arch/arm/mach-omap2/omap_phy_internal.c 
> b/arch/arm/mach-omap2/omap_phy_internal.c
> index 8e903564ede2..456a883bbbda 100644
> --- a/arch/arm/mach-omap2/omap_phy_internal.c
> +++ b/arch/arm/mach-omap2/omap_phy_internal.c
> @@ -23,17 +23,11 @@
>  
>  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>  
> -#include 
> -#include 
> -#include 
> -#include 
>  #include 
> -#include 
> -#include 
> +#include 
> +#include 
>  
>  #include "soc.h"
> -#include "control.h"
> -#include "usb.h"
>  
>  #define CONTROL_DEV_CONF 0x300
>  #define PHY_PD   0x1
> @@ -66,89 +60,3 @@ static int __init omap4430_phy_power_down(void)
>   return 0;
>  }
>  omap_early_initcall(omap4430_phy_power_down);
> -
> -void am35x_musb_reset(void)
> -{
> - u32 regval;
> -
> - /* Reset the musb interface */
> - regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
> -
> - regval |= AM35XX_USBOTGSS_SW_RST;
> - omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
> -
> - regval &= ~AM35XX_USBOTGSS_SW_RST;
> - omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
> -
> - regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
> -}
> -
> -void am35x_musb_phy_power(u8 on)
> -{
> - unsigned long timeout = jiffies + msecs_to_jiffies(100);
> - u32 devconf2;
> -
> - if (on) {
> - /*
> -  * Start the on-chip PHY and its PLL.
> -  */
> - devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
> -
> - devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN);
> - devconf2 |= CONF2_PHY_PLLON;
> -
> - omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
> -
> - pr_info("Waiting for PHY clock good...\n");
> - while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2)
> - & CONF2_PHYCLKGD)) {
> - cpu_relax();
> -
> - if (time_after(jiffies, timeout)) {
> - pr_err("musb PHY clock good timed out\n");
> - break;
> - }
> - }
> - } else {
> - /*
> -  * Power down the on-chip PHY.
> -  */
> - devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
> -
> - devconf2 &= ~CONF2_PHY_PLLON;
> - devconf2 |=  CONF2_PHYPWRDN | CONF2_OTGPWRDN;
> - omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
> - }
> -}
> -
> -void am35x_musb_clear_irq(void)
> -{
> - u32 regval;
> -
> - regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
> - regval |= AM35XX_USBOTGSS_INT_CLR;
> - omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
> - regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
> -}
> -
> -void am35x_set_mode(u8 musb_mode)
> -{
> - u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
> -
> - devconf2 &= ~CONF2_OTGMODE;
> - switch (musb_mode) {
> - case MUSB_HOST: /* Force VBUS valid, ID = 0 */
> - devconf2 |= CONF2_FORCE_HOST;
> - break;
> - case MUSB_PERIPHERAL:   /* Force VBUS valid, ID = 1 */
> - devconf2 |= CONF2_FORCE_DEVICE;
> - break;
> - case MUSB_OTG:  /* Don't override the VBUS/ID comparators */
> - devconf2 |= CONF2_NO_OVERRIDE;
> - break;
> - default:
> - pr_info("Unsupported mode %u\n", musb_mode);
> - }
>

Re: [PATCH 3/3] mfd: omap-usb-host: Drop support for non-DT probe

2018-09-12 Thread Roger Quadros
Hi Laurent,

On 11/09/18 18:06, Laurent Pinchart wrote:
> Now that all platforms using OMAP USB host devices have been converted
> to DT, drop support for legacy non-DT probe from the driver.
> 
> Signed-off-by: Laurent Pinchart 
> ---
>  drivers/mfd/omap-usb-host.c| 153 
> +++--
>  include/linux/platform_data/usb-omap.h |   4 -
>  2 files changed, 13 insertions(+), 144 deletions(-)
> 
> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
> index b731026541f5..ce28e0fda55e 100644
> --- a/drivers/mfd/omap-usb-host.c
> +++ b/drivers/mfd/omap-usb-host.c
> @@ -23,7 +23,6 @@
>  #include 
>  #include 
>  #include 
> -#include 
>  #include 
>  #include 
>  #include 


> @@ -35,8 +34,6 @@
>  #include "omap-usb.h"
>  
>  #define USBHS_DRIVER_NAME"usbhs_omap"
> -#define OMAP_EHCI_DEVICE "ehci-omap"
> -#define OMAP_OHCI_DEVICE "ohci-omap3"
>  
>  /* OMAP USBHOST Register addresses  */
>  
> @@ -115,7 +112,6 @@ struct usbhs_hcd_omap {
>  /*-*/
>  
>  static const char usbhs_driver_name[] = USBHS_DRIVER_NAME;
> -static u64 usbhs_dmamask = DMA_BIT_MASK(32);
>  
>  /*-*/
>  
> @@ -153,119 +149,6 @@ static const char * const port_modes[] = {
>   [OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM] = "ohci-tll-2pin-dpdm",
>  };
>  
> -static struct platform_device *omap_usbhs_alloc_child(const char *name,
> - struct resource *res, int num_resources, void *pdata,
> - size_t pdata_size, struct device *dev)
> -{
> - struct platform_device  *child;
> - int ret;
> -
> - child = platform_device_alloc(name, 0);
> -
> - if (!child) {
> - dev_err(dev, "platform_device_alloc %s failed\n", name);
> - goto err_end;
> - }
> -
> - ret = platform_device_add_resources(child, res, num_resources);
> - if (ret) {
> - dev_err(dev, "platform_device_add_resources failed\n");
> - goto err_alloc;
> - }
> -
> - ret = platform_device_add_data(child, pdata, pdata_size);
> - if (ret) {
> - dev_err(dev, "platform_device_add_data failed\n");
> - goto err_alloc;
> - }
> -
> - child->dev.dma_mask = _dmamask;
> - dma_set_coherent_mask(>dev, DMA_BIT_MASK(32));
> - child->dev.parent   = dev;
> -
> - ret = platform_device_add(child);
> - if (ret) {
> - dev_err(dev, "platform_device_add failed\n");
> - goto err_alloc;
> - }
> -
> - return child;
> -
> -err_alloc:
> - platform_device_put(child);
> -
> -err_end:
> - return NULL;
> -}
> -
> -static int omap_usbhs_alloc_children(struct platform_device *pdev)
> -{
> - struct device   *dev = >dev;
> - struct usbhs_omap_platform_data *pdata = dev_get_platdata(dev);
> - struct platform_device  *ehci;
> - struct platform_device  *ohci;
> - struct resource *res;
> - struct resource resources[2];
> - int ret;
> -
> - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci");
> - if (!res) {
> - dev_err(dev, "EHCI get resource IORESOURCE_MEM failed\n");
> - ret = -ENODEV;
> - goto err_end;
> - }
> - resources[0] = *res;
> -
> - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ehci-irq");
> - if (!res) {
> - dev_err(dev, " EHCI get resource IORESOURCE_IRQ failed\n");
> - ret = -ENODEV;
> - goto err_end;
> - }
> - resources[1] = *res;
> -
> - ehci = omap_usbhs_alloc_child(OMAP_EHCI_DEVICE, resources, 2, pdata,
> - sizeof(*pdata), dev);
> -
> - if (!ehci) {
> - dev_err(dev, "omap_usbhs_alloc_child failed\n");
> - ret = -ENOMEM;
> - goto err_end;
> - }
> -
> - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ohci");
> - if (!res) {
> - dev_err(dev, "OHCI get resource IORESOURCE_MEM failed\n");
> - ret = -ENODEV;
> - goto err_ehci;
> - }
> - resources[0] = *res;
> -
> - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ohci-irq");
> - if (!res) {
> - dev_err(dev, "OHCI get resource IORESOURCE_IRQ failed\n");
> - ret = -ENODEV;
> - goto err_ehci;
> - }
> - resources[1] = *res;
> -
> - ohci = omap_usbhs_alloc_child(OMAP_OHCI_DEVICE, resources, 2, pdata,
> - sizeof(*pdata), dev);
> - if (!ohci) {
> - dev_err(dev, "omap_usbhs_alloc_child failed\n");
> - ret = -ENOMEM;
> - goto err_ehci;
> - }
> -
> - return 0;
> -
> -err_ehci:
> - 

Re: usb: gadget: ffs: Fix BUG when userland exits with submitted AIO transfers

2018-06-21 Thread Roger Quadros
On 21/06/18 13:52, Lars-Peter Clausen wrote:
> On 06/21/2018 10:29 AM, Roger Quadros wrote:
> [...]
>>>>  static int ffs_aio_cancel(struct kiocb *kiocb)
>>>>  {
>>>> struct ffs_io_data *io_data = kiocb->private;
>>>> -   struct ffs_epfile *epfile = kiocb->ki_filp->private_data;
>>>> +   struct ffs_data *ffs = io_data->ffs;
>>>> int value;
>>>>
>>>> ENTER();
>>>>
>>>> -   spin_lock_irq(>ffs->eps_lock);
>>>> -
>>>> -   if (likely(io_data && io_data->ep && io_data->req))
>>>> -   value = usb_ep_dequeue(io_data->ep, io_data->req);
>>>> -   else
>>>> +   if (likely(io_data && io_data->ep && io_data->req)) {
>>>> +   INIT_WORK(_data->cancellation_work, 
>>>> ffs_aio_cancel_worker);
>>>> +   queue_work(ffs->io_completion_wq, 
>>>> _data->cancellation_work);
>>>> +   value = -EINPROGRESS;
>>>> +   } else {
>>>> value = -EINVAL;
>>>> -
>>>> -   spin_unlock_irq(>ffs->eps_lock);
>>>> +   }
>>
>> Can we avoid the spin_lock() and the work-queue and call usb_ep_dequeue() 
>> directly from here?
>>> What is the purpose of the spin_lock()?
> 
> I agree that the lock doesn't seem to be necessary. But I believe the whole
> thing is already running in non-sleeping context, even before the spinlock
> is taken. So this wouldn't help much.
> 
> Even the io_cancel() syscall takes a spinlock before invoking the cancel
> function. So this issue is not exclusive to program termination.
> 
> Are there any documented guidelines on which context usb_ep_dequeue() should
> be able to be called in? The sleep in the dwc3 driver seems to be a recent
> addition.

drivers/usb/udc/gadget/core.c has the only documentation, but context is not 
mentioned there.
Felipe, what do you suggest?

> 
>>
>>>>
>>>> return value;
>>>>  }
>>>> --
>>>> 2.17.1
>>>>
>>
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: usb: gadget: ffs: Fix BUG when userland exits with submitted AIO transfers

2018-06-21 Thread Roger Quadros
+Lars-Peter

Vincent,

On 14/06/18 16:23, Sam Protsenko wrote:
> + Roger Quadros
> + Praneeth Bajjuri
> 
> Tested-by: Sam Protsenko 
> 
> I've tested it on X15 board (DWC3 controller) on Android master, by
> doing "adb root". Without this patch I see backtrace and kernel panic
> (the same error as described in commit message). When this patch is
> applied, everything works fine.
> 
> Can we please merge this patch, it fixes major bug for us?
> 
> Thanks!
> 
> 
> On 13 June 2018 at 14:05, Vincent Pelletier  wrote:
>> This bug happens only when the UDC needs to sleep during usb_ep_dequeue,
>> as is the case for (at least) dwc3.
>>
>> [  382.200896] BUG: scheduling while atomic: screen/1808/0x0100
>> [  382.207124] 4 locks held by screen/1808:
>> [  382.211266]  #0:  (rcu_callback){}, at: [] 
>> rcu_process_callbacks+0x260/0x440
>> [  382.219949]  #1:  (rcu_read_lock_sched){}, at: [] 
>> percpu_ref_switch_to_atomic_rcu+0xb0/0x130
>> [  382.230034]  #2:  (&(>ctx_lock)->rlock){}, at: [] 
>> free_ioctx_users+0x23/0xd0
>> [  382.230096]  #3:  (&(>eps_lock)->rlock){}, at: [] 
>> ffs_aio_cancel+0x20/0x60 [usb_f_fs]
>> [  382.230160] Modules linked in: usb_f_fs libcomposite configfs bnep btsdio 
>> bluetooth ecdh_generic brcmfmac brcmutil intel_powerclamp coretemp dwc3 
>> kvm_intel ulpi udc_core kvm irqbypass crc32_pclmul crc32c_intel pcbc 
>> dwc3_pci aesni_intel aes_i586 crypto_simd cryptd ehci_pci ehci_hcd gpio_keys 
>> usbcore basincove_gpadc industrialio usb_common
>> [  382.230407] CPU: 1 PID: 1808 Comm: screen Not tainted 4.14.0-edison+ #117
>> [  382.230416] Hardware name: Intel Corporation Merrifield/BODEGA BAY, BIOS 
>> 542 2015.01.21:18.19.48
>> [  382.230425] Call Trace:
>> [  382.230438]  
>> [  382.230466]  dump_stack+0x47/0x62
>> [  382.230498]  __schedule_bug+0x61/0x80
>> [  382.230522]  __schedule+0x43/0x7a0
>> [  382.230587]  schedule+0x5f/0x70
>> [  382.230625]  dwc3_gadget_ep_dequeue+0x14c/0x270 [dwc3]
>> [  382.230669]  ? do_wait_intr_irq+0x70/0x70
>> [  382.230724]  usb_ep_dequeue+0x19/0x90 [udc_core]
>> [  382.230770]  ffs_aio_cancel+0x37/0x60 [usb_f_fs]
>> [  382.230798]  kiocb_cancel+0x31/0x40
>> [  382.230822]  free_ioctx_users+0x4d/0xd0
>> [  382.230858]  percpu_ref_switch_to_atomic_rcu+0x10a/0x130
>> [  382.230881]  ? percpu_ref_exit+0x40/0x40
>> [  382.230904]  rcu_process_callbacks+0x2b3/0x440
>> [  382.230965]  __do_softirq+0xf8/0x26b
>> [  382.231011]  ? __softirqentry_text_start+0x8/0x8
>> [  382.231033]  do_softirq_own_stack+0x22/0x30
>> [  382.231042]  
>> [  382.231071]  irq_exit+0x45/0xc0
>> [  382.231089]  smp_apic_timer_interrupt+0x13c/0x150
>> [  382.231118]  apic_timer_interrupt+0x35/0x3c
>> [  382.231132] EIP: __copy_user_ll+0xe2/0xf0
>> [  382.231142] EFLAGS: 00210293 CPU: 1
>> [  382.231154] EAX: bfd4508c EBX: 0004 ECX: 0003 EDX: f3d8fe50
>> [  382.231165] ESI: f3d8fe51 EDI: bfd4508d EBP: f3d8fe14 ESP: f3d8fe08
>> [  382.231176]  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
>> [  382.231265]  core_sys_select+0x25f/0x320
>> [  382.231346]  ? __wake_up_common_lock+0x62/0x80
>> [  382.231399]  ? tty_ldisc_deref+0x13/0x20
>> [  382.231438]  ? ldsem_up_read+0x1b/0x40
>> [  382.231459]  ? tty_ldisc_deref+0x13/0x20
>> [  382.231479]  ? tty_write+0x29f/0x2e0
>> [  382.231514]  ? n_tty_ioctl+0xe0/0xe0
>> [  382.231541]  ? tty_write_unlock+0x30/0x30
>> [  382.231566]  ? __vfs_write+0x22/0x110
>> [  382.231604]  ? security_file_permission+0x2f/0xd0
>> [  382.231635]  ? rw_verify_area+0xac/0x120
>> [  382.231677]  ? vfs_write+0x103/0x180
>> [  382.231711]  SyS_select+0x87/0xc0
>> [  382.231739]  ? SyS_write+0x42/0x90
>> [  382.231781]  do_fast_syscall_32+0xd6/0x1a0
>> [  382.231836]  entry_SYSENTER_32+0x47/0x71
>> [  382.231848] EIP: 0xb7f75b05
>> [  382.231857] EFLAGS: 0246 CPU: 1
>> [  382.231868] EAX: ffda EBX: 0400 ECX: bfd4508c EDX: bfd4510c
>> [  382.231878] ESI:  EDI:  EBP:  ESP: bfd45020
>> [  382.231889]  DS: 007b ES: 007b FS:  GS: 0033 SS: 007b
>> [  382.232281] softirq: huh, entered softirq 9 RCU c10b4d90 with 
>> preempt_count 0100, exited with ?
>>
>> Signed-off-by: Vincent Pelletier 
>> ---
>>  drivers/usb/gadget/function/f_fs.c | 26 ++
>>  1 file changed, 18 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/usb/gadget/function/f_fs.c 
>> b/drivers/usb/gadget/function/f_fs.c
>> index 199d25700050..01841fdb3

Re: [PATCH] usb: dwc3: of-simple: fix use-after-free on remove

2018-06-21 Thread Roger Quadros
On 21/06/18 01:55, Rafael J. Wysocki wrote:
> On Thu, Jun 21, 2018 at 12:32 AM, Rafael J. Wysocki  wrote:
>> On Wed, Jun 20, 2018 at 5:46 PM, Johan Hovold  wrote:
>>> On Wed, Jun 20, 2018 at 02:54:10PM +0200, Rafael J. Wysocki wrote:
 On Wednesday, June 20, 2018 2:23:46 PM CEST Johan Hovold wrote:
> On Wed, Jun 20, 2018 at 02:16:59AM -0700, Tony Lindgren wrote:
>> Hi,
>>
>> Adding Rafael and linux-pm to Cc as well.
>>
>> * Felipe Balbi  [180619 01:23]:
>>> This is a direct consequence of not paying attention to the order of
>>> things. If driver were to assume that pm_domain->activate() would do the
>>> right thing for the device -- meaning that probe would run with an
>>> active device --, then we wouldn't need that pm_runtime_get() call on
>>> probe at all. Rather we would follow the sequence:
>>>
>>> pm_runtime_forbid()
>>> pm_runtime_set_active()
>>> pm_runtime_enable()
>>>
>>> /* do your probe routine */
>>>
>>> pm_runtime_put_noidle()
>>>
>>> Then you remove you would need to call pm_runtime_get_noresume() to
>>> balance out the pm_runtime_put_noidle() there.
>
>>> (If you need to know why the pm_runtime_put_noidle(), remember that
>>> pm_runtime_set_active() increments the usage counter, so
>>> pm_runtime_put_noidle is basically allowing pm_runtime to happen as soon
>>> as userspace writes "auto" to /sys//power/control)
>
> That's not correct; pm_runtime_set_active() only increments the usage
> counter of a parent (under some circumstances), so unless you have bus
> code incrementing the usage counter before probe, the above
> pm_runtime_put_noidle() would actually introduce an imbalance.

 No, it wouldn't.  It balances the incrementation in pm_runtime_forbid().
>>>
>>> Right, but even if you take the whole sequence, which included
>>> pm_runtime_forbid(), consider what happens when pm_runtime_allow() is
>>> later called through sysfs (see below).
>>>
> And note that that's also the case even if you meant to say that
> *pm_runtime_forbid()* increments the usage counter (which it does).

 Why is it?

 Surely, after

 pm_runtime_forbid(dev);
 pm_runtime_put_noidle(dev);

 the runtime PM usage counter of dev will be the same as before, won't it?
>>>
>>> Sure, but the imbalance, or rather inconsistent state, has already been
>>> introduced.
>>>
>>> Consider the following sequence of events:
>>>
>>> usage count
>>> 0
>>> probe()
>>> pm_runtime_forbid() 1

Can you call pm_runtime_forbid() before pm_runtime_enable()?
Wouldn't it fail with -EACCES as dev->power.disable_depth > 0?

>>> pm_runtime_set_active()
>>> pm_runtime_enable()
>>> pm_runtime_put_noidle() 0
>>>
>>> Here nothing is preventing the device from runtime suspending, despite
>>> runtime PM being forbidden. In fact, it will typically be suspended due
>>> to the pm_request_idle() in driver_probe_device(). If later we have:
>>>
>>> echo auto > power/control
>>> pm_runtime_allow()  -1
>>
>> OK, you have a point.
>>
>> After calling pm_runtime_forbid() the driver should allow user space
>> to unblock runtime PM for the device - or call pm_runtime_allow()
>> itself.
> 
> The confusion regarding the pm_runtime_put_noidle() at the end may
> come from the special requirement of the PCI bus type as per the
> comment in local_pci_probe().
> 

OK. So it is the PCI bus which is behaving odd here and
pm_runtime_put_noidle() needs to be done only if its a PCI device, correct?

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: of-simple: fix use-after-free on remove

2018-06-18 Thread Roger Quadros
+Tero, Tony and some TI folks

On 18/06/18 15:21, Felipe Balbi wrote:
> 
> Hi,
> 
> Roger Quadros  writes:
>> On 18/06/18 12:51, Felipe Balbi wrote:
>>>
>>> Hi,
>>>
>>> Johan Hovold  writes:
>>>> On Mon, Jun 18, 2018 at 12:33:44PM +0300, Felipe Balbi wrote:
>>>>
>>>>> Johan Hovold  writes:
>>>>
>>>>>> I suggest merging this fix for 4.18-rc, and then Roger can rework the
>>>>>> driver so that it works also on OMAP.
>>>>>
>>>>> omap has its own glue layer for several reasons. If you're talking about
>>>>> Keystone devices, then okay, I understand. But in that case, this would
>>>>> mean Keystone is copying the same arguably broken PM domain design from
>>>>> OMAP and it would be best not to propagate that idea.
>>>>
>>>> Maybe so. I'm not sure what Roger's use case is, but perhaps the omap
>>>> glue driver could be used instead.
>>>
>>> unlikely. Keystone devices are very different from OMAP family. But
>>> we'll see what Roger says.
>>>
>>
>> Well, I was considering to use of-simple for the AM654 SoC [1] but now
>> I'm of the opinion that it might be better to add a new glue layer driver
> 
> why isn't dwc3-keystone.c enough?

It is doing too many things than we really need to for AM654.

> 
>> for that because
>> - it needs to poke a few registers in the wrapper region
> 
> dwc3-keystone.c does that already
> 
>> - it doesn't really need the driver to enable any clock
> 
> Seems to me you're trying to port omap_device to arm64...

It isn't an omap_device but is very similar to how it is done on keystone.

> 
>> - it needs a pm_runtime_get_sync() to be done in probe
> 
> this really shouldn't be necessary. Keystone doesn't rely on all the
> omap_device legacy. At least it didn't use to. Could it be that you're
> just missing a struct dev_pm_domain definition for arm64?

I don't think so. If I had missed it it wouldn't enable at all.

> 
> I haven't seen how you guys implemented your PM for arm64 (is there a
> publically accessible version somewhere?), but I'd say you should take
> the opportunity to remove this relying on pm_runtime_get_sync() calls
> from probe and just do what everybody else does; namely: enable clocks
> on probe, pm_runtime_set_active, etc.

This is something Tero can comment on.

> 
> This helps drivers being able to make assumptions about devices being
> enabled during probe. pm_runtime becomes easier to implement generically
> too.
> 

You keep mentioning that PM domain design is broken on OMAP.
Could you please clarify what is broken? Is it the fact that the bus code
doesn't enable the device before probe and that we have to do a 
pm_runtime_sync() in probe?

I tried to discuss this here [1] but looks like you missed it.

Re-iterating here.

Platform bus doesn't seem to enable the device as part of 
of_platform_populate().

see __device_attach() and driver_probe_device() in drivers/base/dd.c

It does a pm_runtime_get_sync() on dev->parent but not on dev.

Also, from section 5 of Documentation/power/runtime_pm.txt

"In addition to that, the initial runtime PM status of all devices is
'suspended', but it need not reflect the actual physical state of the device.
Thus, if the device is initially active (i.e. it is able to process I/O), its
runtime PM status must be changed to 'active', with the help of
pm_runtime_set_active(), before pm_runtime_enable() is called for the device."

"Note, if the device may execute pm_runtime calls during the probe (such as
if it is registers with a subsystem that may call back in) then the
pm_runtime_get_sync() call paired with a pm_runtime_put() call will be
appropriate to ensure that the device is not put back to sleep during the
probe. This can happen with systems such as the network device layer."

So looks like we can't assume that the device is "active" when probe() is 
called.
Which means, we need to do

pm_runtime_get_sync();
enable optional clocks;


[1] https://lkml.org/lkml/2018/6/13/265

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: of-simple: fix use-after-free on remove

2018-06-18 Thread Roger Quadros
On 18/06/18 12:51, Felipe Balbi wrote:
> 
> Hi,
> 
> Johan Hovold  writes:
>> On Mon, Jun 18, 2018 at 12:33:44PM +0300, Felipe Balbi wrote:
>>
>>> Johan Hovold  writes:
>>
 I suggest merging this fix for 4.18-rc, and then Roger can rework the
 driver so that it works also on OMAP.
>>>
>>> omap has its own glue layer for several reasons. If you're talking about
>>> Keystone devices, then okay, I understand. But in that case, this would
>>> mean Keystone is copying the same arguably broken PM domain design from
>>> OMAP and it would be best not to propagate that idea.
>>
>> Maybe so. I'm not sure what Roger's use case is, but perhaps the omap
>> glue driver could be used instead.
> 
> unlikely. Keystone devices are very different from OMAP family. But
> we'll see what Roger says.
> 

Well, I was considering to use of-simple for the AM654 SoC [1] but now
I'm of the opinion that it might be better to add a new glue layer driver
for that because
- it needs to poke a few registers in the wrapper region
- it doesn't really need the driver to enable any clock
- it needs a pm_runtime_get_sync() to be done in probe

[1] - https://lkml.org/lkml/2018/6/5/44

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: of-simple: fix use-after-free on remove

2018-06-13 Thread Roger Quadros
On 13/06/18 11:05, Felipe Balbi wrote:
> Roger Quadros  writes:
> 
>> Hi Johan,
>>
>> On 31/05/18 17:45, Johan Hovold wrote:
>>> The clocks have already been explicitly disabled and put as part of
>>> remove() so the runtime suspend callback must not be run when balancing
>>> the runtime PM usage count before returning.
>>>
>>> Fixes: 16adc674d0d6 ("usb: dwc3: add generic OF glue layer")
>>> Signed-off-by: Johan Hovold 
>>> ---
>>>
>>> Changes in v2
>>>  - balance usage count only after disabling runtime PM to avoid racing
>>>with pm_runtime_suspend() as suggested by Alan
>>>
>>>
>>>  drivers/usb/dwc3/dwc3-of-simple.c | 3 ++-
>>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
>>> b/drivers/usb/dwc3/dwc3-of-simple.c
>>> index cb2ee96fd3e8..048922d549dd 100644
>>> --- a/drivers/usb/dwc3/dwc3-of-simple.c
>>> +++ b/drivers/usb/dwc3/dwc3-of-simple.c
>>> @@ -165,8 +165,9 @@ static int dwc3_of_simple_remove(struct platform_device 
>>> *pdev)
>>>  
>>> reset_control_put(simple->resets);
>>>  
>>> -   pm_runtime_put_sync(dev);
>>
>> Wasn't this call there to balance out the pm_runtime_get_sync() call in 
>> probe()?
>> The pm_runtime_get_sync() call is still there in probe().
> 
> that's now balanced by put_noidle below
> 
> 

OK.

I'm still trying to get my head around this.

in probe() we do
{
enable all clocks;
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
}

How will runtime suspend work at all?
We're holding a positive RPM count in probe().

This was pointed out by Johan as well in [1]

[1] https://lkml.org/lkml/2018/5/28/1705


-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: of-simple: fix use-after-free on remove

2018-06-13 Thread Roger Quadros
Hi Johan,

On 31/05/18 17:45, Johan Hovold wrote:
> The clocks have already been explicitly disabled and put as part of
> remove() so the runtime suspend callback must not be run when balancing
> the runtime PM usage count before returning.
> 
> Fixes: 16adc674d0d6 ("usb: dwc3: add generic OF glue layer")
> Signed-off-by: Johan Hovold 
> ---
> 
> Changes in v2
>  - balance usage count only after disabling runtime PM to avoid racing
>with pm_runtime_suspend() as suggested by Alan
> 
> 
>  drivers/usb/dwc3/dwc3-of-simple.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
> b/drivers/usb/dwc3/dwc3-of-simple.c
> index cb2ee96fd3e8..048922d549dd 100644
> --- a/drivers/usb/dwc3/dwc3-of-simple.c
> +++ b/drivers/usb/dwc3/dwc3-of-simple.c
> @@ -165,8 +165,9 @@ static int dwc3_of_simple_remove(struct platform_device 
> *pdev)
>  
>   reset_control_put(simple->resets);
>  
> - pm_runtime_put_sync(dev);

Wasn't this call there to balance out the pm_runtime_get_sync() call in probe()?
The pm_runtime_get_sync() call is still there in probe().

>   pm_runtime_disable(dev);
> + pm_runtime_put_noidle(dev);
> + pm_runtime_set_suspended(dev);
>  
>   return 0;
>  }
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


[PATCH 2/2] usb: dwc3: of_simple: don't call pm_runtime_set_active()

2018-05-28 Thread Roger Quadros
Don't call pm_runtime_set_active() as it will prevent the device
from being activated in the next pm_runtime_get_sync() call.

Also call pm_runtime_get_sync() before of_platform_populate().

Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/dwc3/dwc3-of-simple.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
b/drivers/usb/dwc3/dwc3-of-simple.c
index e98d221..2cbb5c0 100644
--- a/drivers/usb/dwc3/dwc3-of-simple.c
+++ b/drivers/usb/dwc3/dwc3-of-simple.c
@@ -121,6 +121,9 @@ static int dwc3_of_simple_probe(struct platform_device 
*pdev)
if (ret)
goto err_resetc_assert;
 
+   pm_runtime_enable(dev);
+   pm_runtime_get_sync(dev);
+
ret = of_platform_populate(np, NULL, NULL, dev);
if (ret) {
for (i = 0; i < simple->num_clocks; i++) {
@@ -131,10 +134,6 @@ static int dwc3_of_simple_probe(struct platform_device 
*pdev)
goto err_resetc_assert;
}
 
-   pm_runtime_set_active(dev);
-   pm_runtime_enable(dev);
-   pm_runtime_get_sync(dev);
-
return 0;
 
 err_resetc_assert:
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


[PATCH 1/2] usb: dwc3: of-simple: Don't fail if no clock entries

2018-05-28 Thread Roger Quadros
of_count_phandle_with_args() returns -ENOENT (-2) if
there are no clock entries. Don't fail in such a case.

Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/dwc3/dwc3-of-simple.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-of-simple.c 
b/drivers/usb/dwc3/dwc3-of-simple.c
index cb2ee96..e98d221 100644
--- a/drivers/usb/dwc3/dwc3-of-simple.c
+++ b/drivers/usb/dwc3/dwc3-of-simple.c
@@ -36,11 +36,11 @@ static int dwc3_of_simple_clk_init(struct dwc3_of_simple 
*simple, int count)
struct device_node  *np = dev->of_node;
int i;
 
-   simple->num_clocks = count;
-
-   if (!count)
+   if (count <= 0)
return 0;
 
+   simple->num_clocks = count;
+
simple->clks = devm_kcalloc(dev, simple->num_clocks,
sizeof(struct clk *), GFP_KERNEL);
if (!simple->clks)
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


Re: [RFC PATCH linux-next] USB: dwc3: dwc3_get_extcon() can be static

2018-05-18 Thread Roger Quadros
On 18/05/18 10:47, Andrzej Hajda wrote:
> On 18.05.2018 09:38, Roger Quadros wrote:
>> On 18/05/18 08:39, Andrzej Hajda wrote:
>>> On 17.05.2018 18:06, kbuild test robot wrote:
>>>> Fixes: 5f0b74e54890 ("USB: dwc3: get extcon device by OF graph bindings")
>>>> Signed-off-by: kbuild test robot <fengguang...@intel.com>
>>> It should be static of course, my bad.
>>>
>>> Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
>> I don't think we accept patches from robots, yet :)
> 
> What do you mean by 'we'? In case of whole kernel it is not true:
> 
> $ git log --author='kbuild test robot <fengguang...@intel.com>'
> --oneline | wc -l
> 183

OK, then I'm wrong. Should have checked before commenting. Sorry about that.

> 
> Regards
> Andrzej
> 
>>
>>>  --
>>> Regards
>>> Andrzej
>>>
>>>> ---
>>>>  drd.c |2 +-
>>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
>>>> index 2706824..218371f 100644
>>>> --- a/drivers/usb/dwc3/drd.c
>>>> +++ b/drivers/usb/dwc3/drd.c
>>>> @@ -440,7 +440,7 @@ static int dwc3_drd_notifier(struct notifier_block *nb,
>>>>return NOTIFY_DONE;
>>>>  }
>>>>  
>>>> -struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
>>>> +static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
>>>>  {
>>>>struct device *dev = dwc->dev;
>>>>struct device_node *np_phy, *np_conn;
>>>>
>>>>
>>>>
>>> --
>>> 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
>>>
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [RFC PATCH linux-next] USB: dwc3: dwc3_get_extcon() can be static

2018-05-18 Thread Roger Quadros
On 18/05/18 08:39, Andrzej Hajda wrote:
> On 17.05.2018 18:06, kbuild test robot wrote:
>> Fixes: 5f0b74e54890 ("USB: dwc3: get extcon device by OF graph bindings")
>> Signed-off-by: kbuild test robot 
> 
> It should be static of course, my bad.
> 
> Reviewed-by: Andrzej Hajda 

I don't think we accept patches from robots, yet :)

> 
>  --
> Regards
> Andrzej
> 
>> ---
>>  drd.c |2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
>> index 2706824..218371f 100644
>> --- a/drivers/usb/dwc3/drd.c
>> +++ b/drivers/usb/dwc3/drd.c
>> @@ -440,7 +440,7 @@ static int dwc3_drd_notifier(struct notifier_block *nb,
>>  return NOTIFY_DONE;
>>  }
>>  
>> -struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
>> +static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
>>  {
>>  struct device *dev = dwc->dev;
>>  struct device_node *np_phy, *np_conn;
>>
>>
>>
> 
> --
> 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
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH v2 2/3] usb: gadget: uvc: remove delay usb status phase

2018-04-25 Thread Roger Quadros
Hi Paul,

On 24/04/18 23:59, Paul Elder wrote:
> The completion of the usb status phase doesn't need to be delayed
> from uvc_function_set_alt to uvc_v4l2_streamon/off.
> Remove USB_GADGET_DELAYED_STATUS and usb_composite_setup_delay from
> these two, respectively.
> 
> Signed-off-by: Paul Elder 
> ---
> Changes in v2:
>   1. Remove delay usb status phase
> 
>  drivers/usb/gadget/function/f_uvc.c| 3 ++-
>  drivers/usb/gadget/function/uvc_v4l2.c | 6 --
>  2 files changed, 2 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/usb/gadget/function/f_uvc.c 
> b/drivers/usb/gadget/function/f_uvc.c
> index 9b63b28a1ee3..fa34dcbe1197 100644
> --- a/drivers/usb/gadget/function/f_uvc.c
> +++ b/drivers/usb/gadget/function/f_uvc.c
> @@ -361,7 +361,8 @@ uvc_function_set_alt(struct usb_function *f, unsigned 
> interface, unsigned alt)
>   memset(_event, 0, sizeof(v4l2_event));
>   v4l2_event.type = UVC_EVENT_STREAMON;
>   v4l2_event_queue(>vdev, _event);
> - return USB_GADGET_DELAYED_STATUS;
> +
> + return 0;
>  
>   default:
>   return -EINVAL;
> diff --git a/drivers/usb/gadget/function/uvc_v4l2.c 
> b/drivers/usb/gadget/function/uvc_v4l2.c
> index fdf02b6987c0..138d95b3b8d1 100644
> --- a/drivers/usb/gadget/function/uvc_v4l2.c
> +++ b/drivers/usb/gadget/function/uvc_v4l2.c
> @@ -206,12 +206,6 @@ uvc_v4l2_streamon(struct file *file, void *fh, enum 
> v4l2_buf_type type)
>  
>   uvc->state = UVC_STATE_STREAMING;
>  
> - /*
> -  * Complete the alternate setting selection setup phase now that
> -  * userspace is ready to provide video frames.
> -  */
> - uvc_function_setup_continue(uvc);
> -

We should also get rid of definition of uvc_function_setup_continue() as nobody 
else uses it.

>   return 0;
>  }
>  
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH 2/4] usb: gadget: composite: add function to increment delayed_status

2018-04-20 Thread Roger Quadros
Hi,

On 19/04/18 22:42, Laurent Pinchart wrote:
> Hi Paul,
> 
> (CC'ing Felipe Balbi and Roger Quadros)
> 
> Thank you for the patch.
> 
> Have you used scripts/get_maintainer.pl ? It should point you to Felipe 
> Balbi, 
> the maintainer of the USB gadget subsystem, who I recommend you CC, at least 
> on patch 2/4. The script also points to Greg, who I don't think needs to be 
> CC'ed as he doesn't deal with USB gadget as much as with USB in general, and 
> who is fairly busy as usual.
> 
> While the get_maintainer script doesn't point to Roger, his name can be found 
> as the author of the USB_GADGET_DELAYED_STATUS mechanism. He authored commit 
> 1b9ba000177e ("usb: gadget: composite: Allow function drivers to pause 
> control 
> transfers") with his nokia.com address back then, but git log --author 'Roger 
> Quadros' shows that he's still active on USB and working for TI now. I've 
> thus 
> CC'ed him on this reply.
> 
> On Wednesday, 18 April 2018 06:18:14 EEST Paul Elder wrote:
>> The completion of the usb status phase from uvc_function_set_alt needs
>> to be delayed until uvc_v4l2_streamon/off. This is currently done by
>> uvc_function_set_alt returning USB_GADGET_DELAYED_STATUS and
>> composite_setup detecting this to increment cdev->delayed_status.
>> However, if uvc_v4l2_streamon/off is called in between this return and
>> increment, uvc_function_setup_continue within uvc_v4l2_streamon/off will
>> WARN that cdev->delayed_status is zero.
> 
> While this is correct, I wouldn't mention UVC here as the patch is for the 
> USB 
> composite gadget framework and isn't specific to UVC. You should write a more 
> generic explanation of the problem to explain why the race between returning 
> USB_GADGET_DELAYED_STATUS (and processing it in the caller) and calling 
> usb_composite_setup_continue() can't be properly solved in gadget drivers, 
> thus requiring a new function.
> 
>> To fix situations like this, add a function to increment
>> cdev->delayed_status.
>>
>> Signed-off-by: Paul Elder <paul.el...@pitt.edu>
>> ---
>>  drivers/usb/gadget/composite.c | 6 ++
>>  include/linux/usb/composite.h  | 2 ++
>>  2 files changed, 8 insertions(+)
>>
>> diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
>> index 77c7ecca816a..c02ab640a7ae 100644
>> --- a/drivers/usb/gadget/composite.c
>> +++ b/drivers/usb/gadget/composite.c
>> @@ -1548,6 +1548,12 @@ static int fill_ext_prop(struct usb_configuration *c,
>> int interface, u8 *buf) return 0;
>>  }
>>
>> +void usb_composite_setup_delay(struct usb_composite_dev *cdev)
>> +{
>> +cdev->delayed_status++;
> 
> According to include/linux/usb/composite.h, the delayed_status field should 
> be 
> protected by cdev->lock, which you should use here.
> 
> I've read through the code and found out that, while all callers of 
> reset_config(), as well as usb_composite_setup_continue(), correctly take the 
> lock, it isn't taken around f->set_alt() in composite_setup(). This causes 
> the 
> race condition. I wonder if a simpler fix wouldn't be to take the lock before 
> calling f->set_alt() and releasing it after incrementing delayed_status. I am 
> however worried that this could lead to deadlocks if one of the existing 
> set_alt() handlers calls a function that takes the same lock. Another worry 
> is that some of the .set_alt() handlers might not expect to be called with 
> interrupts disabled. This should be analyzed, and I hope that Roger and/or 
> Felipe will have some insight on this.

Yes, I too think it is necessary to serialize .set_alt() and 
usb_composite_setup_continue().

> 
> If usb_composite_setup_delay() turns out to be the preferred solution, it 
> would be nice to document the function with kerneldoc.
> 
> Finally, I just came to wonder whether the UVC gadget driver really needs to 
> defer the status phase of the SET_INTERFACE request, or if it couldn't just 
> proceed normally.

Might be worth a try :)

> 
>> +}
>> +EXPORT_SYMBOL(usb_composite_setup_delay);
>> +
>>  /*
>>   * The setup() callback implements all the ep0 functionality that's
>>   * not handled lower down, in hardware or the hardware driver(like
>> diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
>> index cef0e44601f8..049f77a4d42b 100644
>> --- a/include/linux/usb/composite.h
>> +++ b/include/linux/usb/composite.h
>> @@ -524,6 +524,8 @@ extern int composite_setup(struct usb_gadget *gadget,
>>  extern void composite_suspend(struct usb_gadget *gadget);
>>  extern void composite_resume(struct usb_gad

Re: [PATCH usb-next v4 0/2] fix HCD PHY suspend handling

2018-04-05 Thread Roger Quadros
Greg,

On 28/03/18 00:26, Martin Blumenstingl wrote:
> This is a follow-up to my previous series "initialize (multiple) PHYs
> for a HCD": [0].
> 
> Roger Quadros reported [1] that it "is breaking low power cases on TI
> SoCs when USB is in host mode". He further explains that "Not doing the
> phy_exit() here [when entering suspend] leaves the clocks enabled on
> our SoC and we're no longer able to reach low power states on system
> suspend."
> Chunfeng Yun from Mediatek noted [2] that we cannot unconditionally call
> phy_exit while entering system suspend, because this would "disconnect
> plugged devices on MTK platforms, due to re-initialize u2 phys when
> resume"
> 
> In the discussion (which followed Roger's bug report: [1]) Roger,
> Chunfeng and me came to the conclusion that we can fix suspend on the
> TI SoCs without breaking it on the Mediatek SoCs by extending the
> suspend and resume code in usb/core/phy.c by checking whether the USB
> controller can wake up the system (which is the case for the Mediatek
> MTU3 controller, but now for the dwc3 controller used on the TI SoCs):
> - if the controller can wake up the system (Mediatek MTU3 use-case) we
>   only call usb_phy_roothub_power_off (which calls phy_power_off) when
>   entering system suspend
> - if the controller however cannot wake up the system (dwc3 on TI SoCs)
>   we additionally call usb_phy_roothub_exit (which calls phy_exit) when
>   entering system suspend
> - (we undo the previous steps during system resume)
> 
> The goal of this series is to fix the issue reported by Roger without
> breaking suspend/resume on the Mediatek SoCs.
> Since I neither have a TI nor a Mediatek device I am sending this as
> RFC. I have tested it on an Amlogic Meson GXM board (Khadas VIM2) which
> does NOT support suspend/resume yet.
> 
> this should be applied on top of [3] "usb: core: phy: fix return value
> of usb_phy_roothub_exit()" (even though there's no strict dependency,
> this is the order I wrote the patches in).
> 
> changes since RFC v3 at [6]:
> - added Chunfeng Yun's Tested-by and Roger Quadros' Reviewed-by (thank
>   you!)
> - dropped RFC prefix
> 
> changes since RFC v2 at [5]:
> - add missing INIT_LIST_HEAD call in usb_phy_roothub_add_phy (affects
>   patch #1 - spotted by Roger Quadros, thank you!)
> - fixed swapped conditions using device_may_wakeup() in
>   usb_phy_roothub_resume because we need to call usb_phy_roothub_init
>   if the controller cannot wake up the device (affects patch #2, spotted
>   by Chunfeng Yun, thank you!)
> - simplified the error condition to "undo" usb_phy_roothub_init if
>   usb_phy_roothub_power_on failed in usb_phy_roothub_resume (suggested
>   by Chunfeng Yun)
> - updated the commit message (using Roger's wording) because (quote from
>   Roger "it doesn't prevent the system from entering suspend but just
>   prevents the system from reaching lowest power levels in the suspend
>   state."
> 
> Changes since RFC v1 (blob attachments) at [4]:
> - use device_may_wakeup instead of device_can_wakeup as suggested by
>   Roger Quadros
> - use the controller device from hcd->self.controller as suggested by
>   Chunfeng Yun
> - compile time fixes thanks to Roger Quadros
> - if usb_phy_roothub_power_on in usb_phy_roothub_resume failes then
>   we now call usb_phy_roothub_exit to keep the PHYs in the correct
>   state if usb_phy_roothub_resume partially failed
> 
> 
> [0] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006599.html
> [1] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006737.html
> [2] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006758.html
> [3] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006819.html
> [4] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006794.html
> [5] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006820.html
> [6] http://lists.infradead.org/pipermail/linux-amlogic/2018-March/006847.html
> 
> Martin Blumenstingl (2):
>   usb: core: split usb_phy_roothub_{init,alloc}
>   usb: core: use phy_exit during suspend if wake up is not supported

Gentle ping on this one. Without this system suspend/resume is broken on TI 
platforms.

> 
>  drivers/usb/core/hcd.c | 18 +++
>  drivers/usb/core/phy.c | 88 
> +++---
>  drivers/usb/core/phy.h |  9 +-
>  3 files changed, 82 insertions(+), 33 deletions(-)
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [RFC usb-next v3 1/2] usb: core: split usb_phy_roothub_{init,alloc}

2018-03-27 Thread Roger Quadros
On 26/03/18 23:38, Martin Blumenstingl wrote:
> Before this patch usb_phy_roothub_init served two purposes (from a
> caller's point of view - like hcd.c):
> - parsing the PHYs and allocating the list entries
> - calling phy_init on each list entry
> 
> While this worked so far it has one disadvantage: if we need to call
> phy_init for each PHY instance then the existing code cannot be re-used.
> Solve this by splitting off usb_phy_roothub_alloc which only parses the
> PHYs and allocates the list entries.
> usb_phy_roothub_init then gets a struct usb_phy_roothub and only calls
> phy_init on each PHY instance (along with the corresponding cleanup if
> that failed somewhere).
> 
> This is a preparation step for adding proper suspend support for some
> hardware that requires phy_exit to be called during suspend and phy_init
> to be called during resume.
> 
> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>

I don't think we need RFC in subject.

Reviewed-by: Roger Quadros <rog...@ti.com>

> ---
>  drivers/usb/core/hcd.c | 10 +++---
>  drivers/usb/core/phy.c | 53 
> +-
>  drivers/usb/core/phy.h |  4 +++-
>  3 files changed, 37 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
> index 777036ae6367..15b0418e3b6a 100644
> --- a/drivers/usb/core/hcd.c
> +++ b/drivers/usb/core/hcd.c
> @@ -2758,12 +2758,16 @@ int usb_add_hcd(struct usb_hcd *hcd,
>   }
>  
>   if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) {
> - hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev);
> + hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev);
>   if (IS_ERR(hcd->phy_roothub)) {
>   retval = PTR_ERR(hcd->phy_roothub);
> - goto err_phy_roothub_init;
> + goto err_phy_roothub_alloc;
>   }
>  
> + retval = usb_phy_roothub_init(hcd->phy_roothub);
> + if (retval)
> + goto err_phy_roothub_alloc;
> +
>   retval = usb_phy_roothub_power_on(hcd->phy_roothub);
>   if (retval)
>   goto err_usb_phy_roothub_power_on;
> @@ -2936,7 +2940,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
>   usb_phy_roothub_power_off(hcd->phy_roothub);
>  err_usb_phy_roothub_power_on:
>   usb_phy_roothub_exit(hcd->phy_roothub);
> -err_phy_roothub_init:
> +err_phy_roothub_alloc:
>   if (hcd->remove_phy && hcd->usb_phy) {
>   usb_phy_shutdown(hcd->usb_phy);
>   usb_put_phy(hcd->usb_phy);
> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c
> index f19aaa3c899c..44f008cda7a8 100644
> --- a/drivers/usb/core/phy.c
> +++ b/drivers/usb/core/phy.c
> @@ -19,19 +19,6 @@ struct usb_phy_roothub {
>   struct list_headlist;
>  };
>  
> -static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev)
> -{
> - struct usb_phy_roothub *roothub_entry;
> -
> - roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL);
> - if (!roothub_entry)
> - return ERR_PTR(-ENOMEM);
> -
> - INIT_LIST_HEAD(_entry->list);
> -
> - return roothub_entry;
> -}
> -
>  static int usb_phy_roothub_add_phy(struct device *dev, int index,
>  struct list_head *list)
>  {
> @@ -45,9 +32,11 @@ static int usb_phy_roothub_add_phy(struct device *dev, int 
> index,
>   return PTR_ERR(phy);
>   }
>  
> - roothub_entry = usb_phy_roothub_alloc(dev);
> - if (IS_ERR(roothub_entry))
> - return PTR_ERR(roothub_entry);
> + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL);
> + if (!roothub_entry)
> + return -ENOMEM;
> +
> + INIT_LIST_HEAD(_entry->list);
>  
>   roothub_entry->phy = phy;
>  
> @@ -56,11 +45,9 @@ static int usb_phy_roothub_add_phy(struct device *dev, int 
> index,
>   return 0;
>  }
>  
> -struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev)
> +struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev)
>  {
>   struct usb_phy_roothub *phy_roothub;
> - struct usb_phy_roothub *roothub_entry;
> - struct list_head *head;
>   int i, num_phys, err;
>  
>   num_phys = of_count_phandle_with_args(dev->of_node, "phys",
> @@ -68,16 +55,31 @@ struct usb_phy_roothub *usb_phy_roothub_init(struct 
> device *dev)
>   if (num_phys <= 0)
>   return NULL;
> 

Re: [RFC usb-next v3 2/2] usb: core: use phy_exit during suspend if wake up is not supported

2018-03-27 Thread Roger Quadros
On 26/03/18 23:38, Martin Blumenstingl wrote:
> If the USB controller can wake up the system (which is the case for
> example with the Mediatek USB3 IP) then we must not call phy_exit during
> suspend to ensure that the USB controller doesn't have to re-enumerate
> the devices during resume.
> However, if the USB controller cannot wake up the system (which is the
> case for example on various TI platforms using a dwc3 controller) then
> we must call phy_exit during suspend. Otherwise the PHY driver keeps the
> clocks enabled, which prevents the system from reaching the lowest power
> levels in the suspend state.
> 
> Solve this by introducing two new functions in the PHY wrapper which are
> dedicated to the suspend and resume handling.
> If the controller can wake up the system the new usb_phy_roothub_suspend
> function will simply call usb_phy_roothub_power_off. However, if wake up
> is not supported by the controller it will also call
> usb_phy_roothub_exit.
> The also new usb_phy_roothub_resume function takes care of calling
> usb_phy_roothub_init (if the controller can't wake up the system) in
> addition to usb_phy_roothub_power_on.
> 
> Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD")
> Fixes: 178a0bce05cbc1 ("usb: core: hcd: integrate the PHY wrapper into the 
> HCD core")
> Reported-by: Roger Quadros <rog...@ti.com>
> Suggested-by: Roger Quadros <rog...@ti.com>
> Suggested-by: Chunfeng Yun <chunfeng@mediatek.com>
> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>

Reviewed-by: Roger Quadros <rog...@ti.com>

> ---
>  drivers/usb/core/hcd.c |  8 +---
>  drivers/usb/core/phy.c | 35 +++
>  drivers/usb/core/phy.h |  5 +
>  3 files changed, 45 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
> index 15b0418e3b6a..78bae4ecd68b 100644
> --- a/drivers/usb/core/hcd.c
> +++ b/drivers/usb/core/hcd.c
> @@ -2262,7 +2262,8 @@ int hcd_bus_suspend(struct usb_device *rhdev, 
> pm_message_t msg)
>   hcd->state = HC_STATE_SUSPENDED;
>  
>   if (!PMSG_IS_AUTO(msg))
> - usb_phy_roothub_power_off(hcd->phy_roothub);
> + usb_phy_roothub_suspend(hcd->self.sysdev,
> + hcd->phy_roothub);
>  
>   /* Did we race with a root-hub wakeup event? */
>   if (rhdev->do_remote_wakeup) {
> @@ -2302,7 +2303,8 @@ int hcd_bus_resume(struct usb_device *rhdev, 
> pm_message_t msg)
>   }
>  
>   if (!PMSG_IS_AUTO(msg)) {
> - status = usb_phy_roothub_power_on(hcd->phy_roothub);
> + status = usb_phy_roothub_resume(hcd->self.sysdev,
> + hcd->phy_roothub);
>   if (status)
>   return status;
>   }
> @@ -2344,7 +2346,7 @@ int hcd_bus_resume(struct usb_device *rhdev, 
> pm_message_t msg)
>   }
>   } else {
>   hcd->state = old_state;
> - usb_phy_roothub_power_off(hcd->phy_roothub);
> + usb_phy_roothub_suspend(hcd->self.sysdev, hcd->phy_roothub);
>   dev_dbg(>dev, "bus %s fail, err %d\n",
>   "resume", status);
>   if (status != -ESHUTDOWN)
> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c
> index 44f008cda7a8..a39d9bb26a4f 100644
> --- a/drivers/usb/core/phy.c
> +++ b/drivers/usb/core/phy.c
> @@ -157,3 +157,38 @@ void usb_phy_roothub_power_off(struct usb_phy_roothub 
> *phy_roothub)
>   phy_power_off(roothub_entry->phy);
>  }
>  EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off);
> +
> +int usb_phy_roothub_suspend(struct device *controller_dev,
> + struct usb_phy_roothub *phy_roothub)
> +{
> + usb_phy_roothub_power_off(phy_roothub);
> +
> + /* keep the PHYs initialized so the device can wake up the system */
> + if (device_may_wakeup(controller_dev))
> + return 0;
> +
> + return usb_phy_roothub_exit(phy_roothub);
> +}
> +EXPORT_SYMBOL_GPL(usb_phy_roothub_suspend);
> +
> +int usb_phy_roothub_resume(struct device *controller_dev,
> +struct usb_phy_roothub *phy_roothub)
> +{
> + int err;
> +
> + /* if the device can't wake up the system _exit was called */
> + if (!device_may_wakeup(controller_dev)) {
> + err = usb_phy_roothub_init(phy_roothub);
> + if (err)
> + return err;
> + }
> +
> + err

Re: [RFC usb-next v2 1/2] usb: core: split usb_phy_roothub_{init,alloc}

2018-03-26 Thread Roger Quadros
On 24/03/18 16:21, Martin Blumenstingl wrote:
> Before this patch usb_phy_roothub_init served two purposes (from a
> caller's point of view - like hcd.c):
> - parsing the PHYs and allocating the list entries
> - calling phy_init on each list entry
> 
> While this worked so far it has one disadvantage: if we need to call
> phy_init for each PHY instance then the existing code cannot be re-used.
> Solve this by splitting off usb_phy_roothub_alloc which only parses the
> PHYs and allocates the list entries.
> usb_phy_roothub_init then gets a struct usb_phy_roothub and only calls
> phy_init on each PHY instance (along with the corresponding cleanup if
> that failed somewhere).
> 
> This is a preparation step for adding proper suspend support for some
> hardware that requires phy_exit to be called during suspend and phy_init
> to be called during resume.
> 
> Signed-off-by: Martin Blumenstingl 
> ---
>  drivers/usb/core/hcd.c | 10 +++---
>  drivers/usb/core/phy.c | 51 
> +-
>  drivers/usb/core/phy.h |  4 +++-
>  3 files changed, 35 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
> index 777036ae6367..15b0418e3b6a 100644
> --- a/drivers/usb/core/hcd.c
> +++ b/drivers/usb/core/hcd.c
> @@ -2758,12 +2758,16 @@ int usb_add_hcd(struct usb_hcd *hcd,
>   }
>  
>   if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) {
> - hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev);
> + hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev);
>   if (IS_ERR(hcd->phy_roothub)) {
>   retval = PTR_ERR(hcd->phy_roothub);
> - goto err_phy_roothub_init;
> + goto err_phy_roothub_alloc;
>   }
>  
> + retval = usb_phy_roothub_init(hcd->phy_roothub);
> + if (retval)
> + goto err_phy_roothub_alloc;
> +
>   retval = usb_phy_roothub_power_on(hcd->phy_roothub);
>   if (retval)
>   goto err_usb_phy_roothub_power_on;
> @@ -2936,7 +2940,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
>   usb_phy_roothub_power_off(hcd->phy_roothub);
>  err_usb_phy_roothub_power_on:
>   usb_phy_roothub_exit(hcd->phy_roothub);
> -err_phy_roothub_init:
> +err_phy_roothub_alloc:
>   if (hcd->remove_phy && hcd->usb_phy) {
>   usb_phy_shutdown(hcd->usb_phy);
>   usb_put_phy(hcd->usb_phy);
> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c
> index f19aaa3c899c..d1861c5a74de 100644
> --- a/drivers/usb/core/phy.c
> +++ b/drivers/usb/core/phy.c
> @@ -19,19 +19,6 @@ struct usb_phy_roothub {
>   struct list_headlist;
>  };
>  
> -static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev)
> -{
> - struct usb_phy_roothub *roothub_entry;
> -
> - roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL);
> - if (!roothub_entry)
> - return ERR_PTR(-ENOMEM);
> -
> - INIT_LIST_HEAD(_entry->list);
> -
> - return roothub_entry;
> -}
> -
>  static int usb_phy_roothub_add_phy(struct device *dev, int index,
>  struct list_head *list)
>  {
> @@ -45,9 +32,9 @@ static int usb_phy_roothub_add_phy(struct device *dev, int 
> index,
>   return PTR_ERR(phy);
>   }
>  
> - roothub_entry = usb_phy_roothub_alloc(dev);
> - if (IS_ERR(roothub_entry))
> - return PTR_ERR(roothub_entry);
> + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL);
> + if (!roothub_entry)
> + return -ENOMEM;
>  

We missed doing a
INIT_LIST_HEAD(_entry->list);

>   roothub_entry->phy = phy;
>  
> @@ -56,11 +43,9 @@ static int usb_phy_roothub_add_phy(struct device *dev, int 
> index,
>   return 0;
>  }
>  
> -struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev)
> +struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev)
>  {
>   struct usb_phy_roothub *phy_roothub;
> - struct usb_phy_roothub *roothub_entry;
> - struct list_head *head;
>   int i, num_phys, err;
>  
>   num_phys = of_count_phandle_with_args(dev->of_node, "phys",
> @@ -68,16 +53,31 @@ struct usb_phy_roothub *usb_phy_roothub_init(struct 
> device *dev)
>   if (num_phys <= 0)
>   return NULL;
>  
> - phy_roothub = usb_phy_roothub_alloc(dev);
> - if (IS_ERR(phy_roothub))
> - return phy_roothub;
> + phy_roothub = devm_kzalloc(dev, sizeof(*phy_roothub), GFP_KERNEL);
> + if (!phy_roothub)
> + return ERR_PTR(-ENOMEM);
> +
> + INIT_LIST_HEAD(_roothub->list);
>  
>   for (i = 0; i < num_phys; i++) {
>   err = usb_phy_roothub_add_phy(dev, i, _roothub->list);
>   if (err)
> - goto err_out;
> + return 

Re: [RFC usb-next v2 2/2] usb: core: use phy_exit during suspend if wake up is not supported

2018-03-26 Thread Roger Quadros
Hi,

On 24/03/18 16:21, Martin Blumenstingl wrote:
> If the USB controller can wake up the system (which is the case for
> example with the Mediatek USB3 IP) then we must not call phy_exit during
> suspend to ensure that the USB controller doesn't have to re-enumerate
> the devices during resume.
> However, if the USB controller cannot wake up the system (which is the
> case for example on various TI platforms using a dwc3 controller) then
> we must call phy_exit during suspend. Otherwise the PHY driver keeps the
> clocks enabled, which prevents the system from entering the suspend
> state.

Actually it doesn't prevent the system from entering suspend but just prevents
the system from reaching lowest power levels in the suspend state.

> 
> Solve this by introducing two new functions in the PHY wrapper which are
> dedicated to the suspend and resume handling.
> If the controller can wake up the system the new usb_phy_roothub_suspend
> function will simply call usb_phy_roothub_power_off. However, if wake up
> is not supported by the controller it will also call
> usb_phy_roothub_exit.
> The also new usb_phy_roothub_resume function takes care of calling
> usb_phy_roothub_init (if the controller can't wake up the system) in
> addition to usb_phy_roothub_power_on.
> 
> Fixes: 07dbff0ddbd86c ("usb: core: add a wrapper for the USB PHYs on the HCD")
> Fixes: 178a0bce05cbc1 ("usb: core: hcd: integrate the PHY wrapper into the 
> HCD core")
> Reported-by: Roger Quadros <rog...@ti.com>
> Suggested-by: Roger Quadros <rog...@ti.com>
> Suggested-by: Chunfeng Yun <chunfeng@mediatek.com>
> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
> ---
>  drivers/usb/core/hcd.c |  8 +---
>  drivers/usb/core/phy.c | 37 +
>  drivers/usb/core/phy.h |  5 +
>  3 files changed, 47 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
> index 15b0418e3b6a..78bae4ecd68b 100644
> --- a/drivers/usb/core/hcd.c
> +++ b/drivers/usb/core/hcd.c
> @@ -2262,7 +2262,8 @@ int hcd_bus_suspend(struct usb_device *rhdev, 
> pm_message_t msg)
>   hcd->state = HC_STATE_SUSPENDED;
>  
>   if (!PMSG_IS_AUTO(msg))
> - usb_phy_roothub_power_off(hcd->phy_roothub);
> + usb_phy_roothub_suspend(hcd->self.sysdev,
> + hcd->phy_roothub);
>  
>   /* Did we race with a root-hub wakeup event? */
>   if (rhdev->do_remote_wakeup) {
> @@ -2302,7 +2303,8 @@ int hcd_bus_resume(struct usb_device *rhdev, 
> pm_message_t msg)
>   }
>  
>   if (!PMSG_IS_AUTO(msg)) {
> - status = usb_phy_roothub_power_on(hcd->phy_roothub);
> + status = usb_phy_roothub_resume(hcd->self.sysdev,
> + hcd->phy_roothub);
>   if (status)
>   return status;
>   }
> @@ -2344,7 +2346,7 @@ int hcd_bus_resume(struct usb_device *rhdev, 
> pm_message_t msg)
>   }
>   } else {
>   hcd->state = old_state;
> - usb_phy_roothub_power_off(hcd->phy_roothub);
> + usb_phy_roothub_suspend(hcd->self.sysdev, hcd->phy_roothub);
>   dev_dbg(>dev, "bus %s fail, err %d\n",
>   "resume", status);
>   if (status != -ESHUTDOWN)
> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c
> index d1861c5a74de..e794cbee97e9 100644
> --- a/drivers/usb/core/phy.c
> +++ b/drivers/usb/core/phy.c
> @@ -155,3 +155,40 @@ void usb_phy_roothub_power_off(struct usb_phy_roothub 
> *phy_roothub)
>   phy_power_off(roothub_entry->phy);
>  }
>  EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off);
> +
> +int usb_phy_roothub_suspend(struct device *controller_dev,
> + struct usb_phy_roothub *phy_roothub)
> +{
> + usb_phy_roothub_power_off(phy_roothub);
> +
> + /* keep the PHYs initialized so the device can wake up the system */
> + if (device_may_wakeup(controller_dev))
> + return 0;
> +
> + return usb_phy_roothub_exit(phy_roothub);
> +}
> +EXPORT_SYMBOL_GPL(usb_phy_roothub_suspend);
> +
> +int usb_phy_roothub_resume(struct device *controller_dev,
> +struct usb_phy_roothub *phy_roothub)
> +{
> + int err;
> +
> + /* if the device can't wake up the system _exit was called */
> + if (device_may_wakeup(controller_dev)) {
> + err = usb_phy_roothub_init(phy_roothub);
> + if (err

Re: [PATCH usb-next v10 3/8] usb: core: add a wrapper for the USB PHYs on the HCD

2018-03-22 Thread Roger Quadros
On 22/03/18 10:10, Chunfeng Yun wrote:
> Hi,
> On Wed, 2018-03-21 at 13:30 +0200, Roger Quadros wrote:
>> Martin,
>>
>> On 21/03/18 00:01, Martin Blumenstingl wrote:
>>> Hi Roger, Hi Chunfeng,
>>>
>>> On Tue, Mar 20, 2018 at 1:04 PM, Chunfeng Yun <chunfeng@mediatek.com> 
>>> wrote:
>>>> Hi Martin & Roger:
>>>>
>>>> On Mon, 2018-03-19 at 17:12 +0100, Martin Blumenstingl wrote:
>>>>> Hi Roger,
>>>>>
>>>>> On Mon, Mar 19, 2018 at 9:49 AM, Roger Quadros <rog...@ti.com> wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On 19/03/18 00:29, Martin Blumenstingl wrote:
>>>>>>> Hi Roger,
>>>>>>>
>>>>>>> On Fri, Mar 16, 2018 at 3:32 PM, Roger Quadros <rog...@ti.com> wrote:
>>>>>>>> +some TI folks
>>>>>>>>
>>>>>>>> Hi Martin,
>>>>>>>>
>>>>>>>> On 18/02/18 20:44, Martin Blumenstingl wrote:
>>>>>>>>> Many SoC platforms have separate devices for the USB PHY which are
>>>>>>>>> registered through the generic PHY framework. These PHYs have to be
>>>>>>>>> enabled to make the USB controller actually work. They also have to be
>>>>>>>>> disabled again on shutdown/suspend.
>>>>>>>>>
>>>>>>>>> Currently (at least) the following HCI platform drivers are using 
>>>>>>>>> custom
>>>>>>>>> code to obtain all PHYs via devicetree for the roothub/controller and
>>>>>>>>> disable/enable them when required:
>>>>>>>>> - ehci-platform.c has ehci_platform_power_{on,off}
>>>>>>>>> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off}
>>>>>>>>> - ohci-platform.c has ohci_platform_power_{on,off}
>>>>>>>>>
>>>>>>>>> With this new wrapper the USB PHYs can be specified directly in the
>>>>>>>>> USB controller's devicetree node (just like on the drivers listed
>>>>>>>>> above). This allows SoCs like the Amlogic Meson GXL family to operate
>>>>>>>>> correctly once this is wired up correctly. These SoCs use a dwc3
>>>>>>>>> controller and require all USB PHYs to be initialized (if one of the 
>>>>>>>>> USB
>>>>>>>>> PHYs it not initialized then none of USB port works at all).
>>>>>>>>>
>>>>>>>>> Signed-off-by: Martin Blumenstingl 
>>>>>>>>> <martin.blumensti...@googlemail.com>
>>>>>>>>> Tested-by: Yixun Lan <yixun@amlogic.com>
>>>>>>>>> Cc: Neil Armstrong <narmstr...@baylibre.com>
>>>>>>>>> Cc: Chunfeng Yun <chunfeng@mediatek.com>
>>>>>>>>
>>>>>>>> This patch is breaking low power cases on TI SoCs when USB is in host 
>>>>>>>> mode.
>>>>>>>> I'll explain why below.
>>>>>>> based on your explanation and reading the TI PHY drivers I am assuming
>>>>>>> that the affected SoCs are using the "phy-omap-usb2" driver
>>>>>>>
>>>>>> yes and phy-ti-pipe3 as well i.e. "ti,phy-usb3" and "ti,omap-usb3"
>>>>> I missed that, thanks
>>>>>
>>>>>>>>> ---
>>>>>>>>>  drivers/usb/core/Makefile |   2 +-
>>>>>>>>>  drivers/usb/core/phy.c| 158 
>>>>>>>>> ++
>>>>>>>>>  drivers/usb/core/phy.h|   7 ++
>>>>>>>>>  3 files changed, 166 insertions(+), 1 deletion(-)
>>>>>>>>>  create mode 100644 drivers/usb/core/phy.c
>>>>>>>>>  create mode 100644 drivers/usb/core/phy.h
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
>>>>>>>>> index 92c9cefb4317..18e874b0441e 100644
>>>>>>>>> --- a/drivers/usb/core/Makefile
>>>>>>>>> +++ b/drivers/usb/core/Makefile
>>>>>>>>> @@ -6,7 +6,7

Re: [usb-next, v3 PATCH] usb: xhci: skip phys initialization of shared hcd

2018-03-22 Thread Roger Quadros
On 22/03/18 14:12, Chunfeng Yun wrote:
> The phys has already been initialized when add primary hcd,
> including usb2 phys and usb3 phys also if exist, so needn't
> re-parse "phys" property again.
> 
> Signed-off-by: Chunfeng Yun <chunfeng@mediatek.com>

Reviewed-by: Roger Quadros <rog...@ti.com>

> ---
> V3:
> add the following info about v1 & v2 suggested by Greg
> V2:
> fix it in hcd.c suggested by Roger
> V1:
> skip phys initialization when add shared HCD by setting
> xhci->shared_hcd->skip_phy_initialization=1;
> for both xhci-plat.c & xhci-mtk.c files.
> ---
>  drivers/usb/core/hcd.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
> index 5a92d8f..777036a 100644
> --- a/drivers/usb/core/hcd.c
> +++ b/drivers/usb/core/hcd.c
> @@ -2757,7 +2757,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
>   }
>   }
>  
> - if (!hcd->skip_phy_initialization) {
> + if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) {
>   hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev);
>   if (IS_ERR(hcd->phy_roothub)) {
>   retval = PTR_ERR(hcd->phy_roothub);
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [usb-next PATCH] usb: xhci: skip phys initialization of shared hcd

2018-03-21 Thread Roger Quadros
On 21/03/18 13:50, Chunfeng Yun wrote:
> Hi Roger,
> 
> On Wed, 2018-03-21 at 11:05 +0200, Roger Quadros wrote:
>> Hi Chunfeng,
>>
>> On 21/03/18 08:12, Chunfeng Yun wrote:
>>> The phys has already been initialized when add primary hcd,
>>> including usb2 phys and usb3 phys also if exist, so needn't
>>> re-parse "phys" property again.
>>>
>>> Signed-off-by: Chunfeng Yun <chunfeng@mediatek.com>
>>> ---
>>>  drivers/usb/host/xhci-mtk.c  | 1 +
>>>  drivers/usb/host/xhci-plat.c | 1 +
>>>  2 files changed, 2 insertions(+)
>>>
>>> diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
>>> index 7334da9..6bb23fb 100644
>>> --- a/drivers/usb/host/xhci-mtk.c
>>> +++ b/drivers/usb/host/xhci-mtk.c
>>> @@ -554,6 +554,7 @@ static int xhci_mtk_probe(struct platform_device *pdev)
>>> if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
>>> xhci->shared_hcd->can_do_streams = 1;
>>>  
>>> +   xhci->shared_hcd->skip_phy_initialization = 1;
>>> ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
>>> if (ret)
>>> goto dealloc_usb2_hcd;
>>> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
>>> index 6700e5e..65a4294 100644
>>> --- a/drivers/usb/host/xhci-plat.c
>>> +++ b/drivers/usb/host/xhci-plat.c
>>> @@ -294,6 +294,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
>>> if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
>>> xhci->shared_hcd->can_do_streams = 1;
>>>  
>>> +   xhci->shared_hcd->skip_phy_initialization = 1;
>>
>> I think this is unnecessary.
>> There aren't separate PHYs for the primary and shared HCDs right?
> Yes, the primary and shared HCDs will get the same PHYs provided by
> "phys" property.
> 
>>
>> Also how can you be sure that phy_init() has been done for all platform HCD 
>> users?
> Here I assume that "phys" and "usb-phy" properties are not used at the
> same time. There are two cases:
> 1. Using "usb-phy": no "phys" to be got by shared HCD.
> 2. Using "phys": the primary HCD will get those phys, so shared HCD can
> skip them.

Now I see the problem.
But the right fix should be in core/hcd.c

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 2884607..1d1da12 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2757,7 +2757,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
}
}
 
-   if (!hcd->skip_phy_initialization) {
+   if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) {
hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev);
if (IS_ERR(hcd->phy_roothub)) {
retval = PTR_ERR(hcd->phy_roothub);

> 
>>
>>> ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
>>> if (ret)
>>> goto dealloc_usb2_hcd;
>>>
>>
> 
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH usb-next v10 3/8] usb: core: add a wrapper for the USB PHYs on the HCD

2018-03-21 Thread Roger Quadros
Martin,

On 21/03/18 00:01, Martin Blumenstingl wrote:
> Hi Roger, Hi Chunfeng,
> 
> On Tue, Mar 20, 2018 at 1:04 PM, Chunfeng Yun <chunfeng@mediatek.com> 
> wrote:
>> Hi Martin & Roger:
>>
>> On Mon, 2018-03-19 at 17:12 +0100, Martin Blumenstingl wrote:
>>> Hi Roger,
>>>
>>> On Mon, Mar 19, 2018 at 9:49 AM, Roger Quadros <rog...@ti.com> wrote:
>>>> Hi,
>>>>
>>>> On 19/03/18 00:29, Martin Blumenstingl wrote:
>>>>> Hi Roger,
>>>>>
>>>>> On Fri, Mar 16, 2018 at 3:32 PM, Roger Quadros <rog...@ti.com> wrote:
>>>>>> +some TI folks
>>>>>>
>>>>>> Hi Martin,
>>>>>>
>>>>>> On 18/02/18 20:44, Martin Blumenstingl wrote:
>>>>>>> Many SoC platforms have separate devices for the USB PHY which are
>>>>>>> registered through the generic PHY framework. These PHYs have to be
>>>>>>> enabled to make the USB controller actually work. They also have to be
>>>>>>> disabled again on shutdown/suspend.
>>>>>>>
>>>>>>> Currently (at least) the following HCI platform drivers are using custom
>>>>>>> code to obtain all PHYs via devicetree for the roothub/controller and
>>>>>>> disable/enable them when required:
>>>>>>> - ehci-platform.c has ehci_platform_power_{on,off}
>>>>>>> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off}
>>>>>>> - ohci-platform.c has ohci_platform_power_{on,off}
>>>>>>>
>>>>>>> With this new wrapper the USB PHYs can be specified directly in the
>>>>>>> USB controller's devicetree node (just like on the drivers listed
>>>>>>> above). This allows SoCs like the Amlogic Meson GXL family to operate
>>>>>>> correctly once this is wired up correctly. These SoCs use a dwc3
>>>>>>> controller and require all USB PHYs to be initialized (if one of the USB
>>>>>>> PHYs it not initialized then none of USB port works at all).
>>>>>>>
>>>>>>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>>>>>>> Tested-by: Yixun Lan <yixun@amlogic.com>
>>>>>>> Cc: Neil Armstrong <narmstr...@baylibre.com>
>>>>>>> Cc: Chunfeng Yun <chunfeng@mediatek.com>
>>>>>>
>>>>>> This patch is breaking low power cases on TI SoCs when USB is in host 
>>>>>> mode.
>>>>>> I'll explain why below.
>>>>> based on your explanation and reading the TI PHY drivers I am assuming
>>>>> that the affected SoCs are using the "phy-omap-usb2" driver
>>>>>
>>>> yes and phy-ti-pipe3 as well i.e. "ti,phy-usb3" and "ti,omap-usb3"
>>> I missed that, thanks
>>>
>>>>>>> ---
>>>>>>>  drivers/usb/core/Makefile |   2 +-
>>>>>>>  drivers/usb/core/phy.c| 158 
>>>>>>> ++
>>>>>>>  drivers/usb/core/phy.h|   7 ++
>>>>>>>  3 files changed, 166 insertions(+), 1 deletion(-)
>>>>>>>  create mode 100644 drivers/usb/core/phy.c
>>>>>>>  create mode 100644 drivers/usb/core/phy.h
>>>>>>>
>>>>>>> diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
>>>>>>> index 92c9cefb4317..18e874b0441e 100644
>>>>>>> --- a/drivers/usb/core/Makefile
>>>>>>> +++ b/drivers/usb/core/Makefile
>>>>>>> @@ -6,7 +6,7 @@
>>>>>>>  usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o
>>>>>>>  usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o
>>>>>>>  usbcore-y += devio.o notify.o generic.o quirks.o devices.o
>>>>>>> -usbcore-y += port.o
>>>>>>> +usbcore-y += phy.o port.o
>>>>>>>
>>>>>>>  usbcore-$(CONFIG_OF) += of.o
>>>>>>>  usbcore-$(CONFIG_USB_PCI)+= hcd-pci.o
>>>>>>> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c
>>>>>>> new file mode 100644
>>>>>>> index ..09b7c43c0ea4
>>>>>>> --- /dev/null
>>&g

Re: [usb-next PATCH] usb: xhci: skip phys initialization of shared hcd

2018-03-21 Thread Roger Quadros
Hi Chunfeng,

On 21/03/18 08:12, Chunfeng Yun wrote:
> The phys has already been initialized when add primary hcd,
> including usb2 phys and usb3 phys also if exist, so needn't
> re-parse "phys" property again.
> 
> Signed-off-by: Chunfeng Yun 
> ---
>  drivers/usb/host/xhci-mtk.c  | 1 +
>  drivers/usb/host/xhci-plat.c | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
> index 7334da9..6bb23fb 100644
> --- a/drivers/usb/host/xhci-mtk.c
> +++ b/drivers/usb/host/xhci-mtk.c
> @@ -554,6 +554,7 @@ static int xhci_mtk_probe(struct platform_device *pdev)
>   if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
>   xhci->shared_hcd->can_do_streams = 1;
>  
> + xhci->shared_hcd->skip_phy_initialization = 1;
>   ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
>   if (ret)
>   goto dealloc_usb2_hcd;
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index 6700e5e..65a4294 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -294,6 +294,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
>   if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
>   xhci->shared_hcd->can_do_streams = 1;
>  
> + xhci->shared_hcd->skip_phy_initialization = 1;

I think this is unnecessary.
There aren't separate PHYs for the primary and shared HCDs right?

Also how can you be sure that phy_init() has been done for all platform HCD 
users?

>   ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
>   if (ret)
>   goto dealloc_usb2_hcd;
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH usb-next v10 3/8] usb: core: add a wrapper for the USB PHYs on the HCD

2018-03-20 Thread Roger Quadros
On 20/03/18 12:55, Roger Quadros wrote:
> On 19/03/18 18:12, Martin Blumenstingl wrote:
>> Hi Roger,
>>
>> On Mon, Mar 19, 2018 at 9:49 AM, Roger Quadros <rog...@ti.com> wrote:
>>> Hi,
>>>
>>> On 19/03/18 00:29, Martin Blumenstingl wrote:
>>>> Hi Roger,
>>>>
>>>> On Fri, Mar 16, 2018 at 3:32 PM, Roger Quadros <rog...@ti.com> wrote:
>>>>> +some TI folks
>>>>>
>>>>> Hi Martin,
>>>>>
>>>>> On 18/02/18 20:44, Martin Blumenstingl wrote:
>>>>>> Many SoC platforms have separate devices for the USB PHY which are
>>>>>> registered through the generic PHY framework. These PHYs have to be
>>>>>> enabled to make the USB controller actually work. They also have to be
>>>>>> disabled again on shutdown/suspend.
>>>>>>
>>>>>> Currently (at least) the following HCI platform drivers are using custom
>>>>>> code to obtain all PHYs via devicetree for the roothub/controller and
>>>>>> disable/enable them when required:
>>>>>> - ehci-platform.c has ehci_platform_power_{on,off}
>>>>>> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off}
>>>>>> - ohci-platform.c has ohci_platform_power_{on,off}
>>>>>>
>>>>>> With this new wrapper the USB PHYs can be specified directly in the
>>>>>> USB controller's devicetree node (just like on the drivers listed
>>>>>> above). This allows SoCs like the Amlogic Meson GXL family to operate
>>>>>> correctly once this is wired up correctly. These SoCs use a dwc3
>>>>>> controller and require all USB PHYs to be initialized (if one of the USB
>>>>>> PHYs it not initialized then none of USB port works at all).
>>>>>>
>>>>>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>>>>>> Tested-by: Yixun Lan <yixun@amlogic.com>
>>>>>> Cc: Neil Armstrong <narmstr...@baylibre.com>
>>>>>> Cc: Chunfeng Yun <chunfeng@mediatek.com>
>>>>>
>>>>> This patch is breaking low power cases on TI SoCs when USB is in host 
>>>>> mode.
>>>>> I'll explain why below.
>>>> based on your explanation and reading the TI PHY drivers I am assuming
>>>> that the affected SoCs are using the "phy-omap-usb2" driver
>>>>
>>> yes and phy-ti-pipe3 as well i.e. "ti,phy-usb3" and "ti,omap-usb3"
>> I missed that, thanks
>>
>>>>>> ---
>>>>>>  drivers/usb/core/Makefile |   2 +-
>>>>>>  drivers/usb/core/phy.c| 158 
>>>>>> ++
>>>>>>  drivers/usb/core/phy.h|   7 ++
>>>>>>  3 files changed, 166 insertions(+), 1 deletion(-)
>>>>>>  create mode 100644 drivers/usb/core/phy.c
>>>>>>  create mode 100644 drivers/usb/core/phy.h
>>>>>>
>>>>>> diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
>>>>>> index 92c9cefb4317..18e874b0441e 100644
>>>>>> --- a/drivers/usb/core/Makefile
>>>>>> +++ b/drivers/usb/core/Makefile
>>>>>> @@ -6,7 +6,7 @@
>>>>>>  usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o
>>>>>>  usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o
>>>>>>  usbcore-y += devio.o notify.o generic.o quirks.o devices.o
>>>>>> -usbcore-y += port.o
>>>>>> +usbcore-y += phy.o port.o
>>>>>>
>>>>>>  usbcore-$(CONFIG_OF) += of.o
>>>>>>  usbcore-$(CONFIG_USB_PCI)+= hcd-pci.o
>>>>>> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c
>>>>>> new file mode 100644
>>>>>> index ..09b7c43c0ea4
>>>>>> --- /dev/null
>>>>>> +++ b/drivers/usb/core/phy.c
>>>>>> @@ -0,0 +1,158 @@
>>>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>>>> +/*
>>>>>> + * A wrapper for multiple PHYs which passes all phy_* function calls to
>>>>>> + * multiple (actual) PHY devices. This is comes handy when initializing
>>>>>> + * all PHYs on a HCD and to keep them all in the same state.
>>>>>> + *
>

Re: [PATCH usb-next v10 3/8] usb: core: add a wrapper for the USB PHYs on the HCD

2018-03-20 Thread Roger Quadros
On 19/03/18 18:12, Martin Blumenstingl wrote:
> Hi Roger,
> 
> On Mon, Mar 19, 2018 at 9:49 AM, Roger Quadros <rog...@ti.com> wrote:
>> Hi,
>>
>> On 19/03/18 00:29, Martin Blumenstingl wrote:
>>> Hi Roger,
>>>
>>> On Fri, Mar 16, 2018 at 3:32 PM, Roger Quadros <rog...@ti.com> wrote:
>>>> +some TI folks
>>>>
>>>> Hi Martin,
>>>>
>>>> On 18/02/18 20:44, Martin Blumenstingl wrote:
>>>>> Many SoC platforms have separate devices for the USB PHY which are
>>>>> registered through the generic PHY framework. These PHYs have to be
>>>>> enabled to make the USB controller actually work. They also have to be
>>>>> disabled again on shutdown/suspend.
>>>>>
>>>>> Currently (at least) the following HCI platform drivers are using custom
>>>>> code to obtain all PHYs via devicetree for the roothub/controller and
>>>>> disable/enable them when required:
>>>>> - ehci-platform.c has ehci_platform_power_{on,off}
>>>>> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off}
>>>>> - ohci-platform.c has ohci_platform_power_{on,off}
>>>>>
>>>>> With this new wrapper the USB PHYs can be specified directly in the
>>>>> USB controller's devicetree node (just like on the drivers listed
>>>>> above). This allows SoCs like the Amlogic Meson GXL family to operate
>>>>> correctly once this is wired up correctly. These SoCs use a dwc3
>>>>> controller and require all USB PHYs to be initialized (if one of the USB
>>>>> PHYs it not initialized then none of USB port works at all).
>>>>>
>>>>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>>>>> Tested-by: Yixun Lan <yixun@amlogic.com>
>>>>> Cc: Neil Armstrong <narmstr...@baylibre.com>
>>>>> Cc: Chunfeng Yun <chunfeng@mediatek.com>
>>>>
>>>> This patch is breaking low power cases on TI SoCs when USB is in host mode.
>>>> I'll explain why below.
>>> based on your explanation and reading the TI PHY drivers I am assuming
>>> that the affected SoCs are using the "phy-omap-usb2" driver
>>>
>> yes and phy-ti-pipe3 as well i.e. "ti,phy-usb3" and "ti,omap-usb3"
> I missed that, thanks
> 
>>>>> ---
>>>>>  drivers/usb/core/Makefile |   2 +-
>>>>>  drivers/usb/core/phy.c| 158 
>>>>> ++
>>>>>  drivers/usb/core/phy.h|   7 ++
>>>>>  3 files changed, 166 insertions(+), 1 deletion(-)
>>>>>  create mode 100644 drivers/usb/core/phy.c
>>>>>  create mode 100644 drivers/usb/core/phy.h
>>>>>
>>>>> diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
>>>>> index 92c9cefb4317..18e874b0441e 100644
>>>>> --- a/drivers/usb/core/Makefile
>>>>> +++ b/drivers/usb/core/Makefile
>>>>> @@ -6,7 +6,7 @@
>>>>>  usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o
>>>>>  usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o
>>>>>  usbcore-y += devio.o notify.o generic.o quirks.o devices.o
>>>>> -usbcore-y += port.o
>>>>> +usbcore-y += phy.o port.o
>>>>>
>>>>>  usbcore-$(CONFIG_OF) += of.o
>>>>>  usbcore-$(CONFIG_USB_PCI)+= hcd-pci.o
>>>>> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c
>>>>> new file mode 100644
>>>>> index ..09b7c43c0ea4
>>>>> --- /dev/null
>>>>> +++ b/drivers/usb/core/phy.c
>>>>> @@ -0,0 +1,158 @@
>>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>>> +/*
>>>>> + * A wrapper for multiple PHYs which passes all phy_* function calls to
>>>>> + * multiple (actual) PHY devices. This is comes handy when initializing
>>>>> + * all PHYs on a HCD and to keep them all in the same state.
>>>>> + *
>>>>> + * Copyright (C) 2018 Martin Blumenstingl 
>>>>> <martin.blumensti...@googlemail.com>
>>>>> + */
>>>>> +
>>>>> +#include 
>>>>> +#include 
>>>>> +#include 
>>>>> +#include 
>>>>> +
>>>>> +#include "phy.h"
>

Re: [PATCH usb-next v10 3/8] usb: core: add a wrapper for the USB PHYs on the HCD

2018-03-19 Thread Roger Quadros
Hi,

On 19/03/18 00:29, Martin Blumenstingl wrote:
> Hi Roger,
> 
> On Fri, Mar 16, 2018 at 3:32 PM, Roger Quadros <rog...@ti.com> wrote:
>> +some TI folks
>>
>> Hi Martin,
>>
>> On 18/02/18 20:44, Martin Blumenstingl wrote:
>>> Many SoC platforms have separate devices for the USB PHY which are
>>> registered through the generic PHY framework. These PHYs have to be
>>> enabled to make the USB controller actually work. They also have to be
>>> disabled again on shutdown/suspend.
>>>
>>> Currently (at least) the following HCI platform drivers are using custom
>>> code to obtain all PHYs via devicetree for the roothub/controller and
>>> disable/enable them when required:
>>> - ehci-platform.c has ehci_platform_power_{on,off}
>>> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off}
>>> - ohci-platform.c has ohci_platform_power_{on,off}
>>>
>>> With this new wrapper the USB PHYs can be specified directly in the
>>> USB controller's devicetree node (just like on the drivers listed
>>> above). This allows SoCs like the Amlogic Meson GXL family to operate
>>> correctly once this is wired up correctly. These SoCs use a dwc3
>>> controller and require all USB PHYs to be initialized (if one of the USB
>>> PHYs it not initialized then none of USB port works at all).
>>>
>>> Signed-off-by: Martin Blumenstingl <martin.blumensti...@googlemail.com>
>>> Tested-by: Yixun Lan <yixun@amlogic.com>
>>> Cc: Neil Armstrong <narmstr...@baylibre.com>
>>> Cc: Chunfeng Yun <chunfeng@mediatek.com>
>>
>> This patch is breaking low power cases on TI SoCs when USB is in host mode.
>> I'll explain why below.
> based on your explanation and reading the TI PHY drivers I am assuming
> that the affected SoCs are using the "phy-omap-usb2" driver
> 
yes and phy-ti-pipe3 as well i.e. "ti,phy-usb3" and "ti,omap-usb3"

>>> ---
>>>  drivers/usb/core/Makefile |   2 +-
>>>  drivers/usb/core/phy.c| 158 
>>> ++
>>>  drivers/usb/core/phy.h|   7 ++
>>>  3 files changed, 166 insertions(+), 1 deletion(-)
>>>  create mode 100644 drivers/usb/core/phy.c
>>>  create mode 100644 drivers/usb/core/phy.h
>>>
>>> diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
>>> index 92c9cefb4317..18e874b0441e 100644
>>> --- a/drivers/usb/core/Makefile
>>> +++ b/drivers/usb/core/Makefile
>>> @@ -6,7 +6,7 @@
>>>  usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o
>>>  usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o
>>>  usbcore-y += devio.o notify.o generic.o quirks.o devices.o
>>> -usbcore-y += port.o
>>> +usbcore-y += phy.o port.o
>>>
>>>  usbcore-$(CONFIG_OF) += of.o
>>>  usbcore-$(CONFIG_USB_PCI)+= hcd-pci.o
>>> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c
>>> new file mode 100644
>>> index ..09b7c43c0ea4
>>> --- /dev/null
>>> +++ b/drivers/usb/core/phy.c
>>> @@ -0,0 +1,158 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * A wrapper for multiple PHYs which passes all phy_* function calls to
>>> + * multiple (actual) PHY devices. This is comes handy when initializing
>>> + * all PHYs on a HCD and to keep them all in the same state.
>>> + *
>>> + * Copyright (C) 2018 Martin Blumenstingl 
>>> <martin.blumensti...@googlemail.com>
>>> + */
>>> +
>>> +#include 
>>> +#include 
>>> +#include 
>>> +#include 
>>> +
>>> +#include "phy.h"
>>> +
>>> +struct usb_phy_roothub {
>>> + struct phy  *phy;
>>> + struct list_headlist;
>>> +};
>>> +
>>> +static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev)
>>> +{
>>> + struct usb_phy_roothub *roothub_entry;
>>> +
>>> + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL);
>>> + if (!roothub_entry)
>>> + return ERR_PTR(-ENOMEM);
>>> +
>>> + INIT_LIST_HEAD(_entry->list);
>>> +
>>> + return roothub_entry;
>>> +}
>>> +
>>> +static int usb_phy_roothub_add_phy(struct device *dev, int index,
>>> +struct list_head *list)
>&

[PATCH] usb: dwc3: core: Fix broken system suspend/resume on AM437x

2018-03-16 Thread Roger Quadros
On TI's AM437x, the DWC3 controller looses state after a
system suspend/resume. We are re-initializing the controller
but we miss restoring the PRTCAP register. This causes
USB host to break on AM437x after a system suspend/resume.

Fix this by restoring the PRTCAP register on system resume.

Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/dwc3/core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index e8890c0..5becd7f 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1374,6 +1374,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, 
pm_message_t msg)
if (ret)
return ret;
 
+   dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);
spin_lock_irqsave(>lock, flags);
dwc3_gadget_resume(dwc);
spin_unlock_irqrestore(>lock, flags);
@@ -1384,6 +1385,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, 
pm_message_t msg)
ret = dwc3_core_init(dwc);
if (ret)
return ret;
+   dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
}
break;
case DWC3_GCTL_PRTCAP_OTG:
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


Re: [PATCH usb-next v10 3/8] usb: core: add a wrapper for the USB PHYs on the HCD

2018-03-16 Thread Roger Quadros
+some TI folks

Hi Martin,

On 18/02/18 20:44, Martin Blumenstingl wrote:
> Many SoC platforms have separate devices for the USB PHY which are
> registered through the generic PHY framework. These PHYs have to be
> enabled to make the USB controller actually work. They also have to be
> disabled again on shutdown/suspend.
> 
> Currently (at least) the following HCI platform drivers are using custom
> code to obtain all PHYs via devicetree for the roothub/controller and
> disable/enable them when required:
> - ehci-platform.c has ehci_platform_power_{on,off}
> - xhci-mtk.c has xhci_mtk_phy_{init,exit,power_on,power_off}
> - ohci-platform.c has ohci_platform_power_{on,off}
> 
> With this new wrapper the USB PHYs can be specified directly in the
> USB controller's devicetree node (just like on the drivers listed
> above). This allows SoCs like the Amlogic Meson GXL family to operate
> correctly once this is wired up correctly. These SoCs use a dwc3
> controller and require all USB PHYs to be initialized (if one of the USB
> PHYs it not initialized then none of USB port works at all).
> 
> Signed-off-by: Martin Blumenstingl 
> Tested-by: Yixun Lan 
> Cc: Neil Armstrong 
> Cc: Chunfeng Yun 

This patch is breaking low power cases on TI SoCs when USB is in host mode.
I'll explain why below.

> ---
>  drivers/usb/core/Makefile |   2 +-
>  drivers/usb/core/phy.c| 158 
> ++
>  drivers/usb/core/phy.h|   7 ++
>  3 files changed, 166 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/usb/core/phy.c
>  create mode 100644 drivers/usb/core/phy.h
> 
> diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
> index 92c9cefb4317..18e874b0441e 100644
> --- a/drivers/usb/core/Makefile
> +++ b/drivers/usb/core/Makefile
> @@ -6,7 +6,7 @@
>  usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o
>  usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o
>  usbcore-y += devio.o notify.o generic.o quirks.o devices.o
> -usbcore-y += port.o
> +usbcore-y += phy.o port.o
>  
>  usbcore-$(CONFIG_OF) += of.o
>  usbcore-$(CONFIG_USB_PCI)+= hcd-pci.o
> diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c
> new file mode 100644
> index ..09b7c43c0ea4
> --- /dev/null
> +++ b/drivers/usb/core/phy.c
> @@ -0,0 +1,158 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * A wrapper for multiple PHYs which passes all phy_* function calls to
> + * multiple (actual) PHY devices. This is comes handy when initializing
> + * all PHYs on a HCD and to keep them all in the same state.
> + *
> + * Copyright (C) 2018 Martin Blumenstingl 
> 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "phy.h"
> +
> +struct usb_phy_roothub {
> + struct phy  *phy;
> + struct list_headlist;
> +};
> +
> +static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev)
> +{
> + struct usb_phy_roothub *roothub_entry;
> +
> + roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL);
> + if (!roothub_entry)
> + return ERR_PTR(-ENOMEM);
> +
> + INIT_LIST_HEAD(_entry->list);
> +
> + return roothub_entry;
> +}
> +
> +static int usb_phy_roothub_add_phy(struct device *dev, int index,
> +struct list_head *list)
> +{
> + struct usb_phy_roothub *roothub_entry;
> + struct phy *phy = devm_of_phy_get_by_index(dev, dev->of_node, index);
> +
> + if (IS_ERR_OR_NULL(phy)) {
> + if (!phy || PTR_ERR(phy) == -ENODEV)
> + return 0;
> + else
> + return PTR_ERR(phy);
> + }
> +
> + roothub_entry = usb_phy_roothub_alloc(dev);
> + if (IS_ERR(roothub_entry))
> + return PTR_ERR(roothub_entry);
> +
> + roothub_entry->phy = phy;
> +
> + list_add_tail(_entry->list, list);
> +
> + return 0;
> +}
> +
> +struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev)
> +{
> + struct usb_phy_roothub *phy_roothub;
> + struct usb_phy_roothub *roothub_entry;
> + struct list_head *head;
> + int i, num_phys, err;
> +
> + num_phys = of_count_phandle_with_args(dev->of_node, "phys",
> +   "#phy-cells");
> + if (num_phys <= 0)
> + return NULL;
> +
> + phy_roothub = usb_phy_roothub_alloc(dev);
> + if (IS_ERR(phy_roothub))
> + return phy_roothub;
> +
> + for (i = 0; i < num_phys; i++) {
> + err = usb_phy_roothub_add_phy(dev, i, _roothub->list);
> + if (err)
> + goto err_out;
> + }
> +
> + head = _roothub->list;
> +
> + list_for_each_entry(roothub_entry, head, list) {
> + err = phy_init(roothub_entry->phy);

The phy_init() function actually enables 

Re: [PATCH v2] usb: dwc3: Prevent indefinite sleep in _dwc3_set_mode during suspend/resume

2018-03-16 Thread Roger Quadros
On 16/03/18 13:00, Felipe Balbi wrote:
> 
> Hi,
> 
> Roger Quadros <rog...@ti.com> writes:
> 
>> Hi Felipe,
>>
>> On 09/03/18 14:47, Roger Quadros wrote:
>>> In the following test we get stuck by sleeping forever in _dwc3_set_mode()
>>> after which dual-role switching doesn't work.
>>>
>>> On dra7-evm's dual-role port,
>>> - Load g_zero gadget driver and enumerate to host
>>> - suspend to mem
>>> - disconnect USB cable to host and connect otg cable with Pen drive in it.
>>> - resume system
>>> - we sleep indefinitely in _dwc3_set_mode due to.
>>>   dwc3_gadget_exit()->usb_del_gadget_udc()->udc_stop()->
>>> dwc3_gadget_stop()->wait_event_lock_irq()
>>>
>>> To fix this instead of waiting indefinitely with wait_event_lock_irq()
>>> we use wait_event_interruptible_lock_irq_timeout() and print
>>> and error message if there was a timeout.
>>>
>>> Signed-off-by: Roger Quadros <rog...@ti.com>
>>
>> Thanks for picking this for -next.
>> Is it better to have this in v4.16-rc fixes?
>> and also stable? v4.12+
> 
> Well, there was no "Fixes: foobar" or "Cc: stable" lines in the commit
> log ;-)
> 
> The best we can do now, is wait for -rc1 and manually send the commit to
> stable.
> 

That's fine. Thanks.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH v2] usb: dwc3: Prevent indefinite sleep in _dwc3_set_mode during suspend/resume

2018-03-16 Thread Roger Quadros
Hi Felipe,

On 09/03/18 14:47, Roger Quadros wrote:
> In the following test we get stuck by sleeping forever in _dwc3_set_mode()
> after which dual-role switching doesn't work.
> 
> On dra7-evm's dual-role port,
> - Load g_zero gadget driver and enumerate to host
> - suspend to mem
> - disconnect USB cable to host and connect otg cable with Pen drive in it.
> - resume system
> - we sleep indefinitely in _dwc3_set_mode due to.
>   dwc3_gadget_exit()->usb_del_gadget_udc()->udc_stop()->
>   dwc3_gadget_stop()->wait_event_lock_irq()
> 
> To fix this instead of waiting indefinitely with wait_event_lock_irq()
> we use wait_event_interruptible_lock_irq_timeout() and print
> and error message if there was a timeout.
> 
> Signed-off-by: Roger Quadros <rog...@ti.com>

Thanks for picking this for -next.
Is it better to have this in v4.16-rc fixes?
and also stable? v4.12+

> ---
> 
> Changelog:
> 
> v2:
> - use wait_event_interruptible_lock_irq_timeout() instead of 
> wait_event_lock_irq()
> 
>  drivers/usb/dwc3/gadget.c | 23 ---
>  1 file changed, 20 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 2bda4eb..7c3a6e4 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -1950,6 +1950,7 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
>   struct dwc3 *dwc = gadget_to_dwc(g);
>   unsigned long   flags;
>   int epnum;
> + u32 tmo_eps = 0;
>  
>   spin_lock_irqsave(>lock, flags);
>  
> @@ -1960,6 +1961,7 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
>  
>   for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
>   struct dwc3_ep  *dep = dwc->eps[epnum];
> + int ret;
>  
>   if (!dep)
>   continue;
> @@ -1967,9 +1969,24 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
>   if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
>   continue;
>  
> - wait_event_lock_irq(dep->wait_end_transfer,
> - !(dep->flags & 
> DWC3_EP_END_TRANSFER_PENDING),
> - dwc->lock);
> + ret = 
> wait_event_interruptible_lock_irq_timeout(dep->wait_end_transfer,
> + !(dep->flags & DWC3_EP_END_TRANSFER_PENDING),
> + dwc->lock, msecs_to_jiffies(5));
> +
> + if (ret <= 0) {
> + /* Timed out or interrupted! There's nothing much
> +  * we can do so we just log here and print which
> +  * endpoints timed out at the end.
> +  */
> + tmo_eps |= 1 << epnum;
> + dep->flags &= DWC3_EP_END_TRANSFER_PENDING;
> + }
> + }
> +
> + if (tmo_eps) {
> + dev_err(dwc->dev,
> + "end transfer timed out on endpoints 0x%x [bitmap]\n",
> + tmo_eps);
>   }
>  
>  out:
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH v5 1/6] dt-bindings: add bindings for USB physical connector

2018-03-15 Thread Roger Quadros
On 15/03/18 13:46, Robin Murphy wrote:
> On 12/03/18 10:41, Roger Quadros wrote:
> [...]
>>>>> @@ -0,0 +1,75 @@
>>>>> +USB Connector
>>>>> +=
>>>>> +
>>>>> +USB connector node represents physical USB connector. It should be
>>>>> +a child of USB interface controller.
>>>>> +
>>>>> +Required properties:
>>>>> +- compatible: describes type of the connector, must be one of:
>>>>> +    "usb-a-connector",
>>>>> +    "usb-b-connector",
>>>>> +    "usb-c-connector".
>>>> compatible should be just "usb-connector"
>>>>
>>>> Type should be a property
>>>>
>>>> type: type of usb connector "A", "B", "AB", "C"
>>>> AB is for dual-role connectors.
>>>
>>> I have proposed such property (and size also) in my first RFC [1]. Rod
>>> did not like it :)
>>>
>>> [1]: https://marc.info/?l=devicetree=150660411515233=2
>>>
>>
>> This is what Rob says here https://patchwork.kernel.org/patch/9976043/
>> "We did "type" for hdmi-connector, but I think I'd really prefer
>> compatible be used to distinguish as least where it may matter to s/w.
>> In the HDMI case, they all are pretty much the same, just different
>> physical size."
>>
>> So the question is. Does it matter to this particular software implementation
>> if it is type A,B,C connector?
>> If yes, how?
>>
>> Type A will never have any alternate function. It is always dedicated to USB.
> 
> In USB spec terms, at least. In reality there are things like the cool trick 
> Rockchip SoCs do whereby they can expose the debug UART Rx/Tx through the OTG 
> port's D+/D- pins, and that is on a type A connector in many products. I'm 
> guessing that's probably beyond the scope of this binding, though.
> 
>> Also does the size "full", "micro", "mini" matter to software?
> 
> If it means the user can look in sysfs to easily correlate logical ports with 
> physical connectors that's certainly handy (e.g. on something like Odroid-XU 
> where the two USB3 ports are brought out to an A and a micro-AB connector 
> respectively).

But this logic fails if both connectors are the same type/size.
This is where the label comes in handy. The labels can be unique and end user 
can identify the port using that.

> 
> Robin.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH v5 1/6] dt-bindings: add bindings for USB physical connector

2018-03-12 Thread Roger Quadros
Andrezej,

Why don't you have any of the USB maintainers in to/cc?

Greg Kroah-Hartman <gre...@linuxfoundation.org> (supporter:USB SUBSYSTEM)
Felipe Balbi <ba...@kernel.org> (maintainer:USB GADGET/PERIPHERAL SUBSYSTEM)

On 12/03/18 09:02, Andrzej Hajda wrote:
> On 09.03.2018 11:24, Roger Quadros wrote:
>> Hi,
>>
>> On 27/02/18 09:11, Andrzej Hajda wrote:
>>> These bindings allow to describe most known standard USB connectors
>>> and it should be possible to extend it if necessary.
>>> USB connectors, beside USB can be used to route other protocols,
>>> for example UART, Audio, MHL. In such case every device passing data
>>> through the connector should have appropriate graph bindings.
>>>
>>> Signed-off-by: Andrzej Hajda <a.ha...@samsung.com>
>>> ---
>>> v4:
>>> - improved 'type' description (Rob),
>>> - improved description of 2nd example (Rob).
>>> v3:
>>> - removed MHL port (samsung connector will have separate bindings),
>>> - added 2nd example for USB-C,
>>> - improved formatting.
>>> v2:
>>> - moved connector type(A,B,C) to compatible string (Rob),
>>> - renamed size property to type (Rob),
>>> - changed type description to be less confusing (Laurent),
>>> - removed vendor specific compatibles (implied by graph port number),
>>> - added requirement of connector being a child of IC (Rob),
>>> - removed max-mode (subtly suggested by Rob, it should be detected anyway
>>>   by USB Controller in runtime, downside is that device is not able to
>>>   report its real capabilities, maybe better would be to make it 
>>> optional(?)),
>>> - assigned port numbers to data buses (Rob).
>>>
>>> Regards
>>> Andrzej
>>> ---
>>>  .../bindings/connector/usb-connector.txt   | 75 
>>> ++
>>>  1 file changed, 75 insertions(+)
>>>  create mode 100644 
>>> Documentation/devicetree/bindings/connector/usb-connector.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/connector/usb-connector.txt 
>>> b/Documentation/devicetree/bindings/connector/usb-connector.txt
>>> new file mode 100644
>>> index ..e1463f14af38
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/connector/usb-connector.txt

Should this lie in  bindings/usb/connector?

>>> @@ -0,0 +1,75 @@
>>> +USB Connector
>>> +=
>>> +
>>> +USB connector node represents physical USB connector. It should be
>>> +a child of USB interface controller.
>>> +
>>> +Required properties:
>>> +- compatible: describes type of the connector, must be one of:
>>> +"usb-a-connector",
>>> +"usb-b-connector",
>>> +"usb-c-connector".
>> compatible should be just "usb-connector"
>>
>> Type should be a property
>>
>> type: type of usb connector "A", "B", "AB", "C"
>> AB is for dual-role connectors.
> 
> I have proposed such property (and size also) in my first RFC [1]. Rod
> did not like it :)
> 
> [1]: https://marc.info/?l=devicetree=150660411515233=2
> 

This is what Rob says here https://patchwork.kernel.org/patch/9976043/
"We did "type" for hdmi-connector, but I think I'd really prefer 
compatible be used to distinguish as least where it may matter to s/w. 
In the HDMI case, they all are pretty much the same, just different 
physical size."

So the question is. Does it matter to this particular software implementation
if it is type A,B,C connector?
If yes, how?

Type A will never have any alternate function. It is always dedicated to USB.

Also does the size "full", "micro", "mini" matter to software?

> 
>>
>> micro super-speed and high-speed connectors are different. How do you 
>> differentiate that?
> 
> I am aware of it, and property differentiating it was also in my earlier
> iterations.
> If there will be need to differentiate such connectors, adding property
> max-speed or max-mode would do the thing.

USB controller binding (bindings/usb/generic.txt) has the speed.
I don't think there is any value for replicating it for the connector. Maybe it 
could
be added later if needed.

> 
>>
>>> +
>>> +Optional properties:
>>> +- label: symbolic name for the connector,
>> Why do you need label? We can't maintain consistency as people will put 
>> creative names there.
>> Device/bus driver could generate a valid label.
> 

[PATCH v2] usb: dwc3: Prevent indefinite sleep in _dwc3_set_mode during suspend/resume

2018-03-09 Thread Roger Quadros
In the following test we get stuck by sleeping forever in _dwc3_set_mode()
after which dual-role switching doesn't work.

On dra7-evm's dual-role port,
- Load g_zero gadget driver and enumerate to host
- suspend to mem
- disconnect USB cable to host and connect otg cable with Pen drive in it.
- resume system
- we sleep indefinitely in _dwc3_set_mode due to.
  dwc3_gadget_exit()->usb_del_gadget_udc()->udc_stop()->
dwc3_gadget_stop()->wait_event_lock_irq()

To fix this instead of waiting indefinitely with wait_event_lock_irq()
we use wait_event_interruptible_lock_irq_timeout() and print
and error message if there was a timeout.

Signed-off-by: Roger Quadros <rog...@ti.com>
---

Changelog:

v2:
- use wait_event_interruptible_lock_irq_timeout() instead of 
wait_event_lock_irq()

 drivers/usb/dwc3/gadget.c | 23 ---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 2bda4eb..7c3a6e4 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1950,6 +1950,7 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
struct dwc3 *dwc = gadget_to_dwc(g);
unsigned long   flags;
int epnum;
+   u32 tmo_eps = 0;
 
spin_lock_irqsave(>lock, flags);
 
@@ -1960,6 +1961,7 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
 
for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
struct dwc3_ep  *dep = dwc->eps[epnum];
+   int ret;
 
if (!dep)
continue;
@@ -1967,9 +1969,24 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
continue;
 
-   wait_event_lock_irq(dep->wait_end_transfer,
-   !(dep->flags & 
DWC3_EP_END_TRANSFER_PENDING),
-   dwc->lock);
+   ret = 
wait_event_interruptible_lock_irq_timeout(dep->wait_end_transfer,
+   !(dep->flags & DWC3_EP_END_TRANSFER_PENDING),
+   dwc->lock, msecs_to_jiffies(5));
+
+   if (ret <= 0) {
+   /* Timed out or interrupted! There's nothing much
+* we can do so we just log here and print which
+* endpoints timed out at the end.
+*/
+   tmo_eps |= 1 << epnum;
+   dep->flags &= DWC3_EP_END_TRANSFER_PENDING;
+   }
+   }
+
+   if (tmo_eps) {
+   dev_err(dwc->dev,
+   "end transfer timed out on endpoints 0x%x [bitmap]\n",
+   tmo_eps);
}
 
 out:
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


--
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


Re: [PATCH v5 1/6] dt-bindings: add bindings for USB physical connector

2018-03-09 Thread Roger Quadros
Hi,

On 27/02/18 09:11, Andrzej Hajda wrote:
> These bindings allow to describe most known standard USB connectors
> and it should be possible to extend it if necessary.
> USB connectors, beside USB can be used to route other protocols,
> for example UART, Audio, MHL. In such case every device passing data
> through the connector should have appropriate graph bindings.
> 
> Signed-off-by: Andrzej Hajda 
> ---
> v4:
> - improved 'type' description (Rob),
> - improved description of 2nd example (Rob).
> v3:
> - removed MHL port (samsung connector will have separate bindings),
> - added 2nd example for USB-C,
> - improved formatting.
> v2:
> - moved connector type(A,B,C) to compatible string (Rob),
> - renamed size property to type (Rob),
> - changed type description to be less confusing (Laurent),
> - removed vendor specific compatibles (implied by graph port number),
> - added requirement of connector being a child of IC (Rob),
> - removed max-mode (subtly suggested by Rob, it should be detected anyway
>   by USB Controller in runtime, downside is that device is not able to
>   report its real capabilities, maybe better would be to make it optional(?)),
> - assigned port numbers to data buses (Rob).
> 
> Regards
> Andrzej
> ---
>  .../bindings/connector/usb-connector.txt   | 75 
> ++
>  1 file changed, 75 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/connector/usb-connector.txt
> 
> diff --git a/Documentation/devicetree/bindings/connector/usb-connector.txt 
> b/Documentation/devicetree/bindings/connector/usb-connector.txt
> new file mode 100644
> index ..e1463f14af38
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/connector/usb-connector.txt
> @@ -0,0 +1,75 @@
> +USB Connector
> +=
> +
> +USB connector node represents physical USB connector. It should be
> +a child of USB interface controller.
> +
> +Required properties:
> +- compatible: describes type of the connector, must be one of:
> +"usb-a-connector",
> +"usb-b-connector",
> +"usb-c-connector".

compatible should be just "usb-connector"

Type should be a property

type: type of usb connector "A", "B", "AB", "C"
AB is for dual-role connectors.

micro super-speed and high-speed connectors are different. How do you 
differentiate that?

> +
> +Optional properties:
> +- label: symbolic name for the connector,

Why do you need label? We can't maintain consistency as people will put 
creative names there.
Device/bus driver could generate a valid label.

> +- type: size of the connector, should be specified in case of USB-A, USB-B
> +  non-fullsize connectors: "mini", "micro".

type is misleading. Type is usually A/B/C. It should be size here instead.

size: size of the connector if not standard size. "mini", "micro"

If not specified it is treated as standard sized connector.
e.g. for Type-C there is no mini/micro. so size doesn't have to be specificed

What about Type-C connector?
> +
> +Required nodes:
> +- any data bus to the connector should be modeled using the OF graph bindings

s/modeled/modelled

> +  specified in bindings/graph.txt, unless the bus is between parent node and
> +  the connector. Since single connector can have multpile data buses every 
> bus

s/multpile/multiple

> +  has assigned OF graph port number as follows:
> +0: High Speed (HS), present in all connectors,
> +1: Super Speed (SS), present in SS capable connectors,
> +2: Sideband use (SBU), present in USB-C.
> +
> +Examples
> +
> +
> +1. Micro-USB connector with HS lines routed via controller (MUIC):
> +
> +muic-max77843@66 {
> + ...
> + usb_con: connector {
> + compatible = "usb-b-connector";
> + label = "micro-USB";
> + type = "micro";
> + };
> +};
> +
> +2. USB-C connector attached to CC controller (s2mm005), HS lines routed
> +to companion PMIC (max77865), SS lines to USB3 PHY and SBU to DisplayPort.
> +DisplayPort video lines are routed to the connector via SS mux in USB3 PHY.
> +
> +ccic: s2mm005@33 {
> + ...
> + usb_con: connector {
> + compatible = "usb-c-connector";
> + label = "USB-C";

The label is not consistent with the earlier example.

> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + reg = <0>;
> + usb_con_hs: endpoint {
> + remote-endpoint = <_usbc_hs>;
> + };
> + };
> + port@1 {
> + reg = <1>;
> + usb_con_ss: endpoint {
> + remote-endpoint = <_phy_ss>;
> + };
> + };
> + port@2 {
> + reg = <2>;
> 

Re: [PATCH] usb: dwc3: Prevent indefinite sleep in _dwc3_set_mode during suspend/resume

2018-03-09 Thread Roger Quadros
On 09/03/18 11:26, Roger Quadros wrote:
> On 09/03/18 11:23, Felipe Balbi wrote:
>>
>> Hi,
>>
>> Roger Quadros <rog...@ti.com> writes:
>>
>> 
>>
>>>>> When we set up the DWC3_DEPCMD_ENDTRANSFER command in
>>>>> dwc3_stop_active_transfer(), we can do not set DWC3_DEPCMD_CMDIOC,
>>>>> then there will no endpoint command complete interrupts I think.
>>>>>
>>>>> cmd |= DWC3_DEPCMD_CMDIOC;
>>>>
>>>> I remember some part of the databook mandating CMDIOC to be set. We
>>>> could test it out without and see if anything blows up. I would,
>>>> however, require a lengthy comment explaining that we're deviating from
>>>> databook revision x.yya, section foobar because $reasons. :-)
>>>>
>>>
>>> This is what the v3.10 databook says
>>>
>>> "When issuing an End Transfer command, software must set the CmdIOC
>>> bit (field 8) so that an Endpoint Command Complete event is generated
>>> after the transfer ends. This is necessary to synchronize the
>>> conclusion of system bus traffic before the End Transfer command is
>>> completed."
>>>
>>> with a note
>>>
>>> "If GUCTL2[Rst_actbitlater] is set, Software can poll the completion
>>> of the End Transfer command by polling the command active bit to be
>>> cleared to 0."
>>>
>>> fyi.
>>>
>>> Rst_actbitlater - "Enable clearing of the command active bit for the
>>> ENDXFER command after the command execution is completed.  This bit is
>>> valid in device mode only."
>>>
>>> So I'd prefer not to clear CMDIOC for all cases.
>>>
>>> Could we some how just tackle the dwc3_gadget_exit case like I did in
>>> this patch?
>>
>> if you can send a version that doesn't iterate over all endpoints twice,
>> sure. We still need a comment somewhere, and I fear we may get
>> interrupts later in some cases. How would we deal with that?
>>
> 
> how about explicitly masking that interrupt? Is it possible?
> 

Other easy option is to use wait_event_interruptible_lock_irq_timeout()
instead of wait_event_lock_irq() in dwc3_gadget_stop().

Is a 200ms timeout sufficient? And after the first timeout we assume all
will timeout so no point in waiting 200ms for each endpoint.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: Prevent indefinite sleep in _dwc3_set_mode during suspend/resume

2018-03-09 Thread Roger Quadros
On 09/03/18 11:23, Felipe Balbi wrote:
> 
> Hi,
> 
> Roger Quadros <rog...@ti.com> writes:
> 
> 
> 
>>>> When we set up the DWC3_DEPCMD_ENDTRANSFER command in
>>>> dwc3_stop_active_transfer(), we can do not set DWC3_DEPCMD_CMDIOC,
>>>> then there will no endpoint command complete interrupts I think.
>>>>
>>>> cmd |= DWC3_DEPCMD_CMDIOC;
>>>
>>> I remember some part of the databook mandating CMDIOC to be set. We
>>> could test it out without and see if anything blows up. I would,
>>> however, require a lengthy comment explaining that we're deviating from
>>> databook revision x.yya, section foobar because $reasons. :-)
>>>
>>
>> This is what the v3.10 databook says
>>
>> "When issuing an End Transfer command, software must set the CmdIOC
>> bit (field 8) so that an Endpoint Command Complete event is generated
>> after the transfer ends. This is necessary to synchronize the
>> conclusion of system bus traffic before the End Transfer command is
>> completed."
>>
>> with a note
>>
>> "If GUCTL2[Rst_actbitlater] is set, Software can poll the completion
>> of the End Transfer command by polling the command active bit to be
>> cleared to 0."
>>
>> fyi.
>>
>> Rst_actbitlater - "Enable clearing of the command active bit for the
>> ENDXFER command after the command execution is completed.  This bit is
>> valid in device mode only."
>>
>> So I'd prefer not to clear CMDIOC for all cases.
>>
>> Could we some how just tackle the dwc3_gadget_exit case like I did in
>> this patch?
> 
> if you can send a version that doesn't iterate over all endpoints twice,
> sure. We still need a comment somewhere, and I fear we may get
> interrupts later in some cases. How would we deal with that?
> 

how about explicitly masking that interrupt? Is it possible?

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: Prevent indefinite sleep in _dwc3_set_mode during suspend/resume

2018-03-09 Thread Roger Quadros
On 05/03/18 13:27, Felipe Balbi wrote:
> 
> Hi,
> 
> Baolin Wang  writes:
>>  void dwc3_gadget_exit(struct dwc3 *dwc)
>>  {
>> +  int epnum;
>> +  unsigned long flags;
>> +
>> +  spin_lock_irqsave(>lock, flags);
>> +  for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
>> +  struct dwc3_ep  *dep = dwc->eps[epnum];
>> +
>> +  if (!dep)
>> +  continue;
>> +
>> +  dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
>> +  }
>> +  spin_unlock_irqrestore(>lock, flags);
>> +
>>usb_del_gadget_udc(>gadget);
>>dwc3_gadget_free_endpoints(dwc);
>
> free endpoints is a better place for this. It's already going to free
> the memory anyway. Might as well clear all flags to 0 there.
>

 But it won't solve the deadlock issue. Since 
 dwc3_gadget_free_endpoints()
 is called after usb_del_gadget_udc() and the deadlock happens when

 usb_del_gadget_udc()->udc_stop()->dwc3_gadget_stop()->wait_event_lock_irq()

 and DWC3_EP_END_TRANSFER_PENDING flag is set.
>>>
>>> indeed. Iterating twice over the entire endpoint list seems
>>> wasteful. Perhaps we just shouldn't wait when removing the UDC since
>>> that's essentially what this patch will do, right? If you clear the flag
>>> before calling ->udc_stop(), this means the loop in dwc3_gadget_stop()
>>> will do nothing. Might as well remove it.
>>>
>>
>> This means that we will never wait for DWC3_EP_END_TRANSFER_PENDING to 
>> clear
>> in dwc3_gadget_stop() like we used to. This is perfectly fine, right?
>>
>> It makes sense to me as dwc3_gadget_stop() calls __dwc3_gadget_stop() 
>> which
>> masks all interrupts and nobody will ever clear that flag if it was set.
>
> I don't think so. It can not mask the endpoint events, please check
> the events which will be masked in DEVTEN register. The reason why we
> should wait for DWC3_EP_END_TRANSFER_PENDING to clear is that,
> sometimes the DWC3_DEPEVT_EPCMDCMPLT event will be triggered later
> than 100us, but now we may have freed the gadget irq which will cause
> crash.

 We could mask command complete events as soon as ->udc_stop() is called,
 right? Hmm, actually, __dwc3_gadget_stop() already clears DEVTEN
 completely.
>>>
>>> But which bit in DEVTEN says Endpoint events are disabled?
>>
>> When we set up the DWC3_DEPCMD_ENDTRANSFER command in
>> dwc3_stop_active_transfer(), we can do not set DWC3_DEPCMD_CMDIOC,
>> then there will no endpoint command complete interrupts I think.
>>
>> cmd |= DWC3_DEPCMD_CMDIOC;
> 
> I remember some part of the databook mandating CMDIOC to be set. We
> could test it out without and see if anything blows up. I would,
> however, require a lengthy comment explaining that we're deviating from
> databook revision x.yya, section foobar because $reasons. :-)
> 

This is what the v3.10 databook says

"When issuing an End Transfer command, software must set the CmdIOC bit (field 
8) so that an Endpoint
Command Complete event is generated after the transfer ends. This is necessary 
to synchronize the
conclusion of system bus traffic before the End Transfer command is completed."

with a note
"If GUCTL2[Rst_actbitlater] is set, Software can poll the completion of the End 
Transfer
command by polling the command active bit to be cleared to 0."

fyi.
Rst_actbitlater - "Enable clearing of the command active bit for the ENDXFER
command after the command execution is completed.
This bit is valid in device mode only."

So I'd prefer not to clear CMDIOC for all cases.

Could we some how just tackle the dwc3_gadget_exit case like I did in this 
patch?

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: core: power on PHYs before initializing core

2018-03-09 Thread Roger Quadros
Hi,

On 08/03/18 18:49, Brian Norris wrote:
> Hi,
> 
> On Thu, Mar 08, 2018 at 12:43:40PM +0200, Felipe Balbi wrote:
>> William Wu  writes:
>>> The dwc3_core_init() gets the PHYs and initializes the PHYs with
>>> the usb_phy_init() and phy_init() functions before initializing
>>> core, and power on the PHYs after core initialization is done.
>>>
>>> However, some platforms (e.g. Rockchip RK3399 DWC3 with Type-C
>>> USB3 PHY), it needs to do some special operation while power on
>>> the Type-C PHY before initializing DWC3 core. It's because that
>>> the RK3399 Type-C PHY requires to hold the DWC3 controller in
>>> reset state to keep the PIPE power state in P2 while configuring
>>> the Type-C PHY, otherwise, it may cause waiting for the PIPE ready
>>> timeout. In this case, if we power on the PHYs after the DWC3 core
>>> initialization is done, the core will be reset to uninitialized
>>> state after power on the PHYs.
>>>
>>> Fix this by powering on the PHYs before initializing core. And
>>> because the GUID register may also be reset in this case, so we
>>> need to configure the GUID register after powering on the PHYs.
>>>
>>> Signed-off-by: William Wu 
>>
>> does this cause any regressions for your boards?
> 
> I'm not Roger, but I believe it was determined we don't need this for
> the Rockchip systems for which William was originally sending this. At
> least not right now. I believe our PHY init problems were mostly
> resolved in other ways.
> 
> (Although I hear USB is currently pretty broken around suspend/resume
> for us on -next. Likely unrelated.)
> 
> I guess we never clearly replied stating the above. I hope this isn't
> merged anywhere? Or I guess it's no problem to me at the moment, but it
> might be needless churn.
> 

I did some quick tests on TI platforms and didn't see any issues with this 
patch.
Since this patch isn't really fixing your problem and we didn't have any
problems to start with I'd suggest to avoid this churn for now.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH v2 2/2] usb: dwc3: add dual role support using OTG block

2018-03-08 Thread Roger Quadros
Felipe,

On 08/03/18 12:39, Felipe Balbi wrote:
> Roger Quadros <rog...@ti.com> writes:
> 
>> This is useful on platforms (e.g. TI AM437x) that don't
>> have ID available on a GPIO but do have the OTG block.
>>
>> We can obtain the ID state via the OTG block and use it
>> for dual-role switching.
>>
>> Signed-off-by: Roger Quadros <rog...@ti.com>
> 
> patch one applied fine to testing/next. But not this one:

That's because you will need this commit from v4.16-rc3

c4a5153e87fd("usb: dwc3: core: Power-off core/PHYs on system_suspend in 
host mode")

Could you please apply that and let me know if it works?

> 
> checking file drivers/usb/dwc3/core.c
> Hunk #2 FAILED at 107.
> Hunk #3 succeeded at 122 (offset -5 lines).
> Hunk #4 succeeded at 166 (offset -3 lines).
> Hunk #5 succeeded at 365 (offset 5 lines).
> Hunk #6 succeeded at 382 (offset 5 lines).
> Hunk #7 succeeded at 1193 with fuzz 2 (offset -145 lines).
> Hunk #8 FAILED at 1383.
> 2 out of 8 hunks FAILED
> checking file drivers/usb/dwc3/core.h
> Hunk #2 succeeded at 901 (offset 33 lines).
> Hunk #3 succeeded at 1040 (offset 35 lines).
> Hunk #4 succeeded at 1316 (offset 46 lines).
> Hunk #5 succeeded at 1334 (offset 46 lines).
> Hunk #6 succeeded at 1380 (offset 46 lines).
> checking file drivers/usb/dwc3/drd.c
> 
> care to rebase?
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: Prevent indefinite sleep in _dwc3_set_mode during suspend/resume

2018-03-05 Thread Roger Quadros
On 05/03/18 13:06, Felipe Balbi wrote:
> 
> Hi,
> 
> Baolin Wang <baolin.w...@linaro.org> writes:
>>>> Roger Quadros <rog...@ti.com> writes:
>>>>>> Roger Quadros <rog...@ti.com> writes:
>>>>>>> In the following test we get stuck by sleeping forever in 
>>>>>>> _dwc3_set_mode()
>>>>>>> after which dual-role switching doesn't work.
>>>>>>>
>>>>>>> On dra7-evm's dual-role port,
>>>>>>> - Load g_zero gadget driver and enumerate to host
>>>>>>> - suspend to mem
>>>>>>> - disconnect USB cable to host and connect otg cable with Pen drive in 
>>>>>>> it.
>>>>>>> - resume system
>>>>>>> - we sleep indefinitely in _dwc3_set_mode due to.
>>>>>>>   dwc3_gadget_exit()->usb_del_gadget_udc()->udc_stop()->
>>>>>>>dwc3_gadget_stop()->wait_event_lock_irq()
>>>>>>>
>>>>>>> Let's clear the DWC3_EP_END_TRANSFER_PENDING flag on all endpoints
>>>>>>> so we don't wait in dwc3_gadget_stop().
>>>>>>>
>>>>>>> Signed-off-by: Roger Quadros <rog...@ti.com>
>>>>>>> ---
>>>>>>>  drivers/usb/dwc3/gadget.c | 14 ++
>>>>>>>  1 file changed, 14 insertions(+)
>>>>>>>
>>>>>>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>>>>>>> index 2bda4eb..0a360da 100644
>>>>>>> --- a/drivers/usb/dwc3/gadget.c
>>>>>>> +++ b/drivers/usb/dwc3/gadget.c
>>>>>>> @@ -3273,6 +3273,20 @@ int dwc3_gadget_init(struct dwc3 *dwc)
>>>>>>>
>>>>>>>  void dwc3_gadget_exit(struct dwc3 *dwc)
>>>>>>>  {
>>>>>>> +  int epnum;
>>>>>>> +  unsigned long flags;
>>>>>>> +
>>>>>>> +  spin_lock_irqsave(>lock, flags);
>>>>>>> +  for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
>>>>>>> +  struct dwc3_ep  *dep = dwc->eps[epnum];
>>>>>>> +
>>>>>>> +  if (!dep)
>>>>>>> +  continue;
>>>>>>> +
>>>>>>> +  dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
>>>>>>> +  }
>>>>>>> +  spin_unlock_irqrestore(>lock, flags);
>>>>>>> +
>>>>>>>usb_del_gadget_udc(>gadget);
>>>>>>>dwc3_gadget_free_endpoints(dwc);
>>>>>>
>>>>>> free endpoints is a better place for this. It's already going to free
>>>>>> the memory anyway. Might as well clear all flags to 0 there.
>>>>>>
>>>>>
>>>>> But it won't solve the deadlock issue. Since dwc3_gadget_free_endpoints()
>>>>> is called after usb_del_gadget_udc() and the deadlock happens when
>>>>>
>>>>> usb_del_gadget_udc()->udc_stop()->dwc3_gadget_stop()->wait_event_lock_irq()
>>>>>
>>>>> and DWC3_EP_END_TRANSFER_PENDING flag is set.
>>>>
>>>> indeed. Iterating twice over the entire endpoint list seems
>>>> wasteful. Perhaps we just shouldn't wait when removing the UDC since
>>>> that's essentially what this patch will do, right? If you clear the flag
>>>> before calling ->udc_stop(), this means the loop in dwc3_gadget_stop()
>>>> will do nothing. Might as well remove it.
>>>>
>>>
>>> This means that we will never wait for DWC3_EP_END_TRANSFER_PENDING to clear
>>> in dwc3_gadget_stop() like we used to. This is perfectly fine, right?
>>>
>>> It makes sense to me as dwc3_gadget_stop() calls __dwc3_gadget_stop() which
>>> masks all interrupts and nobody will ever clear that flag if it was set.
>>
>> I don't think so. It can not mask the endpoint events, please check
>> the events which will be masked in DEVTEN register. The reason why we
>> should wait for DWC3_EP_END_TRANSFER_PENDING to clear is that,
>> sometimes the DWC3_DEPEVT_EPCMDCMPLT event will be triggered later
>> than 100us, but now we may have freed the gadget irq which will cause
>> crash.
> 
> We could mask command complete events as soon as ->udc_stop() is called,
> right? Hmm, actually, __dwc3_gadget_stop() already clears DEVTEN
> completely.

But which bit in DEVTEN says Endpoint events are disabled?

> 
> /me goes check databook
> 
> At least on revision 2.60a of the databook, bit 10 is reserved. I wonder
> if that's the start of all the problems. Anybody has access to older and
> newer databook revisions so we can cross-check?
> 

I can access v2.40 and v3.10 books.

bit 10 is reserved on both

Differences in v2.4 vs v3.10 are:

bit 8   reservedvs  L1SUSPEN
bit 13  reservedvs  StopOnDisconnectEn
bit 14  reservedvs  L1WKUPEVTEN

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: Prevent indefinite sleep in _dwc3_set_mode during suspend/resume

2018-03-05 Thread Roger Quadros
On 05/03/18 12:41, Baolin Wang wrote:
> Hi Roger,
> 
> On 5 March 2018 at 17:45, Roger Quadros <rog...@ti.com> wrote:
>> Felipe,
>>
>> On 05/03/18 10:49, Felipe Balbi wrote:
>>>
>>> Hi,
>>>
>>> Roger Quadros <rog...@ti.com> writes:
>>>>> Roger Quadros <rog...@ti.com> writes:
>>>>>> In the following test we get stuck by sleeping forever in 
>>>>>> _dwc3_set_mode()
>>>>>> after which dual-role switching doesn't work.
>>>>>>
>>>>>> On dra7-evm's dual-role port,
>>>>>> - Load g_zero gadget driver and enumerate to host
>>>>>> - suspend to mem
>>>>>> - disconnect USB cable to host and connect otg cable with Pen drive in 
>>>>>> it.
>>>>>> - resume system
>>>>>> - we sleep indefinitely in _dwc3_set_mode due to.
>>>>>>   dwc3_gadget_exit()->usb_del_gadget_udc()->udc_stop()->
>>>>>>dwc3_gadget_stop()->wait_event_lock_irq()
>>>>>>
>>>>>> Let's clear the DWC3_EP_END_TRANSFER_PENDING flag on all endpoints
>>>>>> so we don't wait in dwc3_gadget_stop().
>>>>>>
>>>>>> Signed-off-by: Roger Quadros <rog...@ti.com>
>>>>>> ---
>>>>>>  drivers/usb/dwc3/gadget.c | 14 ++
>>>>>>  1 file changed, 14 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>>>>>> index 2bda4eb..0a360da 100644
>>>>>> --- a/drivers/usb/dwc3/gadget.c
>>>>>> +++ b/drivers/usb/dwc3/gadget.c
>>>>>> @@ -3273,6 +3273,20 @@ int dwc3_gadget_init(struct dwc3 *dwc)
>>>>>>
>>>>>>  void dwc3_gadget_exit(struct dwc3 *dwc)
>>>>>>  {
>>>>>> +  int epnum;
>>>>>> +  unsigned long flags;
>>>>>> +
>>>>>> +  spin_lock_irqsave(>lock, flags);
>>>>>> +  for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
>>>>>> +  struct dwc3_ep  *dep = dwc->eps[epnum];
>>>>>> +
>>>>>> +  if (!dep)
>>>>>> +  continue;
>>>>>> +
>>>>>> +  dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
>>>>>> +  }
>>>>>> +  spin_unlock_irqrestore(>lock, flags);
>>>>>> +
>>>>>>usb_del_gadget_udc(>gadget);
>>>>>>dwc3_gadget_free_endpoints(dwc);
>>>>>
>>>>> free endpoints is a better place for this. It's already going to free
>>>>> the memory anyway. Might as well clear all flags to 0 there.
>>>>>
>>>>
>>>> But it won't solve the deadlock issue. Since dwc3_gadget_free_endpoints()
>>>> is called after usb_del_gadget_udc() and the deadlock happens when
>>>>
>>>> usb_del_gadget_udc()->udc_stop()->dwc3_gadget_stop()->wait_event_lock_irq()
>>>>
>>>> and DWC3_EP_END_TRANSFER_PENDING flag is set.
>>>
>>> indeed. Iterating twice over the entire endpoint list seems
>>> wasteful. Perhaps we just shouldn't wait when removing the UDC since
>>> that's essentially what this patch will do, right? If you clear the flag
>>> before calling ->udc_stop(), this means the loop in dwc3_gadget_stop()
>>> will do nothing. Might as well remove it.
>>>
>>
>> This means that we will never wait for DWC3_EP_END_TRANSFER_PENDING to clear
>> in dwc3_gadget_stop() like we used to. This is perfectly fine, right?
>>
>> It makes sense to me as dwc3_gadget_stop() calls __dwc3_gadget_stop() which
>> masks all interrupts and nobody will ever clear that flag if it was set.
> 
> I don't think so. It can not mask the endpoint events, please check
> the events which will be masked in DEVTEN register. The reason why we

Correct, endpoint events are not managed by DEVTEN.

> should wait for DWC3_EP_END_TRANSFER_PENDING to clear is that,
> sometimes the DWC3_DEPEVT_EPCMDCMPLT event will be triggered later
> than 100us, but now we may have freed the gadget irq which will cause
> crash.
> 

OK. So what is the right approach here?
In the test case I mentioned in the commit log the endpoint interrupt never
happens and it waits forever in dwc3_gadget_stop().

Since we know we're winding up, can we explicitly disable the endpoint events
here?

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: Prevent indefinite sleep in _dwc3_set_mode during suspend/resume

2018-03-05 Thread Roger Quadros
Felipe,

On 05/03/18 10:49, Felipe Balbi wrote:
> 
> Hi,
> 
> Roger Quadros <rog...@ti.com> writes:
>>> Roger Quadros <rog...@ti.com> writes:
>>>> In the following test we get stuck by sleeping forever in _dwc3_set_mode()
>>>> after which dual-role switching doesn't work.
>>>>
>>>> On dra7-evm's dual-role port,
>>>> - Load g_zero gadget driver and enumerate to host
>>>> - suspend to mem
>>>> - disconnect USB cable to host and connect otg cable with Pen drive in it.
>>>> - resume system
>>>> - we sleep indefinitely in _dwc3_set_mode due to.
>>>>   dwc3_gadget_exit()->usb_del_gadget_udc()->udc_stop()->
>>>>dwc3_gadget_stop()->wait_event_lock_irq()
>>>>
>>>> Let's clear the DWC3_EP_END_TRANSFER_PENDING flag on all endpoints
>>>> so we don't wait in dwc3_gadget_stop().
>>>>
>>>> Signed-off-by: Roger Quadros <rog...@ti.com>
>>>> ---
>>>>  drivers/usb/dwc3/gadget.c | 14 ++
>>>>  1 file changed, 14 insertions(+)
>>>>
>>>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>>>> index 2bda4eb..0a360da 100644
>>>> --- a/drivers/usb/dwc3/gadget.c
>>>> +++ b/drivers/usb/dwc3/gadget.c
>>>> @@ -3273,6 +3273,20 @@ int dwc3_gadget_init(struct dwc3 *dwc)
>>>>  
>>>>  void dwc3_gadget_exit(struct dwc3 *dwc)
>>>>  {
>>>> +  int epnum;
>>>> +  unsigned long flags;
>>>> +
>>>> +  spin_lock_irqsave(>lock, flags);
>>>> +  for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
>>>> +  struct dwc3_ep  *dep = dwc->eps[epnum];
>>>> +
>>>> +  if (!dep)
>>>> +  continue;
>>>> +
>>>> +  dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
>>>> +  }
>>>> +  spin_unlock_irqrestore(>lock, flags);
>>>> +
>>>>usb_del_gadget_udc(>gadget);
>>>>dwc3_gadget_free_endpoints(dwc);
>>>
>>> free endpoints is a better place for this. It's already going to free
>>> the memory anyway. Might as well clear all flags to 0 there.
>>>
>>
>> But it won't solve the deadlock issue. Since dwc3_gadget_free_endpoints()
>> is called after usb_del_gadget_udc() and the deadlock happens when
>>
>> usb_del_gadget_udc()->udc_stop()->dwc3_gadget_stop()->wait_event_lock_irq()
>>
>> and DWC3_EP_END_TRANSFER_PENDING flag is set.
> 
> indeed. Iterating twice over the entire endpoint list seems
> wasteful. Perhaps we just shouldn't wait when removing the UDC since
> that's essentially what this patch will do, right? If you clear the flag
> before calling ->udc_stop(), this means the loop in dwc3_gadget_stop()
> will do nothing. Might as well remove it.
> 

This means that we will never wait for DWC3_EP_END_TRANSFER_PENDING to clear
in dwc3_gadget_stop() like we used to. This is perfectly fine, right?

It makes sense to me as dwc3_gadget_stop() calls __dwc3_gadget_stop() which
masks all interrupts and nobody will ever clear that flag if it was set.

And there is no point in clearing the DWC3_EP_END_TRANSFER_PENDING flag
in dwc3_gadget_free_endpoints() since we're freeing the dwc3_ep memory there.

dwc3_gadget_init_endpoints() will start with a clean slate.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH v3] usb: host: ehci-platform: add support for optional external vbus supply

2018-02-28 Thread Roger Quadros
Hi Amelie,

On 23/02/18 15:46, Amelie Delaunay wrote:
> On some boards, especially when vbus supply requires large current,
> and the charge pump on the PHY isn't enough, an external vbus power switch
> may be used.
> Add support for optional external vbus supply per port in ehci-platform.
> 
> Signed-off-by: Amelie Delaunay <amelie.delau...@st.com>
> 
> ---
> Changes in v3:
>  * Address Felipe Balbi comments: reduce indentation in
>ehci_platform_port_power.
>  * Address Roger Quadros and Alan Stern comments: platforms can have one
>external vbus supply per port, so add support to get as many optional
>regulator as implemented ports on the host controller.
> 
> Changes in v2:
>  * Address Roger Quadros comments: move regulator_enable/disable from
>ehci_platform_power_on/off to ehci_platform_port_power.
> ---
>  Documentation/devicetree/bindings/usb/usb-ehci.txt |  1 +
>  drivers/usb/host/ehci-platform.c   | 52 
> +-
>  2 files changed, 52 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt 
> b/Documentation/devicetree/bindings/usb/usb-ehci.txt
> index 3efde12..cd576db 100644
> --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt
> +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt
> @@ -19,6 +19,7 @@ Optional properties:
>   - phys : phandle + phy specifier pair
>   - phy-names : "usb"
>   - resets : phandle + reset specifier pair
> + - portN_vbus-supply : phandle of regulator supplying vbus for port N
>  
>  Example (Sequoia 440EPx):
>  ehci@e300 {

Sorry for not pointing this out earlier but I think patch to DT bindings
should come separately (before the driver changes) with the following subject.

"dt-bindings: usb: ehci: "


> diff --git a/drivers/usb/host/ehci-platform.c 
> b/drivers/usb/host/ehci-platform.c
> index b065a96..8e9f201 100644
> --- a/drivers/usb/host/ehci-platform.c
> +++ b/drivers/usb/host/ehci-platform.c
> @@ -29,6 +29,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -46,6 +47,7 @@ struct ehci_platform_priv {
>   struct reset_control *rsts;
>   struct phy **phys;
>   int num_phys;
> + struct regulator **vbus_supplies;
>   bool reset_on_resume;
>  };
>  
> @@ -56,7 +58,8 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
>   struct platform_device *pdev = to_platform_device(hcd->self.controller);
>   struct usb_ehci_pdata *pdata = dev_get_platdata(>dev);
>   struct ehci_hcd *ehci = hcd_to_ehci(hcd);
> - int retval;
> + struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
> + int portnum, n_ports, retval;
>  
>   ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug;
>  
> @@ -71,11 +74,57 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
>   if (retval)
>   return retval;
>  
> + n_ports = HCS_N_PORTS(ehci->hcs_params);
> + priv->vbus_supplies = devm_kcalloc(>dev, n_ports,
> +sizeof(struct regulator *),
> +GFP_KERNEL);
> + if (!priv->vbus_supplies)
> + return -ENOMEM;
> +
> + for (portnum = 0; portnum < n_ports; portnum++) {
> + struct regulator *vbus_supply;
> + char id[20];
> +
> + sprintf(id, "port%d_vbus", portnum);
> +
> + vbus_supply = devm_regulator_get_optional(>dev, id);
> + if (IS_ERR(vbus_supply)) {
> + retval = PTR_ERR(vbus_supply);
> + if (retval == -ENODEV)
> + priv->vbus_supplies[portnum] = NULL;
> + else
> + return retval;
> + } else {
> + priv->vbus_supplies[portnum] = vbus_supply;
> + }
> + }
> +
>   if (pdata->no_io_watchdog)
>   ehci->need_io_watchdog = 0;
>   return 0;
>  }
>  
> +static int ehci_platform_port_power(struct usb_hcd *hcd, int portnum,
> + bool enable)
> +{
> + struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
> + int ret;
> +
> + if (!priv->vbus_supplies[portnum])
> + return 0;
> +
> + if (enable)
> + ret = regulator_enable(priv->vbus_supplies[portnum]);
> + else
> + ret = regulator_disable(priv->vbus_supplies[portnum]);

A newline could be used here.

> + if (ret)
> + dev_err(hcd->self.controller,
> + 

Re: [PATCH] usb: dwc3: Prevent indefinite sleep in _dwc3_set_mode during suspend/resume

2018-02-28 Thread Roger Quadros
Felipe,

On 28/02/18 09:53, Felipe Balbi wrote:
> 
> Hi,
> 
> Roger Quadros <rog...@ti.com> writes:
>> In the following test we get stuck by sleeping forever in _dwc3_set_mode()
>> after which dual-role switching doesn't work.
>>
>> On dra7-evm's dual-role port,
>> - Load g_zero gadget driver and enumerate to host
>> - suspend to mem
>> - disconnect USB cable to host and connect otg cable with Pen drive in it.
>> - resume system
>> - we sleep indefinitely in _dwc3_set_mode due to.
>>   dwc3_gadget_exit()->usb_del_gadget_udc()->udc_stop()->
>>  dwc3_gadget_stop()->wait_event_lock_irq()
>>
>> Let's clear the DWC3_EP_END_TRANSFER_PENDING flag on all endpoints
>> so we don't wait in dwc3_gadget_stop().
>>
>> Signed-off-by: Roger Quadros <rog...@ti.com>
>> ---
>>  drivers/usb/dwc3/gadget.c | 14 ++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>> index 2bda4eb..0a360da 100644
>> --- a/drivers/usb/dwc3/gadget.c
>> +++ b/drivers/usb/dwc3/gadget.c
>> @@ -3273,6 +3273,20 @@ int dwc3_gadget_init(struct dwc3 *dwc)
>>  
>>  void dwc3_gadget_exit(struct dwc3 *dwc)
>>  {
>> +int epnum;
>> +unsigned long flags;
>> +
>> +spin_lock_irqsave(>lock, flags);
>> +for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
>> +struct dwc3_ep  *dep = dwc->eps[epnum];
>> +
>> +if (!dep)
>> +continue;
>> +
>> +dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
>> +}
>> +spin_unlock_irqrestore(>lock, flags);
>> +
>>  usb_del_gadget_udc(>gadget);
>>  dwc3_gadget_free_endpoints(dwc);
> 
> free endpoints is a better place for this. It's already going to free
> the memory anyway. Might as well clear all flags to 0 there.
> 

But it won't solve the deadlock issue. Since dwc3_gadget_free_endpoints()
is called after usb_del_gadget_udc() and the deadlock happens when

usb_del_gadget_udc()->udc_stop()->dwc3_gadget_stop()->wait_event_lock_irq()

and DWC3_EP_END_TRANSFER_PENDING flag is set.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: Prevent indefinite sleep in _dwc3_set_mode during suspend/resume

2018-02-28 Thread Roger Quadros
Hi Baolin,

On 28/02/18 05:04, Baolin Wang wrote:
> Hi Roger,
> 
> On 27 February 2018 at 19:22, Roger Quadros <rog...@ti.com> wrote:
>> In the following test we get stuck by sleeping forever in _dwc3_set_mode()
>> after which dual-role switching doesn't work.
>>
>> On dra7-evm's dual-role port,
>> - Load g_zero gadget driver and enumerate to host
>> - suspend to mem
>> - disconnect USB cable to host and connect otg cable with Pen drive in it.
>> - resume system
>> - we sleep indefinitely in _dwc3_set_mode due to.
>>   dwc3_gadget_exit()->usb_del_gadget_udc()->udc_stop()->
>> dwc3_gadget_stop()->wait_event_lock_irq()
>>
>> Let's clear the DWC3_EP_END_TRANSFER_PENDING flag on all endpoints
>> so we don't wait in dwc3_gadget_stop().
> 
> I am curious why the DWC3_DEPEVT_EPCMDCMPLT event was not triggered
> any more when you executed the DWC3_DEPCMD_ENDTRANSFER command?

In this particular case the USB gadget has been disconnected from the host so
we shouldn't be expecting any command completion events.

> 
>>
>> Signed-off-by: Roger Quadros <rog...@ti.com>
>> ---
>>  drivers/usb/dwc3/gadget.c | 14 ++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>> index 2bda4eb..0a360da 100644
>> --- a/drivers/usb/dwc3/gadget.c
>> +++ b/drivers/usb/dwc3/gadget.c
>> @@ -3273,6 +3273,20 @@ int dwc3_gadget_init(struct dwc3 *dwc)
>>
>>  void dwc3_gadget_exit(struct dwc3 *dwc)
>>  {
>> +   int epnum;
>> +   unsigned long flags;
>> +
>> +   spin_lock_irqsave(>lock, flags);
>> +   for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
>> +   struct dwc3_ep  *dep = dwc->eps[epnum];
>> +
>> +   if (!dep)
>> +   continue;
>> +
>> +   dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
>> +   }
>> +   spin_unlock_irqrestore(>lock, flags);
>> +
>> usb_del_gadget_udc(>gadget);
>> dwc3_gadget_free_endpoints(dwc);
>> dma_free_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE, dwc->bounce,
>> --
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


[PATCH v2 2/2] usb: dwc3: add dual role support using OTG block

2018-02-27 Thread Roger Quadros
This is useful on platforms (e.g. TI AM437x) that don't
have ID available on a GPIO but do have the OTG block.

We can obtain the ID state via the OTG block and use it
for dual-role switching.

Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/dwc3/core.c |  67 ++-
 drivers/usb/dwc3/core.h |  29 +++
 drivers/usb/dwc3/drd.c  | 489 ++--
 3 files changed, 557 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index df4569d..397a4d4 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -89,10 +89,7 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
return 0;
 }
 
-static void dwc3_event_buffers_cleanup(struct dwc3 *dwc);
-static int dwc3_event_buffers_setup(struct dwc3 *dwc);
-
-static void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
+void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
 {
u32 reg;
 
@@ -110,16 +107,19 @@ static void __dwc3_set_mode(struct work_struct *work)
unsigned long flags;
int ret;
 
-   if (!dwc->desired_dr_role)
+   if (dwc->dr_mode != USB_DR_MODE_OTG)
return;
 
-   if (dwc->desired_dr_role == dwc->current_dr_role)
+   if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG)
+   dwc3_otg_update(dwc, 0);
+
+   if (!dwc->desired_dr_role)
return;
 
-   if (dwc->dr_mode != USB_DR_MODE_OTG)
+   if (dwc->desired_dr_role == dwc->current_dr_role)
return;
 
-   if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG)
+   if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
return;
 
switch (dwc->current_dr_role) {
@@ -130,6 +130,13 @@ static void __dwc3_set_mode(struct work_struct *work)
dwc3_gadget_exit(dwc);
dwc3_event_buffers_cleanup(dwc);
break;
+   case DWC3_GCTL_PRTCAP_OTG:
+   dwc3_otg_exit(dwc);
+   spin_lock_irqsave(>lock, flags);
+   dwc->desired_otg_role = DWC3_OTG_ROLE_IDLE;
+   spin_unlock_irqrestore(>lock, flags);
+   dwc3_otg_update(dwc, 1);
+   break;
default:
break;
}
@@ -165,9 +172,14 @@ static void __dwc3_set_mode(struct work_struct *work)
if (ret)
dev_err(dwc->dev, "failed to initialize peripheral\n");
break;
+   case DWC3_GCTL_PRTCAP_OTG:
+   dwc3_otg_init(dwc);
+   dwc3_otg_update(dwc, 0);
+   break;
default:
break;
}
+
 }
 
 void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
@@ -351,7 +363,7 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, 
unsigned length)
  *
  * Returns 0 on success otherwise negative errno.
  */
-static int dwc3_event_buffers_setup(struct dwc3 *dwc)
+int dwc3_event_buffers_setup(struct dwc3 *dwc)
 {
struct dwc3_event_buffer*evt;
 
@@ -368,7 +380,7 @@ static int dwc3_event_buffers_setup(struct dwc3 *dwc)
return 0;
 }
 
-static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
+void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
 {
struct dwc3_event_buffer*evt;
 
@@ -1329,6 +1341,20 @@ static int dwc3_suspend_common(struct dwc3 *dwc, 
pm_message_t msg)
if (!PMSG_IS_AUTO(msg))
dwc3_core_exit(dwc);
break;
+   case DWC3_GCTL_PRTCAP_OTG:
+   /* do nothing during runtime_suspend */
+   if (PMSG_IS_AUTO(msg))
+   break;
+
+   if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) {
+   spin_lock_irqsave(>lock, flags);
+   dwc3_gadget_suspend(dwc);
+   spin_unlock_irqrestore(>lock, flags);
+   }
+
+   dwc3_otg_exit(dwc);
+   dwc3_core_exit(dwc);
+   break;
default:
/* do nothing */
break;
@@ -1360,6 +1386,27 @@ static int dwc3_resume_common(struct dwc3 *dwc, 
pm_message_t msg)
return ret;
}
break;
+   case DWC3_GCTL_PRTCAP_OTG:
+   /* nothing to do on runtime_resume */
+   if (PMSG_IS_AUTO(msg))
+   break;
+
+   ret = dwc3_core_init(dwc);
+   if (ret)
+   return ret;
+
+   dwc3_set_prtcap(dwc, dwc->current_dr_role);
+
+   dwc3_otg_init(dwc);
+   if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST) {
+   dwc3_otg_host_init(dwc);
+   } else if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) {
+   spin_lock_irqsave(>lock, flags);
+   dwc3_gadget_resume(dwc);
+  

[PATCH v2 1/2] usb: dwc3: core.h: add some register definitions

2018-02-27 Thread Roger Quadros
Add OTG and GHWPARAMS6 register definitions

Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/dwc3/core.h | 82 +
 1 file changed, 82 insertions(+)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 860d2bc..0d4c698 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -201,6 +201,15 @@
 #define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28)
 #define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW  BIT(24)
 
+/* Global Status Register */
+#define DWC3_GSTS_OTG_IP   BIT(10)
+#define DWC3_GSTS_BC_IPBIT(9)
+#define DWC3_GSTS_ADP_IP   BIT(8)
+#define DWC3_GSTS_HOST_IP  BIT(7)
+#define DWC3_GSTS_DEVICE_IPBIT(6)
+#define DWC3_GSTS_CSR_TIMEOUT  BIT(5)
+#define DWC3_GSTS_BUS_ERR_ADDR_VLD BIT(4)
+
 /* Global USB2 PHY Configuration Register */
 #define DWC3_GUSB2PHYCFG_PHYSOFTRSTBIT(31)
 #define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS BIT(30)
@@ -286,6 +295,11 @@
 #define DWC3_MAX_HIBER_SCRATCHBUFS 15
 
 /* Global HWPARAMS6 Register */
+#define DWC3_GHWPARAMS6_BCSUPPORT  BIT(14)
+#define DWC3_GHWPARAMS6_OTG3SUPPORTBIT(13)
+#define DWC3_GHWPARAMS6_ADPSUPPORT BIT(12)
+#define DWC3_GHWPARAMS6_HNPSUPPORT BIT(11)
+#define DWC3_GHWPARAMS6_SRPSUPPORT BIT(10)
 #define DWC3_GHWPARAMS6_EN_FPGABIT(7)
 
 /* Global HWPARAMS7 Register */
@@ -467,6 +481,74 @@
 #define DWC3_DEV_IMOD_INTERVAL_SHIFT   0
 #define DWC3_DEV_IMOD_INTERVAL_MASK(0x << 0)
 
+/* OTG Configuration Register */
+#define DWC3_OCFG_DISPWRCUTTOFFBIT(5)
+#define DWC3_OCFG_HIBDISMASK   BIT(4)
+#define DWC3_OCFG_SFTRSTMASK   BIT(3)
+#define DWC3_OCFG_OTGVERSION   BIT(2)
+#define DWC3_OCFG_HNPCAP   BIT(1)
+#define DWC3_OCFG_SRPCAP   BIT(0)
+
+/* OTG CTL Register */
+#define DWC3_OCTL_OTG3GOERRBIT(7)
+#define DWC3_OCTL_PERIMODE BIT(6)
+#define DWC3_OCTL_PRTPWRCTLBIT(5)
+#define DWC3_OCTL_HNPREQ   BIT(4)
+#define DWC3_OCTL_SESREQ   BIT(3)
+#define DWC3_OCTL_TERMSELIDPULSE   BIT(2)
+#define DWC3_OCTL_DEVSETHNPEN  BIT(1)
+#define DWC3_OCTL_HSTSETHNPEN  BIT(0)
+
+/* OTG Event Register */
+#define DWC3_OEVT_DEVICEMODE   BIT(31)
+#define DWC3_OEVT_XHCIRUNSTPSETBIT(27)
+#define DWC3_OEVT_DEVRUNSTPSET BIT(26)
+#define DWC3_OEVT_HIBENTRY BIT(25)
+#define DWC3_OEVT_CONIDSTSCHNG BIT(24)
+#define DWC3_OEVT_HRRCONFNOTIF BIT(23)
+#define DWC3_OEVT_HRRINITNOTIF BIT(22)
+#define DWC3_OEVT_ADEVIDLE BIT(21)
+#define DWC3_OEVT_ADEVBHOSTEND BIT(20)
+#define DWC3_OEVT_ADEVHOST BIT(19)
+#define DWC3_OEVT_ADEVHNPCHNG  BIT(18)
+#define DWC3_OEVT_ADEVSRPDET   BIT(17)
+#define DWC3_OEVT_ADEVSESSENDDET   BIT(16)
+#define DWC3_OEVT_BDEVBHOSTEND BIT(11)
+#define DWC3_OEVT_BDEVHNPCHNG  BIT(10)
+#define DWC3_OEVT_BDEVSESSVLDDET   BIT(9)
+#define DWC3_OEVT_BDEVVBUSCHNG BIT(8)
+#define DWC3_OEVT_BSESSVLD BIT(3)
+#define DWC3_OEVT_HSTNEGSTSBIT(2)
+#define DWC3_OEVT_SESREQSTSBIT(1)
+#define DWC3_OEVT_ERRORBIT(0)
+
+/* OTG Event Enable Register */
+#define DWC3_OEVTEN_XHCIRUNSTPSETENBIT(27)
+#define DWC3_OEVTEN_DEVRUNSTPSETEN BIT(26)
+#define DWC3_OEVTEN_HIBENTRYEN BIT(25)
+#define DWC3_OEVTEN_CONIDSTSCHNGEN BIT(24)
+#define DWC3_OEVTEN_HRRCONFNOTIFEN BIT(23)
+#define DWC3_OEVTEN_HRRINITNOTIFEN BIT(22)
+#define DWC3_OEVTEN_ADEVIDLEEN BIT(21)
+#define DWC3_OEVTEN_ADEVBHOSTENDEN BIT(20)
+#define DWC3_OEVTEN_ADEVHOSTEN BIT(19)
+#define DWC3_OEVTEN_ADEVHNPCHNGEN  BIT(18)
+#define DWC3_OEVTEN_ADEVSRPDETEN   BIT(17)
+#define DWC3_OEVTEN_ADEVSESSENDDETEN   BIT(16)
+#define DWC3_OEVTEN_BDEVBHOSTENDEN BIT(11)
+#define DWC3_OEVTEN_BDEVHNPCHNGEN  BIT(10)
+#define DWC3_OEVTEN_BDEVSESSVLDDETEN   BIT(9)
+#define DWC3_OEVTEN_BDEVVBUSCHNGEN BIT(8)
+
+/* OTG Status Register */
+#define DWC3_OSTS_DEVRUNSTPBIT(13)
+#define DWC3_OSTS_XHCIRUNSTP   BIT(12)
+#define DWC3_OSTS_PERIPHERALSTATE  BIT(4)
+#define DWC3_OSTS_XHCIPRTPOWER BIT(3)
+#define DWC3_OSTS_BSESVLD  BIT(2)
+#define DWC3_OSTS_VBUSVLD  BIT(1)
+#define DWC3_OSTS_CONIDSTS BIT(0)
+
 /* Structures */
 
 struct dwc3_trb;
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


[PATCH v2 0/2] usb: dwc3: Add dual-role support using OTG core

2018-02-27 Thread Roger Quadros
Hi Felipe,

Some platforms (e.g. TI's AM437x) don't have USB ID pin state available
over GPIO/extcon but need to rely on the DWC3 core's OTG block to
get the ID pin state instead.

This series implements simple dual-role functionality using DWC3's OTG block.
Debugfs 'mode' override is also functional so user can switch
between "otg", "host" or "device" modes for debug.

Although system suspend/resume isn't working yet in mainline for AM437x,
I've tested this series for system suspend/resume using a local tree.

Roger Quadros (2):
  usb: dwc3: core.h: add some register definitions
  usb: dwc3: add dual role support using OTG block

 drivers/usb/dwc3/core.c |  67 ++-
 drivers/usb/dwc3/core.h | 111 +++
 drivers/usb/dwc3/drd.c  | 489 ++--
 3 files changed, 639 insertions(+), 28 deletions(-)

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


[PATCH] usb: dwc3: Prevent indefinite sleep in _dwc3_set_mode during suspend/resume

2018-02-27 Thread Roger Quadros
In the following test we get stuck by sleeping forever in _dwc3_set_mode()
after which dual-role switching doesn't work.

On dra7-evm's dual-role port,
- Load g_zero gadget driver and enumerate to host
- suspend to mem
- disconnect USB cable to host and connect otg cable with Pen drive in it.
- resume system
- we sleep indefinitely in _dwc3_set_mode due to.
  dwc3_gadget_exit()->usb_del_gadget_udc()->udc_stop()->
dwc3_gadget_stop()->wait_event_lock_irq()

Let's clear the DWC3_EP_END_TRANSFER_PENDING flag on all endpoints
so we don't wait in dwc3_gadget_stop().

Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/dwc3/gadget.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 2bda4eb..0a360da 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -3273,6 +3273,20 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 
 void dwc3_gadget_exit(struct dwc3 *dwc)
 {
+   int epnum;
+   unsigned long flags;
+
+   spin_lock_irqsave(>lock, flags);
+   for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
+   struct dwc3_ep  *dep = dwc->eps[epnum];
+
+   if (!dep)
+   continue;
+
+   dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
+   }
+   spin_unlock_irqrestore(>lock, flags);
+
usb_del_gadget_udc(>gadget);
dwc3_gadget_free_endpoints(dwc);
dma_free_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE, dwc->bounce,
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


[PATCH] usb: dwc3: prevent setting PRTCAP to OTG from debugfs

2018-02-27 Thread Roger Quadros
We don't support PRTCAP == OTG yet, so prevent user from
setting it via debugfs.

Fixes: 41ce1456e1db ("usb: dwc3: core: make dwc3_set_mode() work properly")
Cc: <sta...@vger.kernel.org> # v4.12+
Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/dwc3/core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index e94bf91..df4569d 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -119,6 +119,9 @@ static void __dwc3_set_mode(struct work_struct *work)
if (dwc->dr_mode != USB_DR_MODE_OTG)
return;
 
+   if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG)
+   return;
+
switch (dwc->current_dr_role) {
case DWC3_GCTL_PRTCAP_HOST:
dwc3_host_exit(dwc);
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


[PATCH] usb: dwc3: Fix lock-up on ID change during system suspend/resume

2018-02-27 Thread Roger Quadros
To reproduce the lock up do the following
- connect otg host adapter and a USB device to the dual-role port
so that it is in host mode.
- suspend to mem.
- disconnect otg adapter.
- resume the system.

If we call dwc3_host_exit() before tasks are thawed
xhci_plat_remove() seems to lock up at the second usb_remove_hcd() call.

To work around this we queue the _dwc3_set_mode() work on
the system_freezable_wq.

Fixes: 41ce1456e1db ("usb: dwc3: core: make dwc3_set_mode() work properly")
Cc: <sta...@vger.kernel.org> # v4.12+
Suggested-by: Manu Gautam <mgau...@codeaurora.org>
Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/dwc3/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index f1d838a..e94bf91 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -175,7 +175,7 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
dwc->desired_dr_role = mode;
spin_unlock_irqrestore(>lock, flags);
 
-   queue_work(system_power_efficient_wq, >drd_work);
+   queue_work(system_freezable_wq, >drd_work);
 }
 
 u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type)
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


Re: [PATCH RFC] ehci-omap: simple suspend implementation

2018-02-26 Thread Roger Quadros
Andreas,

On 26/02/18 09:04, Andreas Kemnade wrote:
> Hi,
> 
> On Mon, 19 Feb 2018 11:41:36 +0200
> Roger Quadros <rog...@ti.com> wrote:
> 
>> Andreas,
>>
>> On 16/02/18 20:35, Andreas Kemnade wrote:
>>> On Fri, 16 Feb 2018 13:13:11 -0500 (EST)
>>> Alan Stern <st...@rowland.harvard.edu> wrote:
>>>   
>>>> On Fri, 16 Feb 2018, Andreas Kemnade wrote:
>>>>  
>>>>> This powers down the phy and on a gta04 it reduces
>>>>> suspend current by 13 mA.
>>>>> For unknown reasons usb does not power on properly.
>>>>> Also calling usb_phy_shutdown() here feels wrong
>>>>> apparently the reset line has to be activated.
>>>>> usb_phy_set_suspend is not enough here. The power
>>>>> consumption still stays approximately the same as
>>>>> without any patch.
>>>>>
>>>>> With a device connected the device does not enumerate
>>>>> after resume. A rmmod ehci-omap ; modprobe ehci-omap
>>>>> does not make it reenumerade.
>>>>> So there is still something wrong here.
>>>>>
>>>>> Signed-off-by: Andreas Kemnade <andr...@kemnade.info>
>>>>> ---
>>>>>  drivers/usb/host/ehci-omap.c | 59 
>>>>> ++--
>>>>>  1 file changed, 57 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
>>>>> index 8d8bafc70c1f..0be2ccf8182a 100644
>>>>> --- a/drivers/usb/host/ehci-omap.c
>>>>> +++ b/drivers/usb/host/ehci-omap.c
>>>>> @@ -266,6 +266,58 @@ static int ehci_hcd_omap_remove(struct 
>>>>> platform_device *pdev)
>>>>>   return 0;
>>>>>  }
>>>>>  
>>>>> +
>>>>> +static int __maybe_unused ehci_omap_suspend(struct device *dev)
>>>>> +{
>>>>> + struct usb_hcd *hcd = dev_get_drvdata(dev);
>>>>> + struct omap_hcd *omap = (struct omap_hcd *)hcd_to_ehci(hcd)->priv;
>>>>> + int ret;
>>>>> + int i;
>>>>> +
>>>>> + ret = ehci_suspend(hcd, false);
>>>>> + if (ret) {
>>>>> + dev_err(dev, "ehci suspend failed: %d\n", ret);
>>>>> + return ret;
>>>>> + }
>>>>> + for (i = 0; i < omap->nports; i++) {
>>>>> + if (omap->phy[i])
>>>>> + usb_phy_shutdown(omap->phy[i]);
>>>>> + }
>>>>> + pm_runtime_put_sync(dev);
>>>>
>>>> Why do you include a runtime PM call here, given that the driver
>>>> doesn't support runtime suspend or resume?
>>>>  
>>> Well, the parent (drivers/mfd/omap-usb-host.c) has, and there are runtime PM
>>> calls here in the _probe/_remove functions, so it seems to be sane to do it
>>> here, too.
>>>
>>>   
>>>>> +
>>>>> + return 0;
>>>>> +}
>>>>> +
>>>>> +static int __maybe_unused ehci_omap_resume(struct device *dev)
>>>>> +{
>>>>> + struct usb_hcd *hcd = dev_get_drvdata(dev);
>>>>> + struct omap_hcd *omap = (struct omap_hcd *)hcd_to_ehci(hcd)->priv;
>>>>> + int i;
>>>>> +
>>>>> + pm_runtime_get_sync(dev);
>>>>> + /*
>>>>> +  * An undocumented "feature" in the OMAP3 EHCI controller,
>>>>> +  * causes suspended ports to be taken out of suspend when
>>>>> +  * the USBCMD.Run/Stop bit is cleared (for example when
>>>>> +  * we do ehci_bus_suspend).
>>>>> +  * This breaks suspend-resume if the root-hub is allowed
>>>>> +  * to suspend. Writing 1 to this undocumented register bit
>>>>> +  * disables this feature and restores normal behavior.
>>>>> +  */
>>>>> + ehci_write(hcd->regs, EHCI_INSNREG04,
>>>>> +EHCI_INSNREG04_DISABLE_UNSUSPEND);
>>>>
>>>> Doesn't this code belong in ehci_hcd_omap_probe()?  I assume you only
>>>> need to set this undocumented bit once, not every time the controller
>>>> is suspended.  And in any case, according to the comment, you would
>>>> need to take care of this before the root hub is suspended -- by the
>>>> time the controller is suspended, it is alrea

Re: [PATCH v2] usb: host: ehci-platform: add support for optional external vbus supply

2018-02-20 Thread Roger Quadros
On 20/02/18 16:46, Amelie DELAUNAY wrote:
> Hi,
> 
> On 02/20/2018 03:00 PM, Roger Quadros wrote:
>> Hi,
>>
>> On 20/02/18 14:58, Amelie Delaunay wrote:
>>> On some boards, especially when vbus supply requires large current,
>>> and the charge pump on the PHY isn't enough, an external vbus power switch
>>> may be used.
>>> Add support for this optional external vbus supply in ehci-platform.
>>>
>>> Signed-off-by: Amelie Delaunay <amelie.delau...@st.com>
>>>
>>> ---
>>> Changes in v2:
>>>   * Address Roger Quadros comments: move regulator_enable/disable from
>>> ehci_platform_power_on/off to ehci_platform_port_power.
>>> ---
>>>   Documentation/devicetree/bindings/usb/usb-ehci.txt |  1 +
>>>   drivers/usb/host/ehci-platform.c   | 31 
>>> ++
>>>   2 files changed, 32 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt 
>>> b/Documentation/devicetree/bindings/usb/usb-ehci.txt
>>> index 3efde12..fc480cd 100644
>>> --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt
>>> +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt
>>> @@ -19,6 +19,7 @@ Optional properties:
>>>- phys : phandle + phy specifier pair
>>>- phy-names : "usb"
>>>- resets : phandle + reset specifier pair
>>> + - vbus-supply : phandle of regulator supplying vbus
>>>   
>>
>> Can platforms have more than one regulator e.g. one regulator per port?
>>
> 
> I imagine that yes, platforms could have one regulator per port.
> Regulator consumers bindings impose a -supply property per 
> regulator, so, what do you think about :
> vbus0-supply for port#0
> vbus1-supply for port#1
> ...
> vbusN-supply for port#N
> 
> And then in probe, allocate 'struct regulator *vbus_supplies' with a 
> size corresponding to 'HCS_N_PORTS(ehci->hcs_params) * sizeof(struct 
> regulator *)'.
> And loop to get optional regulator vbus0, vbus1,..., vbusN.
> And then enable/disable the corresponding regulator in 
> ehci_platform_port_power thanks to portnum.

Looks fine to me but we need to get Alan's opinion if this is worth the effort.
If there isn't a single platform needing it we could probably do without it
but the DT binding must be scalable to add this feature in the future.

And what if it is ganged power? i.e. one regulator for more than one port.
Probably they all can point to the same regulator instance and it should work.

> 
>>>   Example (Sequoia 440EPx):
>>>   ehci@e300 {
>>> diff --git a/drivers/usb/host/ehci-platform.c 
>>> b/drivers/usb/host/ehci-platform.c
>>> index b065a96..05be100 100644
>>> --- a/drivers/usb/host/ehci-platform.c
>>> +++ b/drivers/usb/host/ehci-platform.c
>>> @@ -29,6 +29,7 @@
>>>   #include 
>>>   #include 
>>>   #include 
>>> +#include 
>>>   #include 
>>>   #include 
>>>   #include 
>>> @@ -46,6 +47,7 @@ struct ehci_platform_priv {
>>> struct reset_control *rsts;
>>> struct phy **phys;
>>> int num_phys;
>>> +   struct regulator *vbus_supply;
>>> bool reset_on_resume;
>>>   };
>>>   
>>> @@ -76,6 +78,25 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
>>> return 0;
>>>   }
>>>   
>>> +static int ehci_platform_port_power(struct usb_hcd *hcd, int portnum,
>>> +   bool enable)
>>> +{
>>> +   struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
>>> +   int ret = 0;
>>> +
>>> +   if (priv->vbus_supply) {
>>> +   if (enable)
>>> +   ret = regulator_enable(priv->vbus_supply);
>>> +   else
>>> +   ret = regulator_disable(priv->vbus_supply);
>>> +   if (ret)
>>> +   dev_err(hcd->self.controller,
>>> +   "failed to %s vbus supply: %d\n",
>>> +   enable ? "enable" : "disable", ret);
>>> +   }
>>> +   return ret;
>>> +}
>>> +
>>>   static int ehci_platform_power_on(struct platform_device *dev)
>>>   {
>>> struct usb_hcd *hcd = platform_get_drvdata(dev);
>>> @@ -134,6 +155,7 @@ static struct hc_driver __read_mostly 
>>> ehci_platform_hc_driver;
>>>   static const struct ehci_driver_overrides platform_overrides __initc

Re: [PATCH v2] usb: host: ehci-platform: add support for optional external vbus supply

2018-02-20 Thread Roger Quadros
Hi,

On 20/02/18 14:58, Amelie Delaunay wrote:
> On some boards, especially when vbus supply requires large current,
> and the charge pump on the PHY isn't enough, an external vbus power switch
> may be used.
> Add support for this optional external vbus supply in ehci-platform.
> 
> Signed-off-by: Amelie Delaunay <amelie.delau...@st.com>
> 
> ---
> Changes in v2:
>  * Address Roger Quadros comments: move regulator_enable/disable from
> ehci_platform_power_on/off to ehci_platform_port_power.
> ---
>  Documentation/devicetree/bindings/usb/usb-ehci.txt |  1 +
>  drivers/usb/host/ehci-platform.c   | 31 
> ++
>  2 files changed, 32 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt 
> b/Documentation/devicetree/bindings/usb/usb-ehci.txt
> index 3efde12..fc480cd 100644
> --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt
> +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt
> @@ -19,6 +19,7 @@ Optional properties:
>   - phys : phandle + phy specifier pair
>   - phy-names : "usb"
>   - resets : phandle + reset specifier pair
> + - vbus-supply : phandle of regulator supplying vbus
>  

Can platforms have more than one regulator e.g. one regulator per port?

>  Example (Sequoia 440EPx):
>  ehci@e300 {
> diff --git a/drivers/usb/host/ehci-platform.c 
> b/drivers/usb/host/ehci-platform.c
> index b065a96..05be100 100644
> --- a/drivers/usb/host/ehci-platform.c
> +++ b/drivers/usb/host/ehci-platform.c
> @@ -29,6 +29,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -46,6 +47,7 @@ struct ehci_platform_priv {
>   struct reset_control *rsts;
>   struct phy **phys;
>   int num_phys;
> + struct regulator *vbus_supply;
>   bool reset_on_resume;
>  };
>  
> @@ -76,6 +78,25 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
>   return 0;
>  }
>  
> +static int ehci_platform_port_power(struct usb_hcd *hcd, int portnum,
> + bool enable)
> +{
> + struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
> + int ret = 0;
> +
> + if (priv->vbus_supply) {
> + if (enable)
> + ret = regulator_enable(priv->vbus_supply);
> + else
> + ret = regulator_disable(priv->vbus_supply);
> + if (ret)
> + dev_err(hcd->self.controller,
> + "failed to %s vbus supply: %d\n",
> + enable ? "enable" : "disable", ret);
> + }
> + return ret;
> +}
> +
>  static int ehci_platform_power_on(struct platform_device *dev)
>  {
>   struct usb_hcd *hcd = platform_get_drvdata(dev);
> @@ -134,6 +155,7 @@ static struct hc_driver __read_mostly 
> ehci_platform_hc_driver;
>  static const struct ehci_driver_overrides platform_overrides __initconst = {
>   .reset =ehci_platform_reset,
>   .extra_priv_size =  sizeof(struct ehci_platform_priv),
> + .port_power =   ehci_platform_port_power,
>  };
>  
>  static struct usb_ehci_pdata ehci_platform_defaults = {
> @@ -247,6 +269,15 @@ static int ehci_platform_probe(struct platform_device 
> *dev)
>   if (err)
>   goto err_put_clks;
>  
> + priv->vbus_supply = devm_regulator_get_optional(>dev, "vbus");
> + if (IS_ERR(priv->vbus_supply)) {
> + err = PTR_ERR(priv->vbus_supply);
> + if (err == -ENODEV)
> + priv->vbus_supply = NULL;
> + else
> + goto err_reset;
> + }
> +
>   if (pdata->big_endian_desc)
>   ehci->big_endian_desc = 1;
>   if (pdata->big_endian_mmio)
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: host: ehci-platform: add support for optional external vbus supply

2018-02-20 Thread Roger Quadros
Hi,

On 20/02/18 11:11, Amelie Delaunay wrote:
> On some boards, especially when vbus supply requires large current,
> and the charge pump on the PHY isn't enough, an external vbus power switch
> may be used.
> Add support for this optional external vbus supply in ehci-platform.

Isn't this generic enough to be done for all *hci-platform drivers?

And if this is a VBUS supply to the port, the root hub driver should be 
controlling it
based on port power on/off commands to the port right?

> 
> Signed-off-by: Amelie Delaunay 
> ---
>  Documentation/devicetree/bindings/usb/usb-ehci.txt |  1 +
>  drivers/usb/host/ehci-platform.c   | 23 
> ++
>  2 files changed, 24 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt 
> b/Documentation/devicetree/bindings/usb/usb-ehci.txt
> index 3efde12..fc480cd 100644
> --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt
> +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt
> @@ -19,6 +19,7 @@ Optional properties:
>   - phys : phandle + phy specifier pair
>   - phy-names : "usb"
>   - resets : phandle + reset specifier pair
> + - vbus-supply : phandle of regulator supplying vbus
>  
>  Example (Sequoia 440EPx):
>  ehci@e300 {
> diff --git a/drivers/usb/host/ehci-platform.c 
> b/drivers/usb/host/ehci-platform.c
> index b065a96..76cc781 100644
> --- a/drivers/usb/host/ehci-platform.c
> +++ b/drivers/usb/host/ehci-platform.c
> @@ -29,6 +29,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -46,6 +47,7 @@ struct ehci_platform_priv {
>   struct reset_control *rsts;
>   struct phy **phys;
>   int num_phys;
> + struct regulator *vbus_supply;
>   bool reset_on_resume;
>  };
>  
> @@ -99,6 +101,15 @@ static int ehci_platform_power_on(struct platform_device 
> *dev)
>   }
>   }
>  
> + if (priv->vbus_supply) {
> + ret = regulator_enable(priv->vbus_supply);
> + if (ret) {
> + dev_err(>dev,
> + "failed to enable vbus supply: %d\n", ret);
> + goto err_exit_phy;
> + }
> + }
> +
>   return 0;
>  
>  err_exit_phy:
> @@ -119,6 +130,9 @@ static void ehci_platform_power_off(struct 
> platform_device *dev)
>   struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
>   int clk, phy_num;
>  
> + if (priv->vbus_supply)
> + regulator_disable(priv->vbus_supply);
> +

If we disable the VBUS here, which is being called during 
ehci_platform_suspend(),
how can we expect remote wakeup to work?
This is unconditionally powering down the port.

>   for (phy_num = 0; phy_num < priv->num_phys; phy_num++) {
>   phy_power_off(priv->phys[phy_num]);
>   phy_exit(priv->phys[phy_num]);
> @@ -247,6 +261,15 @@ static int ehci_platform_probe(struct platform_device 
> *dev)
>   if (err)
>   goto err_put_clks;
>  
> + priv->vbus_supply = devm_regulator_get_optional(>dev, "vbus");
> + if (IS_ERR(priv->vbus_supply)) {
> + err = PTR_ERR(priv->vbus_supply);
> + if (err == -ENODEV)
> + priv->vbus_supply = NULL;
> + else
> + goto err_reset;
> + }
> +
>   if (pdata->big_endian_desc)
>   ehci->big_endian_desc = 1;
>   if (pdata->big_endian_mmio)
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH RFC] ehci-omap: simple suspend implementation

2018-02-19 Thread Roger Quadros
Andreas,

On 16/02/18 20:35, Andreas Kemnade wrote:
> On Fri, 16 Feb 2018 13:13:11 -0500 (EST)
> Alan Stern  wrote:
> 
>> On Fri, 16 Feb 2018, Andreas Kemnade wrote:
>>
>>> This powers down the phy and on a gta04 it reduces
>>> suspend current by 13 mA.
>>> For unknown reasons usb does not power on properly.
>>> Also calling usb_phy_shutdown() here feels wrong
>>> apparently the reset line has to be activated.
>>> usb_phy_set_suspend is not enough here. The power
>>> consumption still stays approximately the same as
>>> without any patch.
>>>
>>> With a device connected the device does not enumerate
>>> after resume. A rmmod ehci-omap ; modprobe ehci-omap
>>> does not make it reenumerade.
>>> So there is still something wrong here.
>>>
>>> Signed-off-by: Andreas Kemnade 
>>> ---
>>>  drivers/usb/host/ehci-omap.c | 59 
>>> ++--
>>>  1 file changed, 57 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
>>> index 8d8bafc70c1f..0be2ccf8182a 100644
>>> --- a/drivers/usb/host/ehci-omap.c
>>> +++ b/drivers/usb/host/ehci-omap.c
>>> @@ -266,6 +266,58 @@ static int ehci_hcd_omap_remove(struct platform_device 
>>> *pdev)
>>> return 0;
>>>  }
>>>  
>>> +
>>> +static int __maybe_unused ehci_omap_suspend(struct device *dev)
>>> +{
>>> +   struct usb_hcd *hcd = dev_get_drvdata(dev);
>>> +   struct omap_hcd *omap = (struct omap_hcd *)hcd_to_ehci(hcd)->priv;
>>> +   int ret;
>>> +   int i;
>>> +
>>> +   ret = ehci_suspend(hcd, false);
>>> +   if (ret) {
>>> +   dev_err(dev, "ehci suspend failed: %d\n", ret);
>>> +   return ret;
>>> +   }
>>> +   for (i = 0; i < omap->nports; i++) {
>>> +   if (omap->phy[i])
>>> +   usb_phy_shutdown(omap->phy[i]);
>>> +   }
>>> +   pm_runtime_put_sync(dev);  
>>
>> Why do you include a runtime PM call here, given that the driver
>> doesn't support runtime suspend or resume?
>>
> Well, the parent (drivers/mfd/omap-usb-host.c) has, and there are runtime PM
> calls here in the _probe/_remove functions, so it seems to be sane to do it
> here, too.
> 
> 
>>> +
>>> +   return 0;
>>> +}
>>> +
>>> +static int __maybe_unused ehci_omap_resume(struct device *dev)
>>> +{
>>> +   struct usb_hcd *hcd = dev_get_drvdata(dev);
>>> +   struct omap_hcd *omap = (struct omap_hcd *)hcd_to_ehci(hcd)->priv;
>>> +   int i;
>>> +
>>> +   pm_runtime_get_sync(dev);
>>> +   /*
>>> +* An undocumented "feature" in the OMAP3 EHCI controller,
>>> +* causes suspended ports to be taken out of suspend when
>>> +* the USBCMD.Run/Stop bit is cleared (for example when
>>> +* we do ehci_bus_suspend).
>>> +* This breaks suspend-resume if the root-hub is allowed
>>> +* to suspend. Writing 1 to this undocumented register bit
>>> +* disables this feature and restores normal behavior.
>>> +*/
>>> +   ehci_write(hcd->regs, EHCI_INSNREG04,
>>> +  EHCI_INSNREG04_DISABLE_UNSUSPEND);  
>>
>> Doesn't this code belong in ehci_hcd_omap_probe()?  I assume you only
>> need to set this undocumented bit once, not every time the controller
>> is suspended.  And in any case, according to the comment, you would
>> need to take care of this before the root hub is suspended -- by the
>> time the controller is suspended, it is already too late.
>>
>  
> I am not really sure about this one. It is set in ehci_hcd_omap_probe()
> so it is set before suspend. I set it here to ensure it is re-set when
> the controller is powered down too much to keep register contents. I
> do not know if that is the case. But I thought it would not harm.
> 

If the Hardware SAR (Save and restore) functionality is enabled then
everything will be restored by hardware after a sleep to wake transition.

But you will need this patch to enable SAR for the USB power domain.
https://lkml.org/lkml/2013/7/10/356

Missing this might be the reason why things break for you after a system
suspend/resume.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH 2/2] usb: dwc3: drd: Fix lock-up on ID change during system suspend/resume

2018-02-14 Thread Roger Quadros
Felipe,

On 25/01/18 18:11, Roger Quadros wrote:
> Hi,
> 
> On 24/01/18 14:19, Roger Quadros wrote:
>> On 23/01/18 14:41, Roger Quadros wrote:
>>> Hi Manu,
>>>
>>> On 23/01/18 05:45, Manu Gautam wrote:
>>>> Hi,
>>>>
>>>>
>>>> On 1/22/2018 6:31 PM, Roger Quadros wrote:
>>>>> Adding/removing host/gadget controller before .pm_complete()
>>>>> causes a lock-up. Let's prevent any dual-role state change
>>>>> between .pm_prepare() and .pm_complete() to fix this.
>>>>
>>>> What kind of lock-up are you seeing? Some hardware lockup or software 
>>>> deadlock?
>>>> IMO using a freezable_wq for drd_work should address that?
>>>>
>>>
>>> I was seeing a software deadlock. freezable_wq is a good idea. I'll try it 
>>> out.
>>
>> using freezable_wq doesn't get rid of the deadlock.
>> If I use freezable_wq plus add some delay before I do a dwc3_host_init()
>> in the work function then it starts to work.
>>
>> As dependence on delay looks fragile so I'll stick to the current 
>> implementation
>> based on .pm_prepare/complete().
>>
> 
> So I was able to reproduce the lock up with my series as well. On further 
> investigation
> this is what I see.
> 
> There are 2 different scenarios.
> 
> 1) controller in host mode prior to system suspend and switches to device 
> mode during resume.
> 
> In this case when we call dwc3_host_exit() before tasks are thawed
> xhci_plat_remove() seems to lock up at the second usb_remove_hcd() call.
> This issue is resolved by using system_freezable_wq for the _dwc3_set_mode() 
> function.
> 
> 
> 2) controller in device mode prior to system suspend and switches to host 
> mode during resume.
> 
> In this case we sleep indefinitely in _dwc3_set_mode due to
> dwc3_set_mode()->dwc3_gadget_exit()->usb_del_gadget_udc()->udc_stop()->dwc3_gadget_stop()->wait_event_lock_irq()
> 
> This is not resolved by moving the dwc3_set_mode() call to .pm_complete() nor 
> via the system_freezable_wq.
> 
> One way I could fix this is like so.
> 
> Felipe, could you please suggest a better way?
> Maybe we need to do this in dwc3_gadget_exit() before calling 
> usb_del_gadget_udc() ?

Once you let me know your opinion I can revise this series. Thanks.

> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index b417d9a..0c903c1 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -109,6 +109,7 @@ static void __dwc3_set_mode(struct work_struct *work)
>   struct dwc3 *dwc = work_to_dwc(work);
>   unsigned long flags;
>   int ret;
> + int epnum;
>  
>   if (!dwc->desired_dr_role)
>   return;
> @@ -124,6 +125,17 @@ static void __dwc3_set_mode(struct work_struct *work)
>   dwc3_host_exit(dwc);
>   break;
>   case DWC3_GCTL_PRTCAP_DEVICE:
> + spin_lock_irqsave(>lock, flags);
> + for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
> + struct dwc3_ep  *dep = dwc->eps[epnum];
> +
> + if (!dep)
> + continue;
> +
> + dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
> + }
> + spin_unlock_irqrestore(>lock, flags);
> +
>   dwc3_gadget_exit(dwc);
>   dwc3_event_buffers_cleanup(dwc);
>   break;
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH 0/4] usb: dwc3: Add dual-role support using OTG core

2018-02-14 Thread Roger Quadros
Hi Felipe,

On 22/01/18 15:11, Roger Quadros wrote:
> Hi Felipe,
> 
> Some platforms (e.g. TI's AM437x) don't have USB ID pin state available
> over GPIO/extcon but need to rely on the DWC3 core's OTG block to
> get the ID pin state instead.
> 
> This series implements simple dual-role functionality using DWC3's OTG block.
> Debugfs 'mode' override is also functional so user can switch
> between "otg", "host" or "device" modes for debug.
> 
> Although system suspend/resume isn't working yet in mainline for AM437x,
> I've tested this series for system suspend/resume using a local tree.

Any comments on this series?

> 
> This series depends on [1] and [2]
> 
> [1] https://www.mail-archive.com/linux-usb@vger.kernel.org/msg98771.html
> 
> [2] https://www.mail-archive.com/linux-usb@vger.kernel.org/msg98848.html
> 
> Roger Quadros (4):
>   usb: dwc3: prevent setting PRTCAP to OTG from debugfs
>   usb: dwc3: core.h: add some register definitions
>   usb: dwc3: add dual role support using OTG block
>   ARM: dts: am43xx: Enable dual-role mode for USB1
> 
>  arch/arm/boot/dts/am437x-gp-evm.dts  |   2 +-
>  arch/arm/boot/dts/am437x-sk-evm.dts  |   2 +-
>  arch/arm/boot/dts/am43x-epos-evm.dts |   2 +-
>  drivers/usb/dwc3/core.c  |  70 -
>  drivers/usb/dwc3/core.h  | 111 
>  drivers/usb/dwc3/drd.c   | 492 
> +--
>  6 files changed, 650 insertions(+), 29 deletions(-)
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


[PATCH v2 RESEND] usb: dwc3: core: Fix ULPI PHYs and prevent phy_get/ulpi_init during suspend/resume

2018-02-12 Thread Roger Quadros
In order for ULPI PHYs to work, dwc3_phy_setup() and dwc3_ulpi_init()
must be doene before dwc3_core_get_phy().

commit 541768b08a40 ("usb: dwc3: core: Call dwc3_core_get_phy() before 
initializing phys")
broke this.

The other issue is that dwc3_core_get_phy() and dwc3_ulpi_init() should
be called only once during the life cycle of the driver. However,
as dwc3_core_init() is called during system suspend/resume it will
result in multiple calls to dwc3_core_get_phy() and dwc3_ulpi_init()
which is wrong.

Fix this by moving dwc3_ulpi_init() out of dwc3_phy_setup()
into dwc3_core_ulpi_init(). Use a flag 'ulpi_ready' to ensure that
dwc3_core_ulpi_init() is called only once from dwc3_core_init().

Use another flag 'phys_ready' to call dwc3_core_get_phy() only once from
dwc3_core_init().

Fixes: 541768b08a40 ("usb: dwc3: core: Call dwc3_core_get_phy() before 
initializing phys")
Fixes: f54edb539c11 ("usb: dwc3: core: initialize ULPI before trying to get the 
PHY")
Cc: linux-stable <sta...@vger.kernel.org> # >= v4.13
Signed-off-by: Roger Quadros <rog...@ti.com>
---
Rebased on Felipe's testing/fixes branch.

 drivers/usb/dwc3/core.c | 47 ---
 drivers/usb/dwc3/core.h |  5 +
 2 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 59511f2..f1d838a 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -486,6 +486,22 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
 }
 
+static int dwc3_core_ulpi_init(struct dwc3 *dwc)
+{
+   int intf;
+   int ret = 0;
+
+   intf = DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3);
+
+   if (intf == DWC3_GHWPARAMS3_HSPHY_IFC_ULPI ||
+   (intf == DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI &&
+dwc->hsphy_interface &&
+!strncmp(dwc->hsphy_interface, "ulpi", 4)))
+   ret = dwc3_ulpi_init(dwc);
+
+   return ret;
+}
+
 /**
  * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
  * @dwc: Pointer to our controller context structure
@@ -497,7 +513,6 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
 static int dwc3_phy_setup(struct dwc3 *dwc)
 {
u32 reg;
-   int ret;
 
reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
 
@@ -568,9 +583,6 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
}
/* FALLTHROUGH */
case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
-   ret = dwc3_ulpi_init(dwc);
-   if (ret)
-   return ret;
/* FALLTHROUGH */
default:
break;
@@ -727,6 +739,7 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc)
 }
 
 static int dwc3_core_get_phy(struct dwc3 *dwc);
+static int dwc3_core_ulpi_init(struct dwc3 *dwc);
 
 /**
  * dwc3_core_init - Low-level initialization of DWC3 Core
@@ -758,17 +771,27 @@ static int dwc3_core_init(struct dwc3 *dwc)
dwc->maximum_speed = USB_SPEED_HIGH;
}
 
-   ret = dwc3_core_get_phy(dwc);
+   ret = dwc3_phy_setup(dwc);
if (ret)
goto err0;
 
-   ret = dwc3_core_soft_reset(dwc);
-   if (ret)
-   goto err0;
+   if (!dwc->ulpi_ready) {
+   ret = dwc3_core_ulpi_init(dwc);
+   if (ret)
+   goto err0;
+   dwc->ulpi_ready = true;
+   }
 
-   ret = dwc3_phy_setup(dwc);
+   if (!dwc->phys_ready) {
+   ret = dwc3_core_get_phy(dwc);
+   if (ret)
+   goto err0a;
+   dwc->phys_ready = true;
+   }
+
+   ret = dwc3_core_soft_reset(dwc);
if (ret)
-   goto err0;
+   goto err0a;
 
dwc3_core_setup_global_control(dwc);
dwc3_core_num_eps(dwc);
@@ -841,6 +864,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
phy_exit(dwc->usb2_generic_phy);
phy_exit(dwc->usb3_generic_phy);
 
+err0a:
+   dwc3_ulpi_exit(dwc);
+
 err0:
return ret;
 }
@@ -1235,7 +1261,6 @@ static int dwc3_probe(struct platform_device *pdev)
 
 err3:
dwc3_free_event_buffers(dwc);
-   dwc3_ulpi_exit(dwc);
 
 err2:
pm_runtime_allow(>dev);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 185b960..860d2bc 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -797,7 +797,9 @@ struct dwc3_scratchpad_array {
  * @usb3_phy: pointer to USB3 PHY
  * @usb2_generic_phy: pointer to USB2 PHY
  * @usb3_generic_phy: pointer to USB3 PHY
+ * @phys_ready: flag to indicate that PHYs are ready
  * @ulpi: pointer to ulpi interface
+ * @ulpi_ready: flag to indicate that ULPI is initialized
  * @u2sel: parameter from Set SEL request.
  * @u2pel: parameter from S

Re: [PATCH 2/2] usb: dwc3: drd: Fix lock-up on ID change during system suspend/resume

2018-02-12 Thread Roger Quadros
Felipe,

On 12/02/18 10:54, Felipe Balbi wrote:
> 
> Hi,
> 
> Roger Quadros <rog...@ti.com> writes:
>> Adding/removing host/gadget controller before .pm_complete()
>> causes a lock-up. Let's prevent any dual-role state change
>> between .pm_prepare() and .pm_complete() to fix this.
>>
>> Signed-off-by: Roger Quadros <rog...@ti.com>
>> ---
>>  drivers/usb/dwc3/core.c | 31 +++
>>  drivers/usb/dwc3/core.h |  5 +
>>  drivers/usb/dwc3/drd.c  | 10 ++
>>  3 files changed, 42 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>> index 42379cc..85388dd 100644
>> --- a/drivers/usb/dwc3/core.c
>> +++ b/drivers/usb/dwc3/core.c
>> @@ -1414,6 +1414,33 @@ static int dwc3_runtime_idle(struct device *dev)
>>  #endif /* CONFIG_PM */
>>  
>>  #ifdef CONFIG_PM_SLEEP
>> +static int dwc3_prepare(struct device *dev)
>> +{
>> +struct dwc3 *dwc = dev_get_drvdata(dev);
>> +unsigned long   flags;
>> +
>> +if (dwc->dr_mode == USB_DR_MODE_OTG) {
>> +spin_lock_irqsave(>lock, flags);
>> +dwc->dr_keep_role = true;
>> +spin_unlock_irqrestore(>lock, flags);
>> +}
>> +
>> +return 0;
>> +}
>> +
>> +static void dwc3_complete(struct device *dev)
>> +{
>> +struct dwc3 *dwc = dev_get_drvdata(dev);
>> +unsigned long   flags;
>> +
>> +if (dwc->dr_mode == USB_DR_MODE_OTG) {
>> +spin_lock_irqsave(>lock, flags);
>> +dwc->dr_keep_role = false;
>> +spin_unlock_irqrestore(>lock, flags);
>> +dwc3_drd_update(dwc);
>> +}
>> +}
> 
> wouldn't it be far easier to just disable OTG IRQ in prepare? and,
> perhaps, also flush_work_sync() ?
> 

There was some more discussion on this here [1]. Apparently using 
system_freezable_wq
and a patch mentioned at end of [1] is sufficient as well

[1] https://lkml.org/lkml/2018/1/25/384

Could you please share your view there?

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: power management problems in ehci-omap

2018-02-07 Thread Roger Quadros
Hi,

On 06/02/18 20:40, Andreas Kemnade wrote:
> On Tue, 6 Feb 2018 10:16:23 -0800
> Tony Lindgren  wrote:
> 
>> * Andreas Kemnade  [180206 18:04]:
>>> On Tue, 6 Feb 2018 09:17:37 -0800
>>> Tony Lindgren  wrote:  
 uarts=$(find /sys/class/tty/tty[SO]*/power/ -type d 2>/dev/null)
 for uart in $uarts; do
echo enabled > $uart/wakeup 2>&1
echo auto > $uart/control 2>&1
 done
   
>>>
>>> hmm, this looks a bit like runtime suspend.  
>>
>> Not only that, it enables wakeup for UART also for suspend :)
>>
> We are using the rtc for wakeup and measure discharge of battery
> for a time frame of about 300 seconds.
> 
>> That is if your dts has it configured with interrupts-extended
>> for the console UART like omap3-beagle-xm.dts has for example.
>> Seems like the gta04 dts don't have these.. And you also want
>> to have chosen with stdout-path =  or whatever the debug
>> UART is for earlycon to work.
>>
>>> I mean suspend aka echo mem >/sys/power/state
>>>   
 echo -n 1 > /sys/kernel/debug/pm_debug/enable_off_mode  
>>
>> And the above will enable SoC and PMIC off modes, which will also
>> take the suspend power to some much much lower value :) You need
>> to configure the PMIC too depending if the oscillator can be turned
>> off, in that case set "ti,twl4030-power-idle-osc-off". That too
>> seems to be missing in gta04 dts files..
>>
> It was in our tree. It can be enabled for the gta04a5. We have even done
> that. But then suspend while charging breaks. I have no idea how to do a
> proper if-not-charging-power-idle-osc-off patch... 
> 
> Yes there are other places where we can optimize suspend current. But
> lets first find out why ehci-omap seems to cause trouble here.
> So we are looking for around 15mA of additional suspend current when the
> module is loaded. 
> Shouldn't the reset line of the phy (usb-nop-xceiv) be set to low when
> going to suspend? I do not see code how to do it. I guess that is the
> reason.
> 
> BTW:
> root@letux:~# cat 
> /sys/bus/platform/devices/48064800.ehci/power/runtime_status 
> active


PM handling is not yet there in the ehci-omap driver.

> static struct platform_driver ehci_hcd_omap_driver = {
> .probe  = ehci_hcd_omap_probe,
> .remove = ehci_hcd_omap_remove,
> .shutdown   = usb_hcd_platform_shutdown,
> /*.suspend  = ehci_hcd_omap_suspend, */
> /*.resume   = ehci_hcd_omap_resume, */
> .driver = {
> .name   = hcd_name,
> .of_match_table = omap_ehci_dt_ids,
> }
> };

There is also some co-relation with the parent driver
drivers/mfd/omap-usb-host.c

Getting low power on system suspend should be easy as we most probably don't
need wakeup to work in this case. This should fix the increased power during
system suspend.

To fix active power consumption we need to implement runtime PM.
However, for runtime suspend case we do need remote-wakeup to work else we
won't be able to detect any new USB devices after the host runtime suspends.
For this we need to remux one of the PHY lines into a GPIO to capture the wake 
event.
This is where the generic wakeirq support comes in.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH 2/2] usb: dwc3: drd: Fix lock-up on ID change during system suspend/resume

2018-01-25 Thread Roger Quadros
Hi,

On 24/01/18 14:19, Roger Quadros wrote:
> On 23/01/18 14:41, Roger Quadros wrote:
>> Hi Manu,
>>
>> On 23/01/18 05:45, Manu Gautam wrote:
>>> Hi,
>>>
>>>
>>> On 1/22/2018 6:31 PM, Roger Quadros wrote:
>>>> Adding/removing host/gadget controller before .pm_complete()
>>>> causes a lock-up. Let's prevent any dual-role state change
>>>> between .pm_prepare() and .pm_complete() to fix this.
>>>
>>> What kind of lock-up are you seeing? Some hardware lockup or software 
>>> deadlock?
>>> IMO using a freezable_wq for drd_work should address that?
>>>
>>
>> I was seeing a software deadlock. freezable_wq is a good idea. I'll try it 
>> out.
> 
> using freezable_wq doesn't get rid of the deadlock.
> If I use freezable_wq plus add some delay before I do a dwc3_host_init()
> in the work function then it starts to work.
> 
> As dependence on delay looks fragile so I'll stick to the current 
> implementation
> based on .pm_prepare/complete().
> 

So I was able to reproduce the lock up with my series as well. On further 
investigation
this is what I see.

There are 2 different scenarios.

1) controller in host mode prior to system suspend and switches to device mode 
during resume.

In this case when we call dwc3_host_exit() before tasks are thawed
xhci_plat_remove() seems to lock up at the second usb_remove_hcd() call.
This issue is resolved by using system_freezable_wq for the _dwc3_set_mode() 
function.


2) controller in device mode prior to system suspend and switches to host mode 
during resume.

In this case we sleep indefinitely in _dwc3_set_mode due to
dwc3_set_mode()->dwc3_gadget_exit()->usb_del_gadget_udc()->udc_stop()->dwc3_gadget_stop()->wait_event_lock_irq()

This is not resolved by moving the dwc3_set_mode() call to .pm_complete() nor 
via the system_freezable_wq.

One way I could fix this is like so.

Felipe, could you please suggest a better way?
Maybe we need to do this in dwc3_gadget_exit() before calling 
usb_del_gadget_udc() ?

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index b417d9a..0c903c1 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -109,6 +109,7 @@ static void __dwc3_set_mode(struct work_struct *work)
struct dwc3 *dwc = work_to_dwc(work);
unsigned long flags;
int ret;
+   int epnum;
 
if (!dwc->desired_dr_role)
return;
@@ -124,6 +125,17 @@ static void __dwc3_set_mode(struct work_struct *work)
dwc3_host_exit(dwc);
break;
case DWC3_GCTL_PRTCAP_DEVICE:
+   spin_lock_irqsave(>lock, flags);
+   for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
+   struct dwc3_ep  *dep = dwc->eps[epnum];
+
+   if (!dep)
+   continue;
+
+   dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
+   }
+   spin_unlock_irqrestore(>lock, flags);
+
dwc3_gadget_exit(dwc);
dwc3_event_buffers_cleanup(dwc);
break;
-- 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH 2/2] usb: dwc3: drd: Fix lock-up on ID change during system suspend/resume

2018-01-24 Thread Roger Quadros
On 23/01/18 14:41, Roger Quadros wrote:
> Hi Manu,
> 
> On 23/01/18 05:45, Manu Gautam wrote:
>> Hi,
>>
>>
>> On 1/22/2018 6:31 PM, Roger Quadros wrote:
>>> Adding/removing host/gadget controller before .pm_complete()
>>> causes a lock-up. Let's prevent any dual-role state change
>>> between .pm_prepare() and .pm_complete() to fix this.
>>
>> What kind of lock-up are you seeing? Some hardware lockup or software 
>> deadlock?
>> IMO using a freezable_wq for drd_work should address that?
>>
> 
> I was seeing a software deadlock. freezable_wq is a good idea. I'll try it 
> out.

using freezable_wq doesn't get rid of the deadlock.
If I use freezable_wq plus add some delay before I do a dwc3_host_init()
in the work function then it starts to work.

As dependence on delay looks fragile so I'll stick to the current implementation
based on .pm_prepare/complete().

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH 2/2] usb: dwc3: drd: Fix lock-up on ID change during system suspend/resume

2018-01-23 Thread Roger Quadros
Hi Manu,

On 23/01/18 05:45, Manu Gautam wrote:
> Hi,
> 
> 
> On 1/22/2018 6:31 PM, Roger Quadros wrote:
>> Adding/removing host/gadget controller before .pm_complete()
>> causes a lock-up. Let's prevent any dual-role state change
>> between .pm_prepare() and .pm_complete() to fix this.
> 
> What kind of lock-up are you seeing? Some hardware lockup or software 
> deadlock?
> IMO using a freezable_wq for drd_work should address that?
> 

I was seeing a software deadlock. freezable_wq is a good idea. I'll try it out.

> 
>>


-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH 4/4] ARM: dts: am43xx: Enable dual-role mode for USB1

2018-01-22 Thread Roger Quadros
+Tony

On 22/01/18 15:11, Roger Quadros wrote:
> USB1 port is micro-AB type and can function as peripheral
> as well as host. Enable dual-role mode for USB1.
> 
> Signed-off-by: Roger Quadros <rog...@ti.com>
> ---
>  arch/arm/boot/dts/am437x-gp-evm.dts  | 2 +-
>  arch/arm/boot/dts/am437x-sk-evm.dts  | 2 +-
>  arch/arm/boot/dts/am43x-epos-evm.dts | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts 
> b/arch/arm/boot/dts/am437x-gp-evm.dts
> index afb8eb0..4aaf637 100644
> --- a/arch/arm/boot/dts/am437x-gp-evm.dts
> +++ b/arch/arm/boot/dts/am437x-gp-evm.dts
> @@ -803,7 +803,7 @@
>  };
>  
>   {
> - dr_mode = "peripheral";
> + dr_mode = "otg";
>   status = "okay";
>  };
>  
> diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts 
> b/arch/arm/boot/dts/am437x-sk-evm.dts
> index 2c6bf06..096c87e 100644
> --- a/arch/arm/boot/dts/am437x-sk-evm.dts
> +++ b/arch/arm/boot/dts/am437x-sk-evm.dts
> @@ -598,7 +598,7 @@
>  };
>  
>   {
> - dr_mode = "peripheral";
> + dr_mode = "otg";
>   status = "okay";
>   pinctrl-names = "default";
>   pinctrl-0 = <_pins>;
> diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts 
> b/arch/arm/boot/dts/am43x-epos-evm.dts
> index a04d79e..7ee2199 100644
> --- a/arch/arm/boot/dts/am43x-epos-evm.dts
> +++ b/arch/arm/boot/dts/am43x-epos-evm.dts
> @@ -854,7 +854,7 @@
>  };
>  
>   {
> - dr_mode = "peripheral";
> + dr_mode = "otg";
>   status = "okay";
>  };
>  
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


[PATCH 2/4] usb: dwc3: core.h: add some register definitions

2018-01-22 Thread Roger Quadros
Add OTG and GHWPARAMS6 register definitions

Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/dwc3/core.h | 82 +
 1 file changed, 82 insertions(+)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index f5eb474..8006335 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -199,6 +199,15 @@
 #define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28)
 #define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW  BIT(24)
 
+/* Global Status Register */
+#define DWC3_GSTS_OTG_IP   BIT(10)
+#define DWC3_GSTS_BC_IPBIT(9)
+#define DWC3_GSTS_ADP_IP   BIT(8)
+#define DWC3_GSTS_HOST_IP  BIT(7)
+#define DWC3_GSTS_DEVICE_IPBIT(6)
+#define DWC3_GSTS_CSR_TIMEOUT  BIT(5)
+#define DWC3_GSTS_BUS_ERR_ADDR_VLD BIT(4)
+
 /* Global USB2 PHY Configuration Register */
 #define DWC3_GUSB2PHYCFG_PHYSOFTRSTBIT(31)
 #define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS BIT(30)
@@ -284,6 +293,11 @@
 #define DWC3_MAX_HIBER_SCRATCHBUFS 15
 
 /* Global HWPARAMS6 Register */
+#define DWC3_GHWPARAMS6_BCSUPPORT  BIT(14)
+#define DWC3_GHWPARAMS6_OTG3SUPPORTBIT(13)
+#define DWC3_GHWPARAMS6_ADPSUPPORT BIT(12)
+#define DWC3_GHWPARAMS6_HNPSUPPORT BIT(11)
+#define DWC3_GHWPARAMS6_SRPSUPPORT BIT(10)
 #define DWC3_GHWPARAMS6_EN_FPGABIT(7)
 
 /* Global HWPARAMS7 Register */
@@ -465,6 +479,74 @@
 #define DWC3_DEV_IMOD_INTERVAL_SHIFT   0
 #define DWC3_DEV_IMOD_INTERVAL_MASK(0x << 0)
 
+/* OTG Configuration Register */
+#define DWC3_OCFG_DISPWRCUTTOFFBIT(5)
+#define DWC3_OCFG_HIBDISMASK   BIT(4)
+#define DWC3_OCFG_SFTRSTMASK   BIT(3)
+#define DWC3_OCFG_OTGVERSION   BIT(2)
+#define DWC3_OCFG_HNPCAP   BIT(1)
+#define DWC3_OCFG_SRPCAP   BIT(0)
+
+/* OTG CTL Register */
+#define DWC3_OCTL_OTG3GOERRBIT(7)
+#define DWC3_OCTL_PERIMODE BIT(6)
+#define DWC3_OCTL_PRTPWRCTLBIT(5)
+#define DWC3_OCTL_HNPREQ   BIT(4)
+#define DWC3_OCTL_SESREQ   BIT(3)
+#define DWC3_OCTL_TERMSELIDPULSE   BIT(2)
+#define DWC3_OCTL_DEVSETHNPEN  BIT(1)
+#define DWC3_OCTL_HSTSETHNPEN  BIT(0)
+
+/* OTG Event Register */
+#define DWC3_OEVT_DEVICEMODE   BIT(31)
+#define DWC3_OEVT_XHCIRUNSTPSETBIT(27)
+#define DWC3_OEVT_DEVRUNSTPSET BIT(26)
+#define DWC3_OEVT_HIBENTRY BIT(25)
+#define DWC3_OEVT_CONIDSTSCHNG BIT(24)
+#define DWC3_OEVT_HRRCONFNOTIF BIT(23)
+#define DWC3_OEVT_HRRINITNOTIF BIT(22)
+#define DWC3_OEVT_ADEVIDLE BIT(21)
+#define DWC3_OEVT_ADEVBHOSTEND BIT(20)
+#define DWC3_OEVT_ADEVHOST BIT(19)
+#define DWC3_OEVT_ADEVHNPCHNG  BIT(18)
+#define DWC3_OEVT_ADEVSRPDET   BIT(17)
+#define DWC3_OEVT_ADEVSESSENDDET   BIT(16)
+#define DWC3_OEVT_BDEVBHOSTEND BIT(11)
+#define DWC3_OEVT_BDEVHNPCHNG  BIT(10)
+#define DWC3_OEVT_BDEVSESSVLDDET   BIT(9)
+#define DWC3_OEVT_BDEVVBUSCHNG BIT(8)
+#define DWC3_OEVT_BSESSVLD BIT(3)
+#define DWC3_OEVT_HSTNEGSTSBIT(2)
+#define DWC3_OEVT_SESREQSTSBIT(1)
+#define DWC3_OEVT_ERRORBIT(0)
+
+/* OTG Event Enable Register */
+#define DWC3_OEVTEN_XHCIRUNSTPSETENBIT(27)
+#define DWC3_OEVTEN_DEVRUNSTPSETEN BIT(26)
+#define DWC3_OEVTEN_HIBENTRYEN BIT(25)
+#define DWC3_OEVTEN_CONIDSTSCHNGEN BIT(24)
+#define DWC3_OEVTEN_HRRCONFNOTIFEN BIT(23)
+#define DWC3_OEVTEN_HRRINITNOTIFEN BIT(22)
+#define DWC3_OEVTEN_ADEVIDLEEN BIT(21)
+#define DWC3_OEVTEN_ADEVBHOSTENDEN BIT(20)
+#define DWC3_OEVTEN_ADEVHOSTEN BIT(19)
+#define DWC3_OEVTEN_ADEVHNPCHNGEN  BIT(18)
+#define DWC3_OEVTEN_ADEVSRPDETEN   BIT(17)
+#define DWC3_OEVTEN_ADEVSESSENDDETEN   BIT(16)
+#define DWC3_OEVTEN_BDEVBHOSTENDEN BIT(11)
+#define DWC3_OEVTEN_BDEVHNPCHNGEN  BIT(10)
+#define DWC3_OEVTEN_BDEVSESSVLDDETEN   BIT(9)
+#define DWC3_OEVTEN_BDEVVBUSCHNGEN BIT(8)
+
+/* OTG Status Register */
+#define DWC3_OSTS_DEVRUNSTPBIT(13)
+#define DWC3_OSTS_XHCIRUNSTP   BIT(12)
+#define DWC3_OSTS_PERIPHERALSTATE  BIT(4)
+#define DWC3_OSTS_XHCIPRTPOWER BIT(3)
+#define DWC3_OSTS_BSESVLD  BIT(2)
+#define DWC3_OSTS_VBUSVLD  BIT(1)
+#define DWC3_OSTS_CONIDSTS BIT(0)
+
 /* Structures */
 
 struct dwc3_trb;
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


[PATCH 0/4] usb: dwc3: Add dual-role support using OTG core

2018-01-22 Thread Roger Quadros
Hi Felipe,

Some platforms (e.g. TI's AM437x) don't have USB ID pin state available
over GPIO/extcon but need to rely on the DWC3 core's OTG block to
get the ID pin state instead.

This series implements simple dual-role functionality using DWC3's OTG block.
Debugfs 'mode' override is also functional so user can switch
between "otg", "host" or "device" modes for debug.

Although system suspend/resume isn't working yet in mainline for AM437x,
I've tested this series for system suspend/resume using a local tree.

This series depends on [1] and [2]

[1] https://www.mail-archive.com/linux-usb@vger.kernel.org/msg98771.html

[2] https://www.mail-archive.com/linux-usb@vger.kernel.org/msg98848.html

Roger Quadros (4):
  usb: dwc3: prevent setting PRTCAP to OTG from debugfs
  usb: dwc3: core.h: add some register definitions
  usb: dwc3: add dual role support using OTG block
  ARM: dts: am43xx: Enable dual-role mode for USB1

 arch/arm/boot/dts/am437x-gp-evm.dts  |   2 +-
 arch/arm/boot/dts/am437x-sk-evm.dts  |   2 +-
 arch/arm/boot/dts/am43x-epos-evm.dts |   2 +-
 drivers/usb/dwc3/core.c  |  70 -
 drivers/usb/dwc3/core.h  | 111 
 drivers/usb/dwc3/drd.c   | 492 +--
 6 files changed, 650 insertions(+), 29 deletions(-)

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


[PATCH 1/4] usb: dwc3: prevent setting PRTCAP to OTG from debugfs

2018-01-22 Thread Roger Quadros
We don't support PRTCAP == OTG so prevent user from
setting it via debugfs.

Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/dwc3/core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 85388dd..2929b1d 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -119,6 +119,9 @@ static void __dwc3_set_mode(struct work_struct *work)
if (dwc->dr_mode != USB_DR_MODE_OTG)
return;
 
+   if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG)
+   return;
+
switch (dwc->current_dr_role) {
case DWC3_GCTL_PRTCAP_HOST:
dwc3_host_exit(dwc);
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


[PATCH 4/4] ARM: dts: am43xx: Enable dual-role mode for USB1

2018-01-22 Thread Roger Quadros
USB1 port is micro-AB type and can function as peripheral
as well as host. Enable dual-role mode for USB1.

Signed-off-by: Roger Quadros <rog...@ti.com>
---
 arch/arm/boot/dts/am437x-gp-evm.dts  | 2 +-
 arch/arm/boot/dts/am437x-sk-evm.dts  | 2 +-
 arch/arm/boot/dts/am43x-epos-evm.dts | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts 
b/arch/arm/boot/dts/am437x-gp-evm.dts
index afb8eb0..4aaf637 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -803,7 +803,7 @@
 };
 
  {
-   dr_mode = "peripheral";
+   dr_mode = "otg";
status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts 
b/arch/arm/boot/dts/am437x-sk-evm.dts
index 2c6bf06..096c87e 100644
--- a/arch/arm/boot/dts/am437x-sk-evm.dts
+++ b/arch/arm/boot/dts/am437x-sk-evm.dts
@@ -598,7 +598,7 @@
 };
 
  {
-   dr_mode = "peripheral";
+   dr_mode = "otg";
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <_pins>;
diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts 
b/arch/arm/boot/dts/am43x-epos-evm.dts
index a04d79e..7ee2199 100644
--- a/arch/arm/boot/dts/am43x-epos-evm.dts
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -854,7 +854,7 @@
 };
 
  {
-   dr_mode = "peripheral";
+   dr_mode = "otg";
status = "okay";
 };
 
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


[PATCH 3/4] usb: dwc3: add dual role support using OTG block

2018-01-22 Thread Roger Quadros
This is useful on platforms (e.g. TI AM437x) that don't
have ID available on a GPIO but do have the OTG block.

We can obtain the ID state via the OTG block and use it
for dual-role switching.

Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/dwc3/core.c |  73 +--
 drivers/usb/dwc3/core.h |  29 +++
 drivers/usb/dwc3/drd.c  | 492 ++--
 3 files changed, 565 insertions(+), 29 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 2929b1d..6a54e29 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -89,10 +89,7 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
return 0;
 }
 
-static void dwc3_event_buffers_cleanup(struct dwc3 *dwc);
-static int dwc3_event_buffers_setup(struct dwc3 *dwc);
-
-static void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
+void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
 {
u32 reg;
 
@@ -110,16 +107,19 @@ static void __dwc3_set_mode(struct work_struct *work)
unsigned long flags;
int ret;
 
-   if (!dwc->desired_dr_role)
+   if (dwc->dr_mode != USB_DR_MODE_OTG)
return;
 
-   if (dwc->desired_dr_role == dwc->current_dr_role)
+   if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG)
+   dwc3_otg_update(dwc, 0);
+
+   if (!dwc->desired_dr_role)
return;
 
-   if (dwc->dr_mode != USB_DR_MODE_OTG)
+   if (dwc->desired_dr_role == dwc->current_dr_role)
return;
 
-   if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG)
+   if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
return;
 
switch (dwc->current_dr_role) {
@@ -130,6 +130,13 @@ static void __dwc3_set_mode(struct work_struct *work)
dwc3_gadget_exit(dwc);
dwc3_event_buffers_cleanup(dwc);
break;
+   case DWC3_GCTL_PRTCAP_OTG:
+   dwc3_otg_exit(dwc);
+   spin_lock_irqsave(>lock, flags);
+   dwc->desired_otg_role = DWC3_OTG_ROLE_IDLE;
+   spin_unlock_irqrestore(>lock, flags);
+   dwc3_otg_update(dwc, 1);
+   break;
default:
break;
}
@@ -164,9 +171,14 @@ static void __dwc3_set_mode(struct work_struct *work)
if (ret)
dev_err(dwc->dev, "failed to initialize peripheral\n");
break;
+   case DWC3_GCTL_PRTCAP_OTG:
+   dwc3_otg_init(dwc);
+   dwc3_otg_update(dwc, 0);
+   break;
default:
break;
}
+
 }
 
 void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
@@ -347,7 +359,7 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, 
unsigned length)
  *
  * Returns 0 on success otherwise negative errno.
  */
-static int dwc3_event_buffers_setup(struct dwc3 *dwc)
+int dwc3_event_buffers_setup(struct dwc3 *dwc)
 {
struct dwc3_event_buffer*evt;
 
@@ -364,7 +376,7 @@ static int dwc3_event_buffers_setup(struct dwc3 *dwc)
return 0;
 }
 
-static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
+void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
 {
struct dwc3_event_buffer*evt;
 
@@ -1296,6 +1308,20 @@ static int dwc3_suspend_common(struct dwc3 *dwc, 
pm_message_t msg)
if (!PMSG_IS_AUTO(msg))
dwc3_core_exit(dwc);
break;
+   case DWC3_GCTL_PRTCAP_OTG:
+   /* do nothing during runtime_suspend */
+   if (PMSG_IS_AUTO(msg))
+   break;
+
+   if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) {
+   spin_lock_irqsave(>lock, flags);
+   dwc3_gadget_suspend(dwc);
+   spin_unlock_irqrestore(>lock, flags);
+   }
+
+   dwc3_otg_exit(dwc);
+   dwc3_core_exit(dwc);
+   break;
default:
/* do nothing */
break;
@@ -1327,6 +1353,27 @@ static int dwc3_resume_common(struct dwc3 *dwc, 
pm_message_t msg)
return ret;
}
break;
+   case DWC3_GCTL_PRTCAP_OTG:
+   /* nothing to do on runtime_resume */
+   if (PMSG_IS_AUTO(msg))
+   break;
+
+   ret = dwc3_core_init(dwc);
+   if (ret)
+   return ret;
+
+   dwc3_set_prtcap(dwc, dwc->current_dr_role);
+
+   dwc3_otg_init(dwc);
+   if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST) {
+   dwc3_otg_host_init(dwc);
+   } else if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) {
+   spin_lock_irqsave(>lock, flags);
+   dwc3_gadget_resume(dwc);
+  

[PATCH 1/2] usb: dwc3: omap: don't miss events during suspend/resume

2018-01-22 Thread Roger Quadros
The USB cable state can change during suspend/resume
so be sure to check and update the extcon state.

Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/dwc3/dwc3-omap.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index a4719e8..ed8b865 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -582,9 +582,25 @@ static int dwc3_omap_resume(struct device *dev)
return 0;
 }
 
+static void dwc3_omap_complete(struct device *dev)
+{
+   struct dwc3_omap*omap = dev_get_drvdata(dev);
+
+   if (extcon_get_state(omap->edev, EXTCON_USB))
+   dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
+   else
+   dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_OFF);
+
+   if (extcon_get_state(omap->edev, EXTCON_USB_HOST))
+   dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
+   else
+   dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_FLOAT);
+}
+
 static const struct dev_pm_ops dwc3_omap_dev_pm_ops = {
 
SET_SYSTEM_SLEEP_PM_OPS(dwc3_omap_suspend, dwc3_omap_resume)
+   .complete = dwc3_omap_complete,
 };
 
 #define DEV_PM_OPS (_omap_dev_pm_ops)
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


[PATCH 2/2] usb: dwc3: drd: Fix lock-up on ID change during system suspend/resume

2018-01-22 Thread Roger Quadros
Adding/removing host/gadget controller before .pm_complete()
causes a lock-up. Let's prevent any dual-role state change
between .pm_prepare() and .pm_complete() to fix this.

Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/dwc3/core.c | 31 +++
 drivers/usb/dwc3/core.h |  5 +
 drivers/usb/dwc3/drd.c  | 10 ++
 3 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 42379cc..85388dd 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1414,6 +1414,33 @@ static int dwc3_runtime_idle(struct device *dev)
 #endif /* CONFIG_PM */
 
 #ifdef CONFIG_PM_SLEEP
+static int dwc3_prepare(struct device *dev)
+{
+   struct dwc3 *dwc = dev_get_drvdata(dev);
+   unsigned long   flags;
+
+   if (dwc->dr_mode == USB_DR_MODE_OTG) {
+   spin_lock_irqsave(>lock, flags);
+   dwc->dr_keep_role = true;
+   spin_unlock_irqrestore(>lock, flags);
+   }
+
+   return 0;
+}
+
+static void dwc3_complete(struct device *dev)
+{
+   struct dwc3 *dwc = dev_get_drvdata(dev);
+   unsigned long   flags;
+
+   if (dwc->dr_mode == USB_DR_MODE_OTG) {
+   spin_lock_irqsave(>lock, flags);
+   dwc->dr_keep_role = false;
+   spin_unlock_irqrestore(>lock, flags);
+   dwc3_drd_update(dwc);
+   }
+}
+
 static int dwc3_suspend(struct device *dev)
 {
struct dwc3 *dwc = dev_get_drvdata(dev);
@@ -1451,6 +1478,10 @@ static const struct dev_pm_ops dwc3_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume)
SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume,
dwc3_runtime_idle)
+#ifdef CONFIG_PM_SLEEP
+   .prepare = dwc3_prepare,
+   .complete = dwc3_complete,
+#endif
 };
 
 #ifdef CONFIG_OF
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 4a4a4c9..f5eb474 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -786,6 +786,7 @@ struct dwc3_scratchpad_array {
  * @dr_mode: requested mode of operation
  * @current_dr_role: current role of operation when in dual-role mode
  * @desired_dr_role: desired role of operation when in dual-role mode
+ * @dr_keep_role: keep the current dual-role irrespective of ID changes
  * @edev: extcon handle
  * @edev_nb: extcon notifier
  * @hsphy_mode: UTMI phy mode, one of following:
@@ -901,6 +902,7 @@ struct dwc3 {
enum usb_dr_modedr_mode;
u32 current_dr_role;
u32 desired_dr_role;
+   booldr_keep_role;
struct extcon_dev   *edev;
struct notifier_block   edev_nb;
enum usb_phy_interface  hsphy_mode;
@@ -1227,11 +1229,14 @@ static inline int 
dwc3_send_gadget_generic_command(struct dwc3 *dwc,
 #if IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
 int dwc3_drd_init(struct dwc3 *dwc);
 void dwc3_drd_exit(struct dwc3 *dwc);
+void dwc3_drd_update(struct dwc3 *dwc);
 #else
 static inline int dwc3_drd_init(struct dwc3 *dwc)
 { return 0; }
 static inline void dwc3_drd_exit(struct dwc3 *dwc)
 { }
+static inline void dwc3_drd_update(struct dwc3 *dwc);
+{ }
 #endif
 
 /* power management interface */
diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
index cc8ab9a..177a8be 100644
--- a/drivers/usb/dwc3/drd.c
+++ b/drivers/usb/dwc3/drd.c
@@ -13,7 +13,7 @@
 #include "core.h"
 #include "gadget.h"
 
-static void dwc3_drd_update(struct dwc3 *dwc)
+void dwc3_drd_update(struct dwc3 *dwc)
 {
int id;
 
@@ -31,9 +31,11 @@ static int dwc3_drd_notifier(struct notifier_block *nb,
 {
struct dwc3 *dwc = container_of(nb, struct dwc3, edev_nb);
 
-   dwc3_set_mode(dwc, event ?
- DWC3_GCTL_PRTCAP_HOST :
- DWC3_GCTL_PRTCAP_DEVICE);
+   if (!dwc->dr_keep_role) {
+   dwc3_set_mode(dwc, event ?
+ DWC3_GCTL_PRTCAP_HOST :
+ DWC3_GCTL_PRTCAP_DEVICE);
+   }
 
return NOTIFY_DONE;
 }
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


[PATCH 0/2] usb: dwc3: Fix dual role during system suspend/resume

2018-01-22 Thread Roger Quadros
Hi Felipe,

These patches address issues with system suspend/resume when we're
in dual-role configuration and the ID pin state toggles while the
system is suspended.

This series depends on
https://www.mail-archive.com/linux-usb@vger.kernel.org/msg98771.html

Roger Quadros (2):
  usb: dwc3: omap: don't miss events during suspend/resume
  usb: dwc3: drd: Fix lock-up on ID change during system suspend/resume

 drivers/usb/dwc3/core.c  | 31 +++
 drivers/usb/dwc3/core.h  |  5 +
 drivers/usb/dwc3/drd.c   | 10 ++
 drivers/usb/dwc3/dwc3-omap.c | 16 
 4 files changed, 58 insertions(+), 4 deletions(-)

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


Re: [PATCH v2] usb: dwc3: core: Power-off core/PHYs on system_suspend in host mode

2018-01-18 Thread Roger Quadros
On 18/01/18 13:24, Manu Gautam wrote:
> Commit 689bf72c6e0d ("usb: dwc3: Don't reinitialize core during
> host bus-suspend/resume") updated suspend/resume routines to not
> power_off and reinit PHYs/core for host mode.
> It broke platforms that rely on DWC3 core to power_off PHYs to
> enter low power state on system suspend.
> 
> Perform dwc3_core_exit/init only during host mode system_suspend/
> resume to addresses power regression from above mentioned patch
> and also allow USB session to stay connected across
> runtime_suspend/resume in host mode. While at it also replace
> existing checks for HOST only dr_mode with current_dr_role to
> have similar core driver behavior for both Host-only and DRD+Host
> configurations.
> 
> Fixes: 689bf72c6e0d ("usb: dwc3: Don't reinitialize core during host 
> bus-suspend/resume")
> Signed-off-by: Manu Gautam <mgau...@codeaurora.org>

Tested to work on dra7x platform.

Reviewed-by: Roger Quadros <rog...@ti.com>

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH v2] usb: ehci-omap: don't complain on -EPROBE_DEFER when no PHY found

2018-01-17 Thread Roger Quadros
On 17/01/18 12:08, Ladislav Michl wrote:
> Don't complain on -EPROBE_DEFER when when no PHY found, the driver
> probe will be retried later.
> 
> Signed-off-by: Ladislav Michl <la...@linux-mips.org>
> Acked-by: Tony Lindgren <t...@atomide.com>

Acked-by: Roger Quadros <rog...@ti.com>

> ---
>  Changes:
>  - v2: None, just added Tony's ack
> 
>  drivers/usb/host/ehci-omap.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
> index 854b146a457d..fd6170962a1a 100644
> --- a/drivers/usb/host/ehci-omap.c
> +++ b/drivers/usb/host/ehci-omap.c
> @@ -167,8 +167,9 @@ static int ehci_hcd_omap_probe(struct platform_device 
> *pdev)
>   continue;
>  
>   ret = PTR_ERR(phy);
> - dev_err(dev, "Can't get PHY device for port %d: %d\n",
> - i, ret);
> + if (ret != -EPROBE_DEFER)
> + dev_err(dev, "Can't get PHY device for port "
> + "%d: %d\n", i, ret);
>   goto err_phy;
>   }
>  
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: core: Power-off core/PHYs on system_suspend in host mode

2018-01-17 Thread Roger Quadros
Manu,

On 16/01/18 08:26, Manu Gautam wrote:
> Commit 689bf72c6e0d ("usb: dwc3: Don't reinitialize core during
> host bus-suspend/resume") updated suspend/resume routines to not
> power_off and reinit PHYs/core for host mode.
> It broke platforms that rely on DWC3 core to power_off PHYs to
> enter low power state on system suspend.
> 
> Perform dwc3_core_exit/init only during host mode system_suspend/
> resume to addresses power regression from above mentioned patch
> and also allow USB session to stay connected across
> runtime_suspend/resume in host mode.
> 
> Fixes: 689bf72c6e0d ("usb: dwc3: Don't reinitialize core during host 
> bus-suspend/resume")
> Signed-off-by: Manu Gautam 
> ---
>  drivers/usb/dwc3/core.c | 23 +++
>  1 file changed, 15 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 0783250..e9fbee9 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -1279,7 +1279,7 @@ static int dwc3_remove(struct platform_device *pdev)
>  }
>  
>  #ifdef CONFIG_PM
> -static int dwc3_suspend_common(struct dwc3 *dwc)
> +static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
>  {
>   unsigned long   flags;
>  
> @@ -1292,14 +1292,16 @@ static int dwc3_suspend_common(struct dwc3 *dwc)
>   break;
>   case DWC3_GCTL_PRTCAP_HOST:
>   default:
> - /* do nothing */
> + /* do nothing during host runtime_suspend */
> + if (!PMSG_IS_AUTO(msg))
> + dwc3_core_exit(dwc);
>   break;

since we're now doing something specific to HOST case we need to separate out 
the 'default' case
so,

+   default:
+   break;

>   }
>  
>   return 0;
>  }
>  
> -static int dwc3_resume_common(struct dwc3 *dwc)
> +static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
>  {
>   unsigned long   flags;
>   int ret;
> @@ -1316,7 +1318,12 @@ static int dwc3_resume_common(struct dwc3 *dwc)
>   break;
>   case DWC3_GCTL_PRTCAP_HOST:
>   default:
> - /* do nothing */
> + /* nothing to do on host runtime_resume */
> + if (!PMSG_IS_AUTO(msg)) {
> + ret = dwc3_core_init(dwc);
> + if (ret)
> + return ret;
> + }
>   break;

same here.

>   }
>  
> @@ -1348,7 +1355,7 @@ static int dwc3_runtime_suspend(struct device *dev)
>   if (dwc3_runtime_checks(dwc))
>   return -EBUSY;
>  
> - ret = dwc3_suspend_common(dwc);
> + ret = dwc3_suspend_common(dwc, PMSG_AUTO_SUSPEND);
>   if (ret)
>   return ret;
>  
> @@ -1364,7 +1371,7 @@ static int dwc3_runtime_resume(struct device *dev)
>  
>   device_init_wakeup(dev, false);
>  
> - ret = dwc3_resume_common(dwc);
> + ret = dwc3_resume_common(dwc, PMSG_AUTO_RESUME);
>   if (ret)
>   return ret;
>  
> @@ -1411,7 +1418,7 @@ static int dwc3_suspend(struct device *dev)
>   struct dwc3 *dwc = dev_get_drvdata(dev);
>   int ret;
>  
> - ret = dwc3_suspend_common(dwc);
> + ret = dwc3_suspend_common(dwc, PMSG_SUSPEND);
>   if (ret)
>   return ret;
>  
> @@ -1427,7 +1434,7 @@ static int dwc3_resume(struct device *dev)
>  
>   pinctrl_pm_select_default_state(dev);
>  
> - ret = dwc3_resume_common(dwc);
> + ret = dwc3_resume_common(dwc, PMSG_RESUME);
>   if (ret)
>   return ret;
>  
> 

You also need to fix-up

index e9fbee9..a213295 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1333,12 +1333,11 @@ static int dwc3_resume_common(struct dwc3 *dwc, 
pm_message_t msg)
 static int dwc3_runtime_checks(struct dwc3 *dwc)
 {
switch (dwc->current_dr_role) {
-   case USB_DR_MODE_PERIPHERAL:
-   case USB_DR_MODE_OTG:
+   case DWC3_GCTL_PRTCAP_DEVICE:
if (dwc->connected)
return -EBUSY;
break;
-   case USB_DR_MODE_HOST:
+   case DWC3_GCTL_PRTCAP_HOST:
default:
/* do nothing */
break;

and finally

index a213295..728955c 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -218,7 +218,7 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
 * XHCI driver will reset the host block. If dwc3 was configured for
 * host-only mode, then we can return early.
 */
-   if (dwc->dr_mode == USB_DR_MODE_HOST)
+   if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
return 0;
 
reg = dwc3_readl(dwc->regs, DWC3_DCTL);


After these changes applied, I could get suspend/resume working properly on 
dra7x-evm
for host, device and dual-role cases.
 
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. 

Re: [RESEND PATCH 1/3] usb: dwc3: Don't reinitialize core during host bus-suspend/resume

2018-01-15 Thread Roger Quadros
Hi Manu,

On 11/01/18 03:41, Manu Gautam wrote:
> Hi,
> 
> 
> On 1/10/2018 6:18 PM, Roger Quadros wrote:
>> Hi Manu,
>>
>> On 27/09/17 14:19, Manu Gautam wrote:
>>> Driver powers-off PHYs and reinitializes DWC3 core and gadget on
>>> resume. While this works fine for gadget mode but in host
>>> mode there is not re-initialization of host stack. Also, resetting
>>> bus as part of bus_suspend/resume is not correct which could affect
>>> (or disconnect) connected devices.
>>> Fix this by not reinitializing core on suspend/resume in host mode
>>> for HOST only and OTG/drd configurations.
>>>
>> All this seems correct but we (TI) were relying on dwc3_core_exit() to be 
>> called
>> during dwc3_suspend() to have the lowest power state for our platforms.
>>
>> After this patch, DWC3 controller and PHYs won't be turned off thus
>> preventing our platform from reaching low power levels.
>>
>> So this is a regression for us (TI) in v4.15-rc.
>>
>> Felipe, do you agree?
>>
>> If yes I can send a patch which fixes the regression
>> and also makes USB host work after suspend/resume.
>>
> 
> I think it will be better to separate runtime_suspend and pm_suspend handling 
> for
> host mode in dwc3. Powering offf/on PHYs and dwc3_core_exit/init across system
> suspend-resume should be ok but doing that for runtime suspend-resume is not
> correct.
> Let me know if that sounds ok, I can provide a patch for same instead of
> reverting this which affects runtime PM with dwc3 host.
> Also, we need to consider dwc3 in Host mode with dr_mode as DRD/OTG similar to
> dr_mode as HOST.
> 
> 

Are you going to provide a patch for this any time soon?

FYI, suspend/resume is broken on DRA7x with Dual-role while in host mode.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


[PATCH v2] usb: dwc3: core: Fix ULPI PHYs and prevent phy_get/ulpi_init during suspend/resume

2018-01-11 Thread Roger Quadros
In order for ULPI PHYs to work, dwc3_phy_setup() and dwc3_ulpi_init()
must be doene before dwc3_core_get_phy().

commit 541768b08a40 ("usb: dwc3: core: Call dwc3_core_get_phy() before 
initializing phys")
broke this.

The other issue is that dwc3_core_get_phy() and dwc3_ulpi_init() should
be called only once during the life cycle of the driver. However,
as dwc3_core_init() is called during system suspend/resume it will
result in multiple calls to dwc3_core_get_phy() and dwc3_ulpi_init()
which is wrong.

Fix this by moving dwc3_ulpi_init() out of dwc3_phy_setup()
into dwc3_core_ulpi_init(). Use a flag 'ulpi_ready' to ensure that
dwc3_core_ulpi_init() is called only once from dwc3_core_init().

Use another flag 'phys_ready' to call dwc3_core_get_phy() only once from
dwc3_core_init().

Fixes: 541768b08a40 ("usb: dwc3: core: Call dwc3_core_get_phy() before 
initializing phys")
Fixes: f54edb539c11 ("usb: dwc3: core: initialize ULPI before trying to get the 
PHY")
Cc: linux-stable <sta...@vger.kernel.org> # >= v4.13
Signed-off-by: Roger Quadros <rog...@ti.com>
---

Changelog:
v2:
- don't break ULPI case. Also take into consideration suspend/resume for ULPI 
case.

 drivers/usb/dwc3/core.c | 47 ---
 drivers/usb/dwc3/core.h |  5 +
 2 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 0783250..84382f6 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -482,6 +482,22 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
 }
 
+static int dwc3_core_ulpi_init(struct dwc3 *dwc)
+{
+   int intf;
+   int ret = 0;
+
+   intf = DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3);
+
+   if (intf == DWC3_GHWPARAMS3_HSPHY_IFC_ULPI ||
+   (intf == DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI &&
+dwc->hsphy_interface &&
+!strncmp(dwc->hsphy_interface, "ulpi", 4)))
+   ret = dwc3_ulpi_init(dwc);
+
+   return ret;
+}
+
 /**
  * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
  * @dwc: Pointer to our controller context structure
@@ -493,7 +509,6 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
 static int dwc3_phy_setup(struct dwc3 *dwc)
 {
u32 reg;
-   int ret;
 
reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
 
@@ -564,9 +579,6 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
}
/* FALLTHROUGH */
case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
-   ret = dwc3_ulpi_init(dwc);
-   if (ret)
-   return ret;
/* FALLTHROUGH */
default:
break;
@@ -723,6 +735,7 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc)
 }
 
 static int dwc3_core_get_phy(struct dwc3 *dwc);
+static int dwc3_core_ulpi_init(struct dwc3 *dwc);
 
 /**
  * dwc3_core_init - Low-level initialization of DWC3 Core
@@ -754,17 +767,27 @@ static int dwc3_core_init(struct dwc3 *dwc)
dwc->maximum_speed = USB_SPEED_HIGH;
}
 
-   ret = dwc3_core_get_phy(dwc);
+   ret = dwc3_phy_setup(dwc);
if (ret)
goto err0;
 
-   ret = dwc3_core_soft_reset(dwc);
-   if (ret)
-   goto err0;
+   if (!dwc->ulpi_ready) {
+   ret = dwc3_core_ulpi_init(dwc);
+   if (ret)
+   goto err0;
+   dwc->ulpi_ready = true;
+   }
 
-   ret = dwc3_phy_setup(dwc);
+   if (!dwc->phys_ready) {
+   ret = dwc3_core_get_phy(dwc);
+   if (ret)
+   goto err0a;
+   dwc->phys_ready = true;
+   }
+
+   ret = dwc3_core_soft_reset(dwc);
if (ret)
-   goto err0;
+   goto err0a;
 
dwc3_core_setup_global_control(dwc);
dwc3_core_num_eps(dwc);
@@ -837,6 +860,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
phy_exit(dwc->usb2_generic_phy);
phy_exit(dwc->usb3_generic_phy);
 
+err0a:
+   dwc3_ulpi_exit(dwc);
+
 err0:
return ret;
 }
@@ -1229,7 +1255,6 @@ static int dwc3_probe(struct platform_device *pdev)
 
 err3:
dwc3_free_event_buffers(dwc);
-   dwc3_ulpi_exit(dwc);
 
 err2:
pm_runtime_allow(>dev);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 4a4a4c9..6b202e3 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -795,7 +795,9 @@ struct dwc3_scratchpad_array {
  * @usb3_phy: pointer to USB3 PHY
  * @usb2_generic_phy: pointer to USB2 PHY
  * @usb3_generic_phy: pointer to USB3 PHY
+ * @phys_ready: flag to indicate that PHYs are ready
  * @ulpi: pointer to ulpi interface
+ * @ulpi_ready: flag to indicate that ULPI is initialized
  * @isoch_delay: wValue from Set 

Re: [PATCH] usb: dwc3: core: Don't try to get PHYs during suspend/resume

2018-01-11 Thread Roger Quadros
On 11/01/18 11:31, Felipe Balbi wrote:
> 
> Hi,
> 
> Roger Quadros <rog...@ti.com> writes:
>>> Roger Quadros <rog...@ti.com> writes:
>>>>>>> -   ret = dwc3_core_soft_reset(dwc);
>>>>>>> +   ret = dwc3_core_get_phy(dwc);
>>>>>>
>>>>>> we can get_phy in dwc3_core_init() as it will get called on resume().
>>>>>> This was the $subject of this patch.
>>>>>
>>>>> indeed. thanks :-)
>>>>>
>>>>
>>>> oops sorry. I meant we can't call dwc3_core_get_phy() in dwc3_core_init(). 
>>>> :P
>>>
>>> bit of a chicken-and-egg problem. We need to setup the PHY interface
>>> before getting the PHYs, but can't get PHY during resume. Maybe the best
>>> way here would be to check for the pointers being valid. Something like:
>>>
>>> if (!phy)
>>> get_phy();
>>>
>>
>> OK that should take care of not calling get_phy() on suspend.
>> However there is one more issue with the approach
>>
>>> @@ -754,15 +754,15 @@ static int dwc3_core_init(struct dwc3 *dwc)
>>> dwc->maximum_speed = USB_SPEED_HIGH;
>>> }
>>>  
>>> -   ret = dwc3_core_get_phy(dwc);
>>> +   ret = dwc3_phy_setup(dwc);
>>> if (ret)
>>> goto err0;
>>
>> here we configure PHY related bits and register the ulpi interface.
>>
>>>  
>>> -   ret = dwc3_core_soft_reset(dwc);
>>> +   ret = dwc3_core_get_phy(dwc);
>>> if (ret)
>>> goto err0;
>>>  
>>
>> we got the PHYs. all OK here.
>>
>>> -   ret = dwc3_phy_setup(dwc);
>>> +   ret = dwc3_core_soft_reset(dwc);
>>> if (ret)
>>> goto err0;
>>
>> Now we do a soft reset. This means we loose the PHY configuration bits that 
>> we did
>> in dwc3_phy_setup. So we need to call dwc3_phy_setup again but not 
>> re-register the ulpi interface.
>> I can use a flag there so that dwc3_ulpi_init() is done only once.
> 
> sounds like it's better to extract out a smaller function that just
> checks if we need ULPI bus and registers it, something akin to:
> 
> @@ -482,6 +482,21 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
>   parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
>  }
>  
> +static int dwc3_ulpi_init(struct dwc3 *dwc)
> +{
> + int intf;
> +
> + intf = DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3);
> +
> + if (intf == DWC3_GHWPARAMS3_HSPHY_IFC_ULPI ||
> + (intf == DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI &&
> + dwc->hsphy_interface &&
> + !strncmp(dwc->hsphy_interface, "ulpi", 
> 4)))
> + return dwc3_ulpi_init(dwc);
> +
> + return 0;
> +}
> +
>  /**
>   * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
>   * @dwc: Pointer to our controller context structure
> @@ -563,11 +578,6 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
>   break;
>   }
>   /* FALLTHROUGH */
> - case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI:
> - ret = dwc3_ulpi_init(dwc);
> - if (ret)
> - return ret;
> - /* FALLTHROUGH */
>   default:
>   break;
>   }
> 
> Then we just call that outside of any functions that get called during PM.
> 

Right. Seems like we've covered everything. I'll send a patch in a while.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: core: Don't try to get PHYs during suspend/resume

2018-01-11 Thread Roger Quadros


On 11/01/18 11:09, Roger Quadros wrote:
> +Heikki
> 
> On 11/01/18 10:25, Felipe Balbi wrote:
>>
>> Hi,
>>
>> Roger Quadros <rog...@ti.com> writes:
>>>>>> -ret = dwc3_core_soft_reset(dwc);
>>>>>> +ret = dwc3_core_get_phy(dwc);
>>>>>
>>>>> we can get_phy in dwc3_core_init() as it will get called on resume().
>>>>> This was the $subject of this patch.
>>>>
>>>> indeed. thanks :-)
>>>>
>>>
>>> oops sorry. I meant we can't call dwc3_core_get_phy() in dwc3_core_init(). 
>>> :P
>>
>> bit of a chicken-and-egg problem. We need to setup the PHY interface
>> before getting the PHYs, but can't get PHY during resume. Maybe the best
>> way here would be to check for the pointers being valid. Something like:
>>
>> if (!phy)
>>  get_phy();
>>
> 
> OK that should take care of not calling get_phy() on suspend.
> However there is one more issue with the approach
> 
>> @@ -754,15 +754,15 @@ static int dwc3_core_init(struct dwc3 *dwc)
>>  dwc->maximum_speed = USB_SPEED_HIGH;
>>  }
>>  
>> -ret = dwc3_core_get_phy(dwc);
>> +ret = dwc3_phy_setup(dwc);
>>  if (ret)
>>  goto err0;
> 
> here we configure PHY related bits and register the ulpi interface.
> 
>>  
>> -ret = dwc3_core_soft_reset(dwc);
>> +ret = dwc3_core_get_phy(dwc);
>>  if (ret)
>>  goto err0;
>>  
> 
> we got the PHYs. all OK here.
> 
>> -ret = dwc3_phy_setup(dwc);
>> +ret = dwc3_core_soft_reset(dwc);
>>  if (ret)
>>  goto err0;
> 
> Now we do a soft reset. This means we loose the PHY configuration bits that 
> we did

Actually I was wrong. We're only resetting the device side (DCTL.CSFTRST) which 
doesn't seem to affect
GUSB2PHYCFGn and GUSB3PIPECTLn registers.

So we're good.

> in dwc3_phy_setup. So we need to call dwc3_phy_setup again but not 
> re-register the ulpi interface.
> I can use a flag there so that dwc3_ulpi_init() is done only once.
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [RESEND PATCH 1/3] usb: dwc3: Don't reinitialize core during host bus-suspend/resume

2018-01-11 Thread Roger Quadros
Felipe,

On 11/01/18 11:04, Felipe Balbi wrote:
> 
> Hi,
> 
> Manu Gautam  writes:
> On 27/09/17 14:19, Manu Gautam wrote:
>> Driver powers-off PHYs and reinitializes DWC3 core and gadget on
>> resume. While this works fine for gadget mode but in host
>> mode there is not re-initialization of host stack. Also, resetting
>> bus as part of bus_suspend/resume is not correct which could affect
>> (or disconnect) connected devices.
>> Fix this by not reinitializing core on suspend/resume in host mode
>> for HOST only and OTG/drd configurations.
>>
> All this seems correct but we (TI) were relying on dwc3_core_exit() to be 
> called
> during dwc3_suspend() to have the lowest power state for our platforms.
>
> After this patch, DWC3 controller and PHYs won't be turned off thus
> preventing our platform from reaching low power levels.
>
> So this is a regression for us (TI) in v4.15-rc.
>
> Felipe, do you agree?
>
> If yes I can send a patch which fixes the regression
> and also makes USB host work after suspend/resume.
>
 I think it will be better to separate runtime_suspend and pm_suspend 
 handling for
 host mode in dwc3. Powering offf/on PHYs and dwc3_core_exit/init across 
 system
 suspend-resume should be ok but doing that for runtime suspend-resume is 
 not
 correct.
>>> it sure is. It's part of hibernation-while-disconnected programming sequence
>>>
 Let me know if that sounds ok, I can provide a patch for same instead of
 reverting this which affects runtime PM with dwc3 host.
>>> nope, that would break platforms using hibernation
>>
>> Please don't mind me asking this if it is very basic, I am probably
>> missing something there
>>
>> We should be able to distinguish between runtime_pm vs
>> system_suspend/hibernation and then process accordingly.
> 
> I'm not talking about Linux suspend to disk; I'm talking about Synopsys'
> Hibernation feature (open up your databook and have a read ;-)
> 
>> In host mode runtime suspend/resume could happen very often with
>> device connected, and resetting h/w on every runtime_resume might not
>> be desired. And PHYs drivers can also support runtime_suspend which
>> would be preferred instead of shutting down phy.
> 
> We don't do anything when dwc3 is working as a host, we simply assume if
> we reach dwc3.ko, xhci has done its part. Here's what our
> suspend_common looks like:
> 
> static int dwc3_suspend_common(struct dwc3 *dwc)
> {
>   unsigned long   flags;
> 
>   switch (dwc->current_dr_role) {
>   case DWC3_GCTL_PRTCAP_DEVICE:
>   spin_lock_irqsave(>lock, flags);
>   dwc3_gadget_suspend(dwc);
>   spin_unlock_irqrestore(>lock, flags);
>   dwc3_core_exit(dwc);
>   break;
>   case DWC3_GCTL_PRTCAP_HOST:
>   default:
>   /* do nothing */
>   break;
>   }
> 
>   return 0;
> }
> 
> We're not resetting anything, not tearing down anything. No idea why
> you're saying that in host mode we're breaking things apart. If you have
> out-of-tree patches on top of v4.15-rc7, fix them instead of claiming
> mainline is at fault.
> 

This is the case after commit 689bf72c6e0d  ("usb: dwc3: Don't reinitialize 
core during host bus-suspend/resume")
which is breaking low power for TI platforms in Host mode.

If we revert that commit we will be doing dwc3_core_exit() for host mode as 
well. Which is what we want for system suspend
but probably not for runtime suspend in host case.

This is why Manu wants to differentiate runtime vs system suspend.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: core: Don't try to get PHYs during suspend/resume

2018-01-11 Thread Roger Quadros
+Heikki

On 11/01/18 10:25, Felipe Balbi wrote:
> 
> Hi,
> 
> Roger Quadros <rog...@ti.com> writes:
>>>>> - ret = dwc3_core_soft_reset(dwc);
>>>>> + ret = dwc3_core_get_phy(dwc);
>>>>
>>>> we can get_phy in dwc3_core_init() as it will get called on resume().
>>>> This was the $subject of this patch.
>>>
>>> indeed. thanks :-)
>>>
>>
>> oops sorry. I meant we can't call dwc3_core_get_phy() in dwc3_core_init(). :P
> 
> bit of a chicken-and-egg problem. We need to setup the PHY interface
> before getting the PHYs, but can't get PHY during resume. Maybe the best
> way here would be to check for the pointers being valid. Something like:
> 
> if (!phy)
>   get_phy();
> 

OK that should take care of not calling get_phy() on suspend.
However there is one more issue with the approach

> @@ -754,15 +754,15 @@ static int dwc3_core_init(struct dwc3 *dwc)
>   dwc->maximum_speed = USB_SPEED_HIGH;
>   }
>  
> - ret = dwc3_core_get_phy(dwc);
> + ret = dwc3_phy_setup(dwc);
>   if (ret)
>   goto err0;

here we configure PHY related bits and register the ulpi interface.

>  
> - ret = dwc3_core_soft_reset(dwc);
> + ret = dwc3_core_get_phy(dwc);
>   if (ret)
>   goto err0;
>  

we got the PHYs. all OK here.

> - ret = dwc3_phy_setup(dwc);
> + ret = dwc3_core_soft_reset(dwc);
>   if (ret)
>   goto err0;

Now we do a soft reset. This means we loose the PHY configuration bits that we 
did
in dwc3_phy_setup. So we need to call dwc3_phy_setup again but not re-register 
the ulpi interface.
I can use a flag there so that dwc3_ulpi_init() is done only once.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: core: Don't try to get PHYs during suspend/resume

2018-01-10 Thread Roger Quadros


On 10/01/18 16:04, Felipe Balbi wrote:
> 
> Hi,
> 
> Roger Quadros <rog...@ti.com> writes:
>>> Roger Quadros <rog...@ti.com> writes:
>>>> Felipe,
>>>>
>>>> On 10/01/18 15:11, Roger Quadros wrote:
>>>>> The USB PHYs should be requested only once during the life cycle of
>>>>> this driver.
>>>>>
>>>>> As dwc3_core_init() is called during system suspend/resume
>>>>> it will result in multiple calls to dwc3_core_get_phy() which is wrong.
>>>>>
>>>>> To prevent that let's move dwc3_core_get_phy() call
>>>>> outside dwc3_core_init().
>>>>>
>>>>> Fixes: 541768b08a4 ("usb: dwc3: core: Call dwc3_core_get_phy() before 
>>>>> initializing phys")
>>>>> Cc: linux-stable <sta...@vger.kernel.org> # >= v4.13
>>>>> Signed-off-by: Roger Quadros <rog...@ti.com>
>>>>
>>>> FYI. this patch brings the code back to
>>>> revert 541768b08a40("usb: dwc3: core: Call dwc3_core_get_phy() 
>>>> before initializing phys")
>>>> revert f54edb539c11("usb: dwc3: core: initialize ULPI before 
>>>> trying to get the PHY")
>>>>
>>>> So looks like this will break ULPI PHY case?
>>>>
>>>> Where do we initialize ULPI PHY, in dwc3_phy_setup()?
>>>>
>>>> if so then 541768b08a40 breaks the ULPI PHY case as well, right?
>>>
>>> indeed, that commit regressed ULPI PHYs :-(
>>>
>>> Seems like it should be more like below:
>>>
>>> @@ -754,15 +754,15 @@ static int dwc3_core_init(struct dwc3 *dwc)
>>> dwc->maximum_speed = USB_SPEED_HIGH;
>>> }
>>>  
>>> -   ret = dwc3_core_get_phy(dwc);
>>> +   ret = dwc3_phy_setup(dwc);
>>
>> But can we do a dwc3_phy_setup() without doing the soft reset of the 
>> controller first?
> 
> as long as clocks are running, we can do that, yes.
> 
>>> -   ret = dwc3_core_soft_reset(dwc);
>>> +   ret = dwc3_core_get_phy(dwc);
>>
>> we can get_phy in dwc3_core_init() as it will get called on resume().
>> This was the $subject of this patch.
> 
> indeed. thanks :-)
> 

oops sorry. I meant we can't call dwc3_core_get_phy() in dwc3_core_init(). :P

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: core: Don't try to get PHYs during suspend/resume

2018-01-10 Thread Roger Quadros
On 10/01/18 15:33, Felipe Balbi wrote:
> 
> Hi,
> 
> Roger Quadros <rog...@ti.com> writes:
>> Felipe,
>>
>> On 10/01/18 15:11, Roger Quadros wrote:
>>> The USB PHYs should be requested only once during the life cycle of
>>> this driver.
>>>
>>> As dwc3_core_init() is called during system suspend/resume
>>> it will result in multiple calls to dwc3_core_get_phy() which is wrong.
>>>
>>> To prevent that let's move dwc3_core_get_phy() call
>>> outside dwc3_core_init().
>>>
>>> Fixes: 541768b08a4 ("usb: dwc3: core: Call dwc3_core_get_phy() before 
>>> initializing phys")
>>> Cc: linux-stable <sta...@vger.kernel.org> # >= v4.13
>>> Signed-off-by: Roger Quadros <rog...@ti.com>
>>
>> FYI. this patch brings the code back to
>> revert 541768b08a40  ("usb: dwc3: core: Call dwc3_core_get_phy() before 
>> initializing phys")
>> revert f54edb539c11  ("usb: dwc3: core: initialize ULPI before trying to get 
>> the PHY")
>>
>> So looks like this will break ULPI PHY case?
>>
>> Where do we initialize ULPI PHY, in dwc3_phy_setup()?
>>
>> if so then 541768b08a40 breaks the ULPI PHY case as well, right?
> 
> indeed, that commit regressed ULPI PHYs :-(
> 
> Seems like it should be more like below:
> 
> @@ -754,15 +754,15 @@ static int dwc3_core_init(struct dwc3 *dwc)
>   dwc->maximum_speed = USB_SPEED_HIGH;
>   }
>  
> - ret = dwc3_core_get_phy(dwc);
> + ret = dwc3_phy_setup(dwc);

But can we do a dwc3_phy_setup() without doing the soft reset of the controller 
first?


>   if (ret)
>   goto err0;
>  
> - ret = dwc3_core_soft_reset(dwc);
> + ret = dwc3_core_get_phy(dwc);

we can get_phy in dwc3_core_init() as it will get called on resume().
This was the $subject of this patch.

>   if (ret)
>   goto err0;
>  
> - ret = dwc3_phy_setup(dwc);
> + ret = dwc3_core_soft_reset(dwc);
>   if (ret)
>   goto err0;
>  
> And maybe we rename dwc3_phy_setup() to dwc3_phy_intf_config() just to
> make the name match what the function actually does. Can you check that
> it won't regress the case reported by Carlos? If that works, then we
> would have to move BOTH dwc3_phy_setup() (dwc3_phy_intf_config()) and
> dwc3_core_get_phy() outside of dwc3_core_init(), which would mean
> duplicated code in suspend/resume handlers.
> 
> I'm sure we can sort that out in another way; but the proper order is:
> 
> -> initialize ULPI (if necessary)
> -> get phy
> -> soft reset
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [PATCH] usb: dwc3: core: Don't try to get PHYs during suspend/resume

2018-01-10 Thread Roger Quadros
Felipe,

On 10/01/18 15:11, Roger Quadros wrote:
> The USB PHYs should be requested only once during the life cycle of
> this driver.
> 
> As dwc3_core_init() is called during system suspend/resume
> it will result in multiple calls to dwc3_core_get_phy() which is wrong.
> 
> To prevent that let's move dwc3_core_get_phy() call
> outside dwc3_core_init().
> 
> Fixes: 541768b08a4 ("usb: dwc3: core: Call dwc3_core_get_phy() before 
> initializing phys")
> Cc: linux-stable <sta...@vger.kernel.org> # >= v4.13
> Signed-off-by: Roger Quadros <rog...@ti.com>

FYI. this patch brings the code back to
revert 541768b08a40 ("usb: dwc3: core: Call dwc3_core_get_phy() before 
initializing phys")
revert f54edb539c11 ("usb: dwc3: core: initialize ULPI before trying to get 
the PHY")

So looks like this will break ULPI PHY case?

Where do we initialize ULPI PHY, in dwc3_phy_setup()?

if so then 541768b08a40 breaks the ULPI PHY case as well, right?

> ---
>  drivers/usb/dwc3/core.c | 10 --
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 0783250..1274251 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -722,8 +722,6 @@ static void dwc3_core_setup_global_control(struct dwc3 
> *dwc)
>   dwc3_writel(dwc->regs, DWC3_GCTL, reg);
>  }
>  
> -static int dwc3_core_get_phy(struct dwc3 *dwc);
> -
>  /**
>   * dwc3_core_init - Low-level initialization of DWC3 Core
>   * @dwc: Pointer to our controller context structure
> @@ -754,10 +752,6 @@ static int dwc3_core_init(struct dwc3 *dwc)
>   dwc->maximum_speed = USB_SPEED_HIGH;
>   }
>  
> - ret = dwc3_core_get_phy(dwc);
> - if (ret)
> - goto err0;
> -
>   ret = dwc3_core_soft_reset(dwc);
>   if (ret)
>   goto err0;
> @@ -1177,6 +1171,10 @@ static int dwc3_probe(struct platform_device *pdev)
>   platform_set_drvdata(pdev, dwc);
>   dwc3_cache_hwparams(dwc);
>  
> + ret = dwc3_core_get_phy(dwc);
> + if (ret)
> + goto err0;
> +
>   spin_lock_init(>lock);
>  
>   pm_runtime_set_active(dev);
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


[PATCH] usb: dwc3: core: Don't try to get PHYs during suspend/resume

2018-01-10 Thread Roger Quadros
The USB PHYs should be requested only once during the life cycle of
this driver.

As dwc3_core_init() is called during system suspend/resume
it will result in multiple calls to dwc3_core_get_phy() which is wrong.

To prevent that let's move dwc3_core_get_phy() call
outside dwc3_core_init().

Fixes: 541768b08a4 ("usb: dwc3: core: Call dwc3_core_get_phy() before 
initializing phys")
Cc: linux-stable <sta...@vger.kernel.org> # >= v4.13
Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/dwc3/core.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 0783250..1274251 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -722,8 +722,6 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc)
dwc3_writel(dwc->regs, DWC3_GCTL, reg);
 }
 
-static int dwc3_core_get_phy(struct dwc3 *dwc);
-
 /**
  * dwc3_core_init - Low-level initialization of DWC3 Core
  * @dwc: Pointer to our controller context structure
@@ -754,10 +752,6 @@ static int dwc3_core_init(struct dwc3 *dwc)
dwc->maximum_speed = USB_SPEED_HIGH;
}
 
-   ret = dwc3_core_get_phy(dwc);
-   if (ret)
-   goto err0;
-
ret = dwc3_core_soft_reset(dwc);
if (ret)
goto err0;
@@ -1177,6 +1171,10 @@ static int dwc3_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dwc);
dwc3_cache_hwparams(dwc);
 
+   ret = dwc3_core_get_phy(dwc);
+   if (ret)
+   goto err0;
+
spin_lock_init(>lock);
 
pm_runtime_set_active(dev);
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


Re: [RESEND PATCH 1/3] usb: dwc3: Don't reinitialize core during host bus-suspend/resume

2018-01-10 Thread Roger Quadros
On 10/01/18 14:57, Felipe Balbi wrote:
> 
> Hi,
> 
> Roger Quadros <rog...@ti.com> writes:
>> Hi Manu,
>>
>> On 27/09/17 14:19, Manu Gautam wrote:
>>> Driver powers-off PHYs and reinitializes DWC3 core and gadget on
>>> resume. While this works fine for gadget mode but in host
>>> mode there is not re-initialization of host stack. Also, resetting
>>> bus as part of bus_suspend/resume is not correct which could affect
>>> (or disconnect) connected devices.
>>> Fix this by not reinitializing core on suspend/resume in host mode
>>> for HOST only and OTG/drd configurations.
>>>
>>
>> All this seems correct but we (TI) were relying on dwc3_core_exit() to be 
>> called
>> during dwc3_suspend() to have the lowest power state for our platforms.
>>
>> After this patch, DWC3 controller and PHYs won't be turned off thus
>> preventing our platform from reaching low power levels.
>>
>> So this is a regression for us (TI) in v4.15-rc.
>>
>> Felipe, do you agree?
>>
>> If yes I can send a patch which fixes the regression
>> and also makes USB host work after suspend/resume.
> 
> A power consumption regression is still a regression. But it's super
> late in the -rc cycle, I think we need to get this merged after 4.16-rc1
> and make sure to Cc stable.
> 
> Should be more than enough time to review and test patches.
> 

Fine with me. 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: [RESEND PATCH 1/3] usb: dwc3: Don't reinitialize core during host bus-suspend/resume

2018-01-10 Thread Roger Quadros
Hi Manu,

On 27/09/17 14:19, Manu Gautam wrote:
> Driver powers-off PHYs and reinitializes DWC3 core and gadget on
> resume. While this works fine for gadget mode but in host
> mode there is not re-initialization of host stack. Also, resetting
> bus as part of bus_suspend/resume is not correct which could affect
> (or disconnect) connected devices.
> Fix this by not reinitializing core on suspend/resume in host mode
> for HOST only and OTG/drd configurations.
> 

All this seems correct but we (TI) were relying on dwc3_core_exit() to be called
during dwc3_suspend() to have the lowest power state for our platforms.

After this patch, DWC3 controller and PHYs won't be turned off thus
preventing our platform from reaching low power levels.

So this is a regression for us (TI) in v4.15-rc.

Felipe, do you agree?

If yes I can send a patch which fixes the regression
and also makes USB host work after suspend/resume.


> Signed-off-by: Manu Gautam 
> ---
>  drivers/usb/dwc3/core.c | 43 ---
>  1 file changed, 20 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 03474d3..f75613f 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -927,6 +927,7 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
>  
>   switch (dwc->dr_mode) {
>   case USB_DR_MODE_PERIPHERAL:
> + dwc->current_dr_role = DWC3_GCTL_PRTCAP_DEVICE;
>   dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);
>  
>   if (dwc->usb2_phy)
> @@ -942,6 +943,7 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
>   }
>   break;
>   case USB_DR_MODE_HOST:
> + dwc->current_dr_role = DWC3_GCTL_PRTCAP_HOST;
>   dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
>  
>   if (dwc->usb2_phy)
> @@ -1293,21 +1295,19 @@ static int dwc3_suspend_common(struct dwc3 *dwc)
>  {
>   unsigned long   flags;
>  
> - switch (dwc->dr_mode) {
> - case USB_DR_MODE_PERIPHERAL:
> - case USB_DR_MODE_OTG:
> + switch (dwc->current_dr_role) {
> + case DWC3_GCTL_PRTCAP_DEVICE:
>   spin_lock_irqsave(>lock, flags);
>   dwc3_gadget_suspend(dwc);
>   spin_unlock_irqrestore(>lock, flags);
> + dwc3_core_exit(dwc);
>   break;
> - case USB_DR_MODE_HOST:
> + case DWC3_GCTL_PRTCAP_HOST:
>   default:
>   /* do nothing */
>   break;
>   }
>  
> - dwc3_core_exit(dwc);
> -
>   return 0;
>  }
>  
> @@ -1316,18 +1316,17 @@ static int dwc3_resume_common(struct dwc3 *dwc)
>   unsigned long   flags;
>   int ret;
>  
> - ret = dwc3_core_init(dwc);
> - if (ret)
> - return ret;
> + switch (dwc->current_dr_role) {
> + case DWC3_GCTL_PRTCAP_DEVICE:
> + ret = dwc3_core_init(dwc);
> + if (ret)
> + return ret;
>  
> - switch (dwc->dr_mode) {
> - case USB_DR_MODE_PERIPHERAL:
> - case USB_DR_MODE_OTG:
>   spin_lock_irqsave(>lock, flags);
>   dwc3_gadget_resume(dwc);
>   spin_unlock_irqrestore(>lock, flags);
> - /* FALLTHROUGH */
> - case USB_DR_MODE_HOST:
> + break;
> + case DWC3_GCTL_PRTCAP_HOST:
>   default:
>   /* do nothing */
>   break;
> @@ -1338,7 +1337,7 @@ static int dwc3_resume_common(struct dwc3 *dwc)
>  
>  static int dwc3_runtime_checks(struct dwc3 *dwc)
>  {
> - switch (dwc->dr_mode) {
> + switch (dwc->current_dr_role) {
>   case USB_DR_MODE_PERIPHERAL:
>   case USB_DR_MODE_OTG:
>   if (dwc->connected)
> @@ -1381,12 +1380,11 @@ static int dwc3_runtime_resume(struct device *dev)
>   if (ret)
>   return ret;
>  
> - switch (dwc->dr_mode) {
> - case USB_DR_MODE_PERIPHERAL:
> - case USB_DR_MODE_OTG:
> + switch (dwc->current_dr_role) {
> + case DWC3_GCTL_PRTCAP_DEVICE:
>   dwc3_gadget_process_pending_events(dwc);
>   break;
> - case USB_DR_MODE_HOST:
> + case DWC3_GCTL_PRTCAP_HOST:
>   default:
>   /* do nothing */
>   break;
> @@ -1402,13 +1400,12 @@ static int dwc3_runtime_idle(struct device *dev)
>  {
>   struct dwc3 *dwc = dev_get_drvdata(dev);
>  
> - switch (dwc->dr_mode) {
> - case USB_DR_MODE_PERIPHERAL:
> - case USB_DR_MODE_OTG:
> + switch (dwc->current_dr_role) {
> + case DWC3_GCTL_PRTCAP_DEVICE:
>   if (dwc3_runtime_checks(dwc))
>   return -EBUSY;
>   break;
> - case USB_DR_MODE_HOST:
> + case DWC3_GCTL_PRTCAP_HOST:
>   default:
>   /* do nothing */
>   break;
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--

Re: xhci_hcd HC died; cleaning up with TUSB7340 and µPD720201

2017-11-20 Thread Roger Quadros
On 20/11/17 15:19, Vignesh R wrote:
> 
> 
> On Monday 20 November 2017 01:31 PM, Roger Quadros wrote:
> [...]
>>>
>>> So, could you try reverting commit 8c934095fa2f3 and 
>>> also apply below patch and let me know if that fixes the issue?
>>>
>>> ---
>>>
>>> diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
>>> index e77a4ceed74c..8280abc56f30 100644
>>> --- a/drivers/pci/dwc/pci-dra7xx.c
>>> +++ b/drivers/pci/dwc/pci-dra7xx.c
>>> @@ -259,10 +259,17 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int 
>>> irq, void *arg)
>>> u32 reg;
>>>  
>>> reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI);
>>> +   dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI, reg);
>>>  
>>> switch (reg) {
>>> case MSI:
>>> -   dw_handle_msi_irq(pp);
>>> +   /*
>>> +* Need to make sure no MSI IRQs are pending before
>>> +* exiting handler, else the wrapper will not catch new
>>> +* IRQs. So loop around till dw_handle_msi_irq() returns
>>> +* IRQ_NONE
>>> +*/
>>> +   while (dw_handle_msi_irq(pp) != IRQ_NONE);
>>
>> To avoid this kind of looping, shouldn't we be disabling all IRQ events while
>> the interrupt handler is running and enable them just before we return from 
>> the hardirq
>> handler?
> 
> IIUC, you are saying to disable all MSIs at PCIe designware core level,
> then call dw_handle_msi_irq() and then enable MSIs after hardirq
> returns. But, the problem is if PCIe EP raises another MSI after the
> call to EP's handler but before re-enabling MSIs, then it will be
> ignored as IRQs are not yet enabled.
> Ideally, EP's support Per Vector Masking(PVM) which allow RC to prevent
> EP from sending MSI messages for sometime. But, unfortunately, the cards
> mentioned here don't support this feature.

I'm not aware of MSIs.

But for any typical hardware, there should be an interrupt event enable 
register and an
interrupt mask register.

In the IRQ handler, we mask the interrupt but still keep the interrupt events 
enabled so that
they can be latched during the time the interrupt was masked.

When the interrupt is unmasked at end of the IRQ handler, it should re-trigger 
the interrupt
if any events were latched and pending.

This way you don't need to keep checking for any pending events in the IRQ 
handler.

> 
>>
>>
>>> break;
>>> case INTA:
>>> case INTB:
>>> @@ -273,8 +280,6 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, 
>>> void *arg)
>>> break;
>>> }
>>>  
>>> -   dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI, reg);
>>> -
>>> return IRQ_HANDLED;
>>>  }
>>>
>>>
>>>
>>>
>>
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: xhci_hcd HC died; cleaning up with TUSB7340 and µPD720201

2017-11-20 Thread Roger Quadros
Hi Vignesh,

On 16/11/17 14:26, Vignesh R wrote:
> +linux-pci
> 
> Hi Chris,
> 
> On Thursday 16 November 2017 05:20 PM, Quadros, Roger wrote:
>> +Vignesh
>>
>> On 13/09/17 17:26, Chris Welch wrote:
>>> We are developing a product based on the TI AM5728 EVM.  The product 
>>> utilizes a TUSB7340 PCIe USB host for additional ports.  The TUSB7340 is 
>>> detected and setup properly and works OK with low data rate devices.  
>>> However, hot plugging a Realtek USB network adapter and doing Ethernet 
>>> transfer bandwidth testing using iperf3 causes the TUSB7340 host to be  
>>> locked out.  The TUSB7340 host appears to no longer communicate and the 
>>> logging indicates xhci_hcd :01:00.0: HC died; cleaning up.  Same issue 
>>> occurs with another USB Ethernet adapter I tried (Asus).
>>>
>>> We looked at using another host and found a mini PCIe card that utilizes 
>>> the µPD720201 and can be directly installed on the TI AM5728 EVM.  The card 
>>> is detected properly and we reran the transfer test.  The uPD720201 gets 
>>> locks out with the same problem.
>>>
>>> The AM5728 testing was performed using the TI SD card stock 
>>> am57xx-evm-linux-04.00.00.04.img, kernel am57xx-evm 4.9.28-geed43d1050, and 
>>> it reports that it is using the TI AM572x EVM Rev A3 device tree.
>>>
>>> It shows the following logging when it fails (this is with the TI EVM and 
>>> uPD720201).
>>>
>>> [  630.400899] xhci_hcd :01:00.0: xHCI host not responding to stop 
>>> endpoint command.
>>> [  630.408769] xhci_hcd :01:00.0: Assuming host is dying, halting host.
>>> [  630.420849] r8152 2-4:1.0 enp1s0u4: Tx status -108
>>> [  630.425667] r8152 2-4:1.0 enp1s0u4: Tx status -108
>>> [  630.430483] r8152 2-4:1.0 enp1s0u4: Tx status -108
>>> [  630.435297] r8152 2-4:1.0 enp1s0u4: Tx status -108
>>> [  630.440122] xhci_hcd :01:00.0: HC died; cleaning up
>>> [  630.453961] usb 2-4: USB disconnect, device number 2
>>>
>>> The problem appears to be a general driver issue given we get the same 
>>> problem with both the  TUSB7340 and the µPD720201.
> 
> Seems like PCIe driver is missing MSI IRQs leading to stall. 
> Reading xHCI registers via PCIe mem space confirms this.
> 
> I see two problems wrt MSI handling:
> Since commit 8c934095fa2f3 ("PCI: dwc: Clear MSI interrupt status after it is 
> handled, not before"),
> dwc clears MSI status after calling EP's IRQ handler. But, it happens that 
> another MSI interrupt is
> raised just at the end of EP's IRQ handler and before clearing MSI status.
> This will result in loss of new MSI IRQ as we clear the MSI IRQ status 
> without handling.
> 
> Another problem appears to be wrt dra7xx PCIe wrapper:
> PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI does not seem to catch MSI IRQs unless,
> its ensured that PCIE_MSI_INTR0_STATUS register read returns 0.
> 
> So, could you try reverting commit 8c934095fa2f3 and 
> also apply below patch and let me know if that fixes the issue?
> 
> ---
> 
> diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
> index e77a4ceed74c..8280abc56f30 100644
> --- a/drivers/pci/dwc/pci-dra7xx.c
> +++ b/drivers/pci/dwc/pci-dra7xx.c
> @@ -259,10 +259,17 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, 
> void *arg)
> u32 reg;
>  
> reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI);
> +   dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI, reg);
>  
> switch (reg) {
> case MSI:
> -   dw_handle_msi_irq(pp);
> +   /*
> +* Need to make sure no MSI IRQs are pending before
> +* exiting handler, else the wrapper will not catch new
> +* IRQs. So loop around till dw_handle_msi_irq() returns
> +* IRQ_NONE
> +*/
> +   while (dw_handle_msi_irq(pp) != IRQ_NONE);

To avoid this kind of looping, shouldn't we be disabling all IRQ events while
the interrupt handler is running and enable them just before we return from the 
hardirq
handler?


> break;
> case INTA:
> case INTB:
> @@ -273,8 +280,6 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, 
> void *arg)
> break;
> }
>  
> -   dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI, reg);
> -
> return IRQ_HANDLED;
>  }
> 
> 
> 
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


Re: xhci_hcd HC died; cleaning up with TUSB7340 and µPD720201

2017-11-16 Thread Roger Quadros
+Vigesh

On 13/09/17 17:26, Chris Welch wrote:
> We are developing a product based on the TI AM5728 EVM.  The product utilizes 
> a TUSB7340 PCIe USB host for additional ports.  The TUSB7340 is detected and 
> setup properly and works OK with low data rate devices.  However, hot 
> plugging a Realtek USB network adapter and doing Ethernet transfer bandwidth 
> testing using iperf3 causes the TUSB7340 host to be  locked out.  The 
> TUSB7340 host appears to no longer communicate and the logging indicates 
> xhci_hcd :01:00.0: HC died; cleaning up.  Same issue occurs with another 
> USB Ethernet adapter I tried (Asus).
> 
> We looked at using another host and found a mini PCIe card that utilizes the 
> µPD720201 and can be directly installed on the TI AM5728 EVM.  The card is 
> detected properly and we reran the transfer test.  The uPD720201 gets locks 
> out with the same problem.
> 
> The AM5728 testing was performed using the TI SD card stock 
> am57xx-evm-linux-04.00.00.04.img, kernel am57xx-evm 4.9.28-geed43d1050, and 
> it reports that it is using the TI AM572x EVM Rev A3 device tree.
> 
> It shows the following logging when it fails (this is with the TI EVM and 
> uPD720201).
> 
> [  630.400899] xhci_hcd :01:00.0: xHCI host not responding to stop 
> endpoint command.
> [  630.408769] xhci_hcd :01:00.0: Assuming host is dying, halting host.
> [  630.420849] r8152 2-4:1.0 enp1s0u4: Tx status -108
> [  630.425667] r8152 2-4:1.0 enp1s0u4: Tx status -108
> [  630.430483] r8152 2-4:1.0 enp1s0u4: Tx status -108
> [  630.435297] r8152 2-4:1.0 enp1s0u4: Tx status -108
> [  630.440122] xhci_hcd :01:00.0: HC died; cleaning up
> [  630.453961] usb 2-4: USB disconnect, device number 2
> 
> The problem appears to be a general driver issue given we get the same 
> problem with both the  TUSB7340 and the µPD720201.
> 
> I've tried the 4.4.49, 4.12.3 and 4.13.1 kernels and they also fail.
> 
> I tried the TI E2E support community and they were unable to provide any 
> solutions.
> 
> Here is a sample session with the TUSB7340:
> 
> root@arm:~# !iperf3
> iperf3 -c 10.14.21.95 -t 6000
> Connecting to host 10.14.21.95, port 5201
> [ 4] local 10.14.21.89 port 60978 connected to 10.14.21.95 port 5201
> [ ID] Interval Transfer Bandwidth Retr Cwnd
> [ 4] 0.00-1.00 sec 14.2 MBytes 119 Mbits/sec 1 1.41 KBytes
> [ 4] 1.00-2.00 sec 0.00 Bytes 0.00 bits/sec 0 1.41 KBytes
> [ 4] 2.00-3.00 sec 0.00 Bytes 0.00 bits/sec 0 1.41 KBytes
> [ 4] 3.00-4.00 sec 0.00 Bytes 0.00 bits/sec 0 1.41 KBytes
> [ 4] 4.00-5.00 sec 0.00 Bytes 0.00 bits/sec 0 1.41 KBytes
> [ 4] 5.00-6.00 sec 0.00 Bytes 0.00 bits/sec 0 1.41 KBytes
> [ 4] 6.00-7.00 sec 0.00 Bytes 0.00 bits/sec 0 1.41 KBytes
> ^C[ 4] 7.00-7.48 sec 0.00 Bytes 0.00 bits/sec 0 1.41 KBytes
> - - - - - - - - - - - - - - - - - - - - - - - - -
> [ ID] Interval Transfer Bandwidth Retr
> [ 4] 0.00-7.48 sec 14.2 MBytes 15.9 Mbits/sec 1 sender
> [ 4] 0.00-7.48 sec 0.00 Bytes 0.00 bits/sec receiver
> iperf3: interrupt - the client has terminated
> root@arm:~# [ 118.187204] xhci_hcd 0001:07:00.0: xHCI host controller not 
> responding, assume dead
> [ 118.196419] xhci_hcd 0001:07:00.0: HC died; cleaning up
> 
> Any suggestions on how we can address this problem?
> 
> --
> 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
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
--
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


[PATCH] USB: dummy-hcd: don't set gadget.speed in dummy_hub_control()

2017-11-03 Thread Roger Quadros
There will never be a case when gadget.speed isn't already
USB_SPEED_FULL if connection is not USB-3 and gadget.speed
is not USB_SPEED_HIGH or USB_SPEED_LOW.

Remove the unnecessary code.

Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/usb/gadget/udc/dummy_hcd.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/usb/gadget/udc/dummy_hcd.c 
b/drivers/usb/gadget/udc/dummy_hcd.c
index c42ca8e..41cefc5 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -2166,8 +2166,6 @@ static int dummy_hub_control(
USB_PORT_STAT_LOW_SPEED;
break;
default:
-   dum_hcd->dum->gadget.speed =
-   USB_SPEED_FULL;
break;
}
}
-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. 
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

--
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


  1   2   3   4   5   6   7   8   9   10   >