From: jhovold@gmail.com (Johan Hovold)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 4/5] rtc-at91rm9200: add shadow interrupt mask
Date: Thu, 23 May 2013 10:38:54 +0200 [thread overview]
Message-ID: <1369298335-24597-5-git-send-email-jhovold@gmail.com> (raw)
In-Reply-To: <1369298335-24597-1-git-send-email-jhovold@gmail.com>
Add shadow interrupt-mask register which can be used on SoCs where the
actual hardware register is broken.
Note that some care needs to be taken to make sure the shadow mask
corresponds to the actual hardware state. The added overhead is not an
issue for the non-broken SoCs due to the relatively infrequent
interrupt-mask updates. We do, however, only use the shadow mask value
as a fall-back when it actually needed as there is still a theoretical
possibility that the mask is incorrect (see the code for details).
Signed-off-by: Johan Hovold <jhovold@gmail.com>
---
drivers/rtc/rtc-at91rm9200.c | 39 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 9592d08..205701e 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -30,6 +30,7 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/spinlock.h>
#include <asm/uaccess.h>
@@ -43,6 +44,7 @@
#define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */
struct at91_rtc_config {
+ bool use_shadow_imr;
};
static const struct at91_rtc_config *at91_rtc_config;
@@ -50,20 +52,55 @@ static DECLARE_COMPLETION(at91_rtc_updated);
static unsigned int at91_alarm_year = AT91_RTC_EPOCH;
static void __iomem *at91_rtc_regs;
static int irq;
+static DEFINE_SPINLOCK(at91_rtc_lock);
+static u32 at91_rtc_shadow_imr;
static void at91_rtc_write_ier(u32 mask)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&at91_rtc_lock, flags);
+ at91_rtc_shadow_imr |= mask;
at91_rtc_write(AT91_RTC_IER, mask);
+ spin_unlock_irqrestore(&at91_rtc_lock, flags);
}
static void at91_rtc_write_idr(u32 mask)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&at91_rtc_lock, flags);
at91_rtc_write(AT91_RTC_IDR, mask);
+ /*
+ * Register read back (of any RTC-register) needed to make sure
+ * IDR-register write has reached the peripheral before updating
+ * shadow mask.
+ *
+ * Note that there is still a possibility that the mask is updated
+ * before interrupts have actually been disabled in hardware. The only
+ * way to be certain would be to poll the IMR-register, which is is
+ * the very register we are trying to emulate. The register read back
+ * is a reasonable heuristic.
+ */
+ at91_rtc_read(AT91_RTC_SR);
+ at91_rtc_shadow_imr &= ~mask;
+ spin_unlock_irqrestore(&at91_rtc_lock, flags);
}
static u32 at91_rtc_read_imr(void)
{
- return at91_rtc_read(AT91_RTC_IMR);
+ unsigned long flags;
+ u32 mask;
+
+ if (at91_rtc_config->use_shadow_imr) {
+ spin_lock_irqsave(&at91_rtc_lock, flags);
+ mask = at91_rtc_shadow_imr;
+ spin_unlock_irqrestore(&at91_rtc_lock, flags);
+ } else {
+ mask = at91_rtc_read(AT91_RTC_IMR);
+ }
+
+ return mask;
}
/*
--
1.8.2.1
next prev parent reply other threads:[~2013-05-23 8:38 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1364983415-20298-1-git-send-email-jhovold@gmail.com>
2013-05-23 8:38 ` [PATCH v3 0/5] rtc-at91rm9200: add shadow interrupt mask Johan Hovold
2013-05-23 8:38 ` [PATCH v3 1/5] rtc-at91rm9200: add match-table compile guard Johan Hovold
2013-05-23 8:38 ` [PATCH v3 2/5] rtc-at91rm9200: add configuration support Johan Hovold
2013-05-23 8:38 ` [PATCH v3 3/5] rtc-at91rm9200: refactor interrupt-register handling Johan Hovold
2013-05-23 8:38 ` Johan Hovold [this message]
2013-05-23 8:38 ` [PATCH v3 5/5] rtc-at91rm9200: use shadow IMR on at91sam9x5 Johan Hovold
2013-05-29 20:33 ` [PATCH v3 0/5] rtc-at91rm9200: add shadow interrupt mask Andrew Morton
2013-05-29 20:41 ` Robert Nelson
2013-05-29 23:22 ` Douglas Gilbert
2013-05-30 8:18 ` Nicolas Ferre
2013-05-30 7:50 ` Nicolas Ferre
2013-05-30 19:36 ` Andrew Morton
2013-05-30 23:17 ` Douglas Gilbert
2013-05-31 7:54 ` Nicolas Ferre
2013-05-30 7:41 ` 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=1369298335-24597-5-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).