USB: Add platform device support for the ISP1760 USB chip
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>
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index b2ceb4a..89299a5 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -19,6 +19,7 @@
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/
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index c1cfed7..845479f 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -120,7 +120,7 @@
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.
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index 4cf7ca4..3fa3a17 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -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 @@
};
#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