~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/rtc/rtc-mc13xxx.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Real Time Clock driver for Freescale MC13XXX PMIC
 
3
 *
 
4
 * (C) 2009 Sascha Hauer, Pengutronix
 
5
 * (C) 2009 Uwe Kleine-Koenig, Pengutronix
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License version 2 as
 
9
 * published by the Free Software Foundation.
 
10
 */
 
11
 
 
12
#include <linux/mfd/mc13xxx.h>
 
13
#include <linux/platform_device.h>
 
14
#include <linux/kernel.h>
 
15
#include <linux/module.h>
 
16
#include <linux/slab.h>
 
17
#include <linux/rtc.h>
 
18
 
 
19
#define DRIVER_NAME "mc13xxx-rtc"
 
20
 
 
21
#define MC13XXX_RTCTOD  20
 
22
#define MC13XXX_RTCTODA 21
 
23
#define MC13XXX_RTCDAY  22
 
24
#define MC13XXX_RTCDAYA 23
 
25
 
 
26
struct mc13xxx_rtc {
 
27
        struct rtc_device *rtc;
 
28
        struct mc13xxx *mc13xxx;
 
29
        int valid;
 
30
};
 
31
 
 
32
static int mc13xxx_rtc_irq_enable_unlocked(struct device *dev,
 
33
                unsigned int enabled, int irq)
 
34
{
 
35
        struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
 
36
        int (*func)(struct mc13xxx *mc13xxx, int irq);
 
37
 
 
38
        if (!priv->valid)
 
39
                return -ENODATA;
 
40
 
 
41
        func = enabled ? mc13xxx_irq_unmask : mc13xxx_irq_mask;
 
42
        return func(priv->mc13xxx, irq);
 
43
}
 
44
 
 
45
static int mc13xxx_rtc_irq_enable(struct device *dev,
 
46
                unsigned int enabled, int irq)
 
47
{
 
48
        struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
 
49
        int ret;
 
50
 
 
51
        mc13xxx_lock(priv->mc13xxx);
 
52
 
 
53
        ret = mc13xxx_rtc_irq_enable_unlocked(dev, enabled, irq);
 
54
 
 
55
        mc13xxx_unlock(priv->mc13xxx);
 
56
 
 
57
        return ret;
 
58
}
 
59
 
 
60
static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
 
61
{
 
62
        struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
 
63
        unsigned int seconds, days1, days2;
 
64
        unsigned long s1970;
 
65
        int ret;
 
66
 
 
67
        mc13xxx_lock(priv->mc13xxx);
 
68
 
 
69
        if (!priv->valid) {
 
70
                ret = -ENODATA;
 
71
                goto out;
 
72
        }
 
73
 
 
74
        ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days1);
 
75
        if (unlikely(ret))
 
76
                goto out;
 
77
 
 
78
        ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTOD, &seconds);
 
79
        if (unlikely(ret))
 
80
                goto out;
 
81
 
 
82
        ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days2);
 
83
out:
 
84
        mc13xxx_unlock(priv->mc13xxx);
 
85
 
 
86
        if (ret)
 
87
                return ret;
 
88
 
 
89
        if (days2 == days1 + 1) {
 
90
                if (seconds >= 86400 / 2)
 
91
                        days2 = days1;
 
92
                else
 
93
                        days1 = days2;
 
94
        }
 
95
 
 
96
        if (days1 != days2)
 
97
                return -EIO;
 
98
 
 
99
        s1970 = days1 * 86400 + seconds;
 
100
 
 
101
        rtc_time_to_tm(s1970, tm);
 
102
 
 
103
        return rtc_valid_tm(tm);
 
104
}
 
105
 
 
106
static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs)
 
107
{
 
108
        struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
 
109
        unsigned int seconds, days;
 
110
        unsigned int alarmseconds;
 
111
        int ret;
 
112
 
 
113
        seconds = secs % 86400;
 
114
        days = secs / 86400;
 
115
 
 
116
        mc13xxx_lock(priv->mc13xxx);
 
117
 
 
118
        /*
 
119
         * temporarily invalidate alarm to prevent triggering it when the day is
 
120
         * already updated while the time isn't yet.
 
121
         */
 
122
        ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &alarmseconds);
 
