OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [rtc/] [rtc-sh.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * SuperH On-Chip RTC Support
3
 *
4
 * Copyright (C) 2006, 2007  Paul Mundt
5
 * Copyright (C) 2006  Jamie Lenehan
6
 *
7
 * Based on the old arch/sh/kernel/cpu/rtc.c by:
8
 *
9
 *  Copyright (C) 2000  Philipp Rumpf <prumpf@tux.org>
10
 *  Copyright (C) 1999  Tetsuya Okada & Niibe Yutaka
11
 *
12
 * This file is subject to the terms and conditions of the GNU General Public
13
 * License.  See the file "COPYING" in the main directory of this archive
14
 * for more details.
15
 */
16
#include <linux/module.h>
17
#include <linux/kernel.h>
18
#include <linux/bcd.h>
19
#include <linux/rtc.h>
20
#include <linux/init.h>
21
#include <linux/platform_device.h>
22
#include <linux/seq_file.h>
23
#include <linux/interrupt.h>
24
#include <linux/spinlock.h>
25
#include <linux/io.h>
26
#include <asm/rtc.h>
27
 
28
#define DRV_NAME        "sh-rtc"
29
#define DRV_VERSION     "0.1.3"
30
 
31
#ifdef CONFIG_CPU_SH3
32
#define rtc_reg_size            sizeof(u16)
33
#define RTC_BIT_INVERTED        0        /* No bug on SH7708, SH7709A */
34
#define RTC_DEF_CAPABILITIES    0UL
35
#elif defined(CONFIG_CPU_SH4)
36
#define rtc_reg_size            sizeof(u32)
37
#define RTC_BIT_INVERTED        0x40    /* bug on SH7750, SH7750S */
38
#define RTC_DEF_CAPABILITIES    RTC_CAP_4_DIGIT_YEAR
39
#endif
40
 
41
#define RTC_REG(r)      ((r) * rtc_reg_size)
42
 
43
#define R64CNT          RTC_REG(0)
44
 
45
#define RSECCNT         RTC_REG(1)      /* RTC sec */
46
#define RMINCNT         RTC_REG(2)      /* RTC min */
47
#define RHRCNT          RTC_REG(3)      /* RTC hour */
48
#define RWKCNT          RTC_REG(4)      /* RTC week */
49
#define RDAYCNT         RTC_REG(5)      /* RTC day */
50
#define RMONCNT         RTC_REG(6)      /* RTC month */
51
#define RYRCNT          RTC_REG(7)      /* RTC year */
52
#define RSECAR          RTC_REG(8)      /* ALARM sec */
53
#define RMINAR          RTC_REG(9)      /* ALARM min */
54
#define RHRAR           RTC_REG(10)     /* ALARM hour */
55
#define RWKAR           RTC_REG(11)     /* ALARM week */
56
#define RDAYAR          RTC_REG(12)     /* ALARM day */
57
#define RMONAR          RTC_REG(13)     /* ALARM month */
58
#define RCR1            RTC_REG(14)     /* Control */
59
#define RCR2            RTC_REG(15)     /* Control */
60
 
61
/* ALARM Bits - or with BCD encoded value */
62
#define AR_ENB          0x80    /* Enable for alarm cmp   */
63
 
64
/* RCR1 Bits */
65
#define RCR1_CF         0x80    /* Carry Flag             */
66
#define RCR1_CIE        0x10    /* Carry Interrupt Enable */
67
#define RCR1_AIE        0x08    /* Alarm Interrupt Enable */
68
#define RCR1_AF         0x01    /* Alarm Flag             */
69
 
70
/* RCR2 Bits */
71
#define RCR2_PEF        0x80    /* PEriodic interrupt Flag */
72
#define RCR2_PESMASK    0x70    /* Periodic interrupt Set  */
73
#define RCR2_RTCEN      0x08    /* ENable RTC              */
74
#define RCR2_ADJ        0x04    /* ADJustment (30-second)  */
75
#define RCR2_RESET      0x02    /* Reset bit               */
76
#define RCR2_START      0x01    /* Start bit               */
77
 
78
struct sh_rtc {
79
        void __iomem *regbase;
80
        unsigned long regsize;
81
        struct resource *res;
82
        unsigned int alarm_irq, periodic_irq, carry_irq;
83
        struct rtc_device *rtc_dev;
84
        spinlock_t lock;
85
        int rearm_aie;
86
        unsigned long capabilities;     /* See asm-sh/rtc.h for cap bits */
87
};
88
 
89
static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id)
90
{
91
        struct platform_device *pdev = to_platform_device(dev_id);
92
        struct sh_rtc *rtc = platform_get_drvdata(pdev);
93
        unsigned int tmp, events = 0;
94
 
95
        spin_lock(&rtc->lock);
96
 
97
        tmp = readb(rtc->regbase + RCR1);
98
        tmp &= ~RCR1_CF;
99
 
100
        if (rtc->rearm_aie) {
101
                if (tmp & RCR1_AF)
102
                        tmp &= ~RCR1_AF;        /* try to clear AF again */
103
                else {
104
                        tmp |= RCR1_AIE;        /* AF has cleared, rearm IRQ */
105
                        rtc->rearm_aie = 0;
106
                }
107
        }
108
 
109
        writeb(tmp, rtc->regbase + RCR1);
110
 
111
        rtc_update_irq(rtc->rtc_dev, 1, events);
112
 
113
        spin_unlock(&rtc->lock);
114
 
115
        return IRQ_HANDLED;
116
}
117
 
118
static irqreturn_t sh_rtc_alarm(int irq, void *dev_id)
119
{
120
        struct platform_device *pdev = to_platform_device(dev_id);
121
        struct sh_rtc *rtc = platform_get_drvdata(pdev);
122
        unsigned int tmp, events = 0;
123
 
124
        spin_lock(&rtc->lock);
125
 
126
        tmp = readb(rtc->regbase + RCR1);
127
 
128
        /*
129
         * If AF is set then the alarm has triggered. If we clear AF while
130
         * the alarm time still matches the RTC time then AF will
131
         * immediately be set again, and if AIE is enabled then the alarm
132
         * interrupt will immediately be retrigger. So we clear AIE here
133
         * and use rtc->rearm_aie so that the carry interrupt will keep
134
         * trying to clear AF and once it stays cleared it'll re-enable
135
         * AIE.
136
         */
137
        if (tmp & RCR1_AF) {
138
                events |= RTC_AF | RTC_IRQF;
139
 
140
                tmp &= ~(RCR1_AF|RCR1_AIE);
141
 
142
                writeb(tmp, rtc->regbase + RCR1);
143
 
144
                rtc->rearm_aie = 1;
145
 
146
                rtc_update_irq(rtc->rtc_dev, 1, events);
147
        }
148
 
149
        spin_unlock(&rtc->lock);
150
        return IRQ_HANDLED;
151
}
152
 
153
static irqreturn_t sh_rtc_periodic(int irq, void *dev_id)
154
{
155
        struct platform_device *pdev = to_platform_device(dev_id);
156
        struct sh_rtc *rtc = platform_get_drvdata(pdev);
157
 
158
        spin_lock(&rtc->lock);
159
 
160
        rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF);
161
 
162
        spin_unlock(&rtc->lock);
163
 
164
        return IRQ_HANDLED;
165
}
166
 
167
static inline void sh_rtc_setpie(struct device *dev, unsigned int enable)
168
{
169
        struct sh_rtc *rtc = dev_get_drvdata(dev);
170
        unsigned int tmp;
171
 
172
        spin_lock_irq(&rtc->lock);
173
 
174
        tmp = readb(rtc->regbase + RCR2);
175
 
176
        if (enable) {
177
                tmp &= ~RCR2_PESMASK;
178
                tmp |= RCR2_PEF | (2 << 4);
179
        } else
180
                tmp &= ~(RCR2_PESMASK | RCR2_PEF);
181
 
182
        writeb(tmp, rtc->regbase + RCR2);
183
 
184
        spin_unlock_irq(&rtc->lock);
185
}
186
 
