ARM: tegra: move irq drivers to drivers/irqchip
Ajay Nandakumar [Mon, 28 Oct 2013 10:16:56 +0000 (15:16 +0530)]
Bug 1379891

Change-Id: I18a95deafbc112aa22da66d599e8ffb1c85fedab
Signed-off-by: Ajay Nandakumar <anandakumarm@nvidia.com>
Reviewed-on: http://git-master/r/302909
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Bharat Nihalani <bnihalani@nvidia.com>

21 files changed:
arch/arm/boot/dts/tegra114.dtsi
arch/arm/boot/dts/tegra124.dtsi
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/board-ardbeg.c
arch/arm/mach-tegra/board-bonaire.c
arch/arm/mach-tegra/board-dalmore.c
arch/arm/mach-tegra/board-dt-tegra148.c
arch/arm/mach-tegra/board-dt-tegra20.c
arch/arm/mach-tegra/board-dt-tegra30.c
arch/arm/mach-tegra/board-loki.c
arch/arm/mach-tegra/board-macallan.c
arch/arm/mach-tegra/board-pismo.c
arch/arm/mach-tegra/board-pluto.c
arch/arm/mach-tegra/board-roth.c
arch/arm/mach-tegra/board-vcm30_t124.c
arch/arm/mach-tegra/board.h
arch/arm/mach-tegra/fiq.c [deleted file]
arch/arm/mach-tegra/gic.c [deleted file]
drivers/irqchip/Makefile
drivers/irqchip/irq-tegra.c [moved from arch/arm/mach-tegra/irq.c with 57% similarity]
include/linux/irqchip/tegra.h

index cfabd43..3067aef 100644 (file)
                interrupts = <1 9 0xf04>;
        };
 
+       lic: interrupt-controller@60004000 {
+               compatible = "nvidia,tegra-gic";
+               interrupt-controller;
+               reg = <0x60004000 0x40>,
+                     <0x60004100 0x40>,
+                     <0x60004200 0x40>,
+                     <0x60004300 0x40>,
+                     <0x60004400 0x40>;
+        };
+
        timer@60005000 {
                compatible = "nvidia,tegra-nvtimer";
                reg = <0x60005000 0x400>;
index 7fec847..e9308f8 100644 (file)
                      <0x50042000 0x0100>;
        };
 
+       lic: interrupt-controller@60004000 {
+               compatible = "nvidia,tegra-gic";
+               interrupt-controller;
+               reg = <0x60004000 0x40>,
+                     <0x60004100 0x40>,
+                     <0x60004200 0x40>,
+                     <0x60004300 0x40>,
+                     <0x60004400 0x40>;
+        };
+
        timer {
                compatible = "arm,armv7-timer";
                interrupts = <1 13 0xf04
index 8b2b6e0..2948fe3 100644 (file)
@@ -9,7 +9,6 @@ obj-y                                   += common.o
 obj-y                                   += devices.o
 obj-y                                   += board-info.o
 obj-y                                   += io.o
-obj-y                                   += irq.o
 obj-y                                   += clock.o
 ifneq ($(CONFIG_CLK_SRC_TEGRA_TIMER),y)
 obj-y                                   += timer.o
@@ -74,7 +73,6 @@ obj-y                                   += delay.o
 obj-y                                   += pm.o
 obj-$(CONFIG_TEGRA_WDT_RECOVERY)        += wdt-recovery.o
 obj-$(CONFIG_PM_SLEEP)                  += pm-irq.o
-obj-y                                   += gic.o
 
 obj-y                                   += sleep.o
 obj-$(CONFIG_TEGRA_USE_NCT)             += nct.o nct_sysfs.o
@@ -98,7 +96,6 @@ obj-$(CONFIG_ARCH_TEGRA_12x_SOC)        += powergate-t12x.o
 
 obj-y                                   += apbio.o
 obj-y                                   += mc.o
-obj-$(CONFIG_FIQ)                       += fiq.o
 obj-$(CONFIG_TEGRA_FIQ_DEBUGGER)        += tegra_fiq_debugger.o
 obj-$(CONFIG_TEGRA_ARB_SEMAPHORE)       += arb_sema.o
 obj-$(CONFIG_PM_GENERIC_DOMAINS)        += pm_domains.o
index 7cffe0a..2bacbb9 100644 (file)
@@ -56,6 +56,8 @@
 #include <linux/clk/tegra.h>
 #include <media/tegra_dtv.h>
 #include <linux/clocksource.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/tegra.h>
 
 #include <mach/irqs.h>
 #include <mach/pci.h>
@@ -1281,7 +1283,7 @@ DT_MACHINE_START(LAGUNA, "laguna")
        .map_io         = tegra_map_common_io,
        .reserve        = tegra_ardbeg_reserve,
        .init_early     = tegra_ardbeg_init_early,
-       .init_irq       = tegra_dt_init_irq,
+       .init_irq       = irqchip_init,
        .init_time      = clocksource_of_init,
        .init_machine   = tegra_ardbeg_dt_init,
        .restart        = tegra_assert_system_reset,
@@ -1295,7 +1297,7 @@ DT_MACHINE_START(TN8, "tn8")
        .map_io         = tegra_map_common_io,
        .reserve        = tegra_ardbeg_reserve,
        .init_early     = tegra_ardbeg_init_early,
-       .init_irq       = tegra_dt_init_irq,
+       .init_irq       = irqchip_init,
        .init_time      = clocksource_of_init,
        .init_machine   = tegra_ardbeg_dt_init,
        .restart        = tegra_assert_system_reset,
@@ -1309,7 +1311,7 @@ DT_MACHINE_START(ARDBEG, "ardbeg")
        .map_io         = tegra_map_common_io,
        .reserve        = tegra_ardbeg_reserve,
        .init_early     = tegra_ardbeg_init_early,
-       .init_irq       = tegra_dt_init_irq,
+       .init_irq       = irqchip_init,
        .init_time      = clocksource_of_init,
        .init_machine   = tegra_ardbeg_dt_init,
        .restart        = tegra_assert_system_reset,
index 050e0e3..e60e638 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/tegra-soc.h>
 #include <linux/usb/tegra_usb_phy.h>
 #include <linux/clocksource.h>
+#include <linux/irqchip.h>
 
 #include <mach/gpio-tegra.h>
 
@@ -649,7 +650,7 @@ MACHINE_START(BONAIRE, "bonaire")
        .map_io         = tegra_map_common_io,
        .reserve        = tegra_bonaire_reserve,
        .init_early     = tegra12x_init_early,
-       .init_irq       = tegra_dt_init_irq,
+       .init_irq       = irqchip_init,
        .init_machine   = tegra_bonaire_dt_init,
        .init_time      = clocksource_of_init,
        .dt_compat      = bonaire_dt_board_compat,
index edb198d..aae3b04 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/usb/tegra_usb_phy.h>
 #include <linux/clk/tegra.h>
 #include <linux/clocksource.h>
+#include <linux/irqchip.h>
 #include <linux/irqchip/tegra.h>
 
 #include <mach/irqs.h>
@@ -837,7 +838,7 @@ MACHINE_START(DALMORE, "dalmore")
        .map_io         = tegra_map_common_io,
        .reserve        = tegra_dalmore_reserve,
        .init_early     = tegra11x_init_early,
-       .init_irq       = tegra_dt_init_irq,
+       .init_irq       = irqchip_init,
        .init_time      = clocksource_of_init,
        .init_machine   = tegra_dalmore_dt_init,
        .restart        = tegra_assert_system_reset,
index e85a0d0..81d3ed2 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/kernel.h>
 #include <linux/of.h>
+#include <linux/irqchip.h>
 
 #include <asm/mach/arch.h>
 
@@ -40,7 +41,7 @@ DT_MACHINE_START(TEGRA148_DT, "NVIDIA Tegra148 (Flattened Device Tree)")
        .smp            = smp_ops(tegra_smp_ops),
        .map_io         = tegra_map_common_io,
        .init_early     = tegra14x_init_early,
-       .init_irq       = tegra_dt_init_irq,
+       .init_irq       = irqchip_init,
        .init_time      = tegra_init_timer,
        .init_machine   = tegra148_dt_init,
        .restart        = tegra_assert_system_reset,
index db53153..8b50cac 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-tegra.h>
 #include <linux/clk/tegra.h>
+#include <linux/irqchip.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -144,7 +145,7 @@ DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)")
        .map_io         = tegra_map_common_io,
        .smp            = smp_ops(tegra_smp_ops),
        .init_early     = tegra20_init_early,
-       .init_irq       = tegra_dt_init_irq,
+       .init_irq       = irqchip_init,
        .init_time      = tegra_init_timer,
        .init_machine   = tegra_dt_init,
        .init_late      = tegra_dt_init_late,
index 9899b3c..2651007 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/of_fdt.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/irqchip.h>
 
 #include <asm/mach/arch.h>
 
@@ -81,7 +82,7 @@ DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)")
        .smp            = smp_ops(tegra_smp_ops),
        .map_io         = tegra_map_common_io,
        .init_early     = tegra30_init_early,
-       .init_irq       = tegra_dt_init_irq,
+       .init_irq       = irqchip_init,
        .init_time      = tegra_init_timer,
        .init_machine   = tegra30_dt_init,
        .init_late      = tegra_init_late,
index 26a47fd..47b0876 100644 (file)
@@ -54,6 +54,8 @@
 #include <linux/usb/tegra_usb_phy.h>
 #include <linux/clk/tegra.h>
 #include <linux/clocksource.h>
+#include <linux/platform_data/tegra_usb_modem_power.h>
+#include <linux/irqchip.h>
 
 #include <mach/irqs.h>
 #include <mach/pci.h>
@@ -875,7 +877,7 @@ DT_MACHINE_START(LOKI, "loki")
        .map_io         = tegra_map_common_io,
        .reserve        = tegra_loki_reserve,
        .init_early     = tegra_loki_init_early,
-       .init_irq       = tegra_dt_init_irq,
+       .init_irq       = irqchip_init,
        .init_time      = clocksource_of_init,
        .init_machine   = tegra_loki_dt_init,
        .restart        = tegra_assert_system_reset,
index b37b7bb..f46a41f 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/clk/tegra.h>
 #include <linux/tegra-soc.h>
 #include <linux/clocksource.h>
+#include <linux/irqchip.h>
 #include <linux/irqchip/tegra.h>
 
 #include <mach/irqs.h>
@@ -721,7 +722,7 @@ MACHINE_START(MACALLAN, "macallan")
        .map_io         = tegra_map_common_io,
        .reserve        = tegra_macallan_reserve,
        .init_early     = tegra11x_init_early,
-       .init_irq       = tegra_dt_init_irq,
+       .init_irq       = irqchip_init,
        .init_time      = clocksource_of_init,
        .init_machine   = tegra_macallan_dt_init,
        .restart        = tegra_assert_system_reset,
index f784399..7fe9ddf 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/usb/tegra_usb_phy.h>
 #include <linux/clk/tegra.h>
 #include <linux/clocksource.h>
+#include <linux/irqchip.h>
 #include <linux/irqchip/tegra.h>
 
 #include <mach/irqs.h>
@@ -765,7 +766,7 @@ MACHINE_START(PISMO, "pismo")
        .map_io         = tegra_map_common_io,
        .reserve        = tegra_pismo_reserve,
        .init_early     = tegra11x_init_early,
-       .init_irq       = tegra_dt_init_irq,
+       .init_irq       = irqchip_init,
        .init_time      = clocksource_of_init,
        .init_machine   = tegra_pismo_dt_init,
        .restart        = tegra_assert_system_reset,
index 7ec5ff9..abd2694 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/usb/tegra_usb_phy.h>
 #include <linux/clk/tegra.h>
 #include <linux/clocksource.h>
+#include <linux/irqchip.h>
 
 #include <mach/irqs.h>
 #include <mach/pinmux.h>
@@ -1406,7 +1407,7 @@ MACHINE_START(TEGRA_PLUTO, "tegra_pluto")
        .map_io         = tegra_map_common_io,
        .reserve        = tegra_pluto_reserve,
        .init_early     = tegra11x_init_early,
-       .init_irq       = tegra_dt_init_irq,
+       .init_irq       = irqchip_init,
        .init_time      = clocksource_of_init,
        .init_machine   = tegra_pluto_dt_init,
        .restart        = tegra_assert_system_reset,
index 46497f9..eff5a02 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/usb/tegra_usb_phy.h>
 #include <linux/clk/tegra.h>
 #include <linux/clocksource.h>
+#include <linux/irqchip.h>
 
 #include <asm/system_info.h>
 
@@ -744,7 +745,7 @@ MACHINE_START(ROTH, "roth")
        .map_io         = tegra_map_common_io,
        .reserve        = tegra_roth_reserve,
        .init_early     = tegra11x_init_early,
-       .init_irq       = tegra_dt_init_irq,
+       .init_irq       = irqchip_init,
        .init_time      = clocksource_of_init,
        .init_machine   = tegra_roth_dt_init,
        .restart        = tegra_assert_system_reset,
index cff6ef2..a4fdaa0 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/of_platform.h>
 #include <linux/kernel.h>
 #include <linux/clocksource.h>
+#include <linux/irqchip.h>
 
 #include <mach/tegra_asoc_pdata.h>
 #include <mach/pci.h>
@@ -579,7 +580,7 @@ DT_MACHINE_START(VCM30_T124, "vcm30_t124")
        .map_io         = tegra_map_common_io,
        .reserve        = tegra_vcm30_t124_reserve,
        .init_early     = tegra12x_init_early,
-       .init_irq       = tegra_dt_init_irq,
+       .init_irq       = irqchip_init,
         .init_time      = clocksource_of_init,
        .init_machine   = tegra_vcm30_t124_dt_init,
        .restart        = tegra_assert_system_reset,
index ad81934..ca5a80d 100644 (file)
@@ -96,7 +96,6 @@ void __init tegra11x_init_early(void);
 void __init tegra12x_init_early(void);
 void __init tegra14x_init_early(void);
 void __init tegra_map_common_io(void);
-void __init tegra_dt_init_irq(void);
 void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size,
        unsigned long fb2_size);
 int __init tegra_release_bootloader_fb(void);
diff --git a/arch/arm/mach-tegra/fiq.c b/arch/arm/mach-tegra/fiq.c
deleted file mode 100644 (file)
index 1ed4570..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2010 Google, Inc.
- * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
- *
- * Author:
- *     Brian Swetland <swetland@google.com>
- *     Iliyan Malchev <malchev@google.com>
- *     Lucas Dai <lucasd@nvidia.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/irqchip/arm-gic.h>
-
-#include "board.h"
-#include "iomap.h"
-
-#define ICTLR_CPU_IER          0x20
-#define ICTLR_CPU_IER_SET      0x24
-#define ICTLR_CPU_IER_CLR      0x28
-#define ICTLR_CPU_IEP_CLASS    0x2C
-
-#define FIRST_LEGACY_IRQ       32
-
-static void __iomem *ictlr_reg_base[] = {
-       IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
-       IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
-       IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE),
-       IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
-};
-
-static void tegra_legacy_select_fiq(unsigned int irq, bool fiq)
-{
-       void __iomem *base;
-       pr_debug("%s: %d\n", __func__, irq);
-
-       irq -= FIRST_LEGACY_IRQ;
-       base = ictlr_reg_base[irq>>5];
-       writel(fiq << (irq & 31), base + ICTLR_CPU_IEP_CLASS);
-}
-
-static void tegra_fiq_mask(struct irq_data *d)
-{
-       void __iomem *base;
-       int leg_irq;
-
-       if (d->irq < FIRST_LEGACY_IRQ)
-               return;
-
-       leg_irq = d->irq - FIRST_LEGACY_IRQ;
-       base = ictlr_reg_base[leg_irq >> 5];
-       writel(1 << (leg_irq & 31), base + ICTLR_CPU_IER_CLR);
-}
-
-static void tegra_fiq_unmask(struct irq_data *d)
-{
-       void __iomem *base;
-       int leg_irq;
-
-       if (d->irq < FIRST_LEGACY_IRQ)
-               return;
-
-       leg_irq = d->irq - FIRST_LEGACY_IRQ;
-       base = ictlr_reg_base[leg_irq >> 5];
-       writel(1 << (leg_irq & 31), base + ICTLR_CPU_IER_SET);
-}
-
-void tegra_fiq_enable(int irq)
-{
-#if defined(CONFIG_ARCH_TEGRA_3x_SOC) || \
-       defined(CONFIG_ARCH_TEGRA_2x_SOC)
-       void __iomem *base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100);
-#else
-       void __iomem *base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x2000);
-#endif
-       /* enable FIQ */
-       u32 val = readl(base + GIC_CPU_CTRL);
-       val &= ~8; /* pass FIQs through */
-       val |= 2; /* enableNS */
-       writel(val, base + GIC_CPU_CTRL);
-       tegra_legacy_select_fiq(irq, true);
-       tegra_fiq_unmask(irq_get_irq_data(irq));
-}
-
-void tegra_fiq_disable(int irq)
-{
-       tegra_fiq_mask(irq_get_irq_data(irq));
-       tegra_legacy_select_fiq(irq, false);
-}
diff --git a/arch/arm/mach-tegra/gic.c b/arch/arm/mach-tegra/gic.c
deleted file mode 100644 (file)
index 48e5240..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2010-2013, NVIDIA Corporation.  All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/cpumask.h>     /* Required by asm/hardware/gic.h */
-#include <linux/io.h>
-#include <linux/irqnr.h>
-#include <linux/cpu_pm.h>
-#include <linux/irqchip/arm-gic.h>
-#include <linux/irqchip/tegra.h>
-
-#include <mach/irqs.h>
-
-#include "iomap.h"
-#include "pm.h"
-
-#define ARM_VERSION_CORTEX_A15 0xC0F
-
-void __iomem *tegra_gic_cpu_base;
-static u32 gic_version;
-
-#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
-
-void tegra_gic_cpu_disable(bool disable_pass_through)
-{
-       u32 gic_cpu_ctrl = 0;
-
-#ifndef CONFIG_ARCH_TEGRA_2x_SOC
-       if (disable_pass_through) {
-               if (gic_version == GIC_V2)
-                       gic_cpu_ctrl = 0x1E0;
-               else
-                       gic_cpu_ctrl = 2;
-       }
-#endif
-       writel(gic_cpu_ctrl, tegra_gic_cpu_base + GIC_CPU_CTRL);
-}
-
-#endif
-
-#if defined(CONFIG_PM_SLEEP)
-
-int tegra_gic_pending_interrupt(void)
-{
-       u32 irq = readl(tegra_gic_cpu_base + GIC_CPU_HIGHPRI);
-       irq &= 0x3FF;
-
-       return irq;
-}
-
-#ifndef CONFIG_ARCH_TEGRA_2x_SOC
-
-static void __iomem *gic_dist_base = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
-static u32 gic_affinity[INT_GIC_NR/4];
-
-void tegra_gic_dist_disable(void)
-{
-       writel(0, gic_dist_base + GIC_DIST_CTRL);
-}
-
-void tegra_gic_dist_enable(void)
-{
-       writel(1, gic_dist_base + GIC_DIST_CTRL);
-}
-
-void tegra_gic_disable_affinity(void)
-{
-       unsigned int i;
-
-       BUG_ON(is_lp_cluster());
-
-       /* The GIC distributor TARGET register is one byte per IRQ. */
-       for (i = 32; i < INT_GIC_NR; i += 4) {
-               /* Save the affinity. */
-               gic_affinity[i/4] = __raw_readl(gic_dist_base +
-                                               GIC_DIST_TARGET + i);
-
-               /* Force this interrupt to CPU0. */
-               __raw_writel(0x01010101, gic_dist_base + GIC_DIST_TARGET + i);
-       }
-
-       wmb();
-}
-
-void tegra_gic_restore_affinity(void)
-{
-       unsigned int i;
-
-       BUG_ON(is_lp_cluster());
-
-       /* The GIC distributor TARGET register is one byte per IRQ. */
-       for (i = 32; i < INT_GIC_NR; i += 4) {
-#ifdef CONFIG_BUG
-               u32 reg = __raw_readl(gic_dist_base + GIC_DIST_TARGET + i);
-               if (reg & 0xFEFEFEFE)
-                       panic("GIC affinity changed!");
-#endif
-               /* Restore this interrupt's affinity. */
-               __raw_writel(gic_affinity[i/4], gic_dist_base +
-                            GIC_DIST_TARGET + i);
-       }
-
-       wmb();
-}
-
-void tegra_gic_affinity_to_cpu0(void)
-{
-       unsigned int i;
-
-       BUG_ON(is_lp_cluster());
-
-       for (i = 32; i < INT_GIC_NR; i += 4)
-               __raw_writel(0x01010101, gic_dist_base + GIC_DIST_TARGET + i);
-       wmb();
-}
-#endif
-
-static int tegra_gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
-{
-       switch (cmd) {
-       case CPU_PM_ENTER:
-               writel(0x1E0, tegra_gic_cpu_base + GIC_CPU_CTRL);
-               break;
-       }
-
-       return NOTIFY_OK;
-}
-
-static struct notifier_block tegra_gic_notifier_block = {
-       .notifier_call = tegra_gic_notifier,
-};
-#endif
-
-void __init tegra_gic_init(bool is_dt)
-{
-       u32 midr;
-
-       __asm__("mrc p15, 0, %0, c0, c0, 0\n" : "=r" (midr));
-
-       midr = (midr & 0x0000FFF0) >> 4;
-
-       if (midr == ARM_VERSION_CORTEX_A15)
-               tegra_gic_cpu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x2000);
-       else
-               tegra_gic_cpu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100);
-
-       if (!is_dt)
-               gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
-                       tegra_gic_cpu_base);
-
-       gic_version = readl(IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE)+0xFE8);
-       gic_version = (gic_version & 0xF0) >> 4;
-
-#ifdef CONFIG_PM_SLEEP
-       if (gic_version == GIC_V2)
-               cpu_pm_register_notifier(&tegra_gic_notifier_block);
-#endif
-}
index cda4cb5..0eecc1f 100644 (file)
@@ -16,3 +16,4 @@ obj-$(CONFIG_RENESAS_INTC_IRQPIN)     += irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC)             += irq-renesas-irqc.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)       += irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_VT8500)              += irq-vt8500.o
+obj-$(CONFIG_ARCH_TEGRA)               += irq-tegra.o
similarity index 57%
rename from arch/arm/mach-tegra/irq.c
rename to drivers/irqchip/irq-tegra.c
index 9569352..e99dfe2 100644 (file)
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqnr.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/irqchip/arm-gic.h>
-#include <linux/irqchip.h>
 #include <linux/syscore_ops.h>
 #include <linux/clk/tegra.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/arm-gic.h>
 #include <linux/irqchip/tegra.h>
