Re: JMS56x not working reliably with uas driver

2016-12-27 Thread George Cherian

Hi Alan,


On Tuesday 27 December 2016 08:50 PM, Alan Stern wrote:

On Tue, 27 Dec 2016, Oliver Neukum wrote:


On Thu, 2016-12-22 at 17:44 -0500, Alan Stern wrote:

I don't see how this patch fixes anything.  Unless I'm mistaken, it
just avoids the problem by preventing the system from issuing the
command that provokes the error, rather than really fixing the
underlying error.

Please clarify. If a reset leads to a disconnect, isn't that
exactly what we want?

I didn't express myself clearly enough.  Yes, if a reset leads to a
disconnect then avoiding the reset will avoid problems.

But the _real_ error here is that xhci-hcd says "ERROR Transfer event
for disabled endpoint or incorrect stream ring" when the disconnect
occurs during reset.

I think there is some misunderstanding of the issues.

"ERROR Transfer event for disabled endpoint or incorrect stream ring" This 
particular message is during the connect of the device and not during the disconnect.
To avoid this message the unusual_uas.h patch was sent earlier.

During disconnect of the device I get   "scsi host4: uas_post_reset: alloc streams error -19 after reset" and 
I dont get the same with the modified patch which Alan suggested, 
instead I get a proper disconnect.



That shouldn't happen, no matter what quirks the
device has.  It indicates a bug either in uas or in xhci-hcd.

Alan Stern


Regards, -George
--
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: JMS56x not working reliably with uas driver

2016-12-22 Thread George Cherian

Hi Alan,


On Friday 23 December 2016 04:14 AM, Alan Stern wrote:

On Wed, 21 Dec 2016, George Cherian wrote:


Hi Oliver,

I was working with this JMicron device and using the uas driver.
I am seeing the following 2 issues.

1) On connect I see the following messages.
xhci_hcd :00:11.0: ERROR Transfer event for disabled endpoint or
incorrect stream ring
   This was eliminated using the following scissor patch.

-8<
[PATCH] usb: storage: unusual_uas: Add JMicron JMS56x to unusual device

This device gives the following error on detection.
xhci_hcd :00:11.0: ERROR Transfer event for disabled endpoint or
incorrect stream ring

The same error is not seen when it is added to unusual_device
list with US_FL_NO_REPORT_OPCODES passed.

Signed-off-by: George Cherian <george.cher...@cavium.com>
---
   drivers/usb/storage/unusual_uas.h | 7 +++
   1 file changed, 7 insertions(+)

diff --git a/drivers/usb/storage/unusual_uas.h
b/drivers/usb/storage/unusual_uas.h
index cbea9f3..d292299 100644
--- a/drivers/usb/storage/unusual_uas.h
+++ b/drivers/usb/storage/unusual_uas.h
@@ -142,6 +142,13 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x, 0x,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_BROKEN_FUA | US_FL_NO_REPORT_OPCODES),

+/* Reported-by George Cherian <george.cher...@cavium.com> */
+UNUSUAL_DEV(0x152d, 0x9561, 0x, 0x,
+"JMicron",
+"JMS56x",
+USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+US_FL_NO_REPORT_OPCODES),
+
   /* Reported-by: Hans de Goede <hdego...@redhat.com> */
   UNUSUAL_DEV(0x2109, 0x0711, 0x, 0x,
"VIA",
->8

I don't see how this patch fixes anything.  Unless I'm mistaken, it
just avoids the problem by preventing the system from issuing the
command that provokes the error, rather than really fixing the
underlying error.


2) On disconnect I am seeing the following issue

   scsi host4: uas_post_reset: alloc streams error -19 after reset
   sd 4:0:0:0: [sdb] Synchronizing SCSI cache

This is more fatal because after these messages the USB port becomes
unusable. Even an lsusb invocation hangs for ever.

This problem looks pretty simple.  uas doesn't check properly to see if
the device was disconnected following a reset.

Try changing the line in uas_post_reset() that says:

if (devinfo->shutdown)

to:

if (devinfo->shutdown ||
devinfo->udev->state == USB_STATE_NOTATTACHED)
Yes this works for me but with a little bit change as follows, But am 
not sure whether we should goto reset_scsi in case of shutdown.

Please advice.

diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 5ef014b..24db3fd 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -1072,8 +1072,8 @@ static int uas_post_reset(struct usb_interface *intf)
unsigned long flags;
int err;

-   if (devinfo->shutdown)
-   return 0;
+   if (devinfo->shutdown || devinfo->udev->state == 
USB_STATE_NOTATTACHED)

+   goto reset_scsi;

err = uas_configure_endpoints(devinfo);
if (err) {
@@ -1083,6 +1083,7 @@ static int uas_post_reset(struct usb_interface *intf)
return 1;
}

+reset_scsi:
spin_lock_irqsave(shost->host_lock, flags);
scsi_report_bus_reset(shost, 0);
spin_unlock_irqrestore(shost->host_lock, flags);


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


Re: JMS56x not working reliably with uas driver

2016-12-22 Thread George Cherian
:0:0: [sdb] Done: SUCCESS Result: hostbyte=DID_OK 
driverbyte=DRIVER_OK
[  110.257499] sd 4:0:0:0: [sdb] CDB: Read(16) 88 00 00 00 00 00 04 a8 
60 00 00 00 00 80 00 00

[  110.257503] sd 4:0:0:0: [sdb] sd_done: completed 65536 of 65536 bytes
[  110.257506] sd 4:0:0:0: [sdb] 128 sectors total, 65536 bytes done.
[  110.257727] sd 4:0:0:0: [sdb] sd_ioctl: disk=sdb, cmd=0x5331
[  110.257759] sd 4:0:0:0: [sdb] sd_setup_read_write_cmnd: block=0, 
count=128

[  110.257762] sd 4:0:0:0: [sdb] block=0
[  110.257765] sd 4:0:0:0: [sdb] reading 128/128 512 byte blocks.
[  110.257770] sd 4:0:0:0: [sdb] Send: scmd 0x801fcc338a00
[  110.257773] sd 4:0:0:0: [sdb] CDB: Read(16) 88 00 00 00 00 00 00 00 
00 00 00 00 00 80 00 00
[  110.258168] sd 4:0:0:0: [sdb] Done: SUCCESS Result: hostbyte=DID_OK 
driverbyte=DRIVER_OK
[  110.258171] sd 4:0:0:0: [sdb] CDB: Read(16) 88 00 00 00 00 00 00 00 
00 00 00 00 00 80 00 00

[  110.258175] sd 4:0:0:0: [sdb] sd_done: completed 65536 of 65536 bytes
[  110.258179] sd 4:0:0:0: [sdb] 128 sectors total, 65536 bytes done.
[  110.259759] sd 4:0:0:0: Send: scmd 0x801fcc338a00
[  110.259763] sd 4:0:0:0: CDB: Test Unit Ready 00 00 00 00 00 00
[  110.259854] sd 4:0:0:0: Done: SUCCESS Result: hostbyte=DID_OK 
driverbyte=DRIVER_OK

[  110.259858] sd 4:0:0:0: CDB: Test Unit Ready 00 00 00 00 00 00
[  110.259861] sd 4:0:0:0: 0 sectors total, 0 bytes done.
=Connect end 

===Disconnect log =

[  358.581289] scsi host4: uas_post_reset: alloc streams error -19 after 
reset

[  358.588962] sd 4:0:0:0: [sdb] Synchronizing SCSI cache
=


On Thursday 22 December 2016 07:34 AM, George Cherian wrote:

Hi Oliver,

I will try it out and update you!!


Regards,

-George

On Wednesday 21 December 2016 08:09 PM, Oliver Neukum wrote:

On Wed, 2016-12-21 at 18:17 +0530, George Cherian wrote:

[  843.149653] scsi host5: uas_post_reset: alloc streams error -19
after
reset

That would mean the endpoints are gone. Which is odd.


[  843.157268] sd 5:0:0:0: [sdb] Synchronizing SCSI cache

Could you try the attached patch and do a SCSI log of the enumeration?

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: JMS56x not working reliably with uas driver

2016-12-21 Thread George Cherian

Hi Oliver,

I will try it out and update you!!


Regards,

-George

On Wednesday 21 December 2016 08:09 PM, Oliver Neukum wrote:

On Wed, 2016-12-21 at 18:17 +0530, George Cherian wrote:

[  843.149653] scsi host5: uas_post_reset: alloc streams error -19
after
reset

That would mean the endpoints are gone. Which is odd.


[  843.157268] sd 5:0:0:0: [sdb] Synchronizing SCSI cache

Could you try the attached patch and do a SCSI log of the enumeration?

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: JMS56x not working reliably with uas driver

2016-12-21 Thread George Cherian



On 12/21/2016 05:12 PM, Oliver Neukum wrote:

On Wed, 2016-12-21 at 17:09 +0530, George Cherian wrote:

Hi Oliver,

I was working with this JMicron device and using the uas driver.
I am seeing the following 2 issues.

1) On connect I see the following messages.


Thanks. Do you want to submit it to Greg?
The patch is fine.

Yes please!!!




2) On disconnect I am seeing the following issue

   scsi host4: uas_post_reset: alloc streams error -19 after reset
   sd 4:0:0:0: [sdb] Synchronizing SCSI cache

This is more fatal because after these messages the USB port becomes
unusable. Even an lsusb invocation hangs for ever.


Ouch. That points to a logic error. We should not reset if
a device is gone.
Could you send dmesg of such a case?

here is the dmesg!!
[  203.475382] usb 4-1.3: new SuperSpeed USB device number 3 using xhci_hcd
[  203.496172] usb 4-1.3: New USB device found, idVendor=152d, 
idProduct=9561
[  203.503037] usb 4-1.3: New USB device strings: Mfr=1, Product=2, 
SerialNumber=5

[  203.510352] usb 4-1.3: Product: JMS56x Series
[  203.514698] usb 4-1.3: Manufacturer: JMicron
[  203.518966] usb 4-1.3: SerialNumber: 
[  203.594383] usbcore: registered new interface driver usb-storage
[  203.612425] scsi host4: uas
[  203.615418] usbcore: registered new interface driver uas
[  203.620979] scsi 4:0:0:0: Direct-Access ST4000NM 0033-9ZM170 
 0001 PQ: 0 ANSI: 6

[  203.630240] sd 4:0:0:0: Attached scsi generic sg1 type 0
[  203.630382] sd 4:0:0:0: [sdb] 7814037168 512-byte logical blocks: 
(4.00 TB/3.63 TiB)

[  203.631338] sd 4:0:0:0: [sdb] Write Protect is off
[  203.631342] sd 4:0:0:0: [sdb] Mode Sense: 67 00 10 08
[  203.631734] sd 4:0:0:0: [sdb] Write cache: enabled, read cache: 
enabled, supports DPO and FUA
[  203.631899] xhci_hcd :00:11.0: ERROR Transfer event for disabled 
endpoint or incorrect stream ring
[  203.631904] xhci_hcd :00:11.0: @001f610a1c10  
 1b00 03078001 state 14 ep_info 9403

[  203.631906] xhci_hcd :00:11.0: No epring
[  203.674546]  sdb: sdb1
[  203.676639] sd 4:0:0:0: [sdb] Attached SCSI disk
[  213.222913] scsi host4: uas_post_reset: alloc streams error -19 after 
reset

[  213.230548] sd 4:0:0:0: [sdb] Synchronizing SCSI cache

Above is the dmesg without the unusual_uas patch applied.
Do you need me to enable any specific dev_dbg and then the dmesg output?



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: JMS56x not working reliably with uas driver

2016-12-21 Thread George Cherian



On 12/21/2016 05:50 PM, Hans de Goede wrote:

Hi,

On 21-12-16 13:07, George Cherian wrote:



On 12/21/2016 05:12 PM, Oliver Neukum wrote:

On Wed, 2016-12-21 at 17:09 +0530, George Cherian wrote:

Hi Oliver,

I was working with this JMicron device and using the uas driver.
I am seeing the following 2 issues.

1) On connect I see the following messages.


Thanks. Do you want to submit it to Greg?
The patch is fine.

Yes please!!!




2) On disconnect I am seeing the following issue

   scsi host4: uas_post_reset: alloc streams error -19 after reset
   sd 4:0:0:0: [sdb] Synchronizing SCSI cache

This is more fatal because after these messages the USB port becomes
unusable. Even an lsusb invocation hangs for ever.


Ouch. That points to a logic error. We should not reset if
a device is gone.
Could you send dmesg of such a case?

here is the dmesg!!
[  203.475382] usb 4-1.3: new SuperSpeed USB device number 3 using
xhci_hcd
[  203.496172] usb 4-1.3: New USB device found, idVendor=152d,
idProduct=9561
[  203.503037] usb 4-1.3: New USB device strings: Mfr=1, Product=2,
SerialNumber=5
[  203.510352] usb 4-1.3: Product: JMS56x Series
[  203.514698] usb 4-1.3: Manufacturer: JMicron
[  203.518966] usb 4-1.3: SerialNumber: 
[  203.594383] usbcore: registered new interface driver usb-storage
[  203.612425] scsi host4: uas
[  203.615418] usbcore: registered new interface driver uas
[  203.620979] scsi 4:0:0:0: Direct-Access ST4000NM 0033-9ZM170
0001 PQ: 0 ANSI: 6
[  203.630240] sd 4:0:0:0: Attached scsi generic sg1 type 0
[  203.630382] sd 4:0:0:0: [sdb] 7814037168 512-byte logical blocks:
(4.00 TB/3.63 TiB)
[  203.631338] sd 4:0:0:0: [sdb] Write Protect is off
[  203.631342] sd 4:0:0:0: [sdb] Mode Sense: 67 00 10 08
[  203.631734] sd 4:0:0:0: [sdb] Write cache: enabled, read cache:
enabled, supports DPO and FUA
[  203.631899] xhci_hcd :00:11.0: ERROR Transfer event for
disabled endpoint or incorrect stream ring
[  203.631904] xhci_hcd :00:11.0: @001f610a1c10 
 1b00 03078001 state 14 ep_info 9403
[  203.631906] xhci_hcd :00:11.0: No epring
[  203.674546]  sdb: sdb1
[  203.676639] sd 4:0:0:0: [sdb] Attached SCSI disk
[  213.222913] scsi host4: uas_post_reset: alloc streams error -19
after reset
[  213.230548] sd 4:0:0:0: [sdb] Synchronizing SCSI cache

Above is the dmesg without the unusual_uas patch applied.
Do you need me to enable any specific dev_dbg and then the dmesg output?


Can you get us a dmesg with the unusual_uas patch applied? Usually once
things go foobar because
of issue-ing a command which the device does not understand, more things
typically come down
as both the device and the host may be in an undefined state then.


Here is the lsusb -t

lsusb -t
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 5000M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 5000M
|__ Port 3: Dev 4, If 0, Class=Mass Storage, Driver=uas, 5000M
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M

lsusb
Bus 003 Device 002: ID 0bda:5401 Realtek Semiconductor Corp. RTL 8153 
USB 3.0 hub with gigabit ethernet

Bus 004 Device 002: ID 0bda:0401 Realtek Semiconductor Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 004 Device 004: ID 152d:9561 JMicron Technology Corp. / JMicron USA 
Technology Corp.

lsusb -v
Bus 004 Device 004: ID 152d:9561 JMicron Technology Corp. / JMicron USA 
Technology Corp.

Device Descriptor:
  bLength18
  bDescriptorType 1
  bcdUSB   3.00
  bDeviceClass0 (Defined at Interface level)
  bDeviceSubClass 0
  bDeviceProtocol 0
  bMaxPacketSize0 9
  idVendor   0x152d JMicron Technology Corp. / JMicron USA 
Technology Corp.

  idProduct  0x9561
  bcdDevice0.01
  iManufacturer   1 JMicron
  iProduct2 JMS56x Series
  iSerial 5 
  bNumConfigurations  1
  Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength  121
bNumInterfaces  1
bConfigurationValue 1
iConfiguration  4 USB Mass Storage
bmAttributes 0xc0
  Self Powered
MaxPower2mA
Interface Descriptor:
  bLength 9
  bDescriptorType 4
  bInterfaceNumber0
  bAlternateSetting   0
  bNumEndpoints   2
  bInterfaceClass 8 Mass

JMS56x not working reliably with uas driver

2016-12-21 Thread George Cherian

Hi Oliver,

I was working with this JMicron device and using the uas driver.
I am seeing the following 2 issues.

1) On connect I see the following messages.
xhci_hcd :00:11.0: ERROR Transfer event for disabled endpoint or 
incorrect stream ring

 This was eliminated using the following scissor patch.

-8<
[PATCH] usb: storage: unusual_uas: Add JMicron JMS56x to unusual device

This device gives the following error on detection.
xhci_hcd :00:11.0: ERROR Transfer event for disabled endpoint or 
incorrect stream ring


The same error is not seen when it is added to unusual_device
list with US_FL_NO_REPORT_OPCODES passed.

Signed-off-by: George Cherian <george.cher...@cavium.com>
---
 drivers/usb/storage/unusual_uas.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/usb/storage/unusual_uas.h 
b/drivers/usb/storage/unusual_uas.h

index cbea9f3..d292299 100644
--- a/drivers/usb/storage/unusual_uas.h
+++ b/drivers/usb/storage/unusual_uas.h
@@ -142,6 +142,13 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x, 0x,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_BROKEN_FUA | US_FL_NO_REPORT_OPCODES),

+/* Reported-by George Cherian <george.cher...@cavium.com> */
+UNUSUAL_DEV(0x152d, 0x9561, 0x, 0x,
+"JMicron",
+"JMS56x",
+USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+US_FL_NO_REPORT_OPCODES),
+
 /* Reported-by: Hans de Goede <hdego...@redhat.com> */
 UNUSUAL_DEV(0x2109, 0x0711, 0x, 0x,
"VIA",
->8

2) On disconnect I am seeing the following issue

 scsi host4: uas_post_reset: alloc streams error -19 after reset
 sd 4:0:0:0: [sdb] Synchronizing SCSI cache

This is more fatal because after these messages the USB port becomes 
unusable. Even an lsusb invocation hangs for ever.


Also please note that the device works fine with usb-storage driver.
I am attaching the usbmon capture of disconnect using uas and 
usb-storage driver.


Any help in this regard is highly appreciated.

Regards,
-George
801f5efb8a00 57530621 C Ii:4:002:1 0:128 1 = 08
801f5efb8a00 57530654 S Ii:4:002:1 -115:128 2 <
801f61285a00 57530677 S Ci:4:002:0 s a3 00  0003 0004 4 <
801f61285a00 57531618 C Ci:4:002:0 0 4 = c1024000
801f61285a00 57531634 S Co:4:002:0 s 23 01 0019 0003  0
801f61285a00 57531992 C Co:4:002:0 0 0
801f61285a00 57532225 S Ci:4:002:0 s a3 00  0003 0004 4 <
801f61285a00 57533010 C Ci:4:002:0 0 4 = c102
801f61285a00 57533022 S Co:4:002:0 s 23 03 001c 0003  0
801f61285a00 57533405 C Co:4:002:0 0 0
801f61285a00 57553165 S Ci:4:002:0 s a3 00  0003 0004 4 <
801f61285a00 57554174 C Ci:4:002:0 0 4 = b102
801f61285a00 57573164 S Ci:4:002:0 s a3 00  0003 0004 4 <
801f61285a00 57574064 C Ci:4:002:0 0 4 = b102
801f61285a00 57593169 S Ci:4:002:0 s a3 00  0003 0004 4 <
801f61285a00 57594214 C Ci:4:002:0 0 4 = b102
801f5efb8a00 57642612 C Ii:4:002:1 0:128 1 = 08
801f5efb8a00 57642621 S Ii:4:002:1 -115:128 2 <
801f5efb8a00 57658612 C Ii:4:002:1 0:128 1 = 08
801f5efb8a00 57658618 S Ii:4:002:1 -115:128 2 <
801f5efb8a00 57674611 C Ii:4:002:1 0:128 1 = 08
801f5efb8a00 57674617 S Ii:4:002:1 -115:128 2 <
801f5efb8a00 57690610 C Ii:4:002:1 0:128 1 = 08
801f5efb8a00 57690615 S Ii:4:002:1 -115:128 2 <
801f5efb8a00 57706609 C Ii:4:002:1 0:128 1 = 08
801f5efb8a00 57706615 S Ii:4:002:1 -115:128 2 <
801f5efb8a00 57722609 C Ii:4:002:1 0:128 1 = 08
801f5efb8a00 57722614 S Ii:4:002:1 -115:128 2 <
801f5efb8a00 57738611 C Ii:4:002:1 0:128 1 = 08
801f5efb8a00 57738616 S Ii:4:002:1 -115:128 2 <
801f5efb8a00 57754610 C Ii:4:002:1 0:128 1 = 08
801f5efb8a00 57754615 S Ii:4:002:1 -115:128 2 <
801f5efb8a00 57770607 C Ii:4:002:1 0:128 1 = 08
801f5efb8a00 57770612 S Ii:4:002:1 -115:128 2 <
801f5efb8a00 57786609 C Ii:4:002:1 0:128 1 = 08
801f5efb8a00 57786614 S Ii:4:002:1 -115:128 2 <
801f5efb8a00 57802608 C Ii:4:002:1 0:128 1 = 08
801f5efb8a00 57802613 S Ii:4:002:1 -115:128 2 <
801f61285a00 57803198 S Ci:4:002:0 s a3 00  0003 0004 4 <
801f61285a00 57804109 C Ci:4:002:0 0 4 = a0020100
801f61285a00 57804122 S Co:4:002:0 s 23 01 0014 0003  0
801f61285a00 57804539 C Co:4:002:0 0 0
801f61285a00 57804553 S Co:4:002:0 s 23 01 001d 0003  0
801f61285a00 57804876 C Co:4:002:0 0 0
801f61285a00 57804890 S Co:4:002:0 s 23 01 0019 0003  0
801f61285a00 57805185 C Co:4:002:0 0 0
801f61285a00 57805199 S Co:4:002:0 s 23 01 0010 0003  0
801f61285a00 57805735 C Co:4:002:0 0 0
801f61285a00 57805749 S Ci:4:002:0 s a3 00  0003 0004 4 <
801f61285a00 57806491

[PATCH v2] usb: dwc3: dwc3-omap: Fix disable IRQ

2015-02-12 Thread George Cherian
In the wrapper the IRQ disable should be done by writing 1's to the
IRQ*_CLR register. Existing code is broken because it instead writes
zeros to IRQ*_SET register.

Fix this by adding functions dwc3_omap_write_irqmisc_clr() and
dwc3_omap_write_irq0_clr() which do the right thing.

Fixes: 72246da40f37 (usb: Introduce DesignWare USB3 DRD Driver)
Cc: sta...@vger.kernel.org # v3.2+
Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 30 --
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 172d64e..52e0c4e 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -205,6 +205,18 @@ static void dwc3_omap_write_irq0_set(struct dwc3_omap 
*omap, u32 value)
omap-irq0_offset, value);
 }
 
+static void dwc3_omap_write_irqmisc_clr(struct dwc3_omap *omap, u32 value)
+{
+   dwc3_omap_writel(omap-base, USBOTGSS_IRQENABLE_CLR_MISC +
+   omap-irqmisc_offset, value);
+}
+
+static void dwc3_omap_write_irq0_clr(struct dwc3_omap *omap, u32 value)
+{
+   dwc3_omap_writel(omap-base, USBOTGSS_IRQENABLE_CLR_0 -
+   omap-irq0_offset, value);
+}
+
 static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
enum omap_dwc3_vbus_id_status status)
 {
@@ -345,9 +357,23 @@ static void dwc3_omap_enable_irqs(struct dwc3_omap *omap)
 
 static void dwc3_omap_disable_irqs(struct dwc3_omap *omap)
 {
+   u32 reg;
+
/* disable all IRQs */
-   dwc3_omap_write_irqmisc_set(omap, 0x00);
-   dwc3_omap_write_irq0_set(omap, 0x00);
+   reg = USBOTGSS_IRQO_COREIRQ_ST;
+   dwc3_omap_write_irq0_clr(omap, reg);
+
+   reg = (USBOTGSS_IRQMISC_OEVT |
+   USBOTGSS_IRQMISC_DRVVBUS_RISE |
+   USBOTGSS_IRQMISC_CHRGVBUS_RISE |
+   USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
+   USBOTGSS_IRQMISC_IDPULLUP_RISE |
+   USBOTGSS_IRQMISC_DRVVBUS_FALL |
+   USBOTGSS_IRQMISC_CHRGVBUS_FALL |
+   USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
+   USBOTGSS_IRQMISC_IDPULLUP_FALL);
+
+   dwc3_omap_write_irqmisc_clr(omap, reg);
 }
 
 static u64 dwc3_omap_dma_mask = DMA_BIT_MASK(32);
-- 
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: dwc3: dwc3-omap: Fix disable IRQ

2015-02-12 Thread George Cherian


On 02/12/2015 11:52 PM, Felipe Balbi wrote:

On Thu, Feb 12, 2015 at 11:13:16AM +0530, George Cherian wrote:

In the wrapper the IRQ disable should be done by writing 1's to the
IRQ*_CLR register. Existing code is broken because it instead writes
zeros to IRQ*_SET register.

Fix this by adding functions dwc3_omap_write_irqmisc_clr() and
dwc3_omap_write_irq0_clr() which do the right thing.

Signed-off-by: George Cheriangeorge.cher...@ti.com

please resend with:

Fixes: 72246da40f37 (usb: Introduce DesignWare USB3 DRD Driver)
Cc:sta...@vger.kernel.org  # v3.2+

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


[PATCH] usb: dwc3: dwc3-omap: Fix disable IRQ

2015-02-11 Thread George Cherian
In the wrapper the IRQ disable should be done by writing 1's to the
IRQ*_CLR register. Existing code is broken because it instead writes
zeros to IRQ*_SET register.

Fix this by adding functions dwc3_omap_write_irqmisc_clr() and
dwc3_omap_write_irq0_clr() which do the right thing.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 30 --
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 172d64e..52e0c4e 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -205,6 +205,18 @@ static void dwc3_omap_write_irq0_set(struct dwc3_omap 
*omap, u32 value)
omap-irq0_offset, value);
 }
 
+static void dwc3_omap_write_irqmisc_clr(struct dwc3_omap *omap, u32 value)
+{
+   dwc3_omap_writel(omap-base, USBOTGSS_IRQENABLE_CLR_MISC +
+   omap-irqmisc_offset, value);
+}
+
+static void dwc3_omap_write_irq0_clr(struct dwc3_omap *omap, u32 value)
+{
+   dwc3_omap_writel(omap-base, USBOTGSS_IRQENABLE_CLR_0 -
+   omap-irq0_offset, value);
+}
+
 static void dwc3_omap_set_mailbox(struct dwc3_omap *omap,
enum omap_dwc3_vbus_id_status status)
 {
@@ -345,9 +357,23 @@ static void dwc3_omap_enable_irqs(struct dwc3_omap *omap)
 
 static void dwc3_omap_disable_irqs(struct dwc3_omap *omap)
 {
+   u32 reg;
+
/* disable all IRQs */
-   dwc3_omap_write_irqmisc_set(omap, 0x00);
-   dwc3_omap_write_irq0_set(omap, 0x00);
+   reg = USBOTGSS_IRQO_COREIRQ_ST;
+   dwc3_omap_write_irq0_clr(omap, reg);
+
+   reg = (USBOTGSS_IRQMISC_OEVT |
+   USBOTGSS_IRQMISC_DRVVBUS_RISE |
+   USBOTGSS_IRQMISC_CHRGVBUS_RISE |
+   USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
+   USBOTGSS_IRQMISC_IDPULLUP_RISE |
+   USBOTGSS_IRQMISC_DRVVBUS_FALL |
+   USBOTGSS_IRQMISC_CHRGVBUS_FALL |
+   USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
+   USBOTGSS_IRQMISC_IDPULLUP_FALL);
+
+   dwc3_omap_write_irqmisc_clr(omap, reg);
 }
 
 static u64 dwc3_omap_dma_mask = DMA_BIT_MASK(32);
-- 
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 2/2] usb: musb: Fix getting a generic phy for musb_dsps

2015-02-08 Thread George Cherian

Hi Tony,
On 02/06/2015 10:53 PM, Tony Lindgren wrote:

* George Cherian george.cher...@ti.com [150206 05:05]:

Hi Tony,

You also need to add similar things in dsps_musb_reset();

Otherwise you might not recover from a BABBLE condition.

Thank I totally missed that, updated patch below.

Do you have some testcase that easily triggers BABBLE
on MUSB?

On a BBB or BBW you can connect a HUB with multiple device connected on HUB.
Then do a repeated Connect and Disconnect of the HUB, This should 
trigger a BABBLE interrupt.

Not all HUB's might not lead you to a BABBLE condition.


Regards,

Tony

8 --
From: Tony Lindgren t...@atomide.com
Date: Wed, 4 Feb 2015 06:28:49 -0800
Subject: [PATCH] usb: musb: Fix getting a generic phy for musb_dsps

We still have a combination of legacy phys and generic phys in
use so we need to support both types of phy for musb_dsps.c.

Cc: Brian Hutchinson b.hutch...@gmail.com
Signed-off-by: Tony Lindgren t...@atomide.com

--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -457,12 +457,27 @@ static int dsps_musb_init(struct musb *musb)
if (IS_ERR(musb-xceiv))
return PTR_ERR(musb-xceiv);
  
+	musb-phy = devm_phy_get(dev-parent, usb2-phy);

+
/* Returns zero if e.g. not clocked */
rev = dsps_readl(reg_base, wrp-revision);
if (!rev)
return -ENODEV;
  
  	usb_phy_init(musb-xceiv);

+   if (IS_ERR(musb-phy))  {
+   musb-phy = NULL;
+   } else {
+   ret = phy_init(musb-phy);
+   if (ret  0)
+   return ret;
+   ret = phy_power_on(musb-phy);
+   if (ret) {
+   phy_exit(musb-phy);
+   return ret;
+   }
+   }
+
setup_timer(glue-timer, otg_timer, (unsigned long) musb);
  
  	/* Reset the musb */

@@ -502,6 +517,8 @@ static int dsps_musb_exit(struct musb *musb)
  
  	del_timer_sync(glue-timer);

usb_phy_shutdown(musb-xceiv);
+   phy_power_off(musb-phy);
+   phy_exit(musb-phy);
debugfs_remove_recursive(glue-dbgfs_root);
  
  	return 0;

@@ -610,7 +627,7 @@ static int dsps_musb_reset(struct musb *musb)
struct device *dev = musb-controller;
struct dsps_glue *glue = dev_get_drvdata(dev-parent);
const struct dsps_musb_wrapper *wrp = glue-wrp;
-   int session_restart = 0;
+   int session_restart = 0, error;
  
  	if (glue-sw_babble_enabled)

session_restart = sw_babble_control(musb);
@@ -624,8 +641,14 @@ static int dsps_musb_reset(struct musb *musb)
dsps_writel(musb-ctrl_base, wrp-control, (1  wrp-reset));
usleep_range(100, 200);
usb_phy_shutdown(musb-xceiv);
+   error = phy_power_off(musb-phy);
+   if (error)
+   dev_err(dev, phy shutdown failed: %i\n, error);
usleep_range(100, 200);
usb_phy_init(musb-xceiv);
+   error = phy_power_on(musb-phy);
+   if (error)
+   dev_err(dev, phy powerup failed: %i\n, error);
session_restart = 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 2/2] usb: musb: Fix getting a generic phy for musb_dsps

