|
17 | 17 | #include <linux/irqchip/chained_irq.h> |
18 | 18 | #include <linux/irqdomain.h> |
19 | 19 | #include <linux/mfd/syscon.h> |
| 20 | +#include <linux/module.h> |
20 | 21 | #include <linux/msi.h> |
21 | 22 | #include <linux/of.h> |
22 | 23 | #include <linux/of_irq.h> |
@@ -777,29 +778,7 @@ static int ks_pcie_config_intx_irq(struct keystone_pcie *ks_pcie) |
777 | 778 | return ret; |
778 | 779 | } |
779 | 780 |
|
780 | | -#ifdef CONFIG_ARM |
781 | | -/* |
782 | | - * When a PCI device does not exist during config cycles, keystone host |
783 | | - * gets a bus error instead of returning 0xffffffff (PCI_ERROR_RESPONSE). |
784 | | - * This handler always returns 0 for this kind of fault. |
785 | | - */ |
786 | | -static int ks_pcie_fault(unsigned long addr, unsigned int fsr, |
787 | | - struct pt_regs *regs) |
788 | | -{ |
789 | | - unsigned long instr = *(unsigned long *) instruction_pointer(regs); |
790 | | - |
791 | | - if ((instr & 0x0e100090) == 0x00100090) { |
792 | | - int reg = (instr >> 12) & 15; |
793 | | - |
794 | | - regs->uregs[reg] = -1; |
795 | | - regs->ARM_pc += 4; |
796 | | - } |
797 | | - |
798 | | - return 0; |
799 | | -} |
800 | | -#endif |
801 | | - |
802 | | -static int __init ks_pcie_init_id(struct keystone_pcie *ks_pcie) |
| 781 | +static int ks_pcie_init_id(struct keystone_pcie *ks_pcie) |
803 | 782 | { |
804 | 783 | int ret; |
805 | 784 | unsigned int id; |
@@ -831,7 +810,7 @@ static int __init ks_pcie_init_id(struct keystone_pcie *ks_pcie) |
831 | 810 | return 0; |
832 | 811 | } |
833 | 812 |
|
834 | | -static int __init ks_pcie_host_init(struct dw_pcie_rp *pp) |
| 813 | +static int ks_pcie_host_init(struct dw_pcie_rp *pp) |
835 | 814 | { |
836 | 815 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
837 | 816 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); |
@@ -861,15 +840,6 @@ static int __init ks_pcie_host_init(struct dw_pcie_rp *pp) |
861 | 840 | if (ret < 0) |
862 | 841 | return ret; |
863 | 842 |
|
864 | | -#ifdef CONFIG_ARM |
865 | | - /* |
866 | | - * PCIe access errors that result into OCP errors are caught by ARM as |
867 | | - * "External aborts" |
868 | | - */ |
869 | | - hook_fault_code(17, ks_pcie_fault, SIGBUS, 0, |
870 | | - "Asynchronous external abort"); |
871 | | -#endif |
872 | | - |
873 | 843 | return 0; |
874 | 844 | } |
875 | 845 |
|
@@ -1134,6 +1104,7 @@ static const struct of_device_id ks_pcie_of_match[] = { |
1134 | 1104 | }, |
1135 | 1105 | { }, |
1136 | 1106 | }; |
| 1107 | +MODULE_DEVICE_TABLE(of, ks_pcie_of_match); |
1137 | 1108 |
|
1138 | 1109 | static int ks_pcie_probe(struct platform_device *pdev) |
1139 | 1110 | { |
@@ -1337,6 +1308,8 @@ static int ks_pcie_probe(struct platform_device *pdev) |
1337 | 1308 | break; |
1338 | 1309 | default: |
1339 | 1310 | dev_err(dev, "INVALID device type %d\n", mode); |
| 1311 | + ret = -EINVAL; |
| 1312 | + goto err_get_sync; |
1340 | 1313 | } |
1341 | 1314 |
|
1342 | 1315 | ks_pcie_enable_error_irq(ks_pcie); |
@@ -1379,4 +1352,45 @@ static struct platform_driver ks_pcie_driver = { |
1379 | 1352 | .of_match_table = ks_pcie_of_match, |
1380 | 1353 | }, |
1381 | 1354 | }; |
| 1355 | + |
| 1356 | +#ifdef CONFIG_ARM |
| 1357 | +/* |
| 1358 | + * When a PCI device does not exist during config cycles, keystone host |
| 1359 | + * gets a bus error instead of returning 0xffffffff (PCI_ERROR_RESPONSE). |
| 1360 | + * This handler always returns 0 for this kind of fault. |
| 1361 | + */ |
| 1362 | +static int ks_pcie_fault(unsigned long addr, unsigned int fsr, |
| 1363 | + struct pt_regs *regs) |
| 1364 | +{ |
| 1365 | + unsigned long instr = *(unsigned long *)instruction_pointer(regs); |
| 1366 | + |
| 1367 | + if ((instr & 0x0e100090) == 0x00100090) { |
| 1368 | + int reg = (instr >> 12) & 15; |
| 1369 | + |
| 1370 | + regs->uregs[reg] = -1; |
| 1371 | + regs->ARM_pc += 4; |
| 1372 | + } |
| 1373 | + |
| 1374 | + return 0; |
| 1375 | +} |
| 1376 | + |
| 1377 | +static int __init ks_pcie_init(void) |
| 1378 | +{ |
| 1379 | + /* |
| 1380 | + * PCIe access errors that result into OCP errors are caught by ARM as |
| 1381 | + * "External aborts" |
| 1382 | + */ |
| 1383 | + if (of_find_matching_node(NULL, ks_pcie_of_match)) |
| 1384 | + hook_fault_code(17, ks_pcie_fault, SIGBUS, 0, |
| 1385 | + "Asynchronous external abort"); |
| 1386 | + |
| 1387 | + return platform_driver_register(&ks_pcie_driver); |
| 1388 | +} |
| 1389 | +device_initcall(ks_pcie_init); |
| 1390 | +#else |
1382 | 1391 | builtin_platform_driver(ks_pcie_driver); |
| 1392 | +#endif |
| 1393 | + |
| 1394 | +MODULE_LICENSE("GPL"); |
| 1395 | +MODULE_DESCRIPTION("PCIe controller driver for Texas Instruments Keystone SoCs"); |
| 1396 | +MODULE_AUTHOR("Murali Karicheri <m-karicheri2@ti.com>"); |
0 commit comments