aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-stk17ta8.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-stk17ta8.c')
-rw-r--r--drivers/rtc/rtc-stk17ta8.c124
1 files changed, 50 insertions, 74 deletions
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c
index d491eb265c38..67700831b5c9 100644
--- a/drivers/rtc/rtc-stk17ta8.c
+++ b/drivers/rtc/rtc-stk17ta8.c
@@ -62,7 +62,6 @@
62struct rtc_plat_data { 62struct rtc_plat_data {
63 struct rtc_device *rtc; 63 struct rtc_device *rtc;
64 void __iomem *ioaddr; 64 void __iomem *ioaddr;
65 unsigned long baseaddr;
66 unsigned long last_jiffies; 65 unsigned long last_jiffies;
67 int irq; 66 int irq;
68 unsigned int irqen; 67 unsigned int irqen;
@@ -70,6 +69,7 @@ struct rtc_plat_data {
70 int alrm_min; 69 int alrm_min;
71 int alrm_hour; 70 int alrm_hour;
72 int alrm_mday; 71 int alrm_mday;
72 spinlock_t lock;
73}; 73};
74 74
75static int stk17ta8_rtc_set_time(struct device *dev, struct rtc_time *tm) 75static int stk17ta8_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -142,7 +142,7 @@ static void stk17ta8_rtc_update_alarm(struct rtc_plat_data *pdata)
142 unsigned long irqflags; 142 unsigned long irqflags;
143 u8 flags; 143 u8 flags;
144 144
145 spin_lock_irqsave(&pdata->rtc->irq_lock, irqflags); 145 spin_lock_irqsave(&pdata->lock, irqflags);
146 146
147 flags = readb(ioaddr + RTC_FLAGS); 147 flags = readb(ioaddr + RTC_FLAGS);
148 writeb(flags | RTC_WRITE, ioaddr + RTC_FLAGS); 148 writeb(flags | RTC_WRITE, ioaddr + RTC_FLAGS);
@@ -162,7 +162,7 @@ static void stk17ta8_rtc_update_alarm(struct rtc_plat_data *pdata)
162 writeb(pdata->irqen ? RTC_INTS_AIE : 0, ioaddr + RTC_INTERRUPTS); 162 writeb(pdata->irqen ? RTC_INTS_AIE : 0, ioaddr + RTC_INTERRUPTS);
163 readb(ioaddr + RTC_FLAGS); /* clear interrupts */ 163 readb(ioaddr + RTC_FLAGS); /* clear interrupts */
164 writeb(flags & ~RTC_WRITE, ioaddr + RTC_FLAGS); 164 writeb(flags & ~RTC_WRITE, ioaddr + RTC_FLAGS);
165 spin_unlock_irqrestore(&pdata->rtc->irq_lock, irqflags); 165 spin_unlock_irqrestore(&pdata->lock, irqflags);
166} 166}
167 167
168static int stk17ta8_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 168static int stk17ta8_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
@@ -202,56 +202,53 @@ static irqreturn_t stk17ta8_rtc_interrupt(int irq, void *dev_id)
202 struct platform_device *pdev = dev_id; 202 struct platform_device *pdev = dev_id;
203 struct rtc_plat_data *pdata = platform_get_drvdata(pdev); 203 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
204 void __iomem *ioaddr = pdata->ioaddr; 204 void __iomem *ioaddr = pdata->ioaddr;
205 unsigned long events = RTC_IRQF; 205 unsigned long events = 0;
206 206
207 spin_lock(&pdata->lock);
207 /* read and clear interrupt */ 208 /* read and clear interrupt */
208 if (!(readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_AF)) 209 if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_AF) {
209 return IRQ_NONE; 210 events = RTC_IRQF;
210 if (readb(ioaddr + RTC_SECONDS_ALARM) & 0x80) 211 if (readb(ioaddr + RTC_SECONDS_ALARM) & 0x80)
211 events |= RTC_UF; 212 events |= RTC_UF;
212 else 213 else
213 events |= RTC_AF; 214 events |= RTC_AF;
214 rtc_update_irq(pdata->rtc, 1, events); 215 if (likely(pdata->rtc))
215 return IRQ_HANDLED; 216 rtc_update_irq(pdata->rtc, 1, events);
217 }
218 spin_unlock(&pdata->lock);
219 return events ? IRQ_HANDLED : IRQ_NONE;
216} 220}
217 221
218static int stk17ta8_rtc_ioctl(struct device *dev, unsigned int cmd, 222static int stk17ta8_rtc_alarm_irq_enable(struct device *dev,
219 unsigned long arg) 223 unsigned int enabled)
220{ 224{
221 struct platform_device *pdev = to_platform_device(dev); 225 struct platform_device *pdev = to_platform_device(dev);
222 struct rtc_plat_data *pdata = platform_get_drvdata(pdev); 226 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
223 227
224 if (pdata->irq <= 0) 228 if (pdata->irq <= 0)
225 return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ 229 return -EINVAL;
226 switch (cmd) { 230 if (enabled)
227 case RTC_AIE_OFF:
228 pdata->irqen &= ~RTC_AF;
229 stk17ta8_rtc_update_alarm(pdata);
230 break;
231 case RTC_AIE_ON:
232 pdata->irqen |= RTC_AF; 231 pdata->irqen |= RTC_AF;
233 stk17ta8_rtc_update_alarm(pdata); 232 else
234 break; 233 pdata->irqen &= ~RTC_AF;
235 default: 234 stk17ta8_rtc_update_alarm(pdata);
236 return -ENOIOCTLCMD;
237 }
238 return 0; 235 return 0;
239} 236}
240 237
241static const struct rtc_class_ops stk17ta8_rtc_ops = { 238static const struct rtc_class_ops stk17ta8_rtc_ops = {
242 .read_time = stk17ta8_rtc_read_time, 239 .read_time = stk17ta8_rtc_read_time,
243 .set_time = stk17ta8_rtc_set_time, 240 .set_time = stk17ta8_rtc_set_time,
244 .read_alarm = stk17ta8_rtc_read_alarm, 241 .read_alarm = stk17ta8_rtc_read_alarm,
245 .set_alarm = stk17ta8_rtc_set_alarm, 242 .set_alarm = stk17ta8_rtc_set_alarm,
246 .ioctl = stk17ta8_rtc_ioctl, 243 .alarm_irq_enable = stk17ta8_rtc_alarm_irq_enable,
247}; 244};
248 245
249static ssize_t stk17ta8_nvram_read(struct kobject *kobj, 246static ssize_t stk17ta8_nvram_read(struct kobject *kobj,
250 struct bin_attribute *attr, char *buf, 247 struct bin_attribute *attr, char *buf,
251 loff_t pos, size_t size) 248 loff_t pos, size_t size)
252{ 249{
253 struct platform_device *pdev = 250 struct device *dev = container_of(kobj, struct device, kobj);
254 to_platform_device(container_of(kobj, struct device, kobj)); 251 struct platform_device *pdev = to_platform_device(dev);
255 struct rtc_plat_data *pdata = platform_get_drvdata(pdev); 252 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
256 void __iomem *ioaddr = pdata->ioaddr; 253 void __iomem *ioaddr = pdata->ioaddr;
257 ssize_t count; 254 ssize_t count;
@@ -265,8 +262,8 @@ static ssize_t stk17ta8_nvram_write(struct kobject *kobj,
265 struct bin_attribute *attr, char *buf, 262 struct bin_attribute *attr, char *buf,
266 loff_t pos, size_t size) 263 loff_t pos, size_t size)
267{ 264{
268 struct platform_device *pdev = 265 struct device *dev = container_of(kobj, struct device, kobj);
269 to_platform_device(container_of(kobj, struct device, kobj)); 266 struct platform_device *pdev = to_platform_device(dev);
270 struct rtc_plat_data *pdata = platform_get_drvdata(pdev); 267 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
271 void __iomem *ioaddr = pdata->ioaddr; 268 void __iomem *ioaddr = pdata->ioaddr;
272 ssize_t count; 269 ssize_t count;
@@ -288,31 +285,26 @@ static struct bin_attribute stk17ta8_nvram_attr = {
288 285
289static int __devinit stk17ta8_rtc_probe(struct platform_device *pdev) 286static int __devinit stk17ta8_rtc_probe(struct platform_device *pdev)
290{ 287{
291 struct rtc_device *rtc;
292 struct resource *res; 288 struct resource *res;
293 unsigned int cal; 289 unsigned int cal;
294 unsigned int flags; 290 unsigned int flags;
295 struct rtc_plat_data *pdata; 291 struct rtc_plat_data *pdata;
296 void __iomem *ioaddr = NULL; 292 void __iomem *ioaddr;
297 int ret = 0; 293 int ret = 0;
298 294
299 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 295 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
300 if (!res) 296 if (!res)
301 return -ENODEV; 297 return -ENODEV;
302 298
303 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); 299 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
304 if (!pdata) 300 if (!pdata)
305 return -ENOMEM; 301 return -ENOMEM;
306 if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) { 302 if (!devm_request_mem_region(&pdev->dev, res->start, RTC_REG_SIZE,
307 ret = -EBUSY; 303 pdev->name))
308 goto out; 304 return -EBUSY;
309 } 305 ioaddr = devm_ioremap(&pdev->dev, res->start, RTC_REG_SIZE);
310 pdata->baseaddr = res->start; 306 if (!ioaddr)
311 ioaddr = ioremap(pdata->baseaddr, RTC_REG_SIZE); 307 return -ENOMEM;
312 if (!ioaddr) {
313 ret = -ENOMEM;
314 goto out;
315 }
316 pdata->ioaddr = ioaddr; 308 pdata->ioaddr = ioaddr;
317 pdata->irq = platform_get_irq(pdev, 0); 309 pdata->irq = platform_get_irq(pdev, 0);
318 310
@@ -328,9 +320,13 @@ static int __devinit stk17ta8_rtc_probe(struct platform_device *pdev)
328 if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_PF) 320 if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_PF)
329 dev_warn(&pdev->dev, "voltage-low detected.\n"); 321 dev_warn(&pdev->dev, "voltage-low detected.\n");
330 322
323 spin_lock_init(&pdata->lock);
324 pdata->last_jiffies = jiffies;
325 platform_set_drvdata(pdev, pdata);
331 if (pdata->irq > 0) { 326 if (pdata->irq > 0) {
332 writeb(0, ioaddr + RTC_INTERRUPTS); 327 writeb(0, ioaddr + RTC_INTERRUPTS);
333 if (request_irq(pdata->irq, stk17ta8_rtc_interrupt, 328 if (devm_request_irq(&pdev->dev, pdata->irq,
329 stk17ta8_rtc_interrupt,
334 IRQF_DISABLED | IRQF_SHARED, 330 IRQF_DISABLED | IRQF_SHARED,
335 pdev->name, pdev) < 0) { 331 pdev->name, pdev) < 0) {
336 dev_warn(&pdev->dev, "interrupt not available.\n"); 332 dev_warn(&pdev->dev, "interrupt not available.\n");
@@ -338,29 +334,14 @@ static int __devinit stk17ta8_rtc_probe(struct platform_device *pdev)
338 } 334 }
339 } 335 }
340 336
341 rtc = rtc_device_register(pdev->name, &pdev->dev, 337 pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
342 &stk17ta8_rtc_ops, THIS_MODULE); 338 &stk17ta8_rtc_ops, THIS_MODULE);
343 if (IS_ERR(rtc)) { 339 if (IS_ERR(pdata->rtc))
344 ret = PTR_ERR(rtc); 340 return PTR_ERR(pdata->rtc);
345 goto out; 341
346 }
347 pdata->rtc = rtc;
348 pdata->last_jiffies = jiffies;
349 platform_set_drvdata(pdev, pdata);
350 ret = sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr); 342 ret = sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr);
351 if (ret) 343 if (ret)
352 goto out;
353 return 0;
354 out:
355 if (pdata->rtc)
356 rtc_device_unregister(pdata->rtc); 344 rtc_device_unregister(pdata->rtc);
357 if (pdata->irq > 0)
358 free_irq(pdata->irq, pdev);
359 if (ioaddr)
360 iounmap(ioaddr);
361 if (pdata->baseaddr)
362 release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
363 kfree(pdata);
364 return ret; 345 return ret;
365} 346}
366 347
@@ -370,13 +351,8 @@ static int __devexit stk17ta8_rtc_remove(struct platform_device *pdev)
370 351
371 sysfs_remove_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr); 352 sysfs_remove_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr);
372 rtc_device_unregister(pdata->rtc); 353 rtc_device_unregister(pdata->rtc);
373 if (pdata->irq > 0) { 354 if (pdata->irq > 0)
374 writeb(0, pdata->ioaddr + RTC_INTERRUPTS); 355 writeb(0, pdata->ioaddr + RTC_INTERRUPTS);
375 free_irq(pdata->irq, pdev);
376 }
377 iounmap(pdata->ioaddr);
378 release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
379 kfree(pdata);
380 return 0; 356 return 0;
381} 357}
382 358