]> www.infradead.org Git - users/hch/misc.git/commitdiff
mailbox: zynqmp-ipi: Fix SGI cleanup on unbind
authorHarini T <harini.t@amd.com>
Mon, 29 Sep 2025 07:37:23 +0000 (13:07 +0530)
committerJassi Brar <jassisinghbrar@gmail.com>
Mon, 6 Oct 2025 23:14:01 +0000 (18:14 -0500)
The driver incorrectly determines SGI vs SPI interrupts by checking IRQ
number < 16, which fails with dynamic IRQ allocation. During unbind,
this causes improper SGI cleanup leading to kernel crash.

Add explicit irq_type field to pdata for reliable identification of SGI
interrupts (type-2) and only clean up SGI resources when appropriate.

Fixes: 6ffb1635341b ("mailbox: zynqmp: handle SGI for shared IPI")
Signed-off-by: Harini T <harini.t@amd.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
drivers/mailbox/zynqmp-ipi-mailbox.c

index dddbef6b2cb8f55fd887541ffc9590c4c96ca3fe..967967b2b8a967ab97c00a50db4ba418735f8e83 100644 (file)
@@ -62,7 +62,8 @@
 #define DST_BIT_POS    9U
 #define SRC_BITMASK    GENMASK(11, 8)
 
-#define MAX_SGI 16
+/* Macro to represent SGI type for IPI IRQs */
+#define IPI_IRQ_TYPE_SGI       2
 
 /*
  * Module parameters
@@ -121,6 +122,7 @@ struct zynqmp_ipi_mbox {
  * @dev:                  device pointer corresponding to the Xilinx ZynqMP
  *                        IPI agent
  * @irq:                  IPI agent interrupt ID
+ * @irq_type:             IPI SGI or SPI IRQ type
  * @method:               IPI SMC or HVC is going to be used
  * @local_id:             local IPI agent ID
  * @virq_sgi:             IRQ number mapped to SGI
@@ -130,6 +132,7 @@ struct zynqmp_ipi_mbox {
 struct zynqmp_ipi_pdata {
        struct device *dev;
        int irq;
+       unsigned int irq_type;
        unsigned int method;
        u32 local_id;
        int virq_sgi;
@@ -887,7 +890,7 @@ static void zynqmp_ipi_free_mboxes(struct zynqmp_ipi_pdata *pdata)
        struct zynqmp_ipi_mbox *ipi_mbox;
        int i;
 
-       if (pdata->irq < MAX_SGI)
+       if (pdata->irq_type == IPI_IRQ_TYPE_SGI)
                xlnx_mbox_cleanup_sgi(pdata);
 
        i = pdata->num_mboxes - 1;
@@ -956,14 +959,16 @@ static int zynqmp_ipi_probe(struct platform_device *pdev)
                dev_err(dev, "failed to parse interrupts\n");
                goto free_mbox_dev;
        }
-       ret = out_irq.args[1];
+
+       /* Use interrupt type to distinguish SGI and SPI interrupts */
+       pdata->irq_type = out_irq.args[0];
 
        /*
         * If Interrupt number is in SGI range, then request SGI else request
         * IPI system IRQ.
         */
-       if (ret < MAX_SGI) {
-               pdata->irq = ret;
+       if (pdata->irq_type == IPI_IRQ_TYPE_SGI) {
+               pdata->irq = out_irq.args[1];
                ret = xlnx_mbox_init_sgi(pdev, pdata->irq, pdata);
                if (ret)
                        goto free_mbox_dev;