Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 16093362 authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Bjorn Helgaas
Browse files

Merge remote-tracking branch 'lorenzo/pci/dwc' into next

* lorenzo/pci/dwc:
  PCI: exynos: Fix a potential init_clk_resources NULL pointer dereference
  PCI: iproc: Fix NULL pointer dereference for BCMA
  PCI: dra7xx: Iterate over INTx status bits
  PCI: dra7xx: Fix legacy INTD IRQ handling
  PCI: qcom: Account for const type of of_device_id.data
  PCI: dwc: artpec6: Fix return value check in artpec6_add_pcie_ep()
  PCI: exynos: Remove deprecated PHY initialization code
  PCI: dwc: artpec6: Add support for the ARTPEC-7 SoC
  bindings: PCI: artpec: Add support for the ARTPEC-7 SoC
  PCI: dwc: artpec6: Deassert the core before waiting for PHY
  PCI: dwc: Make cpu_addr_fixup take struct dw_pcie as argument
  PCI: dwc: artpec6: Add support for endpoint mode
  bindings: PCI: artpec: Add support for endpoint mode
  PCI: dwc: artpec6: Split artpec6_pcie_establish_link() into smaller functions
  PCI: dwc: artpec6: Use BIT and GENMASK macros
  PCI: dwc: artpec6: Remove unused defines
  PCI: dwc: dra7xx: Help compiler to remove unused code
  PCI: dwc: dra7xx: Assign pp->ops in dra7xx_add_pcie_port() rather than in probe
  PCI: dwc: dra7xx: Refactor Kconfig and Makefile handling for host/ep mode
  PCI: designware-ep: Add generic function for raising MSI irq
  PCI: designware-ep: Remove static keyword from dw_pcie_ep_reset_bar()
  PCI: designware-ep: Pre-allocate memory for MSI in dw_pcie_ep_init
  PCI: designware-ep: Read-only registers need DBI_RO_WR_EN to be writable
  PCI: designware-ep: dw_pcie_ep_set_msi() should only set MMC bits
  PCI: dwc: Use the DMA-API to get the MSI address
  pci: dwc: pci-dra7xx: Make shutdown handler static

Includes resolution to conflict between:

  4494738d ("PCI: endpoint: Add the function number as argument to EPC ops")
  6f6d7873 ("PCI: designware-ep: Add generic function for raising MSI irq")

The resolution is due to Niklas Cassel <niklas.cassel@axis.com>:
https://lkml.kernel.org/r/20180201085608.GA22568@axis.com
parents c7f75aec b5d6bc90
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -4,7 +4,10 @@ This PCIe host controller is based on the Synopsys DesignWare PCIe IP
and thus inherits all the common properties defined in designware-pcie.txt.
and thus inherits all the common properties defined in designware-pcie.txt.


Required properties:
Required properties:
- compatible: "axis,artpec6-pcie", "snps,dw-pcie"
- compatible: "axis,artpec6-pcie", "snps,dw-pcie" for ARTPEC-6 in RC mode;
	      "axis,artpec6-pcie-ep", "snps,dw-pcie" for ARTPEC-6 in EP mode;
	      "axis,artpec7-pcie", "snps,dw-pcie" for ARTPEC-7 in RC mode;
	      "axis,artpec7-pcie-ep", "snps,dw-pcie" for ARTPEC-7 in EP mode;
- reg: base addresses and lengths of the PCIe controller (DBI),
- reg: base addresses and lengths of the PCIe controller (DBI),
	the PHY controller, and configuration address space.
	the PHY controller, and configuration address space.
- reg-names: Must include the following entries:
- reg-names: Must include the following entries:
+11 −47
Original line number Original line Diff line number Diff line
@@ -6,9 +6,6 @@ and thus inherits all the common properties defined in designware-pcie.txt.
Required properties:
Required properties:
- compatible: "samsung,exynos5440-pcie"
- compatible: "samsung,exynos5440-pcie"
- reg: base addresses and lengths of the PCIe controller,
- reg: base addresses and lengths of the PCIe controller,
	the PHY controller, additional register for the PHY controller.
	(Registers for the PHY controller are DEPRECATED.
	 Use the PHY framework.)
- reg-names : First name should be set to "elbi".
- reg-names : First name should be set to "elbi".
	And use the "config" instead of getting the configuration address space
	And use the "config" instead of getting the configuration address space
	from "ranges".
	from "ranges".
@@ -23,49 +20,8 @@ For other common properties, refer to


