Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Bogendoerfer <tbogendoerfer@suse.de>2018-11-08 15:24:18 +0100
committerThomas Bogendoerfer <tbogendoerfer@suse.de>2018-11-09 12:11:04 +0100
commit9358b55d7124cc5b05c86492dd7954f06c7c8bf2 (patch)
tree3f93b01cb9b9d1a5006ea285c44261429a40b1fd
parent1ffbf519057eec6fb82feb339970168d0e3edf5d (diff)
PCI: Add pcie_get_width_cap() to find max supported link width
-rw-r--r--drivers/pci/pci-sysfs.c10
-rw-r--r--drivers/pci/pci.c18
-rw-r--r--drivers/pci/pci.h1
3 files changed, 21 insertions, 8 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 6461a43cb651..7bc5808a23ea 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -166,15 +166,9 @@ static DEVICE_ATTR_RO(max_link_speed);
static ssize_t max_link_width_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct pci_dev *pci_dev = to_pci_dev(dev);
- u32 linkcap;
- int err;
-
- err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, &linkcap);
- if (err)
- return -EINVAL;
+ struct pci_dev *pdev = to_pci_dev(dev);
- return sprintf(buf, "%u\n", (linkcap & PCI_EXP_LNKCAP_MLW) >> 4);
+ return sprintf(buf, "%u\n", pcie_get_width_cap(pdev));
}
static DEVICE_ATTR_RO(max_link_width);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 106ead96c266..cf87025b0952 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -5157,6 +5157,24 @@ enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev)
}
/**
+ * pcie_get_width_cap - query for the PCI device's link width capability
+ * @dev: PCI device to query
+ *
+ * Query the PCI device width capability. Return the maximum link width
+ * supported by the device.
+ */
+enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev)
+{
+ u32 lnkcap;
+
+ pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap);
+ if (lnkcap)
+ return (lnkcap & PCI_EXP_LNKCAP_MLW) >> 4;
+
+ return PCIE_LNK_WIDTH_UNKNOWN;
+}
+
+/**
* pci_select_bars - Make BAR mask from the type of resource
* @dev: the PCI device for which BAR mask is made
* @flags: resource type mask to be selected
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index e6fe0b0a8fcb..b1a955aa376b 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -265,6 +265,7 @@ void pci_disable_bridge_window(struct pci_dev *dev);
"Unknown speed")
enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev);
+enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev);
/* Single Root I/O Virtualization */
struct pci_sriov {