From patchwork Wed Sep 30 22:47:00 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Daney X-Patchwork-Id: 7303191 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 8FE0D9F314 for ; Wed, 30 Sep 2015 22:49:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9266D20719 for ; Wed, 30 Sep 2015 22:49:26 +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 9543920718 for ; Wed, 30 Sep 2015 22:49:25 +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 1ZhQAI-0002Al-Vw; Wed, 30 Sep 2015 22:47:59 +0000 Received: from mail-io0-x22b.google.com ([2607:f8b0:4001:c06::22b]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZhQ9r-0001uT-RE for linux-arm-kernel@lists.infradead.org; Wed, 30 Sep 2015 22:47:33 +0000 Received: by iow1 with SMTP id 1so28123388iow.1 for ; Wed, 30 Sep 2015 15:47:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=HLNteEysGVxul73W6sObVwZuiRqrFXNYI4hfLVtdhu8=; b=LzFhwHgwnx8vLHlofkgma1U5qp/m8rWG047xeWIWtiEpjUcg12nV2LtxwF9VpX7WUl 7RIV5dRboplsJ/mNTQEUM5dyoDQF2uTAPsll1uEE3VgmUyv14PAgAHSPe4KQ29sfxS3o oEYC9xqvlo+/reJmfeNsUsW9e8tMAuZ06O6jDcaoTW/1EQ8PgdbJ9+FMiBTo71OkhrbE cO8VUp267stVUV9Omanf3OixmycQroQJjZ0V9w2Ke7CujXxMYGZ34Dusj2piaGJmPp5e zRE48nOIf6/4gni7sMAgdLfXfDiQ/FmwGK2JNIvqNfBvWMtR/42Muvs7U7cn9A4fAzI2 T+YA== X-Received: by 10.107.138.231 with SMTP id c100mr7166436ioj.87.1443653231091; Wed, 30 Sep 2015 15:47:11 -0700 (PDT) Received: from dl.caveonetworks.com (64.2.3.194.ptr.us.xo.net. [64.2.3.194]) by smtp.gmail.com with ESMTPSA id 67sm1313168iol.7.2015.09.30.15.47.07 (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 30 Sep 2015 15:47:08 -0700 (PDT) Received: from dl.caveonetworks.com (localhost.localdomain [127.0.0.1]) by dl.caveonetworks.com (8.14.5/8.14.5) with ESMTP id t8UMl6u4024970; Wed, 30 Sep 2015 15:47:06 -0700 Received: (from ddaney@localhost) by dl.caveonetworks.com (8.14.5/8.14.5/Submit) id t8UMl6sw024969; Wed, 30 Sep 2015 15:47:06 -0700 From: David Daney To: linux-kernel@vger.kernel.org, Will Deacon , Rob Herring , Pawel Moll , Mark Rutland , Ian Campbell , Kumar Gala , linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, Marc Zyngier , Grant Likely , Thomas Gleixner , Jason Cooper , Frank Rowand , Bjorn Helgaas , linux-pci@vger.kernel.org Subject: [PATCH v3 2/4] of/irq: Add new function of_msi_map_rid() Date: Wed, 30 Sep 2015 15:47:00 -0700 Message-Id: <1443653222-24924-3-git-send-email-ddaney.cavm@gmail.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1443653222-24924-1-git-send-email-ddaney.cavm@gmail.com> References: <1443653222-24924-1-git-send-email-ddaney.cavm@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150930_154732_043236_0FE3604F X-CRM114-Status: GOOD ( 18.93 ) X-Spam-Score: -2.7 (--) 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: David Daney 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=-4.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_RP_MATCHES_RCVD, 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 From: David Daney The device tree property "msi-map" specifies how to create the PCI requester id used in some MSI controllers. Add a new function of_msi_map_rid() that finds the msi-map property and applies its translation to a given requester id. Reviewed-by: Marc Zyngier Signed-off-by: David Daney Acked-by: Rob Herring --- drivers/of/irq.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/of_irq.h | 7 +++++ 2 files changed, 91 insertions(+) diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 55317fa..c90bd4e 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -598,3 +598,87 @@ void of_msi_configure(struct device *dev, struct device_node *np) d = irq_find_host(msi_np); dev_set_msi_domain(dev, d); } + +/** + * of_msi_map_rid - Map a MSI requester ID for a device. + * @dev: device for which the mapping is to be done. + * @msi_np: device node of the expected msi controller. + * @rid_in: unmapped MSI requester ID for the device. + * + * Walk up the device hierarchy looking for devices with a "msi-map" + * property. If found, apply the mapping to @rid_in. + * + * Returns the mapped MSI requester ID. + */ +u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in) +{ + struct device *parent_dev; + struct device_node *msi_controller_node; + u32 map_mask, masked_rid, rid_base, msi_base, rid_len, phandle; + int msi_map_len; + bool matched; + u32 rid_out = rid_in; + const __be32 *msi_map = NULL; + + /* + * Walk up the device parent links looking for one with a + * "msi-map" property. + */ + for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) { + if (!parent_dev->of_node) + continue; + + msi_map = of_get_property(parent_dev->of_node, + "msi-map", &msi_map_len); + if (!msi_map) + continue; + + if (msi_map_len % (4 * sizeof(__be32))) { + dev_err(parent_dev, "Error: Bad msi-map length: %d\n", + msi_map_len); + return rid_out; + } + /* We have a good parent_dev and msi_map, let's use them. */ + break; + } + if (!msi_map) + return rid_out; + + /* The default is to select all bits. */ + map_mask = 0xffffffff; + + /* + * Can be overridden by "msi-map-mask" property. If + * of_property_read_u32() fails, the default is used. + */ + of_property_read_u32(parent_dev->of_node, "msi-map-mask", &map_mask); + + masked_rid = map_mask & rid_in; + matched = false; + while (!matched && msi_map_len >= 4 * sizeof(__be32)) { + rid_base = be32_to_cpup(msi_map + 0); + phandle = be32_to_cpup(msi_map + 1); + msi_base = be32_to_cpup(msi_map + 2); + rid_len = be32_to_cpup(msi_map + 3); + + msi_controller_node = of_find_node_by_phandle(phandle); + + matched = masked_rid >= rid_base && + masked_rid < rid_base + rid_len && + msi_np == msi_controller_node; + + of_node_put(msi_controller_node); + msi_map_len -= 4 * sizeof(__be32); + msi_map += 4; + } + if (!matched) + return rid_out; + + rid_out = masked_rid + msi_base; + dev_dbg(dev, + "msi-map at: %s, using mask %08x, rid-base: %08x, msi-base: %08x, length: %08x, rid: %08x -> %08x\n", + dev_name(parent_dev), map_mask, rid_base, msi_base, + rid_len, rid_in, rid_out); + + return rid_out; +} diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index 4bcbd58..8cd9334 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h @@ -75,6 +75,7 @@ static inline int of_irq_to_resource_table(struct device_node *dev, extern unsigned int irq_of_parse_and_map(struct device_node *node, int index); extern struct device_node *of_irq_find_parent(struct device_node *child); extern void of_msi_configure(struct device *dev, struct device_node *np); +u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in); #else /* !CONFIG_OF */ static inline unsigned int irq_of_parse_and_map(struct device_node *dev, @@ -87,6 +88,12 @@ static inline void *of_irq_find_parent(struct device_node *child) { return NULL; } + +static inline u32 of_msi_map_rid(struct device *dev, + struct device_node *msi_np, u32 rid_in) +{ + return rid_in; +} #endif /* !CONFIG_OF */ #endif /* __OF_IRQ_H */