Example:
Example:


SoC-specific DT Entry:
SoC-specific DT Entry (with using PHY framework):


	pcie@290000 {
		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
		reg = <0x290000 0x1000
			0x270000 0x1000
			0x271000 0x40>;
		interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
		clocks = <&clock 28>, <&clock 27>;
		clock-names = "pcie", "pcie_bus";
		#address-cells = <3>;
		#size-cells = <2>;
		device_type = "pci";
		ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000   /* configuration space */
			  0x81000000 0 0	  0x40001000 0 0x00010000   /* downstream I/O */
			  0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
		#interrupt-cells = <1>;
		interrupt-map-mask = <0 0 0 0>;
		interrupt-map = <0 0 0 0 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
		num-lanes = <4>;
	};

	pcie@2a0000 {
		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
		reg = <0x2a0000 0x1000
			0x272000 0x1000
			0x271040 0x40>;
		interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
		clocks = <&clock 29>, <&clock 27>;
		clock-names = "pcie", "pcie_bus";
		#address-cells = <3>;
		#size-cells = <2>;
		device_type = "pci";
		ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000   /* configuration space */
			  0x81000000 0 0	  0x60001000 0 0x00010000   /* downstream I/O */
			  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
		#interrupt-cells = <1>;
		interrupt-map-mask = <0 0 0 0>;
		interrupt-map = <0 0 0 0 &gic GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
		num-lanes = <4>;
	};

With using PHY framework:
	pcie_phy0: pcie-phy@270000 {
	pcie_phy0: pcie-phy@270000 {
		...
		...
		reg = <0x270000 0x1000>, <0x271000 0x40>;
		reg = <0x270000 0x1000>, <0x271000 0x40>;
@@ -74,13 +30,21 @@ With using PHY framework:
	};
	};


	pcie@290000 {
	pcie@290000 {
		...
		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
		reg = <0x290000 0x1000>, <0x40000000 0x1000>;
		reg = <0x290000 0x1000>, <0x40000000 0x1000>;
		reg-names = "elbi", "config";
		reg-names = "elbi", "config";
		clocks = <&clock 28>, <&clock 27>;
		clock-names = "pcie", "pcie_bus";
		#address-cells = <3>;
		#size-cells = <2>;
		device_type = "pci";
		phys = <&pcie_phy0>;
		phys = <&pcie_phy0>;
		ranges = <0x81000000 0 0	  0x60001000 0 0x00010000
		ranges = <0x81000000 0 0	  0x60001000 0 0x00010000
			  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>;
			  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>;
		...
		#interrupt-cells = <1>;
		interrupt-map-mask = <0 0 0 0>;
		interrupt-map = <0 0 0 0 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
		num-lanes = <4>;
	};
	};


Board-specific DT Entry:
Board-specific DT Entry:
+40 −28
Original line number Original line Diff line number Diff line
@@ -15,39 +15,38 @@ config PCIE_DW_EP
	select PCIE_DW
	select PCIE_DW


config PCI_DRA7XX
config PCI_DRA7XX
	bool "TI DRA7xx PCIe controller"
	bool
	depends on SOC_DRA7XX || COMPILE_TEST
	depends on (PCI && PCI_MSI_IRQ_DOMAIN) || PCI_ENDPOINT
	depends on OF && HAS_IOMEM && TI_PIPE3
	help
	 Enables support for the PCIe controller in the DRA7xx SoC. There
	 are two instances of PCIe controller in DRA7xx. This controller can
	 work either as EP or RC. In order to enable host-specific features
	 PCI_DRA7XX_HOST must be selected and in order to enable device-
	 specific features PCI_DRA7XX_EP must be selected. This uses
	 the DesignWare core.

if PCI_DRA7XX


config PCI_DRA7XX_HOST
config PCI_DRA7XX_HOST
	bool "PCI DRA7xx Host Mode"
	bool "TI DRA7xx PCIe controller Host Mode"
	depends on PCI
	depends on SOC_DRA7XX || COMPILE_TEST
	depends on PCI_MSI_IRQ_DOMAIN
	depends on PCI && PCI_MSI_IRQ_DOMAIN
	depends on OF && HAS_IOMEM && TI_PIPE3
	select PCIE_DW_HOST
	select PCIE_DW_HOST
	select PCI_DRA7XX
	default y
	default y
	help
	help
	  Enables support for the PCIe controller in the DRA7xx SoC to work in
	  Enables support for the PCIe controller in the DRA7xx SoC to work in
	 host mode.
	  host mode. There are two instances of PCIe controller in DRA7xx.
	  This controller can work either as EP or RC. In order to enable
	  host-specific features PCI_DRA7XX_HOST must be selected and in order
	  to enable device-specific features PCI_DRA7XX_EP must be selected.
	  This uses the DesignWare core.


