1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * pci-rcar-gen2: internal PCI bus support
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2013 Renesas Solutions Corp.
6*4882a593Smuzhiyun * Copyright (C) 2013 Cogent Embedded, Inc.
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * Author: Valentine Barshak <valentine.barshak@cogentembedded.com>
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/delay.h>
12*4882a593Smuzhiyun #include <linux/init.h>
13*4882a593Smuzhiyun #include <linux/interrupt.h>
14*4882a593Smuzhiyun #include <linux/io.h>
15*4882a593Smuzhiyun #include <linux/kernel.h>
16*4882a593Smuzhiyun #include <linux/of_address.h>
17*4882a593Smuzhiyun #include <linux/of_pci.h>
18*4882a593Smuzhiyun #include <linux/pci.h>
19*4882a593Smuzhiyun #include <linux/platform_device.h>
20*4882a593Smuzhiyun #include <linux/pm_runtime.h>
21*4882a593Smuzhiyun #include <linux/sizes.h>
22*4882a593Smuzhiyun #include <linux/slab.h>
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #include "../pci.h"
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun /* AHB-PCI Bridge PCI communication registers */
27*4882a593Smuzhiyun #define RCAR_AHBPCI_PCICOM_OFFSET 0x800
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #define RCAR_PCIAHB_WIN1_CTR_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x00)
30*4882a593Smuzhiyun #define RCAR_PCIAHB_WIN2_CTR_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x04)
31*4882a593Smuzhiyun #define RCAR_PCIAHB_PREFETCH0 0x0
32*4882a593Smuzhiyun #define RCAR_PCIAHB_PREFETCH4 0x1
33*4882a593Smuzhiyun #define RCAR_PCIAHB_PREFETCH8 0x2
34*4882a593Smuzhiyun #define RCAR_PCIAHB_PREFETCH16 0x3
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #define RCAR_AHBPCI_WIN1_CTR_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x10)
37*4882a593Smuzhiyun #define RCAR_AHBPCI_WIN2_CTR_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x14)
38*4882a593Smuzhiyun #define RCAR_AHBPCI_WIN_CTR_MEM (3 << 1)
39*4882a593Smuzhiyun #define RCAR_AHBPCI_WIN_CTR_CFG (5 << 1)
40*4882a593Smuzhiyun #define RCAR_AHBPCI_WIN1_HOST (1 << 30)
41*4882a593Smuzhiyun #define RCAR_AHBPCI_WIN1_DEVICE (1 << 31)
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun #define RCAR_PCI_INT_ENABLE_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x20)
44*4882a593Smuzhiyun #define RCAR_PCI_INT_STATUS_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x24)
45*4882a593Smuzhiyun #define RCAR_PCI_INT_SIGTABORT (1 << 0)
46*4882a593Smuzhiyun #define RCAR_PCI_INT_SIGRETABORT (1 << 1)
47*4882a593Smuzhiyun #define RCAR_PCI_INT_REMABORT (1 << 2)
48*4882a593Smuzhiyun #define RCAR_PCI_INT_PERR (1 << 3)
49*4882a593Smuzhiyun #define RCAR_PCI_INT_SIGSERR (1 << 4)
50*4882a593Smuzhiyun #define RCAR_PCI_INT_RESERR (1 << 5)
51*4882a593Smuzhiyun #define RCAR_PCI_INT_WIN1ERR (1 << 12)
52*4882a593Smuzhiyun #define RCAR_PCI_INT_WIN2ERR (1 << 13)
53*4882a593Smuzhiyun #define RCAR_PCI_INT_A (1 << 16)
54*4882a593Smuzhiyun #define RCAR_PCI_INT_B (1 << 17)
55*4882a593Smuzhiyun #define RCAR_PCI_INT_PME (1 << 19)
56*4882a593Smuzhiyun #define RCAR_PCI_INT_ALLERRORS (RCAR_PCI_INT_SIGTABORT | \
57*4882a593Smuzhiyun RCAR_PCI_INT_SIGRETABORT | \
58*4882a593Smuzhiyun RCAR_PCI_INT_REMABORT | \
59*4882a593Smuzhiyun RCAR_PCI_INT_PERR | \
60*4882a593Smuzhiyun RCAR_PCI_INT_SIGSERR | \
61*4882a593Smuzhiyun RCAR_PCI_INT_RESERR | \
62*4882a593Smuzhiyun RCAR_PCI_INT_WIN1ERR | \
63*4882a593Smuzhiyun RCAR_PCI_INT_WIN2ERR)
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun #define RCAR_AHB_BUS_CTR_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x30)
66*4882a593Smuzhiyun #define RCAR_AHB_BUS_MMODE_HTRANS (1 << 0)
67*4882a593Smuzhiyun #define RCAR_AHB_BUS_MMODE_BYTE_BURST (1 << 1)
68*4882a593Smuzhiyun #define RCAR_AHB_BUS_MMODE_WR_INCR (1 << 2)
69*4882a593Smuzhiyun #define RCAR_AHB_BUS_MMODE_HBUS_REQ (1 << 7)
70*4882a593Smuzhiyun #define RCAR_AHB_BUS_SMODE_READYCTR (1 << 17)
71*4882a593Smuzhiyun #define RCAR_AHB_BUS_MODE (RCAR_AHB_BUS_MMODE_HTRANS | \
72*4882a593Smuzhiyun RCAR_AHB_BUS_MMODE_BYTE_BURST | \
73*4882a593Smuzhiyun RCAR_AHB_BUS_MMODE_WR_INCR | \
74*4882a593Smuzhiyun RCAR_AHB_BUS_MMODE_HBUS_REQ | \
75*4882a593Smuzhiyun RCAR_AHB_BUS_SMODE_READYCTR)
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun #define RCAR_USBCTR_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x34)
78*4882a593Smuzhiyun #define RCAR_USBCTR_USBH_RST (1 << 0)
79*4882a593Smuzhiyun #define RCAR_USBCTR_PCICLK_MASK (1 << 1)
80*4882a593Smuzhiyun #define RCAR_USBCTR_PLL_RST (1 << 2)
81*4882a593Smuzhiyun #define RCAR_USBCTR_DIRPD (1 << 8)
82*4882a593Smuzhiyun #define RCAR_USBCTR_PCIAHB_WIN2_EN (1 << 9)
83*4882a593Smuzhiyun #define RCAR_USBCTR_PCIAHB_WIN1_256M (0 << 10)
84*4882a593Smuzhiyun #define RCAR_USBCTR_PCIAHB_WIN1_512M (1 << 10)
85*4882a593Smuzhiyun #define RCAR_USBCTR_PCIAHB_WIN1_1G (2 << 10)
86*4882a593Smuzhiyun #define RCAR_USBCTR_PCIAHB_WIN1_2G (3 << 10)
87*4882a593Smuzhiyun #define RCAR_USBCTR_PCIAHB_WIN1_MASK (3 << 10)
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun #define RCAR_PCI_ARBITER_CTR_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x40)
90*4882a593Smuzhiyun #define RCAR_PCI_ARBITER_PCIREQ0 (1 << 0)
91*4882a593Smuzhiyun #define RCAR_PCI_ARBITER_PCIREQ1 (1 << 1)
92*4882a593Smuzhiyun #define RCAR_PCI_ARBITER_PCIBP_MODE (1 << 12)
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun #define RCAR_PCI_UNIT_REV_REG (RCAR_AHBPCI_PCICOM_OFFSET + 0x48)
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun struct rcar_pci_priv {
97*4882a593Smuzhiyun struct device *dev;
98*4882a593Smuzhiyun void __iomem *reg;
99*4882a593Smuzhiyun struct resource mem_res;
100*4882a593Smuzhiyun struct resource *cfg_res;
101*4882a593Smuzhiyun int irq;
102*4882a593Smuzhiyun };
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun /* PCI configuration space operations */
rcar_pci_cfg_base(struct pci_bus * bus,unsigned int devfn,int where)105*4882a593Smuzhiyun static void __iomem *rcar_pci_cfg_base(struct pci_bus *bus, unsigned int devfn,
106*4882a593Smuzhiyun int where)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun struct rcar_pci_priv *priv = bus->sysdata;
109*4882a593Smuzhiyun int slot, val;
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun if (!pci_is_root_bus(bus) || PCI_FUNC(devfn))
112*4882a593Smuzhiyun return NULL;
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun /* Only one EHCI/OHCI device built-in */
115*4882a593Smuzhiyun slot = PCI_SLOT(devfn);
116*4882a593Smuzhiyun if (slot > 2)
117*4882a593Smuzhiyun return NULL;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun /* bridge logic only has registers to 0x40 */
120*4882a593Smuzhiyun if (slot == 0x0 && where >= 0x40)
121*4882a593Smuzhiyun return NULL;
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun val = slot ? RCAR_AHBPCI_WIN1_DEVICE | RCAR_AHBPCI_WIN_CTR_CFG :
124*4882a593Smuzhiyun RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG;
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun iowrite32(val, priv->reg + RCAR_AHBPCI_WIN1_CTR_REG);
127*4882a593Smuzhiyun return priv->reg + (slot >> 1) * 0x100 + where;
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun #ifdef CONFIG_PCI_DEBUG
131*4882a593Smuzhiyun /* if debug enabled, then attach an error handler irq to the bridge */
132*4882a593Smuzhiyun
rcar_pci_err_irq(int irq,void * pw)133*4882a593Smuzhiyun static irqreturn_t rcar_pci_err_irq(int irq, void *pw)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun struct rcar_pci_priv *priv = pw;
136*4882a593Smuzhiyun struct device *dev = priv->dev;
137*4882a593Smuzhiyun u32 status = ioread32(priv->reg + RCAR_PCI_INT_STATUS_REG);
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun if (status & RCAR_PCI_INT_ALLERRORS) {
140*4882a593Smuzhiyun dev_err(dev, "error irq: status %08x\n", status);
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun /* clear the error(s) */
143*4882a593Smuzhiyun iowrite32(status & RCAR_PCI_INT_ALLERRORS,
144*4882a593Smuzhiyun priv->reg + RCAR_PCI_INT_STATUS_REG);
145*4882a593Smuzhiyun return IRQ_HANDLED;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun return IRQ_NONE;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun
rcar_pci_setup_errirq(struct rcar_pci_priv * priv)151*4882a593Smuzhiyun static void rcar_pci_setup_errirq(struct rcar_pci_priv *priv)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun struct device *dev = priv->dev;
154*4882a593Smuzhiyun int ret;
155*4882a593Smuzhiyun u32 val;
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun ret = devm_request_irq(dev, priv->irq, rcar_pci_err_irq,
158*4882a593Smuzhiyun IRQF_SHARED, "error irq", priv);
159*4882a593Smuzhiyun if (ret) {
160*4882a593Smuzhiyun dev_err(dev, "cannot claim IRQ for error handling\n");
161*4882a593Smuzhiyun return;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun val = ioread32(priv->reg + RCAR_PCI_INT_ENABLE_REG);
165*4882a593Smuzhiyun val |= RCAR_PCI_INT_ALLERRORS;
166*4882a593Smuzhiyun iowrite32(val, priv->reg + RCAR_PCI_INT_ENABLE_REG);
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun #else
rcar_pci_setup_errirq(struct rcar_pci_priv * priv)169*4882a593Smuzhiyun static inline void rcar_pci_setup_errirq(struct rcar_pci_priv *priv) { }
170*4882a593Smuzhiyun #endif
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun /* PCI host controller setup */
rcar_pci_setup(struct rcar_pci_priv * priv)173*4882a593Smuzhiyun static void rcar_pci_setup(struct rcar_pci_priv *priv)
174*4882a593Smuzhiyun {
175*4882a593Smuzhiyun struct pci_host_bridge *bridge = pci_host_bridge_from_priv(priv);
176*4882a593Smuzhiyun struct device *dev = priv->dev;
177*4882a593Smuzhiyun void __iomem *reg = priv->reg;
178*4882a593Smuzhiyun struct resource_entry *entry;
179*4882a593Smuzhiyun unsigned long window_size;
180*4882a593Smuzhiyun unsigned long window_addr;
181*4882a593Smuzhiyun unsigned long window_pci;
182*4882a593Smuzhiyun u32 val;
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun entry = resource_list_first_type(&bridge->dma_ranges, IORESOURCE_MEM);
185*4882a593Smuzhiyun if (!entry) {
186*4882a593Smuzhiyun window_addr = 0x40000000;
187*4882a593Smuzhiyun window_pci = 0x40000000;
188*4882a593Smuzhiyun window_size = SZ_1G;
189*4882a593Smuzhiyun } else {
190*4882a593Smuzhiyun window_addr = entry->res->start;
191*4882a593Smuzhiyun window_pci = entry->res->start - entry->offset;
192*4882a593Smuzhiyun window_size = resource_size(entry->res);
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun pm_runtime_enable(dev);
196*4882a593Smuzhiyun pm_runtime_get_sync(dev);
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun val = ioread32(reg + RCAR_PCI_UNIT_REV_REG);
199*4882a593Smuzhiyun dev_info(dev, "PCI: revision %x\n", val);
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun /* Disable Direct Power Down State and assert reset */
202*4882a593Smuzhiyun val = ioread32(reg + RCAR_USBCTR_REG) & ~RCAR_USBCTR_DIRPD;
203*4882a593Smuzhiyun val |= RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST;
204*4882a593Smuzhiyun iowrite32(val, reg + RCAR_USBCTR_REG);
205*4882a593Smuzhiyun udelay(4);
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun /* De-assert reset and reset PCIAHB window1 size */
208*4882a593Smuzhiyun val &= ~(RCAR_USBCTR_PCIAHB_WIN1_MASK | RCAR_USBCTR_PCICLK_MASK |
209*4882a593Smuzhiyun RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST);
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun /* Setup PCIAHB window1 size */
212*4882a593Smuzhiyun switch (window_size) {
213*4882a593Smuzhiyun case SZ_2G:
214*4882a593Smuzhiyun val |= RCAR_USBCTR_PCIAHB_WIN1_2G;
215*4882a593Smuzhiyun break;
216*4882a593Smuzhiyun case SZ_1G:
217*4882a593Smuzhiyun val |= RCAR_USBCTR_PCIAHB_WIN1_1G;
218*4882a593Smuzhiyun break;
219*4882a593Smuzhiyun case SZ_512M:
220*4882a593Smuzhiyun val |= RCAR_USBCTR_PCIAHB_WIN1_512M;
221*4882a593Smuzhiyun break;
222*4882a593Smuzhiyun default:
223*4882a593Smuzhiyun pr_warn("unknown window size %ld - defaulting to 256M\n",
224*4882a593Smuzhiyun window_size);
225*4882a593Smuzhiyun window_size = SZ_256M;
226*4882a593Smuzhiyun fallthrough;
227*4882a593Smuzhiyun case SZ_256M:
228*4882a593Smuzhiyun val |= RCAR_USBCTR_PCIAHB_WIN1_256M;
229*4882a593Smuzhiyun break;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun iowrite32(val, reg + RCAR_USBCTR_REG);
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun /* Configure AHB master and slave modes */
234*4882a593Smuzhiyun iowrite32(RCAR_AHB_BUS_MODE, reg + RCAR_AHB_BUS_CTR_REG);
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun /* Configure PCI arbiter */
237*4882a593Smuzhiyun val = ioread32(reg + RCAR_PCI_ARBITER_CTR_REG);
238*4882a593Smuzhiyun val |= RCAR_PCI_ARBITER_PCIREQ0 | RCAR_PCI_ARBITER_PCIREQ1 |
239*4882a593Smuzhiyun RCAR_PCI_ARBITER_PCIBP_MODE;
240*4882a593Smuzhiyun iowrite32(val, reg + RCAR_PCI_ARBITER_CTR_REG);
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun /* PCI-AHB mapping */
243*4882a593Smuzhiyun iowrite32(window_addr | RCAR_PCIAHB_PREFETCH16,
244*4882a593Smuzhiyun reg + RCAR_PCIAHB_WIN1_CTR_REG);
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun /* AHB-PCI mapping: OHCI/EHCI registers */
247*4882a593Smuzhiyun val = priv->mem_res.start | RCAR_AHBPCI_WIN_CTR_MEM;
248*4882a593Smuzhiyun iowrite32(val, reg + RCAR_AHBPCI_WIN2_CTR_REG);
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun /* Enable AHB-PCI bridge PCI configuration access */
251*4882a593Smuzhiyun iowrite32(RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG,
252*4882a593Smuzhiyun reg + RCAR_AHBPCI_WIN1_CTR_REG);
253*4882a593Smuzhiyun /* Set PCI-AHB Window1 address */
254*4882a593Smuzhiyun iowrite32(window_pci | PCI_BASE_ADDRESS_MEM_PREFETCH,
255*4882a593Smuzhiyun reg + PCI_BASE_ADDRESS_1);
256*4882a593Smuzhiyun /* Set AHB-PCI bridge PCI communication area address */
257*4882a593Smuzhiyun val = priv->cfg_res->start + RCAR_AHBPCI_PCICOM_OFFSET;
258*4882a593Smuzhiyun iowrite32(val, reg + PCI_BASE_ADDRESS_0);
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun val = ioread32(reg + PCI_COMMAND);
261*4882a593Smuzhiyun val |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
262*4882a593Smuzhiyun PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
263*4882a593Smuzhiyun iowrite32(val, reg + PCI_COMMAND);
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun /* Enable PCI interrupts */
266*4882a593Smuzhiyun iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME,
267*4882a593Smuzhiyun reg + RCAR_PCI_INT_ENABLE_REG);
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun rcar_pci_setup_errirq(priv);
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun static struct pci_ops rcar_pci_ops = {
273*4882a593Smuzhiyun .map_bus = rcar_pci_cfg_base,
274*4882a593Smuzhiyun .read = pci_generic_config_read,
275*4882a593Smuzhiyun .write = pci_generic_config_write,
276*4882a593Smuzhiyun };
277*4882a593Smuzhiyun
rcar_pci_probe(struct platform_device * pdev)278*4882a593Smuzhiyun static int rcar_pci_probe(struct platform_device *pdev)
279*4882a593Smuzhiyun {
280*4882a593Smuzhiyun struct device *dev = &pdev->dev;
281*4882a593Smuzhiyun struct resource *cfg_res, *mem_res;
282*4882a593Smuzhiyun struct rcar_pci_priv *priv;
283*4882a593Smuzhiyun struct pci_host_bridge *bridge;
284*4882a593Smuzhiyun void __iomem *reg;
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun bridge = devm_pci_alloc_host_bridge(dev, sizeof(*priv));
287*4882a593Smuzhiyun if (!bridge)
288*4882a593Smuzhiyun return -ENOMEM;
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun priv = pci_host_bridge_priv(bridge);
291*4882a593Smuzhiyun bridge->sysdata = priv;
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun cfg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
294*4882a593Smuzhiyun reg = devm_ioremap_resource(dev, cfg_res);
295*4882a593Smuzhiyun if (IS_ERR(reg))
296*4882a593Smuzhiyun return PTR_ERR(reg);
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
299*4882a593Smuzhiyun if (!mem_res || !mem_res->start)
300*4882a593Smuzhiyun return -ENODEV;
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun if (mem_res->start & 0xFFFF)
303*4882a593Smuzhiyun return -EINVAL;
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun priv->mem_res = *mem_res;
306*4882a593Smuzhiyun priv->cfg_res = cfg_res;
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun priv->irq = platform_get_irq(pdev, 0);
309*4882a593Smuzhiyun priv->reg = reg;
310*4882a593Smuzhiyun priv->dev = dev;
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun if (priv->irq < 0) {
313*4882a593Smuzhiyun dev_err(dev, "no valid irq found\n");
314*4882a593Smuzhiyun return priv->irq;
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun bridge->ops = &rcar_pci_ops;
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun pci_add_flags(PCI_REASSIGN_ALL_BUS);
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun rcar_pci_setup(priv);
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun return pci_host_probe(bridge);
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun static const struct of_device_id rcar_pci_of_match[] = {
327*4882a593Smuzhiyun { .compatible = "renesas,pci-r8a7790", },
328*4882a593Smuzhiyun { .compatible = "renesas,pci-r8a7791", },
329*4882a593Smuzhiyun { .compatible = "renesas,pci-r8a7794", },
330*4882a593Smuzhiyun { .compatible = "renesas,pci-rcar-gen2", },
331*4882a593Smuzhiyun { },
332*4882a593Smuzhiyun };
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun static struct platform_driver rcar_pci_driver = {
335*4882a593Smuzhiyun .driver = {
336*4882a593Smuzhiyun .name = "pci-rcar-gen2",
337*4882a593Smuzhiyun .suppress_bind_attrs = true,
338*4882a593Smuzhiyun .of_match_table = rcar_pci_of_match,
339*4882a593Smuzhiyun },
340*4882a593Smuzhiyun .probe = rcar_pci_probe,
341*4882a593Smuzhiyun };
342*4882a593Smuzhiyun builtin_platform_driver(rcar_pci_driver);
343