2006-03-27 13:16:40 +04:00
/*
* RTC subsystem , proc interface
*
* Copyright ( C ) 2005 - 06 Tower Technologies
* Author : Alessandro Zummo < a . zummo @ towertech . it >
*
* based on arch / arm / common / rtctime . c
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/module.h>
# include <linux/rtc.h>
# include <linux/proc_fs.h>
# include <linux/seq_file.h>
2007-05-08 11:33:30 +04:00
# include "rtc-core.h"
2012-10-05 04:13:45 +04:00
# define NAME_SIZE 10
# if defined(CONFIG_RTC_HCTOSYS_DEVICE)
static bool is_rtc_hctosys ( struct rtc_device * rtc )
{
int size ;
char name [ NAME_SIZE ] ;
size = scnprintf ( name , NAME_SIZE , " rtc%d " , rtc - > id ) ;
if ( size > NAME_SIZE )
return false ;
return ! strncmp ( name , CONFIG_RTC_HCTOSYS_DEVICE , NAME_SIZE ) ;
}
# else
static bool is_rtc_hctosys ( struct rtc_device * rtc )
{
return ( rtc - > id = = 0 ) ;
}
# endif
2007-05-08 11:33:30 +04:00
2006-03-27 13:16:40 +04:00
static int rtc_proc_show ( struct seq_file * seq , void * offset )
{
int err ;
2007-05-08 11:33:30 +04:00
struct rtc_device * rtc = seq - > private ;
const struct rtc_class_ops * ops = rtc - > ops ;
2006-03-27 13:16:40 +04:00
struct rtc_wkalrm alrm ;
struct rtc_time tm ;
2007-05-08 11:33:30 +04:00
err = rtc_read_time ( rtc , & tm ) ;
2006-03-27 13:16:40 +04:00
if ( err = = 0 ) {
seq_printf ( seq ,
" rtc_time \t : %02d:%02d:%02d \n "
" rtc_date \t : %04d-%02d-%02d \n " ,
tm . tm_hour , tm . tm_min , tm . tm_sec ,
tm . tm_year + 1900 , tm . tm_mon + 1 , tm . tm_mday ) ;
}
2007-05-08 11:33:30 +04:00
err = rtc_read_alarm ( rtc , & alrm ) ;
2006-03-27 13:16:40 +04:00
if ( err = = 0 ) {
seq_printf ( seq , " alrm_time \t : " ) ;
if ( ( unsigned int ) alrm . time . tm_hour < = 24 )
seq_printf ( seq , " %02d: " , alrm . time . tm_hour ) ;
else
seq_printf ( seq , " **: " ) ;
if ( ( unsigned int ) alrm . time . tm_min < = 59 )
seq_printf ( seq , " %02d: " , alrm . time . tm_min ) ;
else
seq_printf ( seq , " **: " ) ;
if ( ( unsigned int ) alrm . time . tm_sec < = 59 )
seq_printf ( seq , " %02d \n " , alrm . time . tm_sec ) ;
else
seq_printf ( seq , " ** \n " ) ;
seq_printf ( seq , " alrm_date \t : " ) ;
if ( ( unsigned int ) alrm . time . tm_year < = 200 )
seq_printf ( seq , " %04d- " , alrm . time . tm_year + 1900 ) ;
else
seq_printf ( seq , " ****- " ) ;
if ( ( unsigned int ) alrm . time . tm_mon < = 11 )
seq_printf ( seq , " %02d- " , alrm . time . tm_mon + 1 ) ;
else
seq_printf ( seq , " **- " ) ;
2006-10-01 10:28:16 +04:00
if ( alrm . time . tm_mday & & ( unsigned int ) alrm . time . tm_mday < = 31 )
2006-03-27 13:16:40 +04:00
seq_printf ( seq , " %02d \n " , alrm . time . tm_mday ) ;
else
seq_printf ( seq , " ** \n " ) ;
2006-12-13 11:35:08 +03:00
seq_printf ( seq , " alarm_IRQ \t : %s \n " ,
2006-03-27 13:16:40 +04:00
alrm . enabled ? " yes " : " no " ) ;
seq_printf ( seq , " alrm_pending \t : %s \n " ,
alrm . pending ? " yes " : " no " ) ;
2011-02-11 16:50:24 +03:00
seq_printf ( seq , " update IRQ enabled \t : %s \n " ,
( rtc - > uie_rtctimer . enabled ) ? " yes " : " no " ) ;
seq_printf ( seq , " periodic IRQ enabled \t : %s \n " ,
( rtc - > pie_enabled ) ? " yes " : " no " ) ;
seq_printf ( seq , " periodic IRQ frequency \t : %d \n " ,
rtc - > irq_freq ) ;
seq_printf ( seq , " max user IRQ frequency \t : %d \n " ,
rtc - > max_user_freq ) ;
2006-03-27 13:16:40 +04:00
}
2006-04-11 09:54:43 +04:00
seq_printf ( seq , " 24hr \t \t : yes \n " ) ;
2006-03-27 13:16:40 +04:00
if ( ops - > proc )
2007-05-08 11:33:40 +04:00
ops - > proc ( rtc - > dev . parent , seq ) ;
2006-03-27 13:16:40 +04:00
return 0 ;
}
static int rtc_proc_open ( struct inode * inode , struct file * file )
{
2011-02-11 02:01:25 +03:00
int ret ;
2013-04-01 02:16:14 +04:00
struct rtc_device * rtc = PDE_DATA ( inode ) ;
2006-03-27 13:16:40 +04:00
if ( ! try_module_get ( THIS_MODULE ) )
return - ENODEV ;
2011-02-11 02:01:25 +03:00
ret = single_open ( file , rtc_proc_show , rtc ) ;
if ( ret )
module_put ( THIS_MODULE ) ;
return ret ;
2006-03-27 13:16:40 +04:00
}
static int rtc_proc_release ( struct inode * inode , struct file * file )
{
int res = single_release ( inode , file ) ;
module_put ( THIS_MODULE ) ;
return res ;
}
2007-02-12 11:55:34 +03:00
static const struct file_operations rtc_proc_fops = {
2006-03-27 13:16:40 +04:00
. open = rtc_proc_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = rtc_proc_release ,
} ;
2007-05-08 11:33:38 +04:00
void rtc_proc_add_device ( struct rtc_device * rtc )
2006-03-27 13:16:40 +04:00
{
2012-10-05 04:13:45 +04:00
if ( is_rtc_hctosys ( rtc ) )
2009-03-25 22:48:06 +03:00
proc_create_data ( " driver/rtc " , 0 , NULL , & rtc_proc_fops , rtc ) ;
2006-03-27 13:16:40 +04:00
}
2007-05-08 11:33:38 +04:00
void rtc_proc_del_device ( struct rtc_device * rtc )
2006-03-27 13:16:40 +04:00
{
2012-10-05 04:13:45 +04:00
if ( is_rtc_hctosys ( rtc ) )
2006-03-27 13:16:40 +04:00
remove_proc_entry ( " driver/rtc " , NULL ) ;
}