Implement the i3c_master_add_spd_dev() function in the I3C master to
handle SPD (Serial Presence Detect) device creation and map the board
information into the I3C device structure.
Co-developed-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
---
drivers/i3c/master.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 7d23c32e1c0f..ba6f17cb8aa6 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -1657,6 +1657,45 @@ i3c_master_register_new_i3c_devs(struct i3c_master_controller *master)
}
}
+static int i3c_master_add_spd_dev(struct i3c_master_controller *master,
+ struct i3c_dev_boardinfo *boardinfo)
+{
+ struct i3c_dev_desc *i3cdev;
+ int ret;
+
+ list_for_each_entry(boardinfo, &master->boardinfo.i3c, node) {
+ struct i3c_device_info info = {
+ .static_addr = boardinfo->static_addr,
+ };
+
+ ret = i3c_bus_get_addr_slot_status(&master->bus, boardinfo->static_addr);
+ if (ret != I3C_ADDR_SLOT_FREE)
+ return -EBUSY;
+
+ i3cdev = i3c_master_alloc_i3c_dev(master, &info);
+ if (IS_ERR(i3cdev))
+ return -ENOMEM;
+
+ i3cdev->boardinfo = boardinfo;
+ ret = i3c_master_attach_i3c_dev(master, i3cdev);
+ if (ret)
+ goto err_free_dev;
+
+ i3cdev->info.pid = i3cdev->boardinfo->pid;
+ i3cdev->info.dyn_addr = i3cdev->boardinfo->init_dyn_addr;
+
+ i3c_bus_normaluse_lock(&master->bus);
+ i3c_master_register_new_i3c_devs(master);
+ i3c_bus_normaluse_unlock(&master->bus);
+ }
+
+ return 0;
+
+err_free_dev:
+ i3c_master_free_i3c_dev(i3cdev);
+ return ret;
+}
+
/**
* i3c_master_do_daa() - do a DAA (Dynamic Address Assignment)
* @master: master doing the DAA
@@ -1814,7 +1853,7 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
{
enum i3c_addr_slot_status status;
struct i2c_dev_boardinfo *i2cboardinfo;
- struct i3c_dev_boardinfo *i3cboardinfo;
+ struct i3c_dev_boardinfo *i3cboardinfo = NULL;
struct i2c_dev_desc *i2cdev;
int ret;
@@ -1868,6 +1907,8 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
goto err_bus_cleanup;
}
+ i3c_master_add_spd_dev(master, i3cboardinfo);
+
if (master->ops->set_speed) {
ret = master->ops->set_speed(master, I3C_OPEN_DRAIN_SLOW_SPEED);
if (ret)
--
2.34.1