2015-02-06 Thread George Cherian

Hi Tony,

You also need to add similar things in dsps_musb_reset();

Otherwise you might not recover from a BABBLE condition.

On 02/05/2015 10:05 PM, Tony Lindgren wrote:

We still have a combination of legacy phys and generic phys in
use so we need to support both types of phy for musb_dsps.c.

Cc: Brian Hutchinson b.hutch...@gmail.com
Signed-off-by: Tony Lindgren t...@atomide.com
---
  drivers/usb/musb/musb_dsps.c | 17 +
  1 file changed, 17 insertions(+)

--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -457,12 +457,25 @@ static int dsps_musb_init(struct musb *musb)
if (IS_ERR(musb-xceiv))
return PTR_ERR(musb-xceiv);
  
+	musb-phy = devm_phy_get(dev-parent, usb2-phy);

+
/* Returns zero if e.g. not clocked */
rev = dsps_readl(reg_base, wrp-revision);
if (!rev)
return -ENODEV;
  
  	usb_phy_init(musb-xceiv);

+   if (IS_ERR(musb-phy))  {
+   musb-phy = NULL;
+   } else {
+   ret = phy_init(musb-phy);
+   if (ret  0)
+   return ret;
+   ret = phy_power_on(musb-phy);
+   if (ret)
+   return ret;
+   }
+
setup_timer(glue-timer, otg_timer, (unsigned long) musb);
  
  	/* Reset the musb */

@@ -502,6 +515,10 @@ static int dsps_musb_exit(struct musb *musb)
  
  	del_timer_sync(glue-timer);

usb_phy_shutdown(musb-xceiv);
+   if (musb-phy) {
+   phy_power_off(musb-phy);
+   phy_exit(musb-phy);
+   }
debugfs_remove_recursive(glue-dbgfs_root);
  
  	return 0;

-George

--
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 17/19] arm: dts: dra7: Add named interrupt property for dwc3

2014-11-25 Thread George Cherian
Add interrupt names so that the same can be used for OTG easily.

