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 (2): USB: OHCI: make ohci-ep93xx a separate driver USB: OHCI: make ohci-pxa27x a separate driver
drivers/usb/host/Kconfig | 16 +++++ drivers/usb/host/Makefile | 2 + drivers/usb/host/ohci-ep93xx.c | 84 ++++++++++------------ drivers/usb/host/ohci-hcd.c | 24 ------- drivers/usb/host/ohci-pxa27x.c | 154 ++++++++++++++++------------------------ 5 files changed, 120 insertions(+), 160 deletions(-)
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 Cc: Arnd Bergmann arnd@arndb.de Cc: Alan Stern stern@rowland.harvard.edu Cc: Greg KH greg@kroah.com Cc: linux-usb@vger.kernel.org --- drivers/usb/host/Kconfig | 8 ++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ohci-ep93xx.c | 84 +++++++++++++++++++--------------------- drivers/usb/host/ohci-hcd.c | 19 --------- 4 files changed, 48 insertions(+), 64 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index bf9a162..35c7001 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -414,6 +414,14 @@ config USB_OHCI_HCD_DA8XX Enables support for the on-chip OHCI controller on DA8xx/OMAP-L1x 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 f8d59371..3fee3ea 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_S3CXXXX) += ohci-s3c2410.o obj-$(CONFIG_USB_OHCI_HCD_LPC32XX) += ohci-nxp.o obj-$(CONFIG_USB_OHCI_HCD_DA8XX) += ohci-da8xx.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 f0aaa48..0c2f6df 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -25,8 +25,21 @@
#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> + +#include "ohci.h" + +#define DRIVER_DESC "OHCI EP93xx driver" + +static const char hcd_name[] = "ohci-ep93xx"; + +static struct hc_driver __read_mostly ohci_ep93xx_hc_driver;
static struct clk *usb_host_clock;
@@ -45,6 +58,7 @@ static int usb_hcd_ep93xx_probe(const struct hc_driver *driver, { int retval; struct usb_hcd *hcd; + struct ohci_hcd *ohci;
if (pdev->resource[1].flags != IORESOURCE_IRQ) { dev_dbg(&pdev->dev, "resource[1] is not IORESOURCE_IRQ\n"); @@ -79,7 +93,10 @@ static int usb_hcd_ep93xx_probe(const struct hc_driver *driver,
ep93xx_start_hc(&pdev->dev);
- ohci_hcd_init(hcd_to_ohci(hcd)); + ohci = hcd_to_ohci(hcd); + ohci->next_statechange = jiffies; + spin_lock_init(&ohci->lock); + INIT_LIST_HEAD(&ohci->pending);
retval = usb_add_hcd(hcd, pdev->resource[1].start, 0); if (retval == 0) @@ -107,48 +124,6 @@ static void usb_hcd_ep93xx_remove(struct usb_hcd *hcd, usb_put_hcd(hcd); }
-static int ohci_ep93xx_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 %s\n", - hcd->self.bus_name); - ohci_stop(hcd); - return ret; - } - - 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, -}; - -extern int usb_disabled(void); - static int ohci_hcd_ep93xx_drv_probe(struct platform_device *pdev) { int ret; @@ -206,7 +181,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, @@ -221,4 +195,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 d514e11..3f46cff 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1189,11 +1189,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_USB_OHCI_HCD_PPC_OF #include "ohci-ppc-of.c" #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver @@ -1284,20 +1279,9 @@ static int __init ohci_hcd_mod_init(void) if (retval < 0) goto error_tmio; #endif - -#ifdef EP93XX_PLATFORM_DRIVER - retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER); - if (retval < 0) - goto error_ep93xx; -#endif - return retval;
/* Error path */ -#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: @@ -1335,9 +1319,6 @@ module_init(ohci_hcd_mod_init);
static void __exit ohci_hcd_mod_exit(void) { -#ifdef EP93XX_PLATFORM_DRIVER - platform_driver_unregister(&EP93XX_PLATFORM_DRIVER); -#endif #ifdef TMIO_OHCI_DRIVER platform_driver_unregister(&TMIO_OHCI_DRIVER); #endif
On Thu, 4 Jul 2013, Manjunath Goudar wrote:
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.
@@ -79,7 +93,10 @@ static int usb_hcd_ep93xx_probe(const struct hc_driver *driver, ep93xx_start_hc(&pdev->dev);
- ohci_hcd_init(hcd_to_ohci(hcd));
- ohci = hcd_to_ohci(hcd);
- ohci->next_statechange = jiffies;
- spin_lock_init(&ohci->lock);
- INIT_LIST_HEAD(&ohci->pending);
retval = usb_add_hcd(hcd, pdev->resource[1].start, 0); if (retval == 0)
Why did you add these lines?
Alan Stern
On 5 July 2013 01:46, Alan Stern stern@rowland.harvard.edu wrote:
On Thu, 4 Jul 2013, Manjunath Goudar wrote:
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.
@@ -79,7 +93,10 @@ static int usb_hcd_ep93xx_probe(const struct
hc_driver *driver,
ep93xx_start_hc(&pdev->dev);
ohci_hcd_init(hcd_to_ohci(hcd));
ohci = hcd_to_ohci(hcd);
ohci->next_statechange = jiffies;
spin_lock_init(&ohci->lock);
INIT_LIST_HEAD(&ohci->pending); retval = usb_add_hcd(hcd, pdev->resource[1].start, 0); if (retval == 0)
Instead of ohci_hcd_ini() function call,wrote above code.
Why did you add these lines?
Alan Stern
On Mon, 8 Jul 2013, Manjunath Goudar wrote:
@@ -79,7 +93,10 @@ static int usb_hcd_ep93xx_probe(const struct
hc_driver *driver,
ep93xx_start_hc(&pdev->dev);
ohci_hcd_init(hcd_to_ohci(hcd));
ohci = hcd_to_ohci(hcd);
ohci->next_statechange = jiffies;
spin_lock_init(&ohci->lock);
INIT_LIST_HEAD(&ohci->pending); retval = usb_add_hcd(hcd, pdev->resource[1].start, 0); if (retval == 0)
Instead of ohci_hcd_ini() function call,wrote above code.
You ought to be aware that usb_add_hcd() will call ohci_setup(), which calls ohci_hcd_init() -- after all, _you_ wrote ohci_setup()!
So what reason is there for doing these things a second time?
Alan Stern
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 Cc: Arnd Bergmann arnd@arndb.de Cc: Greg KH greg@kroah.com Cc: Alan Stern stern@rowland.harvard.edu Cc: linux-usb@vger.kernel.org --- drivers/usb/host/Kconfig | 8 +++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ohci-hcd.c | 5 -- drivers/usb/host/ohci-pxa27x.c | 154 ++++++++++++++++------------------------ 4 files changed, 72 insertions(+), 96 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 35c7001..f6fefa2 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -422,6 +422,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 && ARCH_PXA + 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 3fee3ea..8b7fa89 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_USB_OHCI_HCD_S3CXXXX) += ohci-s3c2410.o obj-$(CONFIG_USB_OHCI_HCD_LPC32XX) += ohci-nxp.o obj-$(CONFIG_USB_OHCI_HCD_DA8XX) += ohci-da8xx.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 3f46cff..f601dde 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1184,11 +1184,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_USB_OHCI_HCD_PPC_OF #include "ohci-ppc-of.c" #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 5fb91f1..791e2b5 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 driver"
/* * UHC: USB Host Controller (OHCI-like) register definitions @@ -101,11 +112,11 @@
#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; }; @@ -154,8 +165,6 @@ static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *ohci, int mode) return 0; }
-extern int usb_disabled(void); - /*-------------------------------------------------------------------------*/
static inline void pxa27x_setup_hc(struct pxa27x_ohci *ohci, @@ -218,6 +227,7 @@ static int pxa27x_start_hc(struct pxa27x_ohci *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->platform_data;
@@ -240,7 +250,7 @@ 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); @@ -254,12 +264,13 @@ static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev) static void pxa27x_stop_hc(struct pxa27x_ohci *ohci, struct device *dev) { struct pxaohci_platform_data *inf; + struct usb_hcd *hcd = dev_get_drvdata(dev); uint32_t uhccoms;
inf = dev->platform_data;
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); @@ -357,6 +368,7 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device struct usb_hcd *hcd; struct pxaohci_platform_data *inf; struct pxa27x_ohci *ohci; + struct ohci_hcd *pxaohci; struct resource *r; struct clk *usb_clk;
@@ -410,7 +422,6 @@ 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;
@@ -425,7 +436,13 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device if (inf->power_budget) hcd->power_budget = inf->power_budget;
- ohci_hcd_init(hcd_to_ohci(hcd)); + pxaohci = hcd_to_ohci(hcd); + pxaohci->next_statechange = jiffies; + spin_lock_init(&pxaohci->lock); + INIT_LIST_HEAD(&pxaohci->pending); + + /* The value of NDP in roothub_a is incorrect on this hardware */ + pxaohci->num_ports = 3;
retval = usb_add_hcd(hcd, irq, 0); if (retval == 0) @@ -471,76 +488,6 @@ void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)
/*-------------------------------------------------------------------------*/
-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"); @@ -565,11 +512,13 @@ 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); bool do_wakeup = device_may_wakeup(dev); + struct ohci_hcd *pxaohci = hcd_to_ohci(hcd); int ret;
- if (time_before(jiffies, ohci->ohci.next_statechange)) + if (time_before(jiffies, pxaohci->next_statechange)) msleep(5); - ohci->ohci.next_statechange = jiffies; + + pxaohci->next_statechange = jiffies;
ret = ohci_suspend(hcd, do_wakeup); if (ret) @@ -584,11 +533,13 @@ 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 pxaohci_platform_data *inf = dev->platform_data; + struct ohci_hcd *pxaohci = hcd_to_ohci(hcd); int status;
- if (time_before(jiffies, ohci->ohci.next_statechange)) + if (time_before(jiffies, pxaohci->next_statechange)) msleep(5); - ohci->ohci.next_statechange = jiffies; + + pxaohci->next_statechange = jiffies;
if ((status = pxa27x_start_hc(ohci, dev)) < 0) return status; @@ -606,9 +557,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, @@ -623,3 +571,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");
On Thu, 4 Jul 2013, Manjunath Goudar wrote:
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.
+config USB_OHCI_HCD_PXA27X
- tristate "Support for PXA27X/PXA3XX on-chip OHCI USB controller"
- depends on USB_OHCI_HCD && ARCH_PXA
Shouldn't the ARCH_PXA part be the same as ...
@@ -1184,11 +1184,6 @@ MODULE_LICENSE ("GPL"); #define SA1111_DRIVER ohci_hcd_sa1111_driver #endif -#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
... this?
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 5fb91f1..791e2b5 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c
Several aspects of this are strange. For example, consider how you used the private part of the ohci_hcd structure and how the variable names are inconsistent with the other OHCI glue drivers.
Alan Stern
On 5 July 2013 02:06, Alan Stern stern@rowland.harvard.edu wrote:
On Thu, 4 Jul 2013, Manjunath Goudar wrote:
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.
+config USB_OHCI_HCD_PXA27X
tristate "Support for PXA27X/PXA3XX on-chip OHCI USB controller"
depends on USB_OHCI_HCD && ARCH_PXA
Ok sure I will use
depends on USB_OHCI_HCD && (CONFIG_PXA27x || CONFIG_PXA3xx)
Shouldn't the ARCH_PXA part be the same as ...
@@ -1184,11 +1184,6 @@ MODULE_LICENSE ("GPL"); #define SA1111_DRIVER ohci_hcd_sa1111_driver #endif
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
... this?
diff --git a/drivers/usb/host/ohci-pxa27x.c
b/drivers/usb/host/ohci-pxa27x.c
index 5fb91f1..791e2b5 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c
Several aspects of this are strange. For example, consider how you used the private part of the ohci_hcd structure and how the variable names are inconsistent with the other OHCI glue drivers.
Here we are considering private date like "clk" and "*mmio_base". These are keeping separate from general ohci_hcd using pxa27x_ohci struct (As EHCI).
In this glue already used ohci as pxa27x_ohci variable that is what I used pxaohci as variable of pxa27x_ohci struct.
Let me know shall I write these information in change log.
Manjunath Goudar
Alan Stern
On Mon, 8 Jul 2013, Manjunath Goudar wrote:
Several aspects of this are strange. For example, consider how you used the private part of the ohci_hcd structure and how the variable names are inconsistent with the other OHCI glue drivers.
Here we are considering private date like "clk" and "*mmio_base". These are keeping separate from general ohci_hcd using pxa27x_ohci struct (As EHCI).
In this glue already used ohci as pxa27x_ohci variable that is what I used pxaohci as variable of pxa27x_ohci struct.
You should make this driver look like all the other glue drivers. That means you should change it so that "ohci" is the name of the struct ohci_hcd variable. You can call the private structure "pxa_ohci". And don't forget the '_' character; without it the variable's name is unreadable.
Also, you should store the private data in the ohci->private region. Change the current code so that it works like the other glue drivers.
Alan Stern
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.
In V2:
patch 1/2: -ohci_hcd_init() statements are removed, because by default it is called in ohci_setup().
Patch 2/2: -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.
Manjunath Goudar (2): USB: OHCI: make ohci-ep93xx a separate driver USB: OHCI: make ohci-pxa27x a separate driver
drivers/usb/host/Kconfig | 16 +++ drivers/usb/host/Makefile | 2 + drivers/usb/host/ohci-ep93xx.c | 81 ++++++-------- drivers/usb/host/ohci-hcd.c | 24 ---- drivers/usb/host/ohci-pxa27x.c | 240 ++++++++++++++++++---------------------- 5 files changed, 158 insertions(+), 205 deletions(-)
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 Cc: Arnd Bergmann arnd@arndb.de Cc: Alan Stern stern@rowland.harvard.edu Cc: Greg KH greg@kroah.com Cc: linux-usb@vger.kernel.org
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 | 81 +++++++++++++++++----------------------- drivers/usb/host/ohci-hcd.c | 19 ---------- 4 files changed, 44 insertions(+), 65 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index f7f7823..cdfaa04 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -414,6 +414,14 @@ config USB_OHCI_HCD_DA8XX Enables support for the on-chip OHCI controller on DA8xx/OMAP-L1x 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 f8d59371..3fee3ea 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_S3CXXXX) += ohci-s3c2410.o obj-$(CONFIG_USB_OHCI_HCD_LPC32XX) += ohci-nxp.o obj-$(CONFIG_USB_OHCI_HCD_DA8XX) += ohci-da8xx.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 f0aaa48..30b0ffe 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -25,8 +25,21 @@
#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> + +#include "ohci.h" + +#define DRIVER_DESC "OHCI EP93xx driver" + +static const char hcd_name[] = "ohci-ep93xx"; + +static struct hc_driver __read_mostly ohci_ep93xx_hc_driver;
static struct clk *usb_host_clock;
@@ -45,6 +58,7 @@ static int usb_hcd_ep93xx_probe(const struct hc_driver *driver, { int retval; struct usb_hcd *hcd; + struct ohci_hcd *ohci;
if (pdev->resource[1].flags != IORESOURCE_IRQ) { dev_dbg(&pdev->dev, "resource[1] is not IORESOURCE_IRQ\n"); @@ -79,8 +93,6 @@ static int usb_hcd_ep93xx_probe(const struct hc_driver *driver,
ep93xx_start_hc(&pdev->dev);
- ohci_hcd_init(hcd_to_ohci(hcd)); - retval = usb_add_hcd(hcd, pdev->resource[1].start, 0); if (retval == 0) return retval; @@ -107,48 +119,6 @@ static void usb_hcd_ep93xx_remove(struct usb_hcd *hcd, usb_put_hcd(hcd); }
-static int ohci_ep93xx_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 %s\n", - hcd->self.bus_name); - ohci_stop(hcd); - return ret; - } - - 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, -}; - -extern int usb_disabled(void); - static int ohci_hcd_ep93xx_drv_probe(struct platform_device *pdev) { int ret; @@ -206,7 +176,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, @@ -221,4 +190,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 d514e11..3f46cff 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1189,11 +1189,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_USB_OHCI_HCD_PPC_OF #include "ohci-ppc-of.c" #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver @@ -1284,20 +1279,9 @@ static int __init ohci_hcd_mod_init(void) if (retval < 0) goto error_tmio; #endif - -#ifdef EP93XX_PLATFORM_DRIVER - retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER); - if (retval < 0) - goto error_ep93xx; -#endif - return retval;
/* Error path */ -#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: @@ -1335,9 +1319,6 @@ module_init(ohci_hcd_mod_init);
static void __exit ohci_hcd_mod_exit(void) { -#ifdef EP93XX_PLATFORM_DRIVER - platform_driver_unregister(&EP93XX_PLATFORM_DRIVER); -#endif #ifdef TMIO_OHCI_DRIVER platform_driver_unregister(&TMIO_OHCI_DRIVER); #endif
On Tue, 23 Jul 2013, Manjunath Goudar wrote:
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 Cc: Arnd Bergmann arnd@arndb.de Cc: Alan Stern stern@rowland.harvard.edu Cc: Greg KH greg@kroah.com Cc: linux-usb@vger.kernel.org
V2: -ohci_hcd_init() statements are removed, because by default it is called in ohci_setup().
@@ -45,6 +58,7 @@ static int usb_hcd_ep93xx_probe(const struct hc_driver *driver, { int retval; struct usb_hcd *hcd;
- struct ohci_hcd *ohci;
if (pdev->resource[1].flags != IORESOURCE_IRQ) { dev_dbg(&pdev->dev, "resource[1] is not IORESOURCE_IRQ\n");
What's that line for? After you remove it, you can add
Acked-by: Alan Stern stern@rowland.harvard.edu
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 Cc: Arnd Bergmann arnd@arndb.de Cc: Greg KH greg@kroah.com Cc: Alan Stern stern@rowland.harvard.edu Cc: linux-usb@vger.kernel.org
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, 114 insertions(+), 140 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index cdfaa04..0d7ee36 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -422,6 +422,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 3fee3ea..8b7fa89 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_USB_OHCI_HCD_S3CXXXX) += ohci-s3c2410.o obj-$(CONFIG_USB_OHCI_HCD_LPC32XX) += ohci-nxp.o obj-$(CONFIG_USB_OHCI_HCD_DA8XX) += ohci-da8xx.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 3f46cff..f601dde 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1184,11 +1184,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_USB_OHCI_HCD_PPC_OF #include "ohci-ppc-of.c" #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 5fb91f1..3d97c63 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,11 +112,11 @@
#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"; + +static struct hc_driver __read_mostly ohci_pxa27x_hc_driver;
- struct device *dev; +struct pxa27x_ohci { struct clk *clk; void __iomem *mmio_base; }; @@ -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->platform_data;
- 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->platform_data;
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 = (struct pxa27x_ohci *)hcd_to_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); 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; + clk_put(pxa_ohci->clk); }
/*-------------------------------------------------------------------------*/
-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,38 +507,43 @@ 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); bool do_wakeup = device_may_wakeup(dev); + struct ohci_hcd *ohci = hcd_to_ohci(hcd); int ret;
- 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;
ret = ohci_suspend(hcd, do_wakeup); if (ret) return ret;
- pxa27x_stop_hc(ohci, dev); + pxa27x_stop_hc(pxa_ohci, dev); return ret; }
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->platform_data; + 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;
- if ((status = pxa27x_start_hc(ohci, dev)) < 0) + ohci->next_statechange = jiffies; + + 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; @@ -606,9 +555,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, @@ -623,3 +569,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");
On Tue, 23 Jul 2013, Manjunath Goudar wrote:
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 Cc: Arnd Bergmann arnd@arndb.de Cc: Greg KH greg@kroah.com Cc: Alan Stern stern@rowland.harvard.edu Cc: linux-usb@vger.kernel.org
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.
There's a couple of small problems...
-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";
+static struct hc_driver __read_mostly ohci_pxa27x_hc_driver;
- struct device *dev;
+struct pxa27x_ohci { struct clk *clk; void __iomem *mmio_base; };
You didn't change the definition of to_pxa27x_ohci.
@@ -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 = (struct pxa27x_ohci *)hcd_to_ohci(hcd);
Use the to_pxa27x_ohci macro.
@@ -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); usb_put_hcd(hcd);
- clk_put(ohci->clk);
...
- clk_put(pxa_ohci->clk);
This line must come before the usb_put_hcd().
Alan Stern
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.
In V2:
patch 1/2: -ohci_hcd_init() statements are removed, because by default it is called in ohci_setup().
Patch 2/2: -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.
In V3:
Patch 1/2: -Unused *ohci variable has been removed.
patch 2/2: -Rewrite the macro definition of to_pxa27x_ohci. -clk_put() function has been called before usb_put_hcd().
Manjunath Goudar (2): USB: OHCI: make ohci-ep93xx a separate driver USB: OHCI: make ohci-pxa27x a separate driver
drivers/usb/host/Kconfig | 16 +++ drivers/usb/host/Makefile | 2 + drivers/usb/host/ohci-ep93xx.c | 80 ++++++------- drivers/usb/host/ohci-hcd.c | 24 ---- drivers/usb/host/ohci-pxa27x.c | 242 ++++++++++++++++++---------------------- 5 files changed, 158 insertions(+), 206 deletions(-)
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 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: -ohci_hcd_init() statements are removed, because by default it is called in ohci_setup().
V3: -Unused *ohci variable has been removed. --- drivers/usb/host/Kconfig | 8 ++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ohci-ep93xx.c | 80 +++++++++++++++++----------------------- drivers/usb/host/ohci-hcd.c | 19 ---------- 4 files changed, 43 insertions(+), 65 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index f7f7823..cdfaa04 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -414,6 +414,14 @@ config USB_OHCI_HCD_DA8XX Enables support for the on-chip OHCI controller on DA8xx/OMAP-L1x 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 f8d59371..3fee3ea 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_S3CXXXX) += ohci-s3c2410.o obj-$(CONFIG_USB_OHCI_HCD_LPC32XX) += ohci-nxp.o obj-$(CONFIG_USB_OHCI_HCD_DA8XX) += ohci-da8xx.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 f0aaa48..7b0e3ae 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -25,8 +25,21 @@
#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> + +#include "ohci.h" + +#define DRIVER_DESC "OHCI EP93xx driver" + +static const char hcd_name[] = "ohci-ep93xx"; + +static struct hc_driver __read_mostly ohci_ep93xx_hc_driver;
static struct clk *usb_host_clock;
@@ -79,8 +92,6 @@ static int usb_hcd_ep93xx_probe(const struct hc_driver *driver,
ep93xx_start_hc(&pdev->dev);
- ohci_hcd_init(hcd_to_ohci(hcd)); - retval = usb_add_hcd(hcd, pdev->resource[1].start, 0); if (retval == 0) return retval; @@ -107,48 +118,6 @@ static void usb_hcd_ep93xx_remove(struct usb_hcd *hcd, usb_put_hcd(hcd); }
-static int ohci_ep93xx_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 %s\n", - hcd->self.bus_name); - ohci_stop(hcd); - return ret; - } - - 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, -}; - -extern int usb_disabled(void); - static int ohci_hcd_ep93xx_drv_probe(struct platform_device *pdev) { int ret; @@ -206,7 +175,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, @@ -221,4 +189,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 d514e11..3f46cff 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1189,11 +1189,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_USB_OHCI_HCD_PPC_OF #include "ohci-ppc-of.c" #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver @@ -1284,20 +1279,9 @@ static int __init ohci_hcd_mod_init(void) if (retval < 0) goto error_tmio; #endif - -#ifdef EP93XX_PLATFORM_DRIVER - retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER); - if (retval < 0) - goto error_ep93xx; -#endif - return retval;
/* Error path */ -#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: @@ -1335,9 +1319,6 @@ module_init(ohci_hcd_mod_init);
static void __exit ohci_hcd_mod_exit(void) { -#ifdef EP93XX_PLATFORM_DRIVER - platform_driver_unregister(&EP93XX_PLATFORM_DRIVER); -#endif #ifdef TMIO_OHCI_DRIVER platform_driver_unregister(&TMIO_OHCI_DRIVER); #endif
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 Cc: Arnd Bergmann arnd@arndb.de Cc: Greg KH greg@kroah.com Cc: Alan Stern stern@rowland.harvard.edu Cc: linux-usb@vger.kernel.org
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.
V3: -Rewrite the macro definition of to_pxa27x_ohci. -clk_put() function has been called before usb_put_hcd(). --- drivers/usb/host/Kconfig | 8 ++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ohci-hcd.c | 5 - drivers/usb/host/ohci-pxa27x.c | 242 ++++++++++++++++++---------------------- 4 files changed, 115 insertions(+), 141 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index cdfaa04..0d7ee36 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -422,6 +422,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 3fee3ea..8b7fa89 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_USB_OHCI_HCD_S3CXXXX) += ohci-s3c2410.o obj-$(CONFIG_USB_OHCI_HCD_LPC32XX) += ohci-nxp.o obj-$(CONFIG_USB_OHCI_HCD_DA8XX) += ohci-da8xx.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 3f46cff..f601dde 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1184,11 +1184,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_USB_OHCI_HCD_PPC_OF #include "ohci-ppc-of.c" #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 5fb91f1..394f221 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"; + +static struct hc_driver __read_mostly ohci_pxa27x_hc_driver;
- struct device *dev; +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->platform_data;
- 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->platform_data;
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,38 +507,43 @@ 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); bool do_wakeup = device_may_wakeup(dev); + struct ohci_hcd *ohci = hcd_to_ohci(hcd); int ret;
- 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;
ret = ohci_suspend(hcd, do_wakeup); if (ret) return ret;
- pxa27x_stop_hc(ohci, dev); + pxa27x_stop_hc(pxa_ohci, dev); return ret; }
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->platform_data; + 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;
- if ((status = pxa27x_start_hc(ohci, dev)) < 0) + ohci->next_statechange = jiffies; + + 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; @@ -606,9 +555,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, @@ -623,3 +569,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");
On Fri, 26 Jul 2013, Manjunath Goudar wrote:
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 Cc: Arnd Bergmann arnd@arndb.de Cc: Greg KH greg@kroah.com Cc: Alan Stern stern@rowland.harvard.edu Cc: linux-usb@vger.kernel.org
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.
V3: -Rewrite the macro definition of to_pxa27x_ohci. -clk_put() function has been called before usb_put_hcd().
Acked-by: Alan Stern stern@rowland.harvard.edu
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.
In V2:
patch 1/2: -ohci_hcd_init() statements are removed, because by default it is called in ohci_setup().
Patch 2/2: -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.
In V3:
Patch 1/2: -Unused *ohci variable has been removed.
patch 2/2: -Rewrite the macro definition of to_pxa27x_ohci. -clk_put() function has been called before usb_put_hcd().
Manjunath Goudar (2): USB: OHCI: make ohci-ep93xx a separate driver USB: OHCI: make ohci-pxa27x a separate driver
drivers/usb/host/Kconfig | 16 +++ drivers/usb/host/Makefile | 2 + drivers/usb/host/ohci-ep93xx.c | 80 ++++++------- drivers/usb/host/ohci-hcd.c | 23 ---- drivers/usb/host/ohci-pxa27x.c | 242 ++++++++++++++++++---------------------- 5 files changed, 158 insertions(+), 205 deletions(-)
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@vger.kernel.org
V2: -ohci_hcd_init() statements are removed, because by default it is called in ohci_setup().
V3: -Unused *ohci variable has been removed. --- drivers/usb/host/Kconfig | 8 ++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ohci-ep93xx.c | 80 +++++++++++++++++----------------------- drivers/usb/host/ohci-hcd.c | 18 --------- 4 files changed, 43 insertions(+), 64 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index f7f7823..cdfaa04 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -414,6 +414,14 @@ config USB_OHCI_HCD_DA8XX Enables support for the on-chip OHCI controller on DA8xx/OMAP-L1x 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 f8d59371..3fee3ea 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_S3CXXXX) += ohci-s3c2410.o obj-$(CONFIG_USB_OHCI_HCD_LPC32XX) += ohci-nxp.o obj-$(CONFIG_USB_OHCI_HCD_DA8XX) += ohci-da8xx.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 f0aaa48..7b0e3ae 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -25,8 +25,21 @@
#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> + +#include "ohci.h" + +#define DRIVER_DESC "OHCI EP93xx driver" + +static const char hcd_name[] = "ohci-ep93xx"; + +static struct hc_driver __read_mostly ohci_ep93xx_hc_driver;
static struct clk *usb_host_clock;
@@ -79,8 +92,6 @@ static int usb_hcd_ep93xx_probe(const struct hc_driver *driver,
ep93xx_start_hc(&pdev->dev);
- ohci_hcd_init(hcd_to_ohci(hcd)); - retval = usb_add_hcd(hcd, pdev->resource[1].start, 0); if (retval == 0) return retval; @@ -107,48 +118,6 @@ static void usb_hcd_ep93xx_remove(struct usb_hcd *hcd, usb_put_hcd(hcd); }
-static int ohci_ep93xx_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 %s\n", - hcd->self.bus_name); - ohci_stop(hcd); - return ret; - } - - 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, -}; - -extern int usb_disabled(void); - static int ohci_hcd_ep93xx_drv_probe(struct platform_device *pdev) { int ret; @@ -206,7 +175,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, @@ -221,4 +189,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 6ae5520..3f46cff 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1189,11 +1189,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_USB_OHCI_HCD_PPC_OF #include "ohci-ppc-of.c" #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver @@ -1284,19 +1279,9 @@ static int __init ohci_hcd_mod_init(void) if (retval < 0) goto error_tmio; #endif - -#ifdef EP93XX_PLATFORM_DRIVER - retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER); - if (retval < 0) - goto error_ep93xx; -#endif return retval;
/* Error path */ -#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: @@ -1334,9 +1319,6 @@ module_init(ohci_hcd_mod_init);
static void __exit ohci_hcd_mod_exit(void) { -#ifdef EP93XX_PLATFORM_DRIVER - platform_driver_unregister(&EP93XX_PLATFORM_DRIVER); -#endif #ifdef TMIO_OHCI_DRIVER platform_driver_unregister(&TMIO_OHCI_DRIVER); #endif
On Sat, Aug 10, 2013 at 01:11:39PM +0530, Manjunath Goudar wrote:
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@vger.kernel.org
V2: -ohci_hcd_init() statements are removed, because by default it is called in ohci_setup().
V3:
-Unused *ohci variable has been removed.
drivers/usb/host/Kconfig | 8 ++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ohci-ep93xx.c | 80 +++++++++++++++++----------------------- drivers/usb/host/ohci-hcd.c | 18 --------- 4 files changed, 43 insertions(+), 64 deletions(-)
This too fails to apply:
$ p1 < ../s1 checking file drivers/usb/host/Kconfig Hunk #1 FAILED at 414. 1 out of 1 hunk FAILED checking file drivers/usb/host/Makefile Hunk #1 FAILED at 54. 1 out of 1 hunk FAILED checking file drivers/usb/host/ohci-ep93xx.c Hunk #2 FAILED at 92. Hunk #3 FAILED at 120. Hunk #4 succeeded at 179 (offset -40 lines). Hunk #5 succeeded at 193 (offset -40 lines). 2 out of 5 hunks FAILED checking file drivers/usb/host/ohci-hcd.c Reversed (or previously applied) patch detected! Assume -R? [n] Apply anyway? [n] Skipping patch. 3 out of 3 hunks ignored
Can you respin _all_ of your pending patches you have sent me in a format that I can apply them, and resend them in a series that shows what should be applied in which order. As it is, I have 3-4 different series of patches from you, with no obvious order which should be applied in which order. Because of that, that might be why these aren't applying.
thanks,
greg k-h
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@vger.kernel.org
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.
V3: -Rewrite the macro definition of to_pxa27x_ohci. -clk_put() function has been called before usb_put_hcd(). --- drivers/usb/host/Kconfig | 8 ++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ohci-hcd.c | 5 - drivers/usb/host/ohci-pxa27x.c | 242 ++++++++++++++++++---------------------- 4 files changed, 115 insertions(+), 141 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index cdfaa04..0d7ee36 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -422,6 +422,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 3fee3ea..8b7fa89 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_USB_OHCI_HCD_S3CXXXX) += ohci-s3c2410.o obj-$(CONFIG_USB_OHCI_HCD_LPC32XX) += ohci-nxp.o obj-$(CONFIG_USB_OHCI_HCD_DA8XX) += ohci-da8xx.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 3f46cff..f601dde 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1184,11 +1184,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_USB_OHCI_HCD_PPC_OF #include "ohci-ppc-of.c" #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 5fb91f1..394f221 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"; + +static struct hc_driver __read_mostly ohci_pxa27x_hc_driver;
- struct device *dev; +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->platform_data;
- 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->platform_data;
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,38 +507,43 @@ 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); bool do_wakeup = device_may_wakeup(dev); + struct ohci_hcd *ohci = hcd_to_ohci(hcd); int ret;
- 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;
ret = ohci_suspend(hcd, do_wakeup); if (ret) return ret;
- pxa27x_stop_hc(ohci, dev); + pxa27x_stop_hc(pxa_ohci, dev); return ret; }
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->platform_data; + 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;
- if ((status = pxa27x_start_hc(ohci, dev)) < 0) + ohci->next_statechange = jiffies; + + 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; @@ -606,9 +555,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, @@ -623,3 +569,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");
linaro-kernel@lists.linaro.org