Blame view

drivers/rtc/rtc-test.c 4.16 KB
c7080e201   Alexandre Belloni   rtc: test: Switch...
1
  // SPDX-License-Identifier: GPL-2.0
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
2
3
4
5
  /*
   * An RTC test device/driver
   * Copyright (C) 2005 Tower Technologies
   * Author: Alessandro Zummo <a.zummo@towertech.it>
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
6
7
8
9
10
11
   */
  
  #include <linux/module.h>
  #include <linux/err.h>
  #include <linux/rtc.h>
  #include <linux/platform_device.h>
5b257571c   Alexandre Belloni   rtc: test: allow ...
12
  #define MAX_RTC_TEST 3
4dc2403be   Alexandre Belloni   rtc: test: store ...
13
14
15
  struct rtc_test_data {
  	struct rtc_device *rtc;
  	time64_t offset;
8be090299   Alexandre Belloni   rtc: test: emulat...
16
17
  	struct timer_list alarm;
  	bool alarm_en;
4dc2403be   Alexandre Belloni   rtc: test: store ...
18
  };
2b4f07e99   Colin Ian King   rtc: test: make a...
19
  static struct platform_device *pdev[MAX_RTC_TEST];
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
20

8be090299   Alexandre Belloni   rtc: test: emulat...
21
  static int test_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
22
  {
8be090299   Alexandre Belloni   rtc: test: emulat...
23
24
25
26
27
28
29
30
  	struct rtc_test_data *rtd = dev_get_drvdata(dev);
  	time64_t alarm;
  
  	alarm = (rtd->alarm.expires - jiffies) / HZ;
  	alarm += ktime_get_real_seconds() + rtd->offset;
  
  	rtc_time64_to_tm(alarm, &alrm->time);
  	alrm->enabled = rtd->alarm_en;
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
31
32
  	return 0;
  }
8be090299   Alexandre Belloni   rtc: test: emulat...
33
  static int test_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
