mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
i3c: master: Add support for devices without PID
Devices using SETAASA for address assignment are not required to have a 48-bit PID according to the I3C specification. Allow such devices to register and use the static address where PID was required. Reviewed-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Akhil R <akhilrajeev@nvidia.com> Link: https://patch.msgid.link/20260728065955.809445-6-akhilrajeev@nvidia.com Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
This commit is contained in:
parent
bbaf8733b8
commit
a1dd42fb82
|
|
@ -2071,8 +2071,17 @@ i3c_master_register_new_i3c_devs(struct i3c_master_controller *master)
|
|||
desc->dev->dev.type = &i3c_device_type;
|
||||
desc->dev->dev.bus = &i3c_bus_type;
|
||||
desc->dev->dev.release = i3c_device_release;
|
||||
dev_set_name(&desc->dev->dev, "%d-%llx", master->bus.id,
|
||||
desc->info.pid);
|
||||
|
||||
/*
|
||||
* For devices without PID (e.g., SETAASA devices), use
|
||||
* static address for naming instead.
|
||||
*/
|
||||
if (desc->info.pid)
|
||||
dev_set_name(&desc->dev->dev, "%d-%llx", master->bus.id,
|
||||
desc->info.pid);
|
||||
else
|
||||
dev_set_name(&desc->dev->dev, "%d-%02x", master->bus.id,
|
||||
desc->info.static_addr);
|
||||
|
||||
if (desc->boardinfo)
|
||||
device_set_node(&desc->dev->dev, desc->boardinfo->fwnode);
|
||||
|
|
@ -2473,8 +2482,18 @@ static void i3c_master_attach_boardinfo(struct i3c_dev_desc *i3cdev)
|
|||
struct i3c_dev_boardinfo *i3cboardinfo;
|
||||
|
||||
list_for_each_entry(i3cboardinfo, &master->boardinfo.i3c, node) {
|
||||
if (i3cdev->info.pid != i3cboardinfo->pid)
|
||||
continue;
|
||||
/*
|
||||
* For devices without PID (e.g., SETAASA devices), match by
|
||||
* static address. For devices with PID, match by PID.
|
||||
*/
|
||||
if (i3cboardinfo->pid) {
|
||||
if (i3cdev->info.pid != i3cboardinfo->pid)
|
||||
continue;
|
||||
} else {
|
||||
if (!i3cboardinfo->static_addr ||
|
||||
i3cdev->info.static_addr != i3cboardinfo->static_addr)
|
||||
continue;
|
||||
}
|
||||
|
||||
i3cdev->boardinfo = i3cboardinfo;
|
||||
i3cdev->info.static_addr = i3cboardinfo->static_addr;
|
||||
|
|
@ -2488,8 +2507,12 @@ i3c_master_search_i3c_dev_duplicate(struct i3c_dev_desc *refdev)
|
|||
struct i3c_master_controller *master = i3c_dev_get_master(refdev);
|
||||
struct i3c_dev_desc *i3cdev;
|
||||
|
||||
if (!refdev->info.pid)
|
||||
return NULL;
|
||||
|
||||
i3c_bus_for_each_i3cdev(&master->bus, i3cdev) {
|
||||
if (i3cdev != refdev && i3cdev->info.pid == refdev->info.pid)
|
||||
if (i3cdev != refdev && i3cdev->info.pid &&
|
||||
i3cdev->info.pid == refdev->info.pid)
|
||||
return i3cdev;
|
||||
}
|
||||
|
||||
|
|
@ -2932,9 +2955,16 @@ i3c_master_add_i3c_boardinfo(struct i3c_master_controller *master,
|
|||
|
||||
boardinfo->pid = ((u64)reg[1] << 32) | reg[2];
|
||||
|
||||
if ((boardinfo->pid & GENMASK_ULL(63, 48)) ||
|
||||
I3C_PID_RND_LOWER_32BITS(boardinfo->pid))
|
||||
return -EINVAL;
|
||||
/* For SETAASA devices, validate the static address instead of PID */
|
||||
if (boardinfo->static_addr_method & I3C_ADDR_METHOD_SETAASA) {
|
||||
if (!boardinfo->static_addr)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (!I3C_PID_MANUF_ID(boardinfo->pid) ||
|
||||
(boardinfo->pid & GENMASK_ULL(63, 48)) ||
|
||||
I3C_PID_RND_LOWER_32BITS(boardinfo->pid))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
boardinfo->init_dyn_addr = init_dyn_addr;
|
||||
boardinfo->fwnode = fwnode_handle_get(fwnode);
|
||||
|
|
@ -2957,10 +2987,10 @@ static int i3c_master_add_of_dev(struct i3c_master_controller *master,
|
|||
return ret;
|
||||
|
||||
/*
|
||||
* The manufacturer ID can't be 0. If reg[1] == 0 that means we're
|
||||
* dealing with an I2C device.
|
||||
* I3C device should have either the manufacturer ID specified or the
|
||||
* address discovery method specified. Else treat it as an I2C device.
|
||||
*/
|
||||
if (!reg[1])
|
||||
if (!reg[1] && !fwnode_property_present(fwnode, "mipi-i3c-static-method"))
|
||||
ret = i3c_master_add_i2c_boardinfo(master, fwnode, reg);
|
||||
else
|
||||
ret = i3c_master_add_i3c_boardinfo(master, fwnode, reg);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user