static bool hci_pio_prep_new_ibi()

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;
}