linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users
@ 2018-09-14 14:39 Bartosz Golaszewski
  2018-09-14 14:39 ` [PATCH v4 01/22] nvmem: provide nvmem_dev_name() Bartosz Golaszewski
                   ` (22 more replies)
  0 siblings, 23 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:39 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

NOTE: I decided to post v4 despite no new reviews from Srinivas as I'll
be off next week. There were a couple issues reported by the kbuild bot
and one bug I noticed after sending v3.

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.

The patches are conceptually split into a couple groups.

First five patches fix issues with existing issues.

Patch 6 switches the nvmem providers to using kref which is necessary
for removal of the return value from nvmem_unregister(). This is an
approach similar to the one used in the clock framework where the
provider is only removed after the last reference to it is dropped.

Patch 7 changes the errno returned from the driver after kzalloc()
fails from -EINVAL to -ENOMEM which makes more sense.

Patches 8-10 convert last remaining users of nvmem_unregister() who
still check its return value to using devm_nvmem_unregister() and
patch 11 changes its return value from int to void.

Patches 12-15 introduce the most significant changes of this series:
we remove the global cell list, add support for static cell definitions
external to the provider structure, change the way DT lookup works and
allow to associate resources and consumers using lookup tables. The way
nvmem_cell_get() for non-DT users is changed but there are no current
users and it's currently broken anyway (cell being removed after a call
to nvmem_cell_put()).

Patch 16 updates the documentation.

Patch 17 adds support for notifiers to nvmem so that users can
subscribe for events such as device or cell registration or removal.

Patches 18 & 19 add some minor improvements to the codebase.

Last three patches contain fixes to warnings emitted by checkpatch.
It's a good moment to add them if we're already touching a big part
of the subsystem's code.

Tested both DT and non-DT use cases.

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

v1 -> v2:
- extended the lookup structure with a proper con_id independent from the
  cell name defined in the cell definition table
- added a patch that makes the naming convention for the cell name argument
  in the nvmem_cell_get() family of functions consistent
- there were two users of nvmem_unregister() that still checked the return
  value, now switched to devm_nvmem_register()
- fixed build failures reported by kbuild test robot

v2 -> v3:
- dropped the patch removing unused APIs and introduced changes on top of
  existing code instead
- fixed nvmem provider reference decreasing in error paths
- added checkpatch fixes
- removed nvmem-machine.h and distributed new definitions among existing
  consumer and provider headers
- reordered patches thematically
- added more patches fixing issues in existing codebase

v3 -> v4:
- fixed the notifier chain call when removing nvmem devices: call the
  notifier chain for NVMEM_REMOVE before releasing any resources
- added patch 7/22 ("sunxi_sid: return -ENOMEM if kzalloc() fails")
- fixed the return value in error path for patch 8/22 ("sunxi_sid: use
  devm_nvmem_register())"
- fixed the return value of devm_nvmem_unregister() in
  patch 11/22 ("change the signature of nvmem_unregister()")

Bartosz Golaszewski (22):
  nvmem: provide nvmem_dev_name()
  nvmem: remove the name field from struct nvmem_device
  nvmem: use list_for_each_entry_safe in nvmem_device_remove_all_cells()
  nvmem: remove a stray newline
  nvmem: check the return value of nvmem_add_cells()
  nvmem: use kref
  nvmem: sunxi_sid: return -ENOMEM if kzalloc() fails
  nvmem: sunxi_sid: use devm_nvmem_register()
  nvmem: lpc18xx_eeprom: use devm_nvmem_register()
  nvmem: mxs-ocotp: use devm_nvmem_register()
  nvmem: change the signature of nvmem_unregister()
  nvmem: remove the global cell list
  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: add a notifier chain
  nvmem: use SPDX license identifiers
  nvmem: make the naming of arguments in nvmem_cell_get() consistent
  nvmem: use EOPNOTSUPP instead of ENOSYS
  nvmem: fix commenting style
  nvmem: use octal permissions instead of constants

 Documentation/nvmem/nvmem.txt  |  31 ++
 drivers/nvmem/core.c           | 527 ++++++++++++++++++++++-----------
 drivers/nvmem/lpc18xx_eeprom.c |   6 +-
 drivers/nvmem/mxs-ocotp.c      |   4 +-
 drivers/nvmem/sunxi_sid.c      |  20 +-
 include/linux/nvmem-consumer.h | 100 +++++--
 include/linux/nvmem-provider.h |  50 ++--
 7 files changed, 497 insertions(+), 241 deletions(-)

-- 
2.18.0


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

* [PATCH v4 01/22] nvmem: provide nvmem_dev_name()
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
@ 2018-09-14 14:39 ` Bartosz Golaszewski
  2018-09-14 14:39 ` [PATCH v4 02/22] nvmem: remove the name field from struct nvmem_device Bartosz Golaszewski
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:39 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  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 future 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 aa1657831b70..d96348ae0f37 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1343,6 +1343,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 4e85447f7860..0389fe00b177 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -55,6 +55,8 @@ ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
 int nvmem_device_cell_write(struct nvmem_device *nvmem,
 			    struct nvmem_cell_info *info, void *buf);
 
+const char *nvmem_dev_name(struct nvmem_device *nvmem);
+
 #else
 
 static inline struct nvmem_cell *nvmem_cell_get(struct device *dev,
@@ -143,6 +145,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] 25+ messages in thread

* [PATCH v4 02/22] nvmem: remove the name field from struct nvmem_device
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
  2018-09-14 14:39 ` [PATCH v4 01/22] nvmem: provide nvmem_dev_name() Bartosz Golaszewski
@ 2018-09-14 14:39 ` Bartosz Golaszewski
  2018-09-14 14:39 ` [PATCH v4 03/22] nvmem: use list_for_each_entry_safe in nvmem_device_remove_all_cells() Bartosz Golaszewski
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:39 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  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 d96348ae0f37..8987da0f7456 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;
@@ -652,7 +651,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));
 
 		mutex_lock(&nvmem_mutex);
 		nvmem->users--;
-- 
2.18.0


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

* [PATCH v4 03/22] nvmem: use list_for_each_entry_safe in nvmem_device_remove_all_cells()
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
  2018-09-14 14:39 ` [PATCH v4 01/22] nvmem: provide nvmem_dev_name() Bartosz Golaszewski
  2018-09-14 14:39 ` [PATCH v4 02/22] nvmem: remove the name field from struct nvmem_device Bartosz Golaszewski
@ 2018-09-14 14:39 ` Bartosz Golaszewski
  2018-09-14 14:39 ` [PATCH v4 04/22] nvmem: remove a stray newline Bartosz Golaszewski
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:39 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Use the provided helper for iterating over list entries without having
to use the list_entry() macro.

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

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 8987da0f7456..b69005367908 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -308,14 +308,11 @@ static void nvmem_cell_drop(struct nvmem_cell *cell)
 
 static void nvmem_device_remove_all_cells(const 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);
+	list_for_each_entry_safe(cell, p, &nvmem_cells, node)
 		if (cell->nvmem == nvmem)
 			nvmem_cell_drop(cell);
-	}
 }
 
 static void nvmem_cell_add(struct nvmem_cell *cell)
-- 
2.18.0


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

* [PATCH v4 04/22] nvmem: remove a stray newline
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (2 preceding siblings ...)
  2018-09-14 14:39 ` [PATCH v4 03/22] nvmem: use list_for_each_entry_safe in nvmem_device_remove_all_cells() Bartosz Golaszewski
