diff options
author | Heiko Stübner <heiko@sntech.de> | 2011-08-21 14:32:14 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-08-23 01:03:15 +0200 |
commit | 938fbe54f33e97c2911d0665ec613d7f0c967d9a (patch) | |
tree | 24248499a682ab124a9c37e90e497e901c2bc0f6 /drivers/usb/gadget/s3c-hsudc.c | |
parent | s3c-hsudc: Fix possible nullpointer dereference during probe (diff) | |
download | linux-938fbe54f33e97c2911d0665ec613d7f0c967d9a.tar.xz linux-938fbe54f33e97c2911d0665ec613d7f0c967d9a.zip |
s3c-hsudc: Add basic otg transceiver handling
Makes it possible to use i.e. gpio-vbus to handle vbus events.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/s3c-hsudc.c')
-rw-r--r-- | drivers/usb/gadget/s3c-hsudc.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 00056c27a1c8..3e96cc5bb77f 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -26,6 +26,7 @@ #include <linux/clk.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> +#include <linux/usb/otg.h> #include <linux/prefetch.h> #include <mach/regs-s3c2443-clock.h> @@ -137,6 +138,7 @@ struct s3c_hsudc { struct usb_gadget_driver *driver; struct device *dev; struct s3c24xx_hsudc_platdata *pd; + struct otg_transceiver *transceiver; spinlock_t lock; void __iomem *regs; struct resource *mem_rsrc; @@ -1171,6 +1173,22 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver, return ret; } + /* connect to bus through transceiver */ + if (hsudc->transceiver) { + ret = otg_set_peripheral(hsudc->transceiver, &hsudc->gadget); + if (ret) { + dev_err(hsudc->dev, "%s: can't bind to transceiver\n", + hsudc->gadget.name); + driver->unbind(&hsudc->gadget); + + device_del(&hsudc->gadget.dev); + + hsudc->driver = NULL; + hsudc->gadget.dev.driver = NULL; + return ret; + } + } + enable_irq(hsudc->irq); dev_info(hsudc->dev, "bound driver %s\n", driver->driver.name); @@ -1201,6 +1219,9 @@ static int s3c_hsudc_stop(struct usb_gadget_driver *driver) s3c_hsudc_stop_activity(hsudc, driver); spin_unlock_irqrestore(&hsudc->lock, flags); + if (hsudc->transceiver) + (void) otg_set_peripheral(hsudc->transceiver, NULL); + driver->unbind(&hsudc->gadget); device_del(&hsudc->gadget.dev); disable_irq(hsudc->irq); @@ -1247,6 +1268,8 @@ static int s3c_hsudc_probe(struct platform_device *pdev) hsudc->dev = dev; hsudc->pd = pdev->dev.platform_data; + hsudc->transceiver = otg_get_transceiver(); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "unable to obtain driver resource data\n"); |