Skip to content

Commit be5bfa1

Browse files
committed
Merge tag 'usb-6.12-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB / Thunderbolt fixes from Greg KH: "Here are some small USB and Thunderbolt driver fixes for 6.12-rc6 that have been sitting in my tree this week. Included in here are the following: - thunderbolt driver fixes for reported issues - USB typec driver fixes - xhci driver fixes for reported problems - dwc2 driver revert for a broken change - usb phy driver fix - usbip tool fix All of these have been in linux-next this week with no reported issues" * tag 'usb-6.12-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: usb: typec: tcpm: restrict SNK_WAIT_CAPABILITIES_TIMEOUT transitions to non self-powered devices usb: phy: Fix API devm_usb_put_phy() can not release the phy usb: typec: use cleanup facility for 'altmodes_node' usb: typec: fix unreleased fwnode_handle in typec_port_register_altmodes() usb: typec: qcom-pmic-typec: fix missing fwnode removal in error path usb: typec: qcom-pmic-typec: use fwnode_handle_put() to release fwnodes usb: acpi: fix boot hang due to early incorrect 'tunneled' USB3 device links Revert "usb: dwc2: Skip clock gating on Broadcom SoCs" xhci: Fix Link TRB DMA in command ring stopped completion event xhci: Use pm_runtime_get to prevent RPM on unsupported systems usbip: tools: Fix detach_port() invalid port error path thunderbolt: Honor TMU requirements in the domain when setting TMU mode thunderbolt: Fix KASAN reported stack out-of-bounds read in tb_retimer_scan()
2 parents 32cfb3c + afb92ad commit be5bfa1

File tree

11 files changed

+78
-31
lines changed

11 files changed

+78
-31
lines changed

drivers/thunderbolt/retimer.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ int tb_retimer_scan(struct tb_port *port, bool add)
516516
*/
517517
tb_retimer_set_inbound_sbtx(port);
518518

