All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] nvmem: rework of the subsystem for non-DT users
@ 2018-09-05  9:57 ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Boris Brezillon, Andrew Lunn, Alban Bedel,
	Maxime Ripard
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

This series contains nvmem framework changes prerequisite for further
development of my previous series[1] that aims at removal of the
platform data struct from at24 EEPROM driver.

First we remove unused APIs and the global cell list. We then switch
to using kref instead of manual user counting. Next we simplify the
provider unregistration by removing the return value from
nvmem_unregister().

Next three patches improve the framework by adding a notifier chain
for future use and fixing the issue with nvmem device names.

Finally we add support for cell definitions, cell lookups and make
DT systems resolve the nvmem cells during provider's registration.

Last patch just uses the SPDX license identifiers.

Tested both DT and non-DT use cases.

[1] https://lkml.org/lkml/2018/8/10/149

Bartosz Golaszewski (13):
  nvmem: remove unused APIs
  nvmem: remove the global cell list
  nvmem: use kref
  nvmem: lpc18xx_eeprom: use devm_nvmem_register()
  nvmem: change the signature of nvmem_unregister()
  nvmem: provide nvmem_dev_name()
  nvmem: remove the name field from struct nvmem_device
  nvmem: add a notifier chain
  nvmem: add support for cell info
  nvmem: resolve cells from DT at registration time
  nvmem: add support for cell lookups from machine code
  Documentation: nvmem: document cell tables and lookup entries
  nvmem: use SPDX license identifiers

 Documentation/nvmem/nvmem.txt  |  30 ++
 MAINTAINERS                    |   1 +
 drivers/nvmem/core.c           | 650 ++++++++++++++++++---------------
 drivers/nvmem/lpc18xx_eeprom.c |   6 +-
 include/linux/nvmem-consumer.h |  50 ++-
 include/linux/nvmem-machine.h  |  56 +++
 include/linux/nvmem-provider.h |  22 +-
 7 files changed, 465 insertions(+), 350 deletions(-)
 create mode 100644 include/linux/nvmem-machine.h

-- 
2.18.0


^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 00/13] nvmem: rework of the subsystem for non-DT users
@ 2018-09-05  9:57 ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

This series contains nvmem framework changes prerequisite for further
development of my previous series[1] that aims at removal of the
platform data struct from at24 EEPROM driver.

First we remove unused APIs and the global cell list. We then switch
to using kref instead of manual user counting. Next we simplify the
provider unregistration by removing the return value from
nvmem_unregister().

Next three patches improve the framework by adding a notifier chain
for future use and fixing the issue with nvmem device names.

Finally we add support for cell definitions, cell lookups and make
DT systems resolve the nvmem cells during provider's registration.

Last patch just uses the SPDX license identifiers.

Tested both DT and non-DT use cases.

[1] https://lkml.org/lkml/2018/8/10/149

Bartosz Golaszewski (13):
  nvmem: remove unused APIs
  nvmem: remove the global cell list
  nvmem: use kref
  nvmem: lpc18xx_eeprom: use devm_nvmem_register()
  nvmem: change the signature of nvmem_unregister()
  nvmem: provide nvmem_dev_name()
  nvmem: remove the name field from struct nvmem_device
  nvmem: add a notifier chain
  nvmem: add support for cell info
  nvmem: resolve cells from DT at registration time
  nvmem: add support for cell lookups from machine code
  Documentation: nvmem: document cell tables and lookup entries
  nvmem: use SPDX license identifiers

 Documentation/nvmem/nvmem.txt  |  30 ++
 MAINTAINERS                    |   1 +
 drivers/nvmem/core.c           | 650 ++++++++++++++++++---------------
 drivers/nvmem/lpc18xx_eeprom.c |   6 +-
 include/linux/nvmem-consumer.h |  50 ++-
 include/linux/nvmem-machine.h  |  56 +++
 include/linux/nvmem-provider.h |  22 +-
 7 files changed, 465 insertions(+), 350 deletions(-)
 create mode 100644 include/linux/nvmem-machine.h

-- 
2.18.0

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 01/13] nvmem: remove unused APIs
  2018-09-05  9:57 ` Bartosz Golaszewski
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Boris Brezillon, Andrew Lunn, Alban Bedel,
	Maxime Ripard
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Remove all APIs dealing with nvmem_cell_info. There are no users and
this part of the subsystem will be reworked.

This patch temprarily disables support for non-DT users.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c           | 212 ++-------------------------------
 include/linux/nvmem-consumer.h |  26 ----
 include/linux/nvmem-provider.h |  13 --
 3 files changed, 12 insertions(+), 239 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index aa1657831b70..bb475c2688f9 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -282,23 +282,6 @@ static struct nvmem_device *of_nvmem_find(struct device_node *nvmem_np)
 	return to_nvmem_device(d);
 }
 
-static struct nvmem_cell *nvmem_find_cell(const char *cell_id)
-{
-	struct nvmem_cell *p;
-
-	mutex_lock(&nvmem_cells_mutex);
-
-	list_for_each_entry(p, &nvmem_cells, node)
-		if (!strcmp(p->name, cell_id)) {
-			mutex_unlock(&nvmem_cells_mutex);
-			return p;
-		}
-
-	mutex_unlock(&nvmem_cells_mutex);
-
-	return NULL;
-}
-
 static void nvmem_cell_drop(struct nvmem_cell *cell)
 {
 	mutex_lock(&nvmem_cells_mutex);
@@ -326,82 +309,6 @@ static void nvmem_cell_add(struct nvmem_cell *cell)
 	mutex_unlock(&nvmem_cells_mutex);
 }
 
-static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem,
-				   const struct nvmem_cell_info *info,
-				   struct nvmem_cell *cell)
-{
-	cell->nvmem = nvmem;
-	cell->offset = info->offset;
-	cell->bytes = info->bytes;
-	cell->name = info->name;
-
-	cell->bit_offset = info->bit_offset;
-	cell->nbits = info->nbits;
-
-	if (cell->nbits)
-		cell->bytes = DIV_ROUND_UP(cell->nbits + cell->bit_offset,
-					   BITS_PER_BYTE);
-
-	if (!IS_ALIGNED(cell->offset, nvmem->stride)) {
-		dev_err(&nvmem->dev,
-			"cell %s unaligned to nvmem stride %d\n",
-			cell->name, nvmem->stride);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/**
- * nvmem_add_cells() - Add cell information to an nvmem device
- *
- * @nvmem: nvmem device to add cells to.
- * @info: nvmem cell info to add to the device
- * @ncells: number of cells in info
- *
- * Return: 0 or negative error code on failure.
- */
-int nvmem_add_cells(struct nvmem_device *nvmem,
-		    const struct nvmem_cell_info *info,
-		    int ncells)
-{
-	struct nvmem_cell **cells;
-	int i, rval;
-
-	cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL);
-	if (!cells)
-		return -ENOMEM;
-
-	for (i = 0; i < ncells; i++) {
-		cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL);
-		if (!cells[i]) {
-			rval = -ENOMEM;
-			goto err;
-		}
-
-		rval = nvmem_cell_info_to_nvmem_cell(nvmem, &info[i], cells[i]);
-		if (rval) {
-			kfree(cells[i]);
-			goto err;
-		}
-
-		nvmem_cell_add(cells[i]);
-	}
-
-	/* remove tmp array */
-	kfree(cells);
-
-	return 0;
-err:
-	while (i--)
-		nvmem_cell_drop(cells[i]);
-
-	kfree(cells);
-
-	return rval;
-}
-EXPORT_SYMBOL_GPL(nvmem_add_cells);
-
 /*
  * nvmem_setup_compat() - Create an additional binary entry in
  * drivers sys directory, to be backwards compatible with the older
@@ -516,9 +423,6 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 			goto err_device_del;
 	}
 
-	if (config->cells)
-		nvmem_add_cells(nvmem, config->cells, config->ncells);
-
 	return nvmem;
 
 err_device_del:
@@ -618,32 +522,19 @@ 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,
-					       struct nvmem_cell **cellp,
-					       const char *cell_id)
+static struct nvmem_device *__nvmem_device_get(struct device_node *np)
 {
 	struct nvmem_device *nvmem = NULL;
 
-	mutex_lock(&nvmem_mutex);
-
-	if (np) {
-		nvmem = of_nvmem_find(np);
-		if (!nvmem) {
-			mutex_unlock(&nvmem_mutex);
-			return ERR_PTR(-EPROBE_DEFER);
-		}
-	} else {
-		struct nvmem_cell *cell = nvmem_find_cell(cell_id);
+	if (!np)
+		return ERR_PTR(-EINVAL);
 
-		if (cell) {
-			nvmem = cell->nvmem;
-			*cellp = cell;
-		}
+	mutex_lock(&nvmem_mutex);
 
-		if (!nvmem) {
-			mutex_unlock(&nvmem_mutex);
-			return ERR_PTR(-ENOENT);
-		}
+	nvmem = of_nvmem_find(np);
+	if (!nvmem) {
+		mutex_unlock(&nvmem_mutex);
+		return ERR_PTR(-EPROBE_DEFER);
 	}
 
 	nvmem->users++;
@@ -706,7 +597,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, NULL, NULL);
+	return __nvmem_device_get(nvmem_np);
 }
 EXPORT_SYMBOL_GPL(of_nvmem_device_get);
 #endif
@@ -810,18 +701,6 @@ struct nvmem_device *devm_nvmem_device_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL_GPL(devm_nvmem_device_get);
 
-static struct nvmem_cell *nvmem_cell_get_from_list(const char *cell_id)
-{
-	struct nvmem_cell *cell = NULL;
-	struct nvmem_device *nvmem;
-
-	nvmem = __nvmem_device_get(NULL, &cell, cell_id);
-	if (IS_ERR(nvmem))
-		return ERR_CAST(nvmem);
-
-	return cell;
-}
-
 #if IS_ENABLED(CONFIG_OF)
 /**
  * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
@@ -857,7 +736,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, NULL, NULL);
+	nvmem = __nvmem_device_get(nvmem_np);
 	of_node_put(nvmem_np);
 	if (IS_ERR(nvmem))
 		return ERR_CAST(nvmem);
@@ -926,19 +805,10 @@ EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
  */
 struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *cell_id)
 {
-	struct nvmem_cell *cell;
-
-	if (dev->of_node) { /* try dt first */
-		cell = of_nvmem_cell_get(dev->of_node, cell_id);
-		if (!IS_ERR(cell) || PTR_ERR(cell) == -EPROBE_DEFER)
-			return cell;
-	}
-
-	/* NULL cell_id only allowed for device tree; invalid otherwise */
-	if (!cell_id)
+	if (!dev->of_node)
 		return ERR_PTR(-EINVAL);
 
-	return nvmem_cell_get_from_list(cell_id);
+	return of_nvmem_cell_get(dev->of_node, cell_id);
 }
 EXPORT_SYMBOL_GPL(nvmem_cell_get);
 
@@ -1227,64 +1097,6 @@ int nvmem_cell_read_u32(struct device *dev, const char *cell_id, u32 *val)
 }
 EXPORT_SYMBOL_GPL(nvmem_cell_read_u32);
 
-/**
- * nvmem_device_cell_read() - Read a given nvmem device and cell
- *
- * @nvmem: nvmem device to read from.
- * @info: nvmem cell info to be read.
- * @buf: buffer pointer which will be populated on successful read.
- *
- * Return: length of successful bytes read on success and negative
- * error code on error.
- */
-ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
-			   struct nvmem_cell_info *info, void *buf)
-{
-	struct nvmem_cell cell;
-	int rc;
-	ssize_t len;
-
-	if (!nvmem)
-		return -EINVAL;
-
-	rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell);
-	if (rc)
-		return rc;
-
-	rc = __nvmem_cell_read(nvmem, &cell, buf, &len);
-	if (rc)
-		return rc;
-
-	return len;
-}
-EXPORT_SYMBOL_GPL(nvmem_device_cell_read);
-
-/**
- * nvmem_device_cell_write() - Write cell to a given nvmem device
- *
- * @nvmem: nvmem device to be written to.
- * @info: nvmem cell info to be written.
- * @buf: buffer to be written to cell.
- *
- * Return: length of bytes written or negative error code on failure.
- * */
-int nvmem_device_cell_write(struct nvmem_device *nvmem,
-			    struct nvmem_cell_info *info, void *buf)
-{
-	struct nvmem_cell cell;
-	int rc;
-
-	if (!nvmem)
-		return -EINVAL;
-
-	rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell);
-	if (rc)
-		return rc;
-
-	return nvmem_cell_write(&cell, buf, cell.bytes);
-}
-EXPORT_SYMBOL_GPL(nvmem_device_cell_write);
-
 /**
  * nvmem_device_read() - Read from a given nvmem device
  *
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 4e85447f7860..7e9fb5a19d91 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -21,14 +21,6 @@ struct device_node;
 struct nvmem_cell;
 struct nvmem_device;
 
-struct nvmem_cell_info {
-	const char		*name;
-	unsigned int		offset;
-	unsigned int		bytes;
-	unsigned int		bit_offset;
-	unsigned int		nbits;
-};
-
 #if IS_ENABLED(CONFIG_NVMEM)
 
 /* Cell based interface */
@@ -50,10 +42,6 @@ int nvmem_device_read(struct nvmem_device *nvmem, unsigned int offset,
 		      size_t bytes, void *buf);
 int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,
 		       size_t bytes, void *buf);
-ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
-			   struct nvmem_cell_info *info, void *buf);
-int nvmem_device_cell_write(struct nvmem_device *nvmem,
-			    struct nvmem_cell_info *info, void *buf);
 
 #else
 
@@ -116,20 +104,6 @@ static inline void devm_nvmem_device_put(struct device *dev,
 {
 }
 
-static inline ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
-					 struct nvmem_cell_info *info,
-					 void *buf)
-{
-	return -ENOSYS;
-}
-
-static inline int nvmem_device_cell_write(struct nvmem_device *nvmem,
-					  struct nvmem_cell_info *info,
-					  void *buf)
-{
-	return -ENOSYS;
-}
-
 static inline int nvmem_device_read(struct nvmem_device *nvmem,
 				    unsigned int offset, size_t bytes,
 				    void *buf)
diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
index 24def6ad09bb..cc8556e3c825 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -16,7 +16,6 @@
 #include <linux/errno.h>
 
 struct nvmem_device;
-struct nvmem_cell_info;
 typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset,
 				void *val, size_t bytes);
 typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
@@ -52,8 +51,6 @@ struct nvmem_config {
 	const char		*name;
 	int			id;
 	struct module		*owner;
-	const struct nvmem_cell_info	*cells;
-	int			ncells;
 	bool			read_only;
 	bool			root_only;
 	nvmem_reg_read_t	reg_read;
@@ -77,9 +74,6 @@ struct nvmem_device *devm_nvmem_register(struct device *dev,
 
 int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem);
 
-int nvmem_add_cells(struct nvmem_device *nvmem,
-		    const struct nvmem_cell_info *info,
-		    int ncells);
 #else
 
 static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
@@ -105,12 +99,5 @@ devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem)
 
 }
 
-static inline int nvmem_add_cells(struct nvmem_device *nvmem,
-				  const struct nvmem_cell_info *info,
-				  int ncells)
-{
-	return -ENOSYS;
-}
-
 #endif /* CONFIG_NVMEM */
 #endif  /* ifndef _LINUX_NVMEM_PROVIDER_H */
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 01/13] nvmem: remove unused APIs
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Remove all APIs dealing with nvmem_cell_info. There are no users and
this part of the subsystem will be reworked.

This patch temprarily disables support for non-DT users.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c           | 212 ++-------------------------------
 include/linux/nvmem-consumer.h |  26 ----
 include/linux/nvmem-provider.h |  13 --
 3 files changed, 12 insertions(+), 239 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index aa1657831b70..bb475c2688f9 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -282,23 +282,6 @@ static struct nvmem_device *of_nvmem_find(struct device_node *nvmem_np)
 	return to_nvmem_device(d);
 }
 
-static struct nvmem_cell *nvmem_find_cell(const char *cell_id)
-{
-	struct nvmem_cell *p;
-
-	mutex_lock(&nvmem_cells_mutex);
-
-	list_for_each_entry(p, &nvmem_cells, node)
-		if (!strcmp(p->name, cell_id)) {
-			mutex_unlock(&nvmem_cells_mutex);
-			return p;
-		}
-
-	mutex_unlock(&nvmem_cells_mutex);
-
-	return NULL;
-}
-
 static void nvmem_cell_drop(struct nvmem_cell *cell)
 {
 	mutex_lock(&nvmem_cells_mutex);
@@ -326,82 +309,6 @@ static void nvmem_cell_add(struct nvmem_cell *cell)
 	mutex_unlock(&nvmem_cells_mutex);
 }
 
-static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem,
-				   const struct nvmem_cell_info *info,
-				   struct nvmem_cell *cell)
-{
-	cell->nvmem = nvmem;
-	cell->offset = info->offset;
-	cell->bytes = info->bytes;
-	cell->name = info->name;
-
-	cell->bit_offset = info->bit_offset;
-	cell->nbits = info->nbits;
-
-	if (cell->nbits)
-		cell->bytes = DIV_ROUND_UP(cell->nbits + cell->bit_offset,
-					   BITS_PER_BYTE);
-
-	if (!IS_ALIGNED(cell->offset, nvmem->stride)) {
-		dev_err(&nvmem->dev,
-			"cell %s unaligned to nvmem stride %d\n",
-			cell->name, nvmem->stride);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/**
- * nvmem_add_cells() - Add cell information to an nvmem device
- *
- * @nvmem: nvmem device to add cells to.
- * @info: nvmem cell info to add to the device
- * @ncells: number of cells in info
- *
- * Return: 0 or negative error code on failure.
- */
-int nvmem_add_cells(struct nvmem_device *nvmem,
-		    const struct nvmem_cell_info *info,
-		    int ncells)
-{
-	struct nvmem_cell **cells;
-	int i, rval;
-
-	cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL);
-	if (!cells)
-		return -ENOMEM;
-
-	for (i = 0; i < ncells; i++) {
-		cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL);
-		if (!cells[i]) {
-			rval = -ENOMEM;
-			goto err;
-		}
-
-		rval = nvmem_cell_info_to_nvmem_cell(nvmem, &info[i], cells[i]);
-		if (rval) {
-			kfree(cells[i]);
-			goto err;
-		}
-
-		nvmem_cell_add(cells[i]);
-	}
-
-	/* remove tmp array */
-	kfree(cells);
-
-	return 0;
-err:
-	while (i--)
-		nvmem_cell_drop(cells[i]);
-
-	kfree(cells);
-
-	return rval;
-}
-EXPORT_SYMBOL_GPL(nvmem_add_cells);
-
 /*
  * nvmem_setup_compat() - Create an additional binary entry in
  * drivers sys directory, to be backwards compatible with the older
@@ -516,9 +423,6 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 			goto err_device_del;
 	}
 
-	if (config->cells)
-		nvmem_add_cells(nvmem, config->cells, config->ncells);
-
 	return nvmem;
 
 err_device_del:
@@ -618,32 +522,19 @@ 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,
-					       struct nvmem_cell **cellp,
-					       const char *cell_id)
+static struct nvmem_device *__nvmem_device_get(struct device_node *np)
 {
 	struct nvmem_device *nvmem = NULL;
 
-	mutex_lock(&nvmem_mutex);
-
-	if (np) {
-		nvmem = of_nvmem_find(np);
-		if (!nvmem) {
-			mutex_unlock(&nvmem_mutex);
-			return ERR_PTR(-EPROBE_DEFER);
-		}
-	} else {
-		struct nvmem_cell *cell = nvmem_find_cell(cell_id);
+	if (!np)
+		return ERR_PTR(-EINVAL);
 
-		if (cell) {
-			nvmem = cell->nvmem;
-			*cellp = cell;
-		}
+	mutex_lock(&nvmem_mutex);
 
-		if (!nvmem) {
-			mutex_unlock(&nvmem_mutex);
-			return ERR_PTR(-ENOENT);
-		}
+	nvmem = of_nvmem_find(np);
+	if (!nvmem) {
+		mutex_unlock(&nvmem_mutex);
+		return ERR_PTR(-EPROBE_DEFER);
 	}
 
 	nvmem->users++;
@@ -706,7 +597,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, NULL, NULL);
+	return __nvmem_device_get(nvmem_np);
 }
 EXPORT_SYMBOL_GPL(of_nvmem_device_get);
 #endif
@@ -810,18 +701,6 @@ struct nvmem_device *devm_nvmem_device_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL_GPL(devm_nvmem_device_get);
 
-static struct nvmem_cell *nvmem_cell_get_from_list(const char *cell_id)
-{
-	struct nvmem_cell *cell = NULL;
-	struct nvmem_device *nvmem;
-
-	nvmem = __nvmem_device_get(NULL, &cell, cell_id);
-	if (IS_ERR(nvmem))
-		return ERR_CAST(nvmem);
-
-	return cell;
-}
-
 #if IS_ENABLED(CONFIG_OF)
 /**
  * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
@@ -857,7 +736,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, NULL, NULL);
+	nvmem = __nvmem_device_get(nvmem_np);
 	of_node_put(nvmem_np);
 	if (IS_ERR(nvmem))
 		return ERR_CAST(nvmem);
@@ -926,19 +805,10 @@ EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
  */
 struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *cell_id)
 {
-	struct nvmem_cell *cell;
-
-	if (dev->of_node) { /* try dt first */
-		cell = of_nvmem_cell_get(dev->of_node, cell_id);
-		if (!IS_ERR(cell) || PTR_ERR(cell) == -EPROBE_DEFER)
-			return cell;
-	}
-
-	/* NULL cell_id only allowed for device tree; invalid otherwise */
-	if (!cell_id)
+	if (!dev->of_node)
 		return ERR_PTR(-EINVAL);
 
-	return nvmem_cell_get_from_list(cell_id);
+	return of_nvmem_cell_get(dev->of_node, cell_id);
 }
 EXPORT_SYMBOL_GPL(nvmem_cell_get);
 
@@ -1227,64 +1097,6 @@ int nvmem_cell_read_u32(struct device *dev, const char *cell_id, u32 *val)
 }
 EXPORT_SYMBOL_GPL(nvmem_cell_read_u32);
 
-/**
- * nvmem_device_cell_read() - Read a given nvmem device and cell
- *
- * @nvmem: nvmem device to read from.
- * @info: nvmem cell info to be read.
- * @buf: buffer pointer which will be populated on successful read.
- *
- * Return: length of successful bytes read on success and negative
- * error code on error.
- */
-ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
-			   struct nvmem_cell_info *info, void *buf)
-{
-	struct nvmem_cell cell;
-	int rc;
-	ssize_t len;
-
-	if (!nvmem)
-		return -EINVAL;
-
-	rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell);
-	if (rc)
-		return rc;
-
-	rc = __nvmem_cell_read(nvmem, &cell, buf, &len);
-	if (rc)
-		return rc;
-
-	return len;
-}
-EXPORT_SYMBOL_GPL(nvmem_device_cell_read);
-
-/**
- * nvmem_device_cell_write() - Write cell to a given nvmem device
- *
- * @nvmem: nvmem device to be written to.
- * @info: nvmem cell info to be written.
- * @buf: buffer to be written to cell.
- *
- * Return: length of bytes written or negative error code on failure.
- * */
-int nvmem_device_cell_write(struct nvmem_device *nvmem,
-			    struct nvmem_cell_info *info, void *buf)
-{
-	struct nvmem_cell cell;
-	int rc;
-
-	if (!nvmem)
-		return -EINVAL;
-
-	rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell);
-	if (rc)
-		return rc;
-
-	return nvmem_cell_write(&cell, buf, cell.bytes);
-}
-EXPORT_SYMBOL_GPL(nvmem_device_cell_write);
-
 /**
  * nvmem_device_read() - Read from a given nvmem device
  *
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 4e85447f7860..7e9fb5a19d91 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -21,14 +21,6 @@ struct device_node;
 struct nvmem_cell;
 struct nvmem_device;
 
-struct nvmem_cell_info {
-	const char		*name;
-	unsigned int		offset;
-	unsigned int		bytes;
-	unsigned int		bit_offset;
-	unsigned int		nbits;
-};
-
 #if IS_ENABLED(CONFIG_NVMEM)
 
 /* Cell based interface */
@@ -50,10 +42,6 @@ int nvmem_device_read(struct nvmem_device *nvmem, unsigned int offset,
 		      size_t bytes, void *buf);
 int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,
 		       size_t bytes, void *buf);
-ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
-			   struct nvmem_cell_info *info, void *buf);
-int nvmem_device_cell_write(struct nvmem_device *nvmem,
-			    struct nvmem_cell_info *info, void *buf);
 
 #else
 
@@ -116,20 +104,6 @@ static inline void devm_nvmem_device_put(struct device *dev,
 {
 }
 
-static inline ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
-					 struct nvmem_cell_info *info,
-					 void *buf)
-{
-	return -ENOSYS;
-}
-
-static inline int nvmem_device_cell_write(struct nvmem_device *nvmem,
-					  struct nvmem_cell_info *info,
-					  void *buf)
-{
-	return -ENOSYS;
-}
-
 static inline int nvmem_device_read(struct nvmem_device *nvmem,
 				    unsigned int offset, size_t bytes,
 				    void *buf)
diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
index 24def6ad09bb..cc8556e3c825 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -16,7 +16,6 @@
 #include <linux/errno.h>
 
 struct nvmem_device;
-struct nvmem_cell_info;
 typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset,
 				void *val, size_t bytes);
 typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
@@ -52,8 +51,6 @@ struct nvmem_config {
 	const char		*name;
 	int			id;
 	struct module		*owner;
-	const struct nvmem_cell_info	*cells;
-	int			ncells;
 	bool			read_only;
 	bool			root_only;
 	nvmem_reg_read_t	reg_read;
@@ -77,9 +74,6 @@ struct nvmem_device *devm_nvmem_register(struct device *dev,
 
 int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem);
 
-int nvmem_add_cells(struct nvmem_device *nvmem,
-		    const struct nvmem_cell_info *info,
-		    int ncells);
 #else
 
 static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
@@ -105,12 +99,5 @@ devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem)
 
 }
 
-static inline int nvmem_add_cells(struct nvmem_device *nvmem,
-				  const struct nvmem_cell_info *info,
-				  int ncells)
-{
-	return -ENOSYS;
-}
-
 #endif /* CONFIG_NVMEM */
 #endif  /* ifndef _LINUX_NVMEM_PROVIDER_H */
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 02/13] nvmem: remove the global cell list
  2018-09-05  9:57 ` Bartosz Golaszewski
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Boris Brezillon, Andrew Lunn, Alban Bedel,
	Maxime Ripard
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Make each nvmem device the owner of its nvmem cells.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c | 28 ++++++++++++----------------
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index bb475c2688f9..86af62e2df47 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -38,6 +38,7 @@ struct nvmem_device {
 	int			flags;
 	struct bin_attribute	eeprom;
 	struct device		*base_dev;
+	struct list_head	cells;
 	nvmem_reg_read_t	reg_read;
 	nvmem_reg_write_t	reg_write;
 	void *priv;
@@ -58,9 +59,6 @@ struct nvmem_cell {
 static DEFINE_MUTEX(nvmem_mutex);
 static DEFINE_IDA(nvmem_ida);
 
-static LIST_HEAD(nvmem_cells);
-static DEFINE_MUTEX(nvmem_cells_mutex);
-
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static struct lock_class_key eeprom_lock_key;
 #endif
@@ -284,29 +282,25 @@ static struct nvmem_device *of_nvmem_find(struct device_node *nvmem_np)
 
 static void nvmem_cell_drop(struct nvmem_cell *cell)
 {
-	mutex_lock(&nvmem_cells_mutex);
+	mutex_lock(&nvmem_mutex);
 	list_del(&cell->node);
-	mutex_unlock(&nvmem_cells_mutex);
+	mutex_unlock(&nvmem_mutex);
 	kfree(cell);
 }
 
-static void nvmem_device_remove_all_cells(const struct nvmem_device *nvmem)
+static void nvmem_device_remove_all_cells(struct nvmem_device *nvmem)
 {
-	struct nvmem_cell *cell;
-	struct list_head *p, *n;
+	struct nvmem_cell *cell, *p;
 
-	list_for_each_safe(p, n, &nvmem_cells) {
-		cell = list_entry(p, struct nvmem_cell, node);
-		if (cell->nvmem == nvmem)
-			nvmem_cell_drop(cell);
-	}
+	list_for_each_entry_safe(cell, p, &nvmem->cells, node)
+		nvmem_cell_drop(cell);
 }
 
 static void nvmem_cell_add(struct nvmem_cell *cell)
 {
-	mutex_lock(&nvmem_cells_mutex);
-	list_add_tail(&cell->node, &nvmem_cells);
-	mutex_unlock(&nvmem_cells_mutex);
+	mutex_lock(&nvmem_mutex);
+	list_add_tail(&cell->node, &cell->nvmem->cells);
+	mutex_unlock(&nvmem_mutex);
 }
 
 /*
@@ -423,6 +417,8 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 			goto err_device_del;
 	}
 
+	INIT_LIST_HEAD(&nvmem->cells);
+
 	return nvmem;
 
 err_device_del:
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 02/13] nvmem: remove the global cell list
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Make each nvmem device the owner of its nvmem cells.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c | 28 ++++++++++++----------------
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index bb475c2688f9..86af62e2df47 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -38,6 +38,7 @@ struct nvmem_device {
 	int			flags;
 	struct bin_attribute	eeprom;
 	struct device		*base_dev;
+	struct list_head	cells;
 	nvmem_reg_read_t	reg_read;
 	nvmem_reg_write_t	reg_write;
 	void *priv;
@@ -58,9 +59,6 @@ struct nvmem_cell {
 static DEFINE_MUTEX(nvmem_mutex);
 static DEFINE_IDA(nvmem_ida);
 
-static LIST_HEAD(nvmem_cells);
-static DEFINE_MUTEX(nvmem_cells_mutex);
-
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static struct lock_class_key eeprom_lock_key;
 #endif
@@ -284,29 +282,25 @@ static struct nvmem_device *of_nvmem_find(struct device_node *nvmem_np)
 
 static void nvmem_cell_drop(struct nvmem_cell *cell)
 {
-	mutex_lock(&nvmem_cells_mutex);
+	mutex_lock(&nvmem_mutex);
 	list_del(&cell->node);
-	mutex_unlock(&nvmem_cells_mutex);
+	mutex_unlock(&nvmem_mutex);
 	kfree(cell);
 }
 
-static void nvmem_device_remove_all_cells(const struct nvmem_device *nvmem)
+static void nvmem_device_remove_all_cells(struct nvmem_device *nvmem)
 {
-	struct nvmem_cell *cell;
-	struct list_head *p, *n;
+	struct nvmem_cell *cell, *p;
 
-	list_for_each_safe(p, n, &nvmem_cells) {
-		cell = list_entry(p, struct nvmem_cell, node);
-		if (cell->nvmem == nvmem)
-			nvmem_cell_drop(cell);
-	}
+	list_for_each_entry_safe(cell, p, &nvmem->cells, node)
+		nvmem_cell_drop(cell);
 }
 
 static void nvmem_cell_add(struct nvmem_cell *cell)
 {
-	mutex_lock(&nvmem_cells_mutex);
-	list_add_tail(&cell->node, &nvmem_cells);
-	mutex_unlock(&nvmem_cells_mutex);
+	mutex_lock(&nvmem_mutex);
+	list_add_tail(&cell->node, &cell->nvmem->cells);
+	mutex_unlock(&nvmem_mutex);
 }
 
 /*
@@ -423,6 +417,8 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 			goto err_device_del;
 	}
 
+	INIT_LIST_HEAD(&nvmem->cells);
+
 	return nvmem;
 
 err_device_del:
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 03/13] nvmem: use kref
  2018-09-05  9:57 ` Bartosz Golaszewski
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Boris Brezillon, Andrew Lunn, Alban Bedel,
	Maxime Ripard
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Use kref for reference counting. Use an approach similar to the one
seen in the common clock subsystem: don't actually destroy the nvmem
device until the last user puts it. This way we can get rid of the
users check from nvmem_unregister().

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c | 45 +++++++++++++++++++++-----------------------
 1 file changed, 21 insertions(+), 24 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 86af62e2df47..2335b72d4b3e 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -32,7 +32,7 @@ struct nvmem_device {
 	int			stride;
 	int			word_size;
 	int			id;
-	int			users;
+	struct kref		refcnt;
 	size_t			size;
 	bool			read_only;
 	int			flags;
@@ -368,6 +368,8 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 		return ERR_PTR(rval);
 	}
 
+	kref_init(&nvmem->refcnt);
+
 	nvmem->id = rval;
 	nvmem->owner = config->owner;
 	if (!nvmem->owner && config->dev->driver)
@@ -430,6 +432,20 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 }
 EXPORT_SYMBOL_GPL(nvmem_register);
 
+static void nvmem_device_release(struct kref *kref)
+{
+	struct nvmem_device *nvmem;
+
+	nvmem = container_of(kref, struct nvmem_device, refcnt);
+
+	if (nvmem->flags & FLAG_COMPAT)
+		device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
+
+	nvmem_device_remove_all_cells(nvmem);
+	device_del(&nvmem->dev);
+	put_device(&nvmem->dev);
+}
+
 /**
  * nvmem_unregister() - Unregister previously registered nvmem device
  *
@@ -439,19 +455,7 @@ EXPORT_SYMBOL_GPL(nvmem_register);
  */
 int nvmem_unregister(struct nvmem_device *nvmem)
 {
-	mutex_lock(&nvmem_mutex);
-	if (nvmem->users) {
-		mutex_unlock(&nvmem_mutex);
-		return -EBUSY;
-	}
-	mutex_unlock(&nvmem_mutex);
-
-	if (nvmem->flags & FLAG_COMPAT)
-		device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
-
-	nvmem_device_remove_all_cells(nvmem);
-	device_del(&nvmem->dev);
-	put_device(&nvmem->dev);
+	kref_put(&nvmem->refcnt, nvmem_device_release);
 
 	return 0;
 }
@@ -517,7 +521,6 @@ 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)
 {
 	struct nvmem_device *nvmem = NULL;
@@ -533,30 +536,24 @@ static struct nvmem_device *__nvmem_device_get(struct device_node *np)
 		return ERR_PTR(-EPROBE_DEFER);
 	}
 
-	nvmem->users++;
 	mutex_unlock(&nvmem_mutex);
 
 	if (!try_module_get(nvmem->owner)) {
 		dev_err(&nvmem->dev,
 			"could not increase module refcount for cell %s\n",
 			nvmem->name);
-
-		mutex_lock(&nvmem_mutex);
-		nvmem->users--;
-		mutex_unlock(&nvmem_mutex);
-
 		return ERR_PTR(-EINVAL);
 	}
 
+	kref_get(&nvmem->refcnt);
+
 	return nvmem;
 }
 
 static void __nvmem_device_put(struct nvmem_device *nvmem)
 {
 	module_put(nvmem->owner);
-	mutex_lock(&nvmem_mutex);
-	nvmem->users--;
-	mutex_unlock(&nvmem_mutex);
+	kref_put(&nvmem->refcnt, nvmem_device_release);
 }
 
 static struct nvmem_device *nvmem_find(const char *name)
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 03/13] nvmem: use kref
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Use kref for reference counting. Use an approach similar to the one
seen in the common clock subsystem: don't actually destroy the nvmem
device until the last user puts it. This way we can get rid of the
users check from nvmem_unregister().

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c | 45 +++++++++++++++++++++-----------------------
 1 file changed, 21 insertions(+), 24 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 86af62e2df47..2335b72d4b3e 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -32,7 +32,7 @@ struct nvmem_device {
 	int			stride;
 	int			word_size;
 	int			id;
-	int			users;
+	struct kref		refcnt;
 	size_t			size;
 	bool			read_only;
 	int			flags;
@@ -368,6 +368,8 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 		return ERR_PTR(rval);
 	}
 
