> From: [email protected] [mailto:[email protected]]
> Sent: Monday, February 03, 2014 9:00 AM

Hi Dinh,

> According to the spec for the DWC2 controller, when the PRTINT interrupt 
> fires,
> the application must clear the appropriate status bit in the Host Port Control
> and Status register to clear this bit.
> 
> When disconnecting an A-cable when the dwc2 host driver, the PRTINT fires, but
> only the GINTSTS_PRTINT status is cleared, no action is done with the HPRT0
> register. The HPRT0_ENACHG bit in the HPRT0 must also be poked to correctly
> clear the GINTSTS_PRTINT interrupt.
> 
> I am seeing this behavoir on v2.93 of the DWC2 IP. When I disconnect an OTG
> A-cable adapter, the PRTINT interrupt fires when the DWC2 is in device mode
> and is never cleared.
> 
> This patch adds the function to read the HPRT0 register when the PRTINT fires
> and the dwc2 IP has already transitioned to device mode. This function is only
> clearing the HPRT0_ENACHG bit for now, but can be modified to handle more.
> 
> Signed-off-by: Dinh Nguyen <[email protected]>
> Cc: Paul Zimmerman <[email protected]>
> Cc: Matt Porter <[email protected]>
> Cc: Matthijs Kooijman <[email protected]>
> ---
>  drivers/usb/dwc2/core_intr.c |   20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
> index 12dde73..64fee902 100644
> --- a/drivers/usb/dwc2/core_intr.c
> +++ b/drivers/usb/dwc2/core_intr.c
> @@ -76,6 +76,24 @@ static const char *dwc2_op_state_str(struct dwc2_hsotg 
> *hsotg)
>  }
> 
>  /**
> + * dwc2_handle_usb_port_intr - handles OTG PRTINT interrupts.
> + * When the PRTINT interrupt fires, there are certain status bits in the Host
> + * Port that needs to get cleared.
> + *
> + * @hsotg: Programming view of DWC_otg controller
> + */
> +static void dwc2_handle_usb_port_intr(struct dwc2_hsotg *hsotg)
> +{
> +     u32 hprt0;
> +
> +     hprt0 = readl(hsotg->regs + HPRT0);
> +     if (hprt0 & HPRT0_ENACHG) {

This would be a little cleaner like this:

        u32 hprt0 = readl(hsotg->regs + HPRT0);

        if (hprt0 & HPRT0_ENACHG) {

> +             hprt0 |= HPRT0_ENACHG;
> +             writel(hprt0, hsotg->regs + HPRT0);
> +     }
> +}
> +
> +/**
>   * dwc2_handle_mode_mismatch_intr() - Logs a mode mismatch warning message
>   *
>   * @hsotg: Programming view of DWC_otg controller
> @@ -583,8 +601,10 @@ irq_retry:
>               if (dwc2_is_device_mode(hsotg)) {
>                       dev_dbg(hsotg->dev,
>                               " --Port interrupt received in Device 
> mode--\n");
> +                     dwc2_handle_usb_port_intr(hsotg);
>                       gintsts = GINTSTS_PRTINT;
>                       writel(gintsts, hsotg->regs + GINTSTS);
> +                     dwc2_handle_usb_port_intr(hsotg);

Why do you have two calls to dwc2_handle_usb_port_intr() here? Does it
still work if you remove the first call?

I don't see this problem on our internal FPGA platform, so I will just
have to take your word that this fixes a problem. If you resubmit the
patch with just a single call to dwc2_handle_usb_port_intr(), I will
ack it.

-- 
Paul

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

Reply via email to