Re: [Kernel] usbhid 3-2:1.1: couldn't find an input interrupt endpoint

2017-02-20 Thread Oliver Neukum
Am Montag, den 20.02.2017, 15:28 -0300 schrieb Cristian:
> Hello,
> 
> dmesg:
> [2.465370] usbhid 3-2:1.1: couldn't find an input interrupt
> endpoint

Most likely it does not have an interrupt endpoint. You will need
to provide "lsusb -v" not lspci, as this bug is about a USB device.
Is this a regression?

Regards
Oliver

--
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 1/2] Fix format overflows

2017-02-20 Thread Jonathan Dieter
Thanks for looking at this.  One quick question before I put out
version two with your corrections:

On Tue, 2017-02-21 at 07:12 +0100, Krzysztof Opasiak wrote:
> Hi,
> 
> W dniu 2017-02-20 o 21:51, Jonathan Dieter pisze:
> > The usbip userspace tools call sprintf()/snprintf() and don't check
> > for
> > the return value which can lead the paths to overflow, truncating
> > the
> > final file in the path.
> > 
> > More urgently, GCC 7 now warns that these aren't checked with
> > -Wformat-overflow, and with -Werror enabled in configure.ac, that
> > makes
> > these tools unbuildable.
> > 
> > This patch fixes these problems by replacing sprintf() with
> > snprintf() in
> > one place and adding checks for the return value of snprintf().
> > 
> > Reviewed-by: Peter Senna Tschudin 
> > Signed-off-by: Jonathan Dieter 
> > ---
> >  tools/usb/usbip/libsrc/usbip_common.c  |  8 +++-
> >  tools/usb/usbip/libsrc/usbip_host_common.c | 25
> > -
> >  2 files changed, 27 insertions(+), 6 deletions(-)
> > 
> > diff --git a/tools/usb/usbip/libsrc/usbip_common.c
> > b/tools/usb/usbip/libsrc/usbip_common.c
> > index ac73710..fc875ee 100644
> > --- a/tools/usb/usbip/libsrc/usbip_common.c
> > +++ b/tools/usb/usbip/libsrc/usbip_common.c
> > @@ -215,9 +215,15 @@ int read_usb_interface(struct usbip_usb_device
> > *udev, int i,
> >        struct usbip_usb_interface *uinf)
> >  {
> >     char busid[SYSFS_BUS_ID_SIZE];
> > +   int size;
> >     struct udev_device *sif;
> > 
> > -   sprintf(busid, "%s:%d.%d", udev->busid, udev-
> > >bConfigurationValue, i);
> > +   size = snprintf(busid, SYSFS_BUS_ID_SIZE, "%s:%d.%d",
> 
> why not sizeof(busid)?
> 
> > +   udev->busid, udev->bConfigurationValue,
> > i);
> > +   if (size >= SYSFS_BUS_ID_SIZE) {
> 
> As above.
> 
> > +   err("busid length %i >= SYSFS_BUS_ID_SIZE", size);

Should I also change the error messages to use real values?
Ex:
err("busid length %i >= %i", size, sizeof(busid));

> > +   return -1;
> > +   }
> > 
> >     sif = udev_device_new_from_subsystem_sysname(udev_context,
> > "usb", busid);
> >     if (!sif) {
> > diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c
> > b/tools/usb/usbip/libsrc/usbip_host_common.c
> > index 9d41522..690cd49 100644
> > --- a/tools/usb/usbip/libsrc/usbip_host_common.c
> > +++ b/tools/usb/usbip/libsrc/usbip_host_common.c
> > @@ -40,13 +40,19 @@ struct udev *udev_context;
> >  static int32_t read_attr_usbip_status(struct usbip_usb_device
> > *udev)
> >  {
> >     char status_attr_path[SYSFS_PATH_MAX];
> > +   int size;
> >     int fd;
> >     int length;
> >     char status;
> >     int value = 0;
> > 
> > -   snprintf(status_attr_path, SYSFS_PATH_MAX,
> > "%s/usbip_status",
> > -    udev->path);
> > +   size = snprintf(status_attr_path, SYSFS_PATH_MAX,
> > "%s/usbip_status",
> 
> The same here.
> 
> > +   udev->path);
> > +   if (size >= SYSFS_PATH_MAX) {
> > +   err("usbip_status path length %i >=
> > SYSFS_PATH_MAX", size);
> > +   return -1;
> > +   }
> > +
> > 
> >     fd = open(status_attr_path, O_RDONLY);
> >     if (fd < 0) {
> > @@ -218,6 +224,7 @@ int usbip_export_device(struct
> > usbip_exported_device *edev, int sockfd)
> >  {
> >     char attr_name[] = "usbip_sockfd";
> >     char sockfd_attr_path[SYSFS_PATH_MAX];
> > +   int size;
> >     char sockfd_buff[30];
> >     int ret;
> > 
> > @@ -237,10 +244,18 @@ int usbip_export_device(struct
> > usbip_exported_device *edev, int sockfd)
> >     }
> > 
> >     /* only the first interface is true */
> > -   snprintf(sockfd_attr_path, sizeof(sockfd_attr_path),
> > "%s/%s",
> > -    edev->udev.path, attr_name);
> > +   size = snprintf(sockfd_attr_path,
> > sizeof(sockfd_attr_path), "%s/%s",
> > +   edev->udev.path, attr_name);
> > +   if (size >= SYSFS_PATH_MAX) {
> 
> hmmm this should be sizeof(sockfd_attr_path) not SYSFS_PATH_MAX
> 
> > +   err("exported device path length %i >=
> > SYSFS_PATH_MAX", size);
> > +   return -1;
> > +   }
> > 
> > -   snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n",
> > sockfd);
> > +   size = snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n",
> > sockfd);
> > +   if (size >= 30) {
> 
> Please don't hardcode such values in if. use sizeof() like one line
> above
> 
> > +   err("socket length %i >= 30", size);
> > +   return -1;
> > +   }
> > 
> >     ret = write_sysfs_attribute(sockfd_attr_path, sockfd_buff,
> >     strlen(sockfd_buff));
> > 
> 
> Best regards,
--
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 1/2] Fix format overflows

2017-02-20 Thread Krzysztof Opasiak


Hi,

W dniu 2017-02-20 o 21:51, Jonathan Dieter pisze:

The usbip userspace tools call sprintf()/snprintf() and don't check for
the return value which can lead the paths to overflow, truncating the
final file in the path.

More urgently, GCC 7 now warns that these aren't checked with
-Wformat-overflow, and with -Werror enabled in configure.ac, that makes
these tools unbuildable.

This patch fixes these problems by replacing sprintf() with snprintf() in
one place and adding checks for the return value of snprintf().

Reviewed-by: Peter Senna Tschudin 
Signed-off-by: Jonathan Dieter 
---
 tools/usb/usbip/libsrc/usbip_common.c  |  8 +++-
 tools/usb/usbip/libsrc/usbip_host_common.c | 25 -
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/tools/usb/usbip/libsrc/usbip_common.c 
b/tools/usb/usbip/libsrc/usbip_common.c
index ac73710..fc875ee 100644
--- a/tools/usb/usbip/libsrc/usbip_common.c
+++ b/tools/usb/usbip/libsrc/usbip_common.c
@@ -215,9 +215,15 @@ int read_usb_interface(struct usbip_usb_device *udev, int 
i,
   struct usbip_usb_interface *uinf)
 {
char busid[SYSFS_BUS_ID_SIZE];
+   int size;
struct udev_device *sif;

-   sprintf(busid, "%s:%d.%d", udev->busid, udev->bConfigurationValue, i);
+   size = snprintf(busid, SYSFS_BUS_ID_SIZE, "%s:%d.%d",


why not sizeof(busid)?


+   udev->busid, udev->bConfigurationValue, i);
+   if (size >= SYSFS_BUS_ID_SIZE) {


As above.


+   err("busid length %i >= SYSFS_BUS_ID_SIZE", size);
+   return -1;
+   }

sif = udev_device_new_from_subsystem_sysname(udev_context, "usb", 
busid);
if (!sif) {
diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c 
b/tools/usb/usbip/libsrc/usbip_host_common.c
index 9d41522..690cd49 100644
--- a/tools/usb/usbip/libsrc/usbip_host_common.c
+++ b/tools/usb/usbip/libsrc/usbip_host_common.c
@@ -40,13 +40,19 @@ struct udev *udev_context;
 static int32_t read_attr_usbip_status(struct usbip_usb_device *udev)
 {
char status_attr_path[SYSFS_PATH_MAX];
+   int size;
int fd;
int length;
char status;
int value = 0;

-   snprintf(status_attr_path, SYSFS_PATH_MAX, "%s/usbip_status",
-udev->path);
+   size = snprintf(status_attr_path, SYSFS_PATH_MAX, "%s/usbip_status",


The same here.


+   udev->path);
+   if (size >= SYSFS_PATH_MAX) {
+   err("usbip_status path length %i >= SYSFS_PATH_MAX", size);
+   return -1;
+   }
+

fd = open(status_attr_path, O_RDONLY);
if (fd < 0) {
@@ -218,6 +224,7 @@ int usbip_export_device(struct usbip_exported_device *edev, 
int sockfd)
 {
char attr_name[] = "usbip_sockfd";
char sockfd_attr_path[SYSFS_PATH_MAX];
+   int size;
char sockfd_buff[30];
int ret;

@@ -237,10 +244,18 @@ int usbip_export_device(struct usbip_exported_device 
*edev, int sockfd)
}

/* only the first interface is true */
-   snprintf(sockfd_attr_path, sizeof(sockfd_attr_path), "%s/%s",
-edev->udev.path, attr_name);
+   size = snprintf(sockfd_attr_path, sizeof(sockfd_attr_path), "%s/%s",
+   edev->udev.path, attr_name);
+   if (size >= SYSFS_PATH_MAX) {


hmmm this should be sizeof(sockfd_attr_path) not SYSFS_PATH_MAX


+   err("exported device path length %i >= SYSFS_PATH_MAX", size);
+   return -1;
+   }

-   snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd);
+   size = snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd);
+   if (size >= 30) {


Please don't hardcode such values in if. use sizeof() like one line above


+   err("socket length %i >= 30", size);
+   return -1;
+   }

ret = write_sysfs_attribute(sockfd_attr_path, sockfd_buff,
strlen(sockfd_buff));



Best regards,
--
Krzysztof Opasiak
Samsung R Institute Poland
Samsung Electronics
--
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


Fast Loans

2017-02-20 Thread Service Loans
Apply for a loan at 3% reply to this Email for more Info

Do you need a loan to pay up bill or to start a business? Email Us
--
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: [Kernel] usbhid 3-2:1.1: couldn't find an input interrupt endpoint

2017-02-20 Thread Greg KH
On Mon, Feb 20, 2017 at 03:28:37PM -0300, Cristian wrote:
> Hello,
> 
> dmesg:
> [2.465370] usbhid 3-2:1.1: couldn't find an input interrupt endpoint

And does this cause a problem?  Does the device not work?
What is the output of 'lsusb -v -s3:2' with the device plugged in?

thanks,

greg k-h
--
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/2] usb: host: plat: Enable xhci plat runtime PM

2017-02-20 Thread Baolin Wang
On 20 February 2017 at 23:10, Mathias Nyman
 wrote:
> On 20.02.2017 04:47, Baolin Wang wrote:
>>
>> Hi Mathias,
>>
>> On 6 February 2017 at 13:26, Baolin Wang  wrote:
>>>
>>> Hi Mathias,
>>>
>>> On 31 January 2017 at 21:14, Mathias Nyman
>>>  wrote:

 On 16.01.2017 12:56, Baolin Wang wrote:
>
>
> Hi Mathias,



 Hi

 Sorry about the long review delay
 CC Alan in case my pm assumptions need to be corrected


>
> On 13 December 2016 at 15:49, Baolin Wang 
> wrote:
>>
>>
>> Enable the xhci plat runtime PM for parent device to suspend/resume
>> xhci.
>> Also call pm_runtime_get_noresume() in probe() function in case the
>> parent
>> device doesn't call suspend/resume callback by runtime PM now.
>>
>> Signed-off-by: Baolin Wang 
>> ---
>> Changes since v4:
>>- No updates.
>>
>> Changes since v3:
>>- Fix kbuild error.
>>
>> Changes since v2:
>>- Add pm_runtime_get_noresume() in probe() function.
>>- Add pm_runtime_set_suspended()/pm_runtime_put_noidle() in
>> remove()
>> function.
>>
>> Changes since v1:
>>- No updates.
>> ---
>
>
>
> Do you have any comments about this patch? Thanks.
>
>>drivers/usb/host/xhci-plat.c |   41
>> -
>>1 file changed, 36 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/usb/host/xhci-plat.c
>> b/drivers/usb/host/xhci-plat.c
>> index ed56bf9..5805c6a 100644
>> --- a/drivers/usb/host/xhci-plat.c
>> +++ b/drivers/usb/host/xhci-plat.c
>> @@ -246,6 +246,10 @@ static int xhci_plat_probe(struct platform_device
>> *pdev)
>>   if (ret)
>>   goto dealloc_usb2_hcd;
>>
>> +   pm_runtime_get_noresume(>dev);
>> +   pm_runtime_set_active(>dev);
>> +   pm_runtime_enable(>dev);
>> +
>>   return 0;
>>
>>

 To me this looks like we are not really enabling runtime pm for xhci, we
 increment the
 usage count in probe, and keep it until remove is called.

 This would normally prevent parent dwc3 from runtime suspending, but I
 see
 that in patch 2/2 adds
 pm_suspend_ignore_children(dev, true) to dwc3, and, that dwc3 actually
 controls xhci runtime
 pm by calling pm_runtime_get/put for xhci in its own dwc3
 runtime_suspend/resume callbacks.

 Looks a bit upside down to me, what's the reason for this?

 what prevents calling pm_runtime_put_* before leaving probe in xhci and
 let
 pm code handle
 the runtime suspend and parent/child relationships?
>>>
>>>
>>> When dwc3 controller is working on host mode, which will create and
>>> add the USB hcd for host side. Then if we want to suspend dwc3
>>> controller as host mode, the USB device (bus) of host side will
>>> runtime suspend automatically if there are no slave attached (by
>>>
>>> usb_runtime_suspend()--->usb_suspend_both()--->usb_suspend_interface()--->usb_suspend_device()--->generic_suspend()--->hcd_bus_suspend()--->xhci_bus_suspend()),
>>> but we should not suspend xHCI device (issuing xhci_suspend()) now,
>>> since some other  controllers did not implement the runtime PM to
>>> control xHCI device's runtime state, which will cause other
>>> controllers can not resume xHCI device (issuing xhci_resume()) if the
>>> xHCI device suspend automatically by its child device. Thus we should
>>> get the runtime count for xHCI device in xhci_plat_probe() in case
>>> xHCI device will also suspend automatically by its child device.
>>> According to that, for xHCI device's parent: dwc3 device, we should
>>> put the xHCI device's runtime count to suspend xHCI device manually.
>>>
>>
>> Any more comments?
>>
>
> I think I at least partially understand your point. You don't want to enable
> runtime suspend for all xhci platform devices by default, but only for the
> ones
> that are part of dwc3.
>
> The implementation you suggest is that xhci platform driver always increase
> the xhci platform
> device usage counter during probe with pm_runtime_get_noresume(), and never
> decrement it,
> preventing xhci platform devices from runtime suspending by themselves.
>
> You then control xhci runtime suspend from dwc3 driver runtime suspend,
> allowing
> xhci platfrom controller to runtime suspend only when dwc3 runtime suspends
> by decrementing xhci
> platform device usage in dwc3 runtime suspend callback.
> As xhci is a child of dwc3 in this case,  dwc3 would never runtime suspend
> as long as xhci is running, so
> dwc3 needed to be detached from xhci by setting dwc3 to ignore its children
> to get it to work.

Yes, that's my point.

>
> I don't yet understand why we can't just keep 

[usb-misc] question about missing break in switch

2017-02-20 Thread Gustavo A. R. Silva


Hello everybody,

I ran into the following piece of code at  
drivers/usb/misc/usbtest.c:149 (linux-next)


149/* take the first altsetting with in-bulk + out-bulk;
150 * ignore other endpoints and altsettings.
151 */
152for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) {
153struct usb_host_endpoint*e;
154
155e = alt->endpoint + ep;
156switch (usb_endpoint_type(>desc)) {
157case USB_ENDPOINT_XFER_BULK:
158break;
159case USB_ENDPOINT_XFER_INT:
160if (dev->info->intr)
161goto try_intr;
162case USB_ENDPOINT_XFER_ISOC:
163if (dev->info->iso)
164goto try_iso;
165/* FALLTHROUGH */
166default:
167continue;
168}

The thing is that the case for USB_ENDPOINT_XFER_INT is not terminated  
by a break statement, and it falls through to the next case  
USB_ENDPOINT_XFER_ISOC, in case "if (dev->info->intr)" turns to be  
false.


My question here is if this code is intentional?
Similar to the case for USB_ENDPOINT_XFER_ISOC, which falls through to  
the default case. But in that case there is a code comment that  
confirms such behavior.


In case it is not intentional, I will write a patch to fix this.
In case it is indeed intentional I think it would be good to add a  
code comment (/* fall through */) before "case USB_ENDPOINT_XFER_ISOC:"


It would be great to hear any comment about this.

Thank you
--
Gustavo A. R. Silva




--
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: misc: remove unnecessary code

2017-02-20 Thread Gustavo A. R. Silva
'val' is an unsigned variable, and less-than-zero comparison of an unsigned
variable is never true.

Addresses-Coverity-ID: 1230257
Signed-off-by: Gustavo A. R. Silva 
---
 drivers/usb/misc/lvstest.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c
index c7c2104..6f37610 100644
--- a/drivers/usb/misc/lvstest.c
+++ b/drivers/usb/misc/lvstest.c
@@ -193,7 +193,7 @@ static ssize_t u2_timeout_store(struct device *dev,
return ret;
}
 
-   if (val < 0 || val > 127)
+   if (val > 127)
return -EINVAL;
 
ret = lvs_rh_set_port_feature(hdev, lvs->portnum | (val << 8),
-- 
2.5.0

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

2017-02-20 Thread Viet Xuan Luong
I am Viet Xuan Luong. I am an American soldier presently on active  service 
with 4th Squadron battalion here in Afghanistan. I served with the third 
Infantry Division in Iraq before thousand of my lucky  colleagues were pulled 
out in August Last year, leaving me among the  unlucky ones drafted to 
Afghanistan where I am serving presently. Am  seeking your urgent help, please 
get back to me via email and I will  tell you more about it thank you and God 
bless you.


Respectfully submitted.
vietxuanluong...@gmail.com
Viet Xuan Luong
--
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

2017-02-20 Thread Viet Xuan Luong
I am Viet Xuan Luong. I am an American soldier presently on active  service 
with 4th Squadron battalion here in Afghanistan. I served with the third 
Infantry Division in Iraq before thousand of my lucky  colleagues were pulled 
out in August Last year, leaving me among the  unlucky ones drafted to 
Afghanistan where I am serving presently. Am  seeking your urgent help, please 
get back to me via email and I will  tell you more about it thank you and God 
bless you.


Respectfully submitted.
vietxuanluong...@gmail.com
Viet Xuan Luong
--
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] Fix implicit fallthrough warning

2017-02-20 Thread Jonathan Dieter
GCC 7 now warns when switch statements fall through implicitly, and with
-Werror enabled in configure.ac, that makes these tools unbuildable.

We fix this by notifying the compiler that this particular case statement
is meant to fall through.

Reviewed-by: Peter Senna Tschudin 
Signed-off-by: Jonathan Dieter 
---
 tools/usb/usbip/src/usbip.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c
index d7599d9..73d8eee 100644
--- a/tools/usb/usbip/src/usbip.c
+++ b/tools/usb/usbip/src/usbip.c
@@ -176,6 +176,8 @@ int main(int argc, char *argv[])
break;
case '?':
printf("usbip: invalid option\n");
+   /* Terminate after printing error */
+   /* FALLTHRU */
default:
usbip_usage();
goto out;
-- 
2.9.3

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


[PATCH 1/2] Fix format overflows

2017-02-20 Thread Jonathan Dieter
The usbip userspace tools call sprintf()/snprintf() and don't check for
the return value which can lead the paths to overflow, truncating the
final file in the path.

More urgently, GCC 7 now warns that these aren't checked with
-Wformat-overflow, and with -Werror enabled in configure.ac, that makes
these tools unbuildable.

This patch fixes these problems by replacing sprintf() with snprintf() in
one place and adding checks for the return value of snprintf().

Reviewed-by: Peter Senna Tschudin 
Signed-off-by: Jonathan Dieter 
---
 tools/usb/usbip/libsrc/usbip_common.c  |  8 +++-
 tools/usb/usbip/libsrc/usbip_host_common.c | 25 -
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/tools/usb/usbip/libsrc/usbip_common.c 
b/tools/usb/usbip/libsrc/usbip_common.c
index ac73710..fc875ee 100644
--- a/tools/usb/usbip/libsrc/usbip_common.c
+++ b/tools/usb/usbip/libsrc/usbip_common.c
@@ -215,9 +215,15 @@ int read_usb_interface(struct usbip_usb_device *udev, int 
i,
   struct usbip_usb_interface *uinf)
 {
char busid[SYSFS_BUS_ID_SIZE];
+   int size;
struct udev_device *sif;
 
-   sprintf(busid, "%s:%d.%d", udev->busid, udev->bConfigurationValue, i);
+   size = snprintf(busid, SYSFS_BUS_ID_SIZE, "%s:%d.%d",
+   udev->busid, udev->bConfigurationValue, i);
+   if (size >= SYSFS_BUS_ID_SIZE) {
+   err("busid length %i >= SYSFS_BUS_ID_SIZE", size);
+   return -1;
+   }
 
sif = udev_device_new_from_subsystem_sysname(udev_context, "usb", 
busid);
if (!sif) {
diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c 
b/tools/usb/usbip/libsrc/usbip_host_common.c
index 9d41522..690cd49 100644
--- a/tools/usb/usbip/libsrc/usbip_host_common.c
+++ b/tools/usb/usbip/libsrc/usbip_host_common.c
@@ -40,13 +40,19 @@ struct udev *udev_context;
 static int32_t read_attr_usbip_status(struct usbip_usb_device *udev)
 {
char status_attr_path[SYSFS_PATH_MAX];
+   int size;
int fd;
int length;
char status;
int value = 0;
 
-   snprintf(status_attr_path, SYSFS_PATH_MAX, "%s/usbip_status",
-udev->path);
+   size = snprintf(status_attr_path, SYSFS_PATH_MAX, "%s/usbip_status",
+   udev->path);
+   if (size >= SYSFS_PATH_MAX) {
+   err("usbip_status path length %i >= SYSFS_PATH_MAX", size);
+   return -1;
+   }
+
 
fd = open(status_attr_path, O_RDONLY);
if (fd < 0) {
@@ -218,6 +224,7 @@ int usbip_export_device(struct usbip_exported_device *edev, 
int sockfd)
 {
char attr_name[] = "usbip_sockfd";
char sockfd_attr_path[SYSFS_PATH_MAX];
+   int size;
char sockfd_buff[30];
int ret;
 
@@ -237,10 +244,18 @@ int usbip_export_device(struct usbip_exported_device 
*edev, int sockfd)
}
 
/* only the first interface is true */
-   snprintf(sockfd_attr_path, sizeof(sockfd_attr_path), "%s/%s",
-edev->udev.path, attr_name);
+   size = snprintf(sockfd_attr_path, sizeof(sockfd_attr_path), "%s/%s",
+   edev->udev.path, attr_name);
+   if (size >= SYSFS_PATH_MAX) {
+   err("exported device path length %i >= SYSFS_PATH_MAX", size);
+   return -1;
+   }
 
-   snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd);
+   size = snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd);
+   if (size >= 30) {
+   err("socket length %i >= 30", size);
+   return -1;
+   }
 
ret = write_sysfs_attribute(sockfd_attr_path, sockfd_buff,
strlen(sockfd_buff));
-- 
2.9.3

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


Re: Subject: [PATCH v3] USB:Core: BugFix: Proper handling of Race Condition when two USB class drivers try to call init_usb_class simultaneously

2017-02-20 Thread Alan Stern
On Mon, 20 Feb 2017, Ajay Kaher wrote:

> Alan, as per my understanding I have shifted the lock from
> release_usb_class() to destroy_usb_class() in patch v3. 
> If it is not right, please explain in detail which race condition
> I have missed and also share your suggestions.
> 
> thanks,
> ajay kaher
> 
> Signed-off-by: Ajay Kaher
> 
> ---
> 
>  drivers/usb/core/file.c |6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
> index 822ced9..a12d184 100644
> --- a/drivers/usb/core/file.c
> +++ b/drivers/usb/core/file.c
> @@ -27,6 +27,7 @@
>  #define MAX_USB_MINORS 256
>  static const struct file_operations *usb_minors[MAX_USB_MINORS];
>  static DECLARE_RWSEM(minor_rwsem);
> +static DEFINE_MUTEX(init_usb_class_mutex);
> 
>  static int usb_open(struct inode *inode, struct file *file)
>  {
> @@ -109,8 +110,10 @@ static void release_usb_class(struct kref *kref)
> 
>  static void destroy_usb_class(void)
>  {
> +   mutex_lock(_usb_class_mutex);
> if (usb_class)
> kref_put(_class->kref, release_usb_class);
> +   mutex_unlock(_usb_class_mutex);
>  }
> 
>  int usb_major_init(void)
> @@ -171,7 +174,10 @@ int usb_register_dev(struct usb_interface *intf,
> if (intf->minor >= 0)
> return -EADDRINUSE;
> 
> +   mutex_lock(_usb_class_mutex);
> retval = init_usb_class();
> +   mutex_unlock(_usb_class_mutex);
> +
> if (retval)
> return retval;

Have you considered what would happen if destroy_usb_class() ran, but 
some other CPU was still holding a reference to usb_class?  And what if 
the last reference gets dropped later on, while init_usb_class() is 
running?

Maybe that's not possible here, but it is possible in general for 
refcounted objects.  So yes, this code is probably okay, but it isn't 
good form.

Alan Stern

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


[Kernel] usbhid 3-2:1.1: couldn't find an input interrupt endpoint

2017-02-20 Thread Cristian
Hello,

dmesg:
[2.465370] usbhid 3-2:1.1: couldn't find an input interrupt endpoint

Thanks,
-- 
Cristian
[0.00] microcode: microcode updated early to revision 0x29, date = 
2013-06-12
[0.00] Linux version 4.10.0-041000-generic (kernel@gloin) (gcc version 
6.2.0 20161005 (Ubuntu 6.2.0-5ubuntu12) ) #201702191831 SMP Sun Feb 19 23:33:19 
UTC 2017
[0.00] Command line: BOOT_IMAGE=/vmlinuz-4.10.0-041000-generic 
root=UUID=4f4435ca-b877-47a5-9065-3dd624c0514e ro rootflags=subvol=@ quiet 
splash vt.handoff=7
[0.00] KERNEL supported cpus:
[0.00]   Intel GenuineIntel
[0.00]   AMD AuthenticAMD
[0.00]   Centaur CentaurHauls
[0.00] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point 
registers'
[0.00] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
[0.00] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
[0.00] x86/fpu: xstate_offset[2]:  576, xstate_sizes[2]:  256
[0.00] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, 
using 'standard' format.
[0.00] e820: BIOS-provided physical RAM map:
[0.00] BIOS-e820: [mem 0x-0x0009d7ff] usable
[0.00] BIOS-e820: [mem 0x0009d800-0x0009] reserved
[0.00] BIOS-e820: [mem 0x000e-0x000f] reserved
[0.00] BIOS-e820: [mem 0x0010-0x1fff] usable
[0.00] BIOS-e820: [mem 0x2000-0x201f] reserved
[0.00] BIOS-e820: [mem 0x2020-0x3fff] usable
[0.00] BIOS-e820: [mem 0x4000-0x401f] reserved
[0.00] BIOS-e820: [mem 0x4020-0xc42a9fff] usable
[0.00] BIOS-e820: [mem 0xc42aa000-0xc44abfff] reserved
[0.00] BIOS-e820: [mem 0xc44ac000-0xd33eefff] usable
[0.00] BIOS-e820: [mem 0xd33ef000-0xdaeeefff] reserved
[0.00] BIOS-e820: [mem 0xdaeef000-0xdaf9efff] ACPI NVS
[0.00] BIOS-e820: [mem 0xdaf9f000-0xdaffefff] ACPI data
[0.00] BIOS-e820: [mem 0xdafff000-0xdaff] usable
[0.00] BIOS-e820: [mem 0xdb00-0xdf9f] reserved
[0.00] BIOS-e820: [mem 0xf800-0xfbff] reserved
[0.00] BIOS-e820: [mem 0xfec0-0xfec00fff] reserved
[0.00] BIOS-e820: [mem 0xfed08000-0xfed08fff] reserved
[0.00] BIOS-e820: [mem 0xfed1-0xfed19fff] reserved
[0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] reserved
[0.00] BIOS-e820: [mem 0xfee0-0xfee00fff] reserved
[0.00] BIOS-e820: [mem 0xffd0-0x] reserved
[0.00] BIOS-e820: [mem 0x0001-0x00031f5f] usable
[0.00] BIOS-e820: [mem 0x00031f60-0x00031f7f] reserved
[0.00] NX (Execute Disable) protection: active
[0.00] SMBIOS 2.7 present.
[0.00] DMI: SAMSUNG ELECTRONICS CO., LTD. 
530U3C/530U4C/SAMSUNG_NP1234567890, BIOS P14AAJ 04/15/2013
[0.00] e820: update [mem 0x-0x0fff] usable ==> reserved
[0.00] e820: remove [mem 0x000a-0x000f] usable
[0.00] e820: last_pfn = 0x31f600 max_arch_pfn = 0x4
[0.00] MTRR default type: uncachable
[0.00] MTRR fixed ranges enabled:
[0.00]   0-9 write-back
[0.00]   A-B uncachable
[0.00]   C-F write-protect
[0.00] MTRR variable ranges enabled:
[0.00]   0 base 0FFC0 mask FFFC0 write-protect
[0.00]   1 base 0 mask F8000 write-back
[0.00]   2 base 08000 mask FC000 write-back
[0.00]   3 base 0C000 mask FE000 write-back
[0.00]   4 base 0DC00 mask FFC00 uncachable
[0.00]   5 base 0DB00 mask FFF00 uncachable
[0.00]   6 base 1 mask F write-back
[0.00]   7 base 2 mask F write-back
[0.00]   8 base 3 mask FE000 write-back
[0.00]   9 base 31F80 mask FFF80 uncachable
[0.00] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WC  UC- WT  
[0.00] e820: last_pfn = 0xdb000 max_arch_pfn = 0x4
[0.00] found SMP MP-table at [mem 0x000f0100-0x000f010f] mapped at 
[9448000f0100]
[0.00] Scanning 1 areas for low memory corruption
[0.00] Base memory trampoline at [944800097000] 97000 size 24576
[0.00] reserving inaccessible SNB gfx pages
[0.00] BRK [0x263a27000, 0x263a27fff] PGTABLE
[0.00] BRK [0x263a28000, 0x263a28fff] PGTABLE
[0.00] BRK [0x263a29000, 0x263a29fff] PGTABLE
[0.00] BRK [0x263a2a000, 0x263a2afff] PGTABLE
[0.00] BRK [0x263a2b000, 0x263a2bfff] PGTABLE
[

Re: [PATCH] lvs: fix race condition in disconnect handling

2017-02-20 Thread Sergei Shtylyov

On 02/20/2017 05:38 PM, Oliver Neukum wrote:


There is a small window during which the an URB may


   So the or an?


remain active after disconnect has returned. If in that case
already freed memory may be accessed and executed.

The fix is to poison the URB befotre the work is flushed.

Signed-off-by: Oliver Neukum 
---
 drivers/usb/misc/lvstest.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c
index 7717651..e5d2500 100644
--- a/drivers/usb/misc/lvstest.c
+++ b/drivers/usb/misc/lvstest.c
@@ -429,6 +429,8 @@ static void lvs_rh_disconnect(struct usb_interface *intf)
struct lvs_rh *lvs = usb_get_intfdata(intf);

sysfs_remove_group(>dev.kobj, _attr_group);
+   usb_poison_urb(lvs->urb); /* used in scheduled work */
+   (lvs->urb);


   What?

[...]

MBR, Sergei

--
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: ohci-at91: revert patch 2e2aa1bc7eff90ec on cpu without SFR register

2017-02-20 Thread Jelle Martijn Kok

usb: ohci-at91: Do not drop unhandled USB suspend control requests

In patch 2e2aa1bc7eff90ecm, USB suspend and wakeup control requests are
passed to SFR_OHCIICR register. If a processor does not have such a
register, this hub control request will be dropped.

If no such a SFR register is available, all USB suspend control requests
will now be processed using ohci_hub_control()
(like before patch 2e2aa1bc7eff90ecm.)

Tested on an Atmel AT91SAM9G20 with an on-board TI TUSB2046B hub chip
If the last USB device is unplugged from the USB hub, the hub goes into
sleep and will not wakeup when an USB devices is inserted.

Fixes: 2e2aa1bc7eff90ec ("usb: ohci-at91: Forcibly suspend ports while 
USB suspend")

Signed-off-by: Jelle Martijn Kok 
Tested-by: Wenyou Yang 
Cc: Wenyou Yang 
Cc: Alexandre Belloni 
Cc: Nicolas Ferre 
Cc: Alan Stern 


On 16-02-17 17:35, Greg KH wrote:

On Thu, Feb 16, 2017 at 04:19:44PM +0100, Jelle Martijn Kok wrote:

External USB hubs seems to go into suspend, but never wakeup again.
Tested on an AT91SAM9G20

Signed-off-by: Jelle Martijn Kok 
---
  drivers/usb/host/ohci-at91.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

Can you put a "Fixes:" line in here and cc: the original authors of the
patch you are trying to revert?

Also, this isn't a "full" revert at all, are you sure you just don't
have a hub that can't handle suspend and you should disable it from
userspace instead?

thanks,

greg k-h


--

You/Com Audiocommunicatie b.v.
Motorenweg 5k
2623CR Delft
The Netherlands
tel. : (+31)15 262 59 55
fax. : (+31)15 257 15 95
mail : jm...@youcom.nl
http : https://www.youcom.nl/


--
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 RESEND v8] usb: xhci: plat: Enable async suspend/resume

2017-02-20 Thread Robert Foss
From: Andrew Bresticker 

USB host controllers can take a significant amount of time to suspend
and resume, adding several hundred miliseconds to the kernel resume
time. Since the XHCI controller has no outside dependencies (other than
clocks, which are suspended late/resumed early), allow it to suspend and
resume asynchronously.

Signed-off-by: Andrew Bresticker 
Tested-by: Andrew Bresticker 
Tested-by: Robert Foss 
Signed-off-by: Robert Foss 
Reviewed-by: Baolin Wang 
---

Changes since v8:
 - Rebased on upstream/master
 - Added r-b of Baolin Wang


 drivers/usb/host/xhci-plat.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index e5834dd9bcde..8ef34fe4d5c0 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -255,6 +255,8 @@ static int xhci_plat_probe(struct platform_device *pdev)
if (ret)
goto dealloc_usb2_hcd;
 
+   device_enable_async_suspend(>dev);
+
return 0;
 
 
-- 
2.11.0.453.g787f75f05

--
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/2] usb: host: plat: Enable xhci plat runtime PM

2017-02-20 Thread Mathias Nyman

On 20.02.2017 04:47, Baolin Wang wrote:

Hi Mathias,

On 6 February 2017 at 13:26, Baolin Wang  wrote:

Hi Mathias,

On 31 January 2017 at 21:14, Mathias Nyman
 wrote:

On 16.01.2017 12:56, Baolin Wang wrote:


Hi Mathias,



Hi

Sorry about the long review delay
CC Alan in case my pm assumptions need to be corrected




On 13 December 2016 at 15:49, Baolin Wang  wrote:


Enable the xhci plat runtime PM for parent device to suspend/resume xhci.
Also call pm_runtime_get_noresume() in probe() function in case the
parent
device doesn't call suspend/resume callback by runtime PM now.

Signed-off-by: Baolin Wang 
---
Changes since v4:
   - No updates.

Changes since v3:
   - Fix kbuild error.

Changes since v2:
   - Add pm_runtime_get_noresume() in probe() function.
   - Add pm_runtime_set_suspended()/pm_runtime_put_noidle() in remove()
function.

Changes since v1:
   - No updates.
---



Do you have any comments about this patch? Thanks.


   drivers/usb/host/xhci-plat.c |   41
-
   1 file changed, 36 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index ed56bf9..5805c6a 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -246,6 +246,10 @@ static int xhci_plat_probe(struct platform_device
*pdev)
  if (ret)
  goto dealloc_usb2_hcd;

+   pm_runtime_get_noresume(>dev);
+   pm_runtime_set_active(>dev);
+   pm_runtime_enable(>dev);
+
  return 0;




To me this looks like we are not really enabling runtime pm for xhci, we
increment the
usage count in probe, and keep it until remove is called.

This would normally prevent parent dwc3 from runtime suspending, but I see
that in patch 2/2 adds
pm_suspend_ignore_children(dev, true) to dwc3, and, that dwc3 actually
controls xhci runtime
pm by calling pm_runtime_get/put for xhci in its own dwc3
runtime_suspend/resume callbacks.

Looks a bit upside down to me, what's the reason for this?

what prevents calling pm_runtime_put_* before leaving probe in xhci and let
pm code handle
the runtime suspend and parent/child relationships?


When dwc3 controller is working on host mode, which will create and
add the USB hcd for host side. Then if we want to suspend dwc3
controller as host mode, the USB device (bus) of host side will
runtime suspend automatically if there are no slave attached (by
usb_runtime_suspend()--->usb_suspend_both()--->usb_suspend_interface()--->usb_suspend_device()--->generic_suspend()--->hcd_bus_suspend()--->xhci_bus_suspend()),
but we should not suspend xHCI device (issuing xhci_suspend()) now,
since some other  controllers did not implement the runtime PM to
control xHCI device's runtime state, which will cause other
controllers can not resume xHCI device (issuing xhci_resume()) if the
xHCI device suspend automatically by its child device. Thus we should
get the runtime count for xHCI device in xhci_plat_probe() in case
xHCI device will also suspend automatically by its child device.
According to that, for xHCI device's parent: dwc3 device, we should
put the xHCI device's runtime count to suspend xHCI device manually.



Any more comments?



I think I at least partially understand your point. You don't want to enable
runtime suspend for all xhci platform devices by default, but only for the ones
that are part of dwc3.

The implementation you suggest is that xhci platform driver always increase the 
xhci platform
device usage counter during probe with pm_runtime_get_noresume(), and never 
decrement it,
preventing xhci platform devices from runtime suspending by themselves.

You then control xhci runtime suspend from dwc3 driver runtime suspend, allowing
xhci platfrom controller to runtime suspend only when dwc3 runtime suspends by 
decrementing xhci
platform device usage in dwc3 runtime suspend callback.
As xhci is a child of dwc3 in this case,  dwc3 would never runtime suspend as 
long as xhci is running, so
dwc3 needed to be detached from xhci by setting dwc3 to ignore its children to 
get it to work.

I don't yet understand why we can't just keep runtime pm disabled as a default 
for xhci platform devices.
It could be enabled by whatever creates the platform device by setting some 
device property
(or equivalent), which would be checked in xhci_plat_probe() before enabling 
runtime pm. It
could then optionally be set in sysfs via power/control entry.

We would keep the usage counting intact, and only enable xhci platform device 
runtime pm
if the platform supports it, and dwc3 and xhci would keep their parent-child 
relationship
intact and make sure dwc3 can't runtime suspend before xhci.

To the concerns about xhci runtime suspending too early, the codepath you 
describet only applies
for roothub devices, which sohuld be called only after other devices have 
suspended.

To make sure 

[PATCH 04/15] usb: dwc2: gadget: Fix dwc2_restore_device_registers

2017-02-20 Thread Vardan Mikayelyan
Add parameter remote_wakeup to dwc2_restore_device_registers()
to be able to restore device registers according to programming
guide for dwc-otg. It says that in case of rem_wakeup DCTL must not
be restored here.

Remove setting of DCTL_PWRONPRGDONE from this function, because it
will be done in function responsible for exiting from hibernation.

Signed-off-by: Vardan Mikayelyan 
Signed-off-by: John Youn 
---
 drivers/usb/dwc2/core.c   |  2 +-
 drivers/usb/dwc2/core.h   |  5 +++--
 drivers/usb/dwc2/gadget.c | 16 +++-
 3 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 7addf69..185d24c 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -162,7 +162,7 @@ int dwc2_exit_partial_power_down(struct dwc2_hsotg *hsotg, 
bool restore)
return ret;
}
} else {
-   ret = dwc2_restore_device_registers(hsotg);
+   ret = dwc2_restore_device_registers(hsotg, 0);
if (ret) {
dev_err(hsotg->dev, "%s: failed to restore 
device registers\n",
__func__);
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 4cb95b3..60ad2e6 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -1183,7 +1183,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg 
*dwc2,
 int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode);
 #define dwc2_is_device_connected(hsotg) (hsotg->connected)
 int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg);
-int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg);
+int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg, int remote_wakeup);
 int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg);
 int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg);
 int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg);
@@ -1206,7 +1206,8 @@ static inline int dwc2_hsotg_set_test_mode(struct 
dwc2_hsotg *hsotg,
 #define dwc2_is_device_connected(hsotg) (0)
 static inline int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
 { return 0; }
-static inline int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg)
+static inline int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg,
+   int remote_wakeup)
 { return 0; }
 static inline int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg)
 { return 0; }
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 3e969a5..3b082ed 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -4822,11 +4822,13 @@ int dwc2_backup_device_registers(struct dwc2_hsotg 
*hsotg)
  * if controller power were disabled.
  *
  * @hsotg: Programming view of the DWC_otg controller
