All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/14] nvmem: patches (set 1) for 5.9
@ 2020-07-22 10:06 Srinivas Kandagatla
  2020-07-22 10:06 ` [PATCH 01/14] nvmem: sprd: Fix return value of sprd_efuse_probe() Srinivas Kandagatla
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-kernel, Srinivas Kandagatla

Hi Greg,

Here are some nvmem patches for 5.9 which includes
- adding support to AUTO devid for providers which have multiple instances.
- add new nvmem_cell_read_u8()
- new sc27xx provider, add write support to qfprom.
- few trivial fixes.

Can you please queue them up for 5.9.

thanks for you help,
srini

Andreas Färber (2):
  nvmem: core: Grammar fixes for help text
  nvmem: core: Add nvmem_cell_read_u8()

Douglas Anderson (1):
  nvmem: Enforce nvmem stride in the sysfs interface

Freeman Liu (1):
  nvmem: sc27xx: add sc2730 efuse support

Guru Das Srinagesh (1):
  nvmem: qcom-spmi-sdam: Enable multiple devices

Matteo Croce (1):
  nvmem: update Kconfig description

Ravi Kumar Bokka (3):
  dt-bindings: nvmem: qfprom: Convert to yaml
  dt-bindings: nvmem: Add properties needed for blowing fuses
  nvmem: qfprom: Add fuse blowing support

Srinivas Kandagatla (2):
  nvmem: core: add support to auto devid
  nvmem: qfprom: use NVMEM_DEVID_AUTO for multiple instances

Tiezhu Yang (2):
  nvmem: sprd: Fix return value of sprd_efuse_probe()
  MAINTAINERS: Add git tree for NVMEM FRAMEWORK

Yangtao Li (1):
  dt-bindings: nvmem: SID: add binding for A100's SID controller

 .../nvmem/allwinner,sun4i-a10-sid.yaml        |  19 +-
 .../bindings/nvmem/qcom,qfprom.yaml           |  96 ++++++
 .../devicetree/bindings/nvmem/qfprom.txt      |  35 --
 MAINTAINERS                                   |   1 +
 drivers/nvmem/Kconfig                         |   3 -
 drivers/nvmem/core.c                          |  43 ++-
 drivers/nvmem/qcom-spmi-sdam.c                |   4 +-
 drivers/nvmem/qfprom.c                        | 315 +++++++++++++++++-
 drivers/nvmem/sc27xx-efuse.c                  |  27 +-
 drivers/nvmem/sprd-efuse.c                    |   4 +-
 include/linux/nvmem-consumer.h                |   1 +
 include/linux/nvmem-provider.h                |   3 +
 12 files changed, 479 insertions(+), 72 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
 delete mode 100644 Documentation/devicetree/bindings/nvmem/qfprom.txt

-- 
2.21.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 01/14] nvmem: sprd: Fix return value of sprd_efuse_probe()
  2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
@ 2020-07-22 10:06 ` Srinivas Kandagatla
  2020-07-22 10:06 ` [PATCH 02/14] MAINTAINERS: Add git tree for NVMEM FRAMEWORK Srinivas Kandagatla
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-kernel, Tiezhu Yang, Srinivas Kandagatla

From: Tiezhu Yang <yangtiezhu@loongson.cn>

When call function devm_platform_ioremap_resource(), we should use IS_ERR()
to check the return value and return PTR_ERR() if failed.

Fixes: 096030e7f449 ("nvmem: sprd: Add Spreadtrum SoCs eFuse support")
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/nvmem/sprd-efuse.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/nvmem/sprd-efuse.c b/drivers/nvmem/sprd-efuse.c
index 925feb21d5ad..59523245db8a 100644
--- a/drivers/nvmem/sprd-efuse.c
+++ b/drivers/nvmem/sprd-efuse.c
@@ -378,8 +378,8 @@ static int sprd_efuse_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	efuse->base = devm_platform_ioremap_resource(pdev, 0);
-	if (!efuse->base)
-		return -ENOMEM;
+	if (IS_ERR(efuse->base))
+		return PTR_ERR(efuse->base);
 
 	ret = of_hwspin_lock_get_id(np, 0);
 	if (ret < 0) {
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 02/14] MAINTAINERS: Add git tree for NVMEM FRAMEWORK
  2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
  2020-07-22 10:06 ` [PATCH 01/14] nvmem: sprd: Fix return value of sprd_efuse_probe() Srinivas Kandagatla
@ 2020-07-22 10:06 ` Srinivas Kandagatla
  2020-07-22 10:06 ` [PATCH 03/14] nvmem: Enforce nvmem stride in the sysfs interface Srinivas Kandagatla
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-kernel, Tiezhu Yang, Srinivas Kandagatla

From: Tiezhu Yang <yangtiezhu@loongson.cn>

There is no git tree for NVMEM FRAMEWORK in MAINTAINERS, it is not
convinent to rebase, add it.

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 68f21d46614c..83078661cd2b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12260,6 +12260,7 @@ F:	drivers/nvme/target/
 NVMEM FRAMEWORK
 M:	Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 S:	Maintained
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/srini/nvmem.git
 F:	Documentation/ABI/stable/sysfs-bus-nvmem
 F:	Documentation/devicetree/bindings/nvmem/
 F:	drivers/nvmem/
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 03/14] nvmem: Enforce nvmem stride in the sysfs interface
  2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
  2020-07-22 10:06 ` [PATCH 01/14] nvmem: sprd: Fix return value of sprd_efuse_probe() Srinivas Kandagatla
  2020-07-22 10:06 ` [PATCH 02/14] MAINTAINERS: Add git tree for NVMEM FRAMEWORK Srinivas Kandagatla
@ 2020-07-22 10:06 ` Srinivas Kandagatla
  2020-07-22 10:06 ` [PATCH 04/14] nvmem: sc27xx: add sc2730 efuse support Srinivas Kandagatla
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:06 UTC (permalink / raw)
  To: gregkh
  Cc: linux-kernel, Douglas Anderson, Ravi Kumar Bokka, Srinivas Kandagatla

From: Douglas Anderson <dianders@chromium.org>

The 'struct nvmem_config' has a stride attribute that specifies the
needed alignment for accesses into the nvmem.  This is used in
nvmem_cell_info_to_nvmem_cell() but not in the sysfs read/write
functions.  If the alignment is important in one place it's important
everywhere, so let's add enforcement.

