diff options
Diffstat (limited to 'drivers/thunderbolt/switch.c')
-rw-r--r-- | drivers/thunderbolt/switch.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index ad992e6204d9..cdba05e72486 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -1387,6 +1387,30 @@ static ssize_t authorized_show(struct device *dev, return sprintf(buf, "%u\n", sw->authorized); } +static int disapprove_switch(struct device *dev, void *not_used) +{ + struct tb_switch *sw; + + sw = tb_to_switch(dev); + if (sw && sw->authorized) { + int ret; + + /* First children */ + ret = device_for_each_child_reverse(&sw->dev, NULL, disapprove_switch); + if (ret) + return ret; + + ret = tb_domain_disapprove_switch(sw->tb, sw); + if (ret) + return ret; + + sw->authorized = 0; + kobject_uevent(&sw->dev.kobj, KOBJ_CHANGE); + } + + return 0; +} + static int tb_switch_set_authorized(struct tb_switch *sw, unsigned int val) { int ret = -EINVAL; @@ -1394,10 +1418,18 @@ static int tb_switch_set_authorized(struct tb_switch *sw, unsigned int val) if (!mutex_trylock(&sw->tb->lock)) return restart_syscall(); - if (sw->authorized) + if (!!sw->authorized == !!val) goto unlock; switch (val) { + /* Disapprove switch */ + case 0: + if (tb_route(sw)) { + ret = disapprove_switch(&sw->dev, NULL); + goto unlock; + } + break; + /* Approve switch */ case 1: if (sw->key) |