Skip to content

Commit

Permalink
PCI: imx6: Fix config read timeout handling
Browse files Browse the repository at this point in the history
Commit cc7b0d4 ("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: cc7b0d4 ("PCI: designware: Update PCI config space remap function")
Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
Tested-by: Peter Senna Tschudin <peter.senna@collabora.com>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Richard Zhu <hongxing.zhu@nxp.com>
  • Loading branch information
Lucas Stach authored and Bjorn Helgaas committed May 22, 2017
1 parent 9871e9b commit 415b618
Showing 1 changed file with 30 additions and 3 deletions.
33 changes: 30 additions & 3 deletions drivers/pci/dwc/pci-imx6.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,34 @@ static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie)
static int imx6q_pcie_abort_handler(unsigned long addr,
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)
Expand Down Expand Up @@ -819,8 +846,8 @@ static int __init imx6_pcie_init(void)
* we can install the handler here without risking it
* accessing some uninitialized driver state.
*/
hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0,
"imprecise external abort");
hook_fault_code(8, imx6q_pcie_abort_handler, SIGBUS, 0,
"external abort on non-linefetch");

return platform_driver_register(&imx6_pcie_driver);
}
Expand Down

0 comments on commit 415b618

Please sign in to comment.