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

Commit 07b4fed7 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "nvmem: core: Export nvmem cell info to userspace"

parents 32b9fcd6 15d33a02
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -97,6 +97,13 @@ config MTK_EFUSE
	  This driver can also be built as a module. If so, the module
	  will be called efuse-mtk.

config QCOM_QFPROM_SYSFS
	tristate "QCOM QFPROM SYSFS"
	depends on QCOM_QFPROM
	help
	  Say y here to enable QFPROM SYSFS support. The QFPROM SYSFS
	  create each child node of QFPROM as sysfs entries as well.

config QCOM_QFPROM
	tristate "QCOM QFPROM Support"
	depends on ARCH_QCOM || COMPILE_TEST
+45 −0
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ struct nvmem_cell {
	int			nbits;
	struct device_node	*np;
	struct nvmem_device	*nvmem;
#ifdef CONFIG_QCOM_QFPROM_SYSFS
	struct bin_attribute	attr;
#endif
	struct list_head	node;
};

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

#ifdef CONFIG_QCOM_QFPROM_SYSFS
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;
}
#endif

static void nvmem_release(struct device *dev)
{
	struct nvmem_device *nvmem = to_nvmem_device(dev);
@@ -107,6 +132,9 @@ static void nvmem_cell_drop(struct nvmem_cell *cell)
{
	blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_REMOVE, cell);
	mutex_lock(&nvmem_mutex);
#ifdef CONFIG_QCOM_QFPROM_SYSFS
	device_remove_bin_file(&cell->nvmem->dev, &cell->attr);
#endif
	list_del(&cell->node);
	mutex_unlock(&nvmem_mutex);
	of_node_put(cell->np);
@@ -124,8 +152,25 @@ static void nvmem_device_remove_all_cells(const struct nvmem_device *nvmem)

static void nvmem_cell_add(struct nvmem_cell *cell)
{
#ifdef CONFIG_QCOM_QFPROM_SYSFS
	int rval;
	struct bin_attribute *nvmem_cell_attr = &cell->attr;
#endif
	mutex_lock(&nvmem_mutex);
	list_add_tail(&cell->node, &cell->nvmem->cells);

#ifdef CONFIG_QCOM_QFPROM_SYSFS
	/* 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);
#endif
	mutex_unlock(&nvmem_mutex);
	blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_ADD, cell);
}