On Thu, 5 Sep 2019 12:00:35 +0200 Vitor Soares <vitor.soa...@synopsys.com> wrote:
> The newdev->boardinfo assignment was missing in > i3c_master_add_i3c_dev_locked() and hence the ->of_node info isn't > propagated to i3c_dev_desc. > > Fix this by trying to initialize device i3c_dev_boardinfo if available. > > Cc: <sta...@vger.kernel.org> > Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure") > Signed-off-by: Vitor Soares <vitor.soa...@synopsys.com> > --- > Change in v3: > - None > > Changes in v2: > - Change commit message > - Change i3c_master_search_i3c_boardinfo(newdev) to > i3c_master_init_i3c_dev_boardinfo(newdev) > - Add fixes, stable tags > > drivers/i3c/master.c | 27 +++++++++++++++++++++++++-- > 1 file changed, 25 insertions(+), 2 deletions(-) > > diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c > index 586e34f..9fb99bc 100644 > --- a/drivers/i3c/master.c > +++ b/drivers/i3c/master.c > @@ -1798,6 +1798,22 @@ i3c_master_search_i3c_dev_duplicate(struct > i3c_dev_desc *refdev) > return NULL; > } > > +static void i3c_master_init_i3c_dev_boardinfo(struct i3c_dev_desc *dev) > +{ > + struct i3c_master_controller *master = i3c_dev_get_master(dev); > + struct i3c_dev_boardinfo *boardinfo; > + > + if (dev->boardinfo) > + return; > + > + list_for_each_entry(boardinfo, &master->boardinfo.i3c, node) { > + if (dev->info.pid == boardinfo->pid) { > + dev->boardinfo = boardinfo; > + return; > + } > + } > +} > + > /** > * i3c_master_add_i3c_dev_locked() - add an I3C slave to the bus > * @master: master used to send frames on the bus > @@ -1818,8 +1834,9 @@ int i3c_master_add_i3c_dev_locked(struct > i3c_master_controller *master, > u8 addr) > { > struct i3c_device_info info = { .dyn_addr = addr }; > - struct i3c_dev_desc *newdev, *olddev; > u8 old_dyn_addr = addr, expected_dyn_addr; > + enum i3c_addr_slot_status addrstatus; > + struct i3c_dev_desc *newdev, *olddev; > struct i3c_ibi_setup ibireq = { }; > bool enable_ibi = false; > int ret; > @@ -1878,6 +1895,8 @@ int i3c_master_add_i3c_dev_locked(struct > i3c_master_controller *master, > if (ret) > goto err_detach_dev; > > + i3c_master_init_i3c_dev_boardinfo(newdev); > + > /* > * Depending on our previous state, the expected dynamic address might > * differ: > @@ -1895,7 +1914,11 @@ int i3c_master_add_i3c_dev_locked(struct > i3c_master_controller *master, > else > expected_dyn_addr = newdev->info.dyn_addr; > > - if (newdev->info.dyn_addr != expected_dyn_addr) { > + addrstatus = i3c_bus_get_addr_slot_status(&master->bus, > + expected_dyn_addr); > + > + if (newdev->info.dyn_addr != expected_dyn_addr && > + addrstatus == I3C_ADDR_SLOT_FREE) { First, this change shouldn't be part of this patch, since the commit message only mentions the boardinfo init stuff, not the extra 'is slot free check'. Plus, I want the fix to be backported so we should avoid any unneeded deps. But even with those 2 things addressed, I'm still convinced the 'free desc when device is not reachable' change you do in patch 1 is not that great, and the fact that you can't pre-reserve the address to make sure no one uses it until the device had a chance to show up tends to prove me right. Can we please do what I suggest and solve the "not enough dev slots" problem later on (if we really have to). > /* > * Try to apply the expected dynamic address. If it fails, keep > * the address assigned by the master.