Commit 4051a1c9 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'thunderbolt-for-v6.2-rc1' of...

Merge tag 'thunderbolt-for-v6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-next

Mika writes:

thunderbolt: Changes for v6.2 merge window

This includes following Thunderbolt/USB4 changes for the v6.2 merge
window:

  - Add wake on connect/disconnect for USB4 ports
  - A couple of minor cleanups

All these have been in linux-next with no reported issues.

* tag 'thunderbolt-for-v6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt:
  thunderbolt: Add wake on connect/disconnect on USB4 ports
  thunderbolt: ACPI: Use the helper fwnode_find_reference()
  thunderbolt: Remove redundant assignment to variable len
  thunderbolt: Use str_enabled_disabled() helper
parents b47ec972 a5cfc9d6
...@@ -15,24 +15,20 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data, ...@@ -15,24 +15,20 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data,
void **return_value) void **return_value)
{ {
struct acpi_device *adev = acpi_fetch_acpi_dev(handle); struct acpi_device *adev = acpi_fetch_acpi_dev(handle);
struct fwnode_reference_args args;
struct fwnode_handle *fwnode; struct fwnode_handle *fwnode;
struct tb_nhi *nhi = data; struct tb_nhi *nhi = data;
struct pci_dev *pdev; struct pci_dev *pdev;
struct device *dev; struct device *dev;
int ret;
if (!adev) if (!adev)
return AE_OK; return AE_OK;
fwnode = acpi_fwnode_handle(adev); fwnode = fwnode_find_reference(acpi_fwnode_handle(adev), "usb4-host-interface", 0);
ret = fwnode_property_get_reference_args(fwnode, "usb4-host-interface", if (IS_ERR(fwnode))
NULL, 0, 0, &args);
if (ret)
return AE_OK; return AE_OK;
/* It needs to reference this NHI */ /* It needs to reference this NHI */
if (dev_fwnode(&nhi->pdev->dev) != args.fwnode) if (dev_fwnode(&nhi->pdev->dev) != fwnode)
goto out_put; goto out_put;
/* /*
...@@ -100,7 +96,7 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data, ...@@ -100,7 +96,7 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data,
} }
out_put: out_put:
fwnode_handle_put(args.fwnode); fwnode_handle_put(fwnode);
return AE_OK; return AE_OK;
} }
......
...@@ -8,12 +8,13 @@ ...@@ -8,12 +8,13 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/module.h>
#include <linux/nvmem-provider.h> #include <linux/nvmem-provider.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/sched/signal.h> #include <linux/sched/signal.h>
#include <linux/sizes.h> #include <linux/sizes.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/string_helpers.h>
#include "tb.h" #include "tb.h"
...@@ -644,7 +645,7 @@ static int __tb_port_enable(struct tb_port *port, bool enable) ...@@ -644,7 +645,7 @@ static int __tb_port_enable(struct tb_port *port, bool enable)
if (ret) if (ret)
return ret; return ret;
tb_port_dbg(port, "lane %sabled\n", enable ? "en" : "dis"); tb_port_dbg(port, "lane %s\n", str_enabled_disabled(enable));
return 0; return 0;
} }
......
...@@ -361,6 +361,8 @@ struct tb_regs_port_header { ...@@ -361,6 +361,8 @@ struct tb_regs_port_header {
#define PORT_CS_18_BE BIT(8) #define PORT_CS_18_BE BIT(8)
#define PORT_CS_18_TCM BIT(9) #define PORT_CS_18_TCM BIT(9)
#define PORT_CS_18_CPS BIT(10) #define PORT_CS_18_CPS BIT(10)
#define PORT_CS_18_WOCS BIT(16)
#define PORT_CS_18_WODS BIT(17)
#define PORT_CS_18_WOU4S BIT(18) #define PORT_CS_18_WOU4S BIT(18)
#define PORT_CS_19 0x13 #define PORT_CS_19 0x13
#define PORT_CS_19_PC BIT(3) #define PORT_CS_19_PC BIT(3)
......
...@@ -155,6 +155,8 @@ static inline int usb4_switch_op_data(struct tb_switch *sw, u16 opcode, ...@@ -155,6 +155,8 @@ static inline int usb4_switch_op_data(struct tb_switch *sw, u16 opcode,
static void usb4_switch_check_wakes(struct tb_switch *sw) static void usb4_switch_check_wakes(struct tb_switch *sw)
{ {
bool wakeup_usb4 = false;
struct usb4_port *usb4;
struct tb_port *port; struct tb_port *port;
bool wakeup = false; bool wakeup = false;
u32 val; u32 val;
...@@ -173,20 +175,31 @@ static void usb4_switch_check_wakes(struct tb_switch *sw) ...@@ -173,20 +175,31 @@ static void usb4_switch_check_wakes(struct tb_switch *sw)
wakeup = val & (ROUTER_CS_6_WOPS | ROUTER_CS_6_WOUS); wakeup = val & (ROUTER_CS_6_WOPS | ROUTER_CS_6_WOUS);
} }
/* Check for any connected downstream ports for USB4 wake */ /*
* Check for any downstream ports for USB4 wake,
* connection wake and disconnection wake.
*/
tb_switch_for_each_port(sw, port) { tb_switch_for_each_port(sw, port) {
if (!tb_port_has_remote(port)) if (!port->cap_usb4)
continue; continue;
if (tb_port_read(port, &val, TB_CFG_PORT, if (tb_port_read(port, &val, TB_CFG_PORT,
port->cap_usb4 + PORT_CS_18, 1)) port->cap_usb4 + PORT_CS_18, 1))
break; break;
tb_port_dbg(port, "USB4 wake: %s\n", tb_port_dbg(port, "USB4 wake: %s, connection wake: %s, disconnection wake: %s\n",
(val & PORT_CS_18_WOU4S) ? "yes" : "no"); (val & PORT_CS_18_WOU4S) ? "yes" : "no",
(val & PORT_CS_18_WOCS) ? "yes" : "no",
(val & PORT_CS_18_WODS) ? "yes" : "no");
wakeup_usb4 = val & (PORT_CS_18_WOU4S | PORT_CS_18_WOCS |
PORT_CS_18_WODS);
usb4 = port->usb4;
if (device_may_wakeup(&usb4->dev) && wakeup_usb4)
pm_wakeup_event(&usb4->dev, 0);
if (val & PORT_CS_18_WOU4S) wakeup |= wakeup_usb4;
wakeup = true;
} }
if (wakeup) if (wakeup)
...@@ -366,6 +379,7 @@ bool usb4_switch_lane_bonding_possible(struct tb_switch *sw) ...@@ -366,6 +379,7 @@ bool usb4_switch_lane_bonding_possible(struct tb_switch *sw)
*/ */
int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags) int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags)
{ {
struct usb4_port *usb4;
struct tb_port *port; struct tb_port *port;
u64 route = tb_route(sw); u64 route = tb_route(sw);
u32 val; u32 val;
...@@ -395,10 +409,13 @@ int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags) ...@@ -395,10 +409,13 @@ int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags)
val |= PORT_CS_19_WOU4; val |= PORT_CS_19_WOU4;
} else { } else {
bool configured = val & PORT_CS_19_PC; bool configured = val & PORT_CS_19_PC;
usb4 = port->usb4;
if ((flags & TB_WAKE_ON_CONNECT) && !configured) if (((flags & TB_WAKE_ON_CONNECT) |
device_may_wakeup(&usb4->dev)) && !configured)
val |= PORT_CS_19_WOC; val |= PORT_CS_19_WOC;
if ((flags & TB_WAKE_ON_DISCONNECT) && configured) if (((flags & TB_WAKE_ON_DISCONNECT) |
device_may_wakeup(&usb4->dev)) && configured)
val |= PORT_CS_19_WOD; val |= PORT_CS_19_WOD;
if ((flags & TB_WAKE_ON_USB4) && configured) if ((flags & TB_WAKE_ON_USB4) && configured)
val |= PORT_CS_19_WOU4; val |= PORT_CS_19_WOU4;
......
...@@ -284,6 +284,9 @@ struct usb4_port *usb4_port_device_add(struct tb_port *port) ...@@ -284,6 +284,9 @@ struct usb4_port *usb4_port_device_add(struct tb_port *port)
} }
} }
if (!tb_is_upstream_port(port))
device_set_wakeup_capable(&usb4->dev, true);
pm_runtime_no_callbacks(&usb4->dev); pm_runtime_no_callbacks(&usb4->dev);
pm_runtime_set_active(&usb4->dev); pm_runtime_set_active(&usb4->dev);
pm_runtime_enable(&usb4->dev); pm_runtime_enable(&usb4->dev);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/prandom.h> #include <linux/prandom.h>
#include <linux/string_helpers.h>
#include <linux/utsname.h> #include <linux/utsname.h>
#include <linux/uuid.h> #include <linux/uuid.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
...@@ -341,7 +342,6 @@ static int tb_xdp_properties_request(struct tb_ctl *ctl, u64 route, ...@@ -341,7 +342,6 @@ static int tb_xdp_properties_request(struct tb_ctl *ctl, u64 route,
memcpy(&req.src_uuid, src_uuid, sizeof(*src_uuid)); memcpy(&req.src_uuid, src_uuid, sizeof(*src_uuid));
memcpy(&req.dst_uuid, dst_uuid, sizeof(*dst_uuid)); memcpy(&req.dst_uuid, dst_uuid, sizeof(*dst_uuid));
len = 0;
data_len = 0; data_len = 0;
do { do {
...@@ -1344,7 +1344,7 @@ static int tb_xdomain_bond_lanes_uuid_high(struct tb_xdomain *xd) ...@@ -1344,7 +1344,7 @@ static int tb_xdomain_bond_lanes_uuid_high(struct tb_xdomain *xd)
tb_port_update_credits(port); tb_port_update_credits(port);
tb_xdomain_update_link_attributes(xd); tb_xdomain_update_link_attributes(xd);
dev_dbg(&xd->dev, "lane bonding %sabled\n", width == 2 ? "en" : "dis"); dev_dbg(&xd->dev, "lane bonding %s\n", str_enabled_disabled(width == 2));
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment