lkml.org 
[lkml]   [2017]   [Sep]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 030/233] usb: dwc3: gadget: Prevent losing events in event cache
    3.16.48-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>

    commit d325a1de49d61ee11aca58a529571c91ecea7879 upstream.

    The dwc3 driver can overwite its previous events if its top-half IRQ
    handler (TH) gets invoked again before processing the events in the
    cache. We see this as a hang in the file transfer and the host will
    attempt to reset the device. TH gets the event count and deasserts the
    interrupt line by writing DWC3_GEVNTSIZ_INTMASK to DWC3_GEVNTSIZ. If
    there's a new event coming between reading the event count and interrupt
    deassertion, dwc3 will lose previous pending events. More generally, we
    will see 0 event count, which should not affect anything.

    This shouldn't be possible in the current dwc3 implementation. However,
    through testing and reading the PCIe trace, the TH occasionally still
    gets invoked one more time after HW interrupt deassertion. (With PCIe
    legacy interrupts, TH is called repeatedly as long as the interrupt line
    is asserted). We suspect that there is a small detection delay in the
    SW.

    To avoid this issue, Check DWC3_EVENT_PENDING flag to determine if the
    events are processed in the bottom-half IRQ handler. If not, return
    IRQ_HANDLED and don't process new event.

    Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
    Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
    [bwh: Backported to 3.16: adjust context]
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/usb/dwc3/gadget.c | 9 +++++++++
    1 file changed, 9 insertions(+)

    --- a/drivers/usb/dwc3/gadget.c
    +++ b/drivers/usb/dwc3/gadget.c
    @@ -2761,6 +2761,15 @@ static irqreturn_t dwc3_check_event_buf(

    evt = dwc->ev_buffs[buf];

    + /*
    + * With PCIe legacy interrupt, test shows that top-half irq handler can
    + * be called again after HW interrupt deassertion. Check if bottom-half
    + * irq event handler completes before caching new event to prevent
    + * losing events.
    + */
    + if (evt->flags & DWC3_EVENT_PENDING)
    + return IRQ_HANDLED;
    +
    count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(buf));
    count &= DWC3_GEVNTCOUNT_MASK;
    if (!count)
    \
     
     \ /
      Last update: 2017-09-10 01:30    [W:4.718 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site