summaryrefslogtreecommitdiff
path: root/target/linux/lantiq/patches-3.3/0004-lantiq-core-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/lantiq/patches-3.3/0004-lantiq-core-support.patch')
-rw-r--r--target/linux/lantiq/patches-3.3/0004-lantiq-core-support.patch1009
1 files changed, 0 insertions, 1009 deletions
diff --git a/target/linux/lantiq/patches-3.3/0004-lantiq-core-support.patch b/target/linux/lantiq/patches-3.3/0004-lantiq-core-support.patch
deleted file mode 100644
index d048988..0000000
--- a/target/linux/lantiq/patches-3.3/0004-lantiq-core-support.patch
+++ /dev/null
@@ -1,1009 +0,0 @@
-From 94a0ad7aea40f0143670cfb6d5794f2f4b6b1aa7 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Fri, 3 Aug 2012 09:51:32 +0200
-Subject: [PATCH 04/25] lantiq core support
-
----
- arch/mips/Kconfig | 6 +-
- arch/mips/lantiq/Kconfig | 10 ++
- arch/mips/lantiq/Makefile | 2 +
- arch/mips/lantiq/Platform | 2 +
- arch/mips/lantiq/clk.c | 136 +++++++++++----------
- arch/mips/lantiq/clk.h | 59 ++++++++-
- arch/mips/lantiq/devices.c | 30 +----
- arch/mips/lantiq/devices.h | 4 +
- arch/mips/lantiq/early_printk.c | 14 ++-
- arch/mips/lantiq/irq.c | 262 +++++++++++++++++++++++++++++++--------
- arch/mips/lantiq/machtypes.h | 5 +
- arch/mips/lantiq/prom.c | 63 ++++++++--
- arch/mips/lantiq/prom.h | 4 +
- 13 files changed, 435 insertions(+), 162 deletions(-)
-
-diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
-index cffcae6..0e2ce5d 100644
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -228,8 +228,11 @@ config LANTIQ
- select ARCH_REQUIRE_GPIOLIB
- select SWAP_IO_SPACE
- select BOOT_RAW
-- select HAVE_CLK
-+ select HAVE_MACH_CLKDEV
-+ select CLKDEV_LOOKUP
-+ select HAVE_OPROFILE
- select MIPS_MACHINE
-+ select USB_ARCH_HAS_HCD
-
- config LASAT
- bool "LASAT Networks platforms"
-@@ -2391,6 +2394,7 @@ config PCI_DOMAINS
- bool
-
- source "drivers/pci/Kconfig"
-+source "drivers/pci/pcie/Kconfig"
-
- #
- # ISA support is now enabled via select. Too many systems still have the one
-diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
-index 3fccf21..b7ba0fe 100644
---- a/arch/mips/lantiq/Kconfig
-+++ b/arch/mips/lantiq/Kconfig
-@@ -16,8 +16,18 @@ config SOC_XWAY
- bool "XWAY"
- select SOC_TYPE_XWAY
- select HW_HAS_PCI
-+
-+config SOC_FALCON
-+ bool "FALCON"
-+
-+config SOC_SVIP
-+ bool "SVIP"
-+ select MIPS_CPU_SCACHE
-+
- endchoice
-
- source "arch/mips/lantiq/xway/Kconfig"
-+source "arch/mips/lantiq/falcon/Kconfig"
-+source "arch/mips/lantiq/svip/Kconfig"
-
- endif
-diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile
-index e5dae0e..db1ce50 100644
---- a/arch/mips/lantiq/Makefile
-+++ b/arch/mips/lantiq/Makefile
-@@ -9,3 +9,5 @@ obj-y := irq.o setup.o clk.o prom.o devices.o
- obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
-
- obj-$(CONFIG_SOC_TYPE_XWAY) += xway/
-+obj-$(CONFIG_SOC_FALCON) += falcon/
-+obj-$(CONFIG_SOC_SVIP) += svip/
-diff --git a/arch/mips/lantiq/Platform b/arch/mips/lantiq/Platform
-index f3dff05..857548c 100644
---- a/arch/mips/lantiq/Platform
-+++ b/arch/mips/lantiq/Platform
-@@ -6,3 +6,5 @@ platform-$(CONFIG_LANTIQ) += lantiq/
- cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq
- load-$(CONFIG_LANTIQ) = 0xffffffff80002000
- cflags-$(CONFIG_SOC_TYPE_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway
-+cflags-$(CONFIG_SOC_FALCON) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/falcon
-+cflags-$(CONFIG_SOC_SVIP) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/svip
-diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c
-index 412814f..6c95f5e 100644
---- a/arch/mips/lantiq/clk.c
-+++ b/arch/mips/lantiq/clk.c
-@@ -12,6 +12,7 @@
- #include <linux/kernel.h>
- #include <linux/types.h>
- #include <linux/clk.h>
-+#include <linux/clkdev.h>
- #include <linux/err.h>
- #include <linux/list.h>
-
-@@ -22,44 +23,32 @@
- #include <lantiq_soc.h>
-
- #include "clk.h"
-+#include "prom.h"
-
--struct clk {
-- const char *name;
-- unsigned long rate;
-- unsigned long (*get_rate) (void);
--};
-+/* lantiq socs have 3 static clocks */
-+static struct clk cpu_clk_generic[3];
-
--static struct clk *cpu_clk;
--static int cpu_clk_cnt;
-+void clkdev_add_static(unsigned long cpu, unsigned long fpi, unsigned long io)
-+{
-+ cpu_clk_generic[0].rate = cpu;
-+ cpu_clk_generic[1].rate = fpi;
-+ cpu_clk_generic[2].rate = io;
-+}
-
--/* lantiq socs have 3 static clocks */
--static struct clk cpu_clk_generic[] = {
-- {
-- .name = "cpu",
-- .get_rate = ltq_get_cpu_hz,
-- }, {
-- .name = "fpi",
-- .get_rate = ltq_get_fpi_hz,
-- }, {
-- .name = "io",
-- .get_rate = ltq_get_io_region_clock,
-- },
--};
--
--static struct resource ltq_cgu_resource = {
-- .name = "cgu",
-- .start = LTQ_CGU_BASE_ADDR,
-- .end = LTQ_CGU_BASE_ADDR + LTQ_CGU_SIZE - 1,
-- .flags = IORESOURCE_MEM,
--};
--
--/* remapped clock register range */
--void __iomem *ltq_cgu_membase;
--
--void clk_init(void)
-+struct clk *clk_get_cpu(void)
- {
-- cpu_clk = cpu_clk_generic;
-- cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic);
-+ return &cpu_clk_generic[0];
-+}
-+
-+struct clk *clk_get_fpi(void)
-+{
-+ return &cpu_clk_generic[1];
-+}
-+EXPORT_SYMBOL_GPL(clk_get_fpi);
-+
-+struct clk *clk_get_io(void)
-+{
-+ return &cpu_clk_generic[2];
- }
-
- static inline int clk_good(struct clk *clk)
-@@ -82,37 +71,60 @@ unsigned long clk_get_rate(struct clk *clk)
- }
- EXPORT_SYMBOL(clk_get_rate);
-
--struct clk *clk_get(struct device *dev, const char *id)
-+int clk_set_rate(struct clk *clk, unsigned long rate)
- {
-- int i;
--
-- for (i = 0; i < cpu_clk_cnt; i++)
-- if (!strcmp(id, cpu_clk[i].name))
-- return &cpu_clk[i];
-- BUG();
-- return ERR_PTR(-ENOENT);
--}
--EXPORT_SYMBOL(clk_get);
-+ if (unlikely(!clk_good(clk)))
-+ return 0;
-
--void clk_put(struct clk *clk)
--{
-- /* not used */
-+ clk->rate = rate;
-+ return 0;
- }
--EXPORT_SYMBOL(clk_put);
-+EXPORT_SYMBOL(clk_set_rate);
-
- int clk_enable(struct clk *clk)
- {
-- /* not used */
-- return 0;
-+ if (unlikely(!clk_good(clk)))
-+ return -1;
-+
-+ if (clk->enable)
-+ return clk->enable(clk);
-+
-+ return -1;
- }
- EXPORT_SYMBOL(clk_enable);
-
- void clk_disable(struct clk *clk)
- {
-- /* not used */
-+ if (unlikely(!clk_good(clk)))
-+ return;
-+
-+ if (clk->disable)
-+ clk->disable(clk);
- }
- EXPORT_SYMBOL(clk_disable);
-
-+int clk_activate(struct clk *clk)
-+{
-+ if (unlikely(!clk_good(clk)))
-+ return -1;
-+
-+ if (clk->activate)
-+ return clk->activate(clk);
-+
-+ return -1;
-+}
-+EXPORT_SYMBOL(clk_activate);
-+
-+void clk_deactivate(struct clk *clk)
-+{
-+ if (unlikely(!clk_good(clk)))
-+ return;
-+
-+ if (clk->deactivate)
-+ clk->deactivate(clk);
-+}
-+EXPORT_SYMBOL(clk_deactivate);
-+
- static inline u32 ltq_get_counter_resolution(void)
- {
- u32 res;
-@@ -133,21 +145,17 @@ void __init plat_time_init(void)
- {
- struct clk *clk;
-
-- if (insert_resource(&iomem_resource, &ltq_cgu_resource) < 0)
-- panic("Failed to insert cgu memory");
--
-- if (request_mem_region(ltq_cgu_resource.start,
-- resource_size(&ltq_cgu_resource), "cgu") < 0)
-- panic("Failed to request cgu memory");
-+ ltq_soc_init();
-
-- ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start,
-- resource_size(&ltq_cgu_resource));
-- if (!ltq_cgu_membase) {
-- pr_err("Failed to remap cgu memory\n");
-- unreachable();
-- }
-- clk = clk_get(0, "cpu");
-+ clk = clk_get_cpu();
- mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution();
-+#ifdef CONFIG_SOC_SVIP
-+ write_c0_count(0);
-+ write_c0_compare(mips_hpt_frequency / HZ);
-+ enable_irq(MIPS_CPU_TIMER_IRQ);
-+#else
- write_c0_compare(read_c0_count());
-+#endif
-+ pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
- clk_put(clk);
- }
-diff --git a/arch/mips/lantiq/clk.h b/arch/mips/lantiq/clk.h
-index 3328925..564ef03 100644
---- a/arch/mips/lantiq/clk.h
-+++ b/arch/mips/lantiq/clk.h
-@@ -9,10 +9,61 @@
- #ifndef _LTQ_CLK_H__
- #define _LTQ_CLK_H__
-
--extern void clk_init(void);
-+#include <linux/clkdev.h>
-
--extern unsigned long ltq_get_cpu_hz(void);
--extern unsigned long ltq_get_fpi_hz(void);
--extern unsigned long ltq_get_io_region_clock(void);
-+/* clock speeds */
-+#define CLOCK_33M 33333333
-+#define CLOCK_60M 60000000
-+#define CLOCK_62_5M 62500000
-+#define CLOCK_83M 83333333
-+#define CLOCK_83_5M 83500000
-+#define CLOCK_98_304M 98304000
-+#define CLOCK_100M 100000000
-+#define CLOCK_111M 111111111
-+#define CLOCK_125M 125000000
-+#define CLOCK_133M 133333333
-+#define CLOCK_150M 150000000
-+#define CLOCK_166M 166666666
-+#define CLOCK_167M 166666667
-+#define CLOCK_196_608M 196608000
-+#define CLOCK_200M 200000000
-+#define CLOCK_250M 250000000
-+#define CLOCK_266M 266666666
-+#define CLOCK_300M 300000000
-+#define CLOCK_333M 333333333
-+#define CLOCK_393M 393215332
-+#define CLOCK_400M 400000000
-+#define CLOCK_500M 500000000
-+#define CLOCK_600M 600000000
-+
-+struct clk {
-+ struct clk_lookup cl;
-+ unsigned long rate;
-+ unsigned int module;
-+ unsigned int bits;
-+ unsigned long (*get_rate) (void);
-+ int (*enable) (struct clk *clk);
-+ void (*disable) (struct clk *clk);
-+ int (*activate) (struct clk *clk);
-+ void (*deactivate) (struct clk *clk);
-+ void (*reboot) (struct clk *clk);
-+};
-+
-+extern void clkdev_add_static(unsigned long cpu, unsigned long fpi,
-+ unsigned long io);
-+
-+extern unsigned long ltq_danube_cpu_hz(void);
-+extern unsigned long ltq_danube_fpi_hz(void);
-+extern unsigned long ltq_danube_io_region_clock(void);
-+
-+extern unsigned long ltq_svip_cpu_hz(void);
-+extern unsigned long ltq_svip_fpi_hz(void);
-+extern unsigned long ltq_svip_io_region_clock(void);
-+
-+extern unsigned long ltq_ar9_cpu_hz(void);
-+extern unsigned long ltq_ar9_fpi_hz(void);
-+
-+extern unsigned long ltq_vr9_cpu_hz(void);
-+extern unsigned long ltq_vr9_fpi_hz(void);
-
- #endif
-diff --git a/arch/mips/lantiq/devices.c b/arch/mips/lantiq/devices.c
-index de1cb2b..7193d78 100644
---- a/arch/mips/lantiq/devices.c
-+++ b/arch/mips/lantiq/devices.c
-@@ -27,12 +27,8 @@
- #include "devices.h"
-
- /* nor flash */
--static struct resource ltq_nor_resource = {
-- .name = "nor",
-- .start = LTQ_FLASH_START,
-- .end = LTQ_FLASH_START + LTQ_FLASH_MAX - 1,
-- .flags = IORESOURCE_MEM,
--};
-+static struct resource ltq_nor_resource =
-+ MEM_RES("nor", LTQ_FLASH_START, LTQ_FLASH_MAX);
-
- static struct platform_device ltq_nor = {
- .name = "ltq_nor",
-@@ -47,12 +43,8 @@ void __init ltq_register_nor(struct physmap_flash_data *data)
- }
-
- /* watchdog */
--static struct resource ltq_wdt_resource = {
-- .name = "watchdog",
-- .start = LTQ_WDT_BASE_ADDR,
-- .end = LTQ_WDT_BASE_ADDR + LTQ_WDT_SIZE - 1,
-- .flags = IORESOURCE_MEM,
--};
-+static struct resource ltq_wdt_resource =
-+ MEM_RES("watchdog", LTQ_WDT_BASE_ADDR, LTQ_WDT_SIZE);
-
- void __init ltq_register_wdt(void)
- {
-@@ -61,24 +53,14 @@ void __init ltq_register_wdt(void)
-
- /* asc ports */
- static struct resource ltq_asc0_resources[] = {
-- {
-- .name = "asc0",
-- .start = LTQ_ASC0_BASE_ADDR,
-- .end = LTQ_ASC0_BASE_ADDR + LTQ_ASC_SIZE - 1,
-- .flags = IORESOURCE_MEM,
-- },
-+ MEM_RES("asc0", LTQ_ASC0_BASE_ADDR, LTQ_ASC_SIZE),
- IRQ_RES(tx, LTQ_ASC_TIR(0)),
- IRQ_RES(rx, LTQ_ASC_RIR(0)),
- IRQ_RES(err, LTQ_ASC_EIR(0)),
- };
-
- static struct resource ltq_asc1_resources[] = {
-- {
-- .name = "asc1",
-- .start = LTQ_ASC1_BASE_ADDR,
-- .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
-- .flags = IORESOURCE_MEM,
-- },
-+ MEM_RES("asc1", LTQ_ASC1_BASE_ADDR, LTQ_ASC_SIZE),
- IRQ_RES(tx, LTQ_ASC_TIR(1)),
- IRQ_RES(rx, LTQ_ASC_RIR(1)),
- IRQ_RES(err, LTQ_ASC_EIR(1)),
-diff --git a/arch/mips/lantiq/devices.h b/arch/mips/lantiq/devices.h
-index 2947bb1..a03c23f 100644
---- a/arch/mips/lantiq/devices.h
-+++ b/arch/mips/lantiq/devices.h
-@@ -14,6 +14,10 @@
-
- #define IRQ_RES(resname, irq) \
- {.name = #resname, .start = (irq), .flags = IORESOURCE_IRQ}
-+#define MEM_RES(resname, adr_start, adr_size) \
-+ { .name = resname, .flags = IORESOURCE_MEM, \
-+ .start = ((adr_start) & ~KSEG1), \
-+ .end = ((adr_start + adr_size - 1) & ~KSEG1) }
-
- extern void ltq_register_nor(struct physmap_flash_data *data);
- extern void ltq_register_wdt(void);
-diff --git a/arch/mips/lantiq/early_printk.c b/arch/mips/lantiq/early_printk.c
-index 972e05f..5089075 100644
---- a/arch/mips/lantiq/early_printk.c
-+++ b/arch/mips/lantiq/early_printk.c
-@@ -12,11 +12,13 @@
- #include <lantiq.h>
- #include <lantiq_soc.h>
-
--/* no ioremap possible at this early stage, lets use KSEG1 instead */
--#define LTQ_ASC_BASE KSEG1ADDR(LTQ_ASC1_BASE_ADDR)
- #define ASC_BUF 1024
--#define LTQ_ASC_FSTAT ((u32 *)(LTQ_ASC_BASE + 0x0048))
--#define LTQ_ASC_TBUF ((u32 *)(LTQ_ASC_BASE + 0x0020))
-+#define LTQ_ASC_FSTAT ((u32 *)(LTQ_EARLY_ASC + 0x0048))
-+#ifdef __BIG_ENDIAN
-+#define LTQ_ASC_TBUF ((u32 *)(LTQ_EARLY_ASC + 0x0020 + 3))
-+#else
-+#define LTQ_ASC_TBUF ((u32 *)(LTQ_EARLY_ASC + 0x0020))
-+#endif
- #define TXMASK 0x3F00
- #define TXOFFSET 8
-
-@@ -27,7 +29,7 @@ void prom_putchar(char c)
- local_irq_save(flags);
- do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET);
- if (c == '\n')
-- ltq_w32('\r', LTQ_ASC_TBUF);
-- ltq_w32(c, LTQ_ASC_TBUF);
-+ ltq_w8('\r', LTQ_ASC_TBUF);
-+ ltq_w8(c, LTQ_ASC_TBUF);
- local_irq_restore(flags);
- }
-diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
-index d673731..63dbb83 100644
---- a/arch/mips/lantiq/irq.c
-+++ b/arch/mips/lantiq/irq.c
-@@ -9,12 +9,17 @@
-
- #include <linux/interrupt.h>
- #include <linux/ioport.h>
-+#include <linux/sched.h>
-
- #include <asm/bootinfo.h>
- #include <asm/irq_cpu.h>
-
- #include <lantiq_soc.h>
- #include <irq.h>
-+#ifdef CONFIG_SOC_SVIP
-+#include <ebu_reg.h>
-+#include <base_reg.h>
-+#endif
-
- /* register definitions */
- #define LTQ_ICU_IM0_ISR 0x0000
-@@ -40,17 +45,28 @@
-
- #define MAX_EIU 6
-
-+/* the performance counter */
-+#define LTQ_PERF_IRQ (INT_NUM_IM4_IRL0 + 31)
-+
- /* irqs generated by device attached to the EBU need to be acked in
- * a special manner
- */
- #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(x, y, m) ltq_w32((x), ltq_icu_membase[m] + (y))
-+#define ltq_icu_r32(x, m) 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))
-
-+/* our 2 ipi interrupts for VSMP */
-+#define MIPS_CPU_IPI_RESCHED_IRQ 0
-+#define MIPS_CPU_IPI_CALL_IRQ 1
-+
-+#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
-+int gic_present;
-+#endif
-+
- static unsigned short ltq_eiu_irq[MAX_EIU] = {
- LTQ_EIU_IR0,
- LTQ_EIU_IR1,
-@@ -60,11 +76,78 @@ static unsigned short ltq_eiu_irq[MAX_EIU] = {
- LTQ_EIU_IR5,
- };
-
--static struct resource ltq_icu_resource = {
-- .name = "icu",
-- .start = LTQ_ICU_BASE_ADDR,
-- .end = LTQ_ICU_BASE_ADDR + LTQ_ICU_SIZE - 1,
-- .flags = IORESOURCE_MEM,
-+static struct resource ltq_icu_resource[IM_NUM] = {
-+{
-+ .name = "icu_im0",
-+ .start = LTQ_ICU_BASE_ADDR,
-+ .end = LTQ_ICU_BASE_ADDR + LTQ_ICU_OFFSET - 1,
-+ .flags = IORESOURCE_MEM,
-+},
-+#if IM_NUM >= 2
-+{
-+ .name = "icu_im1",
-+#ifdef LTQ_ICU_BASE_ADDR1
-+ .start = LTQ_ICU_BASE_ADDR1,
-+ .end = LTQ_ICU_BASE_ADDR1 + LTQ_ICU_OFFSET - 1,
-+#else
-+ .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 1),
-+ .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 2) - 1,
-+#endif
-+ .flags = IORESOURCE_MEM,
-+},
-+#endif
-+#if IM_NUM >= 3
-+{
-+ .name = "icu_im2",
-+#ifdef LTQ_ICU_BASE_ADDR2
-+ .start = LTQ_ICU_BASE_ADDR2,
-+ .end = LTQ_ICU_BASE_ADDR2 + LTQ_ICU_OFFSET - 1,
-+#else
-+ .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 2),
-+ .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 3) - 1,
-+#endif
-+ .flags = IORESOURCE_MEM,
-+},
-+#endif
-+#if IM_NUM >= 4
-+{
-+ .name = "icu_im3",
-+#ifdef LTQ_ICU_BASE_ADDR3
-+ .start = LTQ_ICU_BASE_ADDR3,
-+ .end = LTQ_ICU_BASE_ADDR3 + LTQ_ICU_OFFSET - 1,
-+#else
-+ .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 3),
-+ .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 4) - 1,
-+#endif
-+ .flags = IORESOURCE_MEM,
-+},
-+#endif
-+#if IM_NUM >= 5
-+{
-+ .name = "icu_im4",
-+#ifdef LTQ_ICU_BASE_ADDR4
-+ .start = LTQ_ICU_BASE_ADDR4,
-+ .end = LTQ_ICU_BASE_ADDR4 + LTQ_ICU_OFFSET - 1,
-+#else
-+ .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 4),
-+ .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 5) - 1,
-+#endif
-+ .flags = IORESOURCE_MEM,
-+},
-+#endif
-+#if IM_NUM >= 6
-+{
-+ .name = "icu_im5",
-+#ifdef LTQ_ICU_BASE_ADDR5
-+ .start = LTQ_ICU_BASE_ADDR5,
-+ .end = LTQ_ICU_BASE_ADDR5 + LTQ_ICU_OFFSET - 1,
-+#else
-+ .start = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 5),
-+ .end = LTQ_ICU_BASE_ADDR + (LTQ_ICU_OFFSET * 6) - 1,
-+#endif
-+ .flags = IORESOURCE_MEM,
-+},
-+#endif
- };
-
- static struct resource ltq_eiu_resource = {
-@@ -74,50 +157,53 @@ static struct resource ltq_eiu_resource = {
- .flags = IORESOURCE_MEM,
- };
-
--static void __iomem *ltq_icu_membase;
-+static void __iomem *ltq_icu_membase[IM_NUM];
- static void __iomem *ltq_eiu_membase;
-
- void ltq_disable_irq(struct irq_data *d)
- {
-- u32 ier = LTQ_ICU_IM0_IER;
- int irq_nr = d->irq - INT_NUM_IRQ0;
-+ unsigned int im_nr;
-
-- ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
-+ im_nr = (irq_nr / INT_NUM_IM_OFFSET);
- irq_nr %= INT_NUM_IM_OFFSET;
-- ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
-+
-+ ltq_icu_w32(ltq_icu_r32(LTQ_ICU_IM0_IER, im_nr) & ~(1 << irq_nr),
-+ LTQ_ICU_IM0_IER, im_nr);
- }
-
- void ltq_mask_and_ack_irq(struct irq_data *d)
- {
-- u32 ier = LTQ_ICU_IM0_IER;
-- u32 isr = LTQ_ICU_IM0_ISR;
- int irq_nr = d->irq - INT_NUM_IRQ0;
-+ unsigned int im_nr;
-
-- ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
-- isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
-+ im_nr = (irq_nr / INT_NUM_IM_OFFSET);
- irq_nr %= INT_NUM_IM_OFFSET;
-- ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
-- ltq_icu_w32((1 << irq_nr), isr);
-+
-+ ltq_icu_w32(ltq_icu_r32(LTQ_ICU_IM0_IER, im_nr) & ~(1 << irq_nr), LTQ_ICU_IM0_IER, im_nr);
-+ ltq_icu_w32((1 << irq_nr), LTQ_ICU_IM0_ISR, im_nr);
- }
-
- static void ltq_ack_irq(struct irq_data *d)
- {
-- u32 isr = LTQ_ICU_IM0_ISR;
- int irq_nr = d->irq - INT_NUM_IRQ0;
-+ unsigned int im_nr;
-
-- isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
-+ im_nr = (irq_nr / INT_NUM_IM_OFFSET);
- irq_nr %= INT_NUM_IM_OFFSET;
-- ltq_icu_w32((1 << irq_nr), isr);
-+
-+ ltq_icu_w32((1 << irq_nr), LTQ_ICU_IM0_ISR, im_nr);
- }
-
- void ltq_enable_irq(struct irq_data *d)
- {
-- u32 ier = LTQ_ICU_IM0_IER;
- int irq_nr = d->irq - INT_NUM_IRQ0;
-+ unsigned int im_nr;
-
-- ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
-+ im_nr = (irq_nr / INT_NUM_IM_OFFSET);
- irq_nr %= INT_NUM_IM_OFFSET;
-- ltq_icu_w32(ltq_icu_r32(ier) | (1 << irq_nr), ier);
-+
-+ ltq_icu_w32(ltq_icu_r32(LTQ_ICU_IM0_IER, im_nr) | (1 << irq_nr), LTQ_ICU_IM0_IER, im_nr);
- }
-
- static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
-@@ -184,7 +270,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(LTQ_ICU_IM0_IOSR, module);
- if (irq == 0)
- return;
-
-@@ -194,10 +280,12 @@ static void ltq_hw_irqdispatch(int module)
- irq = __fls(irq);
- do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module));
-
-+#ifndef CONFIG_SOC_SVIP
- /* if this is a EBU irq, we need to ack it or get a deadlock */
-- if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0))
-+ if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0) && LTQ_EBU_PCC_ISTAT)
- ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10,
- LTQ_EBU_PCC_ISTAT);
-+#endif
- }
-
- #define DEFINE_HWx_IRQDISPATCH(x) \
-@@ -211,21 +299,66 @@ 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)
-+{
-+ setup_irq(irq, action);
-+ irq_set_handler(irq, handle_percpu_irq);
-+}
-+
-+static void ltq_sw0_irqdispatch(void)
-+{
-+ do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ);
-+}
-+
-+static void ltq_sw1_irqdispatch(void)
-+{
-+ do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
-+}
-+static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
-+{
-+ scheduler_ipi();
-+ return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
-+{
-+ smp_call_function_interrupt();
-+ return IRQ_HANDLED;
-+}
-+
-+static struct irqaction irq_resched = {
-+ .handler = ipi_resched_interrupt,
-+ .flags = IRQF_PERCPU,
-+ .name = "IPI_resched"
-+};
-+
-+static struct irqaction irq_call = {
-+ .handler = ipi_call_interrupt,
-+ .flags = IRQF_PERCPU,
-+ .name = "IPI_call"
-+};
-+#endif
-
- 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 {
-- for (i = 0; i < 5; i++) {
-+ for (i = 0; i < IM_NUM; i++) {
- if (pending & (CAUSEF_IP2 << i)) {
- ltq_hw_irqdispatch(i);
- goto out;
-@@ -247,41 +380,45 @@ void __init arch_init_irq(void)
- {
- int i;
-
-- if (insert_resource(&iomem_resource, &ltq_icu_resource) < 0)
-- panic("Failed to insert icu memory");
-+ for (i=0; i < IM_NUM; i++) {
-+ if (insert_resource(&iomem_resource, &ltq_icu_resource[i]) < 0)
-+ panic("Failed to insert icu memory\n");
-
-- if (request_mem_region(ltq_icu_resource.start,
-- resource_size(&ltq_icu_resource), "icu") < 0)
-- panic("Failed to request icu memory");
-+ if (request_mem_region(ltq_icu_resource[i].start,
-+ resource_size(&ltq_icu_resource[i]), "icu") < 0)
-+ panic("Failed to request icu memory\n");
-
-- ltq_icu_membase = ioremap_nocache(ltq_icu_resource.start,
-- resource_size(&ltq_icu_resource));
-- if (!ltq_icu_membase)
-- panic("Failed to remap icu memory");
-+ ltq_icu_membase[i] = ioremap_nocache(ltq_icu_resource[i].start,
-+ resource_size(&ltq_icu_resource[i]));
-+ if (!ltq_icu_membase[i])
-+ panic("Failed to remap icu memory\n");
-+ }
-
-- if (insert_resource(&iomem_resource, &ltq_eiu_resource) < 0)
-- panic("Failed to insert eiu memory");
-+ if (LTQ_EIU_BASE_ADDR) {
-+ if (insert_resource(&iomem_resource, &ltq_eiu_resource) < 0)
-+ panic("Failed to insert eiu memory\n");
-
-- if (request_mem_region(ltq_eiu_resource.start,
-- resource_size(&ltq_eiu_resource), "eiu") < 0)
-- panic("Failed to request eiu memory");
-+ if (request_mem_region(ltq_eiu_resource.start,
-+ resource_size(&ltq_eiu_resource), "eiu") < 0)
-+ panic("Failed to request eiu memory\n");
-
-- ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start,
-+ ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start,
- resource_size(&ltq_eiu_resource));
-- if (!ltq_eiu_membase)
-- panic("Failed to remap eiu memory");
-+ if (!ltq_eiu_membase)
-+ panic("Failed to remap eiu memory\n");
-+ }
-
- /* make sure all irqs are turned off by default */
-- for (i = 0; i < 5; i++)
-- ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET));
--
-- /* clear all possibly pending interrupts */
-- ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET));
-+ for (i = 0; i < IM_NUM; i++) {
-+ ltq_icu_w32(0, LTQ_ICU_IM0_IER, i);
-+ /* clear all possibly pending interrupts */
-+ ltq_icu_w32(~0, LTQ_ICU_IM0_ISR, i);
-+ }
-
- mips_cpu_irq_init();
-
-- for (i = 2; i <= 6; i++)
-- setup_irq(i, &cascade);
-+ for (i = 0; i < IM_NUM; i++)
-+ setup_irq(i + 2, &cascade);
-
- if (cpu_has_vint) {
- pr_info("Setting up vectored interrupts\n");
-@@ -294,9 +431,9 @@ void __init arch_init_irq(void)
- }
-
- for (i = INT_NUM_IRQ0;
-- i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++)
-- if ((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) ||
-- (i == LTQ_EIU_IR2))
-+ i <= (INT_NUM_IRQ0 + (IM_NUM * INT_NUM_IM_OFFSET)); i++)
-+ if (((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) ||
-+ (i == LTQ_EIU_IR2)) && LTQ_EIU_BASE_ADDR)
- irq_set_chip_and_handler(i, &ltq_eiu_type,
- handle_level_irq);
- /* EIU3-5 only exist on ar9 and vr9 */
-@@ -308,6 +445,17 @@ void __init arch_init_irq(void)
- irq_set_chip_and_handler(i, &ltq_irq_type,
- handle_level_irq);
-
-+#if defined(CONFIG_MIPS_MT_SMP)
-+ if (cpu_has_vint) {
-+ pr_info("Setting up IPI vectored interrupts\n");
-+ set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ltq_sw0_irqdispatch);
-+ set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ltq_sw1_irqdispatch);
-+ }
-+ arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ,
-+ &irq_resched);
-+ arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ, &irq_call);
-+#endif
-+
- #if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
- set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
- IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
-@@ -315,9 +463,15 @@ void __init arch_init_irq(void)
- set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 |
- IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
- #endif
-+
-+ cp0_perfcount_irq = LTQ_PERF_IRQ;
- }
-
- unsigned int __cpuinit get_c0_compare_int(void)
- {
-+#ifdef CONFIG_SOC_SVIP
-+ return MIPS_CPU_TIMER_IRQ;
-+#else
- return CP0_LEGACY_COMPARE_IRQ;
-+#endif
- }
-diff --git a/arch/mips/lantiq/machtypes.h b/arch/mips/lantiq/machtypes.h
-index 7e01b8c..dfc6af7 100644
---- a/arch/mips/lantiq/machtypes.h
-+++ b/arch/mips/lantiq/machtypes.h
-@@ -15,6 +15,11 @@ enum lantiq_mach_type {
- LTQ_MACH_GENERIC = 0,
- LTQ_MACH_EASY50712, /* Danube evaluation board */
- LTQ_MACH_EASY50601, /* Amazon SE evaluation board */
-+
-+ /* FALCON */
-+ LANTIQ_MACH_EASY98000, /* Falcon Eval Board, NOR Flash */
-+ LANTIQ_MACH_EASY98000SF, /* Falcon Eval Board, Serial Flash */
-+ LANTIQ_MACH_EASY98000NAND, /* Falcon Eval Board, NAND Flash */
- };
-
- #endif
-diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
-index e34fcfd..00ad59c 100644
---- a/arch/mips/lantiq/prom.c
-+++ b/arch/mips/lantiq/prom.c
-@@ -16,6 +16,10 @@
- #include "prom.h"
- #include "clk.h"
-
-+/* access to the ebu needs to be locked between different drivers */
-+DEFINE_SPINLOCK(ebu_lock);
-+EXPORT_SYMBOL_GPL(ebu_lock);
-+
- static struct ltq_soc_info soc_info;
-
- unsigned int ltq_get_cpu_ver(void)
-@@ -45,27 +49,68 @@ static void __init prom_init_cmdline(void)
- char **argv = (char **) KSEG1ADDR(fw_arg1);
- int i;
-
-+ arcs_cmdline[0] = '\0';
-+
- for (i = 0; i < argc; i++) {
-- char *p = (char *) KSEG1ADDR(argv[i]);
-+ char *p = (char *) KSEG1ADDR(argv[i]);
-
-- if (p && *p) {
-+ if (CPHYSADDR(p) && *p) {
- strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
- strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
- }
- }
- }
-
--void __init prom_init(void)
-+void __iomem *ltq_remap_resource(struct resource *res)
- {
-- struct clk *clk;
-+ __iomem void *ret = NULL;
-+ struct resource *lookup = lookup_resource(&iomem_resource, res->start);
-+
-+ if (lookup && strcmp(lookup->name, res->name)) {
-+ pr_err("conflicting memory range %s\n", res->name);
-+ return NULL;
-+ }
-+ if (!lookup) {
-+ if (insert_resource(&iomem_resource, res) < 0) {
-+ pr_err("Failed to insert %s memory\n", res->name);
-+ return NULL;
-+ }
-+ }
-+ if (request_mem_region(res->start,
-+ resource_size(res), res->name) < 0) {
-+ pr_err("Failed to request %s memory\n", res->name);
-+ goto err_res;
-+ }
-
-+ ret = ioremap_nocache(res->start, resource_size(res));
-+ if (!ret)
-+ goto err_mem;
-+
-+ pr_debug("remap: 0x%08X-0x%08X : \"%s\"\n",
-+ res->start, res->end, res->name);
-+ return ret;
-+
-+err_mem:
-+ panic("Failed to remap %s memory\n", res->name);
-+ release_mem_region(res->start, resource_size(res));
-+
-+err_res:
-+ release_resource(res);
-+ return NULL;
-+}
-+EXPORT_SYMBOL(ltq_remap_resource);
-+
-+void __init prom_init(void)
-+{
- ltq_soc_detect(&soc_info);
-- clk_init();
-- clk = clk_get(0, "cpu");
-- snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev1.%d",
-- soc_info.name, soc_info.rev);
-- clk_put(clk);
-+ snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev %s",
-+ soc_info.name, soc_info.rev_type);
- soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
- pr_info("SoC: %s\n", soc_info.sys_type);
- prom_init_cmdline();
-+
-+#if defined(CONFIG_MIPS_MT_SMP)
-+ if (register_vsmp_smp_ops())
-+ panic("failed to register_vsmp_smp_ops()");
-+#endif
- }
-diff --git a/arch/mips/lantiq/prom.h b/arch/mips/lantiq/prom.h
-index b4229d9..51dba1b 100644
---- a/arch/mips/lantiq/prom.h
-+++ b/arch/mips/lantiq/prom.h
-@@ -9,17 +9,21 @@
- #ifndef _LTQ_PROM_H__
- #define _LTQ_PROM_H__
-
-+#define LTQ_SYS_REV_LEN 0x10
- #define LTQ_SYS_TYPE_LEN 0x100
-
- struct ltq_soc_info {
- unsigned char *name;
- unsigned int rev;
-+ unsigned char rev_type[LTQ_SYS_REV_LEN];
-+ unsigned int srev;
- unsigned int partnum;
- unsigned int type;
- unsigned char sys_type[LTQ_SYS_TYPE_LEN];
- };
-
- extern void ltq_soc_detect(struct ltq_soc_info *i);
-+extern void ltq_soc_init(void);
- extern void ltq_soc_setup(void);
-
- #endif
---
-1.7.9.1
-