[PATCH 2/2] mailbox: arm_mhuv2: Add support for multiple rx interrupt

Cristian Marussi cristian.marussi at arm.com
Wed Mar 29 08:39:36 PDT 2023


ARM MHUv2 can be configured to receive multiple interrupt related to the
receiver block, up to the maximum number of available channels, and not
necessarily grouped into a single combined interrupt.

Allow to register more interrupt for the RX block up to the maximum number
of interrupts supported by an AMBA device.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/mailbox/arm_mhuv2.c | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/mailbox/arm_mhuv2.c b/drivers/mailbox/arm_mhuv2.c
index c6d4957c4da8..89060bee1fb0 100644
--- a/drivers/mailbox/arm_mhuv2.c
+++ b/drivers/mailbox/arm_mhuv2.c
@@ -163,7 +163,6 @@ enum mhuv2_frame {
  * @send:	Base address of the register mapping region.
  * @recv:	Base address of the register mapping region.
  * @frame:	Frame type: RECEIVER_FRAME or SENDER_FRAME.
- * @irq:	Interrupt.
  * @windows:	Channel windows implemented by the platform.
  * @minor:	Minor version of the controller.
  * @length:	Length of the protocols array in bytes.
@@ -178,7 +177,6 @@ struct mhuv2 {
 		struct mhu2_recv_frame_reg __iomem *recv;
 	};
 	enum mhuv2_frame frame;
-	unsigned int irq;
 	unsigned int windows;
 	unsigned int minor;
 	unsigned int length;
@@ -991,7 +989,6 @@ static int mhuv2_tx_init(struct amba_device *adev, struct mhuv2 *mhu,
 		} else {
 			mhu->mbox.txdone_irq = true;
 			mhu->mbox.txdone_poll = false;
-			mhu->irq = adev->irq[0];
 
 			writel_relaxed_bitfield(1, &mhu->send->int_en, struct int_en_t, chcomb);
 
@@ -1029,18 +1026,23 @@ static int mhuv2_rx_init(struct amba_device *adev, struct mhuv2 *mhu,
 	mhu->windows = readl_relaxed_bitfield(&mhu->recv->mhu_cfg, struct mhu_cfg_t, num_ch);
 	mhu->minor = readl_relaxed_bitfield(&mhu->recv->aidr, struct aidr_t, arch_minor_rev);
 
-	mhu->irq = adev->irq[0];
-	if (!mhu->irq) {
-		dev_err(dev, "Missing receiver IRQ\n");
-		return -EINVAL;
-	}
+	for (i = 0; i < min_t(unsigned int, mhu->windows, AMBA_NR_IRQS); i++) {
+		if (!adev->irq[i]) {
+			/* At least one receiver IRQ is needed */
+			if (i == 0) {
+				dev_err(dev, "Missing receiver IRQ\n");
+				return -EINVAL;
+			}
+			continue;
+		}
 
-	ret = devm_request_threaded_irq(dev, mhu->irq, NULL,
-					mhuv2_receiver_interrupt, IRQF_ONESHOT,
-					"mhuv2-rx", mhu);
-	if (ret) {
-		dev_err(dev, "Failed to request rx IRQ\n");
-		return ret;
+		ret = devm_request_threaded_irq(dev, adev->irq[i], NULL,
+						mhuv2_receiver_interrupt, IRQF_ONESHOT,
+						"mhuv2-rx", mhu);
+		if (ret) {
+			dev_err(dev, "Failed to request rx IRQ\n");
+			return ret;
+		}
 	}
 
 	/* Mask all the channel windows */
-- 
2.34.1




More information about the linux-arm-kernel mailing list