+ * @remote_wakeup: Indicates whether resume is initiated by Device or Host.
+ *
+ * Return: 0 if successful, negative error code otherwise
  */
-int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg)
+int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg, int remote_wakeup)
 {
struct dwc2_dregs_backup *dr;
-   u32 dctl;
int i;
 
dev_dbg(hsotg->dev, "%s\n", __func__);
@@ -4840,8 +4842,9 @@ int dwc2_restore_device_registers(struct dwc2_hsotg 
*hsotg)
}
dr->valid = false;
 
-   dwc2_writel(dr->dcfg, hsotg->regs + DCFG);
-   dwc2_writel(dr->dctl, hsotg->regs + DCTL);
+   if (!remote_wakeup)
+   dwc2_writel(dr->dctl, hsotg->regs + DCTL);
+
dwc2_writel(dr->daintmsk, hsotg->regs + DAINTMSK);
dwc2_writel(dr->diepmsk, hsotg->regs + DIEPMSK);
dwc2_writel(dr->doepmsk, hsotg->regs + DOEPMSK);
@@ -4859,10 +4862,5 @@ int dwc2_restore_device_registers(struct dwc2_hsotg 
*hsotg)
dwc2_writel(dr->doepdma[i], hsotg->regs + DOEPDMA(i));
}
 
