@@ -215,15 +215,8 @@ static ssize_t current_link_width_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- u16 linkstat;
- int err;
- err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &linkstat);
- if (err)
- return -EINVAL;
-
- return sysfs_emit(buf, "%u\n",
- (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT);
+ return sysfs_emit(buf, "%u\n", pcie_get_width(pci_dev));
}
static DEVICE_ATTR_RO(current_link_width);
@@ -6235,6 +6235,26 @@ enum pci_bus_speed pcie_get_speed(struct pci_dev *dev)
}
EXPORT_SYMBOL(pcie_get_speed);
+/**
+ * pcie_get_width - query for the PCI device's current link width
+ * @dev: PCI device to query
+ *
+ * Query the PCI device current negoiated width.
+ */
+
+enum pcie_link_width pcie_get_width(struct pci_dev *dev)
+{
+ u16 linkstat;
+ int err;
+
+ err = pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat);
+ if (err)
+ return PCIE_LNK_WIDTH_UNKNOWN;
+
+ return FIELD_GET(PCI_EXP_LNKSTA_NLW, linkstat);
+}
+EXPORT_SYMBOL(pcie_get_width);
+
/**
* pcie_bandwidth_capable - calculate a PCI device's link bandwidth capability
* @dev: PCI device
@@ -305,6 +305,7 @@ enum pci_bus_speed {
enum pci_bus_speed pcie_get_speed(struct pci_dev *dev);
enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev);
+enum pcie_link_width pcie_get_width(struct pci_dev *dev);
enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev);
struct pci_vpd {
Move the logic in current_link_width_show() to a common function and export that functiuon as pcie_get_width() to allow other drivers to to retrieve the current negotiated link width. Signed-off-by: Dave Jiang <dave.jiang@intel.com> --- drivers/pci/pci-sysfs.c | 9 +-------- drivers/pci/pci.c | 20 ++++++++++++++++++++ include/linux/pci.h | 1 + 3 files changed, 22 insertions(+), 8 deletions(-)