Skip to content

Commit 8614ecd

Browse files
pawellcdnsgregkh
authored andcommitted
usb: cdnsp: fix L1 resume issue for RTL_REVISION_NEW_LPM version
The controllers with rtl version larger than RTL_REVISION_NEW_LPM (0x00002700) has bug which causes that controller doesn't resume from L1 state. It happens if after receiving LPM packet controller starts transitioning to L1 and in this moment the driver force resuming by write operation to PORTSC.PLS. It's corner case and happens when write operation to PORTSC occurs during device delay before transitioning to L1 after transmitting ACK time (TL1TokenRetry). Forcing transition from L1->L0 by driver for revision larger than RTL_REVISION_NEW_LPM is not needed, so driver can simply fix this issue through block call of cdnsp_force_l0_go function. Fixes: 3d82904 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") Cc: stable <stable@kernel.org> Signed-off-by: Pawel Laszczak <pawell@cadence.com> Acked-by: Peter Chen <peter.chen@kernel.org> Link: https://lore.kernel.org/r/PH7PR07MB9538B55C3A6E71F9ED29E980DD842@PH7PR07MB9538.namprd07.prod.outlook.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 312d796 commit 8614ecd

File tree

3 files changed

+7
-1
lines changed

3 files changed

+7
-1
lines changed

drivers/usb/cdns3/cdnsp-gadget.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,6 +1793,8 @@ static void cdnsp_get_rev_cap(struct cdnsp_device *pdev)
17931793
reg += cdnsp_find_next_ext_cap(reg, 0, RTL_REV_CAP);
17941794
pdev->rev_cap = reg;
17951795

1796+
pdev->rtl_revision = readl(&pdev->rev_cap->rtl_revision);
1797+
17961798
dev_info(pdev->dev, "Rev: %08x/%08x, eps: %08x, buff: %08x/%08x\n",
17971799
readl(&pdev->rev_cap->ctrl_revision),
17981800
readl(&pdev->rev_cap->rtl_revision),

drivers/usb/cdns3/cdnsp-gadget.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,6 +1360,7 @@ struct cdnsp_port {
13601360
* @rev_cap: Controller Capabilities Registers.
13611361
* @hcs_params1: Cached register copies of read-only HCSPARAMS1
13621362
* @hcc_params: Cached register copies of read-only HCCPARAMS1
1363+
* @rtl_revision: Cached controller rtl revision.
13631364
* @setup: Temporary buffer for setup packet.
13641365
* @ep0_preq: Internal allocated request used during enumeration.
13651366
* @ep0_stage: ep0 stage during enumeration process.
@@ -1414,6 +1415,8 @@ struct cdnsp_device {
14141415
__u32 hcs_params1;
14151416
__u32 hcs_params3;
14161417
__u32 hcc_params;
1418+
#define RTL_REVISION_NEW_LPM 0x2700
1419+
__u32 rtl_revision;
14171420
/* Lock used in interrupt thread context. */
14181421
spinlock_t lock;
14191422
struct usb_ctrlrequest setup;

drivers/usb/cdns3/cdnsp-ring.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,8 @@ static bool cdnsp_ring_ep_doorbell(struct cdnsp_device *pdev,
308308

309309
writel(db_value, reg_addr);
310310

311-
cdnsp_force_l0_go(pdev);
311+
if (pdev->rtl_revision < RTL_REVISION_NEW_LPM)
312+
cdnsp_force_l0_go(pdev);
312313

313314
/* Doorbell was set. */
314315
return true;

0 commit comments

Comments
 (0)