[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