aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musb_gadget.c
diff options
context:
space:
mode:
authorApelete Seketeli <apelete@seketeli.net>2013-12-19 15:42:27 -0500
committerFelipe Balbi <balbi@ti.com>2013-12-20 10:53:59 -0500
commit23db9fd238d6ca5aa165900bf14fb42e3e2d0815 (patch)
treec0686a0a6700f2ff05ef01bac28ad8e2c864e2bc /drivers/usb/musb/musb_gadget.c
parent10434d273ccdcee8eab4f5e08497d65841bbf354 (diff)
usb: musb: fix setting JZ4740 gadget periphal mode on reset
JZ4740 USB Device Controller is not OTG compatible and does not have DEVCTL register in silicon. During ethernet-over-usb transactions, on reset, musb driver tries to read from DEVCTL and consequently sets device as host (A-Device) instead of peripheral (B-Device), which makes it a composite device to the USB gadget driver. This induces a kernel panic during power down where the USB gadget driver does a null pointer dereference when trying to access the composite device configuration. On reset, do not rely on DEVCTL value for setting gadget peripheral mode. Use is_otg flag instead to set it to B-Device. Signed-off-by: Apelete Seketeli <apelete@seketeli.net> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/musb/musb_gadget.c')
-rw-r--r--drivers/usb/musb/musb_gadget.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index c410a7ff150b..d4aa779339f1 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -2119,7 +2119,15 @@ __acquires(musb->lock)
2119 /* Normal reset, as B-Device; 2119 /* Normal reset, as B-Device;
2120 * or else after HNP, as A-Device 2120 * or else after HNP, as A-Device
2121 */ 2121 */
2122 if (devctl & MUSB_DEVCTL_BDEVICE) { 2122 if (!musb->g.is_otg) {
2123 /* USB device controllers that are not OTG compatible
2124 * may not have DEVCTL register in silicon.
2125 * In that case, do not rely on devctl for setting
2126 * peripheral mode.
2127 */
2128 musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
2129 musb->g.is_a_peripheral = 0;
2130 } else if (devctl & MUSB_DEVCTL_BDEVICE) {
2123 musb->xceiv->state = OTG_STATE_B_PERIPHERAL; 2131 musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
2124 musb->g.is_a_peripheral = 0; 2132 musb->g.is_a_peripheral = 0;
2125 } else { 2133 } else {