in master/mipi-i3c-hci/pio.c [806:859]
static bool hci_pio_prep_new_ibi(struct i3c_hci *hci, struct hci_pio_data *pio)
{
struct hci_pio_ibi_data *ibi = &pio->ibi;
struct i3c_dev_desc *dev;
struct i3c_hci_dev_data *dev_data;
struct hci_pio_dev_ibi_data *dev_ibi;
u32 ibi_status;
/*
* We have a new IBI. Try to set up its payload retrieval.
* When returning true, the IBI data has to be consumed whether
* or not we are set up to capture it. If we return true with
* ibi->slot == NULL that means the data payload has to be
* drained out of the IBI port and dropped.
*/
ibi_status = pio_reg_read(IBI_PORT);
DBG("status = %#x", ibi_status);
ibi->addr = FIELD_GET(IBI_TARGET_ADDR, ibi_status);
if (ibi_status & IBI_ERROR) {
dev_err(&hci->master.dev, "IBI error from %#x\n", ibi->addr);
return false;
}
ibi->last_seg = ibi_status & IBI_LAST_STATUS;
ibi->seg_len = FIELD_GET(IBI_DATA_LENGTH, ibi_status);
ibi->seg_cnt = ibi->seg_len;
dev = i3c_hci_addr_to_dev(hci, ibi->addr);
if (!dev) {
dev_err(&hci->master.dev,
"IBI for unknown device %#x\n", ibi->addr);
return true;
}
dev_data = i3c_dev_get_master_data(dev);
dev_ibi = dev_data->ibi_data;
ibi->max_len = dev_ibi->max_len;
if (ibi->seg_len > ibi->max_len) {
dev_err(&hci->master.dev, "IBI payload too big (%d > %d)\n",
ibi->seg_len, ibi->max_len);
return true;
}
ibi->slot = i3c_generic_ibi_get_free_slot(dev_ibi->pool);
if (!ibi->slot) {
dev_err(&hci->master.dev, "no free slot for IBI\n");
} else {
ibi->slot->len = 0;
ibi->data_ptr = ibi->slot->data;
}
return true;
}