Patch "rtc: sun6i: Add some locking" has been added to the 4.9-stable tree
This is a note to let you know that I've just added the patch titled
rtc: sun6i: Add some locking
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
rtc-sun6i-add-some-locking.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
a9422a19ce270a22fc520f2278fb7e80c58be508Mon Sep 17 00:00:00 2001
From: Maxime Ripard <[email protected]>
Date: Mon, 23 Jan 2017 11:41:47 +0100
Subject: rtc: sun6i: Add some locking
From: Maxime Ripard <[email protected]>
commit a9422a19ce270a22fc520f2278fb7e80c58be508 upstream.
Some registers have a read-modify-write access pattern that are not atomic.
Add some locking to prevent from concurrent accesses.
--- drivers/rtc/rtc-sun6i.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
drivers/rtc/rtc-sun6i.c +15 -2
@@ -114,13 +114,17 @@ struct sun6i_rtc_dev {void __iomem *base;int irq;unsigned long alarm; + +spinlock_t lock; };static irqreturn_t sun6i_rtc_alarmirq (int irq,void *id) {struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id; +irqreturn_t ret =IRQ_NONE ;u32 val; +spin_lock (&chip->lock); val =readl (chip->base +SUN6I_ALRM_IRQ_STA );if (val &SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND ) {
@@ -129,10 +133,11 @@ static irqreturn_t sun6i_rtc_alarmirq(inrtc_update_irq (chip->rtc,1 ,RTC_AF |RTC_IRQF ); -return IRQ_HANDLED ; + ret =IRQ_HANDLED ; } +spin_unlock (&chip->lock); -return IRQ_NONE ; +return ret; }static void sun6i_rtc_setaie (int to,struct sun6i_rtc_dev *chip)
@@ -140,6 +145,7 @@ static void sun6i_rtc_setaie(int to, stru32 alrm_val =0 ;u32 alrm_irq_val =0 ;u32 alrm_wake_val =0 ; +unsigned long flags;if (to) { alrm_val =SUN6I_ALRM_EN_CNT_EN ;
@@ -150,9 +156,11 @@ static void sun6i_rtc_setaie(int to, str chip->base + SUN6I_ALRM_IRQ_STA); } +spin_lock_irqsave (&chip->lock, flags);writel (alrm_val, chip->base +SUN6I_ALRM_EN );writel (alrm_irq_val, chip->base +SUN6I_ALRM_IRQ_EN );writel (alrm_wake_val, chip->base +SUN6I_ALARM_CONFIG ); +spin_unlock_irqrestore (&chip->lock, flags); }static int sun6i_rtc_gettime (struct device *dev,struct rtc_time *rtc_tm)
@@ -191,11 +199,15 @@ static int sun6i_rtc_gettime(struct devistatic int sun6i_rtc_getalarm (struct device *dev,struct rtc_wkalrm *wkalrm) {struct sun6i_rtc_dev *chip =dev_get_drvdata (dev); +unsigned long flags;u32 alrm_st;u32 alrm_en; +spin_lock_irqsave (&chip->lock, flags); alrm_en =readl (chip->base +SUN6I_ALRM_IRQ_EN ); alrm_st =readl (chip->base +SUN6I_ALRM_IRQ_STA ); +spin_unlock_irqrestore (&chip->lock, flags); + wkalrm->enabled = !!(alrm_en &SUN6I_ALRM_EN_CNT_EN ); wkalrm->pending = !!(alrm_st &SUN6I_ALRM_EN_CNT_EN );rtc_time_to_tm (chip->alarm, &wkalrm->time);
@@ -356,6 +368,7 @@ static int sun6i_rtc_probe(struct platfo chip =devm_kzalloc (&pdev->dev,sizeof (*chip),GFP_KERNEL );if (!chip)return -ENOMEM ; +spin_lock_init (&chip->lock);platform_set_drvdata (pdev, chip); chip->dev = &pdev->dev;
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/rtc-sun6i-disable-the-build-as-a-module.patch queue-4.9/rtc-sun6i-add-some-locking.patch queue-4.9/rtc-sun6i-switch-to-the-external-oscillator.patch