This patch (as1624) prepares ehci-hcd for being split up into a core
library and separate platform driver modules.  A generic
ehci_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
ehci_setup(), ehci_suspend(), and ehci_resume() routines need to be
EXPORTed for use by the drivers.

As a side effect of this change, a few routines no longer need to be
marked __maybe_unused.

Signed-off-by: Alan Stern <st...@rowland.harvard.edu>
CC: Felipe Balbi <ba...@ti.com>

---

 drivers/usb/host/ehci-hcd.c |   73 ++++++++++++++++++++++++++++++++++++++++++--
 drivers/usb/host/ehci-hub.c |    6 +--
 drivers/usb/host/ehci.h     |   17 ++++++++++
 3 files changed, 89 insertions(+), 7 deletions(-)

Index: usb-3.7/drivers/usb/host/ehci.h
===================================================================
--- usb-3.7.orig/drivers/usb/host/ehci.h
+++ usb-3.7/drivers/usb/host/ehci.h
@@ -781,4 +781,21 @@ static inline u32 hc32_to_cpup (const st
 
 /*-------------------------------------------------------------------------*/
 
+/* Declarations of things exported for use by ehci platform drivers */
+
+struct ehci_driver_overrides {
+       const char      *product_desc;
+       size_t          extra_priv_size;
+       int             (*reset)(struct usb_hcd *hcd);
+};
+
+extern void    ehci_init_driver(struct hc_driver *drv,
+                               const struct ehci_driver_overrides *over);
+extern int     ehci_setup(struct usb_hcd *hcd);
+
+#ifdef CONFIG_PM
+extern int     ehci_suspend(struct usb_hcd *hcd, bool do_wakeup);
+extern int     ehci_resume(struct usb_hcd *hcd, bool hibernated);
+#endif /* CONFIG_PM */
+
 #endif /* __LINUX_EHCI_HCD_H */
Index: usb-3.7/drivers/usb/host/ehci-hcd.c
===================================================================
--- usb-3.7.orig/drivers/usb/host/ehci-hcd.c
+++ usb-3.7/drivers/usb/host/ehci-hcd.c
@@ -649,7 +649,7 @@ static int ehci_run (struct usb_hcd *hcd
        return 0;
 }
 
-static int ehci_setup(struct usb_hcd *hcd)
+int ehci_setup(struct usb_hcd *hcd)
 {
        struct ehci_hcd *ehci = hcd_to_ehci(hcd);
        int retval;
@@ -680,6 +680,7 @@ static int ehci_setup(struct usb_hcd *hc
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(ehci_setup);
 
 /*-------------------------------------------------------------------------*/
 
@@ -1085,7 +1086,7 @@ static int ehci_get_frame (struct usb_hc
 
 /* These routines handle the generic parts of controller suspend/resume */
 
-static int __maybe_unused ehci_suspend(struct usb_hcd *hcd, bool do_wakeup)
+int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
 
@@ -1108,9 +1109,10 @@ static int __maybe_unused ehci_suspend(s
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(ehci_suspend);
 
 /* Returns 0 if power was preserved, 1 if power was lost */
-static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated)
+int ehci_resume(struct usb_hcd *hcd, bool hibernated)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
 
@@ -1168,11 +1170,76 @@ static int __maybe_unused ehci_resume(st
 
        return 1;
 }
+EXPORT_SYMBOL_GPL(ehci_resume);
 
 #endif
 
 /*-------------------------------------------------------------------------*/
 
+/*
+ * Generic structure: This gets copied for platform drivers so that
+ * individual entries can be overridden as needed.
+ */
+
+static const struct hc_driver ehci_hc_driver = {
+       .description =          hcd_name,
+       .product_desc =         "EHCI Host Controller",
+       .hcd_priv_size =        sizeof(struct ehci_hcd),
+
+       /*
+        * generic hardware linkage
+        */
+       .irq =                  ehci_irq,
+       .flags =                HCD_MEMORY | HCD_USB2,
+
+       /*
+        * basic lifecycle operations
+        */
+       .reset =                ehci_setup,
+       .start =                ehci_run,
+       .stop =                 ehci_stop,
+       .shutdown =             ehci_shutdown,
+
+       /*
+        * managing i/o requests and associated device resources
+        */
+       .urb_enqueue =          ehci_urb_enqueue,
+       .urb_dequeue =          ehci_urb_dequeue,
+       .endpoint_disable =     ehci_endpoint_disable,
+       .endpoint_reset =       ehci_endpoint_reset,
+       .clear_tt_buffer_complete =     ehci_clear_tt_buffer_complete,
+
+       /*
+        * scheduling support
+        */
+       .get_frame_number =     ehci_get_frame,
+
+       /*
+        * root hub support
+        */
+       .hub_status_data =      ehci_hub_status_data,
+       .hub_control =          ehci_hub_control,
+       .bus_suspend =          ehci_bus_suspend,
+       .bus_resume =           ehci_bus_resume,
+       .relinquish_port =      ehci_relinquish_port,
+       .port_handed_over =     ehci_port_handed_over,
+};
+
+void ehci_init_driver(struct hc_driver *drv,
+               const struct ehci_driver_overrides *over)
+{
+       /* Copy the generic table to drv and then apply the overrides */
+       *drv = ehci_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(ehci_init_driver);
+
+/*-------------------------------------------------------------------------*/
+
 /*
  * The EHCI in ChipIdea HDRC cannot be a separate module or device,
  * because its registers (and irq) are shared between host/gadget/otg
Index: usb-3.7/drivers/usb/host/ehci-hub.c
===================================================================
--- usb-3.7.orig/drivers/usb/host/ehci-hub.c
+++ usb-3.7/drivers/usb/host/ehci-hub.c
@@ -1109,8 +1109,7 @@ error_exit:
        return retval;
 }
 
-static void __maybe_unused ehci_relinquish_port(struct usb_hcd *hcd,
-               int portnum)
+static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
 
@@ -1119,8 +1118,7 @@ static void __maybe_unused ehci_relinqui
        set_owner(ehci, --portnum, PORT_OWNER);
 }
 
-static int __maybe_unused ehci_port_handed_over(struct usb_hcd *hcd,
-               int portnum)
+static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
        u32 __iomem             *reg;

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to