diff options
author | Maarten ter Huurne <maarten@treewalker.org> | 2016-02-28 10:34:16 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@kernel.org> | 2016-03-04 08:14:47 -0500 |
commit | 2eafe93b92921308b624466b4c8a99bd1ace6e4f (patch) | |
tree | cdbe0aac33f1d5ac233a30def2d49bc89c3f22e2 | |
parent | cff5638ef7852196879f9687e70d49ea291bbb33 (diff) |
usb: phy: generic: Handle late registration of gadget
It is possible for the VBUS detect GPIO interrupt to occur before
nop_set_peripheral() is called, in which case otg->gadget is NULL.
Signed-off-by: Maarten ter Huurne <maarten@treewalker.org>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
-rw-r--r-- | drivers/usb/phy/phy-generic.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index 5320cb8642cb..980c9dee09eb 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c | |||
@@ -118,7 +118,8 @@ static irqreturn_t nop_gpio_vbus_thread(int irq, void *data) | |||
118 | status = USB_EVENT_VBUS; | 118 | status = USB_EVENT_VBUS; |
119 | otg->state = OTG_STATE_B_PERIPHERAL; | 119 | otg->state = OTG_STATE_B_PERIPHERAL; |
120 | nop->phy.last_event = status; | 120 | nop->phy.last_event = status; |
121 | usb_gadget_vbus_connect(otg->gadget); | 121 | if (otg->gadget) |
122 | usb_gadget_vbus_connect(otg->gadget); | ||
122 | 123 | ||
123 | /* drawing a "unit load" is *always* OK, except for OTG */ | 124 | /* drawing a "unit load" is *always* OK, except for OTG */ |
124 | nop_set_vbus_draw(nop, 100); | 125 | nop_set_vbus_draw(nop, 100); |
@@ -128,7 +129,8 @@ static irqreturn_t nop_gpio_vbus_thread(int irq, void *data) | |||
128 | } else { | 129 | } else { |
129 | nop_set_vbus_draw(nop, 0); | 130 | nop_set_vbus_draw(nop, 0); |
130 | 131 | ||
131 | usb_gadget_vbus_disconnect(otg->gadget); | 132 | if (otg->gadget) |
133 | usb_gadget_vbus_disconnect(otg->gadget); | ||
132 | status = USB_EVENT_NONE; | 134 | status = USB_EVENT_NONE; |
133 | otg->state = OTG_STATE_B_IDLE; | 135 | otg->state = OTG_STATE_B_IDLE; |
134 | nop->phy.last_event = status; | 136 | nop->phy.last_event = status; |
@@ -184,7 +186,10 @@ static int nop_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) | |||
184 | } | 186 | } |
185 | 187 | ||
186 | otg->gadget = gadget; | 188 | otg->gadget = gadget; |
187 | otg->state = OTG_STATE_B_IDLE; | 189 | if (otg->state == OTG_STATE_B_PERIPHERAL) |
190 | usb_gadget_vbus_connect(gadget); | ||
191 | else | ||
192 | otg->state = OTG_STATE_B_IDLE; | ||
188 | return 0; | 193 | return 0; |
189 | } | 194 | } |
190 | 195 | ||