187
static inline void sh_rtc_setaie(struct device *dev, unsigned int enable)
188
{
189
        struct sh_rtc *rtc = dev_get_drvdata(dev);
190
        unsigned int tmp;
191
 
192
        spin_lock_irq(&rtc->lock);
193
 
194
        tmp = readb(rtc->regbase + RCR1);
195
 
196
        if (!enable) {
197
                tmp &= ~RCR1_AIE;
198
                rtc->rearm_aie = 0;
199
        } else if (rtc->rearm_aie == 0)
200
                tmp |= RCR1_AIE;
201
 
202
        writeb(tmp, rtc->regbase + RCR1);
203
 
204
        spin_unlock_irq(&rtc->lock);
205
}
206
 
207
static int sh_rtc_open(struct device *dev)
208
{
209
        struct sh_rtc *rtc = dev_get_drvdata(dev);
210
        unsigned int tmp;
211
        int ret;
212
 
213
        tmp = readb(rtc->regbase + RCR1);
214
        tmp &= ~RCR1_CF;
215
        tmp |= RCR1_CIE;
216
        writeb(tmp, rtc->regbase + RCR1);
217
 
218
        ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED,
219
                          "sh-rtc period", dev);
220
        if (unlikely(ret)) {
221
                dev_err(dev, "request period IRQ failed with %d, IRQ %d\n",
222
                        ret, rtc->periodic_irq);
223
                return ret;
224
        }
225
 
226
        ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED,
227
                          "sh-rtc carry", dev);
228
        if (unlikely(ret)) {
229
                dev_err(dev, "request carry IRQ failed with %d, IRQ %d\n",
230
                        ret, rtc->carry_irq);
231
                free_irq(rtc->periodic_irq, dev);
232
                goto err_bad_carry;
233
        }
234
 
235
        ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED,
236
                          "sh-rtc alarm", dev);
237
        if (unlikely(ret)) {
238
                dev_err(dev, "request alarm IRQ failed with %d, IRQ %d\n",
239
                        ret, rtc->alarm_irq);
240
                goto err_bad_alarm;
241
        }
242
 
243
        return 0;
244
 
245
err_bad_alarm:
246
        free_irq(rtc->carry_irq, dev);
247
err_bad_carry:
248
        free_irq(rtc->periodic_irq, dev);
249
 
250
        return ret;
251
}
252
 
253
static void sh_rtc_release(struct device *dev)
254
{
255
        struct sh_rtc *rtc = dev_get_drvdata(dev);
256
 
257
        sh_rtc_setpie(dev, 0);
258
        sh_rtc_setaie(dev, 0);
259
 
260
        free_irq(rtc->periodic_irq, dev);
261
        free_irq(rtc->carry_irq, dev);
262
        free_irq(rtc->alarm_irq, dev);
263
}
264
 
265
static int sh_rtc_proc(struct device *dev, struct seq_file *seq)
266
{
267
        struct sh_rtc *rtc = dev_get_drvdata(dev);
268
        unsigned int tmp;
269
 
270
        tmp = readb(rtc->regbase + RCR1);
271
        seq_printf(seq, "carry_IRQ\t: %s\n",
272
                   (tmp & RCR1_CIE) ? "yes" : "no");
273
 
274
        tmp = readb(rtc->regbase + RCR2);
275
        seq_printf(seq, "periodic_IRQ\t: %s\n",
276
                   (tmp & RCR2_PEF) ? "yes" : "no");
277
 
278
        return 0;
279
}
280
 
281
static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
282
{
283
        unsigned int ret = -ENOIOCTLCMD;
284
 
285
        switch (cmd) {
286
        case RTC_PIE_OFF:
287
        case RTC_PIE_ON:
288
                sh_rtc_setpie(dev, cmd == RTC_PIE_ON);
289
                ret = 0;
290
                break;
291
        case RTC_AIE_OFF:
292
        case RTC_AIE_ON:
293
                sh_rtc_setaie(dev, cmd == RTC_AIE_ON);
294
                ret = 0;
295
                break;
296
        }
297
 
298
        return ret;
299
}
300
 
301
static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
302
{
303
        struct platform_device *pdev = to_platform_device(dev);
304
        struct sh_rtc *rtc = platform_get_drvdata(pdev);
305
        unsigned int sec128, sec2, yr, yr100, cf_bit;
306
 
307
        do {
308
                unsigned int tmp;
309
 
310
                spin_lock_irq(&rtc->lock);
311
 
312
                tmp = readb(rtc->regbase + RCR1);
313
                tmp &= ~RCR1_CF; /* Clear CF-bit */
314
                tmp |= RCR1_CIE;
315
                writeb(tmp, rtc->regbase + RCR1);
316
 
317
                sec128 = readb(rtc->regbase + R64CNT);
318
 
319
                tm->tm_sec      = BCD2BIN(readb(rtc->regbase + RSECCNT));
320
                tm->tm_min      = BCD2BIN(readb(rtc->regbase + RMINCNT));
321
                tm->tm_hour     = BCD2BIN(readb(rtc->regbase + RHRCNT));
322
                tm->tm_wday     = BCD2BIN(readb(rtc->regbase + RWKCNT));
323
                tm->tm_mday     = BCD2BIN(readb(rtc->regbase + RDAYCNT));
324
                tm->tm_mon      = BCD2BIN(readb(rtc->regbase + RMONCNT)) - 1;
325
 
326
                if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) {
327
                        yr  = readw(rtc->regbase + RYRCNT);
328
                        yr100 = BCD2BIN(yr >> 8);
329
                        yr &= 0xff;
330
                } else {
331
                        yr  = readb(rtc->regbase + RYRCNT);
332
                        yr100 = BCD2BIN((yr == 0x99) ? 0x19 : 0x20);
333
                }
334
 
335
                tm->tm_year = (yr100 * 100 + BCD2BIN(yr)) - 1900;
336
 
337
                sec2 = readb(rtc->regbase + R64CNT);
338
                cf_bit = readb(rtc->regbase + RCR1) & RCR1_CF;
339
 
340
                spin_unlock_irq(&rtc->lock);
341
        } while (cf_bit != 0 || ((sec128 ^ sec2) & RTC_BIT_INVERTED) != 0);
342
 
343
#if RTC_BIT_INVERTED != 0
344
        if ((sec128 & RTC_BIT_INVERTED))
345
                tm->tm_sec--;
346
#endif
347
 
348
        dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
349
                "mday=%d, mon=%d, year=%d, wday=%d\n",
350
                __FUNCTION__,
351
                tm->tm_sec, tm->tm_min, tm->tm_hour,
352
                tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
353
 
354
        if (rtc_valid_tm(tm) < 0) {
355
                dev_err(dev, "invalid date\n");
356
                rtc_time_to_tm(0, tm);
357
        }
358
 
359
        return 0;
360
}
361
 
362
static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm)
363
{
364
        struct platform_device *pdev = to_platform_device(dev);
365
        struct sh_rtc *rtc = platform_get_drvdata(pdev);
366
        unsigned int tmp;
367
        int year;
368
 
369
        spin_lock_irq(&rtc->lock);
370
 
371
        /* Reset pre-scaler & stop RTC */
372
        tmp = readb(rtc->regbase + RCR2);
373
        tmp |= RCR2_RESET;
374
        tmp &= ~RCR2_START;
375
        writeb(tmp, rtc->regbase + RCR2);
376
 
377
        writeb(BIN2BCD(tm->tm_sec),  rtc->regbase + RSECCNT);
378
        writeb(BIN2BCD(tm->tm_min),  rtc->regbase + RMINCNT);
379
        writeb(BIN2BCD(tm->tm_hour), rtc->regbase + RHRCNT);
380
        writeb(BIN2BCD(tm->tm_wday), rtc->regbase + RWKCNT);
381
        writeb(BIN2BCD(tm->tm_mday), rtc->regbase + RDAYCNT);
382
        writeb(BIN2BCD(tm->tm_mon + 1), rtc->regbase + RMONCNT);
383
 
384
        if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) {
385
                year = (BIN2BCD((tm->tm_year + 1900) / 100) << 8) |
386
                        BIN2BCD(tm->tm_year % 100);
387
                writew(year, rtc->regbase + RYRCNT);
388
        } else {
389
                year = tm->tm_year % 100;
390
                writeb(BIN2BCD(year), rtc->regbase + RYRCNT);
391
        }
392
 
393
        /* Start RTC */
394
        tmp = readb(rtc->regbase + RCR2);
395
        tmp &= ~RCR2_RESET;
396
        tmp |= RCR2_RTCEN | RCR2_START;
397
        writeb(tmp, rtc->regbase + RCR2);
398
 
399
        spin_unlock_irq(&rtc->lock);
400
 
401
        return 0;
402
}
403
 
404
static inline int sh_rtc_read_alarm_value(struct sh_rtc *rtc, int reg_off)
405
{
406
        unsigned int byte;
407
        int value = 0xff;       /* return 0xff for ignored values */
408
 
409
        byte = readb(rtc->regbase + reg_off);
410
        if (byte & AR_ENB) {
411
                byte &= ~AR_ENB;        /* strip the enable bit */
412
                value = BCD2BIN(byte);
413
        }
414
 
415
        return value;
416
}
417
 
418
static int sh_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
419
{
420
        struct platform_device *pdev = to_platform_device(dev);
421
        struct sh_rtc *rtc = platform_get_drvdata(pdev);
422
        struct rtc_time* tm = &wkalrm->time;
423
 
424
        spin_lock_irq(&rtc->lock);
425
 
426
        tm->tm_sec      = sh_rtc_read_alarm_value(rtc, RSECAR);
427
        tm->tm_min      = sh_rtc_read_alarm_value(rtc, RMINAR);
428
        tm->tm_hour     = sh_rtc_read_alarm_value(rtc, RHRAR);
429
        tm->tm_wday     = sh_rtc_read_alarm_value(rtc, RWKAR);
430
        tm->tm_mday     = sh_rtc_read_alarm_value(rtc, RDAYAR);
431
        tm->tm_mon      = sh_rtc_read_alarm_value(rtc, RMONAR);
432
        if (tm->tm_mon > 0)
433
                tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */
434
        tm->tm_year     = 0xffff;
435
 
436
        wkalrm->enabled = (readb(rtc->regbase + RCR1) & RCR1_AIE) ? 1 : 0;
437
 
438
        spin_unlock_irq(&rtc->lock);
439
 
440
        return 0;
441
}
442
 
443
static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc,
444
                                            int value, int reg_off)
445
{
446
        /* < 0 for a value that is ignored */
447
        if (value < 0)
448
                writeb(0, rtc->regbase + reg_off);
449
        else
450
                writeb(BIN2BCD(value) | AR_ENB,  rtc->regbase + reg_off);
451
}
452
 
453
static int sh_rtc_check_alarm(struct rtc_time* tm)
454
{
455
        /*
456
         * The original rtc says anything > 0xc0 is "don't care" or "match
457
         * all" - most users use 0xff but rtc-dev uses -1 for the same thing.
458
         * The original rtc doesn't support years - some things use -1 and
459
         * some 0xffff. We use -1 to make out tests easier.
460
         */
461
        if (tm->tm_year == 0xffff)
462
                tm->tm_year = -1;
463
        if (tm->tm_mon >= 0xff)
464
                tm->tm_mon = -1;
465
        if (tm->tm_mday >= 0xff)
466
                tm->tm_mday = -1;
467
        if (tm->tm_wday >= 0xff)
468
                tm->tm_wday = -1;
469
        if (tm->tm_hour >= 0xff)
470
                tm->tm_hour = -1;
471
        if (tm->tm_min >= 0xff)
472
                tm->tm_min = -1;
473
        if (tm->tm_sec >= 0xff)
474
                tm->tm_sec = -1;
475
 
476
        if (tm->tm_year > 9999 ||
477
                tm->tm_mon >= 12 ||
478
                tm->tm_mday == 0 || tm->tm_mday >= 32 ||
479
                tm->tm_wday >= 7 ||
480
                tm->tm_hour >= 24 ||
481
                tm->tm_min >= 60 ||
482
                tm->tm_sec >= 60)
483
                return -EINVAL;
484
 
485
        return 0;
486
}
487
 
488
static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
489
{
490
        struct platform_device *pdev = to_platform_device(dev);
491
        struct sh_rtc *rtc = platform_get_drvdata(pdev);
492
        unsigned int rcr1;
493
        struct rtc_time *tm = &wkalrm->time;
494
        int mon, err;
495
 
496
        err = sh_rtc_check_alarm(tm);
497
        if (unlikely(err < 0))
498
                return err;
499
 
500
        spin_lock_irq(&rtc->lock);
501
 
502
        /* disable alarm interrupt and clear the alarm flag */
503
        rcr1 = readb(rtc->regbase + RCR1);
504
        rcr1 &= ~(RCR1_AF|RCR1_AIE);
505
        writeb(rcr1, rtc->regbase + RCR1);
506
 
507
        rtc->rearm_aie = 0;
508
 
509
        /* set alarm time */
510
        sh_rtc_write_alarm_value(rtc, tm->tm_sec,  RSECAR);
511
        sh_rtc_write_alarm_value(rtc, tm->tm_min,  RMINAR);
512
        sh_rtc_write_alarm_value(rtc, tm->tm_hour, RHRAR);
513
        sh_rtc_write_alarm_value(rtc, tm->tm_wday, RWKAR);
514
        sh_rtc_write_alarm_value(rtc, tm->tm_mday, RDAYAR);
515
        mon = tm->tm_mon;
516
        if (mon >= 0)
517
                mon += 1;
518
        sh_rtc_write_alarm_value(rtc, mon, RMONAR);
519
 
520
        if (wkalrm->enabled) {
521
                rcr1 |= RCR1_AIE;
522
                writeb(rcr1, rtc->regbase + RCR1);
523
        }
524
 
525
        spin_unlock_irq(&rtc->lock);
526
 
527
        return 0;
528
}
529
 
530
static struct rtc_class_ops sh_rtc_ops = {
531
        .open           = sh_rtc_open,
532
        .release        = sh_rtc_release,
533
        .ioctl          = sh_rtc_ioctl,
534
        .read_time      = sh_rtc_read_time,
535
        .set_time       = sh_rtc_set_time,
536
        .read_alarm     = sh_rtc_read_alarm,
537
        .set_alarm      = sh_rtc_set_alarm,
538
        .proc           = sh_rtc_proc,
539
};
540
 
541
static int __devinit sh_rtc_probe(struct platform_device *pdev)
542
{
543
        struct sh_rtc *rtc;
544
        struct resource *res;
545
        int ret = -ENOENT;
546
 
547
        rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL);
548
        if (unlikely(!rtc))
549
                return -ENOMEM;
550
 
551
        spin_lock_init(&rtc->lock);
552
 
553
        rtc->periodic_irq = platform_get_irq(pdev, 0);
