[U-Boot] [PATCH 0/5] 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.
Patrick Delaunay (5): 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 misc: change RCC form MISC to NOP uclass
arch/arm/mach-stm32mp/bsec.c | 31 +++++++------ board/st/stm32mp1/stm32mp1.c | 2 +- drivers/misc/stm32_rcc.c | 5 +- drivers/misc/stm32mp_fuse.c | 74 +++++++++++++++++++++++------- drivers/power/pmic/stpmic1.c | 107 +++++++++++++++++++++++-------------------- include/power/stpmic1.h | 7 --- 6 files changed, 132 insertions(+), 94 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 ---
arch/arm/mach-stm32mp/bsec.c | 31 ++++++++++++++++--------------- drivers/misc/stm32mp_fuse.c | 30 +++++++++++++++++------------- 2 files changed, 33 insertions(+), 28 deletions(-)
diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c index 0166649..50ff636 100644 --- a/arch/arm/mach-stm32mp/bsec.c +++ b/arch/arm/mach-stm32mp/bsec.c @@ -363,15 +363,13 @@ static int stm32mp_bsec_read(struct udevice *dev, int offset, offset -= STM32_BSEC_OTP_OFFSET; shadow = false; } - otp = offset / 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 (offset < 0 || (offset % 4) || (size % 4)) return -EINVAL; - }
- for (i = otp; i < (otp + nb_otp); i++) { + otp = offset / sizeof(u32); + + for (i = otp; i < (otp + nb_otp) && i <= BSEC_OTP_MAX_VALUE; i++) { u32 *addr = &((u32 *)buf)[i - otp];
if (shadow) @@ -382,7 +380,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, @@ -398,15 +399,12 @@ static int stm32mp_bsec_write(struct udevice *dev, int offset, offset -= STM32_BSEC_OTP_OFFSET; shadow = false; } - otp = offset / 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 (offset < 0 || (offset % 4) || (size % 4)) return -EINVAL; - }
- for (i = otp; i < otp + nb_otp; i++) { + otp = offset / sizeof(u32); + + for (i = otp; i < otp + nb_otp && i <= BSEC_OTP_MAX_VALUE; i++) { u32 *val = &((u32 *)buf)[i - otp];
if (shadow) @@ -416,7 +414,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 8dc246b..ac33130 100644 --- a/drivers/misc/stm32mp_fuse.c +++ b/drivers/misc/stm32mp_fuse.c @@ -19,7 +19,7 @@ */ int fuse_read(u32 bank, u32 word, u32 *val) { - int ret = 0; + int ret; struct udevice *dev;
switch (bank) { @@ -31,9 +31,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 @@ -66,9 +67,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 @@ -99,9 +101,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 @@ -134,9 +137,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

Hi,
From: Patrick DELAUNAY patrick.delaunay@st.com Sent: vendredi 19 juillet 2019 11:39 Subject: [PATCH 1/5] bsec: update after MISC u-class update Importance: High
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
arch/arm/mach-stm32mp/bsec.c | 31 ++++++++++++++++--------------- drivers/misc/stm32mp_fuse.c | 30 +++++++++++++++++------------- 2 files changed, 33 insertions(+), 28 deletions(-)
For information, this patch need rework after commit dae0bd28c1638ea751021045bd1453b2ba3f3245 "stm32mp1: bsec: Fix warnings when compiling with W=1"
This commit is integrated in v2019.10-rc1 and I will rebase the patchset and sent a V2.
Regards
Patrick

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 ---
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

Retrieve parent device from dev->parent instead of calling uclass_get_device_by_driver()
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
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 9f20c31..b644176 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) 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 ---
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 7769293..b1e592c 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -95,7 +95,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,

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 ---
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 (2)
-
Patrick DELAUNAY
-
Patrick Delaunay