aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-4.19/950-0198-dwc-otg-FIQ-Fix-bad-mode-in-data-abort-handler.patch
diff options
context:
space:
mode:
authorAdrian Schmutzler <freifunk@adrianschmutzler.de>2020-02-08 21:58:55 +0100
committerAdrian Schmutzler <freifunk@adrianschmutzler.de>2020-02-14 14:10:51 +0100
commit7d7aa2fd924c27829ec25f825481554dd81bce97 (patch)
tree658b87b89331670266163e522ea5fb52535633cb /target/linux/bcm27xx/patches-4.19/950-0198-dwc-otg-FIQ-Fix-bad-mode-in-data-abort-handler.patch
parente7bfda2c243e66a75ff966ba04c28b1590b5d24c (diff)
downloadupstream-7d7aa2fd924c27829ec25f825481554dd81bce97.tar.gz
upstream-7d7aa2fd924c27829ec25f825481554dd81bce97.tar.bz2
upstream-7d7aa2fd924c27829ec25f825481554dd81bce97.zip
brcm2708: rename target to bcm27xx
This change makes the names of Broadcom targets consistent by using the common notation based on SoC/CPU ID (which is used internally anyway), bcmXXXX instead of brcmXXXX. This is even used for target TITLE in make menuconfig already, only the short target name used brcm so far. Despite, since subtargets range from bcm2708 to bcm2711, it seems appropriate to use bcm27xx instead of bcm2708 (again, as already done for BOARDNAME). This also renames the packages brcm2708-userland and brcm2708-gpu-fw. Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de> Acked-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx/patches-4.19/950-0198-dwc-otg-FIQ-Fix-bad-mode-in-data-abort-handler.patch')
-rw-r--r--target/linux/bcm27xx/patches-4.19/950-0198-dwc-otg-FIQ-Fix-bad-mode-in-data-abort-handler.patch128
1 files changed, 128 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-4.19/950-0198-dwc-otg-FIQ-Fix-bad-mode-in-data-abort-handler.patch b/target/linux/bcm27xx/patches-4.19/950-0198-dwc-otg-FIQ-Fix-bad-mode-in-data-abort-handler.patch
new file mode 100644
index 0000000000..51c7732beb
--- /dev/null
+++ b/target/linux/bcm27xx/patches-4.19/950-0198-dwc-otg-FIQ-Fix-bad-mode-in-data-abort-handler.patch
@@ -0,0 +1,128 @@
+From f36b3119d83e03c9d0c684b8712b66a979c48124 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 16 Jul 2018 14:40:13 +0100
+Subject: [PATCH] dwc-otg: FIQ: Fix "bad mode in data abort handler"
+
+Create a semi-static mapping for the USB registers early in the boot
+process, before additional kernel threads are started, so all threads
+will have the mappings from the start. This avoids the need for
+data aborts to lazily update them.
+
+See: https://github.com/raspberrypi/linux/issues/2450
+
+Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
+---
+ arch/arm/mach-bcm/board_bcm2835.c | 69 +++++++++++++++++++++++
+ drivers/usb/host/dwc_otg/dwc_otg_driver.c | 2 +-
+ 2 files changed, 70 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/mach-bcm/board_bcm2835.c
++++ b/arch/arm/mach-bcm/board_bcm2835.c
+@@ -15,6 +15,7 @@
+ #include <linux/init.h>
+ #include <linux/irqchip.h>
+ #include <linux/of_address.h>
++#include <linux/of_fdt.h>
+ #include <asm/system_info.h>
+
+ #include <asm/mach/arch.h>
+@@ -22,6 +23,9 @@
+
+ #include "platsmp.h"
+
++#define BCM2835_USB_VIRT_BASE 0xf0980000
++#define BCM2835_USB_VIRT_MPHI 0xf0006000
++
+ static void __init bcm2835_init(void)
+ {
+ struct device_node *np = of_find_node_by_path("/system");
+@@ -34,6 +38,70 @@ static void __init bcm2835_init(void)
+ system_serial_low = val64;
+ }
+
++/*
++ * We need to map registers that are going to be accessed by the FIQ
++ * very early, before any kernel threads are spawned. Because if done
++ * later, the mapping tables are not updated instantly but lazily upon
++ * first access through a data abort handler. While that is fine
++ * when executing regular kernel code, if the first access in a specific
++ * thread happens while running FIQ code this will result in a panic.
++ *
++ * For more background see the following old mailing list thread:
++ * https://www.spinics.net/lists/arm-kernel/msg325250.html
++ */
++static int __init bcm2835_map_usb(unsigned long node, const char *uname,
++ int depth, void *data)
++{
++ struct map_desc map[2];
++ const __be32 *reg;
++ int len;
++ unsigned long p2b_offset = *((unsigned long *) data);
++
++ if (!of_flat_dt_is_compatible(node, "brcm,bcm2708-usb"))
++ return 0;
++ reg = of_get_flat_dt_prop(node, "reg", &len);
++ if (!reg || len != (sizeof(unsigned long) * 4))
++ return 0;
++
++ /* Use information about the physical addresses of the
++ * registers from the device tree, but use legacy
++ * iotable_init() static mapping function to map them,
++ * as ioremap() is not functional at this stage in boot.
++ */
++ map[0].virtual = (unsigned long) BCM2835_USB_VIRT_BASE;
++ map[0].pfn = __phys_to_pfn(be32_to_cpu(reg[0]) - p2b_offset);
++ map[0].length = be32_to_cpu(reg[1]);
++ map[0].type = MT_DEVICE;
++ map[1].virtual = (unsigned long) BCM2835_USB_VIRT_MPHI;
++ map[1].pfn = __phys_to_pfn(be32_to_cpu(reg[2]) - p2b_offset);
++ map[1].length = be32_to_cpu(reg[3]);
++ map[1].type = MT_DEVICE;
++ iotable_init(map, 2);
++
++ return 1;
++}
++
++static void __init bcm2835_map_io(void)
++{
++ const __be32 *ranges;
++ int soc, len;
++ unsigned long p2b_offset;
++
++ debug_ll_io_init();
++
++ /* Find out how to map bus to physical address first from soc/ranges */
++ soc = of_get_flat_dt_subnode_by_name(of_get_flat_dt_root(), "soc");
++ if (soc < 0)
++ return;
++ ranges = of_get_flat_dt_prop(soc, "ranges", &len);
++ if (!ranges || len < (sizeof(unsigned long) * 3))
++ return;
++ p2b_offset = be32_to_cpu(ranges[0]) - be32_to_cpu(ranges[1]);
++
++ /* Now search for bcm2708-usb node in device tree */
++ of_scan_flat_dt(bcm2835_map_usb, &p2b_offset);
++}
++
+ static const char * const bcm2835_compat[] = {
+ #ifdef CONFIG_ARCH_MULTI_V6
+ "brcm,bcm2835",
+@@ -46,6 +114,7 @@ static const char * const bcm2835_compat
+ };
+
+ DT_MACHINE_START(BCM2835, "BCM2835")
++ .map_io = bcm2835_map_io,
+ .init_machine = bcm2835_init,
+ .dt_compat = bcm2835_compat,
+ .smp = smp_ops(bcm2836_smp_ops),
+--- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c
+@@ -837,7 +837,7 @@ static int dwc_otg_driver_probe(
+ retval = -ENOMEM;
+ goto fail;
+ }
+- dev_dbg(&_dev->dev, "base=0x%08x\n",
++ dev_info(&_dev->dev, "base=0x%08x\n",
+ (unsigned)dwc_otg_device->os_dep.base);
+ #endif
+