Skip to content

Commit 5606b7b

Browse files
committed
Merge branch 'pci/controller/keystone'
- Fail the probe instead of silently succeeding if ks_pcie_of_data didn't specify Root Complex or Endpoint mode (Siddharth Vadapalli) - Make keystone buildable as a loadable module, except on ARM32 where hook_fault_code() is __init (Siddharth Vadapalli) * pci/controller/keystone: PCI: keystone: Add support to build as a loadable module PCI: dwc: Export dw_pcie_allocate_domains() and dw_pcie_ep_raise_msix_irq() PCI: Export pci_get_host_bridge_device() for use by pci-keystone PCI: keystone: Exit ks_pcie_probe() for invalid mode
2 parents 51f8276 + bc10d0a commit 5606b7b

7 files changed

Lines changed: 65 additions & 37 deletions

File tree

drivers/pci/controller/dwc/Kconfig

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -482,27 +482,34 @@ config PCI_DRA7XX_EP
482482
to enable device-specific features PCI_DRA7XX_EP must be selected.
483483
This uses the DesignWare core.
484484

485+
# ARM32 platforms use hook_fault_code() and cannot support loadable module.
485486
config PCI_KEYSTONE
486487
bool
487488

489+
# On non-ARM32 platforms, loadable module can be supported.
490+
config PCI_KEYSTONE_TRISTATE
491+
tristate
492+
488493
config PCI_KEYSTONE_HOST
489-
bool "TI Keystone PCIe controller (host mode)"
494+
tristate "TI Keystone PCIe controller (host mode)"
490495
depends on ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
491496
depends on PCI_MSI
492497
select PCIE_DW_HOST
493-
select PCI_KEYSTONE
498+
select PCI_KEYSTONE if ARM
499+
select PCI_KEYSTONE_TRISTATE if !ARM
494500
help
495501
Enables support for the PCIe controller in the Keystone SoC to
496502
work in host mode. The PCI controller on Keystone is based on
497503
DesignWare hardware and therefore the driver re-uses the
498504
DesignWare core functions to implement the driver.
499505

500506
config PCI_KEYSTONE_EP
501-
bool "TI Keystone PCIe controller (endpoint mode)"
507+
tristate "TI Keystone PCIe controller (endpoint mode)"
502508
depends on ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
503509
depends on PCI_ENDPOINT
504510
select PCIE_DW_EP
505-
select PCI_KEYSTONE
511+
select PCI_KEYSTONE if ARM
512+
select PCI_KEYSTONE_TRISTATE if !ARM
506513
help
507514
Enables support for the PCIe controller in the Keystone SoC to
508515
work in endpoint mode. The PCI controller on Keystone is based

drivers/pci/controller/dwc/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
1111
obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
1212
obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
1313
obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
14+
# ARM32 platforms use hook_fault_code() and cannot support loadable module.
1415
obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o
16+
# On non-ARM32 platforms, loadable module can be supported.
17+
obj-$(CONFIG_PCI_KEYSTONE_TRISTATE) += pci-keystone.o
1518
obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
1619
obj-$(CONFIG_PCI_LAYERSCAPE_EP) += pci-layerscape-ep.o
1720
obj-$(CONFIG_PCIE_QCOM_COMMON) += pcie-qcom-common.o

drivers/pci/controller/dwc/pci-keystone.c

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/irqchip/chained_irq.h>
1818
#include <linux/irqdomain.h>
1919
#include <linux/mfd/syscon.h>
20+
#include <linux/module.h>
2021
#include <linux/msi.h>
2122
#include <linux/of.h>
2223
#include <linux/of_irq.h>
@@ -777,29 +778,7 @@ static int ks_pcie_config_intx_irq(struct keystone_pcie *ks_pcie)
777778
return ret;
778779
}
779780

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)
803782
{
804783
int ret;
805784
unsigned int id;
@@ -831,7 +810,7 @@ static int __init ks_pcie_init_id(struct keystone_pcie *ks_pcie)
831810
return 0;
832811
}
833812

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)
835814
{
836815
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
837816
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)
861840
if (ret < 0)
862841
return ret;
863842

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-
873843
return 0;
874844
}
875845

@@ -1134,6 +1104,7 @@ static const struct of_device_id ks_pcie_of_match[] = {
11341104
},
11351105
{ },
11361106
};
1107+
MODULE_DEVICE_TABLE(of, ks_pcie_of_match);
11371108

11381109
static int ks_pcie_probe(struct platform_device *pdev)
11391110
{
@@ -1337,6 +1308,8 @@ static int ks_pcie_probe(struct platform_device *pdev)
13371308
break;
13381309
default:
13391310
dev_err(dev, "INVALID device type %d\n", mode);
1311+
ret = -EINVAL;
1312+
goto err_get_sync;
13401313
}
13411314

13421315
ks_pcie_enable_error_irq(ks_pcie);
@@ -1379,4 +1352,45 @@ static struct platform_driver ks_pcie_driver = {
13791352
.of_match_table = ks_pcie_of_match,
13801353
},
13811354
};
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
13821391
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>");

drivers/pci/controller/dwc/pcie-designware-ep.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
797797

798798
return 0;
799799
}
800+
EXPORT_SYMBOL_GPL(dw_pcie_ep_raise_msix_irq);
800801

801802
/**
802803
* dw_pcie_ep_cleanup - Cleanup DWC EP resources after fundamental reset

drivers/pci/controller/dwc/pcie-designware-host.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ int dw_pcie_allocate_domains(struct dw_pcie_rp *pp)
232232

233233
return 0;
234234
}
235+
EXPORT_SYMBOL_GPL(dw_pcie_allocate_domains);
235236

236237
void dw_pcie_free_msi(struct dw_pcie_rp *pp)
237238
{

drivers/pci/host-bridge.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct device *pci_get_host_bridge_device(struct pci_dev *dev)
3333
kobject_get(&bridge->kobj);
3434
return bridge;
3535
}
36+
EXPORT_SYMBOL_GPL(pci_get_host_bridge_device);
3637

3738
void pci_put_host_bridge_device(struct device *dev)
3839
{

include/linux/pci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,7 @@ struct pci_host_bridge *pci_alloc_host_bridge(size_t priv);
648648
struct pci_host_bridge *devm_pci_alloc_host_bridge(struct device *dev,
649649
size_t priv);
650650
void pci_free_host_bridge(struct pci_host_bridge *bridge);
651+
struct device *pci_get_host_bridge_device(struct pci_dev *dev);
651652
struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus);
652653

653654
void pci_set_host_bridge_release(struct pci_host_bridge *bridge,

0 commit comments

Comments
 (0)