519-
for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) {
519+
for (max = 1, i = 1; i <= TB_MAX_RETIMER_INDEX; i++) {
520520
/*
521521
* Last retimer is true only for the last on-board
522522
* retimer (the one connected directly to the Type-C
@@ -527,9 +527,10 @@ int tb_retimer_scan(struct tb_port *port, bool add)
527527
last_idx = i;
528528
else if (ret < 0)
529529
break;
530+
531+
max = i;
530532
}
531533

532-
max = i;
533534
ret = 0;
534535

535536
/* Add retimers if they do not exist already */

drivers/thunderbolt/tb.c

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,24 @@ static void tb_increase_tmu_accuracy(struct tb_tunnel *tunnel)
288288
device_for_each_child(&sw->dev, NULL, tb_increase_switch_tmu_accuracy);
289289
}
290290

291+
static int tb_switch_tmu_hifi_uni_required(struct device *dev, void *not_used)
292+
{
293+
struct tb_switch *sw = tb_to_switch(dev);
294+
295+
if (sw && tb_switch_tmu_is_enabled(sw) &&
296+
tb_switch_tmu_is_configured(sw, TB_SWITCH_TMU_MODE_HIFI_UNI))
297+
return 1;
298+
299+
return device_for_each_child(dev, NULL,
300+
tb_switch_tmu_hifi_uni_required);
301+
}
302+
303+
static bool tb_tmu_hifi_uni_required(struct tb *tb)
304+
{
305+
return device_for_each_child(&tb->dev, NULL,
306+
tb_switch_tmu_hifi_uni_required) == 1;
307+
}
308+
291309
static int tb_enable_tmu(struct tb_switch *sw)
292310
{
293311
int ret;
@@ -302,12 +320,30 @@ static int tb_enable_tmu(struct tb_switch *sw)
302320
ret = tb_switch_tmu_configure(sw,
303321
TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI);
304322
if (ret == -EOPNOTSUPP) {
305-
if (tb_switch_clx_is_enabled(sw, TB_CL1))
306-
ret = tb_switch_tmu_configure(sw,
307-
TB_SWITCH_TMU_MODE_LOWRES);
308-
else
309-
ret = tb_switch_tmu_configure(sw,
310-
TB_SWITCH_TMU_MODE_HIFI_BI);
323+
if (tb_switch_clx_is_enabled(sw, TB_CL1)) {
324+
/*
325+
* Figure out uni-directional HiFi TMU requirements
326+
* currently in the domain. If there are no
327+
* uni-directional HiFi requirements we can put the TMU
328+
* into LowRes mode.
329+
*
330+
* Deliberately skip bi-directional HiFi links
331+
* as these work independently of other links
332+
* (and they do not allow any CL states anyway).
333+
*/
334+
if (tb_tmu_hifi_uni_required(sw->tb))
335+
ret = tb_switch_tmu_configure(sw,
336+
TB_SWITCH_TMU_MODE_HIFI_UNI);
337+
else
338+
ret = tb_switch_tmu_configure(sw,
339+
TB_SWITCH_TMU_MODE_LOWRES);
340+
} else {
341+
ret = tb_switch_tmu_configure(sw, TB_SWITCH_TMU_MODE_HIFI_BI);
342+
}
343+
344+
/* If not supported, fallback to bi-directional HiFi */
345+
if (ret == -EOPNOTSUPP)
346+
ret = tb_switch_tmu_configure(sw, TB_SWITCH_TMU_MODE_HIFI_BI);
311347
}
312348
if (ret)
313349
return ret;

drivers/usb/core/usb-acpi.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,11 @@ static int usb_acpi_add_usb4_devlink(struct usb_device *udev)
170170
struct fwnode_handle *nhi_fwnode __free(fwnode_handle) =
171171
fwnode_find_reference(dev_fwnode(&port_dev->dev), "usb4-host-interface", 0);
172172

173-
if (IS_ERR(nhi_fwnode))
173+
if (IS_ERR(nhi_fwnode) || !nhi_fwnode->dev)
174174
return 0;
175175

176176
link = device_link_add(&port_dev->child->dev, nhi_fwnode->dev,
177-
DL_FLAG_AUTOREMOVE_CONSUMER |
177+
DL_FLAG_STATELESS |
178178
DL_FLAG_RPM_ACTIVE |
179179
DL_FLAG_PM_RUNTIME);
180180
if (!link) {

drivers/usb/dwc2/params.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ static void dwc2_set_bcm_params(struct dwc2_hsotg *hsotg)
2323
p->max_transfer_size = 65535;
2424
p->max_packet_count = 511;
2525
p->ahbcfg = 0x10;
26-
p->no_clock_gating = true;
2726
}
2827

2928
static void dwc2_set_his_params(struct dwc2_hsotg *hsotg)

drivers/usb/host/xhci-pci.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ int xhci_pci_common_probe(struct pci_dev *dev, const struct pci_device_id *id)
640640
pm_runtime_put_noidle(&dev->dev);
641641

642642
if (pci_choose_state(dev, PMSG_SUSPEND) == PCI_D0)
643-
pm_runtime_forbid(&dev->dev);
643+
pm_runtime_get(&dev->dev);
644644
else if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW)
645645
pm_runtime_allow(&dev->dev);
646646

@@ -683,7 +683,9 @@ void xhci_pci_remove(struct pci_dev *dev)
683683

684684
xhci->xhc_state |= XHCI_STATE_REMOVING;
685685

686-
if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW)
686+
if (pci_choose_state(dev, PMSG_SUSPEND) == PCI_D0)
687+
pm_runtime_put(&dev->dev);
688+
else if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW)
687689
pm_runtime_forbid(&dev->dev);
688690

