diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pci/pci.c | 32 | ||||
-rw-r--r-- | drivers/pci/pci.h | 12 | ||||
-rw-r--r-- | drivers/pci/probe.c | 3 |
3 files changed, 47 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 553ca6657955..4db261e13e69 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1299,6 +1299,38 @@ void pci_pm_init(struct pci_dev *dev) | |||
1299 | } | 1299 | } |
1300 | } | 1300 | } |
1301 | 1301 | ||
1302 | /** | ||
1303 | * pci_enable_ari - enable ARI forwarding if hardware support it | ||
1304 | * @dev: the PCI device | ||
1305 | */ | ||
1306 | void pci_enable_ari(struct pci_dev *dev) | ||
1307 | { | ||
1308 | int pos; | ||
1309 | u32 cap; | ||
1310 | u16 ctrl; | ||
1311 | |||
1312 | if (!dev->is_pcie) | ||
1313 | return; | ||
1314 | |||
1315 | if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | ||
1316 | dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) | ||
1317 | return; | ||
1318 | |||
1319 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | ||
1320 | if (!pos) | ||
1321 | return; | ||
1322 | |||
1323 | pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap); | ||
1324 | if (!(cap & PCI_EXP_DEVCAP2_ARI)) | ||
1325 | return; | ||
1326 | |||
1327 | pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); | ||
1328 | ctrl |= PCI_EXP_DEVCTL2_ARI; | ||
1329 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); | ||
1330 | |||
1331 | dev->ari_enabled = 1; | ||
1332 | } | ||
1333 | |||
1302 | int | 1334 | int |
1303 | pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) | 1335 | pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) |
1304 | { | 1336 | { |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 601abdc8dd9f..39684c1415c5 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -151,4 +151,16 @@ struct pci_slot_attribute { | |||
151 | }; | 151 | }; |
152 | #define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr) | 152 | #define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr) |
153 | 153 | ||
154 | extern void pci_enable_ari(struct pci_dev *dev); | ||
155 | /** | ||
156 | * pci_ari_enabled - query ARI forwarding status | ||
157 | * @dev: the PCI device | ||
158 | * | ||
159 | * Returns 1 if ARI forwarding is enabled, or 0 if not enabled; | ||
160 | */ | ||
161 | static inline int pci_ari_enabled(struct pci_dev *dev) | ||
162 | { | ||
163 | return dev->ari_enabled; | ||
164 | } | ||
165 | |||
154 | #endif /* DRIVERS_PCI_H */ | 166 | #endif /* DRIVERS_PCI_H */ |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 8c158b9abd41..3141e8deeac4 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1025,6 +1025,9 @@ static void pci_init_capabilities(struct pci_dev *dev) | |||
1025 | 1025 | ||
1026 | /* Vital Product Data */ | 1026 | /* Vital Product Data */ |
1027 | pci_vpd_pci22_init(dev); | 1027 | pci_vpd_pci22_init(dev); |
1028 | |||
1029 | /* Alternative Routing-ID Forwarding */ | ||
1030 | pci_enable_ari(dev); | ||
1028 | } | 1031 | } |
1029 | 1032 | ||
1030 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | 1033 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) |