diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2016-05-30 14:57:55 -0400 |
|---|---|---|
| committer | Alexandre Belloni <alexandre.belloni@free-electrons.com> | 2016-06-03 18:23:04 -0400 |
| commit | ca6da801878635bfb851088e1a4eaa3745720582 (patch) | |
| tree | c3a5e2e01e9c5237a60e94bc0db9ff4781693da2 /arch/parisc/kernel | |
| parent | 7ee942179fd8d485cedaf1875f81c5ee7a3ebeae (diff) | |
rtc: parisc: provide rtc_class_ops directly
The rtc-generic driver provides an architecture specific
wrapper on top of the generic rtc_class_ops abstraction,
and on pa-risc, that is implemented using an open-coded
version of rtc_time_to_tm/rtc_tm_to_time.
This changes the parisc rtc-generic device to provide its
rtc_class_ops directly, using the normal helper functions,
which makes this y2038 safe (on 32-bit) and simplifies
the implementation.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Diffstat (limited to 'arch/parisc/kernel')
| -rw-r--r-- | arch/parisc/kernel/time.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 58dd6801f5be..744878789752 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | */ | 12 | */ |
| 13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/rtc.h> | ||
| 15 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
| 16 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
| 17 | #include <linux/param.h> | 18 | #include <linux/param.h> |
| @@ -248,14 +249,47 @@ void __init start_cpu_itimer(void) | |||
| 248 | per_cpu(cpu_data, cpu).it_value = next_tick; | 249 | per_cpu(cpu_data, cpu).it_value = next_tick; |
| 249 | } | 250 | } |
| 250 | 251 | ||
| 252 | #if IS_ENABLED(CONFIG_RTC_DRV_GENERIC) | ||
| 253 | static int rtc_generic_get_time(struct device *dev, struct rtc_time *tm) | ||
| 254 | { | ||
| 255 | struct pdc_tod tod_data; | ||
| 256 | |||
| 257 | memset(tm, 0, sizeof(*tm)); | ||
| 258 | if (pdc_tod_read(&tod_data) < 0) | ||
| 259 | return -EOPNOTSUPP; | ||
| 260 | |||
| 261 | /* we treat tod_sec as unsigned, so this can work until year 2106 */ | ||
| 262 | rtc_time64_to_tm(tod_data.tod_sec, tm); | ||
| 263 | return rtc_valid_tm(tm); | ||
| 264 | } | ||
| 265 | |||
| 266 | static int rtc_generic_set_time(struct device *dev, struct rtc_time *tm) | ||
| 267 | { | ||
| 268 | time64_t secs = rtc_tm_to_time64(tm); | ||
| 269 | |||
| 270 | if (pdc_tod_set(secs, 0) < 0) | ||
| 271 | return -EOPNOTSUPP; | ||
| 272 | |||
| 273 | return 0; | ||
| 274 | } | ||
| 275 | |||
| 276 | static const struct rtc_class_ops rtc_generic_ops = { | ||
| 277 | .read_time = rtc_generic_get_time, | ||
| 278 | .set_time = rtc_generic_set_time, | ||
| 279 | }; | ||
| 280 | |||
| 251 | static int __init rtc_init(void) | 281 | static int __init rtc_init(void) |
| 252 | { | 282 | { |
| 253 | struct platform_device *pdev; | 283 | struct platform_device *pdev; |
| 254 | 284 | ||
| 255 | pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); | 285 | pdev = platform_device_register_data(NULL, "rtc-generic", -1, |
| 286 | &rtc_generic_ops, | ||
| 287 | sizeof(rtc_generic_ops)); | ||
| 288 | |||
| 256 | return PTR_ERR_OR_ZERO(pdev); | 289 | return PTR_ERR_OR_ZERO(pdev); |
| 257 | } | 290 | } |
| 258 | device_initcall(rtc_init); | 291 | device_initcall(rtc_init); |
| 292 | #endif | ||
| 259 | 293 | ||
| 260 | void read_persistent_clock(struct timespec *ts) | 294 | void read_persistent_clock(struct timespec *ts) |
| 261 | { | 295 | { |
