platform-msi: Track shared domain allocation
authorMarc Zyngier <maz@kernel.org>
Sun, 29 Nov 2020 13:52:06 +0000 (13:52 +0000)
committerMarc Zyngier <maz@kernel.org>
Fri, 11 Dec 2020 14:47:50 +0000 (14:47 +0000)
We have two flavours of platform-MSI:

- MSIs generated by devices for themselves (the usual case)

- MSIs generated on behalf of other devices, as the generating
  device is some form of bridge (either a wire-to-MSI bridge,
  or even a non-transparent PCI bridge that repaints the PCI
  requester ID).

In the latter case, the underlying interrupt architecture may need
to track this in order to keep the mapping alive even when no MSI
are currently being generated.

Add a set of flags to the generic msi_alloc_info_t structure, as
well as the MSI_ALLOC_FLAGS_PROXY_DEVICE flag that will get
advertized by the platform-MSI code when allocating an irqdomain
for a device.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Tested-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/r/20201129135208.680293-2-maz@kernel.org
drivers/base/platform-msi.c
include/asm-generic/msi.h

index c4a17e5edf8b4333b9e8df0977c3c450aaf9797e..2c1e2e0c1a59cc5f037f57aec963c8fcfa04a8e2 100644 (file)
@@ -59,9 +59,15 @@ static int platform_msi_init(struct irq_domain *domain,
        return irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
                                             info->chip, info->chip_data);
 }
+
+static void platform_msi_set_proxy_dev(msi_alloc_info_t *arg)
+{
+       arg->flags |= MSI_ALLOC_FLAGS_PROXY_DEVICE;
+}
 #else
 #define platform_msi_set_desc          NULL
 #define platform_msi_init              NULL
+#define platform_msi_set_proxy_dev(x)  do {} while(0)
 #endif
 
 static void platform_msi_update_dom_ops(struct msi_domain_info *info)
@@ -343,6 +349,7 @@ __platform_msi_create_device_domain(struct device *dev,
        if (!domain)
                goto free_priv;
 
+       platform_msi_set_proxy_dev(&data->arg);
        err = msi_domain_prepare_irqs(domain->parent, dev, nvec, &data->arg);
        if (err)
                goto free_domain;
index e6795f088bdddf4fa1bbd322a6a4a39280a6f3b6..1010e74cb8e054375e03230b2b281cc1d10c226d 100644 (file)
@@ -22,12 +22,16 @@ struct msi_desc;
 typedef struct msi_alloc_info {
        struct msi_desc                 *desc;
        irq_hw_number_t                 hwirq;
+       unsigned long                   flags;
        union {
                unsigned long           ul;
                void                    *ptr;
        } scratchpad[NUM_MSI_ALLOC_SCRATCHPAD_REGS];
 } msi_alloc_info_t;
 
+/* Device generating MSIs is proxying for another device */
+#define MSI_ALLOC_FLAGS_PROXY_DEVICE   (1UL << 0)
+
 #define GENERIC_MSI_DOMAIN_OPS         1
 
 #endif