diff options
author | Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com> | 2012-05-17 15:09:32 +0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-05-17 22:20:34 +0400 |
commit | 123bbceebeb1174e385eab1fc2b2535dcdcc9ec3 (patch) | |
tree | da536562050c623182c4fbc8d5fe02b3140f78c5 /drivers/usb/otg/gpio_vbus.c | |
parent | 8f9d973a0daee49e0b9b924c724b18b0170ec9cb (diff) | |
download | linux-123bbceebeb1174e385eab1fc2b2535dcdcc9ec3.tar.xz |
USB: gpio_vbus: use cached IRQ number for consistency with the probed one
gpio_vbus is designed to be able to get an IRQ number for VBUS change
interrupt either (1) through platform_get_resource(IORESOURCE_IRQ) or
(2) by processing gpio_to_irq(pdata->gpio_vbus), in probe() function.
On the other hand, gpio_vbus_set_peripheral() and gpio_vbus_remove()
are always doing gpio_to_irq(pdata->gpio_vbus) to get an IRQ number.
This is not just inconsistent, but also broken. There is no guarantee
that an IRQ number obtained by platform_get_resource() is equal to
gpio_to_irq(pdata->gpio_vbus).
Cache an IRQ number in probe() function, and use it where necessary.
Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/otg/gpio_vbus.c')
-rw-r--r-- | drivers/usb/otg/gpio_vbus.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c index bd6e755dd3d8..8853cb1fd9d7 100644 --- a/drivers/usb/otg/gpio_vbus.c +++ b/drivers/usb/otg/gpio_vbus.c @@ -39,6 +39,7 @@ struct gpio_vbus_data { unsigned mA; struct delayed_work work; int vbus; + int irq; }; @@ -173,12 +174,11 @@ static int gpio_vbus_set_peripheral(struct usb_otg *otg, struct gpio_vbus_data *gpio_vbus; struct gpio_vbus_mach_info *pdata; struct platform_device *pdev; - int gpio, irq; + int gpio; 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); gpio = pdata->gpio_pullup; if (!gadget) { @@ -203,7 +203,7 @@ static int gpio_vbus_set_peripheral(struct usb_otg *otg, /* initialize connection state */ gpio_vbus->vbus = 0; /* start with disconnected */ - gpio_vbus_irq(irq, pdev); + gpio_vbus_irq(gpio_vbus->irq, pdev); return 0; } @@ -284,6 +284,8 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) } else irq = gpio_to_irq(gpio); + gpio_vbus->irq = irq; + /* if data line pullup is in use, initialize it to "not pulling up" */ gpio = pdata->gpio_pullup; if (gpio_is_valid(gpio)) { @@ -350,7 +352,7 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev) usb_set_transceiver(NULL); - free_irq(gpio_to_irq(gpio), pdev); + free_irq(gpio_vbus->irq, pdev); if (gpio_is_valid(pdata->gpio_pullup)) gpio_free(pdata->gpio_pullup); gpio_free(gpio); |