123
        if (unlikely(ret))
 
124
                goto out;
 
125
 
 
126
        if (alarmseconds < 86400) {
 
127
                ret = mc13xxx_reg_write(priv->mc13xxx,
 
128
                                MC13XXX_RTCTODA, 0x1ffff);
 
129
                if (unlikely(ret))
 
130
                        goto out;
 
131
        }
 
132
 
 
133
        /*
 
134
         * write seconds=0 to prevent a day switch between writing days
 
135
         * and seconds below
 
136
         */
 
137
        ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, 0);
 
138
        if (unlikely(ret))
 
139
                goto out;
 
140
 
 
141
        ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAY, days);
 
142
        if (unlikely(ret))
 
143
                goto out;
 
144
 
 
145
        ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, seconds);
 
146
        if (unlikely(ret))
 
147
                goto out;
 
148
 
 
149
        /* restore alarm */
 
150
        if (alarmseconds < 86400) {
 
151
                ret = mc13xxx_reg_write(priv->mc13xxx,
 
152
                                MC13XXX_RTCTODA, alarmseconds);
 
153
                if (unlikely(ret))
 
154
                        goto out;
 
155
        }
 
156
 
 
157
        ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_RTCRST);
 
158
        if (unlikely(ret))
 
159
                goto out;
 
160
 
 
161
        ret = mc13xxx_irq_unmask(priv->mc13xxx, MC13XXX_IRQ_RTCRST);
 
162
out:
 
163
        priv->valid = !ret;
 
164
 
 
165
        mc13xxx_unlock(priv->mc13xxx);
 
166
 
 
167
        return ret;
 
168
}
 
169
 
 
170
static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 
171
{
 
172
        struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
 
173
        unsigned seconds, days;
 
174
        unsigned long s1970;
 
175
        int enabled, pending;
 
176
        int ret;
 
177
 
 
178
        mc13xxx_lock(priv->mc13xxx);
 
179
 
 
180
        ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &seconds);
 
181
        if (unlikely(ret))
 
182
                goto out;
 
183
        if (seconds >= 86400) {
 
184
                ret = -ENODATA;
 
185
                goto out;
 
186
        }
 
187
 
 
188
        ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days);
 
189
        if (unlikely(ret))
 
190
                goto out;
 
191
 
 
192
        ret = mc13xxx_irq_status(priv->mc13xxx, MC13XXX_IRQ_TODA,
 
193
                        &enabled, &pending);
 
194
 
 
195
out:
 
196
        mc13xxx_unlock(priv->mc13xxx);
 
197
 
 
198
        if (ret)
 
199
                return ret;
 
200
 
 
201
        alarm->enabled = enabled;
 
202
        alarm->pending = pending;
 
203
 
 
204
        s1970 = days * 86400 + seconds;
 
205
 
 
206
        rtc_time_to_tm(s1970, &alarm->time);
 
207
        dev_dbg(dev, "%s: %lu\n", __func__, s1970);
 
208
 
 
209
        return 0;
 
210
}
 
211
 
 
212
static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 
213
{
 
214
        struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
 
215
        unsigned long s1970;
 
216
        unsigned seconds, days;
 
217
        int ret;
 
218
 
 
219
        mc13xxx_lock(priv->mc13xxx);
 
220
 
 
221
        /* disable alarm to prevent false triggering */
 
222
        ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, 0x1ffff);
 
223
        if (unlikely(ret))
 
224
                goto out;
 
225
 
 
226
        ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_TODA);
 
227
        if (unlikely(ret))
 
228
                goto out;
 
229
 
 
230
        ret = rtc_tm_to_time(&alarm->time, &s1970);
 
231
        if (unlikely(ret))
 
232
                goto out;
 
233
 
 
234
        dev_dbg(dev, "%s: o%2.s %lu\n", __func__, alarm->enabled ? "n" : "ff",
 
235
                        s1970);
 