554
        if (unlikely(rtc->periodic_irq < 0)) {
555
                dev_err(&pdev->dev, "No IRQ for period\n");
556
                goto err_badres;
557
        }
558
 
559
        rtc->carry_irq = platform_get_irq(pdev, 1);
560
        if (unlikely(rtc->carry_irq < 0)) {
561
                dev_err(&pdev->dev, "No IRQ for carry\n");
562
                goto err_badres;
563
        }
564
 
565
        rtc->alarm_irq = platform_get_irq(pdev, 2);
566
        if (unlikely(rtc->alarm_irq < 0)) {
567
                dev_err(&pdev->dev, "No IRQ for alarm\n");
568
                goto err_badres;
569
        }
570
 
571
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
572
        if (unlikely(res == NULL)) {
573
                dev_err(&pdev->dev, "No IO resource\n");
574
                goto err_badres;
575
        }
576
 
577
        rtc->regsize = res->end - res->start + 1;
578
 
579
        rtc->res = request_mem_region(res->start, rtc->regsize, pdev->name);
580
        if (unlikely(!rtc->res)) {
581
                ret = -EBUSY;
582
                goto err_badres;
583
        }
584
 
585
        rtc->regbase = (void __iomem *)rtc->res->start;
586
        if (unlikely(!rtc->regbase)) {
587
                ret = -EINVAL;
588
                goto err_badmap;
589
        }
590
 
591
        rtc->rtc_dev = rtc_device_register("sh", &pdev->dev,
592
                                           &sh_rtc_ops, THIS_MODULE);
593
        if (IS_ERR(rtc->rtc_dev)) {
594
                ret = PTR_ERR(rtc->rtc_dev);
595
                goto err_badmap;
596
        }
597
 
598
        rtc->capabilities = RTC_DEF_CAPABILITIES;
599
        if (pdev->dev.platform_data) {
600
                struct sh_rtc_platform_info *pinfo = pdev->dev.platform_data;
601
 
602
                /*
603
                 * Some CPUs have special capabilities in addition to the
604
                 * default set. Add those in here.
605
                 */
606
                rtc->capabilities |= pinfo->capabilities;
607
        }
608
 
609
        platform_set_drvdata(pdev, rtc);
610
 
611
        return 0;
612
 
613
err_badmap:
614
        release_resource(rtc->res);
615
err_badres:
616
        kfree(rtc);
617
 
618
        return ret;
619
}
620
 
621
static int __devexit sh_rtc_remove(struct platform_device *pdev)
622
{
623
        struct sh_rtc *rtc = platform_get_drvdata(pdev);
624
 
625
        if (likely(rtc->rtc_dev))
626
                rtc_device_unregister(rtc->rtc_dev);
627
 
628
        sh_rtc_setpie(&pdev->dev, 0);
629
        sh_rtc_setaie(&pdev->dev, 0);
630
 
631
        release_resource(rtc->res);
632
 
633
        platform_set_drvdata(pdev, NULL);
634
 
635
        kfree(rtc);
636
 
637
        return 0;
638
}
639
static struct platform_driver sh_rtc_platform_driver = {
640
        .driver         = {
641
                .name   = DRV_NAME,
642
                .owner  = THIS_MODULE,
643
        },
644
        .probe          = sh_rtc_probe,
645
        .remove         = __devexit_p(sh_rtc_remove),
646
};
647
 
648
static int __init sh_rtc_init(void)
649
{
650
        return platform_driver_register(&sh_rtc_platform_driver);
651
}
652
 
653
static void __exit sh_rtc_exit(void)
654
{
655
        platform_driver_unregister(&sh_rtc_platform_driver);
656
}
657
 
658
module_init(sh_rtc_init);
659
module_exit(sh_rtc_exit);
660
 
661
MODULE_DESCRIPTION("SuperH on-chip RTC driver");
662
MODULE_VERSION(DRV_VERSION);
663
MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, Jamie Lenehan <lenehan@twibble.org>");
664
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.