lkml.org 
[lkml]   [2021]   [Jul]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.13 171/223] usb: dwc2: gadget: Fix GOUTNAK flow for Slave mode.
    Date
    From: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>

    commit fecb3a171db425e5068b27231f8efe154bf72637 upstream.

    Because of dwc2_hsotg_ep_stop_xfr() function uses poll
    mode, first need to mask GINTSTS_GOUTNAKEFF interrupt.
    In Slave mode GINTSTS_GOUTNAKEFF interrupt will be
    aserted only after pop OUT NAK status packet from RxFIFO.

    In dwc2_hsotg_ep_sethalt() function before setting
    DCTL_SGOUTNAK need to unmask GOUTNAKEFF interrupt.

    Tested by USBCV CH9 and MSC tests set in Slave, BDMA and DDMA.
    All tests are passed.

    Fixes: a4f827714539a ("usb: dwc2: gadget: Disable enabled HW endpoint in dwc2_hsotg_ep_disable")
    Fixes: 6070636c4918c ("usb: dwc2: Fix Stalling a Non-Isochronous OUT EP")
    Cc: stable <stable@vger.kernel.org>
    Signed-off-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
    Link: https://lore.kernel.org/r/e17fad802bbcaf879e1ed6745030993abb93baf8.1626152924.git.Minas.Harutyunyan@synopsys.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/usb/dwc2/gadget.c | 21 +++++++++++++++++++++
    1 file changed, 21 insertions(+)

    --- a/drivers/usb/dwc2/gadget.c
    +++ b/drivers/usb/dwc2/gadget.c
    @@ -3900,9 +3900,27 @@ static void dwc2_hsotg_ep_stop_xfr(struc
    __func__);
    }
    } else {
    + /* Mask GINTSTS_GOUTNAKEFF interrupt */
    + dwc2_hsotg_disable_gsint(hsotg, GINTSTS_GOUTNAKEFF);
    +
    if (!(dwc2_readl(hsotg, GINTSTS) & GINTSTS_GOUTNAKEFF))
    dwc2_set_bit(hsotg, DCTL, DCTL_SGOUTNAK);

    + if (!using_dma(hsotg)) {
    + /* Wait for GINTSTS_RXFLVL interrupt */
    + if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS,
    + GINTSTS_RXFLVL, 100)) {
    + dev_warn(hsotg->dev, "%s: timeout GINTSTS.RXFLVL\n",
    + __func__);
    + } else {
    + /*
    + * Pop GLOBAL OUT NAK status packet from RxFIFO
    + * to assert GOUTNAKEFF interrupt
    + */
    + dwc2_readl(hsotg, GRXSTSP);
    + }
    + }
    +
    /* Wait for global nak to take effect */
    if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS,
    GINTSTS_GOUTNAKEFF, 100))
    @@ -4348,6 +4366,9 @@ static int dwc2_hsotg_ep_sethalt(struct
    epctl = dwc2_readl(hs, epreg);

    if (value) {
    + /* Unmask GOUTNAKEFF interrupt */
    + dwc2_hsotg_en_gsint(hs, GINTSTS_GOUTNAKEFF);
    +
    if (!(dwc2_readl(hs, GINTSTS) & GINTSTS_GOUTNAKEFF))
    dwc2_set_bit(hs, DCTL, DCTL_SGOUTNAK);
    // STALL bit will be set in GOUTNAKEFF interrupt handler

    \
     
     \ /
      Last update: 2021-07-26 18:43    [W:4.742 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site