aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nvmem/core.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-05 19:20:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-05 19:20:22 -0400
commitabf7dba7c4f77d781f6df50fefb19a64c5dc331f (patch)
tree38648731b502d5aec508f3b33f6616190e598eb6 /drivers/nvmem/core.c
parent07c4dd3435aa387d3b58f4e941dc516513f14507 (diff)
parentb23220fe054e92f616b82450fae8cd3ab176cc60 (diff)
Merge tag 'char-misc-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH: "Here is the "big" char and misc driver patches for 4.18-rc1. It's not a lot of stuff here, but there are some highlights: - coreboot driver updates - soundwire driver updates - android binder updates - fpga big sync, mostly documentation - lots of minor driver updates All of these have been in linux-next for a while with no reported issues" * tag 'char-misc-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (81 commits) vmw_balloon: fixing double free when batching mode is off MAINTAINERS: Add driver-api/fpga path fpga: clarify that unregister functions also free documentation: fpga: move fpga-region.txt to driver-api documentation: fpga: add bridge document to driver-api documentation: fpga: move fpga-mgr.txt to driver-api Documentation: fpga: move fpga overview to driver-api fpga: region: kernel-doc fixes fpga: bridge: kernel-doc fixes fpga: mgr: kernel-doc fixes fpga: use SPDX fpga: region: change api, add fpga_region_create/free fpga: bridge: change api, don't use drvdata fpga: manager: change api, don't use drvdata fpga: region: don't use drvdata in common fpga code Drivers: hv: vmbus: Removed an unnecessary cast from void * ver_linux: Drop redundant calls to system() to test if file is readable ver_linux: Move stderr redirection from function parameter to function body misc: IBM Virtual Management Channel Driver (VMC) rpmsg: Correct support for MODULE_DEVICE_TABLE() ...
Diffstat (limited to 'drivers/nvmem/core.c')
-rw-r--r--drivers/nvmem/core.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index b05aa8e81303..b5b0cdc21d01 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -353,18 +353,27 @@ static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem,
353 return 0; 353 return 0;
354} 354}
355 355
356static int nvmem_add_cells(struct nvmem_device *nvmem, 356/**
357 const struct nvmem_config *cfg) 357 * nvmem_add_cells() - Add cell information to an nvmem device
358 *
359 * @nvmem: nvmem device to add cells to.
360 * @info: nvmem cell info to add to the device
361 * @ncells: number of cells in info
362 *
363 * Return: 0 or negative error code on failure.
364 */
365int nvmem_add_cells(struct nvmem_device *nvmem,
366 const struct nvmem_cell_info *info,
367 int ncells)
358{ 368{
359 struct nvmem_cell **cells; 369 struct nvmem_cell **cells;
360 const struct nvmem_cell_info *info = cfg->cells;
361 int i, rval; 370 int i, rval;
362 371
363 cells = kcalloc(cfg->ncells, sizeof(*cells), GFP_KERNEL); 372 cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL);
364 if (!cells) 373 if (!cells)
365 return -ENOMEM; 374 return -ENOMEM;
366 375
367 for (i = 0; i < cfg->ncells; i++) { 376 for (i = 0; i < ncells; i++) {
368 cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL); 377 cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL);
369 if (!cells[i]) { 378 if (!cells[i]) {
370 rval = -ENOMEM; 379 rval = -ENOMEM;
@@ -380,7 +389,7 @@ static int nvmem_add_cells(struct nvmem_device *nvmem,
380 nvmem_cell_add(cells[i]); 389 nvmem_cell_add(cells[i]);
381 } 390 }
382 391
383 nvmem->ncells = cfg->ncells; 392 nvmem->ncells = ncells;
384 /* remove tmp array */ 393 /* remove tmp array */
385 kfree(cells); 394 kfree(cells);
386 395
@@ -393,6 +402,7 @@ err:
393 402
394 return rval; 403 return rval;
395} 404}
405EXPORT_SYMBOL_GPL(nvmem_add_cells);
396 406
397/* 407/*
398 * nvmem_setup_compat() - Create an additional binary entry in 408 * nvmem_setup_compat() - Create an additional binary entry in
@@ -509,7 +519,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
509 } 519 }
510 520
511 if (config->cells) 521 if (config->cells)
512 nvmem_add_cells(nvmem, config); 522 nvmem_add_cells(nvmem, config->cells, config->ncells);
513 523
514 return nvmem; 524 return nvmem;
515 525
@@ -559,6 +569,7 @@ static void devm_nvmem_release(struct device *dev, void *res)
559 * nvmem_config. 569 * nvmem_config.
560 * Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem 570 * Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
561 * 571 *
572 * @dev: Device that uses the nvmem device.
562 * @config: nvmem device configuration with which nvmem device is created. 573 * @config: nvmem device configuration with which nvmem device is created.
563 * 574 *
564 * Return: Will be an ERR_PTR() on error or a valid pointer to nvmem_device 575 * Return: Will be an ERR_PTR() on error or a valid pointer to nvmem_device
@@ -597,6 +608,7 @@ static int devm_nvmem_match(struct device *dev, void *res, void *data)
597 * devm_nvmem_unregister() - Unregister previously registered managed nvmem 608 * devm_nvmem_unregister() - Unregister previously registered managed nvmem
598 * device. 609 * device.
599 * 610 *
611 * @dev: Device that uses the nvmem device.
600 * @nvmem: Pointer to previously registered nvmem device. 612 * @nvmem: Pointer to previously registered nvmem device.
601 * 613 *
602 * Return: Will be an negative on error or a zero on success. 614 * Return: Will be an negative on error or a zero on success.
@@ -1107,6 +1119,8 @@ static void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell,
1107 1119
1108 /* setup the first byte with lsb bits from nvmem */ 1120 /* setup the first byte with lsb bits from nvmem */
1109 rc = nvmem_reg_read(nvmem, cell->offset, &v, 1); 1121 rc = nvmem_reg_read(nvmem, cell->offset, &v, 1);
1122 if (rc)
1123 goto err;
1110 *b++ |= GENMASK(bit_offset - 1, 0) & v; 1124 *b++ |= GENMASK(bit_offset - 1, 0) & v;
1111 1125
1112 /* setup rest of the byte if any */ 1126 /* setup rest of the byte if any */
@@ -1125,11 +1139,16 @@ static void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell,
1125 /* setup the last byte with msb bits from nvmem */ 1139 /* setup the last byte with msb bits from nvmem */
1126 rc = nvmem_reg_read(nvmem, 1140 rc = nvmem_reg_read(nvmem,
1127 cell->offset + cell->bytes - 1, &v, 1); 1141 cell->offset + cell->bytes - 1, &v, 1);
1142 if (rc)
1143 goto err;
1128 *p |= GENMASK(7, (nbits + bit_offset) % BITS_PER_BYTE) & v; 1144 *p |= GENMASK(7, (nbits + bit_offset) % BITS_PER_BYTE) & v;
1129 1145
1130 } 1146 }
1131 1147
1132 return buf; 1148 return buf;
1149err:
1150 kfree(buf);
1151 return ERR_PTR(rc);
1133} 1152}
1134 1153
1135/** 1154/**