diff options
Diffstat (limited to 'drivers/thunderbolt/usb4.c')
| -rw-r--r-- | drivers/thunderbolt/usb4.c | 33 | 
1 files changed, 25 insertions, 8 deletions
diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c index f986854aa207..2ed50fcbcca7 100644 --- a/drivers/thunderbolt/usb4.c +++ b/drivers/thunderbolt/usb4.c @@ -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)  { +	bool wakeup_usb4 = false; +	struct usb4_port *usb4;  	struct tb_port *port;  	bool wakeup = false;  	u32 val; @@ -173,20 +175,31 @@ static void usb4_switch_check_wakes(struct tb_switch *sw)  		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) { -		if (!tb_port_has_remote(port)) +		if (!port->cap_usb4)  			continue;  		if (tb_port_read(port, &val, TB_CFG_PORT,  				 port->cap_usb4 + PORT_CS_18, 1))  			break; -		tb_port_dbg(port, "USB4 wake: %s\n", -			    (val & PORT_CS_18_WOU4S) ? "yes" : "no"); +		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_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 = true; +		wakeup |= wakeup_usb4;  	}  	if (wakeup) @@ -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)  { +	struct usb4_port *usb4;  	struct tb_port *port;  	u64 route = tb_route(sw);  	u32 val; @@ -395,10 +409,13 @@ int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags)  			val |= PORT_CS_19_WOU4;  		} else {  			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; -			if ((flags & TB_WAKE_ON_DISCONNECT) && configured) +			if (((flags & TB_WAKE_ON_DISCONNECT) | +			      device_may_wakeup(&usb4->dev)) && configured)  				val |= PORT_CS_19_WOD;  			if ((flags & TB_WAKE_ON_USB4) && configured)  				val |= PORT_CS_19_WOU4;  |