For now we'll consider it totally invalid to access with the wrong
alignment.  We could relax this in the read case where we could just
read some extra bytes and throw them away.  Relaxing it in the write
case seems harder (and less safe?) since we'd have to read some data
first and then write it back.  To keep it symmetric we'll just
disallow it in both cases.

Reported-by: Ravi Kumar Bokka <rbokka@codeaurora.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Ravi Kumar Bokka <rbokka@codeaurora.org>
Tested-by: Ravi Kumar Bokka <rbokka@codeaurora.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/nvmem/core.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 927eb5f6003f..fc480d636be2 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -135,6 +135,9 @@ static ssize_t bin_attr_nvmem_read(struct file *filp, struct kobject *kobj,
 	if (pos >= nvmem->size)
 		return 0;
 
+	if (!IS_ALIGNED(pos, nvmem->stride))
+		return -EINVAL;
+
 	if (count < nvmem->word_size)
 		return -EINVAL;
 
@@ -172,6 +175,9 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
 	if (pos >= nvmem->size)
 		return -EFBIG;
 
+	if (!IS_ALIGNED(pos, nvmem->stride))
+		return -EINVAL;
+
 	if (count < nvmem->word_size)
 		return -EINVAL;
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 04/14] nvmem: sc27xx: add sc2730 efuse support
  2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
                   ` (2 preceding siblings ...)
  2020-07-22 10:06 ` [PATCH 03/14] nvmem: Enforce nvmem stride in the sysfs interface Srinivas Kandagatla
@ 2020-07-22 10:06 ` Srinivas Kandagatla
  2020-07-22 10:06 ` [PATCH 05/14] nvmem: core: Grammar fixes for help text Srinivas Kandagatla
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:06 UTC (permalink / raw)
  To: gregkh
  Cc: linux-kernel, Freeman Liu, Chunyan Zhang, Baolin Wang,
	Srinivas Kandagatla

From: Freeman Liu <freeman.liu@unisoc.com>

Add support to the new efuse IP which is integrated in the SC2730
which includes multiple blocks in a single chip.

Signed-off-by: Freeman Liu <freeman.liu@unisoc.com>
Signed-off-by: Chunyan Zhang <chunyan.zhang@unisoc.com>
Reviewed-by: Baolin Wang <baolin.wang7@gmail.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/nvmem/sc27xx-efuse.c | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/nvmem/sc27xx-efuse.c b/drivers/nvmem/sc27xx-efuse.c
index ab5e7e0bc3d8..c825fc902d10 100644
--- a/drivers/nvmem/sc27xx-efuse.c
+++ b/drivers/nvmem/sc27xx-efuse.c
@@ -4,12 +4,14 @@
 #include <linux/hwspinlock.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/nvmem-provider.h>
 
 /* PMIC global registers definition */
 #define SC27XX_MODULE_EN		0xc08
+#define SC2730_MODULE_EN		0x1808
 #define SC27XX_EFUSE_EN			BIT(6)
 
 /* Efuse controller registers definition */
@@ -49,12 +51,29 @@
 #define SC27XX_EFUSE_POLL_TIMEOUT	3000000
 #define SC27XX_EFUSE_POLL_DELAY_US	10000
 
+/*
+ * Since different PMICs of SC27xx series can have different
+ * address , we should save address in the device data structure.
+ */
+struct sc27xx_efuse_variant_data {
+	u32 module_en;
+};
+
 struct sc27xx_efuse {
 	struct device *dev;
 	struct regmap *regmap;
 	struct hwspinlock *hwlock;
 	struct mutex mutex;
 	u32 base;
+	const struct sc27xx_efuse_variant_data *var_data;
+};
+
+static const struct sc27xx_efuse_variant_data sc2731_edata = {
+	.module_en = SC27XX_MODULE_EN,
+};
+
+static const struct sc27xx_efuse_variant_data sc2730_edata = {
+	.module_en = SC2730_MODULE_EN,
 };
 
 /*
@@ -119,7 +138,7 @@ static int sc27xx_efuse_read(void *context, u32 offset, void *val, size_t bytes)
 		return ret;
 
 	/* Enable the efuse controller. */
-	ret = regmap_update_bits(efuse->regmap, SC27XX_MODULE_EN,
+	ret = regmap_update_bits(efuse->regmap, efuse->var_data->module_en,
 				 SC27XX_EFUSE_EN, SC27XX_EFUSE_EN);
 	if (ret)
 		goto unlock_efuse;
@@ -169,7 +188,7 @@ static int sc27xx_efuse_read(void *context, u32 offset, void *val, size_t bytes)
 
 disable_efuse:
 	/* Disable the efuse controller after reading. */
-	regmap_update_bits(efuse->regmap, SC27XX_MODULE_EN, SC27XX_EFUSE_EN, 0);
+	regmap_update_bits(efuse->regmap, efuse->var_data->module_en, SC27XX_EFUSE_EN, 0);
 unlock_efuse:
 	sc27xx_efuse_unlock(efuse);
 
@@ -219,6 +238,7 @@ static int sc27xx_efuse_probe(struct platform_device *pdev)
 
 	mutex_init(&efuse->mutex);
 	efuse->dev = &pdev->dev;
+	efuse->var_data = of_device_get_match_data(&pdev->dev);
 
 	econfig.stride = 1;
 	econfig.word_size = 1;
@@ -238,7 +258,8 @@ static int sc27xx_efuse_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id sc27xx_efuse_of_match[] = {
-	{ .compatible = "sprd,sc2731-efuse" },
+	{ .compatible = "sprd,sc2731-efuse", .data = &sc2731_edata},
+	{ .compatible = "sprd,sc2730-efuse", .data = &sc2730_edata},
 	{ }
 };
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 05/14] nvmem: core: Grammar fixes for help text
  2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
                   ` (3 preceding siblings ...)
  2020-07-22 10:06 ` [PATCH 04/14] nvmem: sc27xx: add sc2730 efuse support Srinivas Kandagatla
@ 2020-07-22 10:06 ` Srinivas Kandagatla
  2020-07-22 10:06 ` [PATCH 06/14] nvmem: core: Add nvmem_cell_read_u8() Srinivas Kandagatla
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-kernel, Andreas Färber, Srinivas Kandagatla

From: Andreas Färber <afaerber@suse.de>

It's "an unsigned" but "a U".
Similarly, "an entry" but "a binary entry".

