1

irqchip/loongson-pch-msi: Switch to MSI parent domains

Remove the global PCI/MSI irqdomain implementation and provide the
required MSI parent functionality by filling in msi_parent_ops, so the
PCI/MSI code can detect the new parent and setup per-device MSI domains.

Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Tianyang Zhang <zhangtianyang@loongson.cn>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20240815112608.26925-2-zhangtianyang@loongson.cn
This commit is contained in:
Huacai Chen 2024-08-15 19:26:07 +08:00 committed by Thomas Gleixner
parent e68ac2b488
commit 0b3af7591d
2 changed files with 24 additions and 35 deletions

View File

@ -685,6 +685,7 @@ config LOONGSON_PCH_MSI
depends on PCI depends on PCI
default MACH_LOONGSON64 default MACH_LOONGSON64
select IRQ_DOMAIN_HIERARCHY select IRQ_DOMAIN_HIERARCHY
select IRQ_MSI_LIB
select PCI_MSI select PCI_MSI
help help
Support for the Loongson PCH MSI Controller. Support for the Loongson PCH MSI Controller.

View File

@ -15,6 +15,8 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "irq-msi-lib.h"
static int nr_pics; static int nr_pics;
struct pch_msi_data { struct pch_msi_data {
@ -27,26 +29,6 @@ struct pch_msi_data {
static struct fwnode_handle *pch_msi_handle[MAX_IO_PICS]; static struct fwnode_handle *pch_msi_handle[MAX_IO_PICS];
static void pch_msi_mask_msi_irq(struct irq_data *d)
{
pci_msi_mask_irq(d);
irq_chip_mask_parent(d);
}
static void pch_msi_unmask_msi_irq(struct irq_data *d)
{
irq_chip_unmask_parent(d);
pci_msi_unmask_irq(d);
}
static struct irq_chip pch_msi_irq_chip = {
.name = "PCH PCI MSI",
.irq_mask = pch_msi_mask_msi_irq,
.irq_unmask = pch_msi_unmask_msi_irq,
.irq_ack = irq_chip_ack_parent,
.irq_set_affinity = irq_chip_set_affinity_parent,
};
static int pch_msi_allocate_hwirq(struct pch_msi_data *priv, int num_req) static int pch_msi_allocate_hwirq(struct pch_msi_data *priv, int num_req)
{ {
int first; int first;
@ -85,12 +67,6 @@ static void pch_msi_compose_msi_msg(struct irq_data *data,
msg->data = data->hwirq; msg->data = data->hwirq;
} }
static struct msi_domain_info pch_msi_domain_info = {
.flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX,
.chip = &pch_msi_irq_chip,
};
static struct irq_chip middle_irq_chip = { static struct irq_chip middle_irq_chip = {
.name = "PCH MSI", .name = "PCH MSI",
.irq_mask = irq_chip_mask_parent, .irq_mask = irq_chip_mask_parent,
@ -155,13 +131,31 @@ static void pch_msi_middle_domain_free(struct irq_domain *domain,
static const struct irq_domain_ops pch_msi_middle_domain_ops = { static const struct irq_domain_ops pch_msi_middle_domain_ops = {
.alloc = pch_msi_middle_domain_alloc, .alloc = pch_msi_middle_domain_alloc,
.free = pch_msi_middle_domain_free, .free = pch_msi_middle_domain_free,
.select = msi_lib_irq_domain_select,
};
#define PCH_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
MSI_FLAG_USE_DEF_CHIP_OPS | \
MSI_FLAG_PCI_MSI_MASK_PARENT)
#define PCH_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \
MSI_FLAG_PCI_MSIX | \
MSI_FLAG_MULTI_PCI_MSI)
static struct msi_parent_ops pch_msi_parent_ops = {
.required_flags = PCH_MSI_FLAGS_REQUIRED,
.supported_flags = PCH_MSI_FLAGS_SUPPORTED,
.bus_select_mask = MATCH_PCI_MSI,
.bus_select_token = DOMAIN_BUS_NEXUS,
.prefix = "PCH-",
.init_dev_msi_info = msi_lib_init_dev_msi_info,
}; };
static int pch_msi_init_domains(struct pch_msi_data *priv, static int pch_msi_init_domains(struct pch_msi_data *priv,
struct irq_domain *parent, struct irq_domain *parent,
struct fwnode_handle *domain_handle) struct fwnode_handle *domain_handle)
{ {
struct irq_domain *middle_domain, *msi_domain; struct irq_domain *middle_domain;
middle_domain = irq_domain_create_hierarchy(parent, 0, priv->num_irqs, middle_domain = irq_domain_create_hierarchy(parent, 0, priv->num_irqs,
domain_handle, domain_handle,
@ -174,14 +168,8 @@ static int pch_msi_init_domains(struct pch_msi_data *priv,
irq_domain_update_bus_token(middle_domain, DOMAIN_BUS_NEXUS); irq_domain_update_bus_token(middle_domain, DOMAIN_BUS_NEXUS);
msi_domain = pci_msi_create_irq_domain(domain_handle, middle_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
&pch_msi_domain_info, middle_domain->msi_parent_ops = &pch_msi_parent_ops;
middle_domain);
if (!msi_domain) {
pr_err("Failed to create PCI MSI domain\n");
irq_domain_remove(middle_domain);
return -ENOMEM;
}
return 0; return 0;
} }