diff options
Diffstat (limited to 'drivers/usb/otg/gpio_vbus.c')
-rw-r--r-- | drivers/usb/otg/gpio_vbus.c | 15 |
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"); |