[U-Boot] [PATCH v2 0/7] misc: update drivers for stm32mp1

Update the stm32mp1 drivers after the commit 8729b1ae2cbd ("misc: Update read() and write() methods to return bytes xfered") And the introduction of NOP u-class.
Changes in v2: - udpate bsec patch after rebase (use offs) - impact in added command stboard after rebase - rebase v2019.10-rc1
Patrick Delaunay (7): bsec: update after MISC u-class update pmu: stpmic1: change specific NVM api to MISC stpmic1: simplify stpmic1_sysreset_request stm32mp1: update test on misc_read result stm32mp1: update sysconf_init on misc_read result stm32mp1: board update command stboard on misc_read result misc: change RCC form MISC to NOP uclass
arch/arm/mach-stm32mp/bsec.c | 30 +++++------ board/st/stm32mp1/cmd_stboard.c | 2 +- board/st/stm32mp1/stm32mp1.c | 4 +- drivers/misc/stm32_rcc.c | 5 +- drivers/misc/stm32mp_fuse.c | 74 ++++++++++++++++++++------- drivers/power/pmic/stpmic1.c | 107 +++++++++++++++++++++------------------- include/power/stpmic1.h | 7 --- 7 files changed, 134 insertions(+), 95 deletions(-)

Since the commit 8729b1ae2cbd ("misc: Update read() and write() methods to return bytes xfered"); The misc bsec driver need to be adapted to reflect the number of transferred bytes.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: - udpate bsec patch after rebase (use offs)
arch/arm/mach-stm32mp/bsec.c | 30 ++++++++++++++++-------------- drivers/misc/stm32mp_fuse.c | 30 +++++++++++++++++------------- 2 files changed, 33 insertions(+), 27 deletions(-)
diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c index 8018366..a77c706 100644 --- a/arch/arm/mach-stm32mp/bsec.c +++ b/arch/arm/mach-stm32mp/bsec.c @@ -364,15 +364,13 @@ static int stm32mp_bsec_read(struct udevice *dev, int offset, offs -= STM32_BSEC_OTP_OFFSET; shadow = false; } - otp = offs / sizeof(u32);
- if (otp < 0 || (otp + nb_otp - 1) > BSEC_OTP_MAX_VALUE) { - dev_err(dev, "wrong value for otp, max value : %i\n", - BSEC_OTP_MAX_VALUE); + if (offs < 0 || (offs % 4) || (size % 4)) return -EINVAL; - }
- for (i = otp; i < (otp + nb_otp); i++) { + otp = offs / sizeof(u32); + + for (i = otp; i < (otp + nb_otp) && i <= BSEC_OTP_MAX_VALUE; i++) { u32 *addr = &((u32 *)buf)[i - otp];
if (shadow) @@ -383,7 +381,10 @@ static int stm32mp_bsec_read(struct udevice *dev, int offset, if (ret) break; } - return ret; + if (ret) + return ret; + else + return (i - otp) * 4; }
static int stm32mp_bsec_write(struct udevice *dev, int offset, @@ -400,15 +401,13 @@ static int stm32mp_bsec_write(struct udevice *dev, int offset, offs -= STM32_BSEC_OTP_OFFSET; shadow = false; } - otp = offs / sizeof(u32);
- if (otp < 0 || (otp + nb_otp - 1) > BSEC_OTP_MAX_VALUE) { - dev_err(dev, "wrong value for otp, max value : %d\n", - BSEC_OTP_MAX_VALUE); + if (offs < 0 || (offs % 4) || (size % 4)) return -EINVAL; - }
- for (i = otp; i < otp + nb_otp; i++) { + otp = offs / sizeof(u32); + + for (i = otp; i < otp + nb_otp && i <= BSEC_OTP_MAX_VALUE; i++) { u32 *val = &((u32 *)buf)[i - otp];
if (shadow) @@ -418,7 +417,10 @@ static int stm32mp_bsec_write(struct udevice *dev, int offset, if (ret) break; } - return ret; + if (ret) + return ret; + else + return (i - otp) * 4; }
static const struct misc_ops stm32mp_bsec_ops = { diff --git a/drivers/misc/stm32mp_fuse.c b/drivers/misc/stm32mp_fuse.c index 801d946..a1a27d1 100644 --- a/drivers/misc/stm32mp_fuse.c +++ b/drivers/misc/stm32mp_fuse.c @@ -20,7 +20,7 @@ */ int fuse_read(u32 bank, u32 word, u32 *val) { - int ret = 0; + int ret; struct udevice *dev;
switch (bank) { @@ -32,9 +32,10 @@ int fuse_read(u32 bank, u32 word, u32 *val) return ret; ret = misc_read(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET, val, 4); - if (ret < 0) - return ret; - ret = 0; + if (ret != 4) + ret = -EINVAL; + else + ret = 0; break;
#ifdef CONFIG_PMIC_STPMIC1 @@ -67,9 +68,10 @@ int fuse_prog(u32 bank, u32 word, u32 val) return ret; ret = misc_write(dev, word * 4 + STM32_BSEC_OTP_OFFSET, &val, 4); - if (ret < 0) - return ret; - ret = 0; + if (ret != 4) + ret = -EINVAL; + else + ret = 0; break;
#ifdef CONFIG_PMIC_STPMIC1 @@ -100,9 +102,10 @@ int fuse_sense(u32 bank, u32 word, u32 *val) if (ret) return ret; ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4); - if (ret < 0) - return ret; - ret = 0; + if (ret != 4) + ret = -EINVAL; + else + ret = 0; break;
#ifdef CONFIG_PMIC_STPMIC1 @@ -135,9 +138,10 @@ int fuse_override(u32 bank, u32 word, u32 val) return ret; ret = misc_write(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET, &val, 4); - if (ret < 0) - return ret; - ret = 0; + if (ret != 4) + ret = -EINVAL; + else + ret = 0; break;
#ifdef CONFIG_PMIC_STPMIC1

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@st.com ---
Changes in v2: None
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 a1a27d1..0eed345 100644 --- a/drivers/misc/stm32mp_fuse.c +++ b/drivers/misc/stm32mp_fuse.c @@ -40,8 +40,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 */
@@ -76,7 +85,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 */
@@ -110,8 +128,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 */
@@ -146,7 +173,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 c338148..509baed 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

Retrieve parent device from dev->parent instead of calling uclass_get_device_by_driver()
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: None
drivers/power/pmic/stpmic1.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/drivers/power/pmic/stpmic1.c b/drivers/power/pmic/stpmic1.c index 509baed..de31934 100644 --- a/drivers/power/pmic/stpmic1.c +++ b/drivers/power/pmic/stpmic1.c @@ -232,19 +232,12 @@ U_BOOT_DRIVER(stpmic1_nvm) = { #ifdef CONFIG_SYSRESET static int stpmic1_sysreset_request(struct udevice *dev, enum sysreset_t type) { - struct udevice *pmic_dev; + struct udevice *pmic_dev = dev->parent; int ret;
if (type != SYSRESET_POWER && type != SYSRESET_POWER_OFF) return -EPROTONOSUPPORT;
- ret = uclass_get_device_by_driver(UCLASS_PMIC, - DM_GET_DRIVER(pmic_stpmic1), - &pmic_dev); - - if (ret) - return -EOPNOTSUPP; - ret = pmic_reg_read(pmic_dev, STPMIC1_MAIN_CR); if (ret < 0) return ret;

Update the stm32mp1 baord after the commit 8729b1ae2cbd ("misc: Update read() and write() methods to return bytes xfered")
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: None
board/st/stm32mp1/stm32mp1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index b99c6c0..ca20d85 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -101,7 +101,7 @@ int checkboard(void) if (!ret) ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD), &otp, sizeof(otp)); - if (!ret && otp) { + if (ret > 0 && otp) { printf("Board: MB%04x Var%d Rev.%c-%02d\n", otp >> 16, (otp >> 12) & 0xF,

Update management of misc_read in sysconf_init, which now return length of data after the commit 8729b1ae2cbd ("misc: Update read() and write() methods to return bytes xfered")
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: None
board/st/stm32mp1/stm32mp1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index ca20d85..5ab2226 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -464,7 +464,7 @@ static void sysconf_init(void) }
ret = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4); - if (!ret) + if (ret > 0) otp = otp & BIT(13);
/* get VDD = pwr-supply */

Update management of misc_read, which now return length of data after the commit 8729b1ae2cbd ("misc: Update read() and write() methods to return bytes xfered")
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: - impact in added command stboard after rebase
board/st/stm32mp1/cmd_stboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/board/st/stm32mp1/cmd_stboard.c b/board/st/stm32mp1/cmd_stboard.c index f781c36..04352ae 100644 --- a/board/st/stm32mp1/cmd_stboard.c +++ b/board/st/stm32mp1/cmd_stboard.c @@ -60,7 +60,7 @@ static int do_stboard(cmd_tbl_t *cmdtp, int flag, int argc, ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD), &otp, sizeof(otp));
- if (ret) { + if (ret < 0) { puts("OTP read error"); return CMD_RET_FAILURE; }

The RCC driver have no operation so the new NOP uclass is more appropriate. It only used as parent for clock and reset driver.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: - rebase v2019.10-rc1
drivers/misc/stm32_rcc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/misc/stm32_rcc.c b/drivers/misc/stm32_rcc.c index 13d7069..e7efcde 100644 --- a/drivers/misc/stm32_rcc.c +++ b/drivers/misc/stm32_rcc.c @@ -68,8 +68,6 @@ static int stm32_rcc_bind(struct udevice *dev) dev_ofnode(dev), &child); }
-static const struct misc_ops stm32_rcc_ops = { -};
static const struct udevice_id stm32_rcc_ids[] = { {.compatible = "st,stm32f42xx-rcc", .data = (ulong)&stm32_rcc_clk_f42x }, @@ -82,8 +80,7 @@ static const struct udevice_id stm32_rcc_ids[] = {
U_BOOT_DRIVER(stm32_rcc) = { .name = "stm32-rcc", - .id = UCLASS_MISC, + .id = UCLASS_NOP, .of_match = stm32_rcc_ids, .bind = stm32_rcc_bind, - .ops = &stm32_rcc_ops, };
participants (1)
-
Patrick Delaunay