in bus.c [725:812]
static int sdw_program_device_num(struct sdw_bus *bus)
{
u8 buf[SDW_NUM_DEV_ID_REGISTERS] = {0};
struct sdw_slave *slave, *_s;
struct sdw_slave_id id;
struct sdw_msg msg;
bool found;
int count = 0, ret;
u64 addr;
/* No Slave, so use raw xfer api */
ret = sdw_fill_msg(&msg, NULL, SDW_SCP_DEVID_0,
SDW_NUM_DEV_ID_REGISTERS, 0, SDW_MSG_FLAG_READ, buf);
if (ret < 0)
return ret;
do {
ret = sdw_transfer(bus, &msg);
if (ret == -ENODATA) { /* end of device id reads */
dev_dbg(bus->dev, "No more devices to enumerate\n");
ret = 0;
break;
}
if (ret < 0) {
dev_err(bus->dev, "DEVID read fail:%d\n", ret);
break;
}
/*
* Construct the addr and extract. Cast the higher shift
* bits to avoid truncation due to size limit.
*/
addr = buf[5] | (buf[4] << 8) | (buf[3] << 16) |
((u64)buf[2] << 24) | ((u64)buf[1] << 32) |
((u64)buf[0] << 40);
sdw_extract_slave_id(bus, addr, &id);
found = false;
/* Now compare with entries */
list_for_each_entry_safe(slave, _s, &bus->slaves, node) {
if (sdw_compare_devid(slave, id) == 0) {
found = true;
/*
* Assign a new dev_num to this Slave and
* not mark it present. It will be marked
* present after it reports ATTACHED on new
* dev_num
*/
ret = sdw_assign_device_num(slave);
if (ret < 0) {
dev_err(bus->dev,
"Assign dev_num failed:%d\n",
ret);
return ret;
}
break;
}
}
if (!found) {
/* TODO: Park this device in Group 13 */
/*
* add Slave device even if there is no platform
* firmware description. There will be no driver probe
* but the user/integration will be able to see the
* device, enumeration status and device number in sysfs
*/
sdw_slave_add(bus, &id, NULL);
dev_err(bus->dev, "Slave Entry not found\n");
}
count++;
/*
* Check till error out or retry (count) exhausts.
* Device can drop off and rejoin during enumeration
* so count till twice the bound.
*/
} while (ret == 0 && count < (SDW_MAX_DEVICES * 2));
return ret;
}