Commit e9bc7363 authored by Barry Song's avatar Barry Song Committed by Linus Torvalds
Browse files

drivers/rtc/rtc-sirfsoc.c: replace local_irq_disable by spin_lock_irq for SMP safety



Signed-off-by: default avatarBarry Song <Baohua.Song@csr.com>
Cc: hao liu <hao.liu@csr.com>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 09e427f8
Loading
Loading
Loading
Loading
+19 −8
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ struct sirfsoc_rtc_drv {
	unsigned		irq_wake;
	/* Overflow for every 8 years extra time */
	u32			overflow_rtc;
	spinlock_t		lock;
#ifdef CONFIG_PM
	u32		saved_counter;
	u32		saved_overflow_rtc;
@@ -61,7 +62,7 @@ static int sirfsoc_rtc_read_alarm(struct device *dev,

	rtcdrv = dev_get_drvdata(dev);

	local_irq_disable();
	spin_lock_irq(&rtcdrv->lock);

	rtc_count = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN);

@@ -84,7 +85,8 @@ static int sirfsoc_rtc_read_alarm(struct device *dev,
	if (sirfsoc_rtc_iobrg_readl(
			rtcdrv->rtc_base + RTC_STATUS) & SIRFSOC_RTC_AL0E)
		alrm->enabled = 1;
	local_irq_enable();

	spin_unlock_irq(&rtcdrv->lock);

	return 0;
}
@@ -99,7 +101,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,
	if (alrm->enabled) {
		rtc_tm_to_time(&(alrm->time), &rtc_alarm);

		local_irq_disable();
		spin_lock_irq(&rtcdrv->lock);

		rtc_status_reg = sirfsoc_rtc_iobrg_readl(
				rtcdrv->rtc_base + RTC_STATUS);
@@ -123,14 +125,15 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,
		rtc_status_reg |= SIRFSOC_RTC_AL0E;
		sirfsoc_rtc_iobrg_writel(
			rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
		local_irq_enable();

		spin_unlock_irq(&rtcdrv->lock);
	} else {
		/*
		 * if this function was called with enabled=0
		 * then it could mean that the application is
		 * trying to cancel an ongoing alarm
		 */
		local_irq_disable();
		spin_lock_irq(&rtcdrv->lock);

		rtc_status_reg = sirfsoc_rtc_iobrg_readl(
				rtcdrv->rtc_base + RTC_STATUS);
@@ -146,7 +149,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,
					rtcdrv->rtc_base + RTC_STATUS);
		}

		local_irq_enable();
		spin_unlock_irq(&rtcdrv->lock);
	}

	return 0;
@@ -217,7 +220,7 @@ static int sirfsoc_rtc_alarm_irq_enable(struct device *dev,

	rtcdrv = dev_get_drvdata(dev);

	local_irq_disable();
	spin_lock_irq(&rtcdrv->lock);

	rtc_status_reg = sirfsoc_rtc_iobrg_readl(
				rtcdrv->rtc_base + RTC_STATUS);
@@ -227,7 +230,8 @@ static int sirfsoc_rtc_alarm_irq_enable(struct device *dev,
		rtc_status_reg &= ~SIRFSOC_RTC_AL0E;

	sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
	local_irq_enable();

	spin_unlock_irq(&rtcdrv->lock);

	return 0;

@@ -248,6 +252,8 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)
	unsigned long rtc_status_reg = 0x0;
	unsigned long events = 0x0;

	spin_lock(&rtcdrv->lock);

	rtc_status_reg = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_STATUS);
	/* this bit will be set ONLY if an alarm was active
	 * and it expired NOW
@@ -265,6 +271,9 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)
		rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
	}
	sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);

	spin_unlock(&rtcdrv->lock);

	/* this should wake up any apps polling/waiting on the read
	 * after setting the alarm
	 */
@@ -292,6 +301,8 @@ static int sirfsoc_rtc_probe(struct platform_device *pdev)
	if (rtcdrv == NULL)
		return -ENOMEM;

	spin_lock_init(&rtcdrv->lock);

	err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base);
	if (err) {
		dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n");