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

nvmem: core: fix regression in of_nvmem_cell_get()

NVMEM DT support seems to be totally broken after
commit e888d445ac33 ("nvmem: resolve cells from DT at registration time")
Fix this!

Index used in of_nvmem_cell_get() to find cell is specific to
consumer, It can not be used for searching the cell in provider.
Use device_node instead of this to find the matching cell in device
tree case.

Fixes: e888d445ac33 ("nvmem: resolve cells from DT at registration time")
Reported-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Tested-by: Niklas Cassel <niklas.cassel@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Srinivas Kandagatla and committed by
Greg Kroah-Hartman
0749aa25 7c973012

+6 -4
+6 -4
drivers/nvmem/core.c
··· 44 44 int bytes; 45 45 int bit_offset; 46 46 int nbits; 47 + struct device_node *np; 47 48 struct nvmem_device *nvmem; 48 49 struct list_head node; 49 50 }; ··· 299 298 mutex_lock(&nvmem_mutex); 300 299 list_del(&cell->node); 301 300 mutex_unlock(&nvmem_mutex); 301 + of_node_put(cell->np); 302 302 kfree(cell->name); 303 303 kfree(cell); 304 304 } ··· 532 530 return -ENOMEM; 533 531 534 532 cell->nvmem = nvmem; 533 + cell->np = of_node_get(child); 535 534 cell->offset = be32_to_cpup(addr++); 536 535 cell->bytes = be32_to_cpup(addr); 537 536 cell->name = kasprintf(GFP_KERNEL, "%pOFn", child); ··· 963 960 964 961 #if IS_ENABLED(CONFIG_OF) 965 962 static struct nvmem_cell * 966 - nvmem_find_cell_by_index(struct nvmem_device *nvmem, int index) 963 + nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np) 967 964 { 968 965 struct nvmem_cell *cell = NULL; 969 - int i = 0; 970 966 971 967 mutex_lock(&nvmem_mutex); 972 968 list_for_each_entry(cell, &nvmem->cells, node) { 973 - if (index == i++) 969 + if (np == cell->np) 974 970 break; 975 971 } 976 972 mutex_unlock(&nvmem_mutex); ··· 1013 1011 if (IS_ERR(nvmem)) 1014 1012 return ERR_CAST(nvmem); 1015 1013 1016 - cell = nvmem_find_cell_by_index(nvmem, index); 1014 + cell = nvmem_find_cell_by_node(nvmem, cell_np); 1017 1015 if (!cell) { 1018 1016 __nvmem_device_put(nvmem); 1019 1017 return ERR_PTR(-ENOENT);