diff options
Diffstat (limited to 'drivers/nvmem/core.c')
-rw-r--r-- | drivers/nvmem/core.c | 33 |
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 | ||
356 | static 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 | */ | ||
365 | int 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 | } |
405 | EXPORT_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; |
1149 | err: | ||
1150 | kfree(buf); | ||
1151 | return ERR_PTR(rc); | ||
1133 | } | 1152 | } |
1134 | 1153 | ||
1135 | /** | 1154 | /** |