diff options
author | Apelete Seketeli <apelete@seketeli.net> | 2013-12-19 15:42:27 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-12-20 10:53:59 -0500 |
commit | 23db9fd238d6ca5aa165900bf14fb42e3e2d0815 (patch) | |
tree | c0686a0a6700f2ff05ef01bac28ad8e2c864e2bc /drivers/usb/musb/musb_gadget.c | |
parent | 10434d273ccdcee8eab4f5e08497d65841bbf354 (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.c | 10 |
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 { |