aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2015-02-03 15:44:51 -0500
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>2015-09-05 13:37:16 -0400
commit90d0ae8e9583355725583e9d1ff0ebdc97936f39 (patch)
treea30d02f925242015987afc043f1cdecfb67cead0
parent2c4fabec8790384b91473aa3d0d28d4407168ef9 (diff)
rtc: sa1100/pxa: convert to run-time register mapping
SA1100 and PXA differ only in register offsets which are currently hardcoded in a machine specific header. Some arm64 platforms (PXA1928) have this RTC block as well (and not the PXA270 variant). Convert the driver to use ioremap and set the register offsets dynamically. Since we are touching all the register accesses, convert them all to readl_relaxed/writel_relaxed. Signed-off-by: Rob Herring <robh@kernel.org> Acked-by: Robert Jarzmik <robert.jarzmik@free.fr> Cc: Alessandro Zummo <a.zummo@towertech.it> Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com> Cc: rtc-linux@googlegroups.com Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
-rw-r--r--drivers/rtc/rtc-pxa.c4
-rw-r--r--drivers/rtc/rtc-sa1100.c82
-rw-r--r--drivers/rtc/rtc-sa1100.h4
3 files changed, 63 insertions, 27 deletions
diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c
index fb9b3a7d2266..fe4985b54608 100644
--- a/drivers/rtc/rtc-pxa.c
+++ b/drivers/rtc/rtc-pxa.c
@@ -356,6 +356,10 @@ static int __init pxa_rtc_probe(struct platform_device *pdev)
356 return -ENOMEM; 356 return -ENOMEM;
357 } 357 }
358 358
359 sa1100_rtc->rcnr = pxa_rtc->base + 0x0;
360 sa1100_rtc->rtsr = pxa_rtc->base + 0x8;
361 sa1100_rtc->rtar = pxa_rtc->base + 0x4;
362 sa1100_rtc->rttr = pxa_rtc->base + 0xc;
359 ret = sa1100_rtc_init(pdev, sa1100_rtc); 363 ret = sa1100_rtc_init(pdev, sa1100_rtc);
360 if (!ret) { 364 if (!ret) {
361 dev_err(dev, "Unable to init SA1100 RTC sub-device\n"); 365 dev_err(dev, "Unable to init SA1100 RTC sub-device\n");
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index abc19abd5f2d..c2187bf6c7e4 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -35,12 +35,10 @@
35#include <linux/bitops.h> 35#include <linux/bitops.h>
36#include <linux/io.h> 36#include <linux/io.h>
37 37
38#include <mach/hardware.h> 38#define RTSR_HZE BIT(3) /* HZ interrupt enable */
39#include <mach/irqs.h> 39#define RTSR_ALE BIT(2) /* RTC alarm interrupt enable */
40 40#define RTSR_HZ BIT(1) /* HZ rising-edge detected */
41#if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP) 41#define RTSR_AL BIT(0) /* RTC alarm detected */
42#include <mach/regs-rtc.h>
43#endif
44 42
45#include "rtc-sa1100.h" 43#include "rtc-sa1100.h"
46 44
@@ -58,16 +56,16 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
58 56
59 spin_lock(&info->lock); 57 spin_lock(&info->lock);
60 58
61 rtsr = RTSR; 59 rtsr = readl_relaxed(info->rtsr);
62 /* clear interrupt sources */ 60 /* clear interrupt sources */
63 RTSR = 0; 61 writel_relaxed(0, info->rtsr);
64 /* Fix for a nasty initialization problem the in SA11xx RTSR register. 62 /* Fix for a nasty initialization problem the in SA11xx RTSR register.
65 * See also the comments in sa1100_rtc_probe(). */ 63 * See also the comments in sa1100_rtc_probe(). */
66 if (rtsr & (RTSR_ALE | RTSR_HZE)) { 64 if (rtsr & (RTSR_ALE | RTSR_HZE)) {
67 /* This is the original code, before there was the if test 65 /* This is the original code, before there was the if test
68 * above. This code does not clear interrupts that were not 66 * above. This code does not clear interrupts that were not
69 * enabled. */ 67 * enabled. */
70 RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); 68 writel_relaxed((RTSR_AL | RTSR_HZ) & (rtsr >> 2), info->rtsr);
71 } else { 69 } else {
72 /* For some reason, it is possible to enter this routine 70 /* For some reason, it is possible to enter this routine
73 * without interruptions enabled, it has been tested with 71 * without interruptions enabled, it has been tested with
@@ -76,13 +74,13 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
76 * This situation leads to an infinite "loop" of interrupt 74 * This situation leads to an infinite "loop" of interrupt
77 * routine calling and as a result the processor seems to 75 * routine calling and as a result the processor seems to
78 * lock on its first call to open(). */ 76 * lock on its first call to open(). */
79 RTSR = RTSR_AL | RTSR_HZ; 77 writel_relaxed(RTSR_AL | RTSR_HZ, info->rtsr);
80 } 78 }
81 79
82 /* clear alarm interrupt if it has occurred */ 80 /* clear alarm interrupt if it has occurred */
83 if (rtsr & RTSR_AL) 81 if (rtsr & RTSR_AL)
84 rtsr &= ~RTSR_ALE; 82 rtsr &= ~RTSR_ALE;
85 RTSR = rtsr & (RTSR_ALE | RTSR_HZE); 83 writel_relaxed(rtsr & (RTSR_ALE | RTSR_HZE), info->rtsr);
86 84
87 /* update irq data & counter */ 85 /* update irq data & counter */
88 if (rtsr & RTSR_AL) 86 if (rtsr & RTSR_AL)
@@ -130,7 +128,7 @@ static void sa1100_rtc_release(struct device *dev)
130 struct sa1100_rtc *info = dev_get_drvdata(dev); 128 struct sa1100_rtc *info = dev_get_drvdata(dev);
131 129
132 spin_lock_irq(&info->lock); 130 spin_lock_irq(&info->lock);
133 RTSR = 0; 131 writel_relaxed(0, info->rtsr);
134 spin_unlock_irq(&info->lock); 132 spin_unlock_irq(&info->lock);
135 133
136 free_irq(info->irq_alarm, dev); 134 free_irq(info->irq_alarm, dev);
@@ -139,39 +137,46 @@ static void sa1100_rtc_release(struct device *dev)
139 137
140static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) 138static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
141{ 139{
140 u32 rtsr;
142 struct sa1100_rtc *info = dev_get_drvdata(dev); 141 struct sa1100_rtc *info = dev_get_drvdata(dev);
143 142
144 spin_lock_irq(&info->lock); 143 spin_lock_irq(&info->lock);
144 rtsr = readl_relaxed(info->rtsr);
145 if (enabled) 145 if (enabled)
146 RTSR |= RTSR_ALE; 146 rtsr |= RTSR_ALE;
147 else 147 else
148 RTSR &= ~RTSR_ALE; 148 rtsr &= ~RTSR_ALE;
149 writel_relaxed(rtsr, info->rtsr);
149 spin_unlock_irq(&info->lock); 150 spin_unlock_irq(&info->lock);
150 return 0; 151 return 0;
151} 152}
152 153
153static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) 154static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm)
154{ 155{
155 rtc_time_to_tm(RCNR, tm); 156 struct sa1100_rtc *info = dev_get_drvdata(dev);
157
158 rtc_time_to_tm(readl_relaxed(info->rcnr), tm);
156 return 0; 159 return 0;
157} 160}
158 161
159static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) 162static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm)
160{ 163{
164 struct sa1100_rtc *info = dev_get_drvdata(dev);
161 unsigned long time; 165 unsigned long time;
162 int ret; 166 int ret;
163 167
164 ret = rtc_tm_to_time(tm, &time); 168 ret = rtc_tm_to_time(tm, &time);
165 if (ret == 0) 169 if (ret == 0)
166 RCNR = time; 170 writel_relaxed(time, info->rcnr);
167 return ret; 171 return ret;
168} 172}
169 173
170static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 174static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
171{ 175{
172 u32 rtsr; 176 u32 rtsr;
177 struct sa1100_rtc *info = dev_get_drvdata(dev);
173 178
174 rtsr = RTSR; 179 rtsr = readl_relaxed(info->rtsr);
175 alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0; 180 alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0;
176 alrm->pending = (rtsr & RTSR_AL) ? 1 : 0; 181 alrm->pending = (rtsr & RTSR_AL) ? 1 : 0;
177 return 0; 182 return 0;
@@ -187,12 +192,13 @@ static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
187 ret = rtc_tm_to_time(&alrm->time, &time); 192 ret = rtc_tm_to_time(&alrm->time, &time);
188 if (ret != 0) 193 if (ret != 0)
189 goto out; 194 goto out;
190 RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); 195 writel_relaxed(readl_relaxed(info->rtsr) &
191 RTAR = time; 196 (RTSR_HZE | RTSR_ALE | RTSR_AL), info->rtsr);
197 writel_relaxed(time, info->rtar);
192 if (alrm->enabled) 198 if (alrm->enabled)
193 RTSR |= RTSR_ALE; 199 writel_relaxed(readl_relaxed(info->rtsr) | RTSR_ALE, info->rtsr);
194 else 200 else
195 RTSR &= ~RTSR_ALE; 201 writel_relaxed(readl_relaxed(info->rtsr) & ~RTSR_ALE, info->rtsr);
196out: 202out:
197 spin_unlock_irq(&info->lock); 203 spin_unlock_irq(&info->lock);
198 204
@@ -201,8 +207,10 @@ out:
201 207
202static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) 208static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq)
203{ 209{
204 seq_printf(seq, "trim/divider\t\t: 0x%08x\n", (u32) RTTR); 210 struct sa1100_rtc *info = dev_get_drvdata(dev);
205 seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", (u32)RTSR); 211
212 seq_printf(seq, "trim/divider\t\t: 0x%08x\n", readl_relaxed(info->rttr));
213 seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", readl_relaxed(info->rtsr));
206 214
207 return 0; 215 return 0;
208} 216}
@@ -241,12 +249,12 @@ int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info)
241 * If the clock divider is uninitialized then reset it to the 249 * If the clock divider is uninitialized then reset it to the
242 * default value to get the 1Hz clock. 250 * default value to get the 1Hz clock.
243 */ 251 */
244 if (RTTR == 0) { 252 if (readl_relaxed(info->rttr) == 0) {
245 RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); 253 writel_relaxed(RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16), info->rttr);
246 dev_warn(&pdev->dev, "warning: " 254 dev_warn(&pdev->dev, "warning: "
247 "initializing default clock divider/trim value\n"); 255 "initializing default clock divider/trim value\n");
248 /* The current RTC value probably doesn't make sense either */ 256 /* The current RTC value probably doesn't make sense either */
249 RCNR = 0; 257 writel_relaxed(0, info->rcnr);
250 } 258 }
251 259
252 rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &sa1100_rtc_ops, 260 rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &sa1100_rtc_ops,
@@ -279,7 +287,7 @@ int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info)
279 * 287 *
280 * Notice that clearing bit 1 and 0 is accomplished by writting ONES to 288 * Notice that clearing bit 1 and 0 is accomplished by writting ONES to
281 * the corresponding bits in RTSR. */ 289 * the corresponding bits in RTSR. */
282 RTSR = RTSR_AL | RTSR_HZ; 290 writel_relaxed(RTSR_AL | RTSR_HZ, info->rtsr);
283 291
284 return 0; 292 return 0;
285} 293}
@@ -288,6 +296,8 @@ EXPORT_SYMBOL_GPL(sa1100_rtc_init);
288static int sa1100_rtc_probe(struct platform_device *pdev) 296static int sa1100_rtc_probe(struct platform_device *pdev)
289{ 297{
290 struct sa1100_rtc *info; 298 struct sa1100_rtc *info;
299 struct resource *iores;
300 void __iomem *base;
291 int irq_1hz, irq_alarm; 301 int irq_1hz, irq_alarm;
292 302
293 irq_1hz = platform_get_irq_byname(pdev, "rtc 1Hz"); 303 irq_1hz = platform_get_irq_byname(pdev, "rtc 1Hz");
@@ -301,6 +311,24 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
301 info->irq_1hz = irq_1hz; 311 info->irq_1hz = irq_1hz;
302 info->irq_alarm = irq_alarm; 312 info->irq_alarm = irq_alarm;
303 313
314 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
315 base = devm_ioremap_resource(&pdev->dev, iores);
316 if (IS_ERR(base))
317 return PTR_ERR(base);
318
319 if (IS_ENABLED(CONFIG_ARCH_SA1100) ||
320 of_device_is_compatible(pdev->dev.of_node, "mrvl,sa1100-rtc")) {
321 info->rcnr = base + 0x04;
322 info->rtsr = base + 0x10;
323 info->rtar = base + 0x00;
324 info->rttr = base + 0x08;
325 } else {
326 info->rcnr = base + 0x0;
327 info->rtsr = base + 0x8;
328 info->rtar = base + 0x4;
329 info->rttr = base + 0xc;
330 }
331
304 platform_set_drvdata(pdev, info); 332 platform_set_drvdata(pdev, info);
305 device_init_wakeup(&pdev->dev, 1); 333 device_init_wakeup(&pdev->dev, 1);
306 334
diff --git a/drivers/rtc/rtc-sa1100.h b/drivers/rtc/rtc-sa1100.h
index 665d054740a1..2c79c0c57822 100644
--- a/drivers/rtc/rtc-sa1100.h
+++ b/drivers/rtc/rtc-sa1100.h
@@ -8,6 +8,10 @@ struct platform_device;
8 8
9struct sa1100_rtc { 9struct sa1100_rtc {
10 spinlock_t lock; 10 spinlock_t lock;
11 void __iomem *rcnr;
12 void __iomem *rtar;
13 void __iomem *rtsr;
14 void __iomem *rttr;
11 int irq_1hz; 15 int irq_1hz;
12 int irq_alarm; 16 int irq_alarm;
13 struct rtc_device *rtc; 17 struct rtc_device *rtc;