aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/pci.c35
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/probe.c5
3 files changed, 42 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 4859669f0ab5..557218222826 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1546,6 +1546,41 @@ void pci_enable_ari(struct pci_dev *dev)
1546} 1546}
1547 1547
1548/** 1548/**
1549 * pci_enable_acs - enable ACS if hardware support it
1550 * @dev: the PCI device
1551 */
1552void pci_enable_acs(struct pci_dev *dev)
1553{
1554 int pos;
1555 u16 cap;
1556 u16 ctrl;
1557
1558 if (!dev->is_pcie)
1559 return;
1560
1561 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
1562 if (!pos)
1563 return;
1564
1565 pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap);
1566 pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl);
1567
1568 /* Source Validation */
1569 ctrl |= (cap & PCI_ACS_SV);
1570
1571 /* P2P Request Redirect */
1572 ctrl |= (cap & PCI_ACS_RR);
1573
1574 /* P2P Completion Redirect */
1575 ctrl |= (cap & PCI_ACS_CR);
1576
1577 /* Upstream Forwarding */
1578 ctrl |= (cap & PCI_ACS_UF);
1579
1580 pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
1581}
1582
1583/**
1549 * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge 1584 * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
1550 * @dev: the PCI device 1585 * @dev: the PCI device
1551 * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTD, 4=INTD) 1586 * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTD, 4=INTD)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index d92d1954a2fb..33ed8e0aba1e 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -311,4 +311,6 @@ static inline int pci_resource_alignment(struct pci_dev *dev,
311 return resource_alignment(res); 311 return resource_alignment(res);
312} 312}
313 313
314extern void pci_enable_acs(struct pci_dev *dev);
315
314#endif /* DRIVERS_PCI_H */ 316#endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 2adb47574d86..aac5b156a5c5 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -10,6 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/cpumask.h> 11#include <linux/cpumask.h>
12#include <linux/pci-aspm.h> 12#include <linux/pci-aspm.h>
13#include <linux/iommu.h>
13#include "pci.h" 14#include "pci.h"
14 15
15#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ 16#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */
@@ -1004,6 +1005,10 @@ static void pci_init_capabilities(struct pci_dev *dev)
1004 1005
1005 /* Single Root I/O Virtualization */ 1006 /* Single Root I/O Virtualization */
1006 pci_iov_init(dev); 1007 pci_iov_init(dev);
1008
1009 /* Enable ACS P2P upstream forwarding */
1010 if (iommu_found())
1011 pci_enable_acs(dev);
1007} 1012}
1008 1013
1009void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) 1014void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)