aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller/pcie-altera.c
diff options
context:
space:
mode:
authorShawn Lin <shawn.lin@rock-chips.com>2018-05-30 21:12:37 -0400
committerBjorn Helgaas <bhelgaas@google.com>2018-06-08 08:50:11 -0400
commit6e0832fa432ec99c94caee733c8f5851cf85560b (patch)
treec4326f9e2d8ff1a6cb17e959fc5268c9e577ca94 /drivers/pci/controller/pcie-altera.c
parent3a3869f1c443383ef8354ffa0e5fb8df65d8b549 (diff)
PCI: Collect all native drivers under drivers/pci/controller/
Native PCI drivers for root complex devices were originally all in drivers/pci/host/. Some of these devices can also be operated in endpoint mode. Drivers for endpoint mode didn't seem to fit in the "host" directory, so we put both the root complex and endpoint drivers in per-device directories, e.g., drivers/pci/dwc/, drivers/pci/cadence/, etc. These per-device directories contain trivial Kconfig and Makefiles and clutter drivers/pci/. Make a new drivers/pci/controllers/ directory and collect all the device-specific drivers there. No functional change intended. Link: https://lkml.kernel.org/r/1520304202-232891-1-git-send-email-shawn.lin@rock-chips.com Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com> [bhelgaas: changelog] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/controller/pcie-altera.c')
-rw-r--r--drivers/pci/controller/pcie-altera.c645
1 files changed, 645 insertions, 0 deletions
diff --git a/drivers/pci/controller/pcie-altera.c b/drivers/pci/controller/pcie-altera.c
new file mode 100644
index 000000000000..7d05e51205b3
--- /dev/null
+++ b/drivers/pci/controller/pcie-altera.c
@@ -0,0 +1,645 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright Altera Corporation (C) 2013-2015. All rights reserved
4 *
5 * Author: Ley Foon Tan <lftan@altera.com>
6 * Description: Altera PCIe host controller driver
7 */
8
9#include <linux/delay.h>
10#include <linux/interrupt.h>
11#include <linux/irqchip/chained_irq.h>
12#include <linux/init.h>
13#include <linux/of_address.h>
14#include <linux/of_irq.h>
15#include <linux/of_pci.h>
16#include <linux/pci.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19
20#include "../pci.h"
21
22#define RP_TX_REG0 0x2000
23#define RP_TX_REG1 0x2004
24#define RP_TX_CNTRL 0x2008
25#define RP_TX_EOP 0x2
26#define RP_TX_SOP 0x1
27#define RP_RXCPL_STATUS 0x2010
28#define RP_RXCPL_EOP 0x2
29#define RP_RXCPL_SOP 0x1
30#define RP_RXCPL_REG0 0x2014
31#define RP_RXCPL_REG1 0x2018
32#define P2A_INT_STATUS 0x3060
33#define P2A_INT_STS_ALL 0xf
34#define P2A_INT_ENABLE 0x3070
35#define P2A_INT_ENA_ALL 0xf
36#define RP_LTSSM 0x3c64
37#define RP_LTSSM_MASK 0x1f
38#define LTSSM_L0 0xf
39
40#define PCIE_CAP_OFFSET 0x80
41/* TLP configuration type 0 and 1 */
42#define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */
43#define TLP_FMTTYPE_CFGWR0 0x44 /* Configuration Write Type 0 */
44#define TLP_FMTTYPE_CFGRD1 0x05 /* Configuration Read Type 1 */
45#define TLP_FMTTYPE_CFGWR1 0x45 /* Configuration Write Type 1 */
46#define TLP_PAYLOAD_SIZE 0x01
47#define TLP_READ_TAG 0x1d
48#define TLP_WRITE_TAG 0x10
49#define RP_DEVFN 0
50#define TLP_REQ_ID(bus, devfn) (((bus) << 8) | (devfn))
51#define TLP_CFGRD_DW0(pcie, bus) \
52 ((((bus == pcie->root_bus_nr) ? TLP_FMTTYPE_CFGRD0 \
53 : TLP_FMTTYPE_CFGRD1) << 24) | \
54 TLP_PAYLOAD_SIZE)
55#define TLP_CFGWR_DW0(pcie, bus) \
56 ((((bus == pcie->root_bus_nr) ? TLP_FMTTYPE_CFGWR0 \
57 : TLP_FMTTYPE_CFGWR1) << 24) | \
58 TLP_PAYLOAD_SIZE)
59#define TLP_CFG_DW1(pcie, tag, be) \
60 (((TLP_REQ_ID(pcie->root_bus_nr, RP_DEVFN)) << 16) | (tag << 8) | (be))
61#define TLP_CFG_DW2(bus, devfn, offset) \
62 (((bus) << 24) | ((devfn) << 16) | (offset))
63#define TLP_COMP_STATUS(s) (((s) >> 13) & 7)
64#define TLP_HDR_SIZE 3
65#define TLP_LOOP 500
66
67#define LINK_UP_TIMEOUT HZ
68#define LINK_RETRAIN_TIMEOUT HZ
69
70#define DWORD_MASK 3
71
72struct altera_pcie {
73 struct platform_device *pdev;
74 void __iomem *cra_base; /* DT Cra */
75 int irq;
76 u8 root_bus_nr;
77 struct irq_domain *irq_domain;
78 struct resource bus_range;
79 struct list_head resources;
80};
81
82struct tlp_rp_regpair_t {
83 u32 ctrl;
84 u32 reg0;
85 u32 reg1;
86};
87
88static inline void cra_writel(struct altera_pcie *pcie, const u32 value,
89 const u32 reg)
90{
91 writel_relaxed(value, pcie->cra_base + reg);
92}
93
94static inline u32 cra_readl(struct altera_pcie *pcie, const u32 reg)
95{
96 return readl_relaxed(pcie->cra_base + reg);
97}
98
99static bool altera_pcie_link_up(struct altera_pcie *pcie)
100{
101 return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0);
102}
103
104/*
105 * Altera PCIe port uses BAR0 of RC's configuration space as the translation
106 * from PCI bus to native BUS. Entire DDR region is mapped into PCIe space
107 * using these registers, so it can be reached by DMA from EP devices.
108 * This BAR0 will also access to MSI vector when receiving MSI/MSIX interrupt
109 * from EP devices, eventually trigger interrupt to GIC. The BAR0 of bridge
110 * should be hidden during enumeration to avoid the sizing and resource
111 * allocation by PCIe core.
112 */
113static bool altera_pcie_hide_rc_bar(struct pci_bus *bus, unsigned int devfn,
114 int offset)
115{
116 if (pci_is_root_bus(bus) && (devfn == 0) &&
117 (offset == PCI_BASE_ADDRESS_0))
118 return true;
119
120 return false;
121}
122
123static void tlp_write_tx(struct altera_pcie *pcie,
124 struct tlp_rp_regpair_t *tlp_rp_regdata)
125{
126 cra_writel(pcie, tlp_rp_regdata->reg0, RP_TX_REG0);
127 cra_writel(pcie, tlp_rp_regdata->reg1, RP_TX_REG1);
128 cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL);
129}
130
131static bool altera_pcie_valid_device(struct altera_pcie *pcie,
132 struct pci_bus *bus, int dev)
133{
134 /* If there is no link, then there is no device */
135 if (bus->number != pcie->root_bus_nr) {
136 if (!altera_pcie_link_up(pcie))
137 return false;
138 }
139
140 /* access only one slot on each root port */
141 if (bus->number == pcie->root_bus_nr && dev > 0)
142 return false;
143
144 return true;
145}
146
147static int tlp_read_packet(struct altera_pcie *pcie, u32 *value)
148{
149 int i;
150 bool sop = false;
151 u32 ctrl;
152 u32 reg0, reg1;
153 u32 comp_status = 1;
154
155 /*
156 * Minimum 2 loops to read TLP headers and 1 loop to read data
157 * payload.
158 */
159 for (i = 0; i < TLP_LOOP; i++) {
160 ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
161 if ((ctrl & RP_RXCPL_SOP) || (ctrl & RP_RXCPL_EOP) || sop) {
162 reg0 = cra_readl(pcie, RP_RXCPL_REG0);
163 reg1 = cra_readl(pcie, RP_RXCPL_REG1);
164
165 if (ctrl & RP_RXCPL_SOP) {
166 sop = true;
167 comp_status = TLP_COMP_STATUS(reg1);
168 }
169
170 if (ctrl & RP_RXCPL_EOP) {
171 if (comp_status)
172 return PCIBIOS_DEVICE_NOT_FOUND;
173
174 if (value)
175 *value = reg0;
176
177 return PCIBIOS_SUCCESSFUL;
178 }
179 }
180 udelay(5);
181 }
182
183 return PCIBIOS_DEVICE_NOT_FOUND;
184}
185
186static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers,
187 u32 data, bool align)
188{
189 struct tlp_rp_regpair_t tlp_rp_regdata;
190
191 tlp_rp_regdata.reg0 = headers[0];
192 tlp_rp_regdata.reg1 = headers[1];
193 tlp_rp_regdata.ctrl = RP_TX_SOP;
194 tlp_write_tx(pcie, &tlp_rp_regdata);
195
196 if (align) {
197 tlp_rp_regdata.reg0 = headers[2];
198 tlp_rp_regdata.reg1 = 0;
199 tlp_rp_regdata.ctrl = 0;
200 tlp_write_tx(pcie, &tlp_rp_regdata);
201
202 tlp_rp_regdata.reg0 = data;
203 tlp_rp_regdata.reg1 = 0;
204 } else {
205 tlp_rp_regdata.reg0 = headers[2];
206 tlp_rp_regdata.reg1 = data;
207 }
208
209 tlp_rp_regdata.ctrl = RP_TX_EOP;
210 tlp_write_tx(pcie, &tlp_rp_regdata);
211}
212
213static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
214 int where, u8 byte_en, u32 *value)
215{
216 u32 headers[TLP_HDR_SIZE];
217
218 headers[0] = TLP_CFGRD_DW0(pcie, bus);
219 headers[1] = TLP_CFG_DW1(pcie, TLP_READ_TAG, byte_en);
220 headers[2] = TLP_CFG_DW2(bus, devfn, where);
221
222 tlp_write_packet(pcie, headers, 0, false);
223
224 return tlp_read_packet(pcie, value);
225}
226
227static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
228 int where, u8 byte_en, u32 value)
229{
230 u32 headers[TLP_HDR_SIZE];
231 int ret;
232
233 headers[0] = TLP_CFGWR_DW0(pcie, bus);
234 headers[1] = TLP_CFG_DW1(pcie, TLP_WRITE_TAG, byte_en);
235 headers[2] = TLP_CFG_DW2(bus, devfn, where);
236
237 /* check alignment to Qword */
238 if ((where & 0x7) == 0)
239 tlp_write_packet(pcie, headers, value, true);
240 else
241 tlp_write_packet(pcie, headers, value, false);
242
243 ret = tlp_read_packet(pcie, NULL);
244 if (ret != PCIBIOS_SUCCESSFUL)
245 return ret;
246
247 /*
248 * Monitor changes to PCI_PRIMARY_BUS register on root port
249 * and update local copy of root bus number accordingly.
250 */
251 if ((bus == pcie->root_bus_nr) && (where == PCI_PRIMARY_BUS))
252 pcie->root_bus_nr = (u8)(value);
253
254 return PCIBIOS_SUCCESSFUL;
255}
256
257static int _altera_pcie_cfg_read(struct altera_pcie *pcie, u8 busno,
258 unsigned int devfn, int where, int size,
259 u32 *value)
260{
261 int ret;
262 u32 data;
263 u8 byte_en;
264
265 switch (size) {
266 case 1:
267 byte_en = 1 << (where & 3);
268 break;
269 case 2:
270 byte_en = 3 << (where & 3);
271 break;
272 default:
273 byte_en = 0xf;
274 break;
275 }
276
277 ret = tlp_cfg_dword_read(pcie, busno, devfn,
278 (where & ~DWORD_MASK), byte_en, &data);
279 if (ret != PCIBIOS_SUCCESSFUL)
280 return ret;
281
282 switch (size) {
283 case 1:
284 *value = (data >> (8 * (where & 0x3))) & 0xff;
285 break;
286 case 2:
287 *value = (data >> (8 * (where & 0x2))) & 0xffff;
288 break;
289 default:
290 *value = data;
291 break;
292 }
293
294 return PCIBIOS_SUCCESSFUL;
295}
296
297static int _altera_pcie_cfg_write(struct altera_pcie *pcie, u8 busno,
298 unsigned int devfn, int where, int size,
299 u32 value)
300{
301 u32 data32;
302 u32 shift = 8 * (where & 3);
303 u8 byte_en;
304
305 switch (size) {
306 case 1:
307 data32 = (value & 0xff) << shift;
308 byte_en = 1 << (where & 3);
309 break;
310 case 2:
311 data32 = (value & 0xffff) << shift;
312 byte_en = 3 << (where & 3);
313 break;
314 default:
315 data32 = value;
316 byte_en = 0xf;
317 break;
318 }
319
320 return tlp_cfg_dword_write(pcie, busno, devfn, (where & ~DWORD_MASK),
321 byte_en, data32);
322}
323
324static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
325 int where, int size, u32 *value)
326{
327 struct altera_pcie *pcie = bus->sysdata;
328
329 if (altera_pcie_hide_rc_bar(bus, devfn, where))
330 return PCIBIOS_BAD_REGISTER_NUMBER;
331
332 if (!altera_pcie_valid_device(pcie, bus, PCI_SLOT(devfn))) {
333 *value = 0xffffffff;
334 return PCIBIOS_DEVICE_NOT_FOUND;
335 }
336
337 return _altera_pcie_cfg_read(pcie, bus->number, devfn, where, size,
338 value);
339}
340
341static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn,
342 int where, int size, u32 value)
343{
344 struct altera_pcie *pcie = bus->sysdata;
345
346 if (altera_pcie_hide_rc_bar(bus, devfn, where))
347 return PCIBIOS_BAD_REGISTER_NUMBER;
348
349 if (!altera_pcie_valid_device(pcie, bus, PCI_SLOT(devfn)))
350 return PCIBIOS_DEVICE_NOT_FOUND;
351
352 return _altera_pcie_cfg_write(pcie, bus->number, devfn, where, size,
353 value);
354}
355
356static struct pci_ops altera_pcie_ops = {
357 .read = altera_pcie_cfg_read,
358 .write = altera_pcie_cfg_write,
359};
360
361static int altera_read_cap_word(struct altera_pcie *pcie, u8 busno,
362 unsigned int devfn, int offset, u16 *value)
363{
364 u32 data;
365 int ret;
366
367 ret = _altera_pcie_cfg_read(pcie, busno, devfn,
368 PCIE_CAP_OFFSET + offset, sizeof(*value),
369 &data);
370 *value = data;
371 return ret;
372}
373
374static int altera_write_cap_word(struct altera_pcie *pcie, u8 busno,
375 unsigned int devfn, int offset, u16 value)
376{
377 return _altera_pcie_cfg_write(pcie, busno, devfn,
378 PCIE_CAP_OFFSET + offset, sizeof(value),
379 value);
380}
381
382static void altera_wait_link_retrain(struct altera_pcie *pcie)
383{
384 struct device *dev = &pcie->pdev->dev;
385 u16 reg16;
386 unsigned long start_jiffies;
387
388 /* Wait for link training end. */
389 start_jiffies = jiffies;
390 for (;;) {
391 altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN,
392 PCI_EXP_LNKSTA, &reg16);
393 if (!(reg16 & PCI_EXP_LNKSTA_LT))
394 break;
395
396 if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) {
397 dev_err(dev, "link retrain timeout\n");
398 break;
399 }
400 udelay(100);
401 }
402
403 /* Wait for link is up */
404 start_jiffies = jiffies;
405 for (;;) {
406 if (altera_pcie_link_up(pcie))
407 break;
408
409 if (time_after(jiffies, start_jiffies + LINK_UP_TIMEOUT)) {
410 dev_err(dev, "link up timeout\n");
411 break;
412 }
413 udelay(100);
414 }
415}
416
417static void altera_pcie_retrain(struct altera_pcie *pcie)
418{
419 u16 linkcap, linkstat, linkctl;
420
421 if (!altera_pcie_link_up(pcie))
422 return;
423
424 /*
425 * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but
426 * current speed is 2.5 GB/s.
427 */
428 altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN, PCI_EXP_LNKCAP,
429 &linkcap);
430 if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
431 return;
432
433 altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN, PCI_EXP_LNKSTA,
434 &linkstat);
435 if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) {
436 altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN,
437 PCI_EXP_LNKCTL, &linkctl);
438 linkctl |= PCI_EXP_LNKCTL_RL;
439 altera_write_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN,
440 PCI_EXP_LNKCTL, linkctl);
441
442 altera_wait_link_retrain(pcie);
443 }
444}
445
446static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
447 irq_hw_number_t hwirq)
448{
449 irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
450 irq_set_chip_data(irq, domain->host_data);
451 return 0;
452}
453
454static const struct irq_domain_ops intx_domain_ops = {
455 .map = altera_pcie_intx_map,
456 .xlate = pci_irqd_intx_xlate,
457};
458
459static void altera_pcie_isr(struct irq_desc *desc)
460{
461 struct irq_chip *chip = irq_desc_get_chip(desc);
462 struct altera_pcie *pcie;
463 struct device *dev;
464 unsigned long status;
465 u32 bit;
466 u32 virq;
467
468 chained_irq_enter(chip, desc);
469 pcie = irq_desc_get_handler_data(desc);
470 dev = &pcie->pdev->dev;
471
472 while ((status = cra_readl(pcie, P2A_INT_STATUS)
473 & P2A_INT_STS_ALL) != 0) {
474 for_each_set_bit(bit, &status, PCI_NUM_INTX) {
475 /* clear interrupts */
476 cra_writel(pcie, 1 << bit, P2A_INT_STATUS);
477
478 virq = irq_find_mapping(pcie->irq_domain, bit);
479 if (virq)
480 generic_handle_irq(virq);
481 else
482 dev_err(dev, "unexpected IRQ, INT%d\n", bit);
483 }
484 }
485
486 chained_irq_exit(chip, desc);
487}
488
489static int altera_pcie_parse_request_of_pci_ranges(struct altera_pcie *pcie)
490{
491 int err, res_valid = 0;
492 struct device *dev = &pcie->pdev->dev;
493 struct resource_entry *win;
494
495 err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
496 &pcie->resources, NULL);
497 if (err)
498 return err;
499
500 err = devm_request_pci_bus_resources(dev, &pcie->resources);
501 if (err)
502 goto out_release_res;
503
504 resource_list_for_each_entry(win, &pcie->resources) {
505 struct resource *res = win->res;
506
507 if (resource_type(res) == IORESOURCE_MEM)
508 res_valid |= !(res->flags & IORESOURCE_PREFETCH);
509 }
510
511 if (res_valid)
512 return 0;
513
514 dev_err(dev, "non-prefetchable memory resource required\n");
515 err = -EINVAL;
516
517out_release_res:
518 pci_free_resource_list(&pcie->resources);
519 return err;
520}
521
522static int altera_pcie_init_irq_domain(struct altera_pcie *pcie)
523{
524 struct device *dev = &pcie->pdev->dev;
525 struct device_node *node = dev->of_node;
526
527 /* Setup INTx */
528 pcie->irq_domain = irq_domain_add_linear(node, PCI_NUM_INTX,
529 &intx_domain_ops, pcie);
530 if (!pcie->irq_domain) {
531 dev_err(dev, "Failed to get a INTx IRQ domain\n");
532 return -ENOMEM;
533 }
534
535 return 0;
536}
537
538static int altera_pcie_parse_dt(struct altera_pcie *pcie)
539{
540 struct device *dev = &pcie->pdev->dev;
541 struct platform_device *pdev = pcie->pdev;
542 struct resource *cra;
543
544 cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra");
545 pcie->cra_base = devm_ioremap_resource(dev, cra);
546 if (IS_ERR(pcie->cra_base))
547 return PTR_ERR(pcie->cra_base);
548
549 /* setup IRQ */
550 pcie->irq = platform_get_irq(pdev, 0);
551 if (pcie->irq < 0) {
552 dev_err(dev, "failed to get IRQ: %d\n", pcie->irq);
553 return pcie->irq;
554 }
555
556 irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie);
557 return 0;
558}
559
560static void altera_pcie_host_init(struct altera_pcie *pcie)
561{
562 altera_pcie_retrain(pcie);
563}
564
565static int altera_pcie_probe(struct platform_device *pdev)
566{
567 struct device *dev = &pdev->dev;
568 struct altera_pcie *pcie;
569 struct pci_bus *bus;
570 struct pci_bus *child;
571 struct pci_host_bridge *bridge;
572 int ret;
573
574 bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
575 if (!bridge)
576 return -ENOMEM;
577
578 pcie = pci_host_bridge_priv(bridge);
579 pcie->pdev = pdev;
580
581 ret = altera_pcie_parse_dt(pcie);
582 if (ret) {
583 dev_err(dev, "Parsing DT failed\n");
584 return ret;
585 }
586
587 INIT_LIST_HEAD(&pcie->resources);
588
589 ret = altera_pcie_parse_request_of_pci_ranges(pcie);
590 if (ret) {
591 dev_err(dev, "Failed add resources\n");
592 return ret;
593 }
594
595 ret = altera_pcie_init_irq_domain(pcie);
596 if (ret) {
597 dev_err(dev, "Failed creating IRQ Domain\n");
598 return ret;
599 }
600
601 /* clear all interrupts */
602 cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
603 /* enable all interrupts */
604 cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE);
605 altera_pcie_host_init(pcie);
606
607 list_splice_init(&pcie->resources, &bridge->windows);
608 bridge->dev.parent = dev;
609 bridge->sysdata = pcie;
610 bridge->busnr = pcie->root_bus_nr;
611 bridge->ops = &altera_pcie_ops;
612 bridge->map_irq = of_irq_parse_and_map_pci;
613 bridge->swizzle_irq = pci_common_swizzle;
614
615 ret = pci_scan_root_bus_bridge(bridge);
616 if (ret < 0)
617 return ret;
618
619 bus = bridge->bus;
620
621 pci_assign_unassigned_bus_resources(bus);
622
623 /* Configure PCI Express setting. */
624 list_for_each_entry(child, &bus->children, node)
625 pcie_bus_configure_settings(child);
626
627 pci_bus_add_devices(bus);
628 return ret;
629}
630
631static const struct of_device_id altera_pcie_of_match[] = {
632 { .compatible = "altr,pcie-root-port-1.0", },
633 {},
634};
635
636static struct platform_driver altera_pcie_driver = {
637 .probe = altera_pcie_probe,
638 .driver = {
639 .name = "altera-pcie",
640 .of_match_table = altera_pcie_of_match,
641 .suppress_bind_attrs = true,
642 },
643};
644
645builtin_platform_driver(altera_pcie_driver);