[U-Boot] [PATCH 2/5] pmu: stpmic1: change specific NVM api to MISC

Patrick Delaunay patrick.delaunay at st.com
Fri Jul 19 09:39:28 UTC 2019


Use MISC u-class to export the NVM register (starting at 0xF8 offset)
and avoid specific API.
- SHADOW have offset < 0.
- NVM have register > 0

Signed-off-by: Patrick Delaunay <patrick.delaunay at st.com>
---

 drivers/misc/stm32mp_fuse.c  | 44 ++++++++++++++++++--
 drivers/power/pmic/stpmic1.c | 98 +++++++++++++++++++++++++-------------------
 include/power/stpmic1.h      |  7 ----
 3 files changed, 96 insertions(+), 53 deletions(-)

diff --git a/drivers/misc/stm32mp_fuse.c b/drivers/misc/stm32mp_fuse.c
index ac33130..1850f08 100644
--- a/drivers/misc/stm32mp_fuse.c
+++ b/drivers/misc/stm32mp_fuse.c
@@ -39,8 +39,17 @@ int fuse_read(u32 bank, u32 word, u32 *val)
 
 #ifdef CONFIG_PMIC_STPMIC1
 	case STM32MP_NVM_BANK:
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_GET_DRIVER(stpmic1_nvm),
+						  &dev);
+		if (ret)
+			return ret;
 		*val = 0;
-		ret = stpmic1_shadow_read_byte(word, (u8 *)val);
+		ret = misc_read(dev, -word, val, 1);
+		if (ret != 1)
+			ret = -EINVAL;
+		else
+			ret = 0;
 		break;
 #endif /* CONFIG_PMIC_STPMIC1 */
 
@@ -75,7 +84,16 @@ int fuse_prog(u32 bank, u32 word, u32 val)
 
 #ifdef CONFIG_PMIC_STPMIC1
 	case STM32MP_NVM_BANK:
-		ret = stpmic1_nvm_write_byte(word, (u8 *)&val);
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_GET_DRIVER(stpmic1_nvm),
+						  &dev);
+		if (ret)
+			return ret;
+		ret = misc_write(dev, word, &val, 1);
+		if (ret != 1)
+			ret = -EINVAL;
+		else
+			ret = 0;
 		break;
 #endif /* CONFIG_PMIC_STPMIC1 */
 
@@ -109,8 +127,17 @@ int fuse_sense(u32 bank, u32 word, u32 *val)
 
 #ifdef CONFIG_PMIC_STPMIC1
 	case STM32MP_NVM_BANK:
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_GET_DRIVER(stpmic1_nvm),
+						  &dev);
+		if (ret)
+			return ret;
 		*val = 0;
-		ret = stpmic1_nvm_read_byte(word, (u8 *)val);
+		ret = misc_read(dev, word, val, 1);
+		if (ret != 1)
+			ret = -EINVAL;
+		else
+			ret = 0;
 		break;
 #endif /* CONFIG_PMIC_STPMIC1 */
 
@@ -145,7 +172,16 @@ int fuse_override(u32 bank, u32 word, u32 val)
 
 #ifdef CONFIG_PMIC_STPMIC1
 	case STM32MP_NVM_BANK:
-		ret = stpmic1_shadow_write_byte(word, (u8 *)&val);
+		ret = uclass_get_device_by_driver(UCLASS_MISC,
+						  DM_GET_DRIVER(stpmic1_nvm),
+						  &dev);
+		if (ret)
+			return ret;
+		ret = misc_write(dev, -word, &val, 1);
+		if (ret != 1)
+			ret = -EINVAL;
+		else
+			ret = 0;
 		break;
 #endif /* CONFIG_PMIC_STPMIC1 */
 
diff --git a/drivers/power/pmic/stpmic1.c b/drivers/power/pmic/stpmic1.c
index 65296c5..9f20c31 100644
--- a/drivers/power/pmic/stpmic1.c
+++ b/drivers/power/pmic/stpmic1.c
@@ -7,6 +7,7 @@
 #include <dm.h>
 #include <errno.h>
 #include <i2c.h>
+#include <misc.h>
 #include <sysreset.h>
 #include <dm/device.h>
 #include <dm/lists.h>
