Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/rtc/rtc-vr41xx.c (Version 2.6.31.13) and /linux/drivers/rtc/rtc-vr41xx.c (Version 2.6.11.8)


  1 /*                                                  1 
  2  *  Driver for NEC VR4100 series Real Time Clo    
  3  *                                                
  4  *  Copyright (C) 2003-2008  Yoichi Yuasa <yua    
  5  *                                                
  6  *  This program is free software; you can red    
  7  *  it under the terms of the GNU General Publ    
  8  *  the Free Software Foundation; either versi    
  9  *  (at your option) any later version.           
 10  *                                                
 11  *  This program is distributed in the hope th    
 12  *  but WITHOUT ANY WARRANTY; without even the    
 13  *  MERCHANTABILITY or FITNESS FOR A PARTICULA    
 14  *  GNU General Public License for more detail    
 15  *                                                
 16  *  You should have received a copy of the GNU    
 17  *  along with this program; if not, write to     
 18  *  Foundation, Inc., 59 Temple Place, Suite 3    
 19  */                                               
 20 #include <linux/err.h>                            
 21 #include <linux/fs.h>                             
 22 #include <linux/init.h>                           
 23 #include <linux/ioport.h>                         
 24 #include <linux/interrupt.h>                      
 25 #include <linux/module.h>                         
 26 #include <linux/platform_device.h>                
 27 #include <linux/rtc.h>                            
 28 #include <linux/spinlock.h>                       
 29 #include <linux/types.h>                          
 30 #include <linux/log2.h>                           
 31                                                   
 32 #include <asm/div64.h>                            
 33 #include <asm/io.h>                               
 34 #include <asm/uaccess.h>                          
 35                                                   
 36 MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.    
 37 MODULE_DESCRIPTION("NEC VR4100 series RTC driv    
 38 MODULE_LICENSE("GPL v2");                         
 39                                                   
 40 /* RTC 1 registers */                             
 41 #define ETIMELREG               0x00              
 42 #define ETIMEMREG               0x02              
 43 #define ETIMEHREG               0x04              
 44 /* RFU */                                         
 45 #define ECMPLREG                0x08              
 46 #define ECMPMREG                0x0a              
 47 #define ECMPHREG                0x0c              
 48 /* RFU */                                         
 49 #define RTCL1LREG               0x10              
 50 #define RTCL1HREG               0x12              
 51 #define RTCL1CNTLREG            0x14              
 52 #define RTCL1CNTHREG            0x16              
 53 #define RTCL2LREG               0x18              
 54 #define RTCL2HREG               0x1a              
 55 #define RTCL2CNTLREG            0x1c              
 56 #define RTCL2CNTHREG            0x1e              
 57                                                   
 58 /* RTC 2 registers */                             
 59 #define TCLKLREG                0x00              
 60 #define TCLKHREG                0x02              
 61 #define TCLKCNTLREG             0x04              
 62 #define TCLKCNTHREG             0x06              
 63 /* RFU */                                         
 64 #define RTCINTREG               0x1e              
 65  #define TCLOCK_INT             0x08              
 66  #define RTCLONG2_INT           0x04              
 67  #define RTCLONG1_INT           0x02              
 68  #define ELAPSEDTIME_INT        0x01              
 69                                                   
 70 #define RTC_FREQUENCY           32768             
 71 #define MAX_PERIODIC_RATE       6553              
 72                                                   
 73 static void __iomem *rtc1_base;                   
 74 static void __iomem *rtc2_base;                   
 75                                                   
 76 #define rtc1_read(offset)               readw(    
 77 #define rtc1_write(offset, value)       writew    
 78                                                   
 79 #define rtc2_read(offset)               readw(    
 80 #define rtc2_write(offset, value)       writew    
 81                                                   
 82 static unsigned long epoch = 1970;      /* Jan    
 83                                                   
 84 static DEFINE_SPINLOCK(rtc_lock);                 
 85 static char rtc_name[] = "RTC";                   
 86 static unsigned long periodic_count;              
 87 static unsigned int alarm_enabled;                
 88 static int aie_irq;                               
 89 static int pie_irq;                               
 90                                                   
 91 static inline unsigned long read_elapsed_secon    
 92 {                                                 
 93                                                   
 94         unsigned long first_low, first_mid, fi    
 95                                                   
 96         unsigned long second_low, second_mid,     
 97                                                   
 98         do {                                      
 99                 first_low = rtc1_read(ETIMELRE    
100                 first_mid = rtc1_read(ETIMEMRE    
101                 first_high = rtc1_read(ETIMEHR    
102                 second_low = rtc1_read(ETIMELR    
103                 second_mid = rtc1_read(ETIMEMR    
104                 second_high = rtc1_read(ETIMEH    
105         } while (first_low != second_low || fi    
106                  first_high != second_high);      
107                                                   
108         return (first_high << 17) | (first_mid    
109 }                                                 
110                                                   
111 static inline void write_elapsed_second(unsign    
112 {                                                 
113         spin_lock_irq(&rtc_lock);                 
114                                                   
115         rtc1_write(ETIMELREG, (uint16_t)(sec <    
116         rtc1_write(ETIMEMREG, (uint16_t)(sec >    
117         rtc1_write(ETIMEHREG, (uint16_t)(sec >    
118                                                   
119         spin_unlock_irq(&rtc_lock);               
120 }                                                 
121                                                   
122 static void vr41xx_rtc_release(struct device *    
123 {                                                 
124                                                   
125         spin_lock_irq(&rtc_lock);                 
126                                                   
127         rtc1_write(ECMPLREG, 0);                  
128         rtc1_write(ECMPMREG, 0);                  
129         rtc1_write(ECMPHREG, 0);                  
130         rtc1_write(RTCL1LREG, 0);                 
131         rtc1_write(RTCL1HREG, 0);                 
132                                                   
133         spin_unlock_irq(&rtc_lock);               
134                                                   
135         disable_irq(aie_irq);                     
136         disable_irq(pie_irq);                     
137 }                                                 
138                                                   
139 static int vr41xx_rtc_read_time(struct device     
140 {                                                 
141         unsigned long epoch_sec, elapsed_sec;     
142                                                   
143         epoch_sec = mktime(epoch, 1, 1, 0, 0,     
144         elapsed_sec = read_elapsed_second();      
145                                                   
146         rtc_time_to_tm(epoch_sec + elapsed_sec    
147                                                   
148         return 0;                                 
149 }                                                 
150                                                   
151 static int vr41xx_rtc_set_time(struct device *    
152 {                                                 
153         unsigned long epoch_sec, current_sec;     
154                                                   
155         epoch_sec = mktime(epoch, 1, 1, 0, 0,     
156         current_sec = mktime(time->tm_year + 1    
157                              time->tm_hour, ti    
158                                                   
159         write_elapsed_second(current_sec - epo    
160                                                   
161         return 0;                                 
162 }                                                 
163                                                   
164 static int vr41xx_rtc_read_alarm(struct device    
165 {                                                 
166         unsigned long low, mid, high;             
167         struct rtc_time *time = &wkalrm->time;    
168                                                   
169         spin_lock_irq(&rtc_lock);                 
170                                                   
171         low = rtc1_read(ECMPLREG);                
172         mid = rtc1_read(ECMPMREG);                
173         high = rtc1_read(ECMPHREG);               
174         wkalrm->enabled = alarm_enabled;          
175                                                   
176         spin_unlock_irq(&rtc_lock);               
177                                                   
178         rtc_time_to_tm((high << 17) | (mid <<     
179                                                   
180         return 0;                                 
181 }                                                 
182                                                   
183 static int vr41xx_rtc_set_alarm(struct device     
184 {                                                 
185         unsigned long alarm_sec;                  
186         struct rtc_time *time = &wkalrm->time;    
187                                                   
188         alarm_sec = mktime(time->tm_year + 190    
189                            time->tm_hour, time    
190                                                   
191         spin_lock_irq(&rtc_lock);                 
192                                                   
193         if (alarm_enabled)                        
194                 disable_irq(aie_irq);             
195                                                   
196         rtc1_write(ECMPLREG, (uint16_t)(alarm_    
197         rtc1_write(ECMPMREG, (uint16_t)(alarm_    
198         rtc1_write(ECMPHREG, (uint16_t)(alarm_    
199                                                   
200         if (wkalrm->enabled)                      
201                 enable_irq(aie_irq);              
202                                                   
203         alarm_enabled = wkalrm->enabled;          
204                                                   
205         spin_unlock_irq(&rtc_lock);               
206                                                   
207         return 0;                                 
208 }                                                 
209                                                   
210 static int vr41xx_rtc_irq_set_freq(struct devi    
211 {                                                 
212         unsigned long count;                      
213                                                   
214         if (!is_power_of_2(freq))                 
215                 return -EINVAL;                   
216         count = RTC_FREQUENCY;                    
217         do_div(count, freq);                      
218                                                   
219         periodic_count = count;                   
220                                                   
221         spin_lock_irq(&rtc_lock);                 
222                                                   
223         rtc1_write(RTCL1LREG, count);             
224         rtc1_write(RTCL1HREG, count >> 16);       
225                                                   
226         spin_unlock_irq(&rtc_lock);               
227                                                   
228         return 0;                                 
229 }                                                 
230                                                   
231 static int vr41xx_rtc_irq_set_state(struct dev    
232 {                                                 
233         if (enabled)                              
234                 enable_irq(pie_irq);              
235         else                                      
236                 disable_irq(pie_irq);             
237                                                   
238         return 0;                                 
239 }                                                 
240                                                   
241 static int vr41xx_rtc_ioctl(struct device *dev    
242 {                                                 
243         switch (cmd) {                            
244         case RTC_AIE_ON:                          
245                 spin_lock_irq(&rtc_lock);         
246                                                   
247                 if (!alarm_enabled) {             
248                         enable_irq(aie_irq);      
249                         alarm_enabled = 1;        
250                 }                                 
251                                                   
252                 spin_unlock_irq(&rtc_lock);       
253                 break;                            
254         case RTC_AIE_OFF:                         
255                 spin_lock_irq(&rtc_lock);         
256                                                   
257                 if (alarm_enabled) {              
258                         disable_irq(aie_irq);     
259                         alarm_enabled = 0;        
260                 }                                 
261                                                   
262                 spin_unlock_irq(&rtc_lock);       
263                 break;                            
264         case RTC_EPOCH_READ:                      
265                 return put_user(epoch, (unsign    
266         case RTC_EPOCH_SET:                       
267                 /* Doesn't support before 1900    
268                 if (arg < 1900)                   
269                         return -EINVAL;           
270                 epoch = arg;                      
271                 break;                            
272         default:                                  
273                 return -ENOIOCTLCMD;              
274         }                                         
275                                                   
276         return 0;                                 
277 }                                                 
278                                                   
279 static irqreturn_t elapsedtime_interrupt(int i    
280 {                                                 
281         struct platform_device *pdev = (struct    
282         struct rtc_device *rtc = platform_get_    
283                                                   
284         rtc2_write(RTCINTREG, ELAPSEDTIME_INT)    
285                                                   
286         rtc_update_irq(rtc, 1, RTC_AF);           
287                                                   
288         return IRQ_HANDLED;                       
289 }                                                 
290                                                   
291 static irqreturn_t rtclong1_interrupt(int irq,    
292 {                                                 
293         struct platform_device *pdev = (struct    
294         struct rtc_device *rtc = platform_get_    
295         unsigned long count = periodic_count;     
296                                                   
297         rtc2_write(RTCINTREG, RTCLONG1_INT);      
298                                                   
299         rtc1_write(RTCL1LREG, count);             
300         rtc1_write(RTCL1HREG, count >> 16);       
301                                                   
302         rtc_update_irq(rtc, 1, RTC_PF);           
303                                                   
304         return IRQ_HANDLED;                       
305 }                                                 
306                                                   
307 static const struct rtc_class_ops vr41xx_rtc_o    
308         .release        = vr41xx_rtc_release,     
309         .ioctl          = vr41xx_rtc_ioctl,       
310         .read_time      = vr41xx_rtc_read_time    
311         .set_time       = vr41xx_rtc_set_time,    
312         .read_alarm     = vr41xx_rtc_read_alar    
313         .set_alarm      = vr41xx_rtc_set_alarm    
314         .irq_set_freq   = vr41xx_rtc_irq_set_f    
315         .irq_set_state  = vr41xx_rtc_irq_set_s    
316 };                                                
317                                                   
318 static int __devinit rtc_probe(struct platform    
319 {                                                 
320         struct resource *res;                     
321         struct rtc_device *rtc;                   
322         int retval;                               
323                                                   
324         if (pdev->num_resources != 4)             
325                 return -EBUSY;                    
326                                                   
327         res = platform_get_resource(pdev, IORE    
328         if (!res)                                 
329                 return -EBUSY;                    
330                                                   
331         rtc1_base = ioremap(res->start, res->e    
332         if (!rtc1_base)                           
333                 return -EBUSY;                    
334                                                   
335         res = platform_get_resource(pdev, IORE    
336         if (!res) {                               
337                 retval = -EBUSY;                  
338                 goto err_rtc1_iounmap;            
339         }                                         
340                                                   
341         rtc2_base = ioremap(res->start, res->e    
342         if (!rtc2_base) {                         
343                 retval = -EBUSY;                  
344                 goto err_rtc1_iounmap;            
345         }                                         
346                                                   
347         rtc = rtc_device_register(rtc_name, &p    
348         if (IS_ERR(rtc)) {                        
349                 retval = PTR_ERR(rtc);            
350                 goto err_iounmap_all;             
351         }                                         
352                                                   
353         rtc->max_user_freq = MAX_PERIODIC_RATE    
354                                                   
355         spin_lock_irq(&rtc_lock);                 
356                                                   
357         rtc1_write(ECMPLREG, 0);                  
358         rtc1_write(ECMPMREG, 0);                  
359         rtc1_write(ECMPHREG, 0);                  
360         rtc1_write(RTCL1LREG, 0);                 
361         rtc1_write(RTCL1HREG, 0);                 
362                                                   
363         spin_unlock_irq(&rtc_lock);               
364                                                   
365         aie_irq = platform_get_irq(pdev, 0);      
366         if (aie_irq <= 0) {                       
367                 retval = -EBUSY;                  
368                 goto err_device_unregister;       
369         }                                         
370                                                   
371         retval = request_irq(aie_irq, elapsedt    
372                              "elapsed_time", p    
373         if (retval < 0)                           
374                 goto err_device_unregister;       
375                                                   
376         pie_irq = platform_get_irq(pdev, 1);      
377         if (pie_irq <= 0)                         
378                 goto err_free_irq;                
379                                                   
380         retval = request_irq(pie_irq, rtclong1    
381                              "rtclong1", pdev)    
382         if (retval < 0)                           
383                 goto err_free_irq;                
384                                                   
385         platform_set_drvdata(pdev, rtc);          
386                                                   
387         disable_irq(aie_irq);                     
388         disable_irq(pie_irq);                     
389                                                   
390         printk(KERN_INFO "rtc: Real Time Clock    
391                                                   
392         return 0;                                 
393                                                   
394 err_free_irq:                                     
395         free_irq(aie_irq, pdev);                  
396                                                   
397 err_device_unregister:                            
398         rtc_device_unregister(rtc);               
399                                                   
400 err_iounmap_all:                                  
401         iounmap(rtc2_base);                       
402         rtc2_base = NULL;                         
403                                                   
404 err_rtc1_iounmap:                                 
405         iounmap(rtc1_base);                       
406         rtc1_base = NULL;                         
407                                                   
408         return retval;                            
409 }                                                 
410                                                   
411 static int __devexit rtc_remove(struct platfor    
412 {                                                 
413         struct rtc_device *rtc;                   
414                                                   
415         rtc = platform_get_drvdata(pdev);         
416         if (rtc)                                  
417                 rtc_device_unregister(rtc);       
418                                                   
419         platform_set_drvdata(pdev, NULL);         
420                                                   
421         free_irq(aie_irq, pdev);                  
422         free_irq(pie_irq, pdev);                  
423         if (rtc1_base)                            
424                 iounmap(rtc1_base);               
425         if (rtc2_base)                            
426                 iounmap(rtc2_base);               
427                                                   
428         return 0;                                 
429 }                                                 
430                                                   
431 /* work with hotplug and coldplug */              
432 MODULE_ALIAS("platform:RTC");                     
433                                                   
434 static struct platform_driver rtc_platform_dri    
435         .probe          = rtc_probe,              
436         .remove         = __devexit_p(rtc_remo    
437         .driver         = {                       
438                 .name   = rtc_name,               
439                 .owner  = THIS_MODULE,            
440         },                                        
441 };                                                
442                                                   
443 static int __init vr41xx_rtc_init(void)           
444 {                                                 
445         return platform_driver_register(&rtc_p    
446 }                                                 
447                                                   
448 static void __exit vr41xx_rtc_exit(void)          
449 {                                                 
450         platform_driver_unregister(&rtc_platfo    
451 }                                                 
452                                                   
453 module_init(vr41xx_rtc_init);                     
454 module_exit(vr41xx_rtc_exit);                     
455                                                   
  This page was automatically generated by the LXR engine.