Thread (1 message) 1 message, 1 author, 2016-06-14

[PATCH v2 3/7] of/irq: Break out msi-map lookup (again)

From: Will Deacon <hidden>
Date: 2016-06-14 18:20:07
Also in: linux-devicetree, linux-iommu

On Tue, Jun 14, 2016 at 07:12:46PM +0100, Robin Murphy wrote:
On 14/06/16 15:37, Will Deacon wrote:
quoted
On Fri, Jun 03, 2016 at 06:15:38PM +0100, Robin Murphy wrote:
quoted
The PCI msi-map code is already doing double-duty translating IDs and
retrieving MSI parents, which unsurprisingly is the same functionality
we need for the identically-formatted PCI iommu-map property. Drag the
core parsing routine up yet another layer into the general OF-PCI code,
and further generalise it for either kind of lookup in either flavour
of map property.

CC: Rob Herring <robh+dt@kernel.org>
CC: Frank Rowand <redacted>
CC: Marc Zyngier <redacted>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---

v2: No change.

 drivers/of/irq.c       |  70 ++-------------------------------
 drivers/of/of_pci.c    | 102 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_pci.h |   8 ++++
 3 files changed, 114 insertions(+), 66 deletions(-)
[...]
quoted
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 13f4fed38048..20bf5a0c57fd 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -306,3 +306,105 @@ struct msi_controller *of_pci_find_msi_chip_by_node(struct device_node *of_node)
 EXPORT_SYMBOL_GPL(of_pci_find_msi_chip_by_node);

 #endif /* CONFIG_PCI_MSI */
+
+#define MASK_NAME_LEN	32	/* Safely longer than "iommu-map-mask" */
+
+/**
+ * of_pci_map_rid - Translate a requester ID through a downstream mapping.
+ * @np: root complex device node.
+ * @map_name: property name of the map to use.
+ * @target: optional pointer to a target device node.
+ * @id_out: optional pointer to receive the translated ID.
+ *
+ * Given a PCI requester ID, look up the appropriate implementation-defined
+ * platform ID and/or the target device which receives transactions on that
+ * ID, as per the "iommu-map" and "msi-map" bindings. @target or @id_out may
+ * be NULL if not required. If @target points to a device node pointer, only
+ * entries targeting that node will be matched; if it points to a NULL
+ * value, it will receive the device node for the first matching target entry,
+ * with a reference held.
+ *
+ * Return: 0 on success or a standard error code on failure.
+ */
+int of_pci_map_rid(struct device_node *np, const char *map_name, u32 rid_in,
+		   struct device_node **target, u32 *rid_out)
+{
+	u32 map_mask, masked_rid;
+	int map_len;
+	const __be32 *map = NULL;
+	char mask_name[MASK_NAME_LEN];
Couldn't you avoid this if you just took const char *mask_name as a
parameter too?
Having started out with that, I considered two strings essentially
duplicating each other, possibly duplicated per callsite, and thought it
might be prudent to trade off a little runtime work for a permanent
reduction in static data. I like the "never save anything you can
recalculate" philosophy, but it is possible I got a bit carried away here.
If you hate it I can just add the extra argument back.
Yeah, please do. The idea is that this can be used with different bindings,
and I don't think we gain anything from constructing the mask string other
than and ugliness complexity.

Will
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help