aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/otg/gpio_vbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/otg/gpio_vbus.c')
-rw-r--r--drivers/usb/otg/gpio_vbus.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c
index 3ece43a2e4c1..a0a2178974fe 100644
--- a/drivers/usb/otg/gpio_vbus.c
+++ b/drivers/usb/otg/gpio_vbus.c
@@ -96,7 +96,7 @@ static void gpio_vbus_work(struct work_struct *work)
96 struct gpio_vbus_data *gpio_vbus = 96 struct gpio_vbus_data *gpio_vbus =
97 container_of(work, struct gpio_vbus_data, work); 97 container_of(work, struct gpio_vbus_data, work);
98 struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data; 98 struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data;
99 int gpio; 99 int gpio, status;
100 100
101 if (!gpio_vbus->phy.otg->gadget) 101 if (!gpio_vbus->phy.otg->gadget)
102 return; 102 return;
@@ -108,7 +108,9 @@ static void gpio_vbus_work(struct work_struct *work)
108 */ 108 */
109 gpio = pdata->gpio_pullup; 109 gpio = pdata->gpio_pullup;
110 if (is_vbus_powered(pdata)) { 110 if (is_vbus_powered(pdata)) {
111 status = USB_EVENT_VBUS;
111 gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL; 112 gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL;
113 gpio_vbus->phy.last_event = status;
112 usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget); 114 usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget);
113 115
114 /* drawing a "unit load" is *always* OK, except for OTG */ 116 /* drawing a "unit load" is *always* OK, except for OTG */
@@ -117,6 +119,9 @@ static void gpio_vbus_work(struct work_struct *work)
117 /* optionally enable D+ pullup */ 119 /* optionally enable D+ pullup */
118 if (gpio_is_valid(gpio)) 120 if (gpio_is_valid(gpio))
119 gpio_set_value(gpio, !pdata->gpio_pullup_inverted); 121 gpio_set_value(gpio, !pdata->gpio_pullup_inverted);
122
123 atomic_notifier_call_chain(&gpio_vbus->phy.notifier,
124 status, gpio_vbus->phy.otg->gadget);
120 } else { 125 } else {
121 /* optionally disable D+ pullup */ 126 /* optionally disable D+ pullup */
122 if (gpio_is_valid(gpio)) 127 if (gpio_is_valid(gpio))
@@ -125,7 +130,12 @@ static void gpio_vbus_work(struct work_struct *work)
125 set_vbus_draw(gpio_vbus, 0); 130 set_vbus_draw(gpio_vbus, 0);
126 131
127 usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget); 132 usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget);
133 status = USB_EVENT_NONE;
128 gpio_vbus->phy.state = OTG_STATE_B_IDLE; 134 gpio_vbus->phy.state = OTG_STATE_B_IDLE;
135 gpio_vbus->phy.last_event = status;
136
137 atomic_notifier_call_chain(&gpio_vbus->phy.notifier,
138 status, gpio_vbus->phy.otg->gadget);
129 } 139 }
130} 140}
131 141
@@ -287,6 +297,9 @@ static int __init gpio_vbus_probe(struct platform_device *pdev)
287 irq, err); 297 irq, err);
288 goto err_irq; 298 goto err_irq;
289 } 299 }
300
301 ATOMIC_INIT_NOTIFIER_HEAD(&gpio_vbus->phy.notifier);
302
290 INIT_WORK(&gpio_vbus->work, gpio_vbus_work); 303 INIT_WORK(&gpio_vbus->work, gpio_vbus_work);
291 304
292 gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); 305 gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw");