[PATCH linux dev-5.3 4/4] fsi: aspeed: Implement byte and half world transfers
Joel Stanley
joel at jms.id.au
Wed Oct 23 17:18:48 AEDT 2019
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>
---
drivers/fsi/fsi-master-aspeed.c | 37 +++++++++++++++++++++++----------
1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c
index 8c5eb2bb1994..a99f9172ffa7 100644
--- a/drivers/fsi/fsi-master-aspeed.c
+++ b/drivers/fsi/fsi-master-aspeed.c
@@ -164,24 +164,38 @@ 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 u32 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(void __iomem *base, uint32_t addr, uint32_t val,
size_t size)
{
- u32 reg, ret, status;
+ u32 reg, ret, status, 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(0x1, base + OPB0_SELECT);
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);
@@ -208,15 +222,16 @@ static u32 opb_write(void __iomem *base, uint32_t addr, uint32_t val,
static int opb_read(void __iomem *base, uint32_t addr, size_t size, u32 *out)
{
- u32 result, reg;
+ u32 result, reg, xfer_size;
int status, ret;
- /* TODO: implement other sizes, see 0x18 */
- WARN_ON(size != 4);
+ xfer_size = get_xfer_size(size);
+ if (xfer_size < 0)
+ return xfer_size;
writel(0x1, base + OPB0_SELECT);
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);
@@ -242,7 +257,7 @@ static int opb_read(void __iomem *base, uint32_t addr, size_t size, u32 *out)
return -EIO;
if (out)
- *out = result;
+ memcpy(out, &result, size);
return 0;
}
--
2.23.0
More information about the openbmc
mailing list