From: jhovold@gmail.com (Johan Hovold)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 3/3] ARM: at91: fix hanged boot
Date: Fri, 8 Mar 2013 13:51:43 +0100 [thread overview]
Message-ID: <1362747103-21445-4-git-send-email-jhovold@gmail.com> (raw)
In-Reply-To: <1362747103-21445-1-git-send-email-jhovold@gmail.com>
Make sure the RTC and RTT-interrupts are masked at boot by adding a new
SOC-initialiser and helpers functions.
This fixes hanged boot on all AT91 SOCs but RM9200, for example, after a
reset during an RTC-update or if an RTC or RTT-alarm goes off after a
non-clean shutdown.
The RTC and RTT-peripherals are powered by backup power (VDDBU) (on all
AT91 SOCs but RM9200) and are not reset on wake-up, user, watchdog or
software reset. This means that their interrupts may be enabled during
early boot if, for example, they where not disabled during a previous
shutdown (e.g. due to a buggy driver or a non-clean shutdown such as a
user reset). Furthermore, an RTC or RTT-alarm may also be active.
The RTC and RTT-interrupts use the shared system-interrupt line, and if
an interrupt occurs before a handler (e.g. RTC-driver) has been
installed this leads to the system interrupt being disabled and prevents
the system from booting.
Note that when boot hangs due to an early RTC or RTT-interrupt, the only
way to get the system to start again is to remove the backup power (e.g.
battery) or to disable the interrupt manually from the bootloader. In
particular, a user reset is not sufficient.
Tested on at91sam9263 and at91sam9g45.
Signed-off-by: Johan Hovold <jhovold@gmail.com>
---
arch/arm/mach-at91/at91rm9200.c | 9 ++++++++
arch/arm/mach-at91/at91sam9260.c | 6 ++++++
arch/arm/mach-at91/at91sam9261.c | 6 ++++++
arch/arm/mach-at91/at91sam9263.c | 7 ++++++
arch/arm/mach-at91/at91sam9g45.c | 7 ++++++
arch/arm/mach-at91/at91sam9n12.c | 6 ++++++
arch/arm/mach-at91/at91sam9rl.c | 7 ++++++
arch/arm/mach-at91/at91sam9x5.c | 6 ++++++
arch/arm/mach-at91/generic.h | 2 ++
arch/arm/mach-at91/include/mach/at91sam9n12.h | 5 +++++
arch/arm/mach-at91/include/mach/at91sam9x5.h | 5 +++++
arch/arm/mach-at91/setup.c | 31 +++++++++++++++++++++++++++
arch/arm/mach-at91/soc.h | 1 +
13 files changed, 98 insertions(+)
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 7aeb473..4651ebb 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -325,6 +325,14 @@ static void __init at91rm9200_ioremap_registers(void)
at91_ioremap_ramc(0, AT91RM9200_BASE_MC, 256);
}
+static void __init at91rm9200_sysirq_mask(void)
+{
+ /*
+ * No need to mask any system interrupts as the RM9200 has no backup
+ * power and resets all system peripherals at every reset.
+ */
+}
+
static void __init at91rm9200_initialize(void)
{
arm_pm_idle = at91rm9200_idle;
@@ -387,5 +395,6 @@ AT91_SOC_START(rm9200)
.default_irq_priority = at91rm9200_default_irq_priority,
.ioremap_registers = at91rm9200_ioremap_registers,
.register_clocks = at91rm9200_register_clocks,
+ .sysirq_mask = at91rm9200_sysirq_mask,
.init = at91rm9200_initialize,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index b67cd53..c47a0db 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -342,6 +342,11 @@ static void __init at91sam9260_ioremap_registers(void)
at91_ioremap_matrix(AT91SAM9260_BASE_MATRIX);
}
+static void __init at91sam9260_sysirq_mask(void)
+{
+ at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT);
+}
+
static void __init at91sam9260_initialize(void)
{
arm_pm_idle = at91sam9_idle;
@@ -400,5 +405,6 @@ AT91_SOC_START(sam9260)
.default_irq_priority = at91sam9260_default_irq_priority,
.ioremap_registers = at91sam9260_ioremap_registers,
.register_clocks = at91sam9260_register_clocks,
+ .sysirq_mask = at91sam9260_sysirq_mask,
.init = at91sam9260_initialize,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 0204f4c..396e4cb 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -286,6 +286,11 @@ static void __init at91sam9261_ioremap_registers(void)
at91_ioremap_matrix(AT91SAM9261_BASE_MATRIX);
}
+static void __init at91sam9261_sysirq_mask(void)
+{
+ at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT);
+}
+
static void __init at91sam9261_initialize(void)
{
arm_pm_idle = at91sam9_idle;
@@ -344,5 +349,6 @@ AT91_SOC_START(sam9261)
.default_irq_priority = at91sam9261_default_irq_priority,
.ioremap_registers = at91sam9261_ioremap_registers,
.register_clocks = at91sam9261_register_clocks,
+ .sysirq_mask = at91sam9261_sysirq_mask,
.init = at91sam9261_initialize,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index c0cbb81..a0166a3 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -325,6 +325,12 @@ static void __init at91sam9263_ioremap_registers(void)
at91_ioremap_matrix(AT91SAM9263_BASE_MATRIX);
}
+static void __init at91sam9263_sysirq_mask(void)
+{
+ at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0);
+ at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1);
+}
+
static void __init at91sam9263_initialize(void)
{
arm_pm_idle = at91sam9_idle;
@@ -382,5 +388,6 @@ AT91_SOC_START(sam9263)
.default_irq_priority = at91sam9263_default_irq_priority,
.ioremap_registers = at91sam9263_ioremap_registers,
.register_clocks = at91sam9263_register_clocks,
+ .sysirq_mask = at91sam9263_sysirq_mask,
.init = at91sam9263_initialize,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index b4968aa..3d5498e 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -370,6 +370,12 @@ static void __init at91sam9g45_ioremap_registers(void)
at91_ioremap_matrix(AT91SAM9G45_BASE_MATRIX);
}
+static void __init at91sam9g45_sysirq_mask(void)
+{
+ at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC);
+ at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT);
+}
+
static void __init at91sam9g45_initialize(void)
{
arm_pm_idle = at91sam9_idle;
@@ -427,5 +433,6 @@ AT91_SOC_START(sam9g45)
.default_irq_priority = at91sam9g45_default_irq_priority,
.ioremap_registers = at91sam9g45_ioremap_registers,
.register_clocks = at91sam9g45_register_clocks,
+ .sysirq_mask = at91sam9g45_sysirq_mask,
.init = at91sam9g45_initialize,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c
index 5dfc8fd..e2ddb89 100644
--- a/arch/arm/mach-at91/at91sam9n12.c
+++ b/arch/arm/mach-at91/at91sam9n12.c
@@ -221,6 +221,11 @@ static void __init at91sam9n12_map_io(void)
at91_init_sram(0, AT91SAM9N12_SRAM_BASE, AT91SAM9N12_SRAM_SIZE);
}
+static void __init at91sam9n12_sysirq_mask(void)
+{
+ at91_sysirq_mask_rtc(AT91SAM9N12_BASE_RTC);
+}
+
void __init at91sam9n12_initialize(void)
{
at91_extern_irq = (1 << AT91SAM9N12_ID_IRQ0);
@@ -229,5 +234,6 @@ void __init at91sam9n12_initialize(void)
AT91_SOC_START(sam9n12)
.map_io = at91sam9n12_map_io,
.register_clocks = at91sam9n12_register_clocks,
+ .sysirq_mask = at91sam9n12_sysirq_mask,
.init = at91sam9n12_initialize,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 3de3e04..bde999f 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -289,6 +289,12 @@ static void __init at91sam9rl_ioremap_registers(void)
at91_ioremap_matrix(AT91SAM9RL_BASE_MATRIX);
}
+static void __init at91sam9rl_sysirq_mask(void)
+{
+ at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC);
+ at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT);
+}
+
static void __init at91sam9rl_initialize(void)
{
arm_pm_idle = at91sam9_idle;
@@ -346,5 +352,6 @@ AT91_SOC_START(sam9rl)
.default_irq_priority = at91sam9rl_default_irq_priority,
.ioremap_registers = at91sam9rl_ioremap_registers,
.register_clocks = at91sam9rl_register_clocks,
+ .sysirq_mask = at91sam9rl_sysirq_mask,
.init = at91sam9rl_initialize,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
index 44a9a62..20a214f 100644
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -316,6 +316,11 @@ static void __init at91sam9x5_map_io(void)
at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE);
}
+static void __init at91sam9x5_sysirq_mask(void)
+{
+ at91_sysirq_mask_rtc(AT91SAM9X5_BASE_RTC);
+}
+
/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */
@@ -323,4 +328,5 @@ static void __init at91sam9x5_map_io(void)
AT91_SOC_START(sam9x5)
.map_io = at91sam9x5_map_io,
.register_clocks = at91sam9x5_register_clocks,
+ .sysirq_mask = at91sam9x5_sysirq_mask,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index fc593d6..90a854d 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -33,6 +33,8 @@ extern int __init at91_aic_of_init(struct device_node *node,
struct device_node *parent);
extern int __init at91_aic5_of_init(struct device_node *node,
struct device_node *parent);
+extern void __init at91_sysirq_mask_rtc(u32 rtc_base);
+extern void __init at91_sysirq_mask_rtt(u32 rtt_base);
/* Timer */
diff --git a/arch/arm/mach-at91/include/mach/at91sam9n12.h b/arch/arm/mach-at91/include/mach/at91sam9n12.h
index d374b87..0151bcf 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9n12.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9n12.h
@@ -49,6 +49,11 @@
#define AT91SAM9N12_BASE_USART3 0xf8028000
/*
+ * System Peripherals
+ */
+#define AT91SAM9N12_BASE_RTC 0xfffffeb0
+
+/*
* Internal Memory.
*/
#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 c75ee19..2fc76c4 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9x5.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9x5.h
@@ -55,6 +55,11 @@
#define AT91SAM9X5_BASE_USART2 0xf8024000
/*
+ * System Peripherals
+ */
+#define AT91SAM9X5_BASE_RTC 0xfffffeb0
+
+/*
* Internal Memory.
*/
#define AT91SAM9X5_SRAM_BASE 0x00300000 /* Internal SRAM base address */
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index 4b67847..ac05453 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -19,6 +19,8 @@
#include <mach/cpu.h>
#include <mach/at91_dbgu.h>
#include <mach/at91_pmc.h>
+#include <mach/at91_rtc.h>
+#include <mach/at91_rtt.h>
#include "at91_shdwc.h"
#include "soc.h"
@@ -311,6 +313,31 @@ void __init at91_ioremap_matrix(u32 base_addr)
panic("Impossible to ioremap at91_matrix_base\n");
}
+void __init at91_sysirq_mask_rtc(u32 rtc_base)
+{
+ void *base = AT91_IO_P2V(rtc_base);
+ u32 mask;
+
+ mask = __raw_readl(base + AT91_RTC_IMR);
+ if (mask) {
+ pr_info("AT91: Disabling rtc irq\n");
+ __raw_writel(mask, base + AT91_RTC_IDR);
+ }
+}
+
+void __init at91_sysirq_mask_rtt(u32 rtt_base)
+{
+ void *base = AT91_IO_P2V(rtt_base);
+ u32 mr;
+
+ mr = __raw_readl(base + AT91_RTT_MR);
+ if (mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)) {
+ pr_info("AT91: Disabling rtt irq\n");
+ mr &= ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN);
+ __raw_writel(mr, base + AT91_RTT_MR);
+ }
+}
+
#if defined(CONFIG_OF)
static struct of_device_id rstc_ids[] = {
{ .compatible = "atmel,at91sam9260-rstc", .data = at91sam9_alt_restart },
@@ -467,6 +494,8 @@ void __init at91_dt_initialize(void)
if (at91_boot_soc.init)
at91_boot_soc.init();
+
+ at91_boot_soc.sysirq_mask();
}
#endif
@@ -482,5 +511,7 @@ void __init at91_initialize(unsigned long main_clock)
at91_boot_soc.init();
+ at91_boot_soc.sysirq_mask();
+
pinctrl_provide_dummies();
}
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
index 9c6d3d4..134f4c4 100644
--- a/arch/arm/mach-at91/soc.h
+++ b/arch/arm/mach-at91/soc.h
@@ -10,6 +10,7 @@ struct at91_init_soc {
void (*map_io)(void);
void (*ioremap_registers)(void);
void (*register_clocks)(void);
+ void (*sysirq_mask)(void);
void (*init)(void);
};
--
1.8.1.1
WARNING: multiple messages have this Message-ID (diff)
From: Johan Hovold <jhovold@gmail.com>
To: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>,
Andrew Victor <linux@maxim.org.za>,
Alessandro Zummo <a.zummo@towertech.it>,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, rtc-linux@googlegroups.com,
Johan Hovold <jhovold@gmail.com>
Subject: [PATCH 3/3] ARM: at91: fix hanged boot
Date: Fri, 8 Mar 2013 13:51:43 +0100 [thread overview]
Message-ID: <1362747103-21445-4-git-send-email-jhovold@gmail.com> (raw)
In-Reply-To: <1362747103-21445-1-git-send-email-jhovold@gmail.com>
Make sure the RTC and RTT-interrupts are masked at boot by adding a new
SOC-initialiser and helpers functions.
This fixes hanged boot on all AT91 SOCs but RM9200, for example, after a
reset during an RTC-update or if an RTC or RTT-alarm goes off after a
non-clean shutdown.
The RTC and RTT-peripherals are powered by backup power (VDDBU) (on all
AT91 SOCs but RM9200) and are not reset on wake-up, user, watchdog or
software reset. This means that their interrupts may be enabled during
early boot if, for example, they where not disabled during a previous
shutdown (e.g. due to a buggy driver or a non-clean shutdown such as a
user reset). Furthermore, an RTC or RTT-alarm may also be active.
The RTC and RTT-interrupts use the shared system-interrupt line, and if
an interrupt occurs before a handler (e.g. RTC-driver) has been
installed this leads to the system interrupt being disabled and prevents
the system from booting.
Note that when boot hangs due to an early RTC or RTT-interrupt, the only
way to get the system to start again is to remove the backup power (e.g.
battery) or to disable the interrupt manually from the bootloader. In
particular, a user reset is not sufficient.
Tested on at91sam9263 and at91sam9g45.
Signed-off-by: Johan Hovold <jhovold@gmail.com>
---
arch/arm/mach-at91/at91rm9200.c | 9 ++++++++
arch/arm/mach-at91/at91sam9260.c | 6 ++++++
arch/arm/mach-at91/at91sam9261.c | 6 ++++++
arch/arm/mach-at91/at91sam9263.c | 7 ++++++
arch/arm/mach-at91/at91sam9g45.c | 7 ++++++
arch/arm/mach-at91/at91sam9n12.c | 6 ++++++
arch/arm/mach-at91/at91sam9rl.c | 7 ++++++
arch/arm/mach-at91/at91sam9x5.c | 6 ++++++
arch/arm/mach-at91/generic.h | 2 ++
arch/arm/mach-at91/include/mach/at91sam9n12.h | 5 +++++
arch/arm/mach-at91/include/mach/at91sam9x5.h | 5 +++++
arch/arm/mach-at91/setup.c | 31 +++++++++++++++++++++++++++
arch/arm/mach-at91/soc.h | 1 +
13 files changed, 98 insertions(+)
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 7aeb473..4651ebb 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -325,6 +325,14 @@ static void __init at91rm9200_ioremap_registers(void)
at91_ioremap_ramc(0, AT91RM9200_BASE_MC, 256);
}
+static void __init at91rm9200_sysirq_mask(void)
+{
+ /*
+ * No need to mask any system interrupts as the RM9200 has no backup
+ * power and resets all system peripherals at every reset.
+ */
+}
+
static void __init at91rm9200_initialize(void)
{
arm_pm_idle = at91rm9200_idle;
@@ -387,5 +395,6 @@ AT91_SOC_START(rm9200)
.default_irq_priority = at91rm9200_default_irq_priority,
.ioremap_registers = at91rm9200_ioremap_registers,
.register_clocks = at91rm9200_register_clocks,
+ .sysirq_mask = at91rm9200_sysirq_mask,
.init = at91rm9200_initialize,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index b67cd53..c47a0db 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -342,6 +342,11 @@ static void __init at91sam9260_ioremap_registers(void)
at91_ioremap_matrix(AT91SAM9260_BASE_MATRIX);
}
+static void __init at91sam9260_sysirq_mask(void)
+{
+ at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT);
+}
+
static void __init at91sam9260_initialize(void)
{
arm_pm_idle = at91sam9_idle;
@@ -400,5 +405,6 @@ AT91_SOC_START(sam9260)
.default_irq_priority = at91sam9260_default_irq_priority,
.ioremap_registers = at91sam9260_ioremap_registers,
.register_clocks = at91sam9260_register_clocks,
+ .sysirq_mask = at91sam9260_sysirq_mask,
.init = at91sam9260_initialize,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 0204f4c..396e4cb 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -286,6 +286,11 @@ static void __init at91sam9261_ioremap_registers(void)
at91_ioremap_matrix(AT91SAM9261_BASE_MATRIX);
}
+static void __init at91sam9261_sysirq_mask(void)
+{
+ at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT);
+}
+
static void __init at91sam9261_initialize(void)
{
arm_pm_idle = at91sam9_idle;
@@ -344,5 +349,6 @@ AT91_SOC_START(sam9261)
.default_irq_priority = at91sam9261_default_irq_priority,
.ioremap_registers = at91sam9261_ioremap_registers,
.register_clocks = at91sam9261_register_clocks,
+ .sysirq_mask = at91sam9261_sysirq_mask,
.init = at91sam9261_initialize,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index c0cbb81..a0166a3 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -325,6 +325,12 @@ static void __init at91sam9263_ioremap_registers(void)
at91_ioremap_matrix(AT91SAM9263_BASE_MATRIX);
}
+static void __init at91sam9263_sysirq_mask(void)
+{
+ at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0);
+ at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1);
+}
+
static void __init at91sam9263_initialize(void)
{
arm_pm_idle = at91sam9_idle;
@@ -382,5 +388,6 @@ AT91_SOC_START(sam9263)
.default_irq_priority = at91sam9263_default_irq_priority,
.ioremap_registers = at91sam9263_ioremap_registers,
.register_clocks = at91sam9263_register_clocks,
+ .sysirq_mask = at91sam9263_sysirq_mask,
.init = at91sam9263_initialize,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index b4968aa..3d5498e 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -370,6 +370,12 @@ static void __init at91sam9g45_ioremap_registers(void)
at91_ioremap_matrix(AT91SAM9G45_BASE_MATRIX);
}
+static void __init at91sam9g45_sysirq_mask(void)
+{
+ at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC);
+ at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT);
+}
+
static void __init at91sam9g45_initialize(void)
{
arm_pm_idle = at91sam9_idle;
@@ -427,5 +433,6 @@ AT91_SOC_START(sam9g45)
.default_irq_priority = at91sam9g45_default_irq_priority,
.ioremap_registers = at91sam9g45_ioremap_registers,
.register_clocks = at91sam9g45_register_clocks,
+ .sysirq_mask = at91sam9g45_sysirq_mask,
.init = at91sam9g45_initialize,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c
index 5dfc8fd..e2ddb89 100644
--- a/arch/arm/mach-at91/at91sam9n12.c
+++ b/arch/arm/mach-at91/at91sam9n12.c
@@ -221,6 +221,11 @@ static void __init at91sam9n12_map_io(void)
at91_init_sram(0, AT91SAM9N12_SRAM_BASE, AT91SAM9N12_SRAM_SIZE);
}
+static void __init at91sam9n12_sysirq_mask(void)
+{
+ at91_sysirq_mask_rtc(AT91SAM9N12_BASE_RTC);
+}
+
void __init at91sam9n12_initialize(void)
{
at91_extern_irq = (1 << AT91SAM9N12_ID_IRQ0);
@@ -229,5 +234,6 @@ void __init at91sam9n12_initialize(void)
AT91_SOC_START(sam9n12)
.map_io = at91sam9n12_map_io,
.register_clocks = at91sam9n12_register_clocks,
+ .sysirq_mask = at91sam9n12_sysirq_mask,
.init = at91sam9n12_initialize,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 3de3e04..bde999f 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -289,6 +289,12 @@ static void __init at91sam9rl_ioremap_registers(void)
at91_ioremap_matrix(AT91SAM9RL_BASE_MATRIX);
}
+static void __init at91sam9rl_sysirq_mask(void)
+{
+ at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC);
+ at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT);
+}
+
static void __init at91sam9rl_initialize(void)
{
arm_pm_idle = at91sam9_idle;
@@ -346,5 +352,6 @@ AT91_SOC_START(sam9rl)
.default_irq_priority = at91sam9rl_default_irq_priority,
.ioremap_registers = at91sam9rl_ioremap_registers,
.register_clocks = at91sam9rl_register_clocks,
+ .sysirq_mask = at91sam9rl_sysirq_mask,
.init = at91sam9rl_initialize,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
index 44a9a62..20a214f 100644
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -316,6 +316,11 @@ static void __init at91sam9x5_map_io(void)
at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE);
}
+static void __init at91sam9x5_sysirq_mask(void)
+{
+ at91_sysirq_mask_rtc(AT91SAM9X5_BASE_RTC);
+}
+
/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */
@@ -323,4 +328,5 @@ static void __init at91sam9x5_map_io(void)
AT91_SOC_START(sam9x5)
.map_io = at91sam9x5_map_io,
.register_clocks = at91sam9x5_register_clocks,
+ .sysirq_mask = at91sam9x5_sysirq_mask,
AT91_SOC_END
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index fc593d6..90a854d 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -33,6 +33,8 @@ extern int __init at91_aic_of_init(struct device_node *node,
struct device_node *parent);
extern int __init at91_aic5_of_init(struct device_node *node,
struct device_node *parent);
+extern void __init at91_sysirq_mask_rtc(u32 rtc_base);
+extern void __init at91_sysirq_mask_rtt(u32 rtt_base);
/* Timer */
diff --git a/arch/arm/mach-at91/include/mach/at91sam9n12.h b/arch/arm/mach-at91/include/mach/at91sam9n12.h
index d374b87..0151bcf 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9n12.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9n12.h
@@ -49,6 +49,11 @@
#define AT91SAM9N12_BASE_USART3 0xf8028000
/*
+ * System Peripherals
+ */
+#define AT91SAM9N12_BASE_RTC 0xfffffeb0
+
+/*
* Internal Memory.
*/
#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 c75ee19..2fc76c4 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9x5.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9x5.h
@@ -55,6 +55,11 @@
#define AT91SAM9X5_BASE_USART2 0xf8024000
/*
+ * System Peripherals
+ */
+#define AT91SAM9X5_BASE_RTC 0xfffffeb0
+
+/*
* Internal Memory.
*/
#define AT91SAM9X5_SRAM_BASE 0x00300000 /* Internal SRAM base address */
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index 4b67847..ac05453 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -19,6 +19,8 @@
#include <mach/cpu.h>
#include <mach/at91_dbgu.h>
#include <mach/at91_pmc.h>
+#include <mach/at91_rtc.h>
+#include <mach/at91_rtt.h>
#include "at91_shdwc.h"
#include "soc.h"
@@ -311,6 +313,31 @@ void __init at91_ioremap_matrix(u32 base_addr)
panic("Impossible to ioremap at91_matrix_base\n");
}
+void __init at91_sysirq_mask_rtc(u32 rtc_base)
+{
+ void *base = AT91_IO_P2V(rtc_base);
+ u32 mask;
+
+ mask = __raw_readl(base + AT91_RTC_IMR);
+ if (mask) {
+ pr_info("AT91: Disabling rtc irq\n");
+ __raw_writel(mask, base + AT91_RTC_IDR);
+ }
+}
+
+void __init at91_sysirq_mask_rtt(u32 rtt_base)
+{
+ void *base = AT91_IO_P2V(rtt_base);
+ u32 mr;
+
+ mr = __raw_readl(base + AT91_RTT_MR);
+ if (mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)) {
+ pr_info("AT91: Disabling rtt irq\n");
+ mr &= ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN);
+ __raw_writel(mr, base + AT91_RTT_MR);
+ }
+}
+
#if defined(CONFIG_OF)
static struct of_device_id rstc_ids[] = {
{ .compatible = "atmel,at91sam9260-rstc", .data = at91sam9_alt_restart },
@@ -467,6 +494,8 @@ void __init at91_dt_initialize(void)
if (at91_boot_soc.init)
at91_boot_soc.init();
+
+ at91_boot_soc.sysirq_mask();
}
#endif
@@ -482,5 +511,7 @@ void __init at91_initialize(unsigned long main_clock)
at91_boot_soc.init();
+ at91_boot_soc.sysirq_mask();
+
pinctrl_provide_dummies();
}
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
index 9c6d3d4..134f4c4 100644
--- a/arch/arm/mach-at91/soc.h
+++ b/arch/arm/mach-at91/soc.h
@@ -10,6 +10,7 @@ struct at91_init_soc {
void (*map_io)(void);
void (*ioremap_registers)(void);
void (*register_clocks)(void);
+ void (*sysirq_mask)(void);
void (*init)(void);
};
--
1.8.1.1
next prev parent reply other threads:[~2013-03-08 12:51 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-08 12:51 [PATCH 0/3] ARM: at91: fix hanged boot Johan Hovold
2013-03-08 12:51 ` Johan Hovold
2013-03-08 12:51 ` [PATCH 1/3] ARM: at91/rtc: fix boot after RTC wake-up Johan Hovold
2013-03-08 12:51 ` Johan Hovold
2013-03-08 12:51 ` [PATCH 2/3] Revert "arm: at91: move at91rm9200 rtc header in drivers/rtc" Johan Hovold
2013-03-08 12:51 ` Johan Hovold
2013-03-08 12:51 ` Johan Hovold [this message]
2013-03-08 12:51 ` [PATCH 3/3] ARM: at91: fix hanged boot Johan Hovold
2013-03-08 16:02 ` [rtc-linux] " Jean-Christophe PLAGNIOL-VILLARD
2013-03-08 16:02 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-11 10:02 ` Johan Hovold
2013-03-11 10:02 ` Johan Hovold
2013-03-11 11:06 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-11 11:06 ` Jean-Christophe PLAGNIOL-VILLARD
2013-03-11 18:06 ` Johan Hovold
2013-03-11 18:06 ` Johan Hovold
2013-03-11 18:07 ` [PATCH v2 0/5] " Johan Hovold
2013-03-11 18:07 ` Johan Hovold
2013-03-11 18:07 ` [PATCH v2 1/5] ARM: at91/rtc: fix boot after RTC wake-up Johan Hovold
2013-03-11 18:07 ` Johan Hovold
2013-03-11 18:07 ` [PATCH v2 2/5] ARM: at91/dts: add RTC nodes Johan Hovold
2013-03-11 18:07 ` Johan Hovold
2013-03-11 18:07 ` [PATCH v2 3/5] ARM: at91/dts: add RTT nodes Johan Hovold
2013-03-11 18:07 ` Johan Hovold
2013-03-11 18:07 ` [PATCH v2 4/5] Revert "arm: at91: move at91rm9200 rtc header in drivers/rtc" Johan Hovold
2013-03-11 18:07 ` Johan Hovold
2013-03-11 18:07 ` [PATCH v2 5/5] ARM: at91: fix hanged boot Johan Hovold
2013-03-11 18:07 ` Johan Hovold
2013-04-11 15:55 ` [PATCH v2 0/5] " Johan Hovold
2013-04-11 15:55 ` Johan Hovold
2013-04-11 16:54 ` [rtc-linux] " Jean-Christophe PLAGNIOL-VILLARD
2013-04-11 16:54 ` Jean-Christophe PLAGNIOL-VILLARD
2013-04-12 9:33 ` Johan Hovold
2013-04-12 9:33 ` Johan Hovold
2013-04-12 12:09 ` Nicolas Ferre
2013-04-12 12:09 ` Nicolas Ferre
2013-10-16 9:56 ` [PATCH v3 0/3] " Johan Hovold
2013-10-16 9:56 ` Johan Hovold
2013-10-16 9:56 ` [PATCH v3 1/3] ARM: at91: fix hanged boot due to early rtc-interrupt Johan Hovold
2013-10-16 9:56 ` Johan Hovold
2013-11-15 11:09 ` Nicolas Ferre
2013-11-15 11:09 ` Nicolas Ferre
2013-10-16 9:56 ` [PATCH v3 2/3] ARM: at91: fix hanged boot due to early rtt-interrupt Johan Hovold
2013-10-16 9:56 ` Johan Hovold
2013-11-15 11:10 ` Nicolas Ferre
2013-11-15 11:10 ` Nicolas Ferre
2013-10-16 9:56 ` [PATCH v3 3/3] ARM: at91/rtc: disable interrupts at shutdown Johan Hovold
2013-10-16 9:56 ` Johan Hovold
2013-11-15 10:43 ` Nicolas Ferre
2013-11-15 10:43 ` Nicolas Ferre
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1362747103-21445-4-git-send-email-jhovold@gmail.com \
--to=jhovold@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.