USB: Add platform device support for the ISP1760 USB chip
authorCatalin Marinas <catalin.marinas@arm.com>
Tue, 10 Feb 2009 16:55:51 +0000 (16:55 +0000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 24 Mar 2009 23:20:31 +0000 (16:20 -0700)
Currently, the driver only supports PCI and PPC_OF but there are
boards like ARM RealView where this is a platform device. The patch adds
the necessary functions and registration to the isp1760-if.c file and
modifies the corresponding Makefile and Kconfig to be able to use this
driver even if PCI and PPC_OF are not enabled.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Sebastian Siewior <bigeasy@linutronix.de>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/Makefile
drivers/usb/host/Kconfig
drivers/usb/host/isp1760-if.c

index b2ceb4aff2330423150fcb48e69e637e88dca548..89299a5ce1688cbf114f2ee68993cdca6febc619 100644 (file)
@@ -19,6 +19,7 @@ obj-$(CONFIG_USB_SL811_HCD)   += host/
 obj-$(CONFIG_USB_U132_HCD)     += host/
 obj-$(CONFIG_USB_R8A66597_HCD) += host/
 obj-$(CONFIG_USB_HWA_HCD)      += host/
+obj-$(CONFIG_USB_ISP1760_HCD)  += host/
 
 obj-$(CONFIG_USB_C67X00_HCD)   += c67x00/
 
index c1cfed7eefb5969904cf638b931e9900ffb8b98a..845479f7c70773cacff061d3a04c0f3ca0b21d86 100644 (file)
@@ -120,7 +120,7 @@ config USB_ISP116X_HCD
 
 config USB_ISP1760_HCD
        tristate "ISP 1760 HCD support"
-       depends on USB && EXPERIMENTAL && (PCI || PPC_OF)
+       depends on USB && EXPERIMENTAL
        ---help---
          The ISP1760 chip is a USB 2.0 host controller.
 
index 4cf7ca428b335ce049e86e27fcaa824ea65a607b..3fa3a17027963af75a2d15d5c5da7990b7c5fc7f 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/usb.h>
 #include <linux/io.h>
+#include <linux/platform_device.h>
 
 #include "../core/hcd.h"
 #include "isp1760-hcd.h"
@@ -300,39 +301,101 @@ static struct pci_driver isp1761_pci_driver = {
 };
 #endif
 
+static int __devinit isp1760_plat_probe(struct platform_device *pdev)
+{
+       int ret = 0;
+       struct usb_hcd *hcd;
+       struct resource *mem_res;
+       struct resource *irq_res;
+       resource_size_t mem_size;
+       unsigned long irqflags = IRQF_SHARED | IRQF_DISABLED;
+
+       mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!mem_res) {
+               pr_warning("isp1760: Memory resource not available\n");
+               ret = -ENODEV;
+               goto out;
+       }
+       mem_size = resource_size(mem_res);
+       if (!request_mem_region(mem_res->start, mem_size, "isp1760")) {
+               pr_warning("isp1760: Cannot reserve the memory resource\n");
+               ret = -EBUSY;
+               goto out;
+       }
+
+       irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!irq_res) {
+               pr_warning("isp1760: IRQ resource not available\n");
+               return -ENODEV;
+       }
+       irqflags |= irq_res->flags & IRQF_TRIGGER_MASK;
+
+       hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
+                              irqflags, &pdev->dev, dev_name(&pdev->dev), 0);
+       if (IS_ERR(hcd)) {
+               pr_warning("isp1760: Failed to register the HCD device\n");
+               ret = -ENODEV;
+               goto cleanup;
+       }
+
+       pr_info("ISP1760 USB device initialised\n");
+       return ret;
+
+cleanup:
+       release_mem_region(mem_res->start, mem_size);
+out:
+       return ret;
+}
+
+static int __devexit isp1760_plat_remove(struct platform_device *pdev)
+{
+       struct resource *mem_res;
+       resource_size_t mem_size;
+
+       mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mem_size = resource_size(mem_res);
+       release_mem_region(mem_res->start, mem_size);
+
+       return 0;
+}
+
+static struct platform_driver isp1760_plat_driver = {
+       .probe  = isp1760_plat_probe,
+       .remove = isp1760_plat_remove,
+       .driver = {
+               .name   = "isp1760",
+       },
+};
+
 static int __init isp1760_init(void)
 {
-       int ret;
+       int ret, any_ret = -ENODEV;
 
        init_kmem_once();
 
+       ret = platform_driver_register(&isp1760_plat_driver);
+       if (!ret)
+               any_ret = 0;
 #ifdef CONFIG_PPC_OF
        ret = of_register_platform_driver(&isp1760_of_driver);
-       if (ret) {
-               deinit_kmem_cache();
-               return ret;
-       }
+       if (!ret)
+               any_ret = 0;
 #endif
 #ifdef CONFIG_PCI
        ret = pci_register_driver(&isp1761_pci_driver);
-       if (ret)
-               goto unreg_of;
+       if (!ret)
+               any_ret = 0;
 #endif
-       return ret;
 
-#ifdef CONFIG_PCI
-unreg_of:
-#endif
-#ifdef CONFIG_PPC_OF
-       of_unregister_platform_driver(&isp1760_of_driver);
-#endif
-       deinit_kmem_cache();
-       return ret;
+       if (any_ret)
+               deinit_kmem_cache();
+       return any_ret;
 }
 module_init(isp1760_init);
 
 static void __exit isp1760_exit(void)
 {
+       platform_driver_unregister(&isp1760_plat_driver);
 #ifdef CONFIG_PPC_OF
        of_unregister_platform_driver(&isp1760_of_driver);
 #endif