Skip to content

Commit

Permalink
USB: EHCI: prepare to make ehci-hcd a library module
Browse files Browse the repository at this point in the history
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 <stern@rowland.harvard.edu>
CC: Felipe Balbi <balbi@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Nov 1, 2012
1 parent 7c83b44 commit 3e02320
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 7 deletions.
73 changes: 70 additions & 3 deletions drivers/usb/host/ehci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -680,6 +680,7 @@ static int ehci_setup(struct usb_hcd *hcd)

return 0;
}
EXPORT_SYMBOL_GPL(ehci_setup);

/*-------------------------------------------------------------------------*/

Expand Down Expand Up @@ -1085,7 +1086,7 @@ static int ehci_get_frame (struct usb_hcd *hcd)

/* 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);

Expand All @@ -1108,9 +1109,10 @@ static int __maybe_unused ehci_suspend(struct usb_hcd *hcd, bool do_wakeup)

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);

Expand Down Expand Up @@ -1168,11 +1170,76 @@ static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated)

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
Expand Down
6 changes: 2 additions & 4 deletions drivers/usb/host/ehci-hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1109,8 +1109,7 @@ static int ehci_hub_control (
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);

Expand All @@ -1119,8 +1118,7 @@ static void __maybe_unused ehci_relinquish_port(struct usb_hcd *hcd,
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;
Expand Down
17 changes: 17 additions & 0 deletions drivers/usb/host/ehci.h
Original file line number Diff line number Diff line change
Expand Up @@ -781,4 +781,21 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x)

/*-------------------------------------------------------------------------*/

/* 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 */

0 comments on commit 3e02320

Please sign in to comment.