+#include <linux/cpumask.h>     /* Required by asm/hardware/gic.h */
+#include <linux/cpu_pm.h>
 
-#include "board.h"
-#include "iomap.h"
+/* HACK: will be removed once cpuidle is moved to drivers */
+#include "../../arch/arm/mach-tegra/pm.h"
+
+#include "irqchip.h"
 
 #define ICTLR_CPU_IEP_VFIQ     0x08
 #define ICTLR_CPU_IEP_FIR      0x14
 #endif
 
 #define FIRST_LEGACY_IRQ 32
+#define ARM_VERSION_CORTEX_A15 0xC0F
+
+
+static u32 gic_version;
+
+static void __iomem *gic_dist_base;
+static void __iomem *gic_cpu_base;
+static u32 gic_affinity[INT_GIC_NR/4];
 
 static int num_ictlrs;
 
-static void __iomem *ictlr_reg_base[] = {
-       IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
-       IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
-       IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE),
-       IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
-#if (NUM_ICTLRS > 4)
-       IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE),
-#endif
-};
+static void __iomem **ictlr_reg_base;
 
 #ifdef CONFIG_PM_SLEEP
 static u32 cop_ier[NUM_ICTLRS];
@@ -77,6 +83,167 @@ static u32 cpu_iep[NUM_ICTLRS];
 static u32 ictlr_wake_mask[NUM_ICTLRS];
 #endif
 
