diff options
author | Wludzik, Jozef <jozef.wludzik@intel.com> | 2021-01-19 14:04:06 +0300 |
---|---|---|
committer | Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> | 2021-11-05 10:22:13 +0300 |
commit | 2dbab0fd6e1235b2d119234430ea11f9ced83b8b (patch) | |
tree | b987ef3d509495c054b5e47548d3ab89b9a6e6f9 /drivers/i3c | |
parent | 96502b5d20664ff6fafef129a5ee685f330dcc1f (diff) | |
download | linux-2dbab0fd6e1235b2d119234430ea11f9ced83b8b.tar.xz |
i3c: master: dw: Fix out of range write
Fixed out of range write by ignoring usage of CCC_WORKAROUND
when DEVICE_ADDR_TABLE_POINTER register returns 0 value. It
allows to use simulation software like QEMU where I3C may not
be implemented and all its registers are set to zeros.
Signed-off-by: Wludzik, Jozef <jozef.wludzik@intel.com>
Diffstat (limited to 'drivers/i3c')
-rw-r--r-- | drivers/i3c/master/dw-i3c-master.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c index 8123d5c637e4..abeed03314d5 100644 --- a/drivers/i3c/master/dw-i3c-master.c +++ b/drivers/i3c/master/dw-i3c-master.c @@ -1375,11 +1375,14 @@ static int dw_i3c_probe(struct platform_device *pdev) master->maxdevs = ret >> 16; master->free_pos = GENMASK(master->maxdevs - 1, 0); #ifdef CCC_WORKAROUND - master->free_pos &= ~BIT(master->maxdevs - 1); - ret = (even_parity(I3C_BROADCAST_ADDR) << 7) | I3C_BROADCAST_ADDR; - master->addrs[master->maxdevs - 1] = ret; - writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(ret), - master->regs + DEV_ADDR_TABLE_LOC(master->datstartaddr, master->maxdevs - 1)); + if (master->maxdevs > 0) { + master->free_pos &= ~BIT(master->maxdevs - 1); + ret = (even_parity(I3C_BROADCAST_ADDR) << 7) | I3C_BROADCAST_ADDR; + master->addrs[master->maxdevs - 1] = ret; + writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(ret), + master->regs + DEV_ADDR_TABLE_LOC(master->datstartaddr, + master->maxdevs - 1)); + } #endif writel(INTR_ALL, master->regs + INTR_STATUS); |