Skip to content

Commit 9b5ff3c

Browse files
committed
Merge tag 'usb-5.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB driver fixes from Greg KH: "Here are a number of small bugfixes for reported issues in some USB drivers. They include: - typec bugfixes - xhci bugfixes and lockdep warning fixes - cdc-acm driver regression fix - kernel doc fixes - cdns3 driver bugfixes for a bunch of reported issues - other tiny USB driver fixes All have been in linux-next with no reported issues" * tag 'usb-5.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: usb: cdns3: gadget: own the lock wrongly at the suspend routine usb: cdns3: Fix on-chip memory overflow issue usb: cdns3: gadget: suspicious implicit sign extension xhci: Don't create stream debugfs files with spinlock held. usb: xhci: Workaround for S3 issue on AMD SNPS 3.0 xHC xhci: Fix sizeof() mismatch usb: typec: stusb160x: fix signedness comparison issue with enum variables usb: typec: add missing MODULE_DEVICE_TABLE() to stusb160x USB: apple-mfi-fastcharge: don't probe unhandled devices usbcore: Check both id_table and match() when both available usb: host: ehci-tegra: Fix error handling in tegra_ehci_probe() usb: typec: stusb160x: fix an IS_ERR() vs NULL check in probe usb: typec: tcpm: reset hard_reset_count for any disconnect usb: cdc-acm: fix cooldown mechanism usb: host: fsl-mph-dr-of: check return of dma_set_mask() usb: fix kernel-doc markups usb: typec: stusb160x: fix some signedness bugs usb: cdns3: Variable 'length' set but not used
2 parents 2d38c80 + 00c27a1 commit 9b5ff3c

22 files changed

Lines changed: 195 additions & 138 deletions

File tree

drivers/usb/cdns3/ep0.c

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -137,48 +137,36 @@ static int cdns3_req_ep0_set_configuration(struct cdns3_device *priv_dev,
137137
struct usb_ctrlrequest *ctrl_req)
138138
{
139139
enum usb_device_state device_state = priv_dev->gadget.state;
140-
struct cdns3_endpoint *priv_ep;
141140
u32 config = le16_to_cpu(ctrl_req->wValue);
142141
int result = 0;
143-
int i;
144142

145143
switch (device_state) {
146144
case USB_STATE_ADDRESS:
147-
/* Configure non-control EPs */
148-
for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++) {
149-
priv_ep = priv_dev->eps[i];
150-
if (!priv_ep)
151-
continue;
152-
153-
if (priv_ep->flags & EP_CLAIMED)
154-
cdns3_ep_config(priv_ep);
155-
}
156-
157145
result = cdns3_ep0_delegate_req(priv_dev, ctrl_req);
158146

159-
if (result)
160-
return result;
161-
162-
if (!config) {
163-
cdns3_hw_reset_eps_config(priv_dev);
164-
usb_gadget_set_state(&priv_dev->gadget,
165-
USB_STATE_ADDRESS);
166-
}
147+
if (result || !config)
148+
goto reset_config;
167149

168150
break;
169151
case USB_STATE_CONFIGURED:
170152
result = cdns3_ep0_delegate_req(priv_dev, ctrl_req);
153+
if (!config && !result)
154+
goto reset_config;
171155

172-
if (!config && !result) {
173-
cdns3_hw_reset_eps_config(priv_dev);
174-
usb_gadget_set_state(&priv_dev->gadget,
175-
USB_STATE_ADDRESS);
176-
}
177156
break;
178157
default:
179-
result = -EINVAL;
158+
return -EINVAL;
180159
}
181160

161+
return 0;
162+
163+
reset_config:
164+
if (result != USB_GADGET_DELAYED_STATUS)
165+
cdns3_hw_reset_eps_config(priv_dev);
166+
167+
usb_gadget_set_state(&priv_dev->gadget,
168+
USB_STATE_ADDRESS);
169+
182170
return result;
183171
}
184172

