[PATCH 3/7] spmi: apple: check transaction status
From: Sasha Finkelstein <k@chaosmail.tech>
Date: 2026-07-25 13:48:13
Also in:
asahi, linux-devicetree, lkml
Subsystem:
arm/apple machine support, spmi subsystem, the rest · Maintainers:
Sven Peter, Janne Grunau, Stephen Boyd, Linus Torvalds
From: Alba Mendez <redacted> Check for parity errors and missing command ACKs Signed-off-by: Alba Mendez <redacted> Signed-off-by: Sasha Finkelstein <k@chaosmail.tech> --- drivers/spmi/spmi-apple-controller.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/drivers/spmi/spmi-apple-controller.c b/drivers/spmi/spmi-apple-controller.c
index b4f442d0b4ad..4678a9e5270a 100644
--- a/drivers/spmi/spmi-apple-controller.c
+++ b/drivers/spmi/spmi-apple-controller.c@@ -22,6 +22,12 @@ #define SPMI_CMD_REG 0x4 #define SPMI_RSP_REG 0x8 +/* SPMI_RSP_REG reply word */ +#define SPMI_REPLY_FRAME_PARITY_OFFSET 16 +#define SPMI_REPLY_ACK BIT(15) +#define SPMI_REPLY_SLAVE_ID GENMASK(14, 8) +#define SPMI_REPLY_CMD GENMASK(7, 0) + #define SPMI_RX_FIFO_EMPTY BIT(24) #define REG_POLL_INTERVAL_US 10000
@@ -62,7 +68,7 @@ static int spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, { struct apple_spmi *spmi = spmi_controller_get_drvdata(ctrl); u32 spmi_cmd = apple_spmi_pack_cmd(opc, sid, saddr, len); - u32 rsp; + u32 reply, rsp; size_t len_read = 0; u8 i; int ret;
@@ -73,8 +79,7 @@ static int spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, if (ret) return ret; - /* Discard SPMI reply status */ - readl(spmi->regs + SPMI_RSP_REG); + reply = readl(spmi->regs + SPMI_RSP_REG); /* Read SPMI data reply */ while (len_read < len) {
@@ -93,6 +98,10 @@ static int spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, if (!(readl(spmi->regs + SPMI_STATUS_REG) & SPMI_RX_FIFO_EMPTY)) dev_warn(&ctrl->dev, "FIFO has extra data\n"); + if ((~reply >> SPMI_REPLY_FRAME_PARITY_OFFSET) & ((1 << len) - 1)) { + dev_err(&ctrl->dev, "some frames failed parity check\n"); + return -EIO; + } return 0; }
@@ -101,6 +110,7 @@ static int spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, { struct apple_spmi *spmi = spmi_controller_get_drvdata(ctrl); u32 spmi_cmd = apple_spmi_pack_cmd(opc, sid, saddr, len); + u32 reply; size_t i = 0, j; int ret;
@@ -119,12 +129,15 @@ static int spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, if (ret) return ret; - /* Discard */ - readl(spmi->regs + SPMI_RSP_REG); + reply = readl(spmi->regs + SPMI_RSP_REG); if (!(readl(spmi->regs + SPMI_STATUS_REG) & SPMI_RX_FIFO_EMPTY)) dev_warn(&ctrl->dev, "FIFO has extra data\n"); + if (!(reply & SPMI_REPLY_ACK)) { + dev_err(&ctrl->dev, "command not acknowledged\n"); + return -EIO; + } return 0; }
--
2.55.0