Re: [PATCH 1/2] usb: dwc2: Fix DMA alignment to start at allocated boundary

2018-07-07 Thread Antti Seppälä
On 6 July 2018 at 18:57, Doug Anderson  wrote:
> Hi,
>
> Thanks for tracking this down and sorry for the original regression.
> Seems like a good fix.  With this fix, I'd be curious of your
> observations on how dwc2 performs (both performance and compatibility
> under stress) with the newest driver compared to whatever you were
> using before.
>

My totally not scientifically accurate performance test included
running iperf through my LTE dongle that was connected to dwc2. I saw
throughput increase in download speeds.

Before (kernel 4.9.109 with the offending commit reverted) iperf
reported download bandwidth at 33.2 Mbits/sec

Using newest dwc2 driver after applying "Fix DMA alignment to start at
allocated boundary" patch I got 38.2 Mbits/sec

If I also apply the "Fix inefficient copy of unaligned buffers" patch
I could achieve a total throughput for download around 44.6 Mbits/sec
which I believe is capped by my 50Mbit/s subscription.

> Also: you're using the dwc2_set_ltq_params() parameters?  Have you
> checked if removing the "max_transfer_size" limit boosts your
> performance?
>

Yes, I'm using the parameters set there. I tried removing
max_transfer_size but it did not have noticeable impact on the
performance in my tests.

> Cc: sta...@vger.kernel.org
> Reviewed-by: Douglas Anderson 

Thanks for reviewing :)

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


[PATCH 0/2] usb: dwc2: DMA alignment fixes

2018-07-05 Thread Antti Seppälä
Here are two patches that improve DMA alignment handling of the dwc2
driver significantly.

