summaryrefslogtreecommitdiffstats
path: root/drivers/thunderbolt/switch.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-04 20:07:20 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-04 20:07:20 -0700
commit06dd3dfeea60e2a6457a6aedf97afc8e6d2ba497 (patch)
tree1d8b9efbd7cd3dbb5d7b7663d7fd2de61b26f453 /drivers/thunderbolt/switch.c
parent38047d5c269bbdedf900fc86954913f3dffa01f1 (diff)
parent86f690e8bfd124c38940e7ad58875ef383003348 (diff)
downloadlinux-06dd3dfeea60e2a6457a6aedf97afc8e6d2ba497.tar.bz2
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.c61
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);