@ 2018-09-14 14:39 ` Bartosz Golaszewski
  2018-09-14 14:39 ` [PATCH v4 05/22] nvmem: check the return value of nvmem_add_cells() Bartosz Golaszewski
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:39 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

There are two empty lines between devm_nvmem_unregister() and
__nvmem_device_get(). Remove one.

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

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index b69005367908..b469f700c699 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -613,7 +613,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_cell **cellp,
 					       const char *cell_id)
-- 
2.18.0


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

* [PATCH v4 05/22] nvmem: check the return value of nvmem_add_cells()
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (3 preceding siblings ...)
  2018-09-14 14:39 ` [PATCH v4 04/22] nvmem: remove a stray newline Bartosz Golaszewski
@ 2018-09-14 14:39 ` Bartosz Golaszewski
  2018-09-14 14:39 ` [PATCH v4 06/22] nvmem: use kref Bartosz Golaszewski
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:39 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

This function can fail so check its return value in nvmem_register()
and act accordingly.

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

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index b469f700c699..ffed8fa16936 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -512,11 +512,17 @@ 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);
+	if (config->cells) {
+		rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
+		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:
-- 
2.18.0


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

* [PATCH v4 06/22] nvmem: use kref
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (4 preceding siblings ...)
  2018-09-14 14:39 ` [PATCH v4 05/22] nvmem: check the return value of nvmem_add_cells() Bartosz Golaszewski
@ 2018-09-14 14:39 ` Bartosz Golaszewski
  2018-09-14 14:39 ` [PATCH v4 07/22] nvmem: sunxi_sid: return -ENOMEM if kzalloc() fails Bartosz Golaszewski
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:39 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  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 | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index ffed8fa16936..552ffedce38e 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -19,6 +19,7 @@
 #include <linux/fs.h>
 #include <linux/idr.h>
 #include <linux/init.h>
+#include <linux/kref.h>
 #include <linux/module.h>
 #include <linux/nvmem-consumer.h>
 #include <linux/nvmem-provider.h>
@@ -31,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;
@@ -463,6 +464,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)
@@ -532,6 +535,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
  *
@@ -541,19 +558,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;
 }
@@ -647,7 +652,6 @@ static struct nvmem_device *__nvmem_device_get(struct device_node *np,
 		}
 	}
 
-	nvmem->users++;
 	mutex_unlock(&nvmem_mutex);
 
 	if (!try_module_get(nvmem->owner)) {
@@ -655,22 +659,18 @@ static struct nvmem_device *__nvmem_device_get(struct device_node *np,
 			"could not increase module refcount for cell %s\n",
 			nvmem_dev_name(nvmem));
 
-		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] 25+ messages in thread

* [PATCH v4 07/22] nvmem: sunxi_sid: return -ENOMEM if kzalloc() fails
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (5 preceding siblings ...)
  2018-09-14 14:39 ` [PATCH v4 06/22] nvmem: use kref Bartosz Golaszewski
@ 2018-09-14 14:39 ` Bartosz Golaszewski
  2018-09-14 14:39 ` [PATCH v4 08/22] nvmem: sunxi_sid: use devm_nvmem_register() Bartosz Golaszewski
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:39 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

The driver currently returns -EINVAL if kzalloc() fails in probe().
Change it to -ENOMEM as it should be.

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

diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index d020f89248fd..4d0b7e72aa2e 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -187,7 +187,7 @@ static int sunxi_sid_probe(struct platform_device *pdev)
 
 	randomness = kzalloc(size, GFP_KERNEL);
 	if (!randomness) {
-		ret = -EINVAL;
+		ret = -ENOMEM;
 		goto err_unreg_nvmem;
 	}
 
-- 
2.18.0


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

* [PATCH v4 08/22] nvmem: sunxi_sid: use devm_nvmem_register()
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (6 preceding siblings ...)
  2018-09-14 14:39 ` [PATCH v4 07/22] nvmem: sunxi_sid: return -ENOMEM if kzalloc() fails Bartosz Golaszewski
@ 2018-09-14 14:39 ` Bartosz Golaszewski
  2018-09-14 14:39 ` [PATCH v4 09/22] nvmem: lpc18xx_eeprom: " Bartosz Golaszewski
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:39 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Use the resource managed variant of nvmem_register().

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

diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index 4d0b7e72aa2e..1310f8af37f8 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -181,15 +181,13 @@ static int sunxi_sid_probe(struct platform_device *pdev)
 	else
 		econfig.reg_read = sunxi_sid_read;
 	econfig.priv = sid;
-	nvmem = nvmem_register(&econfig);
+	nvmem = devm_nvmem_register(dev, &econfig);
 	if (IS_ERR(nvmem))
 		return PTR_ERR(nvmem);
 
 	randomness = kzalloc(size, GFP_KERNEL);
-	if (!randomness) {
-		ret = -ENOMEM;
-		goto err_unreg_nvmem;
-	}
+	if (!randomness)
+		return -ENOMEM;
 
 	for (i = 0; i < size; i++)
 		econfig.reg_read(sid, i, &randomness[i], 1);
@@ -200,17 +198,6 @@ static int sunxi_sid_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, nvmem);
 
 	return 0;
-
-err_unreg_nvmem:
-	nvmem_unregister(nvmem);
-	return ret;
-}
-
-static int sunxi_sid_remove(struct platform_device *pdev)
-{
-	struct nvmem_device *nvmem = platform_get_drvdata(pdev);
-
-	return nvmem_unregister(nvmem);
 }
 
 static const struct sunxi_sid_cfg sun4i_a10_cfg = {
@@ -243,7 +230,6 @@ MODULE_DEVICE_TABLE(of, sunxi_sid_of_match);
 
 static struct platform_driver sunxi_sid_driver = {
 	.probe = sunxi_sid_probe,
-	.remove = sunxi_sid_remove,
 	.driver = {
 		.name = "eeprom-sunxi-sid",
 		.of_match_table = sunxi_sid_of_match,
-- 
2.18.0


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

* [PATCH v4 09/22] nvmem: lpc18xx_eeprom: use devm_nvmem_register()
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (7 preceding siblings ...)
  2018-09-14 14:39 ` [PATCH v4 08/22] nvmem: sunxi_sid: use devm_nvmem_register() Bartosz Golaszewski
@ 2018-09-14 14:39 ` Bartosz Golaszewski
  2018-09-14 14:39 ` [PATCH v4 10/22] nvmem: mxs-ocotp: " Bartosz Golaszewski
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:39 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  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] 25+ messages in thread

* [PATCH v4 10/22] nvmem: mxs-ocotp: use devm_nvmem_register()
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (8 preceding siblings ...)
  2018-09-14 14:39 ` [PATCH v4 09/22] nvmem: lpc18xx_eeprom: " Bartosz Golaszewski
@ 2018-09-14 14:39 ` Bartosz Golaszewski
  2018-09-14 14:40 ` [PATCH v4 11/22] nvmem: change the signature of nvmem_unregister() Bartosz Golaszewski
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:39 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Use the resource managed variant of nvmem_register();

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

diff --git a/drivers/nvmem/mxs-ocotp.c b/drivers/nvmem/mxs-ocotp.c
index 7018e2ef5714..53122f59c4b2 100644
--- a/drivers/nvmem/mxs-ocotp.c
+++ b/drivers/nvmem/mxs-ocotp.c
@@ -177,7 +177,7 @@ static int mxs_ocotp_probe(struct platform_device *pdev)
 	ocotp_config.size = data->size;
 	ocotp_config.priv = otp;
 	ocotp_config.dev = dev;
-	otp->nvmem = nvmem_register(&ocotp_config);
+	otp->nvmem = devm_nvmem_register(dev, &ocotp_config);
 	if (IS_ERR(otp->nvmem)) {
 		ret = PTR_ERR(otp->nvmem);
 		goto err_clk;
@@ -199,7 +199,7 @@ static int mxs_ocotp_remove(struct platform_device *pdev)
 
 	clk_unprepare(otp->clk);
 
-	return nvmem_unregister(otp->nvmem);
+	return 0;
 }
 
 static struct platform_driver mxs_ocotp_driver = {
-- 
2.18.0


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

* [PATCH v4 11/22] nvmem: change the signature of nvmem_unregister()
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (9 preceding siblings ...)
  2018-09-14 14:39 ` [PATCH v4 10/22] nvmem: mxs-ocotp: " Bartosz Golaszewski
@ 2018-09-14 14:40 ` Bartosz Golaszewski
  2018-09-14 14:40 ` [PATCH v4 12/22] nvmem: remove the global cell list Bartosz Golaszewski
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:40 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

We switched the nvmem framework to using kref instead of manually
checking the current number of users in nvmem_unregister() so this
function can no longer fail. We also converted all remaining users
that still checked the return value of nvmem_unregister() to using
devm_nvmem_register(). Make the routine return void.

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

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 552ffedce38e..c950d54bb69d 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -553,20 +553,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 24def6ad09bb..0f357d0c1e75 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -70,7 +70,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);
@@ -87,10 +87,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)
-{
-	return -ENOSYS;
-}
+static inline void nvmem_unregister(struct nvmem_device *nvmem) {}
 
 static inline struct nvmem_device *
 devm_nvmem_register(struct device *dev, const struct nvmem_config *c)
@@ -101,7 +98,7 @@ devm_nvmem_register(struct device *dev, const struct nvmem_config *c)
 static inline int
 devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem)
 {
-	return nvmem_unregister(nvmem);
+	return -ENOSYS;
 
 }
 
-- 
2.18.0


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

* [PATCH v4 12/22] nvmem: remove the global cell list
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (10 preceding siblings ...)
  2018-09-14 14:40 ` [PATCH v4 11/22] nvmem: change the signature of nvmem_unregister() Bartosz Golaszewski
@ 2018-09-14 14:40 ` Bartosz Golaszewski
  2018-09-14 14:40 ` [PATCH v4 13/22] nvmem: add support for cell info Bartosz Golaszewski
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:40 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Nvmem subsystem keeps a global list of cells that, for non-DT systems,
can only be referenced by cell name, which makes it impossible to have
more than one nvmem device with cells named the same.

This patch makes every nvmem device the owner of the list of its cells.
This effectively removes the support for non-DT systems, but it will
be reintroduced following a different approach in subsequent patches.

This isn't a problem as support for board files in nvmem is currently
broken anyway: any user that would try to get an nvmem cell from the
global cell list would remove the cell after the calling
nvmem_cell_put(). This can cause anything from a subsequent user not
being able to get the cell to double free errors if more users hold
reference to the same cell at the same time.

Fortunately there are no such users which allows us to rework this part.

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

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index c950d54bb69d..585688ea2152 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
@@ -282,28 +280,11 @@ 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);
+	mutex_lock(&nvmem_mutex);
 	list_del(&cell->node);
-	mutex_unlock(&nvmem_cells_mutex);
+	mutex_unlock(&nvmem_mutex);
 	kfree(cell);
 }
 
@@ -311,16 +292,15 @@ static void nvmem_device_remove_all_cells(const struct nvmem_device *nvmem)
 {
 	struct nvmem_cell *cell, *p;
 
-	list_for_each_entry_safe(cell, p, &nvmem_cells, 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);
 }
 
 static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem,
@@ -465,6 +445,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	}
 
 	kref_init(&nvmem->refcnt);
+	INIT_LIST_HEAD(&nvmem->cells);
 
 	nvmem->id = rval;
 	nvmem->owner = config->owner;
@@ -626,29 +607,14 @@ 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 (cell) {
-			nvmem = cell->nvmem;
-			*cellp = cell;
-		}
-
-		if (!nvmem) {
-			mutex_unlock(&nvmem_mutex);
-			return ERR_PTR(-ENOENT);
-		}
-	}
+	if (!np)
+		return ERR_PTR(-ENOENT);
 
+	mutex_lock(&nvmem_mutex);
+	nvmem = of_nvmem_find(np);
 	mutex_unlock(&nvmem_mutex);
+	if (!nvmem)
+		return ERR_PTR(-EPROBE_DEFER);
 
 	if (!try_module_get(nvmem->owner)) {
 		dev_err(&nvmem->dev,
-- 
2.18.0


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

* [PATCH v4 13/22] nvmem: add support for cell info
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (11 preceding siblings ...)
  2018-09-14 14:40 ` [PATCH v4 12/22] nvmem: remove the global cell list Bartosz Golaszewski
@ 2018-09-14 14:40 ` Bartosz Golaszewski
  2018-09-14 14:40 ` [PATCH v4 14/22] nvmem: resolve cells from DT at registration time Bartosz Golaszewski
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:40 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  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>
---
 drivers/nvmem/core.c           | 72 ++++++++++++++++++++++++++++++++++
 include/linux/nvmem-provider.h | 33 +++++++++++-----
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 585688ea2152..9329857f6137 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -59,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);
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static struct lock_class_key eeprom_lock_key;
 #endif
@@ -416,6 +419,43 @@ static int nvmem_setup_compat(struct nvmem_device *nvmem,
 	return 0;
 }
 
+static int nvmem_add_cells_from_table(struct nvmem_device *nvmem)
+{
+	const struct nvmem_cell_info *info;
+	struct nvmem_cell_table *table;
+	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 = kzalloc(sizeof(*cell), GFP_KERNEL);
+				if (!cell) {
+					rval = -ENOMEM;
+					goto out;
+				}
+
+				rval = nvmem_cell_info_to_nvmem_cell(nvmem,
+								     info,
+								     cell);
+				if (rval) {
+					kfree(cell);
+					goto out;
+				}
+
+				nvmem_cell_add(cell);
+			}
+		}
+	}
+
+out:
+	mutex_unlock(&nvmem_cell_mutex);
+	return rval;
+}
+
 /**
  * nvmem_register() - Register a nvmem device for given nvmem_config.
  * Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
@@ -502,8 +542,14 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 			goto err_teardown_compat;
 	}
 
+	rval = nvmem_add_cells_from_table(nvmem);
+	if (rval)
+		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);
@@ -1306,6 +1352,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-provider.h b/include/linux/nvmem-provider.h
index 0f357d0c1e75..5c9f205cac8f 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -67,6 +67,25 @@ struct nvmem_config {
 	struct device		*base_dev;
 };
 
+/**
+ * struct nvmem_cell_table - NVMEM cell definitions for given provider
+ *
+ * @nvmem_name:		Provider name.
+ * @cells:		Array of cell definitions.
+ * @ncells:		Number of cell definitions in the array.
+ * @node:		List node.
+ *
+ * This structure together with related helper functions is provided for users
+ * that don't can't access the nvmem provided structure but wish to register
+ * cell definitions for it e.g. board files registering an EEPROM device.
+ */
+struct nvmem_cell_table {
+	const char		*nvmem_name;
+	const struct nvmem_cell_info	*cells;
+	size_t			ncells;
+	struct list_head	node;
+};
+
 #if IS_ENABLED(CONFIG_NVMEM)
 
 struct nvmem_device *nvmem_register(const struct nvmem_config *cfg);
@@ -77,9 +96,9 @@ 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);
+void nvmem_add_cell_table(struct nvmem_cell_table *table);
+void nvmem_del_cell_table(struct nvmem_cell_table *table);
+
 #else
 
 static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
@@ -102,12 +121,8 @@ 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;
-}
+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_PROVIDER_H */
-- 
2.18.0


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

* [PATCH v4 14/22] nvmem: resolve cells from DT at registration time
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (12 preceding siblings ...)
  2018-09-14 14:40 ` [PATCH v4 13/22] nvmem: add support for cell info Bartosz Golaszewski
@ 2018-09-14 14:40 ` Bartosz Golaszewski
  2018-09-14 14:40 ` [PATCH v4 15/22] nvmem: add support for cell lookups from machine code Bartosz Golaszewski
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:40 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  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 user
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 | 123 ++++++++++++++++++++++++++-----------------
 1 file changed, 75 insertions(+), 48 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 9329857f6137..13568e7ad178 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -456,6 +456,73 @@ static int nvmem_add_cells_from_table(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() - Register a nvmem device for given nvmem_config.
  * Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
@@ -546,6 +613,10 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	if (rval)
 		goto err_remove_cells;
 
+	rval = nvmem_add_cells_from_of(nvmem);
+	if (rval)
+		goto err_remove_cells;
+
 	return nvmem;
 
 err_remove_cells:
@@ -848,10 +919,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 */
@@ -871,54 +940,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
@@ -1024,7 +1052,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] 25+ messages in thread

* [PATCH v4 15/22] nvmem: add support for cell lookups from machine code
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (13 preceding siblings ...)
  2018-09-14 14:40 ` [PATCH v4 14/22] nvmem: resolve cells from DT at registration time Bartosz Golaszewski
@ 2018-09-14 14:40 ` Bartosz Golaszewski
  2018-09-21  1:12   ` Srinivas Kandagatla
  2018-09-14 14:40 ` [PATCH v4 16/22] Documentation: nvmem: document cell tables and lookup entries Bartosz Golaszewski
                   ` (7 subsequent siblings)
  22 siblings, 1 reply; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:40 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  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.

This restores the support for non-DT systems but following a different
approach. Cells must now be associated with devices using provided
routines and data structures before they can be retrieved using
nvmem_cell_get().

It's still possible to define cells statically in nvmem_config but
cells created this way still need to be associated with consumers using
lookup entries.

Note that nvmem_find() must be moves higher in the source file as we
want to call it from __nvmem_device_get() for devices that don't have
a device node.

The signature of __nvmem_device_get() is also changed as it's no longer
used to retrieve cells.

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

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 13568e7ad178..9cc86d131e1e 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);
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static struct lock_class_key eeprom_lock_key;
 #endif
@@ -283,6 +286,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);
@@ -472,6 +487,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;
@@ -719,16 +749,12 @@ 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)
+					       const char *nvmem_name)
 {
 	struct nvmem_device *nvmem = NULL;
 
-	if (!np)
-		return ERR_PTR(-ENOENT);
-
 	mutex_lock(&nvmem_mutex);
-	nvmem = of_nvmem_find(np);
+	nvmem = np ? of_nvmem_find(np) : nvmem_find(nvmem_name);
 	mutex_unlock(&nvmem_mutex);
 	if (!nvmem)
 		return ERR_PTR(-EPROBE_DEFER);
@@ -752,18 +778,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
@@ -786,7 +800,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, NULL);
 }
 EXPORT_SYMBOL_GPL(of_nvmem_device_get);
 #endif
@@ -890,15 +904,43 @@ 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)
+static struct nvmem_cell *
+nvmem_cell_get_from_lookup(struct device *dev, const char *con_id)
 {
-	struct nvmem_cell *cell = NULL;
+	struct nvmem_cell *cell = ERR_PTR(-ENOENT);
+	struct nvmem_cell_lookup *lookup;
 	struct nvmem_device *nvmem;
+	const char *dev_id;
 
-	nvmem = __nvmem_device_get(NULL, &cell, cell_id);
-	if (IS_ERR(nvmem))
-		return ERR_CAST(nvmem);
+	if (!dev)
+		return ERR_PTR(-EINVAL);
+
+	dev_id = dev_name(dev);
+
+	mutex_lock(&nvmem_lookup_mutex);
+
+	list_for_each_entry(lookup, &nvmem_lookup_list, node) {
+		if ((strcmp(lookup->dev_id, dev_id) == 0) &&
+		    (strcmp(lookup->con_id, con_id) == 0)) {
+			/* This is the right entry. */
+			nvmem = __nvmem_device_get(NULL, lookup->nvmem_name);
+			if (!nvmem) {
+				/* Provider may not be registered yet. */
+				cell = ERR_PTR(-EPROBE_DEFER);
+				goto out;
+			}
+
+			cell = nvmem_find_cell_by_name(nvmem,
+						       lookup->cell_name);
+			if (!cell) {
+				__nvmem_device_put(nvmem);
+				goto out;
+			}
+		}
+	}
 
+out:
+	mutex_unlock(&nvmem_lookup_mutex);
 	return cell;
 }
 
@@ -935,7 +977,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, NULL);
 	of_node_put(nvmem_np);
 	if (IS_ERR(nvmem))
 		return ERR_CAST(nvmem);
@@ -975,7 +1017,7 @@ struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *cell_id)
 	if (!cell_id)
 		return ERR_PTR(-EINVAL);
 
-	return nvmem_cell_get_from_list(cell_id);
+	return nvmem_cell_get_from_lookup(dev, cell_id);
 }
 EXPORT_SYMBOL_GPL(nvmem_cell_get);
 
@@ -1405,6 +1447,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-consumer.h b/include/linux/nvmem-consumer.h
index 0389fe00b177..27eee3945405 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -29,6 +29,24 @@ struct nvmem_cell_info {
 	unsigned int		nbits;
 };
 
+/**
+ * struct nvmem_cell_lookup - cell lookup entry
+ *
+ * @nvmem_name:	Name of the provider.
+ * @cell_name:	Name of the nvmem cell as defined in the name field of
+ *		struct nvmem_cell_info.
+ * @dev_id:	Name of the consumer device that will be associated with
+ *		this cell.
+ * @con_id:	Connector id for this cell lookup.
+ */
+struct nvmem_cell_lookup {
+	const char		*nvmem_name;
+	const char		*cell_name;
+	const char		*dev_id;
+	const char		*con_id;
+	struct list_head	node;
+};
+
 #if IS_ENABLED(CONFIG_NVMEM)
 
 /* Cell based interface */
@@ -57,6 +75,11 @@ int nvmem_device_cell_write(struct nvmem_device *nvmem,
 
 const char *nvmem_dev_name(struct nvmem_device *nvmem);
 
+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
 
 static inline struct nvmem_cell *nvmem_cell_get(struct device *dev,
@@ -151,6 +174,11 @@ static inline const char *nvmem_dev_name(struct nvmem_device *nvmem)
 	return NULL;
 }
 
+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 */
 
 #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
-- 
2.18.0


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

* [PATCH v4 16/22] Documentation: nvmem: document cell tables and lookup entries
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (14 preceding siblings ...)
  2018-09-14 14:40 ` [PATCH v4 15/22] nvmem: add support for cell lookups from machine code Bartosz Golaszewski
@ 2018-09-14 14:40 ` Bartosz Golaszewski
  2018-09-14 14:40 ` [PATCH v4 17/22] nvmem: add a notifier chain Bartosz Golaszewski
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:40 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  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 | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/Documentation/nvmem/nvmem.txt b/Documentation/nvmem/nvmem.txt
index 8d8d8f58f96f..fc2fe4b18655 100644
--- a/Documentation/nvmem/nvmem.txt
+++ b/Documentation/nvmem/nvmem.txt
@@ -58,6 +58,37 @@ 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		= "macaddr",
+		.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",
+	.cell_name		= "macaddr",
+	.dev_id			= "foo_mac.0",
+	.con_id			= "mac-address",
+};
+
+nvmem_add_cell_lookups(&foo_nvmem_lookup, 1);
+
 NVMEM Consumers
 +++++++++++++++
 
-- 
2.18.0


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

* [PATCH v4 17/22] nvmem: add a notifier chain
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (15 preceding siblings ...)
  2018-09-14 14:40 ` [PATCH v4 16/22] Documentation: nvmem: document cell tables and lookup entries Bartosz Golaszewski
@ 2018-09-14 14:40 ` Bartosz Golaszewski
  2018-09-14 14:40 ` [PATCH v4 18/22] nvmem: use SPDX license identifiers Bartosz Golaszewski
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:40 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Add a blocking notifier chain with four events (add and remove for
both devices and cells) so that users can get notified about the
addition of nvmem resources 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 | 21 ++++++++++++++++++++
 2 files changed, 57 insertions(+)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 9cc86d131e1e..da441019b609 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -65,6 +65,8 @@ 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
 static struct lock_class_key eeprom_lock_key;
 #endif
@@ -300,6 +302,7 @@ static struct nvmem_device *nvmem_find(const char *name)
 
 static void nvmem_cell_drop(struct nvmem_cell *cell)
 {
+	blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_REMOVE, cell);
 	mutex_lock(&nvmem_mutex);
 	list_del(&cell->node);
 	mutex_unlock(&nvmem_mutex);
@@ -319,6 +322,7 @@ static void nvmem_cell_add(struct nvmem_cell *cell)
 	mutex_lock(&nvmem_mutex);
 	list_add_tail(&cell->node, &cell->nvmem->cells);
 	mutex_unlock(&nvmem_mutex);
+	blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_ADD, cell);
 }
 
 static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem,
@@ -434,6 +438,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);
+
 static int nvmem_add_cells_from_table(struct nvmem_device *nvmem)
 {
 	const struct nvmem_cell_info *info;
@@ -647,6 +677,10 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	if (rval)
 		goto err_remove_cells;
 
+	rval = blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem);
+	if (rval)
+		goto err_remove_cells;
+
 	return nvmem;
 
 err_remove_cells:
@@ -669,6 +703,8 @@ static void nvmem_device_release(struct kref *kref)
 
 	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 27eee3945405..0326b52e906b 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;
@@ -47,6 +48,13 @@ struct nvmem_cell_lookup {
 	struct list_head	node;
 };
 
+enum {
+	NVMEM_ADD = 1,
+	NVMEM_REMOVE,
+	NVMEM_CELL_ADD,
+	NVMEM_CELL_REMOVE,
+};
+
 #if IS_ENABLED(CONFIG_NVMEM)
 
 /* Cell based interface */
@@ -80,6 +88,9 @@ void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries,
 void nvmem_del_cell_lookups(struct nvmem_cell_lookup *entries,
 			    size_t nentries);
 
+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,
@@ -179,6 +190,16 @@ 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) {}
 
+static inline int nvmem_register_notifier(struct notifier_block *nb)
+{
+	return -ENOSYS;
+}
+
+static inline 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] 25+ messages in thread

* [PATCH v4 18/22] nvmem: use SPDX license identifiers
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (16 preceding siblings ...)
  2018-09-14 14:40 ` [PATCH v4 17/22] nvmem: add a notifier chain Bartosz Golaszewski
@ 2018-09-14 14:40 ` Bartosz Golaszewski
  2018-09-14 14:40 ` [PATCH v4 19/22] nvmem: make the naming of arguments in nvmem_cell_get() consistent Bartosz Golaszewski
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:40 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  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 da441019b609..ea05219e60b4 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 0326b52e906b..d18caae2f7ac 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 5c9f205cac8f..8ae012f6545a 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] 25+ messages in thread

* [PATCH v4 19/22] nvmem: make the naming of arguments in nvmem_cell_get() consistent
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (17 preceding siblings ...)
  2018-09-14 14:40 ` [PATCH v4 18/22] nvmem: use SPDX license identifiers Bartosz Golaszewski
@ 2018-09-14 14:40 ` Bartosz Golaszewski
  2018-09-14 14:40 ` [PATCH v4 20/22] nvmem: use EOPNOTSUPP instead of ENOSYS Bartosz Golaszewski
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:40 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

The argument representing the cell name in the nvmem_cell_get() family
of functions is not consistend between function prototypes and
definitions. Name it 'id' in all those routines. This is in line with
other frameworks and can represent both the DT cell name from the
nvmem-cell-names property as well as the con_id field from cell
lookup entries.

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

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index ea05219e60b4..ff21402fbd7d 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -977,16 +977,15 @@ nvmem_cell_get_from_lookup(struct device *dev, const char *con_id)
  * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
  *
  * @np: Device tree node that uses the nvmem cell.
- * @name: nvmem cell name from nvmem-cell-names property, or NULL
- *	  for the cell at index 0 (the lone cell with no accompanying
- *	  nvmem-cell-names property).
+ * @id: nvmem cell name from nvmem-cell-names property, or NULL
+ *      for the cell at index 0 (the lone cell with no accompanying
+ *      nvmem-cell-names property).
  *
  * Return: Will be an ERR_PTR() on error or a valid pointer
  * to a struct nvmem_cell.  The nvmem_cell will be freed by the
  * nvmem_cell_put().
  */
-struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
-					    const char *name)
+struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id)
 {
 	struct device_node *cell_np, *nvmem_np;
 	struct nvmem_device *nvmem;
@@ -994,8 +993,8 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
 	int index = 0;
 
 	/* if cell name exists, find index to the name */
-	if (name)
-		index = of_property_match_string(np, "nvmem-cell-names", name);
+	if (id)
+		index = of_property_match_string(np, "nvmem-cell-names", id);
 
 	cell_np = of_parse_phandle(np, "nvmem-cells", index);
 	if (!cell_np)
@@ -1025,27 +1024,29 @@ EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
  * nvmem_cell_get() - Get nvmem cell of device form a given cell name
  *
  * @dev: Device that requests the nvmem cell.
- * @cell_id: nvmem cell name to get.
+ * @id: nvmem cell name to get (this corresponds with the name from the
+ *      nvmem-cell-names property for DT systems and with the con_id from
+ *      the lookup entry for non-DT systems).
  *
  * Return: Will be an ERR_PTR() on error or a valid pointer
  * to a struct nvmem_cell.  The nvmem_cell will be freed by the
  * nvmem_cell_put().
  */
-struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *cell_id)
+struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *id)
 {
 	struct nvmem_cell *cell;
 
 	if (dev->of_node) { /* try dt first */
-		cell = of_nvmem_cell_get(dev->of_node, cell_id);
+		cell = of_nvmem_cell_get(dev->of_node, 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)
+	/* NULL cell id only allowed for device tree; invalid otherwise */
+	if (!id)
 		return ERR_PTR(-EINVAL);
 
-	return nvmem_cell_get_from_lookup(dev, cell_id);
+	return nvmem_cell_get_from_lookup(dev, id);
 }
 EXPORT_SYMBOL_GPL(nvmem_cell_get);
 
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index d18caae2f7ac..e17617fa034f 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -55,8 +55,8 @@ enum {
 #if IS_ENABLED(CONFIG_NVMEM)
 
 /* Cell based interface */
-struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *name);
-struct nvmem_cell *devm_nvmem_cell_get(struct device *dev, const char *name);
+struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *id);
+struct nvmem_cell *devm_nvmem_cell_get(struct device *dev, const char *id);
 void nvmem_cell_put(struct nvmem_cell *cell);
 void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
 void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len);
@@ -91,13 +91,13 @@ int nvmem_unregister_notifier(struct notifier_block *nb);
 #else
 
 static inline struct nvmem_cell *nvmem_cell_get(struct device *dev,
-						const char *name)
+						const char *id)
 {
 	return ERR_PTR(-ENOSYS);
 }
 
 static inline struct nvmem_cell *devm_nvmem_cell_get(struct device *dev,
-				       const char *name)
+						     const char *id)
 {
 	return ERR_PTR(-ENOSYS);
 }
@@ -201,12 +201,12 @@ static inline int nvmem_unregister_notifier(struct notifier_block *nb)
 
 #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
 struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
-				     const char *name);
+				     const char *id);
 struct nvmem_device *of_nvmem_device_get(struct device_node *np,
 					 const char *name);
 #else
 static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
-				     const char *name)
+						   const char *id)
 {
 	return ERR_PTR(-ENOSYS);
 }
-- 
2.18.0


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

* [PATCH v4 20/22] nvmem: use EOPNOTSUPP instead of ENOSYS
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (18 preceding siblings ...)
  2018-09-14 14:40 ` [PATCH v4 19/22] nvmem: make the naming of arguments in nvmem_cell_get() consistent Bartosz Golaszewski
@ 2018-09-14 14:40 ` Bartosz Golaszewski
  2018-09-14 14:40 ` [PATCH v4 21/22] nvmem: fix commenting style Bartosz Golaszewski
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:40 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Checkpatch emits warnings when using ENOSYS. Some of the frameworks
started using EOPNOTSUPP as return values for API functions when given
subsystem is disabled in Kconfig.

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

diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index e17617fa034f..312bfa5efd80 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -93,13 +93,13 @@ int nvmem_unregister_notifier(struct notifier_block *nb);
 static inline struct nvmem_cell *nvmem_cell_get(struct device *dev,
 						const char *id)
 {
-	return ERR_PTR(-ENOSYS);
+	return ERR_PTR(-EOPNOTSUPP);
 }
 
 static inline struct nvmem_cell *devm_nvmem_cell_get(struct device *dev,
 						     const char *id)
 {
-	return ERR_PTR(-ENOSYS);
+	return ERR_PTR(-EOPNOTSUPP);
 }
 
 static inline void devm_nvmem_cell_put(struct device *dev,
@@ -113,31 +113,31 @@ static inline void nvmem_cell_put(struct nvmem_cell *cell)
 
 static inline void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
 {
-	return ERR_PTR(-ENOSYS);
+	return ERR_PTR(-EOPNOTSUPP);
 }
 
 static inline int nvmem_cell_write(struct nvmem_cell *cell,
 				    const char *buf, size_t len)
 {
-	return -ENOSYS;
+	return -EOPNOTSUPP;
 }
 
 static inline int nvmem_cell_read_u32(struct device *dev,
 				      const char *cell_id, u32 *val)
 {
-	return -ENOSYS;
+	return -EOPNOTSUPP;
 }
 
 static inline struct nvmem_device *nvmem_device_get(struct device *dev,
 						    const char *name)
 {
-	return ERR_PTR(-ENOSYS);
+	return ERR_PTR(-EOPNOTSUPP);
 }
 
 static inline struct nvmem_device *devm_nvmem_device_get(struct device *dev,
 							 const char *name)
 {
-	return ERR_PTR(-ENOSYS);
+	return ERR_PTR(-EOPNOTSUPP);
 }
 
 static inline void nvmem_device_put(struct nvmem_device *nvmem)
@@ -153,28 +153,28 @@ static inline ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem,
 					 struct nvmem_cell_info *info,
 					 void *buf)
 {
-	return -ENOSYS;
+	return -EOPNOTSUPP;
 }
 
 static inline int nvmem_device_cell_write(struct nvmem_device *nvmem,
 					  struct nvmem_cell_info *info,
 					  void *buf)
 {
-	return -ENOSYS;
+	return -EOPNOTSUPP;
 }
 
 static inline int nvmem_device_read(struct nvmem_device *nvmem,
 				    unsigned int offset, size_t bytes,
 				    void *buf)
 {
-	return -ENOSYS;
+	return -EOPNOTSUPP;
 }
 
 static inline int nvmem_device_write(struct nvmem_device *nvmem,
 				     unsigned int offset, size_t bytes,
 				     void *buf)
 {
-	return -ENOSYS;
+	return -EOPNOTSUPP;
 }
 
 static inline const char *nvmem_dev_name(struct nvmem_device *nvmem)
@@ -189,12 +189,12 @@ nvmem_del_cell_lookups(struct nvmem_cell_lookup *entries, size_t nentries) {}
 
 static inline int nvmem_register_notifier(struct notifier_block *nb)
 {
-	return -ENOSYS;
+	return -EOPNOTSUPP;
 }
 
 static inline int nvmem_unregister_notifier(struct notifier_block *nb)
 {
-	return -ENOSYS;
+	return -EOPNOTSUPP;
 }
 
 #endif /* CONFIG_NVMEM */
@@ -208,13 +208,13 @@ struct nvmem_device *of_nvmem_device_get(struct device_node *np,
 static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
 						   const char *id)
 {
-	return ERR_PTR(-ENOSYS);
+	return ERR_PTR(-EOPNOTSUPP);
 }
 
 static inline struct nvmem_device *of_nvmem_device_get(struct device_node *np,
 						       const char *name)
 {
-	return ERR_PTR(-ENOSYS);
+	return ERR_PTR(-EOPNOTSUPP);
 }
 #endif /* CONFIG_NVMEM && CONFIG_OF */
 
diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
index 8ae012f6545a..1e3283c2af77 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -100,7 +100,7 @@ void nvmem_del_cell_table(struct nvmem_cell_table *table);
 
 static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
 {
-	return ERR_PTR(-ENOSYS);
+	return ERR_PTR(-EOPNOTSUPP);
 }
 
 static inline void nvmem_unregister(struct nvmem_device *nvmem) {}
@@ -114,8 +114,7 @@ devm_nvmem_register(struct device *dev, const struct nvmem_config *c)
 static inline int
 devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem)
 {
-	return -ENOSYS;
-
+	return -EOPNOTSUPP;
 }
 
 static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {}
-- 
2.18.0


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

* [PATCH v4 21/22] nvmem: fix commenting style
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (19 preceding siblings ...)
  2018-09-14 14:40 ` [PATCH v4 20/22] nvmem: use EOPNOTSUPP instead of ENOSYS Bartosz Golaszewski
@ 2018-09-14 14:40 ` Bartosz Golaszewski
  2018-09-14 14:40 ` [PATCH v4 22/22] nvmem: use octal permissions instead of constants Bartosz Golaszewski
  2018-09-16 14:08 ` [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Srinivas Kandagatla
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:40 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Remove a redundant '*/' as pointed out by checkpatch.

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

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index ff21402fbd7d..e44a1860a2b3 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1374,7 +1374,7 @@ EXPORT_SYMBOL_GPL(nvmem_device_cell_read);
  * @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)
 {
@@ -1430,7 +1430,7 @@ EXPORT_SYMBOL_GPL(nvmem_device_read);
  * @buf: buffer to be written.
  *
  * Return: length of bytes written or negative error code on failure.
- * */
+ */
 int nvmem_device_write(struct nvmem_device *nvmem,
 		       unsigned int offset,
 		       size_t bytes, void *buf)
-- 
2.18.0


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

* [PATCH v4 22/22] nvmem: use octal permissions instead of constants
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (20 preceding siblings ...)
  2018-09-14 14:40 ` [PATCH v4 21/22] nvmem: fix commenting style Bartosz Golaszewski
@ 2018-09-14 14:40 ` Bartosz Golaszewski
  2018-09-16 14:08 ` [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Srinivas Kandagatla
  22 siblings, 0 replies; 25+ messages in thread
From: Bartosz Golaszewski @ 2018-09-14 14:40 UTC (permalink / raw)
  To: Srinivas Kandagatla, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski

From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

Checkpatch emits a warning when using symbolic permissions. Use octal
permissions instead.

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

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index e44a1860a2b3..ad1227df1984 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -154,7 +154,7 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
 static struct bin_attribute bin_attr_rw_nvmem = {
 	.attr	= {
 		.name	= "nvmem",
-		.mode	= S_IWUSR | S_IRUGO,
+		.mode	= 0644,
 	},
 	.read	= bin_attr_nvmem_read,
 	.write	= bin_attr_nvmem_write,
@@ -178,7 +178,7 @@ static const struct attribute_group *nvmem_rw_dev_groups[] = {
 static struct bin_attribute bin_attr_ro_nvmem = {
 	.attr	= {
 		.name	= "nvmem",
-		.mode	= S_IRUGO,
+		.mode	= 0444,
 	},
 	.read	= bin_attr_nvmem_read,
 };
@@ -201,7 +201,7 @@ static const struct attribute_group *nvmem_ro_dev_groups[] = {
 static struct bin_attribute bin_attr_rw_root_nvmem = {
 	.attr	= {
 		.name	= "nvmem",
-		.mode	= S_IWUSR | S_IRUSR,
+		.mode	= 0600,
 	},
 	.read	= bin_attr_nvmem_read,
 	.write	= bin_attr_nvmem_write,
@@ -225,7 +225,7 @@ static const struct attribute_group *nvmem_rw_root_dev_groups[] = {
 static struct bin_attribute bin_attr_ro_root_nvmem = {
 	.attr	= {
 		.name	= "nvmem",
-		.mode	= S_IRUSR,
+		.mode	= 0400,
 	},
 	.read	= bin_attr_nvmem_read,
 };
-- 
2.18.0


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

* Re: [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users
  2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
                   ` (21 preceding siblings ...)
  2018-09-14 14:40 ` [PATCH v4 22/22] nvmem: use octal permissions instead of constants Bartosz Golaszewski
@ 2018-09-16 14:08 ` Srinivas Kandagatla
  22 siblings, 0 replies; 25+ messages in thread
From: Srinivas Kandagatla @ 2018-09-16 14:08 UTC (permalink / raw)
  To: Bartosz Golaszewski, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski



On 14/09/18 15:39, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> 
> NOTE: I decided to post v4 despite no new reviews from Srinivas as I'll
> be off next week. There were a couple issues reported by the kbuild bot
> and one bug I noticed after sending v3.
> 
> 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.
> 
> The patches are conceptually split into a couple groups.
> 
> First five patches fix issues with existing issues.
> 
> Patch 6 switches the nvmem providers to using kref which is necessary
> for removal of the return value from nvmem_unregister(). This is an
> approach similar to the one used in the clock framework where the
> provider is only removed after the last reference to it is dropped.
> 
> Patch 7 changes the errno returned from the driver after kzalloc()
> fails from -EINVAL to -ENOMEM which makes more sense.
> 
> Patches 8-10 convert last remaining users of nvmem_unregister() who
> still check its return value to using devm_nvmem_unregister() and
> patch 11 changes its return value from int to void.
> 
> Patches 12-15 introduce the most significant changes of this series:
> we remove the global cell list, add support for static cell definitions
> external to the provider structure, change the way DT lookup works and
> allow to associate resources and consumers using lookup tables. The way
> nvmem_cell_get() for non-DT users is changed but there are no current
> users and it's currently broken anyway (cell being removed after a call
> to nvmem_cell_put()).
> 
> Patch 16 updates the documentation.
> 
> Patch 17 adds support for notifiers to nvmem so that users can
> subscribe for events such as device or cell registration or removal.
> 
> Patches 18 & 19 add some minor improvements to the codebase.
> 
> Last three patches contain fixes to warnings emitted by checkpatch.
> It's a good moment to add them if we're already touching a big part
> of the subsystem's code.
> 
> Tested both DT and non-DT use cases.
> 
> [1] https://lkml.org/lkml/2018/8/10/149
> 
> v1 -> v2:
> - extended the lookup structure with a proper con_id independent from the
>    cell name defined in the cell definition table
> - added a patch that makes the naming convention for the cell name argument
>    in the nvmem_cell_get() family of functions consistent
> - there were two users of nvmem_unregister() that still checked the return
>    value, now switched to devm_nvmem_register()
> - fixed build failures reported by kbuild test robot
> 
> v2 -> v3:
> - dropped the patch removing unused APIs and introduced changes on top of
>    existing code instead
> - fixed nvmem provider reference decreasing in error paths
> - added checkpatch fixes
> - removed nvmem-machine.h and distributed new definitions among existing
>    consumer and provider headers
> - reordered patches thematically
> - added more patches fixing issues in existing codebase
> 
> v3 -> v4:
> - fixed the notifier chain call when removing nvmem devices: call the
>    notifier chain for NVMEM_REMOVE before releasing any resources
> - added patch 7/22 ("sunxi_sid: return -ENOMEM if kzalloc() fails")
> - fixed the return value in error path for patch 8/22 ("sunxi_sid: use
>    devm_nvmem_register())"
> - fixed the return value of devm_nvmem_unregister() in
>    patch 11/22 ("change the signature of nvmem_unregister()")
> 
> Bartosz Golaszewski (22):
>    nvmem: provide nvmem_dev_name()
>    nvmem: remove the name field from struct nvmem_device
>    nvmem: use list_for_each_entry_safe in nvmem_device_remove_all_cells()
>    nvmem: remove a stray newline
>    nvmem: check the return value of nvmem_add_cells()
>    nvmem: use kref
>    nvmem: sunxi_sid: return -ENOMEM if kzalloc() fails
>    nvmem: sunxi_sid: use devm_nvmem_register()
>    nvmem: lpc18xx_eeprom: use devm_nvmem_register()
>    nvmem: mxs-ocotp: use devm_nvmem_register()
>    nvmem: change the signature of nvmem_unregister()
>    nvmem: remove the global cell list
>    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: add a notifier chain
>    nvmem: use SPDX license identifiers
>    nvmem: make the naming of arguments in nvmem_cell_get() consistent
>    nvmem: use EOPNOTSUPP instead of ENOSYS
>    nvmem: fix commenting style
>    nvmem: use octal permissions instead of constants

Thanks for working on this!
Nice work!

Overall the patchset looks good!

I will send these to Greg KH along with other nvmem patches sometime 
this week!



-srini

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

* Re: [PATCH v4 15/22] nvmem: add support for cell lookups from machine code
  2018-09-14 14:40 ` [PATCH v4 15/22] nvmem: add support for cell lookups from machine code Bartosz Golaszewski
@ 2018-09-21  1:12   ` Srinivas Kandagatla
  0 siblings, 0 replies; 25+ messages in thread
From: Srinivas Kandagatla @ 2018-09-21  1:12 UTC (permalink / raw)
  To: Bartosz Golaszewski, 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,
	Chen-Yu Tsai
  Cc: linux-doc, linux-kernel, linux-arm-kernel, Bartosz Golaszewski



On 14/09/18 07:40, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> 
> Add a way for machine code users to associate devices with nvmem cells.
> 
> This restores the support for non-DT systems but following a different
> approach. Cells must now be associated with devices using provided
> routines and data structures before they can be retrieved using
> nvmem_cell_get().
> 
> It's still possible to define cells statically in nvmem_config but
> cells created this way still need to be associated with consumers using
> lookup entries.
> 
> Note that nvmem_find() must be moves higher in the source file as we
> want to call it from __nvmem_device_get() for devices that don't have
> a device node.
> 
> The signature of __nvmem_device_get() is also changed as it's no longer
> used to retrieve cells.
> 
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> ---
>   drivers/nvmem/core.c           | 129 ++++++++++++++++++++++++++-------
>   include/linux/nvmem-consumer.h |  28 +++++++
>   2 files changed, 131 insertions(+), 26 deletions(-)

This patch and other follow on patches for core.c does not apply on top 
of 
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git/log/?h=char-misc-next

Please rebase and send!

thanks,
srini

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

end of thread, other threads:[~2018-09-21  1:12 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-14 14:39 [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Bartosz Golaszewski
2018-09-14 14:39 ` [PATCH v4 01/22] nvmem: provide nvmem_dev_name() Bartosz Golaszewski
2018-09-14 14:39 ` [PATCH v4 02/22] nvmem: remove the name field from struct nvmem_device Bartosz Golaszewski
2018-09-14 14:39 ` [PATCH v4 03/22] nvmem: use list_for_each_entry_safe in nvmem_device_remove_all_cells() Bartosz Golaszewski
2018-09-14 14:39 ` [PATCH v4 04/22] nvmem: remove a stray newline Bartosz Golaszewski
2018-09-14 14:39 ` [PATCH v4 05/22] nvmem: check the return value of nvmem_add_cells() Bartosz Golaszewski
2018-09-14 14:39 ` [PATCH v4 06/22] nvmem: use kref Bartosz Golaszewski
2018-09-14 14:39 ` [PATCH v4 07/22] nvmem: sunxi_sid: return -ENOMEM if kzalloc() fails Bartosz Golaszewski
2018-09-14 14:39 ` [PATCH v4 08/22] nvmem: sunxi_sid: use devm_nvmem_register() Bartosz Golaszewski
2018-09-14 14:39 ` [PATCH v4 09/22] nvmem: lpc18xx_eeprom: " Bartosz Golaszewski
2018-09-14 14:39 ` [PATCH v4 10/22] nvmem: mxs-ocotp: " Bartosz Golaszewski
2018-09-14 14:40 ` [PATCH v4 11/22] nvmem: change the signature of nvmem_unregister() Bartosz Golaszewski
2018-09-14 14:40 ` [PATCH v4 12/22] nvmem: remove the global cell list Bartosz Golaszewski
2018-09-14 14:40 ` [PATCH v4 13/22] nvmem: add support for cell info Bartosz Golaszewski
2018-09-14 14:40 ` [PATCH v4 14/22] nvmem: resolve cells from DT at registration time Bartosz Golaszewski
2018-09-14 14:40 ` [PATCH v4 15/22] nvmem: add support for cell lookups from machine code Bartosz Golaszewski
2018-09-21  1:12   ` Srinivas Kandagatla
2018-09-14 14:40 ` [PATCH v4 16/22] Documentation: nvmem: document cell tables and lookup entries Bartosz Golaszewski
2018-09-14 14:40 ` [PATCH v4 17/22] nvmem: add a notifier chain Bartosz Golaszewski
2018-09-14 14:40 ` [PATCH v4 18/22] nvmem: use SPDX license identifiers Bartosz Golaszewski
2018-09-14 14:40 ` [PATCH v4 19/22] nvmem: make the naming of arguments in nvmem_cell_get() consistent Bartosz Golaszewski
2018-09-14 14:40 ` [PATCH v4 20/22] nvmem: use EOPNOTSUPP instead of ENOSYS Bartosz Golaszewski
2018-09-14 14:40 ` [PATCH v4 21/22] nvmem: fix commenting style Bartosz Golaszewski
2018-09-14 14:40 ` [PATCH v4 22/22] nvmem: use octal permissions instead of constants Bartosz Golaszewski
2018-09-16 14:08 ` [PATCH v4 00/22] nvmem: rework of the subsystem for non-DT users Srinivas Kandagatla

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).