Signed-off-by: George Cherian george.cher...@ti.com
---
 arch/arm/boot/dts/dra7.dtsi | 28 
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 9cc9843..78f1761 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1153,7 +1153,12 @@
usb1: usb@4889 {
compatible = snps,dwc3;
reg = 0x4889 0x17000;
-   interrupts = GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH;
+   interrupts = GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH,
+GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH,
+GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH;
+   interrupt-names = peripheral,
+ host,
+ otg;
phys = usb2_phy1, usb3_phy1;
phy-names = usb2-phy, usb3-phy;
tx-fifo-resize;
@@ -1174,7 +1179,12 @@
usb2: usb@488d {
compatible = snps,dwc3;
reg = 0x488d 0x17000;
-   interrupts = GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH;
+   interrupts = GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH,
+GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH,
+GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH;
+   interrupt-names = peripheral,
+ host,
+ otg;
phys = usb2_phy2;
phy-names = usb2-phy;
tx-fifo-resize;
@@ -1197,7 +1207,12 @@
usb3: usb@4891 {
compatible = snps,dwc3;
reg = 0x4891 0x17000;
-   interrupts = GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH;
+   interrupts = GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH,
+GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH,
+GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH;
+   interrupt-names = peripheral,
+ host,
+ otg;
tx-fifo-resize;
maximum-speed = high-speed;
dr_mode = otg;
@@ -1217,7 +1232,12 @@
usb4: usb@4895 {
compatible = snps,dwc3;
reg = 0x4895 0x17000;
-   interrupts = GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH;
+   interrupts = GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH,
+GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH,
+GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH;
+   interrupt-names = peripheral,
+ host,
+ otg;
tx-fifo-resize;
maximum-speed = high-speed;
dr_mode = otg;
-- 
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


[PATCH 19/19] arm: dts: am43x evms: Make usb1 as OTG

2014-11-25 Thread George Cherian
USB1 of am43x EPOS EVM, am437x GP EVM and am437x SK EVM can be used as OTG.
Enable the same.

Signed-off-by: George Cherian george.cher...@ti.com
---
 arch/arm/boot/dts/am437x-gp-evm.dts  | 2 +-
 arch/arm/boot/dts/am437x-sk-evm.dts  | 2 +-
 arch/arm/boot/dts/am43x-epos-evm.dts | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts 
b/arch/arm/boot/dts/am437x-gp-evm.dts
index e7ac47f..a8b5752 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -380,7 +380,7 @@
 };
 
 usb1 {
-   dr_mode = peripheral;
+   dr_mode = otg;
status = okay;
 };
 
diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts 
b/arch/arm/boot/dts/am437x-sk-evm.dts
index 859ff3d..b258826 100644
--- a/arch/arm/boot/dts/am437x-sk-evm.dts
+++ b/arch/arm/boot/dts/am437x-sk-evm.dts
@@ -478,7 +478,7 @@
 };
 
 usb1 {
-   dr_mode = peripheral;
+   dr_mode = otg;
status = okay;
 };
 
diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts 
b/arch/arm/boot/dts/am43x-epos-evm.dts
index ac3e485..3d106e9 100644
--- a/arch/arm/boot/dts/am43x-epos-evm.dts
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -542,7 +542,7 @@
 };
 
 usb1 {
-   dr_mode = peripheral;
+   dr_mode = otg;
status = okay;
 };
 
-- 
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


[PATCH 18/19] arm: dts: exynos5250: Add named interrupt property for dwc3

2014-11-25 Thread George Cherian
Add interrupt names so that the same can be used for OTG easily.

Signed-off-by: George Cherian george.cher...@ti.com
---
 arch/arm/boot/dts/exynos5250.dtsi | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi 
b/arch/arm/boot/dts/exynos5250.dtsi
index f21b9aa..c74cd8b 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -558,7 +558,12 @@
dwc3 {
compatible = synopsys,dwc3;
reg = 0x1200 0x1;
-   interrupts = 0 72 0;
+   interrupts = 0 72 0,
+0 72 0,
+0 72 0;
+   interrupt-names = peripheral,
+ host,
+ otg;
phys = usbdrd_phy 0, usbdrd_phy 1;
phy-names = usb2-phy, usb3-phy;
};
-- 
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


[PATCH 11/19] usb: dwc3: Add seperate dwc3_gadget object to support gadget release

2014-11-25 Thread George Cherian
With the current implementation it's impossible to release the gadget.
Add a separate dwc3_gadget object to dwc3 structure so that the same
can be freed during the gadget release.
This is in prepration to adapt dwc3 gadget driver to  drd library.
DRD library uses usb_del/add_gadget_udc while switching roles between
HOST and DEVICE modes. If the usb_gadget is not released during 
usb_del_gadget_udc,
the subsequent usb_add_gadget_udc would try to initialize an already initialized
kobject. To avoid this make sure we have an easily freeable object.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/core.h   |   7 ++-
 drivers/usb/dwc3/ep0.c|  35 --
 drivers/usb/dwc3/gadget.c | 113 ++
 drivers/usb/dwc3/gadget.h |   1 +
 4 files changed, 101 insertions(+), 55 deletions(-)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 7c5ae37..7fbe736 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -626,6 +626,11 @@ struct dwc3_scratchpad_array {
__le64  dma_adr[DWC3_MAX_HIBER_SCRATCHBUFS];
 };
 
+struct dwc3_gadget {
+   struct usb_gadget gadget;
+   struct dwc3 *dwc;
+};
+
 /**
  * struct dwc3 - representation of our controller
  * @ctrl_req: usb control request which is used for ep0
@@ -736,7 +741,7 @@ struct dwc3 {
struct dwc3_event_buffer **ev_buffs;
struct dwc3_ep  *eps[DWC3_ENDPOINTS_NUM];
 
-   struct usb_gadget   gadget;
+   struct dwc3_gadget  *dwc_gadget;
struct usb_gadget_driver *gadget_driver;
 
struct usb_phy  *usb2_phy;
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index baeedbd..e7409f1 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -109,6 +109,7 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
struct dwc3_request *req)
 {
struct dwc3 *dwc = dep-dwc;
+   struct dwc3_gadget  *dwc_gadget = dwc-dwc_gadget;
 
req-request.actual = 0;
req-request.status = -EINPROGRESS;
@@ -152,7 +153,7 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
 
direction = !dwc-ep0_expect_in;
dwc-delayed_status = false;
-   usb_gadget_set_state(dwc-gadget, USB_STATE_CONFIGURED);
+   usb_gadget_set_state(dwc_gadget-gadget, USB_STATE_CONFIGURED);
 
if (dwc-ep0state == EP0_STATUS_PHASE)
__dwc3_ep0_do_control_status(dwc, dwc-eps[direction]);
@@ -391,6 +392,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
struct usb_ctrlrequest *ctrl, int set)
 {
struct dwc3_ep  *dep;
+   struct dwc3_gadget  *dwc_gadget = dwc-dwc_gadget;
u32 recip;
u32 wValue;
u32 wIndex;
@@ -401,7 +403,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
wValue = le16_to_cpu(ctrl-wValue);
wIndex = le16_to_cpu(ctrl-wIndex);
recip = ctrl-bRequestType  USB_RECIP_MASK;
-   state = dwc-gadget.state;
+   state = dwc_gadget-gadget.state;
 
switch (recip) {
case USB_RECIP_DEVICE:
@@ -499,7 +501,8 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
 
 static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
 {
-   enum usb_device_state state = dwc-gadget.state;
+   struct dwc3_gadget *dwc_gadget = dwc-dwc_gadget;
+   enum usb_device_state state = dwc_gadget-gadget.state;
u32 addr;
u32 reg;
 
@@ -521,26 +524,28 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct 
usb_ctrlrequest *ctrl)
dwc3_writel(dwc-regs, DWC3_DCFG, reg);
 
if (addr)
-   usb_gadget_set_state(dwc-gadget, USB_STATE_ADDRESS);
+   usb_gadget_set_state(dwc_gadget-gadget, USB_STATE_ADDRESS);
else
-   usb_gadget_set_state(dwc-gadget, USB_STATE_DEFAULT);
+   usb_gadget_set_state(dwc_gadget-gadget, USB_STATE_DEFAULT);
 
return 0;
 }
 
 static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest 
*ctrl)
 {
+   struct dwc3_gadget *dwc_gadget = dwc-dwc_gadget;
int ret;
 
spin_unlock(dwc-lock);
-   ret = dwc-gadget_driver-setup(dwc-gadget, ctrl);
+   ret = dwc-gadget_driver-setup(dwc_gadget-gadget, ctrl);
spin_lock(dwc-lock);
return ret;
 }
 
 static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
 {
-   enum usb_device_state state = dwc-gadget.state;
+   struct dwc3_gadget *dwc_gadget = dwc-dwc_gadget;
+   enum usb_device_state state = dwc_gadget-gadget.state;
u32 cfg;
int ret;
u32 reg;
@@ -564,8 +569,8 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct 
usb_ctrlrequest *ctrl)
 * to change the state on the next usb_ep_queue

[PATCH 13/19] usb: dwc3: core: Add DWC3 OTG specific register defines

2014-11-25 Thread George Cherian
Add OTG reggister defines to DWC3 core.h

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/core.h | 68 +
 1 file changed, 68 insertions(+)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 7fbe736..eb2e970 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -381,6 +381,74 @@
 #define DWC3_DEPCMD_TYPE_BULK  2
 #define DWC3_DEPCMD_TYPE_INTR  3
 
+/* OTG Configuration Register */
+#define DWC3_OCFG_DISPWRCUTTOFF(1  5)
+#define DWC3_OCFG_HIBDISMASK   (1  4)
+#define DWC3_OCFG_SFTRSTMASK   (1  3)
+#define DWC3_OCFG_OTGVERSION   (1  2)
+#define DWC3_OCFG_HNPCAP   (1  1)
+#define DWC3_OCFG_SRPCAP   (1  0)
+
+/* OTG CTL Register */
+#define DWC3_OCTL_OTG3GOERR(1  7)
+#define DWC3_OCTL_PERIMODE (1  6)
+#define DWC3_OCTL_PRTPWRCTL(1  5)
+#define DWC3_OCTL_HNPREQ   (1  4)
+#define DWC3_OCTL_SESREQ   (1  3)
+#define DWC3_OCTL_TERMSELIDPULSE   (1  2)
+#define DWC3_OCTL_DEVSETHNPEN  (1  1)
+#define DWC3_OCTL_HOSTSETHNPEN (1  0)
+
+/* OTG Event Register */
+#define DWC3_OEVT_DEVICEMODE   (1  31)
+#define DWC3_OEVT_XHCIRUNSTPSET(1  27)
+#define DWC3_OEVT_DEVRUNSTPSET (1  26)
+#define DWC3_OEVT_HIBENTRY (1  25)
+#define DWC3_OEVT_IDSTSCHNG(1  24)
+#define DWC3_OEVT_HRRCONFNOTIF (1  23)
+#define DWC3_OEVT_HRRINITNOTIF (1  22)
+#define DWC3_OEVT_ADEVIDLE (1  21)
+#define DWC3_OEVT_ADEVBHOSTEND (1  20)
+#define DWC3_OEVT_ADEVHOST (1  19)
+#define DWC3_OEVT_ADEVHNPCHNG  (1  18)
+#define DWC3_OEVT_ADEVSRPDET   (1  17)
+#define DWC3_OEVT_ADEVSESSENDDET   (1  16)
+#define DWC3_OEVT_BDEVBHOSTEND (1  11)
+#define DWC3_OEVT_BDEVHNPCHNG  (1  10)
+#define DWC3_OEVT_BDEVSESSVLDDET   (1  9)
+#define DWC3_OEVT_BDEVVBUSCHNG (1  8)
+#define DWC3_OEVT_BSESSVLD (1  3)
+#define DWC3_OEVT_HOSTNEGSTS   (1  2)
+#define DWC3_OEVT_SESSREQSTS   (1  1)
+#define DWC3_OEVT_ERR  (1  0)
+
+/* OTG Event Enable Register */
+#define DWC3_OEVTEN_XHCIRUNSTPSETEN(1  27)
+#define DWC3_OEVTEN_DEVRUNSTPSETEN (1  26)
+#define DWC3_OEVTEN_HIBENTRYEN (1  25)
+#define DWC3_OEVTEN_CONIDSTSCHNGEN (1  24)
+#define DWC3_OEVTEN_HRRCONFNOTIFEN (1  23)
+#define DWC3_OEVTEN_HRRINITNOTIFEN (1  22)
+#define DWC3_OEVTEN_ADEVIDLEEN (1  21)
+#define DWC3_OEVTEN_ADEVBHOSTENDEN (1  20)
+#define DWC3_OEVTEN_ADEVHOSTEN (1  19)
+#define DWC3_OEVTEN_ADEVHNPCHNGEN  (1  18)
+#define DWC3_OEVTEN_ADEVSRPDETEN   (1  17)
+#define DWC3_OEVTEN_ADEVSESSENDDETEN   (1  16)
+#define DWC3_OEVTEN_BDEVHOSTENDEN  (1  11)
+#define DWC3_OEVTEN_BDEVHNPCHNGEN  (1  10)
+#define DWC3_OEVTEN_BDEVSESSVLDDETEN   (1  9)
+#define DWC3_OEVTEN_BDEVVBUSCHNGEVNTEN (1  8)
+
+/* OTG Status Register */
+#define DWC3_OSTS_DEVRUNSTP(1  13)
+#define DWC3_OSTS_XHCIRUNSTP   (1  12)
+#define DWC3_OSTS_PERIPHERALSTATE  (1  4)
+#define DWC3_OSTS_XHCIPORTPOWER(1  3)
+#define DWC3_OSTS_BSESVLD  (1  2)
+#define DWC3_OSTS_VBUSVLD  (1  1)
+#define DWC3_OSTS_CONIDSTS (1  0)
+
 /* Structures */
 
 struct dwc3_trb;
-- 
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


[PATCH 15/19] arm: dts: am4372: Add named interrupt property for dwc3

2014-11-25 Thread George Cherian
From: Felipe Balbi ba...@ti.com

Add interrupt names so that the same can be used for OTG easily.

Signed-off-by: Felipe Balbi ba...@ti.com
Signed-off-by: George Cherian george.cher...@ti.com
---
 arch/arm/boot/dts/am4372.dtsi | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index e19068d..3dda4c8 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -810,8 +810,13 @@
 
usb1: usb@4839 {
compatible = synopsys,dwc3;
-   reg = 0x4839 0x1;
-   interrupts = GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH;
+   reg = 0x4839 0x17000;
+   interrupts = GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH,
+GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH,
+GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH;
+   interrupt-names = peripheral,
+ host,
+ otg;
phys = usb2_phy1;
phy-names = usb2-phy;
maximum-speed = high-speed;
@@ -834,8 +839,13 @@
 
usb2: usb@483d {
compatible = synopsys,dwc3;
-   reg = 0x483d 0x1;
-   interrupts = GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH;
+   reg = 0x483d 0x17000;
+   interrupts = GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH,
+GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH,
+GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH;
+   interrupt-names = peripheral,
+ host,
+ otg;
phys = usb2_phy2;
phy-names = usb2-phy;
maximum-speed = high-speed;
-- 
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


[PATCH 12/19] usb: dwc3: gadget: Adapt gadget to drd library

2014-11-25 Thread George Cherian
Adapt the dwc3 gadget to use drd library functions.
In prepration to support DRD on dwc3.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/gadget.c | 128 --
 1 file changed, 100 insertions(+), 28 deletions(-)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 2c54d45..a75fae5 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -29,6 +29,7 @@
 
 #include linux/usb/ch9.h
 #include linux/usb/gadget.h
+#include linux/usb/drd.h
 
 #include debug.h
 #include core.h
@@ -2681,6 +2682,89 @@ static irqreturn_t dwc3_interrupt(int irq, void *_dwc)
return ret;
 }
 
+void dwc3_gadget_release(struct device *dev)
+{
+   struct usb_gadget *gadget = container_of(dev, struct usb_gadget, dev);
+   struct dwc3_gadget *dwc_gadget = gadget_to_dwc_gadget(gadget);
+   struct dwc3 *dwc = dwc_gadget-dwc;
+
+   dev_dbg(dev, releasing '%s'\n, dev_name(dev));
+   dwc3_gadget_free_endpoints(dwc);
+   dma_free_coherent(dwc-dev, DWC3_EP0_BOUNCE_SIZE,
+ dwc-ep0_bounce, dwc-ep0_bounce_addr);
+   kfree(dwc-setup_buf);
+   dma_free_coherent(dwc-dev, sizeof(*dwc-ep0_trb),
+ dwc-ep0_trb, dwc-ep0_trb_addr);
+   dma_free_coherent(dwc-dev, sizeof(*dwc-ctrl_req),
+ dwc-ctrl_req, dwc-ctrl_req_addr);
+   usb_drd_unregister_udc(dwc-dev);
+   kfree(dwc_gadget);
+}
+
+int dwc3_gadget_setup(void *data)
+{
+   struct dwc3 *dwc = data;
+   struct dwc3_gadget *dwc_gadget;
+   struct usb_drd_gadget *drd_gadget;
+   struct usb_drd_setup *gadget_setup;
+   int ret;
+
+   drd_gadget = kzalloc(sizeof(*drd_gadget), GFP_KERNEL);
+   if (!drd_gadget) {
+   ret = -ENOMEM;
+   goto err1;
+   }
+
+   gadget_setup = kzalloc(sizeof(*gadget_setup), GFP_KERNEL);
+   if (!gadget_setup) {
+   ret = -ENOMEM;
+   goto err2;
+   }
+
+   dwc_gadget = kzalloc(sizeof(*dwc_gadget), GFP_KERNEL);
+   if (!dwc_gadget) {
+   ret = -ENOMEM;
+   goto err3;
+   }
+
+   drd_gadget-g_driver = dwc-gadget_driver;
+
+   /*
+* Pass the DWC3 specific routines for
+* switching roles to the drd library
+*/
+   gadget_setup-ll_start = NULL;
+   gadget_setup-ll_stop = NULL;
+   gadget_setup-ll_release = dwc3_gadget_release;
+   gadget_setup-data =  (void *)dwc;
+   drd_gadget-gadget_setup = gadget_setup;
+
+   dwc_gadget-gadget.ops  = dwc3_gadget_ops;
+   dwc_gadget-gadget.max_speed= USB_SPEED_SUPER;
+   dwc_gadget-gadget.speed= USB_SPEED_UNKNOWN;
+   dwc_gadget-gadget.sg_supported = true;
+   dwc_gadget-gadget.name = dwc3-gadget;
+   dwc_gadget-dwc = dwc;
+   drd_gadget-gadget = dwc_gadget-gadget;
+
+   /*
+* Per databook, DWC3 needs buffer size to be aligned to MaxPacketSize
+* on ep out.
+*/
+   dwc_gadget-gadget.quirk_ep_out_aligned_size = true;
+   dwc-dwc_gadget = dwc_gadget;
+   usb_drd_register_udc(dwc-dev, drd_gadget);
+
+   return 0;
+
+err3:
+   kfree(gadget_setup);
+err2:
+   kfree(drd_gadget);
+err1:
+   return ret;
+}
+
 /**
  * dwc3_gadget_init - Initializes gadget related registers
  * @dwc: pointer to our controller context structure
@@ -2690,7 +2774,6 @@ static irqreturn_t dwc3_interrupt(int irq, void *_dwc)
 int dwc3_gadget_init(struct dwc3 *dwc)
 {
int ret;
-   struct dwc3_gadget  *dwc_gadget;
 
dwc-ctrl_req = dma_alloc_coherent(dwc-dev, sizeof(*dwc-ctrl_req),
dwc-ctrl_req_addr, GFP_KERNEL);
@@ -2723,24 +2806,9 @@ int dwc3_gadget_init(struct dwc3 *dwc)
goto err3;
}
 
-   dwc_gadget = kzalloc(sizeof(*dwc_gadget), GFP_KERNEL);
-   if (!dwc_gadget) {
-   ret = -ENOMEM;
+   ret = dwc3_gadget_setup(dwc);
+   if (ret)
goto err3;
-   }
-
-   dwc_gadget-gadget.ops  = dwc3_gadget_ops;
-   dwc_gadget-gadget.max_speed= USB_SPEED_SUPER;
-   dwc_gadget-gadget.speed= USB_SPEED_UNKNOWN;
-   dwc_gadget-gadget.sg_supported = true;
-   dwc_gadget-gadget.name = dwc3-gadget;
-   dwc_gadget-dwc = dwc;
-
-   /*
-* Per databook, DWC3 needs buffer size to be aligned to MaxPacketSize
-* on ep out.
-*/
-   dwc_gadget-gadget.quirk_ep_out_aligned_size = true;
 
/*
 * REVISIT: Here we should clear all pending IRQs to be
@@ -2751,7 +2819,8 @@ int dwc3_gadget_init(struct dwc3 *dwc)
if (ret)
goto err4;
 
-   ret = usb_add_gadget_udc(dwc-dev, dwc_gadget-gadget);
+   ret = usb_add_gadget_udc_release(dwc

[PATCH 14/19] usb: dwc3: otg: Add the initial otg driver for dwc3.

2014-11-25 Thread George Cherian
Add the Initial OTG driver for dwc3.
Currently support only
* ID based Role switching.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/Makefile |   4 ++
 drivers/usb/dwc3/core.c   |  10 +---
 drivers/usb/dwc3/core.h   |  10 
 drivers/usb/dwc3/otg.c| 126 ++
 4 files changed, 142 insertions(+), 8 deletions(-)
 create mode 100644 drivers/usb/dwc3/otg.c

diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index bb34fbc..fe7af97 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -12,6 +12,10 @@ ifneq ($(filter y,$(CONFIG_USB_DWC3_HOST) 
$(CONFIG_USB_DWC3_DUAL_ROLE)),)
dwc3-y  += host.o
 endif
 
+ifneq ($(CONFIG_USB_DWC3_DUAL_ROLE),)
+   dwc3-y  += otg.o
+endif
+
 ifneq ($(filter y,$(CONFIG_USB_DWC3_GADGET) $(CONFIG_USB_DWC3_DUAL_ROLE)),)
dwc3-y  += gadget.o ep0.o
 endif
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index dbd5589..dd4af3f 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -685,15 +685,9 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
break;
case USB_DR_MODE_OTG:
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
-   ret = dwc3_host_init(dwc);
-   if (ret) {
-   dev_err(dev, failed to initialize host\n);
-   return ret;
-   }
-
-   ret = dwc3_gadget_init(dwc);
+   ret = dwc3_otg_init(dwc);
if (ret) {
-   dev_err(dev, failed to initialize gadget\n);
+   dev_err(dev, failed to initialize otg\n);
return ret;
}
break;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index eb2e970..001d77d 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1103,6 +1103,16 @@ static inline int 
dwc3_send_gadget_generic_command(struct dwc3 *dwc,
 { return 0; }
 #endif
 
+#if IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
+int dwc3_otg_init(struct dwc3 *dwc);
+void dwc3_otg_exit(struct dwc3 *dwc);
+#else
+static inline int dwc3_otg_init(struct dwc3 *dwc)
+{ return 0; }
+static inline void dwc3_otg_exit(struct dwc3 *dwc)
+{ }
+#endif
+
 /* power management interface */
 #if !IS_ENABLED(CONFIG_USB_DWC3_HOST)
 int dwc3_gadget_suspend(struct dwc3 *dwc);
diff --git a/drivers/usb/dwc3/otg.c b/drivers/usb/dwc3/otg.c
new file mode 100644
index 000..b5c31c0
--- /dev/null
+++ b/drivers/usb/dwc3/otg.c
@@ -0,0 +1,126 @@
+/**
+ * otg.c - DesignWare USB3 DRD Controller OTG
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Authors: George Cherian george.cher...@ti.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include linux/module.h
+#include linux/kernel.h
+#include linux/platform_device.h
+#include linux/interrupt.h
+#include linux/usb.h
+#include linux/usb/hcd.h
+
+#include linux/usb/drd.h
+#include core.h
+#include io.h
+
+#define DWC3_GSTS_OTG_IP (1  10)
+
+static irqreturn_t dwc3_otg_interrupt(int irq , void *_dwc)
+{
+   struct dwc3 *dwc = _dwc;
+   u32 reg;
+
+   spin_lock(dwc-lock);
+   reg = dwc3_readl(dwc-regs, DWC3_GSTS);
+   if (reg  DWC3_GSTS_OTG_IP) {
+   reg = dwc3_readl(dwc-regs, DWC3_OEVT);
+   dev_vdbg(dwc-dev, OTG Interrupt %x\n, reg);
+   dwc3_writel(dwc-regs, DWC3_OEVT, reg);
+   spin_unlock(dwc-lock);
+   return IRQ_WAKE_THREAD;
+   }
+
+   spin_unlock(dwc-lock);
+   return IRQ_NONE;
+}
+
+static irqreturn_t dwc3_otg_thread_interrupt(int irq, void *_dwc)
+{
+   struct dwc3 *dwc = _dwc;
+   u32 reg = dwc3_readl(dwc-regs, DWC3_OSTS);
+
+   dev_vdbg(dwc-dev, OTG thread interrupt\n);
+   if ((reg  DWC3_OSTS_CONIDSTS)) {
+   usb_drd_stop_hcd(dwc-dev);
+   dwc3_writel(dwc-regs, DWC3_OCFG, DWC3_OCFG_SFTRSTMASK);
+   dwc3_writel(dwc-regs, DWC3_OCTL,
+   DWC3_OCTL_SESREQ | DWC3_OCTL_PERIMODE);
+   if (usb_drd_get_state(dwc-dev)  DRD_DEVICE_REGISTERED) {
+   usb_drd_start_udc(dwc-dev);
+   } else {
+   dwc3_core_gadget_helper(dwc);
+   dwc3_gadget_init(dwc);
+   }
+   dwc3_writel(dwc-regs, DWC3_OEVTEN,
+   DWC3_OEVTEN_CONIDSTSCHNGEN);
+   } else

[PATCH 16/19] arm: dts: omap5: Add named interrupt property for dwc3

2014-11-25 Thread George Cherian
Add interrupt names so that the same can be used for OTG easily.

Signed-off-by: George Cherian george.cher...@ti.com
---
 arch/arm/boot/dts/omap5.dtsi | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index 256b7f6..a712ad9 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -817,7 +817,12 @@
dwc3@4a03 {
compatible = snps,dwc3;
reg = 0x4a03 0x1;
-   interrupts = GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH;
+   interrupts = GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH,
+GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH,
+GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH;
+   interrupt-names = peripheral,
+ host,
+ otg;
phys = usb2_phy, usb3_phy;
phy-names = usb2-phy, usb3-phy;
dr_mode = peripheral;
-- 
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


[PATCH 10/19] usb: dwc3: core: Adapt to named interrupts

2014-11-25 Thread George Cherian
From: Felipe Balbi ba...@ti.com

Add support to use interrupt names,

Following are the interrupt names

Peripheral Interrupt - peripheral
HOST Interrupt - host
OTG Interrupt - otg

Signed-off-by: Felipe Balbi ba...@ti.com
Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/core.c | 12 
 drivers/usb/dwc3/core.h |  7 +++
 2 files changed, 19 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index fadd767..dbd5589 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -760,6 +760,18 @@ static int dwc3_probe(struct platform_device *pdev)
dwc-xhci_resources[1].flags = res-flags;
dwc-xhci_resources[1].name = res-name;
 
+   dwc-otg_irq = platform_get_irq_byname(pdev, otg);
+   if (!dwc-otg_irq)
+   dev_err(dev, missing OTG IRQ\n);
+
+   dwc-gadget_irq = platform_get_irq_byname(pdev, peripheral);
+   if (!dwc-gadget_irq)
+   dev_err(dev, missing peripheral IRQ\n);
+
+   dwc-xhci_irq = platform_get_irq_byname(pdev, host);
+   if (!dwc-xhci_irq)
+   dev_err(dev, missing HOST IRQ\n);
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, missing memory resource\n);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 6b38223..7c5ae37 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -651,6 +651,9 @@ struct dwc3_scratchpad_array {
  * @maximum_speed: maximum speed requested (mainly for testing purposes)
  * @revision: revision register contents
  * @dr_mode: requested mode of operation
+ * @xhci_irq: IRQ number for XHCI IRQs
+ * @gadget_irq: IRQ number for Peripheral IRQs
+ * @otg_irq: IRQ number for OTG IRQs
  * @usb2_phy: pointer to USB2 PHY
  * @usb3_phy: pointer to USB3 PHY
  * @usb2_generic_phy: pointer to USB2 PHY
@@ -747,6 +750,10 @@ struct dwc3 {
 
enum usb_dr_modedr_mode;
 
+   int gadget_irq;
+   int xhci_irq;
+   int otg_irq;
+
/* used for suspend/resume */
u32 dcfg;
u32 gctl;
-- 
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


[PATCH 09/19] usb: dwc3: dwc3-omap: Make the wrapper interrupt shared

2014-11-25 Thread George Cherian
OTG interrupt and wrapper is shared

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 172d64e..f99e2ca 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -525,8 +525,8 @@ static int dwc3_omap_probe(struct platform_device *pdev)
reg = dwc3_omap_readl(omap-base, USBOTGSS_SYSCONFIG);
omap-dma_status = !!(reg  USBOTGSS_SYSCONFIG_DMADISABLE);
 
-   ret = devm_request_irq(dev, omap-irq, dwc3_omap_interrupt, 0,
-   dwc3-omap, omap);
+   ret = devm_request_irq(dev, omap-irq, dwc3_omap_interrupt, IRQF_SHARED,
+  dwc3-omap, omap);
if (ret) {
dev_err(dev, failed to request IRQ #%d -- %d\n,
omap-irq, ret);
-- 
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


[PATCH 06/19] usb: dwc3: host: Pass the XHCI_DRD_SUPPORT and XHCI_NEEDS_LHC_RESET quirk

2014-11-25 Thread George Cherian
Pass the quir flag XHCI_DRD_SUPPORT from DWC3 host to xhci platform driver.
This enables xhci driver to handle deallocation's differently while in DRD mode.
Pass the quirk flag XHCI_NEEDS_LHC_RESET from DWC3 host to xhci platform
driver. This enables to do LHRESET during xhci_reset().

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/host.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index dcb8ca0..257b5b5 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -53,6 +53,8 @@ int dwc3_host_init(struct dwc3 *dwc)
 #ifdef CONFIG_DWC3_HOST_USB3_LPM_ENABLE
pdata.usb3_lpm_capable = 1;
 #endif
+   pdata.usb_drd_support = 1;
+   pdata.usb_needs_lhc_reset = 1;
 
ret = platform_device_add_data(xhci, pdata, sizeof(pdata));
if (ret) {
-- 
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


[PATCH 05/19] usb: host: xhci-plat: Add support to pass XHCI_NEEDS_LHC_RESET quirk

2014-11-25 Thread George Cherian
Extend the platform data to pass XHCI_NEEDS_LHC_RESET quirk to
the xhci driver.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/host/xhci-plat.c | 3 +++
 include/linux/usb/xhci_pdriver.h | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 2c42273..d8d024d 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -31,6 +31,9 @@ static void xhci_plat_quirks(struct device *dev, struct 
xhci_hcd *xhci)
 
if (pdata-usb_drd_support)
xhci-quirks |= XHCI_DRD_SUPPORT;
+
+   if (pdata-usb_needs_lhc_reset)
+   xhci-quirks |= XHCI_NEEDS_LHC_RESET;
/*
 * As of now platform drivers don't provide MSI support so we ensure
 * here that the generic code does not try to make a pci_dev from our
diff --git a/include/linux/usb/xhci_pdriver.h b/include/linux/usb/xhci_pdriver.h
index 539c2d8..8ef7321 100644
--- a/include/linux/usb/xhci_pdriver.h
+++ b/include/linux/usb/xhci_pdriver.h
@@ -23,6 +23,7 @@
 struct usb_xhci_pdata {
unsignedusb3_lpm_capable:1;
unsignedusb_drd_support:1;
+   unsignedusb_needs_lhc_reset:1;
 };
 
 #endif /* __USB_CORE_XHCI_PDRIVER_H */
-- 
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


[PATCH 07/19] usb: host: xhci: Adapt xhci to use usb drd library

2014-11-25 Thread George Cherian
Adapt the xhci-plat driver  to use drd library functions.
In prepration to support DRD on dwc3.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/host/xhci-plat.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index d8d024d..fbbbd59 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -17,6 +17,8 @@
 #include linux/of.h
 #include linux/platform_device.h
 #include linux/slab.h
+#include linux/usb/otg.h
+#include linux/usb/drd.h
 #include linux/usb/xhci_pdriver.h
 
 #include xhci.h
@@ -78,6 +80,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
struct resource *res;
struct usb_hcd  *hcd;
struct clk  *clk;
+   struct usb_drd_host *drd_host;
int ret;
int irq;
 
@@ -169,6 +172,17 @@ static int xhci_plat_probe(struct platform_device *pdev)
if (ret)
goto put_usb3_hcd;
 
+   drd_host = kzalloc(sizeof(*drd_host), GFP_KERNEL);
+   if (!drd_host)
+   return -ENOMEM;
+
+   drd_host-main_hcd = xhci-main_hcd;
+   drd_host-shared_hcd = xhci-shared_hcd;
+   drd_host-hcd_irq = irq;
+   drd_host-host_setup = NULL;
+
+   usb_drd_register_hcd(pdev-dev.parent, drd_host);
+
return 0;
 
 put_usb3_hcd:
@@ -200,6 +214,7 @@ static int xhci_plat_remove(struct platform_device *dev)
if (!IS_ERR(clk))
clk_disable_unprepare(clk);
usb_put_hcd(hcd);
+   usb_drd_unregister_hcd(dev-dev.parent);
kfree(xhci);
 
return 0;
-- 
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


[PATCH 04/19] usb: host xhci: Add XHCI_NEEDS_LHC_RESET quirk

2014-11-25 Thread George Cherian
This adds XHCI_NEEDS_LHC_RESET quirk, to make sure only Light Host Reset
is done during xhci_reset(). This is mainly useful when we switch roles
HOST to Device mode and viceversa.

The DWC3 IP shares internal RAM for both HOST and Device specific registers.
So while switching roles between HOST and Device modes, it's advbised to do
a LIGHT HC reset else the already configured global registers of the DWC3 IP
gets re-initialized.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/host/xhci.c | 5 +++--
 drivers/usb/host/xhci.h | 1 +
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index d4196f8..5dabf9a 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -170,11 +170,12 @@ int xhci_reset(struct xhci_hcd *xhci)
 
xhci_dbg_trace(xhci, trace_xhci_dbg_init, // Reset the HC);
command = readl(xhci-op_regs-command);
-   command |= CMD_RESET;
+   command |= (xhci-quirks  XHCI_NEEDS_LHC_RESET) ? CMD_LRESET : 
CMD_RESET;
writel(command, xhci-op_regs-command);
 
ret = xhci_handshake(xhci, xhci-op_regs-command,
-   CMD_RESET, 0, 10 * 1000 * 1000);
+   (xhci-quirks  XHCI_NEEDS_LHC_RESET) ? CMD_LRESET : 
CMD_RESET,
+   0, 10 * 1000 * 1000);
if (ret)
return ret;
 
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 2248058..1b14b09 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1561,6 +1561,7 @@ struct xhci_hcd {
 /* For controllers with a broken beyond repair streams implementation */
 #define XHCI_BROKEN_STREAMS(1  19)
 #define XHCI_DRD_SUPPORT   (1  20)
+#define XHCI_NEEDS_LHC_RESET   (1  21)
unsigned intnum_active_eps;
unsigned intlimit_active_eps;
/* There are two roothubs to keep track of bus suspend info for */
-- 
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


[PATCH 08/19] usb: dwc3: core: Add dwc3_drd_helper function

2014-11-25 Thread George Cherian
This helper function, facilitates to re-initialize the event buffers.
It re-initilizes the event buffers while switching role from
HOST to DEVICE mode.

The DWC3 IP shares internal RAM for both HOST and Device specific registers.
So while switching roles from HOST to Device modes, it's required to
re-initialize the EVENT buffer registers for the Device mode to continue
work properly. dwc3_event_buffers_setup() is exported out from core.c via
wrapper dwc3_core_gadget_helper() which will be invoked from dwc3 otg driver.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/core.c | 5 +
 drivers/usb/dwc3/core.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 25ddc39..fadd767 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -254,6 +254,11 @@ static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
}
 }
 
+int dwc3_core_gadget_helper(struct dwc3 *dwc)
+{
+   return dwc3_event_buffers_setup(dwc);
+}
+
 static int dwc3_alloc_scratch_buffers(struct dwc3 *dwc)
 {
if (!dwc-has_hibernation)
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 4bb9aa6..6b38223 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -981,6 +981,7 @@ struct dwc3_gadget_ep_cmd_params {
 /* prototypes */
 void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
 int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc);
+int dwc3_core_gadget_helper(struct dwc3 *dwc);
 
 #if IS_ENABLED(CONFIG_USB_DWC3_HOST) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
 int dwc3_host_init(struct dwc3 *dwc);
-- 
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


[PATCH 01/19] usb: common: drd-lib: Add DRD lib for USB.

2014-11-25 Thread George Cherian
Add USB DRD library. This Library facilitates to
switch roles between HOST and Device modes.

A DRD should be added to the library using usb_drd_add().
Register the HOST and UDC using usb_drd_register_hcd/udc().
Un-Register the HOST and UDC using usb_drd_unregister_hcd/udc().

Depending on the state of IP -
Call the following to start/stop HOST controller
usb_drd_start/stop_hcd().
This internally calls usb_add/remove_hcd() or IP specific low level start/stop
defined in ll_start/stop

Call the following to start/stop UDC
usb_drd_start/stop_udc().
This internally calls udc_start/udc_stop() or IP specific low level start/stop
defined in ll_start/stop

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/Kconfig  |  15 ++
 drivers/usb/common/Makefile  |   1 +
 drivers/usb/common/drd-lib.c | 346 +++
 include/linux/usb/drd.h  |  77 ++
 4 files changed, 439 insertions(+)
 create mode 100644 drivers/usb/common/drd-lib.c
 create mode 100644 include/linux/usb/drd.h

diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index ae481c3..ea0d944 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -34,6 +34,21 @@ config USB_COMMON
default y
depends on USB || USB_GADGET
 
+config DRD_LIB
+   tristate  DRD Library support
+   default y
+   depends on USB  USB_GADGET
+   ---help---
+ This option adds DRD Library support for Universal Serial Bus (USB).
+ DRD Library faciliatets the Role switching by HOST and DEVICE roles,
+ If your hardware has a Dual Role Device.
+
+ The DRD Library uses USB core API's to start/stop HOST controllers,
+ UDC API's to start/stop DEVICE controllers, ther by enabling to
+ switch roles between HOST and Device modes.
+
+ Say N if unsure.
+
 config USB_ARCH_HAS_HCD
def_bool y
 
diff --git a/drivers/usb/common/Makefile b/drivers/usb/common/Makefile
index ca2f8bd..e2c1593 100644
--- a/drivers/usb/common/Makefile
+++ b/drivers/usb/common/Makefile
@@ -7,3 +7,4 @@ usb-common-y  += common.o
 usb-common-$(CONFIG_USB_LED_TRIG) += led.o
 
 obj-$(CONFIG_USB_OTG_FSM) += usb-otg-fsm.o
+obj-$(CONFIG_DRD_LIB)   += drd-lib.o
diff --git a/drivers/usb/common/drd-lib.c b/drivers/usb/common/drd-lib.c
new file mode 100644
index 000..6159436
--- /dev/null
+++ b/drivers/usb/common/drd-lib.c
@@ -0,0 +1,346 @@
+/**
+ * drd-lib.c - USB DRD library functions
+ *
+ * Copyright (C) 2014 Texas Instruments
+ * Author: George Cherian george.cher...@ti.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see http://www.gnu.org/licenses/.
+ */
+
+#include linux/device.h
+#include linux/err.h
+#include linux/kernel.h
+#include linux/list.h
+#include linux/module.h
+#include linux/usb.h
+
+#include linux/usb/hcd.h
+#include linux/usb/gadget.h
+#include linux/usb/drd.h
+
+/**
+ * struct usb_drd - describes one dual role device
+ * @host - the HOST controller device of this drd
+ * @gadget - the gadget of drd
+ * @parent - the device to the actual controller
+ * @list - for use by the drd lib
+ * @state - specifies the current state
+ *
+ * This represents the internal data structure which is used by the UDC-class
+ * to hold information about udc driver and gadget together.
+ */
+struct usb_drd {
+   struct usb_drd_host *host;
+   struct usb_drd_gadget   *gadget;
+   struct device   *parent;
+   struct list_headlist;
+   unsigned intstate;
+};
+
+static LIST_HEAD(drd_list);
+static DEFINE_SPINLOCK(drd_lock);
+
+static struct usb_drd *usb_drd_get_dev(struct device *parent)
+{
+   struct usb_drd *drd;
+
+   spin_lock(drd_lock);
+   list_for_each_entry(drd, drd_list, list)
+   if (drd-parent == parent)
+   goto out;
+   drd = NULL;
+out:
+   spin_unlock(drd_lock);
+
+   return drd;
+}
+
+int usb_drd_get_state(struct device *parent)
+{
+   struct usb_drd  *drd;
+
+   drd = usb_drd_get_dev(parent);
+   if (!drd)
+   return -ENODEV;
+
+   return drd-state;
+}
+EXPORT_SYMBOL_GPL(usb_drd_get_state);
+
+int usb_drd_release(struct device *parent)
+{
+   struct usb_drd  *drd;
+   int ret;
+
+   spin_lock(drd_lock);
+   list_for_each_entry(drd, drd_list, list) {
+   if (drd-parent == parent) {
+   kfree(drd);
+   ret = 0

[PATCH 03/19] usb: host: xhci-plat: Add support to pass XHCI_DRD_SUPPORT quirk

2014-11-25 Thread George Cherian
Extend the platform data to pass XHCI_DRD_SUPPORT quirk to the xhci driver.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/host/xhci-plat.c | 4 
 include/linux/usb/xhci_pdriver.h | 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 3d78b0c..2c42273 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -27,6 +27,10 @@ static struct hc_driver __read_mostly xhci_plat_hc_driver;
 
 static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
 {
+   struct usb_xhci_pdata   *pdata = dev_get_platdata(dev);
+
+   if (pdata-usb_drd_support)
+   xhci-quirks |= XHCI_DRD_SUPPORT;
/*
 * As of now platform drivers don't provide MSI support so we ensure
 * here that the generic code does not try to make a pci_dev from our
diff --git a/include/linux/usb/xhci_pdriver.h b/include/linux/usb/xhci_pdriver.h
index 376654b..539c2d8 100644
--- a/include/linux/usb/xhci_pdriver.h
+++ b/include/linux/usb/xhci_pdriver.h
@@ -22,6 +22,7 @@
  */
 struct usb_xhci_pdata {
unsignedusb3_lpm_capable:1;
+   unsignedusb_drd_support:1;
 };
 
 #endif /* __USB_CORE_XHCI_PDRIVER_H */
-- 
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


[PATCH 00/19] Add Support for USB DRD in AM437x

2014-11-25 Thread George Cherian
The series add DRD suport for AM437x.

The serires adds 
- USB DRD Library
This Library facilitates in switching roles between HOST
and Device. 
- DWC3 OTG driver.
This driver currently suports only the ID based switching


Felipe Balbi (2):
  usb: dwc3: core: Adapt to named interrupts
  arm: dts: am4372: Add named interrupt property for dwc3

George Cherian (17):
  usb: common: drd-lib: Add DRD lib for USB.
  usb: host xhci: fix up deallocation code
  usb: host: xhci-plat: Add support to pass XHCI_DRD_SUPPORT quirk
  usb: host xhci: Add XHCI_NEEDS_LHC_RESET quirk
  usb: host: xhci-plat: Add support to pass XHCI_NEEDS_LHC_RESET quirk
  usb: dwc3: host: Pass the XHCI_DRD_SUPPORT and XHCI_NEEDS_LHC_RESET
quirk
  usb: host: xhci: Adapt xhci to use usb drd library
  usb: dwc3: core: Add dwc3_drd_helper function
  usb: dwc3: dwc3-omap: Make the wrapper interrupt shared
  usb: dwc3: Add seperate dwc3_gadget object to support gadget release
  usb: dwc3: gadget: Adapt gadget to drd library
  usb: dwc3: core: Add DWC3 OTG specific register defines
  usb: dwc3: otg: Add the initial otg driver for dwc3.
  arm: dts: omap5: Add named interrupt property for dwc3
  arm: dts: dra7: Add named interrupt property for dwc3
  arm: dts: exynos5250: Add named interrupt property for dwc3
  arm: dts: am43x evms: Make usb1 as OTG

 arch/arm/boot/dts/am4372.dtsi|  18 +-
 arch/arm/boot/dts/am437x-gp-evm.dts  |   2 +-
 arch/arm/boot/dts/am437x-sk-evm.dts  |   2 +-
 arch/arm/boot/dts/am43x-epos-evm.dts |   2 +-
 arch/arm/boot/dts/dra7.dtsi  |  28 ++-
 arch/arm/boot/dts/exynos5250.dtsi|   7 +-
 arch/arm/boot/dts/omap5.dtsi |   7 +-
 drivers/usb/Kconfig  |  15 ++
 drivers/usb/common/Makefile  |   1 +
 drivers/usb/common/drd-lib.c | 346 +++
 drivers/usb/dwc3/Makefile|   4 +
 drivers/usb/dwc3/core.c  |  27 ++-
 drivers/usb/dwc3/core.h  |  93 +-
 drivers/usb/dwc3/dwc3-omap.c |   4 +-
 drivers/usb/dwc3/ep0.c   |  35 ++--
 drivers/usb/dwc3/gadget.c| 211 +++--
 drivers/usb/dwc3/gadget.h|   1 +
 drivers/usb/dwc3/host.c  |   2 +
 drivers/usb/dwc3/otg.c   | 126 +
 drivers/usb/host/xhci-plat.c |  22 +++
 drivers/usb/host/xhci.c  |  27 ++-
 drivers/usb/host/xhci.h  |   2 +
 include/linux/usb/drd.h  |  77 
 include/linux/usb/xhci_pdriver.h |   2 +
 24 files changed, 962 insertions(+), 99 deletions(-)
 create mode 100644 drivers/usb/common/drd-lib.c
 create mode 100644 drivers/usb/dwc3/otg.c
 create mode 100644 include/linux/usb/drd.h

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


[PATCH 02/19] usb: host xhci: fix up deallocation code

2014-11-25 Thread George Cherian
This fixes up the deallocation code in the xhci driver, so that
usb_add_hcd()/usb_remove_hcd() can be called repeatedly without
crashing.

In case of DRD mode, the DRD library calls /usb_remove_hcd() while
switching from HOST mode to Device mode, but it doesnot call usb_put_hcd().
We need to preserve the already allocated xhci struct for the subsequent
call of usb_add_hcd() from the DRD library.

A new quirk flag XHCI_DRD_SUPPORT is added to differentiate between
normal usb_remove_hcd and drd specific call.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/host/xhci.c | 22 --
 drivers/usb/host/xhci.h |  1 +
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 2a5d45b..d4196f8 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -666,7 +666,8 @@ static void xhci_only_stop_hcd(struct usb_hcd *hcd)
 * calls this function when allocation fails in usb_add_hcd(), or
 * usb_remove_hcd() is called).  So we need to unset xHCI's pointer.
 */
-   xhci-shared_hcd = NULL;
+   if (!(xhci-quirks  XHCI_DRD_SUPPORT))
+   xhci-shared_hcd = NULL;
spin_unlock_irq(xhci-lock);
 }
 
@@ -4815,6 +4816,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t 
get_quirks)
struct xhci_hcd *xhci;
struct device   *dev = hcd-self.controller;
int retval;
+   boolallocated = false;
 
/* Accept arbitrarily long scatter-gather lists */
hcd-self.sg_tablesize = ~0;
@@ -4826,10 +4828,15 @@ int xhci_gen_setup(struct usb_hcd *hcd, 
xhci_get_quirks_t get_quirks)
hcd-self.no_stop_on_short = 1;
 
if (usb_hcd_is_primary_hcd(hcd)) {
-   xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL);
-   if (!xhci)
-   return -ENOMEM;
-   *((struct xhci_hcd **) hcd-hcd_priv) = xhci;
+   if (*((struct xhci_hcd **)hcd-hcd_priv) == NULL) {
+   xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL);
+   if (!xhci)
+   return -ENOMEM;
+   *((struct xhci_hcd **)hcd-hcd_priv) = xhci;
+   allocated = true;
+   } else {
+   xhci = *((struct xhci_hcd **)hcd-hcd_priv);
+   }
xhci-main_hcd = hcd;
/* Mark the first roothub as being USB 2.0.
 * The xHCI driver will register the USB 3.0 roothub.
@@ -4902,7 +4909,10 @@ int xhci_gen_setup(struct usb_hcd *hcd, 
xhci_get_quirks_t get_quirks)
xhci_dbg(xhci, Called HCD init\n);
return 0;
 error:
-   kfree(xhci);
+   if (allocated) {
+   *((struct xhci_hcd **)hcd-hcd_priv) = NULL;
+   kfree(xhci);
+   }
return retval;
 }
 EXPORT_SYMBOL_GPL(xhci_gen_setup);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index df76d64..2248058 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1560,6 +1560,7 @@ struct xhci_hcd {
 #define XHCI_SPURIOUS_WAKEUP   (1  18)
 /* For controllers with a broken beyond repair streams implementation */
 #define XHCI_BROKEN_STREAMS(1  19)
+#define XHCI_DRD_SUPPORT   (1  20)
unsigned intnum_active_eps;
unsigned intlimit_active_eps;
/* There are two roothubs to keep track of bus suspend info for */
-- 
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


[PATCH] usb: musb: core: Disable the Interrupts till BABBLE is fully handled

2014-11-14 Thread George Cherian
Disable the MUSB interrupts till MUSB is recovered fully from BABBLE
condition. There are chances that we could get multiple interrupts
till the time the babble recover work gets scheduled. Sometimes
this could even end up in an endless loop making MUSB itself unusable.

Reported-by: Felipe Balbi ba...@ti.com
Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_core.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 3345c94..992c768 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -423,6 +423,7 @@ void musb_hnp_stop(struct musb *musb)
musb-port1_status = ~(USB_PORT_STAT_C_CONNECTION  16);
 }
 
+static void musb_generic_disable(struct musb *musb);
 /*
  * Interrupt Service Routine to record USB global interrupts.
  * Since these do not happen often and signify things of
@@ -846,9 +847,11 @@ b_host:
}
 
/* handle babble condition */
-   if (int_usb  MUSB_INTR_BABBLE  is_host_active(musb))
+   if (int_usb  MUSB_INTR_BABBLE  is_host_active(musb)) {
+   musb_generic_disable(musb);
schedule_delayed_work(musb-recover_work,
  msecs_to_jiffies(100));
+   }
 
 #if 0
 /* REVISIT ... this would be for multiplexing periodic endpoints, or
-- 
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: musb: core: Disable the Interrupts till BABBLE is fully handled

2014-11-14 Thread George Cherian


On 11/14/2014 02:12 PM, Sebastian Andrzej Siewior wrote:

On 11/14/2014 09:24 AM, George Cherian wrote:

Disable the MUSB interrupts till MUSB is recovered fully from BABBLE
condition. There are chances that we could get multiple interrupts
till the time the babble recover work gets scheduled. Sometimes
this could even end up in an endless loop making MUSB itself unusable.

How do you trigger the babble error? Is this something that happens
during suspend resume, plugging / unplugging a device or randomly while
the device is used?
I have never seen this error while device is successfully enumerated 
and  while working fine.

Mostly u get it when we connect/disconnect devices to HOST port.
Normally I use the following for testing BABBLE
 - Especially when a fully loaded USB HUB getting connected to HOST port.
 - Or repeatedly load and unload musb_hdrc.ko with some device connected.

If nothing of the above work you might be the lucky one to have a good 
board




Sebastian



--
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: musb: musb_dsps: fix NULL pointer in suspend

2014-10-08 Thread George Cherian


On 10/08/2014 11:59 PM, Sebastian Andrzej Siewior wrote:

So testing managed to configure musb in DMA mode but not load the
matching cppi41 driver for DMA. This results in

|musb-hdrc musb-hdrc.0.auto: Failed to request rx1.
|musb-hdrc musb-hdrc.0.auto: musb_init_controller failed with status -517
|platform musb-hdrc.0.auto: Driver musb-hdrc requests probe deferral

which is okay. Once the driver is loaded we re-try probing and
everyone is happy. Until then if you try suspend say
 echo mem  /sys/power/state
then you go boom

|Unable to handle kernel NULL pointer dereference at virtual address 03a4
|pgd = cf50c000
|[03a4] *pgd=8f6a3831, *pte=, *ppte=
|Internal error: Oops: 17 [#1] ARM
|PC is at dsps_suspend+0x18/0x9c [musb_dsps]
|LR is at dsps_suspend+0x18/0x9c [musb_dsps]
|pc : [bf08e268] lr : [bf08e268] psr: a013
|sp : cbd97e00 ip : c0af4394 fp : 
|r10: c0831d90 r9 : 0002 r8 : cf6da410
|r7 : c03ba4dc r6 : bf08f224 r5 :  r4 : cbc5fcd0
|r3 : bf08e250 r2 : bf08f264 r1 : cf6da410 r0 : 
|[bf08e268] (dsps_suspend [musb_dsps]) from [c03ba508] 
(platform_pm_suspend+0x2c/0x54)
|Code: e1a04000 e9900041 e2800010 eb4caa8e (e59053a4)

because platform_get_drvdata(glue-musb) returns a NULL pointer as long as the
device is not fully probed.

Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de

Tested-by: George Cherian george.cher...@ti.com

---
  drivers/usb/musb/musb_dsps.c | 13 +++--
  1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index c791ba5da91a..2f71f04ed8f7 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -868,8 +868,13 @@ static int dsps_suspend(struct device *dev)
struct dsps_glue *glue = dev_get_drvdata(dev);
const struct dsps_musb_wrapper *wrp = glue-wrp;
struct musb *musb = platform_get_drvdata(glue-musb);
-   void __iomem *mbase = musb-ctrl_base;
+   void __iomem *mbase;
  
+	if (!musb)

+   /* This can happen if the musb device is in -EPROBE_DEFER */
+   return 0;
+
+   mbase = musb-ctrl_base;
glue-context.control = dsps_readl(mbase, wrp-control);
glue-context.epintr = dsps_readl(mbase, wrp-epintr_set);
glue-context.coreintr = dsps_readl(mbase, wrp-coreintr_set);
@@ -886,8 +891,12 @@ static int dsps_resume(struct device *dev)
struct dsps_glue *glue = dev_get_drvdata(dev);
const struct dsps_musb_wrapper *wrp = glue-wrp;
struct musb *musb = platform_get_drvdata(glue-musb);
-   void __iomem *mbase = musb-ctrl_base;
+   void __iomem *mbase;
+
+   if (!musb)
+   return 0;
  
+	mbase = musb-ctrl_base;

dsps_writel(mbase, wrp-control, glue-context.control);
dsps_writel(mbase, wrp-epintr_set, glue-context.epintr);
dsps_writel(mbase, wrp-coreintr_set, glue-context.coreintr);


--
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: OOPS: musb_hdrc

2014-09-09 Thread George Cherian

Hi Matwey,

On 09/09/2014 01:58 PM, Matwey V. Kornilov wrote:

Hi,


Can you add a few printks around drivers/usb/musb/musb_cppi41.c to
further narrow down where the problem is ? I ran v3.17-rc1 on my
beaglebone black (a while back) and didn't have any issues.

Now I am rebuilding the kernel to see where the problem is.


Are you sure you're running v3.16.1 vanilla ? I just tested on my end
and it's working fine. Please provide full boot logs including u-boot
all the way to the error scenario.

I am sure that I am running 3.16.1 opensuse, where no patches
affecting musb applied. Full log is quite big, please find it at
http://susepaste.org/31032538


attached you can find my logs (couldn't paste it anywhere as my test
case for mass storage devices outputs quite a bit of data)

Could you please share your kernel config? My config is attached.

Please set CONFIG_USB_TI_CPPI41_DMA=y and re-run your tests.

-George
--
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 v7 1/4] usb: musb: core: Handle Babble condition only in HOST mode

2014-07-16 Thread George Cherian
BABBLE and RESET share the same interrupt. The interrupt
is considered to be RESET if MUSB is in peripheral mode and
as a BABBLE if MUSB is in HOST mode.

Handle babble condition iff MUSB is in HOST mode.

Signed-off-by: George Cherian george.cher...@ti.com
Tested-by: Bin Liu b-...@ti.com
---
 drivers/usb/musb/musb_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 3c6043c..0ad9551 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -849,7 +849,7 @@ b_host:
}
 
/* handle babble condition */
-   if (int_usb  MUSB_INTR_BABBLE)
+   if (int_usb  MUSB_INTR_BABBLE  is_host_active(musb))
schedule_work(musb-recover_work);
 
 #if 0
-- 
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


[PATCH v7 0/4] Add support for SW babble Control

2014-07-16 Thread George Cherian
Hi Felipe,

Series add support for SW babble control logic found in 
new silicon versions of AM335x. Runtime differentiation of
silicon version is done by checking the BABBLE_CTL register.
For newer silicon the register default value read is 0x4 and
for older versions its 0x0.

Patch 1 - Handle Babble only if MUSB is in HOST mode
   (This patch is available in linux-next but missing in your 
testing/next).

Patch 2 - Convert recover work to delayed work.
Patch 3 - Add return value for musb_platform_reset() in prepration
   to support SW babble_ctrl
Patch 4 - Add and Enable sw babble control for newer silicon

v6 - v7 : Rebased for to balbi testing/next
v5 - v6 : Squash patch 5 and 6 form v5 to avoid build warnings.

v4 - v5 : Added a debug print before resetting MUSB.
   changed a musb_readb to dsps_readb introduced in Patch#5 of v4.

v3 - v4 : Fixes an issue in gagdet mode - BUS RESET should not
   be handled as a BABBLE. Added a check for the same.(Patch #1)
   Enable sw babble control properly (Patch #6)

v2 - v3 : Modify musb_platform_reset() to return zero on success.

George Cherian (4):
  usb: musb: core: Handle Babble condition only in HOST mode
  usb: musb: core: Convert babble recover work to delayed work
  usb: musb: core: Convert the musb_platform_reset to have a return
value.
  usb: musb: dsps: Add the sw_babble_control() and Enable for newer
silicon

 drivers/usb/musb/musb_core.c | 27 +++--
 drivers/usb/musb/musb_core.h | 12 +++---
 drivers/usb/musb/musb_dsps.c | 90 +---
 drivers/usb/musb/musb_regs.h |  7 
 4 files changed, 113 insertions(+), 23 deletions(-)

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


[PATCH v7 2/4] usb: musb: core: Convert babble recover work to delayed work

2014-07-16 Thread George Cherian
During babble condition both first disconnect of devices are
initiated. Make sure MUSB controller is reset and re-initialized
after all disconnects.

To acheive this schedule a delayed work for babble recovery.

While at that convert udelay to usleep_range.
Refer Documentation/timers/timers-howto.txt

Signed-off-by: George Cherian george.cher...@ti.com
Tested-by: Bin Liu b-...@ti.com
---
 drivers/usb/musb/musb_core.c | 15 ---
 drivers/usb/musb/musb_core.h |  2 +-
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 0ad9551..c0ce09f 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -850,7 +850,8 @@ b_host:
 
/* handle babble condition */
if (int_usb  MUSB_INTR_BABBLE  is_host_active(musb))
-   schedule_work(musb-recover_work);
+   schedule_delayed_work(musb-recover_work,
+ msecs_to_jiffies(100));
 
 #if 0
 /* REVISIT ... this would be for multiplexing periodic endpoints, or
@@ -1751,16 +1752,16 @@ static void musb_irq_work(struct work_struct *data)
 /* Recover from babble interrupt conditions */
 static void musb_recover_work(struct work_struct *data)
 {
-   struct musb *musb = container_of(data, struct musb, recover_work);
+   struct musb *musb = container_of(data, struct musb, recover_work.work);
int status;
 
musb_platform_reset(musb);
 
usb_phy_vbus_off(musb-xceiv);
-   udelay(100);
+   usleep_range(100, 200);
 
usb_phy_vbus_on(musb-xceiv);
-   udelay(100);
+   usleep_range(100, 200);
 
/*
 * When a babble condition occurs, the musb controller removes the
@@ -1943,7 +1944,7 @@ musb_init_controller(struct device *dev, int nIrq, void 
__iomem *ctrl)
 
/* Init IRQ workqueue before request_irq */
INIT_WORK(musb-irq_work, musb_irq_work);
-   INIT_WORK(musb-recover_work, musb_recover_work);
+   INIT_DELAYED_WORK(musb-recover_work, musb_recover_work);
INIT_DELAYED_WORK(musb-deassert_reset_work, musb_deassert_reset);
INIT_DELAYED_WORK(musb-finish_resume_work, musb_host_finish_resume);
 
@@ -2039,7 +2040,7 @@ fail4:
 
 fail3:
cancel_work_sync(musb-irq_work);
-   cancel_work_sync(musb-recover_work);
+   cancel_delayed_work_sync(musb-recover_work);
cancel_delayed_work_sync(musb-finish_resume_work);
cancel_delayed_work_sync(musb-deassert_reset_work);
if (musb-dma_controller)
@@ -2105,7 +2106,7 @@ static int musb_remove(struct platform_device *pdev)
dma_controller_destroy(musb-dma_controller);
 
cancel_work_sync(musb-irq_work);
-   cancel_work_sync(musb-recover_work);
+   cancel_delayed_work_sync(musb-recover_work);
cancel_delayed_work_sync(musb-finish_resume_work);
cancel_delayed_work_sync(musb-deassert_reset_work);
musb_free(musb);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index d155a15..9241025 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -297,7 +297,7 @@ struct musb {
 
irqreturn_t (*isr)(int, void *);
struct work_struct  irq_work;
-   struct work_struct  recover_work;
+   struct delayed_work recover_work;
struct delayed_work deassert_reset_work;
struct delayed_work finish_resume_work;
u16 hwvers;
-- 
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


[PATCH v7 4/4] usb: musb: dsps: Add the sw_babble_control() and Enable for newer silicon

2014-07-16 Thread George Cherian
Add sw_babble_control() logic to differentiate between transient
babble and real babble condition. Also add the SW babble control
register definitions.

Babble control register logic is implemented in the latest
revision of AM335x.

Find whether we are running on newer silicon. The babble control
register reads 0x4 by default in newer silicon as opposed to 0
in old versions of AM335x. Based on this enable the sw babble
control logic.

Signed-off-by: George Cherian george.cher...@ti.com
Tested-by: Bin Liu b-...@ti.com
---
 drivers/usb/musb/musb_dsps.c | 89 +---
 drivers/usb/musb/musb_regs.h |  7 
 2 files changed, 90 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 53a4351..f119a62 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -144,6 +144,7 @@ struct dsps_glue {
const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
struct timer_list timer;/* otg_workaround timer */
unsigned long last_timer;/* last timer data for each instance */
+   bool sw_babble_enabled;
 
struct dsps_context context;
struct debugfs_regset32 regset;
@@ -477,6 +478,19 @@ static int dsps_musb_init(struct musb *musb)
val = ~(1  wrp-otg_disable);
dsps_writel(musb-ctrl_base, wrp-phy_utmi, val);
 
+   /*
+*  Check whether the dsps version has babble control enabled.
+* In latest silicon revision the babble control logic is enabled.
+* If MUSB_BABBLE_CTL returns 0x4 then we have the babble control
+* logic enabled.
+*/
+   val = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   if (val == MUSB_BABBLE_RCV_DISABLE) {
+   glue-sw_babble_enabled = true;
+   val |= MUSB_BABBLE_SW_SESSION_CTRL;
+   dsps_writeb(musb-mregs, MUSB_BABBLE_CTL, val);
+   }
+
ret = dsps_musb_dbg_init(musb, glue);
if (ret)
return ret;
@@ -544,19 +558,82 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode)
return 0;
 }
 
+static bool  sw_babble_control(struct musb *musb)
+{
+   u8 babble_ctl;
+   bool session_restart =  false;
+
+   babble_ctl = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   dev_dbg(musb-controller, babble: MUSB_BABBLE_CTL value %x\n,
+   babble_ctl);
+   /*
+* check line monitor flag to check whether babble is
+* due to noise
+*/
+   dev_dbg(musb-controller, STUCK_J is %s\n,
+   babble_ctl  MUSB_BABBLE_STUCK_J ? set : reset);
+
+   if (babble_ctl  MUSB_BABBLE_STUCK_J) {
+   int timeout = 10;
+
+   /*
+* babble is due to noise, then set transmit idle (d7 bit)
+* to resume normal operation
+*/
+   babble_ctl = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   babble_ctl |= MUSB_BABBLE_FORCE_TXIDLE;
+   dsps_writeb(musb-mregs, MUSB_BABBLE_CTL, babble_ctl);
+
+   /* wait till line monitor flag cleared */
+   dev_dbg(musb-controller, Set TXIDLE, wait J to clear\n);
+   do {
+   babble_ctl = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   udelay(1);
+   } while ((babble_ctl  MUSB_BABBLE_STUCK_J)  timeout--);
+
+   /* check whether stuck_at_j bit cleared */
+   if (babble_ctl  MUSB_BABBLE_STUCK_J) {
+   /*
+* real babble condition has occurred
+* restart the controller to start the
+* session again
+*/
+   dev_dbg(musb-controller, J not cleared, misc (%x)\n,
+   babble_ctl);
+   session_restart = true;
+   }
+   } else {
+   session_restart = true;
+   }
+
+   return session_restart;
+}
+
 static int dsps_musb_reset(struct musb *musb)
 {
struct device *dev = musb-controller;
struct dsps_glue *glue = dev_get_drvdata(dev-parent);
const struct dsps_musb_wrapper *wrp = glue-wrp;
+   int session_restart = 0;
 
-   dsps_writel(musb-ctrl_base, wrp-control, (1  wrp-reset));
-   usleep_range(100, 200);
-   usb_phy_shutdown(musb-xceiv);
-   usleep_range(100, 200);
-   usb_phy_init(musb-xceiv);
+   if (glue-sw_babble_enabled)
+   session_restart = sw_babble_control(musb);
+   /*
+* In case of new silicon version babble condition can be recovered
+* without resetting the MUSB. But for older silicon versions, MUSB
+* reset is needed
+*/
+   if (session_restart || !glue-sw_babble_enabled) {
+   dev_info(musb-controller, Restarting MUSB to recover from 
Babble\n);
+   dsps_writel(musb-ctrl_base, wrp

[PATCH v7 3/4] usb: musb: core: Convert the musb_platform_reset to have a return value.

2014-07-16 Thread George Cherian
Currently musb_platform_reset() is only used by dsps.
In case of BABBLE interrupt for other platforms the  musb_platform_reset()
is a NOP. In such situations no need to re-initialize the endpoints.
Also in the latest silicon revision of AM335x, we do have a babble recovery
mechanism without resetting the IP block. In preperation to add that support
its better to have a rest_done return for  musb_platform_reset().

Signed-off-by: George Cherian george.cher...@ti.com
Tested-by: Bin Liu b-...@ti.com
---
 drivers/usb/musb/musb_core.c | 10 ++
 drivers/usb/musb/musb_core.h | 10 ++
 drivers/usb/musb/musb_dsps.c |  3 ++-
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index c0ce09f..b841ee0 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1753,9 +1753,11 @@ static void musb_irq_work(struct work_struct *data)
 static void musb_recover_work(struct work_struct *data)
 {
struct musb *musb = container_of(data, struct musb, recover_work.work);
-   int status;
+   int status, ret;
 
-   musb_platform_reset(musb);
+   ret  = musb_platform_reset(musb);
+   if (ret)
+   return;
 
usb_phy_vbus_off(musb-xceiv);
usleep_range(100, 200);
@@ -1764,8 +1766,8 @@ static void musb_recover_work(struct work_struct *data)
usleep_range(100, 200);
 
/*
-* When a babble condition occurs, the musb controller removes the
-* session bit and the endpoint config is lost.
+* When a babble condition occurs, the musb controller
+* removes the session bit and the endpoint config is lost.
 */
if (musb-dyn_fifo)
status = ep_config_from_table(musb);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 9241025..414e57a 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -192,7 +192,7 @@ struct musb_platform_ops {
 
int (*set_mode)(struct musb *musb, u8 mode);
void(*try_idle)(struct musb *musb, unsigned long timeout);
-   void(*reset)(struct musb *musb);
+   int (*reset)(struct musb *musb);
 
int (*vbus_status)(struct musb *musb);
void(*set_vbus)(struct musb *musb, int on);
@@ -555,10 +555,12 @@ static inline void musb_platform_try_idle(struct musb 
*musb,
musb-ops-try_idle(musb, timeout);
 }
 
-static inline void musb_platform_reset(struct musb *musb)
+static inline int  musb_platform_reset(struct musb *musb)
 {
-   if (musb-ops-reset)
-   musb-ops-reset(musb);
+   if (!musb-ops-reset)
+   return -EINVAL;
+
+   return musb-ops-reset(musb);
 }
 
 static inline int musb_platform_get_vbus_status(struct musb *musb)
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index b29f59f..53a4351 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -544,7 +544,7 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode)
return 0;
 }
 
-static void dsps_musb_reset(struct musb *musb)
+static int dsps_musb_reset(struct musb *musb)
 {
struct device *dev = musb-controller;
struct dsps_glue *glue = dev_get_drvdata(dev-parent);
@@ -556,6 +556,7 @@ static void dsps_musb_reset(struct musb *musb)
usleep_range(100, 200);
usb_phy_init(musb-xceiv);
 
+   return 0;
 }
 
 static struct musb_platform_ops dsps_ops = {
-- 
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


[RESEND PATCH v3 0/4] Cleanup for dwc3-omap

2014-07-16 Thread George Cherian
The series does some refactoring on dwc3_probe()

Patch 1 - Now that we use driver compatible for revision check, remove the 
unnecessary logic.
Patch 2-4 - reduce the size of dwc3_probe()

George Cherian (4):
  usb: dwc3: dwc3-omap: Remove x_major calculation from revision
register
  usb: dwc3: dwc3-omap: Add dwc3_omap_map_offset() function
  usb: dwc3: dwc3-omap: Add dwc3_omap_set_utmi_mode() function
  usb: dwc3: dwc3-omap: Add dwc3_omap_extcon_register function

 drivers/usb/dwc3/dwc3-omap.c | 170 +--
 1 file changed, 84 insertions(+), 86 deletions(-)

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


[RESEND PATCH v3 3/4] usb: dwc3: dwc3-omap: Add dwc3_omap_set_utmi_mode() function

2014-07-16 Thread George Cherian
Move find and set the utmi mode to its own seperate function.
Improve code readability, decrease the dwc3_probe() size.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 44 +---
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 09918ac..56ec6eb 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -397,6 +397,30 @@ static void dwc3_omap_map_offset(struct dwc3_omap *omap)
}
 }
 
+static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap)
+{
+   u32 reg;
+   struct device_node  *node = omap-dev-of_node;
+   int utmi_mode = 0;
+
+   reg = dwc3_omap_read_utmi_status(omap);
+
+   of_property_read_u32(node, utmi-mode, utmi_mode);
+
+   switch (utmi_mode) {
+   case DWC3_OMAP_UTMI_MODE_SW:
+   reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
+   break;
+   case DWC3_OMAP_UTMI_MODE_HW:
+   reg = ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
+   break;
+   default:
+   dev_dbg(omap-dev, UNKNOWN utmi mode %d\n, utmi_mode);
+   }
+
+   dwc3_omap_write_utmi_status(omap, reg);
+}
+
 static int dwc3_omap_probe(struct platform_device *pdev)
 {
struct device_node  *node = pdev-dev.of_node;
@@ -410,8 +434,6 @@ static int dwc3_omap_probe(struct platform_device *pdev)
int ret;
int irq;
 
-   int utmi_mode = 0;
-
u32 reg;
 
void __iomem*base;
@@ -462,23 +484,7 @@ static int dwc3_omap_probe(struct platform_device *pdev)
}
 
dwc3_omap_map_offset(omap);
-
-   reg = dwc3_omap_read_utmi_status(omap);
-
-   of_property_read_u32(node, utmi-mode, utmi_mode);
-
-   switch (utmi_mode) {
-   case DWC3_OMAP_UTMI_MODE_SW:
-   reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
-   break;
-   case DWC3_OMAP_UTMI_MODE_HW:
-   reg = ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
-   break;
-   default:
-   dev_dbg(dev, UNKNOWN utmi mode %d\n, utmi_mode);
-   }
-
-   dwc3_omap_write_utmi_status(omap, reg);
+   dwc3_omap_set_utmi_mode(omap);
 
/* check the DMA Status */
reg = dwc3_omap_readl(omap-base, USBOTGSS_SYSCONFIG);
-- 
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


[RESEND PATCH v3 1/4] usb: dwc3: dwc3-omap: Remove x_major calculation from revision register

2014-07-16 Thread George Cherian
Remove the x_major calculation logic from the wrapper revision register
to differentiate between OMAP5 and AM437x. This was done to find the
register offsets of wrapper register. Now that We do it using dt
compatible, remove the whole logic.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 36 
 1 file changed, 4 insertions(+), 32 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 4af4c35..999bdc8 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -77,10 +77,6 @@
 #define USBOTGSS_DEV_EBC_EN0x0110
 #define USBOTGSS_DEBUG_OFFSET  0x0600
 
-/* REVISION REGISTER */
-#define USBOTGSS_REVISION_XMAJOR(reg)  ((reg  8)  0x7)
-#define USBOTGSS_REVISION_XMAJOR1  1
-#define USBOTGSS_REVISION_XMAJOR2  2
 /* SYSCONFIG REGISTER */
 #define USBOTGSS_SYSCONFIG_DMADISABLE  (1  16)
 
@@ -129,7 +125,6 @@ struct dwc3_omap {
u32 irq_eoi_offset;
u32 debug_offset;
u32 irq0_offset;
-   u32 revision;
 
u32 dma_status:1;
 
@@ -397,7 +392,6 @@ static int dwc3_omap_probe(struct platform_device *pdev)
int irq;
 
int utmi_mode = 0;
-   int x_major;
 
u32 reg;
 
@@ -448,32 +442,10 @@ static int dwc3_omap_probe(struct platform_device *pdev)
goto err0;
}
 
-   reg = dwc3_omap_readl(omap-base, USBOTGSS_REVISION);
-   omap-revision = reg;
-   x_major = USBOTGSS_REVISION_XMAJOR(reg);
-
-   /* Differentiate between OMAP5 and AM437x */
-   switch (x_major) {
-   case USBOTGSS_REVISION_XMAJOR1:
-   case USBOTGSS_REVISION_XMAJOR2:
-   omap-irq_eoi_offset = 0;
-   omap-irq0_offset = 0;
-   omap-irqmisc_offset = 0;
-   omap-utmi_otg_offset = 0;
-   omap-debug_offset = 0;
-   break;
-   default:
-   /* Default to the latest revision */
-   omap-irq_eoi_offset = USBOTGSS_EOI_OFFSET;
-   omap-irq0_offset = USBOTGSS_IRQ0_OFFSET;
-   omap-irqmisc_offset = USBOTGSS_IRQMISC_OFFSET;
-   omap-utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET;
-   omap-debug_offset = USBOTGSS_DEBUG_OFFSET;
-   break;
-   }
-
-   /* For OMAP5(ES2.0) and AM437x x_major is 2 even though there are
-* changes in wrapper registers, Using dt compatible for aegis
+   /* Differentiate between OMAP5 and AM437x.
+* For OMAP5(ES2.0) and AM437x wrapper revision is same, even
+* though there are changes in wrapper register offsets.
+* Using dt compatible to differentiate  AM437x.
 */
 
if (of_device_is_compatible(node, ti,am437x-dwc3)) {
-- 
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


[RESEND PATCH v3 4/4] usb: dwc3: dwc3-omap: Add dwc3_omap_extcon_register function

2014-07-16 Thread George Cherian
Move the extcon related code to its own function.
Improve code readability, decrease the dwc3_probe() size.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 65 ++--
 1 file changed, 39 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 56ec6eb..7594535 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -421,6 +421,42 @@ static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap)
dwc3_omap_write_utmi_status(omap, reg);
 }
 
+static int dwc3_omap_extcon_register(struct dwc3_omap *omap)
+{
+   u32 ret;
+   struct device_node  *node = omap-dev-of_node;
+   struct extcon_dev   *edev;
+
+   if (of_property_read_bool(node, extcon)) {
+   edev = extcon_get_edev_by_phandle(omap-dev, 0);
+   if (IS_ERR(edev)) {
+   dev_vdbg(omap-dev, couldn't get extcon device\n);
+   return -EPROBE_DEFER;
+   }
+
+   omap-vbus_nb.notifier_call = dwc3_omap_vbus_notifier;
+   ret = extcon_register_interest(omap-extcon_vbus_dev,
+  edev-name, USB,
+  omap-vbus_nb);
+   if (ret  0)
+   dev_vdbg(omap-dev, failed to register notifier for 
USB\n);
+
+   omap-id_nb.notifier_call = dwc3_omap_id_notifier;
+   ret = extcon_register_interest(omap-extcon_id_dev,
+  edev-name, USB-HOST,
+  omap-id_nb);
+   if (ret  0)
+   dev_vdbg(omap-dev, failed to register notifier for 
USB-HOST\n);
+
+   if (extcon_get_cable_state(edev, USB) == true)
+   dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
+   if (extcon_get_cable_state(edev, USB-HOST) == true)
+   dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
+   }
+
+   return 0;
+}
+
 static int dwc3_omap_probe(struct platform_device *pdev)
 {
struct device_node  *node = pdev-dev.of_node;
@@ -428,7 +464,6 @@ static int dwc3_omap_probe(struct platform_device *pdev)
struct dwc3_omap*omap;
struct resource *res;
struct device   *dev = pdev-dev;
-   struct extcon_dev   *edev;
struct regulator*vbus_reg = NULL;
 
int ret;
@@ -500,31 +535,9 @@ static int dwc3_omap_probe(struct platform_device *pdev)
 
dwc3_omap_enable_irqs(omap);
 
-   if (of_property_read_bool(node, extcon)) {
-   edev = extcon_get_edev_by_phandle(dev, 0);
-   if (IS_ERR(edev)) {
-   dev_vdbg(dev, couldn't get extcon device\n);
-   ret = -EPROBE_DEFER;
-   goto err2;
-   }
-
-   omap-vbus_nb.notifier_call = dwc3_omap_vbus_notifier;
-   ret = extcon_register_interest(omap-extcon_vbus_dev,
-   edev-name, USB, omap-vbus_nb);
-   if (ret  0)
-   dev_vdbg(dev, failed to register notifier for USB\n);
-   omap-id_nb.notifier_call = dwc3_omap_id_notifier;
-   ret = extcon_register_interest(omap-extcon_id_dev, edev-name,
-USB-HOST, omap-id_nb);
-   if (ret  0)
-   dev_vdbg(dev,
-   failed to register notifier for USB-HOST\n);
-
-   if (extcon_get_cable_state(edev, USB) == true)
-   dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
-   if (extcon_get_cable_state(edev, USB-HOST) == true)
-   dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
-   }
+   ret = dwc3_omap_extcon_register(omap);
+   if (ret  0)
+   goto err2;
 
ret = of_platform_populate(node, NULL, NULL, dev);
if (ret) {
-- 
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


[RESEND PATCH v3 2/4] usb: dwc3: dwc3-omap: Add dwc3_omap_map_offset() function

2014-07-16 Thread George Cherian
Move map offset to its own seperate function.
Improve code readability, decrease the dwc3_probe() size.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 33 -
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 999bdc8..09918ac 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -378,6 +378,25 @@ static int dwc3_omap_vbus_notifier(struct notifier_block 
*nb,
return NOTIFY_DONE;
 }
 
+static void dwc3_omap_map_offset(struct dwc3_omap *omap)
+{
+   struct device_node  *node = omap-dev-of_node;
+
+   /* Differentiate between OMAP5 and AM437x.
+* For OMAP5(ES2.0) and AM437x wrapper revision is same  even
+* though there are changes in wrapper register offsets.
+* Using dt compatible to differentiate  AM437x.
+*/
+
+   if (of_device_is_compatible(node, ti,am437x-dwc3)) {
+   omap-irq_eoi_offset = USBOTGSS_EOI_OFFSET;
+   omap-irq0_offset = USBOTGSS_IRQ0_OFFSET;
+   omap-irqmisc_offset = USBOTGSS_IRQMISC_OFFSET;
+   omap-utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET;
+   omap-debug_offset = USBOTGSS_DEBUG_OFFSET;
+   }
+}
+
 static int dwc3_omap_probe(struct platform_device *pdev)
 {
struct device_node  *node = pdev-dev.of_node;
@@ -442,19 +461,7 @@ static int dwc3_omap_probe(struct platform_device *pdev)
goto err0;
}
 
-   /* Differentiate between OMAP5 and AM437x.
-* For OMAP5(ES2.0) and AM437x wrapper revision is same, even
-* though there are changes in wrapper register offsets.
-* Using dt compatible to differentiate  AM437x.
-*/
-
-   if (of_device_is_compatible(node, ti,am437x-dwc3)) {
-   omap-irq_eoi_offset = USBOTGSS_EOI_OFFSET;
-   omap-irq0_offset = USBOTGSS_IRQ0_OFFSET;
-   omap-irqmisc_offset = USBOTGSS_IRQMISC_OFFSET;
-   omap-utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET;
-   omap-debug_offset = USBOTGSS_DEBUG_OFFSET;
-   }
+   dwc3_omap_map_offset(omap);
 
reg = dwc3_omap_read_utmi_status(omap);
 
-- 
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 0/2] usb musb/cppi41: Address issues with isochronous audio endpoints

2014-06-24 Thread George Cherian

Hi Torben,

On 6/24/2014 6:31 PM, Torben Hohn wrote:

On Wed, Jun 18, 2014 at 11:28:25AM +0200, Daniel Mack wrote:

Hi,

Hi Daniel,


I've been debugging issues with musb in host mode and both full-speed
and high-speed USB audio devices with cppi41 DMA mode enabled.

The effect that was observed with full-speed devices was that CPU load
went up to 100% due to the dma channels dma_completion work struct.
For FS devices, the MUSB_TXCSR_TXPKTRDY bit that signals the FIFO's
emptyness takes a long time to be cleared, and if the worker function
determines that it's still set, it will re-queue the work immediately,
which effectively results in a busy poll that renders the system
unusable. There are audible crackles on the output, and every bit of
extra load will distort the audio stream even more.

The work struct was introduced by 1af54b7a40 (usb: musb: musb_cppi41:
Handle ISOCH differently and not use the hrtimer.), apparantly in
order to mitigate an unreliable behaviour of the driver.

Geroge, do you recall which problems you saw, which device you tested
with and what the effect of this patch was for you? I'm asking because
I suspect the issue in fact lies in the hrtimer interval setup and can
hence be fixed well without the extra worker.

Sebastian's patch to implement that timer (a655f481d: usb: musb:
musb_cppi41: handle pre-mature TX complete interrupt) expressed some
uncertainty about the chosen value of 140us, and suspected that there's
a relation between the dma burst size and the minimum time value.

Hence, I'm sending two patches. The first one reverts 1af54b7a40 as it
causes trouble with FS audio devices, and the seconds addresses the
issue by tweaking the hrtimer settings instead. This seems to work fine
with both FS and HS audio devices now.

George, could you give this a try with your original test case?

Note that these patches are to be applied on top of my musb/cppi41
cleanup series that I sent ~3 weeks ago.

Could you test, whether this commit also fixes your problem ?
https://lkml.org/lkml/2014/6/20/598


Theoretically it looks fine. But unfortunately the SoC with musb/cppi41 
is a single core.




--
-George

--
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: Gadget regression with enabling of MUSB babble interrupt handling

2014-06-19 Thread George Cherian

On 6/19/2014 4:54 PM, Tony Lindgren wrote:

* Daniel Mack dan...@zonque.org [140619 03:51]:

On 06/19/2014 12:43 PM, Tony Lindgren wrote:

* Daniel Mack dan...@zonque.org [140619 03:38]:

On 06/19/2014 12:31 PM, Tony Lindgren wrote:

* Daniel Mack dan...@zonque.org [140619 03:10]:

On 06/19/2014 11:56 AM, Tony Lindgren wrote:

But that also raises a question: Were these patches merged for
v3.16 ever even tested in peripheral mode?

At the time, I had no such hardware to test this on, so I was hoping for
more testers to give them a try in different environments, which
apparently didn't happen. It fixed a dead USB port condition on
host-mode enabled hardware, though.

Well we probably should not merge patches without proper acks and
tested-by:s in general as things just seem to keep breaking
constantly otherwise. And things not working will keep people from
using linux next which will lead into even less testing..

I'm fairly sure the patch causing your trouble has been in linux-next
for a while before they hit the merge window, so people with gadget
enabled musb could have noticed the breakage early enough. The feedback
rate for patches to this driver posted to linux-usb is also usually low,
unfortunately.

I blame myself for not explicitly pointing out the fix.
Instead I clubbed it with this series.

http://marc.info/?l=linux-usbm=140109627505065w=4

Sorry for that.


Right but the problem is that people are not touching linux next
because it's constantly broken :)
  

Anyway, breaking things is certainly not good, and I'm sorry for that.
I'm just uncertain what detail in the procedure should be tweaked in
order to prevent that from happening in the future.

Well I guess somebody should run basic tests on this driver in
linux next, that would probably solve the issues.


I am doing it.

Regards,

Tony



--
-George

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


Re: [PATCH v2 0/2] usb musb/cppi41: Address issues with isochronous audio endpoints

2014-06-19 Thread George Cherian

On 6/20/2014 3:50 AM, Daniel Mack wrote:

Hi,

I've been debugging issues with musb in host mode and both full-speed
and high-speed USB audio devices with cppi41 DMA mode enabled.

The effect that was observed with full-speed devices was that CPU load
went up to 100% due to the dma channels dma_completion work struct.
For FS devices, the MUSB_TXCSR_TXPKTRDY bit that signals the FIFO's
emptyness takes a long time to be cleared, and if the worker function
determines that it's still set, it will re-queue the work immediately,
which effectively results in a busy poll that renders the system
unusable. There are audible crackles on the output, and every bit of
extra load will distort the audio stream even more.

The work struct was introduced by 1af54b7a40 (usb: musb: musb_cppi41:
Handle ISOCH differently and not use the hrtimer.), apparantly in
order to mitigate an unreliable behaviour of the driver.

Geroge, do you recall which problems you saw, which device you tested
with and what the effect of this patch was for you? I'm asking because
I suspect the issue in fact lies in the hrtimer interval setup and can
hence be fixed well without the extra worker.

Sebastian's patch to implement that timer (a655f481d: usb: musb:
musb_cppi41: handle pre-mature TX complete interrupt) expressed some
uncertainty about the chosen value of 140us, and suspected that there's
a relation between the dma burst size and the minimum time value.

Hence, I'm sending two patches. The first one reverts 1af54b7a40 as it
causes trouble with FS audio devices, and the seconds addresses the
issue by tweaking the hrtimer settings instead. This seems to work fine
with both FS and HS audio devices now.

George, could you give this a try with your original test case?


Yes, I would do by this weekend and update.
Sorry that am lil busy with some trainings.


Note that these patches are to be applied on top of my musb/cppi41
cleanup series that I sent ~3 weeks ago.


Thanks,
Daniel


v1 - v2:
* clean up nanosecond/microsecond confusion in patch #2


Daniel Mack (2):
   Revert usb: musb: musb_cppi41: Handle ISOCH differently and not use
 the hrtimer.
   usb: musb: cppi41: fire hrtimer according to programmed channel length

  drivers/usb/musb/musb_cppi41.c | 59 +++---
  1 file changed, 4 insertions(+), 55 deletions(-)




--
-George

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


Re: [PATCH] usb: dwc3: add support for USB 2.0-only core configuration

2014-06-02 Thread George Cherian

On 5/31/2014 5:35 AM, Paul Zimmerman wrote:

From: Felipe Balbi [mailto:ba...@ti.com]
Sent: Friday, May 30, 2014 4:42 PM

On Fri, May 23, 2014 at 11:39:24AM -0700, Paul Zimmerman wrote:

Newer DWC3 controllers can be built for USB 2.0-only mode, where
most of the USB 3.0 circuitry is left out. To support this mode,
the driver must limit the speed programmed into the DCFG register
to Hi-Speed or lower.

Reads and writes to the PIPECTL register are left as-is, since
they should be no-ops in USB 2.0-only mode. Calls to phy_init()
etc. for the USB3 phy are also left as-is, since the no-op USB3
phy should be used for USB 2.0-only mode controllers.

Signed-off-by: Paul Zimmerman pa...@synopsys.com
---
Hi Felipe,

Does this look OK to you? I think it is fine to leave the PIPECTL
accesses and the phy_init() calls as-is, but if you would prefer
that I also conditionalize those I can do that. We have at least
one customer who will need this feature fairly soon, so we would
like to get this in without too much delay, although I guess we
missed the 3.16 merge window.

I like this a lot :-) Very nice of Synopsys to support this
configuration. Could you just let me know which versions of the core
support this configuration ? We have AM437x which has this sort of
quirk although, I think it's done using a TI-specific modification,
perhaps ?

AM437x is version 2.40a

It has been officially supported since 2.60a. But it's possible that
customers have hacked up something like this on their own with previous
versions, so the exact version number might not mean much. The patch
should work for all versions of the core, because the
DWC_USB3_SSPHY_INTERFACE bits have always been there, going back to
preproduction versions of the core.

It has been pointed out to me that DT can already be used to limit the
max speed, using the 'maximum-speed' property (duh). But I think we
still want the patch for non-DT platforms like dwc3-pci.

In TI  implementation  (AM437x)

DWC3_GHWPARAMS3_SSPHY_IFC(dwc-hwparams.hwparams3) is read as 1.



--
-George

--
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 4/7] usb: musb: fix bit mask for CSR in musb_h_tx_flush_fifo()

2014-05-26 Thread George Cherian

On 5/25/2014 7:28 PM, Sergei Shtylyov wrote:

Hello.

On 25-05-2014 12:36, Daniel Mack wrote:


The datasheet says that MUSB_TXCSR_FLUSHFIFO is only valid when
MUSB_CSR0_TXPKTRDY is set as well.



With this patch applied, the warning in this function does no longer
kick in when an USB soundcard is unplugged while the stream is active.



Signed-off-by: Daniel Mack zon...@gmail.com
---
  drivers/usb/musb/musb_host.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)



diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index f98a7c0..44cc57c 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -120,7 +120,7 @@ static void musb_h_tx_flush_fifo(struct 
musb_hw_ep *ep)

  if (csr != lastcsr)
  dev_dbg(musb-controller, Host TX FIFONOTEMPTY csr: 
%02x\n, csr);

  lastcsr = csr;
-csr |= MUSB_TXCSR_FLUSHFIFO;
+csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_CSR0_TXPKTRDY;


   s/CSR0/TXCSR/.

Yes Should be
csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_TXCSR_TXPKTRDY;


WBR, Sergei




--
-George

--
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 5/7] usb: musb: introduce dma_channel.packet_done

2014-05-26 Thread George Cherian

On 5/25/2014 2:06 PM, Daniel Mack wrote:

The musb/cppi41 glue layer is capable of handling transactions that span
over more than one USB packet by reloading the DMA descriptors
partially. An urb is considered completed when either its transfer
buffer has been filled entirely (actual_length ==
transfer_buffer_length) or if a packet in the stream has less bytes than
the endpoint's wMaxPacketSize.

Once one of the above conditions is met, musb_dma_completion() is called
from cppi41_trans_done(). However, the final decision whether or not to
return the urb to its owner is made by the core and its determination of
the variable 'done' in musb_host_rx(). This code has currently no way of
knowing what the size of the last packet was, and whether or not to
give back the urb due to a short read.

Fix this by introducing a new boolean flag in 'struct dma_channel', and
set it from musb_cppi41.c. If set, it will make the core do what the
DMA layer decided and complete the urb.

Signed-off-by: Daniel Mack zon...@gmail.com
Since this is used only for rx, Can you name newly added  dma flag as 
rx_packet_done?

Other than that.
Acked-by: George Cherian george.cher...@ti.com

---
  drivers/usb/musb/musb_cppi41.c | 2 ++
  drivers/usb/musb/musb_dma.h| 1 +
  drivers/usb/musb/musb_host.c   | 3 ++-
  3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
index 7b8bbf5..a11bbb6 100644
--- a/drivers/usb/musb/musb_cppi41.c
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -139,6 +139,7 @@ static void cppi41_trans_done(struct cppi41_dma_channel 
*cppi41_channel)
cppi41_channel-channel.actual_len =
cppi41_channel-transferred;
cppi41_channel-channel.status = MUSB_DMA_STATUS_FREE;
+   cppi41_channel-channel.packet_done = true;
musb_dma_completion(musb, hw_ep-epnum, cppi41_channel-is_tx);
} else {
/* next iteration, reload */
@@ -450,6 +451,7 @@ static bool cppi41_configure_channel(struct dma_channel 
*channel,
dma_desc-callback = cppi41_dma_callback;
dma_desc-callback_param = channel;
cppi41_channel-cookie = dma_desc-tx_submit(dma_desc);
+   cppi41_channel-channel.packet_done = false;
  
  	save_rx_toggle(cppi41_channel);

dma_async_issue_pending(dc);
diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h
index 1345a4f..7253358 100644
--- a/drivers/usb/musb/musb_dma.h
+++ b/drivers/usb/musb/musb_dma.h
@@ -129,6 +129,7 @@ struct dma_channel {
size_t  actual_len;
enum dma_channel_status status;
booldesired_mode;
+   boolpacket_done;
  };
  
  /*

diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 44cc57c..0f7ba24 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -1737,7 +1737,8 @@ void musb_host_rx(struct musb *musb, u8 epnum)
/* done if urb buffer is full or short packet is recd */
done = (urb-actual_length + xfer_len =
urb-transfer_buffer_length
-   || dma-actual_len  qh-maxpacket);
+   || dma-actual_len  qh-maxpacket
+   || dma-packet_done);
}
  
  		/* send IN token for next packet, without AUTOREQ */