While at it, also drop superfluous articles for negative and zero.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/nvmem/core.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index fc480d636be2..95bed31391cd 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -573,7 +573,7 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
 
 /**
  * nvmem_register() - Register a nvmem device for given nvmem_config.
- * Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
+ * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
  *
  * @config: nvmem device configuration with which nvmem device is created.
  *
@@ -728,7 +728,7 @@ static void devm_nvmem_release(struct device *dev, void *res)
 /**
  * devm_nvmem_register() - Register a managed nvmem device for given
  * nvmem_config.
- * Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
+ * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
  *
  * @dev: Device that uses the nvmem device.
  * @config: nvmem device configuration with which nvmem device is created.
@@ -772,7 +772,7 @@ static int devm_nvmem_match(struct device *dev, void *res, void *data)
  * @dev: Device that uses the nvmem device.
  * @nvmem: Pointer to previously registered nvmem device.
  *
- * Return: Will be an negative on error or a zero on success.
+ * Return: Will be negative on error or zero on success.
  */
 int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem)
 {
@@ -1375,7 +1375,7 @@ static int nvmem_cell_read_common(struct device *dev, const char *cell_id,
 }
 
 /**
- * nvmem_cell_read_u16() - Read a cell value as an u16
+ * nvmem_cell_read_u16() - Read a cell value as a u16
  *
  * @dev: Device that requests the nvmem cell.
  * @cell_id: Name of nvmem cell to read.
@@ -1390,7 +1390,7 @@ int nvmem_cell_read_u16(struct device *dev, const char *cell_id, u16 *val)
 EXPORT_SYMBOL_GPL(nvmem_cell_read_u16);
 
 /**
- * nvmem_cell_read_u32() - Read a cell value as an u32
+ * nvmem_cell_read_u32() - Read a cell value as a u32
  *
  * @dev: Device that requests the nvmem cell.
  * @cell_id: Name of nvmem cell to read.
@@ -1405,7 +1405,7 @@ int nvmem_cell_read_u32(struct device *dev, const char *cell_id, u32 *val)
 EXPORT_SYMBOL_GPL(nvmem_cell_read_u32);
 
 /**
- * nvmem_cell_read_u64() - Read a cell value as an u64
+ * nvmem_cell_read_u64() - Read a cell value as a u64
  *
  * @dev: Device that requests the nvmem cell.
  * @cell_id: Name of nvmem cell to read.
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 06/14] nvmem: core: Add nvmem_cell_read_u8()
  2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
                   ` (4 preceding siblings ...)
  2020-07-22 10:06 ` [PATCH 05/14] nvmem: core: Grammar fixes for help text Srinivas Kandagatla
@ 2020-07-22 10:06 ` Srinivas Kandagatla
  2020-07-22 10:06 ` [PATCH 07/14] nvmem: core: add support to auto devid Srinivas Kandagatla
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-kernel, Andreas Färber, Srinivas Kandagatla

From: Andreas Färber <afaerber@suse.de>

Complement the u16, u32 and u64 helpers with a u8 variant to ease
accessing byte-sized values.

This helper will be useful for Realtek Digital Home Center platforms,
which store some byte and sub-byte sized values in non-volatile memory.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/nvmem/core.c           | 15 +++++++++++++++
 include/linux/nvmem-consumer.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 95bed31391cd..d6bacc878500 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1374,6 +1374,21 @@ static int nvmem_cell_read_common(struct device *dev, const char *cell_id,
 	return 0;
 }
 
+/**
+ * nvmem_cell_read_u8() - Read a cell value as a u8
+ *
+ * @dev: Device that requests the nvmem cell.
+ * @cell_id: Name of nvmem cell to read.
+ * @val: pointer to output value.
+ *
+ * Return: 0 on success or negative errno.
+ */
+int nvmem_cell_read_u8(struct device *dev, const char *cell_id, u8 *val)
+{
+	return nvmem_cell_read_common(dev, cell_id, val, sizeof(*val));
+}
+EXPORT_SYMBOL_GPL(nvmem_cell_read_u8);
+
 /**
  * nvmem_cell_read_u16() - Read a cell value as a u16
  *
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 1b311d27c9b8..052293f4cbdb 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -61,6 +61,7 @@ void nvmem_cell_put(struct nvmem_cell *cell);
 void devm_nvmem_cell_put(struct device *dev, struct nvmem_cell *cell);
 void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len);
 int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len);
+int nvmem_cell_read_u8(struct device *dev, const char *cell_id, u8 *val);
 int nvmem_cell_read_u16(struct device *dev, const char *cell_id, u16 *val);
 int nvmem_cell_read_u32(struct device *dev, const char *cell_id, u32 *val);
 int nvmem_cell_read_u64(struct device *dev, const char *cell_id, u64 *val);
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 07/14] nvmem: core: add support to auto devid
  2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
                   ` (5 preceding siblings ...)
  2020-07-22 10:06 ` [PATCH 06/14] nvmem: core: Add nvmem_cell_read_u8() Srinivas Kandagatla
@ 2020-07-22 10:06 ` Srinivas Kandagatla
  2020-07-22 10:06 ` [PATCH 08/14] nvmem: qfprom: use NVMEM_DEVID_AUTO for multiple instances Srinivas Kandagatla
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-kernel, Srinivas Kandagatla, Shawn Guo

For nvmem providers which have multiple instances, it is required
to suffix the provider name with proper id, so that they do not
confict for the same name. Currently the core does not handle
this case properly eventhough core already has logic to generate the id.

This patch add new devid type NVMEM_DEVID_AUTO for providers to be
able to allow core to assign id and append it to provier name.

Reported-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
---
 drivers/nvmem/core.c           | 10 ++++++++--
 include/linux/nvmem-provider.h |  3 +++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index d6bacc878500..6cd3edb2eaf6 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -635,12 +635,18 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	if (!config->no_of_node)
 		nvmem->dev.of_node = config->dev->of_node;
 
-	if (config->id == -1 && config->name) {
+	switch (config->id) {
+	case NVMEM_DEVID_NONE:
 		dev_set_name(&nvmem->dev, "%s", config->name);
-	} else {
+		break;
+	case NVMEM_DEVID_AUTO:
+		dev_set_name(&nvmem->dev, "%s%d", config->name, nvmem->id);
+		break;
+	default:
 		dev_set_name(&nvmem->dev, "%s%d",
 			     config->name ? : "nvmem",
 			     config->name ? config->id : nvmem->id);
+		break;
 	}
 
 	nvmem->read_only = device_property_present(config->dev, "read-only") ||
diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
index 6d6f8e5d24c9..06409a6c40bc 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -27,6 +27,9 @@ enum nvmem_type {
 	NVMEM_TYPE_BATTERY_BACKED,
 };
 
+#define NVMEM_DEVID_NONE	(-1)
+#define NVMEM_DEVID_AUTO	(-2)
+
 /**
  * struct nvmem_config - NVMEM device configuration
  *
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 08/14] nvmem: qfprom: use NVMEM_DEVID_AUTO for multiple instances
  2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
                   ` (6 preceding siblings ...)
  2020-07-22 10:06 ` [PATCH 07/14] nvmem: core: add support to auto devid Srinivas Kandagatla
@ 2020-07-22 10:06 ` Srinivas Kandagatla
  2020-07-22 10:07 ` [PATCH 09/14] dt-bindings: nvmem: qfprom: Convert to yaml Srinivas Kandagatla
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:06 UTC (permalink / raw)
  To: gregkh; +Cc: linux-kernel, Srinivas Kandagatla, Shawn Guo

There could be multiple qfprom devices on some SoCs.  For example, on
MSM8939, qfprom@58000 holds efuse bits for Core Power Reduction (CPR),
and qfprom@5c000 holds bits for TSENS.  Registering multiple nvmem
devices with the same id results in the following failure on the second
device.

[    1.682731] sysfs: cannot create duplicate filename /bus/nvmem/devices/qfprom0
[    1.685889] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.107-00567-g11c887ce2838-dirty #334
[    1.693191] Hardware name: Square, Inc. T2 Devkit (DT)
[    1.701610] Call trace:
[    1.706673]  dump_backtrace+0x0/0x158
[    1.708987]  show_stack+0x14/0x20
[    1.712810]  dump_stack+0x98/0xbc
[    1.716114]  sysfs_warn_dup+0x60/0x78
[    1.719401]  sysfs_do_create_link_sd.isra.0+0xdc/0xe8
[    1.723047]  sysfs_create_link+0x20/0x40
[    1.728088]  bus_add_device+0x68/0x130
[    1.732083]  device_add+0x3f8/0x628
[    1.735639]  nvmem_register.part.4+0x150/0x348
[    1.739018]  devm_nvmem_register+0x4c/0xa8
[    1.743532]  qfprom_probe+0x94/0xb8
[    1.747615]  platform_drv_probe+0x50/0xa0
[    1.750998]  really_probe+0x1b8/0x298
[    1.755164]  driver_probe_device+0x58/0x100
[    1.758810]  __driver_attach+0xe0/0xe8
[    1.762802]  bus_for_each_dev+0x74/0xc8
[    1.766622]  driver_attach+0x20/0x28
[    1.770354]  bus_add_driver+0x1ac/0x218
[    1.774175]  driver_register+0x60/0x110
[    1.777734]  __platform_driver_register+0x40/0x48
[    1.781570]  qfprom_driver_init+0x18/0x20
[    1.786416]  do_one_initcall+0x5c/0x178
[    1.790418]  kernel_init_freeable+0x198/0x244
[    1.794062]  kernel_init+0x10/0x108
[    1.798567]  ret_from_fork+0x10/0x18
[    1.802084] qcom,qfprom: probe of 5c000.qfprom failed with error -17

Fix this issue by using NVMEM_DEVID_AUTO.

Reported-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
---
 drivers/nvmem/qfprom.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c
index 8a91717600be..8b425f8d847d 100644
--- a/drivers/nvmem/qfprom.c
+++ b/drivers/nvmem/qfprom.c
@@ -31,6 +31,7 @@ static struct nvmem_config econfig = {
 	.name = "qfprom",
 	.stride = 1,
 	.word_size = 1,
+	.id = NVMEM_DEVID_AUTO,
 	.reg_read = qfprom_reg_read,
 };
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 09/14] dt-bindings: nvmem: qfprom: Convert to yaml
  2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
                   ` (7 preceding siblings ...)
  2020-07-22 10:06 ` [PATCH 08/14] nvmem: qfprom: use NVMEM_DEVID_AUTO for multiple instances Srinivas Kandagatla
@ 2020-07-22 10:07 ` Srinivas Kandagatla
  2020-07-22 10:07 ` [PATCH 10/14] dt-bindings: nvmem: Add properties needed for blowing fuses Srinivas Kandagatla
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:07 UTC (permalink / raw)
  To: gregkh
  Cc: linux-kernel, Ravi Kumar Bokka, Douglas Anderson, Rob Herring,
	Srinivas Kandagatla

From: Ravi Kumar Bokka <rbokka@codeaurora.org>

This switches the bindings over from txt to yaml.

Signed-off-by: Ravi Kumar Bokka <rbokka@codeaurora.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 .../bindings/nvmem/qcom,qfprom.yaml           | 50 +++++++++++++++++++
 .../devicetree/bindings/nvmem/qfprom.txt      | 35 -------------
 2 files changed, 50 insertions(+), 35 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
 delete mode 100644 Documentation/devicetree/bindings/nvmem/qfprom.txt

diff --git a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
new file mode 100644
index 000000000000..39f97c1c83a4
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/qcom,qfprom.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies Inc, QFPROM Efuse bindings
+
+maintainers:
+  - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+
+allOf:
+  - $ref: "nvmem.yaml#"
+
+properties:
+  compatible:
+    const: qcom,qfprom
+
+  reg:
+    items:
+      - description: The corrected region.
+
+  # Needed if any child nodes are present.
+  "#address-cells":
+    const: 1
+  "#size-cells":
+    const: 1
+
+required:
+   - compatible
+   - reg
+
+examples:
+  - |
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      efuse@784000 {
+        compatible = "qcom,qfprom";
+        reg = <0 0x00784000 0 0x8ff>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        hstx-trim-primary@1eb {
+          reg = <0x1eb 0x1>;
+          bits = <1 4>;
+        };
+      };
+    };
diff --git a/Documentation/devicetree/bindings/nvmem/qfprom.txt b/Documentation/devicetree/bindings/nvmem/qfprom.txt
deleted file mode 100644
index 26fe878d5c86..000000000000
--- a/Documentation/devicetree/bindings/nvmem/qfprom.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-= Qualcomm QFPROM device tree bindings =
-
-This binding is intended to represent QFPROM which is found in most QCOM SOCs.
-
-Required properties:
-- compatible: should be "qcom,qfprom"
-- reg: Should contain registers location and length
-
-= Data cells =
-Are child nodes of qfprom, bindings of which as described in
-bindings/nvmem/nvmem.txt
-
-Example:
-
-	qfprom: qfprom@700000 {
-		compatible 	= "qcom,qfprom";
-		reg		= <0x00700000 0x8000>;
-		...
-		/* Data cells */
-		tsens_calibration: calib@404 {
-			reg = <0x4404 0x10>;
-		};
-	};
-
-
-= Data consumers =
-Are device nodes which consume nvmem data cells.
-
-For example:
-
-	tsens {
-		...
-		nvmem-cells = <&tsens_calibration>;
-		nvmem-cell-names = "calibration";
-	};
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 10/14] dt-bindings: nvmem: Add properties needed for blowing fuses
  2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
                   ` (8 preceding siblings ...)
  2020-07-22 10:07 ` [PATCH 09/14] dt-bindings: nvmem: qfprom: Convert to yaml Srinivas Kandagatla
@ 2020-07-22 10:07 ` Srinivas Kandagatla
  2020-07-22 10:07 ` [PATCH 11/14] nvmem: qfprom: Add fuse blowing support Srinivas Kandagatla
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:07 UTC (permalink / raw)
  To: gregkh
  Cc: linux-kernel, Ravi Kumar Bokka, Douglas Anderson, Rob Herring,
	Srinivas Kandagatla

From: Ravi Kumar Bokka <rbokka@codeaurora.org>

On some systems it's possible to actually blow the fuses in the qfprom
from the kernel.  Add properties to support that.

NOTE: Whether this is possible depends on the BIOS settings and
whether the kernel has permissions here, so not all boards will be
able to blow fuses in the kernel.

Signed-off-by: Ravi Kumar Bokka <rbokka@codeaurora.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 .../bindings/nvmem/qcom,qfprom.yaml           | 50 ++++++++++++++++++-
 1 file changed, 48 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
index 39f97c1c83a4..d10a0cf91ba7 100644
--- a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
+++ b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
@@ -17,8 +17,27 @@ properties:
     const: qcom,qfprom
 
   reg:
-    items:
-      - description: The corrected region.
+    # If the QFPROM is read-only OS image then only the corrected region
+    # needs to be provided.  If the QFPROM is writable then all 4 regions
+    # must be provided.
+    oneOf:
+      - items:
+          - description: The corrected region.
+      - items:
+          - description: The corrected region.
+          - description: The raw region.
+          - description: The config region.
+          - description: The security control region.
+
+  # Clock must be provided if QFPROM is writable from the OS image.
+  clocks:
+    maxItems: 1
+  clock-names:
+    const: core
+
+  # Supply reference must be provided if QFPROM is writable from the OS image.
+  vcc-supply:
+    description: Our power supply.
 
   # Needed if any child nodes are present.
   "#address-cells":
