Blame view

drivers/rtc/rtc-sh.c 18.3 KB
317a6104a   Paul Mundt   rtc: New RTC driv...
1
2
3
  /*
   * SuperH On-Chip RTC Support
   *
063adc750   Paul Mundt   rtc: rtc-sh: cloc...
4
   * Copyright (C) 2006 - 2009  Paul Mundt
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
5
   * Copyright (C) 2006  Jamie Lenehan
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
6
   * Copyright (C) 2008  Angelo Castello
317a6104a   Paul Mundt   rtc: New RTC driv...
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
   *
   * Based on the old arch/sh/kernel/cpu/rtc.c by:
   *
   *  Copyright (C) 2000  Philipp Rumpf <prumpf@tux.org>
   *  Copyright (C) 1999  Tetsuya Okada & Niibe Yutaka
   *
   * This file is subject to the terms and conditions of the GNU General Public
   * License.  See the file "COPYING" in the main directory of this archive
   * for more details.
   */
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/bcd.h>
  #include <linux/rtc.h>
  #include <linux/init.h>
  #include <linux/platform_device.h>
  #include <linux/seq_file.h>
  #include <linux/interrupt.h>
  #include <linux/spinlock.h>
31ccb081e   Jamie Lenehan   rtc: rtc-sh: fix ...
26
  #include <linux/io.h>
5d2a50371   Jonathan Cameron   rtc: move power o...
27
  #include <linux/log2.h>
063adc750   Paul Mundt   rtc: rtc-sh: cloc...
28
  #include <linux/clk.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
29
  #include <linux/slab.h>
ad89f87a8   Paul Mundt   rtc: rtc-sh: Supp...
30
  #include <asm/rtc.h>
317a6104a   Paul Mundt   rtc: New RTC driv...
31

1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
32
  #define DRV_NAME	"sh-rtc"
317a6104a   Paul Mundt   rtc: New RTC driv...
33
34
  
  #define RTC_REG(r)	((r) * rtc_reg_size)
31ccb081e   Jamie Lenehan   rtc: rtc-sh: fix ...
35
  #define R64CNT		RTC_REG(0)
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  
  #define RSECCNT		RTC_REG(1)	/* RTC sec */
  #define RMINCNT		RTC_REG(2)	/* RTC min */
  #define RHRCNT		RTC_REG(3)	/* RTC hour */
  #define RWKCNT		RTC_REG(4)	/* RTC week */
  #define RDAYCNT		RTC_REG(5)	/* RTC day */
  #define RMONCNT		RTC_REG(6)	/* RTC month */
  #define RYRCNT		RTC_REG(7)	/* RTC year */
  #define RSECAR		RTC_REG(8)	/* ALARM sec */
  #define RMINAR		RTC_REG(9)	/* ALARM min */
  #define RHRAR		RTC_REG(10)	/* ALARM hour */
  #define RWKAR		RTC_REG(11)	/* ALARM week */
  #define RDAYAR		RTC_REG(12)	/* ALARM day */
  #define RMONAR		RTC_REG(13)	/* ALARM month */
  #define RCR1		RTC_REG(14)	/* Control */
  #define RCR2		RTC_REG(15)	/* Control */
ff1b75060   Paul Mundt   rtc: rtc-sh: SH-2...
52
53
54
55
56
57
58
59
60
61
62
  /*
   * Note on RYRAR and RCR3: Up until this point most of the register
   * definitions are consistent across all of the available parts. However,
   * the placement of the optional RYRAR and RCR3 (the RYRAR control
   * register used to control RYRCNT/RYRAR compare) varies considerably
   * across various parts, occasionally being mapped in to a completely
   * unrelated address space. For proper RYRAR support a separate resource
   * would have to be handed off, but as this is purely optional in
   * practice, we simply opt not to support it, thereby keeping the code
   * quite a bit more simplified.
   */
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
63
64
  /* ALARM Bits - or with BCD encoded value */
  #define AR_ENB		0x80	/* Enable for alarm cmp   */
317a6104a   Paul Mundt   rtc: New RTC driv...
65

b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
66
67
68
69
70
71
  /* Period Bits */
  #define PF_HP		0x100	/* Enable Half Period to support 8,32,128Hz */
  #define PF_COUNT	0x200	/* Half periodic counter */
  #define PF_OXS		0x400	/* Periodic One x Second */
  #define PF_KOU		0x800	/* Kernel or User periodic request 1=kernel */
  #define PF_MASK		0xf00
317a6104a   Paul Mundt   rtc: New RTC driv...
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
  /* RCR1 Bits */
  #define RCR1_CF		0x80	/* Carry Flag             */
  #define RCR1_CIE	0x10	/* Carry Interrupt Enable */
  #define RCR1_AIE	0x08	/* Alarm Interrupt Enable */
  #define RCR1_AF		0x01	/* Alarm Flag             */
  
  /* RCR2 Bits */
  #define RCR2_PEF	0x80	/* PEriodic interrupt Flag */
  #define RCR2_PESMASK	0x70	/* Periodic interrupt Set  */
  #define RCR2_RTCEN	0x08	/* ENable RTC              */
  #define RCR2_ADJ	0x04	/* ADJustment (30-second)  */
  #define RCR2_RESET	0x02	/* Reset bit               */
  #define RCR2_START	0x01	/* Start bit               */
  
  struct sh_rtc {
063adc750   Paul Mundt   rtc: rtc-sh: cloc...
87
88
89
90
91
92
93
94
95
96
97
  	void __iomem		*regbase;
  	unsigned long		regsize;
  	struct resource		*res;
  	int			alarm_irq;
  	int			periodic_irq;
  	int			carry_irq;
  	struct clk		*clk;
  	struct rtc_device	*rtc_dev;
  	spinlock_t		lock;
  	unsigned long		capabilities;	/* See asm/rtc.h for cap bits */
  	unsigned short		periodic_freq;
317a6104a   Paul Mundt   rtc: New RTC driv...
98
  };
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
99
  static int __sh_rtc_interrupt(struct sh_rtc *rtc)
