From: Sunil V L <sunilvl@xxxxxxxxxxxxxxxx> Add ACPI support for the RISC-V RPMI system MSI based irqchip driver. Signed-off-by: Sunil V L <sunilvl@xxxxxxxxxxxxxxxx> Signed-off-by: Anup Patel <apatel@xxxxxxxxxxxxxxxx> --- drivers/irqchip/Kconfig | 2 +- drivers/irqchip/irq-riscv-rpmi-sysmsi.c | 34 ++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 2ae44354735b..cf96382113ce 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -599,7 +599,7 @@ config RISCV_IMSIC_PCI config RISCV_RPMI_SYSMSI bool - depends on MAILBOX + depends on RISCV && MAILBOX select IRQ_DOMAIN_HIERARCHY select GENERIC_MSI_IRQ default RISCV diff --git a/drivers/irqchip/irq-riscv-rpmi-sysmsi.c b/drivers/irqchip/irq-riscv-rpmi-sysmsi.c index 3022f0924c94..1f03241920bb 100644 --- a/drivers/irqchip/irq-riscv-rpmi-sysmsi.c +++ b/drivers/irqchip/irq-riscv-rpmi-sysmsi.c @@ -8,6 +8,7 @@ #include <linux/cpu.h> #include <linux/interrupt.h> #include <linux/irqchip.h> +#include <linux/irqchip/riscv-imsic.h> #include <linux/mailbox_client.h> #include <linux/mailbox/riscv-rpmi-message.h> #include <linux/module.h> @@ -215,6 +216,7 @@ static int rpmi_sysmsi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rpmi_sysmsi_priv *priv; + u32 id; int rc; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -223,6 +225,15 @@ static int rpmi_sysmsi_probe(struct platform_device *pdev) priv->dev = dev; platform_set_drvdata(pdev, priv); + if (!is_of_node(dev->fwnode)) { + rc = riscv_acpi_get_gsi_info(dev->fwnode, &priv->gsi_base, &id, + &priv->nr_irqs, NULL); + if (rc) { + dev_err(dev, "failed to find GSI mapping\n"); + return rc; + } + } + /* Setup mailbox client */ priv->client.dev = priv->dev; priv->client.rx_callback = NULL; @@ -252,8 +263,16 @@ static int rpmi_sysmsi_probe(struct platform_device *pdev) * then we need to set it explicitly before using any platform * MSI functions. */ - if (is_of_node(dev->fwnode)) + if (is_of_node(dev->fwnode)) { of_msi_configure(dev, to_of_node(dev->fwnode)); + } else { + struct irq_domain *msi_domain; + + msi_domain = irq_find_matching_fwnode(imsic_acpi_get_fwnode(dev), + DOMAIN_BUS_PLATFORM_MSI); + if (msi_domain) + dev_set_msi_domain(dev, msi_domain); + } if (!dev_get_msi_domain(dev)) return -EPROBE_DEFER; @@ -264,6 +283,10 @@ static int rpmi_sysmsi_probe(struct platform_device *pdev) priv->nr_irqs, priv, priv)) return dev_err_probe(dev, -ENOMEM, "failed to create MSI irq domain\n"); +#ifdef CONFIG_ACPI + if (!acpi_disabled) + acpi_dev_clear_dependencies(ACPI_COMPANION(dev)); +#endif dev_info(dev, "%d system MSIs registered\n", priv->nr_irqs); return 0; } @@ -273,10 +296,19 @@ static const struct of_device_id rpmi_sysmsi_match[] = { {} }; +#ifdef CONFIG_ACPI +static const struct acpi_device_id acpi_rpmi_sysmsi_match[] = { + { "RSCV0006", 0 }, + {} +}; +MODULE_DEVICE_TABLE(acpi, acpi_rpmi_sysmsi_match); +#endif + static struct platform_driver rpmi_sysmsi_driver = { .driver = { .name = "rpmi-sysmsi", .of_match_table = rpmi_sysmsi_match, + .acpi_match_table = ACPI_PTR(acpi_rpmi_sysmsi_match), }, .probe = rpmi_sysmsi_probe, }; -- 2.43.0