--
-George

--
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 v4 1/6] usb: musb: core: Handle Babble condition only in HOST mode

2014-05-26 Thread George Cherian

On 5/23/2014 2:12 AM, Bin Liu wrote:

Hi George,

On Mon, May 19, 2014 at 11:32 PM, George Cherian george.cher...@ti.com wrote:

Hi Bin,

On 5/19/2014 9:24 PM, Bin Liu wrote:

Hi,

On Mon, May 19, 2014 at 8:39 AM, George Cherian george.cher...@ti.com
wrote:

BABBLE and RESET share the same interrupt. The interrupt
is considered to be RESET if MUSB is in peripheral mode and
as a BABBLE if MUSB is in HOST mode.

Handle babble condition iff MUSB is in HOST mode.

Signed-off-by: George Cherian george.cher...@ti.com
---
   drivers/usb/musb/musb_core.c | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 61da471..eff3c5c 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -849,7 +849,7 @@ b_host:
  }

  /* handle babble condition */
-   if (int_usb  MUSB_INTR_BABBLE)
+   if (int_usb  MUSB_INTR_BABBLE  is_host_active(musb))
  schedule_work(musb-recover_work);

I guess my following comments are for Daniel's patch as while which
initially added the babble work.

Should this if statement be merged into the previous 'if(int_usb 
MUSB_INTR_RESET)' one, which handles the same interrupt and already
handles host and device mode respectively.