317a6104a   Paul Mundt   rtc: New RTC driv...
100
  {
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
101
  	unsigned int tmp, pending;
317a6104a   Paul Mundt   rtc: New RTC driv...
102
103
  
  	tmp = readb(rtc->regbase + RCR1);
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
104
  	pending = tmp & RCR1_CF;
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
105
  	tmp &= ~RCR1_CF;
317a6104a   Paul Mundt   rtc: New RTC driv...
106
  	writeb(tmp, rtc->regbase + RCR1);
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
107
  	/* Users have requested One x Second IRQ */
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
108
  	if (pending && rtc->periodic_freq & PF_OXS)
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
109
  		rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF);
317a6104a   Paul Mundt   rtc: New RTC driv...
110

5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
111
  	return pending;
317a6104a   Paul Mundt   rtc: New RTC driv...
112
  }
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
113
  static int __sh_rtc_alarm(struct sh_rtc *rtc)
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
114
  {
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
115
  	unsigned int tmp, pending;
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
116
117
  
  	tmp = readb(rtc->regbase + RCR1);
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
118
  	pending = tmp & RCR1_AF;
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
119
  	tmp &= ~(RCR1_AF | RCR1_AIE);
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
120
  	writeb(tmp, rtc->regbase + RCR1);
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
121

5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
122
123
  	if (pending)
  		rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
124

5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
125
  	return pending;
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
126
  }
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
127
  static int __sh_rtc_periodic(struct sh_rtc *rtc)
317a6104a   Paul Mundt   rtc: New RTC driv...
128
  {
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
129
  	struct rtc_device *rtc_dev = rtc->rtc_dev;
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
130
131
  	struct rtc_task *irq_task;
  	unsigned int tmp, pending;
317a6104a   Paul Mundt   rtc: New RTC driv...
132

b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
133
  	tmp = readb(rtc->regbase + RCR2);
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
134
  	pending = tmp & RCR2_PEF;
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
135
136
  	tmp &= ~RCR2_PEF;
  	writeb(tmp, rtc->regbase + RCR2);
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
137
138
  	if (!pending)
  		return 0;
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
139
140
141
142
143
144
145
146
  	/* Half period enabled than one skipped and the next notified */
  	if ((rtc->periodic_freq & PF_HP) && (rtc->periodic_freq & PF_COUNT))
  		rtc->periodic_freq &= ~PF_COUNT;
  	else {
  		if (rtc->periodic_freq & PF_HP)
  			rtc->periodic_freq |= PF_COUNT;
  		if (rtc->periodic_freq & PF_KOU) {
  			spin_lock(&rtc_dev->irq_task_lock);
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
147
148
149
  			irq_task = rtc_dev->irq_task;
  			if (irq_task)
  				irq_task->func(irq_task->private_data);
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
150
151
152
153
  			spin_unlock(&rtc_dev->irq_task_lock);
  		} else
  			rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF);
  	}
317a6104a   Paul Mundt   rtc: New RTC driv...
154

5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
  	return pending;
  }
  
  static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id)
  {
  	struct sh_rtc *rtc = dev_id;
  	int ret;
  
  	spin_lock(&rtc->lock);
  	ret = __sh_rtc_interrupt(rtc);
  	spin_unlock(&rtc->lock);
  
  	return IRQ_RETVAL(ret);
  }
  
  static irqreturn_t sh_rtc_alarm(int irq, void *dev_id)
  {
  	struct sh_rtc *rtc = dev_id;
  	int ret;
  
  	spin_lock(&rtc->lock);
  	ret = __sh_rtc_alarm(rtc);
  	spin_unlock(&rtc->lock);
  
  	return IRQ_RETVAL(ret);
  }
  
  static irqreturn_t sh_rtc_periodic(int irq, void *dev_id)
  {
  	struct sh_rtc *rtc = dev_id;
  	int ret;
  
  	spin_lock(&rtc->lock);
  	ret = __sh_rtc_periodic(rtc);
317a6104a   Paul Mundt   rtc: New RTC driv...
189
  	spin_unlock(&rtc->lock);
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
  	return IRQ_RETVAL(ret);
  }
  
  static irqreturn_t sh_rtc_shared(int irq, void *dev_id)
  {
  	struct sh_rtc *rtc = dev_id;
  	int ret;
  
  	spin_lock(&rtc->lock);
  	ret = __sh_rtc_interrupt(rtc);
  	ret |= __sh_rtc_alarm(rtc);
  	ret |= __sh_rtc_periodic(rtc);
  	spin_unlock(&rtc->lock);
  
  	return IRQ_RETVAL(ret);
317a6104a   Paul Mundt   rtc: New RTC driv...
205
  }
5c9740a8b   Alessandro Zummo   rtc: rtc-sh fixes
206
  static int sh_rtc_irq_set_state(struct device *dev, int enable)
317a6104a   Paul Mundt   rtc: New RTC driv...
207
208
209
210
211
212
213
214
215
  {
  	struct sh_rtc *rtc = dev_get_drvdata(dev);
  	unsigned int tmp;
  
  	spin_lock_irq(&rtc->lock);
  
  	tmp = readb(rtc->regbase + RCR2);
  
  	if (enable) {
5c9740a8b   Alessandro Zummo   rtc: rtc-sh fixes
216
  		rtc->periodic_freq |= PF_KOU;
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
217
218
  		tmp &= ~RCR2_PEF;	/* Clear PES bit */
  		tmp |= (rtc->periodic_freq & ~PF_HP);	/* Set PES2-0 */
5c9740a8b   Alessandro Zummo   rtc: rtc-sh fixes
219
220
  	} else {
  		rtc->periodic_freq &= ~PF_KOU;
317a6104a   Paul Mundt   rtc: New RTC driv...
221
  		tmp &= ~(RCR2_PESMASK | RCR2_PEF);
5c9740a8b   Alessandro Zummo   rtc: rtc-sh fixes
222
  	}
317a6104a   Paul Mundt   rtc: New RTC driv...
223
224
225
226
  
  	writeb(tmp, rtc->regbase + RCR2);
  
  	spin_unlock_irq(&rtc->lock);
5c9740a8b   Alessandro Zummo   rtc: rtc-sh fixes
227
228
  
  	return 0;
317a6104a   Paul Mundt   rtc: New RTC driv...
229
  }
5c9740a8b   Alessandro Zummo   rtc: rtc-sh fixes
230
  static int sh_rtc_irq_set_freq(struct device *dev, int freq)
317a6104a   Paul Mundt   rtc: New RTC driv...
231
232
  {
  	struct sh_rtc *rtc = dev_get_drvdata(dev);
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
233
  	int tmp, ret = 0;
317a6104a   Paul Mundt   rtc: New RTC driv...
234
235
  
  	spin_lock_irq(&rtc->lock);
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
236
  	tmp = rtc->periodic_freq & PF_MASK;
317a6104a   Paul Mundt   rtc: New RTC driv...
237

b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
  	switch (freq) {
  	case 0:
  		rtc->periodic_freq = 0x00;
  		break;
  	case 1:
  		rtc->periodic_freq = 0x60;
  		break;
  	case 2:
  		rtc->periodic_freq = 0x50;
  		break;
  	case 4:
  		rtc->periodic_freq = 0x40;
  		break;
  	case 8:
  		rtc->periodic_freq = 0x30 | PF_HP;
  		break;
  	case 16:
  		rtc->periodic_freq = 0x30;
  		break;
  	case 32:
  		rtc->periodic_freq = 0x20 | PF_HP;
  		break;
  	case 64:
  		rtc->periodic_freq = 0x20;
  		break;
  	case 128:
  		rtc->periodic_freq = 0x10 | PF_HP;
  		break;
  	case 256:
  		rtc->periodic_freq = 0x10;
  		break;
  	default:
  		ret = -ENOTSUPP;
  	}
317a6104a   Paul Mundt   rtc: New RTC driv...
272

1043bf5c9   Paul Mundt   rtc: rtc-sh: Fix ...
273
  	if (ret == 0)
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
274
  		rtc->periodic_freq |= tmp;
317a6104a   Paul Mundt   rtc: New RTC driv...
275
276
  
  	spin_unlock_irq(&rtc->lock);
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
277
  	return ret;
317a6104a   Paul Mundt   rtc: New RTC driv...
278
  }
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
279
  static inline void sh_rtc_setaie(struct device *dev, unsigned int enable)
317a6104a   Paul Mundt   rtc: New RTC driv...
280
281
282
  {
  	struct sh_rtc *rtc = dev_get_drvdata(dev);
  	unsigned int tmp;
317a6104a   Paul Mundt   rtc: New RTC driv...
283

b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
284
  	spin_lock_irq(&rtc->lock);
317a6104a   Paul Mundt   rtc: New RTC driv...
285

b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
286
  	tmp = readb(rtc->regbase + RCR1);
317a6104a   Paul Mundt   rtc: New RTC driv...
287

063adc750   Paul Mundt   rtc: rtc-sh: cloc...
288
  	if (enable)
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
289
  		tmp |= RCR1_AIE;
063adc750   Paul Mundt   rtc: rtc-sh: cloc...
290
291
  	else
  		tmp &= ~RCR1_AIE;
317a6104a   Paul Mundt   rtc: New RTC driv...
292

b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
293
  	writeb(tmp, rtc->regbase + RCR1);
317a6104a   Paul Mundt   rtc: New RTC driv...
294

b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
295
  	spin_unlock_irq(&rtc->lock);
317a6104a   Paul Mundt   rtc: New RTC driv...
296
  }
