Lines Matching +full:mipi +full:- +full:i3c +full:- +full:hci

1 // SPDX-License-Identifier: BSD-3-Clause
3 * Copyright (c) 2020, MIPI Alliance, Inc.
11 #include <linux/i3c/master.h>
14 #include "hci.h"
23 #define pio_reg_read(r) readl(hci->PIO_regs + (PIO_##r))
24 #define pio_reg_write(r, v) writel(v, hci->PIO_regs + (PIO_##r))
139 static int hci_pio_init(struct i3c_hci *hci) in hci_pio_init() argument
146 return -ENOMEM; in hci_pio_init()
148 hci->io_data = pio; in hci_pio_init()
149 spin_lock_init(&pio->lock); in hci_pio_init()
152 dev_info(&hci->master.dev, "CMD/RESP FIFO = %ld entries\n", in hci_pio_init()
154 dev_info(&hci->master.dev, "IBI FIFO = %ld bytes\n", in hci_pio_init()
156 dev_info(&hci->master.dev, "RX data FIFO = %d bytes\n", in hci_pio_init()
158 dev_info(&hci->master.dev, "TX data FIFO = %d bytes\n", in hci_pio_init()
168 if (hci->version_major == 1) { in hci_pio_init()
171 rx_thresh -= 1; in hci_pio_init()
173 tx_thresh -= 1; in hci_pio_init()
174 pio->rx_thresh_size = 2 << rx_thresh; in hci_pio_init()
175 pio->tx_thresh_size = 2 << tx_thresh; in hci_pio_init()
178 pio->rx_thresh_size = 1 << rx_thresh; in hci_pio_init()
179 pio->tx_thresh_size = 1 << tx_thresh; in hci_pio_init()
191 pio->max_ibi_thresh = clamp_val(ibi_val/2, 1, 63); in hci_pio_init()
193 FIELD_PREP(QUEUE_IBI_DATA_THLD, pio->max_ibi_thresh) | in hci_pio_init()
197 pio->reg_queue_thresh = val; in hci_pio_init()
204 pio->enabled_irqs = STAT_ALL_ERRORS; in hci_pio_init()
209 static void hci_pio_cleanup(struct i3c_hci *hci) in hci_pio_cleanup() argument
211 struct hci_pio_data *pio = hci->io_data; in hci_pio_cleanup()
218 BUG_ON(pio->curr_xfer); in hci_pio_cleanup()
219 BUG_ON(pio->curr_rx); in hci_pio_cleanup()
220 BUG_ON(pio->curr_tx); in hci_pio_cleanup()
221 BUG_ON(pio->curr_resp); in hci_pio_cleanup()
223 hci->io_data = NULL; in hci_pio_cleanup()
227 static void hci_pio_write_cmd(struct i3c_hci *hci, struct hci_xfer *xfer) in hci_pio_write_cmd() argument
229 DBG("cmd_desc[%d] = 0x%08x", 0, xfer->cmd_desc[0]); in hci_pio_write_cmd()
230 DBG("cmd_desc[%d] = 0x%08x", 1, xfer->cmd_desc[1]); in hci_pio_write_cmd()
231 pio_reg_write(COMMAND_QUEUE_PORT, xfer->cmd_desc[0]); in hci_pio_write_cmd()
232 pio_reg_write(COMMAND_QUEUE_PORT, xfer->cmd_desc[1]); in hci_pio_write_cmd()
233 if (hci->cmd == &mipi_i3c_hci_cmd_v2) { in hci_pio_write_cmd()
234 DBG("cmd_desc[%d] = 0x%08x", 2, xfer->cmd_desc[2]); in hci_pio_write_cmd()
235 DBG("cmd_desc[%d] = 0x%08x", 3, xfer->cmd_desc[3]); in hci_pio_write_cmd()
236 pio_reg_write(COMMAND_QUEUE_PORT, xfer->cmd_desc[2]); in hci_pio_write_cmd()
237 pio_reg_write(COMMAND_QUEUE_PORT, xfer->cmd_desc[3]); in hci_pio_write_cmd()
241 static bool hci_pio_do_rx(struct i3c_hci *hci, struct hci_pio_data *pio) in hci_pio_do_rx() argument
243 struct hci_xfer *xfer = pio->curr_rx; in hci_pio_do_rx()
247 p = xfer->data; in hci_pio_do_rx()
248 p += (xfer->data_len - xfer->data_left) / 4; in hci_pio_do_rx()
250 while (xfer->data_left >= 4) { in hci_pio_do_rx()
254 nr_words = min(xfer->data_left / 4, pio->rx_thresh_size); in hci_pio_do_rx()
256 xfer->data_left -= nr_words * 4; in hci_pio_do_rx()
257 DBG("now %d left %d", nr_words * 4, xfer->data_left); in hci_pio_do_rx()
258 while (nr_words--) in hci_pio_do_rx()
263 return !xfer->data_left; in hci_pio_do_rx()
266 static void hci_pio_do_trailing_rx(struct i3c_hci *hci, in hci_pio_do_trailing_rx() argument
269 struct hci_xfer *xfer = pio->curr_rx; in hci_pio_do_trailing_rx()
274 p = xfer->data; in hci_pio_do_trailing_rx()
275 p += (xfer->data_len - xfer->data_left) / 4; in hci_pio_do_trailing_rx()
280 xfer->data_left -= nr_words * 4; in hci_pio_do_trailing_rx()
281 DBG("now %d left %d", nr_words * 4, xfer->data_left); in hci_pio_do_trailing_rx()
282 while (nr_words--) in hci_pio_do_trailing_rx()
297 xfer->data_word_before_partial = data; in hci_pio_do_trailing_rx()
298 xfer->data_left -= count; in hci_pio_do_trailing_rx()
300 while (count--) { in hci_pio_do_trailing_rx()
307 static bool hci_pio_do_tx(struct i3c_hci *hci, struct hci_pio_data *pio) in hci_pio_do_tx() argument
309 struct hci_xfer *xfer = pio->curr_tx; in hci_pio_do_tx()
313 p = xfer->data; in hci_pio_do_tx()
314 p += (xfer->data_len - xfer->data_left) / 4; in hci_pio_do_tx()
316 while (xfer->data_left >= 4) { in hci_pio_do_tx()
321 nr_words = min(xfer->data_left / 4, pio->tx_thresh_size); in hci_pio_do_tx()
323 xfer->data_left -= nr_words * 4; in hci_pio_do_tx()
324 DBG("now %d left %d", nr_words * 4, xfer->data_left); in hci_pio_do_tx()
325 while (nr_words--) in hci_pio_do_tx()
329 if (xfer->data_left) { in hci_pio_do_tx()
339 DBG("trailing %d", xfer->data_left); in hci_pio_do_tx()
341 xfer->data_left = 0; in hci_pio_do_tx()
347 static bool hci_pio_process_rx(struct i3c_hci *hci, struct hci_pio_data *pio) in hci_pio_process_rx() argument
349 while (pio->curr_rx && hci_pio_do_rx(hci, pio)) in hci_pio_process_rx()
350 pio->curr_rx = pio->curr_rx->next_data; in hci_pio_process_rx()
351 return !pio->curr_rx; in hci_pio_process_rx()
354 static bool hci_pio_process_tx(struct i3c_hci *hci, struct hci_pio_data *pio) in hci_pio_process_tx() argument
356 while (pio->curr_tx && hci_pio_do_tx(hci, pio)) in hci_pio_process_tx()
357 pio->curr_tx = pio->curr_tx->next_data; in hci_pio_process_tx()
358 return !pio->curr_tx; in hci_pio_process_tx()
361 static void hci_pio_queue_data(struct i3c_hci *hci, struct hci_pio_data *pio) in hci_pio_queue_data() argument
363 struct hci_xfer *xfer = pio->curr_xfer; in hci_pio_queue_data()
366 if (!xfer->data) { in hci_pio_queue_data()
367 xfer->data_len = xfer->data_left = 0; in hci_pio_queue_data()
371 if (xfer->rnw) { in hci_pio_queue_data()
372 prev_queue_tail = pio->rx_queue; in hci_pio_queue_data()
373 pio->rx_queue = xfer; in hci_pio_queue_data()
374 if (pio->curr_rx) { in hci_pio_queue_data()
375 prev_queue_tail->next_data = xfer; in hci_pio_queue_data()
377 pio->curr_rx = xfer; in hci_pio_queue_data()
378 if (!hci_pio_process_rx(hci, pio)) in hci_pio_queue_data()
379 pio->enabled_irqs |= STAT_RX_THLD; in hci_pio_queue_data()
382 prev_queue_tail = pio->tx_queue; in hci_pio_queue_data()
383 pio->tx_queue = xfer; in hci_pio_queue_data()
384 if (pio->curr_tx) { in hci_pio_queue_data()
385 prev_queue_tail->next_data = xfer; in hci_pio_queue_data()
387 pio->curr_tx = xfer; in hci_pio_queue_data()
388 if (!hci_pio_process_tx(hci, pio)) in hci_pio_queue_data()
389 pio->enabled_irqs |= STAT_TX_THLD; in hci_pio_queue_data()
394 static void hci_pio_push_to_next_rx(struct i3c_hci *hci, struct hci_xfer *xfer, in hci_pio_push_to_next_rx() argument
397 u32 *from = xfer->data; in hci_pio_push_to_next_rx()
401 received = (xfer->data_len - xfer->data_left) / 4; in hci_pio_push_to_next_rx()
402 if ((xfer->data_len - xfer->data_left) & 3) { in hci_pio_push_to_next_rx()
403 from_last = xfer->data_word_before_partial; in hci_pio_push_to_next_rx()
409 count = received - words_to_keep; in hci_pio_push_to_next_rx()
415 xfer = xfer->next_data; in hci_pio_push_to_next_rx()
417 dev_err(&hci->master.dev, "pushing RX data to unexistent xfer\n"); in hci_pio_push_to_next_rx()
421 room = DIV_ROUND_UP(xfer->data_len, 4); in hci_pio_push_to_next_rx()
422 left = DIV_ROUND_UP(xfer->data_left, 4); in hci_pio_push_to_next_rx()
425 hci_pio_push_to_next_rx(hci, xfer, chunk - left); in hci_pio_push_to_next_rx()
427 xfer->data_left = left * 4; in hci_pio_push_to_next_rx()
430 bytes_to_move = xfer->data_len - xfer->data_left; in hci_pio_push_to_next_rx()
433 u32 *p = xfer->data; in hci_pio_push_to_next_rx()
435 xfer->data_word_before_partial = p[bytes_to_move / 4]; in hci_pio_push_to_next_rx()
437 memmove(xfer->data + chunk, xfer->data, bytes_to_move); in hci_pio_push_to_next_rx()
440 chunk -= 1; in hci_pio_push_to_next_rx()
442 memcpy(xfer->data, from, chunk * 4); in hci_pio_push_to_next_rx()
443 xfer->data_left -= chunk * 4; in hci_pio_push_to_next_rx()
445 count -= chunk; in hci_pio_push_to_next_rx()
448 if (xfer->data_left < 4) { in hci_pio_push_to_next_rx()
454 u8 *p_byte = xfer->data; in hci_pio_push_to_next_rx()
457 xfer->data_word_before_partial = last_word; in hci_pio_push_to_next_rx()
459 while (xfer->data_left--) { in hci_pio_push_to_next_rx()
464 u32 *p = xfer->data; in hci_pio_push_to_next_rx()
467 xfer->data_left -= 4; in hci_pio_push_to_next_rx()
469 count--; in hci_pio_push_to_next_rx()
473 static void hci_pio_err(struct i3c_hci *hci, struct hci_pio_data *pio,
476 static bool hci_pio_process_resp(struct i3c_hci *hci, struct hci_pio_data *pio) in hci_pio_process_resp() argument
478 while (pio->curr_resp && in hci_pio_process_resp()
480 struct hci_xfer *xfer = pio->curr_resp; in hci_pio_process_resp()
485 if (tid != xfer->cmd_tid) { in hci_pio_process_resp()
486 dev_err(&hci->master.dev, in hci_pio_process_resp()
488 tid, xfer->cmd_tid); in hci_pio_process_resp()
490 hci_pio_err(hci, pio, STAT_PROG_ERRORS); in hci_pio_process_resp()
493 xfer->response = resp; in hci_pio_process_resp()
495 if (pio->curr_rx == xfer) { in hci_pio_process_resp()
503 received = xfer->data_len - xfer->data_left; in hci_pio_process_resp()
504 expected = RESP_DATA_LENGTH(xfer->response); in hci_pio_process_resp()
506 hci_pio_do_trailing_rx(hci, pio, in hci_pio_process_resp()
507 expected - received); in hci_pio_process_resp()
511 hci_pio_push_to_next_rx(hci, xfer, to_keep); in hci_pio_process_resp()
515 if (hci_pio_process_rx(hci, pio)) in hci_pio_process_resp()
516 pio->enabled_irqs &= ~STAT_RX_THLD; in hci_pio_process_resp()
524 if (pio->curr_rx == xfer) { in hci_pio_process_resp()
526 pio->curr_rx = pio->curr_rx->next_data; in hci_pio_process_resp()
527 } else if (pio->curr_tx == xfer) { in hci_pio_process_resp()
529 pio->curr_tx = pio->curr_tx->next_data; in hci_pio_process_resp()
530 } else if (xfer->data_left) { in hci_pio_process_resp()
532 xfer->data_left); in hci_pio_process_resp()
535 pio->curr_resp = xfer->next_resp; in hci_pio_process_resp()
536 if (xfer->completion) in hci_pio_process_resp()
537 complete(xfer->completion); in hci_pio_process_resp()
539 return !pio->curr_resp; in hci_pio_process_resp()
542 static void hci_pio_queue_resp(struct i3c_hci *hci, struct hci_pio_data *pio) in hci_pio_queue_resp() argument
544 struct hci_xfer *xfer = pio->curr_xfer; in hci_pio_queue_resp()
547 if (!(xfer->cmd_desc[0] & CMD_0_ROC)) in hci_pio_queue_resp()
550 prev_queue_tail = pio->resp_queue; in hci_pio_queue_resp()
551 pio->resp_queue = xfer; in hci_pio_queue_resp()
552 if (pio->curr_resp) { in hci_pio_queue_resp()
553 prev_queue_tail->next_resp = xfer; in hci_pio_queue_resp()
555 pio->curr_resp = xfer; in hci_pio_queue_resp()
556 if (!hci_pio_process_resp(hci, pio)) in hci_pio_queue_resp()
557 pio->enabled_irqs |= STAT_RESP_READY; in hci_pio_queue_resp()
561 static bool hci_pio_process_cmd(struct i3c_hci *hci, struct hci_pio_data *pio) in hci_pio_process_cmd() argument
563 while (pio->curr_xfer && in hci_pio_process_cmd()
569 hci_pio_queue_data(hci, pio); in hci_pio_process_cmd()
575 hci_pio_queue_resp(hci, pio); in hci_pio_process_cmd()
579 hci_pio_write_cmd(hci, pio->curr_xfer); in hci_pio_process_cmd()
583 pio->curr_xfer = pio->curr_xfer->next_xfer; in hci_pio_process_cmd()
585 return !pio->curr_xfer; in hci_pio_process_cmd()
588 static int hci_pio_queue_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int n) in hci_pio_queue_xfer() argument
590 struct hci_pio_data *pio = hci->io_data; in hci_pio_queue_xfer()
604 spin_lock_irq(&pio->lock); in hci_pio_queue_xfer()
605 prev_queue_tail = pio->xfer_queue; in hci_pio_queue_xfer()
606 pio->xfer_queue = &xfer[n - 1]; in hci_pio_queue_xfer()
607 if (pio->curr_xfer) { in hci_pio_queue_xfer()
608 prev_queue_tail->next_xfer = xfer; in hci_pio_queue_xfer()
610 pio->curr_xfer = xfer; in hci_pio_queue_xfer()
611 if (!hci_pio_process_cmd(hci, pio)) in hci_pio_queue_xfer()
612 pio->enabled_irqs |= STAT_CMD_QUEUE_READY; in hci_pio_queue_xfer()
613 pio_reg_write(INTR_SIGNAL_ENABLE, pio->enabled_irqs); in hci_pio_queue_xfer()
617 spin_unlock_irq(&pio->lock); in hci_pio_queue_xfer()
621 static bool hci_pio_dequeue_xfer_common(struct i3c_hci *hci, in hci_pio_dequeue_xfer_common() argument
634 for (p = pio->curr_resp; p; p = p->next_resp) in hci_pio_dequeue_xfer_common()
638 for (p = pio->curr_rx; p; p = p->next_data) in hci_pio_dequeue_xfer_common()
642 for (p = pio->curr_tx; p; p = p->next_data) in hci_pio_dequeue_xfer_common()
651 p_prev_next = &pio->curr_xfer; in hci_pio_dequeue_xfer_common()
652 for (p = pio->curr_xfer; p; p = p->next_xfer) { in hci_pio_dequeue_xfer_common()
654 *p_prev_next = xfer[n - 1].next_xfer; in hci_pio_dequeue_xfer_common()
657 p_prev_next = &p->next_xfer; in hci_pio_dequeue_xfer_common()
668 for (p = pio->curr_resp; p; p = p->next_resp) { in hci_pio_dequeue_xfer_common()
669 p->response = FIELD_PREP(RESP_ERR_FIELD, RESP_ERR_HC_TERMINATED); in hci_pio_dequeue_xfer_common()
670 if (p->completion) in hci_pio_dequeue_xfer_common()
671 complete(p->completion); in hci_pio_dequeue_xfer_common()
673 for (p = pio->curr_xfer; p; p = p->next_xfer) { in hci_pio_dequeue_xfer_common()
674 p->response = FIELD_PREP(RESP_ERR_FIELD, RESP_ERR_HC_TERMINATED); in hci_pio_dequeue_xfer_common()
675 if (p->completion) in hci_pio_dequeue_xfer_common()
676 complete(p->completion); in hci_pio_dequeue_xfer_common()
678 pio->curr_xfer = pio->curr_rx = pio->curr_tx = pio->curr_resp = NULL; in hci_pio_dequeue_xfer_common()
683 static bool hci_pio_dequeue_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int n) in hci_pio_dequeue_xfer() argument
685 struct hci_pio_data *pio = hci->io_data; in hci_pio_dequeue_xfer()
688 spin_lock_irq(&pio->lock); in hci_pio_dequeue_xfer()
692 readl(hci->base_regs + 0x20), readl(hci->base_regs + 0x28)); in hci_pio_dequeue_xfer()
694 ret = hci_pio_dequeue_xfer_common(hci, pio, xfer, n); in hci_pio_dequeue_xfer()
695 spin_unlock_irq(&pio->lock); in hci_pio_dequeue_xfer()
699 static void hci_pio_err(struct i3c_hci *hci, struct hci_pio_data *pio, in hci_pio_err() argument
708 dev_err(&hci->master.dev, in hci_pio_err()
717 dev_err(&hci->master.dev, in hci_pio_err()
728 hci_pio_dequeue_xfer_common(hci, pio, pio->curr_resp, 1); in hci_pio_err()
729 /* ... and half-way TX transfers if any */ in hci_pio_err()
730 if (pio->curr_tx && pio->curr_tx->data_left != pio->curr_tx->data_len) in hci_pio_err()
731 hci_pio_dequeue_xfer_common(hci, pio, pio->curr_tx, 1); in hci_pio_err()
733 mipi_i3c_hci_pio_reset(hci); in hci_pio_err()
734 mipi_i3c_hci_resume(hci); in hci_pio_err()
740 static void hci_pio_set_ibi_thresh(struct i3c_hci *hci, in hci_pio_set_ibi_thresh() argument
744 u32 regval = pio->reg_queue_thresh; in hci_pio_set_ibi_thresh()
749 if (regval != pio->reg_queue_thresh) { in hci_pio_set_ibi_thresh()
751 pio->reg_queue_thresh = regval; in hci_pio_set_ibi_thresh()
756 static bool hci_pio_get_ibi_segment(struct i3c_hci *hci, in hci_pio_get_ibi_segment() argument
759 struct hci_pio_ibi_data *ibi = &pio->ibi; in hci_pio_get_ibi_segment()
763 p = ibi->data_ptr; in hci_pio_get_ibi_segment()
764 p += (ibi->seg_len - ibi->seg_cnt) / 4; in hci_pio_get_ibi_segment()
766 while ((nr_words = ibi->seg_cnt/4)) { in hci_pio_get_ibi_segment()
768 thresh_val = min(nr_words, pio->max_ibi_thresh); in hci_pio_get_ibi_segment()
769 hci_pio_set_ibi_thresh(hci, pio, thresh_val); in hci_pio_get_ibi_segment()
775 ibi->seg_cnt -= nr_words * 4; in hci_pio_get_ibi_segment()
776 DBG("now %d left %d", nr_words * 4, ibi->seg_cnt); in hci_pio_get_ibi_segment()
777 while (nr_words--) in hci_pio_get_ibi_segment()
781 if (ibi->seg_cnt) { in hci_pio_get_ibi_segment()
791 hci_pio_set_ibi_thresh(hci, pio, 1); in hci_pio_get_ibi_segment()
794 DBG("trailing %d", ibi->seg_cnt); in hci_pio_get_ibi_segment()
797 while (ibi->seg_cnt--) { in hci_pio_get_ibi_segment()
806 static bool hci_pio_prep_new_ibi(struct i3c_hci *hci, struct hci_pio_data *pio) in hci_pio_prep_new_ibi() argument
808 struct hci_pio_ibi_data *ibi = &pio->ibi; in hci_pio_prep_new_ibi()
818 * ibi->slot == NULL that means the data payload has to be in hci_pio_prep_new_ibi()
824 ibi->addr = FIELD_GET(IBI_TARGET_ADDR, ibi_status); in hci_pio_prep_new_ibi()
826 dev_err(&hci->master.dev, "IBI error from %#x\n", ibi->addr); in hci_pio_prep_new_ibi()
830 ibi->last_seg = ibi_status & IBI_LAST_STATUS; in hci_pio_prep_new_ibi()
831 ibi->seg_len = FIELD_GET(IBI_DATA_LENGTH, ibi_status); in hci_pio_prep_new_ibi()
832 ibi->seg_cnt = ibi->seg_len; in hci_pio_prep_new_ibi()
834 dev = i3c_hci_addr_to_dev(hci, ibi->addr); in hci_pio_prep_new_ibi()
836 dev_err(&hci->master.dev, in hci_pio_prep_new_ibi()
837 "IBI for unknown device %#x\n", ibi->addr); in hci_pio_prep_new_ibi()
842 dev_ibi = dev_data->ibi_data; in hci_pio_prep_new_ibi()
843 ibi->max_len = dev_ibi->max_len; in hci_pio_prep_new_ibi()
845 if (ibi->seg_len > ibi->max_len) { in hci_pio_prep_new_ibi()
846 dev_err(&hci->master.dev, "IBI payload too big (%d > %d)\n", in hci_pio_prep_new_ibi()
847 ibi->seg_len, ibi->max_len); in hci_pio_prep_new_ibi()
851 ibi->slot = i3c_generic_ibi_get_free_slot(dev_ibi->pool); in hci_pio_prep_new_ibi()
852 if (!ibi->slot) { in hci_pio_prep_new_ibi()
853 dev_err(&hci->master.dev, "no free slot for IBI\n"); in hci_pio_prep_new_ibi()
855 ibi->slot->len = 0; in hci_pio_prep_new_ibi()
856 ibi->data_ptr = ibi->slot->data; in hci_pio_prep_new_ibi()
861 static void hci_pio_free_ibi_slot(struct i3c_hci *hci, struct hci_pio_data *pio) in hci_pio_free_ibi_slot() argument
863 struct hci_pio_ibi_data *ibi = &pio->ibi; in hci_pio_free_ibi_slot()
866 if (ibi->slot) { in hci_pio_free_ibi_slot()
867 dev_ibi = ibi->slot->dev->common.master_priv; in hci_pio_free_ibi_slot()
868 i3c_generic_ibi_recycle_slot(dev_ibi->pool, ibi->slot); in hci_pio_free_ibi_slot()
869 ibi->slot = NULL; in hci_pio_free_ibi_slot()
873 static bool hci_pio_process_ibi(struct i3c_hci *hci, struct hci_pio_data *pio) in hci_pio_process_ibi() argument
875 struct hci_pio_ibi_data *ibi = &pio->ibi; in hci_pio_process_ibi()
877 if (!ibi->slot && !ibi->seg_cnt && ibi->last_seg) in hci_pio_process_ibi()
878 if (!hci_pio_prep_new_ibi(hci, pio)) in hci_pio_process_ibi()
885 if (ibi->slot) { in hci_pio_process_ibi()
886 if (!hci_pio_get_ibi_segment(hci, pio)) in hci_pio_process_ibi()
888 ibi->slot->len += ibi->seg_len; in hci_pio_process_ibi()
889 ibi->data_ptr += ibi->seg_len; in hci_pio_process_ibi()
890 if (ibi->last_seg) { in hci_pio_process_ibi()
892 i3c_master_queue_ibi(ibi->slot->dev, ibi->slot); in hci_pio_process_ibi()
893 ibi->slot = NULL; in hci_pio_process_ibi()
894 hci_pio_set_ibi_thresh(hci, pio, 1); in hci_pio_process_ibi()
897 } else if (ibi->seg_cnt) { in hci_pio_process_ibi()
899 * No slot but a non-zero count. This is the result in hci_pio_process_ibi()
904 hci_pio_set_ibi_thresh(hci, pio, 1); in hci_pio_process_ibi()
909 } while (--ibi->seg_cnt); in hci_pio_process_ibi()
910 if (ibi->last_seg) in hci_pio_process_ibi()
915 hci_pio_set_ibi_thresh(hci, pio, 1); in hci_pio_process_ibi()
920 if (ibi->addr != ibi_addr) { in hci_pio_process_ibi()
922 dev_err(&hci->master.dev, in hci_pio_process_ibi()
924 ibi->addr, ibi_addr); in hci_pio_process_ibi()
925 hci_pio_free_ibi_slot(hci, pio); in hci_pio_process_ibi()
927 ibi->last_seg = ibi_status & IBI_LAST_STATUS; in hci_pio_process_ibi()
928 ibi->seg_len = FIELD_GET(IBI_DATA_LENGTH, ibi_status); in hci_pio_process_ibi()
929 ibi->seg_cnt = ibi->seg_len; in hci_pio_process_ibi()
930 if (ibi->slot && ibi->slot->len + ibi->seg_len > ibi->max_len) { in hci_pio_process_ibi()
931 dev_err(&hci->master.dev, in hci_pio_process_ibi()
933 ibi->slot->len + ibi->seg_len, ibi->max_len); in hci_pio_process_ibi()
934 hci_pio_free_ibi_slot(hci, pio); in hci_pio_process_ibi()
941 static int hci_pio_request_ibi(struct i3c_hci *hci, struct i3c_dev_desc *dev, in hci_pio_request_ibi() argument
950 return -ENOMEM; in hci_pio_request_ibi()
956 dev_ibi->pool = pool; in hci_pio_request_ibi()
957 dev_ibi->max_len = req->max_payload_len; in hci_pio_request_ibi()
958 dev_data->ibi_data = dev_ibi; in hci_pio_request_ibi()
962 static void hci_pio_free_ibi(struct i3c_hci *hci, struct i3c_dev_desc *dev) in hci_pio_free_ibi() argument
965 struct hci_pio_dev_ibi_data *dev_ibi = dev_data->ibi_data; in hci_pio_free_ibi()
967 dev_data->ibi_data = NULL; in hci_pio_free_ibi()
968 i3c_generic_ibi_free_pool(dev_ibi->pool); in hci_pio_free_ibi()
972 static void hci_pio_recycle_ibi_slot(struct i3c_hci *hci, in hci_pio_recycle_ibi_slot() argument
977 struct hci_pio_dev_ibi_data *dev_ibi = dev_data->ibi_data; in hci_pio_recycle_ibi_slot()
979 i3c_generic_ibi_recycle_slot(dev_ibi->pool, slot); in hci_pio_recycle_ibi_slot()
982 static bool hci_pio_irq_handler(struct i3c_hci *hci, unsigned int unused) in hci_pio_irq_handler() argument
984 struct hci_pio_data *pio = hci->io_data; in hci_pio_irq_handler()
987 spin_lock(&pio->lock); in hci_pio_irq_handler()
989 DBG("(in) status: %#x/%#x", status, pio->enabled_irqs); in hci_pio_irq_handler()
990 status &= pio->enabled_irqs | STAT_LATENCY_WARNINGS; in hci_pio_irq_handler()
992 spin_unlock(&pio->lock); in hci_pio_irq_handler()
997 hci_pio_process_ibi(hci, pio); in hci_pio_irq_handler()
1000 if (hci_pio_process_rx(hci, pio)) in hci_pio_irq_handler()
1001 pio->enabled_irqs &= ~STAT_RX_THLD; in hci_pio_irq_handler()
1003 if (hci_pio_process_tx(hci, pio)) in hci_pio_irq_handler()
1004 pio->enabled_irqs &= ~STAT_TX_THLD; in hci_pio_irq_handler()
1006 if (hci_pio_process_resp(hci, pio)) in hci_pio_irq_handler()
1007 pio->enabled_irqs &= ~STAT_RESP_READY; in hci_pio_irq_handler()
1011 dev_warn_ratelimited(&hci->master.dev, in hci_pio_irq_handler()
1018 hci_pio_err(hci, pio, status & STAT_ALL_ERRORS); in hci_pio_irq_handler()
1022 if (hci_pio_process_cmd(hci, pio)) in hci_pio_irq_handler()
1023 pio->enabled_irqs &= ~STAT_CMD_QUEUE_READY; in hci_pio_irq_handler()
1025 pio_reg_write(INTR_SIGNAL_ENABLE, pio->enabled_irqs); in hci_pio_irq_handler()
1028 spin_unlock(&pio->lock); in hci_pio_irq_handler()