From 62bb84ed0e4d14b0a5070f44b2387a42f7f535d9 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Tue, 8 May 2012 23:29:01 +0300 Subject: usb: gadget: ci13xxx: convert to platform device Let's break ci13xxx driver into a separate udc driver and platform drivers _pci and _msm, which will create a platform device for each pci (or msm) device found. The approach was introduced by Felipe in dwc3 driver and there seems to be no reason not to use it. msm related code is only compile-tested. Signed-off-by: Alexander Shishkin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/ci13xxx_udc.c | 78 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 4 deletions(-) (limited to 'drivers/usb/gadget/ci13xxx_udc.c') diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 3b47ca1b64ee..009a3cd5895d 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c @@ -55,6 +55,8 @@ #include #include #include +#include +#include #include #include #include @@ -67,7 +69,6 @@ #include "ci13xxx_udc.h" - /****************************************************************************** * DEFINE *****************************************************************************/ @@ -2806,7 +2807,7 @@ static int ci13xxx_stop(struct usb_gadget_driver *driver) * This function returns IRQ_HANDLED if the IRQ has been handled * It locks access to registers */ -static irqreturn_t udc_irq(void) +static irqreturn_t udc_irq(int irq, void *data) { struct ci13xxx *udc = _udc; irqreturn_t retval; @@ -2901,7 +2902,7 @@ static void udc_release(struct device *dev) * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask */ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, - void __iomem *regs, uintptr_t capoffset) + void __iomem *regs) { struct ci13xxx *udc; int retval = 0; @@ -2935,7 +2936,7 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, udc->gadget.dev.parent = dev; udc->gadget.dev.release = udc_release; - retval = hw_device_init(udc, regs, capoffset); + retval = hw_device_init(udc, regs, driver->capoffset); if (retval < 0) goto free_udc; @@ -3033,3 +3034,72 @@ static void udc_remove(void) kfree(udc); _udc = NULL; } + +static int __devinit ci_udc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ci13xxx_udc_driver *driver = dev->platform_data; + struct resource *res; + void __iomem *base; + int ret; + + if (!driver) { + dev_err(dev, "platform data missing\n"); + return -ENODEV; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "missing resource\n"); + return -ENODEV; + } + + base = devm_request_and_ioremap(dev, res); + if (!res) { + dev_err(dev, "can't request and ioremap resource\n"); + return -ENOMEM; + } + + ret = udc_probe(driver, dev, base); + if (ret) + return ret; + + _udc->irq = platform_get_irq(pdev, 0); + if (_udc->irq < 0) { + dev_err(dev, "missing IRQ\n"); + ret = -ENODEV; + goto out; + } + + ret = request_irq(_udc->irq, udc_irq, IRQF_SHARED, driver->name, _udc); + +out: + if (ret) + udc_remove(); + + return ret; +} + +static int __devexit ci_udc_remove(struct platform_device *pdev) +{ + free_irq(_udc->irq, _udc); + udc_remove(); + + return 0; +} + +static struct platform_driver ci_udc_driver = { + .probe = ci_udc_probe, + .remove = __devexit_p(ci_udc_remove), + .driver = { + .name = "ci_udc", + }, +}; + +module_platform_driver(ci_udc_driver); + +MODULE_ALIAS("platform:ci_udc"); +MODULE_ALIAS("platform:ci13xxx"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("David Lopo "); +MODULE_DESCRIPTION("ChipIdea UDC Driver"); -- cgit v1.2.1