diff options
Diffstat (limited to 'drivers/usb/otg/gpio_vbus.c')
-rw-r--r-- | drivers/usb/otg/gpio_vbus.c | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c index fb644c107ded..3ece43a2e4c1 100644 --- a/drivers/usb/otg/gpio_vbus.c +++ b/drivers/usb/otg/gpio_vbus.c | |||
@@ -32,7 +32,7 @@ | |||
32 | * Needs to be loaded before the UDC driver that will use it. | 32 | * Needs to be loaded before the UDC driver that will use it. |
33 | */ | 33 | */ |
34 | struct gpio_vbus_data { | 34 | struct gpio_vbus_data { |
35 | struct otg_transceiver otg; | 35 | struct usb_phy phy; |
36 | struct device *dev; | 36 | struct device *dev; |
37 | struct regulator *vbus_draw; | 37 | struct regulator *vbus_draw; |
38 | int vbus_draw_enabled; | 38 | int vbus_draw_enabled; |
@@ -98,7 +98,7 @@ static void gpio_vbus_work(struct work_struct *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; |
100 | 100 | ||
101 | if (!gpio_vbus->otg.gadget) | 101 | if (!gpio_vbus->phy.otg->gadget) |
102 | return; | 102 | return; |
103 | 103 | ||
104 | /* Peripheral controllers which manage the pullup themselves won't have | 104 | /* Peripheral controllers which manage the pullup themselves won't have |
@@ -108,8 +108,8 @@ 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 | gpio_vbus->otg.state = OTG_STATE_B_PERIPHERAL; | 111 | gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL; |
112 | usb_gadget_vbus_connect(gpio_vbus->otg.gadget); | 112 | usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget); |
113 | 113 | ||
114 | /* drawing a "unit load" is *always* OK, except for OTG */ | 114 | /* drawing a "unit load" is *always* OK, except for OTG */ |
115 | set_vbus_draw(gpio_vbus, 100); | 115 | set_vbus_draw(gpio_vbus, 100); |
@@ -124,8 +124,8 @@ static void gpio_vbus_work(struct work_struct *work) | |||
124 | 124 | ||
125 | set_vbus_draw(gpio_vbus, 0); | 125 | set_vbus_draw(gpio_vbus, 0); |
126 | 126 | ||
127 | usb_gadget_vbus_disconnect(gpio_vbus->otg.gadget); | 127 | usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget); |
128 | gpio_vbus->otg.state = OTG_STATE_B_IDLE; | 128 | gpio_vbus->phy.state = OTG_STATE_B_IDLE; |
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
@@ -135,12 +135,13 @@ static irqreturn_t gpio_vbus_irq(int irq, void *data) | |||
135 | struct platform_device *pdev = data; | 135 | struct platform_device *pdev = data; |
136 | struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; | 136 | struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; |
137 | struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); | 137 | struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); |
138 | struct usb_otg *otg = gpio_vbus->phy.otg; | ||
138 | 139 | ||
139 | dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n", | 140 | dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n", |
140 | is_vbus_powered(pdata) ? "supplied" : "inactive", | 141 | is_vbus_powered(pdata) ? "supplied" : "inactive", |
141 | gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none"); | 142 | otg->gadget ? otg->gadget->name : "none"); |
142 | 143 | ||
143 | if (gpio_vbus->otg.gadget) | 144 | if (otg->gadget) |
144 | schedule_work(&gpio_vbus->work); | 145 | schedule_work(&gpio_vbus->work); |
145 | 146 | ||
146 | return IRQ_HANDLED; | 147 | return IRQ_HANDLED; |
@@ -149,15 +150,15 @@ static irqreturn_t gpio_vbus_irq(int irq, void *data) | |||
149 | /* OTG transceiver interface */ | 150 | /* OTG transceiver interface */ |
150 | 151 | ||
151 | /* bind/unbind the peripheral controller */ | 152 | /* bind/unbind the peripheral controller */ |
152 | static int gpio_vbus_set_peripheral(struct otg_transceiver *otg, | 153 | static int gpio_vbus_set_peripheral(struct usb_otg *otg, |
153 | struct usb_gadget *gadget) | 154 | struct usb_gadget *gadget) |
154 | { | 155 | { |
155 | struct gpio_vbus_data *gpio_vbus; | 156 | struct gpio_vbus_data *gpio_vbus; |
156 | struct gpio_vbus_mach_info *pdata; | 157 | struct gpio_vbus_mach_info *pdata; |
157 | struct platform_device *pdev; | 158 | struct platform_device *pdev; |
158 | int gpio, irq; | 159 | int gpio, irq; |
159 | 160 | ||
160 | gpio_vbus = container_of(otg, struct gpio_vbus_data, otg); | 161 | gpio_vbus = container_of(otg->phy, struct gpio_vbus_data, phy); |
161 | pdev = to_platform_device(gpio_vbus->dev); | 162 | pdev = to_platform_device(gpio_vbus->dev); |
162 | pdata = gpio_vbus->dev->platform_data; | 163 | pdata = gpio_vbus->dev->platform_data; |
163 | irq = gpio_to_irq(pdata->gpio_vbus); | 164 | irq = gpio_to_irq(pdata->gpio_vbus); |
@@ -174,7 +175,7 @@ static int gpio_vbus_set_peripheral(struct otg_transceiver *otg, | |||
174 | set_vbus_draw(gpio_vbus, 0); | 175 | set_vbus_draw(gpio_vbus, 0); |
175 | 176 | ||
176 | usb_gadget_vbus_disconnect(otg->gadget); | 177 | usb_gadget_vbus_disconnect(otg->gadget); |
177 | otg->state = OTG_STATE_UNDEFINED; | 178 | otg->phy->state = OTG_STATE_UNDEFINED; |
178 | 179 | ||
179 | otg->gadget = NULL; | 180 | otg->gadget = NULL; |
180 | return 0; | 181 | return 0; |
@@ -189,23 +190,23 @@ static int gpio_vbus_set_peripheral(struct otg_transceiver *otg, | |||
189 | } | 190 | } |
190 | 191 | ||
191 | /* effective for B devices, ignored for A-peripheral */ | 192 | /* effective for B devices, ignored for A-peripheral */ |
192 | static int gpio_vbus_set_power(struct otg_transceiver *otg, unsigned mA) | 193 | static int gpio_vbus_set_power(struct usb_phy *phy, unsigned mA) |
193 | { | 194 | { |
194 | struct gpio_vbus_data *gpio_vbus; | 195 | struct gpio_vbus_data *gpio_vbus; |
195 | 196 | ||
196 | gpio_vbus = container_of(otg, struct gpio_vbus_data, otg); | 197 | gpio_vbus = container_of(phy, struct gpio_vbus_data, phy); |
197 | 198 | ||
198 | if (otg->state == OTG_STATE_B_PERIPHERAL) | 199 | if (phy->state == OTG_STATE_B_PERIPHERAL) |
199 | set_vbus_draw(gpio_vbus, mA); | 200 | set_vbus_draw(gpio_vbus, mA); |
200 | return 0; | 201 | return 0; |
201 | } | 202 | } |
202 | 203 | ||
203 | /* for non-OTG B devices: set/clear transceiver suspend mode */ | 204 | /* for non-OTG B devices: set/clear transceiver suspend mode */ |
204 | static int gpio_vbus_set_suspend(struct otg_transceiver *otg, int suspend) | 205 | static int gpio_vbus_set_suspend(struct usb_phy *phy, int suspend) |
205 | { | 206 | { |
206 | struct gpio_vbus_data *gpio_vbus; | 207 | struct gpio_vbus_data *gpio_vbus; |
207 | 208 | ||
208 | gpio_vbus = container_of(otg, struct gpio_vbus_data, otg); | 209 | gpio_vbus = container_of(phy, struct gpio_vbus_data, phy); |
209 | 210 | ||
210 | /* draw max 0 mA from vbus in suspend mode; or the previously | 211 | /* draw max 0 mA from vbus in suspend mode; or the previously |
211 | * recorded amount of current if not suspended | 212 | * recorded amount of current if not suspended |
@@ -213,7 +214,7 @@ static int gpio_vbus_set_suspend(struct otg_transceiver *otg, int suspend) | |||
213 | * NOTE: high powered configs (mA > 100) may draw up to 2.5 mA | 214 | * NOTE: high powered configs (mA > 100) may draw up to 2.5 mA |
214 | * if they're wake-enabled ... we don't handle that yet. | 215 | * if they're wake-enabled ... we don't handle that yet. |
215 | */ | 216 | */ |
216 | return gpio_vbus_set_power(otg, suspend ? 0 : gpio_vbus->mA); | 217 | return gpio_vbus_set_power(phy, suspend ? 0 : gpio_vbus->mA); |
217 | } | 218 | } |
218 | 219 | ||
219 | /* platform driver interface */ | 220 | /* platform driver interface */ |
@@ -233,13 +234,21 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) | |||
233 | if (!gpio_vbus) | 234 | if (!gpio_vbus) |
234 | return -ENOMEM; | 235 | return -ENOMEM; |
235 | 236 | ||
237 | gpio_vbus->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); | ||
238 | if (!gpio_vbus->phy.otg) { | ||
239 | kfree(gpio_vbus); | ||
240 | return -ENOMEM; | ||
241 | } | ||
242 | |||
236 | platform_set_drvdata(pdev, gpio_vbus); | 243 | platform_set_drvdata(pdev, gpio_vbus); |
237 | gpio_vbus->dev = &pdev->dev; | 244 | gpio_vbus->dev = &pdev->dev; |
238 | gpio_vbus->otg.label = "gpio-vbus"; | 245 | gpio_vbus->phy.label = "gpio-vbus"; |
239 | gpio_vbus->otg.state = OTG_STATE_UNDEFINED; | 246 | gpio_vbus->phy.set_power = gpio_vbus_set_power; |
240 | gpio_vbus->otg.set_peripheral = gpio_vbus_set_peripheral; | 247 | gpio_vbus->phy.set_suspend = gpio_vbus_set_suspend; |
241 | gpio_vbus->otg.set_power = gpio_vbus_set_power; | 248 | gpio_vbus->phy.state = OTG_STATE_UNDEFINED; |
242 | gpio_vbus->otg.set_suspend = gpio_vbus_set_suspend; | 249 | |
250 | gpio_vbus->phy.otg->phy = &gpio_vbus->phy; | ||
251 | gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; | ||
243 | 252 | ||
244 | err = gpio_request(gpio, "vbus_detect"); | 253 | err = gpio_request(gpio, "vbus_detect"); |
245 | if (err) { | 254 | if (err) { |
@@ -288,7 +297,7 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) | |||
288 | } | 297 | } |
289 | 298 | ||
290 | /* only active when a gadget is registered */ | 299 | /* only active when a gadget is registered */ |
291 | err = otg_set_transceiver(&gpio_vbus->otg); | 300 | err = usb_set_transceiver(&gpio_vbus->phy); |
292 | if (err) { | 301 | if (err) { |
293 | dev_err(&pdev->dev, "can't register transceiver, err: %d\n", | 302 | dev_err(&pdev->dev, "can't register transceiver, err: %d\n", |
294 | err); | 303 | err); |
@@ -304,6 +313,7 @@ err_irq: | |||
304 | gpio_free(pdata->gpio_vbus); | 313 | gpio_free(pdata->gpio_vbus); |
305 | err_gpio: | 314 | err_gpio: |
306 | platform_set_drvdata(pdev, NULL); | 315 | platform_set_drvdata(pdev, NULL); |
316 | kfree(gpio_vbus->phy.otg); | ||
307 | kfree(gpio_vbus); | 317 | kfree(gpio_vbus); |
308 | return err; | 318 | return err; |
309 | } | 319 | } |
@@ -316,13 +326,14 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev) | |||
316 | 326 | ||
317 | regulator_put(gpio_vbus->vbus_draw); | 327 | regulator_put(gpio_vbus->vbus_draw); |
318 | 328 | ||
319 | otg_set_transceiver(NULL); | 329 | usb_set_transceiver(NULL); |
320 | 330 | ||
321 | free_irq(gpio_to_irq(gpio), &pdev->dev); | 331 | free_irq(gpio_to_irq(gpio), &pdev->dev); |
322 | if (gpio_is_valid(pdata->gpio_pullup)) | 332 | if (gpio_is_valid(pdata->gpio_pullup)) |
323 | gpio_free(pdata->gpio_pullup); | 333 | gpio_free(pdata->gpio_pullup); |
324 | gpio_free(gpio); | 334 | gpio_free(gpio); |
325 | platform_set_drvdata(pdev, NULL); | 335 | platform_set_drvdata(pdev, NULL); |
336 | kfree(gpio_vbus->phy.otg); | ||
326 | kfree(gpio_vbus); | 337 | kfree(gpio_vbus); |
327 | 338 | ||
328 | return 0; | 339 | return 0; |