]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
irqchip/sg2042-msi: Add the Sophgo SG2044 MSI interrupt controller
authorInochi Amaoto <inochiama@gmail.com>
Sun, 13 Apr 2025 22:49:15 +0000 (06:49 +0800)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 14 Apr 2025 17:35:36 +0000 (19:35 +0200)
Add support for Sophgo SG2044 MSI interrupt controller.

Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Chen Wang <wangchen20@iscas.ac.cn> # SG2042
Reviewed-by: Chen Wang <unicorn_wang@outlook.com>
Link: https://lore.kernel.org/all/20250413224922.69719-5-inochiama@gmail.com
drivers/irqchip/irq-sg2042-msi.c

index 325a83c1757327cc310a459ca85eec2a1f029e76..8a83c690b760934211b79b3390c1590b01873c5e 100644 (file)
@@ -94,6 +94,35 @@ static const struct irq_chip sg2042_msi_middle_irq_chip = {
        .irq_compose_msi_msg    = sg2042_msi_irq_compose_msi_msg,
 };
 
+static void sg2044_msi_irq_ack(struct irq_data *d)
+{
+       struct sg204x_msi_chipdata *data = irq_data_get_irq_chip_data(d);
+
+       writel(0, (u32 *)data->reg_clr + d->hwirq);
+       irq_chip_ack_parent(d);
+}
+
+static void sg2044_msi_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
+{
+       struct sg204x_msi_chipdata *data = irq_data_get_irq_chip_data(d);
+       phys_addr_t doorbell = data->doorbell_addr + 4 * (d->hwirq / 32);
+
+       msg->address_lo = lower_32_bits(doorbell);
+       msg->address_hi = upper_32_bits(doorbell);
+       msg->data = d->hwirq % 32;
+}
+
+static struct irq_chip sg2044_msi_middle_irq_chip = {
+       .name                   = "SG2044 MSI",
+       .irq_ack                = sg2044_msi_irq_ack,
+       .irq_mask               = irq_chip_mask_parent,
+       .irq_unmask             = irq_chip_unmask_parent,
+#ifdef CONFIG_SMP
+       .irq_set_affinity       = irq_chip_set_affinity_parent,
+#endif
+       .irq_compose_msi_msg    = sg2044_msi_irq_compose_msi_msg,
+};
+
 static int sg204x_msi_parent_domain_alloc(struct irq_domain *domain, unsigned int virq, int hwirq)
 {
        struct sg204x_msi_chipdata *data = domain->host_data;
@@ -132,13 +161,11 @@ static int sg204x_msi_middle_domain_alloc(struct irq_domain *domain, unsigned in
                irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
                                              data->chip_info->irqchip, data);
        }
-
        return 0;
 
 err_hwirq:
        sg204x_msi_free_hwirq(data, hwirq, nr_irqs);
        irq_domain_free_irqs_parent(domain, virq, i);
-
        return err;
 }
 
@@ -172,6 +199,22 @@ static const struct msi_parent_ops sg2042_msi_parent_ops = {
        .init_dev_msi_info      = msi_lib_init_dev_msi_info,
 };
 
+#define SG2044_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS |  \
+                                  MSI_FLAG_USE_DEF_CHIP_OPS)
+
+#define SG2044_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK |   \
+                                   MSI_FLAG_PCI_MSIX)
+
+static const struct msi_parent_ops sg2044_msi_parent_ops = {
+       .required_flags         = SG2044_MSI_FLAGS_REQUIRED,
+       .supported_flags        = SG2044_MSI_FLAGS_SUPPORTED,
+       .chip_flags             = MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
+       .bus_select_mask        = MATCH_PCI_MSI,
+       .bus_select_token       = DOMAIN_BUS_NEXUS,
+       .prefix                 = "SG2044-",
+       .init_dev_msi_info      = msi_lib_init_dev_msi_info,
+};
+
 static int sg204x_msi_init_domains(struct sg204x_msi_chipdata *data,
                                   struct irq_domain *plic_domain, struct device *dev)
 {
@@ -265,8 +308,14 @@ static const struct sg204x_msi_chip_info sg2042_chip_info = {
        .parent_ops     = &sg2042_msi_parent_ops,
 };
 
+static const struct sg204x_msi_chip_info sg2044_chip_info = {
+       .irqchip        = &sg2044_msi_middle_irq_chip,
+       .parent_ops     = &sg2044_msi_parent_ops,
+};
+
 static const struct of_device_id sg2042_msi_of_match[] = {
        { .compatible   = "sophgo,sg2042-msi", .data    = &sg2042_chip_info },
+       { .compatible   = "sophgo,sg2044-msi", .data    = &sg2044_chip_info },
        { }
 };