mirror of
https://github.com/torvalds/linux.git
synced 2026-10-13 05:41:02 +02:00
i3c: master: Report actual GET CCC payload length on success
Set dests[].payload.actual_len on successful GET CCC transfers in I3C master drivers so the core can distinguish requested and received buffer lengths. Switch core GET helpers to use actual_len instead of len when interpreting GET CCC results. Signed-off-by: Adrian Ng Ho Yin <adrian.ho.yin.ng@altera.com> Signed-off-by: Tze Yee Ng <tze.yee.ng@altera.com> Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Tested-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com> Tested-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> # on RZ/G3S Link: https://patch.msgid.link/6c66571ae7166aa4b87616d900e6d643631ac355.1783493868.git.tze.yee.ng@altera.com Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
This commit is contained in:
parent
cae22bd965
commit
cb92910153
|
|
@ -952,6 +952,7 @@ static void *i3c_ccc_cmd_dest_init(struct i3c_ccc_cmd_dest *dest, u8 addr,
|
|||
{
|
||||
dest->addr = addr;
|
||||
dest->payload.len = payloadlen;
|
||||
dest->payload.actual_len = 0;
|
||||
if (payloadlen)
|
||||
dest->payload.data = kzalloc(payloadlen, GFP_KERNEL);
|
||||
else
|
||||
|
|
@ -1374,7 +1375,7 @@ static int i3c_master_getmrl_locked(struct i3c_master_controller *master,
|
|||
if (ret)
|
||||
goto out;
|
||||
|
||||
switch (dest.payload.len) {
|
||||
switch (dest.payload.actual_len) {
|
||||
case 3:
|
||||
info->max_ibi_len = mrl->ibi_len;
|
||||
fallthrough;
|
||||
|
|
@ -1409,7 +1410,7 @@ static int i3c_master_getmwl_locked(struct i3c_master_controller *master,
|
|||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (dest.payload.len != sizeof(*mwl)) {
|
||||
if (dest.payload.actual_len != sizeof(*mwl)) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -1448,14 +1449,14 @@ static int i3c_master_getmxds_locked(struct i3c_master_controller *master,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (dest.payload.len != 2 && dest.payload.len != 5) {
|
||||
if (dest.payload.actual_len != 2 && dest.payload.actual_len != 5) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
info->max_read_ds = getmaxds->maxrd;
|
||||
info->max_write_ds = getmaxds->maxwr;
|
||||
if (dest.payload.len == 5)
|
||||
if (dest.payload.actual_len == 5)
|
||||
info->max_read_turnaround = getmaxds->maxrdturn[0] |
|
||||
((u32)getmaxds->maxrdturn[1] << 8) |
|
||||
((u32)getmaxds->maxrdturn[2] << 16);
|
||||
|
|
@ -1484,7 +1485,7 @@ static int i3c_master_gethdrcap_locked(struct i3c_master_controller *master,
|
|||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (dest.payload.len != 1) {
|
||||
if (dest.payload.actual_len != 1) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ static void adi_i3c_master_end_xfer_locked(struct adi_i3c_master *master,
|
|||
if (cmd->cmd0 & REG_CMD_FIFO_0_RNW) {
|
||||
rx_len = min_t(u32, REG_CMDR_FIFO_XFER_BYTES(cmdr), cmd->rx_len);
|
||||
adi_i3c_master_rd_from_rx_fifo(master, cmd->rx_buf, rx_len);
|
||||
cmd->rx_len = rx_len;
|
||||
}
|
||||
cmd->error = REG_CMDR_FIFO_ERROR(cmdr);
|
||||
}
|
||||
|
|
@ -360,6 +361,8 @@ static int adi_i3c_master_send_ccc_cmd(struct i3c_master_controller *m,
|
|||
adi_i3c_master_unqueue_xfer(master, xfer);
|
||||
|
||||
cmd->err = adi_i3c_cmd_get_err(&xfer->cmds[0]);
|
||||
if (!xfer->ret && cmd->rnw)
|
||||
cmd->dests[0].payload.actual_len = ccmd->rx_len;
|
||||
|
||||
return xfer->ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -780,7 +780,10 @@ static int dw_i3c_ccc_get(struct dw_i3c_master *master, struct i3c_ccc_cmd *ccc)
|
|||
dw_i3c_master_dequeue_xfer(master, xfer);
|
||||
|
||||
ret = xfer->ret;
|
||||
if (xfer->cmds[0].error == RESPONSE_ERROR_IBA_NACK)
|
||||
cmd = &xfer->cmds[0];
|
||||
if (!ret)
|
||||
ccc->dests[0].payload.actual_len = cmd->rx_len;
|
||||
if (cmd->error == RESPONSE_ERROR_IBA_NACK)
|
||||
ccc->err = I3C_ERROR_M2;
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -573,6 +573,7 @@ static void cdns_i3c_master_end_xfer_locked(struct cdns_i3c_master *master,
|
|||
cmd = &xfer->cmds[CMDR_CMDID(cmdr)];
|
||||
rx_len = min_t(u32, CMDR_XFER_BYTES(cmdr), cmd->rx_len);
|
||||
cdns_i3c_master_rd_from_rx_fifo(master, cmd->rx_buf, rx_len);
|
||||
cmd->rx_len = rx_len;
|
||||
cmd->error = CMDR_ERROR(cmdr);
|
||||
}
|
||||
|
||||
|
|
@ -714,6 +715,8 @@ static int cdns_i3c_master_send_ccc_cmd(struct i3c_master_controller *m,
|
|||
|
||||
ret = xfer->ret;
|
||||
cmd->err = cdns_i3c_cmd_get_err(&xfer->cmds[0]);
|
||||
if (!ret && cmd->rnw)
|
||||
cmd->dests[0].payload.actual_len = ccmd->rx_len;
|
||||
cdns_i3c_master_free_xfer(xfer);
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ static int i3c_hci_send_ccc_cmd(struct i3c_master_controller *m,
|
|||
goto out;
|
||||
for (i = prefixed; i < nxfers; i++) {
|
||||
if (ccc->rnw)
|
||||
ccc->dests[i - prefixed].payload.len =
|
||||
ccc->dests[i - prefixed].payload.actual_len =
|
||||
RESP_DATA_LENGTH(xfer[i].response);
|
||||
switch (RESP_STATUS(xfer[i].response)) {
|
||||
case RESP_SUCCESS:
|
||||
|
|
@ -392,7 +392,8 @@ static int i3c_hci_send_ccc_cmd(struct i3c_master_controller *m,
|
|||
|
||||
if (ccc->rnw)
|
||||
dev_dbg(&hci->master.dev, "got: %*ph",
|
||||
ccc->dests[0].payload.len, ccc->dests[0].payload.data);
|
||||
ccc->dests[0].payload.actual_len,
|
||||
ccc->dests[0].payload.data);
|
||||
|
||||
out:
|
||||
hci_free_xfer(xfer, nxfers);
|
||||
|
|
|
|||
|
|
@ -805,6 +805,8 @@ static int renesas_i3c_send_ccc_cmd(struct i3c_master_controller *m,
|
|||
ret = xfer->ret;
|
||||
if (ret)
|
||||
ccc->err = I3C_ERROR_M2;
|
||||
else if (ccc->rnw)
|
||||
ccc->dests[0].payload.actual_len = cmd->rx_count;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1072,10 +1074,16 @@ static irqreturn_t renesas_i3c_resp_isr(int irq, void *data)
|
|||
break;
|
||||
case I3C_INTERNAL_STATE_CONTROLLER_READ:
|
||||
case I3C_INTERNAL_STATE_CONTROLLER_COMMAND_READ:
|
||||
if (NDBSTLV0_RDBLV(renesas_readl(i3c->regs, NDBSTLV0)) && !cmd->err)
|
||||
bytes_remaining = data_len - cmd->rx_count;
|
||||
if (!cmd->err) {
|
||||
u32 rx_count = min(cmd->rx_count, data_len);
|
||||
|
||||
i3c_readl_fifo(i3c->regs + NTDTBP0, cmd->rx_buf, bytes_remaining);
|
||||
bytes_remaining = data_len - rx_count;
|
||||
if (bytes_remaining)
|
||||
i3c_readl_fifo(i3c->regs + NTDTBP0,
|
||||
cmd->rx_buf + rx_count,
|
||||
bytes_remaining);
|
||||
cmd->rx_count = data_len;
|
||||
}
|
||||
renesas_clear_bit(i3c->regs, NTIE, NTIE_RDBFIE0);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -1725,8 +1725,8 @@ static int svc_i3c_master_send_direct_ccc_cmd(struct svc_i3c_master *master,
|
|||
svc_i3c_master_dequeue_xfer(master, xfer);
|
||||
mutex_unlock(&master->lock);
|
||||
|
||||
if (cmd->actual_len != xfer_len)
|
||||
ccc->dests[0].payload.len = cmd->actual_len;
|
||||
if (ccc->rnw)
|
||||
ccc->dests[0].payload.actual_len = cmd->actual_len;
|
||||
|
||||
ret = xfer->ret;
|
||||
svc_i3c_master_free_xfer(xfer);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user