xref: /OK3568_Linux_fs/kernel/drivers/pci/controller/pci-rcar-gen2.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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