This source file includes following definitions.
- type_show
- bin_attr_nvmem_read
- bin_attr_nvmem_write
- nvmem_sysfs_get_groups
- nvmem_sysfs_setup_compat
- nvmem_sysfs_remove_compat
1
2
3
4
5 #include "nvmem.h"
6
7 static const char * const nvmem_type_str[] = {
8 [NVMEM_TYPE_UNKNOWN] = "Unknown",
9 [NVMEM_TYPE_EEPROM] = "EEPROM",
10 [NVMEM_TYPE_OTP] = "OTP",
11 [NVMEM_TYPE_BATTERY_BACKED] = "Battery backed",
12 };
13
14 #ifdef CONFIG_DEBUG_LOCK_ALLOC
15 static struct lock_class_key eeprom_lock_key;
16 #endif
17
18 static ssize_t type_show(struct device *dev,
19 struct device_attribute *attr, char *buf)
20 {
21 struct nvmem_device *nvmem = to_nvmem_device(dev);
22
23 return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]);
24 }
25
26 static DEVICE_ATTR_RO(type);
27
28 static struct attribute *nvmem_attrs[] = {
29 &dev_attr_type.attr,
30 NULL,
31 };
32
33 static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
34 struct bin_attribute *attr,
35 char *buf, loff_t pos, size_t count)
36 {
37 struct device *dev;
38 struct nvmem_device *nvmem;
39 int rc;
40
41 if (attr->private)
42 dev = attr->private;
43 else
44 dev = container_of(kobj, struct device, kobj);
45 nvmem = to_nvmem_device(dev);
46
47
48 if (pos >= nvmem->size)
49 return 0;
50
51 if (count < nvmem->word_size)
52 return -EINVAL;
53
54 if (pos + count > nvmem->size)
55 count = nvmem->size - pos;
56
57 count = round_down(count, nvmem->word_size);
58
59 if (!nvmem->reg_read)
60 return -EPERM;
61
62 rc = nvmem->reg_read(nvmem->priv, pos, buf, count);
63
64 if (rc)
65 return rc;
66
67 return count;
68 }
69
70 static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
71 struct bin_attribute *attr,
72 char *buf, loff_t pos, size_t count)
73 {
74 struct device *dev;
75 struct nvmem_device *nvmem;
76 int rc;
77
78 if (attr->private)
79 dev = attr->private;
80 else
81 dev = container_of(kobj, struct device, kobj);
82 nvmem = to_nvmem_device(dev);
83
84
85 if (pos >= nvmem->size)
86 return -EFBIG;
87
88 if (count < nvmem->word_size)
89 return -EINVAL;
90
91 if (pos + count > nvmem->size)
92 count = nvmem->size - pos;
93
94 count = round_down(count, nvmem->word_size);
95
96 if (!nvmem->reg_write)
97 return -EPERM;
98
99 rc = nvmem->reg_write(nvmem->priv, pos, buf, count);
100
101 if (rc)
102 return rc;
103
104 return count;
105 }
106
107
108 static struct bin_attribute bin_attr_rw_nvmem = {
109 .attr = {
110 .name = "nvmem",
111 .mode = 0644,
112 },
113 .read = bin_attr_nvmem_read,
114 .write = bin_attr_nvmem_write,
115 };
116
117 static struct bin_attribute *nvmem_bin_rw_attributes[] = {
118 &bin_attr_rw_nvmem,
119 NULL,
120 };
121
122 static const struct attribute_group nvmem_bin_rw_group = {
123 .bin_attrs = nvmem_bin_rw_attributes,
124 .attrs = nvmem_attrs,
125 };
126
127 static const struct attribute_group *nvmem_rw_dev_groups[] = {
128 &nvmem_bin_rw_group,
129 NULL,
130 };
131
132
133 static struct bin_attribute bin_attr_ro_nvmem = {
134 .attr = {
135 .name = "nvmem",
136 .mode = 0444,
137 },
138 .read = bin_attr_nvmem_read,
139 };
140
141 static struct bin_attribute *nvmem_bin_ro_attributes[] = {
142 &bin_attr_ro_nvmem,
143 NULL,
144 };
145
146 static const struct attribute_group nvmem_bin_ro_group = {
147 .bin_attrs = nvmem_bin_ro_attributes,
148 .attrs = nvmem_attrs,
149 };
150
151 static const struct attribute_group *nvmem_ro_dev_groups[] = {
152 &nvmem_bin_ro_group,
153 NULL,
154 };
155
156
157 static struct bin_attribute bin_attr_rw_root_nvmem = {
158 .attr = {
159 .name = "nvmem",
160 .mode = 0600,
161 },
162 .read = bin_attr_nvmem_read,
163 .write = bin_attr_nvmem_write,
164 };
165
166 static struct bin_attribute *nvmem_bin_rw_root_attributes[] = {
167 &bin_attr_rw_root_nvmem,
168 NULL,
169 };
170
171 static const struct attribute_group nvmem_bin_rw_root_group = {
172 .bin_attrs = nvmem_bin_rw_root_attributes,
173 .attrs = nvmem_attrs,
174 };
175
176 static const struct attribute_group *nvmem_rw_root_dev_groups[] = {
177 &nvmem_bin_rw_root_group,
178 NULL,
179 };
180
181
182 static struct bin_attribute bin_attr_ro_root_nvmem = {
183 .attr = {
184 .name = "nvmem",
185 .mode = 0400,
186 },
187 .read = bin_attr_nvmem_read,
188 };
189
190 static struct bin_attribute *nvmem_bin_ro_root_attributes[] = {
191 &bin_attr_ro_root_nvmem,
192 NULL,
193 };
194
195 static const struct attribute_group nvmem_bin_ro_root_group = {
196 .bin_attrs = nvmem_bin_ro_root_attributes,
197 .attrs = nvmem_attrs,
198 };
199
200 static const struct attribute_group *nvmem_ro_root_dev_groups[] = {
201 &nvmem_bin_ro_root_group,
202 NULL,
203 };
204
205 const struct attribute_group **nvmem_sysfs_get_groups(
206 struct nvmem_device *nvmem,
207 const struct nvmem_config *config)
208 {
209 if (config->root_only)
210 return nvmem->read_only ?
211 nvmem_ro_root_dev_groups :
212 nvmem_rw_root_dev_groups;
213
214 return nvmem->read_only ? nvmem_ro_dev_groups : nvmem_rw_dev_groups;
215 }
216
217
218
219
220
221
222 int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem,
223 const struct nvmem_config *config)
224 {
225 int rval;
226
227 if (!config->compat)
228 return 0;
229
230 if (!config->base_dev)
231 return -EINVAL;
232
233 if (nvmem->read_only) {
234 if (config->root_only)
235 nvmem->eeprom = bin_attr_ro_root_nvmem;
236 else
237 nvmem->eeprom = bin_attr_ro_nvmem;
238 } else {
239 if (config->root_only)
240 nvmem->eeprom = bin_attr_rw_root_nvmem;
241 else
242 nvmem->eeprom = bin_attr_rw_nvmem;
243 }
244 nvmem->eeprom.attr.name = "eeprom";
245 nvmem->eeprom.size = nvmem->size;
246 #ifdef CONFIG_DEBUG_LOCK_ALLOC
247 nvmem->eeprom.attr.key = &eeprom_lock_key;
248 #endif
249 nvmem->eeprom.private = &nvmem->dev;
250 nvmem->base_dev = config->base_dev;
251
252 rval = device_create_bin_file(nvmem->base_dev, &nvmem->eeprom);
253 if (rval) {
254 dev_err(&nvmem->dev,
255 "Failed to create eeprom binary file %d\n", rval);
256 return rval;
257 }
258
259 nvmem->flags |= FLAG_COMPAT;
260
261 return 0;
262 }
263
264 void nvmem_sysfs_remove_compat(struct nvmem_device *nvmem,
265 const struct nvmem_config *config)
266 {
267 if (config->compat)
268 device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
269 }