Re: [PATCH v4 2/6] spmi: apple: Validate FIFO state
Janne Grunau <[email protected]> Wed, 5 Aug 2026 14:03:02 +0200
| Newsgroups | gmane.linux.drivers.devicetree,gmane.linux.ports.arm.kernel,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
On Wed, Aug 05, 2026 at 12:11:12PM +0200, Sasha Finkelstein wrote: > From: Alba Mendez <[email protected]> > > Check for data before reading the body of a reply, and check for > end of data afterwards. > > Signed-off-by: Alba Mendez <[email protected]> > Signed-off-by: Sasha Finkelstein <[email protected]> > --- > drivers/spmi/spmi-apple-controller.c | 29 +++++++++++++++++++++++++++++ > 1 file changed, 29 insertions(+) > > diff --git a/drivers/spmi/spmi-apple-controller.c b/drivers/spmi/spmi-apple-controller.c > index 376cf682c43e..4d5356bf9bbf 100644 > --- a/drivers/spmi/spmi-apple-controller.c > +++ b/drivers/spmi/spmi-apple-controller.c > @@ -21,7 +21,9 @@ > #define SPMI_STATUS_REG 0 > #define SPMI_CMD_REG 0x4 > #define SPMI_RSP_REG 0x8 > +#define SPMI_ACT_REG 0xa4 > > +#define SPMI_ACT_FIFO_FLUSH BIT(0) > #define SPMI_RX_FIFO_EMPTY BIT(24) > > #define REG_POLL_INTERVAL_US 10000 > @@ -29,6 +31,7 @@ > > struct apple_spmi { > void __iomem *regs; > + bool prev_fail; > }; > > #define poll_reg(spmi, reg, val, cond) \ > @@ -49,6 +52,7 @@ static int apple_spmi_wait_rx_not_empty(struct spmi_controller *ctrl) > > ret = poll_reg(spmi, SPMI_STATUS_REG, status, !(status & SPMI_RX_FIFO_EMPTY)); > if (ret) { > + spmi->prev_fail = true; > dev_err(&ctrl->dev, > "failed to wait for RX FIFO not empty\n"); > return ret; > @@ -67,6 +71,11 @@ static int spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, > u8 i; > int ret; > > + if (spmi->prev_fail) { > + writel(SPMI_ACT_FIFO_FLUSH, spmi->regs + SPMI_RSP_REG); > + spmi->prev_fail = false; > + } > + > writel(spmi_cmd, spmi->regs + SPMI_CMD_REG); > > ret = apple_spmi_wait_rx_not_empty(ctrl); > @@ -78,6 +87,11 @@ static int spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, > > /* Read SPMI data reply */ > while (len_read < len) { > + if (readl(spmi->regs + SPMI_STATUS_REG) & SPMI_RX_FIFO_EMPTY) { > + dev_err_ratelimited(&ctrl->dev, > + "FIFO lacks reply data, controller stuck?\n"); > + return -EIO; > + } > rsp = readl(spmi->regs + SPMI_RSP_REG); > i = 0; > while ((len_read < len) && (i < 4)) { > @@ -86,6 +100,11 @@ 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"); > + spmi->prev_fail = true; > + } > + > return 0; > } > > @@ -97,6 +116,11 @@ static int spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, > size_t i = 0, j; > int ret; > > + if (spmi->prev_fail) { > + writel(SPMI_ACT_FIFO_FLUSH, spmi->regs + SPMI_RSP_REG); > + spmi->prev_fail = false; > + } > + > writel(spmi_cmd, spmi->regs + SPMI_CMD_REG); > > while (i < len) { > @@ -115,6 +139,11 @@ static int spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, > /* Discard */ > 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"); > + spmi->prev_fail = true; > + } > + > return 0; > } Reviewed-by: Janne Grunau <[email protected]> Janne