From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 37D61C433E6 for ; Fri, 26 Feb 2021 20:11:25 +0000 (UTC) Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C2A1864F1F for ; Fri, 26 Feb 2021 20:11:24 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C2A1864F1F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=iommu-bounces@lists.linux-foundation.org Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 772016F9D4; Fri, 26 Feb 2021 20:11:24 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id XcbR0WAf7-JD; Fri, 26 Feb 2021 20:11:23 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTP id E55AC6F9C6; Fri, 26 Feb 2021 20:11:22 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 9FC1EC0019; Fri, 26 Feb 2021 20:11:22 +0000 (UTC) Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3B2CFC0001 for ; Fri, 26 Feb 2021 20:11:20 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 553F284346 for ; Fri, 26 Feb 2021 20:11:15 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id HAMRSJY2BDEW for ; Fri, 26 Feb 2021 20:11:14 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by smtp1.osuosl.org (Postfix) with ESMTPS id 6AB11842D2 for ; Fri, 26 Feb 2021 20:11:14 +0000 (UTC) IronPort-SDR: 4pFSKgnQJbIbIt4g9k2gqUmmTBloFKyeAdBM2l2t8fglunyL9TkGI8rQ+qS2ZggSZ5dge2I6yV kTNCWO049eOw== X-IronPort-AV: E=McAfee;i="6000,8403,9907"; a="247407451" X-IronPort-AV: E=Sophos;i="5.81,209,1610438400"; d="scan'208";a="247407451" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Feb 2021 12:11:13 -0800 IronPort-SDR: 2O8Bb0nl9sJ8koTH0I8Pftu3UbS4RCIhJBkkw7Eheb1P/ldui9Khm3YVSEW/cT8K8rEgkdiV+6 XwmX7rteDhWw== X-IronPort-AV: E=Sophos;i="5.81,209,1610438400"; d="scan'208";a="405109439" Received: from megha-z97x-ud7-th.sc.intel.com ([143.183.85.154]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-SHA; 26 Feb 2021 12:11:12 -0800 From: Megha Dey To: tglx@linutronix.de Subject: [Patch V2 06/13] platform-msi: Add device MSI infrastructure Date: Fri, 26 Feb 2021 12:11:10 -0800 Message-Id: <1614370277-23235-7-git-send-email-megha.dey@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1614370277-23235-1-git-send-email-megha.dey@intel.com> References: <1614370277-23235-1-git-send-email-megha.dey@intel.com> Cc: alex.williamson@redhat.com, kevin.tian@intel.com, tony.luck@intel.com, dave.jiang@intel.com, ashok.raj@intel.com, kvm@vger.kernel.org, ravi.v.shankar@intel.com, maz@kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org, jgg@mellanox.com, megha.dey@intel.com, linux-pci@vger.kernel.org, bhelgaas@google.com, dan.j.williams@intel.com, dwmw@amazon.co.uk X-BeenThere: iommu@lists.linux-foundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Development issues for Linux IOMMU support List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: iommu-bounces@lists.linux-foundation.org Sender: "iommu" From: Thomas Gleixner Add device specific MSI domain infrastructure for devices which have their own resource management and interrupt chip. These devices are not related to PCI and contrary to platform MSI they do not share a common resource and interrupt chip. They provide their own domain specific resource management and interrupt chip. This utilizes the new alloc/free override in a non evil way which avoids having yet another set of specialized alloc/free functions. Just using msi_domain_alloc/free_irqs() is sufficient While initially it was suggested and tried to piggyback device MSI on platform MSI, the better variant is to reimplement platform MSI on top of device MSI. Reviewed-by: Tony Luck Signed-off-by: Thomas Gleixner Signed-off-by: Megha Dey --- drivers/base/platform-msi.c | 131 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/irqdomain.h | 1 + include/linux/msi.h | 24 ++++++++ kernel/irq/Kconfig | 4 ++ 4 files changed, 160 insertions(+) diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c index 9d9ccfc..6127b3b 100644 --- a/drivers/base/platform-msi.c +++ b/drivers/base/platform-msi.c @@ -419,3 +419,134 @@ int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq, return err; } + +#ifdef CONFIG_DEVICE_MSI +/* + * Device specific MSI domain infrastructure for devices which have their + * own resource management and interrupt chip. These devices are not + * related to PCI and contrary to platform MSI they do not share a common + * resource and interrupt chip. They provide their own domain specific + * resource management and interrupt chip. + */ + +static void device_msi_free_msi_entries(struct device *dev) +{ + struct list_head *msi_list = dev_to_msi_list(dev); + struct msi_desc *entry, *tmp; + + list_for_each_entry_safe(entry, tmp, msi_list, list) { + list_del(&entry->list); + free_msi_entry(entry); + } +} + +/** + * device_msi_free_irqs - Free MSI interrupts assigned to a device + * @dev: Pointer to the device + * + * Frees the interrupt and the MSI descriptors. + */ +static void device_msi_free_irqs(struct irq_domain *domain, struct device *dev) +{ + __msi_domain_free_irqs(domain, dev); + device_msi_free_msi_entries(dev); +} + +/** + * device_msi_alloc_irqs - Allocate MSI interrupts for a device + * @dev: Pointer to the device + * @nvec: Number of vectors + * + * Allocates the required number of MSI descriptors and the corresponding + * interrupt descriptors. + */ +static int device_msi_alloc_irqs(struct irq_domain *domain, struct device *dev, int nvec) +{ + int i, ret = -ENOMEM; + + for (i = 0; i < nvec; i++) { + struct msi_desc *entry = alloc_msi_entry(dev, 1, NULL); + + if (!entry) + goto fail; + list_add_tail(&entry->list, dev_to_msi_list(dev)); + } + + ret = __msi_domain_alloc_irqs(domain, dev, nvec); + if (!ret) + return 0; +fail: + device_msi_free_msi_entries(dev); + return ret; +} + +static void device_msi_update_dom_ops(struct msi_domain_info *info) +{ + if (!info->ops->domain_alloc_irqs) + info->ops->domain_alloc_irqs = device_msi_alloc_irqs; + if (!info->ops->domain_free_irqs) + info->ops->domain_free_irqs = device_msi_free_irqs; + if (!info->ops->msi_prepare) + info->ops->msi_prepare = arch_msi_prepare; +} + +/** + * device_msi_create_msi_irq_domain - Create an irq domain for devices + * @fwnode: Firmware node of the interrupt controller + * @info: MSI domain info to configure the new domain + * @parent: Parent domain + */ +struct irq_domain *device_msi_create_irq_domain(struct fwnode_handle *fn, + struct msi_domain_info *info, + struct irq_domain *parent) +{ + struct irq_domain *domain; + + if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) + platform_msi_update_chip_ops(info); + + if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS) + device_msi_update_dom_ops(info); + + msi_domain_set_default_info_flags(info); + + domain = msi_create_irq_domain(fn, info, parent); + if (domain) + irq_domain_update_bus_token(domain, DOMAIN_BUS_DEVICE_MSI); + return domain; +} + +#ifdef CONFIG_PCI +#include + +/** + * pci_subdevice_msi_create_irq_domain - Create an irq domain for subdevices + * @pdev: Pointer to PCI device for which the subdevice domain is created + * @info: MSI domain info to configure the new domain + */ +struct irq_domain *pci_subdevice_msi_create_irq_domain(struct pci_dev *pdev, + struct msi_domain_info *info) +{ + struct irq_domain *domain, *pdev_msi; + struct fwnode_handle *fn; + + /* + * Retrieve the MSI domain of the underlying PCI device's MSI + * domain. The PCI device domain's parent domain is also the parent + * domain of the new subdevice domain. + */ + pdev_msi = dev_get_msi_domain(&pdev->dev); + if (!pdev_msi) + return NULL; + + fn = irq_domain_alloc_named_fwnode(dev_name(&pdev->dev)); + if (!fn) + return NULL; + domain = device_msi_create_irq_domain(fn, info, pdev_msi->parent); + if (!domain) + irq_domain_free_fwnode(fn); + return domain; +} +EXPORT_SYMBOL_GPL(pci_subdevice_msi_create_irq_domain); +#endif /* CONFIG_PCI */ +#endif /* CONFIG_DEVICE_MSI */ diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 42d1968..06c88ba 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -85,6 +85,7 @@ enum irq_domain_bus_token { DOMAIN_BUS_TI_SCI_INTA_MSI, DOMAIN_BUS_WAKEUP, DOMAIN_BUS_VMD_MSI, + DOMAIN_BUS_DEVICE_MSI, }; /** diff --git a/include/linux/msi.h b/include/linux/msi.h index f6e52de..46e879c 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -95,6 +95,18 @@ struct ti_sci_inta_msi_desc { }; /** + * device_msi_desc - Device MSI specific MSI descriptor data + * @priv: Pointer to device specific private data + * @priv_iomem: Pointer to device specific private io memory + * @hwirq: The hardware irq number in the device domain + */ +struct device_msi_desc { + void *priv; + void __iomem *priv_iomem; + u16 hwirq; +}; + +/** * struct msi_desc - Descriptor structure for MSI based interrupts * @list: List head for management * @irq: The base interrupt number @@ -166,6 +178,7 @@ struct msi_desc { struct platform_msi_desc platform; struct fsl_mc_msi_desc fsl_mc; struct ti_sci_inta_msi_desc inta; + struct device_msi_desc device_msi; }; }; @@ -457,6 +470,17 @@ void *platform_msi_get_host_data(struct irq_domain *domain); void msi_domain_set_default_info_flags(struct msi_domain_info *info); #endif /* CONFIG_GENERIC_MSI_IRQ_DOMAIN */ +#ifdef CONFIG_DEVICE_MSI +struct irq_domain *device_msi_create_irq_domain(struct fwnode_handle *fn, + struct msi_domain_info *info, + struct irq_domain *parent); + +# ifdef CONFIG_PCI +struct irq_domain *pci_subdevice_msi_create_irq_domain(struct pci_dev *pdev, + struct msi_domain_info *info); +# endif +#endif /* CONFIG_DEVICE_MSI */ + #ifdef CONFIG_PCI_MSI_IRQ_DOMAIN void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg); struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode, diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index d79ef24..7223327 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig @@ -89,6 +89,10 @@ config GENERIC_MSI_IRQ_DOMAIN select IRQ_DOMAIN_HIERARCHY select GENERIC_MSI_IRQ +config DEVICE_MSI + bool + select GENERIC_MSI_IRQ_DOMAIN + config IRQ_MSI_IOMMU bool -- 2.7.4 _______________________________________________ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu