diff options
author | Mika Westerberg <mika.westerberg@linux.intel.com> | 2020-04-02 11:42:44 +0200 |
---|---|---|
committer | Mika Westerberg <mika.westerberg@linux.intel.com> | 2020-09-03 11:06:41 +0200 |
commit | e28178bf566cf7281b513856aa71a8d41aa81154 (patch) | |
tree | a80cfb170eec85f5a2e26535d4b0e536f3cba0ec /drivers/thunderbolt/usb4.c | |
parent | thunderbolt: Configure link after lane bonding is enabled (diff) | |
download | linux-e28178bf566cf7281b513856aa71a8d41aa81154.tar.xz linux-e28178bf566cf7281b513856aa71a8d41aa81154.zip |
thunderbolt: Set port configured for both ends of the link
Both ends of the link needs to have this set. Otherwise the link is not
re-established properly after sleep. Now since it is possible to have
mixed USB4 and Thunderbolt 1, 2 and 3 devices we need to split the link
configuration functionality to happen per port so we can pick the
correct implementation.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Diffstat (limited to 'drivers/thunderbolt/usb4.c')
-rw-r--r-- | drivers/thunderbolt/usb4.c | 92 |
1 files changed, 44 insertions, 48 deletions
diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index dd601a6db23c..b2677427789f 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -338,54 +338,6 @@ int usb4_switch_drom_read(struct tb_switch *sw, unsigned int address, void *buf, usb4_switch_drom_read_block, sw); } -static int usb4_set_port_configured(struct tb_port *port, bool configured) -{ - int ret; - u32 val; - - ret = tb_port_read(port, &val, TB_CFG_PORT, - port->cap_usb4 + PORT_CS_19, 1); - if (ret) - return ret; - - if (configured) - val |= PORT_CS_19_PC; - else - val &= ~PORT_CS_19_PC; - - return tb_port_write(port, &val, TB_CFG_PORT, - port->cap_usb4 + PORT_CS_19, 1); -} - -/** - * usb4_switch_configure_link() - Set upstream USB4 link configured - * @sw: USB4 router - * - * Sets the upstream USB4 link to be configured for power management - * purposes. - */ -int usb4_switch_configure_link(struct tb_switch *sw) -{ - struct tb_port *up; - - up = tb_upstream_port(sw); - return usb4_set_port_configured(up, true); -} - -/** - * usb4_switch_unconfigure_link() - Un-set upstream USB4 link configuration - * @sw: USB4 router - * - * Reverse of usb4_switch_configure_link(). - */ -void usb4_switch_unconfigure_link(struct tb_switch *sw) -{ - struct tb_port *up; - - up = tb_upstream_port(sw); - usb4_set_port_configured(up, false); -} - /** * usb4_switch_lane_bonding_possible() - Are conditions met for lane bonding * @sw: USB4 router @@ -789,6 +741,50 @@ int usb4_port_unlock(struct tb_port *port) return tb_port_write(port, &val, TB_CFG_PORT, ADP_CS_4, 1); } +static int usb4_port_set_configured(struct tb_port *port, bool configured) +{ + int ret; + u32 val; + + if (!port->cap_usb4) + return -EINVAL; + + ret = tb_port_read(port, &val, TB_CFG_PORT, + port->cap_usb4 + PORT_CS_19, 1); + if (ret) + return ret; + + if (configured) + val |= PORT_CS_19_PC; + else + val &= ~PORT_CS_19_PC; + + return tb_port_write(port, &val, TB_CFG_PORT, + port->cap_usb4 + PORT_CS_19, 1); +} + +/** + * usb4_port_configure() - Set USB4 port configured + * @port: USB4 router + * + * Sets the USB4 link to be configured for power management purposes. + */ +int usb4_port_configure(struct tb_port *port) +{ + return usb4_port_set_configured(port, true); +} + +/** + * usb4_port_unconfigure() - Set USB4 port unconfigured + * @port: USB4 router + * + * Sets the USB4 link to be unconfigured for power management purposes. + */ +void usb4_port_unconfigure(struct tb_port *port) +{ + usb4_port_set_configured(port, false); +} + static int usb4_port_wait_for_bit(struct tb_port *port, u32 offset, u32 bit, u32 value, int timeout_msec) { |