The first one ("usb: dwc2: Fix DMA alignment to start at allocated
boundary") fixes an actual crash regression on some platforms introduced
by commit 3bc04e28a030 ("usb: dwc2: host: Get aligned DMA in a more
supported way") and should be considered for inclusion in stable kernel
release.

The second patch ("usb: dwc2: Fix inefficient copy of unaligned
buffers") is a port of an optimization found from similar drivers to
dwc2. In my tests it offered a significant performance improvement in
certain use cases. Since it touches the same area that I was already
modifying I decided to split it into separate patch and include in the
series.

Antti Seppälä (2):
  usb: dwc2: Fix DMA alignment to start at allocated boundary
  usb: dwc2: Fix inefficient copy of unaligned buffers

 drivers/usb/dwc2/hcd.c | 54 +-
 1 file changed, 31 insertions(+), 23 deletions(-)

-- 
2.13.6

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


[PATCH 1/2] usb: dwc2: Fix DMA alignment to start at allocated boundary

2018-07-05 Thread Antti Seppälä
The commit 3bc04e28a030 ("usb: dwc2: host: Get aligned DMA in a more
supported way") introduced a common way to align DMA allocations.
The code in the commit aligns the struct dma_aligned_buffer but the
actual DMA address pointed by data[0] gets aligned to an offset from
the allocated boundary by the kmalloc_ptr and the old_xfer_buffer
pointers.

This is against the recommendation in Documentation/DMA-API.txt which
states:

  Therefore, it is recommended that driver writers who don't take
  special care to determine the cache line size at run time only map
  virtual regions that begin and end on page boundaries (which are
  guaranteed also to be cache line boundaries).

The effect of this is that architectures with non-coherent DMA caches
may run into memory corruption or kernel crashes with Unhandled
kernel unaligned accesses exceptions.

Fix the alignment by positioning the DMA area in front of the allocation
and use memory at the end of the area for storing the orginal
transfer_buffer pointer. This may have the added benefit of increased
performance as the DMA area is now fully aligned on all architectures.

Tested with Lantiq xRX200 (MIPS) and RPi Model B Rev 2 (ARM).

Fixes: 3bc04e28a030 ("usb: dwc2: host: Get aligned DMA in a more
supported way")

Signed-off-by: Antti Seppälä 
---
 drivers/usb/dwc2/hcd.c | 44 +++-
 1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index b1104be3429c..2ed0ac18e053 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -2665,34 +2665,29 @@ static int dwc2_alloc_split_dma_aligned_buf(struct 
dwc2_hsotg *hsotg,
 
 #define DWC2_USB_DMA_ALIGN 4
 
-struct dma_aligned_buffer {
-   void *kmalloc_ptr;
-   void *old_xfer_buffer;
-   u8 data[0];
-};
-
 static void dwc2_free_dma_aligned_buffer(struct urb *urb)
 {
-   struct dma_aligned_buffer *temp;
+   void *stored_xfer_buffer;
 
if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
return;
 
-   temp = container_of(urb->transfer_buffer,
-   struct dma_aligned_buffer, data);
+   /* Restore urb->transfer_buffer from the end of the allocated area */
+   memcpy(_xfer_buffer, urb->transfer_buffer +
+  urb->transfer_buffer_length, sizeof(urb->transfer_buffer));
 
if (usb_urb_dir_in(urb))
-   memcpy(temp->old_xfer_buffer, temp->data,
+   memcpy(stored_xfer_buffer, urb->transfer_buffer,
   urb->transfer_buffer_length);
-   urb->transfer_buffer = temp->old_xfer_buffer;
-   kfree(temp->kmalloc_ptr);
+   kfree(urb->transfer_buffer);
+   urb->transfer_buffer = stored_xfer_buffer;
 
urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
 }
 
 static int dwc2_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
 {
-   struct dma_aligned_buffer *temp, *kmalloc_ptr;
+   void *kmalloc_ptr;
size_t kmalloc_size;
 
if (urb->num_sgs || urb->sg ||
@@ -2700,22 +2695,29 @@ static int dwc2_alloc_dma_aligned_buffer(struct urb 
*urb, gfp_t mem_flags)
!((uintptr_t)urb->transfer_buffer & (DWC2_USB_DMA_ALIGN - 1)))
return 0;
 
-   /* Allocate a buffer with enough padding for alignment */
+   /*
+* Allocate a buffer with enough padding for original transfer_buffer
+* pointer. This allocation is guaranteed to be aligned properly for
+* DMA
+*/
kmalloc_size = urb->transfer_buffer_length +
-   sizeof(struct dma_aligned_buffer) + DWC2_USB_DMA_ALIGN - 1;
+   sizeof(urb->transfer_buffer);
 
kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
if (!kmalloc_ptr)
return -ENOMEM;
 
-   /* Position our struct dma_aligned_buffer such that data is aligned */
-   temp = PTR_ALIGN(kmalloc_ptr + 1, DWC2_USB_DMA_ALIGN) - 1;
-   temp->kmalloc_ptr = kmalloc_ptr;
-   temp->old_xfer_buffer = urb->transfer_buffer;
+   /*
+* Position value of original urb->transfer_buffer pointer to the end
+* of allocation for later referencing
+*/
+   memcpy(kmalloc_ptr + urb->transfer_buffer_length,
+  >transfer_buffer, sizeof(urb->transfer_buffer));
+
if (usb_urb_dir_out(urb))
-   memcpy(temp->data, urb->transfer_buffer,
+   memcpy(kmalloc_ptr, urb->transfer_buffer,
   urb->transfer_buffer_length);
-   urb->transfer_buffer = temp->data;
+   urb->transfer_buffer = kmalloc_ptr;
 
urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER;
 
-- 
2.13.6

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


[PATCH 2/2] usb: dwc2: Fix inefficient copy of unaligned buffers

2018-07-05 Thread Antti Seppälä
Make sure only to copy any actual data rather than the whole buffer,
when releasing the temporary buffer used for unaligned non-isochronous
transfers.

Taken directly from commit 0efd937e27d5e ("USB: ehci-tegra: fix inefficient
copy of unaligned buffers")

Tested with Lantiq xRX200 (MIPS) and RPi Model B Rev 2 (ARM)

Signed-off-by: Antti Seppälä 
---
 drivers/usb/dwc2/hcd.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 2ed0ac18e053..6e2cdd7b93d4 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -2668,6 +2668,7 @@ static int dwc2_alloc_split_dma_aligned_buf(struct 
dwc2_hsotg *hsotg,
 static void dwc2_free_dma_aligned_buffer(struct urb *urb)
 {
void *stored_xfer_buffer;
+   size_t length;
 
if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
return;
@@ -2676,9 +2677,14 @@ static void dwc2_free_dma_aligned_buffer(struct urb *urb)
memcpy(_xfer_buffer, urb->transfer_buffer +
   urb->transfer_buffer_length, sizeof(urb->transfer_buffer));
 
-   if (usb_urb_dir_in(urb))
-   memcpy(stored_xfer_buffer, urb->transfer_buffer,
-  urb->transfer_buffer_length);
+   if (usb_urb_dir_in(urb)) {
+   if (usb_pipeisoc(urb->pipe))
+   length = urb->transfer_buffer_length;
+   else
+   length = urb->actual_length;
+
+   memcpy(stored_xfer_buffer, urb->transfer_buffer, length);
+   }
kfree(urb->transfer_buffer);
urb->transfer_buffer = stored_xfer_buffer;
 
-- 
2.13.6

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


Re: usb: dwc2: crash regression in commit 3bc04e28a030 (bisected)

2018-07-03 Thread Antti Seppälä
On 3 July 2018 at 09:56, Doug Anderson  wrote:
> Hi,
>
> On Sun, Jul 1, 2018 at 11:30 PM, Antti Seppälä  wrote:
>> On 30 June 2018 at 02:57, Doug Anderson  wrote:
>>> Hi,
>>>
>>> On Fri, Jun 29, 2018 at 11:29 AM, Antti Seppälä  wrote:
>>>> Hi Doug, John and linux-usb.
>>>>
>>>> I'd like to report a regression in commit 3bc04e28a030 (usb: dwc2:
>>>> host: Get aligned DMA in a more supported way)
>>>
>>> Seems unlikely, but any chance that
>>> <https://patchwork.kernel.org/patch/10393775/> helps you?
>>>
>>
>> Thank you for your suggestion but unfortunately the patch does not
>> help and the crash remains.
>
> A few more shots in the dark in case they help:
>
> 1. For the kmalloc() in dwc2_alloc_dma_aligned_buffer(), change from:
>
> kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
>
> to:
>
> kmalloc_ptr = kmalloc(kmalloc_size, mem_flags | GFP_DMA);
>
>
> The old code used to hardcode this, so maybe it somehow makes a difference?
>

I tried this but it did not have any effect on the crash.

> ---
>
> 2. Change DWC2_USB_DMA_ALIGN to a larger size.  Maybe 32 or 64?
>

I tried these values too but they did not help. It seems to me that
these change the alignment of the start of the struct
dma_aligned_buffer but since the issue is with the alignment of ->data
inside that struct it is always moved to an unaligned location (offset
by the two pointers at the start of the struct).

There is even a mention of this requirement in Documentation/DMA-API.txt:

  Memory coherency operates at a granularity called the cache
  line width.  In order for memory mapped by this API to operate
  correctly, the mapped region must begin exactly on a cache line
  boundary and end exactly on one (to prevent two separately mapped
  regions from sharing a single cache line).  Since the cache line size
  may not be known at compile time, the API will not enforce this
  requirement.  Therefore, it is recommended that driver writers who
  don't take special care to determine the cache line size at run time
  only map virtual regions that begin and end on page boundaries (which
  are guaranteed also to be cache line boundaries).


> ---
>
> 3. Undo just the part of the patch that removed:
>
> /*
>  * Clip max_transfer_size to 65535. dwc2_hc_setup_align_buf() allocates
>  * coherent buffers with this size, and if it's too large we can
>  * exhaust the coherent DMA pool.
>  */
> if (hw->max_transfer_size > 65535)
>   hw->max_transfer_size = 65535;
>
> Maybe there's something on your platform where you have a problem with
> big transfers?
>

I tried adding back this one as well but unfortunately no help from that either.

Then I wrote a proof-of-concept patch that really solves the issue for me.

The patch allocates additional space at the end of that temp bounce
buffer and stores the original value of urb->transfer_buffer there for
keeping until it is needed again.

This way the bounce buffer for DMA is aligned on a page boundary that
is compliant from DMA-API.txt perspective.

Any thoughts or comments? If the patch doesn't look too crazy I can
send it properly with git.

-- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -2606,34 +2606,28 @@

 #define DWC2_USB_DMA_ALIGN 4

-struct dma_aligned_buffer {
-void *kmalloc_ptr;
-void *old_xfer_buffer;
-u8 data[0];
-};
-
 static void dwc2_free_dma_aligned_buffer(struct urb *urb)
 {
-struct dma_aligned_buffer *temp;
+void *stored_xfer_buffer;

 if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
 return;

-temp = container_of(urb->transfer_buffer,
-struct dma_aligned_buffer, data);
+memcpy(_xfer_buffer, urb->transfer_buffer +
+urb->transfer_buffer_length, sizeof(void *));

 if (usb_urb_dir_in(urb))
-memcpy(temp->old_xfer_buffer, temp->data,
+memcpy(stored_xfer_buffer, urb->transfer_buffer,
urb->transfer_buffer_length);
-urb->transfer_buffer = temp->old_xfer_buffer;
-kfree(temp->kmalloc_ptr);
+kfree(urb->transfer_buffer);
+urb->transfer_buffer = stored_xfer_buffer;

 urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
 }

 static int dwc2_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
 {
-struct dma_aligned_buffer *temp, *kmalloc_ptr;
+void *kmalloc_ptr;
 size_t kmalloc_size;

 if (urb->num_sgs || urb->sg ||
@@ -2641,22 +2635,21 @@
 !((uintptr_t)urb->transfer_buffer & (DWC2_USB_DMA_ALIGN - 1)))
 return 0;

-/* Allocate a buffer with enough padding for alignment */
-  

Re: usb: dwc2: crash regression in commit 3bc04e28a030 (bisected)

2018-07-02 Thread Antti Seppälä
On 30 June 2018 at 02:57, Doug Anderson  wrote:
> Hi,
>
> On Fri, Jun 29, 2018 at 11:29 AM, Antti Seppälä  wrote:
>> Hi Doug, John and linux-usb.
>>
>> I'd like to report a regression in commit 3bc04e28a030 (usb: dwc2:
>> host: Get aligned DMA in a more supported way)
>
> Seems unlikely, but any chance that
> <https://patchwork.kernel.org/patch/10393775/> helps you?
>

Thank you for your suggestion but unfortunately the patch does not
help and the crash remains.

>
>> Apparently the patch does something nasty that the Lantiq platform
>> really does not like as whenever I plug my usb 3g modem into the usb
>> port of my BT HomeHub v5 (Lantiq XRX200) I get a kernel
>> oops/crash/panic with usually quite a weird content that looks like
>> some sort of memory corruption.
>>
>> I've bisected the crash and reverting 3bc04e28a030 allows the 3g-modem
>> to be plugged and the kernel does not crash.
>>
>> Below is the console log when I plug the modem in. I used stable
>> vanilla kernel 4.9.109 from OpenWrt during my tests with dwc2 debug
>> prints enabled:
>>
>> root@lantiq:/# echo -n "module dwc2 +p" >
>> /sys/kernel/debug/dynamic_debug/control
>> [   92.563454] dwc2 1e101000.ifxhcd: gintsts=0521  gintmsk=f3000806
>> [   92.568762] dwc2 1e101000.ifxhcd: DWC OTG HCD HUB STATUS DATA: Root
>> port status changed
>> [   92.576447] dwc2 1e101000.ifxhcd:   port_connect_status_change: 1
>> [   92.582523] dwc2 1e101000.ifxhcd:   port_reset_change: 0
>> [   92.587830] dwc2 1e101000.ifxhcd:   port_enable_change: 0
>> [   92.593228] dwc2 1e101000.ifxhcd:   port_suspend_change: 0
>> [   92.598710] dwc2 1e101000.ifxhcd:   port_over_current_change: 0
>> [   92.607242] dwc2 1e101000.ifxhcd: ClearPortFeature 
>> USB_PORT_FEAT_C_CONNECTION
>> [   92.758240] dwc2 1e101000.ifxhcd: SetPortFeature
>> [   92.761535] dwc2 1e101000.ifxhcd: SetPortFeature - USB_PORT_FEAT_RESET
>> [   92.768063] dwc2 1e101000.ifxhcd: In host mode, hprt0=00021501
>> [   92.841013] dwc2 1e101000.ifxhcd: gintsts=0529  gintmsk=f3000806
>> [   92.905329] dwc2 1e101000.ifxhcd: ClearPortFeature USB_PORT_FEAT_C_RESET
>> [   92.968536] usb 1-1: new high-speed USB device number 2 using dwc2
>> [   92.975029] dwc2 1e101000.ifxhcd: SetPortFeature
>> [   92.978358] dwc2 1e101000.ifxhcd: SetPortFeature - USB_PORT_FEAT_RESET
>> [   92.984837] dwc2 1e101000.ifxhcd: In host mode, hprt0=1101
>> [   92.990674] dwc2 1e101000.ifxhcd: gintsts=0529  gintmsk=f3000806
>> [   93.060349] dwc2 1e101000.ifxhcd: DWC OTG HCD HUB STATUS DATA: Root
>> port status changed
>> [   93.067020] dwc2 1e101000.ifxhcd:   port_connect_status_change: 0
>> [   93.073099] dwc2 1e101000.ifxhcd:   port_reset_change: 0
>> [   93.078375] dwc2 1e101000.ifxhcd:   port_enable_change: 1
>> [   93.083766] dwc2 1e101000.ifxhcd:   port_suspend_change: 0
>> [   93.089252] dwc2 1e101000.ifxhcd:   port_over_current_change: 0
>> [   93.096284] dwc2 1e101000.ifxhcd: gintsts=0529  gintmsk=f3000806
>> [   93.152672] dwc2 1e101000.ifxhcd: ClearPortFeature USB_PORT_FEAT_C_RESET
>> [   93.216952] dwc2 1e101000.ifxhcd: DWC OTG HCD EP DISABLE:
>> bEndpointAddress=0x00, ep->hcpriv=86e4fa00
>> [   93.224792] dwc2 1e101000.ifxhcd: DWC OTG HCD EP DISABLE:
>> bEndpointAddress=0x00, ep->hcpriv=  (null)
>> [   93.233926] dwc2 1e101000.ifxhcd: DWC OTG HCD EP RESET: 
>> bEndpointAddress=0x00
>> [   93.268547] dwc2 1e101000.ifxhcd: DWC OTG HCD EP RESET: 
>> bEndpointAddress=0x81
>> [   93.274399] dwc2 1e101000.ifxhcd: DWC OTG HCD EP RESET: 
>> bEndpointAddress=0x01
>> [   93.307463] usb-storage 1-1:1.0: USB Mass Storage device detected
>> [   93.312238] dwc2 1e101000.ifxhcd: DWC OTG HCD HUB STATUS DATA: Root
>> port status changed
>> [   93.312256] dwc2 1e101000.ifxhcd:   port_connect_status_change: 0
>> [   93.312270] dwc2 1e101000.ifxhcd:   port_reset_change: 0
>> [   93.312329] dwc2 1e101000.ifxhcd:   port_enable_change: 1
>> [   93.312342] dwc2 1e101000.ifxhcd:   port_suspend_change: 0
>> [   93.312356] dwc2 1e101000.ifxhcd:   port_over_current_change: 0
>> [   93.408514] scsi host0: usb-storage 1-1:1.0
>> [   93.437010] dwc2 1e101000.ifxhcd: ClearPortFeature USB_PORT_FEAT_C_ENABLE
>> [   94.152597] dwc2 1e101000.ifxhcd: DWC OTG HCD EP RESET: 
>> bEndpointAddress=0x01
>> [   94.166421] dwc2 1e101000.ifxhcd: gintsts=2529  gintmsk=f3000806
>> [   94.171336] dwc2 1e101000.ifxhcd: ++Disconnect Detected Interrupt++
>> (Host) a_host
>> [   94.180561] dwc2 1e101000.ifxhcd: DWC OTG HCD EP RESET: 
>> bEndpointAddress=0x01
&g

usb: dwc2: crash regression in commit 3bc04e28a030 (bisected)

2018-06-29 Thread Antti Seppälä
Hi Doug, John and linux-usb.

I'd like to report a regression in commit 3bc04e28a030 (usb: dwc2:
host: Get aligned DMA in a more supported way)

Apparently the patch does something nasty that the Lantiq platform
really does not like as whenever I plug my usb 3g modem into the usb
port of my BT HomeHub v5 (Lantiq XRX200) I get a kernel
oops/crash/panic with usually quite a weird content that looks like
some sort of memory corruption.

I've bisected the crash and reverting 3bc04e28a030 allows the 3g-modem
to be plugged and the kernel does not crash.

Below is the console log when I plug the modem in. I used stable
vanilla kernel 4.9.109 from OpenWrt during my tests with dwc2 debug
prints enabled:

root@lantiq:/# echo -n "module dwc2 +p" >
/sys/kernel/debug/dynamic_debug/control
[   92.563454] dwc2 1e101000.ifxhcd: gintsts=0521  gintmsk=f3000806
[   92.568762] dwc2 1e101000.ifxhcd: DWC OTG HCD HUB STATUS DATA: Root
port status changed
[   92.576447] dwc2 1e101000.ifxhcd:   port_connect_status_change: 1
[   92.582523] dwc2 1e101000.ifxhcd:   port_reset_change: 0
[   92.587830] dwc2 1e101000.ifxhcd:   port_enable_change: 0
[   92.593228] dwc2 1e101000.ifxhcd:   port_suspend_change: 0
[   92.598710] dwc2 1e101000.ifxhcd:   port_over_current_change: 0
[   92.607242] dwc2 1e101000.ifxhcd: ClearPortFeature USB_PORT_FEAT_C_CONNECTION
[   92.758240] dwc2 1e101000.ifxhcd: SetPortFeature
[   92.761535] dwc2 1e101000.ifxhcd: SetPortFeature - USB_PORT_FEAT_RESET
[   92.768063] dwc2 1e101000.ifxhcd: In host mode, hprt0=00021501
[   92.841013] dwc2 1e101000.ifxhcd: gintsts=0529  gintmsk=f3000806
[   92.905329] dwc2 1e101000.ifxhcd: ClearPortFeature USB_PORT_FEAT_C_RESET
[   92.968536] usb 1-1: new high-speed USB device number 2 using dwc2
[   92.975029] dwc2 1e101000.ifxhcd: SetPortFeature
[   92.978358] dwc2 1e101000.ifxhcd: SetPortFeature - USB_PORT_FEAT_RESET
[   92.984837] dwc2 1e101000.ifxhcd: In host mode, hprt0=1101
[   92.990674] dwc2 1e101000.ifxhcd: gintsts=0529  gintmsk=f3000806
[   93.060349] dwc2 1e101000.ifxhcd: DWC OTG HCD HUB STATUS DATA: Root
port status changed
[   93.067020] dwc2 1e101000.ifxhcd:   port_connect_status_change: 0
[   93.073099] dwc2 1e101000.ifxhcd:   port_reset_change: 0
[   93.078375] dwc2 1e101000.ifxhcd:   port_enable_change: 1
[   93.083766] dwc2 1e101000.ifxhcd:   port_suspend_change: 0
[   93.089252] dwc2 1e101000.ifxhcd:   port_over_current_change: 0
[   93.096284] dwc2 1e101000.ifxhcd: gintsts=0529  gintmsk=f3000806
[   93.152672] dwc2 1e101000.ifxhcd: ClearPortFeature USB_PORT_FEAT_C_RESET
[   93.216952] dwc2 1e101000.ifxhcd: DWC OTG HCD EP DISABLE:
bEndpointAddress=0x00, ep->hcpriv=86e4fa00
[   93.224792] dwc2 1e101000.ifxhcd: DWC OTG HCD EP DISABLE:
bEndpointAddress=0x00, ep->hcpriv=  (null)
[   93.233926] dwc2 1e101000.ifxhcd: DWC OTG HCD EP RESET: bEndpointAddress=0x00
[   93.268547] dwc2 1e101000.ifxhcd: DWC OTG HCD EP RESET: bEndpointAddress=0x81
[   93.274399] dwc2 1e101000.ifxhcd: DWC OTG HCD EP RESET: bEndpointAddress=0x01
[   93.307463] usb-storage 1-1:1.0: USB Mass Storage device detected
[   93.312238] dwc2 1e101000.ifxhcd: DWC OTG HCD HUB STATUS DATA: Root
port status changed
[   93.312256] dwc2 1e101000.ifxhcd:   port_connect_status_change: 0
[   93.312270] dwc2 1e101000.ifxhcd:   port_reset_change: 0
[   93.312329] dwc2 1e101000.ifxhcd:   port_enable_change: 1
[   93.312342] dwc2 1e101000.ifxhcd:   port_suspend_change: 0
[   93.312356] dwc2 1e101000.ifxhcd:   port_over_current_change: 0
[   93.408514] scsi host0: usb-storage 1-1:1.0
[   93.437010] dwc2 1e101000.ifxhcd: ClearPortFeature USB_PORT_FEAT_C_ENABLE
[   94.152597] dwc2 1e101000.ifxhcd: DWC OTG HCD EP RESET: bEndpointAddress=0x01
[   94.166421] dwc2 1e101000.ifxhcd: gintsts=2529  gintmsk=f3000806
[   94.171336] dwc2 1e101000.ifxhcd: ++Disconnect Detected Interrupt++
(Host) a_host
[   94.180561] dwc2 1e101000.ifxhcd: DWC OTG HCD EP RESET: bEndpointAddress=0x01
[   94.186473] dwc2 1e101000.ifxhcd: Not connected
[   94.300415] dwc2 1e101000.ifxhcd: DWC OTG HCD HUB STATUS DATA: Root
port status changed
[   94.307074] dwc2 1e101000.ifxhcd:   port_connect_status_change: 1
[   94.313203] dwc2 1e101000.ifxhcd:   port_reset_change: 0
[   94.318467] dwc2 1e101000.ifxhcd:   port_enable_change: 1
[   94.323858] dwc2 1e101000.ifxhcd:   port_suspend_change: 0
[   94.329344] dwc2 1e101000.ifxhcd:   port_over_current_change: 0
[   94.336998] dwc2 1e101000.ifxhcd: ClearPortFeature USB_PORT_FEAT_C_CONNECTION
[   94.343368] dwc2 1e101000.ifxhcd: ClearPortFeature USB_PORT_FEAT_C_ENABLE
[   94.350145] usb 1-1: USB disconnect, device number 2
[   94.365605] dwc2 1e101000.ifxhcd: DWC OTG HCD EP DISABLE:
bEndpointAddress=0x00, ep->hcpriv=86e4f980
[   94.373454] dwc2 1e101000.ifxhcd: DWC OTG HCD EP DISABLE:
bEndpointAddress=0x00, ep->hcpriv=  (null)
[   94.382555] dwc2 1e101000.ifxhcd: DWC OTG HCD EP DISABLE:
bEndpointAddress=0x01, ep->hcpriv=86e61400
[   94.391728] dwc2 1e101000.ifxhcd: DWC OTG HCD EP 

[PATCH] usb: dwc2: Add support for Lantiq ARX and XRX SoCs

2016-02-27 Thread Antti Seppälä
Add support for Lantiq ARX and XRX SoC families to the dwc2 driver.

Signed-off-by: Antti Seppälä <a.sepp...@gmail.com>
---
 Documentation/devicetree/bindings/usb/dwc2.txt |  2 ++
 drivers/usb/dwc2/platform.c| 34 ++
 2 files changed, 36 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt 
b/Documentation/devicetree/bindings/usb/dwc2.txt
index 2213682..20a68bf 100644
--- a/Documentation/devicetree/bindings/usb/dwc2.txt
+++ b/Documentation/devicetree/bindings/usb/dwc2.txt
@@ -8,6 +8,8 @@ Required properties:
   - rockchip,rk3066-usb: The DWC2 USB controller instance in the rk3066 Soc;
   - "rockchip,rk3188-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3188 Soc;
   - "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2": for rk3288 Soc;
+  - "lantiq,arx100-usb": The DWC2 USB controller instance in Lantiq ARX SoCs;
+  - "lantiq,xrx200-usb": The DWC2 USB controller instance in Lantiq XRX SoCs;
   - snps,dwc2: A generic DWC2 USB controller with default parameters.
 - reg : Should contain 1 register range (address and length)
 - interrupts : Should contain 1 interrupt
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 690b9fd..0e9e4d3 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -149,6 +149,38 @@ static const struct dwc2_core_params params_rk3066 = {
.hibernation= -1,
 };
 
+static const struct dwc2_core_params params_ltq = {
+   .otg_cap= 2,/* non-HNP/non-SRP */
+   .otg_ver= -1,
+   .dma_enable = -1,
+   .dma_desc_enable= -1,
+   .dma_desc_fs_enable = -1,
+   .speed  = -1,
+   .enable_dynamic_fifo= -1,
+   .en_multiple_tx_fifo= -1,
+   .host_rx_fifo_size  = 288,  /* 288 DWORDs */
+   .host_nperio_tx_fifo_size   = 128,  /* 128 DWORDs */
+   .host_perio_tx_fifo_size= 96,   /* 96 DWORDs */
+   .max_transfer_size  = 65535,
+   .max_packet_count   = 511,
+   .host_channels  = -1,
+   .phy_type   = -1,
+   .phy_utmi_width = -1,
+   .phy_ulpi_ddr   = -1,
+   .phy_ulpi_ext_vbus  = -1,
+   .i2c_enable = -1,
+   .ulpi_fs_ls = -1,
+   .host_support_fs_ls_low_power   = -1,
+   .host_ls_low_power_phy_clk  = -1,
+   .ts_dline   = -1,
+   .reload_ctl = -1,
+   .ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
+ GAHBCFG_HBSTLEN_SHIFT,
+   .uframe_sched   = -1,
+   .external_id_pin_ctl= -1,
+   .hibernation= -1,
+};
+
 /*
  * Check the dr_mode against the module configuration and hardware
  * capabilities.
@@ -428,6 +460,8 @@ static const struct of_device_id dwc2_of_match_table[] = {
{ .compatible = "brcm,bcm2835-usb", .data = _bcm2835 },
{ .compatible = "hisilicon,hi6220-usb", .data = _hi6220 },
{ .compatible = "rockchip,rk3066-usb", .data = _rk3066 },
+   { .compatible = "lantiq,arx100-usb", .data = _ltq },
+   { .compatible = "lantiq,xrx200-usb", .data = _ltq },
{ .compatible = "snps,dwc2", .data = NULL },
{ .compatible = "samsung,s3c6400-hsotg", .data = NULL},
{},
-- 
2.4.10

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


Re: [PATCH v3 2/2] usb: dwc2: host: Clear interrupts before handling them

2015-11-19 Thread Antti Seppälä
On 19 November 2015 at 21:45, Douglas Anderson  wrote:
> In general it is wise to clear interrupts before processing them.  If
> you don't do that, you can get:
>  1. Interrupt happens
>  2. You look at system state and process interrupt
>  3. A new interrupt happens
>  4. You clear interrupt without processing it.
>
> This patch was actually a first attempt to fix missing device insertions
> as described in (usb: dwc2: host: Fix missing device insertions) and it
> did solve some of the signal bouncing problems but not all of
> them (which is why I submitted the other patch).  Specifically, this
> patch itself would sometimes change:
>  1. hardware sees connect
>  2. hardware sees disconnect
>  3. hardware sees connect
>  4. dwc2_port_intr() - clears connect interrupt
>  5. dwc2_handle_common_intr() - calls dwc2_hcd_disconnect()
>
> ...to:
>  1. hardware sees connect
>  2. hardware sees disconnect
>  3. dwc2_port_intr() - clears connect interrupt
>  4. hardware sees connect
>  5. dwc2_handle_common_intr() - calls dwc2_hcd_disconnect()
>
> ...but with different timing then sometimes we'd still miss cable
> insertions.
>
> In any case, though this patch doesn't fix any (known) problems, it
> still seems wise as a general policy to clear interrupt before handling
> them.
>
> Signed-off-by: Douglas Anderson 
> Acked-by: John Youn 
> Tested-by: John Youn 
> ---
> Changes in v3:
> - Don't (uselessly) clear the PRTINT anymore (Felipe Balbi).
>
> Changes in v2: None
>

Hi.

It seems that towards the end of hcd_intr.c you seem to be switching a
few calls of dwc2_writel() to plain writel(). It looks like something
that is easily overlooked but please always use dwc2_writel to
preserve correct register endianness on big-endian platforms.

Br,
-- 
Antti
--
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 v3] usb: dwc2: add support for big-endian Lantiq SoCs

2015-08-20 Thread Antti Seppälä
Here is a patch which makes it possible to support mips based big-endian 
SoCs made by Lantiq in the dwc2 driver.

The patch converts the readl/writel io-accessors of dwc2 to big-endian 
friendly versions and was discussed on the linux-usb ml
already earlier [1].

The patch has been included in OpenWrt for some time now and it would be 
nice to get some more exposure to it. It was also agreed that this patch 
would be redone once certain other patches have been applied to dwc2 [2].

As dust has probably settled enough here is the patch again, rebased to 
the latest usb-next tree.

I've also dropped the dwc2 core parameters patch for Lantiq from this 
series for now as finding the right parameters is still a bit of a work 
in progress.

[1] http://www.spinics.net/lists/linux-usb/msg122814.html
[2] http://www.spinics.net/lists/linux-usb/msg122897.html

Antti Seppälä (1):
  usb: dwc2: Use platform endianness when accessing registers

 drivers/usb/dwc2/core.c  | 469 ++-
 drivers/usb/dwc2/core.h  |  28 ++-
 drivers/usb/dwc2/core_intr.c |  73 +++
 drivers/usb/dwc2/debugfs.c   |  52 ++---
 drivers/usb/dwc2/gadget.c| 314 ++---
 drivers/usb/dwc2/hcd.c   | 140 ++---
 drivers/usb/dwc2/hcd.h   |  15 +-
 drivers/usb/dwc2/hcd_ddma.c  |  10 +-
 drivers/usb/dwc2/hcd_intr.c  |  82 
 drivers/usb/dwc2/hcd_queue.c |  10 +-
 10 files changed, 606 insertions(+), 587 deletions(-)

-- 
2.4.6

--
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 v3] usb: dwc2: Use platform endianness when accessing registers

2015-08-20 Thread Antti Seppälä
This patch switches calls to readl/writel to their
dwc2_readl/dwc2_writel equivalents which preserve platform endianness.

This patch is necessary to access dwc2 registers correctly on big-endian
systems such as the mips based SoCs made by Lantiq. Then dwc2 can be
used to replace ifx-hcd driver for Lantiq platforms found e.g. in
OpenWrt.

The patch was autogenerated with the following commands:
$EDITOR core.h
sed -i s/\readl\/dwc2_readl/g *.c hcd.h hw.h
sed -i s/\writel\/dwc2_writel/g *.c hcd.h hw.h

Some files were then hand-edited to fix checkpatch.pl warnings about
too long lines.

Signed-off-by: Antti Seppälä a.sepp...@gmail.com
Signed-off-by: Vincent Pelletier plr.vinc...@gmail.com
---

Notes:
Changes in v2:
 - Fixed wrong comment style

Changes in v3
 - Rebased against latest linux-next
 - Tweaked indentation in some files

 drivers/usb/dwc2/core.c  | 469 ++-
 drivers/usb/dwc2/core.h  |  28 ++-
 drivers/usb/dwc2/core_intr.c |  73 +++
 drivers/usb/dwc2/debugfs.c   |  52 ++---
 drivers/usb/dwc2/gadget.c| 314 ++---
 drivers/usb/dwc2/hcd.c   | 140 ++---
 drivers/usb/dwc2/hcd.h   |  15 +-
 drivers/usb/dwc2/hcd_ddma.c  |  10 +-
 drivers/usb/dwc2/hcd_intr.c  |  82 
 drivers/usb/dwc2/hcd_queue.c |  10 +-
 10 files changed, 606 insertions(+), 587 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index c3cc1a7..a9de441 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -73,13 +73,13 @@ static int dwc2_backup_host_registers(struct dwc2_hsotg 
*hsotg)
 
/* Backup Host regs */
hr = hsotg-hr_backup;
-   hr-hcfg = readl(hsotg-regs + HCFG);
-   hr-haintmsk = readl(hsotg-regs + HAINTMSK);
+   hr-hcfg = dwc2_readl(hsotg-regs + HCFG);
+   hr-haintmsk = dwc2_readl(hsotg-regs + HAINTMSK);
for (i = 0; i  hsotg-core_params-host_channels; ++i)
-   hr-hcintmsk[i] = readl(hsotg-regs + HCINTMSK(i));
+   hr-hcintmsk[i] = dwc2_readl(hsotg-regs + HCINTMSK(i));
 
-   hr-hprt0 = readl(hsotg-regs + HPRT0);
-   hr-hfir = readl(hsotg-regs + HFIR);
+   hr-hprt0 = dwc2_readl(hsotg-regs + HPRT0);
+   hr-hfir = dwc2_readl(hsotg-regs + HFIR);
hr-valid = true;
 
return 0;
@@ -108,14 +108,14 @@ static int dwc2_restore_host_registers(struct dwc2_hsotg 
*hsotg)
}
hr-valid = false;
 
-   writel(hr-hcfg, hsotg-regs + HCFG);
-   writel(hr-haintmsk, hsotg-regs + HAINTMSK);
+   dwc2_writel(hr-hcfg, hsotg-regs + HCFG);
+   dwc2_writel(hr-haintmsk, hsotg-regs + HAINTMSK);
 
for (i = 0; i  hsotg-core_params-host_channels; ++i)
-   writel(hr-hcintmsk[i], hsotg-regs + HCINTMSK(i));
+   dwc2_writel(hr-hcintmsk[i], hsotg-regs + HCINTMSK(i));
 
-   writel(hr-hprt0, hsotg-regs + HPRT0);
-   writel(hr-hfir, hsotg-regs + HFIR);
+   dwc2_writel(hr-hprt0, hsotg-regs + HPRT0);
+   dwc2_writel(hr-hfir, hsotg-regs + HFIR);
 
return 0;
 }
@@ -146,15 +146,15 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg 
*hsotg)
/* Backup dev regs */
dr = hsotg-dr_backup;
 
-   dr-dcfg = readl(hsotg-regs + DCFG);
-   dr-dctl = readl(hsotg-regs + DCTL);
-   dr-daintmsk = readl(hsotg-regs + DAINTMSK);
-   dr-diepmsk = readl(hsotg-regs + DIEPMSK);
-   dr-doepmsk = readl(hsotg-regs + DOEPMSK);
+   dr-dcfg = dwc2_readl(hsotg-regs + DCFG);
+   dr-dctl = dwc2_readl(hsotg-regs + DCTL);
+   dr-daintmsk = dwc2_readl(hsotg-regs + DAINTMSK);
+   dr-diepmsk = dwc2_readl(hsotg-regs + DIEPMSK);
+   dr-doepmsk = dwc2_readl(hsotg-regs + DOEPMSK);
 
for (i = 0; i  hsotg-num_of_eps; i++) {
/* Backup IN EPs */
-   dr-diepctl[i] = readl(hsotg-regs + DIEPCTL(i));
+   dr-diepctl[i] = dwc2_readl(hsotg-regs + DIEPCTL(i));
 
/* Ensure DATA PID is correctly configured */
if (dr-diepctl[i]  DXEPCTL_DPID)
@@ -162,11 +162,11 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg 
*hsotg)
else
dr-diepctl[i] |= DXEPCTL_SETD0PID;
 
-   dr-dieptsiz[i] = readl(hsotg-regs + DIEPTSIZ(i));
-   dr-diepdma[i] = readl(hsotg-regs + DIEPDMA(i));
+   dr-dieptsiz[i] = dwc2_readl(hsotg-regs + DIEPTSIZ(i));
+   dr-diepdma[i] = dwc2_readl(hsotg-regs + DIEPDMA(i));
 
/* Backup OUT EPs */
-   dr-doepctl[i] = readl(hsotg-regs + DOEPCTL(i));
+   dr-doepctl[i] = dwc2_readl(hsotg-regs + DOEPCTL(i));
 
/* Ensure DATA PID is correctly configured */
if (dr-doepctl[i]  DXEPCTL_DPID)
@@ -174,8 +174,8 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg 
*hsotg)
else
dr-doepctl[i] |= DXEPCTL_SETD0PID;
 
-   dr-doeptsiz

[PATCH v2 1/2] usb: dwc2: Use platform endianness when accessing registers

2015-03-12 Thread Antti Seppälä
This patch switches calls to readl/writel to their
dwc2_readl/dwc2_writel equivalents which preserve platform endianness.

This patch is necessary to access dwc2 registers correctly on big endian
systems such as the mips based SoCs made by Lantiq. Then dwc2 can be
used to replace ifx-hcd driver for Lantiq platforms found e.g. in
OpenWrt.

The patch was autogenerated with the following commands:
$EDITOR core.h
sed -i s/\readl\/dwc2_readl/g *.c hcd.h hw.h
sed -i s/\writel\/dwc2_writel/g *.c hcd.h hw.h

Some files were then hand-edited to fix checkpatch.pl warnings about
too long lines.

Signed-off-by: Antti Seppälä a.sepp...@gmail.com
Signed-off-by: Vincent Pelletier plr.vinc...@gmail.com
---
 drivers/usb/dwc2/core.c  | 341 ++-
 drivers/usb/dwc2/core.h  |  29 +++-
 drivers/usb/dwc2/core_intr.c |  73 -
 drivers/usb/dwc2/gadget.c| 312 +++
 drivers/usb/dwc2/hcd.c   | 138 -
 drivers/usb/dwc2/hcd.h   |  15 +-
 drivers/usb/dwc2/hcd_ddma.c  |  10 +-
 drivers/usb/dwc2/hcd_intr.c  |  82 +--
 drivers/usb/dwc2/hcd_queue.c |  10 +-
 9 files changed, 515 insertions(+), 495 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index d5197d4..a7bad24 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -67,10 +67,10 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg 
*hsotg)
u32 intmsk;
 
/* Clear any pending OTG Interrupts */
-   writel(0x, hsotg-regs + GOTGINT);
+   dwc2_writel(0x, hsotg-regs + GOTGINT);
 
/* Clear any pending interrupts */
-   writel(0x, hsotg-regs + GINTSTS);
+   dwc2_writel(0x, hsotg-regs + GINTSTS);
 
/* Enable the interrupts in the GINTMSK */
intmsk = GINTSTS_MODEMIS | GINTSTS_OTGINT;
@@ -81,7 +81,7 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg 
*hsotg)
intmsk |= GINTSTS_CONIDSTSCHNG | GINTSTS_WKUPINT | GINTSTS_USBSUSP |
  GINTSTS_SESSREQINT;
 
-   writel(intmsk, hsotg-regs + GINTMSK);
+   dwc2_writel(intmsk, hsotg-regs + GINTMSK);
 }
 
 /*
@@ -104,10 +104,10 @@ static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg 
*hsotg)
}
 
dev_dbg(hsotg-dev, Initializing HCFG.FSLSPClkSel to %08x\n, val);
-   hcfg = readl(hsotg-regs + HCFG);
+   hcfg = dwc2_readl(hsotg-regs + HCFG);
hcfg = ~HCFG_FSLSPCLKSEL_MASK;
hcfg |= val  HCFG_FSLSPCLKSEL_SHIFT;
-   writel(hcfg, hsotg-regs + HCFG);
+   dwc2_writel(hcfg, hsotg-regs + HCFG);
 }
 
 /*
@@ -125,7 +125,7 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
/* Wait for AHB master IDLE state */
do {
usleep_range(2, 4);
-   greset = readl(hsotg-regs + GRSTCTL);
+   greset = dwc2_readl(hsotg-regs + GRSTCTL);
if (++count  50) {
dev_warn(hsotg-dev,
 %s() HANG! AHB Idle GRSTCTL=%0x\n,
@@ -137,10 +137,10 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
/* Core Soft Reset */
count = 0;
greset |= GRSTCTL_CSFTRST;
-   writel(greset, hsotg-regs + GRSTCTL);
+   dwc2_writel(greset, hsotg-regs + GRSTCTL);
do {
usleep_range(2, 4);
-   greset = readl(hsotg-regs + GRSTCTL);
+   greset = dwc2_readl(hsotg-regs + GRSTCTL);
if (++count  50) {
dev_warn(hsotg-dev,
 %s() HANG! Soft Reset GRSTCTL=%0x\n,
@@ -150,20 +150,20 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
} while (greset  GRSTCTL_CSFTRST);
 
if (hsotg-dr_mode == USB_DR_MODE_HOST) {
-   gusbcfg = readl(hsotg-regs + GUSBCFG);
+   gusbcfg = dwc2_readl(hsotg-regs + GUSBCFG);
gusbcfg = ~GUSBCFG_FORCEDEVMODE;
gusbcfg |= GUSBCFG_FORCEHOSTMODE;
-   writel(gusbcfg, hsotg-regs + GUSBCFG);
+   dwc2_writel(gusbcfg, hsotg-regs + GUSBCFG);
} else if (hsotg-dr_mode == USB_DR_MODE_PERIPHERAL) {
-   gusbcfg = readl(hsotg-regs + GUSBCFG);
+   gusbcfg = dwc2_readl(hsotg-regs + GUSBCFG);
gusbcfg = ~GUSBCFG_FORCEHOSTMODE;
gusbcfg |= GUSBCFG_FORCEDEVMODE;
-   writel(gusbcfg, hsotg-regs + GUSBCFG);
+   dwc2_writel(gusbcfg, hsotg-regs + GUSBCFG);
} else if (hsotg-dr_mode == USB_DR_MODE_OTG) {
-   gusbcfg = readl(hsotg-regs + GUSBCFG);
+   gusbcfg = dwc2_readl(hsotg-regs + GUSBCFG);
gusbcfg = ~GUSBCFG_FORCEHOSTMODE;
gusbcfg = ~GUSBCFG_FORCEDEVMODE;
-   writel(gusbcfg, hsotg-regs + GUSBCFG);
+   dwc2_writel(gusbcfg, hsotg-regs + GUSBCFG);
}
 
/*
@@ -186,9 +186,9 @@ static int dwc2_fs_phy_init(struct

[PATCH v2 0/2] usb: dwc2: add support for big-endian Lantiq SoCs

2015-03-12 Thread Antti Seppälä
Here are two patches needed to add support for mips based
big-endian SoCs made by Lantiq to dwc2 driver.

The first patch converts the readl/writel io-accessors of dwc2 to
big-endian friendly versions and was discussed on the linux-usb ml
already earlier.

The second patch adds default fifo parameters for Lantiq SoCs to dwc2
which is needed to support devices equipped with smaller fifo sizes.

Note: The only reason for the second patch to exist is that dynamic
calculation algorithm in dwc2_calculate_dynamic_fifo does not cope well
with fifo sizes below certain limit.

Changes since previous version:
 * Patches updated to apply to latest dwc2 code
 * Fixing wrong comment style (as pointed out by Felipe Balbi)

Antti Seppälä (2):
  usb: dwc2: Use platform endianness when accessing registers
  usb: dwc2: Add default fifo sizes for Lantiq SoCs

 Documentation/devicetree/bindings/usb/dwc2.txt |   1 +
 drivers/usb/dwc2/core.c| 341 +
 drivers/usb/dwc2/core.h|  29 ++-
 drivers/usb/dwc2/core_intr.c   |  73 +++---
 drivers/usb/dwc2/gadget.c  | 312 +++---
 drivers/usb/dwc2/hcd.c | 138 +-
 drivers/usb/dwc2/hcd.h |  15 +-
 drivers/usb/dwc2/hcd_ddma.c|  10 +-
 drivers/usb/dwc2/hcd_intr.c|  82 +++---
 drivers/usb/dwc2/hcd_queue.c   |  10 +-
 drivers/usb/dwc2/platform.c|  29 +++
 11 files changed, 545 insertions(+), 495 deletions(-)

-- 
2.0.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 2/2] usb: dwc2: Add default fifo sizes for Lantiq SoCs

2015-03-12 Thread Antti Seppälä
Lantiq SoCs define the total_fifo_size to be 552 dwords which is too
small for algorithm in dwc2_calculate_dynamic_fifo to work properly.

This patch provides sensible defaults for fifo sizes for Lantiq SoCs
to be used in dwc2 driver. The default values are taken from original
ifx-hcd driver.

Signed-off-by: Antti Seppälä a.sepp...@gmail.com
Signed-off-by: Vincent Pelletier plr.vinc...@gmail.com
---
 Documentation/devicetree/bindings/usb/dwc2.txt |  1 +
 drivers/usb/dwc2/platform.c| 29 ++
 2 files changed, 30 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt 
b/Documentation/devicetree/bindings/usb/dwc2.txt
index fd132cb..9182a9f 100644
--- a/Documentation/devicetree/bindings/usb/dwc2.txt
+++ b/Documentation/devicetree/bindings/usb/dwc2.txt
@@ -7,6 +7,7 @@ Required properties:
   - rockchip,rk3066-usb: The DWC2 USB controller instance in the rk3066 Soc;
   - rockchip,rk3188-usb, rockchip,rk3066-usb, snps,dwc2: for rk3188 Soc;
   - rockchip,rk3288-usb, rockchip,rk3066-usb, snps,dwc2: for rk3288 Soc;
+  - lantiq,dwc2: DWC2 USB controllers found in Lantiq SoCs;
   - snps,dwc2: A generic DWC2 USB controller with default parameters.
 - reg : Should contain 1 register range (address and length)
 - interrupts : Should contain 1 interrupt
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index ae095f0..99d6b60 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -106,6 +106,34 @@ static const struct dwc2_core_params params_rk3066 = {
.uframe_sched   = -1,
 };
 
+static const struct dwc2_core_params params_ltq = {
+   .otg_cap= -1,
+   .otg_ver= -1,
+   .dma_enable = -1,
+   .dma_desc_enable= -1,
+   .speed  = -1,
+   .enable_dynamic_fifo= -1,
+   .en_multiple_tx_fifo= -1,
+   .host_rx_fifo_size  = 240,  /* 240 DWORDs */
+   .host_nperio_tx_fifo_size   = 240,  /* 240 DWORDs */
+   .host_perio_tx_fifo_size= 32,   /* 32 DWORDs */
+   .max_transfer_size  = -1,
+   .max_packet_count   = -1,
+   .host_channels  = -1,
+   .phy_type   = -1,
+   .phy_utmi_width = -1,
+   .phy_ulpi_ddr   = -1,
+   .phy_ulpi_ext_vbus  = -1,
+   .i2c_enable = -1,
+   .ulpi_fs_ls = -1,
+   .host_support_fs_ls_low_power   = -1,
+   .host_ls_low_power_phy_clk  = -1,
+   .ts_dline   = -1,
+   .reload_ctl = -1,
+   .ahbcfg = -1,
+   .uframe_sched   = -1,
+};
+
 /**
  * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the
  * DWC_otg driver
@@ -130,6 +158,7 @@ static int dwc2_driver_remove(struct platform_device *dev)
 static const struct of_device_id dwc2_of_match_table[] = {
{ .compatible = brcm,bcm2835-usb, .data = params_bcm2835 },
{ .compatible = rockchip,rk3066-usb, .data = params_rk3066 },
+   { .compatible = lantiq,dwc2, .data = params_ltq },
{ .compatible = snps,dwc2, .data = NULL },
{ .compatible = samsung,s3c6400-hsotg, .data = NULL},
{},
-- 
2.0.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 1/2] usb: dwc2: Use platform endianness when accessing registers

2015-01-31 Thread Antti Seppälä
This patch switches calls to readl/writel to their
dwc2_readl/dwc2_writel equivalents which preserve platform endianness.

This patch is necessary to access dwc2 registers correctly on big endian
systems such as the mips based SoCs made by Lantiq. Then dwc2 can be
used to replace ifx-hcd driver for Lantiq platforms found e.g. in
OpenWrt.

The patch was autogenerated with the following commands:
$EDITOR core.h
sed -i s/\readl\/dwc2_readl/g *.c hcd.h hw.h
sed -i s/\writel\/dwc2_writel/g *.c hcd.h hw.h

Some files were then hand-edited to fix checkpatch.pl warnings about
too long lines.

Signed-off-by: Antti Seppälä a.sepp...@gmail.com
Signed-off-by: Vincent Pelletier plr.vinc...@gmail.com
---
 drivers/usb/dwc2/core.c  | 341 ++-
 drivers/usb/dwc2/core.h  |  24 ++-
 drivers/usb/dwc2/core_intr.c |  73 -
 drivers/usb/dwc2/gadget.c| 312 +++
 drivers/usb/dwc2/hcd.c   | 144 +-
 drivers/usb/dwc2/hcd.h   |  15 +-
 drivers/usb/dwc2/hcd_ddma.c  |  10 +-
 drivers/usb/dwc2/hcd_intr.c  |  82 +--
 drivers/usb/dwc2/hcd_queue.c |  10 +-
 9 files changed, 513 insertions(+), 498 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 7605850b..10f50e5 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -67,10 +67,10 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg 
*hsotg)
u32 intmsk;
 
/* Clear any pending OTG Interrupts */
-   writel(0x, hsotg-regs + GOTGINT);
+   dwc2_writel(0x, hsotg-regs + GOTGINT);
 
/* Clear any pending interrupts */
-   writel(0x, hsotg-regs + GINTSTS);
+   dwc2_writel(0x, hsotg-regs + GINTSTS);
 
/* Enable the interrupts in the GINTMSK */
intmsk = GINTSTS_MODEMIS | GINTSTS_OTGINT;
@@ -81,7 +81,7 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg 
*hsotg)
intmsk |= GINTSTS_CONIDSTSCHNG | GINTSTS_WKUPINT | GINTSTS_USBSUSP |
  GINTSTS_SESSREQINT;
 
-   writel(intmsk, hsotg-regs + GINTMSK);
+   dwc2_writel(intmsk, hsotg-regs + GINTMSK);
 }
 
 /*
@@ -104,10 +104,10 @@ static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg 
*hsotg)
}
 
dev_dbg(hsotg-dev, Initializing HCFG.FSLSPClkSel to %08x\n, val);
-   hcfg = readl(hsotg-regs + HCFG);
+   hcfg = dwc2_readl(hsotg-regs + HCFG);
hcfg = ~HCFG_FSLSPCLKSEL_MASK;
hcfg |= val  HCFG_FSLSPCLKSEL_SHIFT;
-   writel(hcfg, hsotg-regs + HCFG);
+   dwc2_writel(hcfg, hsotg-regs + HCFG);
 }
 
 /*
@@ -125,7 +125,7 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
/* Wait for AHB master IDLE state */
do {
usleep_range(2, 4);
-   greset = readl(hsotg-regs + GRSTCTL);
+   greset = dwc2_readl(hsotg-regs + GRSTCTL);
if (++count  50) {
dev_warn(hsotg-dev,
 %s() HANG! AHB Idle GRSTCTL=%0x\n,
@@ -137,10 +137,10 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
/* Core Soft Reset */
count = 0;
greset |= GRSTCTL_CSFTRST;
-   writel(greset, hsotg-regs + GRSTCTL);
+   dwc2_writel(greset, hsotg-regs + GRSTCTL);
do {
usleep_range(2, 4);
-   greset = readl(hsotg-regs + GRSTCTL);
+   greset = dwc2_readl(hsotg-regs + GRSTCTL);
if (++count  50) {
dev_warn(hsotg-dev,
 %s() HANG! Soft Reset GRSTCTL=%0x\n,
@@ -150,20 +150,20 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
} while (greset  GRSTCTL_CSFTRST);
 
if (hsotg-dr_mode == USB_DR_MODE_HOST) {
-   gusbcfg = readl(hsotg-regs + GUSBCFG);
+   gusbcfg = dwc2_readl(hsotg-regs + GUSBCFG);
gusbcfg = ~GUSBCFG_FORCEDEVMODE;
gusbcfg |= GUSBCFG_FORCEHOSTMODE;
-   writel(gusbcfg, hsotg-regs + GUSBCFG);
+   dwc2_writel(gusbcfg, hsotg-regs + GUSBCFG);
} else if (hsotg-dr_mode == USB_DR_MODE_PERIPHERAL) {
-   gusbcfg = readl(hsotg-regs + GUSBCFG);
+   gusbcfg = dwc2_readl(hsotg-regs + GUSBCFG);
gusbcfg = ~GUSBCFG_FORCEHOSTMODE;
gusbcfg |= GUSBCFG_FORCEDEVMODE;
-   writel(gusbcfg, hsotg-regs + GUSBCFG);
+   dwc2_writel(gusbcfg, hsotg-regs + GUSBCFG);
} else if (hsotg-dr_mode == USB_DR_MODE_OTG) {
-   gusbcfg = readl(hsotg-regs + GUSBCFG);
+   gusbcfg = dwc2_readl(hsotg-regs + GUSBCFG);
gusbcfg = ~GUSBCFG_FORCEHOSTMODE;
gusbcfg = ~GUSBCFG_FORCEDEVMODE;
-   writel(gusbcfg, hsotg-regs + GUSBCFG);
+   dwc2_writel(gusbcfg, hsotg-regs + GUSBCFG);
}
 
/*
@@ -186,9 +186,9 @@ static int dwc2_fs_phy_init(struct

[PATCH 2/2] usb: dwc2: Add default fifo sizes for Lantiq SoCs

2015-01-31 Thread Antti Seppälä
Lantiq SoCs define the total_fifo_size to be 552 dwords which is too
small for algorithm in dwc2_calculate_dynamic_fifo to work properly.

This patch provides sensible defaults for fifo sizes for Lantiq SoCs
to be used in dwc2 driver. The default values are taken from original
ifx-hcd driver.

Signed-off-by: Antti Seppälä a.sepp...@gmail.com
Signed-off-by: Vincent Pelletier plr.vinc...@gmail.com
---
 Documentation/devicetree/bindings/usb/dwc2.txt |  1 +
 drivers/usb/dwc2/platform.c| 29 ++
 2 files changed, 30 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt 
b/Documentation/devicetree/bindings/usb/dwc2.txt
index 482f815..2b3a2b2 100644
--- a/Documentation/devicetree/bindings/usb/dwc2.txt
+++ b/Documentation/devicetree/bindings/usb/dwc2.txt
@@ -7,6 +7,7 @@ Required properties:
   - rockchip,rk3066-usb: The DWC2 USB controller instance in the rk3066 Soc;
   - rockchip,rk3188-usb, rockchip,rk3066-usb, snps,dwc2: for rk3188 Soc;
   - rockchip,rk3288-usb, rockchip,rk3066-usb, snps,dwc2: for rk3288 Soc;
+  - lantiq,dwc2: DWC2 USB controllers found in Lantiq SoCs;
   - snps,dwc2: A generic DWC2 USB controller with default parameters.
 - reg : Should contain 1 register range (address and length)
 - interrupts : Should contain 1 interrupt
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 6a795aa..2b0714a 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -106,6 +106,34 @@ static const struct dwc2_core_params params_rk3066 = {
.uframe_sched   = -1,
 };
 
+static const struct dwc2_core_params params_ltq = {
+   .otg_cap= -1,
+   .otg_ver= -1,
+   .dma_enable = -1,
+   .dma_desc_enable= -1,
+   .speed  = -1,
+   .enable_dynamic_fifo= -1,
+   .en_multiple_tx_fifo= -1,
+   .host_rx_fifo_size  = 240,  /* 240 DWORDs */
+   .host_nperio_tx_fifo_size   = 240,  /* 240 DWORDs */
+   .host_perio_tx_fifo_size= 32,   /* 32 DWORDs */
+   .max_transfer_size  = -1,
+   .max_packet_count   = -1,
+   .host_channels  = -1,
+   .phy_type   = -1,
+   .phy_utmi_width = -1,
+   .phy_ulpi_ddr   = -1,
+   .phy_ulpi_ext_vbus  = -1,
+   .i2c_enable = -1,
+   .ulpi_fs_ls = -1,
+   .host_support_fs_ls_low_power   = -1,
+   .host_ls_low_power_phy_clk  = -1,
+   .ts_dline   = -1,
+   .reload_ctl = -1,
+   .ahbcfg = -1,
+   .uframe_sched   = -1,
+};
+
 /**
  * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the
  * DWC_otg driver
@@ -130,6 +158,7 @@ static int dwc2_driver_remove(struct platform_device *dev)
 static const struct of_device_id dwc2_of_match_table[] = {
{ .compatible = brcm,bcm2835-usb, .data = params_bcm2835 },
{ .compatible = rockchip,rk3066-usb, .data = params_rk3066 },
+   { .compatible = lantiq,dwc2, .data = params_ltq },
{ .compatible = snps,dwc2, .data = NULL },
{ .compatible = samsung,s3c6400-hsotg, .data = NULL},
{},
-- 
2.0.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 0/2] usb: dwc2: add support for big-endian Lantiq SoCs

2015-01-31 Thread Antti Seppälä
Here are two patches needed to add support for mips based 
big-endian SoCs made by Lantiq to dwc2 driver.

The first patch converts the readl/writel io-accessors of dwc2 to 
big-endian friendly versions and was discussed on the linux-usb ml 
already earlier.

The second patch adds default fifo parameters for Lantiq SoCs to dwc2 
which is needed to support devices equipped with smaller fifo sizes.

Antti Seppälä (2):
  usb: dwc2: Use platform endianness when accessing registers
  usb: dwc2: Add default fifo sizes for Lantiq SoCs

 Documentation/devicetree/bindings/usb/dwc2.txt |   1 +
 drivers/usb/dwc2/core.c| 341 +
 drivers/usb/dwc2/core.h|  24 +-
 drivers/usb/dwc2/core_intr.c   |  73 +++---
 drivers/usb/dwc2/gadget.c  | 312 +++---
 drivers/usb/dwc2/hcd.c | 144 +--
 drivers/usb/dwc2/hcd.h |  15 +-
 drivers/usb/dwc2/hcd_ddma.c|  10 +-
 drivers/usb/dwc2/hcd_intr.c|  82 +++---
 drivers/usb/dwc2/hcd_queue.c   |  10 +-
 drivers/usb/dwc2/platform.c|  29 +++
 11 files changed, 543 insertions(+), 498 deletions(-)

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


Re: [RFC PATCH] usb: dwc2: Use platform endianness when accessing registers

2015-01-28 Thread Antti Seppälä
On 27 January 2015 at 04:18, John Youn john.y...@synopsys.com wrote:
 From: Vincent Pelletier [mailto:plr.vinc...@gmail.com]
 Sent: Friday, January 23, 2015 12:19 AM

 On Fri, 23 Jan 2015 02:38:37 +, John Youn john.y...@synopsys.com
 wrote:
  Having the __raw functions everywhere is not pretty and probably not a
  good idea either.
 
  I would rather have a dwc2_writel/dwc2_readl (like in dwc3), and we
  can figure out what needs to happen in there to support your platform.
 
  As for readl/writel or the __raw equivalents, I am not sure. I haven't
  run the in-kernel driver on a big endian system so I don't know what
  the issue is. But I suspect there may be consequences to other
  platforms if we simply change this to __raw_readl/__raw_writel.

 (focussing on readl, but the following also applies to writel)

 readl is defined as __le32_to_cpu(__raw_readl(...)), so using readl on
 little endian is equivalent to __raw_readl, as __le32_to_cpu is a no-op.

 On big endian, it causes problems because __le32_to_cpu swaps bytes
 around, causing GSNPSID to be read as 0xnn2n544f instead of expected
 0x4f542nnn - and likewise for all other registers.

 An earlier version (sent to linux-usb a week ago with not enough CC,
 but I cannot find it in archives now) defined dwc2_readl as
   le32_to_cpu(readl(...))
 which is equivalent to
   le32_to_cpu(le32_to_cpu(__raw_readl(...)))
 and which, on big-endian, makes le32_to_cpu(le32_to_cpu()) a no-op and
 (ignoring possible compiler optimisation) swaps bytes twice per call.
 On little endian, it is still equivalent to __raw_readl(...).

 As for the prettiness of calling double-underscore functions,
 speaking for myself I'm not used to Linux development enough to tell.
 My python developer reflex tell me it's not how it should be.
 OTOH there is no raw_readl or so alias, and other USB drivers
 reference __raw_readl (example as of v3.14.28):
 linux/drivers/usb$ git grep -l __raw_readl
 gadget/at91_udc.c
 gadget/atmel_usba_udc.c
 gadget/atmel_usba_udc.h
 gadget/fsl_udc_core.c
 gadget/pxa27x_udc.h
 host/ehci-omap.c
 host/ehci-orion.c
 host/ehci-w90x900.c
 host/ehci.h
 host/isp1760-hcd.c
 host/ohci-da8xx.c
 host/ohci-nxp.c
 host/ohci-pxa27x.c
 musb/da8xx.c
 musb/davinci.c
 musb/musb_dsps.c
 musb/musb_io.h
 phy/phy-fsl-usb.c

 Would it be better to wrap __raw_readl in a macro and call that
 everywhere rather than calling __raw_readl itself ?

 I was thinking more along the lines of what dwc3 does. See
 drivers/usb/dwc3/io.h.

 One solution would be to do as above, and put in a compile-time check
 for your platform and call the appropriate access function.

 I believe writel/readl also preserves memory ordering so it might
 affect other platforms to just use the __raw equivalent in its place.


Broadly speaking readl(x) can be split to three separate functions. I
think it evaluates to something like below for dwc2:

static inline u32 dwc2_readl(const volatile void __iomem *addr)
{
u32 value = __raw_readl(addr); /* Raw access to io */
value = le32_to_cpu(value); /* Ensure little-endian byte order */
mb(); /* Prevent re-ordering of io-accesses */

return value;
}

Now le32_to_cpu is a no-op for little-endian platforms and breaks dwc2
for big endian ones (as Vincent explained, it swaps bytes
unnecessarily for big endian platforms). So I'm thinking of dropping
it and re-spinning the patch with something like below:

static inline u32 dwc2_readl(const volatile void __iomem *addr)
{
u32 value = __raw_readl(addr); /* Raw access to io */
mb(); /* Prevent re-ordering of io-accesses */

return value;
}

and then replacing all readl's in dwc2 with dwc2_readl (and same for
writel). That way nothing should get broken on little-endian as we're
only dropping a no-op and we get to use the same code for big-endian
platforms too. Would that be ok?

I really would not want to add platform specific io-access
functionalities if we can manage with a generic approach.

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


[RFC PATCH] usb: dwc2: Use platform endianness when accessing registers

2015-01-21 Thread Antti Seppälä
This patch switches calls to readl/writel to their
__raw_readl/__raw_writel equivalents which preserve platform endianness.

This patch is necessary to access dwc2 registers correctly on big endian
systems such as mips. Then dwc2 can be used to replace ifx-hcd driver
for lantiq platform found e.g. in OpenWrt.

The patch was autogenerated with the following commands:
sed -i s/\readl\/__raw_readl/g *.c hcd.h hw.h
sed -i s/\writel\/__raw_writel/g *.c hcd.h hw.h

Some files were then hand-edited to fix checkpatch.pl warning about
too long lines.

Signed-off-by: Antti Seppälä a.sepp...@gmail.com
Signed-off-by: Vincent Pelletier plr.vinc...@gmail.com
---
 drivers/usb/dwc2/core.c  | 341 ++-
 drivers/usb/dwc2/core_intr.c |  73 -
 drivers/usb/dwc2/gadget.c| 312 +++
 drivers/usb/dwc2/hcd.c   | 144 +-
 drivers/usb/dwc2/hcd.h   |  15 +-
 drivers/usb/dwc2/hcd_ddma.c  |  10 +-
 drivers/usb/dwc2/hcd_intr.c  |  82 +--
 drivers/usb/dwc2/hcd_queue.c |  10 +-
 8 files changed, 495 insertions(+), 492 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 7605850b..30ef56b 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -67,10 +67,10 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg 
*hsotg)
u32 intmsk;
 
/* Clear any pending OTG Interrupts */
-   writel(0x, hsotg-regs + GOTGINT);
+   __raw_writel(0x, hsotg-regs + GOTGINT);
 
/* Clear any pending interrupts */
-   writel(0x, hsotg-regs + GINTSTS);
+   __raw_writel(0x, hsotg-regs + GINTSTS);
 
/* Enable the interrupts in the GINTMSK */
intmsk = GINTSTS_MODEMIS | GINTSTS_OTGINT;
@@ -81,7 +81,7 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg 
*hsotg)
intmsk |= GINTSTS_CONIDSTSCHNG | GINTSTS_WKUPINT | GINTSTS_USBSUSP |
  GINTSTS_SESSREQINT;
 
-   writel(intmsk, hsotg-regs + GINTMSK);
+   __raw_writel(intmsk, hsotg-regs + GINTMSK);
 }
 
 /*
@@ -104,10 +104,10 @@ static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg 
*hsotg)
}
 
dev_dbg(hsotg-dev, Initializing HCFG.FSLSPClkSel to %08x\n, val);
-   hcfg = readl(hsotg-regs + HCFG);
+   hcfg = __raw_readl(hsotg-regs + HCFG);
hcfg = ~HCFG_FSLSPCLKSEL_MASK;
hcfg |= val  HCFG_FSLSPCLKSEL_SHIFT;
-   writel(hcfg, hsotg-regs + HCFG);
+   __raw_writel(hcfg, hsotg-regs + HCFG);
 }
 
 /*
@@ -125,7 +125,7 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
/* Wait for AHB master IDLE state */
do {
usleep_range(2, 4);
-   greset = readl(hsotg-regs + GRSTCTL);
+   greset = __raw_readl(hsotg-regs + GRSTCTL);
if (++count  50) {
dev_warn(hsotg-dev,
 %s() HANG! AHB Idle GRSTCTL=%0x\n,
@@ -137,10 +137,10 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
/* Core Soft Reset */
count = 0;
greset |= GRSTCTL_CSFTRST;
-   writel(greset, hsotg-regs + GRSTCTL);
+   __raw_writel(greset, hsotg-regs + GRSTCTL);
do {
usleep_range(2, 4);
-   greset = readl(hsotg-regs + GRSTCTL);
+   greset = __raw_readl(hsotg-regs + GRSTCTL);
if (++count  50) {
dev_warn(hsotg-dev,
 %s() HANG! Soft Reset GRSTCTL=%0x\n,
@@ -150,20 +150,20 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
} while (greset  GRSTCTL_CSFTRST);
 
if (hsotg-dr_mode == USB_DR_MODE_HOST) {
-   gusbcfg = readl(hsotg-regs + GUSBCFG);
+   gusbcfg = __raw_readl(hsotg-regs + GUSBCFG);
gusbcfg = ~GUSBCFG_FORCEDEVMODE;
gusbcfg |= GUSBCFG_FORCEHOSTMODE;
-   writel(gusbcfg, hsotg-regs + GUSBCFG);
+   __raw_writel(gusbcfg, hsotg-regs + GUSBCFG);
} else if (hsotg-dr_mode == USB_DR_MODE_PERIPHERAL) {
-   gusbcfg = readl(hsotg-regs + GUSBCFG);
+   gusbcfg = __raw_readl(hsotg-regs + GUSBCFG);
gusbcfg = ~GUSBCFG_FORCEHOSTMODE;
gusbcfg |= GUSBCFG_FORCEDEVMODE;
-   writel(gusbcfg, hsotg-regs + GUSBCFG);
+   __raw_writel(gusbcfg, hsotg-regs + GUSBCFG);
} else if (hsotg-dr_mode == USB_DR_MODE_OTG) {
-   gusbcfg = readl(hsotg-regs + GUSBCFG);
+   gusbcfg = __raw_readl(hsotg-regs + GUSBCFG);
gusbcfg = ~GUSBCFG_FORCEHOSTMODE;
gusbcfg = ~GUSBCFG_FORCEDEVMODE;
-   writel(gusbcfg, hsotg-regs + GUSBCFG);
+   __raw_writel(gusbcfg, hsotg-regs + GUSBCFG);
}
 
/*
@@ -186,9 +186,9 @@ static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool 
select_phy

Regression: Two em28xx devices in the same xhci-hcd (bisected)

2014-05-30 Thread Antti Seppälä
   Data
wMaxPacketSize 0x03ac  1x 940 bytes
bInterval   1
  Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x85  EP 5 IN
bmAttributes1
  Transfer TypeIsochronous
  Synch Type   None
  Usage Type   Data
wMaxPacketSize 0x03ac  1x 940 bytes
bInterval   1
Device Qualifier (for other device speed):
  bLength10
  bDescriptorType 6
  bcdUSB   2.00
  bDeviceClass0 (Defined at Interface level)
  bDeviceSubClass 0
  bDeviceProtocol 0
  bMaxPacketSize064
  bNumConfigurations  1
Device Status: 0x
  (Bus Powered)

Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Device Descriptor:
  bLength18
  bDescriptorType 1
  bcdUSB   2.00
  bDeviceClass9 Hub
  bDeviceSubClass 0 Unused
  bDeviceProtocol 1 Single TT
  bMaxPacketSize064
  idVendor   0x1d6b Linux Foundation
  idProduct  0x0002 2.0 root hub
  bcdDevice3.15
  iManufacturer   3 Linux 3.15.0-rc7-1-ge545e63 xhci_hcd
  iProduct2 xHCI Host Controller
  iSerial 1 :00:14.0
  bNumConfigurations  1
  Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength   25
bNumInterfaces  1
bConfigurationValue 1
iConfiguration  0
bmAttributes 0xe0
  Self Powered
  Remote Wakeup
MaxPower0mA
Interface Descriptor:
  bLength 9
  bDescriptorType 4
  bInterfaceNumber0
  bAlternateSetting   0
  bNumEndpoints   1
  bInterfaceClass 9 Hub
  bInterfaceSubClass  0 Unused
  bInterfaceProtocol  0 Full speed (or root) hub
  iInterface  0
  Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81  EP 1 IN
bmAttributes3
  Transfer TypeInterrupt
  Synch Type   None
  Usage Type   Data
wMaxPacketSize 0x0004  1x 4 bytes
bInterval  12
Hub Descriptor:
  bLength  11
  bDescriptorType  41
  nNbrPorts 9
  wHubCharacteristic 0x000a
No power switching (usb 1.0)
Per-port overcurrent protection
TT think time 8 FS bits
  bPwrOn2PwrGood   10 * 2 milli seconds
  bHubContrCurrent  0 milli Ampere
  DeviceRemovable0x00 0x02
  PortPwrCtrlMask0xff 0xff
 Hub Port Status:
   Port 1: .0503 highspeed power enable connect
   Port 2: .0503 highspeed power enable connect
   Port 3: .0100 power
   Port 4: .0100 power
   Port 5: .0100 power
   Port 6: .0100 power
   Port 7: .0100 power
   Port 8: .0100 power
   Port 9: .0100 power
Device Status: 0x0001
  Self Powered


Best regards,
-- 
Antti Seppälä
--
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