Initially I too had the babble handling as part of  'if(int_usb 
MUSB_INTR_RESET)'
one. But during my tests I hit a corner case where in we hit a BABBLE
condition
on disconnect. In such case the babble interrupt can be handled only if we
have a seperate
check, else its considered as a BUS RESET.

When all devices are disconnected  MUSB_DEVCTL_HM = 0 and the code always
enter the
else path. In this path it treats the BABBLE as a BUS RESET.

The code flow is a bit confusing, two if() handle the same interrupt.
The second one implied using 'handled = IRQ_HANDLED;' from the first
one.
Also does the switch() in else{} in the first if() cause any side effect?

No it doesn't.

Since this babble handing is AM335x specific, how about handle it in
dsps_interrupt() in musb_dsps.c, which already has an entry for babble
interrupt? TI 3.2 kernel does this way.
That the reason we have platform specific callbacks added  from the main 
interrupt handler.

Regards,
-Bin.




Regards,
-Bin.


   #if 0
--
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



--
-George




--
-George

--
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 v6 3/5] usb: musb: dsps: Call usb_phy(_shutdown/_init) during musb_platform_reset()

2014-05-26 Thread George Cherian
For DSPS platform usb_phy_vbus(_off/_on) are NOPs.
So during musb_platform_reset() call usb_phy(_shutdown/_init)

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_dsps.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 51beb13..74c4193 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -543,7 +543,11 @@ static void dsps_musb_reset(struct musb *musb)
const struct dsps_musb_wrapper *wrp = glue-wrp;
 
