Message ID | 20180907100750.14564-14-brgl@bgdev.pl (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | nvmem: rework of the subsystem for non-DT users | expand |
On 07/09/18 11:07, Bartosz Golaszewski wrote: > From: Bartosz Golaszewski <bgolaszewski@baylibre.com> > > Add a way for machine code users to associate devices with nvmem cells. > > Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> > --- > drivers/nvmem/core.c | 143 +++++++++++++++++++++++++++------- > include/linux/nvmem-machine.h | 16 ++++ > 2 files changed, 132 insertions(+), 27 deletions(-) > > diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c > index da7a9d5beb33..9e2f9c993a07 100644 > --- a/drivers/nvmem/core.c > +++ b/drivers/nvmem/core.c > @@ -62,6 +62,9 @@ static DEFINE_IDA(nvmem_ida); > static DEFINE_MUTEX(nvmem_cell_mutex); > static LIST_HEAD(nvmem_cell_tables); > > +static DEFINE_MUTEX(nvmem_lookup_mutex); > +static LIST_HEAD(nvmem_lookup_list); > + > static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); > > #ifdef CONFIG_DEBUG_LOCK_ALLOC > @@ -285,6 +288,18 @@ static struct nvmem_device *of_nvmem_find(struct device_node *nvmem_np) > return to_nvmem_device(d); > } > > +static struct nvmem_device *nvmem_find(const char *name) > +{ > + struct device *d; > + > + d = bus_find_device_by_name(&nvmem_bus_type, NULL, name); > + > + if (!d) > + return NULL; > + > + return to_nvmem_device(d); > +} > + This is removed and added back in same patch, you should consider positioning the caller if possible to avoid any un-necessary changes. > static void nvmem_cell_drop(struct nvmem_cell *cell) > { > mutex_lock(&nvmem_mutex); > @@ -421,6 +436,21 @@ nvmem_find_cell_by_index(struct nvmem_device *nvmem, int index) > return cell; > } > > +static struct nvmem_cell * > +nvmem_cell_get_from_lookup(struct device *dev, const char *con_id) > +{ > + struct nvmem_cell *cell = ERR_PTR(-ENOENT); > + struct nvmem_cell_lookup *lookup; > + struct nvmem_device *nvmem; > + const char *dev_id; > + > + if (!dev) > + return ERR_PTR(-EINVAL); > + > + dev_id = dev_name(dev); > + > + mutex_lock(&nvmem_lookup_mutex); > + > + list_for_each_entry(lookup, &nvmem_lookup_list, node) { > + if ((strcmp(lookup->dev_id, dev_id) == 0) && > + (strcmp(lookup->con_id, con_id) == 0)) { > + /* This is the right entry. */ > + nvmem = __nvmem_device_get(NULL, lookup->nvmem_name); > + if (!nvmem) { > + /* Provider may not be registered yet. */ > + cell = ERR_PTR(-EPROBE_DEFER); > + goto out; > + } > + > + cell = nvmem_find_cell_by_name(nvmem, > + lookup->cell_name); > + if (!cell) > + goto out; Here nvmem refcount has already increased, you should probably fix this! > + } > + } > + > +out: > + mutex_unlock(&nvmem_lookup_mutex); > + return cell; > +} ... > diff --git a/include/linux/nvmem-machine.h b/include/linux/nvmem-machine.h Should be part of nvmem-consumer.h. > index 1e199dfaacab..7859c08934d5 100644 > --- a/include/linux/nvmem-machine.h > +++ b/include/linux/nvmem-machine.h > @@ -26,16 +26,32 @@ struct nvmem_cell_table { > struct list_head node; > }; > > +struct nvmem_cell_lookup { > + const char *nvmem_name; > + const char *cell_name; > + const char *dev_id; > + const char *con_id; > + struct list_head node; > +}; Consider adding kerneldoc to this structure. > + > #if IS_ENABLED(CONFIG_NVMEM) > > void nvmem_add_cell_table(struct nvmem_cell_table *table); > void nvmem_del_cell_table(struct nvmem_cell_table *table); > > +void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries); > +void nvmem_del_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries); > + > #else /* CONFIG_NVMEM */ > > static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {} > static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {} > > +static inline void > +nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries) {} > +static inline void > +nvmem_del_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries) {} > + > #endif /* CONFIG_NVMEM */ > > #endif /* ifndef _LINUX_NVMEM_MACHINE_H */ >
2018-09-10 9:32 GMT+02:00 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>: > > > On 07/09/18 11:07, Bartosz Golaszewski wrote: >> >> From: Bartosz Golaszewski <bgolaszewski@baylibre.com> >> >> Add a way for machine code users to associate devices with nvmem cells. >> >> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> >> --- >> drivers/nvmem/core.c | 143 +++++++++++++++++++++++++++------- >> include/linux/nvmem-machine.h | 16 ++++ >> 2 files changed, 132 insertions(+), 27 deletions(-) >> >> diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c >> index da7a9d5beb33..9e2f9c993a07 100644 >> --- a/drivers/nvmem/core.c >> +++ b/drivers/nvmem/core.c >> @@ -62,6 +62,9 @@ static DEFINE_IDA(nvmem_ida); >> static DEFINE_MUTEX(nvmem_cell_mutex); >> static LIST_HEAD(nvmem_cell_tables); >> +static DEFINE_MUTEX(nvmem_lookup_mutex); >> +static LIST_HEAD(nvmem_lookup_list); >> + >> static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); >> #ifdef CONFIG_DEBUG_LOCK_ALLOC >> @@ -285,6 +288,18 @@ static struct nvmem_device *of_nvmem_find(struct >> device_node *nvmem_np) >> return to_nvmem_device(d); >> } >> +static struct nvmem_device *nvmem_find(const char *name) >> +{ >> + struct device *d; >> + >> + d = bus_find_device_by_name(&nvmem_bus_type, NULL, name); >> + >> + if (!d) >> + return NULL; >> + >> + return to_nvmem_device(d); >> +} >> + > > This is removed and added back in same patch, you should consider > positioning the caller if possible to avoid any un-necessary changes. > >> static void nvmem_cell_drop(struct nvmem_cell *cell) >> { >> mutex_lock(&nvmem_mutex); >> @@ -421,6 +436,21 @@ nvmem_find_cell_by_index(struct nvmem_device *nvmem, >> int index) >> return cell; >> } >> +static struct nvmem_cell * >> +nvmem_cell_get_from_lookup(struct device *dev, const char *con_id) >> +{ >> + struct nvmem_cell *cell = ERR_PTR(-ENOENT); >> + struct nvmem_cell_lookup *lookup; >> + struct nvmem_device *nvmem; >> + const char *dev_id; >> + >> + if (!dev) >> + return ERR_PTR(-EINVAL); >> + >> + dev_id = dev_name(dev); >> + >> + mutex_lock(&nvmem_lookup_mutex); >> + >> + list_for_each_entry(lookup, &nvmem_lookup_list, node) { >> + if ((strcmp(lookup->dev_id, dev_id) == 0) && >> + (strcmp(lookup->con_id, con_id) == 0)) { >> + /* This is the right entry. */ >> + nvmem = __nvmem_device_get(NULL, >> lookup->nvmem_name); >> + if (!nvmem) { >> + /* Provider may not be registered yet. */ >> + cell = ERR_PTR(-EPROBE_DEFER); >> + goto out; >> + } >> + >> + cell = nvmem_find_cell_by_name(nvmem, >> + lookup->cell_name); >> + if (!cell) >> + goto out; > > Here nvmem refcount has already increased, you should probably fix this! Indeed. >> >> + } >> + } >> + >> +out: >> + mutex_unlock(&nvmem_lookup_mutex); >> + return cell; >> +} > > > ... > >> diff --git a/include/linux/nvmem-machine.h b/include/linux/nvmem-machine.h > > > Should be part of nvmem-consumer.h. > If anything, this should probably go to nvmem-provider.h. But I like the gpiolib way of putting machine-specific code into a separate header. Most systems are not interested in these definitions anyway. IMO this is a valid use case where creating a new header makes sense. Bart >> index 1e199dfaacab..7859c08934d5 100644 >> --- a/include/linux/nvmem-machine.h >> +++ b/include/linux/nvmem-machine.h >> @@ -26,16 +26,32 @@ struct nvmem_cell_table { >> struct list_head node; >> }; >> +struct nvmem_cell_lookup { >> + const char *nvmem_name; >> + const char *cell_name; >> + const char *dev_id; >> + const char *con_id; >> + struct list_head node; >> +}; > > > Consider adding kerneldoc to this structure. > > >> + >> #if IS_ENABLED(CONFIG_NVMEM) >> void nvmem_add_cell_table(struct nvmem_cell_table *table); >> void nvmem_del_cell_table(struct nvmem_cell_table *table); >> +void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries, size_t >> nentries); >> +void nvmem_del_cell_lookups(struct nvmem_cell_lookup *entries, size_t >> nentries); >> + >> #else /* CONFIG_NVMEM */ >> static inline void nvmem_add_cell_table(struct nvmem_cell_table >> *table) {} >> static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) >> {} >> +static inline void >> +nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries, size_t >> nentries) {} >> +static inline void >> +nvmem_del_cell_lookups(struct nvmem_cell_lookup *entries, size_t >> nentries) {} >> + >> #endif /* CONFIG_NVMEM */ >> #endif /* ifndef _LINUX_NVMEM_MACHINE_H */ >> >
On Mon, 10 Sep 2018 10:17:48 +0200 Bartosz Golaszewski <brgl@bgdev.pl> wrote: > 2018-09-10 9:32 GMT+02:00 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>: > > > > > > On 07/09/18 11:07, Bartosz Golaszewski wrote: > >> > >> From: Bartosz Golaszewski <bgolaszewski@baylibre.com> > >> > >> Add a way for machine code users to associate devices with nvmem cells. > >> > >> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> > >> --- > >> drivers/nvmem/core.c | 143 +++++++++++++++++++++++++++------- > >> include/linux/nvmem-machine.h | 16 ++++ > >> 2 files changed, 132 insertions(+), 27 deletions(-) > >> > >> diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c > >> index da7a9d5beb33..9e2f9c993a07 100644 > >> --- a/drivers/nvmem/core.c > >> +++ b/drivers/nvmem/core.c > >> @@ -62,6 +62,9 @@ static DEFINE_IDA(nvmem_ida); > >> static DEFINE_MUTEX(nvmem_cell_mutex); > >> static LIST_HEAD(nvmem_cell_tables); > >> +static DEFINE_MUTEX(nvmem_lookup_mutex); > >> +static LIST_HEAD(nvmem_lookup_list); > >> + > >> static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); > >> #ifdef CONFIG_DEBUG_LOCK_ALLOC > >> @@ -285,6 +288,18 @@ static struct nvmem_device *of_nvmem_find(struct > >> device_node *nvmem_np) > >> return to_nvmem_device(d); > >> } > >> +static struct nvmem_device *nvmem_find(const char *name) > >> +{ > >> + struct device *d; > >> + > >> + d = bus_find_device_by_name(&nvmem_bus_type, NULL, name); > >> + > >> + if (!d) > >> + return NULL; > >> + > >> + return to_nvmem_device(d); > >> +} > >> + > > > > This is removed and added back in same patch, you should consider > > positioning the caller if possible to avoid any un-necessary changes. > > > >> static void nvmem_cell_drop(struct nvmem_cell *cell) > >> { > >> mutex_lock(&nvmem_mutex); > >> @@ -421,6 +436,21 @@ nvmem_find_cell_by_index(struct nvmem_device *nvmem, > >> int index) > >> return cell; > >> } > >> +static struct nvmem_cell * > >> +nvmem_cell_get_from_lookup(struct device *dev, const char *con_id) > >> +{ > >> + struct nvmem_cell *cell = ERR_PTR(-ENOENT); > >> + struct nvmem_cell_lookup *lookup; > >> + struct nvmem_device *nvmem; > >> + const char *dev_id; > >> + > >> + if (!dev) > >> + return ERR_PTR(-EINVAL); > >> + > >> + dev_id = dev_name(dev); > >> + > >> + mutex_lock(&nvmem_lookup_mutex); > >> + > >> + list_for_each_entry(lookup, &nvmem_lookup_list, node) { > >> + if ((strcmp(lookup->dev_id, dev_id) == 0) && > >> + (strcmp(lookup->con_id, con_id) == 0)) { > >> + /* This is the right entry. */ > >> + nvmem = __nvmem_device_get(NULL, > >> lookup->nvmem_name); > >> + if (!nvmem) { > >> + /* Provider may not be registered yet. */ > >> + cell = ERR_PTR(-EPROBE_DEFER); > >> + goto out; > >> + } > >> + > >> + cell = nvmem_find_cell_by_name(nvmem, > >> + lookup->cell_name); > >> + if (!cell) > >> + goto out; > > > > Here nvmem refcount has already increased, you should probably fix this! > > Indeed. > > >> > >> + } > >> + } > >> + > >> +out: > >> + mutex_unlock(&nvmem_lookup_mutex); > >> + return cell; > >> +} > > > > > > ... > > > >> diff --git a/include/linux/nvmem-machine.h b/include/linux/nvmem-machine.h > > > > > > Should be part of nvmem-consumer.h. > > > > If anything, this should probably go to nvmem-provider.h. Well, if we get rid of nvmem-machine.h, the cell-lookup stuff should go in nvmem-consumer.h not nvmem-provider.h. On the other hand, everything that is related to cell creation should be placed in nvmem-provider.h. > But I like > the gpiolib way of putting machine-specific code into a separate > header. Most systems are not interested in these definitions anyway. > IMO this is a valid use case where creating a new header makes sense.
On 10/09/18 09:23, Boris Brezillon wrote: > Well, if we get rid of nvmem-machine.h, the cell-lookup stuff > should go in nvmem-consumer.h not nvmem-provider.h. On the other hand, > everything that is related to cell creation should be placed in > nvmem-provider.h. Yes, this is how it should be! --srini
2018-09-10 10:55 GMT+02:00 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>: > > > On 10/09/18 09:23, Boris Brezillon wrote: >> >> Well, if we get rid of nvmem-machine.h, the cell-lookup stuff >> should go in nvmem-consumer.h not nvmem-provider.h. On the other hand, >> everything that is related to cell creation should be placed in >> nvmem-provider.h. > > Yes, this is how it should be! > Any actual reason for not putting these definitions into a separate 'machine' header? This approach is currently used by gpio, pinctrl, iio and regulator framework because most systems use either DT or ACPI and don't need to pull in any stuff aimed at board files. Bart
On Mon, 10 Sep 2018 11:45:48 +0200 Bartosz Golaszewski <brgl@bgdev.pl> wrote: > 2018-09-10 10:55 GMT+02:00 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>: > > > > > > On 10/09/18 09:23, Boris Brezillon wrote: > >> > >> Well, if we get rid of nvmem-machine.h, the cell-lookup stuff > >> should go in nvmem-consumer.h not nvmem-provider.h. On the other hand, > >> everything that is related to cell creation should be placed in > >> nvmem-provider.h. > > > > Yes, this is how it should be! > > > > Any actual reason for not putting these definitions into a separate > 'machine' header? This approach is currently used by gpio, pinctrl, > iio and regulator framework because most systems use either DT or ACPI > and don't need to pull in any stuff aimed at board files. I'm perfectly fine with the separate header file, all I'm saying is, if Srinivas does not want nvmem-machine.h, definitions should be placed in nvmem-provider.h or nvmem-consumer.h depending on who they're meant to be used by (providers or consumers).
On 10/09/18 10:45, Bartosz Golaszewski wrote: >> Yes, this is how it should be! >> > Any actual reason for not putting these definitions into a separate > 'machine' header? This approach is currently used by gpio, pinctrl, > iio and regulator framework because most systems use either DT or ACPI > and don't need to pull in any stuff aimed at board files. I don't want to create header files specific to usecase! Lets keep it simple! --srini
2018-09-10 11:50 GMT+02:00 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>: > > > On 10/09/18 10:45, Bartosz Golaszewski wrote: >>> >>> Yes, this is how it should be! >>> >> Any actual reason for not putting these definitions into a separate >> 'machine' header? This approach is currently used by gpio, pinctrl, >> iio and regulator framework because most systems use either DT or ACPI >> and don't need to pull in any stuff aimed at board files. > > > I don't want to create header files specific to usecase! > Lets keep it simple! > I won't argue this point anymore, but I disagree. This is not specific to a usecase but to a whole family of users that need to a) define nvmem cells without knowing the provider and b) associate them with consumers. Something normal providers and consumers are not bothered by, thus a new header file would be in order. But as you wish... Bart
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index da7a9d5beb33..9e2f9c993a07 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -62,6 +62,9 @@ static DEFINE_IDA(nvmem_ida); static DEFINE_MUTEX(nvmem_cell_mutex); static LIST_HEAD(nvmem_cell_tables); +static DEFINE_MUTEX(nvmem_lookup_mutex); +static LIST_HEAD(nvmem_lookup_list); + static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); #ifdef CONFIG_DEBUG_LOCK_ALLOC @@ -285,6 +288,18 @@ static struct nvmem_device *of_nvmem_find(struct device_node *nvmem_np) return to_nvmem_device(d); } +static struct nvmem_device *nvmem_find(const char *name) +{ + struct device *d; + + d = bus_find_device_by_name(&nvmem_bus_type, NULL, name); + + if (!d) + return NULL; + + return to_nvmem_device(d); +} + static void nvmem_cell_drop(struct nvmem_cell *cell) { mutex_lock(&nvmem_mutex); @@ -421,6 +436,21 @@ nvmem_find_cell_by_index(struct nvmem_device *nvmem, int index) return cell; } +static struct nvmem_cell * +nvmem_find_cell_by_name(struct nvmem_device *nvmem, const char *cell_id) +{ + struct nvmem_cell *cell = NULL; + + mutex_lock(&nvmem_mutex); + list_for_each_entry(cell, &nvmem->cells, node) { + if (strcmp(cell_id, cell->name) == 0) + break; + } + mutex_unlock(&nvmem_mutex); + + return cell; +} + static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) { struct device_node *parent, *child; @@ -691,22 +721,16 @@ int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem) } EXPORT_SYMBOL(devm_nvmem_unregister); -static struct nvmem_device *__nvmem_device_get(struct device_node *np) +static struct nvmem_device * +__nvmem_device_get(struct device_node *np, const char *name) { struct nvmem_device *nvmem = NULL; - if (!np) - return ERR_PTR(-EINVAL); - mutex_lock(&nvmem_mutex); - - nvmem = of_nvmem_find(np); - if (!nvmem) { - mutex_unlock(&nvmem_mutex); - return ERR_PTR(-EPROBE_DEFER); - } - + nvmem = np ? of_nvmem_find(np) : nvmem_find(name); mutex_unlock(&nvmem_mutex); + if (!nvmem) + return ERR_PTR(-EPROBE_DEFER); if (!try_module_get(nvmem->owner)) { dev_err(&nvmem->dev, @@ -726,18 +750,6 @@ static void __nvmem_device_put(struct nvmem_device *nvmem) kref_put(&nvmem->refcnt, nvmem_device_release); } -static struct nvmem_device *nvmem_find(const char *name) -{ - struct device *d; - - d = bus_find_device_by_name(&nvmem_bus_type, NULL, name); - - if (!d) - return NULL; - - return to_nvmem_device(d); -} - #if IS_ENABLED(CONFIG_OF) /** * of_nvmem_device_get() - Get nvmem device from a given id @@ -760,7 +772,7 @@ struct nvmem_device *of_nvmem_device_get(struct device_node *np, const char *id) if (!nvmem_np) return ERR_PTR(-EINVAL); - return __nvmem_device_get(nvmem_np); + return __nvmem_device_get(nvmem_np, NULL); } EXPORT_SYMBOL_GPL(of_nvmem_device_get); #endif @@ -897,7 +909,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, if (!nvmem_np) return ERR_PTR(-EINVAL); - nvmem = __nvmem_device_get(nvmem_np); + nvmem = __nvmem_device_get(nvmem_np, NULL); of_node_put(nvmem_np); if (IS_ERR(nvmem)) return ERR_CAST(nvmem); @@ -913,6 +925,44 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, EXPORT_SYMBOL_GPL(of_nvmem_cell_get); #endif +static struct nvmem_cell * +nvmem_cell_get_from_lookup(struct device *dev, const char *con_id) +{ + struct nvmem_cell *cell = ERR_PTR(-ENOENT); + struct nvmem_cell_lookup *lookup; + struct nvmem_device *nvmem; + const char *dev_id; + + if (!dev) + return ERR_PTR(-EINVAL); + + dev_id = dev_name(dev); + + mutex_lock(&nvmem_lookup_mutex); + + list_for_each_entry(lookup, &nvmem_lookup_list, node) { + if ((strcmp(lookup->dev_id, dev_id) == 0) && + (strcmp(lookup->con_id, con_id) == 0)) { + /* This is the right entry. */ + nvmem = __nvmem_device_get(NULL, lookup->nvmem_name); + if (!nvmem) { + /* Provider may not be registered yet. */ + cell = ERR_PTR(-EPROBE_DEFER); + goto out; + } + + cell = nvmem_find_cell_by_name(nvmem, + lookup->cell_name); + if (!cell) + goto out; + } + } + +out: + mutex_unlock(&nvmem_lookup_mutex); + return cell; +} + /** * nvmem_cell_get() - Get nvmem cell of device form a given cell name * @@ -925,10 +975,14 @@ EXPORT_SYMBOL_GPL(of_nvmem_cell_get); */ struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *cell_id) { - if (!dev->of_node) + if (dev->of_node) + return of_nvmem_cell_get(dev->of_node, cell_id); + + /* Only allow empty cell_id for DT systems. */ + if (!cell_id) return ERR_PTR(-EINVAL); - return of_nvmem_cell_get(dev->of_node, cell_id); + return nvmem_cell_get_from_lookup(dev, cell_id); } EXPORT_SYMBOL_GPL(nvmem_cell_get); @@ -1300,6 +1354,41 @@ void nvmem_del_cell_table(struct nvmem_cell_table *table) } EXPORT_SYMBOL_GPL(nvmem_del_cell_table); +/** + * nvmem_add_cell_lookups() - register a list of cell lookup entries + * + * @entries: array of cell lookup entries + * @nentries: number of cell lookup entries in the array + */ +void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries) +{ + int i; + + mutex_lock(&nvmem_lookup_mutex); + for (i = 0; i < nentries; i++) + list_add_tail(&entries[i].node, &nvmem_lookup_list); + mutex_unlock(&nvmem_lookup_mutex); +} +EXPORT_SYMBOL_GPL(nvmem_add_cell_lookups); + +/** + * nvmem_del_cell_lookups() - remove a list of previously added cell lookup + * entries + * + * @entries: array of cell lookup entries + * @nentries: number of cell lookup entries in the array + */ +void nvmem_del_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries) +{ + int i; + + mutex_lock(&nvmem_lookup_mutex); + for (i = 0; i < nentries; i++) + list_del(&entries[i].node); + mutex_unlock(&nvmem_lookup_mutex); +} +EXPORT_SYMBOL_GPL(nvmem_del_cell_lookups); + /** * nvmem_dev_name() - Get the name of a given nvmem device. * diff --git a/include/linux/nvmem-machine.h b/include/linux/nvmem-machine.h index 1e199dfaacab..7859c08934d5 100644 --- a/include/linux/nvmem-machine.h +++ b/include/linux/nvmem-machine.h @@ -26,16 +26,32 @@ struct nvmem_cell_table { struct list_head node; }; +struct nvmem_cell_lookup { + const char *nvmem_name; + const char *cell_name; + const char *dev_id; + const char *con_id; + struct list_head node; +}; + #if IS_ENABLED(CONFIG_NVMEM) void nvmem_add_cell_table(struct nvmem_cell_table *table); void nvmem_del_cell_table(struct nvmem_cell_table *table); +void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries); +void nvmem_del_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries); + #else /* CONFIG_NVMEM */ static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {} static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {} +static inline void +nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries) {} +static inline void +nvmem_del_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries) {} + #endif /* CONFIG_NVMEM */ #endif /* ifndef _LINUX_NVMEM_MACHINE_H */