diff options
author | Wludzik, Jozef <jozef.wludzik@intel.com> | 2021-01-19 14:04:06 +0300 |
---|---|---|
committer | Wludzik, Jozef <jozef.wludzik@intel.com> | 2021-01-20 00:21:49 +0300 |
commit | 89fe0020d10b02efb8021f81ef1aa607283fd8db (patch) | |
tree | 877b1ee999b8c6aaf44a13de5a0b7427c76a07c8 | |
parent | 7dc56f9f1e6271d217f65389808dd772717ba9d5 (diff) | |
download | linux-89fe0020d10b02efb8021f81ef1aa607283fd8db.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>
Change-Id: I06d0faebf370d60251b7ea771236ce7b7d44a98f
-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 437c616fe0d0..6b789979a7f5 100644 --- a/drivers/i3c/master/dw-i3c-master.c +++ b/drivers/i3c/master/dw-i3c-master.c @@ -1384,11 +1384,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); |