-   /* Set the Power-On Programming done bit */
-   dctl = dwc2_readl(hsotg->regs + DCTL);
-   dctl |= DCTL_PWRONPRGDONE;
-   dwc2_writel(dctl, hsotg->regs + DCTL);
-
return 0;
 }
-- 
1.9.1

--
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 15/15] usb: dwc2: Replace msleep with mdelay in dwc2_clear_force_mode()

2017-02-20 Thread Vardan Mikayelyan
dwc2_clear_force_mode() can be called in hibernation exit flow which
can occur in interrupt context.

Signed-off-by: Vardan Mikayelyan 
---
 drivers/usb/dwc2/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 2c90d8e..c7c76e8 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -634,7 +634,7 @@ void dwc2_clear_force_mode(struct dwc2_hsotg *hsotg)
dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
 
if (dwc2_iddig_filter_enabled(hsotg))
-   msleep(100);
+   mdelay(100);
 }
 
 /*
-- 
1.9.1

--
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 13/15] usb: dwc2: Change hub-control to allow hibernation

2017-02-20 Thread Vardan Mikayelyan
Affected cases:
ClearPortFeature's
 USB_PORT_FEAT_SUSPEND

SetPortFeature's
 USB_PORT_FEAT_SUSPEND
 USB_PORT_FEAT_RESET

Signed-off-by: Vardan Mikayelyan 
Signed-off-by: John Youn 
---
 drivers/usb/dwc2/hcd.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 0b889a0..636dffc 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3471,8 +3471,12 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg 
*hsotg, u16 typereq,
dev_dbg(hsotg->dev,
"ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
 
-   if (hsotg->bus_suspended)
-   dwc2_port_resume(hsotg);
+   if (hsotg->bus_suspended) {
+   if (hsotg->hibernated)
+   dwc2_exit_hibernation(hsotg, 0, 0, 1);
+   else
+   dwc2_port_resume(hsotg);
+   }
break;
 
case USB_PORT_FEAT_POWER:
@@ -3680,7 +3684,10 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg 
*hsotg, u16 typereq,
"SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
if (windex != hsotg->otg_port)
goto error;
-   dwc2_port_suspend(hsotg, windex);
+   if (hsotg->params.power_down == 2)
+   dwc2_enter_hibernation(hsotg, 1);
+   else
+   dwc2_port_suspend(hsotg, windex);
break;
 
case USB_PORT_FEAT_POWER:
@@ -3692,6 +3699,9 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, 
u16 typereq,
break;
 
case USB_PORT_FEAT_RESET:
+   if (hsotg->params.power_down == 2 &&
+   hsotg->hibernated)
+   dwc2_exit_hibernation(hsotg, 0, 1, 1);
hprt0 = dwc2_read_hprt0(hsotg);
dev_dbg(hsotg->dev,
"SetPortFeature - USB_PORT_FEAT_RESET\n");
-- 
1.9.1

--
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 12/15] usb: dwc2: Add dwc2_handle_gpwrdn_intr() handler

2017-02-20 Thread Vardan Mikayelyan
The GPWRDN interrupts are those that occur in both Host and
Device mode while core is in hibernated state.

Export dwc2_core_init to be able to use it in GPWRDN_IDSTS
interrupt handler.

Here we have duplicated init functions in host and gadget sides
so I have left things as it was(used corresponing functions for
host and gadget), maybe in the future we'll resolve this problem
and will use dwc2_core_init for both sides.

Signed-off-by: Vardan Mikayelyan 
Signed-off-by: John Youn 
---
 drivers/usb/dwc2/core.h  |   3 ++
 drivers/usb/dwc2/core_intr.c | 110 +++
 drivers/usb/dwc2/hcd.c   |   2 +-
 3 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index a3561e1..263ad53 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -1245,6 +1245,7 @@ static inline int dwc2_hsotg_tx_fifo_average_depth(struct 
dwc2_hsotg *hsotg)
 void dwc2_hcd_connect(struct dwc2_hsotg *hsotg);
 void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force);
 void dwc2_hcd_start(struct dwc2_hsotg *hsotg);
+int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup);
 int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg);
 int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg);
 int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg);
@@ -1260,6 +1261,8 @@ static inline void dwc2_hcd_connect(struct dwc2_hsotg 
*hsotg) {}
 static inline void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg, bool force) {}
 static inline void dwc2_hcd_start(struct dwc2_hsotg *hsotg) {}
 static inline void dwc2_hcd_remove(struct dwc2_hsotg *hsotg) {}
+static inline int dwc2_core_init(struct dwc2_hsotg *hsotg, bool initial_setup)
+{ return 0; }
 static inline int dwc2_hcd_init(struct dwc2_hsotg *hsotg)
 { return 0; }
 static inline int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 45c9b57..86cbbb9 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -520,6 +520,109 @@ static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg)
return 0;
 }
 
+/**
+ * GPWRDN interrupt handler.
+ *
+ * The GPWRDN interrupts are those that occur in both Host and
+ * Device mode while core is in hibernated state.
+ */
+static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
+{
+   u32 gpwrdn;
+   int linestate;
+
+   gpwrdn = dwc2_readl(hsotg->regs + GPWRDN);
+   linestate = (gpwrdn & GPWRDN_LINESTATE_MASK) >> GPWRDN_LINESTATE_SHIFT;
+   dev_dbg(hsotg->dev,
+   "%s: dwc2_handle_gpwrdwn_intr called gpwrdn= %08x\n", __func__,
+   gpwrdn);
+
+   if ((gpwrdn & GPWRDN_DISCONN_DET) &&
+   (gpwrdn & GPWRDN_DISCONN_DET_MSK) && !linestate) {
+   u32 gpwrdn_tmp;
+
+   dev_dbg(hsotg->dev, "%s: GPWRDN_DISCONN_DET\n", __func__);
+   /* clear interrupt */
+   dwc2_writel(GPWRDN_DISCONN_DET, hsotg->regs + GPWRDN);
+
+   /* Switch-on voltage to the core */
+   gpwrdn_tmp = dwc2_readl(hsotg->regs + GPWRDN);
+   gpwrdn_tmp &= ~GPWRDN_PWRDNSWTCH;
+   dwc2_writel(gpwrdn_tmp, hsotg->regs + GPWRDN);
+   udelay(10);
+
+   /* Reset core */
+   gpwrdn_tmp = dwc2_readl(hsotg->regs + GPWRDN);
+   gpwrdn_tmp &= ~GPWRDN_PWRDNRSTN;
+   dwc2_writel(gpwrdn_tmp, hsotg->regs + GPWRDN);
+   udelay(10);
+
+   /* Disable Power Down Clamp */
+   gpwrdn_tmp = dwc2_readl(hsotg->regs + GPWRDN);
+   gpwrdn_tmp &= ~GPWRDN_PWRDNCLMP;
+   dwc2_writel(gpwrdn_tmp, hsotg->regs + GPWRDN);
+   udelay(10);
+
+   /* Deassert reset core */
+   gpwrdn_tmp = dwc2_readl(hsotg->regs + GPWRDN);
+   gpwrdn_tmp |= GPWRDN_PWRDNRSTN;
+   dwc2_writel(gpwrdn_tmp, hsotg->regs + GPWRDN);
+   udelay(10);
+
+   /* Disable PMU interrupt */
+   gpwrdn_tmp = dwc2_readl(hsotg->regs + GPWRDN);
+   gpwrdn_tmp &= ~GPWRDN_PMUINTSEL;
+   dwc2_writel(gpwrdn_tmp, hsotg->regs + GPWRDN);
+
+   /* De-assert Wakeup Logic */
+   gpwrdn_tmp = dwc2_readl(hsotg->regs + GPWRDN);
+   gpwrdn_tmp &= ~GPWRDN_PMUACTV;
+   dwc2_writel(gpwrdn_tmp, hsotg->regs + GPWRDN);
+
+   hsotg->hibernated = 0;
+
+   if (gpwrdn & GPWRDN_IDSTS) {
+   hsotg->op_state = OTG_STATE_B_PERIPHERAL;
+   dwc2_core_init(hsotg, false);
+   dwc2_enable_global_interrupts(hsotg);
+   dwc2_hsotg_core_init_disconnected(hsotg, false);
+   dwc2_hsotg_core_connect(hsotg);
+   } else {
+   hsotg->op_state = 

[PATCH 14/15] usb: dwc2: Enable power down

2017-02-20 Thread Vardan Mikayelyan
From: John Youn 

Enable the power down option based on the core capability.

Signed-off-by: John Youn 
Signed-off-by: Vardan Mikayelyan 
---
 drivers/usb/dwc2/params.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c
index baa76bf..9480b8f 100644
--- a/drivers/usb/dwc2/params.c
+++ b/drivers/usb/dwc2/params.c
@@ -238,6 +238,20 @@ static void dwc2_set_param_tx_fifo_sizes(struct dwc2_hsotg 
*hsotg)
p->g_tx_fifo_size[i] = depth_average;
 }
 
+static void dwc2_set_param_power_down(struct dwc2_hsotg *hsotg)
+{
+   int val;
+
+   if (hsotg->hw_params.hibernation)
+   val = 2;
+   else if (hsotg->hw_params.power_optimized)
+   val = 1;
+   else
+   val = 0;
+
+   hsotg->params.power_down = val;
+}
+
 /**
  * dwc2_set_default_params() - Set all core parameters to their
  * auto-detected default values.
@@ -252,6 +266,7 @@ static void dwc2_set_default_params(struct dwc2_hsotg 
*hsotg)
dwc2_set_param_phy_type(hsotg);
dwc2_set_param_speed(hsotg);
dwc2_set_param_phy_utmi_width(hsotg);
+   dwc2_set_param_power_down(hsotg);
p->phy_ulpi_ddr = false;
p->phy_ulpi_ext_vbus = false;
 
@@ -263,7 +278,6 @@ static void dwc2_set_default_params(struct dwc2_hsotg 
*hsotg)
p->reload_ctl = (hw->snpsid >= DWC2_CORE_REV_2_92a);
p->uframe_sched = true;
p->external_id_pin_ctl = false;
-   p->power_down = false;
p->max_packet_count = hw->max_packet_count;
p->max_transfer_size = hw->max_transfer_size;
p->ahbcfg = GAHBCFG_HBSTLEN_INCR4 << GAHBCFG_HBSTLEN_SHIFT;
-- 
1.9.1

--
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 01/15] usb: dwc2: Rename hibernation to partial_power_down

2017-02-20 Thread Vardan Mikayelyan
No-op change, only rename.

This code was misnamed originally. It was only responsible for partial
power down and not for hibernation.

Rename core_params->hibernation to core_params->power_down,
dwc2_set_param_hibernation() to dwc2_set_param_power_down().

Signed-off-by: Vardan Mikayelyan 
Signed-off-by: John Youn 
---
 drivers/usb/dwc2/core.c  | 14 +++---
 drivers/usb/dwc2/core.h  | 12 ++--
 drivers/usb/dwc2/core_intr.c | 14 +++---
 drivers/usb/dwc2/debugfs.c   |  2 +-
 drivers/usb/dwc2/gadget.c|  6 +++---
 drivers/usb/dwc2/hcd.c   | 26 +-
 drivers/usb/dwc2/params.c|  2 +-
 7 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 42ac47f..e8708fd 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -125,17 +125,17 @@ static int dwc2_restore_global_registers(struct 
dwc2_hsotg *hsotg)
 }
 
 /**
- * dwc2_exit_hibernation() - Exit controller from Partial Power Down.
+ * dwc2_exit_partial_power_down() - Exit controller from Partial Power Down.
  *
  * @hsotg: Programming view of the DWC_otg controller
  * @restore: Controller registers need to be restored
  */
-int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore)
+int dwc2_exit_partial_power_down(struct dwc2_hsotg *hsotg, bool restore)
 {
u32 pcgcctl;
int ret = 0;
 
-   if (!hsotg->params.hibernation)
+   if (!hsotg->params.power_down)
return -ENOTSUPP;
 
pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
@@ -179,16 +179,16 @@ int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool 
restore)
 }
 
 /**
- * dwc2_enter_hibernation() - Put controller in Partial Power Down.
+ * dwc2_enter_partial_power_down() - Put controller in Partial Power Down.
  *
  * @hsotg: Programming view of the DWC_otg controller
  */
