diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-04 20:07:20 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-04 20:07:20 -0700 |
commit | 06dd3dfeea60e2a6457a6aedf97afc8e6d2ba497 (patch) | |
tree | 1d8b9efbd7cd3dbb5d7b7663d7fd2de61b26f453 /drivers/thunderbolt/switch.c | |
parent | 38047d5c269bbdedf900fc86954913f3dffa01f1 (diff) | |
parent | 86f690e8bfd124c38940e7ad58875ef383003348 (diff) |
Merge tag 'char-misc-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc updates from Greg KH:
"Here is the big set of char/misc driver patches for 4.17-rc1.
There are a lot of little things in here, nothing huge, but all
important to the different hardware types involved:
- thunderbolt driver updates
- parport updates (people still care...)
- nvmem driver updates
- mei updates (as always)
- hwtracing driver updates
- hyperv driver updates
- extcon driver updates
- ... and a handful of even smaller driver subsystem and individual
driver updates
All of these have been in linux-next with no reported issues"
* tag 'char-misc-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (149 commits)
hwtracing: Add HW tracing support menu
intel_th: Add ACPI glue layer
intel_th: Allow forcing host mode through drvdata
intel_th: Pick up irq number from resources
intel_th: Don't touch switch routing in host mode
intel_th: Use correct method of finding hub
intel_th: Add SPDX GPL-2.0 header to replace GPLv2 boilerplate
stm class: Make dummy's master/channel ranges configurable
stm class: Add SPDX GPL-2.0 header to replace GPLv2 boilerplate
MAINTAINERS: Bestow upon myself the care for drivers/hwtracing
hv: add SPDX license id to Kconfig
hv: add SPDX license to trace
Drivers: hv: vmbus: do not mark HV_PCIE as perf_device
Drivers: hv: vmbus: respect what we get from hv_get_synint_state()
/dev/mem: Avoid overwriting "err" in read_mem()
eeprom: at24: use SPDX identifier instead of GPL boiler-plate
eeprom: at24: simplify the i2c functionality checking
eeprom: at24: fix a line break
eeprom: at24: tweak newlines
eeprom: at24: refactor at24_probe()
...
Diffstat (limited to 'drivers/thunderbolt/switch.c')
-rw-r--r-- | drivers/thunderbolt/switch.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index da54ace4dd2f..25758671ddf4 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -716,6 +716,13 @@ static int tb_switch_set_authorized(struct tb_switch *sw, unsigned int val) if (sw->authorized) goto unlock; + /* + * Make sure there is no PCIe rescan ongoing when a new PCIe + * tunnel is created. Otherwise the PCIe rescan code might find + * the new tunnel too early. + */ + pci_lock_rescan_remove(); + switch (val) { /* Approve switch */ case 1: @@ -735,6 +742,8 @@ static int tb_switch_set_authorized(struct tb_switch *sw, unsigned int val) break; } + pci_unlock_rescan_remove(); + if (!ret) { sw->authorized = val; /* Notify status change to the userspace */ @@ -766,6 +775,15 @@ static ssize_t authorized_store(struct device *dev, } static DEVICE_ATTR_RW(authorized); +static ssize_t boot_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct tb_switch *sw = tb_to_switch(dev); + + return sprintf(buf, "%u\n", sw->boot); +} +static DEVICE_ATTR_RO(boot); + static ssize_t device_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -942,6 +960,7 @@ static DEVICE_ATTR_RO(unique_id); static struct attribute *switch_attrs[] = { &dev_attr_authorized.attr, + &dev_attr_boot.attr, &dev_attr_device.attr, &dev_attr_device_name.attr, &dev_attr_key.attr, @@ -970,6 +989,10 @@ static umode_t switch_attr_is_visible(struct kobject *kobj, if (sw->dma_port) return attr->mode; return 0; + } else if (attr == &dev_attr_boot.attr) { + if (tb_route(sw)) + return attr->mode; + return 0; } return sw->safe_mode ? 0 : attr->mode; @@ -1028,6 +1051,9 @@ static int tb_switch_get_generation(struct tb_switch *sw) case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE: case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_BRIDGE: case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_BRIDGE: + case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_BRIDGE: + case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_BRIDGE: + case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_BRIDGE: return 3; default: @@ -1470,6 +1496,7 @@ struct tb_sw_lookup { u8 link; u8 depth; const uuid_t *uuid; + u64 route; }; static int tb_switch_match(struct device *dev, void *data) @@ -1485,6 +1512,11 @@ static int tb_switch_match(struct device *dev, void *data) if (lookup->uuid) return !memcmp(sw->uuid, lookup->uuid, sizeof(*lookup->uuid)); + if (lookup->route) { + return sw->config.route_lo == lower_32_bits(lookup->route) && + sw->config.route_hi == upper_32_bits(lookup->route); + } + /* Root switch is matched only by depth */ if (!lookup->depth) return !sw->depth; @@ -1519,7 +1551,7 @@ struct tb_switch *tb_switch_find_by_link_depth(struct tb *tb, u8 link, u8 depth) } /** - * tb_switch_find_by_link_depth() - Find switch by UUID + * tb_switch_find_by_uuid() - Find switch by UUID * @tb: Domain the switch belongs * @uuid: UUID to look for * @@ -1542,6 +1574,33 @@ struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_t *uuid) return NULL; } +/** + * tb_switch_find_by_route() - Find switch by route string + * @tb: Domain the switch belongs + * @route: Route string to look for + * + * Returned switch has reference count increased so the caller needs to + * call tb_switch_put() when done with the switch. + */ +struct tb_switch *tb_switch_find_by_route(struct tb *tb, u64 route) +{ + struct tb_sw_lookup lookup; + struct device *dev; + + if (!route) + return tb_switch_get(tb->root_switch); + + memset(&lookup, 0, sizeof(lookup)); + lookup.tb = tb; + lookup.route = route; + + dev = bus_find_device(&tb_bus_type, NULL, &lookup, tb_switch_match); + if (dev) + return tb_to_switch(dev); + + return NULL; +} + void tb_switch_exit(void) { ida_destroy(&nvm_ida); |