blob: 796c45dee661ad0fc29fbe4c60514208bc3b216a [file] [log] [blame]
Alessandro Zummoa95579c2006-03-27 01:16:42 -08001/*
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
Alexandre Belloni5b257572018-05-31 23:09:56 +020016#define MAX_RTC_TEST 3
17
18struct platform_device *pdev[MAX_RTC_TEST];
Alessandro Zummoa95579c2006-03-27 01:16:42 -080019
20static int test_rtc_read_alarm(struct device *dev,
21 struct rtc_wkalrm *alrm)
22{
23 return 0;
24}
25
26static int test_rtc_set_alarm(struct device *dev,
27 struct rtc_wkalrm *alrm)
28{
29 return 0;
30}
31
32static int test_rtc_read_time(struct device *dev,
33 struct rtc_time *tm)
34{
Xunlei Pang4d644ab82015-04-01 20:34:28 -070035 rtc_time64_to_tm(ktime_get_real_seconds(), tm);
36 return 0;
37}
38
39static int test_rtc_set_mmss64(struct device *dev, time64_t secs)
40{
41 dev_info(dev, "%s, secs = %lld\n", __func__, (long long)secs);
Alessandro Zummoa95579c2006-03-27 01:16:42 -080042 return 0;
43}
44
John Stultz16380c12011-02-02 17:02:41 -080045static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
Alessandro Zummoa95579c2006-03-27 01:16:42 -080046{
John Stultz16380c12011-02-02 17:02:41 -080047 return 0;
Alessandro Zummoa95579c2006-03-27 01:16:42 -080048}
49
Alexandre Belloni78417682018-05-26 03:57:29 +020050static const struct rtc_class_ops test_rtc_ops = {
Alessandro Zummoa95579c2006-03-27 01:16:42 -080051 .read_time = test_rtc_read_time,
Alessandro Zummoa95579c2006-03-27 01:16:42 -080052 .read_alarm = test_rtc_read_alarm,
53 .set_alarm = test_rtc_set_alarm,
Alexandre Belloni78417682018-05-26 03:57:29 +020054 .set_mmss64 = test_rtc_set_mmss64,
John Stultz16380c12011-02-02 17:02:41 -080055 .alarm_irq_enable = test_rtc_alarm_irq_enable,
Alessandro Zummoa95579c2006-03-27 01:16:42 -080056};
57
58static ssize_t test_irq_show(struct device *dev,
59 struct device_attribute *attr, char *buf)
60{
61 return sprintf(buf, "%d\n", 42);
62}
63static ssize_t test_irq_store(struct device *dev,
64 struct device_attribute *attr,
65 const char *buf, size_t count)
66{
67 int retval;
Wolfram Sang85368bb2018-04-19 16:06:14 +020068 struct rtc_device *rtc = dev_get_drvdata(dev);
Alessandro Zummoa95579c2006-03-27 01:16:42 -080069
70 retval = count;
Marcelo Roberto Jimeneza4174932011-02-07 19:16:07 -020071 if (strncmp(buf, "tick", 4) == 0 && rtc->pie_enabled)
David Brownellab6a2d72007-05-08 00:33:30 -070072 rtc_update_irq(rtc, 1, RTC_PF | RTC_IRQF);
Marcelo Roberto Jimeneza4174932011-02-07 19:16:07 -020073 else if (strncmp(buf, "alarm", 5) == 0) {
74 struct rtc_wkalrm alrm;
75 int err = rtc_read_alarm(rtc, &alrm);
76
77 if (!err && alrm.enabled)
78 rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF);
79
80 } else if (strncmp(buf, "update", 6) == 0 && rtc->uie_rtctimer.enabled)
David Brownellab6a2d72007-05-08 00:33:30 -070081 rtc_update_irq(rtc, 1, RTC_UF | RTC_IRQF);
Alessandro Zummoa95579c2006-03-27 01:16:42 -080082 else
83 retval = -EINVAL;
84
85 return retval;
86}
87static DEVICE_ATTR(irq, S_IRUGO | S_IWUSR, test_irq_show, test_irq_store);
88
89static int test_probe(struct platform_device *plat_dev)
90{
91 int err;
Jingoo Handd8d8132013-04-29 16:19:52 -070092 struct rtc_device *rtc;
93
94 rtc = devm_rtc_device_register(&plat_dev->dev, "test",
95 &test_rtc_ops, THIS_MODULE);
Alessandro Zummoa95579c2006-03-27 01:16:42 -080096 if (IS_ERR(rtc)) {
Alessandro Zummo4071ea22014-04-03 14:49:36 -070097 return PTR_ERR(rtc);
Alessandro Zummoa95579c2006-03-27 01:16:42 -080098 }
Jeff Garzik91046a82006-12-06 20:35:34 -080099
100 err = device_create_file(&plat_dev->dev, &dev_attr_irq);
101 if (err)
Alessandro Zummo4071ea22014-04-03 14:49:36 -0700102 dev_err(&plat_dev->dev, "Unable to create sysfs entry: %s\n",
103 dev_attr_irq.attr.name);
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800104
105 platform_set_drvdata(plat_dev, rtc);
106
107 return 0;
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800108}
109
Greg Kroah-Hartman5a167f42012-12-21 13:09:38 -0800110static int test_remove(struct platform_device *plat_dev)
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800111{
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800112 device_remove_file(&plat_dev->dev, &dev_attr_irq);
113
114 return 0;
115}
116
Sam Ravnborgc4646522008-04-28 02:11:55 -0700117static struct platform_driver test_driver = {
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800118 .probe = test_probe,
Greg Kroah-Hartman5a167f42012-12-21 13:09:38 -0800119 .remove = test_remove,
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800120 .driver = {
121 .name = "rtc-test",
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800122 },
123};
124
125static int __init test_init(void)
126{
Alexandre Belloni5b257572018-05-31 23:09:56 +0200127 int i, err;
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800128
Sam Ravnborgc4646522008-04-28 02:11:55 -0700129 if ((err = platform_driver_register(&test_driver)))
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800130 return err;
131
Alexandre Belloni5b257572018-05-31 23:09:56 +0200132 err = -ENOMEM;
133 for (i = 0; i < MAX_RTC_TEST; i++) {
134 pdev[i] = platform_device_alloc("rtc-test", i);
135 if (!pdev[i])
136 goto exit_free_mem;
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800137 }
138
Alexandre Belloni5b257572018-05-31 23:09:56 +0200139 for (i = 0; i < MAX_RTC_TEST; i++) {
140 err = platform_device_add(pdev[i]);
141 if (err)
142 goto exit_device_del;
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800143 }
144
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800145 return 0;
146
Alexandre Belloni5b257572018-05-31 23:09:56 +0200147exit_device_del:
148 for (; i > 0; i--)
149 platform_device_del(pdev[i - 1]);
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800150
Alexandre Belloni5b257572018-05-31 23:09:56 +0200151exit_free_mem:
152 for (i = 0; i < MAX_RTC_TEST; i++)
153 platform_device_put(pdev[i]);
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800154
Sam Ravnborgc4646522008-04-28 02:11:55 -0700155 platform_driver_unregister(&test_driver);
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800156 return err;
157}
158
159static void __exit test_exit(void)
160{
Alexandre Belloni5b257572018-05-31 23:09:56 +0200161 int i;
162
163 for (i = 0; i < MAX_RTC_TEST; i++)
164 platform_device_unregister(pdev[i]);
165
Sam Ravnborgc4646522008-04-28 02:11:55 -0700166 platform_driver_unregister(&test_driver);
Alessandro Zummoa95579c2006-03-27 01:16:42 -0800167}
168
169MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
170MODULE_DESCRIPTION("RTC test driver/device");
171MODULE_LICENSE("GPL");
172
173module_init(test_init);
174module_exit(test_exit);