34
  {
8be090299   Alexandre Belloni   rtc: test: emulat...
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  	struct rtc_test_data *rtd = dev_get_drvdata(dev);
  	ktime_t timeout;
  	u64 expires;
  
  	timeout = rtc_tm_to_time64(&alrm->time) - ktime_get_real_seconds();
  	timeout -= rtd->offset;
  
  	del_timer(&rtd->alarm);
  
  	expires = jiffies + timeout * HZ;
  	if (expires > U32_MAX)
  		expires = U32_MAX;
  
  	pr_err("ABE: %s +%d %s
  ", __FILE__, __LINE__, __func__);
  	rtd->alarm.expires = expires;
  
  	if (alrm->enabled)
  		add_timer(&rtd->alarm);
  
  	rtd->alarm_en = alrm->enabled;
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
56
57
  	return 0;
  }
4dc2403be   Alexandre Belloni   rtc: test: store ...
58
  static int test_rtc_read_time(struct device *dev, struct rtc_time *tm)
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
59
  {
4dc2403be   Alexandre Belloni   rtc: test: store ...
60
61
62
  	struct rtc_test_data *rtd = dev_get_drvdata(dev);
  
  	rtc_time64_to_tm(ktime_get_real_seconds() + rtd->offset, tm);
4d644ab84   Xunlei Pang   drivers/rtc/test:...
63
64
  	return 0;
  }
43dae505d   Alexandre Belloni   rtc: test: use .s...
65
  static int test_rtc_set_time(struct device *dev, struct rtc_time *tm)
4d644ab84   Xunlei Pang   drivers/rtc/test:...
66
  {
4dc2403be   Alexandre Belloni   rtc: test: store ...
67
  	struct rtc_test_data *rtd = dev_get_drvdata(dev);
43dae505d   Alexandre Belloni   rtc: test: use .s...
68
  	rtd->offset = rtc_tm_to_time64(tm) - ktime_get_real_seconds();
4dc2403be   Alexandre Belloni   rtc: test: store ...
69

a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
70
71
  	return 0;
  }
16380c153   John Stultz   RTC: Convert rtc ...
72
  static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
73
  {
8be090299   Alexandre Belloni   rtc: test: emulat...
74
75
76
77
78
79
80
  	struct rtc_test_data *rtd = dev_get_drvdata(dev);
  
  	rtd->alarm_en = enable;
  	if (enable)
  		add_timer(&rtd->alarm);
  	else
  		del_timer(&rtd->alarm);
16380c153   John Stultz   RTC: Convert rtc ...
81
  	return 0;
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
82
  }
1928906d1   Alexandre Belloni   rtc: test: remove...
83
84
  static const struct rtc_class_ops test_rtc_ops_noalm = {
  	.read_time = test_rtc_read_time,
43dae505d   Alexandre Belloni   rtc: test: use .s...
85
  	.set_time = test_rtc_set_time,
1928906d1   Alexandre Belloni   rtc: test: remove...
86
87
  	.alarm_irq_enable = test_rtc_alarm_irq_enable,
  };
784176820   Alexandre Belloni   rtc: test: remove...
88
  static const struct rtc_class_ops test_rtc_ops = {
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
89
  	.read_time = test_rtc_read_time,
43dae505d   Alexandre Belloni   rtc: test: use .s...
90
  	.set_time = test_rtc_set_time,
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
91
92
  	.read_alarm = test_rtc_read_alarm,
  	.set_alarm = test_rtc_set_alarm,
16380c153   John Stultz   RTC: Convert rtc ...
93
  	.alarm_irq_enable = test_rtc_alarm_irq_enable,
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
94
  };
8be090299   Alexandre Belloni   rtc: test: emulat...
95
96
97
98
99
100
  static void test_rtc_alarm_handler(struct timer_list *t)
  {
  	struct rtc_test_data *rtd = from_timer(rtd, t, alarm);
  
  	rtc_update_irq(rtd->rtc, 1, RTC_AF | RTC_IRQF);
  }
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
101
102
  static int test_probe(struct platform_device *plat_dev)
  {
4dc2403be   Alexandre Belloni   rtc: test: store ...
103
  	struct rtc_test_data *rtd;
dd8d8137f   Jingoo Han   rtc: rtc-test: us...
104

4dc2403be   Alexandre Belloni   rtc: test: store ...
105
106
107
  	rtd = devm_kzalloc(&plat_dev->dev, sizeof(*rtd), GFP_KERNEL);
  	if (!rtd)
  		return -ENOMEM;
91046a8a6   Jeff Garzik   [PATCH] RTC: hand...
108

4dc2403be   Alexandre Belloni   rtc: test: store ...
109
  	platform_set_drvdata(plat_dev, rtd);
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
110

0b472ad29   Alexandre Belloni   rtc: test: conver...
111
  	rtd->rtc = devm_rtc_allocate_device(&plat_dev->dev);
4dc2403be   Alexandre Belloni   rtc: test: store ...
112
113
  	if (IS_ERR(rtd->rtc))
  		return PTR_ERR(rtd->rtc);
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
114

1928906d1   Alexandre Belloni   rtc: test: remove...
115
116
117
118
119
120
  	switch (plat_dev->id) {
  	case 0:
  		rtd->rtc->ops = &test_rtc_ops_noalm;
  		break;
  	default:
  		rtd->rtc->ops = &test_rtc_ops;
c19623db3   Roman Stratiienko   rtc: test: enable...
121
  		device_init_wakeup(&plat_dev->dev, 1);
1928906d1   Alexandre Belloni   rtc: test: remove...
122
  	}
0b472ad29   Alexandre Belloni   rtc: test: conver...
123

8be090299   Alexandre Belloni   rtc: test: emulat...
124
125
  	timer_setup(&rtd->alarm, test_rtc_alarm_handler, 0);
  	rtd->alarm.expires = 0;
0b472ad29   Alexandre Belloni   rtc: test: conver...
126
  	return rtc_register_device(rtd->rtc);
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
127
  }
c46465281   Sam Ravnborg   rtc: silence sect...
128
  static struct platform_driver test_driver = {
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
129
  	.probe	= test_probe,
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
130
131
  	.driver = {
  		.name = "rtc-test",
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
132
133
134
135
136
  	},
  };
  
  static int __init test_init(void)
  {
5b257571c   Alexandre Belloni   rtc: test: allow ...
137
  	int i, err;
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
138

540a11d8b   Alexandre Belloni   rtc: test: do not...
139
140
  	err = platform_driver_register(&test_driver);
  	if (err)
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
141
  		return err;
5b257571c   Alexandre Belloni   rtc: test: allow ...
142
143
144
145
146
  	err = -ENOMEM;
  	for (i = 0; i < MAX_RTC_TEST; i++) {
  		pdev[i] = platform_device_alloc("rtc-test", i);
  		if (!pdev[i])
  			goto exit_free_mem;
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
147
  	}
5b257571c   Alexandre Belloni   rtc: test: allow ...
148
149
150
151
  	for (i = 0; i < MAX_RTC_TEST; i++) {
  		err = platform_device_add(pdev[i]);
  		if (err)
  			goto exit_device_del;
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
152
  	}
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
153
  	return 0;
5b257571c   Alexandre Belloni   rtc: test: allow ...
154
155
156
  exit_device_del:
  	for (; i > 0; i--)
  		platform_device_del(pdev[i - 1]);
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
157

5b257571c   Alexandre Belloni   rtc: test: allow ...
158
159
160
  exit_free_mem:
  	for (i = 0; i < MAX_RTC_TEST; i++)
  		platform_device_put(pdev[i]);
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
161

c46465281   Sam Ravnborg   rtc: silence sect...
162
  	platform_driver_unregister(&test_driver);
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
163
164
165
166
167
  	return err;
  }
  
  static void __exit test_exit(void)
  {
5b257571c   Alexandre Belloni   rtc: test: allow ...
168
169
170
171
  	int i;
  
  	for (i = 0; i < MAX_RTC_TEST; i++)
  		platform_device_unregister(pdev[i]);
c46465281   Sam Ravnborg   rtc: silence sect...
172
  	platform_driver_unregister(&test_driver);
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
173
174
175
176
  }
  
  MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
  MODULE_DESCRIPTION("RTC test driver/device");
fd13c930f   Alexandre Belloni   rtc: test: make l...
177
  MODULE_LICENSE("GPL v2");
a95579cd4   Alessandro Zummo   [PATCH] RTC subsy...
178
179
180
  
  module_init(test_init);
  module_exit(test_exit);