236
 
 
237
        ret = mc13xxx_rtc_irq_enable_unlocked(dev, alarm->enabled,
 
238
                        MC13XXX_IRQ_TODA);
 
239
        if (unlikely(ret))
 
240
                goto out;
 
241
 
 
242
        seconds = s1970 % 86400;
 
243
        days = s1970 / 86400;
 
244
 
 
245
        ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAYA, days);
 
246
        if (unlikely(ret))
 
247
                goto out;
 
248
 
 
249
        ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, seconds);
 
250
 
 
251
out:
 
252
        mc13xxx_unlock(priv->mc13xxx);
 
253
 
 
254
        return ret;
 
255
}
 
256
 
 
257
static irqreturn_t mc13xxx_rtc_alarm_handler(int irq, void *dev)
 
258
{
 
259
        struct mc13xxx_rtc *priv = dev;
 
260
        struct mc13xxx *mc13xxx = priv->mc13xxx;
 
261
 
 
262
        dev_dbg(&priv->rtc->dev, "Alarm\n");
 
263
 
 
264
        rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF);
 
265
 
 
266
        mc13xxx_irq_ack(mc13xxx, irq);
 
267
 
 
268
        return IRQ_HANDLED;
 
269
}
 
270
 
 
271
static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev)
 
272
{
 
273
        struct mc13xxx_rtc *priv = dev;
 
274
        struct mc13xxx *mc13xxx = priv->mc13xxx;
 
275
 
 
276
        dev_dbg(&priv->rtc->dev, "1HZ\n");
 
277
 
 
278
        rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF);
 
279
 
 
280
        mc13xxx_irq_ack(mc13xxx, irq);
 
281
 
 
282
        return IRQ_HANDLED;
 
283
}
 
284
 
 
285
static int mc13xxx_rtc_alarm_irq_enable(struct device *dev,
 
286
                unsigned int enabled)
 
287
{
 
288
        return mc13xxx_rtc_irq_enable(dev, enabled, MC13XXX_IRQ_TODA);
 
289
}
 
290
 
 
291
static const struct rtc_class_ops mc13xxx_rtc_ops = {
 
292
        .read_time = mc13xxx_rtc_read_time,
 
293
        .set_mmss = mc13xxx_rtc_set_mmss,
 
294
        .read_alarm = mc13xxx_rtc_read_alarm,
 
295
        .set_alarm = mc13xxx_rtc_set_alarm,
 
296
        .alarm_irq_enable = mc13xxx_rtc_alarm_irq_enable,
 
297
};
 
298
 
 
299
static irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev)
 
300
{
 
301
        struct mc13xxx_rtc *priv = dev;
 
302
        struct mc13xxx *mc13xxx = priv->mc13xxx;
 
303
 
 
304
        dev_dbg(&priv->rtc->dev, "RTCRST\n");
 
305
        priv->valid = 0;
 
306
 
 
307
        mc13xxx_irq_mask(mc13xxx, irq);
 
308
 
 
309
        return IRQ_HANDLED;
 
310
}
 
311
 
 
312
static int __init mc13xxx_rtc_probe(struct platform_device *pdev)
 
313
{
 
314
        int ret;
 
315
        struct mc13xxx_rtc *priv;
 
316
        struct mc13xxx *mc13xxx;
 
317
        int rtcrst_pending;
 
318
 
 
319
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 
320
        if (!priv)
 
321
                return -ENOMEM;
 
322
 
 
323
        mc13xxx = dev_get_drvdata(pdev->dev.parent);
 
324
        priv->mc13xxx = mc13xxx;
 
325
 
 
326
        platform_set_drvdata(pdev, priv);
 
327
 
 
328
        mc13xxx_lock(mc13xxx);
 
329
 
 
330
        ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_RTCRST,
 
331
                        mc13xxx_rtc_reset_handler, DRIVER_NAME, priv);
 
332
        if (ret)
 
333
                goto err_reset_irq_request;
 
334
 
 
335
        ret = mc13xxx_irq_status(mc13xxx, MC13XXX_IRQ_RTCRST,
 
336
                        NULL, &rtcrst_pending);
 
337
        if (ret)
 
338
                goto err_reset_irq_status;
 
339
 
 
340
        priv->valid = !rtcrst_pending;
 
341
 
 
342
        ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_1HZ,
 
343
                        mc13xxx_rtc_update_handler, DRIVER_NAME, priv);
 
344
        if (ret)
 
345
                goto err_update_irq_request;
 
346
 
 
347
        ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_TODA,
 
348
                        mc13xxx_rtc_alarm_handler, DRIVER_NAME, priv);
 
349
        if (ret)
 
350
                goto err_alarm_irq_request;
 
351
 
 
352
        mc13xxx_unlock(mc13xxx);
 
353
 
 
354
        priv->rtc = rtc_device_register(pdev->name,
 
355
                        &pdev->dev, &mc13xxx_rtc_ops, THIS_MODULE);
 
356
        if (IS_ERR(priv->rtc)) {
 
357
                ret = PTR_ERR(priv->rtc);
 
358
 
 
359
                mc13xxx_lock(mc13xxx);
 
360
 
 
361
                mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv);
 
362
err_alarm_irq_request:
 
363
 
 
364
                mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_1HZ, priv);
 
365
err_update_irq_request:
 
366
 
 
367
err_reset_irq_status:
 
368
 
 
369
                mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv);
 
370
err_reset_irq_request:
 
371
 
 
372
                mc13xxx_unlock(mc13xxx);
 
373
 
 
374
                platform_set_drvdata(pdev, NULL);
 
375
                kfree(priv);
 
376
        }
 
377
 
 
378
        return ret;
 
379
}
 
380
 
 
381
static int __exit mc13xxx_rtc_remove(struct platform_device *pdev)
 
382
{
 
383
        struct mc13xxx_rtc *priv = platform_get_drvdata(pdev);
 
384
 
 
385
        mc13xxx_lock(priv->mc13xxx);
 
386
 
 
387
        rtc_device_unregister(priv->rtc);
 
388
 
 
389
        mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_TODA, priv);
 
390
        mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_1HZ, priv);
 
391
        mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_RTCRST, priv);
 
392
 
 
393
        mc13xxx_unlock(priv->mc13xxx);
 
394
 
 
395
        platform_set_drvdata(pdev, NULL);
 
396
 
 
397
        kfree(priv);
 
398
 
 
399
        return 0;
 
400
}
 
401
 
 
402
const struct platform_device_id mc13xxx_rtc_idtable[] = {
 
403
        {
 
404
                .name = "mc13783-rtc",
 
405
        }, {
 
406
                .name = "mc13892-rtc",
 
407
        },
 
408
        { }
 
409
};
 
410
 
 
411
static struct platform_driver mc13xxx_rtc_driver = {
 
412
        .id_table = mc13xxx_rtc_idtable,
 
413
        .remove = __exit_p(mc13xxx_rtc_remove),
 
414
        .driver = {
 
415
                .name = DRIVER_NAME,
 
416
                .owner = THIS_MODULE,
 
417
        },
 
418
};
 
419
 
 
420
static int __init mc13xxx_rtc_init(void)
 
421
{
 
422
        return platform_driver_probe(&mc13xxx_rtc_driver, &mc13xxx_rtc_probe);
 
423
}
 
424
module_init(mc13xxx_rtc_init);
 
425
 
 
426
static void __exit mc13xxx_rtc_exit(void)
 
427
{
 
428
        platform_driver_unregister(&mc13xxx_rtc_driver);
 
429
}
 
430
module_exit(mc13xxx_rtc_exit);
 
431
 
 
432
MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
 
433
MODULE_DESCRIPTION("RTC driver for Freescale MC13XXX PMIC");
 
434
MODULE_LICENSE("GPL v2");
 
435
MODULE_ALIAS("platform:" DRIVER_NAME);