dsps_writel(musb-ctrl_base, wrp-control, (1  wrp-reset));
-   udelay(100);
+   usleep_range(100, 200);
+   usb_phy_shutdown(musb-xceiv);
+   usleep_range(100, 200);
+   usb_phy_init(musb-xceiv);
+
 }
 
 static struct musb_platform_ops dsps_ops = {
-- 
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


[PATCH v6 4/5] usb: musb: core: Convert the musb_platform_reset to have a return value.

2014-05-26 Thread George Cherian
Currently musb_platform_reset() is only used by dsps.
In case of BABBLE interrupt for other platforms the  musb_platform_reset()
is a NOP. In such situations no need to re-initialize the endpoints.
Also in the latest silicon revision of AM335x, we do have a babble recovery
mechanism without resetting the IP block. In preperation to add that support
its better to have a rest_done return for  musb_platform_reset().

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_core.c | 10 ++
 drivers/usb/musb/musb_core.h | 10 ++
 drivers/usb/musb/musb_dsps.c |  3 ++-
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index c0ce09f..b841ee0 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1753,9 +1753,11 @@ static void musb_irq_work(struct work_struct *data)
 static void musb_recover_work(struct work_struct *data)
 {
struct musb *musb = container_of(data, struct musb, recover_work.work);
-   int status;
+   int status, ret;
 
-   musb_platform_reset(musb);
+   ret  = musb_platform_reset(musb);
+   if (ret)
+   return;
 
usb_phy_vbus_off(musb-xceiv);
usleep_range(100, 200);
@@ -1764,8 +1766,8 @@ static void musb_recover_work(struct work_struct *data)
usleep_range(100, 200);
 
/*
-* When a babble condition occurs, the musb controller removes the
-* session bit and the endpoint config is lost.
+* When a babble condition occurs, the musb controller
+* removes the session bit and the endpoint config is lost.
 */
if (musb-dyn_fifo)
status = ep_config_from_table(musb);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 9241025..414e57a 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -192,7 +192,7 @@ struct musb_platform_ops {
 
int (*set_mode)(struct musb *musb, u8 mode);
void(*try_idle)(struct musb *musb, unsigned long timeout);
-   void(*reset)(struct musb *musb);
+   int (*reset)(struct musb *musb);
 
int (*vbus_status)(struct musb *musb);
void(*set_vbus)(struct musb *musb, int on);
@@ -555,10 +555,12 @@ static inline void musb_platform_try_idle(struct musb 
*musb,
musb-ops-try_idle(musb, timeout);
 }
 
-static inline void musb_platform_reset(struct musb *musb)
+static inline int  musb_platform_reset(struct musb *musb)
 {
-   if (musb-ops-reset)
-   musb-ops-reset(musb);
+   if (!musb-ops-reset)
+   return -EINVAL;
+
+   return musb-ops-reset(musb);
 }
 
 static inline int musb_platform_get_vbus_status(struct musb *musb)
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 74c4193..f6f3087 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -536,7 +536,7 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode)
return 0;
 }
 
-static void dsps_musb_reset(struct musb *musb)
+static int dsps_musb_reset(struct musb *musb)
 {
struct device *dev = musb-controller;
struct dsps_glue *glue = dev_get_drvdata(dev-parent);
@@ -548,6 +548,7 @@ static void dsps_musb_reset(struct musb *musb)
usleep_range(100, 200);
usb_phy_init(musb-xceiv);
 
+   return 0;
 }
 
 static struct musb_platform_ops dsps_ops = {
-- 
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


[PATCH v6 5/5] usb: musb: dsps: Add the sw_babble_control() and Enable for newer silicon

2014-05-26 Thread George Cherian
Add sw_babble_control() logic to differentiate between transient
babble and real babble condition. Also add the SW babble control
register definitions.

Babble control register logic is implemented in the latest
revision of AM335x.

Find whether we are running on newer silicon. The babble control
register reads 0x4 by default in newer silicon as opposed to 0
in old versions of AM335x. Based on this enable the sw babble
control logic.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_dsps.c | 89 +---
 drivers/usb/musb/musb_regs.h |  7 
 2 files changed, 90 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index f6f3087..01543a9 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -136,6 +136,7 @@ struct dsps_glue {
const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
struct timer_list timer;/* otg_workaround timer */
unsigned long last_timer;/* last timer data for each instance */
+   bool sw_babble_enabled;
 
struct dsps_context context;
struct debugfs_regset32 regset;
@@ -469,6 +470,19 @@ static int dsps_musb_init(struct musb *musb)
val = ~(1  wrp-otg_disable);
dsps_writel(musb-ctrl_base, wrp-phy_utmi, val);
 
+   /*
+*  Check whether the dsps version has babble control enabled.
+* In latest silicon revision the babble control logic is enabled.
+* If MUSB_BABBLE_CTL returns 0x4 then we have the babble control
+* logic enabled.
+*/
+   val = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   if (val == MUSB_BABBLE_RCV_DISABLE) {
+   glue-sw_babble_enabled = true;
+   val |= MUSB_BABBLE_SW_SESSION_CTRL;
+   dsps_writeb(musb-mregs, MUSB_BABBLE_CTL, val);
+   }
+
ret = dsps_musb_dbg_init(musb, glue);
if (ret)
return ret;
@@ -536,19 +550,82 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode)
return 0;
 }
 
+static bool  sw_babble_control(struct musb *musb)
+{
+   u8 babble_ctl;
+   bool session_restart =  false;
+
+   babble_ctl = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   dev_dbg(musb-controller, babble: MUSB_BABBLE_CTL value %x\n,
+   babble_ctl);
+   /*
+* check line monitor flag to check whether babble is
+* due to noise
+*/
+   dev_dbg(musb-controller, STUCK_J is %s\n,
+   babble_ctl  MUSB_BABBLE_STUCK_J ? set : reset);
+
+   if (babble_ctl  MUSB_BABBLE_STUCK_J) {
+   int timeout = 10;
+
+   /*
+* babble is due to noise, then set transmit idle (d7 bit)
+* to resume normal operation
+*/
+   babble_ctl = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   babble_ctl |= MUSB_BABBLE_FORCE_TXIDLE;
+   dsps_writeb(musb-mregs, MUSB_BABBLE_CTL, babble_ctl);
+
+   /* wait till line monitor flag cleared */
+   dev_dbg(musb-controller, Set TXIDLE, wait J to clear\n);
+   do {
+   babble_ctl = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   udelay(1);
+   } while ((babble_ctl  MUSB_BABBLE_STUCK_J)  timeout--);
+
+   /* check whether stuck_at_j bit cleared */
+   if (babble_ctl  MUSB_BABBLE_STUCK_J) {
+   /*
+* real babble condition has occurred
+* restart the controller to start the
+* session again
+*/
+   dev_dbg(musb-controller, J not cleared, misc (%x)\n,
+   babble_ctl);
+   session_restart = true;
+   }
+   } else {
+   session_restart = true;
+   }
+
+   return session_restart;
+}
+
 static int dsps_musb_reset(struct musb *musb)
 {
struct device *dev = musb-controller;
struct dsps_glue *glue = dev_get_drvdata(dev-parent);
const struct dsps_musb_wrapper *wrp = glue-wrp;
+   int session_restart = 0;
 
-   dsps_writel(musb-ctrl_base, wrp-control, (1  wrp-reset));
-   usleep_range(100, 200);
-   usb_phy_shutdown(musb-xceiv);
-   usleep_range(100, 200);
-   usb_phy_init(musb-xceiv);
+   if (glue-sw_babble_enabled)
+   session_restart = sw_babble_control(musb);
+   /*
+* In case of new silicon version babble condition can be recovered
+* without resetting the MUSB. But for older silicon versions, MUSB
+* reset is needed
+*/
+   if (session_restart || !glue-sw_babble_enabled) {
+   dev_info(musb-controller, Restarting MUSB to recover from 
Babble\n);
+   dsps_writel(musb-ctrl_base, wrp-control, (1  wrp-reset

[PATCH v6 0/5] Add support for SW babble Control

2014-05-26 Thread George Cherian
Series add support for SW babble control logic found in 
new silicon versions of AM335x. Runtime differentiation of
silicon version is done by checking the BABBLE_CTL register.
For newer silicon the register default value read is 0x4 and
for older versions its 0x0.

Patch 1 - Handle Babble only if MUSB is in HOST mode
Patch 2 - Convert recover work to delayed work.
Patch 3 - usb_phy_vbus_(off/_on) are NOPs for am335x PHY
   so use usb_phy(_shutdown/_init) in musb_platform_reset()
Patch 4 - Add return value for musb_platform_reset() in prepration
   to support SW babble_ctrl
Patch 5 - Add and Enable sw babble control for newer silicon

v5 - v6 : Squash patch 5 and 6 form v5 to avoid build warnings.

v4 - v5 : Added a debug print before resetting MUSB.
   changed a musb_readb to dsps_readb introduced in Patch#5 of v4.

v3 - v4 : Fixes an issue in gagdet mode - BUS RESET should not
   be handled as a BABBLE. Added a check for the same.(Patch #1)
   Enable sw babble control properly (Patch #6)

v2 - v3 : Modify musb_platform_reset() to return zero on success.



George Cherian (5):
  usb: musb: core: Handle Babble condition only in HOST mode
  usb: musb: core: Convert babble recover work to delayed work
  usb: musb: dsps: Call usb_phy(_shutdown/_init) during
musb_platform_reset()
  usb: musb: core: Convert the musb_platform_reset to have a return
value.
  usb: musb: dsps: Add the sw_babble_control() and Enable for newer
silicon

 drivers/usb/musb/musb_core.c | 27 --
 drivers/usb/musb/musb_core.h | 12 +++---
 drivers/usb/musb/musb_dsps.c | 88 ++--
 drivers/usb/musb/musb_regs.h |  7 
 4 files changed, 114 insertions(+), 20 deletions(-)

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


[PATCH v6 2/5] usb: musb: core: Convert babble recover work to delayed work

2014-05-26 Thread George Cherian
During babble condition both first disconnect of devices are
initiated. Make sure MUSB controller is reset and re-initialized
after all disconnects.

To acheive this schedule a delayed work for babble recovery.

While at that convert udelay to usleep_range.
Refer Documentation/timers/timers-howto.txt

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_core.c | 15 ---
 drivers/usb/musb/musb_core.h |  2 +-
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 0ad9551..c0ce09f 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -850,7 +850,8 @@ b_host:
 
/* handle babble condition */
if (int_usb  MUSB_INTR_BABBLE  is_host_active(musb))
-   schedule_work(musb-recover_work);
+   schedule_delayed_work(musb-recover_work,
+ msecs_to_jiffies(100));
 
 #if 0
 /* REVISIT ... this would be for multiplexing periodic endpoints, or
@@ -1751,16 +1752,16 @@ static void musb_irq_work(struct work_struct *data)
 /* Recover from babble interrupt conditions */
 static void musb_recover_work(struct work_struct *data)
 {
-   struct musb *musb = container_of(data, struct musb, recover_work);
+   struct musb *musb = container_of(data, struct musb, recover_work.work);
int status;
 
musb_platform_reset(musb);
 
usb_phy_vbus_off(musb-xceiv);
-   udelay(100);
+   usleep_range(100, 200);
 
usb_phy_vbus_on(musb-xceiv);
-   udelay(100);
+   usleep_range(100, 200);
 
/*
 * When a babble condition occurs, the musb controller removes the
@@ -1943,7 +1944,7 @@ musb_init_controller(struct device *dev, int nIrq, void 
__iomem *ctrl)
 
/* Init IRQ workqueue before request_irq */
INIT_WORK(musb-irq_work, musb_irq_work);
-   INIT_WORK(musb-recover_work, musb_recover_work);
+   INIT_DELAYED_WORK(musb-recover_work, musb_recover_work);
INIT_DELAYED_WORK(musb-deassert_reset_work, musb_deassert_reset);
INIT_DELAYED_WORK(musb-finish_resume_work, musb_host_finish_resume);
 
@@ -2039,7 +2040,7 @@ fail4:
 
 fail3:
cancel_work_sync(musb-irq_work);
-   cancel_work_sync(musb-recover_work);
+   cancel_delayed_work_sync(musb-recover_work);
cancel_delayed_work_sync(musb-finish_resume_work);
cancel_delayed_work_sync(musb-deassert_reset_work);
if (musb-dma_controller)
@@ -2105,7 +2106,7 @@ static int musb_remove(struct platform_device *pdev)
dma_controller_destroy(musb-dma_controller);
 
cancel_work_sync(musb-irq_work);
-   cancel_work_sync(musb-recover_work);
+   cancel_delayed_work_sync(musb-recover_work);
cancel_delayed_work_sync(musb-finish_resume_work);
cancel_delayed_work_sync(musb-deassert_reset_work);
musb_free(musb);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index d155a15..9241025 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -297,7 +297,7 @@ struct musb {
 
irqreturn_t (*isr)(int, void *);
struct work_struct  irq_work;
-   struct work_struct  recover_work;
+   struct delayed_work recover_work;
struct delayed_work deassert_reset_work;
struct delayed_work finish_resume_work;
u16 hwvers;
-- 
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


[PATCH v6 1/5] usb: musb: core: Handle Babble condition only in HOST mode

2014-05-26 Thread George Cherian
BABBLE and RESET share the same interrupt. The interrupt
is considered to be RESET if MUSB is in peripheral mode and
as a BABBLE if MUSB is in HOST mode.

Handle babble condition iff MUSB is in HOST mode.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 3c6043c..0ad9551 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -849,7 +849,7 @@ b_host:
}
 
/* handle babble condition */
-   if (int_usb  MUSB_INTR_BABBLE)
+   if (int_usb  MUSB_INTR_BABBLE  is_host_active(musb))
schedule_work(musb-recover_work);
 
 #if 0
-- 
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 v2 5/6] usb: musb: introduce dma_channel.packet_done

2014-05-23 Thread George Cherian

On 5/23/2014 3:01 PM, Daniel Mack wrote:

The musb/cppi41 glue layer is capable of handling transactions that span
over more than one USB packet by reloading the DMA descriptors
partially. An urb is considered completed when either its transfer
buffer has been filled entirely (actual_length ==
transfer_buffer_length) or if a packet in the stream has less bytes than
the endpoint's wMaxPacketSize.

Can you explain a bit more. Doesn't it checks for
actual_length + xfer_len = transfer_buffer_length ?

This check is also failing?


Once one of the above conditions is met, musb_dma_completion() is called
from cppi41_trans_done(). However, the final decision whether or not to
return the urb to its owner is made by the core, which currently has no
way of knowing what the last packet size was, as long as DMA and a glue
layer is involved. Hence, it won't give the urb back, effectively
starving the data stream.

Fix this by introducing a new boolean flag in 'struct dma_channel'
which, and set it from musb_cppi41.c. If set, it will make the core do
what the DMA layer decided and complete the urb.

Signed-off-by: Daniel Mack zon...@gmail.com
---
  drivers/usb/musb/musb_cppi41.c | 2 ++
  drivers/usb/musb/musb_dma.h| 1 +
  drivers/usb/musb/musb_host.c   | 3 ++-
  3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
index 7b8bbf5..a11bbb6 100644
--- a/drivers/usb/musb/musb_cppi41.c
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -139,6 +139,7 @@ static void cppi41_trans_done(struct cppi41_dma_channel 
*cppi41_channel)
cppi41_channel-channel.actual_len =
cppi41_channel-transferred;
cppi41_channel-channel.status = MUSB_DMA_STATUS_FREE;
+   cppi41_channel-channel.packet_done = true;
musb_dma_completion(musb, hw_ep-epnum, cppi41_channel-is_tx);
} else {
/* next iteration, reload */
@@ -450,6 +451,7 @@ static bool cppi41_configure_channel(struct dma_channel 
*channel,
dma_desc-callback = cppi41_dma_callback;
dma_desc-callback_param = channel;
cppi41_channel-cookie = dma_desc-tx_submit(dma_desc);
+   cppi41_channel-channel.packet_done = false;
  
  	save_rx_toggle(cppi41_channel);

dma_async_issue_pending(dc);
diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h
index 1345a4f..7253358 100644
--- a/drivers/usb/musb/musb_dma.h
+++ b/drivers/usb/musb/musb_dma.h
@@ -129,6 +129,7 @@ struct dma_channel {
size_t  actual_len;
enum dma_channel_status status;
booldesired_mode;
+   boolpacket_done;
  };
  
  /*

diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 9d3a5b2..6531426 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -1738,7 +1738,8 @@ void musb_host_rx(struct musb *musb, u8 epnum)
/* done if urb buffer is full or short packet is recd */
done = (urb-actual_length + xfer_len =
urb-transfer_buffer_length
-   || dma-actual_len  qh-maxpacket);
+   || dma-actual_len  qh-maxpacket
+   || dma-packet_done);
}
  
  		/* send IN token for next packet, without AUTOREQ */



--
-George

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


Re: [PATCH v2 5/6] usb: musb: introduce dma_channel.packet_done

2014-05-23 Thread George Cherian

On 5/23/2014 5:04 PM, Daniel Mack wrote:

Hi George,

Thanks for having a look!

On 05/23/2014 01:24 PM, George Cherian wrote:

On 5/23/2014 3:01 PM, Daniel Mack wrote:

The musb/cppi41 glue layer is capable of handling transactions that span
over more than one USB packet by reloading the DMA descriptors
partially. An urb is considered completed when either its transfer
buffer has been filled entirely (actual_length ==
transfer_buffer_length) or if a packet in the stream has less bytes than
the endpoint's wMaxPacketSize.

Can you explain a bit more.

Sure.


Doesn't it checks for
actual_length + xfer_len = transfer_buffer_length ?

This check is also failing?

Yes. For the driver I'm testing with, transfer_buffer_length is 16k.

Assume wMaxPacketSize == 512 and the following sequence of incoming
packet sizes: 512, 512, 384. The URB should be given back after the 384
packet has been received, with an effective total length of 1408 bytes.

The code in musb_cppi41.c does the right thing by not reloading a new
DMA descriptor but calling musb_dma_completion() from
cppi41_trans_done(). However, both checks for 'done' that the core
currently looks at a false in that case (musb_host.c, ~ line 1740):

In rx we always use the transparent mode of CPPI dma.
In transparent mode we always program the min( packet_sz,len) 
[musb_cppi41.c cppi41_configure_channel()]

In your example len is 16K and packet_sz is wMaxPacketSize.

Basically it always does a wMaxPacketSize of dma and updates the 
urb-actual_length in return.


In RX we cant use the Generic RNDIS mode of CPPI, due to some of the 
bugs in the silicon.

  done = (urb-actual_length + xfer_len = urb-transfer_buffer_length
 || dma-actual_len  qh-maxpacket);

... because dma-actual_len is already 1408, and hence the maxpacket
size check doesn't make sense in such cases.

This is why I added a new flag to overrule that decision from the cppi41
glue layer.


HTH,
Daniel




--
-George

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


Re: [PATCH v2 2/6] usb: musb: remove unnecessary (void) prefix at function calls

2014-05-23 Thread George Cherian

On 5/23/2014 3:00 PM, Daniel Mack wrote:

Just a little cleanup that removes unnecessary casts.

Signed-off-by: Daniel Mack zon...@gmail.com

Acked-by: George Cherian george.cher...@ti.com

---
  drivers/usb/musb/musb_host.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index eb06291..f98a7c0 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -1295,7 +1295,7 @@ done:
if (status) {
if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
dma-status = MUSB_DMA_STATUS_CORE_ABORT;
-   (void) musb-dma_controller-channel_abort(dma);
+   musb-dma_controller-channel_abort(dma);
}
  
  		/* do the proper sequence to abort the transfer in the

@@ -1640,7 +1640,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
/* clean up dma and collect transfer count */
if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
dma-status = MUSB_DMA_STATUS_CORE_ABORT;
-   (void) musb-dma_controller-channel_abort(dma);
+   musb-dma_controller-channel_abort(dma);
xfer_len = dma-actual_len;
}
musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG);
@@ -1671,7 +1671,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
 */
if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
dma-status = MUSB_DMA_STATUS_CORE_ABORT;
-   (void) musb-dma_controller-channel_abort(dma);
+   musb-dma_controller-channel_abort(dma);
xfer_len = dma-actual_len;
done = true;
}



--
-George

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


Re: [PATCH v2 6/6] usb: musb/cppi41: call musb_ep_select() before accessing an endpoint's CSR

2014-05-23 Thread George Cherian

On 5/23/2014 3:01 PM, Daniel Mack wrote:

Before accessing any of an endpoint's CSR registers, make sure the
correct endpoint is selected. Otherwise, data read from or written to
the registers is likely to affect the wrong endpoint as long as the
connected device has more than one endpoint.

This, of course, leads to all sorts of strange effects such as stream
starvation and driver internal state machine confusion due to spurious
interrupts.

Signed-off-by: Daniel Mack zon...@gmail.com
---
  drivers/usb/musb/musb_cppi41.c | 17 ++---
  1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
index a11bbb6..db497dd 100644
--- a/drivers/usb/musb/musb_cppi41.c
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -58,14 +58,17 @@ struct cppi41_dma_controller {
  
  static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel)

  {
+   struct musb_hw_ep *hw_ep = cppi41_channel-hw_ep;
+   struct musb *musb = hw_ep-musb;
u16 csr;
u8 toggle;
  
  	if (cppi41_channel-is_tx)

return;
-   if (!is_host_active(cppi41_channel-controller-musb))
+   if (!is_host_active(musb))
return;
  
+	musb_ep_select(musb-mregs, hw_ep-epnum);


save_rx_toggle is called from cppi41_configure_channel as part of 
channel_program() from musb_host_rx()
and musb_ep_program(). Both these functions call musb_ep_select() before 
calling channel_program().


Both musb_ep_program() and musb_host_rx() are called with IRQ's disabled.
Still do we need this musb_ep_select() in save_rx_toggle? Or am I confused?



csr = musb_readw(cppi41_channel-hw_ep-regs, MUSB_RXCSR);
toggle = csr  MUSB_RXCSR_H_DATATOGGLE ? 1 : 0;
  
@@ -74,15 +77,18 @@ static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel)
  
  static void update_rx_toggle(struct cppi41_dma_channel *cppi41_channel)

  {
+   struct musb_hw_ep *hw_ep = cppi41_channel-hw_ep;
+   struct musb *musb = hw_ep-musb;
u16 csr;
u8 toggle;
  
  	if (cppi41_channel-is_tx)

return;
-   if (!is_host_active(cppi41_channel-controller-musb))
+   if (!is_host_active(musb))
return;
  
-	csr = musb_readw(cppi41_channel-hw_ep-regs, MUSB_RXCSR);

+   musb_ep_select(musb-mregs, hw_ep-epnum);

Yes it makes sense to do musb_ep_select() in update_rx_toggle().

+   csr = musb_readw(hw_ep-regs, MUSB_RXCSR);
toggle = csr  MUSB_RXCSR_H_DATATOGGLE ? 1 : 0;
  
  	/*

@@ -107,6 +113,7 @@ static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep)
void __iomem*epio = musb-endpoints[epnum].regs;
u16 csr;
  
+	musb_ep_select(musb-mregs, hw_ep-epnum);

Yes it makes sense here.

csr = musb_readw(epio, MUSB_TXCSR);
if (csr  MUSB_TXCSR_TXPKTRDY)
return false;
@@ -173,6 +180,7 @@ static void cppi41_trans_done(struct cppi41_dma_channel 
*cppi41_channel)
dma_async_issue_pending(dc);
  
  		if (!cppi41_channel-is_tx) {

+   musb_ep_select(musb-mregs, hw_ep-epnum);
Since in update_rx_toggle () we did musb_epe_select(), do we really it 
again here?

csr = musb_readw(epio, MUSB_RXCSR);
csr |= MUSB_RXCSR_H_REQPKT;
musb_writew(epio, MUSB_RXCSR, csr);
@@ -551,6 +559,7 @@ static int cppi41_dma_channel_abort(struct dma_channel 
*channel)
  {
struct cppi41_dma_channel *cppi41_channel = channel-private_data;
struct cppi41_dma_controller *controller = cppi41_channel-controller;
+   struct musb_hw_ep *hw_ep = cppi41_channel-hw_ep;
struct musb *musb = controller-musb;
void __iomem *epio = cppi41_channel-hw_ep-regs;
int tdbit;
@@ -565,6 +574,8 @@ static int cppi41_dma_channel_abort(struct dma_channel 
*channel)
if (cppi41_channel-channel.status == MUSB_DMA_STATUS_FREE)
return 0;
  

musb_ep_select is done before calling channel_abort.

+   musb_ep_select(musb-mregs, hw_ep-epnum);
+
list_del_init(cppi41_channel-tx_check);
if (is_tx) {
csr = musb_readw(epio, MUSB_TXCSR);



--
-George

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


Re: [PATCH v2 6/6] usb: musb/cppi41: call musb_ep_select() before accessing an endpoint's CSR

2014-05-23 Thread George Cherian

On 5/23/2014 6:58 PM, Daniel Mack wrote:

On 05/23/2014 03:18 PM, George Cherian wrote:

On 5/23/2014 3:01 PM, Daniel Mack wrote:

Before accessing any of an endpoint's CSR registers, make sure the
correct endpoint is selected. Otherwise, data read from or written to
the registers is likely to affect the wrong endpoint as long as the
connected device has more than one endpoint.

This, of course, leads to all sorts of strange effects such as stream
starvation and driver internal state machine confusion due to spurious
interrupts.

Signed-off-by: Daniel Mack zon...@gmail.com
---
   drivers/usb/musb/musb_cppi41.c | 17 ++---
   1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
index a11bbb6..db497dd 100644
--- a/drivers/usb/musb/musb_cppi41.c
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -58,14 +58,17 @@ struct cppi41_dma_controller {
   
   static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel)

   {
+   struct musb_hw_ep *hw_ep = cppi41_channel-hw_ep;
+   struct musb *musb = hw_ep-musb;
u16 csr;
u8 toggle;
   
   	if (cppi41_channel-is_tx)

return;
-   if (!is_host_active(cppi41_channel-controller-musb))
+   if (!is_host_active(musb))
return;
   
+	musb_ep_select(musb-mregs, hw_ep-epnum);

save_rx_toggle is called from cppi41_configure_channel as part of
channel_program() from musb_host_rx()
and musb_ep_program(). Both these functions call musb_ep_select() before
calling channel_program().

Both musb_ep_program() and musb_host_rx() are called with IRQ's disabled.
Still do we need this musb_ep_select() in save_rx_toggle? Or am I confused?

No, you're right. It seems not necessary here.


@@ -173,6 +180,7 @@ static void cppi41_trans_done(struct cppi41_dma_channel 
*cppi41_channel)
dma_async_issue_pending(dc);
   
   		if (!cppi41_channel-is_tx) {

+   musb_ep_select(musb-mregs, hw_ep-epnum);

Since in update_rx_toggle () we did musb_epe_select(), do we really it
again here?

I'd say so, because cppi41_trans_done() may be called from a work
tasklet or hrtimer callback. In such cases, another endpoint might have
been selected.


Yes Correct!!!

@@ -565,6 +574,8 @@ static int cppi41_dma_channel_abort(struct dma_channel 
*channel)
if (cppi41_channel-channel.status == MUSB_DMA_STATUS_FREE)
return 0;
   

musb_ep_select is done before calling channel_abort.

Right, thanks for spotting this. I'll drop it in v3.


Thanks,
Daniel




--
-George

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


Re: [PATCH v2 3/6] usb: musb: use is_host_active() to distinguish between host and gadget mode

2014-05-23 Thread George Cherian

On 5/23/2014 3:00 PM, Daniel Mack wrote:

On AM33xx platforms, unplugging a device in the middle of an active
transfer leads to a drop of MUSB_DEVCTL_HM in MUSB_DEVCTL before the
system is informed about a disconnect. This consequently makes the musb
core call the gadget code to handle the interrupt request, which then
crashes the kernel because the relevant pointers haven't been set up
for gadget mode.

To fix this, use is_host_active() rather than (devctl  MUSB_DEVCTL_HM)
in musb_interrupt() and musb_dma_completion() to detect whether the
controller is in host or peripheral mode. This information is provided
by the driver logic and does not rely on register contents.


Yes w.r.t AM33xx platform this looks okay. But since its a core file 
used by different

implementations am not sure of any possible issues.

Signed-off-by: Daniel Mack zon...@gmail.com
---

snip


--
-George

--
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 v5 3/6] usb: musb: dsps: Call usb_phy(_shutdown/_init) during musb_platform_reset()

2014-05-22 Thread George Cherian
For DSPS platform usb_phy_vbus(_off/_on) are NOPs.
So during musb_platform_reset() call usb_phy(_shutdown/_init)

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_dsps.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 51beb13..74c4193 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -543,7 +543,11 @@ static void dsps_musb_reset(struct musb *musb)
const struct dsps_musb_wrapper *wrp = glue-wrp;
 
dsps_writel(musb-ctrl_base, wrp-control, (1  wrp-reset));
-   udelay(100);
+   usleep_range(100, 200);
+   usb_phy_shutdown(musb-xceiv);
+   usleep_range(100, 200);
+   usb_phy_init(musb-xceiv);
+
 }
 
 static struct musb_platform_ops dsps_ops = {
-- 
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


[PATCH v5 1/6] usb: musb: core: Handle Babble condition only in HOST mode

2014-05-22 Thread George Cherian
BABBLE and RESET share the same interrupt. The interrupt
is considered to be RESET if MUSB is in peripheral mode and
as a BABBLE if MUSB is in HOST mode.

Handle babble condition iff MUSB is in HOST mode.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 61da471..eff3c5c 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -849,7 +849,7 @@ b_host:
}
 
/* handle babble condition */
-   if (int_usb  MUSB_INTR_BABBLE)
+   if (int_usb  MUSB_INTR_BABBLE  is_host_active(musb))
schedule_work(musb-recover_work);
 
 #if 0
-- 
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


[PATCH v5 4/6] usb: musb: core: Convert the musb_platform_reset to have a return value.

2014-05-22 Thread George Cherian
Currently musb_platform_reset() is only used by dsps.
In case of BABBLE interrupt for other platforms the  musb_platform_reset()
is a NOP. In such situations no need to re-initialize the endpoints.
Also in the latest silicon revision of AM335x, we do have a babble recovery
mechanism without resetting the IP block. In preperation to add that support
its better to have a rest_done return for  musb_platform_reset().

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_core.c | 10 ++
 drivers/usb/musb/musb_core.h | 10 ++
 drivers/usb/musb/musb_dsps.c |  3 ++-
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 8920b80..7c6836cc 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1755,9 +1755,11 @@ static void musb_irq_work(struct work_struct *data)
 static void musb_recover_work(struct work_struct *data)
 {
struct musb *musb = container_of(data, struct musb, recover_work.work);
-   int status;
+   int status, ret;
 
-   musb_platform_reset(musb);
+   ret  = musb_platform_reset(musb);
+   if (ret)
+   return;
 
usb_phy_vbus_off(musb-xceiv);
usleep_range(100, 200);
@@ -1766,8 +1768,8 @@ static void musb_recover_work(struct work_struct *data)
usleep_range(100, 200);
 
/*
-* When a babble condition occurs, the musb controller removes the
-* session bit and the endpoint config is lost.
+* When a babble condition occurs, the musb controller
+* removes the session bit and the endpoint config is lost.
 */
if (musb-dyn_fifo)
status = ep_config_from_table(musb);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 9241025..414e57a 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -192,7 +192,7 @@ struct musb_platform_ops {
 
int (*set_mode)(struct musb *musb, u8 mode);
void(*try_idle)(struct musb *musb, unsigned long timeout);
-   void(*reset)(struct musb *musb);
+   int (*reset)(struct musb *musb);
 
int (*vbus_status)(struct musb *musb);
void(*set_vbus)(struct musb *musb, int on);
@@ -555,10 +555,12 @@ static inline void musb_platform_try_idle(struct musb 
*musb,
musb-ops-try_idle(musb, timeout);
 }
 
-static inline void musb_platform_reset(struct musb *musb)
+static inline int  musb_platform_reset(struct musb *musb)
 {
-   if (musb-ops-reset)
-   musb-ops-reset(musb);
+   if (!musb-ops-reset)
+   return -EINVAL;
+
+   return musb-ops-reset(musb);
 }
 
 static inline int musb_platform_get_vbus_status(struct musb *musb)
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 74c4193..f6f3087 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -536,7 +536,7 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode)
return 0;
 }
 
-static void dsps_musb_reset(struct musb *musb)
+static int dsps_musb_reset(struct musb *musb)
 {
struct device *dev = musb-controller;
struct dsps_glue *glue = dev_get_drvdata(dev-parent);
@@ -548,6 +548,7 @@ static void dsps_musb_reset(struct musb *musb)
usleep_range(100, 200);
usb_phy_init(musb-xceiv);
 
+   return 0;
 }
 
 static struct musb_platform_ops dsps_ops = {
-- 
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


[PATCH v5 5/6] usb: musb: dsps: Add the sw_babble_control()

2014-05-22 Thread George Cherian
Add sw_babble_control() logic to differentiate between transient
babble and real babble condition. Also add the SW babble control
register definitions.

Babble control register logic is implemented in the latest
revision of AM335x.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_dsps.c | 50 
 drivers/usb/musb/musb_regs.h |  7 +++
 2 files changed, 57 insertions(+)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index f6f3087..868caf8 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -536,6 +536,56 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode)
return 0;
 }
 
+static int sw_babble_control(struct musb *musb)
+{
+   int timeout = 10;
+   u8 babble_ctl, session_restart = 0;
+
+   babble_ctl = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   dev_dbg(musb-controller, babble: MUSB_BABBLE_CTL value %x\n,
+   babble_ctl);
+   /*
+* check line monitor flag to check whether babble is
+* due to noise
+*/
+   dev_dbg(musb-controller, STUCK_J is %s\n,
+   babble_ctl  MUSB_BABBLE_STUCK_J ? set : reset);
+
+   if (babble_ctl  MUSB_BABBLE_STUCK_J) {
+   /*
+* babble is due to noise, then set transmit idle (d7 bit)
+* to resume normal operation
+*/
+   babble_ctl = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   babble_ctl |= MUSB_BABBLE_FORCE_TXIDLE;
+   dsps_writeb(musb-mregs, MUSB_BABBLE_CTL, babble_ctl);
+
+   /* wait till line monitor flag cleared */
+   dev_dbg(musb-controller, Set TXIDLE, wait J to clear\n);
+   do {
+   babble_ctl = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   udelay(1);
+   } while ((babble_ctl  MUSB_BABBLE_STUCK_J)  timeout--);
+
+   /* check whether stuck_at_j bit cleared */
+   if (babble_ctl  MUSB_BABBLE_STUCK_J) {
+   /*
+* real babble condition is occured
+* restart the controller to start the
+* session again
+*/
+   dev_dbg(musb-controller, J not cleared, misc (%x)\n,
+   babble_ctl);
+   session_restart = 1;
+   }
+
+   } else {
+   session_restart = 1;
+   }
+
+   return session_restart;
+}
+
 static int dsps_musb_reset(struct musb *musb)
 {
struct device *dev = musb-controller;
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
index 03f2655..b9bcda5 100644
--- a/drivers/usb/musb/musb_regs.h
+++ b/drivers/usb/musb/musb_regs.h
@@ -72,6 +72,12 @@
 #define MUSB_DEVCTL_HR 0x02
 #define MUSB_DEVCTL_SESSION0x01
 
+/* BABBLE_CTL */
+#define MUSB_BABBLE_FORCE_TXIDLE   0x80
+#define MUSB_BABBLE_SW_SESSION_CTRL0x40
+#define MUSB_BABBLE_STUCK_J0x20
+#define MUSB_BABBLE_RCV_DISABLE0x04
+
 /* MUSB ULPI VBUSCONTROL */
 #define MUSB_ULPI_USE_EXTVBUS  0x01
 #define MUSB_ULPI_USE_EXTVBUSIND 0x02
@@ -246,6 +252,7 @@
  */
 
 #define MUSB_DEVCTL0x60/* 8 bit */
+#define MUSB_BABBLE_CTL0x61/* 8 bit */
 
 /* These are always controlled through the INDEX register */
 #define MUSB_TXFIFOSZ  0x62/* 8-bit (see masks) */
-- 
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


[PATCH v5 6/6] usb: musb: dsps: Enable sw babble control for newer silicon

2014-05-22 Thread George Cherian
Find whether we are running on newer silicon. The babble control
register reads 0x4 by default in newer silicon as opposed to 0
in old versions of AM335x. Based on this enable the sw babble
control logic.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_dsps.c | 38 --
 1 file changed, 32 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 868caf8..2ced061 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -136,6 +136,7 @@ struct dsps_glue {
const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
struct timer_list timer;/* otg_workaround timer */
unsigned long last_timer;/* last timer data for each instance */
+   bool sw_babble_enabled;
 
struct dsps_context context;
struct debugfs_regset32 regset;
@@ -469,6 +470,19 @@ static int dsps_musb_init(struct musb *musb)
val = ~(1  wrp-otg_disable);
dsps_writel(musb-ctrl_base, wrp-phy_utmi, val);
 
+   /*
+*  Check whether the dsps version has babble control enabled.
+* In latest silicon revision the babble control logic is enabled.
+* If MUSB_BABBLE_CTL returns 0x4 then we have the babble control
+* logic enabled.
+*/
+   val = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   if (val == MUSB_BABBLE_RCV_DISABLE) {
+   glue-sw_babble_enabled = true;
+   val |= MUSB_BABBLE_SW_SESSION_CTRL;
+   dsps_writeb(musb-mregs, MUSB_BABBLE_CTL, val);
+   }
+
ret = dsps_musb_dbg_init(musb, glue);
if (ret)
return ret;
@@ -591,14 +605,26 @@ static int dsps_musb_reset(struct musb *musb)
struct device *dev = musb-controller;
struct dsps_glue *glue = dev_get_drvdata(dev-parent);
const struct dsps_musb_wrapper *wrp = glue-wrp;
+   int session_restart = 0;
 
-   dsps_writel(musb-ctrl_base, wrp-control, (1  wrp-reset));
-   usleep_range(100, 200);
-   usb_phy_shutdown(musb-xceiv);
-   usleep_range(100, 200);
-   usb_phy_init(musb-xceiv);
+   if (glue-sw_babble_enabled)
+   session_restart = sw_babble_control(musb);
+   /*
+* In case of new silicon version babble condition can be recovered
+* without resetting the MUSB. But for older silicon versions, MUSB
+* reset is needed
+*/
+   if (session_restart || !glue-sw_babble_enabled) {
+   dev_info(musb-controller, Restarting MUSB to recover from 
Babble\n);
+   dsps_writel(musb-ctrl_base, wrp-control, (1  wrp-reset));
+   usleep_range(100, 200);
+   usb_phy_shutdown(musb-xceiv);
+   usleep_range(100, 200);
+   usb_phy_init(musb-xceiv);
+   session_restart = 1;
+   }
 
-   return 0;
+   return !session_restart;
 }
 
 static struct musb_platform_ops dsps_ops = {
-- 
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


[PATCH v5 0/6] Add support for SW babble Control

2014-05-22 Thread George Cherian
Series add support for SW babble control logic found in 
new silicon versions of AM335x. Runtime differentiation of
silicon version is done by checking the BABBLE_CTL register.
For newer silicon the register default value read is 0x4 and
for older versions its 0x0.

Patch 1 - Handle Babble only if MUSB is in HOST mode
Patch 2 - Convert recover work to delayed work.
Patch 3 - usb_phy_vbus_(off/_on) are NOPs for am335x PHY
   so use usb_phy(_shutdown/_init) in musb_platform_reset()
Patch 4 - Add return value for musb_platform_reset() in prepration
   to support SW babble_ctrl
Patch 5 - Add the sw_babble_control()
Patch 6 - Enable sw babble control for newer silicon

v4 - v5 : Added a debug print before resetting MUSB.
   changed a musb_readb to dsps_readb introduced in Patch#5 of v4.

v3 - v4 : Fixes an issue in gagdet mode - BUS RESET should not
   be handled as a BABBLE. Added a check for the same.(Patch #1)
   Enable sw babble control properly (Patch #6)

v2 - v3 : Modify musb_platform_reset() to return zero on success.

George Cherian (6):
  usb: musb: core: Handle Babble condition only in HOST mode
  usb: musb: core: Convert babble recover work to delayed work
  usb: musb: dsps: Call usb_phy(_shutdown/_init) during
musb_platform_reset()
  usb: musb: core: Convert the musb_platform_reset to have a return
value.
  usb: musb: dsps: Add the sw_babble_control()
  usb: musb: dsps: Enable sw babble control for newer silicon

 drivers/usb/musb/musb_core.c | 27 --
 drivers/usb/musb/musb_core.h | 12 +++---
 drivers/usb/musb/musb_dsps.c | 87 ++--
 drivers/usb/musb/musb_regs.h |  7 
 4 files changed, 113 insertions(+), 20 deletions(-)

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


[PATCH v5 2/6] usb: musb: core: Convert babble recover work to delayed work

2014-05-22 Thread George Cherian
During babble condition both first disconnect of devices are
initiated. Make sure MUSB controller is reset and re-initialized
after all disconnects.

To acheive this schedule a delayed work for babble rrecovery.

While at that convert udelay to usleep_range.
Refer Documentation/timers/timers-howto.txt

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_core.c | 15 ---
 drivers/usb/musb/musb_core.h |  2 +-
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index eff3c5c..8920b80 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -850,7 +850,8 @@ b_host:
 
/* handle babble condition */
if (int_usb  MUSB_INTR_BABBLE  is_host_active(musb))
-   schedule_work(musb-recover_work);
+   schedule_delayed_work(musb-recover_work,
+ msecs_to_jiffies(100));
 
 #if 0
 /* REVISIT ... this would be for multiplexing periodic endpoints, or
@@ -1753,16 +1754,16 @@ static void musb_irq_work(struct work_struct *data)
 /* Recover from babble interrupt conditions */
 static void musb_recover_work(struct work_struct *data)
 {
-   struct musb *musb = container_of(data, struct musb, recover_work);
+   struct musb *musb = container_of(data, struct musb, recover_work.work);
int status;
 
musb_platform_reset(musb);
 
usb_phy_vbus_off(musb-xceiv);
-   udelay(100);
+   usleep_range(100, 200);
 
usb_phy_vbus_on(musb-xceiv);
-   udelay(100);
+   usleep_range(100, 200);
 
/*
 * When a babble condition occurs, the musb controller removes the
@@ -1945,7 +1946,7 @@ musb_init_controller(struct device *dev, int nIrq, void 
__iomem *ctrl)
 
/* Init IRQ workqueue before request_irq */
INIT_WORK(musb-irq_work, musb_irq_work);
-   INIT_WORK(musb-recover_work, musb_recover_work);
+   INIT_DELAYED_WORK(musb-recover_work, musb_recover_work);
INIT_DELAYED_WORK(musb-deassert_reset_work, musb_deassert_reset);
INIT_DELAYED_WORK(musb-finish_resume_work, musb_host_finish_resume);
 
@@ -2041,7 +2042,7 @@ fail4:
 
 fail3:
cancel_work_sync(musb-irq_work);
-   cancel_work_sync(musb-recover_work);
+   cancel_delayed_work_sync(musb-recover_work);
cancel_delayed_work_sync(musb-finish_resume_work);
cancel_delayed_work_sync(musb-deassert_reset_work);
if (musb-dma_controller)
@@ -2107,7 +2108,7 @@ static int musb_remove(struct platform_device *pdev)
dma_controller_destroy(musb-dma_controller);
 
cancel_work_sync(musb-irq_work);
-   cancel_work_sync(musb-recover_work);
+   cancel_delayed_work_sync(musb-recover_work);
cancel_delayed_work_sync(musb-finish_resume_work);
cancel_delayed_work_sync(musb-deassert_reset_work);
musb_free(musb);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index d155a15..9241025 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -297,7 +297,7 @@ struct musb {
 
irqreturn_t (*isr)(int, void *);
struct work_struct  irq_work;
-   struct work_struct  recover_work;
+   struct delayed_work recover_work;
struct delayed_work deassert_reset_work;
struct delayed_work finish_resume_work;
u16 hwvers;
-- 
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 v5 6/6] usb: musb: dsps: Enable sw babble control for newer silicon

2014-05-22 Thread George Cherian

On 5/22/2014 5:28 PM, Sergei Shtylyov wrote:

Hello.

On 22-05-2014 10:29, George Cherian wrote:


Find whether we are running on newer silicon. The babble control
register reads 0x4 by default in newer silicon as opposed to 0
in old versions of AM335x. Based on this enable the sw babble
control logic.



Signed-off-by: George Cherian george.cher...@ti.com
---
  drivers/usb/musb/musb_dsps.c | 38 
--

  1 file changed, 32 insertions(+), 6 deletions(-)



diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 868caf8..2ced061 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c

[...]

@@ -469,6 +470,19 @@ static int dsps_musb_init(struct musb *musb)
  val = ~(1  wrp-otg_disable);
  dsps_writel(musb-ctrl_base, wrp-phy_utmi, val);

+/*
+ *  Check whether the dsps version has babble control enabled.


   One space too many before this sentence.


+ * In latest silicon revision the babble control logic is enabled.
+ * If MUSB_BABBLE_CTL returns 0x4 then we have the babble control
+ * logic enabled.
+ */
+val = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+if (val == MUSB_BABBLE_RCV_DISABLE) {
+glue-sw_babble_enabled = true;
+val |= MUSB_BABBLE_SW_SESSION_CTRL;
+dsps_writeb(musb-mregs, MUSB_BABBLE_CTL, val);
+}
+


   Hm, from the register offset that you declared in the previous 
patch, I got an impression that this is a new standard MUSB register? 

Its very AM335x MUSB specific register, not a standard one.
Unfortunately the designers put it as part of MUSB core regs.

Shouldn't this check be done in the generic MUSB code then?

WBR, Sergei




--
-George

--
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 0/6] Cleanup and fixes for dwc3-omap

2014-05-21 Thread George Cherian
The series does some refactoring on dwc3_probe()

Patch 1 - Now that we use driver compatible for revision check, remove the 
unnecessary logic.
Patch 2-4 - reduce the size of dwc3_probe()
Patch 5 - Fix the crash on dwc3_omap removal
Patch 6 - Addresses the issue of  xhci hang while resuming from system sleep.

George Cherian (6):
  usb: dwc3: dwc3-omap: Remove x_major calculation from revision
register
  usb: dwc3: dwc3-omap: Add dwc3_omap_map_offset() function
  usb: dwc3: dwc3-omap: Add dwc3_omap_set_utmi_mode() function
  usb: dwc3: dwc3-omap: Add dwc3_omap_extcon_register function
  usb: dwc3: dwc3-omap: Fix the crash on module removal
  usb: dwc3: dwc3-omap: Disable/Enable only wrapper interrupts in
prepare/complete

 drivers/usb/dwc3/dwc3-omap.c | 187 +++
 1 file changed, 98 insertions(+), 89 deletions(-)

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


[PATCH v3 3/6] usb: dwc3: dwc3-omap: Add dwc3_omap_set_utmi_mode() function

2014-05-21 Thread George Cherian
Move find and set the utmi mode to its own seperate function.
Improve code readability, decrease the dwc3_probe() size.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 44 +---
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 09918ac..56ec6eb 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -397,6 +397,30 @@ static void dwc3_omap_map_offset(struct dwc3_omap *omap)
}
 }
 
+static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap)
+{
+   u32 reg;
+   struct device_node  *node = omap-dev-of_node;
+   int utmi_mode = 0;
+
+   reg = dwc3_omap_read_utmi_status(omap);
+
+   of_property_read_u32(node, utmi-mode, utmi_mode);
+
+   switch (utmi_mode) {
+   case DWC3_OMAP_UTMI_MODE_SW:
+   reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
+   break;
+   case DWC3_OMAP_UTMI_MODE_HW:
+   reg = ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
+   break;
+   default:
+   dev_dbg(omap-dev, UNKNOWN utmi mode %d\n, utmi_mode);
+   }
+
+   dwc3_omap_write_utmi_status(omap, reg);
+}
+
 static int dwc3_omap_probe(struct platform_device *pdev)
 {
struct device_node  *node = pdev-dev.of_node;
@@ -410,8 +434,6 @@ static int dwc3_omap_probe(struct platform_device *pdev)
int ret;
int irq;
 
-   int utmi_mode = 0;
-
u32 reg;
 
void __iomem*base;
@@ -462,23 +484,7 @@ static int dwc3_omap_probe(struct platform_device *pdev)
}
 
dwc3_omap_map_offset(omap);
-
-   reg = dwc3_omap_read_utmi_status(omap);
-
-   of_property_read_u32(node, utmi-mode, utmi_mode);
-
-   switch (utmi_mode) {
-   case DWC3_OMAP_UTMI_MODE_SW:
-   reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
-   break;
-   case DWC3_OMAP_UTMI_MODE_HW:
-   reg = ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
-   break;
-   default:
-   dev_dbg(dev, UNKNOWN utmi mode %d\n, utmi_mode);
-   }
-
-   dwc3_omap_write_utmi_status(omap, reg);
+   dwc3_omap_set_utmi_mode(omap);
 
/* check the DMA Status */
reg = dwc3_omap_readl(omap-base, USBOTGSS_SYSCONFIG);
-- 
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


[PATCH v3 5/6] usb: dwc3: dwc3-omap: Fix the crash on module removal

2014-05-21 Thread George Cherian
Following crash is seen on dwc3_omap removal
Unable to handle kernel NULL pointer dereference at virtual address 0018
pgd = ec098000
[0018] *pgd=ad1f9831, *pte=, *ppte=
Internal error: Oops: 17 [#1] SMP ARM
Modules linked in: usb_f_ss_lb g_zero usb_f_acm u_serial usb_f_ecm u_ether 
libcomposite configfs snd_usb_audio snd_usbmidi_lib snd_rawmidi snd_hwdep 
snd_soc_omap snd_pcm_dmaengine snd_soc_core snd_compress snd_pcm snd_tim]
CPU: 0 PID: 1296 Comm: rmmod Tainted: GW 
3.15.0-rc4-02716-g95c4e18-dirty #10
task: ed05a080 ti: ec368000 task.ti: ec368000
PC is at release_resource+0x14/0x7c
LR is at release_resource+0x10/0x7c
pc : [c0044724]lr : [c0044720]psr: 6013
sp : ec369ec0  ip : 6013  fp : 00021008
r10:   r9 : ec368000  r8 : c000e7a4
r7 : 0081  r6 : bf0062c0  r5 : ed7cd000  r4 : ed7d85c0
r3 :   r2 :   r1 : 0011  r0 : c086d08c
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 10c5387d  Table: ac098059  DAC: 0015
Process rmmod (pid: 1296, stack limit = 0xec368248)
Stack: (0xec369ec0 to 0xec36a000)
9ec0:  0001 ed7cd000 c034de94 ed7cd010 ed7cd000  c034e194
9ee0:  bf0062cc ed7cd010 c03490b0 ed154cc0 ed4c2570 ed2b8410 ed156810
ed156810 bf006d24 c034db9c c034db84 c034c518
9f20: bf006d24 ed156810 bf006d24 c034cd2c bf006d24 bf006d68 0800 c034c340
9f40:  c00a9e5c 0020  bf006d68 0800 ec369f4c 33637764
9f60: 616d6f5f 0070 0001 ec368000 ed05a080 c000e670 0001 c0084010
9f80: 00021088 0800 00021088 0081 8010 e6f4 00021088 0800
9fa0: 00021088 c000e5e0 00021088 0800 000210b8 0800 e04f6d00 e04f6d00
9fc0: 00021088 0800 00021088 0081 0001  be91de08 00021008
9fe0: 4d768880 be91dbb4 b6fc5984 4d76888c 8010 000210b8  
[c0044724] (release_resource) from [c034de94] 
(platform_device_del+0x6c/0x9c)
[c034de94] (platform_device_del) from [c034e194] 
(platform_device_unregister+0xc/0x18)
[c034e194] (platform_device_unregister) from [bf0062cc] 
(dwc3_omap_remove_core+0xc/0x14 [dwc3_omap])
[bf0062cc] (dwc3_omap_remove_core [dwc3_omap]) from [c03490b0] 
(device_for_each_child+0x34/0x74)
[c03490b0] (device_for_each_child) from [bf0062b4] 
(dwc3_omap_remove+0x6c/0x78 [dwc3_omap])
[bf0062b4] (dwc3_omap_remove [dwc3_omap]) from [c034db9c] 
(platform_drv_remove+0x18/0x1c)
[c034db9c] (platform_drv_remove) from [c034c518] 
(__device_release_driver+0x70/0xc8)
[c034c518] (__device_release_driver) from [c034cd2c] 
(driver_detach+0xb4/0xb8)
[c034cd2c] (driver_detach) from [c034c340] (bus_remove_driver+0x4c/0x90)
[c034c340] (bus_remove_driver) from [c00a9e5c] 
(SyS_delete_module+0x10c/0x198)
[c00a9e5c] (SyS_delete_module) from [c000e5e0] (ret_fast_syscall+0x0/0x48)
Code: e1a04000 e59f0068 eb14505e e5943010 (e5932018)
---[ end trace 7e2a8746ff4fc811 ]---
Segmentation fault

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 7594535..b729cdb 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -317,7 +317,7 @@ static int dwc3_omap_remove_core(struct device *dev, void 
*c)
 {
struct platform_device *pdev = to_platform_device(dev);
 
-   platform_device_unregister(pdev);
+   of_device_unregister(pdev);
 
return 0;
 }
-- 
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


[PATCH v3 4/6] usb: dwc3: dwc3-omap: Add dwc3_omap_extcon_register function

2014-05-21 Thread George Cherian
Move the extcon related code to its own function.
Improve code readability, decrease the dwc3_probe() size.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 65 ++--
 1 file changed, 39 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 56ec6eb..7594535 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -421,6 +421,42 @@ static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap)
dwc3_omap_write_utmi_status(omap, reg);
 }
 
+static int dwc3_omap_extcon_register(struct dwc3_omap *omap)
+{
+   u32 ret;
+   struct device_node  *node = omap-dev-of_node;
+   struct extcon_dev   *edev;
+
+   if (of_property_read_bool(node, extcon)) {
+   edev = extcon_get_edev_by_phandle(omap-dev, 0);
+   if (IS_ERR(edev)) {
+   dev_vdbg(omap-dev, couldn't get extcon device\n);
+   return -EPROBE_DEFER;
+   }
+
+   omap-vbus_nb.notifier_call = dwc3_omap_vbus_notifier;
+   ret = extcon_register_interest(omap-extcon_vbus_dev,
+  edev-name, USB,
+  omap-vbus_nb);
+   if (ret  0)
+   dev_vdbg(omap-dev, failed to register notifier for 
USB\n);
+
+   omap-id_nb.notifier_call = dwc3_omap_id_notifier;
+   ret = extcon_register_interest(omap-extcon_id_dev,
+  edev-name, USB-HOST,
+  omap-id_nb);
+   if (ret  0)
+   dev_vdbg(omap-dev, failed to register notifier for 
USB-HOST\n);
+
+   if (extcon_get_cable_state(edev, USB) == true)
+   dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
+   if (extcon_get_cable_state(edev, USB-HOST) == true)
+   dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
+   }
+
+   return 0;
+}
+
 static int dwc3_omap_probe(struct platform_device *pdev)
 {
struct device_node  *node = pdev-dev.of_node;
@@ -428,7 +464,6 @@ static int dwc3_omap_probe(struct platform_device *pdev)
struct dwc3_omap*omap;
struct resource *res;
struct device   *dev = pdev-dev;
-   struct extcon_dev   *edev;
struct regulator*vbus_reg = NULL;
 
int ret;
@@ -500,31 +535,9 @@ static int dwc3_omap_probe(struct platform_device *pdev)
 
dwc3_omap_enable_irqs(omap);
 
-   if (of_property_read_bool(node, extcon)) {
-   edev = extcon_get_edev_by_phandle(dev, 0);
-   if (IS_ERR(edev)) {
-   dev_vdbg(dev, couldn't get extcon device\n);
-   ret = -EPROBE_DEFER;
-   goto err2;
-   }
-
-   omap-vbus_nb.notifier_call = dwc3_omap_vbus_notifier;
-   ret = extcon_register_interest(omap-extcon_vbus_dev,
-   edev-name, USB, omap-vbus_nb);
-   if (ret  0)
-   dev_vdbg(dev, failed to register notifier for USB\n);
-   omap-id_nb.notifier_call = dwc3_omap_id_notifier;
-   ret = extcon_register_interest(omap-extcon_id_dev, edev-name,
-USB-HOST, omap-id_nb);
-   if (ret  0)
-   dev_vdbg(dev,
-   failed to register notifier for USB-HOST\n);
-
-   if (extcon_get_cable_state(edev, USB) == true)
-   dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
-   if (extcon_get_cable_state(edev, USB-HOST) == true)
-   dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
-   }
+   ret = dwc3_omap_extcon_register(omap);
+   if (ret  0)
+   goto err2;
 
ret = of_platform_populate(node, NULL, NULL, dev);
if (ret) {
-- 
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


[PATCH v3 2/6] usb: dwc3: dwc3-omap: Add dwc3_omap_map_offset() function

2014-05-21 Thread George Cherian
Move map offset to its own seperate function.
Improve code readability, decrease the dwc3_probe() size.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 33 -
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 999bdc8..09918ac 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -378,6 +378,25 @@ static int dwc3_omap_vbus_notifier(struct notifier_block 
*nb,
return NOTIFY_DONE;
 }
 
+static void dwc3_omap_map_offset(struct dwc3_omap *omap)
+{
+   struct device_node  *node = omap-dev-of_node;
+
+   /* Differentiate between OMAP5 and AM437x.
+* For OMAP5(ES2.0) and AM437x wrapper revision is same  even
+* though there are changes in wrapper register offsets.
+* Using dt compatible to differentiate  AM437x.
+*/
+
+   if (of_device_is_compatible(node, ti,am437x-dwc3)) {
+   omap-irq_eoi_offset = USBOTGSS_EOI_OFFSET;
+   omap-irq0_offset = USBOTGSS_IRQ0_OFFSET;
+   omap-irqmisc_offset = USBOTGSS_IRQMISC_OFFSET;
+   omap-utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET;
+   omap-debug_offset = USBOTGSS_DEBUG_OFFSET;
+   }
+}
+
 static int dwc3_omap_probe(struct platform_device *pdev)
 {
struct device_node  *node = pdev-dev.of_node;
@@ -442,19 +461,7 @@ static int dwc3_omap_probe(struct platform_device *pdev)
goto err0;
}
 
-   /* Differentiate between OMAP5 and AM437x.
-* For OMAP5(ES2.0) and AM437x wrapper revision is same, even
-* though there are changes in wrapper register offsets.
-* Using dt compatible to differentiate  AM437x.
-*/
-
-   if (of_device_is_compatible(node, ti,am437x-dwc3)) {
-   omap-irq_eoi_offset = USBOTGSS_EOI_OFFSET;
-   omap-irq0_offset = USBOTGSS_IRQ0_OFFSET;
-   omap-irqmisc_offset = USBOTGSS_IRQMISC_OFFSET;
-   omap-utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET;
-   omap-debug_offset = USBOTGSS_DEBUG_OFFSET;
-   }
+   dwc3_omap_map_offset(omap);
 
reg = dwc3_omap_read_utmi_status(omap);
 
-- 
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


[PATCH v3 6/6] usb: dwc3: dwc3-omap: Disable/Enable only wrapper interrupts in prepare/complete

2014-05-21 Thread George Cherian
The dwc3 wrapper driver should not be fiddling with the core interrupts.
Disabling the core interrupts in prepare stops xhci from proper operation.
So remove disable/enable of core interrupts from prepare/complete.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index b729cdb..116f71c 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -597,7 +597,7 @@ static int dwc3_omap_prepare(struct device *dev)
 {
struct dwc3_omap*omap = dev_get_drvdata(dev);
 
-   dwc3_omap_disable_irqs(omap);
+   dwc3_omap_write_irqmisc_set(omap, 0x00);
 
return 0;
 }
@@ -605,8 +605,19 @@ static int dwc3_omap_prepare(struct device *dev)
 static void dwc3_omap_complete(struct device *dev)
 {
struct dwc3_omap*omap = dev_get_drvdata(dev);
+   u32 reg;
 
-   dwc3_omap_enable_irqs(omap);
+   reg = (USBOTGSS_IRQMISC_OEVT |
+   USBOTGSS_IRQMISC_DRVVBUS_RISE |
+   USBOTGSS_IRQMISC_CHRGVBUS_RISE |
+   USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
+   USBOTGSS_IRQMISC_IDPULLUP_RISE |
+   USBOTGSS_IRQMISC_DRVVBUS_FALL |
+   USBOTGSS_IRQMISC_CHRGVBUS_FALL |
+   USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
+   USBOTGSS_IRQMISC_IDPULLUP_FALL);
+
+   dwc3_omap_write_irqmisc_set(omap, reg);
 }
 
 static int dwc3_omap_suspend(struct device *dev)
-- 
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


[PATCH v3 1/6] usb: dwc3: dwc3-omap: Remove x_major calculation from revision register

2014-05-21 Thread George Cherian
Remove the x_major calculation logic from the wrapper revision register
to differentiate between OMAP5 and AM437x. This was done to find the
register offsets of wrapper register. Now that We do it using dt
compatible, remove the whole logic.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 36 
 1 file changed, 4 insertions(+), 32 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 4af4c35..999bdc8 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -77,10 +77,6 @@
 #define USBOTGSS_DEV_EBC_EN0x0110
 #define USBOTGSS_DEBUG_OFFSET  0x0600
 
-/* REVISION REGISTER */
-#define USBOTGSS_REVISION_XMAJOR(reg)  ((reg  8)  0x7)
-#define USBOTGSS_REVISION_XMAJOR1  1
-#define USBOTGSS_REVISION_XMAJOR2  2
 /* SYSCONFIG REGISTER */
 #define USBOTGSS_SYSCONFIG_DMADISABLE  (1  16)
 
@@ -129,7 +125,6 @@ struct dwc3_omap {
u32 irq_eoi_offset;
u32 debug_offset;
u32 irq0_offset;
-   u32 revision;
 
u32 dma_status:1;
 
@@ -397,7 +392,6 @@ static int dwc3_omap_probe(struct platform_device *pdev)
int irq;
 
int utmi_mode = 0;
-   int x_major;
 
u32 reg;
 
@@ -448,32 +442,10 @@ static int dwc3_omap_probe(struct platform_device *pdev)
goto err0;
}
 
-   reg = dwc3_omap_readl(omap-base, USBOTGSS_REVISION);
-   omap-revision = reg;
-   x_major = USBOTGSS_REVISION_XMAJOR(reg);
-
-   /* Differentiate between OMAP5 and AM437x */
-   switch (x_major) {
-   case USBOTGSS_REVISION_XMAJOR1:
-   case USBOTGSS_REVISION_XMAJOR2:
-   omap-irq_eoi_offset = 0;
-   omap-irq0_offset = 0;
-   omap-irqmisc_offset = 0;
-   omap-utmi_otg_offset = 0;
-   omap-debug_offset = 0;
-   break;
-   default:
-   /* Default to the latest revision */
-   omap-irq_eoi_offset = USBOTGSS_EOI_OFFSET;
-   omap-irq0_offset = USBOTGSS_IRQ0_OFFSET;
-   omap-irqmisc_offset = USBOTGSS_IRQMISC_OFFSET;
-   omap-utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET;
-   omap-debug_offset = USBOTGSS_DEBUG_OFFSET;
-   break;
-   }
-
-   /* For OMAP5(ES2.0) and AM437x x_major is 2 even though there are
-* changes in wrapper registers, Using dt compatible for aegis
+   /* Differentiate between OMAP5 and AM437x.
+* For OMAP5(ES2.0) and AM437x wrapper revision is same, even
+* though there are changes in wrapper register offsets.
+* Using dt compatible to differentiate  AM437x.
 */
 
if (of_device_is_compatible(node, ti,am437x-dwc3)) {
-- 
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


[PATCH v2 6/6] usb: dwc3: dwc3-omap: Disable/Enable only wrapper interrupts in prepare/complete

2014-05-19 Thread George Cherian
The dwc3 wrapper driver should not be fiddling with the core interrupts.
Disabling the core interrupts in prepare stops xhci from proper operation.
So remove disable/enable of core interrupts from prepare/complete.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index e4f681a..3f86f29 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -596,7 +596,7 @@ static int dwc3_omap_prepare(struct device *dev)
 {
struct dwc3_omap*omap = dev_get_drvdata(dev);
 
-   dwc3_omap_disable_irqs(omap);
+   dwc3_omap_write_irqmisc_set(omap, 0x00);
 
return 0;
 }
@@ -604,8 +604,19 @@ static int dwc3_omap_prepare(struct device *dev)
 static void dwc3_omap_complete(struct device *dev)
 {
struct dwc3_omap*omap = dev_get_drvdata(dev);
+   u32 reg;
 
-   dwc3_omap_enable_irqs(omap);
+   reg = (USBOTGSS_IRQMISC_OEVT |
+   USBOTGSS_IRQMISC_DRVVBUS_RISE |
+   USBOTGSS_IRQMISC_CHRGVBUS_RISE |
+   USBOTGSS_IRQMISC_DISCHRGVBUS_RISE |
+   USBOTGSS_IRQMISC_IDPULLUP_RISE |
+   USBOTGSS_IRQMISC_DRVVBUS_FALL |
+   USBOTGSS_IRQMISC_CHRGVBUS_FALL |
+   USBOTGSS_IRQMISC_DISCHRGVBUS_FALL |
+   USBOTGSS_IRQMISC_IDPULLUP_FALL);
+
+   dwc3_omap_write_irqmisc_set(omap, reg);
 }
 
 static int dwc3_omap_suspend(struct device *dev)
-- 
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


[PATCH v2 4/6] usb: dwc3: dwc3-omap: Add dwc3_omap_extcon_register function

2014-05-19 Thread George Cherian
Move the extcon related code to its own function.
Improve code readability, decrease the dwc3_probe() size.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 65 ++--
 1 file changed, 39 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 2223ab8..131d75a 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -420,6 +420,42 @@ static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap)
dwc3_omap_write_utmi_status(omap, reg);
 }
 
+static int dwc3_omap_extcon_register(struct dwc3_omap *omap)
+{
+   u32 ret;
+   struct device_node  *node = omap-dev-of_node;
+   struct extcon_dev   *edev;
+
+   if (of_property_read_bool(node, extcon)) {
+   edev = extcon_get_edev_by_phandle(omap-dev, 0);
+   if (IS_ERR(edev)) {
+   dev_vdbg(omap-dev, couldn't get extcon device\n);
+   return -EPROBE_DEFER;
+   }
+
+   omap-vbus_nb.notifier_call = dwc3_omap_vbus_notifier;
+   ret = extcon_register_interest(omap-extcon_vbus_dev,
+  edev-name, USB,
+  omap-vbus_nb);
+   if (ret  0)
+   dev_vdbg(omap-dev, failed to register notifier for 
USB\n);
+
+   omap-id_nb.notifier_call = dwc3_omap_id_notifier;
+   ret = extcon_register_interest(omap-extcon_id_dev,
+  edev-name, USB-HOST,
+  omap-id_nb);
+   if (ret  0)
+   dev_vdbg(omap-dev, failed to register notifier for 
USB-HOST\n);
+
+   if (extcon_get_cable_state(edev, USB) == true)
+   dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
+   if (extcon_get_cable_state(edev, USB-HOST) == true)
+   dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
+   }
+
+   return 0;
+}
+
 static int dwc3_omap_probe(struct platform_device *pdev)
 {
struct device_node  *node = pdev-dev.of_node;
@@ -427,7 +463,6 @@ static int dwc3_omap_probe(struct platform_device *pdev)
struct dwc3_omap*omap;
struct resource *res;
struct device   *dev = pdev-dev;
-   struct extcon_dev   *edev;
struct regulator*vbus_reg = NULL;
 
int ret = -ENOMEM;
@@ -499,31 +534,9 @@ static int dwc3_omap_probe(struct platform_device *pdev)
 
dwc3_omap_enable_irqs(omap);
 
-   if (of_property_read_bool(node, extcon)) {
-   edev = extcon_get_edev_by_phandle(dev, 0);
-   if (IS_ERR(edev)) {
-   dev_vdbg(dev, couldn't get extcon device\n);
-   ret = -EPROBE_DEFER;
-   goto err2;
-   }
-
-   omap-vbus_nb.notifier_call = dwc3_omap_vbus_notifier;
-   ret = extcon_register_interest(omap-extcon_vbus_dev,
-   edev-name, USB, omap-vbus_nb);
-   if (ret  0)
-   dev_vdbg(dev, failed to register notifier for USB\n);
-   omap-id_nb.notifier_call = dwc3_omap_id_notifier;
-   ret = extcon_register_interest(omap-extcon_id_dev, edev-name,
-USB-HOST, omap-id_nb);
-   if (ret  0)
-   dev_vdbg(dev,
-   failed to register notifier for USB-HOST\n);
-
-   if (extcon_get_cable_state(edev, USB) == true)
-   dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID);
-   if (extcon_get_cable_state(edev, USB-HOST) == true)
-   dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND);
-   }
+   ret = dwc3_omap_extcon_register(omap);
+   if (ret  0)
+   goto err2;
 
ret = of_platform_populate(node, NULL, NULL, dev);
if (ret) {
-- 
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


[PATCH v2 5/6] usb: dwc3: dwc3-omap: Fix the crash on module removal

2014-05-19 Thread George Cherian
Following crash is seen on dwc3_omap removal
Unable to handle kernel NULL pointer dereference at virtual address 0018
pgd = ec098000
[0018] *pgd=ad1f9831, *pte=, *ppte=
Internal error: Oops: 17 [#1] SMP ARM
Modules linked in: usb_f_ss_lb g_zero usb_f_acm u_serial usb_f_ecm u_ether 
libcomposite configfs snd_usb_audio snd_usbmidi_lib snd_rawmidi snd_hwdep 
snd_soc_omap snd_pcm_dmaengine snd_soc_core snd_compress snd_pcm snd_tim]
CPU: 0 PID: 1296 Comm: rmmod Tainted: GW 
3.15.0-rc4-02716-g95c4e18-dirty #10
task: ed05a080 ti: ec368000 task.ti: ec368000
PC is at release_resource+0x14/0x7c
LR is at release_resource+0x10/0x7c
pc : [c0044724]lr : [c0044720]psr: 6013
sp : ec369ec0  ip : 6013  fp : 00021008
r10:   r9 : ec368000  r8 : c000e7a4
r7 : 0081  r6 : bf0062c0  r5 : ed7cd000  r4 : ed7d85c0
r3 :   r2 :   r1 : 0011  r0 : c086d08c
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 10c5387d  Table: ac098059  DAC: 0015
Process rmmod (pid: 1296, stack limit = 0xec368248)
Stack: (0xec369ec0 to 0xec36a000)
9ec0:  0001 ed7cd000 c034de94 ed7cd010 ed7cd000  c034e194
9ee0:  bf0062cc ed7cd010 c03490b0 ed154cc0 ed4c2570 ed2b8410 ed156810
ed156810 bf006d24 c034db9c c034db84 c034c518
9f20: bf006d24 ed156810 bf006d24 c034cd2c bf006d24 bf006d68 0800 c034c340
9f40:  c00a9e5c 0020  bf006d68 0800 ec369f4c 33637764
9f60: 616d6f5f 0070 0001 ec368000 ed05a080 c000e670 0001 c0084010
9f80: 00021088 0800 00021088 0081 8010 e6f4 00021088 0800
9fa0: 00021088 c000e5e0 00021088 0800 000210b8 0800 e04f6d00 e04f6d00
9fc0: 00021088 0800 00021088 0081 0001  be91de08 00021008
9fe0: 4d768880 be91dbb4 b6fc5984 4d76888c 8010 000210b8  
[c0044724] (release_resource) from [c034de94] 
(platform_device_del+0x6c/0x9c)
[c034de94] (platform_device_del) from [c034e194] 
(platform_device_unregister+0xc/0x18)
[c034e194] (platform_device_unregister) from [bf0062cc] 
(dwc3_omap_remove_core+0xc/0x14 [dwc3_omap])
[bf0062cc] (dwc3_omap_remove_core [dwc3_omap]) from [c03490b0] 
(device_for_each_child+0x34/0x74)
[c03490b0] (device_for_each_child) from [bf0062b4] 
(dwc3_omap_remove+0x6c/0x78 [dwc3_omap])
[bf0062b4] (dwc3_omap_remove [dwc3_omap]) from [c034db9c] 
(platform_drv_remove+0x18/0x1c)
[c034db9c] (platform_drv_remove) from [c034c518] 
(__device_release_driver+0x70/0xc8)
[c034c518] (__device_release_driver) from [c034cd2c] 
(driver_detach+0xb4/0xb8)
[c034cd2c] (driver_detach) from [c034c340] (bus_remove_driver+0x4c/0x90)
[c034c340] (bus_remove_driver) from [c00a9e5c] 
(SyS_delete_module+0x10c/0x198)
[c00a9e5c] (SyS_delete_module) from [c000e5e0] (ret_fast_syscall+0x0/0x48)
Code: e1a04000 e59f0068 eb14505e e5943010 (e5932018)
---[ end trace 7e2a8746ff4fc811 ]---
Segmentation fault

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 131d75a..e4f681a 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -317,7 +317,7 @@ static int dwc3_omap_remove_core(struct device *dev, void 
*c)
 {
struct platform_device *pdev = to_platform_device(dev);
 
-   platform_device_unregister(pdev);
+   of_device_unregister(pdev);
 
return 0;
 }
-- 
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


[PATCH v2 2/6] usb: dwc3: dwc3-omap: Add dwc3_omap_map_offset() function

2014-05-19 Thread George Cherian
Move map offset to its own seperate function.
Improve code readability, decrease the dwc3_probe() size.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 31 +++
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 53f6490..0df8adf 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -378,6 +378,24 @@ static int dwc3_omap_vbus_notifier(struct notifier_block 
*nb,
return NOTIFY_DONE;
 }
 
+static void dwc3_omap_map_offset(struct dwc3_omap *omap)
+{
+   struct device_node  *node = omap-dev-of_node;
+
+   /* Differentiate between OMAP5 and AM437x
+* For OMAP5(ES2.0) and AM437x x_major is 2 even though there are
+* changes in wrapper registers, Using dt compatible for AM437x
+*/
+
+   if (of_device_is_compatible(node, ti,am437x-dwc3)) {
+   omap-irq_eoi_offset = USBOTGSS_EOI_OFFSET;
+   omap-irq0_offset = USBOTGSS_IRQ0_OFFSET;
+   omap-irqmisc_offset = USBOTGSS_IRQMISC_OFFSET;
+   omap-utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET;
+   omap-debug_offset = USBOTGSS_DEBUG_OFFSET;
+   }
+}
+
 static int dwc3_omap_probe(struct platform_device *pdev)
 {
struct device_node  *node = pdev-dev.of_node;
@@ -442,18 +460,7 @@ static int dwc3_omap_probe(struct platform_device *pdev)
goto err0;
}
 
-   /* Differentiate between OMAP5 and AM437x
-* For OMAP5(ES2.0) and AM437x x_major is 2 even though there are
-* changes in wrapper registers, Using dt compatible for AM437x
-*/
-
-   if (of_device_is_compatible(node, ti,am437x-dwc3)) {
-   omap-irq_eoi_offset = USBOTGSS_EOI_OFFSET;
-   omap-irq0_offset = USBOTGSS_IRQ0_OFFSET;
-   omap-irqmisc_offset = USBOTGSS_IRQMISC_OFFSET;
-   omap-utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET;
-   omap-debug_offset = USBOTGSS_DEBUG_OFFSET;
-   }
+   dwc3_omap_map_offset(omap);
 
reg = dwc3_omap_read_utmi_status(omap);
 
-- 
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


[PATCH v2 3/6] usb: dwc3: dwc3-omap: Add dwc3_omap_set_utmi_mode() function

2014-05-19 Thread George Cherian
Move find and set the utmi mode to its own seperate function.
Improve code readability, decrease the dwc3_probe() size.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 44 +---
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 0df8adf..2223ab8 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -396,6 +396,30 @@ static void dwc3_omap_map_offset(struct dwc3_omap *omap)
}
 }
 
+static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap)
+{
+   u32 reg;
+   struct device_node  *node = omap-dev-of_node;
+   int utmi_mode = 0;
+
+   reg = dwc3_omap_read_utmi_status(omap);
+
+   of_property_read_u32(node, utmi-mode, utmi_mode);
+
+   switch (utmi_mode) {
+   case DWC3_OMAP_UTMI_MODE_SW:
+   reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
+   break;
+   case DWC3_OMAP_UTMI_MODE_HW:
+   reg = ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
+   break;
+   default:
+   dev_dbg(omap-dev, UNKNOWN utmi mode %d\n, utmi_mode);
+   }
+
+   dwc3_omap_write_utmi_status(omap, reg);
+}
+
 static int dwc3_omap_probe(struct platform_device *pdev)
 {
struct device_node  *node = pdev-dev.of_node;
@@ -409,8 +433,6 @@ static int dwc3_omap_probe(struct platform_device *pdev)
int ret = -ENOMEM;
int irq;
 
-   int utmi_mode = 0;
-
u32 reg;
 
void __iomem*base;
@@ -461,23 +483,7 @@ static int dwc3_omap_probe(struct platform_device *pdev)
}
 
dwc3_omap_map_offset(omap);
-
-   reg = dwc3_omap_read_utmi_status(omap);
-
-   of_property_read_u32(node, utmi-mode, utmi_mode);
-
-   switch (utmi_mode) {
-   case DWC3_OMAP_UTMI_MODE_SW:
-   reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
-   break;
-   case DWC3_OMAP_UTMI_MODE_HW:
-   reg = ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
-   break;
-   default:
-   dev_dbg(dev, UNKNOWN utmi mode %d\n, utmi_mode);
-   }
-
-   dwc3_omap_write_utmi_status(omap, reg);
+   dwc3_omap_set_utmi_mode(omap);
 
/* check the DMA Status */
reg = dwc3_omap_readl(omap-base, USBOTGSS_SYSCONFIG);
-- 
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


[PATCH v2 1/6] usb: dwc3: dwc3-omap: Remove x_major calculation from revision register

2014-05-19 Thread George Cherian
Remove the x_major calculation logic from the wrapper revision register
to differentiate between OMAP5 and AM437x. This was done to find the
register offsets of wrapper register. Now that We do it using dt
compatible, remove the whole logic.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/dwc3/dwc3-omap.c | 35 +++
 1 file changed, 3 insertions(+), 32 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 1160ff4..53f6490 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -77,10 +77,6 @@
 #define USBOTGSS_DEV_EBC_EN0x0110
 #define USBOTGSS_DEBUG_OFFSET  0x0600
 
-/* REVISION REGISTER */
-#define USBOTGSS_REVISION_XMAJOR(reg)  ((reg  8)  0x7)
-#define USBOTGSS_REVISION_XMAJOR1  1
-#define USBOTGSS_REVISION_XMAJOR2  2
 /* SYSCONFIG REGISTER */
 #define USBOTGSS_SYSCONFIG_DMADISABLE  (1  16)
 
@@ -129,7 +125,6 @@ struct dwc3_omap {
u32 irq_eoi_offset;
u32 debug_offset;
u32 irq0_offset;
-   u32 revision;
 
u32 dma_status:1;
 
@@ -397,7 +392,6 @@ static int dwc3_omap_probe(struct platform_device *pdev)
int irq;
 
int utmi_mode = 0;
-   int x_major;
 
u32 reg;
 
@@ -448,32 +442,9 @@ static int dwc3_omap_probe(struct platform_device *pdev)
goto err0;
}
 
-   reg = dwc3_omap_readl(omap-base, USBOTGSS_REVISION);
-   omap-revision = reg;
-   x_major = USBOTGSS_REVISION_XMAJOR(reg);
-
-   /* Differentiate between OMAP5 and AM437x */
-   switch (x_major) {
-   case USBOTGSS_REVISION_XMAJOR1:
-   case USBOTGSS_REVISION_XMAJOR2:
-   omap-irq_eoi_offset = 0;
-   omap-irq0_offset = 0;
-   omap-irqmisc_offset = 0;
-   omap-utmi_otg_offset = 0;
-   omap-debug_offset = 0;
-   break;
-   default:
-   /* Default to the latest revision */
-   omap-irq_eoi_offset = USBOTGSS_EOI_OFFSET;
-   omap-irq0_offset = USBOTGSS_IRQ0_OFFSET;
-   omap-irqmisc_offset = USBOTGSS_IRQMISC_OFFSET;
-   omap-utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET;
-   omap-debug_offset = USBOTGSS_DEBUG_OFFSET;
-   break;
-   }
-
-   /* For OMAP5(ES2.0) and AM437x x_major is 2 even though there are
-* changes in wrapper registers, Using dt compatible for aegis
+   /* Differentiate between OMAP5 and AM437x
+* For OMAP5(ES2.0) and AM437x x_major is 2 even though there are
+* changes in wrapper registers, Using dt compatible for AM437x
 */
 
if (of_device_is_compatible(node, ti,am437x-dwc3)) {
-- 
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


[PATCH v2 0/6] Cleanup and fixes for dwc3-omap

2014-05-19 Thread George Cherian

The series does some refactoring on dwc3_probe()

Patch 1 - Now that we use driver compatible for revision check, remove the 
unnecessary logic.
Patch 2-4 - reduce the size of dwc3_probe()
Patch 5 - Fix the crash on dwc3_omap removal
Patch 6 - Addresses the issue of  xhci hang while resuming from system sleep.


George Cherian (6):
  usb: dwc3: dwc3-omap: Remove x_major calculation from revision
register
  usb: dwc3: dwc3-omap: Add dwc3_omap_map_offset() function
  usb: dwc3: dwc3-omap: Add dwc3_omap_set_utmi_mode() function
  usb: dwc3: dwc3-omap: Add dwc3_omap_extcon_register function
  usb: dwc3: dwc3-omap: Fix the crash on module removal
  usb: dwc3: dwc3-omap: Disable/Enable only wrapper interrupts in
prepare/complete

 drivers/usb/dwc3/dwc3-omap.c | 186 ++-
 1 file changed, 97 insertions(+), 89 deletions(-)

-- 
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 v3 0/5] Add support for SW babble Control

2014-05-19 Thread George Cherian

Hi Bin,

On 5/15/2014 8:49 PM, Bin Liu wrote:

George,

On Thu, May 15, 2014 at 1:28 AM, George Cherian george.cher...@ti.com wrote:

Hi Bin,


On 5/14/2014 10:13 PM, Bin Liu wrote:

George,

On Wed, May 14, 2014 at 9:34 AM, Bin Liu binml...@gmail.com wrote:

George,

On Wed, May 14, 2014 at 12:37 AM, George Cherian george.cher...@ti.com
wrote:

On 5/14/2014 12:07 AM, Bin Liu wrote:

Hi,

On Tue, May 13, 2014 at 8:24 AM, George Cherian george.cher...@ti.com
wrote:

Hi Daniel,


On 5/13/2014 6:44 PM, Daniel Mack wrote:

Hi George,

On 05/13/2014 02:57 PM, George Cherian wrote:

I never enabled the MUSB_BABBLE_SW_SESSION_CTRL in the
MUSB_BABBLE_CTL
reg.
can you try with the following patch.

diff --git a/drivers/usb/musb/musb_dsps.c
b/drivers/usb/musb/musb_dsps.c
index 1ae6681..1160cd1 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -477,8 +477,11 @@ static int dsps_musb_init(struct musb *musb)
* logic enabled.
*/
   val = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
-   if (val == MUSB_BABBLE_RCV_DISABLE)
+   if (val == MUSB_BABBLE_RCV_DISABLE) {
   glue-sw_babble_enabled = true;
+   val |= MUSB_BABBLE_SW_SESSION_CTRL;
+   dsps_writeb(musb-mregs, MUSB_BABBLE_CTL, val);
+   }
   ret = dsps_musb_dbg_init(musb, glue);
   if (ret)

MUSB_BABBLE_STUCK_J still remains unset, so I get the same result as
without the patch: a full glue reset is conducted. Do I get you right
that you expect MUSB_BABBLE_STUCK_J to be set in babble conditions
when
MUSB_BABBLE_SW_SESSION_CTRL is set?


Basically, there are 2 types of babble conditions.
1) Transient babble condition - which could be recovered from without
an
IP
reset .
2) Babble condition - which could be recovered from only by doing an
IP
reset.

Looks like you are always hitting case 2 (Most times am also hitting
the
same).
Case 1 is really hard to reproduce. I don't have a reliable method as
of
now
to
reproduce this case consistently.


[   19.672373] CAUTION: musb: Babble Interrupt Occurred
[   19.66] musb_stage0_irq 789: unhandled DISCONNECT transition
(a_wait_bcon)
[   19.685815] usb 1-1: USB disconnect, device number 3
[   19.769720] musb-hdrc musb-hdrc.0.auto: babble: MUSB_BABBLE_CTL
value
44
[   19.776765] musb-hdrc musb-hdrc.0.auto: STUCK_J is reset


I don't quite follow, especially as I lack documentation of the IP
core.
How do you test babble errors, is there any way to force them to
happen
reliably?


There is no 100% reliable method to force it to happen. Following is

I have a way to force babble happen reliably - shorting DP or DM to
VBUS. I opened the far-end plug of the USB cable, so I can easily
short DP or DM to VBUS.

Good to know that you have a reliable way to test babble condition.
Can you please do a quick test on 3.15.0-rc4 with the series applied?
In case of any assistance please do let me know.

Sure, but could you please re-send those patches to my corporate email
so that I can apply them from Thunderbird?

You don't have to resend the patches. Nishanth Menon showed me a way
to extract the patch from Gmail - Thanks Nishanth.

But which repo do you want to me test with? The first patch ([PATCH v2
1/5] usb: musb: core: Convert babble recover work to delayed work)
does not apply to v3.15-rc4 tag. the current musb_core.c does not have
the recovery work for musb. Please let me know what I missed.

Oops I missed to mention the same.
Please try on
git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git master

The test is done. The babble always causes STUCK_J is reset,
MUSB_BABBLE_CTL is 0x44 or 0x4. MUSB reset happens.

Thankyou Bin for the help.

Can I get a Tested-by from you?

Do you think when re-start happens the driver should print a message
on console saying re-start due to babble? It would help debug the
babble problems while the dynamic debug is off.


It prints  out a message saying babble condition occured.
More over, it re-enumerates all the devices connected  as part of Musb 
re-start.

Don't you think that is sufficient enough ?

Thanks,
-Bin.


Thanks,
-Bin.


I read these linux-usb emails in Gmail, and  am not aware of any easy
way to extract patches from Gmail.

BTY, I tested with TI 3.12.10 kernel, in which I guess the babble
handling is similar to this patch set. With TI3.12.10, MISC is always
0x64, so MUSB never restarts.

Thanks,
-Bin.


But the interesting thing is that with TI 3.2 kernel, shorting DP or
DM to VBUS causes MISC register to be 0x4, but the result is
completely opposite in TI 3.12.10 kernel, which cause MISC to be 0x64.

So in the 3.2 kernel, the babble handing resets the controller, but
the 3.12.10 does not.

Regards,
-Bin.


my setup ,
I have a HUB with 4 devices connected , which gives me a Babble
interrupt
on both connects and disconnects ( Not always though).


Anyway, the full glue layer solves this rare condition quite well for
me. Is there any downside

[PATCH v4 6/6] usb: musb: dsps: Enable sw babble control for newer silicon

2014-05-19 Thread George Cherian
Find whether we are running on newer silicon. The babble control
register reads 0x4 by default in newer silicon as opposed to 0
in old versions of AM335x. Based on this enable the sw babble
control logic.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_dsps.c | 37 +++--
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index eb1985a..8daccb2 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -136,6 +136,7 @@ struct dsps_glue {
const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
struct timer_list timer;/* otg_workaround timer */
unsigned long last_timer;/* last timer data for each instance */
+   bool sw_babble_enabled;
 
struct dsps_context context;
struct debugfs_regset32 regset;
@@ -469,6 +470,19 @@ static int dsps_musb_init(struct musb *musb)
val = ~(1  wrp-otg_disable);
dsps_writel(musb-ctrl_base, wrp-phy_utmi, val);
 
+   /*
+*  Check whether the dsps version has babble control enabled.
+* In latest silicon revision the babble control logic is enabled.
+* If MUSB_BABBLE_CTL returns 0x4 then we have the babble control
+* logic enabled.
+*/
+   val = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   if (val == MUSB_BABBLE_RCV_DISABLE) {
+   glue-sw_babble_enabled = true;
+   val |= MUSB_BABBLE_SW_SESSION_CTRL;
+   dsps_writeb(musb-mregs, MUSB_BABBLE_CTL, val);
+   }
+
ret = dsps_musb_dbg_init(musb, glue);
if (ret)
return ret;
@@ -591,14 +605,25 @@ static int dsps_musb_reset(struct musb *musb)
struct device *dev = musb-controller;
struct dsps_glue *glue = dev_get_drvdata(dev-parent);
const struct dsps_musb_wrapper *wrp = glue-wrp;
+   int session_restart = 0;
 
-   dsps_writel(musb-ctrl_base, wrp-control, (1  wrp-reset));
-   usleep_range(100, 200);
-   usb_phy_shutdown(musb-xceiv);
-   usleep_range(100, 200);
-   usb_phy_init(musb-xceiv);
+   if (glue-sw_babble_enabled)
+   session_restart = sw_babble_control(musb);
+   /*
+* In case of new silicon version babble condition can be recovered
+* without resetting the MUSB. But for older silicon versions, MUSB
+* reset is needed
+*/
+   if (session_restart || !glue-sw_babble_enabled) {
+   dsps_writel(musb-ctrl_base, wrp-control, (1  wrp-reset));
+   usleep_range(100, 200);
+   usb_phy_shutdown(musb-xceiv);
+   usleep_range(100, 200);
+   usb_phy_init(musb-xceiv);
+   session_restart = 1;
+   }
 
-   return 0;
+   return !session_restart;
 }
 
 static struct musb_platform_ops dsps_ops = {
-- 
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


[PATCH v4 3/6] usb: musb: dsps: Call usb_phy(_shutdown/_init) during musb_platform_reset()

2014-05-19 Thread George Cherian
For DSPS platform usb_phy_vbus(_off/_on) are NOPs.
So during musb_platform_reset() call usb_phy(_shutdown/_init)

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_dsps.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 51beb13..74c4193 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -543,7 +543,11 @@ static void dsps_musb_reset(struct musb *musb)
const struct dsps_musb_wrapper *wrp = glue-wrp;
 
dsps_writel(musb-ctrl_base, wrp-control, (1  wrp-reset));
-   udelay(100);
+   usleep_range(100, 200);
+   usb_phy_shutdown(musb-xceiv);
+   usleep_range(100, 200);
+   usb_phy_init(musb-xceiv);
+
 }
 
 static struct musb_platform_ops dsps_ops = {
-- 
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


[PATCH v4 5/6] usb: musb: dsps: Add the sw_babble_control()

2014-05-19 Thread George Cherian
Add sw_babble_control() logic to differentiate between transient
babble and real babble condition. Also add the SW babble control
register definitions.

Babble control register logic is implemented in the latest
revision of AM335x.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_dsps.c | 50 
 drivers/usb/musb/musb_regs.h |  7 +++
 2 files changed, 57 insertions(+)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index f6f3087..eb1985a 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -536,6 +536,56 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode)
return 0;
 }
 
+static int sw_babble_control(struct musb *musb)
+{
+   int timeout = 10;
+   u8 babble_ctl, session_restart = 0;
+
+   babble_ctl = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   dev_dbg(musb-controller, babble: MUSB_BABBLE_CTL value %x\n,
+   babble_ctl);
+   /*
+* check line monitor flag to check whether babble is
+* due to noise
+*/
+   dev_dbg(musb-controller, STUCK_J is %s\n,
+   babble_ctl  MUSB_BABBLE_STUCK_J ? set : reset);
+
+   if (babble_ctl  MUSB_BABBLE_STUCK_J) {
+   /*
+* babble is due to noise, then set transmit idle (d7 bit)
+* to resume normal operation
+*/
+   babble_ctl = musb_readb(musb-mregs, MUSB_BABBLE_CTL);
+   babble_ctl |= MUSB_BABBLE_FORCE_TXIDLE;
+   dsps_writeb(musb-mregs, MUSB_BABBLE_CTL, babble_ctl);
+
+   /* wait till line monitor flag cleared */
+   dev_dbg(musb-controller, Set TXIDLE, wait J to clear\n);
+   do {
+   babble_ctl = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   udelay(1);
+   } while ((babble_ctl  MUSB_BABBLE_STUCK_J)  timeout--);
+
+   /* check whether stuck_at_j bit cleared */
+   if (babble_ctl  MUSB_BABBLE_STUCK_J) {
+   /*
+* real babble condition is occured
+* restart the controller to start the
+* session again
+*/
+   dev_dbg(musb-controller, J not cleared, misc (%x)\n,
+   babble_ctl);
+   session_restart = 1;
+   }
+
+   } else {
+   session_restart = 1;
+   }
+
+   return session_restart;
+}
+
 static int dsps_musb_reset(struct musb *musb)
 {
struct device *dev = musb-controller;
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
index 03f2655..b9bcda5 100644
--- a/drivers/usb/musb/musb_regs.h
+++ b/drivers/usb/musb/musb_regs.h
@@ -72,6 +72,12 @@
 #define MUSB_DEVCTL_HR 0x02
 #define MUSB_DEVCTL_SESSION0x01
 
+/* BABBLE_CTL */
+#define MUSB_BABBLE_FORCE_TXIDLE   0x80
+#define MUSB_BABBLE_SW_SESSION_CTRL0x40
+#define MUSB_BABBLE_STUCK_J0x20
+#define MUSB_BABBLE_RCV_DISABLE0x04
+
 /* MUSB ULPI VBUSCONTROL */
 #define MUSB_ULPI_USE_EXTVBUS  0x01
 #define MUSB_ULPI_USE_EXTVBUSIND 0x02
@@ -246,6 +252,7 @@
  */
 
 #define MUSB_DEVCTL0x60/* 8 bit */
+#define MUSB_BABBLE_CTL0x61/* 8 bit */
 
 /* These are always controlled through the INDEX register */
 #define MUSB_TXFIFOSZ  0x62/* 8-bit (see masks) */
-- 
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


[PATCH v4 0/6] Add support for SW babble Control

2014-05-19 Thread George Cherian

Subject: [PATCH v3 0/5] Add support for SW babble Control

Series add support for SW babble control logic found in 
new silicon versions of AM335x. Runtime differentiation of
silicon version is done by checking the BABBLE_CTL register.
For newer silicon the register default value read is 0x4 and
for older versions its 0x0.

Patch 1 - Handle Babble only if MUSB is in HOST mode
Patch 2 - Convert recover work to delayed work.
Patch 3 - usb_phy_vbus_(off/_on) are NOPs for am335x PHY
   so use usb_phy(_shutdown/_init) in musb_platform_reset()
Patch 4 - Add return value for musb_platform_reset() in prepration
   to support SW babble_ctrl
Patch 5 - Add the sw_babble_control()
Patch 6 - Enable sw babble control for newer silicon

v3 - v4 : Fixes an issue in gagdet mode - BUS RESET should not
   be handled as a BABBLE. Added a check for the same.(Patch #1)
   Enable sw babble control properly (Patch #6)

v2 - v3 : Modify musb_platform_reset() to return zero on success.

George Cherian (6):
  usb: musb: core: Handle Babble condition only in HOST mode
  usb: musb: core: Convert babble recover work to delayed work
  usb: musb: dsps: Call usb_phy(_shutdown/_init) during
musb_platform_reset()
  usb: musb: core: Convert the musb_platform_reset to have a return
value.
  usb: musb: dsps: Add the sw_babble_control()
  usb: musb: dsps: Enable sw babble control for newer silicon

 drivers/usb/musb/musb_core.c | 51 ++
 drivers/usb/musb/musb_core.h | 12 ---
 drivers/usb/musb/musb_dsps.c | 86 ++--
 drivers/usb/musb/musb_regs.h |  7 
 4 files changed, 125 insertions(+), 31 deletions(-)

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


[PATCH v4 2/6] usb: musb: core: Convert babble recover work to delayed work

2014-05-19 Thread George Cherian
During babble condition both first disconnect of devices are
initiated. Make sure MUSB controller is reset and re-initialized
after all disconnects.

To acheive this schedule a delayed work for babble rrecovery.

While at that convert udelay to usleep_range.
Refer Documentation/timers/timers-howto.txt

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_core.c | 15 ---
 drivers/usb/musb/musb_core.h |  2 +-
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index eff3c5c..8920b80 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -850,7 +850,8 @@ b_host:
 
/* handle babble condition */
if (int_usb  MUSB_INTR_BABBLE  is_host_active(musb))
-   schedule_work(musb-recover_work);
+   schedule_delayed_work(musb-recover_work,
+ msecs_to_jiffies(100));
 
 #if 0
 /* REVISIT ... this would be for multiplexing periodic endpoints, or
@@ -1753,16 +1754,16 @@ static void musb_irq_work(struct work_struct *data)
 /* Recover from babble interrupt conditions */
 static void musb_recover_work(struct work_struct *data)
 {
-   struct musb *musb = container_of(data, struct musb, recover_work);
+   struct musb *musb = container_of(data, struct musb, recover_work.work);
int status;
 
musb_platform_reset(musb);
 
usb_phy_vbus_off(musb-xceiv);
-   udelay(100);
+   usleep_range(100, 200);
 
usb_phy_vbus_on(musb-xceiv);
-   udelay(100);
+   usleep_range(100, 200);
 
/*
 * When a babble condition occurs, the musb controller removes the
@@ -1945,7 +1946,7 @@ musb_init_controller(struct device *dev, int nIrq, void 
__iomem *ctrl)
 
/* Init IRQ workqueue before request_irq */
INIT_WORK(musb-irq_work, musb_irq_work);
-   INIT_WORK(musb-recover_work, musb_recover_work);
+   INIT_DELAYED_WORK(musb-recover_work, musb_recover_work);
INIT_DELAYED_WORK(musb-deassert_reset_work, musb_deassert_reset);
INIT_DELAYED_WORK(musb-finish_resume_work, musb_host_finish_resume);
 
@@ -2041,7 +2042,7 @@ fail4:
 
 fail3:
cancel_work_sync(musb-irq_work);
-   cancel_work_sync(musb-recover_work);
+   cancel_delayed_work_sync(musb-recover_work);
cancel_delayed_work_sync(musb-finish_resume_work);
cancel_delayed_work_sync(musb-deassert_reset_work);
if (musb-dma_controller)
@@ -2107,7 +2108,7 @@ static int musb_remove(struct platform_device *pdev)
dma_controller_destroy(musb-dma_controller);
 
cancel_work_sync(musb-irq_work);
-   cancel_work_sync(musb-recover_work);
+   cancel_delayed_work_sync(musb-recover_work);
cancel_delayed_work_sync(musb-finish_resume_work);
cancel_delayed_work_sync(musb-deassert_reset_work);
musb_free(musb);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 47e8874..423cd00 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -297,7 +297,7 @@ struct musb {
 
irqreturn_t (*isr)(int, void *);
struct work_struct  irq_work;
-   struct work_struct  recover_work;
+   struct delayed_work recover_work;
struct delayed_work deassert_reset_work;
struct delayed_work finish_resume_work;
u16 hwvers;
-- 
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


[PATCH v4 4/6] usb: musb: core: Convert the musb_platform_reset to have a return value.

2014-05-19 Thread George Cherian
Currently musb_platform_reset() is only used by dsps.
In case of BABBLE interrupt for other platforms the  musb_platform_reset()
is a NOP. In such situations no need to re-initialize the endpoints.
Also in the latest silicon revision of AM335x, we do have a babble recovery
mechanism without resetting the IP block. In preperation to add that support
its better to have a rest_done return for  musb_platform_reset().

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_core.c | 38 +-
 drivers/usb/musb/musb_core.h | 10 ++
 drivers/usb/musb/musb_dsps.c |  3 ++-
 3 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 8920b80..1b0b85d 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1755,28 +1755,32 @@ static void musb_irq_work(struct work_struct *data)
 static void musb_recover_work(struct work_struct *data)
 {
struct musb *musb = container_of(data, struct musb, recover_work.work);
-   int status;
+   int status, ret;
 
-   musb_platform_reset(musb);
+   ret  = musb_platform_reset(musb);
+   if (ret   0)
+   return;
 
-   usb_phy_vbus_off(musb-xceiv);
-   usleep_range(100, 200);
+   if (!ret) {
+   usb_phy_vbus_off(musb-xceiv);
+   usleep_range(100, 200);
 
-   usb_phy_vbus_on(musb-xceiv);
-   usleep_range(100, 200);
+   usb_phy_vbus_on(musb-xceiv);
+   usleep_range(100, 200);
 
-   /*
-* When a babble condition occurs, the musb controller removes the
-* session bit and the endpoint config is lost.
-*/
-   if (musb-dyn_fifo)
-   status = ep_config_from_table(musb);
-   else
-   status = ep_config_from_hw(musb);
+   /*
+* When a babble condition occurs, the musb controller
+* removes the session bit and the endpoint config is lost.
+*/
+   if (musb-dyn_fifo)
+   status = ep_config_from_table(musb);
+   else
+   status = ep_config_from_hw(musb);
 
-   /* start the session again */
-   if (status == 0)
-   musb_start(musb);
+   /* start the session again */
+   if (status == 0)
+   musb_start(musb);
+   }
 }
 
 /* --
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 423cd00..3ccb428 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -192,7 +192,7 @@ struct musb_platform_ops {
 
int (*set_mode)(struct musb *musb, u8 mode);
void(*try_idle)(struct musb *musb, unsigned long timeout);
-   void(*reset)(struct musb *musb);
+   int (*reset)(struct musb *musb);
 
int (*vbus_status)(struct musb *musb);
void(*set_vbus)(struct musb *musb, int on);
@@ -554,10 +554,12 @@ static inline void musb_platform_try_idle(struct musb 
*musb,
musb-ops-try_idle(musb, timeout);
 }
 
-static inline void musb_platform_reset(struct musb *musb)
+static inline int  musb_platform_reset(struct musb *musb)
 {
-   if (musb-ops-reset)
-   musb-ops-reset(musb);
+   if (!musb-ops-reset)
+   return -EINVAL;
+
+   return musb-ops-reset(musb);
 }
 
 static inline int musb_platform_get_vbus_status(struct musb *musb)
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 74c4193..f6f3087 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -536,7 +536,7 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode)
return 0;
 }
 
-static void dsps_musb_reset(struct musb *musb)
+static int dsps_musb_reset(struct musb *musb)
 {
struct device *dev = musb-controller;
struct dsps_glue *glue = dev_get_drvdata(dev-parent);
@@ -548,6 +548,7 @@ static void dsps_musb_reset(struct musb *musb)
usleep_range(100, 200);
usb_phy_init(musb-xceiv);
 
+   return 0;
 }
 
 static struct musb_platform_ops dsps_ops = {
-- 
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


[PATCH v4 1/6] usb: musb: core: Handle Babble condition only in HOST mode

2014-05-19 Thread George Cherian
BABBLE and RESET share the same interrupt. The interrupt
is considered to be RESET if MUSB is in peripheral mode and
as a BABBLE if MUSB is in HOST mode.

Handle babble condition iff MUSB is in HOST mode.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 61da471..eff3c5c 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -849,7 +849,7 @@ b_host:
}
 
/* handle babble condition */
-   if (int_usb  MUSB_INTR_BABBLE)
+   if (int_usb  MUSB_INTR_BABBLE  is_host_active(musb))
schedule_work(musb-recover_work);
 
 #if 0
-- 
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 v4 1/6] usb: musb: core: Handle Babble condition only in HOST mode

2014-05-19 Thread George Cherian

Hi Bin,
On 5/19/2014 9:24 PM, Bin Liu wrote:

Hi,

On Mon, May 19, 2014 at 8:39 AM, George Cherian george.cher...@ti.com wrote:

BABBLE and RESET share the same interrupt. The interrupt
is considered to be RESET if MUSB is in peripheral mode and
as a BABBLE if MUSB is in HOST mode.

Handle babble condition iff MUSB is in HOST mode.

Signed-off-by: George Cherian george.cher...@ti.com
---
  drivers/usb/musb/musb_core.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 61da471..eff3c5c 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -849,7 +849,7 @@ b_host:
 }

 /* handle babble condition */
-   if (int_usb  MUSB_INTR_BABBLE)
+   if (int_usb  MUSB_INTR_BABBLE  is_host_active(musb))
 schedule_work(musb-recover_work);

I guess my following comments are for Daniel's patch as while which
initially added the babble work.

Should this if statement be merged into the previous 'if(int_usb 
MUSB_INTR_RESET)' one, which handles the same interrupt and already
handles host and device mode respectively.


Initially I too had the babble handling as part of  'if(int_usb  
MUSB_INTR_RESET)'
one. But during my tests I hit a corner case where in we hit a BABBLE 
condition
on disconnect. In such case the babble interrupt can be handled only if 
we have a seperate

check, else its considered as a BUS RESET.

When all devices are disconnected  MUSB_DEVCTL_HM = 0 and the code 
always enter the

else path. In this path it treats the BABBLE as a BUS RESET.


Regards,
-Bin.


  #if 0
--
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



--
-George

--
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 0/5] Add support for SW babble Control

2014-05-15 Thread George Cherian

Hi Bin,

On 5/14/2014 10:13 PM, Bin Liu wrote:

George,

On Wed, May 14, 2014 at 9:34 AM, Bin Liu binml...@gmail.com wrote:

George,

On Wed, May 14, 2014 at 12:37 AM, George Cherian george.cher...@ti.com wrote:

On 5/14/2014 12:07 AM, Bin Liu wrote:

Hi,

On Tue, May 13, 2014 at 8:24 AM, George Cherian george.cher...@ti.com
wrote:

Hi Daniel,


On 5/13/2014 6:44 PM, Daniel Mack wrote:

Hi George,

On 05/13/2014 02:57 PM, George Cherian wrote:

I never enabled the MUSB_BABBLE_SW_SESSION_CTRL in the MUSB_BABBLE_CTL
reg.
can you try with the following patch.

diff --git a/drivers/usb/musb/musb_dsps.c
b/drivers/usb/musb/musb_dsps.c
index 1ae6681..1160cd1 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -477,8 +477,11 @@ static int dsps_musb_init(struct musb *musb)
   * logic enabled.
   */
  val = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
-   if (val == MUSB_BABBLE_RCV_DISABLE)
+   if (val == MUSB_BABBLE_RCV_DISABLE) {
  glue-sw_babble_enabled = true;
+   val |= MUSB_BABBLE_SW_SESSION_CTRL;
+   dsps_writeb(musb-mregs, MUSB_BABBLE_CTL, val);
+   }
  ret = dsps_musb_dbg_init(musb, glue);
  if (ret)

MUSB_BABBLE_STUCK_J still remains unset, so I get the same result as
without the patch: a full glue reset is conducted. Do I get you right
that you expect MUSB_BABBLE_STUCK_J to be set in babble conditions when
MUSB_BABBLE_SW_SESSION_CTRL is set?


Basically, there are 2 types of babble conditions.
1) Transient babble condition - which could be recovered from without an
IP
reset .
2) Babble condition - which could be recovered from only by doing an IP
reset.

