genirq/msi: Limit level-triggered MSI to platform devices
authorMarc Zyngier <marc.zyngier@arm.com>
Tue, 8 May 2018 12:14:31 +0000 (13:14 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Sun, 13 May 2018 13:58:59 +0000 (15:58 +0200)
Nobody would be insane enough to try and use level triggered
MSIs on PCI, but let's make sure it doesn't happen. Also,
let's mandate that the irqchip backing the platform MSI domain
is providing the IRQCHIP_SUPPORTS_LEVEL_MSI flag.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lkml.kernel.org/r/20180508121438.11301-3-marc.zyngier@arm.com
drivers/base/platform-msi.c
drivers/bus/fsl-mc/fsl-mc-msi.c
drivers/pci/msi.c
include/linux/irq.h

index 8e22073..60d6cc6 100644 (file)
@@ -101,6 +101,9 @@ static void platform_msi_update_chip_ops(struct msi_domain_info *info)
                chip->irq_set_affinity = msi_domain_set_affinity;
        if (!chip->irq_write_msi_msg)
                chip->irq_write_msi_msg = platform_msi_write_msg;
+       if (WARN_ON((info->flags & MSI_FLAG_LEVEL_CAPABLE) &&
+                   !(chip->flags & IRQCHIP_SUPPORTS_LEVEL_MSI)))
+               info->flags &= ~MSI_FLAG_LEVEL_CAPABLE;
 }
 
 static void platform_msi_free_descs(struct device *dev, int base, int nvec)
index ec35e25..8b9c66d 100644 (file)
@@ -163,6 +163,8 @@ struct irq_domain *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode,
 {
        struct irq_domain *domain;
 
+       if (WARN_ON((info->flags & MSI_FLAG_LEVEL_CAPABLE)))
+               info->flags &= ~MSI_FLAG_LEVEL_CAPABLE;
        if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS)
                fsl_mc_msi_update_dom_ops(info);
        if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
index 3025063..f45b74f 100644 (file)
@@ -1434,6 +1434,9 @@ struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode,
 {
        struct irq_domain *domain;
 
+       if (WARN_ON(info->flags & MSI_FLAG_LEVEL_CAPABLE))
+               info->flags &= ~MSI_FLAG_LEVEL_CAPABLE;
+
        if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS)
                pci_msi_domain_update_dom_ops(info);
        if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
index 65916a3..b206708 100644 (file)
@@ -512,6 +512,7 @@ enum {
        IRQCHIP_SKIP_SET_WAKE           = (1 <<  4),
        IRQCHIP_ONESHOT_SAFE            = (1 <<  5),
        IRQCHIP_EOI_THREADED            = (1 <<  6),
+       IRQCHIP_SUPPORTS_LEVEL_MSI      = (1 <<  7),
 };
 
 #include <linux/irqdesc.h>