From patchwork Mon Apr 4 08:52:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Nowicki X-Patchwork-Id: 8738921 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D54429F39A for ; Mon, 4 Apr 2016 08:55:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D21452022D for ; Mon, 4 Apr 2016 08:55:38 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D3D7A2021F for ; Mon, 4 Apr 2016 08:55:37 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1an0GN-0000A8-DQ; Mon, 04 Apr 2016 08:53:35 +0000 Received: from mail-lf0-x234.google.com ([2a00:1450:4010:c07::234]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1an0GB-0008U4-9b for linux-arm-kernel@lists.infradead.org; Mon, 04 Apr 2016 08:53:25 +0000 Received: by mail-lf0-x234.google.com with SMTP id g184so84740289lfb.3 for ; Mon, 04 Apr 2016 01:53:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=GVBny71WjYf+6PpqruzVGZFeCJEVGlErtKc1tQyMg8U=; b=XOuVGx1CTf3KDD7lRLytFuQ2BV/myh4BUZh8dsnPjKxtOS6O0ObUTrK2ydc3ccut5b gRV0sZKkK5uIOhS231BwTNvtdQHbBdcMKaMjysrRRn4Nf/96iBYPON9gOKdcA0uVOki8 C+sXAbs+Ik07Zm6v7kaiIQwnhNTYBudCAeMB3goLFDwZ7i87jMH87AhUFuL7I0VzglCi PrWsQb4Od7zAdWoERbvPdQkNlcTdg0uLC9HLrY5Hpbvhh5rMzygca05Xl03QGRpO+v1T L1S/iUGzkUhA7yy+vQKfr4OgDZR7ikvRcU751RmPPQ4otVj2HkBiv8kT1Xj3VECSQpRV XQ4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=GVBny71WjYf+6PpqruzVGZFeCJEVGlErtKc1tQyMg8U=; b=ejcg1aWqznDwKOErmxu9Ynrpd89k6U3MVwrKMuDGo56OREYFAKMOo4q3YiUjOvODWn CqQS7T89ohnoMiqU0OZ9FuAq8id5wN8llCdOLQ816m+KDyqdL0jYaxHAsnoFCeLtNd4O oMPmUjNc3YXuExEU66Dvjem+YmiqtSOtYAc59uIlOVzsqmQNlDiVtTynNwaU324x1oBJ INkBokQNZW/DxRCcXYiMZMbWFCG8RZvRLv2wdb3OFFAM1IpjnycO5kssYaWS6DAQ0LBA w05q8qAcCHYu+6fFB96Ub1x0M/o7TJifFeXE10CmvuCcbcmDjtO+kzBl9PSvF3of2tR8 HXAw== X-Gm-Message-State: AD7BkJLy5bvh+Yuvd4DILU75Zkrj7yIZ4AO+9ZuODV0sVQwG8tek/doQE+0+Gk4JBOptAg== X-Received: by 10.194.92.237 with SMTP id cp13mr11995258wjb.168.1459759981382; Mon, 04 Apr 2016 01:53:01 -0700 (PDT) Received: from tn-HP-4.semihalf.local (cardhu.semihalf.com. [213.17.239.108]) by smtp.gmail.com with ESMTPSA id js8sm27765096wjc.37.2016.04.04.01.52.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 04 Apr 2016 01:53:00 -0700 (PDT) From: Tomasz Nowicki To: marc.zyngier@arm.com, tglx@linutronix.de, jason@lakedaemon.net, rjw@rjwysocki.net, lorenzo.pieralisi@arm.com, robert.richter@caviumnetworks.com, shijie.huang@arm.com, Suravee.Suthikulpanit@amd.com, hanjun.guo@linaro.org Subject: [PATCH V4 1/7] acpi, pci: Setup MSI domain on a per-devices basis. Date: Mon, 4 Apr 2016 10:52:49 +0200 Message-Id: <1459759975-24097-2-git-send-email-tn@semihalf.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1459759975-24097-1-git-send-email-tn@semihalf.com> References: <1459759975-24097-1-git-send-email-tn@semihalf.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160404_015323_820064_AF927B4A X-CRM114-Status: GOOD ( 16.30 ) X-Spam-Score: -2.6 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: al.stone@linaro.org, graeme.gregory@linaro.org, Catalin.Marinas@arm.com, will.deacon@arm.com, linux-kernel@vger.kernel.org, okaya@codeaurora.org, linux-acpi@vger.kernel.org, ddaney.cavm@gmail.com, Tomasz Nowicki , mw@semihalf.com, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-5.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP It is now possible to provide information about which MSI controller to use on a per-device basis for DT. This patch supply this with ACPI support. In order to handle MSI domain on per-devices basis we need to add PCI device requester ID (RID) mapper, MSI domain provider and corresponding registration: pci_acpi_msi_domain_get_msi_rid - maps PCI ID and returns MSI RID pci_acpi_register_msi_rid_mapper - registers RID mapper pci_acpi_msi_get_device_domain - finds PCI device MSI domain pci_acpi_register_dev_msi_fwnode_provider - registers MSI domain finder Then, it is plugged into MSI infrastructure. To: Bjorn Helgaas To: Rafael J. Wysocki Signed-off-by: Tomasz Nowicki --- drivers/pci/msi.c | 10 +++++-- drivers/pci/pci-acpi.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 11 ++++++++ 3 files changed, 95 insertions(+), 3 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index a080f44..07b59a3 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -1364,8 +1364,8 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev) pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); of_node = irq_domain_get_of_node(domain); - if (of_node) - rid = of_msi_map_rid(&pdev->dev, of_node, rid); + rid = of_node ? of_msi_map_rid(&pdev->dev, of_node, rid) : + pci_acpi_msi_domain_get_msi_rid(pdev, rid); return rid; } @@ -1381,9 +1381,13 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev) */ struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev) { + struct irq_domain *dom; u32 rid = 0; pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); - return of_msi_map_get_device_domain(&pdev->dev, rid); + dom = of_msi_map_get_device_domain(&pdev->dev, rid); + if (!dom) + dom = pci_acpi_msi_get_device_domain(pdev, rid); + return dom; } #endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */ diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 9a033e8..26f4552 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -731,6 +731,83 @@ struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI); } +static u32 (*pci_msi_map_dev_rid_cb)(struct pci_dev *pdev, u32 req_id); + +/** + * pci_acpi_register_msi_rid_mapper - Register callback to map the MSI + * requester id (RID) + * @fn: Callback mapping a PCI device RID. + * + * This should be called by irqchip driver, which can provide firmware-defined + * topologies about MSI requester id (RID) on a per-device basis. + */ +void pci_acpi_register_msi_rid_mapper(u32 (*fn)(struct pci_dev *, u32)) +{ + pci_msi_map_dev_rid_cb = fn; +} + +/** + * pci_acpi_msi_domain_get_msi_rid - Get the MSI requester id (RID) of + * a PCI device + * @pdev: The PCI device. + * @rid_in: The PCI device request ID. + * + * This function uses the callback function registered by + * pci_acpi_register_msi_rid_mapper() to get the device RID based on ACPI + * supplied mapping. + * This should return rid_in on error or when there is no valid map. + */ +u32 pci_acpi_msi_domain_get_msi_rid(struct pci_dev *pdev, u32 rid_in) +{ + if (!pci_msi_map_dev_rid_cb) + return rid_in; + + return pci_msi_map_dev_rid_cb(pdev, rid_in); +} + +static struct fwnode_handle *(*pci_msi_get_dev_fwnode_cb)(struct pci_dev *pdev, + u32 req_id); + +/** + * pci_acpi_register_dev_msi_fwnode_provider - Register callback to retrieve + * domain fwnode on the per-device basis + * @fn: Callback matching a device to a fwnode that identifies a PCI + * MSI domain. + * + * This should be called by irqchip driver, which can provide firmware-defined + * topologies about which MSI controller to use on a per-device basis. + */ +void +pci_acpi_register_dev_msi_fwnode_provider( + struct fwnode_handle *(*fn)(struct pci_dev *, u32)) +{ + pci_msi_get_dev_fwnode_cb = fn; +} + +/** + * pci_acpi_msi_get_device_domain - Retrieve MSI domain of a PCI device + * @pdev: The PCI device. + * @rid: The PCI device requester ID. + * + * This function uses the callback function registered by + * pci_acpi_register_dev_msi_fwnode_provider() to retrieve the irq_domain with + * type DOMAIN_BUS_PCI_MSI of the specified PCI device. + * This returns NULL on error or when the domain is not found. + */ +struct irq_domain *pci_acpi_msi_get_device_domain(struct pci_dev *pdev, u32 rid) +{ + struct fwnode_handle *fwnode; + + if (!pci_msi_get_dev_fwnode_cb) + return NULL; + + fwnode = pci_msi_get_dev_fwnode_cb(pdev, rid); + if (!fwnode) + return NULL; + + return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI); +} + static int __init acpi_pci_init(void) { int ret; diff --git a/include/linux/pci.h b/include/linux/pci.h index 2771625..f50ba85 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1932,9 +1932,20 @@ struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus); void pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *)); +u32 pci_acpi_msi_domain_get_msi_rid(struct pci_dev *pdev, u32 rid_in); +void pci_acpi_register_msi_rid_mapper(u32 (*fn)(struct pci_dev *, u32)); +struct irq_domain * +pci_acpi_msi_get_device_domain(struct pci_dev *pdev, u32 rid); +void pci_acpi_register_dev_msi_fwnode_provider( + struct fwnode_handle *(*fn)(struct pci_dev *, u32)); #else static inline struct irq_domain * pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; } +static inline u32 +pci_acpi_msi_domain_get_msi_rid(struct pci_dev *pdev, u32 rid_in) +{ return rid_in; } +static inline struct irq_domain * +pci_acpi_msi_get_device_domain(struct pci_dev *pdev, u32 rid) { return NULL; } #endif #ifdef CONFIG_EEH