@@ -31,6 +50,33 @@ required:
    - reg
 
 examples:
+  - |
+    #include <dt-bindings/clock/qcom,gcc-sc7180.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      efuse@784000 {
+        compatible = "qcom,qfprom";
+        reg = <0 0x00784000 0 0x8ff>,
+              <0 0x00780000 0 0x7a0>,
+              <0 0x00782000 0 0x100>,
+              <0 0x00786000 0 0x1fff>;
+        clocks = <&gcc GCC_SEC_CTRL_CLK_SRC>;
+        clock-names = "core";
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        vcc-supply = <&vreg_l11a_1p8>;
+
+        hstx-trim-primary@25b {
+          reg = <0x25b 0x1>;
+          bits = <1 3>;
+        };
+      };
+    };
+
   - |
     soc {
       #address-cells = <2>;
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 11/14] nvmem: qfprom: Add fuse blowing support
  2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
                   ` (9 preceding siblings ...)
  2020-07-22 10:07 ` [PATCH 10/14] dt-bindings: nvmem: Add properties needed for blowing fuses Srinivas Kandagatla
@ 2020-07-22 10:07 ` Srinivas Kandagatla
  2020-07-22 10:07 ` [PATCH 12/14] nvmem: update Kconfig description Srinivas Kandagatla
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:07 UTC (permalink / raw)
  To: gregkh
  Cc: linux-kernel, Ravi Kumar Bokka, Douglas Anderson, Srinivas Kandagatla

From: Ravi Kumar Bokka <rbokka@codeaurora.org>

This patch adds support for blowing fuses to the qfprom driver if the
required properties are defined in the device tree.

[Srini: Fixed merge conflict with AUTO ID]
Signed-off-by: Ravi Kumar Bokka <rbokka@codeaurora.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/nvmem/qfprom.c | 316 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 304 insertions(+), 12 deletions(-)

diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c
index 8b425f8d847d..5e9e60e2e591 100644
--- a/drivers/nvmem/qfprom.c
+++ b/drivers/nvmem/qfprom.c
@@ -3,58 +3,350 @@
  * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
  */
 
+#include <linux/clk.h>
 #include <linux/device.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
-#include <linux/io.h>
 #include <linux/nvmem-provider.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+/* Blow timer clock frequency in Mhz */
+#define QFPROM_BLOW_TIMER_OFFSET 0x03c
+
+/* Amount of time required to hold charge to blow fuse in micro-seconds */
+#define QFPROM_FUSE_BLOW_POLL_US	100
+#define QFPROM_FUSE_BLOW_TIMEOUT_US	1000
+
+#define QFPROM_BLOW_STATUS_OFFSET	0x048
+#define QFPROM_BLOW_STATUS_BUSY		0x1
+#define QFPROM_BLOW_STATUS_READY	0x0
+
+#define QFPROM_ACCEL_OFFSET		0x044
+
+#define QFPROM_VERSION_OFFSET		0x0
+#define QFPROM_MAJOR_VERSION_SHIFT	28
+#define QFPROM_MAJOR_VERSION_MASK	GENMASK(31, QFPROM_MAJOR_VERSION_SHIFT)
+#define QFPROM_MINOR_VERSION_SHIFT	16
+#define QFPROM_MINOR_VERSION_MASK	GENMASK(27, QFPROM_MINOR_VERSION_SHIFT)
+
+static bool read_raw_data;
+module_param(read_raw_data, bool, 0644);
+MODULE_PARM_DESC(read_raw_data, "Read raw instead of corrected data");
 