-int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg)
+int dwc2_enter_partial_power_down(struct dwc2_hsotg *hsotg)
 {
u32 pcgcctl;
int ret = 0;
 
-   if (!hsotg->params.hibernation)
+   if (!hsotg->params.power_down)
return -ENOTSUPP;
 
/* Backup all registers */
@@ -217,7 +217,7 @@ int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg)
 
/*
 * Clear any pending interrupts since dwc2 will not be able to
-* clear them after entering hibernation.
+* clear them after entering partial_power_down.
 */
dwc2_writel(0x, hsotg->regs + GINTSTS);
 
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 67ca757..61c5e56 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -417,9 +417,9 @@ enum dwc2_ep0_state {
  *  case.
  *  0 - No (default)
  *  1 - Yes
- * @hibernation:   Specifies whether the controller support hibernation.
- * If hibernation is enabled, the controller will enter
- * hibernation in both peripheral and host mode when
+ * @power_down: Specifies whether the controller support power_down.
+ * If power_down is enabled, the controller will enter
+ * power_down in both peripheral and host mode when
  * needed.
  * 0 - No (default)
  * 1 - Yes
@@ -480,7 +480,7 @@ struct dwc2_core_params {
bool reload_ctl;
bool uframe_sched;
bool external_id_pin_ctl;
-   bool hibernation;
+   bool power_down;
bool activate_stm_fs_transceiver;
u16 max_packet_count;
u32 max_transfer_size;
@@ -1095,8 +1095,8 @@ static inline bool dwc2_is_hs_iot(struct dwc2_hsotg 
*hsotg)
  * and the DWC_otg controller
  */
 int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait);
-int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg);
-int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore);
+int dwc2_enter_partial_power_down(struct dwc2_hsotg *hsotg);
+int dwc2_exit_partial_power_down(struct dwc2_hsotg *hsotg, bool restore);
 
 void dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host);
 void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg);
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index b8bcb00..0fb8cf6 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -320,10 +320,10 @@ static void dwc2_handle_session_req_intr(struct 
dwc2_hsotg *hsotg)
 
if (dwc2_is_device_mode(hsotg)) {
if (hsotg->lx_state == DWC2_L2) {
-   ret = dwc2_exit_hibernation(hsotg, true);
+   ret = dwc2_exit_partial_power_down(hsotg, true);
if (ret && (ret != -ENOTSUPP))
dev_err(hsotg->dev,
-   "exit hibernation failed\n");
+   

[PATCH 02/15] usb: dwc2: Add hibernation field into dwc2_hw_params

2017-02-20 Thread Vardan Mikayelyan
Add parameter and it's initialization, needed for hibernation.

Reimplement dwc2_set_param_power_down() to support hibernation too.
Now 'power_down' parameter can be initialized with 0, 1 or 2.
0 - No
1 - Partial power down
2 - Hibernation

Signed-off-by: Vardan Mikayelyan 
Signed-off-by: John Youn 
---
 drivers/usb/dwc2/core.c   |  2 +-
 drivers/usb/dwc2/core.h   | 12 ++--
 drivers/usb/dwc2/hcd.c|  4 ++--
 drivers/usb/dwc2/params.c | 34 ++
 4 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index e8708fd..fe976eb 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -135,7 +135,7 @@ int dwc2_exit_partial_power_down(struct dwc2_hsotg *hsotg, 
bool restore)
u32 pcgcctl;
int ret = 0;
 
-   if (!hsotg->params.power_down)
+   if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL)
return -ENOTSUPP;
 
pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 61c5e56..526d870 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -422,7 +422,8 @@ enum dwc2_ep0_state {
  * power_down in both peripheral and host mode when
  * needed.
  * 0 - No (default)
- * 1 - Yes
+ * 1 - Partial power down
+ * 2 - Hibernation
  * @activate_stm_fs_transceiver: Activate internal transceiver using GGPIO
  * register.
  * 0 - Deactivate the transceiver (default)
@@ -480,7 +481,12 @@ struct dwc2_core_params {
bool reload_ctl;
bool uframe_sched;
bool external_id_pin_ctl;
-   bool power_down;
+
+   int power_down;
+#define DWC2_POWER_DOWN_PARAM_NONE 0
+#define DWC2_POWER_DOWN_PARAM_PARTIAL  1
+#define DWC2_POWER_DOWN_PARAM_HIBERNATION  2
+
bool activate_stm_fs_transceiver;
u16 max_packet_count;
u32 max_transfer_size;
@@ -554,6 +560,7 @@ struct dwc2_core_params {
  *   2 - FS pins shared with UTMI+ pins
  *   3 - FS pins shared with ULPI pins
  * @total_fifo_size:Total internal RAM for FIFOs (bytes)
+ * @hibernationIs hibernation enabled?
  * @utmi_phy_data_width UTMI+ PHY data width
  *   0 - 8 bits
  *   1 - 16 bits
@@ -584,6 +591,7 @@ struct dwc2_hw_params {
unsigned num_dev_perio_in_ep:4;
unsigned total_fifo_size:16;
unsigned power_optimized:1;
+   unsigned hibernation:1;
unsigned utmi_phy_data_width:2;
u32 snpsid;
u32 dev_ep_dirs;
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 604356c..53d580f 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4396,7 +4396,7 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
if (hsotg->op_state == OTG_STATE_B_PERIPHERAL)
goto unlock;
 
-   if (!hsotg->params.power_down)
+   if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL)
goto skip_power_saving;
 
/*
@@ -4448,7 +4448,7 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
if (hsotg->lx_state != DWC2_L2)
goto unlock;
 
-   if (!hsotg->params.power_down) {
+   if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL) {
hsotg->lx_state = DWC2_L0;
goto unlock;
}
diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c
index 38336e5..baa76bf 100644
--- a/drivers/usb/dwc2/params.c
+++ b/drivers/usb/dwc2/params.c
@@ -446,6 +446,38 @@ static void dwc2_check_param_phy_utmi_width(struct 
dwc2_hsotg *hsotg)
dwc2_set_param_phy_utmi_width(hsotg);
 }
 
+static void dwc2_check_param_power_down(struct dwc2_hsotg *hsotg)
+{
+   int param = hsotg->params.power_down;
+
+   switch (param) {
+   case DWC2_POWER_DOWN_PARAM_NONE:
+   break;
+   case DWC2_POWER_DOWN_PARAM_PARTIAL:
+   if (hsotg->hw_params.power_optimized)
+   break;
+   dev_dbg(hsotg->dev,
+   "Partial power down isn't supported by HW\n");
+   param = DWC2_POWER_DOWN_PARAM_NONE;
+   break;
+   case DWC2_POWER_DOWN_PARAM_HIBERNATION:
+   if (hsotg->hw_params.hibernation)
+   break;
+   dev_dbg(hsotg->dev,
+   "Hibernation isn't supported by HW\n");
+   param = DWC2_POWER_DOWN_PARAM_NONE;
+   break;
+   default:
+   dev_err(hsotg->dev,
+   "%s: Invalid parameter power_down=%d\n",
+   __func__, param);
+   param = DWC2_POWER_DOWN_PARAM_NONE;
+   

[PATCH 10/15] usb: dwc2: Add dwc2_enter_hibernation(), dwc2_exit_hibernation()

2017-02-20 Thread Vardan Mikayelyan
These are wrapper functions which are calling device or host
enter/exit hibernation functions.

Signed-off-by: Vardan Mikayelyan 
Signed-off-by: John Youn 
---
 drivers/usb/dwc2/core.c | 38 ++
 drivers/usb/dwc2/core.h |  3 +++
 2 files changed, 41 insertions(+)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index a37dfc2..2c90d8e 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -446,6 +446,44 @@ static bool dwc2_iddig_filter_enabled(struct dwc2_hsotg 
*hsotg)
 }
 
 /*
+ * dwc2_enter_hibernation() - Common function to enter hibernation.
+ *
+ * @hsotg: Programming view of the DWC_otg controller
+ * @is_host: True if core is in host mode.
+ *
+ * Return: 0 if successful, negative error code otherwise
+ */
+int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg, int is_host)
+{
+   if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_HIBERNATION)
+   return -ENOTSUPP;
+
+   if (is_host)
+   return dwc2_host_enter_hibernation(hsotg);
+   else
+   return dwc2_gadget_enter_hibernation(hsotg);
+}
+
+/*
+ * dwc2_exit_hibernation() - Common function to exit from hibernation.
+ *
+ * @hsotg: Programming view of the DWC_otg controller
+ * @rem_wakeup: Remote-wakeup, enabled in case of remote-wakeup.
+ * @reset: Enabled in case of restore with reset.
+ * @is_host: True if core is in host mode.
+ *
+ * Return: 0 if successful, negative error code otherwise
+ */
+int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,
+ int reset, int is_host)
+{
+   if (is_host)
+   return dwc2_host_exit_hibernation(hsotg, rem_wakeup, reset);
+   else
+   return dwc2_gadget_exit_hibernation(hsotg, rem_wakeup, reset);
+}
+
+/*
  * Do core a soft reset of the core.  Be careful with this because it
  * resets all the internal state machines of the core.
  */
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 9d17f4a..a3561e1 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -1112,6 +1112,9 @@ static inline bool dwc2_is_hs_iot(struct dwc2_hsotg 
*hsotg)
 int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait);
 int dwc2_enter_partial_power_down(struct dwc2_hsotg *hsotg);
 int dwc2_exit_partial_power_down(struct dwc2_hsotg *hsotg, bool restore);
