linux-acpi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] nvmem: Change to unified property interface
@ 2021-03-29 22:38 Kevin Paul Herbert
  2021-03-30  3:21 ` kernel test robot
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Kevin Paul Herbert @ 2021-03-29 22:38 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Rafael J . Wysocki, Len Brown, linux-acpi, Rob Herring,
	Frank Rowand, devicetree, Tom Grennan, linux-kernel,
	Kevin Paul Herbert

Change from using device tree (Open Firmware) APIs to the unified
'fwnode' interface.

Change of_nvmem_cell_get() to fwnode_nvmem_cell_get(), and add a
wrapper for of_nvmem_cell_get().

Change of_nvmem_device_get() to fwnode_nvmem_device_get(). There
are no known accessors to the OF interface, so no need for a wrapper.

Signed-off-by: Kevin Paul Herbert <kph@platinasystems.com>
---
 drivers/nvmem/core.c           | 176 ++++++++++++++++++++-------------
 include/linux/nvmem-consumer.h |  27 ++---
 2 files changed, 123 insertions(+), 80 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index a5ab1e0c74cf..2e49304cd9a8 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -6,6 +6,7 @@
  * Copyright (C) 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
  */
 
+#include <linux/acpi.h>
 #include <linux/device.h>
 #include <linux/export.h>
 #include <linux/fs.h>
@@ -17,6 +18,7 @@
 #include <linux/nvmem-provider.h>
 #include <linux/gpio/consumer.h>
 #include <linux/of.h>
+#include <linux/property.h>
 #include <linux/slab.h>
 
 struct nvmem_device {
@@ -52,7 +54,7 @@ struct nvmem_cell {
 	int			bytes;
 	int			bit_offset;
 	int			nbits;
-	struct device_node	*np;
+	struct fwnode_handle	*fwnode;
 	struct nvmem_device	*nvmem;
 	struct list_head	node;
 };
@@ -424,7 +426,7 @@ static void nvmem_cell_drop(struct nvmem_cell *cell)
 	mutex_lock(&nvmem_mutex);
 	list_del(&cell->node);
 	mutex_unlock(&nvmem_mutex);
-	of_node_put(cell->np);
+	fwnode_handle_put(cell->fwnode);
 	kfree_const(cell->name);
 	kfree(cell);
 }
@@ -670,39 +672,40 @@ static int nvmem_validate_keepouts(struct nvmem_device *nvmem)
 	return 0;
 }
 
-static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
+static int nvmem_add_cells_from_fw(struct nvmem_device *nvmem)
 {
-	struct device_node *parent, *child;
+	struct fwnode_handle *parent, *child;
 	struct device *dev = &nvmem->dev;
 	struct nvmem_cell *cell;
-	const __be32 *addr;
-	int len;
+	int rval;
+	u32 vals[2];
 
-	parent = dev->of_node;
+	parent = dev_fwnode(dev);
 
-	for_each_child_of_node(parent, child) {
-		addr = of_get_property(child, "reg", &len);
-		if (!addr)
+	fwnode_for_each_child_node(parent, child) {
+		rval = fwnode_property_read_u32_array(child, "reg", NULL, 2);
+		if (rval < 0)
 			continue;
-		if (len < 2 * sizeof(u32)) {
-			dev_err(dev, "nvmem: invalid reg on %pOF\n", child);
+		if (rval < 2) {
+			dev_err(dev, "nvmem: invalid reg %d on %pfw\n",
+				rval, child);
 			return -EINVAL;
 		}
-
+		rval = fwnode_property_read_u32_array(child, "reg", vals, 2);
 		cell = kzalloc(sizeof(*cell), GFP_KERNEL);
 		if (!cell)
 			return -ENOMEM;
 
 		cell->nvmem = nvmem;
-		cell->np = of_node_get(child);
-		cell->offset = be32_to_cpup(addr++);
-		cell->bytes = be32_to_cpup(addr);
-		cell->name = kasprintf(GFP_KERNEL, "%pOFn", child);
-
-		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);
+		cell->fwnode = child;
+		cell->offset = vals[0];
+		cell->bytes = vals[1];
+		cell->name = kasprintf(GFP_KERNEL, "%pfwn", child);
+
+		rval = fwnode_property_read_u32_array(child, "bits", vals, 2);
+		if (rval >= 0) {
+			cell->bit_offset = vals[0];
+			cell->nbits = vals[1];
 		}
 
 		if (cell->nbits)
@@ -715,7 +718,7 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
 				cell->name, nvmem->stride);
 			/* Cells already added will be freed later. */
 			kfree_const(cell->name);
-			of_node_put(cell->np);
+			fwnode_handle_put(cell->fwnode);
 			kfree(cell);
 			return -EINVAL;
 		}
@@ -789,8 +792,10 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	nvmem->reg_write = config->reg_write;
 	nvmem->keepout = config->keepout;
 	nvmem->nkeepout = config->nkeepout;
-	if (!config->no_of_node)
+	if (!config->no_of_node) {
 		nvmem->dev.of_node = config->dev->of_node;
+		nvmem->dev.fwnode = config->dev->fwnode;
+	}
 
 	switch (config->id) {
 	case NVMEM_DEVID_NONE:
@@ -841,7 +846,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	if (rval)
 		goto err_remove_cells;
 
-	rval = nvmem_add_cells_from_of(nvmem);
+	rval = nvmem_add_cells_from_fw(nvmem);
 	if (rval)
 		goto err_remove_cells;
 
@@ -984,36 +989,46 @@ static void __nvmem_device_put(struct nvmem_device *nvmem)
 	kref_put(&nvmem->refcnt, nvmem_device_release);
 }
 
-#if IS_ENABLED(CONFIG_OF)
 /**
- * of_nvmem_device_get() - Get nvmem device from a given id
+ * fwnode_nvmem_device_get() - Get nvmem device from a given id
  *
- * @np: Device tree node that uses the nvmem device.
+ * @fwnode: Firmware node that uses the nvmem device.
  * @id: nvmem name from nvmem-names property.
  *
  * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device
  * on success.
  */
-struct nvmem_device *of_nvmem_device_get(struct device_node *np, const char *id)
+struct nvmem_device *fwnode_nvmem_device_get(struct fwnode_handle *fwnode, const char *id)
 {
-
-	struct device_node *nvmem_np;
+	struct fwnode_handle *nvmem_fwnode;
 	struct nvmem_device *nvmem;
 	int index = 0;
 
 	if (id)
-		index = of_property_match_string(np, "nvmem-names", id);
-
-	nvmem_np = of_parse_phandle(np, "nvmem", index);
-	if (!nvmem_np)
-		return ERR_PTR(-ENOENT);
+		index = fwnode_property_match_string(fwnode, "nvmem-names", id);
+
+	if (is_of_node(fwnode)) {
+		struct device_node *nvmem_np = of_parse_phandle(to_of_node(fwnode),
+								"nvmem", index);
+		if (!nvmem_np)
+			return ERR_PTR(-ENOENT);
+		nvmem_fwnode = &nvmem_np->fwnode;
+	} else if (is_acpi_device_node(fwnode)) {
+		struct fwnode_reference_args args;
+		int rval = acpi_node_get_property_reference(fwnode,
+							    "nvmem", index, &args);
+		if (rval)
+			return ERR_PTR(rval);
+		nvmem_fwnode = args.fwnode;
+	} else {
+		return ERR_PTR(-ENXIO);
+	}
 
-	nvmem = __nvmem_device_get(nvmem_np, device_match_of_node);
-	of_node_put(nvmem_np);
+	nvmem = __nvmem_device_get(nvmem_fwnode, device_match_fwnode);
+	fwnode_handle_put(nvmem_fwnode);
 	return nvmem;
 }
-EXPORT_SYMBOL_GPL(of_nvmem_device_get);
-#endif
+EXPORT_SYMBOL_GPL(fwnode_nvmem_device_get);
 
 /**
  * nvmem_device_get() - Get nvmem device from a given id
@@ -1026,16 +1041,15 @@ EXPORT_SYMBOL_GPL(of_nvmem_device_get);
  */
 struct nvmem_device *nvmem_device_get(struct device *dev, const char *dev_name)
 {
-	if (dev->of_node) { /* try dt first */
-		struct nvmem_device *nvmem;
+	struct fwnode_handle *fwnode = dev_fwnode(dev);
 
-		nvmem = of_nvmem_device_get(dev->of_node, dev_name);
+	if (fwnode) { /* try firmware tree first */
+		struct nvmem_device *nvmem;
 
+		nvmem = fwnode_nvmem_device_get(fwnode, dev_name);
 		if (!IS_ERR(nvmem) || PTR_ERR(nvmem) == -EPROBE_DEFER)
 			return nvmem;
-
 	}
-
 	return __nvmem_device_get((void *)dev_name, device_match_name);
 }
 EXPORT_SYMBOL_GPL(nvmem_device_get);
@@ -1171,15 +1185,14 @@ nvmem_cell_get_from_lookup(struct device *dev, const char *con_id)
 	return cell;
 }
 
-#if IS_ENABLED(CONFIG_OF)
 static struct nvmem_cell *
-nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np)
+nvmem_find_cell_by_fwnode(struct nvmem_device *nvmem, struct fwnode_handle *fwnode)
 {
 	struct nvmem_cell *iter, *cell = NULL;
 
 	mutex_lock(&nvmem_mutex);
 	list_for_each_entry(iter, &nvmem->cells, node) {
-		if (np == iter->np) {
+		if (fwnode == iter->fwnode) {
 			cell = iter;
 			break;
 		}
@@ -1190,42 +1203,67 @@ nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np)
 }
 
 /**
- * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
+ * fwnode_nvmem_cell_get() - Get a nvmem cell from given firmwar node and cell id
  *
- * @np: Device tree node that uses the nvmem cell.
+ * @fwnode: Firmware node that uses the nvmem cell.
  * @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).
+ *	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 *id)
+struct nvmem_cell *fwnode_nvmem_cell_get(struct fwnode_handle *fwnode,
+					 const char *id)
 {
-	struct device_node *cell_np, *nvmem_np;
+	struct fwnode_handle *nvmem_fwnode, *cell_fwnode;
 	struct nvmem_device *nvmem;
 	struct nvmem_cell *cell;
 	int index = 0;
 
 	/* if cell name exists, find index to the name */
-	if (id)
-		index = of_property_match_string(np, "nvmem-cell-names", id);
+	if (id) {
+		index = fwnode_property_match_string(fwnode, "nvmem-cell-names", id);
+		if (index < 0)
+			return ERR_PTR(index);
+	}
 
-	cell_np = of_parse_phandle(np, "nvmem-cells", index);
-	if (!cell_np)
-		return ERR_PTR(-ENOENT);
+	if (is_of_node(fwnode)) {
+		struct device_node *np = to_of_node(fwnode);
+		struct device_node *cell_np = of_parse_phandle(np, "nvmem-cells", index);
+
+		if (!cell_np)
+			return ERR_PTR(-EINVAL);
+		cell_fwnode = &cell_np->fwnode;
+	} else if (is_acpi_device_node(fwnode)) {
+		struct fwnode_reference_args args;
+		struct fwnode_handle *dev_fwnode;
+		int rval;
 
-	nvmem_np = of_get_next_parent(cell_np);
-	if (!nvmem_np)
+		rval = acpi_node_get_property_reference(fwnode,
+							"nvmem-cells", index, &args);
+		if (rval)
+			return ERR_PTR(rval);
+		dev_fwnode = args.fwnode;
+		cell_fwnode = fwnode_get_named_child_node(dev_fwnode,
+							  id ? id : "nvmem");
+		if (!cell_fwnode)
+			return ERR_PTR(-EINVAL);
+	} else {
+		return ERR_PTR(-ENXIO);
+	}
+
+	nvmem_fwnode = fwnode_get_next_parent(cell_fwnode);
+	if (!nvmem_fwnode)
 		return ERR_PTR(-EINVAL);
 
-	nvmem = __nvmem_device_get(nvmem_np, device_match_of_node);
-	of_node_put(nvmem_np);
+	nvmem = __nvmem_device_get(nvmem_fwnode, device_match_fwnode);
+	fwnode_handle_put(nvmem_fwnode);
 	if (IS_ERR(nvmem))
 		return ERR_CAST(nvmem);
 
-	cell = nvmem_find_cell_by_node(nvmem, cell_np);
+	cell = nvmem_find_cell_by_fwnode(nvmem, cell_fwnode);
 	if (!cell) {
 		__nvmem_device_put(nvmem);
 		return ERR_PTR(-ENOENT);
@@ -1233,8 +1271,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id)
 
 	return cell;
 }
-EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
-#endif
+EXPORT_SYMBOL_GPL(fwnode_nvmem_cell_get);
 
 /**
  * nvmem_cell_get() - Get nvmem cell of device form a given cell name
@@ -1251,14 +1288,15 @@ EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
 struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *id)
 {
 	struct nvmem_cell *cell;
+	struct fwnode_handle *fwnode = dev_fwnode(dev);
 
-	if (dev->of_node) { /* try dt first */
-		cell = of_nvmem_cell_get(dev->of_node, id);
+	if (fwnode) { /* try firmware tree first */
+		cell = fwnode_nvmem_cell_get(fwnode, id);
 		if (!IS_ERR(cell) || PTR_ERR(cell) == -EPROBE_DEFER)
 			return cell;
 	}
 
-	/* NULL cell id only allowed for device tree; invalid otherwise */
+	/* NULL cell_id only allowed for firmware tree; invalid otherwise */
 	if (!id)
 		return ERR_PTR(-EINVAL);
 
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 052293f4cbdb..e52c587d0a23 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -12,12 +12,14 @@
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/notifier.h>
+#include <linux/of.h>
 
 struct device;
 struct device_node;
 /* consumer cookie */
 struct nvmem_cell;
 struct nvmem_device;
+struct fwnode_handle;
 
 struct nvmem_cell_info {
 	const char		*name;
@@ -94,6 +96,10 @@ int nvmem_unregister_notifier(struct notifier_block *nb);
 struct nvmem_device *nvmem_device_find(void *data,
 			int (*match)(struct device *dev, const void *data));
 
+struct nvmem_cell *fwnode_nvmem_cell_get(struct fwnode_handle *np,
+					 const char *name);
+struct nvmem_device *fwnode_nvmem_device_get(struct fwnode_handle *np,
+					     const char *name);
 #else
 
 static inline struct nvmem_cell *nvmem_cell_get(struct device *dev,
@@ -221,25 +227,24 @@ static inline struct nvmem_device *nvmem_device_find(void *data,
 	return NULL;
 }
 
-#endif /* CONFIG_NVMEM */
+static inline struct nvmem_cell *fwnode_nvmem_cell_get(struct fwnode_handle *np,
+						       const char *name)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
 
-#if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
-struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
-				     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 *id)
+static inline struct nvmem_device *fwnode_nvmem_device_get(struct fwnode_handle *np,
+							   const char *name)
 {
 	return ERR_PTR(-EOPNOTSUPP);
 }
 
+#endif /* CONFIG_NVMEM */
+
 static inline struct nvmem_device *of_nvmem_device_get(struct device_node *np,
 						       const char *name)
 {
-	return ERR_PTR(-EOPNOTSUPP);
+	return np ? fwnode_nvmem_device_get(&np->fwnode, name) : NULL;
 }
-#endif /* CONFIG_NVMEM && CONFIG_OF */
 
 #endif  /* ifndef _LINUX_NVMEM_CONSUMER_H */
-- 
2.25.1


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

* Re: [PATCH] nvmem: Change to unified property interface
  2021-03-29 22:38 [PATCH] nvmem: Change to unified property interface Kevin Paul Herbert
@ 2021-03-30  3:21 ` kernel test robot
  2021-03-30  4:26 ` [PATCH v2] " Kevin Paul Herbert
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2021-03-30  3:21 UTC (permalink / raw)
  To: Kevin Paul Herbert, Srinivas Kandagatla
  Cc: kbuild-all, Rafael J . Wysocki, Len Brown, linux-acpi,
	Rob Herring, Frank Rowand, devicetree, Tom Grennan, linux-kernel,
	Kevin Paul Herbert

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

Hi Kevin,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.12-rc5 next-20210329]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Kevin-Paul-Herbert/nvmem-Change-to-unified-property-interface/20210330-064121
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 1e43c377a79f9189fea8f2711b399d4e8b4e609b
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/edbc7632702cf638265a6d7180bd8c951cda6ad9
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Kevin-Paul-Herbert/nvmem-Change-to-unified-property-interface/20210330-064121
        git checkout edbc7632702cf638265a6d7180bd8c951cda6ad9
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/thermal/sprd_thermal.c: In function 'sprd_thm_cal_read':
   drivers/thermal/sprd_thermal.c:128:9: error: implicit declaration of function 'of_nvmem_cell_get'; did you mean 'nvmem_cell_get'? [-Werror=implicit-function-declaration]
     128 |  cell = of_nvmem_cell_get(np, cell_id);
         |         ^~~~~~~~~~~~~~~~~
         |         nvmem_cell_get
>> drivers/thermal/sprd_thermal.c:128:7: warning: assignment to 'struct nvmem_cell *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     128 |  cell = of_nvmem_cell_get(np, cell_id);
         |       ^
   cc1: some warnings being treated as errors


vim +128 drivers/thermal/sprd_thermal.c

554fdbaf19b188 Freeman Liu 2020-02-18  120  
554fdbaf19b188 Freeman Liu 2020-02-18  121  static int sprd_thm_cal_read(struct device_node *np, const char *cell_id,
554fdbaf19b188 Freeman Liu 2020-02-18  122  			     u32 *val)
554fdbaf19b188 Freeman Liu 2020-02-18  123  {
554fdbaf19b188 Freeman Liu 2020-02-18  124  	struct nvmem_cell *cell;
554fdbaf19b188 Freeman Liu 2020-02-18  125  	void *buf;
554fdbaf19b188 Freeman Liu 2020-02-18  126  	size_t len;
554fdbaf19b188 Freeman Liu 2020-02-18  127  
554fdbaf19b188 Freeman Liu 2020-02-18 @128  	cell = of_nvmem_cell_get(np, cell_id);
554fdbaf19b188 Freeman Liu 2020-02-18  129  	if (IS_ERR(cell))
554fdbaf19b188 Freeman Liu 2020-02-18  130  		return PTR_ERR(cell);
554fdbaf19b188 Freeman Liu 2020-02-18  131  
554fdbaf19b188 Freeman Liu 2020-02-18  132  	buf = nvmem_cell_read(cell, &len);
554fdbaf19b188 Freeman Liu 2020-02-18  133  	nvmem_cell_put(cell);
554fdbaf19b188 Freeman Liu 2020-02-18  134  	if (IS_ERR(buf))
554fdbaf19b188 Freeman Liu 2020-02-18  135  		return PTR_ERR(buf);
554fdbaf19b188 Freeman Liu 2020-02-18  136  
554fdbaf19b188 Freeman Liu 2020-02-18  137  	if (len > sizeof(u32)) {
554fdbaf19b188 Freeman Liu 2020-02-18  138  		kfree(buf);
554fdbaf19b188 Freeman Liu 2020-02-18  139  		return -EINVAL;
554fdbaf19b188 Freeman Liu 2020-02-18  140  	}
554fdbaf19b188 Freeman Liu 2020-02-18  141  
554fdbaf19b188 Freeman Liu 2020-02-18  142  	memcpy(val, buf, len);
554fdbaf19b188 Freeman Liu 2020-02-18  143  
554fdbaf19b188 Freeman Liu 2020-02-18  144  	kfree(buf);
554fdbaf19b188 Freeman Liu 2020-02-18  145  	return 0;
554fdbaf19b188 Freeman Liu 2020-02-18  146  }
554fdbaf19b188 Freeman Liu 2020-02-18  147  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

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

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

* [PATCH v2] nvmem: Change to unified property interface
  2021-03-29 22:38 [PATCH] nvmem: Change to unified property interface Kevin Paul Herbert
  2021-03-30  3:21 ` kernel test robot
@ 2021-03-30  4:26 ` Kevin Paul Herbert
  2021-03-30  4:28 ` Kevin Paul Herbert
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Kevin Paul Herbert @ 2021-03-30  4:26 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Rafael J . Wysocki, Len Brown, linux-acpi, Rob Herring,
	Frank Rowand, devicetree, Tom Grennan, linux-kernel


THis first version of this patch erroneously had an unnecessary wrapper
for of_nvmem_device_get() even though the commentary properly stated
that the only wrapper needed was of_nvmem_cell_get(). Fix the code to
match the intent.


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

* [PATCH v2] nvmem: Change to unified property interface
  2021-03-29 22:38 [PATCH] nvmem: Change to unified property interface Kevin Paul Herbert
  2021-03-30  3:21 ` kernel test robot
  2021-03-30  4:26 ` [PATCH v2] " Kevin Paul Herbert
@ 2021-03-30  4:28 ` Kevin Paul Herbert
  2021-03-30  4:34 ` Kevin Paul Herbert
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Kevin Paul Herbert @ 2021-03-30  4:28 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Rafael J . Wysocki, Len Brown, linux-acpi, Rob Herring,
	Frank Rowand, devicetree, Tom Grennan, linux-kernel


The original version of this patch correctly stated that the only
wrapper needed was for of_nvmem_cell_get(), but included only a wrapper
for of_nvmem_device_get(). Replace with the proper wrapper.


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

* [PATCH v2] nvmem: Change to unified property interface
  2021-03-29 22:38 [PATCH] nvmem: Change to unified property interface Kevin Paul Herbert
                   ` (2 preceding siblings ...)
  2021-03-30  4:28 ` Kevin Paul Herbert
@ 2021-03-30  4:34 ` Kevin Paul Herbert
  2021-03-30  4:57 ` [PATCH] " kernel test robot
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Kevin Paul Herbert @ 2021-03-30  4:34 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Rafael J . Wysocki, Len Brown, linux-acpi, Rob Herring,
	Frank Rowand, devicetree, Tom Grennan, linux-kernel,
	Kevin Paul Herbert, kernel test robot

Change from using device tree (Open Firmware) APIs to the unified
'fwnode' interface.

Change of_nvmem_cell_get() to fwnode_nvmem_cell_get(), and add a
wrapper for of_nvmem_cell_get().

Change of_nvmem_device_get() to fwnode_nvmem_device_get(). There
are no known accessors to the OF interface, so no need for a wrapper.

The first version of this patch incorrectly had a wrapper for
of_nvmem_device_get(), even though the comments about the patch
not needing this were correct.

Reported-by: kernel test robot <lkp@intel.com>

Signed-off-by: Kevin Paul Herbert <kph@platinasystems.com>
---
 drivers/nvmem/core.c           | 176 ++++++++++++++++++++-------------
 include/linux/nvmem-consumer.h |  31 +++---
 2 files changed, 125 insertions(+), 82 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index a5ab1e0c74cf..2e49304cd9a8 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -6,6 +6,7 @@
  * Copyright (C) 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
  */
 
+#include <linux/acpi.h>
 #include <linux/device.h>
 #include <linux/export.h>
 #include <linux/fs.h>
@@ -17,6 +18,7 @@
 #include <linux/nvmem-provider.h>
 #include <linux/gpio/consumer.h>
 #include <linux/of.h>
+#include <linux/property.h>
 #include <linux/slab.h>
 
 struct nvmem_device {
@@ -52,7 +54,7 @@ struct nvmem_cell {
 	int			bytes;
 	int			bit_offset;
 	int			nbits;
-	struct device_node	*np;
+	struct fwnode_handle	*fwnode;
 	struct nvmem_device	*nvmem;
 	struct list_head	node;
 };
@@ -424,7 +426,7 @@ static void nvmem_cell_drop(struct nvmem_cell *cell)
 	mutex_lock(&nvmem_mutex);
 	list_del(&cell->node);
 	mutex_unlock(&nvmem_mutex);
-	of_node_put(cell->np);
+	fwnode_handle_put(cell->fwnode);
 	kfree_const(cell->name);
 	kfree(cell);
 }
@@ -670,39 +672,40 @@ static int nvmem_validate_keepouts(struct nvmem_device *nvmem)
 	return 0;
 }
 
-static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
+static int nvmem_add_cells_from_fw(struct nvmem_device *nvmem)
 {
-	struct device_node *parent, *child;
+	struct fwnode_handle *parent, *child;
 	struct device *dev = &nvmem->dev;
 	struct nvmem_cell *cell;
-	const __be32 *addr;
-	int len;
+	int rval;
+	u32 vals[2];
 
-	parent = dev->of_node;
+	parent = dev_fwnode(dev);
 
-	for_each_child_of_node(parent, child) {
-		addr = of_get_property(child, "reg", &len);
-		if (!addr)
+	fwnode_for_each_child_node(parent, child) {
+		rval = fwnode_property_read_u32_array(child, "reg", NULL, 2);
+		if (rval < 0)
 			continue;
-		if (len < 2 * sizeof(u32)) {
-			dev_err(dev, "nvmem: invalid reg on %pOF\n", child);
+		if (rval < 2) {
+			dev_err(dev, "nvmem: invalid reg %d on %pfw\n",
+				rval, child);
 			return -EINVAL;
 		}
-
+		rval = fwnode_property_read_u32_array(child, "reg", vals, 2);
 		cell = kzalloc(sizeof(*cell), GFP_KERNEL);
 		if (!cell)
 			return -ENOMEM;
 
 		cell->nvmem = nvmem;
-		cell->np = of_node_get(child);
-		cell->offset = be32_to_cpup(addr++);
-		cell->bytes = be32_to_cpup(addr);
-		cell->name = kasprintf(GFP_KERNEL, "%pOFn", child);
-
-		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);
+		cell->fwnode = child;
+		cell->offset = vals[0];
+		cell->bytes = vals[1];
+		cell->name = kasprintf(GFP_KERNEL, "%pfwn", child);
+
+		rval = fwnode_property_read_u32_array(child, "bits", vals, 2);
+		if (rval >= 0) {
+			cell->bit_offset = vals[0];
+			cell->nbits = vals[1];
 		}
 
 		if (cell->nbits)
@@ -715,7 +718,7 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
 				cell->name, nvmem->stride);
 			/* Cells already added will be freed later. */
 			kfree_const(cell->name);
-			of_node_put(cell->np);
+			fwnode_handle_put(cell->fwnode);
 			kfree(cell);
 			return -EINVAL;
 		}
@@ -789,8 +792,10 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	nvmem->reg_write = config->reg_write;
 	nvmem->keepout = config->keepout;
 	nvmem->nkeepout = config->nkeepout;
-	if (!config->no_of_node)
+	if (!config->no_of_node) {
 		nvmem->dev.of_node = config->dev->of_node;
+		nvmem->dev.fwnode = config->dev->fwnode;
+	}
 
 	switch (config->id) {
 	case NVMEM_DEVID_NONE:
@@ -841,7 +846,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	if (rval)
 		goto err_remove_cells;
 
-	rval = nvmem_add_cells_from_of(nvmem);
+	rval = nvmem_add_cells_from_fw(nvmem);
 	if (rval)
 		goto err_remove_cells;
 
@@ -984,36 +989,46 @@ static void __nvmem_device_put(struct nvmem_device *nvmem)
 	kref_put(&nvmem->refcnt, nvmem_device_release);
 }
 
-#if IS_ENABLED(CONFIG_OF)
 /**
- * of_nvmem_device_get() - Get nvmem device from a given id
+ * fwnode_nvmem_device_get() - Get nvmem device from a given id
  *
- * @np: Device tree node that uses the nvmem device.
+ * @fwnode: Firmware node that uses the nvmem device.
  * @id: nvmem name from nvmem-names property.
  *
  * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device
  * on success.
  */
-struct nvmem_device *of_nvmem_device_get(struct device_node *np, const char *id)
+struct nvmem_device *fwnode_nvmem_device_get(struct fwnode_handle *fwnode, const char *id)
 {
-
-	struct device_node *nvmem_np;
+	struct fwnode_handle *nvmem_fwnode;
 	struct nvmem_device *nvmem;
 	int index = 0;
 
 	if (id)
-		index = of_property_match_string(np, "nvmem-names", id);
-
-	nvmem_np = of_parse_phandle(np, "nvmem", index);
-	if (!nvmem_np)
-		return ERR_PTR(-ENOENT);
+		index = fwnode_property_match_string(fwnode, "nvmem-names", id);
+
+	if (is_of_node(fwnode)) {
+		struct device_node *nvmem_np = of_parse_phandle(to_of_node(fwnode),
+								"nvmem", index);
+		if (!nvmem_np)
+			return ERR_PTR(-ENOENT);
+		nvmem_fwnode = &nvmem_np->fwnode;
+	} else if (is_acpi_device_node(fwnode)) {
+		struct fwnode_reference_args args;
+		int rval = acpi_node_get_property_reference(fwnode,
+							    "nvmem", index, &args);
+		if (rval)
+			return ERR_PTR(rval);
+		nvmem_fwnode = args.fwnode;
+	} else {
+		return ERR_PTR(-ENXIO);
+	}
 
-	nvmem = __nvmem_device_get(nvmem_np, device_match_of_node);
-	of_node_put(nvmem_np);
+	nvmem = __nvmem_device_get(nvmem_fwnode, device_match_fwnode);
+	fwnode_handle_put(nvmem_fwnode);
 	return nvmem;
 }
-EXPORT_SYMBOL_GPL(of_nvmem_device_get);
-#endif
+EXPORT_SYMBOL_GPL(fwnode_nvmem_device_get);
 
 /**
  * nvmem_device_get() - Get nvmem device from a given id
@@ -1026,16 +1041,15 @@ EXPORT_SYMBOL_GPL(of_nvmem_device_get);
  */
 struct nvmem_device *nvmem_device_get(struct device *dev, const char *dev_name)
 {
-	if (dev->of_node) { /* try dt first */
-		struct nvmem_device *nvmem;
+	struct fwnode_handle *fwnode = dev_fwnode(dev);
 
-		nvmem = of_nvmem_device_get(dev->of_node, dev_name);
+	if (fwnode) { /* try firmware tree first */
+		struct nvmem_device *nvmem;
 
+		nvmem = fwnode_nvmem_device_get(fwnode, dev_name);
 		if (!IS_ERR(nvmem) || PTR_ERR(nvmem) == -EPROBE_DEFER)
 			return nvmem;
-
 	}
-
 	return __nvmem_device_get((void *)dev_name, device_match_name);
 }
 EXPORT_SYMBOL_GPL(nvmem_device_get);
@@ -1171,15 +1185,14 @@ nvmem_cell_get_from_lookup(struct device *dev, const char *con_id)
 	return cell;
 }
 
-#if IS_ENABLED(CONFIG_OF)
 static struct nvmem_cell *
-nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np)
+nvmem_find_cell_by_fwnode(struct nvmem_device *nvmem, struct fwnode_handle *fwnode)
 {
 	struct nvmem_cell *iter, *cell = NULL;
 
 	mutex_lock(&nvmem_mutex);
 	list_for_each_entry(iter, &nvmem->cells, node) {
-		if (np == iter->np) {
+		if (fwnode == iter->fwnode) {
 			cell = iter;
 			break;
 		}
@@ -1190,42 +1203,67 @@ nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np)
 }
 
 /**
- * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
+ * fwnode_nvmem_cell_get() - Get a nvmem cell from given firmwar node and cell id
  *
- * @np: Device tree node that uses the nvmem cell.
+ * @fwnode: Firmware node that uses the nvmem cell.
  * @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).
+ *	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 *id)
+struct nvmem_cell *fwnode_nvmem_cell_get(struct fwnode_handle *fwnode,
+					 const char *id)
 {
-	struct device_node *cell_np, *nvmem_np;
+	struct fwnode_handle *nvmem_fwnode, *cell_fwnode;
 	struct nvmem_device *nvmem;
 	struct nvmem_cell *cell;
 	int index = 0;
 
 	/* if cell name exists, find index to the name */
-	if (id)
-		index = of_property_match_string(np, "nvmem-cell-names", id);
+	if (id) {
+		index = fwnode_property_match_string(fwnode, "nvmem-cell-names", id);
+		if (index < 0)
+			return ERR_PTR(index);
+	}
 
-	cell_np = of_parse_phandle(np, "nvmem-cells", index);
-	if (!cell_np)
-		return ERR_PTR(-ENOENT);
+	if (is_of_node(fwnode)) {
+		struct device_node *np = to_of_node(fwnode);
+		struct device_node *cell_np = of_parse_phandle(np, "nvmem-cells", index);
+
+		if (!cell_np)
+			return ERR_PTR(-EINVAL);
+		cell_fwnode = &cell_np->fwnode;
+	} else if (is_acpi_device_node(fwnode)) {
+		struct fwnode_reference_args args;
+		struct fwnode_handle *dev_fwnode;
+		int rval;
 
-	nvmem_np = of_get_next_parent(cell_np);
-	if (!nvmem_np)
+		rval = acpi_node_get_property_reference(fwnode,
+							"nvmem-cells", index, &args);
+		if (rval)
+			return ERR_PTR(rval);
+		dev_fwnode = args.fwnode;
+		cell_fwnode = fwnode_get_named_child_node(dev_fwnode,
+							  id ? id : "nvmem");
+		if (!cell_fwnode)
+			return ERR_PTR(-EINVAL);
+	} else {
+		return ERR_PTR(-ENXIO);
+	}
+
+	nvmem_fwnode = fwnode_get_next_parent(cell_fwnode);
+	if (!nvmem_fwnode)
 		return ERR_PTR(-EINVAL);
 
-	nvmem = __nvmem_device_get(nvmem_np, device_match_of_node);
-	of_node_put(nvmem_np);
+	nvmem = __nvmem_device_get(nvmem_fwnode, device_match_fwnode);
+	fwnode_handle_put(nvmem_fwnode);
 	if (IS_ERR(nvmem))
 		return ERR_CAST(nvmem);
 
-	cell = nvmem_find_cell_by_node(nvmem, cell_np);
+	cell = nvmem_find_cell_by_fwnode(nvmem, cell_fwnode);
 	if (!cell) {
 		__nvmem_device_put(nvmem);
 		return ERR_PTR(-ENOENT);
@@ -1233,8 +1271,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id)
 
 	return cell;
 }
-EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
-#endif
+EXPORT_SYMBOL_GPL(fwnode_nvmem_cell_get);
 
 /**
  * nvmem_cell_get() - Get nvmem cell of device form a given cell name
@@ -1251,14 +1288,15 @@ EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
 struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *id)
 {
 	struct nvmem_cell *cell;
+	struct fwnode_handle *fwnode = dev_fwnode(dev);
 
-	if (dev->of_node) { /* try dt first */
-		cell = of_nvmem_cell_get(dev->of_node, id);
+	if (fwnode) { /* try firmware tree first */
+		cell = fwnode_nvmem_cell_get(fwnode, id);
 		if (!IS_ERR(cell) || PTR_ERR(cell) == -EPROBE_DEFER)
 			return cell;
 	}
 
-	/* NULL cell id only allowed for device tree; invalid otherwise */
+	/* NULL cell_id only allowed for firmware tree; invalid otherwise */
 	if (!id)
 		return ERR_PTR(-EINVAL);
 
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 052293f4cbdb..be407c2941fc 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -12,12 +12,14 @@
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/notifier.h>
+#include <linux/of.h>
 
 struct device;
 struct device_node;
 /* consumer cookie */
 struct nvmem_cell;
 struct nvmem_device;
+struct fwnode_handle;
 
 struct nvmem_cell_info {
 	const char		*name;
@@ -94,6 +96,10 @@ int nvmem_unregister_notifier(struct notifier_block *nb);
 struct nvmem_device *nvmem_device_find(void *data,
 			int (*match)(struct device *dev, const void *data));
 
+struct nvmem_cell *fwnode_nvmem_cell_get(struct fwnode_handle *np,
+					 const char *name);
+struct nvmem_device *fwnode_nvmem_device_get(struct fwnode_handle *np,
+					     const char *name);
 #else
 
 static inline struct nvmem_cell *nvmem_cell_get(struct device *dev,
@@ -221,25 +227,24 @@ static inline struct nvmem_device *nvmem_device_find(void *data,
 	return NULL;
 }
 
-#endif /* CONFIG_NVMEM */
-
-#if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
-struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
-				     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 *id)
+static inline struct nvmem_cell *fwnode_nvmem_cell_get(struct fwnode_handle *np,
+						       const char *name)
 {
 	return ERR_PTR(-EOPNOTSUPP);
 }
 
-static inline struct nvmem_device *of_nvmem_device_get(struct device_node *np,
-						       const char *name)
+static inline struct nvmem_device *fwnode_nvmem_device_get(struct fwnode_handle *np,
+							   const char *name)
 {
 	return ERR_PTR(-EOPNOTSUPP);
 }
-#endif /* CONFIG_NVMEM && CONFIG_OF */
+
+#endif /* CONFIG_NVMEM */
+
+static inline struct nvmem_device *of_nvmem_cell_get(struct device_node *np,
+						     const char *name)
+{
+	return np ? fwnode_nvmem_cell_get(&np->fwnode, name) : NULL;
+}
 
 #endif  /* ifndef _LINUX_NVMEM_CONSUMER_H */
-- 
2.25.1


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

* Re: [PATCH] nvmem: Change to unified property interface
  2021-03-29 22:38 [PATCH] nvmem: Change to unified property interface Kevin Paul Herbert
                   ` (3 preceding siblings ...)
  2021-03-30  4:34 ` Kevin Paul Herbert
@ 2021-03-30  4:57 ` kernel test robot
  2021-03-30 10:43 ` kernel test robot
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2021-03-30  4:57 UTC (permalink / raw)
  To: Kevin Paul Herbert, Srinivas Kandagatla
  Cc: kbuild-all, clang-built-linux, Rafael J . Wysocki, Len Brown,
	linux-acpi, Rob Herring, Frank Rowand, devicetree, Tom Grennan,
	linux-kernel, Kevin Paul Herbert

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

Hi Kevin,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.12-rc5 next-20210329]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Kevin-Paul-Herbert/nvmem-Change-to-unified-property-interface/20210330-064121
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 1e43c377a79f9189fea8f2711b399d4e8b4e609b
config: x86_64-randconfig-a014-20210329 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 482283042f795ecc27838a3b2f76b5494991401c)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # https://github.com/0day-ci/linux/commit/edbc7632702cf638265a6d7180bd8c951cda6ad9
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Kevin-Paul-Herbert/nvmem-Change-to-unified-property-interface/20210330-064121
        git checkout edbc7632702cf638265a6d7180bd8c951cda6ad9
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/thermal/sprd_thermal.c:128:9: error: implicit declaration of function 'of_nvmem_cell_get' [-Werror,-Wimplicit-function-declaration]
           cell = of_nvmem_cell_get(np, cell_id);
                  ^
   drivers/thermal/sprd_thermal.c:128:9: note: did you mean 'nvmem_cell_get'?
   include/linux/nvmem-consumer.h:60:20: note: 'nvmem_cell_get' declared here
   struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *id);
                      ^
>> drivers/thermal/sprd_thermal.c:128:7: warning: incompatible integer to pointer conversion assigning to 'struct nvmem_cell *' from 'int' [-Wint-conversion]
           cell = of_nvmem_cell_get(np, cell_id);
                ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1 warning and 1 error generated.


vim +128 drivers/thermal/sprd_thermal.c

554fdbaf19b188 Freeman Liu 2020-02-18  120  
554fdbaf19b188 Freeman Liu 2020-02-18  121  static int sprd_thm_cal_read(struct device_node *np, const char *cell_id,
554fdbaf19b188 Freeman Liu 2020-02-18  122  			     u32 *val)
554fdbaf19b188 Freeman Liu 2020-02-18  123  {
554fdbaf19b188 Freeman Liu 2020-02-18  124  	struct nvmem_cell *cell;
554fdbaf19b188 Freeman Liu 2020-02-18  125  	void *buf;
554fdbaf19b188 Freeman Liu 2020-02-18  126  	size_t len;
554fdbaf19b188 Freeman Liu 2020-02-18  127  
554fdbaf19b188 Freeman Liu 2020-02-18 @128  	cell = of_nvmem_cell_get(np, cell_id);
554fdbaf19b188 Freeman Liu 2020-02-18  129  	if (IS_ERR(cell))
554fdbaf19b188 Freeman Liu 2020-02-18  130  		return PTR_ERR(cell);
554fdbaf19b188 Freeman Liu 2020-02-18  131  
554fdbaf19b188 Freeman Liu 2020-02-18  132  	buf = nvmem_cell_read(cell, &len);
554fdbaf19b188 Freeman Liu 2020-02-18  133  	nvmem_cell_put(cell);
554fdbaf19b188 Freeman Liu 2020-02-18  134  	if (IS_ERR(buf))
554fdbaf19b188 Freeman Liu 2020-02-18  135  		return PTR_ERR(buf);
554fdbaf19b188 Freeman Liu 2020-02-18  136  
554fdbaf19b188 Freeman Liu 2020-02-18  137  	if (len > sizeof(u32)) {
554fdbaf19b188 Freeman Liu 2020-02-18  138  		kfree(buf);
554fdbaf19b188 Freeman Liu 2020-02-18  139  		return -EINVAL;
554fdbaf19b188 Freeman Liu 2020-02-18  140  	}
554fdbaf19b188 Freeman Liu 2020-02-18  141  
554fdbaf19b188 Freeman Liu 2020-02-18  142  	memcpy(val, buf, len);
554fdbaf19b188 Freeman Liu 2020-02-18  143  
554fdbaf19b188 Freeman Liu 2020-02-18  144  	kfree(buf);
554fdbaf19b188 Freeman Liu 2020-02-18  145  	return 0;
554fdbaf19b188 Freeman Liu 2020-02-18  146  }
554fdbaf19b188 Freeman Liu 2020-02-18  147  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

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

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

* Re: [PATCH] nvmem: Change to unified property interface
  2021-03-29 22:38 [PATCH] nvmem: Change to unified property interface Kevin Paul Herbert
                   ` (4 preceding siblings ...)
  2021-03-30  4:57 ` [PATCH] " kernel test robot
@ 2021-03-30 10:43 ` kernel test robot
  2021-03-30 16:18 ` [PATCH v3 0/1] " Kevin Paul Herbert
  2021-03-30 16:18 ` [PATCH v3 1/1] " Kevin Paul Herbert
  7 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2021-03-30 10:43 UTC (permalink / raw)
  To: Kevin Paul Herbert, Srinivas Kandagatla
  Cc: kbuild-all, Rafael J . Wysocki, Len Brown, linux-acpi,
	Rob Herring, Frank Rowand, devicetree, Tom Grennan, linux-kernel,
	Kevin Paul Herbert

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

Hi Kevin,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v5.12-rc5 next-20210329]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Kevin-Paul-Herbert/nvmem-Change-to-unified-property-interface/20210330-064121
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 1e43c377a79f9189fea8f2711b399d4e8b4e609b
config: mips-allmodconfig (attached as .config)
compiler: mips-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/edbc7632702cf638265a6d7180bd8c951cda6ad9
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Kevin-Paul-Herbert/nvmem-Change-to-unified-property-interface/20210330-064121
        git checkout edbc7632702cf638265a6d7180bd8c951cda6ad9
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/thermal/sprd_thermal.c: In function 'sprd_thm_cal_read':
>> drivers/thermal/sprd_thermal.c:128:9: error: implicit declaration of function 'of_nvmem_cell_get'; did you mean 'nvmem_cell_get'? [-Werror=implicit-function-declaration]
     128 |  cell = of_nvmem_cell_get(np, cell_id);
         |         ^~~~~~~~~~~~~~~~~
         |         nvmem_cell_get
   drivers/thermal/sprd_thermal.c:128:7: warning: assignment to 'struct nvmem_cell *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     128 |  cell = of_nvmem_cell_get(np, cell_id);
         |       ^
   cc1: some warnings being treated as errors


vim +128 drivers/thermal/sprd_thermal.c

554fdbaf19b188 Freeman Liu 2020-02-18  120  
554fdbaf19b188 Freeman Liu 2020-02-18  121  static int sprd_thm_cal_read(struct device_node *np, const char *cell_id,
554fdbaf19b188 Freeman Liu 2020-02-18  122  			     u32 *val)
554fdbaf19b188 Freeman Liu 2020-02-18  123  {
554fdbaf19b188 Freeman Liu 2020-02-18  124  	struct nvmem_cell *cell;
554fdbaf19b188 Freeman Liu 2020-02-18  125  	void *buf;
554fdbaf19b188 Freeman Liu 2020-02-18  126  	size_t len;
554fdbaf19b188 Freeman Liu 2020-02-18  127  
554fdbaf19b188 Freeman Liu 2020-02-18 @128  	cell = of_nvmem_cell_get(np, cell_id);
554fdbaf19b188 Freeman Liu 2020-02-18  129  	if (IS_ERR(cell))
554fdbaf19b188 Freeman Liu 2020-02-18  130  		return PTR_ERR(cell);
554fdbaf19b188 Freeman Liu 2020-02-18  131  
554fdbaf19b188 Freeman Liu 2020-02-18  132  	buf = nvmem_cell_read(cell, &len);
554fdbaf19b188 Freeman Liu 2020-02-18  133  	nvmem_cell_put(cell);
554fdbaf19b188 Freeman Liu 2020-02-18  134  	if (IS_ERR(buf))
554fdbaf19b188 Freeman Liu 2020-02-18  135  		return PTR_ERR(buf);
554fdbaf19b188 Freeman Liu 2020-02-18  136  
554fdbaf19b188 Freeman Liu 2020-02-18  137  	if (len > sizeof(u32)) {
554fdbaf19b188 Freeman Liu 2020-02-18  138  		kfree(buf);
554fdbaf19b188 Freeman Liu 2020-02-18  139  		return -EINVAL;
554fdbaf19b188 Freeman Liu 2020-02-18  140  	}
554fdbaf19b188 Freeman Liu 2020-02-18  141  
554fdbaf19b188 Freeman Liu 2020-02-18  142  	memcpy(val, buf, len);
554fdbaf19b188 Freeman Liu 2020-02-18  143  
554fdbaf19b188 Freeman Liu 2020-02-18  144  	kfree(buf);
554fdbaf19b188 Freeman Liu 2020-02-18  145  	return 0;
554fdbaf19b188 Freeman Liu 2020-02-18  146  }
554fdbaf19b188 Freeman Liu 2020-02-18  147  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

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

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

* [PATCH v3 0/1] nvmem: Change to unified property interface
  2021-03-29 22:38 [PATCH] nvmem: Change to unified property interface Kevin Paul Herbert
                   ` (5 preceding siblings ...)
  2021-03-30 10:43 ` kernel test robot
@ 2021-03-30 16:18 ` Kevin Paul Herbert
  2021-03-30 16:18 ` [PATCH v3 1/1] " Kevin Paul Herbert
  7 siblings, 0 replies; 9+ messages in thread
From: Kevin Paul Herbert @ 2021-03-30 16:18 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Rafael J . Wysocki, Len Brown, linux-acpi, Rob Herring,
	Frank Rowand, devicetree, Tom Grennan, linux-kernel

nvmem: Change to unified property interface

Change from using device tree (Open Firmware) APIs to the unified
'fwnode' interface.

Change of_nvmem_cell_get() to fwnode_nvmem_cell_get(), and add a
wrapper for of_nvmem_cell_get().

Change of_nvmem_device_get() to fwnode_nvmem_device_get(). There
are no known accessors to the OF interface, so no need for a wrapper.

The first version of this patch incorrectly had a wrapper for
of_nvmem_device_get(), even though the comments about the patch
not needing this were correct.

The second version of this patch had an incorrect return type for
of_nvmem_device_get().


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

* [PATCH v3 1/1] nvmem: Change to unified property interface
  2021-03-29 22:38 [PATCH] nvmem: Change to unified property interface Kevin Paul Herbert
                   ` (6 preceding siblings ...)
  2021-03-30 16:18 ` [PATCH v3 0/1] " Kevin Paul Herbert
@ 2021-03-30 16:18 ` Kevin Paul Herbert
  7 siblings, 0 replies; 9+ messages in thread
From: Kevin Paul Herbert @ 2021-03-30 16:18 UTC (permalink / raw)
  To: Srinivas Kandagatla
  Cc: Rafael J . Wysocki, Len Brown, linux-acpi, Rob Herring,
	Frank Rowand, devicetree, Tom Grennan, linux-kernel,
	Kevin Paul Herbert, kernel test robot

Change from using device tree (Open Firmware) APIs to the unified
'fwnode' interface.

Change of_nvmem_cell_get() to fwnode_nvmem_cell_get(), and add a
wrapper for of_nvmem_cell_get().

Change of_nvmem_device_get() to fwnode_nvmem_device_get(). There
are no known accessors to the OF interface, so no need for a wrapper.

Reported-by: kernel test robot <lkp@intel.com>

Signed-off-by: Kevin Paul Herbert <kph@platinasystems.com>
---
 drivers/nvmem/core.c           | 176 ++++++++++++++++++++-------------
 include/linux/nvmem-consumer.h |  31 +++---
 2 files changed, 125 insertions(+), 82 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index a5ab1e0c74cf..2e49304cd9a8 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -6,6 +6,7 @@
  * Copyright (C) 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
  */
 
+#include <linux/acpi.h>
 #include <linux/device.h>
 #include <linux/export.h>
 #include <linux/fs.h>
@@ -17,6 +18,7 @@
 #include <linux/nvmem-provider.h>
 #include <linux/gpio/consumer.h>
 #include <linux/of.h>
+#include <linux/property.h>
 #include <linux/slab.h>
 
 struct nvmem_device {
@@ -52,7 +54,7 @@ struct nvmem_cell {
 	int			bytes;
 	int			bit_offset;
 	int			nbits;
-	struct device_node	*np;
+	struct fwnode_handle	*fwnode;
 	struct nvmem_device	*nvmem;
 	struct list_head	node;
 };
@@ -424,7 +426,7 @@ static void nvmem_cell_drop(struct nvmem_cell *cell)
 	mutex_lock(&nvmem_mutex);
 	list_del(&cell->node);
 	mutex_unlock(&nvmem_mutex);
-	of_node_put(cell->np);
+	fwnode_handle_put(cell->fwnode);
 	kfree_const(cell->name);
 	kfree(cell);
 }
@@ -670,39 +672,40 @@ static int nvmem_validate_keepouts(struct nvmem_device *nvmem)
 	return 0;
 }
 
-static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
+static int nvmem_add_cells_from_fw(struct nvmem_device *nvmem)
 {
-	struct device_node *parent, *child;
+	struct fwnode_handle *parent, *child;
 	struct device *dev = &nvmem->dev;
 	struct nvmem_cell *cell;
-	const __be32 *addr;
-	int len;
+	int rval;
+	u32 vals[2];
 
-	parent = dev->of_node;
+	parent = dev_fwnode(dev);
 
-	for_each_child_of_node(parent, child) {
-		addr = of_get_property(child, "reg", &len);
-		if (!addr)
+	fwnode_for_each_child_node(parent, child) {
+		rval = fwnode_property_read_u32_array(child, "reg", NULL, 2);
+		if (rval < 0)
 			continue;
-		if (len < 2 * sizeof(u32)) {
-			dev_err(dev, "nvmem: invalid reg on %pOF\n", child);
+		if (rval < 2) {
+			dev_err(dev, "nvmem: invalid reg %d on %pfw\n",
+				rval, child);
 			return -EINVAL;
 		}
-
+		rval = fwnode_property_read_u32_array(child, "reg", vals, 2);
 		cell = kzalloc(sizeof(*cell), GFP_KERNEL);
 		if (!cell)
 			return -ENOMEM;
 
 		cell->nvmem = nvmem;
-		cell->np = of_node_get(child);
-		cell->offset = be32_to_cpup(addr++);
-		cell->bytes = be32_to_cpup(addr);
-		cell->name = kasprintf(GFP_KERNEL, "%pOFn", child);
-
-		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);
+		cell->fwnode = child;
+		cell->offset = vals[0];
+		cell->bytes = vals[1];
+		cell->name = kasprintf(GFP_KERNEL, "%pfwn", child);
+
+		rval = fwnode_property_read_u32_array(child, "bits", vals, 2);
+		if (rval >= 0) {
+			cell->bit_offset = vals[0];
+			cell->nbits = vals[1];
 		}
 
 		if (cell->nbits)
@@ -715,7 +718,7 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
 				cell->name, nvmem->stride);
 			/* Cells already added will be freed later. */
 			kfree_const(cell->name);
-			of_node_put(cell->np);
+			fwnode_handle_put(cell->fwnode);
 			kfree(cell);
 			return -EINVAL;
 		}
@@ -789,8 +792,10 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	nvmem->reg_write = config->reg_write;
 	nvmem->keepout = config->keepout;
 	nvmem->nkeepout = config->nkeepout;
-	if (!config->no_of_node)
+	if (!config->no_of_node) {
 		nvmem->dev.of_node = config->dev->of_node;
+		nvmem->dev.fwnode = config->dev->fwnode;
+	}
 
 	switch (config->id) {
 	case NVMEM_DEVID_NONE:
@@ -841,7 +846,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	if (rval)
 		goto err_remove_cells;
 
-	rval = nvmem_add_cells_from_of(nvmem);
+	rval = nvmem_add_cells_from_fw(nvmem);
 	if (rval)
 		goto err_remove_cells;
 
@@ -984,36 +989,46 @@ static void __nvmem_device_put(struct nvmem_device *nvmem)
 	kref_put(&nvmem->refcnt, nvmem_device_release);
 }
 
-#if IS_ENABLED(CONFIG_OF)
 /**
- * of_nvmem_device_get() - Get nvmem device from a given id
+ * fwnode_nvmem_device_get() - Get nvmem device from a given id
  *
- * @np: Device tree node that uses the nvmem device.
+ * @fwnode: Firmware node that uses the nvmem device.
  * @id: nvmem name from nvmem-names property.
  *
  * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device
  * on success.
  */
-struct nvmem_device *of_nvmem_device_get(struct device_node *np, const char *id)
+struct nvmem_device *fwnode_nvmem_device_get(struct fwnode_handle *fwnode, const char *id)
 {
-
-	struct device_node *nvmem_np;
+	struct fwnode_handle *nvmem_fwnode;
 	struct nvmem_device *nvmem;
 	int index = 0;
 
 	if (id)
-		index = of_property_match_string(np, "nvmem-names", id);
-
-	nvmem_np = of_parse_phandle(np, "nvmem", index);
-	if (!nvmem_np)
-		return ERR_PTR(-ENOENT);
+		index = fwnode_property_match_string(fwnode, "nvmem-names", id);
+
+	if (is_of_node(fwnode)) {
+		struct device_node *nvmem_np = of_parse_phandle(to_of_node(fwnode),
+								"nvmem", index);
+		if (!nvmem_np)
+			return ERR_PTR(-ENOENT);
+		nvmem_fwnode = &nvmem_np->fwnode;
+	} else if (is_acpi_device_node(fwnode)) {
+		struct fwnode_reference_args args;
+		int rval = acpi_node_get_property_reference(fwnode,
+							    "nvmem", index, &args);
+		if (rval)
+			return ERR_PTR(rval);
+		nvmem_fwnode = args.fwnode;
+	} else {
+		return ERR_PTR(-ENXIO);
+	}
 
-	nvmem = __nvmem_device_get(nvmem_np, device_match_of_node);
-	of_node_put(nvmem_np);
+	nvmem = __nvmem_device_get(nvmem_fwnode, device_match_fwnode);
+	fwnode_handle_put(nvmem_fwnode);
 	return nvmem;
 }
-EXPORT_SYMBOL_GPL(of_nvmem_device_get);
-#endif
+EXPORT_SYMBOL_GPL(fwnode_nvmem_device_get);
 
 /**
  * nvmem_device_get() - Get nvmem device from a given id
@@ -1026,16 +1041,15 @@ EXPORT_SYMBOL_GPL(of_nvmem_device_get);
  */
 struct nvmem_device *nvmem_device_get(struct device *dev, const char *dev_name)
 {
-	if (dev->of_node) { /* try dt first */
-		struct nvmem_device *nvmem;
+	struct fwnode_handle *fwnode = dev_fwnode(dev);
 
-		nvmem = of_nvmem_device_get(dev->of_node, dev_name);
+	if (fwnode) { /* try firmware tree first */
+		struct nvmem_device *nvmem;
 
+		nvmem = fwnode_nvmem_device_get(fwnode, dev_name);
 		if (!IS_ERR(nvmem) || PTR_ERR(nvmem) == -EPROBE_DEFER)
 			return nvmem;
-
 	}
-
 	return __nvmem_device_get((void *)dev_name, device_match_name);
 }
 EXPORT_SYMBOL_GPL(nvmem_device_get);
@@ -1171,15 +1185,14 @@ nvmem_cell_get_from_lookup(struct device *dev, const char *con_id)
 	return cell;
 }
 
-#if IS_ENABLED(CONFIG_OF)
 static struct nvmem_cell *
-nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np)
+nvmem_find_cell_by_fwnode(struct nvmem_device *nvmem, struct fwnode_handle *fwnode)
 {
 	struct nvmem_cell *iter, *cell = NULL;
 
 	mutex_lock(&nvmem_mutex);
 	list_for_each_entry(iter, &nvmem->cells, node) {
-		if (np == iter->np) {
+		if (fwnode == iter->fwnode) {
 			cell = iter;
 			break;
 		}
@@ -1190,42 +1203,67 @@ nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np)
 }
 
 /**
- * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
+ * fwnode_nvmem_cell_get() - Get a nvmem cell from given firmwar node and cell id
  *
- * @np: Device tree node that uses the nvmem cell.
+ * @fwnode: Firmware node that uses the nvmem cell.
  * @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).
+ *	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 *id)
+struct nvmem_cell *fwnode_nvmem_cell_get(struct fwnode_handle *fwnode,
+					 const char *id)
 {
-	struct device_node *cell_np, *nvmem_np;
+	struct fwnode_handle *nvmem_fwnode, *cell_fwnode;
 	struct nvmem_device *nvmem;
 	struct nvmem_cell *cell;
 	int index = 0;
 
 	/* if cell name exists, find index to the name */
-	if (id)
-		index = of_property_match_string(np, "nvmem-cell-names", id);
+	if (id) {
+		index = fwnode_property_match_string(fwnode, "nvmem-cell-names", id);
+		if (index < 0)
+			return ERR_PTR(index);
+	}
 
-	cell_np = of_parse_phandle(np, "nvmem-cells", index);
-	if (!cell_np)
-		return ERR_PTR(-ENOENT);
+	if (is_of_node(fwnode)) {
+		struct device_node *np = to_of_node(fwnode);
+		struct device_node *cell_np = of_parse_phandle(np, "nvmem-cells", index);
+
+		if (!cell_np)
+			return ERR_PTR(-EINVAL);
+		cell_fwnode = &cell_np->fwnode;
+	} else if (is_acpi_device_node(fwnode)) {
+		struct fwnode_reference_args args;
+		struct fwnode_handle *dev_fwnode;
+		int rval;
 
-	nvmem_np = of_get_next_parent(cell_np);
-	if (!nvmem_np)
+		rval = acpi_node_get_property_reference(fwnode,
+							"nvmem-cells", index, &args);
+		if (rval)
+			return ERR_PTR(rval);
+		dev_fwnode = args.fwnode;
+		cell_fwnode = fwnode_get_named_child_node(dev_fwnode,
+							  id ? id : "nvmem");
+		if (!cell_fwnode)
+			return ERR_PTR(-EINVAL);
+	} else {
+		return ERR_PTR(-ENXIO);
+	}
+
+	nvmem_fwnode = fwnode_get_next_parent(cell_fwnode);
+	if (!nvmem_fwnode)
 		return ERR_PTR(-EINVAL);
 
-	nvmem = __nvmem_device_get(nvmem_np, device_match_of_node);
-	of_node_put(nvmem_np);
+	nvmem = __nvmem_device_get(nvmem_fwnode, device_match_fwnode);
+	fwnode_handle_put(nvmem_fwnode);
 	if (IS_ERR(nvmem))
 		return ERR_CAST(nvmem);
 
-	cell = nvmem_find_cell_by_node(nvmem, cell_np);
+	cell = nvmem_find_cell_by_fwnode(nvmem, cell_fwnode);
 	if (!cell) {
 		__nvmem_device_put(nvmem);
 		return ERR_PTR(-ENOENT);
@@ -1233,8 +1271,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id)
 
 	return cell;
 }
-EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
-#endif
+EXPORT_SYMBOL_GPL(fwnode_nvmem_cell_get);
 
 /**
  * nvmem_cell_get() - Get nvmem cell of device form a given cell name
@@ -1251,14 +1288,15 @@ EXPORT_SYMBOL_GPL(of_nvmem_cell_get);
 struct nvmem_cell *nvmem_cell_get(struct device *dev, const char *id)
 {
 	struct nvmem_cell *cell;
+	struct fwnode_handle *fwnode = dev_fwnode(dev);
 
-	if (dev->of_node) { /* try dt first */
-		cell = of_nvmem_cell_get(dev->of_node, id);
+	if (fwnode) { /* try firmware tree first */
+		cell = fwnode_nvmem_cell_get(fwnode, id);
 		if (!IS_ERR(cell) || PTR_ERR(cell) == -EPROBE_DEFER)
 			return cell;
 	}
 
-	/* NULL cell id only allowed for device tree; invalid otherwise */
+	/* NULL cell_id only allowed for firmware tree; invalid otherwise */
 	if (!id)
 		return ERR_PTR(-EINVAL);
 
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 052293f4cbdb..50ada98cca2a 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -12,12 +12,14 @@
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/notifier.h>
+#include <linux/of.h>
 
 struct device;
 struct device_node;
 /* consumer cookie */
 struct nvmem_cell;
 struct nvmem_device;
+struct fwnode_handle;
 
 struct nvmem_cell_info {
 	const char		*name;
@@ -94,6 +96,10 @@ int nvmem_unregister_notifier(struct notifier_block *nb);
 struct nvmem_device *nvmem_device_find(void *data,
 			int (*match)(struct device *dev, const void *data));
 
+struct nvmem_cell *fwnode_nvmem_cell_get(struct fwnode_handle *np,
+					 const char *name);
+struct nvmem_device *fwnode_nvmem_device_get(struct fwnode_handle *np,
+					     const char *name);
 #else
 
 static inline struct nvmem_cell *nvmem_cell_get(struct device *dev,
@@ -221,25 +227,24 @@ static inline struct nvmem_device *nvmem_device_find(void *data,
 	return NULL;
 }
 
-#endif /* CONFIG_NVMEM */
-
-#if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
-struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
-				     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 *id)
+static inline struct nvmem_cell *fwnode_nvmem_cell_get(struct fwnode_handle *np,
+						       const char *name)
 {
 	return ERR_PTR(-EOPNOTSUPP);
 }
 
-static inline struct nvmem_device *of_nvmem_device_get(struct device_node *np,
-						       const char *name)
+static inline struct nvmem_device *fwnode_nvmem_device_get(struct fwnode_handle *np,
+							   const char *name)
 {
 	return ERR_PTR(-EOPNOTSUPP);
 }
-#endif /* CONFIG_NVMEM && CONFIG_OF */
+
+#endif /* CONFIG_NVMEM */
+
+static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np,
+						     const char *name)
+{
+	return np ? fwnode_nvmem_cell_get(&np->fwnode, name) : NULL;
+}
 
 #endif  /* ifndef _LINUX_NVMEM_CONSUMER_H */
-- 
2.25.1


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

end of thread, other threads:[~2021-03-30 16:19 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-29 22:38 [PATCH] nvmem: Change to unified property interface Kevin Paul Herbert
2021-03-30  3:21 ` kernel test robot
2021-03-30  4:26 ` [PATCH v2] " Kevin Paul Herbert
2021-03-30  4:28 ` Kevin Paul Herbert
2021-03-30  4:34 ` Kevin Paul Herbert
2021-03-30  4:57 ` [PATCH] " kernel test robot
2021-03-30 10:43 ` kernel test robot
2021-03-30 16:18 ` [PATCH v3 0/1] " Kevin Paul Herbert
2021-03-30 16:18 ` [PATCH v3 1/1] " Kevin Paul Herbert

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).