+/**
+ * struct qfprom_soc_data - config that varies from SoC to SoC.
+ *
+ * @accel_value:             Should contain qfprom accel value.
+ * @qfprom_blow_timer_value: The timer value of qfprom when doing efuse blow.
+ * @qfprom_blow_set_freq:    The frequency required to set when we start the
+ *                           fuse blowing.
+ */
+struct qfprom_soc_data {
+	u32 accel_value;
+	u32 qfprom_blow_timer_value;
+	u32 qfprom_blow_set_freq;
+};
+
+/**
+ * struct qfprom_priv - structure holding qfprom attributes
+ *
+ * @qfpraw:       iomapped memory space for qfprom-efuse raw address space.
+ * @qfpconf:      iomapped memory space for qfprom-efuse configuration address
+ *                space.
+ * @qfpcorrected: iomapped memory space for qfprom corrected address space.
+ * @qfpsecurity:  iomapped memory space for qfprom security control space.
+ * @dev:          qfprom device structure.
+ * @secclk:       Clock supply.
+ * @vcc:          Regulator supply.
+ * @soc_data:     Data that for things that varies from SoC to SoC.
+ */
 struct qfprom_priv {
-	void __iomem *base;
+	void __iomem *qfpraw;
+	void __iomem *qfpconf;
+	void __iomem *qfpcorrected;
+	void __iomem *qfpsecurity;
+	struct device *dev;
+	struct clk *secclk;
+	struct regulator *vcc;
+	const struct qfprom_soc_data *soc_data;
+};
+
+/**
+ * struct qfprom_touched_values - saved values to restore after blowing
+ *
+ * @clk_rate: The rate the clock was at before blowing.
+ * @accel_val: The value of the accel reg before blowing.
+ * @timer_val: The value of the timer before blowing.
+ */
+struct qfprom_touched_values {
+	unsigned long clk_rate;
+	u32 accel_val;
+	u32 timer_val;
 };
 