config PCI_DRA7XX_EP
config PCI_DRA7XX_EP
	bool "PCI DRA7xx Endpoint Mode"
	bool "TI DRA7xx PCIe controller Endpoint Mode"
	depends on SOC_DRA7XX || COMPILE_TEST
	depends on PCI_ENDPOINT
	depends on PCI_ENDPOINT
	depends on OF && HAS_IOMEM && TI_PIPE3
	select PCIE_DW_EP
	select PCIE_DW_EP
	select PCI_DRA7XX
	help
	help
	  Enables support for the PCIe controller in the DRA7xx SoC to work in
	  Enables support for the PCIe controller in the DRA7xx SoC to work in
	 endpoint mode.
	  endpoint mode. There are two instances of PCIe controller in DRA7xx.

	  This controller can work either as EP or RC. In order to enable
endif
	  host-specific features PCI_DRA7XX_HOST must be selected and in order
	  to enable device-specific features PCI_DRA7XX_EP must be selected.
	  This uses the DesignWare core.


config PCIE_DW_PLAT
config PCIE_DW_PLAT
	bool "Platform bus based DesignWare PCIe Controller"
	bool "Platform bus based DesignWare PCIe Controller"
@@ -149,15 +148,28 @@ config PCIE_ARMADA_8K
	  DesignWare core functions to implement the driver.
	  DesignWare core functions to implement the driver.


config PCIE_ARTPEC6
config PCIE_ARTPEC6
	bool "Axis ARTPEC-6 PCIe controller"
	bool
	depends on PCI

config PCIE_ARTPEC6_HOST
	bool "Axis ARTPEC-6 PCIe controller Host Mode"
	depends on MACH_ARTPEC6
	depends on MACH_ARTPEC6
	depends on PCI_MSI_IRQ_DOMAIN
	depends on PCI && PCI_MSI_IRQ_DOMAIN
	select PCIEPORTBUS
	select PCIEPORTBUS
	select PCIE_DW_HOST
	select PCIE_DW_HOST
	select PCIE_ARTPEC6
	help
	  Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
	  host mode. This uses the DesignWare core.

config PCIE_ARTPEC6_EP
	bool "Axis ARTPEC-6 PCIe controller Endpoint Mode"
	depends on MACH_ARTPEC6
	depends on PCI_ENDPOINT
	select PCIE_DW_EP
	select PCIE_ARTPEC6
	help
	help
	  Say Y here to enable PCIe controller support on Axis ARTPEC-6
	  Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
	  SoCs.  This PCIe controller uses the DesignWare core.
	  endpoint mode. This uses the DesignWare core.


config PCIE_KIRIN
config PCIE_KIRIN
	depends on OF && ARM64
	depends on OF && ARM64
+1 −3
Original line number Original line Diff line number Diff line
@@ -3,9 +3,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
ifneq ($(filter y,$(CONFIG_PCI_DRA7XX_HOST) $(CONFIG_PCI_DRA7XX_EP)),)
obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
endif
obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
+23 −19
Original line number Original line Diff line number Diff line
@@ -110,7 +110,7 @@ static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset,
	writel(value, pcie->base + offset);
	writel(value, pcie->base + offset);
}
}


static u64 dra7xx_pcie_cpu_addr_fixup(u64 pci_addr)
static u64 dra7xx_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr)
{
{
	return pci_addr & DRA7XX_CPU_TO_BUS_ADDR;
	return pci_addr & DRA7XX_CPU_TO_BUS_ADDR;
}
}
@@ -226,6 +226,7 @@ static int dra7xx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,


static const struct irq_domain_ops intx_domain_ops = {
static const struct irq_domain_ops intx_domain_ops = {
	.map = dra7xx_pcie_intx_map,
	.map = dra7xx_pcie_intx_map,
	.xlate = pci_irqd_intx_xlate,
};
};


static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
@@ -256,7 +257,8 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
	struct dra7xx_pcie *dra7xx = arg;
	struct dra7xx_pcie *dra7xx = arg;
	struct dw_pcie *pci = dra7xx->pci;
	struct dw_pcie *pci = dra7xx->pci;
	struct pcie_port *pp = &pci->pp;
	struct pcie_port *pp = &pci->pp;
	u32 reg;
	unsigned long reg;
	u32 virq, bit;


	reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI);
	reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI);