@@ -69,6 +70,7 @@ static int stpmic1_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
 
 static int stpmic1_bind(struct udevice *dev)
 {
+	int ret;
 #if CONFIG_IS_ENABLED(DM_REGULATOR)
 	ofnode regulators_node;
 	int children;
@@ -86,6 +88,13 @@ static int stpmic1_bind(struct udevice *dev)
 		dev_dbg(dev, "no child found\n");
 #endif /* DM_REGULATOR */
 
+	if (!IS_ENABLED(CONFIG_SPL_BUILD)) {
+		ret = device_bind_driver(dev, "stpmic1-nvm",
+					 "stpmic1-nvm", NULL);
+		if (ret)
+			return ret;
+	}
+
 	if (CONFIG_IS_ENABLED(SYSRESET))
 		return device_bind_driver(dev, "stpmic1-sysreset",
 					  "stpmic1-sysreset", NULL);
@@ -113,32 +122,38 @@ U_BOOT_DRIVER(pmic_stpmic1) = {
 };
 
 #ifndef CONFIG_SPL_BUILD
-static int stpmic1_nvm_rw(u8 addr, u8 *buf, int buf_len, enum pmic_nvm_op op)
+static int stpmic1_nvm_rw(struct udevice *dev, u8 addr, u8 *buf, int buf_len,
+			  enum pmic_nvm_op op)
 {
-	struct udevice *dev;
 	unsigned long timeout;
 	u8 cmd = STPMIC1_NVM_CMD_READ;
-	int ret;
-
-	ret = uclass_get_device_by_driver(UCLASS_PMIC,
-					  DM_GET_DRIVER(pmic_stpmic1), &dev);
-	if (ret)
-		/* No PMIC on power discrete board */
-		return -EOPNOTSUPP;
+	int ret, len = buf_len;
 
 	if (addr < STPMIC1_NVM_START_ADDRESS)
 		return -EACCES;
+	if (addr + buf_len > STPMIC1_NVM_START_ADDRESS + STPMIC1_NVM_SIZE)
+		len = STPMIC1_NVM_START_ADDRESS + STPMIC1_NVM_SIZE - addr;
 
-	if (op == SHADOW_READ)
-		return pmic_read(dev, addr, buf, buf_len);
+	if (op == SHADOW_READ) {
+		ret = pmic_read(dev, addr, buf, len);
+		if (ret < 0)
+			return ret;
+		else
+			return len;
+	}
 
-	if (op == SHADOW_WRITE)
-		return pmic_write(dev, addr, buf, buf_len);
+	if (op == SHADOW_WRITE) {
+		ret = pmic_write(dev, addr, buf, len);
+		if (ret < 0)
+			return ret;
+		else
+			return len;
+	}
 
 	if (op == NVM_WRITE) {
 		cmd = STPMIC1_NVM_CMD_PROGRAM;
 
-		ret = pmic_write(dev, addr, buf, buf_len);
+		ret = pmic_write(dev, addr, buf, len);
 		if (ret < 0)
 			return ret;
 	}
@@ -168,51 +183,50 @@ static int stpmic1_nvm_rw(u8 addr, u8 *buf, int buf_len, enum pmic_nvm_op op)
 		return -ETIMEDOUT;
 
 	if (op == NVM_READ) {
-		ret = pmic_read(dev, addr, buf, buf_len);
+		ret = pmic_read(dev, addr, buf, len);
 		if (ret < 0)
 			return ret;
 	}
 
-	return 0;
+	return len;
 }
 
-int stpmic1_shadow_read_byte(u8 addr, u8 *buf)
+static int stpmic1_nvm_read(struct udevice *dev, int offset,
+			    void *buf, int size)
 {
-	return stpmic1_nvm_rw(addr, buf, 1, SHADOW_READ);
-}
+	enum pmic_nvm_op op = NVM_READ;
 
-int stpmic1_shadow_write_byte(u8 addr, u8 *buf)
-{
-	return stpmic1_nvm_rw(addr, buf, 1, SHADOW_WRITE);
-}
+	if (offset < 0) {
+		op = SHADOW_READ;
+		offset = -offset;
+	}
 
-int stpmic1_nvm_read_byte(u8 addr, u8 *buf)
-{
-	return stpmic1_nvm_rw(addr, buf, 1, NVM_READ);
+	return stpmic1_nvm_rw(dev->parent, offset, buf, size, op);
 }
 
-int stpmic1_nvm_write_byte(u8 addr, u8 *buf)
+static int stpmic1_nvm_write(struct udevice *dev, int offset,
+			     const void *buf, int size)
 {
-	return stpmic1_nvm_rw(addr, buf, 1, NVM_WRITE);
-}
+	enum pmic_nvm_op op = NVM_WRITE;
 
-int stpmic1_nvm_read_all(u8 *buf, int buf_len)
-{
-	if (buf_len != STPMIC1_NVM_SIZE)
-		return -EINVAL;
+	if (offset < 0) {
+		op = SHADOW_WRITE;
+		offset = -offset;
+	}
 
-	return stpmic1_nvm_rw(STPMIC1_NVM_START_ADDRESS,
-			     buf, buf_len, NVM_READ);
+	return stpmic1_nvm_rw(dev->parent, offset, (void *)buf, size, op);
 }
 
-int stpmic1_nvm_write_all(u8 *buf, int buf_len)
-{
-	if (buf_len != STPMIC1_NVM_SIZE)
-		return -EINVAL;
+static const struct misc_ops stpmic1_nvm_ops = {
+	.read = stpmic1_nvm_read,
+	.write = stpmic1_nvm_write,
+};
 
-	return stpmic1_nvm_rw(STPMIC1_NVM_START_ADDRESS,
-			     buf, buf_len, NVM_WRITE);
-}
+U_BOOT_DRIVER(stpmic1_nvm) = {
+	.name = "stpmic1-nvm",
+	.id = UCLASS_MISC,
+	.ops = &stpmic1_nvm_ops,
+};
 #endif /* CONFIG_SPL_BUILD */
 
 #ifdef CONFIG_SYSRESET
diff --git a/include/power/stpmic1.h b/include/power/stpmic1.h
index 0e6721d..ea91b75 100644
--- a/include/power/stpmic1.h
+++ b/include/power/stpmic1.h
@@ -107,11 +107,4 @@ enum {
 	STPMIC1_PWR_SW2,
 	STPMIC1_MAX_PWR_SW,
 };
-
-int stpmic1_shadow_read_byte(u8 addr, u8 *buf);
-int stpmic1_shadow_write_byte(u8 addr, u8 *buf);
-int stpmic1_nvm_read_byte(u8 addr, u8 *buf);
-int stpmic1_nvm_write_byte(u8 addr, u8 *buf);
-int stpmic1_nvm_read_all(u8 *buf, int buf_len);
-int stpmic1_nvm_write_all(u8 *buf, int buf_len);
 #endif
-- 
2.7.4



More information about the U-Boot mailing list