aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap4-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/omap4-common.c')
-rw-r--r--arch/arm/mach-omap2/omap4-common.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index e1f289748c5d..6f94b4e7b18d 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -14,6 +14,7 @@
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/irq.h>
17#include <linux/platform_device.h> 18#include <linux/platform_device.h>
18#include <linux/memblock.h> 19#include <linux/memblock.h>
19#include <linux/of_irq.h> 20#include <linux/of_irq.h>
@@ -24,6 +25,7 @@
24#include <asm/hardware/cache-l2x0.h> 25#include <asm/hardware/cache-l2x0.h>
25#include <asm/mach/map.h> 26#include <asm/mach/map.h>
26#include <asm/memblock.h> 27#include <asm/memblock.h>
28#include <asm/smp_twd.h>
27 29
28#include <plat/sram.h> 30#include <plat/sram.h>
29#include <plat/omap-secure.h> 31#include <plat/omap-secure.h>
@@ -41,6 +43,10 @@ static void __iomem *l2cache_base;
41#endif 43#endif
42 44
43static void __iomem *sar_ram_base; 45static void __iomem *sar_ram_base;
46static void __iomem *gic_dist_base_addr;
47static void __iomem *twd_base;
48
49#define IRQ_LOCALTIMER 29
44 50
45#ifdef CONFIG_OMAP4_ERRATA_I688 51#ifdef CONFIG_OMAP4_ERRATA_I688
46/* Used to implement memory barrier on DRAM path */ 52/* Used to implement memory barrier on DRAM path */
@@ -95,12 +101,14 @@ void __init omap_barriers_init(void)
95void __init gic_init_irq(void) 101void __init gic_init_irq(void)
96{ 102{
97 void __iomem *omap_irq_base; 103 void __iomem *omap_irq_base;
98 void __iomem *gic_dist_base_addr;
99 104
100 /* Static mapping, never released */ 105 /* Static mapping, never released */
101 gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K); 106 gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K);
102 BUG_ON(!gic_dist_base_addr); 107 BUG_ON(!gic_dist_base_addr);
103 108
109 twd_base = ioremap(OMAP44XX_LOCAL_TWD_BASE, SZ_4K);
110 BUG_ON(!twd_base);
111
104 /* Static mapping, never released */ 112 /* Static mapping, never released */
105 omap_irq_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512); 113 omap_irq_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512);
106 BUG_ON(!omap_irq_base); 114 BUG_ON(!omap_irq_base);
@@ -110,6 +118,38 @@ void __init gic_init_irq(void)
110 gic_init(0, 29, gic_dist_base_addr, omap_irq_base); 118 gic_init(0, 29, gic_dist_base_addr, omap_irq_base);
111} 119}
112 120
121void gic_dist_disable(void)
122{
123 if (gic_dist_base_addr)
124 __raw_writel(0x0, gic_dist_base_addr + GIC_DIST_CTRL);
125}
126
127bool gic_dist_disabled(void)
128{
129 return !(__raw_readl(gic_dist_base_addr + GIC_DIST_CTRL) & 0x1);
130}
131
132void gic_timer_retrigger(void)
133{
134 u32 twd_int = __raw_readl(twd_base + TWD_TIMER_INTSTAT);
135 u32 gic_int = __raw_readl(gic_dist_base_addr + GIC_DIST_PENDING_SET);
136 u32 twd_ctrl = __raw_readl(twd_base + TWD_TIMER_CONTROL);
137
138 if (twd_int && !(gic_int & BIT(IRQ_LOCALTIMER))) {
139 /*
140 * The local timer interrupt got lost while the distributor was
141 * disabled. Ack the pending interrupt, and retrigger it.
142 */
143 pr_warn("%s: lost localtimer interrupt\n", __func__);
144 __raw_writel(1, twd_base + TWD_TIMER_INTSTAT);
145 if (!(twd_ctrl & TWD_TIMER_CONTROL_PERIODIC)) {
146 __raw_writel(1, twd_base + TWD_TIMER_COUNTER);
147 twd_ctrl |= TWD_TIMER_CONTROL_ENABLE;
148 __raw_writel(twd_ctrl, twd_base + TWD_TIMER_CONTROL);
149 }
150 }
151}
152
113#ifdef CONFIG_CACHE_L2X0 153#ifdef CONFIG_CACHE_L2X0
114 154
115void __iomem *omap4_get_l2cache_base(void) 155void __iomem *omap4_get_l2cache_base(void)