+/**
+ * qfprom_disable_fuse_blowing() - Undo enabling of fuse blowing.
+ * @priv: Our driver data.
+ * @old:  The data that was stashed from before fuse blowing.
+ *
+ * Resets the value of the blow timer, accel register and the clock
+ * and voltage settings.
+ *
+ * Prints messages if there are errors but doesn't return an error code
+ * since there's not much we can do upon failure.
+ */
+static void qfprom_disable_fuse_blowing(const struct qfprom_priv *priv,
+					const struct qfprom_touched_values *old)
+{
+	int ret;
+
+	ret = regulator_disable(priv->vcc);
+	if (ret)
+		dev_warn(priv->dev, "Failed to disable regulator (ignoring)\n");
+
+	ret = clk_set_rate(priv->secclk, old->clk_rate);
+	if (ret)
+		dev_warn(priv->dev,
+			 "Failed to set clock rate for disable (ignoring)\n");
+
+	clk_disable_unprepare(priv->secclk);
+
+	writel(old->timer_val, priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
+	writel(old->accel_val, priv->qfpconf + QFPROM_ACCEL_OFFSET);
+}
+
+/**
+ * qfprom_enable_fuse_blowing() - Enable fuse blowing.
+ * @priv: Our driver data.
+ * @old:  We'll stash stuff here to use when disabling.
+ *
+ * Sets the value of the blow timer, accel register and the clock
+ * and voltage settings.
+ *
+ * Prints messages if there are errors so caller doesn't need to.
+ *
+ * Return: 0 or -err.
+ */
+static int qfprom_enable_fuse_blowing(const struct qfprom_priv *priv,
+				      struct qfprom_touched_values *old)
+{
+	int ret;
+
+	ret = clk_prepare_enable(priv->secclk);
+	if (ret) {
+		dev_err(priv->dev, "Failed to enable clock\n");
+		return ret;
+	}
+
+	old->clk_rate = clk_get_rate(priv->secclk);
+	ret = clk_set_rate(priv->secclk, priv->soc_data->qfprom_blow_set_freq);
+	if (ret) {
+		dev_err(priv->dev, "Failed to set clock rate for enable\n");
+		goto err_clk_prepared;
+	}
+
+	ret = regulator_enable(priv->vcc);
+	if (ret) {
+		dev_err(priv->dev, "Failed to enable regulator\n");
+		goto err_clk_rate_set;
+	}
+
+	old->timer_val = readl(priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
+	old->accel_val = readl(priv->qfpconf + QFPROM_ACCEL_OFFSET);
+	writel(priv->soc_data->qfprom_blow_timer_value,
+	       priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
+	writel(priv->soc_data->accel_value,
+	       priv->qfpconf + QFPROM_ACCEL_OFFSET);
+
+	return 0;
+
+err_clk_rate_set:
+	clk_set_rate(priv->secclk, old->clk_rate);
+err_clk_prepared:
+	clk_disable_unprepare(priv->secclk);
+	return ret;
+}
+
+/**
+ * qfprom_efuse_reg_write() - Write to fuses.
+ * @context: Our driver data.
+ * @reg:     The offset to write at.
+ * @_val:    Pointer to data to write.
+ * @bytes:   The number of bytes to write.
+ *
+ * Writes to fuses.  WARNING: THIS IS PERMANENT.
+ *
+ * Return: 0 or -err.
+ */
+static int qfprom_reg_write(void *context, unsigned int reg, void *_val,
+			    size_t bytes)
+{
+	struct qfprom_priv *priv = context;
+	struct qfprom_touched_values old;
+	int words = bytes / 4;
+	u32 *value = _val;
+	u32 blow_status;
+	int ret;
+	int i;
+
+	dev_dbg(priv->dev,
+		"Writing to raw qfprom region : %#010x of size: %zu\n",
+		reg, bytes);
+
+	/*
+	 * The hardware only allows us to write word at a time, but we can
+	 * read byte at a time.  Until the nvmem framework allows a separate
+	 * word_size and stride for reading vs. writing, we'll enforce here.
+	 */
+	if (bytes % 4) {
+		dev_err(priv->dev,
+			"%zu is not an integral number of words\n", bytes);
+		return -EINVAL;
+	}
+	if (reg % 4) {
+		dev_err(priv->dev,
+			"Invalid offset: %#x.  Must be word aligned\n", reg);
+		return -EINVAL;
+	}
+
+	ret = qfprom_enable_fuse_blowing(priv, &old);
+	if (ret)
+		return ret;
+
+	ret = readl_relaxed_poll_timeout(
+		priv->qfpconf + QFPROM_BLOW_STATUS_OFFSET,
+		blow_status, blow_status == QFPROM_BLOW_STATUS_READY,
+		QFPROM_FUSE_BLOW_POLL_US, QFPROM_FUSE_BLOW_TIMEOUT_US);
+
+	if (ret) {
+		dev_err(priv->dev,
+			"Timeout waiting for initial ready; aborting.\n");
+		goto exit_enabled_fuse_blowing;
+	}
+
+	for (i = 0; i < words; i++)
+		writel(value[i], priv->qfpraw + reg + (i * 4));
+
+	ret = readl_relaxed_poll_timeout(
+		priv->qfpconf + QFPROM_BLOW_STATUS_OFFSET,
+		blow_status, blow_status == QFPROM_BLOW_STATUS_READY,
+		QFPROM_FUSE_BLOW_POLL_US, QFPROM_FUSE_BLOW_TIMEOUT_US);
+
+	/* Give an error, but not much we can do in this case */
+	if (ret)
+		dev_err(priv->dev, "Timeout waiting for finish.\n");
+
+exit_enabled_fuse_blowing:
+	qfprom_disable_fuse_blowing(priv, &old);
+
+	return ret;
+}
+
 static int qfprom_reg_read(void *context,
 			unsigned int reg, void *_val, size_t bytes)
 {
 	struct qfprom_priv *priv = context;
 	u8 *val = _val;
 	int i = 0, words = bytes;
+	void __iomem *base = priv->qfpcorrected;
+
+	if (read_raw_data && priv->qfpraw)
+		base = priv->qfpraw;
 
 	while (words--)
-		*val++ = readb(priv->base + reg + i++);
+		*val++ = readb(base + reg + i++);
 
 	return 0;
 }
 
-static struct nvmem_config econfig = {
-	.name = "qfprom",
-	.stride = 1,
-	.word_size = 1,
-	.id = NVMEM_DEVID_AUTO,
-	.reg_read = qfprom_reg_read,
+static const struct qfprom_soc_data qfprom_7_8_data = {
+	.accel_value = 0xD10,
+	.qfprom_blow_timer_value = 25,
+	.qfprom_blow_set_freq = 4800000,
 };
 
 static int qfprom_probe(struct platform_device *pdev)
 {
+	struct nvmem_config econfig = {
+		.name = "qfprom",
+		.stride = 1,
+		.word_size = 1,
+		.id = NVMEM_DEVID_AUTO,
+		.reg_read = qfprom_reg_read,
+	};
 	struct device *dev = &pdev->dev;
 	struct resource *res;
 	struct nvmem_device *nvmem;
 	struct qfprom_priv *priv;
+	int ret;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
+	/* The corrected section is always provided */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(priv->base))
-		return PTR_ERR(priv->base);
+	priv->qfpcorrected = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->qfpcorrected))
+		return PTR_ERR(priv->qfpcorrected);
 
 	econfig.size = resource_size(res);
 	econfig.dev = dev;
 	econfig.priv = priv;
 
+	priv->dev = dev;
+
+	/*
+	 * If more than one region is provided then the OS has the ability
+	 * to write.
+	 */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (res) {
+		u32 version;
+		int major_version, minor_version;
+
+		priv->qfpraw = devm_ioremap_resource(dev, res);
+		if (IS_ERR(priv->qfpraw))
+			return PTR_ERR(priv->qfpraw);
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+		priv->qfpconf = devm_ioremap_resource(dev, res);
+		if (IS_ERR(priv->qfpconf))
+			return PTR_ERR(priv->qfpconf);
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+		priv->qfpsecurity = devm_ioremap_resource(dev, res);
+		if (IS_ERR(priv->qfpsecurity))
+			return PTR_ERR(priv->qfpsecurity);
+
+		version = readl(priv->qfpsecurity + QFPROM_VERSION_OFFSET);
+		major_version = (version & QFPROM_MAJOR_VERSION_MASK) >>
+				QFPROM_MAJOR_VERSION_SHIFT;
+		minor_version = (version & QFPROM_MINOR_VERSION_MASK) >>
+				QFPROM_MINOR_VERSION_SHIFT;
+
+		if (major_version == 7 && minor_version == 8)
+			priv->soc_data = &qfprom_7_8_data;
+
+		priv->vcc = devm_regulator_get(&pdev->dev, "vcc");
+		if (IS_ERR(priv->vcc))
+			return PTR_ERR(priv->vcc);
+
+		priv->secclk = devm_clk_get(dev, "core");
+		if (IS_ERR(priv->secclk)) {
+			ret = PTR_ERR(priv->secclk);
+			if (ret != -EPROBE_DEFER)
+				dev_err(dev, "Error getting clock: %d\n", ret);
+			return ret;
+		}
+
+		/* Only enable writing if we have SoC data. */
+		if (priv->soc_data)
+			econfig.reg_write = qfprom_reg_write;
+	}
+
 	nvmem = devm_nvmem_register(dev, &econfig);
 
 	return PTR_ERR_OR_ZERO(nvmem);
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 12/14] nvmem: update Kconfig description
  2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
                   ` (10 preceding siblings ...)
  2020-07-22 10:07 ` [PATCH 11/14] nvmem: qfprom: Add fuse blowing support Srinivas Kandagatla
@ 2020-07-22 10:07 ` Srinivas Kandagatla
  2020-07-22 10:07 ` [PATCH 13/14] dt-bindings: nvmem: SID: add binding for A100's SID controller Srinivas Kandagatla
  2020-07-22 10:07 ` [PATCH 14/14] nvmem: qcom-spmi-sdam: Enable multiple devices Srinivas Kandagatla
  13 siblings, 0 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:07 UTC (permalink / raw)
  To: gregkh; +Cc: linux-kernel, Matteo Croce, Srinivas Kandagatla

From: Matteo Croce <mcroce@microsoft.com>

nvmem can't be built as module anymore, update its Kconfig description.

Fixes: 2a37ce25d9f2 ("nvmem: disallow modular CONFIG_NVMEM")
Signed-off-by: Matteo Croce <mcroce@microsoft.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/nvmem/Kconfig | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index d7b7f6d688e7..954d3b4a52ab 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -7,9 +7,6 @@ menuconfig NVMEM
 	  This framework is designed to provide a generic interface to NVMEM
 	  from both the Linux Kernel and the userspace.
 
-	  This driver can also be built as a module. If so, the module
-	  will be called nvmem_core.
-
 	  If unsure, say no.
 
 if NVMEM
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 13/14] dt-bindings: nvmem: SID: add binding for A100's SID controller
  2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
                   ` (11 preceding siblings ...)
  2020-07-22 10:07 ` [PATCH 12/14] nvmem: update Kconfig description Srinivas Kandagatla
@ 2020-07-22 10:07 ` Srinivas Kandagatla
  2020-07-22 10:07 ` [PATCH 14/14] nvmem: qcom-spmi-sdam: Enable multiple devices Srinivas Kandagatla
  13 siblings, 0 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:07 UTC (permalink / raw)
  To: gregkh; +Cc: linux-kernel, Yangtao Li, Rob Herring, Srinivas Kandagatla

From: Yangtao Li <frank@allwinnertech.com>

Add a binding for A100's SID controller.

Signed-off-by: Yangtao Li <frank@allwinnertech.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 .../nvmem/allwinner,sun4i-a10-sid.yaml        | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/nvmem/allwinner,sun4i-a10-sid.yaml b/Documentation/devicetree/bindings/nvmem/allwinner,sun4i-a10-sid.yaml
index daf1321d76ad..6687ab720304 100644
--- a/Documentation/devicetree/bindings/nvmem/allwinner,sun4i-a10-sid.yaml
+++ b/Documentation/devicetree/bindings/nvmem/allwinner,sun4i-a10-sid.yaml
@@ -15,14 +15,17 @@ allOf:
 
 properties:
   compatible:
-    enum:
-      - allwinner,sun4i-a10-sid
-      - allwinner,sun7i-a20-sid
-      - allwinner,sun8i-a83t-sid
-      - allwinner,sun8i-h3-sid
-      - allwinner,sun50i-a64-sid
-      - allwinner,sun50i-h5-sid
-      - allwinner,sun50i-h6-sid
+    oneOf:
+      - const: allwinner,sun4i-a10-sid
+      - const: allwinner,sun7i-a20-sid
+      - const: allwinner,sun8i-a83t-sid
+      - const: allwinner,sun8i-h3-sid
+      - const: allwinner,sun50i-a64-sid
+      - items:
+          - const: allwinner,sun50i-a100-sid
+          - const: allwinner,sun50i-a64-sid
+      - const: allwinner,sun50i-h5-sid
+      - const: allwinner,sun50i-h6-sid
 
   reg:
     maxItems: 1
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 14/14] nvmem: qcom-spmi-sdam: Enable multiple devices
  2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
                   ` (12 preceding siblings ...)
  2020-07-22 10:07 ` [PATCH 13/14] dt-bindings: nvmem: SID: add binding for A100's SID controller Srinivas Kandagatla
@ 2020-07-22 10:07 ` Srinivas Kandagatla
  13 siblings, 0 replies; 15+ messages in thread
From: Srinivas Kandagatla @ 2020-07-22 10:07 UTC (permalink / raw)
  To: gregkh; +Cc: linux-kernel, Guru Das Srinagesh, Srinivas Kandagatla

From: Guru Das Srinagesh <gurus@codeaurora.org>

Using pdev->id as the nvmem's config ID (which, by default, is
NVMEM_DEVID_NONE) prevents multiple instances of this driver from
probing because of the following error:

  sysfs: cannot create duplicate filename '/bus/nvmem/devices/spmi_sdam'

