diff options
-rw-r--r-- | drivers/pci/dwc/pcie-armada8k.c | 8 | ||||
-rw-r--r-- | drivers/pci/host/pci-aardvark.c | 5 | ||||
-rw-r--r-- | drivers/pci/host/pcie-altera-msi.c | 6 | ||||
-rw-r--r-- | drivers/pci/host/pcie-altera.c | 13 | ||||
-rw-r--r-- | include/linux/pci-epf.h | 9 | ||||
-rw-r--r-- | include/linux/pci.h | 54 |
6 files changed, 70 insertions, 25 deletions
diff --git a/drivers/pci/dwc/pcie-armada8k.c b/drivers/pci/dwc/pcie-armada8k.c index ea8f34af6a85..8047686c3856 100644 --- a/drivers/pci/dwc/pcie-armada8k.c +++ b/drivers/pci/dwc/pcie-armada8k.c @@ -176,9 +176,9 @@ static int armada8k_add_pcie_port(struct armada8k_pcie *pcie, pp->ops = &armada8k_pcie_host_ops; pp->irq = platform_get_irq(pdev, 0); - if (!pp->irq) { + if (pp->irq < 0) { dev_err(dev, "failed to get irq for port\n"); - return -ENODEV; + return pp->irq; } ret = devm_request_irq(dev, pp->irq, armada8k_pcie_irq_handler, @@ -226,7 +226,9 @@ static int armada8k_pcie_probe(struct platform_device *pdev) if (IS_ERR(pcie->clk)) return PTR_ERR(pcie->clk); - clk_prepare_enable(pcie->clk); + ret = clk_prepare_enable(pcie->clk); + if (ret) + return ret; /* Get the dw-pcie unit configuration/control registers base. */ base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl"); diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c index 5fb9b620ac78..89f4e3d072d7 100644 --- a/drivers/pci/host/pci-aardvark.c +++ b/drivers/pci/host/pci-aardvark.c @@ -191,7 +191,6 @@ #define LINK_WAIT_USLEEP_MIN 90000 #define LINK_WAIT_USLEEP_MAX 100000 -#define LEGACY_IRQ_NUM 4 #define MSI_IRQ_NUM 32 struct advk_pcie { @@ -729,7 +728,7 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie) irq_chip->irq_unmask = advk_pcie_irq_unmask; pcie->irq_domain = - irq_domain_add_linear(pcie_intc_node, LEGACY_IRQ_NUM, + irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, &advk_pcie_irq_domain_ops, pcie); if (!pcie->irq_domain) { dev_err(dev, "Failed to get a INTx IRQ domain\n"); @@ -786,7 +785,7 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie) advk_pcie_handle_msi(pcie); /* Process legacy interrupts */ - for (i = 0; i < LEGACY_IRQ_NUM; i++) { + for (i = 0; i < PCI_NUM_INTX; i++) { if (!(status & PCIE_ISR0_INTX_ASSERT(i))) continue; diff --git a/drivers/pci/host/pcie-altera-msi.c b/drivers/pci/host/pcie-altera-msi.c index 4e5d628e8cd4..d8141f4865de 100644 --- a/drivers/pci/host/pcie-altera-msi.c +++ b/drivers/pci/host/pcie-altera-msi.c @@ -64,13 +64,11 @@ static void altera_msi_isr(struct irq_desc *desc) struct irq_chip *chip = irq_desc_get_chip(desc); struct altera_msi *msi; unsigned long status; - u32 num_of_vectors; u32 bit; u32 virq; chained_irq_enter(chip, desc); msi = irq_desc_get_handler_data(desc); - num_of_vectors = msi->num_of_vectors; while ((status = msi_readl(msi, MSI_STATUS)) != 0) { for_each_set_bit(bit, &status, msi->num_of_vectors) { @@ -267,9 +265,9 @@ static int altera_msi_probe(struct platform_device *pdev) return ret; msi->irq = platform_get_irq(pdev, 0); - if (msi->irq <= 0) { + if (msi->irq < 0) { dev_err(&pdev->dev, "failed to map IRQ: %d\n", msi->irq); - ret = -ENODEV; + ret = msi->irq; goto err; } diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c index 4ea4f8f5dc77..b468b8cccf8d 100644 --- a/drivers/pci/host/pcie-altera.c +++ b/drivers/pci/host/pcie-altera.c @@ -76,8 +76,6 @@ #define LINK_UP_TIMEOUT HZ #define LINK_RETRAIN_TIMEOUT HZ -#define INTX_NUM 4 - #define DWORD_MASK 3 struct altera_pcie { @@ -464,6 +462,7 @@ static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq, static const struct irq_domain_ops intx_domain_ops = { .map = altera_pcie_intx_map, + .xlate = pci_irqd_intx_xlate, }; static void altera_pcie_isr(struct irq_desc *desc) @@ -481,11 +480,11 @@ static void altera_pcie_isr(struct irq_desc *desc) while ((status = cra_readl(pcie, P2A_INT_STATUS) & P2A_INT_STS_ALL) != 0) { - for_each_set_bit(bit, &status, INTX_NUM) { + for_each_set_bit(bit, &status, PCI_NUM_INTX) { /* clear interrupts */ cra_writel(pcie, 1 << bit, P2A_INT_STATUS); - virq = irq_find_mapping(pcie->irq_domain, bit + 1); + virq = irq_find_mapping(pcie->irq_domain, bit); if (virq) generic_handle_irq(virq); else @@ -536,7 +535,7 @@ static int altera_pcie_init_irq_domain(struct altera_pcie *pcie) struct device_node *node = dev->of_node; /* Setup INTx */ - pcie->irq_domain = irq_domain_add_linear(node, INTX_NUM + 1, + pcie->irq_domain = irq_domain_add_linear(node, PCI_NUM_INTX, &intx_domain_ops, pcie); if (!pcie->irq_domain) { dev_err(dev, "Failed to get a INTx IRQ domain\n"); @@ -559,9 +558,9 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie) /* setup IRQ */ pcie->irq = platform_get_irq(pdev, 0); - if (pcie->irq <= 0) { + if (pcie->irq < 0) { dev_err(dev, "failed to get IRQ: %d\n", pcie->irq); - return -EINVAL; + return pcie->irq; } irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie); 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 <linux/device.h> #include <linux/mod_devicetable.h> +#include <linux/pci.h> 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..bbc2a991b63f 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. @@ -1394,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; |