Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

BUS: brcmstb_gisb: Hook to MIPS board_be_handler

MIPS kernels allow platforms to invoke a custom Bus Error handler, add the
necessary code to do this for Broadcom SoCs where the GISB bus error handler can be used.

We may get a bus error from an address decoded outside of the GISB bus space,
so we need to check the validity of such a capture before printing anything.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Cc: cernekee@gmail.com
Cc: arnd@arndb.de
Cc: jaedon.shin@gmail.com
Cc: pgynther@google.com
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/12284/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Florian Fainelli and committed by
Ralf Baechle
c400d5eb 885872b7

+30
+30
drivers/bus/brcmstb_gisb.c
··· 30 30 #include <asm/signal.h> 31 31 #endif 32 32 33 + #ifdef CONFIG_MIPS 34 + #include <asm/traps.h> 35 + #endif 36 + 33 37 #define ARB_ERR_CAP_CLEAR (1 << 0) 34 38 #define ARB_ERR_CAP_STATUS_TIMEOUT (1 << 12) 35 39 #define ARB_ERR_CAP_STATUS_TEA (1 << 11) ··· 242 238 } 243 239 #endif 244 240 241 + #ifdef CONFIG_MIPS 242 + static int brcmstb_bus_error_handler(struct pt_regs *regs, int is_fixup) 243 + { 244 + int ret = 0; 245 + struct brcmstb_gisb_arb_device *gdev; 246 + u32 cap_status; 247 + 248 + list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next) { 249 + cap_status = gisb_read(gdev, ARB_ERR_CAP_STATUS); 250 + 251 + /* Invalid captured address, bail out */ 252 + if (!(cap_status & ARB_ERR_CAP_STATUS_VALID)) { 253 + is_fixup = 1; 254 + goto out; 255 + } 256 + 257 + ret |= brcmstb_gisb_arb_decode_addr(gdev, "bus error"); 258 + } 259 + out: 260 + return is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL; 261 + } 262 + #endif 263 + 245 264 static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id) 246 265 { 247 266 brcmstb_gisb_arb_decode_addr(dev_id, "timeout"); ··· 381 354 #ifdef CONFIG_ARM 382 355 hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0, 383 356 "imprecise external abort"); 357 + #endif 358 + #ifdef CONFIG_MIPS 359 + board_be_handler = brcmstb_bus_error_handler; 384 360 #endif 385 361 386 362 dev_info(&pdev->dev, "registered mem: %p, irqs: %d, %d\n",