From nobody Mon Dec 1 21:32:47 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E0B5E28727A for ; Mon, 1 Dec 2025 06:51:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764571896; cv=none; b=FcOj0rPoX9r0gCejXfImdyZnoyLgbWv/GKbjDA0HjPX5iDEe0Yvy8B58RmT+LCRvX/yF6pgoKiH+kIrvQeXFZkSJc9iSQ2uDgGcKA4eLUuVdy+T7wPZmGBUSdWQW5sd2Af8WmMaLzQvA5i5+2E1PnFQd9VLwNYkNiKptFG2Mjy8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764571896; c=relaxed/simple; bh=NiaYmOIJCMNtjGEGzP0wFGxoo5F4ZTm9179sUJeyoCE=; h=From:To:Cc:Subject:References:Message-ID:Content-Type: MIME-Version:Date; b=UBUn99o2ovLhmcqX5kGlZEk4qbYmYM4Ijahy1wh4uViLRBwJHxppUBKNeSLCMStvht6Fl9T9RoH+pdH+kVaJjpZeDvWBw6ND32ehee0s0NZWVX71ea/4ABhQfY5tpE7mhxI7M4LzW1PyKF3WoDqTlFOAnPJa4o4KKs0HJWxCU2U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=h4/pdmzw; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=xIB9zl70; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="h4/pdmzw"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="xIB9zl70" From: Thomas Gleixner DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1764571892; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: references:references; bh=82hQmG08tLbRvYJncr/JHFwy0CmWB08OSuqXamwsrMY=; b=h4/pdmzwpCv0D8b/mo5+5dg1qFPRad/y37zX1t8T5HDRi//X+LHvPxxq/BhQpm/hsYT5Lc KAv4mO1YV6/8syHlwL02cC+pBIS+ayG3fLWyBKS1CMkYqQyRyZTWtmm82yR+WNJQHVyZyQ EJvfgqd6Jp3opTA3gT6Fqqmpy89evNqbJzAdJeuCNaHlS+heXgJgNW53fFXA9Gq3VBKy+O rwb88Cyx+14pOZaAf9453+PHOXm/+hteeWlkgwzDuqU6yf7syAyW3yZX4/BjwGv9OgUuq9 oSN1z7jNumsvoz2ditNW/+r9gZ2d5pbv53R4LZClbvci1AQmlhbFtoy0Q80DZw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1764571892; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: references:references; bh=82hQmG08tLbRvYJncr/JHFwy0CmWB08OSuqXamwsrMY=; b=xIB9zl70TNZ9HM7f61eo1oXR4M5PBlwRgck+oaJuo/Rfy8AuBCF7gVCikhtCDhatIzLIka 0+SbKrNvx2lq/LCQ== To: Linus Torvalds Cc: linux-kernel@vger.kernel.org, x86@kernel.org Subject: [GIT pull] irq/msi for v6.19-rc1 References: <176457119565.1888260.10012195384143368631.tglx@xen13> Message-ID: <176457121420.1888260.1505338022841590073.tglx@xen13> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Mon, 1 Dec 2025 07:51:27 +0100 (CET) Linus, please pull the latest irq/msi branch from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-msi-2025-1= 1-30 up to: 9c1fbc56ca0a: irqchip/gic-its: Rework platform MSI deviceID detecti= on Updates for [PCI] MSI related code: - Remove one variant of PCI/MSI management as all users have been converted to use per device domains. That reduces the variants to two: The modern and the real archaic legacy variant, which keeps the usual suspects in the museum category alive. - Rework the platform MSI device ID detection mechanism in the ARM GIC world to address resource leaks, duplicated code and other details. This requires a corresponding preparatory step in the PCI/iproc driver. - Trivial core code cleanups =20 Thanks, tglx ------------------> Christophe JAILLET (1): genirq/msi: Slightly simplify msi_domain_alloc() Lorenzo Pieralisi (2): PCI: iproc: Implement MSI controller node detection with of_msi_xlate= () irqchip/gic-its: Rework platform MSI deviceID detection Nam Cao (1): PCI/MSI: Delete pci_msi_create_irq_domain() drivers/irqchip/irq-gic-its-msi-parent.c | 91 ++++++++--------------------= ---- drivers/pci/controller/pcie-iproc.c | 22 ++------ drivers/pci/msi/irqdomain.c | 90 ----------------------------= --- include/linux/msi.h | 3 -- kernel/irq/msi.c | 2 +- 5 files changed, 29 insertions(+), 179 deletions(-) diff --git a/drivers/irqchip/irq-gic-its-msi-parent.c b/drivers/irqchip/irq= -gic-its-msi-parent.c index eb1473f1448a..12f45228c867 100644 --- a/drivers/irqchip/irq-gic-its-msi-parent.c +++ b/drivers/irqchip/irq-gic-its-msi-parent.c @@ -142,83 +142,38 @@ static int its_v5_pci_msi_prepare(struct irq_domain *= domain, struct device *dev, #define its_v5_pci_msi_prepare NULL #endif /* !CONFIG_PCI_MSI */ =20 -static int of_pmsi_get_dev_id(struct irq_domain *domain, struct device *de= v, - u32 *dev_id) +static int of_pmsi_get_msi_info(struct irq_domain *domain, struct device *= dev, u32 *dev_id, + phys_addr_t *pa) { - int ret, index =3D 0; + struct of_phandle_iterator it; + int ret; =20 /* Suck the DeviceID out of the msi-parent property */ - do { - struct of_phandle_args args; - - ret =3D of_parse_phandle_with_args(dev->of_node, - "msi-parent", "#msi-cells", - index, &args); - if (args.np =3D=3D irq_domain_get_of_node(domain)) { - if (WARN_ON(args.args_count !=3D 1)) - return -EINVAL; - *dev_id =3D args.args[0]; - break; - } - index++; - } while (!ret); - - if (ret) { - struct device_node *np =3D NULL; + of_for_each_phandle(&it, ret, dev->of_node, "msi-parent", "#msi-cells", -= 1) { + /* GICv5 ITS domain matches the MSI controller node parent */ + struct device_node *np __free(device_node) =3D pa ? of_get_parent(it.nod= e) + : of_node_get(it.node); =20 - ret =3D of_map_id(dev->of_node, dev->id, "msi-map", "msi-map-mask", &np,= dev_id); - if (np) - of_node_put(np); - } + if (np =3D=3D irq_domain_get_of_node(domain)) { + u32 args; =20 - return ret; -} + if (WARN_ON(of_phandle_iterator_args(&it, &args, 1) !=3D 1)) + ret =3D -EINVAL; =20 -static int of_v5_pmsi_get_msi_info(struct irq_domain *domain, struct devic= e *dev, - u32 *dev_id, phys_addr_t *pa) -{ - int ret, index =3D 0; - /* - * Retrieve the DeviceID and the ITS translate frame node pointer - * out of the msi-parent property. - */ - do { - struct of_phandle_args args; - - ret =3D of_parse_phandle_with_args(dev->of_node, - "msi-parent", "#msi-cells", - index, &args); - if (ret) - break; - /* - * The IRQ domain fwnode is the msi controller parent - * in GICv5 (where the msi controller nodes are the - * ITS translate frames). - */ - if (args.np->parent =3D=3D irq_domain_get_of_node(domain)) { - if (WARN_ON(args.args_count !=3D 1)) - return -EINVAL; - *dev_id =3D args.args[0]; - - ret =3D its_translate_frame_address(args.np, pa); - if (ret) - return -ENODEV; - break; - } - index++; - } while (!ret); + if (!ret && pa) + ret =3D its_translate_frame_address(it.node, pa); =20 - if (ret) { - struct device_node *np =3D NULL; + if (!ret) + *dev_id =3D args; =20 - ret =3D of_map_id(dev->of_node, dev->id, "msi-map", "msi-map-mask", &np,= dev_id); - if (np) { - ret =3D its_translate_frame_address(np, pa); - of_node_put(np); + of_node_put(it.node); + return ret; } } =20 - return ret; + struct device_node *msi_ctrl __free(device_node) =3D NULL; + + return of_map_id(dev->of_node, dev->id, "msi-map", "msi-map-mask", &msi_c= trl, dev_id); } =20 int __weak iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id) @@ -234,7 +189,7 @@ static int its_pmsi_prepare(struct irq_domain *domain, = struct device *dev, int ret; =20 if (dev->of_node) - ret =3D of_pmsi_get_dev_id(domain->parent, dev, &dev_id); + ret =3D of_pmsi_get_msi_info(domain->parent, dev, &dev_id, NULL); else ret =3D iort_pmsi_get_dev_id(dev, &dev_id); if (ret) @@ -262,7 +217,7 @@ static int its_v5_pmsi_prepare(struct irq_domain *domai= n, struct device *dev, if (!dev->of_node) return -ENODEV; =20 - ret =3D of_v5_pmsi_get_msi_info(domain->parent, dev, &dev_id, &pa); + ret =3D of_pmsi_get_msi_info(domain->parent, dev, &dev_id, &pa); if (ret) return ret; =20 diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/p= cie-iproc.c index 22134e95574b..ccf71993ea35 100644 --- a/drivers/pci/controller/pcie-iproc.c +++ b/drivers/pci/controller/pcie-iproc.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -1337,29 +1338,16 @@ static int iproc_pcie_msi_steer(struct iproc_pcie *= pcie, =20 static int iproc_pcie_msi_enable(struct iproc_pcie *pcie) { - struct device_node *msi_node; + struct device_node *msi_node =3D NULL; int ret; =20 /* * Either the "msi-parent" or the "msi-map" phandle needs to exist * for us to obtain the MSI node. */ - - msi_node =3D of_parse_phandle(pcie->dev->of_node, "msi-parent", 0); - if (!msi_node) { - const __be32 *msi_map =3D NULL; - int len; - u32 phandle; - - msi_map =3D of_get_property(pcie->dev->of_node, "msi-map", &len); - if (!msi_map) - return -ENODEV; - - phandle =3D be32_to_cpup(msi_map + 1); - msi_node =3D of_find_node_by_phandle(phandle); - if (!msi_node) - return -ENODEV; - } + of_msi_xlate(pcie->dev, &msi_node, 0); + if (!msi_node) + return -ENODEV; =20 /* * Certain revisions of the iProc PCIe controller require additional diff --git a/drivers/pci/msi/irqdomain.c b/drivers/pci/msi/irqdomain.c index ce741ed9dc3f..a329060287b5 100644 --- a/drivers/pci/msi/irqdomain.c +++ b/drivers/pci/msi/irqdomain.c @@ -49,96 +49,6 @@ static void pci_msi_domain_write_msg(struct irq_data *ir= q_data, struct msi_msg * __pci_write_msi_msg(desc, msg); } =20 -/** - * pci_msi_domain_calc_hwirq - Generate a unique ID for an MSI source - * @desc: Pointer to the MSI descriptor - * - * The ID number is only used within the irqdomain. - */ -static irq_hw_number_t pci_msi_domain_calc_hwirq(struct msi_desc *desc) -{ - struct pci_dev *dev =3D msi_desc_to_pci_dev(desc); - - return (irq_hw_number_t)desc->msi_index | - pci_dev_id(dev) << 11 | - ((irq_hw_number_t)(pci_domain_nr(dev->bus) & 0xFFFFFFFF)) << 27; -} - -static void pci_msi_domain_set_desc(msi_alloc_info_t *arg, - struct msi_desc *desc) -{ - arg->desc =3D desc; - arg->hwirq =3D pci_msi_domain_calc_hwirq(desc); -} - -static struct msi_domain_ops pci_msi_domain_ops_default =3D { - .set_desc =3D pci_msi_domain_set_desc, -}; - -static void pci_msi_domain_update_dom_ops(struct msi_domain_info *info) -{ - struct msi_domain_ops *ops =3D info->ops; - - if (ops =3D=3D NULL) { - info->ops =3D &pci_msi_domain_ops_default; - } else { - if (ops->set_desc =3D=3D NULL) - ops->set_desc =3D pci_msi_domain_set_desc; - } -} - -static void pci_msi_domain_update_chip_ops(struct msi_domain_info *info) -{ - struct irq_chip *chip =3D info->chip; - - BUG_ON(!chip); - if (!chip->irq_write_msi_msg) - chip->irq_write_msi_msg =3D pci_msi_domain_write_msg; - if (!chip->irq_mask) - chip->irq_mask =3D pci_msi_mask_irq; - if (!chip->irq_unmask) - chip->irq_unmask =3D pci_msi_unmask_irq; -} - -/** - * pci_msi_create_irq_domain - Create a MSI interrupt domain - * @fwnode: Optional fwnode of the interrupt controller - * @info: MSI domain info - * @parent: Parent irq domain - * - * Updates the domain and chip ops and creates a MSI interrupt domain. - * - * Returns: - * A domain pointer or NULL in case of failure. - */ -struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode, - struct msi_domain_info *info, - struct irq_domain *parent) -{ - if (WARN_ON(info->flags & MSI_FLAG_LEVEL_CAPABLE)) - info->flags &=3D ~MSI_FLAG_LEVEL_CAPABLE; - - if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS) - pci_msi_domain_update_dom_ops(info); - if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) - pci_msi_domain_update_chip_ops(info); - - /* Let the core code free MSI descriptors when freeing interrupts */ - info->flags |=3D MSI_FLAG_FREE_MSI_DESCS; - - info->flags |=3D MSI_FLAG_ACTIVATE_EARLY | MSI_FLAG_DEV_SYSFS; - if (IS_ENABLED(CONFIG_GENERIC_IRQ_RESERVATION_MODE)) - info->flags |=3D MSI_FLAG_MUST_REACTIVATE; - - /* PCI-MSI is oneshot-safe */ - info->chip->flags |=3D IRQCHIP_ONESHOT_SAFE; - /* Let the core update the bus token */ - info->bus_token =3D DOMAIN_BUS_PCI_MSI; - - return msi_create_irq_domain(fwnode, info, parent); -} -EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain); - /* * Per device MSI[-X] domain functionality */ diff --git a/include/linux/msi.h b/include/linux/msi.h index d415dd15a0a9..8003e3218c46 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -701,9 +701,6 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct = msi_msg *msg); void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg); void pci_msi_mask_irq(struct irq_data *data); void pci_msi_unmask_irq(struct irq_data *data); -struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode, - struct msi_domain_info *info, - struct irq_domain *parent); u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *= pdev); u32 pci_msi_map_rid_ctlr_node(struct pci_dev *pdev, struct device_node **n= ode); struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev); diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index e7ad99254841..68886881fe10 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -706,7 +706,7 @@ static int msi_domain_alloc(struct irq_domain *domain, = unsigned int virq, irq_hw_number_t hwirq =3D ops->get_hwirq(info, arg); int i, ret; =20 - if (irq_find_mapping(domain, hwirq) > 0) + if (irq_resolve_mapping(domain, hwirq)) return -EEXIST; =20 if (domain->parent) {