Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

nvmem: core: Implement force_ro sysfs attribute

Implement "force_ro" sysfs attribute to allow users to set read-write
devices as read-only and back to read-write from userspace. The choice
of the name is based on MMC core 'force_ro' attribute.

This solves a situation where an AT24 I2C EEPROM with GPIO based nWP
signal may have to be occasionally updated. Such I2C EEPROM device is
usually set as read-only during most of the regular system operation,
but in case it has to be updated in a controlled manner, it could be
unlocked using this new "force_ro" sysfs attribute and then re-locked
again.

The "read-only" DT property and config->read_only configuration is
respected and is used to set default state of the device, read-only
or read-write, for devices which do implement .reg_write function.
For devices which do not implement .reg_write function, the device
is unconditionally read-only and the "force_ro" attribute is not
visible.

Signed-off-by: Marek Vasut <marex@denx.de>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20240705074852.423202-16-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Marek Vasut and committed by
Greg Kroah-Hartman
9d7eb234 08c367e4

+60
+17
Documentation/ABI/stable/sysfs-bus-nvmem
··· 1 + What: /sys/bus/nvmem/devices/.../force_ro 2 + Date: June 2024 3 + KernelVersion: 6.11 4 + Contact: Marek Vasut <marex@denx.de> 5 + Description: 6 + This read/write attribute allows users to set read-write 7 + devices as read-only and back to read-write from userspace. 8 + This can be used to unlock and relock write-protection of 9 + devices which are generally locked, except during sporadic 10 + programming operation. 11 + Read returns '0' or '1' for read-write or read-only modes 12 + respectively. 13 + Write parses one of 'YyTt1NnFf0', or [oO][NnFf] for "on" 14 + and "off", i.e. what kstrbool() supports. 15 + Note: This file is only present if CONFIG_NVMEM_SYSFS 16 + is enabled. 17 + 1 18 What: /sys/bus/nvmem/devices/.../nvmem 2 19 Date: July 2015 3 20 KernelVersion: 4.2
+43
drivers/nvmem/core.c
··· 184 184 185 185 static DEVICE_ATTR_RO(type); 186 186 187 + static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr, 188 + char *buf) 189 + { 190 + struct nvmem_device *nvmem = to_nvmem_device(dev); 191 + 192 + return sysfs_emit(buf, "%d\n", nvmem->read_only); 193 + } 194 + 195 + static ssize_t force_ro_store(struct device *dev, struct device_attribute *attr, 196 + const char *buf, size_t count) 197 + { 198 + struct nvmem_device *nvmem = to_nvmem_device(dev); 199 + int ret = kstrtobool(buf, &nvmem->read_only); 200 + 201 + if (ret < 0) 202 + return ret; 203 + 204 + return count; 205 + } 206 + 207 + static DEVICE_ATTR_RW(force_ro); 208 + 187 209 static struct attribute *nvmem_attrs[] = { 210 + &dev_attr_force_ro.attr, 188 211 &dev_attr_type.attr, 189 212 NULL, 190 213 }; ··· 308 285 return nvmem_bin_attr_get_umode(nvmem); 309 286 } 310 287 288 + static umode_t nvmem_attr_is_visible(struct kobject *kobj, 289 + struct attribute *attr, int i) 290 + { 291 + struct device *dev = kobj_to_dev(kobj); 292 + struct nvmem_device *nvmem = to_nvmem_device(dev); 293 + 294 + /* 295 + * If the device has no .reg_write operation, do not allow 296 + * configuration as read-write. 297 + * If the device is set as read-only by configuration, it 298 + * can be forced into read-write mode using the 'force_ro' 299 + * attribute. 300 + */ 301 + if (attr == &dev_attr_force_ro.attr && !nvmem->reg_write) 302 + return 0; /* Attribute not visible */ 303 + 304 + return attr->mode; 305 + } 306 + 311 307 static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, 312 308 const char *id, int index); 313 309 ··· 383 341 .bin_attrs = nvmem_bin_attributes, 384 342 .attrs = nvmem_attrs, 385 343 .is_bin_visible = nvmem_bin_attr_is_visible, 344 + .is_visible = nvmem_attr_is_visible, 386 345 }; 387 346 388 347 static const struct attribute_group *nvmem_dev_groups[] = {