aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-at91
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2013-11-15 14:10:41 -0500
committerOlof Johansson <olof@lixom.net>2013-11-15 14:10:41 -0500
commitca439c9b983ffa14e9eae6030e3ee80ad039388f (patch)
tree9ae38ed0b1e6559ffd79896d32248bda50f04839 /arch/arm/mach-at91
parentba52b7d4afaec172073a4169e1d6522552b2979c (diff)
parent94c4c79f2f1acca6e69a50bff5a7d9027509c16b (diff)
Merge tag 'at91-fixes-non-critical' of git://github.com/at91linux/linux-at91 into fixes
From Nicolas Ferre, fixes for early boot hangs on at91: Fixes for RTT & RTC interrupts that can fire early during boot process and kill the system. * tag 'at91-fixes-non-critical' of git://github.com/at91linux/linux-at91: ARM: at91: fix hanged boot due to early rtt-interrupt ARM: at91: fix hanged boot due to early rtc-interrupt
Diffstat (limited to 'arch/arm/mach-at91')
-rw-r--r--arch/arm/mach-at91/Makefile2
-rw-r--r--arch/arm/mach-at91/at91sam9260.c2
-rw-r--r--arch/arm/mach-at91/at91sam9261.c2
-rw-r--r--arch/arm/mach-at91/at91sam9263.c3
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c3
-rw-r--r--arch/arm/mach-at91/at91sam9n12.c6
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c3
-rw-r--r--arch/arm/mach-at91/at91sam9x5.c6
-rw-r--r--arch/arm/mach-at91/generic.h2
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9n12.h5
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9x5.h5
-rw-r--r--arch/arm/mach-at91/include/mach/sama5d3.h5
-rw-r--r--arch/arm/mach-at91/sama5d3.c6
-rw-r--r--arch/arm/mach-at91/sysirq_mask.c71
14 files changed, 120 insertions, 1 deletions
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 3b0a9538093c..e0fda04e6aa1 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4 4
5obj-y := irq.o gpio.o setup.o 5obj-y := irq.o gpio.o setup.o sysirq_mask.o
6obj-m := 6obj-m :=
7obj-n := 7obj-n :=
8obj- := 8obj- :=
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index 5de6074b4f4f..ae10d14de700 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -349,6 +349,8 @@ static void __init at91sam9260_initialize(void)
349 arm_pm_idle = at91sam9_idle; 349 arm_pm_idle = at91sam9_idle;
350 arm_pm_restart = at91sam9_alt_restart; 350 arm_pm_restart = at91sam9_alt_restart;
351 351
352 at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT);
353
352 /* Register GPIO subsystem */ 354 /* Register GPIO subsystem */
353 at91_gpio_init(at91sam9260_gpio, 3); 355 at91_gpio_init(at91sam9260_gpio, 3);
354} 356}
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 0e0793241ab7..e761e74ac64b 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -291,6 +291,8 @@ static void __init at91sam9261_initialize(void)
291 arm_pm_idle = at91sam9_idle; 291 arm_pm_idle = at91sam9_idle;
292 arm_pm_restart = at91sam9_alt_restart; 292 arm_pm_restart = at91sam9_alt_restart;
293 293
294 at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT);
295
294 /* Register GPIO subsystem */ 296 /* Register GPIO subsystem */
295 at91_gpio_init(at91sam9261_gpio, 3); 297 at91_gpio_init(at91sam9261_gpio, 3);
296} 298}
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 6ce7d1850893..e6fed6253a7f 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -328,6 +328,9 @@ static void __init at91sam9263_initialize(void)
328 arm_pm_idle = at91sam9_idle; 328 arm_pm_idle = at91sam9_idle;
329 arm_pm_restart = at91sam9_alt_restart; 329 arm_pm_restart = at91sam9_alt_restart;
330 330
331 at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0);
332 at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1);
333
331 /* Register GPIO subsystem */ 334 /* Register GPIO subsystem */
332 at91_gpio_init(at91sam9263_gpio, 5); 335 at91_gpio_init(at91sam9263_gpio, 5);
333} 336}
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 474ee04d24b9..9f7a97c84c12 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -377,6 +377,9 @@ static void __init at91sam9g45_initialize(void)
377 arm_pm_idle = at91sam9_idle; 377 arm_pm_idle = at91sam9_idle;
378 arm_pm_restart = at91sam9g45_restart; 378 arm_pm_restart = at91sam9g45_restart;
379 379
380 at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC);
381 at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT);
382
380 /* Register GPIO subsystem */ 383 /* Register GPIO subsystem */
381 at91_gpio_init(at91sam9g45_gpio, 5); 384 at91_gpio_init(at91sam9g45_gpio, 5);
382} 385}
diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c
index 2d895a297739..388ec3aec4b9 100644
--- a/arch/arm/mach-at91/at91sam9n12.c
+++ b/arch/arm/mach-at91/at91sam9n12.c
@@ -224,7 +224,13 @@ static void __init at91sam9n12_map_io(void)
224 at91_init_sram(0, AT91SAM9N12_SRAM_BASE, AT91SAM9N12_SRAM_SIZE); 224 at91_init_sram(0, AT91SAM9N12_SRAM_BASE, AT91SAM9N12_SRAM_SIZE);
225} 225}
226 226
227static void __init at91sam9n12_initialize(void)
228{
229 at91_sysirq_mask_rtc(AT91SAM9N12_BASE_RTC);
230}
231
227AT91_SOC_START(at91sam9n12) 232AT91_SOC_START(at91sam9n12)
228 .map_io = at91sam9n12_map_io, 233 .map_io = at91sam9n12_map_io,
229 .register_clocks = at91sam9n12_register_clocks, 234 .register_clocks = at91sam9n12_register_clocks,
235 .init = at91sam9n12_initialize,
230AT91_SOC_END 236AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index d4ec0d9a9872..301e1728d353 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -294,6 +294,9 @@ static void __init at91sam9rl_initialize(void)
294 arm_pm_idle = at91sam9_idle; 294 arm_pm_idle = at91sam9_idle;
295 arm_pm_restart = at91sam9_alt_restart; 295 arm_pm_restart = at91sam9_alt_restart;
296 296
297 at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC);
298 at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT);
299
297 /* Register GPIO subsystem */ 300 /* Register GPIO subsystem */
298 at91_gpio_init(at91sam9rl_gpio, 4); 301 at91_gpio_init(at91sam9rl_gpio, 4);
299} 302}
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
index 916e5a142917..e8a2e075a1b8 100644
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -322,6 +322,11 @@ static void __init at91sam9x5_map_io(void)
322 at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE); 322 at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE);
323} 323}
324 324
325static void __init at91sam9x5_initialize(void)
326{
327 at91_sysirq_mask_rtc(AT91SAM9X5_BASE_RTC);
328}
329
325/* -------------------------------------------------------------------- 330/* --------------------------------------------------------------------
326 * Interrupt initialization 331 * Interrupt initialization
327 * -------------------------------------------------------------------- */ 332 * -------------------------------------------------------------------- */
@@ -329,4 +334,5 @@ static void __init at91sam9x5_map_io(void)
329AT91_SOC_START(at91sam9x5) 334AT91_SOC_START(at91sam9x5)
330 .map_io = at91sam9x5_map_io, 335 .map_io = at91sam9x5_map_io,
331 .register_clocks = at91sam9x5_register_clocks, 336 .register_clocks = at91sam9x5_register_clocks,
337 .init = at91sam9x5_initialize,
332AT91_SOC_END 338AT91_SOC_END
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index dc6e2f5f804d..26dee3ce9397 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -34,6 +34,8 @@ extern int __init at91_aic_of_init(struct device_node *node,
34 struct device_node *parent); 34 struct device_node *parent);
35extern int __init at91_aic5_of_init(struct device_node *node, 35extern int __init at91_aic5_of_init(struct device_node *node,
36 struct device_node *parent); 36 struct device_node *parent);
37extern void __init at91_sysirq_mask_rtc(u32 rtc_base);
38extern void __init at91_sysirq_mask_rtt(u32 rtt_base);
37 39
38 40
39 /* Timer */ 41 /* Timer */
diff --git a/arch/arm/mach-at91/include/mach/at91sam9n12.h b/arch/arm/mach-at91/include/mach/at91sam9n12.h
index d374b87c0459..0151bcf6163c 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9n12.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9n12.h
@@ -49,6 +49,11 @@
49#define AT91SAM9N12_BASE_USART3 0xf8028000 49#define AT91SAM9N12_BASE_USART3 0xf8028000
50 50
51/* 51/*
52 * System Peripherals
53 */
54#define AT91SAM9N12_BASE_RTC 0xfffffeb0
55
56/*
52 * Internal Memory. 57 * Internal Memory.
53 */ 58 */
54#define AT91SAM9N12_SRAM_BASE 0x00300000 /* Internal SRAM base address */ 59#define AT91SAM9N12_SRAM_BASE 0x00300000 /* Internal SRAM base address */
diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5.h b/arch/arm/mach-at91/include/mach/at91sam9x5.h
index c75ee19b58d3..2fc76c49e97c 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9x5.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9x5.h
@@ -55,6 +55,11 @@
55#define AT91SAM9X5_BASE_USART2 0xf8024000 55#define AT91SAM9X5_BASE_USART2 0xf8024000
56 56
57/* 57/*
58 * System Peripherals
59 */
60#define AT91SAM9X5_BASE_RTC 0xfffffeb0
61
62/*
58 * Internal Memory. 63 * Internal Memory.
59 */ 64 */
60#define AT91SAM9X5_SRAM_BASE 0x00300000 /* Internal SRAM base address */ 65#define AT91SAM9X5_SRAM_BASE 0x00300000 /* Internal SRAM base address */
diff --git a/arch/arm/mach-at91/include/mach/sama5d3.h b/arch/arm/mach-at91/include/mach/sama5d3.h
index 31096a8aaf1d..25613d8c6dcd 100644
--- a/arch/arm/mach-at91/include/mach/sama5d3.h
+++ b/arch/arm/mach-at91/include/mach/sama5d3.h
@@ -73,6 +73,11 @@
73#define SAMA5D3_BASE_USART3 0xf8024000 73#define SAMA5D3_BASE_USART3 0xf8024000
74 74
75/* 75/*
76 * System Peripherals
77 */
78#define SAMA5D3_BASE_RTC 0xfffffeb0
79
80/*
76 * Internal Memory 81 * Internal Memory
77 */ 82 */
78#define SAMA5D3_SRAM_BASE 0x00300000 /* Internal SRAM base address */ 83#define SAMA5D3_SRAM_BASE 0x00300000 /* Internal SRAM base address */
diff --git a/arch/arm/mach-at91/sama5d3.c b/arch/arm/mach-at91/sama5d3.c
index 401279715ab1..3ea86428ee09 100644
--- a/arch/arm/mach-at91/sama5d3.c
+++ b/arch/arm/mach-at91/sama5d3.c
@@ -371,7 +371,13 @@ static void __init sama5d3_map_io(void)
371 at91_init_sram(0, SAMA5D3_SRAM_BASE, SAMA5D3_SRAM_SIZE); 371 at91_init_sram(0, SAMA5D3_SRAM_BASE, SAMA5D3_SRAM_SIZE);
372} 372}
373 373
374static void __init sama5d3_initialize(void)
375{
376 at91_sysirq_mask_rtc(SAMA5D3_BASE_RTC);
377}
378
374AT91_SOC_START(sama5d3) 379AT91_SOC_START(sama5d3)
375 .map_io = sama5d3_map_io, 380 .map_io = sama5d3_map_io,
376 .register_clocks = sama5d3_register_clocks, 381 .register_clocks = sama5d3_register_clocks,
382 .init = sama5d3_initialize,
377AT91_SOC_END 383AT91_SOC_END
diff --git a/arch/arm/mach-at91/sysirq_mask.c b/arch/arm/mach-at91/sysirq_mask.c
new file mode 100644
index 000000000000..2ba694f9626b
--- /dev/null
+++ b/arch/arm/mach-at91/sysirq_mask.c
@@ -0,0 +1,71 @@
1/*
2 * sysirq_mask.c - System-interrupt masking
3 *
4 * Copyright (C) 2013 Johan Hovold <jhovold@gmail.com>
5 *
6 * Functions to disable system interrupts from backup-powered peripherals.
7 *
8 * The RTC and RTT-peripherals are generally powered by backup power (VDDBU)
9 * and are not reset on wake-up, user, watchdog or software reset. This means
10 * that their interrupts may be enabled during early boot (e.g. after a user
11 * reset).
12 *
13 * As the RTC and RTT share the system-interrupt line with the PIT, an
14 * interrupt occurring before a handler has been installed would lead to the
15 * system interrupt being disabled and prevent the system from booting.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 */
22
23#include <linux/io.h>
24#include <mach/at91_rtt.h>
25
26#include "generic.h"
27
28#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
29#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
30
31void __init at91_sysirq_mask_rtc(u32 rtc_base)
32{
33 void __iomem *base;
34 u32 mask;
35
36 base = ioremap(rtc_base, 64);
37 if (!base)
38 return;
39
40 mask = readl_relaxed(base + AT91_RTC_IMR);
41 if (mask) {
42 pr_info("AT91: Disabling rtc irq\n");
43 writel_relaxed(mask, base + AT91_RTC_IDR);
44 (void)readl_relaxed(base + AT91_RTC_IMR); /* flush */
45 }
46
47 iounmap(base);
48}
49
50void __init at91_sysirq_mask_rtt(u32 rtt_base)
51{
52 void __iomem *base;
53 void __iomem *reg;
54 u32 mode;
55
56 base = ioremap(rtt_base, 16);
57 if (!base)
58 return;
59
60 reg = base + AT91_RTT_MR;
61
62 mode = readl_relaxed(reg);
63 if (mode & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)) {
64 pr_info("AT91: Disabling rtt irq\n");
65 mode &= ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN);
66 writel_relaxed(mode, reg);
67 (void)readl_relaxed(reg); /* flush */
68 }
69
70 iounmap(base);
71}