From 3dac521a49dc1fba0484968ce0c0cb6bc406ab34 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sat, 15 Dec 2012 02:01:08 +0000 Subject: remove 3.3 and 3.6 SVN-Revision: 34699 --- ...antiq-explicitly-enable-clkout-generation.patch | 34 - .../0002-MIPS-lantiq-split-up-IRQ-IM-ranges.patch | 195 -- ...PS-lantiq-timer-irq-can-be-different-to-7.patch | 84 - ...-dont-register-irq_chip-for-the-irq-casca.patch | 30 - ...-external-irq-sources-are-not-loaded-prop.patch | 31 - ...-adds-support-for-nmi-and-ejtag-bootrom-v.patch | 39 - ...q-falcon-clocks-were-not-enabled-properly.patch | 30 - ...-enable-pci-clk-conditional-for-xrx200-So.patch | 31 - ...-MIPS-lantiq-adds-support-for-gptu-timers.patch | 246 --- ...MIPS-lantiq-implement-lantiq-xway-pinctrl.patch | 1632 -------------- ...l-MIPS-lantiq-adds-support-for-FALCON-SoC.patch | 554 ----- ...vicetree-add-OF-documents-for-lantiq-xway.patch | 121 -- ...vicetree-add-OF-documents-for-lantiq-falc.patch | 108 - ...014-MIPS-lantiq-make-use-of-__gpio_to_irq.patch | 33 - ...antiq-fix-overflow-inside-stp-xway-driver.patch | 34 - ...antiq-Add-NAND-support-on-Lantiq-XWAY-SoC.patch | 257 --- ...-external-interrupt-units-not-loaded-prop.patch | 71 - .../0101-MIPS-lantiq-bootsel-bits-are-wrong.patch | 27 - .../0102-MIPS-lantiq-fixes-dma-irq-ack.patch | 62 - ...q-prom-code-invalidated-devicetree-memory.patch | 36 - ...-xway-split-ltq_reset_once-into-2-subfunc.patch | 60 - ...-lantiq-xway-adds-reset-code-for-11G-PHYs.patch | 210 -- ...IPS-lantiq-xway-adds-PHY11G-platform-code.patch | 607 ------ ...107-MIPS-lantiq-add-xrx200-ethernet-clock.patch | 28 - ...irmware-lantiq-adds-PHY11G-firmware-blobs.patch | 2221 -------------------- ...ntiq-xway-fix-NAND-reset-timeout-handling.patch | 47 - ...110-NET-PHY-adds-driver-for-lantiq-PHY11G.patch | 228 -- ...-lantiq-update-etop-driver-for-devicetree.patch | 807 ------- .../0112-NET-MIPS-lantiq-adds-xrx200-net.patch | 1382 ------------ .../patches-3.6/0113-EASY80920-dts-file.patch | 539 ----- .../patches-3.6/0200-MIPS-dtb-image-hack.patch | 26 - .../patches-3.6/0201-lantiq-dtb-image-hack.patch | 58 - .../lantiq/patches-3.6/0300-owrt-mtd-split.patch | 230 -- .../linux/lantiq/patches-3.6/0301-owrt-atm.patch | 80 - 34 files changed, 10178 deletions(-) delete mode 100644 target/linux/lantiq/patches-3.6/0001-MIPS-lantiq-explicitly-enable-clkout-generation.patch delete mode 100644 target/linux/lantiq/patches-3.6/0002-MIPS-lantiq-split-up-IRQ-IM-ranges.patch delete mode 100644 target/linux/lantiq/patches-3.6/0003-MIPS-lantiq-timer-irq-can-be-different-to-7.patch delete mode 100644 target/linux/lantiq/patches-3.6/0004-MIPS-lantiq-dont-register-irq_chip-for-the-irq-casca.patch delete mode 100644 target/linux/lantiq/patches-3.6/0005-MIPS-lantiq-external-irq-sources-are-not-loaded-prop.patch delete mode 100644 target/linux/lantiq/patches-3.6/0006-MIPS-lantiq-adds-support-for-nmi-and-ejtag-bootrom-v.patch delete mode 100644 target/linux/lantiq/patches-3.6/0007-MIPS-lantiq-falcon-clocks-were-not-enabled-properly.patch delete mode 100644 target/linux/lantiq/patches-3.6/0008-MIPS-lantiq-enable-pci-clk-conditional-for-xrx200-So.patch delete mode 100644 target/linux/lantiq/patches-3.6/0009-MIPS-lantiq-adds-support-for-gptu-timers.patch delete mode 100644 target/linux/lantiq/patches-3.6/0010-OF-pinctrl-MIPS-lantiq-implement-lantiq-xway-pinctrl.patch delete mode 100644 target/linux/lantiq/patches-3.6/0011-OF-pinctrl-MIPS-lantiq-adds-support-for-FALCON-SoC.patch delete mode 100644 target/linux/lantiq/patches-3.6/0012-Document-devicetree-add-OF-documents-for-lantiq-xway.patch delete mode 100644 target/linux/lantiq/patches-3.6/0013-Document-devicetree-add-OF-documents-for-lantiq-falc.patch delete mode 100644 target/linux/lantiq/patches-3.6/0014-MIPS-lantiq-make-use-of-__gpio_to_irq.patch delete mode 100644 target/linux/lantiq/patches-3.6/0015-GPIO-MIPS-lantiq-fix-overflow-inside-stp-xway-driver.patch delete mode 100644 target/linux/lantiq/patches-3.6/0016-mtd-lantiq-Add-NAND-support-on-Lantiq-XWAY-SoC.patch delete mode 100644 target/linux/lantiq/patches-3.6/0100-MIPS-lantiq-external-interrupt-units-not-loaded-prop.patch delete mode 100644 target/linux/lantiq/patches-3.6/0101-MIPS-lantiq-bootsel-bits-are-wrong.patch delete mode 100644 target/linux/lantiq/patches-3.6/0102-MIPS-lantiq-fixes-dma-irq-ack.patch delete mode 100644 target/linux/lantiq/patches-3.6/0103-MIPS-lantiq-prom-code-invalidated-devicetree-memory.patch delete mode 100644 target/linux/lantiq/patches-3.6/0104-MIPS-lantiq-xway-split-ltq_reset_once-into-2-subfunc.patch delete mode 100644 target/linux/lantiq/patches-3.6/0105-MIPS-lantiq-xway-adds-reset-code-for-11G-PHYs.patch delete mode 100644 target/linux/lantiq/patches-3.6/0106-MIPS-lantiq-xway-adds-PHY11G-platform-code.patch delete mode 100644 target/linux/lantiq/patches-3.6/0107-MIPS-lantiq-add-xrx200-ethernet-clock.patch delete mode 100644 target/linux/lantiq/patches-3.6/0108-firmware-lantiq-adds-PHY11G-firmware-blobs.patch delete mode 100644 target/linux/lantiq/patches-3.6/0109-MTD-lantiq-xway-fix-NAND-reset-timeout-handling.patch delete mode 100644 target/linux/lantiq/patches-3.6/0110-NET-PHY-adds-driver-for-lantiq-PHY11G.patch delete mode 100644 target/linux/lantiq/patches-3.6/0111-NET-MIPS-lantiq-update-etop-driver-for-devicetree.patch delete mode 100644 target/linux/lantiq/patches-3.6/0112-NET-MIPS-lantiq-adds-xrx200-net.patch delete mode 100644 target/linux/lantiq/patches-3.6/0113-EASY80920-dts-file.patch delete mode 100644 target/linux/lantiq/patches-3.6/0200-MIPS-dtb-image-hack.patch delete mode 100644 target/linux/lantiq/patches-3.6/0201-lantiq-dtb-image-hack.patch delete mode 100644 target/linux/lantiq/patches-3.6/0300-owrt-mtd-split.patch delete mode 100644 target/linux/lantiq/patches-3.6/0301-owrt-atm.patch (limited to 'target/linux/lantiq/patches-3.6') diff --git a/target/linux/lantiq/patches-3.6/0001-MIPS-lantiq-explicitly-enable-clkout-generation.patch b/target/linux/lantiq/patches-3.6/0001-MIPS-lantiq-explicitly-enable-clkout-generation.patch deleted file mode 100644 index 50428d6e6d..0000000000 --- a/target/linux/lantiq/patches-3.6/0001-MIPS-lantiq-explicitly-enable-clkout-generation.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 98dbc5764d8b6fa9cabe316fe725281703bf0fc6 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Tue, 24 Jul 2012 08:56:41 +0200 -Subject: [PATCH] MIPS: lantiq: explicitly enable clkout generation - -Previously we relied on the bootloader to have enabled this bit. However some -bootloaders seem to not enable this for us. - -Signed-off-by: John Crispin -Patchwork: http://patchwork.linux-mips.org/patch/4120/ ---- - arch/mips/lantiq/xway/sysctrl.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c -index befbb76..8430983 100644 ---- a/arch/mips/lantiq/xway/sysctrl.c -+++ b/arch/mips/lantiq/xway/sysctrl.c -@@ -187,10 +187,12 @@ static int clkout_enable(struct clk *clk) - for (i = 0; i < 4; i++) { - if (clk->rates[i] == clk->rate) { - int shift = 14 - (2 * clk->module); -+ int enable = 7 - clk->module; - unsigned int val = ltq_cgu_r32(ifccr); - - val &= ~(3 << shift); - val |= i << shift; -+ val |= enable; - ltq_cgu_w32(val, ifccr); - return 0; - } --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0002-MIPS-lantiq-split-up-IRQ-IM-ranges.patch b/target/linux/lantiq/patches-3.6/0002-MIPS-lantiq-split-up-IRQ-IM-ranges.patch deleted file mode 100644 index 17d3ab7e37..0000000000 --- a/target/linux/lantiq/patches-3.6/0002-MIPS-lantiq-split-up-IRQ-IM-ranges.patch +++ /dev/null @@ -1,195 +0,0 @@ -From 61fa969f27ec58296544bf94d058f3aa704cb8d9 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 16 Aug 2012 11:39:57 +0000 -Subject: [PATCH 2/9] MIPS: lantiq: split up IRQ IM ranges - -Up to now all our SoCs had the 5 IM ranges in a consecutive order. To accomodate -the SVIP we need to support IM ranges that are scattered inside the register range. - -Signed-off-by: John Crispin -Patchwork: http://patchwork.linux-mips.org/patch/4237/ ---- - .../include/asm/mach-lantiq/falcon/falcon_irq.h | 2 + - .../mips/include/asm/mach-lantiq/xway/lantiq_irq.h | 2 + - arch/mips/lantiq/irq.c | 60 +++++++++++--------- - 3 files changed, 36 insertions(+), 28 deletions(-) - -diff --git a/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h -index 318f982..c6b63a4 100644 ---- a/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h -+++ b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h -@@ -20,4 +20,6 @@ - - #define MIPS_CPU_TIMER_IRQ 7 - -+#define MAX_IM 5 -+ - #endif /* _FALCON_IRQ__ */ -diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h -index aa0b3b8..5eadfe5 100644 ---- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h -+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h -@@ -21,4 +21,6 @@ - - #define MIPS_CPU_TIMER_IRQ 7 - -+#define MAX_IM 5 -+ - #endif -diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c -index 57c1a4e..a2699a70 100644 ---- a/arch/mips/lantiq/irq.c -+++ b/arch/mips/lantiq/irq.c -@@ -55,8 +55,8 @@ - */ - #define LTQ_ICU_EBU_IRQ 22 - --#define ltq_icu_w32(x, y) ltq_w32((x), ltq_icu_membase + (y)) --#define ltq_icu_r32(x) ltq_r32(ltq_icu_membase + (x)) -+#define ltq_icu_w32(m, x, y) ltq_w32((x), ltq_icu_membase[m] + (y)) -+#define ltq_icu_r32(m, x) ltq_r32(ltq_icu_membase[m] + (x)) - - #define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y)) - #define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x)) -@@ -82,17 +82,17 @@ static unsigned short ltq_eiu_irq[MAX_EIU] = { - }; - - static int exin_avail; --static void __iomem *ltq_icu_membase; -+static void __iomem *ltq_icu_membase[MAX_IM]; - static void __iomem *ltq_eiu_membase; - - void ltq_disable_irq(struct irq_data *d) - { - u32 ier = LTQ_ICU_IM0_IER; - int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE; -+ int im = offset / INT_NUM_IM_OFFSET; - -- ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET); - offset %= INT_NUM_IM_OFFSET; -- ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier); -+ ltq_icu_w32(im, ltq_icu_r32(im, ier) & ~BIT(offset), ier); - } - - void ltq_mask_and_ack_irq(struct irq_data *d) -@@ -100,32 +100,31 @@ void ltq_mask_and_ack_irq(struct irq_data *d) - u32 ier = LTQ_ICU_IM0_IER; - u32 isr = LTQ_ICU_IM0_ISR; - int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE; -+ int im = offset / INT_NUM_IM_OFFSET; - -- ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET); -- isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET); - offset %= INT_NUM_IM_OFFSET; -- ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier); -- ltq_icu_w32(BIT(offset), isr); -+ ltq_icu_w32(im, ltq_icu_r32(im, ier) & ~BIT(offset), ier); -+ ltq_icu_w32(im, BIT(offset), isr); - } - - static void ltq_ack_irq(struct irq_data *d) - { - u32 isr = LTQ_ICU_IM0_ISR; - int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE; -+ int im = offset / INT_NUM_IM_OFFSET; - -- isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET); - offset %= INT_NUM_IM_OFFSET; -- ltq_icu_w32(BIT(offset), isr); -+ ltq_icu_w32(im, BIT(offset), isr); - } - - void ltq_enable_irq(struct irq_data *d) - { - u32 ier = LTQ_ICU_IM0_IER; - int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE; -+ int im = offset / INT_NUM_IM_OFFSET; - -- ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET); - offset %= INT_NUM_IM_OFFSET; -- ltq_icu_w32(ltq_icu_r32(ier) | BIT(offset), ier); -+ ltq_icu_w32(im, ltq_icu_r32(im, ier) | BIT(offset), ier); - } - - static unsigned int ltq_startup_eiu_irq(struct irq_data *d) -@@ -192,7 +191,7 @@ static void ltq_hw_irqdispatch(int module) - { - u32 irq; - -- irq = ltq_icu_r32(LTQ_ICU_IM0_IOSR + (module * LTQ_ICU_OFFSET)); -+ irq = ltq_icu_r32(module, LTQ_ICU_IM0_IOSR); - if (irq == 0) - return; - -@@ -275,7 +274,7 @@ asmlinkage void plat_irq_dispatch(void) - do_IRQ(MIPS_CPU_TIMER_IRQ); - goto out; - } else { -- for (i = 0; i < 5; i++) { -+ for (i = 0; i < MAX_IM; i++) { - if (pending & (CAUSEF_IP2 << i)) { - ltq_hw_irqdispatch(i); - goto out; -@@ -318,15 +317,19 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) - struct resource res; - int i; - -- if (of_address_to_resource(node, 0, &res)) -- panic("Failed to get icu memory range"); -+ for (i = 0; i < MAX_IM; i++) { -+ if (of_address_to_resource(node, i, &res)) -+ panic("Failed to get icu memory range"); - -- if (request_mem_region(res.start, resource_size(&res), res.name) < 0) -- pr_err("Failed to request icu memory"); -+ if (request_mem_region(res.start, resource_size(&res), -+ res.name) < 0) -+ pr_err("Failed to request icu memory"); - -- ltq_icu_membase = ioremap_nocache(res.start, resource_size(&res)); -- if (!ltq_icu_membase) -- panic("Failed to remap icu memory"); -+ ltq_icu_membase[i] = ioremap_nocache(res.start, -+ resource_size(&res)); -+ if (!ltq_icu_membase[i]) -+ panic("Failed to remap icu memory"); -+ } - - /* the external interrupts are optional and xway only */ - eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu"); -@@ -351,17 +354,17 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) - } - - /* turn off all irqs by default */ -- for (i = 0; i < 5; i++) { -+ for (i = 0; i < MAX_IM; i++) { - /* make sure all irqs are turned off by default */ -- ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET)); -+ ltq_icu_w32(i, 0, LTQ_ICU_IM0_IER); - /* clear all possibly pending interrupts */ -- ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET)); -+ ltq_icu_w32(i, ~0, LTQ_ICU_IM0_ISR); - } - - mips_cpu_irq_init(); - -- for (i = 2; i <= 6; i++) -- setup_irq(i, &cascade); -+ for (i = 0; i < MAX_IM; i++) -+ setup_irq(i + 2, &cascade); - - if (cpu_has_vint) { - pr_info("Setting up vectored interrupts\n"); -@@ -373,7 +376,8 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) - set_vi_handler(7, ltq_hw5_irqdispatch); - } - -- irq_domain_add_linear(node, 6 * INT_NUM_IM_OFFSET, -+ irq_domain_add_linear(node, -+ (MAX_IM * INT_NUM_IM_OFFSET) + MIPS_CPU_IRQ_CASCADE, - &irq_domain_ops, 0); - - #if defined(CONFIG_MIPS_MT_SMP) --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0003-MIPS-lantiq-timer-irq-can-be-different-to-7.patch b/target/linux/lantiq/patches-3.6/0003-MIPS-lantiq-timer-irq-can-be-different-to-7.patch deleted file mode 100644 index 26519d0055..0000000000 --- a/target/linux/lantiq/patches-3.6/0003-MIPS-lantiq-timer-irq-can-be-different-to-7.patch +++ /dev/null @@ -1,84 +0,0 @@ -From c2c9c788b91218bccbb9ac31539ffa577fe502bf Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 16 Aug 2012 08:09:20 +0000 -Subject: [PATCH 3/9] MIPS: lantiq: timer irq can be different to 7 - -The SVIP SoC has its timer IRQ on a different IRQ than 7. Fix up the irq -code to be able to handle this. - -Signed-off-by: John Crispin -Patchwork: http://patchwork.linux-mips.org/patch/4229/ ---- - arch/mips/lantiq/irq.c | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - -diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c -index a2699a70..0cec43d 100644 ---- a/arch/mips/lantiq/irq.c -+++ b/arch/mips/lantiq/irq.c -@@ -84,6 +84,7 @@ static unsigned short ltq_eiu_irq[MAX_EIU] = { - static int exin_avail; - static void __iomem *ltq_icu_membase[MAX_IM]; - static void __iomem *ltq_eiu_membase; -+static struct irq_domain *ltq_domain; - - void ltq_disable_irq(struct irq_data *d) - { -@@ -219,10 +220,14 @@ DEFINE_HWx_IRQDISPATCH(2) - DEFINE_HWx_IRQDISPATCH(3) - DEFINE_HWx_IRQDISPATCH(4) - -+#if MIPS_CPU_TIMER_IRQ == 7 - static void ltq_hw5_irqdispatch(void) - { - do_IRQ(MIPS_CPU_TIMER_IRQ); - } -+#else -+DEFINE_HWx_IRQDISPATCH(5) -+#endif - - #ifdef CONFIG_MIPS_MT_SMP - void __init arch_init_ipiirq(int irq, struct irqaction *action) -@@ -270,7 +275,7 @@ asmlinkage void plat_irq_dispatch(void) - unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; - unsigned int i; - -- if (pending & CAUSEF_IP7) { -+ if ((MIPS_CPU_TIMER_IRQ == 7) && (pending & CAUSEF_IP7)) { - do_IRQ(MIPS_CPU_TIMER_IRQ); - goto out; - } else { -@@ -376,7 +381,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) - set_vi_handler(7, ltq_hw5_irqdispatch); - } - -- irq_domain_add_linear(node, -+ ltq_domain = irq_domain_add_linear(node, - (MAX_IM * INT_NUM_IM_OFFSET) + MIPS_CPU_IRQ_CASCADE, - &irq_domain_ops, 0); - -@@ -401,12 +406,20 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) - - /* tell oprofile which irq to use */ - cp0_perfcount_irq = LTQ_PERF_IRQ; -+ -+ /* -+ * if the timer irq is not one of the mips irqs we need to -+ * create a mapping -+ */ -+ if (MIPS_CPU_TIMER_IRQ != 7) -+ irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ); -+ - return 0; - } - - unsigned int __cpuinit get_c0_compare_int(void) - { -- return CP0_LEGACY_COMPARE_IRQ; -+ return MIPS_CPU_TIMER_IRQ; - } - - static struct of_device_id __initdata of_irq_ids[] = { --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0004-MIPS-lantiq-dont-register-irq_chip-for-the-irq-casca.patch b/target/linux/lantiq/patches-3.6/0004-MIPS-lantiq-dont-register-irq_chip-for-the-irq-casca.patch deleted file mode 100644 index 6d8e38c3a0..0000000000 --- a/target/linux/lantiq/patches-3.6/0004-MIPS-lantiq-dont-register-irq_chip-for-the-irq-casca.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 9c1628b603ee9d2bb220be0400c5dc6950cf012b Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 16 Aug 2012 08:09:21 +0000 -Subject: [PATCH 4/9] MIPS: lantiq: dont register irq_chip for the irq cascade - -We dont want to register the irq_chip for the MIPS IRQ cascade. - -Signed-off-by: John Crispin -Patchwork: http://patchwork.linux-mips.org/patch/4230/ ---- - arch/mips/lantiq/irq.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c -index 0cec43d..87f15d6 100644 ---- a/arch/mips/lantiq/irq.c -+++ b/arch/mips/lantiq/irq.c -@@ -297,6 +297,9 @@ static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) - struct irq_chip *chip = <q_irq_type; - int i; - -+ if (hw < MIPS_CPU_IRQ_CASCADE) -+ return 0; -+ - for (i = 0; i < exin_avail; i++) - if (hw == ltq_eiu_irq[i]) - chip = <q_eiu_type; --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0005-MIPS-lantiq-external-irq-sources-are-not-loaded-prop.patch b/target/linux/lantiq/patches-3.6/0005-MIPS-lantiq-external-irq-sources-are-not-loaded-prop.patch deleted file mode 100644 index b67197e7a6..0000000000 --- a/target/linux/lantiq/patches-3.6/0005-MIPS-lantiq-external-irq-sources-are-not-loaded-prop.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 70ec9054e7a65c878298666083f7d5b70ccf9032 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 16 Aug 2012 08:09:22 +0000 -Subject: [PATCH 5/9] MIPS: lantiq: external irq sources are not loaded - properly - -Support for the external interrupt unit was broken when the code was converted -to devicetree support. - -Signed-off-by: John Crispin -Patchwork: http://patchwork.linux-mips.org/patch/4231/ ---- - arch/mips/lantiq/irq.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c -index 87f15d6..f36acd1 100644 ---- a/arch/mips/lantiq/irq.c -+++ b/arch/mips/lantiq/irq.c -@@ -341,7 +341,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) - - /* the external interrupts are optional and xway only */ - eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu"); -- if (eiu_node && of_address_to_resource(eiu_node, 0, &res)) { -+ if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) { - /* find out how many external irq sources we have */ - const __be32 *count = of_get_property(node, - "lantiq,count", NULL); --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0006-MIPS-lantiq-adds-support-for-nmi-and-ejtag-bootrom-v.patch b/target/linux/lantiq/patches-3.6/0006-MIPS-lantiq-adds-support-for-nmi-and-ejtag-bootrom-v.patch deleted file mode 100644 index a6631b2f36..0000000000 --- a/target/linux/lantiq/patches-3.6/0006-MIPS-lantiq-adds-support-for-nmi-and-ejtag-bootrom-v.patch +++ /dev/null @@ -1,39 +0,0 @@ -From f8cd170dabeca90c976e6487ba7a8a7752aae571 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 16 Aug 2012 11:39:56 +0000 -Subject: [PATCH 6/9] MIPS: lantiq: adds support for nmi and ejtag bootrom - vectors - -Register nmi and ejtag bootrom vectors for FALC-ON SoC. - -Signed-off-by: Thomas Langer -Signed-off-by: John Crispin -Patchwork: http://patchwork.linux-mips.org/patch/4238/ ---- - arch/mips/lantiq/falcon/prom.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/arch/mips/lantiq/falcon/prom.c b/arch/mips/lantiq/falcon/prom.c -index c1d278f..aa94979 100644 ---- a/arch/mips/lantiq/falcon/prom.c -+++ b/arch/mips/lantiq/falcon/prom.c -@@ -8,6 +8,8 @@ - */ - - #include -+#include -+#include - #include - - #include -@@ -84,4 +86,7 @@ void __init ltq_soc_detect(struct ltq_soc_info *i) - unreachable(); - break; - } -+ -+ board_nmi_handler_setup = ltq_soc_nmi_setup; -+ board_ejtag_handler_setup = ltq_soc_ejtag_setup; - } --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0007-MIPS-lantiq-falcon-clocks-were-not-enabled-properly.patch b/target/linux/lantiq/patches-3.6/0007-MIPS-lantiq-falcon-clocks-were-not-enabled-properly.patch deleted file mode 100644 index 2053753ac3..0000000000 --- a/target/linux/lantiq/patches-3.6/0007-MIPS-lantiq-falcon-clocks-were-not-enabled-properly.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 3a6ac5004c7c8b140319439f8b1f3f6d4cbfe67a Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 16 Aug 2012 08:25:41 +0000 -Subject: [PATCH 7/9] MIPS: lantiq: falcon clocks were not enabled properly - -As a result of a non populated ->bits field inside the clock struct, the clock -domains were never powered on the Falcon. Until now we only used domains that -were also used and powered by the bootloader. - -Signed-off-by: John Crispin -Patchwork: http://patchwork.linux-mips.org/patch/4234/ ---- - arch/mips/lantiq/falcon/sysctrl.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c -index ba0123d..2d4ced3 100644 ---- a/arch/mips/lantiq/falcon/sysctrl.c -+++ b/arch/mips/lantiq/falcon/sysctrl.c -@@ -171,6 +171,7 @@ static inline void clkdev_add_sys(const char *dev, unsigned int module, - clk->cl.con_id = NULL; - clk->cl.clk = clk; - clk->module = module; -+ clk->bits = bits; - clk->activate = sysctl_activate; - clk->deactivate = sysctl_deactivate; - clk->enable = sysctl_clken; --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0008-MIPS-lantiq-enable-pci-clk-conditional-for-xrx200-So.patch b/target/linux/lantiq/patches-3.6/0008-MIPS-lantiq-enable-pci-clk-conditional-for-xrx200-So.patch deleted file mode 100644 index d68515cff0..0000000000 --- a/target/linux/lantiq/patches-3.6/0008-MIPS-lantiq-enable-pci-clk-conditional-for-xrx200-So.patch +++ /dev/null @@ -1,31 +0,0 @@ -From f40e1f9d856ec417468c090c4b56826171daa670 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 16 Aug 2012 08:25:42 +0000 -Subject: [PATCH 8/9] MIPS: lantiq: enable pci clk conditional for xrx200 SoC - -The xrx200 SoC family has the same PCI clock register layout as the AR9. -Enable the same quirk as for AR9 - -Signed-off-by: John Crispin -Patchwork: http://patchwork.linux-mips.org/patch/4235/ ---- - arch/mips/lantiq/xway/sysctrl.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c -index befbb76..67c3a91 100644 ---- a/arch/mips/lantiq/xway/sysctrl.c -+++ b/arch/mips/lantiq/xway/sysctrl.c -@@ -145,7 +145,8 @@ static int pci_enable(struct clk *clk) - { - unsigned int val = ltq_cgu_r32(ifccr); - /* set bus clock speed */ -- if (of_machine_is_compatible("lantiq,ar9")) { -+ if (of_machine_is_compatible("lantiq,ar9") || -+ of_machine_is_compatible("lantiq,vr9")) { - val &= ~0x1f00000; - if (clk->rate == CLOCK_33M) - val |= 0xe00000; --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0009-MIPS-lantiq-adds-support-for-gptu-timers.patch b/target/linux/lantiq/patches-3.6/0009-MIPS-lantiq-adds-support-for-gptu-timers.patch deleted file mode 100644 index 0f8b5f6698..0000000000 --- a/target/linux/lantiq/patches-3.6/0009-MIPS-lantiq-adds-support-for-gptu-timers.patch +++ /dev/null @@ -1,246 +0,0 @@ -From 30404aec4d093942ba67ded8e1926cbf4472d4f7 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 16 Aug 2012 11:31:02 +0000 -Subject: [PATCH 9/9] MIPS: lantiq: adds support for gptu timers - -Lantiq socs have a General Purpose Timer Unit (GPTU). This driver allows us to -initialize the timers. The voice firmware needs these timers as a reference. - -Signed-off-by: John Crispin -Patchwork: http://patchwork.linux-mips.org/patch/4236/ ---- - arch/mips/lantiq/xway/Makefile | 2 +- - arch/mips/lantiq/xway/gptu.c | 214 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 215 insertions(+), 1 deletion(-) - create mode 100644 arch/mips/lantiq/xway/gptu.c - -diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile -index dc3194f..f7053b8 100644 ---- a/arch/mips/lantiq/xway/Makefile -+++ b/arch/mips/lantiq/xway/Makefile -@@ -1 +1 @@ --obj-y := prom.o sysctrl.o clk.o reset.o gpio.o dma.o -+obj-y := prom.o sysctrl.o clk.o reset.o gpio.o dma.o gptu.o -diff --git a/arch/mips/lantiq/xway/gptu.c b/arch/mips/lantiq/xway/gptu.c -new file mode 100644 -index 0000000..cbb56fc ---- /dev/null -+++ b/arch/mips/lantiq/xway/gptu.c -@@ -0,0 +1,214 @@ -+/* -+ * 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. -+ * -+ * Copyright (C) 2012 John Crispin -+ * Copyright (C) 2012 Lantiq GmbH -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include "../clk.h" -+ -+/* the magic ID byte of the core */ -+#define GPTU_MAGIC 0x59 -+/* clock control register */ -+#define GPTU_CLC 0x00 -+/* id register */ -+#define GPTU_ID 0x08 -+/* interrupt node enable */ -+#define GPTU_IRNEN 0xf4 -+/* interrupt control register */ -+#define GPTU_IRCR 0xf8 -+/* interrupt capture register */ -+#define GPTU_IRNCR 0xfc -+/* there are 3 identical blocks of 2 timers. calculate register offsets */ -+#define GPTU_SHIFT(x) (x % 2 ? 4 : 0) -+#define GPTU_BASE(x) (((x >> 1) * 0x20) + 0x10) -+/* timer control register */ -+#define GPTU_CON(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x00) -+/* timer auto reload register */ -+#define GPTU_RUN(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x08) -+/* timer manual reload register */ -+#define GPTU_RLD(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x10) -+/* timer count register */ -+#define GPTU_CNT(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x18) -+ -+/* GPTU_CON(x) */ -+#define CON_CNT BIT(2) -+#define CON_EDGE_ANY (BIT(7) | BIT(6)) -+#define CON_SYNC BIT(8) -+#define CON_CLK_INT BIT(10) -+ -+/* GPTU_RUN(x) */ -+#define RUN_SEN BIT(0) -+#define RUN_RL BIT(2) -+ -+/* set clock to runmode */ -+#define CLC_RMC BIT(8) -+/* bring core out of suspend */ -+#define CLC_SUSPEND BIT(4) -+/* the disable bit */ -+#define CLC_DISABLE BIT(0) -+ -+#define gptu_w32(x, y) ltq_w32((x), gptu_membase + (y)) -+#define gptu_r32(x) ltq_r32(gptu_membase + (x)) -+ -+enum gptu_timer { -+ TIMER1A = 0, -+ TIMER1B, -+ TIMER2A, -+ TIMER2B, -+ TIMER3A, -+ TIMER3B -+}; -+ -+static void __iomem *gptu_membase; -+static struct resource irqres[6]; -+ -+static irqreturn_t timer_irq_handler(int irq, void *priv) -+{ -+ int timer = irq - irqres[0].start; -+ gptu_w32(1 << timer, GPTU_IRNCR); -+ return IRQ_HANDLED; -+} -+ -+static void gptu_hwinit(void) -+{ -+ gptu_w32(0x00, GPTU_IRNEN); -+ gptu_w32(0xff, GPTU_IRNCR); -+ gptu_w32(CLC_RMC | CLC_SUSPEND, GPTU_CLC); -+} -+ -+static void gptu_hwexit(void) -+{ -+ gptu_w32(0x00, GPTU_IRNEN); -+ gptu_w32(0xff, GPTU_IRNCR); -+ gptu_w32(CLC_DISABLE, GPTU_CLC); -+} -+ -+static int gptu_enable(struct clk *clk) -+{ -+ int ret = request_irq(irqres[clk->bits].start, timer_irq_handler, -+ IRQF_TIMER, "gtpu", NULL); -+ if (ret) { -+ pr_err("gptu: failed to request irq\n"); -+ return ret; -+ } -+ -+ gptu_w32(CON_CNT | CON_EDGE_ANY | CON_SYNC | CON_CLK_INT, -+ GPTU_CON(clk->bits)); -+ gptu_w32(1, GPTU_RLD(clk->bits)); -+ gptu_w32(gptu_r32(GPTU_IRNEN) | BIT(clk->bits), GPTU_IRNEN); -+ gptu_w32(RUN_SEN | RUN_RL, GPTU_RUN(clk->bits)); -+ return 0; -+} -+ -+static void gptu_disable(struct clk *clk) -+{ -+ gptu_w32(0, GPTU_RUN(clk->bits)); -+ gptu_w32(0, GPTU_CON(clk->bits)); -+ gptu_w32(0, GPTU_RLD(clk->bits)); -+ gptu_w32(gptu_r32(GPTU_IRNEN) & ~BIT(clk->bits), GPTU_IRNEN); -+ free_irq(irqres[clk->bits].start, NULL); -+} -+ -+static inline void clkdev_add_gptu(struct device *dev, const char *con, -+ unsigned int timer) -+{ -+ struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); -+ -+ clk->cl.dev_id = dev_name(dev); -+ clk->cl.con_id = con; -+ clk->cl.clk = clk; -+ clk->enable = gptu_enable; -+ clk->disable = gptu_disable; -+ clk->bits = timer; -+ clkdev_add(&clk->cl); -+} -+ -+static int __devinit gptu_probe(struct platform_device *pdev) -+{ -+ struct clk *clk; -+ struct resource *res; -+ -+ if (of_irq_to_resource_table(pdev->dev.of_node, irqres, 6) != 6) { -+ dev_err(&pdev->dev, "Failed to get IRQ list\n"); -+ return -EINVAL; -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "Failed to get resource\n"); -+ return -ENOMEM; -+ } -+ -+ /* remap gptu register range */ -+ gptu_membase = devm_request_and_ioremap(&pdev->dev, res); -+ if (!gptu_membase) { -+ dev_err(&pdev->dev, "Failed to remap resource\n"); -+ return -ENOMEM; -+ } -+ -+ /* enable our clock */ -+ clk = clk_get(&pdev->dev, NULL); -+ if (IS_ERR(clk)) { -+ dev_err(&pdev->dev, "Failed to get clock\n"); -+ return -ENOENT; -+ } -+ clk_enable(clk); -+ -+ /* power up the core */ -+ gptu_hwinit(); -+ -+ /* the gptu has a ID register */ -+ if (((gptu_r32(GPTU_ID) >> 8) & 0xff) != GPTU_MAGIC) { -+ dev_err(&pdev->dev, "Failed to find magic\n"); -+ gptu_hwexit(); -+ return -ENAVAIL; -+ } -+ -+ /* register the clocks */ -+ clkdev_add_gptu(&pdev->dev, "timer1a", TIMER1A); -+ clkdev_add_gptu(&pdev->dev, "timer1b", TIMER1B); -+ clkdev_add_gptu(&pdev->dev, "timer2a", TIMER2A); -+ clkdev_add_gptu(&pdev->dev, "timer2b", TIMER2B); -+ clkdev_add_gptu(&pdev->dev, "timer3a", TIMER3A); -+ clkdev_add_gptu(&pdev->dev, "timer3b", TIMER3B); -+ -+ dev_info(&pdev->dev, "gptu: 6 timers loaded\n"); -+ -+ return 0; -+} -+ -+static const struct of_device_id gptu_match[] = { -+ { .compatible = "lantiq,gptu-xway" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, dma_match); -+ -+static struct platform_driver dma_driver = { -+ .probe = gptu_probe, -+ .driver = { -+ .name = "gptu-xway", -+ .owner = THIS_MODULE, -+ .of_match_table = gptu_match, -+ }, -+}; -+ -+int __init gptu_init(void) -+{ -+ int ret = platform_driver_register(&dma_driver); -+ -+ if (ret) -+ pr_info("gptu: Error registering platform driver\n"); -+ return ret; -+} -+ -+arch_initcall(gptu_init); --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0010-OF-pinctrl-MIPS-lantiq-implement-lantiq-xway-pinctrl.patch b/target/linux/lantiq/patches-3.6/0010-OF-pinctrl-MIPS-lantiq-implement-lantiq-xway-pinctrl.patch deleted file mode 100644 index 44822553e5..0000000000 --- a/target/linux/lantiq/patches-3.6/0010-OF-pinctrl-MIPS-lantiq-implement-lantiq-xway-pinctrl.patch +++ /dev/null @@ -1,1632 +0,0 @@ -From 3f8c50c9b110dad4136ea7226cd87b0c4cdb70c8 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Tue, 28 Aug 2012 12:44:59 +0200 -Subject: [PATCH 10/15] OF: pinctrl: MIPS: lantiq: implement lantiq/xway - pinctrl support - -Implement support for pinctrl on lantiq/xway socs. The IO core found on these -socs has the registers for pinctrl, pinconf and gpio mixed up in the same -register range. As the gpio_chip handling is only a few lines, the driver also -implements the gpio functionality. This obseletes the old gpio driver that was -located in the arch/ folder. - -Signed-off-by: John Crispin -Acked-by: Linus Walleij -Cc: devicetree-discuss@lists.ozlabs.org -Cc: linux-kernel@vger.kernel.org ---- - arch/mips/Kconfig | 2 + - arch/mips/lantiq/Kconfig | 1 + - arch/mips/lantiq/xway/Makefile | 2 +- - arch/mips/lantiq/xway/gpio.c | 183 --------- - drivers/pinctrl/Kconfig | 11 + - drivers/pinctrl/Makefile | 2 + - drivers/pinctrl/pinctrl-lantiq.c | 342 +++++++++++++++++ - drivers/pinctrl/pinctrl-lantiq.h | 194 ++++++++++ - drivers/pinctrl/pinctrl-xway.c | 781 ++++++++++++++++++++++++++++++++++++++ - 9 files changed, 1334 insertions(+), 184 deletions(-) - delete mode 100644 arch/mips/lantiq/xway/gpio.c - create mode 100644 drivers/pinctrl/pinctrl-lantiq.c - create mode 100644 drivers/pinctrl/pinctrl-lantiq.h - create mode 100644 drivers/pinctrl/pinctrl-xway.c - -diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig -index 331d574..b0f74b8 100644 ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -241,6 +241,8 @@ config LANTIQ - select HAVE_MACH_CLKDEV - select CLKDEV_LOOKUP - select USE_OF -+ select PINCTRL -+ select PINCTRL_LANTIQ - - config LASAT - bool "LASAT Networks platforms" -diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig -index 20bdf40..080c013 100644 ---- a/arch/mips/lantiq/Kconfig -+++ b/arch/mips/lantiq/Kconfig -@@ -2,6 +2,7 @@ if LANTIQ - - config SOC_TYPE_XWAY - bool -+ select PINCTRL_XWAY - default n - - choice -diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile -index f7053b8..70a58c7 100644 ---- a/arch/mips/lantiq/xway/Makefile -+++ b/arch/mips/lantiq/xway/Makefile -@@ -1 +1 @@ --obj-y := prom.o sysctrl.o clk.o reset.o gpio.o dma.o gptu.o -+obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o -diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c -deleted file mode 100644 -index 2ab39e9..0000000 ---- a/arch/mips/lantiq/xway/gpio.c -+++ /dev/null -@@ -1,183 +0,0 @@ --/* -- * 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. -- * -- * Copyright (C) 2010 John Crispin -- */ -- --#include --#include --#include --#include --#include --#include -- --#include -- --#define LTQ_GPIO_OUT 0x00 --#define LTQ_GPIO_IN 0x04 --#define LTQ_GPIO_DIR 0x08 --#define LTQ_GPIO_ALTSEL0 0x0C --#define LTQ_GPIO_ALTSEL1 0x10 --#define LTQ_GPIO_OD 0x14 -- --#define PINS_PER_PORT 16 --#define MAX_PORTS 3 -- --#define ltq_gpio_getbit(m, r, p) (!!(ltq_r32(m + r) & (1 << p))) --#define ltq_gpio_setbit(m, r, p) ltq_w32_mask(0, (1 << p), m + r) --#define ltq_gpio_clearbit(m, r, p) ltq_w32_mask((1 << p), 0, m + r) -- --struct ltq_gpio { -- void __iomem *membase; -- struct gpio_chip chip; --}; -- --static struct ltq_gpio ltq_gpio_port[MAX_PORTS]; -- --int ltq_gpio_request(unsigned int pin, unsigned int alt0, -- unsigned int alt1, unsigned int dir, const char *name) --{ -- int id = 0; -- -- if (pin >= (MAX_PORTS * PINS_PER_PORT)) -- return -EINVAL; -- if (gpio_request(pin, name)) { -- pr_err("failed to setup lantiq gpio: %s\n", name); -- return -EBUSY; -- } -- if (dir) -- gpio_direction_output(pin, 1); -- else -- gpio_direction_input(pin); -- while (pin >= PINS_PER_PORT) { -- pin -= PINS_PER_PORT; -- id++; -- } -- if (alt0) -- ltq_gpio_setbit(ltq_gpio_port[id].membase, -- LTQ_GPIO_ALTSEL0, pin); -- else -- ltq_gpio_clearbit(ltq_gpio_port[id].membase, -- LTQ_GPIO_ALTSEL0, pin); -- if (alt1) -- ltq_gpio_setbit(ltq_gpio_port[id].membase, -- LTQ_GPIO_ALTSEL1, pin); -- else -- ltq_gpio_clearbit(ltq_gpio_port[id].membase, -- LTQ_GPIO_ALTSEL1, pin); -- return 0; --} --EXPORT_SYMBOL(ltq_gpio_request); -- --static void ltq_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) --{ -- struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); -- -- if (value) -- ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset); -- else -- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset); --} -- --static int ltq_gpio_get(struct gpio_chip *chip, unsigned int offset) --{ -- struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); -- -- return ltq_gpio_getbit(ltq_gpio->membase, LTQ_GPIO_IN, offset); --} -- --static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) --{ -- struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); -- -- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset); -- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset); -- -- return 0; --} -- --static int ltq_gpio_direction_output(struct gpio_chip *chip, -- unsigned int offset, int value) --{ -- struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); -- -- ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset); -- ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset); -- ltq_gpio_set(chip, offset, value); -- -- return 0; --} -- --static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset) --{ -- struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); -- -- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset); -- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset); -- return 0; --} -- --static int ltq_gpio_probe(struct platform_device *pdev) --{ -- struct resource *res; -- -- if (pdev->id >= MAX_PORTS) { -- dev_err(&pdev->dev, "invalid gpio port %d\n", -- pdev->id); -- return -EINVAL; -- } -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (!res) { -- dev_err(&pdev->dev, "failed to get memory for gpio port %d\n", -- pdev->id); -- return -ENOENT; -- } -- res = devm_request_mem_region(&pdev->dev, res->start, -- resource_size(res), dev_name(&pdev->dev)); -- if (!res) { -- dev_err(&pdev->dev, -- "failed to request memory for gpio port %d\n", -- pdev->id); -- return -EBUSY; -- } -- ltq_gpio_port[pdev->id].membase = devm_ioremap_nocache(&pdev->dev, -- res->start, resource_size(res)); -- if (!ltq_gpio_port[pdev->id].membase) { -- dev_err(&pdev->dev, "failed to remap memory for gpio port %d\n", -- pdev->id); -- return -ENOMEM; -- } -- ltq_gpio_port[pdev->id].chip.label = "ltq_gpio"; -- ltq_gpio_port[pdev->id].chip.direction_input = ltq_gpio_direction_input; -- ltq_gpio_port[pdev->id].chip.direction_output = -- ltq_gpio_direction_output; -- ltq_gpio_port[pdev->id].chip.get = ltq_gpio_get; -- ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set; -- ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req; -- ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id; -- ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT; -- platform_set_drvdata(pdev, <q_gpio_port[pdev->id]); -- return gpiochip_add(<q_gpio_port[pdev->id].chip); --} -- --static struct platform_driver --ltq_gpio_driver = { -- .probe = ltq_gpio_probe, -- .driver = { -- .name = "ltq_gpio", -- .owner = THIS_MODULE, -- }, --}; -- --int __init ltq_gpio_init(void) --{ -- int ret = platform_driver_register(<q_gpio_driver); -- -- if (ret) -- pr_info("ltq_gpio : Error registering platform driver!"); -- return ret; --} -- --postcore_initcall(ltq_gpio_init); -diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig -index 54e3588..f77dce0 100644 ---- a/drivers/pinctrl/Kconfig -+++ b/drivers/pinctrl/Kconfig -@@ -55,6 +55,12 @@ config PINCTRL_IMX6Q - help - Say Y here to enable the imx6q pinctrl driver - -+config PINCTRL_LANTIQ -+ bool -+ depends on LANTIQ -+ select PINMUX -+ select PINCONF -+ - config PINCTRL_PXA3xx - bool - select PINMUX -@@ -147,6 +153,11 @@ config PINCTRL_COH901 - - source "drivers/pinctrl/spear/Kconfig" - -+config PINCTRL_XWAY -+ bool -+ depends on SOC_TYPE_XWAY -+ depends on PINCTRL_LANTIQ -+ - endmenu - - endif -diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile -index f40b1f8..e19e207 100644 ---- a/drivers/pinctrl/Makefile -+++ b/drivers/pinctrl/Makefile -@@ -29,5 +29,7 @@ obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o - obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o - obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o - obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o -+obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o -+obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o - - obj-$(CONFIG_PLAT_SPEAR) += spear/ -diff --git a/drivers/pinctrl/pinctrl-lantiq.c b/drivers/pinctrl/pinctrl-lantiq.c -new file mode 100644 -index 0000000..07ba768 ---- /dev/null -+++ b/drivers/pinctrl/pinctrl-lantiq.c -@@ -0,0 +1,342 @@ -+/* -+ * linux/drivers/pinctrl/pinctrl-lantiq.c -+ * based on linux/drivers/pinctrl/pinctrl-pxa3xx.c -+ * -+ * 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 -+ * publishhed by the Free Software Foundation. -+ * -+ * Copyright (C) 2012 John Crispin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "pinctrl-lantiq.h" -+ -+static int ltq_get_group_count(struct pinctrl_dev *pctrldev) -+{ -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); -+ return info->num_grps; -+} -+ -+static const char *ltq_get_group_name(struct pinctrl_dev *pctrldev, -+ unsigned selector) -+{ -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); -+ if (selector >= info->num_grps) -+ return NULL; -+ return info->grps[selector].name; -+} -+ -+static int ltq_get_group_pins(struct pinctrl_dev *pctrldev, -+ unsigned selector, -+ const unsigned **pins, -+ unsigned *num_pins) -+{ -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); -+ if (selector >= info->num_grps) -+ return -EINVAL; -+ *pins = info->grps[selector].pins; -+ *num_pins = info->grps[selector].npins; -+ return 0; -+} -+ -+void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, -+ struct pinctrl_map *map, unsigned num_maps) -+{ -+ int i; -+ -+ for (i = 0; i < num_maps; i++) -+ if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN) -+ kfree(map[i].data.configs.configs); -+ kfree(map); -+} -+ -+static void ltq_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, -+ struct seq_file *s, -+ unsigned offset) -+{ -+ seq_printf(s, " %s", dev_name(pctldev->dev)); -+} -+ -+static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, -+ struct device_node *np, -+ struct pinctrl_map **map) -+{ -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev); -+ unsigned long configs[3]; -+ unsigned num_configs = 0; -+ struct property *prop; -+ const char *group, *pin; -+ const char *function; -+ int ret, i; -+ -+ ret = of_property_read_string(np, "lantiq,function", &function); -+ if (!ret) { -+ of_property_for_each_string(np, "lantiq,groups", prop, group) { -+ (*map)->type = PIN_MAP_TYPE_MUX_GROUP; -+ (*map)->name = function; -+ (*map)->data.mux.group = group; -+ (*map)->data.mux.function = function; -+ (*map)++; -+ } -+ if (of_find_property(np, "lantiq,pins", NULL)) -+ dev_err(pctldev->dev, -+ "%s mixes pins and groups settings\n", -+ np->name); -+ return 0; -+ } -+ -+ for (i = 0; i < info->num_params; i++) { -+ u32 val; -+ int ret = of_property_read_u32(np, -+ info->params[i].property, &val); -+ if (!ret) -+ configs[num_configs++] = -+ LTQ_PINCONF_PACK(info->params[i].param, -+ val); -+ } -+ -+ if (!num_configs) -+ return -EINVAL; -+ -+ of_property_for_each_string(np, "lantiq,pins", prop, pin) { -+ (*map)->data.configs.configs = kmemdup(configs, -+ num_configs * sizeof(unsigned long), -+ GFP_KERNEL); -+ (*map)->type = PIN_MAP_TYPE_CONFIGS_PIN; -+ (*map)->name = pin; -+ (*map)->data.configs.group_or_pin = pin; -+ (*map)->data.configs.num_configs = num_configs; -+ (*map)++; -+ } -+ return 0; -+} -+ -+static int ltq_pinctrl_dt_subnode_size(struct device_node *np) -+{ -+ int ret; -+ -+ ret = of_property_count_strings(np, "lantiq,groups"); -+ if (ret < 0) -+ ret = of_property_count_strings(np, "lantiq,pins"); -+ return ret; -+} -+ -+int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, -+ struct device_node *np_config, -+ struct pinctrl_map **map, -+ unsigned *num_maps) -+{ -+ struct pinctrl_map *tmp; -+ struct device_node *np; -+ int ret; -+ -+ *num_maps = 0; -+ for_each_child_of_node(np_config, np) -+ *num_maps += ltq_pinctrl_dt_subnode_size(np); -+ *map = kzalloc(*num_maps * sizeof(struct pinctrl_map), GFP_KERNEL); -+ if (!*map) -+ return -ENOMEM; -+ tmp = *map; -+ -+ for_each_child_of_node(np_config, np) { -+ ret = ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp); -+ if (ret < 0) { -+ ltq_pinctrl_dt_free_map(pctldev, *map, *num_maps); -+ return ret; -+ } -+ } -+ return 0; -+} -+ -+static struct pinctrl_ops ltq_pctrl_ops = { -+ .get_groups_count = ltq_get_group_count, -+ .get_group_name = ltq_get_group_name, -+ .get_group_pins = ltq_get_group_pins, -+ .pin_dbg_show = ltq_pinctrl_pin_dbg_show, -+ .dt_node_to_map = ltq_pinctrl_dt_node_to_map, -+ .dt_free_map = ltq_pinctrl_dt_free_map, -+}; -+ -+static int ltq_pmx_func_count(struct pinctrl_dev *pctrldev) -+{ -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); -+ -+ return info->num_funcs; -+} -+ -+static const char *ltq_pmx_func_name(struct pinctrl_dev *pctrldev, -+ unsigned selector) -+{ -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); -+ -+ if (selector >= info->num_funcs) -+ return NULL; -+ -+ return info->funcs[selector].name; -+} -+ -+static int ltq_pmx_get_groups(struct pinctrl_dev *pctrldev, -+ unsigned func, -+ const char * const **groups, -+ unsigned * const num_groups) -+{ -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); -+ -+ *groups = info->funcs[func].groups; -+ *num_groups = info->funcs[func].num_groups; -+ -+ return 0; -+} -+ -+/* Return function number. If failure, return negative value. */ -+static int match_mux(const struct ltq_mfp_pin *mfp, unsigned mux) -+{ -+ int i; -+ for (i = 0; i < LTQ_MAX_MUX; i++) { -+ if (mfp->func[i] == mux) -+ break; -+ } -+ if (i >= LTQ_MAX_MUX) -+ return -EINVAL; -+ return i; -+} -+ -+/* dont assume .mfp is linearly mapped. find the mfp with the correct .pin */ -+static int match_mfp(const struct ltq_pinmux_info *info, int pin) -+{ -+ int i; -+ for (i = 0; i < info->num_mfp; i++) { -+ if (info->mfp[i].pin == pin) -+ return i; -+ } -+ return -1; -+} -+ -+/* check whether current pin configuration is valid. Negative for failure */ -+static int match_group_mux(const struct ltq_pin_group *grp, -+ const struct ltq_pinmux_info *info, -+ unsigned mux) -+{ -+ int i, pin, ret = 0; -+ for (i = 0; i < grp->npins; i++) { -+ pin = match_mfp(info, grp->pins[i]); -+ if (pin < 0) { -+ dev_err(info->dev, "could not find mfp for pin %d\n", -+ grp->pins[i]); -+ return -EINVAL; -+ } -+ ret = match_mux(&info->mfp[pin], mux); -+ if (ret < 0) { -+ dev_err(info->dev, "Can't find mux %d on pin%d\n", -+ mux, pin); -+ break; -+ } -+ } -+ return ret; -+} -+ -+static int ltq_pmx_enable(struct pinctrl_dev *pctrldev, -+ unsigned func, -+ unsigned group) -+{ -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); -+ const struct ltq_pin_group *pin_grp = &info->grps[group]; -+ int i, pin, pin_func, ret; -+ -+ if (!pin_grp->npins || -+ (match_group_mux(pin_grp, info, pin_grp->mux) < 0)) { -+ dev_err(info->dev, "Failed to set the pin group: %s\n", -+ info->grps[group].name); -+ return -EINVAL; -+ } -+ for (i = 0; i < pin_grp->npins; i++) { -+ pin = match_mfp(info, pin_grp->pins[i]); -+ if (pin < 0) { -+ dev_err(info->dev, "could not find mfp for pin %d\n", -+ pin_grp->pins[i]); -+ return -EINVAL; -+ } -+ pin_func = match_mux(&info->mfp[pin], pin_grp->mux); -+ ret = info->apply_mux(pctrldev, pin, pin_func); -+ if (ret) { -+ dev_err(info->dev, -+ "failed to apply mux %d for pin %d\n", -+ pin_func, pin); -+ return ret; -+ } -+ } -+ return 0; -+} -+ -+static void ltq_pmx_disable(struct pinctrl_dev *pctrldev, -+ unsigned func, -+ unsigned group) -+{ -+ /* -+ * Nothing to do here. However, pinconf_check_ops() requires this -+ * callback to be defined. -+ */ -+} -+ -+static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev, -+ struct pinctrl_gpio_range *range, -+ unsigned pin) -+{ -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); -+ int mfp = match_mfp(info, pin + (range->id * 32)); -+ int pin_func; -+ -+ if (mfp < 0) { -+ dev_err(info->dev, "could not find mfp for pin %d\n", pin); -+ return -EINVAL; -+ } -+ -+ pin_func = match_mux(&info->mfp[mfp], 0); -+ if (pin_func < 0) { -+ dev_err(info->dev, "No GPIO function on pin%d\n", mfp); -+ return -EINVAL; -+ } -+ -+ return info->apply_mux(pctrldev, mfp, pin_func); -+} -+ -+static struct pinmux_ops ltq_pmx_ops = { -+ .get_functions_count = ltq_pmx_func_count, -+ .get_function_name = ltq_pmx_func_name, -+ .get_function_groups = ltq_pmx_get_groups, -+ .enable = ltq_pmx_enable, -+ .disable = ltq_pmx_disable, -+ .gpio_request_enable = ltq_pmx_gpio_request_enable, -+}; -+ -+/* -+ * allow different socs to register with the generic part of the lanti -+ * pinctrl code -+ */ -+int ltq_pinctrl_register(struct platform_device *pdev, -+ struct ltq_pinmux_info *info) -+{ -+ struct pinctrl_desc *desc; -+ -+ if (!info) -+ return -EINVAL; -+ desc = info->desc; -+ desc->pctlops = <q_pctrl_ops; -+ desc->pmxops = <q_pmx_ops; -+ info->dev = &pdev->dev; -+ -+ info->pctrl = pinctrl_register(desc, &pdev->dev, info); -+ if (!info->pctrl) { -+ dev_err(&pdev->dev, "failed to register LTQ pinmux driver\n"); -+ return -EINVAL; -+ } -+ platform_set_drvdata(pdev, info); -+ return 0; -+} -diff --git a/drivers/pinctrl/pinctrl-lantiq.h b/drivers/pinctrl/pinctrl-lantiq.h -new file mode 100644 -index 0000000..4419d32 ---- /dev/null -+++ b/drivers/pinctrl/pinctrl-lantiq.h -@@ -0,0 +1,194 @@ -+/* -+ * linux/drivers/pinctrl/pinctrl-lantiq.h -+ * based on linux/drivers/pinctrl/pinctrl-pxa3xx.h -+ * -+ * 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 -+ * publishhed by the Free Software Foundation. -+ * -+ * Copyright (C) 2012 John Crispin -+ */ -+ -+#ifndef __PINCTRL_LANTIQ_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "core.h" -+ -+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) -+ -+#define LTQ_MAX_MUX 4 -+#define MFPR_FUNC_MASK 0x3 -+ -+#define LTQ_PINCONF_PACK(param, arg) ((param) << 16 | (arg)) -+#define LTQ_PINCONF_UNPACK_PARAM(conf) ((conf) >> 16) -+#define LTQ_PINCONF_UNPACK_ARG(conf) ((conf) & 0xffff) -+ -+enum ltq_pinconf_param { -+ LTQ_PINCONF_PARAM_PULL, -+ LTQ_PINCONF_PARAM_OPEN_DRAIN, -+ LTQ_PINCONF_PARAM_DRIVE_CURRENT, -+ LTQ_PINCONF_PARAM_SLEW_RATE, -+}; -+ -+struct ltq_cfg_param { -+ const char *property; -+ enum ltq_pinconf_param param; -+}; -+ -+struct ltq_mfp_pin { -+ const char *name; -+ const unsigned int pin; -+ const unsigned short func[LTQ_MAX_MUX]; -+}; -+ -+struct ltq_pin_group { -+ const char *name; -+ const unsigned mux; -+ const unsigned *pins; -+ const unsigned npins; -+}; -+ -+struct ltq_pmx_func { -+ const char *name; -+ const char * const *groups; -+ const unsigned num_groups; -+}; -+ -+struct ltq_pinmux_info { -+ struct device *dev; -+ struct pinctrl_dev *pctrl; -+ -+ /* we need to manage up to 5 pad controllers */ -+ void __iomem *membase[5]; -+ -+ /* the descriptor for the subsystem */ -+ struct pinctrl_desc *desc; -+ -+ /* we expose our pads to the subsystem */ -+ struct pinctrl_pin_desc *pads; -+ -+ /* the number of pads. this varies between socs */ -+ unsigned int num_pads; -+ -+ /* these are our multifunction pins */ -+ const struct ltq_mfp_pin *mfp; -+ unsigned int num_mfp; -+ -+ /* a number of multifunction pins can be grouped together */ -+ const struct ltq_pin_group *grps; -+ unsigned int num_grps; -+ -+ /* a mapping between function string and id */ -+ const struct ltq_pmx_func *funcs; -+ unsigned int num_funcs; -+ -+ /* the pinconf options that we are able to read from the DT */ -+ const struct ltq_cfg_param *params; -+ unsigned int num_params; -+ -+ /* the pad controller can have a irq mapping */ -+ const unsigned *exin; -+ unsigned int num_exin; -+ -+ /* we need 5 clocks max */ -+ struct clk *clk[5]; -+ -+ /* soc specific callback used to apply muxing */ -+ int (*apply_mux)(struct pinctrl_dev *pctrldev, int pin, int mux); -+}; -+ -+enum ltq_pin { -+ GPIO0 = 0, -+ GPIO1, -+ GPIO2, -+ GPIO3, -+ GPIO4, -+ GPIO5, -+ GPIO6, -+ GPIO7, -+ GPIO8, -+ GPIO9, -+ GPIO10, /* 10 */ -+ GPIO11, -+ GPIO12, -+ GPIO13, -+ GPIO14, -+ GPIO15, -+ GPIO16, -+ GPIO17, -+ GPIO18, -+ GPIO19, -+ GPIO20, /* 20 */ -+ GPIO21, -+ GPIO22, -+ GPIO23, -+ GPIO24, -+ GPIO25, -+ GPIO26, -+ GPIO27, -+ GPIO28, -+ GPIO29, -+ GPIO30, /* 30 */ -+ GPIO31, -+ GPIO32, -+ GPIO33, -+ GPIO34, -+ GPIO35, -+ GPIO36, -+ GPIO37, -+ GPIO38, -+ GPIO39, -+ GPIO40, /* 40 */ -+ GPIO41, -+ GPIO42, -+ GPIO43, -+ GPIO44, -+ GPIO45, -+ GPIO46, -+ GPIO47, -+ GPIO48, -+ GPIO49, -+ GPIO50, /* 50 */ -+ GPIO51, -+ GPIO52, -+ GPIO53, -+ GPIO54, -+ GPIO55, -+ -+ GPIO64, -+ GPIO65, -+ GPIO66, -+ GPIO67, -+ GPIO68, -+ GPIO69, -+ GPIO70, -+ GPIO71, -+ GPIO72, -+ GPIO73, -+ GPIO74, -+ GPIO75, -+ GPIO76, -+ GPIO77, -+ GPIO78, -+ GPIO79, -+ GPIO80, -+ GPIO81, -+ GPIO82, -+ GPIO83, -+ GPIO84, -+ GPIO85, -+ GPIO86, -+ GPIO87, -+ GPIO88, -+}; -+ -+extern int ltq_pinctrl_register(struct platform_device *pdev, -+ struct ltq_pinmux_info *info); -+extern int ltq_pinctrl_unregister(struct platform_device *pdev); -+#endif /* __PINCTRL_PXA3XX_H */ -diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c -new file mode 100644 -index 0000000..f8d917d ---- /dev/null -+++ b/drivers/pinctrl/pinctrl-xway.c -@@ -0,0 +1,781 @@ -+/* -+ * linux/drivers/pinctrl/pinmux-xway.c -+ * based on linux/drivers/pinctrl/pinmux-pxa910.c -+ * -+ * 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 -+ * publishhed by the Free Software Foundation. -+ * -+ * Copyright (C) 2012 John Crispin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "pinctrl-lantiq.h" -+ -+#include -+ -+/* we have 3 1/2 banks of 16 bit each */ -+#define PINS 16 -+#define PORT3 3 -+#define PORT(x) (x / PINS) -+#define PORT_PIN(x) (x % PINS) -+ -+/* we have 2 mux bits that can be set for each pin */ -+#define MUX_ALT0 0x1 -+#define MUX_ALT1 0x2 -+ -+/* -+ * each bank has this offset apart from the 1/2 bank that is mixed into the -+ * other 3 ranges -+ */ -+#define REG_OFF 0x30 -+ -+/* these are the offsets to our registers */ -+#define GPIO_BASE(p) (REG_OFF * PORT(p)) -+#define GPIO_OUT(p) GPIO_BASE(p) -+#define GPIO_IN(p) (GPIO_BASE(p) + 0x04) -+#define GPIO_DIR(p) (GPIO_BASE(p) + 0x08) -+#define GPIO_ALT0(p) (GPIO_BASE(p) + 0x0C) -+#define GPIO_ALT1(p) (GPIO_BASE(p) + 0x10) -+#define GPIO_OD(p) (GPIO_BASE(p) + 0x14) -+#define GPIO_PUDSEL(p) (GPIO_BASE(p) + 0x1c) -+#define GPIO_PUDEN(p) (GPIO_BASE(p) + 0x20) -+ -+/* the 1/2 port needs special offsets for some registers */ -+#define GPIO3_OD (GPIO_BASE(0) + 0x24) -+#define GPIO3_PUDSEL (GPIO_BASE(0) + 0x28) -+#define GPIO3_PUDEN (GPIO_BASE(0) + 0x2C) -+#define GPIO3_ALT1 (GPIO_BASE(PINS) + 0x24) -+ -+/* macros to help us access the registers */ -+#define gpio_getbit(m, r, p) (!!(ltq_r32(m + r) & BIT(p))) -+#define gpio_setbit(m, r, p) ltq_w32_mask(0, BIT(p), m + r) -+#define gpio_clearbit(m, r, p) ltq_w32_mask(BIT(p), 0, m + r) -+ -+#define MFP_XWAY(a, f0, f1, f2, f3) \ -+ { \ -+ .name = #a, \ -+ .pin = a, \ -+ .func = { \ -+ XWAY_MUX_##f0, \ -+ XWAY_MUX_##f1, \ -+ XWAY_MUX_##f2, \ -+ XWAY_MUX_##f3, \ -+ }, \ -+ } -+ -+#define GRP_MUX(a, m, p) \ -+ { .name = a, .mux = XWAY_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), } -+ -+#define FUNC_MUX(f, m) \ -+ { .func = f, .mux = XWAY_MUX_##m, } -+ -+#define XWAY_MAX_PIN 32 -+#define XR9_MAX_PIN 56 -+ -+enum xway_mux { -+ XWAY_MUX_GPIO = 0, -+ XWAY_MUX_SPI, -+ XWAY_MUX_ASC, -+ XWAY_MUX_PCI, -+ XWAY_MUX_CGU, -+ XWAY_MUX_EBU, -+ XWAY_MUX_JTAG, -+ XWAY_MUX_EXIN, -+ XWAY_MUX_TDM, -+ XWAY_MUX_STP, -+ XWAY_MUX_SIN, -+ XWAY_MUX_GPT, -+ XWAY_MUX_NMI, -+ XWAY_MUX_MDIO, -+ XWAY_MUX_MII, -+ XWAY_MUX_EPHY, -+ XWAY_MUX_DFE, -+ XWAY_MUX_SDIO, -+ XWAY_MUX_NONE = 0xffff, -+}; -+ -+static const struct ltq_mfp_pin xway_mfp[] = { -+ /* pin f0 f1 f2 f3 */ -+ MFP_XWAY(GPIO0, GPIO, EXIN, NONE, TDM), -+ MFP_XWAY(GPIO1, GPIO, EXIN, NONE, NONE), -+ MFP_XWAY(GPIO2, GPIO, CGU, EXIN, NONE), -+ MFP_XWAY(GPIO3, GPIO, CGU, NONE, PCI), -+ MFP_XWAY(GPIO4, GPIO, STP, NONE, ASC), -+ MFP_XWAY(GPIO5, GPIO, STP, NONE, NONE), -+ MFP_XWAY(GPIO6, GPIO, STP, GPT, ASC), -+ MFP_XWAY(GPIO7, GPIO, CGU, PCI, NONE), -+ MFP_XWAY(GPIO8, GPIO, CGU, NMI, NONE), -+ MFP_XWAY(GPIO9, GPIO, ASC, SPI, EXIN), -+ MFP_XWAY(GPIO10, GPIO, ASC, SPI, NONE), -+ MFP_XWAY(GPIO11, GPIO, ASC, PCI, SPI), -+ MFP_XWAY(GPIO12, GPIO, ASC, NONE, NONE), -+ MFP_XWAY(GPIO13, GPIO, EBU, SPI, NONE), -+ MFP_XWAY(GPIO14, GPIO, CGU, PCI, NONE), -+ MFP_XWAY(GPIO15, GPIO, SPI, JTAG, NONE), -+ MFP_XWAY(GPIO16, GPIO, SPI, NONE, JTAG), -+ MFP_XWAY(GPIO17, GPIO, SPI, NONE, JTAG), -+ MFP_XWAY(GPIO18, GPIO, SPI, NONE, JTAG), -+ MFP_XWAY(GPIO19, GPIO, PCI, NONE, NONE), -+ MFP_XWAY(GPIO20, GPIO, JTAG, NONE, NONE), -+ MFP_XWAY(GPIO21, GPIO, PCI, EBU, GPT), -+ MFP_XWAY(GPIO22, GPIO, SPI, NONE, NONE), -+ MFP_XWAY(GPIO23, GPIO, EBU, PCI, STP), -+ MFP_XWAY(GPIO24, GPIO, EBU, TDM, PCI), -+ MFP_XWAY(GPIO25, GPIO, TDM, NONE, ASC), -+ MFP_XWAY(GPIO26, GPIO, EBU, NONE, TDM), -+ MFP_XWAY(GPIO27, GPIO, TDM, NONE, ASC), -+ MFP_XWAY(GPIO28, GPIO, GPT, NONE, NONE), -+ MFP_XWAY(GPIO29, GPIO, PCI, NONE, NONE), -+ MFP_XWAY(GPIO30, GPIO, PCI, NONE, NONE), -+ MFP_XWAY(GPIO31, GPIO, EBU, PCI, NONE), -+ MFP_XWAY(GPIO32, GPIO, NONE, NONE, EBU), -+ MFP_XWAY(GPIO33, GPIO, NONE, NONE, EBU), -+ MFP_XWAY(GPIO34, GPIO, NONE, NONE, EBU), -+ MFP_XWAY(GPIO35, GPIO, NONE, NONE, EBU), -+ MFP_XWAY(GPIO36, GPIO, SIN, NONE, EBU), -+ MFP_XWAY(GPIO37, GPIO, PCI, NONE, NONE), -+ MFP_XWAY(GPIO38, GPIO, PCI, NONE, NONE), -+ MFP_XWAY(GPIO39, GPIO, EXIN, NONE, NONE), -+ MFP_XWAY(GPIO40, GPIO, NONE, NONE, NONE), -+ MFP_XWAY(GPIO41, GPIO, NONE, NONE, NONE), -+ MFP_XWAY(GPIO42, GPIO, MDIO, NONE, NONE), -+ MFP_XWAY(GPIO43, GPIO, MDIO, NONE, NONE), -+ MFP_XWAY(GPIO44, GPIO, NONE, NONE, SIN), -+ MFP_XWAY(GPIO45, GPIO, NONE, NONE, SIN), -+ MFP_XWAY(GPIO46, GPIO, NONE, NONE, EXIN), -+ MFP_XWAY(GPIO47, GPIO, NONE, NONE, SIN), -+ MFP_XWAY(GPIO48, GPIO, EBU, NONE, NONE), -+ MFP_XWAY(GPIO49, GPIO, EBU, NONE, NONE), -+ MFP_XWAY(GPIO50, GPIO, NONE, NONE, NONE), -+ MFP_XWAY(GPIO51, GPIO, NONE, NONE, NONE), -+ MFP_XWAY(GPIO52, GPIO, NONE, NONE, NONE), -+ MFP_XWAY(GPIO53, GPIO, NONE, NONE, NONE), -+ MFP_XWAY(GPIO54, GPIO, NONE, NONE, NONE), -+ MFP_XWAY(GPIO55, GPIO, NONE, NONE, NONE), -+}; -+ -+static const struct ltq_mfp_pin ase_mfp[] = { -+ /* pin f0 f1 f2 f3 */ -+ MFP_XWAY(GPIO0, GPIO, EXIN, MII, TDM), -+ MFP_XWAY(GPIO1, GPIO, STP, DFE, EBU), -+ MFP_XWAY(GPIO2, GPIO, STP, DFE, EPHY), -+ MFP_XWAY(GPIO3, GPIO, STP, EPHY, EBU), -+ MFP_XWAY(GPIO4, GPIO, GPT, EPHY, MII), -+ MFP_XWAY(GPIO5, GPIO, MII, ASC, GPT), -+ MFP_XWAY(GPIO6, GPIO, MII, ASC, EXIN), -+ MFP_XWAY(GPIO7, GPIO, SPI, MII, JTAG), -+ MFP_XWAY(GPIO8, GPIO, SPI, MII, JTAG), -+ MFP_XWAY(GPIO9, GPIO, SPI, MII, JTAG), -+ MFP_XWAY(GPIO10, GPIO, SPI, MII, JTAG), -+ MFP_XWAY(GPIO11, GPIO, EBU, CGU, JTAG), -+ MFP_XWAY(GPIO12, GPIO, EBU, MII, SDIO), -+ MFP_XWAY(GPIO13, GPIO, EBU, MII, CGU), -+ MFP_XWAY(GPIO14, GPIO, EBU, SPI, CGU), -+ MFP_XWAY(GPIO15, GPIO, EBU, SPI, SDIO), -+ MFP_XWAY(GPIO16, GPIO, NONE, NONE, NONE), -+ MFP_XWAY(GPIO17, GPIO, NONE, NONE, NONE), -+ MFP_XWAY(GPIO18, GPIO, NONE, NONE, NONE), -+ MFP_XWAY(GPIO19, GPIO, EBU, MII, SDIO), -+ MFP_XWAY(GPIO20, GPIO, EBU, MII, SDIO), -+ MFP_XWAY(GPIO21, GPIO, EBU, MII, SDIO), -+ MFP_XWAY(GPIO22, GPIO, EBU, MII, CGU), -+ MFP_XWAY(GPIO23, GPIO, EBU, MII, CGU), -+ MFP_XWAY(GPIO24, GPIO, EBU, NONE, MII), -+ MFP_XWAY(GPIO25, GPIO, EBU, MII, GPT), -+ MFP_XWAY(GPIO26, GPIO, EBU, MII, SDIO), -+ MFP_XWAY(GPIO27, GPIO, EBU, NONE, MII), -+ MFP_XWAY(GPIO28, GPIO, MII, EBU, SDIO), -+ MFP_XWAY(GPIO29, GPIO, EBU, MII, EXIN), -+ MFP_XWAY(GPIO30, GPIO, NONE, NONE, NONE), -+ MFP_XWAY(GPIO31, GPIO, NONE, NONE, NONE), -+}; -+ -+static const unsigned pins_jtag[] = {GPIO15, GPIO16, GPIO17, GPIO19, GPIO35}; -+static const unsigned pins_asc0[] = {GPIO11, GPIO12}; -+static const unsigned pins_asc0_cts_rts[] = {GPIO9, GPIO10}; -+static const unsigned pins_stp[] = {GPIO4, GPIO5, GPIO6}; -+static const unsigned pins_nmi[] = {GPIO8}; -+static const unsigned pins_mdio[] = {GPIO42, GPIO43}; -+ -+static const unsigned pins_ebu_a24[] = {GPIO13}; -+static const unsigned pins_ebu_clk[] = {GPIO21}; -+static const unsigned pins_ebu_cs1[] = {GPIO23}; -+static const unsigned pins_ebu_a23[] = {GPIO24}; -+static const unsigned pins_ebu_wait[] = {GPIO26}; -+static const unsigned pins_ebu_a25[] = {GPIO31}; -+static const unsigned pins_ebu_rdy[] = {GPIO48}; -+static const unsigned pins_ebu_rd[] = {GPIO49}; -+ -+static const unsigned pins_nand_ale[] = {GPIO13}; -+static const unsigned pins_nand_cs1[] = {GPIO23}; -+static const unsigned pins_nand_cle[] = {GPIO24}; -+static const unsigned pins_nand_rdy[] = {GPIO48}; -+static const unsigned pins_nand_rd[] = {GPIO49}; -+ -+static const unsigned pins_exin0[] = {GPIO0}; -+static const unsigned pins_exin1[] = {GPIO1}; -+static const unsigned pins_exin2[] = {GPIO2}; -+static const unsigned pins_exin3[] = {GPIO39}; -+static const unsigned pins_exin4[] = {GPIO46}; -+static const unsigned pins_exin5[] = {GPIO9}; -+ -+static const unsigned pins_spi[] = {GPIO16, GPIO17, GPIO18}; -+static const unsigned pins_spi_cs1[] = {GPIO15}; -+static const unsigned pins_spi_cs2[] = {GPIO21}; -+static const unsigned pins_spi_cs3[] = {GPIO13}; -+static const unsigned pins_spi_cs4[] = {GPIO10}; -+static const unsigned pins_spi_cs5[] = {GPIO9}; -+static const unsigned pins_spi_cs6[] = {GPIO11}; -+ -+static const unsigned pins_gpt1[] = {GPIO28}; -+static const unsigned pins_gpt2[] = {GPIO21}; -+static const unsigned pins_gpt3[] = {GPIO6}; -+ -+static const unsigned pins_clkout0[] = {GPIO8}; -+static const unsigned pins_clkout1[] = {GPIO7}; -+static const unsigned pins_clkout2[] = {GPIO3}; -+static const unsigned pins_clkout3[] = {GPIO2}; -+ -+static const unsigned pins_pci_gnt1[] = {GPIO30}; -+static const unsigned pins_pci_gnt2[] = {GPIO23}; -+static const unsigned pins_pci_gnt3[] = {GPIO19}; -+static const unsigned pins_pci_gnt4[] = {GPIO38}; -+static const unsigned pins_pci_req1[] = {GPIO29}; -+static const unsigned pins_pci_req2[] = {GPIO31}; -+static const unsigned pins_pci_req3[] = {GPIO3}; -+static const unsigned pins_pci_req4[] = {GPIO37}; -+ -+static const unsigned ase_pins_jtag[] = {GPIO7, GPIO8, GPIO9, GPIO10, GPIO11}; -+static const unsigned ase_pins_asc[] = {GPIO5, GPIO6}; -+static const unsigned ase_pins_stp[] = {GPIO1, GPIO2, GPIO3}; -+static const unsigned ase_pins_ephy[] = {GPIO2, GPIO3, GPIO4}; -+static const unsigned ase_pins_dfe[] = {GPIO1, GPIO2}; -+ -+static const unsigned ase_pins_spi[] = {GPIO8, GPIO9, GPIO10}; -+static const unsigned ase_pins_spi_cs1[] = {GPIO7}; -+static const unsigned ase_pins_spi_cs2[] = {GPIO15}; -+static const unsigned ase_pins_spi_cs3[] = {GPIO14}; -+ -+static const unsigned ase_pins_exin0[] = {GPIO6}; -+static const unsigned ase_pins_exin1[] = {GPIO29}; -+static const unsigned ase_pins_exin2[] = {GPIO0}; -+ -+static const unsigned ase_pins_gpt1[] = {GPIO5}; -+static const unsigned ase_pins_gpt2[] = {GPIO4}; -+static const unsigned ase_pins_gpt3[] = {GPIO25}; -+ -+static const struct ltq_pin_group xway_grps[] = { -+ GRP_MUX("exin0", EXIN, pins_exin0), -+ GRP_MUX("exin1", EXIN, pins_exin1), -+ GRP_MUX("exin2", EXIN, pins_exin2), -+ GRP_MUX("jtag", JTAG, pins_jtag), -+ GRP_MUX("ebu a23", EBU, pins_ebu_a23), -+ GRP_MUX("ebu a24", EBU, pins_ebu_a24), -+ GRP_MUX("ebu a25", EBU, pins_ebu_a25), -+ GRP_MUX("ebu clk", EBU, pins_ebu_clk), -+ GRP_MUX("ebu cs1", EBU, pins_ebu_cs1), -+ GRP_MUX("ebu wait", EBU, pins_ebu_wait), -+ GRP_MUX("nand ale", EBU, pins_nand_ale), -+ GRP_MUX("nand cs1", EBU, pins_nand_cs1), -+ GRP_MUX("nand cle", EBU, pins_nand_cle), -+ GRP_MUX("spi", SPI, pins_spi), -+ GRP_MUX("spi_cs1", SPI, pins_spi_cs1), -+ GRP_MUX("spi_cs2", SPI, pins_spi_cs2), -+ GRP_MUX("spi_cs3", SPI, pins_spi_cs3), -+ GRP_MUX("spi_cs4", SPI, pins_spi_cs4), -+ GRP_MUX("spi_cs5", SPI, pins_spi_cs5), -+ GRP_MUX("spi_cs6", SPI, pins_spi_cs6), -+ GRP_MUX("asc0", ASC, pins_asc0), -+ GRP_MUX("asc0 cts rts", ASC, pins_asc0_cts_rts), -+ GRP_MUX("stp", STP, pins_stp), -+ GRP_MUX("nmi", NMI, pins_nmi), -+ GRP_MUX("gpt1", GPT, pins_gpt1), -+ GRP_MUX("gpt2", GPT, pins_gpt2), -+ GRP_MUX("gpt3", GPT, pins_gpt3), -+ GRP_MUX("clkout0", CGU, pins_clkout0), -+ GRP_MUX("clkout1", CGU, pins_clkout1), -+ GRP_MUX("clkout2", CGU, pins_clkout2), -+ GRP_MUX("clkout3", CGU, pins_clkout3), -+ GRP_MUX("gnt1", PCI, pins_pci_gnt1), -+ GRP_MUX("gnt2", PCI, pins_pci_gnt2), -+ GRP_MUX("gnt3", PCI, pins_pci_gnt3), -+ GRP_MUX("req1", PCI, pins_pci_req1), -+ GRP_MUX("req2", PCI, pins_pci_req2), -+ GRP_MUX("req3", PCI, pins_pci_req3), -+/* xrx only */ -+ GRP_MUX("nand rdy", EBU, pins_nand_rdy), -+ GRP_MUX("nand rd", EBU, pins_nand_rd), -+ GRP_MUX("exin3", EXIN, pins_exin3), -+ GRP_MUX("exin4", EXIN, pins_exin4), -+ GRP_MUX("exin5", EXIN, pins_exin5), -+ GRP_MUX("gnt4", PCI, pins_pci_gnt4), -+ GRP_MUX("req4", PCI, pins_pci_gnt4), -+ GRP_MUX("mdio", MDIO, pins_mdio), -+}; -+ -+static const struct ltq_pin_group ase_grps[] = { -+ GRP_MUX("exin0", EXIN, ase_pins_exin0), -+ GRP_MUX("exin1", EXIN, ase_pins_exin1), -+ GRP_MUX("exin2", EXIN, ase_pins_exin2), -+ GRP_MUX("jtag", JTAG, ase_pins_jtag), -+ GRP_MUX("stp", STP, ase_pins_stp), -+ GRP_MUX("asc", ASC, ase_pins_asc), -+ GRP_MUX("gpt1", GPT, ase_pins_gpt1), -+ GRP_MUX("gpt2", GPT, ase_pins_gpt2), -+ GRP_MUX("gpt3", GPT, ase_pins_gpt3), -+ GRP_MUX("ephy", EPHY, ase_pins_ephy), -+ GRP_MUX("dfe", DFE, ase_pins_dfe), -+ GRP_MUX("spi", SPI, ase_pins_spi), -+ GRP_MUX("spi_cs1", SPI, ase_pins_spi_cs1), -+ GRP_MUX("spi_cs2", SPI, ase_pins_spi_cs2), -+ GRP_MUX("spi_cs3", SPI, ase_pins_spi_cs3), -+}; -+ -+static const char * const xway_pci_grps[] = {"gnt1", "gnt2", -+ "gnt3", "req1", -+ "req2", "req3"}; -+static const char * const xway_spi_grps[] = {"spi", "spi_cs1", -+ "spi_cs2", "spi_cs3", -+ "spi_cs4", "spi_cs5", -+ "spi_cs6"}; -+static const char * const xway_cgu_grps[] = {"clkout0", "clkout1", -+ "clkout2", "clkout3"}; -+static const char * const xway_ebu_grps[] = {"ebu a23", "ebu a24", -+ "ebu a25", "ebu cs1", -+ "ebu wait", "ebu clk", -+ "nand ale", "nand cs1", -+ "nand cle"}; -+static const char * const xway_exin_grps[] = {"exin0", "exin1", "exin2"}; -+static const char * const xway_gpt_grps[] = {"gpt1", "gpt2", "gpt3"}; -+static const char * const xway_asc_grps[] = {"asc0", "asc0 cts rts"}; -+static const char * const xway_jtag_grps[] = {"jtag"}; -+static const char * const xway_stp_grps[] = {"stp"}; -+static const char * const xway_nmi_grps[] = {"nmi"}; -+ -+/* ar9/vr9/gr9 */ -+static const char * const xrx_mdio_grps[] = {"mdio"}; -+static const char * const xrx_ebu_grps[] = {"ebu a23", "ebu a24", -+ "ebu a25", "ebu cs1", -+ "ebu wait", "ebu clk", -+ "nand ale", "nand cs1", -+ "nand cle", "nand rdy", -+ "nand rd"}; -+static const char * const xrx_exin_grps[] = {"exin0", "exin1", "exin2", -+ "exin3", "exin4", "exin5"}; -+static const char * const xrx_pci_grps[] = {"gnt1", "gnt2", -+ "gnt3", "gnt4", -+ "req1", "req2", -+ "req3", "req4"}; -+ -+/* ase */ -+static const char * const ase_exin_grps[] = {"exin0", "exin1", "exin2"}; -+static const char * const ase_gpt_grps[] = {"gpt1", "gpt2", "gpt3"}; -+static const char * const ase_dfe_grps[] = {"dfe"}; -+static const char * const ase_ephy_grps[] = {"ephy"}; -+static const char * const ase_asc_grps[] = {"asc"}; -+static const char * const ase_jtag_grps[] = {"jtag"}; -+static const char * const ase_stp_grps[] = {"stp"}; -+static const char * const ase_spi_grps[] = {"spi", "spi_cs1", -+ "spi_cs2", "spi_cs3"}; -+ -+static const struct ltq_pmx_func danube_funcs[] = { -+ {"spi", ARRAY_AND_SIZE(xway_spi_grps)}, -+ {"asc", ARRAY_AND_SIZE(xway_asc_grps)}, -+ {"cgu", ARRAY_AND_SIZE(xway_cgu_grps)}, -+ {"jtag", ARRAY_AND_SIZE(xway_jtag_grps)}, -+ {"exin", ARRAY_AND_SIZE(xway_exin_grps)}, -+ {"stp", ARRAY_AND_SIZE(xway_stp_grps)}, -+ {"gpt", ARRAY_AND_SIZE(xway_gpt_grps)}, -+ {"nmi", ARRAY_AND_SIZE(xway_nmi_grps)}, -+ {"pci", ARRAY_AND_SIZE(xway_pci_grps)}, -+ {"ebu", ARRAY_AND_SIZE(xway_ebu_grps)}, -+}; -+ -+static const struct ltq_pmx_func xrx_funcs[] = { -+ {"spi", ARRAY_AND_SIZE(xway_spi_grps)}, -+ {"asc", ARRAY_AND_SIZE(xway_asc_grps)}, -+ {"cgu", ARRAY_AND_SIZE(xway_cgu_grps)}, -+ {"jtag", ARRAY_AND_SIZE(xway_jtag_grps)}, -+ {"exin", ARRAY_AND_SIZE(xrx_exin_grps)}, -+ {"stp", ARRAY_AND_SIZE(xway_stp_grps)}, -+ {"gpt", ARRAY_AND_SIZE(xway_gpt_grps)}, -+ {"nmi", ARRAY_AND_SIZE(xway_nmi_grps)}, -+ {"pci", ARRAY_AND_SIZE(xrx_pci_grps)}, -+ {"ebu", ARRAY_AND_SIZE(xrx_ebu_grps)}, -+ {"mdio", ARRAY_AND_SIZE(xrx_mdio_grps)}, -+}; -+ -+static const struct ltq_pmx_func ase_funcs[] = { -+ {"spi", ARRAY_AND_SIZE(ase_spi_grps)}, -+ {"asc", ARRAY_AND_SIZE(ase_asc_grps)}, -+ {"jtag", ARRAY_AND_SIZE(ase_jtag_grps)}, -+ {"exin", ARRAY_AND_SIZE(ase_exin_grps)}, -+ {"stp", ARRAY_AND_SIZE(ase_stp_grps)}, -+ {"gpt", ARRAY_AND_SIZE(ase_gpt_grps)}, -+ {"ephy", ARRAY_AND_SIZE(ase_ephy_grps)}, -+ {"dfe", ARRAY_AND_SIZE(ase_dfe_grps)}, -+}; -+ -+/* --------- pinconf related code --------- */ -+static int xway_pinconf_get(struct pinctrl_dev *pctldev, -+ unsigned pin, -+ unsigned long *config) -+{ -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev); -+ enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(*config); -+ int port = PORT(pin); -+ u32 reg; -+ -+ switch (param) { -+ case LTQ_PINCONF_PARAM_OPEN_DRAIN: -+ if (port == PORT3) -+ reg = GPIO3_OD; -+ else -+ reg = GPIO_OD(port); -+ *config = LTQ_PINCONF_PACK(param, -+ !!gpio_getbit(info->membase[0], reg, PORT_PIN(port))); -+ break; -+ -+ case LTQ_PINCONF_PARAM_PULL: -+ if (port == PORT3) -+ reg = GPIO3_PUDEN; -+ else -+ reg = GPIO_PUDEN(port); -+ if (!gpio_getbit(info->membase[0], reg, PORT_PIN(port))) { -+ *config = LTQ_PINCONF_PACK(param, 0); -+ break; -+ } -+ -+ if (port == PORT3) -+ reg = GPIO3_PUDSEL; -+ else -+ reg = GPIO_PUDSEL(port); -+ if (!gpio_getbit(info->membase[0], reg, PORT_PIN(port))) -+ *config = LTQ_PINCONF_PACK(param, 2); -+ else -+ *config = LTQ_PINCONF_PACK(param, 1); -+ break; -+ -+ default: -+ dev_err(pctldev->dev, "Invalid config param %04x\n", param); -+ return -ENOTSUPP; -+ } -+ return 0; -+} -+ -+static int xway_pinconf_set(struct pinctrl_dev *pctldev, -+ unsigned pin, -+ unsigned long config) -+{ -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev); -+ enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(config); -+ int arg = LTQ_PINCONF_UNPACK_ARG(config); -+ int port = PORT(pin); -+ u32 reg; -+ -+ switch (param) { -+ case LTQ_PINCONF_PARAM_OPEN_DRAIN: -+ if (port == PORT3) -+ reg = GPIO3_OD; -+ else -+ reg = GPIO_OD(port); -+ gpio_setbit(info->membase[0], reg, PORT_PIN(port)); -+ break; -+ -+ case LTQ_PINCONF_PARAM_PULL: -+ if (port == PORT3) -+ reg = GPIO3_PUDEN; -+ else -+ reg = GPIO_PUDEN(port); -+ if (arg == 0) { -+ gpio_clearbit(info->membase[0], reg, PORT_PIN(port)); -+ break; -+ } -+ gpio_setbit(info->membase[0], reg, PORT_PIN(port)); -+ -+ if (port == PORT3) -+ reg = GPIO3_PUDSEL; -+ else -+ reg = GPIO_PUDSEL(port); -+ if (arg == 1) -+ gpio_clearbit(info->membase[0], reg, PORT_PIN(port)); -+ else if (arg == 2) -+ gpio_setbit(info->membase[0], reg, PORT_PIN(port)); -+ else -+ dev_err(pctldev->dev, "Invalid pull value %d\n", arg); -+ break; -+ -+ default: -+ dev_err(pctldev->dev, "Invalid config param %04x\n", param); -+ return -ENOTSUPP; -+ } -+ return 0; -+} -+ -+struct pinconf_ops xway_pinconf_ops = { -+ .pin_config_get = xway_pinconf_get, -+ .pin_config_set = xway_pinconf_set, -+}; -+ -+static struct pinctrl_desc xway_pctrl_desc = { -+ .owner = THIS_MODULE, -+ .confops = &xway_pinconf_ops, -+}; -+ -+static inline int xway_mux_apply(struct pinctrl_dev *pctrldev, -+ int pin, int mux) -+{ -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); -+ int port = PORT(pin); -+ u32 alt1_reg = GPIO_ALT1(pin); -+ -+ if (port == PORT3) -+ alt1_reg = GPIO3_ALT1; -+ -+ if (mux & MUX_ALT0) -+ gpio_setbit(info->membase[0], GPIO_ALT0(pin), PORT_PIN(pin)); -+ else -+ gpio_clearbit(info->membase[0], GPIO_ALT0(pin), PORT_PIN(pin)); -+ -+ if (mux & MUX_ALT1) -+ gpio_setbit(info->membase[0], alt1_reg, PORT_PIN(pin)); -+ else -+ gpio_clearbit(info->membase[0], alt1_reg, PORT_PIN(pin)); -+ -+ return 0; -+} -+ -+static const struct ltq_cfg_param xway_cfg_params[] = { -+ {"lantiq,pull", LTQ_PINCONF_PARAM_PULL}, -+ {"lantiq,open-drain", LTQ_PINCONF_PARAM_OPEN_DRAIN}, -+}; -+ -+static struct ltq_pinmux_info xway_info = { -+ .desc = &xway_pctrl_desc, -+ .apply_mux = xway_mux_apply, -+ .params = xway_cfg_params, -+ .num_params = ARRAY_SIZE(xway_cfg_params), -+}; -+ -+/* --------- gpio_chip related code --------- */ -+static void xway_gpio_set(struct gpio_chip *chip, unsigned int pin, int val) -+{ -+ struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev); -+ -+ if (val) -+ gpio_setbit(info->membase[0], GPIO_OUT(pin), PORT_PIN(pin)); -+ else -+ gpio_clearbit(info->membase[0], GPIO_OUT(pin), PORT_PIN(pin)); -+} -+ -+static int xway_gpio_get(struct gpio_chip *chip, unsigned int pin) -+{ -+ struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev); -+ -+ return gpio_getbit(info->membase[0], GPIO_IN(pin), PORT_PIN(pin)); -+} -+ -+static int xway_gpio_dir_in(struct gpio_chip *chip, unsigned int pin) -+{ -+ struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev); -+ -+ gpio_clearbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin)); -+ -+ return 0; -+} -+ -+static int xway_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, int val) -+{ -+ struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev); -+ -+ gpio_setbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin)); -+ xway_gpio_set(chip, pin, val); -+ -+ return 0; -+} -+ -+static int xway_gpio_req(struct gpio_chip *chip, unsigned offset) -+{ -+ int gpio = chip->base + offset; -+ -+ return pinctrl_request_gpio(gpio); -+} -+ -+static void xway_gpio_free(struct gpio_chip *chip, unsigned offset) -+{ -+ int gpio = chip->base + offset; -+ -+ pinctrl_free_gpio(gpio); -+} -+ -+static struct gpio_chip xway_chip = { -+ .label = "gpio-xway", -+ .direction_input = xway_gpio_dir_in, -+ .direction_output = xway_gpio_dir_out, -+ .get = xway_gpio_get, -+ .set = xway_gpio_set, -+ .request = xway_gpio_req, -+ .free = xway_gpio_free, -+ .base = -1, -+}; -+ -+ -+/* --------- register the pinctrl layer --------- */ -+static const unsigned xway_exin_pin_map[] = {GPIO0, GPIO1, GPIO2, GPIO39, GPIO46, GPIO9}; -+static const unsigned ase_exin_pins_map[] = {GPIO6, GPIO29, GPIO0}; -+ -+static struct pinctrl_xway_soc { -+ int pin_count; -+ const struct ltq_mfp_pin *mfp; -+ const struct ltq_pin_group *grps; -+ unsigned int num_grps; -+ const struct ltq_pmx_func *funcs; -+ unsigned int num_funcs; -+ const unsigned *exin; -+ unsigned int num_exin; -+} soc_cfg[] = { -+ /* legacy xway */ -+ {XWAY_MAX_PIN, xway_mfp, -+ xway_grps, ARRAY_SIZE(xway_grps), -+ danube_funcs, ARRAY_SIZE(danube_funcs), -+ xway_exin_pin_map, 3}, -+ /* xway xr9 series */ -+ {XR9_MAX_PIN, xway_mfp, -+ xway_grps, ARRAY_SIZE(xway_grps), -+ xrx_funcs, ARRAY_SIZE(xrx_funcs), -+ xway_exin_pin_map, 6}, -+ /* xway ase series */ -+ {XWAY_MAX_PIN, ase_mfp, -+ ase_grps, ARRAY_SIZE(ase_grps), -+ ase_funcs, ARRAY_SIZE(ase_funcs), -+ ase_exin_pins_map, 3}, -+}; -+ -+static struct pinctrl_gpio_range xway_gpio_range = { -+ .name = "XWAY GPIO", -+ .gc = &xway_chip, -+}; -+ -+static const struct of_device_id xway_match[] = { -+ { .compatible = "lantiq,pinctrl-xway", .data = &soc_cfg[0]}, -+ { .compatible = "lantiq,pinctrl-xr9", .data = &soc_cfg[1]}, -+ { .compatible = "lantiq,pinctrl-ase", .data = &soc_cfg[2]}, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, xway_match); -+ -+static int __devinit pinmux_xway_probe(struct platform_device *pdev) -+{ -+ const struct of_device_id *match; -+ const struct pinctrl_xway_soc *xway_soc; -+ struct resource *res; -+ int ret, i; -+ -+ /* get and remap our register range */ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "Failed to get resource\n"); -+ return -ENOENT; -+ } -+ xway_info.membase[0] = devm_request_and_ioremap(&pdev->dev, res); -+ if (!xway_info.membase[0]) { -+ dev_err(&pdev->dev, "Failed to remap resource\n"); -+ return -ENOMEM; -+ } -+ -+ match = of_match_device(xway_match, &pdev->dev); -+ if (match) -+ xway_soc = (const struct pinctrl_xway_soc *) match->data; -+ else -+ xway_soc = &soc_cfg[0]; -+ -+ /* find out how many pads we have */ -+ xway_chip.ngpio = xway_soc->pin_count; -+ -+ /* load our pad descriptors */ -+ xway_info.pads = devm_kzalloc(&pdev->dev, -+ sizeof(struct pinctrl_pin_desc) * xway_chip.ngpio, -+ GFP_KERNEL); -+ if (!xway_info.pads) { -+ dev_err(&pdev->dev, "Failed to allocate pads\n"); -+ return -ENOMEM; -+ } -+ for (i = 0; i < xway_chip.ngpio; i++) { -+ /* strlen("ioXY") + 1 = 5 */ -+ char *name = devm_kzalloc(&pdev->dev, 5, GFP_KERNEL); -+ -+ if (!name) { -+ dev_err(&pdev->dev, "Failed to allocate pad name\n"); -+ return -ENOMEM; -+ } -+ snprintf(name, 5, "io%d", i); -+ xway_info.pads[i].number = GPIO0 + i; -+ xway_info.pads[i].name = name; -+ } -+ xway_pctrl_desc.pins = xway_info.pads; -+ -+ /* load the gpio chip */ -+ xway_chip.dev = &pdev->dev; -+ of_gpiochip_add(&xway_chip); -+ ret = gpiochip_add(&xway_chip); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to register gpio chip\n"); -+ return ret; -+ } -+ -+ /* setup the data needed by pinctrl */ -+ xway_pctrl_desc.name = dev_name(&pdev->dev); -+ xway_pctrl_desc.npins = xway_chip.ngpio; -+ -+ xway_info.num_pads = xway_chip.ngpio; -+ xway_info.num_mfp = xway_chip.ngpio; -+ xway_info.mfp = xway_soc->mfp; -+ xway_info.grps = xway_soc->grps; -+ xway_info.num_grps = xway_soc->num_grps; -+ xway_info.funcs = xway_soc->funcs; -+ xway_info.num_funcs = xway_soc->num_funcs; -+ xway_info.exin = xway_soc->exin; -+ xway_info.num_exin = xway_soc->num_exin; -+ -+ /* register with the generic lantiq layer */ -+ ret = ltq_pinctrl_register(pdev, &xway_info); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to register pinctrl driver\n"); -+ return ret; -+ } -+ -+ /* finish with registering the gpio range in pinctrl */ -+ xway_gpio_range.npins = xway_chip.ngpio; -+ xway_gpio_range.base = xway_chip.base; -+ pinctrl_add_gpio_range(xway_info.pctrl, &xway_gpio_range); -+ dev_info(&pdev->dev, "Init done\n"); -+ return 0; -+} -+ -+static struct platform_driver pinmux_xway_driver = { -+ .probe = pinmux_xway_probe, -+ .driver = { -+ .name = "pinctrl-xway", -+ .owner = THIS_MODULE, -+ .of_match_table = xway_match, -+ }, -+}; -+ -+static int __init pinmux_xway_init(void) -+{ -+ return platform_driver_register(&pinmux_xway_driver); -+} -+ -+core_initcall_sync(pinmux_xway_init); --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0011-OF-pinctrl-MIPS-lantiq-adds-support-for-FALCON-SoC.patch b/target/linux/lantiq/patches-3.6/0011-OF-pinctrl-MIPS-lantiq-adds-support-for-FALCON-SoC.patch deleted file mode 100644 index ec413fcd4f..0000000000 --- a/target/linux/lantiq/patches-3.6/0011-OF-pinctrl-MIPS-lantiq-adds-support-for-FALCON-SoC.patch +++ /dev/null @@ -1,554 +0,0 @@ -From e316cb2b16bbfbe48387b56e7e6b5d32ec686f82 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sun, 20 May 2012 00:33:56 +0200 -Subject: [PATCH 11/15] OF: pinctrl: MIPS: lantiq: adds support for FALCON SoC - -Implement support for pinctrl on lantiq/falcon socs. The FALCON has 5 banks -of up to 32 pins. - -Signed-off-by: John Crispin -Signed-off-by: Thomas Langer -Acked-by: Linus Walleij -Cc: devicetree-discuss@lists.ozlabs.org -Cc: linux-kernel@vger.kernel.org ---- - .../include/asm/mach-lantiq/falcon/lantiq_soc.h | 4 + - arch/mips/lantiq/Kconfig | 1 + - drivers/pinctrl/Kconfig | 5 + - drivers/pinctrl/Makefile | 1 + - drivers/pinctrl/pinctrl-falcon.c | 468 ++++++++++++++++++++ - 5 files changed, 479 insertions(+) - create mode 100644 drivers/pinctrl/pinctrl-falcon.c - -diff --git a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h -index b385252..fccac35 100644 ---- a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h -+++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h -@@ -57,6 +57,10 @@ extern __iomem void *ltq_sys1_membase; - #define ltq_sys1_w32_mask(clear, set, reg) \ - ltq_sys1_w32((ltq_sys1_r32(reg) & ~(clear)) | (set), reg) - -+/* allow the gpio and pinctrl drivers to talk to eachother */ -+extern int pinctrl_falcon_get_range_size(int id); -+extern void pinctrl_falcon_add_gpio_range(struct pinctrl_gpio_range *range); -+ - /* - * to keep the irq code generic we need to define this to 0 as falcon - * has no EIU/EBU -diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig -index 080c013..d84f361 100644 ---- a/arch/mips/lantiq/Kconfig -+++ b/arch/mips/lantiq/Kconfig -@@ -20,6 +20,7 @@ config SOC_XWAY - - config SOC_FALCON - bool "FALCON" -+ select PINCTRL_FALCON - - endchoice - -diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig -index f77dce0..45d2158 100644 ---- a/drivers/pinctrl/Kconfig -+++ b/drivers/pinctrl/Kconfig -@@ -65,6 +65,11 @@ config PINCTRL_PXA3xx - bool - select PINMUX - -+config PINCTRL_FALCON -+ bool -+ depends on SOC_FALCON -+ depends on PINCTRL_LANTIQ -+ - config PINCTRL_MMP2 - bool "MMP2 pin controller driver" - depends on ARCH_MMP -diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile -index e19e207..c0566c8 100644 ---- a/drivers/pinctrl/Makefile -+++ b/drivers/pinctrl/Makefile -@@ -14,6 +14,7 @@ obj-$(CONFIG_PINCTRL_IMX51) += pinctrl-imx51.o - obj-$(CONFIG_PINCTRL_IMX53) += pinctrl-imx53.o - obj-$(CONFIG_PINCTRL_IMX6Q) += pinctrl-imx6q.o - obj-$(CONFIG_PINCTRL_PXA3xx) += pinctrl-pxa3xx.o -+obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o - obj-$(CONFIG_PINCTRL_MMP2) += pinctrl-mmp2.o - obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o - obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o -diff --git a/drivers/pinctrl/pinctrl-falcon.c b/drivers/pinctrl/pinctrl-falcon.c -new file mode 100644 -index 0000000..ee73059 ---- /dev/null -+++ b/drivers/pinctrl/pinctrl-falcon.c -@@ -0,0 +1,468 @@ -+/* -+ * linux/drivers/pinctrl/pinmux-falcon.c -+ * based on linux/drivers/pinctrl/pinmux-pxa910.c -+ * -+ * 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. -+ * -+ * Copyright (C) 2012 Thomas Langer -+ * Copyright (C) 2012 John Crispin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "pinctrl-lantiq.h" -+ -+#include -+ -+/* Multiplexer Control Register */ -+#define LTQ_PADC_MUX(x) (x * 0x4) -+/* Pull Up Enable Register */ -+#define LTQ_PADC_PUEN 0x80 -+/* Pull Down Enable Register */ -+#define LTQ_PADC_PDEN 0x84 -+/* Slew Rate Control Register */ -+#define LTQ_PADC_SRC 0x88 -+/* Drive Current Control Register */ -+#define LTQ_PADC_DCC 0x8C -+/* Pad Control Availability Register */ -+#define LTQ_PADC_AVAIL 0xF0 -+ -+#define pad_r32(p, reg) ltq_r32(p + reg) -+#define pad_w32(p, val, reg) ltq_w32(val, p + reg) -+#define pad_w32_mask(c, clear, set, reg) \ -+ pad_w32(c, (pad_r32(c, reg) & ~(clear)) | (set), reg) -+ -+#define pad_getbit(m, r, p) (!!(ltq_r32(m + r) & (1 << p))) -+ -+#define PORTS 5 -+#define PINS 32 -+#define PORT(x) (x / PINS) -+#define PORT_PIN(x) (x % PINS) -+ -+#define MFP_FALCON(a, f0, f1, f2, f3) \ -+{ \ -+ .name = #a, \ -+ .pin = a, \ -+ .func = { \ -+ FALCON_MUX_##f0, \ -+ FALCON_MUX_##f1, \ -+ FALCON_MUX_##f2, \ -+ FALCON_MUX_##f3, \ -+ }, \ -+} -+ -+#define GRP_MUX(a, m, p) \ -+{ \ -+ .name = a, \ -+ .mux = FALCON_MUX_##m, \ -+ .pins = p, \ -+ .npins = ARRAY_SIZE(p), \ -+} -+ -+enum falcon_mux { -+ FALCON_MUX_GPIO = 0, -+ FALCON_MUX_RST, -+ FALCON_MUX_NTR, -+ FALCON_MUX_MDIO, -+ FALCON_MUX_LED, -+ FALCON_MUX_SPI, -+ FALCON_MUX_ASC, -+ FALCON_MUX_I2C, -+ FALCON_MUX_HOSTIF, -+ FALCON_MUX_SLIC, -+ FALCON_MUX_JTAG, -+ FALCON_MUX_PCM, -+ FALCON_MUX_MII, -+ FALCON_MUX_PHY, -+ FALCON_MUX_NONE = 0xffff, -+}; -+ -+static struct pinctrl_pin_desc falcon_pads[PORTS * PINS]; -+static int pad_count[PORTS]; -+ -+static void lantiq_load_pin_desc(struct pinctrl_pin_desc *d, int bank, int len) -+{ -+ int base = bank * PINS; -+ int i; -+ -+ for (i = 0; i < len; i++) { -+ /* strlen("ioXYZ") + 1 = 6 */ -+ char *name = kzalloc(6, GFP_KERNEL); -+ snprintf(name, 6, "io%d", base + i); -+ d[i].number = base + i; -+ d[i].name = name; -+ } -+ pad_count[bank] = len; -+} -+ -+static struct ltq_mfp_pin falcon_mfp[] = { -+ /* pin f0 f1 f2 f3 */ -+ MFP_FALCON(GPIO0, RST, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO1, GPIO, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO2, GPIO, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO3, GPIO, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO4, NTR, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO5, NTR, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO6, RST, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO7, MDIO, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO8, MDIO, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO9, LED, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO10, LED, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO11, LED, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO12, LED, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO13, LED, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO14, LED, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO32, ASC, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO33, ASC, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO34, SPI, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO35, SPI, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO36, SPI, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO37, SPI, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO38, SPI, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO39, I2C, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO40, I2C, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO41, HOSTIF, GPIO, HOSTIF, JTAG), -+ MFP_FALCON(GPIO42, HOSTIF, GPIO, HOSTIF, NONE), -+ MFP_FALCON(GPIO43, SLIC, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO44, SLIC, GPIO, PCM, ASC), -+ MFP_FALCON(GPIO45, SLIC, GPIO, PCM, ASC), -+ MFP_FALCON(GPIO64, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO65, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO66, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO67, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO68, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO69, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO70, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO71, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO72, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO73, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO74, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO75, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO76, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO77, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO78, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO79, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO80, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO81, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO82, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO83, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO84, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO85, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO86, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO87, MII, GPIO, NONE, NONE), -+ MFP_FALCON(GPIO88, PHY, GPIO, NONE, NONE), -+}; -+ -+static const unsigned pins_por[] = {GPIO0}; -+static const unsigned pins_ntr[] = {GPIO4}; -+static const unsigned pins_ntr8k[] = {GPIO5}; -+static const unsigned pins_hrst[] = {GPIO6}; -+static const unsigned pins_mdio[] = {GPIO7, GPIO8}; -+static const unsigned pins_bled[] = {GPIO7, GPIO10, GPIO11, -+ GPIO12, GPIO13, GPIO14}; -+static const unsigned pins_asc0[] = {GPIO32, GPIO33}; -+static const unsigned pins_spi[] = {GPIO34, GPIO35, GPIO36}; -+static const unsigned pins_spi_cs0[] = {GPIO37}; -+static const unsigned pins_spi_cs1[] = {GPIO38}; -+static const unsigned pins_i2c[] = {GPIO39, GPIO40}; -+static const unsigned pins_jtag[] = {GPIO41}; -+static const unsigned pins_slic[] = {GPIO43, GPIO44, GPIO45}; -+static const unsigned pins_pcm[] = {GPIO44, GPIO45}; -+static const unsigned pins_asc1[] = {GPIO44, GPIO45}; -+ -+static struct ltq_pin_group falcon_grps[] = { -+ GRP_MUX("por", RST, pins_por), -+ GRP_MUX("ntr", NTR, pins_ntr), -+ GRP_MUX("ntr8k", NTR, pins_ntr8k), -+ GRP_MUX("hrst", RST, pins_hrst), -+ GRP_MUX("mdio", MDIO, pins_mdio), -+ GRP_MUX("bootled", LED, pins_bled), -+ GRP_MUX("asc0", ASC, pins_asc0), -+ GRP_MUX("spi", SPI, pins_spi), -+ GRP_MUX("spi cs0", SPI, pins_spi_cs0), -+ GRP_MUX("spi cs1", SPI, pins_spi_cs1), -+ GRP_MUX("i2c", I2C, pins_i2c), -+ GRP_MUX("jtag", JTAG, pins_jtag), -+ GRP_MUX("slic", SLIC, pins_slic), -+ GRP_MUX("pcm", PCM, pins_pcm), -+ GRP_MUX("asc1", ASC, pins_asc1), -+}; -+ -+static const char * const ltq_rst_grps[] = {"por", "hrst"}; -+static const char * const ltq_ntr_grps[] = {"ntr", "ntr8k"}; -+static const char * const ltq_mdio_grps[] = {"mdio"}; -+static const char * const ltq_bled_grps[] = {"bootled"}; -+static const char * const ltq_asc_grps[] = {"asc0", "asc1"}; -+static const char * const ltq_spi_grps[] = {"spi", "spi cs0", "spi cs1"}; -+static const char * const ltq_i2c_grps[] = {"i2c"}; -+static const char * const ltq_jtag_grps[] = {"jtag"}; -+static const char * const ltq_slic_grps[] = {"slic"}; -+static const char * const ltq_pcm_grps[] = {"pcm"}; -+ -+static struct ltq_pmx_func falcon_funcs[] = { -+ {"rst", ARRAY_AND_SIZE(ltq_rst_grps)}, -+ {"ntr", ARRAY_AND_SIZE(ltq_ntr_grps)}, -+ {"mdio", ARRAY_AND_SIZE(ltq_mdio_grps)}, -+ {"led", ARRAY_AND_SIZE(ltq_bled_grps)}, -+ {"asc", ARRAY_AND_SIZE(ltq_asc_grps)}, -+ {"spi", ARRAY_AND_SIZE(ltq_spi_grps)}, -+ {"i2c", ARRAY_AND_SIZE(ltq_i2c_grps)}, -+ {"jtag", ARRAY_AND_SIZE(ltq_jtag_grps)}, -+ {"slic", ARRAY_AND_SIZE(ltq_slic_grps)}, -+ {"pcm", ARRAY_AND_SIZE(ltq_pcm_grps)}, -+}; -+ -+ -+ -+ -+/* --------- pinconf related code --------- */ -+static int falcon_pinconf_group_get(struct pinctrl_dev *pctrldev, -+ unsigned group, unsigned long *config) -+{ -+ return -ENOTSUPP; -+} -+ -+static int falcon_pinconf_group_set(struct pinctrl_dev *pctrldev, -+ unsigned group, unsigned long config) -+{ -+ return -ENOTSUPP; -+} -+ -+static int falcon_pinconf_get(struct pinctrl_dev *pctrldev, -+ unsigned pin, unsigned long *config) -+{ -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); -+ enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(*config); -+ void __iomem *mem = info->membase[PORT(pin)]; -+ -+ switch (param) { -+ case LTQ_PINCONF_PARAM_DRIVE_CURRENT: -+ *config = LTQ_PINCONF_PACK(param, -+ !!pad_getbit(mem, LTQ_PADC_DCC, PORT_PIN(pin))); -+ break; -+ -+ case LTQ_PINCONF_PARAM_SLEW_RATE: -+ *config = LTQ_PINCONF_PACK(param, -+ !!pad_getbit(mem, LTQ_PADC_SRC, PORT_PIN(pin))); -+ break; -+ -+ case LTQ_PINCONF_PARAM_PULL: -+ if (pad_getbit(mem, LTQ_PADC_PDEN, PORT_PIN(pin))) -+ *config = LTQ_PINCONF_PACK(param, 1); -+ else if (pad_getbit(mem, LTQ_PADC_PUEN, PORT_PIN(pin))) -+ *config = LTQ_PINCONF_PACK(param, 2); -+ else -+ *config = LTQ_PINCONF_PACK(param, 0); -+ -+ break; -+ -+ default: -+ return -ENOTSUPP; -+ } -+ -+ return 0; -+} -+ -+static int falcon_pinconf_set(struct pinctrl_dev *pctrldev, -+ unsigned pin, unsigned long config) -+{ -+ enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(config); -+ int arg = LTQ_PINCONF_UNPACK_ARG(config); -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); -+ void __iomem *mem = info->membase[PORT(pin)]; -+ u32 reg; -+ -+ switch (param) { -+ case LTQ_PINCONF_PARAM_DRIVE_CURRENT: -+ reg = LTQ_PADC_DCC; -+ break; -+ -+ case LTQ_PINCONF_PARAM_SLEW_RATE: -+ reg = LTQ_PADC_SRC; -+ break; -+ -+ case LTQ_PINCONF_PARAM_PULL: -+ if (arg == 1) -+ reg = LTQ_PADC_PDEN; -+ else -+ reg = LTQ_PADC_PUEN; -+ break; -+ -+ default: -+ pr_err("%s: Invalid config param %04x\n", -+ pinctrl_dev_get_name(pctrldev), param); -+ return -ENOTSUPP; -+ } -+ -+ pad_w32(mem, BIT(PORT_PIN(pin)), reg); -+ if (!(pad_r32(mem, reg) & BIT(PORT_PIN(pin)))) -+ return -ENOTSUPP; -+ return 0; -+} -+ -+static void falcon_pinconf_dbg_show(struct pinctrl_dev *pctrldev, -+ struct seq_file *s, unsigned offset) -+{ -+} -+ -+static void falcon_pinconf_group_dbg_show(struct pinctrl_dev *pctrldev, -+ struct seq_file *s, unsigned selector) -+{ -+} -+ -+struct pinconf_ops falcon_pinconf_ops = { -+ .pin_config_get = falcon_pinconf_get, -+ .pin_config_set = falcon_pinconf_set, -+ .pin_config_group_get = falcon_pinconf_group_get, -+ .pin_config_group_set = falcon_pinconf_group_set, -+ .pin_config_dbg_show = falcon_pinconf_dbg_show, -+ .pin_config_group_dbg_show = falcon_pinconf_group_dbg_show, -+}; -+ -+static struct pinctrl_desc falcon_pctrl_desc = { -+ .owner = THIS_MODULE, -+ .pins = falcon_pads, -+ .confops = &falcon_pinconf_ops, -+}; -+ -+static inline int falcon_mux_apply(struct pinctrl_dev *pctrldev, -+ int mfp, int mux) -+{ -+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); -+ int port = PORT(info->mfp[mfp].pin); -+ -+ if ((port >= PORTS) || (!info->membase[port])) -+ return -ENODEV; -+ -+ pad_w32(info->membase[port], mux, -+ LTQ_PADC_MUX(PORT_PIN(info->mfp[mfp].pin))); -+ return 0; -+} -+ -+static const struct ltq_cfg_param falcon_cfg_params[] = { -+ {"lantiq,pull", LTQ_PINCONF_PARAM_PULL}, -+ {"lantiq,drive-current", LTQ_PINCONF_PARAM_DRIVE_CURRENT}, -+ {"lantiq,slew-rate", LTQ_PINCONF_PARAM_SLEW_RATE}, -+}; -+ -+static struct ltq_pinmux_info falcon_info = { -+ .desc = &falcon_pctrl_desc, -+ .apply_mux = falcon_mux_apply, -+}; -+ -+ -+ -+ -+/* --------- register the pinctrl layer --------- */ -+ -+int pinctrl_falcon_get_range_size(int id) -+{ -+ u32 avail; -+ -+ if ((id >= PORTS) || (!falcon_info.membase[id])) -+ return -EINVAL; -+ -+ avail = pad_r32(falcon_info.membase[id], LTQ_PADC_AVAIL); -+ -+ return fls(avail); -+} -+ -+void pinctrl_falcon_add_gpio_range(struct pinctrl_gpio_range *range) -+{ -+ pinctrl_add_gpio_range(falcon_info.pctrl, range); -+} -+ -+static int pinctrl_falcon_probe(struct platform_device *pdev) -+{ -+ struct device_node *np; -+ int pad_count = 0; -+ int ret = 0; -+ -+ /* load and remap the pad resources of the different banks */ -+ for_each_compatible_node(np, NULL, "lantiq,pad-falcon") { -+ struct platform_device *ppdev = of_find_device_by_node(np); -+ const __be32 *bank = of_get_property(np, "lantiq,bank", NULL); -+ struct resource res; -+ u32 avail; -+ int pins; -+ -+ if (!ppdev) { -+ dev_err(&pdev->dev, "failed to find pad pdev\n"); -+ continue; -+ } -+ if (!bank || *bank >= PORTS) -+ continue; -+ if (of_address_to_resource(np, 0, &res)) -+ continue; -+ falcon_info.clk[*bank] = clk_get(&ppdev->dev, NULL); -+ if (IS_ERR(falcon_info.clk[*bank])) { -+ dev_err(&ppdev->dev, "failed to get clock\n"); -+ return PTR_ERR(falcon_info.clk[*bank]); -+ } -+ falcon_info.membase[*bank] = -+ devm_request_and_ioremap(&pdev->dev, &res); -+ if (!falcon_info.membase[*bank]) { -+ dev_err(&pdev->dev, -+ "Failed to remap memory for bank %d\n", -+ *bank); -+ return -ENOMEM; -+ } -+ avail = pad_r32(falcon_info.membase[*bank], -+ LTQ_PADC_AVAIL); -+ pins = fls(avail); -+ lantiq_load_pin_desc(&falcon_pads[pad_count], *bank, pins); -+ pad_count += pins; -+ clk_enable(falcon_info.clk[*bank]); -+ dev_dbg(&pdev->dev, "found %s with %d pads\n", -+ res.name, pins); -+ } -+ dev_dbg(&pdev->dev, "found a total of %d pads\n", pad_count); -+ falcon_pctrl_desc.name = dev_name(&pdev->dev); -+ falcon_pctrl_desc.npins = pad_count; -+ -+ falcon_info.mfp = falcon_mfp; -+ falcon_info.num_mfp = ARRAY_SIZE(falcon_mfp); -+ falcon_info.grps = falcon_grps; -+ falcon_info.num_grps = ARRAY_SIZE(falcon_grps); -+ falcon_info.funcs = falcon_funcs; -+ falcon_info.num_funcs = ARRAY_SIZE(falcon_funcs); -+ -+ ret = ltq_pinctrl_register(pdev, &falcon_info); -+ if (!ret) -+ dev_info(&pdev->dev, "Init done\n"); -+ return ret; -+} -+ -+static const struct of_device_id falcon_match[] = { -+ { .compatible = "lantiq,pinctrl-falcon" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, falcon_match); -+ -+static struct platform_driver pinctrl_falcon_driver = { -+ .probe = pinctrl_falcon_probe, -+ .driver = { -+ .name = "pinctrl-falcon", -+ .owner = THIS_MODULE, -+ .of_match_table = falcon_match, -+ }, -+}; -+ -+int __init pinctrl_falcon_init(void) -+{ -+ return platform_driver_register(&pinctrl_falcon_driver); -+} -+ -+core_initcall_sync(pinctrl_falcon_init); --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0012-Document-devicetree-add-OF-documents-for-lantiq-xway.patch b/target/linux/lantiq/patches-3.6/0012-Document-devicetree-add-OF-documents-for-lantiq-xway.patch deleted file mode 100644 index 84f930fa8a..0000000000 --- a/target/linux/lantiq/patches-3.6/0012-Document-devicetree-add-OF-documents-for-lantiq-xway.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 5c56f76995691cf761f66d6d89a00eea80be660c Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 20 Jul 2012 19:01:00 +0200 -Subject: [PATCH 12/15] Document: devicetree: add OF documents for lantiq xway - pinctrl - -Signed-off-by: John Crispin -Acked-by: Linus Walleij -Cc: devicetree-discuss@lists.ozlabs.org -Cc: linux-kernel@vger.kernel.org ---- - .../bindings/pinctrl/lantiq,xway-pinumx.txt | 97 ++++++++++++++++++++ - 1 file changed, 97 insertions(+) - create mode 100644 Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt - -diff --git a/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt b/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt -new file mode 100644 -index 0000000..b5469db ---- /dev/null -+++ b/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt -@@ -0,0 +1,97 @@ -+Lantiq XWAY pinmux controller -+ -+Required properties: -+- compatible: "lantiq,pinctrl-xway" or "lantiq,pinctrl-xr9" -+- reg: Should contain the physical address and length of the gpio/pinmux -+ register range -+ -+Please refer to pinctrl-bindings.txt in this directory for details of the -+common pinctrl bindings used by client devices, including the meaning of the -+phrase "pin configuration node". -+ -+Lantiq's pin configuration nodes act as a container for an abitrary number of -+subnodes. Each of these subnodes represents some desired configuration for a -+pin, a group, or a list of pins or groups. This configuration can include the -+mux function to select on those group(s), and two pin configuration parameters: -+pull-up and open-drain -+ -+The name of each subnode is not important as long as it is unique; all subnodes -+should be enumerated and processed purely based on their content. -+ -+Each subnode only affects those parameters that are explicitly listed. In -+other words, a subnode that lists a mux function but no pin configuration -+parameters implies no information about any pin configuration parameters. -+Similarly, a pin subnode that describes a pullup parameter implies no -+information about e.g. the mux function. -+ -+We support 2 types of nodes. -+ -+Definition of mux function groups: -+ -+Required subnode-properties: -+- lantiq,groups : An array of strings. Each string contains the name of a group. -+ Valid values for these names are listed below. -+- lantiq,function: A string containing the name of the function to mux to the -+ group. Valid values for function names are listed below. -+ -+Valid values for group and function names: -+ -+ mux groups: -+ exin0, exin1, exin2, jtag, ebu a23, ebu a24, ebu a25, ebu clk, ebu cs1, -+ ebu wait, nand ale, nand cs1, nand cle, spi, spi_cs1, spi_cs2, spi_cs3, -+ spi_cs4, spi_cs5, spi_cs6, asc0, asc0 cts rts, stp, nmi , gpt1, gpt2, -+ gpt3, clkout0, clkout1, clkout2, clkout3, gnt1, gnt2, gnt3, req1, req2, -+ req3 -+ -+ additional mux groups (XR9 only): -+ mdio, nand rdy, nand rd, exin3, exin4, gnt4, req4 -+ -+ functions: -+ spi, asc, cgu, jtag, exin, stp, gpt, nmi, pci, ebu, mdio -+ -+ -+ -+Definition of pin configurations: -+ -+Required subnode-properties: -+- lantiq,pins : An array of strings. Each string contains the name of a pin. -+ Valid values for these names are listed below. -+ -+Optional subnode-properties: -+- lantiq,pull: Integer, representing the pull-down/up to apply to the pin. -+ 0: none, 1: down, 2: up. -+- lantiq,open-drain: Boolean, enables open-drain on the defined pin. -+ -+Valid values for XWAY pin names: -+ Pinconf pins can be referenced via the names io0-io31. -+ -+Valid values for XR9 pin names: -+ Pinconf pins can be referenced via the names io0-io55. -+ -+Example: -+ gpio: pinmux@E100B10 { -+ compatible = "lantiq,pinctrl-xway"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&state_default>; -+ -+ #gpio-cells = <2>; -+ gpio-controller; -+ reg = <0xE100B10 0xA0>; -+ -+ state_default: pinmux { -+ stp { -+ lantiq,groups = "stp"; -+ lantiq,function = "stp"; -+ }; -+ pci { -+ lantiq,groups = "gnt1"; -+ lantiq,function = "pci"; -+ }; -+ conf_out { -+ lantiq,pins = "io4", "io5", "io6"; /* stp */ -+ lantiq,open-drain; -+ lantiq,pull = <0>; -+ }; -+ }; -+ }; -+ --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0013-Document-devicetree-add-OF-documents-for-lantiq-falc.patch b/target/linux/lantiq/patches-3.6/0013-Document-devicetree-add-OF-documents-for-lantiq-falc.patch deleted file mode 100644 index 28fd21276c..0000000000 --- a/target/linux/lantiq/patches-3.6/0013-Document-devicetree-add-OF-documents-for-lantiq-falc.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 8e004b47b7645fe8ebe1bb81f75cd8f16650de68 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sun, 22 Jul 2012 09:23:50 +0200 -Subject: [PATCH 13/15] Document: devicetree: add OF documents for lantiq - falcon pinctrl - -Signed-off-by: John Crispin -Signed-off-by: Thomas Langer -Acked-by: Linus Walleij -Cc: devicetree-discuss@lists.ozlabs.org -Cc: linux-kernel@vger.kernel.org ---- - .../bindings/pinctrl/lantiq,falcon-pinumx.txt | 83 ++++++++++++++++++++ - 1 file changed, 83 insertions(+) - create mode 100644 Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt - -diff --git a/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt b/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt -new file mode 100644 -index 0000000..daa7689 ---- /dev/null -+++ b/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt -@@ -0,0 +1,83 @@ -+Lantiq FALCON pinmux controller -+ -+Required properties: -+- compatible: "lantiq,pinctrl-falcon" -+- reg: Should contain the physical address and length of the gpio/pinmux -+ register range -+ -+Please refer to pinctrl-bindings.txt in this directory for details of the -+common pinctrl bindings used by client devices, including the meaning of the -+phrase "pin configuration node". -+ -+Lantiq's pin configuration nodes act as a container for an abitrary number of -+subnodes. Each of these subnodes represents some desired configuration for a -+pin, a group, or a list of pins or groups. This configuration can include the -+mux function to select on those group(s), and two pin configuration parameters: -+pull-up and open-drain -+ -+The name of each subnode is not important as long as it is unique; all subnodes -+should be enumerated and processed purely based on their content. -+ -+Each subnode only affects those parameters that are explicitly listed. In -+other words, a subnode that lists a mux function but no pin configuration -+parameters implies no information about any pin configuration parameters. -+Similarly, a pin subnode that describes a pullup parameter implies no -+information about e.g. the mux function. -+ -+We support 2 types of nodes. -+ -+Definition of mux function groups: -+ -+Required subnode-properties: -+- lantiq,groups : An array of strings. Each string contains the name of a group. -+ Valid values for these names are listed below. -+- lantiq,function: A string containing the name of the function to mux to the -+ group. Valid values for function names are listed below. -+ -+Valid values for group and function names: -+ -+ mux groups: -+ por, ntr, ntr8k, hrst, mdio, bootled, asc0, spi, spi cs0, spi cs1, i2c, -+ jtag, slic, pcm, asc1 -+ -+ functions: -+ rst, ntr, mdio, led, asc, spi, i2c, jtag, slic, pcm -+ -+ -+Definition of pin configurations: -+ -+Required subnode-properties: -+- lantiq,pins : An array of strings. Each string contains the name of a pin. -+ Valid values for these names are listed below. -+ -+Optional subnode-properties: -+- lantiq,pull: Integer, representing the pull-down/up to apply to the pin. -+ 0: none, 1: down -+- lantiq,drive-current: Boolean, enables drive-current -+- lantiq,slew-rate: Boolean, enables slew-rate -+ -+Example: -+ pinmux0 { -+ compatible = "lantiq,pinctrl-falcon"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&state_default>; -+ -+ state_default: pinmux { -+ asc0 { -+ lantiq,groups = "asc0"; -+ lantiq,function = "asc"; -+ }; -+ ntr { -+ lantiq,groups = "ntr8k"; -+ lantiq,function = "ntr"; -+ }; -+ i2c { -+ lantiq,groups = "i2c"; -+ lantiq,function = "i2c"; -+ }; -+ hrst { -+ lantiq,groups = "hrst"; -+ lantiq,function = "rst"; -+ }; -+ }; -+ }; --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0014-MIPS-lantiq-make-use-of-__gpio_to_irq.patch b/target/linux/lantiq/patches-3.6/0014-MIPS-lantiq-make-use-of-__gpio_to_irq.patch deleted file mode 100644 index 6b24782b68..0000000000 --- a/target/linux/lantiq/patches-3.6/0014-MIPS-lantiq-make-use-of-__gpio_to_irq.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 6a88a0f762a61f212d4bbcf1ad45369f28014484 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Wed, 15 Aug 2012 15:41:50 +0200 -Subject: [PATCH 14/15] MIPS: lantiq: make use of __gpio_to_irq - -The gpio_chip struct allows us to set a .to_irq callback. Once this is set -we can rely on the generic __gpio_to_irq() function to map gpio->irq allowing -more than one gpio_chip to register an interrupt - -Signed-off-by: John Crispin ---- - arch/mips/include/asm/mach-lantiq/gpio.h | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - -diff --git a/arch/mips/include/asm/mach-lantiq/gpio.h b/arch/mips/include/asm/mach-lantiq/gpio.h -index f79505b..9ba1cae 100644 ---- a/arch/mips/include/asm/mach-lantiq/gpio.h -+++ b/arch/mips/include/asm/mach-lantiq/gpio.h -@@ -1,10 +1,7 @@ - #ifndef __ASM_MIPS_MACH_LANTIQ_GPIO_H - #define __ASM_MIPS_MACH_LANTIQ_GPIO_H - --static inline int gpio_to_irq(unsigned int gpio) --{ -- return -1; --} -+#define gpio_to_irq __gpio_to_irq - - #define gpio_get_value __gpio_get_value - #define gpio_set_value __gpio_set_value --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0015-GPIO-MIPS-lantiq-fix-overflow-inside-stp-xway-driver.patch b/target/linux/lantiq/patches-3.6/0015-GPIO-MIPS-lantiq-fix-overflow-inside-stp-xway-driver.patch deleted file mode 100644 index d142420a3c..0000000000 --- a/target/linux/lantiq/patches-3.6/0015-GPIO-MIPS-lantiq-fix-overflow-inside-stp-xway-driver.patch +++ /dev/null @@ -1,34 +0,0 @@ -From c9e854cf940fbc09846c255895efceb3bc9bf095 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Wed, 11 Jul 2012 16:33:43 +0200 -Subject: [PATCH 15/15] GPIO: MIPS: lantiq: fix overflow inside stp-xway - driver - -The driver was using a 16 bit field for storing the shadow value of the shift -register cascade. This resulted in only the first 2 shift registeres receiving -the correct data. The third shift register would always receive 0x00. - -Fix this by using a 32bit field for the shadow value. - -Signed-off-by: John Crispin -Cc: linux-kernel@vger.kernel.org ---- - drivers/gpio/gpio-stp-xway.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/gpio/gpio-stp-xway.c b/drivers/gpio/gpio-stp-xway.c -index e35096b..8bead0b 100644 ---- a/drivers/gpio/gpio-stp-xway.c -+++ b/drivers/gpio/gpio-stp-xway.c -@@ -82,7 +82,7 @@ struct xway_stp { - struct gpio_chip gc; - void __iomem *virt; - u32 edge; /* rising or falling edge triggered shift register */ -- u16 shadow; /* shadow the shift registers state */ -+ u32 shadow; /* shadow the shift registers state */ - u8 groups; /* we can drive 1-3 groups of 8bit each */ - u8 dsl; /* the 2 LSBs can be driven by the dsl core */ - u8 phy1; /* 3 bits can be driven by phy1 */ --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0016-mtd-lantiq-Add-NAND-support-on-Lantiq-XWAY-SoC.patch b/target/linux/lantiq/patches-3.6/0016-mtd-lantiq-Add-NAND-support-on-Lantiq-XWAY-SoC.patch deleted file mode 100644 index b57790a89d..0000000000 --- a/target/linux/lantiq/patches-3.6/0016-mtd-lantiq-Add-NAND-support-on-Lantiq-XWAY-SoC.patch +++ /dev/null @@ -1,257 +0,0 @@ -From 99f2b107924c07bee0bae7151426495fb815ca6e Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 23 Aug 2012 20:28:32 +0200 -Subject: [PATCH] mtd: lantiq: Add NAND support on Lantiq XWAY SoC. - -The driver uses plat_nand. As the platform_device is loaded from DT, we need -to lookup the node and attach our xway specific "struct platform_nand_data" -to it. - -Signed-off-by: John Crispin -Signed-off-by: Artem Bityutskiy -Signed-off-by: David Woodhouse ---- - drivers/mtd/nand/Kconfig | 8 ++ - drivers/mtd/nand/Makefile | 1 + - drivers/mtd/nand/xway_nand.c | 201 ++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 210 insertions(+) - create mode 100644 drivers/mtd/nand/xway_nand.c - -diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig -index 7101e8a..ce5cf02 100644 ---- a/drivers/mtd/nand/Kconfig -+++ b/drivers/mtd/nand/Kconfig -@@ -580,4 +580,12 @@ config MTD_NAND_FSMC - Enables support for NAND Flash chips on the ST Microelectronics - Flexible Static Memory Controller (FSMC) - -+config MTD_NAND_XWAY -+ tristate "Support for NAND on Lantiq XWAY SoC" -+ depends on LANTIQ && SOC_TYPE_XWAY -+ select MTD_NAND_PLATFORM -+ help -+ Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached -+ to the External Bus Unit (EBU). -+ - endif # MTD_NAND -diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile -index ddee818..c4b0ab3 100644 ---- a/drivers/mtd/nand/Makefile -+++ b/drivers/mtd/nand/Makefile -@@ -53,5 +53,6 @@ obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o - obj-$(CONFIG_MTD_NAND_RICOH) += r852.o - obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o - obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ -+obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o - - nand-objs := nand_base.o nand_bbt.o -diff --git a/drivers/mtd/nand/xway_nand.c b/drivers/mtd/nand/xway_nand.c -new file mode 100644 -index 0000000..3f81dc8 ---- /dev/null -+++ b/drivers/mtd/nand/xway_nand.c -@@ -0,0 +1,201 @@ -+/* -+ * 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. -+ * -+ * Copyright © 2012 John Crispin -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+/* nand registers */ -+#define EBU_ADDSEL1 0x24 -+#define EBU_NAND_CON 0xB0 -+#define EBU_NAND_WAIT 0xB4 -+#define EBU_NAND_ECC0 0xB8 -+#define EBU_NAND_ECC_AC 0xBC -+ -+/* nand commands */ -+#define NAND_CMD_ALE (1 << 2) -+#define NAND_CMD_CLE (1 << 3) -+#define NAND_CMD_CS (1 << 4) -+#define NAND_WRITE_CMD_RESET 0xff -+#define NAND_WRITE_CMD (NAND_CMD_CS | NAND_CMD_CLE) -+#define NAND_WRITE_ADDR (NAND_CMD_CS | NAND_CMD_ALE) -+#define NAND_WRITE_DATA (NAND_CMD_CS) -+#define NAND_READ_DATA (NAND_CMD_CS) -+#define NAND_WAIT_WR_C (1 << 3) -+#define NAND_WAIT_RD (0x1) -+ -+/* we need to tel the ebu which addr we mapped the nand to */ -+#define ADDSEL1_MASK(x) (x << 4) -+#define ADDSEL1_REGEN 1 -+ -+/* we need to tell the EBU that we have nand attached and set it up properly */ -+#define BUSCON1_SETUP (1 << 22) -+#define BUSCON1_BCGEN_RES (0x3 << 12) -+#define BUSCON1_WAITWRC2 (2 << 8) -+#define BUSCON1_WAITRDC2 (2 << 6) -+#define BUSCON1_HOLDC1 (1 << 4) -+#define BUSCON1_RECOVC1 (1 << 2) -+#define BUSCON1_CMULT4 1 -+ -+#define NAND_CON_CE (1 << 20) -+#define NAND_CON_OUT_CS1 (1 << 10) -+#define NAND_CON_IN_CS1 (1 << 8) -+#define NAND_CON_PRE_P (1 << 7) -+#define NAND_CON_WP_P (1 << 6) -+#define NAND_CON_SE_P (1 << 5) -+#define NAND_CON_CS_P (1 << 4) -+#define NAND_CON_CSMUX (1 << 1) -+#define NAND_CON_NANDM 1 -+ -+static void xway_reset_chip(struct nand_chip *chip) -+{ -+ unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W; -+ unsigned long flags; -+ -+ nandaddr &= ~NAND_WRITE_ADDR; -+ nandaddr |= NAND_WRITE_CMD; -+ -+ /* finish with a reset */ -+ spin_lock_irqsave(&ebu_lock, flags); -+ writeb(NAND_WRITE_CMD_RESET, (void __iomem *) nandaddr); -+ while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0) -+ ; -+ spin_unlock_irqrestore(&ebu_lock, flags); -+} -+ -+static void xway_select_chip(struct mtd_info *mtd, int chip) -+{ -+ -+ switch (chip) { -+ case -1: -+ ltq_ebu_w32_mask(NAND_CON_CE, 0, EBU_NAND_CON); -+ ltq_ebu_w32_mask(NAND_CON_NANDM, 0, EBU_NAND_CON); -+ break; -+ case 0: -+ ltq_ebu_w32_mask(0, NAND_CON_NANDM, EBU_NAND_CON); -+ ltq_ebu_w32_mask(0, NAND_CON_CE, EBU_NAND_CON); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+static void xway_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) -+{ -+ struct nand_chip *this = mtd->priv; -+ unsigned long nandaddr = (unsigned long) this->IO_ADDR_W; -+ unsigned long flags; -+ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ nandaddr &= ~(NAND_WRITE_CMD | NAND_WRITE_ADDR); -+ if (ctrl & NAND_CLE) -+ nandaddr |= NAND_WRITE_CMD; -+ else -+ nandaddr |= NAND_WRITE_ADDR; -+ this->IO_ADDR_W = (void __iomem *) nandaddr; -+ } -+ -+ if (cmd != NAND_CMD_NONE) { -+ spin_lock_irqsave(&ebu_lock, flags); -+ writeb(cmd, this->IO_ADDR_W); -+ while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0) -+ ; -+ spin_unlock_irqrestore(&ebu_lock, flags); -+ } -+} -+ -+static int xway_dev_ready(struct mtd_info *mtd) -+{ -+ return ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD; -+} -+ -+static unsigned char xway_read_byte(struct mtd_info *mtd) -+{ -+ struct nand_chip *this = mtd->priv; -+ unsigned long nandaddr = (unsigned long) this->IO_ADDR_R; -+ unsigned long flags; -+ int ret; -+ -+ spin_lock_irqsave(&ebu_lock, flags); -+ ret = ltq_r8((void __iomem *)(nandaddr + NAND_READ_DATA)); -+ spin_unlock_irqrestore(&ebu_lock, flags); -+ -+ return ret; -+} -+ -+static int xway_nand_probe(struct platform_device *pdev) -+{ -+ struct nand_chip *this = platform_get_drvdata(pdev); -+ unsigned long nandaddr = (unsigned long) this->IO_ADDR_W; -+ const __be32 *cs = of_get_property(pdev->dev.of_node, -+ "lantiq,cs", NULL); -+ u32 cs_flag = 0; -+ -+ /* load our CS from the DT. Either we find a valid 1 or default to 0 */ -+ if (cs && (*cs == 1)) -+ cs_flag = NAND_CON_IN_CS1 | NAND_CON_OUT_CS1; -+ -+ /* setup the EBU to run in NAND mode on our base addr */ -+ ltq_ebu_w32(CPHYSADDR(nandaddr) -+ | ADDSEL1_MASK(3) | ADDSEL1_REGEN, EBU_ADDSEL1); -+ -+ ltq_ebu_w32(BUSCON1_SETUP | BUSCON1_BCGEN_RES | BUSCON1_WAITWRC2 -+ | BUSCON1_WAITRDC2 | BUSCON1_HOLDC1 | BUSCON1_RECOVC1 -+ | BUSCON1_CMULT4, LTQ_EBU_BUSCON1); -+ -+ ltq_ebu_w32(NAND_CON_NANDM | NAND_CON_CSMUX | NAND_CON_CS_P -+ | NAND_CON_SE_P | NAND_CON_WP_P | NAND_CON_PRE_P -+ | cs_flag, EBU_NAND_CON); -+ -+ /* finish with a reset */ -+ xway_reset_chip(this); -+ -+ return 0; -+} -+ -+/* allow users to override the partition in DT using the cmdline */ -+static const char *part_probes[] = { "cmdlinepart", "ofpart", NULL }; -+ -+static struct platform_nand_data xway_nand_data = { -+ .chip = { -+ .nr_chips = 1, -+ .chip_delay = 30, -+ .part_probe_types = part_probes, -+ }, -+ .ctrl = { -+ .probe = xway_nand_probe, -+ .cmd_ctrl = xway_cmd_ctrl, -+ .dev_ready = xway_dev_ready, -+ .select_chip = xway_select_chip, -+ .read_byte = xway_read_byte, -+ } -+}; -+ -+/* -+ * Try to find the node inside the DT. If it is available attach out -+ * platform_nand_data -+ */ -+static int __init xway_register_nand(void) -+{ -+ struct device_node *node; -+ struct platform_device *pdev; -+ -+ node = of_find_compatible_node(NULL, NULL, "lantiq,nand-xway"); -+ if (!node) -+ return -ENOENT; -+ pdev = of_find_device_by_node(node); -+ if (!pdev) -+ return -EINVAL; -+ pdev->dev.platform_data = &xway_nand_data; -+ of_node_put(node); -+ return 0; -+} -+ -+subsys_initcall(xway_register_nand); --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0100-MIPS-lantiq-external-interrupt-units-not-loaded-prop.patch b/target/linux/lantiq/patches-3.6/0100-MIPS-lantiq-external-interrupt-units-not-loaded-prop.patch deleted file mode 100644 index 1ae8d59a0f..0000000000 --- a/target/linux/lantiq/patches-3.6/0100-MIPS-lantiq-external-interrupt-units-not-loaded-prop.patch +++ /dev/null @@ -1,71 +0,0 @@ -From b27b8f1bd7d46f1affc9a2bc4142e248411c1afa Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 22 Oct 2012 17:42:48 +0200 -Subject: [PATCH 100/113] MIPS: lantiq: external interrupt units not loaded - properly - -The code references the wrong device node causing the number of EIU pins to -be wrong. - -Signed-off-by: John Crispin ---- - arch/mips/lantiq/irq.c | 2 +- - drivers/pinctrl/pinctrl-xway.c | 15 +++++++++++++++ - 2 files changed, 16 insertions(+), 1 deletion(-) - -diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c -index f36acd1..8e55622 100644 ---- a/arch/mips/lantiq/irq.c -+++ b/arch/mips/lantiq/irq.c -@@ -343,7 +343,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) - eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu"); - if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) { - /* find out how many external irq sources we have */ -- const __be32 *count = of_get_property(node, -+ const __be32 *count = of_get_property(eiu_node, - "lantiq,count", NULL); - - if (count) -diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c -index b9bcaec..ea5e017 100644 ---- a/drivers/pinctrl/pinctrl-xway.c -+++ b/drivers/pinctrl/pinctrl-xway.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -618,6 +619,19 @@ static void xway_gpio_free(struct gpio_chip *chip, unsigned offset) - pinctrl_free_gpio(gpio); - } - -+static int xway_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) -+{ -+ struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev); -+ struct resource res; -+ int i; -+ -+ for (i = 0; i < info->num_exin; i++) -+ if (offset == info->exin[i]) -+ if (of_irq_to_resource(chip->dev->of_node, i, &res)) -+ return res.start; -+ return 0; -+} -+ - static struct gpio_chip xway_chip = { - .label = "gpio-xway", - .direction_input = xway_gpio_dir_in, -@@ -626,6 +640,7 @@ static struct gpio_chip xway_chip = { - .set = xway_gpio_set, - .request = xway_gpio_req, - .free = xway_gpio_free, -+ .to_irq = xway_gpio_to_irq, - .base = -1, - }; - --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0101-MIPS-lantiq-bootsel-bits-are-wrong.patch b/target/linux/lantiq/patches-3.6/0101-MIPS-lantiq-bootsel-bits-are-wrong.patch deleted file mode 100644 index e8a24051c5..0000000000 --- a/target/linux/lantiq/patches-3.6/0101-MIPS-lantiq-bootsel-bits-are-wrong.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 50b5073dd266721a690323519fb906a56daa09d7 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 1 Nov 2012 20:39:43 +0100 -Subject: [PATCH 101/113] MIPS: lantiq: bootsel bits are wrong - ---- - arch/mips/lantiq/xway/reset.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c -index 22c55f7..a89d1a3 100644 ---- a/arch/mips/lantiq/xway/reset.c -+++ b/arch/mips/lantiq/xway/reset.c -@@ -34,8 +34,8 @@ - /* reset cause */ - #define RCU_STAT_SHIFT 26 - /* boot selection */ --#define RCU_BOOT_SEL_SHIFT 26 --#define RCU_BOOT_SEL_MASK 0x7 -+#define RCU_BOOT_SEL_SHIFT 17 -+#define RCU_BOOT_SEL_MASK 0xf - - /* remapped base addr of the reset control unit */ - static void __iomem *ltq_rcu_membase; --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0102-MIPS-lantiq-fixes-dma-irq-ack.patch b/target/linux/lantiq/patches-3.6/0102-MIPS-lantiq-fixes-dma-irq-ack.patch deleted file mode 100644 index 89bcd709b6..0000000000 --- a/target/linux/lantiq/patches-3.6/0102-MIPS-lantiq-fixes-dma-irq-ack.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 671f34ea864ddc353f32272b3a2f7ee62d6f8548 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 1 Nov 2012 20:50:39 +0100 -Subject: [PATCH 102/113] MIPS: lantiq: fixes dma irq ack - ---- - arch/mips/lantiq/xway/dma.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c -index 55d2c4f..a301b3b 100644 ---- a/arch/mips/lantiq/xway/dma.c -+++ b/arch/mips/lantiq/xway/dma.c -@@ -25,6 +25,7 @@ - #include - #include - -+#define LTQ_DMA_ID 0x08 - #define LTQ_DMA_CTRL 0x10 - #define LTQ_DMA_CPOLL 0x14 - #define LTQ_DMA_CS 0x18 -@@ -89,7 +90,7 @@ ltq_dma_ack_irq(struct ltq_dma_channel *ch) - - local_irq_save(flags); - ltq_dma_w32(ch->nr, LTQ_DMA_CS); -- ltq_dma_w32(DMA_IRQ_ACK, LTQ_DMA_CIS); -+ ltq_dma_w32(ltq_dma_r32(LTQ_DMA_CIS), LTQ_DMA_CIS); - local_irq_restore(flags); - } - EXPORT_SYMBOL_GPL(ltq_dma_ack_irq); -@@ -103,6 +104,7 @@ ltq_dma_open(struct ltq_dma_channel *ch) - ltq_dma_w32(ch->nr, LTQ_DMA_CS); - ltq_dma_w32_mask(0, DMA_CHAN_ON, LTQ_DMA_CCTRL); - ltq_dma_enable_irq(ch); -+ ltq_dma_ack_irq(ch); - local_irq_restore(flag); - } - EXPORT_SYMBOL_GPL(ltq_dma_open); -@@ -214,6 +216,7 @@ ltq_dma_init(struct platform_device *pdev) - { - struct clk *clk; - struct resource *res; -+ unsigned id; - int i; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -@@ -243,6 +246,12 @@ ltq_dma_init(struct platform_device *pdev) - ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); - ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); - } -+ -+ id = ltq_dma_r32(LTQ_DMA_ID); -+ dev_info(&pdev->dev, -+ "Init done - hw rev: %X, ports: %d, channels: %d\n", -+ id & 0x1f, (id >> 16) & 0xf, id >> 20); -+ - dev_info(&pdev->dev, "init done\n"); - return 0; - } --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0103-MIPS-lantiq-prom-code-invalidated-devicetree-memory.patch b/target/linux/lantiq/patches-3.6/0103-MIPS-lantiq-prom-code-invalidated-devicetree-memory.patch deleted file mode 100644 index 0c6d91b03a..0000000000 --- a/target/linux/lantiq/patches-3.6/0103-MIPS-lantiq-prom-code-invalidated-devicetree-memory.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 176aad2b97d2e7d623ef07ee9b68b71c7db8cce4 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 1 Nov 2012 20:50:52 +0100 -Subject: [PATCH 103/113] MIPS: lantiq: prom code invalidated devicetree - memory - ---- - arch/mips/lantiq/prom.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - -diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c -index 6cfd611..9f9e875 100644 ---- a/arch/mips/lantiq/prom.c -+++ b/arch/mips/lantiq/prom.c -@@ -87,9 +87,6 @@ void __init device_tree_init(void) - reserve_bootmem(base, size, BOOTMEM_DEFAULT); - - unflatten_device_tree(); -- -- /* free the space reserved for the dt blob */ -- free_bootmem(base, size); - } - - void __init prom_init(void) -@@ -119,7 +116,7 @@ int __init plat_of_setup(void) - sizeof(of_ids[0].compatible)); - strncpy(of_ids[1].compatible, "simple-bus", - sizeof(of_ids[1].compatible)); -- return of_platform_bus_probe(NULL, of_ids, NULL); -+ return of_platform_populate(NULL, of_ids, NULL, NULL); - } - - arch_initcall(plat_of_setup); --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0104-MIPS-lantiq-xway-split-ltq_reset_once-into-2-subfunc.patch b/target/linux/lantiq/patches-3.6/0104-MIPS-lantiq-xway-split-ltq_reset_once-into-2-subfunc.patch deleted file mode 100644 index 7a4c3c7e7c..0000000000 --- a/target/linux/lantiq/patches-3.6/0104-MIPS-lantiq-xway-split-ltq_reset_once-into-2-subfunc.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 8fc2eacbe332fbf6bfd09425fb141bb47d843a78 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 22 Oct 2012 09:32:46 +0200 -Subject: [PATCH 104/113] MIPS: lantiq: xway: split ltq_reset_once into 2 - subfunctions - -We need to call the reset functions from within the phy reset code and dont -want to duplicate the access code for the reset registers. - -Signed-off-by: John Crispin ---- - arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 3 +++ - arch/mips/lantiq/xway/reset.c | 14 ++++++++++++-- - 2 files changed, 15 insertions(+), 2 deletions(-) - -diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -index 6a2df70..6b9f5be 100644 ---- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -@@ -87,5 +87,8 @@ extern __iomem void *ltq_cgu_membase; - extern void ltq_pmu_enable(unsigned int module); - extern void ltq_pmu_disable(unsigned int module); - -+/* allow drivers to reset clock domains and ip cores */ -+void ltq_reset_once(unsigned int module, ulong u); -+ - #endif /* CONFIG_SOC_TYPE_XWAY */ - #endif /* _LTQ_XWAY_H__ */ -diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c -index a89d1a3..1b77f82 100644 ---- a/arch/mips/lantiq/xway/reset.c -+++ b/arch/mips/lantiq/xway/reset.c -@@ -55,12 +55,22 @@ unsigned char ltq_boot_select(void) - return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK; - } - -+static void ltq_reset_enter(unsigned int module) -+{ -+ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ); -+} -+ -+static void ltq_reset_leave(unsigned int module) -+{ -+ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); -+} -+ - /* reset a io domain for u micro seconds */ - void ltq_reset_once(unsigned int module, ulong u) - { -- ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ); -+ ltq_reset_enter(RCU_RST_REQ); - udelay(u); -- ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); -+ ltq_reset_leave(RCU_RST_REQ); - } - - static void ltq_machine_restart(char *command) --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0105-MIPS-lantiq-xway-adds-reset-code-for-11G-PHYs.patch b/target/linux/lantiq/patches-3.6/0105-MIPS-lantiq-xway-adds-reset-code-for-11G-PHYs.patch deleted file mode 100644 index 9b2dc977e9..0000000000 --- a/target/linux/lantiq/patches-3.6/0105-MIPS-lantiq-xway-adds-reset-code-for-11G-PHYs.patch +++ /dev/null @@ -1,210 +0,0 @@ -From 4ed46c23c7257e15a419eb3176375601b312c157 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 22 Oct 2012 09:47:09 +0200 -Subject: [PATCH 105/113] MIPS: lantiq: xway: adds reset code for 11G PHYs - -Signed-off-by: John Crispin ---- - arch/mips/a | 42 +++++++++++++ - arch/mips/b | 36 +++++++++++ - .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 3 + - arch/mips/lantiq/xway/reset.c | 63 +++++++++++++++++++- - 4 files changed, 142 insertions(+), 2 deletions(-) - create mode 100644 arch/mips/a - create mode 100644 arch/mips/b - -diff --git a/arch/mips/a b/arch/mips/a -new file mode 100644 -index 0000000..31e61f8 ---- /dev/null -+++ b/arch/mips/a -@@ -0,0 +1,42 @@ -+diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -+index 6a2df70..056df1a 100644 -+--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -++++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -+@@ -87,5 +87,8 @@ extern __iomem void *ltq_cgu_membase; -+ extern void ltq_pmu_enable(unsigned int module); -+ extern void ltq_pmu_disable(unsigned int module); -+ -++/* allow drivers to reset clock domains and ip cores */ -++void ltq_reset_once(unsigned int module, ulong u); -++ -+ #endif /* CONFIG_SOC_TYPE_XWAY */ -+ #endif /* _LTQ_XWAY_H__ */ -+diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c -+index 22c55f7..c2a7e65 100644 -+--- a/arch/mips/lantiq/xway/reset.c -++++ b/arch/mips/lantiq/xway/reset.c -+@@ -55,13 +62,23 @@ unsigned char ltq_boot_select(void) -+ return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK; -+ } -+ -++static void ltq_reset_enter(unsigned int module) -++{ -++ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ); -++} -++ -++static void ltq_reset_leave(unsigned int module) -++{ -++ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); -++} -++ -+ /* reset a io domain for u micro seconds */ -+ void ltq_reset_once(unsigned int module, ulong u) -+ { -+- ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ); -++ ltq_reset_enter(RCU_RST_REQ); -+ udelay(u); -+- ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); -++ ltq_reset_leave(RCU_RST_REQ); -+ } -+ -+ static void ltq_machine_restart(char *command) -diff --git a/arch/mips/b b/arch/mips/b -new file mode 100644 -index 0000000..c6a0323 ---- /dev/null -+++ b/arch/mips/b -@@ -0,0 +1,36 @@ -+diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -+index 6a2df70..056df1a 100644 -+--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -++++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -+@@ -87,8 +87,11 @@ extern __iomem void *ltq_cgu_membase; -+ extern void ltq_pmu_enable(unsigned int module); -+ extern void ltq_pmu_disable(unsigned int module); -+ -++/* allow booting xrx200 phys */ -++int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr); -++ -+ #endif /* CONFIG_SOC_TYPE_XWAY */ -+ #endif /* _LTQ_XWAY_H__ */ -+diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c -+index 22c55f7..c2a7e65 100644 -+--- a/arch/mips/lantiq/xway/reset.c -++++ b/arch/mips/lantiq/xway/reset.c -+@@ -26,11 +26,18 @@ -+ -+ /* reset request register */ -+ #define RCU_RST_REQ 0x0010 -++ -++#define VR9_RCU_GFS_ADD0 0x0020 -++#define VR9_RCU_GFS_ADD1 0x0068 -++ -+ /* reset status register */ -+ #define RCU_RST_STAT 0x0014 -+ -+ /* reboot bit */ -++#define VR9_RCU_RD_GPHY0 BIT(31) -+ #define RCU_RD_SRST BIT(30) -++#define VR9_RCU_RD_GPHY1 BIT(29) -++ -+ /* reset cause */ -+ #define RCU_STAT_SHIFT 26 -+ /* boot selection */ -diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -index 6b9f5be..056df1a 100644 ---- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -@@ -90,5 +90,8 @@ extern void ltq_pmu_disable(unsigned int module); - /* allow drivers to reset clock domains and ip cores */ - void ltq_reset_once(unsigned int module, ulong u); - -+/* allow booting xrx200 phys */ -+int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr); -+ - #endif /* CONFIG_SOC_TYPE_XWAY */ - #endif /* _LTQ_XWAY_H__ */ -diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c -index 1b77f82..56293cf 100644 ---- a/arch/mips/lantiq/xway/reset.c -+++ b/arch/mips/lantiq/xway/reset.c -@@ -28,9 +28,15 @@ - #define RCU_RST_REQ 0x0010 - /* reset status register */ - #define RCU_RST_STAT 0x0014 -+/* vr9 gphy registers */ -+#define VR9_RCU_GFS_ADD0 0x0020 -+#define VR9_RCU_GFS_ADD1 0x0068 - - /* reboot bit */ -+#define VR9_RCU_RD_GPHY0 BIT(31) - #define RCU_RD_SRST BIT(30) -+#define VR9_RCU_RD_GPHY1 BIT(29) -+ - /* reset cause */ - #define RCU_STAT_SHIFT 26 - /* boot selection */ -@@ -65,13 +71,66 @@ static void ltq_reset_leave(unsigned int module) - ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); - } - -+/* reset / boot a gphy */ -+static struct ltq_xrx200_gphy_reset { -+ u32 rd; -+ u32 addr; -+} xrx200_gphy[] = { -+ {VR9_RCU_RD_GPHY0, VR9_RCU_GFS_ADD0}, -+ {VR9_RCU_RD_GPHY1, VR9_RCU_GFS_ADD1}, -+}; -+ -+/* reset and boot a gphy. these phys only exist on xrx200 SoC */ -+int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr) -+{ -+ if (id > 1) { -+ dev_err(dev, "%u is an invalid gphy id\n", id); -+ return -EINVAL; -+ } -+ dev_info(dev, "booting GPHY%u firmware at %X\n", id, dev_addr); -+ -+ ltq_reset_enter(xrx200_gphy[id].rd); -+ ltq_rcu_w32(dev_addr, xrx200_gphy[id].addr); -+ ltq_reset_leave(xrx200_gphy[id].rd); -+ return 0; -+} -+EXPORT_SYMBOL_GPL(xrx200_gphy_boot); -+ - /* reset a io domain for u micro seconds */ - void ltq_reset_once(unsigned int module, ulong u) - { -- ltq_reset_enter(RCU_RST_REQ); -+ ltq_reset_enter(module); - udelay(u); -- ltq_reset_leave(RCU_RST_REQ); -+ ltq_reset_leave(module); -+} -+ -+int ifx_rcu_rst(unsigned int reset_domain_id, unsigned int module_id) -+{ -+ ltq_reset_once(BIT(module_id), 20); -+ return 0; -+} -+EXPORT_SYMBOL(ifx_rcu_rst); -+ -+unsigned int ifx_rcu_rst_req_read(void) -+{ -+ unsigned int ret; -+ -+ ret = ltq_rcu_r32(RCU_RST_REQ); -+ -+ return ret; -+} -+EXPORT_SYMBOL(ifx_rcu_rst_req_read); -+ -+void ifx_rcu_rst_req_write(unsigned int value, unsigned int mask) -+{ -+ unsigned int ret; -+ -+ ret = ltq_rcu_r32(RCU_RST_REQ); -+ ret &= ~mask; -+ ret |= value & mask; -+ ltq_rcu_w32(ret, RCU_RST_REQ); - } -+EXPORT_SYMBOL(ifx_rcu_rst_req_write); - - static void ltq_machine_restart(char *command) - { --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0106-MIPS-lantiq-xway-adds-PHY11G-platform-code.patch b/target/linux/lantiq/patches-3.6/0106-MIPS-lantiq-xway-adds-PHY11G-platform-code.patch deleted file mode 100644 index b6108c1c45..0000000000 --- a/target/linux/lantiq/patches-3.6/0106-MIPS-lantiq-xway-adds-PHY11G-platform-code.patch +++ /dev/null @@ -1,607 +0,0 @@ -From b2ea96b934fcf665b4c0cc844416a7a2618e198e Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 22 Oct 2012 09:52:50 +0200 -Subject: [PATCH 106/113] MIPS: lantiq: xway: adds PHY11G platform code - -Signed-off-by: John Crispin ---- - arch/mips/lantiq/xway/Makefile | 2 +- - arch/mips/lantiq/xway/vr9_switch_regs.h | 425 +++++++++++++++++++++++++++++++ - arch/mips/lantiq/xway/xway_phy_fw.c | 146 +++++++++++ - 3 files changed, 572 insertions(+), 1 deletion(-) - create mode 100644 arch/mips/lantiq/xway/vr9_switch_regs.h - create mode 100644 arch/mips/lantiq/xway/xway_phy_fw.c - -diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile -index 70a58c7..1998b7c 100644 ---- a/arch/mips/lantiq/xway/Makefile -+++ b/arch/mips/lantiq/xway/Makefile -@@ -1 +1 @@ --obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o -+obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o xway_phy_fw.o -diff --git a/arch/mips/lantiq/xway/vr9_switch_regs.h b/arch/mips/lantiq/xway/vr9_switch_regs.h -new file mode 100644 -index 0000000..339e4c1 ---- /dev/null -+++ b/arch/mips/lantiq/xway/vr9_switch_regs.h -@@ -0,0 +1,425 @@ -+/* -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * Copyright (C) 2012 Daniel Schwierzeck -+ */ -+ -+#ifndef __VR9_SWITCH_REGS_H__ -+#define __VR9_SWITCH_REGS_H__ -+ -+/* Switch core registers */ -+struct vr9_switch_core_regs { -+ __be32 swres; -+ /* TODO: implement registers */ -+ __be32 rsvd0[0x3f]; -+}; -+ -+/* Switch buffer management registers */ -+struct vr9_switch_bm_regs { -+ struct bm_core { -+ __be32 ram_val3; /* RAM value 3 */ -+ __be32 ram_val2; /* RAM value 2 */ -+ __be32 ram_val1; /* RAM value 1 */ -+ __be32 ram_val0; /* RAM value 0 */ -+ __be32 ram_addr; /* RAM address */ -+ __be32 ram_ctrl; /* RAM access control */ -+ __be32 fsqm_gctrl; /* Free segment queue global control */ -+ __be32 cons_sel; /* Number of consumed segments */ -+ __be32 cons_pkt; /* Number of consumed packet pointers */ -+ __be32 gctrl; /* Global control */ -+ __be32 queue_gctrl; /* Queue manager global control */ -+ /* TODO: implement registers */ -+ __be32 rsvd0[0x35]; -+ } core; -+ -+ struct bm_port { -+ __be32 pcfg; /* Port config */ -+ __be32 rmon_ctrl; /* RMON control */ -+ } port[13]; -+ -+ __be32 rsvd0[0x66]; -+ -+ struct bm_queue { -+ __be32 rsvd0; -+ __be32 pqm_rs; /* Packet queue manager rate shape assignment */ -+ } queue[32]; -+ -+ struct bm_shaper { -+ __be32 ctrl; /* Rate shaper control */ -+ __be32 cbs; /* Rate shaper committed burst size */ -+ __be32 ibs; /* Rate shaper instantaneous burst size */ -+ __be32 cir_ext; /* Rate shaper rate exponent */ -+ __be32 cir_mant; /* Rate shaper rate mantissa */ -+ } shaper[16]; -+ -+ __be32 rsvd1[0x2a8]; -+}; -+ -+/* Switch parser and classification engine registers */ -+struct vr9_switch_pce_regs { -+ struct pce_core { -+ __be32 tbl_key[16]; /* Table key data */ -+ __be32 tbl_mask; /* Table mask */ -+ __be32 tbl_val[5]; /* Table value */ -+ __be32 tbl_addr; /* Table entry address */ -+ __be32 tbl_ctrl; /* Table access control */ -+ __be32 tbl_stat; /* Table general status */ -+ __be32 age_0; /* Aging counter config 0 */ -+ __be32 age_1; /* Aging counter config 1 */ -+ __be32 pmap_1; /* Port map (monitoring) */ -+ __be32 pmap_2; /* Port map (multicast) */ -+ __be32 pmap_3; /* Port map (unknown unicast) */ -+ __be32 gctrl_0; /* Global control 0 */ -+ __be32 gctrl_1; /* Global control 1 */ -+ __be32 tcm_gctrl; /* Three-color marker global control */ -+ __be32 igmp_ctrl; /* IGMP control */ -+ __be32 igmp_drpm; /* IGMP default router port map */ -+ __be32 igmp_age_0; /* IGMP aging 0 */ -+ __be32 igmp_age_1; /* IGMP aging 1 */ -+ __be32 igmp_stat; /* IGMP status */ -+ __be32 wol_gctrl; /* Wake-on-LAN control */ -+ __be32 wol_da_0; /* Wake-on-LAN destination address 0 */ -+ __be32 wol_da_1; /* Wake-on-LAN destination address 1 */ -+ __be32 wol_da_2; /* Wake-on-LAN destination address 2 */ -+ __be32 wol_pw_0; /* Wake-on-LAN password 0 */ -+ __be32 wol_pw_1; /* Wake-on-LAN password 1 */ -+ __be32 wol_pw_2; /* Wake-on-LAN password 2 */ -+ __be32 ier_0; /* PCE global interrupt enable 0 */ -+ __be32 ier_1; /* PCE global interrupt enable 1 */ -+ __be32 isr_0; /* PCE global interrupt status 0 */ -+ __be32 isr_1; /* PCE global interrupt status 1 */ -+ __be32 parser_stat; /* Parser status */ -+ __be32 rsvd0[0x6]; -+ } core; -+ -+ __be32 rsvd0[0x10]; -+ -+ struct pce_port { -+ __be32 pctrl_0; /* Port control 0 */ -+ __be32 pctrl_1; /* Port control 1 */ -+ __be32 pctrl_2; /* Port control 2 */ -+ __be32 pctrl_3; /* Port control 3 */ -+ __be32 wol_ctrl; /* Wake-on-LAN control */ -+ __be32 vlan_ctrl; /* VLAN control */ -+ __be32 def_pvid; /* Default port VID */ -+ __be32 pstat; /* Port status */ -+ __be32 pier; /* Interrupt enable */ -+ __be32 pisr; /* Interrupt status */ -+ } port[13]; -+ -+ __be32 rsvd1[0x7e]; -+ -+ struct pce_meter { -+ /* TODO: implement registers */ -+ __be32 rsvd0[0x7]; -+ } meter[8]; -+ -+ __be32 rsvd2[0x308]; -+}; -+ -+static inline unsigned int to_pce_tbl_key_id(unsigned int id) -+{ -+ return 15 - id; -+} -+ -+static inline unsigned int to_pce_tbl_value_id(unsigned int id) -+{ -+ return 4 - id; -+} -+ -+/* Switch ethernet MAC registers */ -+struct vr9_switch_mac_regs { -+ struct mac_core { -+ __be32 test; /* MAC test */ -+ __be32 pfad_cfg; /* Pause frame source address config */ -+ __be32 pfsa_0; /* Pause frame source address 0 */ -+ __be32 pfsa_1; /* Pause frame source address 1 */ -+ __be32 pfsa_2; /* Pause frame source address 2 */ -+ __be32 flen; /* Frame length */ -+ __be32 vlan_etype_0; /* VLAN ethertype 0 */ -+ __be32 vlan_etype_1; /* VLAN ethertype 1 */ -+ __be32 ier; /* Interrupt enable */ -+ __be32 isr; /* Interrupt status */ -+ __be32 rsvd0[0x36]; -+ } core; -+ -+ struct mac_port { -+ __be32 pstat; /* Port status */ -+ __be32 pisr; /* Interrupt status */ -+ __be32 pier; /* Interrupt enable */ -+ __be32 ctrl_0; /* Control 0 */ -+ __be32 ctrl_1; /* Control 1 */ -+ __be32 ctrl_2; /* Control 2 */ -+ __be32 ctrl_3; /* Control 3 */ -+ __be32 ctrl_4; /* Control 4 */ -+ __be32 ctrl_5; /* Control 5 */ -+ __be32 rsvd0[0x2]; -+ __be32 testen; /* Test enable */ -+ } port[13]; -+ -+ __be32 rsvd0[0xa4]; -+}; -+ -+/* Switch Fetch DMA registers */ -+struct vr9_switch_fdma_regs { -+ struct fdma_core { -+ __be32 ctrl; /* FDMA control */ -+ __be32 stetype; /* Special tag ethertype control */ -+ __be32 vtetype; /* VLAN tag ethertype control */ -+ __be32 stat; /* FDMA status */ -+ __be32 ier; /* FDMA interrupt enable */ -+ __be32 isr; /* FDMA interrupt status */ -+ } core; -+ -+ __be32 rsvd0[0x3a]; -+ -+ struct fdma_port { -+ __be32 pctrl; /* Port control */ -+ __be32 prio; /* Port priority */ -+ __be32 pstat_0; /* Port status 0 */ -+ __be32 pstat_1; /* Port status 1 */ -+ __be32 tstamp_0; /* Egress time stamp 0 */ -+ __be32 tstamp_1; /* Egress time stamp 1 */ -+ } port[13]; -+ -+ __be32 rsvd1[0x72]; -+}; -+ -+/* Switch Store DMA registers */ -+struct vr9_switch_sdma_regs { -+ struct sdma_core { -+ __be32 ctrl; /* SDMA Control */ -+ __be32 fcthr_1; /* Flow control threshold 1 */ -+ __be32 rsvd0; -+ __be32 fcthr_3; /* Flow control threshold 3 */ -+ __be32 fcthr_4; /* Flow control threshold 4 */ -+ __be32 fcthr_5; /* Flow control threshold 5 */ -+ __be32 fcthr_6; /* Flow control threshold 6 */ -+ __be32 fcthr_7; /* Flow control threshold 7 */ -+ __be32 stat_0; /* SDMA status 0 */ -+ __be32 stat_1; /* SDMA status 1 */ -+ __be32 stat_2; /* SDMA status 2 */ -+ __be32 ier; /* SDMA interrupt enable */ -+ __be32 isr; /* SDMA interrupt status */ -+ } core; -+ -+ __be32 rsvd0[0x73]; -+ -+ struct sdma_port { -+ __be32 pctrl; /* Port control */ -+ __be32 prio; /* Port priority */ -+ __be32 pstat_0; /* Port status 0 */ -+ __be32 pstat_1; /* Port status 1 */ -+ __be32 tstamp_0; /* Ingress time stamp 0 */ -+ __be32 tstamp_1; /* Ingress time stamp 1 */ -+ } port[13]; -+ -+ __be32 rsvd1[0x32]; -+}; -+ -+/* Switch MDIO control and status registers */ -+struct vr9_switch_mdio_regs { -+ __be32 glob_ctrl; /* Global control 0 */ -+ __be32 rsvd0[7]; -+ __be32 mdio_ctrl; /* MDIO control */ -+ __be32 mdio_read; /* MDIO read data */ -+ __be32 mdio_write; /* MDIO write data */ -+ __be32 mdc_cfg_0; /* MDC clock configuration 0 */ -+ __be32 mdc_cfg_1; /* MDC clock configuration 1 */ -+ __be32 rsvd1[0x3]; -+ __be32 phy_addr[6]; /* PHY address port 5..0 */ -+ __be32 mdio_stat[6]; /* MDIO PHY polling status port 0..5 */ -+ __be32 aneg_eee[6]; /* EEE auto-neg overrides port 0..5 */ -+ __be32 rsvd2[0x14]; -+}; -+ -+static inline unsigned int to_mdio_phyaddr_id(unsigned int id) -+{ -+ return 5 - id; -+} -+ -+/* Switch xMII control registers */ -+struct vr9_switch_mii_regs { -+ __be32 mii_cfg0; /* xMII port 0 configuration */ -+ __be32 pcdu0; /* Port 0 clock delay configuration */ -+ __be32 mii_cfg1; /* xMII port 1 configuration */ -+ __be32 pcdu1; /* Port 1 clock delay configuration */ -+ __be32 rsvd0[0x6]; -+ __be32 mii_cfg5; /* xMII port 5 configuration */ -+ __be32 pcdu5; /* Port 5 clock delay configuration */ -+ __be32 rsvd1[0x14]; -+ __be32 rxb_ctl_0; /* Port 0 receive buffer control */ -+ __be32 rxb_ctl_1; /* Port 1 receive buffer control */ -+ __be32 rxb_ctl_5; /* Port 5 receive buffer control */ -+ __be32 rsvd2[0x28]; -+ __be32 dbg_ctl; /* Debug control */ -+}; -+ -+/* Switch Pseudo-MAC registers */ -+struct vr9_switch_pmac_regs { -+ __be32 hd_ctl; /* PMAC header control */ -+ __be32 tl; /* PMAC type/length */ -+ __be32 sa1; /* PMAC source address 1 */ -+ __be32 sa2; /* PMAC source address 2 */ -+ __be32 sa3; /* PMAC source address 3 */ -+ __be32 da1; /* PMAC destination address 1 */ -+ __be32 da2; /* PMAC destination address 2 */ -+ __be32 da3; /* PMAC destination address 3 */ -+ __be32 vlan; /* PMAC VLAN */ -+ __be32 rx_ipg; /* PMAC interpacket gap in RX direction */ -+ __be32 st_etype; /* PMAC special tag ethertype */ -+ __be32 ewan; /* PMAC ethernet WAN group */ -+ __be32 ctl; /* PMAC control */ -+ __be32 rsvd0[0x2]; -+}; -+ -+struct vr9_switch_regs { -+ struct vr9_switch_core_regs core; -+ struct vr9_switch_bm_regs bm; -+ struct vr9_switch_pce_regs pce; -+ struct vr9_switch_mac_regs mac; -+ struct vr9_switch_fdma_regs fdma; -+ struct vr9_switch_sdma_regs sdma; -+ struct vr9_switch_mdio_regs mdio; -+ struct vr9_switch_mii_regs mii; -+ struct vr9_switch_pmac_regs pmac; -+}; -+ -+#define VR9_SWITCH_REG_OFFSET(reg) (4 * (reg)) -+ -+#define BUILD_CHECK_VR9_REG(name, offset) \ -+ BUILD_BUG_ON(offsetof(struct vr9_switch_regs, name) != (4 * offset)) -+ -+static inline void build_check_vr9_registers(void) -+{ -+ BUILD_CHECK_VR9_REG(core, 0x0); -+ BUILD_CHECK_VR9_REG(bm.core, 0x40); -+ BUILD_CHECK_VR9_REG(bm.core.queue_gctrl, 0x4a); -+ BUILD_CHECK_VR9_REG(bm.port[0], 0x80); -+ BUILD_CHECK_VR9_REG(bm.queue, 0x100); -+ BUILD_CHECK_VR9_REG(bm.shaper, 0x140); -+ BUILD_CHECK_VR9_REG(pce.core, 0x438); -+ BUILD_CHECK_VR9_REG(pce.core.tbl_ctrl, 0x44f); -+ BUILD_CHECK_VR9_REG(pce.core.parser_stat, 0x469); -+ BUILD_CHECK_VR9_REG(pce.port[0], 0x480); -+ BUILD_CHECK_VR9_REG(pce.meter[0], 0x580); -+ BUILD_CHECK_VR9_REG(mac.core, 0x8c0); -+ BUILD_CHECK_VR9_REG(mac.port[0].pstat, 0x900); -+ BUILD_CHECK_VR9_REG(mac.port[0].ctrl_0, 0x903); -+ BUILD_CHECK_VR9_REG(mac.port[1].pstat, 0x90c); -+ BUILD_CHECK_VR9_REG(mac.port[1].ctrl_0, 0x90f); -+ BUILD_CHECK_VR9_REG(mac.port[2].pstat, 0x918); -+ BUILD_CHECK_VR9_REG(mac.port[2].ctrl_0, 0x91b); -+ BUILD_CHECK_VR9_REG(fdma.core, 0xa40); -+ BUILD_CHECK_VR9_REG(fdma.port[0], 0xa80); -+ BUILD_CHECK_VR9_REG(sdma.core, 0xb40); -+ BUILD_CHECK_VR9_REG(sdma.port[0], 0xbc0); -+ BUILD_CHECK_VR9_REG(mdio, 0xc40); -+ BUILD_CHECK_VR9_REG(mii, (0xc40 + 0x36)); -+ BUILD_CHECK_VR9_REG(pmac, (0xc40 + 0x82)); -+} -+ -+#define MAC_CTRL0_BM BIT(12) -+#define MAC_CTRL0_APADEN BIT(11) -+#define MAC_CTRL0_VPAD2EN BIT(10) -+#define MAC_CTRL0_VPADEN BIT(9) -+#define MAC_CTRL0_PADEN BIT(8) -+#define MAC_CTRL0_FCS BIT(7) -+#define MAC_CTRL0_FCON_SHIFT 4 -+#define MAC_CTRL0_FCON_AUTO (0x0 << MAC_CTRL0_FCON_SHIFT) -+#define MAC_CTRL0_FCON_RX (0x1 << MAC_CTRL0_FCON_SHIFT) -+#define MAC_CTRL0_FCON_TX (0x2 << MAC_CTRL0_FCON_SHIFT) -+#define MAC_CTRL0_FCON_RXTX (0x3 << MAC_CTRL0_FCON_SHIFT) -+#define MAC_CTRL0_FCON_NONE (0x4 << MAC_CTRL0_FCON_SHIFT) -+#define MAC_CTRL0_FDUP_SHIFT 2 -+#define MAC_CTRL0_FDUP_AUTO (0x0 << MAC_CTRL0_FDUP_SHIFT) -+#define MAC_CTRL0_FDUP_EN (0x1 << MAC_CTRL0_FDUP_SHIFT) -+#define MAC_CTRL0_FDUP_DIS (0x3 << MAC_CTRL0_FDUP_SHIFT) -+#define MAC_CTRL0_GMII_AUTO 0x0 -+#define MAC_CTRL0_GMII_MII 0x1 -+#define MAC_CTRL0_GMII_GMII 0x2 -+#define MAC_CTRL0_GMII_GMII_2G 0x3 -+ -+#define MAC_CTRL1_DEFERMODE BIT(15) -+#define MAC_CTRL1_SHORTPRE BIT(8) -+ -+#define MAC_CTRL2_MLEN BIT(3) -+#define MAC_CTRL2_LCHKL BIT(2) -+#define MAC_CTRL2_LCHKS_DIS 0x0 -+#define MAC_CTRL2_LCHKS_UNTAG 0x1 -+#define MAC_CTRL2_LCHKS_TAG 0x2 -+ -+#define PHY_ADDR_LNKST_SHIFT 13 -+#define PHY_ADDR_LNKST_AUTO (0x0 << PHY_ADDR_LNKST_SHIFT) -+#define PHY_ADDR_LNKST_UP (0x1 << PHY_ADDR_LNKST_SHIFT) -+#define PHY_ADDR_LNKST_DOWN (0x2 << PHY_ADDR_LNKST_SHIFT) -+#define PHY_ADDR_SPEED_SHIFT 11 -+#define PHY_ADDR_SPEED_M10 (0x0 << PHY_ADDR_SPEED_SHIFT) -+#define PHY_ADDR_SPEED_M100 (0x1 << PHY_ADDR_SPEED_SHIFT) -+#define PHY_ADDR_SPEED_G1 (0x2 << PHY_ADDR_SPEED_SHIFT) -+#define PHY_ADDR_SPEED_AUTO (0x3 << PHY_ADDR_SPEED_SHIFT) -+#define PHY_ADDR_FDUP_SHIFT 9 -+#define PHY_ADDR_FDUP_AUTO (0x0 << PHY_ADDR_FDUP_SHIFT) -+#define PHY_ADDR_FDUP_EN (0x1 << PHY_ADDR_FDUP_SHIFT) -+#define PHY_ADDR_FDUP_DIS (0x3 << PHY_ADDR_FDUP_SHIFT) -+#define PHY_ADDR_FCONTX_SHIFT 7 -+#define PHY_ADDR_FCONTX_AUTO (0x0 << PHY_ADDR_FCONTX_SHIFT) -+#define PHY_ADDR_FCONTX_EN (0x1 << PHY_ADDR_FCONTX_SHIFT) -+#define PHY_ADDR_FCONTX_DIS (0x3 << PHY_ADDR_FCONTX_SHIFT) -+#define PHY_ADDR_FCONRX_SHIFT 5 -+#define PHY_ADDR_FCONRX_AUTO (0x0 << PHY_ADDR_FCONRX_SHIFT) -+#define PHY_ADDR_FCONRX_EN (0x1 << PHY_ADDR_FCONRX_SHIFT) -+#define PHY_ADDR_FCONRX_DIS (0x3 << PHY_ADDR_FCONRX_SHIFT) -+ -+#define MII_CFG_RES BIT(15) -+#define MII_CFG_EN BIT(14) -+#define MII_CFG_LDCLKDIS BIT(12) -+#define MII_CFG_MIIRATE_SHIFT 4 -+#define MII_CFG_MIIRATE_MASK (0x7 << MII_CFG_MIIRATE_SHIFT) -+#define MII_CFG_MIIRATE_M2P5 (0x0 << MII_CFG_MIIRATE_SHIFT) -+#define MII_CFG_MIIRATE_M25 (0x1 << MII_CFG_MIIRATE_SHIFT) -+#define MII_CFG_MIIRATE_M125 (0x2 << MII_CFG_MIIRATE_SHIFT) -+#define MII_CFG_MIIRATE_M50 (0x3 << MII_CFG_MIIRATE_SHIFT) -+#define MII_CFG_MIIRATE_AUTO (0x4 << MII_CFG_MIIRATE_SHIFT) -+#define MII_CFG_MIIMODE_MASK 0xf -+#define MII_CFG_MIIMODE_MIIP 0x0 -+#define MII_CFG_MIIMODE_MIIM 0x1 -+#define MII_CFG_MIIMODE_RMIIP 0x2 -+#define MII_CFG_MIIMODE_RMIIM 0x3 -+#define MII_CFG_MIIMODE_RGMII 0x4 -+ -+#define PMAC_HD_CTL_FC BIT(10) -+#define PMAC_HD_CTL_RST BIT(8) -+#define PMAC_HD_CTL_AST BIT(7) -+#define PMAC_HD_CTL_RXSH BIT(6) -+#define PMAC_HD_CTL_RC BIT(4) -+#define PMAC_HD_CTL_AS BIT(3) -+#define PMAC_HD_CTL_AC BIT(2) -+ -+#define PCE_PCTRL_0_IGSTEN BIT(11) -+ -+#define FDMA_PCTRL_STEN BIT(1) -+#define FDMA_PCTRL_EN BIT(0) -+ -+#define SDMA_PCTRL_EN BIT(0) -+ -+#define MDIO_CTRL_MBUSY BIT(12) -+#define MDIO_CTRL_OP_READ BIT(11) -+#define MDIO_CTRL_OP_WRITE BIT(10) -+#define MDIO_CTRL_PHYAD_SHIFT 5 -+#define MDIO_CTRL_PHYAD_MASK (0x1f << MDIO_CTRL_PHYAD_SHIFT) -+#define MDIO_CTRL_REGAD_MASK 0x1f -+ -+#endif /* __VR9_SWITCH_REGS_H__ */ -diff --git a/arch/mips/lantiq/xway/xway_phy_fw.c b/arch/mips/lantiq/xway/xway_phy_fw.c -new file mode 100644 -index 0000000..97a6d22 ---- /dev/null -+++ b/arch/mips/lantiq/xway/xway_phy_fw.c -@@ -0,0 +1,146 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+ -+#include "vr9_switch_regs.h" -+ -+#define XWAY_GPHY_FW_ALIGN (16 * 1024) -+#define XWAY_GPHY_FW_NAME_SIZE 32 -+ -+struct xway_gphy_core { -+ struct device *dev; -+ char fw_name[XWAY_GPHY_FW_NAME_SIZE]; -+ dma_addr_t dev_addr; -+ void *fw_addr; -+ size_t fw_size; -+}; -+ -+static int xway_gphy_load(struct platform_device *pdev, struct xway_gphy_core *gphy) -+{ -+ const struct firmware *fw; -+ dma_addr_t dev_addr; -+ void *fw_addr; -+ int err; -+ size_t size; -+ const char *fw_name; -+ -+ err = of_property_read_string(pdev->dev.of_node, "firmware", &fw_name); -+ if (err) { -+ dev_err(&pdev->dev, "failed to load firmware filename\n"); -+ return err; -+ } -+ -+ if (strlen(fw_name) >= sizeof(gphy->fw_name)) { -+ dev_err(&pdev->dev, "firmware filename too long\n"); -+ return ENAMETOOLONG; -+ } -+ -+ strncpy(gphy->fw_name, fw_name, sizeof(gphy->fw_name)); -+ -+ dev_info(&pdev->dev, "requesting %s\n", gphy->fw_name); -+ err = request_firmware(&fw, gphy->fw_name, &pdev->dev); -+ if (err) { -+ dev_err(&pdev->dev, "failed to load firmware: %s\n", gphy->fw_name); -+ return err; -+ } -+ -+ /* -+ * GPHY cores need the firmware code in a persistent and contiguous -+ * memory area with a 16 kB boundary aligned start address -+ */ -+ size = fw->size + XWAY_GPHY_FW_ALIGN; -+ fw_addr = dma_alloc_coherent(&pdev->dev, size, &dev_addr, GFP_KERNEL); -+ if (!fw_addr) { -+ dev_err(&pdev->dev, "failed to alloc firmware memory\n"); -+ goto err_release; -+ } -+ -+ fw_addr = PTR_ALIGN(fw_addr, XWAY_GPHY_FW_ALIGN); -+ dev_addr = ALIGN(dev_addr, XWAY_GPHY_FW_ALIGN); -+ -+ memcpy(fw_addr, fw->data, fw->size); -+ release_firmware(fw); -+ -+ gphy->dev = &pdev->dev; -+ gphy->dev_addr = dev_addr; -+ gphy->fw_addr = fw_addr; -+ gphy->fw_size = size; -+ -+ return 0; -+ -+err_release: -+ release_firmware(fw); -+ -+ return err; -+} -+ -+static int __devinit xway_phy_fw_probe(struct platform_device *pdev) -+{ -+ struct xway_gphy_core gphy; -+ struct property *pp; -+ unsigned char *phyids; -+ int i, ret; -+ -+ ret = xway_gphy_load(pdev, &gphy); -+ if (ret) -+ return ret; -+ pp = of_find_property(pdev->dev.of_node, "phys", NULL); -+ if (!pp) -+ return -ENOENT; -+ phyids = pp->value; -+ for (i = 0; i < pp->length && !ret; i++) -+ ret = xrx200_gphy_boot(&pdev->dev, phyids[i], gphy.dev_addr); -+ if (!ret) -+ mdelay(100); -+ return ret; -+} -+ -+static const struct of_device_id xway_phy_match[] = { -+ { .compatible = "lantiq,phy-xrx200" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, xway_phy_match); -+ -+static struct platform_driver xway_phy_driver = { -+ .probe = xway_phy_fw_probe, -+ .driver = { -+ .name = "phy-xrx200", -+ .owner = THIS_MODULE, -+ .of_match_table = xway_phy_match, -+ }, -+}; -+ -+module_platform_driver(xway_phy_driver); -+ -+MODULE_AUTHOR("John Crispin "); -+MODULE_DESCRIPTION("Lantiq XRX200 PHY Firmware Loader"); -+MODULE_LICENSE("GPL"); -+ --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0107-MIPS-lantiq-add-xrx200-ethernet-clock.patch b/target/linux/lantiq/patches-3.6/0107-MIPS-lantiq-add-xrx200-ethernet-clock.patch deleted file mode 100644 index e941ee3db6..0000000000 --- a/target/linux/lantiq/patches-3.6/0107-MIPS-lantiq-add-xrx200-ethernet-clock.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 00b0721cce51988b6dda27b21afb0e09c620bc21 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sat, 27 Oct 2012 09:14:17 +0200 -Subject: [PATCH 107/113] MIPS: lantiq: add xrx200 ethernet clock - -Signed-off-by: John Crispin ---- - arch/mips/lantiq/xway/sysctrl.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c -index 2917b56..3925e66 100644 ---- a/arch/mips/lantiq/xway/sysctrl.c -+++ b/arch/mips/lantiq/xway/sysctrl.c -@@ -370,6 +370,10 @@ void __init ltq_soc_init(void) - clkdev_add_pmu("1d900000.pcie", "pdi", 1, PMU1_PCIE_PDI); - clkdev_add_pmu("1d900000.pcie", "ctl", 1, PMU1_PCIE_CTL); - clkdev_add_pmu("1d900000.pcie", "ahb", 0, PMU_AHBM | PMU_AHBS); -+ clkdev_add_pmu("1e108000.eth", NULL, 0, -+ PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM | -+ PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 | -+ PMU_PPE_QSB | PMU_PPE_TOP); - } else if (of_machine_is_compatible("lantiq,ar9")) { - clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(), - ltq_ar9_fpi_hz()); --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0108-firmware-lantiq-adds-PHY11G-firmware-blobs.patch b/target/linux/lantiq/patches-3.6/0108-firmware-lantiq-adds-PHY11G-firmware-blobs.patch deleted file mode 100644 index 4ba49e4463..0000000000 --- a/target/linux/lantiq/patches-3.6/0108-firmware-lantiq-adds-PHY11G-firmware-blobs.patch +++ /dev/null @@ -1,2221 +0,0 @@ -From 817acb2b92075a3c1e6aed7972c32710cf3a10c3 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 22 Oct 2012 09:26:24 +0200 -Subject: [PATCH 108/113] firmware: lantiq: adds PHY11G firmware blobs - -Signed-off-by: John Crispin ---- - firmware/Makefile | 1 + - firmware/lantiq/COPYING | 286 ++++++++++++++++++++++++++++++++++++ - firmware/lantiq/README | 45 ++++++ - firmware/lantiq/vr9_phy11g_a1x.bin | Bin 0 -> 65536 bytes - firmware/lantiq/vr9_phy11g_a2x.bin | Bin 0 -> 65536 bytes - firmware/lantiq/vr9_phy22f_a1x.bin | Bin 0 -> 65536 bytes - firmware/lantiq/vr9_phy22f_a2x.bin | Bin 0 -> 65536 bytes - 7 files changed, 332 insertions(+) - create mode 100644 firmware/lantiq/COPYING - create mode 100644 firmware/lantiq/README - create mode 100644 firmware/lantiq/vr9_phy11g_a1x.bin - create mode 100644 firmware/lantiq/vr9_phy11g_a2x.bin - create mode 100644 firmware/lantiq/vr9_phy22f_a1x.bin - create mode 100644 firmware/lantiq/vr9_phy22f_a2x.bin - -diff --git a/firmware/Makefile b/firmware/Makefile -index eeb1403..4259bed 100644 ---- a/firmware/Makefile -+++ b/firmware/Makefile -@@ -135,6 +135,7 @@ fw-shipped-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda/keyspan_pda.fw - fw-shipped-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda/xircom_pgs.fw - fw-shipped-$(CONFIG_USB_VICAM) += vicam/firmware.fw - fw-shipped-$(CONFIG_VIDEO_CPIA2) += cpia2/stv0672_vp4.bin -+fw-shipped-$(CONFIG_SOC_TYPE_XWAY) += lantiq/vr9_phy11g_a2x.bin - fw-shipped-$(CONFIG_YAM) += yam/1200.bin yam/9600.bin - - fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) -diff --git a/firmware/lantiq/COPYING b/firmware/lantiq/COPYING -new file mode 100644 -index 0000000..5ec70b2 ---- /dev/null -+++ b/firmware/lantiq/COPYING -@@ -0,0 +1,286 @@ -+All firmware files are copyrighted by Lantiq Deutschland GmbH. -+The files have been extracted from header files found in Lantiq BSPs. -+If not stated otherwise all files are licensed under GPL. -+ -+======================================================================= -+ -+ GNU GENERAL PUBLIC LICENSE -+ Version 2, June 1991 -+ -+ Copyright (C) 1989, 1991 Free Software Foundation, Inc. -+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ Everyone is permitted to copy and distribute verbatim copies -+ of this license document, but changing it is not allowed. -+ -+ Preamble -+ -+ The licenses for most software are designed to take away your -+freedom to share and change it. By contrast, the GNU General Public -+License is intended to guarantee your freedom to share and change free -+software--to make sure the software is free for all its users. This -+General Public License applies to most of the Free Software -+Foundation's software and to any other program whose authors commit to -+using it. (Some other Free Software Foundation software is covered by -+the GNU Library General Public License instead.) You can apply it to -+your programs, too. -+ -+ When we speak of free software, we are referring to freedom, not -+price. Our General Public Licenses are designed to make sure that you -+have the freedom to distribute copies of free software (and charge for -+this service if you wish), that you receive source code or can get it -+if you want it, that you can change the software or use pieces of it -+in new free programs; and that you know you can do these things. -+ -+ To protect your rights, we need to make restrictions that forbid -+anyone to deny you these rights or to ask you to surrender the rights. -+These restrictions translate to certain responsibilities for you if you -+distribute copies of the software, or if you modify it. -+ -+ For example, if you distribute copies of such a program, whether -+gratis or for a fee, you must give the recipients all the rights that -+you have. You must make sure that they, too, receive or can get the -+source code. And you must show them these terms so they know their -+rights. -+ -+ We protect your rights with two steps: (1) copyright the software, and -+(2) offer you this license which gives you legal permission to copy, -+distribute and/or modify the software. -+ -+ Also, for each author's protection and ours, we want to make certain -+that everyone understands that there is no warranty for this free -+software. If the software is modified by someone else and passed on, we -+want its recipients to know that what they have is not the original, so -+that any problems introduced by others will not reflect on the original -+authors' reputations. -+ -+ Finally, any free program is threatened constantly by software -+patents. We wish to avoid the danger that redistributors of a free -+program will individually obtain patent licenses, in effect making the -+program proprietary. To prevent this, we have made it clear that any -+patent must be licensed for everyone's free use or not licensed at all. -+ -+ The precise terms and conditions for copying, distribution and -+modification follow. -+ -+ GNU GENERAL PUBLIC LICENSE -+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -+ -+ 0. This License applies to any program or other work which contains -+a notice placed by the copyright holder saying it may be distributed -+under the terms of this General Public License. The "Program", below, -+refers to any such program or work, and a "work based on the Program" -+means either the Program or any derivative work under copyright law: -+that is to say, a work containing the Program or a portion of it, -+either verbatim or with modifications and/or translated into another -+language. (Hereinafter, translation is included without limitation in -+the term "modification".) Each licensee is addressed as "you". -+ -+Activities other than copying, distribution and modification are not -+covered by this License; they are outside its scope. The act of -+running the Program is not restricted, and the output from the Program -+is covered only if its contents constitute a work based on the -+Program (independent of having been made by running the Program). -+Whether that is true depends on what the Program does. -+ -+ 1. You may copy and distribute verbatim copies of the Program's -+source code as you receive it, in any medium, provided that you -+conspicuously and appropriately publish on each copy an appropriate -+copyright notice and disclaimer of warranty; keep intact all the -+notices that refer to this License and to the absence of any warranty; -+and give any other recipients of the Program a copy of this License -+along with the Program. -+ -+You may charge a fee for the physical act of transferring a copy, and -+you may at your option offer warranty protection in exchange for a fee. -+ -+ 2. You may modify your copy or copies of the Program or any portion -+of it, thus forming a work based on the Program, and copy and -+distribute such modifications or work under the terms of Section 1 -+above, provided that you also meet all of these conditions: -+ -+ a) You must cause the modified files to carry prominent notices -+ stating that you changed the files and the date of any change. -+ -+ b) You must cause any work that you distribute or publish, that in -+ whole or in part contains or is derived from the Program or any -+ part thereof, to be licensed as a whole at no charge to all third -+ parties under the terms of this License. -+ -+ c) If the modified program normally reads commands interactively -+ when run, you must cause it, when started running for such -+ interactive use in the most ordinary way, to print or display an -+ announcement including an appropriate copyright notice and a -+ notice that there is no warranty (or else, saying that you provide -+ a warranty) and that users may redistribute the program under -+ these conditions, and telling the user how to view a copy of this -+ License. (Exception: if the Program itself is interactive but -+ does not normally print such an announcement, your work based on -+ the Program is not required to print an announcement.) -+ -+These requirements apply to the modified work as a whole. If -+identifiable sections of that work are not derived from the Program, -+and can be reasonably considered independent and separate works in -+themselves, then this License, and its terms, do not apply to those -+sections when you distribute them as separate works. But when you -+distribute the same sections as part of a whole which is a work based -+on the Program, the distribution of the whole must be on the terms of -+this License, whose permissions for other licensees extend to the -+entire whole, and thus to each and every part regardless of who wrote it. -+ -+Thus, it is not the intent of this section to claim rights or contest -+your rights to work written entirely by you; rather, the intent is to -+exercise the right to control the distribution of derivative or -+collective works based on the Program. -+ -+In addition, mere aggregation of another work not based on the Program -+with the Program (or with a work based on the Program) on a volume of -+a storage or distribution medium does not bring the other work under -+the scope of this License. -+ -+ 3. You may copy and distribute the Program (or a work based on it, -+under Section 2) in object code or executable form under the terms of -+Sections 1 and 2 above provided that you also do one of the following: -+ -+ a) Accompany it with the complete corresponding machine-readable -+ source code, which must be distributed under the terms of Sections -+ 1 and 2 above on a medium customarily used for software interchange; or, -+ -+ b) Accompany it with a written offer, valid for at least three -+ years, to give any third party, for a charge no more than your -+ cost of physically performing source distribution, a complete -+ machine-readable copy of the corresponding source code, to be -+ distributed under the terms of Sections 1 and 2 above on a medium -+ customarily used for software interchange; or, -+ -+ c) Accompany it with the information you received as to the offer -+ to distribute corresponding source code. (This alternative is -+ allowed only for noncommercial distribution and only if you -+ received the program in object code or executable form with such -+ an offer, in accord with Subsection b above.) -+ -+The source code for a work means the preferred form of the work for -+making modifications to it. For an executable work, complete source -+code means all the source code for all modules it contains, plus any -+associated interface definition files, plus the scripts used to -+control compilation and installation of the executable. However, as a -+special exception, the source code distributed need not include -+anything that is normally distributed (in either source or binary -+form) with the major components (compiler, kernel, and so on) of the -+operating system on which the executable runs, unless that component -+itself accompanies the executable. -+ -+If distribution of executable or object code is made by offering -+access to copy from a designated place, then offering equivalent -+access to copy the source code from the same place counts as -+distribution of the source code, even though third parties are not -+compelled to copy the source along with the object code. -+ -+ 4. You may not copy, modify, sublicense, or distribute the Program -+except as expressly provided under this License. Any attempt -+otherwise to copy, modify, sublicense or distribute the Program is -+void, and will automatically terminate your rights under this License. -+However, parties who have received copies, or rights, from you under -+this License will not have their licenses terminated so long as such -+parties remain in full compliance. -+ -+ 5. You are not required to accept this License, since you have not -+signed it. However, nothing else grants you permission to modify or -+distribute the Program or its derivative works. These actions are -+prohibited by law if you do not accept this License. Therefore, by -+modifying or distributing the Program (or any work based on the -+Program), you indicate your acceptance of this License to do so, and -+all its terms and conditions for copying, distributing or modifying -+the Program or works based on it. -+ -+ 6. Each time you redistribute the Program (or any work based on the -+Program), the recipient automatically receives a license from the -+original licensor to copy, distribute or modify the Program subject to -+these terms and conditions. You may not impose any further -+restrictions on the recipients' exercise of the rights granted herein. -+You are not responsible for enforcing compliance by third parties to -+this License. -+ -+ 7. If, as a consequence of a court judgment or allegation of patent -+infringement or for any other reason (not limited to patent issues), -+conditions are imposed on you (whether by court order, agreement or -+otherwise) that contradict the conditions of this License, they do not -+excuse you from the conditions of this License. If you cannot -+distribute so as to satisfy simultaneously your obligations under this -+License and any other pertinent obligations, then as a consequence you -+may not distribute the Program at all. For example, if a patent -+license would not permit royalty-free redistribution of the Program by -+all those who receive copies directly or indirectly through you, then -+the only way you could satisfy both it and this License would be to -+refrain entirely from distribution of the Program. -+ -+If any portion of this section is held invalid or unenforceable under -+any particular circumstance, the balance of the section is intended to -+apply and the section as a whole is intended to apply in other -+circumstances. -+ -+It is not the purpose of this section to induce you to infringe any -+patents or other property right claims or to contest validity of any -+such claims; this section has the sole purpose of protecting the -+integrity of the free software distribution system, which is -+implemented by public license practices. Many people have made -+generous contributions to the wide range of software distributed -+through that system in reliance on consistent application of that -+system; it is up to the author/donor to decide if he or she is willing -+to distribute software through any other system and a licensee cannot -+impose that choice. -+ -+This section is intended to make thoroughly clear what is believed to -+be a consequence of the rest of this License. -+ -+ 8. If the distribution and/or use of the Program is restricted in -+certain countries either by patents or by copyrighted interfaces, the -+original copyright holder who places the Program under this License -+may add an explicit geographical distribution limitation excluding -+those countries, so that distribution is permitted only in or among -+countries not thus excluded. In such case, this License incorporates -+the limitation as if written in the body of this License. -+ -+ 9. The Free Software Foundation may publish revised and/or new versions -+of the General Public License from time to time. Such new versions will -+be similar in spirit to the present version, but may differ in detail to -+address new problems or concerns. -+ -+Each version is given a distinguishing version number. If the Program -+specifies a version number of this License which applies to it and "any -+later version", you have the option of following the terms and conditions -+either of that version or of any later version published by the Free -+Software Foundation. If the Program does not specify a version number of -+this License, you may choose any version ever published by the Free Software -+Foundation. -+ -+ 10. If you wish to incorporate parts of the Program into other free -+programs whose distribution conditions are different, write to the author -+to ask for permission. For software which is copyrighted by the Free -+Software Foundation, write to the Free Software Foundation; we sometimes -+make exceptions for this. Our decision will be guided by the two goals -+of preserving the free status of all derivatives of our free software and -+of promoting the sharing and reuse of software generally. -+ -+ NO WARRANTY -+ -+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -+REPAIR OR CORRECTION. -+ -+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -+POSSIBILITY OF SUCH DAMAGES. -+ -+ END OF TERMS AND CONDITIONS -diff --git a/firmware/lantiq/README b/firmware/lantiq/README -new file mode 100644 -index 0000000..cb1a10a ---- /dev/null -+++ b/firmware/lantiq/README -@@ -0,0 +1,45 @@ -+# -+# 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. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -+# MA 02111-1307 USA -+# -+# (C) Copyright 2007 - 2012 -+# Lantiq Deutschland GmbH -+# -+# (C) Copyright 2012 -+# Daniel Schwierzeck -+# -+ -+# -+# How to use -+# -+Configure kernel with: -+CONFIG_FW_LOADER=y -+CONFIG_EXTRA_FIRMWARE_DIR="FIRMWARE_DIR" -+CONFIG_EXTRA_FIRMWARE="FIRMWARE_FILES" -+ -+where FIRMWARE_DIR should point to this git tree and FIRMWARE_FILES is a list -+of space separated files from list below. -+ -+# -+# Firmware files -+# -+ -+# GPHY core on Lantiq XWAY VR9 v1.1 -+lantiq/vr9_phy11g_a1x.bin -+lantiq/vr9_phy22f_a1x.bin -+ -+# GPHY core on Lantiq XWAY VR9 v1.1 -+lantiq/vr9_phy11g_a2x.bin -+lantiq/vr9_phy22f_a2x.bin -diff --git a/firmware/lantiq/vr9_phy11g_a1x.bin b/firmware/lantiq/vr9_phy11g_a1x.bin -new file mode 100644 -index 0000000000000000000000000000000000000000..cdf3d3063405c1239d15bae873e11f4ad8644e0f -GIT binary patch -literal 65536 -zcmb5X3t$x0y+1xP`{Hwh#m8v=+Zu*jkyNP?_NuO=)KUV^avoK07O -z-7zusg=CaqwGSzTS_P7=y?9&u0@<{;|NCzxLcQ1a_W$c?yR$wZ*`swrfF%3>oZZA) -zulJ={=gfJ0&+B`>?=z|&3&N~fvpALghnsa-hgI&!nmy0ND}cdY%l+0(D-FP=8_=ASkxJgym%*C%d05^rgSG6-U^RRhthJwq -z75Fk(TfPid@ISyZ^`^oPb0&@FoZ1Vr_M}sLlGnb;bKm3zC%>pdL-sdaS`UxE#9OGu -z*Ui+facXbXXusvP_xabZ@Yc$bf^uzIwPyEd&JwMzM7piyLQP4>bk_DOrP}rqEn2eW -z`4Y}q@@uDdq(plj-SGG`KgpkQ@+n#SL%H@%8J(h!JKy4!QhsZ-R)9V#vwi&P3U875 -zAGowPUD_3=c7@mMB|c}#bIy{etetggb@(gMZYx>!m68@`$s{N1H;TU!?)j3XN9nVv -zeP`*bZ&w_pGx5UxR34qq{XF+^9UA&|q9!HL(Yk^3z;N9~?~50|{q2Ea3w<|# -zbmZ;ChsIF9?0kHHc8^|vPNE^&pRP%X-jTX@tqm{6oBdtMrQ4vjr8k3Fx9J+F>E -zhsT~HW6x1dMt=@dAo2as(FwI*-<8(h-F3o8MDd9wv>z#{M|Zst -zl~a=zA0J2;xKg8JcG^Y#>DdG6ktzD<6hm;$9==w8_F97*XxrCHQ(g2`BO#wS_kr=@ -zxsT3W4t;R$cSM -zNb~%W4Xxs7>*+J4FL~a$PJb!KW4hjQUF;f#i(J=g)SNK5*#j>bq)kwB&WL@vXO3*J -z_Vu;)v36~(eSLkTudNT~b{1gKFT&+db2!w(Y0GKzY1Ri3M9m-b8-<0vDG%>2tbI!$ -z{**r!9Ck%r4;>Z`3&D}#sOt%rmPro_!J^n@*Z*_a`j!wB0+U=;E&f(vFX7O%@XWQu -zqgu5OsOlqxvuZIUcwfpHf6HmGcW1u8*H0!Bt42ru=qIMwgfrBM@(MLuPTYcjz}b^F -z>aY5pT-3=&g$cd9Kb0o_I#%E`>i{sBL6 -z8Yq(RzDOPM4+s-H3)om$BY`;cow4{^hS`_G!zqoA(P7m@e_^i>;G+H%AEf}89Z$-S -zrp`2(Vg=0Jw}gP{daL%GE_#Fh7M-e30pP;kGzpsgg~+#)u2C}8xMBYX@5J9i6O6Yv -zEi{|Zbxr_P3MJF2^i+MSKk$p5lD+w~SwCG2% -z_!g}n!nVY(xT5}HS4m*lH9IikT7c)ez*Sds;9A#awA&R-VO_O}D)ke)mDgyBI7!-W -z)&7Bw__6M*)u^8oB}f<5d@Ak5;4PL2mY}KaHQPy^ns?tQ|Y^yeb -zcF_cmi`GX|{yuA;*k|su^a*_?pf3+JJOVTX7WVN#!`4}(kCN-G+GW=?|A#I)5GcAS -z5WL>CP`{z)fr0yjQ?1%pf@VLtp1#3rGEH>dpihmtQcHuHHwaw00dq)O(OnFMDIck_ -zJ|a`E^3mRpf>Sqsw2@cLw&K7IQ#bb8kqqVrZrF$>T6^o%cA2)_Kye6KaR~Zw2yiwy -zmS&05pF0E^4uM(ODE=IarBO3Ulb`X2&SQZRRo;O9;Td!A{*Cu-T&FXfc({X)<^>+s -z+rM&O`?~gjxc~k@`+fJncHc2kyRe#g$R5foIRp!&0q@hqWL<>4*2;({L@KTK7~I`t -zpQznq+~YRxo|6b!19#sO;_j}*zN_>e9Yr?o?hsit@g76$`|z9v3v0r{@>p0#7e0T! -zDHc}4!h#&3HR)<1v#jfYbeb4g#poDlO2O%|$#Y|q-+;+;n7n|=n?V7rpa7sor>UfD -zv -z!ot*LlYfyPd1>T{EHC+d_^S7%xHUYO5aQP4vx({6Zzem#gURB-Pxpljf@$JT7D=ZD -z`IZCWec=ge8codnslmYm;RLT;N#MNvDRtlKbZ6Kan78;!lKcr+BKms+$V~1FTQy|* -z3E@#i42yx(l~0rVh7a%i#8aOhQD@nG!c;rHs|VO6-5fZbzj3)l9fr>ztH1N#*zV0vY!YOUU+ra|KZ -zsV7z!#y^~bd8U_n51lsyKpX&W1%TL1s(|8q;}@m`o(-o9QJh3^`8fPy!1wpwt3R_P4y*YDv9En -zQO(Am@}qLGIx4y*1ya0{9>o^CifIT~vEk8mqg{L -z!584XZ4mqD7ik4p7C8dMJuMswNx<7!mzyVHKo>^_%Z`rIw;zdhWBN{3Mi^?%FiUq$^@fuFh_2oRSLxae9G -zdgt&WJ)WmxUH|p4(6FFqp{`1cUVZ<_+t&B6Xhyz&NNqm9RPsL6d82EoZdI2WOWhu2 -zX>6%6tQ>uAk+I0F$4{~53*z|=sNv -zVQfK9C6;jE3xXpj?Q!)lvMlNun(0+~ewq5^9+WzA_HqmMzaX4d7j`%Ti*&EDXi{=$ -zky}0bT>9*Vv#DDwN1qddx9ER->}E^U8Igxa5+1Ae?qk#ZNv-hX6qU;;aUuP=z{Rp@8M}AwK~&NlDuc?G!w7 -z>Khl7H+aRNCG0nt)sJ{q4$+i4UgsUW<23(U-tjN@-gdXTtl{=`cipq@D-B%EP4idQ -z`*VD5=iURyIQgdfOXxZnd^<~LFAyJd}L&Uiqq9$D?YUz5sh+2X|R=-2*r^_$W -zl_G`g4sbG)qui*7Y6Qt;s8+AhRboHAQ=|=|RxfH7Sv4FX5waNN00hT~(5n#40Mv|k -z3x4=B)3jn$c*x&`nuRF6q`3qKuW%wr5JXS%Ox~Gv{yEEEJo(~=ylb6WirX`CATH*4 -z5+mPE*tOwr6~@Ukd(6ZcN$-sc`B7&@mGt>PObB(D!WpobnX2b(rFZd|W7wo8Ern%dW|KPH_M91pxEOJ^>W -zqkRJH8$(XxD*(dI30|uJE)NM`I!a$vMoo?!?Glg^ypZWH1j<(QgEO8)YPE?6Q^Zm0riVFA3dp)*cB1(Kp6N_o -zH0lQxAduTthD+xlWNLxh4}4_32&`fx+Y9_D!0(Uvow9>sfPHabUs3H?uH%miZ`Zz? -z>zJeD*&}&TiY&V#*)=IjE0K&q#W)5YPoQFGP%-@Ew>FJ{RcrK=KdSuBHjL~u^g$(8 -z5c0?~b}b{*-a|ZbQf_q+2YJ2{! -zUieGuArJNZ9w2ouag#XoJJ%sziRL|@)_%EqHBBAm&}BwHLmuR6bv3%Mexcs_|4{Fj -ztC9Czj$mN)2&a+n;@O2KU@;XEUBuCa>zAv8(bOxPhHMHIke~}OllQ%B-kazx_3Gcs -z&#W#KQ?F&;*>-Z;o2xPHV{A-JHbgm}I?idVJ8J%v5cG*7|LLdXdmOUN$a)RMnKFz+ -z9v_EQQ=*XN%D~e`&E6+EM`u#Sldc&se`?Ar!;qOw6*Uo0hb(h@oqI~7rN{GLw?;U9 -z!Wm~!Xf7Qdx$3k=yiw;K=j+1mm3yrbHOlXHz8(c5LcP|4mRb+t5v4; -zBkm5@{_C44G7)~VSwSP{rN(^=t4R%>dFn6T=@Ytu{CI<6+xYDRNR;6c_hE{ -ze9E1=+iR?J5$EhgD?~JdSE>xX+BhJ%M#{_das%?<@V?e(%kD;@GQ+5)q@D`yyYR_gk7>hv$RH_-k7uT;48=?0XukztqaX2K@S -zYtMGk3O%1r*8|SxlxN{#K}(2vU38w+)O>;F9Vrds9M!S8Q84hjg#Abz>_Mu(t_~tk -zx*i0SNi-S-J)|Y}w6fT~9w`XUayVzrmyJvWng2l6WI -z$COrkUgmuw-mB~$MX<|ww`B61$aBLMK}7=_z=Qw_!Gp;R1MbP1K0GIq41PHVRrKZ?cIs&MdIF6c`A=Qt{Xf}#{ -zAE^T@){M*_@9$;_bu)m_PGbGy<(9Ew(FJ4mGvj16S>N-d&-Fbr*7x!Z95#0RuAlbr5 -zJGLqiWH%tiLzb;yWwZGg-&xJ&EL#$pAbA`UqE2T_w;O--r=ZR{O9bM-y@d4*YsT!itzp9SN8W$=J#B=zS^GPgE!V1z -zJY-@tK@4Cm=k!}*R7;y+H$VxkANHdjjs{;iN@|%M71eg48uF+aNXFsl)S-On(pUp@ -zSrg=&O=vycx5!VXs?>{NF_67lA+t5qTA^Aj0xA%!DJ;uW!ajyrZ>U2E_CF(IAVW(_ -z7)K@p;AR?Vv-zcx@*6_^z) -z%Kxk^fW<_;YphzX$e$!^jYIMRmb)(RoP1v>S8%X&V@STo3i%RiDYLZuv&5qCXATp_g~ -zCT}oC{UM<-q$TDxby1JihIMELGh2^6%(ZHN7*FRQ&CF7aN9{10hyi0B&}1i*g{)d0 -zfq}conc-Is@Co85vTB>LHspRVL$;Ly7990yw*I6{{Vad85ggiDO=R}qT4oQv1Qz;z -zu+TzYD_qGdaY=+N(I^shzR%arqTp -z=ditwRj54N2Rl7595M4ZvT7Nzhyg)ZKI3huYo{on*zFB5Q8m!X_jzpt8#Aw6L-6>K -z20YJ<^Hkb|@t9fP7+#@fV>YB(>mn6XL?)J^P;(KF2P=kc{_|NhQXvXs9cA=GNba9K -z1-`R>tspyZO#dvV6pL*zc%0S^*v2C08%1nya73Fh*4cbSrdaDUIId+s1DUmIHnZ19 -ziZnS6JGleckyh|*9#P#8D(3}^zIGVWb -zK?r7iL{x*O=8M?7^$@SgJ!;;$1;OnfUP-oxpA09Zk4(W$lY^UzTf=$hI^#*JcB2=x -zu*fR5P_;c=r6#2-$rqjspO3y!{83c!aw;rvo$-s46suQIN55rylZ)D5cjEm6Vox0y -zpO!w2^HpT^(E3x@-#pA^ww!l_f?de?W&W|*d?jn|ve|ON?)f&GjcazV^@rWud_VN` -zhqwB|i}9@9zV!h-d`qg=tmJaGZSghOY@zkHfgUQ`S1e&QeASDqm*BZ#34^uZ&Na7j -zInD0shE+CY>-u{EHfPOkYyHjc1$VOAIS+5Vs~VY}TIa$r6tQaVVf=iz)o{LLYihVV -zmoBa08mhUa&F=YYc!A5o7X1WU6k`4iXN;zdtNs+utTV%>z!WAzxrQ=*B*FN}U~9OS -zJPnzLo#6(1M>ug*jh -zqb5iM9LOA~vk5p*VuJVyUe-108%R&X`OM4MW3cy(vCCkq6`%_t@tV-2&^L;|H8~^> -z?g=LtZ~E@UL8&<=oij$jCz@l;&7cJtz5u!o_D~wTfjA4}NKL}CFy$o9MU39(`XLKC -zK>VjdcL#k*HEtX*HSRYDmhWon@B@(6Y>arw%c3(f?N5{2g=pKPcG$9q$-8-u5nr}k -z5R{k2jSuKlhY}uu622Zv_&F%yuR#fisq_Ji>kNjI0&i`u{fmd#aUe)(7M~q3GB{yJ -zC~lt|ZM)__z~&{u_Jgs527ne#^C#QFMKN2>NdX6Jvbw=gt!-iCP23Q(1=-xgCUt|T -zO>TqW@}215<6$+|5qUf;dINlO5=Teqn-jjtm0Fk>+#8h# -zi!uH^qBfxc{4`r13@-UtSY~>tq#R0E{2Y#N@o-WaE!;kkE|gM(#V~IS+8zHVI#Uqz -z$ZW_EQ=(2KtlL|p*)3T1pEAAX`NBp1UG{T%Ul+ArjhYl#i>z>uLdtN)qE6!y`c*)! -z8oHZ8E>xFMz0iIp?|G)jdY}(lwfsEz`aqjW6T_t=d1vnFg%F(Yqkc%dX(osG8C{_D -z1d@XtqH&=QIS^Y54uRK0_N6`~@Nm*eN}f_>*T9G!G@*Q~d?IR4RbM~nSC2rf&VzBP -z4rk0a4yPV)m{dL92Sh;lf9;wR02y2gxG+CxNIC$!O8FQTIlu$#PYCp4x=_;U5_w15 -z!`L6_{tOrCs;g{UFOu|-pJHPL$q75q&kw^R8GS08&<7O=f8T78TBI2*EsutO^+Ag? -zvfbEb2rc1oXnTva+2A)>wJip0pi*mbJ2?wvW@on@FKwsWu1OOFzkmT@8Q{B3jWTS3 -z(|5$bsz1%>XT9pLgZr`%)hVjCqk0=ui!{^qwNaCQgdFC$$jfm)A~XcKz5N6HUcsu3 -z-U)Pa5ZJ++m;mu8dbQItQLHrknqe2Yyht -zJR4$f?qURFLoA12=&5qZ0zi>yxV%A?um~Gs+go}CKh6R5{}DJJ+F;Z-g~}VlqIy>1 -zTOjw&ZDD6JCm=KrVnNy3HOKB$aUN2W+m{kXSJJR7`3JW3Y%}UlwYN@ghvRJ0_BTk^ -zwl@YQS)U3|6oBcCp=-TQHH9iBw@*}Ao33pJ0WhKgDA3V*;VpsWI$EMpn^y%6hezKM -zyiU+5Jc$#d|7ti)g0~eXF{jz%`aOIQA_Y?hexFgpy}L$5e-bW1iN&CVf8|Qe9vJ+p -zI#@gd=dOeqaYleJZ2uB`a3_;>(R2>VXgGXoR|{K=LUlWPw1l^}Fnqz0`IS|Ba~Jk% -z`kye2qAj`>G~XD&a2^Rm){sV89(Ai9wB$M-jmD-nsEk$s$BMZY=~@Cr#}V=QaE7*o -zD4PNwo|0{2*FI?Zqo4344Cj$hw-^b4a05gxK*Ruou<-zd%E|#k3n8%~CTv0IL<-%8 -z0RsGnw*$l=7u -zDPk*>=mrB*a-i9DEMCG1VYWoE5XGd@#t?n%!KP4YFAA9sgRx(KJu1%zkI^7>VOOoF -zQ^4pLrYnC6vR*2AWLT^|E60)J8SjBEL42ugvBWmR%kYT}4(KW}u`LFf0I1sBzLI!= -zc9WS`w+P5t0OU*pIlV&X`RR?JS#nWRh~c*%aN4&Sr^f3Bw{Ild7;l9m9-zR!w#8)h -zvlxU1LwOiOT_(0X9UgXV)|p)-P$UL|R+lJl4%PLdE>^8@TTcbf$M#rrYE-lYS4pa{ -zITYL0GYKx??K#K{iNRHZYT3M5-)vccXbsoiKv9Vh91U1pY0b7+*rw-Lx9eRL;Ammo -z={JGCAa;d7j-|aS>=lq>nB1d+0KW1}_;7=r^(dP2)l2e;`z;Rf!O_Lo*to)BUmuXx0c{%Y%%LS%DZ#o|l|;O_Athg5&_zCJmxJ;d$D%f1Q3tT70v2@@78Rl%cxN19 -z;3ywhw~7}wg)F>QuOjRFD)etmYZBWNOuTTq>LHA$ph`fSp;~$|X}~UI%i>V;Rkj9f -ztypCVl{SS$)gq{(Ym>gIXi;Ef`ePVbQK0BPJc}__Az*dw3@ML=OsZrga&|)X*^#Tl -zzt8UsA!!(3SS)Xc;q(~^}2~h>IX5|$(A@@0AJ^)vD7-~`tuV{Zn^utkp3F^wFq_hLp-JJ#(#cZQk -z!?Ah!A!KEAj|pm>L1H{&Eq0)2Cr|LJ`Y~BR%W+_{v`yfn` -z36QJ1b{HFCI}PAJcvrq3BHfO5G-UWdcj#?&r{2ZteQq7gBu|M7Je=xBqaA3((MxP@Knh4Fq=b{*#;Z -zo1L*-5!opw_f|B9Ds?bEr+9J`lhNS9xdau<+K$*8Mq|JR+rS39810EnI43(E$>O6G -zgpAoOl23)xc@2l+k6}F^3ObUi^(m&yqu*X0$_KJVWVemyA!KYkuYD}9(29XPfr`$E -zS+zT!iK4j<8xhg24GO)G8dw}h1eMf|D5Gg+zX>?!AZW&Tg59dF?ltJZTrXg}jY~31O%2Y+gQ@g|mw{Z?& -zGo{j#vuermWl%_w_T>Q3{05|&-OjaeCL^`Pxx}|P=dPuR>y}|W!9RC2GFT*oem|l@COmpd%@njQtChvCZQ1P!E74B=NUG+?>yyuo5&%OTk -zw-?u~UbM3HAB?*{dEnog9(wTXrauS&<)OtbZ#=yB(Z|D2@14Hqf#|m*>F9e=Pl1!0 -zS6m^@E^?V~xxOlImO~ciPnnT3cXF9^;nbNEYA2TPH(fj3HfNICvfzeldtG6v>E`Py -zb8oz+TwFA*CV%y74X>^_e%G<1wBv)L^qF7p|8Tf!xauf9+E1U}|Iu*OtG_{-K11E} -zeqG)1;RyW=$}SAkIipAE{*DXuwO^b)N^knjOgel^V)X6mqaP(k=$wo4@GZlI?;jaJ -zd`Mwx6lgD}AvV>G)b)?bh~ItR)2w5gW`V48*lNy(7jDm%Zm4{Y?uk(+^uMi4|9i0e -znkb6*SaUt^IpPH&&mBvi_Le+(WjB)@TlC3~l-NClF+(KxQzn?yP0?xyY$ZU2V~ZkPi(YBE!x@ -zwtbvV6bClwTeJ<6a#(%{gJv@DNJ4(sbu~47Wgsm)Gs?|Qv_0Kwhc!5l=YF4O912UD9G%Jj?me%L5WgWL35 -zoZ5$Zbt4CMsKewSaer9YYD8QH945o?X^b4;71!12I@}rpH~UIO>oXMwz1a4&O8dJ; -zrt8-t8?nR{`m+@Vr^DF+w(L5UPu=PSp4+C&&qZJ_aMVSe+jQOTfxeU=mOl|QA~NYr -zF8x^8p4`3VFSTGzXDa` -z!KfudBi~rf?Ku(U_H%nJ`&=ER@0303K2g@)+vAG4JIeQ$K0AG11?LIP2zhHmbs=t6 -zoqnF5rF%OCFmoeu^ev;(m|3OAs}3e=4?@iMR2zwX2dnk?tb>U<6&ZEznfgq<#?W(b -zIcZ&RvgVfk-+kx1?=0w8&~eND@4Zvgy{Kd1{u!~E-N)aV-g8sOJfv$f>6<&|??-%^ -zuH5K#x+@QQjh9`Y^Fz%w^c#%>F5<3Cv>HuqSa4FA~TZzr@nRBpi;O5iABV=H1kF}i~th;Ofnj0I8 -z)rPay+BY6My(qS@2So!`RID4A-7^Oj4OHwy#XeRMF|jGc#11SmD*JCW=3iWF+|=VW -z<_)0X2paaFA)3!!b7MPMjfPe1?l2Pd^Dv0zH?=Rj -z1A|zGL9Dk$4HVgvIjpfGDIli$$%)}s!#EOsE_|bIU7snsR0B*+sFno;g -zwu4JC01V$)X81A#Sn+X9cdb6tQfXAW&5u=E40DZMX(VPE>#Hn -zu5OlI_owx<44|9bfid?ZCiJL4LkNv?x6PqC)CogIY;6S)e+Cf$9A6!pnCHpUE34ay -zQ>zAy18UxxDz{h3VIAsu=c+0Xp0BFxUgn(%Y_96A>98LA-aD1u;&FhF)f}(?xT<^R -zF_y0EuK##?4={cI@k~9IwjMj4satb=MW$Y!XT`^QwMFxG#;ap;ySD?CzBoqu5ynU_ -zbita^&Cc+};RNNz@EpUpyb8M|;s-6`{%aIn#1S~r27fB)x@$HYXl39@=hfpQC~f^*pG%f)B;EPjaOuEJURTL#0M)f@*RZ -zQ(UN?Fdj4#28^p7V>6APl^Sh{$kGb;AgcKo=nrq2_z^qKaT_P8un9hJc< -zy{f3vB4GQBDhute?5Wc68pLangU5pRZGkI+YzV -z#agBQwpODgZ9R7NZ)aURy{3a4WM@{ynJsZx`}Ws#IQLaQJJVgMR~gs@3y94XY(n}f -z>8cwLde}M6+_%6v28rlkw1kDu>&_BKjZsr$ES#w?sMbM0tBqKdaZC5io*GYRxO)HW -zj%oX5JzKZ5R0UWSeEw8OSy!UGu)PXLihUVpezE*Ge3Ygq7Ife@z)A!rNEuk5% -z)U|42hG9-jHx_QTY%v}J^2`D9z?QTfaML~Ix(9yFGB(~CfvLi_5TboIjS-U21EQItUN4=Elmv)n`OV`rh*|bN)cC|$+Z$Xkv -zAb3R@42S>CrVS$ei7ND`-B0Hv#n~-r1u~MJO -zC-ba!Z4yBk0f*45Oq`XLu&At(MftVuT|f%KkKGiiVLX?`Xgqis<~_JteY~<=durX#apg3a#)*G&6sMj-Wt9H=GOUpKeg(l3Sbz9pE{oJ`hzg6H -z$h@z^bPzB>8zpKENEG?7gC)k~NnTl+u`#Q#oo&SLcKkMDO`n3fIRO(k)#UbTVht`-=}Kj$Ld?t`pi!G5D)S_2!FnP%17IYW=SP(h -z*u*(35%dT_85Qx0y4K9v-yB~QArR*7LjAA-ErW0xmZ8qL-3Y7q~yuY>Mp=qvE+d>fXJC!yA -zd6eZjza+2ZOY-C|$t(R_-bvWa?AkOFq6wb@uDS4p^O3sodhSx#7N=PPy -zpdolAcop#45{}d0aA)$7G@NG1;=G2zvPZ&$a}&jBMN}C*+Z{eXSj=@MA)Y5ECnaez -zE;%H_VVRb5@aH5YjIo}LkzK_E8gmbC^k;N%W#byC*1^!NE8!JJYGwTr8+7gkx8sG& -zS$Zqe)ibd%@aV2tDKQ4`nOw^`WkR`C>e{oW)D;M0_~s^DW_WHtyKD9M6r_ -zw=ZTf;F)s&(lrgp3%jdV+=c4SjE$h4Tf;eCLgY4V7!@loJVo>G2?%NIjRu; -z-#{;!9DO^_QJA?C3ELO5l|G8evG{fPlHsH6CB(_BK%|oS1bazWDP9VTVSpr$Fg0)yX!FC198>5HcdlPg^L_-#n&gdcIMQ~pfdd&!0OeX~92N1PsxYI=5 -zSS?~u`KxiCd>_VBnf`7N?`)qGuobde>_DjTw!LNCi -zo(7)8SbYI8(j!>A77@uI?0Y|XgY7#SAgnEmYw%;4e3XCzv9&e>5Mos*3)|KJ2)ks* -z>kwWKjmICtK0>{SLuAhYp4nK#uOO}s4q3VqzwLG({6h$@0s3TO@nF)WDRl5h7T2gT -z2NhjB_FSKdR|GrF;`e1yGb8@40}ap%`o9AH>KpPQ1Ej?ZfFn6zv`BOKrE?Hdm_@w< -zHoUXA!RN6q8Mh?J1&#y9>an=Pe}t790H#o>}@{5d{kB%zeOYt++OjVzF8%`-NTbL=kkP -zgGdrPkeA`=>)0sJ*t+q(MlgqnW)mQlWMVEtkWLss4Hv7wA)aJQFe&AgH-;vt*D&i4 -zWR|@DD6@P%wkr+N3-Lt*-%U9l!c}_s86e$>g3=-$%ym$Nh%#UIF*+7>&*Jd&5fchD -zz`7@}m!F6x2ss%U4SRxYAC~B}XY&4lyo)wo`P9Y(601LgA8W(fAHWZ*3mN5k+jB^>J%sp+l`eW-qtDsQ -z%0JuK{^73(V>_$#*)*grkd5A9a*(2&v;7(wEIy%F`OR3GS1iiE*m^Q^Gbsrg6Dd15 -zI3vnynYrBn8SHz?tGM8bpjyO$f0KU0rhUt%CBBV}m+?D<-*@oq!jHkuQ;yh1AzTtg -z(()y3L_^GQBl(@Q(58);nj1+fJ~7ZaknZH929D=WO`9tAvw93(@5OmQFm=gM7N;nErLMzntHmK?J -zS$Bv07^jtKa|~kOI>$}!_PLSyW$oP|*j;ZrG2acR$WeSm!GP7OyX<%!Vi4Ws9Usnc -z<7I|Jj2^5@eOTT-N}z}KAL@?}zkG3qQ4^YO{KgaFoY68pDws}&W_75wx~tKA| -zbitHuTN{g2bbN^RbdDgW8lWl -z8T$F=={o1dExIcGd|jo^b+QX}bM>+Y9k=gZRGZ6t@~3zO-@v>%Xg{7OG;oodRX&2Y -z@dh-g)Z+`Y?dEvZX7i`b<@!*0!;9*?9wCam_yeD!F~FGtPWN(=7YE?e>_%k9sK0++ -zYM!yGR^JpTJDx6DSL^Pc*-^c}&OKW{Ht+ZdaOFmQS-E2b8P&&T9xr!z*?pyD{qwpb -zkv`b9+p)g!{&~*G*}Qq(&oG|Z{~Rjp>A$g?*}%V!boGgu-A=sJSw?c(%PZQe+NW2Z -ztkq}KT7*TN=WF$d)$3Ki5#^&?#O!gWeluslV_2ZL|4X@0D+lZJZvzI%fMcF$;-;=g`>9AcY$J|ep=)@x^Xtu(?)BD#C+Et7@M3C5Af{H44yH+ -zco{CeL2LnC;FZ=G$KifyPv?NzxmfUWh;Ck~L@%md;9Yd(V&O`e1D~zX5((LW^j&I< -zsepgeO0}4wHzx1-C}-LBXKi{xMHq7r8;Leo#X^n-J6O#_o~eozpXY8 -z3>}}+@M28vEVH884MB-+~q|>tW4n9`z?%1|=5u -zri8H!gII>I90RVG83{`$Rc^SB7SK6~k(|&+!?YSkwp%do=^YhD`oqf!gjhxPnoU36 -zi$Q!FgTVe@1U?P$vDyZAw{Se1T33s^o+6VmVAB~oF_LbBYS6}99Bw!`2FC0P?f7MV&m -zrhXY6Fa;kd2&_k-@xLo&_{M=5>86gx{r{C5mE0Yc{`+_|F}lR5=|bQ@qHve(4CpRo -zr~f{7^3k!_NraXRirUS!)UNy$+n#7a%ww`eI>uy1A{R74Ov}Wb{4G9hN+v$7%&Og; -zl^cbO+;}VGMmyqeVe;V35MP+w!{Wu*WegTShAU?ju!ttR;EBw$I}n&Q&PQK|UFImb -zSKc|Vs-P{Z=4a&<&dy{i1_Rv1??CX`-@~c0zm6a@W)sNpV_XV50x1NSM)C-P&@=?0 -z`4LleaV!W8;S)n}PhE;2P{mOOKW-*=@6#6O2`(nyKpj9o>~6<1BE)V1f;M*@0)~@c -z4WCCiVP!Z(Z0fGuWY5N{xeDR_o>l(1CTB3jfZ5vyct -zaW{r~wTGKRnL7c9LB_gUAW^F<)-QZB9B-etgwM;a7N~)l*hxw9a=6N#49k;wR)!&F -z;=Fc;ee8ZrlEv0xJxBQ9PF&;%uho-~9?gd?#{SZI6T*<-p84cHGSe^UvE2FqLGZq6l5${zL -z7iTCg&M3Gz!`fgg+)N%K5LU-T+cEi?*?@dQxHj{5`Nwg~m`O_bE5g;8Q3V1I%q~2( -z<8CISGI{hKWKc+{)Pp^`7xo^=zH3?D71-Iv?&IJJj>IfV_+xMyaRrCTV?5fYnL#Wg -zzK#pM@Pp$D&S&G`Ak#8B!S3onW`iy;A_5N6>*{8+ewZHjg?l)xE0o{z*}WSG!R)?G -z7Jv3bor76CM4T}xL!^?w(0oGx -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 -zCTNp`!7@|>oDu&uD7!E|PE^W{Gi1wv4A>aR -zPVx^nk?*Iu2rz~u*8O@&0y*Ewo)Te -z3GG=wJ>+sp!%5EEGm<>=c1{>By7%Mhq4zGP5A_dneJ@+YSEQ40M#}m*(9#0P>G+hO -zORv!({2}dzudY)+m`Ru8(_WYLD-y$_>2!wPq_4vo;2Y=`AbYc{%WnyR9E`h*$>lW= -z9(?2YkGt$P?b8;>gKsdLtOL_wx;$Y)4@{xQ`FjV8gd_73NWF3%sC6A%V@wo}^O&Op -z4}#V8;t_yMz_WX$N>u(4qig8X&en?EIrYdtglsSYwEg;wkM<8Ol4V?9Jt1k=L2U&b -z2ZJ*a;BwBB7Ms|R)A_eMQ5B6C`eY0}A7`^9b7u<5FDnl(!o7WD?3`$UO>%a_I4`wp -zlT9LYV36ZDd@Q-y*kZvRz+@3`Aj-3#Ya&KelYi8dckXsc!FMNzWcMCiuT7pO6TFhw -z(TP_j@66<(R`*84RJR%y#3P)D!*l0$o7A7I~^hbbi!xb}$%QQoAa5An&N -znmySvW(BDq>Ls6udt4?zuH+ASp_H>QH|9sfC!mN0jrO1sifYF6^+28npEhtt$}r#Z -z2*#!$PBk+=DDW2WZMcx-_aRsw`4e>5tW3yk+_Tu))Xr*=urzC|*og5t3SiFTGzCin -zyV8^f*wm*(r1gV#N?51!VA}AX35tRQupke=uY)hY=!~q!-rW<8vHS7N0)w-I5bneg -z7PAAX1oZ^`J_}1x!t^_E!?$Q_YPmFd6+sWp=fhTf$3T4L3G=5Z>zTnP!pSGXAAofg -zJ`oMA-HR+8$c_LYs(rcKr(EL8ju^ZX?VmD^ECI+YJBq#fln|?)gbv= -zm!us+65pRc#@Vz(tC5sg5EPQQr122qQB>+^iaMVF(bo>BlQoRzKZ~47AaW`rWqmdi -z%<4Nftr7n}3h3399&E^Y+|$H-Qc;svO~qx2#bqE~BkGZdP5k9h5C{U}VX}cf -z`mgL0R;KawhOK!e;{v+s~5mGH4NKJhRMvA_NJ_;R=+xH2!8+)cntm<4_uGGtd+azmN1Ty+ -zv2TGW+<7{VYC^t;mJlYx_)bqt -z@!;25+QR(clVSb@oJfap%^Pa|-Dw0~BwolLeMQ^n!N!=C(FcsDC!cTL;Ek41-`bR`egjU@9N!vrAS -zWjG}zta*c9gLulf6who7HK=QwLMU4nL0QxcWEE5%aJc4yLvd9ZQp1*p7u~A$YiN^T -zMo$wYiNs{p8fV`fYEDX~hNn9bj*id1l{Ny-k081AO7ysROw^Li$zmFw8bq9E@@rVK -zGz;Uzr(vnv~MYzIs^40K6af=@_lfe+tENWvuNr`QYS2k`C6)WKi{p9q^!l!KzW -zq)8P-@XaT}^mSHWyKTrX(;tX$W#zjISjs1&E$#UFVOyB(!TaYgKS>R>xfy+X=|L4) -zIY}&Rc(6TuGHGoSwcnd@c27PD`W=2hepzt6&sNq{t4D3f;EK* -z7MVD?DE_x9ST`Q)c1$GrP-g-}n8Wyz*7mSA~fnDqxdD#JD(8^rr4&y&3&B5_nh-PzxVkx -zNSIA(Oz79k+y5fnD;n^?RgFG}!iGD#&>YoKJBB)Fe0TiVgSLv)E!6R}vHQ -zljnQn@kq*>*)?= -z&YX!NVCMA*;)8H!%izSOSg!^DI{RbmoR2IOfPi{A)ZjdC#g{-OS;Kid!>gVh9ICs| -zaU0R8iT?3HvpnSb)KlGCrH#;X>T|-sV8Cn9G-982AOm6kTc@P6Uv5iQbWhp2 -zP9*7XZsGDKWPK;?Z%MTbWQrwEyW}_Z*(*)*uX{ZFQb^Gfu4DYWgMYl@-47q!Z6B<) -z&G-_dT4ZD~xnXnn{Ng2x6XublnDsrIyyUyWB+s7eJ|nh&d4^ek*t7kAmbd-O{O6s| -zFMH<*;wIVAhJ2)g${nRl#a@PIsqbFCOw~^*2WvouEO$FCf -ztV%7&`qrf)CGmB?SYni2W;?DwFuP!8n8oiU+wpYK;o08=n{Z20%hk5u4#lf2I$BLf -z>nC;l8~1kmk@KUTZk^;vhh1O8;j@Q7?#vzT-xlvOw#BzMMZdTG9z-c|8;L+>UP!{! -zv*NG>x-aqjF#aAdzbqGp8_*+-5a -z&29Uu#pXga8Od1#xr1~#(7S(*)#lm`4BUJvE}Jmw;VA>rZP{RLYK4(pO=gqFhHHMh -zA|9R)j~g|&cD}K~c;HXEBC_9+zV3&q^pGR*K%#5x=@?;ezH;+fbN}m&t9BmgT=f%U -zGXZE)_gasKT|1B_E|4nkU+|SZmnt8^PjJeRv-^jqcLmx<2H&sVRnmTzpVQf)nb)b3 -zWSe_75~!g=;zvuF7iv>==^7HO>^xGF%}!~oMR!@_&`IH8U{^b7;sZ1>8lun|nAS+= -zyX4!b>jHypX2e%hw0ZajBUI9nUHy}X*&bHYt{db&XQ1-PipQ>bAHk(^@V502v -ztTSwT&g6lN#~ZI>`QAiz*bPKJSr}}^0OlZ2h#joTQp@vl#hoHoY*dTnA?#&?@Rd&m -zZxX(8Y@V-#2+e}MM23dgc{225`Q~9YzTWpX@@l2XJq)bKJ?ZvLfZTkjegf%c_|{0L -zRSyT=btL+BmYkPSVQeH1Nt#4Z+u3P9!I4aOd_Rdu*mmJDickqTFZg}0an=vnEmct` -zk6$Q$Wsq++`TL7D8A;(YVoq7L6CJS9Fv+Z&=ztmH|M)DOnc|ctpL4z-M|}QKkjv@| -zJUeJ~NIJEe67%4hw7+Ctuw-7buX+6$S*tbKkzlQ_c^xWk@*^$w#~|vlqiZVzEYc|i -zp5;b{Yd8|*Xl^9&dUhlk8zhcy(2Sk=aB%S%dG_%i@Ymq?wq)#RK%E)kXp9=tLgx-u -z7Ll`muyO<%lwfVJ%){`C*Aq5VT~DquXQiq7A}#abl`K-@)BfAjY)50jA1f(UQnmvZg1B42vi$<2{J% -z$#};t;eS-q)uC2oe3mqR6;7i1blqNwX&H@Cf&2#?EMbzrIZUU852TNtxj>Dd8R8SO -zuWqXe|5$=)%jL=NC`NQW+%n%;sjR+;eDy@Hdq_Uc_cdV}#qsH|&eLmRPU4APf@kTU -zQB3fW9h`mz`PrD)r>+YX*ORMl3*vpVseaa*t#f|9$5fj{KFjZAzk^rs_S2l~r=k~$ -zvDZ=eAmZCTwsg;~BD{g*RkioC$7kFL!f*7zTO1j29uE+V3cH|QtMJER^-B3}4^44V -zquN*Vfm|nP7YiASFtc_3b!9qPrLC8As+RNrSz*$DOQ`eVw+6>OFBCAGM?(TVhKC2{i$t -z)_i$m1)|H!x8gGP_XYbROD5g7Y)Ql1$Efx(wqnP-ALxtB4PiwJf?y%>At%+dhM}JMkv-aSZolvxu^>t_o9(nEcG}x!y@qH(xqINS1+zhUNwsC -zpGsh)+sZ$&Rq`Veu<*031uQIKzuphA>_4d;8 -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 -z!+}q)MCp&CuWO#fz$9sqxqhU1{@CUg -zp~u#9zWAH|*KSq6>F}Fxv)-DxN#dGsZPBVvYuxPNZ)&8~BsMKK9slRoQZ@|p+scV -z8~48avgu`0Bpn&^{?yxNq(@DW{6AjxreB_a&J;0)r+973<#Ty`ghSK3^EVT}Y*Rj@ -za*zLIemO6rIS!CD{yOd?-Aan=E@qGh&$JvxO`5t1XFmp#fdq(Y>E)d>obM9cqqlkDLTx|Clx|dw@z-c -zq0hc^rm*=ooAR4ZTBx3*)6`qgabBNJBIZyY@|~n}j7-xC58d|Z<#T9)`S$6iMl*(X -zgi$3=G@sR{sne{5R#QY!esfL;k>_XF6n%GYhzN=!Y*WZ{G)XH6G8J72p;$Oa>#ks1 -zE?@J;L!;iJ@ThloIPG1C=Z5fgZ)5mo?>4mC6G;KC%4C^_h||U^G)3G*ciNPHpy?3c -zzE+NhNPd!ZQY9$UK1|M-kLfS-nV4@eW-5DfTppV;jgGOlQ)HPYD`wl29NI~fI4(** -zO@;bx{X)N`-`a2LHv@fnpy4r~A+WHY2O74_BK?%yYE!Oyr-wfBdcxuSJHnCMyo=Pr -z?oGoFN2b}7FGegOavOb(S3ES?S*T7+cvH(GN+1GUDa0Cd8-`1uFcl<~wkJF^Abq_5 -z5 -zhrl9j6@Ct2DbzxA@&&RZf6Z+U3T29@E&0G82(8_zcdU=;usVI`IwWi)Tmprsrb^VmY#o -zCKmqe$jI}tB(Gdc;=H_{YG12&#BAZ6ORf!)_kkrss4tAn!2>ayg3J&hJgNvWA)LB) -zY4E^ka_16)xoYfiwjOFBonO#+DmA;X{%bHotPE@;32! -ztW#eRIC{Z?4tmkSQgo2GLpGuK3%#G*5s+6lUWq^q)Z&=Gsj6jph>FvKgeK^JCM}hXq9rCOuRXgmq(zoj)5w -z{IB%PU -ze)_kx0xXLh1LF3WjzvY_?MY=)n=Aj-y#D@AOtk-4KZ^SqUZeOJLu(X^C_af|7mE8C -ztzl@7;vN*6P~3lJlB(pLv}IZ3{8wGCPX4R9+^fQgyKnx$J}BD5e57FN1yAo(N1S@R -zhn&s)eqXy@?Uvfc7A3uHExwj^((0tGhdduy-Y7p*t=OR2H*0%+SKoPaxJ7Ge)mrC_=Jj55r1OS)e?zCiOx~yIOvvB~W&xwN*P7%-qwAZ -z+c$h$i+0)zIpm^BQ>~F(x7;@17%=7Kc~0+3^P%=T4{-+<9$3)kJiqA9ww49@^U2l% -z$O~ttIo-|yi|sMP_(E-w`tD&%Wa0965BuZlVl5e7xO`D! -zVRr?YP$xh5tgZsV@&Wk=JQ^jZsr9lL?)55DA{Mip;K`3bJ4mO_x&%w@WOZ!l -zAOPm7fN-?Y+iZnkpcuFH6Nwf|u4%713t!_u=9Q$9w8)((=UpE9g}Yk#74>&-xbJ}t -zU!1jM!yWaUW7hmtbs6s#0-dy}}T^N1&?&1!D9? -zh}l$oSbIp@q-|6hwDk%-%}42XIdOo0JZjnyy*&Aru)BF^a*oRspFFdsaNmjjYbNW- -zjd(s(gD29~$$b3ZTw81YO;47aOj}GYq3fSO+#*9kjL*M8`MW{Gs3}Np#b8_WGa;`XJV?-jEB$@EJ}r!xBOyk2r@pM|)a_5E>EUfeAxPAATz0GW<*P#h=@ -zExir_Pry##-HIRnEL4|l5)V0^P>U%}FDqV?iRGRd1FN1-u6Cbhf}8LfiF!6hH>po-vP2rTtlzRxUEd~#H#M|v+;~zP -zFu69p>JiU>Qi1kKv|k@}YwOVoJ2QCoqq}IcXGeo;PTaj70~|mZ(9q*u1f}`-+VQ%AU?Y9jkUJDtMh5AZzs#l-nTQ|j-v#;mHTpWQKy2xR?Da#O56H+r;1h-n+lk^IvGWRf -z7IHql$h)N>e%N@IrODEt_&*!zfFw(ocnCqLLnR`O@R!Hy+$3G$uNvtd)VaoAH_~NN -zKpN%KM*4{Ki8Kb8FG&kEszXK4NQj6KK^Q(x&(n$158>CQEFhhuMC6`K6HB*gZ||Gd -z7^Byri~7~j&?s365yKkeni;>-!S9B~)?9=@Th~d4Mf8(m{Y+;v^aA2XH#T(B+0F0e -z(2a%hPjvGRx?z$^2;HniH&%30i*9suGlXs!+3Z9&f*-=jU(ZMUf1VFiJf|ND;$Qb; -z`G4-m1m#SDP#YppIB6Y7oKpb18b7 -z7~%8U^HQ0nmTS+OylJ0T^=Xg?Mh~+3XWvUSL(@KzbkWG(9H%cod(0j;aCtR~E0M=y__JCuu -zw;xBr9RKjVmOL;SBB`66fx|9F6c({=R=S?fs%03zv2D%t1hmz3Y}raW?L{A@fxK<`V5kNBA><0w>w -z?B{fE)!X&))NxKJ#hhV^AlQFlpIjd&$oT7eJO8d;NZx7GBYxmkAMr`OIfh}ITL^?T4)MB|rzV|8;$Rgwv2X1V+bmKfq -zY)WJd3KZnS3z8-9mEp0OG~2IN>y}Gqf{jI7eDe`jK)R|#zw@EL->g& -zn>u2A(}9=*1@#va;kSV({{eKelSU+knkBcCVe7NJFe)q6^(70xrlPq61@?f-ucNubd=IqS4&+Dev)7 -zIwwhT1?Bij8jV%a?ghgmdk4jl0{SIUVfm;QQuO1K`p`yA=Z5NrMrqYxLHex)Nga^! -zjub3Tipn5c-FDzeE{bw%lX{it@VHoCQH%FpbPhl -z3bJ$Ydtfv~9%5Zj3igK9v$|%~`!lQwXvkm_Bzs}`qC9qEANDrLOGkwcWE{co1^m8= -z-?#D0%nopUNdR1Vz||DgrQ-s#lrynnVjI*R8SJLrYdyagG(s -znsY?ID<|%DCkk`4_d+SC&Thv4@f>F78zQdYSs0G?A%g%xK^$uty%5gof>E|K9A*53 -zohzs9tj=WO4bfHMwc)4OIkq`B% -zkFc>}Ihp;YEk+pc`+VC8I# -zg5`~o8sn@A;oYc)JZj-lI8OhsU^|Qk7_vITH=6NM9$XwE(_|XJv{;vYN*=Ro)Yxbs -zxHyQO86E)SBKCSOYm7RC>_bi+b_p4ZE@B==2D-1dfpqj_=C+?z8r4w=tY0qc$ZVBfln`Um2bi$cYMY{VXB -z*_3xD(hj7V2@H~vzDsK$8k9(&$!?$&_AZ;in4a&3&}CCx1U5}qzD?N%*pP>be=&ol -z2>?fZnyEjC}p;Ou=)^&cCfupl*v3?6}$Z~QZZ9IvT7JH -zNB}`tK7oLSx=xA$cD6Ss1X;r%-{+OhY|gxL6XUx-R)FWmJkRQ8%*VpU##HkZJF{2S -z*cQuJA~LbGJjF}=en8BoWc}eSG?L-9031CShmfp4_$LM53MrE^>&Eim!jck+%^Hu> -zx*6M;4_zjo?G27-1LiuLhh7F)pU28d-bf1}n_{;>7RgsUy|Br#N%O2?H9keO82Ludn6Pl>p7ORv8#cP9Ke7U0d4+O|J*%E8pg)b!Tz@v$2-h -zp6p|c&UqNEWB=^-V9|s3+3k*)Z@%4b=Nf$vhGIT$eh4;z$F~P#OYp4PxqTBJ!DUtJ -zR&kCUj|A)O_UOjDKo6yzE0?hv!Kx)y%kW&ejP9JSCW$-1Z?cgr!lT&x=!fz1MZZliPp0%O3EMGSG#na8q;?CknDN_wH$E -z51}KaQA_*Dalzd@{r#zJrg-a=HrUNaiPPyy2Q%d+6L{K|O)6EP;D@2$Z-jzB00sY5 -zDEKhTZo<6IV>+qhg3?&?M?Z1mK#<}LKD%H5aW^}i1#MH~tvCH$-@J&vH-HB-4<7-M -z8ElQ^C+v<;|ipwG}>%4dfL;c{(P9xcJ~m++;cf -z6AiSC+S<+C`jxuNq2cEEX085AmJ3H!*o=+FGL_g(I9q21pGMx~&2SF#P0casQj@qj -zLD?}&O$OldP{?RP3|!Nksf+gM5X)zkhA{wp;!%fVI?RXac$TL@*#XElE9H#t+-Jxv -zP=A&k1qaeWr@4JxGt7?X;k{HzIdxHu1l -z&N+|`m(wryKumfGt}5j`v>;$ej$6AN%5q8ZsIC4?L)5!oC!PUD7tcdBhnVg(gDEJv -z*?u?EBS?gyQeO7?M@TIcxge}u>_C97@gNH!S_h0Sax&W0$85|Bv@NXE37PchQ8;KJ -z{|0+Wxh>nNOa3E$T%1ONpQCDF%(%oNyR4W;4Wv5YVW! -z6o_!r+<(=rW -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 -z6wIuwP@zoy>yo) -zs*|m6m#)Ml+E&bCleps^OhU#a?!_clU=nv@5@?PZcgEF$NB_^;^yZgvpm;k1)-J>l(5*(jEH6}3A8h^XOSEE*0E3|6$_ZyQlHA^MZe)X-5 -zel4$8%d1g+wQ7wD32K&BJ1gP&=|+ZRLx?LqZlY0y+xc4Oz#aW@tLCAfbOPlM0p$-2 -z@Kw>t+5T*`qN?p9w^9X!dS1>xU+D`-4s>6kW)DHD;z -zOE?9PCaO=hzFpZh^CU}GbhWQ5nA8H(H4#KYS!6FriY2v69l0ZGD0if -z^daa1p?`$K8M#JUHNBd2UL0HWF|v%9gW*<Kf36!*aTmE}TPo999U -zf};gRf^k(zjuD08g-TE>BFrB*hB%kU>98b3wyU1R&hF{Bt??)#H??inV(n31nKUQ) -zs21I+?exn0_MP2dQgb4YCbTKul!i*?FGY*JsT>*AZ%Gzwi?(ZD(te8oF)=Rm2tB`@ -z{M*Ts;su|j-En_^O}n|jy5F0y_E&(YRaz_CO_54f%dfC998fE*G*Z!BiB}U|HN1X; -zR~4@jyynwtwY3tJOsK@#sHlWG{=ceIqqe3h+C39+1*o~}*r;LMc9PMQo(xS94y|h^ -zj8-5DzrMW4Wt(}Zy1nv1)xiv{8s9@~RJVSekpYuIFA($Ij<*Rq;6e<4wOU@JR%_KW -zwM8?vg;nZ;O0}vwQK?mR&Fr4;kB-(Jn%!P=VAjD|%WKr7wW_{!wkp^oDM90BM>QM* -zca2)(pK{X&wcWE5HK%8FwYL|!4x*8aM$I*eqCt5L#JcEOt>?ZXSG|Uz%Q1BAY+tgbR-LWYY9Pk5<|J$8 -zBxlV^)M&al>d|~!GFqyY6esxNvi9FjKGIvJwwdd_WvaI<;5%}`SJq}O^_8h}lBJrp -zL@VhnR*MG$fsUQskEnLw!i@IvL$dHl)Z$IuyeJ9Yn=IF)ZPrH^^6Uii=*gX$AN`he -zm#V#Rg0lH0tF^1%Q#IO*gsO -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 -zXYl(c{C*;2&H}ru@Y$YUAu?AY&U4neB2en -zZ5((oKu>~kxSR`lDCd0Bmt(k=TM&bfg2k3d@t-v@U7g{HCjeQ=54yEF?nd>TCXsJ? -z+Z4Y9dhsU)!4+|GZNy;k#?Vi*Y0S^iaJuIsWr%aed^(mcb(^ugyr9zCkZibpR{`76nh -zu@K@q#AfIVt_^W_JK*r2*?6}7HO)-jNHbvuZYNK13a8A`=4wQ4yTjM!Zk}H7El@9fel8ZC6qfqR= -zzzg#5yzbn2nkgtZ&N1@1<`-nRxa-y4J6Xl@-bM8?Yd0q#cUUgX -zRaNW{wx`q-FRc%vu{uw)G+HjrL3c8mHa43A9D)k@p?O_n+M2OYV>mTW&xfrIFsVA! -zuy(dOv;9=M)|b5fLqVzM*~ztp$PyG-;bC#8;iMdZYOb|aF9M3qN!8I -zx6r7n-{Nf-XH(d5T2KVt=aZ8tvZH7SMaNO3qNtt8ZoYPpt|hG}Q?O?oM<9MO?eKmK -zCk(SKQdO^NFVhx$bTwIykTKn2{t0K2<^8E%_kOwY;!ASl@RdYO{R>^DQ+%pnt?w9Y -zD=<}j(4t*=C#|<0GPzn$e{gL0={z`UO0`m-Rx)S!hqAq-t);xJL~SiAW&Q-js4w-` -zFmX2&9T$Li?ApEx{=q7U!CVzy9)EoIs#U1K(!1bDWRW -zXc331bm+P)2JIfQ9u1 -zvA$U>ChId_{k)8?p4kKt+g}J?2S^qndd0=--nZr_7bnvv -zai?RHNxG~qiu;l%#5JB;b -zsI!eJ2e>{&yqMgaWcn0L`xNH8+%zUPipeSHSiwc35C#Mp#Hjjl?Cm6~UeCRb$+7WI -zVsfLHT&C`J5m$_ai|T^{V4z;ZoXNwAm9(P!IAHv3%!j_j#$pMK -zXXrXCULE(942QXqaXp0V7@=HTbb0`D{{ntNf*4jH3my;Rtb;CmQKUCv&Ho@OCBdH1 -zL#z%IG4#qKxd6KNdZv@1TWZ9^V>Jk)2{uoIoR=GSXXE|~*4%BZ84F{6BoWF7&eVtz -z&w+Rx=+#a(9SND3vX~zx-vC)qGVr(oX85=Wn>&uV&eU5L4vTY$Z&akxAq2!Clo)r9 -z>+r1}+RbPID?`Z77>je&FS9`JHA5^m0Cle1P^TCC2SM0IOl^vND+=Wl^XR6Vq{HkS -zgBBu|uK{<}48y`Jh|uHnP=L@Pv4A;)!d9Lp&*-~s?Z?Fg~>PXG_+_7wp!LjvfS$mkeYi3j1^BLwhc -zFbN_k9cC%ZVGu%?0Xz#pbeLX_kZs}HY|j~fp>rrjAxca(m@GP>-qI+(tHo@P6L;ZZ -z)8hQ#=Z*(Mo5syq5^hUyj(TbPYB25x!MGXwb|82LQ8b)y;j+8yVQca&ypPptbof`+ -zF}{!Z7iP(7bkwY@TUlqs#LRNkj;HO8*|^lfZG4Q~=-9D&*AwfQNU)j71`{zhY^;T= -zR>8K_=!0m$V>vUh91gAv*tZ{S0J<3W8JZz;H|>j!fGwL(0yuFnSLg;!xTsRYXgk6$ -za#_qeqq}j$9WuQEl)oNd|EqM-Q6BGBk12Hn;{ -zw>N@cbNJCKjAu{K{s}to$3;yK>ROHZZq)ZVzdgMXg=cN|8ttp?rb8o -zIv1qe!ssfmr1wLX=sTz>Jb&mZumKvi6jfZ?9n83zTxE3L)nPkTO~K%CMuT{x)iwd -zmqr#eGAg5i6F&@Z%u(`+j263?EX%&>#%MaDh5v;Nd*_WZY}wz)unB$sT~LTV%l@$<)ipl}yf2D65ASZ*~B->D^Q0*n9xOv8yKMJ -zputx>h_!w>69fJ*j^1P(FW}-8&~CRAarIZ2EC*MHmz@E)G7J=iJW!qHyl;(KW~WFN -z?lZfgOD(^MuSAT9jOsX*k^NZtt8Q#Q^R^mn6PQg_h>9in=g=zT1#y<}a7Th-()ES -zJc?|A%RgYUu!1-X9sPFTUVAJ%(B|kE+%MbA^}U|n9OR{vmipEUxNGDFZz)D&eTe&adZsr-zdXJc_MI}A_Iq&H%o9FZ93=tvXCC{Q -zN;CqhP#i(O8^#sK2N)e^@!e1(?qz#Tsu_icz)(v3FvEjXziERR{!Lu@#J3x9rxW#m -zkVV|l$@Q1n-KKppPk&Z;>Y%{jg$YG5A;uE`4tD+ae!%hz07pz|Wco`fqcI{tv6A`V -zK?4aX7Zv9Jn89%4j|Oh!0|YafEnJW`iknzIGVn0N>A3mw59qrv)7QVy5G?^XJvQ7i -zLFfx&4o|^eKMVG?wQ&qrm=F6JL8l<6!09SB?sbr>nhXsVKBK`uxVy>~$K=8Pp1iT& -zne6TgobdI|j$YW~M0qBQu!-7|Sq)J-TU3}09eoCD5pp|Qw;SumWpDA$8*o5WtWBV0 -zK1O#-QF)wA{Kalv2Hz|eXOuDW$<7Mkfg6&cs=uwz==ID@S@jKNupBCk9)Fg{_n0}NsaE2cV)GorSPCBp8pln}KWvUYLxH2aoPoG2JahR*F!Q -zt{CtHqTw2J$e>49O#Nk_3&&dU0D;(fRB9u4VK@=PG21BZvGpvu9pqdD(Hu^bc|!lt -zs1w0G*n4LTdk-`0lYY;oCU^7Wz_pbIuHiUy3~r3&0lhJPxrpQywhxoW_rcgtjL-Iv -z@w|!sV$db@11y>OFVZ22%wp^NHEiY^Ato4gAtpddND@q)J_%%HHsZfpLvG}*ULdQj -z{-%yh{OwVkg+-X(dSiZ8Hox+Wtf$<^?oOJV)DIsFgeE*fOm4!1;Nix@hmTzZS$)R8 -zoG==XCU3z#s&uW>wIvRaIh{BgMF3XjdsP+d9dXZ-w*C05%Ybtqi)mqWBw*{ffa5c_ -z{^kyX@7c`kOOw{2(cI8QNH-8;^66@P1DLe5#%ZUD0(*N1(1f;{aHZ<@vjoWvTOw56mBptRAD$ri15B2 -zE;`ipQ0(=e!AcP~Jor?OD-y?*;zF?h5eSfkef#A9k6sE=@IA&y*%>~;WFcg*ZDAQ1 -z-DV79pMd(rq9*8jm{uB8dxY^xKR!aGlNrXK`tDcIKMgryhkIqlX>F-P)BO@ -zVzqY+u~0`n+IKtzjo2Mnk2*(W6d_5ARYqgJ?|8$>&Y%b2fU0K1A1t~19u{KYsJiE_ -zRa+k29^xEDk4?lPIO@M(pSY92ArgV9YD~w10{0+PH9J%@q-$2r`Yc_$av3fxusZ9i -zmOU6m5W@WVoZF3W^{vK@24vsAav4-SH1f@l*d^SXV0S2D^B?8#hYF3ppl^O7t1t@{ -z*}UpjEvgDGU%8Csq4zpydye^Q?!JfVfGgLq-1_^O9T*8|Rd6+WSh#A9$T7j1 -z^4S^FH|QJ4?+F}g(B(ID^bR>VOTFIwuI$|Rzv9d_z`u9nNqzJO?XHDz@>Bn}s_TXcqXqjn)>Aj5U>6o5kmn_67c~Fk? -z=#jpELsJD!6+g`J?&c!U#QZqykA*^5iZzMTo0_b0;KL@-tRpinnOsZ{-Wzk(M}_bp -z^W!3H>F}D2J0G4an79pFK~G4B-w`GT3bIWm@Ejo5-@{!ZhR;x~DZ2)!Cv(mViZ&U? -z7$(7i8v2ixU -zyYWqXA>Zc9*xvj&;v$&%wl~Jd_r`=*6d^JgB;OZe_y8B<6Cl%H#Jp|n+jp=7>G@$? -zoWfAG!&C=RSMVDpQIK>E}i}+Z2hM{RJBX4c*c|+k1?(S>mPF?aBCFy2lbv@1c8N -zAKVw~id#E+aSfFaUy8=l$?KS^8K06X2q2MseUFo3!Z2S?=m7BN?l=6ouxr>nN<(y9 -z-(vQfMTpFfiD1lN%}q(Vw=vnZCr#hT%nR!^DfGOZ&G&80XB_W)p5;4i=abpi!|>As-yG5i`V(a<-rfbsMlA5@-v}2t?d{A5FU2X3tK2T- -z*XK+D=~woaSdxNwk5qT`f>+#L&v%g93**&+gP)4cN=YQeWJrw9z9UzH;c;&@Y|fD; -zi4!u7Y-@=@thtrRlgMVgcq(MIQlp&N+kObS8l8VzROSWHd2>tLpF-!NQW^n!`#PH= -zP?fN?L3a<+94SgVL?s5~lWn$^uTS(H{jBc;D5fw45K>?_`bL1le53CV;|kk}ah10;>oVq>pzaAX>!mKc>sN<>u4z$H`0;POBNI%ack9Bhfj -z?BQIXL=!FrHNjjr{tb!J^+59rOa@S_9>iGw$_^QoDqan7sPja?(Wf9fStBorSa+#X -z#?mJHR=ZNJ%wXwlc7y;_;42Jj&lRs%93A8=-RZ$&Z#oRWCS>tVU-#=@rBLih9*KDwr+OK3bx_sD8^xm*N|Ry2=@AEJqk~qq@b20j{v(AT%Nf -z;G8M!z`XyRNhq;&(z75uxVNQ!G&qwROwEQgF@3AJ_&DEgcnHUOuR)i-QAO`aiY>a!EZ3A43eg6um -zP3wSuKmT=!ivp$D+yfmK$nDCl0saE{w&-HW0bt>A0dTV8L74sr^J6jY`Foroo~-XE -zfZl+M*wAOe(VBB`c5k!d>?-dziA;CD6}me)BPw`YxY@3_@F3`pjny0%>K%-q;P}_W -z{#=%ePMF+0ZX>`bjwV(v#TL{vI#BX^Mp!r00g0mF_0m2xr -zg$tgOh*QHy2NW1gvj^%#$)hE&czpXf7#1#&oPZc8=)kL#eSYed7T*@!-DuIQxTt~{ -zVep&ZTEGRav6#-x{~G}#86Wz(Cg3}UW=TKF4_>L>mnm}_Wqr5^xX)`2!8UOvFm9Vb -zs1Y?o*0-Y3J~Tp6HHrkt-QjFMt;14F0I$+!%uT9{yN&t5j=|#Cdohm>5F~Q!W_(x0 -z@5x5pNvJ!E(Z#j1VB3-6&*SqcS!|7dtkK#e0{3~%&Feo(F+oCO9~3cu-+c(6G9dW1;g2FGQLBJSwpi2aBrzMF%<+K>%pai -zVRkKCu*PW}i$x!lVsGkje9yv%tcUO+>sU!-Rd!@>F9BVJnW+~n(oCRhbo4^dchp-$ -zmfR3XY%b3lN9|t89`a -zB!I_^?tIscV4_>V03QILnEwLdfS5e^M3SZz`a3&#KI9|AZ}>l0>=NVC1OZIQ0_`%& -z#&Di8WsFXujM+|^dv)U5oF?fX?EpVTm_N@c&#%3plM^fmCiXu7!j2x!=R08l!p3gy&&-S*H7y(Xz{d;-u-rE6&`S&FRMR{ -zKH>kafDazNr&l>74C9TD3 -zHgAd)PeByYl&2z|<(mK#&*@_0`wa?V(SOXt&c0T85>IqI9^jXxlAX!6QvAaKCL3XI -z>@Muh1<%cfEiY~k$f;hB$kvQcz{LHYE9f}~cvo-WouTKC>(NOI@yF%EIy=AkG{R?l -zc$kk{aMeKe9K@bGz0s1W!)GgvI>(aGj>GxG-l^ey<<^Kv#(Bc|nViN!l=0nCr1RNX -z5|nKAJ<Il -zWcKsiNszAnWB32pBWG^zeee6e_xnE2^FGh>KJW8>VssC=t>}--zgzgdvsaRBtsB|a -zYLH@f6X_x%CkCtIb1a(5}ww|XUz?Fz~n1OXg6-X@3#~9 -zA4rf~vbW!ZV#VGb#NM|2aFb(iC$P6EVzag6Gxj#CqY@jmrinzc;y2>@jx5*Mxi-tX -zMx6YyyqZCj4mvh5$3Xoxn;0?T_&)eaU=zPrn(Hk;CT2BNz&}~|=UsHo=08g;e`9zF -zvS9uv|Hm}{7cAeXjcI{>9;G~wY$UX7pBEhP?#G4V9+|gg`(2Cgc5fXLj|8jnd_Tn=%k%1=TqmOMJL$Oz}z=JaFoOmc*6Oq-eWTOz$rO&{v53S6|L3Xzk( -zoVW7aX3P!O+B!DR#InR5@@#$w&oUku0YkBObGodxe^+{@-)t>p5O~LqB(>HEjUI8wH4~{Ew+`st_QK!Bceo95Z@4Y;<=G3r5`Px3 -zv`Fm->2r^!iMQQEo#8Y*)mxr?)R(=YS$vJ+8?qS-<5kv#!!|h(4(Q28({3JB@MwCk -zJFDsFI*+F9{ZihXdp;hvU)5cu^^p@mxg&!|-^D=57<_PIaEo2YwzkrCll@edTNS+k -zn?AQGy_dZfy7^xoWcqTc%S` -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 -zWnX1XU|WXlpSg#cik98Gum*4+> -zi`Fy38;frVl81u>v&?X7p@KD688=y1MK#E*ur|2IrM&|$UVX0DPp`C_g` -zo-o-XFUi?zJ2vKgDj@{@@2TS+!G+;7&)D~w_Px4`h8>>2qS-op=6IOvK3Tu;uRG%O -zGtES>)|1$HWDqN$wN#)4crOSI7HH4K8W5PJ?i04@* -z!j)5ws@gbZBn^|c<iq3t+$b7m46N5{PcaX|3^KTo7w-hUgx6dl@moQZGZ{q2 -zJS^_^F|qRP5X5pse3WKeT39Fy@|P -zr;V5TtBA!Y%%GbcNX1xJAX@jNZGA(so!5V`<6Q&l;DoV^26@F3SzYq -zcsVi|;)d{~pQ{Xl97B1+o^dCQS-1?!6 -zSula`@hL8$`%)}5@@JSKczM*`7C$I4{KF-C`+eEIu>g@Y-NxX?6(>0rw#hybDK@gl -z<70M!#ED7$v_Qk0wq*!8$=hQ(&zM%#AmQu&lVOo^5o&L=D$VmPHK@DU55He)rI{!_#io -zP;bvbj_98@p-47NZLAOhCkYA2NrVm|GRl4*a&b-ILg>awIBS+JWWAI71_-s!*zCK7 -z?j(l49F7&bx392oGG4me*4IeNv-F93GxuW5H)71c*`kf<^?tiyIsb=&;hXw#FGULzXZB;|P3*&% -z9ut_bt~0vz3}$Zx8)u+%?Di9!BN8Q4Zmc82#L0vYZ3cpT7eHV~HWM}_xnb*l>2zQ- -zNnhxbhhrv!+^ah1J$N;Fr*w&{>buxKM7pwfoOt4EKaD4ra_gcm%@p6kE&MTYcf`qG -zj3}w+JDd2t@Z37BHPkULIX193L(}7FdPaf0ka5=YhzF`h9M8Z^U+6t}56|_3gi+2S -zjMDdxcXyxUNDE_2Z|@H0vu`(5P+x3rotyd=P~Xx^^)cn{%Clz3yy?VyiA{bF{UPPr -zL9uZ8gyG%fVB!_Xn-+DW@EaO?% -zW8S!pX6ETs>8V5yq)3=$J;SW-2?>o;#|6Y0x2v+EC~;lBExddiq&h4His(j|V9@-h -zWm9y}410naub~#$<~vzUbS#%~l{K!l)2>Mlv^H)V-o`8FvmW%>NG*|bn}jzYed%Je -zw8*O(T+@SDc&lzceyM#kJh{uqzCVgOa@35qrYPcLDz~>4b7!gcMyj<+{rGLLz~pYP -z$gi*%j3x%-Q1O^2v?AZ!d`LTK{mk(d)=J*z7x_q;D`mdb&E`XhxSzG+8z+vyFH-){C6n -zC|2W&y!qC#T277fagJCuSm=)OA+Vy{ijE+<4K)#CVx4VE+3gKAsXDVKkYYU)ZwOyq -zL68=|Quo1Y18(YY6d2_7Kxr*xzK$Ddz(#?wQDE*vN5L`_db=0;Xh+oHSCTo9KCn2A -zG>Hui+wld}aSzMYw#=VnSvxGn#|vIld?~bnK&rlmF)a#~@;%mvF7r8e^6c2eS?g1c -z+GV2hdUS;FCAmBQv->;1@oN%RYbQ(NA~YpB-ne?Jk*>9kPqyVTOS>^kEzD9EW@#~5 -zGE2RO_zjYjI1#)fk<=nzW7|=USjSW+HvbJe1_U-tyO)IWK680NjNr@b$_HY_m~VTV -z2V=Kn26VZ~?>`1U;gzsfyBMmaZx~phDHQG84U8YxG36ZRMr{G0^SYT27@B -z1LtC*T!}zWL6o|g2=L8VJ7HUNO`~mGWg8z?FP%??i?Cw_?V?|o+J*gWhrX$wF1Tzz -zJVU=FUbl+Q3hjx$&Ub12{K>J47~E02h^`3@drEEQY`Xs9yMfdsy6(tCqw*AIh}pij -zP2*0P*H2g}c;f}L+-<+Jfiht2mib%G$Dw(G8{{NG{0ZV78D>ZlqjsBM4uv;yKMS4C -zFY)>9KEyz^gnpYGR>&3=8J8qfJCF9k#t%R37FjSLIss}K3GJ2y&>JuR&xt!8y&(%{ -z{_$hAZ?bXp>&qT)sUW$T8QxkJGRmqr#@IOn6_q8&(WuU~&W25&E-``n+A>U4*)t@Y -z+(898Z4#YE=T>5L-{Z{7&Qg_ledraQamT-$2u34!5ohr2q+9kuc6dk5TV*rkTVn#> -zTbFTnRB^V0y}R^~^n!t>IS{jhhuQCC+(h5c$k;!S^IN&(;kS(nHxECT-I3u9lj_z< -zd<@m`aHT2|0}99WnKVm)yoXvPaY=MW)HEYHq!2h$BX9ynf?-0|znJF4Xn^ -z_Rx^TV{4qX4o=HPaUwRj33XymI3LU=_F!ZZX(Yrevs7un$;VDCGRuB8h7|2;#?Os^ -z)qlygV}Jb$y_k!Vj(}eSV`_B2cr%6;#UxLclb=rZ++%t-8{+w&3%>;CI;{4x4{7G&Rn7dv`97wONA3wNZHx>)6mS -zb?H6xr!Jj&_g9zBo4WY!rLk!@Fa2U;eCf0ea~fxqm2K!4EvtSN0tx|zfI>hapb$_9 -zCy)5Kssx1QY@a0fm4hapb$_9Cy)5Kssx1QY@a0fm4hapb$_9Cy)5Kssx1QY@a0fm4hapb$_9Cy)5KsvGH3a?#8=B1Q - -literal 0 -HcmV?d00001 - -diff --git a/firmware/lantiq/vr9_phy22f_a1x.bin b/firmware/lantiq/vr9_phy22f_a1x.bin -new file mode 100644 -index 0000000000000000000000000000000000000000..02b88a078b85fbf73a4e0540ada7d49ea6287cd3 -GIT binary patch -literal 65536 -zcmeIb4R}*kx-Xucq}fSJ`jHl7oEc3++VV|HK^^=ch43YXwy>q3ASrD@ECWGz;#Nx& -zTkE%U3uRzfgm#$YoO|xvnE_hPxju7dlmpI{GuOE;C5fW6*^VZnw8{OwJ4q?Z -zIP-u0=l}fgbDtn#uf4wZ+V5KH{k^|;t-bUw)o7xKd}vwL8DH45|PNEJC2_gk#aCs -zhhjpqm>P*WYjjLLzx6XG+lDtNf*DsUTi^=O($?Mn2>!sv%FnJwHUSqNi&pV(z8-C_( -z<<+;wA5f;^M)PZ1Y=Y*uS&t&#rW}cTF8)3+Eo@X`5n7lPk(ayE6>NLKfCBr{@L?iBetH?x$#_kIL2lS*cBl>V;~;S3&!FRt$k=PH<*_j -z(adOjruErymomVP+myEB%JEZ}pY@tkp0?xM{{8i>$B%1{bH}y#=`mLg$206dE#%1sa6Wmg`HAPVeU^qj)!{i(EWHQ!W^=-a(Ji?56!?sc|4S9d3j;a!pKR75Y`F# -z`HE*zL}NeTm=S1=L|S_cqPb&Kd{L1#!@Vfz|7TAA6({Rh*C5M^WIl6pU|~0kastYAbtyyd -z3#_Z?K2gzlFD`PTthqgERojvuV*^8+faaX+iY?)AVN20C0d?`O#+0RDA%tq8sHQzX -z-zbD)vxVr=A>lr8&j%qqe9s437d_`BGB9h7@G2to^ng7dM2)xxagA8)=20^Pt;iE; -z!Q5-nx-^_Hz{M2253+s`T^bI*^Vyzjp!dB -zdM4|NQGaY-gv#@G#O*N6y*LutG|G=e#K}mcTpuV^ -zUxpX$*jU0v-;SU}K>V4FEu=x>df?Pz`=j82Jj -zvf^Y`W=_5@L^H~-3<<~H`K&xE!>HBbCEocgGb32&3gZ$ -zL!sdjY~)yl$bzSotl+5;lLpg)YsFmIk4b|++$l_&>6kRvj(9fp|8ZMfhiOY#+lFa- -z3e&b8)3y!McK?WJd;E3}e_XTJV-*{D8Ly#N^z0wmKXEd2XWX&(4C_?_j>hG|^Fh74 -z##i0A%!mFCuI%924X%~T+pCw&<>eX-WyW$?sT|1>+FKX5?+movUVW%CqO;Vz2DN(* -z)v`GIFC4>-1C^dfrFS*139d$^8sD9b94cKGT-UK0mEN_c{Z8iOWp#d_(sopOJ1UK! -z(%0@hRC!Kkxr;UPvY5$A(UTme*^GaI>~PC)D>|8I$SPC({HgP&Gaxt}v<(MsLwW@2 -zh4e@plnt~@+bJ1>gAT-KVO@8#>4vo!jB_8ds2*4mZ^~q`F@99tRx120?DIEIbLlUn}i08c8AjY(QqhauD -zeqVlgNko_}D_89`vfEGr=B}}v5Zf}jS -zr4iOv6=7ZM7$?h$);@#%mdl4KITN}#@j8d5Q;g@IM=-y7@0l^;?<%xL?WWcM_OwN~8Bm|BJAS>u3j5b -zN%8!?y=Ow#aALK?j|$HwD@2}(nx#FXuXTk7k>&guG+LbG*gNu>OM^e~$5G*EWJb1{ -zS2@uP8E6Ml$tRh*Ia-&#fs_AI_}>NAa}>f-5MVbLQx^!^EPR#Yy=%JDkWx+Ax7;spSe7~=(_A@R;bYX{Gc-v2{CvIUSW -z9+}o7BAbe5$abM;=<$7-8OdZBZ -zUpT8LD>#%7mA?di5e~-<0;cT}=#yU;F(r&Ji258A -zi{yBq%?S0_rA#)!*m5`-+ms0WaD+~3Z_R3lC6SrJga8__Rq0Z`)t>9np4rr%#c0oJ -zw|$hWz;1N)+x4!Pf3bUvJu7I^>s)=Nc842}g>H^9)Dcg$iENf+GbW=M3bltG&Dt{C -zllgu~?~azj{+R;=%g@)d((B{X{GzpZjP;t+8Q1ihHQJ1v?!%hqft=Pzs~zUhg`g5{ -zb7wc^oE~#pdy?4>Q#noZ5O-V0t=k>X&VJ^$_PpM`Pt0wy$%s6I$1WQ5Bwr4Hdz@YJaCc -zxa5TP)!E$+gWp(@|Iz-pE}qSQYXNj@r@!G$(CBzFa-)5LXz(wHEGQ~Hx}ax4(V)ot -zD;QkX)Df(ROmZQrXLfhyHcfN? -zcAcd=UTPOBGAjP{;?y~_yZ<$;X?FDJEScLnW^dmfeB19BZE;l;%@Hf&p^Ft^KY#S- -z+n>H2ye)$VI^Skn@$#*OK5NU%gF}JW_*W~x_mN3sG`SYI$Bqfv`o?g%`)y~e_VU1u -zLg?Zd&eeCAv)C+0ISXg`CvN(xh1Dz8&Y!Ny{L!+?Dxun0WSzD15bmnhZ;J%7Y`r;= -zY}=ULYa-Q=K;+IyO+<*?6}dZdM`T50ZNwF+mk8uu -z@RcOentk>XH7(%t+0{U^l1f9Mn4+{F`kpq+deS|mxxMk+(;4T&Ieh)jF;=-012)jd -z=k5s%y@))6*8D!^Yt}PsOMIJIJIdEPo~z`Zocm1VsYt-~%;{%#d$#vlpPbu!I{d5$ -zuf07cumzkDRu=NGuW-Z50R``SyWFoVx}a3@%3=r)8DaVWC4?}tF$5PPTa~OV<@=Q- -zyi(1}RlIyb4%jgJySXm>8@)zSq$mK(7|qAeC^AkCbSbAkgg)<5N=3+6EENNs4uBX^ -zkrLZb_3`H}7IkJ(Tiy&VLt;-`ZtZC7g -z_hm?DA&}x={HxZ8(T-OM07BcCz*+$>gG(iXo4d`|c@9)zhX|SziT5#x#)ok#KHE46?l;F_R;G~Fua%2h0fB&21#YvH!lTo>S -zXnZg@KBCpk7%XXhwj?qs*!Ik15T%B2j#8m@S#$DAb8bq$1NyM+QwY1P^?iV6>c_cxGZ4sMNc;|rlMPyET_2IDb-6+ZJmIkOP0@Hnb}Zu>pIlu -zoU&;nJ<$M#Y=J^v;aQ+PQR}g~Rt9Z|$|W7`v99o}@-){r-Vx+L4QgF08Uhrquv*+LHrjf1d$J0dp=>M`F;L)K##CM9Ks+A3^dqc -zXyApy-~@MJB-eRYqg~XBdhqx=8z+bv6?*sD#=9G}2x(m&0ElcmxSWcdp>gWS=qx}3 -zeXFyz9zzYc92xGDY%4OkH$pJ$WYA3fF-^Dxlcx+-bWQ?*l!h--v64K)I4)zY)o`>*WJ$SE}5N@!x -zG(@s3g+7BESWQZonG7=5aJ}$Qoz}&&MuaozZD4d64RZ8x>24!PQ)y^y6m*=?JCyi2 -z=gH6$64^(197k`(IR}L&r15@C!4NCe35YT)$V?ddgmj%>Ks=NOPk9*<{K}VTQ4ik$ -zLz#7OGWF?moO}%~%phlj3$ZdicMLe|Wci`TC8!<9*hGeQnRJ6+$wy=<6p%r-vkyy| -z5!Gfn-xk>S{EC&K{iTQySk{M1uJdhlgC9v{-uom4;@~i*#z*~9fZ8I#VX(I^{NhHT3MpZ5`Ib?9k{=UrdhVdEA^*Sif8?|mBLcogCQuL>13gp4thdue8d -z_i5>AN#{p?!%XC#?ar{rLyt;mkFiU6J2Ny^3Fr4&1s#nI_!01$%1OV#WRNF;nGJsU -zIFLOX+2hLFGAF@c=Ndv!Bg%!S(A&8v00m2QxCOdZs`6QzheA(Rnk^a>mn9fK@EARc -z;aA?!9luz0Oc-eBX^5at!#<2tEwgHbFz18%;h=uXk=or5sq(!MdJ1jiIryxMcyA@! -za+eR{T^)T?iarIz$E$=ExC%<`PFI0^tDEmbha1r08D1(^=EuA-qWXMheM<5hy?Q_I -zy$(a~T0ECYNPzY76psWQ5+uV@5~_PDW-kIb=DMDcZgh_gWP1J1Q1l5Y(?2%Ad3{1C -zYQ?>Ltv?!L+quUj))h4x4$^oYi-uPr1NtqBW;arwSz9X2*_N$|Hj8NR3tpqwIMIvt -zzbWC?Yt(wt)J<~K$i-2~hQr`Q&)#!HdAseIZV0sFo}LZI+qSnd5JL>*xPUQyG905< -z$``^z+|vHIk9>U)SverCYD2fu)`~*V+uH%*Mu;&EF$$QM4Vagi)E7*F#>X59z|c~F -z!mxU}Y&PZjq{X87Tl(F(i1hos%0?)9=kbnD0-;=`B42u8=>ekq3Bzn=q*t6S}1y}%j2@WS?9@xherd! -zdN5Dwp!T_XPg`B%+Th(#^d^_9vHfmWd%b6E-D`Ir;^5<1Ypah0%&z+2D3l4JOyqr` -zu(U8(_%;-MU%0RboGpJk6#Yqrp>_p}L7omh!VJgaJhV7(n^5Or%P{f~2^D?@)$mYt -z1)r9Yo?PvbY+Keqh2QUh;v(G$6>dGr92k07fchVW;CKj=a%Ww2)LBq^MHB}Goxjx} -z4?%@P7x6Ao0uNNU0u_#Vh7{Gg=m6i3b5P-1)v~;63$l?9Ko1q}pgDx}i%{We0aUdW -zD%^#pjX~2swe48rNww2sYgt3`f(ma#V;s<_IiG^Q&^vV4US5Ouvg5rT;UO#HU(n|k -z0Yah1qnM}1)>a4o-ehfQf_@*L((i7zXoOB*JR*F1Qok>Re((C0e&3qV?*}gHcf0}V -z_X8vJJEDg5`+<@A9SOtwy{U(9BK^KMq2FJ=QonD#tlzsv>i4Zl{oXY~zb{0!m-Rc^ -zUy6ut==ZJO`-k=WwCEn_cjQUx_dN;yexuK@XIQ^)y{zAVi4}#{Z8dn{l1Xq2(um>*6$d4BlY{i%liEw>Gy*v -z{eEDCem`(k{r(cymD2C1^a}lcP}+1^ze|ZW%OmvrKIzTQlzvCvgnnOW*sSXJEtmEC -zmY&Ti{f?phH}(5wRlje!tluH*q<(LLe!rceFRsw<`-b&9OX>HGo1wrnOGQmw!yQKC -zPr3d0_l`;dYQ0*#zY&Q}v60Mix5rs+GG%UlU`r(wI3ng$%{7^z!z<_E2I^Z{g7{l2 -zE1jgjwU+5VjX^$_kA+q0lU_UQ#oXSHwHBS-8VMLc*JZ6m=|Ub(@xjmPH^`?EkUz@% -z*vZ!MPNrZ&D{vbsSanfB>XNxd`SKTK(EL7gi&_3fnKDT -zw+H;VDKW?s$WF{f<|oT)d|_nvA@k`Re@$84<+4xWCj1YajAUg$R1ktn7p|yIL3M5= -ze2{aaAk_`S=#?*!16lO?FId+r2q*{?Ln+5{1O`{z8By}Se$t{gfi|fD8Q6ljV -zjZeph0ydk;D))zT26u99!=ctlLAG+C?WvFReq)Aeu|Z{PY!GmU*DHzF8)b+>hhHHG -zx=k!p?{nZ&8dp$)SYA}b@oJo2RthF$h!c$y5KTU*Yec)TNDYsMe`=C(iW+u^IjWVLqPih@&k@;@? -z)}RiTz~XQd;#oQ|rVR14??4m71#tz)GlX9`^3BQ+Z#Le7n_KY{l`Ih#6Uy8~&&?2T -zG~S@b>qL~}puIg{U8Qg7B$oeHejg`%b(VBBUIe+kc)w`|*u=*ZcE|%LQZ+bQe3{>m -z5cPJcc#!WBH+ldv?mo4#adKZ5P_FzSmB)Cx>NYf?_(8y_sW_ -zhg`Y_*4fvesnJ)*TL%2*<|RHW;fOd!l@WFMSp2TV?*}N)DO!XeDMgR|)C>i%KjSxZ -zka;*0k~sX30d2dS*@*|E?pK`v)VHcL^sH- -z^1yFSSN7$Vq*`wRXwtn0v-EW?067RJ1Y -zsk$hL+f~`n81D!uPz~s8J-TzJ+M|%I8o3iX`avE=b)e3=hmaPBLCP??$Uo+S!vU}K -zgE?l)&1xJ7B*_5zRDUnp2X2kU$b^_mASRfkU0}lb`320%p=wzMe;1g}0C`=a_fG1! -z`GAgq2LMOD2e_cJXilX5B=D^4{}ViO803LrJS!wTJFVhbA>rB2IT^3i1t@bIM}ROb -zkoWOvKpDn6EPGO9;KGa?+E|=#QQjBI96mFktVixCb4?N#ngL~sNmlLwlx+c&A*|kK -z0?Nc3+yKfHK$!?Ali?c3mnX5(KDNOCD9Z^cM}%f;<1+=7}P;s9m6fHFUz -zY=eq>HNMJKw0j33_fB)fU;6R89a&oLx3_9pezh1 -z;{au?fHKTS+sA-1A7s1QyF;=qHOU#|yO)(}6DQV~sv#&@$pJPkGp#@vP*zZ@#_17S -zX%bhNWZY&z{jC(2tKn;u(V`&UsfP86LtHK1p@wzHvs6Td$ZrOetw5FlpiBXj`7{r| -zSpz70NP4p-4(Qqk=rRJzL_nE{`$6360cHJwvR!~O!oD{FWeyqn1-9ITI%Ak)TQEn| -z5pX{uXwMlgdO+EIfHEhb3>dc61SlJ1TTGDNB>_+t29)Ij%F2~B)VBC1=#smYPuH4o -z8=y50S*b8fqQmS0U;)Z-e+X+EbIj`yo~PbhA+JXB9&x^TJ??K;O+ESb(`+j4NT-qb8X!s~xwAetFFF -zp7^-wY1|`PL>(A9+i~|Se$Swe4ilSdk^x!Re>uf88L^nNiV28@il@j5#jHcVjVAG4 -zwJ$Od(F7>l1SkV`Zh(C7-1UhxJfe{rA}hb;W6W&;lyw2h-U5{61Ijo+nV=lQ`)z?f -zI(b}xe#>Xa@q*Z|BYvXlx6uj=0}(4rh%H4`XO(xc7vw+GdmY;UCs{d*wYc|q<$of_ -zpON;zppycMPFCInuH9z36%AA^Q%q@-JQM(w-3BOg0m?c7Wg0+P3!todo=L8hmAPo^ -z0+d*U-(nM1p-g26O~{sD=Kv^!JY#pEsjD2HM$z_4!YV+uC;aT@RHPf -zENfr88}4vjeb819_Xe -z)=4K*I-txsptX!jjkO;5ngC^mXpprI4MO%q^G|5qfHIXA$KV$MlnwVKpbUso9spE0 -z0Ar4l>HgqDYIU}8=ce1=3?bl^{w<(Kv&WGlkXf*<^q)Y5I2W>p(F!5f`h%#DL;tUY>ck4j>g->` -zl<9>jH=uLhk?Rr~?`YgF7Gv!KR%T;u$BON=SR$xCv=xo*SS(qE -z#gf;sSOOo~9TFBxI3e`#-aubm(`gjP4rU0k{Ju~;KV*!K-85i}8pAyLum&A(i3eh! -zep-1<*|?MJDRV;OKW&ar%Mt8vmj`BqhhV=Bf(o##3-JTiha_d5v8q2RN&#B3je3oT -zycp9V55{z@r*K7_*}hisE_X+MDJwDLmg?}Yd~H3}DTy0lxS%O-X)*QR>aB*v&2lbb -zgQ71qGmRPjx)*kY6`5%4FzO)JJ}-&ru20M}3c~u@X&IEBlAs -z{mN~$zQ&4J(Ks^3E(r`K9WZYk=3TMRD@m*EUgH-Gb{EDj#^g@o0357{r^#+2{5qhW17n{9`znt5{!uwibrtK9h@UU{B-SKw@$Ep#%efXQiUonD6yw -z_@6lGHJUsyLJjibT2!gYfIrZW20^xbCS)r~W6IDBuXM&{*K~#+#BXfKXmoIRm?YW8 -zP})9Tw!87L(8H1w(?J+w;|wI<0OyA0%Y7ttwWWe~MRAYl_BZv%d^vKn)_*n9}&4Wh?=9_}ZbLE+4x -za0)0K;;g{9A~Wb3s-V6lT{$E;Swxj1)WTN@xt>rt0lJBZ!jSU1c(MTOtykp_nIb3t -zi}4PGQ9NP7LC+_-TPfOP7OJ(I6*hp1IrPz6#Rf8{Me%*p@Sw`~F -zA%OYCP*5IhN|zO$2(LxArSRS0Uk~| -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 -zqQ -z1~}RqLO#hge=I)suFyuqcDet$eB;)X2`MeK|r?=&^-X?=4p?+QNGUC -zjLA&@d-p@UMtQOf8U~DbGqXT%fVvhtc -zx9maO$I*Wb>0~b~P1y_ms=Z)1O!h+1o>7_E*=MizzvW2Qr$hdws82}Mhgs#c2knu> -zHw;saElQPgd@1Y-yhMzZ8Sx6T;c)*D9gmQKwgSNHZ#j&e%TN)ft>p|b(&V_M^Df+< -z!M$wjvz=iFc!OhK=X%5$<YciXOwZW}PM0+R?UsS8MRhuD0MrfYyZ8NLwV>XZA;0cTL%F5bC(PoGtRswbVbUx-TiIbcDF=})u?kDx<4=BN4$tR<1+7&l#8?$ -z_LNz+0}p74QQhN$&-|wiY3y$g>Su)6C|*8b#UVTME?~tvY9!aDS&r^jj*Cyyo{xk> -ziTqMlVA}mATyofb6z@iyA8}jo6%~{U{BrnSA?G^(=o)POk--nJ!knL94?~~6^P+uM -zh|bs}jjf?J`D*?4x@^myJyLZw-Fr>4Jp%)EuVk+#%x5Tw;zL-j!{%UD0BcKzy^>-C -zZwpyl3SlpP&xb6lk%wWqZua#M0DW`!Zr;jlcnTf$Z~`FR2CBzE_2}8Tpn42cuhfbL -zCaKmO7L?;Nl#-dg8EHfl2$;v-)E`433!eCck{BC%ad0< -z1fM#5nzpJHH#5H!nP%(G; -zhS&+!4z5v6TmyTaawsjqHR?=P=NfCM9mF;64z5MpRIY)ND%YqsC4A}$uJJs$#`DAP(k1tzpo=77lO}w -z&`;nR>%cYYiEAYKNaY&U*t$l2O$!2?AivE{B-hv>t;GEIjB|l!IP1VOZU@hpKayvd5 -zSO5I~#y8ffSexJ*74t4J6MAbL1 -zD8x6&A%B@~yz|%jM#|s*U2F8IJXiYUhxrDc1(!T|Cr9#)&8{C0^9?n81>Xqw_9ywq -zm*}_m!8bN28^I?4cnQ8ym*N{0gq8Ri>dm2Z&K5e`Pew*=qtsC;Af -z_8q=Ex32-;xGTvwUP$td7ye)K4Ug#?d;U^Uv!8f3yiElug5#Mkn_{Prf;2U+O -zk$l6H;2Yk*k8iwi1>eAI-*A~& -zo#}7z4Ug&De4~GuZ4F@0T|@b -z3{zqT^s@rH>{jyEl5dcFX7ELRi0{)};l`fP5{>|XFYA#poI~RdJtE;#X$RTB(_jN* -zUnllGT`%-(=q`pHzX$HhHnPEG0OLuPYd|m`wlYU&PA);=vw7RK_Vdn&NR4MxjwukzO&EY*c~Zs?YOsxz7gNp -ztsJ8;&XnBVjzwJT6J39od;M5!ER-DD&c1G~_Z}o~L~<*=BR(gmb0G(abKpHHd$Ra9 -zaCDfJ)<{=)Zf4aGY6B92Q{8;zOTo%DgscsraW45f+7>v&(2c#ysrqQm7@y8RitqWO -z=!dA*Vswo&$k#XYEZ$1rzBKe?(w^IJ3FJ?HPN}524xh_Q4LzH@C$&Pj8~%&;aZrE< -z2L;qZz!LAD0B$Gp@(uJs)4nXoJ&MYW_}IRu)*nTcjonqObolvkhj0vM5^U^_R;6UH -z-pIPfLI_fxdwm~-a2RO1Q8)E37bu2VnB0dK=Ro82LH`Zyvx!`0pIUES| -z++If~iZtRSwn+~#>-@2y2MqEIHz?CMT64jY42{W|y>L!RE4JprPufz1vl?)0D|-`1 -zs}4jTkfLKJ&hSZvewDL9Fp$Lv&NdU?BE=}xYz>i2B-IVhZ*+W(60A(h!#tl#)_8V -zy6}+(>VnxjsP5@QU8%jf_@)x8b}|E%Q$Xd)LFE{ht+21)l8{_?nuIxR6`$v2@=20> -zK}qxTPUr3rAy}{RhhFbPQsoz3BX<&=fu*AShMrNZ9OH-1Lcx|8KaCZ=?pR#w=X?#_ -z8XsgfzzJ0xId_xiP=smx^?bj&4%_=0(04)xvu62~LQ#1{)X|)8=vh>YsTcPB0DIiC -zEe~PuIL`c-;DZiXO&@_^OEb<4h}L3!J`{xSp=Bm~>tlUZ5%#XvIKzuq`gMv=Z$;zr -zIx9d+AQyG*>wRl5dY=^&>axGTa0QmJqFC0j)0qx9UrvZz6091~SCyyXgDDF-hL<1I -zlKTkUlC%@LjqfuiI -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 -TC6JatS^{Yaq$TiwrUd>s+;lNd - -literal 0 -HcmV?d00001 - -diff --git a/firmware/lantiq/vr9_phy22f_a2x.bin b/firmware/lantiq/vr9_phy22f_a2x.bin -new file mode 100644 -index 0000000000000000000000000000000000000000..1fed6ad65e2b6895f21e1ad81b1ef26b13edabff -GIT binary patch -literal 65536 -zcmcG%3w%>mx;LDiq}e-#&@?Sj#nCjjTw6#fAO(Z~;cB5RZVTRnv?z)YWbaNCXhLge -zbdJ&u)C)R}#}*wxpyJ?}Ii901v~$kPeCG%Q=X~G1?_5};Nxac!&1fo@w)y_gPErcu -z=y|{2hpl_>wbx$PXFa$7vsOcMO~%QSCmTZeUr>%+2)Xve4F<#CLiiv4eZD<;-5N?> -z|CoA?8TIGKGn3a_hbFI;!;;s1scSrSotKqNZ_c7}WG(XCaZ_j3akIjXHymdMv#~J? -zi42JhiH%5%NM>Uv5|P7n9EnCGY7x5`pUJ7u^hA7?H@Gb4waOZMt+L$LDr@@SvOL!+ -zYw@+ps=QWNs|J_lyH;5bU8^kr*UB<=#sZrSW=+`Q(hN@RshhQz1^k>iEEt@^4WlXT -z@M!Iq0)9sQ7p1+QPig;^uYD}w=lzS6);osME{@S``S|H|<{O;(n~NyTIZ-Rk$IqyR -zl&0uu3nyxK=HqA7dP@61Pg`H41@rOq!7fTWHCiijYP<5arv&_LdRh4An}we_wO5_m -z%V-X@W&baQe{c!1Q^U`HIjJod1=W_XI`cnvYL)q#(@FI%%>Ve#{L1|NPn{Zm);m#w -z0j2Kc&&HlP$@hIQb}yfZ2gAR*`o|gGAMzy9UHni&J^vr!Nim7{mv$$*drQxGUOe~8 -zE8V>r{J*pM`#uPN8b9CVaz5G35B1-0TH-42N=%B0p1#umwp6~@;rbi0^}YDH>ofit -zkH7jUpZAkd8%Pil~{rT=t3@&*@As<`m_>h72ZU -zvZx^`abgoMWumCf=XURj4S -zsq2@iYdm%BNnO86UC*bk7gE=Ysq3ZGwKsL`OI`al7wY3!*bT=UkDpRc9T!^H80emE -zjtj>PSoOx^8OP0T@wjEriGn@XzjIwAZ=~CFUB-3o4T_<@yCFWQ5#wOXPB3F=Quui0mU^ooH})iV^WV#W~Yv)DmA1kU4u#usMLr`&8XCZ -zN-;~vpNKP~9DAZYC#Tc1C2o@UdbrvUHx#s6ri7av@rFXDlCvd}*dk~de$5p6MK60- -z82Joqd*X0j9N%=i1vw}37bBCqpE#T`eA7*`#qa|$U@=>)+b#cQvF*z>i^Ig>Yej=$ -zJ1~E#}^FqDR-zmu5{Y);Um!Y2JXYt*Q^j#b8 -zlV#S{7F77zy7OBK@!HVT0gGMPS!?`C~Nt?elEvQSWZ*Va=qP> -z%=+iZIm`RxXh<^lP~9e9^gOy{q_X5r)@WkRtbKSkd!r)d!DSyVQbA56gnl|2Cvvnx^HIB#{-P$3qd(RAz=QY0@!$}sx#swCscq5drqHrAqP3A3CT -zddR{aO5V#zH1di|RE9+xjyJYq!5y>KwAC46GHr^y0-NODTYUoM=U70}r -z%!%+AZVPZ5j_`0}B-g(sKE5Caj}0<9E8_czBeeVKwDTxjLIXg?p^F7K$>$5k`z{nL -z^Ia;a^<7us_k{$bkLaqctfwdwkbc<)@BdIA}d%!+@`mq4;5$6 -z4ROhM>=$_$%#j#OU+fpz1zRGMvN7P1!qESPChKiPljAv&5ut|o6#d&aB!K;K6w5L& -z_Mu-0+Pi{gqWL_9`NT37v5YgYj7?a^0+w+rmN8Z_mUiQ*1}tNK{h;;{Sw>t5Qyc_9 -zV?y;ED&cLT2IaYc{(oAa`ku-+`tg(NyP@EP_JjFGUv4bV*Htjg*I$t78&P0sLfY`A -zh7oPOtT89jhyLD>YV*0qni%hDdfYG2d$6j;wtm)tX&T5g6l2o&Ww^Jy_setl#`^C8 -z|4Bq{3N`vV3i3P<>-ek*%W612X&Y#3cVpbeV{NPmG{Ze!FI#VEa&gbdriMJ^Ym9#{ -z)u&ivd{<7ZE1cV!E1&NyO+57LEG~D38bZXONRIO?8EV-#6yJ>g0(e6Hw8#g&h_BV*y%uKLil&W~y6br~a -zgvbBDVEr`5?d}n>+kR@#*!xjzA&@S)#}?AzkMUA=5m$ -zb6X?_1@@yr#pa7iD5MmHm{5qh=CjN%w;O$|T>vlncgUY30+!&vgZ`(jF|D}R#uCQ6 -z@ZkO2G*5z15)Zogxh(VTt>Zp&7nX)cl!g;*(qW}v0D+-9vqkw_0`>Q!ehc;ad!fGj -zk*yWk3fqp1st60+D+YQH|P6?fCt;pP2vVoWb -z^cm(!t_80%@=3%Q7vh39A4@&|6t^pwdT}rffZsQg+SaPJ9tXcLYE9Cqd7`!e{Ead9 -zO{8aMh)}|4oonjC`2JZ3GO@gGZPFGtVaaD>$v0{XnsQq~P7ocZP}F1;g&Silic&>w -zg@&T$p{N`b#ZZ(NMTzR|@vJ2WhH56q(*4@)O*7MLeMM7l97Sm;sue{s6m=X$sVM4{ -zwm@q_Q6kX-igKeUk$B2N@QMSOn(COdfA+$rnI^Ce4Q!(cMeRmW3sBU6eu|=6Nj+VG -zj-n{=qnsQRbrXuxP?QNpv7wrJd-?v`4xlIpin=|`+fHdKno!g!l9BW+KJBM5niNvZ -zqenUur!(@LHiI$m`ojlLZ0){2Bi>M8Fibhuz#(6*tGzxl^0d)k?>cxo{9e#0g?jr? -zHv^v${LLG8JofCSXZ%gsCmJ_4HTV;|!_KmNW8u-8vh%Y~n=_BbCOK?DYi96|S^lP? -ze9DuLJjh-|*)L%ZDt!N1P~&3-M&G%D&FZ-P&5@3wp_Wk1q -zzt8y~2YoyrsyXwx -zJ3mp`bok$5hOLja8y%V3nm6q@5IGroY+~*;On@>e!_LeXsTB2r^}6W6&&Tp -z$#*WUtiFHYZ?5S<0L -z6Wi=Ydr;dUj76y;%I9HjR!q2>@e78*=@xCaD1xYYA(!lsQ4V8rzUV4y-G2RE(DIgo{gg$w>sD+p5?damjR_WpuB0MMIHr~bq_=Vv5bx&uYr$_3M -z1g%HnrxfTF;WoGOpwR@-jE0;`1!=FwTZ;>`H54UukOOknhyAkObZ0?ArQoNuCcP?0-v=Qh-v#g2?XjP%F|^vJkWuxcd+0;Wt{ -zW^ly9=sDMSlU&i&zx)(z7r2)iS2aO0tZZuFPA@wKMIU3uodtcRtr+Y}r5Ej=fuNx> -z4Cn$h1_49;=O19gEP_ -zO>;whY(ad@)bK7SR0TDWY}gG&jYxor$8z9+NQ51`e0>F<`%MKy?v00Q9}nFZkKLW^ -z_GGo3VTG|f8seJ^;?5~ylKHy@W%WIg2jaTl?C!`tcc=VjtMAwy7L@zr@dxhM-Edcv -zFVc8tQ>5?92Uzcyt1$-m+#l(?H*#;h{J!`y-#w90p{u{Y7lp$esPx?xx$iE#oYH$| -zsph6tQ;kv4vBEQ{Y~^f_y?-JNsMhb;7AI`x6Z#&4?myfnKN<1fhQY7M%o+wiU6 -z8**vbQCiw5Btmj&5k5@O=o(%TlqZ1GQk@2ut2(*llK-dm93C2RlYei_{?P{_Gfl>D -zhHoOV^%?F;*M@bgm$@qqnd>$znPJFuD@%}AqO99MY08?pGcs%I)*;C-canF$eEX7l -znYS-@((~q8*_!FCROr6;cB?hhuj=>SO5AVw{zgilS8lc9l4-SCXWUv|G2f6`Q)tBt -zWnEwarAG{zGwSWWiH`3Doki*>`nP8$4M&|F0<+F4qmk>h-=!&;gwFsMUtXph5EBg*-aN&ft}-CJ5)tr!)v-{_lM -zd$;oHT(kd{+G({$+!=kSQY}z-jVmowjSlF&@F9l(akHR?HG0u0Wt|E1k`bn`H)KH{am{6>a21!If5`K_GEl8pXBvA~K5I_(RxFlipC1^Z0VmzGnqkWyMAxLvidb~E)?vR;a!TS)%B8P?W6<80^ -z3G#G~VNQK$Z^F=`2;Juk4}eofMQCF0C7GE<)7WCtFjip$#*6Vhg*$DUl4;ZMxDLPL -z`BufkM$#)j%;nJgd8>DJu2k@rNai(vb~1*&iCZDQ=SiBNaMOIe!$rYGz-2bI-=xUW9r`y} -z_@-LQR_>PW)t^lYdM9l`V`%!laNOcz!Y8kC&;iHfbDDh2xAJ41E=Y}i1-k2AED0Bu -z1R-u=6#^!;KC4{+Qm8^gxX4eX%ZHruxcHH~v{`(ufmAKzP_l8VJ3uLXBZ?)DG-daxO -z2NqZ%lazItNQZNcOb6l*-&38_)tTy_%4%2N2-;5@I0!UnE0uYJgYhWYS5A_*iM}k84kivJuV!=CP-h6Vx5-MqS?@%xv -z5CQ#VYW{Q-Gul~yz0dA&2Vv)oQfsHGB~XHq<$ocIf-K-6x0Th~d@~(0g3kQND0_Y! -zOv0TXX}@o-5o{qpY-aBE$)SYY8OxsxW(X;v>s_MdSVA>U2cNvVtdp&8h*iPi3kT<>I<1LM~|%8o9^!1|r|e7Y8P{Ym3*jo%MU26O1b`=jpy|+edh58kY|CO=7g$TtMSz~;@RLNm#{`8u#`SC -z)|j_hW>$^6iI;u{Uh;;{OZHg5GcU0wdC804%u8Od3d&2??Px@jmxNOH#7jcfhxByf -zB^#|n6u(vHC7Y}|FL?~_h?n3(yyVd&FKM(sseePfq{*7C{K)!@{!F~2(fTWN{@?IB -zh?jiI|BQsQ`27&SAAy%d2YAWH;3eHygQN@58oXaEpf$L@3?wd0$3z**)X}scr|B|! -zdTkRH^BY -zSJwXd)qa%4wU(70nv^XTxn=COh{F-|%*^f?zCNErs# -z7>XB4v>FZ??kL}*djU+2$-(STPJj4-s2$g3Iwp|Q1d@`KnnXj;R&T3sD`_in1{DeO -z$oPJZkHy*@k1(0#I-oX&xjWbx -ziw#PHr|Ts>ma)}Xq|5|7~aU9jqH!|*c-y5DA#^EEA&LkBSAcBc;tBZ -z2#@_#U?>RW@a30KrBII9{3ZLT{j`f)w8|hv)M)rP`^}yow)9WriaRl>+x(@;J{q(^ -z>V6P5d)Vbdh)!2uR`2fle#?PaJa?FIuJK0=+3(pnY{5@-`A+kflJENbmA+FundZ-p -z`GcQsM>XcJw0UxPYV#C9n?dt;l-BxWef~+^T;%K1Auc>WFv3Wwbz=zwf~d(gR=7X -z?Du)@64JBe+hJJ41g|B#dL1;WJBlCKfLqeD+>dNnSH5{;c`=?h0A -zu*$H+i(3QKEjQGy0M_mxU5jk7?qY}igm7bJMfU#Sn0o(&+SvHoZqxgU-Dk$b_}Vc_ -z(GIh3LZrCa4CB2B#(NQr_X#lG55RbLz<7r`W{N%)nA8EILQ-B0XUK+@j%Z$QRO-)J -z-<`;jVm*0KReS7?F~RWtn?`+TawJM_wrB@z+G3)0OpZ?T(7`A5846DJny19r5a{<# -z1aB=km+0#GVIbTiRY*PC0|)A$n@8&;n{r8nDal=T6{|Tp3AQU|jy%Sq*|BVxcD>#0 -z1V6B7PY}{K`U7LqHe=2Uzt`+19?Vh%8|)6!HO#NV`hnsBxty;oP=?vEa8JHsUW}WG -z_?-l;1on;7`>H%t&o@nRC`GmlV9OjzmiG%?UpM3SA}mO+#=nqjLwg0AW699UK!Q!i-YPUeganb -zI$UxK1UQdaAuGg?CMv*VVV-hl{msy6D}r@Rfl&o@(w7W&1jLos%l1(Cg@C2K(*T)9 -z<9}upbGJmF475b^43gDj@B`GaghmMJm?Blw_7}qle#7b$YS>Q5Gx$Ytxe*t(Jz!;Z -zQchji5_*c}2DTxB!;00kPXO)7fW8@Gn2f;Ul1%B#x+b6`buG~!B1_1bT#Iuaj{AbhG75PZoSt(YguJVV -zymPDzI>WGx$e_pUg8M+C@I3GTUv?^n^*s9zl2T;E8bJdTTXk)Fl}8fAz2c!+CnXIq -zhHk1dn5rDvwM&?c&oA=GgmafFPR`4@cVQ0@!2b@A>+HfB5lvkRh)Tc~PvcJKI8(3RF161zf^ppA#v; -zm7@i~S#ml)FkJv(2{)PyH(Dvv{Ws835et^nd0d9Rn8UW=BlzOdwmX>1D=_z|k0$Vk -zJKze?*h&d8qfB0fL|hmy4qWck_(=Fc?vnUu?{RiFd<)dEvWVWi -zh|IvUx7RO+uWRyv9^Gz2XW{N+GJK4soxK7>Fd$!kRwh5-IT}Rp4a9!vd_x~s=xJaP -zAfbL)>S+wTA!)leP1# -z90Tapm5|}%7PJbMV7#693B5!3MnA-#3()x -z?@8Bg=MN}58QLSjFDtXzKA)*ZYzUmWCC|_j_23uqtOR&A53<5l4_V=ulN=j#GdVWk -zmoyeG8Vi(jEFsF<1CojOS|IFt3i#W042S-j?G-f@gINs52p;=Be7WGUj|5*4wNXj> -z`>_bV+)rg2G48C5Gg5lPP@2@9VBml1pBW_oOGy5c-{dO!UvicFFGft+Ss%K`A`1rG0Jqv|63wukpE@1aK}X8j`5}3F{$zdtbZ -zyUPDAlK*SIMg9*REdTeVGGedU5?)h$p1$b)P;MJ{~J?&4wC=tN&Y*%C*|W)d@Na -zL6v?J@?S~Ie+;R}KE&u-jlX8&!fBhQre>%zkGIE0J^8XJ> -z`Hzb(|68w+|E&Soosj=!kpCVX6F_^?^8dk<{C^`U|9^Td`H$77%YVKBg;3-e~dlD;19@ujJ&c`A7}DYKMX(hLcSJhm;Kb`d_A7$>3Q79^8ozR3wW(f -z1HB~u)G24gWk0o9f_>D?O32Cq5BZMre~R_H%l}gAwdMb0q)*lTJ|zE}t*CsE{MW29 -z+iBJ1|1K-$p5*`YR`ASkm;cxDeSMSse-ZuuM*08U{9ZC!XGJ$i{%?f)OT#_M|4kgu -zFZL+4o#g+o((?b$AmyZNho_w6|6lN&MBgy|K -z;l9(@53IWU{~;1d{^LUO|EZ+>f7+_c{~y60n3DhG>l={&DC;WuKXZ`$KQezn{)euV -z|8N+mbOXuSov?g&bcrKPKfb;=uPu1Pwgm -z+vNWdhD_fg|I>NCN&X*!{Qm<(dj`w@wrk0MIIQa-D+bB`$5`kB9_5hyZ@p6f -zw_-Sw^1nMN|I5@dgc}UV|Bnace>5%skIeg;{0{}-ewzZnOf}qZNqpv8?0+}x|IAhL -z1Ax^HfL5#q0P!&6fw8Y%3Gogzeuf+7{W6&Mt0+Bl{-U{*chOuOXPJ*oPT(yo$QN*1 -zg>?olZu-VKV}5xWug@&Gt%AOpj0}VFl_EO|oN}99M@^xD9@ngXOhy@xkUt`G&4$P6 -zJGdIGg)~qo^r$i)YOl^90$-0+&v7x0qK?jC|6GfdVb_cnCi9% -zK7`J7pf1`Nh?a~He6US7$WYP|vYZ8YljK0c23#`Ru|23-DrXd{6N=!s7-oUr0=Mdf -z$gtwS=bz95u1RE5!adOe_k;xZL`R_M;-g3gwmqwGcM>m{p- -zRoBfRjc@iZEV-6{VOrY1fHgvXfeU22;}*L7MG;G-m-P0OjXxc7yy*0l&>Q)17(f~; -zKyhu~Wb;EFnfY|3h{Hd?eu^&_NE$+)S`iWeypt8mFqmD~vtk55?W|{W?T#rygH0Qy -z^DL)L3*ZKJ_Omv~S-F$J{i3^F-h|sF3vQQExLx|-cIk!Ng~9Ezw+mrsR=U8L1jjZ9Mupbfqf`_>}JBY -zePO{5wOypPK&;ytAb$e9{E$aZTO+t* -z-Ex04x-*aoTjNZHq}`l}P^9RH>pgH|!yYl%q5un$_f8w;<~$&<`aXPMcNn(fb}YVm -zfMWSoVDkutD1x8t&vwTz^)^Re3H%n>`n2#^&_+9CyU7v=^GjGZPm+yBd{_6i05k+1 -zI0@SpWca(rq;U@Nca>PQkwm`~Em65;(-7D}*)9p9A5<$;tfeNkDXJeb7aQ7A_>4Asa`^Q2TYn2#(G)nvhCQ9=F`;x7+LTGk^d -zlS&_=tdOeody|qmaBoB(%Or00NGab$2C~dUljhSmfcMciVE?x!+kx9zTTnJ!1hD`5 -z8C(PbifM+6;DQ9hmb4MP+Ik#b0+4?v`cGJ`?j_*Em7nr`x@-+&sXwP7005As_yWo! -ziHr-<%zKgn0Waa*%g}eigpKS$dvcjW!c)JTD`|b?u50P&$~2fO6ZPF8+t&XTbb`bT -z$_;uuDMaB${5tXL!namF1b0L6Ym+pap)agm3cWWEnFliAl@-6JALDU3vlo>jS>O(( -z04`Y#ZM50pj7a(*hrvF6IEbY)>dpy{3=ssV78I%Q_Z3g_M;nzXlIE=E9?S8~K}i#j -zYyIq&J~mxC)z#bWu$&T$uqbxJ*cR%35O952CoRT;+=WFGz=G6j>Kbjz80j`tj^)VM -zQu2eCyhdf5G#+W*k93}ti#W`Q%4)sOBKr9N`NE(IhX=RCg0`q*DOTugas4XDfKbqh -zCfg+~vyP(@6iNOXGm0EffQSYrD6?Yf_a&4$kxfeas05`%nv6vLp9)LWX$JK^5Jsh& -zP-#%~Y?+bm_yN{j<%nXn0J6>n^7FTJu;q|xBa6`pjN1rjeG$g(X?@(#ms~wArkLuu -z1R5@(di%JTr2Xb>Zt`ro+2Qy>P!z#8)8ji4ePYWct1sx%Fm!+d3g$~~6(9u=d(1kI?QiLrb+IhHU5>%jZR5q<`KQc0LRScV%H7cLmj -z44ZC8fw{n(l1U>2+ZsoFd?^5*zS7?Cewup_u?>A&ihGLfD^|x9Wd>abEZc1L_S3el -z*w)hw_5lmD^f-xj@6AuDD -zz=2SqX`>-zGi|MWybV0rZg(6Ef>)2~`B8v@9KwTWOd=WsIq36)X_3H^IHJrIns*20 -z9kg~c&5H`UFILAFArfmr!VmdK#9M(8K!TPSin#?5^NKGtBrtcm1QuptmJo&|OQyKs -z#bA$2{EJ(H+{LhQs1#r5v1sS!8XZ3mIs*WEEn3f0kOiarVchuP+zdi@P1;5;QGCex -zw9iz7aU*~t!!T|*GATdR*X|rXUfGxS{}C^uwoz=208M=ubN5S7GjR_%* -zFN2?XG5DkRi{u)lww04joJIX(-0!7LKNtcBhCsv+sL9yK$HxhXjihmzsE#Pc7z=jC -z$skw=d})F*N7*Mr#BsEr8#+ -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 -z{?-INC -zog%+S)b7T*q;Em)%D^}(LqGZm1L~dEbhD`4MD(~GuSdQRm^a)HO=DifBD@l?`1wv_ -z-4%3&hJtQ%x{6w!(`k28<~$Y6Nb)qyIoJc}V2MO^!s`UwGK0p+PQDo80Y)#EY5!~| -zWO!2c-YV%T1~dl-NlrGAPDAiP@5ACPCK~wN92MPGQO+EqV~`(q;bM^eUosy8bU(-D -zF+UEPL7L?Ru3Gnrb5P&(G1KiZ`0Vkm8N3E|m=pB4l-l%#A3kq1nPZxXgj{qK7tsNx -znd8Kh{6q_Tnmr|GLn{+4D7Fp7Q#DVSK?B|h-=4e3muoEWf(oV!pPD&IujyuID3s3X|xD|8EdJ^&t3Z3ZGgt -z2%mZo_|)MfK6N;aPaRI-Q}xy)K6NCGPpwJgQ-GCI_|%cB@ToQ5j8BcF{bJM060F|Z -zav7gG@O6CZKmaN}?f?7bZ*kKXeP73v;3~sucKirbk@>H~uYjW?db|Mikp>f+c_v{W -z8G%LEG9e~yW}F2D18*e2BH923`Jcd++Bwqs=(jwncGE)A8%m_h?-sb|$rt>&M8mmOq``+XZ?`#?zpoG+zq9BCsf-8Mbkf -zzuI-I25~ZGJ7|o2y1;A_Fe@2C|77f5vr>vx%aSp-lfl2HD&uhnu*i&996WQSIk|_5 -zf-P_wC$O5GR)oUf{vz(5rx+7G?v`v-RKrot9#n(s24PaE_!e>#^B1fdwsBE$0+{o5 -zY~7-J6VDvDH{$srEUS$f2xP$)E(&3}#{RAK)<=*|^>b|2x>h`i7hn;>Nd$zFaDSHc -zODpgO>L#zooUKgFS(Z|*tV*^EPTzab6cPU2dvouzYWL#-7mN**80AjuUHbiS_=|nk -z2lRUnXy$G!5gX;PDb-dg0PbIf`>Yz=zgzw)=>FWd;r>1McHr&5!u=bC`*$zgzYOl* -z=ivTT;r>m){hNUMHwO1_*s$g8zry|d#M^&`u68HI^7PBtHlxRKp?HcP_&(}`zOls$ -zeU-B(tQtbPWh@!~I5Lob7#9J{s1EL54)<>sTyR}ht-_c1jIW8+ShZSY(8Bz47hhvt -zjKLm+q3xx9pvWYKh5||dFk+C<6dgmug)p>x70f2?2}9e-Xb}NJBcJ}w#1k-4eoWLj -zY`$|{EK|RSI?6Fugwq8w>-K75-P>LS;$i)Zfa-k6$}{Vh`_Dw*4%`gj9IQ_B063Qc -zoFgWI_J4U~0OzTDUp;{H0D$wYebKiu*MG(Ebpv?DH(KsatCs2}LpS+P0p0;#yQ06_ -zzEO3_34z94O&{1aHoE{4@x1 -zp8;~84%&T919;cLwpk^BcL+67EusG^Bl_0Dhsqe{ko;&^0$c@nhpuC#xz<59u9gAb -ztwEdUod)nO&K|TT0N(Y(arP>}JHqjh{u6Aer1sc(b)+T&;s9-|w4q!A?=moO$@tNk -zz#v}^q8p>u0lXu-uo6Ze1Alh|pL+n4i3`JpFuVmxo?WYBc*w8E%#e*3uC21w1H5wp -zyxR-#t{&i>1K=I$TE8k&$JZ|ny0$LdW@`p`M`!Y#0i&G;V;hKbk#zmN+zLpx}lPUaP;B%C}C7U65`4Q~CgMOTjgV%aOfe_5# -z1i(856{-O5u8xZ%+k^gnoBc5epDOuo_*BW&_*98Ag-^jGxB{P|=da^aIK$xU_*BVN -z_*BUZ!lzKc06vBLuj5lCmDj+hN(SRo)P}F&Q%D@Zr&9N+rj~p=J~d+ipTd-+@TqT) -z3q6>^r%nWV4iqf`KDB+RTCR?{ZKJ5I)bXhe1NfBx3VbR?_|!XJ!>9ZfZN^}{CW%kI -zcNIQ`TCc*Vx^#T%y#RxblftLY4vziB`XhYmh>lPF;hXU(kYoy<`olNkQ|UY%2vQ{s -z>uP+8-lGbvIl`y>SKw1t;8Vu}Y#Y{_j!&V#U&p8J06rB1K6OVDpCX=3_|zTO!lzRD -z&Nc9<(NGy(tpO9&@hSZs;Zv(^Xd>ZL+oAR*@hLER(pO~GG8mugA$Jw&^mNvzf|{Vh5l>Y)7VT$vadq6Sr$fNtcdK9ZKO-hyK6gQ^!*H)N{W};ZweE!lzb)Ujm=H -zELR8NQ?FkOpMvU1_|$_};8VxHBR++W)YV{> -z>gR*7sW3jinlB`AsV@g`DQgm!s!!ok2hzCI0pLbOV)UX4qp1Mk -z6!u&iM1WHmmtKTCDJolQZ2~y865tf+7dWhiB>+xU1DrAfoN5L*6$3c68{pI#fKyoj -zr?6G`7>}*CJPU9t4sfaiun_F?SPub~jf|99sAoazHO^)A4v -zmjOa -za4OC=z_yOanU%34_PX~2#_92ugIbV39;1rxI;hEBNU2!9>m6oZCG=U_sL -zh-ZQKK!2vA%Ig4i5IY1>Yjl4aAQ1ih -zW-qI;Rj51!2*ihT>AnQEz@gGI1xhk*$76aos1t63pDn-q>ThLy`%eKLBn+cMwFug0 -zRhficp(-b;uM6mP3W^m2t;@N~?Y9vek<`;KV2@QNUr&4-Rsh9bK_pt{B)1Ae*9PH+ -z`By4*^m4W6HefNgT*hL~(iT~Y=f@h+&y+pO??bEa6*XV#Oj$hLk73?`sdfR69uIRSbEe;Du(&}78XZ2%wmKKUTNfGa{H4DNA^g^t0&6iQ-n`iu%m -zS{Sd>LPx&8g6$c=E?#79Ln|$QARsRa+WP@+u3l}f^W|1WyuRE;*?waI!=PbnvwR=Q -zrU*s!aZ&`%wz#FB0(c5g6t;)Hb>L2FsfY|N4@=*yxvDa#en~6(h{l@`ke6ZXJg?7N -z2F^!nwpJkygyvt=eqIi`#$>oSV4Dp}#qcc9r;wyiQyuz_@kQVBKXlW2J+u=zDToRD -z0c%HRYtj;x8zW2ABEZKkz{eegbpt;B>hjr&`W$}6t1)YLh}x>lbGQ=SdpKDKV$8EX -zbkeuT^%bRy+62PX9>#r!<{EM&&J^o59$p?aZ~ajF*-k90MI!2!mMv9_wVoruc6-v; -zZi`Ou=opoPJOb49qJes(51q>+u)Ka7;wT<;lEGZ-k8ms@O+QNq;IAoEV`E;@2}52< -z*>2V89OY@1%T)Rn>xu(fq;>T(((}~fC0I-COO2?IuyD(}flP!MMYVCSS(0^3V3vOk -za7r7#tla{bdfB0!Jx6FP(FHG>w*=or=sjEqIQxjLA>RRXP#x36y7MN_&dSuWKp4-G -zZXeFaGWt8`pW`hv=0`^gW;sy&>$<{){j2e2z*>&#C>%0Ly4iN{ZJo3=|V!Edo -z#nlUoy_w2-mE!+yn?D!(uDrz*n^;`2+&W*LyA0VD&qYG!=GqmMXEx#x4ek=>!eWDa -zak0U>V3NUGY*?_MaK`PG$XhcXc~OpDKG}22ZeO?xv4*$Ox5bsqt%R51HWML?SG-&I -zz+9ZeTD+dlY!MM4q5h*sou`U(5xLh&@q+kydXoD8RK;#>7jBKi&xD&3x5oP`5V&U1 -zhIrs3F_61IIHBHATpK%qZQXusdaO2S%OVU{-s!5I1{c -zb^j2Ug>3~wI~Ey26lc*M8C0E3@(st+-IUBLnlMZ;q|c)CS%-nr;ZHprPE-ikJvK|O -z5M)Zj5nbK4w$F+qz&*wg3_*J`Ve(K+LjO%NdvzdZQg4l~j#E_Tu^53v6o$@k= -zF_yX8ajxy?fjzWFiqksr7;}cRTkUqavlQ@)w-bSp5Q8}tPPsH6wkY|#1o*7 -zM7j>R@mRWkFX~72cGP81oHnv$^KkUdI5+m-Wh+*OYT(BTVeb>p>lyy7=k>I~Cwa~D -zdJg_h^lidGgU)_}6Ky+i&7|=Q0;mHWZ*K~WsjQQXbx2JFQ*lg=w$DA> -zgDn&DVBa1bx>=X7A&j$8y -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 -z$`-lq1;?3PKKFc10*gk78 -zeg?~4<5l^&KludKgd#>Xeq!;6D=Kzl4a8;a^kLz|M&aXynAS&mv5*iRmaug-SQ0TC -z>&h$?u@%1ab$tn)4hDW~QxF?zY>%1fz&@LkhwlJNk5F?@TOsf|1*M{Fn;LDC+CPP2 -z-F?($urWUa1bxc)XCvH0tx7jv7}vrpPsj^Cz#@Hwwu+}6@n!M9H0YCdI34jFvFGYl$&5dxv2uRyhsE4Y -zagjWVpW?;4=TosH -zG9p{giOyhkpe$Sys)8@k7<)aqX1A)-%k|PvVvVjSQr%t^N^6#vU#kv267PqrLe)~W -z+Enb1A)di!c&PGqePo)PsvO7n9A@(-yIJfC<{)kRq_#KS&Gm78N0nnrT71B!4=i>=^NY@-**ea1PE>h#s}y^Ub#%nGT19qTg-P@m-#aEr -z;0(-m-n-gr#=(+XDRvg$JBr~%9P0G&Cgh|{swUjQDdnB1N@sn_omu9R*!yYtbS&H~ -z9qtXJn+%DTtM2~rRHn($EL}YuNQX^cmcpN~2WT?eeTV-h`N7dId&@5CCe-DR(p8OyO(8@90(VR`Z=UT;XMjMKkbK -z+(B|$=9beZ-?=KM0$LY3WXfK=qS+wBgY0xK{Kw*G(xM5@MH4cbTxiOmiN&Y!^`bqY -zzFKQnY|0YEX-MmG`TBUd;~%6xxKgLQEdi%2S;E&P_wAxbNwe;oWIX*R2dRws@N^KQMyQsA(ryV`tNxr%s -zl!+yDX+J4D(cAn`{As>kfIU-6ouOOHf=2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la5CI}U -z1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la5CI}U -z1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la5CI}U -o1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+Sp|33o%0>w{+uK)l5 - -literal 0 -HcmV?d00001 - --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0109-MTD-lantiq-xway-fix-NAND-reset-timeout-handling.patch b/target/linux/lantiq/patches-3.6/0109-MTD-lantiq-xway-fix-NAND-reset-timeout-handling.patch deleted file mode 100644 index 0b2ce06e69..0000000000 --- a/target/linux/lantiq/patches-3.6/0109-MTD-lantiq-xway-fix-NAND-reset-timeout-handling.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 5967e3171d56b7c433587aa418b87ae7fea02f28 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 22 Oct 2012 10:25:39 +0200 -Subject: [PATCH 109/113] MTD: lantiq: xway: fix NAND reset timeout handling - -Fixes a possible deadlock in the code that resets the NAND flash. - -http://lists.infradead.org/pipermail/linux-mtd/2012-September/044240.html - -Signed-off-by: John Crispin ---- - drivers/mtd/nand/xway_nand.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/drivers/mtd/nand/xway_nand.c b/drivers/mtd/nand/xway_nand.c -index 3f81dc8..4731300 100644 ---- a/drivers/mtd/nand/xway_nand.c -+++ b/drivers/mtd/nand/xway_nand.c -@@ -58,15 +58,23 @@ static void xway_reset_chip(struct nand_chip *chip) - { - unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W; - unsigned long flags; -+ unsigned long timeout; - - nandaddr &= ~NAND_WRITE_ADDR; - nandaddr |= NAND_WRITE_CMD; - - /* finish with a reset */ -+ timeout = jiffies + msecs_to_jiffies(200); -+ - spin_lock_irqsave(&ebu_lock, flags); -+ - writeb(NAND_WRITE_CMD_RESET, (void __iomem *) nandaddr); -- while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0) -- ; -+ do { -+ if ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0) -+ break; -+ cond_resched(); -+ } while (!time_after_eq(jiffies, timeout)); -+ - spin_unlock_irqrestore(&ebu_lock, flags); - } - --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0110-NET-PHY-adds-driver-for-lantiq-PHY11G.patch b/target/linux/lantiq/patches-3.6/0110-NET-PHY-adds-driver-for-lantiq-PHY11G.patch deleted file mode 100644 index f3a31cd348..0000000000 --- a/target/linux/lantiq/patches-3.6/0110-NET-PHY-adds-driver-for-lantiq-PHY11G.patch +++ /dev/null @@ -1,228 +0,0 @@ -From 2fa550e1ca132377ee4910eaaf331a257190b75e Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 22 Oct 2012 09:28:30 +0200 -Subject: [PATCH 110/113] NET: PHY: adds driver for lantiq PHY11G - -Signed-off-by: John Crispin ---- - drivers/net/phy/Kconfig | 5 ++ - drivers/net/phy/Makefile | 1 + - drivers/net/phy/lantiq.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 184 insertions(+) - create mode 100644 drivers/net/phy/lantiq.c - -diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -index 983bbf4..a7ff1d2 100644 ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -102,6 +102,11 @@ config MICREL_PHY - ---help--- - Supports the KSZ9021, VSC8201, KS8001 PHYs. - -+config LANTIQ_PHY -+ tristate "Driver for Lantiq PHYs" -+ ---help--- -+ Supports the 11G and 22E PHYs. -+ - config FIXED_PHY - bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" - depends on PHYLIB=y -diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile -index 426674d..3aa92bf 100644 ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -23,6 +23,7 @@ obj-$(CONFIG_NATIONAL_PHY) += national.o - obj-$(CONFIG_DP83640_PHY) += dp83640.o - obj-$(CONFIG_STE10XP) += ste10Xp.o - obj-$(CONFIG_MICREL_PHY) += micrel.o -+obj-$(CONFIG_LANTIQ_PHY) += lantiq.o - obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o - obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o - obj-$(CONFIG_AMD_PHY) += amd.o -diff --git a/drivers/net/phy/lantiq.c b/drivers/net/phy/lantiq.c -new file mode 100644 -index 0000000..ba4d7b7 ---- /dev/null -+++ b/drivers/net/phy/lantiq.c -@@ -0,0 +1,178 @@ -+/* -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * Copyright (C) 2012 Daniel Schwierzeck -+ */ -+ -+#include -+#include -+ -+#define MII_MMDCTRL 0x0d -+#define MII_MMDDATA 0x0e -+ -+#define MII_VR9_11G_IMASK 0x19 /* interrupt mask */ -+#define MII_VR9_11G_ISTAT 0x1a /* interrupt status */ -+ -+#define INT_VR9_11G_WOL BIT(15) /* Wake-On-LAN */ -+#define INT_VR9_11G_ANE BIT(11) /* Auto-Neg error */ -+#define INT_VR9_11G_ANC BIT(10) /* Auto-Neg complete */ -+#define INT_VR9_11G_ADSC BIT(5) /* Link auto-downspeed detect */ -+#define INT_VR9_11G_DXMC BIT(2) /* Duplex mode change */ -+#define INT_VR9_11G_LSPC BIT(1) /* Link speed change */ -+#define INT_VR9_11G_LSTC BIT(0) /* Link state change */ -+#define INT_VR9_11G_MASK (INT_VR9_11G_LSTC | INT_VR9_11G_ADSC) -+ -+#define ADVERTISED_MPD BIT(10) /* Multi-port device */ -+ -+#define MMD_DEVAD 0x1f -+#define MMD_ACTYPE_SHIFT 14 -+#define MMD_ACTYPE_ADDRESS (0 << MMD_ACTYPE_SHIFT) -+#define MMD_ACTYPE_DATA (1 << MMD_ACTYPE_SHIFT) -+#define MMD_ACTYPE_DATA_PI (2 << MMD_ACTYPE_SHIFT) -+#define MMD_ACTYPE_DATA_PIWR (3 << MMD_ACTYPE_SHIFT) -+ -+static __maybe_unused int vr9_gphy_mmd_read(struct phy_device *phydev, -+ u16 regnum) -+{ -+ phy_write(phydev, MII_MMDCTRL, MMD_ACTYPE_ADDRESS | MMD_DEVAD); -+ phy_write(phydev, MII_MMDDATA, regnum); -+ phy_write(phydev, MII_MMDCTRL, MMD_ACTYPE_DATA | MMD_DEVAD); -+ -+ return phy_read(phydev, MII_MMDDATA); -+} -+ -+static __maybe_unused int vr9_gphy_mmd_write(struct phy_device *phydev, -+ u16 regnum, u16 val) -+{ -+ phy_write(phydev, MII_MMDCTRL, MMD_ACTYPE_ADDRESS | MMD_DEVAD); -+ phy_write(phydev, MII_MMDDATA, regnum); -+ phy_write(phydev, MII_MMDCTRL, MMD_ACTYPE_DATA | MMD_DEVAD); -+ phy_write(phydev, MII_MMDDATA, val); -+ -+ return 0; -+} -+ -+static int vr9_gphy_config_init(struct phy_device *phydev) -+{ -+ int err; -+ -+ dev_dbg(&phydev->dev, "%s\n", __func__); -+ -+ /* Mask all interrupts */ -+ err = phy_write(phydev, MII_VR9_11G_IMASK, 0); -+ if (err) -+ return err; -+ -+ /* Clear all pending interrupts */ -+ phy_read(phydev, MII_VR9_11G_ISTAT); -+ -+ return 0; -+} -+ -+static int vr9_gphy_config_aneg(struct phy_device *phydev) -+{ -+ int reg, err; -+ -+ /* Advertise as multi-port device */ -+ reg = phy_read(phydev, MII_CTRL1000); -+ reg |= ADVERTISED_MPD; -+ err = phy_write(phydev, MII_CTRL1000, reg); -+ if (err) -+ return err; -+ -+ return genphy_config_aneg(phydev); -+} -+ -+static int vr9_gphy_ack_interrupt(struct phy_device *phydev) -+{ -+ int reg; -+ -+ /* -+ * Possible IRQ numbers: -+ * - IM3_IRL18 for GPHY0 -+ * - IM3_IRL17 for GPHY1 -+ * -+ * Due to a silicon bug IRQ lines are not really independent from -+ * each other. Sometimes the two lines are driven at the same time -+ * if only one GPHY core raises the interrupt. -+ */ -+ -+ reg = phy_read(phydev, MII_VR9_11G_ISTAT); -+ -+ return (reg < 0) ? reg : 0; -+} -+ -+static int vr9_gphy_did_interrupt(struct phy_device *phydev) -+{ -+ int reg; -+ -+ reg = phy_read(phydev, MII_VR9_11G_ISTAT); -+ -+ return reg > 0; -+} -+ -+static int vr9_gphy_config_intr(struct phy_device *phydev) -+{ -+ int err; -+ -+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) -+ err = phy_write(phydev, MII_VR9_11G_IMASK, INT_VR9_11G_MASK); -+ else -+ err = phy_write(phydev, MII_VR9_11G_IMASK, 0); -+ -+ return err; -+} -+ -+/* TODO: add vr9_gphy_22f_driver and drivers for external Lantiq PEF7071 PHYs */ -+static struct phy_driver vr9_gphy_11g_driver = { -+ .phy_id = 0xd565a408, -+ .phy_id_mask = 0xfffffff0, -+ .name = "Lantiq XWAY VR9 GPHY 11G", -+ .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause), -+ .flags = 0, /*PHY_HAS_INTERRUPT,*/ -+ .config_init = vr9_gphy_config_init, -+ .config_aneg = vr9_gphy_config_aneg, -+ .read_status = genphy_read_status, -+ .ack_interrupt = vr9_gphy_ack_interrupt, -+ .did_interrupt = vr9_gphy_did_interrupt, -+ .config_intr = vr9_gphy_config_intr, -+ .driver = { .owner = THIS_MODULE }, -+}; -+ -+static int __init ltq_phy_init(void) -+{ -+ int err; -+ -+ err = phy_driver_register(&vr9_gphy_11g_driver); -+ if (err) -+ goto err_out; -+ -+ return 0; -+ -+err_out: -+ return err; -+} -+ -+static void __exit ltq_phy_exit(void) -+{ -+ phy_driver_unregister(&vr9_gphy_11g_driver); -+} -+ -+module_init(ltq_phy_init); -+module_exit(ltq_phy_exit); -+ -+MODULE_DESCRIPTION("Lantiq PHY drivers"); -+MODULE_AUTHOR("Daniel Schwierzeck "); -+MODULE_LICENSE("GPL"); --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0111-NET-MIPS-lantiq-update-etop-driver-for-devicetree.patch b/target/linux/lantiq/patches-3.6/0111-NET-MIPS-lantiq-update-etop-driver-for-devicetree.patch deleted file mode 100644 index ff857ac51a..0000000000 --- a/target/linux/lantiq/patches-3.6/0111-NET-MIPS-lantiq-update-etop-driver-for-devicetree.patch +++ /dev/null @@ -1,807 +0,0 @@ -From 6db31b14d4998f480349dd5f1ef83dc68a1fab0c Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Wed, 24 Oct 2012 19:50:30 +0200 -Subject: [PATCH 111/113] NET: MIPS: lantiq: update etop driver for devicetree - ---- - drivers/net/ethernet/lantiq_etop.c | 470 +++++++++++++++++++++++++----------- - 1 file changed, 333 insertions(+), 137 deletions(-) - -diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c -index 003c5bc..dc5457a 100644 ---- a/drivers/net/ethernet/lantiq_etop.c -+++ b/drivers/net/ethernet/lantiq_etop.c -@@ -12,7 +12,7 @@ - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - * -- * Copyright (C) 2011 John Crispin -+ * Copyright (C) 2011-12 John Crispin - */ - - #include -@@ -36,6 +36,10 @@ - #include - #include - #include -+#include -+#include -+#include -+#include - - #include - -@@ -71,25 +75,56 @@ - #define ETOP_MII_REVERSE 0xe - #define ETOP_PLEN_UNDER 0x40 - #define ETOP_CGEN 0x800 -- --/* use 2 static channels for TX/RX */ --#define LTQ_ETOP_TX_CHANNEL 1 --#define LTQ_ETOP_RX_CHANNEL 6 --#define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL) --#define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL) -- -+#define ETOP_CFG_MII0 0x01 -+ -+#define LTQ_GBIT_MDIO_CTL 0xCC -+#define LTQ_GBIT_MDIO_DATA 0xd0 -+#define LTQ_GBIT_GCTL0 0x68 -+#define LTQ_GBIT_PMAC_HD_CTL 0x8c -+#define LTQ_GBIT_P0_CTL 0x4 -+#define LTQ_GBIT_PMAC_RX_IPG 0xa8 -+ -+#define PMAC_HD_CTL_AS (1 << 19) -+#define PMAC_HD_CTL_RXSH (1 << 22) -+ -+/* Switch Enable (0=disable, 1=enable) */ -+#define GCTL0_SE 0x80000000 -+/* Disable MDIO auto polling (0=disable, 1=enable) */ -+#define PX_CTL_DMDIO 0x00400000 -+ -+/* register information for the gbit's MDIO bus */ -+#define MDIO_XR9_REQUEST 0x00008000 -+#define MDIO_XR9_READ 0x00000800 -+#define MDIO_XR9_WRITE 0x00000400 -+#define MDIO_XR9_REG_MASK 0x1f -+#define MDIO_XR9_ADDR_MASK 0x1f -+#define MDIO_XR9_RD_MASK 0xffff -+#define MDIO_XR9_REG_OFFSET 0 -+#define MDIO_XR9_ADDR_OFFSET 5 -+#define MDIO_XR9_WR_OFFSET 16 -+ -+#define LTQ_DMA_ETOP ((of_machine_is_compatible("lantiq,ase")) ? \ -+ (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0)) -+ -+/* the newer xway socks have a embedded 3/7 port gbit multiplexer */ - #define ltq_etop_r32(x) ltq_r32(ltq_etop_membase + (x)) - #define ltq_etop_w32(x, y) ltq_w32(x, ltq_etop_membase + (y)) - #define ltq_etop_w32_mask(x, y, z) \ - ltq_w32_mask(x, y, ltq_etop_membase + (z)) - --#define DRV_VERSION "1.0" -+#define ltq_gbit_r32(x) ltq_r32(ltq_gbit_membase + (x)) -+#define ltq_gbit_w32(x, y) ltq_w32(x, ltq_gbit_membase + (y)) -+#define ltq_gbit_w32_mask(x, y, z) \ -+ ltq_w32_mask(x, y, ltq_gbit_membase + (z)) -+ -+#define DRV_VERSION "1.2" - - static void __iomem *ltq_etop_membase; -+static void __iomem *ltq_gbit_membase; - - struct ltq_etop_chan { -- int idx; - int tx_free; -+ int irq; - struct net_device *netdev; - struct napi_struct napi; - struct ltq_dma_channel dma; -@@ -99,22 +134,35 @@ struct ltq_etop_chan { - struct ltq_etop_priv { - struct net_device *netdev; - struct platform_device *pdev; -- struct ltq_eth_data *pldata; - struct resource *res; - - struct mii_bus *mii_bus; - struct phy_device *phydev; - -- struct ltq_etop_chan ch[MAX_DMA_CHAN]; -- int tx_free[MAX_DMA_CHAN >> 1]; -+ struct ltq_etop_chan txch; -+ struct ltq_etop_chan rxch; -+ -+ int tx_irq; -+ int rx_irq; -+ -+ const void *mac; -+ int mii_mode; - - spinlock_t lock; -+ -+ struct clk *clk_ppe; -+ struct clk *clk_switch; -+ struct clk *clk_ephy; -+ struct clk *clk_ephycgu; - }; - -+static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, -+ int phy_reg, u16 phy_data); -+ - static int - ltq_etop_alloc_skb(struct ltq_etop_chan *ch) - { -- ch->skb[ch->dma.desc] = netdev_alloc_skb(ch->netdev, MAX_DMA_DATA_LEN); -+ ch->skb[ch->dma.desc] = dev_alloc_skb(MAX_DMA_DATA_LEN); - if (!ch->skb[ch->dma.desc]) - return -ENOMEM; - ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(NULL, -@@ -149,8 +197,11 @@ ltq_etop_hw_receive(struct ltq_etop_chan *ch) - spin_unlock_irqrestore(&priv->lock, flags); - - skb_put(skb, len); -+ skb->dev = ch->netdev; - skb->protocol = eth_type_trans(skb, ch->netdev); - netif_receive_skb(skb); -+ ch->netdev->stats.rx_packets++; -+ ch->netdev->stats.rx_bytes += len; - } - - static int -@@ -158,8 +209,10 @@ ltq_etop_poll_rx(struct napi_struct *napi, int budget) - { - struct ltq_etop_chan *ch = container_of(napi, - struct ltq_etop_chan, napi); -+ struct ltq_etop_priv *priv = netdev_priv(ch->netdev); - int rx = 0; - int complete = 0; -+ unsigned long flags; - - while ((rx < budget) && !complete) { - struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc]; -@@ -173,7 +226,9 @@ ltq_etop_poll_rx(struct napi_struct *napi, int budget) - } - if (complete || !rx) { - napi_complete(&ch->napi); -+ spin_lock_irqsave(&priv->lock, flags); - ltq_dma_ack_irq(&ch->dma); -+ spin_unlock_irqrestore(&priv->lock, flags); - } - return rx; - } -@@ -185,12 +240,14 @@ ltq_etop_poll_tx(struct napi_struct *napi, int budget) - container_of(napi, struct ltq_etop_chan, napi); - struct ltq_etop_priv *priv = netdev_priv(ch->netdev); - struct netdev_queue *txq = -- netdev_get_tx_queue(ch->netdev, ch->idx >> 1); -+ netdev_get_tx_queue(ch->netdev, ch->dma.nr >> 1); - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - while ((ch->dma.desc_base[ch->tx_free].ctl & - (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) { -+ ch->netdev->stats.tx_packets++; -+ ch->netdev->stats.tx_bytes += ch->skb[ch->tx_free]->len; - dev_kfree_skb_any(ch->skb[ch->tx_free]); - ch->skb[ch->tx_free] = NULL; - memset(&ch->dma.desc_base[ch->tx_free], 0, -@@ -203,7 +260,9 @@ ltq_etop_poll_tx(struct napi_struct *napi, int budget) - if (netif_tx_queue_stopped(txq)) - netif_tx_start_queue(txq); - napi_complete(&ch->napi); -+ spin_lock_irqsave(&priv->lock, flags); - ltq_dma_ack_irq(&ch->dma); -+ spin_unlock_irqrestore(&priv->lock, flags); - return 1; - } - -@@ -211,9 +270,10 @@ static irqreturn_t - ltq_etop_dma_irq(int irq, void *_priv) - { - struct ltq_etop_priv *priv = _priv; -- int ch = irq - LTQ_DMA_CH0_INT; -- -- napi_schedule(&priv->ch[ch].napi); -+ if (irq == priv->txch.dma.irq) -+ napi_schedule(&priv->txch.napi); -+ else -+ napi_schedule(&priv->rxch.napi); - return IRQ_HANDLED; - } - -@@ -225,7 +285,7 @@ ltq_etop_free_channel(struct net_device *dev, struct ltq_etop_chan *ch) - ltq_dma_free(&ch->dma); - if (ch->dma.irq) - free_irq(ch->dma.irq, priv); -- if (IS_RX(ch->idx)) { -+ if (ch == &priv->txch) { - int desc; - for (desc = 0; desc < LTQ_DESC_NUM; desc++) - dev_kfree_skb_any(ch->skb[ch->dma.desc]); -@@ -236,23 +296,55 @@ static void - ltq_etop_hw_exit(struct net_device *dev) - { - struct ltq_etop_priv *priv = netdev_priv(dev); -- int i; - -- ltq_pmu_disable(PMU_PPE); -- for (i = 0; i < MAX_DMA_CHAN; i++) -- if (IS_TX(i) || IS_RX(i)) -- ltq_etop_free_channel(dev, &priv->ch[i]); -+ clk_disable(priv->clk_ppe); -+ -+ if (of_machine_is_compatible("lantiq,ar9")) -+ clk_disable(priv->clk_switch); -+ -+ if (of_machine_is_compatible("lantiq,ase")) { -+ clk_disable(priv->clk_ephy); -+ clk_disable(priv->clk_ephycgu); -+ } -+ -+ ltq_etop_free_channel(dev, &priv->txch); -+ ltq_etop_free_channel(dev, &priv->rxch); -+} -+ -+static void -+ltq_etop_gbit_init(struct net_device *dev) -+{ -+ struct ltq_etop_priv *priv = netdev_priv(dev); -+ -+ clk_enable(priv->clk_switch); -+ -+ ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0); -+ /** Disable MDIO auto polling mode */ -+ ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL); -+ /* set 1522 packet size */ -+ ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0); -+ /* disable pmac & dmac headers */ -+ ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0, -+ LTQ_GBIT_PMAC_HD_CTL); -+ /* Due to traffic halt when burst length 8, -+ replace default IPG value with 0x3B */ -+ ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG); - } - - static int - ltq_etop_hw_init(struct net_device *dev) - { - struct ltq_etop_priv *priv = netdev_priv(dev); -- int i; - -- ltq_pmu_enable(PMU_PPE); -+ clk_enable(priv->clk_ppe); - -- switch (priv->pldata->mii_mode) { -+ if (of_machine_is_compatible("lantiq,ar9")) { -+ ltq_etop_gbit_init(dev); -+ /* force the etops link to the gbit to MII */ -+ priv->mii_mode = PHY_INTERFACE_MODE_MII; -+ } -+ -+ switch (priv->mii_mode) { - case PHY_INTERFACE_MODE_RMII: - ltq_etop_w32_mask(ETOP_MII_MASK, - ETOP_MII_REVERSE, LTQ_ETOP_CFG); -@@ -264,39 +356,68 @@ ltq_etop_hw_init(struct net_device *dev) - break; - - default: -+ if (of_machine_is_compatible("lantiq,ase")) { -+ clk_enable(priv->clk_ephy); -+ /* disable external MII */ -+ ltq_etop_w32_mask(0, ETOP_CFG_MII0, LTQ_ETOP_CFG); -+ /* enable clock for internal PHY */ -+ clk_enable(priv->clk_ephycgu); -+ /* we need to write this magic to the internal phy to -+ make it work */ -+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020); -+ pr_info("Selected EPHY mode\n"); -+ break; -+ } - netdev_err(dev, "unknown mii mode %d\n", -- priv->pldata->mii_mode); -+ priv->mii_mode); - return -ENOTSUPP; - } - - /* enable crc generation */ - ltq_etop_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG); - -+ return 0; -+} -+ -+static int -+ltq_etop_dma_init(struct net_device *dev) -+{ -+ struct ltq_etop_priv *priv = netdev_priv(dev); -+ int tx = priv->tx_irq - LTQ_DMA_ETOP; -+ int rx = priv->rx_irq - LTQ_DMA_ETOP; -+ int err; -+ - ltq_dma_init_port(DMA_PORT_ETOP); - -- for (i = 0; i < MAX_DMA_CHAN; i++) { -- int irq = LTQ_DMA_CH0_INT + i; -- struct ltq_etop_chan *ch = &priv->ch[i]; -- -- ch->idx = ch->dma.nr = i; -- -- if (IS_TX(i)) { -- ltq_dma_alloc_tx(&ch->dma); -- request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED, -- "etop_tx", priv); -- } else if (IS_RX(i)) { -- ltq_dma_alloc_rx(&ch->dma); -- for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM; -- ch->dma.desc++) -- if (ltq_etop_alloc_skb(ch)) -- return -ENOMEM; -- ch->dma.desc = 0; -- request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED, -- "etop_rx", priv); -+ priv->txch.dma.nr = tx; -+ ltq_dma_alloc_tx(&priv->txch.dma); -+ err = request_irq(priv->tx_irq, ltq_etop_dma_irq, IRQF_DISABLED, -+ "eth_tx", priv); -+ if (err) { -+ netdev_err(dev, "failed to allocate tx irq\n"); -+ goto err_out; -+ } -+ priv->txch.dma.irq = priv->tx_irq; -+ -+ priv->rxch.dma.nr = rx; -+ ltq_dma_alloc_rx(&priv->rxch.dma); -+ for (priv->rxch.dma.desc = 0; priv->rxch.dma.desc < LTQ_DESC_NUM; -+ priv->rxch.dma.desc++) { -+ if (ltq_etop_alloc_skb(&priv->rxch)) { -+ netdev_err(dev, "failed to allocate skbs\n"); -+ err = -ENOMEM; -+ goto err_out; - } -- ch->dma.irq = irq; - } -- return 0; -+ priv->rxch.dma.desc = 0; -+ err = request_irq(priv->rx_irq, ltq_etop_dma_irq, IRQF_DISABLED, -+ "eth_rx", priv); -+ if (err) -+ netdev_err(dev, "failed to allocate rx irq\n"); -+ else -+ priv->rxch.dma.irq = priv->rx_irq; -+err_out: -+ return err; - } - - static void -@@ -312,7 +433,10 @@ ltq_etop_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) - { - struct ltq_etop_priv *priv = netdev_priv(dev); - -- return phy_ethtool_gset(priv->phydev, cmd); -+ if (priv->phydev) -+ return phy_ethtool_gset(priv->phydev, cmd); -+ else -+ return 0; - } - - static int -@@ -320,7 +444,10 @@ ltq_etop_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) - { - struct ltq_etop_priv *priv = netdev_priv(dev); - -- return phy_ethtool_sset(priv->phydev, cmd); -+ if (priv->phydev) -+ return phy_ethtool_sset(priv->phydev, cmd); -+ else -+ return 0; - } - - static int -@@ -328,7 +455,10 @@ ltq_etop_nway_reset(struct net_device *dev) - { - struct ltq_etop_priv *priv = netdev_priv(dev); - -- return phy_start_aneg(priv->phydev); -+ if (priv->phydev) -+ return phy_start_aneg(priv->phydev); -+ else -+ return 0; - } - - static const struct ethtool_ops ltq_etop_ethtool_ops = { -@@ -339,6 +469,39 @@ static const struct ethtool_ops ltq_etop_ethtool_ops = { - }; - - static int -+ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr, -+ int phy_reg, u16 phy_data) -+{ -+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE | -+ (phy_data << MDIO_XR9_WR_OFFSET) | -+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) | -+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET); -+ -+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST) -+ ; -+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL); -+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST) -+ ; -+ return 0; -+} -+ -+static int -+ltq_etop_mdio_rd_xr9(struct mii_bus *bus, int phy_addr, int phy_reg) -+{ -+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_READ | -+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) | -+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET); -+ -+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST) -+ ; -+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL); -+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST) -+ ; -+ val = ltq_gbit_r32(LTQ_GBIT_MDIO_DATA) & MDIO_XR9_RD_MASK; -+ return val; -+} -+ -+static int - ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data) - { - u32 val = MDIO_REQUEST | -@@ -379,14 +542,11 @@ ltq_etop_mdio_probe(struct net_device *dev) - { - struct ltq_etop_priv *priv = netdev_priv(dev); - struct phy_device *phydev = NULL; -- int phy_addr; - -- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { -- if (priv->mii_bus->phy_map[phy_addr]) { -- phydev = priv->mii_bus->phy_map[phy_addr]; -- break; -- } -- } -+ if (of_machine_is_compatible("lantiq,ase")) -+ phydev = priv->mii_bus->phy_map[8]; -+ else -+ phydev = priv->mii_bus->phy_map[0]; - - if (!phydev) { - netdev_err(dev, "no PHY found\n"); -@@ -394,7 +554,7 @@ ltq_etop_mdio_probe(struct net_device *dev) - } - - phydev = phy_connect(dev, dev_name(&phydev->dev), <q_etop_mdio_link, -- 0, priv->pldata->mii_mode); -+ 0, priv->mii_mode); - - if (IS_ERR(phydev)) { - netdev_err(dev, "Could not attach to PHY\n"); -@@ -408,6 +568,9 @@ ltq_etop_mdio_probe(struct net_device *dev) - | SUPPORTED_Autoneg - | SUPPORTED_MII - | SUPPORTED_TP); -+ if (of_machine_is_compatible("lantiq,ar9")) -+ phydev->supported &= SUPPORTED_1000baseT_Half -+ | SUPPORTED_1000baseT_Full; - - phydev->advertising = phydev->supported; - priv->phydev = phydev; -@@ -433,8 +596,13 @@ ltq_etop_mdio_init(struct net_device *dev) - } - - priv->mii_bus->priv = dev; -- priv->mii_bus->read = ltq_etop_mdio_rd; -- priv->mii_bus->write = ltq_etop_mdio_wr; -+ if (of_machine_is_compatible("lantiq,ar9")) { -+ priv->mii_bus->read = ltq_etop_mdio_rd_xr9; -+ priv->mii_bus->write = ltq_etop_mdio_wr_xr9; -+ } else { -+ priv->mii_bus->read = ltq_etop_mdio_rd; -+ priv->mii_bus->write = ltq_etop_mdio_wr; -+ } - priv->mii_bus->name = "ltq_mii"; - snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", - priv->pdev->name, priv->pdev->id); -@@ -483,17 +651,19 @@ static int - ltq_etop_open(struct net_device *dev) - { - struct ltq_etop_priv *priv = netdev_priv(dev); -- int i; -+ unsigned long flags; - -- for (i = 0; i < MAX_DMA_CHAN; i++) { -- struct ltq_etop_chan *ch = &priv->ch[i]; -+ napi_enable(&priv->txch.napi); -+ napi_enable(&priv->rxch.napi); -+ -+ spin_lock_irqsave(&priv->lock, flags); -+ ltq_dma_open(&priv->txch.dma); -+ ltq_dma_open(&priv->rxch.dma); -+ spin_unlock_irqrestore(&priv->lock, flags); -+ -+ if (priv->phydev) -+ phy_start(priv->phydev); - -- if (!IS_TX(i) && (!IS_RX(i))) -- continue; -- ltq_dma_open(&ch->dma); -- napi_enable(&ch->napi); -- } -- phy_start(priv->phydev); - netif_tx_start_all_queues(dev); - return 0; - } -@@ -502,18 +672,19 @@ static int - ltq_etop_stop(struct net_device *dev) - { - struct ltq_etop_priv *priv = netdev_priv(dev); -- int i; -+ unsigned long flags; - - netif_tx_stop_all_queues(dev); -- phy_stop(priv->phydev); -- for (i = 0; i < MAX_DMA_CHAN; i++) { -- struct ltq_etop_chan *ch = &priv->ch[i]; -+ if (priv->phydev) -+ phy_stop(priv->phydev); -+ napi_disable(&priv->txch.napi); -+ napi_disable(&priv->rxch.napi); -+ -+ spin_lock_irqsave(&priv->lock, flags); -+ ltq_dma_close(&priv->txch.dma); -+ ltq_dma_close(&priv->rxch.dma); -+ spin_unlock_irqrestore(&priv->lock, flags); - -- if (!IS_RX(i) && !IS_TX(i)) -- continue; -- napi_disable(&ch->napi); -- ltq_dma_close(&ch->dma); -- } - return 0; - } - -@@ -523,16 +694,16 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev) - int queue = skb_get_queue_mapping(skb); - struct netdev_queue *txq = netdev_get_tx_queue(dev, queue); - struct ltq_etop_priv *priv = netdev_priv(dev); -- struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1]; -- struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc]; -- int len; -+ struct ltq_dma_desc *desc = -+ &priv->txch.dma.desc_base[priv->txch.dma.desc]; - unsigned long flags; - u32 byte_offset; -+ int len; - - len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; - -- if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) { -- dev_kfree_skb_any(skb); -+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || -+ priv->txch.skb[priv->txch.dma.desc]) { - netdev_err(dev, "tx ring full\n"); - netif_tx_stop_queue(txq); - return NETDEV_TX_BUSY; -@@ -540,7 +711,7 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev) - - /* dma needs to start on a 16 byte aligned address */ - byte_offset = CPHYSADDR(skb->data) % 16; -- ch->skb[ch->dma.desc] = skb; -+ priv->txch.skb[priv->txch.dma.desc] = skb; - - dev->trans_start = jiffies; - -@@ -550,11 +721,11 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev) - wmb(); - desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP | - LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK); -- ch->dma.desc++; -- ch->dma.desc %= LTQ_DESC_NUM; -+ priv->txch.dma.desc++; -+ priv->txch.dma.desc %= LTQ_DESC_NUM; - spin_unlock_irqrestore(&priv->lock, flags); - -- if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN) -+ if (priv->txch.dma.desc_base[priv->txch.dma.desc].ctl & LTQ_DMA_OWN) - netif_tx_stop_queue(txq); - - return NETDEV_TX_OK; -@@ -633,34 +804,32 @@ ltq_etop_init(struct net_device *dev) - struct ltq_etop_priv *priv = netdev_priv(dev); - struct sockaddr mac; - int err; -- bool random_mac = false; - - ether_setup(dev); - dev->watchdog_timeo = 10 * HZ; - err = ltq_etop_hw_init(dev); - if (err) - goto err_hw; -+ err = ltq_etop_dma_init(dev); -+ if (err) -+ goto err_hw; -+ - ltq_etop_change_mtu(dev, 1500); - -- memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr)); -+ memcpy(&mac.sa_data, priv->mac, ETH_ALEN); - if (!is_valid_ether_addr(mac.sa_data)) { - pr_warn("etop: invalid MAC, using random\n"); -- eth_random_addr(mac.sa_data); -- random_mac = true; -+ random_ether_addr(mac.sa_data); - } - - err = ltq_etop_set_mac_address(dev, &mac); - if (err) - goto err_netdev; -- -- /* Set addr_assign_type here, ltq_etop_set_mac_address would reset it. */ -- if (random_mac) -- dev->addr_assign_type |= NET_ADDR_RANDOM; -- - ltq_etop_set_multicast_list(dev); -- err = ltq_etop_mdio_init(dev); -- if (err) -- goto err_netdev; -+ if (!ltq_etop_mdio_init(dev)) -+ dev->ethtool_ops = <q_etop_ethtool_ops; -+ else -+ pr_warn("etop: mdio probe failed\n");; - return 0; - - err_netdev: -@@ -680,6 +849,9 @@ ltq_etop_tx_timeout(struct net_device *dev) - err = ltq_etop_hw_init(dev); - if (err) - goto err_hw; -+ err = ltq_etop_dma_init(dev); -+ if (err) -+ goto err_hw; - dev->trans_start = jiffies; - netif_wake_queue(dev); - return; -@@ -703,14 +875,19 @@ static const struct net_device_ops ltq_eth_netdev_ops = { - .ndo_tx_timeout = ltq_etop_tx_timeout, - }; - --static int __init -+static int __devinit - ltq_etop_probe(struct platform_device *pdev) - { - struct net_device *dev; - struct ltq_etop_priv *priv; -- struct resource *res; -+ struct resource *res, *gbit_res, irqres[2]; - int err; -- int i; -+ -+ err = of_irq_to_resource_table(pdev->dev.of_node, irqres, 2); -+ if (err != 2) { -+ dev_err(&pdev->dev, "failed to get etop irqs\n"); -+ return -EINVAL; -+ } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { -@@ -736,30 +913,58 @@ ltq_etop_probe(struct platform_device *pdev) - goto err_out; - } - -- dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4); -- if (!dev) { -- err = -ENOMEM; -- goto err_out; -+ if (of_machine_is_compatible("lantiq,ar9")) { -+ gbit_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ if (!gbit_res) { -+ dev_err(&pdev->dev, "failed to get gbit resource\n"); -+ err = -ENOENT; -+ goto err_out; -+ } -+ ltq_gbit_membase = devm_ioremap_nocache(&pdev->dev, -+ gbit_res->start, resource_size(gbit_res)); -+ if (!ltq_gbit_membase) { -+ dev_err(&pdev->dev, "failed to remap gigabit switch %d\n", -+ pdev->id); -+ err = -ENOMEM; -+ goto err_out; -+ } - } -+ -+ dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4); - strcpy(dev->name, "eth%d"); - dev->netdev_ops = <q_eth_netdev_ops; -- dev->ethtool_ops = <q_etop_ethtool_ops; - priv = netdev_priv(dev); - priv->res = res; - priv->pdev = pdev; -- priv->pldata = dev_get_platdata(&pdev->dev); - priv->netdev = dev; -+ priv->tx_irq = irqres[0].start; -+ priv->rx_irq = irqres[1].start; -+ priv->mii_mode = of_get_phy_mode(pdev->dev.of_node); -+ priv->mac = of_get_mac_address(pdev->dev.of_node); -+ -+ priv->clk_ppe = clk_get(&pdev->dev, NULL); -+ if (IS_ERR(priv->clk_ppe)) -+ return PTR_ERR(priv->clk_ppe); -+ if (of_machine_is_compatible("lantiq,ar9")) { -+ priv->clk_switch = clk_get(&pdev->dev, "switch"); -+ if (IS_ERR(priv->clk_switch)) -+ return PTR_ERR(priv->clk_switch); -+ } -+ if (of_machine_is_compatible("lantiq,ase")) { -+ priv->clk_ephy = clk_get(&pdev->dev, "ephy"); -+ if (IS_ERR(priv->clk_ephy)) -+ return PTR_ERR(priv->clk_ephy); -+ priv->clk_ephycgu = clk_get(&pdev->dev, "ephycgu"); -+ if (IS_ERR(priv->clk_ephycgu)) -+ return PTR_ERR(priv->clk_ephycgu); -+ } -+ - spin_lock_init(&priv->lock); - -- for (i = 0; i < MAX_DMA_CHAN; i++) { -- if (IS_TX(i)) -- netif_napi_add(dev, &priv->ch[i].napi, -- ltq_etop_poll_tx, 8); -- else if (IS_RX(i)) -- netif_napi_add(dev, &priv->ch[i].napi, -- ltq_etop_poll_rx, 32); -- priv->ch[i].netdev = dev; -- } -+ netif_napi_add(dev, &priv->txch.napi, ltq_etop_poll_tx, 8); -+ netif_napi_add(dev, &priv->rxch.napi, ltq_etop_poll_rx, 32); -+ priv->txch.netdev = dev; -+ priv->rxch.netdev = dev; - - err = register_netdev(dev); - if (err) -@@ -788,32 +993,23 @@ ltq_etop_remove(struct platform_device *pdev) - return 0; - } - -+static const struct of_device_id ltq_etop_match[] = { -+ { .compatible = "lantiq,etop-xway" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, ltq_etop_match); -+ - static struct platform_driver ltq_mii_driver = { -+ .probe = ltq_etop_probe, - .remove = __devexit_p(ltq_etop_remove), - .driver = { - .name = "ltq_etop", - .owner = THIS_MODULE, -+ .of_match_table = ltq_etop_match, - }, - }; - --int __init --init_ltq_etop(void) --{ -- int ret = platform_driver_probe(<q_mii_driver, ltq_etop_probe); -- -- if (ret) -- pr_err("ltq_etop: Error registering platform driver!"); -- return ret; --} -- --static void __exit --exit_ltq_etop(void) --{ -- platform_driver_unregister(<q_mii_driver); --} -- --module_init(init_ltq_etop); --module_exit(exit_ltq_etop); -+module_platform_driver(ltq_mii_driver); - - MODULE_AUTHOR("John Crispin "); - MODULE_DESCRIPTION("Lantiq SoC ETOP"); --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0112-NET-MIPS-lantiq-adds-xrx200-net.patch b/target/linux/lantiq/patches-3.6/0112-NET-MIPS-lantiq-adds-xrx200-net.patch deleted file mode 100644 index ea69c5c21e..0000000000 --- a/target/linux/lantiq/patches-3.6/0112-NET-MIPS-lantiq-adds-xrx200-net.patch +++ /dev/null @@ -1,1382 +0,0 @@ -From dd440736aa03cbe9fcf49e4bfdbb22c947f8ba67 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 22 Oct 2012 12:22:23 +0200 -Subject: [PATCH 112/113] NET: MIPS: lantiq: adds xrx200-net - ---- - drivers/net/ethernet/Kconfig | 8 +- - drivers/net/ethernet/Makefile | 1 + - drivers/net/ethernet/lantiq_pce.h | 163 +++++ - drivers/net/ethernet/lantiq_xrx200.c | 1159 ++++++++++++++++++++++++++++++++++ - 4 files changed, 1330 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/ethernet/lantiq_pce.h - create mode 100644 drivers/net/ethernet/lantiq_xrx200.c - -diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig -index e4ff389..35cb7b0 100644 ---- a/drivers/net/ethernet/Kconfig -+++ b/drivers/net/ethernet/Kconfig -@@ -83,7 +83,13 @@ config LANTIQ_ETOP - tristate "Lantiq SoC ETOP driver" - depends on SOC_TYPE_XWAY - ---help--- -- Support for the MII0 inside the Lantiq SoC -+ Support for the MII0 inside the Lantiq ADSL SoC -+ -+config LANTIQ_XRX200 -+ tristate "Lantiq SoC XRX200 driver" -+ depends on SOC_TYPE_XWAY -+ ---help--- -+ Support for the MII0 inside the Lantiq VDSL SoC - - source "drivers/net/ethernet/marvell/Kconfig" - source "drivers/net/ethernet/mellanox/Kconfig" -diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile -index d447307..4f95100 100644 ---- a/drivers/net/ethernet/Makefile -+++ b/drivers/net/ethernet/Makefile -@@ -36,6 +36,7 @@ obj-$(CONFIG_IP1000) += icplus/ - obj-$(CONFIG_JME) += jme.o - obj-$(CONFIG_KORINA) += korina.o - obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o -+obj-$(CONFIG_LANTIQ_XRX200) += lantiq_xrx200.o - obj-$(CONFIG_NET_VENDOR_MARVELL) += marvell/ - obj-$(CONFIG_NET_VENDOR_MELLANOX) += mellanox/ - obj-$(CONFIG_NET_VENDOR_MICREL) += micrel/ -diff --git a/drivers/net/ethernet/lantiq_pce.h b/drivers/net/ethernet/lantiq_pce.h -new file mode 100644 -index 0000000..0c38efe ---- /dev/null -+++ b/drivers/net/ethernet/lantiq_pce.h -@@ -0,0 +1,163 @@ -+/* -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * Copyright (C) 2010 Lantiq Deutschland GmbH -+ * Copyright (C) 2012 John Crispin -+ * -+ * PCE microcode extracted from UGW5.2 switch api -+ */ -+ -+/* Switch API Micro Code V0.3 */ -+enum { -+ OUT_MAC0 = 0, -+ OUT_MAC1, -+ OUT_MAC2, -+ OUT_MAC3, -+ OUT_MAC4, -+ OUT_MAC5, -+ OUT_ETHTYP, -+ OUT_VTAG0, -+ OUT_VTAG1, -+ OUT_ITAG0, -+ OUT_ITAG1, /*10 */ -+ OUT_ITAG2, -+ OUT_ITAG3, -+ OUT_IP0, -+ OUT_IP1, -+ OUT_IP2, -+ OUT_IP3, -+ OUT_SIP0, -+ OUT_SIP1, -+ OUT_SIP2, -+ OUT_SIP3, /*20*/ -+ OUT_SIP4, -+ OUT_SIP5, -+ OUT_SIP6, -+ OUT_SIP7, -+ OUT_DIP0, -+ OUT_DIP1, -+ OUT_DIP2, -+ OUT_DIP3, -+ OUT_DIP4, -+ OUT_DIP5, /*30*/ -+ OUT_DIP6, -+ OUT_DIP7, -+ OUT_SESID, -+ OUT_PROT, -+ OUT_APP0, -+ OUT_APP1, -+ OUT_IGMP0, -+ OUT_IGMP1, -+ OUT_IPOFF, /*39*/ -+ OUT_NONE = 63 -+}; -+ -+/* parser's microcode length type */ -+#define INSTR 0 -+#define IPV6 1 -+#define LENACCU 2 -+ -+/* parser's microcode flag type */ -+enum { -+ FLAG_ITAG = 0, -+ FLAG_VLAN, -+ FLAG_SNAP, -+ FLAG_PPPOE, -+ FLAG_IPV6, -+ FLAG_IPV6FL, -+ FLAG_IPV4, -+ FLAG_IGMP, -+ FLAG_TU, -+ FLAG_HOP, -+ FLAG_NN1, /*10 */ -+ FLAG_NN2, -+ FLAG_END, -+ FLAG_NO, /*13*/ -+}; -+ -+/* Micro code version V2_11 (extension for parsing IPv6 in PPPoE) */ -+#define MC_ENTRY(val, msk, ns, out, len, type, flags, ipv4_len) \ -+ { {val, msk, (ns<<10 | out<<4 | len>>1), (len&1)<<15 | type<<13 | flags<<9 | ipv4_len<<8 }} -+struct pce_microcode { -+ unsigned short val[4]; -+/* unsigned short val_2; -+ unsigned short val_1; -+ unsigned short val_0;*/ -+} pce_microcode[] = { -+ /* value mask ns fields L type flags ipv4_len */ -+ MC_ENTRY(0x88c3, 0xFFFF, 1, OUT_ITAG0, 4, INSTR, FLAG_ITAG, 0), -+ MC_ENTRY(0x8100, 0xFFFF, 2, OUT_VTAG0, 2, INSTR, FLAG_VLAN, 0), -+ MC_ENTRY(0x88A8, 0xFFFF, 1, OUT_VTAG0, 2, INSTR, FLAG_VLAN, 0), -+ MC_ENTRY(0x8100, 0xFFFF, 1, OUT_VTAG0, 2, INSTR, FLAG_VLAN, 0), -+ MC_ENTRY(0x8864, 0xFFFF, 17, OUT_ETHTYP, 1, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0800, 0xFFFF, 21, OUT_ETHTYP, 1, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x86DD, 0xFFFF, 22, OUT_ETHTYP, 1, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x8863, 0xFFFF, 16, OUT_ETHTYP, 1, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0000, 0xF800, 10, OUT_NONE, 0, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0000, 0x0000, 38, OUT_ETHTYP, 1, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0600, 0x0600, 38, OUT_ETHTYP, 1, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0000, 0x0000, 12, OUT_NONE, 1, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0xAAAA, 0xFFFF, 14, OUT_NONE, 1, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0300, 0xFF00, 39, OUT_NONE, 0, INSTR, FLAG_SNAP, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_DIP7, 3, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0000, 0x0000, 18, OUT_DIP7, 3, INSTR, FLAG_PPPOE, 0), -+ MC_ENTRY(0x0021, 0xFFFF, 21, OUT_NONE, 1, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0057, 0xFFFF, 22, OUT_NONE, 1, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x4000, 0xF000, 24, OUT_IP0, 4, INSTR, FLAG_IPV4, 1), -+ MC_ENTRY(0x6000, 0xF000, 27, OUT_IP0, 3, INSTR, FLAG_IPV6, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0000, 0x0000, 25, OUT_IP3, 2, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0000, 0x0000, 26, OUT_SIP0, 4, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0000, 0x0000, 38, OUT_NONE, 0, LENACCU, FLAG_NO, 0), -+ MC_ENTRY(0x1100, 0xFF00, 37, OUT_PROT, 1, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0600, 0xFF00, 37, OUT_PROT, 1, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0000, 0xFF00, 33, OUT_IP3, 17, INSTR, FLAG_HOP, 0), -+ MC_ENTRY(0x2B00, 0xFF00, 33, OUT_IP3, 17, INSTR, FLAG_NN1, 0), -+ MC_ENTRY(0x3C00, 0xFF00, 33, OUT_IP3, 17, INSTR, FLAG_NN2, 0), -+ MC_ENTRY(0x0000, 0x0000, 37, OUT_PROT, 1, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0000, 0xFF00, 33, OUT_NONE, 0, IPV6, FLAG_HOP, 0), -+ MC_ENTRY(0x2B00, 0xFF00, 33, OUT_NONE, 0, IPV6, FLAG_NN1, 0), -+ MC_ENTRY(0x3C00, 0xFF00, 33, OUT_NONE, 0, IPV6, FLAG_NN2, 0), -+ MC_ENTRY(0x0000, 0x0000, 38, OUT_PROT, 1, IPV6, FLAG_NO, 0), -+ MC_ENTRY(0x0000, 0x0000, 38, OUT_SIP0, 16, INSTR, FLAG_NO, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_APP0, 4, INSTR, FLAG_IGMP, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+ MC_ENTRY(0x0000, 0x0000, 39, OUT_NONE, 0, INSTR, FLAG_END, 0), -+}; -diff --git a/drivers/net/ethernet/lantiq_xrx200.c b/drivers/net/ethernet/lantiq_xrx200.c -new file mode 100644 -index 0000000..71abc7d ---- /dev/null -+++ b/drivers/net/ethernet/lantiq_xrx200.c -@@ -0,0 +1,1159 @@ -+/* -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * Copyright (C) 2010 Lantiq Deutschland -+ * Copyright (C) 2012 John Crispin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "lantiq_pce.h" -+ -+#define SW_POLLING -+#define SW_ROUTING -+ -+#ifdef SW_ROUTING -+#define XRX200_MAX_DEV 2 -+#else -+#define XRX200_MAX_DEV 1 -+#endif -+ -+#define XRX200_MAX_PORT 7 -+#define XRX200_MAX_DMA 8 -+ -+#define XRX200_HEADROOM 4 -+ -+#define XRX200_TX_TIMEOUT (10 * HZ) -+ -+/* port type */ -+#define XRX200_PORT_TYPE_PHY 1 -+#define XRX200_PORT_TYPE_MAC 2 -+ -+/* DMA */ -+#define XRX200_DMA_CRC_LEN 0x4 -+#define XRX200_DMA_DATA_LEN 0x600 -+#define XRX200_DMA_IRQ INT_NUM_IM2_IRL0 -+#define XRX200_DMA_RX 0 -+#define XRX200_DMA_TX 1 -+ -+/* fetch / store dma */ -+#define FDMA_PCTRL0 0x2A00 -+#define FDMA_PCTRLx(x) (FDMA_PCTRL0 + (x * 0x18)) -+#define SDMA_PCTRL0 0x2F00 -+#define SDMA_PCTRLx(x) (SDMA_PCTRL0 + (x * 0x18)) -+ -+/* buffer management */ -+#define BM_PCFG0 0x200 -+#define BM_PCFGx(x) (BM_PCFG0 + (x * 8)) -+ -+/* MDIO */ -+#define MDIO_GLOB 0x0000 -+#define MDIO_CTRL 0x0020 -+#define MDIO_READ 0x0024 -+#define MDIO_WRITE 0x0028 -+#define MDIO_PHY0 0x0054 -+#define MDIO_PHY(x) (0x0054 - (x * sizeof(unsigned))) -+#define MDIO_CLK_CFG0 0x002C -+#define MDIO_CLK_CFG1 0x0030 -+ -+#define MDIO_GLOB_ENABLE 0x8000 -+#define MDIO_BUSY BIT(12) -+#define MDIO_RD BIT(11) -+#define MDIO_WR BIT(10) -+#define MDIO_MASK 0x1f -+#define MDIO_ADDRSHIFT 5 -+#define MDIO1_25MHZ 9 -+ -+#define MDIO_PHY_LINK_DOWN 0x4000 -+#define MDIO_PHY_LINK_UP 0x2000 -+ -+#define MDIO_PHY_SPEED_M10 0x0000 -+#define MDIO_PHY_SPEED_M100 0x0800 -+#define MDIO_PHY_SPEED_G1 0x1000 -+ -+#define MDIO_PHY_FDUP_EN 0x0600 -+#define MDIO_PHY_FDUP_DIS 0x0200 -+ -+#define MDIO_PHY_LINK_MASK 0x6000 -+#define MDIO_PHY_SPEED_MASK 0x1800 -+#define MDIO_PHY_FDUP_MASK 0x0600 -+#define MDIO_PHY_ADDR_MASK 0x001f -+#define MDIO_UPDATE_MASK MDIO_PHY_ADDR_MASK | MDIO_PHY_LINK_MASK | \ -+ MDIO_PHY_SPEED_MASK | MDIO_PHY_FDUP_MASK -+ -+/* MII */ -+#define MII_CFG(p) (p * 8) -+ -+#define MII_CFG_EN BIT(14) -+ -+#define MII_CFG_MODE_MIIP 0x0 -+#define MII_CFG_MODE_MIIM 0x1 -+#define MII_CFG_MODE_RMIIP 0x2 -+#define MII_CFG_MODE_RMIIM 0x3 -+#define MII_CFG_MODE_RGMII 0x4 -+#define MII_CFG_MODE_MASK 0xf -+ -+#define MII_CFG_RATE_M2P5 0x00 -+#define MII_CFG_RATE_M25 0x10 -+#define MII_CFG_RATE_M125 0x20 -+#define MII_CFG_RATE_M50 0x30 -+#define MII_CFG_RATE_AUTO 0x40 -+#define MII_CFG_RATE_MASK 0x70 -+ -+/* cpu port mac */ -+#define PMAC_HD_CTL 0x0000 -+#define PMAC_RX_IPG 0x0024 -+#define PMAC_EWAN 0x002c -+ -+#define PMAC_IPG_MASK 0xf -+#define PMAC_HD_CTL_AS 0x0008 -+#define PMAC_HD_CTL_AC 0x0004 -+#define PMAC_HD_CTL_RXSH 0x0040 -+#define PMAC_HD_CTL_AST 0x0080 -+ -+/* PCE */ -+#define PCE_TBL_KEY(x) (0x1100 + ((7 - x) * 4)) -+#define PCE_TBL_MASK 0x1120 -+#define PCE_TBL_VAL(x) (0x1124 + ((4 - x) * 4)) -+#define PCE_TBL_ADDR 0x1138 -+#define PCE_TBL_CTRL 0x113c -+#define PCE_PMAP1 0x114c -+#define PCE_PMAP2 0x1150 -+#define PCE_PMAP3 0x1154 -+#define PCE_GCTRL_REG(x) (0x1158 + (x * 4)) -+#define PCE_PCTRL_REG(p, x) (0x1200 + (((p * 0xa) + x) * 4)) -+ -+#define PCE_TBL_BUSY BIT(15) -+#define PCE_TBL_CFG_ADDR_MASK 0x1f -+#define PCE_TBL_CFG_ADWR 0x20 -+#define PCE_TBL_CFG_ADWR_MASK 0x60 -+#define PCE_INGRESS BIT(11) -+ -+/* buffer management */ -+#define BM_PCFG(p) (0x200 + (p * 8)) -+ -+/* special tag in TX path header */ -+#define SPID_SHIFT 24 -+#define DPID_SHIFT 16 -+#define DPID_ENABLE 1 -+#define SPID_CPU_PORT 2 -+ -+#define SPPID_MASK 0x7 -+#define SPPID_SHIFT 4 -+ -+/* MII regs not yet in linux */ -+#define MDIO_DEVAD_NONE (-1) -+#define ADVERTIZE_MPD (1 << 10) -+ -+struct xrx200_port { -+ u8 num; -+ u8 phy_addr; -+ u16 flags; -+ phy_interface_t phy_if; -+ -+ int link; -+ -+ struct phy_device *phydev; -+ struct device_node *phy_node; -+}; -+ -+struct xrx200_chan { -+ int idx; -+ int refcount; -+ int tx_free; -+ -+ struct net_device dummy_dev; -+ struct net_device *devs[XRX200_MAX_DEV]; -+ -+ struct napi_struct napi; -+ struct ltq_dma_channel dma; -+ struct sk_buff *skb[LTQ_DESC_NUM]; -+}; -+ -+struct xrx200_hw { -+ struct clk *clk; -+ struct mii_bus *mii_bus; -+ -+ struct xrx200_chan chan[XRX200_MAX_DMA]; -+ -+ struct net_device *devs[XRX200_MAX_DEV]; -+ int num_devs; -+ -+ int port_map[XRX200_MAX_PORT]; -+ unsigned short wan_map; -+ -+ spinlock_t lock; -+}; -+ -+struct xrx200_priv { -+ struct net_device_stats stats; -+ int id; -+ -+ struct xrx200_port port[XRX200_MAX_PORT]; -+ int num_port; -+ int wan; -+ const void *mac; -+ -+ struct xrx200_hw *hw; -+}; -+ -+static __iomem void *xrx200_switch_membase; -+static __iomem void *xrx200_mii_membase; -+static __iomem void *xrx200_mdio_membase; -+static __iomem void *xrx200_pmac_membase; -+ -+#define ltq_switch_r32(x) ltq_r32(xrx200_switch_membase + (x)) -+#define ltq_switch_w32(x, y) ltq_w32(x, xrx200_switch_membase + (y)) -+#define ltq_switch_w32_mask(x, y, z) \ -+ ltq_w32_mask(x, y, xrx200_switch_membase + (z)) -+ -+#define ltq_mdio_r32(x) ltq_r32(xrx200_mdio_membase + (x)) -+#define ltq_mdio_w32(x, y) ltq_w32(x, xrx200_mdio_membase + (y)) -+#define ltq_mdio_w32_mask(x, y, z) \ -+ ltq_w32_mask(x, y, xrx200_mdio_membase + (z)) -+ -+#define ltq_mii_r32(x) ltq_r32(xrx200_mii_membase + (x)) -+#define ltq_mii_w32(x, y) ltq_w32(x, xrx200_mii_membase + (y)) -+#define ltq_mii_w32_mask(x, y, z) \ -+ ltq_w32_mask(x, y, xrx200_mii_membase + (z)) -+ -+#define ltq_pmac_r32(x) ltq_r32(xrx200_pmac_membase + (x)) -+#define ltq_pmac_w32(x, y) ltq_w32(x, xrx200_pmac_membase + (y)) -+#define ltq_pmac_w32_mask(x, y, z) \ -+ ltq_w32_mask(x, y, xrx200_pmac_membase + (z)) -+ -+static int xrx200_open(struct net_device *dev) -+{ -+ struct xrx200_priv *priv = netdev_priv(dev); -+ unsigned long flags; -+ int i; -+ -+ for (i = 0; i < XRX200_MAX_DMA; i++) { -+ if (!priv->hw->chan[i].dma.irq) -+ continue; -+ spin_lock_irqsave(&priv->hw->lock, flags); -+ if (!priv->hw->chan[i].refcount) { -+ napi_enable(&priv->hw->chan[i].napi); -+ ltq_dma_open(&priv->hw->chan[i].dma); -+ } -+ priv->hw->chan[i].refcount++; -+ spin_unlock_irqrestore(&priv->hw->lock, flags); -+ } -+ for (i = 0; i < priv->num_port; i++) -+ if (priv->port[i].phydev) -+ phy_start(priv->port[i].phydev); -+ netif_start_queue(dev); -+ -+ return 0; -+} -+ -+static int xrx200_close(struct net_device *dev) -+{ -+ struct xrx200_priv *priv = netdev_priv(dev); -+ unsigned long flags; -+ int i; -+ -+ netif_stop_queue(dev); -+ -+ for (i = 0; i < priv->num_port; i++) -+ if (priv->port[i].phydev) -+ phy_stop(priv->port[i].phydev); -+ -+ for (i = 0; i < XRX200_MAX_DMA; i++) { -+ if (!priv->hw->chan[i].dma.irq) -+ continue; -+ spin_lock_irqsave(&priv->hw->lock, flags); -+ priv->hw->chan[i].refcount--; -+ if (!priv->hw->chan[i].refcount) { -+ napi_disable(&priv->hw->chan[i].napi); -+ ltq_dma_close(&priv->hw->chan[XRX200_DMA_RX].dma); -+ } -+ spin_unlock_irqrestore(&priv->hw->lock, flags); -+ } -+ -+ return 0; -+} -+ -+static int xrx200_alloc_skb(struct xrx200_chan *ch) -+{ -+#define DMA_PAD (NET_IP_ALIGN) // + NET_SKB_PAD) -+ ch->skb[ch->dma.desc] = dev_alloc_skb(XRX200_DMA_DATA_LEN + DMA_PAD); -+ if (!ch->skb[ch->dma.desc]) -+ return -ENOMEM; -+ -+ ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(NULL, -+ ch->skb[ch->dma.desc]->data, XRX200_DMA_DATA_LEN, -+ DMA_FROM_DEVICE); -+ ch->dma.desc_base[ch->dma.desc].addr = -+ CPHYSADDR(ch->skb[ch->dma.desc]->data); -+ ch->dma.desc_base[ch->dma.desc].ctl = -+ LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) | -+ XRX200_DMA_DATA_LEN; -+ skb_reserve(ch->skb[ch->dma.desc], DMA_PAD); -+ -+ return 0; -+} -+ -+static void xrx200_hw_receive(struct xrx200_chan *ch, int id) -+{ -+ struct net_device *dev = ch->devs[id]; -+ struct xrx200_priv *priv = netdev_priv(dev); -+ struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc]; -+ struct sk_buff *skb = ch->skb[ch->dma.desc]; -+ int len = (desc->ctl & LTQ_DMA_SIZE_MASK) - XRX200_DMA_CRC_LEN; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&priv->hw->lock, flags); -+ if (xrx200_alloc_skb(ch)) { -+ netdev_err(dev, -+ "failed to allocate new rx buffer, stopping DMA\n"); -+ ltq_dma_close(&ch->dma); -+ } -+ -+ ch->dma.desc++; -+ ch->dma.desc %= LTQ_DESC_NUM; -+ spin_unlock_irqrestore(&priv->hw->lock, flags); -+ -+ skb_put(skb, len); -+#ifdef SW_ROUTING -+ skb_pull(skb, 8); -+#endif -+ skb->dev = dev; -+ skb->protocol = eth_type_trans(skb, dev); -+ netif_receive_skb(skb); -+ priv->stats.rx_packets++; -+ priv->stats.rx_bytes+=len; -+} -+ -+static int xrx200_poll_rx(struct napi_struct *napi, int budget) -+{ -+ struct xrx200_chan *ch = container_of(napi, -+ struct xrx200_chan, napi); -+ struct xrx200_priv *priv = netdev_priv(ch->devs[0]); -+ int rx = 0; -+ int complete = 0; -+ unsigned long flags; -+ -+ while ((rx < budget) && !complete) { -+ struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc]; -+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) { -+#ifdef SW_ROUTING -+ struct sk_buff *skb = ch->skb[ch->dma.desc]; -+ u32 *special_tag = (u32*)skb->data; -+ int port = (special_tag[1] >> SPPID_SHIFT) & SPPID_MASK; -+ xrx200_hw_receive(ch, priv->hw->port_map[port]); -+#else -+ xrx200_hw_receive(ch, 0); -+#endif -+ rx++; -+ } else { -+ complete = 1; -+ } -+ } -+ if (complete || !rx) { -+ napi_complete(&ch->napi); -+ spin_lock_irqsave(&priv->hw->lock, flags); -+ ltq_dma_ack_irq(&ch->dma); -+ spin_unlock_irqrestore(&priv->hw->lock, flags); -+ } -+ return rx; -+} -+ -+static int xrx200_poll_tx(struct napi_struct *napi, int budget) -+{ -+ struct xrx200_chan *ch = -+ container_of(napi, struct xrx200_chan, napi); -+ struct xrx200_priv *priv = netdev_priv(ch->devs[0]); -+ unsigned long flags; -+ int i; -+ -+ spin_lock_irqsave(&priv->hw->lock, flags); -+ while ((ch->dma.desc_base[ch->tx_free].ctl & -+ (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) { -+ dev_kfree_skb_any(ch->skb[ch->tx_free]); -+ ch->skb[ch->tx_free] = NULL; -+ memset(&ch->dma.desc_base[ch->tx_free], 0, -+ sizeof(struct ltq_dma_desc)); -+ ch->tx_free++; -+ ch->tx_free %= LTQ_DESC_NUM; -+ } -+ spin_unlock_irqrestore(&priv->hw->lock, flags); -+ -+ for (i = 0; i < XRX200_MAX_DEV; i++) { -+ struct netdev_queue *txq = -+ netdev_get_tx_queue(ch->devs[i], 0); -+ if (netif_tx_queue_stopped(txq)) -+ netif_tx_start_queue(txq); -+ } -+ napi_complete(&ch->napi); -+ spin_lock_irqsave(&priv->hw->lock, flags); -+ ltq_dma_ack_irq(&ch->dma); -+ spin_unlock_irqrestore(&priv->hw->lock, flags); -+ -+ return 1; -+} -+ -+static struct net_device_stats *xrx200_get_stats (struct net_device *dev) -+{ -+ struct xrx200_priv *priv = netdev_priv(dev); -+ -+ return &priv->stats; -+} -+ -+static void xrx200_tx_timeout(struct net_device *dev) -+{ -+ struct xrx200_priv *priv = netdev_priv(dev); -+ -+ printk(KERN_ERR "%s: transmit timed out, disable the dma channel irq\n", dev->name); -+ -+ priv->stats.tx_errors++; -+ netif_wake_queue(dev); -+} -+ -+static int xrx200_start_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ int queue = skb_get_queue_mapping(skb); -+ struct netdev_queue *txq = netdev_get_tx_queue(dev, queue); -+ struct xrx200_priv *priv = netdev_priv(dev); -+ struct xrx200_chan *ch = &priv->hw->chan[XRX200_DMA_TX]; -+ struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc]; -+ unsigned long flags; -+ u32 byte_offset; -+ int len; -+#ifdef SW_ROUTING -+ u32 special_tag = (SPID_CPU_PORT << SPID_SHIFT) | DPID_ENABLE; -+#endif -+ -+ len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; -+ -+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) { -+ netdev_err(dev, "tx ring full\n"); -+ netif_tx_stop_queue(txq); -+ return NETDEV_TX_BUSY; -+ } -+#ifdef SW_ROUTING -+ if(priv->id) -+ special_tag |= (1 << DPID_SHIFT); -+ if(skb_headroom(skb) < 4) { -+ struct sk_buff *tmp = skb_realloc_headroom(skb, 4); -+ dev_kfree_skb_any(skb); -+ skb = tmp; -+ } -+ skb_push(skb, 4); -+ memcpy(skb->data, &special_tag, sizeof(u32)); -+ len += 4; -+#endif -+ -+ /* dma needs to start on a 16 byte aligned address */ -+ byte_offset = CPHYSADDR(skb->data) % 16; -+ ch->skb[ch->dma.desc] = skb; -+ -+ dev->trans_start = jiffies; -+ -+ spin_lock_irqsave(&priv->hw->lock, flags); -+ desc->addr = ((unsigned int) dma_map_single(NULL, skb->data, len, -+ DMA_TO_DEVICE)) - byte_offset; -+ wmb(); -+ desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP | -+ LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK); -+ ch->dma.desc++; -+ ch->dma.desc %= LTQ_DESC_NUM; -+ spin_unlock_irqrestore(&priv->hw->lock, flags); -+ -+ if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN) -+ netif_tx_stop_queue(txq); -+ -+ priv->stats.tx_packets++; -+ priv->stats.tx_bytes+=len; -+ -+ return NETDEV_TX_OK; -+} -+ -+static irqreturn_t xrx200_dma_irq(int irq, void *priv) -+{ -+ struct xrx200_hw *hw = priv; -+ int ch = irq - XRX200_DMA_IRQ; -+ -+ napi_schedule(&hw->chan[ch].napi); -+ -+ return IRQ_HANDLED; -+} -+ -+static int xrx200_dma_init(struct xrx200_hw *hw) -+{ -+ int i, err = 0; -+ -+ ltq_dma_init_port(DMA_PORT_ETOP); -+ -+ for (i = 0; i < 8 && !err; i++) { -+ int irq = XRX200_DMA_IRQ + i; -+ struct xrx200_chan *ch = &hw->chan[i]; -+ -+ ch->idx = ch->dma.nr = i; -+ -+ if (i == XRX200_DMA_TX) { -+ ltq_dma_alloc_tx(&ch->dma); -+ err = request_irq(irq, xrx200_dma_irq, 0, "vrx200_tx", hw); -+ } else if (i == XRX200_DMA_RX) { -+ ltq_dma_alloc_rx(&ch->dma); -+ for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM; -+ ch->dma.desc++) -+ if (xrx200_alloc_skb(ch)) -+ err = -ENOMEM; -+ ch->dma.desc = 0; -+ err = request_irq(irq, xrx200_dma_irq, 0, "vrx200_rx", hw); -+ } else -+ continue; -+ -+ if (!err) -+ ch->dma.irq = irq; -+ } -+ -+ return err; -+} -+ -+#ifdef SW_POLLING -+static void xrx200_gmac_update(struct xrx200_port *port) -+{ -+ u16 phyaddr = port->phydev->addr & MDIO_PHY_ADDR_MASK; -+ u16 miimode = ltq_mii_r32(MII_CFG(port->num)) & MII_CFG_MODE_MASK; -+ u16 miirate = 0; -+ -+ switch (port->phydev->speed) { -+ case SPEED_1000: -+ phyaddr |= MDIO_PHY_SPEED_G1; -+ miirate = MII_CFG_RATE_M125; -+ break; -+ -+ case SPEED_100: -+ phyaddr |= MDIO_PHY_SPEED_M100; -+ switch (miimode) { -+ case MII_CFG_MODE_RMIIM: -+ case MII_CFG_MODE_RMIIP: -+ miirate = MII_CFG_RATE_M50; -+ break; -+ default: -+ miirate = MII_CFG_RATE_M25; -+ break; -+ } -+ break; -+ -+ default: -+ phyaddr |= MDIO_PHY_SPEED_M10; -+ miirate = MII_CFG_RATE_M2P5; -+ break; -+ } -+ -+ if (port->phydev->link) -+ phyaddr |= MDIO_PHY_LINK_UP; -+ else -+ phyaddr |= MDIO_PHY_LINK_DOWN; -+ -+ if (port->phydev->duplex == DUPLEX_FULL) -+ phyaddr |= MDIO_PHY_FDUP_EN; -+ else -+ phyaddr |= MDIO_PHY_FDUP_DIS; -+ -+ ltq_mdio_w32_mask(MDIO_UPDATE_MASK, phyaddr, MDIO_PHY(port->num)); -+ ltq_mii_w32_mask(MII_CFG_RATE_MASK, miirate, MII_CFG(port->num)); -+ udelay(1); -+} -+#else -+static void xrx200_gmac_update(struct xrx200_port *port) -+{ -+ -+} -+#endif -+ -+static void xrx200_mdio_link(struct net_device *dev) -+{ -+ struct xrx200_priv *priv = netdev_priv(dev); -+ int i; -+ -+ for (i = 0; i < priv->num_port; i++) { -+ if (!priv->port[i].phydev) -+ continue; -+ -+ if (priv->port[i].link != priv->port[i].phydev->link) { -+ xrx200_gmac_update(&priv->port[i]); -+ priv->port[i].link = priv->port[i].phydev->link; -+ netdev_info(dev, "port %d %s link\n", -+ priv->port[i].num, -+ (priv->port[i].link)?("got"):("lost")); -+ } -+ } -+} -+ -+static inline int xrx200_mdio_poll(struct mii_bus *bus) -+{ -+ unsigned cnt = 10000; -+ -+ while (likely(cnt--)) { -+ unsigned ctrl = ltq_mdio_r32(MDIO_CTRL); -+ if ((ctrl & MDIO_BUSY) == 0) -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static int xrx200_mdio_wr(struct mii_bus *bus, int addr, int reg, u16 val) -+{ -+ if (xrx200_mdio_poll(bus)) -+ return 1; -+ -+ ltq_mdio_w32(val, MDIO_WRITE); -+ ltq_mdio_w32(MDIO_BUSY | MDIO_WR | -+ ((addr & MDIO_MASK) << MDIO_ADDRSHIFT) | -+ (reg & MDIO_MASK), -+ MDIO_CTRL); -+ -+ return 0; -+} -+ -+static int xrx200_mdio_rd(struct mii_bus *bus, int addr, int reg) -+{ -+ if (xrx200_mdio_poll(bus)) -+ return -1; -+ -+ ltq_mdio_w32(MDIO_BUSY | MDIO_RD | -+ ((addr & MDIO_MASK) << MDIO_ADDRSHIFT) | -+ (reg & MDIO_MASK), -+ MDIO_CTRL); -+ -+ if (xrx200_mdio_poll(bus)) -+ return -1; -+ -+ return ltq_mdio_r32(MDIO_READ); -+} -+ -+static int xrx200_mdio_probe(struct net_device *dev, struct xrx200_port *port) -+{ -+ struct xrx200_priv *priv = netdev_priv(dev); -+ struct phy_device *phydev = NULL; -+ unsigned val; -+ -+ phydev = priv->hw->mii_bus->phy_map[port->phy_addr]; -+ -+ if (!phydev) { -+ netdev_err(dev, "no PHY found\n"); -+ return -ENODEV; -+ } -+ -+ phydev = phy_connect(dev, dev_name(&phydev->dev), &xrx200_mdio_link, -+ 0, port->phy_if); -+ -+ if (IS_ERR(phydev)) { -+ netdev_err(dev, "Could not attach to PHY\n"); -+ return PTR_ERR(phydev); -+ } -+ -+ phydev->supported &= (SUPPORTED_10baseT_Half -+ | SUPPORTED_10baseT_Full -+ | SUPPORTED_100baseT_Half -+ | SUPPORTED_100baseT_Full -+ | SUPPORTED_1000baseT_Half -+ | SUPPORTED_1000baseT_Full -+ | SUPPORTED_Autoneg -+ | SUPPORTED_MII -+ | SUPPORTED_TP); -+ phydev->advertising = phydev->supported; -+ port->phydev = phydev; -+ -+ pr_info("%s: attached PHY [%s] (phy_addr=%s, irq=%d)\n", -+ dev->name, phydev->drv->name, -+ dev_name(&phydev->dev), phydev->irq); -+ -+#ifdef SW_POLLING -+ phy_read_status(phydev); -+ -+ val = xrx200_mdio_rd(priv->hw->mii_bus, MDIO_DEVAD_NONE, MII_CTRL1000); -+ val |= ADVERTIZE_MPD; -+ xrx200_mdio_wr(priv->hw->mii_bus, MDIO_DEVAD_NONE, MII_CTRL1000, val); -+ xrx200_mdio_wr(priv->hw->mii_bus, 0, 0, 0x1040); -+ -+ phy_start_aneg(phydev); -+#endif -+ return 0; -+} -+ -+static void xrx200_port_config(struct xrx200_priv *priv, -+ const struct xrx200_port *port) -+{ -+ u16 miimode = 0; -+ -+ switch (port->num) { -+ case 0: /* xMII0 */ -+ case 1: /* xMII1 */ -+ switch (port->phy_if) { -+ case PHY_INTERFACE_MODE_MII: -+ if (port->flags & XRX200_PORT_TYPE_PHY) -+ /* MII MAC mode, connected to external PHY */ -+ miimode = MII_CFG_MODE_MIIM; -+ else -+ /* MII PHY mode, connected to external MAC */ -+ miimode = MII_CFG_MODE_MIIP; -+ break; -+ case PHY_INTERFACE_MODE_RMII: -+ if (port->flags & XRX200_PORT_TYPE_PHY) -+ /* RMII MAC mode, connected to external PHY */ -+ miimode = MII_CFG_MODE_RMIIM; -+ else -+ /* RMII PHY mode, connected to external MAC */ -+ miimode = MII_CFG_MODE_RMIIP; -+ break; -+ case PHY_INTERFACE_MODE_RGMII: -+ /* RGMII MAC mode, connected to external PHY */ -+ miimode = MII_CFG_MODE_RGMII; -+ break; -+ default: -+ break; -+ } -+ break; -+ case 2: /* internal GPHY0 */ -+ case 3: /* internal GPHY0 */ -+ case 4: /* internal GPHY1 */ -+ switch (port->phy_if) { -+ case PHY_INTERFACE_MODE_MII: -+ case PHY_INTERFACE_MODE_GMII: -+ /* MII MAC mode, connected to internal GPHY */ -+ miimode = MII_CFG_MODE_MIIM; -+ break; -+ default: -+ break; -+ } -+ break; -+ case 5: /* internal GPHY1 or xMII2 */ -+ switch (port->phy_if) { -+ case PHY_INTERFACE_MODE_MII: -+ /* MII MAC mode, connected to internal GPHY */ -+ miimode = MII_CFG_MODE_MIIM; -+ break; -+ case PHY_INTERFACE_MODE_RGMII: -+ /* RGMII MAC mode, connected to external PHY */ -+ miimode = MII_CFG_MODE_RGMII; -+ break; -+ default: -+ break; -+ } -+ break; -+ default: -+ break; -+ } -+ -+ ltq_mii_w32_mask(MII_CFG_MODE_MASK, miimode | MII_CFG_EN, -+ MII_CFG(port->num)); -+} -+ -+static int xrx200_init(struct net_device *dev) -+{ -+ struct xrx200_priv *priv = netdev_priv(dev); -+ struct sockaddr mac; -+ int err, i; -+ -+#ifndef SW_POLLING -+ unsigned int reg = 0; -+ -+ /* enable auto polling */ -+ for (i = 0; i < priv->num_port; i++) -+ reg |= BIT(priv->port[i].num); -+ ltq_mdio_w32(reg, MDIO_CLK_CFG0); -+ ltq_mdio_w32(MDIO1_25MHZ, MDIO_CLK_CFG1); -+#endif -+ -+ /* setup each port */ -+ for (i = 0; i < priv->num_port; i++) -+ xrx200_port_config(priv, &priv->port[i]); -+ -+ memcpy(&mac.sa_data, priv->mac, ETH_ALEN); -+ if (!is_valid_ether_addr(mac.sa_data)) { -+ pr_warn("net-xrx200: invalid MAC, using random\n"); -+ eth_random_addr(mac.sa_data); -+ dev->addr_assign_type |= NET_ADDR_RANDOM; -+ } -+ -+ err = eth_mac_addr(dev, &mac); -+ if (err) -+ goto err_netdev; -+ -+ for (i = 0; i < priv->num_port; i++) -+ if (xrx200_mdio_probe(dev, &priv->port[i])) -+ pr_warn("xrx200-mdio: probing phy of port %d failed\n", -+ priv->port[i].num); -+ -+ return 0; -+ -+err_netdev: -+ unregister_netdev(dev); -+ free_netdev(dev); -+ return err; -+} -+ -+static void xrx200_pci_microcode(void) -+{ -+ int i; -+ -+ ltq_switch_w32_mask(PCE_TBL_CFG_ADDR_MASK | PCE_TBL_CFG_ADWR_MASK, -+ PCE_TBL_CFG_ADWR, PCE_TBL_CTRL); -+ ltq_switch_w32(0, PCE_TBL_MASK); -+ -+ for (i = 0; i < ARRAY_SIZE(pce_microcode); i++) { -+ ltq_switch_w32(i, PCE_TBL_ADDR); -+ ltq_switch_w32(pce_microcode[i].val[3], PCE_TBL_VAL(0)); -+ ltq_switch_w32(pce_microcode[i].val[2], PCE_TBL_VAL(1)); -+ ltq_switch_w32(pce_microcode[i].val[1], PCE_TBL_VAL(2)); -+ ltq_switch_w32(pce_microcode[i].val[0], PCE_TBL_VAL(3)); -+ -+ // start the table access: -+ ltq_switch_w32_mask(0, PCE_TBL_BUSY, PCE_TBL_CTRL); -+ while (ltq_switch_r32(PCE_TBL_CTRL) & PCE_TBL_BUSY); -+ } -+ -+ /* tell the switch that the microcode is loaded */ -+ ltq_switch_w32_mask(0, BIT(3), PCE_GCTRL_REG(0)); -+} -+ -+static void xrx200_hw_init(struct xrx200_hw *hw) -+{ -+ int i; -+ -+ /* enable clock gate */ -+ clk_enable(hw->clk); -+ -+ /* -+ * TODO: we should really disbale all phys/miis here and explicitly -+ * enable them in the device secific init function -+ */ -+ -+ /* disable port fetch/store dma */ -+ for (i = 0; i < 7; i++ ) { -+ ltq_switch_w32(0, FDMA_PCTRLx(i)); -+ ltq_switch_w32(0, SDMA_PCTRLx(i)); -+ } -+ -+ /* enable Switch */ -+ ltq_mdio_w32_mask(0, MDIO_GLOB_ENABLE, MDIO_GLOB); -+ -+ /* load the pce microcode */ -+ xrx200_pci_microcode(); -+ -+ /* Default unknown Broadcat/Multicast/Unicast port maps */ -+ ltq_switch_w32(0x7f, PCE_PMAP1); -+ ltq_switch_w32(0x7f, PCE_PMAP2); -+ ltq_switch_w32(0x7f, PCE_PMAP3); -+ -+ /* RMON Counter Enable for all physical ports */ -+ for (i = 0; i < 7; i++) -+ ltq_switch_w32(0x1, BM_PCFG(i)); -+ -+ /* disable auto polling */ -+ ltq_mdio_w32(0x0, MDIO_CLK_CFG0); -+ -+ /* enable port statistic counters */ -+ for (i = 0; i < 7; i++) -+ ltq_switch_w32(0x1, BM_PCFGx(i)); -+ -+ /* set IPG to 12 */ -+ ltq_pmac_w32_mask(PMAC_IPG_MASK, 0xb, PMAC_RX_IPG); -+ -+#ifdef SW_ROUTING -+ /* enable status header, enable CRC */ -+ ltq_pmac_w32_mask(0, -+ PMAC_HD_CTL_AST | PMAC_HD_CTL_RXSH | PMAC_HD_CTL_AS | PMAC_HD_CTL_AC, -+ PMAC_HD_CTL); -+#else -+ /* disable status header, enable CRC */ -+ ltq_pmac_w32_mask(PMAC_HD_CTL_AST | PMAC_HD_CTL_RXSH | PMAC_HD_CTL_AS, -+ PMAC_HD_CTL_AC, -+ PMAC_HD_CTL); -+#endif -+ -+ /* enable port fetch/store dma */ -+ for (i = 0; i < 7; i++ ) { -+ ltq_switch_w32_mask(0, 0x01, FDMA_PCTRLx(i)); -+ ltq_switch_w32_mask(0, 0x01, SDMA_PCTRLx(i)); -+ ltq_switch_w32_mask(0, PCE_INGRESS, PCE_PCTRL_REG(i, 0)); -+ } -+ -+ /* enable special tag insertion on cpu port */ -+ ltq_switch_w32_mask(0, 0x02, FDMA_PCTRLx(6)); -+} -+ -+static void xrx200_hw_cleanup(struct xrx200_hw *hw) -+{ -+ int i; -+ -+ /* disable the switch */ -+ ltq_mdio_w32_mask(MDIO_GLOB_ENABLE, 0, MDIO_GLOB); -+ -+ /* free the channels and IRQs */ -+ for (i = 0; i < 2; i++) { -+ ltq_dma_free(&hw->chan[i].dma); -+ if (hw->chan[i].dma.irq) -+ free_irq(hw->chan[i].dma.irq, hw); -+ } -+ -+ /* free the allocated RX ring */ -+ for (i = 0; i < LTQ_DESC_NUM; i++) -+ dev_kfree_skb_any(hw->chan[XRX200_DMA_RX].skb[i]); -+ -+ /* clear the mdio bus */ -+ mdiobus_unregister(hw->mii_bus); -+ mdiobus_free(hw->mii_bus); -+ -+ /* release the clock */ -+ clk_disable(hw->clk); -+ clk_put(hw->clk); -+} -+ -+static int xrx200_of_mdio(struct xrx200_hw *hw, struct device_node *np) -+{ -+ hw->mii_bus = mdiobus_alloc(); -+ if (!hw->mii_bus) -+ return -ENOMEM; -+ -+ hw->mii_bus->read = xrx200_mdio_rd; -+ hw->mii_bus->write = xrx200_mdio_wr; -+ hw->mii_bus->name = "lantiq,xrx200-mdio"; -+ snprintf(hw->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0); -+ -+ if (of_mdiobus_register(hw->mii_bus, np)) { -+ mdiobus_free(hw->mii_bus); -+ return -ENXIO; -+ } -+ -+ return 0; -+} -+ -+static void xrx200_of_port(struct xrx200_priv *priv, struct device_node *port) -+{ -+ const __be32 *addr, *id = of_get_property(port, "reg", NULL); -+ struct xrx200_port *p = &priv->port[priv->num_port]; -+ -+ if (!id) -+ return; -+ -+ memset(p, 0, sizeof(struct xrx200_port)); -+ p->phy_node = of_parse_phandle(port, "phy-handle", 0); -+ addr = of_get_property(p->phy_node, "reg", NULL); -+ if (!addr) -+ return; -+ -+ p->num = *id; -+ p->phy_addr = *addr; -+ p->phy_if = of_get_phy_mode(port); -+ if (p->phy_addr > 0x10) -+ p->flags = XRX200_PORT_TYPE_MAC; -+ else -+ p->flags = XRX200_PORT_TYPE_PHY; -+ priv->num_port++; -+ -+ /* is this port a wan port ? */ -+ if (priv->wan) -+ priv->hw->wan_map |= BIT(p->num); -+ -+ /* store the port id in the hw struct so we can map ports -> devices */ -+ priv->hw->port_map[p->num] = priv->hw->num_devs; -+} -+ -+static const struct net_device_ops xrx200_netdev_ops = { -+ .ndo_init = xrx200_init, -+ .ndo_open = xrx200_open, -+ .ndo_stop = xrx200_close, -+ .ndo_start_xmit = xrx200_start_xmit, -+ .ndo_set_mac_address = eth_mac_addr, -+ .ndo_validate_addr = eth_validate_addr, -+ .ndo_change_mtu = eth_change_mtu, -+ .ndo_get_stats = xrx200_get_stats, -+ .ndo_tx_timeout = xrx200_tx_timeout, -+}; -+ -+static void xrx200_of_iface(struct xrx200_hw *hw, struct device_node *iface) -+{ -+ struct xrx200_priv *priv; -+ struct device_node *port; -+ const __be32 *wan; -+ -+ /* alloc the network device */ -+ hw->devs[hw->num_devs] = alloc_etherdev(sizeof(struct xrx200_priv)); -+ if (!hw->devs[hw->num_devs]) -+ return; -+ -+ /* setup the network device */ -+ strcpy(hw->devs[hw->num_devs]->name, "eth%d"); -+ hw->devs[hw->num_devs]->netdev_ops = &xrx200_netdev_ops; -+ hw->devs[hw->num_devs]->watchdog_timeo = XRX200_TX_TIMEOUT; -+ hw->devs[hw->num_devs]->needed_headroom = XRX200_HEADROOM; -+ -+ /* setup our private data */ -+ priv = netdev_priv(hw->devs[hw->num_devs]); -+ priv->hw = hw; -+ priv->mac = of_get_mac_address(iface); -+ priv->id = hw->num_devs; -+ -+ /* is this the wan interface ? */ -+ wan = of_get_property(iface, "lantiq,wan", NULL); -+ if (wan && (*wan == 1)) -+ priv->wan = 1; -+ -+ /* load the ports that are part of the interface */ -+ for_each_child_of_node(iface, port) -+ if (of_device_is_compatible(port, "lantiq,xrx200-pdi-port")) -+ xrx200_of_port(priv, port); -+ -+ /* register the actual device */ -+ if (!register_netdev(hw->devs[hw->num_devs])) -+ hw->num_devs++; -+} -+ -+static struct xrx200_hw xrx200_hw; -+ -+static int __devinit xrx200_probe(struct platform_device *pdev) -+{ -+ struct resource *res[4]; -+ struct device_node *mdio_np, *iface_np; -+ int i; -+ -+ /* load the memory ranges */ -+ for (i = 0; i < 4; i++) { -+ res[i] = platform_get_resource(pdev, IORESOURCE_MEM, i); -+ if (!res[i]) { -+ dev_err(&pdev->dev, "failed to get resources\n"); -+ return -ENOENT; -+ } -+ } -+ xrx200_switch_membase = devm_request_and_ioremap(&pdev->dev, res[0]); -+ xrx200_mdio_membase = devm_request_and_ioremap(&pdev->dev, res[1]); -+ xrx200_mii_membase = devm_request_and_ioremap(&pdev->dev, res[2]); -+ xrx200_pmac_membase = devm_request_and_ioremap(&pdev->dev, res[3]); -+ if (!xrx200_switch_membase || !xrx200_mdio_membase || -+ !xrx200_mii_membase || !xrx200_pmac_membase) { -+ dev_err(&pdev->dev, "failed to request and remap io ranges \n"); -+ return -ENOMEM; -+ } -+ -+ /* get the clock */ -+ xrx200_hw.clk = clk_get(&pdev->dev, NULL); -+ if (IS_ERR(xrx200_hw.clk)) { -+ dev_err(&pdev->dev, "failed to get clock\n"); -+ return PTR_ERR(xrx200_hw.clk); -+ } -+ -+ /* bring up the dma engine and IP core */ -+ spin_lock_init(&xrx200_hw.lock); -+ xrx200_dma_init(&xrx200_hw); -+ xrx200_hw_init(&xrx200_hw); -+ -+ /* bring up the mdio bus */ -+ mdio_np = of_find_compatible_node(pdev->dev.of_node, NULL, -+ "lantiq,xrx200-mdio"); -+ if (mdio_np) -+ if (xrx200_of_mdio(&xrx200_hw, mdio_np)) -+ dev_err(&pdev->dev, "mdio probe failed\n"); -+ -+ /* load the interfaces */ -+ for_each_child_of_node(pdev->dev.of_node, iface_np) -+ if (of_device_is_compatible(iface_np, "lantiq,xrx200-pdi")) { -+ if (xrx200_hw.num_devs < XRX200_MAX_DEV) -+ xrx200_of_iface(&xrx200_hw, iface_np); -+ else -+ dev_err(&pdev->dev, -+ "only %d interfaces allowed\n", -+ XRX200_MAX_DEV); -+ } -+ -+ if (!xrx200_hw.num_devs) { -+ xrx200_hw_cleanup(&xrx200_hw); -+ dev_err(&pdev->dev, "failed to load interfaces\n"); -+ return -ENOENT; -+ } -+ -+ /* set wan port mask */ -+ ltq_pmac_w32(xrx200_hw.wan_map, PMAC_EWAN); -+ -+ for (i = 0; i < xrx200_hw.num_devs; i++) { -+ xrx200_hw.chan[XRX200_DMA_RX].devs[i] = xrx200_hw.devs[i]; -+ xrx200_hw.chan[XRX200_DMA_TX].devs[i] = xrx200_hw.devs[i]; -+ } -+ -+ /* setup NAPI */ -+ init_dummy_netdev(&xrx200_hw.chan[XRX200_DMA_RX].dummy_dev); -+ init_dummy_netdev(&xrx200_hw.chan[XRX200_DMA_TX].dummy_dev); -+ netif_napi_add(&xrx200_hw.chan[XRX200_DMA_RX].dummy_dev, -+ &xrx200_hw.chan[XRX200_DMA_RX].napi, xrx200_poll_rx, 32); -+ netif_napi_add(&xrx200_hw.chan[XRX200_DMA_TX].dummy_dev, -+ &xrx200_hw.chan[XRX200_DMA_TX].napi, xrx200_poll_tx, 8); -+ -+ platform_set_drvdata(pdev, &xrx200_hw); -+ -+ return 0; -+} -+ -+static int __devexit xrx200_remove(struct platform_device *pdev) -+{ -+ struct net_device *dev = platform_get_drvdata(pdev); -+ struct xrx200_priv *priv; -+ -+ if (!dev) -+ return 0; -+ -+ priv = netdev_priv(dev); -+ -+ /* free stack related instances */ -+ netif_stop_queue(dev); -+ netif_napi_del(&xrx200_hw.chan[XRX200_DMA_RX].napi); -+ netif_napi_del(&xrx200_hw.chan[XRX200_DMA_TX].napi); -+ -+ /* shut down hardware */ -+ xrx200_hw_cleanup(&xrx200_hw); -+ -+ /* remove the actual device */ -+ unregister_netdev(dev); -+ free_netdev(dev); -+ -+ return 0; -+} -+ -+static const struct of_device_id xrx200_match[] = { -+ { .compatible = "lantiq,xrx200-net" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, xrx200_match); -+ -+static struct platform_driver xrx200_driver = { -+ .probe = xrx200_probe, -+ .remove = __devexit_p(xrx200_remove), -+ .driver = { -+ .name = "lantiq,xrx200-net", -+ .of_match_table = xrx200_match, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+module_platform_driver(xrx200_driver); -+ -+MODULE_AUTHOR("John Crispin "); -+MODULE_DESCRIPTION("Lantiq SoC XRX200 ethernet"); -+MODULE_LICENSE("GPL"); --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0113-EASY80920-dts-file.patch b/target/linux/lantiq/patches-3.6/0113-EASY80920-dts-file.patch deleted file mode 100644 index 72dd3696c0..0000000000 --- a/target/linux/lantiq/patches-3.6/0113-EASY80920-dts-file.patch +++ /dev/null @@ -1,539 +0,0 @@ -From b072ba5c8e730b6d6e828cbc7caf99f669667831 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 22 Oct 2012 12:22:10 +0200 -Subject: [PATCH 113/113] EASY80920 dts file - ---- - arch/mips/lantiq/Kconfig | 4 + - arch/mips/lantiq/dts/Makefile | 1 + - arch/mips/lantiq/dts/easy80920.dts | 369 ++++++++++++++++++++++++++++++++++++ - arch/mips/lantiq/dts/vr9.dtsi | 116 ++++++++++++ - 4 files changed, 490 insertions(+) - create mode 100644 arch/mips/lantiq/dts/easy80920.dts - create mode 100644 arch/mips/lantiq/dts/vr9.dtsi - -diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig -index d84f361..c9d0984 100644 ---- a/arch/mips/lantiq/Kconfig -+++ b/arch/mips/lantiq/Kconfig -@@ -30,6 +30,10 @@ choice - config DT_EASY50712 - bool "Easy50712" - depends on SOC_XWAY -+ -+config DT_EASY80920 -+ bool "Easy80920" -+ depends on SOC_XWAY - endchoice - - config PCI_LANTIQ -diff --git a/arch/mips/lantiq/dts/Makefile b/arch/mips/lantiq/dts/Makefile -index 674fca4..0876c97 100644 ---- a/arch/mips/lantiq/dts/Makefile -+++ b/arch/mips/lantiq/dts/Makefile -@@ -1,4 +1,5 @@ - obj-$(CONFIG_DT_EASY50712) := easy50712.dtb.o -+obj-$(CONFIG_DT_EASY80920) := easy80920.dtb.o - - $(obj)/%.dtb: $(obj)/%.dts - $(call if_changed,dtc) -diff --git a/arch/mips/lantiq/dts/easy80920.dts b/arch/mips/lantiq/dts/easy80920.dts -new file mode 100644 -index 0000000..703e768 ---- /dev/null -+++ b/arch/mips/lantiq/dts/easy80920.dts -@@ -0,0 +1,369 @@ -+/dts-v1/; -+ -+ -+/include/ "vr9.dtsi" -+ -+/ { -+ chosen { -+ bootargs = "console=ttyLTQ0,115200 init=/etc/preinit"; -+ }; -+ -+ memory@0 { -+ reg = <0x0 0x4000000>; -+ }; -+ -+ fpi@10000000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "lantiq,fpi", "simple-bus"; -+ ranges = <0x0 0x10000000 0xEEFFFFF>; -+ reg = <0x10000000 0xEF00000>; -+ -+ localbus@0 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "lantiq,localbus", "simple-bus"; -+ -+ ranges = <0 0 0x0 0x3ffffff>; -+ nor-boot@0 { -+ compatible = "lantiq,nor"; -+ bank-width = <2>; -+ reg = <0 0x0 0x2000000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "uboot"; -+ reg = <0x00000 0x10000>; -+ }; -+ -+ partition@10000 { -+ label = "uboot_env"; -+ reg = <0x10000 0x10000>; -+ }; -+ -+ partition@20000 { -+ label = "linux"; -+ reg = <0x20000 0x7e0000>; -+ }; -+ }; -+ -+ /*ranges = <0 0 0x4000000 0x3ffffff>; -+ nand-parts@0 { -+ compatible = "gen_nand", "lantiq,nand-xway"; -+ lantiq,cs = <1>; -+ bank-width = <2>; -+ reg = <0 0x0 0x2000000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "uboot"; -+ reg = <0x00000 0x40000>; -+ }; -+ -+ partition@10000 { -+ label = "uboot_env"; -+ reg = <0x40000 0x40000>; -+ }; -+ -+ partition@20000 { -+ label = "linux"; -+ reg = <0x80000 0x3f80000>; -+ }; -+ };*/ -+ }; -+ -+ sflash@E100800 { -+ compatible = "lantiq,sflash"; -+ reg = <0xE100800 0x100>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ label = "uboot"; -+ reg = <0x00000 0x10000>; -+ }; -+ -+ partition@10000 { -+ label = "uboot_env"; -+ reg = <0x10000 0x10000>; -+ }; -+ -+ partition@20000 { -+ label = "linux"; -+ reg = <0x20000 0x1d0000>; -+ }; -+ }; -+ -+ gpio: pinmux@E100B10 { -+ compatible = "lantiq,pinctrl-xr9"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&state_default>; -+ -+ interrupt-parent = <&icu0>; -+ interrupts = <166 135 66 40 41 42 38>; -+ -+ #gpio-cells = <2>; -+ gpio-controller; -+ reg = <0xE100B10 0xA0>; -+ -+ state_default: pinmux { -+ stp { -+ lantiq,groups = "stp"; -+ lantiq,function = "stp"; -+ }; -+ /*spi { -+ lantiq,groups = "spi", "spi_cs4"; -+ lantiq,function = "spi"; -+ };*/ -+ nand { -+ lantiq,groups = "nand cle", "nand ale", -+ "nand rd", "nand rdy"; -+ lantiq,function = "ebu"; -+ }; -+ mdio { -+ lantiq,groups = "mdio"; -+ lantiq,function = "mdio"; -+ }; -+ pci { -+ lantiq,groups = "gnt1", "req1"; -+ lantiq,function = "pci"; -+ }; -+ exin { -+ lantiq,groups = "exin3"; -+ lantiq,function = "exin"; -+ }; -+ conf_out { -+ lantiq,pins = "io24", "io13", "io49", /* nand cle, ale and rd */ -+ "io4", "io5", "io6", /* stp */ -+ "io17", "io18", /* spi dout & clk */ -+ "io21", /* pci-rst */ -+ "io38"; /* pcie-rst */ -+ lantiq,open-drain; -+ lantiq,pull = <0>; -+ }; -+ conf_in { -+ lantiq,pins = "io39", /* exin3 */ -+ "io48"; /* nand rdy */ -+ lantiq,pull = <2>; -+ }; -+ }; -+ }; -+ -+ eth@0xE108000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "lantiq,xrx200-net"; -+ reg = < 0xE108000 0x3000 /* switch */ -+ 0xE10B100 0x70 /* mdio */ -+ 0xE10B1D8 0x30 /* mii */ -+ 0xE10B308 0x30 /* pmac */ -+ >; -+ interrupt-parent = <&icu0>; -+ interrupts = <73 72>; -+ -+ lan: interface@0 { -+ compatible = "lantiq,xrx200-pdi"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ mac-address = [ 00 11 22 33 44 55 ]; -+ -+ ethernet@0 { -+ compatible = "lantiq,xrx200-pdi-port"; -+ reg = <0>; -+ phy-mode = "rgmii"; -+ phy-handle = <&phy0>; -+ }; -+ ethernet@1 { -+ compatible = "lantiq,xrx200-pdi-port"; -+ reg = <1>; -+ phy-mode = "rgmii"; -+ phy-handle = <&phy1>; -+ }; -+ ethernet@2 { -+ compatible = "lantiq,xrx200-pdi-port"; -+ reg = <2>; -+ phy-mode = "gmii"; -+ phy-handle = <&phy11>; -+ }; -+ ethernet@4 { -+ compatible = "lantiq,xrx200-pdi-port"; -+ reg = <4>; -+ phynmode0 = "gmii"; -+ phy-handle = <&phy13>; -+ }; -+ }; -+ -+ wan: interface@1 { -+ compatible = "lantiq,xrx200-pdi"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ mac-address = [ 00 11 22 33 44 56 ]; -+ -+ ethernet@5 { -+ compatible = "lantiq,xrx200-pdi-port"; -+ reg = <5>; -+ phy-mode = "rgmii"; -+ phy-handle = <&phy5>; -+ }; -+ }; -+ -+ mdio@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "lantiq,xrx200-mdio"; -+ phy0: ethernet-phy@0 { -+ reg = <0x0>; -+ compatible = "lantiq,phy11g", "ethernet-phy-ieee802.3-c22"; -+ lantiq,c45-reg-init = <1 0 0 0>; -+ }; -+ phy1: ethernet-phy@1 { -+ reg = <0x1>; -+ compatible = "lantiq,phy11g", "ethernet-phy-ieee802.3-c22"; -+ lantiq,c45-reg-init = <1 0 0 0>; -+ }; -+ phy5: ethernet-phy@5 { -+ reg = <0x5>; -+ compatible = "lantiq,phy11g", "ethernet-phy-ieee802.3-c22"; -+ lantiq,c45-reg-init = <1 0 0 0>; -+ }; -+ phy11: ethernet-phy@11 { -+ reg = <0x11>; -+ compatible = "lantiq,phy11g", "ethernet-phy-ieee802.3-c22"; -+ lantiq,c45-reg-init = <1 0 0 0>; -+ }; -+ phy13: ethernet-phy@13 { -+ reg = <0x13>; -+ compatible = "lantiq,phy11g", "ethernet-phy-ieee802.3-c22"; -+ lantiq,c45-reg-init = <1 0 0 0>; -+ }; -+ }; -+ }; -+ -+ stp: stp@E100BB0 { -+ compatible = "lantiq,gpio-stp-xway"; -+ reg = <0xE100BB0 0x40>; -+ #gpio-cells = <2>; -+ gpio-controller; -+ -+ lantiq,shadow = <0xffff>; -+ lantiq,groups = <0x7>; -+ lantiq,dsl = <0x3>; -+ lantiq,phy1 = <0x7>; -+ lantiq,phy2 = <0x7>; -+ /* lantiq,rising; */ -+ }; -+ -+ pci@E105400 { -+ #address-cells = <3>; -+ #size-cells = <2>; -+ #interrupt-cells = <1>; -+ compatible = "lantiq,pci-xway"; -+ bus-range = <0x0 0x0>; -+ ranges = <0x2000000 0 0x8000000 0x8000000 0 0x2000000 /* pci memory */ -+ 0x1000000 0 0x00000000 0xAE00000 0 0x200000>; /* io space */ -+ reg = <0x7000000 0x8000 /* config space */ -+ 0xE105400 0x400>; /* pci bridge */ -+ lantiq,bus-clock = <33333333>; -+ /*lantiq,external-clock;*/ -+ lantiq,delay-hi = <0>; /* 0ns delay */ -+ lantiq,delay-lo = <0>; /* 0.0ns delay */ -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ 0x7000 0 0 1 &icu0 29 1 // slot 14, irq 29 -+ >; -+ gpios-reset = <&gpio 21 0>; -+ req-mask = <0x1>; /* GNT1 */ -+ }; -+ }; -+ -+ ifxhcd { -+ compatible = "lantiq,ifxhcd"; -+ interrupt-parent = <&icu0>; -+ interrupts = <62 91>; -+ }; -+ -+ gphy-xrx200 { -+ compatible = "lantiq,phy-xrx200"; -+ firmware = "lantiq/vr9_phy11g_a2x.bin"; -+ phys = [ 00 01 ]; -+ }; -+ -+ gpio-keys-polled { -+ compatible = "gpio-keys-polled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ poll-interval = <100>; -+ reset { -+ label = "Reset"; -+ gpios = <&gpio 7 0>; -+ linux,code = <0x100>; -+ }; -+ paging { -+ label = "paging"; -+ gpios = <&gpio 11 1>; -+ linux,code = <0x100>; -+ }; -+ }; -+ -+/* gpio-keys { -+ compatible = "gpio-keys"; -+ wps { -+ gpios = <&gpio 39 0>; -+ linux,code = <0x100>; -+ }; -+ };*/ -+ -+ gpio-leds { -+ compatible = "gpio-leds"; -+ -+ led0 { -+ label = "led0"; -+ gpios = <&stp 9 0>; -+ default-state = "on"; -+ }; -+ warning { -+ label = "warning"; -+ gpios = <&stp 22 0>; -+ default-state = "on"; -+ }; -+ fxs1 { -+ label = "fxs1"; -+ gpios = <&stp 21 0>; -+ default-state = "on"; -+ }; -+ fxs2 { -+ label = "fxs2"; -+ gpios = <&stp 20 0>; -+ default-state = "on"; -+ }; -+ fxo { -+ label = "fxo"; -+ gpios = <&stp 19 0>; -+ default-state = "on"; -+ }; -+ usb1 { -+ label = "usb1"; -+ gpios = <&stp 18 0>; -+ default-state = "on"; -+ }; -+ usb2 { -+ label = "usb2"; -+ gpios = <&stp 15 0>; -+ default-state = "on"; -+ }; -+ sd { -+ label = "sd"; -+ gpios = <&stp 14 0>; -+ default-state = "on"; -+ }; -+ wps { -+ label = "wps"; -+ gpios = <&stp 12 0>; -+ default-state = "on"; -+ }; -+ }; -+}; -diff --git a/arch/mips/lantiq/dts/vr9.dtsi b/arch/mips/lantiq/dts/vr9.dtsi -new file mode 100644 -index 0000000..d3adb58 ---- /dev/null -+++ b/arch/mips/lantiq/dts/vr9.dtsi -@@ -0,0 +1,116 @@ -+/ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "lantiq,xway", "lantiq,vr9"; -+ -+ cpus { -+ cpu@0 { -+ compatible = "mips,mips34Kc"; -+ }; -+ }; -+ -+ biu@1F800000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "lantiq,biu", "simple-bus"; -+ reg = <0x1F800000 0x800000>; -+ ranges = <0x0 0x1F800000 0x7FFFFF>; -+ -+ icu0: icu@80200 { -+ #interrupt-cells = <1>; -+ interrupt-controller; -+ compatible = "lantiq,icu"; -+ reg = <0x80200 0x28 -+ 0x80228 0x28 -+ 0x80250 0x28 -+ 0x80278 0x28 -+ 0x802a0 0x28>; -+ }; -+ -+ watchdog@803F0 { -+ compatible = "lantiq,wdt"; -+ reg = <0x803F0 0x10>; -+ }; -+ }; -+ -+ sram@1F000000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "lantiq,sram"; -+ reg = <0x1F000000 0x800000>; -+ ranges = <0x0 0x1F000000 0x7FFFFF>; -+ -+ eiu0: eiu@101000 { -+ compatible = "lantiq,eiu"; -+ #interrupt-cells = <1>; -+ interrupt-controller; -+ interrupt-parent; -+ reg = <0x101000 0x1000>; -+ lantiq,count = <6>; -+ }; -+ -+ pmu0: pmu@102000 { -+ compatible = "lantiq,pmu-xway"; -+ reg = <0x102000 0x1000>; -+ }; -+ -+ cgu0: cgu@103000 { -+ compatible = "lantiq,cgu-xway"; -+ reg = <0x103000 0x1000>; -+ #clock-cells = <1>; -+ }; -+ -+ rcu0: rcu@203000 { -+ compatible = "lantiq,rcu-xway"; -+ reg = <0x203000 0x1000>; -+ /* irq for thermal sensor */ -+ interrupt-parent = <&icu0>; -+ interrupts = <115>; -+ }; -+ }; -+ -+ fpi@10000000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "lantiq,fpi", "simple-bus"; -+ ranges = <0x0 0x10000000 0xEEFFFFF>; -+ reg = <0x10000000 0xEF00000>; -+ -+ gptu@E100A00 { -+ compatible = "lantiq,gptu-xway"; -+ reg = <0xE100A00 0x100>; -+ interrupt-parent = <&icu0>; -+ interrupts = <126 127 128 129 130 131>; -+ }; -+ -+ asc1: serial@E100C00 { -+ compatible = "lantiq,asc"; -+ reg = <0xE100C00 0x400>; -+ interrupt-parent = <&icu0>; -+ interrupts = <112 113 114>; -+ }; -+ -+ dma0: dma@E104100 { -+ compatible = "lantiq,dma-xway"; -+ reg = <0xE104100 0x800>; -+ }; -+ -+ ebu0: ebu@E105300 { -+ compatible = "lantiq,ebu-xway"; -+ reg = <0xE105300 0x100>; -+ }; -+ -+ pci0: pci@E105400 { -+ #address-cells = <3>; -+ #size-cells = <2>; -+ #interrupt-cells = <1>; -+ compatible = "lantiq,pci-xway"; -+ bus-range = <0x0 0x0>; -+ ranges = <0x2000000 0 0x8000000 0x8000000 0 0x2000000 /* pci memory */ -+ 0x1000000 0 0x00000000 0xAE00000 0 0x200000>; /* io space */ -+ reg = <0x7000000 0x8000 /* config space */ -+ 0xE105400 0x400>; /* pci bridge */ -+ }; -+ -+ }; -+}; --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0200-MIPS-dtb-image-hack.patch b/target/linux/lantiq/patches-3.6/0200-MIPS-dtb-image-hack.patch deleted file mode 100644 index 0c6fa51e1e..0000000000 --- a/target/linux/lantiq/patches-3.6/0200-MIPS-dtb-image-hack.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 5dd6dd9cddc0327b638d15f8c4f489fee6257fb0 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 2 Nov 2012 15:40:08 +0100 -Subject: [PATCH 200/201] MIPS: dtb image hack - ---- - arch/mips/kernel/head.S | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S -index ea695d9..be87456 100644 ---- a/arch/mips/kernel/head.S -+++ b/arch/mips/kernel/head.S -@@ -141,6 +141,9 @@ FEXPORT(__kernel_entry) - j kernel_entry - #endif - -+ .ascii "OWRTDTB:" -+ EXPORT(__image_dtb) -+ .fill 0x4000 - __REF - - NESTED(kernel_entry, 16, sp) # kernel entry point --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0201-lantiq-dtb-image-hack.patch b/target/linux/lantiq/patches-3.6/0201-lantiq-dtb-image-hack.patch deleted file mode 100644 index b2f781e557..0000000000 --- a/target/linux/lantiq/patches-3.6/0201-lantiq-dtb-image-hack.patch +++ /dev/null @@ -1,58 +0,0 @@ -From a86a157eb87fb21a62205a5382842c2f331fb473 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 2 Nov 2012 15:40:34 +0100 -Subject: [PATCH 201/201] lantiq: dtb image hack - ---- - arch/mips/lantiq/Kconfig | 12 ------------ - arch/mips/lantiq/prom.c | 4 +++- - 2 files changed, 3 insertions(+), 13 deletions(-) - -diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig -index c9d0984..bef648f 100644 ---- a/arch/mips/lantiq/Kconfig -+++ b/arch/mips/lantiq/Kconfig -@@ -24,18 +24,6 @@ config SOC_FALCON - - endchoice - --choice -- prompt "Devicetree" -- --config DT_EASY50712 -- bool "Easy50712" -- depends on SOC_XWAY -- --config DT_EASY80920 -- bool "Easy80920" -- depends on SOC_XWAY --endchoice -- - config PCI_LANTIQ - bool "PCI Support" - depends on SOC_XWAY && PCI -diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c -index 9f9e875..72b183a 100644 ---- a/arch/mips/lantiq/prom.c -+++ b/arch/mips/lantiq/prom.c -@@ -57,6 +57,8 @@ static void __init prom_init_cmdline(void) - } - } - -+extern struct boot_param_header __image_dtb; -+ - void __init plat_mem_setup(void) - { - ioport_resource.start = IOPORT_RESOURCE_START; -@@ -70,7 +72,7 @@ void __init plat_mem_setup(void) - * Load the builtin devicetree. This causes the chosen node to be - * parsed resulting in our memory appearing - */ -- __dt_setup_arch(&__dtb_start); -+ __dt_setup_arch(&__image_dtb); - } - - void __init device_tree_init(void) --- -1.7.10.4 - diff --git a/target/linux/lantiq/patches-3.6/0300-owrt-mtd-split.patch b/target/linux/lantiq/patches-3.6/0300-owrt-mtd-split.patch deleted file mode 100644 index 4f69ef96b3..0000000000 --- a/target/linux/lantiq/patches-3.6/0300-owrt-mtd-split.patch +++ /dev/null @@ -1,230 +0,0 @@ -From 2a295753a10823a47542c779a25bbb1f52c71281 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 3 Aug 2012 10:27:13 +0200 -Subject: [PATCH 19/25] owrt mtd split - ---- - .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 1 + - arch/mips/lantiq/setup.c | 7 + - drivers/mtd/Kconfig | 4 + - drivers/mtd/mtdpart.c | 173 +++++++++++++++++++- - 4 files changed, 184 insertions(+), 1 deletions(-) - -diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h -index 1ec8f2a..1ff93cc 100644 -diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig -index 982a98b..e2f3f3e 100644 ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -31,6 +31,10 @@ config MTD_ROOTFS_SPLIT - bool "Automatically split 'rootfs' partition for squashfs" - default y - -+config MTD_UIMAGE_SPLIT -+ bool "Automatically split 'linux' partition into 'kernel' and 'rootfs'" -+ default y -+ - config MTD_REDBOOT_PARTS - tristate "RedBoot partition table parsing" - ---help--- -diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c -index 855b70b..93711e2 100644 ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -867,6 +867,168 @@ static int refresh_rootfs_split(struct mtd_info *mtd) - } - #endif /* CONFIG_MTD_ROOTFS_SPLIT */ - -+#ifdef CONFIG_MTD_UIMAGE_SPLIT -+static unsigned long find_uimage_size(struct mtd_info *mtd, -+ unsigned long offset) -+{ -+#define UBOOT_MAGIC 0x56190527 -+ unsigned long magic = 0; -+ unsigned long temp; -+ size_t len; -+ int ret; -+ -+ ret = mtd_read(mtd, offset, 4, &len, (void *)&magic); -+ if (ret || len != sizeof(magic)) -+ return 0; -+ -+ if (le32_to_cpu(magic) != UBOOT_MAGIC) -+ return 0; -+ -+ ret = mtd_read(mtd, offset + 12, 4, &len, (void *)&temp); -+ if (ret || len != sizeof(temp)) -+ return 0; -+ -+ return temp + 0x40; -+} -+ -+static unsigned long find_eva_size(struct mtd_info *mtd, -+ unsigned long offset) -+{ -+#define EVA_MAGIC 0xfeed1281 -+ unsigned long magic = 0; -+ unsigned long temp; -+ size_t len; -+ int ret; -+ -+ ret = mtd_read(mtd, offset, 4, &len, (void *)&magic); -+ if (ret || len != sizeof(magic)) -+ return 0; -+ -+ if (le32_to_cpu(magic) != EVA_MAGIC) -+ return 0; -+ -+ ret = mtd_read(mtd, offset + 4, 4, &len, (void *)&temp); -+ if (ret || len != sizeof(temp)) -+ return 0; -+ -+ /* add eva header size */ -+ temp = le32_to_cpu(temp) + 0x18; -+ -+ temp &= ~0xffff; -+ temp += 0x10000; -+ return temp; -+} -+ -+static int detect_squashfs_partition(struct mtd_info *mtd, unsigned long offset) -+{ -+ unsigned long temp; -+ size_t len; -+ int ret; -+ -+ ret = mtd_read(mtd, offset, 4, &len, (void *)&temp); -+ if (ret || len != sizeof(temp)) -+ return 0; -+ -+ -+ return le32_to_cpu(temp) == SQUASHFS_MAGIC; -+} -+ -+static int detect_eva_squashfs_partition(struct mtd_info *mtd, unsigned long offset) -+{ -+ unsigned long temp; -+ size_t len; -+ int ret; -+ -+ ret = mtd_read(mtd, offset, 4, &len, (void *)&temp); -+ if (ret || len != sizeof(temp)) -+ return 0; -+ -+ return be32_to_cpu(temp) == SQUASHFS_MAGIC; -+} -+ -+static unsigned long find_brnimage_size(struct mtd_info *mtd, -+ unsigned long offset) -+{ -+ unsigned long buf[4]; -+ // Assume at most 2MB of kernel image -+ unsigned long end = offset + (2 << 20); -+ unsigned long ptr = offset + 0x400 - 12; -+ size_t len; -+ int ret; -+ -+ while (ptr < end) { -+ long size_min = ptr - 0x400 - 12 - offset; -+ long size_max = ptr + 12 - offset; -+ ret = mtd_read(mtd, ptr, 16, &len, (void *)buf); -+ if (ret || len != 16) -+ return 0; -+ -+ if (le32_to_cpu(buf[0]) < size_min || -+ le32_to_cpu(buf[0]) > size_max) { -+ ptr += 0x400; -+ continue; -+ } -+ -+ if (le32_to_cpu(buf[3]) == SQUASHFS_MAGIC) -+ return ptr + 12 - offset; -+ -+ ptr += 0x400; -+ } -+ -+ return 0; -+} -+ -+static int split_uimage(struct mtd_info *mtd, -+ const struct mtd_partition *part) -+{ -+ static struct mtd_partition split_partitions[] = { -+ { -+ .name = "kernel", -+ .offset = 0x0, -+ .size = 0x0, -+ }, { -+ .name = "rootfs", -+ .offset = 0x0, -+ .size = 0x0, -+ }, -+ }; -+ -+ split_partitions[0].size = find_uimage_size(mtd, part->offset); -+ if (!split_partitions[0].size) { -+ split_partitions[0].size = find_eva_size(mtd, part->offset); -+ if (!split_partitions[0].size) { -+ split_partitions[0].size = find_brnimage_size(mtd, part->offset); -+ if (!split_partitions[0].size) { -+ printk(KERN_NOTICE "no uImage or brnImage or eva found in linux partition\n"); -+ return -1; -+ } -+ } -+ } -+ -+ if (detect_eva_squashfs_partition(mtd, -+ part->offset -+ + split_partitions[0].size)) { -+ split_partitions[0].size += 0x100; -+ pr_info("found eva dummy squashfs behind kernel\n"); -+ } else if (!detect_squashfs_partition(mtd, -+ part->offset -+ + split_partitions[0].size)) { -+ split_partitions[0].size &= ~(mtd->erasesize - 1); -+ split_partitions[0].size += mtd->erasesize; -+ } else { -+ pr_info("found squashfs behind kernel\n"); -+ } -+ -+ split_partitions[0].offset = part->offset; -+ split_partitions[1].offset = part->offset + split_partitions[0].size; -+ split_partitions[1].size = part->size - split_partitions[0].size; -+ -+ add_mtd_partitions(mtd, split_partitions, 2); -+ -+ return 0; -+} -+#endif -+ - /* - * This function, given a master MTD object and a partition table, creates - * and registers slave MTD objects which are bound to the master according to -@@ -883,7 +1045,7 @@ int add_mtd_partitions(struct mtd_info *master, - struct mtd_part *slave; - uint64_t cur_offset = 0; - int i; --#ifdef CONFIG_MTD_ROOTFS_SPLIT -+#if defined(CONFIG_MTD_ROOTFS_SPLIT) || defined(CONFIG_MTD_UIMAGE_SPLIT) - int ret; - #endif - -@@ -900,6 +1062,15 @@ int add_mtd_partitions(struct mtd_info *master, - - add_mtd_device(&slave->mtd); - -+#ifdef CONFIG_MTD_UIMAGE_SPLIT -+ if (!strcmp(parts[i].name, "linux")) { -+ ret = split_uimage(master, &parts[i]); -+ -+ if (ret) -+ printk(KERN_WARNING "Can't split linux partition\n"); -+ } -+#endif -+ - if (!strcmp(parts[i].name, "rootfs")) { - #ifdef CONFIG_MTD_ROOTFS_ROOT_DEV - if (ROOT_DEV == 0) { --- -1.7.9.1 - diff --git a/target/linux/lantiq/patches-3.6/0301-owrt-atm.patch b/target/linux/lantiq/patches-3.6/0301-owrt-atm.patch deleted file mode 100644 index 63eb820c49..0000000000 --- a/target/linux/lantiq/patches-3.6/0301-owrt-atm.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 8d2a7d1fb561c9cb098c2b13ded34fe0f49dcca5 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 3 Aug 2012 10:27:25 +0200 -Subject: [PATCH 20/25] owrt atm - ---- - arch/mips/lantiq/irq.c | 2 ++ - arch/mips/mm/cache.c | 2 ++ - net/atm/common.c | 6 ++++++ - net/atm/proc.c | 2 +- - 4 files changed, 11 insertions(+), 1 deletions(-) - -Index: linux-3.6.6/arch/mips/lantiq/irq.c -=================================================================== ---- linux-3.6.6.orig/arch/mips/lantiq/irq.c 2012-11-08 23:08:47.000000000 +0100 -+++ linux-3.6.6/arch/mips/lantiq/irq.c 2012-11-08 23:10:32.023843184 +0100 -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -107,6 +108,7 @@ - ltq_icu_w32(im, ltq_icu_r32(im, ier) & ~BIT(offset), ier); - ltq_icu_w32(im, BIT(offset), isr); - } -+EXPORT_SYMBOL(ltq_mask_and_ack_irq); - - static void ltq_ack_irq(struct irq_data *d) - { -Index: linux-3.6.6/arch/mips/mm/cache.c -=================================================================== ---- linux-3.6.6.orig/arch/mips/mm/cache.c 2012-11-08 23:08:45.000000000 +0100 -+++ linux-3.6.6/arch/mips/mm/cache.c 2012-11-08 23:09:41.155841939 +0100 -@@ -58,6 +58,8 @@ - void (*_dma_cache_inv)(unsigned long start, unsigned long size); - - EXPORT_SYMBOL(_dma_cache_wback_inv); -+EXPORT_SYMBOL(_dma_cache_wback); -+EXPORT_SYMBOL(_dma_cache_inv); - - #endif /* CONFIG_DMA_NONCOHERENT */ - -Index: linux-3.6.6/net/atm/common.c -=================================================================== ---- linux-3.6.6.orig/net/atm/common.c 2012-11-05 09:57:06.000000000 +0100 -+++ linux-3.6.6/net/atm/common.c 2012-11-08 23:09:41.155841939 +0100 -@@ -62,11 +62,17 @@ - write_unlock_irq(&vcc_sklist_lock); - } - -+struct sk_buff* (*ifx_atm_alloc_tx)(struct atm_vcc *, unsigned int) = NULL; -+EXPORT_SYMBOL(ifx_atm_alloc_tx); -+ - static struct sk_buff *alloc_tx(struct atm_vcc *vcc, unsigned int size) - { - struct sk_buff *skb; - struct sock *sk = sk_atm(vcc); - -+ if (ifx_atm_alloc_tx != NULL) -+ return ifx_atm_alloc_tx(vcc, size); -+ - if (sk_wmem_alloc_get(sk) && !atm_may_send(vcc, size)) { - pr_debug("Sorry: wmem_alloc = %d, size = %d, sndbuf = %d\n", - sk_wmem_alloc_get(sk), size, sk->sk_sndbuf); -Index: linux-3.6.6/net/atm/proc.c -=================================================================== ---- linux-3.6.6.orig/net/atm/proc.c 2012-11-05 09:57:06.000000000 +0100 -+++ linux-3.6.6/net/atm/proc.c 2012-11-08 23:09:41.159841940 +0100 -@@ -154,7 +154,7 @@ - static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc) - { - static const char *const class_name[] = { -- "off", "UBR", "CBR", "VBR", "ABR"}; -+ "off","UBR","CBR","NTR-VBR","ABR","ANY","RT-VBR","UBR+","GFR"}; - static const char *const aal_name[] = { - "---", "1", "2", "3/4", /* 0- 3 */ - "???", "5", "???", "???", /* 4- 7 */ -- cgit v1.2.3