All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules
@ 2013-06-07  6:03 Manjunath Goudar
  2013-06-07  6:03 ` [RFC][PATCH 1/7] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
                   ` (14 more replies)
  0 siblings, 15 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-07  6:03 UTC (permalink / raw)
  To: linux-arm-kernel

These patches are for separating the SOC On-Chip ohci host controller 
from ohci-hcd host code into its own driver module.
This work is part of enabling multi-platform kernels on ARM.

Manjunath Goudar (7):
  USB: OHCI: make ohci-exynos a separate driver
  USB: OHCI: make ohci-omap a separate driver
  USB: OHCI: make ohci-omap3 a separate driver
  USB: OHCI: make ohci-spear a separate driver
  USB: OHCI: export ohci_hub_control and ohci_hub_status_data
  USB: OHCI: make ohci-at91 a separate driver
  USB: OHCI: make ohci-s3c2410 a separate driver

 drivers/usb/host/Kconfig        |   30 +++++++-
 drivers/usb/host/Makefile       |    6 ++
 drivers/usb/host/ohci-at91.c    |  135 +++++++++++++++-------------------
 drivers/usb/host/ohci-exynos.c  |  154 +++++++++++++++++----------------------
 drivers/usb/host/ohci-hcd.c     |  122 ++-----------------------------
 drivers/usb/host/ohci-hub.c     |    8 +-
 drivers/usb/host/ohci-omap.c    |  142 +++++++++++++-----------------------
 drivers/usb/host/ohci-omap3.c   |  122 +++++++++++--------------------
 drivers/usb/host/ohci-s3c2410.c |  116 ++++++++++++-----------------
 drivers/usb/host/ohci-spear.c   |  149 ++++++++++++++++---------------------
 drivers/usb/host/ohci.h         |    9 +++
 11 files changed, 383 insertions(+), 610 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [RFC][PATCH 1/7] USB: OHCI: make ohci-exynos a separate driver
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
@ 2013-06-07  6:03 ` Manjunath Goudar
  2013-06-07 13:49   ` Arnd Bergmann
  2013-06-07 17:20   ` Alan Stern
  2013-06-07  6:03 ` [RFC][PATCH 2/7] USB: OHCI: make ohci-omap " Manjunath Goudar
                   ` (13 subsequent siblings)
  14 siblings, 2 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-07  6:03 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  Samsung OHCI EXYNOS host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Jingoo Han <jg1.han@samsung.com>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb at vger.kernel.org
---
 drivers/usb/host/Kconfig       |    2 +-
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ohci-exynos.c |  154 +++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c    |   20 +-----
 4 files changed, 70 insertions(+), 107 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 5391a38..f827386 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -484,7 +484,7 @@ config USB_OHCI_SH
 	  If you use the PCI OHCI controller, this option is not necessary.
 
 config USB_OHCI_EXYNOS
-	boolean "OHCI support for Samsung EXYNOS SoC Series"
+	tristate "OHCI support for Samsung EXYNOS SoC Series"
 	depends on ARCH_EXYNOS
 	help
 	 Enable support for the Samsung Exynos SOC's on-chip OHCI controller.
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 8a89c3d..2a4f11f 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
+obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index 07592c0..a5f4c33 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -12,24 +12,38 @@
  */
 
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-exynos.h>
 #include <linux/usb/phy.h>
 #include <linux/usb/samsung_usb_phy.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include "ohci.h"
+
+#define DRIVER_DESC "OHCI exynos driver"
+
+static const char hcd_name[] = "ohci-exynos";
+static struct hc_driver __read_mostly exynos_ohci_hc_driver;
+
+#define to_exynos_ohci(hcd) (struct exynos_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
 
 struct exynos_ohci_hcd {
-	struct device *dev;
-	struct usb_hcd *hcd;
 	struct clk *clk;
 	struct usb_phy *phy;
 	struct usb_otg *otg;
 	struct exynos4_ohci_platdata *pdata;
 };
 
-static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_enable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
 
 	if (exynos_ohci->phy)
 		usb_phy_init(exynos_ohci->phy);
@@ -37,9 +51,9 @@ static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
 }
 
-static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_disable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
 
 	if (exynos_ohci->phy)
 		usb_phy_shutdown(exynos_ohci->phy);
@@ -47,57 +61,6 @@ static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
 }
 
-static int ohci_exynos_reset(struct usb_hcd *hcd)
-{
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-static int ohci_exynos_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci);
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-static const struct hc_driver exynos_ohci_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "EXYNOS OHCI Host Controller",
-	.hcd_priv_size		= sizeof(struct ohci_hcd),
-
-	.irq			= ohci_irq,
-	.flags			= HCD_MEMORY|HCD_USB11,
-
-	.reset			= ohci_exynos_reset,
-	.start			= ohci_exynos_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-
-	.get_frame_number	= ohci_get_frame,
-
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-	.start_port_reset	= ohci_start_port_reset,
-};
-
 static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32);
 
 static int exynos_ohci_probe(struct platform_device *pdev)
@@ -105,7 +68,6 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_ohci_hcd *exynos_ohci;
 	struct usb_hcd *hcd;
-	struct ohci_hcd *ohci;
 	struct resource *res;
 	struct usb_phy *phy;
 	int irq;
@@ -121,15 +83,18 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	if (!pdev->dev.coherent_dma_mask)
 		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
-	exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd),
-					GFP_KERNEL);
-	if (!exynos_ohci)
+	hcd = usb_create_hcd(&exynos_ohci_hc_driver,
+				&pdev->dev, dev_name(&pdev->dev));
+	if (!hcd) {
+		dev_err(&pdev->dev, "Unable to create HCD\n");
 		return -ENOMEM;
 
 	if (of_device_is_compatible(pdev->dev.of_node,
 					"samsung,exynos5440-ohci"))
 		goto skip_phy;
 
+	}
+	exynos_ohci = to_exynos_ohci(hcd);
 	phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
 	if (IS_ERR(phy)) {
 		/* Fallback to pdata */
@@ -146,7 +111,6 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 
 skip_phy:
 
-	exynos_ohci->dev = &pdev->dev;
 
 	hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
 					dev_name(&pdev->dev));
@@ -155,7 +119,6 @@ skip_phy:
 		return -ENOMEM;
 	}
 
-	exynos_ohci->hcd = hcd;
 	exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");
 
 	if (IS_ERR(exynos_ohci->clk)) {
@@ -192,13 +155,11 @@ skip_phy:
 	}
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	exynos_ohci_phy_enable(pdev);
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
+	ohci_setup(hcd);
 
 	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (err) {
@@ -206,12 +167,12 @@ skip_phy:
 		goto fail_add_hcd;
 	}
 
-	platform_set_drvdata(pdev, exynos_ohci);
+	platform_set_drvdata(pdev, hcd);
 
 	return 0;
 
 fail_add_hcd:
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 fail_io:
 	clk_disable_unprepare(exynos_ohci->clk);
 fail_clk:
@@ -221,16 +182,15 @@ fail_clk:
 
 static int exynos_ohci_remove(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	usb_remove_hcd(hcd);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -241,8 +201,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
 
 static void exynos_ohci_shutdown(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
 	if (hcd->driver->shutdown)
 		hcd->driver->shutdown(hcd);
@@ -251,9 +210,10 @@ static void exynos_ohci_shutdown(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int exynos_ohci_suspend(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	struct platform_device *pdev = to_platform_device(dev);
 	unsigned long flags;
 	int rc = 0;
 
@@ -273,10 +233,9 @@ static int exynos_ohci_suspend(struct device *dev)
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -288,16 +247,16 @@ fail:
 
 static int exynos_ohci_resume(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd			= dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci	= to_exynos_ohci(hcd);
+	struct platform_device *pdev		= to_platform_device(dev);
 
 	clk_prepare_enable(exynos_ohci->clk);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	ohci_resume(hcd, false);
 
@@ -308,6 +267,10 @@ static int exynos_ohci_resume(struct device *dev)
 #define exynos_ohci_resume	NULL
 #endif
 
+static const struct ohci_driver_overrides exynos_overrides __initconst = {
+	.extra_priv_size =	sizeof(struct exynos_ohci_hcd),
+};
+
 static const struct dev_pm_ops exynos_ohci_pm_ops = {
 	.suspend	= exynos_ohci_suspend,
 	.resume		= exynos_ohci_resume,
@@ -333,6 +296,23 @@ static struct platform_driver exynos_ohci_driver = {
 		.of_match_table	= of_match_ptr(exynos_ohci_match),
 	}
 };
+static int __init ohci_exynos_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&exynos_ohci_hc_driver, &exynos_overrides);
+	return platform_driver_register(&exynos_ohci_driver);
+}
+module_init(ohci_exynos_init);
+
+static void __exit ohci_exynos_cleanup(void)
+{
+	platform_driver_unregister(&exynos_ohci_driver);
+}
+module_exit(ohci_exynos_cleanup);
 
 MODULE_ALIAS("platform:exynos-ohci");
 MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 39c7624..14962f8 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1178,11 +1178,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_EXYNOS
-#include "ohci-exynos.c"
-#define EXYNOS_PLATFORM_DRIVER	exynos_ohci_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP1
 #include "ohci-omap.c"
 #define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
@@ -1260,6 +1255,7 @@ MODULE_LICENSE ("GPL");
 
 #if	!IS_ENABLED(CONFIG_USB_OHCI_HCD_PCI) &&	\
 	!IS_ENABLED(CONFIG_USB_OHCI_HCD_PLATFORM) && \
+	!IS_ENABLED(CONFIG_USB_OHCI_EXYNOS) && \
 	!defined(PLATFORM_DRIVER) &&	\
 	!defined(OMAP1_PLATFORM_DRIVER) &&	\
 	!defined(OMAP3_PLATFORM_DRIVER) &&	\
@@ -1269,7 +1265,6 @@ MODULE_LICENSE ("GPL");
 	!defined(SM501_OHCI_DRIVER) && \
 	!defined(TMIO_OHCI_DRIVER) && \
 	!defined(S3C2410_PLATFORM_DRIVER) && \
-	!defined(EXYNOS_PLATFORM_DRIVER) && \
 	!defined(EP93XX_PLATFORM_DRIVER) && \
 	!defined(AT91_PLATFORM_DRIVER) && \
 	!defined(NXP_PLATFORM_DRIVER) && \
@@ -1352,12 +1347,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_s3c2410;
 #endif
 
-#ifdef EXYNOS_PLATFORM_DRIVER
-	retval = platform_driver_register(&EXYNOS_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_exynos;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1411,10 +1400,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
- error_exynos:
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
  error_s3c2410:
@@ -1479,9 +1464,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [RFC][PATCH 2/7] USB: OHCI: make ohci-omap a separate driver
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
  2013-06-07  6:03 ` [RFC][PATCH 1/7] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
@ 2013-06-07  6:03 ` Manjunath Goudar
  2013-06-07 17:37   ` Alan Stern
  2013-06-07  6:03 ` [RFC][PATCH 3/7] USB: OHCI: make ohci-omap3 " Manjunath Goudar
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-07  6:03 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP1/2 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb at vger.kernel.org
---
 drivers/usb/host/Kconfig     |    2 +-
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-hcd.c  |   20 +-----
 drivers/usb/host/ohci-omap.c |  142 ++++++++++++++++--------------------------
 4 files changed, 55 insertions(+), 110 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index f827386..744673b 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -397,7 +397,7 @@ config USB_OHCI_HCD
 if USB_OHCI_HCD
 
 config USB_OHCI_HCD_OMAP1
-	bool "OHCI support for OMAP1/2 chips"
+	tristate "OHCI support for OMAP1/2 chips"
 	depends on ARCH_OMAP1
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 2a4f11f..1326df2 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 14962f8..4bfd890 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1178,11 +1178,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP1
-#include "ohci-omap.c"
-#define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP3
 #include "ohci-omap3.c"
 #define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
@@ -1256,8 +1251,8 @@ MODULE_LICENSE ("GPL");
 #if	!IS_ENABLED(CONFIG_USB_OHCI_HCD_PCI) &&	\
 	!IS_ENABLED(CONFIG_USB_OHCI_HCD_PLATFORM) && \
 	!IS_ENABLED(CONFIG_USB_OHCI_EXYNOS) && \
+	!IS_ENABLED(CONFIG_USB_OHCI_HCD_OMAP1) && \
 	!defined(PLATFORM_DRIVER) &&	\
-	!defined(OMAP1_PLATFORM_DRIVER) &&	\
 	!defined(OMAP3_PLATFORM_DRIVER) &&	\
 	!defined(OF_PLATFORM_DRIVER) &&	\
 	!defined(SA1111_DRIVER) &&	\
@@ -1305,12 +1300,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP1_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP1_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap1_platform;
-#endif
-
 #ifdef OMAP3_PLATFORM_DRIVER
 	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1424,10 +1413,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
  error_omap3_platform:
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
- error_omap1_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1482,9 +1467,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OMAP3_PLATFORM_DRIVER
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 8747fa6..eee4b72 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -14,12 +14,21 @@
  * This file is licenced under the GPL.
  */
 
-#include <linux/signal.h>
-#include <linux/jiffies.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
 #include <asm/io.h>
 #include <asm/mach-types.h>
@@ -42,10 +51,7 @@
 #define OMAP1510_LB_MMU_RAM_H	0xfffec234
 #define OMAP1510_LB_MMU_RAM_L	0xfffec238
 
-
-#ifndef CONFIG_ARCH_OMAP
-#error "This file is OMAP bus glue.  CONFIG_OMAP must be defined."
-#endif
+#define DRIVER_DESC "OHCI OMAP driver"
 
 #ifdef CONFIG_TPS65010
 #include <linux/i2c/tps65010.h>
@@ -71,6 +77,10 @@ static struct clk *usb_dc_ck;
 static int host_enabled;
 static int host_initialized;
 
+static const char hcd_name[] = "ohci-omap";
+static struct hc_driver __read_mostly ohci_omap_hc_driver;
+
+
 static void omap_ohci_clock_power(int on)
 {
 	if (on) {
@@ -188,7 +198,7 @@ static void start_hnp(struct ohci_hcd *ohci)
 
 /*-------------------------------------------------------------------------*/
 
-static int ohci_omap_init(struct usb_hcd *hcd)
+static int ohci_omap_reset(struct usb_hcd *hcd)
 {
 	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
 	struct omap_usb_config	*config = hcd->self.controller->platform_data;
@@ -201,8 +211,14 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 		ohci_to_hcd(ohci)->self.otg_port = config->otg;
 		/* default/minimum OTG power budget:  8 mA */
 		ohci_to_hcd(ohci)->power_budget = 8;
+		ohci->hc_control = OHCI_CTRL_RWC;
+		writel(OHCI_CTRL_RWC, &ohci->regs->control);
 	}
 
+	if (config->rwc) {
+		ohci->hc_control = OHCI_CTRL_RWC;
+		writel(OHCI_CTRL_RWC, &ohci->regs->control);
+	}
 	/* boards can use OTG transceivers in non-OTG modes */
 	need_transceiver = need_transceiver
 			|| machine_is_omap_h2() || machine_is_omap_h3();
@@ -238,7 +254,8 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 		omap_1510_local_bus_init();
 	}
 
-	if ((ret = ohci_init(ohci)) < 0)
+	ret = ohci_setup(hcd);
+	if (ret < 0)
 		return ret;
 
 	/* board-specific power switching and overcurrent support */
@@ -281,14 +298,6 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	return 0;
 }
 
-static void ohci_omap_stop(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
-	ohci_stop(hcd);
-	omap_ohci_clock_power(0);
-}
-
-
 /*-------------------------------------------------------------------------*/
 
 /**
@@ -304,7 +313,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 {
 	int retval, irq;
 	struct usb_hcd *hcd = 0;
-	struct ohci_hcd *ohci;
 
 	if (pdev->num_resources != 2) {
 		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
@@ -354,8 +362,7 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 		goto err2;
 	}
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
+	ohci_setup(hcd);
 
 	host_initialized = 0;
 	host_enabled = 1;
@@ -418,76 +425,6 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_omap_start (struct usb_hcd *hcd)
-{
-	struct omap_usb_config *config;
-	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ret;
-
-	if (!host_enabled)
-		return 0;
-	config = hcd->self.controller->platform_data;
-	if (config->otg || config->rwc) {
-		ohci->hc_control = OHCI_CTRL_RWC;
-		writel(OHCI_CTRL_RWC, &ohci->regs->control);
-	}
-
-	if ((ret = ohci_run (ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop (hcd);
-		return ret;
-	}
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_omap_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap_init,
-	.start =		ohci_omap_start,
-	.stop =			ohci_omap_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static int ohci_hcd_omap_drv_probe(struct platform_device *dev)
 {
 	return usb_hcd_omap_probe(&ohci_omap_hc_driver, dev);
@@ -553,4 +490,29 @@ static struct platform_driver ohci_hcd_omap_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides omap_overrides __initconst = {
+	.product_desc	= "OMAP OHCI",
+	.reset		= ohci_omap_reset
+};
+
+static int __init ohci_omap_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap_hc_driver, &omap_overrides);
+	return platform_driver_register(&ohci_hcd_omap_driver);
+}
+module_init(ohci_omap_init);
+
+static void __exit ohci_omap_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap_driver);
+}
+module_exit(ohci_omap_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [RFC][PATCH 3/7] USB: OHCI: make ohci-omap3 a separate driver
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
  2013-06-07  6:03 ` [RFC][PATCH 1/7] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
  2013-06-07  6:03 ` [RFC][PATCH 2/7] USB: OHCI: make ohci-omap " Manjunath Goudar
@ 2013-06-07  6:03 ` Manjunath Goudar
  2013-06-07 13:51   ` Arnd Bergmann
  2013-06-07 17:49   ` Alan Stern
  2013-06-07  6:03 ` [RFC][PATCH 4/7] USB: OHCI: make ohci-spear " Manjunath Goudar
                   ` (11 subsequent siblings)
  14 siblings, 2 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-07  6:03 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP3 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Anand Gadiyar <gadiyar@ti.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb at vger.kernel.org
---
 drivers/usb/host/Kconfig      |    2 +-
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   20 +------
 drivers/usb/host/ohci-omap3.c |  122 ++++++++++++++---------------------------
 4 files changed, 45 insertions(+), 100 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 744673b..f42db93 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -404,7 +404,7 @@ config USB_OHCI_HCD_OMAP1
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
 config USB_OHCI_HCD_OMAP3
-	bool "OHCI support for OMAP3 and later chips"
+	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 1326df2..ceb4e55 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 4bfd890..8002bbe 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1178,11 +1178,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP3
-#include "ohci-omap3.c"
-#define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1252,8 +1247,8 @@ MODULE_LICENSE ("GPL");
 	!IS_ENABLED(CONFIG_USB_OHCI_HCD_PLATFORM) && \
 	!IS_ENABLED(CONFIG_USB_OHCI_EXYNOS) && \
 	!IS_ENABLED(CONFIG_USB_OHCI_HCD_OMAP1) && \
+	!IS_ENABLED(CONFIG_USB_OHCI_HCD_OMAP3) && \
 	!defined(PLATFORM_DRIVER) &&	\
-	!defined(OMAP3_PLATFORM_DRIVER) &&	\
 	!defined(OF_PLATFORM_DRIVER) &&	\
 	!defined(SA1111_DRIVER) &&	\
 	!defined(PS3_SYSTEM_BUS_DRIVER) && \
@@ -1300,12 +1295,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP3_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap3_platform;
-#endif
-
 #ifdef OF_PLATFORM_DRIVER
 	retval = platform_driver_register(&OF_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1409,10 +1398,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
  error_of_platform:
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
- error_omap3_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1464,9 +1449,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OF_PLATFORM_DRIVER
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index 08e811d..1d30bc8 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -29,90 +29,22 @@
  *	- add kernel-doc
  */
 
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/of.h>
-#include <linux/dma-mapping.h>
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_init(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "starting OHCI controller\n");
-
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	/*
-	 * RemoteWakeupConnected has to be set explicitly before
-	 * calling ohci_run. The reset value of RWC is 0.
-	 */
-	ohci->hc_control = OHCI_CTRL_RWC;
-	writel(OHCI_CTRL_RWC, &ohci->regs->control);
-
-	ret = ohci_run(ohci);
-
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-	}
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
-	return ret;
-}
+#include "ohci.h"
 
-/*-------------------------------------------------------------------------*/
+#define DRIVER_DESC "OHCI OMAP3 driver"
 
-static const struct hc_driver ohci_omap3_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP3 OHCI Host Controller",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap3_init,
-	.start =		ohci_omap3_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
+static const char hcd_name[] = "ohci-omap3";
+static struct hc_driver __read_mostly ohci_omap3_hc_driver;
 
 static u64 omap_ohci_dma_mask = DMA_BIT_MASK(32);
 
@@ -131,6 +63,7 @@ static u64 omap_ohci_dma_mask = DMA_BIT_MASK(32);
 static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 {
 	struct device		*dev = &pdev->dev;
+	struct ohci_hcd		*ohci;
 	struct usb_hcd		*hcd = NULL;
 	void __iomem		*regs = NULL;
 	struct resource		*res;
@@ -185,7 +118,16 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	ohci = hcd_to_ohci(hcd);
+	/*
+	* RemoteWakeupConnected has to be set explicitly before
+	* calling ohci_run. The reset value of RWC is 0.
+	*/
+	ohci->hc_control = OHCI_CTRL_RWC;
+	writel(OHCI_CTRL_RWC, &ohci->regs->control);
+	dev_dbg(hcd->self.controller, "starting OHCI controller\n");
+
+	ohci_setup(hcd);
 
 	ret = usb_add_hcd(hcd, irq, 0);
 	if (ret) {
@@ -256,5 +198,25 @@ static struct platform_driver ohci_hcd_omap3_driver = {
 	},
 };
 
+static int __init ohci_omap3_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap3_hc_driver, NULL);
+	return platform_driver_register(&ohci_hcd_omap3_driver);
+}
+module_init(ohci_omap3_init);
+
+static void __exit ohci_omap3_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap3_driver);
+}
+module_exit(ohci_omap3_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci-omap3");
 MODULE_AUTHOR("Anand Gadiyar <gadiyar@ti.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [RFC][PATCH 4/7] USB: OHCI: make ohci-spear a separate driver
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (2 preceding siblings ...)
  2013-06-07  6:03 ` [RFC][PATCH 3/7] USB: OHCI: make ohci-omap3 " Manjunath Goudar
@ 2013-06-07  6:03 ` Manjunath Goudar
  2013-06-07 10:30   ` Viresh Kumar
  2013-06-07 18:34   ` Alan Stern
  2013-06-07  6:03 ` [RFC][PATCH 5/7] USB: OHCI: export ohci_hub_control and ohci_hub_status_data Manjunath Goudar
                   ` (10 subsequent siblings)
  14 siblings, 2 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-07  6:03 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI SPEAr host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb at vger.kernel.org
---
 drivers/usb/host/Kconfig      |    8 +++
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   22 +-----
 drivers/usb/host/ohci-spear.c |  149 ++++++++++++++++++-----------------------
 4 files changed, 75 insertions(+), 105 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index f42db93..c347cb3 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -403,6 +403,14 @@ config USB_OHCI_HCD_OMAP1
 	---help---
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
+config USB_OHCI_HCD_SPEAR
+        tristate "Support for ST SPEAr on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && PLAT_SPEAR
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          ST SPEAr chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index ceb4e55..1e0d83e 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
+obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 8002bbe..27f0abe 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1208,11 +1208,6 @@ MODULE_LICENSE ("GPL");
 #define OF_PLATFORM_DRIVER	ohci_hcd_ppc_of_driver
 #endif
 
-#ifdef CONFIG_PLAT_SPEAR
-#include "ohci-spear.c"
-#define SPEAR_PLATFORM_DRIVER	spear_ohci_hcd_driver
-#endif
-
 #ifdef CONFIG_PPC_PS3
 #include "ohci-ps3.c"
 #define PS3_SYSTEM_BUS_DRIVER	ps3_ohci_driver
@@ -1248,6 +1243,7 @@ MODULE_LICENSE ("GPL");
 	!IS_ENABLED(CONFIG_USB_OHCI_EXYNOS) && \
 	!IS_ENABLED(CONFIG_USB_OHCI_HCD_OMAP1) && \
 	!IS_ENABLED(CONFIG_USB_OHCI_HCD_OMAP3) && \
+	!IS_ENABLED(CONFIG_USB_OHCI_HCD_SPEAR) && \
 	!defined(PLATFORM_DRIVER) &&	\
 	!defined(OF_PLATFORM_DRIVER) &&	\
 	!defined(SA1111_DRIVER) &&	\
@@ -1258,8 +1254,7 @@ MODULE_LICENSE ("GPL");
 	!defined(EP93XX_PLATFORM_DRIVER) && \
 	!defined(AT91_PLATFORM_DRIVER) && \
 	!defined(NXP_PLATFORM_DRIVER) && \
-	!defined(DAVINCI_PLATFORM_DRIVER) && \
-	!defined(SPEAR_PLATFORM_DRIVER)
+	!defined(DAVINCI_PLATFORM_DRIVER)
 #error "missing bus glue for ohci-hcd"
 #endif
 
@@ -1349,19 +1344,9 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_davinci;
 #endif
 
-#ifdef SPEAR_PLATFORM_DRIVER
-	retval = platform_driver_register(&SPEAR_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_spear;
-#endif
-
 	return retval;
 
 	/* Error path */
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
- error_spear:
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
  error_davinci:
@@ -1419,9 +1404,6 @@ module_init(ohci_hcd_mod_init);
 
 static void __exit ohci_hcd_mod_exit(void)
 {
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index 6a7cb14..9e79d24 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -11,94 +11,41 @@
 * warranty of any kind, whether express or implied.
 */
 
-#include <linux/signal.h>
-#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 #include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/debugfs.h>
+#include <linux/errno.h>
 
-struct spear_ohci {
-	struct ohci_hcd ohci;
-	struct clk *clk;
-};
-
-#define to_spear_ohci(hcd)	(struct spear_ohci *)hcd_to_ohci(hcd)
-
-static void spear_start_ohci(struct spear_ohci *ohci)
-{
-	clk_prepare_enable(ohci->clk);
-}
-
-static void spear_stop_ohci(struct spear_ohci *ohci)
-{
-	clk_disable_unprepare(ohci->clk);
-}
-
-static int ohci_spear_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-	ohci->regs = hcd->regs;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	create_debug_files(ohci);
-
-#ifdef DEBUG
-	ohci_dump(ohci, 1);
-#endif
-	return 0;
-}
-
-static const struct hc_driver ohci_spear_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "SPEAr OHCI",
-	.hcd_priv_size		= sizeof(struct spear_ohci),
-
-	/* generic hardware linkage */
-	.irq			= ohci_irq,
-	.flags			= HCD_USB11 | HCD_MEMORY,
-
-	/* basic lifecycle operations */
-	.start			= ohci_spear_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-
-	/* managing i/o requests and associated device resources */
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
 
-	/* scheduling support */
-	.get_frame_number	= ohci_get_frame,
+#include "ohci.h"
 
-	/* root hub support */
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
+#define DRIVER_DESC "OHCI SPEAr driver"
 
-	.start_port_reset	= ohci_start_port_reset,
+static const char hcd_name[] = "SPEAr-ohci";
+struct spear_ohci {
+	struct clk *clk;
 };
 
+#define to_spear_ohci(hcd)     (struct spear_ohci *)(hcd_to_ohci(hcd)->priv)
+
+static struct hc_driver __read_mostly ohci_spear_hc_driver;
 static u64 spear_ohci_dma_mask = DMA_BIT_MASK(32);
 
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
 	const struct hc_driver *driver = &ohci_spear_hc_driver;
+	struct ohci_hcd *ohci;
 	struct usb_hcd *hcd = NULL;
 	struct clk *usbh_clk;
-	struct spear_ohci *ohci_p;
+	struct spear_ohci *sohci_p;
 	struct resource *res;
 	int retval, irq;
 
@@ -151,16 +98,24 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 		goto err_put_hcd;
 	}
 
-	ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
-	ohci_p->clk = usbh_clk;
-	spear_start_ohci(ohci_p);
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	sohci_p = to_spear_ohci(hcd);
+	sohci_p->clk = usbh_clk;
+	hcd_to_ohci(hcd)->regs = hcd->regs;
+
+	ohci_setup(hcd);
+	clk_prepare_enable(sohci_p->clk);
+
+	ohci = hcd_to_ohci(hcd);
+
+#ifdef DEBUG
+	ohci_dump(ohci, 1);
+#endif
 
 	retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0);
 	if (retval == 0)
 		return retval;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
 err_put_hcd:
 	usb_put_hcd(hcd);
 fail:
@@ -172,11 +127,11 @@ fail:
 static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	usb_remove_hcd(hcd);
-	if (ohci_p->clk)
-		spear_stop_ohci(ohci_p);
+	if (sohci_p->clk)
+		clk_disable_unprepare(sohci_p->clk);
 
 	usb_put_hcd(hcd);
 	return 0;
@@ -188,13 +143,13 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
 	return 0;
 }
 
@@ -202,13 +157,13 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_start_ohci(ohci_p);
+	 clk_prepare_enable(sohci_p->clk);
 	ohci_resume(hcd, false);
 	return 0;
 }
@@ -234,4 +189,28 @@ static struct platform_driver spear_ohci_hcd_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides spear_overrides __initconst = {
+	.extra_priv_size = sizeof(struct spear_ohci),
+};
+static int __init ohci_spear_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_spear_hc_driver, &spear_overrides);
+	return platform_driver_register(&spear_ohci_hcd_driver);
+}
+module_init(ohci_spear_init);
+
+static void __exit ohci_spear_cleanup(void)
+{
+	platform_driver_unregister(&spear_ohci_hcd_driver);
+}
+module_exit(ohci_spear_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Deepak Sikri");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:spear-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [RFC][PATCH 5/7] USB: OHCI: export ohci_hub_control and ohci_hub_status_data
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (3 preceding siblings ...)
  2013-06-07  6:03 ` [RFC][PATCH 4/7] USB: OHCI: make ohci-spear " Manjunath Goudar
@ 2013-06-07  6:03 ` Manjunath Goudar
  2013-06-07 18:42   ` Alan Stern
  2013-06-07  6:03 ` [RFC][PATCH 6/7] USB: OHCI: make ohci-at91 a separate driver Manjunath Goudar
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-07  6:03 UTC (permalink / raw)
  To: linux-arm-kernel

In order to make ohci-at91 and ohci-s3c2410 as a separate driver,
ohci_hub_control and ohci_hub_status_data symbol needs to be exported.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org
---
 drivers/usb/host/ohci-hub.c |    8 ++++----
 drivers/usb/host/ohci.h     |    9 +++++++++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 2347ab8..c601e70 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -437,8 +437,7 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
 
 /* build "status change" packet (one or two bytes) from HC registers */
 
-static int
-ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
+int ohci_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
 	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
 	int		i, changed = 0, length = 1;
@@ -503,6 +502,7 @@ done:
 
 	return changed ? length : 0;
 }
+EXPORT_SYMBOL_GPL(ohci_hub_status_data);
 
 /*-------------------------------------------------------------------------*/
 
@@ -645,7 +645,7 @@ static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port)
 	return 0;
 }
 
-static int ohci_hub_control (
+int ohci_hub_control(
 	struct usb_hcd	*hcd,
 	u16		typeReq,
 	u16		wValue,
@@ -773,4 +773,4 @@ error:
 	}
 	return retval;
 }
-
+EXPORT_SYMBOL_GPL(ohci_hub_control);
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index e2e5faa..d0d9b60 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -738,3 +738,12 @@ extern int	ohci_setup(struct usb_hcd *hcd);
 extern int	ohci_suspend(struct usb_hcd *hcd, bool do_wakeup);
 extern int	ohci_resume(struct usb_hcd *hcd, bool hibernated);
 #endif
+extern int ohci_hub_control(
+		struct usb_hcd  *hcd,
+		u16		typeReq,
+		u16		wValue,
+		u16		wIndex,
+		char            *buf,
+		u16		wLength
+);
+extern int ohci_hub_status_data(struct usb_hcd *hcd, char *buf);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [RFC][PATCH 6/7] USB: OHCI: make ohci-at91 a separate driver
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (4 preceding siblings ...)
  2013-06-07  6:03 ` [RFC][PATCH 5/7] USB: OHCI: export ohci_hub_control and ohci_hub_status_data Manjunath Goudar
@ 2013-06-07  6:03 ` Manjunath Goudar
  2013-06-07 18:52   ` Alan Stern
  2013-06-07  6:03 ` [RFC][PATCH 7/7] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-07  6:03 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI Atmel host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org
---
 drivers/usb/host/Kconfig     |    8 +++
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-at91.c |  135 ++++++++++++++++++------------------------
 drivers/usb/host/ohci-hcd.c  |   20 +------
 4 files changed, 67 insertions(+), 97 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index c347cb3..0aabd84 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -411,6 +411,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_AT91
+        tristate  "Support for Atmel on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && ARCH_AT91
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          Atmel chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 1e0d83e..746ffc7 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
+obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index a0cb44f..b4a88a6 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -13,16 +13,25 @@
  */
 
 #include <linux/clk.h>
-#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/atmel.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
 #include <mach/hardware.h>
 #include <asm/gpio.h>
 
 #include <mach/cpu.h>
 
+
+#include "ohci.h"
+
 #ifndef CONFIG_ARCH_AT91
 #error "CONFIG_ARCH_AT91 must be defined."
 #endif
@@ -32,6 +41,12 @@
 		for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++)
 
 /* interface and function clocks; sometimes also an AHB clock */
+
+#define DRIVER_DESC "OHCI Atmel driver"
+
+static const char hcd_name[] = "ohci-atmel";
+
+static struct hc_driver __read_mostly ohci_at91_hc_driver;
 static struct clk *iclk, *fclk, *hclk;
 static int clocked;
 
@@ -111,6 +126,8 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
 static int usb_hcd_at91_probe(const struct hc_driver *driver,
 			struct platform_device *pdev)
 {
+	struct at91_usbh_data	*board;
+	struct ohci_hcd	*ohci;
 	int retval;
 	struct usb_hcd *hcd = NULL;
 
@@ -163,8 +180,11 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
 		goto err5;
 	}
 
+	board = hcd->self.controller->platform_data;
+	ohci = hcd_to_ohci(hcd);
+	ohci->num_ports = board->ports;
 	at91_start_hc(pdev);
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	ohci_setup(hcd);
 
 	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
 	if (retval == 0)
@@ -221,36 +241,6 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd,
 }
 
 /*-------------------------------------------------------------------------*/
-
-static int
-ohci_at91_reset (struct usb_hcd *hcd)
-{
-	struct at91_usbh_data	*board = hcd->self.controller->platform_data;
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
-	ohci->num_ports = board->ports;
-	return 0;
-}
-
-static int
-ohci_at91_start (struct usb_hcd *hcd)
-{
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_run(ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-	return 0;
-}
-
 static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
 {
 	if (!valid_port(port))
@@ -413,51 +403,6 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 /*-------------------------------------------------------------------------*/
 
-static const struct hc_driver ohci_at91_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"AT91 OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_at91_reset,
-	.start =		ohci_at91_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_at91_hub_status_data,
-	.hub_control =		ohci_at91_hub_control,
-#ifdef CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
 {
 	struct platform_device *pdev = data;
@@ -686,7 +631,7 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
 	 * REVISIT: some boards will be able to turn VBUS off...
 	 */
 	if (at91_suspend_entering_slow_clock()) {
-		ohci_usb_reset (ohci);
+		ohci_restart(ohci);
 		/* flush the writes */
 		(void) ohci_readl (ohci, &ohci->regs->control);
 		at91_stop_clock();
@@ -727,3 +672,37 @@ static struct platform_driver ohci_hcd_at91_driver = {
 		.of_match_table	= of_match_ptr(at91_ohci_dt_ids),
 	},
 };
+
+static int __init ohci_at91_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_at91_hc_driver, NULL);
+
+	/*
+	* The Atmel HW has some unusual quirks, which require Atmel-specific
+	* workarounds. We override certain hc_driver functions here to
+	* achieve that. We explicitly do not enhance ohci_driver_overrides to
+	* allow this more easily, since this is an unusual case, and we don't
+	* want to encourage others to override these functions by making it
+	* too easy.
+	*/
+
+	ohci_at91_hc_driver.hub_status_data	= ohci_at91_hub_status_data;
+	ohci_at91_hc_driver.hub_control		= ohci_at91_hub_control;
+
+	return platform_driver_register(&ohci_hcd_at91_driver);
+}
+module_init(ohci_at91_init);
+
+static void __exit ohci_at91_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_at91_driver);
+}
+module_exit(ohci_at91_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 27f0abe..00409b9 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1188,11 +1188,6 @@ MODULE_LICENSE ("GPL");
 #define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver
 #endif
 
-#ifdef CONFIG_ARCH_AT91
-#include "ohci-at91.c"
-#define AT91_PLATFORM_DRIVER	ohci_hcd_at91_driver
-#endif
-
 #ifdef CONFIG_ARCH_LPC32XX
 #include "ohci-nxp.c"
 #define NXP_PLATFORM_DRIVER	usb_hcd_nxp_driver
@@ -1244,6 +1239,7 @@ MODULE_LICENSE ("GPL");
 	!IS_ENABLED(CONFIG_USB_OHCI_HCD_OMAP1) && \
 	!IS_ENABLED(CONFIG_USB_OHCI_HCD_OMAP3) && \
 	!IS_ENABLED(CONFIG_USB_OHCI_HCD_SPEAR) && \
+	!IS_ENABLED(CONFIG_USB_OHCI_HCD_AT91) && \
 	!defined(PLATFORM_DRIVER) &&	\
 	!defined(OF_PLATFORM_DRIVER) &&	\
 	!defined(SA1111_DRIVER) &&	\
@@ -1252,7 +1248,6 @@ MODULE_LICENSE ("GPL");
 	!defined(TMIO_OHCI_DRIVER) && \
 	!defined(S3C2410_PLATFORM_DRIVER) && \
 	!defined(EP93XX_PLATFORM_DRIVER) && \
-	!defined(AT91_PLATFORM_DRIVER) && \
 	!defined(NXP_PLATFORM_DRIVER) && \
 	!defined(DAVINCI_PLATFORM_DRIVER)
 #error "missing bus glue for ohci-hcd"
@@ -1326,12 +1321,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_ep93xx;
 #endif
 
-#ifdef AT91_PLATFORM_DRIVER
-	retval = platform_driver_register(&AT91_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_at91;
-#endif
-
 #ifdef NXP_PLATFORM_DRIVER
 	retval = platform_driver_register(&NXP_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1355,10 +1344,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
  error_nxp:
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
- error_at91:
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
@@ -1410,9 +1395,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef NXP_PLATFORM_DRIVER
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [RFC][PATCH 7/7] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (5 preceding siblings ...)
  2013-06-07  6:03 ` [RFC][PATCH 6/7] USB: OHCI: make ohci-at91 a separate driver Manjunath Goudar
@ 2013-06-07  6:03 ` Manjunath Goudar
  2013-06-07 13:56   ` Arnd Bergmann
  2013-06-07 18:54   ` Alan Stern
  2013-06-12 15:53 ` [PATCH V2 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (7 subsequent siblings)
  14 siblings, 2 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-07  6:03 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the Samsung OHCI S3CXXXX host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org
---
 drivers/usb/host/Kconfig        |    8 +++
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ohci-hcd.c     |   20 +------
 drivers/usb/host/ohci-s3c2410.c |  116 ++++++++++++++++-----------------------
 4 files changed, 58 insertions(+), 87 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 0aabd84..a863c60 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -411,6 +411,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_S3CXXXX
+        tristate "Support for S3CXXXX on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && (ARCH_S3C24XX) || (ARCH_S3C64XX)
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          S3CXXXX chips.
+
 config USB_OHCI_HCD_AT91
         tristate  "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 746ffc7..4290701 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
+obj-$(CONFIG_USB_OHCI_HCD_S3CXXXX)	+= ohci-s3c2410.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 00409b9..8e5d979 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1173,11 +1173,6 @@ MODULE_LICENSE ("GPL");
 #define SA1111_DRIVER		ohci_hcd_sa1111_driver
 #endif
 
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
-#include "ohci-s3c2410.c"
-#define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1240,13 +1235,13 @@ MODULE_LICENSE ("GPL");
 	!IS_ENABLED(CONFIG_USB_OHCI_HCD_OMAP3) && \
 	!IS_ENABLED(CONFIG_USB_OHCI_HCD_SPEAR) && \
 	!IS_ENABLED(CONFIG_USB_OHCI_HCD_AT91) && \
+	!IS_ENABLED(CONFIG_USB_OHCI_HCD_S3CXXXX) && \
 	!defined(PLATFORM_DRIVER) &&	\
 	!defined(OF_PLATFORM_DRIVER) &&	\
 	!defined(SA1111_DRIVER) &&	\
 	!defined(PS3_SYSTEM_BUS_DRIVER) && \
 	!defined(SM501_OHCI_DRIVER) && \
 	!defined(TMIO_OHCI_DRIVER) && \
-	!defined(S3C2410_PLATFORM_DRIVER) && \
 	!defined(EP93XX_PLATFORM_DRIVER) && \
 	!defined(NXP_PLATFORM_DRIVER) && \
 	!defined(DAVINCI_PLATFORM_DRIVER)
@@ -1309,12 +1304,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_tmio;
 #endif
 
-#ifdef S3C2410_PLATFORM_DRIVER
-	retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_s3c2410;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1348,10 +1337,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
- error_s3c2410:
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
  error_tmio:
@@ -1398,9 +1383,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index e125770..14843d2 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -19,14 +19,27 @@
  * This file is licenced under the GPL.
 */
 
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
+
 
 #define valid_port(idx) ((idx) == 1 || (idx) == 2)
 
 /* clock device associated with the hcd */
 
+
+#define DRIVER_DESC "OHCI S3CXXXX driver"
+
+static const char hcd_name[] = "ohci-s3cxxxx";
+
 static struct clk *clk;
 static struct clk *usb_clk;
 
@@ -371,10 +384,9 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 		goto err_put;
 	}
 
+	ohci_setup(hcd);
 	s3c2410_start_hc(dev, hcd);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
-
 	retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
 	if (retval != 0)
 		goto err_ioremap;
@@ -391,71 +403,7 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_s3c2410_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-
-static const struct hc_driver ohci_s3c2410_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"S3C24XX OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.start =		ohci_s3c2410_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_s3c2410_hub_status_data,
-	.hub_control =		ohci_s3c2410_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/* device driver */
+static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;
 
 static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
 {
@@ -532,4 +480,36 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {
 	},
 };
 
+static int __init ohci_s3cxxxx_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
+
+	/*
+	* The Samsung HW has some unusual quirks, which require Sumsung-specific
+	* workarounds. We override certain hc_driver functions here to
+	* achieve that. We explicitly do not enhance ohci_driver_overrides to
+	* allow this more easily, since this is an unusual case, and we don't
+	* want to encourage others to override these functions by making it
+	* too easy.
+	*/
+
+	ohci_s3c2410_hc_driver.hub_status_data	= ohci_s3c2410_hub_status_data;
+	ohci_s3c2410_hc_driver.hub_control	= ohci_s3c2410_hub_control;
+
+	return platform_driver_register(&ohci_hcd_s3c2410_driver);
+}
+module_init(ohci_s3cxxxx_init);
+
+static void __exit ohci_s3cxxxx_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_s3c2410_driver);
+}
+module_exit(ohci_s3cxxxx_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:s3c2410-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [RFC][PATCH 4/7] USB: OHCI: make ohci-spear a separate driver
  2013-06-07  6:03 ` [RFC][PATCH 4/7] USB: OHCI: make ohci-spear " Manjunath Goudar
@ 2013-06-07 10:30   ` Viresh Kumar
  2013-06-07 18:34   ` Alan Stern
  1 sibling, 0 replies; 110+ messages in thread
From: Viresh Kumar @ 2013-06-07 10:30 UTC (permalink / raw)
  To: linux-arm-kernel

you need to cc spear-devel at list.st.com list for SPEAr patches.

On 7 June 2013 11:33, Manjunath Goudar <manjunath.goudar@linaro.org> wrote:
> Separate the  TI OHCI SPEAr host controller driver from ohci-hcd

TI ??

> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM.
>
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Cc: Viresh Kumar <viresh.linux@gmail.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Greg KH <greg@kroah.com>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: linux-usb at vger.kernel.org
> ---
>  drivers/usb/host/Kconfig      |    8 +++
>  drivers/usb/host/Makefile     |    1 +
>  drivers/usb/host/ohci-hcd.c   |   22 +-----
>  drivers/usb/host/ohci-spear.c |  149 ++++++++++++++++++-----------------------
>  4 files changed, 75 insertions(+), 105 deletions(-)
>
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index f42db93..c347cb3 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -403,6 +403,14 @@ config USB_OHCI_HCD_OMAP1
>         ---help---
>           Enables support for the OHCI controller on OMAP1/2 chips.
>
> +config USB_OHCI_HCD_SPEAR
> +        tristate "Support for ST SPEAr on-chip OHCI USB controller"
> +        depends on USB_OHCI_HCD && PLAT_SPEAR
> +        default y
> +        ---help---
> +          Enables support for the on-chip OHCI controller on
> +          ST SPEAr chips.
> +
>  config USB_OHCI_HCD_OMAP3
>         tristate "OHCI support for OMAP3 and later chips"
>         depends on (ARCH_OMAP3 || ARCH_OMAP4)
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index ceb4e55..1e0d83e 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -49,6 +49,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)   += ohci-platform.o
>  obj-$(CONFIG_USB_OHCI_EXYNOS)  += ohci-exynos.o
>  obj-$(CONFIG_USB_OHCI_HCD_OMAP1)       += ohci-omap.o
>  obj-$(CONFIG_USB_OHCI_HCD_OMAP3)       += ohci-omap3.o
> +obj-$(CONFIG_USB_OHCI_HCD_SPEAR)       += ohci-spear.o
>
>  obj-$(CONFIG_USB_UHCI_HCD)     += uhci-hcd.o
>  obj-$(CONFIG_USB_FHCI_HCD)     += fhci.o
> diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
> index 8002bbe..27f0abe 100644
> --- a/drivers/usb/host/ohci-hcd.c
> +++ b/drivers/usb/host/ohci-hcd.c
> @@ -1208,11 +1208,6 @@ MODULE_LICENSE ("GPL");
>  #define OF_PLATFORM_DRIVER     ohci_hcd_ppc_of_driver
>  #endif
>
> -#ifdef CONFIG_PLAT_SPEAR
> -#include "ohci-spear.c"
> -#define SPEAR_PLATFORM_DRIVER  spear_ohci_hcd_driver
> -#endif
> -
>  #ifdef CONFIG_PPC_PS3
>  #include "ohci-ps3.c"
>  #define PS3_SYSTEM_BUS_DRIVER  ps3_ohci_driver
> @@ -1248,6 +1243,7 @@ MODULE_LICENSE ("GPL");
>         !IS_ENABLED(CONFIG_USB_OHCI_EXYNOS) && \
>         !IS_ENABLED(CONFIG_USB_OHCI_HCD_OMAP1) && \
>         !IS_ENABLED(CONFIG_USB_OHCI_HCD_OMAP3) && \
> +       !IS_ENABLED(CONFIG_USB_OHCI_HCD_SPEAR) && \
>         !defined(PLATFORM_DRIVER) &&    \
>         !defined(OF_PLATFORM_DRIVER) && \
>         !defined(SA1111_DRIVER) &&      \
> @@ -1258,8 +1254,7 @@ MODULE_LICENSE ("GPL");
>         !defined(EP93XX_PLATFORM_DRIVER) && \
>         !defined(AT91_PLATFORM_DRIVER) && \
>         !defined(NXP_PLATFORM_DRIVER) && \
> -       !defined(DAVINCI_PLATFORM_DRIVER) && \
> -       !defined(SPEAR_PLATFORM_DRIVER)
> +       !defined(DAVINCI_PLATFORM_DRIVER)
>  #error "missing bus glue for ohci-hcd"
>  #endif
>
> @@ -1349,19 +1344,9 @@ static int __init ohci_hcd_mod_init(void)
>                 goto error_davinci;
>  #endif
>
> -#ifdef SPEAR_PLATFORM_DRIVER
> -       retval = platform_driver_register(&SPEAR_PLATFORM_DRIVER);
> -       if (retval < 0)
> -               goto error_spear;
> -#endif
> -
>         return retval;
>
>         /* Error path */
> -#ifdef SPEAR_PLATFORM_DRIVER
> -       platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
> - error_spear:
> -#endif
>  #ifdef DAVINCI_PLATFORM_DRIVER
>         platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
>   error_davinci:
> @@ -1419,9 +1404,6 @@ module_init(ohci_hcd_mod_init);
>
>  static void __exit ohci_hcd_mod_exit(void)
>  {
> -#ifdef SPEAR_PLATFORM_DRIVER
> -       platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
> -#endif
>  #ifdef DAVINCI_PLATFORM_DRIVER
>         platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
>  #endif
> diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
> index 6a7cb14..9e79d24 100644
> --- a/drivers/usb/host/ohci-spear.c
> +++ b/drivers/usb/host/ohci-spear.c
> @@ -11,94 +11,41 @@
>  * warranty of any kind, whether express or implied.
>  */
>
> -#include <linux/signal.h>
> -#include <linux/platform_device.h>
> +#include <linux/dma-mapping.h>
>  #include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
>  #include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/signal.h>
> +#include <linux/usb.h>
> +#include <linux/usb/hcd.h>
> +#include <linux/debugfs.h>
> +#include <linux/errno.h>

In alphabetical order please. And please which ones of these are must
to have.

>
> -struct spear_ohci {
> -       struct ohci_hcd ohci;
> -       struct clk *clk;
> -};
> -
> -#define to_spear_ohci(hcd)     (struct spear_ohci *)hcd_to_ohci(hcd)
> -
> -static void spear_start_ohci(struct spear_ohci *ohci)
> -{
> -       clk_prepare_enable(ohci->clk);
> -}
> -
> -static void spear_stop_ohci(struct spear_ohci *ohci)
> -{
> -       clk_disable_unprepare(ohci->clk);
> -}
> -
> -static int ohci_spear_start(struct usb_hcd *hcd)
> -{
> -       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
> -       int ret;
> -
> -       ret = ohci_init(ohci);
> -       if (ret < 0)
> -               return ret;
> -       ohci->regs = hcd->regs;
> -
> -       ret = ohci_run(ohci);
> -       if (ret < 0) {
> -               dev_err(hcd->self.controller, "can't start\n");
> -               ohci_stop(hcd);
> -               return ret;
> -       }
> -
> -       create_debug_files(ohci);
> -
> -#ifdef DEBUG
> -       ohci_dump(ohci, 1);
> -#endif
> -       return 0;
> -}
> -
> -static const struct hc_driver ohci_spear_hc_driver = {
> -       .description            = hcd_name,
> -       .product_desc           = "SPEAr OHCI",
> -       .hcd_priv_size          = sizeof(struct spear_ohci),
> -
> -       /* generic hardware linkage */
> -       .irq                    = ohci_irq,
> -       .flags                  = HCD_USB11 | HCD_MEMORY,
> -
> -       /* basic lifecycle operations */
> -       .start                  = ohci_spear_start,
> -       .stop                   = ohci_stop,
> -       .shutdown               = ohci_shutdown,
> -#ifdef CONFIG_PM
> -       .bus_suspend            = ohci_bus_suspend,
> -       .bus_resume             = ohci_bus_resume,
> -#endif
> -
> -       /* managing i/o requests and associated device resources */
> -       .urb_enqueue            = ohci_urb_enqueue,
> -       .urb_dequeue            = ohci_urb_dequeue,
> -       .endpoint_disable       = ohci_endpoint_disable,
>
> -       /* scheduling support */
> -       .get_frame_number       = ohci_get_frame,
> +#include "ohci.h"
>
> -       /* root hub support */
> -       .hub_status_data        = ohci_hub_status_data,
> -       .hub_control            = ohci_hub_control,
> +#define DRIVER_DESC "OHCI SPEAr driver"
>
> -       .start_port_reset       = ohci_start_port_reset,
> +static const char hcd_name[] = "SPEAr-ohci";
> +struct spear_ohci {
> +       struct clk *clk;
>  };
>
> +#define to_spear_ohci(hcd)     (struct spear_ohci *)(hcd_to_ohci(hcd)->priv)
> +
> +static struct hc_driver __read_mostly ohci_spear_hc_driver;
>  static u64 spear_ohci_dma_mask = DMA_BIT_MASK(32);
>
>  static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
>  {
>         const struct hc_driver *driver = &ohci_spear_hc_driver;
> +       struct ohci_hcd *ohci;
>         struct usb_hcd *hcd = NULL;
>         struct clk *usbh_clk;
> -       struct spear_ohci *ohci_p;
> +       struct spear_ohci *sohci_p;

why rename this?

>         struct resource *res;
>         int retval, irq;
>
> @@ -151,16 +98,24 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
>                 goto err_put_hcd;
>         }
>
> -       ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
> -       ohci_p->clk = usbh_clk;
> -       spear_start_ohci(ohci_p);
> -       ohci_hcd_init(hcd_to_ohci(hcd));
> +       sohci_p = to_spear_ohci(hcd);
> +       sohci_p->clk = usbh_clk;
> +       hcd_to_ohci(hcd)->regs = hcd->regs;
> +
> +       ohci_setup(hcd);
> +       clk_prepare_enable(sohci_p->clk);
> +
> +       ohci = hcd_to_ohci(hcd);
> +
> +#ifdef DEBUG
> +       ohci_dump(ohci, 1);
> +#endif
>
>         retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0);
>         if (retval == 0)
>                 return retval;
>
> -       spear_stop_ohci(ohci_p);
> +       clk_disable_unprepare(sohci_p->clk);
>  err_put_hcd:
>         usb_put_hcd(hcd);
>  fail:
> @@ -172,11 +127,11 @@ fail:
>  static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
>  {
>         struct usb_hcd *hcd = platform_get_drvdata(pdev);
> -       struct spear_ohci *ohci_p = to_spear_ohci(hcd);
> +       struct spear_ohci *sohci_p = to_spear_ohci(hcd);
>
>         usb_remove_hcd(hcd);
> -       if (ohci_p->clk)
> -               spear_stop_ohci(ohci_p);
> +       if (sohci_p->clk)
> +               clk_disable_unprepare(sohci_p->clk);
>
>         usb_put_hcd(hcd);
>         return 0;
> @@ -188,13 +143,13 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
>  {
>         struct usb_hcd *hcd = platform_get_drvdata(dev);
>         struct ohci_hcd *ohci = hcd_to_ohci(hcd);
> -       struct spear_ohci *ohci_p = to_spear_ohci(hcd);
> +       struct spear_ohci *sohci_p = to_spear_ohci(hcd);
>
>         if (time_before(jiffies, ohci->next_statechange))
>                 msleep(5);
>         ohci->next_statechange = jiffies;
>
> -       spear_stop_ohci(ohci_p);
> +       clk_disable_unprepare(sohci_p->clk);
>         return 0;
>  }
>
> @@ -202,13 +157,13 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
>  {
>         struct usb_hcd *hcd = platform_get_drvdata(dev);
>         struct ohci_hcd *ohci = hcd_to_ohci(hcd);
> -       struct spear_ohci *ohci_p = to_spear_ohci(hcd);
> +       struct spear_ohci *sohci_p = to_spear_ohci(hcd);
>
>         if (time_before(jiffies, ohci->next_statechange))
>                 msleep(5);
>         ohci->next_statechange = jiffies;
>
> -       spear_start_ohci(ohci_p);
> +        clk_prepare_enable(sohci_p->clk);
>         ohci_resume(hcd, false);
>         return 0;
>  }
> @@ -234,4 +189,28 @@ static struct platform_driver spear_ohci_hcd_driver = {
>         },
>  };
>
> +static const struct ohci_driver_overrides spear_overrides __initconst = {
> +       .extra_priv_size = sizeof(struct spear_ohci),
> +};
> +static int __init ohci_spear_init(void)
> +{
> +       if (usb_disabled())
> +               return -ENODEV;
> +
> +       pr_info("%s: " DRIVER_DESC "\n", hcd_name);
> +
> +       ohci_init_driver(&ohci_spear_hc_driver, &spear_overrides);
> +       return platform_driver_register(&spear_ohci_hcd_driver);
> +}
> +module_init(ohci_spear_init);
> +
> +static void __exit ohci_spear_cleanup(void)
> +{
> +       platform_driver_unregister(&spear_ohci_hcd_driver);
> +}
> +module_exit(ohci_spear_cleanup);
> +
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +MODULE_AUTHOR("Deepak Sikri");
> +MODULE_LICENSE("GPL v2");
>  MODULE_ALIAS("platform:spear-ohci");

I can't really review it functionally.

@Deepak: Can you?

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [RFC][PATCH 1/7] USB: OHCI: make ohci-exynos a separate driver
  2013-06-07  6:03 ` [RFC][PATCH 1/7] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
@ 2013-06-07 13:49   ` Arnd Bergmann
  2013-06-07 17:20   ` Alan Stern
  1 sibling, 0 replies; 110+ messages in thread
From: Arnd Bergmann @ 2013-06-07 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 07 June 2013 11:33:27 Manjunath Goudar wrote:
> 
>  #if    !IS_ENABLED(CONFIG_USB_OHCI_HCD_PCI) && \
>         !IS_ENABLED(CONFIG_USB_OHCI_HCD_PLATFORM) && \
> +       !IS_ENABLED(CONFIG_USB_OHCI_EXYNOS) && \
>         !defined(PLATFORM_DRIVER) &&    \
>         !defined(OMAP1_PLATFORM_DRIVER) &&      \
>         !defined(OMAP3_PLATFORM_DRIVER) &&      \
> @@ -1269,7 +1265,6 @@ MODULE_LICENSE ("GPL");
>         !defined(SM501_OHCI_DRIVER) && \
>         !defined(TMIO_OHCI_DRIVER) && \
>         !defined(S3C2410_PLATFORM_DRIVER) && \
> -       !defined(EXYNOS_PLATFORM_DRIVER) && \
>         !defined(EP93XX_PLATFORM_DRIVER) && \
>         !defined(AT91_PLATFORM_DRIVER) && \
>         !defined(NXP_PLATFORM_DRIVER) && \

Hi Manjunath,

please note that Greg just merged my patch to remove this entire list and
the #error statement. The next time you rebase your patch, you will have
to remove this hunk in each of your patches.

	Arnd

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [RFC][PATCH 3/7] USB: OHCI: make ohci-omap3 a separate driver
  2013-06-07  6:03 ` [RFC][PATCH 3/7] USB: OHCI: make ohci-omap3 " Manjunath Goudar
@ 2013-06-07 13:51   ` Arnd Bergmann
  2013-06-07 17:49   ` Alan Stern
  1 sibling, 0 replies; 110+ messages in thread
From: Arnd Bergmann @ 2013-06-07 13:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 07 June 2013 11:33:29 Manjunath Goudar wrote:
> +       /*
> +       * RemoteWakeupConnected has to be set explicitly before
> +       * calling ohci_run. The reset value of RWC is 0.
> +       */

Just nitpicking, but you still use the wrong commenting style
occasionally. The '*' characters should always be aligned
vertically, like

       /*
        * RemoteWakeupConnected has to be set explicitly before
        * calling ohci_run. The reset value of RWC is 0.
        */

	Arnd

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [RFC][PATCH 7/7] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-06-07  6:03 ` [RFC][PATCH 7/7] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
@ 2013-06-07 13:56   ` Arnd Bergmann
  2013-06-07 18:54   ` Alan Stern
  1 sibling, 0 replies; 110+ messages in thread
From: Arnd Bergmann @ 2013-06-07 13:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 07 June 2013 11:33:33 Manjunath Goudar wrote:
> 
> +       ohci_setup(hcd);
>         s3c2410_start_hc(dev, hcd);
>  
> -       ohci_hcd_init(hcd_to_ohci(hcd));
> -

I'm not sure about this part: s3c2410_start_hc is where the clock gets
enabled, presumable we are not supposed to touch the ohci registers
before it gets called, so ohci_init() being called implicitly
by ohci_setup() seems like a bad idea.

	Arnd

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [RFC][PATCH 1/7] USB: OHCI: make ohci-exynos a separate driver
  2013-06-07  6:03 ` [RFC][PATCH 1/7] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
  2013-06-07 13:49   ` Arnd Bergmann
@ 2013-06-07 17:20   ` Alan Stern
  1 sibling, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-07 17:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 7 Jun 2013, Manjunath Goudar wrote:

> Separate the  Samsung OHCI EXYNOS host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM.

> -static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
> +static void exynos_ohci_phy_enable(struct platform_device *pdev)
>  {
> -	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
> +	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);

This is wrong.  platform_get_drvdata() will return the hcd, not the 
exynos_ohci_hcd structure.

> @@ -37,9 +51,9 @@ static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
>  		exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>  }
>  
> -static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
> +static void exynos_ohci_phy_disable(struct platform_device *pdev)
>  {
> -	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
> +	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);

Same problem here.

> @@ -121,15 +83,18 @@ static int exynos_ohci_probe(struct platform_device *pdev)
>  	if (!pdev->dev.coherent_dma_mask)
>  		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
>  
> -	exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd),
> -					GFP_KERNEL);
> -	if (!exynos_ohci)
> +	hcd = usb_create_hcd(&exynos_ohci_hc_driver,
> +				&pdev->dev, dev_name(&pdev->dev));
> +	if (!hcd) {
> +		dev_err(&pdev->dev, "Unable to create HCD\n");
>  		return -ENOMEM;
>  
>  	if (of_device_is_compatible(pdev->dev.of_node,
>  					"samsung,exynos5440-ohci"))
>  		goto skip_phy;
>  
> +	}

This close brace belongs with the previous "if" statement.

> @@ -146,7 +111,6 @@ static int exynos_ohci_probe(struct platform_device *pdev)
>  
>  skip_phy:
>  
> -	exynos_ohci->dev = &pdev->dev;
>  
>  	hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
>  					dev_name(&pdev->dev));

This needs to be deleted, because it was done already.

Manjunath, I have already asked you to proof-read your patches before 
posting them.  Please do so.  New patches should _not_ have this kind 
of error.

> @@ -192,13 +155,11 @@ skip_phy:
>  	}
>  
>  	if (exynos_ohci->otg)
> -		exynos_ohci->otg->set_host(exynos_ohci->otg,
> -					&exynos_ohci->hcd->self);
> +		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
>  
> -	exynos_ohci_phy_enable(exynos_ohci);
> +	exynos_ohci_phy_enable(pdev);

This call will not work, because you don't set pdev's platform_data
until later.  The call to platform_set_drvdata() must be moved before
this line.

>  
> -	ohci = hcd_to_ohci(hcd);
> -	ohci_hcd_init(ohci);
> +	ohci_setup(hcd);

There's no need to call ohci_setup(), because it will get called anyway
as the .reset member of the ohci_hc_driver structure.

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [RFC][PATCH 2/7] USB: OHCI: make ohci-omap a separate driver
  2013-06-07  6:03 ` [RFC][PATCH 2/7] USB: OHCI: make ohci-omap " Manjunath Goudar
@ 2013-06-07 17:37   ` Alan Stern
  0 siblings, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-07 17:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 7 Jun 2013, Manjunath Goudar wrote:

> Separate the  TI OHCI OMAP1/2 host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM.

> @@ -71,6 +77,10 @@ static struct clk *usb_dc_ck;
>  static int host_enabled;
>  static int host_initialized;

These two variables aren't used for anything.  You should get rid of 
them.

> @@ -201,8 +211,14 @@ static int ohci_omap_init(struct usb_hcd *hcd)
>  		ohci_to_hcd(ohci)->self.otg_port = config->otg;
>  		/* default/minimum OTG power budget:  8 mA */
>  		ohci_to_hcd(ohci)->power_budget = 8;
> +		ohci->hc_control = OHCI_CTRL_RWC;
> +		writel(OHCI_CTRL_RWC, &ohci->regs->control);
>  	}
>  
> +	if (config->rwc) {
> +		ohci->hc_control = OHCI_CTRL_RWC;
> +		writel(OHCI_CTRL_RWC, &ohci->regs->control);
> +	}

It's better to have two tests.  Remove the two lines added to the
previous "if" block, and change this test to

	if (config->otg || config->rwc) {

> @@ -281,14 +298,6 @@ static int ohci_omap_init(struct usb_hcd *hcd)
>  	return 0;
>  }
>  
> -static void ohci_omap_stop(struct usb_hcd *hcd)
> -{
> -	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
> -	ohci_stop(hcd);
> -	omap_ohci_clock_power(0);

This last line seems to have gotten lost.  You need to add it to 
usb_hcd_omap_remove().

> @@ -354,8 +362,7 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
>  		goto err2;
>  	}
>  
> -	ohci = hcd_to_ohci(hcd);
> -	ohci_hcd_init(ohci);
> +	ohci_setup(hcd);

Not needed, since you call ohci_setup() from within ohci_omap_reset().

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [RFC][PATCH 3/7] USB: OHCI: make ohci-omap3 a separate driver
  2013-06-07  6:03 ` [RFC][PATCH 3/7] USB: OHCI: make ohci-omap3 " Manjunath Goudar
  2013-06-07 13:51   ` Arnd Bergmann
@ 2013-06-07 17:49   ` Alan Stern
  1 sibling, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-07 17:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 7 Jun 2013, Manjunath Goudar wrote:

> Separate the  TI OHCI OMAP3 host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM.

> @@ -185,7 +118,16 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
>  	pm_runtime_enable(dev);
>  	pm_runtime_get_sync(dev);
>  
> -	ohci_hcd_init(hcd_to_ohci(hcd));
> +	ohci = hcd_to_ohci(hcd);
> +	/*
> +	* RemoteWakeupConnected has to be set explicitly before
> +	* calling ohci_run. The reset value of RWC is 0.
> +	*/
> +	ohci->hc_control = OHCI_CTRL_RWC;
> +	writel(OHCI_CTRL_RWC, &ohci->regs->control);
> +	dev_dbg(hcd->self.controller, "starting OHCI controller\n");
> +
> +	ohci_setup(hcd);

Don't call ohci_setup().

Apart from that (and the comment format), this is okay.

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [RFC][PATCH 4/7] USB: OHCI: make ohci-spear a separate driver
  2013-06-07  6:03 ` [RFC][PATCH 4/7] USB: OHCI: make ohci-spear " Manjunath Goudar
  2013-06-07 10:30   ` Viresh Kumar
@ 2013-06-07 18:34   ` Alan Stern
  1 sibling, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-07 18:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 7 Jun 2013, Manjunath Goudar wrote:

> Separate the  TI OHCI SPEAr host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM.

> @@ -151,16 +98,24 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
>  		goto err_put_hcd;
>  	}
>  
> -	ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
> -	ohci_p->clk = usbh_clk;
> -	spear_start_ohci(ohci_p);
> -	ohci_hcd_init(hcd_to_ohci(hcd));
> +	sohci_p = to_spear_ohci(hcd);
> +	sohci_p->clk = usbh_clk;
> +	hcd_to_ohci(hcd)->regs = hcd->regs;

This line isn't needed.  It is one of the first things that ohci_init() 
does.

> +
> +	ohci_setup(hcd);

Don't call ohci_setup().

> +	clk_prepare_enable(sohci_p->clk);
> +
> +	ohci = hcd_to_ohci(hcd);
> +
> +#ifdef DEBUG
> +	ohci_dump(ohci, 1);
> +#endif

I suspect this debugging stuff isn't needed any more.  You can get rid 
of it.

> @@ -188,13 +143,13 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
>  {
>  	struct usb_hcd *hcd = platform_get_drvdata(dev);
>  	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
> -	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
> +	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
>  
>  	if (time_before(jiffies, ohci->next_statechange))
>  		msleep(5);
>  	ohci->next_statechange = jiffies;
>  
> -	spear_stop_ohci(ohci_p);
> +	clk_disable_unprepare(sohci_p->clk);
>  	return 0;
>  }

This routine needs to call ohci_suspend() just before the 
clk_disable_unprepare().  I don't know how that got left out, but it 
looks like the same problem exists in several of the ohci glue files.  
I guess they should all be fixed at once, in a separate patch.

>  
> @@ -202,13 +157,13 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
>  {
>  	struct usb_hcd *hcd = platform_get_drvdata(dev);
>  	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
> -	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
> +	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
>  
>  	if (time_before(jiffies, ohci->next_statechange))
>  		msleep(5);
>  	ohci->next_statechange = jiffies;
>  
> -	spear_start_ohci(ohci_p);
> +	 clk_prepare_enable(sohci_p->clk);

You got an extra space character after the tab.

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [RFC][PATCH 5/7] USB: OHCI: export ohci_hub_control and ohci_hub_status_data
  2013-06-07  6:03 ` [RFC][PATCH 5/7] USB: OHCI: export ohci_hub_control and ohci_hub_status_data Manjunath Goudar
@ 2013-06-07 18:42   ` Alan Stern
  0 siblings, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-07 18:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 7 Jun 2013, Manjunath Goudar wrote:

> In order to make ohci-at91 and ohci-s3c2410 as a separate driver,
> ohci_hub_control and ohci_hub_status_data symbol needs to be exported.
> This work is part of enabling multi-platform kernels on ARM.

No, we are not going to export those two routines.  You can copy the 
approach used by Stephen Warren in the ehci-tegra conversion.

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [RFC][PATCH 6/7] USB: OHCI: make ohci-at91 a separate driver
  2013-06-07  6:03 ` [RFC][PATCH 6/7] USB: OHCI: make ohci-at91 a separate driver Manjunath Goudar
@ 2013-06-07 18:52   ` Alan Stern
  0 siblings, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-07 18:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 7 Jun 2013, Manjunath Goudar wrote:

> Separate the  TI OHCI Atmel host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM.

> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -411,6 +411,14 @@ config USB_OHCI_HCD_SPEAR
>            Enables support for the on-chip OHCI controller on
>            ST SPEAr chips.
>  
> +config USB_OHCI_HCD_AT91
> +        tristate  "Support for Atmel on-chip OHCI USB controller"
> +        depends on USB_OHCI_HCD && ARCH_AT91
> +        default y
> +        ---help---
> +          Enables support for the on-chip OHCI controller on
> +          Atmel chips.

Notice the "depends on" line you added here?

> diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
> index a0cb44f..b4a88a6 100644
> --- a/drivers/usb/host/ohci-at91.c
> +++ b/drivers/usb/host/ohci-at91.c
> @@ -13,16 +13,25 @@
...
>  #ifndef CONFIG_ARCH_AT91
>  #error "CONFIG_ARCH_AT91 must be defined."
>  #endif

As a result of the "depends on" line, this test will never succeed.  
You can remove these three lines.

> @@ -111,6 +126,8 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
>  static int usb_hcd_at91_probe(const struct hc_driver *driver,
>  			struct platform_device *pdev)
>  {
> +	struct at91_usbh_data	*board;

Tab character where it should be a space.

> +	struct ohci_hcd	*ohci;
>  	int retval;
>  	struct usb_hcd *hcd = NULL;
>  
> @@ -163,8 +180,11 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
>  		goto err5;
>  	}
>  
> +	board = hcd->self.controller->platform_data;
> +	ohci = hcd_to_ohci(hcd);
> +	ohci->num_ports = board->ports;
>  	at91_start_hc(pdev);
> -	ohci_hcd_init(hcd_to_ohci(hcd));
> +	ohci_setup(hcd);

Don't call ohci_setup().

> @@ -727,3 +672,37 @@ static struct platform_driver ohci_hcd_at91_driver = {
>  		.of_match_table	= of_match_ptr(at91_ohci_dt_ids),
>  	},
>  };
> +
> +static int __init ohci_at91_init(void)
> +{
> +	if (usb_disabled())
> +		return -ENODEV;
> +
> +	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
> +	ohci_init_driver(&ohci_at91_hc_driver, NULL);
> +
> +	/*
> +	* The Atmel HW has some unusual quirks, which require Atmel-specific
> +	* workarounds. We override certain hc_driver functions here to
> +	* achieve that. We explicitly do not enhance ohci_driver_overrides to
> +	* allow this more easily, since this is an unusual case, and we don't
> +	* want to encourage others to override these functions by making it
> +	* too easy.
> +	*/
> +
> +	ohci_at91_hc_driver.hub_status_data	= ohci_at91_hub_status_data;
> +	ohci_at91_hc_driver.hub_control		= ohci_at91_hub_control;

Since the hub_status_data and hub_control routines aren't going to be
exported, you can't do it like this.  Instead, save the values of
ohci_at91_hc_driver.hub_status_data and ohci_at91_hc_driver.hub_control
before overwriting them.

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [RFC][PATCH 7/7] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-06-07  6:03 ` [RFC][PATCH 7/7] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
  2013-06-07 13:56   ` Arnd Bergmann
@ 2013-06-07 18:54   ` Alan Stern
  1 sibling, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-07 18:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 7 Jun 2013, Manjunath Goudar wrote:

> Separate the Samsung OHCI S3CXXXX host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM.

> @@ -371,10 +384,9 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
>  		goto err_put;
>  	}
>  
> +	ohci_setup(hcd);

Don't call ohci_setup().

> @@ -532,4 +480,36 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {
>  	},
>  };
>  
> +static int __init ohci_s3cxxxx_init(void)
> +{
> +	if (usb_disabled())
> +		return -ENODEV;
> +
> +	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
> +	ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
> +
> +	/*
> +	* The Samsung HW has some unusual quirks, which require Sumsung-specific
> +	* workarounds. We override certain hc_driver functions here to
> +	* achieve that. We explicitly do not enhance ohci_driver_overrides to
> +	* allow this more easily, since this is an unusual case, and we don't
> +	* want to encourage others to override these functions by making it
> +	* too easy.
> +	*/
> +
> +	ohci_s3c2410_hc_driver.hub_status_data	= ohci_s3c2410_hub_status_data;
> +	ohci_s3c2410_hc_driver.hub_control	= ohci_s3c2410_hub_control;

Like in ohci-at91, save the pointers before overwriting them.

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V2 0/6] USB: OHCI: more bus glues as separate modules
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (6 preceding siblings ...)
  2013-06-07  6:03 ` [RFC][PATCH 7/7] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
@ 2013-06-12 15:53 ` Manjunath Goudar
  2013-06-12 15:53   ` [PATCH V2 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
                     ` (5 more replies)
  2013-06-25  6:23 ` [PATCH V3 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (6 subsequent siblings)
  14 siblings, 6 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-12 15:53 UTC (permalink / raw)
  To: linux-arm-kernel

These patches are for separating the SOC On-Chip ohci host controller
from ohci-hcd host code into its own driver module.
This work is part of enabling multi-platform kernels on ARM.

V2:
  In patch 5/6 and 6/6:
  -Set non-standard fields in hc_driver manually, rather than
   relying on an expanded struct ohci_driver_overrides.
  -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
   relying on ohci_hub_control and hub_status_data being exported.
  -ohci_setup() has been removed because it is called in .reset member
   of the ohci_hc_driver structure.
 
  In patch 1/6 to 4/6
  -ohci_setup() has been removed because it is called in .reset member
   of the ohci_hc_driver structure.

Manjunath Goudar (6):
  USB: OHCI: make ohci-exynos a separate driver
  USB: OHCI: make ohci-omap a separate driver
  USB: OHCI: make ohci-omap3 a separate driver
  USB: OHCI: make ohci-spear a separate driver
  USB: OHCI: make ohci-at91 a separate driver
  USB: OHCI: make ohci-s3c2410 a separate driver

 drivers/usb/host/Kconfig        |   30 ++++++-
 drivers/usb/host/Makefile       |    6 ++
 drivers/usb/host/ohci-at91.c    |  148 +++++++++++++++-------------------
 drivers/usb/host/ohci-exynos.c  |  167 ++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c     |  108 -------------------------
 drivers/usb/host/ohci-omap.c    |  156 ++++++++++++------------------------
 drivers/usb/host/ohci-omap3.c   |  120 ++++++++++------------------
 drivers/usb/host/ohci-s3c2410.c |  129 ++++++++++++++----------------
 drivers/usb/host/ohci-spear.c   |  140 +++++++++++++-------------------
 9 files changed, 370 insertions(+), 634 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V2 1/6] USB: OHCI: make ohci-exynos a separate driver
  2013-06-12 15:53 ` [PATCH V2 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
@ 2013-06-12 15:53   ` Manjunath Goudar
  2013-06-18 17:30     ` Alan Stern
  2013-06-20  4:10     ` Jingoo Han
  2013-06-12 15:53   ` [PATCH V2 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
                     ` (4 subsequent siblings)
  5 siblings, 2 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-12 15:53 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  Samsung OHCI EXYNOS host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

V2:
 -exynos_ohci_hcd structure assignment error fixed.
 -Removed multiple usb_create_hcd() from prob funtion.
 -platform_set_drvdata() called before exynos_ohci_phy_enable().
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Jingoo Han <jg1.han@samsung.com>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb at vger.kernel.org
---
 drivers/usb/host/Kconfig       |    2 +-
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ohci-exynos.c |  167 +++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c    |   18 -----
 4 files changed, 71 insertions(+), 117 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index f35f71e..75456f2 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -463,7 +463,7 @@ config USB_OHCI_SH
 	  If you use the PCI OHCI controller, this option is not necessary.
 
 config USB_OHCI_EXYNOS
-	boolean "OHCI support for Samsung EXYNOS SoC Series"
+	tristate "OHCI support for Samsung EXYNOS SoC Series"
 	depends on ARCH_EXYNOS
 	help
 	 Enable support for the Samsung Exynos SOC's on-chip OHCI controller.
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index d1a34e0..bf4a4b2 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
+obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index b0b542c..6ff830c 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -12,24 +12,39 @@
  */
 
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-exynos.h>
 #include <linux/usb/phy.h>
 #include <linux/usb/samsung_usb_phy.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include "ohci.h"
+
+#define DRIVER_DESC "OHCI exynos driver"
+
+static const char hcd_name[] = "ohci-exynos";
+static struct hc_driver __read_mostly exynos_ohci_hc_driver;
+
+#define to_exynos_ohci(hcd) (struct exynos_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
 
 struct exynos_ohci_hcd {
-	struct device *dev;
-	struct usb_hcd *hcd;
 	struct clk *clk;
 	struct usb_phy *phy;
 	struct usb_otg *otg;
 	struct exynos4_ohci_platdata *pdata;
 };
 
-static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_enable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_init(exynos_ohci->phy);
@@ -37,9 +52,10 @@ static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
 }
 
-static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_disable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_shutdown(exynos_ohci->phy);
@@ -47,63 +63,11 @@ static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
 }
 
-static int ohci_exynos_reset(struct usb_hcd *hcd)
-{
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-static int ohci_exynos_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci);
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-static const struct hc_driver exynos_ohci_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "EXYNOS OHCI Host Controller",
-	.hcd_priv_size		= sizeof(struct ohci_hcd),
-
-	.irq			= ohci_irq,
-	.flags			= HCD_MEMORY|HCD_USB11,
-
-	.reset			= ohci_exynos_reset,
-	.start			= ohci_exynos_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-
-	.get_frame_number	= ohci_get_frame,
-
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-	.start_port_reset	= ohci_start_port_reset,
-};
-
 static int exynos_ohci_probe(struct platform_device *pdev)
 {
 	struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_ohci_hcd *exynos_ohci;
 	struct usb_hcd *hcd;
-	struct ohci_hcd *ohci;
 	struct resource *res;
 	struct usb_phy *phy;
 	int irq;
@@ -119,10 +83,14 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	if (!pdev->dev.coherent_dma_mask)
 		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
-	exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd),
-					GFP_KERNEL);
-	if (!exynos_ohci)
+	hcd = usb_create_hcd(&exynos_ohci_hc_driver,
+				&pdev->dev, dev_name(&pdev->dev));
+	if (!hcd) {
+		dev_err(&pdev->dev, "Unable to create HCD\n");
 		return -ENOMEM;
+	}
+
+	exynos_ohci = to_exynos_ohci(hcd);
 
 	if (of_device_is_compatible(pdev->dev.of_node,
 					"samsung,exynos5440-ohci"))
@@ -143,17 +111,6 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	}
 
 skip_phy:
-
-	exynos_ohci->dev = &pdev->dev;
-
-	hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
-					dev_name(&pdev->dev));
-	if (!hcd) {
-		dev_err(&pdev->dev, "Unable to create HCD\n");
-		return -ENOMEM;
-	}
-
-	exynos_ohci->hcd = hcd;
 	exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");
 
 	if (IS_ERR(exynos_ohci->clk)) {
@@ -190,26 +147,21 @@ skip_phy:
 	}
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	platform_set_drvdata(pdev, hcd);
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to add USB HCD\n");
 		goto fail_add_hcd;
 	}
-
-	platform_set_drvdata(pdev, exynos_ohci);
-
 	return 0;
 
 fail_add_hcd:
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 fail_io:
 	clk_disable_unprepare(exynos_ohci->clk);
 fail_clk:
@@ -219,16 +171,15 @@ fail_clk:
 
 static int exynos_ohci_remove(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	usb_remove_hcd(hcd);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -239,8 +190,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
 
 static void exynos_ohci_shutdown(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
 	if (hcd->driver->shutdown)
 		hcd->driver->shutdown(hcd);
@@ -249,9 +199,10 @@ static void exynos_ohci_shutdown(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int exynos_ohci_suspend(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	struct platform_device *pdev = to_platform_device(dev);
 	unsigned long flags;
 	int rc = 0;
 
@@ -271,10 +222,9 @@ static int exynos_ohci_suspend(struct device *dev)
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -286,16 +236,16 @@ fail:
 
 static int exynos_ohci_resume(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd			= dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci	= to_exynos_ohci(hcd);
+	struct platform_device *pdev		= to_platform_device(dev);
 
 	clk_prepare_enable(exynos_ohci->clk);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	ohci_resume(hcd, false);
 
@@ -306,6 +256,10 @@ static int exynos_ohci_resume(struct device *dev)
 #define exynos_ohci_resume	NULL
 #endif
 
+static const struct ohci_driver_overrides exynos_overrides __initconst = {
+	.extra_priv_size =	sizeof(struct exynos_ohci_hcd),
+};
+
 static const struct dev_pm_ops exynos_ohci_pm_ops = {
 	.suspend	= exynos_ohci_suspend,
 	.resume		= exynos_ohci_resume,
@@ -331,6 +285,23 @@ static struct platform_driver exynos_ohci_driver = {
 		.of_match_table	= of_match_ptr(exynos_ohci_match),
 	}
 };
+static int __init ohci_exynos_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&exynos_ohci_hc_driver, &exynos_overrides);
+	return platform_driver_register(&exynos_ohci_driver);
+}
+module_init(ohci_exynos_init);
+
+static void __exit ohci_exynos_cleanup(void)
+{
+	platform_driver_unregister(&exynos_ohci_driver);
+}
+module_exit(ohci_exynos_cleanup);
 
 MODULE_ALIAS("platform:exynos-ohci");
 MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index a9d3437..2980bb6 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_EXYNOS
-#include "ohci-exynos.c"
-#define EXYNOS_PLATFORM_DRIVER	exynos_ohci_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP1
 #include "ohci-omap.c"
 #define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
@@ -1336,12 +1331,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_s3c2410;
 #endif
 
-#ifdef EXYNOS_PLATFORM_DRIVER
-	retval = platform_driver_register(&EXYNOS_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_exynos;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1395,10 +1384,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
- error_exynos:
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
  error_s3c2410:
@@ -1463,9 +1448,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V2 2/6] USB: OHCI: make ohci-omap a separate driver
  2013-06-12 15:53 ` [PATCH V2 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
  2013-06-12 15:53   ` [PATCH V2 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
@ 2013-06-12 15:53   ` Manjunath Goudar
  2013-06-18 17:47     ` Alan Stern
  2013-06-18 18:13     ` Alan Stern
  2013-06-12 15:53   ` [PATCH V2 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
                     ` (3 subsequent siblings)
  5 siblings, 2 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-12 15:53 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP1/2 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

V2:
 -omap_ohci_clock_power(0) called in usb_hcd_omap_remove().
 -Removed ohci_setup() call from usb_hcd_omap_probe() and ohci_omap_reset().
 -host_enabled and host_initialized variables aren't used for anything
  thats what removed.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb at vger.kernel.org
---
 drivers/usb/host/Kconfig     |    2 +-
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-hcd.c  |   18 -----
 drivers/usb/host/ohci-omap.c |  156 +++++++++++++-----------------------------
 4 files changed, 51 insertions(+), 126 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 75456f2..7a87c72 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -376,7 +376,7 @@ config USB_OHCI_HCD
 if USB_OHCI_HCD
 
 config USB_OHCI_HCD_OMAP1
-	bool "OHCI support for OMAP1/2 chips"
+	tristate "OHCI support for OMAP1/2 chips"
 	depends on ARCH_OMAP1
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index bf4a4b2..52f2c44 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 2980bb6..1abc1e7 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP1
-#include "ohci-omap.c"
-#define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP3
 #include "ohci-omap3.c"
 #define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
@@ -1289,12 +1284,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP1_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP1_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap1_platform;
-#endif
-
 #ifdef OMAP3_PLATFORM_DRIVER
 	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1408,10 +1397,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
  error_omap3_platform:
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
- error_omap1_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1466,9 +1451,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OMAP3_PLATFORM_DRIVER
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 8747fa6..b900dba 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -14,12 +14,21 @@
  * This file is licenced under the GPL.
  */
 
-#include <linux/signal.h>
-#include <linux/jiffies.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
 #include <asm/io.h>
 #include <asm/mach-types.h>
@@ -42,10 +51,7 @@
 #define OMAP1510_LB_MMU_RAM_H	0xfffec234
 #define OMAP1510_LB_MMU_RAM_L	0xfffec238
 
-
-#ifndef CONFIG_ARCH_OMAP
-#error "This file is OMAP bus glue.  CONFIG_OMAP must be defined."
-#endif
+#define DRIVER_DESC "OHCI OMAP driver"
 
 #ifdef CONFIG_TPS65010
 #include <linux/i2c/tps65010.h>
@@ -68,8 +74,9 @@ extern int ocpi_enable(void);
 
 static struct clk *usb_host_ck;
 static struct clk *usb_dc_ck;
-static int host_enabled;
-static int host_initialized;
+
+static const char hcd_name[] = "ohci-omap";
+static struct hc_driver __read_mostly ohci_omap_hc_driver;
 
 static void omap_ohci_clock_power(int on)
 {
@@ -188,21 +195,21 @@ static void start_hnp(struct ohci_hcd *ohci)
 
 /*-------------------------------------------------------------------------*/
 
-static int ohci_omap_init(struct usb_hcd *hcd)
+static int ohci_omap_reset(struct usb_hcd *hcd)
 {
 	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
 	struct omap_usb_config	*config = hcd->self.controller->platform_data;
 	int			need_transceiver = (config->otg != 0);
-	int			ret;
 
 	dev_dbg(hcd->self.controller, "starting USB Controller\n");
 
-	if (config->otg) {
+	if (config->otg || config->rwc) {
 		ohci_to_hcd(ohci)->self.otg_port = config->otg;
 		/* default/minimum OTG power budget:  8 mA */
 		ohci_to_hcd(ohci)->power_budget = 8;
+		ohci->hc_control = OHCI_CTRL_RWC;
+		writel(OHCI_CTRL_RWC, &ohci->regs->control);
 	}
-
 	/* boards can use OTG transceivers in non-OTG modes */
 	need_transceiver = need_transceiver
 			|| machine_is_omap_h2() || machine_is_omap_h3();
@@ -238,9 +245,6 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 		omap_1510_local_bus_init();
 	}
 
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
 	/* board-specific power switching and overcurrent support */
 	if (machine_is_omap_osk() || machine_is_omap_innovator()) {
 		u32	rh = roothub_a (ohci);
@@ -281,14 +285,6 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	return 0;
 }
 
-static void ohci_omap_stop(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
-	ohci_stop(hcd);
-	omap_ohci_clock_power(0);
-}
-
-
 /*-------------------------------------------------------------------------*/
 
 /**
@@ -304,7 +300,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 {
 	int retval, irq;
 	struct usb_hcd *hcd = 0;
-	struct ohci_hcd *ohci;
 
 	if (pdev->num_resources != 2) {
 		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
@@ -354,12 +349,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 		goto err2;
 	}
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
-
-	host_initialized = 0;
-	host_enabled = 1;
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		retval = -ENXIO;
@@ -368,12 +357,8 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 	retval = usb_add_hcd(hcd, irq, 0);
 	if (retval)
 		goto err3;
-
-	host_initialized = 1;
-
-	if (!host_enabled)
-		omap_ohci_clock_power(0);
-
+	
+	omap_ohci_clock_power(0);
 	return 0;
 err3:
 	iounmap(hcd->regs);
@@ -402,6 +387,8 @@ err0:
 static inline void
 usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
+	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
+	omap_ohci_clock_power(0);
 	usb_remove_hcd(hcd);
 	if (!IS_ERR_OR_NULL(hcd->phy)) {
 		(void) otg_set_host(hcd->phy->otg, 0);
@@ -418,76 +405,6 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_omap_start (struct usb_hcd *hcd)
-{
-	struct omap_usb_config *config;
-	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ret;
-
-	if (!host_enabled)
-		return 0;
-	config = hcd->self.controller->platform_data;
-	if (config->otg || config->rwc) {
-		ohci->hc_control = OHCI_CTRL_RWC;
-		writel(OHCI_CTRL_RWC, &ohci->regs->control);
-	}
-
-	if ((ret = ohci_run (ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop (hcd);
-		return ret;
-	}
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_omap_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap_init,
-	.start =		ohci_omap_start,
-	.stop =			ohci_omap_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static int ohci_hcd_omap_drv_probe(struct platform_device *dev)
 {
 	return usb_hcd_omap_probe(&ohci_omap_hc_driver, dev);
@@ -553,4 +470,29 @@ static struct platform_driver ohci_hcd_omap_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides omap_overrides __initconst = {
+	.product_desc	= "OMAP OHCI",
+	.reset		= ohci_omap_reset
+};
+
+static int __init ohci_omap_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap_hc_driver, &omap_overrides);
+	return platform_driver_register(&ohci_hcd_omap_driver);
+}
+module_init(ohci_omap_init);
+
+static void __exit ohci_omap_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap_driver);
+}
+module_exit(ohci_omap_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V2 3/6] USB: OHCI: make ohci-omap3 a separate driver
  2013-06-12 15:53 ` [PATCH V2 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
  2013-06-12 15:53   ` [PATCH V2 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
  2013-06-12 15:53   ` [PATCH V2 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
@ 2013-06-12 15:53   ` Manjunath Goudar
  2013-06-18 18:16     ` Alan Stern
  2013-06-12 15:54   ` [PATCH V2 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
                     ` (2 subsequent siblings)
  5 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-12 15:53 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP3 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -The improper multi-line commenting style written in proper way.
  ('*' characters aligned in vertically).

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Anand Gadiyar <gadiyar@ti.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb at vger.kernel.org
---
 drivers/usb/host/Kconfig      |    2 +-
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 -------
 drivers/usb/host/ohci-omap3.c |  120 ++++++++++++++---------------------------
 4 files changed, 42 insertions(+), 99 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 7a87c72..db20e43 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -383,7 +383,7 @@ config USB_OHCI_HCD_OMAP1
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
 config USB_OHCI_HCD_OMAP3
-	bool "OHCI support for OMAP3 and later chips"
+	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 52f2c44..9f2f5f3 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 1abc1e7..cad51d2 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP3
-#include "ohci-omap3.c"
-#define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1284,12 +1279,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP3_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap3_platform;
-#endif
-
 #ifdef OF_PLATFORM_DRIVER
 	retval = platform_driver_register(&OF_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1393,10 +1382,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
  error_of_platform:
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
- error_omap3_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1448,9 +1433,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OF_PLATFORM_DRIVER
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index 8f71357..b7c75ab 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -29,90 +29,22 @@
  *	- add kernel-doc
  */
 
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/of.h>
-#include <linux/dma-mapping.h>
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_init(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "starting OHCI controller\n");
-
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	/*
-	 * RemoteWakeupConnected has to be set explicitly before
-	 * calling ohci_run. The reset value of RWC is 0.
-	 */
-	ohci->hc_control = OHCI_CTRL_RWC;
-	writel(OHCI_CTRL_RWC, &ohci->regs->control);
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
-	ret = ohci_run(ohci);
+#include "ohci.h"
 
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-	}
+#define DRIVER_DESC "OHCI OMAP3 driver"
 
-	return ret;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_omap3_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP3 OHCI Host Controller",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap3_init,
-	.start =		ohci_omap3_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
+static const char hcd_name[] = "ohci-omap3";
+static struct hc_driver __read_mostly ohci_omap3_hc_driver;
 
 /*
  * configure so an HC device and id are always provided
@@ -129,6 +61,7 @@ static const struct hc_driver ohci_omap3_hc_driver = {
 static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 {
 	struct device		*dev = &pdev->dev;
+	struct ohci_hcd		*ohci;
 	struct usb_hcd		*hcd = NULL;
 	void __iomem		*regs = NULL;
 	struct resource		*res;
@@ -185,7 +118,14 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	ohci = hcd_to_ohci(hcd);
+	/*
+	 * RemoteWakeupConnected has to be set explicitly before
+	 * calling ohci_run. The reset value of RWC is 0.
+	 */
+	ohci->hc_control = OHCI_CTRL_RWC;
+	writel(OHCI_CTRL_RWC, &ohci->regs->control);
+	dev_dbg(hcd->self.controller, "starting OHCI controller\n");
 
 	ret = usb_add_hcd(hcd, irq, 0);
 	if (ret) {
@@ -256,5 +196,25 @@ static struct platform_driver ohci_hcd_omap3_driver = {
 	},
 };
 
+static int __init ohci_omap3_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap3_hc_driver, NULL);
+	return platform_driver_register(&ohci_hcd_omap3_driver);
+}
+module_init(ohci_omap3_init);
+
+static void __exit ohci_omap3_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap3_driver);
+}
+module_exit(ohci_omap3_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci-omap3");
 MODULE_AUTHOR("Anand Gadiyar <gadiyar@ti.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V2 4/6] USB: OHCI: make ohci-spear a separate driver
  2013-06-12 15:53 ` [PATCH V2 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (2 preceding siblings ...)
  2013-06-12 15:53   ` [PATCH V2 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
@ 2013-06-12 15:54   ` Manjunath Goudar
  2013-06-18 18:23     ` Alan Stern
  2013-06-12 15:54   ` [PATCH V2 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
  2013-06-12 15:54   ` [PATCH V2 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
  5 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-12 15:54 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the ST OHCI SPEAr host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -debugging stuff isn't needed any more that's what removed.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb at vger.kernel.org
---
 drivers/usb/host/Kconfig      |    8 +++
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 ------
 drivers/usb/host/ohci-spear.c |  140 +++++++++++++++++------------------------
 4 files changed, 65 insertions(+), 102 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index db20e43..46c2f42 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -382,6 +382,14 @@ config USB_OHCI_HCD_OMAP1
 	---help---
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
+config USB_OHCI_HCD_SPEAR
+        tristate "Support for ST SPEAr on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && PLAT_SPEAR
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          ST SPEAr chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 9f2f5f3..26cb6b3 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
+obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index cad51d2..34ec156 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1212,11 +1212,6 @@ MODULE_LICENSE ("GPL");
 #define OF_PLATFORM_DRIVER	ohci_hcd_ppc_of_driver
 #endif
 
-#ifdef CONFIG_PLAT_SPEAR
-#include "ohci-spear.c"
-#define SPEAR_PLATFORM_DRIVER	spear_ohci_hcd_driver
-#endif
-
 #ifdef CONFIG_PPC_PS3
 #include "ohci-ps3.c"
 #define PS3_SYSTEM_BUS_DRIVER	ps3_ohci_driver
@@ -1333,19 +1328,9 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_davinci;
 #endif
 
-#ifdef SPEAR_PLATFORM_DRIVER
-	retval = platform_driver_register(&SPEAR_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_spear;
-#endif
-
 	return retval;
 
 	/* Error path */
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
- error_spear:
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
  error_davinci:
@@ -1403,9 +1388,6 @@ module_init(ohci_hcd_mod_init);
 
 static void __exit ohci_hcd_mod_exit(void)
 {
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index cc9dd9e..31ff3fc 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -11,92 +11,37 @@
 * warranty of any kind, whether express or implied.
 */
 
-#include <linux/signal.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
+#define DRIVER_DESC "OHCI SPEAr driver"
+
+static const char hcd_name[] = "SPEAr-ohci";
 struct spear_ohci {
-	struct ohci_hcd ohci;
 	struct clk *clk;
 };
 
-#define to_spear_ohci(hcd)	(struct spear_ohci *)hcd_to_ohci(hcd)
-
-static void spear_start_ohci(struct spear_ohci *ohci)
-{
-	clk_prepare_enable(ohci->clk);
-}
-
-static void spear_stop_ohci(struct spear_ohci *ohci)
-{
-	clk_disable_unprepare(ohci->clk);
-}
-
-static int ohci_spear_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-	ohci->regs = hcd->regs;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	create_debug_files(ohci);
-
-#ifdef DEBUG
-	ohci_dump(ohci, 1);
-#endif
-	return 0;
-}
-
-static const struct hc_driver ohci_spear_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "SPEAr OHCI",
-	.hcd_priv_size		= sizeof(struct spear_ohci),
-
-	/* generic hardware linkage */
-	.irq			= ohci_irq,
-	.flags			= HCD_USB11 | HCD_MEMORY,
-
-	/* basic lifecycle operations */
-	.start			= ohci_spear_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-
-	/* managing i/o requests and associated device resources */
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	/* scheduling support */
-	.get_frame_number	= ohci_get_frame,
+#define to_spear_ohci(hcd)     (struct spear_ohci *)(hcd_to_ohci(hcd)->priv)
 
-	/* root hub support */
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-
-	.start_port_reset	= ohci_start_port_reset,
-};
+static struct hc_driver __read_mostly ohci_spear_hc_driver;
 
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
 	const struct hc_driver *driver = &ohci_spear_hc_driver;
+	struct ohci_hcd *ohci;
 	struct usb_hcd *hcd = NULL;
 	struct clk *usbh_clk;
-	struct spear_ohci *ohci_p;
+	struct spear_ohci *sohci_p;
 	struct resource *res;
 	int retval, irq;
 
@@ -151,16 +96,18 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 		goto err_put_hcd;
 	}
 
-	ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
-	ohci_p->clk = usbh_clk;
-	spear_start_ohci(ohci_p);
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	sohci_p = to_spear_ohci(hcd);
+	sohci_p->clk = usbh_clk;
+
+	clk_prepare_enable(sohci_p->clk);
+
+	ohci = hcd_to_ohci(hcd);
 
 	retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0);
 	if (retval == 0)
 		return retval;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
 err_put_hcd:
 	usb_put_hcd(hcd);
 fail:
@@ -172,11 +119,11 @@ fail:
 static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	usb_remove_hcd(hcd);
-	if (ohci_p->clk)
-		spear_stop_ohci(ohci_p);
+	if (sohci_p->clk)
+		clk_disable_unprepare(sohci_p->clk);
 
 	usb_put_hcd(hcd);
 	return 0;
@@ -188,13 +135,14 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
+
 	return 0;
 }
 
@@ -202,13 +150,13 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_start_ohci(ohci_p);
+	clk_prepare_enable(sohci_p->clk);
 	ohci_resume(hcd, false);
 	return 0;
 }
@@ -234,4 +182,28 @@ static struct platform_driver spear_ohci_hcd_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides spear_overrides __initconst = {
+	.extra_priv_size = sizeof(struct spear_ohci),
+};
+static int __init ohci_spear_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_spear_hc_driver, &spear_overrides);
+	return platform_driver_register(&spear_ohci_hcd_driver);
+}
+module_init(ohci_spear_init);
+
+static void __exit ohci_spear_cleanup(void)
+{
+	platform_driver_unregister(&spear_ohci_hcd_driver);
+}
+module_exit(ohci_spear_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Deepak Sikri");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:spear-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V2 5/6] USB: OHCI: make ohci-at91 a separate driver
  2013-06-12 15:53 ` [PATCH V2 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (3 preceding siblings ...)
  2013-06-12 15:54   ` [PATCH V2 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
@ 2013-06-12 15:54   ` Manjunath Goudar
  2013-06-19 20:16     ` Alan Stern
  2013-06-12 15:54   ` [PATCH V2 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
  5 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-12 15:54 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI Atmel host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

V2:
 -Set non-standard fields in ohci_at91_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org
---
 drivers/usb/host/Kconfig     |    8 +++
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-at91.c |  148 +++++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c  |   18 -----
 4 files changed, 74 insertions(+), 101 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 46c2f42..e4dc9ab 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_AT91
+        tristate  "Support for Atmel on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && ARCH_AT91
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          Atmel chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 26cb6b3..f3e02c0 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
+obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 2ee1496..fb2f127 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -13,27 +13,41 @@
  */
 
 #include <linux/clk.h>
-#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/atmel.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
 #include <mach/hardware.h>
 #include <asm/gpio.h>
 
 #include <mach/cpu.h>
 
-#ifndef CONFIG_ARCH_AT91
-#error "CONFIG_ARCH_AT91 must be defined."
-#endif
+
+#include "ohci.h"
 
 #define valid_port(index)	((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
 #define at91_for_each_port(index)	\
 		for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++)
 
 /* interface and function clocks; sometimes also an AHB clock */
+
+#define DRIVER_DESC "OHCI Atmel driver"
+
+static const char hcd_name[] = "ohci-atmel";
+
+static struct hc_driver __read_mostly ohci_at91_hc_driver;
 static struct clk *iclk, *fclk, *hclk;
 static int clocked;
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq, u16 wValue,
+			u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
 
 extern int usb_disabled(void);
 
@@ -111,6 +125,8 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
 static int usb_hcd_at91_probe(const struct hc_driver *driver,
 			struct platform_device *pdev)
 {
+	struct at91_usbh_data	*board;
+	struct ohci_hcd	*ohci;
 	int retval;
 	struct usb_hcd *hcd = NULL;
 
@@ -163,8 +179,11 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
 		goto err5;
 	}
 
+	board = hcd->self.controller->platform_data;
+	ohci = hcd_to_ohci(hcd);
+	ohci->num_ports = board->ports;
 	at91_start_hc(pdev);
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	ohci_setup(hcd);
 
 	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
 	if (retval == 0)
@@ -221,36 +240,6 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd,
 }
 
 /*-------------------------------------------------------------------------*/
-
-static int
-ohci_at91_reset (struct usb_hcd *hcd)
-{
-	struct at91_usbh_data	*board = hcd->self.controller->platform_data;
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
-	ohci->num_ports = board->ports;
-	return 0;
-}
-
-static int
-ohci_at91_start (struct usb_hcd *hcd)
-{
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_run(ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-	return 0;
-}
-
 static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
 {
 	if (!valid_port(port))
@@ -281,7 +270,7 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
 static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
 	struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
-	int length = ohci_hub_status_data(hcd, buf);
+	int length = orig_ohci_hub_status_data(hcd, buf);
 	int port;
 
 	at91_for_each_port(port) {
@@ -359,7 +348,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex + 1,
+				buf, wLength);
 	if (ret)
 		goto out;
 
@@ -413,51 +403,6 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 /*-------------------------------------------------------------------------*/
 
-static const struct hc_driver ohci_at91_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"AT91 OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_at91_reset,
-	.start =		ohci_at91_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_at91_hub_status_data,
-	.hub_control =		ohci_at91_hub_control,
-#ifdef CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
 {
 	struct platform_device *pdev = data;
@@ -686,7 +631,7 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
 	 * REVISIT: some boards will be able to turn VBUS off...
 	 */
 	if (at91_suspend_entering_slow_clock()) {
-		ohci_usb_reset (ohci);
+		ohci_restart(ohci);
 		/* flush the writes */
 		(void) ohci_readl (ohci, &ohci->regs->control);
 		at91_stop_clock();
@@ -727,3 +672,40 @@ static struct platform_driver ohci_hcd_at91_driver = {
 		.of_match_table	= of_match_ptr(at91_ohci_dt_ids),
 	},
 };
+
+static int __init ohci_at91_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_at91_hc_driver, NULL);
+
+	/*
+	 * The Atmel HW has some unusual quirks, which require Atmel-specific
+	 * workarounds. We override certain hc_driver functions here to
+	 * achieve that. We explicitly do not enhance ohci_driver_overrides to
+	 * allow this more easily, since this is an unusual case, and we don't
+	 * want to encourage others to override these functions by making it
+	 * too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_at91_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_at91_hc_driver.hub_status_data;
+
+	ohci_at91_hc_driver.hub_status_data	= ohci_at91_hub_status_data;
+	ohci_at91_hc_driver.hub_control		= ohci_at91_hub_control;
+
+	return platform_driver_register(&ohci_hcd_at91_driver);
+}
+module_init(ohci_at91_init);
+
+static void __exit ohci_at91_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_at91_driver);
+}
+module_exit(ohci_at91_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 34ec156..b48c892 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1192,11 +1192,6 @@ MODULE_LICENSE ("GPL");
 #define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver
 #endif
 
-#ifdef CONFIG_ARCH_AT91
-#include "ohci-at91.c"
-#define AT91_PLATFORM_DRIVER	ohci_hcd_at91_driver
-#endif
-
 #ifdef CONFIG_ARCH_LPC32XX
 #include "ohci-nxp.c"
 #define NXP_PLATFORM_DRIVER	usb_hcd_nxp_driver
@@ -1310,12 +1305,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_ep93xx;
 #endif
 
-#ifdef AT91_PLATFORM_DRIVER
-	retval = platform_driver_register(&AT91_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_at91;
-#endif
-
 #ifdef NXP_PLATFORM_DRIVER
 	retval = platform_driver_register(&NXP_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1339,10 +1328,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
  error_nxp:
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
- error_at91:
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
@@ -1394,9 +1379,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef NXP_PLATFORM_DRIVER
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V2 6/6] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-06-12 15:53 ` [PATCH V2 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (4 preceding siblings ...)
  2013-06-12 15:54   ` [PATCH V2 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
@ 2013-06-12 15:54   ` Manjunath Goudar
  2013-06-19 20:38     ` Alan Stern
  5 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-12 15:54 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the Samsung OHCI S3CXXXX host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

V2:
 -Set non-standard fields in ohci_s3c2410_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org
---
 drivers/usb/host/Kconfig        |    8 +++
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ohci-hcd.c     |   18 ------
 drivers/usb/host/ohci-s3c2410.c |  129 ++++++++++++++++++---------------------
 4 files changed, 67 insertions(+), 89 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index e4dc9ab..0b7b0f7 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_S3CXXXX
+        tristate "Support for S3CXXXX on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && (ARCH_S3C24XX) || (ARCH_S3C64XX)
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          S3CXXXX chips.
+
 config USB_OHCI_HCD_AT91
         tristate  "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index f3e02c0..9fa4b3e 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
+obj-$(CONFIG_USB_OHCI_HCD_S3CXXXX)	+= ohci-s3c2410.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index b48c892..b69a49e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1177,11 +1177,6 @@ MODULE_LICENSE ("GPL");
 #define SA1111_DRIVER		ohci_hcd_sa1111_driver
 #endif
 
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
-#include "ohci-s3c2410.c"
-#define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1293,12 +1288,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_tmio;
 #endif
 
-#ifdef S3C2410_PLATFORM_DRIVER
-	retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_s3c2410;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1332,10 +1321,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
- error_s3c2410:
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
  error_tmio:
@@ -1382,9 +1367,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index e125770..8018bb1 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -19,17 +19,34 @@
  * This file is licenced under the GPL.
 */
 
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
+
 
 #define valid_port(idx) ((idx) == 1 || (idx) == 2)
 
 /* clock device associated with the hcd */
 
+
+#define DRIVER_DESC "OHCI S3CXXXX driver"
+
+static const char hcd_name[] = "ohci-s3cxxxx";
+
 static struct clk *clk;
 static struct clk *usb_clk;
 
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq, u16 wValue,
+                        u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
+
 /* forward definitions */
 
 static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
@@ -93,7 +110,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd, char *buf)
 	int orig;
 	int portno;
 
-	orig  = ohci_hub_status_data(hcd, buf);
+	orig  = orig_ohci_hub_status_data(hcd, buf);
 
 	if (info == NULL)
 		return orig;
@@ -164,7 +181,7 @@ static int ohci_s3c2410_hub_control(
 	 * process the request straight away and exit */
 
 	if (info == NULL) {
-		ret = ohci_hub_control(hcd, typeReq, wValue,
+		ret = orig_ohci_hub_control(hcd, typeReq, wValue,
 				       wIndex, buf, wLength);
 		goto out;
 	}
@@ -214,7 +231,7 @@ static int ohci_s3c2410_hub_control(
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
 	if (ret)
 		goto out;
 
@@ -371,10 +388,9 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 		goto err_put;
 	}
 
+	ohci_setup(hcd);
 	s3c2410_start_hc(dev, hcd);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
-
 	retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
 	if (retval != 0)
 		goto err_ioremap;
@@ -391,71 +407,7 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_s3c2410_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-
-static const struct hc_driver ohci_s3c2410_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"S3C24XX OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.start =		ohci_s3c2410_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_s3c2410_hub_status_data,
-	.hub_control =		ohci_s3c2410_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/* device driver */
+static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;
 
 static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
 {
@@ -532,4 +484,39 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {
 	},
 };
 
+static int __init ohci_s3cxxxx_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
+
+	/*
+	 * The Samsung HW has some unusual quirks, which require Sumsung-specific
+	 * workarounds. We override certain hc_driver functions here to
+	 * achieve that. We explicitly do not enhance ohci_driver_overrides to
+	 * allow this more easily, since this is an unusual case, and we don't
+	 * want to encourage others to override these functions by making it
+	 * too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_s3c2410_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_s3c2410_hc_driver.hub_status_data;
+
+	ohci_s3c2410_hc_driver.hub_status_data	= ohci_s3c2410_hub_status_data;
+	ohci_s3c2410_hc_driver.hub_control	= ohci_s3c2410_hub_control;
+
+	return platform_driver_register(&ohci_hcd_s3c2410_driver);
+}
+module_init(ohci_s3cxxxx_init);
+
+static void __exit ohci_s3cxxxx_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_s3c2410_driver);
+}
+module_exit(ohci_s3cxxxx_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:s3c2410-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V2 1/6] USB: OHCI: make ohci-exynos a separate driver
  2013-06-12 15:53   ` [PATCH V2 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
@ 2013-06-18 17:30     ` Alan Stern
  2013-06-20  4:10     ` Jingoo Han
  1 sibling, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-18 17:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 12 Jun 2013, Manjunath Goudar wrote:

> Separate the  Samsung OHCI EXYNOS host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.
> 
> V2:
>  -exynos_ohci_hcd structure assignment error fixed.
>  -Removed multiple usb_create_hcd() from prob funtion.
>  -platform_set_drvdata() called before exynos_ohci_phy_enable().
>  -ohci_setup() removed because it is called in .reset member
>   of the ohci_hc_driver structure

> --- a/drivers/usb/host/ohci-exynos.c
> +++ b/drivers/usb/host/ohci-exynos.c
> @@ -12,24 +12,39 @@
>   */
>  
>  #include <linux/clk.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
>  #include <linux/platform_data/usb-ohci-exynos.h>
>  #include <linux/usb/phy.h>
>  #include <linux/usb/samsung_usb_phy.h>
> +#include <linux/usb.h>
> +#include <linux/usb/hcd.h>
> +#include <linux/usb/otg.h>
> +
> +#include "ohci.h"
> +
> +#define DRIVER_DESC "OHCI exynos driver"

I think the word "EXYNOS" is supposed to be in all capital letters.  
Apart from that,

Acked-by: Alan Stern <stern@rowland.harvard.edu>

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V2 2/6] USB: OHCI: make ohci-omap a separate driver
  2013-06-12 15:53   ` [PATCH V2 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
@ 2013-06-18 17:47     ` Alan Stern
  2013-06-18 18:13     ` Alan Stern
  1 sibling, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-18 17:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 12 Jun 2013, Manjunath Goudar wrote:

> Separate the  TI OHCI OMAP1/2 host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.
> 
> V2:
>  -omap_ohci_clock_power(0) called in usb_hcd_omap_remove().
>  -Removed ohci_setup() call from usb_hcd_omap_probe() and ohci_omap_reset().

You were supposed to remove the call from usb_hcd_omap_probe but leave 
in the call from ohci_omap_reset.

>  -host_enabled and host_initialized variables aren't used for anything
>   thats what removed.


> @@ -188,21 +195,21 @@ static void start_hnp(struct ohci_hcd *ohci)
>  
>  /*-------------------------------------------------------------------------*/
>  
> -static int ohci_omap_init(struct usb_hcd *hcd)
> +static int ohci_omap_reset(struct usb_hcd *hcd)
>  {
>  	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
>  	struct omap_usb_config	*config = hcd->self.controller->platform_data;
>  	int			need_transceiver = (config->otg != 0);
> -	int			ret;
>  
>  	dev_dbg(hcd->self.controller, "starting USB Controller\n");
>  
> -	if (config->otg) {
> +	if (config->otg || config->rwc) {
>  		ohci_to_hcd(ohci)->self.otg_port = config->otg;
>  		/* default/minimum OTG power budget:  8 mA */
>  		ohci_to_hcd(ohci)->power_budget = 8;

These three lines are supposed to run only when config->otg is set, not
when config->rwc is set.  The next two lines can run when either one is
set.

Also, "ohci_to_hcd(ohci)" should be replaced by "hcd".

> +		ohci->hc_control = OHCI_CTRL_RWC;
> +		writel(OHCI_CTRL_RWC, &ohci->regs->control);
>  	}
> -

Don't remove this blank line.

>  	/* boards can use OTG transceivers in non-OTG modes */
>  	need_transceiver = need_transceiver
>  			|| machine_is_omap_h2() || machine_is_omap_h3();
> @@ -238,9 +245,6 @@ static int ohci_omap_init(struct usb_hcd *hcd)
>  		omap_1510_local_bus_init();
>  	}
>  
> -	if ((ret = ohci_init(ohci)) < 0)
> -		return ret;
> -

This should call ohci_setup instead of ohci_init.

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V2 2/6] USB: OHCI: make ohci-omap a separate driver
  2013-06-12 15:53   ` [PATCH V2 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
  2013-06-18 17:47     ` Alan Stern
@ 2013-06-18 18:13     ` Alan Stern
  1 sibling, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-18 18:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 12 Jun 2013, Manjunath Goudar wrote:

> Separate the  TI OHCI OMAP1/2 host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.
> 
> V2:
>  -omap_ohci_clock_power(0) called in usb_hcd_omap_remove().
>  -Removed ohci_setup() call from usb_hcd_omap_probe() and ohci_omap_reset().
>  -host_enabled and host_initialized variables aren't used for anything
>   thats what removed.

There's one more thing I just noticed.


> @@ -188,21 +195,21 @@ static void start_hnp(struct ohci_hcd *ohci)
>  
>  /*-------------------------------------------------------------------------*/
>  
> -static int ohci_omap_init(struct usb_hcd *hcd)
> +static int ohci_omap_reset(struct usb_hcd *hcd)
>  {
>  	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
>  	struct omap_usb_config	*config = hcd->self.controller->platform_data;
>  	int			need_transceiver = (config->otg != 0);
> -	int			ret;
>  
>  	dev_dbg(hcd->self.controller, "starting USB Controller\n");
>  
> -	if (config->otg) {
> +	if (config->otg || config->rwc) {
>  		ohci_to_hcd(ohci)->self.otg_port = config->otg;
>  		/* default/minimum OTG power budget:  8 mA */
>  		ohci_to_hcd(ohci)->power_budget = 8;
> +		ohci->hc_control = OHCI_CTRL_RWC;
> +		writel(OHCI_CTRL_RWC, &ohci->regs->control);

This last line must not appear here, because ohci->regs doesn't get set
until ohci_setup() calls ohci_init().  Removing it entirely is safe
because ohci_run() does the same thing later on.  Or you can move both 
of these last two lines after the call to ohci_setup().

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V2 3/6] USB: OHCI: make ohci-omap3 a separate driver
  2013-06-12 15:53   ` [PATCH V2 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
@ 2013-06-18 18:16     ` Alan Stern
  0 siblings, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-18 18:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 12 Jun 2013, Manjunath Goudar wrote:

> Separate the  TI OHCI OMAP3 host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.
> 
> V2:
>  -ohci_setup() removed because it is called in .reset member
>   of the ohci_hc_driver structure.
>  -The improper multi-line commenting style written in proper way.
>   ('*' characters aligned in vertically).

Generally okay, just one problem...

> @@ -185,7 +118,14 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
>  	pm_runtime_enable(dev);
>  	pm_runtime_get_sync(dev);
>  
> -	ohci_hcd_init(hcd_to_ohci(hcd));
> +	ohci = hcd_to_ohci(hcd);
> +	/*
> +	 * RemoteWakeupConnected has to be set explicitly before
> +	 * calling ohci_run. The reset value of RWC is 0.
> +	 */
> +	ohci->hc_control = OHCI_CTRL_RWC;
> +	writel(OHCI_CTRL_RWC, &ohci->regs->control);

ohci->regs doesn't get set until usb_add_hcd, so this line must not 
appear here.  You can simply remove it.

> +	dev_dbg(hcd->self.controller, "starting OHCI controller\n");
>  
>  	ret = usb_add_hcd(hcd, irq, 0);
>  	if (ret) {

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V2 4/6] USB: OHCI: make ohci-spear a separate driver
  2013-06-12 15:54   ` [PATCH V2 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
@ 2013-06-18 18:23     ` Alan Stern
  0 siblings, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-18 18:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 12 Jun 2013, Manjunath Goudar wrote:

> Separate the ST OHCI SPEAr host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.
> 
> V2:
>  -ohci_setup() removed because it is called in .reset member
>   of the ohci_hc_driver structure.
>  -debugging stuff isn't needed any more that's what removed.

Acked-by: Alan Stern <stern@rowland.harvard.edu>

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V2 5/6] USB: OHCI: make ohci-at91 a separate driver
  2013-06-12 15:54   ` [PATCH V2 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
@ 2013-06-19 20:16     ` Alan Stern
  0 siblings, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-19 20:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 12 Jun 2013, Manjunath Goudar wrote:

> Separate the  TI OHCI Atmel host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.
> 
> V2:
>  -Set non-standard fields in ohci_at91_hc_driver manually, rather than
>   relying on an expanded struct ohci_driver_overrides.
>  -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
>   relying on ohci_hub_control and hub_status_data being exported.
>  -ohci_setup() has been removed because it is called in .reset member
>   of the ohci_hc_driver structure.

> @@ -111,6 +125,8 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
>  static int usb_hcd_at91_probe(const struct hc_driver *driver,
>  			struct platform_device *pdev)
>  {
> +	struct at91_usbh_data	*board;
> +	struct ohci_hcd	*ohci;

Variables are supposed to be not aligned at all (in which case you 
don't use tabs) or all aligned the same way.  In this case you put a 
tab before the "*board"; therefore the "*ohci" should line up with it.

No, this isn't an artifact of my email program.  They really are not
aligned.

> @@ -163,8 +179,11 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
>  		goto err5;
>  	}
>  
> +	board = hcd->self.controller->platform_data;
> +	ohci = hcd_to_ohci(hcd);
> +	ohci->num_ports = board->ports;
>  	at91_start_hc(pdev);
> -	ohci_hcd_init(hcd_to_ohci(hcd));
> +	ohci_setup(hcd);

Didn't you say above that this version of the patch removes the call to 
ohci_setup()?

> @@ -686,7 +631,7 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
>  	 * REVISIT: some boards will be able to turn VBUS off...
>  	 */
>  	if (at91_suspend_entering_slow_clock()) {
> -		ohci_usb_reset (ohci);
> +		ohci_restart(ohci);

Why did you change this?  Did we discuss it earlier?

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V2 6/6] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-06-12 15:54   ` [PATCH V2 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
@ 2013-06-19 20:38     ` Alan Stern
  0 siblings, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-19 20:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 12 Jun 2013, Manjunath Goudar wrote:

> Separate the Samsung OHCI S3CXXXX host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.
> 
> V2:
>  -Set non-standard fields in ohci_s3c2410_hc_driver manually, rather than
>   relying on an expanded struct ohci_driver_overrides.
>  -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
>   relying on ohci_hub_control and hub_status_data being exported.
>  -ohci_setup() has been removed because it is called in .reset member
>   of the ohci_hc_driver structure.

> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index e4dc9ab..0b7b0f7 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
>            Enables support for the on-chip OHCI controller on
>            ST SPEAr chips.
>  
> +config USB_OHCI_HCD_S3CXXXX
> +        tristate "Support for S3CXXXX on-chip OHCI USB controller"
> +        depends on USB_OHCI_HCD && (ARCH_S3C24XX) || (ARCH_S3C64XX)

The use of parentheses here is wrong.

> +static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq, u16 wValue,
> +                        u16 wIndex, char *buf, u16 wLength);

Avoid having more than 80 columns in a line.

> @@ -371,10 +388,9 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
>  		goto err_put;
>  	}
>  
> +	ohci_setup(hcd);
>  	s3c2410_start_hc(dev, hcd);

I thought this patch was supposed to get rid of the call to
ohci_setup()?

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V2 1/6] USB: OHCI: make ohci-exynos a separate driver
  2013-06-12 15:53   ` [PATCH V2 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
  2013-06-18 17:30     ` Alan Stern
@ 2013-06-20  4:10     ` Jingoo Han
  1 sibling, 0 replies; 110+ messages in thread
From: Jingoo Han @ 2013-06-20  4:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, June 13, 2013 12:54 AM, Manjunath Goudar wrote:
> 
> Separate the  Samsung OHCI EXYNOS host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.
> 
> V2:
>  -exynos_ohci_hcd structure assignment error fixed.
>  -Removed multiple usb_create_hcd() from prob funtion.
>  -platform_set_drvdata() called before exynos_ohci_phy_enable().
>  -ohci_setup() removed because it is called in .reset member
>   of the ohci_hc_driver structure
> 
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Jingoo Han <jg1.han@samsung.com>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Cc: Greg KH <greg@kroah.com>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: linux-usb at vger.kernel.org
> ---
>  drivers/usb/host/Kconfig       |    2 +-
>  drivers/usb/host/Makefile      |    1 +
>  drivers/usb/host/ohci-exynos.c |  167 +++++++++++++++++-----------------------
>  drivers/usb/host/ohci-hcd.c    |   18 -----
>  4 files changed, 71 insertions(+), 117 deletions(-)

CC'ed Vivek Gautam

Hi Manjunath Goudar,

It looks good.
I tested this patch on Exynos4210. It works properly.
I really appreciate your work.

Acked-by: Jingoo Han <jg1.han@samsung.com>


Also, I agree on Alan's opinion.
> +#define DRIVER_DESC "OHCI exynos driver"
Please, replace 'exynos' with 'EXYNOS'.

Best regards,
Jingoo Han

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V3 0/6]  USB: OHCI: more bus glues as separate modules
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (7 preceding siblings ...)
  2013-06-12 15:53 ` [PATCH V2 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
@ 2013-06-25  6:23 ` Manjunath Goudar
  2013-06-25  6:23   ` [PATCH V3 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
                     ` (5 more replies)
  2013-07-22  9:19 ` [PATCH 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (5 subsequent siblings)
  14 siblings, 6 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-25  6:23 UTC (permalink / raw)
  To: linux-arm-kernel

These patches are for separating the SOC On-Chip ohci host controller
from ohci-hcd host code into its own driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

V2:
  In patch 5/6 and 6/6:
  -Set non-standard fields in hc_driver manually, rather than
   relying on an expanded struct ohci_driver_overrides.
  -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
   relying on ohci_hub_control and hub_status_data being exported.

  In patch 1/6 to 4/6
  -ohci_setup() has been removed because it is called in .reset member
   of the ohci_hc_driver structure.

V3:
 In patch 5/6 and 6/6:
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.
 
 In patch 5/6:
 -The ohci_restart() function is not required in  current scenario,
  only discarding connection state of integrated transceivers is sufficient,
  for this directly handling ohci->hc_control.
 
 In patch 2/6 :
 -rewritten if (config->otg || config->rwc) block statements into
  two separate 'if blocks' to handle below scenarios
  1. config->otg set scenario.
  2. if any of these (config->otg, config->rwc) are set, this
     scenario should be handled only after ohci_setup()

 In patch 1/6 and 4/6:
  No change. 

Manjunath Goudar (6):
  USB: OHCI: make ohci-exynos a separate driver
  USB: OHCI: make ohci-omap a separate driver
  USB: OHCI: make ohci-omap3 a separate driver
  USB: OHCI: make ohci-spear a separate driver
  USB: OHCI: make ohci-at91 a separate driver
  USB: OHCI: make ohci-s3c2410 a separate driver

 drivers/usb/host/Kconfig        |   30 ++++++-
 drivers/usb/host/Makefile       |    6 ++
 drivers/usb/host/ohci-at91.c    |  151 ++++++++++++++++-------------------
 drivers/usb/host/ohci-exynos.c  |  167 ++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c     |  108 -------------------------
 drivers/usb/host/ohci-omap.c    |  157 +++++++++++++-----------------------
 drivers/usb/host/ohci-omap3.c   |  113 ++++++++------------------
 drivers/usb/host/ohci-s3c2410.c |  128 +++++++++++++-----------------
 drivers/usb/host/ohci-spear.c   |  140 +++++++++++++-------------------
 9 files changed, 369 insertions(+), 631 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V3 1/6] USB: OHCI: make ohci-exynos a separate driver
  2013-06-25  6:23 ` [PATCH V3 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
@ 2013-06-25  6:23   ` Manjunath Goudar
  2013-06-25  6:23   ` [PATCH V3 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-25  6:23 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  Samsung OHCI EXYNOS host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Cc: Vivek Gautam <gautam.vivek@samsung.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -exynos_ohci_hcd structure assignment error fixed.
 -Removed multiple usb_create_hcd() from prob funtion.
 -platform_set_drvdata() called before exynos_ohci_phy_enable().
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure

V3:
 -No major changes only "exynos" written in capital letters
  in "OHCI exynos driver".
---
 drivers/usb/host/Kconfig       |    2 +-
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ohci-exynos.c |  167 +++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c    |   18 -----
 4 files changed, 71 insertions(+), 117 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index f35f71e..75456f2 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -463,7 +463,7 @@ config USB_OHCI_SH
 	  If you use the PCI OHCI controller, this option is not necessary.
 
 config USB_OHCI_EXYNOS
-	boolean "OHCI support for Samsung EXYNOS SoC Series"
+	tristate "OHCI support for Samsung EXYNOS SoC Series"
 	depends on ARCH_EXYNOS
 	help
 	 Enable support for the Samsung Exynos SOC's on-chip OHCI controller.
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index d1a34e0..bf4a4b2 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
+obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index b0b542c..ae6068d 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -12,24 +12,39 @@
  */
 
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-exynos.h>
 #include <linux/usb/phy.h>
 #include <linux/usb/samsung_usb_phy.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include "ohci.h"
+
+#define DRIVER_DESC "OHCI EXYNOS driver"
+
+static const char hcd_name[] = "ohci-exynos";
+static struct hc_driver __read_mostly exynos_ohci_hc_driver;
+
+#define to_exynos_ohci(hcd) (struct exynos_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
 
 struct exynos_ohci_hcd {
-	struct device *dev;
-	struct usb_hcd *hcd;
 	struct clk *clk;
 	struct usb_phy *phy;
 	struct usb_otg *otg;
 	struct exynos4_ohci_platdata *pdata;
 };
 
-static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_enable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_init(exynos_ohci->phy);
@@ -37,9 +52,10 @@ static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
 }
 
-static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_disable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_shutdown(exynos_ohci->phy);
@@ -47,63 +63,11 @@ static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
 }
 
-static int ohci_exynos_reset(struct usb_hcd *hcd)
-{
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-static int ohci_exynos_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci);
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-static const struct hc_driver exynos_ohci_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "EXYNOS OHCI Host Controller",
-	.hcd_priv_size		= sizeof(struct ohci_hcd),
-
-	.irq			= ohci_irq,
-	.flags			= HCD_MEMORY|HCD_USB11,
-
-	.reset			= ohci_exynos_reset,
-	.start			= ohci_exynos_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-
-	.get_frame_number	= ohci_get_frame,
-
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-	.start_port_reset	= ohci_start_port_reset,
-};
-
 static int exynos_ohci_probe(struct platform_device *pdev)
 {
 	struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_ohci_hcd *exynos_ohci;
 	struct usb_hcd *hcd;
-	struct ohci_hcd *ohci;
 	struct resource *res;
 	struct usb_phy *phy;
 	int irq;
@@ -119,10 +83,14 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	if (!pdev->dev.coherent_dma_mask)
 		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
-	exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd),
-					GFP_KERNEL);
-	if (!exynos_ohci)
+	hcd = usb_create_hcd(&exynos_ohci_hc_driver,
+				&pdev->dev, dev_name(&pdev->dev));
+	if (!hcd) {
+		dev_err(&pdev->dev, "Unable to create HCD\n");
 		return -ENOMEM;
+	}
+
+	exynos_ohci = to_exynos_ohci(hcd);
 
 	if (of_device_is_compatible(pdev->dev.of_node,
 					"samsung,exynos5440-ohci"))
@@ -143,17 +111,6 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	}
 
 skip_phy:
-
-	exynos_ohci->dev = &pdev->dev;
-
-	hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
-					dev_name(&pdev->dev));
-	if (!hcd) {
-		dev_err(&pdev->dev, "Unable to create HCD\n");
-		return -ENOMEM;
-	}
-
-	exynos_ohci->hcd = hcd;
 	exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");
 
 	if (IS_ERR(exynos_ohci->clk)) {
@@ -190,26 +147,21 @@ skip_phy:
 	}
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	platform_set_drvdata(pdev, hcd);
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to add USB HCD\n");
 		goto fail_add_hcd;
 	}
-
-	platform_set_drvdata(pdev, exynos_ohci);
-
 	return 0;
 
 fail_add_hcd:
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 fail_io:
 	clk_disable_unprepare(exynos_ohci->clk);
 fail_clk:
@@ -219,16 +171,15 @@ fail_clk:
 
 static int exynos_ohci_remove(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	usb_remove_hcd(hcd);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -239,8 +190,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
 
 static void exynos_ohci_shutdown(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
 	if (hcd->driver->shutdown)
 		hcd->driver->shutdown(hcd);
@@ -249,9 +199,10 @@ static void exynos_ohci_shutdown(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int exynos_ohci_suspend(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	struct platform_device *pdev = to_platform_device(dev);
 	unsigned long flags;
 	int rc = 0;
 
@@ -271,10 +222,9 @@ static int exynos_ohci_suspend(struct device *dev)
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -286,16 +236,16 @@ fail:
 
 static int exynos_ohci_resume(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd			= dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci	= to_exynos_ohci(hcd);
+	struct platform_device *pdev		= to_platform_device(dev);
 
 	clk_prepare_enable(exynos_ohci->clk);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	ohci_resume(hcd, false);
 
@@ -306,6 +256,10 @@ static int exynos_ohci_resume(struct device *dev)
 #define exynos_ohci_resume	NULL
 #endif
 
+static const struct ohci_driver_overrides exynos_overrides __initconst = {
+	.extra_priv_size =	sizeof(struct exynos_ohci_hcd),
+};
+
 static const struct dev_pm_ops exynos_ohci_pm_ops = {
 	.suspend	= exynos_ohci_suspend,
 	.resume		= exynos_ohci_resume,
@@ -331,6 +285,23 @@ static struct platform_driver exynos_ohci_driver = {
 		.of_match_table	= of_match_ptr(exynos_ohci_match),
 	}
 };
+static int __init ohci_exynos_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&exynos_ohci_hc_driver, &exynos_overrides);
+	return platform_driver_register(&exynos_ohci_driver);
+}
+module_init(ohci_exynos_init);
+
+static void __exit ohci_exynos_cleanup(void)
+{
+	platform_driver_unregister(&exynos_ohci_driver);
+}
+module_exit(ohci_exynos_cleanup);
 
 MODULE_ALIAS("platform:exynos-ohci");
 MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index a9d3437..2980bb6 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_EXYNOS
-#include "ohci-exynos.c"
-#define EXYNOS_PLATFORM_DRIVER	exynos_ohci_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP1
 #include "ohci-omap.c"
 #define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
@@ -1336,12 +1331,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_s3c2410;
 #endif
 
-#ifdef EXYNOS_PLATFORM_DRIVER
-	retval = platform_driver_register(&EXYNOS_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_exynos;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1395,10 +1384,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
- error_exynos:
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
  error_s3c2410:
@@ -1463,9 +1448,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V3 2/6] USB: OHCI: make ohci-omap a separate driver
  2013-06-25  6:23 ` [PATCH V3 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
  2013-06-25  6:23   ` [PATCH V3 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
@ 2013-06-25  6:23   ` Manjunath Goudar
  2013-07-18 15:50     ` Alan Stern
  2013-06-25  6:23   ` [PATCH V3 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-25  6:23 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP1/2 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb at vger.kernel.org

V2:
 -omap_ohci_clock_power(0) called in usb_hcd_omap_remove().
 -Removed ohci_setup() call from usb_hcd_omap_probe().
 -host_enabled and host_initialized variables aren't used for anything
  thats what removed.

V3:
 -rewritten if (config->otg || config->rwc) block statements into
  two separate 'if blocks' to handle below scenarios
  1. config->otg set scenario.
  2. if any of these (config->otg, config->rwc) are set, this
     scenario should be handled only after ohci_setup()
---
 drivers/usb/host/Kconfig     |    2 +-
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-hcd.c  |   18 -----
 drivers/usb/host/ohci-omap.c |  157 +++++++++++++++---------------------------
 4 files changed, 56 insertions(+), 122 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 75456f2..7a87c72 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -376,7 +376,7 @@ config USB_OHCI_HCD
 if USB_OHCI_HCD
 
 config USB_OHCI_HCD_OMAP1
-	bool "OHCI support for OMAP1/2 chips"
+	tristate "OHCI support for OMAP1/2 chips"
 	depends on ARCH_OMAP1
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index bf4a4b2..52f2c44 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 2980bb6..1abc1e7 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP1
-#include "ohci-omap.c"
-#define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP3
 #include "ohci-omap3.c"
 #define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
@@ -1289,12 +1284,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP1_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP1_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap1_platform;
-#endif
-
 #ifdef OMAP3_PLATFORM_DRIVER
 	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1408,10 +1397,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
  error_omap3_platform:
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
- error_omap1_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1466,9 +1451,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OMAP3_PLATFORM_DRIVER
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 8747fa6..10ba58d 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -14,12 +14,21 @@
  * This file is licenced under the GPL.
  */
 
-#include <linux/signal.h>
-#include <linux/jiffies.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
 #include <asm/io.h>
 #include <asm/mach-types.h>
@@ -42,10 +51,7 @@
 #define OMAP1510_LB_MMU_RAM_H	0xfffec234
 #define OMAP1510_LB_MMU_RAM_L	0xfffec238
 
-
-#ifndef CONFIG_ARCH_OMAP
-#error "This file is OMAP bus glue.  CONFIG_OMAP must be defined."
-#endif
+#define DRIVER_DESC "OHCI OMAP driver"
 
 #ifdef CONFIG_TPS65010
 #include <linux/i2c/tps65010.h>
@@ -68,8 +74,9 @@ extern int ocpi_enable(void);
 
 static struct clk *usb_host_ck;
 static struct clk *usb_dc_ck;
-static int host_enabled;
-static int host_initialized;
+
+static const char hcd_name[] = "ohci-omap";
+static struct hc_driver __read_mostly ohci_omap_hc_driver;
 
 static void omap_ohci_clock_power(int on)
 {
@@ -188,7 +195,7 @@ static void start_hnp(struct ohci_hcd *ohci)
 
 /*-------------------------------------------------------------------------*/
 
-static int ohci_omap_init(struct usb_hcd *hcd)
+static int ohci_omap_reset(struct usb_hcd *hcd)
 {
 	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
 	struct omap_usb_config	*config = hcd->self.controller->platform_data;
@@ -198,9 +205,9 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	dev_dbg(hcd->self.controller, "starting USB Controller\n");
 
 	if (config->otg) {
-		ohci_to_hcd(ohci)->self.otg_port = config->otg;
+		hcd->self.otg_port = config->otg;
 		/* default/minimum OTG power budget:  8 mA */
-		ohci_to_hcd(ohci)->power_budget = 8;
+		hcd->power_budget = 8;
 	}
 
 	/* boards can use OTG transceivers in non-OTG modes */
@@ -238,9 +245,15 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 		omap_1510_local_bus_init();
 	}
 
-	if ((ret = ohci_init(ohci)) < 0)
+	ret = ohci_setup(hcd);
+	if (ret < 0)
 		return ret;
 
+	if (config->otg || config->rwc) {
+		ohci->hc_control = OHCI_CTRL_RWC;
+		writel(OHCI_CTRL_RWC, &ohci->regs->control);
+	}
+
 	/* board-specific power switching and overcurrent support */
 	if (machine_is_omap_osk() || machine_is_omap_innovator()) {
 		u32	rh = roothub_a (ohci);
@@ -281,14 +294,6 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	return 0;
 }
 
-static void ohci_omap_stop(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
-	ohci_stop(hcd);
-	omap_ohci_clock_power(0);
-}
-
-
 /*-------------------------------------------------------------------------*/
 
 /**
@@ -304,7 +309,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 {
 	int retval, irq;
 	struct usb_hcd *hcd = 0;
-	struct ohci_hcd *ohci;
 
 	if (pdev->num_resources != 2) {
 		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
@@ -354,12 +358,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 		goto err2;
 	}
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
-
-	host_initialized = 0;
-	host_enabled = 1;
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		retval = -ENXIO;
@@ -369,11 +367,7 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 	if (retval)
 		goto err3;
 
-	host_initialized = 1;
-
-	if (!host_enabled)
-		omap_ohci_clock_power(0);
-
+	omap_ohci_clock_power(0);
 	return 0;
 err3:
 	iounmap(hcd->regs);
@@ -402,6 +396,8 @@ err0:
 static inline void
 usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
+	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
+	omap_ohci_clock_power(0);
 	usb_remove_hcd(hcd);
 	if (!IS_ERR_OR_NULL(hcd->phy)) {
 		(void) otg_set_host(hcd->phy->otg, 0);
@@ -418,76 +414,6 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_omap_start (struct usb_hcd *hcd)
-{
-	struct omap_usb_config *config;
-	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ret;
-
-	if (!host_enabled)
-		return 0;
-	config = hcd->self.controller->platform_data;
-	if (config->otg || config->rwc) {
-		ohci->hc_control = OHCI_CTRL_RWC;
-		writel(OHCI_CTRL_RWC, &ohci->regs->control);
-	}
-
-	if ((ret = ohci_run (ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop (hcd);
-		return ret;
-	}
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_omap_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap_init,
-	.start =		ohci_omap_start,
-	.stop =			ohci_omap_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static int ohci_hcd_omap_drv_probe(struct platform_device *dev)
 {
 	return usb_hcd_omap_probe(&ohci_omap_hc_driver, dev);
@@ -553,4 +479,29 @@ static struct platform_driver ohci_hcd_omap_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides omap_overrides __initconst = {
+	.product_desc	= "OMAP OHCI",
+	.reset		= ohci_omap_reset
+};
+
+static int __init ohci_omap_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap_hc_driver, &omap_overrides);
+	return platform_driver_register(&ohci_hcd_omap_driver);
+}
+module_init(ohci_omap_init);
+
+static void __exit ohci_omap_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap_driver);
+}
+module_exit(ohci_omap_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V3 3/6] USB: OHCI: make ohci-omap3 a separate driver
  2013-06-25  6:23 ` [PATCH V3 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
  2013-06-25  6:23   ` [PATCH V3 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
  2013-06-25  6:23   ` [PATCH V3 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
@ 2013-06-25  6:23   ` Manjunath Goudar
  2013-06-25 18:14     ` Alan Stern
  2013-06-25  6:23   ` [PATCH V3 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
                     ` (2 subsequent siblings)
  5 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-25  6:23 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP3 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Anand Gadiyar <gadiyar@ti.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb at vger.kernel.org

V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -The improper multi-line commenting style written in proper way.
  ('*' characters aligned in vertically).

V3:
 -RemoteWakeupConnected setting has been removed.
---
 drivers/usb/host/Kconfig      |    2 +-
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 -------
 drivers/usb/host/ohci-omap3.c |  113 ++++++++++++-----------------------------
 4 files changed, 34 insertions(+), 100 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 7a87c72..db20e43 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -383,7 +383,7 @@ config USB_OHCI_HCD_OMAP1
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
 config USB_OHCI_HCD_OMAP3
-	bool "OHCI support for OMAP3 and later chips"
+	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 52f2c44..9f2f5f3 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 1abc1e7..cad51d2 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP3
-#include "ohci-omap3.c"
-#define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1284,12 +1279,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP3_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap3_platform;
-#endif
-
 #ifdef OF_PLATFORM_DRIVER
 	retval = platform_driver_register(&OF_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1393,10 +1382,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
  error_of_platform:
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
- error_omap3_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1448,9 +1433,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OF_PLATFORM_DRIVER
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index 8f71357..f2de21b 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -29,90 +29,22 @@
  *	- add kernel-doc
  */
 
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/of.h>
-#include <linux/dma-mapping.h>
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_init(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "starting OHCI controller\n");
-
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	/*
-	 * RemoteWakeupConnected has to be set explicitly before
-	 * calling ohci_run. The reset value of RWC is 0.
-	 */
-	ohci->hc_control = OHCI_CTRL_RWC;
-	writel(OHCI_CTRL_RWC, &ohci->regs->control);
-
-	ret = ohci_run(ohci);
-
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-	}
-
-	return ret;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_omap3_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP3 OHCI Host Controller",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap3_init,
-	.start =		ohci_omap3_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
+#include "ohci.h"
 
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
+#define DRIVER_DESC "OHCI OMAP3 driver"
 
-/*-------------------------------------------------------------------------*/
+static const char hcd_name[] = "ohci-omap3";
+static struct hc_driver __read_mostly ohci_omap3_hc_driver;
 
 /*
  * configure so an HC device and id are always provided
@@ -129,6 +61,7 @@ static const struct hc_driver ohci_omap3_hc_driver = {
 static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 {
 	struct device		*dev = &pdev->dev;
+	struct ohci_hcd		*ohci;
 	struct usb_hcd		*hcd = NULL;
 	void __iomem		*regs = NULL;
 	struct resource		*res;
@@ -185,8 +118,6 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
-
 	ret = usb_add_hcd(hcd, irq, 0);
 	if (ret) {
 		dev_dbg(dev, "failed to add hcd with err %d\n", ret);
@@ -256,5 +187,25 @@ static struct platform_driver ohci_hcd_omap3_driver = {
 	},
 };
 
+static int __init ohci_omap3_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap3_hc_driver, NULL);
+	return platform_driver_register(&ohci_hcd_omap3_driver);
+}
+module_init(ohci_omap3_init);
+
+static void __exit ohci_omap3_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap3_driver);
+}
+module_exit(ohci_omap3_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci-omap3");
 MODULE_AUTHOR("Anand Gadiyar <gadiyar@ti.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V3 4/6] USB: OHCI: make ohci-spear a separate driver
  2013-06-25  6:23 ` [PATCH V3 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (2 preceding siblings ...)
  2013-06-25  6:23   ` [PATCH V3 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
@ 2013-06-25  6:23   ` Manjunath Goudar
  2013-06-25  6:23   ` [PATCH V3 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
  2013-06-25  6:23   ` [PATCH V3 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
  5 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-25  6:23 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the ST OHCI SPEAr host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -debugging stuff isn't needed any more that's what removed.

V3:
 No change.
---
 drivers/usb/host/Kconfig      |    8 +++
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 ------
 drivers/usb/host/ohci-spear.c |  140 +++++++++++++++++------------------------
 4 files changed, 65 insertions(+), 102 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index db20e43..46c2f42 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -382,6 +382,14 @@ config USB_OHCI_HCD_OMAP1
 	---help---
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
+config USB_OHCI_HCD_SPEAR
+        tristate "Support for ST SPEAr on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && PLAT_SPEAR
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          ST SPEAr chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 9f2f5f3..26cb6b3 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
+obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index cad51d2..34ec156 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1212,11 +1212,6 @@ MODULE_LICENSE ("GPL");
 #define OF_PLATFORM_DRIVER	ohci_hcd_ppc_of_driver
 #endif
 
-#ifdef CONFIG_PLAT_SPEAR
-#include "ohci-spear.c"
-#define SPEAR_PLATFORM_DRIVER	spear_ohci_hcd_driver
-#endif
-
 #ifdef CONFIG_PPC_PS3
 #include "ohci-ps3.c"
 #define PS3_SYSTEM_BUS_DRIVER	ps3_ohci_driver
@@ -1333,19 +1328,9 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_davinci;
 #endif
 
-#ifdef SPEAR_PLATFORM_DRIVER
-	retval = platform_driver_register(&SPEAR_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_spear;
-#endif
-
 	return retval;
 
 	/* Error path */
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
- error_spear:
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
  error_davinci:
@@ -1403,9 +1388,6 @@ module_init(ohci_hcd_mod_init);
 
 static void __exit ohci_hcd_mod_exit(void)
 {
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index cc9dd9e..31ff3fc 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -11,92 +11,37 @@
 * warranty of any kind, whether express or implied.
 */
 
-#include <linux/signal.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
+#define DRIVER_DESC "OHCI SPEAr driver"
+
+static const char hcd_name[] = "SPEAr-ohci";
 struct spear_ohci {
-	struct ohci_hcd ohci;
 	struct clk *clk;
 };
 
-#define to_spear_ohci(hcd)	(struct spear_ohci *)hcd_to_ohci(hcd)
-
-static void spear_start_ohci(struct spear_ohci *ohci)
-{
-	clk_prepare_enable(ohci->clk);
-}
-
-static void spear_stop_ohci(struct spear_ohci *ohci)
-{
-	clk_disable_unprepare(ohci->clk);
-}
-
-static int ohci_spear_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-	ohci->regs = hcd->regs;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	create_debug_files(ohci);
-
-#ifdef DEBUG
-	ohci_dump(ohci, 1);
-#endif
-	return 0;
-}
-
-static const struct hc_driver ohci_spear_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "SPEAr OHCI",
-	.hcd_priv_size		= sizeof(struct spear_ohci),
-
-	/* generic hardware linkage */
-	.irq			= ohci_irq,
-	.flags			= HCD_USB11 | HCD_MEMORY,
-
-	/* basic lifecycle operations */
-	.start			= ohci_spear_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-
-	/* managing i/o requests and associated device resources */
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	/* scheduling support */
-	.get_frame_number	= ohci_get_frame,
+#define to_spear_ohci(hcd)     (struct spear_ohci *)(hcd_to_ohci(hcd)->priv)
 
-	/* root hub support */
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-
-	.start_port_reset	= ohci_start_port_reset,
-};
+static struct hc_driver __read_mostly ohci_spear_hc_driver;
 
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
 	const struct hc_driver *driver = &ohci_spear_hc_driver;
+	struct ohci_hcd *ohci;
 	struct usb_hcd *hcd = NULL;
 	struct clk *usbh_clk;
-	struct spear_ohci *ohci_p;
+	struct spear_ohci *sohci_p;
 	struct resource *res;
 	int retval, irq;
 
@@ -151,16 +96,18 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 		goto err_put_hcd;
 	}
 
-	ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
-	ohci_p->clk = usbh_clk;
-	spear_start_ohci(ohci_p);
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	sohci_p = to_spear_ohci(hcd);
+	sohci_p->clk = usbh_clk;
+
+	clk_prepare_enable(sohci_p->clk);
+
+	ohci = hcd_to_ohci(hcd);
 
 	retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0);
 	if (retval == 0)
 		return retval;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
 err_put_hcd:
 	usb_put_hcd(hcd);
 fail:
@@ -172,11 +119,11 @@ fail:
 static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	usb_remove_hcd(hcd);
-	if (ohci_p->clk)
-		spear_stop_ohci(ohci_p);
+	if (sohci_p->clk)
+		clk_disable_unprepare(sohci_p->clk);
 
 	usb_put_hcd(hcd);
 	return 0;
@@ -188,13 +135,14 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
+
 	return 0;
 }
 
@@ -202,13 +150,13 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_start_ohci(ohci_p);
+	clk_prepare_enable(sohci_p->clk);
 	ohci_resume(hcd, false);
 	return 0;
 }
@@ -234,4 +182,28 @@ static struct platform_driver spear_ohci_hcd_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides spear_overrides __initconst = {
+	.extra_priv_size = sizeof(struct spear_ohci),
+};
+static int __init ohci_spear_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_spear_hc_driver, &spear_overrides);
+	return platform_driver_register(&spear_ohci_hcd_driver);
+}
+module_init(ohci_spear_init);
+
+static void __exit ohci_spear_cleanup(void)
+{
+	platform_driver_unregister(&spear_ohci_hcd_driver);
+}
+module_exit(ohci_spear_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Deepak Sikri");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:spear-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V3 5/6] USB: OHCI: make ohci-at91 a separate driver
  2013-06-25  6:23 ` [PATCH V3 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (3 preceding siblings ...)
  2013-06-25  6:23   ` [PATCH V3 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
@ 2013-06-25  6:23   ` Manjunath Goudar
  2013-07-18 20:51     ` Alan Stern
  2013-06-25  6:23   ` [PATCH V3 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
  5 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-25  6:23 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI Atmel host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -Set non-standard fields in ohci_at91_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

V3:
 -The ohci_restart() function is not required in  current scenario,
  only discarding connection state of integrated transceivers is sufficient,
  for this directly handling ohci->hc_control.
---
 drivers/usb/host/Kconfig     |    8 +++
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-at91.c |  151 +++++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c  |   18 -----
 4 files changed, 77 insertions(+), 101 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 46c2f42..e4dc9ab 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_AT91
+        tristate  "Support for Atmel on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && ARCH_AT91
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          Atmel chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 26cb6b3..f3e02c0 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
+obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 2ee1496..4c01759 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -13,27 +13,41 @@
  */
 
 #include <linux/clk.h>
-#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/atmel.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
 #include <mach/hardware.h>
 #include <asm/gpio.h>
 
 #include <mach/cpu.h>
 
-#ifndef CONFIG_ARCH_AT91
-#error "CONFIG_ARCH_AT91 must be defined."
-#endif
+
+#include "ohci.h"
 
 #define valid_port(index)	((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
 #define at91_for_each_port(index)	\
 		for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++)
 
 /* interface and function clocks; sometimes also an AHB clock */
+
+#define DRIVER_DESC "OHCI Atmel driver"
+
+static const char hcd_name[] = "ohci-atmel";
+
+static struct hc_driver __read_mostly ohci_at91_hc_driver;
 static struct clk *iclk, *fclk, *hclk;
 static int clocked;
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq, u16 wValue,
+			u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
 
 extern int usb_disabled(void);
 
@@ -111,6 +125,8 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
 static int usb_hcd_at91_probe(const struct hc_driver *driver,
 			struct platform_device *pdev)
 {
+	struct at91_usbh_data *board;
+	struct ohci_hcd *ohci;
 	int retval;
 	struct usb_hcd *hcd = NULL;
 
@@ -163,8 +179,10 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
 		goto err5;
 	}
 
+	board = hcd->self.controller->platform_data;
+	ohci = hcd_to_ohci(hcd);
+	ohci->num_ports = board->ports;
 	at91_start_hc(pdev);
-	ohci_hcd_init(hcd_to_ohci(hcd));
 
 	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
 	if (retval == 0)
@@ -221,36 +239,6 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd,
 }
 
 /*-------------------------------------------------------------------------*/
-
-static int
-ohci_at91_reset (struct usb_hcd *hcd)
-{
-	struct at91_usbh_data	*board = hcd->self.controller->platform_data;
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
-	ohci->num_ports = board->ports;
-	return 0;
-}
-
-static int
-ohci_at91_start (struct usb_hcd *hcd)
-{
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_run(ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-	return 0;
-}
-
 static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
 {
 	if (!valid_port(port))
@@ -281,7 +269,7 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
 static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
 	struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
-	int length = ohci_hub_status_data(hcd, buf);
+	int length = orig_ohci_hub_status_data(hcd, buf);
 	int port;
 
 	at91_for_each_port(port) {
@@ -359,7 +347,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex + 1,
+				buf, wLength);
 	if (ret)
 		goto out;
 
@@ -413,51 +402,6 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 /*-------------------------------------------------------------------------*/
 
-static const struct hc_driver ohci_at91_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"AT91 OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_at91_reset,
-	.start =		ohci_at91_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_at91_hub_status_data,
-	.hub_control =		ohci_at91_hub_control,
-#ifdef CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
 {
 	struct platform_device *pdev = data;
@@ -686,7 +630,11 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
 	 * REVISIT: some boards will be able to turn VBUS off...
 	 */
 	if (at91_suspend_entering_slow_clock()) {
-		ohci_usb_reset (ohci);
+		ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
+		ohci->hc_control &= OHCI_CTRL_RWC;
+		ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
+		ohci->rh_state = OHCI_RH_HALTED;
+
 		/* flush the writes */
 		(void) ohci_readl (ohci, &ohci->regs->control);
 		at91_stop_clock();
@@ -727,3 +675,40 @@ static struct platform_driver ohci_hcd_at91_driver = {
 		.of_match_table	= of_match_ptr(at91_ohci_dt_ids),
 	},
 };
+
+static int __init ohci_at91_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_at91_hc_driver, NULL);
+
+	/*
+	 * The Atmel HW has some unusual quirks, which require Atmel-specific
+	 * workarounds. We override certain hc_driver functions here to
+	 * achieve that. We explicitly do not enhance ohci_driver_overrides to
+	 * allow this more easily, since this is an unusual case, and we don't
+	 * want to encourage others to override these functions by making it
+	 * too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_at91_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_at91_hc_driver.hub_status_data;
+
+	ohci_at91_hc_driver.hub_status_data	= ohci_at91_hub_status_data;
+	ohci_at91_hc_driver.hub_control		= ohci_at91_hub_control;
+
+	return platform_driver_register(&ohci_hcd_at91_driver);
+}
+module_init(ohci_at91_init);
+
+static void __exit ohci_at91_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_at91_driver);
+}
+module_exit(ohci_at91_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 34ec156..b48c892 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1192,11 +1192,6 @@ MODULE_LICENSE ("GPL");
 #define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver
 #endif
 
-#ifdef CONFIG_ARCH_AT91
-#include "ohci-at91.c"
-#define AT91_PLATFORM_DRIVER	ohci_hcd_at91_driver
-#endif
-
 #ifdef CONFIG_ARCH_LPC32XX
 #include "ohci-nxp.c"
 #define NXP_PLATFORM_DRIVER	usb_hcd_nxp_driver
@@ -1310,12 +1305,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_ep93xx;
 #endif
 
-#ifdef AT91_PLATFORM_DRIVER
-	retval = platform_driver_register(&AT91_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_at91;
-#endif
-
 #ifdef NXP_PLATFORM_DRIVER
 	retval = platform_driver_register(&NXP_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1339,10 +1328,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
  error_nxp:
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
- error_at91:
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
@@ -1394,9 +1379,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef NXP_PLATFORM_DRIVER
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V3 6/6] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-06-25  6:23 ` [PATCH V3 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (4 preceding siblings ...)
  2013-06-25  6:23   ` [PATCH V3 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
@ 2013-06-25  6:23   ` Manjunath Goudar
  2013-07-18 20:38     ` Alan Stern
  5 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-06-25  6:23 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the Samsung OHCI S3CXXXX host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -Set non-standard fields in ohci_s3c2410_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.

V3:
 -Kconfig wrong parentheses discription fixed.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.
---
 drivers/usb/host/Kconfig        |    8 +++
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ohci-hcd.c     |   18 ------
 drivers/usb/host/ohci-s3c2410.c |  128 +++++++++++++++++----------------------
 4 files changed, 66 insertions(+), 89 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index e4dc9ab..f19524f 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_S3CXXXX
+        tristate "Support for S3CXXXX on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX)
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          S3CXXXX chips.
+
 config USB_OHCI_HCD_AT91
         tristate  "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index f3e02c0..9fa4b3e 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
+obj-$(CONFIG_USB_OHCI_HCD_S3CXXXX)	+= ohci-s3c2410.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index b48c892..b69a49e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1177,11 +1177,6 @@ MODULE_LICENSE ("GPL");
 #define SA1111_DRIVER		ohci_hcd_sa1111_driver
 #endif
 
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
-#include "ohci-s3c2410.c"
-#define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1293,12 +1288,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_tmio;
 #endif
 
-#ifdef S3C2410_PLATFORM_DRIVER
-	retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_s3c2410;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1332,10 +1321,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
- error_s3c2410:
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
  error_tmio:
@@ -1382,9 +1367,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index e125770..b0f6644 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -19,17 +19,34 @@
  * This file is licenced under the GPL.
 */
 
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
+
 
 #define valid_port(idx) ((idx) == 1 || (idx) == 2)
 
 /* clock device associated with the hcd */
 
+
+#define DRIVER_DESC "OHCI S3CXXXX driver"
+
+static const char hcd_name[] = "ohci-s3cxxxx";
+
 static struct clk *clk;
 static struct clk *usb_clk;
 
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+			u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
+
 /* forward definitions */
 
 static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
@@ -93,7 +110,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd, char *buf)
 	int orig;
 	int portno;
 
-	orig  = ohci_hub_status_data(hcd, buf);
+	orig  = orig_ohci_hub_status_data(hcd, buf);
 
 	if (info == NULL)
 		return orig;
@@ -164,7 +181,7 @@ static int ohci_s3c2410_hub_control(
 	 * process the request straight away and exit */
 
 	if (info == NULL) {
-		ret = ohci_hub_control(hcd, typeReq, wValue,
+		ret = orig_ohci_hub_control(hcd, typeReq, wValue,
 				       wIndex, buf, wLength);
 		goto out;
 	}
@@ -214,7 +231,7 @@ static int ohci_s3c2410_hub_control(
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
 	if (ret)
 		goto out;
 
@@ -373,8 +390,6 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 	s3c2410_start_hc(dev, hcd);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
-
 	retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
 	if (retval != 0)
 		goto err_ioremap;
@@ -391,71 +406,7 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_s3c2410_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-
-static const struct hc_driver ohci_s3c2410_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"S3C24XX OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.start =		ohci_s3c2410_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_s3c2410_hub_status_data,
-	.hub_control =		ohci_s3c2410_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/* device driver */
+static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;
 
 static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
 {
@@ -532,4 +483,39 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {
 	},
 };
 
+static int __init ohci_s3cxxxx_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
+
+	/*
+	 * The Samsung HW has some unusual quirks, which require
+	 * Sumsung-specific workarounds. We override certain hc_driver
+	 * functions here to achieve that. We explicitly do not enhance
+	 * ohci_driver_overrides to allow this more easily, since this
+	 * is an unusual case, and we don't want to encourage others to
+	 * override these functions by making it too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_s3c2410_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_s3c2410_hc_driver.hub_status_data;
+
+	ohci_s3c2410_hc_driver.hub_status_data	= ohci_s3c2410_hub_status_data;
+	ohci_s3c2410_hc_driver.hub_control	= ohci_s3c2410_hub_control;
+
+	return platform_driver_register(&ohci_hcd_s3c2410_driver);
+}
+module_init(ohci_s3cxxxx_init);
+
+static void __exit ohci_s3cxxxx_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_s3c2410_driver);
+}
+module_exit(ohci_s3cxxxx_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:s3c2410-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V3 3/6] USB: OHCI: make ohci-omap3 a separate driver
  2013-06-25  6:23   ` [PATCH V3 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
@ 2013-06-25 18:14     ` Alan Stern
  0 siblings, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-06-25 18:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 25 Jun 2013, Manjunath Goudar wrote:

> Separate the  TI OHCI OMAP3 host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.
> 
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Cc: Anand Gadiyar <gadiyar@ti.com>
> Cc: Felipe Balbi <balbi@ti.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Greg KH <greg@kroah.com>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: linux-usb at vger.kernel.org
> 
> V2:
>  -ohci_setup() removed because it is called in .reset member
>   of the ohci_hc_driver structure.
>  -The improper multi-line commenting style written in proper way.
>   ('*' characters aligned in vertically).
> 
> V3:
>  -RemoteWakeupConnected setting has been removed.

You weren't supposed to remove it!  I told you to remove this one line:

	writel(OHCI_CTRL_RWC, &ohci->regs->control);

The preceding lines:

	/*
	 * RemoteWakeupConnected has to be set explicitly before
	 * calling ohci_run. The reset value of RWC is 0.
	 */
	ohci->hc_control = OHCI_CTRL_RWC;

should remain.

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V3 2/6] USB: OHCI: make ohci-omap a separate driver
  2013-06-25  6:23   ` [PATCH V3 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
@ 2013-07-18 15:50     ` Alan Stern
  0 siblings, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-07-18 15:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 25 Jun 2013, Manjunath Goudar wrote:

> Separate the  TI OHCI OMAP1/2 host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.
   
I'm sorry it took so long to review this; I have been very busy. 
    
This patch is almost right.  There are just a couple of problems 
involving the clock_power calls.

> @@ -354,12 +358,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
>  		goto err2;
>  	}
>  
> -	ohci = hcd_to_ohci(hcd);
> -	ohci_hcd_init(ohci);
> -
> -	host_initialized = 0;
> -	host_enabled = 1;
> -
>  	irq = platform_get_irq(pdev, 0);
>  	if (irq < 0) {
>  		retval = -ENXIO;
> @@ -369,11 +367,7 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
>  	if (retval)
>  		goto err3;
>  
> -	host_initialized = 1;
> -
> -	if (!host_enabled)
> -		omap_ohci_clock_power(0);
> -
> +	omap_ohci_clock_power(0);

Since host_enabled was always 1 at this point, omap_ohci_clock_power()
would never be called.  You should remove it.

> @@ -402,6 +396,8 @@ err0:
>  static inline void
>  usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
>  {
> +	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
> +	omap_ohci_clock_power(0);
>  	usb_remove_hcd(hcd);
>  	if (!IS_ERR_OR_NULL(hcd->phy)) {
>  		(void) otg_set_host(hcd->phy->otg, 0);

omap_ohci_clock_power() should be called after usb_remove_hcd(), not
before.  This reason is simple: Until usb_remove_hcd() is called, the
controller is still running and therefore needs to have a valid clock
signal.

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V3 6/6] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-06-25  6:23   ` [PATCH V3 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
@ 2013-07-18 20:38     ` Alan Stern
  0 siblings, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-07-18 20:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 25 Jun 2013, Manjunath Goudar wrote:

> Separate the Samsung OHCI S3CXXXX host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.

This patch looks very good.  I have only two very small nits:

> diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
> index e125770..b0f6644 100644
> --- a/drivers/usb/host/ohci-s3c2410.c
> +++ b/drivers/usb/host/ohci-s3c2410.c
> @@ -19,17 +19,34 @@
>   * This file is licenced under the GPL.
>  */
>  
> -#include <linux/platform_device.h>
>  #include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
>  #include <linux/platform_data/usb-ohci-s3c2410.h>
> +#include <linux/usb.h>
> +#include <linux/usb/hcd.h>
> +
> +#include "ohci.h"
> +
>  
>  #define valid_port(idx) ((idx) == 1 || (idx) == 2)
>  
>  /* clock device associated with the hcd */
>  
> +
> +#define DRIVER_DESC "OHCI S3CXXXX driver"
> +
> +static const char hcd_name[] = "ohci-s3cxxxx";
> +
>  static struct clk *clk;
>  static struct clk *usb_clk;
>  
> +static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
> +			u16 wValue, u16 wIndex, char *buf, u16 wLength);
> +static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
> +
>  /* forward definitions */

Do you understand what "forward definitions" means?  It refers to 
declarations of functions whose actual code is given later.  In other 
words, your declarations of orig_ohci_hub_control and 
orig_ohci_hub_status_data belong just after this comment, not just 
before it.

> @@ -93,7 +110,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd, char *buf)
>  	int orig;
>  	int portno;
>  
> -	orig  = ohci_hub_status_data(hcd, buf);
> +	orig  = orig_ohci_hub_status_data(hcd, buf);

Since you're changing the line anyway, you should get rid of the extra
space before the '='.

After you make those two changes, you can add my Acked-by.

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V3 5/6] USB: OHCI: make ohci-at91 a separate driver
  2013-06-25  6:23   ` [PATCH V3 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
@ 2013-07-18 20:51     ` Alan Stern
  0 siblings, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-07-18 20:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 25 Jun 2013, Manjunath Goudar wrote:

> Separate the  TI OHCI Atmel host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.

This looks okay except for some very minor issues.

> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 46c2f42..e4dc9ab 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
>            Enables support for the on-chip OHCI controller on
>            ST SPEAr chips.
>  
> +config USB_OHCI_HCD_AT91
> +        tristate  "Support for Atmel on-chip OHCI USB controller"
> +        depends on USB_OHCI_HCD && ARCH_AT91
> +        default y
> +        ---help---
> +          Enables support for the on-chip OHCI controller on
> +          Atmel chips.

Get rid of the extra space after "tristate".

> @@ -686,7 +630,11 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
>  	 * REVISIT: some boards will be able to turn VBUS off...
>  	 */
>  	if (at91_suspend_entering_slow_clock()) {
> -		ohci_usb_reset (ohci);
> +		ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
> +		ohci->hc_control &= OHCI_CTRL_RWC;
> +		ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
> +		ohci->rh_state = OHCI_RH_HALTED;

Even though you're just copying the code, don't also copy its mistakes.
Get rid of the extra spaces before the '(' characters.

> +static void __exit ohci_at91_cleanup(void)
> +{
> +	platform_driver_unregister(&ohci_hcd_at91_driver);
> +}
> +module_exit(ohci_at91_cleanup);
> +
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +MODULE_LICENSE("GPL");

Please move the existing MODULE_ALIAS line down here with these lines.

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH 0/6] USB: OHCI: more bus glues as separate modules
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (8 preceding siblings ...)
  2013-06-25  6:23 ` [PATCH V3 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
@ 2013-07-22  9:19 ` Manjunath Goudar
  2013-07-22  9:19   ` [PATCH 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
                     ` (6 more replies)
  2013-07-31  6:07 ` Manjunath Goudar
                   ` (4 subsequent siblings)
  14 siblings, 7 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-07-22  9:19 UTC (permalink / raw)
  To: linux-arm-kernel

These patches are for separating the SOC On-Chip ohci host controller
from ohci-hcd host code into its own driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.12.

V2:
  In patch 5/6 and 6/6:
  -Set non-standard fields in hc_driver manually, rather than
   relying on an expanded struct ohci_driver_overrides.
  -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
   relying on ohci_hub_control and hub_status_data being exported.

  In patch 1/6 to 4/6
  -ohci_setup() has been removed because it is called in .reset member
   of the ohci_hc_driver structure.

V3:
 In patch 5/6 and 6/6:
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

 In patch 5/6:
 -The ohci_restart() function is not required in  current scenario,
  only discarding connection state of integrated transceivers is sufficient,
  for this directly handling ohci->hc_control.

 In patch 2/6 :
 -rewritten if (config->otg || config->rwc) block statements into
  two separate 'if blocks' to handle below scenarios
  1. config->otg set scenario.
  2. if any of these (config->otg, config->rwc) are set, this
     scenario should be handled only after ohci_setup()

 In patch 1/6 and 4/6:
  No change.

V4:
 In patch 1/6 and 4/6:
  No change.
 
 In patch 2/6 :
 -usb_remove_hcd() function is required a valid clock that is what
  omap_ohci_clock_power(0) is called after hcd shutdown.

 In patch 3/6 :
 -V3 modification revert back, only ohci->regs setting write()
  function has been removed because ohci->regs doesn't get set until
  usb_add_hcd.

 In patch 5/6 :
 - Removed extra space after "tristate".
 - Removed extra space between function name  and '(' characters.
 - MODULE_ALIAS line moved to last statement of ohci-at91 file.

 In patch 6/6 :
 - Removed extra space before the '='.
 - Moved  /* forward definitions */ line before the declarations of functions.

Manjunath Goudar (6):
  USB: OHCI: make ohci-exynos a separate driver
  USB: OHCI: make ohci-omap a separate driver
  USB: OHCI: make ohci-omap3 a separate driver
  USB: OHCI: make ohci-spear a separate driver
  USB: OHCI: make ohci-at91 a separate driver
  USB: OHCI: make ohci-s3c2410 a separate driver

 drivers/usb/host/Kconfig        |   30 ++++++-
 drivers/usb/host/Makefile       |    6 ++
 drivers/usb/host/ohci-at91.c    |  153 ++++++++++++++++-------------------
 drivers/usb/host/ohci-exynos.c  |  167 ++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c     |  108 -------------------------
 drivers/usb/host/ohci-omap.c    |  156 +++++++++++++-----------------------
 drivers/usb/host/ohci-omap3.c   |  118 +++++++++------------------
 drivers/usb/host/ohci-s3c2410.c |  128 +++++++++++++-----------------
 drivers/usb/host/ohci-spear.c   |  140 +++++++++++++-------------------
 9 files changed, 374 insertions(+), 632 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH 1/6] USB: OHCI: make ohci-exynos a separate driver
  2013-07-22  9:19 ` [PATCH 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
@ 2013-07-22  9:19   ` Manjunath Goudar
  2013-07-22  9:19   ` [PATCH 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-07-22  9:19 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  Samsung OHCI EXYNOS host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Cc: Vivek Gautam <gautam.vivek@samsung.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -exynos_ohci_hcd structure assignment error fixed.
 -Removed multiple usb_create_hcd() from prob funtion.
 -platform_set_drvdata() called before exynos_ohci_phy_enable().
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure

V3:
 -No major changes only "exynos" written in capital letters
  in "OHCI exynos driver".
---
 drivers/usb/host/Kconfig       |    2 +-
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ohci-exynos.c |  167 +++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c    |   18 -----
 4 files changed, 71 insertions(+), 117 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 7bc598b..7b8f6bd 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -463,7 +463,7 @@ config USB_OHCI_SH
 	  If you use the PCI OHCI controller, this option is not necessary.
 
 config USB_OHCI_EXYNOS
-	boolean "OHCI support for Samsung EXYNOS SoC Series"
+	tristate "OHCI support for Samsung EXYNOS SoC Series"
 	depends on ARCH_EXYNOS
 	help
 	 Enable support for the Samsung Exynos SOC's on-chip OHCI controller.
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 480e203..26cf69a 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
+obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index b0b542c..ae6068d 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -12,24 +12,39 @@
  */
 
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-exynos.h>
 #include <linux/usb/phy.h>
 #include <linux/usb/samsung_usb_phy.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include "ohci.h"
+
+#define DRIVER_DESC "OHCI EXYNOS driver"
+
+static const char hcd_name[] = "ohci-exynos";
+static struct hc_driver __read_mostly exynos_ohci_hc_driver;
+
+#define to_exynos_ohci(hcd) (struct exynos_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
 
 struct exynos_ohci_hcd {
-	struct device *dev;
-	struct usb_hcd *hcd;
 	struct clk *clk;
 	struct usb_phy *phy;
 	struct usb_otg *otg;
 	struct exynos4_ohci_platdata *pdata;
 };
 
-static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_enable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_init(exynos_ohci->phy);
@@ -37,9 +52,10 @@ static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
 }
 
-static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_disable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_shutdown(exynos_ohci->phy);
@@ -47,63 +63,11 @@ static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
 }
 
-static int ohci_exynos_reset(struct usb_hcd *hcd)
-{
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-static int ohci_exynos_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci);
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-static const struct hc_driver exynos_ohci_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "EXYNOS OHCI Host Controller",
-	.hcd_priv_size		= sizeof(struct ohci_hcd),
-
-	.irq			= ohci_irq,
-	.flags			= HCD_MEMORY|HCD_USB11,
-
-	.reset			= ohci_exynos_reset,
-	.start			= ohci_exynos_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-
-	.get_frame_number	= ohci_get_frame,
-
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-	.start_port_reset	= ohci_start_port_reset,
-};
-
 static int exynos_ohci_probe(struct platform_device *pdev)
 {
 	struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_ohci_hcd *exynos_ohci;
 	struct usb_hcd *hcd;
-	struct ohci_hcd *ohci;
 	struct resource *res;
 	struct usb_phy *phy;
 	int irq;
@@ -119,10 +83,14 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	if (!pdev->dev.coherent_dma_mask)
 		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
-	exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd),
-					GFP_KERNEL);
-	if (!exynos_ohci)
+	hcd = usb_create_hcd(&exynos_ohci_hc_driver,
+				&pdev->dev, dev_name(&pdev->dev));
+	if (!hcd) {
+		dev_err(&pdev->dev, "Unable to create HCD\n");
 		return -ENOMEM;
+	}
+
+	exynos_ohci = to_exynos_ohci(hcd);
 
 	if (of_device_is_compatible(pdev->dev.of_node,
 					"samsung,exynos5440-ohci"))
@@ -143,17 +111,6 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	}
 
 skip_phy:
-
-	exynos_ohci->dev = &pdev->dev;
-
-	hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
-					dev_name(&pdev->dev));
-	if (!hcd) {
-		dev_err(&pdev->dev, "Unable to create HCD\n");
-		return -ENOMEM;
-	}
-
-	exynos_ohci->hcd = hcd;
 	exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");
 
 	if (IS_ERR(exynos_ohci->clk)) {
@@ -190,26 +147,21 @@ skip_phy:
 	}
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	platform_set_drvdata(pdev, hcd);
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to add USB HCD\n");
 		goto fail_add_hcd;
 	}
-
-	platform_set_drvdata(pdev, exynos_ohci);
-
 	return 0;
 
 fail_add_hcd:
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 fail_io:
 	clk_disable_unprepare(exynos_ohci->clk);
 fail_clk:
@@ -219,16 +171,15 @@ fail_clk:
 
 static int exynos_ohci_remove(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	usb_remove_hcd(hcd);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -239,8 +190,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
 
 static void exynos_ohci_shutdown(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
 	if (hcd->driver->shutdown)
 		hcd->driver->shutdown(hcd);
@@ -249,9 +199,10 @@ static void exynos_ohci_shutdown(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int exynos_ohci_suspend(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	struct platform_device *pdev = to_platform_device(dev);
 	unsigned long flags;
 	int rc = 0;
 
@@ -271,10 +222,9 @@ static int exynos_ohci_suspend(struct device *dev)
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -286,16 +236,16 @@ fail:
 
 static int exynos_ohci_resume(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd			= dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci	= to_exynos_ohci(hcd);
+	struct platform_device *pdev		= to_platform_device(dev);
 
 	clk_prepare_enable(exynos_ohci->clk);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	ohci_resume(hcd, false);
 
@@ -306,6 +256,10 @@ static int exynos_ohci_resume(struct device *dev)
 #define exynos_ohci_resume	NULL
 #endif
 
+static const struct ohci_driver_overrides exynos_overrides __initconst = {
+	.extra_priv_size =	sizeof(struct exynos_ohci_hcd),
+};
+
 static const struct dev_pm_ops exynos_ohci_pm_ops = {
 	.suspend	= exynos_ohci_suspend,
 	.resume		= exynos_ohci_resume,
@@ -331,6 +285,23 @@ static struct platform_driver exynos_ohci_driver = {
 		.of_match_table	= of_match_ptr(exynos_ohci_match),
 	}
 };
+static int __init ohci_exynos_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&exynos_ohci_hc_driver, &exynos_overrides);
+	return platform_driver_register(&exynos_ohci_driver);
+}
+module_init(ohci_exynos_init);
+
+static void __exit ohci_exynos_cleanup(void)
+{
+	platform_driver_unregister(&exynos_ohci_driver);
+}
+module_exit(ohci_exynos_cleanup);
 
 MODULE_ALIAS("platform:exynos-ohci");
 MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index a9d3437..2980bb6 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_EXYNOS
-#include "ohci-exynos.c"
-#define EXYNOS_PLATFORM_DRIVER	exynos_ohci_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP1
 #include "ohci-omap.c"
 #define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
@@ -1336,12 +1331,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_s3c2410;
 #endif
 
-#ifdef EXYNOS_PLATFORM_DRIVER
-	retval = platform_driver_register(&EXYNOS_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_exynos;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1395,10 +1384,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
- error_exynos:
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
  error_s3c2410:
@@ -1463,9 +1448,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH 2/6] USB: OHCI: make ohci-omap a separate driver
  2013-07-22  9:19 ` [PATCH 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
  2013-07-22  9:19   ` [PATCH 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
@ 2013-07-22  9:19   ` Manjunath Goudar
  2013-07-23 18:39     ` Alan Stern
  2013-07-22  9:19   ` [PATCH 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
                     ` (4 subsequent siblings)
  6 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-07-22  9:19 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP1/2 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb at vger.kernel.org

V2:
 -omap_ohci_clock_power(0) called in usb_hcd_omap_remove().
 -Removed ohci_setup() call from usb_hcd_omap_probe().
 -host_enabled and host_initialized variables aren't used for anything
  thats what removed.

V3:
 -rewritten if (config->otg || config->rwc) block statements into
  two separate 'if blocks' to handle below scenarios
  1. config->otg set scenario.
  2. if any of these (config->otg, config->rwc) are set, this
     scenario should be handled only after ohci_setup()

V4:
 -usb_remove_hcd() function is required a valid clock that is what
  omap_ohci_clock_power(0) is called after hcd shutdown.
---
 drivers/usb/host/Kconfig     |    2 +-
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-hcd.c  |   18 -----
 drivers/usb/host/ohci-omap.c |  156 ++++++++++++++----------------------------
 4 files changed, 55 insertions(+), 122 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 7b8f6bd..99b7e7e 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -376,7 +376,7 @@ config USB_OHCI_HCD
 if USB_OHCI_HCD
 
 config USB_OHCI_HCD_OMAP1
-	bool "OHCI support for OMAP1/2 chips"
+	tristate "OHCI support for OMAP1/2 chips"
 	depends on ARCH_OMAP1
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 26cf69a..c7076ec 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 2980bb6..1abc1e7 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP1
-#include "ohci-omap.c"
-#define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP3
 #include "ohci-omap3.c"
 #define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
@@ -1289,12 +1284,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP1_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP1_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap1_platform;
-#endif
-
 #ifdef OMAP3_PLATFORM_DRIVER
 	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1408,10 +1397,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
  error_omap3_platform:
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
- error_omap1_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1466,9 +1451,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OMAP3_PLATFORM_DRIVER
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 8747fa6..8149ef0 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -14,12 +14,21 @@
  * This file is licenced under the GPL.
  */
 
-#include <linux/signal.h>
-#include <linux/jiffies.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
 #include <asm/io.h>
 #include <asm/mach-types.h>
@@ -42,10 +51,7 @@
 #define OMAP1510_LB_MMU_RAM_H	0xfffec234
 #define OMAP1510_LB_MMU_RAM_L	0xfffec238
 
-
-#ifndef CONFIG_ARCH_OMAP
-#error "This file is OMAP bus glue.  CONFIG_OMAP must be defined."
-#endif
+#define DRIVER_DESC "OHCI OMAP driver"
 
 #ifdef CONFIG_TPS65010
 #include <linux/i2c/tps65010.h>
@@ -68,8 +74,9 @@ extern int ocpi_enable(void);
 
 static struct clk *usb_host_ck;
 static struct clk *usb_dc_ck;
-static int host_enabled;
-static int host_initialized;
+
+static const char hcd_name[] = "ohci-omap";
+static struct hc_driver __read_mostly ohci_omap_hc_driver;
 
 static void omap_ohci_clock_power(int on)
 {
@@ -188,7 +195,7 @@ static void start_hnp(struct ohci_hcd *ohci)
 
 /*-------------------------------------------------------------------------*/
 
-static int ohci_omap_init(struct usb_hcd *hcd)
+static int ohci_omap_reset(struct usb_hcd *hcd)
 {
 	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
 	struct omap_usb_config	*config = hcd->self.controller->platform_data;
@@ -198,9 +205,9 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	dev_dbg(hcd->self.controller, "starting USB Controller\n");
 
 	if (config->otg) {
-		ohci_to_hcd(ohci)->self.otg_port = config->otg;
+		hcd->self.otg_port = config->otg;
 		/* default/minimum OTG power budget:  8 mA */
-		ohci_to_hcd(ohci)->power_budget = 8;
+		hcd->power_budget = 8;
 	}
 
 	/* boards can use OTG transceivers in non-OTG modes */
@@ -238,9 +245,15 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 		omap_1510_local_bus_init();
 	}
 
-	if ((ret = ohci_init(ohci)) < 0)
+	ret = ohci_setup(hcd);
+	if (ret < 0)
 		return ret;
 
+	if (config->otg || config->rwc) {
+		ohci->hc_control = OHCI_CTRL_RWC;
+		writel(OHCI_CTRL_RWC, &ohci->regs->control);
+	}
+
 	/* board-specific power switching and overcurrent support */
 	if (machine_is_omap_osk() || machine_is_omap_innovator()) {
 		u32	rh = roothub_a (ohci);
@@ -281,14 +294,6 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	return 0;
 }
 
-static void ohci_omap_stop(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
-	ohci_stop(hcd);
-	omap_ohci_clock_power(0);
-}
-
-
 /*-------------------------------------------------------------------------*/
 
 /**
@@ -304,7 +309,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 {
 	int retval, irq;
 	struct usb_hcd *hcd = 0;
-	struct ohci_hcd *ohci;
 
 	if (pdev->num_resources != 2) {
 		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
@@ -354,12 +358,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 		goto err2;
 	}
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
-
-	host_initialized = 0;
-	host_enabled = 1;
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		retval = -ENXIO;
@@ -369,11 +367,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 	if (retval)
 		goto err3;
 
-	host_initialized = 1;
-
-	if (!host_enabled)
-		omap_ohci_clock_power(0);
-
 	return 0;
 err3:
 	iounmap(hcd->regs);
@@ -402,7 +395,9 @@ err0:
 static inline void
 usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
+	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
 	usb_remove_hcd(hcd);
+	omap_ohci_clock_power(0);
 	if (!IS_ERR_OR_NULL(hcd->phy)) {
 		(void) otg_set_host(hcd->phy->otg, 0);
 		usb_put_phy(hcd->phy);
@@ -418,76 +413,6 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_omap_start (struct usb_hcd *hcd)
-{
-	struct omap_usb_config *config;
-	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ret;
-
-	if (!host_enabled)
-		return 0;
-	config = hcd->self.controller->platform_data;
-	if (config->otg || config->rwc) {
-		ohci->hc_control = OHCI_CTRL_RWC;
-		writel(OHCI_CTRL_RWC, &ohci->regs->control);
-	}
-
-	if ((ret = ohci_run (ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop (hcd);
-		return ret;
-	}
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_omap_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap_init,
-	.start =		ohci_omap_start,
-	.stop =			ohci_omap_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static int ohci_hcd_omap_drv_probe(struct platform_device *dev)
 {
 	return usb_hcd_omap_probe(&ohci_omap_hc_driver, dev);
@@ -553,4 +478,29 @@ static struct platform_driver ohci_hcd_omap_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides omap_overrides __initconst = {
+	.product_desc	= "OMAP OHCI",
+	.reset		= ohci_omap_reset
+};
+
+static int __init ohci_omap_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap_hc_driver, &omap_overrides);
+	return platform_driver_register(&ohci_hcd_omap_driver);
+}
+module_init(ohci_omap_init);
+
+static void __exit ohci_omap_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap_driver);
+}
+module_exit(ohci_omap_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH 3/6] USB: OHCI: make ohci-omap3 a separate driver
  2013-07-22  9:19 ` [PATCH 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
  2013-07-22  9:19   ` [PATCH 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
  2013-07-22  9:19   ` [PATCH 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
@ 2013-07-22  9:19   ` Manjunath Goudar
  2013-07-23 18:43     ` Alan Stern
  2013-07-22  9:19   ` [PATCH 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
                     ` (3 subsequent siblings)
  6 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-07-22  9:19 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP3 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Anand Gadiyar <gadiyar@ti.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb at vger.kernel.org

V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -The improper multi-line commenting style written in proper way.
  ('*' characters aligned in vertically).

V3:
 -RemoteWakeupConnected setting has been removed.

V4:
 -V3 modification revert back, only ohci->regs setting write()
  function has been removed because ohci->regs doesn't get set until
  usb_add_hcd.
---
 drivers/usb/host/Kconfig      |    2 +-
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 -------
 drivers/usb/host/ohci-omap3.c |  118 +++++++++++++----------------------------
 4 files changed, 40 insertions(+), 99 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 99b7e7e..3eab432 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -383,7 +383,7 @@ config USB_OHCI_HCD_OMAP1
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
 config USB_OHCI_HCD_OMAP3
-	bool "OHCI support for OMAP3 and later chips"
+	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index c7076ec..954466d 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 1abc1e7..cad51d2 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP3
-#include "ohci-omap3.c"
-#define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1284,12 +1279,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP3_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap3_platform;
-#endif
-
 #ifdef OF_PLATFORM_DRIVER
 	retval = platform_driver_register(&OF_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1393,10 +1382,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
  error_of_platform:
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
- error_omap3_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1448,9 +1433,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OF_PLATFORM_DRIVER
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index 8f71357..e14f4d9 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -29,90 +29,22 @@
  *	- add kernel-doc
  */
 
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/of.h>
-#include <linux/dma-mapping.h>
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_init(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "starting OHCI controller\n");
-
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	/*
-	 * RemoteWakeupConnected has to be set explicitly before
-	 * calling ohci_run. The reset value of RWC is 0.
-	 */
-	ohci->hc_control = OHCI_CTRL_RWC;
-	writel(OHCI_CTRL_RWC, &ohci->regs->control);
-
-	ret = ohci_run(ohci);
-
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-	}
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
-	return ret;
-}
+#include "ohci.h"
 
-/*-------------------------------------------------------------------------*/
+#define DRIVER_DESC "OHCI OMAP3 driver"
 
-static const struct hc_driver ohci_omap3_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP3 OHCI Host Controller",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap3_init,
-	.start =		ohci_omap3_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
+static const char hcd_name[] = "ohci-omap3";
+static struct hc_driver __read_mostly ohci_omap3_hc_driver;
 
 /*
  * configure so an HC device and id are always provided
@@ -129,6 +61,7 @@ static const struct hc_driver ohci_omap3_hc_driver = {
 static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 {
 	struct device		*dev = &pdev->dev;
+	struct ohci_hcd		*ohci;
 	struct usb_hcd		*hcd = NULL;
 	void __iomem		*regs = NULL;
 	struct resource		*res;
@@ -185,7 +118,12 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	ohci = hcd_to_ohci(hcd);
+	/*
+	 * RemoteWakeupConnected has to be set explicitly before
+	 * calling ohci_run. The reset value of RWC is 0.
+	 */
+	ohci->hc_control = OHCI_CTRL_RWC;
 
 	ret = usb_add_hcd(hcd, irq, 0);
 	if (ret) {
@@ -256,5 +194,25 @@ static struct platform_driver ohci_hcd_omap3_driver = {
 	},
 };
 
+static int __init ohci_omap3_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap3_hc_driver, NULL);
+	return platform_driver_register(&ohci_hcd_omap3_driver);
+}
+module_init(ohci_omap3_init);
+
+static void __exit ohci_omap3_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap3_driver);
+}
+module_exit(ohci_omap3_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci-omap3");
 MODULE_AUTHOR("Anand Gadiyar <gadiyar@ti.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH 4/6] USB: OHCI: make ohci-spear a separate driver
  2013-07-22  9:19 ` [PATCH 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (2 preceding siblings ...)
  2013-07-22  9:19   ` [PATCH 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
@ 2013-07-22  9:19   ` Manjunath Goudar
  2013-07-22  9:19   ` [PATCH 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
                     ` (2 subsequent siblings)
  6 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-07-22  9:19 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the ST OHCI SPEAr host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -debugging stuff isn't needed any more that's what removed.

V3:
 No change.
---
 drivers/usb/host/Kconfig      |    8 +++
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 ------
 drivers/usb/host/ohci-spear.c |  140 +++++++++++++++++------------------------
 4 files changed, 65 insertions(+), 102 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 3eab432..a5a34a3 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -382,6 +382,14 @@ config USB_OHCI_HCD_OMAP1
 	---help---
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
+config USB_OHCI_HCD_SPEAR
+        tristate "Support for ST SPEAr on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && PLAT_SPEAR
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          ST SPEAr chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 954466d..b8ea17c 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
+obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index cad51d2..34ec156 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1212,11 +1212,6 @@ MODULE_LICENSE ("GPL");
 #define OF_PLATFORM_DRIVER	ohci_hcd_ppc_of_driver
 #endif
 
-#ifdef CONFIG_PLAT_SPEAR
-#include "ohci-spear.c"
-#define SPEAR_PLATFORM_DRIVER	spear_ohci_hcd_driver
-#endif
-
 #ifdef CONFIG_PPC_PS3
 #include "ohci-ps3.c"
 #define PS3_SYSTEM_BUS_DRIVER	ps3_ohci_driver
@@ -1333,19 +1328,9 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_davinci;
 #endif
 
-#ifdef SPEAR_PLATFORM_DRIVER
-	retval = platform_driver_register(&SPEAR_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_spear;
-#endif
-
 	return retval;
 
 	/* Error path */
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
- error_spear:
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
  error_davinci:
@@ -1403,9 +1388,6 @@ module_init(ohci_hcd_mod_init);
 
 static void __exit ohci_hcd_mod_exit(void)
 {
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index cc9dd9e..31ff3fc 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -11,92 +11,37 @@
 * warranty of any kind, whether express or implied.
 */
 
-#include <linux/signal.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
+#define DRIVER_DESC "OHCI SPEAr driver"
+
+static const char hcd_name[] = "SPEAr-ohci";
 struct spear_ohci {
-	struct ohci_hcd ohci;
 	struct clk *clk;
 };
 
-#define to_spear_ohci(hcd)	(struct spear_ohci *)hcd_to_ohci(hcd)
-
-static void spear_start_ohci(struct spear_ohci *ohci)
-{
-	clk_prepare_enable(ohci->clk);
-}
-
-static void spear_stop_ohci(struct spear_ohci *ohci)
-{
-	clk_disable_unprepare(ohci->clk);
-}
-
-static int ohci_spear_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-	ohci->regs = hcd->regs;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	create_debug_files(ohci);
-
-#ifdef DEBUG
-	ohci_dump(ohci, 1);
-#endif
-	return 0;
-}
-
-static const struct hc_driver ohci_spear_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "SPEAr OHCI",
-	.hcd_priv_size		= sizeof(struct spear_ohci),
-
-	/* generic hardware linkage */
-	.irq			= ohci_irq,
-	.flags			= HCD_USB11 | HCD_MEMORY,
-
-	/* basic lifecycle operations */
-	.start			= ohci_spear_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-
-	/* managing i/o requests and associated device resources */
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	/* scheduling support */
-	.get_frame_number	= ohci_get_frame,
+#define to_spear_ohci(hcd)     (struct spear_ohci *)(hcd_to_ohci(hcd)->priv)
 
-	/* root hub support */
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-
-	.start_port_reset	= ohci_start_port_reset,
-};
+static struct hc_driver __read_mostly ohci_spear_hc_driver;
 
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
 	const struct hc_driver *driver = &ohci_spear_hc_driver;
+	struct ohci_hcd *ohci;
 	struct usb_hcd *hcd = NULL;
 	struct clk *usbh_clk;
-	struct spear_ohci *ohci_p;
+	struct spear_ohci *sohci_p;
 	struct resource *res;
 	int retval, irq;
 
@@ -151,16 +96,18 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 		goto err_put_hcd;
 	}
 
-	ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
-	ohci_p->clk = usbh_clk;
-	spear_start_ohci(ohci_p);
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	sohci_p = to_spear_ohci(hcd);
+	sohci_p->clk = usbh_clk;
+
+	clk_prepare_enable(sohci_p->clk);
+
+	ohci = hcd_to_ohci(hcd);
 
 	retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0);
 	if (retval == 0)
 		return retval;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
 err_put_hcd:
 	usb_put_hcd(hcd);
 fail:
@@ -172,11 +119,11 @@ fail:
 static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	usb_remove_hcd(hcd);
-	if (ohci_p->clk)
-		spear_stop_ohci(ohci_p);
+	if (sohci_p->clk)
+		clk_disable_unprepare(sohci_p->clk);
 
 	usb_put_hcd(hcd);
 	return 0;
@@ -188,13 +135,14 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
+
 	return 0;
 }
 
@@ -202,13 +150,13 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_start_ohci(ohci_p);
+	clk_prepare_enable(sohci_p->clk);
 	ohci_resume(hcd, false);
 	return 0;
 }
@@ -234,4 +182,28 @@ static struct platform_driver spear_ohci_hcd_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides spear_overrides __initconst = {
+	.extra_priv_size = sizeof(struct spear_ohci),
+};
+static int __init ohci_spear_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_spear_hc_driver, &spear_overrides);
+	return platform_driver_register(&spear_ohci_hcd_driver);
+}
+module_init(ohci_spear_init);
+
+static void __exit ohci_spear_cleanup(void)
+{
+	platform_driver_unregister(&spear_ohci_hcd_driver);
+}
+module_exit(ohci_spear_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Deepak Sikri");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:spear-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH 5/6] USB: OHCI: make ohci-at91 a separate driver
  2013-07-22  9:19 ` [PATCH 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (3 preceding siblings ...)
  2013-07-22  9:19   ` [PATCH 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
@ 2013-07-22  9:19   ` Manjunath Goudar
  2013-07-23 18:45     ` Alan Stern
  2013-07-22  9:19   ` [PATCH 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
  2013-07-22  9:41   ` [PATCH V4 0/6] USB: OHCI: more bus glues as separate modules manjunath
  6 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-07-22  9:19 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI Atmel host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.12.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -Set non-standard fields in ohci_at91_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

V3:
 -The ohci_restart() function is not required in  current scenario,
  only discarding connection state of integrated transceivers is sufficient,
  for this directly handling ohci->hc_control.

V4:
 - Removed extra space after "tristate".
 - Removed extra space between function name  and '(' characters.
 - MODULE_ALIAS line moved to last statement of ohci-at91 file.
---
 drivers/usb/host/Kconfig     |    8 +++
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-at91.c |  153 +++++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c  |   18 -----
 4 files changed, 77 insertions(+), 103 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index a5a34a3..693560a 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_AT91
+        tristate "Support for Atmel on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && ARCH_AT91
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          Atmel chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index b8ea17c..a70b044 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
+obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 9677f68..08e28eb 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -13,27 +13,41 @@
  */
 
 #include <linux/clk.h>
-#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/atmel.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
 #include <mach/hardware.h>
 #include <asm/gpio.h>
 
 #include <mach/cpu.h>
 
-#ifndef CONFIG_ARCH_AT91
-#error "CONFIG_ARCH_AT91 must be defined."
-#endif
+
+#include "ohci.h"
 
 #define valid_port(index)	((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
 #define at91_for_each_port(index)	\
 		for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++)
 
 /* interface and function clocks; sometimes also an AHB clock */
+
+#define DRIVER_DESC "OHCI Atmel driver"
+
+static const char hcd_name[] = "ohci-atmel";
+
+static struct hc_driver __read_mostly ohci_at91_hc_driver;
 static struct clk *iclk, *fclk, *hclk;
 static int clocked;
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+			u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
 
 extern int usb_disabled(void);
 
@@ -111,6 +125,8 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
 static int usb_hcd_at91_probe(const struct hc_driver *driver,
 			struct platform_device *pdev)
 {
+	struct at91_usbh_data *board;
+	struct ohci_hcd *ohci;
 	int retval;
 	struct usb_hcd *hcd = NULL;
 
@@ -163,8 +179,10 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
 		goto err5;
 	}
 
+	board = hcd->self.controller->platform_data;
+	ohci = hcd_to_ohci(hcd);
+	ohci->num_ports = board->ports;
 	at91_start_hc(pdev);
-	ohci_hcd_init(hcd_to_ohci(hcd));
 
 	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
 	if (retval == 0)
@@ -221,36 +239,6 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd,
 }
 
 /*-------------------------------------------------------------------------*/
-
-static int
-ohci_at91_reset (struct usb_hcd *hcd)
-{
-	struct at91_usbh_data	*board = hcd->self.controller->platform_data;
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
-	ohci->num_ports = board->ports;
-	return 0;
-}
-
-static int
-ohci_at91_start (struct usb_hcd *hcd)
-{
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_run(ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-	return 0;
-}
-
 static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
 {
 	if (!valid_port(port))
@@ -281,7 +269,7 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
 static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
 	struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
-	int length = ohci_hub_status_data(hcd, buf);
+	int length = orig_ohci_hub_status_data(hcd, buf);
 	int port;
 
 	at91_for_each_port(port) {
@@ -359,7 +347,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex + 1,
+				buf, wLength);
 	if (ret)
 		goto out;
 
@@ -413,51 +402,6 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 /*-------------------------------------------------------------------------*/
 
-static const struct hc_driver ohci_at91_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"AT91 OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_at91_reset,
-	.start =		ohci_at91_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_at91_hub_status_data,
-	.hub_control =		ohci_at91_hub_control,
-#ifdef CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
 {
 	struct platform_device *pdev = data;
@@ -686,7 +630,11 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
 	 * REVISIT: some boards will be able to turn VBUS off...
 	 */
 	if (at91_suspend_entering_slow_clock()) {
-		ohci_usb_reset (ohci);
+		ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
+		ohci->hc_control &= OHCI_CTRL_RWC;
+		ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
+		ohci->rh_state = OHCI_RH_HALTED;
+
 		/* flush the writes */
 		(void) ohci_readl (ohci, &ohci->regs->control);
 		at91_stop_clock();
@@ -713,8 +661,6 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
 #define ohci_hcd_at91_drv_resume  NULL
 #endif
 
-MODULE_ALIAS("platform:at91_ohci");
-
 static struct platform_driver ohci_hcd_at91_driver = {
 	.probe		= ohci_hcd_at91_drv_probe,
 	.remove		= ohci_hcd_at91_drv_remove,
@@ -727,3 +673,40 @@ static struct platform_driver ohci_hcd_at91_driver = {
 		.of_match_table	= of_match_ptr(at91_ohci_dt_ids),
 	},
 };
+
+static int __init ohci_at91_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_at91_hc_driver, NULL);
+
+	/*
+	 * The Atmel HW has some unusual quirks, which require Atmel-specific
+	 * workarounds. We override certain hc_driver functions here to
+	 * achieve that. We explicitly do not enhance ohci_driver_overrides to
+	 * allow this more easily, since this is an unusual case, and we don't
+	 * want to encourage others to override these functions by making it
+	 * too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_at91_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_at91_hc_driver.hub_status_data;
+
+	ohci_at91_hc_driver.hub_status_data	= ohci_at91_hub_status_data;
+	ohci_at91_hc_driver.hub_control		= ohci_at91_hub_control;
+
+	return platform_driver_register(&ohci_hcd_at91_driver);
+}
+module_init(ohci_at91_init);
+
+static void __exit ohci_at91_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_at91_driver);
+}
+module_exit(ohci_at91_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:at91_ohci");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 34ec156..b48c892 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1192,11 +1192,6 @@ MODULE_LICENSE ("GPL");
 #define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver
 #endif
 
-#ifdef CONFIG_ARCH_AT91
-#include "ohci-at91.c"
-#define AT91_PLATFORM_DRIVER	ohci_hcd_at91_driver
-#endif
-
 #ifdef CONFIG_ARCH_LPC32XX
 #include "ohci-nxp.c"
 #define NXP_PLATFORM_DRIVER	usb_hcd_nxp_driver
@@ -1310,12 +1305,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_ep93xx;
 #endif
 
-#ifdef AT91_PLATFORM_DRIVER
-	retval = platform_driver_register(&AT91_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_at91;
-#endif
-
 #ifdef NXP_PLATFORM_DRIVER
 	retval = platform_driver_register(&NXP_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1339,10 +1328,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
  error_nxp:
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
- error_at91:
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
@@ -1394,9 +1379,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef NXP_PLATFORM_DRIVER
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH 6/6] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-07-22  9:19 ` [PATCH 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (4 preceding siblings ...)
  2013-07-22  9:19   ` [PATCH 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
@ 2013-07-22  9:19   ` Manjunath Goudar
  2013-07-23  8:23     ` Tomasz Figa
  2013-07-22  9:41   ` [PATCH V4 0/6] USB: OHCI: more bus glues as separate modules manjunath
  6 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-07-22  9:19 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the Samsung OHCI S3CXXXX host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.12.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -Set non-standard fields in ohci_s3c2410_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.

V3:
 -Kconfig wrong parentheses discription fixed.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

V4:
 - Removed extra space before the '='.
 - Moved  /* forward definitions */ line before the declarations of functions.
---
 drivers/usb/host/Kconfig        |    8 +++
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ohci-hcd.c     |   18 ------
 drivers/usb/host/ohci-s3c2410.c |  128 +++++++++++++++++----------------------
 4 files changed, 66 insertions(+), 89 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 693560a..795d14d 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_S3CXXXX
+        tristate "Support for S3CXXXX on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX)
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          S3CXXXX chips.
+
 config USB_OHCI_HCD_AT91
         tristate "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index a70b044..9dffe81 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
+obj-$(CONFIG_USB_OHCI_HCD_S3CXXXX)	+= ohci-s3c2410.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index b48c892..b69a49e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1177,11 +1177,6 @@ MODULE_LICENSE ("GPL");
 #define SA1111_DRIVER		ohci_hcd_sa1111_driver
 #endif
 
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
-#include "ohci-s3c2410.c"
-#define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1293,12 +1288,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_tmio;
 #endif
 
-#ifdef S3C2410_PLATFORM_DRIVER
-	retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_s3c2410;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1332,10 +1321,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
- error_s3c2410:
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
  error_tmio:
@@ -1382,9 +1367,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index e125770..48b5948 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -19,19 +19,36 @@
  * This file is licenced under the GPL.
 */
 
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
+
 
 #define valid_port(idx) ((idx) == 1 || (idx) == 2)
 
 /* clock device associated with the hcd */
 
+
+#define DRIVER_DESC "OHCI S3CXXXX driver"
+
+static const char hcd_name[] = "ohci-s3cxxxx";
+
 static struct clk *clk;
 static struct clk *usb_clk;
 
 /* forward definitions */
 
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+			u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
+
 static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
 
 /* conversion functions */
@@ -93,7 +110,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd, char *buf)
 	int orig;
 	int portno;
 
-	orig  = ohci_hub_status_data(hcd, buf);
+	orig = orig_ohci_hub_status_data(hcd, buf);
 
 	if (info == NULL)
 		return orig;
@@ -164,7 +181,7 @@ static int ohci_s3c2410_hub_control(
 	 * process the request straight away and exit */
 
 	if (info == NULL) {
-		ret = ohci_hub_control(hcd, typeReq, wValue,
+		ret = orig_ohci_hub_control(hcd, typeReq, wValue,
 				       wIndex, buf, wLength);
 		goto out;
 	}
@@ -214,7 +231,7 @@ static int ohci_s3c2410_hub_control(
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
 	if (ret)
 		goto out;
 
@@ -373,8 +390,6 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 	s3c2410_start_hc(dev, hcd);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
-
 	retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
 	if (retval != 0)
 		goto err_ioremap;
@@ -391,71 +406,7 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_s3c2410_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-
-static const struct hc_driver ohci_s3c2410_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"S3C24XX OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.start =		ohci_s3c2410_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_s3c2410_hub_status_data,
-	.hub_control =		ohci_s3c2410_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/* device driver */
+static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;
 
 static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
 {
@@ -532,4 +483,39 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {
 	},
 };
 
+static int __init ohci_s3cxxxx_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
+
+	/*
+	 * The Samsung HW has some unusual quirks, which require
+	 * Sumsung-specific workarounds. We override certain hc_driver
+	 * functions here to achieve that. We explicitly do not enhance
+	 * ohci_driver_overrides to allow this more easily, since this
+	 * is an unusual case, and we don't want to encourage others to
+	 * override these functions by making it too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_s3c2410_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_s3c2410_hc_driver.hub_status_data;
+
+	ohci_s3c2410_hc_driver.hub_status_data	= ohci_s3c2410_hub_status_data;
+	ohci_s3c2410_hc_driver.hub_control	= ohci_s3c2410_hub_control;
+
+	return platform_driver_register(&ohci_hcd_s3c2410_driver);
+}
+module_init(ohci_s3cxxxx_init);
+
+static void __exit ohci_s3cxxxx_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_s3c2410_driver);
+}
+module_exit(ohci_s3cxxxx_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:s3c2410-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH  V4 0/6] USB: OHCI: more bus glues as separate modules
  2013-07-22  9:19 ` [PATCH 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (5 preceding siblings ...)
  2013-07-22  9:19   ` [PATCH 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
@ 2013-07-22  9:41   ` manjunath
  6 siblings, 0 replies; 110+ messages in thread
From: manjunath @ 2013-07-22  9:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 22 July 2013 02:49 PM, Manjunath Goudar wrote:
> These patches are for separating the SOC On-Chip ohci host controller
> from ohci-hcd host code into its own driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.12.
>
> V2:
>    In patch 5/6 and 6/6:
>    -Set non-standard fields in hc_driver manually, rather than
>     relying on an expanded struct ohci_driver_overrides.
>    -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
>     relying on ohci_hub_control and hub_status_data being exported.
>
>    In patch 1/6 to 4/6
>    -ohci_setup() has been removed because it is called in .reset member
>     of the ohci_hc_driver structure.
>
> V3:
>   In patch 5/6 and 6/6:
>   -ohci_setup() has been removed because it is called in .reset member
>    of the ohci_hc_driver structure.
>
>   In patch 5/6:
>   -The ohci_restart() function is not required in  current scenario,
>    only discarding connection state of integrated transceivers is sufficient,
>    for this directly handling ohci->hc_control.
>
>   In patch 2/6 :
>   -rewritten if (config->otg || config->rwc) block statements into
>    two separate 'if blocks' to handle below scenarios
>    1. config->otg set scenario.
>    2. if any of these (config->otg, config->rwc) are set, this
>       scenario should be handled only after ohci_setup()
>
>   In patch 1/6 and 4/6:
>    No change.
>
> V4:
>   In patch 1/6 and 4/6:
>    No change.
>   
>   In patch 2/6 :
>   -usb_remove_hcd() function is required a valid clock that is what
>    omap_ohci_clock_power(0) is called after hcd shutdown.
>
>   In patch 3/6 :
>   -V3 modification revert back, only ohci->regs setting write()
>    function has been removed because ohci->regs doesn't get set until
>    usb_add_hcd.
>
>   In patch 5/6 :
>   - Removed extra space after "tristate".
>   - Removed extra space between function name  and '(' characters.
>   - MODULE_ALIAS line moved to last statement of ohci-at91 file.
>
>   In patch 6/6 :
>   - Removed extra space before the '='.
>   - Moved  /* forward definitions */ line before the declarations of functions.
>
> Manjunath Goudar (6):
>    USB: OHCI: make ohci-exynos a separate driver
>    USB: OHCI: make ohci-omap a separate driver
>    USB: OHCI: make ohci-omap3 a separate driver
>    USB: OHCI: make ohci-spear a separate driver
>    USB: OHCI: make ohci-at91 a separate driver
>    USB: OHCI: make ohci-s3c2410 a separate driver
>
>   drivers/usb/host/Kconfig        |   30 ++++++-
>   drivers/usb/host/Makefile       |    6 ++
>   drivers/usb/host/ohci-at91.c    |  153 ++++++++++++++++-------------------
>   drivers/usb/host/ohci-exynos.c  |  167 ++++++++++++++++-----------------------
>   drivers/usb/host/ohci-hcd.c     |  108 -------------------------
>   drivers/usb/host/ohci-omap.c    |  156 +++++++++++++-----------------------
>   drivers/usb/host/ohci-omap3.c   |  118 +++++++++------------------
>   drivers/usb/host/ohci-s3c2410.c |  128 +++++++++++++-----------------
>   drivers/usb/host/ohci-spear.c   |  140 +++++++++++++-------------------
>   9 files changed, 374 insertions(+), 632 deletions(-)
>
I am very sorry, this is patch V4 series.

Thanks
Manjunath Goudar

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH 6/6] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-07-22  9:19   ` [PATCH 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
@ 2013-07-23  8:23     ` Tomasz Figa
  0 siblings, 0 replies; 110+ messages in thread
From: Tomasz Figa @ 2013-07-23  8:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Manjunath,

Please see some comments inline.

On Monday 22 of July 2013 14:49:30 Manjunath Goudar wrote:
> Separate the Samsung OHCI S3CXXXX host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.12.
> 
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Acked-by: Alan Stern <stern@rowland.harvard.edu>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Greg KH <greg@kroah.com>
> Cc: linux-usb at vger.kernel.org
> 
> V2:
>  -Set non-standard fields in ohci_s3c2410_hc_driver manually, rather
> than relying on an expanded struct ohci_driver_overrides.
>  -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
>   relying on ohci_hub_control and hub_status_data being exported.
> 
> V3:
>  -Kconfig wrong parentheses discription fixed.
>  -ohci_setup() has been removed because it is called in .reset member
>   of the ohci_hc_driver structure.
> 
> V4:
>  - Removed extra space before the '='.
>  - Moved  /* forward definitions */ line before the declarations of
> functions. ---
>  drivers/usb/host/Kconfig        |    8 +++
>  drivers/usb/host/Makefile       |    1 +
>  drivers/usb/host/ohci-hcd.c     |   18 ------
>  drivers/usb/host/ohci-s3c2410.c |  128
> +++++++++++++++++---------------------- 4 files changed, 66
> insertions(+), 89 deletions(-)
> 
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 693560a..795d14d 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
>            Enables support for the on-chip OHCI controller on
>            ST SPEAr chips.
> 
> +config USB_OHCI_HCD_S3CXXXX
> +        tristate "Support for S3CXXXX on-chip OHCI USB controller"
> +        depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX)
> +        default y
> +        ---help---
> +          Enables support for the on-chip OHCI controller on
> +          S3CXXXX chips.
> +

Please keep the name s3c2410 for consistency. Having all the names come 
from the first SoC with this hardware is somewhat deterministic as opposed 
to some other naming methods, e.g. ohci-exynos2, while later on a 
different SoC from Exynos 2 shows up that needs a different driver.

>  config USB_OHCI_HCD_AT91
>          tristate "Support for Atmel on-chip OHCI USB controller"
>          depends on USB_OHCI_HCD && ARCH_AT91
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index a70b044..9dffe81 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -51,6 +51,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
>  obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
>  obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
>  obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
> +obj-$(CONFIG_USB_OHCI_HCD_S3CXXXX)	+= ohci-s3c2410.o
> 
>  obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
>  obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
> diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
> index b48c892..b69a49e 100644
> --- a/drivers/usb/host/ohci-hcd.c
> +++ b/drivers/usb/host/ohci-hcd.c
> @@ -1177,11 +1177,6 @@ MODULE_LICENSE ("GPL");
>  #define SA1111_DRIVER		ohci_hcd_sa1111_driver
>  #endif
> 
> -#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
> -#include "ohci-s3c2410.c"
> -#define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
> -#endif
> -
>  #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
>  #include "ohci-pxa27x.c"
>  #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
> @@ -1293,12 +1288,6 @@ static int __init ohci_hcd_mod_init(void)
>  		goto error_tmio;
>  #endif
> 
> -#ifdef S3C2410_PLATFORM_DRIVER
> -	retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER);
> -	if (retval < 0)
> -		goto error_s3c2410;
> -#endif
> -
>  #ifdef EP93XX_PLATFORM_DRIVER
>  	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
>  	if (retval < 0)
> @@ -1332,10 +1321,6 @@ static int __init ohci_hcd_mod_init(void)
>  	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
>   error_ep93xx:
>  #endif
> -#ifdef S3C2410_PLATFORM_DRIVER
> -	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
> - error_s3c2410:
> -#endif
>  #ifdef TMIO_OHCI_DRIVER
>  	platform_driver_unregister(&TMIO_OHCI_DRIVER);
>   error_tmio:
> @@ -1382,9 +1367,6 @@ static void __exit ohci_hcd_mod_exit(void)
>  #ifdef EP93XX_PLATFORM_DRIVER
>  	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
>  #endif
> -#ifdef S3C2410_PLATFORM_DRIVER
> -	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
> -#endif
>  #ifdef TMIO_OHCI_DRIVER
>  	platform_driver_unregister(&TMIO_OHCI_DRIVER);
>  #endif
> diff --git a/drivers/usb/host/ohci-s3c2410.c
> b/drivers/usb/host/ohci-s3c2410.c index e125770..48b5948 100644
> --- a/drivers/usb/host/ohci-s3c2410.c
> +++ b/drivers/usb/host/ohci-s3c2410.c
> @@ -19,19 +19,36 @@
>   * This file is licenced under the GPL.
>  */
> 
> -#include <linux/platform_device.h>
>  #include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
>  #include <linux/platform_data/usb-ohci-s3c2410.h>
> +#include <linux/usb.h>
> +#include <linux/usb/hcd.h>
> +
> +#include "ohci.h"
> +
> 
>  #define valid_port(idx) ((idx) == 1 || (idx) == 2)
> 
>  /* clock device associated with the hcd */
> 
> +
> +#define DRIVER_DESC "OHCI S3CXXXX driver"
> +
> +static const char hcd_name[] = "ohci-s3cxxxx";
> +

Ditto.

>  static struct clk *clk;
>  static struct clk *usb_clk;
> 
>  /* forward definitions */
> 
> +static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
> +			u16 wValue, u16 wIndex, char *buf, u16 wLength);
> +static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char
> *buf); +
>  static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
> 
>  /* conversion functions */
> @@ -93,7 +110,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd,
> char *buf) int orig;
>  	int portno;
> 
> -	orig  = ohci_hub_status_data(hcd, buf);
> +	orig = orig_ohci_hub_status_data(hcd, buf);
> 
>  	if (info == NULL)
>  		return orig;
> @@ -164,7 +181,7 @@ static int ohci_s3c2410_hub_control(
>  	 * process the request straight away and exit */
> 
>  	if (info == NULL) {
> -		ret = ohci_hub_control(hcd, typeReq, wValue,
> +		ret = orig_ohci_hub_control(hcd, typeReq, wValue,
>  				       wIndex, buf, wLength);
>  		goto out;
>  	}
> @@ -214,7 +231,7 @@ static int ohci_s3c2410_hub_control(
>  		break;
>  	}
> 
> -	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, 
wLength);
> +	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex, buf,
> wLength); if (ret)
>  		goto out;
> 
> @@ -373,8 +390,6 @@ static int usb_hcd_s3c2410_probe(const struct
> hc_driver *driver,
> 
>  	s3c2410_start_hc(dev, hcd);
> 
> -	ohci_hcd_init(hcd_to_ohci(hcd));
> -
>  	retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
>  	if (retval != 0)
>  		goto err_ioremap;
> @@ -391,71 +406,7 @@ static int usb_hcd_s3c2410_probe(const struct
> hc_driver *driver,
> 
>  /*---------------------------------------------------------------------
> ----*/
> 
> -static int
> -ohci_s3c2410_start(struct usb_hcd *hcd)
> -{
> -	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
> -	int ret;
> -
> -	ret = ohci_init(ohci);
> -	if (ret < 0)
> -		return ret;
> -
> -	ret = ohci_run(ohci);
> -	if (ret < 0) {
> -		dev_err(hcd->self.controller, "can't start %s\n",
> -			hcd->self.bus_name);
> -		ohci_stop(hcd);
> -		return ret;
> -	}
> -
> -	return 0;
> -}
> -
> -
> -static const struct hc_driver ohci_s3c2410_hc_driver = {
> -	.description =		hcd_name,
> -	.product_desc =		"S3C24XX OHCI",
> -	.hcd_priv_size =	sizeof(struct ohci_hcd),
> -
> -	/*
> -	 * generic hardware linkage
> -	 */
> -	.irq =			ohci_irq,
> -	.flags =		HCD_USB11 | HCD_MEMORY,
> -
> -	/*
> -	 * basic lifecycle operations
> -	 */
> -	.start =		ohci_s3c2410_start,
> -	.stop =			ohci_stop,
> -	.shutdown =		ohci_shutdown,
> -
> -	/*
> -	 * managing i/o requests and associated device resources
> -	 */
> -	.urb_enqueue =		ohci_urb_enqueue,
> -	.urb_dequeue =		ohci_urb_dequeue,
> -	.endpoint_disable =	ohci_endpoint_disable,
> -
> -	/*
> -	 * scheduling support
> -	 */
> -	.get_frame_number =	ohci_get_frame,
> -
> -	/*
> -	 * root hub support
> -	 */
> -	.hub_status_data =	ohci_s3c2410_hub_status_data,
> -	.hub_control =		ohci_s3c2410_hub_control,
> -#ifdef	CONFIG_PM
> -	.bus_suspend =		ohci_bus_suspend,
> -	.bus_resume =		ohci_bus_resume,
> -#endif
> -	.start_port_reset =	ohci_start_port_reset,
> -};
> -
> -/* device driver */
> +static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;
> 
>  static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
>  {
> @@ -532,4 +483,39 @@ static struct platform_driver
> ohci_hcd_s3c2410_driver = { },
>  };
> 
> +static int __init ohci_s3cxxxx_init(void)
> +{
> +	if (usb_disabled())
> +		return -ENODEV;
> +
> +	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
> +	ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
> +
> +	/*
> +	 * The Samsung HW has some unusual quirks, which require
> +	 * Sumsung-specific workarounds. We override certain hc_driver
> +	 * functions here to achieve that. We explicitly do not enhance
> +	 * ohci_driver_overrides to allow this more easily, since this
> +	 * is an unusual case, and we don't want to encourage others to
> +	 * override these functions by making it too easy.
> +	 */
> +
> +	orig_ohci_hub_control = ohci_s3c2410_hc_driver.hub_control;
> +	orig_ohci_hub_status_data = 
ohci_s3c2410_hc_driver.hub_status_data;
> +
> +	ohci_s3c2410_hc_driver.hub_status_data	= 
ohci_s3c2410_hub_status_data;
> +	ohci_s3c2410_hc_driver.hub_control	= 
ohci_s3c2410_hub_control; +
> +	return platform_driver_register(&ohci_hcd_s3c2410_driver);
> +}
> +module_init(ohci_s3cxxxx_init);
> +
> +static void __exit ohci_s3cxxxx_cleanup(void)
> +{
> +	platform_driver_unregister(&ohci_hcd_s3c2410_driver);
> +}
> +module_exit(ohci_s3cxxxx_cleanup);
> +
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +MODULE_LICENSE("GPL");
>  MODULE_ALIAS("platform:s3c2410-ohci");

Otherwise looks good to me. I will try to test this on S3C6410 in next 
days.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH 2/6] USB: OHCI: make ohci-omap a separate driver
  2013-07-22  9:19   ` [PATCH 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
@ 2013-07-23 18:39     ` Alan Stern
  0 siblings, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-07-23 18:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 22 Jul 2013, Manjunath Goudar wrote:

> Separate the  TI OHCI OMAP1/2 host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.
> 
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Cc: Felipe Balbi <balbi@ti.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Greg KH <greg@kroah.com>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: linux-usb at vger.kernel.org
> 
> V2:
>  -omap_ohci_clock_power(0) called in usb_hcd_omap_remove().
>  -Removed ohci_setup() call from usb_hcd_omap_probe().
>  -host_enabled and host_initialized variables aren't used for anything
>   thats what removed.
> 
> V3:
>  -rewritten if (config->otg || config->rwc) block statements into
>   two separate 'if blocks' to handle below scenarios
>   1. config->otg set scenario.
>   2. if any of these (config->otg, config->rwc) are set, this
>      scenario should be handled only after ohci_setup()
> 
> V4:
>  -usb_remove_hcd() function is required a valid clock that is what
>   omap_ohci_clock_power(0) is called after hcd shutdown.

> @@ -369,11 +367,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
>  	if (retval)
>  		goto err3;
>  
> -	host_initialized = 1;
> -
> -	if (!host_enabled)
> -		omap_ohci_clock_power(0);
> -
>  	return 0;
>  err3:
>  	iounmap(hcd->regs);

I suspect there's a mistake here, and the omap_ohci_clock_power() call 
perhaps should be moved after the "err3:" label.  But that mistake (if 
it is a mistake) was present in the original code, and this patch 
shouldn't change it.

Acked-by: Alan Stern <stern@rowland.harvard.edu>

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH 3/6] USB: OHCI: make ohci-omap3 a separate driver
  2013-07-22  9:19   ` [PATCH 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
@ 2013-07-23 18:43     ` Alan Stern
  0 siblings, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-07-23 18:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 22 Jul 2013, Manjunath Goudar wrote:

> Separate the  TI OHCI OMAP3 host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.
> 
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Cc: Anand Gadiyar <gadiyar@ti.com>
> Cc: Felipe Balbi <balbi@ti.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Greg KH <greg@kroah.com>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: linux-usb at vger.kernel.org
> 
> V2:
>  -ohci_setup() removed because it is called in .reset member
>   of the ohci_hc_driver structure.
>  -The improper multi-line commenting style written in proper way.
>   ('*' characters aligned in vertically).
> 
> V3:
>  -RemoteWakeupConnected setting has been removed.
> 
> V4:
>  -V3 modification revert back, only ohci->regs setting write()
>   function has been removed because ohci->regs doesn't get set until
>   usb_add_hcd.

Acked-by: Alan Stern <stern@rowland.harvard.edu>

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH 5/6] USB: OHCI: make ohci-at91 a separate driver
  2013-07-22  9:19   ` [PATCH 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
@ 2013-07-23 18:45     ` Alan Stern
  0 siblings, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-07-23 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 22 Jul 2013, Manjunath Goudar wrote:

> Separate the  TI OHCI Atmel host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.12.
> 
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: Greg KH <greg@kroah.com>
> Cc: linux-usb at vger.kernel.org
> 
> V2:
>  -Set non-standard fields in ohci_at91_hc_driver manually, rather than
>   relying on an expanded struct ohci_driver_overrides.
>  -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
>   relying on ohci_hub_control and hub_status_data being exported.
>  -ohci_setup() has been removed because it is called in .reset member
>   of the ohci_hc_driver structure.
> 
> V3:
>  -The ohci_restart() function is not required in  current scenario,
>   only discarding connection state of integrated transceivers is sufficient,
>   for this directly handling ohci->hc_control.
> 
> V4:
>  - Removed extra space after "tristate".
>  - Removed extra space between function name  and '(' characters.
>  - MODULE_ALIAS line moved to last statement of ohci-at91 file.

Acked-by: Alan Stern <stern@rowland.harvard.edu>

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V4 0/6]  USB: OHCI: more bus glues as separate modules
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (9 preceding siblings ...)
  2013-07-22  9:19 ` [PATCH 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
@ 2013-07-31  6:07 ` Manjunath Goudar
  2013-07-31  6:07   ` [PATCH V4 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
                     ` (5 more replies)
  2013-08-10  7:37 ` [PATCH V4 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (3 subsequent siblings)
  14 siblings, 6 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-07-31  6:07 UTC (permalink / raw)
  To: linux-arm-kernel

These patches are for separating the SOC On-Chip ohci host controller
from ohci-hcd host code into its own driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.12.

V2:
  In patch 5/6 and 6/6:
  -Set non-standard fields in hc_driver manually, rather than
   relying on an expanded struct ohci_driver_overrides.
  -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
   relying on ohci_hub_control and hub_status_data being exported.

  In patch 1/6 to 4/6
  -ohci_setup() has been removed because it is called in .reset member
   of the ohci_hc_driver structure.

V3:
 In patch 5/6 and 6/6:
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

 In patch 5/6:
 -The ohci_restart() function is not required in  current scenario,
  only discarding connection state of integrated transceivers is sufficient,
  for this directly handling ohci->hc_control.

 In patch 2/6 :
 -rewritten if (config->otg || config->rwc) block statements into
  two separate 'if blocks' to handle below scenarios
  1. config->otg set scenario.
  2. if any of these (config->otg, config->rwc) are set, this
     scenario should be handled only after ohci_setup()
 
 In patch 1/6 and 4/6:
  No change.

V4:
 In patch 1/6 and 4/6:
  No change.

 In patch 2/6 :
 -usb_remove_hcd() function is required a valid clock that is what
  omap_ohci_clock_power(0) is called after hcd shutdown.

 In patch 3/6 :
 -V3 modification revert back, only ohci->regs setting write()
  function has been removed because ohci->regs doesn't get set until
  usb_add_hcd.

 In patch 5/6 :
 - Removed extra space after "tristate".
 - Removed extra space between function name  and '(' characters.
 - MODULE_ALIAS line moved to last statement of ohci-at91 file.

 In patch 6/6 :
 - Removed extra space before the '='.
 - Moved  /* forward definitions */ line before the declarations of functions.

Manjunath Goudar (6):
  USB: OHCI: make ohci-exynos a separate driver
  USB: OHCI: make ohci-omap a separate driver
  USB: OHCI: make ohci-omap3 a separate driver
  USB: OHCI: make ohci-spear a separate driver
  USB: OHCI: make ohci-at91 a separate driver
  USB: OHCI: make ohci-s3c2410 a separate driver

 drivers/usb/host/Kconfig        |   30 ++++++-
 drivers/usb/host/Makefile       |    6 ++
 drivers/usb/host/ohci-at91.c    |  153 ++++++++++++++++-------------------
 drivers/usb/host/ohci-exynos.c  |  167 ++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c     |  108 -------------------------
 drivers/usb/host/ohci-omap.c    |  156 +++++++++++++-----------------------
 drivers/usb/host/ohci-omap3.c   |  118 +++++++++------------------
 drivers/usb/host/ohci-s3c2410.c |  128 +++++++++++++-----------------
 drivers/usb/host/ohci-spear.c   |  140 +++++++++++++-------------------
 9 files changed, 374 insertions(+), 632 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V4 1/6] USB: OHCI: make ohci-exynos a separate driver
  2013-07-31  6:07 ` Manjunath Goudar
@ 2013-07-31  6:07   ` Manjunath Goudar
  2013-07-31  6:08   ` [PATCH V4 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-07-31  6:07 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  Samsung OHCI EXYNOS host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Cc: Vivek Gautam <gautam.vivek@samsung.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -exynos_ohci_hcd structure assignment error fixed.
 -Removed multiple usb_create_hcd() from prob funtion.
 -platform_set_drvdata() called before exynos_ohci_phy_enable().
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure

V3:
 -No major changes only "exynos" written in capital letters
  in "OHCI exynos driver".
---
 drivers/usb/host/Kconfig       |    2 +-
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ohci-exynos.c |  167 +++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c    |   18 -----
 4 files changed, 71 insertions(+), 117 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 7bc598b..7b8f6bd 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -463,7 +463,7 @@ config USB_OHCI_SH
 	  If you use the PCI OHCI controller, this option is not necessary.
 
 config USB_OHCI_EXYNOS
-	boolean "OHCI support for Samsung EXYNOS SoC Series"
+	tristate "OHCI support for Samsung EXYNOS SoC Series"
 	depends on ARCH_EXYNOS
 	help
 	 Enable support for the Samsung Exynos SOC's on-chip OHCI controller.
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 480e203..26cf69a 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
+obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index b0b542c..ae6068d 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -12,24 +12,39 @@
  */
 
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-exynos.h>
 #include <linux/usb/phy.h>
 #include <linux/usb/samsung_usb_phy.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include "ohci.h"
+
+#define DRIVER_DESC "OHCI EXYNOS driver"
+
+static const char hcd_name[] = "ohci-exynos";
+static struct hc_driver __read_mostly exynos_ohci_hc_driver;
+
+#define to_exynos_ohci(hcd) (struct exynos_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
 
 struct exynos_ohci_hcd {
-	struct device *dev;
-	struct usb_hcd *hcd;
 	struct clk *clk;
 	struct usb_phy *phy;
 	struct usb_otg *otg;
 	struct exynos4_ohci_platdata *pdata;
 };
 
-static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_enable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_init(exynos_ohci->phy);
@@ -37,9 +52,10 @@ static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
 }
 
-static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_disable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_shutdown(exynos_ohci->phy);
@@ -47,63 +63,11 @@ static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
 }
 
-static int ohci_exynos_reset(struct usb_hcd *hcd)
-{
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-static int ohci_exynos_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci);
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-static const struct hc_driver exynos_ohci_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "EXYNOS OHCI Host Controller",
-	.hcd_priv_size		= sizeof(struct ohci_hcd),
-
-	.irq			= ohci_irq,
-	.flags			= HCD_MEMORY|HCD_USB11,
-
-	.reset			= ohci_exynos_reset,
-	.start			= ohci_exynos_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-
-	.get_frame_number	= ohci_get_frame,
-
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-	.start_port_reset	= ohci_start_port_reset,
-};
-
 static int exynos_ohci_probe(struct platform_device *pdev)
 {
 	struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_ohci_hcd *exynos_ohci;
 	struct usb_hcd *hcd;
-	struct ohci_hcd *ohci;
 	struct resource *res;
 	struct usb_phy *phy;
 	int irq;
@@ -119,10 +83,14 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	if (!pdev->dev.coherent_dma_mask)
 		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
-	exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd),
-					GFP_KERNEL);
-	if (!exynos_ohci)
+	hcd = usb_create_hcd(&exynos_ohci_hc_driver,
+				&pdev->dev, dev_name(&pdev->dev));
+	if (!hcd) {
+		dev_err(&pdev->dev, "Unable to create HCD\n");
 		return -ENOMEM;
+	}
+
+	exynos_ohci = to_exynos_ohci(hcd);
 
 	if (of_device_is_compatible(pdev->dev.of_node,
 					"samsung,exynos5440-ohci"))
@@ -143,17 +111,6 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	}
 
 skip_phy:
-
-	exynos_ohci->dev = &pdev->dev;
-
-	hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
-					dev_name(&pdev->dev));
-	if (!hcd) {
-		dev_err(&pdev->dev, "Unable to create HCD\n");
-		return -ENOMEM;
-	}
-
-	exynos_ohci->hcd = hcd;
 	exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");
 
 	if (IS_ERR(exynos_ohci->clk)) {
@@ -190,26 +147,21 @@ skip_phy:
 	}
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	platform_set_drvdata(pdev, hcd);
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to add USB HCD\n");
 		goto fail_add_hcd;
 	}
-
-	platform_set_drvdata(pdev, exynos_ohci);
-
 	return 0;
 
 fail_add_hcd:
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 fail_io:
 	clk_disable_unprepare(exynos_ohci->clk);
 fail_clk:
@@ -219,16 +171,15 @@ fail_clk:
 
 static int exynos_ohci_remove(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	usb_remove_hcd(hcd);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -239,8 +190,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
 
 static void exynos_ohci_shutdown(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
 	if (hcd->driver->shutdown)
 		hcd->driver->shutdown(hcd);
@@ -249,9 +199,10 @@ static void exynos_ohci_shutdown(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int exynos_ohci_suspend(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	struct platform_device *pdev = to_platform_device(dev);
 	unsigned long flags;
 	int rc = 0;
 
@@ -271,10 +222,9 @@ static int exynos_ohci_suspend(struct device *dev)
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -286,16 +236,16 @@ fail:
 
 static int exynos_ohci_resume(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd			= dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci	= to_exynos_ohci(hcd);
+	struct platform_device *pdev		= to_platform_device(dev);
 
 	clk_prepare_enable(exynos_ohci->clk);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	ohci_resume(hcd, false);
 
@@ -306,6 +256,10 @@ static int exynos_ohci_resume(struct device *dev)
 #define exynos_ohci_resume	NULL
 #endif
 
+static const struct ohci_driver_overrides exynos_overrides __initconst = {
+	.extra_priv_size =	sizeof(struct exynos_ohci_hcd),
+};
+
 static const struct dev_pm_ops exynos_ohci_pm_ops = {
 	.suspend	= exynos_ohci_suspend,
 	.resume		= exynos_ohci_resume,
@@ -331,6 +285,23 @@ static struct platform_driver exynos_ohci_driver = {
 		.of_match_table	= of_match_ptr(exynos_ohci_match),
 	}
 };
+static int __init ohci_exynos_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&exynos_ohci_hc_driver, &exynos_overrides);
+	return platform_driver_register(&exynos_ohci_driver);
+}
+module_init(ohci_exynos_init);
+
+static void __exit ohci_exynos_cleanup(void)
+{
+	platform_driver_unregister(&exynos_ohci_driver);
+}
+module_exit(ohci_exynos_cleanup);
 
 MODULE_ALIAS("platform:exynos-ohci");
 MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index a9d3437..2980bb6 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_EXYNOS
-#include "ohci-exynos.c"
-#define EXYNOS_PLATFORM_DRIVER	exynos_ohci_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP1
 #include "ohci-omap.c"
 #define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
@@ -1336,12 +1331,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_s3c2410;
 #endif
 
-#ifdef EXYNOS_PLATFORM_DRIVER
-	retval = platform_driver_register(&EXYNOS_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_exynos;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1395,10 +1384,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
- error_exynos:
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
  error_s3c2410:
@@ -1463,9 +1448,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V4 2/6] USB: OHCI: make ohci-omap a separate driver
  2013-07-31  6:07 ` Manjunath Goudar
  2013-07-31  6:07   ` [PATCH V4 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
@ 2013-07-31  6:08   ` Manjunath Goudar
  2013-07-31  6:08   ` [PATCH V4 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-07-31  6:08 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP1/2 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -omap_ohci_clock_power(0) called in usb_hcd_omap_remove().
 -Removed ohci_setup() call from usb_hcd_omap_probe().
 -host_enabled and host_initialized variables aren't used for anything
  thats what removed.

V3:
 -rewritten if (config->otg || config->rwc) block statements into
  two separate 'if blocks' to handle below scenarios
  1. config->otg set scenario.
  2. if any of these (config->otg, config->rwc) are set, this
     scenario should be handled only after ohci_setup()

V4:
 -usb_remove_hcd() function is required a valid clock that is what
  omap_ohci_clock_power(0) is called after hcd shutdown.
---
 drivers/usb/host/Kconfig     |    2 +-
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-hcd.c  |   18 -----
 drivers/usb/host/ohci-omap.c |  156 ++++++++++++++----------------------------
 4 files changed, 55 insertions(+), 122 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 7b8f6bd..99b7e7e 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -376,7 +376,7 @@ config USB_OHCI_HCD
 if USB_OHCI_HCD
 
 config USB_OHCI_HCD_OMAP1
-	bool "OHCI support for OMAP1/2 chips"
+	tristate "OHCI support for OMAP1/2 chips"
 	depends on ARCH_OMAP1
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 26cf69a..c7076ec 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 2980bb6..1abc1e7 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP1
-#include "ohci-omap.c"
-#define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP3
 #include "ohci-omap3.c"
 #define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
@@ -1289,12 +1284,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP1_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP1_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap1_platform;
-#endif
-
 #ifdef OMAP3_PLATFORM_DRIVER
 	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1408,10 +1397,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
  error_omap3_platform:
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
- error_omap1_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1466,9 +1451,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OMAP3_PLATFORM_DRIVER
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 8747fa6..8149ef0 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -14,12 +14,21 @@
  * This file is licenced under the GPL.
  */
 
-#include <linux/signal.h>
-#include <linux/jiffies.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
 #include <asm/io.h>
 #include <asm/mach-types.h>
@@ -42,10 +51,7 @@
 #define OMAP1510_LB_MMU_RAM_H	0xfffec234
 #define OMAP1510_LB_MMU_RAM_L	0xfffec238
 
-
-#ifndef CONFIG_ARCH_OMAP
-#error "This file is OMAP bus glue.  CONFIG_OMAP must be defined."
-#endif
+#define DRIVER_DESC "OHCI OMAP driver"
 
 #ifdef CONFIG_TPS65010
 #include <linux/i2c/tps65010.h>
@@ -68,8 +74,9 @@ extern int ocpi_enable(void);
 
 static struct clk *usb_host_ck;
 static struct clk *usb_dc_ck;
-static int host_enabled;
-static int host_initialized;
+
+static const char hcd_name[] = "ohci-omap";
+static struct hc_driver __read_mostly ohci_omap_hc_driver;
 
 static void omap_ohci_clock_power(int on)
 {
@@ -188,7 +195,7 @@ static void start_hnp(struct ohci_hcd *ohci)
 
 /*-------------------------------------------------------------------------*/
 
-static int ohci_omap_init(struct usb_hcd *hcd)
+static int ohci_omap_reset(struct usb_hcd *hcd)
 {
 	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
 	struct omap_usb_config	*config = hcd->self.controller->platform_data;
@@ -198,9 +205,9 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	dev_dbg(hcd->self.controller, "starting USB Controller\n");
 
 	if (config->otg) {
-		ohci_to_hcd(ohci)->self.otg_port = config->otg;
+		hcd->self.otg_port = config->otg;
 		/* default/minimum OTG power budget:  8 mA */
-		ohci_to_hcd(ohci)->power_budget = 8;
+		hcd->power_budget = 8;
 	}
 
 	/* boards can use OTG transceivers in non-OTG modes */
@@ -238,9 +245,15 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 		omap_1510_local_bus_init();
 	}
 
-	if ((ret = ohci_init(ohci)) < 0)
+	ret = ohci_setup(hcd);
+	if (ret < 0)
 		return ret;
 
+	if (config->otg || config->rwc) {
+		ohci->hc_control = OHCI_CTRL_RWC;
+		writel(OHCI_CTRL_RWC, &ohci->regs->control);
+	}
+
 	/* board-specific power switching and overcurrent support */
 	if (machine_is_omap_osk() || machine_is_omap_innovator()) {
 		u32	rh = roothub_a (ohci);
@@ -281,14 +294,6 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	return 0;
 }
 
-static void ohci_omap_stop(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
-	ohci_stop(hcd);
-	omap_ohci_clock_power(0);
-}
-
-
 /*-------------------------------------------------------------------------*/
 
 /**
@@ -304,7 +309,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 {
 	int retval, irq;
 	struct usb_hcd *hcd = 0;
-	struct ohci_hcd *ohci;
 
 	if (pdev->num_resources != 2) {
 		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
@@ -354,12 +358,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 		goto err2;
 	}
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
-
-	host_initialized = 0;
-	host_enabled = 1;
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		retval = -ENXIO;
@@ -369,11 +367,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 	if (retval)
 		goto err3;
 
-	host_initialized = 1;
-
-	if (!host_enabled)
-		omap_ohci_clock_power(0);
-
 	return 0;
 err3:
 	iounmap(hcd->regs);
@@ -402,7 +395,9 @@ err0:
 static inline void
 usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
+	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
 	usb_remove_hcd(hcd);
+	omap_ohci_clock_power(0);
 	if (!IS_ERR_OR_NULL(hcd->phy)) {
 		(void) otg_set_host(hcd->phy->otg, 0);
 		usb_put_phy(hcd->phy);
@@ -418,76 +413,6 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_omap_start (struct usb_hcd *hcd)
-{
-	struct omap_usb_config *config;
-	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ret;
-
-	if (!host_enabled)
-		return 0;
-	config = hcd->self.controller->platform_data;
-	if (config->otg || config->rwc) {
-		ohci->hc_control = OHCI_CTRL_RWC;
-		writel(OHCI_CTRL_RWC, &ohci->regs->control);
-	}
-
-	if ((ret = ohci_run (ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop (hcd);
-		return ret;
-	}
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_omap_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap_init,
-	.start =		ohci_omap_start,
-	.stop =			ohci_omap_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static int ohci_hcd_omap_drv_probe(struct platform_device *dev)
 {
 	return usb_hcd_omap_probe(&ohci_omap_hc_driver, dev);
@@ -553,4 +478,29 @@ static struct platform_driver ohci_hcd_omap_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides omap_overrides __initconst = {
+	.product_desc	= "OMAP OHCI",
+	.reset		= ohci_omap_reset
+};
+
+static int __init ohci_omap_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap_hc_driver, &omap_overrides);
+	return platform_driver_register(&ohci_hcd_omap_driver);
+}
+module_init(ohci_omap_init);
+
+static void __exit ohci_omap_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap_driver);
+}
+module_exit(ohci_omap_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V4 3/6] USB: OHCI: make ohci-omap3 a separate driver
  2013-07-31  6:07 ` Manjunath Goudar
  2013-07-31  6:07   ` [PATCH V4 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
  2013-07-31  6:08   ` [PATCH V4 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
@ 2013-07-31  6:08   ` Manjunath Goudar
  2013-07-31  6:08   ` [PATCH V4 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-07-31  6:08 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP3 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Anand Gadiyar <gadiyar@ti.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -The improper multi-line commenting style written in proper way.
  ('*' characters aligned in vertically).

V3:
 -RemoteWakeupConnected setting has been removed.

V4:
 -V3 modification revert back, only ohci->regs setting write()
  function has been removed because ohci->regs doesn't get set until
  usb_add_hcd.
---
 drivers/usb/host/Kconfig      |    2 +-
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 -------
 drivers/usb/host/ohci-omap3.c |  118 +++++++++++++----------------------------
 4 files changed, 40 insertions(+), 99 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 99b7e7e..3eab432 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -383,7 +383,7 @@ config USB_OHCI_HCD_OMAP1
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
 config USB_OHCI_HCD_OMAP3
-	bool "OHCI support for OMAP3 and later chips"
+	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index c7076ec..954466d 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 1abc1e7..cad51d2 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP3
-#include "ohci-omap3.c"
-#define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1284,12 +1279,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP3_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap3_platform;
-#endif
-
 #ifdef OF_PLATFORM_DRIVER
 	retval = platform_driver_register(&OF_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1393,10 +1382,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
  error_of_platform:
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
- error_omap3_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1448,9 +1433,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OF_PLATFORM_DRIVER
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index 8f71357..e14f4d9 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -29,90 +29,22 @@
  *	- add kernel-doc
  */
 
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/of.h>
-#include <linux/dma-mapping.h>
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_init(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "starting OHCI controller\n");
-
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	/*
-	 * RemoteWakeupConnected has to be set explicitly before
-	 * calling ohci_run. The reset value of RWC is 0.
-	 */
-	ohci->hc_control = OHCI_CTRL_RWC;
-	writel(OHCI_CTRL_RWC, &ohci->regs->control);
-
-	ret = ohci_run(ohci);
-
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-	}
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
-	return ret;
-}
+#include "ohci.h"
 
-/*-------------------------------------------------------------------------*/
+#define DRIVER_DESC "OHCI OMAP3 driver"
 
-static const struct hc_driver ohci_omap3_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP3 OHCI Host Controller",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap3_init,
-	.start =		ohci_omap3_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
+static const char hcd_name[] = "ohci-omap3";
+static struct hc_driver __read_mostly ohci_omap3_hc_driver;
 
 /*
  * configure so an HC device and id are always provided
@@ -129,6 +61,7 @@ static const struct hc_driver ohci_omap3_hc_driver = {
 static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 {
 	struct device		*dev = &pdev->dev;
+	struct ohci_hcd		*ohci;
 	struct usb_hcd		*hcd = NULL;
 	void __iomem		*regs = NULL;
 	struct resource		*res;
@@ -185,7 +118,12 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	ohci = hcd_to_ohci(hcd);
+	/*
+	 * RemoteWakeupConnected has to be set explicitly before
+	 * calling ohci_run. The reset value of RWC is 0.
+	 */
+	ohci->hc_control = OHCI_CTRL_RWC;
 
 	ret = usb_add_hcd(hcd, irq, 0);
 	if (ret) {
@@ -256,5 +194,25 @@ static struct platform_driver ohci_hcd_omap3_driver = {
 	},
 };
 
+static int __init ohci_omap3_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap3_hc_driver, NULL);
+	return platform_driver_register(&ohci_hcd_omap3_driver);
+}
+module_init(ohci_omap3_init);
+
+static void __exit ohci_omap3_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap3_driver);
+}
+module_exit(ohci_omap3_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci-omap3");
 MODULE_AUTHOR("Anand Gadiyar <gadiyar@ti.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V4 4/6] USB: OHCI: make ohci-spear a separate driver
  2013-07-31  6:07 ` Manjunath Goudar
                     ` (2 preceding siblings ...)
  2013-07-31  6:08   ` [PATCH V4 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
@ 2013-07-31  6:08   ` Manjunath Goudar
  2013-07-31  6:08   ` [PATCH V4 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
  2013-07-31  6:08   ` [PATCH V4 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
  5 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-07-31  6:08 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the ST OHCI SPEAr host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -debugging stuff isn't needed any more that's what removed.

V3:
 No change.
---
 drivers/usb/host/Kconfig      |    8 +++
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 ------
 drivers/usb/host/ohci-spear.c |  140 +++++++++++++++++------------------------
 4 files changed, 65 insertions(+), 102 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 3eab432..a5a34a3 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -382,6 +382,14 @@ config USB_OHCI_HCD_OMAP1
 	---help---
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
+config USB_OHCI_HCD_SPEAR
+        tristate "Support for ST SPEAr on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && PLAT_SPEAR
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          ST SPEAr chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 954466d..b8ea17c 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
+obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index cad51d2..34ec156 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1212,11 +1212,6 @@ MODULE_LICENSE ("GPL");
 #define OF_PLATFORM_DRIVER	ohci_hcd_ppc_of_driver
 #endif
 
-#ifdef CONFIG_PLAT_SPEAR
-#include "ohci-spear.c"
-#define SPEAR_PLATFORM_DRIVER	spear_ohci_hcd_driver
-#endif
-
 #ifdef CONFIG_PPC_PS3
 #include "ohci-ps3.c"
 #define PS3_SYSTEM_BUS_DRIVER	ps3_ohci_driver
@@ -1333,19 +1328,9 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_davinci;
 #endif
 
-#ifdef SPEAR_PLATFORM_DRIVER
-	retval = platform_driver_register(&SPEAR_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_spear;
-#endif
-
 	return retval;
 
 	/* Error path */
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
- error_spear:
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
  error_davinci:
@@ -1403,9 +1388,6 @@ module_init(ohci_hcd_mod_init);
 
 static void __exit ohci_hcd_mod_exit(void)
 {
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index cc9dd9e..31ff3fc 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -11,92 +11,37 @@
 * warranty of any kind, whether express or implied.
 */
 
-#include <linux/signal.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
+#define DRIVER_DESC "OHCI SPEAr driver"
+
+static const char hcd_name[] = "SPEAr-ohci";
 struct spear_ohci {
-	struct ohci_hcd ohci;
 	struct clk *clk;
 };
 
-#define to_spear_ohci(hcd)	(struct spear_ohci *)hcd_to_ohci(hcd)
-
-static void spear_start_ohci(struct spear_ohci *ohci)
-{
-	clk_prepare_enable(ohci->clk);
-}
-
-static void spear_stop_ohci(struct spear_ohci *ohci)
-{
-	clk_disable_unprepare(ohci->clk);
-}
-
-static int ohci_spear_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-	ohci->regs = hcd->regs;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	create_debug_files(ohci);
-
-#ifdef DEBUG
-	ohci_dump(ohci, 1);
-#endif
-	return 0;
-}
-
-static const struct hc_driver ohci_spear_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "SPEAr OHCI",
-	.hcd_priv_size		= sizeof(struct spear_ohci),
-
-	/* generic hardware linkage */
-	.irq			= ohci_irq,
-	.flags			= HCD_USB11 | HCD_MEMORY,
-
-	/* basic lifecycle operations */
-	.start			= ohci_spear_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-
-	/* managing i/o requests and associated device resources */
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	/* scheduling support */
-	.get_frame_number	= ohci_get_frame,
+#define to_spear_ohci(hcd)     (struct spear_ohci *)(hcd_to_ohci(hcd)->priv)
 
-	/* root hub support */
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-
-	.start_port_reset	= ohci_start_port_reset,
-};
+static struct hc_driver __read_mostly ohci_spear_hc_driver;
 
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
 	const struct hc_driver *driver = &ohci_spear_hc_driver;
+	struct ohci_hcd *ohci;
 	struct usb_hcd *hcd = NULL;
 	struct clk *usbh_clk;
-	struct spear_ohci *ohci_p;
+	struct spear_ohci *sohci_p;
 	struct resource *res;
 	int retval, irq;
 
@@ -151,16 +96,18 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 		goto err_put_hcd;
 	}
 
-	ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
-	ohci_p->clk = usbh_clk;
-	spear_start_ohci(ohci_p);
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	sohci_p = to_spear_ohci(hcd);
+	sohci_p->clk = usbh_clk;
+
+	clk_prepare_enable(sohci_p->clk);
+
+	ohci = hcd_to_ohci(hcd);
 
 	retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0);
 	if (retval == 0)
 		return retval;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
 err_put_hcd:
 	usb_put_hcd(hcd);
 fail:
@@ -172,11 +119,11 @@ fail:
 static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	usb_remove_hcd(hcd);
-	if (ohci_p->clk)
-		spear_stop_ohci(ohci_p);
+	if (sohci_p->clk)
+		clk_disable_unprepare(sohci_p->clk);
 
 	usb_put_hcd(hcd);
 	return 0;
@@ -188,13 +135,14 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
+
 	return 0;
 }
 
@@ -202,13 +150,13 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_start_ohci(ohci_p);
+	clk_prepare_enable(sohci_p->clk);
 	ohci_resume(hcd, false);
 	return 0;
 }
@@ -234,4 +182,28 @@ static struct platform_driver spear_ohci_hcd_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides spear_overrides __initconst = {
+	.extra_priv_size = sizeof(struct spear_ohci),
+};
+static int __init ohci_spear_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_spear_hc_driver, &spear_overrides);
+	return platform_driver_register(&spear_ohci_hcd_driver);
+}
+module_init(ohci_spear_init);
+
+static void __exit ohci_spear_cleanup(void)
+{
+	platform_driver_unregister(&spear_ohci_hcd_driver);
+}
+module_exit(ohci_spear_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Deepak Sikri");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:spear-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V4 5/6] USB: OHCI: make ohci-at91 a separate driver
  2013-07-31  6:07 ` Manjunath Goudar
                     ` (3 preceding siblings ...)
  2013-07-31  6:08   ` [PATCH V4 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
@ 2013-07-31  6:08   ` Manjunath Goudar
  2013-07-31  6:08   ` [PATCH V4 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
  5 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-07-31  6:08 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI Atmel host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.12.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -Set non-standard fields in ohci_at91_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

V3:
 -The ohci_restart() function is not required in  current scenario,
  only discarding connection state of integrated transceivers is sufficient,
  for this directly handling ohci->hc_control.

V4:
 - Removed extra space after "tristate".
 - Removed extra space between function name  and '(' characters.
 - MODULE_ALIAS line moved to last statement of ohci-at91 file.
---
 drivers/usb/host/Kconfig     |    8 +++
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-at91.c |  153 +++++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c  |   18 -----
 4 files changed, 77 insertions(+), 103 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index a5a34a3..693560a 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_AT91
+        tristate "Support for Atmel on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && ARCH_AT91
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          Atmel chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index b8ea17c..a70b044 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
+obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 9677f68..08e28eb 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -13,27 +13,41 @@
  */
 
 #include <linux/clk.h>
-#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/atmel.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
 #include <mach/hardware.h>
 #include <asm/gpio.h>
 
 #include <mach/cpu.h>
 
-#ifndef CONFIG_ARCH_AT91
-#error "CONFIG_ARCH_AT91 must be defined."
-#endif
+
+#include "ohci.h"
 
 #define valid_port(index)	((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
 #define at91_for_each_port(index)	\
 		for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++)
 
 /* interface and function clocks; sometimes also an AHB clock */
+
+#define DRIVER_DESC "OHCI Atmel driver"
+
+static const char hcd_name[] = "ohci-atmel";
+
+static struct hc_driver __read_mostly ohci_at91_hc_driver;
 static struct clk *iclk, *fclk, *hclk;
 static int clocked;
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+			u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
 
 extern int usb_disabled(void);
 
@@ -111,6 +125,8 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
 static int usb_hcd_at91_probe(const struct hc_driver *driver,
 			struct platform_device *pdev)
 {
+	struct at91_usbh_data *board;
+	struct ohci_hcd *ohci;
 	int retval;
 	struct usb_hcd *hcd = NULL;
 
@@ -163,8 +179,10 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
 		goto err5;
 	}
 
+	board = hcd->self.controller->platform_data;
+	ohci = hcd_to_ohci(hcd);
+	ohci->num_ports = board->ports;
 	at91_start_hc(pdev);
-	ohci_hcd_init(hcd_to_ohci(hcd));
 
 	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
 	if (retval == 0)
@@ -221,36 +239,6 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd,
 }
 
 /*-------------------------------------------------------------------------*/
-
-static int
-ohci_at91_reset (struct usb_hcd *hcd)
-{
-	struct at91_usbh_data	*board = hcd->self.controller->platform_data;
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
-	ohci->num_ports = board->ports;
-	return 0;
-}
-
-static int
-ohci_at91_start (struct usb_hcd *hcd)
-{
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_run(ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-	return 0;
-}
-
 static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
 {
 	if (!valid_port(port))
@@ -281,7 +269,7 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
 static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
 	struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
-	int length = ohci_hub_status_data(hcd, buf);
+	int length = orig_ohci_hub_status_data(hcd, buf);
 	int port;
 
 	at91_for_each_port(port) {
@@ -359,7 +347,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex + 1,
+				buf, wLength);
 	if (ret)
 		goto out;
 
@@ -413,51 +402,6 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 /*-------------------------------------------------------------------------*/
 
-static const struct hc_driver ohci_at91_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"AT91 OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_at91_reset,
-	.start =		ohci_at91_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_at91_hub_status_data,
-	.hub_control =		ohci_at91_hub_control,
-#ifdef CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
 {
 	struct platform_device *pdev = data;
@@ -686,7 +630,11 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
 	 * REVISIT: some boards will be able to turn VBUS off...
 	 */
 	if (at91_suspend_entering_slow_clock()) {
-		ohci_usb_reset (ohci);
+		ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
+		ohci->hc_control &= OHCI_CTRL_RWC;
+		ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
+		ohci->rh_state = OHCI_RH_HALTED;
+
 		/* flush the writes */
 		(void) ohci_readl (ohci, &ohci->regs->control);
 		at91_stop_clock();
@@ -713,8 +661,6 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
 #define ohci_hcd_at91_drv_resume  NULL
 #endif
 
-MODULE_ALIAS("platform:at91_ohci");
-
 static struct platform_driver ohci_hcd_at91_driver = {
 	.probe		= ohci_hcd_at91_drv_probe,
 	.remove		= ohci_hcd_at91_drv_remove,
@@ -727,3 +673,40 @@ static struct platform_driver ohci_hcd_at91_driver = {
 		.of_match_table	= of_match_ptr(at91_ohci_dt_ids),
 	},
 };
+
+static int __init ohci_at91_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_at91_hc_driver, NULL);
+
+	/*
+	 * The Atmel HW has some unusual quirks, which require Atmel-specific
+	 * workarounds. We override certain hc_driver functions here to
+	 * achieve that. We explicitly do not enhance ohci_driver_overrides to
+	 * allow this more easily, since this is an unusual case, and we don't
+	 * want to encourage others to override these functions by making it
+	 * too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_at91_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_at91_hc_driver.hub_status_data;
+
+	ohci_at91_hc_driver.hub_status_data	= ohci_at91_hub_status_data;
+	ohci_at91_hc_driver.hub_control		= ohci_at91_hub_control;
+
+	return platform_driver_register(&ohci_hcd_at91_driver);
+}
+module_init(ohci_at91_init);
+
+static void __exit ohci_at91_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_at91_driver);
+}
+module_exit(ohci_at91_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:at91_ohci");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 34ec156..b48c892 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1192,11 +1192,6 @@ MODULE_LICENSE ("GPL");
 #define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver
 #endif
 
-#ifdef CONFIG_ARCH_AT91
-#include "ohci-at91.c"
-#define AT91_PLATFORM_DRIVER	ohci_hcd_at91_driver
-#endif
-
 #ifdef CONFIG_ARCH_LPC32XX
 #include "ohci-nxp.c"
 #define NXP_PLATFORM_DRIVER	usb_hcd_nxp_driver
@@ -1310,12 +1305,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_ep93xx;
 #endif
 
-#ifdef AT91_PLATFORM_DRIVER
-	retval = platform_driver_register(&AT91_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_at91;
-#endif
-
 #ifdef NXP_PLATFORM_DRIVER
 	retval = platform_driver_register(&NXP_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1339,10 +1328,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
  error_nxp:
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
- error_at91:
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
@@ -1394,9 +1379,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef NXP_PLATFORM_DRIVER
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V4 6/6] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-07-31  6:07 ` Manjunath Goudar
                     ` (4 preceding siblings ...)
  2013-07-31  6:08   ` [PATCH V4 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
@ 2013-07-31  6:08   ` Manjunath Goudar
  5 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-07-31  6:08 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the Samsung OHCI S3CXXXX host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.12.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -Set non-standard fields in ohci_s3c2410_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.

V3:
 -Kconfig wrong parentheses discription fixed.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

V4:
 - Removed extra space before the '='.
 - Moved  /* forward definitions */ line before the declarations of functions.
---
 drivers/usb/host/Kconfig        |    8 +++
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ohci-hcd.c     |   18 ------
 drivers/usb/host/ohci-s3c2410.c |  128 +++++++++++++++++----------------------
 4 files changed, 66 insertions(+), 89 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 693560a..795d14d 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_S3CXXXX
+        tristate "Support for S3CXXXX on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX)
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          S3CXXXX chips.
+
 config USB_OHCI_HCD_AT91
         tristate "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index a70b044..9dffe81 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
+obj-$(CONFIG_USB_OHCI_HCD_S3CXXXX)	+= ohci-s3c2410.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index b48c892..b69a49e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1177,11 +1177,6 @@ MODULE_LICENSE ("GPL");
 #define SA1111_DRIVER		ohci_hcd_sa1111_driver
 #endif
 
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
-#include "ohci-s3c2410.c"
-#define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1293,12 +1288,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_tmio;
 #endif
 
-#ifdef S3C2410_PLATFORM_DRIVER
-	retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_s3c2410;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1332,10 +1321,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
- error_s3c2410:
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
  error_tmio:
@@ -1382,9 +1367,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index e125770..48b5948 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -19,19 +19,36 @@
  * This file is licenced under the GPL.
 */
 
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
+
 
 #define valid_port(idx) ((idx) == 1 || (idx) == 2)
 
 /* clock device associated with the hcd */
 
+
+#define DRIVER_DESC "OHCI S3CXXXX driver"
+
+static const char hcd_name[] = "ohci-s3cxxxx";
+
 static struct clk *clk;
 static struct clk *usb_clk;
 
 /* forward definitions */
 
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+			u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
+
 static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
 
 /* conversion functions */
@@ -93,7 +110,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd, char *buf)
 	int orig;
 	int portno;
 
-	orig  = ohci_hub_status_data(hcd, buf);
+	orig = orig_ohci_hub_status_data(hcd, buf);
 
 	if (info == NULL)
 		return orig;
@@ -164,7 +181,7 @@ static int ohci_s3c2410_hub_control(
 	 * process the request straight away and exit */
 
 	if (info == NULL) {
-		ret = ohci_hub_control(hcd, typeReq, wValue,
+		ret = orig_ohci_hub_control(hcd, typeReq, wValue,
 				       wIndex, buf, wLength);
 		goto out;
 	}
@@ -214,7 +231,7 @@ static int ohci_s3c2410_hub_control(
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
 	if (ret)
 		goto out;
 
@@ -373,8 +390,6 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 	s3c2410_start_hc(dev, hcd);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
-
 	retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
 	if (retval != 0)
 		goto err_ioremap;
@@ -391,71 +406,7 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_s3c2410_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-
-static const struct hc_driver ohci_s3c2410_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"S3C24XX OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.start =		ohci_s3c2410_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_s3c2410_hub_status_data,
-	.hub_control =		ohci_s3c2410_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/* device driver */
+static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;
 
 static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
 {
@@ -532,4 +483,39 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {
 	},
 };
 
+static int __init ohci_s3cxxxx_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
+
+	/*
+	 * The Samsung HW has some unusual quirks, which require
+	 * Sumsung-specific workarounds. We override certain hc_driver
+	 * functions here to achieve that. We explicitly do not enhance
+	 * ohci_driver_overrides to allow this more easily, since this
+	 * is an unusual case, and we don't want to encourage others to
+	 * override these functions by making it too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_s3c2410_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_s3c2410_hc_driver.hub_status_data;
+
+	ohci_s3c2410_hc_driver.hub_status_data	= ohci_s3c2410_hub_status_data;
+	ohci_s3c2410_hc_driver.hub_control	= ohci_s3c2410_hub_control;
+
+	return platform_driver_register(&ohci_hcd_s3c2410_driver);
+}
+module_init(ohci_s3cxxxx_init);
+
+static void __exit ohci_s3cxxxx_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_s3c2410_driver);
+}
+module_exit(ohci_s3cxxxx_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:s3c2410-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V4 0/6] USB: OHCI: more bus glues as separate modules
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (10 preceding siblings ...)
  2013-07-31  6:07 ` Manjunath Goudar
@ 2013-08-10  7:37 ` Manjunath Goudar
  2013-08-10  7:37   ` [PATCH V4 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
                     ` (5 more replies)
  2013-08-12  6:46 ` [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (2 subsequent siblings)
  14 siblings, 6 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-08-10  7:37 UTC (permalink / raw)
  To: linux-arm-kernel

These patches are for separating the SOC On-Chip ohci host controller
from ohci-hcd host code into its own driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.12.

V2:
  In patch 5/6 and 6/6:
  -Set non-standard fields in hc_driver manually, rather than
   relying on an expanded struct ohci_driver_overrides.
  -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
   relying on ohci_hub_control and hub_status_data being exported.

  In patch 1/6 to 4/6
  -ohci_setup() has been removed because it is called in .reset member
   of the ohci_hc_driver structure.

V3:
 In patch 5/6 and 6/6:
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

 In patch 5/6:
 -The ohci_restart() function is not required in  current scenario,
  only discarding connection state of integrated transceivers is sufficient,
  for this directly handling ohci->hc_control.

 In patch 2/6 :
 -rewritten if (config->otg || config->rwc) block statements into
  two separate 'if blocks' to handle below scenarios
  1. config->otg set scenario.
  2. if any of these (config->otg, config->rwc) are set, this
     scenario should be handled only after ohci_setup()
 
In patch 1/6 and 4/6:
  No change.

V4:
 In patch 1/6 and 4/6:
  No change.

 In patch 2/6 :
 -usb_remove_hcd() function is required a valid clock that is what
  omap_ohci_clock_power(0) is called after hcd shutdown.

 In patch 3/6 :
 -V3 modification revert back, only ohci->regs setting write()
  function has been removed because ohci->regs doesn't get set until
  usb_add_hcd.

 In patch 5/6 :
 - Removed extra space after "tristate".
 - Removed extra space between function name  and '(' characters.
 - MODULE_ALIAS line moved to last statement of ohci-at91 file.

 In patch 6/6 :
 - Removed extra space before the '='.
 - Moved  /* forward definitions */ line before the declarations of functions.


Manjunath Goudar (6):
  USB: OHCI: make ohci-exynos a separate driver
  USB: OHCI: make ohci-omap a separate driver
  USB: OHCI: make ohci-omap3 a separate driver
  USB: OHCI: make ohci-spear a separate driver
  USB: OHCI: make ohci-at91 a separate driver
  USB: OHCI: make ohci-s3c2410 a separate driver

 drivers/usb/host/Kconfig        |   30 ++++++-
 drivers/usb/host/Makefile       |    6 ++
 drivers/usb/host/ohci-at91.c    |  153 ++++++++++++++++-------------------
 drivers/usb/host/ohci-exynos.c  |  167 ++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c     |  108 -------------------------
 drivers/usb/host/ohci-omap.c    |  156 +++++++++++++-----------------------
 drivers/usb/host/ohci-omap3.c   |  118 +++++++++------------------
 drivers/usb/host/ohci-s3c2410.c |  128 +++++++++++++-----------------
 drivers/usb/host/ohci-spear.c   |  140 +++++++++++++-------------------
 9 files changed, 374 insertions(+), 632 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V4 1/6] USB: OHCI: make ohci-exynos a separate driver
  2013-08-10  7:37 ` [PATCH V4 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
@ 2013-08-10  7:37   ` Manjunath Goudar
  2013-08-10  7:37   ` [PATCH V4 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-08-10  7:37 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  Samsung OHCI EXYNOS host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Cc: Vivek Gautam <gautam.vivek@samsung.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -exynos_ohci_hcd structure assignment error fixed.
 -Removed multiple usb_create_hcd() from prob funtion.
 -platform_set_drvdata() called before exynos_ohci_phy_enable().
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure

V3:
 -No major changes only "exynos" written in capital letters
  in "OHCI exynos driver".

V4:
 -No changes.

---
 drivers/usb/host/Kconfig       |    2 +-
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ohci-exynos.c |  167 +++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c    |   18 -----
 4 files changed, 71 insertions(+), 117 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 7bc598b..7b8f6bd 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -463,7 +463,7 @@ config USB_OHCI_SH
 	  If you use the PCI OHCI controller, this option is not necessary.
 
 config USB_OHCI_EXYNOS
-	boolean "OHCI support for Samsung EXYNOS SoC Series"
+	tristate "OHCI support for Samsung EXYNOS SoC Series"
 	depends on ARCH_EXYNOS
 	help
 	 Enable support for the Samsung Exynos SOC's on-chip OHCI controller.
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 28adb3f..45e2ffb 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
+obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index b0b542c..ae6068d 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -12,24 +12,39 @@
  */
 
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-exynos.h>
 #include <linux/usb/phy.h>
 #include <linux/usb/samsung_usb_phy.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include "ohci.h"
+
+#define DRIVER_DESC "OHCI EXYNOS driver"
+
+static const char hcd_name[] = "ohci-exynos";
+static struct hc_driver __read_mostly exynos_ohci_hc_driver;
+
+#define to_exynos_ohci(hcd) (struct exynos_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
 
 struct exynos_ohci_hcd {
-	struct device *dev;
-	struct usb_hcd *hcd;
 	struct clk *clk;
 	struct usb_phy *phy;
 	struct usb_otg *otg;
 	struct exynos4_ohci_platdata *pdata;
 };
 
-static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_enable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_init(exynos_ohci->phy);
@@ -37,9 +52,10 @@ static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
 }
 
-static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_disable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_shutdown(exynos_ohci->phy);
@@ -47,63 +63,11 @@ static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
 }
 
-static int ohci_exynos_reset(struct usb_hcd *hcd)
-{
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-static int ohci_exynos_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci);
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-static const struct hc_driver exynos_ohci_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "EXYNOS OHCI Host Controller",
-	.hcd_priv_size		= sizeof(struct ohci_hcd),
-
-	.irq			= ohci_irq,
-	.flags			= HCD_MEMORY|HCD_USB11,
-
-	.reset			= ohci_exynos_reset,
-	.start			= ohci_exynos_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-
-	.get_frame_number	= ohci_get_frame,
-
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-	.start_port_reset	= ohci_start_port_reset,
-};
-
 static int exynos_ohci_probe(struct platform_device *pdev)
 {
 	struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_ohci_hcd *exynos_ohci;
 	struct usb_hcd *hcd;
-	struct ohci_hcd *ohci;
 	struct resource *res;
 	struct usb_phy *phy;
 	int irq;
@@ -119,10 +83,14 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	if (!pdev->dev.coherent_dma_mask)
 		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
-	exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd),
-					GFP_KERNEL);
-	if (!exynos_ohci)
+	hcd = usb_create_hcd(&exynos_ohci_hc_driver,
+				&pdev->dev, dev_name(&pdev->dev));
+	if (!hcd) {
+		dev_err(&pdev->dev, "Unable to create HCD\n");
 		return -ENOMEM;
+	}
+
+	exynos_ohci = to_exynos_ohci(hcd);
 
 	if (of_device_is_compatible(pdev->dev.of_node,
 					"samsung,exynos5440-ohci"))
@@ -143,17 +111,6 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	}
 
 skip_phy:
-
-	exynos_ohci->dev = &pdev->dev;
-
-	hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
-					dev_name(&pdev->dev));
-	if (!hcd) {
-		dev_err(&pdev->dev, "Unable to create HCD\n");
-		return -ENOMEM;
-	}
-
-	exynos_ohci->hcd = hcd;
 	exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");
 
 	if (IS_ERR(exynos_ohci->clk)) {
@@ -190,26 +147,21 @@ skip_phy:
 	}
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	platform_set_drvdata(pdev, hcd);
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to add USB HCD\n");
 		goto fail_add_hcd;
 	}
-
-	platform_set_drvdata(pdev, exynos_ohci);
-
 	return 0;
 
 fail_add_hcd:
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 fail_io:
 	clk_disable_unprepare(exynos_ohci->clk);
 fail_clk:
@@ -219,16 +171,15 @@ fail_clk:
 
 static int exynos_ohci_remove(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	usb_remove_hcd(hcd);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -239,8 +190,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
 
 static void exynos_ohci_shutdown(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
 	if (hcd->driver->shutdown)
 		hcd->driver->shutdown(hcd);
@@ -249,9 +199,10 @@ static void exynos_ohci_shutdown(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int exynos_ohci_suspend(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	struct platform_device *pdev = to_platform_device(dev);
 	unsigned long flags;
 	int rc = 0;
 
@@ -271,10 +222,9 @@ static int exynos_ohci_suspend(struct device *dev)
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -286,16 +236,16 @@ fail:
 
 static int exynos_ohci_resume(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd			= dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci	= to_exynos_ohci(hcd);
+	struct platform_device *pdev		= to_platform_device(dev);
 
 	clk_prepare_enable(exynos_ohci->clk);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	ohci_resume(hcd, false);
 
@@ -306,6 +256,10 @@ static int exynos_ohci_resume(struct device *dev)
 #define exynos_ohci_resume	NULL
 #endif
 
+static const struct ohci_driver_overrides exynos_overrides __initconst = {
+	.extra_priv_size =	sizeof(struct exynos_ohci_hcd),
+};
+
 static const struct dev_pm_ops exynos_ohci_pm_ops = {
 	.suspend	= exynos_ohci_suspend,
 	.resume		= exynos_ohci_resume,
@@ -331,6 +285,23 @@ static struct platform_driver exynos_ohci_driver = {
 		.of_match_table	= of_match_ptr(exynos_ohci_match),
 	}
 };
+static int __init ohci_exynos_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&exynos_ohci_hc_driver, &exynos_overrides);
+	return platform_driver_register(&exynos_ohci_driver);
+}
+module_init(ohci_exynos_init);
+
+static void __exit ohci_exynos_cleanup(void)
+{
+	platform_driver_unregister(&exynos_ohci_driver);
+}
+module_exit(ohci_exynos_cleanup);
 
 MODULE_ALIAS("platform:exynos-ohci");
 MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index a9d3437..2980bb6 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_EXYNOS
-#include "ohci-exynos.c"
-#define EXYNOS_PLATFORM_DRIVER	exynos_ohci_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP1
 #include "ohci-omap.c"
 #define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
@@ -1336,12 +1331,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_s3c2410;
 #endif
 
-#ifdef EXYNOS_PLATFORM_DRIVER
-	retval = platform_driver_register(&EXYNOS_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_exynos;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1395,10 +1384,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
- error_exynos:
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
  error_s3c2410:
@@ -1463,9 +1448,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V4 2/6] USB: OHCI: make ohci-omap a separate driver
  2013-08-10  7:37 ` [PATCH V4 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
  2013-08-10  7:37   ` [PATCH V4 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
@ 2013-08-10  7:37   ` Manjunath Goudar
  2013-08-10  7:37   ` [PATCH V4 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-08-10  7:37 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP1/2 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -omap_ohci_clock_power(0) called in usb_hcd_omap_remove().
 -Removed ohci_setup() call from usb_hcd_omap_probe().
 -host_enabled and host_initialized variables aren't used for anything
  thats what removed.

V3:
 -rewritten if (config->otg || config->rwc) block statements into
  two separate 'if blocks' to handle below scenarios
  1. config->otg set scenario.
  2. if any of these (config->otg, config->rwc) are set, this
     scenario should be handled only after ohci_setup()

V4:
 -usb_remove_hcd() function is required a valid clock that is what
  omap_ohci_clock_power(0) is called after hcd shutdown.
---
 drivers/usb/host/Kconfig     |    2 +-
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-hcd.c  |   18 -----
 drivers/usb/host/ohci-omap.c |  156 ++++++++++++++----------------------------
 4 files changed, 55 insertions(+), 122 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 7b8f6bd..99b7e7e 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -376,7 +376,7 @@ config USB_OHCI_HCD
 if USB_OHCI_HCD
 
 config USB_OHCI_HCD_OMAP1
-	bool "OHCI support for OMAP1/2 chips"
+	tristate "OHCI support for OMAP1/2 chips"
 	depends on ARCH_OMAP1
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 45e2ffb..a0220c1 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 2980bb6..1abc1e7 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP1
-#include "ohci-omap.c"
-#define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP3
 #include "ohci-omap3.c"
 #define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
@@ -1289,12 +1284,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP1_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP1_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap1_platform;
-#endif
-
 #ifdef OMAP3_PLATFORM_DRIVER
 	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1408,10 +1397,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
  error_omap3_platform:
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
- error_omap1_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1466,9 +1451,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OMAP3_PLATFORM_DRIVER
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 8747fa6..8149ef0 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -14,12 +14,21 @@
  * This file is licenced under the GPL.
  */
 
-#include <linux/signal.h>
-#include <linux/jiffies.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
 #include <asm/io.h>
 #include <asm/mach-types.h>
@@ -42,10 +51,7 @@
 #define OMAP1510_LB_MMU_RAM_H	0xfffec234
 #define OMAP1510_LB_MMU_RAM_L	0xfffec238
 
-
-#ifndef CONFIG_ARCH_OMAP
-#error "This file is OMAP bus glue.  CONFIG_OMAP must be defined."
-#endif
+#define DRIVER_DESC "OHCI OMAP driver"
 
 #ifdef CONFIG_TPS65010
 #include <linux/i2c/tps65010.h>
@@ -68,8 +74,9 @@ extern int ocpi_enable(void);
 
 static struct clk *usb_host_ck;
 static struct clk *usb_dc_ck;
-static int host_enabled;
-static int host_initialized;
+
+static const char hcd_name[] = "ohci-omap";
+static struct hc_driver __read_mostly ohci_omap_hc_driver;
 
 static void omap_ohci_clock_power(int on)
 {
@@ -188,7 +195,7 @@ static void start_hnp(struct ohci_hcd *ohci)
 
 /*-------------------------------------------------------------------------*/
 
-static int ohci_omap_init(struct usb_hcd *hcd)
+static int ohci_omap_reset(struct usb_hcd *hcd)
 {
 	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
 	struct omap_usb_config	*config = hcd->self.controller->platform_data;
@@ -198,9 +205,9 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	dev_dbg(hcd->self.controller, "starting USB Controller\n");
 
 	if (config->otg) {
-		ohci_to_hcd(ohci)->self.otg_port = config->otg;
+		hcd->self.otg_port = config->otg;
 		/* default/minimum OTG power budget:  8 mA */
-		ohci_to_hcd(ohci)->power_budget = 8;
+		hcd->power_budget = 8;
 	}
 
 	/* boards can use OTG transceivers in non-OTG modes */
@@ -238,9 +245,15 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 		omap_1510_local_bus_init();
 	}
 
-	if ((ret = ohci_init(ohci)) < 0)
+	ret = ohci_setup(hcd);
+	if (ret < 0)
 		return ret;
 
+	if (config->otg || config->rwc) {
+		ohci->hc_control = OHCI_CTRL_RWC;
+		writel(OHCI_CTRL_RWC, &ohci->regs->control);
+	}
+
 	/* board-specific power switching and overcurrent support */
 	if (machine_is_omap_osk() || machine_is_omap_innovator()) {
 		u32	rh = roothub_a (ohci);
@@ -281,14 +294,6 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	return 0;
 }
 
-static void ohci_omap_stop(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
-	ohci_stop(hcd);
-	omap_ohci_clock_power(0);
-}
-
-
 /*-------------------------------------------------------------------------*/
 
 /**
@@ -304,7 +309,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 {
 	int retval, irq;
 	struct usb_hcd *hcd = 0;
-	struct ohci_hcd *ohci;
 
 	if (pdev->num_resources != 2) {
 		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
@@ -354,12 +358,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 		goto err2;
 	}
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
-
-	host_initialized = 0;
-	host_enabled = 1;
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		retval = -ENXIO;
@@ -369,11 +367,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 	if (retval)
 		goto err3;
 
-	host_initialized = 1;
-
-	if (!host_enabled)
-		omap_ohci_clock_power(0);
-
 	return 0;
 err3:
 	iounmap(hcd->regs);
@@ -402,7 +395,9 @@ err0:
 static inline void
 usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
+	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
 	usb_remove_hcd(hcd);
+	omap_ohci_clock_power(0);
 	if (!IS_ERR_OR_NULL(hcd->phy)) {
 		(void) otg_set_host(hcd->phy->otg, 0);
 		usb_put_phy(hcd->phy);
@@ -418,76 +413,6 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_omap_start (struct usb_hcd *hcd)
-{
-	struct omap_usb_config *config;
-	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ret;
-
-	if (!host_enabled)
-		return 0;
-	config = hcd->self.controller->platform_data;
-	if (config->otg || config->rwc) {
-		ohci->hc_control = OHCI_CTRL_RWC;
-		writel(OHCI_CTRL_RWC, &ohci->regs->control);
-	}
-
-	if ((ret = ohci_run (ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop (hcd);
-		return ret;
-	}
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_omap_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap_init,
-	.start =		ohci_omap_start,
-	.stop =			ohci_omap_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static int ohci_hcd_omap_drv_probe(struct platform_device *dev)
 {
 	return usb_hcd_omap_probe(&ohci_omap_hc_driver, dev);
@@ -553,4 +478,29 @@ static struct platform_driver ohci_hcd_omap_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides omap_overrides __initconst = {
+	.product_desc	= "OMAP OHCI",
+	.reset		= ohci_omap_reset
+};
+
+static int __init ohci_omap_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap_hc_driver, &omap_overrides);
+	return platform_driver_register(&ohci_hcd_omap_driver);
+}
+module_init(ohci_omap_init);
+
+static void __exit ohci_omap_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap_driver);
+}
+module_exit(ohci_omap_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V4 3/6] USB: OHCI: make ohci-omap3 a separate driver
  2013-08-10  7:37 ` [PATCH V4 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
  2013-08-10  7:37   ` [PATCH V4 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
  2013-08-10  7:37   ` [PATCH V4 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
@ 2013-08-10  7:37   ` Manjunath Goudar
  2013-08-10  7:37   ` [PATCH V4 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-08-10  7:37 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP3 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Anand Gadiyar <gadiyar@ti.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -The improper multi-line commenting style written in proper way.
  ('*' characters aligned in vertically).

V3:
 -RemoteWakeupConnected setting has been removed.

V4:
 -V3 modification revert back, only ohci->regs setting write()
  function has been removed because ohci->regs doesn't get set until
  usb_add_hcd.
---
 drivers/usb/host/Kconfig      |    2 +-
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 -------
 drivers/usb/host/ohci-omap3.c |  118 +++++++++++++----------------------------
 4 files changed, 40 insertions(+), 99 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 99b7e7e..3eab432 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -383,7 +383,7 @@ config USB_OHCI_HCD_OMAP1
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
 config USB_OHCI_HCD_OMAP3
-	bool "OHCI support for OMAP3 and later chips"
+	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index a0220c1..a0064a6 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 1abc1e7..cad51d2 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP3
-#include "ohci-omap3.c"
-#define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1284,12 +1279,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP3_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap3_platform;
-#endif
-
 #ifdef OF_PLATFORM_DRIVER
 	retval = platform_driver_register(&OF_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1393,10 +1382,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
  error_of_platform:
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
- error_omap3_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1448,9 +1433,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OF_PLATFORM_DRIVER
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index 8f71357..e14f4d9 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -29,90 +29,22 @@
  *	- add kernel-doc
  */
 
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/of.h>
-#include <linux/dma-mapping.h>
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_init(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "starting OHCI controller\n");
-
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	/*
-	 * RemoteWakeupConnected has to be set explicitly before
-	 * calling ohci_run. The reset value of RWC is 0.
-	 */
-	ohci->hc_control = OHCI_CTRL_RWC;
-	writel(OHCI_CTRL_RWC, &ohci->regs->control);
-
-	ret = ohci_run(ohci);
-
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-	}
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
-	return ret;
-}
+#include "ohci.h"
 
-/*-------------------------------------------------------------------------*/
+#define DRIVER_DESC "OHCI OMAP3 driver"
 
-static const struct hc_driver ohci_omap3_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP3 OHCI Host Controller",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap3_init,
-	.start =		ohci_omap3_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
+static const char hcd_name[] = "ohci-omap3";
+static struct hc_driver __read_mostly ohci_omap3_hc_driver;
 
 /*
  * configure so an HC device and id are always provided
@@ -129,6 +61,7 @@ static const struct hc_driver ohci_omap3_hc_driver = {
 static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 {
 	struct device		*dev = &pdev->dev;
+	struct ohci_hcd		*ohci;
 	struct usb_hcd		*hcd = NULL;
 	void __iomem		*regs = NULL;
 	struct resource		*res;
@@ -185,7 +118,12 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	ohci = hcd_to_ohci(hcd);
+	/*
+	 * RemoteWakeupConnected has to be set explicitly before
+	 * calling ohci_run. The reset value of RWC is 0.
+	 */
+	ohci->hc_control = OHCI_CTRL_RWC;
 
 	ret = usb_add_hcd(hcd, irq, 0);
 	if (ret) {
@@ -256,5 +194,25 @@ static struct platform_driver ohci_hcd_omap3_driver = {
 	},
 };
 
+static int __init ohci_omap3_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap3_hc_driver, NULL);
+	return platform_driver_register(&ohci_hcd_omap3_driver);
+}
+module_init(ohci_omap3_init);
+
+static void __exit ohci_omap3_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap3_driver);
+}
+module_exit(ohci_omap3_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci-omap3");
 MODULE_AUTHOR("Anand Gadiyar <gadiyar@ti.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V4 4/6] USB: OHCI: make ohci-spear a separate driver
  2013-08-10  7:37 ` [PATCH V4 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (2 preceding siblings ...)
  2013-08-10  7:37   ` [PATCH V4 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
@ 2013-08-10  7:37   ` Manjunath Goudar
  2013-08-10  7:37   ` [PATCH V4 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
  2013-08-10  7:37   ` [PATCH V4 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
  5 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-08-10  7:37 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the ST OHCI SPEAr host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -debugging stuff isn't needed any more that's what removed.

V3:
 No change.
---
 drivers/usb/host/Kconfig      |    8 +++
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 ------
 drivers/usb/host/ohci-spear.c |  140 +++++++++++++++++------------------------
 4 files changed, 65 insertions(+), 102 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 3eab432..a5a34a3 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -382,6 +382,14 @@ config USB_OHCI_HCD_OMAP1
 	---help---
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
+config USB_OHCI_HCD_SPEAR
+        tristate "Support for ST SPEAr on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && PLAT_SPEAR
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          ST SPEAr chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index a0064a6..8cc3f63 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
+obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index cad51d2..34ec156 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1212,11 +1212,6 @@ MODULE_LICENSE ("GPL");
 #define OF_PLATFORM_DRIVER	ohci_hcd_ppc_of_driver
 #endif
 
-#ifdef CONFIG_PLAT_SPEAR
-#include "ohci-spear.c"
-#define SPEAR_PLATFORM_DRIVER	spear_ohci_hcd_driver
-#endif
-
 #ifdef CONFIG_PPC_PS3
 #include "ohci-ps3.c"
 #define PS3_SYSTEM_BUS_DRIVER	ps3_ohci_driver
@@ -1333,19 +1328,9 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_davinci;
 #endif
 
-#ifdef SPEAR_PLATFORM_DRIVER
-	retval = platform_driver_register(&SPEAR_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_spear;
-#endif
-
 	return retval;
 
 	/* Error path */
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
- error_spear:
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
  error_davinci:
@@ -1403,9 +1388,6 @@ module_init(ohci_hcd_mod_init);
 
 static void __exit ohci_hcd_mod_exit(void)
 {
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index cc9dd9e..31ff3fc 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -11,92 +11,37 @@
 * warranty of any kind, whether express or implied.
 */
 
-#include <linux/signal.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
+#define DRIVER_DESC "OHCI SPEAr driver"
+
+static const char hcd_name[] = "SPEAr-ohci";
 struct spear_ohci {
-	struct ohci_hcd ohci;
 	struct clk *clk;
 };
 
-#define to_spear_ohci(hcd)	(struct spear_ohci *)hcd_to_ohci(hcd)
-
-static void spear_start_ohci(struct spear_ohci *ohci)
-{
-	clk_prepare_enable(ohci->clk);
-}
-
-static void spear_stop_ohci(struct spear_ohci *ohci)
-{
-	clk_disable_unprepare(ohci->clk);
-}
-
-static int ohci_spear_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-	ohci->regs = hcd->regs;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	create_debug_files(ohci);
-
-#ifdef DEBUG
-	ohci_dump(ohci, 1);
-#endif
-	return 0;
-}
-
-static const struct hc_driver ohci_spear_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "SPEAr OHCI",
-	.hcd_priv_size		= sizeof(struct spear_ohci),
-
-	/* generic hardware linkage */
-	.irq			= ohci_irq,
-	.flags			= HCD_USB11 | HCD_MEMORY,
-
-	/* basic lifecycle operations */
-	.start			= ohci_spear_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-
-	/* managing i/o requests and associated device resources */
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	/* scheduling support */
-	.get_frame_number	= ohci_get_frame,
+#define to_spear_ohci(hcd)     (struct spear_ohci *)(hcd_to_ohci(hcd)->priv)
 
-	/* root hub support */
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-
-	.start_port_reset	= ohci_start_port_reset,
-};
+static struct hc_driver __read_mostly ohci_spear_hc_driver;
 
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
 	const struct hc_driver *driver = &ohci_spear_hc_driver;
+	struct ohci_hcd *ohci;
 	struct usb_hcd *hcd = NULL;
 	struct clk *usbh_clk;
-	struct spear_ohci *ohci_p;
+	struct spear_ohci *sohci_p;
 	struct resource *res;
 	int retval, irq;
 
@@ -151,16 +96,18 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 		goto err_put_hcd;
 	}
 
-	ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
-	ohci_p->clk = usbh_clk;
-	spear_start_ohci(ohci_p);
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	sohci_p = to_spear_ohci(hcd);
+	sohci_p->clk = usbh_clk;
+
+	clk_prepare_enable(sohci_p->clk);
+
+	ohci = hcd_to_ohci(hcd);
 
 	retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0);
 	if (retval == 0)
 		return retval;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
 err_put_hcd:
 	usb_put_hcd(hcd);
 fail:
@@ -172,11 +119,11 @@ fail:
 static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	usb_remove_hcd(hcd);
-	if (ohci_p->clk)
-		spear_stop_ohci(ohci_p);
+	if (sohci_p->clk)
+		clk_disable_unprepare(sohci_p->clk);
 
 	usb_put_hcd(hcd);
 	return 0;
@@ -188,13 +135,14 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
+
 	return 0;
 }
 
@@ -202,13 +150,13 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_start_ohci(ohci_p);
+	clk_prepare_enable(sohci_p->clk);
 	ohci_resume(hcd, false);
 	return 0;
 }
@@ -234,4 +182,28 @@ static struct platform_driver spear_ohci_hcd_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides spear_overrides __initconst = {
+	.extra_priv_size = sizeof(struct spear_ohci),
+};
+static int __init ohci_spear_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_spear_hc_driver, &spear_overrides);
+	return platform_driver_register(&spear_ohci_hcd_driver);
+}
+module_init(ohci_spear_init);
+
+static void __exit ohci_spear_cleanup(void)
+{
+	platform_driver_unregister(&spear_ohci_hcd_driver);
+}
+module_exit(ohci_spear_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Deepak Sikri");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:spear-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V4 5/6] USB: OHCI: make ohci-at91 a separate driver
  2013-08-10  7:37 ` [PATCH V4 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (3 preceding siblings ...)
  2013-08-10  7:37   ` [PATCH V4 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
@ 2013-08-10  7:37   ` Manjunath Goudar
  2013-08-10  7:37   ` [PATCH V4 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
  5 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-08-10  7:37 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI Atmel host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.12.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -Set non-standard fields in ohci_at91_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

V3:
 -The ohci_restart() function is not required in  current scenario,
  only discarding connection state of integrated transceivers is sufficient,
  for this directly handling ohci->hc_control.

V4:
 - Removed extra space after "tristate".
 - Removed extra space between function name  and '(' characters.
 - MODULE_ALIAS line moved to last statement of ohci-at91 file.
---
 drivers/usb/host/Kconfig     |    8 +++
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-at91.c |  153 +++++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c  |   18 -----
 4 files changed, 77 insertions(+), 103 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index a5a34a3..693560a 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_AT91
+        tristate "Support for Atmel on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && ARCH_AT91
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          Atmel chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 8cc3f63..a0ac663 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
+obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 9677f68..08e28eb 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -13,27 +13,41 @@
  */
 
 #include <linux/clk.h>
-#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/atmel.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
 #include <mach/hardware.h>
 #include <asm/gpio.h>
 
 #include <mach/cpu.h>
 
-#ifndef CONFIG_ARCH_AT91
-#error "CONFIG_ARCH_AT91 must be defined."
-#endif
+
+#include "ohci.h"
 
 #define valid_port(index)	((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
 #define at91_for_each_port(index)	\
 		for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++)
 
 /* interface and function clocks; sometimes also an AHB clock */
+
+#define DRIVER_DESC "OHCI Atmel driver"
+
+static const char hcd_name[] = "ohci-atmel";
+
+static struct hc_driver __read_mostly ohci_at91_hc_driver;
 static struct clk *iclk, *fclk, *hclk;
 static int clocked;
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+			u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
 
 extern int usb_disabled(void);
 
@@ -111,6 +125,8 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
 static int usb_hcd_at91_probe(const struct hc_driver *driver,
 			struct platform_device *pdev)
 {
+	struct at91_usbh_data *board;
+	struct ohci_hcd *ohci;
 	int retval;
 	struct usb_hcd *hcd = NULL;
 
@@ -163,8 +179,10 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
 		goto err5;
 	}
 
+	board = hcd->self.controller->platform_data;
+	ohci = hcd_to_ohci(hcd);
+	ohci->num_ports = board->ports;
 	at91_start_hc(pdev);
-	ohci_hcd_init(hcd_to_ohci(hcd));
 
 	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
 	if (retval == 0)
@@ -221,36 +239,6 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd,
 }
 
 /*-------------------------------------------------------------------------*/
-
-static int
-ohci_at91_reset (struct usb_hcd *hcd)
-{
-	struct at91_usbh_data	*board = hcd->self.controller->platform_data;
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
-	ohci->num_ports = board->ports;
-	return 0;
-}
-
-static int
-ohci_at91_start (struct usb_hcd *hcd)
-{
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_run(ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-	return 0;
-}
-
 static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
 {
 	if (!valid_port(port))
@@ -281,7 +269,7 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
 static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
 	struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
-	int length = ohci_hub_status_data(hcd, buf);
+	int length = orig_ohci_hub_status_data(hcd, buf);
 	int port;
 
 	at91_for_each_port(port) {
@@ -359,7 +347,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex + 1,
+				buf, wLength);
 	if (ret)
 		goto out;
 
@@ -413,51 +402,6 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 /*-------------------------------------------------------------------------*/
 
-static const struct hc_driver ohci_at91_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"AT91 OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_at91_reset,
-	.start =		ohci_at91_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_at91_hub_status_data,
-	.hub_control =		ohci_at91_hub_control,
-#ifdef CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
 {
 	struct platform_device *pdev = data;
@@ -686,7 +630,11 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
 	 * REVISIT: some boards will be able to turn VBUS off...
 	 */
 	if (at91_suspend_entering_slow_clock()) {
-		ohci_usb_reset (ohci);
+		ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
+		ohci->hc_control &= OHCI_CTRL_RWC;
+		ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
+		ohci->rh_state = OHCI_RH_HALTED;
+
 		/* flush the writes */
 		(void) ohci_readl (ohci, &ohci->regs->control);
 		at91_stop_clock();
@@ -713,8 +661,6 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
 #define ohci_hcd_at91_drv_resume  NULL
 #endif
 
-MODULE_ALIAS("platform:at91_ohci");
-
 static struct platform_driver ohci_hcd_at91_driver = {
 	.probe		= ohci_hcd_at91_drv_probe,
 	.remove		= ohci_hcd_at91_drv_remove,
@@ -727,3 +673,40 @@ static struct platform_driver ohci_hcd_at91_driver = {
 		.of_match_table	= of_match_ptr(at91_ohci_dt_ids),
 	},
 };
+
+static int __init ohci_at91_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_at91_hc_driver, NULL);
+
+	/*
+	 * The Atmel HW has some unusual quirks, which require Atmel-specific
+	 * workarounds. We override certain hc_driver functions here to
+	 * achieve that. We explicitly do not enhance ohci_driver_overrides to
+	 * allow this more easily, since this is an unusual case, and we don't
+	 * want to encourage others to override these functions by making it
+	 * too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_at91_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_at91_hc_driver.hub_status_data;
+
+	ohci_at91_hc_driver.hub_status_data	= ohci_at91_hub_status_data;
+	ohci_at91_hc_driver.hub_control		= ohci_at91_hub_control;
+
+	return platform_driver_register(&ohci_hcd_at91_driver);
+}
+module_init(ohci_at91_init);
+
+static void __exit ohci_at91_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_at91_driver);
+}
+module_exit(ohci_at91_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:at91_ohci");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 34ec156..b48c892 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1192,11 +1192,6 @@ MODULE_LICENSE ("GPL");
 #define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver
 #endif
 
-#ifdef CONFIG_ARCH_AT91
-#include "ohci-at91.c"
-#define AT91_PLATFORM_DRIVER	ohci_hcd_at91_driver
-#endif
-
 #ifdef CONFIG_ARCH_LPC32XX
 #include "ohci-nxp.c"
 #define NXP_PLATFORM_DRIVER	usb_hcd_nxp_driver
@@ -1310,12 +1305,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_ep93xx;
 #endif
 
-#ifdef AT91_PLATFORM_DRIVER
-	retval = platform_driver_register(&AT91_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_at91;
-#endif
-
 #ifdef NXP_PLATFORM_DRIVER
 	retval = platform_driver_register(&NXP_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1339,10 +1328,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
  error_nxp:
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
- error_at91:
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
@@ -1394,9 +1379,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef NXP_PLATFORM_DRIVER
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V4 6/6] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-08-10  7:37 ` [PATCH V4 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (4 preceding siblings ...)
  2013-08-10  7:37   ` [PATCH V4 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
@ 2013-08-10  7:37   ` Manjunath Goudar
  2013-08-10 10:53     ` Tomasz Figa
  5 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-08-10  7:37 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the Samsung OHCI S3CXXXX host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.12.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -Set non-standard fields in ohci_s3c2410_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.

V3:
 -Kconfig wrong parentheses discription fixed.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

V4:
 - Removed extra space before the '='.
 - Moved  /* forward definitions */ line before the declarations of functions.
---
 drivers/usb/host/Kconfig        |    8 +++
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ohci-hcd.c     |   18 ------
 drivers/usb/host/ohci-s3c2410.c |  128 +++++++++++++++++----------------------
 4 files changed, 66 insertions(+), 89 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 693560a..795d14d 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_S3CXXXX
+        tristate "Support for S3CXXXX on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX)
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          S3CXXXX chips.
+
 config USB_OHCI_HCD_AT91
         tristate "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index a0ac663..d3e9e66 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
+obj-$(CONFIG_USB_OHCI_HCD_S3CXXXX)	+= ohci-s3c2410.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index b48c892..b69a49e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1177,11 +1177,6 @@ MODULE_LICENSE ("GPL");
 #define SA1111_DRIVER		ohci_hcd_sa1111_driver
 #endif
 
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
-#include "ohci-s3c2410.c"
-#define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1293,12 +1288,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_tmio;
 #endif
 
-#ifdef S3C2410_PLATFORM_DRIVER
-	retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_s3c2410;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1332,10 +1321,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
- error_s3c2410:
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
  error_tmio:
@@ -1382,9 +1367,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index e125770..48b5948 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -19,19 +19,36 @@
  * This file is licenced under the GPL.
 */
 
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
+
 
 #define valid_port(idx) ((idx) == 1 || (idx) == 2)
 
 /* clock device associated with the hcd */
 
+
+#define DRIVER_DESC "OHCI S3CXXXX driver"
+
+static const char hcd_name[] = "ohci-s3cxxxx";
+
 static struct clk *clk;
 static struct clk *usb_clk;
 
 /* forward definitions */
 
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+			u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
+
 static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
 
 /* conversion functions */
@@ -93,7 +110,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd, char *buf)
 	int orig;
 	int portno;
 
-	orig  = ohci_hub_status_data(hcd, buf);
+	orig = orig_ohci_hub_status_data(hcd, buf);
 
 	if (info == NULL)
 		return orig;
@@ -164,7 +181,7 @@ static int ohci_s3c2410_hub_control(
 	 * process the request straight away and exit */
 
 	if (info == NULL) {
-		ret = ohci_hub_control(hcd, typeReq, wValue,
+		ret = orig_ohci_hub_control(hcd, typeReq, wValue,
 				       wIndex, buf, wLength);
 		goto out;
 	}
@@ -214,7 +231,7 @@ static int ohci_s3c2410_hub_control(
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
 	if (ret)
 		goto out;
 
@@ -373,8 +390,6 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 	s3c2410_start_hc(dev, hcd);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
-
 	retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
 	if (retval != 0)
 		goto err_ioremap;
@@ -391,71 +406,7 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_s3c2410_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-
-static const struct hc_driver ohci_s3c2410_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"S3C24XX OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.start =		ohci_s3c2410_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_s3c2410_hub_status_data,
-	.hub_control =		ohci_s3c2410_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/* device driver */
+static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;
 
 static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
 {
@@ -532,4 +483,39 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {
 	},
 };
 
+static int __init ohci_s3cxxxx_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
+
+	/*
+	 * The Samsung HW has some unusual quirks, which require
+	 * Sumsung-specific workarounds. We override certain hc_driver
+	 * functions here to achieve that. We explicitly do not enhance
+	 * ohci_driver_overrides to allow this more easily, since this
+	 * is an unusual case, and we don't want to encourage others to
+	 * override these functions by making it too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_s3c2410_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_s3c2410_hc_driver.hub_status_data;
+
+	ohci_s3c2410_hc_driver.hub_status_data	= ohci_s3c2410_hub_status_data;
+	ohci_s3c2410_hc_driver.hub_control	= ohci_s3c2410_hub_control;
+
+	return platform_driver_register(&ohci_hcd_s3c2410_driver);
+}
+module_init(ohci_s3cxxxx_init);
+
+static void __exit ohci_s3cxxxx_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_s3c2410_driver);
+}
+module_exit(ohci_s3cxxxx_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:s3c2410-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V4 6/6] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-08-10  7:37   ` [PATCH V4 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
@ 2013-08-10 10:53     ` Tomasz Figa
  0 siblings, 0 replies; 110+ messages in thread
From: Tomasz Figa @ 2013-08-10 10:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Manjunath,

On Saturday 10 of August 2013 13:07:36 Manjunath Goudar wrote:
> Separate the Samsung OHCI S3CXXXX host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.12.
> 
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
> Acked-by: Alan Stern <stern@rowland.harvard.edu>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Greg KH <greg@kroah.com>
> Cc: linux-usb at vger.kernel.org
> 
> V2:
>  -Set non-standard fields in ohci_s3c2410_hc_driver manually, rather
> than relying on an expanded struct ohci_driver_overrides.
>  -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
>   relying on ohci_hub_control and hub_status_data being exported.
> 
> V3:
>  -Kconfig wrong parentheses discription fixed.
>  -ohci_setup() has been removed because it is called in .reset member
>   of the ohci_hc_driver structure.
> 
> V4:
>  - Removed extra space before the '='.
>  - Moved  /* forward definitions */ line before the declarations of
> functions. ---
>  drivers/usb/host/Kconfig        |    8 +++
>  drivers/usb/host/Makefile       |    1 +
>  drivers/usb/host/ohci-hcd.c     |   18 ------
>  drivers/usb/host/ohci-s3c2410.c |  128
> +++++++++++++++++---------------------- 4 files changed, 66
> insertions(+), 89 deletions(-)
> 
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 693560a..795d14d 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
>            Enables support for the on-chip OHCI controller on
>            ST SPEAr chips.
> 
> +config USB_OHCI_HCD_S3CXXXX
> +        tristate "Support for S3CXXXX on-chip OHCI USB controller"

As far as I remember, you were supposed to keep the original name of this 
driver, as I suggested in previous iteration of this patch and you agreed. 
S3CXXXX is totally confusing when it's about Samsung SoC naming.

So here the config entry would be USB_OHCI_HCD_S3C2410 and I would call it 
"OHCI support for Samsung S3C24xx/S3C64xx SoC series".

> +        depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX)
> +        default y
> +        ---help---
> +          Enables support for the on-chip OHCI controller on
> +          S3CXXXX chips.

S3C24xx/S3C64xx chips

> +
>  config USB_OHCI_HCD_AT91
>          tristate "Support for Atmel on-chip OHCI USB controller"
>          depends on USB_OHCI_HCD && ARCH_AT91
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index a0ac663..d3e9e66 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -49,6 +49,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
>  obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
>  obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
>  obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
> +obj-$(CONFIG_USB_OHCI_HCD_S3CXXXX)	+= ohci-s3c2410.o

CONFIG_USB_OHCI_HCD_S3C2410

> 
>  obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
>  obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
> diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
> index b48c892..b69a49e 100644
> --- a/drivers/usb/host/ohci-hcd.c
> +++ b/drivers/usb/host/ohci-hcd.c
> @@ -1177,11 +1177,6 @@ MODULE_LICENSE ("GPL");
>  #define SA1111_DRIVER		ohci_hcd_sa1111_driver
>  #endif
> 
> -#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
> -#include "ohci-s3c2410.c"
> -#define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
> -#endif
> -
>  #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
>  #include "ohci-pxa27x.c"
>  #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
> @@ -1293,12 +1288,6 @@ static int __init ohci_hcd_mod_init(void)
>  		goto error_tmio;
>  #endif
> 
> -#ifdef S3C2410_PLATFORM_DRIVER
> -	retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER);
> -	if (retval < 0)
> -		goto error_s3c2410;
> -#endif
> -
>  #ifdef EP93XX_PLATFORM_DRIVER
>  	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
>  	if (retval < 0)
> @@ -1332,10 +1321,6 @@ static int __init ohci_hcd_mod_init(void)
>  	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
>   error_ep93xx:
>  #endif
> -#ifdef S3C2410_PLATFORM_DRIVER
> -	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
> - error_s3c2410:
> -#endif
>  #ifdef TMIO_OHCI_DRIVER
>  	platform_driver_unregister(&TMIO_OHCI_DRIVER);
>   error_tmio:
> @@ -1382,9 +1367,6 @@ static void __exit ohci_hcd_mod_exit(void)
>  #ifdef EP93XX_PLATFORM_DRIVER
>  	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
>  #endif
> -#ifdef S3C2410_PLATFORM_DRIVER
> -	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
> -#endif
>  #ifdef TMIO_OHCI_DRIVER
>  	platform_driver_unregister(&TMIO_OHCI_DRIVER);
>  #endif
> diff --git a/drivers/usb/host/ohci-s3c2410.c
> b/drivers/usb/host/ohci-s3c2410.c index e125770..48b5948 100644
> --- a/drivers/usb/host/ohci-s3c2410.c
> +++ b/drivers/usb/host/ohci-s3c2410.c
> @@ -19,19 +19,36 @@
>   * This file is licenced under the GPL.
>  */
> 
> -#include <linux/platform_device.h>
>  #include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
>  #include <linux/platform_data/usb-ohci-s3c2410.h>
> +#include <linux/usb.h>
> +#include <linux/usb/hcd.h>
> +
> +#include "ohci.h"
> +
> 
>  #define valid_port(idx) ((idx) == 1 || (idx) == 2)
> 
>  /* clock device associated with the hcd */
> 
> +
> +#define DRIVER_DESC "OHCI S3CXXXX driver"

OHCI S3C2410 driver

> +
> +static const char hcd_name[] = "ohci-s3cxxxx";

ohci-s3c2410

> +
>  static struct clk *clk;
>  static struct clk *usb_clk;
> 
>  /* forward definitions */
> 
> +static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
> +			u16 wValue, u16 wIndex, char *buf, u16 wLength);
> +static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char
> *buf); +
>  static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
> 
>  /* conversion functions */
> @@ -93,7 +110,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd,
> char *buf) int orig;
>  	int portno;
> 
> -	orig  = ohci_hub_status_data(hcd, buf);
> +	orig = orig_ohci_hub_status_data(hcd, buf);
> 
>  	if (info == NULL)
>  		return orig;
> @@ -164,7 +181,7 @@ static int ohci_s3c2410_hub_control(
>  	 * process the request straight away and exit */
> 
>  	if (info == NULL) {
> -		ret = ohci_hub_control(hcd, typeReq, wValue,
> +		ret = orig_ohci_hub_control(hcd, typeReq, wValue,
>  				       wIndex, buf, wLength);
>  		goto out;
>  	}
> @@ -214,7 +231,7 @@ static int ohci_s3c2410_hub_control(
>  		break;
>  	}
> 
> -	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, 
wLength);
> +	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex, buf,
> wLength); if (ret)
>  		goto out;
> 
> @@ -373,8 +390,6 @@ static int usb_hcd_s3c2410_probe(const struct
> hc_driver *driver,
> 
>  	s3c2410_start_hc(dev, hcd);
> 
> -	ohci_hcd_init(hcd_to_ohci(hcd));
> -
>  	retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
>  	if (retval != 0)
>  		goto err_ioremap;
> @@ -391,71 +406,7 @@ static int usb_hcd_s3c2410_probe(const struct
> hc_driver *driver,
> 
>  /*---------------------------------------------------------------------
> ----*/
> 
> -static int
> -ohci_s3c2410_start(struct usb_hcd *hcd)
> -{
> -	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
> -	int ret;
> -
> -	ret = ohci_init(ohci);
> -	if (ret < 0)
> -		return ret;
> -
> -	ret = ohci_run(ohci);
> -	if (ret < 0) {
> -		dev_err(hcd->self.controller, "can't start %s\n",
> -			hcd->self.bus_name);
> -		ohci_stop(hcd);
> -		return ret;
> -	}
> -
> -	return 0;
> -}
> -
> -
> -static const struct hc_driver ohci_s3c2410_hc_driver = {
> -	.description =		hcd_name,
> -	.product_desc =		"S3C24XX OHCI",
> -	.hcd_priv_size =	sizeof(struct ohci_hcd),
> -
> -	/*
> -	 * generic hardware linkage
> -	 */
> -	.irq =			ohci_irq,
> -	.flags =		HCD_USB11 | HCD_MEMORY,
> -
> -	/*
> -	 * basic lifecycle operations
> -	 */
> -	.start =		ohci_s3c2410_start,
> -	.stop =			ohci_stop,
> -	.shutdown =		ohci_shutdown,
> -
> -	/*
> -	 * managing i/o requests and associated device resources
> -	 */
> -	.urb_enqueue =		ohci_urb_enqueue,
> -	.urb_dequeue =		ohci_urb_dequeue,
> -	.endpoint_disable =	ohci_endpoint_disable,
> -
> -	/*
> -	 * scheduling support
> -	 */
> -	.get_frame_number =	ohci_get_frame,
> -
> -	/*
> -	 * root hub support
> -	 */
> -	.hub_status_data =	ohci_s3c2410_hub_status_data,
> -	.hub_control =		ohci_s3c2410_hub_control,
> -#ifdef	CONFIG_PM
> -	.bus_suspend =		ohci_bus_suspend,
> -	.bus_resume =		ohci_bus_resume,
> -#endif
> -	.start_port_reset =	ohci_start_port_reset,
> -};
> -
> -/* device driver */
> +static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;
> 
>  static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
>  {
> @@ -532,4 +483,39 @@ static struct platform_driver
> ohci_hcd_s3c2410_driver = { },
>  };
> 
> +static int __init ohci_s3cxxxx_init(void)

ohci_s3c2410_init

> +{
> +	if (usb_disabled())
> +		return -ENODEV;
> +
> +	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
> +	ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
> +
> +	/*
> +	 * The Samsung HW has some unusual quirks, which require
> +	 * Sumsung-specific workarounds. We override certain hc_driver
> +	 * functions here to achieve that. We explicitly do not enhance
> +	 * ohci_driver_overrides to allow this more easily, since this
> +	 * is an unusual case, and we don't want to encourage others to
> +	 * override these functions by making it too easy.
> +	 */
> +
> +	orig_ohci_hub_control = ohci_s3c2410_hc_driver.hub_control;
> +	orig_ohci_hub_status_data = 
ohci_s3c2410_hc_driver.hub_status_data;
> +
> +	ohci_s3c2410_hc_driver.hub_status_data	= 
ohci_s3c2410_hub_status_data;
> +	ohci_s3c2410_hc_driver.hub_control	= 
ohci_s3c2410_hub_control; +
> +	return platform_driver_register(&ohci_hcd_s3c2410_driver);
> +}
> +module_init(ohci_s3cxxxx_init);
> +
> +static void __exit ohci_s3cxxxx_cleanup(void)

ohci_s3c2410_cleanup

> +{
> +	platform_driver_unregister(&ohci_hcd_s3c2410_driver);
> +}
> +module_exit(ohci_s3cxxxx_cleanup);
> +
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +MODULE_LICENSE("GPL");
>  MODULE_ALIAS("platform:s3c2410-ohci");

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (11 preceding siblings ...)
  2013-08-10  7:37 ` [PATCH V4 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
@ 2013-08-12  6:46 ` Manjunath Goudar
  2013-08-12  6:46   ` [PATCH V5 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
                     ` (6 more replies)
  2013-09-16 10:10 ` [PATCH V5 0/9] USB: " Manjunath Goudar
  2013-09-21 11:08 ` [PATCH V5 0/9] USB: OHCI: more bus glues as separate modules Manjunath Goudar
  14 siblings, 7 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-08-12  6:46 UTC (permalink / raw)
  To: linux-arm-kernel

These patches are for separating the SOC On-Chip ohci host controller
from ohci-hcd host code into its own driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.12.

V2:
  In patch 5/6 and 6/6:
  -Set non-standard fields in hc_driver manually, rather than
   relying on an expanded struct ohci_driver_overrides.
  -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
   relying on ohci_hub_control and hub_status_data being exported.

  In patch 1/6 to 4/6
  -ohci_setup() has been removed because it is called in .reset member
   of the ohci_hc_driver structure.

V3:
 In patch 5/6 and 6/6:
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

 In patch 5/6:
 -The ohci_restart() function is not required in  current scenario,
  only discarding connection state of integrated transceivers is sufficient,
  for this directly handling ohci->hc_control.

 In patch 2/6 :
 -rewritten if (config->otg || config->rwc) block statements into
  two separate 'if blocks' to handle below scenarios
  1. config->otg set scenario.
  2. if any of these (config->otg, config->rwc) are set, this
     scenario should be handled only after ohci_setup()
 
In patch 1/6 and 4/6:
  No change.

V4:
 In patch 1/6 and 4/6:
  No change.

 In patch 2/6 :
 -usb_remove_hcd() function is required a valid clock that is what
  omap_ohci_clock_power(0) is called after hcd shutdown.

 In patch 3/6 :
 -V3 modification revert back, only ohci->regs setting write()
  function has been removed because ohci->regs doesn't get set until
  usb_add_hcd.

 In patch 5/6 :
 - Removed extra space after "tristate".
 - Removed extra space between function name  and '(' characters.
 - MODULE_ALIAS line moved to last statement of ohci-at91 file.

 In patch 6/6 :
 - Removed extra space before the '='.
 - Moved  /* forward definitions */ line before the declarations of functions.

V5:
 In patch 1/6 to 5/6
  - No change.
 
 In patch 6/6:
  - String "s3cxxxx" is replaced by "s3c2410".

Manjunath Goudar (6):
  USB: OHCI: make ohci-exynos a separate driver
  USB: OHCI: make ohci-omap a separate driver
  USB: OHCI: make ohci-omap3 a separate driver
  USB: OHCI: make ohci-spear a separate driver
  USB: OHCI: make ohci-at91 a separate driver
  USB: OHCI: make ohci-s3c2410 a separate driver

 drivers/usb/host/Kconfig        |   30 ++++++-
 drivers/usb/host/Makefile       |    6 ++
 drivers/usb/host/ohci-at91.c    |  153 ++++++++++++++++-------------------
 drivers/usb/host/ohci-exynos.c  |  167 ++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c     |  108 -------------------------
 drivers/usb/host/ohci-omap.c    |  156 +++++++++++++-----------------------
 drivers/usb/host/ohci-omap3.c   |  118 +++++++++------------------
 drivers/usb/host/ohci-s3c2410.c |  128 +++++++++++++-----------------
 drivers/usb/host/ohci-spear.c   |  140 +++++++++++++-------------------
 9 files changed, 374 insertions(+), 632 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V5 1/6] USB: OHCI: make ohci-exynos a separate driver
  2013-08-12  6:46 ` [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules Manjunath Goudar
@ 2013-08-12  6:46   ` Manjunath Goudar
  2013-08-12  6:46   ` [PATCH V5 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-08-12  6:46 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  Samsung OHCI EXYNOS host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.12.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Cc: Vivek Gautam <gautam.vivek@samsung.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -exynos_ohci_hcd structure assignment error fixed.
 -Removed multiple usb_create_hcd() from prob funtion.
 -platform_set_drvdata() called before exynos_ohci_phy_enable().
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure

V3:
 -No major changes only "exynos" written in capital letters
  in "OHCI exynos driver".

V4:
 -No change.

V5:
 -No Change. 

---
 drivers/usb/host/Kconfig       |    2 +-
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ohci-exynos.c |  167 +++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c    |   18 -----
 4 files changed, 71 insertions(+), 117 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 7bc598b..7b8f6bd 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -463,7 +463,7 @@ config USB_OHCI_SH
 	  If you use the PCI OHCI controller, this option is not necessary.
 
 config USB_OHCI_EXYNOS
-	boolean "OHCI support for Samsung EXYNOS SoC Series"
+	tristate "OHCI support for Samsung EXYNOS SoC Series"
 	depends on ARCH_EXYNOS
 	help
 	 Enable support for the Samsung Exynos SOC's on-chip OHCI controller.
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 28adb3f..45e2ffb 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
+obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index b0b542c..ae6068d 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -12,24 +12,39 @@
  */
 
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-exynos.h>
 #include <linux/usb/phy.h>
 #include <linux/usb/samsung_usb_phy.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include "ohci.h"
+
+#define DRIVER_DESC "OHCI EXYNOS driver"
+
+static const char hcd_name[] = "ohci-exynos";
+static struct hc_driver __read_mostly exynos_ohci_hc_driver;
+
+#define to_exynos_ohci(hcd) (struct exynos_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
 
 struct exynos_ohci_hcd {
-	struct device *dev;
-	struct usb_hcd *hcd;
 	struct clk *clk;
 	struct usb_phy *phy;
 	struct usb_otg *otg;
 	struct exynos4_ohci_platdata *pdata;
 };
 
-static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_enable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_init(exynos_ohci->phy);
@@ -37,9 +52,10 @@ static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
 }
 
-static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_disable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_shutdown(exynos_ohci->phy);
@@ -47,63 +63,11 @@ static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
 }
 
-static int ohci_exynos_reset(struct usb_hcd *hcd)
-{
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-static int ohci_exynos_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci);
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-static const struct hc_driver exynos_ohci_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "EXYNOS OHCI Host Controller",
-	.hcd_priv_size		= sizeof(struct ohci_hcd),
-
-	.irq			= ohci_irq,
-	.flags			= HCD_MEMORY|HCD_USB11,
-
-	.reset			= ohci_exynos_reset,
-	.start			= ohci_exynos_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-
-	.get_frame_number	= ohci_get_frame,
-
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-	.start_port_reset	= ohci_start_port_reset,
-};
-
 static int exynos_ohci_probe(struct platform_device *pdev)
 {
 	struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_ohci_hcd *exynos_ohci;
 	struct usb_hcd *hcd;
-	struct ohci_hcd *ohci;
 	struct resource *res;
 	struct usb_phy *phy;
 	int irq;
@@ -119,10 +83,14 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	if (!pdev->dev.coherent_dma_mask)
 		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
-	exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd),
-					GFP_KERNEL);
-	if (!exynos_ohci)
+	hcd = usb_create_hcd(&exynos_ohci_hc_driver,
+				&pdev->dev, dev_name(&pdev->dev));
+	if (!hcd) {
+		dev_err(&pdev->dev, "Unable to create HCD\n");
 		return -ENOMEM;
+	}
+
+	exynos_ohci = to_exynos_ohci(hcd);
 
 	if (of_device_is_compatible(pdev->dev.of_node,
 					"samsung,exynos5440-ohci"))
@@ -143,17 +111,6 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	}
 
 skip_phy:
-
-	exynos_ohci->dev = &pdev->dev;
-
-	hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
-					dev_name(&pdev->dev));
-	if (!hcd) {
-		dev_err(&pdev->dev, "Unable to create HCD\n");
-		return -ENOMEM;
-	}
-
-	exynos_ohci->hcd = hcd;
 	exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");
 
 	if (IS_ERR(exynos_ohci->clk)) {
@@ -190,26 +147,21 @@ skip_phy:
 	}
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	platform_set_drvdata(pdev, hcd);
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to add USB HCD\n");
 		goto fail_add_hcd;
 	}
-
-	platform_set_drvdata(pdev, exynos_ohci);
-
 	return 0;
 
 fail_add_hcd:
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 fail_io:
 	clk_disable_unprepare(exynos_ohci->clk);
 fail_clk:
@@ -219,16 +171,15 @@ fail_clk:
 
 static int exynos_ohci_remove(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	usb_remove_hcd(hcd);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -239,8 +190,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
 
 static void exynos_ohci_shutdown(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
 	if (hcd->driver->shutdown)
 		hcd->driver->shutdown(hcd);
@@ -249,9 +199,10 @@ static void exynos_ohci_shutdown(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int exynos_ohci_suspend(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	struct platform_device *pdev = to_platform_device(dev);
 	unsigned long flags;
 	int rc = 0;
 
@@ -271,10 +222,9 @@ static int exynos_ohci_suspend(struct device *dev)
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -286,16 +236,16 @@ fail:
 
 static int exynos_ohci_resume(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd			= dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci	= to_exynos_ohci(hcd);
+	struct platform_device *pdev		= to_platform_device(dev);
 
 	clk_prepare_enable(exynos_ohci->clk);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	ohci_resume(hcd, false);
 
@@ -306,6 +256,10 @@ static int exynos_ohci_resume(struct device *dev)
 #define exynos_ohci_resume	NULL
 #endif
 
+static const struct ohci_driver_overrides exynos_overrides __initconst = {
+	.extra_priv_size =	sizeof(struct exynos_ohci_hcd),
+};
+
 static const struct dev_pm_ops exynos_ohci_pm_ops = {
 	.suspend	= exynos_ohci_suspend,
 	.resume		= exynos_ohci_resume,
@@ -331,6 +285,23 @@ static struct platform_driver exynos_ohci_driver = {
 		.of_match_table	= of_match_ptr(exynos_ohci_match),
 	}
 };
+static int __init ohci_exynos_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&exynos_ohci_hc_driver, &exynos_overrides);
+	return platform_driver_register(&exynos_ohci_driver);
+}
+module_init(ohci_exynos_init);
+
+static void __exit ohci_exynos_cleanup(void)
+{
+	platform_driver_unregister(&exynos_ohci_driver);
+}
+module_exit(ohci_exynos_cleanup);
 
 MODULE_ALIAS("platform:exynos-ohci");
 MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index a9d3437..2980bb6 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_EXYNOS
-#include "ohci-exynos.c"
-#define EXYNOS_PLATFORM_DRIVER	exynos_ohci_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP1
 #include "ohci-omap.c"
 #define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
@@ -1336,12 +1331,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_s3c2410;
 #endif
 
-#ifdef EXYNOS_PLATFORM_DRIVER
-	retval = platform_driver_register(&EXYNOS_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_exynos;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1395,10 +1384,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
- error_exynos:
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
  error_s3c2410:
@@ -1463,9 +1448,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 2/6] USB: OHCI: make ohci-omap a separate driver
  2013-08-12  6:46 ` [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules Manjunath Goudar
  2013-08-12  6:46   ` [PATCH V5 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
@ 2013-08-12  6:46   ` Manjunath Goudar
  2013-08-12  6:46   ` [PATCH V5 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
                     ` (4 subsequent siblings)
  6 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-08-12  6:46 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP1/2 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -omap_ohci_clock_power(0) called in usb_hcd_omap_remove().
 -Removed ohci_setup() call from usb_hcd_omap_probe().
 -host_enabled and host_initialized variables aren't used for anything
  thats what removed.

V3:
 -rewritten if (config->otg || config->rwc) block statements into
  two separate 'if blocks' to handle below scenarios
  1. config->otg set scenario.
  2. if any of these (config->otg, config->rwc) are set, this
     scenario should be handled only after ohci_setup()

V4:
 -usb_remove_hcd() function is required a valid clock that is what
  omap_ohci_clock_power(0) is called after hcd shutdown.

V5:
 -No change.
---
 drivers/usb/host/Kconfig     |    2 +-
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-hcd.c  |   18 -----
 drivers/usb/host/ohci-omap.c |  156 ++++++++++++++----------------------------
 4 files changed, 55 insertions(+), 122 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 7b8f6bd..99b7e7e 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -376,7 +376,7 @@ config USB_OHCI_HCD
 if USB_OHCI_HCD
 
 config USB_OHCI_HCD_OMAP1
-	bool "OHCI support for OMAP1/2 chips"
+	tristate "OHCI support for OMAP1/2 chips"
 	depends on ARCH_OMAP1
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 45e2ffb..a0220c1 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 2980bb6..1abc1e7 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP1
-#include "ohci-omap.c"
-#define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP3
 #include "ohci-omap3.c"
 #define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
@@ -1289,12 +1284,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP1_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP1_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap1_platform;
-#endif
-
 #ifdef OMAP3_PLATFORM_DRIVER
 	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1408,10 +1397,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
  error_omap3_platform:
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
- error_omap1_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1466,9 +1451,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OMAP3_PLATFORM_DRIVER
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 8747fa6..8149ef0 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -14,12 +14,21 @@
  * This file is licenced under the GPL.
  */
 
-#include <linux/signal.h>
-#include <linux/jiffies.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
 #include <asm/io.h>
 #include <asm/mach-types.h>
@@ -42,10 +51,7 @@
 #define OMAP1510_LB_MMU_RAM_H	0xfffec234
 #define OMAP1510_LB_MMU_RAM_L	0xfffec238
 
-
-#ifndef CONFIG_ARCH_OMAP
-#error "This file is OMAP bus glue.  CONFIG_OMAP must be defined."
-#endif
+#define DRIVER_DESC "OHCI OMAP driver"
 
 #ifdef CONFIG_TPS65010
 #include <linux/i2c/tps65010.h>
@@ -68,8 +74,9 @@ extern int ocpi_enable(void);
 
 static struct clk *usb_host_ck;
 static struct clk *usb_dc_ck;
-static int host_enabled;
-static int host_initialized;
+
+static const char hcd_name[] = "ohci-omap";
+static struct hc_driver __read_mostly ohci_omap_hc_driver;
 
 static void omap_ohci_clock_power(int on)
 {
@@ -188,7 +195,7 @@ static void start_hnp(struct ohci_hcd *ohci)
 
 /*-------------------------------------------------------------------------*/
 
-static int ohci_omap_init(struct usb_hcd *hcd)
+static int ohci_omap_reset(struct usb_hcd *hcd)
 {
 	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
 	struct omap_usb_config	*config = hcd->self.controller->platform_data;
@@ -198,9 +205,9 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	dev_dbg(hcd->self.controller, "starting USB Controller\n");
 
 	if (config->otg) {
-		ohci_to_hcd(ohci)->self.otg_port = config->otg;
+		hcd->self.otg_port = config->otg;
 		/* default/minimum OTG power budget:  8 mA */
-		ohci_to_hcd(ohci)->power_budget = 8;
+		hcd->power_budget = 8;
 	}
 
 	/* boards can use OTG transceivers in non-OTG modes */
@@ -238,9 +245,15 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 		omap_1510_local_bus_init();
 	}
 
-	if ((ret = ohci_init(ohci)) < 0)
+	ret = ohci_setup(hcd);
+	if (ret < 0)
 		return ret;
 
+	if (config->otg || config->rwc) {
+		ohci->hc_control = OHCI_CTRL_RWC;
+		writel(OHCI_CTRL_RWC, &ohci->regs->control);
+	}
+
 	/* board-specific power switching and overcurrent support */
 	if (machine_is_omap_osk() || machine_is_omap_innovator()) {
 		u32	rh = roothub_a (ohci);
@@ -281,14 +294,6 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	return 0;
 }
 
-static void ohci_omap_stop(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
-	ohci_stop(hcd);
-	omap_ohci_clock_power(0);
-}
-
-
 /*-------------------------------------------------------------------------*/
 
 /**
@@ -304,7 +309,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 {
 	int retval, irq;
 	struct usb_hcd *hcd = 0;
-	struct ohci_hcd *ohci;
 
 	if (pdev->num_resources != 2) {
 		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
@@ -354,12 +358,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 		goto err2;
 	}
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
-
-	host_initialized = 0;
-	host_enabled = 1;
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		retval = -ENXIO;
@@ -369,11 +367,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 	if (retval)
 		goto err3;
 
-	host_initialized = 1;
-
-	if (!host_enabled)
-		omap_ohci_clock_power(0);
-
 	return 0;
 err3:
 	iounmap(hcd->regs);
@@ -402,7 +395,9 @@ err0:
 static inline void
 usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
+	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
 	usb_remove_hcd(hcd);
+	omap_ohci_clock_power(0);
 	if (!IS_ERR_OR_NULL(hcd->phy)) {
 		(void) otg_set_host(hcd->phy->otg, 0);
 		usb_put_phy(hcd->phy);
@@ -418,76 +413,6 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_omap_start (struct usb_hcd *hcd)
-{
-	struct omap_usb_config *config;
-	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ret;
-
-	if (!host_enabled)
-		return 0;
-	config = hcd->self.controller->platform_data;
-	if (config->otg || config->rwc) {
-		ohci->hc_control = OHCI_CTRL_RWC;
-		writel(OHCI_CTRL_RWC, &ohci->regs->control);
-	}
-
-	if ((ret = ohci_run (ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop (hcd);
-		return ret;
-	}
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_omap_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap_init,
-	.start =		ohci_omap_start,
-	.stop =			ohci_omap_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static int ohci_hcd_omap_drv_probe(struct platform_device *dev)
 {
 	return usb_hcd_omap_probe(&ohci_omap_hc_driver, dev);
@@ -553,4 +478,29 @@ static struct platform_driver ohci_hcd_omap_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides omap_overrides __initconst = {
+	.product_desc	= "OMAP OHCI",
+	.reset		= ohci_omap_reset
+};
+
+static int __init ohci_omap_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap_hc_driver, &omap_overrides);
+	return platform_driver_register(&ohci_hcd_omap_driver);
+}
+module_init(ohci_omap_init);
+
+static void __exit ohci_omap_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap_driver);
+}
+module_exit(ohci_omap_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 3/6] USB: OHCI: make ohci-omap3 a separate driver
  2013-08-12  6:46 ` [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules Manjunath Goudar
  2013-08-12  6:46   ` [PATCH V5 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
  2013-08-12  6:46   ` [PATCH V5 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
@ 2013-08-12  6:46   ` Manjunath Goudar
  2013-08-12  6:46   ` [PATCH V5 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
                     ` (3 subsequent siblings)
  6 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-08-12  6:46 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP3 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Anand Gadiyar <gadiyar@ti.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -The improper multi-line commenting style written in proper way.
  ('*' characters aligned in vertically).

V3:
 -RemoteWakeupConnected setting has been removed.

V4:
 -V3 modification revert back, only ohci->regs setting write()
  function has been removed because ohci->regs doesn't get set until
  usb_add_hcd.

V5:
 - No change.
---
 drivers/usb/host/Kconfig      |    2 +-
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 -------
 drivers/usb/host/ohci-omap3.c |  118 +++++++++++++----------------------------
 4 files changed, 40 insertions(+), 99 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 99b7e7e..3eab432 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -383,7 +383,7 @@ config USB_OHCI_HCD_OMAP1
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
 config USB_OHCI_HCD_OMAP3
-	bool "OHCI support for OMAP3 and later chips"
+	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index a0220c1..a0064a6 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 1abc1e7..cad51d2 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP3
-#include "ohci-omap3.c"
-#define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1284,12 +1279,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP3_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap3_platform;
-#endif
-
 #ifdef OF_PLATFORM_DRIVER
 	retval = platform_driver_register(&OF_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1393,10 +1382,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
  error_of_platform:
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
- error_omap3_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1448,9 +1433,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OF_PLATFORM_DRIVER
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index 8f71357..e14f4d9 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -29,90 +29,22 @@
  *	- add kernel-doc
  */
 
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/of.h>
-#include <linux/dma-mapping.h>
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_init(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "starting OHCI controller\n");
-
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	/*
-	 * RemoteWakeupConnected has to be set explicitly before
-	 * calling ohci_run. The reset value of RWC is 0.
-	 */
-	ohci->hc_control = OHCI_CTRL_RWC;
-	writel(OHCI_CTRL_RWC, &ohci->regs->control);
-
-	ret = ohci_run(ohci);
-
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-	}
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
-	return ret;
-}
+#include "ohci.h"
 
-/*-------------------------------------------------------------------------*/
+#define DRIVER_DESC "OHCI OMAP3 driver"
 
-static const struct hc_driver ohci_omap3_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP3 OHCI Host Controller",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap3_init,
-	.start =		ohci_omap3_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
+static const char hcd_name[] = "ohci-omap3";
+static struct hc_driver __read_mostly ohci_omap3_hc_driver;
 
 /*
  * configure so an HC device and id are always provided
@@ -129,6 +61,7 @@ static const struct hc_driver ohci_omap3_hc_driver = {
 static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 {
 	struct device		*dev = &pdev->dev;
+	struct ohci_hcd		*ohci;
 	struct usb_hcd		*hcd = NULL;
 	void __iomem		*regs = NULL;
 	struct resource		*res;
@@ -185,7 +118,12 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	ohci = hcd_to_ohci(hcd);
+	/*
+	 * RemoteWakeupConnected has to be set explicitly before
+	 * calling ohci_run. The reset value of RWC is 0.
+	 */
+	ohci->hc_control = OHCI_CTRL_RWC;
 
 	ret = usb_add_hcd(hcd, irq, 0);
 	if (ret) {
@@ -256,5 +194,25 @@ static struct platform_driver ohci_hcd_omap3_driver = {
 	},
 };
 
+static int __init ohci_omap3_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap3_hc_driver, NULL);
+	return platform_driver_register(&ohci_hcd_omap3_driver);
+}
+module_init(ohci_omap3_init);
+
+static void __exit ohci_omap3_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap3_driver);
+}
+module_exit(ohci_omap3_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci-omap3");
 MODULE_AUTHOR("Anand Gadiyar <gadiyar@ti.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 4/6] USB: OHCI: make ohci-spear a separate driver
  2013-08-12  6:46 ` [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (2 preceding siblings ...)
  2013-08-12  6:46   ` [PATCH V5 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
@ 2013-08-12  6:46   ` Manjunath Goudar
  2013-08-12  6:56     ` Viresh Kumar
  2013-08-12  6:46   ` [PATCH V5 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
                     ` (2 subsequent siblings)
  6 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-08-12  6:46 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the ST OHCI SPEAr host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.11.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -debugging stuff isn't needed any more that's what removed.

V3:
 No change.

V4:
 No change.

V5:
 No change.
---
 drivers/usb/host/Kconfig      |    8 +++
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 ------
 drivers/usb/host/ohci-spear.c |  140 +++++++++++++++++------------------------
 4 files changed, 65 insertions(+), 102 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 3eab432..a5a34a3 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -382,6 +382,14 @@ config USB_OHCI_HCD_OMAP1
 	---help---
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
+config USB_OHCI_HCD_SPEAR
+        tristate "Support for ST SPEAr on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && PLAT_SPEAR
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          ST SPEAr chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index a0064a6..8cc3f63 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
+obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index cad51d2..34ec156 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1212,11 +1212,6 @@ MODULE_LICENSE ("GPL");
 #define OF_PLATFORM_DRIVER	ohci_hcd_ppc_of_driver
 #endif
 
-#ifdef CONFIG_PLAT_SPEAR
-#include "ohci-spear.c"
-#define SPEAR_PLATFORM_DRIVER	spear_ohci_hcd_driver
-#endif
-
 #ifdef CONFIG_PPC_PS3
 #include "ohci-ps3.c"
 #define PS3_SYSTEM_BUS_DRIVER	ps3_ohci_driver
@@ -1333,19 +1328,9 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_davinci;
 #endif
 
-#ifdef SPEAR_PLATFORM_DRIVER
-	retval = platform_driver_register(&SPEAR_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_spear;
-#endif
-
 	return retval;
 
 	/* Error path */
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
- error_spear:
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
  error_davinci:
@@ -1403,9 +1388,6 @@ module_init(ohci_hcd_mod_init);
 
 static void __exit ohci_hcd_mod_exit(void)
 {
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index cc9dd9e..31ff3fc 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -11,92 +11,37 @@
 * warranty of any kind, whether express or implied.
 */
 
-#include <linux/signal.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
+#define DRIVER_DESC "OHCI SPEAr driver"
+
+static const char hcd_name[] = "SPEAr-ohci";
 struct spear_ohci {
-	struct ohci_hcd ohci;
 	struct clk *clk;
 };
 
-#define to_spear_ohci(hcd)	(struct spear_ohci *)hcd_to_ohci(hcd)
-
-static void spear_start_ohci(struct spear_ohci *ohci)
-{
-	clk_prepare_enable(ohci->clk);
-}
-
-static void spear_stop_ohci(struct spear_ohci *ohci)
-{
-	clk_disable_unprepare(ohci->clk);
-}
-
-static int ohci_spear_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-	ohci->regs = hcd->regs;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	create_debug_files(ohci);
-
-#ifdef DEBUG
-	ohci_dump(ohci, 1);
-#endif
-	return 0;
-}
-
-static const struct hc_driver ohci_spear_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "SPEAr OHCI",
-	.hcd_priv_size		= sizeof(struct spear_ohci),
-
-	/* generic hardware linkage */
-	.irq			= ohci_irq,
-	.flags			= HCD_USB11 | HCD_MEMORY,
-
-	/* basic lifecycle operations */
-	.start			= ohci_spear_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-
-	/* managing i/o requests and associated device resources */
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	/* scheduling support */
-	.get_frame_number	= ohci_get_frame,
+#define to_spear_ohci(hcd)     (struct spear_ohci *)(hcd_to_ohci(hcd)->priv)
 
-	/* root hub support */
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-
-	.start_port_reset	= ohci_start_port_reset,
-};
+static struct hc_driver __read_mostly ohci_spear_hc_driver;
 
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
 	const struct hc_driver *driver = &ohci_spear_hc_driver;
+	struct ohci_hcd *ohci;
 	struct usb_hcd *hcd = NULL;
 	struct clk *usbh_clk;
-	struct spear_ohci *ohci_p;
+	struct spear_ohci *sohci_p;
 	struct resource *res;
 	int retval, irq;
 
@@ -151,16 +96,18 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 		goto err_put_hcd;
 	}
 
-	ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
-	ohci_p->clk = usbh_clk;
-	spear_start_ohci(ohci_p);
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	sohci_p = to_spear_ohci(hcd);
+	sohci_p->clk = usbh_clk;
+
+	clk_prepare_enable(sohci_p->clk);
+
+	ohci = hcd_to_ohci(hcd);
 
 	retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0);
 	if (retval == 0)
 		return retval;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
 err_put_hcd:
 	usb_put_hcd(hcd);
 fail:
@@ -172,11 +119,11 @@ fail:
 static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	usb_remove_hcd(hcd);
-	if (ohci_p->clk)
-		spear_stop_ohci(ohci_p);
+	if (sohci_p->clk)
+		clk_disable_unprepare(sohci_p->clk);
 
 	usb_put_hcd(hcd);
 	return 0;
@@ -188,13 +135,14 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
+
 	return 0;
 }
 
@@ -202,13 +150,13 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_start_ohci(ohci_p);
+	clk_prepare_enable(sohci_p->clk);
 	ohci_resume(hcd, false);
 	return 0;
 }
@@ -234,4 +182,28 @@ static struct platform_driver spear_ohci_hcd_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides spear_overrides __initconst = {
+	.extra_priv_size = sizeof(struct spear_ohci),
+};
+static int __init ohci_spear_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_spear_hc_driver, &spear_overrides);
+	return platform_driver_register(&spear_ohci_hcd_driver);
+}
+module_init(ohci_spear_init);
+
+static void __exit ohci_spear_cleanup(void)
+{
+	platform_driver_unregister(&spear_ohci_hcd_driver);
+}
+module_exit(ohci_spear_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Deepak Sikri");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:spear-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 5/6] USB: OHCI: make ohci-at91 a separate driver
  2013-08-12  6:46 ` [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (3 preceding siblings ...)
  2013-08-12  6:46   ` [PATCH V5 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
@ 2013-08-12  6:46   ` Manjunath Goudar
  2013-08-12  6:47   ` [PATCH V5 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
  2013-08-12  6:54   ` [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules Viresh Kumar
  6 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-08-12  6:46 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI Atmel host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
it would be nice to have in 3.12.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -Set non-standard fields in ohci_at91_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

V3:
 -The ohci_restart() function is not required in  current scenario,
  only discarding connection state of integrated transceivers is sufficient,
  for this directly handling ohci->hc_control.

V4:
 - Removed extra space after "tristate".
 - Removed extra space between function name  and '(' characters.
 - MODULE_ALIAS line moved to last statement of ohci-at91 file.

V5:
 -No change.
---
 drivers/usb/host/Kconfig     |    8 +++
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-at91.c |  153 +++++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c  |   18 -----
 4 files changed, 77 insertions(+), 103 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index a5a34a3..693560a 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_AT91
+        tristate "Support for Atmel on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && ARCH_AT91
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          Atmel chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 8cc3f63..a0ac663 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
+obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 9677f68..08e28eb 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -13,27 +13,41 @@
  */
 
 #include <linux/clk.h>
-#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/atmel.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
 #include <mach/hardware.h>
 #include <asm/gpio.h>
 
 #include <mach/cpu.h>
 
-#ifndef CONFIG_ARCH_AT91
-#error "CONFIG_ARCH_AT91 must be defined."
-#endif
+
+#include "ohci.h"
 
 #define valid_port(index)	((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
 #define at91_for_each_port(index)	\
 		for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++)
 
 /* interface and function clocks; sometimes also an AHB clock */
+
+#define DRIVER_DESC "OHCI Atmel driver"
+
+static const char hcd_name[] = "ohci-atmel";
+
+static struct hc_driver __read_mostly ohci_at91_hc_driver;
 static struct clk *iclk, *fclk, *hclk;
 static int clocked;
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+			u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
 
 extern int usb_disabled(void);
 
@@ -111,6 +125,8 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
 static int usb_hcd_at91_probe(const struct hc_driver *driver,
 			struct platform_device *pdev)
 {
+	struct at91_usbh_data *board;
+	struct ohci_hcd *ohci;
 	int retval;
 	struct usb_hcd *hcd = NULL;
 
@@ -163,8 +179,10 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
 		goto err5;
 	}
 
+	board = hcd->self.controller->platform_data;
+	ohci = hcd_to_ohci(hcd);
+	ohci->num_ports = board->ports;
 	at91_start_hc(pdev);
-	ohci_hcd_init(hcd_to_ohci(hcd));
 
 	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
 	if (retval == 0)
@@ -221,36 +239,6 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd,
 }
 
 /*-------------------------------------------------------------------------*/
-
-static int
-ohci_at91_reset (struct usb_hcd *hcd)
-{
-	struct at91_usbh_data	*board = hcd->self.controller->platform_data;
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
-	ohci->num_ports = board->ports;
-	return 0;
-}
-
-static int
-ohci_at91_start (struct usb_hcd *hcd)
-{
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_run(ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-	return 0;
-}
-
 static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
 {
 	if (!valid_port(port))
@@ -281,7 +269,7 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
 static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
 	struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
-	int length = ohci_hub_status_data(hcd, buf);
+	int length = orig_ohci_hub_status_data(hcd, buf);
 	int port;
 
 	at91_for_each_port(port) {
@@ -359,7 +347,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex + 1,
+				buf, wLength);
 	if (ret)
 		goto out;
 
@@ -413,51 +402,6 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 /*-------------------------------------------------------------------------*/
 
-static const struct hc_driver ohci_at91_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"AT91 OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_at91_reset,
-	.start =		ohci_at91_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_at91_hub_status_data,
-	.hub_control =		ohci_at91_hub_control,
-#ifdef CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
 {
 	struct platform_device *pdev = data;
@@ -686,7 +630,11 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
 	 * REVISIT: some boards will be able to turn VBUS off...
 	 */
 	if (at91_suspend_entering_slow_clock()) {
-		ohci_usb_reset (ohci);
+		ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
+		ohci->hc_control &= OHCI_CTRL_RWC;
+		ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
+		ohci->rh_state = OHCI_RH_HALTED;
+
 		/* flush the writes */
 		(void) ohci_readl (ohci, &ohci->regs->control);
 		at91_stop_clock();
@@ -713,8 +661,6 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
 #define ohci_hcd_at91_drv_resume  NULL
 #endif
 
-MODULE_ALIAS("platform:at91_ohci");
-
 static struct platform_driver ohci_hcd_at91_driver = {
 	.probe		= ohci_hcd_at91_drv_probe,
 	.remove		= ohci_hcd_at91_drv_remove,
@@ -727,3 +673,40 @@ static struct platform_driver ohci_hcd_at91_driver = {
 		.of_match_table	= of_match_ptr(at91_ohci_dt_ids),
 	},
 };
+
+static int __init ohci_at91_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_at91_hc_driver, NULL);
+
+	/*
+	 * The Atmel HW has some unusual quirks, which require Atmel-specific
+	 * workarounds. We override certain hc_driver functions here to
+	 * achieve that. We explicitly do not enhance ohci_driver_overrides to
+	 * allow this more easily, since this is an unusual case, and we don't
+	 * want to encourage others to override these functions by making it
+	 * too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_at91_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_at91_hc_driver.hub_status_data;
+
+	ohci_at91_hc_driver.hub_status_data	= ohci_at91_hub_status_data;
+	ohci_at91_hc_driver.hub_control		= ohci_at91_hub_control;
+
+	return platform_driver_register(&ohci_hcd_at91_driver);
+}
+module_init(ohci_at91_init);
+
+static void __exit ohci_at91_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_at91_driver);
+}
+module_exit(ohci_at91_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:at91_ohci");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 34ec156..b48c892 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1192,11 +1192,6 @@ MODULE_LICENSE ("GPL");
 #define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver
 #endif
 
-#ifdef CONFIG_ARCH_AT91
-#include "ohci-at91.c"
-#define AT91_PLATFORM_DRIVER	ohci_hcd_at91_driver
-#endif
-
 #ifdef CONFIG_ARCH_LPC32XX
 #include "ohci-nxp.c"
 #define NXP_PLATFORM_DRIVER	usb_hcd_nxp_driver
@@ -1310,12 +1305,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_ep93xx;
 #endif
 
-#ifdef AT91_PLATFORM_DRIVER
-	retval = platform_driver_register(&AT91_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_at91;
-#endif
-
 #ifdef NXP_PLATFORM_DRIVER
 	retval = platform_driver_register(&NXP_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1339,10 +1328,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
  error_nxp:
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
- error_at91:
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
@@ -1394,9 +1379,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef NXP_PLATFORM_DRIVER
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 6/6] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-08-12  6:46 ` [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (4 preceding siblings ...)
  2013-08-12  6:46   ` [PATCH V5 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
@ 2013-08-12  6:47   ` Manjunath Goudar
  2013-08-17 13:21     ` Tomasz Figa
  2013-08-12  6:54   ` [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules Viresh Kumar
  6 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-08-12  6:47 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the Samsung OHCI S3C24xx/S3C64xx host controller driver
from ohci-hcd host code so that it can be built as a separate
driver module.This work is part of enabling multi-platform
kernels on ARM;it would be nice to have in 3.12.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2:
 -Set non-standard fields in ohci_s3c2410_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.

V3:
 -Kconfig wrong parentheses discription fixed.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

V4:
 - Removed extra space before the '='.
 - Moved  /* forward definitions */ line before the declarations of functions.

V5:
 - String "s3cxxxx" is replaced by "s3c2410".
---
 drivers/usb/host/Kconfig        |    8 +++
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ohci-hcd.c     |   18 ------
 drivers/usb/host/ohci-s3c2410.c |  128 +++++++++++++++++----------------------
 4 files changed, 66 insertions(+), 89 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 693560a..ac7df55 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_S3C2410
+        tristate "OHCI support for Samsung S3C24xx/S3C64xx SoC series"
+        depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX)
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          S3C24xx/S3C64xx chips.
+
 config USB_OHCI_HCD_AT91
         tristate "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index a0ac663..cc5beaf 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
+obj-$(CONFIG_USB_OHCI_HCD_S3C2410)	+= ohci-s3c2410.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index b48c892..b69a49e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1177,11 +1177,6 @@ MODULE_LICENSE ("GPL");
 #define SA1111_DRIVER		ohci_hcd_sa1111_driver
 #endif
 
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
-#include "ohci-s3c2410.c"
-#define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1293,12 +1288,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_tmio;
 #endif
 
-#ifdef S3C2410_PLATFORM_DRIVER
-	retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_s3c2410;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1332,10 +1321,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
- error_s3c2410:
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
  error_tmio:
@@ -1382,9 +1367,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index e125770..61f9aea 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -19,19 +19,36 @@
  * This file is licenced under the GPL.
 */
 
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
+
 
 #define valid_port(idx) ((idx) == 1 || (idx) == 2)
 
 /* clock device associated with the hcd */
 
+
+#define DRIVER_DESC "OHCI S3C2410 driver"
+
+static const char hcd_name[] = "ohci-s3c2410";
+
 static struct clk *clk;
 static struct clk *usb_clk;
 
 /* forward definitions */
 
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+			u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
+
 static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
 
 /* conversion functions */
@@ -93,7 +110,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd, char *buf)
 	int orig;
 	int portno;
 
-	orig  = ohci_hub_status_data(hcd, buf);
+	orig = orig_ohci_hub_status_data(hcd, buf);
 
 	if (info == NULL)
 		return orig;
@@ -164,7 +181,7 @@ static int ohci_s3c2410_hub_control(
 	 * process the request straight away and exit */
 
 	if (info == NULL) {
-		ret = ohci_hub_control(hcd, typeReq, wValue,
+		ret = orig_ohci_hub_control(hcd, typeReq, wValue,
 				       wIndex, buf, wLength);
 		goto out;
 	}
@@ -214,7 +231,7 @@ static int ohci_s3c2410_hub_control(
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
 	if (ret)
 		goto out;
 
@@ -373,8 +390,6 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 	s3c2410_start_hc(dev, hcd);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
-
 	retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
 	if (retval != 0)
 		goto err_ioremap;
@@ -391,71 +406,7 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_s3c2410_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-
-static const struct hc_driver ohci_s3c2410_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"S3C24XX OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.start =		ohci_s3c2410_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_s3c2410_hub_status_data,
-	.hub_control =		ohci_s3c2410_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/* device driver */
+static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;
 
 static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
 {
@@ -532,4 +483,39 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {
 	},
 };
 
+static int __init ohci_s3c2410_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
+
+	/*
+	 * The Samsung HW has some unusual quirks, which require
+	 * Sumsung-specific workarounds. We override certain hc_driver
+	 * functions here to achieve that. We explicitly do not enhance
+	 * ohci_driver_overrides to allow this more easily, since this
+	 * is an unusual case, and we don't want to encourage others to
+	 * override these functions by making it too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_s3c2410_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_s3c2410_hc_driver.hub_status_data;
+
+	ohci_s3c2410_hc_driver.hub_status_data	= ohci_s3c2410_hub_status_data;
+	ohci_s3c2410_hc_driver.hub_control	= ohci_s3c2410_hub_control;
+
+	return platform_driver_register(&ohci_hcd_s3c2410_driver);
+}
+module_init(ohci_s3c2410_init);
+
+static void __exit ohci_s3c2410_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_s3c2410_driver);
+}
+module_exit(ohci_s3c2410_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:s3c2410-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules
  2013-08-12  6:46 ` [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (5 preceding siblings ...)
  2013-08-12  6:47   ` [PATCH V5 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
@ 2013-08-12  6:54   ` Viresh Kumar
  6 siblings, 0 replies; 110+ messages in thread
From: Viresh Kumar @ 2013-08-12  6:54 UTC (permalink / raw)
  To: linux-arm-kernel

On 12 August 2013 12:16, Manjunath Goudar <manjunath.goudar@linaro.org> wrote:
> V5:
>  In patch 1/6 to 5/6
>   - No change.
>
>  In patch 6/6:
>   - String "s3cxxxx" is replaced by "s3c2410".

In such cases its better to just send only one patch and that can be
done by pasting your patch as a reply to earlier review..

Also, In the version log mention recent changes first, as people
are more interested in them.. So, it should be like:

V4->V5
...

V3->V4
...

V2->V3
...

...

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V5 4/6] USB: OHCI: make ohci-spear a separate driver
  2013-08-12  6:46   ` [PATCH V5 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
@ 2013-08-12  6:56     ` Viresh Kumar
  2013-08-12 20:20       ` Greg KH
  0 siblings, 1 reply; 110+ messages in thread
From: Viresh Kumar @ 2013-08-12  6:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 12 August 2013 12:16, Manjunath Goudar <manjunath.goudar@linaro.org> wrote:
> This work is part of enabling multi-platform kernels on ARM;
> it would be nice to have in 3.11.

You really want it in 3.11, we are already at 3.11-rc5 :)

Whatever you write here gets in git history with your patch and I
am sure you never wanted this to be commited. :)

So, both the above lines must be removed from each of
your patches and must be present only once in the cover-letter.

Don't resend your patches now with this.. Unless Greg wants you
to.

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V5 4/6] USB: OHCI: make ohci-spear a separate driver
  2013-08-12  6:56     ` Viresh Kumar
@ 2013-08-12 20:20       ` Greg KH
  0 siblings, 0 replies; 110+ messages in thread
From: Greg KH @ 2013-08-12 20:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 12, 2013 at 12:26:09PM +0530, Viresh Kumar wrote:
> On 12 August 2013 12:16, Manjunath Goudar <manjunath.goudar@linaro.org> wrote:
> > This work is part of enabling multi-platform kernels on ARM;
> > it would be nice to have in 3.11.
> 
> You really want it in 3.11, we are already at 3.11-rc5 :)
> 
> Whatever you write here gets in git history with your patch and I
> am sure you never wanted this to be commited. :)
> 
> So, both the above lines must be removed from each of
> your patches and must be present only once in the cover-letter.
> 
> Don't resend your patches now with this.. Unless Greg wants you
> to.

Yes, they all need to be resent as they don't seem to apply :(

Please just delete that part of the sentance from all of the patches in
this series.  It does not matter which tree it would be "nice" to have
them in, once they are accepted the changelog will show where it was
accepted.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V5 6/6] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-08-12  6:47   ` [PATCH V5 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
@ 2013-08-17 13:21     ` Tomasz Figa
  0 siblings, 0 replies; 110+ messages in thread
From: Tomasz Figa @ 2013-08-17 13:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Manjunath,

On Monday 12 of August 2013 12:17:00 Manjunath Goudar wrote:
> Separate the Samsung OHCI S3C24xx/S3C64xx host controller driver
> from ohci-hcd host code so that it can be built as a separate
> driver module.This work is part of enabling multi-platform
> kernels on ARM;it would be nice to have in 3.12.
> 
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
> Acked-by: Alan Stern <stern@rowland.harvard.edu>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Greg KH <greg@kroah.com>
> Cc: linux-usb at vger.kernel.org
> 
> V2:
>  -Set non-standard fields in ohci_s3c2410_hc_driver manually, rather
> than relying on an expanded struct ohci_driver_overrides.
>  -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
>   relying on ohci_hub_control and hub_status_data being exported.
> 
> V3:
>  -Kconfig wrong parentheses discription fixed.
>  -ohci_setup() has been removed because it is called in .reset member
>   of the ohci_hc_driver structure.
> 
> V4:
>  - Removed extra space before the '='.
>  - Moved  /* forward definitions */ line before the declarations of
> functions.
> 
> V5:
>  - String "s3cxxxx" is replaced by "s3c2410".
> ---
>  drivers/usb/host/Kconfig        |    8 +++
>  drivers/usb/host/Makefile       |    1 +
>  drivers/usb/host/ohci-hcd.c     |   18 ------
>  drivers/usb/host/ohci-s3c2410.c |  128
> +++++++++++++++++---------------------- 4 files changed, 66
> insertions(+), 89 deletions(-)
> 
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 693560a..ac7df55 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -390,6 +390,14 @@ config USB_OHCI_HCD_SPEAR
>            Enables support for the on-chip OHCI controller on
>            ST SPEAr chips.
> 
> +config USB_OHCI_HCD_S3C2410
> +        tristate "OHCI support for Samsung S3C24xx/S3C64xx SoC series"
> +        depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX)
> +        default y
> +        ---help---
> +          Enables support for the on-chip OHCI controller on
> +          S3C24xx/S3C64xx chips.
> +
>  config USB_OHCI_HCD_AT91
>          tristate "Support for Atmel on-chip OHCI USB controller"
>          depends on USB_OHCI_HCD && ARCH_AT91
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index a0ac663..cc5beaf 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -49,6 +49,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
>  obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
>  obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
>  obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
> +obj-$(CONFIG_USB_OHCI_HCD_S3C2410)	+= ohci-s3c2410.o
> 
>  obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
>  obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
> diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
> index b48c892..b69a49e 100644
> --- a/drivers/usb/host/ohci-hcd.c
> +++ b/drivers/usb/host/ohci-hcd.c
> @@ -1177,11 +1177,6 @@ MODULE_LICENSE ("GPL");
>  #define SA1111_DRIVER		ohci_hcd_sa1111_driver
>  #endif
> 
> -#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
> -#include "ohci-s3c2410.c"
> -#define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
> -#endif
> -
>  #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
>  #include "ohci-pxa27x.c"
>  #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
> @@ -1293,12 +1288,6 @@ static int __init ohci_hcd_mod_init(void)
>  		goto error_tmio;
>  #endif
> 
> -#ifdef S3C2410_PLATFORM_DRIVER
> -	retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER);
> -	if (retval < 0)
> -		goto error_s3c2410;
> -#endif
> -
>  #ifdef EP93XX_PLATFORM_DRIVER
>  	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
>  	if (retval < 0)
> @@ -1332,10 +1321,6 @@ static int __init ohci_hcd_mod_init(void)
>  	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
>   error_ep93xx:
>  #endif
> -#ifdef S3C2410_PLATFORM_DRIVER
> -	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
> - error_s3c2410:
> -#endif
>  #ifdef TMIO_OHCI_DRIVER
>  	platform_driver_unregister(&TMIO_OHCI_DRIVER);
>   error_tmio:
> @@ -1382,9 +1367,6 @@ static void __exit ohci_hcd_mod_exit(void)
>  #ifdef EP93XX_PLATFORM_DRIVER
>  	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
>  #endif
> -#ifdef S3C2410_PLATFORM_DRIVER
> -	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
> -#endif
>  #ifdef TMIO_OHCI_DRIVER
>  	platform_driver_unregister(&TMIO_OHCI_DRIVER);
>  #endif
> diff --git a/drivers/usb/host/ohci-s3c2410.c
> b/drivers/usb/host/ohci-s3c2410.c index e125770..61f9aea 100644
> --- a/drivers/usb/host/ohci-s3c2410.c
> +++ b/drivers/usb/host/ohci-s3c2410.c
> @@ -19,19 +19,36 @@
>   * This file is licenced under the GPL.
>  */
> 
> -#include <linux/platform_device.h>
>  #include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
>  #include <linux/platform_data/usb-ohci-s3c2410.h>
> +#include <linux/usb.h>
> +#include <linux/usb/hcd.h>
> +
> +#include "ohci.h"
> +
> 
>  #define valid_port(idx) ((idx) == 1 || (idx) == 2)
> 
>  /* clock device associated with the hcd */
> 
> +
> +#define DRIVER_DESC "OHCI S3C2410 driver"
> +
> +static const char hcd_name[] = "ohci-s3c2410";
> +
>  static struct clk *clk;
>  static struct clk *usb_clk;
> 
>  /* forward definitions */
> 
> +static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
> +			u16 wValue, u16 wIndex, char *buf, u16 wLength);
> +static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char
> *buf); +
>  static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
> 
>  /* conversion functions */
> @@ -93,7 +110,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd,
> char *buf) int orig;
>  	int portno;
> 
> -	orig  = ohci_hub_status_data(hcd, buf);
> +	orig = orig_ohci_hub_status_data(hcd, buf);
> 
>  	if (info == NULL)
>  		return orig;
> @@ -164,7 +181,7 @@ static int ohci_s3c2410_hub_control(
>  	 * process the request straight away and exit */
> 
>  	if (info == NULL) {
> -		ret = ohci_hub_control(hcd, typeReq, wValue,
> +		ret = orig_ohci_hub_control(hcd, typeReq, wValue,
>  				       wIndex, buf, wLength);
>  		goto out;
>  	}
> @@ -214,7 +231,7 @@ static int ohci_s3c2410_hub_control(
>  		break;
>  	}
> 
> -	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, 
wLength);
> +	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex, buf,
> wLength); if (ret)
>  		goto out;
> 
> @@ -373,8 +390,6 @@ static int usb_hcd_s3c2410_probe(const struct
> hc_driver *driver,
> 
>  	s3c2410_start_hc(dev, hcd);
> 
> -	ohci_hcd_init(hcd_to_ohci(hcd));
> -
>  	retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
>  	if (retval != 0)
>  		goto err_ioremap;
> @@ -391,71 +406,7 @@ static int usb_hcd_s3c2410_probe(const struct
> hc_driver *driver,
> 
>  /*---------------------------------------------------------------------
> ----*/
> 
> -static int
> -ohci_s3c2410_start(struct usb_hcd *hcd)
> -{
> -	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
> -	int ret;
> -
> -	ret = ohci_init(ohci);
> -	if (ret < 0)
> -		return ret;
> -
> -	ret = ohci_run(ohci);
> -	if (ret < 0) {
> -		dev_err(hcd->self.controller, "can't start %s\n",
> -			hcd->self.bus_name);
> -		ohci_stop(hcd);
> -		return ret;
> -	}
> -
> -	return 0;
> -}
> -
> -
> -static const struct hc_driver ohci_s3c2410_hc_driver = {
> -	.description =		hcd_name,
> -	.product_desc =		"S3C24XX OHCI",
> -	.hcd_priv_size =	sizeof(struct ohci_hcd),
> -
> -	/*
> -	 * generic hardware linkage
> -	 */
> -	.irq =			ohci_irq,
> -	.flags =		HCD_USB11 | HCD_MEMORY,
> -
> -	/*
> -	 * basic lifecycle operations
> -	 */
> -	.start =		ohci_s3c2410_start,
> -	.stop =			ohci_stop,
> -	.shutdown =		ohci_shutdown,
> -
> -	/*
> -	 * managing i/o requests and associated device resources
> -	 */
> -	.urb_enqueue =		ohci_urb_enqueue,
> -	.urb_dequeue =		ohci_urb_dequeue,
> -	.endpoint_disable =	ohci_endpoint_disable,
> -
> -	/*
> -	 * scheduling support
> -	 */
> -	.get_frame_number =	ohci_get_frame,
> -
> -	/*
> -	 * root hub support
> -	 */
> -	.hub_status_data =	ohci_s3c2410_hub_status_data,
> -	.hub_control =		ohci_s3c2410_hub_control,
> -#ifdef	CONFIG_PM
> -	.bus_suspend =		ohci_bus_suspend,
> -	.bus_resume =		ohci_bus_resume,
> -#endif
> -	.start_port_reset =	ohci_start_port_reset,
> -};
> -
> -/* device driver */
> +static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;
> 
>  static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
>  {
> @@ -532,4 +483,39 @@ static struct platform_driver
> ohci_hcd_s3c2410_driver = { },
>  };
> 
> +static int __init ohci_s3c2410_init(void)
> +{
> +	if (usb_disabled())
> +		return -ENODEV;
> +
> +	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
> +	ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
> +
> +	/*
> +	 * The Samsung HW has some unusual quirks, which require
> +	 * Sumsung-specific workarounds. We override certain hc_driver
> +	 * functions here to achieve that. We explicitly do not enhance
> +	 * ohci_driver_overrides to allow this more easily, since this
> +	 * is an unusual case, and we don't want to encourage others to
> +	 * override these functions by making it too easy.
> +	 */
> +
> +	orig_ohci_hub_control = ohci_s3c2410_hc_driver.hub_control;
> +	orig_ohci_hub_status_data = 
ohci_s3c2410_hc_driver.hub_status_data;
> +
> +	ohci_s3c2410_hc_driver.hub_status_data	= 
ohci_s3c2410_hub_status_data;
> +	ohci_s3c2410_hc_driver.hub_control	= 
ohci_s3c2410_hub_control; +
> +	return platform_driver_register(&ohci_hcd_s3c2410_driver);
> +}
> +module_init(ohci_s3c2410_init);
> +
> +static void __exit ohci_s3c2410_cleanup(void)
> +{
> +	platform_driver_unregister(&ohci_hcd_s3c2410_driver);
> +}
> +module_exit(ohci_s3c2410_cleanup);
> +
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +MODULE_LICENSE("GPL");
>  MODULE_ALIAS("platform:s3c2410-ohci");

Looks good.

Reviewed-by: Tomasz Figa <t.figa@samsung.com>

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V5 0/9]  USB: OHCI: more bus glues as separate modules
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (12 preceding siblings ...)
  2013-08-12  6:46 ` [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules Manjunath Goudar
@ 2013-09-16 10:10 ` Manjunath Goudar
  2013-09-16 10:10   ` [PATCH V5 1/9] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
                     ` (8 more replies)
  2013-09-21 11:08 ` [PATCH V5 0/9] USB: OHCI: more bus glues as separate modules Manjunath Goudar
  14 siblings, 9 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-16 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

These patches are for separating the SOC On-Chip ohci host controller
from ohci-hcd host code and making per SOC driver module similar to EHCI 
module available in the kernel. This work is part of enabling multi-platform 
kernel on ARM.
 
Before I was sending three different ohci patch set as below.
 1. Six series patch set is having exynos, omap, omap3, spear, at91 and s3c2410.
 2. ohci-nxp a separate driver patch.
 3. Two series patch set is having ep93xx and pxa27x.
In this patch set all three previous ohci series have been combined into single 
series as all these patches are related to OHCI.



Manjunath Goudar (9):
  USB: OHCI: make ohci-exynos a separate driver
  USB: OHCI: make ohci-omap a separate driver
  USB: OHCI: make ohci-omap3 a separate driver
  USB: OHCI: make ohci-spear a separate driver
  USB: OHCI: make ohci-at91 a separate driver
  USB: OHCI: make ohci-s3c2410 a separate driver
  USB: OHCI: make ohci-nxp a separate driver
  USB: OHCI: make ohci-ep93xx a separate driver
  USB: OHCI: make ohci-pxa27x a separate driver

 drivers/usb/host/Kconfig        |   56 ++++++++-
 drivers/usb/host/Makefile       |    9 ++
 drivers/usb/host/ohci-at91.c    |  156 ++++++++++++-------------
 drivers/usb/host/ohci-ep93xx.c  |   72 +++++-------
 drivers/usb/host/ohci-exynos.c  |  167 +++++++++++----------------
 drivers/usb/host/ohci-hcd.c     |  149 ------------------------
 drivers/usb/host/ohci-nxp.c     |  123 ++++++++------------
 drivers/usb/host/ohci-omap.c    |  156 +++++++++----------------
 drivers/usb/host/ohci-omap3.c   |  118 +++++++------------
 drivers/usb/host/ohci-pxa27x.c  |  240 +++++++++++++++++----------------------
 drivers/usb/host/ohci-s3c2410.c |  128 ++++++++++-----------
 drivers/usb/host/ohci-spear.c   |  140 +++++++++--------------
 12 files changed, 587 insertions(+), 927 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V5 1/9] USB: OHCI: make ohci-exynos a separate driver
  2013-09-16 10:10 ` [PATCH V5 0/9] USB: " Manjunath Goudar
@ 2013-09-16 10:10   ` Manjunath Goudar
  2013-09-16 10:10   ` [PATCH V5 2/9] USB: OHCI: make ohci-omap " Manjunath Goudar
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-16 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  Samsung OHCI EXYNOS host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Cc: Vivek Gautam <gautam.vivek@samsung.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2->V3:
 -No major changes only "exynos" written in capital letters
  in "OHCI exynos driver".

V1->V2:
 -exynos_ohci_hcd structure assignment error fixed.
 -Removed multiple usb_create_hcd() from prob funtion.
 -platform_set_drvdata() called before exynos_ohci_phy_enable().
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure
---
 drivers/usb/host/Kconfig       |    4 +-
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ohci-exynos.c |  167 +++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c    |   18 -----
 4 files changed, 72 insertions(+), 118 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 5be0326..e8bd542 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -455,8 +455,8 @@ config USB_OHCI_SH
 	  If you use the PCI OHCI controller, this option is not necessary.
 
 config USB_OHCI_EXYNOS
-	boolean "OHCI support for Samsung EXYNOS SoC Series"
-	depends on ARCH_EXYNOS
+	tristate "OHCI support for Samsung S5P/EXYNOS SoC Series"
+	depends on PLAT_S5P || ARCH_EXYNOS
 	help
 	 Enable support for the Samsung Exynos SOC's on-chip OHCI controller.
 
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 50b0041..73cc986 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
+obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index dc6ee9a..3e4bc74 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -12,24 +12,39 @@
  */
 
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-exynos.h>
 #include <linux/usb/phy.h>
 #include <linux/usb/samsung_usb_phy.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include "ohci.h"
+
+#define DRIVER_DESC "OHCI EXYNOS driver"
+
+static const char hcd_name[] = "ohci-exynos";
+static struct hc_driver __read_mostly exynos_ohci_hc_driver;
+
+#define to_exynos_ohci(hcd) (struct exynos_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
 
 struct exynos_ohci_hcd {
-	struct device *dev;
-	struct usb_hcd *hcd;
 	struct clk *clk;
 	struct usb_phy *phy;
 	struct usb_otg *otg;
 	struct exynos4_ohci_platdata *pdata;
 };
 
-static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_enable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_init(exynos_ohci->phy);
@@ -37,9 +52,10 @@ static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
 }
 
-static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_disable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_shutdown(exynos_ohci->phy);
@@ -47,63 +63,11 @@ static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
 }
 
-static int ohci_exynos_reset(struct usb_hcd *hcd)
-{
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-static int ohci_exynos_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci);
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-static const struct hc_driver exynos_ohci_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "EXYNOS OHCI Host Controller",
-	.hcd_priv_size		= sizeof(struct ohci_hcd),
-
-	.irq			= ohci_irq,
-	.flags			= HCD_MEMORY|HCD_USB11,
-
-	.reset			= ohci_exynos_reset,
-	.start			= ohci_exynos_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-
-	.get_frame_number	= ohci_get_frame,
-
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-	.start_port_reset	= ohci_start_port_reset,
-};
-
 static int exynos_ohci_probe(struct platform_device *pdev)
 {
 	struct exynos4_ohci_platdata *pdata = dev_get_platdata(&pdev->dev);
 	struct exynos_ohci_hcd *exynos_ohci;
 	struct usb_hcd *hcd;
-	struct ohci_hcd *ohci;
 	struct resource *res;
 	struct usb_phy *phy;
 	int irq;
@@ -119,10 +83,14 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	if (!pdev->dev.coherent_dma_mask)
 		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
-	exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd),
-					GFP_KERNEL);
-	if (!exynos_ohci)
+	hcd = usb_create_hcd(&exynos_ohci_hc_driver,
+				&pdev->dev, dev_name(&pdev->dev));
+	if (!hcd) {
+		dev_err(&pdev->dev, "Unable to create HCD\n");
 		return -ENOMEM;
+	}
+
+	exynos_ohci = to_exynos_ohci(hcd);
 
 	if (of_device_is_compatible(pdev->dev.of_node,
 					"samsung,exynos5440-ohci"))
@@ -143,17 +111,6 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	}
 
 skip_phy:
-
-	exynos_ohci->dev = &pdev->dev;
-
-	hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
-					dev_name(&pdev->dev));
-	if (!hcd) {
-		dev_err(&pdev->dev, "Unable to create HCD\n");
-		return -ENOMEM;
-	}
-
-	exynos_ohci->hcd = hcd;
 	exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");
 
 	if (IS_ERR(exynos_ohci->clk)) {
@@ -190,26 +147,21 @@ skip_phy:
 	}
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	platform_set_drvdata(pdev, hcd);
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to add USB HCD\n");
 		goto fail_add_hcd;
 	}
-
-	platform_set_drvdata(pdev, exynos_ohci);
-
 	return 0;
 
 fail_add_hcd:
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 fail_io:
 	clk_disable_unprepare(exynos_ohci->clk);
 fail_clk:
@@ -219,16 +171,15 @@ fail_clk:
 
 static int exynos_ohci_remove(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	usb_remove_hcd(hcd);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -239,8 +190,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
 
 static void exynos_ohci_shutdown(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
 	if (hcd->driver->shutdown)
 		hcd->driver->shutdown(hcd);
@@ -249,9 +199,10 @@ static void exynos_ohci_shutdown(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int exynos_ohci_suspend(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	struct platform_device *pdev = to_platform_device(dev);
 	unsigned long flags;
 	int rc = 0;
 
@@ -271,10 +222,9 @@ static int exynos_ohci_suspend(struct device *dev)
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -286,16 +236,16 @@ fail:
 
 static int exynos_ohci_resume(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd			= dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci	= to_exynos_ohci(hcd);
+	struct platform_device *pdev		= to_platform_device(dev);
 
 	clk_prepare_enable(exynos_ohci->clk);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	ohci_resume(hcd, false);
 
@@ -306,6 +256,10 @@ static int exynos_ohci_resume(struct device *dev)
 #define exynos_ohci_resume	NULL
 #endif
 
+static const struct ohci_driver_overrides exynos_overrides __initconst = {
+	.extra_priv_size =	sizeof(struct exynos_ohci_hcd),
+};
+
 static const struct dev_pm_ops exynos_ohci_pm_ops = {
 	.suspend	= exynos_ohci_suspend,
 	.resume		= exynos_ohci_resume,
@@ -331,6 +285,23 @@ static struct platform_driver exynos_ohci_driver = {
 		.of_match_table	= of_match_ptr(exynos_ohci_match),
 	}
 };
+static int __init ohci_exynos_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&exynos_ohci_hc_driver, &exynos_overrides);
+	return platform_driver_register(&exynos_ohci_driver);
+}
+module_init(ohci_exynos_init);
+
+static void __exit ohci_exynos_cleanup(void)
+{
+	platform_driver_unregister(&exynos_ohci_driver);
+}
+module_exit(ohci_exynos_cleanup);
 
 MODULE_ALIAS("platform:exynos-ohci");
 MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 8f6b695..1fc7d3b 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_EXYNOS
-#include "ohci-exynos.c"
-#define EXYNOS_PLATFORM_DRIVER	exynos_ohci_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP1
 #include "ohci-omap.c"
 #define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
@@ -1336,12 +1331,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_s3c2410;
 #endif
 
-#ifdef EXYNOS_PLATFORM_DRIVER
-	retval = platform_driver_register(&EXYNOS_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_exynos;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1395,10 +1384,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
- error_exynos:
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
  error_s3c2410:
@@ -1463,9 +1448,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 2/9] USB: OHCI: make ohci-omap a separate driver
  2013-09-16 10:10 ` [PATCH V5 0/9] USB: " Manjunath Goudar
  2013-09-16 10:10   ` [PATCH V5 1/9] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
@ 2013-09-16 10:10   ` Manjunath Goudar
  2013-09-16 10:10   ` [PATCH V5 3/9] USB: OHCI: make ohci-omap3 " Manjunath Goudar
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-16 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP1/2 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V3->V4:
 -usb_remove_hcd() function is required a valid clock that is what
  omap_ohci_clock_power(0) is called after hcd shutdown.

V2->V3:
 -rewritten if (config->otg || config->rwc) block statements into
  two separate 'if blocks' to handle below scenarios
  1. config->otg set scenario.
  2. if any of these (config->otg, config->rwc) are set, this
     scenario should be handled only after ohci_setup()

V1->V2:
 -omap_ohci_clock_power(0) called in usb_hcd_omap_remove().
 -Removed ohci_setup() call from usb_hcd_omap_probe().
 -host_enabled and host_initialized variables aren't used for anything
  thats what removed.
---
 drivers/usb/host/Kconfig     |    2 +-
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-hcd.c  |   18 -----
 drivers/usb/host/ohci-omap.c |  156 ++++++++++++++----------------------------
 4 files changed, 55 insertions(+), 122 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index e8bd542..6aa2c3f 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -368,7 +368,7 @@ config USB_OHCI_HCD
 if USB_OHCI_HCD
 
 config USB_OHCI_HCD_OMAP1
-	bool "OHCI support for OMAP1/2 chips"
+	tristate "OHCI support for OMAP1/2 chips"
 	depends on ARCH_OMAP1
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 73cc986..cfbfe13 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 1fc7d3b..fcef838 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP1
-#include "ohci-omap.c"
-#define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP3
 #include "ohci-omap3.c"
 #define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
@@ -1289,12 +1284,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP1_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP1_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap1_platform;
-#endif
-
 #ifdef OMAP3_PLATFORM_DRIVER
 	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1408,10 +1397,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
  error_omap3_platform:
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
- error_omap1_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1466,9 +1451,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OMAP3_PLATFORM_DRIVER
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 31d3a12..18b27a2 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -14,12 +14,21 @@
  * This file is licenced under the GPL.
  */
 
-#include <linux/signal.h>
-#include <linux/jiffies.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
 #include <asm/io.h>
 #include <asm/mach-types.h>
@@ -42,10 +51,7 @@
 #define OMAP1510_LB_MMU_RAM_H	0xfffec234
 #define OMAP1510_LB_MMU_RAM_L	0xfffec238
 
-
-#ifndef CONFIG_ARCH_OMAP
-#error "This file is OMAP bus glue.  CONFIG_OMAP must be defined."
-#endif
+#define DRIVER_DESC "OHCI OMAP driver"
 
 #ifdef CONFIG_TPS65010
 #include <linux/i2c/tps65010.h>
@@ -68,8 +74,9 @@ extern int ocpi_enable(void);
 
 static struct clk *usb_host_ck;
 static struct clk *usb_dc_ck;
-static int host_enabled;
-static int host_initialized;
+
+static const char hcd_name[] = "ohci-omap";
+static struct hc_driver __read_mostly ohci_omap_hc_driver;
 
 static void omap_ohci_clock_power(int on)
 {
@@ -188,7 +195,7 @@ static void start_hnp(struct ohci_hcd *ohci)
 
 /*-------------------------------------------------------------------------*/
 
-static int ohci_omap_init(struct usb_hcd *hcd)
+static int ohci_omap_reset(struct usb_hcd *hcd)
 {
 	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
 	struct omap_usb_config	*config = dev_get_platdata(hcd->self.controller);
@@ -198,9 +205,9 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	dev_dbg(hcd->self.controller, "starting USB Controller\n");
 
 	if (config->otg) {
-		ohci_to_hcd(ohci)->self.otg_port = config->otg;
+		hcd->self.otg_port = config->otg;
 		/* default/minimum OTG power budget:  8 mA */
-		ohci_to_hcd(ohci)->power_budget = 8;
+		hcd->power_budget = 8;
 	}
 
 	/* boards can use OTG transceivers in non-OTG modes */
@@ -238,9 +245,15 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 		omap_1510_local_bus_init();
 	}
 
-	if ((ret = ohci_init(ohci)) < 0)
+	ret = ohci_setup(hcd);
+	if (ret < 0)
 		return ret;
 
+	if (config->otg || config->rwc) {
+		ohci->hc_control = OHCI_CTRL_RWC;
+		writel(OHCI_CTRL_RWC, &ohci->regs->control);
+	}
+
 	/* board-specific power switching and overcurrent support */
 	if (machine_is_omap_osk() || machine_is_omap_innovator()) {
 		u32	rh = roothub_a (ohci);
@@ -281,14 +294,6 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	return 0;
 }
 
-static void ohci_omap_stop(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
-	ohci_stop(hcd);
-	omap_ohci_clock_power(0);
-}
-
-
 /*-------------------------------------------------------------------------*/
 
 /**
@@ -304,7 +309,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 {
 	int retval, irq;
 	struct usb_hcd *hcd = 0;
-	struct ohci_hcd *ohci;
 
 	if (pdev->num_resources != 2) {
 		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
@@ -354,12 +358,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 		goto err2;
 	}
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
-
-	host_initialized = 0;
-	host_enabled = 1;
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		retval = -ENXIO;
@@ -369,11 +367,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 	if (retval)
 		goto err3;
 
-	host_initialized = 1;
-
-	if (!host_enabled)
-		omap_ohci_clock_power(0);
-
 	return 0;
 err3:
 	iounmap(hcd->regs);
@@ -402,7 +395,9 @@ err0:
 static inline void
 usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
+	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
 	usb_remove_hcd(hcd);
+	omap_ohci_clock_power(0);
 	if (!IS_ERR_OR_NULL(hcd->phy)) {
 		(void) otg_set_host(hcd->phy->otg, 0);
 		usb_put_phy(hcd->phy);
@@ -418,76 +413,6 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_omap_start (struct usb_hcd *hcd)
-{
-	struct omap_usb_config *config;
-	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ret;
-
-	if (!host_enabled)
-		return 0;
-	config = dev_get_platdata(hcd->self.controller);
-	if (config->otg || config->rwc) {
-		ohci->hc_control = OHCI_CTRL_RWC;
-		writel(OHCI_CTRL_RWC, &ohci->regs->control);
-	}
-
-	if ((ret = ohci_run (ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop (hcd);
-		return ret;
-	}
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_omap_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap_init,
-	.start =		ohci_omap_start,
-	.stop =			ohci_omap_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static int ohci_hcd_omap_drv_probe(struct platform_device *dev)
 {
 	return usb_hcd_omap_probe(&ohci_omap_hc_driver, dev);
@@ -553,4 +478,29 @@ static struct platform_driver ohci_hcd_omap_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides omap_overrides __initconst = {
+	.product_desc	= "OMAP OHCI",
+	.reset		= ohci_omap_reset
+};
+
+static int __init ohci_omap_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap_hc_driver, &omap_overrides);
+	return platform_driver_register(&ohci_hcd_omap_driver);
+}
+module_init(ohci_omap_init);
+
+static void __exit ohci_omap_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap_driver);
+}
+module_exit(ohci_omap_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 3/9] USB: OHCI: make ohci-omap3 a separate driver
  2013-09-16 10:10 ` [PATCH V5 0/9] USB: " Manjunath Goudar
  2013-09-16 10:10   ` [PATCH V5 1/9] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
  2013-09-16 10:10   ` [PATCH V5 2/9] USB: OHCI: make ohci-omap " Manjunath Goudar
@ 2013-09-16 10:10   ` Manjunath Goudar
  2013-09-16 10:10   ` [PATCH V5 4/9] USB: OHCI: make ohci-spear " Manjunath Goudar
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-16 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP3 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Anand Gadiyar <gadiyar@ti.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V3->V4:
 -V3 modification revert back, only ohci->regs setting write()
  function has been removed because ohci->regs doesn't get set until
  usb_add_hcd.

V2->V3:
 -RemoteWakeupConnected setting has been removed.

V1->V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -The improper multi-line commenting style written in proper way.
  ('*' characters aligned in vertically).
---
 drivers/usb/host/Kconfig      |    2 +-
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 -------
 drivers/usb/host/ohci-omap3.c |  118 +++++++++++++----------------------------
 4 files changed, 40 insertions(+), 99 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 6aa2c3f..2a91a3f 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -375,7 +375,7 @@ config USB_OHCI_HCD_OMAP1
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
 config USB_OHCI_HCD_OMAP3
-	bool "OHCI support for OMAP3 and later chips"
+	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index cfbfe13..aa1721d 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index fcef838..5e9c334 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP3
-#include "ohci-omap3.c"
-#define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1284,12 +1279,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP3_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap3_platform;
-#endif
-
 #ifdef OF_PLATFORM_DRIVER
 	retval = platform_driver_register(&OF_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1393,10 +1382,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
  error_of_platform:
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
- error_omap3_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1448,9 +1433,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OF_PLATFORM_DRIVER
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index a09af26..408d06a 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -29,90 +29,22 @@
  *	- add kernel-doc
  */
 
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/of.h>
-#include <linux/dma-mapping.h>
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_init(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "starting OHCI controller\n");
-
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	/*
-	 * RemoteWakeupConnected has to be set explicitly before
-	 * calling ohci_run. The reset value of RWC is 0.
-	 */
-	ohci->hc_control = OHCI_CTRL_RWC;
-	writel(OHCI_CTRL_RWC, &ohci->regs->control);
-
-	ret = ohci_run(ohci);
-
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-	}
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
-	return ret;
-}
+#include "ohci.h"
 
-/*-------------------------------------------------------------------------*/
+#define DRIVER_DESC "OHCI OMAP3 driver"
 
-static const struct hc_driver ohci_omap3_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP3 OHCI Host Controller",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap3_init,
-	.start =		ohci_omap3_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
+static const char hcd_name[] = "ohci-omap3";
+static struct hc_driver __read_mostly ohci_omap3_hc_driver;
 
 /*
  * configure so an HC device and id are always provided
@@ -129,6 +61,7 @@ static const struct hc_driver ohci_omap3_hc_driver = {
 static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 {
 	struct device		*dev = &pdev->dev;
+	struct ohci_hcd		*ohci;
 	struct usb_hcd		*hcd = NULL;
 	void __iomem		*regs = NULL;
 	struct resource		*res;
@@ -185,7 +118,12 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	ohci = hcd_to_ohci(hcd);
+	/*
+	 * RemoteWakeupConnected has to be set explicitly before
+	 * calling ohci_run. The reset value of RWC is 0.
+	 */
+	ohci->hc_control = OHCI_CTRL_RWC;
 
 	ret = usb_add_hcd(hcd, irq, 0);
 	if (ret) {
@@ -248,5 +186,25 @@ static struct platform_driver ohci_hcd_omap3_driver = {
 	},
 };
 
+static int __init ohci_omap3_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap3_hc_driver, NULL);
+	return platform_driver_register(&ohci_hcd_omap3_driver);
+}
+module_init(ohci_omap3_init);
+
+static void __exit ohci_omap3_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap3_driver);
+}
+module_exit(ohci_omap3_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci-omap3");
 MODULE_AUTHOR("Anand Gadiyar <gadiyar@ti.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 4/9] USB: OHCI: make ohci-spear a separate driver
  2013-09-16 10:10 ` [PATCH V5 0/9] USB: " Manjunath Goudar
                     ` (2 preceding siblings ...)
  2013-09-16 10:10   ` [PATCH V5 3/9] USB: OHCI: make ohci-omap3 " Manjunath Goudar
@ 2013-09-16 10:10   ` Manjunath Goudar
  2013-09-16 10:10   ` [PATCH V5 5/9] USB: OHCI: make ohci-at91 " Manjunath Goudar
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-16 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the ST OHCI SPEAr host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2->V3:
 -No change.

V1->V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -debugging stuff isn't needed any more that's what removed.
---
 drivers/usb/host/Kconfig      |    8 +++
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 ------
 drivers/usb/host/ohci-spear.c |  140 +++++++++++++++++------------------------
 4 files changed, 65 insertions(+), 102 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 2a91a3f..00d22f5 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -374,6 +374,14 @@ config USB_OHCI_HCD_OMAP1
 	---help---
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
+config USB_OHCI_HCD_SPEAR
+        tristate "Support for ST SPEAr on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && PLAT_SPEAR
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          ST SPEAr chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index aa1721d..9efcb7c 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
+obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 5e9c334..523f58e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1212,11 +1212,6 @@ MODULE_LICENSE ("GPL");
 #define OF_PLATFORM_DRIVER	ohci_hcd_ppc_of_driver
 #endif
 
-#ifdef CONFIG_PLAT_SPEAR
-#include "ohci-spear.c"
-#define SPEAR_PLATFORM_DRIVER	spear_ohci_hcd_driver
-#endif
-
 #ifdef CONFIG_PPC_PS3
 #include "ohci-ps3.c"
 #define PS3_SYSTEM_BUS_DRIVER	ps3_ohci_driver
@@ -1333,19 +1328,9 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_davinci;
 #endif
 
-#ifdef SPEAR_PLATFORM_DRIVER
-	retval = platform_driver_register(&SPEAR_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_spear;
-#endif
-
 	return retval;
 
 	/* Error path */
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
- error_spear:
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
  error_davinci:
@@ -1403,9 +1388,6 @@ module_init(ohci_hcd_mod_init);
 
 static void __exit ohci_hcd_mod_exit(void)
 {
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index cc9dd9e..31ff3fc 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -11,92 +11,37 @@
 * warranty of any kind, whether express or implied.
 */
 
-#include <linux/signal.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
+#define DRIVER_DESC "OHCI SPEAr driver"
+
+static const char hcd_name[] = "SPEAr-ohci";
 struct spear_ohci {
-	struct ohci_hcd ohci;
 	struct clk *clk;
 };
 
-#define to_spear_ohci(hcd)	(struct spear_ohci *)hcd_to_ohci(hcd)
-
-static void spear_start_ohci(struct spear_ohci *ohci)
-{
-	clk_prepare_enable(ohci->clk);
-}
-
-static void spear_stop_ohci(struct spear_ohci *ohci)
-{
-	clk_disable_unprepare(ohci->clk);
-}
-
-static int ohci_spear_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-	ohci->regs = hcd->regs;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	create_debug_files(ohci);
-
-#ifdef DEBUG
-	ohci_dump(ohci, 1);
-#endif
-	return 0;
-}
-
-static const struct hc_driver ohci_spear_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "SPEAr OHCI",
-	.hcd_priv_size		= sizeof(struct spear_ohci),
-
-	/* generic hardware linkage */
-	.irq			= ohci_irq,
-	.flags			= HCD_USB11 | HCD_MEMORY,
-
-	/* basic lifecycle operations */
-	.start			= ohci_spear_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-
-	/* managing i/o requests and associated device resources */
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	/* scheduling support */
-	.get_frame_number	= ohci_get_frame,
+#define to_spear_ohci(hcd)     (struct spear_ohci *)(hcd_to_ohci(hcd)->priv)
 
-	/* root hub support */
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-
-	.start_port_reset	= ohci_start_port_reset,
-};
+static struct hc_driver __read_mostly ohci_spear_hc_driver;
 
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
 	const struct hc_driver *driver = &ohci_spear_hc_driver;
+	struct ohci_hcd *ohci;
 	struct usb_hcd *hcd = NULL;
 	struct clk *usbh_clk;
-	struct spear_ohci *ohci_p;
+	struct spear_ohci *sohci_p;
 	struct resource *res;
 	int retval, irq;
 
@@ -151,16 +96,18 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 		goto err_put_hcd;
 	}
 
-	ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
-	ohci_p->clk = usbh_clk;
-	spear_start_ohci(ohci_p);
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	sohci_p = to_spear_ohci(hcd);
+	sohci_p->clk = usbh_clk;
+
+	clk_prepare_enable(sohci_p->clk);
+
+	ohci = hcd_to_ohci(hcd);
 
 	retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0);
 	if (retval == 0)
 		return retval;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
 err_put_hcd:
 	usb_put_hcd(hcd);
 fail:
@@ -172,11 +119,11 @@ fail:
 static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	usb_remove_hcd(hcd);
-	if (ohci_p->clk)
-		spear_stop_ohci(ohci_p);
+	if (sohci_p->clk)
+		clk_disable_unprepare(sohci_p->clk);
 
 	usb_put_hcd(hcd);
 	return 0;
@@ -188,13 +135,14 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
+
 	return 0;
 }
 
@@ -202,13 +150,13 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_start_ohci(ohci_p);
+	clk_prepare_enable(sohci_p->clk);
 	ohci_resume(hcd, false);
 	return 0;
 }
@@ -234,4 +182,28 @@ static struct platform_driver spear_ohci_hcd_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides spear_overrides __initconst = {
+	.extra_priv_size = sizeof(struct spear_ohci),
+};
+static int __init ohci_spear_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_spear_hc_driver, &spear_overrides);
+	return platform_driver_register(&spear_ohci_hcd_driver);
+}
+module_init(ohci_spear_init);
+
+static void __exit ohci_spear_cleanup(void)
+{
+	platform_driver_unregister(&spear_ohci_hcd_driver);
+}
+module_exit(ohci_spear_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Deepak Sikri");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:spear-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 5/9] USB: OHCI: make ohci-at91 a separate driver
  2013-09-16 10:10 ` [PATCH V5 0/9] USB: " Manjunath Goudar
                     ` (3 preceding siblings ...)
  2013-09-16 10:10   ` [PATCH V5 4/9] USB: OHCI: make ohci-spear " Manjunath Goudar
@ 2013-09-16 10:10   ` Manjunath Goudar
  2013-09-16 10:10   ` [PATCH V5 6/9] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-16 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI Atmel host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V3->V4:
 - Removed extra space after "tristate".
 - Removed extra space between function name  and '(' characters.
 - MODULE_ALIAS line moved to last statement of ohci-at91 file.

V2->V3:
 -The ohci_restart() function is not required in  current scenario,
  only discarding connection state of integrated transceivers is sufficient,
  for this directly handling ohci->hc_control.

V1->V2:
 -Set non-standard fields in ohci_at91_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.
---
 drivers/usb/host/Kconfig     |    8 +++
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-at91.c |  156 +++++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c  |   18 -----
 4 files changed, 79 insertions(+), 104 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 00d22f5..6900b72 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -382,6 +382,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_AT91
+        tristate "Support for Atmel on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && ARCH_AT91
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          Atmel chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 9efcb7c..0d7a81a 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
+obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index caa3764..476b5a5 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -13,19 +13,24 @@
  */
 
 #include <linux/clk.h>
-#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/atmel.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
 #include <mach/hardware.h>
 #include <asm/gpio.h>
 
 #include <mach/cpu.h>
 
-#ifndef CONFIG_ARCH_AT91
-#error "CONFIG_ARCH_AT91 must be defined."
-#endif
+
+#include "ohci.h"
 
 #define valid_port(index)	((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
 #define at91_for_each_port(index)	\
@@ -33,7 +38,17 @@
 
 /* interface, function and usb clocks; sometimes also an AHB clock */
 static struct clk *iclk, *fclk, *uclk, *hclk;
+/* interface and function clocks; sometimes also an AHB clock */
+
+#define DRIVER_DESC "OHCI Atmel driver"
+
+static const char hcd_name[] = "ohci-atmel";
+
+static struct hc_driver __read_mostly ohci_at91_hc_driver;
 static int clocked;
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+			u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
 
 extern int usb_disabled(void);
 
@@ -117,6 +132,8 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
 static int usb_hcd_at91_probe(const struct hc_driver *driver,
 			struct platform_device *pdev)
 {
+	struct at91_usbh_data *board;
+	struct ohci_hcd *ohci;
 	int retval;
 	struct usb_hcd *hcd = NULL;
 
@@ -177,8 +194,10 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
 		}
 	}
 
+	board = hcd->self.controller->platform_data;
+	ohci = hcd_to_ohci(hcd);
+	ohci->num_ports = board->ports;
 	at91_start_hc(pdev);
-	ohci_hcd_init(hcd_to_ohci(hcd));
 
 	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
 	if (retval == 0)
@@ -238,36 +257,6 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd,
 }
 
 /*-------------------------------------------------------------------------*/
-
-static int
-ohci_at91_reset (struct usb_hcd *hcd)
-{
-	struct at91_usbh_data	*board = dev_get_platdata(hcd->self.controller);
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
-	ohci->num_ports = board->ports;
-	return 0;
-}
-
-static int
-ohci_at91_start (struct usb_hcd *hcd)
-{
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_run(ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-	return 0;
-}
-
 static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
 {
 	if (!valid_port(port))
@@ -297,8 +286,8 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
  */
 static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
-	struct at91_usbh_data *pdata = dev_get_platdata(hcd->self.controller);
-	int length = ohci_hub_status_data(hcd, buf);
+	struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
+	int length = orig_ohci_hub_status_data(hcd, buf);
 	int port;
 
 	at91_for_each_port(port) {
@@ -376,7 +365,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex + 1,
+				buf, wLength);
 	if (ret)
 		goto out;
 
@@ -430,51 +420,6 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 /*-------------------------------------------------------------------------*/
 
-static const struct hc_driver ohci_at91_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"AT91 OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_at91_reset,
-	.start =		ohci_at91_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_at91_hub_status_data,
-	.hub_control =		ohci_at91_hub_control,
-#ifdef CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
 {
 	struct platform_device *pdev = data;
@@ -703,7 +648,11 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
 	 * REVISIT: some boards will be able to turn VBUS off...
 	 */
 	if (at91_suspend_entering_slow_clock()) {
-		ohci_usb_reset (ohci);
+		ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
+		ohci->hc_control &= OHCI_CTRL_RWC;
+		ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
+		ohci->rh_state = OHCI_RH_HALTED;
+
 		/* flush the writes */
 		(void) ohci_readl (ohci, &ohci->regs->control);
 		at91_stop_clock();
@@ -730,8 +679,6 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
 #define ohci_hcd_at91_drv_resume  NULL
 #endif
 
-MODULE_ALIAS("platform:at91_ohci");
-
 static struct platform_driver ohci_hcd_at91_driver = {
 	.probe		= ohci_hcd_at91_drv_probe,
 	.remove		= ohci_hcd_at91_drv_remove,
@@ -744,3 +691,40 @@ static struct platform_driver ohci_hcd_at91_driver = {
 		.of_match_table	= of_match_ptr(at91_ohci_dt_ids),
 	},
 };
+
+static int __init ohci_at91_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_at91_hc_driver, NULL);
+
+	/*
+	 * The Atmel HW has some unusual quirks, which require Atmel-specific
+	 * workarounds. We override certain hc_driver functions here to
+	 * achieve that. We explicitly do not enhance ohci_driver_overrides to
+	 * allow this more easily, since this is an unusual case, and we don't
+	 * want to encourage others to override these functions by making it
+	 * too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_at91_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_at91_hc_driver.hub_status_data;
+
+	ohci_at91_hc_driver.hub_status_data	= ohci_at91_hub_status_data;
+	ohci_at91_hc_driver.hub_control		= ohci_at91_hub_control;
+
+	return platform_driver_register(&ohci_hcd_at91_driver);
+}
+module_init(ohci_at91_init);
+
+static void __exit ohci_at91_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_at91_driver);
+}
+module_exit(ohci_at91_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:at91_ohci");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 523f58e..2fdaaf8 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1192,11 +1192,6 @@ MODULE_LICENSE ("GPL");
 #define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver
 #endif
 
-#ifdef CONFIG_ARCH_AT91
-#include "ohci-at91.c"
-#define AT91_PLATFORM_DRIVER	ohci_hcd_at91_driver
-#endif
-
 #ifdef CONFIG_ARCH_LPC32XX
 #include "ohci-nxp.c"
 #define NXP_PLATFORM_DRIVER	usb_hcd_nxp_driver
@@ -1310,12 +1305,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_ep93xx;
 #endif
 
-#ifdef AT91_PLATFORM_DRIVER
-	retval = platform_driver_register(&AT91_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_at91;
-#endif
-
 #ifdef NXP_PLATFORM_DRIVER
 	retval = platform_driver_register(&NXP_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1339,10 +1328,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
  error_nxp:
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
- error_at91:
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
@@ -1394,9 +1379,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef NXP_PLATFORM_DRIVER
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 6/9] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-09-16 10:10 ` [PATCH V5 0/9] USB: " Manjunath Goudar
                     ` (4 preceding siblings ...)
  2013-09-16 10:10   ` [PATCH V5 5/9] USB: OHCI: make ohci-at91 " Manjunath Goudar
@ 2013-09-16 10:10   ` Manjunath Goudar
  2013-09-16 10:10   ` [PATCH V5 7/9] USB: OHCI: make ohci-nxp " Manjunath Goudar
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-16 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the Samsung OHCI S3C24xx/S3C64xx host controller driver
from ohci-hcd host code so that it can be built as a separate
driver module.This work is part of enabling multi-platform.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V4->V5:
 - String "s3cxxxx" is replaced by "s3c2410".

V3->V4:
 - Removed extra space before the '='.
 - Moved  /* forward definitions */ line before the declarations of functions.

V2->V3:
 -Kconfig wrong parentheses discription fixed.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

V1->V2:
 -Set non-standard fields in ohci_s3c2410_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.
---
 drivers/usb/host/Kconfig        |    8 +++
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ohci-hcd.c     |   18 ------
 drivers/usb/host/ohci-s3c2410.c |  128 +++++++++++++++++----------------------
 4 files changed, 66 insertions(+), 89 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 6900b72..1196a56 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -382,6 +382,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_S3C2410
+        tristate "OHCI support for Samsung S3C24xx/S3C64xx SoC series"
+        depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX)
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          S3C24xx/S3C64xx chips.
+
 config USB_OHCI_HCD_AT91
         tristate "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 0d7a81a..ddba422 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
+obj-$(CONFIG_USB_OHCI_HCD_S3C2410)	+= ohci-s3c2410.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 2fdaaf8..fcfcab5 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1177,11 +1177,6 @@ MODULE_LICENSE ("GPL");
 #define SA1111_DRIVER		ohci_hcd_sa1111_driver
 #endif
 
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
-#include "ohci-s3c2410.c"
-#define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1293,12 +1288,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_tmio;
 #endif
 
-#ifdef S3C2410_PLATFORM_DRIVER
-	retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_s3c2410;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1332,10 +1321,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
- error_s3c2410:
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
  error_tmio:
@@ -1382,9 +1367,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index 4919afa..be3429e 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -19,19 +19,36 @@
  * This file is licenced under the GPL.
 */
 
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
+
 
 #define valid_port(idx) ((idx) == 1 || (idx) == 2)
 
 /* clock device associated with the hcd */
 
+
+#define DRIVER_DESC "OHCI S3C2410 driver"
+
+static const char hcd_name[] = "ohci-s3c2410";
+
 static struct clk *clk;
 static struct clk *usb_clk;
 
 /* forward definitions */
 
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+			u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
+
 static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
 
 /* conversion functions */
@@ -93,7 +110,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd, char *buf)
 	int orig;
 	int portno;
 
-	orig  = ohci_hub_status_data(hcd, buf);
+	orig = orig_ohci_hub_status_data(hcd, buf);
 
 	if (info == NULL)
 		return orig;
@@ -164,7 +181,7 @@ static int ohci_s3c2410_hub_control(
 	 * process the request straight away and exit */
 
 	if (info == NULL) {
-		ret = ohci_hub_control(hcd, typeReq, wValue,
+		ret = orig_ohci_hub_control(hcd, typeReq, wValue,
 				       wIndex, buf, wLength);
 		goto out;
 	}
@@ -214,7 +231,7 @@ static int ohci_s3c2410_hub_control(
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
 	if (ret)
 		goto out;
 
@@ -374,8 +391,6 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 	s3c2410_start_hc(dev, hcd);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
-
 	retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
 	if (retval != 0)
 		goto err_ioremap;
@@ -392,71 +407,7 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_s3c2410_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-
-static const struct hc_driver ohci_s3c2410_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"S3C24XX OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.start =		ohci_s3c2410_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_s3c2410_hub_status_data,
-	.hub_control =		ohci_s3c2410_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/* device driver */
+static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;
 
 static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
 {
@@ -533,4 +484,39 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {
 	},
 };
 
+static int __init ohci_s3c2410_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
+
+	/*
+	 * The Samsung HW has some unusual quirks, which require
+	 * Sumsung-specific workarounds. We override certain hc_driver
+	 * functions here to achieve that. We explicitly do not enhance
+	 * ohci_driver_overrides to allow this more easily, since this
+	 * is an unusual case, and we don't want to encourage others to
+	 * override these functions by making it too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_s3c2410_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_s3c2410_hc_driver.hub_status_data;
+
+	ohci_s3c2410_hc_driver.hub_status_data	= ohci_s3c2410_hub_status_data;
+	ohci_s3c2410_hc_driver.hub_control	= ohci_s3c2410_hub_control;
+
+	return platform_driver_register(&ohci_hcd_s3c2410_driver);
+}
+module_init(ohci_s3c2410_init);
+
+static void __exit ohci_s3c2410_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_s3c2410_driver);
+}
+module_exit(ohci_s3c2410_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:s3c2410-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 7/9] USB: OHCI: make ohci-nxp a separate driver
  2013-09-16 10:10 ` [PATCH V5 0/9] USB: " Manjunath Goudar
                     ` (5 preceding siblings ...)
  2013-09-16 10:10   ` [PATCH V5 6/9] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
@ 2013-09-16 10:10   ` Manjunath Goudar
  2013-09-16 10:10   ` [PATCH V5 8/9] USB: OHCI: make ohci-ep93xx " Manjunath Goudar
  2013-09-16 10:10   ` [PATCH V5 9/9] USB: OHCI: make ohci-pxa27x " Manjunath Goudar
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-16 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the OHCI NXP host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Many place function name and struct name started with usb,
current scenario replaced usb with ohci for proper naming.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V1->V2:
  - Directive check NXP_PLATFORM_DRIVER block has been removed.
---
 drivers/usb/host/Kconfig    |    8 +++
 drivers/usb/host/Makefile   |    1 +
 drivers/usb/host/ohci-hcd.c |   18 -------
 drivers/usb/host/ohci-nxp.c |  123 +++++++++++++++++--------------------------
 4 files changed, 57 insertions(+), 93 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 1196a56..06c0cec 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -390,6 +390,14 @@ config USB_OHCI_HCD_S3C2410
           Enables support for the on-chip OHCI controller on
           S3C24xx/S3C64xx chips.
 
+config USB_OHCI_HCD_LPC32XX
+	tristate "Support for LPC on-chip OHCI USB controller"
+	depends on USB_OHCI_HCD && ARCH_LPC32XX
+	default y
+	---help---
+          Enables support for the on-chip OHCI controller on
+          NXP chips.
+
 config USB_OHCI_HCD_AT91
         tristate "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index ddba422..30a632c 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 obj-$(CONFIG_USB_OHCI_HCD_S3C2410)	+= ohci-s3c2410.o
+obj-$(CONFIG_USB_OHCI_HCD_LPC32XX)	+= ohci-nxp.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index fcfcab5..c515192 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1187,11 +1187,6 @@ MODULE_LICENSE ("GPL");
 #define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver
 #endif
 
-#ifdef CONFIG_ARCH_LPC32XX
-#include "ohci-nxp.c"
-#define NXP_PLATFORM_DRIVER	usb_hcd_nxp_driver
-#endif
-
 #ifdef CONFIG_ARCH_DAVINCI_DA8XX
 #include "ohci-da8xx.c"
 #define DAVINCI_PLATFORM_DRIVER	ohci_hcd_da8xx_driver
@@ -1294,12 +1289,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_ep93xx;
 #endif
 
-#ifdef NXP_PLATFORM_DRIVER
-	retval = platform_driver_register(&NXP_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_nxp;
-#endif
-
 #ifdef DAVINCI_PLATFORM_DRIVER
 	retval = platform_driver_register(&DAVINCI_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1313,10 +1302,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
  error_davinci:
 #endif
-#ifdef NXP_PLATFORM_DRIVER
-	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
- error_nxp:
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
@@ -1361,9 +1346,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
 #endif
-#ifdef NXP_PLATFORM_DRIVER
-	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c
index 7d7d507..9ab7e24 100644
--- a/drivers/usb/host/ohci-nxp.c
+++ b/drivers/usb/host/ohci-nxp.c
@@ -19,10 +19,19 @@
  * or implied.
  */
 #include <linux/clk.h>
-#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
 #include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
 #include <linux/usb/isp1301.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
+
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -57,6 +66,11 @@
 #define start_int_umask(irq)
 #endif
 
+#define DRIVER_DESC "OHCI NXP driver"
+
+static const char hcd_name[] = "ohci-nxp";
+static struct hc_driver __read_mostly ohci_nxp_hc_driver;
+
 static struct i2c_client *isp1301_i2c_client;
 
 extern int usb_disabled(void);
@@ -132,14 +146,14 @@ static inline void isp1301_vbus_off(void)
 		OTG1_VBUS_DRV);
 }
 
-static void nxp_start_hc(void)
+static void ohci_nxp_start_hc(void)
 {
 	unsigned long tmp = __raw_readl(USB_OTG_STAT_CONTROL) | HOST_EN;
 	__raw_writel(tmp, USB_OTG_STAT_CONTROL);
 	isp1301_vbus_on();
 }
 
-static void nxp_stop_hc(void)
+static void ohci_nxp_stop_hc(void)
 {
 	unsigned long tmp;
 	isp1301_vbus_off();
@@ -147,68 +161,9 @@ static void nxp_stop_hc(void)
 	__raw_writel(tmp, USB_OTG_STAT_CONTROL);
 }
 
-static int ohci_nxp_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
-	if ((ret = ohci_run(ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-		return ret;
-	}
-	return 0;
-}
-
-static const struct hc_driver ohci_nxp_hc_driver = {
-	.description = hcd_name,
-	.product_desc =		"nxp OHCI",
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq = ohci_irq,
-	.flags = HCD_USB11 | HCD_MEMORY,
-
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-	/*
-	 * basic lifecycle operations
-	 */
-	.start = ohci_nxp_start,
-	.stop = ohci_stop,
-	.shutdown = ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue = ohci_urb_enqueue,
-	.urb_dequeue = ohci_urb_dequeue,
-	.endpoint_disable = ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number = ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data = ohci_hub_status_data,
-	.hub_control = ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend = ohci_bus_suspend,
-	.bus_resume = ohci_bus_resume,
-#endif
-	.start_port_reset = ohci_start_port_reset,
-};
-
-static int usb_hcd_nxp_probe(struct platform_device *pdev)
+static int ohci_hcd_nxp_probe(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = 0;
-	struct ohci_hcd *ohci;
 	const struct hc_driver *driver = &ohci_nxp_hc_driver;
 	struct resource *res;
 	int ret = 0, irq;
@@ -313,17 +268,15 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
 		goto fail_resource;
 	}
 
-	nxp_start_hc();
+	ohci_nxp_start_hc();
 	platform_set_drvdata(pdev, hcd);
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
 
 	dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);
 	ret = usb_add_hcd(hcd, irq, 0);
 	if (ret == 0)
 		return ret;
 
-	nxp_stop_hc();
+	ohci_nxp_stop_hc();
 fail_resource:
 	usb_put_hcd(hcd);
 fail_hcd:
@@ -345,12 +298,12 @@ fail_disable:
 	return ret;
 }
 
-static int usb_hcd_nxp_remove(struct platform_device *pdev)
+static int ohci_hcd_nxp_remove(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
 	usb_remove_hcd(hcd);
-	nxp_stop_hc();
+	ohci_nxp_stop_hc();
 	usb_put_hcd(hcd);
 	clk_disable(usb_pll_clk);
 	clk_put(usb_pll_clk);
@@ -366,20 +319,40 @@ static int usb_hcd_nxp_remove(struct platform_device *pdev)
 MODULE_ALIAS("platform:usb-ohci");
 
 #ifdef CONFIG_OF
-static const struct of_device_id usb_hcd_nxp_match[] = {
+static const struct of_device_id ohci_hcd_nxp_match[] = {
 	{ .compatible = "nxp,ohci-nxp" },
 	{},
 };
-MODULE_DEVICE_TABLE(of, usb_hcd_nxp_match);
+MODULE_DEVICE_TABLE(of, ohci_hcd_nxp_match);
 #endif
 
-static struct platform_driver usb_hcd_nxp_driver = {
+static struct platform_driver ohci_hcd_nxp_driver = {
 	.driver = {
 		.name = "usb-ohci",
 		.owner	= THIS_MODULE,
-		.of_match_table = of_match_ptr(usb_hcd_nxp_match),
+		.of_match_table = of_match_ptr(ohci_hcd_nxp_match),
 	},
-	.probe = usb_hcd_nxp_probe,
-	.remove = usb_hcd_nxp_remove,
+	.probe = ohci_hcd_nxp_probe,
+	.remove = ohci_hcd_nxp_remove,
 };
 
+static int __init ohci_nxp_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_nxp_hc_driver, NULL);
+	return platform_driver_register(&ohci_hcd_nxp_driver);
+}
+module_init(ohci_nxp_init);
+
+static void __exit ohci_nxp_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_nxp_driver);
+}
+module_exit(ohci_nxp_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 8/9] USB: OHCI: make ohci-ep93xx a separate driver
  2013-09-16 10:10 ` [PATCH V5 0/9] USB: " Manjunath Goudar
                     ` (6 preceding siblings ...)
  2013-09-16 10:10   ` [PATCH V5 7/9] USB: OHCI: make ohci-nxp " Manjunath Goudar
@ 2013-09-16 10:10   ` Manjunath Goudar
  2013-09-16 10:10   ` [PATCH V5 9/9] USB: OHCI: make ohci-pxa27x " Manjunath Goudar
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-16 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the OHCI EP93XX host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2->V3:
 -Unused *ohci variable has been removed.

V1->V2:
 -ohci_hcd_init() statements are removed,
  because by default it is called in ohci_setup().
---
 drivers/usb/host/Kconfig       |    8 +++++
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ohci-ep93xx.c |   72 +++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c    |   18 ----------
 4 files changed, 40 insertions(+), 59 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 06c0cec..8e31c98 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -398,6 +398,14 @@ config USB_OHCI_HCD_LPC32XX
           Enables support for the on-chip OHCI controller on
           NXP chips.
 
+config USB_OHCI_HCD_EP93XX
+	tristate "Support for EP93XX on-chip OHCI USB controller"
+	depends on USB_OHCI_HCD && ARCH_EP93XX
+	default y
+	---help---
+	  Enables support for the on-chip OHCI controller on
+	  EP93XX chips.
+
 config USB_OHCI_HCD_AT91
         tristate "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 30a632c..02f9cd2 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 obj-$(CONFIG_USB_OHCI_HCD_S3C2410)	+= ohci-s3c2410.o
 obj-$(CONFIG_USB_OHCI_HCD_LPC32XX)	+= ohci-nxp.o
+obj-$(CONFIG_USB_OHCI_HCD_EP93XX)	+= ohci-ep93xx.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
index 84a20d5..492f681 100644
--- a/drivers/usb/host/ohci-ep93xx.c
+++ b/drivers/usb/host/ohci-ep93xx.c
@@ -25,50 +25,23 @@
 
 #include <linux/clk.h>
 #include <linux/device.h>
-#include <linux/signal.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
-static struct clk *usb_host_clock;
+#include "ohci.h"
 
-static int ohci_ep93xx_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
+#define DRIVER_DESC "OHCI EP93xx driver"
 
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
+static const char hcd_name[] = "ohci-ep93xx";
 
-	if ((ret = ohci_run(ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
+static struct hc_driver __read_mostly ohci_ep93xx_hc_driver;
 
-	return 0;
-}
-
-static struct hc_driver ohci_ep93xx_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "EP93xx OHCI",
-	.hcd_priv_size		= sizeof(struct ohci_hcd),
-	.irq			= ohci_irq,
-	.flags			= HCD_USB11 | HCD_MEMORY,
-	.start			= ohci_ep93xx_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-	.get_frame_number	= ohci_get_frame,
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-#ifdef CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-	.start_port_reset	= ohci_start_port_reset,
-};
+static struct clk *usb_host_clock;
 
 static int ohci_hcd_ep93xx_drv_probe(struct platform_device *pdev)
 {
@@ -109,8 +82,6 @@ static int ohci_hcd_ep93xx_drv_probe(struct platform_device *pdev)
 
 	clk_enable(usb_host_clock);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
-
 	ret = usb_add_hcd(hcd, irq, 0);
 	if (ret)
 		goto err_clk_disable;
@@ -166,7 +137,6 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev)
 }
 #endif
 
-
 static struct platform_driver ohci_hcd_ep93xx_driver = {
 	.probe		= ohci_hcd_ep93xx_drv_probe,
 	.remove		= ohci_hcd_ep93xx_drv_remove,
@@ -181,4 +151,24 @@ static struct platform_driver ohci_hcd_ep93xx_driver = {
 	},
 };
 
+static int __init ohci_ep93xx_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_ep93xx_hc_driver, NULL);
+	return platform_driver_register(&ohci_hcd_ep93xx_driver);
+}
+module_init(ohci_ep93xx_init);
+
+static void __exit ohci_ep93xx_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_ep93xx_driver);
+}
+module_exit(ohci_ep93xx_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:ep93xx-ohci");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index c515192..2ee3171 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
 #endif
 
-#ifdef CONFIG_ARCH_EP93XX
-#include "ohci-ep93xx.c"
-#define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver
-#endif
-
 #ifdef CONFIG_ARCH_DAVINCI_DA8XX
 #include "ohci-da8xx.c"
 #define DAVINCI_PLATFORM_DRIVER	ohci_hcd_da8xx_driver
@@ -1283,12 +1278,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_tmio;
 #endif
 
-#ifdef EP93XX_PLATFORM_DRIVER
-	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_ep93xx;
-#endif
-
 #ifdef DAVINCI_PLATFORM_DRIVER
 	retval = platform_driver_register(&DAVINCI_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1302,10 +1291,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
  error_davinci:
 #endif
-#ifdef EP93XX_PLATFORM_DRIVER
-	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
- error_ep93xx:
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
  error_tmio:
@@ -1346,9 +1331,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
 #endif
-#ifdef EP93XX_PLATFORM_DRIVER
-	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 9/9] USB: OHCI: make ohci-pxa27x a separate driver
  2013-09-16 10:10 ` [PATCH V5 0/9] USB: " Manjunath Goudar
                     ` (7 preceding siblings ...)
  2013-09-16 10:10   ` [PATCH V5 8/9] USB: OHCI: make ohci-ep93xx " Manjunath Goudar
@ 2013-09-16 10:10   ` Manjunath Goudar
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-16 10:10 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  OHCI pxa27x/pxa3xx host controller driver from
ohci-hcd host code so that it can be built as a separate driver
module. This work is part of enabling multi-platform kernels on
ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2->V3:
 -Rewrite the macro definition of to_pxa27x_ohci.
 -clk_put() function has been called before usb_put_hcd().

V1->V2:
 -Changed ohci_hcd and pxa27x_ohci struct variable names.
    1 ohci_hcd struct variable name is ohci.
    2 pxa27x_ohci struct variable name is pxa_ohci.
---
 drivers/usb/host/Kconfig       |    8 ++
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ohci-hcd.c    |    5 -
 drivers/usb/host/ohci-pxa27x.c |  240 +++++++++++++++++-----------------------
 4 files changed, 113 insertions(+), 141 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 8e31c98..8ea1afc 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -406,6 +406,14 @@ config USB_OHCI_HCD_EP93XX
 	  Enables support for the on-chip OHCI controller on
 	  EP93XX chips.
 
+config USB_OHCI_HCD_PXA27X
+	tristate "Support for PXA27X/PXA3XX on-chip OHCI USB controller"
+	depends on USB_OHCI_HCD && (PXA27x || PXA3xx)
+	default y
+	---help---
+	  Enables support for the on-chip OHCI controller on
+	  PXA27x/PXA3xx chips.
+
 config USB_OHCI_HCD_AT91
         tristate "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 02f9cd2..8fcb8da 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 obj-$(CONFIG_USB_OHCI_HCD_S3C2410)	+= ohci-s3c2410.o
 obj-$(CONFIG_USB_OHCI_HCD_LPC32XX)	+= ohci-nxp.o
 obj-$(CONFIG_USB_OHCI_HCD_EP93XX)	+= ohci-ep93xx.o
+obj-$(CONFIG_USB_OHCI_HCD_PXA27X)	+= ohci-pxa27x.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 2ee3171..c6fff6e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1177,11 +1177,6 @@ MODULE_LICENSE ("GPL");
 #define SA1111_DRIVER		ohci_hcd_sa1111_driver
 #endif
 
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-#include "ohci-pxa27x.c"
-#define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
-#endif
-
 #ifdef CONFIG_ARCH_DAVINCI_DA8XX
 #include "ohci-da8xx.c"
 #define DAVINCI_PLATFORM_DRIVER	ohci_hcd_da8xx_driver
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 93371a2..c1b1fa3 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -19,15 +19,26 @@
  * This file is licenced under the GPL.
  */
 
-#include <linux/device.h>
-#include <linux/signal.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
-#include <mach/hardware.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 #include <linux/platform_data/usb-pxa3xx-ulpi.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include <mach/hardware.h>
+
+#include "ohci.h"
+
+#define DRIVER_DESC "OHCI PXA27x/PXA3x driver"
 
 /*
  * UHC: USB Host Controller (OHCI-like) register definitions
@@ -101,16 +112,16 @@
 
 #define PXA_UHC_MAX_PORTNUM    3
 
-struct pxa27x_ohci {
-	/* must be 1st member here for hcd_to_ohci() to work */
-	struct ohci_hcd ohci;
+static const char hcd_name[] = "ohci-pxa27x";
 
-	struct device	*dev;
+static struct hc_driver __read_mostly ohci_pxa27x_hc_driver;
+
+struct pxa27x_ohci {
 	struct clk	*clk;
 	void __iomem	*mmio_base;
 };
 
-#define to_pxa27x_ohci(hcd)	(struct pxa27x_ohci *)hcd_to_ohci(hcd)
+#define to_pxa27x_ohci(hcd)	(struct pxa27x_ohci *)(hcd_to_ohci(hcd)->priv)
 
 /*
   PMM_NPS_MODE -- PMM Non-power switching mode
@@ -122,10 +133,10 @@ struct pxa27x_ohci {
   PMM_PERPORT_MODE -- PMM per port switching mode
       Ports are powered individually.
  */
-static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *ohci, int mode)
+static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *pxa_ohci, int mode)
 {
-	uint32_t uhcrhda = __raw_readl(ohci->mmio_base + UHCRHDA);
-	uint32_t uhcrhdb = __raw_readl(ohci->mmio_base + UHCRHDB);
+	uint32_t uhcrhda = __raw_readl(pxa_ohci->mmio_base + UHCRHDA);
+	uint32_t uhcrhdb = __raw_readl(pxa_ohci->mmio_base + UHCRHDB);
 
 	switch (mode) {
 	case PMM_NPS_MODE:
@@ -149,20 +160,18 @@ static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *ohci, int mode)
 		uhcrhda |= RH_A_NPS;
 	}
 
-	__raw_writel(uhcrhda, ohci->mmio_base + UHCRHDA);
-	__raw_writel(uhcrhdb, ohci->mmio_base + UHCRHDB);
+	__raw_writel(uhcrhda, pxa_ohci->mmio_base + UHCRHDA);
+	__raw_writel(uhcrhdb, pxa_ohci->mmio_base + UHCRHDB);
 	return 0;
 }
 
-extern int usb_disabled(void);
-
 /*-------------------------------------------------------------------------*/
 
-static inline void pxa27x_setup_hc(struct pxa27x_ohci *ohci,
+static inline void pxa27x_setup_hc(struct pxa27x_ohci *pxa_ohci,
 				   struct pxaohci_platform_data *inf)
 {
-	uint32_t uhchr = __raw_readl(ohci->mmio_base + UHCHR);
-	uint32_t uhcrhda = __raw_readl(ohci->mmio_base + UHCRHDA);
+	uint32_t uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR);
+	uint32_t uhcrhda = __raw_readl(pxa_ohci->mmio_base + UHCRHDA);
 
 	if (inf->flags & ENABLE_PORT1)
 		uhchr &= ~UHCHR_SSEP1;
@@ -194,17 +203,17 @@ static inline void pxa27x_setup_hc(struct pxa27x_ohci *ohci,
 		uhcrhda |= UHCRHDA_POTPGT(inf->power_on_delay / 2);
 	}
 
-	__raw_writel(uhchr, ohci->mmio_base + UHCHR);
-	__raw_writel(uhcrhda, ohci->mmio_base + UHCRHDA);
+	__raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR);
+	__raw_writel(uhcrhda, pxa_ohci->mmio_base + UHCRHDA);
 }
 
-static inline void pxa27x_reset_hc(struct pxa27x_ohci *ohci)
+static inline void pxa27x_reset_hc(struct pxa27x_ohci *pxa_ohci)
 {
-	uint32_t uhchr = __raw_readl(ohci->mmio_base + UHCHR);
+	uint32_t uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR);
 
-	__raw_writel(uhchr | UHCHR_FHR, ohci->mmio_base + UHCHR);
+	__raw_writel(uhchr | UHCHR_FHR, pxa_ohci->mmio_base + UHCHR);
 	udelay(11);
-	__raw_writel(uhchr & ~UHCHR_FHR, ohci->mmio_base + UHCHR);
+	__raw_writel(uhchr & ~UHCHR_FHR, pxa_ohci->mmio_base + UHCHR);
 }
 
 #ifdef CONFIG_PXA27x
@@ -213,25 +222,26 @@ extern void pxa27x_clear_otgph(void);
 #define pxa27x_clear_otgph()	do {} while (0)
 #endif
 
-static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev)
+static int pxa27x_start_hc(struct pxa27x_ohci *pxa_ohci, struct device *dev)
 {
 	int retval = 0;
 	struct pxaohci_platform_data *inf;
 	uint32_t uhchr;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
 
 	inf = dev_get_platdata(dev);
 
-	clk_prepare_enable(ohci->clk);
+	clk_prepare_enable(pxa_ohci->clk);
 
-	pxa27x_reset_hc(ohci);
+	pxa27x_reset_hc(pxa_ohci);
 
-	uhchr = __raw_readl(ohci->mmio_base + UHCHR) | UHCHR_FSBIR;
-	__raw_writel(uhchr, ohci->mmio_base + UHCHR);
+	uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR) | UHCHR_FSBIR;
+	__raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR);
 
-	while (__raw_readl(ohci->mmio_base + UHCHR) & UHCHR_FSBIR)
+	while (__raw_readl(pxa_ohci->mmio_base + UHCHR) & UHCHR_FSBIR)
 		cpu_relax();
 
-	pxa27x_setup_hc(ohci, inf);
+	pxa27x_setup_hc(pxa_ohci, inf);
 
 	if (inf->init)
 		retval = inf->init(dev);
@@ -240,38 +250,39 @@ static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev)
 		return retval;
 
 	if (cpu_is_pxa3xx())
-		pxa3xx_u2d_start_hc(&ohci_to_hcd(&ohci->ohci)->self);
+		pxa3xx_u2d_start_hc(&hcd->self);
 
-	uhchr = __raw_readl(ohci->mmio_base + UHCHR) & ~UHCHR_SSE;
-	__raw_writel(uhchr, ohci->mmio_base + UHCHR);
-	__raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, ohci->mmio_base + UHCHIE);
+	uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR) & ~UHCHR_SSE;
+	__raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR);
+	__raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, pxa_ohci->mmio_base + UHCHIE);
 
 	/* Clear any OTG Pin Hold */
 	pxa27x_clear_otgph();
 	return 0;
 }
 
-static void pxa27x_stop_hc(struct pxa27x_ohci *ohci, struct device *dev)
+static void pxa27x_stop_hc(struct pxa27x_ohci *pxa_ohci, struct device *dev)
 {
 	struct pxaohci_platform_data *inf;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
 	uint32_t uhccoms;
 
 	inf = dev_get_platdata(dev);
 
 	if (cpu_is_pxa3xx())
-		pxa3xx_u2d_stop_hc(&ohci_to_hcd(&ohci->ohci)->self);
+		pxa3xx_u2d_stop_hc(&hcd->self);
 
 	if (inf->exit)
 		inf->exit(dev);
 
-	pxa27x_reset_hc(ohci);
+	pxa27x_reset_hc(pxa_ohci);
 
 	/* Host Controller Reset */
-	uhccoms = __raw_readl(ohci->mmio_base + UHCCOMS) | 0x01;
-	__raw_writel(uhccoms, ohci->mmio_base + UHCCOMS);
+	uhccoms = __raw_readl(pxa_ohci->mmio_base + UHCCOMS) | 0x01;
+	__raw_writel(uhccoms, pxa_ohci->mmio_base + UHCCOMS);
 	udelay(10);
 
-	clk_disable_unprepare(ohci->clk);
+	clk_disable_unprepare(pxa_ohci->clk);
 }
 
 #ifdef CONFIG_OF
@@ -356,7 +367,8 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
 	int retval, irq;
 	struct usb_hcd *hcd;
 	struct pxaohci_platform_data *inf;
-	struct pxa27x_ohci *ohci;
+	struct pxa27x_ohci *pxa_ohci;
+	struct ohci_hcd *ohci;
 	struct resource *r;
 	struct clk *usb_clk;
 
@@ -409,29 +421,31 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
 	}
 
 	/* initialize "struct pxa27x_ohci" */
-	ohci = (struct pxa27x_ohci *)hcd_to_ohci(hcd);
-	ohci->dev = &pdev->dev;
-	ohci->clk = usb_clk;
-	ohci->mmio_base = (void __iomem *)hcd->regs;
+	pxa_ohci = to_pxa27x_ohci(hcd);
+	pxa_ohci->clk = usb_clk;
+	pxa_ohci->mmio_base = (void __iomem *)hcd->regs;
 
-	if ((retval = pxa27x_start_hc(ohci, &pdev->dev)) < 0) {
+	retval = pxa27x_start_hc(pxa_ohci, &pdev->dev);
+	if (retval < 0) {
 		pr_debug("pxa27x_start_hc failed");
 		goto err3;
 	}
 
 	/* Select Power Management Mode */
-	pxa27x_ohci_select_pmm(ohci, inf->port_mode);
+	pxa27x_ohci_select_pmm(pxa_ohci, inf->port_mode);
 
 	if (inf->power_budget)
 		hcd->power_budget = inf->power_budget;
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	/* The value of NDP in roothub_a is incorrect on this hardware */
+	ohci = hcd_to_ohci(hcd);
+	ohci->num_ports = 3;
 
 	retval = usb_add_hcd(hcd, irq, 0);
 	if (retval == 0)
 		return retval;
 
-	pxa27x_stop_hc(ohci, &pdev->dev);
+	pxa27x_stop_hc(pxa_ohci, &pdev->dev);
  err3:
 	iounmap(hcd->regs);
  err2:
@@ -459,88 +473,18 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
  */
 void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
-	struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
+	struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd);
 
 	usb_remove_hcd(hcd);
-	pxa27x_stop_hc(ohci, &pdev->dev);
+	pxa27x_stop_hc(pxa_ohci, &pdev->dev);
 	iounmap(hcd->regs);
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	clk_put(pxa_ohci->clk);
 	usb_put_hcd(hcd);
-	clk_put(ohci->clk);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int
-ohci_pxa27x_start (struct usb_hcd *hcd)
-{
-	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ret;
-
-	ohci_dbg (ohci, "ohci_pxa27x_start, ohci:%p", ohci);
-
-	/* The value of NDP in roothub_a is incorrect on this hardware */
-	ohci->num_ports = 3;
-
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
-	if ((ret = ohci_run (ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start %s",
-			hcd->self.bus_name);
-		ohci_stop (hcd);
-		return ret;
-	}
-
-	return 0;
 }
 
 /*-------------------------------------------------------------------------*/
 
-static const struct hc_driver ohci_pxa27x_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"PXA27x OHCI",
-	.hcd_priv_size =	sizeof(struct pxa27x_ohci),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.start =		ohci_pxa27x_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef  CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev)
 {
 	pr_debug ("In ohci_hcd_pxa27x_drv_probe");
@@ -563,32 +507,35 @@ static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev)
 static int ohci_hcd_pxa27x_drv_suspend(struct device *dev)
 {
 	struct usb_hcd *hcd = dev_get_drvdata(dev);
-	struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
+	struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd);
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
 
-	if (time_before(jiffies, ohci->ohci.next_statechange))
+	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
-	ohci->ohci.next_statechange = jiffies;
+	ohci->next_statechange = jiffies;
 
-	pxa27x_stop_hc(ohci, dev);
+	pxa27x_stop_hc(pxa_ohci, dev);
 	return 0;
 }
 
 static int ohci_hcd_pxa27x_drv_resume(struct device *dev)
 {
 	struct usb_hcd *hcd = dev_get_drvdata(dev);
-	struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
+	struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd);
 	struct pxaohci_platform_data *inf = dev_get_platdata(dev);
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
 	int status;
 
-	if (time_before(jiffies, ohci->ohci.next_statechange))
+	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
-	ohci->ohci.next_statechange = jiffies;
+	ohci->next_statechange = jiffies;
 
-	if ((status = pxa27x_start_hc(ohci, dev)) < 0)
+	status = pxa27x_start_hc(pxa_ohci, dev);
+	if (status < 0)
 		return status;
 
 	/* Select Power Management Mode */
-	pxa27x_ohci_select_pmm(ohci, inf->port_mode);
+	pxa27x_ohci_select_pmm(pxa_ohci, inf->port_mode);
 
 	ohci_resume(hcd, false);
 	return 0;
@@ -600,9 +547,6 @@ static const struct dev_pm_ops ohci_hcd_pxa27x_pm_ops = {
 };
 #endif
 
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:pxa27x-ohci");
-
 static struct platform_driver ohci_hcd_pxa27x_driver = {
 	.probe		= ohci_hcd_pxa27x_drv_probe,
 	.remove		= ohci_hcd_pxa27x_drv_remove,
@@ -617,3 +561,27 @@ static struct platform_driver ohci_hcd_pxa27x_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides pxa27x_overrides __initconst = {
+	.extra_priv_size =      sizeof(struct pxa27x_ohci),
+};
+
+static int __init ohci_pxa27x_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_pxa27x_hc_driver, &pxa27x_overrides);
+	return platform_driver_register(&ohci_hcd_pxa27x_driver);
+}
+module_init(ohci_pxa27x_init);
+
+static void __exit ohci_pxa27x_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_pxa27x_driver);
+}
+module_exit(ohci_pxa27x_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pxa27x-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 0/9]  USB: OHCI: more bus glues as separate modules
  2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                   ` (13 preceding siblings ...)
  2013-09-16 10:10 ` [PATCH V5 0/9] USB: " Manjunath Goudar
@ 2013-09-21 11:08 ` Manjunath Goudar
  2013-09-21 11:08   ` [PATCH V5 1/9] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
                     ` (8 more replies)
  14 siblings, 9 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-21 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

These patches are for separating the SOC On-Chip ohci host controller
from ohci-hcd host code and making per SOC driver module similar to EHCI 
module available in the kernel. This work is part of enabling multi-platform 
kernel on ARM.
 
Before I was sending three different ohci patch set as below.
 1. Six series patch set is having exynos, omap, omap3, spear, at91 and s3c2410.
 2. ohci-nxp a separate driver patch.
 3. Two series patch set is having ep93xx and pxa27x.
In this patch set all three previous ohci series have been combined into single 
series as all these patches are related to OHCI.

This patch series is rebased on greghk/usb-next 3.12 rc1. 

Manjunath Goudar (9):
  USB: OHCI: make ohci-exynos a separate driver
  USB: OHCI: make ohci-omap a separate driver
  USB: OHCI: make ohci-omap3 a separate driver
  USB: OHCI: make ohci-spear a separate driver
  USB: OHCI: make ohci-at91 a separate driver
  USB: OHCI: make ohci-s3c2410 a separate driver
  USB: OHCI: make ohci-nxp a separate driver
  USB: OHCI: make ohci-ep93xx a separate driver
  USB: OHCI: make ohci-pxa27x a separate driver

 drivers/usb/host/Kconfig        |   56 ++++++++-
 drivers/usb/host/Makefile       |    9 ++
 drivers/usb/host/ohci-at91.c    |  156 ++++++++++++-------------
 drivers/usb/host/ohci-ep93xx.c  |   72 +++++-------
 drivers/usb/host/ohci-exynos.c  |  167 +++++++++++----------------
 drivers/usb/host/ohci-hcd.c     |  149 ------------------------
 drivers/usb/host/ohci-nxp.c     |  123 ++++++++------------
 drivers/usb/host/ohci-omap.c    |  156 +++++++++----------------
 drivers/usb/host/ohci-omap3.c   |  118 +++++++------------
 drivers/usb/host/ohci-pxa27x.c  |  240 +++++++++++++++++----------------------
 drivers/usb/host/ohci-s3c2410.c |  128 ++++++++++-----------
 drivers/usb/host/ohci-spear.c   |  140 +++++++++--------------
 12 files changed, 587 insertions(+), 927 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V5 1/9] USB: OHCI: make ohci-exynos a separate driver
  2013-09-21 11:08 ` [PATCH V5 0/9] USB: OHCI: more bus glues as separate modules Manjunath Goudar
@ 2013-09-21 11:08   ` Manjunath Goudar
  2013-09-26 16:50     ` Greg KH
  2013-09-21 11:08   ` [PATCH V5 2/9] USB: OHCI: make ohci-omap " Manjunath Goudar
                     ` (7 subsequent siblings)
  8 siblings, 1 reply; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-21 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  Samsung OHCI EXYNOS host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Cc: Vivek Gautam <gautam.vivek@samsung.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2->V3:
 -No major changes only "exynos" written in capital letters
  in "OHCI exynos driver".

V1->V2:
 -exynos_ohci_hcd structure assignment error fixed.
 -Removed multiple usb_create_hcd() from prob funtion.
 -platform_set_drvdata() called before exynos_ohci_phy_enable().
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure
---
 drivers/usb/host/Kconfig       |    4 +-
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ohci-exynos.c |  167 +++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c    |   18 -----
 4 files changed, 72 insertions(+), 118 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 5be0326..e8bd542 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -455,8 +455,8 @@ config USB_OHCI_SH
 	  If you use the PCI OHCI controller, this option is not necessary.
 
 config USB_OHCI_EXYNOS
-	boolean "OHCI support for Samsung EXYNOS SoC Series"
-	depends on ARCH_EXYNOS
+	tristate "OHCI support for Samsung S5P/EXYNOS SoC Series"
+	depends on PLAT_S5P || ARCH_EXYNOS
 	help
 	 Enable support for the Samsung Exynos SOC's on-chip OHCI controller.
 
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 50b0041..73cc986 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
+obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index dc6ee9a..3e4bc74 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -12,24 +12,39 @@
  */
 
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-exynos.h>
 #include <linux/usb/phy.h>
 #include <linux/usb/samsung_usb_phy.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include "ohci.h"
+
+#define DRIVER_DESC "OHCI EXYNOS driver"
+
+static const char hcd_name[] = "ohci-exynos";
+static struct hc_driver __read_mostly exynos_ohci_hc_driver;
+
+#define to_exynos_ohci(hcd) (struct exynos_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
 
 struct exynos_ohci_hcd {
-	struct device *dev;
-	struct usb_hcd *hcd;
 	struct clk *clk;
 	struct usb_phy *phy;
 	struct usb_otg *otg;
 	struct exynos4_ohci_platdata *pdata;
 };
 
-static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_enable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_init(exynos_ohci->phy);
@@ -37,9 +52,10 @@ static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
 }
 
-static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
+static void exynos_ohci_phy_disable(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	if (exynos_ohci->phy)
 		usb_phy_shutdown(exynos_ohci->phy);
@@ -47,63 +63,11 @@ static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
 		exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
 }
 
-static int ohci_exynos_reset(struct usb_hcd *hcd)
-{
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-static int ohci_exynos_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci);
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-static const struct hc_driver exynos_ohci_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "EXYNOS OHCI Host Controller",
-	.hcd_priv_size		= sizeof(struct ohci_hcd),
-
-	.irq			= ohci_irq,
-	.flags			= HCD_MEMORY|HCD_USB11,
-
-	.reset			= ohci_exynos_reset,
-	.start			= ohci_exynos_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-
-	.get_frame_number	= ohci_get_frame,
-
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-	.start_port_reset	= ohci_start_port_reset,
-};
-
 static int exynos_ohci_probe(struct platform_device *pdev)
 {
 	struct exynos4_ohci_platdata *pdata = dev_get_platdata(&pdev->dev);
 	struct exynos_ohci_hcd *exynos_ohci;
 	struct usb_hcd *hcd;
-	struct ohci_hcd *ohci;
 	struct resource *res;
 	struct usb_phy *phy;
 	int irq;
@@ -119,10 +83,14 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	if (!pdev->dev.coherent_dma_mask)
 		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
-	exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd),
-					GFP_KERNEL);
-	if (!exynos_ohci)
+	hcd = usb_create_hcd(&exynos_ohci_hc_driver,
+				&pdev->dev, dev_name(&pdev->dev));
+	if (!hcd) {
+		dev_err(&pdev->dev, "Unable to create HCD\n");
 		return -ENOMEM;
+	}
+
+	exynos_ohci = to_exynos_ohci(hcd);
 
 	if (of_device_is_compatible(pdev->dev.of_node,
 					"samsung,exynos5440-ohci"))
@@ -143,17 +111,6 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	}
 
 skip_phy:
-
-	exynos_ohci->dev = &pdev->dev;
-
-	hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
-					dev_name(&pdev->dev));
-	if (!hcd) {
-		dev_err(&pdev->dev, "Unable to create HCD\n");
-		return -ENOMEM;
-	}
-
-	exynos_ohci->hcd = hcd;
 	exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");
 
 	if (IS_ERR(exynos_ohci->clk)) {
@@ -190,26 +147,21 @@ skip_phy:
 	}
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	platform_set_drvdata(pdev, hcd);
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to add USB HCD\n");
 		goto fail_add_hcd;
 	}
-
-	platform_set_drvdata(pdev, exynos_ohci);
-
 	return 0;
 
 fail_add_hcd:
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 fail_io:
 	clk_disable_unprepare(exynos_ohci->clk);
 fail_clk:
@@ -219,16 +171,15 @@ fail_clk:
 
 static int exynos_ohci_remove(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 
 	usb_remove_hcd(hcd);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -239,8 +190,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
 
 static void exynos_ohci_shutdown(struct platform_device *pdev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
 	if (hcd->driver->shutdown)
 		hcd->driver->shutdown(hcd);
@@ -249,9 +199,10 @@ static void exynos_ohci_shutdown(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int exynos_ohci_suspend(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
 	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	struct platform_device *pdev = to_platform_device(dev);
 	unsigned long flags;
 	int rc = 0;
 
@@ -271,10 +222,9 @@ static int exynos_ohci_suspend(struct device *dev)
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_disable(exynos_ohci);
+	exynos_ohci_phy_disable(pdev);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -286,16 +236,16 @@ fail:
 
 static int exynos_ohci_resume(struct device *dev)
 {
-	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
-	struct usb_hcd *hcd = exynos_ohci->hcd;
+	struct usb_hcd *hcd			= dev_get_drvdata(dev);
+	struct exynos_ohci_hcd *exynos_ohci	= to_exynos_ohci(hcd);
+	struct platform_device *pdev		= to_platform_device(dev);
 
 	clk_prepare_enable(exynos_ohci->clk);
 
 	if (exynos_ohci->otg)
-		exynos_ohci->otg->set_host(exynos_ohci->otg,
-					&exynos_ohci->hcd->self);
+		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
 
-	exynos_ohci_phy_enable(exynos_ohci);
+	exynos_ohci_phy_enable(pdev);
 
 	ohci_resume(hcd, false);
 
@@ -306,6 +256,10 @@ static int exynos_ohci_resume(struct device *dev)
 #define exynos_ohci_resume	NULL
 #endif
 
+static const struct ohci_driver_overrides exynos_overrides __initconst = {
+	.extra_priv_size =	sizeof(struct exynos_ohci_hcd),
+};
+
 static const struct dev_pm_ops exynos_ohci_pm_ops = {
 	.suspend	= exynos_ohci_suspend,
 	.resume		= exynos_ohci_resume,
@@ -331,6 +285,23 @@ static struct platform_driver exynos_ohci_driver = {
 		.of_match_table	= of_match_ptr(exynos_ohci_match),
 	}
 };
+static int __init ohci_exynos_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&exynos_ohci_hc_driver, &exynos_overrides);
+	return platform_driver_register(&exynos_ohci_driver);
+}
+module_init(ohci_exynos_init);
+
+static void __exit ohci_exynos_cleanup(void)
+{
+	platform_driver_unregister(&exynos_ohci_driver);
+}
+module_exit(ohci_exynos_cleanup);
 
 MODULE_ALIAS("platform:exynos-ohci");
 MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 8f6b695..1fc7d3b 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_EXYNOS
-#include "ohci-exynos.c"
-#define EXYNOS_PLATFORM_DRIVER	exynos_ohci_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP1
 #include "ohci-omap.c"
 #define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
@@ -1336,12 +1331,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_s3c2410;
 #endif
 
-#ifdef EXYNOS_PLATFORM_DRIVER
-	retval = platform_driver_register(&EXYNOS_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_exynos;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1395,10 +1384,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
- error_exynos:
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
  error_s3c2410:
@@ -1463,9 +1448,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef EXYNOS_PLATFORM_DRIVER
-	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER);
-#endif
 #ifdef S3C2410_PLATFORM_DRIVER
 	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 2/9] USB: OHCI: make ohci-omap a separate driver
  2013-09-21 11:08 ` [PATCH V5 0/9] USB: OHCI: more bus glues as separate modules Manjunath Goudar
  2013-09-21 11:08   ` [PATCH V5 1/9] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
@ 2013-09-21 11:08   ` Manjunath Goudar
  2013-09-21 11:08   ` [PATCH V5 3/9] USB: OHCI: make ohci-omap3 " Manjunath Goudar
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-21 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP1/2 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V3->V4:
 -usb_remove_hcd() function is required a valid clock that is what
  omap_ohci_clock_power(0) is called after hcd shutdown.

V2->V3:
 -rewritten if (config->otg || config->rwc) block statements into
  two separate 'if blocks' to handle below scenarios
  1. config->otg set scenario.
  2. if any of these (config->otg, config->rwc) are set, this
     scenario should be handled only after ohci_setup()

V1->V2:
 -omap_ohci_clock_power(0) called in usb_hcd_omap_remove().
 -Removed ohci_setup() call from usb_hcd_omap_probe().
 -host_enabled and host_initialized variables aren't used for anything
  thats what removed.
---
 drivers/usb/host/Kconfig     |    2 +-
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-hcd.c  |   18 -----
 drivers/usb/host/ohci-omap.c |  156 ++++++++++++++----------------------------
 4 files changed, 55 insertions(+), 122 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index e8bd542..6aa2c3f 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -368,7 +368,7 @@ config USB_OHCI_HCD
 if USB_OHCI_HCD
 
 config USB_OHCI_HCD_OMAP1
-	bool "OHCI support for OMAP1/2 chips"
+	tristate "OHCI support for OMAP1/2 chips"
 	depends on ARCH_OMAP1
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 73cc986..cfbfe13 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 1fc7d3b..fcef838 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP1
-#include "ohci-omap.c"
-#define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver
-#endif
-
 #ifdef CONFIG_USB_OHCI_HCD_OMAP3
 #include "ohci-omap3.c"
 #define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
@@ -1289,12 +1284,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP1_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP1_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap1_platform;
-#endif
-
 #ifdef OMAP3_PLATFORM_DRIVER
 	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1408,10 +1397,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
  error_omap3_platform:
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
- error_omap1_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1466,9 +1451,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OMAP3_PLATFORM_DRIVER
 	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP1_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 31d3a12..18b27a2 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -14,12 +14,21 @@
  * This file is licenced under the GPL.
  */
 
-#include <linux/signal.h>
-#include <linux/jiffies.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
 #include <asm/io.h>
 #include <asm/mach-types.h>
@@ -42,10 +51,7 @@
 #define OMAP1510_LB_MMU_RAM_H	0xfffec234
 #define OMAP1510_LB_MMU_RAM_L	0xfffec238
 
-
-#ifndef CONFIG_ARCH_OMAP
-#error "This file is OMAP bus glue.  CONFIG_OMAP must be defined."
-#endif
+#define DRIVER_DESC "OHCI OMAP driver"
 
 #ifdef CONFIG_TPS65010
 #include <linux/i2c/tps65010.h>
@@ -68,8 +74,9 @@ extern int ocpi_enable(void);
 
 static struct clk *usb_host_ck;
 static struct clk *usb_dc_ck;
-static int host_enabled;
-static int host_initialized;
+
+static const char hcd_name[] = "ohci-omap";
+static struct hc_driver __read_mostly ohci_omap_hc_driver;
 
 static void omap_ohci_clock_power(int on)
 {
@@ -188,7 +195,7 @@ static void start_hnp(struct ohci_hcd *ohci)
 
 /*-------------------------------------------------------------------------*/
 
-static int ohci_omap_init(struct usb_hcd *hcd)
+static int ohci_omap_reset(struct usb_hcd *hcd)
 {
 	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
 	struct omap_usb_config	*config = dev_get_platdata(hcd->self.controller);
@@ -198,9 +205,9 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	dev_dbg(hcd->self.controller, "starting USB Controller\n");
 
 	if (config->otg) {
-		ohci_to_hcd(ohci)->self.otg_port = config->otg;
+		hcd->self.otg_port = config->otg;
 		/* default/minimum OTG power budget:  8 mA */
-		ohci_to_hcd(ohci)->power_budget = 8;
+		hcd->power_budget = 8;
 	}
 
 	/* boards can use OTG transceivers in non-OTG modes */
@@ -238,9 +245,15 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 		omap_1510_local_bus_init();
 	}
 
-	if ((ret = ohci_init(ohci)) < 0)
+	ret = ohci_setup(hcd);
+	if (ret < 0)
 		return ret;
 
+	if (config->otg || config->rwc) {
+		ohci->hc_control = OHCI_CTRL_RWC;
+		writel(OHCI_CTRL_RWC, &ohci->regs->control);
+	}
+
 	/* board-specific power switching and overcurrent support */
 	if (machine_is_omap_osk() || machine_is_omap_innovator()) {
 		u32	rh = roothub_a (ohci);
@@ -281,14 +294,6 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 	return 0;
 }
 
-static void ohci_omap_stop(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
-	ohci_stop(hcd);
-	omap_ohci_clock_power(0);
-}
-
-
 /*-------------------------------------------------------------------------*/
 
 /**
@@ -304,7 +309,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 {
 	int retval, irq;
 	struct usb_hcd *hcd = 0;
-	struct ohci_hcd *ohci;
 
 	if (pdev->num_resources != 2) {
 		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
@@ -354,12 +358,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 		goto err2;
 	}
 
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
-
-	host_initialized = 0;
-	host_enabled = 1;
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		retval = -ENXIO;
@@ -369,11 +367,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 	if (retval)
 		goto err3;
 
-	host_initialized = 1;
-
-	if (!host_enabled)
-		omap_ohci_clock_power(0);
-
 	return 0;
 err3:
 	iounmap(hcd->regs);
@@ -402,7 +395,9 @@ err0:
 static inline void
 usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
+	dev_dbg(hcd->self.controller, "stopping USB Controller\n");
 	usb_remove_hcd(hcd);
+	omap_ohci_clock_power(0);
 	if (!IS_ERR_OR_NULL(hcd->phy)) {
 		(void) otg_set_host(hcd->phy->otg, 0);
 		usb_put_phy(hcd->phy);
@@ -418,76 +413,6 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_omap_start (struct usb_hcd *hcd)
-{
-	struct omap_usb_config *config;
-	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ret;
-
-	if (!host_enabled)
-		return 0;
-	config = dev_get_platdata(hcd->self.controller);
-	if (config->otg || config->rwc) {
-		ohci->hc_control = OHCI_CTRL_RWC;
-		writel(OHCI_CTRL_RWC, &ohci->regs->control);
-	}
-
-	if ((ret = ohci_run (ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop (hcd);
-		return ret;
-	}
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_omap_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap_init,
-	.start =		ohci_omap_start,
-	.stop =			ohci_omap_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static int ohci_hcd_omap_drv_probe(struct platform_device *dev)
 {
 	return usb_hcd_omap_probe(&ohci_omap_hc_driver, dev);
@@ -553,4 +478,29 @@ static struct platform_driver ohci_hcd_omap_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides omap_overrides __initconst = {
+	.product_desc	= "OMAP OHCI",
+	.reset		= ohci_omap_reset
+};
+
+static int __init ohci_omap_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap_hc_driver, &omap_overrides);
+	return platform_driver_register(&ohci_hcd_omap_driver);
+}
+module_init(ohci_omap_init);
+
+static void __exit ohci_omap_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap_driver);
+}
+module_exit(ohci_omap_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 3/9] USB: OHCI: make ohci-omap3 a separate driver
  2013-09-21 11:08 ` [PATCH V5 0/9] USB: OHCI: more bus glues as separate modules Manjunath Goudar
  2013-09-21 11:08   ` [PATCH V5 1/9] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
  2013-09-21 11:08   ` [PATCH V5 2/9] USB: OHCI: make ohci-omap " Manjunath Goudar
@ 2013-09-21 11:08   ` Manjunath Goudar
  2013-09-21 11:08   ` [PATCH V5 4/9] USB: OHCI: make ohci-spear " Manjunath Goudar
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-21 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI OMAP3 host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Anand Gadiyar <gadiyar@ti.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V3->V4:
 -V3 modification revert back, only ohci->regs setting write()
  function has been removed because ohci->regs doesn't get set until
  usb_add_hcd.

V2->V3:
 -RemoteWakeupConnected setting has been removed.

V1->V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -The improper multi-line commenting style written in proper way.
  ('*' characters aligned in vertically).
---
 drivers/usb/host/Kconfig      |    2 +-
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 -------
 drivers/usb/host/ohci-omap3.c |  118 +++++++++++++----------------------------
 4 files changed, 40 insertions(+), 99 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 6aa2c3f..2a91a3f 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -375,7 +375,7 @@ config USB_OHCI_HCD_OMAP1
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
 config USB_OHCI_HCD_OMAP3
-	bool "OHCI support for OMAP3 and later chips"
+	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index cfbfe13..aa1721d 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o
 obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
+obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index fcef838..5e9c334 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_OMAP3
-#include "ohci-omap3.c"
-#define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1284,12 +1279,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_platform;
 #endif
 
-#ifdef OMAP3_PLATFORM_DRIVER
-	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_omap3_platform;
-#endif
-
 #ifdef OF_PLATFORM_DRIVER
 	retval = platform_driver_register(&OF_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1393,10 +1382,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
  error_of_platform:
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
- error_omap3_platform:
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
  error_platform:
@@ -1448,9 +1433,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef OF_PLATFORM_DRIVER
 	platform_driver_unregister(&OF_PLATFORM_DRIVER);
 #endif
-#ifdef OMAP3_PLATFORM_DRIVER
-	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER);
-#endif
 #ifdef PLATFORM_DRIVER
 	platform_driver_unregister(&PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index a09af26..408d06a 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -29,90 +29,22 @@
  *	- add kernel-doc
  */
 
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/of.h>
-#include <linux/dma-mapping.h>
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_init(struct usb_hcd *hcd)
-{
-	dev_dbg(hcd->self.controller, "starting OHCI controller\n");
-
-	return ohci_init(hcd_to_ohci(hcd));
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_omap3_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	/*
-	 * RemoteWakeupConnected has to be set explicitly before
-	 * calling ohci_run. The reset value of RWC is 0.
-	 */
-	ohci->hc_control = OHCI_CTRL_RWC;
-	writel(OHCI_CTRL_RWC, &ohci->regs->control);
-
-	ret = ohci_run(ohci);
-
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-	}
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
-	return ret;
-}
+#include "ohci.h"
 
-/*-------------------------------------------------------------------------*/
+#define DRIVER_DESC "OHCI OMAP3 driver"
 
-static const struct hc_driver ohci_omap3_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"OMAP3 OHCI Host Controller",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_omap3_init,
-	.start =		ohci_omap3_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
+static const char hcd_name[] = "ohci-omap3";
+static struct hc_driver __read_mostly ohci_omap3_hc_driver;
 
 /*
  * configure so an HC device and id are always provided
@@ -129,6 +61,7 @@ static const struct hc_driver ohci_omap3_hc_driver = {
 static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 {
 	struct device		*dev = &pdev->dev;
+	struct ohci_hcd		*ohci;
 	struct usb_hcd		*hcd = NULL;
 	void __iomem		*regs = NULL;
 	struct resource		*res;
@@ -185,7 +118,12 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	ohci = hcd_to_ohci(hcd);
+	/*
+	 * RemoteWakeupConnected has to be set explicitly before
+	 * calling ohci_run. The reset value of RWC is 0.
+	 */
+	ohci->hc_control = OHCI_CTRL_RWC;
 
 	ret = usb_add_hcd(hcd, irq, 0);
 	if (ret) {
@@ -248,5 +186,25 @@ static struct platform_driver ohci_hcd_omap3_driver = {
 	},
 };
 
+static int __init ohci_omap3_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_omap3_hc_driver, NULL);
+	return platform_driver_register(&ohci_hcd_omap3_driver);
+}
+module_init(ohci_omap3_init);
+
+static void __exit ohci_omap3_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_omap3_driver);
+}
+module_exit(ohci_omap3_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_ALIAS("platform:ohci-omap3");
 MODULE_AUTHOR("Anand Gadiyar <gadiyar@ti.com>");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 4/9] USB: OHCI: make ohci-spear a separate driver
  2013-09-21 11:08 ` [PATCH V5 0/9] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (2 preceding siblings ...)
  2013-09-21 11:08   ` [PATCH V5 3/9] USB: OHCI: make ohci-omap3 " Manjunath Goudar
@ 2013-09-21 11:08   ` Manjunath Goudar
  2013-09-21 11:08   ` [PATCH V5 5/9] USB: OHCI: make ohci-at91 " Manjunath Goudar
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-21 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the ST OHCI SPEAr host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2->V3:
 -No change.

V1->V2:
 -ohci_setup() removed because it is called in .reset member
  of the ohci_hc_driver structure.
 -debugging stuff isn't needed any more that's what removed.
---
 drivers/usb/host/Kconfig      |    8 +++
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ohci-hcd.c   |   18 ------
 drivers/usb/host/ohci-spear.c |  140 +++++++++++++++++------------------------
 4 files changed, 65 insertions(+), 102 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 2a91a3f..00d22f5 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -374,6 +374,14 @@ config USB_OHCI_HCD_OMAP1
 	---help---
 	  Enables support for the OHCI controller on OMAP1/2 chips.
 
+config USB_OHCI_HCD_SPEAR
+        tristate "Support for ST SPEAr on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && PLAT_SPEAR
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          ST SPEAr chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index aa1721d..9efcb7c 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o
 obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
+obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 5e9c334..523f58e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1212,11 +1212,6 @@ MODULE_LICENSE ("GPL");
 #define OF_PLATFORM_DRIVER	ohci_hcd_ppc_of_driver
 #endif
 
-#ifdef CONFIG_PLAT_SPEAR
-#include "ohci-spear.c"
-#define SPEAR_PLATFORM_DRIVER	spear_ohci_hcd_driver
-#endif
-
 #ifdef CONFIG_PPC_PS3
 #include "ohci-ps3.c"
 #define PS3_SYSTEM_BUS_DRIVER	ps3_ohci_driver
@@ -1333,19 +1328,9 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_davinci;
 #endif
 
-#ifdef SPEAR_PLATFORM_DRIVER
-	retval = platform_driver_register(&SPEAR_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_spear;
-#endif
-
 	return retval;
 
 	/* Error path */
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
- error_spear:
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
  error_davinci:
@@ -1403,9 +1388,6 @@ module_init(ohci_hcd_mod_init);
 
 static void __exit ohci_hcd_mod_exit(void)
 {
-#ifdef SPEAR_PLATFORM_DRIVER
-	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER);
-#endif
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index cc9dd9e..31ff3fc 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -11,92 +11,37 @@
 * warranty of any kind, whether express or implied.
 */
 
-#include <linux/signal.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
 
+#define DRIVER_DESC "OHCI SPEAr driver"
+
+static const char hcd_name[] = "SPEAr-ohci";
 struct spear_ohci {
-	struct ohci_hcd ohci;
 	struct clk *clk;
 };
 
-#define to_spear_ohci(hcd)	(struct spear_ohci *)hcd_to_ohci(hcd)
-
-static void spear_start_ohci(struct spear_ohci *ohci)
-{
-	clk_prepare_enable(ohci->clk);
-}
-
-static void spear_stop_ohci(struct spear_ohci *ohci)
-{
-	clk_disable_unprepare(ohci->clk);
-}
-
-static int ohci_spear_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-	ohci->regs = hcd->regs;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	create_debug_files(ohci);
-
-#ifdef DEBUG
-	ohci_dump(ohci, 1);
-#endif
-	return 0;
-}
-
-static const struct hc_driver ohci_spear_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "SPEAr OHCI",
-	.hcd_priv_size		= sizeof(struct spear_ohci),
-
-	/* generic hardware linkage */
-	.irq			= ohci_irq,
-	.flags			= HCD_USB11 | HCD_MEMORY,
-
-	/* basic lifecycle operations */
-	.start			= ohci_spear_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-
-	/* managing i/o requests and associated device resources */
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	/* scheduling support */
-	.get_frame_number	= ohci_get_frame,
+#define to_spear_ohci(hcd)     (struct spear_ohci *)(hcd_to_ohci(hcd)->priv)
 
-	/* root hub support */
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-
-	.start_port_reset	= ohci_start_port_reset,
-};
+static struct hc_driver __read_mostly ohci_spear_hc_driver;
 
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
 	const struct hc_driver *driver = &ohci_spear_hc_driver;
+	struct ohci_hcd *ohci;
 	struct usb_hcd *hcd = NULL;
 	struct clk *usbh_clk;
-	struct spear_ohci *ohci_p;
+	struct spear_ohci *sohci_p;
 	struct resource *res;
 	int retval, irq;
 
@@ -151,16 +96,18 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 		goto err_put_hcd;
 	}
 
-	ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
-	ohci_p->clk = usbh_clk;
-	spear_start_ohci(ohci_p);
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	sohci_p = to_spear_ohci(hcd);
+	sohci_p->clk = usbh_clk;
+
+	clk_prepare_enable(sohci_p->clk);
+
+	ohci = hcd_to_ohci(hcd);
 
 	retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0);
 	if (retval == 0)
 		return retval;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
 err_put_hcd:
 	usb_put_hcd(hcd);
 fail:
@@ -172,11 +119,11 @@ fail:
 static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	usb_remove_hcd(hcd);
-	if (ohci_p->clk)
-		spear_stop_ohci(ohci_p);
+	if (sohci_p->clk)
+		clk_disable_unprepare(sohci_p->clk);
 
 	usb_put_hcd(hcd);
 	return 0;
@@ -188,13 +135,14 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_stop_ohci(ohci_p);
+	clk_disable_unprepare(sohci_p->clk);
+
 	return 0;
 }
 
@@ -202,13 +150,13 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(dev);
 	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+	struct spear_ohci *sohci_p = to_spear_ohci(hcd);
 
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
 
-	spear_start_ohci(ohci_p);
+	clk_prepare_enable(sohci_p->clk);
 	ohci_resume(hcd, false);
 	return 0;
 }
@@ -234,4 +182,28 @@ static struct platform_driver spear_ohci_hcd_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides spear_overrides __initconst = {
+	.extra_priv_size = sizeof(struct spear_ohci),
+};
+static int __init ohci_spear_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_spear_hc_driver, &spear_overrides);
+	return platform_driver_register(&spear_ohci_hcd_driver);
+}
+module_init(ohci_spear_init);
+
+static void __exit ohci_spear_cleanup(void)
+{
+	platform_driver_unregister(&spear_ohci_hcd_driver);
+}
+module_exit(ohci_spear_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Deepak Sikri");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:spear-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 5/9] USB: OHCI: make ohci-at91 a separate driver
  2013-09-21 11:08 ` [PATCH V5 0/9] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (3 preceding siblings ...)
  2013-09-21 11:08   ` [PATCH V5 4/9] USB: OHCI: make ohci-spear " Manjunath Goudar
@ 2013-09-21 11:08   ` Manjunath Goudar
  2013-09-23 12:22     ` Nicolas Ferre
  2013-09-27 15:10     ` Kevin Hilman
  2013-09-21 11:08   ` [PATCH V5 6/9] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
                     ` (3 subsequent siblings)
  8 siblings, 2 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-21 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  TI OHCI Atmel host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V3->V4:
 - Removed extra space after "tristate".
 - Removed extra space between function name  and '(' characters.
 - MODULE_ALIAS line moved to last statement of ohci-at91 file.

V2->V3:
 -The ohci_restart() function is not required in  current scenario,
  only discarding connection state of integrated transceivers is sufficient,
  for this directly handling ohci->hc_control.

V1->V2:
 -Set non-standard fields in ohci_at91_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.
---
 drivers/usb/host/Kconfig     |    8 +++
 drivers/usb/host/Makefile    |    1 +
 drivers/usb/host/ohci-at91.c |  156 +++++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c  |   18 -----
 4 files changed, 79 insertions(+), 104 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 00d22f5..6900b72 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -382,6 +382,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_AT91
+        tristate "Support for Atmel on-chip OHCI USB controller"
+        depends on USB_OHCI_HCD && ARCH_AT91
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          Atmel chips.
+
 config USB_OHCI_HCD_OMAP3
 	tristate "OHCI support for OMAP3 and later chips"
 	depends on (ARCH_OMAP3 || ARCH_OMAP4)
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 9efcb7c..0d7a81a 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
+obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index caa3764..476b5a5 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -13,19 +13,24 @@
  */
 
 #include <linux/clk.h>
-#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/atmel.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
 #include <mach/hardware.h>
 #include <asm/gpio.h>
 
 #include <mach/cpu.h>
 
-#ifndef CONFIG_ARCH_AT91
-#error "CONFIG_ARCH_AT91 must be defined."
-#endif
+
+#include "ohci.h"
 
 #define valid_port(index)	((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
 #define at91_for_each_port(index)	\
@@ -33,7 +38,17 @@
 
 /* interface, function and usb clocks; sometimes also an AHB clock */
 static struct clk *iclk, *fclk, *uclk, *hclk;
+/* interface and function clocks; sometimes also an AHB clock */
+
+#define DRIVER_DESC "OHCI Atmel driver"
+
+static const char hcd_name[] = "ohci-atmel";
+
+static struct hc_driver __read_mostly ohci_at91_hc_driver;
 static int clocked;
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+			u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
 
 extern int usb_disabled(void);
 
@@ -117,6 +132,8 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
 static int usb_hcd_at91_probe(const struct hc_driver *driver,
 			struct platform_device *pdev)
 {
+	struct at91_usbh_data *board;
+	struct ohci_hcd *ohci;
 	int retval;
 	struct usb_hcd *hcd = NULL;
 
@@ -177,8 +194,10 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
 		}
 	}
 
+	board = hcd->self.controller->platform_data;
+	ohci = hcd_to_ohci(hcd);
+	ohci->num_ports = board->ports;
 	at91_start_hc(pdev);
-	ohci_hcd_init(hcd_to_ohci(hcd));
 
 	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
 	if (retval == 0)
@@ -238,36 +257,6 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd,
 }
 
 /*-------------------------------------------------------------------------*/
-
-static int
-ohci_at91_reset (struct usb_hcd *hcd)
-{
-	struct at91_usbh_data	*board = dev_get_platdata(hcd->self.controller);
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
-	ohci->num_ports = board->ports;
-	return 0;
-}
-
-static int
-ohci_at91_start (struct usb_hcd *hcd)
-{
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-	int			ret;
-
-	if ((ret = ohci_run(ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-	return 0;
-}
-
 static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
 {
 	if (!valid_port(port))
@@ -297,8 +286,8 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
  */
 static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
-	struct at91_usbh_data *pdata = dev_get_platdata(hcd->self.controller);
-	int length = ohci_hub_status_data(hcd, buf);
+	struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
+	int length = orig_ohci_hub_status_data(hcd, buf);
 	int port;
 
 	at91_for_each_port(port) {
@@ -376,7 +365,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex + 1,
+				buf, wLength);
 	if (ret)
 		goto out;
 
@@ -430,51 +420,6 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 /*-------------------------------------------------------------------------*/
 
-static const struct hc_driver ohci_at91_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"AT91 OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset =		ohci_at91_reset,
-	.start =		ohci_at91_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_at91_hub_status_data,
-	.hub_control =		ohci_at91_hub_control,
-#ifdef CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
 {
 	struct platform_device *pdev = data;
@@ -703,7 +648,11 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
 	 * REVISIT: some boards will be able to turn VBUS off...
 	 */
 	if (at91_suspend_entering_slow_clock()) {
-		ohci_usb_reset (ohci);
+		ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
+		ohci->hc_control &= OHCI_CTRL_RWC;
+		ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
+		ohci->rh_state = OHCI_RH_HALTED;
+
 		/* flush the writes */
 		(void) ohci_readl (ohci, &ohci->regs->control);
 		at91_stop_clock();
@@ -730,8 +679,6 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
 #define ohci_hcd_at91_drv_resume  NULL
 #endif
 
-MODULE_ALIAS("platform:at91_ohci");
-
 static struct platform_driver ohci_hcd_at91_driver = {
 	.probe		= ohci_hcd_at91_drv_probe,
 	.remove		= ohci_hcd_at91_drv_remove,
@@ -744,3 +691,40 @@ static struct platform_driver ohci_hcd_at91_driver = {
 		.of_match_table	= of_match_ptr(at91_ohci_dt_ids),
 	},
 };
+
+static int __init ohci_at91_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_at91_hc_driver, NULL);
+
+	/*
+	 * The Atmel HW has some unusual quirks, which require Atmel-specific
+	 * workarounds. We override certain hc_driver functions here to
+	 * achieve that. We explicitly do not enhance ohci_driver_overrides to
+	 * allow this more easily, since this is an unusual case, and we don't
+	 * want to encourage others to override these functions by making it
+	 * too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_at91_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_at91_hc_driver.hub_status_data;
+
+	ohci_at91_hc_driver.hub_status_data	= ohci_at91_hub_status_data;
+	ohci_at91_hc_driver.hub_control		= ohci_at91_hub_control;
+
+	return platform_driver_register(&ohci_hcd_at91_driver);
+}
+module_init(ohci_at91_init);
+
+static void __exit ohci_at91_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_at91_driver);
+}
+module_exit(ohci_at91_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:at91_ohci");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 523f58e..2fdaaf8 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1192,11 +1192,6 @@ MODULE_LICENSE ("GPL");
 #define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver
 #endif
 
-#ifdef CONFIG_ARCH_AT91
-#include "ohci-at91.c"
-#define AT91_PLATFORM_DRIVER	ohci_hcd_at91_driver
-#endif
-
 #ifdef CONFIG_ARCH_LPC32XX
 #include "ohci-nxp.c"
 #define NXP_PLATFORM_DRIVER	usb_hcd_nxp_driver
@@ -1310,12 +1305,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_ep93xx;
 #endif
 
-#ifdef AT91_PLATFORM_DRIVER
-	retval = platform_driver_register(&AT91_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_at91;
-#endif
-
 #ifdef NXP_PLATFORM_DRIVER
 	retval = platform_driver_register(&NXP_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1339,10 +1328,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
  error_nxp:
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
- error_at91:
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
@@ -1394,9 +1379,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef NXP_PLATFORM_DRIVER
 	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
 #endif
-#ifdef AT91_PLATFORM_DRIVER
-	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 6/9] USB: OHCI: make ohci-s3c2410 a separate driver
  2013-09-21 11:08 ` [PATCH V5 0/9] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (4 preceding siblings ...)
  2013-09-21 11:08   ` [PATCH V5 5/9] USB: OHCI: make ohci-at91 " Manjunath Goudar
@ 2013-09-21 11:08   ` Manjunath Goudar
  2013-09-21 11:08   ` [PATCH V5 7/9] USB: OHCI: make ohci-nxp " Manjunath Goudar
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-21 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the Samsung OHCI S3C24xx/S3C64xx host controller driver
from ohci-hcd host code so that it can be built as a separate
driver module.This work is part of enabling multi-platform.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V4->V5:
 - String "s3cxxxx" is replaced by "s3c2410".

V3->V4:
 - Removed extra space before the '='.
 - Moved  /* forward definitions */ line before the declarations of functions.

V2->V3:
 -Kconfig wrong parentheses discription fixed.
 -ohci_setup() has been removed because it is called in .reset member
  of the ohci_hc_driver structure.

V1->V2:
 -Set non-standard fields in ohci_s3c2410_hc_driver manually, rather than
  relying on an expanded struct ohci_driver_overrides.
 -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
  relying on ohci_hub_control and hub_status_data being exported.
---
 drivers/usb/host/Kconfig        |    8 +++
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ohci-hcd.c     |   18 ------
 drivers/usb/host/ohci-s3c2410.c |  128 +++++++++++++++++----------------------
 4 files changed, 66 insertions(+), 89 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 6900b72..1196a56 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -382,6 +382,14 @@ config USB_OHCI_HCD_SPEAR
           Enables support for the on-chip OHCI controller on
           ST SPEAr chips.
 
+config USB_OHCI_HCD_S3C2410
+        tristate "OHCI support for Samsung S3C24xx/S3C64xx SoC series"
+        depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX)
+        default y
+        ---help---
+          Enables support for the on-chip OHCI controller on
+          S3C24xx/S3C64xx chips.
+
 config USB_OHCI_HCD_AT91
         tristate "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 0d7a81a..ddba422 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
 obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
+obj-$(CONFIG_USB_OHCI_HCD_S3C2410)	+= ohci-s3c2410.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 2fdaaf8..fcfcab5 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1177,11 +1177,6 @@ MODULE_LICENSE ("GPL");
 #define SA1111_DRIVER		ohci_hcd_sa1111_driver
 #endif
 
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
-#include "ohci-s3c2410.c"
-#define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver
-#endif
-
 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #include "ohci-pxa27x.c"
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
@@ -1293,12 +1288,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_tmio;
 #endif
 
-#ifdef S3C2410_PLATFORM_DRIVER
-	retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_s3c2410;
-#endif
-
 #ifdef EP93XX_PLATFORM_DRIVER
 	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1332,10 +1321,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
- error_s3c2410:
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
  error_tmio:
@@ -1382,9 +1367,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
-#ifdef S3C2410_PLATFORM_DRIVER
-	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index 4919afa..be3429e 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -19,19 +19,36 @@
  * This file is licenced under the GPL.
 */
 
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/platform_data/usb-ohci-s3c2410.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
+
 
 #define valid_port(idx) ((idx) == 1 || (idx) == 2)
 
 /* clock device associated with the hcd */
 
+
+#define DRIVER_DESC "OHCI S3C2410 driver"
+
+static const char hcd_name[] = "ohci-s3c2410";
+
 static struct clk *clk;
 static struct clk *usb_clk;
 
 /* forward definitions */
 
+static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
+			u16 wValue, u16 wIndex, char *buf, u16 wLength);
+static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
+
 static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
 
 /* conversion functions */
@@ -93,7 +110,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd, char *buf)
 	int orig;
 	int portno;
 
-	orig  = ohci_hub_status_data(hcd, buf);
+	orig = orig_ohci_hub_status_data(hcd, buf);
 
 	if (info == NULL)
 		return orig;
@@ -164,7 +181,7 @@ static int ohci_s3c2410_hub_control(
 	 * process the request straight away and exit */
 
 	if (info == NULL) {
-		ret = ohci_hub_control(hcd, typeReq, wValue,
+		ret = orig_ohci_hub_control(hcd, typeReq, wValue,
 				       wIndex, buf, wLength);
 		goto out;
 	}
@@ -214,7 +231,7 @@ static int ohci_s3c2410_hub_control(
 		break;
 	}
 
-	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
 	if (ret)
 		goto out;
 
@@ -374,8 +391,6 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 	s3c2410_start_hc(dev, hcd);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
-
 	retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
 	if (retval != 0)
 		goto err_ioremap;
@@ -392,71 +407,7 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_s3c2410_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	ret = ohci_init(ohci);
-	if (ret < 0)
-		return ret;
-
-	ret = ohci_run(ohci);
-	if (ret < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
-
-	return 0;
-}
-
-
-static const struct hc_driver ohci_s3c2410_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"S3C24XX OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.start =		ohci_s3c2410_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_s3c2410_hub_status_data,
-	.hub_control =		ohci_s3c2410_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/* device driver */
+static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;
 
 static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
 {
@@ -533,4 +484,39 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {
 	},
 };
 
+static int __init ohci_s3c2410_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
+
+	/*
+	 * The Samsung HW has some unusual quirks, which require
+	 * Sumsung-specific workarounds. We override certain hc_driver
+	 * functions here to achieve that. We explicitly do not enhance
+	 * ohci_driver_overrides to allow this more easily, since this
+	 * is an unusual case, and we don't want to encourage others to
+	 * override these functions by making it too easy.
+	 */
+
+	orig_ohci_hub_control = ohci_s3c2410_hc_driver.hub_control;
+	orig_ohci_hub_status_data = ohci_s3c2410_hc_driver.hub_status_data;
+
+	ohci_s3c2410_hc_driver.hub_status_data	= ohci_s3c2410_hub_status_data;
+	ohci_s3c2410_hc_driver.hub_control	= ohci_s3c2410_hub_control;
+
+	return platform_driver_register(&ohci_hcd_s3c2410_driver);
+}
+module_init(ohci_s3c2410_init);
+
+static void __exit ohci_s3c2410_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_s3c2410_driver);
+}
+module_exit(ohci_s3c2410_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:s3c2410-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 7/9] USB: OHCI: make ohci-nxp a separate driver
  2013-09-21 11:08 ` [PATCH V5 0/9] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (5 preceding siblings ...)
  2013-09-21 11:08   ` [PATCH V5 6/9] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
@ 2013-09-21 11:08   ` Manjunath Goudar
  2013-09-21 11:08   ` [PATCH V5 8/9] USB: OHCI: make ohci-ep93xx " Manjunath Goudar
  2013-09-21 11:08   ` [PATCH V5 9/9] USB: OHCI: make ohci-pxa27x " Manjunath Goudar
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-21 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the OHCI NXP host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Many place function name and struct name started with usb,
current scenario replaced usb with ohci for proper naming.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V1->V2:
  - Directive check NXP_PLATFORM_DRIVER block has been removed.
---
 drivers/usb/host/Kconfig    |    8 +++
 drivers/usb/host/Makefile   |    1 +
 drivers/usb/host/ohci-hcd.c |   18 -------
 drivers/usb/host/ohci-nxp.c |  123 +++++++++++++++++--------------------------
 4 files changed, 57 insertions(+), 93 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 1196a56..06c0cec 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -390,6 +390,14 @@ config USB_OHCI_HCD_S3C2410
           Enables support for the on-chip OHCI controller on
           S3C24xx/S3C64xx chips.
 
+config USB_OHCI_HCD_LPC32XX
+	tristate "Support for LPC on-chip OHCI USB controller"
+	depends on USB_OHCI_HCD && ARCH_LPC32XX
+	default y
+	---help---
+          Enables support for the on-chip OHCI controller on
+          NXP chips.
+
 config USB_OHCI_HCD_AT91
         tristate "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index ddba422..30a632c 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
 obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 obj-$(CONFIG_USB_OHCI_HCD_S3C2410)	+= ohci-s3c2410.o
+obj-$(CONFIG_USB_OHCI_HCD_LPC32XX)	+= ohci-nxp.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index fcfcab5..c515192 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1187,11 +1187,6 @@ MODULE_LICENSE ("GPL");
 #define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver
 #endif
 
-#ifdef CONFIG_ARCH_LPC32XX
-#include "ohci-nxp.c"
-#define NXP_PLATFORM_DRIVER	usb_hcd_nxp_driver
-#endif
-
 #ifdef CONFIG_ARCH_DAVINCI_DA8XX
 #include "ohci-da8xx.c"
 #define DAVINCI_PLATFORM_DRIVER	ohci_hcd_da8xx_driver
@@ -1294,12 +1289,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_ep93xx;
 #endif
 
-#ifdef NXP_PLATFORM_DRIVER
-	retval = platform_driver_register(&NXP_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_nxp;
-#endif
-
 #ifdef DAVINCI_PLATFORM_DRIVER
 	retval = platform_driver_register(&DAVINCI_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1313,10 +1302,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
  error_davinci:
 #endif
-#ifdef NXP_PLATFORM_DRIVER
-	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
- error_nxp:
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
  error_ep93xx:
@@ -1361,9 +1346,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
 #endif
-#ifdef NXP_PLATFORM_DRIVER
-	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
-#endif
 #ifdef EP93XX_PLATFORM_DRIVER
 	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c
index 7d7d507..9ab7e24 100644
--- a/drivers/usb/host/ohci-nxp.c
+++ b/drivers/usb/host/ohci-nxp.c
@@ -19,10 +19,19 @@
  * or implied.
  */
 #include <linux/clk.h>
-#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
 #include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
 #include <linux/usb/isp1301.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ohci.h"
+
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -57,6 +66,11 @@
 #define start_int_umask(irq)
 #endif
 
+#define DRIVER_DESC "OHCI NXP driver"
+
+static const char hcd_name[] = "ohci-nxp";
+static struct hc_driver __read_mostly ohci_nxp_hc_driver;
+
 static struct i2c_client *isp1301_i2c_client;
 
 extern int usb_disabled(void);
@@ -132,14 +146,14 @@ static inline void isp1301_vbus_off(void)
 		OTG1_VBUS_DRV);
 }
 
-static void nxp_start_hc(void)
+static void ohci_nxp_start_hc(void)
 {
 	unsigned long tmp = __raw_readl(USB_OTG_STAT_CONTROL) | HOST_EN;
 	__raw_writel(tmp, USB_OTG_STAT_CONTROL);
 	isp1301_vbus_on();
 }
 
-static void nxp_stop_hc(void)
+static void ohci_nxp_stop_hc(void)
 {
 	unsigned long tmp;
 	isp1301_vbus_off();
@@ -147,68 +161,9 @@ static void nxp_stop_hc(void)
 	__raw_writel(tmp, USB_OTG_STAT_CONTROL);
 }
 
-static int ohci_nxp_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
-
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
-	if ((ret = ohci_run(ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start\n");
-		ohci_stop(hcd);
-		return ret;
-	}
-	return 0;
-}
-
-static const struct hc_driver ohci_nxp_hc_driver = {
-	.description = hcd_name,
-	.product_desc =		"nxp OHCI",
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq = ohci_irq,
-	.flags = HCD_USB11 | HCD_MEMORY,
-
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-	/*
-	 * basic lifecycle operations
-	 */
-	.start = ohci_nxp_start,
-	.stop = ohci_stop,
-	.shutdown = ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue = ohci_urb_enqueue,
-	.urb_dequeue = ohci_urb_dequeue,
-	.endpoint_disable = ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number = ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data = ohci_hub_status_data,
-	.hub_control = ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend = ohci_bus_suspend,
-	.bus_resume = ohci_bus_resume,
-#endif
-	.start_port_reset = ohci_start_port_reset,
-};
-
-static int usb_hcd_nxp_probe(struct platform_device *pdev)
+static int ohci_hcd_nxp_probe(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = 0;
-	struct ohci_hcd *ohci;
 	const struct hc_driver *driver = &ohci_nxp_hc_driver;
 	struct resource *res;
 	int ret = 0, irq;
@@ -313,17 +268,15 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)
 		goto fail_resource;
 	}
 
-	nxp_start_hc();
+	ohci_nxp_start_hc();
 	platform_set_drvdata(pdev, hcd);
-	ohci = hcd_to_ohci(hcd);
-	ohci_hcd_init(ohci);
 
 	dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);
 	ret = usb_add_hcd(hcd, irq, 0);
 	if (ret == 0)
 		return ret;
 
-	nxp_stop_hc();
+	ohci_nxp_stop_hc();
 fail_resource:
 	usb_put_hcd(hcd);
 fail_hcd:
@@ -345,12 +298,12 @@ fail_disable:
 	return ret;
 }
 
-static int usb_hcd_nxp_remove(struct platform_device *pdev)
+static int ohci_hcd_nxp_remove(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
 	usb_remove_hcd(hcd);
-	nxp_stop_hc();
+	ohci_nxp_stop_hc();
 	usb_put_hcd(hcd);
 	clk_disable(usb_pll_clk);
 	clk_put(usb_pll_clk);
@@ -366,20 +319,40 @@ static int usb_hcd_nxp_remove(struct platform_device *pdev)
 MODULE_ALIAS("platform:usb-ohci");
 
 #ifdef CONFIG_OF
-static const struct of_device_id usb_hcd_nxp_match[] = {
+static const struct of_device_id ohci_hcd_nxp_match[] = {
 	{ .compatible = "nxp,ohci-nxp" },
 	{},
 };
-MODULE_DEVICE_TABLE(of, usb_hcd_nxp_match);
+MODULE_DEVICE_TABLE(of, ohci_hcd_nxp_match);
 #endif
 
-static struct platform_driver usb_hcd_nxp_driver = {
+static struct platform_driver ohci_hcd_nxp_driver = {
 	.driver = {
 		.name = "usb-ohci",
 		.owner	= THIS_MODULE,
-		.of_match_table = of_match_ptr(usb_hcd_nxp_match),
+		.of_match_table = of_match_ptr(ohci_hcd_nxp_match),
 	},
-	.probe = usb_hcd_nxp_probe,
-	.remove = usb_hcd_nxp_remove,
+	.probe = ohci_hcd_nxp_probe,
+	.remove = ohci_hcd_nxp_remove,
 };
 
+static int __init ohci_nxp_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_nxp_hc_driver, NULL);
+	return platform_driver_register(&ohci_hcd_nxp_driver);
+}
+module_init(ohci_nxp_init);
+
+static void __exit ohci_nxp_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_nxp_driver);
+}
+module_exit(ohci_nxp_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 8/9] USB: OHCI: make ohci-ep93xx a separate driver
  2013-09-21 11:08 ` [PATCH V5 0/9] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (6 preceding siblings ...)
  2013-09-21 11:08   ` [PATCH V5 7/9] USB: OHCI: make ohci-nxp " Manjunath Goudar
@ 2013-09-21 11:08   ` Manjunath Goudar
  2013-09-21 11:08   ` [PATCH V5 9/9] USB: OHCI: make ohci-pxa27x " Manjunath Goudar
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-21 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the OHCI EP93XX host controller driver from ohci-hcd
host code so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2->V3:
 -Unused *ohci variable has been removed.

V1->V2:
 -ohci_hcd_init() statements are removed,
  because by default it is called in ohci_setup().
---
 drivers/usb/host/Kconfig       |    8 +++++
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ohci-ep93xx.c |   72 +++++++++++++++++-----------------------
 drivers/usb/host/ohci-hcd.c    |   18 ----------
 4 files changed, 40 insertions(+), 59 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 06c0cec..8e31c98 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -398,6 +398,14 @@ config USB_OHCI_HCD_LPC32XX
           Enables support for the on-chip OHCI controller on
           NXP chips.
 
+config USB_OHCI_HCD_EP93XX
+	tristate "Support for EP93XX on-chip OHCI USB controller"
+	depends on USB_OHCI_HCD && ARCH_EP93XX
+	default y
+	---help---
+	  Enables support for the on-chip OHCI controller on
+	  EP93XX chips.
+
 config USB_OHCI_HCD_AT91
         tristate "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 30a632c..02f9cd2 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
 obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 obj-$(CONFIG_USB_OHCI_HCD_S3C2410)	+= ohci-s3c2410.o
 obj-$(CONFIG_USB_OHCI_HCD_LPC32XX)	+= ohci-nxp.o
+obj-$(CONFIG_USB_OHCI_HCD_EP93XX)	+= ohci-ep93xx.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
index 84a20d5..492f681 100644
--- a/drivers/usb/host/ohci-ep93xx.c
+++ b/drivers/usb/host/ohci-ep93xx.c
@@ -25,50 +25,23 @@
 
 #include <linux/clk.h>
 #include <linux/device.h>
-#include <linux/signal.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
-static struct clk *usb_host_clock;
+#include "ohci.h"
 
-static int ohci_ep93xx_start(struct usb_hcd *hcd)
-{
-	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	int ret;
+#define DRIVER_DESC "OHCI EP93xx driver"
 
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
+static const char hcd_name[] = "ohci-ep93xx";
 
-	if ((ret = ohci_run(ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start %s\n",
-			hcd->self.bus_name);
-		ohci_stop(hcd);
-		return ret;
-	}
+static struct hc_driver __read_mostly ohci_ep93xx_hc_driver;
 
-	return 0;
-}
-
-static struct hc_driver ohci_ep93xx_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "EP93xx OHCI",
-	.hcd_priv_size		= sizeof(struct ohci_hcd),
-	.irq			= ohci_irq,
-	.flags			= HCD_USB11 | HCD_MEMORY,
-	.start			= ohci_ep93xx_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-	.get_frame_number	= ohci_get_frame,
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-#ifdef CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-	.start_port_reset	= ohci_start_port_reset,
-};
+static struct clk *usb_host_clock;
 
 static int ohci_hcd_ep93xx_drv_probe(struct platform_device *pdev)
 {
@@ -109,8 +82,6 @@ static int ohci_hcd_ep93xx_drv_probe(struct platform_device *pdev)
 
 	clk_enable(usb_host_clock);
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
-
 	ret = usb_add_hcd(hcd, irq, 0);
 	if (ret)
 		goto err_clk_disable;
@@ -166,7 +137,6 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev)
 }
 #endif
 
-
 static struct platform_driver ohci_hcd_ep93xx_driver = {
 	.probe		= ohci_hcd_ep93xx_drv_probe,
 	.remove		= ohci_hcd_ep93xx_drv_remove,
@@ -181,4 +151,24 @@ static struct platform_driver ohci_hcd_ep93xx_driver = {
 	},
 };
 
+static int __init ohci_ep93xx_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ohci_init_driver(&ohci_ep93xx_hc_driver, NULL);
+	return platform_driver_register(&ohci_hcd_ep93xx_driver);
+}
+module_init(ohci_ep93xx_init);
+
+static void __exit ohci_ep93xx_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_ep93xx_driver);
+}
+module_exit(ohci_ep93xx_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:ep93xx-ohci");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index c515192..2ee3171 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1182,11 +1182,6 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
 #endif
 
-#ifdef CONFIG_ARCH_EP93XX
-#include "ohci-ep93xx.c"
-#define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver
-#endif
-
 #ifdef CONFIG_ARCH_DAVINCI_DA8XX
 #include "ohci-da8xx.c"
 #define DAVINCI_PLATFORM_DRIVER	ohci_hcd_da8xx_driver
@@ -1283,12 +1278,6 @@ static int __init ohci_hcd_mod_init(void)
 		goto error_tmio;
 #endif
 
-#ifdef EP93XX_PLATFORM_DRIVER
-	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
-	if (retval < 0)
-		goto error_ep93xx;
-#endif
-
 #ifdef DAVINCI_PLATFORM_DRIVER
 	retval = platform_driver_register(&DAVINCI_PLATFORM_DRIVER);
 	if (retval < 0)
@@ -1302,10 +1291,6 @@ static int __init ohci_hcd_mod_init(void)
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
  error_davinci:
 #endif
-#ifdef EP93XX_PLATFORM_DRIVER
-	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
- error_ep93xx:
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
  error_tmio:
@@ -1346,9 +1331,6 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef DAVINCI_PLATFORM_DRIVER
 	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);
 #endif
-#ifdef EP93XX_PLATFORM_DRIVER
-	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
-#endif
 #ifdef TMIO_OHCI_DRIVER
 	platform_driver_unregister(&TMIO_OHCI_DRIVER);
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 9/9] USB: OHCI: make ohci-pxa27x a separate driver
  2013-09-21 11:08 ` [PATCH V5 0/9] USB: OHCI: more bus glues as separate modules Manjunath Goudar
                     ` (7 preceding siblings ...)
  2013-09-21 11:08   ` [PATCH V5 8/9] USB: OHCI: make ohci-ep93xx " Manjunath Goudar
@ 2013-09-21 11:08   ` Manjunath Goudar
  8 siblings, 0 replies; 110+ messages in thread
From: Manjunath Goudar @ 2013-09-21 11:08 UTC (permalink / raw)
  To: linux-arm-kernel

Separate the  OHCI pxa27x/pxa3xx host controller driver from
ohci-hcd host code so that it can be built as a separate driver
module. This work is part of enabling multi-platform kernels on
ARM.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg KH <greg@kroah.com>
Cc: linux-usb at vger.kernel.org

V2->V3:
 -Rewrite the macro definition of to_pxa27x_ohci.
 -clk_put() function has been called before usb_put_hcd().

V1->V2:
 -Changed ohci_hcd and pxa27x_ohci struct variable names.
    1 ohci_hcd struct variable name is ohci.
    2 pxa27x_ohci struct variable name is pxa_ohci.
---
 drivers/usb/host/Kconfig       |    8 ++
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ohci-hcd.c    |    5 -
 drivers/usb/host/ohci-pxa27x.c |  240 +++++++++++++++++-----------------------
 4 files changed, 113 insertions(+), 141 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 8e31c98..8ea1afc 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -406,6 +406,14 @@ config USB_OHCI_HCD_EP93XX
 	  Enables support for the on-chip OHCI controller on
 	  EP93XX chips.
 
+config USB_OHCI_HCD_PXA27X
+	tristate "Support for PXA27X/PXA3XX on-chip OHCI USB controller"
+	depends on USB_OHCI_HCD && (PXA27x || PXA3xx)
+	default y
+	---help---
+	  Enables support for the on-chip OHCI controller on
+	  PXA27x/PXA3xx chips.
+
 config USB_OHCI_HCD_AT91
         tristate "Support for Atmel on-chip OHCI USB controller"
         depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 02f9cd2..8fcb8da 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
 obj-$(CONFIG_USB_OHCI_HCD_S3C2410)	+= ohci-s3c2410.o
 obj-$(CONFIG_USB_OHCI_HCD_LPC32XX)	+= ohci-nxp.o
 obj-$(CONFIG_USB_OHCI_HCD_EP93XX)	+= ohci-ep93xx.o
+obj-$(CONFIG_USB_OHCI_HCD_PXA27X)	+= ohci-pxa27x.o
 
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 2ee3171..c6fff6e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1177,11 +1177,6 @@ MODULE_LICENSE ("GPL");
 #define SA1111_DRIVER		ohci_hcd_sa1111_driver
 #endif
 
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-#include "ohci-pxa27x.c"
-#define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver
-#endif
-
 #ifdef CONFIG_ARCH_DAVINCI_DA8XX
 #include "ohci-da8xx.c"
 #define DAVINCI_PLATFORM_DRIVER	ohci_hcd_da8xx_driver
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 93371a2..c1b1fa3 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -19,15 +19,26 @@
  * This file is licenced under the GPL.
  */
 
-#include <linux/device.h>
-#include <linux/signal.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
-#include <mach/hardware.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 #include <linux/platform_data/usb-pxa3xx-ulpi.h>
+#include <linux/platform_device.h>
+#include <linux/signal.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/otg.h>
+
+#include <mach/hardware.h>
+
+#include "ohci.h"
+
+#define DRIVER_DESC "OHCI PXA27x/PXA3x driver"
 
 /*
  * UHC: USB Host Controller (OHCI-like) register definitions
@@ -101,16 +112,16 @@
 
 #define PXA_UHC_MAX_PORTNUM    3
 
-struct pxa27x_ohci {
-	/* must be 1st member here for hcd_to_ohci() to work */
-	struct ohci_hcd ohci;
+static const char hcd_name[] = "ohci-pxa27x";
 
-	struct device	*dev;
+static struct hc_driver __read_mostly ohci_pxa27x_hc_driver;
+
+struct pxa27x_ohci {
 	struct clk	*clk;
 	void __iomem	*mmio_base;
 };
 
-#define to_pxa27x_ohci(hcd)	(struct pxa27x_ohci *)hcd_to_ohci(hcd)
+#define to_pxa27x_ohci(hcd)	(struct pxa27x_ohci *)(hcd_to_ohci(hcd)->priv)
 
 /*
   PMM_NPS_MODE -- PMM Non-power switching mode
@@ -122,10 +133,10 @@ struct pxa27x_ohci {
   PMM_PERPORT_MODE -- PMM per port switching mode
       Ports are powered individually.
  */
-static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *ohci, int mode)
+static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *pxa_ohci, int mode)
 {
-	uint32_t uhcrhda = __raw_readl(ohci->mmio_base + UHCRHDA);
-	uint32_t uhcrhdb = __raw_readl(ohci->mmio_base + UHCRHDB);
+	uint32_t uhcrhda = __raw_readl(pxa_ohci->mmio_base + UHCRHDA);
+	uint32_t uhcrhdb = __raw_readl(pxa_ohci->mmio_base + UHCRHDB);
 
 	switch (mode) {
 	case PMM_NPS_MODE:
@@ -149,20 +160,18 @@ static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *ohci, int mode)
 		uhcrhda |= RH_A_NPS;
 	}
 
-	__raw_writel(uhcrhda, ohci->mmio_base + UHCRHDA);
-	__raw_writel(uhcrhdb, ohci->mmio_base + UHCRHDB);
+	__raw_writel(uhcrhda, pxa_ohci->mmio_base + UHCRHDA);
+	__raw_writel(uhcrhdb, pxa_ohci->mmio_base + UHCRHDB);
 	return 0;
 }
 
-extern int usb_disabled(void);
-
 /*-------------------------------------------------------------------------*/
 
-static inline void pxa27x_setup_hc(struct pxa27x_ohci *ohci,
+static inline void pxa27x_setup_hc(struct pxa27x_ohci *pxa_ohci,
 				   struct pxaohci_platform_data *inf)
 {
-	uint32_t uhchr = __raw_readl(ohci->mmio_base + UHCHR);
-	uint32_t uhcrhda = __raw_readl(ohci->mmio_base + UHCRHDA);
+	uint32_t uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR);
+	uint32_t uhcrhda = __raw_readl(pxa_ohci->mmio_base + UHCRHDA);
 
 	if (inf->flags & ENABLE_PORT1)
 		uhchr &= ~UHCHR_SSEP1;
@@ -194,17 +203,17 @@ static inline void pxa27x_setup_hc(struct pxa27x_ohci *ohci,
 		uhcrhda |= UHCRHDA_POTPGT(inf->power_on_delay / 2);
 	}
 
-	__raw_writel(uhchr, ohci->mmio_base + UHCHR);
-	__raw_writel(uhcrhda, ohci->mmio_base + UHCRHDA);
+	__raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR);
+	__raw_writel(uhcrhda, pxa_ohci->mmio_base + UHCRHDA);
 }
 
-static inline void pxa27x_reset_hc(struct pxa27x_ohci *ohci)
+static inline void pxa27x_reset_hc(struct pxa27x_ohci *pxa_ohci)
 {
-	uint32_t uhchr = __raw_readl(ohci->mmio_base + UHCHR);
+	uint32_t uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR);
 
-	__raw_writel(uhchr | UHCHR_FHR, ohci->mmio_base + UHCHR);
+	__raw_writel(uhchr | UHCHR_FHR, pxa_ohci->mmio_base + UHCHR);
 	udelay(11);
-	__raw_writel(uhchr & ~UHCHR_FHR, ohci->mmio_base + UHCHR);
+	__raw_writel(uhchr & ~UHCHR_FHR, pxa_ohci->mmio_base + UHCHR);
 }
 
 #ifdef CONFIG_PXA27x
@@ -213,25 +222,26 @@ extern void pxa27x_clear_otgph(void);
 #define pxa27x_clear_otgph()	do {} while (0)
 #endif
 
-static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev)
+static int pxa27x_start_hc(struct pxa27x_ohci *pxa_ohci, struct device *dev)
 {
 	int retval = 0;
 	struct pxaohci_platform_data *inf;
 	uint32_t uhchr;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
 
 	inf = dev_get_platdata(dev);
 
-	clk_prepare_enable(ohci->clk);
+	clk_prepare_enable(pxa_ohci->clk);
 
-	pxa27x_reset_hc(ohci);
+	pxa27x_reset_hc(pxa_ohci);
 
-	uhchr = __raw_readl(ohci->mmio_base + UHCHR) | UHCHR_FSBIR;
-	__raw_writel(uhchr, ohci->mmio_base + UHCHR);
+	uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR) | UHCHR_FSBIR;
+	__raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR);
 
-	while (__raw_readl(ohci->mmio_base + UHCHR) & UHCHR_FSBIR)
+	while (__raw_readl(pxa_ohci->mmio_base + UHCHR) & UHCHR_FSBIR)
 		cpu_relax();
 
-	pxa27x_setup_hc(ohci, inf);
+	pxa27x_setup_hc(pxa_ohci, inf);
 
 	if (inf->init)
 		retval = inf->init(dev);
@@ -240,38 +250,39 @@ static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev)
 		return retval;
 
 	if (cpu_is_pxa3xx())
-		pxa3xx_u2d_start_hc(&ohci_to_hcd(&ohci->ohci)->self);
+		pxa3xx_u2d_start_hc(&hcd->self);
 
-	uhchr = __raw_readl(ohci->mmio_base + UHCHR) & ~UHCHR_SSE;
-	__raw_writel(uhchr, ohci->mmio_base + UHCHR);
-	__raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, ohci->mmio_base + UHCHIE);
+	uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR) & ~UHCHR_SSE;
+	__raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR);
+	__raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, pxa_ohci->mmio_base + UHCHIE);
 
 	/* Clear any OTG Pin Hold */
 	pxa27x_clear_otgph();
 	return 0;
 }
 
-static void pxa27x_stop_hc(struct pxa27x_ohci *ohci, struct device *dev)
+static void pxa27x_stop_hc(struct pxa27x_ohci *pxa_ohci, struct device *dev)
 {
 	struct pxaohci_platform_data *inf;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
 	uint32_t uhccoms;
 
 	inf = dev_get_platdata(dev);
 
 	if (cpu_is_pxa3xx())
-		pxa3xx_u2d_stop_hc(&ohci_to_hcd(&ohci->ohci)->self);
+		pxa3xx_u2d_stop_hc(&hcd->self);
 
 	if (inf->exit)
 		inf->exit(dev);
 
-	pxa27x_reset_hc(ohci);
+	pxa27x_reset_hc(pxa_ohci);
 
 	/* Host Controller Reset */
-	uhccoms = __raw_readl(ohci->mmio_base + UHCCOMS) | 0x01;
-	__raw_writel(uhccoms, ohci->mmio_base + UHCCOMS);
+	uhccoms = __raw_readl(pxa_ohci->mmio_base + UHCCOMS) | 0x01;
+	__raw_writel(uhccoms, pxa_ohci->mmio_base + UHCCOMS);
 	udelay(10);
 
-	clk_disable_unprepare(ohci->clk);
+	clk_disable_unprepare(pxa_ohci->clk);
 }
 
 #ifdef CONFIG_OF
@@ -356,7 +367,8 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
 	int retval, irq;
 	struct usb_hcd *hcd;
 	struct pxaohci_platform_data *inf;
-	struct pxa27x_ohci *ohci;
+	struct pxa27x_ohci *pxa_ohci;
+	struct ohci_hcd *ohci;
 	struct resource *r;
 	struct clk *usb_clk;
 
@@ -409,29 +421,31 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
 	}
 
 	/* initialize "struct pxa27x_ohci" */
-	ohci = (struct pxa27x_ohci *)hcd_to_ohci(hcd);
-	ohci->dev = &pdev->dev;
-	ohci->clk = usb_clk;
-	ohci->mmio_base = (void __iomem *)hcd->regs;
+	pxa_ohci = to_pxa27x_ohci(hcd);
+	pxa_ohci->clk = usb_clk;
+	pxa_ohci->mmio_base = (void __iomem *)hcd->regs;
 
-	if ((retval = pxa27x_start_hc(ohci, &pdev->dev)) < 0) {
+	retval = pxa27x_start_hc(pxa_ohci, &pdev->dev);
+	if (retval < 0) {
 		pr_debug("pxa27x_start_hc failed");
 		goto err3;
 	}
 
 	/* Select Power Management Mode */
-	pxa27x_ohci_select_pmm(ohci, inf->port_mode);
+	pxa27x_ohci_select_pmm(pxa_ohci, inf->port_mode);
 
 	if (inf->power_budget)
 		hcd->power_budget = inf->power_budget;
 
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	/* The value of NDP in roothub_a is incorrect on this hardware */
+	ohci = hcd_to_ohci(hcd);
+	ohci->num_ports = 3;
 
 	retval = usb_add_hcd(hcd, irq, 0);
 	if (retval == 0)
 		return retval;
 
-	pxa27x_stop_hc(ohci, &pdev->dev);
+	pxa27x_stop_hc(pxa_ohci, &pdev->dev);
  err3:
 	iounmap(hcd->regs);
  err2:
@@ -459,88 +473,18 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
  */
 void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
-	struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
+	struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd);
 
 	usb_remove_hcd(hcd);
-	pxa27x_stop_hc(ohci, &pdev->dev);
+	pxa27x_stop_hc(pxa_ohci, &pdev->dev);
 	iounmap(hcd->regs);
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	clk_put(pxa_ohci->clk);
 	usb_put_hcd(hcd);
-	clk_put(ohci->clk);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int
-ohci_pxa27x_start (struct usb_hcd *hcd)
-{
-	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ret;
-
-	ohci_dbg (ohci, "ohci_pxa27x_start, ohci:%p", ohci);
-
-	/* The value of NDP in roothub_a is incorrect on this hardware */
-	ohci->num_ports = 3;
-
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
-	if ((ret = ohci_run (ohci)) < 0) {
-		dev_err(hcd->self.controller, "can't start %s",
-			hcd->self.bus_name);
-		ohci_stop (hcd);
-		return ret;
-	}
-
-	return 0;
 }
 
 /*-------------------------------------------------------------------------*/
 
-static const struct hc_driver ohci_pxa27x_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"PXA27x OHCI",
-	.hcd_priv_size =	sizeof(struct pxa27x_ohci),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.start =		ohci_pxa27x_start,
-	.stop =			ohci_stop,
-	.shutdown =		ohci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef  CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
 static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev)
 {
 	pr_debug ("In ohci_hcd_pxa27x_drv_probe");
@@ -563,32 +507,35 @@ static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev)
 static int ohci_hcd_pxa27x_drv_suspend(struct device *dev)
 {
 	struct usb_hcd *hcd = dev_get_drvdata(dev);
-	struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
+	struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd);
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
 
-	if (time_before(jiffies, ohci->ohci.next_statechange))
+	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
-	ohci->ohci.next_statechange = jiffies;
+	ohci->next_statechange = jiffies;
 
-	pxa27x_stop_hc(ohci, dev);
+	pxa27x_stop_hc(pxa_ohci, dev);
 	return 0;
 }
 
 static int ohci_hcd_pxa27x_drv_resume(struct device *dev)
 {
 	struct usb_hcd *hcd = dev_get_drvdata(dev);
-	struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
+	struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd);
 	struct pxaohci_platform_data *inf = dev_get_platdata(dev);
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
 	int status;
 
-	if (time_before(jiffies, ohci->ohci.next_statechange))
+	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
-	ohci->ohci.next_statechange = jiffies;
+	ohci->next_statechange = jiffies;
 
-	if ((status = pxa27x_start_hc(ohci, dev)) < 0)
+	status = pxa27x_start_hc(pxa_ohci, dev);
+	if (status < 0)
 		return status;
 
 	/* Select Power Management Mode */
-	pxa27x_ohci_select_pmm(ohci, inf->port_mode);
+	pxa27x_ohci_select_pmm(pxa_ohci, inf->port_mode);
 
 	ohci_resume(hcd, false);
 	return 0;
@@ -600,9 +547,6 @@ static const struct dev_pm_ops ohci_hcd_pxa27x_pm_ops = {
 };
 #endif
 
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:pxa27x-ohci");
-
 static struct platform_driver ohci_hcd_pxa27x_driver = {
 	.probe		= ohci_hcd_pxa27x_drv_probe,
 	.remove		= ohci_hcd_pxa27x_drv_remove,
@@ -617,3 +561,27 @@ static struct platform_driver ohci_hcd_pxa27x_driver = {
 	},
 };
 
+static const struct ohci_driver_overrides pxa27x_overrides __initconst = {
+	.extra_priv_size =      sizeof(struct pxa27x_ohci),
+};
+
+static int __init ohci_pxa27x_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ohci_init_driver(&ohci_pxa27x_hc_driver, &pxa27x_overrides);
+	return platform_driver_register(&ohci_hcd_pxa27x_driver);
+}
+module_init(ohci_pxa27x_init);
+
+static void __exit ohci_pxa27x_cleanup(void)
+{
+	platform_driver_unregister(&ohci_hcd_pxa27x_driver);
+}
+module_exit(ohci_pxa27x_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pxa27x-ohci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 5/9] USB: OHCI: make ohci-at91 a separate driver
  2013-09-21 11:08   ` [PATCH V5 5/9] USB: OHCI: make ohci-at91 " Manjunath Goudar
@ 2013-09-23 12:22     ` Nicolas Ferre
  2013-09-27 15:10     ` Kevin Hilman
  1 sibling, 0 replies; 110+ messages in thread
From: Nicolas Ferre @ 2013-09-23 12:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 21/09/2013 13:08, Manjunath Goudar :
> Separate the  TI OHCI Atmel host controller driver from ohci-hcd

Why "TI" here? ?


> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM.
>
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
> Acked-by: Alan Stern <stern@rowland.harvard.edu>

Otherwise, seems correct.

Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>

> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Greg KH <greg@kroah.com>
> Cc: linux-usb at vger.kernel.org
>
> V3->V4:
>   - Removed extra space after "tristate".
>   - Removed extra space between function name  and '(' characters.
>   - MODULE_ALIAS line moved to last statement of ohci-at91 file.
>
> V2->V3:
>   -The ohci_restart() function is not required in  current scenario,
>    only discarding connection state of integrated transceivers is sufficient,
>    for this directly handling ohci->hc_control.
>
> V1->V2:
>   -Set non-standard fields in ohci_at91_hc_driver manually, rather than
>    relying on an expanded struct ohci_driver_overrides.
>   -Save orig_ohci_hub_control and orig_ohci_hub_status_data rather than
>    relying on ohci_hub_control and hub_status_data being exported.
>   -ohci_setup() has been removed because it is called in .reset member
>    of the ohci_hc_driver structure.
> ---
>   drivers/usb/host/Kconfig     |    8 +++
>   drivers/usb/host/Makefile    |    1 +
>   drivers/usb/host/ohci-at91.c |  156 +++++++++++++++++++-----------------------
>   drivers/usb/host/ohci-hcd.c  |   18 -----
>   4 files changed, 79 insertions(+), 104 deletions(-)
>
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 00d22f5..6900b72 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -382,6 +382,14 @@ config USB_OHCI_HCD_SPEAR
>             Enables support for the on-chip OHCI controller on
>             ST SPEAr chips.
>
> +config USB_OHCI_HCD_AT91
> +        tristate "Support for Atmel on-chip OHCI USB controller"
> +        depends on USB_OHCI_HCD && ARCH_AT91
> +        default y
> +        ---help---
> +          Enables support for the on-chip OHCI controller on
> +          Atmel chips.
> +
>   config USB_OHCI_HCD_OMAP3
>   	tristate "OHCI support for OMAP3 and later chips"
>   	depends on (ARCH_OMAP3 || ARCH_OMAP4)
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index 9efcb7c..0d7a81a 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -50,6 +50,7 @@ obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o
>   obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o
>   obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o
>   obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o
> +obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o
>
>   obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
>   obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
> diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
> index caa3764..476b5a5 100644
> --- a/drivers/usb/host/ohci-at91.c
> +++ b/drivers/usb/host/ohci-at91.c
> @@ -13,19 +13,24 @@
>    */
>
>   #include <linux/clk.h>
> -#include <linux/platform_device.h>
> +#include <linux/dma-mapping.h>
>   #include <linux/of_platform.h>
>   #include <linux/of_gpio.h>
> +#include <linux/platform_device.h>
>   #include <linux/platform_data/atmel.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/usb.h>
> +#include <linux/usb/hcd.h>
>
>   #include <mach/hardware.h>
>   #include <asm/gpio.h>
>
>   #include <mach/cpu.h>
>
> -#ifndef CONFIG_ARCH_AT91
> -#error "CONFIG_ARCH_AT91 must be defined."
> -#endif
> +
> +#include "ohci.h"
>
>   #define valid_port(index)	((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
>   #define at91_for_each_port(index)	\
> @@ -33,7 +38,17 @@
>
>   /* interface, function and usb clocks; sometimes also an AHB clock */
>   static struct clk *iclk, *fclk, *uclk, *hclk;
> +/* interface and function clocks; sometimes also an AHB clock */
> +
> +#define DRIVER_DESC "OHCI Atmel driver"
> +
> +static const char hcd_name[] = "ohci-atmel";
> +
> +static struct hc_driver __read_mostly ohci_at91_hc_driver;
>   static int clocked;
> +static int (*orig_ohci_hub_control)(struct usb_hcd  *hcd, u16 typeReq,
> +			u16 wValue, u16 wIndex, char *buf, u16 wLength);
> +static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
>
>   extern int usb_disabled(void);
>
> @@ -117,6 +132,8 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
>   static int usb_hcd_at91_probe(const struct hc_driver *driver,
>   			struct platform_device *pdev)
>   {
> +	struct at91_usbh_data *board;
> +	struct ohci_hcd *ohci;
>   	int retval;
>   	struct usb_hcd *hcd = NULL;
>
> @@ -177,8 +194,10 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
>   		}
>   	}
>
> +	board = hcd->self.controller->platform_data;
> +	ohci = hcd_to_ohci(hcd);
> +	ohci->num_ports = board->ports;
>   	at91_start_hc(pdev);
> -	ohci_hcd_init(hcd_to_ohci(hcd));
>
>   	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
>   	if (retval == 0)
> @@ -238,36 +257,6 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd,
>   }
>
>   /*-------------------------------------------------------------------------*/
> -
> -static int
> -ohci_at91_reset (struct usb_hcd *hcd)
> -{
> -	struct at91_usbh_data	*board = dev_get_platdata(hcd->self.controller);
> -	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
> -	int			ret;
> -
> -	if ((ret = ohci_init(ohci)) < 0)
> -		return ret;
> -
> -	ohci->num_ports = board->ports;
> -	return 0;
> -}
> -
> -static int
> -ohci_at91_start (struct usb_hcd *hcd)
> -{
> -	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
> -	int			ret;
> -
> -	if ((ret = ohci_run(ohci)) < 0) {
> -		dev_err(hcd->self.controller, "can't start %s\n",
> -			hcd->self.bus_name);
> -		ohci_stop(hcd);
> -		return ret;
> -	}
> -	return 0;
> -}
> -
>   static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
>   {
>   	if (!valid_port(port))
> @@ -297,8 +286,8 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
>    */
>   static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
>   {
> -	struct at91_usbh_data *pdata = dev_get_platdata(hcd->self.controller);
> -	int length = ohci_hub_status_data(hcd, buf);
> +	struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
> +	int length = orig_ohci_hub_status_data(hcd, buf);
>   	int port;
>
>   	at91_for_each_port(port) {
> @@ -376,7 +365,8 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
>   		break;
>   	}
>
> -	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
> +	ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex + 1,
> +				buf, wLength);
>   	if (ret)
>   		goto out;
>
> @@ -430,51 +420,6 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
>
>   /*-------------------------------------------------------------------------*/
>
> -static const struct hc_driver ohci_at91_hc_driver = {
> -	.description =		hcd_name,
> -	.product_desc =		"AT91 OHCI",
> -	.hcd_priv_size =	sizeof(struct ohci_hcd),
> -
> -	/*
> -	 * generic hardware linkage
> -	 */
> -	.irq =			ohci_irq,
> -	.flags =		HCD_USB11 | HCD_MEMORY,
> -
> -	/*
> -	 * basic lifecycle operations
> -	 */
> -	.reset =		ohci_at91_reset,
> -	.start =		ohci_at91_start,
> -	.stop =			ohci_stop,
> -	.shutdown =		ohci_shutdown,
> -
> -	/*
> -	 * managing i/o requests and associated device resources
> -	 */
> -	.urb_enqueue =		ohci_urb_enqueue,
> -	.urb_dequeue =		ohci_urb_dequeue,
> -	.endpoint_disable =	ohci_endpoint_disable,
> -
> -	/*
> -	 * scheduling support
> -	 */
> -	.get_frame_number =	ohci_get_frame,
> -
> -	/*
> -	 * root hub support
> -	 */
> -	.hub_status_data =	ohci_at91_hub_status_data,
> -	.hub_control =		ohci_at91_hub_control,
> -#ifdef CONFIG_PM
> -	.bus_suspend =		ohci_bus_suspend,
> -	.bus_resume =		ohci_bus_resume,
> -#endif
> -	.start_port_reset =	ohci_start_port_reset,
> -};
> -
> -/*-------------------------------------------------------------------------*/
> -
>   static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
>   {
>   	struct platform_device *pdev = data;
> @@ -703,7 +648,11 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
>   	 * REVISIT: some boards will be able to turn VBUS off...
>   	 */
>   	if (at91_suspend_entering_slow_clock()) {
> -		ohci_usb_reset (ohci);
> +		ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
> +		ohci->hc_control &= OHCI_CTRL_RWC;
> +		ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
> +		ohci->rh_state = OHCI_RH_HALTED;
> +
>   		/* flush the writes */
>   		(void) ohci_readl (ohci, &ohci->regs->control);
>   		at91_stop_clock();
> @@ -730,8 +679,6 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
>   #define ohci_hcd_at91_drv_resume  NULL
>   #endif
>
> -MODULE_ALIAS("platform:at91_ohci");
> -
>   static struct platform_driver ohci_hcd_at91_driver = {
>   	.probe		= ohci_hcd_at91_drv_probe,
>   	.remove		= ohci_hcd_at91_drv_remove,
> @@ -744,3 +691,40 @@ static struct platform_driver ohci_hcd_at91_driver = {
>   		.of_match_table	= of_match_ptr(at91_ohci_dt_ids),
>   	},
>   };
> +
> +static int __init ohci_at91_init(void)
> +{
> +	if (usb_disabled())
> +		return -ENODEV;
> +
> +	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
> +	ohci_init_driver(&ohci_at91_hc_driver, NULL);
> +
> +	/*
> +	 * The Atmel HW has some unusual quirks, which require Atmel-specific
> +	 * workarounds. We override certain hc_driver functions here to
> +	 * achieve that. We explicitly do not enhance ohci_driver_overrides to
> +	 * allow this more easily, since this is an unusual case, and we don't
> +	 * want to encourage others to override these functions by making it
> +	 * too easy.
> +	 */
> +
> +	orig_ohci_hub_control = ohci_at91_hc_driver.hub_control;
> +	orig_ohci_hub_status_data = ohci_at91_hc_driver.hub_status_data;
> +
> +	ohci_at91_hc_driver.hub_status_data	= ohci_at91_hub_status_data;
> +	ohci_at91_hc_driver.hub_control		= ohci_at91_hub_control;
> +
> +	return platform_driver_register(&ohci_hcd_at91_driver);
> +}
> +module_init(ohci_at91_init);
> +
> +static void __exit ohci_at91_cleanup(void)
> +{
> +	platform_driver_unregister(&ohci_hcd_at91_driver);
> +}
> +module_exit(ohci_at91_cleanup);
> +
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:at91_ohci");
> diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
> index 523f58e..2fdaaf8 100644
> --- a/drivers/usb/host/ohci-hcd.c
> +++ b/drivers/usb/host/ohci-hcd.c
> @@ -1192,11 +1192,6 @@ MODULE_LICENSE ("GPL");
>   #define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver
>   #endif
>
> -#ifdef CONFIG_ARCH_AT91
> -#include "ohci-at91.c"
> -#define AT91_PLATFORM_DRIVER	ohci_hcd_at91_driver
> -#endif
> -
>   #ifdef CONFIG_ARCH_LPC32XX
>   #include "ohci-nxp.c"
>   #define NXP_PLATFORM_DRIVER	usb_hcd_nxp_driver
> @@ -1310,12 +1305,6 @@ static int __init ohci_hcd_mod_init(void)
>   		goto error_ep93xx;
>   #endif
>
> -#ifdef AT91_PLATFORM_DRIVER
> -	retval = platform_driver_register(&AT91_PLATFORM_DRIVER);
> -	if (retval < 0)
> -		goto error_at91;
> -#endif
> -
>   #ifdef NXP_PLATFORM_DRIVER
>   	retval = platform_driver_register(&NXP_PLATFORM_DRIVER);
>   	if (retval < 0)
> @@ -1339,10 +1328,6 @@ static int __init ohci_hcd_mod_init(void)
>   	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
>    error_nxp:
>   #endif
> -#ifdef AT91_PLATFORM_DRIVER
> -	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
> - error_at91:
> -#endif
>   #ifdef EP93XX_PLATFORM_DRIVER
>   	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
>    error_ep93xx:
> @@ -1394,9 +1379,6 @@ static void __exit ohci_hcd_mod_exit(void)
>   #ifdef NXP_PLATFORM_DRIVER
>   	platform_driver_unregister(&NXP_PLATFORM_DRIVER);
>   #endif
> -#ifdef AT91_PLATFORM_DRIVER
> -	platform_driver_unregister(&AT91_PLATFORM_DRIVER);
> -#endif
>   #ifdef EP93XX_PLATFORM_DRIVER
>   	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
>   #endif
>


-- 
Nicolas Ferre

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V5 1/9] USB: OHCI: make ohci-exynos a separate driver
  2013-09-21 11:08   ` [PATCH V5 1/9] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
@ 2013-09-26 16:50     ` Greg KH
  0 siblings, 0 replies; 110+ messages in thread
From: Greg KH @ 2013-09-26 16:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Sep 21, 2013 at 04:38:38PM +0530, Manjunath Goudar wrote:
> Separate the  Samsung OHCI EXYNOS host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM.
> 
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
> Acked-by: Alan Stern <stern@rowland.harvard.edu>
> Acked-by: Jingoo Han <jg1.han@samsung.com>
> Cc: Vivek Gautam <gautam.vivek@samsung.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Cc: Greg KH <greg@kroah.com>
> Cc: linux-usb at vger.kernel.org
> 
> V2->V3:
>  -No major changes only "exynos" written in capital letters
>   in "OHCI exynos driver".
> 
> V1->V2:
>  -exynos_ohci_hcd structure assignment error fixed.
>  -Removed multiple usb_create_hcd() from prob funtion.
>  -platform_set_drvdata() called before exynos_ohci_phy_enable().
>  -ohci_setup() removed because it is called in .reset member
>   of the ohci_hc_driver structure
> ---

In the future, these "version" lines need to go below the cut ("---"),
not above it, as I need to edit these patches by hand to remove them now
:(

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V5 5/9] USB: OHCI: make ohci-at91 a separate driver
  2013-09-21 11:08   ` [PATCH V5 5/9] USB: OHCI: make ohci-at91 " Manjunath Goudar
  2013-09-23 12:22     ` Nicolas Ferre
@ 2013-09-27 15:10     ` Kevin Hilman
  2013-09-27 15:25       ` Greg KH
  2013-09-27 15:38       ` Alan Stern
  1 sibling, 2 replies; 110+ messages in thread
From: Kevin Hilman @ 2013-09-27 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

Manjunath,

Manjunath Goudar <manjunath.goudar@linaro.org> writes:

> Separate the  TI OHCI Atmel host controller driver from ohci-hcd
> host code so that it can be built as a separate driver module.
> This work is part of enabling multi-platform kernels on ARM.

This broke booting on atmel sama5 boards (and likely others with the
same conversion)...

[...]

> +static int __init ohci_at91_init(void)
> +{
> +	if (usb_disabled())
> +		return -ENODEV;
> +
> +	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
> +	ohci_init_driver(&ohci_at91_hc_driver, NULL);

ohci_init_driver() doesn't have any sanity checks for NULL overrides, so
it blindly dereferences and faults.

Some of the other conversions have this same problem (at least omap3).
Did anyone test this series on hardware?

I'm not too familiar with OHCI, but something like the patch below is
probably needed along with this series.

Kevin


>From a3b5cc90e74038a6449fbd25e0d720ea02884f30 Mon Sep 17 00:00:00 2001
From: Kevin Hilman <khilman@linaro.org>
Date: Fri, 27 Sep 2013 08:07:19 -0700
Subject: [PATCH] USB: OHCI: ohci_init_driver(): sanity check overrides

Check for non-NULL overrides before dereferencing since platforms may
pass in NULL overrides.

Signed-off-by: Kevin Hilman <khilman@linaro.org>
---
 drivers/usb/host/ohci-hcd.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 21d937a..8ada13f 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1161,10 +1161,12 @@ void ohci_init_driver(struct hc_driver *drv,
 	/* Copy the generic table to drv and then apply the overrides */
 	*drv = ohci_hc_driver;
 
-	drv->product_desc = over->product_desc;
-	drv->hcd_priv_size += over->extra_priv_size;
-	if (over->reset)
-		drv->reset = over->reset;
+	if (over) {
+		drv->product_desc = over->product_desc;
+		drv->hcd_priv_size += over->extra_priv_size;
+		if (over->reset)
+			drv->reset = over->reset;
+	}
 }
 EXPORT_SYMBOL_GPL(ohci_init_driver);
 
-- 
1.8.3

^ permalink raw reply related	[flat|nested] 110+ messages in thread

* [PATCH V5 5/9] USB: OHCI: make ohci-at91 a separate driver
  2013-09-27 15:10     ` Kevin Hilman
@ 2013-09-27 15:25       ` Greg KH
  2013-09-27 15:37         ` Alan Stern
  2013-09-27 15:38       ` Alan Stern
  1 sibling, 1 reply; 110+ messages in thread
From: Greg KH @ 2013-09-27 15:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 27, 2013 at 08:10:32AM -0700, Kevin Hilman wrote:
> Manjunath,
> 
> Manjunath Goudar <manjunath.goudar@linaro.org> writes:
> 
> > Separate the  TI OHCI Atmel host controller driver from ohci-hcd
> > host code so that it can be built as a separate driver module.
> > This work is part of enabling multi-platform kernels on ARM.
> 
> This broke booting on atmel sama5 boards (and likely others with the
> same conversion)...

Crap.

And it looks like Manjunath is now no longer working at Linaro, so these
patches are "abandoned" :(

Unless someone at Linaro steps up in the next few days to fix these,
I'll have to go revert them all.  Again.

bleah.

greg k-h

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V5 5/9] USB: OHCI: make ohci-at91 a separate driver
  2013-09-27 15:25       ` Greg KH
@ 2013-09-27 15:37         ` Alan Stern
  2013-09-27 15:40           ` Greg KH
  0 siblings, 1 reply; 110+ messages in thread
From: Alan Stern @ 2013-09-27 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 27 Sep 2013, Greg KH wrote:

> On Fri, Sep 27, 2013 at 08:10:32AM -0700, Kevin Hilman wrote:
> > Manjunath,
> > 
> > Manjunath Goudar <manjunath.goudar@linaro.org> writes:
> > 
> > > Separate the  TI OHCI Atmel host controller driver from ohci-hcd
> > > host code so that it can be built as a separate driver module.
> > > This work is part of enabling multi-platform kernels on ARM.
> > 
> > This broke booting on atmel sama5 boards (and likely others with the
> > same conversion)...
> 
> Crap.
> 
> And it looks like Manjunath is now no longer working at Linaro, so these
> patches are "abandoned" :(
> 
> Unless someone at Linaro steps up in the next few days to fix these,
> I'll have to go revert them all.  Again.
> 
> bleah.

It's not so bad as all that.  The patch Kevin wrote duplicates what 
ehci-hcd does.  It's an obvious oversight; I need to work harder at 
keeping the two drivers in sync.

Alan Stern

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V5 5/9] USB: OHCI: make ohci-at91 a separate driver
  2013-09-27 15:10     ` Kevin Hilman
  2013-09-27 15:25       ` Greg KH
@ 2013-09-27 15:38       ` Alan Stern
  1 sibling, 0 replies; 110+ messages in thread
From: Alan Stern @ 2013-09-27 15:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 27 Sep 2013, Kevin Hilman wrote:

> Manjunath,
> 
> Manjunath Goudar <manjunath.goudar@linaro.org> writes:
> 
> > Separate the  TI OHCI Atmel host controller driver from ohci-hcd
> > host code so that it can be built as a separate driver module.
> > This work is part of enabling multi-platform kernels on ARM.
> 
> This broke booting on atmel sama5 boards (and likely others with the
> same conversion)...
> 
> [...]
> 
> > +static int __init ohci_at91_init(void)
> > +{
> > +	if (usb_disabled())
> > +		return -ENODEV;
> > +
> > +	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
> > +	ohci_init_driver(&ohci_at91_hc_driver, NULL);
> 
> ohci_init_driver() doesn't have any sanity checks for NULL overrides, so
> it blindly dereferences and faults.
> 
> Some of the other conversions have this same problem (at least omap3).
> Did anyone test this series on hardware?
> 
> I'm not too familiar with OHCI, but something like the patch below is
> probably needed along with this series.
> 
> Kevin
> 
> 
> From a3b5cc90e74038a6449fbd25e0d720ea02884f30 Mon Sep 17 00:00:00 2001
> From: Kevin Hilman <khilman@linaro.org>
> Date: Fri, 27 Sep 2013 08:07:19 -0700
> Subject: [PATCH] USB: OHCI: ohci_init_driver(): sanity check overrides
> 
> Check for non-NULL overrides before dereferencing since platforms may
> pass in NULL overrides.
> 
> Signed-off-by: Kevin Hilman <khilman@linaro.org>
> ---
>  drivers/usb/host/ohci-hcd.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
> index 21d937a..8ada13f 100644
> --- a/drivers/usb/host/ohci-hcd.c
> +++ b/drivers/usb/host/ohci-hcd.c
> @@ -1161,10 +1161,12 @@ void ohci_init_driver(struct hc_driver *drv,
>  	/* Copy the generic table to drv and then apply the overrides */
>  	*drv = ohci_hc_driver;
>  
> -	drv->product_desc = over->product_desc;
> -	drv->hcd_priv_size += over->extra_priv_size;
> -	if (over->reset)
> -		drv->reset = over->reset;
> +	if (over) {
> +		drv->product_desc = over->product_desc;
> +		drv->hcd_priv_size += over->extra_priv_size;
> +		if (over->reset)
> +			drv->reset = over->reset;
> +	}
>  }
>  EXPORT_SYMBOL_GPL(ohci_init_driver);

Yes, this is exactly what ehci-hcd does and it clearly is necessary.

Acked-by: Alan Stern <stern@rowland.harvard.edu>

^ permalink raw reply	[flat|nested] 110+ messages in thread

* [PATCH V5 5/9] USB: OHCI: make ohci-at91 a separate driver
  2013-09-27 15:37         ` Alan Stern
@ 2013-09-27 15:40           ` Greg KH
  0 siblings, 0 replies; 110+ messages in thread
From: Greg KH @ 2013-09-27 15:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 27, 2013 at 11:37:16AM -0400, Alan Stern wrote:
> On Fri, 27 Sep 2013, Greg KH wrote:
> 
> > On Fri, Sep 27, 2013 at 08:10:32AM -0700, Kevin Hilman wrote:
> > > Manjunath,
> > > 
> > > Manjunath Goudar <manjunath.goudar@linaro.org> writes:
> > > 
> > > > Separate the  TI OHCI Atmel host controller driver from ohci-hcd
> > > > host code so that it can be built as a separate driver module.
> > > > This work is part of enabling multi-platform kernels on ARM.
> > > 
> > > This broke booting on atmel sama5 boards (and likely others with the
> > > same conversion)...
> > 
> > Crap.
> > 
> > And it looks like Manjunath is now no longer working at Linaro, so these
> > patches are "abandoned" :(
> > 
> > Unless someone at Linaro steps up in the next few days to fix these,
> > I'll have to go revert them all.  Again.
> > 
> > bleah.
> 
> It's not so bad as all that.  The patch Kevin wrote duplicates what 
> ehci-hcd does.  It's an obvious oversight; I need to work harder at 
> keeping the two drivers in sync.

Ah, ok, so Kevin's patch should resolve it all?  That's good, I'll go
queue it up.

greg k-h

^ permalink raw reply	[flat|nested] 110+ messages in thread

end of thread, other threads:[~2013-09-27 15:40 UTC | newest]

Thread overview: 110+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-07  6:03 [RFC][PATCH 0/7] USB: OHCI: more bus glues as separate modules Manjunath Goudar
2013-06-07  6:03 ` [RFC][PATCH 1/7] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
2013-06-07 13:49   ` Arnd Bergmann
2013-06-07 17:20   ` Alan Stern
2013-06-07  6:03 ` [RFC][PATCH 2/7] USB: OHCI: make ohci-omap " Manjunath Goudar
2013-06-07 17:37   ` Alan Stern
2013-06-07  6:03 ` [RFC][PATCH 3/7] USB: OHCI: make ohci-omap3 " Manjunath Goudar
2013-06-07 13:51   ` Arnd Bergmann
2013-06-07 17:49   ` Alan Stern
2013-06-07  6:03 ` [RFC][PATCH 4/7] USB: OHCI: make ohci-spear " Manjunath Goudar
2013-06-07 10:30   ` Viresh Kumar
2013-06-07 18:34   ` Alan Stern
2013-06-07  6:03 ` [RFC][PATCH 5/7] USB: OHCI: export ohci_hub_control and ohci_hub_status_data Manjunath Goudar
2013-06-07 18:42   ` Alan Stern
2013-06-07  6:03 ` [RFC][PATCH 6/7] USB: OHCI: make ohci-at91 a separate driver Manjunath Goudar
2013-06-07 18:52   ` Alan Stern
2013-06-07  6:03 ` [RFC][PATCH 7/7] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
2013-06-07 13:56   ` Arnd Bergmann
2013-06-07 18:54   ` Alan Stern
2013-06-12 15:53 ` [PATCH V2 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
2013-06-12 15:53   ` [PATCH V2 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
2013-06-18 17:30     ` Alan Stern
2013-06-20  4:10     ` Jingoo Han
2013-06-12 15:53   ` [PATCH V2 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
2013-06-18 17:47     ` Alan Stern
2013-06-18 18:13     ` Alan Stern
2013-06-12 15:53   ` [PATCH V2 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
2013-06-18 18:16     ` Alan Stern
2013-06-12 15:54   ` [PATCH V2 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
2013-06-18 18:23     ` Alan Stern
2013-06-12 15:54   ` [PATCH V2 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
2013-06-19 20:16     ` Alan Stern
2013-06-12 15:54   ` [PATCH V2 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
2013-06-19 20:38     ` Alan Stern
2013-06-25  6:23 ` [PATCH V3 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
2013-06-25  6:23   ` [PATCH V3 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
2013-06-25  6:23   ` [PATCH V3 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
2013-07-18 15:50     ` Alan Stern
2013-06-25  6:23   ` [PATCH V3 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
2013-06-25 18:14     ` Alan Stern
2013-06-25  6:23   ` [PATCH V3 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
2013-06-25  6:23   ` [PATCH V3 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
2013-07-18 20:51     ` Alan Stern
2013-06-25  6:23   ` [PATCH V3 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
2013-07-18 20:38     ` Alan Stern
2013-07-22  9:19 ` [PATCH 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
2013-07-22  9:19   ` [PATCH 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
2013-07-22  9:19   ` [PATCH 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
2013-07-23 18:39     ` Alan Stern
2013-07-22  9:19   ` [PATCH 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
2013-07-23 18:43     ` Alan Stern
2013-07-22  9:19   ` [PATCH 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
2013-07-22  9:19   ` [PATCH 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
2013-07-23 18:45     ` Alan Stern
2013-07-22  9:19   ` [PATCH 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
2013-07-23  8:23     ` Tomasz Figa
2013-07-22  9:41   ` [PATCH V4 0/6] USB: OHCI: more bus glues as separate modules manjunath
2013-07-31  6:07 ` Manjunath Goudar
2013-07-31  6:07   ` [PATCH V4 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
2013-07-31  6:08   ` [PATCH V4 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
2013-07-31  6:08   ` [PATCH V4 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
2013-07-31  6:08   ` [PATCH V4 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
2013-07-31  6:08   ` [PATCH V4 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
2013-07-31  6:08   ` [PATCH V4 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
2013-08-10  7:37 ` [PATCH V4 0/6] USB: OHCI: more bus glues as separate modules Manjunath Goudar
2013-08-10  7:37   ` [PATCH V4 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
2013-08-10  7:37   ` [PATCH V4 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
2013-08-10  7:37   ` [PATCH V4 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
2013-08-10  7:37   ` [PATCH V4 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
2013-08-10  7:37   ` [PATCH V4 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
2013-08-10  7:37   ` [PATCH V4 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
2013-08-10 10:53     ` Tomasz Figa
2013-08-12  6:46 ` [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules Manjunath Goudar
2013-08-12  6:46   ` [PATCH V5 1/6] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
2013-08-12  6:46   ` [PATCH V5 2/6] USB: OHCI: make ohci-omap " Manjunath Goudar
2013-08-12  6:46   ` [PATCH V5 3/6] USB: OHCI: make ohci-omap3 " Manjunath Goudar
2013-08-12  6:46   ` [PATCH V5 4/6] USB: OHCI: make ohci-spear " Manjunath Goudar
2013-08-12  6:56     ` Viresh Kumar
2013-08-12 20:20       ` Greg KH
2013-08-12  6:46   ` [PATCH V5 5/6] USB: OHCI: make ohci-at91 " Manjunath Goudar
2013-08-12  6:47   ` [PATCH V5 6/6] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
2013-08-17 13:21     ` Tomasz Figa
2013-08-12  6:54   ` [PATCH V5 0/6]USB: OHCI: more bus glues as separate modules Viresh Kumar
2013-09-16 10:10 ` [PATCH V5 0/9] USB: " Manjunath Goudar
2013-09-16 10:10   ` [PATCH V5 1/9] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
2013-09-16 10:10   ` [PATCH V5 2/9] USB: OHCI: make ohci-omap " Manjunath Goudar
2013-09-16 10:10   ` [PATCH V5 3/9] USB: OHCI: make ohci-omap3 " Manjunath Goudar
2013-09-16 10:10   ` [PATCH V5 4/9] USB: OHCI: make ohci-spear " Manjunath Goudar
2013-09-16 10:10   ` [PATCH V5 5/9] USB: OHCI: make ohci-at91 " Manjunath Goudar
2013-09-16 10:10   ` [PATCH V5 6/9] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
2013-09-16 10:10   ` [PATCH V5 7/9] USB: OHCI: make ohci-nxp " Manjunath Goudar
2013-09-16 10:10   ` [PATCH V5 8/9] USB: OHCI: make ohci-ep93xx " Manjunath Goudar
2013-09-16 10:10   ` [PATCH V5 9/9] USB: OHCI: make ohci-pxa27x " Manjunath Goudar
2013-09-21 11:08 ` [PATCH V5 0/9] USB: OHCI: more bus glues as separate modules Manjunath Goudar
2013-09-21 11:08   ` [PATCH V5 1/9] USB: OHCI: make ohci-exynos a separate driver Manjunath Goudar
2013-09-26 16:50     ` Greg KH
2013-09-21 11:08   ` [PATCH V5 2/9] USB: OHCI: make ohci-omap " Manjunath Goudar
2013-09-21 11:08   ` [PATCH V5 3/9] USB: OHCI: make ohci-omap3 " Manjunath Goudar
2013-09-21 11:08   ` [PATCH V5 4/9] USB: OHCI: make ohci-spear " Manjunath Goudar
2013-09-21 11:08   ` [PATCH V5 5/9] USB: OHCI: make ohci-at91 " Manjunath Goudar
2013-09-23 12:22     ` Nicolas Ferre
2013-09-27 15:10     ` Kevin Hilman
2013-09-27 15:25       ` Greg KH
2013-09-27 15:37         ` Alan Stern
2013-09-27 15:40           ` Greg KH
2013-09-27 15:38       ` Alan Stern
2013-09-21 11:08   ` [PATCH V5 6/9] USB: OHCI: make ohci-s3c2410 " Manjunath Goudar
2013-09-21 11:08   ` [PATCH V5 7/9] USB: OHCI: make ohci-nxp " Manjunath Goudar
2013-09-21 11:08   ` [PATCH V5 8/9] USB: OHCI: make ohci-ep93xx " Manjunath Goudar
2013-09-21 11:08   ` [PATCH V5 9/9] USB: OHCI: make ohci-pxa27x " Manjunath Goudar

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.