Looks like you are always hitting case 2 (Most times am also hitting the
same).
Case 1 is really hard to reproduce. I don't have a reliable method as of
now
to
reproduce this case consistently.


[   19.672373] CAUTION: musb: Babble Interrupt Occurred
[   19.66] musb_stage0_irq 789: unhandled DISCONNECT transition
(a_wait_bcon)
[   19.685815] usb 1-1: USB disconnect, device number 3
[   19.769720] musb-hdrc musb-hdrc.0.auto: babble: MUSB_BABBLE_CTL value
44
[   19.776765] musb-hdrc musb-hdrc.0.auto: STUCK_J is reset


I don't quite follow, especially as I lack documentation of the IP core.
How do you test babble errors, is there any way to force them to happen
reliably?


There is no 100% reliable method to force it to happen. Following is

I have a way to force babble happen reliably - shorting DP or DM to
VBUS. I opened the far-end plug of the USB cable, so I can easily
short DP or DM to VBUS.

Good to know that you have a reliable way to test babble condition.
Can you please do a quick test on 3.15.0-rc4 with the series applied?
In case of any assistance please do let me know.

Sure, but could you please re-send those patches to my corporate email
so that I can apply them from Thunderbird?

You don't have to resend the patches. Nishanth Menon showed me a way
to extract the patch from Gmail - Thanks Nishanth.