@@ -705,6 +693,7 @@ static int cdns3_gadget_ep0_queue(struct usb_ep *ep,
705693
unsigned long flags;
706694
int ret = 0;
707695
u8 zlp = 0;
696+
int i;
708697

709698
spin_lock_irqsave(&priv_dev->lock, flags);
710699
trace_cdns3_ep0_queue(priv_dev, request);
@@ -720,6 +709,17 @@ static int cdns3_gadget_ep0_queue(struct usb_ep *ep,
720709
u32 val;
721710

722711
cdns3_select_ep(priv_dev, 0x00);
712+
713+
/*
714+
* Configure all non-control EPs which are not enabled by class driver
715+
*/
716+
for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++) {
717+
priv_ep = priv_dev->eps[i];
718+
if (priv_ep && priv_ep->flags & EP_CLAIMED &&
719+
!(priv_ep->flags & EP_ENABLED))
720+
cdns3_ep_config(priv_ep, 0);
721+
}
722+
723723
cdns3_set_hw_configuration(priv_dev);
724724
cdns3_ep0_complete_setup(priv_dev, 0, 1);
725725
/* wait until configuration set */
@@ -811,6 +811,7 @@ void cdns3_ep0_config(struct cdns3_device *priv_dev)
811811
struct cdns3_usb_regs __iomem *regs;
812812
struct cdns3_endpoint *priv_ep;
813813
u32 max_packet_size = 64;
814+
u32 ep_cfg;
814815

815816
regs = priv_dev->regs;
816817

@@ -842,17 +843,21 @@ void cdns3_ep0_config(struct cdns3_device *priv_dev)
842843
BIT(0) | BIT(16));
843844
}
844845

845-
writel(EP_CFG_ENABLE | EP_CFG_MAXPKTSIZE(max_packet_size),
846-
&regs->ep_cfg);
846+
ep_cfg = EP_CFG_ENABLE | EP_CFG_MAXPKTSIZE(max_packet_size);
847+
848+
if (!(priv_ep->flags & EP_CONFIGURED))
849+
writel(ep_cfg, &regs->ep_cfg);
847850

848851
writel(EP_STS_EN_SETUPEN | EP_STS_EN_DESCMISEN | EP_STS_EN_TRBERREN,
849852
&regs->ep_sts_en);
850853

851854
/* init ep in */
852855
cdns3_select_ep(priv_dev, USB_DIR_IN);
853856

854-
writel(EP_CFG_ENABLE | EP_CFG_MAXPKTSIZE(max_packet_size),
855-
&regs->ep_cfg);
857+
if (!(priv_ep->flags & EP_CONFIGURED))
858+
writel(ep_cfg, &regs->ep_cfg);
859+
860+
priv_ep->flags |= EP_CONFIGURED;
856861

857862
writel(EP_STS_EN_SETUPEN | EP_STS_EN_TRBERREN, &regs->ep_sts_en);
858863

drivers/usb/cdns3/gadget.c

Lines changed: 64 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ static void cdns3_ep_stall_flush(struct cdns3_endpoint *priv_ep)
296296
*/
297297
void cdns3_hw_reset_eps_config(struct cdns3_device *priv_dev)
298298
{
299+
int i;
300+
299301
writel(USB_CONF_CFGRST, &priv_dev->regs->usb_conf);
300302

301303
cdns3_allow_enable_l1(priv_dev, 0);
@@ -304,6 +306,10 @@ void cdns3_hw_reset_eps_config(struct cdns3_device *priv_dev)
304306
priv_dev->out_mem_is_allocated = 0;
305307
priv_dev->wait_for_setup = 0;
306308
priv_dev->using_streams = 0;
309+
310+
for (i = 0; i < CDNS3_ENDPOINTS_MAX_COUNT; i++)
311+
if (priv_dev->eps[i])
312+
priv_dev->eps[i]->flags &= ~EP_CONFIGURED;
307313
}
308314

