aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/rtc/rtc-armada38x.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
index 43e04af39e09..cb70ced7e0db 100644
--- a/drivers/rtc/rtc-armada38x.c
+++ b/drivers/rtc/rtc-armada38x.c
@@ -40,6 +40,13 @@ struct armada38x_rtc {
40 void __iomem *regs; 40 void __iomem *regs;
41 void __iomem *regs_soc; 41 void __iomem *regs_soc;
42 spinlock_t lock; 42 spinlock_t lock;
43 /*
44 * While setting the time, the RTC TIME register should not be
45 * accessed. Setting the RTC time involves sleeping during
46 * 100ms, so a mutex instead of a spinlock is used to protect
47 * it
48 */
49 struct mutex mutex_time;
43 int irq; 50 int irq;
44}; 51};
45 52
@@ -59,8 +66,7 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
59 struct armada38x_rtc *rtc = dev_get_drvdata(dev); 66 struct armada38x_rtc *rtc = dev_get_drvdata(dev);
60 unsigned long time, time_check, flags; 67 unsigned long time, time_check, flags;
61 68
62 spin_lock_irqsave(&rtc->lock, flags); 69 mutex_lock(&rtc->mutex_time);
63
64 time = readl(rtc->regs + RTC_TIME); 70 time = readl(rtc->regs + RTC_TIME);
65 /* 71 /*
66 * WA for failing time set attempts. As stated in HW ERRATA if 72 * WA for failing time set attempts. As stated in HW ERRATA if
@@ -71,7 +77,7 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
71 if ((time_check - time) > 1) 77 if ((time_check - time) > 1)
72 time_check = readl(rtc->regs + RTC_TIME); 78 time_check = readl(rtc->regs + RTC_TIME);
73 79
74 spin_unlock_irqrestore(&rtc->lock, flags); 80 mutex_unlock(&rtc->mutex_time);
75 81
76 rtc_time_to_tm(time_check, tm); 82 rtc_time_to_tm(time_check, tm);
77 83
@@ -94,19 +100,12 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
94 * then wait for 100ms before writing to the time register to be 100 * then wait for 100ms before writing to the time register to be
95 * sure that the data will be taken into account. 101 * sure that the data will be taken into account.
96 */ 102 */
97 spin_lock_irqsave(&rtc->lock, flags); 103 mutex_lock(&rtc->mutex_time);
98
99 rtc_delayed_write(0, rtc, RTC_STATUS); 104 rtc_delayed_write(0, rtc, RTC_STATUS);
100
101 spin_unlock_irqrestore(&rtc->lock, flags);
102
103 msleep(100); 105 msleep(100);
104
105 spin_lock_irqsave(&rtc->lock, flags);
106
107 rtc_delayed_write(time, rtc, RTC_TIME); 106 rtc_delayed_write(time, rtc, RTC_TIME);
107 mutex_unlock(&rtc->mutex_time);
108 108
109 spin_unlock_irqrestore(&rtc->lock, flags);
110out: 109out:
111 return ret; 110 return ret;
112} 111}
@@ -230,6 +229,7 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
230 return -ENOMEM; 229 return -ENOMEM;
231 230
232 spin_lock_init(&rtc->lock); 231 spin_lock_init(&rtc->lock);
232 mutex_init(&rtc->mutex_time);
233 233
234 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc"); 234 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
235 rtc->regs = devm_ioremap_resource(&pdev->dev, res); 235 rtc->regs = devm_ioremap_resource(&pdev->dev, res);