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(-)
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@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
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@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");
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@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");
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@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");
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.
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
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@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
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@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");
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@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,
goto out; }ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
@@ -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
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 ...
...
linaro-kernel@lists.linaro.org