renesas_usbhs driver is using mod_host/mod_gadget shared irq handler. But HCD_FLAG_SAW_IRQ bit control is needed like usb_hcd_irq() if it is mod_host. Without this patch, the driver will stop when USB hub was disconnected Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@xxxxxxxxxxx> --- drivers/usb/renesas_usbhs/mod.c | 3 +++ drivers/usb/renesas_usbhs/mod.h | 3 +++ drivers/usb/renesas_usbhs/mod_host.c | 24 +++++++++++++++++++++++- 3 files changed, 29 insertions(+), 1 deletions(-) diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 1b97fb1..26ce9df 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c @@ -293,6 +293,9 @@ static irqreturn_t usbhs_interrupt(int irq, void *data) if (irq_state.intsts1 & SACK) usbhs_mod_call(priv, irq_sack, priv, &irq_state); + /* common */ + usbhs_mod_call(priv, irq_common, priv); + return IRQ_HANDLED; } diff --git a/drivers/usb/renesas_usbhs/mod.h b/drivers/usb/renesas_usbhs/mod.h index 6c68755..b6b0989 100644 --- a/drivers/usb/renesas_usbhs/mod.h +++ b/drivers/usb/renesas_usbhs/mod.h @@ -83,6 +83,9 @@ struct usbhs_mod { int (*irq_sack)(struct usbhs_priv *priv, struct usbhs_irq_state *irq_state); + /* common */ + int (*irq_common)(struct usbhs_priv *priv); + struct usbhs_priv *priv; }; diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index c394047..d8a7e97 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -799,11 +799,14 @@ static int usbhsh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) { struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); struct usbhsh_request *ureq = usbhsh_urb_to_ureq(urb); + int ret; + + ret = usb_hcd_check_unlink_urb(hcd, urb, status); if (ureq) usbhsh_ureq_free(hpriv, ureq); - return 0; + return ret; } static void usbhsh_endpoint_disable(struct usb_hcd *hcd, @@ -1116,6 +1119,24 @@ static int usbhsh_irq_setup_err(struct usbhs_priv *priv, return 0; } +static int usbhsh_irq_common(struct usbhs_priv *priv) +{ + struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); + struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); + + /* + * renesas_usbhs driver is not using usb host + * common driver. so, this flags-setting is needed by itself. + * see + * usb_hcd_check_unlink_urb() + * usb_hcd_irq() + */ + + set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); + + return 0; +} + /* * module start/stop */ @@ -1205,6 +1226,7 @@ static int usbhsh_start(struct usbhs_priv *priv) mod->irq_dtch = usbhsh_irq_dtch; mod->irq_sack = usbhsh_irq_setup_ack; mod->irq_sign = usbhsh_irq_setup_err; + mod->irq_common = usbhsh_irq_common; usbhs_irq_callback_update(priv, mod); dev_dbg(dev, "start host\n"); -- 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