Skip to content

Commit c46ac50

Browse files
committed
Merge tag 'usb-6.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg KH: "Here are some small USB fixes for 6.8-rc6 to resolve some reported problems. These include: - regression fixes with typec tpcm code as reported by many - cdnsp and cdns3 driver fixes - usb role setting code bugfixes - build fix for uhci driver - ncm gadget driver bugfix - MAINTAINERS entry update All of these have been in linux-next all week with no reported issues and there is at least one fix in here that is in Thorsten's regression list that is being tracked" * tag 'usb-6.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: usb: typec: tpcm: Fix issues with power being removed during reset MAINTAINERS: Drop myself as maintainer of TYPEC port controller drivers usb: gadget: ncm: Avoid dropping datagrams of properly parsed NTBs Revert "usb: typec: tcpm: reset counter when enter into unattached state after try role" usb: gadget: omap_udc: fix USB gadget regression on Palm TE usb: dwc3: gadget: Don't disconnect if not started usb: cdns3: fix memory double free when handle zero packet usb: cdns3: fixed memory use after free at cdns3_gadget_ep_disable() usb: roles: don't get/set_role() when usb_role_switch is unregistered usb: roles: fix NULL pointer issue when put module's reference usb: cdnsp: fixed issue with incorrect detecting CDNSP family controllers usb: cdnsp: blocked some cdns3 specific code usb: uhci-grlib: Explicitly include linux/platform_device.h
2 parents 1e592e9 + 69f8916 commit c46ac50

File tree

12 files changed

+75
-26
lines changed

12 files changed

+75
-26
lines changed

MAINTAINERS

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22880,9 +22880,8 @@ S: Maintained
2288022880
F: drivers/usb/typec/mux/pi3usb30532.c
2288122881

2288222882
USB TYPEC PORT CONTROLLER DRIVERS
22883-
M: Guenter Roeck <[email protected]>
2288422883
22885-
S: Maintained
22884+
S: Orphan
2288622885
F: drivers/usb/typec/tcpm/
2288722886

2288822887
USB UHCI DRIVER

drivers/usb/cdns3/cdns3-gadget.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,11 @@ void cdns3_gadget_giveback(struct cdns3_endpoint *priv_ep,
828828
return;
829829
}
830830

