aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaarten ter Huurne <maarten@treewalker.org>2016-02-28 10:34:16 -0500
committerFelipe Balbi <balbi@kernel.org>2016-03-04 08:14:47 -0500
commit2eafe93b92921308b624466b4c8a99bd1ace6e4f (patch)
treecdbe0aac33f1d5ac233a30def2d49bc89c3f22e2
parentcff5638ef7852196879f9687e70d49ea291bbb33 (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.c11
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