Commit 733b4393 authored by Jorge Marques's avatar Jorge Marques Committed by Alexandre Belloni
Browse files

i3c: master: Add inline i3c_readl_fifo() and i3c_writel_fifo()



The I3C abstraction expects u8 buffers, but some controllers operate with
a 32-bit bus width FIFO and cannot flag valid bytes individually. To avoid
reading or writing outside the buffer bounds, use 32-bit accesses where
possible and apply memcpy for any remaining bytes

Signed-off-by: default avatarJorge Marques <jorge.marques@analog.com>
Suggested-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: default avatarFrank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20250624-i3c-writesl-readsl-v3-1-63ccf0870f01@analog.com


Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
parent 12aa3e0c
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -22,4 +22,41 @@ int i3c_dev_enable_ibi_locked(struct i3c_dev_desc *dev);
int i3c_dev_request_ibi_locked(struct i3c_dev_desc *dev,
			       const struct i3c_ibi_setup *req);
void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev);

/**
 * i3c_writel_fifo - Write data buffer to 32bit FIFO
 * @addr: FIFO Address to write to
 * @buf: Pointer to the data bytes to write
 * @nbytes: Number of bytes to write
 */
static inline void i3c_writel_fifo(void __iomem *addr, const void *buf,
				   int nbytes)
{
	writesl(addr, buf, nbytes / 4);
	if (nbytes & 3) {
		u32 tmp = 0;

		memcpy(&tmp, buf + (nbytes & ~3), nbytes & 3);
		writel(tmp, addr);
	}
}

/**
 * i3c_readl_fifo - Read data buffer from 32bit FIFO
 * @addr: FIFO Address to read from
 * @buf: Pointer to the buffer to store read bytes
 * @nbytes: Number of bytes to read
 */
static inline void i3c_readl_fifo(const void __iomem *addr, void *buf,
				  int nbytes)
{
	readsl(addr, buf, nbytes / 4);
	if (nbytes & 3) {
		u32 tmp;

		tmp = readl(addr);
		memcpy(buf + (nbytes & ~3), &tmp, nbytes & 3);
	}
}

#endif /* I3C_INTERNAL_H */