@@ -268,8 +270,11 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
	case INTB:
	case INTB:
	case INTC:
	case INTC:
	case INTD:
	case INTD:
		generic_handle_irq(irq_find_mapping(dra7xx->irq_domain,
		for_each_set_bit(bit, &reg, PCI_NUM_INTX) {
						    ffs(reg)));
			virq = irq_find_mapping(dra7xx->irq_domain, bit);
			if (virq)
				generic_handle_irq(virq);
		}
		break;
		break;
	}
	}


@@ -337,15 +342,6 @@ static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg)
	return IRQ_HANDLED;
	return IRQ_HANDLED;
}
}


static void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
{
	u32 reg;

	reg = PCI_BASE_ADDRESS_0 + (4 * bar);
	dw_pcie_writel_dbi2(pci, reg, 0x0);
	dw_pcie_writel_dbi(pci, reg, 0x0);
}

static void dra7xx_pcie_ep_init(struct dw_pcie_ep *ep)
static void dra7xx_pcie_ep_init(struct dw_pcie_ep *ep)
{
{
	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -375,7 +371,7 @@ static void dra7xx_pcie_raise_msi_irq(struct dra7xx_pcie *dra7xx,
	dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_MSI_XMT, reg);
	dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_MSI_XMT, reg);
}
}


static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep,
static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
				 enum pci_epc_irq_type type, u8 interrupt_num)
				 enum pci_epc_irq_type type, u8 interrupt_num)
{
{
	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -470,6 +466,8 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
	if (!pci->dbi_base)
	if (!pci->dbi_base)
		return -ENOMEM;
		return -ENOMEM;


	pp->ops = &dra7xx_pcie_host_ops;

	ret = dw_pcie_host_init(pp);
	ret = dw_pcie_host_init(pp);
	if (ret) {
	if (ret) {
		dev_err(dev, "failed to initialize host\n");
		dev_err(dev, "failed to initialize host\n");
@@ -599,7 +597,6 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
	void __iomem *base;
	void __iomem *base;
	struct resource *res;
	struct resource *res;
	struct dw_pcie *pci;
	struct dw_pcie *pci;
	struct pcie_port *pp;
	struct dra7xx_pcie *dra7xx;
	struct dra7xx_pcie *dra7xx;
	struct device *dev = &pdev->dev;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct device_node *np = dev->of_node;
@@ -627,9 +624,6 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
	pci->dev = dev;
	pci->dev = dev;
	pci->ops = &dw_pcie_ops;
	pci->ops = &dw_pcie_ops;


	pp = &pci->pp;
	pp->ops = &dra7xx_pcie_host_ops;

	irq = platform_get_irq(pdev, 0);
	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
	if (irq < 0) {
		dev_err(dev, "missing IRQ resource: %d\n", irq);
		dev_err(dev, "missing IRQ resource: %d\n", irq);
@@ -705,6 +699,11 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)


	switch (mode) {
	switch (mode) {
	case DW_PCIE_RC_TYPE:
	case DW_PCIE_RC_TYPE:
		if (!IS_ENABLED(CONFIG_PCI_DRA7XX_HOST)) {
			ret = -ENODEV;
			goto err_gpio;
		}

		dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
		dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
				   DEVICE_TYPE_RC);
				   DEVICE_TYPE_RC);
		ret = dra7xx_add_pcie_port(dra7xx, pdev);
		ret = dra7xx_add_pcie_port(dra7xx, pdev);
@@ -712,6 +711,11 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
			goto err_gpio;
			goto err_gpio;
		break;
		break;
	case DW_PCIE_EP_TYPE:
	case DW_PCIE_EP_TYPE:
		if (!IS_ENABLED(CONFIG_PCI_DRA7XX_EP)) {
			ret = -ENODEV;
			goto err_gpio;
		}

		dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
		dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
				   DEVICE_TYPE_EP);
				   DEVICE_TYPE_EP);


@@ -810,7 +814,7 @@ static int dra7xx_pcie_resume_noirq(struct device *dev)
}
}
#endif
#endif


void dra7xx_pcie_shutdown(struct platform_device *pdev)
static void dra7xx_pcie_shutdown(struct platform_device *pdev)
{
{
	struct device *dev = &pdev->dev;
	struct device *dev = &pdev->dev;
	struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
	struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
Loading