But which repo do you want to me test with? The first patch ([PATCH v2
1/5] usb: musb: core: Convert babble recover work to delayed work)
does not apply to v3.15-rc4 tag. the current musb_core.c does not have
the recovery work for musb. Please let me know what I missed.

Oops I missed to mention the same.
Please try on
git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git master

Thanks,
-Bin.


I read these linux-usb emails in Gmail, and  am not aware of any easy
way to extract patches from Gmail.

BTY, I tested with TI 3.12.10 kernel, in which I guess the babble
handling is similar to this patch set. With TI3.12.10, MISC is always
0x64, so MUSB never restarts.

Thanks,
-Bin.


But the interesting thing is that with TI 3.2 kernel, shorting DP or
DM to VBUS causes MISC register to be 0x4, but the result is
completely opposite in TI 3.12.10 kernel, which cause MISC to be 0x64.

So in the 3.2 kernel, the babble handing resets the controller, but
the 3.12.10 does not.

Regards,
-Bin.


my setup ,
I have a HUB with 4 devices connected , which gives me a Babble interrupt
on both connects and disconnects ( Not always though).


Anyway, the full glue layer solves this rare condition quite well for
me. Is there any downside of this?


Daniel


--
-George

--
To unsubscribe from this list: send the line unsubscribe linux-omap in

the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
-George




--
-George

--
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 5/5] usb: dwc3: dwc3-omap: Disable/Enable core interrupts in Suspend/Resume

2014-05-14 Thread George Cherian

On 5/13/2014 9:20 PM, Felipe Balbi wrote:

Hi,

On Thu, May 08, 2014 at 03:03:07PM +0530, George Cherian wrote:

Enabling the core interrupts in complete is too late for XHCI, and stops
xhci from proper operation. So remove prepare and complete and disable/enable

isn't this a bug in xhci ? I mean the driver should make no assumption
as to when IRQs are enabled, why do we need to enable IRQs earlier when
the device is only considered ready for use after -complete()
finishes executing ?
I dont think its a bug in xhci. In case of xhci-pci driver it actually 
does an

hcd-driver-pci_suspend (xhci_suspend) followed by synchronize_irq()
and the does a pci_disable_device().  In resume path it calls 
pci_enable_device()

followed by hcd-driver-pci_resume(xhci_resume).

In case of dwc3-omap we do have a wrapper register which can still 
disable the XHCI IRQs

even though the xhci driver enables the interrupts internally.

Now dwc3-omap wrapper driver should not actually fiddle with the core 
Interrupt

enable/disable except in probe/remove.


 From documentation we have:

107  * @complete: Undo the changes made by @prepare().  This method is executed 
for
108  *  all kinds of resume transitions, following one of the resume 
callbacks:
109  *  @resume(), @thaw(), @restore().  Also called if the state transition
110  *  fails before the driver's suspend callback: @suspend(), @freeze() or
111  *  @poweroff(), can be executed (e.g. if the suspend callback fails 
for one
112  *  of the other devices that the PM core has unsuccessfully attempted 
to
113  *  suspend earlier).
114  *  The PM core executes subsystem-level @complete() after it has 
executed
115  *  the appropriate resume callbacks for all devices.

which tells me that using -complete() to reenable IRQs is ok here.
Specially when you consider that the role of -prepare() is to prevent
new children from being created and, for a USB host, that means we
should prevent hub port changes.
Probably the patch should have been to still keep the complete/prepare 
in place
but not disable the core interrupts, rather enable/disable only the 
wrapper interrupt.

cheers




--
-George

--
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 4/5] usb: musb: dsps: Add the sw_babble_control()

2014-05-13 Thread George Cherian
Add sw_babble_control() logic to differentiate between transient
babble and real babble condition. Also add the SW babble control
register definitions.

Babble control register logic is implemented in the latest
revision of AM335x.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_dsps.c | 50 
 drivers/usb/musb/musb_regs.h |  7 +++
 2 files changed, 57 insertions(+)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index f6f3087..eb1985a 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -536,6 +536,56 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode)
return 0;
 }
 
+static int sw_babble_control(struct musb *musb)
+{
+   int timeout = 10;
+   u8 babble_ctl, session_restart = 0;
+
+   babble_ctl = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   dev_dbg(musb-controller, babble: MUSB_BABBLE_CTL value %x\n,
+   babble_ctl);
+   /*
+* check line monitor flag to check whether babble is
+* due to noise
+*/
+   dev_dbg(musb-controller, STUCK_J is %s\n,
+   babble_ctl  MUSB_BABBLE_STUCK_J ? set : reset);
+
+   if (babble_ctl  MUSB_BABBLE_STUCK_J) {
+   /*
+* babble is due to noise, then set transmit idle (d7 bit)
+* to resume normal operation
+*/
+   babble_ctl = musb_readb(musb-mregs, MUSB_BABBLE_CTL);
+   babble_ctl |= MUSB_BABBLE_FORCE_TXIDLE;
+   dsps_writeb(musb-mregs, MUSB_BABBLE_CTL, babble_ctl);
+
+   /* wait till line monitor flag cleared */
+   dev_dbg(musb-controller, Set TXIDLE, wait J to clear\n);
+   do {
+   babble_ctl = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   udelay(1);
+   } while ((babble_ctl  MUSB_BABBLE_STUCK_J)  timeout--);
+
+   /* check whether stuck_at_j bit cleared */
+   if (babble_ctl  MUSB_BABBLE_STUCK_J) {
+   /*
+* real babble condition is occured
+* restart the controller to start the
+* session again
+*/
+   dev_dbg(musb-controller, J not cleared, misc (%x)\n,
+   babble_ctl);
+   session_restart = 1;
+   }
+
+   } else {
+   session_restart = 1;
+   }
+
+   return session_restart;
+}
+
 static int dsps_musb_reset(struct musb *musb)
 {
struct device *dev = musb-controller;
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
index 03f2655..b9bcda5 100644
--- a/drivers/usb/musb/musb_regs.h
+++ b/drivers/usb/musb/musb_regs.h
@@ -72,6 +72,12 @@
 #define MUSB_DEVCTL_HR 0x02
 #define MUSB_DEVCTL_SESSION0x01
 
+/* BABBLE_CTL */
+#define MUSB_BABBLE_FORCE_TXIDLE   0x80
+#define MUSB_BABBLE_SW_SESSION_CTRL0x40
+#define MUSB_BABBLE_STUCK_J0x20
+#define MUSB_BABBLE_RCV_DISABLE0x04
+
 /* MUSB ULPI VBUSCONTROL */
 #define MUSB_ULPI_USE_EXTVBUS  0x01
 #define MUSB_ULPI_USE_EXTVBUSIND 0x02
@@ -246,6 +252,7 @@
  */
 
 #define MUSB_DEVCTL0x60/* 8 bit */
+#define MUSB_BABBLE_CTL0x61/* 8 bit */
 
 /* These are always controlled through the INDEX register */
 #define MUSB_TXFIFOSZ  0x62/* 8-bit (see masks) */
-- 
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


[PATCH v3 5/5] usb: musb: dsps: Enable sw babble control for newer silicon

2014-05-13 Thread George Cherian
Find whether we are running on newer silicon. The babble control
register reads 0x4 by default in newer silicon as opposed to 0
in old versions of AM335x. Based on this enable the sw babble
control logic.

Signed-off-by: George Cherian george.cher...@ti.com
---
 drivers/usb/musb/musb_dsps.c | 34 --
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index eb1985a..1ae6681 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -136,6 +136,7 @@ struct dsps_glue {
const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
struct timer_list timer;/* otg_workaround timer */
unsigned long last_timer;/* last timer data for each instance */
+   bool sw_babble_enabled;
 
struct dsps_context context;
struct debugfs_regset32 regset;
@@ -469,6 +470,16 @@ static int dsps_musb_init(struct musb *musb)
val = ~(1  wrp-otg_disable);
dsps_writel(musb-ctrl_base, wrp-phy_utmi, val);
 
+   /*
+*  Check whether the dsps version has babble control enabled.
+* In latest silicon revision the babble control logic is enabled.
+* If MUSB_BABBLE_CTL returns 0x4 then we have the babble control
+* logic enabled.
+*/
+   val = dsps_readb(musb-mregs, MUSB_BABBLE_CTL);
+   if (val == MUSB_BABBLE_RCV_DISABLE)
+   glue-sw_babble_enabled = true;
+
ret = dsps_musb_dbg_init(musb, glue);
if (ret)
return ret;
@@ -591,14 +602,25 @@ static int dsps_musb_reset(struct musb *musb)
struct device *dev = musb-controller;
struct dsps_glue *glue = dev_get_drvdata(dev-parent);
const struct dsps_musb_wrapper *wrp = glue-wrp;
+   int session_restart = 0;
 
-   dsps_writel(musb-ctrl_base, wrp-control, (1  wrp-reset));
-   usleep_range(100, 200);
-   usb_phy_shutdown(musb-xceiv);
-   usleep_range(100, 200);
-   usb_phy_init(musb-xceiv);
+   if (glue-sw_babble_enabled)
+   session_restart = sw_babble_control(musb);
+   /*
+* In case of new silicon version babble condition can be recovered
+* without resetting the MUSB. But for older silicon versions, MUSB
+* reset is needed
+*/
+   if (session_restart || !glue-sw_babble_enabled) {
+   dsps_writel(musb-ctrl_base, wrp-control, (1  wrp-reset));
+   usleep_range(100, 200);
+   usb_phy_shutdown(musb-xceiv);
+   usleep_range(100, 200);
+   usb_phy_init(musb-xceiv);
+   session_restart = 1;
+   }
 
-   return 0;
+   return !session_restart;
 }
 
 static struct musb_platform_ops dsps_ops = {
-- 
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


  1   2   3   >