@@ -79,12 +79,6 @@ 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);
@@ -520,7 +514,7 @@ done:
/* init memory, and kick BIOS/SMM off */
-static int ohci_init (struct ohci_hcd *ohci)
+int ohci_init(struct ohci_hcd *ohci)
{
int ret;
struct usb_hcd *hcd = ohci_to_hcd(ohci);
@@ -590,6 +584,7 @@ static int ohci_init (struct ohci_hcd *ohci)
return ret;
}
+EXPORT_SYMBOL_GPL(ohci_init);
/*-------------------------------------------------------------------------*/
@@ -597,7 +592,7 @@ static int ohci_init (struct ohci_hcd *ohci)
* resets USB and controller
* enable interrupts
*/
-static int ohci_run (struct ohci_hcd *ohci)
+int ohci_run(struct ohci_hcd *ohci)
{
u32 mask, val;
int first = ohci->fminterval == 0;
@@ -767,6 +762,7 @@ retry:
return 0;
}
+EXPORT_SYMBOL_GPL(ohci_run);
/*-------------------------------------------------------------------------*/
@@ -914,7 +910,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
/*-------------------------------------------------------------------------*/
-static void ohci_stop (struct usb_hcd *hcd)
+void ohci_stop(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
@@ -943,13 +939,13 @@ static void ohci_stop (struct usb_hcd *hcd)
ohci->hcca_dma = 0;
}
}
-
+EXPORT_SYMBOL_GPL(ohci_stop);
/*-------------------------------------------------------------------------*/
#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;
@@ -1008,12 +1004,12 @@ 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 +1027,9 @@ 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,11 +1077,73 @@ 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
+ */
+ .start = ohci_run,
+ .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,
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
+ .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;
+ if (over->start)
+ drv->start = over->start;
+}
+EXPORT_SYMBOL_GPL(ohci_init_driver);
+
+/*-------------------------------------------------------------------------*/
+
MODULE_AUTHOR (DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE ("GPL");
@@ -23,12 +23,13 @@
/*-------------------------------------------------------------------------*/
-static void ohci_hcd_init (struct ohci_hcd *ohci)
+void ohci_hcd_init (struct ohci_hcd *ohci)
{
ohci->next_statechange = jiffies;
spin_lock_init (&ohci->lock);
INIT_LIST_HEAD (&ohci->pending);
}
+EXPORT_SYMBOL_GPL(ohci_hcd_init);
/*-------------------------------------------------------------------------*/
@@ -718,3 +718,37 @@ 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);
+ int (*start)(struct usb_hcd *hcd);
+};
+
+extern void ohci_init_driver(struct hc_driver *drv,
+ const struct ohci_driver_overrides *over);
+extern int ohci_init (struct ohci_hcd *ohci);
+extern void ohci_stop (struct usb_hcd *hcd);
+extern void ohci_hcd_init (struct ohci_hcd *ohci);
+extern int ohci_run (struct ohci_hcd *ohci);
+
+#if defined(CONFIG_PM) || defined(CONFIG_PCI)
+extern int ohci_restart (struct ohci_hcd *ohci);
+#endif
+
+#ifdef CONFIG_PM
+extern int ohci_suspend(struct usb_hcd *hcd, bool do_wakeup);
+extern int ohci_resume(struct usb_hcd *hcd, bool hibernated);
+#else
+static inline void ohci_suspend(struct usb_hcd *hcd, bool do_wakeup)
+{
+ return;
+}
+static inline int ohci_resume(struct usb_hcd *hcd, bool hibernated)
+{
+ return;
+}
+#endif
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_init(),ohci_restart(),ohci_hcd_init(),ohci_run() ohci_stop(), ohci_suspend() and ohci_resume() routines need to be EXPORTed for use by the drivers. 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/ohci-hcd.c | 90 +++++++++++++++++++++++++++++++++++-------- drivers/usb/host/ohci-mem.c | 3 +- drivers/usb/host/ohci.h | 34 ++++++++++++++++ 3 files changed, 110 insertions(+), 17 deletions(-)