rtc-sa1100.c (8c0961ba7c9356186a0606a391f08e2ecb491a57) | rtc-sa1100.c (90d0ae8e9583355725583e9d1ff0ebdc97936f39) |
---|---|
1/* 2 * Real Time Clock interface for StrongARM SA1x00 and XScale PXA2xx 3 * 4 * Copyright (c) 2000 Nils Faerber 5 * 6 * Based on rtc.c by Paul Gortmaker 7 * 8 * Original Driver by Nils Faerber <nils@kernelconcepts.de> --- 21 unchanged lines hidden (view full) --- 30#include <linux/interrupt.h> 31#include <linux/slab.h> 32#include <linux/string.h> 33#include <linux/of.h> 34#include <linux/pm.h> 35#include <linux/bitops.h> 36#include <linux/io.h> 37 | 1/* 2 * Real Time Clock interface for StrongARM SA1x00 and XScale PXA2xx 3 * 4 * Copyright (c) 2000 Nils Faerber 5 * 6 * Based on rtc.c by Paul Gortmaker 7 * 8 * Original Driver by Nils Faerber <nils@kernelconcepts.de> --- 21 unchanged lines hidden (view full) --- 30#include <linux/interrupt.h> 31#include <linux/slab.h> 32#include <linux/string.h> 33#include <linux/of.h> 34#include <linux/pm.h> 35#include <linux/bitops.h> 36#include <linux/io.h> 37 |
38#include <mach/hardware.h> 39#include <mach/irqs.h> | 38#define RTSR_HZE BIT(3) /* HZ interrupt enable */ 39#define RTSR_ALE BIT(2) /* RTC alarm interrupt enable */ 40#define RTSR_HZ BIT(1) /* HZ rising-edge detected */ 41#define RTSR_AL BIT(0) /* RTC alarm detected */ |
40 | 42 |
41#if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP) 42#include <mach/regs-rtc.h> 43#endif 44 | |
45#include "rtc-sa1100.h" 46 47#define RTC_DEF_DIVIDER (32768 - 1) 48#define RTC_DEF_TRIM 0 49#define RTC_FREQ 1024 50 51 52static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) 53{ 54 struct sa1100_rtc *info = dev_get_drvdata(dev_id); 55 struct rtc_device *rtc = info->rtc; 56 unsigned int rtsr; 57 unsigned long events = 0; 58 59 spin_lock(&info->lock); 60 | 43#include "rtc-sa1100.h" 44 45#define RTC_DEF_DIVIDER (32768 - 1) 46#define RTC_DEF_TRIM 0 47#define RTC_FREQ 1024 48 49 50static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) 51{ 52 struct sa1100_rtc *info = dev_get_drvdata(dev_id); 53 struct rtc_device *rtc = info->rtc; 54 unsigned int rtsr; 55 unsigned long events = 0; 56 57 spin_lock(&info->lock); 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. 65 * See also the comments in sa1100_rtc_probe(). */ 66 if (rtsr & (RTSR_ALE | RTSR_HZE)) { 67 /* This is the original code, before there was the if test 68 * above. This code does not clear interrupts that were not 69 * enabled. */ | 62 /* Fix for a nasty initialization problem the in SA11xx RTSR register. 63 * See also the comments in sa1100_rtc_probe(). */ 64 if (rtsr & (RTSR_ALE | RTSR_HZE)) { 65 /* This is the original code, before there was the if test 66 * above. This code does not clear interrupts that were not 67 * enabled. */ |
70 RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); | 68 writel_relaxed((RTSR_AL | RTSR_HZ) & (rtsr >> 2), info->rtsr); |
71 } else { 72 /* For some reason, it is possible to enter this routine 73 * without interruptions enabled, it has been tested with 74 * several units (Bug in SA11xx chip?). 75 * 76 * This situation leads to an infinite "loop" of interrupt 77 * routine calling and as a result the processor seems to 78 * lock on its first call to open(). */ | 69 } else { 70 /* For some reason, it is possible to enter this routine 71 * without interruptions enabled, it has been tested with 72 * several units (Bug in SA11xx chip?). 73 * 74 * This situation leads to an infinite "loop" of interrupt 75 * routine calling and as a result the processor seems to 76 * lock on its first call to open(). */ |
79 RTSR = RTSR_AL | RTSR_HZ; | 77 writel_relaxed(RTSR_AL | RTSR_HZ, info->rtsr); |
80 } 81 82 /* clear alarm interrupt if it has occurred */ 83 if (rtsr & RTSR_AL) 84 rtsr &= ~RTSR_ALE; | 78 } 79 80 /* clear alarm interrupt if it has occurred */ 81 if (rtsr & RTSR_AL) 82 rtsr &= ~RTSR_ALE; |
85 RTSR = rtsr & (RTSR_ALE | RTSR_HZE); | 83 writel_relaxed(rtsr & (RTSR_ALE | RTSR_HZE), info->rtsr); |
86 87 /* update irq data & counter */ 88 if (rtsr & RTSR_AL) 89 events |= RTC_AF | RTC_IRQF; 90 if (rtsr & RTSR_HZ) 91 events |= RTC_UF | RTC_IRQF; 92 93 rtc_update_irq(rtc, 1, events); --- 31 unchanged lines hidden (view full) --- 125 return ret; 126} 127 128static void sa1100_rtc_release(struct device *dev) 129{ 130 struct sa1100_rtc *info = dev_get_drvdata(dev); 131 132 spin_lock_irq(&info->lock); | 84 85 /* update irq data & counter */ 86 if (rtsr & RTSR_AL) 87 events |= RTC_AF | RTC_IRQF; 88 if (rtsr & RTSR_HZ) 89 events |= RTC_UF | RTC_IRQF; 90 91 rtc_update_irq(rtc, 1, events); --- 31 unchanged lines hidden (view full) --- 123 return ret; 124} 125 126static void sa1100_rtc_release(struct device *dev) 127{ 128 struct sa1100_rtc *info = dev_get_drvdata(dev); 129 130 spin_lock_irq(&info->lock); |
133 RTSR = 0; | 131 writel_relaxed(0, info->rtsr); |
134 spin_unlock_irq(&info->lock); 135 136 free_irq(info->irq_alarm, dev); 137 free_irq(info->irq_1hz, dev); 138} 139 140static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) 141{ | 132 spin_unlock_irq(&info->lock); 133 134 free_irq(info->irq_alarm, dev); 135 free_irq(info->irq_1hz, dev); 136} 137 138static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) 139{ |
140 u32 rtsr; |
|
142 struct sa1100_rtc *info = dev_get_drvdata(dev); 143 144 spin_lock_irq(&info->lock); | 141 struct sa1100_rtc *info = dev_get_drvdata(dev); 142 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 return 0; 151} 152 153static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) 154{ | 150 spin_unlock_irq(&info->lock); 151 return 0; 152} 153 154static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) 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; 157} 158 159static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) 160{ | 159 return 0; 160} 161 162static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) 163{ |
164 struct sa1100_rtc *info = dev_get_drvdata(dev); |
|
161 unsigned long time; 162 int ret; 163 164 ret = rtc_tm_to_time(tm, &time); 165 if (ret == 0) | 165 unsigned long time; 166 int ret; 167 168 ret = rtc_tm_to_time(tm, &time); 169 if (ret == 0) |
166 RCNR = time; | 170 writel_relaxed(time, info->rcnr); |
167 return ret; 168} 169 170static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 171{ 172 u32 rtsr; | 171 return ret; 172} 173 174static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 175{ 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; 176 alrm->pending = (rtsr & RTSR_AL) ? 1 : 0; 177 return 0; 178} 179 180static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 181{ 182 struct sa1100_rtc *info = dev_get_drvdata(dev); 183 unsigned long time; 184 int ret; 185 186 spin_lock_irq(&info->lock); 187 ret = rtc_tm_to_time(&alrm->time, &time); 188 if (ret != 0) 189 goto out; | 180 alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0; 181 alrm->pending = (rtsr & RTSR_AL) ? 1 : 0; 182 return 0; 183} 184 185static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 186{ 187 struct sa1100_rtc *info = dev_get_drvdata(dev); 188 unsigned long time; 189 int ret; 190 191 spin_lock_irq(&info->lock); 192 ret = rtc_tm_to_time(&alrm->time, &time); 193 if (ret != 0) 194 goto out; |
190 RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); 191 RTAR = time; | 195 writel_relaxed(readl_relaxed(info->rtsr) & 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: 197 spin_unlock_irq(&info->lock); 198 199 return ret; 200} 201 202static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) 203{ | 202out: 203 spin_unlock_irq(&info->lock); 204 205 return ret; 206} 207 208static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) 209{ |
204 seq_printf(seq, "trim/divider\t\t: 0x%08x\n", (u32) RTTR); 205 seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", (u32)RTSR); | 210 struct sa1100_rtc *info = dev_get_drvdata(dev); |
206 | 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)); 214 |
|
207 return 0; 208} 209 210static const struct rtc_class_ops sa1100_rtc_ops = { 211 .open = sa1100_rtc_open, 212 .release = sa1100_rtc_release, 213 .read_time = sa1100_rtc_read_time, 214 .set_time = sa1100_rtc_set_time, --- 21 unchanged lines hidden (view full) --- 236 return ret; 237 /* 238 * According to the manual we should be able to let RTTR be zero 239 * and then a default diviser for a 32.768KHz clock is used. 240 * Apparently this doesn't work, at least for my SA1110 rev 5. 241 * If the clock divider is uninitialized then reset it to the 242 * default value to get the 1Hz clock. 243 */ | 215 return 0; 216} 217 218static const struct rtc_class_ops sa1100_rtc_ops = { 219 .open = sa1100_rtc_open, 220 .release = sa1100_rtc_release, 221 .read_time = sa1100_rtc_read_time, 222 .set_time = sa1100_rtc_set_time, --- 21 unchanged lines hidden (view full) --- 244 return ret; 245 /* 246 * According to the manual we should be able to let RTTR be zero 247 * and then a default diviser for a 32.768KHz clock is used. 248 * Apparently this doesn't work, at least for my SA1110 rev 5. 249 * If the clock divider is uninitialized then reset it to the 250 * default value to get the 1Hz clock. 251 */ |
244 if (RTTR == 0) { 245 RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); | 252 if (readl_relaxed(info->rttr) == 0) { 253 writel_relaxed(RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16), info->rttr); |
246 dev_warn(&pdev->dev, "warning: " 247 "initializing default clock divider/trim value\n"); 248 /* The current RTC value probably doesn't make sense either */ | 254 dev_warn(&pdev->dev, "warning: " 255 "initializing default clock divider/trim value\n"); 256 /* The current RTC value probably doesn't make sense either */ |
249 RCNR = 0; | 257 writel_relaxed(0, info->rcnr); |
250 } 251 252 rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &sa1100_rtc_ops, 253 THIS_MODULE); 254 if (IS_ERR(rtc)) { 255 clk_disable_unprepare(info->clk); 256 return PTR_ERR(rtc); 257 } --- 16 unchanged lines hidden (view full) --- 274 * 275 * The issue is also dealt with in sa1100_rtc_interrupt() to be on the 276 * safe side, once the condition that lead to this strange 277 * initialization is unknown and could in principle happen during 278 * normal processing. 279 * 280 * Notice that clearing bit 1 and 0 is accomplished by writting ONES to 281 * the corresponding bits in RTSR. */ | 258 } 259 260 rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &sa1100_rtc_ops, 261 THIS_MODULE); 262 if (IS_ERR(rtc)) { 263 clk_disable_unprepare(info->clk); 264 return PTR_ERR(rtc); 265 } --- 16 unchanged lines hidden (view full) --- 282 * 283 * The issue is also dealt with in sa1100_rtc_interrupt() to be on the 284 * safe side, once the condition that lead to this strange 285 * initialization is unknown and could in principle happen during 286 * normal processing. 287 * 288 * Notice that clearing bit 1 and 0 is accomplished by writting ONES to 289 * the corresponding bits in RTSR. */ |
282 RTSR = RTSR_AL | RTSR_HZ; | 290 writel_relaxed(RTSR_AL | RTSR_HZ, info->rtsr); |
283 284 return 0; 285} 286EXPORT_SYMBOL_GPL(sa1100_rtc_init); 287 288static int sa1100_rtc_probe(struct platform_device *pdev) 289{ 290 struct sa1100_rtc *info; | 291 292 return 0; 293} 294EXPORT_SYMBOL_GPL(sa1100_rtc_init); 295 296static int sa1100_rtc_probe(struct platform_device *pdev) 297{ 298 struct sa1100_rtc *info; |
299 struct resource *iores; 300 void __iomem *base; |
|
291 int irq_1hz, irq_alarm; 292 293 irq_1hz = platform_get_irq_byname(pdev, "rtc 1Hz"); 294 irq_alarm = platform_get_irq_byname(pdev, "rtc alarm"); 295 if (irq_1hz < 0 || irq_alarm < 0) 296 return -ENODEV; 297 298 info = devm_kzalloc(&pdev->dev, sizeof(struct sa1100_rtc), GFP_KERNEL); 299 if (!info) 300 return -ENOMEM; 301 info->irq_1hz = irq_1hz; 302 info->irq_alarm = irq_alarm; 303 | 301 int irq_1hz, irq_alarm; 302 303 irq_1hz = platform_get_irq_byname(pdev, "rtc 1Hz"); 304 irq_alarm = platform_get_irq_byname(pdev, "rtc alarm"); 305 if (irq_1hz < 0 || irq_alarm < 0) 306 return -ENODEV; 307 308 info = devm_kzalloc(&pdev->dev, sizeof(struct sa1100_rtc), GFP_KERNEL); 309 if (!info) 310 return -ENOMEM; 311 info->irq_1hz = irq_1hz; 312 info->irq_alarm = irq_alarm; 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); 305 device_init_wakeup(&pdev->dev, 1); 306 307 return sa1100_rtc_init(pdev, info); 308} 309 310static int sa1100_rtc_remove(struct platform_device *pdev) 311{ --- 54 unchanged lines hidden --- | 332 platform_set_drvdata(pdev, info); 333 device_init_wakeup(&pdev->dev, 1); 334 335 return sa1100_rtc_init(pdev, info); 336} 337 338static int sa1100_rtc_remove(struct platform_device *pdev) 339{ --- 54 unchanged lines hidden --- |