309315
/**
@@ -506,7 +512,6 @@ static void cdns3_wa2_descmiss_copy_data(struct cdns3_endpoint *priv_ep,
506512

507513
while (!list_empty(&priv_ep->wa2_descmiss_req_list)) {
508514
int chunk_end;
509-
int length;
510515

511516
descmiss_priv_req =
512517
cdns3_next_priv_request(&priv_ep->wa2_descmiss_req_list);
@@ -517,7 +522,6 @@ static void cdns3_wa2_descmiss_copy_data(struct cdns3_endpoint *priv_ep,
517522
break;
518523

519524
chunk_end = descmiss_priv_req->flags & REQUEST_INTERNAL_CH;
520-
length = request->actual + descmiss_req->actual;
521525
request->status = descmiss_req->status;
522526
__cdns3_descmiss_copy_data(request, descmiss_req);
523527
list_del_init(&descmiss_priv_req->list);
@@ -1746,11 +1750,8 @@ static int cdns3_check_ep_interrupt_proceed(struct cdns3_endpoint *priv_ep)
17461750

17471751
static void cdns3_disconnect_gadget(struct cdns3_device *priv_dev)
17481752
{
1749-
if (priv_dev->gadget_driver && priv_dev->gadget_driver->disconnect) {
1750-
spin_unlock(&priv_dev->lock);
1753+
if (priv_dev->gadget_driver && priv_dev->gadget_driver->disconnect)
17511754
priv_dev->gadget_driver->disconnect(&priv_dev->gadget);
1752-
spin_lock(&priv_dev->lock);
1753-
}
17541755
}
17551756

17561757
/**
@@ -1761,6 +1762,7 @@ static void cdns3_disconnect_gadget(struct cdns3_device *priv_dev)
17611762
*/
17621763
static void cdns3_check_usb_interrupt_proceed(struct cdns3_device *priv_dev,
17631764
u32 usb_ists)
1765+
__must_hold(&priv_dev->lock)
17641766
{
17651767
int speed = 0;
17661768

@@ -1785,7 +1787,9 @@ static void cdns3_check_usb_interrupt_proceed(struct cdns3_device *priv_dev,
17851787

17861788
/* Disconnection detected */
17871789
if (usb_ists & (USB_ISTS_DIS2I | USB_ISTS_DISI)) {
1790+
spin_unlock(&priv_dev->lock);
17881791
cdns3_disconnect_gadget(priv_dev);
1792+
spin_lock(&priv_dev->lock);
17891793
priv_dev->gadget.speed = USB_SPEED_UNKNOWN;
17901794
usb_gadget_set_state(&priv_dev->gadget, USB_STATE_NOTATTACHED);
17911795
cdns3_hw_reset_eps_config(priv_dev);
@@ -1979,27 +1983,6 @@ static int cdns3_ep_onchip_buffer_reserve(struct cdns3_device *priv_dev,
19791983
return 0;
19801984
}
19811985

1982-
static void cdns3_stream_ep_reconfig(struct cdns3_device *priv_dev,
1983-
struct cdns3_endpoint *priv_ep)
1984-
{
1985-
if (!priv_ep->use_streams || priv_dev->gadget.speed < USB_SPEED_SUPER)
1986-
return;
1987-
1988-
if (priv_dev->dev_ver >= DEV_VER_V3) {
1989-
u32 mask = BIT(priv_ep->num + (priv_ep->dir ? 16 : 0));
1990-
1991-
/*
1992-
* Stream capable endpoints are handled by using ep_tdl
1993-
* register. Other endpoints use TDL from TRB feature.
1994-
*/
1995-
cdns3_clear_register_bit(&priv_dev->regs->tdl_from_trb, mask);
1996-
}
1997-
1998-
/* Enable Stream Bit TDL chk and SID chk */
1999-
cdns3_set_register_bit(&priv_dev->regs->ep_cfg, EP_CFG_STREAM_EN |
2000-
EP_CFG_TDL_CHK | EP_CFG_SID_CHK);
2001-
}
2002-
20031986
static void cdns3_configure_dmult(struct cdns3_device *priv_dev,
20041987
struct cdns3_endpoint *priv_ep)
20051988
{
@@ -2037,8 +2020,9 @@ static void cdns3_configure_dmult(struct cdns3_device *priv_dev,
20372020
/**
20382021
* cdns3_ep_config Configure hardware endpoint
20392022
* @priv_ep: extended endpoint object
2023+
* @enable: set EP_CFG_ENABLE bit in ep_cfg register.
20402024
*/
2041-
void cdns3_ep_config(struct cdns3_endpoint *priv_ep)
2025+
int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
20422026
{
20432027
bool is_iso_ep = (priv_ep->type == USB_ENDPOINT_XFER_ISOC);
20442028
struct cdns3_device *priv_dev = priv_ep->cdns3_dev;
@@ -2099,7 +2083,7 @@ void cdns3_ep_config(struct cdns3_endpoint *priv_ep)
20992083
break;
21002084
default:
21012085
/* all other speed are not supported */
2102-
return;
2086+
return -EINVAL;
21032087
}
21042088

21052089
if (max_packet_size == 1024)
@@ -2109,11 +2093,33 @@ void cdns3_ep_config(struct cdns3_endpoint *priv_ep)
21092093
else
21102094
priv_ep->trb_burst_size = 16;
21112095

2112-
ret = cdns3_ep_onchip_buffer_reserve(priv_dev, buffering + 1,
2113-
!!priv_ep->dir);
2114-
if (ret) {
2115-
dev_err(priv_dev->dev, "onchip mem is full, ep is invalid\n");
2116-
return;
2096+
/* onchip buffer is only allocated before configuration */
2097+
if (!priv_dev->hw_configured_flag) {
2098+
ret = cdns3_ep_onchip_buffer_reserve(priv_dev, buffering + 1,
2099+
!!priv_ep->dir);
2100+
if (ret) {
2101+
dev_err(priv_dev->dev, "onchip mem is full, ep is invalid\n");
2102+
return ret;
2103+
}
2104+
}
2105+
2106+
if (enable)
2107+
ep_cfg |= EP_CFG_ENABLE;
2108+
2109+
if (priv_ep->use_streams && priv_dev->gadget.speed >= USB_SPEED_SUPER) {
2110+
if (priv_dev->dev_ver >= DEV_VER_V3) {
2111+
u32 mask = BIT(priv_ep->num + (priv_ep->dir ? 16 : 0));
2112+
2113+
/*
2114+
* Stream capable endpoints are handled by using ep_tdl
2115+
* register. Other endpoints use TDL from TRB feature.
2116+
*/
2117+
cdns3_clear_register_bit(&priv_dev->regs->tdl_from_trb,
2118+
mask);
2119+
}
2120+
2121+
/* Enable Stream Bit TDL chk and SID chk */
2122+
ep_cfg |= EP_CFG_STREAM_EN | EP_CFG_TDL_CHK | EP_CFG_SID_CHK;
21172123
}
21182124

21192125
ep_cfg |= EP_CFG_MAXPKTSIZE(max_packet_size) |
@@ -2123,9 +2129,12 @@ void cdns3_ep_config(struct cdns3_endpoint *priv_ep)
21232129

21242130
cdns3_select_ep(priv_dev, bEndpointAddress);
21252131
writel(ep_cfg, &priv_dev->regs->ep_cfg);
2132+
priv_ep->flags |= EP_CONFIGURED;
21262133

21272134
dev_dbg(priv_dev->dev, "Configure %s: with val %08x\n",
21282135
priv_ep->name, ep_cfg);
2136+
2137+
return 0;
21292138
}
21302139

21312140
/* Find correct direction for HW endpoint according to description */
@@ -2266,7 +2275,7 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep,
22662275
u32 bEndpointAddress;
22672276
unsigned long flags;
22682277
int enable = 1;
2269-
int ret;
2278+
int ret = 0;
22702279
int val;
22712280

22722281
priv_ep = ep_to_cdns3_ep(ep);
@@ -2305,6 +2314,17 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep,
23052314
bEndpointAddress = priv_ep->num | priv_ep->dir;
23062315
cdns3_select_ep(priv_dev, bEndpointAddress);
23072316

2317+
/*
2318+
* For some versions of controller at some point during ISO OUT traffic
2319+
* DMA reads Transfer Ring for the EP which has never got doorbell.
2320+
* This issue was detected only on simulation, but to avoid this issue
2321+
* driver add protection against it. To fix it driver enable ISO OUT
2322+
* endpoint before setting DRBL. This special treatment of ISO OUT
2323+
* endpoints are recommended by controller specification.
2324+
*/
2325+
if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && !priv_ep->dir)
2326+
enable = 0;
2327+
23082328
if (usb_ss_max_streams(comp_desc) && usb_endpoint_xfer_bulk(desc)) {
23092329
/*
23102330
* Enable stream support (SS mode) related interrupts
@@ -2315,13 +2335,17 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep,
23152335
EP_STS_EN_SIDERREN | EP_STS_EN_MD_EXITEN |
23162336
EP_STS_EN_STREAMREN;
23172337
priv_ep->use_streams = true;
2318-
cdns3_stream_ep_reconfig(priv_dev, priv_ep);
2338+
ret = cdns3_ep_config(priv_ep, enable);
23192339
priv_dev->using_streams |= true;
23202340
}
2341+
} else {
2342+
ret = cdns3_ep_config(priv_ep, enable);
23212343
}
23222344

2323-
ret = cdns3_allocate_trb_pool(priv_ep);
2345+
if (ret)
2346+
goto exit;
23242347

2348+
ret = cdns3_allocate_trb_pool(priv_ep);
23252349
if (ret)
23262350
goto exit;
23272351

@@ -2351,20 +2375,6 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep,
23512375

23522376
writel(reg, &priv_dev->regs->ep_sts_en);
23532377

2354-
/*
2355-
* For some versions of controller at some point during ISO OUT traffic
2356-
* DMA reads Transfer Ring for the EP which has never got doorbell.
2357-
* This issue was detected only on simulation, but to avoid this issue
2358-
* driver add protection against it. To fix it driver enable ISO OUT
2359-
* endpoint before setting DRBL. This special treatment of ISO OUT
2360-
* endpoints are recommended by controller specification.
2361-
*/
2362-
if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && !priv_ep->dir)
2363-
enable = 0;
2364-
2365-
if (enable)
2366-
cdns3_set_register_bit(&priv_dev->regs->ep_cfg, EP_CFG_ENABLE);
2367-
23682378
ep->desc = desc;
23692379
priv_ep->flags &= ~(EP_PENDING_REQUEST | EP_STALLED | EP_STALL_PENDING |
23702380
EP_QUIRK_ISO_OUT_EN | EP_QUIRK_EXTRA_BUF_EN);
@@ -3265,10 +3275,13 @@ static int __cdns3_gadget_init(struct cdns3 *cdns)
32653275
}
32663276

32673277
static int cdns3_gadget_suspend(struct cdns3 *cdns, bool do_wakeup)
3278+
__must_hold(&cdns->lock)
32683279
{
32693280
struct cdns3_device *priv_dev = cdns->gadget_dev;
32703281

3282+
spin_unlock(&cdns->lock);
32713283
cdns3_disconnect_gadget(priv_dev);
3284+
spin_lock(&cdns->lock);
32723285

32733286
priv_dev->gadget.speed = USB_SPEED_UNKNOWN;
32743287
usb_gadget_set_state(&priv_dev->gadget, USB_STATE_NOTATTACHED);

drivers/usb/cdns3/gadget.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,7 @@ struct cdns3_trb {
10721072
#define TRB_TDL_SS_SIZE_GET(p) (((p) & GENMASK(23, 17)) >> 17)
10731073

10741074
/* transfer_len bitmasks - bits 31:24 */
1075-
#define TRB_BURST_LEN(p) (((p) << 24) & GENMASK(31, 24))
1075+
#define TRB_BURST_LEN(p) ((unsigned int)((p) << 24) & GENMASK(31, 24))
10761076
#define TRB_BURST_LEN_GET(p) (((p) & GENMASK(31, 24)) >> 24)
10771077

10781078
/* Data buffer pointer bitmasks*/
@@ -1159,6 +1159,7 @@ struct cdns3_endpoint {
11591159
#define EP_QUIRK_EXTRA_BUF_DET BIT(12)
11601160
#define EP_QUIRK_EXTRA_BUF_EN BIT(13)
11611161
#define EP_TDLCHK_EN BIT(15)
1162+
#define EP_CONFIGURED BIT(16)
11621163
u32 flags;
11631164

11641165
struct cdns3_request *descmis_req;
@@ -1360,7 +1361,7 @@ void cdns3_gadget_giveback(struct cdns3_endpoint *priv_ep,
13601361
int cdns3_init_ep0(struct cdns3_device *priv_dev,
13611362
struct cdns3_endpoint *priv_ep);
13621363
void cdns3_ep0_config(struct cdns3_device *priv_dev);
1363-
void cdns3_ep_config(struct cdns3_endpoint *priv_ep);
1364+
int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable);
13641365
void cdns3_check_ep0_interrupt_proceed(struct cdns3_device *priv_dev, int dir);
13651366
int __cdns3_gadget_wakeup(struct cdns3_device *priv_dev);
13661367

0 commit comments

Comments
 (0)