diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index 0e01f8e6138..b8933587adb 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -306,7 +306,7 @@ static int setup_mac_address(void)
 
 	ret = misc_read(dev, BSEC_OTP_MAC * 4 + STM32_BSEC_OTP_OFFSET,
 			otp, sizeof(otp));
-	if (ret)
+	if (ret < 0)
 		return ret;
 
 	for (i = 0; i < 6; i++)
@@ -344,7 +344,7 @@ static int setup_serial_number(void)
 
 	ret = misc_read(dev, BSEC_OTP_SERIAL * 4 + STM32_BSEC_OTP_OFFSET,
 			otp, sizeof(otp));
-	if (ret)
+	if (ret < 0)
 		return ret;
 
 	sprintf(serial_string, "%08x%08x%08x", otp[0], otp[1], otp[2]);
diff --git a/drivers/clk/clk_vexpress_osc.c b/drivers/clk/clk_vexpress_osc.c
index 7fef4b2e312..c692a6d0b89 100644
--- a/drivers/clk/clk_vexpress_osc.c
+++ b/drivers/clk/clk_vexpress_osc.c
@@ -29,7 +29,7 @@ static ulong vexpress_osc_clk_get_rate(struct clk *clk)
 
 	data = CLK_FUNCTION | priv->osc;
 	err = misc_read(vexpress_cfg, 0, &data, sizeof(data));
-	if (err)
+	if (err < 0)
 		return err;
 
 	return data;
@@ -53,7 +53,7 @@ static ulong vexpress_osc_clk_set_rate(struct clk *clk, ulong rate)
 	buffer[0] = CLK_FUNCTION | priv->osc;
 	buffer[1] = rate;
 	err = misc_write(vexpress_cfg, 0, buffer, 2 * sizeof(u32));
-	if (err)
+	if (err < 0)
 		return err;
 
 	return rate;
diff --git a/drivers/misc/altera_sysid.c b/drivers/misc/altera_sysid.c
index 883b2a35e07..eff33f7343d 100644
--- a/drivers/misc/altera_sysid.c
+++ b/drivers/misc/altera_sysid.c
@@ -35,7 +35,7 @@ void display_sysid(void)
 	if (ret)
 		return;
 	ret = misc_read(dev, 0, &sysid, sizeof(sysid));
-	if (ret)
+	if (ret < 0)
 		return;
 
 	stamp = sysid[1];
diff --git a/drivers/misc/misc_sandbox.c b/drivers/misc/misc_sandbox.c
index e4164f76fba..f7c5b2e25fa 100644
--- a/drivers/misc/misc_sandbox.c
+++ b/drivers/misc/misc_sandbox.c
@@ -20,7 +20,7 @@ int misc_sandbox_read(struct udevice *dev, int offset, void *buf, int size)
 
 	memcpy(buf, priv->mem + offset, size);
 
-	return 0;
+	return size;
 }
 
 int misc_sandbox_write(struct udevice *dev, int offset, const void *buf,
@@ -30,7 +30,7 @@ int misc_sandbox_write(struct udevice *dev, int offset, const void *buf,
 
 	memcpy(priv->mem + offset, buf, size);
 
-	return 0;
+	return size;
 }
 
 int misc_sandbox_ioctl(struct udevice *dev, unsigned long request, void *buf)
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
index 8a213c9e270..2520c6a38ed 100644
--- a/drivers/misc/rockchip-efuse.c
+++ b/drivers/misc/rockchip-efuse.c
@@ -65,7 +65,7 @@ static int dump_efuses(cmd_tbl_t *cmdtp, int flag,
 	}
 
 	ret = misc_read(dev, 0, &fuses, sizeof(fuses));
-	if (ret) {
+	if (ret < 0) {
 		printf("%s: misc_read failed\n", __func__);
 		return 0;
 	}
diff --git a/drivers/misc/stm32mp_fuse.c b/drivers/misc/stm32mp_fuse.c
index 2d661351a17..33943a231b1 100644
--- a/drivers/misc/stm32mp_fuse.c
+++ b/drivers/misc/stm32mp_fuse.c
@@ -29,6 +29,9 @@ 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;
 		break;
 
 	default:
@@ -54,6 +57,9 @@ 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;
 		break;
 
 	default:
@@ -78,6 +84,9 @@ 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;
 		break;
 
 	default:
@@ -103,6 +112,9 @@ 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;
 		break;
 
 	default:
diff --git a/include/misc.h b/include/misc.h
index 50515852b25..12d1325ee26 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -13,7 +13,7 @@
  * @buf: pointer to data buffer
  * @size: data size in bytes to read the device
  *
- * Return: 0 if OK, -ve on error
+ * Return: number of bytes read if OK (may be 0 if EOF), -ve on error
  */
 int misc_read(struct udevice *dev, int offset, void *buf, int size);
 
@@ -24,7 +24,7 @@ int misc_read(struct udevice *dev, int offset, void *buf, int size);
  * @buf: pointer to data buffer
  * @size: data size in bytes to write the device
  *
- * Return: 0 if OK, -ve on error
+ * Return: number of bytes written if OK (may be < @size), -ve on error
  */
 int misc_write(struct udevice *dev, int offset, void *buf, int size);
 
@@ -90,7 +90,7 @@ struct misc_ops {
 	 * @buf: pointer to data buffer
 	 * @size: data size in bytes to read the device
 	 *
-	 * Return: 0 if OK, -ve on error
+	 * Return: number of bytes read if OK (may be 0 if EOF), -ve on error
 	 */
 	int (*read)(struct udevice *dev, int offset, void *buf, int size);
 
@@ -101,7 +101,7 @@ struct misc_ops {
 	 * @buf: pointer to data buffer
 	 * @size: data size in bytes to write the device
 	 *
-	 * Return: 0 if OK, -ve on error
+	 * Return: number of bytes written if OK (may be < @size), -ve on error
 	 */
 	int (*write)(struct udevice *dev, int offset, const void *buf,
 		     int size);
