All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] PCI: imx6: fix downstream bus scanning
@ 2017-05-10 17:57 ` Lucas Stach
  0 siblings, 0 replies; 18+ messages in thread
From: Lucas Stach @ 2017-05-10 17:57 UTC (permalink / raw)
  To: linux-pci
  Cc: lorenzo.pieralisi, hongxing.zhu, tharvey, patchwork-lst,
	Peter Senna Tschudin, kernel, bhelgaas, festevam,
	linux-arm-kernel

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@pengutronix.de>
---
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


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2017-05-24 17:16 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-10 17:57 [PATCH] PCI: imx6: fix downstream bus scanning Lucas Stach
2017-05-10 17:57 ` Lucas Stach
2017-05-10 18:35 ` Fabio Estevam
2017-05-10 18:35   ` Fabio Estevam
2017-05-10 19:04   ` Fabio Estevam
2017-05-10 19:04     ` Fabio Estevam
2017-05-10 19:51 ` Peter Senna Tschudin
2017-05-10 19:51   ` Peter Senna Tschudin
2017-05-11  2:00 ` Richard Zhu
2017-05-11  2:00   ` Richard Zhu
2017-05-22 22:13 ` Bjorn Helgaas
2017-05-22 22:13   ` Bjorn Helgaas
2017-05-23  9:07   ` Lorenzo Pieralisi
2017-05-23  9:07     ` Lorenzo Pieralisi
2017-05-23 22:11   ` Fabio Estevam
2017-05-23 22:11     ` Fabio Estevam
2017-05-24 17:16     ` Bjorn Helgaas
2017-05-24 17:16       ` Bjorn Helgaas

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.