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

nvmem: ensure sysfs writes handle write-protect pin

Commit 2a127da461a9 ("nvmem: add support for the write-protect pin")
added support for handling write-protect pins to the nvmem core, and
Commit 1c89074bf850 ("eeprom: at24: remove the write-protect pin support")
retrofitted the at24 driver to use this support.

These changes broke write() on the nvmem sysfs attribute for eeproms
which utilize a write-protect pin, as the write callback invokes the
nvmem device's reg_write callback directly which no longer handles
changing the state of the write-protect pin.

Change the read and write callbacks for the sysfs attribute to invoke
nvmme_reg_read/nvmem_reg_write helpers which handle this, rather than
calling reg_read/reg_write directly.

Fixes: 2a127da461a9 ("nvmem: add support for the write-protect pin")
Signed-off-by: Michael Auchter <michael.auchter@ni.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20200511145042.31223-3-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Michael Auchter and committed by
Greg Kroah-Hartman
b96fc541 0e2abffd

+26 -26
+26 -26
drivers/nvmem/core.c
··· 66 66 67 67 static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); 68 68 69 + static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset, 70 + void *val, size_t bytes) 71 + { 72 + if (nvmem->reg_read) 73 + return nvmem->reg_read(nvmem->priv, offset, val, bytes); 74 + 75 + return -EINVAL; 76 + } 77 + 78 + static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset, 79 + void *val, size_t bytes) 80 + { 81 + int ret; 82 + 83 + if (nvmem->reg_write) { 84 + gpiod_set_value_cansleep(nvmem->wp_gpio, 0); 85 + ret = nvmem->reg_write(nvmem->priv, offset, val, bytes); 86 + gpiod_set_value_cansleep(nvmem->wp_gpio, 1); 87 + return ret; 88 + } 89 + 90 + return -EINVAL; 91 + } 92 + 69 93 #ifdef CONFIG_NVMEM_SYSFS 70 94 static const char * const nvmem_type_str[] = { 71 95 [NVMEM_TYPE_UNKNOWN] = "Unknown", ··· 146 122 if (!nvmem->reg_read) 147 123 return -EPERM; 148 124 149 - rc = nvmem->reg_read(nvmem->priv, pos, buf, count); 125 + rc = nvmem_reg_read(nvmem, pos, buf, count); 150 126 151 127 if (rc) 152 128 return rc; ··· 183 159 if (!nvmem->reg_write) 184 160 return -EPERM; 185 161 186 - rc = nvmem->reg_write(nvmem->priv, pos, buf, count); 162 + rc = nvmem_reg_write(nvmem, pos, buf, count); 187 163 188 164 if (rc) 189 165 return rc; ··· 310 286 } 311 287 312 288 #endif /* CONFIG_NVMEM_SYSFS */ 313 - 314 - static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset, 315 - void *val, size_t bytes) 316 - { 317 - if (nvmem->reg_read) 318 - return nvmem->reg_read(nvmem->priv, offset, val, bytes); 319 - 320 - return -EINVAL; 321 - } 322 - 323 - static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset, 324 - void *val, size_t bytes) 325 - { 326 - int ret; 327 - 328 - if (nvmem->reg_write) { 329 - gpiod_set_value_cansleep(nvmem->wp_gpio, 0); 330 - ret = nvmem->reg_write(nvmem->priv, offset, val, bytes); 331 - gpiod_set_value_cansleep(nvmem->wp_gpio, 1); 332 - return ret; 333 - } 334 - 335 - return -EINVAL; 336 - } 337 289 338 290 static void nvmem_release(struct device *dev) 339 291 {