Loading drivers/nvmem/Kconfig +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading drivers/nvmem/core.c +45 −0 Original line number Diff line number Diff line Loading @@ -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; }; Loading Loading @@ -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); Loading Loading @@ -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); Loading @@ -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); } Loading Loading
drivers/nvmem/Kconfig +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
drivers/nvmem/core.c +45 −0 Original line number Diff line number Diff line Loading @@ -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; }; Loading Loading @@ -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); Loading Loading @@ -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); Loading @@ -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); } Loading