689691
if (xhci->shared_hcd) {

drivers/usb/host/xhci-ring.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,6 +1718,14 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
17181718

17191719
trace_xhci_handle_command(xhci->cmd_ring, &cmd_trb->generic);
17201720

1721+
cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event->status));
1722+
1723+
/* If CMD ring stopped we own the trbs between enqueue and dequeue */
1724+
if (cmd_comp_code == COMP_COMMAND_RING_STOPPED) {
1725+
complete_all(&xhci->cmd_ring_stop_completion);
1726+
return;
1727+
}
1728+
17211729
cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
17221730
cmd_trb);
17231731
/*
@@ -1734,14 +1742,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
17341742

17351743
cancel_delayed_work(&xhci->cmd_timer);
17361744

1737-
cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event->status));
1738-
1739-
/* If CMD ring stopped we own the trbs between enqueue and dequeue */
1740-
if (cmd_comp_code == COMP_COMMAND_RING_STOPPED) {
1741-
complete_all(&xhci->cmd_ring_stop_completion);
1742-
return;
1743-
}
1744-
17451745
if (cmd->command_trb != xhci->cmd_ring->dequeue) {
17461746
xhci_err(xhci,
17471747
"Command completion event does not match command\n");

drivers/usb/phy/phy.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ void devm_usb_put_phy(struct device *dev, struct usb_phy *phy)
628628
{
629629
int r;
630630

631-
r = devres_destroy(dev, devm_usb_phy_release, devm_usb_phy_match, phy);
631+
r = devres_release(dev, devm_usb_phy_release, devm_usb_phy_match, phy);
632632
dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
633633
}
634634
EXPORT_SYMBOL_GPL(devm_usb_put_phy);

drivers/usb/typec/class.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,15 +2293,17 @@ void typec_port_register_altmodes(struct typec_port *port,
22932293
const struct typec_altmode_ops *ops, void *drvdata,
22942294
struct typec_altmode **altmodes, size_t n)
22952295
{
2296-
struct fwnode_handle *altmodes_node, *child;
2296+
struct fwnode_handle *child;
22972297
struct typec_altmode_desc desc;
22982298
struct typec_altmode *alt;
22992299
size_t index = 0;
23002300
u16 svid;
23012301
u32 vdo;
23022302
int ret;
23032303

2304-
altmodes_node = device_get_named_child_node(&port->dev, "altmodes");
2304+
struct fwnode_handle *altmodes_node __free(fwnode_handle) =
2305+
device_get_named_child_node(&port->dev, "altmodes");
2306+
23052307
if (!altmodes_node)
23062308
return; /* No altmodes specified */
23072309

drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,10 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
9393
return -EINVAL;
9494

9595
bridge_dev = devm_drm_dp_hpd_bridge_alloc(tcpm->dev, to_of_node(tcpm->tcpc.fwnode));
96-
if (IS_ERR(bridge_dev))
97-
return PTR_ERR(bridge_dev);
96+
if (IS_ERR(bridge_dev)) {
97+
ret = PTR_ERR(bridge_dev);
98+
goto fwnode_remove;
99+
}
98100

99101
tcpm->tcpm_port = tcpm_register_port(tcpm->dev, &tcpm->tcpc);
100102
if (IS_ERR(tcpm->tcpm_port)) {
@@ -123,7 +125,7 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
123125
port_unregister:
124126
tcpm_unregister_port(tcpm->tcpm_port);
125127
fwnode_remove:
126-
fwnode_remove_software_node(tcpm->tcpc.fwnode);
128+
fwnode_handle_put(tcpm->tcpc.fwnode);
127129

128130
return ret;
129131
}
@@ -135,7 +137,7 @@ static void qcom_pmic_typec_remove(struct platform_device *pdev)
135137
tcpm->pdphy_stop(tcpm);
136138
tcpm->port_stop(tcpm);
137139
tcpm_unregister_port(tcpm->tcpm_port);
138-
fwnode_remove_software_node(tcpm->tcpc.fwnode);
140+
fwnode_handle_put(tcpm->tcpc.fwnode);
139141
}
140142

141143
static const struct pmic_typec_resources pm8150b_typec_res = {

drivers/usb/typec/tcpm/tcpm.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4515,7 +4515,8 @@ static inline enum tcpm_state hard_reset_state(struct tcpm_port *port)
45154515
return ERROR_RECOVERY;
45164516
if (port->pwr_role == TYPEC_SOURCE)
45174517
return SRC_UNATTACHED;
4518-
if (port->state == SNK_WAIT_CAPABILITIES_TIMEOUT)
4518+
if (port->state == SNK_WAIT_CAPABILITIES ||
4519+
port->state == SNK_WAIT_CAPABILITIES_TIMEOUT)
45194520
return SNK_READY;
45204521
return SNK_UNATTACHED;
45214522
}
@@ -5043,8 +5044,11 @@ static void run_state_machine(struct tcpm_port *port)
50435044
tcpm_set_state(port, SNK_SOFT_RESET,
50445045
PD_T_SINK_WAIT_CAP);
50455046
} else {
5046-
tcpm_set_state(port, SNK_WAIT_CAPABILITIES_TIMEOUT,
5047-
PD_T_SINK_WAIT_CAP);
5047+
if (!port->self_powered)
5048+
upcoming_state = SNK_WAIT_CAPABILITIES_TIMEOUT;
5049+
else
5050+
upcoming_state = hard_reset_state(port);
5051+
tcpm_set_state(port, upcoming_state, PD_T_SINK_WAIT_CAP);
50485052
}
50495053
break;
50505054
case SNK_WAIT_CAPABILITIES_TIMEOUT:

0 commit comments

Comments
 (0)