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

From: Cristian Marussi
Date: Wed Mar 29 2023 - 11:40:16 EST


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@xxxxxxx>
---
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