From 9a5a9262503cb22358ba840fded3b367be0118c7 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Sat, 28 Oct 2023 11:12:35 -0700 Subject: [PATCH] drivers: i3c: specify start addr when searching for a free addr For example, if a driver needed to reserve address before it does a ENTDAA, it would need to get free address in a loop, but the get free address func would return the same address everytime. It needs the start address, which would be the last free address it go, to be passed in to get the next free address. Signed-off-by: Ryan McClelland --- drivers/i3c/i3c_cdns.c | 2 +- drivers/i3c/i3c_common.c | 10 +++++----- include/zephyr/drivers/i3c/addresses.h | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/i3c/i3c_cdns.c b/drivers/i3c/i3c_cdns.c index cad6bab6566437..cad71e5cae6207 100644 --- a/drivers/i3c/i3c_cdns.c +++ b/drivers/i3c/i3c_cdns.c @@ -703,7 +703,7 @@ static void cdns_i3c_program_controller_retaining_reg(const struct device *dev) if (!i3c_addr_slots_is_free(&data->common.attached_dev.addr_slots, controller_da)) { controller_da = - i3c_addr_slots_next_free_find(&data->common.attached_dev.addr_slots); + i3c_addr_slots_next_free_find(&data->common.attached_dev.addr_slots, 0); LOG_DBG("%s: 0x%02x DA selected for controller", dev->name, controller_da); } sys_write32(prepare_rr0_dev_address(controller_da), config->base + DEV_ID_RR0(0)); diff --git a/drivers/i3c/i3c_common.c b/drivers/i3c/i3c_common.c index 29746f3cf68eae..6c170edb9e33b9 100644 --- a/drivers/i3c/i3c_common.c +++ b/drivers/i3c/i3c_common.c @@ -157,13 +157,13 @@ bool i3c_addr_slots_is_free(struct i3c_addr_slots *slots, return (status == I3C_ADDR_SLOT_STATUS_FREE); } -uint8_t i3c_addr_slots_next_free_find(struct i3c_addr_slots *slots) +uint8_t i3c_addr_slots_next_free_find(struct i3c_addr_slots *slots, uint8_t start_addr) { uint8_t addr; enum i3c_addr_slot_status status; /* Addresses 0 to 7 are reserved. So start at 8. */ - for (addr = 8; addr < I3C_MAX_ADDR; addr++) { + for (addr = MAX(start_addr, 8); addr < I3C_MAX_ADDR; addr++) { status = i3c_addr_slots_status(slots, addr); if (status == I3C_ADDR_SLOT_STATUS_FREE) { return addr; @@ -252,7 +252,7 @@ int i3c_determine_default_addr(struct i3c_device_desc *target, uint8_t *addr) } else { /* address is not free, get the next one */ *addr = i3c_addr_slots_next_free_find( - &data->attached_dev.addr_slots); + &data->attached_dev.addr_slots, 0); } } else { /* Use the init dynamic address as it's DA, but the RR will need to @@ -281,7 +281,7 @@ int i3c_determine_default_addr(struct i3c_device_desc *target, uint8_t *addr) } else { /* pick a DA to use */ *addr = i3c_addr_slots_next_free_find( - &data->attached_dev.addr_slots); + &data->attached_dev.addr_slots, 0); } } } else { @@ -488,7 +488,7 @@ int i3c_dev_list_daa_addr_helper(struct i3c_addr_slots *addr_slots, /* * Find the next available address. */ - dyn_addr = i3c_addr_slots_next_free_find(addr_slots); + dyn_addr = i3c_addr_slots_next_free_find(addr_slots, 0); if (dyn_addr == 0U) { /* No free addresses available */ diff --git a/include/zephyr/drivers/i3c/addresses.h b/include/zephyr/drivers/i3c/addresses.h index 191e7f881da9c8..c85255d8a69122 100644 --- a/include/zephyr/drivers/i3c/addresses.h +++ b/include/zephyr/drivers/i3c/addresses.h @@ -113,10 +113,11 @@ bool i3c_addr_slots_is_free(struct i3c_addr_slots *slots, * assigned to a new device. * * @param slots Pointer to the address slots structure. + * @param start_addr Where to start searching * * @return The next free address, or 0 if none found. */ -uint8_t i3c_addr_slots_next_free_find(struct i3c_addr_slots *slots); +uint8_t i3c_addr_slots_next_free_find(struct i3c_addr_slots *slots, uint8_t start_addr); /** * @brief Mark the address as free (not used) in device list.