831-
if (request->complete) {
831+
/*
832+
* zlp request is appended by driver, needn't call usb_gadget_giveback_request() to notify
833+
* gadget composite driver.
834+
*/
835+
if (request->complete && request->buf != priv_dev->zlp_buf) {
832836
spin_unlock(&priv_dev->lock);
833837
usb_gadget_giveback_request(&priv_ep->endpoint,
834838
request);
@@ -2540,11 +2544,11 @@ static int cdns3_gadget_ep_disable(struct usb_ep *ep)
25402544

25412545
while (!list_empty(&priv_ep->wa2_descmiss_req_list)) {
25422546
priv_req = cdns3_next_priv_request(&priv_ep->wa2_descmiss_req_list);
2547+
list_del_init(&priv_req->list);
25432548

25442549
kfree(priv_req->request.buf);
25452550
cdns3_gadget_ep_free_request(&priv_ep->endpoint,
25462551
&priv_req->request);
2547-
list_del_init(&priv_req->list);
25482552
--priv_ep->wa2_counter;
25492553
}
25502554

drivers/usb/cdns3/core.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,6 @@ static int cdns_role_set(struct usb_role_switch *sw, enum usb_role role)
395395
return ret;
396396
}
397397

398-
399398
/**
400399
* cdns_wakeup_irq - interrupt handler for wakeup events
401400
* @irq: irq number for cdns3/cdnsp core device

drivers/usb/cdns3/drd.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ bool cdns_is_device(struct cdns *cdns)
156156
*/
157157
static void cdns_otg_disable_irq(struct cdns *cdns)
158158
{
159-
writel(0, &cdns->otg_irq_regs->ien);
159+
if (cdns->version)
160+
writel(0, &cdns->otg_irq_regs->ien);
160161
}
161162

162163
/**
@@ -422,15 +423,20 @@ int cdns_drd_init(struct cdns *cdns)
422423

423424
cdns->otg_regs = (void __iomem *)&cdns->otg_v1_regs->cmd;
424425

425-
if (readl(&cdns->otg_cdnsp_regs->did) == OTG_CDNSP_DID) {
426+
state = readl(&cdns->otg_cdnsp_regs->did);
427+
428+
if (OTG_CDNSP_CHECK_DID(state)) {
426429
cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *)
427430
&cdns->otg_cdnsp_regs->ien;
428431
cdns->version = CDNSP_CONTROLLER_V2;
429-
} else {
432+
} else if (OTG_CDNS3_CHECK_DID(state)) {
430433
cdns->otg_irq_regs = (struct cdns_otg_irq_regs __iomem *)
431434
&cdns->otg_v1_regs->ien;
432435
writel(1, &cdns->otg_v1_regs->simulate);
433436
cdns->version = CDNS3_CONTROLLER_V1;
437+
} else {
438+
dev_err(cdns->dev, "not supporte DID=0x%08x\n", state);
439+
return -EINVAL;
434440
}
435441

436442
dev_dbg(cdns->dev, "DRD version v1 (ID: %08x, rev: %08x)\n",
@@ -483,7 +489,6 @@ int cdns_drd_exit(struct cdns *cdns)
483489
return 0;
484490
}
485491

486-
487492
/* Indicate the cdns3 core was power lost before */
488493
bool cdns_power_is_lost(struct cdns *cdns)
489494
{

drivers/usb/cdns3/drd.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,11 @@ struct cdnsp_otg_regs {
7979
__le32 susp_timing_ctrl;
8080
};
8181

82-
#define OTG_CDNSP_DID 0x0004034E
82+
/* CDNSP driver supports 0x000403xx Cadence USB controller family. */
83+
#define OTG_CDNSP_CHECK_DID(did) (((did) & GENMASK(31, 8)) == 0x00040300)
84+
85+
/* CDNS3 driver supports 0x000402xx Cadence USB controller family. */
86+
#define OTG_CDNS3_CHECK_DID(did) (((did) & GENMASK(31, 8)) == 0x00040200)
8387

8488
/*
8589
* Common registers interface for both CDNS3 and CDNSP version of DRD.

drivers/usb/cdns3/host.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
#include "../host/xhci.h"
1919
#include "../host/xhci-plat.h"
2020

21+
/*
22+
* The XECP_PORT_CAP_REG and XECP_AUX_CTRL_REG1 exist only
23+
* in Cadence USB3 dual-role controller, so it can't be used
24+
* with Cadence CDNSP dual-role controller.
25+
*/
2126
#define XECP_PORT_CAP_REG 0x8000
2227
#define XECP_AUX_CTRL_REG1 0x8120
2328

@@ -57,6 +62,8 @@ static const struct xhci_plat_priv xhci_plat_cdns3_xhci = {
5762
.resume_quirk = xhci_cdns3_resume_quirk,
5863
};
5964

65+
static const struct xhci_plat_priv xhci_plat_cdnsp_xhci;
66+
6067
static int __cdns_host_init(struct cdns *cdns)
6168
{
6269
struct platform_device *xhci;
@@ -81,8 +88,13 @@ static int __cdns_host_init(struct cdns *cdns)
8188
goto err1;
8289
}
8390

84-
cdns->xhci_plat_data = kmemdup(&xhci_plat_cdns3_xhci,
85-
sizeof(struct xhci_plat_priv), GFP_KERNEL);
91+
if (cdns->version < CDNSP_CONTROLLER_V2)
92+
cdns->xhci_plat_data = kmemdup(&xhci_plat_cdns3_xhci,
93+
sizeof(struct xhci_plat_priv), GFP_KERNEL);
94+
else
95+
cdns->xhci_plat_data = kmemdup(&xhci_plat_cdnsp_xhci,
96+
sizeof(struct xhci_plat_priv), GFP_KERNEL);
97+
8698
if (!cdns->xhci_plat_data) {
8799
ret = -ENOMEM;
88100
goto err1;

drivers/usb/dwc3/gadget.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2650,6 +2650,11 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
26502650
int ret;
26512651

26522652
spin_lock_irqsave(&dwc->lock, flags);
2653+
if (!dwc->pullups_connected) {
2654+
spin_unlock_irqrestore(&dwc->lock, flags);
2655+
return 0;
2656+
}
2657+
26532658
dwc->connected = false;
26542659

26552660
/*

drivers/usb/gadget/function/f_ncm.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1338,7 +1338,15 @@ static int ncm_unwrap_ntb(struct gether *port,
13381338
"Parsed NTB with %d frames\n", dgram_counter);
13391339

13401340
to_process -= block_len;
1341-
if (to_process != 0) {
1341+
1342+
/*
1343+
* Windows NCM driver avoids USB ZLPs by adding a 1-byte
1344+
* zero pad as needed.
1345+
*/
1346+
if (to_process == 1 &&
1347+
(*(unsigned char *)(ntb_ptr + block_len) == 0x00)) {
1348+
to_process--;
1349+
} else if (to_process > 0) {
13421350
ntb_ptr = (unsigned char *)(ntb_ptr + block_len);
13431351
goto parse_ntb;
13441352
}

drivers/usb/gadget/udc/omap_udc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2036,7 +2036,8 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev)
20362036

20372037
static inline int machine_without_vbus_sense(void)
20382038
{
2039-
return machine_is_omap_osk() || machine_is_sx1();
2039+
return machine_is_omap_osk() || machine_is_omap_palmte() ||
2040+
machine_is_sx1();
20402041
}
20412042

20422043
static int omap_udc_start(struct usb_gadget *g,

drivers/usb/host/uhci-grlib.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/of_irq.h>
2323
#include <linux/of_address.h>
2424
#include <linux/of_platform.h>
25+
#include <linux/platform_device.h>
2526

2627
static int uhci_grlib_init(struct usb_hcd *hcd)
2728
{

drivers/usb/roles/class.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ static const struct class role_class = {
2121
struct usb_role_switch {
2222
struct device dev;
2323
struct mutex lock; /* device lock*/
24+
struct module *module; /* the module this device depends on */
2425
enum usb_role role;
26+
bool registered;
2527

2628
/* From descriptor */
2729
struct device *usb2_port;
@@ -48,6 +50,9 @@ int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role)
4850
if (IS_ERR_OR_NULL(sw))
4951
return 0;
5052

53+
if (!sw->registered)
54+
return -EOPNOTSUPP;
55+
5156
mutex_lock(&sw->lock);
5257

5358
ret = sw->set(sw, role);
@@ -73,7 +78,7 @@ enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw)
7378
{
7479
enum usb_role role;
7580

76-
if (IS_ERR_OR_NULL(sw))
81+
if (IS_ERR_OR_NULL(sw) || !sw->registered)
7782
return USB_ROLE_NONE;
7883

7984
mutex_lock(&sw->lock);
@@ -135,7 +140,7 @@ struct usb_role_switch *usb_role_switch_get(struct device *dev)
135140
usb_role_switch_match);
136141

137142
if (!IS_ERR_OR_NULL(sw))
138-
WARN_ON(!try_module_get(sw->dev.parent->driver->owner));
143+
WARN_ON(!try_module_get(sw->module));
139144

140145
return sw;
141146
}
@@ -157,7 +162,7 @@ struct usb_role_switch *fwnode_usb_role_switch_get(struct fwnode_handle *fwnode)
157162
sw = fwnode_connection_find_match(fwnode, "usb-role-switch",
158163
NULL, usb_role_switch_match);
159164
if (!IS_ERR_OR_NULL(sw))
160-
WARN_ON(!try_module_get(sw->dev.parent->driver->owner));
165+
WARN_ON(!try_module_get(sw->module));
161166

162167
return sw;
163168
}
@@ -172,7 +177,7 @@ EXPORT_SYMBOL_GPL(fwnode_usb_role_switch_get);
172177
void usb_role_switch_put(struct usb_role_switch *sw)
173178
{
174179
if (!IS_ERR_OR_NULL(sw)) {
175-
module_put(sw->dev.parent->driver->owner);
180+
module_put(sw->module);
176181
put_device(&sw->dev);
177182
}
178183
}
@@ -189,15 +194,18 @@ struct usb_role_switch *
189194
usb_role_switch_find_by_fwnode(const struct fwnode_handle *fwnode)
190195
{
191196
struct device *dev;
197+
struct usb_role_switch *sw = NULL;
192198

193199
if (!fwnode)
194200
return NULL;
195201

196202
dev = class_find_device_by_fwnode(&role_class, fwnode);
197-
if (dev)
198-
WARN_ON(!try_module_get(dev->parent->driver->owner));
203+
if (dev) {
204+
sw = to_role_switch(dev);
205+
WARN_ON(!try_module_get(sw->module));
206+
}
199207

200-
return dev ? to_role_switch(dev) : NULL;
208+
return sw;
201209
}
202210
EXPORT_SYMBOL_GPL(usb_role_switch_find_by_fwnode);
203211

@@ -338,6 +346,7 @@ usb_role_switch_register(struct device *parent,
338346
sw->set = desc->set;
339347
sw->get = desc->get;
340348

349+
sw->module = parent->driver->owner;
341350
sw->dev.parent = parent;
342351
sw->dev.fwnode = desc->fwnode;
343352
sw->dev.class = &role_class;
@@ -352,6 +361,8 @@ usb_role_switch_register(struct device *parent,
352361
return ERR_PTR(ret);
353362
}
354363

364+
sw->registered = true;
365+
355366
/* TODO: Symlinks for the host port and the device controller. */
356367

357368
return sw;
@@ -366,8 +377,10 @@ EXPORT_SYMBOL_GPL(usb_role_switch_register);
366377
*/
367378
void usb_role_switch_unregister(struct usb_role_switch *sw)
368379
{
369-
if (!IS_ERR_OR_NULL(sw))
380+
if (!IS_ERR_OR_NULL(sw)) {
381+
sw->registered = false;
370382
device_unregister(&sw->dev);
383+
}
371384
}
372385
EXPORT_SYMBOL_GPL(usb_role_switch_unregister);
373386

drivers/usb/typec/tcpm/tcpm.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3743,9 +3743,6 @@ static void tcpm_detach(struct tcpm_port *port)
37433743
if (tcpm_port_is_disconnected(port))
37443744
port->hard_reset_count = 0;
37453745

3746-
port->try_src_count = 0;
3747-
port->try_snk_count = 0;
3748-
37493746
if (!port->attached)
37503747
return;
37513748

@@ -4876,7 +4873,8 @@ static void run_state_machine(struct tcpm_port *port)
48764873
break;
48774874
case PORT_RESET:
48784875
tcpm_reset_port(port);
4879-
tcpm_set_cc(port, TYPEC_CC_OPEN);
4876+
tcpm_set_cc(port, tcpm_default_state(port) == SNK_UNATTACHED ?
4877+
TYPEC_CC_RD : tcpm_rp_cc(port));
48804878
tcpm_set_state(port, PORT_RESET_WAIT_OFF,
48814879
PD_T_ERROR_RECOVERY);
48824880
break;

0 commit comments

Comments
 (0)