aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nvmem
diff options
context:
space:
mode:
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>2015-07-27 07:13:45 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-08-05 16:43:44 -0400
commite2a5402ec7c6d0442cca370a0097e75750f81398 (patch)
treef52d6cbb6926345bb556c0b14d4a639abc4f9cec /drivers/nvmem
parent69aba7948cbe53f2f1827e84e9dd0ae470a5072e (diff)
nvmem: Add nvmem_device based consumer apis.
This patch adds read/write apis which are based on nvmem_device. It is common that the drivers like omap cape manager or qcom cpr driver to access bytes directly at particular offset in the eeprom and not from nvmem cell info in DT. These driver would need to get access to the nvmem directly, which is what these new APIS provide. These wrapper apis would help such users to avoid code duplication in there drivers and also avoid them reading a big eeprom blob and parsing it internally in there driver. Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Tested-by: Stefan Wahren <stefan.wahren@i2se.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> Tested-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/nvmem')
-rw-r--r--drivers/nvmem/core.c258
1 files changed, 258 insertions, 0 deletions
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 8c16ae2e1308..d3c6676b3c0c 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -445,6 +445,148 @@ static void __nvmem_device_put(struct nvmem_device *nvmem)
445 mutex_unlock(&nvmem_mutex); 445 mutex_unlock(&nvmem_mutex);
446} 446}
447 447
448static int nvmem_match(struct device *dev, void *data)
449{
450 return !strcmp(dev_name(dev), data);
451}
452
453static struct nvmem_device *nvmem_find(const char *name)
454{
455 struct device *d;
456
457 d = bus_find_device(&nvmem_bus_type, NULL, (void *)name, nvmem_match);
458
459 if (!d)
460 return NULL;
461
462 return to_nvmem_device(d);
463}
464
465#if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
466/**
467 * of_nvmem_device_get() - Get nvmem device from a given id
468 *
469 * @dev node: Device tree node that uses the nvmem device
470 * @id: nvmem name from nvmem-names property.
471 *
472 * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device
473 * on success.
474 */
475struct nvmem_device *of_nvmem_device_get(struct device_node *np, const char *id)
476{
477
478 struct device_node *nvmem_np;
479 int index;
480
481 index = of_property_match_string(np, "nvmem-names", id);
482
483 nvmem_np = of_parse_phandle(np, "nvmem", index);
484 if (!nvmem_np)
485 return ERR_PTR(-EINVAL);
486
487 return __nvmem_device_get(nvmem_np, NULL, NULL);
488}
489EXPORT_SYMBOL_GPL(of_nvmem_device_get);
490#endif
491
492/**
493 * nvmem_device_get() - Get nvmem device from a given id
494 *
495 * @dev : Device that uses the nvmem device
496 * @id: nvmem name from nvmem-names property.
497 *
498 * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device
499 * on success.
500 */
501struct nvmem_device *nvmem_device_get(struct device *dev, const char *dev_name)
502{
503 if (dev->of_node) { /* try dt first */
504 struct nvmem_device *nvmem;
505
506 nvmem = of_nvmem_device_get(dev->of_node, dev_name);
507
508 if (!IS_ERR(nvmem) || PTR_ERR(nvmem) == -EPROBE_DEFER)
509 return nvmem;
510
511 }
512
513 return nvmem_find(dev_name);
514}
515EXPORT_SYMBOL_GPL(nvmem_device_get);
516
517static int devm_nvmem_device_match(struct device *dev, void *res, void *data)
518{
519 struct nvmem_device **nvmem = res;
520
521 if (WARN_ON(!nvmem || !*nvmem))
522 return 0;
523
524 return *nvmem == data;
525}
526
527static void devm_nvmem_device_release(struct device *dev, void *res)
528{
529 nvmem_device_put(*(struct nvmem_device **)res);
530}
531
532/**
533 * devm_nvmem_device_put() - put alredy got nvmem device
534 *
535 * @nvmem: pointer to nvmem device allocated by devm_nvmem_cell_get(),
536 * that needs to be released.
537 */
538void devm_nvmem_device_put(struct device *dev, struct nvmem_device *nvmem)
539{
540 int ret;
541
542 ret = devres_release(dev, devm_nvmem_device_release,
543 devm_nvmem_device_match, nvmem);
544
545 WARN_ON(ret);
546}
547EXPORT_SYMBOL_GPL(devm_nvmem_device_put);
548
549/**
550 * nvmem_device_put() - put alredy got nvmem device
551 *
552 * @nvmem: pointer to nvmem device that needs to be released.
553 */
554void nvmem_device_put(struct nvmem_device *nvmem)
555{
556 __nvmem_device_put(nvmem);
557}
558EXPORT_SYMBOL_GPL(nvmem_device_put);
559
560/**
561 * devm_nvmem_device_get() - Get nvmem cell of device form a given id
562 *
563 * @dev node: Device tree node that uses the nvmem cell
564 * @id: nvmem name in nvmems property.
565 *
566 * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_cell
567 * on success. The nvmem_cell will be freed by the automatically once the
568 * device is freed.
569 */
570struct nvmem_device *devm_nvmem_device_get(struct device *dev, const char *id)
571{
572 struct nvmem_device **ptr, *nvmem;
573
574 ptr = devres_alloc(devm_nvmem_device_release, sizeof(*ptr), GFP_KERNEL);
575 if (!ptr)
576 return ERR_PTR(-ENOMEM);
577
578 nvmem = nvmem_device_get(dev, id);
579 if (!IS_ERR(nvmem)) {
580 *ptr = nvmem;
581 devres_add(dev, ptr);
582 } else {
583 devres_free(ptr);
584 }
585
586 return nvmem;
587}
588EXPORT_SYMBOL_GPL(devm_nvmem_device_get);
589
448static struct nvmem_cell *nvmem_cell_get_from_list(const char *cell_id) 590static struct nvmem_cell *nvmem_cell_get_from_list(const char *cell_id)
449{ 591{
450 struct nvmem_cell *cell = NULL; 592 struct nvmem_cell *cell = NULL;
@@ -806,6 +948,122 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len)
806} 948}
807EXPORT_SYMBOL_GPL(nvmem_cell_write); 949EXPORT_SYMBOL_GPL(nvmem_cell_write);
808 950
951/**
952 * nvmem_device_cell_read() - Read a given nvmem device and cell
953 *
954 * @nvmem: nvmem device to read from.
955 * @info: nvmem cell info to be read.
956 * @buf: buffer pointer which will be populated on successful read.
957 *
958 * Return: length of successful bytes read on success and negative
959 * error code on error.
960 */
961ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
962 struct nvmem_cell_info *info, void *buf)
963{
964 struct nvmem_cell cell;
965 int rc;
966 ssize_t len;
967
968 if (!nvmem || !nvmem->regmap)
969 return -EINVAL;
970
971 rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell);
972 if (IS_ERR_VALUE(rc))
973 return rc;
974
975 rc = __nvmem_cell_read(nvmem, &cell, buf, &len);
976 if (IS_ERR_VALUE(rc))
977 return rc;
978
979 return len;
980}
981EXPORT_SYMBOL_GPL(nvmem_device_cell_read);
982
983/**
984 * nvmem_device_cell_write() - Write cell to a given nvmem device
985 *
986 * @nvmem: nvmem device to be written to.
987 * @info: nvmem cell info to be written
988 * @buf: buffer to be written to cell.
989 *
990 * Return: length of bytes written or negative error code on failure.
991 * */
992int nvmem_device_cell_write(struct nvmem_device *nvmem,
993 struct nvmem_cell_info *info, void *buf)
994{
995 struct nvmem_cell cell;
996 int rc;
997
998 if (!nvmem || !nvmem->regmap)
999 return -EINVAL;
1000
1001 rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell);
1002 if (IS_ERR_VALUE(rc))
1003 return rc;
1004
1005 return nvmem_cell_write(&cell, buf, cell.bytes);
1006}
1007EXPORT_SYMBOL_GPL(nvmem_device_cell_write);
1008
1009/**
1010 * nvmem_device_read() - Read from a given nvmem device
1011 *
1012 * @nvmem: nvmem device to read from.
1013 * @offset: offset in nvmem device.
1014 * @bytes: number of bytes to read.
1015 * @buf: buffer pointer which will be populated on successful read.
1016 *
1017 * Return: length of successful bytes read on success and negative
1018 * error code on error.
1019 */
1020int nvmem_device_read(struct nvmem_device *nvmem,
1021 unsigned int offset,
1022 size_t bytes, void *buf)
1023{
1024 int rc;
1025
1026 if (!nvmem || !nvmem->regmap)
1027 return -EINVAL;
1028
1029 rc = regmap_raw_read(nvmem->regmap, offset, buf, bytes);
1030
1031 if (IS_ERR_VALUE(rc))
1032 return rc;
1033
1034 return bytes;
1035}
1036EXPORT_SYMBOL_GPL(nvmem_device_read);
1037
1038/**
1039 * nvmem_device_write() - Write cell to a given nvmem device
1040 *
1041 * @nvmem: nvmem device to be written to.
1042 * @offset: offset in nvmem device.
1043 * @bytes: number of bytes to write.
1044 * @buf: buffer to be written.
1045 *
1046 * Return: length of bytes written or negative error code on failure.
1047 * */
1048int nvmem_device_write(struct nvmem_device *nvmem,
1049 unsigned int offset,
1050 size_t bytes, void *buf)
1051{
1052 int rc;
1053
1054 if (!nvmem || !nvmem->regmap)
1055 return -EINVAL;
1056
1057 rc = regmap_raw_write(nvmem->regmap, offset, buf, bytes);
1058
1059 if (IS_ERR_VALUE(rc))
1060 return rc;
1061
1062
1063 return bytes;
1064}
1065EXPORT_SYMBOL_GPL(nvmem_device_write);
1066
809static int __init nvmem_init(void) 1067static int __init nvmem_init(void)
810{ 1068{
811 return bus_register(&nvmem_bus_type); 1069 return bus_register(&nvmem_bus_type);