summaryrefslogtreecommitdiffstats
path: root/target/linux/ramips/patches-4.3/0053-gic.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ramips/patches-4.3/0053-gic.patch')
-rw-r--r--target/linux/ramips/patches-4.3/0053-gic.patch305
1 files changed, 305 insertions, 0 deletions
diff --git a/target/linux/ramips/patches-4.3/0053-gic.patch b/target/linux/ramips/patches-4.3/0053-gic.patch
new file mode 100644
index 0000000000..c20cedf48e
--- /dev/null
+++ b/target/linux/ramips/patches-4.3/0053-gic.patch
@@ -0,0 +1,305 @@
+From 7b042645c1bd6407b1f7d9aa5785868e7e14b860 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 7 Dec 2015 18:40:16 +0100
+Subject: [PATCH 53/53] gic
+
+---
+ arch/mips/ralink/Kconfig | 1 +
+ arch/mips/ralink/Makefile | 2 +-
+ arch/mips/ralink/irq-gic.c | 212 ++------------------------------------------
+ 3 files changed, 11 insertions(+), 204 deletions(-)
+
+--- a/arch/mips/ralink/Kconfig
++++ b/arch/mips/ralink/Kconfig
+@@ -51,9 +51,9 @@
+ select SYS_SUPPORTS_MULTITHREADING
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_MIPS_CMP
++ select MIPS_GIC
+ select IRQ_GIC
+ select HW_HAS_PCI
+-
+ endchoice
+
+ choice
+--- a/arch/mips/ralink/Makefile
++++ b/arch/mips/ralink/Makefile
+@@ -13,7 +13,7 @@
+ obj-$(CONFIG_RALINK_ILL_ACC) += ill_acc.o
+
+ obj-$(CONFIG_IRQ_INTC) += irq.o
+-obj-$(CONFIG_IRQ_GIC) += irq-gic.o
++obj-$(CONFIG_MIPS_GIC_IPI) += irq-gic.o
+ obj-$(CONFIG_MIPS_MT_SMP) += malta-amon.o
+
+ obj-$(CONFIG_SOC_RT288X) += rt288x.o
+--- a/arch/mips/ralink/irq-gic.c
++++ b/arch/mips/ralink/irq-gic.c
+@@ -16,248 +16,22 @@
+ #include <asm/irq.h>
+ #include <asm/setup.h>
+
+-#include <asm/gic.h>
++#include <asm/mips-cm.h>
++#include <linux/irqchip/mips-gic.h>
+
+ #include <asm/mach-ralink/mt7621.h>
+-#define GIC_BASE_ADDR 0x1fbc0000
+
+-unsigned long _gcmp_base;
+-static int gic_resched_int_base = 56;
+-static int gic_call_int_base = 60;
+-static struct irq_chip *irq_gic;
+-static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS];
+-
+-#if defined(CONFIG_MIPS_MT_SMP)
+-static int gic_resched_int_base;
+-static int gic_call_int_base;
++extern int __init gic_of_init(struct device_node *node,
++ struct device_node *parent);
+
+-#define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu))
+-#define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu))
+-
+-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_DISABLED|IRQF_PERCPU,
+- .name = "ipi resched"
+-};
+-
+-static struct irqaction irq_call = {
+- .handler = ipi_call_interrupt,
+- .flags = IRQF_DISABLED|IRQF_PERCPU,
+- .name = "ipi call"
+-};
+-
+-#endif
+-
+-static void __init
+-gic_fill_map(void)
+-{
+- int i;
+-
+- for (i = 0; i < ARRAY_SIZE(gic_intr_map); i++) {
+- gic_intr_map[i].cpunum = 0;
+- gic_intr_map[i].pin = GIC_CPU_INT0;
+- gic_intr_map[i].polarity = GIC_POL_POS;
+- gic_intr_map[i].trigtype = GIC_TRIG_LEVEL;
+- gic_intr_map[i].flags = 0;
+- }
+-
+-#if defined(CONFIG_MIPS_MT_SMP)
+- {
+- int cpu;
+-
+- gic_call_int_base = ARRAY_SIZE(gic_intr_map) - nr_cpu_ids;
+- gic_resched_int_base = gic_call_int_base - nr_cpu_ids;
+-
+- i = gic_resched_int_base;
+-
+- for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
+- gic_intr_map[i + cpu].cpunum = cpu;
+- gic_intr_map[i + cpu].pin = GIC_CPU_INT1;
+- gic_intr_map[i + cpu].trigtype = GIC_TRIG_EDGE;
+-
+- gic_intr_map[i + cpu + nr_cpu_ids].cpunum = cpu;
+- gic_intr_map[i + cpu + nr_cpu_ids].pin = GIC_CPU_INT2;
+- gic_intr_map[i + cpu + nr_cpu_ids].trigtype = GIC_TRIG_EDGE;
+- }
+- }
+-#endif
+-}
+-
+-void
+-gic_irq_ack(struct irq_data *d)
+-{
+- int irq = (d->irq - gic_irq_base);
+-
+- GIC_CLR_INTR_MASK(irq);
+-
+- if (gic_irq_flags[irq] & GIC_TRIG_EDGE)
+- GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
+-}
+-
+-void
+-gic_finish_irq(struct irq_data *d)
+-{
+- GIC_SET_INTR_MASK(d->irq - gic_irq_base);
+-}
+-
+-void __init
+-gic_platform_init(int irqs, struct irq_chip *irq_controller)
+-{
+- irq_gic = irq_controller;
+-}
+-
+-static void
+-gic_irqdispatch(void)
+-{
+- unsigned int irq = gic_get_int();
+-
+- if (likely(irq < GIC_NUM_INTRS))
+- do_IRQ(MIPS_GIC_IRQ_BASE + irq);
+- else {
+- pr_debug("Spurious GIC Interrupt!\n");
+- spurious_interrupt();
+- }
+-
+-}
+-
+-static void
+-vi_timer_irqdispatch(void)
+-{
+- do_IRQ(cp0_compare_irq);
+-}
+-
+-#if defined(CONFIG_MIPS_MT_SMP)
+-unsigned int
+-plat_ipi_call_int_xlate(unsigned int cpu)
+-{
+- return GIC_CALL_INT(cpu);
+-}
+-
+-unsigned int
+-plat_ipi_resched_int_xlate(unsigned int cpu)
+-{
+- return GIC_RESCHED_INT(cpu);
+-}
+-#endif
+-
+-asmlinkage void
+-plat_irq_dispatch(void)
+-{
+- unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+-
+- if (unlikely(!pending)) {
+- pr_err("Spurious CP0 Interrupt!\n");
+- spurious_interrupt();
+- } else {
+- if (pending & CAUSEF_IP7)
+- do_IRQ(cp0_compare_irq);
+-
+- if (pending & (CAUSEF_IP4 | CAUSEF_IP3 | CAUSEF_IP2))
+- gic_irqdispatch();
+- }
+-}
+-
+-unsigned int __cpuinit
+-get_c0_compare_int(void)
+-{
+- return CP0_LEGACY_COMPARE_IRQ;
+-}
+-
+-static int
+-gic_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+-{
+- irq_set_chip_and_handler(irq, irq_gic,
+-#if defined(CONFIG_MIPS_MT_SMP)
+- (hw >= gic_resched_int_base) ?
+- handle_percpu_irq :
+-#endif
+- handle_level_irq);
+-
+- return 0;
+-}
+-
+-static const struct irq_domain_ops irq_domain_ops = {
+- .xlate = irq_domain_xlate_onecell,
+- .map = gic_map,
+-};
+-
+-static int __init
+-of_gic_init(struct device_node *node,
+- struct device_node *parent)
++unsigned int get_c0_compare_int(void)
+ {
+- struct irq_domain *domain;
+- struct resource gcmp = { 0 }, gic = { 0 };
+- unsigned int gic_rev;
+- int i;
+-
+- if (of_address_to_resource(node, 0, &gic))
+- panic("Failed to get gic memory range");
+- if (request_mem_region(gic.start, resource_size(&gic),
+- gic.name) < 0)
+- panic("Failed to request gic memory");
+- if (of_address_to_resource(node, 2, &gcmp))
+- panic("Failed to get gic memory range");
+- if (request_mem_region(gcmp.start, resource_size(&gcmp),
+- gcmp.name) < 0)
+- panic("Failed to request gcmp memory");
+-
+- _gcmp_base = (unsigned long) ioremap_nocache(gcmp.start, resource_size(&gcmp));
+- if (!_gcmp_base)
+- panic("Failed to remap gcmp memory\n");
+-
+- /* tell the gcmp where to find the gic */
+- write_gcr_gic_base(GIC_BASE_ADDR | CM_GCR_GIC_BASE_GICEN_MSK);
+- gic_present = 1;
+- if (cpu_has_vint) {
+- set_vi_handler(2, gic_irqdispatch);
+- set_vi_handler(3, gic_irqdispatch);
+- set_vi_handler(4, gic_irqdispatch);
+- set_vi_handler(7, vi_timer_irqdispatch);
+- }
+-
+- gic_fill_map();
+-
+- gic_init(gic.start, resource_size(&gic), gic_intr_map,
+- ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE);
+-
+- GICREAD(GIC_REG(SHARED, GIC_SH_REVISIONID), gic_rev);
+- pr_info("gic: revision %d.%d\n", (gic_rev >> 8) & 0xff, gic_rev & 0xff);
+-
+- domain = irq_domain_add_legacy(node, GIC_NUM_INTRS, MIPS_GIC_IRQ_BASE,
+- 0, &irq_domain_ops, NULL);
+- if (!domain)
+- panic("Failed to add irqdomain");
+-
+-#if defined(CONFIG_MIPS_MT_SMP)
+- for (i = 0; i < nr_cpu_ids; i++) {
+- setup_irq(MIPS_GIC_IRQ_BASE + GIC_RESCHED_INT(i), &irq_resched);
+- setup_irq(MIPS_GIC_IRQ_BASE + GIC_CALL_INT(i), &irq_call);
+- }
+-#endif
+-
+- change_c0_status(ST0_IM, STATUSF_IP7 | STATUSF_IP4 | STATUSF_IP3 |
+- STATUSF_IP2);
+- return 0;
++ return gic_get_c0_compare_int();
+ }
+
+ static struct of_device_id __initdata of_irq_ids[] = {
+- { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init },
+- { .compatible = "ralink,mt7621-gic", .data = of_gic_init },
++ { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init },
++ { .compatible = "mti,gic", .data = gic_of_init },
+ {},
+ };
+
+--- a/drivers/irqchip/irq-mips-gic.c
++++ b/drivers/irqchip/irq-mips-gic.c
+@@ -864,7 +864,7 @@
+ __gic_init(gic_base_addr, gic_addrspace_size, cpu_vec, irqbase, NULL);
+ }
+
+-static int __init gic_of_init(struct device_node *node,
++int __init gic_of_init(struct device_node *node,
+ struct device_node *parent)
+ {
+ struct resource res;