+int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg, int is_host);
+int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, int rem_wakeup,
+ int reset, int is_host);
 
 void dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host);
 void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg);
-- 
1.9.1

--
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 11/15] usb: dwc2: Allow entering hibernation from USB_SUSPEND interrupt

2017-02-20 Thread Vardan Mikayelyan
Do changes to allow entering hibernated state from USB_SUSPEND
interrupt. All code is added under if conditions and mustn't impact
existing functionality.

Signed-off-by: Vardan Mikayelyan 
Signed-off-by: John Youn 
---
 drivers/usb/dwc2/core_intr.c | 52 +++-
 1 file changed, 32 insertions(+), 20 deletions(-)

diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 0fb8cf6..45c9b57 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -427,32 +427,44 @@ static void dwc2_handle_usb_suspend_intr(struct 
dwc2_hsotg *hsotg)
 * state is active
 */
dsts = dwc2_readl(hsotg->regs + DSTS);
-   dev_dbg(hsotg->dev, "DSTS=0x%0x\n", dsts);
+   dev_dbg(hsotg->dev, "%s: DSTS=0x%0x\n", __func__, dsts);
dev_dbg(hsotg->dev,
-   "DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n",
+   "DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d 
HWCFG4.Hibernation=%d\n",
!!(dsts & DSTS_SUSPSTS),
-   hsotg->hw_params.power_optimized);
-   if ((dsts & DSTS_SUSPSTS) && hsotg->hw_params.power_optimized) {
-   /* Ignore suspend request before enumeration */
-   if (!dwc2_is_device_connected(hsotg)) {
-   dev_dbg(hsotg->dev,
-   "ignore suspend request before 
enumeration\n");
-   return;
+   hsotg->hw_params.power_optimized,
+   hsotg->hw_params.hibernation);
+
+   /* Ignore suspend request before enumeration */
+   if (!dwc2_is_device_connected(hsotg)) {
+   dev_dbg(hsotg->dev,
+   "ignore suspend request before enumeration\n");
+   return;
+   }
+   if (dsts & DSTS_SUSPSTS) {
+   if (hsotg->hw_params.power_optimized) {
+   ret = dwc2_enter_partial_power_down(hsotg);
+   if (ret) {
+   if (ret != -ENOTSUPP)
+   dev_err(hsotg->dev,
+   "%s: enter 
partial_power_down failed\n",
+   __func__);
+   goto skip_power_saving;
+   }
+
+   udelay(100);
+
+   /* Ask phy to be suspended */
+   if (!IS_ERR_OR_NULL(hsotg->uphy))
+   usb_phy_set_suspend(hsotg->uphy, true);
}
 
-   ret = dwc2_enter_partial_power_down(hsotg);
-   if (ret) {
-   if (ret != -ENOTSUPP)
+   if (hsotg->hw_params.hibernation) {
+   ret = dwc2_enter_hibernation(hsotg, 0);
+   if (ret && ret != -ENOTSUPP)
dev_err(hsotg->dev,
-   "enter power_down failed\n");
-   goto skip_power_saving;
+   "%s: enter hibernation 
failed\n",
+   __func__);
}
-
-   udelay(100);
-
-   /* Ask phy to be suspended */
-   if (!IS_ERR_OR_NULL(hsotg->uphy))
-   usb_phy_set_suspend(hsotg->uphy, true);
 skip_power_saving:
/*
 * Change to L2 (suspend) state before releasing
-- 
1.9.1

--
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 00/15] usb: dwc2: Add hibernation support.

2017-02-20 Thread Vardan Mikayelyan
The functions with name hibernation are misnamed originally. They were only
responsible for partial power down and not for hibernation.

This patch set adds the real hibernation support for dwc2 driver and renames
existing functions to power_down.xisting functions to power_down.


John Youn (1):
  usb: dwc2: Enable power down

Vardan Mikayelyan (14):
  usb: dwc2: Rename hibernation to partial_power_down
  usb: dwc2: Add hibernation field into dwc2_hw_params
  usb: dwc2: gadget: Moved dtxfsiz backup array place
  usb: dwc2: gadget: Fix dwc2_restore_device_registers
  usb: dwc2: core: Add hibernated flag
  usb: dwc2: gadget: Add remote_wakeup_allowed flag
  usb: dwc2: Changes in registers backup/restore functions
  usb: dwc2: Add helper functions for restore routine
  usb: dwc2: Add host/device hibernation functions
  usb: dwc2: Add dwc2_enter_hibernation(), dwc2_exit_hibernation()
  usb: dwc2: Allow entering hibernation from USB_SUSPEND interrupt
  usb: dwc2: Add dwc2_handle_gpwrdn_intr() handler
  usb: dwc2: Change hub-control to allow hibernation
  usb: dwc2: Replace msleep with mdelay in dwc2_clear_force_mode()

 drivers/usb/dwc2/core.c  | 212 +---
 drivers/usb/dwc2/core.h  |  68 +--
 drivers/usb/dwc2/core_intr.c | 172 ++
 drivers/usb/dwc2/debugfs.c   |   2 +-
 drivers/usb/dwc2/gadget.c| 226 +--
 drivers/usb/dwc2/hcd.c   | 279 ---
 drivers/usb/dwc2/params.c|  50 +++-
 drivers/usb/dwc2/platform.c  |   1 +
 8 files changed, 922 insertions(+), 88 deletions(-)

-- 
1.9.1

--
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 06/15] usb: dwc2: gadget: Add remote_wakeup_allowed flag

2017-02-20 Thread Vardan Mikayelyan
It will be set once corresponding set_feature command comes.

True if device is allowed to wake-up host by remote-wakeup
signalling.

This is preparation for remote wake-up support implementation,
it will not be implemented until gadget stack provide interface
for bringing remote wake-up signalling.

Signed-off-by: Vardan Mikayelyan 
Signed-off-by: John Youn 
---
 drivers/usb/dwc2/core.h   | 3 +++
 drivers/usb/dwc2/gadget.c | 6 ++
 2 files changed, 9 insertions(+)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index d84d0ce..ace383f 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -897,6 +897,8 @@ struct dwc2_hregs_backup {
  * @ctrl_req:   Request for EP0 control packets.
  * @ep0_state:  EP0 control transfers state
  * @test_mode:  USB test mode requested by the host
+ * @remote_wakeup_allowed: True if device is allowed to wake-up host by
+ *  remote-wakeup signalling
  * @setup_desc_dma:EP0 setup stage desc chain DMA address
  * @setup_desc:EP0 setup stage desc chain pointer
  * @ctrl_in_desc_dma:  EP0 IN data phase desc chain DMA address
@@ -1061,6 +1063,7 @@ struct dwc2_hsotg {
struct usb_gadget gadget;
unsigned int enabled:1;
unsigned int connected:1;
+   unsigned int remote_wakeup_allowed:1;
struct dwc2_hsotg_ep *eps_in[MAX_EPS_CHANNELS];
struct dwc2_hsotg_ep *eps_out[MAX_EPS_CHANNELS];
 #endif /* CONFIG_USB_DWC2_PERIPHERAL || CONFIG_USB_DWC2_DUAL_ROLE */
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 3b082ed..fd274a8 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -1665,6 +1665,10 @@ static int dwc2_hsotg_process_req_feature(struct 
dwc2_hsotg *hsotg,
switch (recip) {
case USB_RECIP_DEVICE:
switch (wValue) {
+   case USB_DEVICE_REMOTE_WAKEUP:
+   hsotg->remote_wakeup_allowed = 1;
+   break;
+
case USB_DEVICE_TEST_MODE:
if ((wIndex & 0xff) != 0)
return -EINVAL;
@@ -4626,6 +4630,8 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg)
hsotg->gadget.max_speed = USB_SPEED_HIGH;
hsotg->gadget.ops = _hsotg_gadget_ops;
hsotg->gadget.name = dev_name(dev);
+   hsotg->remote_wakeup_allowed = 0;
+
if (hsotg->dr_mode == USB_DR_MODE_OTG)
hsotg->gadget.is_otg = 1;
else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
-- 
1.9.1

--
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 07/15] usb: dwc2: Changes in registers backup/restore functions

2017-02-20 Thread Vardan Mikayelyan
Move hptxfsiz to host register's backup/restore functions, not
needed to have it in global register's backup/restore functions.

Add backup for glpmcfg, and read/write for gi2cctl and pcgcctl.
As requires programming guide.

Affected functions:
dwc2_backup_host_registers()
dwc2_restore_host_registers()
dwc2_backup_global_registers()
dwc2_restore_global_registers()

Signed-off-by: Vardan Mikayelyan 
Signed-off-by: John Youn 
---
 drivers/usb/dwc2/core.c | 8 ++--
 drivers/usb/dwc2/core.h | 6 --
 drivers/usb/dwc2/hcd.c  | 2 ++
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 185d24c..0e61511 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -78,8 +78,10 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg 
*hsotg)
gr->gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
gr->grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ);
gr->gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
-   gr->hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ);
gr->gdfifocfg = dwc2_readl(hsotg->regs + GDFIFOCFG);
+   gr->glpmcfg = dwc2_readl(hsotg->regs + GLPMCFG);
+   gr->gi2cctl = dwc2_readl(hsotg->regs + GI2CCTL);
+   gr->pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
 
gr->valid = true;
return 0;
@@ -114,8 +116,10 @@ static int dwc2_restore_global_registers(struct dwc2_hsotg 
*hsotg)
dwc2_writel(gr->gahbcfg, hsotg->regs + GAHBCFG);
dwc2_writel(gr->grxfsiz, hsotg->regs + GRXFSIZ);
dwc2_writel(gr->gnptxfsiz, hsotg->regs + GNPTXFSIZ);
-   dwc2_writel(gr->hptxfsiz, hsotg->regs + HPTXFSIZ);
dwc2_writel(gr->gdfifocfg, hsotg->regs + GDFIFOCFG);
+   dwc2_writel(gr->glpmcfg, hsotg->regs + GLPMCFG);
+   dwc2_writel(gr->pcgcctl, hsotg->regs + PCGCTL);
+   dwc2_writel(gr->gi2cctl, hsotg->regs + GI2CCTL);
 
return 0;
 }
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index ace383f..31ebdfa 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -610,7 +610,7 @@ struct dwc2_hw_params {
  * @grxfsiz:   Backup of GRXFSIZ register
  * @gnptxfsiz: Backup of GNPTXFSIZ register
  * @gi2cctl:   Backup of GI2CCTL register
- * @hptxfsiz:  Backup of HPTXFSIZ register
+ * @glpmcfg:   Backup of GLPMCFG register
  * @gdfifocfg: Backup of GDFIFOCFG register
  * @gpwrdn:Backup of GPWRDN register
  */
@@ -622,7 +622,7 @@ struct dwc2_gregs_backup {
u32 grxfsiz;
u32 gnptxfsiz;
u32 gi2cctl;
-   u32 hptxfsiz;
+   u32 glpmcfg;
u32 pcgcctl;
u32 gdfifocfg;
u32 gpwrdn;
@@ -669,6 +669,7 @@ struct dwc2_dregs_backup {
  * @hcintmsk:  Backup of HCINTMSK register
  * @hptr0: Backup of HPTR0 register
  * @hfir:  Backup of HFIR register
+ * @hptxfsiz:  Backup of HPTXFSIZ register
  */
 struct dwc2_hregs_backup {
u32 hcfg;
@@ -676,6 +677,7 @@ struct dwc2_hregs_backup {
u32 hcintmsk[MAX_EPS_CHANNELS];
u32 hprt0;
u32 hfir;
+   u32 hptxfsiz;
bool valid;
 };
 
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 53d580f..e8adfeb 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -5346,6 +5346,7 @@ int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
 
hr->hprt0 = dwc2_read_hprt0(hsotg);
hr->hfir = dwc2_readl(hsotg->regs + HFIR);
+   hr->hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ);
hr->valid = true;
 
return 0;
@@ -5382,6 +5383,7 @@ int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg)
 
dwc2_writel(hr->hprt0, hsotg->regs + HPRT0);
dwc2_writel(hr->hfir, hsotg->regs + HFIR);
+   dwc2_writel(hr->hptxfsiz, hsotg->regs + HPTXFSIZ);
hsotg->frame_number = 0;
 
return 0;
-- 
1.9.1

--
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 08/15] usb: dwc2: Add helper functions for restore routine

2017-02-20 Thread Vardan Mikayelyan
Add common (host/device) helper functions, which will be called while
exiting from hibernation, from both sides.

dwc2_restore_essential_regs()
dwc2_hib_restore_common()

Signed-off-by: Vardan Mikayelyan 
Signed-off-by: John Youn 
---
 drivers/usb/dwc2/core.c | 136 
 drivers/usb/dwc2/core.h |   2 +
 2 files changed, 138 insertions(+)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 0e61511..f478cdd 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -239,6 +239,142 @@ int dwc2_enter_partial_power_down(struct dwc2_hsotg 
*hsotg)
 }
 
 /**
+ * dwc2_restore_essential_regs() - Restore essiential regs of core.
+ *
+ * @hsotg: Programming view of the DWC_otg controller
+ * @rmode: Restore mode, enabled in case of remote-wakeup.
+ */
+static void dwc2_restore_essential_regs(struct dwc2_hsotg *hsotg, int rmode)
+{
+   u32 pcgcctl;
+   struct dwc2_gregs_backup *gr;
+   struct dwc2_dregs_backup *dr;
+   struct dwc2_hregs_backup *hr;
+   int is_host = dwc2_is_host_mode(hsotg);
+
+   gr = >gr_backup;
+   dr = >dr_backup;
+   hr = >hr_backup;
+
+   dev_dbg(hsotg->dev, "%s: restoring essential regs\n", __func__);
+
+   /* Load restore values for [31:14] bits */
+   pcgcctl = (gr->pcgcctl & 0xc000) | 0x0002;
+   dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
+
+   /* Umnask global Interrupt in GAHBCFG and restore it */
+   dwc2_writel(gr->gahbcfg | GAHBCFG_GLBL_INTR_EN, hsotg->regs + GAHBCFG);
+
+   /* Clear all pending interupts */
+   dwc2_writel(0x, hsotg->regs + GINTSTS);
+
+   /* Unmask restore done interrupt */
+   dwc2_writel(GINTSTS_RESTOREDONE, hsotg->regs + GINTMSK);
+
+   /* Restore GUSBCFG and HCFG/DCFG */
+   dwc2_writel(gr->gusbcfg, hsotg->regs + GUSBCFG);
+
+   if (is_host) {
+   dwc2_writel(hr->hcfg, hsotg->regs + HCFG);
+   if (rmode)
+   pcgcctl |= 0x200;
+   dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
+   udelay(10);
+
+   pcgcctl = (gr->pcgcctl & 0xc000) | 0x0002;
+   pcgcctl |= PCGCTL_ESS_REG_RESTORED;
+   dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
+   udelay(10);
+   } else {
+   dwc2_writel(dr->dcfg, hsotg->regs + DCFG);
+   if (!rmode)
+   pcgcctl |= 0x208;
+   dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
+   udelay(10);
+
+   pcgcctl |= PCGCTL_ESS_REG_RESTORED;
+   dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
+   udelay(10);
+   }
+}
+
+/**
+ * dwc2_hib_restore_common() - Common part of restore routine.
+ *
+ * @hsotg: Programming view of the DWC_otg controller
+ * @rem_wakeup: Remote-wakeup, enabled in case of remote-wakeup.
+ */
+void dwc2_hib_restore_common(struct dwc2_hsotg *hsotg, int rem_wakeup)
+{
+   u32 gpwrdn;
+   u32 gintsts;
+   int timeout;
+   int is_host = dwc2_is_host_mode(hsotg);
+
+   /* Switch-on voltage to the core */
+   gpwrdn = dwc2_readl(hsotg->regs + GPWRDN);
+   gpwrdn &= ~GPWRDN_PWRDNSWTCH;
+   dwc2_writel(gpwrdn, hsotg->regs + GPWRDN);
+   udelay(10);
+
+   /* Reset core */
+   gpwrdn = dwc2_readl(hsotg->regs + GPWRDN);
+   gpwrdn &= ~GPWRDN_PWRDNRSTN;
+   dwc2_writel(gpwrdn, hsotg->regs + GPWRDN);
+   udelay(10);
+
+   /* Enable restore from PMU */
+   gpwrdn = dwc2_readl(hsotg->regs + GPWRDN);
+   gpwrdn |= GPWRDN_RESTORE;
+   dwc2_writel(gpwrdn, hsotg->regs + GPWRDN);
+   udelay(10);
+
+   /* Disable Power Down Clamp */
+   gpwrdn = dwc2_readl(hsotg->regs + GPWRDN);
+   gpwrdn &= ~GPWRDN_PWRDNCLMP;
+   dwc2_writel(gpwrdn, hsotg->regs + GPWRDN);
+   udelay(10);
+
+   if (!is_host && rem_wakeup)
+   udelay(70);
+
+   /* Deassert reset core */
+   gpwrdn = dwc2_readl(hsotg->regs + GPWRDN);
+   gpwrdn |= GPWRDN_PWRDNRSTN;
+   dwc2_writel(gpwrdn, hsotg->regs + GPWRDN);
+   udelay(10);
+
+   /* Disable PMU interrupt */
+   gpwrdn = dwc2_readl(hsotg->regs + GPWRDN);
+   gpwrdn &= ~GPWRDN_PMUINTSEL;
+   dwc2_writel(gpwrdn, hsotg->regs + GPWRDN);
+
+   /* Set Restore Essential Regs bit in PCGCCTL register */
+   dwc2_restore_essential_regs(hsotg, rem_wakeup);
+
+   /*
+* Wait For Restore_done Interrupt. This mechanism of polling the
+* interrupt is introduced to avoid any possible race conditions
+*/
+   timeout = 2000;
+   do {
+   gintsts = dwc2_readl(hsotg->regs + GINTSTS);
+   if (!(gintsts & GINTSTS_RESTOREDONE)) {
+   udelay(10);
+   continue;
+   }
+   dwc2_writel(GINTSTS_RESTOREDONE, hsotg->regs + GINTSTS);
+   

[PATCH 05/15] usb: dwc2: core: Add hibernated flag

2017-02-20 Thread Vardan Mikayelyan
True if core is hibernated.

Signed-off-by: Vardan Mikayelyan 
Signed-off-by: John Youn 
---
 drivers/usb/dwc2/core.h | 2 ++
 drivers/usb/dwc2/platform.c | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 60ad2e6..d84d0ce 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -779,6 +779,7 @@ struct dwc2_hregs_backup {
  * @hcd_enabledHost mode sub-driver initialization indicator.
  * @gadget_enabled Peripheral mode sub-driver initialization indicator.
  * @ll_hw_enabled  Status of low-level hardware resources.
+ * @hibernated:True if core is hibernated
  * @phy:The otg phy transceiver structure for phy control.
  * @uphy:   The otg phy transceiver structure for old USB phy
  *  control.
@@ -916,6 +917,7 @@ struct dwc2_hsotg {
unsigned int hcd_enabled:1;
unsigned int gadget_enabled:1;
unsigned int ll_hw_enabled:1;
+   unsigned int hibernated:1;
 
struct phy *phy;
struct usb_phy *uphy;
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index db98463..c4e365a 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -462,6 +462,7 @@ static int dwc2_driver_probe(struct platform_device *dev)
}
 
platform_set_drvdata(dev, hsotg);
+   hsotg->hibernated = 0;
 
dwc2_debugfs_init(hsotg);
 
-- 
1.9.1

--
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 09/15] usb: dwc2: Add host/device hibernation functions

2017-02-20 Thread Vardan Mikayelyan
Add host/device hibernation functions which must be wrapped
by core's  dwc2_enter_hibernation()/dwc2_exit_hibernation()
functions.

Make dwc2_backup_global_registers dwc2_restore_global_register
non-static to use them in both host/gadget sides.

Added function names:
dwc2_gadget_enter_hibernation()
dwc2_gadget_exit_hibernation()
dwc2_host_enter_hibernation()
dwc2_host_exit_hibernation()

Signed-off-by: Vardan Mikayelyan 
Signed-off-by: John Youn 
---
 drivers/usb/dwc2/core.c   |   4 +-
 drivers/usb/dwc2/core.h   |  18 
 drivers/usb/dwc2/gadget.c | 196 ++
 drivers/usb/dwc2/hcd.c| 233 ++
 4 files changed, 449 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index f478cdd..a37dfc2 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -63,7 +63,7 @@
  *
  * @hsotg: Programming view of the DWC_otg controller
  */
-static int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg)
+int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg)
 {
struct dwc2_gregs_backup *gr;
 
@@ -94,7 +94,7 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg 
*hsotg)
  *
  * @hsotg: Programming view of the DWC_otg controller
  */
