This patch introduces usb_add_hcd_init(). Its purpose is the same as of usb_add_hcd() except it takes a one-time-init callback. This callback should take over from ->reset() in hc_driver. It executed only once and therefore not required for the complete runtime. If the one_time callback is specified, the ->reset() callback is omited. Signed-off-by: Sebastian Andrzej Siewior <sebastian@xxxxxxxxxxxxx> --- drivers/usb/core/hcd.c | 19 ++++++++++++++----- include/linux/usb/hcd.h | 11 +++++++++-- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 73cbbd8..a761a76 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2376,8 +2376,8 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd, * buffers of consistent memory, register the bus, request the IRQ line, * and call the driver's reset() and start() routines. */ -int usb_add_hcd(struct usb_hcd *hcd, - unsigned int irqnum, unsigned long irqflags) +int usb_add_hcd_init(struct usb_hcd *hcd, u32 irqnum, unsigned long irqflags, + hcd_ot_init ot_init, void *ot_priv) { int retval; struct usb_device *rhdev; @@ -2440,9 +2440,18 @@ int usb_add_hcd(struct usb_hcd *hcd, /* "reset" is misnamed; its role is now one-time init. the controller * should already have been reset (and boot firmware kicked off etc). */ - if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) { - dev_err(hcd->self.controller, "can't setup\n"); - goto err_hcd_driver_setup; + if (ot_init) { + retval = ot_init(hcd, ot_priv); + if (retval) { + dev_err(hcd->self.controller, "can't perform init)\n"); + goto err_hcd_driver_setup; + } + } else if (hcd->driver->reset) { + retval = hcd->driver->reset(hcd); + if (retval) { + dev_err(hcd->self.controller, "can't setup\n"); + goto err_hcd_driver_setup; + } } hcd->rh_pollable = 1; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index d29a8a0..c0619af 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -380,8 +380,15 @@ extern struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver, extern struct usb_hcd *usb_get_hcd(struct usb_hcd *hcd); extern void usb_put_hcd(struct usb_hcd *hcd); extern int usb_hcd_is_primary_hcd(struct usb_hcd *hcd); -extern int usb_add_hcd(struct usb_hcd *hcd, - unsigned int irqnum, unsigned long irqflags); + +typedef int (*hcd_ot_init)(struct usb_hcd *hcd, void *priv); +extern int usb_add_hcd_init(struct usb_hcd *hcd, u32 irqnum, + unsigned long irqflags, hcd_ot_init ot_init, void *ot_priv); +static inline int usb_add_hcd(struct usb_hcd *hcd, + unsigned int irqnum, unsigned long irqflags) +{ + return usb_add_hcd_init(hcd, irqnum, irqflags, NULL, NULL); +} extern void usb_remove_hcd(struct usb_hcd *hcd); struct platform_device; -- 1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html