15
15
#include <linux/irqdomain.h>
16
16
#include <linux/kernel.h>
17
17
#include <linux/msi.h>
18
+ #include <linux/module.h>
18
19
#include <linux/of_address.h>
19
20
#include <linux/of_pci.h>
20
21
#include <linux/of_platform.h>
@@ -162,6 +163,7 @@ struct mtk_pcie_soc {
162
163
* @phy: pointer to PHY control block
163
164
* @lane: lane count
164
165
* @slot: port slot
166
+ * @irq: GIC irq
165
167
* @irq_domain: legacy INTx IRQ domain
166
168
* @inner_domain: inner IRQ domain
167
169
* @msi_domain: MSI IRQ domain
@@ -182,6 +184,7 @@ struct mtk_pcie_port {
182
184
struct phy * phy ;
183
185
u32 lane ;
184
186
u32 slot ;
187
+ int irq ;
185
188
struct irq_domain * irq_domain ;
186
189
struct irq_domain * inner_domain ;
187
190
struct irq_domain * msi_domain ;
@@ -530,6 +533,27 @@ static void mtk_pcie_enable_msi(struct mtk_pcie_port *port)
530
533
writel (val , port -> base + PCIE_INT_MASK );
531
534
}
532
535
536
+ static void mtk_pcie_irq_teardown (struct mtk_pcie * pcie )
537
+ {
538
+ struct mtk_pcie_port * port , * tmp ;
539
+
540
+ list_for_each_entry_safe (port , tmp , & pcie -> ports , list ) {
541
+ irq_set_chained_handler_and_data (port -> irq , NULL , NULL );
542
+
543
+ if (port -> irq_domain )
544
+ irq_domain_remove (port -> irq_domain );
545
+
546
+ if (IS_ENABLED (CONFIG_PCI_MSI )) {
547
+ if (port -> msi_domain )
548
+ irq_domain_remove (port -> msi_domain );
549
+ if (port -> inner_domain )
550
+ irq_domain_remove (port -> inner_domain );
551
+ }
552
+
553
+ irq_dispose_mapping (port -> irq );
554
+ }
555
+ }
556
+
533
557
static int mtk_pcie_intx_map (struct irq_domain * domain , unsigned int irq ,
534
558
irq_hw_number_t hwirq )
535
559
{
@@ -620,16 +644,17 @@ static int mtk_pcie_setup_irq(struct mtk_pcie_port *port,
620
644
struct mtk_pcie * pcie = port -> pcie ;
621
645
struct device * dev = pcie -> dev ;
622
646
struct platform_device * pdev = to_platform_device (dev );
623
- int err , irq ;
647
+ int err ;
624
648
625
649
err = mtk_pcie_init_irq_domain (port , node );
626
650
if (err ) {
627
651
dev_err (dev , "failed to init PCIe IRQ domain\n" );
628
652
return err ;
629
653
}
630
654
631
- irq = platform_get_irq (pdev , port -> slot );
632
- irq_set_chained_handler_and_data (irq , mtk_pcie_intr_handler , port );
655
+ port -> irq = platform_get_irq (pdev , port -> slot );
656
+ irq_set_chained_handler_and_data (port -> irq ,
657
+ mtk_pcie_intr_handler , port );
633
658
634
659
return 0 ;
635
660
}
@@ -1168,6 +1193,31 @@ static int mtk_pcie_probe(struct platform_device *pdev)
1168
1193
return err ;
1169
1194
}
1170
1195
1196
+
1197
+ static void mtk_pcie_free_resources (struct mtk_pcie * pcie )
1198
+ {
1199
+ struct pci_host_bridge * host = pci_host_bridge_from_priv (pcie );
1200
+ struct list_head * windows = & host -> windows ;
1201
+
1202
+ pci_free_resource_list (windows );
1203
+ }
1204
+
1205
+ static int mtk_pcie_remove (struct platform_device * pdev )
1206
+ {
1207
+ struct mtk_pcie * pcie = platform_get_drvdata (pdev );
1208
+ struct pci_host_bridge * host = pci_host_bridge_from_priv (pcie );
1209
+
1210
+ pci_stop_root_bus (host -> bus );
1211
+ pci_remove_root_bus (host -> bus );
1212
+ mtk_pcie_free_resources (pcie );
1213
+
1214
+ mtk_pcie_irq_teardown (pcie );
1215
+
1216
+ mtk_pcie_put_resources (pcie );
1217
+
1218
+ return 0 ;
1219
+ }
1220
+
1171
1221
static int __maybe_unused mtk_pcie_suspend_noirq (struct device * dev )
1172
1222
{
1173
1223
struct mtk_pcie * pcie = dev_get_drvdata (dev );
@@ -1245,11 +1295,13 @@ static const struct of_device_id mtk_pcie_ids[] = {
1245
1295
1246
1296
static struct platform_driver mtk_pcie_driver = {
1247
1297
.probe = mtk_pcie_probe ,
1298
+ .remove = mtk_pcie_remove ,
1248
1299
.driver = {
1249
1300
.name = "mtk-pcie" ,
1250
1301
.of_match_table = mtk_pcie_ids ,
1251
1302
.suppress_bind_attrs = true,
1252
1303
.pm = & mtk_pcie_pm_ops ,
1253
1304
},
1254
1305
};
1255
- builtin_platform_driver (mtk_pcie_driver );
1306
+ module_platform_driver (mtk_pcie_driver );
1307
+ MODULE_LICENSE ("GPL v2" );
0 commit comments