317a6104a   Paul Mundt   rtc: New RTC driv...
297
298
299
300
301
302
  static int sh_rtc_proc(struct device *dev, struct seq_file *seq)
  {
  	struct sh_rtc *rtc = dev_get_drvdata(dev);
  	unsigned int tmp;
  
  	tmp = readb(rtc->regbase + RCR1);
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
303
304
  	seq_printf(seq, "carry_IRQ\t: %s
  ", (tmp & RCR1_CIE) ? "yes" : "no");
317a6104a   Paul Mundt   rtc: New RTC driv...
305
306
307
308
  
  	tmp = readb(rtc->regbase + RCR2);
  	seq_printf(seq, "periodic_IRQ\t: %s
  ",
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
309
  		   (tmp & RCR2_PESMASK) ? "yes" : "no");
317a6104a   Paul Mundt   rtc: New RTC driv...
310
311
312
  
  	return 0;
  }
9cd88b90a   Magnus Damm   sh: sh-rtc carry ...
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
  static inline void sh_rtc_setcie(struct device *dev, unsigned int enable)
  {
  	struct sh_rtc *rtc = dev_get_drvdata(dev);
  	unsigned int tmp;
  
  	spin_lock_irq(&rtc->lock);
  
  	tmp = readb(rtc->regbase + RCR1);
  
  	if (!enable)
  		tmp &= ~RCR1_CIE;
  	else
  		tmp |= RCR1_CIE;
  
  	writeb(tmp, rtc->regbase + RCR1);
  
  	spin_unlock_irq(&rtc->lock);
  }
16380c153   John Stultz   RTC: Convert rtc ...
331
332
333
334
335
  static int sh_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
  {
  	sh_rtc_setaie(dev, enabled);
  	return 0;
  }
317a6104a   Paul Mundt   rtc: New RTC driv...
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
  static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
  {
  	struct platform_device *pdev = to_platform_device(dev);
  	struct sh_rtc *rtc = platform_get_drvdata(pdev);
  	unsigned int sec128, sec2, yr, yr100, cf_bit;
  
  	do {
  		unsigned int tmp;
  
  		spin_lock_irq(&rtc->lock);
  
  		tmp = readb(rtc->regbase + RCR1);
  		tmp &= ~RCR1_CF; /* Clear CF-bit */
  		tmp |= RCR1_CIE;
  		writeb(tmp, rtc->regbase + RCR1);
  
  		sec128 = readb(rtc->regbase + R64CNT);
fe20ba70a   Adrian Bunk   drivers/rtc/: use...
353
354
355
356
357
358
  		tm->tm_sec	= bcd2bin(readb(rtc->regbase + RSECCNT));
  		tm->tm_min	= bcd2bin(readb(rtc->regbase + RMINCNT));
  		tm->tm_hour	= bcd2bin(readb(rtc->regbase + RHRCNT));
  		tm->tm_wday	= bcd2bin(readb(rtc->regbase + RWKCNT));
  		tm->tm_mday	= bcd2bin(readb(rtc->regbase + RDAYCNT));
  		tm->tm_mon	= bcd2bin(readb(rtc->regbase + RMONCNT)) - 1;
317a6104a   Paul Mundt   rtc: New RTC driv...
359

ad89f87a8   Paul Mundt   rtc: rtc-sh: Supp...
360
361
  		if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) {
  			yr  = readw(rtc->regbase + RYRCNT);
fe20ba70a   Adrian Bunk   drivers/rtc/: use...
362
  			yr100 = bcd2bin(yr >> 8);
ad89f87a8   Paul Mundt   rtc: rtc-sh: Supp...
363
364
365
  			yr &= 0xff;
  		} else {
  			yr  = readb(rtc->regbase + RYRCNT);
fe20ba70a   Adrian Bunk   drivers/rtc/: use...
366
  			yr100 = bcd2bin((yr == 0x99) ? 0x19 : 0x20);
ad89f87a8   Paul Mundt   rtc: rtc-sh: Supp...
367
  		}
317a6104a   Paul Mundt   rtc: New RTC driv...
368

fe20ba70a   Adrian Bunk   drivers/rtc/: use...
369
  		tm->tm_year = (yr100 * 100 + bcd2bin(yr)) - 1900;
317a6104a   Paul Mundt   rtc: New RTC driv...
370
371
372
373
374
375
376
377
378
379
380
  
  		sec2 = readb(rtc->regbase + R64CNT);
  		cf_bit = readb(rtc->regbase + RCR1) & RCR1_CF;
  
  		spin_unlock_irq(&rtc->lock);
  	} while (cf_bit != 0 || ((sec128 ^ sec2) & RTC_BIT_INVERTED) != 0);
  
  #if RTC_BIT_INVERTED != 0
  	if ((sec128 & RTC_BIT_INVERTED))
  		tm->tm_sec--;
  #endif
9cd88b90a   Magnus Damm   sh: sh-rtc carry ...
381
382
383
  	/* only keep the carry interrupt enabled if UIE is on */
  	if (!(rtc->periodic_freq & PF_OXS))
  		sh_rtc_setcie(dev, 0);
435c55d1e   Paul Mundt   rtc: rtc-sh: Fix ...
384
  	dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
317a6104a   Paul Mundt   rtc: New RTC driv...
385
386
  		"mday=%d, mon=%d, year=%d, wday=%d
  ",
2a4e2b878   Harvey Harrison   rtc: replace rema...
387
  		__func__,
317a6104a   Paul Mundt   rtc: New RTC driv...
388
  		tm->tm_sec, tm->tm_min, tm->tm_hour,
a16147965   Jamie Lenehan   rtc: rtc-sh: fix ...
389
  		tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
317a6104a   Paul Mundt   rtc: New RTC driv...
390

edf22477d   Magnus Damm   sh: sh-rtc invali...
391
  	return rtc_valid_tm(tm);
317a6104a   Paul Mundt   rtc: New RTC driv...
392
393
394
395
396
397
398
399
400
401
402
403
404
405
  }
  
  static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm)
  {
  	struct platform_device *pdev = to_platform_device(dev);
  	struct sh_rtc *rtc = platform_get_drvdata(pdev);
  	unsigned int tmp;
  	int year;
  
  	spin_lock_irq(&rtc->lock);
  
  	/* Reset pre-scaler & stop RTC */
  	tmp = readb(rtc->regbase + RCR2);
  	tmp |= RCR2_RESET;
699bc6614   Markus Brunner   rtc: rtc-sh: Corr...
406
  	tmp &= ~RCR2_START;
317a6104a   Paul Mundt   rtc: New RTC driv...
407
  	writeb(tmp, rtc->regbase + RCR2);
fe20ba70a   Adrian Bunk   drivers/rtc/: use...
408
409
410
411
412
413
  	writeb(bin2bcd(tm->tm_sec),  rtc->regbase + RSECCNT);
  	writeb(bin2bcd(tm->tm_min),  rtc->regbase + RMINCNT);
  	writeb(bin2bcd(tm->tm_hour), rtc->regbase + RHRCNT);
  	writeb(bin2bcd(tm->tm_wday), rtc->regbase + RWKCNT);
  	writeb(bin2bcd(tm->tm_mday), rtc->regbase + RDAYCNT);
  	writeb(bin2bcd(tm->tm_mon + 1), rtc->regbase + RMONCNT);
317a6104a   Paul Mundt   rtc: New RTC driv...
414

ad89f87a8   Paul Mundt   rtc: rtc-sh: Supp...
415
  	if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) {
fe20ba70a   Adrian Bunk   drivers/rtc/: use...
416
417
  		year = (bin2bcd((tm->tm_year + 1900) / 100) << 8) |
  			bin2bcd(tm->tm_year % 100);
ad89f87a8   Paul Mundt   rtc: rtc-sh: Supp...
418
419
420
  		writew(year, rtc->regbase + RYRCNT);
  	} else {
  		year = tm->tm_year % 100;
fe20ba70a   Adrian Bunk   drivers/rtc/: use...
421
  		writeb(bin2bcd(year), rtc->regbase + RYRCNT);
ad89f87a8   Paul Mundt   rtc: rtc-sh: Supp...
422
  	}
