Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7bd5a8d5 authored by Shiraz Hashim's avatar Shiraz Hashim Committed by Gerrit - the friendly Code Review server
Browse files

nvmem: core: Export nvmem cell info to userspace



Existing nvmem framework export full register space
as nvmem binary, but not exporting child node of nvmem
which is nvmem cell. Kernel can read the specific cell
by using nvmem_cell_read but userspace don't have such
provision.

Add framework to export nvmem cell as well, So
userspace can use it directly.

Change-Id: I3b41a91820f6d2a4536933e7bab4ac1b94f1541a
Signed-off-by: default avatarShiraz Hashim <shashim@codeaurora.org>
Signed-off-by: default avatarGaurav Kohli <gkohli@codeaurora.org>
parent b64cdce7
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ struct nvmem_cell {
	int			nbits;
	struct device_node	*np;
	struct nvmem_device	*nvmem;
	struct bin_attribute	attr;
	struct list_head	node;
};

@@ -63,6 +64,26 @@ static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
	return -EINVAL;
}

static ssize_t bin_attr_nvmem_cell_read(struct file *filp, struct kobject *kobj,
				    struct bin_attribute *attr,
				    char *buf, loff_t pos, size_t count)
{
	struct nvmem_cell *cell;
	size_t len;
	u8 *data;

	cell = attr->private;

	data = nvmem_cell_read(cell, &len);
	if (IS_ERR(data))
		return -EINVAL;

	len = min(len, count);
	memcpy(buf, data, len);
	kfree(data);
	return len;
}

static void nvmem_release(struct device *dev)
{
	struct nvmem_device *nvmem = to_nvmem_device(dev);
@@ -102,6 +123,7 @@ static struct nvmem_device *of_nvmem_find(struct device_node *nvmem_np)
static void nvmem_cell_drop(struct nvmem_cell *cell)
{
	mutex_lock(&nvmem_mutex);
	device_remove_bin_file(&cell->nvmem->dev, &cell->attr);
	list_del(&cell->node);
	mutex_unlock(&nvmem_mutex);
	of_node_put(cell->np);
@@ -118,8 +140,23 @@ static void nvmem_device_remove_all_cells(const struct nvmem_device *nvmem)

static void nvmem_cell_add(struct nvmem_cell *cell)
{
	int rval;
	struct bin_attribute *nvmem_cell_attr = &cell->attr;

	mutex_lock(&nvmem_mutex);
	list_add_tail(&cell->node, &cell->nvmem->cells);

	/* add attr for this cell */
	nvmem_cell_attr->attr.name = cell->name;
	nvmem_cell_attr->attr.mode = 0444;
	nvmem_cell_attr->private = cell;
	nvmem_cell_attr->size = cell->bytes;
	nvmem_cell_attr->read = bin_attr_nvmem_cell_read;
	rval = device_create_bin_file(&cell->nvmem->dev, nvmem_cell_attr);
	if (rval)
		dev_err(&cell->nvmem->dev,
			"Failed to create cell binary file %d\n", rval);

	mutex_unlock(&nvmem_mutex);
}