Skip to content

Commit dcd12ac

Browse files
Gil Finewesteri
authored andcommitted
thunderbolt: Avoid notify PM core about runtime PM resume
Currently we notify PM core about occurred wakes after any resume. This is not actually needed after resume from runtime suspend. Hence, notify PM core about occurred wakes only after resume from system sleep. Also, if the wake occurred in USB4 router upstream port, we don't notify the PM core about it since it is not actually needed and can cause unexpected autowake (e.g. if /sys/power/wakeup_count is used). While there add the missing kernel-doc for tb_switch_resume(). Signed-off-by: Gil Fine <gil.fine@linux.intel.com> Cc: stable@vger.kernel.org Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
1 parent c38fa07 commit dcd12ac

File tree

4 files changed

+36
-11
lines changed

4 files changed

+36
-11
lines changed

drivers/thunderbolt/switch.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3448,7 +3448,26 @@ static int tb_switch_set_wake(struct tb_switch *sw, unsigned int flags)
34483448
return tb_lc_set_wake(sw, flags);
34493449
}
34503450

3451-
int tb_switch_resume(struct tb_switch *sw)
3451+
static void tb_switch_check_wakes(struct tb_switch *sw)
3452+
{
3453+
if (device_may_wakeup(&sw->dev)) {
3454+
if (tb_switch_is_usb4(sw))
3455+
usb4_switch_check_wakes(sw);
3456+
}
3457+
}
3458+
3459+
/**
3460+
* tb_switch_resume() - Resume a switch after sleep
3461+
* @sw: Switch to resume
3462+
* @runtime: Is this resume from runtime suspend or system sleep
3463+
*
3464+
* Resumes and re-enumerates router (and all its children), if still plugged
3465+
* after suspend. Don't enumerate device router whose UID was changed during
3466+
* suspend. If this is resume from system sleep, notifies PM core about the
3467+
* wakes occurred during suspend. Disables all wakes, except USB4 wake of
3468+
* upstream port for USB4 routers that shall be always enabled.
3469+
*/
3470+
int tb_switch_resume(struct tb_switch *sw, bool runtime)
34523471
{
34533472
struct tb_port *port;
34543473
int err;
@@ -3497,6 +3516,9 @@ int tb_switch_resume(struct tb_switch *sw)
34973516
if (err)
34983517
return err;
34993518

3519+
if (!runtime)
3520+
tb_switch_check_wakes(sw);
3521+
35003522
/* Disable wakes */
35013523
tb_switch_set_wake(sw, 0);
35023524

@@ -3526,7 +3548,8 @@ int tb_switch_resume(struct tb_switch *sw)
35263548
*/
35273549
if (tb_port_unlock(port))
35283550
tb_port_warn(port, "failed to unlock port\n");
3529-
if (port->remote && tb_switch_resume(port->remote->sw)) {
3551+
if (port->remote &&
3552+
tb_switch_resume(port->remote->sw, runtime)) {
35303553
tb_port_warn(port,
35313554
"lost during suspend, disconnecting\n");
35323555
tb_sw_set_unplugged(port->remote->sw);

drivers/thunderbolt/tb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2942,7 +2942,7 @@ static int tb_resume_noirq(struct tb *tb)
29422942
if (!tb_switch_is_usb4(tb->root_switch))
29432943
tb_switch_reset(tb->root_switch);
29442944

2945-
tb_switch_resume(tb->root_switch);
2945+
tb_switch_resume(tb->root_switch, false);
29462946
tb_free_invalid_tunnels(tb);
29472947
tb_free_unplugged_children(tb->root_switch);
29482948
tb_restore_children(tb->root_switch);
@@ -3068,7 +3068,7 @@ static int tb_runtime_resume(struct tb *tb)
30683068
struct tb_tunnel *tunnel, *n;
30693069

30703070
mutex_lock(&tb->lock);
3071-
tb_switch_resume(tb->root_switch);
3071+
tb_switch_resume(tb->root_switch, true);
30723072
tb_free_invalid_tunnels(tb);
30733073
tb_restore_children(tb->root_switch);
30743074
list_for_each_entry_safe(tunnel, n, &tcm->tunnel_list, list)

drivers/thunderbolt/tb.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,7 @@ int tb_switch_configuration_valid(struct tb_switch *sw);
827827
int tb_switch_add(struct tb_switch *sw);
828828
void tb_switch_remove(struct tb_switch *sw);
829829
void tb_switch_suspend(struct tb_switch *sw, bool runtime);
830-
int tb_switch_resume(struct tb_switch *sw);
830+
int tb_switch_resume(struct tb_switch *sw, bool runtime);
831831
int tb_switch_reset(struct tb_switch *sw);
832832
int tb_switch_wait_for_bit(struct tb_switch *sw, u32 offset, u32 bit,
833833
u32 value, int timeout_msec);
@@ -1288,6 +1288,7 @@ static inline bool tb_switch_is_usb4(const struct tb_switch *sw)
12881288
return usb4_switch_version(sw) > 0;
12891289
}
12901290

1291+
void usb4_switch_check_wakes(struct tb_switch *sw);
12911292
int usb4_switch_setup(struct tb_switch *sw);
12921293
int usb4_switch_configuration_valid(struct tb_switch *sw);
12931294
int usb4_switch_read_uid(struct tb_switch *sw, u64 *uid);

drivers/thunderbolt/usb4.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,17 +155,20 @@ static inline int usb4_switch_op_data(struct tb_switch *sw, u16 opcode,
155155
tx_dwords, rx_data, rx_dwords);
156156
}
157157

158-
static void usb4_switch_check_wakes(struct tb_switch *sw)
158+
/**
159+
* usb4_switch_check_wakes() - Check for wakes and notify PM core about them
160+
* @sw: Router whose wakes to check
161+
*
162+
* Checks wakes occurred during suspend and notify the PM core about them.
163+
*/
164+
void usb4_switch_check_wakes(struct tb_switch *sw)
159165
{
160166
bool wakeup_usb4 = false;
161167
struct usb4_port *usb4;
162168
struct tb_port *port;
163169
bool wakeup = false;
164170
u32 val;
165171

166-
if (!device_may_wakeup(&sw->dev))
167-
return;
168-
169172
if (tb_route(sw)) {
170173
if (tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_6, 1))
171174
return;
@@ -244,8 +247,6 @@ int usb4_switch_setup(struct tb_switch *sw)
244247
u32 val = 0;
245248
int ret;
246249

247-
usb4_switch_check_wakes(sw);
248-
249250
if (!tb_route(sw))
250251
return 0;
251252

0 commit comments

Comments
 (0)