Re: [regression 4.20-rc1, bisected] cpufreq fails to register on db820c

From: Niklas Cassel
Date: Tue Nov 06 2018 - 10:26:13 EST


On Tue, Nov 06, 2018 at 02:37:57PM +0000, Srinivas Kandagatla wrote:
> Hi Niklas,
>
> thanks for reporting this..
>
> I found the issue, DT support seems to be totally broken in NVMEM.
> Will send this fix once you can confirm it works for you!
>
> Can you try this patch!
> ---------------------->cut<--------------------------
>
> Author: Srinivas Kandagatla <srinivas.kandagatla@xxxxxxxxxx>
> Date: Tue Nov 6 14:32:30 2018 +0000
>
> nvmem: core: fix of_nvmem_cell_get()
>
> NVMEM DT support seems to be totally broken after
> e888d445ac33 ("nvmem: resolve cells from DT at registration time")
> Fix this!
>
> Fixes: e888d445ac33 ("nvmem: resolve cells from DT at registration
> time")
> Reported-by: Niklas Cassel <niklas.cassel@xxxxxxxxxx>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@xxxxxxxxxx>
>
> diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
> index 9b18ce90f907..7ae8072f56ae 100644
> --- a/drivers/nvmem/core.c
> +++ b/drivers/nvmem/core.c
> @@ -44,6 +44,7 @@ struct nvmem_cell {
> int bytes;
> int bit_offset;
> int nbits;
> + struct device_node *np;
> struct nvmem_device *nvmem;
> struct list_head node;
> };
> @@ -530,6 +531,7 @@ static int nvmem_add_cells_from_of(struct nvmem_device
> *nvmem)
> return -ENOMEM;
>
> cell->nvmem = nvmem;
> + cell->np = child;
> cell->offset = be32_to_cpup(addr++);
> cell->bytes = be32_to_cpup(addr);
> cell->name = kasprintf(GFP_KERNEL, "%pOFn", child);
> @@ -960,14 +962,13 @@ nvmem_cell_get_from_lookup(struct device *dev, const
> char *con_id)
>
> #if IS_ENABLED(CONFIG_OF)
> static struct nvmem_cell *
> -nvmem_find_cell_by_index(struct nvmem_device *nvmem, int index)
> +nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np)
> {
> struct nvmem_cell *cell = NULL;
> - int i = 0;
>
> mutex_lock(&nvmem_mutex);
> list_for_each_entry(cell, &nvmem->cells, node) {
> - if (index == i++)
> + if (np == cell->np)
> break;
> }
> mutex_unlock(&nvmem_mutex);
> @@ -1001,7 +1002,6 @@ struct nvmem_cell *of_nvmem_cell_get(struct
> device_node *np, const char *id)
> cell_np = of_parse_phandle(np, "nvmem-cells", index);
> if (!cell_np)
> return ERR_PTR(-EINVAL);
> -
> nvmem_np = of_get_next_parent(cell_np);
> if (!nvmem_np)
> return ERR_PTR(-EINVAL);
> @@ -1011,7 +1011,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct
> device_node *np, const char *id)
> if (IS_ERR(nvmem))
> return ERR_CAST(nvmem);
>
> - cell = nvmem_find_cell_by_index(nvmem, index);
> + cell = nvmem_find_cell_by_node(nvmem, cell_np);
> if (!cell) {
> __nvmem_device_put(nvmem);
> return ERR_PTR(-ENOENT);
>

Tested-by: Niklas Cassel <niklas.cassel@xxxxxxxxxx>