diff options
Diffstat (limited to 'drivers/usb/otg')
-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 4e1b1384dc89..3ece43a2e4c1 100644 --- a/drivers/usb/otg/gpio_vbus.c +++ b/drivers/usb/otg/gpio_vbus.c @@ -32,7 +32,7 @@ * Needs to be loaded before the UDC driver that will use it. */ struct gpio_vbus_data { - struct usb_phy otg; + struct usb_phy phy; struct device *dev; struct regulator *vbus_draw; int vbus_draw_enabled; @@ -98,7 +98,7 @@ static void gpio_vbus_work(struct work_struct *work) struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data; int gpio; - if (!gpio_vbus->otg.gadget) + if (!gpio_vbus->phy.otg->gadget) return; /* Peripheral controllers which manage the pullup themselves won't have @@ -108,8 +108,8 @@ static void gpio_vbus_work(struct work_struct *work) */ gpio = pdata->gpio_pullup; if (is_vbus_powered(pdata)) { - gpio_vbus->otg.state = OTG_STATE_B_PERIPHERAL; - usb_gadget_vbus_connect(gpio_vbus->otg.gadget); + gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL; + usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget); /* drawing a "unit load" is *always* OK, except for OTG */ set_vbus_draw(gpio_vbus, 100); @@ -124,8 +124,8 @@ static void gpio_vbus_work(struct work_struct *work) set_vbus_draw(gpio_vbus, 0); - usb_gadget_vbus_disconnect(gpio_vbus->otg.gadget); - gpio_vbus->otg.state = OTG_STATE_B_IDLE; + usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget); + gpio_vbus->phy.state = OTG_STATE_B_IDLE; } } @@ -135,12 +135,13 @@ static irqreturn_t gpio_vbus_irq(int irq, void *data) struct platform_device *pdev = data; struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); + struct usb_otg *otg = gpio_vbus->phy.otg; dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n", is_vbus_powered(pdata) ? "supplied" : "inactive", - gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none"); + otg->gadget ? otg->gadget->name : "none"); - if (gpio_vbus->otg.gadget) + if (otg->gadget) schedule_work(&gpio_vbus->work); return IRQ_HANDLED; @@ -149,15 +150,15 @@ static irqreturn_t gpio_vbus_irq(int irq, void *data) /* OTG transceiver interface */ /* bind/unbind the peripheral controller */ -static int gpio_vbus_set_peripheral(struct usb_phy *otg, - struct usb_gadget *gadget) +static int gpio_vbus_set_peripheral(struct usb_otg *otg, + struct usb_gadget *gadget) { struct gpio_vbus_data *gpio_vbus; struct gpio_vbus_mach_info *pdata; struct platform_device *pdev; int gpio, irq; - gpio_vbus = container_of(otg, struct gpio_vbus_data, otg); + gpio_vbus = container_of(otg->phy, struct gpio_vbus_data, phy); pdev = to_platform_device(gpio_vbus->dev); pdata = gpio_vbus->dev->platform_data; irq = gpio_to_irq(pdata->gpio_vbus); @@ -174,7 +175,7 @@ static int gpio_vbus_set_peripheral(struct usb_phy *otg, set_vbus_draw(gpio_vbus, 0); usb_gadget_vbus_disconnect(otg->gadget); - otg->state = OTG_STATE_UNDEFINED; + otg->phy->state = OTG_STATE_UNDEFINED; otg->gadget = NULL; return 0; @@ -189,23 +190,23 @@ static int gpio_vbus_set_peripheral(struct usb_phy *otg, } /* effective for B devices, ignored for A-peripheral */ -static int gpio_vbus_set_power(struct usb_phy *otg, unsigned mA) +static int gpio_vbus_set_power(struct usb_phy *phy, unsigned mA) { struct gpio_vbus_data *gpio_vbus; - gpio_vbus = container_of(otg, struct gpio_vbus_data, otg); + gpio_vbus = container_of(phy, struct gpio_vbus_data, phy); - if (otg->state == OTG_STATE_B_PERIPHERAL) + if (phy->state == OTG_STATE_B_PERIPHERAL) set_vbus_draw(gpio_vbus, mA); return 0; } /* for non-OTG B devices: set/clear transceiver suspend mode */ -static int gpio_vbus_set_suspend(struct usb_phy *otg, int suspend) +static int gpio_vbus_set_suspend(struct usb_phy *phy, int suspend) { struct gpio_vbus_data *gpio_vbus; - gpio_vbus = container_of(otg, struct gpio_vbus_data, otg); + gpio_vbus = container_of(phy, struct gpio_vbus_data, phy); /* draw max 0 mA from vbus in suspend mode; or the previously * recorded amount of current if not suspended @@ -213,7 +214,7 @@ static int gpio_vbus_set_suspend(struct usb_phy *otg, int suspend) * NOTE: high powered configs (mA > 100) may draw up to 2.5 mA * if they're wake-enabled ... we don't handle that yet. */ - return gpio_vbus_set_power(otg, suspend ? 0 : gpio_vbus->mA); + return gpio_vbus_set_power(phy, suspend ? 0 : gpio_vbus->mA); } /* platform driver interface */ @@ -233,13 +234,21 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) if (!gpio_vbus) return -ENOMEM; + gpio_vbus->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); + if (!gpio_vbus->phy.otg) { + kfree(gpio_vbus); + return -ENOMEM; + } + platform_set_drvdata(pdev, gpio_vbus); gpio_vbus->dev = &pdev->dev; - gpio_vbus->otg.label = "gpio-vbus"; - gpio_vbus->otg.state = OTG_STATE_UNDEFINED; - gpio_vbus->otg.set_peripheral = gpio_vbus_set_peripheral; - gpio_vbus->otg.set_power = gpio_vbus_set_power; - gpio_vbus->otg.set_suspend = gpio_vbus_set_suspend; + gpio_vbus->phy.label = "gpio-vbus"; + gpio_vbus->phy.set_power = gpio_vbus_set_power; + gpio_vbus->phy.set_suspend = gpio_vbus_set_suspend; + gpio_vbus->phy.state = OTG_STATE_UNDEFINED; + + gpio_vbus->phy.otg->phy = &gpio_vbus->phy; + gpio_vbus->phy.otg->set_peripheral = gpio_vbus_set_peripheral; err = gpio_request(gpio, "vbus_detect"); if (err) { @@ -288,7 +297,7 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) } /* only active when a gadget is registered */ - err = otg_set_transceiver(&gpio_vbus->otg); + err = usb_set_transceiver(&gpio_vbus->phy); if (err) { dev_err(&pdev->dev, "can't register transceiver, err: %d\n", err); @@ -304,6 +313,7 @@ err_irq: gpio_free(pdata->gpio_vbus); err_gpio: platform_set_drvdata(pdev, NULL); + kfree(gpio_vbus->phy.otg); kfree(gpio_vbus); return err; } @@ -316,13 +326,14 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev) regulator_put(gpio_vbus->vbus_draw); - otg_set_transceiver(NULL); + usb_set_transceiver(NULL); free_irq(gpio_to_irq(gpio), &pdev->dev); if (gpio_is_valid(pdata->gpio_pullup)) gpio_free(pdata->gpio_pullup); gpio_free(gpio); platform_set_drvdata(pdev, NULL); + kfree(gpio_vbus->phy.otg); kfree(gpio_vbus); return 0; |