diff options
author | Wludzik, Jozef <jozef.wludzik@intel.com> | 2021-01-19 14:04:06 +0300 |
---|---|---|
committer | Jae Hyun Yoo <jae.hyun.yoo@intel.com> | 2021-07-14 20:04:18 +0300 |
commit | 0bd4f1f1c52eb63f7981e05dc8a2465459502a1e (patch) | |
tree | 69c96cf186c559649d5413b9f7545f209562f500 | |
parent | 57daf90aed682e2979e90d892d25b0c971ed35c7 (diff) | |
download | linux-0bd4f1f1c52eb63f7981e05dc8a2465459502a1e.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>
-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 9563246f97fc..00f49e7435fe 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); |