Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] RTC subsystem: class

Add the basic RTC subsystem infrastructure to the kernel.

rtc/class.c - registration facilities for RTC drivers
rtc/interface.c - kernel/rtc interface functions
rtc/hctosys.c - snippet of code that copies hw clock to sw clock
at bootup, if configured to do so.

Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Alessandro Zummo and committed by
Linus Torvalds
0c86edc0 4079c39a

+632 -4
+3 -2
CREDITS
··· 3741 3741 D: Miscellaneous kernel fixes 3742 3742 3743 3743 N: Alessandro Zummo 3744 - E: azummo@ita.flashnet.it 3745 - W: http://freepage.logicom.it/azummo/ 3744 + E: a.zummo@towertech.it 3746 3745 D: CMI8330 support is sb_card.c 3747 3746 D: ISAPnP fixes in sb_card.c 3747 + D: ZyXEL omni.net lcd plus driver 3748 + D: RTC subsystem 3748 3749 S: Italy 3749 3750 3750 3751 N: Marc Zyngier
+6
MAINTAINERS
··· 2233 2233 L: linux-kernel@vger.kernel.org 2234 2234 S: Maintained 2235 2235 2236 + REAL TIME CLOCK (RTC) SUBSYSTEM 2237 + P: Alessandro Zummo 2238 + M: a.zummo@towertech.it 2239 + L: linux-kernel@vger.kernel.org 2240 + S: Maintained 2241 + 2236 2242 REISERFS FILE SYSTEM 2237 2243 P: Hans Reiser 2238 2244 M: reiserfs-dev@namesys.com
+41 -1
drivers/rtc/Kconfig
··· 1 - # 1 + \# 2 2 # RTC class/drivers configuration 3 3 # 4 4 5 + menu "Real Time Clock" 6 + 5 7 config RTC_LIB 6 8 tristate 9 + 10 + config RTC_CLASS 11 + tristate "RTC class" 12 + depends on EXPERIMENTAL 13 + default n 14 + select RTC_LIB 15 + help 16 + Generic RTC class support. If you say yes here, you will 17 + be allowed to plug one or more RTCs to your system. You will 18 + probably want to enable one of more of the interfaces below. 19 + 20 + This driver can also be built as a module. If so, the module 21 + will be called rtc-class. 22 + 23 + config RTC_HCTOSYS 24 + bool "Set system time from RTC on startup" 25 + depends on RTC_CLASS = y 26 + default y 27 + help 28 + If you say yes here, the system time will be set using 29 + the value read from the specified RTC device. This is useful 30 + in order to avoid unnecessary fschk runs. 31 + 32 + config RTC_HCTOSYS_DEVICE 33 + string "The RTC to read the time from" 34 + depends on RTC_HCTOSYS = y 35 + default "rtc0" 36 + help 37 + The RTC device that will be used as the source for 38 + the system time, usually rtc0. 39 + 40 + comment "RTC interfaces" 41 + depends on RTC_CLASS 42 + 43 + comment "RTC drivers" 44 + depends on RTC_CLASS 45 + 46 + endmenu
+4 -1
drivers/rtc/Makefile
··· 2 2 # Makefile for RTC class/drivers. 3 3 # 4 4 5 - obj-$(CONFIG_RTC_LIB) += rtc-lib.o 5 + obj-$(CONFIG_RTC_LIB) += rtc-lib.o 6 + obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o 7 + obj-$(CONFIG_RTC_CLASS) += rtc-core.o 8 + rtc-core-y := class.o interface.o
+145
drivers/rtc/class.c
··· 1 + /* 2 + * RTC subsystem, base class 3 + * 4 + * Copyright (C) 2005 Tower Technologies 5 + * Author: Alessandro Zummo <a.zummo@towertech.it> 6 + * 7 + * class skeleton from drivers/hwmon/hwmon.c 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License version 2 as 11 + * published by the Free Software Foundation. 12 + */ 13 + 14 + #include <linux/module.h> 15 + #include <linux/rtc.h> 16 + #include <linux/kdev_t.h> 17 + #include <linux/idr.h> 18 + 19 + static DEFINE_IDR(rtc_idr); 20 + static DEFINE_MUTEX(idr_lock); 21 + struct class *rtc_class; 22 + 23 + static void rtc_device_release(struct class_device *class_dev) 24 + { 25 + struct rtc_device *rtc = to_rtc_device(class_dev); 26 + mutex_lock(&idr_lock); 27 + idr_remove(&rtc_idr, rtc->id); 28 + mutex_unlock(&idr_lock); 29 + kfree(rtc); 30 + } 31 + 32 + /** 33 + * rtc_device_register - register w/ RTC class 34 + * @dev: the device to register 35 + * 36 + * rtc_device_unregister() must be called when the class device is no 37 + * longer needed. 38 + * 39 + * Returns the pointer to the new struct class device. 40 + */ 41 + struct rtc_device *rtc_device_register(const char *name, struct device *dev, 42 + struct rtc_class_ops *ops, 43 + struct module *owner) 44 + { 45 + struct rtc_device *rtc; 46 + int id, err; 47 + 48 + if (idr_pre_get(&rtc_idr, GFP_KERNEL) == 0) { 49 + err = -ENOMEM; 50 + goto exit; 51 + } 52 + 53 + 54 + mutex_lock(&idr_lock); 55 + err = idr_get_new(&rtc_idr, NULL, &id); 56 + mutex_unlock(&idr_lock); 57 + 58 + if (err < 0) 59 + goto exit; 60 + 61 + id = id & MAX_ID_MASK; 62 + 63 + rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL); 64 + if (rtc == NULL) { 65 + err = -ENOMEM; 66 + goto exit_idr; 67 + } 68 + 69 + rtc->id = id; 70 + rtc->ops = ops; 71 + rtc->owner = owner; 72 + rtc->class_dev.dev = dev; 73 + rtc->class_dev.class = rtc_class; 74 + rtc->class_dev.release = rtc_device_release; 75 + 76 + mutex_init(&rtc->ops_lock); 77 + spin_lock_init(&rtc->irq_lock); 78 + spin_lock_init(&rtc->irq_task_lock); 79 + 80 + strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); 81 + snprintf(rtc->class_dev.class_id, BUS_ID_SIZE, "rtc%d", id); 82 + 83 + err = class_device_register(&rtc->class_dev); 84 + if (err) 85 + goto exit_kfree; 86 + 87 + dev_info(dev, "rtc core: registered %s as %s\n", 88 + rtc->name, rtc->class_dev.class_id); 89 + 90 + return rtc; 91 + 92 + exit_kfree: 93 + kfree(rtc); 94 + 95 + exit_idr: 96 + idr_remove(&rtc_idr, id); 97 + 98 + exit: 99 + return ERR_PTR(err); 100 + } 101 + EXPORT_SYMBOL_GPL(rtc_device_register); 102 + 103 + 104 + /** 105 + * rtc_device_unregister - removes the previously registered RTC class device 106 + * 107 + * @rtc: the RTC class device to destroy 108 + */ 109 + void rtc_device_unregister(struct rtc_device *rtc) 110 + { 111 + mutex_lock(&rtc->ops_lock); 112 + rtc->ops = NULL; 113 + mutex_unlock(&rtc->ops_lock); 114 + class_device_unregister(&rtc->class_dev); 115 + } 116 + EXPORT_SYMBOL_GPL(rtc_device_unregister); 117 + 118 + int rtc_interface_register(struct class_interface *intf) 119 + { 120 + intf->class = rtc_class; 121 + return class_interface_register(intf); 122 + } 123 + EXPORT_SYMBOL_GPL(rtc_interface_register); 124 + 125 + static int __init rtc_init(void) 126 + { 127 + rtc_class = class_create(THIS_MODULE, "rtc"); 128 + if (IS_ERR(rtc_class)) { 129 + printk(KERN_ERR "%s: couldn't create class\n", __FILE__); 130 + return PTR_ERR(rtc_class); 131 + } 132 + return 0; 133 + } 134 + 135 + static void __exit rtc_exit(void) 136 + { 137 + class_destroy(rtc_class); 138 + } 139 + 140 + module_init(rtc_init); 141 + module_exit(rtc_exit); 142 + 143 + MODULE_AUTHOR("Alessandro Zummo <a.zummo@towerteh.it>"); 144 + MODULE_DESCRIPTION("RTC class support"); 145 + MODULE_LICENSE("GPL");
+69
drivers/rtc/hctosys.c
··· 1 + /* 2 + * RTC subsystem, initialize system time on startup 3 + * 4 + * Copyright (C) 2005 Tower Technologies 5 + * Author: Alessandro Zummo <a.zummo@towertech.it> 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/rtc.h> 13 + 14 + /* IMPORTANT: the RTC only stores whole seconds. It is arbitrary 15 + * whether it stores the most close value or the value with partial 16 + * seconds truncated. However, it is important that we use it to store 17 + * the truncated value. This is because otherwise it is necessary, 18 + * in an rtc sync function, to read both xtime.tv_sec and 19 + * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read 20 + * of >32bits is not possible. So storing the most close value would 21 + * slow down the sync API. So here we have the truncated value and 22 + * the best guess is to add 0.5s. 23 + */ 24 + 25 + static int __init rtc_hctosys(void) 26 + { 27 + int err; 28 + struct rtc_time tm; 29 + struct class_device *class_dev = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); 30 + 31 + if (class_dev == NULL) { 32 + printk("%s: unable to open rtc device (%s)\n", 33 + __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); 34 + return -ENODEV; 35 + } 36 + 37 + err = rtc_read_time(class_dev, &tm); 38 + if (err == 0) { 39 + err = rtc_valid_tm(&tm); 40 + if (err == 0) { 41 + struct timespec tv; 42 + 43 + tv.tv_nsec = NSEC_PER_SEC >> 1; 44 + 45 + rtc_tm_to_time(&tm, &tv.tv_sec); 46 + 47 + do_settimeofday(&tv); 48 + 49 + dev_info(class_dev->dev, 50 + "setting the system clock to " 51 + "%d-%02d-%02d %02d:%02d:%02d (%u)\n", 52 + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 53 + tm.tm_hour, tm.tm_min, tm.tm_sec, 54 + (unsigned int) tv.tv_sec); 55 + } 56 + else 57 + dev_err(class_dev->dev, 58 + "hctosys: invalid date/time\n"); 59 + } 60 + else 61 + dev_err(class_dev->dev, 62 + "hctosys: unable to read the hardware clock\n"); 63 + 64 + rtc_class_close(class_dev); 65 + 66 + return 0; 67 + } 68 + 69 + late_initcall(rtc_hctosys);
+277
drivers/rtc/interface.c
··· 1 + /* 2 + * RTC subsystem, interface functions 3 + * 4 + * Copyright (C) 2005 Tower Technologies 5 + * Author: Alessandro Zummo <a.zummo@towertech.it> 6 + * 7 + * based on arch/arm/common/rtctime.c 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License version 2 as 11 + * published by the Free Software Foundation. 12 + */ 13 + 14 + #include <linux/rtc.h> 15 + 16 + int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm) 17 + { 18 + int err; 19 + struct rtc_device *rtc = to_rtc_device(class_dev); 20 + 21 + err = mutex_lock_interruptible(&rtc->ops_lock); 22 + if (err) 23 + return -EBUSY; 24 + 25 + if (!rtc->ops) 26 + err = -ENODEV; 27 + else if (!rtc->ops->read_time) 28 + err = -EINVAL; 29 + else { 30 + memset(tm, 0, sizeof(struct rtc_time)); 31 + err = rtc->ops->read_time(class_dev->dev, tm); 32 + } 33 + 34 + mutex_unlock(&rtc->ops_lock); 35 + return err; 36 + } 37 + EXPORT_SYMBOL_GPL(rtc_read_time); 38 + 39 + int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm) 40 + { 41 + int err; 42 + struct rtc_device *rtc = to_rtc_device(class_dev); 43 + 44 + err = rtc_valid_tm(tm); 45 + if (err != 0) 46 + return err; 47 + 48 + err = mutex_lock_interruptible(&rtc->ops_lock); 49 + if (err) 50 + return -EBUSY; 51 + 52 + if (!rtc->ops) 53 + err = -ENODEV; 54 + else if (!rtc->ops->set_time) 55 + err = -EINVAL; 56 + else 57 + err = rtc->ops->set_time(class_dev->dev, tm); 58 + 59 + mutex_unlock(&rtc->ops_lock); 60 + return err; 61 + } 62 + EXPORT_SYMBOL_GPL(rtc_set_time); 63 + 64 + int rtc_set_mmss(struct class_device *class_dev, unsigned long secs) 65 + { 66 + int err; 67 + struct rtc_device *rtc = to_rtc_device(class_dev); 68 + 69 + err = mutex_lock_interruptible(&rtc->ops_lock); 70 + if (err) 71 + return -EBUSY; 72 + 73 + if (!rtc->ops) 74 + err = -ENODEV; 75 + else if (rtc->ops->set_mmss) 76 + err = rtc->ops->set_mmss(class_dev->dev, secs); 77 + else if (rtc->ops->read_time && rtc->ops->set_time) { 78 + struct rtc_time new, old; 79 + 80 + err = rtc->ops->read_time(class_dev->dev, &old); 81 + if (err == 0) { 82 + rtc_time_to_tm(secs, &new); 83 + 84 + /* 85 + * avoid writing when we're going to change the day of 86 + * the month. We will retry in the next minute. This 87 + * basically means that if the RTC must not drift 88 + * by more than 1 minute in 11 minutes. 89 + */ 90 + if (!((old.tm_hour == 23 && old.tm_min == 59) || 91 + (new.tm_hour == 23 && new.tm_min == 59))) 92 + err = rtc->ops->set_time(class_dev->dev, &new); 93 + } 94 + } 95 + else 96 + err = -EINVAL; 97 + 98 + mutex_unlock(&rtc->ops_lock); 99 + 100 + return err; 101 + } 102 + EXPORT_SYMBOL_GPL(rtc_set_mmss); 103 + 104 + int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) 105 + { 106 + int err; 107 + struct rtc_device *rtc = to_rtc_device(class_dev); 108 + 109 + err = mutex_lock_interruptible(&rtc->ops_lock); 110 + if (err) 111 + return -EBUSY; 112 + 113 + if (rtc->ops == NULL) 114 + err = -ENODEV; 115 + else if (!rtc->ops->read_alarm) 116 + err = -EINVAL; 117 + else { 118 + memset(alarm, 0, sizeof(struct rtc_wkalrm)); 119 + err = rtc->ops->read_alarm(class_dev->dev, alarm); 120 + } 121 + 122 + mutex_unlock(&rtc->ops_lock); 123 + return err; 124 + } 125 + EXPORT_SYMBOL_GPL(rtc_read_alarm); 126 + 127 + int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) 128 + { 129 + int err; 130 + struct rtc_device *rtc = to_rtc_device(class_dev); 131 + 132 + err = mutex_lock_interruptible(&rtc->ops_lock); 133 + if (err) 134 + return -EBUSY; 135 + 136 + if (!rtc->ops) 137 + err = -ENODEV; 138 + else if (!rtc->ops->set_alarm) 139 + err = -EINVAL; 140 + else 141 + err = rtc->ops->set_alarm(class_dev->dev, alarm); 142 + 143 + mutex_unlock(&rtc->ops_lock); 144 + return err; 145 + } 146 + EXPORT_SYMBOL_GPL(rtc_set_alarm); 147 + 148 + void rtc_update_irq(struct class_device *class_dev, 149 + unsigned long num, unsigned long events) 150 + { 151 + struct rtc_device *rtc = to_rtc_device(class_dev); 152 + 153 + spin_lock(&rtc->irq_lock); 154 + rtc->irq_data = (rtc->irq_data + (num << 8)) | events; 155 + spin_unlock(&rtc->irq_lock); 156 + 157 + spin_lock(&rtc->irq_task_lock); 158 + if (rtc->irq_task) 159 + rtc->irq_task->func(rtc->irq_task->private_data); 160 + spin_unlock(&rtc->irq_task_lock); 161 + 162 + wake_up_interruptible(&rtc->irq_queue); 163 + kill_fasync(&rtc->async_queue, SIGIO, POLL_IN); 164 + } 165 + EXPORT_SYMBOL_GPL(rtc_update_irq); 166 + 167 + struct class_device *rtc_class_open(char *name) 168 + { 169 + struct class_device *class_dev = NULL, 170 + *class_dev_tmp; 171 + 172 + down(&rtc_class->sem); 173 + list_for_each_entry(class_dev_tmp, &rtc_class->children, node) { 174 + if (strncmp(class_dev_tmp->class_id, name, BUS_ID_SIZE) == 0) { 175 + class_dev = class_dev_tmp; 176 + break; 177 + } 178 + } 179 + 180 + if (class_dev) { 181 + if (!try_module_get(to_rtc_device(class_dev)->owner)) 182 + class_dev = NULL; 183 + } 184 + up(&rtc_class->sem); 185 + 186 + return class_dev; 187 + } 188 + EXPORT_SYMBOL_GPL(rtc_class_open); 189 + 190 + void rtc_class_close(struct class_device *class_dev) 191 + { 192 + module_put(to_rtc_device(class_dev)->owner); 193 + } 194 + EXPORT_SYMBOL_GPL(rtc_class_close); 195 + 196 + int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task) 197 + { 198 + int retval = -EBUSY; 199 + struct rtc_device *rtc = to_rtc_device(class_dev); 200 + 201 + if (task == NULL || task->func == NULL) 202 + return -EINVAL; 203 + 204 + spin_lock(&rtc->irq_task_lock); 205 + if (rtc->irq_task == NULL) { 206 + rtc->irq_task = task; 207 + retval = 0; 208 + } 209 + spin_unlock(&rtc->irq_task_lock); 210 + 211 + return retval; 212 + } 213 + EXPORT_SYMBOL_GPL(rtc_irq_register); 214 + 215 + void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task) 216 + { 217 + struct rtc_device *rtc = to_rtc_device(class_dev); 218 + 219 + spin_lock(&rtc->irq_task_lock); 220 + if (rtc->irq_task == task) 221 + rtc->irq_task = NULL; 222 + spin_unlock(&rtc->irq_task_lock); 223 + } 224 + EXPORT_SYMBOL_GPL(rtc_irq_unregister); 225 + 226 + int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int enabled) 227 + { 228 + int err = 0; 229 + unsigned long flags; 230 + struct rtc_device *rtc = to_rtc_device(class_dev); 231 + 232 + spin_lock_irqsave(&rtc->irq_task_lock, flags); 233 + if (rtc->irq_task != task) 234 + err = -ENXIO; 235 + spin_unlock_irqrestore(&rtc->irq_task_lock, flags); 236 + 237 + if (err == 0) 238 + err = rtc->ops->irq_set_state(class_dev->dev, enabled); 239 + 240 + return err; 241 + } 242 + EXPORT_SYMBOL_GPL(rtc_irq_set_state); 243 + 244 + int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int freq) 245 + { 246 + int err = 0, tmp = 0; 247 + unsigned long flags; 248 + struct rtc_device *rtc = to_rtc_device(class_dev); 249 + 250 + /* allowed range is 2-8192 */ 251 + if (freq < 2 || freq > 8192) 252 + return -EINVAL; 253 + /* 254 + FIXME: this does not belong here, will move where appropriate 255 + at a later stage. It cannot hurt right now, trust me :) 256 + if ((freq > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE))) 257 + return -EACCES; 258 + */ 259 + /* check if freq is a power of 2 */ 260 + while (freq > (1 << tmp)) 261 + tmp++; 262 + 263 + if (freq != (1 << tmp)) 264 + return -EINVAL; 265 + 266 + spin_lock_irqsave(&rtc->irq_task_lock, flags); 267 + if (rtc->irq_task != task) 268 + err = -ENXIO; 269 + spin_unlock_irqrestore(&rtc->irq_task_lock, flags); 270 + 271 + if (err == 0) { 272 + err = rtc->ops->irq_set_freq(class_dev->dev, freq); 273 + if (err == 0) 274 + rtc->irq_freq = freq; 275 + } 276 + return err; 277 + }
+87
include/linux/rtc.h
··· 91 91 #define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */ 92 92 #define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */ 93 93 94 + /* interrupt flags */ 95 + #define RTC_IRQF 0x80 /* any of the following is active */ 96 + #define RTC_PF 0x40 97 + #define RTC_AF 0x20 98 + #define RTC_UF 0x10 99 + 94 100 #ifdef __KERNEL__ 95 101 96 102 #include <linux/interrupt.h> ··· 105 99 extern int rtc_valid_tm(struct rtc_time *tm); 106 100 extern int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time); 107 101 extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm); 102 + 103 + #include <linux/device.h> 104 + #include <linux/seq_file.h> 105 + #include <linux/cdev.h> 106 + #include <linux/poll.h> 107 + #include <linux/mutex.h> 108 + 109 + extern struct class *rtc_class; 110 + 111 + struct rtc_class_ops { 112 + int (*open)(struct device *); 113 + void (*release)(struct device *); 114 + int (*ioctl)(struct device *, unsigned int, unsigned long); 115 + int (*read_time)(struct device *, struct rtc_time *); 116 + int (*set_time)(struct device *, struct rtc_time *); 117 + int (*read_alarm)(struct device *, struct rtc_wkalrm *); 118 + int (*set_alarm)(struct device *, struct rtc_wkalrm *); 119 + int (*proc)(struct device *, struct seq_file *); 120 + int (*set_mmss)(struct device *, unsigned long secs); 121 + int (*irq_set_state)(struct device *, int enabled); 122 + int (*irq_set_freq)(struct device *, int freq); 123 + int (*read_callback)(struct device *, int data); 124 + }; 125 + 126 + #define RTC_DEVICE_NAME_SIZE 20 127 + struct rtc_task; 128 + 129 + struct rtc_device 130 + { 131 + struct class_device class_dev; 132 + struct module *owner; 133 + 134 + int id; 135 + char name[RTC_DEVICE_NAME_SIZE]; 136 + 137 + struct rtc_class_ops *ops; 138 + struct mutex ops_lock; 139 + 140 + struct class_device *rtc_dev; 141 + struct cdev char_dev; 142 + struct mutex char_lock; 143 + 144 + unsigned long irq_data; 145 + spinlock_t irq_lock; 146 + wait_queue_head_t irq_queue; 147 + struct fasync_struct *async_queue; 148 + 149 + struct rtc_task *irq_task; 150 + spinlock_t irq_task_lock; 151 + int irq_freq; 152 + }; 153 + #define to_rtc_device(d) container_of(d, struct rtc_device, class_dev) 154 + 155 + extern struct rtc_device *rtc_device_register(const char *name, 156 + struct device *dev, 157 + struct rtc_class_ops *ops, 158 + struct module *owner); 159 + extern void rtc_device_unregister(struct rtc_device *rdev); 160 + extern int rtc_interface_register(struct class_interface *intf); 161 + 162 + extern int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm); 163 + extern int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm); 164 + extern int rtc_set_mmss(struct class_device *class_dev, unsigned long secs); 165 + extern int rtc_read_alarm(struct class_device *class_dev, 166 + struct rtc_wkalrm *alrm); 167 + extern int rtc_set_alarm(struct class_device *class_dev, 168 + struct rtc_wkalrm *alrm); 169 + extern void rtc_update_irq(struct class_device *class_dev, 170 + unsigned long num, unsigned long events); 171 + 172 + extern struct class_device *rtc_class_open(char *name); 173 + extern void rtc_class_close(struct class_device *class_dev); 174 + 175 + extern int rtc_irq_register(struct class_device *class_dev, 176 + struct rtc_task *task); 177 + extern void rtc_irq_unregister(struct class_device *class_dev, 178 + struct rtc_task *task); 179 + extern int rtc_irq_set_state(struct class_device *class_dev, 180 + struct rtc_task *task, int enabled); 181 + extern int rtc_irq_set_freq(struct class_device *class_dev, 182 + struct rtc_task *task, int freq); 108 183 109 184 typedef struct rtc_task { 110 185 void (*func)(void *private_data);