xref: /linux/drivers/pci/controller/pci-rcar-gen2.c (revision a1c613ae4c322ddd58d5a8539dbfba2a0380a8c0)
16e0832faSShawn Lin // SPDX-License-Identifier: GPL-2.0
26e0832faSShawn Lin /*
36e0832faSShawn Lin  *  pci-rcar-gen2: internal PCI bus support
46e0832faSShawn Lin  *
56e0832faSShawn Lin  * Copyright (C) 2013 Renesas Solutions Corp.
66e0832faSShawn Lin  * Copyright (C) 2013 Cogent Embedded, Inc.
76e0832faSShawn Lin  *
86e0832faSShawn Lin  * Author: Valentine Barshak <valentine.barshak@cogentembedded.com>
96e0832faSShawn Lin  */
106e0832faSShawn Lin 
116e0832faSShawn Lin #include <linux/delay.h>
126e0832faSShawn Lin #include <linux/init.h>
136e0832faSShawn Lin #include <linux/interrupt.h>
146e0832faSShawn Lin #include <linux/io.h>
156e0832faSShawn Lin #include <linux/kernel.h>
166e0832faSShawn Lin #include <linux/of_address.h>
176e0832faSShawn Lin #include <linux/of_pci.h>
186e0832faSShawn Lin #include <linux/pci.h>
196e0832faSShawn Lin #include <linux/platform_device.h>
206e0832faSShawn Lin #include <linux/pm_runtime.h>
216e0832faSShawn Lin #include <linux/sizes.h>
226e0832faSShawn Lin #include <linux/slab.h>
236e0832faSShawn Lin 
246e0832faSShawn Lin #include "../pci.h"
256e0832faSShawn Lin 
266e0832faSShawn Lin /* AHB-PCI Bridge PCI communication registers */
276e0832faSShawn Lin #define RCAR_AHBPCI_PCICOM_OFFSET	0x800
286e0832faSShawn Lin 
296e0832faSShawn Lin #define RCAR_PCIAHB_WIN1_CTR_REG	(RCAR_AHBPCI_PCICOM_OFFSET + 0x00)
306e0832faSShawn Lin #define RCAR_PCIAHB_WIN2_CTR_REG	(RCAR_AHBPCI_PCICOM_OFFSET + 0x04)
316e0832faSShawn Lin #define RCAR_PCIAHB_PREFETCH0		0x0
326e0832faSShawn Lin #define RCAR_PCIAHB_PREFETCH4		0x1
336e0832faSShawn Lin #define RCAR_PCIAHB_PREFETCH8		0x2
346e0832faSShawn Lin #define RCAR_PCIAHB_PREFETCH16		0x3
356e0832faSShawn Lin 
366e0832faSShawn Lin #define RCAR_AHBPCI_WIN1_CTR_REG	(RCAR_AHBPCI_PCICOM_OFFSET + 0x10)
376e0832faSShawn Lin #define RCAR_AHBPCI_WIN2_CTR_REG	(RCAR_AHBPCI_PCICOM_OFFSET + 0x14)
386e0832faSShawn Lin #define RCAR_AHBPCI_WIN_CTR_MEM		(3 << 1)
396e0832faSShawn Lin #define RCAR_AHBPCI_WIN_CTR_CFG		(5 << 1)
406e0832faSShawn Lin #define RCAR_AHBPCI_WIN1_HOST		(1 << 30)
416e0832faSShawn Lin #define RCAR_AHBPCI_WIN1_DEVICE		(1 << 31)
426e0832faSShawn Lin 
436e0832faSShawn Lin #define RCAR_PCI_INT_ENABLE_REG		(RCAR_AHBPCI_PCICOM_OFFSET + 0x20)
446e0832faSShawn Lin #define RCAR_PCI_INT_STATUS_REG		(RCAR_AHBPCI_PCICOM_OFFSET + 0x24)
456e0832faSShawn Lin #define RCAR_PCI_INT_SIGTABORT		(1 << 0)
466e0832faSShawn Lin #define RCAR_PCI_INT_SIGRETABORT	(1 << 1)
476e0832faSShawn Lin #define RCAR_PCI_INT_REMABORT		(1 << 2)
486e0832faSShawn Lin #define RCAR_PCI_INT_PERR		(1 << 3)
496e0832faSShawn Lin #define RCAR_PCI_INT_SIGSERR		(1 << 4)
506e0832faSShawn Lin #define RCAR_PCI_INT_RESERR		(1 << 5)
516e0832faSShawn Lin #define RCAR_PCI_INT_WIN1ERR		(1 << 12)
526e0832faSShawn Lin #define RCAR_PCI_INT_WIN2ERR		(1 << 13)
536e0832faSShawn Lin #define RCAR_PCI_INT_A			(1 << 16)
546e0832faSShawn Lin #define RCAR_PCI_INT_B			(1 << 17)
556e0832faSShawn Lin #define RCAR_PCI_INT_PME		(1 << 19)
566e0832faSShawn Lin #define RCAR_PCI_INT_ALLERRORS (RCAR_PCI_INT_SIGTABORT		| \
576e0832faSShawn Lin 				RCAR_PCI_INT_SIGRETABORT	| \
586e0832faSShawn Lin 				RCAR_PCI_INT_REMABORT		| \
596e0832faSShawn Lin 				RCAR_PCI_INT_PERR		| \
606e0832faSShawn Lin 				RCAR_PCI_INT_SIGSERR		| \
616e0832faSShawn Lin 				RCAR_PCI_INT_RESERR		| \
626e0832faSShawn Lin 				RCAR_PCI_INT_WIN1ERR		| \
636e0832faSShawn Lin 				RCAR_PCI_INT_WIN2ERR)
646e0832faSShawn Lin 
656e0832faSShawn Lin #define RCAR_AHB_BUS_CTR_REG		(RCAR_AHBPCI_PCICOM_OFFSET + 0x30)
666e0832faSShawn Lin #define RCAR_AHB_BUS_MMODE_HTRANS	(1 << 0)
676e0832faSShawn Lin #define RCAR_AHB_BUS_MMODE_BYTE_BURST	(1 << 1)
686e0832faSShawn Lin #define RCAR_AHB_BUS_MMODE_WR_INCR	(1 << 2)
696e0832faSShawn Lin #define RCAR_AHB_BUS_MMODE_HBUS_REQ	(1 << 7)
706e0832faSShawn Lin #define RCAR_AHB_BUS_SMODE_READYCTR	(1 << 17)
716e0832faSShawn Lin #define RCAR_AHB_BUS_MODE		(RCAR_AHB_BUS_MMODE_HTRANS |	\
726e0832faSShawn Lin 					RCAR_AHB_BUS_MMODE_BYTE_BURST |	\
736e0832faSShawn Lin 					RCAR_AHB_BUS_MMODE_WR_INCR |	\
746e0832faSShawn Lin 					RCAR_AHB_BUS_MMODE_HBUS_REQ |	\
756e0832faSShawn Lin 					RCAR_AHB_BUS_SMODE_READYCTR)
766e0832faSShawn Lin 
776e0832faSShawn Lin #define RCAR_USBCTR_REG			(RCAR_AHBPCI_PCICOM_OFFSET + 0x34)
786e0832faSShawn Lin #define RCAR_USBCTR_USBH_RST		(1 << 0)
796e0832faSShawn Lin #define RCAR_USBCTR_PCICLK_MASK		(1 << 1)
806e0832faSShawn Lin #define RCAR_USBCTR_PLL_RST		(1 << 2)
816e0832faSShawn Lin #define RCAR_USBCTR_DIRPD		(1 << 8)
826e0832faSShawn Lin #define RCAR_USBCTR_PCIAHB_WIN2_EN	(1 << 9)
836e0832faSShawn Lin #define RCAR_USBCTR_PCIAHB_WIN1_256M	(0 << 10)
846e0832faSShawn Lin #define RCAR_USBCTR_PCIAHB_WIN1_512M	(1 << 10)
856e0832faSShawn Lin #define RCAR_USBCTR_PCIAHB_WIN1_1G	(2 << 10)
866e0832faSShawn Lin #define RCAR_USBCTR_PCIAHB_WIN1_2G	(3 << 10)
876e0832faSShawn Lin #define RCAR_USBCTR_PCIAHB_WIN1_MASK	(3 << 10)
886e0832faSShawn Lin 
896e0832faSShawn Lin #define RCAR_PCI_ARBITER_CTR_REG	(RCAR_AHBPCI_PCICOM_OFFSET + 0x40)
906e0832faSShawn Lin #define RCAR_PCI_ARBITER_PCIREQ0	(1 << 0)
916e0832faSShawn Lin #define RCAR_PCI_ARBITER_PCIREQ1	(1 << 1)
926e0832faSShawn Lin #define RCAR_PCI_ARBITER_PCIBP_MODE	(1 << 12)
936e0832faSShawn Lin 
946e0832faSShawn Lin #define RCAR_PCI_UNIT_REV_REG		(RCAR_AHBPCI_PCICOM_OFFSET + 0x48)
956e0832faSShawn Lin 
967025ecb6SBjorn Helgaas struct rcar_pci {
976e0832faSShawn Lin 	struct device *dev;
986e0832faSShawn Lin 	void __iomem *reg;
996e0832faSShawn Lin 	struct resource mem_res;
1006e0832faSShawn Lin 	struct resource *cfg_res;
1016e0832faSShawn Lin 	int irq;
1026e0832faSShawn Lin };
1036e0832faSShawn Lin 
1046e0832faSShawn Lin /* PCI configuration space operations */
rcar_pci_cfg_base(struct pci_bus * bus,unsigned int devfn,int where)1056e0832faSShawn Lin static void __iomem *rcar_pci_cfg_base(struct pci_bus *bus, unsigned int devfn,
1066e0832faSShawn Lin 				       int where)
1076e0832faSShawn Lin {
1087025ecb6SBjorn Helgaas 	struct rcar_pci *priv = bus->sysdata;
1096e0832faSShawn Lin 	int slot, val;
1106e0832faSShawn Lin 
1114a957563SRob Herring 	if (!pci_is_root_bus(bus) || PCI_FUNC(devfn))
1126e0832faSShawn Lin 		return NULL;
1136e0832faSShawn Lin 
1146e0832faSShawn Lin 	/* Only one EHCI/OHCI device built-in */
1156e0832faSShawn Lin 	slot = PCI_SLOT(devfn);
1166e0832faSShawn Lin 	if (slot > 2)
1176e0832faSShawn Lin 		return NULL;
1186e0832faSShawn Lin 
1196e0832faSShawn Lin 	/* bridge logic only has registers to 0x40 */
1206e0832faSShawn Lin 	if (slot == 0x0 && where >= 0x40)
1216e0832faSShawn Lin 		return NULL;
1226e0832faSShawn Lin 
1236e0832faSShawn Lin 	val = slot ? RCAR_AHBPCI_WIN1_DEVICE | RCAR_AHBPCI_WIN_CTR_CFG :
1246e0832faSShawn Lin 		     RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG;
1256e0832faSShawn Lin 
1266e0832faSShawn Lin 	iowrite32(val, priv->reg + RCAR_AHBPCI_WIN1_CTR_REG);
1276e0832faSShawn Lin 	return priv->reg + (slot >> 1) * 0x100 + where;
1286e0832faSShawn Lin }
1296e0832faSShawn Lin 
1306e0832faSShawn Lin #ifdef CONFIG_PCI_DEBUG
1316e0832faSShawn Lin /* if debug enabled, then attach an error handler irq to the bridge */
1326e0832faSShawn Lin 
rcar_pci_err_irq(int irq,void * pw)1336e0832faSShawn Lin static irqreturn_t rcar_pci_err_irq(int irq, void *pw)
1346e0832faSShawn Lin {
1357025ecb6SBjorn Helgaas 	struct rcar_pci *priv = pw;
1366e0832faSShawn Lin 	struct device *dev = priv->dev;
1376e0832faSShawn Lin 	u32 status = ioread32(priv->reg + RCAR_PCI_INT_STATUS_REG);
1386e0832faSShawn Lin 
1396e0832faSShawn Lin 	if (status & RCAR_PCI_INT_ALLERRORS) {
1406e0832faSShawn Lin 		dev_err(dev, "error irq: status %08x\n", status);
1416e0832faSShawn Lin 
1426e0832faSShawn Lin 		/* clear the error(s) */
1436e0832faSShawn Lin 		iowrite32(status & RCAR_PCI_INT_ALLERRORS,
1446e0832faSShawn Lin 			  priv->reg + RCAR_PCI_INT_STATUS_REG);
1456e0832faSShawn Lin 		return IRQ_HANDLED;
1466e0832faSShawn Lin 	}
1476e0832faSShawn Lin 
1486e0832faSShawn Lin 	return IRQ_NONE;
1496e0832faSShawn Lin }
1506e0832faSShawn Lin 
rcar_pci_setup_errirq(struct rcar_pci * priv)1517025ecb6SBjorn Helgaas static void rcar_pci_setup_errirq(struct rcar_pci *priv)
1526e0832faSShawn Lin {
1536e0832faSShawn Lin 	struct device *dev = priv->dev;
1546e0832faSShawn Lin 	int ret;
1556e0832faSShawn Lin 	u32 val;
1566e0832faSShawn Lin 
1576e0832faSShawn Lin 	ret = devm_request_irq(dev, priv->irq, rcar_pci_err_irq,
1586e0832faSShawn Lin 			       IRQF_SHARED, "error irq", priv);
1596e0832faSShawn Lin 	if (ret) {
1606e0832faSShawn Lin 		dev_err(dev, "cannot claim IRQ for error handling\n");
1616e0832faSShawn Lin 		return;
1626e0832faSShawn Lin 	}
1636e0832faSShawn Lin 
1646e0832faSShawn Lin 	val = ioread32(priv->reg + RCAR_PCI_INT_ENABLE_REG);
1656e0832faSShawn Lin 	val |= RCAR_PCI_INT_ALLERRORS;
1666e0832faSShawn Lin 	iowrite32(val, priv->reg + RCAR_PCI_INT_ENABLE_REG);
1676e0832faSShawn Lin }
1686e0832faSShawn Lin #else
rcar_pci_setup_errirq(struct rcar_pci * priv)1697025ecb6SBjorn Helgaas static inline void rcar_pci_setup_errirq(struct rcar_pci *priv) { }
1706e0832faSShawn Lin #endif
1716e0832faSShawn Lin 
1726e0832faSShawn Lin /* PCI host controller setup */
rcar_pci_setup(struct rcar_pci * priv)1737025ecb6SBjorn Helgaas static void rcar_pci_setup(struct rcar_pci *priv)
1746e0832faSShawn Lin {
1754a957563SRob Herring 	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(priv);
1766e0832faSShawn Lin 	struct device *dev = priv->dev;
1776e0832faSShawn Lin 	void __iomem *reg = priv->reg;
1784a957563SRob Herring 	struct resource_entry *entry;
1794a957563SRob Herring 	unsigned long window_size;
1804a957563SRob Herring 	unsigned long window_addr;
1814a957563SRob Herring 	unsigned long window_pci;
1826e0832faSShawn Lin 	u32 val;
1834a957563SRob Herring 
1844a957563SRob Herring 	entry = resource_list_first_type(&bridge->dma_ranges, IORESOURCE_MEM);
1854a957563SRob Herring 	if (!entry) {
1864a957563SRob Herring 		window_addr = 0x40000000;
1874a957563SRob Herring 		window_pci = 0x40000000;
1884a957563SRob Herring 		window_size = SZ_1G;
1894a957563SRob Herring 	} else {
1904a957563SRob Herring 		window_addr = entry->res->start;
1914a957563SRob Herring 		window_pci = entry->res->start - entry->offset;
1924a957563SRob Herring 		window_size = resource_size(entry->res);
1934a957563SRob Herring 	}
1946e0832faSShawn Lin 
1956e0832faSShawn Lin 	pm_runtime_enable(dev);
1966e0832faSShawn Lin 	pm_runtime_get_sync(dev);
1976e0832faSShawn Lin 
1986e0832faSShawn Lin 	val = ioread32(reg + RCAR_PCI_UNIT_REV_REG);
1994a957563SRob Herring 	dev_info(dev, "PCI: revision %x\n", val);
2006e0832faSShawn Lin 
2016e0832faSShawn Lin 	/* Disable Direct Power Down State and assert reset */
2026e0832faSShawn Lin 	val = ioread32(reg + RCAR_USBCTR_REG) & ~RCAR_USBCTR_DIRPD;
2036e0832faSShawn Lin 	val |= RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST;
2046e0832faSShawn Lin 	iowrite32(val, reg + RCAR_USBCTR_REG);
2056e0832faSShawn Lin 	udelay(4);
2066e0832faSShawn Lin 
2076e0832faSShawn Lin 	/* De-assert reset and reset PCIAHB window1 size */
2086e0832faSShawn Lin 	val &= ~(RCAR_USBCTR_PCIAHB_WIN1_MASK | RCAR_USBCTR_PCICLK_MASK |
2096e0832faSShawn Lin 		 RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST);
2106e0832faSShawn Lin 
2116e0832faSShawn Lin 	/* Setup PCIAHB window1 size */
2124a957563SRob Herring 	switch (window_size) {
2136e0832faSShawn Lin 	case SZ_2G:
2146e0832faSShawn Lin 		val |= RCAR_USBCTR_PCIAHB_WIN1_2G;
2156e0832faSShawn Lin 		break;
2166e0832faSShawn Lin 	case SZ_1G:
2176e0832faSShawn Lin 		val |= RCAR_USBCTR_PCIAHB_WIN1_1G;
2186e0832faSShawn Lin 		break;
2196e0832faSShawn Lin 	case SZ_512M:
2206e0832faSShawn Lin 		val |= RCAR_USBCTR_PCIAHB_WIN1_512M;
2216e0832faSShawn Lin 		break;
2226e0832faSShawn Lin 	default:
2236e0832faSShawn Lin 		pr_warn("unknown window size %ld - defaulting to 256M\n",
2244a957563SRob Herring 			window_size);
2254a957563SRob Herring 		window_size = SZ_256M;
226df561f66SGustavo A. R. Silva 		fallthrough;
2276e0832faSShawn Lin 	case SZ_256M:
2286e0832faSShawn Lin 		val |= RCAR_USBCTR_PCIAHB_WIN1_256M;
2296e0832faSShawn Lin 		break;
2306e0832faSShawn Lin 	}
2316e0832faSShawn Lin 	iowrite32(val, reg + RCAR_USBCTR_REG);
2326e0832faSShawn Lin 
2336e0832faSShawn Lin 	/* Configure AHB master and slave modes */
2346e0832faSShawn Lin 	iowrite32(RCAR_AHB_BUS_MODE, reg + RCAR_AHB_BUS_CTR_REG);
2356e0832faSShawn Lin 
2366e0832faSShawn Lin 	/* Configure PCI arbiter */
2376e0832faSShawn Lin 	val = ioread32(reg + RCAR_PCI_ARBITER_CTR_REG);
2386e0832faSShawn Lin 	val |= RCAR_PCI_ARBITER_PCIREQ0 | RCAR_PCI_ARBITER_PCIREQ1 |
2396e0832faSShawn Lin 	       RCAR_PCI_ARBITER_PCIBP_MODE;
2406e0832faSShawn Lin 	iowrite32(val, reg + RCAR_PCI_ARBITER_CTR_REG);
2416e0832faSShawn Lin 
2426e0832faSShawn Lin 	/* PCI-AHB mapping */
2434a957563SRob Herring 	iowrite32(window_addr | RCAR_PCIAHB_PREFETCH16,
2446e0832faSShawn Lin 		  reg + RCAR_PCIAHB_WIN1_CTR_REG);
2456e0832faSShawn Lin 
2466e0832faSShawn Lin 	/* AHB-PCI mapping: OHCI/EHCI registers */
2476e0832faSShawn Lin 	val = priv->mem_res.start | RCAR_AHBPCI_WIN_CTR_MEM;
2486e0832faSShawn Lin 	iowrite32(val, reg + RCAR_AHBPCI_WIN2_CTR_REG);
2496e0832faSShawn Lin 
2506e0832faSShawn Lin 	/* Enable AHB-PCI bridge PCI configuration access */
2516e0832faSShawn Lin 	iowrite32(RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG,
2526e0832faSShawn Lin 		  reg + RCAR_AHBPCI_WIN1_CTR_REG);
2536e0832faSShawn Lin 	/* Set PCI-AHB Window1 address */
2544a957563SRob Herring 	iowrite32(window_pci | PCI_BASE_ADDRESS_MEM_PREFETCH,
2556e0832faSShawn Lin 		  reg + PCI_BASE_ADDRESS_1);
2566e0832faSShawn Lin 	/* Set AHB-PCI bridge PCI communication area address */
2576e0832faSShawn Lin 	val = priv->cfg_res->start + RCAR_AHBPCI_PCICOM_OFFSET;
2586e0832faSShawn Lin 	iowrite32(val, reg + PCI_BASE_ADDRESS_0);
2596e0832faSShawn Lin 
2606e0832faSShawn Lin 	val = ioread32(reg + PCI_COMMAND);
2616e0832faSShawn Lin 	val |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
2626e0832faSShawn Lin 	       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
2636e0832faSShawn Lin 	iowrite32(val, reg + PCI_COMMAND);
2646e0832faSShawn Lin 
2656e0832faSShawn Lin 	/* Enable PCI interrupts */
2666e0832faSShawn Lin 	iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME,
2676e0832faSShawn Lin 		  reg + RCAR_PCI_INT_ENABLE_REG);
2686e0832faSShawn Lin 
2696e0832faSShawn Lin 	rcar_pci_setup_errirq(priv);
2706e0832faSShawn Lin }
2716e0832faSShawn Lin 
2726e0832faSShawn Lin static struct pci_ops rcar_pci_ops = {
2736e0832faSShawn Lin 	.map_bus = rcar_pci_cfg_base,
2746e0832faSShawn Lin 	.read	= pci_generic_config_read,
2756e0832faSShawn Lin 	.write	= pci_generic_config_write,
2766e0832faSShawn Lin };
2776e0832faSShawn Lin 
rcar_pci_probe(struct platform_device * pdev)2786e0832faSShawn Lin static int rcar_pci_probe(struct platform_device *pdev)
2796e0832faSShawn Lin {
2806e0832faSShawn Lin 	struct device *dev = &pdev->dev;
2816e0832faSShawn Lin 	struct resource *cfg_res, *mem_res;
2827025ecb6SBjorn Helgaas 	struct rcar_pci *priv;
2834a957563SRob Herring 	struct pci_host_bridge *bridge;
2846e0832faSShawn Lin 	void __iomem *reg;
2854a957563SRob Herring 
2864a957563SRob Herring 	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*priv));
2874a957563SRob Herring 	if (!bridge)
2884a957563SRob Herring 		return -ENOMEM;
2894a957563SRob Herring 
2904a957563SRob Herring 	priv = pci_host_bridge_priv(bridge);
2914a957563SRob Herring 	bridge->sysdata = priv;
2926e0832faSShawn Lin 
293*da1e3277SYang Li 	reg = devm_platform_get_and_ioremap_resource(pdev, 0, &cfg_res);
2946e0832faSShawn Lin 	if (IS_ERR(reg))
2956e0832faSShawn Lin 		return PTR_ERR(reg);
2966e0832faSShawn Lin 
2976e0832faSShawn Lin 	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
2986e0832faSShawn Lin 	if (!mem_res || !mem_res->start)
2996e0832faSShawn Lin 		return -ENODEV;
3006e0832faSShawn Lin 
3016e0832faSShawn Lin 	if (mem_res->start & 0xFFFF)
3026e0832faSShawn Lin 		return -EINVAL;
3036e0832faSShawn Lin 
3046e0832faSShawn Lin 	priv->mem_res = *mem_res;
3056e0832faSShawn Lin 	priv->cfg_res = cfg_res;
3066e0832faSShawn Lin 
3076e0832faSShawn Lin 	priv->irq = platform_get_irq(pdev, 0);
3086e0832faSShawn Lin 	priv->reg = reg;
3096e0832faSShawn Lin 	priv->dev = dev;
3106e0832faSShawn Lin 
3116e0832faSShawn Lin 	if (priv->irq < 0) {
3126e0832faSShawn Lin 		dev_err(dev, "no valid irq found\n");
3136e0832faSShawn Lin 		return priv->irq;
3146e0832faSShawn Lin 	}
3156e0832faSShawn Lin 
3164a957563SRob Herring 	bridge->ops = &rcar_pci_ops;
3176e0832faSShawn Lin 
3184a957563SRob Herring 	pci_add_flags(PCI_REASSIGN_ALL_BUS);
3196e0832faSShawn Lin 
3204a957563SRob Herring 	rcar_pci_setup(priv);
3214a957563SRob Herring 
3224a957563SRob Herring 	return pci_host_probe(bridge);
3236e0832faSShawn Lin }
3246e0832faSShawn Lin 
3256e0832faSShawn Lin static const struct of_device_id rcar_pci_of_match[] = {
3266e0832faSShawn Lin 	{ .compatible = "renesas,pci-r8a7790", },
3276e0832faSShawn Lin 	{ .compatible = "renesas,pci-r8a7791", },
3286e0832faSShawn Lin 	{ .compatible = "renesas,pci-r8a7794", },
3296e0832faSShawn Lin 	{ .compatible = "renesas,pci-rcar-gen2", },
330aefffba6SHerve Codina 	{ .compatible = "renesas,pci-rzn1", },
3316e0832faSShawn Lin 	{ },
3326e0832faSShawn Lin };
3336e0832faSShawn Lin 
3346e0832faSShawn Lin static struct platform_driver rcar_pci_driver = {
3356e0832faSShawn Lin 	.driver = {
3366e0832faSShawn Lin 		.name = "pci-rcar-gen2",
3376e0832faSShawn Lin 		.suppress_bind_attrs = true,
3386e0832faSShawn Lin 		.of_match_table = rcar_pci_of_match,
3396e0832faSShawn Lin 	},
3406e0832faSShawn Lin 	.probe = rcar_pci_probe,
3416e0832faSShawn Lin };
3426e0832faSShawn Lin builtin_platform_driver(rcar_pci_driver);
343