[PATCH 10/11] PCI: apple: Convert to MSI parent infrastructure
From: Marc Zyngier <maz@kernel.org>
Date: 2024-12-04 12:46:10
Also in:
linux-iommu, linux-pci, linux-riscv, lkml, loongarch
Subsystem:
apple pcie controller driver, pci native host bridge and endpoint drivers, pci subsystem, the rest · Maintainers:
Marc Zyngier, Lorenzo Pieralisi, Krzysztof Wilczyński, Manivannan Sadhasivam, Bjorn Helgaas, Linus Torvalds
In an effort to move arm64 away from the legacy MSI setup, convert the apple PCIe driver to the MSI-parent infrastructure and let each device have its own MSI domain. Signed-off-by: Marc Zyngier <maz@kernel.org> --- drivers/pci/controller/Kconfig | 1 + drivers/pci/controller/pcie-apple.c | 57 ++++++++--------------------- 2 files changed, 17 insertions(+), 41 deletions(-)
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 9800b76810540..98a62f4559dfd 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig@@ -40,6 +40,7 @@ config PCIE_APPLE depends on OF depends on PCI_MSI select PCI_HOST_COMMON + select IRQ_MSI_LIB help Say Y here if you want to enable PCIe controller support on Apple system-on-chips, like the Apple M1. This is required for the USB
diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
index fefab2758a064..945070ac31cf8 100644
--- a/drivers/pci/controller/pcie-apple.c
+++ b/drivers/pci/controller/pcie-apple.c@@ -22,6 +22,7 @@ #include <linux/kernel.h> #include <linux/iopoll.h> #include <linux/irqchip/chained_irq.h> +#include <linux/irqchip/irq-msi-lib.h> #include <linux/irqdomain.h> #include <linux/list.h> #include <linux/module.h>
@@ -134,7 +135,6 @@ struct apple_pcie { struct mutex lock; struct device *dev; void __iomem *base; - struct irq_domain *domain; unsigned long *bitmap; struct list_head ports; struct completion event;
@@ -163,27 +163,6 @@ static void rmw_clear(u32 clr, void __iomem *addr) writel_relaxed(readl_relaxed(addr) & ~clr, addr); } -static void apple_msi_top_irq_mask(struct irq_data *d) -{ - pci_msi_mask_irq(d); - irq_chip_mask_parent(d); -} - -static void apple_msi_top_irq_unmask(struct irq_data *d) -{ - pci_msi_unmask_irq(d); - irq_chip_unmask_parent(d); -} - -static struct irq_chip apple_msi_top_chip = { - .name = "PCIe MSI", - .irq_mask = apple_msi_top_irq_mask, - .irq_unmask = apple_msi_top_irq_unmask, - .irq_eoi = irq_chip_eoi_parent, - .irq_set_affinity = irq_chip_set_affinity_parent, - .irq_set_type = irq_chip_set_type_parent, -}; - static void apple_msi_compose_msg(struct irq_data *data, struct msi_msg *msg) { msg->address_hi = upper_32_bits(DOORBELL_ADDR);
@@ -227,8 +206,7 @@ static int apple_msi_domain_alloc(struct irq_domain *domain, unsigned int virq, for (i = 0; i < nr_irqs; i++) { irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, - &apple_msi_bottom_chip, - domain->host_data); + &apple_msi_bottom_chip, pcie); } return 0;
@@ -252,12 +230,6 @@ static const struct irq_domain_ops apple_msi_domain_ops = { .free = apple_msi_domain_free, }; -static struct msi_domain_info apple_msi_info = { - .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | - MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX), - .chip = &apple_msi_top_chip, -}; - static void apple_port_irq_mask(struct irq_data *data) { struct apple_pcie_port *port = irq_data_get_irq_chip_data(data);
@@ -596,6 +568,17 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, return 0; } +static const struct msi_parent_ops apple_msi_parent_ops = { + .supported_flags = (MSI_GENERIC_FLAGS_MASK | + MSI_FLAG_PCI_MSIX | + MSI_FLAG_MULTI_PCI_MSI), + .required_flags = (MSI_FLAG_USE_DEF_DOM_OPS | + MSI_FLAG_USE_DEF_CHIP_OPS | + MSI_FLAG_PCI_MSI_MASK_PARENT), + .bus_select_token = DOMAIN_BUS_PCI_MSI, + .init_dev_msi_info = msi_lib_init_dev_msi_info, +}; + static int apple_msi_init(struct apple_pcie *pcie) { struct fwnode_handle *fwnode = dev_fwnode(pcie->dev);
@@ -626,21 +609,13 @@ static int apple_msi_init(struct apple_pcie *pcie) return -ENXIO; } - parent = irq_domain_create_hierarchy(parent, 0, pcie->nvecs, fwnode, - &apple_msi_domain_ops, pcie); + parent = msi_create_parent_irq_domain(fwnode, &apple_msi_parent_ops, + &apple_msi_domain_ops, 0, + pcie->nvecs, pcie, parent); if (!parent) { dev_err(pcie->dev, "failed to create IRQ domain\n"); return -ENOMEM; } - irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS); - - pcie->domain = pci_msi_create_irq_domain(fwnode, &apple_msi_info, - parent); - if (!pcie->domain) { - dev_err(pcie->dev, "failed to create MSI domain\n"); - irq_domain_remove(parent); - return -ENOMEM; - } return 0; }
--
2.39.2