+	kref_init(&nvmem->refcnt);
+
 	nvmem->id = rval;
 	nvmem->owner = config->owner;
 	if (!nvmem->owner && config->dev->driver)
@@ -430,6 +432,20 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 }
 EXPORT_SYMBOL_GPL(nvmem_register);
 
+static void nvmem_device_release(struct kref *kref)
+{
+	struct nvmem_device *nvmem;
+
+	nvmem = container_of(kref, struct nvmem_device, refcnt);
+
+	if (nvmem->flags & FLAG_COMPAT)
+		device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
+
+	nvmem_device_remove_all_cells(nvmem);
+	device_del(&nvmem->dev);
+	put_device(&nvmem->dev);
+}
+
 /**
  * nvmem_unregister() - Unregister previously registered nvmem device
  *
@@ -439,19 +455,7 @@ EXPORT_SYMBOL_GPL(nvmem_register);
  */
 int nvmem_unregister(struct nvmem_device *nvmem)
 {
-	mutex_lock(&nvmem_mutex);
-	if (nvmem->users) {
-		mutex_unlock(&nvmem_mutex);
-		return -EBUSY;
-	}
-	mutex_unlock(&nvmem_mutex);
-
-	if (nvmem->flags & FLAG_COMPAT)
-		device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
-
-	nvmem_device_remove_all_cells(nvmem);
-	device_del(&nvmem->dev);
-	put_device(&nvmem->dev);
+	kref_put(&nvmem->refcnt, nvmem_device_release);
 
 	return 0;
 }
@@ -517,7 +521,6 @@ 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)
 {
 	struct nvmem_device *nvmem = NULL;
@@ -533,30 +536,24 @@ static struct nvmem_device *__nvmem_device_get(struct device_node *np)
 		return ERR_PTR(-EPROBE_DEFER);
 	}
 
-	nvmem->users++;
 	mutex_unlock(&nvmem_mutex);
 
 	if (!try_module_get(nvmem->owner)) {
 		dev_err(&nvmem->dev,
 			"could not increase module refcount for cell %s\n",
 			nvmem->name);
-
-		mutex_lock(&nvmem_mutex);
-		nvmem->users--;
-		mutex_unlock(&nvmem_mutex);
-
 		return ERR_PTR(-EINVAL);
 	}
 
+	kref_get(&nvmem->refcnt);
+
 	return nvmem;
 }
 
 static void __nvmem_device_put(struct nvmem_device *nvmem)
 {
 	module_put(nvmem->owner);
-	mutex_lock(&nvmem_mutex);
-	nvmem->users--;
-	mutex_unlock(&nvmem_mutex);
+	kref_put(&nvmem->refcnt, nvmem_device_release);
 }
 
 static struct nvmem_device *nvmem_find(const char *name)
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 04/13] nvmem: lpc18xx_eeprom: use devm_nvmem_register()
  2018-09-05  9:57 ` Bartosz Golaszewski
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Boris Brezillon, Andrew Lunn, Alban Bedel,
	Maxime Ripard
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Use the managed version of nvmem_register().

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/lpc18xx_eeprom.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/nvmem/lpc18xx_eeprom.c b/drivers/nvmem/lpc18xx_eeprom.c
index a9534a6e8636..b42dbaddb419 100644
--- a/drivers/nvmem/lpc18xx_eeprom.c
+++ b/drivers/nvmem/lpc18xx_eeprom.c
@@ -236,7 +236,7 @@ static int lpc18xx_eeprom_probe(struct platform_device *pdev)
 	lpc18xx_nvmem_config.dev = dev;
 	lpc18xx_nvmem_config.priv = eeprom;
 
-	eeprom->nvmem = nvmem_register(&lpc18xx_nvmem_config);
+	eeprom->nvmem = devm_nvmem_register(dev, &lpc18xx_nvmem_config);
 	if (IS_ERR(eeprom->nvmem)) {
 		ret = PTR_ERR(eeprom->nvmem);
 		goto err_clk;
@@ -257,10 +257,6 @@ static int lpc18xx_eeprom_remove(struct platform_device *pdev)
 	struct lpc18xx_eeprom_dev *eeprom = platform_get_drvdata(pdev);
 	int ret;
 
-	ret = nvmem_unregister(eeprom->nvmem);
-	if (ret < 0)
-		return ret;
-
 	clk_disable_unprepare(eeprom->clk);
 
 	return 0;
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 04/13] nvmem: lpc18xx_eeprom: use devm_nvmem_register()
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Use the managed version of nvmem_register().

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/lpc18xx_eeprom.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/nvmem/lpc18xx_eeprom.c b/drivers/nvmem/lpc18xx_eeprom.c
index a9534a6e8636..b42dbaddb419 100644
--- a/drivers/nvmem/lpc18xx_eeprom.c
+++ b/drivers/nvmem/lpc18xx_eeprom.c
@@ -236,7 +236,7 @@ static int lpc18xx_eeprom_probe(struct platform_device *pdev)
 	lpc18xx_nvmem_config.dev = dev;
 	lpc18xx_nvmem_config.priv = eeprom;
 
-	eeprom->nvmem = nvmem_register(&lpc18xx_nvmem_config);
+	eeprom->nvmem = devm_nvmem_register(dev, &lpc18xx_nvmem_config);
 	if (IS_ERR(eeprom->nvmem)) {
 		ret = PTR_ERR(eeprom->nvmem);
 		goto err_clk;
@@ -257,10 +257,6 @@ static int lpc18xx_eeprom_remove(struct platform_device *pdev)
 	struct lpc18xx_eeprom_dev *eeprom = platform_get_drvdata(pdev);
 	int ret;
 
-	ret = nvmem_unregister(eeprom->nvmem);
-	if (ret < 0)
-		return ret;
-
 	clk_disable_unprepare(eeprom->clk);
 
 	return 0;
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 05/13] nvmem: change the signature of nvmem_unregister()
  2018-09-05  9:57 ` Bartosz Golaszewski
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Boris Brezillon, Andrew Lunn, Alban Bedel,
	Maxime Ripard
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

This function can no longer fail and there are no more users that check
it return value. Change it to return void.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c           | 8 ++------
 include/linux/nvmem-provider.h | 4 ++--
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 2335b72d4b3e..89b91f73d08a 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -450,20 +450,16 @@ static void nvmem_device_release(struct kref *kref)
  * nvmem_unregister() - Unregister previously registered nvmem device
  *
  * @nvmem: Pointer to previously registered nvmem device.
- *
- * Return: Will be an negative on error or a zero on success.
  */
-int nvmem_unregister(struct nvmem_device *nvmem)
+void nvmem_unregister(struct nvmem_device *nvmem)
 {
 	kref_put(&nvmem->refcnt, nvmem_device_release);
-
-	return 0;
 }
 EXPORT_SYMBOL_GPL(nvmem_unregister);
 
 static void devm_nvmem_release(struct device *dev, void *res)
 {
-	WARN_ON(nvmem_unregister(*(struct nvmem_device **)res));
+	nvmem_unregister(*(struct nvmem_device **)res);
 }
 
 /**
diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
index cc8556e3c825..07ab1ea73520 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -67,7 +67,7 @@ struct nvmem_config {
 #if IS_ENABLED(CONFIG_NVMEM)
 
 struct nvmem_device *nvmem_register(const struct nvmem_config *cfg);
-int nvmem_unregister(struct nvmem_device *nvmem);
+void nvmem_unregister(struct nvmem_device *nvmem);
 
 struct nvmem_device *devm_nvmem_register(struct device *dev,
 					 const struct nvmem_config *cfg);
@@ -81,7 +81,7 @@ static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
 	return ERR_PTR(-ENOSYS);
 }
 
-static inline int nvmem_unregister(struct nvmem_device *nvmem)
+static inline void nvmem_unregister(struct nvmem_device *nvmem)
 {
 	return -ENOSYS;
 }
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 05/13] nvmem: change the signature of nvmem_unregister()
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

This function can no longer fail and there are no more users that check
it return value. Change it to return void.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c           | 8 ++------
 include/linux/nvmem-provider.h | 4 ++--
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 2335b72d4b3e..89b91f73d08a 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -450,20 +450,16 @@ static void nvmem_device_release(struct kref *kref)
  * nvmem_unregister() - Unregister previously registered nvmem device
  *
  * @nvmem: Pointer to previously registered nvmem device.
- *
- * Return: Will be an negative on error or a zero on success.
  */
-int nvmem_unregister(struct nvmem_device *nvmem)
+void nvmem_unregister(struct nvmem_device *nvmem)
 {
 	kref_put(&nvmem->refcnt, nvmem_device_release);
-
-	return 0;
 }
 EXPORT_SYMBOL_GPL(nvmem_unregister);
 
 static void devm_nvmem_release(struct device *dev, void *res)
 {
-	WARN_ON(nvmem_unregister(*(struct nvmem_device **)res));
+	nvmem_unregister(*(struct nvmem_device **)res);
 }
 
 /**
diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
index cc8556e3c825..07ab1ea73520 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -67,7 +67,7 @@ struct nvmem_config {
 #if IS_ENABLED(CONFIG_NVMEM)
 
 struct nvmem_device *nvmem_register(const struct nvmem_config *cfg);
-int nvmem_unregister(struct nvmem_device *nvmem);
+void nvmem_unregister(struct nvmem_device *nvmem);
 
 struct nvmem_device *devm_nvmem_register(struct device *dev,
 					 const struct nvmem_config *cfg);
@@ -81,7 +81,7 @@ static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
 	return ERR_PTR(-ENOSYS);
 }
 
-static inline int nvmem_unregister(struct nvmem_device *nvmem)
+static inline void nvmem_unregister(struct nvmem_device *nvmem)
 {
 	return -ENOSYS;
 }
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 06/13] nvmem: provide nvmem_dev_name()
  2018-09-05  9:57 ` Bartosz Golaszewski
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Boris Brezillon, Andrew Lunn, Alban Bedel,
	Maxime Ripard
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Kernel users don't have any means of checking the names of nvmem
devices. Add a routine that returns the name of the nvmem provider.

This will be useful for nvmem notifier subscribers - otherwise they
can't check what device is being added/removed.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c           | 13 +++++++++++++
 include/linux/nvmem-consumer.h |  8 ++++++++
 2 files changed, 21 insertions(+)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 89b91f73d08a..364ee16e7d6a 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1144,6 +1144,19 @@ int nvmem_device_write(struct nvmem_device *nvmem,
 }
 EXPORT_SYMBOL_GPL(nvmem_device_write);
 
+/**
+ * nvmem_dev_name() - Get the name of a given nvmem device.
+ *
+ * @nvmem: nvmem device.
+ *
+ * Return: name of the nvmem device.
+ */
+const char *nvmem_dev_name(struct nvmem_device *nvmem)
+{
+	return dev_name(&nvmem->dev);
+}
+EXPORT_SYMBOL_GPL(nvmem_dev_name);
+
 static int __init nvmem_init(void)
 {
 	return bus_register(&nvmem_bus_type);
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 7e9fb5a19d91..1313da6731ff 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -43,6 +43,8 @@ int nvmem_device_read(struct nvmem_device *nvmem, unsigned int offset,
 int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,
 		       size_t bytes, void *buf);
 
+const char *nvmem_dev_name(struct nvmem_device *nvmem);
+
 #else
 
 static inline struct nvmem_cell *nvmem_cell_get(struct device *dev,
@@ -117,6 +119,12 @@ static inline int nvmem_device_write(struct nvmem_device *nvmem,
 {
 	return -ENOSYS;
 }
+
+static inline const char *nvmem_dev_name(struct nvmem_device *nvmem)
+{
+	return NULL;
+}
+
 #endif /* CONFIG_NVMEM */
 
 #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 06/13] nvmem: provide nvmem_dev_name()
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Kernel users don't have any means of checking the names of nvmem
devices. Add a routine that returns the name of the nvmem provider.

This will be useful for nvmem notifier subscribers - otherwise they
can't check what device is being added/removed.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c           | 13 +++++++++++++
 include/linux/nvmem-consumer.h |  8 ++++++++
 2 files changed, 21 insertions(+)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 89b91f73d08a..364ee16e7d6a 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1144,6 +1144,19 @@ int nvmem_device_write(struct nvmem_device *nvmem,
 }
 EXPORT_SYMBOL_GPL(nvmem_device_write);
 
+/**
+ * nvmem_dev_name() - Get the name of a given nvmem device.
+ *
+ * @nvmem: nvmem device.
+ *
+ * Return: name of the nvmem device.
+ */
+const char *nvmem_dev_name(struct nvmem_device *nvmem)
+{
+	return dev_name(&nvmem->dev);
+}
+EXPORT_SYMBOL_GPL(nvmem_dev_name);
+
 static int __init nvmem_init(void)
 {
 	return bus_register(&nvmem_bus_type);
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 7e9fb5a19d91..1313da6731ff 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -43,6 +43,8 @@ int nvmem_device_read(struct nvmem_device *nvmem, unsigned int offset,
 int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,
 		       size_t bytes, void *buf);
 
+const char *nvmem_dev_name(struct nvmem_device *nvmem);
+
 #else
 
 static inline struct nvmem_cell *nvmem_cell_get(struct device *dev,
@@ -117,6 +119,12 @@ static inline int nvmem_device_write(struct nvmem_device *nvmem,
 {
 	return -ENOSYS;
 }
+
+static inline const char *nvmem_dev_name(struct nvmem_device *nvmem)
+{
+	return NULL;
+}
+
 #endif /* CONFIG_NVMEM */
 
 #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 07/13] nvmem: remove the name field from struct nvmem_device
  2018-09-05  9:57 ` Bartosz Golaszewski
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Boris Brezillon, Andrew Lunn, Alban Bedel,
	Maxime Ripard
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

This field is never set and is only used in a single error message.
Remove the field and use nvmem_dev_name() instead.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 364ee16e7d6a..e456aaa6184a 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -26,7 +26,6 @@
 #include <linux/slab.h>
 
 struct nvmem_device {
-	const char		*name;
 	struct module		*owner;
 	struct device		dev;
 	int			stride;
@@ -537,7 +536,7 @@ static struct nvmem_device *__nvmem_device_get(struct device_node *np)
 	if (!try_module_get(nvmem->owner)) {
 		dev_err(&nvmem->dev,
 			"could not increase module refcount for cell %s\n",
-			nvmem->name);
+			nvmem_dev_name(nvmem));
 		return ERR_PTR(-EINVAL);
 	}
 
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 07/13] nvmem: remove the name field from struct nvmem_device
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

This field is never set and is only used in a single error message.
Remove the field and use nvmem_dev_name() instead.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 364ee16e7d6a..e456aaa6184a 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -26,7 +26,6 @@
 #include <linux/slab.h>
 
 struct nvmem_device {
-	const char		*name;
 	struct module		*owner;
 	struct device		dev;
 	int			stride;
@@ -537,7 +536,7 @@ static struct nvmem_device *__nvmem_device_get(struct device_node *np)
 	if (!try_module_get(nvmem->owner)) {
 		dev_err(&nvmem->dev,
 			"could not increase module refcount for cell %s\n",
-			nvmem->name);
+			nvmem_dev_name(nvmem));
 		return ERR_PTR(-EINVAL);
 	}
 
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 08/13] nvmem: add a notifier chain
  2018-09-05  9:57 ` Bartosz Golaszewski
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Boris Brezillon, Andrew Lunn, Alban Bedel,
	Maxime Ripard
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Add a blocking notifier chain with two events (add and remove) so that
users can get notified about the addition of nvmem devices they're
waiting for.

We'll use this instead of the at24 setup callback in the mityomapl138
board file.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c           | 36 ++++++++++++++++++++++++++++++++++
 include/linux/nvmem-consumer.h | 19 ++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index e456aaa6184a..17307015905a 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -58,6 +58,8 @@ struct nvmem_cell {
 static DEFINE_MUTEX(nvmem_mutex);
 static DEFINE_IDA(nvmem_ida);
 
+static BLOCKING_NOTIFIER_HEAD(nvmem_notifier);
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static struct lock_class_key eeprom_lock_key;
 #endif
@@ -339,6 +341,32 @@ static int nvmem_setup_compat(struct nvmem_device *nvmem,
 	return 0;
 }
 
+/**
+ * nvmem_register_notifier() - Register a notifier block for nvmem events.
+ *
+ * @nb: notifier block to be called on nvmem events.
+ *
+ * Return: 0 on success, negative error number on failure.
+ */
+int nvmem_register_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&nvmem_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(nvmem_register_notifier);
+
+/**
+ * nvmem_unregister_notifier() - Unregister a notifier block for nvmem events.
+ *
+ * @nb: notifier block to be unregistered.
+ *
+ * Return: 0 on success, negative error number on failure.
+ */
+int nvmem_unregister_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&nvmem_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(nvmem_unregister_notifier);
+
 /**
  * nvmem_register() - Register a nvmem device for given nvmem_config.
  * Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
@@ -420,8 +448,15 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 
 	INIT_LIST_HEAD(&nvmem->cells);
 
+	rval = blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
+	if (rval)
+		goto err_teardown_compat;
+
 	return nvmem;
 
+err_teardown_compat:
+	if (config->compat)
+		device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
 err_device_del:
 	device_del(&nvmem->dev);
 err_put_device:
@@ -436,6 +471,7 @@ static void nvmem_device_release(struct kref *kref)
 	struct nvmem_device *nvmem;
 
 	nvmem = container_of(kref, struct nvmem_device, refcnt);
+	blocking_notifier_call_chain(&nvmem_notifier, NVMEM_REMOVE, nvmem);
 
 	if (nvmem->flags & FLAG_COMPAT)
 		device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 1313da6731ff..8a6405febc32 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -14,6 +14,7 @@
 
 #include <linux/err.h>
 #include <linux/errno.h>
+#include <linux/notifier.h>
 
 struct device;
 struct device_node;
@@ -21,6 +22,11 @@ struct device_node;
 struct nvmem_cell;
 struct nvmem_device;
 
+enum {
+	NVMEM_ADD = 1,
+	NVMEM_REMOVE,
+};
+
 #if IS_ENABLED(CONFIG_NVMEM)
 
 /* Cell based interface */
@@ -45,6 +51,9 @@ int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,
 
 const char *nvmem_dev_name(struct nvmem_device *nvmem);
 
+int nvmem_register_notifier(struct notifier_block *nb);
+int nvmem_unregister_notifier(struct notifier_block *nb);
+
 #else
 
 static inline struct nvmem_cell *nvmem_cell_get(struct device *dev,
@@ -125,6 +134,16 @@ static inline const char *nvmem_dev_name(struct nvmem_device *nvmem)
 	return NULL;
 }
 
+static inline int nvmem_register_notifier(struct notifier_block *nb)
+{
+	return -ENOSYS;
+}
+
+static inline int int nvmem_unregister_notifier(struct notifier_block *nb)
+{
+	return -ENOSYS;
+}
+
 #endif /* CONFIG_NVMEM */
 
 #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 08/13] nvmem: add a notifier chain
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Add a blocking notifier chain with two events (add and remove) so that
users can get notified about the addition of nvmem devices they're
waiting for.

We'll use this instead of the at24 setup callback in the mityomapl138
board file.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c           | 36 ++++++++++++++++++++++++++++++++++
 include/linux/nvmem-consumer.h | 19 ++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index e456aaa6184a..17307015905a 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -58,6 +58,8 @@ struct nvmem_cell {
 static DEFINE_MUTEX(nvmem_mutex);
 static DEFINE_IDA(nvmem_ida);
 
+static BLOCKING_NOTIFIER_HEAD(nvmem_notifier);
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static struct lock_class_key eeprom_lock_key;
 #endif
@@ -339,6 +341,32 @@ static int nvmem_setup_compat(struct nvmem_device *nvmem,
 	return 0;
 }
 
+/**
+ * nvmem_register_notifier() - Register a notifier block for nvmem events.
+ *
+ * @nb: notifier block to be called on nvmem events.
+ *
+ * Return: 0 on success, negative error number on failure.
+ */
+int nvmem_register_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&nvmem_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(nvmem_register_notifier);
+
+/**
+ * nvmem_unregister_notifier() - Unregister a notifier block for nvmem events.
+ *
+ * @nb: notifier block to be unregistered.
+ *
+ * Return: 0 on success, negative error number on failure.
+ */
+int nvmem_unregister_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&nvmem_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(nvmem_unregister_notifier);
+
 /**
  * nvmem_register() - Register a nvmem device for given nvmem_config.
  * Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
@@ -420,8 +448,15 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 
 	INIT_LIST_HEAD(&nvmem->cells);
 
+	rval = blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
+	if (rval)
+		goto err_teardown_compat;
+
 	return nvmem;
 
+err_teardown_compat:
+	if (config->compat)
+		device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
 err_device_del:
 	device_del(&nvmem->dev);
 err_put_device:
@@ -436,6 +471,7 @@ static void nvmem_device_release(struct kref *kref)
 	struct nvmem_device *nvmem;
 
 	nvmem = container_of(kref, struct nvmem_device, refcnt);
+	blocking_notifier_call_chain(&nvmem_notifier, NVMEM_REMOVE, nvmem);
 
 	if (nvmem->flags & FLAG_COMPAT)
 		device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 1313da6731ff..8a6405febc32 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -14,6 +14,7 @@
 
 #include <linux/err.h>
 #include <linux/errno.h>
+#include <linux/notifier.h>
 
 struct device;
 struct device_node;
@@ -21,6 +22,11 @@ struct device_node;
 struct nvmem_cell;
 struct nvmem_device;
 
+enum {
+	NVMEM_ADD = 1,
+	NVMEM_REMOVE,
+};
+
 #if IS_ENABLED(CONFIG_NVMEM)
 
 /* Cell based interface */
@@ -45,6 +51,9 @@ int nvmem_device_write(struct nvmem_device *nvmem, unsigned int offset,
 
 const char *nvmem_dev_name(struct nvmem_device *nvmem);
 
+int nvmem_register_notifier(struct notifier_block *nb);
+int nvmem_unregister_notifier(struct notifier_block *nb);
+
 #else
 
 static inline struct nvmem_cell *nvmem_cell_get(struct device *dev,
@@ -125,6 +134,16 @@ static inline const char *nvmem_dev_name(struct nvmem_device *nvmem)
 	return NULL;
 }
 
+static inline int nvmem_register_notifier(struct notifier_block *nb)
+{
+	return -ENOSYS;
+}
+
+static inline int int nvmem_unregister_notifier(struct notifier_block *nb)
+{
+	return -ENOSYS;
+}
+
 #endif /* CONFIG_NVMEM */
 
 #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 09/13] nvmem: add support for cell info
  2018-09-05  9:57 ` Bartosz Golaszewski
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Boris Brezillon, Andrew Lunn, Alban Bedel,
	Maxime Ripard
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Add new structs and routines allowing users to define nvmem cells from
machine code. This global list of entries is parsed when a provider
is registered and cells are associated with the relevant nvmem_device
struct.

A possible improvement for the future is to allow users to register
cell tables after the nvmem provider has been registered by updating
the cell list at each call to nvmem_(add|del)_cell_table().

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 MAINTAINERS                   |  1 +
 drivers/nvmem/core.c          | 97 ++++++++++++++++++++++++++++++++++-
 include/linux/nvmem-machine.h | 41 +++++++++++++++
 3 files changed, 138 insertions(+), 1 deletion(-)
 create mode 100644 include/linux/nvmem-machine.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 9ad052aeac39..a520924bf0a9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10391,6 +10391,7 @@ F:	drivers/nvmem/
 F:	Documentation/devicetree/bindings/nvmem/
 F:	Documentation/ABI/stable/sysfs-bus-nvmem
 F:	include/linux/nvmem-consumer.h
+F:	include/linux/nvmem-machine.h
 F:	include/linux/nvmem-provider.h
 
 NXP SGTL5000 DRIVER
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 17307015905a..854baa0559a1 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/nvmem-consumer.h>
+#include <linux/nvmem-machine.h>
 #include <linux/nvmem-provider.h>
 #include <linux/of.h>
 #include <linux/slab.h>
@@ -58,6 +59,9 @@ struct nvmem_cell {
 static DEFINE_MUTEX(nvmem_mutex);
 static DEFINE_IDA(nvmem_ida);
 
+static DEFINE_MUTEX(nvmem_cell_mutex);
+static LIST_HEAD(nvmem_cell_tables);
+
 static BLOCKING_NOTIFIER_HEAD(nvmem_notifier);
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -341,6 +345,66 @@ static int nvmem_setup_compat(struct nvmem_device *nvmem,
 	return 0;
 }
 
+static struct nvmem_cell *
+nvmem_cell_from_cell_info(struct nvmem_device *nvmem,
+			  struct nvmem_cell_info *info)
+{
+	struct nvmem_cell *cell;
+
+	cell = kzalloc(sizeof(*cell), GFP_KERNEL);
+	if (!cell)
+		return ERR_PTR(-ENOMEM);
+
+	cell->nvmem = nvmem;
+	cell->offset = info->offset;
+	cell->bytes = info->bytes;
+	cell->name = info->name;
+	cell->bit_offset = info->bit_offset;
+	cell->nbits = info->nbits;
+
+	if (cell->nbits)
+		cell->bytes = DIV_ROUND_UP(cell->nbits + cell->bit_offset,
+					   BITS_PER_BYTE);
+
+	if (!IS_ALIGNED(cell->offset, nvmem->stride)) {
+		dev_err(&nvmem->dev,
+			"cell %s unaligned to nvmem stride %d\n",
+			cell->name, nvmem->stride);
+		kfree(cell);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return cell;
+}
+
+static int nvmem_add_cells_from_list(struct nvmem_device *nvmem)
+{
+	struct nvmem_cell_table *table;
+	struct nvmem_cell_info *info;
+	struct nvmem_cell *cell;
+	int rval = 0, i;
+
+	mutex_lock(&nvmem_cell_mutex);
+	list_for_each_entry(table, &nvmem_cell_tables, node) {
+		if (strcmp(nvmem_dev_name(nvmem), table->nvmem_name) == 0) {
+			for (i = 0; i < table->ncells; i++) {
+				info = &table->cells[i];
+				cell = nvmem_cell_from_cell_info(nvmem, info);
+				if (IS_ERR(cell)) {
+					rval = PTR_ERR(cell);
+					goto out;
+				}
+
+				nvmem_cell_add(cell);
+			}
+		}
+	}
+
+out:
+	mutex_unlock(&nvmem_cell_mutex);
+	return rval;
+}
+
 /**
  * nvmem_register_notifier() - Register a notifier block for nvmem events.
  *
@@ -447,13 +511,18 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	}
 
 	INIT_LIST_HEAD(&nvmem->cells);
+	rval = nvmem_add_cells_from_list(nvmem);
+	if (rval)
+		goto err_teardown_compat;
 
 	rval = blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
 	if (rval)
-		goto err_teardown_compat;
+		goto err_remove_cells;
 
 	return nvmem;
 
+err_remove_cells:
+	nvmem_device_remove_all_cells(nvmem);
 err_teardown_compat:
 	if (config->compat)
 		device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
@@ -1179,6 +1248,32 @@ int nvmem_device_write(struct nvmem_device *nvmem,
 }
 EXPORT_SYMBOL_GPL(nvmem_device_write);
 
+/**
+ * nvmem_add_cell_table() - register a table of cell info entries
+ *
+ * @table: table of cell info entries
+ */
+void nvmem_add_cell_table(struct nvmem_cell_table *table)
+{
+	mutex_lock(&nvmem_cell_mutex);
+	list_add_tail(&table->node, &nvmem_cell_tables);
+	mutex_unlock(&nvmem_cell_mutex);
+}
+EXPORT_SYMBOL_GPL(nvmem_add_cell_table);
+
+/**
+ * nvmem_del_cell_table() - remove a previously registered cell info table
+ *
+ * @table: table of cell info entries
+ */
+void nvmem_del_cell_table(struct nvmem_cell_table *table)
+{
+	mutex_lock(&nvmem_cell_mutex);
+	list_del(&table->node);
+	mutex_unlock(&nvmem_cell_mutex);
+}
+EXPORT_SYMBOL_GPL(nvmem_del_cell_table);
+
 /**
  * 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
new file mode 100644
index 000000000000..1e199dfaacab
--- /dev/null
+++ b/include/linux/nvmem-machine.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * nvmem framework machine code bindings
+ *
+ * Copyright (C) 2018 Bartosz Golaszewski <bgolaszewski@baylibre.com>
+ */
+
+#ifndef _LINUX_NVMEM_MACHINE_H
+#define _LINUX_NVMEM_MACHINE_H
+
+#include <linux/nvmem-provider.h>
+#include <linux/list.h>
+
+struct nvmem_cell_info {
+	const char		*name;
+	unsigned int		offset;
+	unsigned int		bytes;
+	unsigned int		bit_offset;
+	unsigned int		nbits;
+};
+
+struct nvmem_cell_table {
+	const char		*nvmem_name;
+	struct nvmem_cell_info	*cells;
+	size_t			ncells;
+	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);
+
+#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) {}
+
+#endif /* CONFIG_NVMEM */
+
+#endif  /* ifndef _LINUX_NVMEM_MACHINE_H */
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 09/13] nvmem: add support for cell info
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Add new structs and routines allowing users to define nvmem cells from
machine code. This global list of entries is parsed when a provider
is registered and cells are associated with the relevant nvmem_device
struct.

A possible improvement for the future is to allow users to register
cell tables after the nvmem provider has been registered by updating
the cell list at each call to nvmem_(add|del)_cell_table().

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 MAINTAINERS                   |  1 +
 drivers/nvmem/core.c          | 97 ++++++++++++++++++++++++++++++++++-
 include/linux/nvmem-machine.h | 41 +++++++++++++++
 3 files changed, 138 insertions(+), 1 deletion(-)
 create mode 100644 include/linux/nvmem-machine.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 9ad052aeac39..a520924bf0a9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10391,6 +10391,7 @@ F:	drivers/nvmem/
 F:	Documentation/devicetree/bindings/nvmem/
 F:	Documentation/ABI/stable/sysfs-bus-nvmem
 F:	include/linux/nvmem-consumer.h
+F:	include/linux/nvmem-machine.h
 F:	include/linux/nvmem-provider.h
 
 NXP SGTL5000 DRIVER
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 17307015905a..854baa0559a1 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/nvmem-consumer.h>
+#include <linux/nvmem-machine.h>
 #include <linux/nvmem-provider.h>
 #include <linux/of.h>
 #include <linux/slab.h>
@@ -58,6 +59,9 @@ struct nvmem_cell {
 static DEFINE_MUTEX(nvmem_mutex);
 static DEFINE_IDA(nvmem_ida);
 
+static DEFINE_MUTEX(nvmem_cell_mutex);
+static LIST_HEAD(nvmem_cell_tables);
+
 static BLOCKING_NOTIFIER_HEAD(nvmem_notifier);
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -341,6 +345,66 @@ static int nvmem_setup_compat(struct nvmem_device *nvmem,
 	return 0;
 }
 
+static struct nvmem_cell *
+nvmem_cell_from_cell_info(struct nvmem_device *nvmem,
+			  struct nvmem_cell_info *info)
+{
+	struct nvmem_cell *cell;
+
+	cell = kzalloc(sizeof(*cell), GFP_KERNEL);
+	if (!cell)
+		return ERR_PTR(-ENOMEM);
+
+	cell->nvmem = nvmem;
+	cell->offset = info->offset;
+	cell->bytes = info->bytes;
+	cell->name = info->name;
+	cell->bit_offset = info->bit_offset;
+	cell->nbits = info->nbits;
+
+	if (cell->nbits)
+		cell->bytes = DIV_ROUND_UP(cell->nbits + cell->bit_offset,
+					   BITS_PER_BYTE);
+
+	if (!IS_ALIGNED(cell->offset, nvmem->stride)) {
+		dev_err(&nvmem->dev,
+			"cell %s unaligned to nvmem stride %d\n",
+			cell->name, nvmem->stride);
+		kfree(cell);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return cell;
+}
+
+static int nvmem_add_cells_from_list(struct nvmem_device *nvmem)
+{
+	struct nvmem_cell_table *table;
+	struct nvmem_cell_info *info;
+	struct nvmem_cell *cell;
+	int rval = 0, i;
+
+	mutex_lock(&nvmem_cell_mutex);
+	list_for_each_entry(table, &nvmem_cell_tables, node) {
+		if (strcmp(nvmem_dev_name(nvmem), table->nvmem_name) == 0) {
+			for (i = 0; i < table->ncells; i++) {
+				info = &table->cells[i];
+				cell = nvmem_cell_from_cell_info(nvmem, info);
+				if (IS_ERR(cell)) {
+					rval = PTR_ERR(cell);
+					goto out;
+				}
+
+				nvmem_cell_add(cell);
+			}
+		}
+	}
+
+out:
+	mutex_unlock(&nvmem_cell_mutex);
+	return rval;
+}
+
 /**
  * nvmem_register_notifier() - Register a notifier block for nvmem events.
  *
@@ -447,13 +511,18 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	}
 
 	INIT_LIST_HEAD(&nvmem->cells);
+	rval = nvmem_add_cells_from_list(nvmem);
+	if (rval)
+		goto err_teardown_compat;
 
 	rval = blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
 	if (rval)
-		goto err_teardown_compat;
+		goto err_remove_cells;
 
 	return nvmem;
 
+err_remove_cells:
+	nvmem_device_remove_all_cells(nvmem);
 err_teardown_compat:
 	if (config->compat)
 		device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
@@ -1179,6 +1248,32 @@ int nvmem_device_write(struct nvmem_device *nvmem,
 }
 EXPORT_SYMBOL_GPL(nvmem_device_write);
 
+/**
+ * nvmem_add_cell_table() - register a table of cell info entries
+ *
+ * @table: table of cell info entries
+ */
+void nvmem_add_cell_table(struct nvmem_cell_table *table)
+{
+	mutex_lock(&nvmem_cell_mutex);
+	list_add_tail(&table->node, &nvmem_cell_tables);
+	mutex_unlock(&nvmem_cell_mutex);
+}
+EXPORT_SYMBOL_GPL(nvmem_add_cell_table);
+
+/**
+ * nvmem_del_cell_table() - remove a previously registered cell info table
+ *
+ * @table: table of cell info entries
+ */
+void nvmem_del_cell_table(struct nvmem_cell_table *table)
+{
+	mutex_lock(&nvmem_cell_mutex);
+	list_del(&table->node);
+	mutex_unlock(&nvmem_cell_mutex);
+}
+EXPORT_SYMBOL_GPL(nvmem_del_cell_table);
+
 /**
  * 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
new file mode 100644
index 000000000000..1e199dfaacab
--- /dev/null
+++ b/include/linux/nvmem-machine.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * nvmem framework machine code bindings
+ *
+ * Copyright (C) 2018 Bartosz Golaszewski <bgolaszewski@baylibre.com>
+ */
+
+#ifndef _LINUX_NVMEM_MACHINE_H
+#define _LINUX_NVMEM_MACHINE_H
+
+#include <linux/nvmem-provider.h>
+#include <linux/list.h>
+
+struct nvmem_cell_info {
+	const char		*name;
+	unsigned int		offset;
+	unsigned int		bytes;
+	unsigned int		bit_offset;
+	unsigned int		nbits;
+};
+
+struct nvmem_cell_table {
+	const char		*nvmem_name;
+	struct nvmem_cell_info	*cells;
+	size_t			ncells;
+	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);
+
+#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) {}
+
+#endif /* CONFIG_NVMEM */
+
+#endif  /* ifndef _LINUX_NVMEM_MACHINE_H */
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 10/13] nvmem: resolve cells from DT at registration time
  2018-09-05  9:57 ` Bartosz Golaszewski
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Boris Brezillon, Andrew Lunn, Alban Bedel,
	Maxime Ripard
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Currently we're creating a new cell structure everytime a DT users
calls nvmem_cell_get().

Change this behavior by resolving the cells during nvmem provider
registration and adding all cells to the provider's list. Make
of_nvmem_cell_get() just parse the phandle and look the cell up
in the relevant provider's list.

Don't drop the cell in nvmem_cell_put().

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c | 122 ++++++++++++++++++++++++++-----------------
 1 file changed, 74 insertions(+), 48 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 854baa0559a1..da7a9d5beb33 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -405,6 +405,73 @@ static int nvmem_add_cells_from_list(struct nvmem_device *nvmem)
 	return rval;
 }
 
+static struct nvmem_cell *
+nvmem_find_cell_by_index(struct nvmem_device *nvmem, int index)
+{
+	struct nvmem_cell *cell = NULL;
+	int i = 0;
+
+	mutex_lock(&nvmem_mutex);
+	list_for_each_entry(cell, &nvmem->cells, node) {
+		if (index == i++)
+			break;
+	}
+	mutex_unlock(&nvmem_mutex);
+
+	return cell;
+}
+
+static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
+{
+	struct device_node *parent, *child;
+	struct device *dev = &nvmem->dev;
+	struct nvmem_cell *cell;
+	const __be32 *addr;
+	int len;
+
+	parent = dev->of_node;
+
+	for_each_child_of_node(parent, child) {
+		addr = of_get_property(child, "reg", &len);
+		if (!addr || (len < 2 * sizeof(u32))) {
+			dev_err(dev, "nvmem: invalid reg on %pOF\n", child);
+			return -EINVAL;
+		}
+
+		cell = kzalloc(sizeof(*cell), GFP_KERNEL);
+		if (!cell)
+			return -ENOMEM;
+
+		cell->nvmem = nvmem;
+		cell->offset = be32_to_cpup(addr++);
+		cell->bytes = be32_to_cpup(addr);
+		cell->name = child->name;
+
+		addr = of_get_property(child, "bits", &len);
+		if (addr && len == (2 * sizeof(u32))) {
+			cell->bit_offset = be32_to_cpup(addr++);
+			cell->nbits = be32_to_cpup(addr);
+		}
+
+		if (cell->nbits)
+			cell->bytes = DIV_ROUND_UP(
+					cell->nbits + cell->bit_offset,
+					BITS_PER_BYTE);
+
+		if (!IS_ALIGNED(cell->offset, nvmem->stride)) {
+			dev_err(dev, "cell %s unaligned to nvmem stride %d\n",
+				cell->name, nvmem->stride);
+			/* Cells already added will be freed later. */
+			kfree(cell);
+			return -EINVAL;
+		}
+
+		nvmem_cell_add(cell);
+	}
+
+	return 0;
+}
+
 /**
  * nvmem_register_notifier() - Register a notifier block for nvmem events.
  *
@@ -514,6 +581,9 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	rval = nvmem_add_cells_from_list(nvmem);
 	if (rval)
 		goto err_teardown_compat;
+	rval = nvmem_add_cells_from_of(nvmem);
+	if (rval)
+		goto err_remove_cells;
 
 	rval = blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
 	if (rval)
@@ -811,10 +881,8 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
 					    const char *name)
 {
 	struct device_node *cell_np, *nvmem_np;
-	struct nvmem_cell *cell;
 	struct nvmem_device *nvmem;
-	const __be32 *addr;
-	int rval, len;
+	struct nvmem_cell *cell;
 	int index = 0;
 
 	/* if cell name exists, find index to the name */
@@ -834,54 +902,13 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
 	if (IS_ERR(nvmem))
 		return ERR_CAST(nvmem);
 
-	addr = of_get_property(cell_np, "reg", &len);
-	if (!addr || (len < 2 * sizeof(u32))) {
-		dev_err(&nvmem->dev, "nvmem: invalid reg on %pOF\n",
-			cell_np);
-		rval  = -EINVAL;
-		goto err_mem;
-	}
-
-	cell = kzalloc(sizeof(*cell), GFP_KERNEL);
+	cell = nvmem_find_cell_by_index(nvmem, index);
 	if (!cell) {
-		rval = -ENOMEM;
-		goto err_mem;
-	}
-
-	cell->nvmem = nvmem;
-	cell->offset = be32_to_cpup(addr++);
-	cell->bytes = be32_to_cpup(addr);
-	cell->name = cell_np->name;
-
-	addr = of_get_property(cell_np, "bits", &len);
-	if (addr && len == (2 * sizeof(u32))) {
-		cell->bit_offset = be32_to_cpup(addr++);
-		cell->nbits = be32_to_cpup(addr);
-	}
-
-	if (cell->nbits)
-		cell->bytes = DIV_ROUND_UP(cell->nbits + cell->bit_offset,
-					   BITS_PER_BYTE);
-
-	if (!IS_ALIGNED(cell->offset, nvmem->stride)) {
-			dev_err(&nvmem->dev,
-				"cell %s unaligned to nvmem stride %d\n",
-				cell->name, nvmem->stride);
-		rval  = -EINVAL;
-		goto err_sanity;
+		__nvmem_device_put(nvmem);
+		return ERR_PTR(-ENOENT);
 	}
 
-	nvmem_cell_add(cell);
-
 	return cell;
-
-err_sanity:
-	kfree(cell);
-
-err_mem:
-	__nvmem_device_put(nvmem);
-
-	return ERR_PTR(rval);
 }
 EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
 #endif
@@ -978,7 +1005,6 @@ void nvmem_cell_put(struct nvmem_cell *cell)
 	struct nvmem_device *nvmem = cell->nvmem;
 
 	__nvmem_device_put(nvmem);
-	nvmem_cell_drop(cell);
 }
 EXPORT_SYMBOL_GPL(nvmem_cell_put);
 
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 10/13] nvmem: resolve cells from DT at registration time
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Currently we're creating a new cell structure everytime a DT users
calls nvmem_cell_get().

Change this behavior by resolving the cells during nvmem provider
registration and adding all cells to the provider's list. Make
of_nvmem_cell_get() just parse the phandle and look the cell up
in the relevant provider's list.

Don't drop the cell in nvmem_cell_put().

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c | 122 ++++++++++++++++++++++++++-----------------
 1 file changed, 74 insertions(+), 48 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 854baa0559a1..da7a9d5beb33 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -405,6 +405,73 @@ static int nvmem_add_cells_from_list(struct nvmem_device *nvmem)
 	return rval;
 }
 
+static struct nvmem_cell *
+nvmem_find_cell_by_index(struct nvmem_device *nvmem, int index)
+{
+	struct nvmem_cell *cell = NULL;
+	int i = 0;
+
+	mutex_lock(&nvmem_mutex);
+	list_for_each_entry(cell, &nvmem->cells, node) {
+		if (index == i++)
+			break;
+	}
+	mutex_unlock(&nvmem_mutex);
+
+	return cell;
+}
+
+static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
+{
+	struct device_node *parent, *child;
+	struct device *dev = &nvmem->dev;
+	struct nvmem_cell *cell;
+	const __be32 *addr;
+	int len;
+
+	parent = dev->of_node;
+
+	for_each_child_of_node(parent, child) {
+		addr = of_get_property(child, "reg", &len);
+		if (!addr || (len < 2 * sizeof(u32))) {
+			dev_err(dev, "nvmem: invalid reg on %pOF\n", child);
+			return -EINVAL;
+		}
+
+		cell = kzalloc(sizeof(*cell), GFP_KERNEL);
+		if (!cell)
+			return -ENOMEM;
+
+		cell->nvmem = nvmem;
+		cell->offset = be32_to_cpup(addr++);
+		cell->bytes = be32_to_cpup(addr);
+		cell->name = child->name;
+
+		addr = of_get_property(child, "bits", &len);
+		if (addr && len == (2 * sizeof(u32))) {
+			cell->bit_offset = be32_to_cpup(addr++);
+			cell->nbits = be32_to_cpup(addr);
+		}
+
+		if (cell->nbits)
+			cell->bytes = DIV_ROUND_UP(
+					cell->nbits + cell->bit_offset,
+					BITS_PER_BYTE);
+
+		if (!IS_ALIGNED(cell->offset, nvmem->stride)) {
+			dev_err(dev, "cell %s unaligned to nvmem stride %d\n",
+				cell->name, nvmem->stride);
+			/* Cells already added will be freed later. */
+			kfree(cell);
+			return -EINVAL;
+		}
+
+		nvmem_cell_add(cell);
+	}
+
+	return 0;
+}
+
 /**
  * nvmem_register_notifier() - Register a notifier block for nvmem events.
  *
@@ -514,6 +581,9 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	rval = nvmem_add_cells_from_list(nvmem);
 	if (rval)
 		goto err_teardown_compat;
+	rval = nvmem_add_cells_from_of(nvmem);
+	if (rval)
+		goto err_remove_cells;
 
 	rval = blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
 	if (rval)
@@ -811,10 +881,8 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
 					    const char *name)
 {
 	struct device_node *cell_np, *nvmem_np;
-	struct nvmem_cell *cell;
 	struct nvmem_device *nvmem;
-	const __be32 *addr;
-	int rval, len;
+	struct nvmem_cell *cell;
 	int index = 0;
 
 	/* if cell name exists, find index to the name */
@@ -834,54 +902,13 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
 	if (IS_ERR(nvmem))
 		return ERR_CAST(nvmem);
 
-	addr = of_get_property(cell_np, "reg", &len);
-	if (!addr || (len < 2 * sizeof(u32))) {
-		dev_err(&nvmem->dev, "nvmem: invalid reg on %pOF\n",
-			cell_np);
-		rval  = -EINVAL;
-		goto err_mem;
-	}
-
-	cell = kzalloc(sizeof(*cell), GFP_KERNEL);
+	cell = nvmem_find_cell_by_index(nvmem, index);
 	if (!cell) {
-		rval = -ENOMEM;
-		goto err_mem;
-	}
-
-	cell->nvmem = nvmem;
-	cell->offset = be32_to_cpup(addr++);
-	cell->bytes = be32_to_cpup(addr);
-	cell->name = cell_np->name;
-
-	addr = of_get_property(cell_np, "bits", &len);
-	if (addr && len == (2 * sizeof(u32))) {
-		cell->bit_offset = be32_to_cpup(addr++);
-		cell->nbits = be32_to_cpup(addr);
-	}
-
-	if (cell->nbits)
-		cell->bytes = DIV_ROUND_UP(cell->nbits + cell->bit_offset,
-					   BITS_PER_BYTE);
-
-	if (!IS_ALIGNED(cell->offset, nvmem->stride)) {
-			dev_err(&nvmem->dev,
-				"cell %s unaligned to nvmem stride %d\n",
-				cell->name, nvmem->stride);
-		rval  = -EINVAL;
-		goto err_sanity;
+		__nvmem_device_put(nvmem);
+		return ERR_PTR(-ENOENT);
 	}
 
-	nvmem_cell_add(cell);
-
 	return cell;
-
-err_sanity:
-	kfree(cell);
-
-err_mem:
-	__nvmem_device_put(nvmem);
-
-	return ERR_PTR(rval);
 }
 EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
 #endif
@@ -978,7 +1005,6 @@ void nvmem_cell_put(struct nvmem_cell *cell)
 	struct nvmem_device *nvmem = cell->nvmem;
 
 	__nvmem_device_put(nvmem);
-	nvmem_cell_drop(cell);
 }
 EXPORT_SYMBOL_GPL(nvmem_cell_put);
 
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 11/13] nvmem: add support for cell lookups from machine code
  2018-09-05  9:57 ` Bartosz Golaszewski
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Boris Brezillon, Andrew Lunn, Alban Bedel,
	Maxime Ripard
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

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          | 142 +++++++++++++++++++++++++++-------
 include/linux/nvmem-machine.h |  15 ++++
 2 files changed, 130 insertions(+), 27 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index da7a9d5beb33..d7c609109cfd 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,43 @@ 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 *cell_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->cell_id, cell_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, cell_id);
+			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 +974,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 +1353,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..79421bbf9d13 100644
--- a/include/linux/nvmem-machine.h
+++ b/include/linux/nvmem-machine.h
@@ -26,16 +26,31 @@ struct nvmem_cell_table {
 	struct list_head	node;
 };
 
+struct nvmem_cell_lookup {
+	const char		*nvmem_name;
+	const char		*dev_id;
+	const char		*cell_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 */
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 11/13] nvmem: add support for cell lookups from machine code
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

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          | 142 +++++++++++++++++++++++++++-------
 include/linux/nvmem-machine.h |  15 ++++
 2 files changed, 130 insertions(+), 27 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index da7a9d5beb33..d7c609109cfd 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,43 @@ 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 *cell_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->cell_id, cell_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, cell_id);
+			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 +974,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 +1353,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..79421bbf9d13 100644
--- a/include/linux/nvmem-machine.h
+++ b/include/linux/nvmem-machine.h
@@ -26,16 +26,31 @@ struct nvmem_cell_table {
 	struct list_head	node;
 };
 
+struct nvmem_cell_lookup {
+	const char		*nvmem_name;
+	const char		*dev_id;
+	const char		*cell_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 */
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 12/13] Documentation: nvmem: document cell tables and lookup entries
  2018-09-05  9:57 ` Bartosz Golaszewski
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Boris Brezillon, Andrew Lunn, Alban Bedel,
	Maxime Ripard
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Document the new nvmem kernel APIs.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 Documentation/nvmem/nvmem.txt | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/Documentation/nvmem/nvmem.txt b/Documentation/nvmem/nvmem.txt
index 8d8d8f58f96f..2cb01cdf87c8 100644
--- a/Documentation/nvmem/nvmem.txt
+++ b/Documentation/nvmem/nvmem.txt
@@ -58,6 +58,36 @@ static int qfprom_probe(struct platform_device *pdev)
 It is mandatory that the NVMEM provider has a regmap associated with its
 struct device. Failure to do would return error code from nvmem_register().
 
+Users of board files can define and register nvmem cells using the
+nvmem_cell_table struct:
+
+static struct nvmem_cell_info foo_nvmem_cells[] = {
+	{
+		.name		= "mac-address",
+		.offset		= 0x7f00,
+		.bytes		= ETH_ALEN,
+	}
+};
+
+static struct nvmem_cell_table foo_nvmem_cell_table = {
+	.nvmem_name		= "i2c-eeprom",
+	.cells			= foo_nvmem_cells,
+	.ncells			= ARRAY_SIZE(foo_nvmem_cells),
+};
+
+nvmem_add_cell_table(&foo_nvmem_cell_table);
+
+Additionally it is possible to create nvmem cell lookup entries and register
+them with the nvmem framework from machine code as shown in the example below:
+
+static struct nvmem_cell_lookup foo_nvmem_lookup = {
+	.nvmem_name		= "i2c-eeprom",
+	.dev_id			= "foo_mac.0",
+	.cell_id		= "mac-address",
+};
+
+nvmem_add_cell_lookups(&foo_nvmem_lookup, 1);
+
 NVMEM Consumers
 +++++++++++++++
 
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 12/13] Documentation: nvmem: document cell tables and lookup entries
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Document the new nvmem kernel APIs.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 Documentation/nvmem/nvmem.txt | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/Documentation/nvmem/nvmem.txt b/Documentation/nvmem/nvmem.txt
index 8d8d8f58f96f..2cb01cdf87c8 100644
--- a/Documentation/nvmem/nvmem.txt
+++ b/Documentation/nvmem/nvmem.txt
@@ -58,6 +58,36 @@ static int qfprom_probe(struct platform_device *pdev)
 It is mandatory that the NVMEM provider has a regmap associated with its
 struct device. Failure to do would return error code from nvmem_register().
 
+Users of board files can define and register nvmem cells using the
+nvmem_cell_table struct:
+
+static struct nvmem_cell_info foo_nvmem_cells[] = {
+	{
+		.name		= "mac-address",
+		.offset		= 0x7f00,
+		.bytes		= ETH_ALEN,
+	}
+};
+
+static struct nvmem_cell_table foo_nvmem_cell_table = {
+	.nvmem_name		= "i2c-eeprom",
+	.cells			= foo_nvmem_cells,
+	.ncells			= ARRAY_SIZE(foo_nvmem_cells),
+};
+
+nvmem_add_cell_table(&foo_nvmem_cell_table);
+
+Additionally it is possible to create nvmem cell lookup entries and register
+them with the nvmem framework from machine code as shown in the example below:
+
+static struct nvmem_cell_lookup foo_nvmem_lookup = {
+	.nvmem_name		= "i2c-eeprom",
+	.dev_id			= "foo_mac.0",
+	.cell_id		= "mac-address",
+};
+
+nvmem_add_cell_lookups(&foo_nvmem_lookup, 1);
+
 NVMEM Consumers
 +++++++++++++++
 
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 13/13] nvmem: use SPDX license identifiers
  2018-09-05  9:57 ` Bartosz Golaszewski
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Boris Brezillon, Andrew Lunn, Alban Bedel,
	Maxime Ripard
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Use SPDX license identiefiers to core nvmem files and remove GPL 2.0
license boilerplate.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c           | 10 +---------
 include/linux/nvmem-consumer.h |  5 +----
 include/linux/nvmem-provider.h |  5 +----
 3 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index d7c609109cfd..9a4eaedaa5ea 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * nvmem framework core.
  *
  * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
  * Copyright (C) 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/device.h>
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 8a6405febc32..e417e28d6aa2 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -1,12 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * nvmem framework consumer.
  *
  * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
  * Copyright (C) 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #ifndef _LINUX_NVMEM_CONSUMER_H
diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
index 07ab1ea73520..02ac0dcb2001 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -1,12 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * nvmem framework provider.
  *
  * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
  * Copyright (C) 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #ifndef _LINUX_NVMEM_PROVIDER_H
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 44+ messages in thread

* [PATCH 13/13] nvmem: use SPDX license identifiers
@ 2018-09-05  9:57   ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Use SPDX license identiefiers to core nvmem files and remove GPL 2.0
license boilerplate.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 drivers/nvmem/core.c           | 10 +---------
 include/linux/nvmem-consumer.h |  5 +----
 include/linux/nvmem-provider.h |  5 +----
 3 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index d7c609109cfd..9a4eaedaa5ea 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * nvmem framework core.
  *
  * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
  * Copyright (C) 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/device.h>
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 8a6405febc32..e417e28d6aa2 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -1,12 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * nvmem framework consumer.
  *
  * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
  * Copyright (C) 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #ifndef _LINUX_NVMEM_CONSUMER_H
diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
index 07ab1ea73520..02ac0dcb2001 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -1,12 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * nvmem framework provider.
  *
  * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
  * Copyright (C) 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #ifndef _LINUX_NVMEM_PROVIDER_H
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 44+ messages in thread

* Re: [PATCH 11/13] nvmem: add support for cell lookups from machine code
  2018-09-05  9:57   ` Bartosz Golaszewski
@ 2018-09-05 13:57     ` Boris Brezillon
  -1 siblings, 0 replies; 44+ messages in thread
From: Boris Brezillon @ 2018-09-05 13:57 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Andrew Lunn, Alban Bedel, Maxime Ripard,
	linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

On Wed,  5 Sep 2018 11:57:36 +0200
Bartosz Golaszewski <brgl@bgdev.pl> wrote:

>  
> +struct nvmem_cell_lookup {
> +	const char		*nvmem_name;
> +	const char		*dev_id;

Shouldn't we have a con_id here?

> +	const char		*cell_id;
> +	struct list_head	node;
> +};

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 11/13] nvmem: add support for cell lookups from machine code
@ 2018-09-05 13:57     ` Boris Brezillon
  0 siblings, 0 replies; 44+ messages in thread
From: Boris Brezillon @ 2018-09-05 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed,  5 Sep 2018 11:57:36 +0200
Bartosz Golaszewski <brgl@bgdev.pl> wrote:

>  
> +struct nvmem_cell_lookup {
> +	const char		*nvmem_name;
> +	const char		*dev_id;

Shouldn't we have a con_id here?

> +	const char		*cell_id;
> +	struct list_head	node;
> +};

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 11/13] nvmem: add support for cell lookups from machine code
  2018-09-05 13:57     ` Boris Brezillon
@ 2018-09-05 14:00       ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05 14:00 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Andrew Lunn, Alban Bedel, Maxime Ripard,
	linux-doc, Linux Kernel Mailing List, Linux ARM,
	Bartosz Golaszewski

2018-09-05 15:57 GMT+02:00 Boris Brezillon <boris.brezillon@bootlin.com>:
> On Wed,  5 Sep 2018 11:57:36 +0200
> Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
>>
>> +struct nvmem_cell_lookup {
>> +     const char              *nvmem_name;
>> +     const char              *dev_id;
>
> Shouldn't we have a con_id here?
>
>> +     const char              *cell_id;
>> +     struct list_head        node;
>> +};

I wanted to stay in line with the current API - nvmem_cell_get() takes
as argument a string called cell_id. I wanted to reflect that here.

Bart

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 11/13] nvmem: add support for cell lookups from machine code
@ 2018-09-05 14:00       ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05 14:00 UTC (permalink / raw)
  To: linux-arm-kernel

2018-09-05 15:57 GMT+02:00 Boris Brezillon <boris.brezillon@bootlin.com>:
> On Wed,  5 Sep 2018 11:57:36 +0200
> Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
>>
>> +struct nvmem_cell_lookup {
>> +     const char              *nvmem_name;
>> +     const char              *dev_id;
>
> Shouldn't we have a con_id here?
>
>> +     const char              *cell_id;
>> +     struct list_head        node;
>> +};

I wanted to stay in line with the current API - nvmem_cell_get() takes
as argument a string called cell_id. I wanted to reflect that here.

Bart

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 11/13] nvmem: add support for cell lookups from machine code
  2018-09-05 14:00       ` Bartosz Golaszewski
@ 2018-09-05 14:21         ` Boris Brezillon
  -1 siblings, 0 replies; 44+ messages in thread
From: Boris Brezillon @ 2018-09-05 14:21 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Andrew Lunn, Alban Bedel, Maxime Ripard,
	linux-doc, Linux Kernel Mailing List, Linux ARM,
	Bartosz Golaszewski

On Wed, 5 Sep 2018 16:00:36 +0200
Bartosz Golaszewski <brgl@bgdev.pl> wrote:

> 2018-09-05 15:57 GMT+02:00 Boris Brezillon <boris.brezillon@bootlin.com>:
> > On Wed,  5 Sep 2018 11:57:36 +0200
> > Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> >  
> >>
> >> +struct nvmem_cell_lookup {
> >> +     const char              *nvmem_name;
> >> +     const char              *dev_id;  
> >
> > Shouldn't we have a con_id here?
> >  
> >> +     const char              *cell_id;
> >> +     struct list_head        node;
> >> +};  
> 
> I wanted to stay in line with the current API - nvmem_cell_get() takes
> as argument a string called cell_id. I wanted to reflect that here.

Actually, you need both. con_id is the name you would have in your DT
in the nvmem-cell-names property, cell_id is the name of the cell
you'd find under the nvmem device node.

Let's take an example:

	mydev {
		#nvmem-cell-names = "mac-address", "revision";
		#nvmem-cells = <&cell1>, <&cell2>;
	};

	mynvmemdev {
		#size-cells = <1>;
		#address-cells = <1>;

		cell1: foo@0 {
			reg = <0x0 0x6>;
		};

		cell2: bar@6 {
			reg = <0x6 0x10>;
		};
	};

this can be described the same way using a consumer lookup table:

struct nvmem_cell_lookup_entry {
	const char *con_id;
	const char *nvmem_name;
	const char *cell_name;
};

struct nvmem_cell_lookup_table {
	struct list_head node;
	const char *dev_id;
	unsigned int nentries;
	const struct nvmem_cell_lookup_entry *entries;
}

static const struct nvmem_cell_lookup_entry mydev_nvmem_cells[] = {
	{
		.con_id = "mac-address",
		.nvmem_name = "mynvmemdev",
		.cell_name = "foo",
	},
	{
		.con_id = "revision",
		.nvmem_name = "mynvmemdev",
		.cell_name = "bar",
	},
}

static const struct nvmem_cell_lookup_table mydev_nvmem_lookup = {
	.dev_id = "mydev.0",
	.nentries = ARRAY_SIZE(mydev_nvmem_cells),
	.entries = mydev_nvmem_cells,
};


...

	nvmem_add_cell_lookups(&mydev_nvmem_lookup);

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 11/13] nvmem: add support for cell lookups from machine code
@ 2018-09-05 14:21         ` Boris Brezillon
  0 siblings, 0 replies; 44+ messages in thread
From: Boris Brezillon @ 2018-09-05 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 5 Sep 2018 16:00:36 +0200
Bartosz Golaszewski <brgl@bgdev.pl> wrote:

> 2018-09-05 15:57 GMT+02:00 Boris Brezillon <boris.brezillon@bootlin.com>:
> > On Wed,  5 Sep 2018 11:57:36 +0200
> > Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> >  
> >>
> >> +struct nvmem_cell_lookup {
> >> +     const char              *nvmem_name;
> >> +     const char              *dev_id;  
> >
> > Shouldn't we have a con_id here?
> >  
> >> +     const char              *cell_id;
> >> +     struct list_head        node;
> >> +};  
> 
> I wanted to stay in line with the current API - nvmem_cell_get() takes
> as argument a string called cell_id. I wanted to reflect that here.

Actually, you need both. con_id is the name you would have in your DT
in the nvmem-cell-names property, cell_id is the name of the cell
you'd find under the nvmem device node.

Let's take an example:

	mydev {
		#nvmem-cell-names = "mac-address", "revision";
		#nvmem-cells = <&cell1>, <&cell2>;
	};

	mynvmemdev {
		#size-cells = <1>;
		#address-cells = <1>;

		cell1: foo at 0 {
			reg = <0x0 0x6>;
		};

		cell2: bar at 6 {
			reg = <0x6 0x10>;
		};
	};

this can be described the same way using a consumer lookup table:

struct nvmem_cell_lookup_entry {
	const char *con_id;
	const char *nvmem_name;
	const char *cell_name;
};

struct nvmem_cell_lookup_table {
	struct list_head node;
	const char *dev_id;
	unsigned int nentries;
	const struct nvmem_cell_lookup_entry *entries;
}

static const struct nvmem_cell_lookup_entry mydev_nvmem_cells[] = {
	{
		.con_id = "mac-address",
		.nvmem_name = "mynvmemdev",
		.cell_name = "foo",
	},
	{
		.con_id = "revision",
		.nvmem_name = "mynvmemdev",
		.cell_name = "bar",
	},
}

static const struct nvmem_cell_lookup_table mydev_nvmem_lookup = {
	.dev_id = "mydev.0",
	.nentries = ARRAY_SIZE(mydev_nvmem_cells),
	.entries = mydev_nvmem_cells,
};


...

	nvmem_add_cell_lookups(&mydev_nvmem_lookup);

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 11/13] nvmem: add support for cell lookups from machine code
  2018-09-05 14:21         ` Boris Brezillon
@ 2018-09-05 14:47           ` Bartosz Golaszewski
  -1 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05 14:47 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Andrew Lunn, Alban Bedel, Maxime Ripard,
	linux-doc, Linux Kernel Mailing List, Linux ARM,
	Bartosz Golaszewski

2018-09-05 16:21 GMT+02:00 Boris Brezillon <boris.brezillon@bootlin.com>:
> On Wed, 5 Sep 2018 16:00:36 +0200
> Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
>> 2018-09-05 15:57 GMT+02:00 Boris Brezillon <boris.brezillon@bootlin.com>:
>> > On Wed,  5 Sep 2018 11:57:36 +0200
>> > Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>> >
>> >>
>> >> +struct nvmem_cell_lookup {
>> >> +     const char              *nvmem_name;
>> >> +     const char              *dev_id;
>> >
>> > Shouldn't we have a con_id here?
>> >
>> >> +     const char              *cell_id;
>> >> +     struct list_head        node;
>> >> +};
>>
>> I wanted to stay in line with the current API - nvmem_cell_get() takes
>> as argument a string called cell_id. I wanted to reflect that here.
>
> Actually, you need both. con_id is the name you would have in your DT
> in the nvmem-cell-names property, cell_id is the name of the cell
> you'd find under the nvmem device node.
>
> Let's take an example:
>
>         mydev {
>                 #nvmem-cell-names = "mac-address", "revision";
>                 #nvmem-cells = <&cell1>, <&cell2>;
>         };
>
>         mynvmemdev {
>                 #size-cells = <1>;
>                 #address-cells = <1>;
>
>                 cell1: foo@0 {
>                         reg = <0x0 0x6>;
>                 };
>
>                 cell2: bar@6 {
>                         reg = <0x6 0x10>;
>                 };
>         };
>
> this can be described the same way using a consumer lookup table:
>
> struct nvmem_cell_lookup_entry {
>         const char *con_id;
>         const char *nvmem_name;
>         const char *cell_name;
> };
>
> struct nvmem_cell_lookup_table {
>         struct list_head node;
>         const char *dev_id;
>         unsigned int nentries;
>         const struct nvmem_cell_lookup_entry *entries;
> }
>
> static const struct nvmem_cell_lookup_entry mydev_nvmem_cells[] = {
>         {
>                 .con_id = "mac-address",
>                 .nvmem_name = "mynvmemdev",
>                 .cell_name = "foo",
>         },
>         {
>                 .con_id = "revision",
>                 .nvmem_name = "mynvmemdev",
>                 .cell_name = "bar",
>         },
> }
>
> static const struct nvmem_cell_lookup_table mydev_nvmem_lookup = {
>         .dev_id = "mydev.0",
>         .nentries = ARRAY_SIZE(mydev_nvmem_cells),
>         .entries = mydev_nvmem_cells,
> };
>
>
> ...
>
>         nvmem_add_cell_lookups(&mydev_nvmem_lookup);

Ok I get it. Shouldn't we change the argument name of nvmem_cell_get()
and friends from 'name' to 'con_id' or simply 'id' similarly to what
other frameworks do to avoid such confusion?

I also don't see a need for splitting the lookup into two structures
here. Something like:

struct nvmem_cell_lookup {
        const char *nvmem_name;
        const char *cell_name;
        const char *dev_id;
        const char *con_id;
};

Would be perfectly fine and would allow to register all lookups for
given machine with a single call. How often does it happen that a
single device needs multiple nvmem cells anyway?

Bart

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 11/13] nvmem: add support for cell lookups from machine code
@ 2018-09-05 14:47           ` Bartosz Golaszewski
  0 siblings, 0 replies; 44+ messages in thread
From: Bartosz Golaszewski @ 2018-09-05 14:47 UTC (permalink / raw)
  To: linux-arm-kernel

2018-09-05 16:21 GMT+02:00 Boris Brezillon <boris.brezillon@bootlin.com>:
> On Wed, 5 Sep 2018 16:00:36 +0200
> Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
>> 2018-09-05 15:57 GMT+02:00 Boris Brezillon <boris.brezillon@bootlin.com>:
>> > On Wed,  5 Sep 2018 11:57:36 +0200
>> > Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>> >
>> >>
>> >> +struct nvmem_cell_lookup {
>> >> +     const char              *nvmem_name;
>> >> +     const char              *dev_id;
>> >
>> > Shouldn't we have a con_id here?
>> >
>> >> +     const char              *cell_id;
>> >> +     struct list_head        node;
>> >> +};
>>
>> I wanted to stay in line with the current API - nvmem_cell_get() takes
>> as argument a string called cell_id. I wanted to reflect that here.
>
> Actually, you need both. con_id is the name you would have in your DT
> in the nvmem-cell-names property, cell_id is the name of the cell
> you'd find under the nvmem device node.
>
> Let's take an example:
>
>         mydev {
>                 #nvmem-cell-names = "mac-address", "revision";
>                 #nvmem-cells = <&cell1>, <&cell2>;
>         };
>
>         mynvmemdev {
>                 #size-cells = <1>;
>                 #address-cells = <1>;
>
>                 cell1: foo at 0 {
>                         reg = <0x0 0x6>;
>                 };
>
>                 cell2: bar at 6 {
>                         reg = <0x6 0x10>;
>                 };
>         };
>
> this can be described the same way using a consumer lookup table:
>
> struct nvmem_cell_lookup_entry {
>         const char *con_id;
>         const char *nvmem_name;
>         const char *cell_name;
> };
>
> struct nvmem_cell_lookup_table {
>         struct list_head node;
>         const char *dev_id;
>         unsigned int nentries;
>         const struct nvmem_cell_lookup_entry *entries;
> }
>
> static const struct nvmem_cell_lookup_entry mydev_nvmem_cells[] = {
>         {
>                 .con_id = "mac-address",
>                 .nvmem_name = "mynvmemdev",
>                 .cell_name = "foo",
>         },
>         {
>                 .con_id = "revision",
>                 .nvmem_name = "mynvmemdev",
>                 .cell_name = "bar",
>         },
> }
>
> static const struct nvmem_cell_lookup_table mydev_nvmem_lookup = {
>         .dev_id = "mydev.0",
>         .nentries = ARRAY_SIZE(mydev_nvmem_cells),
>         .entries = mydev_nvmem_cells,
> };
>
>
> ...
>
>         nvmem_add_cell_lookups(&mydev_nvmem_lookup);

Ok I get it. Shouldn't we change the argument name of nvmem_cell_get()
and friends from 'name' to 'con_id' or simply 'id' similarly to what
other frameworks do to avoid such confusion?

I also don't see a need for splitting the lookup into two structures
here. Something like:

struct nvmem_cell_lookup {
        const char *nvmem_name;
        const char *cell_name;
        const char *dev_id;
        const char *con_id;
};

Would be perfectly fine and would allow to register all lookups for
given machine with a single call. How often does it happen that a
single device needs multiple nvmem cells anyway?

Bart

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 11/13] nvmem: add support for cell lookups from machine code
  2018-09-05 14:47           ` Bartosz Golaszewski
@ 2018-09-05 14:59             ` Boris Brezillon
  -1 siblings, 0 replies; 44+ messages in thread
From: Boris Brezillon @ 2018-09-05 14:59 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Srinivas Kandagatla, Joachim Eastwood, David S . Miller,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, Andrew Morton,
	Arnd Bergmann, Jonathan Corbet, Sekhar Nori, Kevin Hilman,
	David Lechner, Andrew Lunn, Alban Bedel, Maxime Ripard,
	linux-doc, Linux Kernel Mailing List, Linux ARM,
	Bartosz Golaszewski

On Wed, 5 Sep 2018 16:47:57 +0200
Bartosz Golaszewski <brgl@bgdev.pl> wrote:

> 2018-09-05 16:21 GMT+02:00 Boris Brezillon <boris.brezillon@bootlin.com>:
> > On Wed, 5 Sep 2018 16:00:36 +0200
> > Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> >  
> >> 2018-09-05 15:57 GMT+02:00 Boris Brezillon <boris.brezillon@bootlin.com>:  
> >> > On Wed,  5 Sep 2018 11:57:36 +0200
> >> > Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> >> >  
> >> >>
> >> >> +struct nvmem_cell_lookup {
> >> >> +     const char              *nvmem_name;
> >> >> +     const char              *dev_id;  
> >> >
> >> > Shouldn't we have a con_id here?
> >> >  
> >> >> +     const char              *cell_id;
> >> >> +     struct list_head        node;
> >> >> +};  
> >>
> >> I wanted to stay in line with the current API - nvmem_cell_get() takes
> >> as argument a string called cell_id. I wanted to reflect that here.  
> >
> > Actually, you need both. con_id is the name you would have in your DT
> > in the nvmem-cell-names property, cell_id is the name of the cell
> > you'd find under the nvmem device node.
> >
> > Let's take an example:
> >
> >         mydev {
> >                 #nvmem-cell-names = "mac-address", "revision";
> >                 #nvmem-cells = <&cell1>, <&cell2>;
> >         };
> >
> >         mynvmemdev {
> >                 #size-cells = <1>;
> >                 #address-cells = <1>;
> >
> >                 cell1: foo@0 {
> >                         reg = <0x0 0x6>;
> >                 };
> >
> >                 cell2: bar@6 {
> >                         reg = <0x6 0x10>;
> >                 };
> >         };
> >
> > this can be described the same way using a consumer lookup table:
> >
> > struct nvmem_cell_lookup_entry {
> >         const char *con_id;
> >         const char *nvmem_name;
> >         const char *cell_name;
> > };
> >
> > struct nvmem_cell_lookup_table {
> >         struct list_head node;
> >         const char *dev_id;
> >         unsigned int nentries;
> >         const struct nvmem_cell_lookup_entry *entries;
> > }
> >
> > static const struct nvmem_cell_lookup_entry mydev_nvmem_cells[] = {
> >         {
> >                 .con_id = "mac-address",
> >                 .nvmem_name = "mynvmemdev",
> >                 .cell_name = "foo",
> >         },
> >         {
> >                 .con_id = "revision",
> >                 .nvmem_name = "mynvmemdev",
> >                 .cell_name = "bar",
> >         },
> > }
> >
> > static const struct nvmem_cell_lookup_table mydev_nvmem_lookup = {
> >         .dev_id = "mydev.0",
> >         .nentries = ARRAY_SIZE(mydev_nvmem_cells),
> >         .entries = mydev_nvmem_cells,
> > };
> >
> >
> > ...
> >
> >         nvmem_add_cell_lookups(&mydev_nvmem_lookup);  
> 
> Ok I get it. Shouldn't we change the argument name of nvmem_cell_get()
> and friends from 'name' to 'con_id' or simply 'id' similarly to what
> other frameworks do to avoid such confusion?

I'll let Srinivas answer that one.

> 
> I also don't see a need for splitting the lookup into two structures
> here. Something like:
> 
> struct nvmem_cell_lookup {
>         const char *nvmem_name;
>         const char *cell_name;
>         const char *dev_id;
>         const char *con_id;
> };
> 
> Would be perfectly fine and would allow to register all lookups for
> given machine with a single call.

Yep, makes sense.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 11/13] nvmem: add support for cell lookups from machine code
@ 2018-09-05 14:59             ` Boris Brezillon
  0 siblings, 0 replies; 44+ messages in thread
From: Boris Brezillon @ 2018-09-05 14:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 5 Sep 2018 16:47:57 +0200
Bartosz Golaszewski <brgl@bgdev.pl> wrote:

> 2018-09-05 16:21 GMT+02:00 Boris Brezillon <boris.brezillon@bootlin.com>:
> > On Wed, 5 Sep 2018 16:00:36 +0200
> > Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> >  
> >> 2018-09-05 15:57 GMT+02:00 Boris Brezillon <boris.brezillon@bootlin.com>:  
> >> > On Wed,  5 Sep 2018 11:57:36 +0200
> >> > Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> >> >  
> >> >>
> >> >> +struct nvmem_cell_lookup {
> >> >> +     const char              *nvmem_name;
> >> >> +     const char              *dev_id;  
> >> >
> >> > Shouldn't we have a con_id here?
> >> >  
> >> >> +     const char              *cell_id;
> >> >> +     struct list_head        node;
> >> >> +};  
> >>
> >> I wanted to stay in line with the current API - nvmem_cell_get() takes
> >> as argument a string called cell_id. I wanted to reflect that here.  
> >
> > Actually, you need both. con_id is the name you would have in your DT
> > in the nvmem-cell-names property, cell_id is the name of the cell
> > you'd find under the nvmem device node.
> >
> > Let's take an example:
> >
> >         mydev {
> >                 #nvmem-cell-names = "mac-address", "revision";
> >                 #nvmem-cells = <&cell1>, <&cell2>;
> >         };
> >
> >         mynvmemdev {
> >                 #size-cells = <1>;
> >                 #address-cells = <1>;
> >
> >                 cell1: foo at 0 {
> >                         reg = <0x0 0x6>;
> >                 };
> >
> >                 cell2: bar at 6 {
> >                         reg = <0x6 0x10>;
> >                 };
> >         };
> >
> > this can be described the same way using a consumer lookup table:
> >
> > struct nvmem_cell_lookup_entry {
> >         const char *con_id;
> >         const char *nvmem_name;
> >         const char *cell_name;
> > };
> >
> > struct nvmem_cell_lookup_table {
> >         struct list_head node;
> >         const char *dev_id;
> >         unsigned int nentries;
> >         const struct nvmem_cell_lookup_entry *entries;
> > }
> >
> > static const struct nvmem_cell_lookup_entry mydev_nvmem_cells[] = {
> >         {
> >                 .con_id = "mac-address",
> >                 .nvmem_name = "mynvmemdev",
> >                 .cell_name = "foo",
> >         },
> >         {
> >                 .con_id = "revision",
> >                 .nvmem_name = "mynvmemdev",
> >                 .cell_name = "bar",
> >         },
> > }
> >
> > static const struct nvmem_cell_lookup_table mydev_nvmem_lookup = {
> >         .dev_id = "mydev.0",
> >         .nentries = ARRAY_SIZE(mydev_nvmem_cells),
> >         .entries = mydev_nvmem_cells,
> > };
> >
> >
> > ...
> >
> >         nvmem_add_cell_lookups(&mydev_nvmem_lookup);  
> 
> Ok I get it. Shouldn't we change the argument name of nvmem_cell_get()
> and friends from 'name' to 'con_id' or simply 'id' similarly to what
> other frameworks do to avoid such confusion?

I'll let Srinivas answer that one.

> 
> I also don't see a need for splitting the lookup into two structures
> here. Something like:
> 
> struct nvmem_cell_lookup {
>         const char *nvmem_name;
>         const char *cell_name;
>         const char *dev_id;
>         const char *con_id;
> };
> 
> Would be perfectly fine and would allow to register all lookups for
> given machine with a single call.

Yep, makes sense.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 05/13] nvmem: change the signature of nvmem_unregister()
  2018-09-05  9:57   ` Bartosz Golaszewski
@ 2018-09-07  4:48     ` kbuild test robot
  -1 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2018-09-07  4:48 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: kbuild-all, Srinivas Kandagatla, Joachim Eastwood,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Andrew Morton, Arnd Bergmann, Jonathan Corbet, Sekhar Nori,
	Kevin Hilman, David Lechner, Boris Brezillon, Andrew Lunn,
	Alban Bedel, Maxime Ripard, linux-doc, linux-kernel,
	linux-arm-kernel, Bartosz Golaszewski

[-- Attachment #1: Type: text/plain, Size: 2972 bytes --]

Hi Bartosz,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.19-rc2 next-20180906]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Bartosz-Golaszewski/nvmem-rework-of-the-subsystem-for-non-DT-users/20180907-112400
config: i386-randconfig-s3-09061342 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/rtc.h:18:0,
                    from include/linux/efi.h:20,
                    from drivers//char/tpm/eventlog/tpm1.c:24:
   include/linux/nvmem-provider.h: In function 'nvmem_unregister':
>> include/linux/nvmem-provider.h:86:9: warning: 'return' with a value, in function returning void
     return -ENOSYS;
            ^
   include/linux/nvmem-provider.h:84:20: note: declared here
    static inline void nvmem_unregister(struct nvmem_device *nvmem)
                       ^~~~~~~~~~~~~~~~
   include/linux/nvmem-provider.h: In function 'devm_nvmem_unregister':
>> include/linux/nvmem-provider.h:98:9: error: void value not ignored as it ought to be
     return nvmem_unregister(nvmem);
            ^~~~~~~~~~~~~~~~~~~~~~~

vim +98 include/linux/nvmem-provider.h

eace75cf Srinivas Kandagatla 2015-07-27  83  
fd7df99e Bartosz Golaszewski 2018-09-05  84  static inline void nvmem_unregister(struct nvmem_device *nvmem)
eace75cf Srinivas Kandagatla 2015-07-27  85  {
eace75cf Srinivas Kandagatla 2015-07-27 @86  	return -ENOSYS;
eace75cf Srinivas Kandagatla 2015-07-27  87  }
eace75cf Srinivas Kandagatla 2015-07-27  88  
f1f50eca Andrey Smirnov      2018-03-09  89  static inline struct nvmem_device *
f1f50eca Andrey Smirnov      2018-03-09  90  devm_nvmem_register(struct device *dev, const struct nvmem_config *c)
f1f50eca Andrey Smirnov      2018-03-09  91  {
f1f50eca Andrey Smirnov      2018-03-09  92  	return nvmem_register(c);
f1f50eca Andrey Smirnov      2018-03-09  93  }
f1f50eca Andrey Smirnov      2018-03-09  94  
f1f50eca Andrey Smirnov      2018-03-09  95  static inline int
f1f50eca Andrey Smirnov      2018-03-09  96  devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem)
f1f50eca Andrey Smirnov      2018-03-09  97  {
f1f50eca Andrey Smirnov      2018-03-09 @98  	return nvmem_unregister(nvmem);
b3db17e4 Andrew Lunn         2018-05-11  99  

:::::: The code at line 98 was first introduced by commit
:::::: f1f50eca5f90527d2cca3479cda08883958777f6 nvmem: Introduce devm_nvmem_(un)register()

:::::: TO: Andrey Smirnov <andrew.smirnov@gmail.com>
:::::: CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27032 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 05/13] nvmem: change the signature of nvmem_unregister()
@ 2018-09-07  4:48     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2018-09-07  4:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Bartosz,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.19-rc2 next-20180906]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Bartosz-Golaszewski/nvmem-rework-of-the-subsystem-for-non-DT-users/20180907-112400
config: i386-randconfig-s3-09061342 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/rtc.h:18:0,
                    from include/linux/efi.h:20,
                    from drivers//char/tpm/eventlog/tpm1.c:24:
   include/linux/nvmem-provider.h: In function 'nvmem_unregister':
>> include/linux/nvmem-provider.h:86:9: warning: 'return' with a value, in function returning void
     return -ENOSYS;
            ^
   include/linux/nvmem-provider.h:84:20: note: declared here
    static inline void nvmem_unregister(struct nvmem_device *nvmem)
                       ^~~~~~~~~~~~~~~~
   include/linux/nvmem-provider.h: In function 'devm_nvmem_unregister':
>> include/linux/nvmem-provider.h:98:9: error: void value not ignored as it ought to be
     return nvmem_unregister(nvmem);
            ^~~~~~~~~~~~~~~~~~~~~~~

vim +98 include/linux/nvmem-provider.h

eace75cf Srinivas Kandagatla 2015-07-27  83  
fd7df99e Bartosz Golaszewski 2018-09-05  84  static inline void nvmem_unregister(struct nvmem_device *nvmem)
eace75cf Srinivas Kandagatla 2015-07-27  85  {
eace75cf Srinivas Kandagatla 2015-07-27 @86  	return -ENOSYS;
eace75cf Srinivas Kandagatla 2015-07-27  87  }
eace75cf Srinivas Kandagatla 2015-07-27  88  
f1f50eca Andrey Smirnov      2018-03-09  89  static inline struct nvmem_device *
f1f50eca Andrey Smirnov      2018-03-09  90  devm_nvmem_register(struct device *dev, const struct nvmem_config *c)
f1f50eca Andrey Smirnov      2018-03-09  91  {
f1f50eca Andrey Smirnov      2018-03-09  92  	return nvmem_register(c);
f1f50eca Andrey Smirnov      2018-03-09  93  }
f1f50eca Andrey Smirnov      2018-03-09  94  
f1f50eca Andrey Smirnov      2018-03-09  95  static inline int
f1f50eca Andrey Smirnov      2018-03-09  96  devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem)
f1f50eca Andrey Smirnov      2018-03-09  97  {
f1f50eca Andrey Smirnov      2018-03-09 @98  	return nvmem_unregister(nvmem);
b3db17e4 Andrew Lunn         2018-05-11  99  

:::::: The code at line 98 was first introduced by commit
:::::: f1f50eca5f90527d2cca3479cda08883958777f6 nvmem: Introduce devm_nvmem_(un)register()

:::::: TO: Andrey Smirnov <andrew.smirnov@gmail.com>
:::::: CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 27032 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180907/f9aef0bc/attachment-0001.gz>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 05/13] nvmem: change the signature of nvmem_unregister()
  2018-09-05  9:57   ` Bartosz Golaszewski
@ 2018-09-07  4:57     ` kbuild test robot
  -1 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2018-09-07  4:57 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: kbuild-all, Srinivas Kandagatla, Joachim Eastwood,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Andrew Morton, Arnd Bergmann, Jonathan Corbet, Sekhar Nori,
	Kevin Hilman, David Lechner, Boris Brezillon, Andrew Lunn,
	Alban Bedel, Maxime Ripard, linux-doc, linux-kernel,
	linux-arm-kernel, Bartosz Golaszewski

[-- Attachment #1: Type: text/plain, Size: 2171 bytes --]

Hi Bartosz,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.19-rc2 next-20180906]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Bartosz-Golaszewski/nvmem-rework-of-the-subsystem-for-non-DT-users/20180907-112400
config: xtensa-allmodconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.1.0 make.cross ARCH=xtensa 

All error/warnings (new ones prefixed by >>):

   drivers//nvmem/mxs-ocotp.c: In function 'mxs_ocotp_remove':
>> drivers//nvmem/mxs-ocotp.c:202:9: error: void value not ignored as it ought to be
     return nvmem_unregister(otp->nvmem);
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers//nvmem/mxs-ocotp.c:203:1: warning: control reaches end of non-void function [-Wreturn-type]
    }
    ^

vim +202 drivers//nvmem/mxs-ocotp.c

c01e9a11 Stefan Wahren 2015-09-30  195  
c01e9a11 Stefan Wahren 2015-09-30  196  static int mxs_ocotp_remove(struct platform_device *pdev)
c01e9a11 Stefan Wahren 2015-09-30  197  {
c01e9a11 Stefan Wahren 2015-09-30  198  	struct mxs_ocotp *otp = platform_get_drvdata(pdev);
c01e9a11 Stefan Wahren 2015-09-30  199  
c01e9a11 Stefan Wahren 2015-09-30  200  	clk_unprepare(otp->clk);
c01e9a11 Stefan Wahren 2015-09-30  201  
c01e9a11 Stefan Wahren 2015-09-30 @202  	return nvmem_unregister(otp->nvmem);
c01e9a11 Stefan Wahren 2015-09-30 @203  }
c01e9a11 Stefan Wahren 2015-09-30  204  

:::::: The code at line 202 was first introduced by commit
:::::: c01e9a11ab6f3096a54574c3224d8732a374f135 nvmem: add driver for ocotp in i.MX23 and i.MX28

:::::: TO: Stefan Wahren <stefan.wahren@i2se.com>
:::::: CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 54957 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 05/13] nvmem: change the signature of nvmem_unregister()
@ 2018-09-07  4:57     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2018-09-07  4:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Bartosz,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.19-rc2 next-20180906]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Bartosz-Golaszewski/nvmem-rework-of-the-subsystem-for-non-DT-users/20180907-112400
config: xtensa-allmodconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.1.0 make.cross ARCH=xtensa 

All error/warnings (new ones prefixed by >>):

   drivers//nvmem/mxs-ocotp.c: In function 'mxs_ocotp_remove':
>> drivers//nvmem/mxs-ocotp.c:202:9: error: void value not ignored as it ought to be
     return nvmem_unregister(otp->nvmem);
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers//nvmem/mxs-ocotp.c:203:1: warning: control reaches end of non-void function [-Wreturn-type]
    }
    ^

vim +202 drivers//nvmem/mxs-ocotp.c

c01e9a11 Stefan Wahren 2015-09-30  195  
c01e9a11 Stefan Wahren 2015-09-30  196  static int mxs_ocotp_remove(struct platform_device *pdev)
c01e9a11 Stefan Wahren 2015-09-30  197  {
c01e9a11 Stefan Wahren 2015-09-30  198  	struct mxs_ocotp *otp = platform_get_drvdata(pdev);
c01e9a11 Stefan Wahren 2015-09-30  199  
c01e9a11 Stefan Wahren 2015-09-30  200  	clk_unprepare(otp->clk);
c01e9a11 Stefan Wahren 2015-09-30  201  
c01e9a11 Stefan Wahren 2015-09-30 @202  	return nvmem_unregister(otp->nvmem);
c01e9a11 Stefan Wahren 2015-09-30 @203  }
c01e9a11 Stefan Wahren 2015-09-30  204  

:::::: The code at line 202 was first introduced by commit
:::::: c01e9a11ab6f3096a54574c3224d8732a374f135 nvmem: add driver for ocotp in i.MX23 and i.MX28

:::::: TO: Stefan Wahren <stefan.wahren@i2se.com>
:::::: CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 54957 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180907/68865a99/attachment-0001.gz>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 08/13] nvmem: add a notifier chain
  2018-09-05  9:57   ` Bartosz Golaszewski
@ 2018-09-07  5:11     ` kbuild test robot
  -1 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2018-09-07  5:11 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: kbuild-all, Srinivas Kandagatla, Joachim Eastwood,
	David S . Miller, Mauro Carvalho Chehab, Greg Kroah-Hartman,
	Andrew Morton, Arnd Bergmann, Jonathan Corbet, Sekhar Nori,
	Kevin Hilman, David Lechner, Boris Brezillon, Andrew Lunn,
	Alban Bedel, Maxime Ripard, linux-doc, linux-kernel,
	linux-arm-kernel, Bartosz Golaszewski

[-- Attachment #1: Type: text/plain, Size: 1217 bytes --]

Hi Bartosz,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.19-rc2 next-20180906]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Bartosz-Golaszewski/nvmem-rework-of-the-subsystem-for-non-DT-users/20180907-112400
config: i386-randconfig-s3-09061342 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   In file included from drivers//of/of_net.c:10:0:
>> include/linux/nvmem-consumer.h:142:19: error: two or more data types in declaration specifiers
    static inline int int nvmem_unregister_notifier(struct notifier_block *nb)
                      ^~~

vim +142 include/linux/nvmem-consumer.h

   141	
 > 142	static inline int int nvmem_unregister_notifier(struct notifier_block *nb)
   143	{
   144		return -ENOSYS;
   145	}
   146	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27032 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 08/13] nvmem: add a notifier chain
@ 2018-09-07  5:11     ` kbuild test robot
  0 siblings, 0 replies; 44+ messages in thread
From: kbuild test robot @ 2018-09-07  5:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Bartosz,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.19-rc2 next-20180906]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Bartosz-Golaszewski/nvmem-rework-of-the-subsystem-for-non-DT-users/20180907-112400
config: i386-randconfig-s3-09061342 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   In file included from drivers//of/of_net.c:10:0:
>> include/linux/nvmem-consumer.h:142:19: error: two or more data types in declaration specifiers
    static inline int int nvmem_unregister_notifier(struct notifier_block *nb)
                      ^~~

vim +142 include/linux/nvmem-consumer.h

   141	
 > 142	static inline int int nvmem_unregister_notifier(struct notifier_block *nb)
   143	{
   144		return -ENOSYS;
   145	}
   146	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 27032 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180907/566153cb/attachment-0001.gz>

^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2018-09-07  5:11 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-05  9:57 [PATCH 00/13] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
2018-09-05  9:57 ` Bartosz Golaszewski
2018-09-05  9:57 ` [PATCH 01/13] nvmem: remove unused APIs Bartosz Golaszewski
2018-09-05  9:57   ` Bartosz Golaszewski
2018-09-05  9:57 ` [PATCH 02/13] nvmem: remove the global cell list Bartosz Golaszewski
2018-09-05  9:57   ` Bartosz Golaszewski
2018-09-05  9:57 ` [PATCH 03/13] nvmem: use kref Bartosz Golaszewski
2018-09-05  9:57   ` Bartosz Golaszewski
2018-09-05  9:57 ` [PATCH 04/13] nvmem: lpc18xx_eeprom: use devm_nvmem_register() Bartosz Golaszewski
2018-09-05  9:57   ` Bartosz Golaszewski
2018-09-05  9:57 ` [PATCH 05/13] nvmem: change the signature of nvmem_unregister() Bartosz Golaszewski
2018-09-05  9:57   ` Bartosz Golaszewski
2018-09-07  4:48   ` kbuild test robot
2018-09-07  4:48     ` kbuild test robot
2018-09-07  4:57   ` kbuild test robot
2018-09-07  4:57     ` kbuild test robot
2018-09-05  9:57 ` [PATCH 06/13] nvmem: provide nvmem_dev_name() Bartosz Golaszewski
2018-09-05  9:57   ` Bartosz Golaszewski
2018-09-05  9:57 ` [PATCH 07/13] nvmem: remove the name field from struct nvmem_device Bartosz Golaszewski
2018-09-05  9:57   ` Bartosz Golaszewski
2018-09-05  9:57 ` [PATCH 08/13] nvmem: add a notifier chain Bartosz Golaszewski
2018-09-05  9:57   ` Bartosz Golaszewski
2018-09-07  5:11   ` kbuild test robot
2018-09-07  5:11     ` kbuild test robot
2018-09-05  9:57 ` [PATCH 09/13] nvmem: add support for cell info Bartosz Golaszewski
2018-09-05  9:57   ` Bartosz Golaszewski
2018-09-05  9:57 ` [PATCH 10/13] nvmem: resolve cells from DT at registration time Bartosz Golaszewski
2018-09-05  9:57   ` Bartosz Golaszewski
2018-09-05  9:57 ` [PATCH 11/13] nvmem: add support for cell lookups from machine code Bartosz Golaszewski
2018-09-05  9:57   ` Bartosz Golaszewski
2018-09-05 13:57   ` Boris Brezillon
2018-09-05 13:57     ` Boris Brezillon
2018-09-05 14:00     ` Bartosz Golaszewski
2018-09-05 14:00       ` Bartosz Golaszewski
2018-09-05 14:21       ` Boris Brezillon
2018-09-05 14:21         ` Boris Brezillon
2018-09-05 14:47         ` Bartosz Golaszewski
2018-09-05 14:47           ` Bartosz Golaszewski
2018-09-05 14:59           ` Boris Brezillon
2018-09-05 14:59             ` Boris Brezillon
2018-09-05  9:57 ` [PATCH 12/13] Documentation: nvmem: document cell tables and lookup entries Bartosz Golaszewski
2018-09-05  9:57   ` Bartosz Golaszewski
2018-09-05  9:57 ` [PATCH 13/13] nvmem: use SPDX license identifiers Bartosz Golaszewski
2018-09-05  9:57   ` Bartosz Golaszewski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.