1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2019, Linaro Limited
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",
14 #ifdef CONFIG_DEBUG_LOCK_ALLOC
15 static struct lock_class_key eeprom_lock_key
;
18 static ssize_t
type_show(struct device
*dev
,
19 struct device_attribute
*attr
, char *buf
)
21 struct nvmem_device
*nvmem
= to_nvmem_device(dev
);
23 return sprintf(buf
, "%s\n", nvmem_type_str
[nvmem
->type
]);
26 static DEVICE_ATTR_RO(type
);
28 static struct attribute
*nvmem_attrs
[] = {
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
)
38 struct nvmem_device
*nvmem
;
44 dev
= container_of(kobj
, struct device
, kobj
);
45 nvmem
= to_nvmem_device(dev
);
47 /* Stop the user from reading */
48 if (pos
>= nvmem
->size
)
51 if (count
< nvmem
->word_size
)
54 if (pos
+ count
> nvmem
->size
)
55 count
= nvmem
->size
- pos
;
57 count
= round_down(count
, nvmem
->word_size
);
59 rc
= nvmem
->reg_read(nvmem
->priv
, pos
, buf
, count
);
67 static ssize_t
bin_attr_nvmem_write(struct file
*filp
, struct kobject
*kobj
,
68 struct bin_attribute
*attr
,
69 char *buf
, loff_t pos
, size_t count
)
72 struct nvmem_device
*nvmem
;
78 dev
= container_of(kobj
, struct device
, kobj
);
79 nvmem
= to_nvmem_device(dev
);
81 /* Stop the user from writing */
82 if (pos
>= nvmem
->size
)
85 if (count
< nvmem
->word_size
)
88 if (pos
+ count
> nvmem
->size
)
89 count
= nvmem
->size
- pos
;
91 count
= round_down(count
, nvmem
->word_size
);
93 rc
= nvmem
->reg_write(nvmem
->priv
, pos
, buf
, count
);
101 /* default read/write permissions */
102 static struct bin_attribute bin_attr_rw_nvmem
= {
107 .read
= bin_attr_nvmem_read
,
108 .write
= bin_attr_nvmem_write
,
111 static struct bin_attribute
*nvmem_bin_rw_attributes
[] = {
116 static const struct attribute_group nvmem_bin_rw_group
= {
117 .bin_attrs
= nvmem_bin_rw_attributes
,
118 .attrs
= nvmem_attrs
,
121 static const struct attribute_group
*nvmem_rw_dev_groups
[] = {
126 /* read only permission */
127 static struct bin_attribute bin_attr_ro_nvmem
= {
132 .read
= bin_attr_nvmem_read
,
135 static struct bin_attribute
*nvmem_bin_ro_attributes
[] = {
140 static const struct attribute_group nvmem_bin_ro_group
= {
141 .bin_attrs
= nvmem_bin_ro_attributes
,
142 .attrs
= nvmem_attrs
,
145 static const struct attribute_group
*nvmem_ro_dev_groups
[] = {
150 /* default read/write permissions, root only */
151 static struct bin_attribute bin_attr_rw_root_nvmem
= {
156 .read
= bin_attr_nvmem_read
,
157 .write
= bin_attr_nvmem_write
,
160 static struct bin_attribute
*nvmem_bin_rw_root_attributes
[] = {
161 &bin_attr_rw_root_nvmem
,
165 static const struct attribute_group nvmem_bin_rw_root_group
= {
166 .bin_attrs
= nvmem_bin_rw_root_attributes
,
167 .attrs
= nvmem_attrs
,
170 static const struct attribute_group
*nvmem_rw_root_dev_groups
[] = {
171 &nvmem_bin_rw_root_group
,
175 /* read only permission, root only */
176 static struct bin_attribute bin_attr_ro_root_nvmem
= {
181 .read
= bin_attr_nvmem_read
,
184 static struct bin_attribute
*nvmem_bin_ro_root_attributes
[] = {
185 &bin_attr_ro_root_nvmem
,
189 static const struct attribute_group nvmem_bin_ro_root_group
= {
190 .bin_attrs
= nvmem_bin_ro_root_attributes
,
191 .attrs
= nvmem_attrs
,
194 static const struct attribute_group
*nvmem_ro_root_dev_groups
[] = {
195 &nvmem_bin_ro_root_group
,
199 const struct attribute_group
**nvmem_sysfs_get_groups(
200 struct nvmem_device
*nvmem
,
201 const struct nvmem_config
*config
)
203 if (config
->root_only
)
204 return nvmem
->read_only
?
205 nvmem_ro_root_dev_groups
:
206 nvmem_rw_root_dev_groups
;
208 return nvmem
->read_only
? nvmem_ro_dev_groups
: nvmem_rw_dev_groups
;
212 * nvmem_setup_compat() - Create an additional binary entry in
213 * drivers sys directory, to be backwards compatible with the older
214 * drivers/misc/eeprom drivers.
216 int nvmem_sysfs_setup_compat(struct nvmem_device
*nvmem
,
217 const struct nvmem_config
*config
)
224 if (!config
->base_dev
)
227 if (nvmem
->read_only
) {
228 if (config
->root_only
)
229 nvmem
->eeprom
= bin_attr_ro_root_nvmem
;
231 nvmem
->eeprom
= bin_attr_ro_nvmem
;
233 if (config
->root_only
)
234 nvmem
->eeprom
= bin_attr_rw_root_nvmem
;
236 nvmem
->eeprom
= bin_attr_rw_nvmem
;
238 nvmem
->eeprom
.attr
.name
= "eeprom";
239 nvmem
->eeprom
.size
= nvmem
->size
;
240 #ifdef CONFIG_DEBUG_LOCK_ALLOC
241 nvmem
->eeprom
.attr
.key
= &eeprom_lock_key
;
243 nvmem
->eeprom
.private = &nvmem
->dev
;
244 nvmem
->base_dev
= config
->base_dev
;
246 rval
= device_create_bin_file(nvmem
->base_dev
, &nvmem
->eeprom
);
249 "Failed to create eeprom binary file %d\n", rval
);
253 nvmem
->flags
|= FLAG_COMPAT
;
258 void nvmem_sysfs_remove_compat(struct nvmem_device
*nvmem
,
259 const struct nvmem_config
*config
)
262 device_remove_bin_file(nvmem
->base_dev
, &nvmem
->eeprom
);