LINUX_RELEASE?=1
LINUX_VERSION-3.18 = .43
-LINUX_VERSION-4.4 = .61
+LINUX_VERSION-4.4 = .69
LINUX_VERSION-4.9 = .20
LINUX_KERNEL_HASH-3.18.43 = 1236e8123a6ce537d5029232560966feed054ae31776fe8481dd7d18cdd5492c
-LINUX_KERNEL_HASH-4.4.61 = 30dee7164615ad8184eba4ea6f4906b3ceb2fe462a8a4a929c8e9aab8d4a31da
+LINUX_KERNEL_HASH-4.4.69 = 207bbc50aaf827d667a2762312bd6127887cc669ff7a7270b876e7102b8f84fa
LINUX_KERNEL_HASH-4.9.20 = 48660806dd32fb8dcbcf5932291bf6cc7d29240070372230871e0f56fea81341
ifdef KERNEL_PATCHVER
- u32 bootstrap;
+ void __iomem *phy_reg;
+ u32 t;
-
-- bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
-- if (bootstrap & AR934X_BOOTSTRAP_USB_MODE_DEVICE)
++
+ phy_reg = ioremap(base, 4);
+ if (!phy_reg)
+ return;
+
+ iounmap(phy_reg);
+}
-+
+
+- bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
+- if (bootstrap & AR934X_BOOTSTRAP_USB_MODE_DEVICE)
+static void ar934x_usb_reset_notifier(struct platform_device *pdev)
+{
+ if (pdev->id != -1)
+#define AR934X_RESET_LUT BIT(2)
+#define AR934X_RESET_MBOX BIT(1)
+#define AR934X_RESET_I2S BIT(0)
-
++
+#define QCA955X_RESET_HOST BIT(31)
+#define QCA955X_RESET_SLIC BIT(30)
+#define QCA955X_RESET_HDMA BIT(29)
+#define QCA955X_RESET_LUT BIT(2)
+#define QCA955X_RESET_MBOX BIT(1)
+#define QCA955X_RESET_I2S BIT(0)
-+
+
+#define AR933X_BOOTSTRAP_MDIO_GPIO_EN BIT(18)
+#define AR933X_BOOTSTRAP_EEPBUSY BIT(4)
#define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0)
+static void __init ap136_common_setup(void)
+{
+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
-
--static int ap136_pci_plat_dev_init(struct pci_dev *dev)
++
+ ath79_register_m25p80(NULL);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap136_leds_gpio),
+ ath79_register_wmac(art + AP136_WMAC_CALDATA_OFFSET, NULL);
+
+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN);
-+
+
+-static int ap136_pci_plat_dev_init(struct pci_dev *dev)
+ ath79_register_mdio(0, 0x0);
+ ath79_init_mac(ath79_eth0_data.mac_addr, art + AP136_MAC0_OFFSET, 0);
+
+ /* GMAC0 of the AR8327 switch is connected to GMAC1 via SGMII */
+ ap136_ar8327_pad0_cfg.mode = AR8327_PAD_MAC_SGMII;
+ ap136_ar8327_pad0_cfg.sgmii_delay_en = true;
-
-- ath79_pci_set_plat_dev_init(ap136_pci_plat_dev_init);
-- ath79_register_pci();
++
+ /* GMAC6 of the AR8327 switch is connected to GMAC0 via RGMII */
+ ap136_ar8327_pad6_cfg.mode = AR8327_PAD_MAC_RGMII;
+ ap136_ar8327_pad6_cfg.txclk_delay_en = true;
+ ap136_ar8327_pad6_cfg.rxclk_delay_en = true;
+ ap136_ar8327_pad6_cfg.txclk_delay_sel = AR8327_CLK_DELAY_SEL1;
+ ap136_ar8327_pad6_cfg.rxclk_delay_sel = AR8327_CLK_DELAY_SEL2;
-+
+
+- ath79_pci_set_plat_dev_init(ap136_pci_plat_dev_init);
+- ath79_register_pci();
+ ath79_eth0_pll_data.pll_1000 = 0x56000000;
+ ath79_eth1_pll_data.pll_1000 = 0x03000101;
+
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
-@@ -1407,7 +1407,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
+@@ -1409,7 +1409,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
dsfield = ipv6_get_dsfield(ipv6h);
if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
* XXX skbs on the gro_list have all been parsed and pulled
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
-@@ -43,7 +43,7 @@ struct prefix_info {
+@@ -45,7 +45,7 @@ struct prefix_info {
__be32 reserved2;
struct in6_addr prefix;
static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
-@@ -883,7 +883,7 @@ static inline void ci_role_destroy(struc
+@@ -851,7 +851,7 @@ static inline void ci_role_destroy(struc
{
ci_hdrc_gadget_destroy(ci);
ci_hdrc_host_destroy(ci);
ci_hdrc_otg_destroy(ci);
}
-@@ -934,6 +934,9 @@ static int ci_hdrc_probe(struct platform
+@@ -902,6 +902,9 @@ static int ci_hdrc_probe(struct platform
ci->supports_runtime_pm = !!(ci->platdata->flags &
CI_HDRC_SUPPORTS_RUNTIME_PM);
ret = hw_device_init(ci, base);
if (ret < 0) {
dev_err(dev, "can't initialize hardware\n");
-@@ -999,7 +1002,7 @@ static int ci_hdrc_probe(struct platform
+@@ -967,7 +970,7 @@ static int ci_hdrc_probe(struct platform
goto deinit_phy;
}
dev_err(dev, "init otg fails, ret = %d\n", ret);
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
-@@ -95,8 +95,10 @@ enum ci_role ci_otg_role(struct ci_hdrc
+@@ -131,8 +131,10 @@ enum ci_role ci_otg_role(struct ci_hdrc
void ci_handle_vbus_change(struct ci_hdrc *ci)
{
usb_gadget_vbus_connect(&ci->gadget);
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
-@@ -55,6 +55,7 @@ struct ci_hdrc_platform_data {
+@@ -57,6 +57,7 @@ struct ci_hdrc_platform_data {
#define CI_HDRC_OVERRIDE_AHB_BURST BIT(9)
#define CI_HDRC_OVERRIDE_TX_BURST BIT(10)
#define CI_HDRC_OVERRIDE_RX_BURST BIT(11)
continue;
}
-@@ -254,10 +258,11 @@ static int bcm47xxpart_parse(struct mtd_
+@@ -252,10 +256,11 @@ static int bcm47xxpart_parse(struct mtd_
}
/* Read middle of the block */
continue;
}
-@@ -277,10 +282,11 @@ static int bcm47xxpart_parse(struct mtd_
+@@ -275,10 +280,11 @@ static int bcm47xxpart_parse(struct mtd_
}
offset = master->size - possible_nvram_sizes[i];
+++ /dev/null
-From bd5d21310133921021d78995ad6346f908483124 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 20 Nov 2016 16:09:30 +0100
-Subject: [PATCH] mtd: bcm47xxpart: fix parsing first block after aligned TRX
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-After parsing TRX we should skip to the first block placed behind it.
-Our code was working only with TRX with length not aligned to the
-blocksize. In other cases (length aligned) it was missing the block
-places right after TRX.
-
-This fixes calculation and simplifies the comment.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Brian Norris <computersforpeace@gmail.com>
----
- drivers/mtd/bcm47xxpart.c | 10 ++++------
- 1 file changed, 4 insertions(+), 6 deletions(-)
-
---- a/drivers/mtd/bcm47xxpart.c
-+++ b/drivers/mtd/bcm47xxpart.c
-@@ -229,12 +229,10 @@ static int bcm47xxpart_parse(struct mtd_
-
- last_trx_part = curr_part - 1;
-
-- /*
-- * We have whole TRX scanned, skip to the next part. Use
-- * roundown (not roundup), as the loop will increase
-- * offset in next step.
-- */
-- offset = rounddown(offset + trx->length, blocksize);
-+ /* Jump to the end of TRX */
-+ offset = roundup(offset + trx->length, blocksize);
-+ /* Next loop iteration will increase the offset */
-+ offset -= blocksize;
- continue;
- }
-
+++ /dev/null
-From: Matt Redfearn <matt.redfearn@imgtec.com>
-Date: Mon, 19 Dec 2016 14:20:56 +0000
-Subject: [PATCH] MIPS: Introduce irq_stack
-
-Allocate a per-cpu irq stack for use within interrupt handlers.
-
-Also add a utility function on_irq_stack to determine if a given stack
-pointer is within the irq stack for that cpu.
-
-Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
----
-
---- a/arch/mips/include/asm/irq.h
-+++ b/arch/mips/include/asm/irq.h
-@@ -17,6 +17,18 @@
-
- #include <irq.h>
-
-+#define IRQ_STACK_SIZE THREAD_SIZE
-+
-+extern void *irq_stack[NR_CPUS];
-+
-+static inline bool on_irq_stack(int cpu, unsigned long sp)
-+{
-+ unsigned long low = (unsigned long)irq_stack[cpu];
-+ unsigned long high = low + IRQ_STACK_SIZE;
-+
-+ return (low <= sp && sp <= high);
-+}
-+
- #ifdef CONFIG_I8259
- static inline int irq_canonicalize(int irq)
- {
---- a/arch/mips/kernel/asm-offsets.c
-+++ b/arch/mips/kernel/asm-offsets.c
-@@ -101,6 +101,7 @@ void output_thread_info_defines(void)
- OFFSET(TI_REGS, thread_info, regs);
- DEFINE(_THREAD_SIZE, THREAD_SIZE);
- DEFINE(_THREAD_MASK, THREAD_MASK);
-+ DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);
- BLANK();
- }
-
---- a/arch/mips/kernel/irq.c
-+++ b/arch/mips/kernel/irq.c
-@@ -25,6 +25,8 @@
- #include <linux/atomic.h>
- #include <asm/uaccess.h>
-
-+void *irq_stack[NR_CPUS];
-+
- /*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves.
-@@ -55,6 +57,15 @@ void __init init_IRQ(void)
- irq_set_noprobe(i);
-
- arch_init_irq();
-+
-+ for_each_possible_cpu(i) {
-+ int irq_pages = IRQ_STACK_SIZE / PAGE_SIZE;
-+ void *s = (void *)__get_free_pages(GFP_KERNEL, irq_pages);
-+
-+ irq_stack[i] = s;
-+ pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i,
-+ irq_stack[i], irq_stack[i] + IRQ_STACK_SIZE);
-+ }
- }
-
- #ifdef CONFIG_DEBUG_STACKOVERFLOW
+++ /dev/null
-From: Matt Redfearn <matt.redfearn@imgtec.com>
-Date: Mon, 19 Dec 2016 14:20:57 +0000
-Subject: [PATCH] MIPS: Stack unwinding while on IRQ stack
-
-Within unwind stack, check if the stack pointer being unwound is within
-the CPU's irq_stack and if so use that page rather than the task's stack
-page.
-
-Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
----
-
---- a/arch/mips/kernel/process.c
-+++ b/arch/mips/kernel/process.c
-@@ -32,6 +32,7 @@
- #include <asm/cpu.h>
- #include <asm/dsp.h>
- #include <asm/fpu.h>
-+#include <asm/irq.h>
- #include <asm/msa.h>
- #include <asm/pgtable.h>
- #include <asm/mipsregs.h>
-@@ -552,7 +553,19 @@ EXPORT_SYMBOL(unwind_stack_by_address);
- unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
- unsigned long pc, unsigned long *ra)
- {
-- unsigned long stack_page = (unsigned long)task_stack_page(task);
-+ unsigned long stack_page = 0;
-+ int cpu;
-+
-+ for_each_possible_cpu(cpu) {
-+ if (on_irq_stack(cpu, *sp)) {
-+ stack_page = (unsigned long)irq_stack[cpu];
-+ break;
-+ }
-+ }
-+
-+ if (!stack_page)
-+ stack_page = (unsigned long)task_stack_page(task);
-+
- return unwind_stack_by_address(stack_page, sp, pc, ra);
- }
- #endif
+++ /dev/null
-From: Matt Redfearn <matt.redfearn@imgtec.com>
-Date: Mon, 19 Dec 2016 14:20:58 +0000
-Subject: [PATCH] MIPS: Only change $28 to thread_info if coming from user
- mode
-
-The SAVE_SOME macro is used to save the execution context on all
-exceptions.
-If an exception occurs while executing user code, the stack is switched
-to the kernel's stack for the current task, and register $28 is switched
-to point to the current_thread_info, which is at the bottom of the stack
-region.
-If the exception occurs while executing kernel code, the stack is left,
-and this change ensures that register $28 is not updated. This is the
-correct behaviour when the kernel can be executing on the separate irq
-stack, because the thread_info will not be at the base of it.
-
-With this change, register $28 is only switched to it's kernel
-conventional usage of the currrent thread info pointer at the point at
-which execution enters kernel space. Doing it on every exception was
-redundant, but OK without an IRQ stack, but will be erroneous once that
-is introduced.
-
-Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
-Reviewed-by: Maciej W. Rozycki <macro@imgtec.com>
----
-
---- a/arch/mips/include/asm/stackframe.h
-+++ b/arch/mips/include/asm/stackframe.h
-@@ -216,12 +216,19 @@
- LONG_S $25, PT_R25(sp)
- LONG_S $28, PT_R28(sp)
- LONG_S $31, PT_R31(sp)
-+
-+ /* Set thread_info if we're coming from user mode */
-+ mfc0 k0, CP0_STATUS
-+ sll k0, 3 /* extract cu0 bit */
-+ bltz k0, 9f
-+
- ori $28, sp, _THREAD_MASK
- xori $28, _THREAD_MASK
- #ifdef CONFIG_CPU_CAVIUM_OCTEON
- .set mips64
- pref 0, 0($28) /* Prefetch the current pointer */
- #endif
-+9:
- .set pop
- .endm
-
+++ /dev/null
-From: Matt Redfearn <matt.redfearn@imgtec.com>
-Date: Mon, 19 Dec 2016 14:20:59 +0000
-Subject: [PATCH] MIPS: Switch to the irq_stack in interrupts
-
-When enterring interrupt context via handle_int or except_vec_vi, switch
-to the irq_stack of the current CPU if it is not already in use.
-
-The current stack pointer is masked with the thread size and compared to
-the base or the irq stack. If it does not match then the stack pointer
-is set to the top of that stack, otherwise this is a nested irq being
-handled on the irq stack so the stack pointer should be left as it was.
-
-The in-use stack pointer is placed in the callee saved register s1. It
-will be saved to the stack when plat_irq_dispatch is invoked and can be
-restored once control returns here.
-
-Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
----
-
---- a/arch/mips/kernel/genex.S
-+++ b/arch/mips/kernel/genex.S
-@@ -188,9 +188,44 @@ NESTED(handle_int, PT_SIZE, sp)
-
- LONG_L s0, TI_REGS($28)
- LONG_S sp, TI_REGS($28)
-- PTR_LA ra, ret_from_irq
-- PTR_LA v0, plat_irq_dispatch
-- jr v0
-+
-+ /*
-+ * SAVE_ALL ensures we are using a valid kernel stack for the thread.
-+ * Check if we are already using the IRQ stack.
-+ */
-+ move s1, sp # Preserve the sp
-+
-+ /* Get IRQ stack for this CPU */
-+ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG
-+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
-+ lui k1, %hi(irq_stack)
-+#else
-+ lui k1, %highest(irq_stack)
-+ daddiu k1, %higher(irq_stack)
-+ dsll k1, 16
-+ daddiu k1, %hi(irq_stack)
-+ dsll k1, 16
-+#endif
-+ LONG_SRL k0, SMP_CPUID_PTRSHIFT
-+ LONG_ADDU k1, k0
-+ LONG_L t0, %lo(irq_stack)(k1)
-+
-+ # Check if already on IRQ stack
-+ PTR_LI t1, ~(_THREAD_SIZE-1)
-+ and t1, t1, sp
-+ beq t0, t1, 2f
-+
-+ /* Switch to IRQ stack */
-+ li t1, _IRQ_STACK_SIZE
-+ PTR_ADD sp, t0, t1
-+
-+2:
-+ jal plat_irq_dispatch
-+
-+ /* Restore sp */
-+ move sp, s1
-+
-+ j ret_from_irq
- #ifdef CONFIG_CPU_MICROMIPS
- nop
- #endif
-@@ -263,8 +298,44 @@ NESTED(except_vec_vi_handler, 0, sp)
-
- LONG_L s0, TI_REGS($28)
- LONG_S sp, TI_REGS($28)
-- PTR_LA ra, ret_from_irq
-- jr v0
-+
-+ /*
-+ * SAVE_ALL ensures we are using a valid kernel stack for the thread.
-+ * Check if we are already using the IRQ stack.
-+ */
-+ move s1, sp # Preserve the sp
-+
-+ /* Get IRQ stack for this CPU */
-+ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG
-+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
-+ lui k1, %hi(irq_stack)
-+#else
-+ lui k1, %highest(irq_stack)
-+ daddiu k1, %higher(irq_stack)
-+ dsll k1, 16
-+ daddiu k1, %hi(irq_stack)
-+ dsll k1, 16
-+#endif
-+ LONG_SRL k0, SMP_CPUID_PTRSHIFT
-+ LONG_ADDU k1, k0
-+ LONG_L t0, %lo(irq_stack)(k1)
-+
-+ # Check if already on IRQ stack
-+ PTR_LI t1, ~(_THREAD_SIZE-1)
-+ and t1, t1, sp
-+ beq t0, t1, 2f
-+
-+ /* Switch to IRQ stack */
-+ li t1, _IRQ_STACK_SIZE
-+ PTR_ADD sp, t0, t1
-+
-+2:
-+ jal plat_irq_dispatch
-+
-+ /* Restore sp */
-+ move sp, s1
-+
-+ j ret_from_irq
- END(except_vec_vi_handler)
-
- /*
+++ /dev/null
-From: Matt Redfearn <matt.redfearn@imgtec.com>
-Date: Mon, 19 Dec 2016 14:21:00 +0000
-Subject: [PATCH] MIPS: Select HAVE_IRQ_EXIT_ON_IRQ_STACK
-
-Since do_IRQ is now invoked on a separate IRQ stack, we select
-HAVE_IRQ_EXIT_ON_IRQ_STACK so that softirq's may be invoked directly
-from irq_exit(), rather than requiring do_softirq_own_stack.
-
-Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
----
-
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -9,6 +9,7 @@ config MIPS
- select HAVE_CONTEXT_TRACKING
- select HAVE_GENERIC_DMA_COHERENT
- select HAVE_IDE
-+ select HAVE_IRQ_EXIT_ON_IRQ_STACK
- select HAVE_OPROFILE
- select HAVE_PERF_EVENTS
- select PERF_USE_VMALLOC
+++ /dev/null
-From de856416e7143e32afc4849625616554aa060f7a Mon Sep 17 00:00:00 2001
-From: Matt Redfearn <matt.redfearn@imgtec.com>
-Date: Wed, 25 Jan 2017 17:00:25 +0000
-Subject: [PATCH] MIPS: IRQ Stack: Fix erroneous jal to plat_irq_dispatch
-
-Commit dda45f701c9d ("MIPS: Switch to the irq_stack in interrupts")
-changed both the normal and vectored interrupt handlers. Unfortunately
-the vectored version, "except_vec_vi_handler", was incorrectly modified
-to unconditionally jal to plat_irq_dispatch, rather than doing a jalr to
-the vectored handler that has been set up. This is ok for many platforms
-which set the vectored handler to plat_irq_dispatch anyway, but will
-cause problems with platforms that use other handlers.
-
-Fixes: dda45f701c9d ("MIPS: Switch to the irq_stack in interrupts")
-Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
-Cc: Ralf Baechle <ralf@linux-mips.org>
-Cc: Paul Burton <paul.burton@imgtec.com>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/15110/
-Signed-off-by: James Hogan <james.hogan@imgtec.com>
----
- arch/mips/kernel/genex.S | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/mips/kernel/genex.S
-+++ b/arch/mips/kernel/genex.S
-@@ -330,7 +330,7 @@ NESTED(except_vec_vi_handler, 0, sp)
- PTR_ADD sp, t0, t1
-
- 2:
-- jal plat_irq_dispatch
-+ jalr v0
-
- /* Restore sp */
- move sp, s1
if (sock->type == SOCK_PACKET)
po->prot_hook.func = packet_rcv_spkt;
-@@ -3737,6 +3740,16 @@ packet_setsockopt(struct socket *sock, i
+@@ -3739,6 +3742,16 @@ packet_setsockopt(struct socket *sock, i
po->xmit = val ? packet_direct_xmit : dev_queue_xmit;
return 0;
}
default:
return -ENOPROTOOPT;
}
-@@ -3789,6 +3802,13 @@ static int packet_getsockopt(struct sock
+@@ -3791,6 +3804,13 @@ static int packet_getsockopt(struct sock
case PACKET_VNET_HDR:
val = po->has_vnet_hdr;
break;
__skb_tunnel_rx(skb, t->dev, t->net);
-@@ -1245,6 +1382,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
+@@ -1247,6 +1384,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
__u32 mtu;
u8 tproto;
int err;
tproto = ACCESS_ONCE(t->parms.proto);
if ((tproto != IPPROTO_IPV6 && tproto != 0) ||
-@@ -1275,6 +1413,18 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
+@@ -1277,6 +1415,18 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
fl6.flowi6_mark = skb->mark;
err = ip6_tnl_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu);
if (err != 0) {
if (err == -EMSGSIZE)
-@@ -1389,6 +1539,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
+@@ -1391,6 +1541,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
t->parms.flowinfo = p->flowinfo;
t->parms.link = p->link;
t->parms.proto = p->proto;
ip6_tnl_dst_reset(t);
ip6_tnl_link_config(t);
return 0;
-@@ -1427,6 +1585,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
+@@ -1429,6 +1587,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
p->flowinfo = u->flowinfo;
p->link = u->link;
p->proto = u->proto;
memcpy(p->name, u->name, sizeof(u->name));
}
-@@ -1722,6 +1881,15 @@ static int ip6_tnl_validate(struct nlatt
+@@ -1724,6 +1883,15 @@ static int ip6_tnl_validate(struct nlatt
return 0;
}
static void ip6_tnl_netlink_parms(struct nlattr *data[],
struct __ip6_tnl_parm *parms)
{
-@@ -1753,6 +1921,46 @@ static void ip6_tnl_netlink_parms(struct
+@@ -1755,6 +1923,46 @@ static void ip6_tnl_netlink_parms(struct
if (data[IFLA_IPTUN_PROTO])
parms->proto = nla_get_u8(data[IFLA_IPTUN_PROTO]);
}
static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
-@@ -1805,6 +2013,12 @@ static void ip6_tnl_dellink(struct net_d
+@@ -1807,6 +2015,12 @@ static void ip6_tnl_dellink(struct net_d
static size_t ip6_tnl_get_size(const struct net_device *dev)
{
return
/* IFLA_IPTUN_LINK */
nla_total_size(4) +
-@@ -1822,6 +2036,24 @@ static size_t ip6_tnl_get_size(const str
+@@ -1824,6 +2038,24 @@ static size_t ip6_tnl_get_size(const str
nla_total_size(4) +
/* IFLA_IPTUN_PROTO */
nla_total_size(1) +
0;
}
-@@ -1829,6 +2061,9 @@ static int ip6_tnl_fill_info(struct sk_b
+@@ -1831,6 +2063,9 @@ static int ip6_tnl_fill_info(struct sk_b
{
struct ip6_tnl *tunnel = netdev_priv(dev);
struct __ip6_tnl_parm *parm = &tunnel->parms;
if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) ||
nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) ||
-@@ -1837,8 +2072,27 @@ static int ip6_tnl_fill_info(struct sk_b
+@@ -1839,8 +2074,27 @@ static int ip6_tnl_fill_info(struct sk_b
nla_put_u8(skb, IFLA_IPTUN_ENCAP_LIMIT, parm->encap_limit) ||
nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) ||
nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) ||
return 0;
nla_put_failure:
-@@ -1862,6 +2116,7 @@ static const struct nla_policy ip6_tnl_p
+@@ -1864,6 +2118,7 @@ static const struct nla_policy ip6_tnl_p
[IFLA_IPTUN_FLOWINFO] = { .type = NLA_U32 },
[IFLA_IPTUN_FLAGS] = { .type = NLA_U32 },
[IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
static const struct rt6_info ip6_blk_hole_entry_template = {
.dst = {
.__refcnt = ATOMIC_INIT(1),
-@@ -1885,6 +1902,11 @@ static struct rt6_info *ip6_route_info_c
+@@ -1889,6 +1906,11 @@ static struct rt6_info *ip6_route_info_c
rt->dst.output = ip6_pkt_prohibit_out;
rt->dst.input = ip6_pkt_prohibit;
break;
case RTN_THROW:
case RTN_UNREACHABLE:
default:
-@@ -2486,6 +2508,17 @@ static int ip6_pkt_prohibit_out(struct n
+@@ -2492,6 +2514,17 @@ static int ip6_pkt_prohibit_out(struct n
return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
}
/*
* Allocate a dst for local (unicast / anycast) address.
*/
-@@ -2728,7 +2761,8 @@ static int rtm_to_fib6_config(struct sk_
+@@ -2734,7 +2767,8 @@ static int rtm_to_fib6_config(struct sk_
if (rtm->rtm_type == RTN_UNREACHABLE ||
rtm->rtm_type == RTN_BLACKHOLE ||
rtm->rtm_type == RTN_PROHIBIT ||
cfg->fc_flags |= RTF_REJECT;
if (rtm->rtm_type == RTN_LOCAL)
-@@ -3087,6 +3121,9 @@ static int rt6_fill_node(struct net *net
+@@ -3093,6 +3127,9 @@ static int rt6_fill_node(struct net *net
case -EACCES:
rtm->rtm_type = RTN_PROHIBIT;
break;
case -EAGAIN:
rtm->rtm_type = RTN_THROW;
break;
-@@ -3363,6 +3400,8 @@ static int ip6_route_dev_notify(struct n
+@@ -3372,6 +3409,8 @@ static int ip6_route_dev_notify(struct n
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
net->ipv6.ip6_prohibit_entry->dst.dev = dev;
net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
#endif
-@@ -3579,6 +3618,17 @@ static int __net_init ip6_route_net_init
+@@ -3594,6 +3633,17 @@ static int __net_init ip6_route_net_init
net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
ip6_template_metrics, true);
#endif
net->ipv6.sysctl.flush_delay = 0;
-@@ -3597,6 +3647,8 @@ out:
+@@ -3612,6 +3662,8 @@ out:
return ret;
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
out_ip6_prohibit_entry:
kfree(net->ipv6.ip6_prohibit_entry);
out_ip6_null_entry:
-@@ -3614,6 +3666,7 @@ static void __net_exit ip6_route_net_exi
+@@ -3629,6 +3681,7 @@ static void __net_exit ip6_route_net_exi
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
kfree(net->ipv6.ip6_prohibit_entry);
kfree(net->ipv6.ip6_blk_hole_entry);
#endif
dst_entries_destroy(&net->ipv6.ip6_dst_ops);
}
-@@ -3711,6 +3764,9 @@ int __init ip6_route_init(void)
+@@ -3702,6 +3755,9 @@ void __init ip6_route_init_special_entri
init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
+ init_net.ipv6.ip6_policy_failed_entry->rt6i_idev =
+ in6_dev_get(init_net.loopback_dev);
#endif
- ret = fib6_init();
- if (ret)
+ }
+
/* disable */
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~BIT(i),
LTQ_EIU_EXIN_INEN);
-@@ -344,10 +344,10 @@ static int icu_map(struct irq_domain *d,
+@@ -343,10 +343,10 @@ static int icu_map(struct irq_domain *d,
return 0;
for (i = 0; i < exin_avail; i++)
return 0;
}
-@@ -437,14 +437,14 @@ int __init icu_of_init(struct device_nod
+@@ -441,14 +441,14 @@ int __init icu_of_init(struct device_nod
eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway");
if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
/* find out how many external irq sources we have */
--- /dev/null
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 19 Jan 2017 12:14:44 +0100
+Subject: [PATCH] MIPS: Lantiq: Fix cascaded IRQ setup
+
+With the IRQ stack changes integrated, the XRX200 devices started
+emitting a constant stream of kernel messages like this:
+
+[ 565.415310] Spurious IRQ: CAUSE=0x1100c300
+
+This appears to be caused by IP0 firing for some reason without being
+handled. Fix this by setting up IP2-6 as a proper chained IRQ handler and
+calling do_IRQ for all MIPS CPU interrupts.
+
+Cc: john@phrozen.org
+Cc: stable@vger.kernel.org
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/arch/mips/lantiq/irq.c
++++ b/arch/mips/lantiq/irq.c
+@@ -271,6 +271,11 @@ static void ltq_hw5_irqdispatch(void)
+ DEFINE_HWx_IRQDISPATCH(5)
+ #endif
+
++static void ltq_hw_irq_handler(struct irq_desc *desc)
++{
++ ltq_hw_irqdispatch(irq_desc_get_irq(desc) - 2);
++}
++
+ #ifdef CONFIG_MIPS_MT_SMP
+ void __init arch_init_ipiirq(int irq, struct irqaction *action)
+ {
+@@ -315,23 +320,19 @@ static struct irqaction irq_call = {
+ asmlinkage void plat_irq_dispatch(void)
+ {
+ unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+- unsigned int i;
++ int irq;
+
+- if ((MIPS_CPU_TIMER_IRQ == 7) && (pending & CAUSEF_IP7)) {
+- do_IRQ(MIPS_CPU_TIMER_IRQ);
+- goto out;
+- } else {
+- for (i = 0; i < MAX_IM; i++) {
+- if (pending & (CAUSEF_IP2 << i)) {
+- ltq_hw_irqdispatch(i);
+- goto out;
+- }
+- }
++ if (!pending) {
++ spurious_interrupt();
++ return;
+ }
+- pr_alert("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status());
+
+-out:
+- return;
++ pending >>= CAUSEB_IP;
++ while (pending) {
++ irq = fls(pending) - 1;
++ do_IRQ(MIPS_CPU_IRQ_BASE + irq);
++ pending &= ~BIT(irq);
++ }
+ }
+
+ static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+@@ -356,11 +357,6 @@ static const struct irq_domain_ops irq_d
+ .map = icu_map,
+ };
+
+-static struct irqaction cascade = {
+- .handler = no_action,
+- .name = "cascade",
+-};
+-
+ int __init icu_of_init(struct device_node *node, struct device_node *parent)
+ {
+ struct device_node *eiu_node;
+@@ -392,7 +388,7 @@ int __init icu_of_init(struct device_nod
+ mips_cpu_irq_init();
+
+ for (i = 0; i < MAX_IM; i++)
+- setup_irq(i + 2, &cascade);
++ irq_set_chained_handler(i + 2, ltq_hw_irq_handler);
+
+ if (cpu_has_vint) {
+ pr_info("Setting up vectored interrupts\n");
int INFTL_mount(struct INFTLrecord *s);
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
-@@ -142,7 +142,9 @@
+@@ -137,7 +137,9 @@
#endif
#ifndef map_bankwidth
static inline int map_bankwidth(void *map)
{
BUG();
-@@ -238,8 +240,11 @@ struct map_info {
+@@ -233,8 +235,11 @@ struct map_info {
If there is no cache to care about this can be set to NULL. */
void (*inval_cache)(struct map_info *, unsigned long, ssize_t);
return IRQ_HANDLED;
--- a/drivers/net/ethernet/mediatek/gsw_mt7620.h
+++ b/drivers/net/ethernet/mediatek/gsw_mt7620.h
-@@ -113,5 +113,6 @@ u32 mt7530_mdio_r32(struct mt7620_gsw *g
+@@ -119,5 +119,6 @@ u32 mt7530_mdio_r32(struct mt7620_gsw *g
u32 _mt7620_mii_write(struct mt7620_gsw *gsw, u32 phy_addr,
u32 phy_register, u32 write_data);
u32 _mt7620_mii_read(struct mt7620_gsw *gsw, int phy_addr, int phy_reg);
#define GSW_REG_PORT_PMCR(x) (0x3000 + (x * 0x100))
#define GSW_REG_PORT_STATUS(x) (0x3008 + (x * 0x100))
#define GSW_REG_SMACCR0 0x3fE4
-@@ -76,6 +78,7 @@
+@@ -82,6 +84,7 @@
#define PHY_PRE_EN BIT(30)
#define PMY_MDC_CONF(_x) ((_x & 0x3f) << 24)
--- a/drivers/clk/sunxi/clk-simple-gates.c
+++ b/drivers/clk/sunxi/clk-simple-gates.c
-@@ -158,3 +158,15 @@ CLK_OF_DECLARE(sun5i_a13_ahb, "allwinner
+@@ -160,3 +160,15 @@ CLK_OF_DECLARE(sun5i_a13_ahb, "allwinner
sun4i_a10_ahb_init);
CLK_OF_DECLARE(sun7i_a20_ahb, "allwinner,sun7i-a20-ahb-gates-clk",
sun4i_a10_ahb_init);
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
-@@ -68,6 +68,7 @@ Required properties:
+@@ -70,6 +70,7 @@ Required properties:
"allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13
"allwinner,sun6i-a31-usb-clk" - for usb gates + resets on A31
"allwinner,sun8i-a23-usb-clk" - for usb gates + resets on A23
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
-@@ -71,6 +71,7 @@ Required properties:
+@@ -73,6 +73,7 @@ Required properties:
"allwinner,sun8i-h3-usb-clk" - for usb gates + resets on H3
"allwinner,sun9i-a80-usb-mod-clk" - for usb gates + resets on A80
"allwinner,sun9i-a80-usb-phy-clk" - for usb phy gates + resets on A80
Required properties for all clocks:
- reg : shall be the control register address for the clock.
-@@ -90,6 +91,9 @@ Required properties for all clocks:
+@@ -92,6 +93,9 @@ Required properties for all clocks:
And "allwinner,*-usb-clk" clocks also require:
- reset-cells : shall be set to 1