summaryrefslogtreecommitdiff
path: root/drivers/i3c
diff options
context:
space:
mode:
authorVitor Soares <Vitor.Soares@synopsys.com>2019-09-03 12:35:54 +0200
committerBoris Brezillon <boris.brezillon@collabora.com>2020-01-13 10:00:05 +0100
commit3952cf8ff2f7751ee2f9d6cc6140df4667853250 (patch)
treed5ba96d4f9d39baeadfb59a1427a20d4f7d4c41b /drivers/i3c
parent3c67166dc58d02c5166193138f0740e3c322ec35 (diff)
i3c: master: dw: reattach device on first available location of address table
For today the reattach function only update the device address on the controller. Update the location to the first available too, will optimize the enumeration process avoiding additional checks to keep the available positions on address table consecutive. Signed-off-by: Vitor Soares <vitor.soares@synopsys.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Diffstat (limited to 'drivers/i3c')
-rw-r--r--drivers/i3c/master/dw-i3c-master.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 7b941e93337f..bd26c3b9634e 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -899,6 +899,22 @@ static int dw_i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev,
struct dw_i3c_i2c_dev_data *data = i3c_dev_get_master_data(dev);
struct i3c_master_controller *m = i3c_dev_get_master(dev);
struct dw_i3c_master *master = to_dw_i3c_master(m);
+ int pos;
+
+ pos = dw_i3c_master_get_free_pos(master);
+
+ if (data->index > pos && pos > 0) {
+ writel(0,
+ master->regs +
+ DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
+
+ master->addrs[data->index] = 0;
+ master->free_pos |= BIT(data->index);
+
+ data->index = pos;
+ master->addrs[pos] = dev->info.dyn_addr;
+ master->free_pos &= ~BIT(pos);
+ }
writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr),
master->regs +