From 2c06b9a2bc204b905256c0f24817a37a1d3453fe Mon Sep 17 00:00:00 2001 From: Naina Mehta Date: Mon, 5 Oct 2020 12:34:02 +0530 Subject: [PATCH 1/2] nvmem: qfprom-sys: Add driver to export cell value Add qfprom-sys driver to export the nvmem cell values as sysfs attrs to enable user space access. Change-Id: Ic1770054fe2a1b87cf56859aafba03f7340fe273 Signed-off-by: Naina Mehta --- drivers/soc/qcom/Kconfig | 10 +++ drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/qfprom-sys.c | 154 ++++++++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 drivers/soc/qcom/qfprom-sys.c diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index adee1670911c..f51ff4b6f95c 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -337,6 +337,16 @@ config QCOM_QMI_HELPERS source "drivers/soc/qcom/memshare/Kconfig" +config QCOM_QFPROM_SYS + tristate "Qualcomm Technologies, Inc. QFPROM_SYS driver " + depends on QCOM_QFPROM + help + Qualcomm Technologies, Inc. QFPROM_SYS driver. The QFPROM SYS driver + provides access to the child nodes of QFPROM to user space. The cell + values are exported as sysfs entries. + + Say y here to enable QFPROM SYS support. + config QCOM_RMTFS_MEM tristate "Qualcomm Remote Filesystem memory driver" depends on ARCH_QCOM diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 445b46d3249c..f630d666b9ab 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -96,3 +96,4 @@ obj-$(CONFIG_ICNSS2) += icnss2/ obj-$(CONFIG_QTI_HW_MEMLAT_SCMI_CLIENT) += memlat_scmi.o obj-$(CONFIG_QTI_HW_MEMLAT) += rimps_memlat.o obj-$(CONFIG_QTI_HW_MEMLAT_LOG) += rimps_log.o +obj-$(CONFIG_QCOM_QFPROM_SYS) += qfprom-sys.o diff --git a/drivers/soc/qcom/qfprom-sys.c b/drivers/soc/qcom/qfprom-sys.c new file mode 100644 index 000000000000..80d8fd4269ae --- /dev/null +++ b/drivers/soc/qcom/qfprom-sys.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct qfprom_sys { + int cell_count; + struct nvmem_cell **cells; + struct bin_attribute **attrs; +}; + +static ssize_t qfprom_sys_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; + if (!cell) + return -EINVAL; + + 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 int qfprom_sys_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct qfprom_sys *priv; + struct nvmem_cell *cell; + int cell_count; + int i, ret; + const char **cells; + + cell_count = of_property_count_strings(dev->of_node, "nvmem-cell-names"); + if (cell_count <= 0) + return -EINVAL; + + priv = devm_kzalloc(dev, sizeof(struct qfprom_sys), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->cells = devm_kzalloc(dev, + cell_count * sizeof(struct nvmem_cell *), + GFP_KERNEL); + if (!priv->cells) + return -ENOMEM; + + cells = devm_kzalloc(dev, cell_count * sizeof(char *), GFP_KERNEL); + if (!cells) + return -ENOMEM; + + priv->attrs = devm_kzalloc(dev, + cell_count * sizeof(struct bin_attribute *), + GFP_KERNEL); + if (!priv->attrs) + return -ENOMEM; + + ret = of_property_read_string_array(dev->of_node, "nvmem-cell-names", + cells, cell_count); + + for (i = 0; i < cell_count; i++) { + cell = nvmem_cell_get(dev, cells[i]); + if (IS_ERR_OR_NULL(cell)) { + ret = PTR_ERR(cell); + dev_err(dev, "cell corresponding to %s not found\n", + cells[i]); + goto remove_cells; + } + + priv->attrs[i] = devm_kzalloc(dev, sizeof(struct bin_attribute), + GFP_KERNEL); + if (!priv->attrs[i]) { + ret = -ENOMEM; + nvmem_cell_put(cell); + goto remove_cells; + } + + priv->cells[i] = cell; + sysfs_bin_attr_init(priv->attrs[i]); + priv->attrs[i]->attr.name = cells[i]; + priv->attrs[i]->attr.mode = 0444; + priv->attrs[i]->private = cell; + priv->attrs[i]->size = 4; + priv->attrs[i]->read = qfprom_sys_cell_read; + ret = sysfs_create_bin_file(&dev->kobj, priv->attrs[i]); + if (ret) { + dev_err(dev, "cell corresponding to %s\n", cells[i]); + nvmem_cell_put(cell); + goto remove_cells; + } + } + + priv->cell_count = cell_count; + dev->platform_data = priv; + return 0; + +remove_cells: + for (; i > 0; i--) { + sysfs_remove_bin_file(&dev->kobj, priv->attrs[i-1]); + nvmem_cell_put(priv->cells[i-1]); + } + priv->cell_count = 0; + return ret; +} + +static int qfprom_sys_remove(struct platform_device *pdev) +{ + struct qfprom_sys *priv; + int i; + + priv = dev_get_platdata(&pdev->dev); + for (i = 0; i < priv->cell_count; i++) { + nvmem_cell_put(priv->cells[i]); + sysfs_remove_bin_file(&pdev->dev.kobj, priv->attrs[i]); + } + + return 0; +} + +static const struct of_device_id qfprom_sys_of_match[] = { + { .compatible = "qcom,qfprom-sys",}, + {}, +}; + +MODULE_DEVICE_TABLE(of, qfprom_sys_of_match); + +static struct platform_driver qfprom_sys_driver = { + .probe = qfprom_sys_probe, + .remove = qfprom_sys_remove, + .driver = { + .name = "qcom,qfprom-sys", + .of_match_table = qfprom_sys_of_match, + }, +}; + +module_platform_driver(qfprom_sys_driver); +MODULE_DESCRIPTION("Qualcomm Technologies, Inc. QFPROM_SYS driver"); +MODULE_LICENSE("GPL v2"); From 0071fbbdb1372739a94b2321c046044e4f10738e Mon Sep 17 00:00:00 2001 From: Neeraj Upadhyay Date: Wed, 14 Oct 2020 16:02:04 +0530 Subject: [PATCH 2/2] defconfig: msm: Enable qfprom_sys for Lahaina GKI Enable qfprom_sys as module in Lahaina gki defconfig. Change-Id: I91d0c9e3883d130ca7ed51c12aa96581950e09db Signed-off-by: Neeraj Upadhyay --- arch/arm64/configs/vendor/lahaina_GKI.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/vendor/lahaina_GKI.config b/arch/arm64/configs/vendor/lahaina_GKI.config index 6d0b919b61ce..aade3f0810ca 100644 --- a/arch/arm64/configs/vendor/lahaina_GKI.config +++ b/arch/arm64/configs/vendor/lahaina_GKI.config @@ -228,3 +228,4 @@ CONFIG_QCOM_SOC_WATCHDOG=m CONFIG_QPNP_PBS=m CONFIG_ARCH_YUPIK=y CONFIG_PINCTRL_YUPIK=m +CONFIG_QCOM_QFPROM_SYS=m