usb: dwc3: gadget: move cmd_endtransfer to extra function
[ Upstream commit e192cc7b52399d1b073f88cd3ba128b74d3a57f1 ] This patch adds the extra function __dwc3_stop_active_transfer to consolidate the same codepath. Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> Link: https://lore.kernel.org/r/20220306211251.2281335-3-m.grzeschik@pengutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Stable-dep-of: d8a2bb4eb758 ("usb: dwc3: gadget: Add 1ms delay after end transfer command without IOC") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
01e4c9c03d
commit
ddb1973e67
@@ -1440,6 +1440,40 @@ static int __dwc3_gadget_get_frame(struct dwc3 *dwc)
|
|||||||
return DWC3_DSTS_SOFFN(reg);
|
return DWC3_DSTS_SOFFN(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __dwc3_stop_active_transfer - stop the current active transfer
|
||||||
|
* @dep: isoc endpoint
|
||||||
|
* @force: set forcerm bit in the command
|
||||||
|
* @interrupt: command complete interrupt after End Transfer command
|
||||||
|
*
|
||||||
|
* When setting force, the ForceRM bit will be set. In that case
|
||||||
|
* the controller won't update the TRB progress on command
|
||||||
|
* completion. It also won't clear the HWO bit in the TRB.
|
||||||
|
* The command will also not complete immediately in that case.
|
||||||
|
*/
|
||||||
|
static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt)
|
||||||
|
{
|
||||||
|
struct dwc3_gadget_ep_cmd_params params;
|
||||||
|
u32 cmd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
cmd = DWC3_DEPCMD_ENDTRANSFER;
|
||||||
|
cmd |= force ? DWC3_DEPCMD_HIPRI_FORCERM : 0;
|
||||||
|
cmd |= interrupt ? DWC3_DEPCMD_CMDIOC : 0;
|
||||||
|
cmd |= DWC3_DEPCMD_PARAM(dep->resource_index);
|
||||||
|
memset(¶ms, 0, sizeof(params));
|
||||||
|
ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms);
|
||||||
|
WARN_ON_ONCE(ret);
|
||||||
|
dep->resource_index = 0;
|
||||||
|
|
||||||
|
if (!interrupt)
|
||||||
|
dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
|
||||||
|
else if (!ret)
|
||||||
|
dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dwc3_gadget_start_isoc_quirk - workaround invalid frame number
|
* dwc3_gadget_start_isoc_quirk - workaround invalid frame number
|
||||||
* @dep: isoc endpoint
|
* @dep: isoc endpoint
|
||||||
@@ -1609,21 +1643,8 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep)
|
|||||||
* status, issue END_TRANSFER command and retry on the next XferNotReady
|
* status, issue END_TRANSFER command and retry on the next XferNotReady
|
||||||
* event.
|
* event.
|
||||||
*/
|
*/
|
||||||
if (ret == -EAGAIN) {
|
if (ret == -EAGAIN)
|
||||||
struct dwc3_gadget_ep_cmd_params params;
|
ret = __dwc3_stop_active_transfer(dep, false, true);
|
||||||
u32 cmd;
|
|
||||||
|
|
||||||
cmd = DWC3_DEPCMD_ENDTRANSFER |
|
|
||||||
DWC3_DEPCMD_CMDIOC |
|
|
||||||
DWC3_DEPCMD_PARAM(dep->resource_index);
|
|
||||||
|
|
||||||
dep->resource_index = 0;
|
|
||||||
memset(¶ms, 0, sizeof(params));
|
|
||||||
|
|
||||||
ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms);
|
|
||||||
if (!ret)
|
|
||||||
dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -3250,10 +3271,6 @@ static void dwc3_reset_gadget(struct dwc3 *dwc)
|
|||||||
static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
|
static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
|
||||||
bool interrupt)
|
bool interrupt)
|
||||||
{
|
{
|
||||||
struct dwc3_gadget_ep_cmd_params params;
|
|
||||||
u32 cmd;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) ||
|
if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) ||
|
||||||
(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
|
(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
|
||||||
return;
|
return;
|
||||||
@@ -3285,19 +3302,7 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
|
|||||||
* This mode is NOT available on the DWC_usb31 IP.
|
* This mode is NOT available on the DWC_usb31 IP.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cmd = DWC3_DEPCMD_ENDTRANSFER;
|
__dwc3_stop_active_transfer(dep, force, interrupt);
|
||||||
cmd |= force ? DWC3_DEPCMD_HIPRI_FORCERM : 0;
|
|
||||||
cmd |= interrupt ? DWC3_DEPCMD_CMDIOC : 0;
|
|
||||||
cmd |= DWC3_DEPCMD_PARAM(dep->resource_index);
|
|
||||||
memset(¶ms, 0, sizeof(params));
|
|
||||||
ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms);
|
|
||||||
WARN_ON_ONCE(ret);
|
|
||||||
dep->resource_index = 0;
|
|
||||||
|
|
||||||
if (!interrupt)
|
|
||||||
dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
|
|
||||||
else
|
|
||||||
dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dwc3_clear_stall_all_ep(struct dwc3 *dwc)
|
static void dwc3_clear_stall_all_ep(struct dwc3 *dwc)
|
||||||
|
Reference in New Issue
Block a user