diff options
| -rw-r--r-- | drivers/rtc/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/rtc/Makefile | 3 | ||||
| -rw-r--r-- | drivers/rtc/class.c | 8 | ||||
| -rw-r--r-- | drivers/rtc/rtc-core.h | 15 | ||||
| -rw-r--r-- | drivers/rtc/rtc-dev.c | 106 | ||||
| -rw-r--r-- | include/linux/rtc.h | 1 | 
6 files changed, 46 insertions, 89 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 1b853c4ff86..48eca80bbfc 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -71,7 +71,7 @@ config RTC_INTF_PROC  	  will be called rtc-proc.  config RTC_INTF_DEV -	tristate "dev" +	boolean "dev"  	depends on RTC_CLASS  	default RTC_CLASS  	help diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index f9a3e0130f4..4820dcc6a8f 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -11,9 +11,10 @@ obj-$(CONFIG_RTC_HCTOSYS)	+= hctosys.o  obj-$(CONFIG_RTC_CLASS)		+= rtc-core.o  rtc-core-y			:= class.o interface.o +rtc-core-$(CONFIG_RTC_INTF_DEV)	+= rtc-dev.o +  obj-$(CONFIG_RTC_INTF_SYSFS)	+= rtc-sysfs.o  obj-$(CONFIG_RTC_INTF_PROC)	+= rtc-proc.o -obj-$(CONFIG_RTC_INTF_DEV)	+= rtc-dev.o  obj-$(CONFIG_RTC_DRV_CMOS)	+= rtc-cmos.o  obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 04aaa634723..786406c2cf7 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -16,6 +16,9 @@  #include <linux/kdev_t.h>  #include <linux/idr.h> +#include "rtc-core.h" + +  static DEFINE_IDR(rtc_idr);  static DEFINE_MUTEX(idr_lock);  struct class *rtc_class; @@ -85,6 +88,8 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,  	if (err)  		goto exit_kfree; +	rtc_dev_add_device(rtc); +  	dev_info(dev, "rtc core: registered %s as %s\n",  			rtc->name, rtc->class_dev.class_id); @@ -118,6 +123,7 @@ void rtc_device_unregister(struct rtc_device *rtc)  		/* remove innards of this RTC, then disable it, before  		 * letting any rtc_class_open() users access it again  		 */ +		rtc_dev_del_device(rtc);  		class_device_unregister(&rtc->class_dev);  		rtc->ops = NULL;  		mutex_unlock(&rtc->ops_lock); @@ -140,11 +146,13 @@ static int __init rtc_init(void)  		printk(KERN_ERR "%s: couldn't create class\n", __FILE__);  		return PTR_ERR(rtc_class);  	} +	rtc_dev_init();  	return 0;  }  static void __exit rtc_exit(void)  { +	rtc_dev_exit();  	class_destroy(rtc_class);  } diff --git a/drivers/rtc/rtc-core.h b/drivers/rtc/rtc-core.h new file mode 100644 index 00000000000..c3c495ed186 --- /dev/null +++ b/drivers/rtc/rtc-core.h @@ -0,0 +1,15 @@ +#ifdef CONFIG_RTC_INTF_DEV + +extern void __init rtc_dev_init(void); +extern void __exit rtc_dev_exit(void); +extern void rtc_dev_add_device(struct rtc_device *rtc); +extern void rtc_dev_del_device(struct rtc_device *rtc); + +#else + +#define rtc_dev_init()		do{}while(0) +#define rtc_dev_exit()		do{}while(0) +#define rtc_dev_add_device(r)	do{}while(0) +#define rtc_dev_del_device(r)	do{}while(0) + +#endif diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 137330b8636..3fa6138523b 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -13,8 +13,8 @@  #include <linux/module.h>  #include <linux/rtc.h> +#include "rtc-core.h" -static struct class *rtc_dev_class;  static dev_t rtc_devt;  #define RTC_DEV_MAX 16 /* 16 RTCs should be enough for everyone... */ @@ -397,17 +397,18 @@ static const struct file_operations rtc_dev_fops = {  /* insertion/removal hooks */ -static int rtc_dev_add_device(struct class_device *class_dev, -				struct class_interface *class_intf) +void rtc_dev_add_device(struct rtc_device *rtc)  { -	int err = 0; -	struct rtc_device *rtc = to_rtc_device(class_dev); +	if (!rtc_devt) +		return;  	if (rtc->id >= RTC_DEV_MAX) { -		dev_err(class_dev->dev, "too many RTCs\n"); -		return -EINVAL; +		pr_debug("%s: too many RTC devices\n", rtc->name); +		return;  	} +	rtc->class_dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id); +  	mutex_init(&rtc->char_lock);  	spin_lock_init(&rtc->irq_lock);  	init_waitqueue_head(&rtc->irq_queue); @@ -419,99 +420,32 @@ static int rtc_dev_add_device(struct class_device *class_dev,  	cdev_init(&rtc->char_dev, &rtc_dev_fops);  	rtc->char_dev.owner = rtc->owner; -	if (cdev_add(&rtc->char_dev, MKDEV(MAJOR(rtc_devt), rtc->id), 1)) { -		dev_err(class_dev->dev, -			"failed to add char device %d:%d\n", +	if (cdev_add(&rtc->char_dev, rtc->class_dev.devt, 1)) +		printk(KERN_WARNING "%s: failed to add char device %d:%d\n", +			rtc->name, MAJOR(rtc_devt), rtc->id); +	else +		pr_debug("%s: dev (%d:%d)\n", rtc->name,  			MAJOR(rtc_devt), rtc->id); -		return -ENODEV; -	} - -	rtc->rtc_dev = class_device_create(rtc_dev_class, NULL, -						MKDEV(MAJOR(rtc_devt), rtc->id), -						class_dev->dev, "rtc%d", rtc->id); -	if (IS_ERR(rtc->rtc_dev)) { -		dev_err(class_dev->dev, "cannot create rtc_dev device\n"); -		err = PTR_ERR(rtc->rtc_dev); -		goto err_cdev_del; -	} - -	dev_dbg(class_dev->dev, "rtc intf: dev (%d:%d)\n", -		MAJOR(rtc->rtc_dev->devt), -		MINOR(rtc->rtc_dev->devt)); - -	return 0; - -err_cdev_del: - -	cdev_del(&rtc->char_dev); -	return err;  } -static void rtc_dev_remove_device(struct class_device *class_dev, -					struct class_interface *class_intf) +void rtc_dev_del_device(struct rtc_device *rtc)  { -	struct rtc_device *rtc = to_rtc_device(class_dev); - -	if (rtc->rtc_dev) { -		dev_dbg(class_dev->dev, "removing char %d:%d\n", -			MAJOR(rtc->rtc_dev->devt), -			MINOR(rtc->rtc_dev->devt)); - -		class_device_unregister(rtc->rtc_dev); +	if (rtc->class_dev.devt)  		cdev_del(&rtc->char_dev); -	}  } -/* interface registration */ - -static struct class_interface rtc_dev_interface = { -	.add = &rtc_dev_add_device, -	.remove = &rtc_dev_remove_device, -}; - -static int __init rtc_dev_init(void) +void __init rtc_dev_init(void)  {  	int err; -	rtc_dev_class = class_create(THIS_MODULE, "rtc-dev"); -	if (IS_ERR(rtc_dev_class)) -		return PTR_ERR(rtc_dev_class); -  	err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc"); -	if (err < 0) { +	if (err < 0)  		printk(KERN_ERR "%s: failed to allocate char dev region\n",  			__FILE__); -		goto err_destroy_class; -	} - -	err = rtc_interface_register(&rtc_dev_interface); -	if (err < 0) { -		printk(KERN_ERR "%s: failed to register the interface\n", -			__FILE__); -		goto err_unregister_chrdev; -	} - -	return 0; - -err_unregister_chrdev: -	unregister_chrdev_region(rtc_devt, RTC_DEV_MAX); - -err_destroy_class: -	class_destroy(rtc_dev_class); - -	return err;  } -static void __exit rtc_dev_exit(void) +void __exit rtc_dev_exit(void)  { -	class_interface_unregister(&rtc_dev_interface); -	class_destroy(rtc_dev_class); -	unregister_chrdev_region(rtc_devt, RTC_DEV_MAX); +	if (rtc_devt) +		unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);  } - -subsys_initcall(rtc_dev_init); -module_exit(rtc_dev_exit); - -MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); -MODULE_DESCRIPTION("RTC class dev interface"); -MODULE_LICENSE("GPL"); diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 5e22d4510d1..f662ae1aa62 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -145,7 +145,6 @@ struct rtc_device  	const struct rtc_class_ops *ops;  	struct mutex ops_lock; -	struct class_device *rtc_dev;  	struct cdev char_dev;  	struct mutex char_lock;  |