1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * RTC subsystem, proc interface |
4 | * |
5 | * Copyright (C) 2005-06 Tower Technologies |
6 | * Author: Alessandro Zummo <a.zummo@towertech.it> |
7 | * |
8 | * based on arch/arm/common/rtctime.c |
9 | */ |
10 | |
11 | #include <linux/module.h> |
12 | #include <linux/rtc.h> |
13 | #include <linux/proc_fs.h> |
14 | #include <linux/seq_file.h> |
15 | |
16 | #include "rtc-core.h" |
17 | |
18 | #define NAME_SIZE 10 |
19 | |
20 | #if defined(CONFIG_RTC_HCTOSYS_DEVICE) |
21 | static bool is_rtc_hctosys(struct rtc_device *rtc) |
22 | { |
23 | int size; |
24 | char name[NAME_SIZE]; |
25 | |
26 | size = snprintf(buf: name, NAME_SIZE, fmt: "rtc%d" , rtc->id); |
27 | if (size >= NAME_SIZE) |
28 | return false; |
29 | |
30 | return !strncmp(name, CONFIG_RTC_HCTOSYS_DEVICE, NAME_SIZE); |
31 | } |
32 | #else |
33 | static bool is_rtc_hctosys(struct rtc_device *rtc) |
34 | { |
35 | return (rtc->id == 0); |
36 | } |
37 | #endif |
38 | |
39 | static int rtc_proc_show(struct seq_file *seq, void *offset) |
40 | { |
41 | int err; |
42 | struct rtc_device *rtc = seq->private; |
43 | const struct rtc_class_ops *ops = rtc->ops; |
44 | struct rtc_wkalrm alrm; |
45 | struct rtc_time tm; |
46 | |
47 | err = rtc_read_time(rtc, tm: &tm); |
48 | if (err == 0) { |
49 | seq_printf(m: seq, |
50 | fmt: "rtc_time\t: %ptRt\n" |
51 | "rtc_date\t: %ptRd\n" , |
52 | &tm, &tm); |
53 | } |
54 | |
55 | err = rtc_read_alarm(rtc, alrm: &alrm); |
56 | if (err == 0) { |
57 | seq_printf(m: seq, fmt: "alrm_time\t: %ptRt\n" , &alrm.time); |
58 | seq_printf(m: seq, fmt: "alrm_date\t: %ptRd\n" , &alrm.time); |
59 | seq_printf(m: seq, fmt: "alarm_IRQ\t: %s\n" , |
60 | alrm.enabled ? "yes" : "no" ); |
61 | seq_printf(m: seq, fmt: "alrm_pending\t: %s\n" , |
62 | alrm.pending ? "yes" : "no" ); |
63 | seq_printf(m: seq, fmt: "update IRQ enabled\t: %s\n" , |
64 | (rtc->uie_rtctimer.enabled) ? "yes" : "no" ); |
65 | seq_printf(m: seq, fmt: "periodic IRQ enabled\t: %s\n" , |
66 | (rtc->pie_enabled) ? "yes" : "no" ); |
67 | seq_printf(m: seq, fmt: "periodic IRQ frequency\t: %d\n" , |
68 | rtc->irq_freq); |
69 | seq_printf(m: seq, fmt: "max user IRQ frequency\t: %d\n" , |
70 | rtc->max_user_freq); |
71 | } |
72 | |
73 | seq_printf(m: seq, fmt: "24hr\t\t: yes\n" ); |
74 | |
75 | if (ops->proc) |
76 | ops->proc(rtc->dev.parent, seq); |
77 | |
78 | return 0; |
79 | } |
80 | |
81 | void rtc_proc_add_device(struct rtc_device *rtc) |
82 | { |
83 | if (is_rtc_hctosys(rtc)) |
84 | proc_create_single_data(name: "driver/rtc" , mode: 0, NULL, show: rtc_proc_show, |
85 | data: rtc); |
86 | } |
87 | |
88 | void rtc_proc_del_device(struct rtc_device *rtc) |
89 | { |
90 | if (is_rtc_hctosys(rtc)) |
91 | remove_proc_entry("driver/rtc" , NULL); |
92 | } |
93 | |