hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/pci/controller/pcie-altera.c
....@@ -10,7 +10,9 @@
1010 #include <linux/interrupt.h>
1111 #include <linux/irqchip/chained_irq.h>
1212 #include <linux/init.h>
13
+#include <linux/module.h>
1314 #include <linux/of_address.h>
15
+#include <linux/of_device.h>
1416 #include <linux/of_irq.h>
1517 #include <linux/of_pci.h>
1618 #include <linux/pci.h>
....@@ -37,7 +39,14 @@
3739 #define RP_LTSSM_MASK 0x1f
3840 #define LTSSM_L0 0xf
3941
40
-#define PCIE_CAP_OFFSET 0x80
42
+#define S10_RP_TX_CNTRL 0x2004
43
+#define S10_RP_RXCPL_REG 0x2008
44
+#define S10_RP_RXCPL_STATUS 0x200C
45
+#define S10_RP_CFG_ADDR(pcie, reg) \
46
+ (((pcie)->hip_base) + (reg) + (1 << 20))
47
+#define S10_RP_SECONDARY(pcie) \
48
+ readb(S10_RP_CFG_ADDR(pcie, PCI_SECONDARY_BUS))
49
+
4150 /* TLP configuration type 0 and 1 */
4251 #define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */
4352 #define TLP_FMTTYPE_CFGWR0 0x44 /* Configuration Write Type 0 */
....@@ -48,19 +57,15 @@
4857 #define TLP_WRITE_TAG 0x10
4958 #define RP_DEVFN 0
5059 #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)
60
+#define TLP_CFG_DW0(pcie, cfg) \
61
+ (((cfg) << 24) | \
62
+ TLP_PAYLOAD_SIZE)
5963 #define TLP_CFG_DW1(pcie, tag, be) \
60
- (((TLP_REQ_ID(pcie->root_bus_nr, RP_DEVFN)) << 16) | (tag << 8) | (be))
64
+ (((TLP_REQ_ID(pcie->root_bus_nr, RP_DEVFN)) << 16) | (tag << 8) | (be))
6165 #define TLP_CFG_DW2(bus, devfn, offset) \
6266 (((bus) << 24) | ((devfn) << 16) | (offset))
6367 #define TLP_COMP_STATUS(s) (((s) >> 13) & 7)
68
+#define TLP_BYTE_COUNT(s) (((s) >> 0) & 0xfff)
6469 #define TLP_HDR_SIZE 3
6570 #define TLP_LOOP 500
6671
....@@ -69,14 +74,46 @@
6974
7075 #define DWORD_MASK 3
7176
77
+#define S10_TLP_FMTTYPE_CFGRD0 0x05
78
+#define S10_TLP_FMTTYPE_CFGRD1 0x04
79
+#define S10_TLP_FMTTYPE_CFGWR0 0x45
80
+#define S10_TLP_FMTTYPE_CFGWR1 0x44
81
+
82
+enum altera_pcie_version {
83
+ ALTERA_PCIE_V1 = 0,
84
+ ALTERA_PCIE_V2,
85
+};
86
+
7287 struct altera_pcie {
7388 struct platform_device *pdev;
74
- void __iomem *cra_base; /* DT Cra */
89
+ void __iomem *cra_base;
90
+ void __iomem *hip_base;
7591 int irq;
7692 u8 root_bus_nr;
7793 struct irq_domain *irq_domain;
7894 struct resource bus_range;
79
- struct list_head resources;
95
+ const struct altera_pcie_data *pcie_data;
96
+};
97
+
98
+struct altera_pcie_ops {
99
+ int (*tlp_read_pkt)(struct altera_pcie *pcie, u32 *value);
100
+ void (*tlp_write_pkt)(struct altera_pcie *pcie, u32 *headers,
101
+ u32 data, bool align);
102
+ bool (*get_link_status)(struct altera_pcie *pcie);
103
+ int (*rp_read_cfg)(struct altera_pcie *pcie, int where,
104
+ int size, u32 *value);
105
+ int (*rp_write_cfg)(struct altera_pcie *pcie, u8 busno,
106
+ int where, int size, u32 value);
107
+};
108
+
109
+struct altera_pcie_data {
110
+ const struct altera_pcie_ops *ops;
111
+ enum altera_pcie_version version;
112
+ u32 cap_offset; /* PCIe capability structure register offset */
113
+ u32 cfgrd0;
114
+ u32 cfgrd1;
115
+ u32 cfgwr0;
116
+ u32 cfgwr1;
80117 };
81118
82119 struct tlp_rp_regpair_t {
....@@ -99,6 +136,15 @@
99136 static bool altera_pcie_link_up(struct altera_pcie *pcie)
100137 {
101138 return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0);
139
+}
140
+
141
+static bool s10_altera_pcie_link_up(struct altera_pcie *pcie)
142
+{
143
+ void __iomem *addr = S10_RP_CFG_ADDR(pcie,
144
+ pcie->pcie_data->cap_offset +
145
+ PCI_EXP_LNKSTA);
146
+
147
+ return !!(readw(addr) & PCI_EXP_LNKSTA_DLLLA);
102148 }
103149
104150 /*
....@@ -128,12 +174,18 @@
128174 cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL);
129175 }
130176
177
+static void s10_tlp_write_tx(struct altera_pcie *pcie, u32 reg0, u32 ctrl)
178
+{
179
+ cra_writel(pcie, reg0, RP_TX_REG0);
180
+ cra_writel(pcie, ctrl, S10_RP_TX_CNTRL);
181
+}
182
+
131183 static bool altera_pcie_valid_device(struct altera_pcie *pcie,
132184 struct pci_bus *bus, int dev)
133185 {
134186 /* If there is no link, then there is no device */
135187 if (bus->number != pcie->root_bus_nr) {
136
- if (!altera_pcie_link_up(pcie))
188
+ if (!pcie->pcie_data->ops->get_link_status(pcie))
137189 return false;
138190 }
139191
....@@ -141,7 +193,7 @@
141193 if (bus->number == pcie->root_bus_nr && dev > 0)
142194 return false;
143195
144
- return true;
196
+ return true;
145197 }
146198
147199 static int tlp_read_packet(struct altera_pcie *pcie, u32 *value)
....@@ -183,6 +235,53 @@
183235 return PCIBIOS_DEVICE_NOT_FOUND;
184236 }
185237
238
+static int s10_tlp_read_packet(struct altera_pcie *pcie, u32 *value)
239
+{
240
+ u32 ctrl;
241
+ u32 comp_status;
242
+ u32 dw[4];
243
+ u32 count;
244
+ struct device *dev = &pcie->pdev->dev;
245
+
246
+ for (count = 0; count < TLP_LOOP; count++) {
247
+ ctrl = cra_readl(pcie, S10_RP_RXCPL_STATUS);
248
+ if (ctrl & RP_RXCPL_SOP) {
249
+ /* Read first DW */
250
+ dw[0] = cra_readl(pcie, S10_RP_RXCPL_REG);
251
+ break;
252
+ }
253
+
254
+ udelay(5);
255
+ }
256
+
257
+ /* SOP detection failed, return error */
258
+ if (count == TLP_LOOP)
259
+ return PCIBIOS_DEVICE_NOT_FOUND;
260
+
261
+ count = 1;
262
+
263
+ /* Poll for EOP */
264
+ while (count < ARRAY_SIZE(dw)) {
265
+ ctrl = cra_readl(pcie, S10_RP_RXCPL_STATUS);
266
+ dw[count++] = cra_readl(pcie, S10_RP_RXCPL_REG);
267
+ if (ctrl & RP_RXCPL_EOP) {
268
+ comp_status = TLP_COMP_STATUS(dw[1]);
269
+ if (comp_status)
270
+ return PCIBIOS_DEVICE_NOT_FOUND;
271
+
272
+ if (value && TLP_BYTE_COUNT(dw[1]) == sizeof(u32) &&
273
+ count == 4)
274
+ *value = dw[3];
275
+
276
+ return PCIBIOS_SUCCESSFUL;
277
+ }
278
+ }
279
+
280
+ dev_warn(dev, "Malformed TLP packet\n");
281
+
282
+ return PCIBIOS_DEVICE_NOT_FOUND;
283
+}
284
+
186285 static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers,
187286 u32 data, bool align)
188287 {
....@@ -210,18 +309,44 @@
210309 tlp_write_tx(pcie, &tlp_rp_regdata);
211310 }
212311
312
+static void s10_tlp_write_packet(struct altera_pcie *pcie, u32 *headers,
313
+ u32 data, bool dummy)
314
+{
315
+ s10_tlp_write_tx(pcie, headers[0], RP_TX_SOP);
316
+ s10_tlp_write_tx(pcie, headers[1], 0);
317
+ s10_tlp_write_tx(pcie, headers[2], 0);
318
+ s10_tlp_write_tx(pcie, data, RP_TX_EOP);
319
+}
320
+
321
+static void get_tlp_header(struct altera_pcie *pcie, u8 bus, u32 devfn,
322
+ int where, u8 byte_en, bool read, u32 *headers)
323
+{
324
+ u8 cfg;
325
+ u8 cfg0 = read ? pcie->pcie_data->cfgrd0 : pcie->pcie_data->cfgwr0;
326
+ u8 cfg1 = read ? pcie->pcie_data->cfgrd1 : pcie->pcie_data->cfgwr1;
327
+ u8 tag = read ? TLP_READ_TAG : TLP_WRITE_TAG;
328
+
329
+ if (pcie->pcie_data->version == ALTERA_PCIE_V1)
330
+ cfg = (bus == pcie->root_bus_nr) ? cfg0 : cfg1;
331
+ else
332
+ cfg = (bus > S10_RP_SECONDARY(pcie)) ? cfg0 : cfg1;
333
+
334
+ headers[0] = TLP_CFG_DW0(pcie, cfg);
335
+ headers[1] = TLP_CFG_DW1(pcie, tag, byte_en);
336
+ headers[2] = TLP_CFG_DW2(bus, devfn, where);
337
+}
338
+
213339 static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
214340 int where, u8 byte_en, u32 *value)
215341 {
216342 u32 headers[TLP_HDR_SIZE];
217343
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);
344
+ get_tlp_header(pcie, bus, devfn, where, byte_en, true,
345
+ headers);
221346
222
- tlp_write_packet(pcie, headers, 0, false);
347
+ pcie->pcie_data->ops->tlp_write_pkt(pcie, headers, 0, false);
223348
224
- return tlp_read_packet(pcie, value);
349
+ return pcie->pcie_data->ops->tlp_read_pkt(pcie, value);
225350 }
226351
227352 static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
....@@ -230,17 +355,18 @@
230355 u32 headers[TLP_HDR_SIZE];
231356 int ret;
232357
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);
358
+ get_tlp_header(pcie, bus, devfn, where, byte_en, false,
359
+ headers);
236360
237361 /* check alignment to Qword */
238362 if ((where & 0x7) == 0)
239
- tlp_write_packet(pcie, headers, value, true);
363
+ pcie->pcie_data->ops->tlp_write_pkt(pcie, headers,
364
+ value, true);
240365 else
241
- tlp_write_packet(pcie, headers, value, false);
366
+ pcie->pcie_data->ops->tlp_write_pkt(pcie, headers,
367
+ value, false);
242368
243
- ret = tlp_read_packet(pcie, NULL);
369
+ ret = pcie->pcie_data->ops->tlp_read_pkt(pcie, NULL);
244370 if (ret != PCIBIOS_SUCCESSFUL)
245371 return ret;
246372
....@@ -254,6 +380,53 @@
254380 return PCIBIOS_SUCCESSFUL;
255381 }
256382
383
+static int s10_rp_read_cfg(struct altera_pcie *pcie, int where,
384
+ int size, u32 *value)
385
+{
386
+ void __iomem *addr = S10_RP_CFG_ADDR(pcie, where);
387
+
388
+ switch (size) {
389
+ case 1:
390
+ *value = readb(addr);
391
+ break;
392
+ case 2:
393
+ *value = readw(addr);
394
+ break;
395
+ default:
396
+ *value = readl(addr);
397
+ break;
398
+ }
399
+
400
+ return PCIBIOS_SUCCESSFUL;
401
+}
402
+
403
+static int s10_rp_write_cfg(struct altera_pcie *pcie, u8 busno,
404
+ int where, int size, u32 value)
405
+{
406
+ void __iomem *addr = S10_RP_CFG_ADDR(pcie, where);
407
+
408
+ switch (size) {
409
+ case 1:
410
+ writeb(value, addr);
411
+ break;
412
+ case 2:
413
+ writew(value, addr);
414
+ break;
415
+ default:
416
+ writel(value, addr);
417
+ break;
418
+ }
419
+
420
+ /*
421
+ * Monitor changes to PCI_PRIMARY_BUS register on root port
422
+ * and update local copy of root bus number accordingly.
423
+ */
424
+ if (busno == pcie->root_bus_nr && where == PCI_PRIMARY_BUS)
425
+ pcie->root_bus_nr = value & 0xff;
426
+
427
+ return PCIBIOS_SUCCESSFUL;
428
+}
429
+
257430 static int _altera_pcie_cfg_read(struct altera_pcie *pcie, u8 busno,
258431 unsigned int devfn, int where, int size,
259432 u32 *value)
....@@ -261,6 +434,10 @@
261434 int ret;
262435 u32 data;
263436 u8 byte_en;
437
+
438
+ if (busno == pcie->root_bus_nr && pcie->pcie_data->ops->rp_read_cfg)
439
+ return pcie->pcie_data->ops->rp_read_cfg(pcie, where,
440
+ size, value);
264441
265442 switch (size) {
266443 case 1:
....@@ -301,6 +478,10 @@
301478 u32 data32;
302479 u32 shift = 8 * (where & 3);
303480 u8 byte_en;
481
+
482
+ if (busno == pcie->root_bus_nr && pcie->pcie_data->ops->rp_write_cfg)
483
+ return pcie->pcie_data->ops->rp_write_cfg(pcie, busno,
484
+ where, size, value);
304485
305486 switch (size) {
306487 case 1:
....@@ -365,7 +546,8 @@
365546 int ret;
366547
367548 ret = _altera_pcie_cfg_read(pcie, busno, devfn,
368
- PCIE_CAP_OFFSET + offset, sizeof(*value),
549
+ pcie->pcie_data->cap_offset + offset,
550
+ sizeof(*value),
369551 &data);
370552 *value = data;
371553 return ret;
....@@ -375,7 +557,8 @@
375557 unsigned int devfn, int offset, u16 value)
376558 {
377559 return _altera_pcie_cfg_write(pcie, busno, devfn,
378
- PCIE_CAP_OFFSET + offset, sizeof(value),
560
+ pcie->pcie_data->cap_offset + offset,
561
+ sizeof(value),
379562 value);
380563 }
381564
....@@ -403,7 +586,7 @@
403586 /* Wait for link is up */
404587 start_jiffies = jiffies;
405588 for (;;) {
406
- if (altera_pcie_link_up(pcie))
589
+ if (pcie->pcie_data->ops->get_link_status(pcie))
407590 break;
408591
409592 if (time_after(jiffies, start_jiffies + LINK_UP_TIMEOUT)) {
....@@ -418,7 +601,7 @@
418601 {
419602 u16 linkcap, linkstat, linkctl;
420603
421
- if (!altera_pcie_link_up(pcie))
604
+ if (!pcie->pcie_data->ops->get_link_status(pcie))
422605 return;
423606
424607 /*
....@@ -486,39 +669,6 @@
486669 chained_irq_exit(chip, desc);
487670 }
488671
489
-static 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
-
517
-out_release_res:
518
- pci_free_resource_list(&pcie->resources);
519
- return err;
520
-}
521
-
522672 static int altera_pcie_init_irq_domain(struct altera_pcie *pcie)
523673 {
524674 struct device *dev = &pcie->pdev->dev;
....@@ -535,23 +685,32 @@
535685 return 0;
536686 }
537687
688
+static void altera_pcie_irq_teardown(struct altera_pcie *pcie)
689
+{
690
+ irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
691
+ irq_domain_remove(pcie->irq_domain);
692
+ irq_dispose_mapping(pcie->irq);
693
+}
694
+
538695 static int altera_pcie_parse_dt(struct altera_pcie *pcie)
539696 {
540
- struct device *dev = &pcie->pdev->dev;
541697 struct platform_device *pdev = pcie->pdev;
542
- struct resource *cra;
543698
544
- cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra");
545
- pcie->cra_base = devm_ioremap_resource(dev, cra);
699
+ pcie->cra_base = devm_platform_ioremap_resource_byname(pdev, "Cra");
546700 if (IS_ERR(pcie->cra_base))
547701 return PTR_ERR(pcie->cra_base);
548702
703
+ if (pcie->pcie_data->version == ALTERA_PCIE_V2) {
704
+ pcie->hip_base =
705
+ devm_platform_ioremap_resource_byname(pdev, "Hip");
706
+ if (IS_ERR(pcie->hip_base))
707
+ return PTR_ERR(pcie->hip_base);
708
+ }
709
+
549710 /* setup IRQ */
550711 pcie->irq = platform_get_irq(pdev, 0);
551
- if (pcie->irq < 0) {
552
- dev_err(dev, "failed to get IRQ: %d\n", pcie->irq);
712
+ if (pcie->irq < 0)
553713 return pcie->irq;
554
- }
555714
556715 irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie);
557716 return 0;
....@@ -562,14 +721,55 @@
562721 altera_pcie_retrain(pcie);
563722 }
564723
724
+static const struct altera_pcie_ops altera_pcie_ops_1_0 = {
725
+ .tlp_read_pkt = tlp_read_packet,
726
+ .tlp_write_pkt = tlp_write_packet,
727
+ .get_link_status = altera_pcie_link_up,
728
+};
729
+
730
+static const struct altera_pcie_ops altera_pcie_ops_2_0 = {
731
+ .tlp_read_pkt = s10_tlp_read_packet,
732
+ .tlp_write_pkt = s10_tlp_write_packet,
733
+ .get_link_status = s10_altera_pcie_link_up,
734
+ .rp_read_cfg = s10_rp_read_cfg,
735
+ .rp_write_cfg = s10_rp_write_cfg,
736
+};
737
+
738
+static const struct altera_pcie_data altera_pcie_1_0_data = {
739
+ .ops = &altera_pcie_ops_1_0,
740
+ .cap_offset = 0x80,
741
+ .version = ALTERA_PCIE_V1,
742
+ .cfgrd0 = TLP_FMTTYPE_CFGRD0,
743
+ .cfgrd1 = TLP_FMTTYPE_CFGRD1,
744
+ .cfgwr0 = TLP_FMTTYPE_CFGWR0,
745
+ .cfgwr1 = TLP_FMTTYPE_CFGWR1,
746
+};
747
+
748
+static const struct altera_pcie_data altera_pcie_2_0_data = {
749
+ .ops = &altera_pcie_ops_2_0,
750
+ .version = ALTERA_PCIE_V2,
751
+ .cap_offset = 0x70,
752
+ .cfgrd0 = S10_TLP_FMTTYPE_CFGRD0,
753
+ .cfgrd1 = S10_TLP_FMTTYPE_CFGRD1,
754
+ .cfgwr0 = S10_TLP_FMTTYPE_CFGWR0,
755
+ .cfgwr1 = S10_TLP_FMTTYPE_CFGWR1,
756
+};
757
+
758
+static const struct of_device_id altera_pcie_of_match[] = {
759
+ {.compatible = "altr,pcie-root-port-1.0",
760
+ .data = &altera_pcie_1_0_data },
761
+ {.compatible = "altr,pcie-root-port-2.0",
762
+ .data = &altera_pcie_2_0_data },
763
+ {},
764
+};
765
+
565766 static int altera_pcie_probe(struct platform_device *pdev)
566767 {
567768 struct device *dev = &pdev->dev;
568769 struct altera_pcie *pcie;
569
- struct pci_bus *bus;
570
- struct pci_bus *child;
571770 struct pci_host_bridge *bridge;
572771 int ret;
772
+ const struct of_device_id *match;
573773
574774 bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
575775 if (!bridge)
....@@ -577,18 +777,17 @@
577777
578778 pcie = pci_host_bridge_priv(bridge);
579779 pcie->pdev = pdev;
780
+ platform_set_drvdata(pdev, pcie);
781
+
782
+ match = of_match_device(altera_pcie_of_match, &pdev->dev);
783
+ if (!match)
784
+ return -ENODEV;
785
+
786
+ pcie->pcie_data = match->data;
580787
581788 ret = altera_pcie_parse_dt(pcie);
582789 if (ret) {
583790 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");
592791 return ret;
593792 }
594793
....@@ -604,42 +803,34 @@
604803 cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE);
605804 altera_pcie_host_init(pcie);
606805
607
- list_splice_init(&pcie->resources, &bridge->windows);
608
- bridge->dev.parent = dev;
609806 bridge->sysdata = pcie;
610807 bridge->busnr = pcie->root_bus_nr;
611808 bridge->ops = &altera_pcie_ops;
612
- bridge->map_irq = of_irq_parse_and_map_pci;
613
- bridge->swizzle_irq = pci_common_swizzle;
614809
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;
810
+ return pci_host_probe(bridge);
629811 }
630812
631
-static const struct of_device_id altera_pcie_of_match[] = {
632
- { .compatible = "altr,pcie-root-port-1.0", },
633
- {},
634
-};
813
+static int altera_pcie_remove(struct platform_device *pdev)
814
+{
815
+ struct altera_pcie *pcie = platform_get_drvdata(pdev);
816
+ struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
817
+
818
+ pci_stop_root_bus(bridge->bus);
819
+ pci_remove_root_bus(bridge->bus);
820
+ altera_pcie_irq_teardown(pcie);
821
+
822
+ return 0;
823
+}
635824
636825 static struct platform_driver altera_pcie_driver = {
637826 .probe = altera_pcie_probe,
827
+ .remove = altera_pcie_remove,
638828 .driver = {
639829 .name = "altera-pcie",
640830 .of_match_table = altera_pcie_of_match,
641
- .suppress_bind_attrs = true,
642831 },
643832 };
644833
645
-builtin_platform_driver(altera_pcie_driver);
834
+MODULE_DEVICE_TABLE(of, altera_pcie_of_match);
835
+module_platform_driver(altera_pcie_driver);
836
+MODULE_LICENSE("GPL v2");