diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap4-common.c')
-rw-r--r-- | arch/arm/mach-omap2/omap4-common.c | 42 |
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 | ||
43 | static void __iomem *sar_ram_base; | 45 | static void __iomem *sar_ram_base; |
46 | static void __iomem *gic_dist_base_addr; | ||
47 | static 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) | |||
95 | void __init gic_init_irq(void) | 101 | void __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 | ||
121 | void gic_dist_disable(void) | ||
122 | { | ||
123 | if (gic_dist_base_addr) | ||
124 | __raw_writel(0x0, gic_dist_base_addr + GIC_DIST_CTRL); | ||
125 | } | ||
126 | |||
127 | bool gic_dist_disabled(void) | ||
128 | { | ||
129 | return !(__raw_readl(gic_dist_base_addr + GIC_DIST_CTRL) & 0x1); | ||
130 | } | ||
131 | |||
132 | void 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 | ||
115 | void __iomem *omap4_get_l2cache_base(void) | 155 | void __iomem *omap4_get_l2cache_base(void) |