[PATCH linux dev-5.3 1/3] fsi: aspeed: Implement byte and half world transfers

Andrew Jeffery andrew at aj.id.au
Wed Oct 30 23:37:05 AEDT 2019


From: Joel Stanley <joel at jms.id.au>

The driver did not previously support non-word size transfers. The
fsi-i2c driver attempts accesses of this size, so we require it now.

Signed-off-by: Joel Stanley <joel at jms.id.au>
[AJ: rebase on dev-5.3, fix conflicts, fix warnings]
Signed-off-by: Andrew Jeffery <andrew at aj.id.au>
---
 drivers/fsi/fsi-master-aspeed.c | 35 ++++++++++++++++++++++++---------
 1 file changed, 26 insertions(+), 9 deletions(-)

diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c
index 97d2cac94291..cb8064cc59c0 100644
--- a/drivers/fsi/fsi-master-aspeed.c
+++ b/drivers/fsi/fsi-master-aspeed.c
@@ -167,24 +167,39 @@ static const u32 fsi_base = 0xa0000000;
 #define CMD_WRITE	0
 
 /* OPBx_XFER_SIZE */
-#define XFER_WORD	(BIT(1) | BIT(0))
-#define XFER_NIBBLE	(BIT(0))
+#define XFER_FULLWORD	(BIT(1) | BIT(0))
+#define XFER_HALFWORD	(BIT(0))
 #define XFER_BYTE	(0)
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/fsi_master_aspeed.h>
 
+static int get_xfer_size(size_t size) {
+	switch (size) {
+	case 1:
+		return XFER_BYTE;
+	case 2:
+		return XFER_HALFWORD;
+	case 4:
+		return XFER_FULLWORD;
+	default:
+		return -EINVAL;
+	}
+}
+
 static u32 opb_write(struct fsi_master_aspeed *aspeed, uint32_t addr,
 		     uint32_t val, size_t size)
 {
 	void __iomem *base = aspeed->base;
 	u32 reg, ret, status;
+	int xfer_size;
 
-	/* TODO: implement other sizes, see 0x18 */
-	WARN_ON(size != 4);
+	xfer_size = get_xfer_size(size);
+	if (xfer_size < 0)
+		return xfer_size;
 
 	writel(CMD_WRITE, base + OPB0_RW);
-	writel(XFER_WORD, base + OPB0_XFER_SIZE);
+	writel(xfer_size, base + OPB0_XFER_SIZE);
 	writel(addr, base + OPB0_FSI_ADDR);
 	writel(val, base + OPB0_FSI_DATA_W);
 	writel(0x1, base + OPB_IRQ_CLEAR);
@@ -215,12 +230,14 @@ static int opb_read(struct fsi_master_aspeed *aspeed, uint32_t addr,
 	void __iomem *base = aspeed->base;
 	u32 result, reg;
 	int status, ret;
+	int xfer_size;
 
-	/* TODO: implement other sizes, see 0x18 */
-	WARN_ON(size != 4);
+	xfer_size = get_xfer_size(size);
+	if (xfer_size < 0)
+		return xfer_size;
 
 	writel(CMD_READ, base + OPB0_RW);
-	writel(XFER_WORD, base + OPB0_XFER_SIZE);
+	writel(xfer_size, base + OPB0_XFER_SIZE);
 	writel(addr, base + OPB0_FSI_ADDR);
 	writel(0x1, base + OPB_IRQ_CLEAR);
 	writel(0x1, base + OPB_TRIGGER);
@@ -246,7 +263,7 @@ static int opb_read(struct fsi_master_aspeed *aspeed, uint32_t addr,
 		return -EIO;
 
 	if (out)
-		*out = result;
+		memcpy(out, &result, size);
 
 	return 0;
 }
-- 
2.20.1



More information about the openbmc mailing list