Commit 415b6185 authored by Lucas Stach's avatar Lucas Stach Committed by Bjorn Helgaas

PCI: imx6: Fix config read timeout handling

Commit cc7b0d49 ("PCI: designware: Update PCI config space remap
function") made PCI configuration requests non-posted, which means we now
get a synchronous abort when the CFG space read to probe for downstream
devices times out.

Synchronous aborts need to be handled differently from the async aborts we
were getting before, in particular the PC needs to be advanced when
resolving the abort.  This is mostly a copy of what other PCI drivers do on
ARM to handle those aborts.

[bhelgaas: changelog, "Fixes"]
Fixes: cc7b0d49 ("PCI: designware: Update PCI config space remap function")
Tested-by: default avatarFabio Estevam <fabio.estevam@nxp.com>
Tested-by: default avatarPeter Senna Tschudin <peter.senna@collabora.com>
Signed-off-by: default avatarLucas Stach <l.stach@pengutronix.de>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Acked-by: default avatarRichard Zhu <hongxing.zhu@nxp.com>
parent 9871e9bb
...@@ -252,7 +252,34 @@ static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie) ...@@ -252,7 +252,34 @@ static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie)
static int imx6q_pcie_abort_handler(unsigned long addr, static int imx6q_pcie_abort_handler(unsigned long addr,
unsigned int fsr, struct pt_regs *regs) unsigned int fsr, struct pt_regs *regs)
{ {
return 0; unsigned long pc = instruction_pointer(regs);
unsigned long instr = *(unsigned long *)pc;
int reg = (instr >> 12) & 15;
/*
* If the instruction being executed was a read,
* make it look like it read all-ones.
*/
if ((instr & 0x0c100000) == 0x04100000) {
unsigned long val;
if (instr & 0x00400000)
val = 255;
else
val = -1;
regs->uregs[reg] = val;
regs->ARM_pc += 4;
return 0;
}
if ((instr & 0x0e100090) == 0x00100090) {
regs->uregs[reg] = -1;
regs->ARM_pc += 4;
return 0;
}
return 1;
} }
static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
...@@ -819,8 +846,8 @@ static int __init imx6_pcie_init(void) ...@@ -819,8 +846,8 @@ static int __init imx6_pcie_init(void)
* we can install the handler here without risking it * we can install the handler here without risking it
* accessing some uninitialized driver state. * accessing some uninitialized driver state.
*/ */
hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0, hook_fault_code(8, imx6q_pcie_abort_handler, SIGBUS, 0,
"imprecise external abort"); "external abort on non-linefetch");
return platform_driver_register(&imx6_pcie_driver); return platform_driver_register(&imx6_pcie_driver);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment