Re: [PATCH v8 2/9] nvmem: Add a simple NVMEM framework for consumers

2015-07-22 Thread Srinivas Kandagatla

Thanks Stefan,

On 21/07/15 17:25, Stefan Wahren wrote:

+
+ addr = of_get_property(cell_np, reg, len);
+ if (!addr || (len  2 * sizeof(int))) {

I'm not sure, but shouldn't be sizeof(u32) more portable?


yes it makes sense, I will change it.

[...]
+
+ addr = of_get_property(cell_np, bits, len);
+ if (addr  len == (2 * sizeof(int))) {

dito

yep.

--srini
--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v8 2/9] nvmem: Add a simple NVMEM framework for consumers

2015-07-21 Thread Stefan Wahren
Hi Srinivas,

 Srinivas Kandagatla srinivas.kandaga...@linaro.org hat am 20. Juli 2015 um
 16:43 geschrieben:


 This patch adds just consumers part of the framework just to enable easy
 review.

 Up until now, nvmem drivers were stored in drivers/misc, where they all
 had to duplicate pretty much the same code to register a sysfs file,
 allow in-kernel users to access the content of the devices they were
 driving, etc.

 This was also a problem as far as other in-kernel users were involved,
 since the solutions used were pretty much different from on driver to
 another, there was a rather big abstraction leak.

 This introduction of this framework aims at solving this. It also
 introduces DT representation for consumer devices to go get the data they
 require (MAC Addresses, SoC/Revision ID, part numbers, and so on) from
 the nvmems.

 Having regmap interface to this framework would give much better
 abstraction for nvmems on different buses.

 Signed-off-by: Maxime Ripard maxime.rip...@free-electrons.com
 [Maxime Ripard: intial version of the framework]
 Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org
 ---
 drivers/nvmem/core.c | 415 +
 include/linux/nvmem-consumer.h | 61 ++
 2 files changed, 476 insertions(+)

 diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
 index bde5528..de14c36 100644
 --- a/drivers/nvmem/core.c
 +++ b/drivers/nvmem/core.c
 [...]
 +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, index;
 +
 + index = of_property_match_string(np, nvmem-cell-names, name);
 +
 + cell_np = of_parse_phandle(np, nvmem-cells, index);
 + if (!cell_np)
 + return ERR_PTR(-EINVAL);
 +
 + nvmem_np = of_get_next_parent(cell_np);
 + if (!nvmem_np)
 + return ERR_PTR(-EINVAL);
 +
 + nvmem = __nvmem_device_get(nvmem_np, NULL, NULL);
 + if (IS_ERR(nvmem))
 + return ERR_CAST(nvmem);
 +
 + addr = of_get_property(cell_np, reg, len);
 + if (!addr || (len  2 * sizeof(int))) {

I'm not sure, but shouldn't be sizeof(u32) more portable?

 [...]
 +
 + addr = of_get_property(cell_np, bits, len);
 + if (addr  len == (2 * sizeof(int))) {

dito

Regards
Stefan
--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v8 2/9] nvmem: Add a simple NVMEM framework for consumers

2015-07-20 Thread Srinivas Kandagatla
This patch adds just consumers part of the framework just to enable easy
review.

Up until now, nvmem drivers were stored in drivers/misc, where they all
had to duplicate pretty much the same code to register a sysfs file,
allow in-kernel users to access the content of the devices they were
driving, etc.

This was also a problem as far as other in-kernel users were involved,
since the solutions used were pretty much different from on driver to
another, there was a rather big abstraction leak.

This introduction of this framework aims at solving this. It also
introduces DT representation for consumer devices to go get the data they
require (MAC Addresses, SoC/Revision ID, part numbers, and so on) from
the nvmems.

Having regmap interface to this framework would give much better
abstraction for nvmems on different buses.

Signed-off-by: Maxime Ripard maxime.rip...@free-electrons.com
[Maxime Ripard: intial version of the framework]
Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org
---
 drivers/nvmem/core.c   | 415 +
 include/linux/nvmem-consumer.h |  61 ++
 2 files changed, 476 insertions(+)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index bde5528..de14c36 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -365,6 +365,421 @@ int nvmem_unregister(struct nvmem_device *nvmem)
 }
 EXPORT_SYMBOL_GPL(nvmem_unregister);
 
+static struct nvmem_device *__nvmem_device_get(struct device_node *np,
+  struct nvmem_cell **cellp,
+  const char *cell_id)
+{
+   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);
+   }
+   }
+
+   nvmem-users++;
+   mutex_unlock(nvmem_mutex);
+
+   if (!try_module_get(nvmem-owner)) {
+   dev_err(nvmem-dev,
+   could not increase module refcount for cell %s\n,
+   nvmem-name);
+
+   mutex_lock(nvmem_mutex);
+   nvmem-users--;
+   mutex_unlock(nvmem_mutex);
+
+   return ERR_PTR(-EINVAL);
+   }
+
+   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);
+}
+
+static struct nvmem_cell *nvmem_cell_get_from_list(const char *cell_id)
+{
+   struct nvmem_cell *cell = NULL;
+   struct nvmem_device *nvmem;
+
+   nvmem = __nvmem_device_get(NULL, cell, cell_id);
+   if (IS_ERR(nvmem))
+   return ERR_CAST(nvmem);
+
+   return cell;
+}
+
+#if IS_ENABLED(CONFIG_NVMEM)  IS_ENABLED(CONFIG_OF)
+/**
+ * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
+ *
+ * @dev node: Device tree node that uses the nvmem cell
+ * @id: nvmem cell name from 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 device_node *cell_np, *nvmem_np;
+   struct nvmem_cell *cell;
+   struct nvmem_device *nvmem;
+   const __be32 *addr;
+   int rval, len, index;
+
+   index = of_property_match_string(np, nvmem-cell-names, name);
+
+   cell_np = of_parse_phandle(np, nvmem-cells, index);
+   if (!cell_np)
+   return ERR_PTR(-EINVAL);
+
+   nvmem_np = of_get_next_parent(cell_np);
+   if (!nvmem_np)
+   return ERR_PTR(-EINVAL);
+
+   nvmem = __nvmem_device_get(nvmem_np, NULL, NULL);
+   if (IS_ERR(nvmem))
+   return ERR_CAST(nvmem);
+
+   addr = of_get_property(cell_np, reg, len);
+   if (!addr || (len  2 * sizeof(int))) {
+   dev_err(nvmem-dev, nvmem: invalid reg on %s\n,
+   cell_np-full_name);
+   rval  = -EINVAL;
+   goto err_mem;
+   }
+
+   cell = kzalloc(sizeof(*cell), GFP_KERNEL);
+   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;
+
+