317a6104a   Paul Mundt   rtc: New RTC driv...
423
424
425
426
427
428
429
430
431
432
433
  
  	/* Start RTC */
  	tmp = readb(rtc->regbase + RCR2);
  	tmp &= ~RCR2_RESET;
  	tmp |= RCR2_RTCEN | RCR2_START;
  	writeb(tmp, rtc->regbase + RCR2);
  
  	spin_unlock_irq(&rtc->lock);
  
  	return 0;
  }
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
434
435
436
437
438
439
440
441
  static inline int sh_rtc_read_alarm_value(struct sh_rtc *rtc, int reg_off)
  {
  	unsigned int byte;
  	int value = 0xff;	/* return 0xff for ignored values */
  
  	byte = readb(rtc->regbase + reg_off);
  	if (byte & AR_ENB) {
  		byte &= ~AR_ENB;	/* strip the enable bit */
fe20ba70a   Adrian Bunk   drivers/rtc/: use...
442
  		value = bcd2bin(byte);
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
443
444
445
446
447
448
449
450
451
  	}
  
  	return value;
  }
  
  static int sh_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
  {
  	struct platform_device *pdev = to_platform_device(dev);
  	struct sh_rtc *rtc = platform_get_drvdata(pdev);
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
452
  	struct rtc_time *tm = &wkalrm->time;
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
453
454
455
456
457
458
459
460
461
462
463
  
  	spin_lock_irq(&rtc->lock);
  
  	tm->tm_sec	= sh_rtc_read_alarm_value(rtc, RSECAR);
  	tm->tm_min	= sh_rtc_read_alarm_value(rtc, RMINAR);
  	tm->tm_hour	= sh_rtc_read_alarm_value(rtc, RHRAR);
  	tm->tm_wday	= sh_rtc_read_alarm_value(rtc, RWKAR);
  	tm->tm_mday	= sh_rtc_read_alarm_value(rtc, RDAYAR);
  	tm->tm_mon	= sh_rtc_read_alarm_value(rtc, RMONAR);
  	if (tm->tm_mon > 0)
  		tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
464

0d103e90f   David Brownell   [PATCH] rtc-sh: c...
465
  	wkalrm->enabled = (readb(rtc->regbase + RCR1) & RCR1_AIE) ? 1 : 0;
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
466
467
468
469
470
471
472
473
474
475
476
477
  	spin_unlock_irq(&rtc->lock);
  
  	return 0;
  }
  
  static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc,
  					    int value, int reg_off)
  {
  	/* < 0 for a value that is ignored */
  	if (value < 0)
  		writeb(0, rtc->regbase + reg_off);
  	else
fe20ba70a   Adrian Bunk   drivers/rtc/: use...
478
  		writeb(bin2bcd(value) | AR_ENB,  rtc->regbase + reg_off);
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
479
  }
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
480
481
482
483
484
485
  static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
  {
  	struct platform_device *pdev = to_platform_device(dev);
  	struct sh_rtc *rtc = platform_get_drvdata(pdev);
  	unsigned int rcr1;
  	struct rtc_time *tm = &wkalrm->time;
8441189e6   Uwe Kleine-König   rtc: sh: don't va...
486
  	int mon;
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
487
488
  
  	spin_lock_irq(&rtc->lock);
15c945c3d   Jamie Lenehan   [PATCH] rtc-sh: a...
489
  	/* disable alarm interrupt and clear the alarm flag */
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
490
  	rcr1 = readb(rtc->regbase + RCR1);
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
491
  	rcr1 &= ~(RCR1_AF | RCR1_AIE);
15c945c3d   Jamie Lenehan   [PATCH] rtc-sh: a...
492
  	writeb(rcr1, rtc->regbase + RCR1);
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
493

1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
494
495
496
497
498
499
500
501
502
503
  	/* set alarm time */
  	sh_rtc_write_alarm_value(rtc, tm->tm_sec,  RSECAR);
  	sh_rtc_write_alarm_value(rtc, tm->tm_min,  RMINAR);
  	sh_rtc_write_alarm_value(rtc, tm->tm_hour, RHRAR);
  	sh_rtc_write_alarm_value(rtc, tm->tm_wday, RWKAR);
  	sh_rtc_write_alarm_value(rtc, tm->tm_mday, RDAYAR);
  	mon = tm->tm_mon;
  	if (mon >= 0)
  		mon += 1;
  	sh_rtc_write_alarm_value(rtc, mon, RMONAR);
15c945c3d   Jamie Lenehan   [PATCH] rtc-sh: a...
504
505
506
507
  	if (wkalrm->enabled) {
  		rcr1 |= RCR1_AIE;
  		writeb(rcr1, rtc->regbase + RCR1);
  	}
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
508
509
510
511
512
  
  	spin_unlock_irq(&rtc->lock);
  
  	return 0;
  }