+#ifdef CONFIG_FIQ
+static void tegra_legacy_select_fiq(unsigned int irq, bool fiq)
+{
+       void __iomem *base;
+       pr_debug("%s: %d\n", __func__, irq);
+
+       irq -= FIRST_LEGACY_IRQ;
+       base = ictlr_reg_base[irq>>5];
+       writel(fiq << (irq & 31), base + ICTLR_CPU_IEP_CLASS);
+}
+
+static void tegra_fiq_mask(struct irq_data *d)
+{
+       void __iomem *base;
+       int leg_irq;
+
+       if (d->irq < FIRST_LEGACY_IRQ)
+               return;
+
+       leg_irq = d->irq - FIRST_LEGACY_IRQ;
+       base = ictlr_reg_base[leg_irq >> 5];
+       writel(1 << (leg_irq & 31), base + ICTLR_CPU_IER_CLR);
+}
+
+static void tegra_fiq_unmask(struct irq_data *d)
+{
+       void __iomem *base;
+       int leg_irq;
+
+       if (d->irq < FIRST_LEGACY_IRQ)
+               return;
+
+       leg_irq = d->irq - FIRST_LEGACY_IRQ;
+       base = ictlr_reg_base[leg_irq >> 5];
+       writel(1 << (leg_irq & 31), base + ICTLR_CPU_IER_SET);
+}
+
+void tegra_fiq_enable(int irq)
+{
+       /* enable FIQ */
+       u32 val = readl(gic_cpu_base + GIC_CPU_CTRL);
+       val &= ~8; /* pass FIQs through */
+       val |= 2; /* enableNS */
+       writel(val, gic_cpu_base + GIC_CPU_CTRL);
+       tegra_legacy_select_fiq(irq, true);
+       tegra_fiq_unmask(irq_get_irq_data(irq));
+}
+
+void tegra_fiq_disable(int irq)
+{
+       tegra_fiq_mask(irq_get_irq_data(irq));
+       tegra_legacy_select_fiq(irq, false);
+}
+#endif /* CONFIG_FIQ */
+
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
+void tegra_gic_cpu_disable(bool disable_pass_through)
+{
+       u32 gic_cpu_ctrl = 0;
+
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+       if (disable_pass_through) {
+               if (gic_version == GIC_V2)
+                       gic_cpu_ctrl = 0x1E0;
+               else
+                       gic_cpu_ctrl = 2;
+       }
+#endif
+       writel(gic_cpu_ctrl, gic_cpu_base + GIC_CPU_CTRL);
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+int tegra_gic_pending_interrupt(void)
+{
+       u32 irq = readl(gic_cpu_base + GIC_CPU_HIGHPRI);
+       irq &= 0x3FF;
+
+       return irq;
+}
+
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+void tegra_gic_dist_disable(void)
+{
+       writel(0, gic_dist_base + GIC_DIST_CTRL);
+}
+
+void tegra_gic_dist_enable(void)
+{
+       writel(1, gic_dist_base + GIC_DIST_CTRL);
+}
+
+void tegra_gic_disable_affinity(void)
+{
+       unsigned int i;
+
+       BUG_ON(is_lp_cluster());
+
+       /* The GIC distributor TARGET register is one byte per IRQ. */
+       for (i = 32; i < INT_GIC_NR; i += 4) {
+               /* Save the affinity. */
+               gic_affinity[i/4] = __raw_readl(gic_dist_base +
+                                               GIC_DIST_TARGET + i);
+
+               /* Force this interrupt to CPU0. */
+               __raw_writel(0x01010101, gic_dist_base + GIC_DIST_TARGET + i);
+       }
+
+       wmb();
+}
+
+void tegra_gic_restore_affinity(void)
+{
+       unsigned int i;
+
+       BUG_ON(is_lp_cluster());
+
+       /* The GIC distributor TARGET register is one byte per IRQ. */
+       for (i = 32; i < INT_GIC_NR; i += 4) {
+#ifdef CONFIG_BUG
+               u32 reg = __raw_readl(gic_dist_base + GIC_DIST_TARGET + i);
+               if (reg & 0xFEFEFEFE)
+                       panic("GIC affinity changed!");
+#endif
+               /* Restore this interrupt's affinity. */
+               __raw_writel(gic_affinity[i/4], gic_dist_base +
+                            GIC_DIST_TARGET + i);
+       }
+
+       wmb();
+}
+
+void tegra_gic_affinity_to_cpu0(void)
+{
+       unsigned int i;
+
+       BUG_ON(is_lp_cluster());
+
+       for (i = 32; i < INT_GIC_NR; i += 4)
+               __raw_writel(0x01010101, gic_dist_base + GIC_DIST_TARGET + i);
+       wmb();
+}
+#endif /* CONFIG_ARCH_TEGRA_2x_SOC */
+
+static int tegra_gic_notifier(struct notifier_block *self,
+                                       unsigned long cmd, void *v)
+{
+       switch (cmd) {
+       case CPU_PM_ENTER:
+               writel(0x1E0, gic_cpu_base + GIC_CPU_CTRL);
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block tegra_gic_notifier_block = {
+       .notifier_call = tegra_gic_notifier,
+};
+#endif /* CONFIG_PM_SLEEP */
+
 int tegra_update_lp1_irq_wake(unsigned int irq, bool enable)
 {
 #ifdef CONFIG_PM_SLEEP
@@ -265,39 +432,52 @@ static struct syscore_ops tegra_legacy_irq_syscore_ops = {
        .restore = tegra_legacy_irq_resume,
 };
 
-static int tegra_legacy_irq_syscore_init(void)
+static int __init tegra_legacy_irq_syscore_init(void)
 {
        register_syscore_ops(&tegra_legacy_irq_syscore_ops);
 
        return 0;
 }
-subsys_initcall(tegra_legacy_irq_syscore_init);
 #else
 #define tegra_set_wake NULL
 #endif
 
-void __init tegra_dt_init_irq(void)
+void tegra_init_legacy_irq_cop(void)
 {
        int i;
-       void __iomem *distbase;
-       bool is_dt = false;
 
-       tegra_clocks_init();
+       for (i = 0; i < NUM_ICTLRS; i++) {
+               void __iomem *ictlr = ictlr_reg_base[i];
+               writel(~0, ictlr + ICTLR_COP_IER_CLR);
+               writel(0, ictlr + ICTLR_COP_IEP_CLASS);
+       }
+}
+
+static int __init tegra_gic_of_init(struct device_node *node,
+                                       struct device_node *parent)
+{
+       int i;
+       struct device_node *arm_gic_np =
+               of_find_compatible_node(NULL, NULL, "arm,cortex-a15-gic");
+       gic_dist_base = of_iomap(arm_gic_np, 0);
+       gic_cpu_base = of_iomap(arm_gic_np, 1);
+       num_ictlrs = readl_relaxed(gic_dist_base + GIC_DIST_CTR) & 0x1f;
+       gic_version = (readl(gic_dist_base + 0xFE8) & 0xF0) >> 4;
 
-       distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
-       num_ictlrs = readl_relaxed(distbase + GIC_DIST_CTR) & 0x1f;
+       pr_info("the number of interrupt controllers found is %d", num_ictlrs);
+       ictlr_reg_base = kzalloc(sizeof(void *) * num_ictlrs, GFP_KERNEL);
 
-       if (num_ictlrs > ARRAY_SIZE(ictlr_reg_base)) {
-               WARN(1, "Too many (%d) interrupt controllers found. Maximum is %d.",
-                       num_ictlrs, ARRAY_SIZE(ictlr_reg_base));
-               num_ictlrs = ARRAY_SIZE(ictlr_reg_base);
-       }
+       tegra_clocks_init();
 
        for (i = 0; i < num_ictlrs; i++) {
-               void __iomem *ictlr = ictlr_reg_base[i];
-               writel(~0, ictlr + ICTLR_CPU_IER_CLR);
-               writel(0, ictlr + ICTLR_CPU_IEP_CLASS);
-               writel(~0, ictlr + ICTLR_CPU_IEP_FIR_CLR);
+               ictlr_reg_base[i] = of_iomap(node, i);
+               if (!ictlr_reg_base[i]) {
+                       pr_info("failed to get the right register\n");
+                       return -EINVAL;
+               }
+               writel(~0, ictlr_reg_base[i] + ICTLR_CPU_IER_CLR);
+               writel(0, ictlr_reg_base[i] + ICTLR_CPU_IEP_CLASS);
+               writel(~0, ictlr_reg_base[i] + ICTLR_CPU_IEP_FIR_CLR);
        }
 
        gic_arch_extn.irq_ack = tegra_ack;
@@ -309,25 +489,12 @@ void __init tegra_dt_init_irq(void)
        gic_arch_extn.irq_set_wake = tegra_set_wake;
        gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND;
 
-       /* check if DT is passed */
-       is_dt = of_have_populated_dt();
-
-       tegra_gic_init(is_dt);
-
-#ifdef CONFIG_OF
-       /* If DT is passed, init the irq via DT */
-       if (is_dt)
-               irqchip_init();
+#ifdef CONFIG_PM_SLEEP
+       tegra_legacy_irq_syscore_init();
+       if (gic_version == GIC_V2)
+               cpu_pm_register_notifier(&tegra_gic_notifier_block);
 #endif
-}
-
-void tegra_init_legacy_irq_cop(void)
-{
-       int i;
 
-       for (i = 0; i < NUM_ICTLRS; i++) {
-               void __iomem *ictlr = ictlr_reg_base[i];
-               writel(~0, ictlr + ICTLR_COP_IER_CLR);
-               writel(0, ictlr + ICTLR_COP_IEP_CLASS);
-       }
+       return 0;
 }
+IRQCHIP_DECLARE(tegra_gic, "nvidia,tegra-gic", tegra_gic_of_init);
index c51b124..cb968dd 100644 (file)
@@ -45,7 +45,6 @@ void tegra_gic_affinity_to_cpu0(void);
 #endif
 
 u32 tegra_gic_version(void);
-void __init tegra_gic_init(bool is_dt);
 
 #if defined(CONFIG_PM_SLEEP)
 u64 tegra_read_pmc_wake_status(void);