• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/rtc/
1/*
2 * An RTC test device/driver
3 * Copyright (C) 2005 Tower Technologies
4 * Author: Alessandro Zummo <a.zummo@towertech.it>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/err.h>
13#include <linux/rtc.h>
14#include <linux/platform_device.h>
15
16static struct platform_device *test0 = NULL, *test1 = NULL;
17
18static int test_rtc_read_alarm(struct device *dev,
19	struct rtc_wkalrm *alrm)
20{
21	return 0;
22}
23
24static int test_rtc_set_alarm(struct device *dev,
25	struct rtc_wkalrm *alrm)
26{
27	return 0;
28}
29
30static int test_rtc_read_time(struct device *dev,
31	struct rtc_time *tm)
32{
33	rtc_time_to_tm(get_seconds(), tm);
34	return 0;
35}
36
37static int test_rtc_set_mmss(struct device *dev, unsigned long secs)
38{
39	dev_info(dev, "%s, secs = %lu\n", __func__, secs);
40	return 0;
41}
42
43static int test_rtc_proc(struct device *dev, struct seq_file *seq)
44{
45	struct platform_device *plat_dev = to_platform_device(dev);
46
47	seq_printf(seq, "test\t\t: yes\n");
48	seq_printf(seq, "id\t\t: %d\n", plat_dev->id);
49
50	return 0;
51}
52
53static int test_rtc_ioctl(struct device *dev, unsigned int cmd,
54	unsigned long arg)
55{
56	/* We do support interrupts, they're generated
57	 * using the sysfs interface.
58	 */
59	switch (cmd) {
60	case RTC_PIE_ON:
61	case RTC_PIE_OFF:
62	case RTC_UIE_ON:
63	case RTC_UIE_OFF:
64	case RTC_AIE_ON:
65	case RTC_AIE_OFF:
66		return 0;
67
68	default:
69		return -ENOIOCTLCMD;
70	}
71}
72
73static const struct rtc_class_ops test_rtc_ops = {
74	.proc = test_rtc_proc,
75	.read_time = test_rtc_read_time,
76	.read_alarm = test_rtc_read_alarm,
77	.set_alarm = test_rtc_set_alarm,
78	.set_mmss = test_rtc_set_mmss,
79	.ioctl = test_rtc_ioctl,
80};
81
82static ssize_t test_irq_show(struct device *dev,
83				struct device_attribute *attr, char *buf)
84{
85	return sprintf(buf, "%d\n", 42);
86}
87static ssize_t test_irq_store(struct device *dev,
88				struct device_attribute *attr,
89				const char *buf, size_t count)
90{
91	int retval;
92	struct platform_device *plat_dev = to_platform_device(dev);
93	struct rtc_device *rtc = platform_get_drvdata(plat_dev);
94
95	retval = count;
96	if (strncmp(buf, "tick", 4) == 0)
97		rtc_update_irq(rtc, 1, RTC_PF | RTC_IRQF);
98	else if (strncmp(buf, "alarm", 5) == 0)
99		rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF);
100	else if (strncmp(buf, "update", 6) == 0)
101		rtc_update_irq(rtc, 1, RTC_UF | RTC_IRQF);
102	else
103		retval = -EINVAL;
104
105	return retval;
106}
107static DEVICE_ATTR(irq, S_IRUGO | S_IWUSR, test_irq_show, test_irq_store);
108
109static int test_probe(struct platform_device *plat_dev)
110{
111	int err;
112	struct rtc_device *rtc = rtc_device_register("test", &plat_dev->dev,
113						&test_rtc_ops, THIS_MODULE);
114	if (IS_ERR(rtc)) {
115		err = PTR_ERR(rtc);
116		return err;
117	}
118
119	err = device_create_file(&plat_dev->dev, &dev_attr_irq);
120	if (err)
121		goto err;
122
123	platform_set_drvdata(plat_dev, rtc);
124
125	return 0;
126
127err:
128	rtc_device_unregister(rtc);
129	return err;
130}
131
132static int __devexit test_remove(struct platform_device *plat_dev)
133{
134	struct rtc_device *rtc = platform_get_drvdata(plat_dev);
135
136	rtc_device_unregister(rtc);
137	device_remove_file(&plat_dev->dev, &dev_attr_irq);
138
139	return 0;
140}
141
142static struct platform_driver test_driver = {
143	.probe	= test_probe,
144	.remove = __devexit_p(test_remove),
145	.driver = {
146		.name = "rtc-test",
147		.owner = THIS_MODULE,
148	},
149};
150
151static int __init test_init(void)
152{
153	int err;
154
155	if ((err = platform_driver_register(&test_driver)))
156		return err;
157
158	if ((test0 = platform_device_alloc("rtc-test", 0)) == NULL) {
159		err = -ENOMEM;
160		goto exit_driver_unregister;
161	}
162
163	if ((test1 = platform_device_alloc("rtc-test", 1)) == NULL) {
164		err = -ENOMEM;
165		goto exit_free_test0;
166	}
167
168	if ((err = platform_device_add(test0)))
169		goto exit_free_test1;
170
171	if ((err = platform_device_add(test1)))
172		goto exit_device_unregister;
173
174	return 0;
175
176exit_device_unregister:
177	platform_device_unregister(test0);
178
179exit_free_test1:
180	platform_device_put(test1);
181
182exit_free_test0:
183	platform_device_put(test0);
184
185exit_driver_unregister:
186	platform_driver_unregister(&test_driver);
187	return err;
188}
189
190static void __exit test_exit(void)
191{
192	platform_device_unregister(test0);
193	platform_device_unregister(test1);
194	platform_driver_unregister(&test_driver);
195}
196
197MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
198MODULE_DESCRIPTION("RTC test driver/device");
199MODULE_LICENSE("GPL");
200
201module_init(test_init);
202module_exit(test_exit);
203