* [RESEND PATCH V2 02/17] OF: MIPS: lantiq: implement OF support
[not found] ` <1337017363-14424-1-git-send-email-blogic-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
@ 2012-05-14 17:42 ` John Crispin
0 siblings, 0 replies; 2+ messages in thread
From: John Crispin @ 2012-05-14 17:42 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
Activate USE_OF, add a sample DTS file and convert the core soc code to OF.
Signed-off-by: John Crispin <blogic-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
---
This patch is part of a series moving the mips/lantiq target to OF and clkdev
support. The patch, once Acked, should go upstream via Ralf's MIPS tree.
arch/mips/Kconfig | 1 +
arch/mips/lantiq/Kconfig | 9 +++
arch/mips/lantiq/Makefile | 4 +-
arch/mips/lantiq/dts/Makefile | 4 +
arch/mips/lantiq/dts/danube.dtsi | 105 +++++++++++++++++++++++++++++++++
arch/mips/lantiq/dts/easy50712.dts | 113 ++++++++++++++++++++++++++++++++++++
arch/mips/lantiq/prom.c | 57 ++++++++++++++----
arch/mips/lantiq/prom.h | 2 +
arch/mips/lantiq/setup.c | 43 --------------
arch/mips/lantiq/xway/ebu.c | 4 -
arch/mips/lantiq/xway/reset.c | 29 ++++-----
11 files changed, 294 insertions(+), 77 deletions(-)
create mode 100644 arch/mips/lantiq/dts/Makefile
create mode 100644 arch/mips/lantiq/dts/danube.dtsi
create mode 100644 arch/mips/lantiq/dts/easy50712.dts
delete mode 100644 arch/mips/lantiq/setup.c
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 27b392e..08b0312 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -229,6 +229,7 @@ config LANTIQ
select SWAP_IO_SPACE
select BOOT_RAW
select HAVE_CLK
+ select USE_OF
config LASAT
bool "LASAT Networks platforms"
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
index 2780461..9485fe5 100644
--- a/arch/mips/lantiq/Kconfig
+++ b/arch/mips/lantiq/Kconfig
@@ -18,4 +18,13 @@ config SOC_XWAY
select HW_HAS_PCI
endchoice
+
+choice
+ prompt "Devicetree"
+
+config DT_EASY50712
+ bool "Easy50712"
+ depends on SOC_XWAY
+endchoice
+
endif
diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile
index a268391..16f1c75 100644
--- a/arch/mips/lantiq/Makefile
+++ b/arch/mips/lantiq/Makefile
@@ -4,7 +4,9 @@
# under the terms of the GNU General Public License version 2 as published
# by the Free Software Foundation.
-obj-y := irq.o setup.o clk.o prom.o
+obj-y := irq.o clk.o prom.o
+
+obj-y += dts/
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/arch/mips/lantiq/dts/Makefile b/arch/mips/lantiq/dts/Makefile
new file mode 100644
index 0000000..674fca4
--- /dev/null
+++ b/arch/mips/lantiq/dts/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_DT_EASY50712) := easy50712.dtb.o
+
+$(obj)/%.dtb: $(obj)/%.dts
+ $(call if_changed,dtc)
diff --git a/arch/mips/lantiq/dts/danube.dtsi b/arch/mips/lantiq/dts/danube.dtsi
new file mode 100644
index 0000000..3a4520f
--- /dev/null
+++ b/arch/mips/lantiq/dts/danube.dtsi
@@ -0,0 +1,105 @@
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "lantiq,xway", "lantiq,danube";
+
+ cpus {
+ cpu@0 {
+ compatible = "mips,mips24Kc";
+ };
+ };
+
+ 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 0x120>;
+ };
+
+ 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 {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ interrupt-parent;
+ compatible = "lantiq,eiu-xway";
+ reg = <0x101000 0x1000>;
+ };
+
+ 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>;
+ };
+ };
+
+ 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>;
+ };
+
+ 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 */
+ };
+ };
+};
diff --git a/arch/mips/lantiq/dts/easy50712.dts b/arch/mips/lantiq/dts/easy50712.dts
new file mode 100644
index 0000000..68c1731
--- /dev/null
+++ b/arch/mips/lantiq/dts/easy50712.dts
@@ -0,0 +1,113 @@
+/dts-v1/;
+
+/include/ "danube.dtsi"
+
+/ {
+ chosen {
+ bootargs = "console=ttyLTQ0,115200 init=/etc/preinit";
+ };
+
+ memory@0 {
+ reg = <0x0 0x2000000>;
+ };
+
+ fpi@10000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ localbus@0 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0x0 0x3ffffff /* addrsel0 */
+ 1 0 0x4000000 0x4000010>; /* addsel1 */
+ compatible = "lantiq,localbus", "simple-bus";
+
+ 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>; /* 64 KB */
+ };
+
+ partition@10000 {
+ label = "uboot_env";
+ reg = <0x10000 0x10000>; /* 64 KB */
+ };
+
+ partition@20000 {
+ label = "linux";
+ reg = <0x20000 0x3d0000>;
+ };
+
+ partition@400000 {
+ label = "rootfs";
+ reg = <0x400000 0x400000>;
+ };
+ };
+ };
+
+ 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";
+ };
+ exin {
+ lantiq,groups = "exin1";
+ lantiq,function = "exin";
+ };
+ pci {
+ lantiq,groups = "gnt1";
+ lantiq,function = "pci";
+ };
+ conf_out {
+ lantiq,pins = "io4", "io5", "io6"; /* stp */
+ lantiq,open-drain;
+ lantiq,pull = <0>;
+ };
+ };
+ };
+
+ etop@E180000 {
+ compatible = "lantiq,etop-xway";
+ reg = <0xE180000 0x40000>;
+ interrupt-parent = <&icu0>;
+ interrupts = <73 78>;
+ phy-mode = "rmii";
+ mac-address = [ 00 11 22 33 44 55 ];
+ };
+
+ stp0: stp@E100BB0 {
+ #gpio-cells = <2>;
+ compatible = "lantiq,gpio-stp-xway";
+ gpio-controller;
+ reg = <0xE100BB0 0x40>;
+
+ lantiq,shadow = <0xfff>;
+ lantiq,groups = <0x3>;
+ };
+
+ pci@E105400 {
+ lantiq,bus-clock = <33333333>;
+ 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 */
+ };
+
+ };
+};
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
index cd56892..413ed53 100644
--- a/arch/mips/lantiq/prom.c
+++ b/arch/mips/lantiq/prom.c
@@ -8,6 +8,7 @@
#include <linux/export.h>
#include <linux/clk.h>
+#include <linux/of_platform.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
@@ -16,13 +17,15 @@
#include "prom.h"
#include "clk.h"
-static struct ltq_soc_info soc_info;
+/* access to the ebu needs to be locked between different drivers */
+DEFINE_SPINLOCK(ebu_lock);
+EXPORT_SYMBOL_GPL(ebu_lock);
-unsigned int ltq_get_cpu_ver(void)
-{
- return soc_info.rev;
-}
-EXPORT_SYMBOL(ltq_get_cpu_ver);
+/*
+ * this struct is filled by the soc specific detection code and holds
+ * information about the specific soc type, revision and name
+ */
+static struct ltq_soc_info soc_info;
unsigned int ltq_get_soc_type(void)
{
@@ -57,16 +60,28 @@ static void __init prom_init_cmdline(void)
}
}
-void __init prom_init(void)
+void __init plat_mem_setup(void)
{
- struct clk *clk;
+ ioport_resource.start = IOPORT_RESOURCE_START;
+ ioport_resource.end = IOPORT_RESOURCE_END;
+ iomem_resource.start = IOMEM_RESOURCE_START;
+ iomem_resource.end = IOMEM_RESOURCE_END;
+
+ set_io_port_base((unsigned long) KSEG1);
+
+ /*
+ * Load the builtin devicetree. This causes the chosen node to be
+ * parsed resulting in our memory appearing
+ */
+ __dt_setup_arch(&__dtb_start);
+}
+void __init prom_init(void)
+{
+ /* call the soc specific detetcion code and get it to fill soc_info */
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();
@@ -76,3 +91,19 @@ void __init prom_init(void)
panic("failed to register_vsmp_smp_ops()");
#endif
}
+
+int __init plat_of_setup(void)
+{
+ static struct of_device_id of_ids[3];
+
+ if (!of_have_populated_dt())
+ panic("device tree not present");
+
+ strncpy(of_ids[0].compatible, soc_info.compatible,
+ 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);
+}
+
+arch_initcall(plat_of_setup);
diff --git a/arch/mips/lantiq/prom.h b/arch/mips/lantiq/prom.h
index f7c2a79..a3fa1a2 100644
--- a/arch/mips/lantiq/prom.h
+++ b/arch/mips/lantiq/prom.h
@@ -26,4 +26,6 @@ struct ltq_soc_info {
extern void ltq_soc_detect(struct ltq_soc_info *i);
extern void ltq_soc_init(void);
+extern struct boot_param_header __dtb_start;
+
#endif
diff --git a/arch/mips/lantiq/setup.c b/arch/mips/lantiq/setup.c
deleted file mode 100644
index f1c605a..0000000
--- a/arch/mips/lantiq/setup.c
+++ /dev/null
@@ -1,43 +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 <blogic-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/export.h>
-#include <linux/io.h>
-#include <linux/ioport.h>
-#include <asm/bootinfo.h>
-
-#include <lantiq_soc.h>
-
-#include "prom.h"
-
-void __init plat_mem_setup(void)
-{
- /* assume 16M as default incase uboot fails to pass proper ramsize */
- unsigned long memsize = 16;
- char **envp = (char **) KSEG1ADDR(fw_arg2);
-
- ioport_resource.start = IOPORT_RESOURCE_START;
- ioport_resource.end = IOPORT_RESOURCE_END;
- iomem_resource.start = IOMEM_RESOURCE_START;
- iomem_resource.end = IOMEM_RESOURCE_END;
-
- set_io_port_base((unsigned long) KSEG1);
-
- while (*envp) {
- char *e = (char *)KSEG1ADDR(*envp);
- if (!strncmp(e, "memsize=", 8)) {
- e += 8;
- if (strict_strtoul(e, 0, &memsize))
- pr_warn("bad memsize specified\n");
- }
- envp++;
- }
- memsize *= 1024 * 1024;
- add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
-}
diff --git a/arch/mips/lantiq/xway/ebu.c b/arch/mips/lantiq/xway/ebu.c
index 862e3e8..419b47b 100644
--- a/arch/mips/lantiq/xway/ebu.c
+++ b/arch/mips/lantiq/xway/ebu.c
@@ -14,10 +14,6 @@
#include <lantiq_soc.h>
-/* all access to the ebu must be locked */
-DEFINE_SPINLOCK(ebu_lock);
-EXPORT_SYMBOL_GPL(ebu_lock);
-
static struct resource ltq_ebu_resource = {
.name = "ebu",
.start = LTQ_EBU_BASE_ADDR,
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
index 3327211..22c55f7 100644
--- a/arch/mips/lantiq/xway/reset.c
+++ b/arch/mips/lantiq/xway/reset.c
@@ -37,13 +37,6 @@
#define RCU_BOOT_SEL_SHIFT 26
#define RCU_BOOT_SEL_MASK 0x7
-static struct resource ltq_rcu_resource = {
- .name = "rcu",
- .start = LTQ_RCU_BASE_ADDR,
- .end = LTQ_RCU_BASE_ADDR + LTQ_RCU_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
/* remapped base addr of the reset control unit */
static void __iomem *ltq_rcu_membase;
@@ -91,17 +84,21 @@ static void ltq_machine_power_off(void)
static int __init mips_reboot_setup(void)
{
- /* insert and request the memory region */
- if (insert_resource(&iomem_resource, <q_rcu_resource) < 0)
- panic("Failed to insert rcu memory");
+ struct resource res;
+ struct device_node *np =
+ of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway");
+
+ /* check if all the reset register range is available */
+ if (!np)
+ panic("Failed to load reset resources from devicetree");
+
+ if (of_address_to_resource(np, 0, &res))
+ panic("Failed to get rcu memory range");
- if (request_mem_region(ltq_rcu_resource.start,
- resource_size(<q_rcu_resource), "rcu") < 0)
- panic("Failed to request rcu memory");
+ if (request_mem_region(res.start, resource_size(&res), res.name) < 0)
+ pr_err("Failed to request rcu memory");
- /* remap rcu register range */
- ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start,
- resource_size(<q_rcu_resource));
+ ltq_rcu_membase = ioremap_nocache(res.start, resource_size(&res));
if (!ltq_rcu_membase)
panic("Failed to remap core memory");
--
1.7.9.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [RESEND PATCH V2 03/17] OF: MIPS: lantiq: implement irq_domain support
[not found] <1337017363-14424-1-git-send-email-blogic@openwrt.org>
[not found] ` <1337017363-14424-1-git-send-email-blogic-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
@ 2012-05-14 17:42 ` John Crispin
1 sibling, 0 replies; 2+ messages in thread
From: John Crispin @ 2012-05-14 17:42 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips, John Crispin, devicetree-discuss, Grant Likely
Add support for irq_domain on lantiq socs. The conversion is straight forward
as the ICU found inside the socs allows the usage of irq_domain_add_linear.
Harware IRQ 0->7 are the generic MIPS IRQs. 8->199 are the Lantiq IRQ Modules.
Our irq_chip callbacks need to substract 8 (MIPS_CPU_IRQ_CASCADE) from d->hwirq
to find out the correct offset into the Interrupt Modules register range.
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: devicetree-discuss@lists.ozlabs.org
Cc: Grant Likely <grant.likely@secretlab.ca>
---
This patch is part of a series moving the mips/lantiq target to OF and clkdev
support. The patch, once Acked, should go upstream via Ralf's MIPS tree.
Changes in V2
* properly reserve 8 irqs for MIPS
* use d->hwirq rather than d->irq
* use BIT(x) instead of (1 << x)
* adds a optional property to allow setting the number of available EIU sources
* simplify icu_map()
arch/mips/lantiq/irq.c | 178 +++++++++++++++++++++++++++--------------------
1 files changed, 102 insertions(+), 76 deletions(-)
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index d227be1..57c1a4e 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -9,6 +9,11 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/irqdomain.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
#include <asm/bootinfo.h>
#include <asm/irq_cpu.h>
@@ -16,7 +21,7 @@
#include <lantiq_soc.h>
#include <irq.h>
-/* register definitions */
+/* register definitions - internal irqs */
#define LTQ_ICU_IM0_ISR 0x0000
#define LTQ_ICU_IM0_IER 0x0008
#define LTQ_ICU_IM0_IOSR 0x0010
@@ -25,6 +30,7 @@
#define LTQ_ICU_IM1_ISR 0x0028
#define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR)
+/* register definitions - external irqs */
#define LTQ_EIU_EXIN_C 0x0000
#define LTQ_EIU_EXIN_INIC 0x0004
#define LTQ_EIU_EXIN_INEN 0x000C
@@ -37,13 +43,14 @@
#define LTQ_EIU_IR4 (INT_NUM_IM1_IRL0 + 1)
#define LTQ_EIU_IR5 (INT_NUM_IM1_IRL0 + 2)
#define LTQ_EIU_IR6 (INT_NUM_IM2_IRL0 + 30)
-
+#define XWAY_EXIN_COUNT 3
#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
+/*
+ * irqs generated by devices attached to the EBU need to be acked in
* a special manner
*/
#define LTQ_ICU_EBU_IRQ 22
@@ -58,6 +65,9 @@
#define MIPS_CPU_IPI_RESCHED_IRQ 0
#define MIPS_CPU_IPI_CALL_IRQ 1
+/* we have a cascade of 8 irqs */
+#define MIPS_CPU_IRQ_CASCADE 8
+
#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
int gic_present;
#endif
@@ -71,64 +81,51 @@ 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_eiu_resource = {
- .name = "eiu",
- .start = LTQ_EIU_BASE_ADDR,
- .end = LTQ_EIU_BASE_ADDR + LTQ_ICU_SIZE - 1,
- .flags = IORESOURCE_MEM,
-};
-
+static int exin_avail;
static void __iomem *ltq_icu_membase;
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;
+ int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
- ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
- irq_nr %= INT_NUM_IM_OFFSET;
- ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
+ ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
+ offset %= INT_NUM_IM_OFFSET;
+ ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier);
}
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;
+ int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
- ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
- isr += LTQ_ICU_OFFSET * (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);
+ 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);
}
static void ltq_ack_irq(struct irq_data *d)
{
u32 isr = LTQ_ICU_IM0_ISR;
- int irq_nr = d->irq - INT_NUM_IRQ0;
+ int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
- isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
- irq_nr %= INT_NUM_IM_OFFSET;
- ltq_icu_w32((1 << irq_nr), isr);
+ isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
+ offset %= INT_NUM_IM_OFFSET;
+ ltq_icu_w32(BIT(offset), isr);
}
void ltq_enable_irq(struct irq_data *d)
{
u32 ier = LTQ_ICU_IM0_IER;
- int irq_nr = d->irq - INT_NUM_IRQ0;
+ int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
- ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
- irq_nr %= INT_NUM_IM_OFFSET;
- ltq_icu_w32(ltq_icu_r32(ier) | (1 << irq_nr), ier);
+ ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
+ offset %= INT_NUM_IM_OFFSET;
+ ltq_icu_w32(ltq_icu_r32(ier) | BIT(offset), ier);
}
static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
@@ -137,15 +134,15 @@ static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
ltq_enable_irq(d);
for (i = 0; i < MAX_EIU; i++) {
- if (d->irq == ltq_eiu_irq[i]) {
+ if (d->hwirq == ltq_eiu_irq[i]) {
/* low level - we should really handle set_type */
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) |
(0x6 << (i * 4)), LTQ_EIU_EXIN_C);
/* clear all pending */
- ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~(1 << i),
+ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~BIT(i),
LTQ_EIU_EXIN_INIC);
/* enable */
- ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | (1 << i),
+ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | BIT(i),
LTQ_EIU_EXIN_INEN);
break;
}
@@ -160,9 +157,9 @@ static void ltq_shutdown_eiu_irq(struct irq_data *d)
ltq_disable_irq(d);
for (i = 0; i < MAX_EIU; i++) {
- if (d->irq == ltq_eiu_irq[i]) {
+ if (d->hwirq == ltq_eiu_irq[i]) {
/* disable */
- ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~(1 << i),
+ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~BIT(i),
LTQ_EIU_EXIN_INEN);
break;
}
@@ -199,14 +196,15 @@ static void ltq_hw_irqdispatch(int module)
if (irq == 0)
return;
- /* silicon bug causes only the msb set to 1 to be valid. all
+ /*
+ * silicon bug causes only the msb set to 1 to be valid. all
* other bits might be bogus
*/
irq = __fls(irq);
- do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module));
+ do_IRQ((int)irq + MIPS_CPU_IRQ_CASCADE + (INT_NUM_IM_OFFSET * module));
/* 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);
}
@@ -290,38 +288,67 @@ out:
return;
}
+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;
+
+ for (i = 0; i < exin_avail; i++)
+ if (hw == ltq_eiu_irq[i])
+ chip = <q_eiu_type;
+
+ irq_set_chip_and_handler(hw, chip, handle_level_irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops irq_domain_ops = {
+ .xlate = irq_domain_xlate_onetwocell,
+ .map = icu_map,
+};
+
static struct irqaction cascade = {
.handler = no_action,
.name = "cascade",
};
-void __init arch_init_irq(void)
+int __init icu_of_init(struct device_node *node, struct device_node *parent)
{
+ struct device_node *eiu_node;
+ struct resource res;
int i;
- if (insert_resource(&iomem_resource, <q_icu_resource) < 0)
- panic("Failed to insert icu memory");
+ if (of_address_to_resource(node, 0, &res))
+ panic("Failed to get icu memory range");
- if (request_mem_region(ltq_icu_resource.start,
- resource_size(<q_icu_resource), "icu") < 0)
- panic("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(ltq_icu_resource.start,
- resource_size(<q_icu_resource));
+ ltq_icu_membase = ioremap_nocache(res.start, resource_size(&res));
if (!ltq_icu_membase)
panic("Failed to remap icu memory");
- if (insert_resource(&iomem_resource, <q_eiu_resource) < 0)
- panic("Failed to insert eiu memory");
-
- if (request_mem_region(ltq_eiu_resource.start,
- resource_size(<q_eiu_resource), "eiu") < 0)
- panic("Failed to request eiu memory");
-
- ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start,
- resource_size(<q_eiu_resource));
- if (!ltq_eiu_membase)
- panic("Failed to remap eiu memory");
+ /* 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)) {
+ /* find out how many external irq sources we have */
+ const __be32 *count = of_get_property(node,
+ "lantiq,count", NULL);
+
+ if (count)
+ exin_avail = *count;
+ if (exin_avail > MAX_EIU)
+ exin_avail = MAX_EIU;
+
+ if (request_mem_region(res.start, resource_size(&res),
+ res.name) < 0)
+ pr_err("Failed to request eiu memory");
+
+ ltq_eiu_membase = ioremap_nocache(res.start,
+ resource_size(&res));
+ if (!ltq_eiu_membase)
+ panic("Failed to remap eiu memory");
+ }
/* turn off all irqs by default */
for (i = 0; i < 5; i++) {
@@ -346,20 +373,8 @@ void __init arch_init_irq(void)
set_vi_handler(7, ltq_hw5_irqdispatch);
}
- 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))
- irq_set_chip_and_handler(i, <q_eiu_type,
- handle_level_irq);
- /* EIU3-5 only exist on ar9 and vr9 */
- else if (((i == LTQ_EIU_IR3) || (i == LTQ_EIU_IR4) ||
- (i == LTQ_EIU_IR5)) && (ltq_is_ar9() || ltq_is_vr9()))
- irq_set_chip_and_handler(i, <q_eiu_type,
- handle_level_irq);
- else
- irq_set_chip_and_handler(i, <q_irq_type,
- handle_level_irq);
+ irq_domain_add_linear(node, 6 * INT_NUM_IM_OFFSET,
+ &irq_domain_ops, 0);
#if defined(CONFIG_MIPS_MT_SMP)
if (cpu_has_vint) {
@@ -382,9 +397,20 @@ void __init arch_init_irq(void)
/* tell oprofile which irq to use */
cp0_perfcount_irq = LTQ_PERF_IRQ;
+ return 0;
}
unsigned int __cpuinit get_c0_compare_int(void)
{
return CP0_LEGACY_COMPARE_IRQ;
}
+
+static struct of_device_id __initdata of_irq_ids[] = {
+ { .compatible = "lantiq,icu", .data = icu_of_init },
+ {},
+};
+
+void __init arch_init_irq(void)
+{
+ of_irq_init(of_irq_ids);
+}
--
1.7.9.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2012-05-14 17:42 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1337017363-14424-1-git-send-email-blogic@openwrt.org>
[not found] ` <1337017363-14424-1-git-send-email-blogic-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
2012-05-14 17:42 ` [RESEND PATCH V2 02/17] OF: MIPS: lantiq: implement OF support John Crispin
2012-05-14 17:42 ` [RESEND PATCH V2 03/17] OF: MIPS: lantiq: implement irq_domain support John Crispin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).