-static int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg)
+int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg)
 {
struct dwc2_gregs_backup *gr;
 
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 950915b..9d17f4a 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -1131,6 +1131,8 @@ static inline bool dwc2_is_hs_iot(struct dwc2_hsotg 
*hsotg)
 void dwc2_disable_global_interrupts(struct dwc2_hsotg *hcd);
 
 void dwc2_hib_restore_common(struct dwc2_hsotg *hsotg, int rem_wakeup);
+int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg);
+int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg);
 
 /* This function should be called on every hardware interrupt. */
 irqreturn_t dwc2_handle_common_intr(int irq, void *dev);
@@ -1193,6 +1195,9 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg 
*dwc2,
 #define dwc2_is_device_connected(hsotg) (hsotg->connected)
 int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg);
 int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg, int remote_wakeup);
+int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg);
+int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg,
+int rem_wakeup, int reset);
 int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg);
 int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg);
 int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg);
@@ -1218,6 +1223,11 @@ static inline int dwc2_backup_device_registers(struct 
dwc2_hsotg *hsotg)
 static inline int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg,
int remote_wakeup)
 { return 0; }
+static inline int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg)
+{ return 0; }
+static inline int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg,
+  int rem_wakeup, int reset)
+{ return 0; }
 static inline int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg)
 { return 0; }
 static inline int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg)
@@ -1234,6 +1244,9 @@ static inline int dwc2_hsotg_tx_fifo_average_depth(struct 
dwc2_hsotg *hsotg)
 void dwc2_hcd_start(struct dwc2_hsotg *hsotg);
 int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg);
 int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg);
+int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg);
+int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg,
+  int rem_wakeup, int reset);
 #else
 static inline int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg)
 { return 0; }
@@ -1250,6 +1263,11 @@ static inline int dwc2_backup_host_registers(struct 
dwc2_hsotg *hsotg)
 { return 0; }
 static inline int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg)
 { return 0; }
+static inline int dwc2_host_enter_hibernation(struct dwc2_hsotg *hsotg)
+{ return 0; }
+static inline int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg,
+int rem_wakeup, int reset)
+{ return 0; }
 
 #endif
 
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index fd274a8..e82e1db 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -4870,3 +4870,199 @@ int dwc2_restore_device_registers(struct dwc2_hsotg 
*hsotg, int remote_wakeup)
 
return 0;
 }
+
+/**
+ * dwc2_gadget_enter_hibernation() - Put controller in Hibernation.
+ *
+ * @hsotg: Programming view of the DWC_otg controller
+ *
+ * Return non-zero if failed to enter to hibernation.
+ */
+int dwc2_gadget_enter_hibernation(struct dwc2_hsotg *hsotg)
+{

[PATCH 03/15] usb: dwc2: gadget: Moved dtxfsiz backup array place

2017-02-20 Thread Vardan Mikayelyan
Moved dtxfsiz from dwc2_gregs_backup to dwc2_dregs_backup,
because it is device register.

Signed-off-by: Vardan Mikayelyan 
Signed-off-by: John Youn 
---
 drivers/usb/dwc2/core.c   | 8 ++--
 drivers/usb/dwc2/core.h   | 4 ++--
 drivers/usb/dwc2/gadget.c | 2 ++
 3 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index fe976eb..7addf69 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -66,7 +66,8 @@
 static int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg)
 {
struct dwc2_gregs_backup *gr;
-   int i;
+
+   dev_dbg(hsotg->dev, "%s\n", __func__);
 
/* Backup global regs */
gr = >gr_backup;
@@ -79,8 +80,6 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg 
*hsotg)
gr->gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
gr->hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ);
gr->gdfifocfg = dwc2_readl(hsotg->regs + GDFIFOCFG);
-   for (i = 0; i < MAX_EPS_CHANNELS; i++)
-   gr->dtxfsiz[i] = dwc2_readl(hsotg->regs + DPTXFSIZN(i));
 
gr->valid = true;
return 0;
@@ -96,7 +95,6 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg 
*hsotg)
 static int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg)
 {
struct dwc2_gregs_backup *gr;
-   int i;
 
dev_dbg(hsotg->dev, "%s\n", __func__);
 
@@ -118,8 +116,6 @@ static int dwc2_restore_global_registers(struct dwc2_hsotg 
*hsotg)
dwc2_writel(gr->gnptxfsiz, hsotg->regs + GNPTXFSIZ);
dwc2_writel(gr->hptxfsiz, hsotg->regs + HPTXFSIZ);
dwc2_writel(gr->gdfifocfg, hsotg->regs + GDFIFOCFG);
-   for (i = 0; i < MAX_EPS_CHANNELS; i++)
-   dwc2_writel(gr->dtxfsiz[i], hsotg->regs + DPTXFSIZN(i));
 
return 0;
 }
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 526d870..4cb95b3 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -612,7 +612,6 @@ struct dwc2_hw_params {
  * @gi2cctl:   Backup of GI2CCTL register
  * @hptxfsiz:  Backup of HPTXFSIZ register
  * @gdfifocfg: Backup of GDFIFOCFG register
- * @dtxfsiz:   Backup of DTXFSIZ registers for each endpoint
  * @gpwrdn:Backup of GPWRDN register
  */
 struct dwc2_gregs_backup {
@@ -626,7 +625,6 @@ struct dwc2_gregs_backup {
u32 hptxfsiz;
u32 pcgcctl;
u32 gdfifocfg;
-   u32 dtxfsiz[MAX_EPS_CHANNELS];
u32 gpwrdn;
bool valid;
 };
@@ -645,6 +643,7 @@ struct dwc2_gregs_backup {
  * @doepctl:   Backup of DOEPCTL register
  * @doeptsiz:  Backup of DOEPTSIZ register
  * @doepdma:   Backup of DOEPDMA register
+ * @dtxfsiz:   Backup of DTXFSIZ registers for each endpoint
  */
 struct dwc2_dregs_backup {
u32 dcfg;
@@ -658,6 +657,7 @@ struct dwc2_dregs_backup {
u32 doepctl[MAX_EPS_CHANNELS];
u32 doeptsiz[MAX_EPS_CHANNELS];
u32 doepdma[MAX_EPS_CHANNELS];
+   u32 dtxfsiz[MAX_EPS_CHANNELS];
bool valid;
 };
 
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 4bd3cab..3e969a5 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -4810,6 +4810,7 @@ int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
 
dr->doeptsiz[i] = dwc2_readl(hsotg->regs + DOEPTSIZ(i));
dr->doepdma[i] = dwc2_readl(hsotg->regs + DOEPDMA(i));
+   dr->dtxfsiz[i] = dwc2_readl(hsotg->regs + DPTXFSIZN(i));
}
dr->valid = true;
return 0;
@@ -4850,6 +4851,7 @@ int dwc2_restore_device_registers(struct dwc2_hsotg 
*hsotg)
dwc2_writel(dr->diepctl[i], hsotg->regs + DIEPCTL(i));
dwc2_writel(dr->dieptsiz[i], hsotg->regs + DIEPTSIZ(i));
dwc2_writel(dr->diepdma[i], hsotg->regs + DIEPDMA(i));
+   dwc2_writel(dr->dtxfsiz[i], hsotg->regs + DPTXFSIZN(i));
 
/* Restore OUT EPs */
dwc2_writel(dr->doepctl[i], hsotg->regs + DOEPCTL(i));
-- 
1.9.1

--
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] lvs: fix race condition in disconnect handling

2017-02-20 Thread Oliver Neukum
There is a small window during which the an URB may
remain active after disconnect has returned. If in that case
already freed memory may be accessed and executed.

The fix is to poison the URB befotre the work is flushed.

Signed-off-by: Oliver Neukum 
---
 drivers/usb/misc/lvstest.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c
index 7717651..e5d2500 100644
--- a/drivers/usb/misc/lvstest.c
+++ b/drivers/usb/misc/lvstest.c
@@ -429,6 +429,8 @@ static void lvs_rh_disconnect(struct usb_interface *intf)
struct lvs_rh *lvs = usb_get_intfdata(intf);
 
sysfs_remove_group(>dev.kobj, _attr_group);
+   usb_poison_urb(lvs->urb); /* used in scheduled work */
+   (lvs->urb);
flush_work(>rh_work);
usb_free_urb(lvs->urb);
 }
-- 
2.10.2

--
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] tools/usb: Add .gitignore file

2017-02-20 Thread Prarit Bhargava
Add .gitignore file for untracked files in tools/usb.

Signed-off-by: Prarit Bhargava 
---
 tools/usb/.gitignore | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 tools/usb/.gitignore

diff --git a/tools/usb/.gitignore b/tools/usb/.gitignore
new file mode 100644
index ..1b7448981435
--- /dev/null
+++ b/tools/usb/.gitignore
@@ -0,0 +1,2 @@
+ffs-test
+testusb
-- 
1.8.3.1

--
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: add cast to avoid potential integer overflow

2017-02-20 Thread David Laight
From: Gustavo A. R. Silva
> Sent: 17 February 2017 00:17
> The type of variable 'sel' is unsigned int. Such variable is being used
> multiple times in a context that expects an expression of type unsigned
> long long. So, to avoid any potential integer overflow, a cast to type
> unsigned long long is added.
...
> - timeout_ns = udev->u1_params.sel * 3;
> + timeout_ns = (unsigned long long)udev->u1_params.sel * 3;
...

It is probably better to just change the constant to 3ull.
However I'd be tempted to look more closely at the valid values
for 'timeout_ns'.
It seems unlikely that that the timeout (in sel) will be near
enough to 4 seconds that multiplying by a small integer will
take the value over 4 seconds without requiring larger input
values be supported.

timeout_ns might even be being used in places where the value
has to be smaller than 1 second!

David

--
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: VL805 USB 3.0 does not see connected devices (only on x86_64) (x86 is ok)

2017-02-20 Thread Oliver Neukum
Am Sonntag, den 19.02.2017, 06:48 +0300 schrieb c400:
> [  805.771818] sd 7:0:0:0: [sdd] Attached SCSI removable disk
> [  805.811101] DMAR: DRHD: handling fault status reg 2
> [  805.811108] DMAR: [DMA Read] Request device [07:00.0] fault addr
> fff98000 [fault reason 06] PTE Read access is not set
> [  805.811139] xhci_hcd :07:00.0: WARNING: Host System Error
> [  805.848184] xhci_hcd :07:00.0: Host not halted after 16000
> microseconds.

This looks like your iommu is acting up. Does it work if you disable
support for it?

Regards
Oliver

--
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 v19 4/4] power: wm831x_power: Support USB charger current limit management

2017-02-20 Thread kbuild test robot
Hi Baolin,

[auto build test ERROR on v4.9-rc8]
[cannot apply to balbi-usb/next usb/usb-testing battery/master next-20170220]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Baolin-Wang/Introduce-usb-charger-framework-to-deal-with-the-usb-gadget-power-negotation/20170220-173051
config: i386-randconfig-x017-201708 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All errors (new ones prefixed by >>):

   In file included from drivers/power/supply/wm831x_power.c:16:0:
   include/linux/usb/charger.h: In function 'usb_charger_get_state':
   include/linux/usb/charger.h:151:9: error: 'USB_CHARGER_REMOVE' undeclared 
(first use in this function)
 return USB_CHARGER_REMOVE;
^~
   include/linux/usb/charger.h:151:9: note: each undeclared identifier is 
reported only once for each function it appears in
   drivers/power/supply/wm831x_power.c: In function 'wm831x_usb_limit_change':
>> drivers/power/supply/wm831x_power.c:151:2: error: 'best' undeclared (first 
>> use in this function)
 best = 0;
 ^~~~
>> drivers/power/supply/wm831x_power.c:152:7: error: 'i' undeclared (first use 
>> in this function)
 for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
  ^

vim +/best +151 drivers/power/supply/wm831x_power.c

10  
11  #include 
12  #include 
13  #include 
14  #include 
15  #include 
  > 16  #include 
