From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8F1EDC982D2 for ; Thu, 17 Sep 2026 19:14:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=pGANFpBVcF1jEiW4ZVLPiLTapAZwwdhPjAr3CtC8hbM=; b=rv2s6z9BrwP29k SjoCCvf3mIxrdNbpx7OCBLurql1lRc5jBq0ces6oePv4XGkRdYR+7G1+lS5SwnrG19lxTbjIRb7nr qYiB+Q5WVUwy+V8WPlYlOnvugZf/Z7VPIc7UcLvoPert7xJQRjJqa28xGu7iuSj6yN9B38WWDkeWv HueWKACj4SfOZBrthvqK7UdQbg6bUsmVGM8Y4QrrsRl5jpeUvfk7KE88NSn3F/UlThYAOkf2dlDJV 40FroxLoQJJRwo5iQcdyQLnc5j519iYZAW6joDScBy1WPzXEsOO71Hv6CwYXjYQchzohUykwQ7Vg9 Ip7mxWrk0jJzG/cRuEuw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x7HYx-0000000CJQ5-11rl; Thu, 17 Sep 2026 19:14:27 +0000 Received: from mgamail.intel.com ([192.198.163.4]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1x7HYu-0000000CJFz-1rok for linux-i3c@lists.infradead.org; Thu, 17 Sep 2026 19:14:25 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1789672464; x=1821208464; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=NJfhRSVxnF/bJ1RKlf/GniaeiWdPCGF/AvPKMBkUNtc=; b=K8BkJTNkm1dlk5kwywFFyQo2RZpNoVxdv34k3oikQGFy6T5ILqjd+Mzn syaL8GcSrIqy6duNkxtGLoddaR6OVESxYxlir+CVxyEHPp3gcAnjhbZeT WnbxYOnNq3dNDnHXQk/9ZKdd31LjxJN+wvV5SVD5Nb5glSo//gHMSqyLF 0+I/YMcLAlDeEGhdRInqPz68WfuOwMBwHquxX6f9BpIcqme9P5OmdUBL1 J5pV5TOCwaibOimZcOJPbbhLUFYPe7zRmJtG5H1S77pkNNwgek6ARZhf/ bEu+HODD07M2/pYypkH+U1NOpml1vhY47ul33sX2rJrguBw7W1swBEK+W Q==; X-CSE-ConnectionGUID: Y/AT0bmcQgyh/GzzUSENFA== X-CSE-MsgGUID: MSG6oypSR2uX4bHATxpcFw== X-IronPort-AV: E=McAfee;i="6800,10657,11905"; a="639935" X-IronPort-AV: E=Sophos;i="6.27,103,1787036400"; d="scan'208";a="639935" Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by fmvoesa114.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Sep 2026 12:14:24 -0700 X-CSE-ConnectionGUID: FepJlruGQiyau2TQOQum3A== X-CSE-MsgGUID: rJewsIzSQEuHZ7lY3Lw6pg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,103,1787036400"; d="scan'208";a="270271985" Received: from fpallare-mobl4.ger.corp.intel.com (HELO ahunter6-desk) ([10.245.245.5]) by fmviesa010-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Sep 2026 12:14:22 -0700 From: Adrian Hunter To: alexandre.belloni@bootlin.com Cc: Frank.Li@nxp.com, billy_tsai@aspeedtech.com, linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH V2 09/17] i3c: mipi-i3c-hci: Process multiple IBIs per interrupt Date: Thu, 17 Sep 2026 22:13:48 +0300 Message-ID: <20260917191356.133242-10-adrian.hunter@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260917191356.133242-1-adrian.hunter@intel.com> References: <20260917191356.133242-1-adrian.hunter@intel.com> MIME-Version: 1.0 Organization: Intel Finland Oy, Registered Address: c/o Alberga Business Park, 6 krs, Bertel Jungin Aukio 5, 02600 Espoo, Business Identity Code: 0357606 - 4, Domiciled in Helsinki X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260917_121424_498665_0455D17F X-CRM114-Status: GOOD ( 12.67 ) X-BeenThere: linux-i3c@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-i3c" Errors-To: linux-i3c-bounces+linux-i3c=archiver.kernel.org@lists.infradead.org INTR_IBI_READY indicates that one or more IBI Status Descriptors are present in the IBI ring. After clearing interrupt status, the interrupt handler processes only a single IBI even though additional IBIs may already be queued. The controller does not reassert INTR_IBI_READY solely because entries remain in the ring after interrupt status has been cleared. Consequently, the remaining IBIs are not processed until some later interrupt occurs, and can accumulate if IBIs arrive more often than the interrupt handler runs. Process all IBIs that are pending when the handler runs: capture the IBI enqueue pointer up front and continue until the dequeue pointer reaches that position. Fixes: 9ad9a52cce28 ("i3c/master: introduce the mipi-i3c-hci driver") Signed-off-by: Adrian Hunter --- Changes in V2: None drivers/i3c/master/mipi-i3c-hci/dma.c | 39 +++++++++++++++++---------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c index 5b195978f376..a798b0648922 100644 --- a/drivers/i3c/master/mipi-i3c-hci/dma.c +++ b/drivers/i3c/master/mipi-i3c-hci/dma.c @@ -868,25 +868,24 @@ static void hci_dma_recycle_ibi_slot(struct i3c_hci *hci, i3c_generic_ibi_recycle_slot(dev_ibi->pool, slot); } -static void hci_dma_process_ibi(struct i3c_hci *hci, struct hci_rh_data *rh) +static bool hci_dma_process_ibi(struct i3c_hci *hci, struct hci_rh_data *rh, + u32 *op1_val, unsigned int enq_ptr) { struct hci_rings_data *rings = hci->io_data; struct i3c_dev_desc *dev; struct i3c_hci_dev_data *dev_data; struct hci_dma_dev_ibi_data *dev_ibi; struct i3c_ibi_slot *slot; - u32 op1_val, op2_val, ibi_status_error; - unsigned int ptr, enq_ptr, deq_ptr; + u32 ibi_status_error; + unsigned int ptr, deq_ptr; unsigned int ibi_size, ibi_chunks, ibi_data_offset, first_part; int ibi_addr, last_ptr; void *ring_ibi_data; dma_addr_t ring_ibi_data_dma; - op1_val = rh_reg_read(RING_OPERATION1); - deq_ptr = FIELD_GET(RING_OP1_IBI_DEQ_PTR, op1_val); - - op2_val = rh_reg_read(RING_OPERATION2); - enq_ptr = FIELD_GET(RING_OP2_IBI_ENQ_PTR, op2_val); + deq_ptr = FIELD_GET(RING_OP1_IBI_DEQ_PTR, *op1_val); + if (deq_ptr == enq_ptr) + return false; ibi_status_error = 0; ibi_addr = -1; @@ -936,7 +935,7 @@ static void hci_dma_process_ibi(struct i3c_hci *hci, struct hci_rh_data *rh) dev_dbg(&hci->master.dev, "no LAST_STATUS available (e=%d d=%d)", enq_ptr, deq_ptr); - return; + return false; } deq_ptr = last_ptr + 1; deq_ptr %= rh->ibi_status_entries; @@ -1015,10 +1014,9 @@ static void hci_dma_process_ibi(struct i3c_hci *hci, struct hci_rh_data *rh) i3c_master_queue_ibi(dev, slot); done: - op1_val = rh_reg_read(RING_OPERATION1); - op1_val &= ~RING_OP1_IBI_DEQ_PTR; - op1_val |= FIELD_PREP(RING_OP1_IBI_DEQ_PTR, deq_ptr); - rh_reg_write(RING_OPERATION1, op1_val); + *op1_val &= ~RING_OP1_IBI_DEQ_PTR; + *op1_val |= FIELD_PREP(RING_OP1_IBI_DEQ_PTR, deq_ptr); + rh_reg_write(RING_OPERATION1, *op1_val); /* update the chunk pointer */ rh->ibi_chunk_ptr += ibi_chunks; @@ -1026,6 +1024,19 @@ static void hci_dma_process_ibi(struct i3c_hci *hci, struct hci_rh_data *rh) /* and tell the hardware about freed chunks */ rh_reg_write(CHUNK_CONTROL, rh_reg_read(CHUNK_CONTROL) + ibi_chunks); + + return true; +} + +static void hci_dma_drain_ibi_ring(struct i3c_hci *hci, struct hci_rh_data *rh) +{ + u32 op1_val = rh_reg_read(RING_OPERATION1); + u32 op2_val = rh_reg_read(RING_OPERATION2); + unsigned int enq_ptr = FIELD_GET(RING_OP2_IBI_ENQ_PTR, op2_val); + + /* Loop is bounded by enq_ptr. Further IBIs will re-assert INTR_IBI_READY */ + while (hci_dma_process_ibi(hci, rh, &op1_val, enq_ptr)) + ; } static bool hci_dma_irq_handler(struct i3c_hci *hci) @@ -1047,7 +1058,7 @@ static bool hci_dma_irq_handler(struct i3c_hci *hci) rh_reg_write(INTR_STATUS, status); if (status & INTR_IBI_READY) - hci_dma_process_ibi(hci, rh); + hci_dma_drain_ibi_ring(hci, rh); if (status & (INTR_TRANSFER_COMPLETION | INTR_TRANSFER_ERR)) hci_dma_xfer_done(hci, rh); if (status & INTR_RING_OP) -- 2.53.0 -- linux-i3c mailing list linux-i3c@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-i3c