summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pitre <npitre@baylibre.com>2020-04-15 23:30:01 +0300
committerBoris Brezillon <boris.brezillon@collabora.com>2020-04-16 15:27:46 +0300
commitb4203ce0556348dcfe29f897d1dbe65102874d89 (patch)
tree05ea519601df4175ecdfcbc1d2bd515c1cc8edbd
parent8f3d9f354286745c751374f5f1fcafee6b3f3136 (diff)
downloadlinux-b4203ce0556348dcfe29f897d1dbe65102874d89.tar.xz
i3c master: GETMRL's 3rd byte is optional even with BCR_IBI_PAYLOAD
According to the I3C spec v1.1 document, GETMRL's payload is 2 bytes, with an optional 3rd byte if the IBI private payload is larger than 1 byte. The whole GETMRL may also be optional so max_ibi_len already defaults to 1 if BCR_IBI_PAYLOAD prior to the i3c_master_getmrl_locked() call. Signed-off-by: Nicolas Pitre <npitre@baylibre.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://lore.kernel.org/linux-i3c/nycvar.YSQ.7.76.2004151623060.2671@knanqh.ubzr
-rw-r--r--drivers/i3c/master.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index d79cd6d54b3a..97f2e29265da 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -1008,7 +1008,6 @@ static int i3c_master_getmrl_locked(struct i3c_master_controller *master,
struct i3c_device_info *info)
{
struct i3c_ccc_cmd_dest dest;
- unsigned int expected_len;
struct i3c_ccc_mrl *mrl;
struct i3c_ccc_cmd cmd;
int ret;
@@ -1024,22 +1023,23 @@ static int i3c_master_getmrl_locked(struct i3c_master_controller *master,
if (!(info->bcr & I3C_BCR_IBI_PAYLOAD))
dest.payload.len -= 1;
- expected_len = dest.payload.len;
i3c_ccc_cmd_init(&cmd, true, I3C_CCC_GETMRL, &dest, 1);
ret = i3c_master_send_ccc_cmd_locked(master, &cmd);
if (ret)
goto out;
- if (dest.payload.len != expected_len) {
+ switch (dest.payload.len) {
+ case 3:
+ info->max_ibi_len = mrl->ibi_len;
+ fallthrough;
+ case 2:
+ info->max_read_len = be16_to_cpu(mrl->read_len);
+ break;
+ default:
ret = -EIO;
goto out;
}
- info->max_read_len = be16_to_cpu(mrl->read_len);
-
- if (info->bcr & I3C_BCR_IBI_PAYLOAD)
- info->max_ibi_len = mrl->ibi_len;
-
out:
i3c_ccc_cmd_dest_cleanup(&dest);