This series of patches begins the process of splitting ohci-hcd up into a core library module and independent pci driver modules.
Patch 1/3 prepares the way by exporting a few functions from ohci-hcd and adding a new mechanism for platform-specific drivers to initialize their hc_driver structures. This deserves to be done in the core because almost all of the entries in these structures are pure boilerplate -- practically none of the drivers need to override more than three of the standard core values.
Change from V7 to V8 ohci_hcd_init() is called by ohci_setup() to make generic ohci initialization in all ohci drivers.
Patch 2/3 is part of separating the ohci pci host controller driver from ohci-hcd host code. Moved sb800_prefetch() function from ohci-pci.c to pci-quirks.c file and EXPORTed, this is part of the effort to move the ohci pci related code to generic pci code.
Change from V7 to V8 no change.
Patch 3/3 separate out ohci-pci into independent driver modules.
Change from V7 to V8 USB_OHCI_HCD_PCI symbol no longer dependence on STB03xxx, PPC_MPC52xx and USB_OHCI_HCD_PPC_OF that's what removed.
Manjunath Goudar (3): USB: OHCI: prepare to make ohci-hcd a library module USB: OHCI: Generic changes to make ohci-pci a separate driver USB: OHCI: make ohci-pci a separate driver
drivers/usb/host/Kconfig | 6 +- drivers/usb/host/Makefile | 3 + drivers/usb/host/ohci-hcd.c | 134 ++++++++++++++++++++++++++---------- drivers/usb/host/ohci-hub.c | 1 - drivers/usb/host/ohci-pci.c | 151 ++++++++++++----------------------------- drivers/usb/host/ohci-q.c | 6 +- drivers/usb/host/ohci.h | 17 +++++ drivers/usb/host/pci-quirks.c | 13 ++++ drivers/usb/host/pci-quirks.h | 2 + 9 files changed, 184 insertions(+), 149 deletions(-)
This patch prepares ohci-hcd for being split up into a core library and separate platform driver modules. A generic ohci_hc_driver structure is created, containing all the "standard" values, and a new mechanism is added whereby a driver module can specify a set of overrides to those values. In addition the ohci_restart(),ohci_suspend() and ohci_resume() routines need to be EXPORTed for use by the drivers.
Added ohci_setip(() and ohci_start() routine for to start the generic controller rather than each having its own idiosyncratic approach. This allow to clean duplicated code in most of SOC driver
In V2: -ohci_hcd_init() ohci_run() and ohci_stop() are not made non-static. -Adds the ohci_setup() and ohci_start() routine.
In V3: -purpose of ohci_setup() and ohci_start() function description written in the patch description. -ohci_init() are not made non-static but now called beginning of the ohci_restart(). -ohci_run() signature change reverted back. -unrelated changes removed. -duplicate comment line removed. -inline ohci_suspend() and ohci_resume() is not needed so removed from ohci.h file.
In V4: -ohci-init() EXPORTed because it is called by all bus glue modules. -ohci-setup() removed from 1/2 added into 2/2 patch.
In V5: -Again ohci_setup() is added and EXPORTed because to replace the ohci_init() from all bus glues. -ohci_init() is not made non-static function.
In V6: -ohci_init() call is removed from ohci_quirk_nec_worker(), because it is already called in ohci_restart().
In V8: -ohci_hcd_init() is called by ohci_setup() to make generic ohci initialization in all ohci drivers.
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 --- drivers/usb/host/ohci-hcd.c | 105 +++++++++++++++++++++++++++++++++++++++---- drivers/usb/host/ohci-hub.c | 1 - drivers/usb/host/ohci-pci.c | 7 --- drivers/usb/host/ohci.h | 17 +++++++ 4 files changed, 113 insertions(+), 17 deletions(-)
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 9e6de95..2815359 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -79,13 +79,7 @@ static const char hcd_name [] = "ohci_hcd"; #include "pci-quirks.h"
static void ohci_dump (struct ohci_hcd *ohci, int verbose); -static int ohci_init (struct ohci_hcd *ohci); static void ohci_stop (struct usb_hcd *hcd); - -#if defined(CONFIG_PM) || defined(CONFIG_PCI) -static int ohci_restart (struct ohci_hcd *ohci); -#endif - #ifdef CONFIG_PCI static void sb800_prefetch(struct ohci_hcd *ohci, int on); #else @@ -768,6 +762,32 @@ retry: return 0; }
+/* ohci_setup routine for generic controller initialization */ + +int ohci_setup(struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + + ohci_hcd_init(ohci); + + return ohci_init(ohci); +} +EXPORT_SYMBOL_GPL(ohci_setup); + +/* ohci_start routine for generic controller start of all OHCI bus glue */ +static int ohci_start(struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + int ret; + + ret = ohci_run(ohci); + if (ret < 0) { + ohci_err(ohci, "can't start\n"); + ohci_stop(hcd); + } + return ret; +} + /*-------------------------------------------------------------------------*/
/* an interrupt happens */ @@ -949,12 +969,13 @@ static void ohci_stop (struct usb_hcd *hcd) #if defined(CONFIG_PM) || defined(CONFIG_PCI)
/* must not be called from interrupt context */ -static int ohci_restart (struct ohci_hcd *ohci) +int ohci_restart(struct ohci_hcd *ohci) { int temp; int i; struct urb_priv *priv;
+ ohci_init(ohci); spin_lock_irq(&ohci->lock); ohci->rh_state = OHCI_RH_HALTED;
@@ -1008,12 +1029,13 @@ static int ohci_restart (struct ohci_hcd *ohci) ohci_dbg(ohci, "restart complete\n"); return 0; } +EXPORT_SYMBOL_GPL(ohci_restart);
#endif
#ifdef CONFIG_PM
-static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup) +int ohci_suspend(struct usb_hcd *hcd, bool do_wakeup) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); unsigned long flags; @@ -1031,9 +1053,10 @@ static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup)
return 0; } +EXPORT_SYMBOL_GPL(ohci_suspend);
-static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated) +int ohci_resume(struct usb_hcd *hcd, bool hibernated) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); int port; @@ -1081,8 +1104,72 @@ static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated)
return 0; } +EXPORT_SYMBOL_GPL(ohci_resume); + +#endif + +/*-------------------------------------------------------------------------*/ + +/* + * Generic structure: This gets copied for platform drivers so that + * individual entries can be overridden as needed. + */
+static const struct hc_driver ohci_hc_driver = { + .description = hcd_name, + .product_desc = "OHCI Host Controller", + .hcd_priv_size = sizeof(struct ohci_hcd), + + /* + * generic hardware linkage + */ + .irq = ohci_irq, + .flags = HCD_MEMORY | HCD_USB11, + + /* + * basic lifecycle operations + */ + .reset = ohci_setup, + .start = ohci_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, +}; + +void ohci_init_driver(struct hc_driver *drv, + const struct ohci_driver_overrides *over) +{ + /* Copy the generic table to drv and then apply the overrides */ + *drv = ohci_hc_driver; + + drv->product_desc = over->product_desc; + drv->hcd_priv_size += over->extra_priv_size; + if (over->reset) + drv->reset = over->reset; +} +EXPORT_SYMBOL_GPL(ohci_init_driver);
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 60ff422..2347ab8 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -176,7 +176,6 @@ __acquires(ohci->lock) if (status == -EBUSY) { if (!autostopped) { spin_unlock_irq (&ohci->lock); - (void) ohci_init (ohci); status = ohci_restart (ohci);
usb_root_hub_lost_power(hcd->self.root_hub); diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 951514e..2c27a5f 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -123,13 +123,6 @@ static void ohci_quirk_nec_worker(struct work_struct *work) struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work); int status;
- status = ohci_init(ohci); - if (status != 0) { - ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n", - "ohci_init", status); - return; - } - status = ohci_restart(ohci); if (status != 0) ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n", diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index d329914..3b58482 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -718,3 +718,20 @@ static inline u32 roothub_status (struct ohci_hcd *hc) { return ohci_readl (hc, &hc->regs->roothub.status); } static inline u32 roothub_portstatus (struct ohci_hcd *hc, int i) { return read_roothub (hc, portstatus [i], 0xffe0fce0); } + +/* Declarations of things exported for use by ohci platform drivers */ + +struct ohci_driver_overrides { + const char *product_desc; + size_t extra_priv_size; + int (*reset)(struct usb_hcd *hcd); +}; + +extern void ohci_init_driver(struct hc_driver *drv, + const struct ohci_driver_overrides *over); +extern int ohci_restart(struct ohci_hcd *ohci); +extern int ohci_setup(struct usb_hcd *hcd); +#ifdef CONFIG_PM +extern int ohci_suspend(struct usb_hcd *hcd, bool do_wakeup); +extern int ohci_resume(struct usb_hcd *hcd, bool hibernated); +#endif
Note that this changes is part of separating the ohci pci host controller driver from ohci-hcd host code. This contains : -Moved sb800_prefetch() function from ohci-pci.c to pci-quirks.c file and EXPORTed, this is part of the effort to move the ohci pci related code to generic pci code. -Passed "device" argument instead of "ohci_hcd" in sb800_prefetch() function to avoid extra include file in pci-quirks.c.
V2: -Passed "device" argment instead of "pci_dev", then we use to_pci_dev() to get the "pci_dev" structure.
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 --- drivers/usb/host/ohci-hcd.c | 9 --------- drivers/usb/host/ohci-pci.c | 13 ------------- drivers/usb/host/ohci-q.c | 6 ++++-- drivers/usb/host/pci-quirks.c | 13 +++++++++++++ drivers/usb/host/pci-quirks.h | 2 ++ 5 files changed, 19 insertions(+), 24 deletions(-)
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 2815359..194ae4a 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -80,15 +80,6 @@ static const char hcd_name [] = "ohci_hcd";
static void ohci_dump (struct ohci_hcd *ohci, int verbose); static void ohci_stop (struct usb_hcd *hcd); -#ifdef CONFIG_PCI -static void sb800_prefetch(struct ohci_hcd *ohci, int on); -#else -static inline void sb800_prefetch(struct ohci_hcd *ohci, int on) -{ - return; -} -#endif -
#include "ohci-hub.c" #include "ohci-dbg.c" diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 2c27a5f..c3fa936 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -168,19 +168,6 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) return 0; }
-static void sb800_prefetch(struct ohci_hcd *ohci, int on) -{ - struct pci_dev *pdev; - u16 misc; - - pdev = to_pci_dev(ohci_to_hcd(ohci)->self.controller); - pci_read_config_word(pdev, 0x50, &misc); - if (on == 0) - pci_write_config_word(pdev, 0x50, misc & 0xfcff); - else - pci_write_config_word(pdev, 0x50, misc | 0x0300); -} - /* List of quirks for OHCI */ static const struct pci_device_id ohci_pci_quirks[] = { { diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 88731b7..df4a670 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -41,6 +41,7 @@ finish_urb(struct ohci_hcd *ohci, struct urb *urb, int status) __releases(ohci->lock) __acquires(ohci->lock) { + struct device *dev = ohci_to_hcd(ohci)->self.controller; // ASSERT (urb->hcpriv != 0);
urb_free_priv (ohci, urb->hcpriv); @@ -55,7 +56,7 @@ __acquires(ohci->lock) if (quirk_amdiso(ohci)) usb_amd_quirk_pll_enable(); if (quirk_amdprefetch(ohci)) - sb800_prefetch(ohci, 0); + sb800_prefetch(dev, 0); } break; case PIPE_INTERRUPT: @@ -580,6 +581,7 @@ static void td_submit_urb ( struct urb *urb ) { struct urb_priv *urb_priv = urb->hcpriv; + struct device *dev = ohci_to_hcd(ohci)->self.controller; dma_addr_t data; int data_len = urb->transfer_buffer_length; int cnt = 0; @@ -689,7 +691,7 @@ static void td_submit_urb ( if (quirk_amdiso(ohci)) usb_amd_quirk_pll_disable(); if (quirk_amdprefetch(ohci)) - sb800_prefetch(ohci, 1); + sb800_prefetch(dev, 1); } periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0 && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0; diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 4c338ec..b9848e4 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -91,6 +91,19 @@ static struct amd_chipset_info {
static DEFINE_SPINLOCK(amd_lock);
+void sb800_prefetch(struct device *dev, int on) +{ + u16 misc; + struct pci_dev *pdev = to_pci_dev(dev); + + pci_read_config_word(pdev, 0x50, &misc); + if (on == 0) + pci_write_config_word(pdev, 0x50, misc & 0xfcff); + else + pci_write_config_word(pdev, 0x50, misc | 0x0300); +} +EXPORT_SYMBOL_GPL(sb800_prefetch); + int usb_amd_find_chipset_info(void) { u8 rev = 0; diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index 7f69a39..4b8a209 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h @@ -11,11 +11,13 @@ void usb_amd_quirk_pll_enable(void); bool usb_is_intel_switchable_xhci(struct pci_dev *pdev); void usb_enable_xhci_ports(struct pci_dev *xhci_pdev); void usb_disable_xhci_ports(struct pci_dev *xhci_pdev); +void sb800_prefetch(struct device *dev, int on); #else static inline void usb_amd_quirk_pll_disable(void) {} static inline void usb_amd_quirk_pll_enable(void) {} static inline void usb_amd_dev_put(void) {} static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {} +static inline void sb800_prefetch(struct device *dev, int on) {} #endif /* CONFIG_PCI */
#endif /* __LINUX_USB_PCI_QUIRKS_H */
This patch splits the PCI portion of ohci-hcd out into its own separate driver module, called ohci-pci.
The major point of difficulty lies in ohci-pci's many vendor- and device-specific workarounds. Some of them have to be applied before calling ohci_start() some after, which necessitates a fair amount of code motion. The other platform drivers require much smaller changes.
The complete sb800_prefetch() function moved to ohci-q.c,because its only related to ohci-pci driver.
USB_OHCI_HCD_PCI symbol no longer dependence on STB03xxx, PPC_MPC52xx and USB_OHCI_HCD_PPC_OF that's what removed.
V2: - few specific content of pci related code in ohci_pci_start function has been moved to ohci_pci_reset and rest of the generic code is written in ohci_start of ohci-hcd.c file. V3: - ohci_restart() has been called in ohci_pci_reset() function for to reset the ohci pci.
V4: -sb800_prefetch() moved to ohci-q.c,because its only related to ohci-pci. -no longer _creating_ CONFIG_USB_OHCI_PCI,creating CONFIG_USB_OHCI_HCD_PCI. -overrides renamed with pci_override,its giving proper meaning.
V5: -sb800_prefetch() moved to pci-quirks.c,because its only related to pci.
V6: -sb800_prefetch() function has been moved to pci-quirks.c made as separate patch in 2/3. -Most of the generic ohci pci changes moved in 2/3 patch,now this is complete ohci-pci separation patch.
V7: -Unrelated include file has been removed from ohci.h file.
V8: -USB_OHCI_HCD_PCI symbol does not dependence on STB03xxx, PPC_MPC52xx and USB_OHCI_HCD_PPC_OF.
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 | 6 +- drivers/usb/host/Makefile | 3 + drivers/usb/host/ohci-hcd.c | 20 +------ drivers/usb/host/ohci-pci.c | 131 +++++++++++++++---------------------------- 4 files changed, 52 insertions(+), 108 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 64d7209..a0a2f3a 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -377,7 +377,7 @@ config USB_FUSBH200_HCD module will be called fusbh200-hcd.
config USB_OHCI_HCD - tristate "OHCI HCD support" + tristate "OHCI HCD (USB 1.1) support" depends on USB_ARCH_HAS_OHCI select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 depends on USB_ISP1301 || !ARCH_LPC32XX @@ -446,8 +446,8 @@ config USB_OHCI_HCD_PPC_OF default USB_OHCI_HCD_PPC_OF_BE || USB_OHCI_HCD_PPC_OF_LE
config USB_OHCI_HCD_PCI - bool "OHCI support for PCI-bus USB controllers" - depends on PCI && (STB03xxx || PPC_MPC52xx || USB_OHCI_HCD_PPC_OF) + tristate "OHCI support for PCI-bus USB controllers" + depends on PCI default y select USB_OHCI_LITTLE_ENDIAN ---help--- diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 661c558..2214ded 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -42,7 +42,10 @@ obj-$(CONFIG_USB_EHCI_TEGRA) +=ehci-tegra.o obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o + obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o +obj-$(CONFIG_USB_OHCI_HCD_PCI) += ohci-pci.o + obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_FHCI_HCD) += fhci.o obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 194ae4a..237be7c 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1168,11 +1168,6 @@ MODULE_AUTHOR (DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE ("GPL");
-#ifdef CONFIG_PCI -#include "ohci-pci.c" -#define PCI_DRIVER ohci_pci_driver -#endif - #if defined(CONFIG_ARCH_SA1100) && defined(CONFIG_SA1111) #include "ohci-sa1111.c" #define SA1111_DRIVER ohci_hcd_sa1111_driver @@ -1268,7 +1263,7 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ohci_platform_driver #endif
-#if !defined(PCI_DRIVER) && \ +#if !IS_ENABLED(CONFIG_USB_OHCI_HCD_PCI) && \ !defined(PLATFORM_DRIVER) && \ !defined(OMAP1_PLATFORM_DRIVER) && \ !defined(OMAP3_PLATFORM_DRIVER) && \ @@ -1343,12 +1338,6 @@ static int __init ohci_hcd_mod_init(void) goto error_sa1111; #endif
-#ifdef PCI_DRIVER - retval = pci_register_driver(&PCI_DRIVER); - if (retval < 0) - goto error_pci; -#endif - #ifdef SM501_OHCI_DRIVER retval = platform_driver_register(&SM501_OHCI_DRIVER); if (retval < 0) @@ -1442,10 +1431,6 @@ static int __init ohci_hcd_mod_init(void) platform_driver_unregister(&SM501_OHCI_DRIVER); error_sm501: #endif -#ifdef PCI_DRIVER - pci_unregister_driver(&PCI_DRIVER); - error_pci: -#endif #ifdef SA1111_DRIVER sa1111_driver_unregister(&SA1111_DRIVER); error_sa1111: @@ -1510,9 +1495,6 @@ static void __exit ohci_hcd_mod_exit(void) #ifdef SM501_OHCI_DRIVER platform_driver_unregister(&SM501_OHCI_DRIVER); #endif -#ifdef PCI_DRIVER - pci_unregister_driver(&PCI_DRIVER); -#endif #ifdef SA1111_DRIVER sa1111_driver_unregister(&SA1111_DRIVER); #endif diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index c3fa936..08613e2 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -14,12 +14,19 @@ * This file is licenced under the GPL. */
-#ifndef CONFIG_PCI -#error "This file is PCI bus glue. CONFIG_PCI must be defined." -#endif - -#include <linux/pci.h> #include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/usb.h> +#include <linux/usb/hcd.h> + +#include "ohci.h" +#include "pci-quirks.h" + +#define DRIVER_DESC "OHCI PCI platform driver" + +static const char hcd_name[] = "ohci-pci";
/*-------------------------------------------------------------------------*/ @@ -229,10 +236,10 @@ static const struct pci_device_id ohci_pci_quirks[] = { static int ohci_pci_reset (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); int ret = 0;
if (hcd->self.controller) { - struct pci_dev *pdev = to_pci_dev(hcd->self.controller); const struct pci_device_id *quirk_id;
quirk_id = pci_match_id(ohci_pci_quirks, pdev); @@ -242,94 +249,25 @@ static int ohci_pci_reset (struct usb_hcd *hcd) ret = quirk(hcd); } } - if (ret == 0) { - ohci_hcd_init (ohci); - return ohci_init (ohci); - } - return ret; -} - - -static int ohci_pci_start (struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - int ret; - -#ifdef CONFIG_PM /* avoid warnings about unused pdev */ - if (hcd->self.controller) { - struct pci_dev *pdev = to_pci_dev(hcd->self.controller); - - /* RWC may not be set for add-in PCI cards, since boot - * firmware probably ignored them. This transfers PCI - * PM wakeup capabilities. - */ - if (device_can_wakeup(&pdev->dev)) - ohci->hc_control |= OHCI_CTRL_RWC; - } -#endif /* CONFIG_PM */
- ret = ohci_run (ohci); - if (ret < 0) { - ohci_err (ohci, "can't start\n"); - ohci_stop (hcd); - } + if (ret == 0) + ret = ohci_setup(hcd); + /* + * After ohci setup RWC may not be set for add-in PCI cards. + * This transfers PCI PM wakeup capabilities. + */ + if (device_can_wakeup(&pdev->dev)) + ohci->hc_control |= OHCI_CTRL_RWC; return ret; }
+static struct hc_driver __read_mostly ohci_pci_hc_driver;
-/*-------------------------------------------------------------------------*/ - -static const struct hc_driver ohci_pci_hc_driver = { - .description = hcd_name, - .product_desc = "OHCI Host Controller", - .hcd_priv_size = sizeof(struct ohci_hcd), - - /* - * generic hardware linkage - */ - .irq = ohci_irq, - .flags = HCD_MEMORY | HCD_USB11, - - /* - * basic lifecycle operations - */ +static const struct ohci_driver_overrides pci_overrides __initconst = { + .product_desc = "OHCI PCI host controller", .reset = ohci_pci_reset, - .start = ohci_pci_start, - .stop = ohci_stop, - .shutdown = ohci_shutdown, - -#ifdef CONFIG_PM - .pci_suspend = ohci_suspend, - .pci_resume = ohci_resume, -#endif - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ohci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, -#ifdef CONFIG_PM - .bus_suspend = ohci_bus_suspend, - .bus_resume = ohci_bus_resume, -#endif - .start_port_reset = ohci_start_port_reset, };
-/*-------------------------------------------------------------------------*/ - - static const struct pci_device_id pci_ids [] = { { /* handle any USB OHCI controller */ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_OHCI, ~0), @@ -357,3 +295,24 @@ static struct pci_driver ohci_pci_driver = { }, #endif }; + +static int __init ohci_pci_init(void) +{ + if (usb_disabled()) + return -ENODEV; + + pr_info("%s: " DRIVER_DESC "\n", hcd_name); + + ohci_init_driver(&ohci_pci_hc_driver, &pci_overrides); + return pci_register_driver(&ohci_pci_driver); +} +module_init(ohci_pci_init); + +static void __exit ohci_pci_cleanup(void) +{ + pci_unregister_driver(&ohci_pci_driver); +} +module_exit(ohci_pci_cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL");
On Tue, 28 May 2013, Manjunath Goudar wrote:
This patch splits the PCI portion of ohci-hcd out into its own separate driver module, called ohci-pci.
The major point of difficulty lies in ohci-pci's many vendor- and device-specific workarounds. Some of them have to be applied before calling ohci_start() some after, which necessitates a fair amount of code motion. The other platform drivers require much smaller changes.
The complete sb800_prefetch() function moved to ohci-q.c,because its only related to ohci-pci driver.
USB_OHCI_HCD_PCI symbol no longer dependence on STB03xxx, PPC_MPC52xx and USB_OHCI_HCD_PPC_OF that's what removed.
V2:
- few specific content of pci related code in ohci_pci_start function has been moved to ohci_pci_reset and rest of the generic code is written in ohci_start of ohci-hcd.c file.
V3:
- ohci_restart() has been called in ohci_pci_reset() function for to reset the ohci pci.
V4: -sb800_prefetch() moved to ohci-q.c,because its only related to ohci-pci. -no longer _creating_ CONFIG_USB_OHCI_PCI,creating CONFIG_USB_OHCI_HCD_PCI. -overrides renamed with pci_override,its giving proper meaning.
V5: -sb800_prefetch() moved to pci-quirks.c,because its only related to pci.
V6: -sb800_prefetch() function has been moved to pci-quirks.c made as separate patch in 2/3. -Most of the generic ohci pci changes moved in 2/3 patch,now this is complete ohci-pci separation patch.
V7: -Unrelated include file has been removed from ohci.h file.
V8: -USB_OHCI_HCD_PCI symbol does not dependence on STB03xxx, PPC_MPC52xx and USB_OHCI_HCD_PPC_OF.
Acked-by: Alan Stern stern@rowland.harvard.edu
On Tuesday 28 May 2013, Manjunath Goudar wrote:
This series of patches begins the process of splitting ohci-hcd up into a core library module and independent pci driver modules.
Seems to basically work now, but I'm getting run-time errors after loading the driver, with patch 1/3 applied:
[15916.438452] input: Logitech USB-PS/2 Optical Mouse as /devices/pci0000:00/0000:00:12.0/usb3/3-1/3-1:1.0/input/input26 [15916.438584] hid-generic 0003:046D:C050.0017: input,hidraw0: USB HID v1.10 Mouse [Logitech USB-PS/2 Optical Mouse] on usb-0000:00:12.0-1/input0 [15917.465597] usb 3-3: new full-speed USB device number 3 using ohci-pci [15917.636712] usb 3-3: New USB device found, idVendor=0ccd, idProduct=0077 [15917.636717] usb 3-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [15917.636721] usb 3-3: Product: USB PnP Sound Device [15917.636724] usb 3-3: Manufacturer: C-Media Electronics Inc. [15917.812827] input: C-Media Electronics Inc. USB PnP Sound Device as /devices/pci0000:00/0000:00:12.0/usb3/3-3/3-3:1.3/input/input27 [15917.812919] hid-generic 0003:0CCD:0077.0018: input,hidraw1: USB HID v1.00 Device [C-Media Electronics Inc. USB PnP Sound Device] on usb-0000:00:12.0-3/input3 [15918.789906] cannot submit urb (err = -18) [15918.790163] cannot submit urb (err = -18) [15918.842095] usb 7-1: new full-speed USB device number 2 using ohci-pci [15919.883135] cannot submit urb (err = -18) [15919.883604] cannot submit urb (err = -18) [15919.883613] cannot submit urb (err = -18) [15919.883616] cannot submit urb (err = -18) [15919.883619] cannot submit urb (err = -18) [15919.883623] cannot submit urb (err = -18) [15919.883626] cannot submit urb (err = -18) [15919.883629] cannot submit urb (err = -18) [15919.883632] cannot submit urb (err = -18) [15919.883639] delay: estimated 354, actual 1 [15919.883644] cannot submit urb (err = -18) [15919.883647] delay: estimated 353, actual 0 [15919.883651] cannot submit urb (err = -18)
Arnd
On Tue, 28 May 2013, Arnd Bergmann wrote:
Seems to basically work now, but I'm getting run-time errors after loading the driver, with patch 1/3 applied:
[15916.438452] input: Logitech USB-PS/2 Optical Mouse as /devices/pci0000:00/0000:00:12.0/usb3/3-1/3-1:1.0/input/input26 [15916.438584] hid-generic 0003:046D:C050.0017: input,hidraw0: USB HID v1.10 Mouse [Logitech USB-PS/2 Optical Mouse] on usb-0000:00:12.0-1/input0 [15917.465597] usb 3-3: new full-speed USB device number 3 using ohci-pci [15917.636712] usb 3-3: New USB device found, idVendor=0ccd, idProduct=0077 [15917.636717] usb 3-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [15917.636721] usb 3-3: Product: USB PnP Sound Device [15917.636724] usb 3-3: Manufacturer: C-Media Electronics Inc. [15917.812827] input: C-Media Electronics Inc. USB PnP Sound Device as /devices/pci0000:00/0000:00:12.0/usb3/3-3/3-3:1.3/input/input27 [15917.812919] hid-generic 0003:0CCD:0077.0018: input,hidraw1: USB HID v1.00 Device [C-Media Electronics Inc. USB PnP Sound Device] on usb-0000:00:12.0-3/input3 [15918.789906] cannot submit urb (err = -18) [15918.790163] cannot submit urb (err = -18) [15918.842095] usb 7-1: new full-speed USB device number 2 using ohci-pci [15919.883135] cannot submit urb (err = -18) [15919.883604] cannot submit urb (err = -18) [15919.883613] cannot submit urb (err = -18) [15919.883616] cannot submit urb (err = -18) [15919.883619] cannot submit urb (err = -18)
Those error messages are annoying; they don't use dev_err(), so they don't include the device and driver names. There's no way to know what they refer to. I rather suspect they come from the usbaudio driver.
When you ran this test, did you have commit 815fa7b91761 applied?
Does the same problem occur without Manjunath's changes?
Alan Stern
On Wednesday 29 May 2013 12:21:02 Alan Stern wrote:
Those error messages are annoying; they don't use dev_err(), so they don't include the device and driver names. There's no way to know what they refer to. I rather suspect they come from the usbaudio driver.
That makes sense. I have a usb audio device, and I don't actually recall getting any sound from my speakers while testing it. I only checked that the mouse was working and assumed that the usb-audio was driven by ehci, but upon closer inspection, they are both on the same OHCI.
When you ran this test, did you have commit 815fa7b91761 applied?
Yes.
Does the same problem occur without Manjunath's changes?
No, it was introduced by the first patch, as I found later.
Arnd
On Wed, 29 May 2013, Arnd Bergmann wrote:
On Wednesday 29 May 2013 12:21:02 Alan Stern wrote:
Those error messages are annoying; they don't use dev_err(), so they don't include the device and driver names. There's no way to know what they refer to. I rather suspect they come from the usbaudio driver.
That makes sense. I have a usb audio device, and I don't actually recall getting any sound from my speakers while testing it. I only checked that the mouse was working and assumed that the usb-audio was driven by ehci, but upon closer inspection, they are both on the same OHCI.
When you ran this test, did you have commit 815fa7b91761 applied?
Yes.
Does the same problem occur without Manjunath's changes?
No, it was introduced by the first patch, as I found later.
I'll try to replicate your result. I don't have my USB audio device here today, so it will have to wait until tomorrow.
Alan Stern
On Wednesday 29 May 2013, Alan Stern wrote:
On Wed, 29 May 2013, Arnd Bergmann wrote:
On Wednesday 29 May 2013 12:21:02 Alan Stern wrote:
Those error messages are annoying; they don't use dev_err(), so they don't include the device and driver names. There's no way to know what they refer to. I rather suspect they come from the usbaudio driver.
That makes sense. I have a usb audio device, and I don't actually recall getting any sound from my speakers while testing it. I only checked that the mouse was working and assumed that the usb-audio was driven by ehci, but upon closer inspection, they are both on the same OHCI.
When you ran this test, did you have commit 815fa7b91761 applied?
Yes.
Does the same problem occur without Manjunath's changes?
No, it was introduced by the first patch, as I found later.
I'll try to replicate your result. I don't have my USB audio device here today, so it will have to wait until tomorrow.
Strange enough, it seems to be working now, on a different base.
The kernel I tried last (based on yesterday's linux-next) also had other issues and was very slow, so it may have been something different.
Arnd
On 30 May 2013 03:32, Arnd Bergmann arnd@arndb.de wrote:
On Wednesday 29 May 2013, Alan Stern wrote:
On Wed, 29 May 2013, Arnd Bergmann wrote:
On Wednesday 29 May 2013 12:21:02 Alan Stern wrote:
Those error messages are annoying; they don't use dev_err(), so they don't include the device and driver names. There's no way to know
what
they refer to. I rather suspect they come from the usbaudio driver.
That makes sense. I have a usb audio device, and I don't actually
recall
getting any sound from my speakers while testing it. I only checked that the mouse was working and assumed that the usb-audio was driven by ehci, but upon closer inspection, they are both on the same OHCI.
When you ran this test, did you have commit 815fa7b91761 applied?
Yes.
Does the same problem occur without Manjunath's changes?
No, it was introduced by the first patch, as I found later.
I'll try to replicate your result. I don't have my USB audio device here today, so it will have to wait until tomorrow.
Strange enough, it seems to be working now, on a different base.
The kernel I tried last (based on yesterday's linux-next) also had other issues and was very slow, so it may have been something different.
Arnd
As I understand by Alan reply,1/3 patch is working properly,if any concerned regarding this patch let me know.
Manjunath Goudar
_______________________________________________
linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
On Thu, 30 May 2013, Arnd Bergmann wrote:
I'll try to replicate your result. I don't have my USB audio device here today, so it will have to wait until tomorrow.
Strange enough, it seems to be working now, on a different base.
The kernel I tried last (based on yesterday's linux-next) also had other issues and was very slow, so it may have been something different.
My test ran successfully, no problems. I guess we can ignore this.
Alan Stern
On Friday 31 May 2013 10:12:38 Alan Stern wrote:
On Thu, 30 May 2013, Arnd Bergmann wrote:
I'll try to replicate your result. I don't have my USB audio device here today, so it will have to wait until tomorrow.
Strange enough, it seems to be working now, on a different base.
The kernel I tried last (based on yesterday's linux-next) also had other issues and was very slow, so it may have been something different.
My test ran successfully, no problems. I guess we can ignore this.
Ok, good.
Arnd