i.MX6 MSI support
Subsystems (5)
cover i.MX6 MSI support
This adds MSI support to the i.MX6 PCIe host controller driver. We keep MSI optional in order to not break any existing DTs.
This series depends on the previous sent series "PCI irq mapping fixes and cleanups".
Lucas Stach (3):
ARM: dts: imx6: extend PCIe interrupt list for MSI
PCI: designware: make MSI isr shared irq aware
PCI: imx6: add support for MSI
.../devicetree/bindings/pci/fsl,imx6q-pcie.txt | 9 +++++++- arch/arm/boot/dts/imx6qdl.dtsi | 4 +++- drivers/pci/host/pci-exynos.c | 4 +--- drivers/pci/host/pci-imx6.c | 26 ++++++++++++++++++++++ drivers/pci/host/pcie-designware.c | 6 ++++- drivers/pci/host/pcie-designware.h | 2 +- 6 files changed, 44 insertions(+), 7 deletions(-)
Signature · 1 line
1.8.5.3
PATCH 1/3 ARM: dts: imx6: extend PCIe interrupt list for MSI
Optional IRQ necessary for handling MSI.
--- Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt | 9 ++++++++- arch/arm/boot/dts/imx6qdl.dtsi | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt +8 -1
@@ -17,6 +17,11 @@ Required properties: - "pcie_axi" Optional properties: +- interrupts: Must contain an entry for each entry in the + interrupt-names property. +- interrupt-names: May include the following entries: + - "inta" + - "msi" if not present the driver won't be able to handle MSI - power-on-gpio: gpio pin number of power-enable signal - wake-up-gpio: gpio pin number of incoming wakeup signal - disable-gpio: gpio pin number of outgoing rfkill/endpoint disable signal
@@ -34,7 +39,9 @@ Example: 0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; num-lanes = <1>; - interrupts = <0 123 0x04>; + interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "inta", "msi"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0x7>;
arch/arm/boot/dts/imx6qdl.dtsi +3 -1
@@ -129,7 +129,9 @@ 0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */ num-lanes = <1>; - interrupts = <0 123 0x04>; + interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "inta", "msi"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0x7>;
Signature · 1 line
1.8.5.3
PATCH 1/3 ARM: dts: imx6: extend PCIe interrupt list for MSI
Quoted 6 lines · Lucas Stach
Optional IRQ necessary for handling MSI.
Signed-off-by Juergen Beisert <[email protected]>Signed-off-by Lucas Stach <[email protected]>--- Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt | 9 ++++++++-
Please have this change go with driver or a separate patch, not with dts update.
Shawn
Quoted 2 lines
arch/arm/boot/dts/imx6qdl.dtsi | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-)
PATCH 2/3 PCI: designware: make MSI isr shared irq aware
In reply to Lucas StachOn i.MX6 the host controller MSI irq is shared with PCI legacy INTD. Make sure we don't bail too early from the irq handler.
The issue is fairly theoretical as it would require a system setup with a PCIe switch where one connected device is using legacy INTD and another one using MSI, but better fix it now.
--- drivers/pci/host/pci-exynos.c | 4 +--- drivers/pci/host/pcie-designware.c | 6 +++++- drivers/pci/host/pcie-designware.h | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-)
drivers/pci/host/pci-exynos.c +1 -3
@@ -415,9 +415,7 @@ static irqreturn_t exynos_pcie_msi_irq_handler(int irq, void *arg) {struct pcie_port *pp = arg; -dw_handle_msi_irq (pp); - -return IRQ_HANDLED ; +return dw_handle_msi_irq (pp); }static void exynos_pcie_msi_init (struct pcie_port *pp)
drivers/pci/host/pcie-designware.c +5 -1
@@ -156,15 +156,17 @@ static struct irq_chip dw_msi_irq_chip = { };/* MSI int handler */ -void dw_handle_msi_irq (struct pcie_port *pp) +irqreturn_t dw_handle_msi_irq (struct pcie_port *pp) {unsigned long val;int i, pos, irq; +irqreturn_t ret =IRQ_NONE ;for (i =0 ; i <MAX_MSI_CTRLS ; i++) {dw_pcie_rd_own_conf (pp,PCIE_MSI_INTR0_STATUS + i *12 ,4 , (u32 *)&val);if (val) { + ret =IRQ_HANDLED ; pos =0 ;while ((pos =find_next_bit (&val,32 , pos)) !=32 ) { irq = irq_find_mapping(pp->irq_domain,
@@ -177,6 +179,8 @@ void dw_handle_msi_irq(struct pcie_port *pp) } } } + +return ret; }void dw_pcie_msi_init (struct pcie_port *pp)
drivers/pci/host/pcie-designware.h +1 -1
@@ -68,7 +68,7 @@ struct pcie_host_ops {int dw_pcie_cfg_read (void __iomem *addr,int where,int size,u32 *val);int dw_pcie_cfg_write (void __iomem *addr,int where,int size,u32 val); -void dw_handle_msi_irq (struct pcie_port *pp); +irqreturn_t dw_handle_msi_irq (struct pcie_port *pp);void dw_pcie_msi_init (struct pcie_port *pp);int dw_pcie_link_up (struct pcie_port *pp);void dw_pcie_setup_rc (struct pcie_port *pp);
Signature · 1 line
1.8.5.3
PATCH 3/3 PCI: imx6: add support for MSI
In reply to Lucas StachThis patch adds support for Message Signaled Interrupts in the imx6-pcie driver.
--- drivers/pci/host/pci-imx6.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
drivers/pci/host/pci-imx6.c +26 -0
@@ -25,6 +25,7 @@#include <linux/resource.h> #include <linux/signal.h> #include <linux/types.h> +#include <linux/interrupt.h> #include "pcie-designware.h"
@@ -329,6 +330,13 @@ static int imx6_pcie_wait_for_link(struct pcie_port *pp)return 0 ; } +static irqreturn_t imx6_pcie_msi_handler (int irq,void *arg) +{ +struct pcie_port *pp = arg; + +return dw_handle_msi_irq (pp); +} +static int imx6_pcie_start_link (struct pcie_port *pp) {struct imx6_pcie *imx6_pcie =to_imx6_pcie (pp);
@@ -403,6 +411,9 @@ static void imx6_pcie_host_init(struct pcie_port *pp)dw_pcie_setup_rc (pp);imx6_pcie_start_link (pp); + +if (IS_ENABLED (CONFIG_PCI_MSI ) && (pp->msi_irq >0 )) +dw_pcie_msi_init (pp); }static void imx6_pcie_reset_phy (struct pcie_port *pp)
@@ -477,6 +488,21 @@ static int imx6_add_pcie_port(struct pcie_port *pp,return -ENODEV ; } +if (IS_ENABLED (CONFIG_PCI_MSI )) { + pp->msi_irq =platform_get_irq_byname (pdev,"msi" ); +if (pp->msi_irq <0 ) { +dev_info (&pdev->dev,"failed to get MSI irq, host will not support MSI\n" ); + }else { + ret =devm_request_irq (&pdev->dev, pp->msi_irq, + imx6_pcie_msi_handler, +IRQF_SHARED ,"mx6-pcie-msi" , pp); +if (ret) { +dev_err (&pdev->dev,"failed to request MSI irq\n" ); +return -ENODEV ; + } + } + } + pp->root_bus_nr =-1 ; pp->ops = &imx6_pcie_host_ops;
Signature · 1 line
1.8.5.3