317a6104a   Paul Mundt   rtc: New RTC driv...
513
  static struct rtc_class_ops sh_rtc_ops = {
317a6104a   Paul Mundt   rtc: New RTC driv...
514
515
  	.read_time	= sh_rtc_read_time,
  	.set_time	= sh_rtc_set_time,
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
516
517
  	.read_alarm	= sh_rtc_read_alarm,
  	.set_alarm	= sh_rtc_set_alarm,
317a6104a   Paul Mundt   rtc: New RTC driv...
518
  	.proc		= sh_rtc_proc,
16380c153   John Stultz   RTC: Convert rtc ...
519
  	.alarm_irq_enable = sh_rtc_alarm_irq_enable,
317a6104a   Paul Mundt   rtc: New RTC driv...
520
  };
5c9740a8b   Alessandro Zummo   rtc: rtc-sh fixes
521
  static int __init sh_rtc_probe(struct platform_device *pdev)
317a6104a   Paul Mundt   rtc: New RTC driv...
522
523
524
  {
  	struct sh_rtc *rtc;
  	struct resource *res;
edf22477d   Magnus Damm   sh: sh-rtc invali...
525
  	struct rtc_time r;
063adc750   Paul Mundt   rtc: rtc-sh: cloc...
526
527
  	char clk_name[6];
  	int clk_id, ret;
317a6104a   Paul Mundt   rtc: New RTC driv...
528

0209affa6   Jingoo Han   rtc: rtc-sh: use ...
529
  	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
317a6104a   Paul Mundt   rtc: New RTC driv...
530
531
532
533
  	if (unlikely(!rtc))
  		return -ENOMEM;
  
  	spin_lock_init(&rtc->lock);
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
534
  	/* get periodic/carry/alarm irqs */
2641dc92b   roel kluin   rtc-sh: Unsigned ...
535
  	ret = platform_get_irq(pdev, 0);
2fac6674d   Anton Vorontsov   rtc: bunch of dri...
536
  	if (unlikely(ret <= 0)) {
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
537
538
  		dev_err(&pdev->dev, "No IRQ resource
  ");
0209affa6   Jingoo Han   rtc: rtc-sh: use ...
539
  		return -ENOENT;
317a6104a   Paul Mundt   rtc: New RTC driv...
540
  	}
063adc750   Paul Mundt   rtc: rtc-sh: cloc...
541

2641dc92b   roel kluin   rtc-sh: Unsigned ...
542
  	rtc->periodic_irq = ret;
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
543
544
  	rtc->carry_irq = platform_get_irq(pdev, 1);
  	rtc->alarm_irq = platform_get_irq(pdev, 2);
317a6104a   Paul Mundt   rtc: New RTC driv...
545
546
547
548
549
  
  	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
  	if (unlikely(res == NULL)) {
  		dev_err(&pdev->dev, "No IO resource
  ");
0209affa6   Jingoo Han   rtc: rtc-sh: use ...
550
  		return -ENOENT;
317a6104a   Paul Mundt   rtc: New RTC driv...
551
  	}
063adc750   Paul Mundt   rtc: rtc-sh: cloc...
552
  	rtc->regsize = resource_size(res);
317a6104a   Paul Mundt   rtc: New RTC driv...
553

0209affa6   Jingoo Han   rtc: rtc-sh: use ...
554
555
556
557
  	rtc->res = devm_request_mem_region(&pdev->dev, res->start,
  					rtc->regsize, pdev->name);
  	if (unlikely(!rtc->res))
  		return -EBUSY;
317a6104a   Paul Mundt   rtc: New RTC driv...
558

0209affa6   Jingoo Han   rtc: rtc-sh: use ...
559
560
561
562
  	rtc->regbase = devm_ioremap_nocache(&pdev->dev, rtc->res->start,
  					rtc->regsize);
  	if (unlikely(!rtc->regbase))
  		return -EINVAL;
317a6104a   Paul Mundt   rtc: New RTC driv...
563

063adc750   Paul Mundt   rtc: rtc-sh: cloc...
564
565
566
567
568
569
  	clk_id = pdev->id;
  	/* With a single device, the clock id is still "rtc0" */
  	if (clk_id < 0)
  		clk_id = 0;
  
  	snprintf(clk_name, sizeof(clk_name), "rtc%d", clk_id);
0209affa6   Jingoo Han   rtc: rtc-sh: use ...
570
  	rtc->clk = devm_clk_get(&pdev->dev, clk_name);
063adc750   Paul Mundt   rtc: rtc-sh: cloc...
571
572
573
574
575
576
577
578
579
580
581
  	if (IS_ERR(rtc->clk)) {
  		/*
  		 * No error handling for rtc->clk intentionally, not all
  		 * platforms will have a unique clock for the RTC, and
  		 * the clk API can handle the struct clk pointer being
  		 * NULL.
  		 */
  		rtc->clk = NULL;
  	}
  
  	clk_enable(rtc->clk);
ad89f87a8   Paul Mundt   rtc: rtc-sh: Supp...
582
  	rtc->capabilities = RTC_DEF_CAPABILITIES;
e58c18d43   Jingoo Han   drivers/rtc/rtc-s...
583
584
585
  	if (dev_get_platdata(&pdev->dev)) {
  		struct sh_rtc_platform_info *pinfo =
  			dev_get_platdata(&pdev->dev);
ad89f87a8   Paul Mundt   rtc: rtc-sh: Supp...
586
587
588
589
590
591
592
  
  		/*
  		 * Some CPUs have special capabilities in addition to the
  		 * default set. Add those in here.
  		 */
  		rtc->capabilities |= pinfo->capabilities;
  	}
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
593
594
  	if (rtc->carry_irq <= 0) {
  		/* register shared periodic/carry/alarm irq */
0209affa6   Jingoo Han   rtc: rtc-sh: use ...
595
596
  		ret = devm_request_irq(&pdev->dev, rtc->periodic_irq,
  				sh_rtc_shared, 0, "sh-rtc", rtc);
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
597
598
599
600
601
602
603
604
605
  		if (unlikely(ret)) {
  			dev_err(&pdev->dev,
  				"request IRQ failed with %d, IRQ %d
  ", ret,
  				rtc->periodic_irq);
  			goto err_unmap;
  		}
  	} else {
  		/* register periodic/carry/alarm irqs */
0209affa6   Jingoo Han   rtc: rtc-sh: use ...
606
607
  		ret = devm_request_irq(&pdev->dev, rtc->periodic_irq,
  				sh_rtc_periodic, 0, "sh-rtc period", rtc);
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
608
609
610
611
612
613
614
  		if (unlikely(ret)) {
  			dev_err(&pdev->dev,
  				"request period IRQ failed with %d, IRQ %d
  ",
  				ret, rtc->periodic_irq);
  			goto err_unmap;
  		}
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
615

0209affa6   Jingoo Han   rtc: rtc-sh: use ...
616
617
  		ret = devm_request_irq(&pdev->dev, rtc->carry_irq,
  				sh_rtc_interrupt, 0, "sh-rtc carry", rtc);
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
618
619
620
621
622
  		if (unlikely(ret)) {
  			dev_err(&pdev->dev,
  				"request carry IRQ failed with %d, IRQ %d
  ",
  				ret, rtc->carry_irq);
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
623
624
  			goto err_unmap;
  		}
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
625

0209affa6   Jingoo Han   rtc: rtc-sh: use ...
626
627
  		ret = devm_request_irq(&pdev->dev, rtc->alarm_irq,
  				sh_rtc_alarm, 0, "sh-rtc alarm", rtc);
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
628
629
630
631
632
  		if (unlikely(ret)) {
  			dev_err(&pdev->dev,
  				"request alarm IRQ failed with %d, IRQ %d
  ",
  				ret, rtc->alarm_irq);
5e084a158   Magnus Damm   rtc: sh-rtc: Add ...
633
634
  			goto err_unmap;
  		}
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
635
  	}
5c9740a8b   Alessandro Zummo   rtc: rtc-sh fixes
636
  	platform_set_drvdata(pdev, rtc);
9cd88b90a   Magnus Damm   sh: sh-rtc carry ...
637
  	/* everything disabled by default */
5c9740a8b   Alessandro Zummo   rtc: rtc-sh fixes
638
639
  	sh_rtc_irq_set_freq(&pdev->dev, 0);
  	sh_rtc_irq_set_state(&pdev->dev, 0);
9cd88b90a   Magnus Damm   sh: sh-rtc carry ...
640
641
  	sh_rtc_setaie(&pdev->dev, 0);
  	sh_rtc_setcie(&pdev->dev, 0);
edf22477d   Magnus Damm   sh: sh-rtc invali...
642

0209affa6   Jingoo Han   rtc: rtc-sh: use ...
643
  	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, "sh",
5c9740a8b   Alessandro Zummo   rtc: rtc-sh fixes
644
645
646
  					   &sh_rtc_ops, THIS_MODULE);
  	if (IS_ERR(rtc->rtc_dev)) {
  		ret = PTR_ERR(rtc->rtc_dev);
5c9740a8b   Alessandro Zummo   rtc: rtc-sh fixes
647
648
649
650
  		goto err_unmap;
  	}
  
  	rtc->rtc_dev->max_user_freq = 256;
edf22477d   Magnus Damm   sh: sh-rtc invali...
651
652
653
654
655
  	/* reset rtc to epoch 0 if time is invalid */
  	if (rtc_read_time(rtc->rtc_dev, &r) < 0) {
  		rtc_time_to_tm(0, &r);
  		rtc_set_time(rtc->rtc_dev, &r);
  	}
7a8fe8e32   Magnus Damm   sh: sh-rtc wakeup...
656
  	device_init_wakeup(&pdev->dev, 1);
317a6104a   Paul Mundt   rtc: New RTC driv...
657
  	return 0;
0305794c7   Paul Mundt   rtc: rtc-sh: Fixu...
658
  err_unmap:
063adc750   Paul Mundt   rtc: rtc-sh: cloc...
659
  	clk_disable(rtc->clk);
317a6104a   Paul Mundt   rtc: New RTC driv...
660
661
662
  
  	return ret;
  }
5c9740a8b   Alessandro Zummo   rtc: rtc-sh fixes
663
  static int __exit sh_rtc_remove(struct platform_device *pdev)
317a6104a   Paul Mundt   rtc: New RTC driv...
664
665
  {
  	struct sh_rtc *rtc = platform_get_drvdata(pdev);
5c9740a8b   Alessandro Zummo   rtc: rtc-sh fixes
666
  	sh_rtc_irq_set_state(&pdev->dev, 0);
317a6104a   Paul Mundt   rtc: New RTC driv...
667

317a6104a   Paul Mundt   rtc: New RTC driv...
668
  	sh_rtc_setaie(&pdev->dev, 0);
9cd88b90a   Magnus Damm   sh: sh-rtc carry ...
669
  	sh_rtc_setcie(&pdev->dev, 0);
317a6104a   Paul Mundt   rtc: New RTC driv...
670

063adc750   Paul Mundt   rtc: rtc-sh: cloc...
671
  	clk_disable(rtc->clk);
317a6104a   Paul Mundt   rtc: New RTC driv...
672
673
674
  
  	return 0;
  }
faa9fa8e4   Magnus Damm   rtc: rtc-sh: use ...
675
676
677
678
679
  
  static void sh_rtc_set_irq_wake(struct device *dev, int enabled)
  {
  	struct platform_device *pdev = to_platform_device(dev);
  	struct sh_rtc *rtc = platform_get_drvdata(pdev);
dced35aeb   Thomas Gleixner   drivers: Final ir...
680
  	irq_set_irq_wake(rtc->periodic_irq, enabled);
063adc750   Paul Mundt   rtc: rtc-sh: cloc...
681

faa9fa8e4   Magnus Damm   rtc: rtc-sh: use ...
682
  	if (rtc->carry_irq > 0) {
dced35aeb   Thomas Gleixner   drivers: Final ir...
683
684
  		irq_set_irq_wake(rtc->carry_irq, enabled);
  		irq_set_irq_wake(rtc->alarm_irq, enabled);
faa9fa8e4   Magnus Damm   rtc: rtc-sh: use ...
685
  	}
faa9fa8e4   Magnus Damm   rtc: rtc-sh: use ...
686
  }
0ed505444   Jingoo Han   rtc: rtc-sh: swit...
687
  #ifdef CONFIG_PM_SLEEP
faa9fa8e4   Magnus Damm   rtc: rtc-sh: use ...
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
  static int sh_rtc_suspend(struct device *dev)
  {
  	if (device_may_wakeup(dev))
  		sh_rtc_set_irq_wake(dev, 1);
  
  	return 0;
  }
  
  static int sh_rtc_resume(struct device *dev)
  {
  	if (device_may_wakeup(dev))
  		sh_rtc_set_irq_wake(dev, 0);
  
  	return 0;
  }
0ed505444   Jingoo Han   rtc: rtc-sh: swit...
703
  #endif
faa9fa8e4   Magnus Damm   rtc: rtc-sh: use ...
704

0ed505444   Jingoo Han   rtc: rtc-sh: swit...
705
  static SIMPLE_DEV_PM_OPS(sh_rtc_pm_ops, sh_rtc_suspend, sh_rtc_resume);
faa9fa8e4   Magnus Damm   rtc: rtc-sh: use ...
706

317a6104a   Paul Mundt   rtc: New RTC driv...
707
708
  static struct platform_driver sh_rtc_platform_driver = {
  	.driver		= {
1b73e6ae4   Jamie Lenehan   rtc: rtc-sh: alar...
709
  		.name	= DRV_NAME,
0ed505444   Jingoo Han   rtc: rtc-sh: swit...
710
  		.pm	= &sh_rtc_pm_ops,
317a6104a   Paul Mundt   rtc: New RTC driv...
711
  	},
5c9740a8b   Alessandro Zummo   rtc: rtc-sh fixes
712
  	.remove		= __exit_p(sh_rtc_remove),
317a6104a   Paul Mundt   rtc: New RTC driv...
713
  };
deed5a9dc   Jingoo Han   rtc: rtc-sh: use ...
714
  module_platform_driver_probe(sh_rtc_platform_driver, sh_rtc_probe);
317a6104a   Paul Mundt   rtc: New RTC driv...
715
716
  
  MODULE_DESCRIPTION("SuperH on-chip RTC driver");
b420b1a7a   Angelo Castello   rtc: rtc-sh: Add ...
717
718
719
  MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, "
  	      "Jamie Lenehan <lenehan@twibble.org>, "
  	      "Angelo Castello <angelo.castello@st.com>");
317a6104a   Paul Mundt   rtc: New RTC driv...
720
  MODULE_LICENSE("GPL");
ad28a07bc   Kay Sievers   rtc: fix platform...
721
  MODULE_ALIAS("platform:" DRV_NAME);