Skip to content

Commit 733b439

Browse files
gastmaieralexandrebelloni
authored andcommitted
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: Jorge Marques <[email protected]> Suggested-by: Wolfram Sang <[email protected]> Reviewed-by: Wolfram Sang <[email protected]> Tested-by: Wolfram Sang <[email protected]> Reviewed-by: Frank Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Belloni <[email protected]>
1 parent 12aa3e0 commit 733b439

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

drivers/i3c/internals.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,41 @@ int i3c_dev_enable_ibi_locked(struct i3c_dev_desc *dev);
2222
int i3c_dev_request_ibi_locked(struct i3c_dev_desc *dev,
2323
const struct i3c_ibi_setup *req);
2424
void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev);
25+
26+
/**
27+
* i3c_writel_fifo - Write data buffer to 32bit FIFO
28+
* @addr: FIFO Address to write to
29+
* @buf: Pointer to the data bytes to write
30+
* @nbytes: Number of bytes to write
31+
*/
32+
static inline void i3c_writel_fifo(void __iomem *addr, const void *buf,
33+
int nbytes)
34+
{
35+
writesl(addr, buf, nbytes / 4);
36+
if (nbytes & 3) {
37+
u32 tmp = 0;
38+
39+
memcpy(&tmp, buf + (nbytes & ~3), nbytes & 3);
40+
writel(tmp, addr);
41+
}
42+
}
43+
44+
/**
45+
* i3c_readl_fifo - Read data buffer from 32bit FIFO
46+
* @addr: FIFO Address to read from
47+
* @buf: Pointer to the buffer to store read bytes
48+
* @nbytes: Number of bytes to read
49+
*/
50+
static inline void i3c_readl_fifo(const void __iomem *addr, void *buf,
51+
int nbytes)
52+
{
53+
readsl(addr, buf, nbytes / 4);
54+
if (nbytes & 3) {
55+
u32 tmp;
56+
57+
tmp = readl(addr);
58+
memcpy(buf + (nbytes & ~3), &tmp, nbytes & 3);
59+
}
60+
}
61+
2562
#endif /* I3C_INTERNAL_H */

0 commit comments

Comments
 (0)