From c5dc3c69f17a7e77359f10c342d1816390bc8846 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 19 Jun 2017 20:04:58 +0200 Subject: PCI/portdrv: Move error handler methods to struct pcie_port_service_driver Move the error handler methods to struct pcie_port_service_driver and avoid the detour through the mostly unused pci_error_handlers structure. Signed-off-by: Christoph Hellwig Signed-off-by: Bjorn Helgaas --- include/linux/pcieport_if.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pcieport_if.h b/include/linux/pcieport_if.h index afcd130ab3a9..18edc651c070 100644 --- a/include/linux/pcieport_if.h +++ b/include/linux/pcieport_if.h @@ -50,8 +50,8 @@ struct pcie_port_service_driver { int (*suspend) (struct pcie_device *dev); int (*resume) (struct pcie_device *dev); - /* Service Error Recovery Handler */ - const struct pci_error_handlers *err_handler; + /* Device driver may resume normal operations */ + void (*error_resume)(struct pci_dev *dev); /* Link Reset Capability - AER service driver specific */ pci_ers_result_t (*reset_link) (struct pci_dev *dev); -- cgit v1.2.3 From 62ce94a7a5a54aac80975f5e6731707225d4077e Mon Sep 17 00:00:00 2001 From: Sinan Kaya Date: Wed, 12 Jul 2017 00:04:14 -0400 Subject: PCI: Mark Broadcom HT2100 Root Port Extended Tags as broken Per PCIe r3.1, sec 2.2.6.2 and 7.8.4, a Requester may not use 8-bit Tags unless its Extended Tag Field Enable is set, but all Receivers/Completers must handle 8-bit Tags correctly regardless of their Extended Tag Field Enable. Some devices do not handle 8-bit Tags as Completers, so add a quirk for them. If we find such a device, we disable Extended Tags for the entire hierarchy to make peer-to-peer DMA possible. The Broadcom HT2100 seems to have issues with handling 8-bit tags. Mark it as broken. The pci_walk_bus() in the quirk handles devices we've enumerated in the past, and pci_configure_device() handles devices we enumerate in the future. Fixes: 60db3a4d8cc9 ("PCI: Enable PCIe Extended Tags if supported") Link: https://bugzilla.redhat.com/show_bug.cgi?id=1467674 Reported-and-tested-by: Wim ten Have Signed-off-by: Sinan Kaya [bhelgaas: changelog, tweak messages, rename bit and quirk] Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 4869e66dd659..3b968d435895 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -451,6 +451,7 @@ struct pci_host_bridge { void *release_data; struct msi_controller *msi; unsigned int ignore_reset_delay:1; /* for entire hierarchy */ + unsigned int no_ext_tags:1; /* no Extended Tags */ /* Resource alignment requirements */ resource_size_t (*align_resource)(struct pci_dev *dev, const struct resource *res, -- cgit v1.2.3 From 004cb784018eaa2a078912180bd9999707c3c483 Mon Sep 17 00:00:00 2001 From: Matthew Minter Date: Mon, 31 Jul 2017 17:37:57 +0100 Subject: PCI: Remove unused pci_fixup_irqs() function Now we have removed all callers of pci_fixup_irqs() and migrated everything to pci_assign_irq(), delete the pci_fixup_irqs() function completely. Signed-off-by: Matthew Minter [lorenzo.pieralisi@arm.com: updated commit log] Signed-off-by: Lorenzo Pieralisi Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 4869e66dd659..69034ab8a68e 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1160,8 +1160,6 @@ void pci_assign_unassigned_bus_resources(struct pci_bus *bus); void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus); void pdev_enable_device(struct pci_dev *); int pci_enable_resources(struct pci_dev *, int mask); -void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *), - int (*)(const struct pci_dev *, u8, u8)); void pci_assign_irq(struct pci_dev *dev); struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res); #define HAVE_PCI_REQ_REGIONS 2 -- cgit v1.2.3 From 606799cc5049ae4ccb51ba3242365ca2d411da13 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 10 Aug 2017 12:49:57 -0500 Subject: PCI: Inline and remove pcibios_update_irq() pcibios_update_irq() was a weak function with only one trivial implementation. Inline it and remove the weak function. Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 69034ab8a68e..a9e8d2f3bd91 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -844,7 +844,6 @@ char *pcibios_setup(char *str); resource_size_t pcibios_align_resource(void *, const struct resource *, resource_size_t, resource_size_t); -void pcibios_update_irq(struct pci_dev *, int irq); /* Weak but can be overriden by arch */ void pci_fixup_cardbus(struct pci_bus *); -- cgit v1.2.3 From b352baf15b66c5799018104d38f9eb77c7445a34 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Tue, 15 Aug 2017 12:02:16 -0700 Subject: PCI: Move enum pci_interrupt_pin to linux/pci.h We currently have a definition of enum pci_interrupt_pin in a header specific to PCI endpoints - linux/pci-epf.h. In order to allow for use of this enum from PCI host code in a future commit, move its definition to linux/pci.h & include that from linux/pci-epf.h. Additionally we add a PCI_NUM_INTX macro which indicates the number of PCI INTx interrupts, and will be used alongside enum pci_interrupt_pin in further patches. Signed-off-by: Paul Burton [bhelgaas: move enum pci_interrupt_pin outside #ifdef CONFIG_PCI] Signed-off-by: Bjorn Helgaas --- include/linux/pci-epf.h | 9 +-------- include/linux/pci.h | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h index 0d529cb90143..bc8750688348 100644 --- a/include/linux/pci-epf.h +++ b/include/linux/pci-epf.h @@ -14,17 +14,10 @@ #include #include +#include struct pci_epf; -enum pci_interrupt_pin { - PCI_INTERRUPT_UNKNOWN, - PCI_INTERRUPT_INTA, - PCI_INTERRUPT_INTB, - PCI_INTERRUPT_INTC, - PCI_INTERRUPT_INTD, -}; - enum pci_barno { BAR_0, BAR_1, diff --git a/include/linux/pci.h b/include/linux/pci.h index 4869e66dd659..bb9c367c85f0 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -102,6 +102,28 @@ enum { DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES, }; +/** + * enum pci_interrupt_pin - PCI INTx interrupt values + * @PCI_INTERRUPT_UNKNOWN: Unknown or unassigned interrupt + * @PCI_INTERRUPT_INTA: PCI INTA pin + * @PCI_INTERRUPT_INTB: PCI INTB pin + * @PCI_INTERRUPT_INTC: PCI INTC pin + * @PCI_INTERRUPT_INTD: PCI INTD pin + * + * Corresponds to values for legacy PCI INTx interrupts, as can be found in the + * PCI_INTERRUPT_PIN register. + */ +enum pci_interrupt_pin { + PCI_INTERRUPT_UNKNOWN, + PCI_INTERRUPT_INTA, + PCI_INTERRUPT_INTB, + PCI_INTERRUPT_INTC, + PCI_INTERRUPT_INTD, +}; + +/* The number of legacy PCI INTx interrupts */ +#define PCI_NUM_INTX 4 + /* * pci_power_t values must match the bits in the Capabilities PME_Support * and Control/Status PowerState fields in the Power Management capability. -- cgit v1.2.3 From 0d58e6c1b19b30623b5f0a053818bd2c32d61166 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Tue, 15 Aug 2017 12:02:17 -0700 Subject: PCI: Add pci_irqd_intx_xlate() Legacy PCI INTx interrupts are represented in the PCI_INTERRUPT_PIN register using the range 1-4, which matches our enum pci_interrupt_pin. This is however not ideal for an IRQ domain, where with 4 interrupts we would ideally have a domain of size 4 & hwirq numbers in the range 0-3. Different PCI host controller drivers have handled this in different ways. Of those under drivers/pci/ which register an INTx IRQ domain, we have: - pcie-altera uses the range 1-4 in device trees and an IRQ domain of size 5 to cover that range, with entry 0 wasted. - pcie-xilinx & pcie-xilinx-nwl use the range 1-4 in device trees but register an IRQ domain of size 4, which doesn't cover the hwirq=4/INTD case leading to that interrupt being broken. - pci-ftpci100 & pci-aardvark use the range 0-3 in both device trees & as hwirq numbering in the driver & IRQ domain. In order to introduce some level of consistency in at least the hwirq numbering used by the drivers & IRQ domains, this patch introduces a new pci_irqd_intx_xlate() helper function which drivers using the 1-4 range in device trees can assign as the xlate callback for their INTx IRQ domain. This translates the 1-4 range into a 0-3 range, allowing us to use an IRQ domain of size 4 & avoid a wasted entry. Further patches will make use of this in drivers to allow them to use an IRQ domain of size 4 for legacy INTx interrupts without breaking INTD. Signed-off-by: Paul Burton Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index bb9c367c85f0..bbc2a991b63f 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1416,6 +1416,38 @@ pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, NULL); } +/** + * pci_irqd_intx_xlate() - Translate PCI INTx value to an IRQ domain hwirq + * @d: the INTx IRQ domain + * @node: the DT node for the device whose interrupt we're translating + * @intspec: the interrupt specifier data from the DT + * @intsize: the number of entries in @intspec + * @out_hwirq: pointer at which to write the hwirq number + * @out_type: pointer at which to write the interrupt type + * + * Translate a PCI INTx interrupt number from device tree in the range 1-4, as + * stored in the standard PCI_INTERRUPT_PIN register, to a value in the range + * 0-3 suitable for use in a 4 entry IRQ domain. That is, subtract one from the + * INTx value to obtain the hwirq number. + * + * Returns 0 on success, or -EINVAL if the interrupt specifier is out of range. + */ +static inline int pci_irqd_intx_xlate(struct irq_domain *d, + struct device_node *node, + const u32 *intspec, + unsigned int intsize, + unsigned long *out_hwirq, + unsigned int *out_type) +{ + const u32 intx = intspec[0]; + + if (intx < PCI_INTERRUPT_INTA || intx > PCI_INTERRUPT_INTD) + return -EINVAL; + + *out_hwirq = intx - PCI_INTERRUPT_INTA; + return 0; +} + #ifdef CONFIG_PCIEPORTBUS extern bool pcie_ports_disabled; extern bool pcie_ports_auto; -- cgit v1.2.3 From f01f969e25ecc6f88844bcdd63f1f27610418bbc Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 18 Aug 2017 20:27:54 +0530 Subject: PCI: endpoint: Add an API to get matching "pci_epf_device_id" Add an API to get "pci_epf_device_id" matching the EPF name. This can be used by the EPF driver to get the driver data corresponding to the EPF device name. Signed-off-by: Kishon Vijay Abraham I [bhelgaas: folded in "while" loop termination fix from Colin Ian King ] Signed-off-by: Bjorn Helgaas --- include/linux/pci-epf.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h index 0d529cb90143..6ed63b5e106b 100644 --- a/include/linux/pci-epf.h +++ b/include/linux/pci-epf.h @@ -149,6 +149,8 @@ static inline void *epf_get_drvdata(struct pci_epf *epf) return dev_get_drvdata(&epf->dev); } +const struct pci_epf_device_id * +pci_epf_match_device(const struct pci_epf_device_id *id, struct pci_epf *epf); struct pci_epf *pci_epf_create(const char *name); void pci_epf_destroy(struct pci_epf *epf); int __pci_epf_register_driver(struct pci_epf_driver *driver, -- cgit v1.2.3 From 52c9285d47459cf241e144c7d8ef15941ba1b181 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 18 Aug 2017 20:27:56 +0530 Subject: PCI: endpoint: Add support for configurable page size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pci-epc-mem uses a page size equal to *PAGE_SIZE* (usually 4KB) to manage the address space. However certain platforms like TI's K2G have a restriction that this address space should be either divided into 1MB/2MB/4MB or 8MB sizes (Ref: 11.14.4.9.1 Outbound Address Translation in K2G TRM SPRUHY8F January 2016 – Revised May 2017). Add support to handle different page sizes here. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Bjorn Helgaas --- include/linux/pci-epc.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h index af5edbf3eea3..f7a04e1af112 100644 --- a/include/linux/pci-epc.h +++ b/include/linux/pci-epc.h @@ -62,11 +62,13 @@ struct pci_epc_ops { * @size: the size of the PCI address space * @bitmap: bitmap to manage the PCI address space * @pages: number of bits representing the address region + * @page_size: size of each page */ struct pci_epc_mem { phys_addr_t phys_base; size_t size; unsigned long *bitmap; + size_t page_size; int pages; }; @@ -98,6 +100,9 @@ struct pci_epc { #define devm_pci_epc_create(dev, ops) \ __devm_pci_epc_create((dev), (ops), THIS_MODULE) +#define pci_epc_mem_init(epc, phys_addr, size) \ + __pci_epc_mem_init((epc), (phys_addr), (size), PAGE_SIZE) + static inline void epc_set_drvdata(struct pci_epc *epc, void *data) { dev_set_drvdata(&epc->dev, data); @@ -135,7 +140,8 @@ void pci_epc_stop(struct pci_epc *epc); struct pci_epc *pci_epc_get(const char *epc_name); void pci_epc_put(struct pci_epc *epc); -int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_addr, size_t size); +int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_addr, size_t size, + size_t page_size); void pci_epc_mem_exit(struct pci_epc *epc); void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc, phys_addr_t *phys_addr, size_t size); -- cgit v1.2.3 From 0142626d08223b0f6ad04859301b53178f11c317 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Fri, 1 Sep 2017 16:35:20 -0500 Subject: PCI: Correct kernel-doc of pci_vpd_srdt_size(), pci_vpd_srdt_tag() The kernel-doc comments don't match the arguments, so fix the comments. Signed-off-by: Shawn Lin Signed-off-by: Bjorn Helgaas --- include/linux/pci.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 4869e66dd659..7950fc697394 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -2059,7 +2059,7 @@ static inline u16 pci_vpd_lrdt_tag(const u8 *lrdt) /** * pci_vpd_srdt_size - Extracts the Small Resource Data Type length - * @lrdt: Pointer to the beginning of the Small Resource Data Type tag + * @srdt: Pointer to the beginning of the Small Resource Data Type tag * * Returns the extracted Small Resource Data Type length. */ @@ -2070,7 +2070,7 @@ static inline u8 pci_vpd_srdt_size(const u8 *srdt) /** * pci_vpd_srdt_tag - Extracts the Small Resource Data Type Tag Item - * @lrdt: Pointer to the beginning of the Small Resource Data Type tag + * @srdt: Pointer to the beginning of the Small Resource Data Type tag * * Returns the extracted Small Resource Data Type Tag Item. */ -- cgit v1.2.3 From 96291d565550c1fd363e488cc17cb3189d2e4cc2 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 1 Sep 2017 16:35:50 -0500 Subject: PCI: Fix typos and whitespace errors Fix various typos and whitespace errors: s/Synopsis/Synopsys/ s/Designware/DesignWare/ s/Keystine/Keystone/ s/gpio/GPIO/ s/pcie/PCIe/ s/phy/PHY/ s/confgiruation/configuration/ No functional change intended. Signed-off-by: Bjorn Helgaas --- include/linux/aer.h | 5 ++--- include/linux/pcieport_if.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/aer.h b/include/linux/aer.h index 04602cbe85dc..43799bd17a02 100644 --- a/include/linux/aer.h +++ b/include/linux/aer.h @@ -39,7 +39,7 @@ struct aer_capability_regs { }; #if defined(CONFIG_PCIEAER) -/* pci-e port driver needs this function to enable aer */ +/* PCIe port driver needs this function to enable AER */ int pci_enable_pcie_error_reporting(struct pci_dev *dev); int pci_disable_pcie_error_reporting(struct pci_dev *dev); int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev); @@ -67,7 +67,6 @@ void cper_print_aer(struct pci_dev *dev, int aer_severity, struct aer_capability_regs *aer); int cper_severity_to_aer(int cper_severity); void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn, - int severity, - struct aer_capability_regs *aer_regs); + int severity, struct aer_capability_regs *aer_regs); #endif //_AER_H_ diff --git a/include/linux/pcieport_if.h b/include/linux/pcieport_if.h index afcd130ab3a9..12542f5ac83d 100644 --- a/include/linux/pcieport_if.h +++ b/include/linux/pcieport_if.h @@ -38,7 +38,7 @@ static inline void set_service_data(struct pcie_device *dev, void *data) dev->priv_data = data; } -static inline void* get_service_data(struct pcie_device *dev) +static inline void *get_service_data(struct pcie_device *dev) { return dev->priv_data; } -- cgit v1.2.3