17  
18  #include 
19  #include 
20  #include 
21  #include 
22  
23  struct wm831x_power {
24  struct wm831x *wm831x;
25  struct power_supply *wall;
26  struct power_supply *usb;
27  struct power_supply *battery;
28  struct power_supply_desc wall_desc;
29  struct power_supply_desc usb_desc;
30  struct power_supply_desc battery_desc;
31  char wall_name[20];
32  char usb_name[20];
33  char battery_name[20];
34  bool have_battery;
35  struct usb_charger *usb_charger;
36  struct notifier_block usb_notify;
37  };
38  
39  static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
40   union power_supply_propval *val)
41  {
42  int ret;
43  
44  ret = wm831x_reg_read(wm831x, WM831X_SYSTEM_STATUS);
45  if (ret < 0)
46  return ret;
47  
48  if (ret & supply)
49  val->intval = 1;
50  else
51  val->intval = 0;
52  
53  return 0;
54  }
55  
56  static int wm831x_power_read_voltage(struct wm831x *wm831x,
57   enum wm831x_auxadc src,
58   union power_supply_propval *val)
59  {
60  int ret;
61  
62  ret = wm831x_auxadc_read_uv(wm831x, src);
63  if (ret >= 0)
64  val->intval = ret;
65  
66  return ret;
67  }
68  
69  /*
70   *  WALL Power
71   */
72  static int wm831x_wall_get_prop(struct power_supply *psy,
73  enum power_supply_property psp,
74  union power_supply_propval *val)
75  {
76  struct wm831x_power *wm831x_power = 
dev_get_drvdata(psy->dev.parent);
77  struct wm831x *wm831x = wm831x_power->wm831x;
78  int ret = 0;
79  
80  switch (psp) {
81  case POWER_SUPPLY_PROP_ONLINE:
82  ret = wm831x_power_check_online(wm831x, 
WM831X_PWR_WALL, val);
83  break;
84  case POWER_SUPPLY_PROP_VOLTAGE_NOW:
85  ret = wm831x_power_read_voltage(wm831x, 
WM831X_AUX_WALL, val);
86  break;
87  default:
88  ret = -EINVAL;
89  break;
90  }
91  
92  return ret;
93  }
94  
95  static enum power_supply_property wm831x_wall_props[] = {
96  POWER_SUPPLY_PROP_ONLINE,
97  POWER_SUPPLY_PROP_VOLTAGE_NOW,
98  };
99  
   100  /*
   101   *  USB Power
   102   */
   103  static int wm831x_usb_get_prop(struct power_supply *psy,
   104 enum power_supp

Re: Subject: [PATCH v3] USB:Core: BugFix: Proper handling of Race Condition when two USB class drivers try to call init_usb_class simultaneously

2017-02-20 Thread Ajay Kaher
 
On Thu, 16 Feb 2017, Alan Stern wrote: 

> On Thu, 16 Feb 2017, Ajay Kaher wrote:
> 
>> > On Thu, 14 Feb 2017, Alan Stern wrote:
>> > 
>> > I think Ajay's argument is correct and a patch is needed.  But this
>> > patch misses the race between init_usb_class() and release_usb_class().  
>> 
>> Thanks Alan for your comments, in patch v2 I have taken care for
>> release_usb_class() also. Please review again.
>> 
>> > The basic problem is that reference counting doesn't work when you try
>> > to use the same global pointer (usb_class) to refer to multiple
>> > generations of a dynamically allocated entity.  We had the same sort of
>> > problem many years ago with the usb_interface structure (and we
>> > ultimately fixed it by creating a separate usb_interface_cache
>> > structure).
>> >  
>> > The best approach here would be to forget about all the reference
>> > counting.  Get rid of usb_class entirely, and create the "usbmisc"
>> > class structure just once, when usbcore initializes.  Or, if you
>> > prefer, use a mutex to protect a routine that allocates the class
>> > structure dynamically, just once.  Either way, don't deallocate it
>> > until usbcore is unloaded.
>> 
>> usbmisc class creation should not require everytime when USB core
>> initializes. So better to keep usbmisc class creation as it is. 
>> And to prevent the race conditions just protect it with Mutex locking
>> as per patch v2.
> 
> This is not right.  What happens if usb_register_dev() runs just before
> release_usb_class() calls mutex_lock()?
 
Alan, as per my understanding I have shifted the lock from
release_usb_class() to destroy_usb_class() in patch v3. 
If it is not right, please explain in detail which race condition
I have missed and also share your suggestions.

thanks,
ajay kaher

Signed-off-by: Ajay Kaher

---

 drivers/usb/core/file.c |6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 822ced9..a12d184 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -27,6 +27,7 @@
 #define MAX_USB_MINORS 256
 static const struct file_operations *usb_minors[MAX_USB_MINORS];
 static DECLARE_RWSEM(minor_rwsem);
+static DEFINE_MUTEX(init_usb_class_mutex);

 static int usb_open(struct inode *inode, struct file *file)
 {
@@ -109,8 +110,10 @@ static void release_usb_class(struct kref *kref)

 static void destroy_usb_class(void)
 {
+   mutex_lock(_usb_class_mutex);
if (usb_class)
kref_put(_class->kref, release_usb_class);
+   mutex_unlock(_usb_class_mutex);
 }

 int usb_major_init(void)
@@ -171,7 +174,10 @@ int usb_register_dev(struct usb_interface *intf,
if (intf->minor >= 0)
return -EADDRINUSE;

+   mutex_lock(_usb_class_mutex);
retval = init_usb_class();
+   mutex_unlock(_usb_class_mutex);
+
if (retval)
return retval;







 


Re: [PATCH v19 2/4] usb: gadget: Support for the usb charger framework

2017-02-20 Thread Baolin Wang
On 20 February 2017 at 18:08, kbuild test robot <l...@intel.com> wrote:
> Hi Baolin,
>
> [auto build test ERROR on v4.9-rc8]
> [cannot apply to balbi-usb/next usb/usb-testing battery/master next-20170220]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improve the system]
>
> url:
> https://github.com/0day-ci/linux/commits/Baolin-Wang/Introduce-usb-charger-framework-to-deal-with-the-usb-gadget-power-negotation/20170220-173051
> config: i386-randconfig-x015-201708 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=i386
>
> All errors (new ones prefixed by >>):
>
>In file included from drivers/usb/gadget/udc/core.c:28:0:
>include/linux/usb/charger.h: In function 'usb_charger_get_state':
>>> include/linux/usb/charger.h:151:9: error: 'USB_CHARGER_REMOVE' undeclared 
>>> (first use in this function)
>  return USB_CHARGER_REMOVE;

Ah, missed fixing the state name without enable USB charger. Will fix
in next version.

> ^~
>include/linux/usb/charger.h:151:9: note: each undeclared identifier is 
> reported only once for each function it appears in
>
> vim +/USB_CHARGER_REMOVE +151 include/linux/usb/charger.h
>
> 28929615 Baolin Wang 2017-02-20  145return UNKNOWN_TYPE;
> 28929615 Baolin Wang 2017-02-20  146  }
> 28929615 Baolin Wang 2017-02-20  147
> 28929615 Baolin Wang 2017-02-20  148  static inline enum usb_charger_state
> 28929615 Baolin Wang 2017-02-20  149  usb_charger_get_state(struct 
> usb_charger *uchger)
> 28929615 Baolin Wang 2017-02-20  150  {
> 28929615 Baolin Wang 2017-02-20 @151return USB_CHARGER_REMOVE;
> 28929615 Baolin Wang 2017-02-20  152  }
> 28929615 Baolin Wang 2017-02-20  153
> 28929615 Baolin Wang 2017-02-20  154  static inline int 
> usb_charger_detect_type(struct usb_charger *uchger)
>
> :: The code at line 151 was first introduced by commit
> :: 289296154f05985dedc08273f04d5b738450b3c7 usb: gadget: Introduce the 
> usb charger framework
>
> :: TO: Baolin Wang <baolin.w...@linaro.org>
> :: CC: 0day robot <fengguang...@intel.com>
>
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation



-- 
Baolin.wang
Best Regards
--
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 v19 2/4] usb: gadget: Support for the usb charger framework

2017-02-20 Thread kbuild test robot
Hi Baolin,

[auto build test ERROR on v4.9-rc8]
[cannot apply to balbi-usb/next usb/usb-testing battery/master next-20170220]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Baolin-Wang/Introduce-usb-charger-framework-to-deal-with-the-usb-gadget-power-negotation/20170220-173051
config: i386-randconfig-x015-201708 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All errors (new ones prefixed by >>):

   In file included from drivers/usb/gadget/udc/core.c:28:0:
   include/linux/usb/charger.h: In function 'usb_charger_get_state':
>> include/linux/usb/charger.h:151:9: error: 'USB_CHARGER_REMOVE' undeclared 
>> (first use in this function)
 return USB_CHARGER_REMOVE;
^~
   include/linux/usb/charger.h:151:9: note: each undeclared identifier is 
reported only once for each function it appears in

vim +/USB_CHARGER_REMOVE +151 include/linux/usb/charger.h

28929615 Baolin Wang 2017-02-20  145return UNKNOWN_TYPE;
28929615 Baolin Wang 2017-02-20  146  }
28929615 Baolin Wang 2017-02-20  147  
28929615 Baolin Wang 2017-02-20  148  static inline enum usb_charger_state
28929615 Baolin Wang 2017-02-20  149  usb_charger_get_state(struct usb_charger 
*uchger)
28929615 Baolin Wang 2017-02-20  150  {
28929615 Baolin Wang 2017-02-20 @151return USB_CHARGER_REMOVE;
28929615 Baolin Wang 2017-02-20  152  }
28929615 Baolin Wang 2017-02-20  153  
28929615 Baolin Wang 2017-02-20  154  static inline int 
usb_charger_detect_type(struct usb_charger *uchger)

:: The code at line 151 was first introduced by commit
:: 289296154f05985dedc08273f04d5b738450b3c7 usb: gadget: Introduce the usb 
charger framework

:: TO: Baolin Wang <baolin.w...@linaro.org>
:: CC: 0day robot <fengguang...@intel.com>

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


[PATCH v19 0/4] Introduce usb charger framework to deal with the usb gadget power negotation

2017-02-20 Thread Baolin Wang
Currently the Linux kernel does not provide any standard integration of this
feature that integrates the USB subsystem with the system power regulation
provided by PMICs meaning that either vendors must add this in their kernels
or USB gadget devices based on Linux (such as mobile phones) may not behave
as they should. Thus provide a standard framework for doing this in kernel.

Now introduce one user with wm831x_power to support and test the usb charger.
Another user introduced to support charger detection by Jun Li:
https://www.spinics.net/lists/linux-usb/msg139425.html
Moreover there may be other potential users will use it in future. 

1. Before v19 patchset we've fixed below issues in extcon subsystem and usb
phy driver, now all were merged. (Thanks for Neil's suggestion)
(1) Have fixed the inconsistencies with USB connector types in extcon subsystem
by following links:
https://lkml.org/lkml/2016/12/21/13
https://lkml.org/lkml/2016/12/21/15
https://lkml.org/lkml/2016/12/21/79
https://lkml.org/lkml/2017/1/3/13

(2) Instead of using 'set_power' callback in phy drivers, we will introduce
USB charger to set PMIC current drawn from USB configuration, moreover some
'set_power' callbacks did not implement anything to set PMIC current, thus
remove them by following links:
https://lkml.org/lkml/2017/1/18/436
https://lkml.org/lkml/2017/1/18/439
https://lkml.org/lkml/2017/1/18/438
Now only two phy drivers (phy-isp1301-omap.c and phy-gpio-vbus-usb.c) still
used 'set_power' callback to set current, we can remove them in future. (I
have no platform with enabling these two phy drivers, so I can not test them
if I converted 'set_power' callback to USB charger.)

2. Some issues pointed by Neil Brown were sill kept in this v19 patchset, and
I expalined each issue and may be need discuss again:
(1) Change all usb phys to register an extcon and to send appropriate 
notifications.
Firstly, now only 3 USB phy drivers (phy-qcom-8x16-usb.c, phy-omap-otg.c and
phy-msm-usb.c) had registered an extcon, mostly did not. I can not change all
usb phys to register an extcon, since there are no extcon device to register
for these different phy drivers.
Secondly, I also agreed with Peter's comments: Not only USB PHY to register
an extcon, but also for the drivers which can detect USB charger type, it may
be USB controller driver, USB type-c driver, pmic driver, and these drivers
may not have an extcon device since the internal part can finish the vbus
detect.

(2) Change the notifier of usb_phy to be used consistently.
Now only 3 phy drivers (phy-generic.c, phy-ab8500-usb.c and phy-gpio-vbus-usb.c)
used the notifier of usb_phy. phy-generic.c and phy-gpio-vbus-usb.c were used to
send out the connect events, and phy-ab8500-usb.c also was used to send out the
MUSB connect events. There are no phy drivers will notify 'vbus_draw' 
information
by the notifier of usb_phy, which was used consistently now.
Moreover it is difficult to change the notifier of usb_phy to be used only to
communicate the 'vbus_draw' information, since we need to refactor and test 
these
related phy drivers, power drivers or some mfd drivers, which is a huge 
workload.

(3) Still keep charger_type_show() API.
Firstly I think we should combine all charger related information into one
place for users, which is convenient.
Secondly not only we get charger type from extcon, but also in some scenarios
we can get charger type from USB controller driver, USB type-c driver, pmic
driver, we should also need one place to export the charger type.

Changes since v18:
 Other issues addressed in this patchset:
 - Modify the method of looking up one USB charger instance, we assume there is
 only one USB charger in the system. But leaving things there to avoid any need
 for future refactoring to touch the usb_charger_register() interface.
 - Remove usb_charger_set_current() API.
 - Rename usb charger state.
 - Remove ->get_charger_type() interface.
 - Add some documentation for ->charger_detect() interface explicitly.
 - Fix one issue: reset current to default values when cable was unplugged.
 - Only notify the max current to power users, but users can get the min current
 by usb_charger_get_current() if users want to use the min current.
 - Other small optimizations.

Changes since v17:
 - Remove goto section in usb_charger_register() function.
 - Remove 'extern' in charger.h file.
 - Move the kfree() to usb_charger_exit() function.

Changes since v16:
 - Modify the charger current range with introducing the maximum and minimum
 current.
 - Remove the getting charger type method from power supply.
 - Add the getting charger type method from extcon system.
 - Introduce new usb_charger_get_current() API for users to get the maximum and
 minimum current.
 - Rename some APIs and other optimization.

Changes since v15:
 - Add charger state checking to avoid sending out duplicate notifies to users.
 - Add one work to notify power users the current has been changed.

Changes since v14:
 

[PATCH v19 2/4] usb: gadget: Support for the usb charger framework

2017-02-20 Thread Baolin Wang
For supporting the usb charger, it adds the usb_charger_init() and
usb_charger_exit() functions for usb charger initialization and exit.

It will report to the usb charger when the gadget state is changed,
then the usb charger can do the power things.

Signed-off-by: Baolin Wang 
Reviewed-by: Li Jun 
Tested-by: Li Jun 
---
 drivers/usb/gadget/udc/core.c |   19 ++-
 include/linux/usb/gadget.h|3 +++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index 9483489..90df022 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -576,12 +577,17 @@ int usb_gadget_vbus_connect(struct usb_gadget *gadget)
  * reporting how much power the device may consume.  For example, this
  * could affect how quickly batteries are recharged.
  *
+ * It will also notify the USB charger how much power the device may
+ * consume if there is a USB charger linking with the gadget.
+ *
  * Returns zero on success, else negative errno.
  */
 int usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
 {
int ret = 0;
 
+   usb_charger_set_cur_limit_by_gadget(gadget, mA);
+
if (!gadget->ops->vbus_draw) {
ret = -EOPNOTSUPP;
goto out;
@@ -963,6 +969,9 @@ static void usb_gadget_state_work(struct work_struct *work)
struct usb_gadget *gadget = work_to_gadget(work);
struct usb_udc *udc = gadget->udc;
 
+   /* when the gadget state is changed, then report to USB charger */
+   usb_charger_plug_by_gadget(gadget, gadget->state);
+
if (udc)
sysfs_notify(>dev.kobj, NULL, "state");
 }
@@ -1132,6 +1141,10 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
if (ret)
goto err4;
 
+   ret = usb_charger_init(gadget);
+   if (ret)
+   goto err5;
+
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
udc->vbus = true;
 
@@ -1143,7 +1156,7 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
if (ret != -EPROBE_DEFER)
list_del(>pending);
if (ret)
-   goto err5;
+   goto err6;
break;
}
}
@@ -1152,6 +1165,9 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
 
