Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /*
3 : : * RTC subsystem, nvmem interface
4 : : *
5 : : * Copyright (C) 2017 Alexandre Belloni
6 : : */
7 : :
8 : : #include <linux/err.h>
9 : : #include <linux/types.h>
10 : : #include <linux/nvmem-consumer.h>
11 : : #include <linux/rtc.h>
12 : : #include <linux/slab.h>
13 : : #include <linux/sysfs.h>
14 : :
15 : : /*
16 : : * Deprecated ABI compatibility, this should be removed at some point
17 : : */
18 : :
19 : : static const char nvram_warning[] = "Deprecated ABI, please use nvmem";
20 : :
21 : : static ssize_t
22 : 0 : rtc_nvram_read(struct file *filp, struct kobject *kobj,
23 : : struct bin_attribute *attr,
24 : : char *buf, loff_t off, size_t count)
25 : : {
26 [ # # ]: 0 : dev_warn_once(kobj_to_dev(kobj), nvram_warning);
27 : :
28 : 0 : return nvmem_device_read(attr->private, off, count, buf);
29 : : }
30 : :
31 : : static ssize_t
32 : 0 : rtc_nvram_write(struct file *filp, struct kobject *kobj,
33 : : struct bin_attribute *attr,
34 : : char *buf, loff_t off, size_t count)
35 : : {
36 [ # # ]: 0 : dev_warn_once(kobj_to_dev(kobj), nvram_warning);
37 : :
38 : 0 : return nvmem_device_write(attr->private, off, count, buf);
39 : : }
40 : :
41 : : static int rtc_nvram_register(struct rtc_device *rtc,
42 : : struct nvmem_device *nvmem, size_t size)
43 : : {
44 : : int err;
45 : :
46 : : rtc->nvram = kzalloc(sizeof(*rtc->nvram), GFP_KERNEL);
47 : : if (!rtc->nvram)
48 : : return -ENOMEM;
49 : :
50 : : rtc->nvram->attr.name = "nvram";
51 : : rtc->nvram->attr.mode = 0644;
52 : : rtc->nvram->private = nvmem;
53 : :
54 : : sysfs_bin_attr_init(rtc->nvram);
55 : :
56 : : rtc->nvram->read = rtc_nvram_read;
57 : : rtc->nvram->write = rtc_nvram_write;
58 : : rtc->nvram->size = size;
59 : :
60 : : err = sysfs_create_bin_file(&rtc->dev.parent->kobj,
61 : : rtc->nvram);
62 : : if (err) {
63 : : kfree(rtc->nvram);
64 : : rtc->nvram = NULL;
65 : : }
66 : :
67 : : return err;
68 : : }
69 : :
70 : 0 : static void rtc_nvram_unregister(struct rtc_device *rtc)
71 : : {
72 : 0 : sysfs_remove_bin_file(&rtc->dev.parent->kobj, rtc->nvram);
73 : 0 : kfree(rtc->nvram);
74 : 0 : rtc->nvram = NULL;
75 : 0 : }
76 : :
77 : : /*
78 : : * New ABI, uses nvmem
79 : : */
80 : 21 : int rtc_nvmem_register(struct rtc_device *rtc,
81 : : struct nvmem_config *nvmem_config)
82 : : {
83 : 21 : struct nvmem_device *nvmem;
84 : :
85 [ + - ]: 21 : if (!nvmem_config)
86 : : return -ENODEV;
87 : :
88 : 21 : nvmem_config->dev = rtc->dev.parent;
89 : 21 : nvmem_config->owner = rtc->owner;
90 : 21 : nvmem = devm_nvmem_register(rtc->dev.parent, nvmem_config);
91 [ - + ]: 21 : if (IS_ERR(nvmem))
92 : 0 : return PTR_ERR(nvmem);
93 : :
94 : : /* Register the old ABI */
95 [ + - ]: 21 : if (rtc->nvram_old_abi)
96 : 21 : rtc_nvram_register(rtc, nvmem, nvmem_config->size);
97 : :
98 : : return 0;
99 : : }
100 : : EXPORT_SYMBOL_GPL(rtc_nvmem_register);
101 : :
102 : 0 : void rtc_nvmem_unregister(struct rtc_device *rtc)
103 : : {
104 : : /* unregister the old ABI */
105 [ # # ]: 0 : if (rtc->nvram)
106 : 0 : rtc_nvram_unregister(rtc);
107 : 0 : }
|