In order to enable PTM feature in a PCIe Endpoint, it is required to enable this feature as well in all devices capable (if present) in the datapath between the Root complex and the referred Endpoint e.g. PCIe switches. RC <--> Switch (USP) <-> Switch (DSP) <-> EP According to PCIe specification Rev5 (6.22.3.2) and (7.9.16), in order to enable this feature on a PTM capable switch, it's required to write a enable bit in the switch upstream port (USP) control register, which after that must respond to all PTM request messages received at any of its downstream ports (DSP). The previous implementation verifies if the PCIe switch has the PTM feature enabled on both streams ports (USP and DSP). Since the DSP doesn't support PTM capability, the previous implementation doesn't allow the PTM feature to be enabled in the Endpoint, the current patch fixes this. Fixes: eec097d43100 ("PCI: Add pci_enable_ptm() for drivers to enable PTM on endpoints") Signed-off-by: Aditya Paluri <venkata.adityapaluri@xxxxxxxxxxxx> Signed-off-by: Gustavo Pimentel <gustavo.pimentel@xxxxxxxxxxxx> Cc: linux-pci@xxxxxxxxxxxxxxx Cc: Joao Pinto <jpinto@xxxxxxxxxxxx> --- drivers/pci/pcie/ptm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c index 9361f3a..cd85d44 100644 --- a/drivers/pci/pcie/ptm.c +++ b/drivers/pci/pcie/ptm.c @@ -111,6 +111,14 @@ int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) */ if (pci_pcie_type(dev) == PCI_EXP_TYPE_ENDPOINT) { ups = pci_upstream_bridge(dev); + /* + * Per PCIe r5.0, sec 7.9.16, the PTM capability is not + * permitted in Switch Downstream Ports + */ + if (ups && ups->hdr_type == PCI_HEADER_TYPE_BRIDGE && + pci_pcie_type(ups) == PCI_EXP_TYPE_DOWNSTREAM) + ups = pci_upstream_bridge(ups); + if (!ups || !ups->ptm_enabled) return -EINVAL; -- 2.7.4