return 0;
 
+err6:
+   usb_charger_exit(gadget);
+
 err5:
device_del(>dev);
 
@@ -1263,6 +1279,7 @@ void usb_del_gadget_udc(struct usb_gadget *gadget)
kobject_uevent(>dev.kobj, KOBJ_REMOVE);
flush_work(>work);
device_unregister(>dev);
+   usb_charger_exit(gadget);
device_unregister(>dev);
 }
 EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index e4516e9..b4d7be2 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define UDC_TRACE_STR_MAX  512
 
@@ -328,6 +329,7 @@ struct usb_gadget_ops {
  * @in_epnum: last used in ep number
  * @mA: last set mA value
  * @otg_caps: OTG capabilities of this gadget.
+ * @charger: Negotiate the power with the usb charger.
  * @sg_supported: true if we can handle scatter-gather
  * @is_otg: True if the USB device port uses a Mini-AB jack, so that the
  * gadget driver must provide a USB OTG descriptor.
@@ -387,6 +389,7 @@ struct usb_gadget {
unsignedin_epnum;
unsignedmA;
struct usb_otg_caps *otg_caps;
+   struct usb_charger  *charger;
 
unsignedsg_supported:1;
unsignedis_otg:1;
-- 
1.7.9.5

--
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 v19 4/4] power: wm831x_power: Support USB charger current limit management

2017-02-20 Thread Baolin Wang
Integrate with the newly added USB charger interface to limit the current
we draw from the USB input based on the input device configuration
identified by the USB stack, allowing us to charge more quickly from high
current inputs without drawing more current than specified from others.

Signed-off-by: Mark Brown 
Signed-off-by: Baolin Wang 
Acked-by: Lee Jones 
Acked-by: Charles Keepax 
Acked-by: Peter Chen 
Acked-by: Sebastian Reichel 
---
 drivers/power/supply/wm831x_power.c |   63 +++
 1 file changed, 63 insertions(+)

diff --git a/drivers/power/supply/wm831x_power.c 
b/drivers/power/supply/wm831x_power.c
index 7082301..b5f1652 100644
--- a/drivers/power/supply/wm831x_power.c
+++ b/drivers/power/supply/wm831x_power.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -31,6 +32,8 @@ struct wm831x_power {
char usb_name[20];
char battery_name[20];
bool have_battery;
+   struct usb_charger *usb_charger;
+   struct notifier_block usb_notify;
 };
 
 static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
@@ -125,6 +128,42 @@ static int wm831x_usb_get_prop(struct power_supply *psy,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
 };
 
+/* In milliamps */
+static const unsigned int wm831x_usb_limits[] = {
+   0,
+   2,
+   100,
+   500,
+   900,
+   1500,
+   1800,
+   550,
+};
+
+static int wm831x_usb_limit_change(struct notifier_block *nb,
+  unsigned long limit, void *data)
+{
+   struct wm831x_power *wm831x_power = container_of(nb,
+struct wm831x_power,
+usb_notify);
+
+   /* Find the highest supported limit */
+   best = 0;
+   for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
+   if (limit >= wm831x_usb_limits[i] &&
+   wm831x_usb_limits[best] < wm831x_usb_limits[i])
+   best = i;
+   }
+
+   dev_dbg(wm831x_power->wm831x->dev,
+   "Limiting USB current to %umA", wm831x_usb_limits[best]);
+
+   wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
+   WM831X_USB_ILIM_MASK, best);
+
+   return 0;
+}
+
 /*
  * Battery properties
  */
@@ -607,8 +646,26 @@ static int wm831x_power_probe(struct platform_device *pdev)
}
}
 
+   power->usb_charger = usb_charger_get_instance();
+   if (IS_ERR(power->usb_charger)) {
+   ret = PTR_ERR(power->usb_charger);
+   dev_err(>dev, "Failed to find USB gadget: %d\n", ret);
+   goto err_bat_irq;
+   }
+
+   power->usb_notify.notifier_call = wm831x_usb_limit_change;
+
+   ret = usb_charger_register_notify(power->usb_charger,
+ >usb_notify);
+   if (ret != 0) {
+   dev_err(>dev, "Failed to register notifier: %d\n", ret);
+   goto err_usb_charger;
+   }
+
return ret;
 
+err_usb_charger:
+   /* put_device on charger */
 err_bat_irq:
--i;
for (; i >= 0; i--) {
@@ -637,6 +694,12 @@ static int wm831x_power_remove(struct platform_device 
*pdev)
struct wm831x *wm831x = wm831x_power->wm831x;
int irq, i;
 
+   if (wm831x_power->usb_charger) {
+   usb_charger_unregister_notify(wm831x_power->usb_charger,
+ _power->usb_notify);
+   /* Free charger */
+   }
+
for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
irq = wm831x_irq(wm831x, 
 platform_get_irq_byname(pdev,
-- 
1.7.9.5

--
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 v19 3/4] usb: gadget: Integrate with the usb gadget supporting for usb charger

2017-02-20 Thread Baolin Wang
When the usb gadget supporting for usb charger is ready, the usb charger
can implement the usb_charger_plug_by_gadget() function, usb_charger_exit()
function and dev_to_uchger() function by getting 'struct usb_charger' from
'struct gadget'.

Signed-off-by: Baolin Wang 
Reviewed-by: Li Jun 
Tested-by: Li Jun 
---
 drivers/usb/gadget/udc/charger.c |   97 +-
 1 file changed, 96 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/udc/charger.c b/drivers/usb/gadget/udc/charger.c
index 6d62f54..19eb044 100644
--- a/drivers/usb/gadget/udc/charger.c
+++ b/drivers/usb/gadget/udc/charger.c
@@ -38,7 +38,9 @@
 
 static struct usb_charger *dev_to_uchger(struct device *dev)
 {
-   return NULL;
+   struct usb_gadget *gadget = container_of(dev, struct usb_gadget, dev);
+
+   return gadget->charger;
 }
 
 /*
@@ -398,6 +400,18 @@ static int __usb_charger_set_cur_limit_by_type(struct 
usb_charger *uchger,
 int usb_charger_set_cur_limit_by_gadget(struct usb_gadget *gadget,
unsigned int cur_limit)
 {
+   struct usb_charger *uchger = gadget->charger;
+   int ret;
+
+   if (!uchger)
+   return -EINVAL;
+
+   ret = __usb_charger_set_cur_limit_by_type(uchger, uchger->type,
+ cur_limit);
+   if (ret)
+   return ret;
+
+   schedule_work(>work);
return 0;
 }
 EXPORT_SYMBOL_GPL(usb_charger_set_cur_limit_by_gadget);
@@ -622,11 +636,66 @@ static int usb_charger_plug_by_extcon(struct 
notifier_block *nb,
 int usb_charger_plug_by_gadget(struct usb_gadget *gadget,
   unsigned long state)
 {
+   struct usb_charger *uchger = gadget->charger;
+   enum usb_charger_state uchger_state;
+
+   if (WARN(!uchger, "charger can not be NULL"))
+   return -EINVAL;
+
+   /*
+* Report event to power to setting the current limitation
+* for this usb charger when one usb charger state is changed
+* with detecting by usb gadget state.
+*/
+   if (uchger->old_gadget_state != state) {
+   uchger->old_gadget_state = state;
+
+   if (state >= USB_STATE_ATTACHED) {
+   uchger_state = USB_CHARGER_PRESENT;
+   } else if (state == USB_STATE_NOTATTACHED) {
+   mutex_lock(>lock);
+
+   /*
+* Need check the charger type to make sure the usb
+* cable is removed, in case it just changes the usb
+* function with configfs.
+*/
+   if (uchger->type != UNKNOWN_TYPE) {
+   mutex_unlock(>lock);
+   return 0;
+   }
+
+   mutex_unlock(>lock);
+   uchger_state = USB_CHARGER_ABSENT;
+   } else {
+   uchger_state = USB_CHARGER_DEFAULT;
+   }
+
+   usb_charger_notify_state(uchger, uchger_state);
+   }
+
return 0;
 }
 EXPORT_SYMBOL_GPL(usb_charger_plug_by_gadget);
 
 /*
+ * usb_charger_unregister() - Unregister a usb charger.
+ * @uchger - the usb charger to be unregistered.
+ */
+static int usb_charger_unregister(struct usb_charger *uchger)
+{
+   ida_simple_remove(_charger_ida, uchger->id);
+   sysfs_remove_groups(>gadget->dev.kobj, usb_charger_groups);
+   uchger->id = -1;
+
+   mutex_lock(_lock);
+   list_del(>list);
+   mutex_unlock(_lock);
+
+   return 0;
+}
+
+/*
  * usb_charger_register() - Register a new usb charger.
  * @uchger - the new usb charger instance.
  */
@@ -725,6 +794,7 @@ int usb_charger_init(struct usb_gadget *ugadget)
}
 
uchger->gadget = ugadget;
+   ugadget->charger = uchger;
uchger->old_gadget_state = USB_STATE_NOTATTACHED;
 
/* Register a new usb charger */
@@ -762,6 +832,31 @@ int usb_charger_init(struct usb_gadget *ugadget)
 
 int usb_charger_exit(struct usb_gadget *ugadget)
 {
+   struct usb_charger *uchger = ugadget->charger;
+
+   if (!uchger)
+   return -EINVAL;
+
+   usb_charger_unregister(uchger);
+   ugadget->charger = NULL;
+
+   extcon_unregister_notifier(uchger->extcon_dev,
+  EXTCON_USB,
+  >extcon_nb.nb);
+   extcon_unregister_notifier(uchger->extcon_dev,
+  EXTCON_CHG_USB_SDP,
+  >extcon_type_nb.nb);
+   extcon_unregister_notifier(uchger->extcon_dev,
+  EXTCON_CHG_USB_CDP,
+  >extcon_type_nb.nb);
+   extcon_unregister_notifier(uchger->extcon_dev,
+  EXTCON_CHG_USB_DCP,
+  

[PATCH v19 1/4] usb: gadget: Introduce the usb charger framework

2017-02-20 Thread Baolin Wang
This patch introduces the usb charger driver based on usb gadget that
makes an enhancement to a power driver. It works well in practice but
that requires a system with suitable hardware.

The basic conception of the usb charger is that, when one usb charger
is added or removed by reporting from the usb gadget state change or
the extcon device state change, the usb charger will report to power
user to set the current limitation.

The usb charger will register notifiees on the usb gadget or the extcon
device to get notified the usb charger state. It also supplies the
notification mechanism to userspace When the usb charger state is changed.

Power user will register a notifiee on the usb charger to get notified
by status changes from the usb charger. It will report to power user
to set the current limitation when detecting the usb charger is added
or removed from extcon device state or usb gadget state.

This patch doesn't yet integrate with the gadget code, so some functions
which rely on the 'gadget' are not completed, that will be implemented
in the following patches.

Signed-off-by: Baolin Wang 
Reviewed-by: Li Jun 
Tested-by: Li Jun 
---
 drivers/usb/gadget/Kconfig   |8 +
 drivers/usb/gadget/udc/Makefile  |1 +
 drivers/usb/gadget/udc/charger.c |  770 ++
 include/linux/usb/charger.h  |  176 +
 include/uapi/linux/usb/charger.h |   31 ++
 5 files changed, 986 insertions(+)
 create mode 100644 drivers/usb/gadget/udc/charger.c
 create mode 100644 include/linux/usb/charger.h
 create mode 100644 include/uapi/linux/usb/charger.h

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 8ad2032..60d2f29 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -134,6 +134,14 @@ config U_SERIAL_CONSOLE
help
   It supports the serial gadget can be used as a console.
 
+config USB_CHARGER
+   bool "USB charger support"
+   select EXTCON
+   help
+ The usb charger driver based on the usb gadget that makes an
+ enhancement to a power driver which can set the current limitation
+ when the usb charger is added or removed.
+
 source "drivers/usb/gadget/udc/Kconfig"
 
 #
diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile
index 98e74ed..ede2351 100644
--- a/drivers/usb/gadget/udc/Makefile
+++ b/drivers/usb/gadget/udc/Makefile
@@ -2,6 +2,7 @@
 CFLAGS_trace.o := -I$(src)
 
 udc-core-y := core.o trace.o
+udc-core-$(CONFIG_USB_CHARGER) += charger.o
 
 #
 # USB peripheral controller drivers
diff --git a/drivers/usb/gadget/udc/charger.c b/drivers/usb/gadget/udc/charger.c
new file mode 100644
index 000..6d62f54
--- /dev/null
+++ b/drivers/usb/gadget/udc/charger.c
@@ -0,0 +1,770 @@
+/*
+ * charger.c -- USB charger driver
+ *
+ * Copyright (C) 2016 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Default current range by charger type. */
+#define DEFAULT_SDP_CUR_MIN2
+#define DEFAULT_SDP_CUR_MAX500
+#define DEFAULT_SDP_CUR_MIN_SS 150
+#define DEFAULT_SDP_CUR_MAX_SS 900
+#define DEFAULT_DCP_CUR_MIN500
+#define DEFAULT_DCP_CUR_MAX5000
+#define DEFAULT_CDP_CUR_MIN1500
+#define DEFAULT_CDP_CUR_MAX5000
+#define DEFAULT_ACA_CUR_MIN1500
+#define DEFAULT_ACA_CUR_MAX5000
+
+static DEFINE_IDA(usb_charger_ida);
+static LIST_HEAD(charger_list);
+static DEFINE_MUTEX(charger_lock);
+
+static struct usb_charger *dev_to_uchger(struct device *dev)
+{
+   return NULL;
+}
+
+/*
+ * charger_current_show() - Show the charger current.
+ */
+static ssize_t charger_current_show(struct device *dev,
+   struct device_attribute *attr,
+   char *buf)
+{
+   struct usb_charger *uchger = dev_to_uchger(dev);
+   unsigned int min, max;
+
+   usb_charger_get_current(uchger, , );
+   return sprintf(buf, "%u-%u\n", min, max);
+}
+static DEVICE_ATTR_RO(charger_current);
+
+/*
+ * charger_type_show() - Show the charger type.
+ *
+ * It can be SDP/DCP/CDP/ACA type, else for unknown type.
+ */
+static ssize_t charger_type_show(struct device *dev,
+struct device_attribute *attr,
+char *buf)
+{
+   struct usb_charger *uchger = dev_to_uchger(dev);
+   enum usb_charger_type type = usb_charger_get_type(uchger);
+   int cnt;
+
+   switch (type) {
+   case SDP_TYPE:
+   cnt = sprintf(buf, "%s\n", "SDP");
+   break;
+   case DCP_TYPE:
+   cnt = sprintf(buf, "%s\n", "DCP");
+   

RE: [PATCH v4 3/3] USB3/DWC3: Enable undefined length INCR burst type

2017-02-20 Thread Jerry Huang
> -Original Message-
> From: Jerry Huang
> Sent: Friday, February 10, 2017 11:30 PM
> To: 'Felipe Balbi' ; robh...@kernel.org;
> mark.rutl...@arm.com; catalin.mari...@arm.com
> Cc: linux-usb@vger.kernel.org; linux-ker...@vger.kernel.org;
> devicet...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; Rajesh
> Bhagat 
> Subject: RE: [PATCH v4 3/3] USB3/DWC3: Enable undefined length INCR burst
> type
> 
> > >> --
> > >> 1.7.9.5
> > > Hi, Balbi and all guys,
> > > Any comment for these patches? Can they be accepted?
> >
> > Rob had comments which you didn't reply yet. I cannot take this
> > patchset yet ;-)
> >
> Balbi,
> I look into his mail again, which was based v3, and I replied it.
> He had different understanding for undefined length burst mode.
> It seems he think for this mode, just setting bit[0] (INCRBrstEna) and don't
> need to set other field.
> However, according to the DWC USB3.0 controller databook, when it is
> undefined length INCR burst mode, we still need to set one max burst type,
> such as INCR8, which means controller will use any length less than or equal
> to this INCR8.
Any comment for it? Ten days passed away again :)
--
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