> -----Original Message----- > From: Lucas Stach [mailto:l.stach@xxxxxxxxxxxxxx] > Sent: Thursday, May 11, 2017 1:58 AM > To: linux-pci@xxxxxxxxxxxxxxx > Cc: Peter Senna Tschudin <peter.senna@xxxxxxxxxxxxx>; Richard Zhu > <hongxing.zhu@xxxxxxx>; festevam@xxxxxxxxx; bhelgaas@xxxxxxxxxx; > tharvey@xxxxxxxxxxxxx; lorenzo.pieralisi@xxxxxxx; linux-arm- > kernel@xxxxxxxxxxxxxxxxxxx; kernel@xxxxxxxxxxxxxx; patchwork- > lst@xxxxxxxxxxxxxx > Subject: [PATCH] PCI: imx6: fix downstream bus scanning > > The change in Linux 4.12 to make PCI configuartion requests non-posted > means that we are now getting 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. > > Signed-off-by: Lucas Stach <l.stach@xxxxxxxxxxxxxx> Thanks lot for your great help at first. Only one little spell comment, "configuartion" in the commit message should be "configuration", the others are okay. Acked-by: Richard Zhu <hongxing.zhu@xxxxxxx> > --- > This is a fix that needs to go in for 4.12, but I would hope to get some > thorough testing before. > --- > drivers/pci/dwc/pci-imx6.c | 33 ++++++++++++++++++++++++++++++--- > 1 file changed, 30 insertions(+), 3 deletions(-) > > diff --git a/drivers/pci/dwc/pci-imx6.c b/drivers/pci/dwc/pci-imx6.c index > a98cba55c7f0..19a289b8cc94 100644 > --- a/drivers/pci/dwc/pci-imx6.c > +++ b/drivers/pci/dwc/pci-imx6.c > @@ -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) @@ - > 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); > } > -- > 2.11.0