+++ /dev/null
-CONFIG_AG71XX=y
-# CONFIG_AG71XX_DEBUG is not set
-CONFIG_AG71XX_DEBUG_FS=y
-CONFIG_AR8216_PHY=y
-CONFIG_AR8216_PHY_LEDS=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_CLOCKSOURCE_DATA=y
-CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN=y
-CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
-CONFIG_ARCH_HAS_DMA_WRITE_COMBINE=y
-CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
-CONFIG_ARCH_HAS_RESET_CONTROLLER=y
-CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y
-CONFIG_ARCH_HAS_UNCACHED_SEGMENT=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SUPPORTS_UPROBES=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_USE_BUILTIN_BSWAP=y
-CONFIG_ARCH_USE_MEMREMAP_PROT=y
-CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
-CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
-CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
-CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
-CONFIG_AT803X_PHY=y
-CONFIG_ATH79=y
-CONFIG_ATH79_WDT=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CEVT_R4K=y
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-CONFIG_COMMON_CLK=y
-# CONFIG_COMMON_CLK_BOSTON is not set
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CPU_BIG_ENDIAN=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_LOAD_STORE_LR=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_MIPS32=y
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_MSA=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CSRC_R4K=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_EFI_EARLYCON=y
-CONFIG_ETHERNET_PACKET_MANGLE=y
-CONFIG_FIXED_PHY=y
-CONFIG_FONT_8x16=y
-CONFIG_FONT_AUTOSELECT=y
-CONFIG_FONT_SUPPORT=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_PINCTRL_GROUPS=y
-CONFIG_GENERIC_PINMUX_FUNCTIONS=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_74X164=y
-CONFIG_GPIO_ATH79=y
-CONFIG_GPIO_GENERIC=y
-# CONFIG_GPIO_LATCH is not set
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HAVE_ARCH_COMPILER_H=y
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
-CONFIG_HAVE_ARCH_TRACEHOOK=y
-CONFIG_HAVE_ASM_MODVERSIONS=y
-CONFIG_HAVE_CLK=y
-CONFIG_HAVE_CLK_PREPARE=y
-CONFIG_HAVE_CONTEXT_TRACKING=y
-CONFIG_HAVE_COPY_THREAD_TLS=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_HAVE_DEBUG_KMEMLEAK=y
-CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
-CONFIG_HAVE_DMA_CONTIGUOUS=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FAST_GUP=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_GENERIC_VDSO=y
-CONFIG_HAVE_IDE=y
-CONFIG_HAVE_IOREMAP_PROT=y
-CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
-CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
-CONFIG_HAVE_KVM=y
-CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
-CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
-CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
-CONFIG_HAVE_NET_DSA=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_PCI=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
-CONFIG_HAVE_RSEQ=y
-CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
-CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_IMAGE_CMDLINE_HACK=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=y
-CONFIG_LEDS_GPIO=y
-# CONFIG_LEDS_RESET is not set
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_MDIO_BITBANG=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_GPIO=y
-CONFIG_MEMFD_CREATE=y
-# CONFIG_MFD_RB4XX_CPLD is not set
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CLOCK_VSYSCALL=y
-# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_MIPS_CMDLINE_FROM_DTB=y
-# CONFIG_MIPS_ELF_APPENDED_DTB is not set
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_MIPS_NO_APPENDED_DTB is not set
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_GEOMETRY=y
-# CONFIG_MTD_CFI_I2 is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
-# CONFIG_MTD_NAND_RB91X is not set
-CONFIG_MTD_PARSER_CYBERTAN=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_ELF_FW=y
-CONFIG_MTD_SPLIT_LZMA_FW=y
-CONFIG_MTD_SPLIT_SEAMA_FW=y
-CONFIG_MTD_SPLIT_TPLINK_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_MTD_SPLIT_WRGG_FW=y
-CONFIG_MTD_VIRT_CONCAT=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
-CONFIG_NVMEM=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_NET=y
-CONFIG_PCI=y
-CONFIG_PCI_AR71XX=y
-CONFIG_PCI_AR724X=y
-CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-# CONFIG_PHY_AR7100_USB is not set
-# CONFIG_PHY_AR7200_USB is not set
-# CONFIG_PHY_ATH79_USB is not set
-CONFIG_PINCTRL=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_RESET_ATH79=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_SERIAL_8250_NR_UARTS=1
-CONFIG_SERIAL_8250_RUNTIME_UARTS=1
-CONFIG_SERIAL_AR933X=y
-CONFIG_SERIAL_AR933X_CONSOLE=y
-CONFIG_SERIAL_AR933X_NR_UARTS=2
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SPI=y
-CONFIG_SPI_AR934X=y
-CONFIG_SPI_ATH79=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_GPIO=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-# CONFIG_SPI_RB4XX is not set
-CONFIG_SRCU=y
-CONFIG_SWCONFIG=y
-CONFIG_SWCONFIG_LEDS=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_ZBOOT=y
-CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TINY_SRCU=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
+++ /dev/null
-From: Paul Burton <paul.burton@mips.com>
-Date: Wed, 9 Oct 2019 23:09:45 +0000
-Subject: MIPS: cmdline: Clean up boot_command_line initialization
-
-Our current code to initialize boot_command_line is a mess. Some of this
-is due to the addition of too many options over the years, and some of
-this is due to workarounds for early_init_dt_scan_chosen() performing
-actions specific to options from other architectures that probably
-shouldn't be in generic code.
-
-Clean this up by introducing a new bootcmdline_init() function that
-simplifies the initialization somewhat. The major changes are:
-
-- Because bootcmdline_init() is a function it can return early in the
- CONFIG_CMDLINE_OVERRIDE case.
-
-- We clear boot_command_line rather than inheriting whatever
- early_init_dt_scan_chosen() may have left us. This means we no longer
- need to set boot_command_line to a space character in an attempt to
- prevent early_init_dt_scan_chosen() from copying CONFIG_CMDLINE into
- boot_command_line without us knowing about it.
-
-- Indirection via USE_PROM_CMDLINE, USE_DTB_CMDLINE, EXTEND_WITH_PROM &
- BUILTIN_EXTEND_WITH_PROM macros is removed; they seemingly served only
- to obfuscate the code.
-
-- The logic is cleaner, clearer & commented.
-
-Two minor drawbacks of this approach are:
-
-1) We call of_scan_flat_dt(), which means we scan through the DT again.
- The overhead is fairly minimal & shouldn't be noticeable.
-
-2) cmdline_scan_chosen() duplicates a small amount of the logic from
- early_init_dt_scan_chosen(). Alternatives might be to allow the
- generic FDT code to keep & expose a copy of the arguments taken from
- the /chosen node's bootargs property, or to introduce a function like
- early_init_dt_scan_chosen() that retrieves them without modification
- to handle CONFIG_CMDLINE. Neither of these sounds particularly
- cleaner though, and this way we at least keep the extra work in
- arch/mips.
-
-Origin: upstream, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7784cac697351f0cc0a4bb619594c0c99348c5aa
-Signed-off-by: Paul Burton <paul.burton@mips.com>
-Cc: linux-mips@vger.kernel.org
-
---- a/arch/mips/kernel/setup.c
-+++ b/arch/mips/kernel/setup.c
-@@ -538,11 +538,88 @@ static void __init check_kernel_sections
- }
- }
-
--#define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
--#define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
--#define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
--#define BUILTIN_EXTEND_WITH_PROM \
-- IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND)
-+static void __init bootcmdline_append(const char *s, size_t max)
-+{
-+ if (!s[0] || !max)
-+ return;
-+
-+ if (boot_command_line[0])
-+ strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
-+
-+ strlcat(boot_command_line, s, max);
-+}
-+
-+static int __init bootcmdline_scan_chosen(unsigned long node, const char *uname,
-+ int depth, void *data)
-+{
-+ bool *dt_bootargs = data;
-+ const char *p;
-+ int l;
-+
-+ if (depth != 1 || !data ||
-+ (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
-+ return 0;
-+
-+ p = of_get_flat_dt_prop(node, "bootargs", &l);
-+ if (p != NULL && l > 0) {
-+ bootcmdline_append(p, min(l, COMMAND_LINE_SIZE));
-+ *dt_bootargs = true;
-+ }
-+
-+ return 1;
-+}
-+
-+static void __init bootcmdline_init(char **cmdline_p)
-+{
-+ bool dt_bootargs = false;
-+
-+ /*
-+ * If CMDLINE_OVERRIDE is enabled then initializing the command line is
-+ * trivial - we simply use the built-in command line unconditionally &
-+ * unmodified.
-+ */
-+ if (IS_ENABLED(CONFIG_CMDLINE_OVERRIDE)) {
-+ strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
-+ return;
-+ }
-+
-+ /*
-+ * If the user specified a built-in command line &
-+ * MIPS_CMDLINE_BUILTIN_EXTEND, then the built-in command line is
-+ * prepended to arguments from the bootloader or DT so we'll copy them
-+ * to the start of boot_command_line here. Otherwise, empty
-+ * boot_command_line to undo anything early_init_dt_scan_chosen() did.
-+ */
-+ if (IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND))
-+ strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
-+ else
-+ boot_command_line[0] = 0;
-+
-+ /*
-+ * If we're configured to take boot arguments from DT, look for those
-+ * now.
-+ */
-+ if (IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB))
-+ of_scan_flat_dt(bootcmdline_scan_chosen, &dt_bootargs);
-+
-+ /*
-+ * If we didn't get any arguments from DT (regardless of whether that's
-+ * because we weren't configured to look for them, or because we looked
-+ * & found none) then we'll take arguments from the bootloader.
-+ * plat_mem_setup() should have filled arcs_cmdline with arguments from
-+ * the bootloader.
-+ */
-+ if (IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND) || !dt_bootargs)
-+ bootcmdline_append(arcs_cmdline, COMMAND_LINE_SIZE);
-+
-+ /*
-+ * If the user specified a built-in command line & we didn't already
-+ * prepend it, we append it to boot_command_line here.
-+ */
-+ if (IS_ENABLED(CONFIG_CMDLINE_BOOL) &&
-+ !IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND))
-+ bootcmdline_append(builtin_cmdline, COMMAND_LINE_SIZE);
-+}
-
- /*
- * arch_mem_init - initialize memory management subsystem
-@@ -570,48 +647,12 @@ static void __init arch_mem_init(char **
- {
- extern void plat_mem_setup(void);
-
-- /*
-- * Initialize boot_command_line to an innocuous but non-empty string in
-- * order to prevent early_init_dt_scan_chosen() from copying
-- * CONFIG_CMDLINE into it without our knowledge. We handle
-- * CONFIG_CMDLINE ourselves below & don't want to duplicate its
-- * content because repeating arguments can be problematic.
-- */
-- strlcpy(boot_command_line, " ", COMMAND_LINE_SIZE);
--
- /* call board setup routine */
- plat_mem_setup();
- memblock_set_bottom_up(true);
-
--#if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
-- strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
--#else
-- if ((USE_PROM_CMDLINE && arcs_cmdline[0]) ||
-- (USE_DTB_CMDLINE && !boot_command_line[0]))
-- strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
--
-- if (EXTEND_WITH_PROM && arcs_cmdline[0]) {
-- if (boot_command_line[0])
-- strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
-- strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
-- }
--
--#if defined(CONFIG_CMDLINE_BOOL)
-- if (builtin_cmdline[0]) {
-- if (boot_command_line[0])
-- strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
-- strlcat(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
-- }
--
-- if (BUILTIN_EXTEND_WITH_PROM && arcs_cmdline[0]) {
-- if (boot_command_line[0])
-- strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
-- strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
-- }
--#endif
--#endif
-+ bootcmdline_init(cmdline_p);
- strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
--
- *cmdline_p = command_line;
-
- parse_early_param();
+++ /dev/null
-From 5f5c9858af167f842ee8df053920b98387a71af1 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Mon, 5 Mar 2018 11:41:25 +0100
-Subject: [PATCH 02/27] watchdog: ath79: fix maximum timeout
-
-If the userland tries to set a timeout higher than the max_timeout,
-then we should fallback to max_timeout.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/watchdog/ath79_wdt.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
---- a/drivers/watchdog/ath79_wdt.c
-+++ b/drivers/watchdog/ath79_wdt.c
-@@ -111,10 +111,14 @@ static inline void ath79_wdt_disable(voi
-
- static int ath79_wdt_set_timeout(int val)
- {
-- if (val < 1 || val > max_timeout)
-+ if (val < 1)
- return -EINVAL;
-
-- timeout = val;
-+ if (val > max_timeout)
-+ timeout = max_timeout;
-+ else
-+ timeout = val;
-+
- ath79_wdt_keepalive();
-
- return 0;
+++ /dev/null
-From ecbd9c87f073f097d9fe56390353e64e963e866a Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 6 Mar 2018 10:03:03 +0100
-Subject: [PATCH 03/27] leds: add reset-controller based driver
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/leds/Kconfig | 11 ++++
- drivers/leds/Makefile | 1 +
- drivers/leds/leds-reset.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 149 insertions(+)
- create mode 100644 drivers/leds/leds-reset.c
-
---- a/drivers/leds/Kconfig
-+++ b/drivers/leds/Kconfig
-@@ -824,6 +824,17 @@ config LEDS_LM36274
- Say Y to enable the LM36274 LED driver for TI LMU devices.
- This supports the LED device LM36274.
-
-+config LEDS_RESET
-+ tristate "LED support for reset-controller API"
-+ depends on LEDS_CLASS
-+ depends on RESET_CONTROLLER
-+ help
-+ This option enables support for LEDs connected to pins driven by reset
-+ controllers. Yes, DNI actual built HW like that.
-+
-+ To compile this driver as a module, choose M here: the module
-+ will be called leds-reset.
-+
- comment "LED Triggers"
- source "drivers/leds/trigger/Kconfig"
-
---- /dev/null
-+++ b/drivers/leds/leds-reset.c
-@@ -0,0 +1,140 @@
-+/*
-+ * Copyright (C) 2018 John Crispin <john@phrozen.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+#include <linux/err.h>
-+#include <linux/reset.h>
-+#include <linux/kernel.h>
-+#include <linux/leds.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset.h>
-+
-+struct reset_led_data {
-+ struct led_classdev cdev;
-+ struct reset_control *rst;
-+};
-+
-+static inline struct reset_led_data *
-+ cdev_to_reset_led_data(struct led_classdev *led_cdev)
-+{
-+ return container_of(led_cdev, struct reset_led_data, cdev);
-+}
-+
-+static void reset_led_set(struct led_classdev *led_cdev,
-+ enum led_brightness value)
-+{
-+ struct reset_led_data *led_dat = cdev_to_reset_led_data(led_cdev);
-+
-+ if (value == LED_OFF)
-+ reset_control_assert(led_dat->rst);
-+ else
-+ reset_control_deassert(led_dat->rst);
-+}
-+
-+struct reset_leds_priv {
-+ int num_leds;
-+ struct reset_led_data leds[];
-+};
-+
-+static inline int sizeof_reset_leds_priv(int num_leds)
-+{
-+ return sizeof(struct reset_leds_priv) +
-+ (sizeof(struct reset_led_data) * num_leds);
-+}
-+
-+static struct reset_leds_priv *reset_leds_create(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct fwnode_handle *child;
-+ struct reset_leds_priv *priv;
-+ int count, ret;
-+
-+ count = device_get_child_node_count(dev);
-+ if (!count)
-+ return ERR_PTR(-ENODEV);
-+
-+ priv = devm_kzalloc(dev, sizeof_reset_leds_priv(count), GFP_KERNEL);
-+ if (!priv)
-+ return ERR_PTR(-ENOMEM);
-+
-+ device_for_each_child_node(dev, child) {
-+ struct reset_led_data *led = &priv->leds[priv->num_leds];
-+ struct device_node *np = to_of_node(child);
-+
-+ ret = fwnode_property_read_string(child, "label", &led->cdev.name);
-+ if (!led->cdev.name) {
-+ fwnode_handle_put(child);
-+ return ERR_PTR(-EINVAL);
-+ }
-+ led->rst = __of_reset_control_get(np, NULL, 0, 0, 0, true);
-+ if (IS_ERR(led->rst))
-+ return ERR_PTR(-EINVAL);
-+
-+ fwnode_property_read_string(child, "linux,default-trigger",
-+ &led->cdev.default_trigger);
-+
-+ led->cdev.brightness_set = reset_led_set;
-+ ret = devm_led_classdev_register(&pdev->dev, &led->cdev);
-+ if (ret < 0)
-+ return ERR_PTR(ret);
-+ led->cdev.dev->of_node = np;
-+ priv->num_leds++;
-+ }
-+
-+ return priv;
-+}
-+
-+static const struct of_device_id of_reset_leds_match[] = {
-+ { .compatible = "reset-leds", },
-+ {},
-+};
-+
-+MODULE_DEVICE_TABLE(of, of_reset_leds_match);
-+
-+static int reset_led_probe(struct platform_device *pdev)
-+{
-+ struct reset_leds_priv *priv;
-+
-+ priv = reset_leds_create(pdev);
-+ if (IS_ERR(priv))
-+ return PTR_ERR(priv);
-+
-+ platform_set_drvdata(pdev, priv);
-+
-+ return 0;
-+}
-+
-+static void reset_led_shutdown(struct platform_device *pdev)
-+{
-+ struct reset_leds_priv *priv = platform_get_drvdata(pdev);
-+ int i;
-+
-+ for (i = 0; i < priv->num_leds; i++) {
-+ struct reset_led_data *led = &priv->leds[i];
-+
-+ if (!(led->cdev.flags & LED_RETAIN_AT_SHUTDOWN))
-+ reset_led_set(&led->cdev, LED_OFF);
-+ }
-+}
-+
-+static struct platform_driver reset_led_driver = {
-+ .probe = reset_led_probe,
-+ .shutdown = reset_led_shutdown,
-+ .driver = {
-+ .name = "leds-reset",
-+ .of_match_table = of_reset_leds_match,
-+ },
-+};
-+
-+module_platform_driver(reset_led_driver);
-+
-+MODULE_AUTHOR("John Crispin <john@phrozen.org>");
-+MODULE_DESCRIPTION("reset controller LED driver");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("platform:leds-reset");
---- a/drivers/leds/Makefile
-+++ b/drivers/leds/Makefile
-@@ -85,6 +85,7 @@ obj-$(CONFIG_LEDS_LM3601X) += leds-lm36
- obj-$(CONFIG_LEDS_TI_LMU_COMMON) += leds-ti-lmu-common.o
- obj-$(CONFIG_LEDS_LM3697) += leds-lm3697.o
- obj-$(CONFIG_LEDS_LM36274) += leds-lm36274.o
-+obj-$(CONFIG_LEDS_RESET) += leds-reset.o
-
- # LED SPI Drivers
- obj-$(CONFIG_LEDS_CR0014114) += leds-cr0014114.o
+++ /dev/null
-From 08c9d6ceef01893678a5d2e8a15517c745417f21 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 6 Mar 2018 10:04:05 +0100
-Subject: [PATCH 04/27] phy: add ath79 usb phys
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/phy/Kconfig | 16 ++++++
- drivers/phy/Makefile | 2 +
- drivers/phy/phy-ar7100-usb.c | 124 +++++++++++++++++++++++++++++++++++++++++++
- drivers/phy/phy-ar7200-usb.c | 108 +++++++++++++++++++++++++++++++++++++
- 4 files changed, 250 insertions(+)
- create mode 100644 drivers/phy/phy-ar7100-usb.c
- create mode 100644 drivers/phy/phy-ar7200-usb.c
-
---- a/drivers/phy/Kconfig
-+++ b/drivers/phy/Kconfig
-@@ -24,6 +24,22 @@ config GENERIC_PHY_MIPI_DPHY
- Provides a number of helpers a core functions for MIPI D-PHY
- drivers to us.
-
-+config PHY_AR7100_USB
-+ tristate "Atheros AR7100 USB PHY driver"
-+ depends on ATH79 || COMPILE_TEST
-+ default y if USB_EHCI_HCD_PLATFORM
-+ select GENERIC_PHY
-+ help
-+ Enable this to support the USB PHY on Atheros AR7100 SoCs.
-+
-+config PHY_AR7200_USB
-+ tristate "Atheros AR7200 USB PHY driver"
-+ depends on ATH79 || COMPILE_TEST
-+ default y if USB_EHCI_HCD_PLATFORM
-+ select GENERIC_PHY
-+ help
-+ Enable this to support the USB PHY on Atheros AR7200 SoCs.
-+
- config PHY_LPC18XX_USB_OTG
- tristate "NXP LPC18xx/43xx SoC USB OTG PHY driver"
- depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
---- a/drivers/phy/Makefile
-+++ b/drivers/phy/Makefile
-@@ -4,6 +4,8 @@
- #
-
- obj-$(CONFIG_GENERIC_PHY) += phy-core.o
-+obj-$(CONFIG_PHY_AR7100_USB) += phy-ar7100-usb.o
-+obj-$(CONFIG_PHY_AR7200_USB) += phy-ar7200-usb.o
- obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY) += phy-core-mipi-dphy.o
- obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
- obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
---- /dev/null
-+++ b/drivers/phy/phy-ar7100-usb.c
-@@ -0,0 +1,140 @@
-+/*
-+ * Copyright (C) 2018 John Crispin <john@phrozen.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/phy/phy.h>
-+#include <linux/delay.h>
-+#include <linux/reset.h>
-+#include <linux/of_gpio.h>
-+
-+#include <asm/mach-ath79/ath79.h>
-+#include <asm/mach-ath79/ar71xx_regs.h>
-+
-+struct ar7100_usb_phy {
-+ struct reset_control *rst_phy;
-+ struct reset_control *rst_host;
-+ struct reset_control *rst_ohci_dll;
-+ void __iomem *io_base;
-+ struct phy *phy;
-+ int gpio;
-+};
-+
-+static int ar7100_usb_phy_power_off(struct phy *phy)
-+{
-+ struct ar7100_usb_phy *priv = phy_get_drvdata(phy);
-+ int err = 0;
-+
-+ err |= reset_control_assert(priv->rst_host);
-+ err |= reset_control_assert(priv->rst_phy);
-+ err |= reset_control_assert(priv->rst_ohci_dll);
-+
-+ return err;
-+}
-+
-+static int ar7100_usb_phy_power_on(struct phy *phy)
-+{
-+ struct ar7100_usb_phy *priv = phy_get_drvdata(phy);
-+ int err = 0;
-+
-+ err |= ar7100_usb_phy_power_off(phy);
-+ mdelay(100);
-+ err |= reset_control_deassert(priv->rst_ohci_dll);
-+ err |= reset_control_deassert(priv->rst_phy);
-+ err |= reset_control_deassert(priv->rst_host);
-+ mdelay(500);
-+ iowrite32(0xf0000, priv->io_base + AR71XX_USB_CTRL_REG_CONFIG);
-+ iowrite32(0x20c00, priv->io_base + AR71XX_USB_CTRL_REG_FLADJ);
-+
-+ return err;
-+}
-+
-+static const struct phy_ops ar7100_usb_phy_ops = {
-+ .power_on = ar7100_usb_phy_power_on,
-+ .power_off = ar7100_usb_phy_power_off,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int ar7100_usb_phy_probe(struct platform_device *pdev)
-+{
-+ struct phy_provider *phy_provider;
-+ struct resource *res;
-+ struct ar7100_usb_phy *priv;
-+
-+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ priv->io_base = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(priv->io_base))
-+ return PTR_ERR(priv->io_base);
-+
-+ priv->rst_phy = devm_reset_control_get(&pdev->dev, "usb-phy");
-+ if (IS_ERR(priv->rst_phy)) {
-+ dev_err(&pdev->dev, "phy reset is missing\n");
-+ return PTR_ERR(priv->rst_phy);
-+ }
-+
-+ priv->rst_host = devm_reset_control_get(&pdev->dev, "usb-host");
-+ if (IS_ERR(priv->rst_host)) {
-+ dev_err(&pdev->dev, "host reset is missing\n");
-+ return PTR_ERR(priv->rst_host);
-+ }
-+
-+ priv->rst_ohci_dll = devm_reset_control_get(&pdev->dev, "usb-ohci-dll");
-+ if (IS_ERR(priv->rst_ohci_dll)) {
-+ dev_err(&pdev->dev, "ohci-dll reset is missing\n");
-+ return PTR_ERR(priv->rst_host);
-+ }
-+
-+ priv->phy = devm_phy_create(&pdev->dev, NULL, &ar7100_usb_phy_ops);
-+ if (IS_ERR(priv->phy)) {
-+ dev_err(&pdev->dev, "failed to create PHY\n");
-+ return PTR_ERR(priv->phy);
-+ }
-+
-+ priv->gpio = of_get_gpio(pdev->dev.of_node, 0);
-+ if (priv->gpio >= 0) {
-+ int ret = devm_gpio_request(&pdev->dev, priv->gpio, dev_name(&pdev->dev));
-+
-+ if (ret) {
-+ dev_err(&pdev->dev, "failed to request gpio\n");
-+ return ret;
-+ }
-+ gpio_export_with_name(priv->gpio, 0, dev_name(&pdev->dev));
-+ gpio_set_value(priv->gpio, 1);
-+ }
-+
-+ phy_set_drvdata(priv->phy, priv);
-+
-+ phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
-+
-+
-+ return PTR_ERR_OR_ZERO(phy_provider);
-+}
-+
-+static const struct of_device_id ar7100_usb_phy_of_match[] = {
-+ { .compatible = "qca,ar7100-usb-phy" },
-+ {}
-+};
-+MODULE_DEVICE_TABLE(of, ar7100_usb_phy_of_match);
-+
-+static struct platform_driver ar7100_usb_phy_driver = {
-+ .probe = ar7100_usb_phy_probe,
-+ .driver = {
-+ .of_match_table = ar7100_usb_phy_of_match,
-+ .name = "ar7100-usb-phy",
-+ }
-+};
-+module_platform_driver(ar7100_usb_phy_driver);
-+
-+MODULE_DESCRIPTION("ATH79 USB PHY driver");
-+MODULE_AUTHOR("Alban Bedel <albeu@free.fr>");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/phy/phy-ar7200-usb.c
-@@ -0,0 +1,136 @@
-+/*
-+ * Copyright (C) 2015 Alban Bedel <albeu@free.fr>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/phy/phy.h>
-+#include <linux/reset.h>
-+#include <linux/of_gpio.h>
-+
-+struct ar7200_usb_phy {
-+ struct reset_control *rst_phy;
-+ struct reset_control *rst_phy_analog;
-+ struct reset_control *suspend_override;
-+ struct phy *phy;
-+ int gpio;
-+};
-+
-+static int ar7200_usb_phy_power_on(struct phy *phy)
-+{
-+ struct ar7200_usb_phy *priv = phy_get_drvdata(phy);
-+ int err = 0;
-+
-+ if (priv->suspend_override)
-+ err = reset_control_assert(priv->suspend_override);
-+ if (priv->rst_phy)
-+ err |= reset_control_deassert(priv->rst_phy);
-+ if (priv->rst_phy_analog)
-+ err |= reset_control_deassert(priv->rst_phy_analog);
-+
-+ return err;
-+}
-+
-+static int ar7200_usb_phy_power_off(struct phy *phy)
-+{
-+ struct ar7200_usb_phy *priv = phy_get_drvdata(phy);
-+ int err = 0;
-+
-+ if (priv->suspend_override)
-+ err = reset_control_deassert(priv->suspend_override);
-+ if (priv->rst_phy)
-+ err |= reset_control_assert(priv->rst_phy);
-+ if (priv->rst_phy_analog)
-+ err |= reset_control_assert(priv->rst_phy_analog);
-+
-+ return err;
-+}
-+
-+static const struct phy_ops ar7200_usb_phy_ops = {
-+ .power_on = ar7200_usb_phy_power_on,
-+ .power_off = ar7200_usb_phy_power_off,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int ar7200_usb_phy_probe(struct platform_device *pdev)
-+{
-+ struct phy_provider *phy_provider;
-+ struct ar7200_usb_phy *priv;
-+
-+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->rst_phy = devm_reset_control_get(&pdev->dev, "usb-phy");
-+ if (IS_ERR(priv->rst_phy)) {
-+ if (PTR_ERR(priv->rst_phy) != -EPROBE_DEFER)
-+ dev_err(&pdev->dev, "phy reset is missing\n");
-+ return PTR_ERR(priv->rst_phy);
-+ }
-+
-+ priv->rst_phy_analog = devm_reset_control_get_optional(
-+ &pdev->dev, "usb-phy-analog");
-+ if (IS_ERR(priv->rst_phy_analog)) {
-+ if (PTR_ERR(priv->rst_phy_analog) == -ENOENT)
-+ priv->rst_phy_analog = NULL;
-+ else
-+ return PTR_ERR(priv->rst_phy_analog);
-+ }
-+
-+ priv->suspend_override = devm_reset_control_get_optional(
-+ &pdev->dev, "usb-suspend-override");
-+ if (IS_ERR(priv->suspend_override)) {
-+ if (PTR_ERR(priv->suspend_override) == -ENOENT)
-+ priv->suspend_override = NULL;
-+ else
-+ return PTR_ERR(priv->suspend_override);
-+ }
-+
-+ priv->phy = devm_phy_create(&pdev->dev, NULL, &ar7200_usb_phy_ops);
-+ if (IS_ERR(priv->phy)) {
-+ dev_err(&pdev->dev, "failed to create PHY\n");
-+ return PTR_ERR(priv->phy);
-+ }
-+
-+ priv->gpio = of_get_gpio(pdev->dev.of_node, 0);
-+ if (priv->gpio >= 0) {
-+ int ret = devm_gpio_request(&pdev->dev, priv->gpio, dev_name(&pdev->dev));
-+
-+ if (ret) {
-+ dev_err(&pdev->dev, "failed to request gpio\n");
-+ return ret;
-+ }
-+ gpio_export_with_name(priv->gpio, 0, dev_name(&pdev->dev));
-+ gpio_set_value(priv->gpio, 1);
-+ }
-+
-+ phy_set_drvdata(priv->phy, priv);
-+
-+ phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
-+
-+ return PTR_ERR_OR_ZERO(phy_provider);
-+}
-+
-+static const struct of_device_id ar7200_usb_phy_of_match[] = {
-+ { .compatible = "qca,ar7200-usb-phy" },
-+ {}
-+};
-+MODULE_DEVICE_TABLE(of, ar7200_usb_phy_of_match);
-+
-+static struct platform_driver ar7200_usb_phy_driver = {
-+ .probe = ar7200_usb_phy_probe,
-+ .driver = {
-+ .of_match_table = ar7200_usb_phy_of_match,
-+ .name = "ar7200-usb-phy",
-+ }
-+};
-+module_platform_driver(ar7200_usb_phy_driver);
-+
-+MODULE_DESCRIPTION("ATH79 USB PHY driver");
-+MODULE_AUTHOR("Alban Bedel <albeu@free.fr>");
-+MODULE_LICENSE("GPL");
+++ /dev/null
-From 2201818e5bd33f389beceb3943fdfcf5a698fc5b Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 6 Mar 2018 10:01:43 +0100
-Subject: [PATCH 05/27] usb: add more OF/quirk properties
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/usb/host/ehci-platform.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/drivers/usb/host/ehci-platform.c
-+++ b/drivers/usb/host/ehci-platform.c
-@@ -269,6 +269,11 @@ static int ehci_platform_probe(struct pl
- ehci = hcd_to_ehci(hcd);
-
- if (pdata == &ehci_platform_defaults && dev->dev.of_node) {
-+ of_property_read_u32(dev->dev.of_node, "caps-offset", &pdata->caps_offset);
-+
-+ if (of_property_read_bool(dev->dev.of_node, "has-synopsys-hc-bug"))
-+ pdata->has_synopsys_hc_bug = 1;
-+
- if (of_property_read_bool(dev->dev.of_node, "big-endian-regs"))
- ehci->big_endian_mmio = 1;
-
+++ /dev/null
-From f3eacff2310a60348a755c50a8da6fc251fc8587 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 6 Mar 2018 09:55:13 +0100
-Subject: [PATCH 07/33] irqchip/irq-ath79-intc: add irq cascade driver for
- QCA9556 SoCs
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/irqchip/Makefile | 1 +
- drivers/irqchip/irq-ath79-intc.c | 142 +++++++++++++++++++++++++++++++++++++++
- 2 files changed, 143 insertions(+)
- create mode 100644 drivers/irqchip/irq-ath79-intc.c
-
---- a/drivers/irqchip/Makefile
-+++ b/drivers/irqchip/Makefile
-@@ -4,6 +4,7 @@ obj-$(CONFIG_IRQCHIP) += irqchip.o
- obj-$(CONFIG_AL_FIC) += irq-al-fic.o
- obj-$(CONFIG_ALPINE_MSI) += irq-alpine-msi.o
- obj-$(CONFIG_ATH79) += irq-ath79-cpu.o
-+obj-$(CONFIG_ATH79) += irq-ath79-intc.o
- obj-$(CONFIG_ATH79) += irq-ath79-misc.o
- obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o
- obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o
---- /dev/null
-+++ b/drivers/irqchip/irq-ath79-intc.c
-@@ -0,0 +1,142 @@
-+/*
-+ * Atheros AR71xx/AR724x/AR913x specific interrupt handling
-+ *
-+ * Copyright (C) 2018 John Crispin <john@phrozen.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ */
-+
-+#include <linux/interrupt.h>
-+#include <linux/irqchip.h>
-+#include <linux/of.h>
-+#include <linux/of_irq.h>
-+#include <linux/irqdomain.h>
-+
-+#include <asm/irq_cpu.h>
-+#include <asm/mach-ath79/ath79.h>
-+#include <asm/mach-ath79/ar71xx_regs.h>
-+
-+#define ATH79_MAX_INTC_CASCADE 3
-+
-+struct ath79_intc {
-+ struct irq_chip chip;
-+ u32 irq;
-+ u32 pending_mask;
-+ u32 int_status;
-+ u32 irq_mask[ATH79_MAX_INTC_CASCADE];
-+ u32 irq_wb_chan[ATH79_MAX_INTC_CASCADE];
-+};
-+
-+static void ath79_intc_irq_handler(struct irq_desc *desc)
-+{
-+ struct irq_domain *domain = irq_desc_get_handler_data(desc);
-+ struct ath79_intc *intc = domain->host_data;
-+ u32 pending;
-+
-+ pending = ath79_reset_rr(intc->int_status);
-+ pending &= intc->pending_mask;
-+
-+ if (pending) {
-+ int i;
-+
-+ for (i = 0; i < domain->hwirq_max; i++)
-+ if (pending & intc->irq_mask[i]) {
-+ if (intc->irq_wb_chan[i] != 0xffffffff)
-+ ath79_ddr_wb_flush(intc->irq_wb_chan[i]);
-+ generic_handle_irq(irq_find_mapping(domain, i));
-+ }
-+ } else {
-+ spurious_interrupt();
-+ }
-+}
-+
-+static void ath79_intc_irq_enable(struct irq_data *d)
-+{
-+ struct ath79_intc *intc = d->domain->host_data;
-+ enable_irq(intc->irq);
-+}
-+
-+static void ath79_intc_irq_disable(struct irq_data *d)
-+{
-+ struct ath79_intc *intc = d->domain->host_data;
-+ disable_irq(intc->irq);
-+}
-+
-+static int ath79_intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
-+{
-+ struct ath79_intc *intc = d->host_data;
-+
-+ irq_set_chip_and_handler(irq, &intc->chip, handle_level_irq);
-+
-+ return 0;
-+}
-+
-+static const struct irq_domain_ops ath79_irq_domain_ops = {
-+ .xlate = irq_domain_xlate_onecell,
-+ .map = ath79_intc_map,
-+};
-+
-+static int __init ath79_intc_of_init(
-+ struct device_node *node, struct device_node *parent)
-+{
-+ struct irq_domain *domain;
-+ struct ath79_intc *intc;
-+ int cnt, cntwb, i, err;
-+
-+ cnt = of_property_count_u32_elems(node, "qca,pending-bits");
-+ if (cnt > ATH79_MAX_INTC_CASCADE)
-+ panic("Too many INTC pending bits\n");
-+
-+ intc = kzalloc(sizeof(*intc), GFP_KERNEL);
-+ if (!intc)
-+ panic("Failed to allocate INTC memory\n");
-+ intc->chip = dummy_irq_chip;
-+ intc->chip.name = "INTC";
-+ intc->chip.irq_disable = ath79_intc_irq_disable;
-+ intc->chip.irq_enable = ath79_intc_irq_enable;
-+
-+ if (of_property_read_u32(node, "qca,int-status-addr", &intc->int_status) < 0) {
-+ panic("Missing address of interrupt status register\n");
-+ }
-+
-+ of_property_read_u32_array(node, "qca,pending-bits", intc->irq_mask, cnt);
-+ for (i = 0; i < cnt; i++) {
-+ intc->pending_mask |= intc->irq_mask[i];
-+ intc->irq_wb_chan[i] = 0xffffffff;
-+ }
-+
-+ cntwb = of_count_phandle_with_args(
-+ node, "qca,ddr-wb-channels", "#qca,ddr-wb-channel-cells");
-+
-+ for (i = 0; i < cntwb; i++) {
-+ struct of_phandle_args args;
-+ u32 irq = i;
-+
-+ of_property_read_u32_index(
-+ node, "qca,ddr-wb-channel-interrupts", i, &irq);
-+ if (irq >= ATH79_MAX_INTC_CASCADE)
-+ continue;
-+
-+ err = of_parse_phandle_with_args(
-+ node, "qca,ddr-wb-channels",
-+ "#qca,ddr-wb-channel-cells",
-+ i, &args);
-+ if (err)
-+ return err;
-+
-+ intc->irq_wb_chan[irq] = args.args[0];
-+ }
-+
-+ intc->irq = irq_of_parse_and_map(node, 0);
-+ if (!intc->irq)
-+ panic("Failed to get INTC IRQ");
-+
-+ domain = irq_domain_add_linear(node, cnt, &ath79_irq_domain_ops, intc);
-+ irq_set_chained_handler_and_data(intc->irq, ath79_intc_irq_handler, domain);
-+
-+ return 0;
-+}
-+IRQCHIP_DECLARE(ath79_intc, "qca,ar9340-intc",
-+ ath79_intc_of_init);
+++ /dev/null
-From e029f998594f151008ecbfa024e2957edd2a5189 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 6 Mar 2018 09:58:19 +0100
-Subject: [PATCH 08/33] irqchip/irq-ath79-cpu: drop !OF init helper
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/irqchip/irq-ath79-cpu.c | 7 -------
- 1 file changed, 7 deletions(-)
-
---- a/drivers/irqchip/irq-ath79-cpu.c
-+++ b/drivers/irqchip/irq-ath79-cpu.c
-@@ -85,10 +85,3 @@ static int __init ar79_cpu_intc_of_init(
- }
- IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
- ar79_cpu_intc_of_init);
--
--void __init ath79_cpu_irq_init(unsigned irq_wb_chan2, unsigned irq_wb_chan3)
--{
-- irq_wb_chan[2] = irq_wb_chan2;
-- irq_wb_chan[3] = irq_wb_chan3;
-- mips_cpu_irq_init();
--}
+++ /dev/null
-From 4a4f869ec58ed8910b9b2e68d0eee50957e9bb20 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Mon, 25 Jun 2018 15:52:10 +0200
-Subject: [PATCH 17/33] dt-bindings: PCI: qcom,ar7100: adds binding doc
-
-With the driver being converted from platform_data to pure OF, we need to
-also add some docs.
-
-Cc: Rob Herring <robh+dt@kernel.org>
-Cc: devicetree@vger.kernel.org
-Signed-off-by: John Crispin <john@phrozen.org>
----
- .../devicetree/bindings/pci/qcom,ar7100-pci.txt | 38 ++++++++++++++++++++++
- 1 file changed, 38 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/pci/qcom,ar7100-pci.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pci/qcom,ar7100-pci.txt
-@@ -0,0 +1,38 @@
-+* Qualcomm Atheros AR7100 PCI express root complex
-+
-+Required properties:
-+- compatible: should contain "qcom,ar7100-pci" to identify the core.
-+- reg: Should contain the register ranges as listed in the reg-names property.
-+- reg-names: Definition: Must include the following entries
-+ - "cfg_base" IO Memory
-+- #address-cells: set to <3>
-+- #size-cells: set to <2>
-+- ranges: ranges for the PCI memory and I/O regions
-+- interrupt-map-mask and interrupt-map: standard PCI
-+ properties to define the mapping of the PCIe interface to interrupt
-+ numbers.
-+- #interrupt-cells: set to <1>
-+- interrupt-controller: define to enable the builtin IRQ cascade.
-+
-+Optional properties:
-+- interrupt-parent: phandle to the MIPS IRQ controller
-+
-+* Example for ar7100
-+ pcie-controller@180c0000 {
-+ compatible = "qca,ar7100-pci";
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ bus-range = <0x0 0x0>;
-+ reg = <0x17010000 0x100>;
-+ reg-names = "cfg_base";
-+ ranges = <0x2000000 0 0x10000000 0x10000000 0 0x07000000
-+ 0x1000000 0 0x00000000 0x00000000 0 0x00000001>;
-+ interrupt-parent = <&cpuintc>;
-+ interrupts = <2>;
-+
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+
-+ interrupt-map-mask = <0 0 0 1>;
-+ interrupt-map = <0 0 0 0 &pcie0 0>;
-+ };
+++ /dev/null
-From 1855ab6b1d27f5b38a648baf57ff6a534afec26d Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Sat, 23 Jun 2018 15:07:23 +0200
-Subject: [PATCH 18/33] MIPS: pci-ar71xx: convert to OF
-
-With the ath79 target getting converted to pure OF, we can drop all the
-platform data code and add the missing OF bits to the driver. We also add
-a irq domain for the PCI/e controllers cascade, thus making it usable from
-dts files.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- arch/mips/pci/pci-ar71xx.c | 82 +++++++++++++++++++++++-----------------------
- 1 file changed, 41 insertions(+), 41 deletions(-)
-
---- a/arch/mips/pci/pci-ar71xx.c
-+++ b/arch/mips/pci/pci-ar71xx.c
-@@ -15,8 +15,11 @@
- #include <linux/pci.h>
- #include <linux/pci_regs.h>
- #include <linux/interrupt.h>
-+#include <linux/irqchip/chained_irq.h>
- #include <linux/init.h>
- #include <linux/platform_device.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_pci.h>
-
- #include <asm/mach-ath79/ar71xx_regs.h>
- #include <asm/mach-ath79/ath79.h>
-@@ -46,12 +49,13 @@
- #define AR71XX_PCI_IRQ_COUNT 5
-
- struct ar71xx_pci_controller {
-+ struct device_node *np;
- void __iomem *cfg_base;
- int irq;
-- int irq_base;
- struct pci_controller pci_ctrl;
- struct resource io_res;
- struct resource mem_res;
-+ struct irq_domain *domain;
- };
-
- /* Byte lane enable bits */
-@@ -225,29 +229,30 @@ static struct pci_ops ar71xx_pci_ops = {
-
- static void ar71xx_pci_irq_handler(struct irq_desc *desc)
- {
-- struct ar71xx_pci_controller *apc;
- void __iomem *base = ath79_reset_base;
-+ struct irq_chip *chip = irq_desc_get_chip(desc);
-+ struct ar71xx_pci_controller *apc = irq_desc_get_handler_data(desc);
- u32 pending;
-
-- apc = irq_desc_get_handler_data(desc);
--
-+ chained_irq_enter(chip, desc);
- pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) &
- __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-
- if (pending & AR71XX_PCI_INT_DEV0)
-- generic_handle_irq(apc->irq_base + 0);
-+ generic_handle_irq(irq_linear_revmap(apc->domain, 1));
-
- else if (pending & AR71XX_PCI_INT_DEV1)
-- generic_handle_irq(apc->irq_base + 1);
-+ generic_handle_irq(irq_linear_revmap(apc->domain, 2));
-
- else if (pending & AR71XX_PCI_INT_DEV2)
-- generic_handle_irq(apc->irq_base + 2);
-+ generic_handle_irq(irq_linear_revmap(apc->domain, 3));
-
- else if (pending & AR71XX_PCI_INT_CORE)
-- generic_handle_irq(apc->irq_base + 4);
-+ generic_handle_irq(irq_linear_revmap(apc->domain, 4));
-
- else
- spurious_interrupt();
-+ chained_irq_exit(chip, desc);
- }
-
- static void ar71xx_pci_irq_unmask(struct irq_data *d)
-@@ -258,7 +263,7 @@ static void ar71xx_pci_irq_unmask(struct
- u32 t;
-
- apc = irq_data_get_irq_chip_data(d);
-- irq = d->irq - apc->irq_base;
-+ irq = irq_linear_revmap(apc->domain, d->irq);
-
- t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
- __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-@@ -275,7 +280,7 @@ static void ar71xx_pci_irq_mask(struct i
- u32 t;
-
- apc = irq_data_get_irq_chip_data(d);
-- irq = d->irq - apc->irq_base;
-+ irq = irq_linear_revmap(apc->domain, d->irq);
-
- t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
- __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-@@ -291,24 +296,31 @@ static struct irq_chip ar71xx_pci_irq_ch
- .irq_mask_ack = ar71xx_pci_irq_mask,
- };
-
-+static int ar71xx_pci_irq_map(struct irq_domain *d,
-+ unsigned int irq, irq_hw_number_t hw)
-+{
-+ struct ar71xx_pci_controller *apc = d->host_data;
-+
-+ irq_set_chip_and_handler(irq, &ar71xx_pci_irq_chip, handle_level_irq);
-+ irq_set_chip_data(irq, apc);
-+
-+ return 0;
-+}
-+
-+static const struct irq_domain_ops ar71xx_pci_domain_ops = {
-+ .xlate = irq_domain_xlate_onecell,
-+ .map = ar71xx_pci_irq_map,
-+};
-+
- static void ar71xx_pci_irq_init(struct ar71xx_pci_controller *apc)
- {
- void __iomem *base = ath79_reset_base;
-- int i;
-
- __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE);
- __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS);
-
-- BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR71XX_PCI_IRQ_COUNT);
--
-- apc->irq_base = ATH79_PCI_IRQ_BASE;
-- for (i = apc->irq_base;
-- i < apc->irq_base + AR71XX_PCI_IRQ_COUNT; i++) {
-- irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip,
-- handle_level_irq);
-- irq_set_chip_data(i, apc);
-- }
--
-+ apc->domain = irq_domain_add_linear(apc->np, AR71XX_PCI_IRQ_COUNT,
-+ &ar71xx_pci_domain_ops, apc);
- irq_set_chained_handler_and_data(apc->irq, ar71xx_pci_irq_handler,
- apc);
- }
-@@ -325,6 +337,11 @@ static void ar71xx_pci_reset(void)
- mdelay(100);
- }
-
-+static const struct of_device_id ar71xx_pci_ids[] = {
-+ { .compatible = "qca,ar7100-pci" },
-+ {},
-+};
-+
- static int ar71xx_pci_probe(struct platform_device *pdev)
- {
- struct ar71xx_pci_controller *apc;
-@@ -345,26 +362,6 @@ static int ar71xx_pci_probe(struct platf
- if (apc->irq < 0)
- return -EINVAL;
-
-- res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base");
-- if (!res)
-- return -EINVAL;
--
-- apc->io_res.parent = res;
-- apc->io_res.name = "PCI IO space";
-- apc->io_res.start = res->start;
-- apc->io_res.end = res->end;
-- apc->io_res.flags = IORESOURCE_IO;
--
-- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base");
-- if (!res)
-- return -EINVAL;
--
-- apc->mem_res.parent = res;
-- apc->mem_res.name = "PCI memory space";
-- apc->mem_res.start = res->start;
-- apc->mem_res.end = res->end;
-- apc->mem_res.flags = IORESOURCE_MEM;
--
- ar71xx_pci_reset();
-
- /* setup COMMAND register */
-@@ -377,9 +374,11 @@ static int ar71xx_pci_probe(struct platf
-
- ar71xx_pci_irq_init(apc);
-
-+ apc->np = pdev->dev.of_node;
- apc->pci_ctrl.pci_ops = &ar71xx_pci_ops;
- apc->pci_ctrl.mem_resource = &apc->mem_res;
- apc->pci_ctrl.io_resource = &apc->io_res;
-+ pci_load_of_ranges(&apc->pci_ctrl, pdev->dev.of_node);
-
- register_pci_controller(&apc->pci_ctrl);
-
-@@ -390,6 +389,7 @@ static struct platform_driver ar71xx_pci
- .probe = ar71xx_pci_probe,
- .driver = {
- .name = "ar71xx-pci",
-+ .of_match_table = of_match_ptr(ar71xx_pci_ids),
- },
- };
-
+++ /dev/null
-From ea27764bc3ef2a05decf3ae05edffc289cd0d93c Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Mon, 25 Jun 2018 15:52:02 +0200
-Subject: [PATCH 19/33] dt-bindings: PCI: qcom,ar7240: adds binding doc
-
-With the driver being converted from platform_data to pure OF, we need to
-also add some docs.
-
-Cc: Rob Herring <robh+dt@kernel.org>
-Cc: devicetree@vger.kernel.org
-Signed-off-by: John Crispin <john@phrozen.org>
----
- .../devicetree/bindings/pci/qcom,ar7240-pci.txt | 42 ++++++++++++++++++++++
- 1 file changed, 42 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/pci/qcom,ar7240-pci.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pci/qcom,ar7240-pci.txt
-@@ -0,0 +1,42 @@
-+* Qualcomm Atheros AR724X PCI express root complex
-+
-+Required properties:
-+- compatible: should contain "qcom,ar7240-pci" to identify the core.
-+- reg: Should contain the register ranges as listed in the reg-names property.
-+- reg-names: Definition: Must include the following entries
-+ - "crp_base" Configuration registers
-+ - "ctrl_base" Control registers
-+ - "cfg_base" IO Memory
-+- #address-cells: set to <3>
-+- #size-cells: set to <2>
-+- ranges: ranges for the PCI memory and I/O regions
-+- interrupt-map-mask and interrupt-map: standard PCI
-+ properties to define the mapping of the PCIe interface to interrupt
-+ numbers.
-+- #interrupt-cells: set to <1>
-+- interrupt-parent: phandle to the MIPS IRQ controller
-+
-+Optional properties:
-+- interrupt-controller: define to enable the builtin IRQ cascade.
-+
-+* Example for qca9557
-+ pcie-controller@180c0000 {
-+ compatible = "qcom,ar7240-pci";
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ bus-range = <0x0 0x0>;
-+ reg = <0x180c0000 0x1000>,
-+ <0x180f0000 0x100>,
-+ <0x14000000 0x1000>;
-+ reg-names = "crp_base", "ctrl_base", "cfg_base";
-+ ranges = <0x2000000 0 0x10000000 0x10000000 0 0x04000000
-+ 0x1000000 0 0x00000000 0x00000000 0 0x00000001>;
-+ interrupt-parent = <&intc2>;
-+ interrupts = <1>;
-+
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+
-+ interrupt-map-mask = <0 0 0 1>;
-+ interrupt-map = <0 0 0 0 &pcie0 0>;
-+ };
+++ /dev/null
-From a522ee0199d5d3ea114ca2e211f6ac398d3e8e0b Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Sat, 23 Jun 2018 15:07:37 +0200
-Subject: [PATCH 20/33] MIPS: pci-ar724x: convert to OF
-
-With the ath79 target getting converted to pure OF, we can drop all the
-platform data code and add the missing OF bits to the driver. We also add
-a irq domain for the PCI/e controllers cascade, thus making it usable from
-dts files.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- arch/mips/pci/pci-ar724x.c | 88 ++++++++++++++++++++++------------------------
- 1 file changed, 42 insertions(+), 46 deletions(-)
-
---- a/arch/mips/pci/pci-ar724x.c
-+++ b/arch/mips/pci/pci-ar724x.c
-@@ -11,8 +11,11 @@
- #include <linux/init.h>
- #include <linux/delay.h>
- #include <linux/platform_device.h>
-+#include <linux/irqchip/chained_irq.h>
- #include <asm/mach-ath79/ath79.h>
- #include <asm/mach-ath79/ar71xx_regs.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_pci.h>
-
- #define AR724X_PCI_REG_APP 0x00
- #define AR724X_PCI_REG_RESET 0x18
-@@ -42,17 +45,20 @@ struct ar724x_pci_controller {
- void __iomem *crp_base;
-
- int irq;
-- int irq_base;
-
- bool link_up;
- bool bar0_is_cached;
- u32 bar0_value;
-
-+ struct device_node *np;
- struct pci_controller pci_controller;
-+ struct irq_domain *domain;
- struct resource io_res;
- struct resource mem_res;
- };
-
-+static struct irq_chip ar724x_pci_irq_chip;
-+
- static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc)
- {
- u32 reset;
-@@ -228,35 +234,31 @@ static struct pci_ops ar724x_pci_ops = {
-
- static void ar724x_pci_irq_handler(struct irq_desc *desc)
- {
-- struct ar724x_pci_controller *apc;
-- void __iomem *base;
-+ struct irq_chip *chip = irq_desc_get_chip(desc);
-+ struct ar724x_pci_controller *apc = irq_desc_get_handler_data(desc);
- u32 pending;
-
-- apc = irq_desc_get_handler_data(desc);
-- base = apc->ctrl_base;
--
-- pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
-- __raw_readl(base + AR724X_PCI_REG_INT_MASK);
-+ chained_irq_enter(chip, desc);
-+ pending = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_INT_STATUS) &
-+ __raw_readl(apc->ctrl_base + AR724X_PCI_REG_INT_MASK);
-
- if (pending & AR724X_PCI_INT_DEV0)
-- generic_handle_irq(apc->irq_base + 0);
--
-+ generic_handle_irq(irq_linear_revmap(apc->domain, 1));
- else
- spurious_interrupt();
-+ chained_irq_exit(chip, desc);
- }
-
- static void ar724x_pci_irq_unmask(struct irq_data *d)
- {
- struct ar724x_pci_controller *apc;
- void __iomem *base;
-- int offset;
- u32 t;
-
- apc = irq_data_get_irq_chip_data(d);
- base = apc->ctrl_base;
-- offset = apc->irq_base - d->irq;
-
-- switch (offset) {
-+ switch (irq_linear_revmap(apc->domain, d->irq)) {
- case 0:
- t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
- __raw_writel(t | AR724X_PCI_INT_DEV0,
-@@ -270,14 +272,12 @@ static void ar724x_pci_irq_mask(struct i
- {
- struct ar724x_pci_controller *apc;
- void __iomem *base;
-- int offset;
- u32 t;
-
- apc = irq_data_get_irq_chip_data(d);
- base = apc->ctrl_base;
-- offset = apc->irq_base - d->irq;
-
-- switch (offset) {
-+ switch (irq_linear_revmap(apc->domain, d->irq)) {
- case 0:
- t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
- __raw_writel(t & ~AR724X_PCI_INT_DEV0,
-@@ -302,26 +302,34 @@ static struct irq_chip ar724x_pci_irq_ch
- .irq_mask_ack = ar724x_pci_irq_mask,
- };
-
-+static int ar724x_pci_irq_map(struct irq_domain *d,
-+ unsigned int irq, irq_hw_number_t hw)
-+{
-+ struct ar724x_pci_controller *apc = d->host_data;
-+
-+ irq_set_chip_and_handler(irq, &ar724x_pci_irq_chip, handle_level_irq);
-+ irq_set_chip_data(irq, apc);
-+
-+ return 0;
-+}
-+
-+static const struct irq_domain_ops ar724x_pci_domain_ops = {
-+ .xlate = irq_domain_xlate_onecell,
-+ .map = ar724x_pci_irq_map,
-+};
-+
- static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc,
- int id)
- {
- void __iomem *base;
-- int i;
-
- base = apc->ctrl_base;
-
- __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
- __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
-
-- apc->irq_base = ATH79_PCI_IRQ_BASE + (id * AR724X_PCI_IRQ_COUNT);
--
-- for (i = apc->irq_base;
-- i < apc->irq_base + AR724X_PCI_IRQ_COUNT; i++) {
-- irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
-- handle_level_irq);
-- irq_set_chip_data(i, apc);
-- }
--
-+ apc->domain = irq_domain_add_linear(apc->np, 2,
-+ &ar724x_pci_domain_ops, apc);
- irq_set_chained_handler_and_data(apc->irq, ar724x_pci_irq_handler,
- apc);
- }
-@@ -391,29 +399,11 @@ static int ar724x_pci_probe(struct platf
- if (apc->irq < 0)
- return -EINVAL;
-
-- res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base");
-- if (!res)
-- return -EINVAL;
--
-- apc->io_res.parent = res;
-- apc->io_res.name = "PCI IO space";
-- apc->io_res.start = res->start;
-- apc->io_res.end = res->end;
-- apc->io_res.flags = IORESOURCE_IO;
--
-- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base");
-- if (!res)
-- return -EINVAL;
--
-- apc->mem_res.parent = res;
-- apc->mem_res.name = "PCI memory space";
-- apc->mem_res.start = res->start;
-- apc->mem_res.end = res->end;
-- apc->mem_res.flags = IORESOURCE_MEM;
--
-+ apc->np = pdev->dev.of_node;
- apc->pci_controller.pci_ops = &ar724x_pci_ops;
- apc->pci_controller.io_resource = &apc->io_res;
- apc->pci_controller.mem_resource = &apc->mem_res;
-+ pci_load_of_ranges(&apc->pci_controller, pdev->dev.of_node);
-
- /*
- * Do the full PCIE Root Complex Initialization Sequence if the PCIe
-@@ -435,10 +425,16 @@ static int ar724x_pci_probe(struct platf
- return 0;
- }
-
-+static const struct of_device_id ar724x_pci_ids[] = {
-+ { .compatible = "qcom,ar7240-pci" },
-+ {},
-+};
-+
- static struct platform_driver ar724x_pci_driver = {
- .probe = ar724x_pci_probe,
- .driver = {
- .name = "ar724x-pci",
-+ .of_match_table = of_match_ptr(ar724x_pci_ids),
- },
- };
-
+++ /dev/null
-From 3fc8585cf76022dba7496627074d42af88c30718 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Sat, 23 Jun 2018 15:16:55 +0200
-Subject: [PATCH 32/33] MIPS: ath79: sanitize symbols
-
-We no longer need to select which SoCs are supported as the whole arch
-code is always built. So lets drop all the SoC symbols
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- arch/mips/Kconfig | 2 ++
- arch/mips/ath79/Kconfig | 44 +++++---------------------------------------
- arch/mips/pci/Makefile | 2 +-
- 3 files changed, 8 insertions(+), 40 deletions(-)
-
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -220,6 +220,8 @@ config ATH79
- select SYS_SUPPORTS_BIG_ENDIAN
- select SYS_SUPPORTS_MIPS16
- select SYS_SUPPORTS_ZBOOT_UART_PROM
-+ select HAVE_PCI
-+ select USB_ARCH_HAS_EHCI
- select USE_OF
- select USB_EHCI_ROOT_HUB_TT if USB_EHCI_HCD_PLATFORM
- help
---- a/arch/mips/ath79/Kconfig
-+++ b/arch/mips/ath79/Kconfig
-@@ -1,48 +1,14 @@
- # SPDX-License-Identifier: GPL-2.0
- if ATH79
-
--config SOC_AR71XX
-- select HAVE_PCI
-- def_bool n
--
--config SOC_AR724X
-- select HAVE_PCI
-- select PCI_AR724X if PCI
-- def_bool n
--
--config SOC_AR913X
-- def_bool n
--
--config SOC_AR933X
-- def_bool n
--
--config SOC_AR934X
-- select HAVE_PCI
-- select PCI_AR724X if PCI
-- def_bool n
--
--config SOC_QCA955X
-- select HAVE_PCI
-- select PCI_AR724X if PCI
-+config PCI_AR71XX
-+ bool "PCI support for AR7100 type SoCs"
-+ depends on PCI
- def_bool n
-
- config PCI_AR724X
-- def_bool n
--
--config ATH79_DEV_GPIO_BUTTONS
-- def_bool n
--
--config ATH79_DEV_LEDS_GPIO
-- def_bool n
--
--config ATH79_DEV_SPI
-- def_bool n
--
--config ATH79_DEV_USB
-- def_bool n
--
--config ATH79_DEV_WMAC
-- depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA955X)
-+ bool "PCI support for AR724x type SoCs"
-+ depends on PCI
- def_bool n
-
- endif
---- a/arch/mips/pci/Makefile
-+++ b/arch/mips/pci/Makefile
-@@ -23,7 +23,7 @@ obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o
- ops-bcm63xx.o
- obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o
- obj-$(CONFIG_PCI_AR2315) += pci-ar2315.o
--obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o
-+obj-$(CONFIG_PCI_AR71XX) += pci-ar71xx.o
- obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o
- obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o
- obj-$(CONFIG_PCI_XTALK_BRIDGE) += pci-xtalk-bridge.o
+++ /dev/null
-From c4e197bbcecc7233aa9e553e7047fa50e4e1fe77 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Mon, 25 Jun 2018 15:52:34 +0200
-Subject: [PATCH 33/33] spi: ath79: drop pdata support
-
-The target is being converted to pure OF. We can therefore drop all of the
-platform data code from the driver.
-
-Cc: linux-spi@vger.kernel.org
-Acked-by: Mark Brown <broonie@kernel.org>
-Signed-off-by: John Crispin <john@phrozen.org>
----
- include/linux/platform_data/spi-ath79.h | 16 -------------------
- drivers/spi/spi-ath79.c | 8 --------
- 2 files changed, 27 deletions(-)
- delete mode 100644 arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
-
---- a/include/linux/platform_data/spi-ath79.h
-+++ /dev/null
-@@ -1,16 +0,0 @@
--/* SPDX-License-Identifier: GPL-2.0-only */
--/*
-- * Platform data definition for Atheros AR71XX/AR724X/AR913X SPI controller
-- *
-- * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
-- */
--
--#ifndef _ATH79_SPI_PLATFORM_H
--#define _ATH79_SPI_PLATFORM_H
--
--struct ath79_spi_platform_data {
-- unsigned bus_num;
-- unsigned num_chipselect;
--};
--
--#endif /* _ATH79_SPI_PLATFORM_H */
---- a/drivers/spi/spi-ath79.c
-+++ b/drivers/spi/spi-ath79.c
-@@ -19,7 +19,6 @@
- #include <linux/bitops.h>
- #include <linux/clk.h>
- #include <linux/err.h>
--#include <linux/platform_data/spi-ath79.h>
-
- #define DRV_NAME "ath79-spi"
-
-@@ -138,7 +137,6 @@ static int ath79_spi_probe(struct platfo
- {
- struct spi_master *master;
- struct ath79_spi *sp;
-- struct ath79_spi_platform_data *pdata;
- unsigned long rate;
- int ret;
-
-@@ -152,15 +150,9 @@ static int ath79_spi_probe(struct platfo
- master->dev.of_node = pdev->dev.of_node;
- platform_set_drvdata(pdev, sp);
-
-- pdata = dev_get_platdata(&pdev->dev);
--
- master->use_gpio_descriptors = true;
- master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
- master->flags = SPI_MASTER_GPIO_SS;
-- if (pdata) {
-- master->bus_num = pdata->bus_num;
-- master->num_chipselect = pdata->num_chipselect;
-- }
-
- sp->bitbang.master = master;
- sp->bitbang.chipselect = ath79_spi_chipselect;
+++ /dev/null
---- a/arch/mips/ath79/common.c
-+++ b/arch/mips/ath79/common.c
-@@ -31,11 +31,13 @@ EXPORT_SYMBOL_GPL(ath79_ddr_freq);
-
- enum ath79_soc_type ath79_soc;
- unsigned int ath79_soc_rev;
-+EXPORT_SYMBOL_GPL(ath79_soc_rev);
-
- void __iomem *ath79_pll_base;
- void __iomem *ath79_reset_base;
- EXPORT_SYMBOL_GPL(ath79_reset_base);
--static void __iomem *ath79_ddr_base;
-+void __iomem *ath79_ddr_base;
-+EXPORT_SYMBOL_GPL(ath79_ddr_base);
- static void __iomem *ath79_ddr_wb_flush_base;
- static void __iomem *ath79_ddr_pci_win_base;
-
---- a/arch/mips/include/asm/mach-ath79/ath79.h
-+++ b/arch/mips/include/asm/mach-ath79/ath79.h
-@@ -149,6 +149,7 @@ void ath79_ddr_wb_flush(unsigned int reg
- void ath79_ddr_set_pci_windows(void);
-
- extern void __iomem *ath79_pll_base;
-+extern void __iomem *ath79_ddr_base;
- extern void __iomem *ath79_reset_base;
-
- static inline void ath79_pll_wr(unsigned reg, u32 val)
+++ /dev/null
-From 4267880319bc1a2270d352e0ded6d6386242a7ef Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 12 Aug 2014 20:49:27 +0200
-Subject: [PATCH 24/53] GPIO: add named gpio exports
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/gpio/gpiolib-of.c | 68 +++++++++++++++++++++++++++++++++++++++++
- drivers/gpio/gpiolib-sysfs.c | 10 +++++-
- include/asm-generic/gpio.h | 6 ++++
- include/linux/gpio/consumer.h | 8 +++++
- 4 files changed, 91 insertions(+), 1 deletion(-)
-
---- a/drivers/gpio/gpiolib-of.c
-+++ b/drivers/gpio/gpiolib-of.c
-@@ -19,6 +19,8 @@
- #include <linux/pinctrl/pinctrl.h>
- #include <linux/slab.h>
- #include <linux/gpio/machine.h>
-+#include <linux/init.h>
-+#include <linux/platform_device.h>
-
- #include "gpiolib.h"
- #include "gpiolib-of.h"
-@@ -915,3 +917,68 @@ void of_gpiochip_remove(struct gpio_chip
- {
- of_node_put(chip->of_node);
- }
-+
-+static struct of_device_id gpio_export_ids[] = {
-+ { .compatible = "gpio-export" },
-+ { /* sentinel */ }
-+};
-+
-+static int of_gpio_export_probe(struct platform_device *pdev)
-+{
-+ struct device_node *np = pdev->dev.of_node;
-+ struct device_node *cnp;
-+ u32 val;
-+ int nb = 0;
-+
-+ for_each_child_of_node(np, cnp) {
-+ const char *name = NULL;
-+ int gpio;
-+ bool dmc;
-+ int max_gpio = 1;
-+ int i;
-+
-+ of_property_read_string(cnp, "gpio-export,name", &name);
-+
-+ if (!name)
-+ max_gpio = of_gpio_count(cnp);
-+
-+ for (i = 0; i < max_gpio; i++) {
-+ unsigned flags = 0;
-+ enum of_gpio_flags of_flags;
-+
-+ gpio = of_get_gpio_flags(cnp, i, &of_flags);
-+ if (!gpio_is_valid(gpio))
-+ return gpio;
-+
-+ if (of_flags == OF_GPIO_ACTIVE_LOW)
-+ flags |= GPIOF_ACTIVE_LOW;
-+
-+ if (!of_property_read_u32(cnp, "gpio-export,output", &val))
-+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
-+ else
-+ flags |= GPIOF_IN;
-+
-+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
-+ continue;
-+
-+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
-+ gpio_export_with_name(gpio, dmc, name);
-+ nb++;
-+ }
-+ }
-+
-+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver gpio_export_driver = {
-+ .driver = {
-+ .name = "gpio-export",
-+ .owner = THIS_MODULE,
-+ .of_match_table = of_match_ptr(gpio_export_ids),
-+ },
-+ .probe = of_gpio_export_probe,
-+};
-+
-+module_platform_driver(gpio_export_driver);
---- a/drivers/gpio/gpiolib-sysfs.c
-+++ b/drivers/gpio/gpiolib-sysfs.c
-@@ -571,7 +571,7 @@ static struct class gpio_class = {
- *
- * Returns zero on success, else an error.
- */
--int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
-+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
- {
- struct gpio_chip *chip;
- struct gpio_device *gdev;
-@@ -633,6 +633,8 @@ int gpiod_export(struct gpio_desc *desc,
- offset = gpio_chip_hwgpio(desc);
- if (chip->names && chip->names[offset])
- ioname = chip->names[offset];
-+ if (name)
-+ ioname = name;
-
- dev = device_create_with_groups(&gpio_class, &gdev->dev,
- MKDEV(0, 0), data, gpio_groups,
-@@ -654,6 +656,12 @@ err_unlock:
- gpiod_dbg(desc, "%s: status %d\n", __func__, status);
- return status;
- }
-+EXPORT_SYMBOL_GPL(__gpiod_export);
-+
-+int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
-+{
-+ return __gpiod_export(desc, direction_may_change, NULL);
-+}
- EXPORT_SYMBOL_GPL(gpiod_export);
-
- static int match_export(struct device *dev, const void *desc)
---- a/include/asm-generic/gpio.h
-+++ b/include/asm-generic/gpio.h
-@@ -127,6 +127,12 @@ static inline int gpio_export(unsigned g
- return gpiod_export(gpio_to_desc(gpio), direction_may_change);
- }
-
-+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
-+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
-+{
-+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name);
-+}
-+
- static inline int gpio_export_link(struct device *dev, const char *name,
- unsigned gpio)
- {
---- a/include/linux/gpio/consumer.h
-+++ b/include/linux/gpio/consumer.h
-@@ -668,6 +668,7 @@ static inline void devm_acpi_dev_remove_
-
- #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
-
-+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
- int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
- int gpiod_export_link(struct device *dev, const char *name,
- struct gpio_desc *desc);
-@@ -675,6 +676,13 @@ void gpiod_unexport(struct gpio_desc *de
-
- #else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
-
-+static inline int _gpiod_export(struct gpio_desc *desc,
-+ bool direction_may_change,
-+ const char *name)
-+{
-+ return -ENOSYS;
-+}
-+
- static inline int gpiod_export(struct gpio_desc *desc,
- bool direction_may_change)
- {
+++ /dev/null
---- a/arch/mips/pci/pci-ar71xx.c
-+++ b/arch/mips/pci/pci-ar71xx.c
-@@ -51,11 +51,9 @@
- struct ar71xx_pci_controller {
- struct device_node *np;
- void __iomem *cfg_base;
-- int irq;
- struct pci_controller pci_ctrl;
- struct resource io_res;
- struct resource mem_res;
-- struct irq_domain *domain;
- };
-
- /* Byte lane enable bits */
-@@ -227,104 +225,6 @@ static struct pci_ops ar71xx_pci_ops = {
- .write = ar71xx_pci_write_config,
- };
-
--static void ar71xx_pci_irq_handler(struct irq_desc *desc)
--{
-- void __iomem *base = ath79_reset_base;
-- struct irq_chip *chip = irq_desc_get_chip(desc);
-- struct ar71xx_pci_controller *apc = irq_desc_get_handler_data(desc);
-- u32 pending;
--
-- chained_irq_enter(chip, desc);
-- pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) &
-- __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
--
-- if (pending & AR71XX_PCI_INT_DEV0)
-- generic_handle_irq(irq_linear_revmap(apc->domain, 1));
--
-- else if (pending & AR71XX_PCI_INT_DEV1)
-- generic_handle_irq(irq_linear_revmap(apc->domain, 2));
--
-- else if (pending & AR71XX_PCI_INT_DEV2)
-- generic_handle_irq(irq_linear_revmap(apc->domain, 3));
--
-- else if (pending & AR71XX_PCI_INT_CORE)
-- generic_handle_irq(irq_linear_revmap(apc->domain, 4));
--
-- else
-- spurious_interrupt();
-- chained_irq_exit(chip, desc);
--}
--
--static void ar71xx_pci_irq_unmask(struct irq_data *d)
--{
-- struct ar71xx_pci_controller *apc;
-- unsigned int irq;
-- void __iomem *base = ath79_reset_base;
-- u32 t;
--
-- apc = irq_data_get_irq_chip_data(d);
-- irq = irq_linear_revmap(apc->domain, d->irq);
--
-- t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-- __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
--
-- /* flush write */
-- __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
--}
--
--static void ar71xx_pci_irq_mask(struct irq_data *d)
--{
-- struct ar71xx_pci_controller *apc;
-- unsigned int irq;
-- void __iomem *base = ath79_reset_base;
-- u32 t;
--
-- apc = irq_data_get_irq_chip_data(d);
-- irq = irq_linear_revmap(apc->domain, d->irq);
--
-- t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-- __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
--
-- /* flush write */
-- __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
--}
--
--static struct irq_chip ar71xx_pci_irq_chip = {
-- .name = "AR71XX PCI",
-- .irq_mask = ar71xx_pci_irq_mask,
-- .irq_unmask = ar71xx_pci_irq_unmask,
-- .irq_mask_ack = ar71xx_pci_irq_mask,
--};
--
--static int ar71xx_pci_irq_map(struct irq_domain *d,
-- unsigned int irq, irq_hw_number_t hw)
--{
-- struct ar71xx_pci_controller *apc = d->host_data;
--
-- irq_set_chip_and_handler(irq, &ar71xx_pci_irq_chip, handle_level_irq);
-- irq_set_chip_data(irq, apc);
--
-- return 0;
--}
--
--static const struct irq_domain_ops ar71xx_pci_domain_ops = {
-- .xlate = irq_domain_xlate_onecell,
-- .map = ar71xx_pci_irq_map,
--};
--
--static void ar71xx_pci_irq_init(struct ar71xx_pci_controller *apc)
--{
-- void __iomem *base = ath79_reset_base;
--
-- __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-- __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS);
--
-- apc->domain = irq_domain_add_linear(apc->np, AR71XX_PCI_IRQ_COUNT,
-- &ar71xx_pci_domain_ops, apc);
-- irq_set_chained_handler_and_data(apc->irq, ar71xx_pci_irq_handler,
-- apc);
--}
--
- static void ar71xx_pci_reset(void)
- {
- ath79_device_reset_set(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE);
-@@ -358,10 +258,6 @@ static int ar71xx_pci_probe(struct platf
- if (IS_ERR(apc->cfg_base))
- return PTR_ERR(apc->cfg_base);
-
-- apc->irq = platform_get_irq(pdev, 0);
-- if (apc->irq < 0)
-- return -EINVAL;
--
- ar71xx_pci_reset();
-
- /* setup COMMAND register */
-@@ -372,8 +268,6 @@ static int ar71xx_pci_probe(struct platf
- /* clear bus errors */
- ar71xx_pci_check_error(apc, 1);
-
-- ar71xx_pci_irq_init(apc);
--
- apc->np = pdev->dev.of_node;
- apc->pci_ctrl.pci_ops = &ar71xx_pci_ops;
- apc->pci_ctrl.mem_resource = &apc->mem_res;
+++ /dev/null
-commit f3ffac90bc7266b7d917616f3233f58e8c08a196
-Author: Christian Lamparter <chunkeey@gmail.com>
-Date: Fri Aug 10 23:24:47 2018 +0200
-
- ath79: gmac: add parsers for rxd(v)- and tx(d|en)-delay for AR9344
-
- Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-
---- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -1226,6 +1226,10 @@
- #define AR934X_ETH_CFG_RDV_DELAY BIT(16)
- #define AR934X_ETH_CFG_RDV_DELAY_MASK 0x3
- #define AR934X_ETH_CFG_RDV_DELAY_SHIFT 16
-+#define AR934X_ETH_CFG_TXD_DELAY_MASK 0x3
-+#define AR934X_ETH_CFG_TXD_DELAY_SHIFT 18
-+#define AR934X_ETH_CFG_TXE_DELAY_MASK 0x3
-+#define AR934X_ETH_CFG_TXE_DELAY_SHIFT 20
-
- /*
- * QCA953X GMAC Interface
+++ /dev/null
-From 60efe35257b063ce584968f9f80b437030ce6ba6 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Mon, 18 Mar 2019 00:54:06 +0100
-Subject: [PATCH] MIPS: ath79: add missing QCA955x GMAC registers
-
-This adds missing GMAC register definitions for the Qualcomm Atheros
-QCA955X series MIPS SoCs.
-
-They originate from the platforms U-Boot code and the AVM FRITZ!WLAN
-Repeater 450E's GPL tarball.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- .../mips/include/asm/mach-ath79/ar71xx_regs.h | 54 +++++++++++++++++++
- 1 file changed, 54 insertions(+)
-
---- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -1246,7 +1246,12 @@
- */
-
- #define QCA955X_GMAC_REG_ETH_CFG 0x00
-+#define QCA955X_GMAC_REG_SGMII_RESET 0x14
- #define QCA955X_GMAC_REG_SGMII_SERDES 0x18
-+#define QCA955X_GMAC_REG_MR_AN_CONTROL 0x1c
-+#define QCA955X_GMAC_REG_MR_AN_STATUS 0x20
-+#define QCA955X_GMAC_REG_SGMII_CONFIG 0x34
-+#define QCA955X_GMAC_REG_SGMII_DEBUG 0x58
-
- #define QCA955X_ETH_CFG_RGMII_EN BIT(0)
- #define QCA955X_ETH_CFG_MII_GE0 BIT(1)
-@@ -1268,9 +1273,58 @@
- #define QCA955X_ETH_CFG_TXE_DELAY_MASK 0x3
- #define QCA955X_ETH_CFG_TXE_DELAY_SHIFT 20
-
-+#define QCA955X_SGMII_RESET_RX_CLK_N_RESET 0
-+#define QCA955X_SGMII_RESET_RX_CLK_N BIT(0)
-+#define QCA955X_SGMII_RESET_TX_CLK_N BIT(1)
-+#define QCA955X_SGMII_RESET_RX_125M_N BIT(2)
-+#define QCA955X_SGMII_RESET_TX_125M_N BIT(3)
-+#define QCA955X_SGMII_RESET_HW_RX_125M_N BIT(4)
-+
- #define QCA955X_SGMII_SERDES_LOCK_DETECT_STATUS BIT(15)
- #define QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT 23
- #define QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK 0xf
-+
-+#define QCA955X_MR_AN_CONTROL_SPEED_SEL1 BIT(6)
-+#define QCA955X_MR_AN_CONTROL_DUPLEX_MODE BIT(8)
-+#define QCA955X_MR_AN_CONTROL_RESTART_AN BIT(9)
-+#define QCA955X_MR_AN_CONTROL_POWER_DOWN BIT(11)
-+#define QCA955X_MR_AN_CONTROL_AN_ENABLE BIT(12)
-+#define QCA955X_MR_AN_CONTROL_SPEED_SEL0 BIT(13)
-+#define QCA955X_MR_AN_CONTROL_LOOPBACK BIT(14)
-+#define QCA955X_MR_AN_CONTROL_PHY_RESET BIT(15)
-+
-+#define QCA955X_MR_AN_STATUS_EXT_CAP BIT(0)
-+#define QCA955X_MR_AN_STATUS_LINK_UP BIT(2)
-+#define QCA955X_MR_AN_STATUS_AN_ABILITY BIT(3)
-+#define QCA955X_MR_AN_STATUS_REMOTE_FAULT BIT(4)
-+#define QCA955X_MR_AN_STATUS_AN_COMPLETE BIT(5)
-+#define QCA955X_MR_AN_STATUS_NO_PREAMBLE BIT(6)
-+#define QCA955X_MR_AN_STATUS_BASE_PAGE BIT(7)
-+
-+#define QCA955X_SGMII_CONFIG_MODE_CTRL_SHIFT 0
-+#define QCA955X_SGMII_CONFIG_MODE_CTRL_MASK 0x7
-+#define QCA955X_SGMII_CONFIG_ENABLE_SGMII_TX_PAUSE BIT(3)
-+#define QCA955X_SGMII_CONFIG_MR_REG4_CHANGED BIT(4)
-+#define QCA955X_SGMII_CONFIG_FORCE_SPEED BIT(5)
-+#define QCA955X_SGMII_CONFIG_SPEED_SHIFT 6
-+#define QCA955X_SGMII_CONFIG_SPEED_MASK 0xc0
-+#define QCA955X_SGMII_CONFIG_REMOTE_PHY_LOOPBACK BIT(8)
-+#define QCA955X_SGMII_CONFIG_NEXT_PAGE_LOADED BIT(9)
-+#define QCA955X_SGMII_CONFIG_MDIO_ENABLE BIT(10)
-+#define QCA955X_SGMII_CONFIG_MDIO_PULSE BIT(11)
-+#define QCA955X_SGMII_CONFIG_MDIO_COMPLETE BIT(12)
-+#define QCA955X_SGMII_CONFIG_PRBS_ENABLE BIT(13)
-+#define QCA955X_SGMII_CONFIG_BERT_ENABLE BIT(14)
-+
-+#define QCA955X_SGMII_DEBUG_TX_STATE_MASK 0xff
-+#define QCA955X_SGMII_DEBUG_TX_STATE_SHIFT 0
-+#define QCA955X_SGMII_DEBUG_RX_STATE_MASK 0xff00
-+#define QCA955X_SGMII_DEBUG_RX_STATE_SHIFT 8
-+#define QCA955X_SGMII_DEBUG_RX_SYNC_STATE_MASK 0xff0000
-+#define QCA955X_SGMII_DEBUG_RX_SYNC_STATE_SHIFT 16
-+#define QCA955X_SGMII_DEBUG_ARB_STATE_MASK 0xf000000
-+#define QCA955X_SGMII_DEBUG_ARB_STATE_SHIFT 24
-+
- /*
- * QCA956X GMAC Interface
- */
+++ /dev/null
---- a/arch/mips/ath79/clock.c
-+++ b/arch/mips/ath79/clock.c
-@@ -40,6 +40,7 @@ static const char * const clk_names[ATH7
- [ATH79_CLK_AHB] = "ahb",
- [ATH79_CLK_REF] = "ref",
- [ATH79_CLK_MDIO] = "mdio",
-+ [ATH79_CLK_UART1] = "uart1",
- };
-
- static const char * __init ath79_clk_name(int type)
-@@ -344,6 +345,9 @@ static void __init ar934x_clocks_init(vo
- if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL)
- ath79_set_clk(ATH79_CLK_MDIO, 100 * 1000 * 1000);
-
-+ if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_UART1_CLK_SEL)
-+ ath79_set_clk(ATH79_CLK_UART1, 100 * 1000 * 1000);
-+
- iounmap(dpll_base);
- }
-
-@@ -649,6 +653,9 @@ static void __init ath79_clocks_init_dt(
- if (!clks[ATH79_CLK_MDIO])
- clks[ATH79_CLK_MDIO] = clks[ATH79_CLK_REF];
-
-+ if (!clks[ATH79_CLK_UART1])
-+ clks[ATH79_CLK_UART1] = clks[ATH79_CLK_REF];
-+
- if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) {
- pr_err("%pOF: could not register clk provider\n", np);
- goto err_iounmap;
---- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -348,6 +348,7 @@
- #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
-
- #define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6)
-+#define AR934X_PLL_SWITCH_CLOCK_CONTROL_UART1_CLK_SEL BIT(7)
-
- #define QCA953X_PLL_CPU_CONFIG_REG 0x00
- #define QCA953X_PLL_DDR_CONFIG_REG 0x04
---- a/include/dt-bindings/clock/ath79-clk.h
-+++ b/include/dt-bindings/clock/ath79-clk.h
-@@ -11,7 +11,8 @@
- #define ATH79_CLK_AHB 2
- #define ATH79_CLK_REF 3
- #define ATH79_CLK_MDIO 4
-+#define ATH79_CLK_UART1 5
-
--#define ATH79_CLK_END 5
-+#define ATH79_CLK_END 6
-
- #endif /* __DT_BINDINGS_ATH79_CLK_H */
+++ /dev/null
-HACK: register the GPIO driver earlier to ensure that gpio_request calls
-from mach files succeed.
-
---- a/drivers/gpio/gpio-ath79.c
-+++ b/drivers/gpio/gpio-ath79.c
-@@ -310,7 +310,11 @@ static struct platform_driver ath79_gpio
- .probe = ath79_gpio_probe,
- };
-
--module_platform_driver(ath79_gpio_driver);
-+static int __init ath79_gpio_init(void)
-+{
-+ return platform_driver_register(&ath79_gpio_driver);
-+}
-+postcore_initcall(ath79_gpio_init);
-
- MODULE_DESCRIPTION("Atheros AR71XX/AR724X/AR913X GPIO API support");
- MODULE_LICENSE("GPL v2");
+++ /dev/null
---- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -1376,5 +1376,6 @@
-
- #define QCA956X_SGMII_CONFIG_MODE_CTRL_SHIFT 0
- #define QCA956X_SGMII_CONFIG_MODE_CTRL_MASK 0x7
-+#define QCA956X_SGMII_CONFIG_MODE_CTRL_SGMII_MAC 0x2
-
- #endif /* __ASM_MACH_AR71XX_REGS_H */
+++ /dev/null
-From 7e161c423a232ef7ddf6c11b09ebe471dd5a23cf Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Wed, 5 Feb 2020 18:25:37 +0800
-Subject: [PATCH v4 1/2] spi: add driver for ar934x spi controller
-
-This patch adds driver for SPI controller found in Qualcomm Atheros
-AR934x/QCA95xx SoCs.
-This controller is a superset of the already supported qca,ar7100-spi.
-Besides the bit-bang mode in spi-ath79.c, this new controller added
-a new "shift register" mode, allowing faster spi operations.
-
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
----
- drivers/spi/Kconfig | 7 ++
- drivers/spi/Makefile | 1 +
- drivers/spi/spi-ar934x.c | 235 +++++++++++++++++++++++++++++++++++++++
- 3 files changed, 243 insertions(+)
- create mode 100644 drivers/spi/spi-ar934x.c
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -62,6 +62,13 @@ config SPI_ALTERA
- help
- This is the driver for the Altera SPI Controller.
-
-+config SPI_AR934X
-+ tristate "Qualcomm Atheros AR934X/QCA95XX SPI controller driver"
-+ depends on ATH79 || COMPILE_TEST
-+ help
-+ This enables support for the SPI controller present on the
-+ Qualcomm Atheros AR934X/QCA95XX SoCs.
-+
- config SPI_ATH79
- tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver"
- depends on ATH79 || COMPILE_TEST
---- a/drivers/spi/Makefile
-+++ b/drivers/spi/Makefile
-@@ -14,6 +14,7 @@ obj-$(CONFIG_SPI_LOOPBACK_TEST) += spi-
-
- # SPI master controller drivers (bus)
- obj-$(CONFIG_SPI_ALTERA) += spi-altera.o
-+obj-$(CONFIG_SPI_AR934X) += spi-ar934x.o
- obj-$(CONFIG_SPI_ARMADA_3700) += spi-armada-3700.o
- obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o
- obj-$(CONFIG_SPI_ATMEL_QUADSPI) += atmel-quadspi.o
---- /dev/null
-+++ b/drivers/spi/spi-ar934x.c
-@@ -0,0 +1,235 @@
-+// SPDX-License-Identifier: GPL-2.0
-+//
-+// SPI controller driver for Qualcomm Atheros AR934x/QCA95xx SoCs
-+//
-+// Copyright (C) 2020 Chuanhong Guo <gch981213@gmail.com>
-+//
-+// Based on spi-mt7621.c:
-+// Copyright (C) 2011 Sergiy <piratfm@gmail.com>
-+// Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
-+// Copyright (C) 2014-2015 Felix Fietkau <nbd@nbd.name>
-+
-+#include <linux/clk.h>
-+#include <linux/io.h>
-+#include <linux/iopoll.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of_device.h>
-+#include <linux/spi/spi.h>
-+
-+#define DRIVER_NAME "spi-ar934x"
-+
-+#define AR934X_SPI_REG_FS 0x00
-+#define AR934X_SPI_ENABLE BIT(0)
-+
-+#define AR934X_SPI_REG_IOC 0x08
-+#define AR934X_SPI_IOC_INITVAL 0x70000
-+
-+#define AR934X_SPI_REG_CTRL 0x04
-+#define AR934X_SPI_CLK_MASK GENMASK(5, 0)
-+
-+#define AR934X_SPI_DATAOUT 0x10
-+
-+#define AR934X_SPI_REG_SHIFT_CTRL 0x14
-+#define AR934X_SPI_SHIFT_EN BIT(31)
-+#define AR934X_SPI_SHIFT_CS(n) BIT(28 + (n))
-+#define AR934X_SPI_SHIFT_TERM 26
-+#define AR934X_SPI_SHIFT_VAL(cs, term, count) \
-+ (AR934X_SPI_SHIFT_EN | AR934X_SPI_SHIFT_CS(cs) | \
-+ (term) << AR934X_SPI_SHIFT_TERM | (count))
-+
-+#define AR934X_SPI_DATAIN 0x18
-+
-+struct ar934x_spi {
-+ struct spi_controller *ctlr;
-+ void __iomem *base;
-+ struct clk *clk;
-+ unsigned int clk_freq;
-+};
-+
-+static inline int ar934x_spi_clk_div(struct ar934x_spi *sp, unsigned int freq)
-+{
-+ int div = DIV_ROUND_UP(sp->clk_freq, freq * 2) - 1;
-+
-+ if (div < 0)
-+ return 0;
-+ else if (div > AR934X_SPI_CLK_MASK)
-+ return -EINVAL;
-+ else
-+ return div;
-+}
-+
-+static int ar934x_spi_setup(struct spi_device *spi)
-+{
-+ struct ar934x_spi *sp = spi_controller_get_devdata(spi->master);
-+
-+ if ((spi->max_speed_hz == 0) ||
-+ (spi->max_speed_hz > (sp->clk_freq / 2))) {
-+ spi->max_speed_hz = sp->clk_freq / 2;
-+ } else if (spi->max_speed_hz < (sp->clk_freq / 128)) {
-+ dev_err(&spi->dev, "spi clock is too low\n");
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int ar934x_spi_transfer_one_message(struct spi_controller *master,
-+ struct spi_message *m)
-+{
-+ struct ar934x_spi *sp = spi_controller_get_devdata(master);
-+ struct spi_transfer *t = NULL;
-+ struct spi_device *spi = m->spi;
-+ unsigned long trx_done, trx_cur;
-+ int stat = 0;
-+ u8 term = 0;
-+ int div, i;
-+ u32 reg;
-+ const u8 *tx_buf;
-+ u8 *buf;
-+
-+ m->actual_length = 0;
-+ list_for_each_entry(t, &m->transfers, transfer_list) {
-+ if (t->speed_hz)
-+ div = ar934x_spi_clk_div(sp, t->speed_hz);
-+ else
-+ div = ar934x_spi_clk_div(sp, spi->max_speed_hz);
-+ if (div < 0) {
-+ stat = -EIO;
-+ goto msg_done;
-+ }
-+
-+ reg = ioread32(sp->base + AR934X_SPI_REG_CTRL);
-+ reg &= ~AR934X_SPI_CLK_MASK;
-+ reg |= div;
-+ iowrite32(reg, sp->base + AR934X_SPI_REG_CTRL);
-+ iowrite32(0, sp->base + AR934X_SPI_DATAOUT);
-+
-+ for (trx_done = 0; trx_done < t->len; trx_done += 4) {
-+ trx_cur = t->len - trx_done;
-+ if (trx_cur > 4)
-+ trx_cur = 4;
-+ else if (list_is_last(&t->transfer_list, &m->transfers))
-+ term = 1;
-+
-+ if (t->tx_buf) {
-+ tx_buf = t->tx_buf + trx_done;
-+ reg = tx_buf[0];
-+ for (i = 1; i < trx_cur; i++)
-+ reg = reg << 8 | tx_buf[i];
-+ iowrite32(reg, sp->base + AR934X_SPI_DATAOUT);
-+ }
-+
-+ reg = AR934X_SPI_SHIFT_VAL(spi->chip_select, term,
-+ trx_cur * 8);
-+ iowrite32(reg, sp->base + AR934X_SPI_REG_SHIFT_CTRL);
-+ stat = readl_poll_timeout(
-+ sp->base + AR934X_SPI_REG_SHIFT_CTRL, reg,
-+ !(reg & AR934X_SPI_SHIFT_EN), 0, 5);
-+ if (stat < 0)
-+ goto msg_done;
-+
-+ if (t->rx_buf) {
-+ reg = ioread32(sp->base + AR934X_SPI_DATAIN);
-+ buf = t->rx_buf + trx_done;
-+ for (i = 0; i < trx_cur; i++) {
-+ buf[trx_cur - i - 1] = reg & 0xff;
-+ reg >>= 8;
-+ }
-+ }
-+ }
-+ m->actual_length += t->len;
-+ }
-+
-+msg_done:
-+ m->status = stat;
-+ spi_finalize_current_message(master);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id ar934x_spi_match[] = {
-+ { .compatible = "qca,ar934x-spi" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, ar934x_spi_match);
-+
-+static int ar934x_spi_probe(struct platform_device *pdev)
-+{
-+ struct spi_controller *ctlr;
-+ struct ar934x_spi *sp;
-+ void __iomem *base;
-+ struct clk *clk;
-+ int ret;
-+
-+ base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ clk = devm_clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(clk)) {
-+ dev_err(&pdev->dev, "failed to get clock\n");
-+ return PTR_ERR(clk);
-+ }
-+
-+ ret = clk_prepare_enable(clk);
-+ if (ret)
-+ return ret;
-+
-+ ctlr = spi_alloc_master(&pdev->dev, sizeof(*sp));
-+ if (!ctlr) {
-+ dev_info(&pdev->dev, "failed to allocate spi controller\n");
-+ return -ENOMEM;
-+ }
-+
-+ /* disable flash mapping and expose spi controller registers */
-+ iowrite32(AR934X_SPI_ENABLE, base + AR934X_SPI_REG_FS);
-+ /* restore pins to default state: CSn=1 DO=CLK=0 */
-+ iowrite32(AR934X_SPI_IOC_INITVAL, base + AR934X_SPI_REG_IOC);
-+
-+ ctlr->mode_bits = SPI_LSB_FIRST;
-+ ctlr->setup = ar934x_spi_setup;
-+ ctlr->transfer_one_message = ar934x_spi_transfer_one_message;
-+ ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
-+ ctlr->dev.of_node = pdev->dev.of_node;
-+ ctlr->num_chipselect = 3;
-+
-+ dev_set_drvdata(&pdev->dev, ctlr);
-+
-+ sp = spi_controller_get_devdata(ctlr);
-+ sp->base = base;
-+ sp->clk = clk;
-+ sp->clk_freq = clk_get_rate(clk);
-+ sp->ctlr = ctlr;
-+
-+ return devm_spi_register_controller(&pdev->dev, ctlr);
-+}
-+
-+static int ar934x_spi_remove(struct platform_device *pdev)
-+{
-+ struct spi_controller *ctlr;
-+ struct ar934x_spi *sp;
-+
-+ ctlr = dev_get_drvdata(&pdev->dev);
-+ sp = spi_controller_get_devdata(ctlr);
-+
-+ clk_disable_unprepare(sp->clk);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver ar934x_spi_driver = {
-+ .driver = {
-+ .name = DRIVER_NAME,
-+ .of_match_table = ar934x_spi_match,
-+ },
-+ .probe = ar934x_spi_probe,
-+ .remove = ar934x_spi_remove,
-+};
-+
-+module_platform_driver(ar934x_spi_driver);
-+
-+MODULE_DESCRIPTION("SPI controller driver for Qualcomm Atheros AR934x/QCA95xx");
-+MODULE_AUTHOR("Chuanhong Guo <gch981213@gmail.com>");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:" DRIVER_NAME);
+++ /dev/null
-From patchwork Fri Feb 21 21:23:31 2020
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
-X-Patchwork-Id: 1198835
-Date: Fri, 21 Feb 2020 22:23:31 +0100
-From: Daniel Golle <daniel@makrotopia.org>
-To: linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org
-Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
- Jiri Slaby <jslaby@suse.com>, Petr =?utf-8?q?=C5=A0tetiar?= <ynezz@true.cz>,
- Chuanhong Guo <gch981213@gmail.com>, Piotr Dymacz <pepe2k@gmail.com>
-Subject: [PATCH v2] serial: ar933x_uart: add RS485 support
-Message-ID: <20200221212331.GA21467@makrotopia.org>
-MIME-Version: 1.0
-Content-Disposition: inline
-Sender: linux-kernel-owner@vger.kernel.org
-Precedence: bulk
-List-ID: <linux-kernel.vger.kernel.org>
-X-Mailing-List: linux-kernel@vger.kernel.org
-
-Emulate half-duplex operation and use mctrl_gpio to add support for
-RS485 tranceiver with transmit/receive switch hooked to RTS GPIO line.
-This is needed to make use of the RS485 port found on Teltonika RUT955.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
-v2: use bool to indicate ongoing half-duplex send, use it afterwards
- to decide whether we've just been in a send operation.
-
- drivers/tty/serial/Kconfig | 1 +
- drivers/tty/serial/ar933x_uart.c | 113 +++++++++++++++++++++++++++++--
- 2 files changed, 108 insertions(+), 6 deletions(-)
-
---- a/drivers/tty/serial/Kconfig
-+++ b/drivers/tty/serial/Kconfig
-@@ -1280,6 +1280,7 @@ config SERIAL_AR933X
- tristate "AR933X serial port support"
- depends on HAVE_CLK && ATH79
- select SERIAL_CORE
-+ select SERIAL_MCTRL_GPIO if GPIOLIB
- help
- If you have an Atheros AR933X SOC based board and want to use the
- built-in UART of the SoC, say Y to this option.
---- a/drivers/tty/serial/ar933x_uart.c
-+++ b/drivers/tty/serial/ar933x_uart.c
-@@ -13,6 +13,7 @@
- #include <linux/console.h>
- #include <linux/sysrq.h>
- #include <linux/delay.h>
-+#include <linux/gpio/consumer.h>
- #include <linux/platform_device.h>
- #include <linux/of.h>
- #include <linux/of_platform.h>
-@@ -29,6 +30,8 @@
-
- #include <asm/mach-ath79/ar933x_uart.h>
-
-+#include "serial_mctrl_gpio.h"
-+
- #define DRIVER_NAME "ar933x-uart"
-
- #define AR933X_UART_MAX_SCALE 0xff
-@@ -47,6 +50,8 @@ struct ar933x_uart_port {
- unsigned int min_baud;
- unsigned int max_baud;
- struct clk *clk;
-+ struct mctrl_gpios *gpios;
-+ struct gpio_desc *rts_gpiod;
- };
-
- static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
-@@ -100,6 +105,18 @@ static inline void ar933x_uart_stop_tx_i
- ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
- }
-
-+static inline void ar933x_uart_start_rx_interrupt(struct ar933x_uart_port *up)
-+{
-+ up->ier |= AR933X_UART_INT_RX_VALID;
-+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
-+}
-+
-+static inline void ar933x_uart_stop_rx_interrupt(struct ar933x_uart_port *up)
-+{
-+ up->ier &= ~AR933X_UART_INT_RX_VALID;
-+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
-+}
-+
- static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch)
- {
- unsigned int rdata;
-@@ -125,11 +142,21 @@ static unsigned int ar933x_uart_tx_empty
-
- static unsigned int ar933x_uart_get_mctrl(struct uart_port *port)
- {
-- return TIOCM_CAR;
-+ struct ar933x_uart_port *up =
-+ container_of(port, struct ar933x_uart_port, port);
-+ int ret = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
-+
-+ mctrl_gpio_get(up->gpios, &ret);
-+
-+ return ret;
- }
-
- static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
- {
-+ struct ar933x_uart_port *up =
-+ container_of(port, struct ar933x_uart_port, port);
-+
-+ mctrl_gpio_set(up->gpios, mctrl);
- }
-
- static void ar933x_uart_start_tx(struct uart_port *port)
-@@ -140,6 +167,37 @@ static void ar933x_uart_start_tx(struct
- ar933x_uart_start_tx_interrupt(up);
- }
-
-+static void ar933x_uart_wait_tx_complete(struct ar933x_uart_port *up)
-+{
-+ unsigned int status;
-+ unsigned int timeout = 60000;
-+
-+ /* Wait up to 60ms for the character(s) to be sent. */
-+ do {
-+ status = ar933x_uart_read(up, AR933X_UART_CS_REG);
-+ if (--timeout == 0)
-+ break;
-+ udelay(1);
-+ } while (status & AR933X_UART_CS_TX_BUSY);
-+
-+ if (timeout == 0)
-+ dev_err(up->port.dev, "waiting for TX timed out\n");
-+}
-+
-+static void ar933x_uart_rx_flush(struct ar933x_uart_port *up)
-+{
-+ unsigned int status;
-+
-+ /* clear RX_VALID interrupt */
-+ ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_RX_VALID);
-+
-+ /* remove characters from the RX FIFO */
-+ do {
-+ ar933x_uart_write(up, AR933X_UART_DATA_REG, AR933X_UART_DATA_RX_CSR);
-+ status = ar933x_uart_read(up, AR933X_UART_DATA_REG);
-+ } while (status & AR933X_UART_DATA_RX_CSR);
-+}
-+
- static void ar933x_uart_stop_tx(struct uart_port *port)
- {
- struct ar933x_uart_port *up =
-@@ -153,8 +211,7 @@ static void ar933x_uart_stop_rx(struct u
- struct ar933x_uart_port *up =
- container_of(port, struct ar933x_uart_port, port);
-
-- up->ier &= ~AR933X_UART_INT_RX_VALID;
-- ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
-+ ar933x_uart_stop_rx_interrupt(up);
- }
-
- static void ar933x_uart_break_ctl(struct uart_port *port, int break_state)
-@@ -336,11 +393,20 @@ static void ar933x_uart_rx_chars(struct
- static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
- {
- struct circ_buf *xmit = &up->port.state->xmit;
-+ struct serial_rs485 *rs485conf = &up->port.rs485;
- int count;
-+ bool half_duplex_send = false;
-
- if (uart_tx_stopped(&up->port))
- return;
-
-+ if ((rs485conf->flags & SER_RS485_ENABLED) &&
-+ (up->port.x_char || !uart_circ_empty(xmit))) {
-+ ar933x_uart_stop_rx_interrupt(up);
-+ gpiod_set_value(up->rts_gpiod, !!(rs485conf->flags & SER_RS485_RTS_ON_SEND));
-+ half_duplex_send = true;
-+ }
-+
- count = up->port.fifosize;
- do {
- unsigned int rdata;
-@@ -368,8 +434,14 @@ static void ar933x_uart_tx_chars(struct
- if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_write_wakeup(&up->port);
-
-- if (!uart_circ_empty(xmit))
-+ if (!uart_circ_empty(xmit)) {
- ar933x_uart_start_tx_interrupt(up);
-+ } else if (half_duplex_send) {
-+ ar933x_uart_wait_tx_complete(up);
-+ ar933x_uart_rx_flush(up);
-+ ar933x_uart_start_rx_interrupt(up);
-+ gpiod_set_value(up->rts_gpiod, !!(rs485conf->flags & SER_RS485_RTS_AFTER_SEND));
-+ }
- }
-
- static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id)
-@@ -427,8 +499,7 @@ static int ar933x_uart_startup(struct ua
- AR933X_UART_CS_TX_READY_ORIDE | AR933X_UART_CS_RX_READY_ORIDE);
-
- /* Enable RX interrupts */
-- up->ier = AR933X_UART_INT_RX_VALID;
-- ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
-+ ar933x_uart_start_rx_interrupt(up);
-
- spin_unlock_irqrestore(&up->port.lock, flags);
-
-@@ -511,6 +582,21 @@ static const struct uart_ops ar933x_uart
- .verify_port = ar933x_uart_verify_port,
- };
-
-+static int ar933x_config_rs485(struct uart_port *port,
-+ struct serial_rs485 *rs485conf)
-+{
-+ struct ar933x_uart_port *up =
-+ container_of(port, struct ar933x_uart_port, port);
-+
-+ if ((rs485conf->flags & SER_RS485_ENABLED) &&
-+ !up->rts_gpiod) {
-+ dev_err(port->dev, "RS485 needs rts-gpio\n");
-+ return 1;
-+ }
-+ port->rs485 = *rs485conf;
-+ return 0;
-+}
-+
- #ifdef CONFIG_SERIAL_AR933X_CONSOLE
- static struct ar933x_uart_port *
- ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS];
-@@ -680,6 +766,8 @@ static int ar933x_uart_probe(struct plat
- goto err_disable_clk;
- }
-
-+ uart_get_rs485_mode(&pdev->dev, &port->rs485);
-+
- port->mapbase = mem_res->start;
- port->line = id;
- port->irq = irq_res->start;
-@@ -690,6 +778,7 @@ static int ar933x_uart_probe(struct plat
- port->regshift = 2;
- port->fifosize = AR933X_UART_FIFO_SIZE;
- port->ops = &ar933x_uart_ops;
-+ port->rs485_config = ar933x_config_rs485;
-
- baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1);
- up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD);
-@@ -697,6 +786,18 @@ static int ar933x_uart_probe(struct plat
- baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP);
- up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD);
-
-+ up->gpios = mctrl_gpio_init(port, 0);
-+ if (IS_ERR(up->gpios) && PTR_ERR(up->gpios) != -ENOSYS)
-+ return PTR_ERR(up->gpios);
-+
-+ up->rts_gpiod = mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS);
-+
-+ if ((port->rs485.flags & SER_RS485_ENABLED) &&
-+ !up->rts_gpiod) {
-+ dev_err(&pdev->dev, "lacking rts-gpio, disabling RS485\n");
-+ port->rs485.flags &= ~SER_RS485_ENABLED;
-+ }
-+
- #ifdef CONFIG_SERIAL_AR933X_CONSOLE
- ar933x_console_ports[up->port.line] = up;
- #endif
+++ /dev/null
-From: David Bauer <mail@david-bauer.net>
-Date: Sat, 11 Apr 2020 14:03:12 +0200
-Subject: MIPS: pci-ar724x: add QCA9550 reset sequence
-
-The QCA9550 family of SoCs have a slightly different reset
-sequence compared to older chips.
-
-Normally the bootloader performs this sequence, however
-some bootloader implementation expect the operating system
-to clear the reset.
-
-Also get the resets from OF to support handling of the second
-PCIe root-complex on the QCA9558.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
-
---- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -391,6 +391,7 @@
- #define QCA955X_PLL_CPU_CONFIG_REG 0x00
- #define QCA955X_PLL_DDR_CONFIG_REG 0x04
- #define QCA955X_PLL_CLK_CTRL_REG 0x08
-+#define QCA955X_PLL_PCIE_CONFIG_REG 0x0c
- #define QCA955X_PLL_ETH_XMII_CONTROL_REG 0x28
- #define QCA955X_PLL_ETH_SGMII_CONTROL_REG 0x48
- #define QCA955X_PLL_ETH_SGMII_SERDES_REG 0x4c
-@@ -476,6 +477,9 @@
- #define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL BIT(21)
- #define QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
-
-+#define QCA955X_PLL_PCIE_CONFIG_PLL_PWD BIT(30)
-+#define QCA955X_PLL_PCIE_CONFIG_PLL_BYPASS BIT(16)
-+
- #define QCA956X_PLL_SWITCH_CLOCK_SPARE_I2C_CLK_SELB BIT(5)
- #define QCA956X_PLL_SWITCH_CLOCK_SPARE_MDIO_CLK_SEL0_1 BIT(6)
- #define QCA956X_PLL_SWITCH_CLOCK_SPARE_UART1_CLK_SEL BIT(7)
---- a/arch/mips/pci/pci-ar724x.c
-+++ b/arch/mips/pci/pci-ar724x.c
-@@ -8,6 +8,7 @@
-
- #include <linux/irq.h>
- #include <linux/pci.h>
-+#include <linux/reset.h>
- #include <linux/init.h>
- #include <linux/delay.h>
- #include <linux/platform_device.h>
-@@ -55,6 +56,9 @@ struct ar724x_pci_controller {
- struct irq_domain *domain;
- struct resource io_res;
- struct resource mem_res;
-+
-+ struct reset_control *hc_reset;
-+ struct reset_control *phy_reset;
- };
-
- static struct irq_chip ar724x_pci_irq_chip;
-@@ -340,18 +344,30 @@ static void ar724x_pci_hw_init(struct ar
- int wait = 0;
-
- /* deassert PCIe host controller and PCIe PHY reset */
-- ath79_device_reset_clear(AR724X_RESET_PCIE);
-- ath79_device_reset_clear(AR724X_RESET_PCIE_PHY);
-+ reset_control_deassert(apc->hc_reset);
-+ reset_control_deassert(apc->phy_reset);
-
-- /* remove the reset of the PCIE PLL */
-- ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
-- ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET;
-- ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
--
-- /* deassert bypass for the PCIE PLL */
-- ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
-- ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_BYPASS;
-- ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
-+ if (of_device_is_compatible(apc->np, "qcom,qca9550-pci")) {
-+ /* remove the reset of the PCIE PLL */
-+ ppl = ath79_pll_rr(QCA955X_PLL_PCIE_CONFIG_REG);
-+ ppl &= ~QCA955X_PLL_PCIE_CONFIG_PLL_PWD;
-+ ath79_pll_wr(QCA955X_PLL_PCIE_CONFIG_REG, ppl);
-+
-+ /* deassert bypass for the PCIE PLL */
-+ ppl = ath79_pll_rr(QCA955X_PLL_PCIE_CONFIG_REG);
-+ ppl &= ~QCA955X_PLL_PCIE_CONFIG_PLL_BYPASS;
-+ ath79_pll_wr(QCA955X_PLL_PCIE_CONFIG_REG, ppl);
-+ } else {
-+ /* remove the reset of the PCIE PLL */
-+ ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
-+ ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET;
-+ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
-+
-+ /* deassert bypass for the PCIE PLL */
-+ ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
-+ ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_BYPASS;
-+ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
-+ }
-
- /* set PCIE Application Control to ready */
- app = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_APP);
-@@ -399,6 +415,14 @@ static int ar724x_pci_probe(struct platf
- if (apc->irq < 0)
- return -EINVAL;
-
-+ apc->hc_reset = devm_reset_control_get_exclusive(&pdev->dev, "hc");
-+ if (IS_ERR(apc->hc_reset))
-+ return PTR_ERR(apc->hc_reset);
-+
-+ apc->phy_reset = devm_reset_control_get_exclusive(&pdev->dev, "phy");
-+ if (IS_ERR(apc->phy_reset))
-+ return PTR_ERR(apc->phy_reset);
-+
- apc->np = pdev->dev.of_node;
- apc->pci_controller.pci_ops = &ar724x_pci_ops;
- apc->pci_controller.io_resource = &apc->io_res;
-@@ -409,7 +433,7 @@ static int ar724x_pci_probe(struct platf
- * Do the full PCIE Root Complex Initialization Sequence if the PCIe
- * host controller is in reset.
- */
-- if (ath79_reset_rr(AR724X_RESET_REG_RESET_MODULE) & AR724X_RESET_PCIE)
-+ if (reset_control_status(apc->hc_reset))
- ar724x_pci_hw_init(apc);
-
- apc->link_up = ar724x_pci_check_link(apc);
-@@ -427,6 +451,7 @@ static int ar724x_pci_probe(struct platf
-
- static const struct of_device_id ar724x_pci_ids[] = {
- { .compatible = "qcom,ar7240-pci" },
-+ { .compatible = "qcom,qca9550-pci" },
- {},
- };
-
+++ /dev/null
---- a/drivers/mtd/parsers/Makefile
-+++ b/drivers/mtd/parsers/Makefile
-@@ -8,6 +8,7 @@ obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
- ofpart-y += ofpart_core.o
- ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += ofpart_bcm4908.o
- ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o
-+obj-$(CONFIG_MTD_PARSER_CYBERTAN) += parser_cybertan.o
- obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o
- obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
- obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
---- a/drivers/mtd/parsers/Kconfig
-+++ b/drivers/mtd/parsers/Kconfig
-@@ -102,6 +102,14 @@ config MTD_OF_PARTS_LINKSYS_NS
- two "firmware" partitions. Currently used firmware has to be detected
- using CFE environment variable.
-
-+config MTD_PARSER_CYBERTAN
-+ tristate "Parser for Cybertan format partitions"
-+ depends on MTD && (ATH79 || COMPILE_TEST)
-+ help
-+ Cybertan has a proprietory header than encompasses a Broadcom trx
-+ header. This driver will parse the header and take care of the
-+ special offsets that result in the extra headers.
-+
- config MTD_PARSER_IMAGETAG
- tristate "Parser for BCM963XX Image Tag format partitions"
- depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST
+++ /dev/null
---- a/drivers/mtd/parsers/redboot.c
-+++ b/drivers/mtd/parsers/redboot.c
-@@ -90,12 +90,18 @@ static int parse_redboot_partitions(stru
-
- parse_redboot_of(master);
-
-+ buf = vmalloc(master->erasesize);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ restart:
- if ( directory < 0 ) {
- offset = master->size + directory * master->erasesize;
- while (mtd_block_isbad(master, offset)) {
- if (!offset) {
- nogood:
- printk(KERN_NOTICE "Failed to find a non-bad block to check for RedBoot partition table\n");
-+ vfree(buf);
- return -EIO;
- }
- offset -= master->erasesize;
-@@ -108,10 +114,6 @@ static int parse_redboot_partitions(stru
- goto nogood;
- }
- }
-- buf = vmalloc(master->erasesize);
--
-- if (!buf)
-- return -ENOMEM;
-
- printk(KERN_NOTICE "Searching for RedBoot partition table in %s at offset 0x%lx\n",
- master->name, offset);
-@@ -184,6 +186,11 @@ static int parse_redboot_partitions(stru
- }
- if (i == numslots) {
- /* Didn't find it */
-+ if (offset + master->erasesize < master->size) {
-+ /* not at the end of the flash yet, maybe next block :) */
-+ directory++;
-+ goto restart;
-+ }
- printk(KERN_NOTICE "No RedBoot partition table detected in %s\n",
- master->name);
- ret = 0;
+++ /dev/null
-From 8d8cdb4a6ccee5b62cc0dc64651c3946364514dc Mon Sep 17 00:00:00 2001
-From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
-Date: Mon, 10 Feb 2020 16:11:27 -0300
-Subject: [PATCH] spi: ath79: Implement the spi_mem interface
-
-Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
----
- drivers/spi/spi-ath79.c | 35 +++++++++++++++++++++++++++++++++++
- 1 file changed, 35 insertions(+)
-
---- a/drivers/spi/spi-ath79.c
-+++ b/drivers/spi/spi-ath79.c
-@@ -15,6 +15,7 @@
- #include <linux/platform_device.h>
- #include <linux/io.h>
- #include <linux/spi/spi.h>
-+#include <linux/spi/spi-mem.h>
- #include <linux/spi/spi_bitbang.h>
- #include <linux/bitops.h>
- #include <linux/clk.h>
-@@ -133,6 +134,39 @@ static u32 ath79_spi_txrx_mode0(struct s
- return ath79_spi_rr(sp, AR71XX_SPI_REG_RDS);
- }
-
-+static int ath79_exec_mem_op(struct spi_mem *mem,
-+ const struct spi_mem_op *op)
-+{
-+ struct ath79_spi *sp = ath79_spidev_to_sp(mem->spi);
-+
-+ /* Ensures that reading is performed on device connected
-+ to hardware cs0 */
-+ if (mem->spi->chip_select || mem->spi->cs_gpiod)
-+ return -ENOTSUPP;
-+
-+ /* Only use for fast-read op. */
-+ if (op->cmd.opcode != 0x0b || op->data.dir != SPI_MEM_DATA_IN ||
-+ op->addr.nbytes != 3 || op->dummy.nbytes != 1)
-+ return -ENOTSUPP;
-+
-+ /* disable GPIO mode */
-+ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
-+
-+ memcpy_fromio(op->data.buf.in, sp->base + op->addr.val, op->data.nbytes);
-+
-+ /* enable GPIO mode */
-+ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
-+
-+ /* restore IOC register */
-+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
-+
-+ return 0;
-+}
-+
-+static const struct spi_controller_mem_ops ath79_mem_ops = {
-+ .exec_op = ath79_exec_mem_op,
-+};
-+
- static int ath79_spi_probe(struct platform_device *pdev)
- {
- struct spi_master *master;
-@@ -164,6 +198,7 @@ static int ath79_spi_probe(struct platfo
- ret = PTR_ERR(sp->base);
- goto err_put_master;
- }
-+ master->mem_ops = &ath79_mem_ops;
-
- sp->clk = devm_clk_get(&pdev->dev, "ahb");
- if (IS_ERR(sp->clk)) {
+++ /dev/null
-From e2e9f6d9f9bd7449ff113c157b639ce1a24b9d3f Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Sat, 24 Apr 2021 16:14:48 +0200
-Subject: [PATCH 2/2] spi: ath79: set number of chipselect lines
-
-All chipsets from AR7100 up to QCA9563 have three dedicated chipselect
-lines for the integrated SPI controller. Remove the number of
-chipselects from the platform data, as there is no need to manually set
-this to a different value.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- drivers/spi/spi-ath79.c | 2 +-
- include/linux/platform_data/spi-ath79.h | 1 -
- 2 files changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/spi/spi-ath79.c
-+++ b/drivers/spi/spi-ath79.c
-@@ -187,6 +187,7 @@ static int ath79_spi_probe(struct platfo
- master->use_gpio_descriptors = true;
- master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
- master->flags = SPI_MASTER_GPIO_SS;
-+ master->num_chipselect = 3;
-
- sp->bitbang.master = master;
- sp->bitbang.chipselect = ath79_spi_chipselect;
+++ /dev/null
---- a/drivers/net/ethernet/atheros/Kconfig
-+++ b/drivers/net/ethernet/atheros/Kconfig
-@@ -17,13 +17,7 @@ config NET_VENDOR_ATHEROS
-
- if NET_VENDOR_ATHEROS
-
--config AG71XX
-- tristate "Atheros AR7XXX/AR9XXX built-in ethernet mac support"
-- depends on ATH79
-- select PHYLIB
-- help
-- If you wish to compile a kernel for AR7XXX/91XXX and enable
-- ethernet support, then you should always answer Y to this.
-+source "drivers/net/ethernet/atheros/ag71xx/Kconfig"
-
- config ATL2
- tristate "Atheros L2 Fast Ethernet support"
---- a/drivers/net/ethernet/atheros/Makefile
-+++ b/drivers/net/ethernet/atheros/Makefile
-@@ -3,7 +3,7 @@
- # Makefile for the Atheros network device drivers.
- #
-
--obj-$(CONFIG_AG71XX) += ag71xx.o
-+obj-$(CONFIG_AG71XX) += ag71xx/
- obj-$(CONFIG_ATL1) += atlx/
- obj-$(CONFIG_ATL2) += atlx/
- obj-$(CONFIG_ATL1E) += atl1e/
+++ /dev/null
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -404,6 +404,13 @@ static int at803x_aneg_done(struct phy_d
- if (!(phy_read(phydev, AT803X_PSSR) & AT803X_PSSR_MR_AN_COMPLETE)) {
- phydev_warn(phydev, "803x_aneg_done: SGMII link is not ok\n");
- aneg_done = 0;
-+#ifdef CONFIG_OF_MDIO
-+ if (phydev->mdio.dev.of_node &&
-+ of_property_read_bool(phydev->mdio.dev.of_node,
-+ "at803x-override-sgmii-link-check")) {
-+ aneg_done = 1;
-+ }
-+#endif
- }
- /* switch back to copper page */
- phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL);
+++ /dev/null
---- a/drivers/Makefile
-+++ b/drivers/Makefile
-@@ -80,8 +80,8 @@ obj-y += scsi/
- obj-y += nvme/
- obj-$(CONFIG_ATA) += ata/
- obj-$(CONFIG_TARGET_CORE) += target/
--obj-$(CONFIG_MTD) += mtd/
- obj-$(CONFIG_SPI) += spi/
-+obj-$(CONFIG_MTD) += mtd/
- obj-$(CONFIG_SPMI) += spmi/
- obj-$(CONFIG_HSI) += hsi/
- obj-$(CONFIG_SLIMBUS) += slimbus/
+++ /dev/null
---- a/drivers/mtd/nand/raw/Kconfig
-+++ b/drivers/mtd/nand/raw/Kconfig
-@@ -544,4 +544,12 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
- load time (assuming you build diskonchip as a module) with the module
- parameter "inftl_bbt_write=1".
-
-+config MTD_NAND_AR934X
-+ tristate "Support for NAND controller on Qualcomm Atheros AR934x/QCA955x SoCs"
-+ depends on ATH79 || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ help
-+ Enables support for NAND controller on Qualcomm Atheros SoCs.
-+ This controller is found on AR934x and QCA955x SoCs.
-+
- endif # MTD_RAW_NAND
---- a/drivers/mtd/nand/raw/Makefile
-+++ b/drivers/mtd/nand/raw/Makefile
-@@ -57,6 +57,7 @@ obj-$(CONFIG_MTD_NAND_MXIC) += mxic_nan
- obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o
- obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o
- obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o
-+obj-$(CONFIG_MTD_NAND_AR934X) += ar934x_nand.o
-
- nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
- nand-objs += nand_onfi.o
+++ /dev/null
-From: Nick Hainke <vincent@systemli.org>
-Date: Sun, 25 Oct 2020 00:52:47 +0200
-Subject: [PATCH] ath79: fix block protection clearing
-
-The block protection bits of macronix do not match the implementation.
-The chip has 3 BP bits. Bit 5 is actually the third BP but here the
-5th bit is SR_TB. Therefore the patch adds SR_TB to the mask. In the
-4.19er kernel the whole register was simply set to 0.
-
-The wrong implementation did not remove the block protection. This led
-to jffs2 errors in the form of:
-"jffs2: Newly-erased block contained word 0x19852003 at offset 0x..."
-This caused inconsistent memory and other errors.
-
-Suggested-by: David Bauer <mail@david-bauer.net>
-Signed-off-by: Nick Hainke <vincent@systemli.org>
-
---- a/drivers/mtd/spi-nor/spi-nor.c
-+++ b/drivers/mtd/spi-nor/spi-nor.c
-@@ -1987,7 +1987,7 @@ static int sr2_bit7_quad_enable(struct s
- static int spi_nor_clear_sr_bp(struct spi_nor *nor)
- {
- int ret;
-- u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
-+ u8 mask = SR_TB | SR_BP2 | SR_BP1 | SR_BP0;
-
- if (nor->flags & SNOR_F_HAS_4BIT_BP)
- mask |= SR_BP3;
+++ /dev/null
---- /dev/null
-+++ b/arch/mips/include/asm/mach-ath79/mangle-port.h
-@@ -0,0 +1,37 @@
-+/*
-+ * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
-+ *
-+ * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h
-+ * Copyright (C) 2003, 2004 Ralf Baechle
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ */
-+
-+#ifndef __ASM_MACH_ATH79_MANGLE_PORT_H
-+#define __ASM_MACH_ATH79_MANGLE_PORT_H
-+
-+#ifdef CONFIG_PCI_AR71XX
-+extern unsigned long (ath79_pci_swizzle_b)(unsigned long port);
-+extern unsigned long (ath79_pci_swizzle_w)(unsigned long port);
-+#else
-+#define ath79_pci_swizzle_b(port) (port)
-+#define ath79_pci_swizzle_w(port) (port)
-+#endif
-+
-+#define __swizzle_addr_b(port) ath79_pci_swizzle_b(port)
-+#define __swizzle_addr_w(port) ath79_pci_swizzle_w(port)
-+#define __swizzle_addr_l(port) (port)
-+#define __swizzle_addr_q(port) (port)
-+
-+# define ioswabb(a, x) (x)
-+# define __mem_ioswabb(a, x) (x)
-+# define ioswabw(a, x) (x)
-+# define __mem_ioswabw(a, x) cpu_to_le16(x)
-+# define ioswabl(a, x) (x)
-+# define __mem_ioswabl(a, x) cpu_to_le32(x)
-+# define ioswabq(a, x) (x)
-+# define __mem_ioswabq(a, x) cpu_to_le64(x)
-+
-+#endif /* __ASM_MACH_ATH79_MANGLE_PORT_H */
---- a/arch/mips/pci/pci-ar71xx.c
-+++ b/arch/mips/pci/pci-ar71xx.c
-@@ -68,6 +68,45 @@ static const u32 ar71xx_pci_read_mask[8]
- 0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0
- };
-
-+static unsigned long (*__ath79_pci_swizzle_b)(unsigned long port);
-+static unsigned long (*__ath79_pci_swizzle_w)(unsigned long port);
-+
-+static inline bool ar71xx_is_pci_addr(unsigned long port)
-+{
-+ unsigned long phys = CPHYSADDR(port);
-+
-+ return (phys >= AR71XX_PCI_MEM_BASE &&
-+ phys < AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE);
-+}
-+
-+static unsigned long ar71xx_pci_swizzle_b(unsigned long port)
-+{
-+ return ar71xx_is_pci_addr(port) ? port ^ 3 : port;
-+}
-+
-+static unsigned long ar71xx_pci_swizzle_w(unsigned long port)
-+{
-+ return ar71xx_is_pci_addr(port) ? port ^ 2 : port;
-+}
-+
-+unsigned long ath79_pci_swizzle_b(unsigned long port)
-+{
-+ if (__ath79_pci_swizzle_b)
-+ return __ath79_pci_swizzle_b(port);
-+
-+ return port;
-+}
-+EXPORT_SYMBOL(ath79_pci_swizzle_b);
-+
-+unsigned long ath79_pci_swizzle_w(unsigned long port)
-+{
-+ if (__ath79_pci_swizzle_w)
-+ return __ath79_pci_swizzle_w(port);
-+
-+ return port;
-+}
-+EXPORT_SYMBOL(ath79_pci_swizzle_w);
-+
- static inline u32 ar71xx_pci_get_ble(int where, int size, int local)
- {
- u32 t;
-@@ -276,6 +315,9 @@ static int ar71xx_pci_probe(struct platf
-
- register_pci_controller(&apc->pci_ctrl);
-
-+ __ath79_pci_swizzle_b = ar71xx_pci_swizzle_b;
-+ __ath79_pci_swizzle_w = ar71xx_pci_swizzle_w;
-+
- return 0;
- }
-
+++ /dev/null
---- a/drivers/net/phy/mdio-bitbang.c
-+++ b/drivers/net/phy/mdio-bitbang.c
-@@ -152,7 +152,7 @@ static int mdiobb_cmd_addr(struct mdiobb
- static int mdiobb_read(struct mii_bus *bus, int phy, int reg)
- {
- struct mdiobb_ctrl *ctrl = bus->priv;
-- int ret, i;
-+ int ret;
-
- if (reg & MII_ADDR_C45) {
- reg = mdiobb_cmd_addr(ctrl, phy, reg);
-@@ -162,19 +162,7 @@ static int mdiobb_read(struct mii_bus *b
-
- ctrl->ops->set_mdio_dir(ctrl, 0);
-
-- /* check the turnaround bit: the PHY should be driving it to zero, if this
-- * PHY is listed in phy_ignore_ta_mask as having broken TA, skip that
-- */
-- if (mdiobb_get_bit(ctrl) != 0 &&
-- !(bus->phy_ignore_ta_mask & (1 << phy))) {
-- /* PHY didn't drive TA low -- flush any bits it
-- * may be trying to send.
-- */
-- for (i = 0; i < 32; i++)
-- mdiobb_get_bit(ctrl);
--
-- return 0xffff;
-- }
-+ mdiobb_get_bit(ctrl);
-
- ret = mdiobb_get_num(ctrl, 16);
- mdiobb_get_bit(ctrl);
+++ /dev/null
-From 66e584435ac0de6e0abeb6d7166fe4fe25d6bb73 Mon Sep 17 00:00:00 2001
-From: Jonas Gorski <jogo@openwrt.org>
-Date: Tue, 16 Jun 2015 13:15:08 +0200
-Subject: [PATCH] phy/mdio-bitbang: prevent rescheduling during command
-
-It seems some phys have some maximum timings for accessing the MDIO line,
-resulting in bit errors under cpu stress. Prevent this from happening by
-disabling interrupts when sending commands.
-
-Signed-off-by: Jonas Gorski <jogo@openwrt.org>
----
- drivers/net/phy/mdio-bitbang.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/drivers/net/phy/mdio-bitbang.c
-+++ b/drivers/net/phy/mdio-bitbang.c
-@@ -14,6 +14,7 @@
- * Vitaly Bordug <vbordug@ru.mvista.com>
- */
-
-+#include <linux/irqflags.h>
- #include <linux/module.h>
- #include <linux/mdio-bitbang.h>
- #include <linux/types.h>
-@@ -153,7 +154,9 @@ static int mdiobb_read(struct mii_bus *b
- {
- struct mdiobb_ctrl *ctrl = bus->priv;
- int ret;
-+ unsigned long flags;
-
-+ local_irq_save(flags);
- if (reg & MII_ADDR_C45) {
- reg = mdiobb_cmd_addr(ctrl, phy, reg);
- mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg);
-@@ -166,13 +169,17 @@ static int mdiobb_read(struct mii_bus *b
-
- ret = mdiobb_get_num(ctrl, 16);
- mdiobb_get_bit(ctrl);
-+ local_irq_restore(flags);
-+
- return ret;
- }
-
- static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
- {
- struct mdiobb_ctrl *ctrl = bus->priv;
-+ unsigned long flags;
-
-+ local_irq_save(flags);
- if (reg & MII_ADDR_C45) {
- reg = mdiobb_cmd_addr(ctrl, phy, reg);
- mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, reg);
-@@ -187,6 +194,8 @@ static int mdiobb_write(struct mii_bus *
-
- ctrl->ops->set_mdio_dir(ctrl, 0);
- mdiobb_get_bit(ctrl);
-+ local_irq_restore(flags);
-+
- return 0;
- }
-
+++ /dev/null
---- a/arch/mips/include/asm/checksum.h
-+++ b/arch/mips/include/asm/checksum.h
-@@ -134,26 +134,30 @@ static inline __sum16 ip_fast_csum(const
- const unsigned int *stop = word + ihl;
- unsigned int csum;
- int carry;
-+ unsigned int w;
-
-- csum = word[0];
-- csum += word[1];
-- carry = (csum < word[1]);
-+ csum = net_hdr_word(word++);
-+
-+ w = net_hdr_word(word++);
-+ csum += w;
-+ carry = (csum < w);
- csum += carry;
-
-- csum += word[2];
-- carry = (csum < word[2]);
-+ w = net_hdr_word(word++);
-+ csum += w;
-+ carry = (csum < w);
- csum += carry;
-
-- csum += word[3];
-- carry = (csum < word[3]);
-+ w = net_hdr_word(word++);
-+ csum += w;
-+ carry = (csum < w);
- csum += carry;
-
-- word += 4;
- do {
-- csum += *word;
-- carry = (csum < *word);
-+ w = net_hdr_word(word++);
-+ csum += w;
-+ carry = (csum < w);
- csum += carry;
-- word++;
- } while (word != stop);
-
- return csum_fold(csum);
-@@ -214,73 +218,6 @@ static inline __sum16 ip_compute_csum(co
- return csum_fold(csum_partial(buff, len, 0));
- }
-
--#define _HAVE_ARCH_IPV6_CSUM
--static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
-- const struct in6_addr *daddr,
-- __u32 len, __u8 proto,
-- __wsum sum)
--{
-- __wsum tmp;
--
-- __asm__(
-- " .set push # csum_ipv6_magic\n"
-- " .set noreorder \n"
-- " .set noat \n"
-- " addu %0, %5 # proto (long in network byte order)\n"
-- " sltu $1, %0, %5 \n"
-- " addu %0, $1 \n"
--
-- " addu %0, %6 # csum\n"
-- " sltu $1, %0, %6 \n"
-- " lw %1, 0(%2) # four words source address\n"
-- " addu %0, $1 \n"
-- " addu %0, %1 \n"
-- " sltu $1, %0, %1 \n"
--
-- " lw %1, 4(%2) \n"
-- " addu %0, $1 \n"
-- " addu %0, %1 \n"
-- " sltu $1, %0, %1 \n"
--
-- " lw %1, 8(%2) \n"
-- " addu %0, $1 \n"
-- " addu %0, %1 \n"
-- " sltu $1, %0, %1 \n"
--
-- " lw %1, 12(%2) \n"
-- " addu %0, $1 \n"
-- " addu %0, %1 \n"
-- " sltu $1, %0, %1 \n"
--
-- " lw %1, 0(%3) \n"
-- " addu %0, $1 \n"
-- " addu %0, %1 \n"
-- " sltu $1, %0, %1 \n"
--
-- " lw %1, 4(%3) \n"
-- " addu %0, $1 \n"
-- " addu %0, %1 \n"
-- " sltu $1, %0, %1 \n"
--
-- " lw %1, 8(%3) \n"
-- " addu %0, $1 \n"
-- " addu %0, %1 \n"
-- " sltu $1, %0, %1 \n"
--
-- " lw %1, 12(%3) \n"
-- " addu %0, $1 \n"
-- " addu %0, %1 \n"
-- " sltu $1, %0, %1 \n"
--
-- " addu %0, $1 # Add final carry\n"
-- " .set pop"
-- : "=&r" (sum), "=&r" (tmp)
-- : "r" (saddr), "r" (daddr),
-- "0" (htonl(len)), "r" (htonl(proto)), "r" (sum));
--
-- return csum_fold(sum);
--}
--
- #include <asm-generic/checksum.h>
- #endif /* CONFIG_GENERIC_CSUM */
-
---- a/include/uapi/linux/ip.h
-+++ b/include/uapi/linux/ip.h
-@@ -103,7 +103,7 @@ struct iphdr {
- __be32 saddr;
- __be32 daddr;
- /*The options start here. */
--};
-+} __attribute__((packed, aligned(2)));
-
-
- struct ip_auth_hdr {
---- a/include/uapi/linux/ipv6.h
-+++ b/include/uapi/linux/ipv6.h
-@@ -131,7 +131,7 @@ struct ipv6hdr {
-
- struct in6_addr saddr;
- struct in6_addr daddr;
--};
-+} __attribute__((packed, aligned(2)));
-
-
- /* index values for the variables in ipv6_devconf */
---- a/include/uapi/linux/tcp.h
-+++ b/include/uapi/linux/tcp.h
-@@ -55,7 +55,7 @@ struct tcphdr {
- __be16 window;
- __sum16 check;
- __be16 urg_ptr;
--};
-+} __attribute__((packed, aligned(2)));
-
- /*
- * The union cast uses a gcc extension to avoid aliasing problems
-@@ -65,7 +65,7 @@ struct tcphdr {
- union tcp_word_hdr {
- struct tcphdr hdr;
- __be32 words[5];
--};
-+} __attribute__((packed, aligned(2)));
-
- #define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3])
-
---- a/include/uapi/linux/udp.h
-+++ b/include/uapi/linux/udp.h
-@@ -25,7 +25,7 @@ struct udphdr {
- __be16 dest;
- __be16 len;
- __sum16 check;
--};
-+} __attribute__((packed, aligned(2)));
-
- /* UDP socket options */
- #define UDP_CORK 1 /* Never send partially complete segments */
---- a/net/netfilter/nf_conntrack_core.c
-+++ b/net/netfilter/nf_conntrack_core.c
-@@ -266,8 +266,8 @@ nf_ct_get_tuple(const struct sk_buff *sk
-
- switch (l3num) {
- case NFPROTO_IPV4:
-- tuple->src.u3.ip = ap[0];
-- tuple->dst.u3.ip = ap[1];
-+ tuple->src.u3.ip = net_hdr_word(ap++);
-+ tuple->dst.u3.ip = net_hdr_word(ap);
- break;
- case NFPROTO_IPV6:
- memcpy(tuple->src.u3.ip6, ap, sizeof(tuple->src.u3.ip6));
---- a/include/uapi/linux/icmp.h
-+++ b/include/uapi/linux/icmp.h
-@@ -82,7 +82,7 @@ struct icmphdr {
- } frag;
- __u8 reserved[4];
- } un;
--};
-+} __attribute__((packed, aligned(2)));
-
-
- /*
---- a/include/uapi/linux/in6.h
-+++ b/include/uapi/linux/in6.h
-@@ -43,7 +43,7 @@ struct in6_addr {
- #define s6_addr16 in6_u.u6_addr16
- #define s6_addr32 in6_u.u6_addr32
- #endif
--};
-+} __attribute__((packed, aligned(2)));
- #endif /* __UAPI_DEF_IN6_ADDR */
-
- #if __UAPI_DEF_SOCKADDR_IN6
---- a/net/ipv6/tcp_ipv6.c
-+++ b/net/ipv6/tcp_ipv6.c
-@@ -35,6 +35,7 @@
- #include <linux/ipsec.h>
- #include <linux/times.h>
- #include <linux/slab.h>
-+#include <asm/unaligned.h>
- #include <linux/uaccess.h>
- #include <linux/ipv6.h>
- #include <linux/icmpv6.h>
-@@ -864,10 +865,10 @@ static void tcp_v6_send_response(const s
- topt = (__be32 *)(t1 + 1);
-
- if (tsecr) {
-- *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
-- (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
-- *topt++ = htonl(tsval);
-- *topt++ = htonl(tsecr);
-+ put_unaligned_be32((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
-+ (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP, topt++);
-+ put_unaligned_be32(tsval, topt++);
-+ put_unaligned_be32(tsecr, topt++);
- }
-
- #ifdef CONFIG_TCP_MD5SIG
---- a/include/linux/ipv6.h
-+++ b/include/linux/ipv6.h
-@@ -6,6 +6,7 @@
-
- #define ipv6_optlen(p) (((p)->hdrlen+1) << 3)
- #define ipv6_authlen(p) (((p)->hdrlen+2) << 2)
-+
- /*
- * This structure contains configuration options per IPv6 link.
- */
---- a/net/ipv6/datagram.c
-+++ b/net/ipv6/datagram.c
-@@ -476,7 +476,7 @@ int ipv6_recv_error(struct sock *sk, str
- ipv6_iface_scope_id(&sin->sin6_addr,
- IP6CB(skb)->iif);
- } else {
-- ipv6_addr_set_v4mapped(*(__be32 *)(nh + serr->addr_offset),
-+ ipv6_addr_set_v4mapped(net_hdr_word(nh + serr->addr_offset),
- &sin->sin6_addr);
- sin->sin6_scope_id = 0;
- }
-@@ -830,12 +830,12 @@ int ip6_datagram_send_ctl(struct net *ne
- }
-
- if (fl6->flowlabel&IPV6_FLOWINFO_MASK) {
-- if ((fl6->flowlabel^*(__be32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) {
-+ if ((fl6->flowlabel^net_hdr_word(CMSG_DATA(cmsg)))&~IPV6_FLOWINFO_MASK) {
- err = -EINVAL;
- goto exit_f;
- }
- }
-- fl6->flowlabel = IPV6_FLOWINFO_MASK & *(__be32 *)CMSG_DATA(cmsg);
-+ fl6->flowlabel = IPV6_FLOWINFO_MASK & net_hdr_word(CMSG_DATA(cmsg));
- break;
-
- case IPV6_2292HOPOPTS:
---- a/net/ipv6/exthdrs.c
-+++ b/net/ipv6/exthdrs.c
-@@ -751,7 +751,7 @@ static bool ipv6_hop_jumbo(struct sk_buf
- goto drop;
- }
-
-- pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
-+ pkt_len = ntohl(net_hdr_word(nh + optoff + 2));
- if (pkt_len <= IPV6_MAXPLEN) {
- __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
- icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
---- a/include/linux/types.h
-+++ b/include/linux/types.h
-@@ -225,5 +225,11 @@ struct callback_head {
- typedef void (*rcu_callback_t)(struct rcu_head *head);
- typedef void (*call_rcu_func_t)(struct rcu_head *head, rcu_callback_t func);
-
-+struct net_hdr_word {
-+ u32 words[1];
-+} __attribute__((packed, aligned(2)));
-+
-+#define net_hdr_word(_p) (((struct net_hdr_word *) (_p))->words[0])
-+
- #endif /* __ASSEMBLY__ */
- #endif /* _LINUX_TYPES_H */
---- a/net/ipv4/af_inet.c
-+++ b/net/ipv4/af_inet.c
-@@ -1441,8 +1441,8 @@ struct sk_buff *inet_gro_receive(struct
- if (unlikely(ip_fast_csum((u8 *)iph, 5)))
- goto out_unlock;
-
-- id = ntohl(*(__be32 *)&iph->id);
-- flush = (u16)((ntohl(*(__be32 *)iph) ^ skb_gro_len(skb)) | (id & ~IP_DF));
-+ id = ntohl(net_hdr_word(&iph->id));
-+ flush = (u16)((ntohl(net_hdr_word(iph)) ^ skb_gro_len(skb)) | (id & ~IP_DF));
- id >>= 16;
-
- list_for_each_entry(p, head, list) {
---- a/net/ipv4/tcp_output.c
-+++ b/net/ipv4/tcp_output.c
-@@ -460,48 +460,53 @@ static void tcp_options_write(__be32 *pt
- u16 options = opts->options; /* mungable copy */
-
- if (unlikely(OPTION_MD5 & options)) {
-- *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
-- (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
-+ net_hdr_word(ptr++) =
-+ htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
-+ (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
- /* overload cookie hash location */
- opts->hash_location = (__u8 *)ptr;
- ptr += 4;
- }
-
- if (unlikely(opts->mss)) {
-- *ptr++ = htonl((TCPOPT_MSS << 24) |
-- (TCPOLEN_MSS << 16) |
-- opts->mss);
-+ net_hdr_word(ptr++) =
-+ htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) |
-+ opts->mss);
- }
-
- if (likely(OPTION_TS & options)) {
- if (unlikely(OPTION_SACK_ADVERTISE & options)) {
-- *ptr++ = htonl((TCPOPT_SACK_PERM << 24) |
-- (TCPOLEN_SACK_PERM << 16) |
-- (TCPOPT_TIMESTAMP << 8) |
-- TCPOLEN_TIMESTAMP);
-+ net_hdr_word(ptr++) =
-+ htonl((TCPOPT_SACK_PERM << 24) |
-+ (TCPOLEN_SACK_PERM << 16) |
-+ (TCPOPT_TIMESTAMP << 8) |
-+ TCPOLEN_TIMESTAMP);
- options &= ~OPTION_SACK_ADVERTISE;
- } else {
-- *ptr++ = htonl((TCPOPT_NOP << 24) |
-- (TCPOPT_NOP << 16) |
-- (TCPOPT_TIMESTAMP << 8) |
-- TCPOLEN_TIMESTAMP);
-+ net_hdr_word(ptr++) =
-+ htonl((TCPOPT_NOP << 24) |
-+ (TCPOPT_NOP << 16) |
-+ (TCPOPT_TIMESTAMP << 8) |
-+ TCPOLEN_TIMESTAMP);
- }
-- *ptr++ = htonl(opts->tsval);
-- *ptr++ = htonl(opts->tsecr);
-+ net_hdr_word(ptr++) = htonl(opts->tsval);
-+ net_hdr_word(ptr++) = htonl(opts->tsecr);
- }
-
- if (unlikely(OPTION_SACK_ADVERTISE & options)) {
-- *ptr++ = htonl((TCPOPT_NOP << 24) |
-- (TCPOPT_NOP << 16) |
-- (TCPOPT_SACK_PERM << 8) |
-- TCPOLEN_SACK_PERM);
-+ net_hdr_word(ptr++) =
-+ htonl((TCPOPT_NOP << 24) |
-+ (TCPOPT_NOP << 16) |
-+ (TCPOPT_SACK_PERM << 8) |
-+ TCPOLEN_SACK_PERM);
- }
-
- if (unlikely(OPTION_WSCALE & options)) {
-- *ptr++ = htonl((TCPOPT_NOP << 24) |
-- (TCPOPT_WINDOW << 16) |
-- (TCPOLEN_WINDOW << 8) |
-- opts->ws);
-+ net_hdr_word(ptr++) =
-+ htonl((TCPOPT_NOP << 24) |
-+ (TCPOPT_WINDOW << 16) |
-+ (TCPOLEN_WINDOW << 8) |
-+ opts->ws);
- }
-
- if (unlikely(opts->num_sack_blocks)) {
-@@ -509,16 +514,17 @@ static void tcp_options_write(__be32 *pt
- tp->duplicate_sack : tp->selective_acks;
- int this_sack;
-
-- *ptr++ = htonl((TCPOPT_NOP << 24) |
-- (TCPOPT_NOP << 16) |
-- (TCPOPT_SACK << 8) |
-- (TCPOLEN_SACK_BASE + (opts->num_sack_blocks *
-+ net_hdr_word(ptr++) =
-+ htonl((TCPOPT_NOP << 24) |
-+ (TCPOPT_NOP << 16) |
-+ (TCPOPT_SACK << 8) |
-+ (TCPOLEN_SACK_BASE + (opts->num_sack_blocks *
- TCPOLEN_SACK_PERBLOCK)));
-
- for (this_sack = 0; this_sack < opts->num_sack_blocks;
- ++this_sack) {
-- *ptr++ = htonl(sp[this_sack].start_seq);
-- *ptr++ = htonl(sp[this_sack].end_seq);
-+ net_hdr_word(ptr++) = htonl(sp[this_sack].start_seq);
-+ net_hdr_word(ptr++) = htonl(sp[this_sack].end_seq);
- }
-
- tp->rx_opt.dsack = 0;
-@@ -531,13 +537,14 @@ static void tcp_options_write(__be32 *pt
-
- if (foc->exp) {
- len = TCPOLEN_EXP_FASTOPEN_BASE + foc->len;
-- *ptr = htonl((TCPOPT_EXP << 24) | (len << 16) |
-+ net_hdr_word(ptr) =
-+ htonl((TCPOPT_EXP << 24) | (len << 16) |
- TCPOPT_FASTOPEN_MAGIC);
- p += TCPOLEN_EXP_FASTOPEN_BASE;
- } else {
- len = TCPOLEN_FASTOPEN_BASE + foc->len;
-- *p++ = TCPOPT_FASTOPEN;
-- *p++ = len;
-+ net_hdr_word(p++) = TCPOPT_FASTOPEN;
-+ net_hdr_word(p++) = len;
- }
-
- memcpy(p, foc->val, foc->len);
---- a/include/uapi/linux/igmp.h
-+++ b/include/uapi/linux/igmp.h
-@@ -33,7 +33,7 @@ struct igmphdr {
- __u8 code; /* For newer IGMP */
- __sum16 csum;
- __be32 group;
--};
-+} __attribute__((packed, aligned(2)));
-
- /* V3 group record types [grec_type] */
- #define IGMPV3_MODE_IS_INCLUDE 1
-@@ -49,7 +49,7 @@ struct igmpv3_grec {
- __be16 grec_nsrcs;
- __be32 grec_mca;
- __be32 grec_src[0];
--};
-+} __attribute__((packed, aligned(2)));
-
- struct igmpv3_report {
- __u8 type;
-@@ -58,7 +58,7 @@ struct igmpv3_report {
- __be16 resv2;
- __be16 ngrec;
- struct igmpv3_grec grec[0];
--};
-+} __attribute__((packed, aligned(2)));
-
- struct igmpv3_query {
- __u8 type;
-@@ -79,7 +79,7 @@ struct igmpv3_query {
- __u8 qqic;
- __be16 nsrcs;
- __be32 srcs[0];
--};
-+} __attribute__((packed, aligned(2)));
-
- #define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* From RFC1112 */
- #define IGMP_HOST_MEMBERSHIP_REPORT 0x12 /* Ditto */
---- a/net/core/flow_dissector.c
-+++ b/net/core/flow_dissector.c
-@@ -212,7 +212,7 @@ __be32 __skb_flow_get_ports(const struct
- ports = __skb_header_pointer(skb, thoff + poff,
- sizeof(_ports), data, hlen, &_ports);
- if (ports)
-- return *ports;
-+ return (__be32)net_hdr_word(ports);
- }
-
- return 0;
---- a/include/uapi/linux/icmpv6.h
-+++ b/include/uapi/linux/icmpv6.h
-@@ -77,7 +77,7 @@ struct icmp6hdr {
- #define icmp6_addrconf_other icmp6_dataun.u_nd_ra.other
- #define icmp6_rt_lifetime icmp6_dataun.u_nd_ra.rt_lifetime
- #define icmp6_router_pref icmp6_dataun.u_nd_ra.router_pref
--};
-+} __attribute__((packed, aligned(2)));
-
-
- #define ICMPV6_ROUTER_PREF_LOW 0x3
---- a/include/net/ndisc.h
-+++ b/include/net/ndisc.h
-@@ -92,7 +92,7 @@ struct ra_msg {
- struct icmp6hdr icmph;
- __be32 reachable_time;
- __be32 retrans_timer;
--};
-+} __attribute__((packed, aligned(2)));
-
- struct rd_msg {
- struct icmp6hdr icmph;
-@@ -371,10 +371,10 @@ static inline u32 ndisc_hashfn(const voi
- {
- const u32 *p32 = pkey;
-
-- return (((p32[0] ^ hash32_ptr(dev)) * hash_rnd[0]) +
-- (p32[1] * hash_rnd[1]) +
-- (p32[2] * hash_rnd[2]) +
-- (p32[3] * hash_rnd[3]));
-+ return (((net_hdr_word(&p32[0]) ^ hash32_ptr(dev)) * hash_rnd[0]) +
-+ (net_hdr_word(&p32[1]) * hash_rnd[1]) +
-+ (net_hdr_word(&p32[2]) * hash_rnd[2]) +
-+ (net_hdr_word(&p32[3]) * hash_rnd[3]));
- }
-
- static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey)
---- a/net/sched/cls_u32.c
-+++ b/net/sched/cls_u32.c
-@@ -155,7 +155,7 @@ next_knode:
- data = skb_header_pointer(skb, toff, 4, &hdata);
- if (!data)
- goto out;
-- if ((*data ^ key->val) & key->mask) {
-+ if ((net_hdr_word(data) ^ key->val) & key->mask) {
- n = rcu_dereference_bh(n->next);
- goto next_knode;
- }
-@@ -206,8 +206,8 @@ check_terminal:
- &hdata);
- if (!data)
- goto out;
-- sel = ht->divisor & u32_hash_fold(*data, &n->sel,
-- n->fshift);
-+ sel = ht->divisor & u32_hash_fold(net_hdr_word(data),
-+ &n->sel, n->fshift);
- }
- if (!(n->sel.flags & (TC_U32_VAROFFSET | TC_U32_OFFSET | TC_U32_EAT)))
- goto next_ht;
---- a/net/ipv6/ip6_offload.c
-+++ b/net/ipv6/ip6_offload.c
-@@ -240,7 +240,7 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *
- continue;
-
- iph2 = (struct ipv6hdr *)(p->data + off);
-- first_word = *(__be32 *)iph ^ *(__be32 *)iph2;
-+ first_word = net_hdr_word(iph) ^ net_hdr_word(iph2);
-
- /* All fields must match except length and Traffic Class.
- * XXX skbs on the gro_list have all been parsed and pulled
---- a/include/net/addrconf.h
-+++ b/include/net/addrconf.h
-@@ -47,7 +47,7 @@ struct prefix_info {
- __be32 reserved2;
-
- struct in6_addr prefix;
--};
-+} __attribute__((packed, aligned(2)));
-
- #include <linux/ipv6.h>
- #include <linux/netdevice.h>
---- a/include/net/inet_ecn.h
-+++ b/include/net/inet_ecn.h
-@@ -140,9 +140,9 @@ static inline int IP6_ECN_set_ce(struct
- if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph)))
- return 0;
-
-- from = *(__be32 *)iph;
-+ from = net_hdr_word(iph);
- to = from | htonl(INET_ECN_CE << 20);
-- *(__be32 *)iph = to;
-+ net_hdr_word(iph) = to;
- if (skb->ip_summed == CHECKSUM_COMPLETE)
- skb->csum = csum_add(csum_sub(skb->csum, (__force __wsum)from),
- (__force __wsum)to);
---- a/include/net/ipv6.h
-+++ b/include/net/ipv6.h
-@@ -146,7 +146,7 @@ struct frag_hdr {
- __u8 reserved;
- __be16 frag_off;
- __be32 identification;
--};
-+} __attribute__((packed, aligned(2)));
-
- #define IP6_MF 0x0001
- #define IP6_OFFSET 0xFFF8
-@@ -557,8 +557,8 @@ static inline void __ipv6_addr_set_half(
- }
- #endif
- #endif
-- addr[0] = wh;
-- addr[1] = wl;
-+ net_hdr_word(&addr[0]) = wh;
-+ net_hdr_word(&addr[1]) = wl;
- }
-
- static inline void ipv6_addr_set(struct in6_addr *addr,
-@@ -617,6 +617,8 @@ static inline bool ipv6_prefix_equal(con
- const __be32 *a1 = addr1->s6_addr32;
- const __be32 *a2 = addr2->s6_addr32;
- unsigned int pdw, pbi;
-+ /* Used for last <32-bit fraction of prefix */
-+ u32 pbia1, pbia2;
-
- /* check complete u32 in prefix */
- pdw = prefixlen >> 5;
-@@ -625,7 +627,9 @@ static inline bool ipv6_prefix_equal(con
-
- /* check incomplete u32 in prefix */
- pbi = prefixlen & 0x1f;
-- if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0xffffffff) << (32 - pbi))))
-+ pbia1 = net_hdr_word(&a1[pdw]);
-+ pbia2 = net_hdr_word(&a2[pdw]);
-+ if (pbi && ((pbia1 ^ pbia2) & htonl((0xffffffff) << (32 - pbi))))
- return false;
-
- return true;
-@@ -741,13 +745,13 @@ static inline void ipv6_addr_set_v4mappe
- */
- static inline int __ipv6_addr_diff32(const void *token1, const void *token2, int addrlen)
- {
-- const __be32 *a1 = token1, *a2 = token2;
-+ const struct in6_addr *a1 = token1, *a2 = token2;
- int i;
-
- addrlen >>= 2;
-
- for (i = 0; i < addrlen; i++) {
-- __be32 xb = a1[i] ^ a2[i];
-+ __be32 xb = a1->s6_addr32[i] ^ a2->s6_addr32[i];
- if (xb)
- return i * 32 + 31 - __fls(ntohl(xb));
- }
-@@ -934,17 +938,18 @@ static inline int ip6_multipath_hash_pol
- static inline void ip6_flow_hdr(struct ipv6hdr *hdr, unsigned int tclass,
- __be32 flowlabel)
- {
-- *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | flowlabel;
-+ net_hdr_word((__be32 *)hdr) =
-+ htonl(0x60000000 | (tclass << 20)) | flowlabel;
- }
-
- static inline __be32 ip6_flowinfo(const struct ipv6hdr *hdr)
- {
-- return *(__be32 *)hdr & IPV6_FLOWINFO_MASK;
-+ return net_hdr_word((__be32 *)hdr) & IPV6_FLOWINFO_MASK;
- }
-
- static inline __be32 ip6_flowlabel(const struct ipv6hdr *hdr)
- {
-- return *(__be32 *)hdr & IPV6_FLOWLABEL_MASK;
-+ return net_hdr_word((__be32 *)hdr) & IPV6_FLOWLABEL_MASK;
- }
-
- static inline u8 ip6_tclass(__be32 flowinfo)
---- a/include/net/secure_seq.h
-+++ b/include/net/secure_seq.h
-@@ -3,6 +3,7 @@
- #define _NET_SECURE_SEQ
-
- #include <linux/types.h>
-+#include <linux/in6.h>
-
- u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
- u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
---- a/include/uapi/linux/in.h
-+++ b/include/uapi/linux/in.h
-@@ -84,7 +84,7 @@ enum {
- /* Internet address. */
- struct in_addr {
- __be32 s_addr;
--};
-+} __attribute__((packed, aligned(2)));
- #endif
-
- #define IP_TOS 1
---- a/net/ipv6/ip6_fib.c
-+++ b/net/ipv6/ip6_fib.c
-@@ -140,7 +140,7 @@ static __be32 addr_bit_set(const void *t
- * See include/asm-generic/bitops/le.h.
- */
- return (__force __be32)(1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)) &
-- addr[fn_bit >> 5];
-+ net_hdr_word(&addr[fn_bit >> 5]);
- }
-
- struct fib6_info *fib6_info_alloc(gfp_t gfp_flags, bool with_fib6_nh)
---- a/net/netfilter/nf_conntrack_proto_tcp.c
-+++ b/net/netfilter/nf_conntrack_proto_tcp.c
-@@ -415,7 +415,7 @@ static void tcp_sack(const struct sk_buf
-
- /* Fast path for timestamp-only option */
- if (length == TCPOLEN_TSTAMP_ALIGNED
-- && *(__be32 *)ptr == htonl((TCPOPT_NOP << 24)
-+ && net_hdr_word(ptr) == htonl((TCPOPT_NOP << 24)
- | (TCPOPT_NOP << 16)
- | (TCPOPT_TIMESTAMP << 8)
- | TCPOLEN_TIMESTAMP))
---- a/net/xfrm/xfrm_input.c
-+++ b/net/xfrm/xfrm_input.c
-@@ -162,8 +162,8 @@ int xfrm_parse_spi(struct sk_buff *skb,
- if (!pskb_may_pull(skb, hlen))
- return -EINVAL;
-
-- *spi = *(__be32 *)(skb_transport_header(skb) + offset);
-- *seq = *(__be32 *)(skb_transport_header(skb) + offset_seq);
-+ *spi = net_hdr_word(skb_transport_header(skb) + offset);
-+ *seq = net_hdr_word(skb_transport_header(skb) + offset_seq);
- return 0;
- }
- EXPORT_SYMBOL(xfrm_parse_spi);
---- a/net/ipv4/tcp_input.c
-+++ b/net/ipv4/tcp_input.c
-@@ -3976,14 +3976,16 @@ static bool tcp_parse_aligned_timestamp(
- {
- const __be32 *ptr = (const __be32 *)(th + 1);
-
-- if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
-- | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
-+ if (net_hdr_word(ptr) ==
-+ htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
-+ (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
- tp->rx_opt.saw_tstamp = 1;
- ++ptr;
-- tp->rx_opt.rcv_tsval = ntohl(*ptr);
-+ tp->rx_opt.rcv_tsval = get_unaligned_be32(ptr);
- ++ptr;
-- if (*ptr)
-- tp->rx_opt.rcv_tsecr = ntohl(*ptr) - tp->tsoffset;
-+ if (net_hdr_word(ptr))
-+ tp->rx_opt.rcv_tsecr = get_unaligned_be32(ptr) -
-+ tp->tsoffset;
- else
- tp->rx_opt.rcv_tsecr = 0;
- return true;
---- a/include/uapi/linux/if_pppox.h
-+++ b/include/uapi/linux/if_pppox.h
-@@ -51,6 +51,7 @@ struct pppoe_addr {
- */
- struct pptp_addr {
- __u16 call_id;
-+ __u16 pad;
- struct in_addr sin_addr;
- };
-
---- a/net/ipv6/netfilter/nf_log_ipv6.c
-+++ b/net/ipv6/netfilter/nf_log_ipv6.c
-@@ -63,9 +63,9 @@ static void dump_ipv6_packet(struct net
- /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
- nf_log_buf_add(m, "LEN=%zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
- ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
-- (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
-+ (ntohl(net_hdr_word(ih)) & 0x0ff00000) >> 20,
- ih->hop_limit,
-- (ntohl(*(__be32 *)ih) & 0x000fffff));
-+ (ntohl(net_hdr_word(ih)) & 0x000fffff));
-
- fragment = 0;
- ptr = ip6hoff + sizeof(struct ipv6hdr);
---- a/include/net/neighbour.h
-+++ b/include/net/neighbour.h
-@@ -275,8 +275,10 @@ static inline bool neigh_key_eq128(const
- const u32 *n32 = (const u32 *)n->primary_key;
- const u32 *p32 = pkey;
-
-- return ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) |
-- (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0;
-+ return ((n32[0] ^ net_hdr_word(&p32[0])) |
-+ (n32[1] ^ net_hdr_word(&p32[1])) |
-+ (n32[2] ^ net_hdr_word(&p32[2])) |
-+ (n32[3] ^ net_hdr_word(&p32[3]))) == 0;
- }
-
- static inline struct neighbour *___neigh_lookup_noref(
---- a/include/uapi/linux/netfilter_arp/arp_tables.h
-+++ b/include/uapi/linux/netfilter_arp/arp_tables.h
-@@ -70,7 +70,7 @@ struct arpt_arp {
- __u8 flags;
- /* Inverse flags */
- __u16 invflags;
--};
-+} __attribute__((aligned(4)));
-
- /* Values for "flag" field in struct arpt_ip (general arp structure).
- * No flags defined yet.
---- a/net/core/utils.c
-+++ b/net/core/utils.c
-@@ -460,8 +460,14 @@ void inet_proto_csum_replace16(__sum16 *
- bool pseudohdr)
- {
- __be32 diff[] = {
-- ~from[0], ~from[1], ~from[2], ~from[3],
-- to[0], to[1], to[2], to[3],
-+ ~net_hdr_word(&from[0]),
-+ ~net_hdr_word(&from[1]),
-+ ~net_hdr_word(&from[2]),
-+ ~net_hdr_word(&from[3]),
-+ net_hdr_word(&to[0]),
-+ net_hdr_word(&to[1]),
-+ net_hdr_word(&to[2]),
-+ net_hdr_word(&to[3]),
- };
- if (skb->ip_summed != CHECKSUM_PARTIAL) {
- *sum = csum_fold(csum_partial(diff, sizeof(diff),
---- a/include/linux/etherdevice.h
-+++ b/include/linux/etherdevice.h
-@@ -489,7 +489,7 @@ static inline bool is_etherdev_addr(cons
- * @b: Pointer to Ethernet header
- *
- * Compare two Ethernet headers, returns 0 if equal.
-- * This assumes that the network header (i.e., IP header) is 4-byte
-+ * This assumes that the network header (i.e., IP header) is 2-byte
- * aligned OR the platform can handle unaligned access. This is the
- * case for all packets coming into netif_receive_skb or similar
- * entry points.
-@@ -512,11 +512,12 @@ static inline unsigned long compare_ethe
- fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6);
- return fold;
- #else
-- u32 *a32 = (u32 *)((u8 *)a + 2);
-- u32 *b32 = (u32 *)((u8 *)b + 2);
-+ const u16 *a16 = a;
-+ const u16 *b16 = b;
-
-- return (*(u16 *)a ^ *(u16 *)b) | (a32[0] ^ b32[0]) |
-- (a32[1] ^ b32[1]) | (a32[2] ^ b32[2]);
-+ return (a16[0] ^ b16[0]) | (a16[1] ^ b16[1]) | (a16[2] ^ b16[2]) |
-+ (a16[3] ^ b16[3]) | (a16[4] ^ b16[4]) | (a16[5] ^ b16[5]) |
-+ (a16[6] ^ b16[6]);
- #endif
- }
-
---- a/net/ipv4/tcp_offload.c
-+++ b/net/ipv4/tcp_offload.c
-@@ -223,7 +223,7 @@ struct sk_buff *tcp_gro_receive(struct l
-
- th2 = tcp_hdr(p);
-
-- if (*(u32 *)&th->source ^ *(u32 *)&th2->source) {
-+ if (net_hdr_word(&th->source) ^ net_hdr_word(&th2->source)) {
- NAPI_GRO_CB(p)->same_flow = 0;
- continue;
- }
-@@ -241,8 +241,8 @@ found:
- ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH));
- flush |= (__force int)(th->ack_seq ^ th2->ack_seq);
- for (i = sizeof(*th); i < thlen; i += 4)
-- flush |= *(u32 *)((u8 *)th + i) ^
-- *(u32 *)((u8 *)th2 + i);
-+ flush |= net_hdr_word((u8 *)th + i) ^
-+ net_hdr_word((u8 *)th2 + i);
-
- /* When we receive our second frame we can made a decision on if we
- * continue this flow as an atomic flow with a fixed ID or if we use
---- a/net/ipv6/netfilter/ip6table_mangle.c
-+++ b/net/ipv6/netfilter/ip6table_mangle.c
-@@ -47,7 +47,7 @@ ip6t_mangle_out(struct sk_buff *skb, con
- hop_limit = ipv6_hdr(skb)->hop_limit;
-
- /* flowlabel and prio (includes version, which shouldn't change either */
-- flowlabel = *((u_int32_t *)ipv6_hdr(skb));
-+ flowlabel = net_hdr_word(ipv6_hdr(skb));
-
- ret = ip6t_do_table(skb, state, state->net->ipv6.ip6table_mangle);
-
-@@ -56,7 +56,7 @@ ip6t_mangle_out(struct sk_buff *skb, con
- !ipv6_addr_equal(&ipv6_hdr(skb)->daddr, &daddr) ||
- skb->mark != mark ||
- ipv6_hdr(skb)->hop_limit != hop_limit ||
-- flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
-+ flowlabel != net_hdr_word(ipv6_hdr(skb)))) {
- err = ip6_route_me_harder(state->net, state->sk, skb);
- if (err < 0)
- ret = NF_DROP_ERR(err);
+++ /dev/null
---- a/drivers/mfd/Kconfig
-+++ b/drivers/mfd/Kconfig
-@@ -2012,5 +2012,13 @@ config RAVE_SP_CORE
- Select this to get support for the Supervisory Processor
- device found on several devices in RAVE line of hardware.
-
-+config MFD_RB4XX_CPLD
-+ tristate "CPLD driver for Mikrotik RB4xx series boards"
-+ select MFD_CORE
-+ depends on ATH79 || COMPILE_TEST
-+ help
-+ Enables support for the CPLD chip (NAND & GPIO) on Mikrotik
-+ Routerboard RB4xx series.
-+
- endmenu
- endif
---- a/drivers/mfd/Makefile
-+++ b/drivers/mfd/Makefile
-@@ -256,3 +256,4 @@ obj-$(CONFIG_MFD_ROHM_BD70528) += rohm-b
- obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o
- obj-$(CONFIG_MFD_STMFX) += stmfx.o
-
-+obj-$(CONFIG_MFD_RB4XX_CPLD) += rb4xx-cpld.o
---- a/drivers/gpio/Kconfig
-+++ b/drivers/gpio/Kconfig
-@@ -1408,6 +1408,12 @@ config GPIO_SODAVILLE
- help
- Say Y here to support Intel Sodaville GPIO.
-
-+config GPIO_RB4XX
-+ tristate "GPIO expander for Mikrotik RB4xx series boards"
-+ depends on MFD_RB4XX_CPLD
-+ help
-+ GPIO driver for Mikrotik Routerboard RB4xx series.
-+
- endmenu
-
- menu "SPI GPIO expanders"
---- a/drivers/gpio/Makefile
-+++ b/drivers/gpio/Makefile
-@@ -113,6 +113,7 @@ obj-$(CONFIG_GPIO_PL061) += gpio-pl061.
- obj-$(CONFIG_GPIO_PMIC_EIC_SPRD) += gpio-pmic-eic-sprd.o
- obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
- obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
-+obj-$(CONFIG_GPIO_RB4XX) += gpio-rb4xx.o
- obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
- obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
- obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
---- a/drivers/mtd/nand/raw/Kconfig
-+++ b/drivers/mtd/nand/raw/Kconfig
-@@ -552,4 +552,11 @@ config MTD_NAND_AR934X
- Enables support for NAND controller on Qualcomm Atheros SoCs.
- This controller is found on AR934x and QCA955x SoCs.
-
-+config MTD_NAND_RB4XX
-+ tristate "Support for NAND driver for Mikrotik RB4xx series boards"
-+ depends on MFD_RB4XX_CPLD
-+ help
-+ Enables support for the NAND flash chip on Mikrotik Routerboard
-+ RB4xx series.
-+
- endif # MTD_RAW_NAND
---- a/drivers/mtd/nand/raw/Makefile
-+++ b/drivers/mtd/nand/raw/Makefile
-@@ -58,6 +58,7 @@ obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_n
- obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o
- obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o
- obj-$(CONFIG_MTD_NAND_AR934X) += ar934x_nand.o
-+obj-$(CONFIG_MTD_NAND_RB4XX) += nand_rb4xx.o
-
- nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
- nand-objs += nand_onfi.o
+++ /dev/null
-From b3797d1a92afe97c173b00fdb7824cedba24eef0 Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Sun, 20 Sep 2020 01:00:45 +0800
-Subject: [PATCH] ath79: ar8216: make switch register access atomic
-
-due to some unknown reason these register accesses sometimes fail
-on the integrated switch without this patch.
-
-THIS ONLY WORKS ON ATH79 AND MAY BREAK THE DRIVER ON OTHER PLATFORMS!
-The mdio bus on ath79 works in polling mode and doesn't rely on
-any interrupt. This patch breaks the driver on any mdio master
-with interrupts used.
-
----
---- a/drivers/net/phy/ar8216.c
-+++ b/drivers/net/phy/ar8216.c
-@@ -252,6 +252,7 @@ ar8xxx_mii_write32(struct ar8xxx_priv *p
- u32
- ar8xxx_read(struct ar8xxx_priv *priv, int reg)
- {
-+ unsigned long flags;
- struct mii_bus *bus = priv->mii_bus;
- u16 r1, r2, page;
- u32 val;
-@@ -259,11 +260,13 @@ ar8xxx_read(struct ar8xxx_priv *priv, in
- split_addr((u32) reg, &r1, &r2, &page);
-
- mutex_lock(&bus->mdio_lock);
-+ local_irq_save(flags);
-
- bus->write(bus, 0x18, 0, page);
- wait_for_page_switch();
- val = ar8xxx_mii_read32(priv, 0x10 | r2, r1);
-
-+ local_irq_restore(flags);
- mutex_unlock(&bus->mdio_lock);
-
- return val;
-@@ -272,17 +275,20 @@ ar8xxx_read(struct ar8xxx_priv *priv, in
- void
- ar8xxx_write(struct ar8xxx_priv *priv, int reg, u32 val)
- {
-+ unsigned long flags;
- struct mii_bus *bus = priv->mii_bus;
- u16 r1, r2, page;
-
- split_addr((u32) reg, &r1, &r2, &page);
-
- mutex_lock(&bus->mdio_lock);
-+ local_irq_save(flags);
-
- bus->write(bus, 0x18, 0, page);
- wait_for_page_switch();
- ar8xxx_mii_write32(priv, 0x10 | r2, r1, val);
-
-+ local_irq_restore(flags);
- mutex_unlock(&bus->mdio_lock);
- }
-
+++ /dev/null
---- a/drivers/mtd/nand/raw/Kconfig
-+++ b/drivers/mtd/nand/raw/Kconfig
-@@ -559,4 +559,8 @@ config MTD_NAND_RB4XX
- Enables support for the NAND flash chip on Mikrotik Routerboard
- RB4xx series.
-
-+config MTD_NAND_RB91X
-+ tristate "MikroTik RB91x NAND driver support"
-+ depends on ATH79 && MTD_RAW_NAND
-+
- endif # MTD_RAW_NAND
---- a/drivers/mtd/nand/raw/Makefile
-+++ b/drivers/mtd/nand/raw/Makefile
-@@ -59,6 +59,7 @@ obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm
- obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o
- obj-$(CONFIG_MTD_NAND_AR934X) += ar934x_nand.o
- obj-$(CONFIG_MTD_NAND_RB4XX) += nand_rb4xx.o
-+obj-$(CONFIG_MTD_NAND_RB91X) += rb91x_nand.o
-
- nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
- nand-objs += nand_onfi.o
---- a/drivers/gpio/Kconfig
-+++ b/drivers/gpio/Kconfig
-@@ -130,6 +130,10 @@ config GPIO_ATH79
- Select this option to enable GPIO driver for
- Atheros AR71XX/AR724X/AR913X SoC devices.
-
-+config GPIO_LATCH
-+ tristate "MikroTik RouterBOARD GPIO latch support"
-+ depends on ATH79
-+
- config GPIO_RASPBERRYPI_EXP
- tristate "Raspberry Pi 3 GPIO Expander"
- default RASPBERRYPI_FIRMWARE
---- a/drivers/gpio/Makefile
-+++ b/drivers/gpio/Makefile
-@@ -67,6 +67,7 @@ obj-$(CONFIG_GPIO_IT87) += gpio-it87.o
- obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o
- obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
- obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o
-+obj-$(CONFIG_GPIO_LATCH) += gpio-latch.o
- obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o
- obj-$(CONFIG_GPIO_LOONGSON) += gpio-loongson.o
- obj-$(CONFIG_GPIO_LP3943) += gpio-lp3943.o