Use NVMEM_DEVID_AUTO as the NVMEM config ID to fix the issue.

Signed-off-by: Guru Das Srinagesh <gurus@codeaurora.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
 drivers/nvmem/qcom-spmi-sdam.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/nvmem/qcom-spmi-sdam.c b/drivers/nvmem/qcom-spmi-sdam.c
index 8682cda448d6..a72704cd0468 100644
--- a/drivers/nvmem/qcom-spmi-sdam.c
+++ b/drivers/nvmem/qcom-spmi-sdam.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017, 2020 The Linux Foundation. All rights reserved.
  */
 
 #include <linux/device.h>
@@ -141,7 +141,7 @@ static int sdam_probe(struct platform_device *pdev)
 
 	sdam->sdam_config.dev = &pdev->dev;
 	sdam->sdam_config.name = "spmi_sdam";
-	sdam->sdam_config.id = pdev->id;
+	sdam->sdam_config.id = NVMEM_DEVID_AUTO;
 	sdam->sdam_config.owner = THIS_MODULE,
 	sdam->sdam_config.stride = 1;
 	sdam->sdam_config.word_size = 1;
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2020-07-22 10:09 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-22 10:06 [PATCH 00/14] nvmem: patches (set 1) for 5.9 Srinivas Kandagatla
2020-07-22 10:06 ` [PATCH 01/14] nvmem: sprd: Fix return value of sprd_efuse_probe() Srinivas Kandagatla
2020-07-22 10:06 ` [PATCH 02/14] MAINTAINERS: Add git tree for NVMEM FRAMEWORK Srinivas Kandagatla
2020-07-22 10:06 ` [PATCH 03/14] nvmem: Enforce nvmem stride in the sysfs interface Srinivas Kandagatla
2020-07-22 10:06 ` [PATCH 04/14] nvmem: sc27xx: add sc2730 efuse support Srinivas Kandagatla
2020-07-22 10:06 ` [PATCH 05/14] nvmem: core: Grammar fixes for help text Srinivas Kandagatla
2020-07-22 10:06 ` [PATCH 06/14] nvmem: core: Add nvmem_cell_read_u8() Srinivas Kandagatla
2020-07-22 10:06 ` [PATCH 07/14] nvmem: core: add support to auto devid Srinivas Kandagatla
2020-07-22 10:06 ` [PATCH 08/14] nvmem: qfprom: use NVMEM_DEVID_AUTO for multiple instances Srinivas Kandagatla
2020-07-22 10:07 ` [PATCH 09/14] dt-bindings: nvmem: qfprom: Convert to yaml Srinivas Kandagatla
2020-07-22 10:07 ` [PATCH 10/14] dt-bindings: nvmem: Add properties needed for blowing fuses Srinivas Kandagatla
2020-07-22 10:07 ` [PATCH 11/14] nvmem: qfprom: Add fuse blowing support Srinivas Kandagatla
2020-07-22 10:07 ` [PATCH 12/14] nvmem: update Kconfig description Srinivas Kandagatla
2020-07-22 10:07 ` [PATCH 13/14] dt-bindings: nvmem: SID: add binding for A100's SID controller Srinivas Kandagatla
2020-07-22 10:07 ` [PATCH 14/14] nvmem: qcom-spmi-sdam: Enable multiple devices Srinivas Kandagatla

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.