From: Stephen Hemminger The /proc/driver/rtc interface didn't have any module owner hook. The simplest fix is to just convert this to the single version of seq_file. Also, fix initialization of rtc_dev to use C99 form. Signed-off-by: Stephen Hemminger Signed-off-by: Andrew Morton --- 25-akpm/drivers/char/rtc.c | 108 ++++++++++++++++++++++----------------------- 1 files changed, 55 insertions(+), 53 deletions(-) diff -puN drivers/char/rtc.c~convert-proc-driver-rtc-to-seq_file drivers/char/rtc.c --- 25/drivers/char/rtc.c~convert-proc-driver-rtc-to-seq_file Mon Feb 7 16:38:27 2005 +++ 25-akpm/drivers/char/rtc.c Mon Feb 7 16:38:27 2005 @@ -73,6 +73,7 @@ #include #include #include +#include #include #include #include @@ -151,8 +152,7 @@ static void set_rtc_irq_bit(unsigned cha static void mask_rtc_irq_bit(unsigned char bit); #endif -static int rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data); +static int rtc_proc_open(struct inode *inode, struct file *file); /* * Bits in rtc_status. (6 bits of room for future expansion) @@ -871,11 +871,18 @@ static struct file_operations rtc_fops = .fasync = rtc_fasync, }; -static struct miscdevice rtc_dev= -{ - RTC_MINOR, - "rtc", - &rtc_fops +static struct miscdevice rtc_dev = { + .minor = RTC_MINOR, + .name = "rtc", + .fops = &rtc_fops, +}; + +static struct file_operations rtc_proc_fops = { + .owner = THIS_MODULE, + .open = rtc_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, }; #if defined(RTC_IRQ) && !defined(__sparc__) @@ -884,6 +891,7 @@ static irqreturn_t (*rtc_int_handler_ptr static int __init rtc_init(void) { + struct proc_dir_entry *ent; #if defined(__alpha__) || defined(__mips__) unsigned int year, ctrl; unsigned long uip_watchdog; @@ -974,7 +982,9 @@ no_irq: release_region(RTC_PORT(0), RTC_IO_EXTENT); return -ENODEV; } - if (!create_proc_read_entry ("driver/rtc", 0, NULL, rtc_read_proc, NULL)) { + + ent = create_proc_entry("driver/rtc", 0, NULL); + if (!ent) { #ifdef RTC_IRQ free_irq(RTC_IRQ, NULL); #endif @@ -982,6 +992,7 @@ no_irq: misc_deregister(&rtc_dev); return -ENOMEM; } + ent->proc_fops = &rtc_proc_fops; #if defined(__alpha__) || defined(__mips__) rtc_freq = HZ; @@ -1119,11 +1130,10 @@ static void rtc_dropped_irq(unsigned lon * Info exported via "/proc/driver/rtc". */ -static int rtc_proc_output (char *buf) +static int rtc_proc_show(struct seq_file *seq, void *v) { #define YN(bit) ((ctrl & bit) ? "yes" : "no") #define NY(bit) ((ctrl & bit) ? "no" : "yes") - char *p; struct rtc_time tm; unsigned char batt, ctrl; unsigned long freq; @@ -1134,7 +1144,6 @@ static int rtc_proc_output (char *buf) freq = rtc_freq; spin_unlock_irq(&rtc_lock); - p = buf; rtc_get_rtc_time(&tm); @@ -1142,12 +1151,12 @@ static int rtc_proc_output (char *buf) * There is no way to tell if the luser has the RTC set for local * time or for Universal Standard Time (GMT). Probably local though. */ - p += sprintf(p, - "rtc_time\t: %02d:%02d:%02d\n" - "rtc_date\t: %04d-%02d-%02d\n" - "rtc_epoch\t: %04lu\n", - tm.tm_hour, tm.tm_min, tm.tm_sec, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch); + seq_printf(seq, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n" + "rtc_epoch\t: %04lu\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch); get_rtc_alm_time(&tm); @@ -1156,57 +1165,50 @@ static int rtc_proc_output (char *buf) * match any value for that particular field. Values that are * greater than a valid time, but less than 0xc0 shouldn't appear. */ - p += sprintf(p, "alarm\t\t: "); + seq_puts(seq, "alarm\t\t: "); if (tm.tm_hour <= 24) - p += sprintf(p, "%02d:", tm.tm_hour); + seq_printf(seq, "%02d:", tm.tm_hour); else - p += sprintf(p, "**:"); + seq_puts(seq, "**:"); if (tm.tm_min <= 59) - p += sprintf(p, "%02d:", tm.tm_min); + seq_printf(seq, "%02d:", tm.tm_min); else - p += sprintf(p, "**:"); + seq_puts(seq, "**:"); if (tm.tm_sec <= 59) - p += sprintf(p, "%02d\n", tm.tm_sec); + seq_printf(seq, "%02d\n", tm.tm_sec); else - p += sprintf(p, "**\n"); + seq_puts(seq, "**\n"); - p += sprintf(p, - "DST_enable\t: %s\n" - "BCD\t\t: %s\n" - "24hr\t\t: %s\n" - "square_wave\t: %s\n" - "alarm_IRQ\t: %s\n" - "update_IRQ\t: %s\n" - "periodic_IRQ\t: %s\n" - "periodic_freq\t: %ld\n" - "batt_status\t: %s\n", - YN(RTC_DST_EN), - NY(RTC_DM_BINARY), - YN(RTC_24H), - YN(RTC_SQWE), - YN(RTC_AIE), - YN(RTC_UIE), - YN(RTC_PIE), - freq, - batt ? "okay" : "dead"); + seq_printf(seq, + "DST_enable\t: %s\n" + "BCD\t\t: %s\n" + "24hr\t\t: %s\n" + "square_wave\t: %s\n" + "alarm_IRQ\t: %s\n" + "update_IRQ\t: %s\n" + "periodic_IRQ\t: %s\n" + "periodic_freq\t: %ld\n" + "batt_status\t: %s\n", + YN(RTC_DST_EN), + NY(RTC_DM_BINARY), + YN(RTC_24H), + YN(RTC_SQWE), + YN(RTC_AIE), + YN(RTC_UIE), + YN(RTC_PIE), + freq, + batt ? "okay" : "dead"); - return p - buf; + return 0; #undef YN #undef NY } -static int rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int rtc_proc_open(struct inode *inode, struct file *file) { - int len = rtc_proc_output (page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - return len; + return single_open(file, rtc_proc_show, NULL); } void rtc_get_rtc_time(struct rtc_time *rtc_tm) _