diff options
Diffstat (limited to 'target/linux/mvebu/patches-3.10/0186-of-irq-Refactor-interrupt-map-parsing.patch')
-rw-r--r-- | target/linux/mvebu/patches-3.10/0186-of-irq-Refactor-interrupt-map-parsing.patch | 287 |
1 files changed, 0 insertions, 287 deletions
diff --git a/target/linux/mvebu/patches-3.10/0186-of-irq-Refactor-interrupt-map-parsing.patch b/target/linux/mvebu/patches-3.10/0186-of-irq-Refactor-interrupt-map-parsing.patch deleted file mode 100644 index 7f17bb737b..0000000000 --- a/target/linux/mvebu/patches-3.10/0186-of-irq-Refactor-interrupt-map-parsing.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 44ad702902e9e274f57edce8944e46540b978f9a Mon Sep 17 00:00:00 2001 -From: Grant Likely <grant.likely@linaro.org> -Date: Thu, 19 Dec 2013 09:30:57 -0300 -Subject: [PATCH 186/203] of/irq: Refactor interrupt-map parsing - -All the users of of_irq_parse_raw pass in a raw interrupt specifier from -the device tree and expect it to be returned (possibly modified) in an -of_phandle_args structure. However, the primary function of -of_irq_parse_raw() is to check for translations due to the presence of -one or more interrupt-map properties. The actual placing of the data -into an of_phandle_args structure is trivial. If it is refactored to -accept an of_phandle_args structure directly, then it becomes possible -to consume of_phandle_args from other sources. This is important for an -upcoming patch that allows a device to be connected to more than one -interrupt parent. It also simplifies the code a bit. - -The biggest complication with this patch is that the old version works -on the interrupt specifiers in __be32 form, but the of_phandle_args -structure is intended to carry it in the cpu-native version. A bit of -churn was required to make this work. In the end it results in tighter -code, so the churn is worth it. - -Signed-off-by: Grant Likely <grant.likely@linaro.org> -Acked-by: Tony Lindgren <tony@atomide.com> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> ---- - arch/powerpc/platforms/fsl_uli1575.c | 6 +- - drivers/of/irq.c | 108 ++++++++++++++++++----------------- - drivers/of/of_pci_irq.c | 7 ++- - include/linux/of_irq.h | 5 +- - 4 files changed, 67 insertions(+), 59 deletions(-) - ---- a/arch/powerpc/platforms/fsl_uli1575.c -+++ b/arch/powerpc/platforms/fsl_uli1575.c -@@ -322,7 +322,6 @@ static void hpcd_final_uli5288(struct pc - struct pci_controller *hose = pci_bus_to_host(dev->bus); - struct device_node *hosenode = hose ? hose->dn : NULL; - struct of_phandle_args oirq; -- int pin = 2; - u32 laddr[3]; - - if (!machine_is(mpc86xx_hpcd)) -@@ -331,9 +330,12 @@ static void hpcd_final_uli5288(struct pc - if (!hosenode) - return; - -+ oirq.np = hosenode; -+ oirq.args[0] = 2; -+ oirq.args_count = 1; - laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(31, 0) << 8); - laddr[1] = laddr[2] = 0; -- of_irq_parse_raw(hosenode, &pin, 1, laddr, &oirq); -+ of_irq_parse_raw(laddr, &oirq); - dev->irq = irq_create_of_mapping(&oirq); - } - ---- a/drivers/of/irq.c -+++ b/drivers/of/irq.c -@@ -80,31 +80,32 @@ struct device_node *of_irq_find_parent(s - /** - * of_irq_parse_raw - Low level interrupt tree parsing - * @parent: the device interrupt parent -- * @intspec: interrupt specifier ("interrupts" property of the device) -- * @ointsize: size of the passed in interrupt specifier -- * @addr: address specifier (start of "reg" property of the device) -- * @out_irq: structure of_irq filled by this function -+ * @addr: address specifier (start of "reg" property of the device) in be32 format -+ * @out_irq: structure of_irq updated by this function - * - * Returns 0 on success and a negative number on error - * - * This function is a low-level interrupt tree walking function. It - * can be used to do a partial walk with synthetized reg and interrupts - * properties, for example when resolving PCI interrupts when no device -- * node exist for the parent. -+ * node exist for the parent. It takes an interrupt specifier structure as -+ * input, walks the tree looking for any interrupt-map properties, translates -+ * the specifier for each map, and then returns the translated map. - */ --int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec, -- u32 ointsize, const __be32 *addr, struct of_phandle_args *out_irq) -+int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) - { - struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; -- const __be32 *tmp, *imap, *imask; -+ __be32 initial_match_array[8]; -+ const __be32 *match_array = initial_match_array; -+ const __be32 *tmp, *imap, *imask, dummy_imask[] = { ~0, ~0, ~0, ~0, ~0 }; - u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; - int imaplen, match, i; - - pr_debug("of_irq_parse_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", -- of_node_full_name(parent), be32_to_cpup(intspec), -- be32_to_cpup(intspec + 1), ointsize); -+ of_node_full_name(out_irq->np), out_irq->args[0], out_irq->args[1], -+ out_irq->args_count); - -- ipar = of_node_get(parent); -+ ipar = of_node_get(out_irq->np); - - /* First get the #interrupt-cells property of the current cursor - * that tells us how to interpret the passed-in intspec. If there -@@ -127,7 +128,7 @@ int of_irq_parse_raw(struct device_node - - pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize); - -- if (ointsize != intsize) -+ if (out_irq->args_count != intsize) - return -EINVAL; - - /* Look for this #address-cells. We have to implement the old linux -@@ -146,6 +147,21 @@ int of_irq_parse_raw(struct device_node - - pr_debug(" -> addrsize=%d\n", addrsize); - -+ /* If we were passed no "reg" property and we attempt to parse -+ * an interrupt-map, then #address-cells must be 0. -+ * Fail if it's not. -+ */ -+ if (addr == NULL && addrsize != 0) { -+ pr_debug(" -> no reg passed in when needed !\n"); -+ return -EINVAL; -+ } -+ -+ /* Precalculate the match array - this simplifies match loop */ -+ for (i = 0; i < addrsize; i++) -+ initial_match_array[i] = addr[i]; -+ for (i = 0; i < intsize; i++) -+ initial_match_array[addrsize + i] = cpu_to_be32(out_irq->args[i]); -+ - /* Now start the actual "proper" walk of the interrupt tree */ - while (ipar != NULL) { - /* Now check if cursor is an interrupt-controller and if it is -@@ -154,11 +170,6 @@ int of_irq_parse_raw(struct device_node - if (of_get_property(ipar, "interrupt-controller", NULL) != - NULL) { - pr_debug(" -> got it !\n"); -- for (i = 0; i < intsize; i++) -- out_irq->args[i] = -- of_read_number(intspec +i, 1); -- out_irq->args_count = intsize; -- out_irq->np = ipar; - of_node_put(old); - return 0; - } -@@ -175,34 +186,16 @@ int of_irq_parse_raw(struct device_node - - /* Look for a mask */ - imask = of_get_property(ipar, "interrupt-map-mask", NULL); -- -- /* If we were passed no "reg" property and we attempt to parse -- * an interrupt-map, then #address-cells must be 0. -- * Fail if it's not. -- */ -- if (addr == NULL && addrsize != 0) { -- pr_debug(" -> no reg passed in when needed !\n"); -- goto fail; -- } -+ if (!imask) -+ imask = dummy_imask; - - /* Parse interrupt-map */ - match = 0; - while (imaplen > (addrsize + intsize + 1) && !match) { - /* Compare specifiers */ - match = 1; -- for (i = 0; i < addrsize && match; ++i) { -- __be32 mask = imask ? imask[i] -- : cpu_to_be32(0xffffffffu); -- match = ((addr[i] ^ imap[i]) & mask) == 0; -- } -- for (; i < (addrsize + intsize) && match; ++i) { -- __be32 mask = imask ? imask[i] -- : cpu_to_be32(0xffffffffu); -- match = -- ((intspec[i-addrsize] ^ imap[i]) & mask) == 0; -- } -- imap += addrsize + intsize; -- imaplen -= addrsize + intsize; -+ for (i = 0; i < (addrsize + intsize); i++, imaplen--) -+ match = !((match_array[i] ^ *imap++) & imask[i]); - - pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); - -@@ -247,12 +240,18 @@ int of_irq_parse_raw(struct device_node - if (!match) - goto fail; - -- of_node_put(old); -- old = of_node_get(newpar); -+ /* -+ * Successfully parsed an interrrupt-map translation; copy new -+ * interrupt specifier into the out_irq structure -+ */ -+ of_node_put(out_irq->np); -+ out_irq->np = of_node_get(newpar); -+ -+ match_array = imap - newaddrsize - newintsize; -+ for (i = 0; i < newintsize; i++) -+ out_irq->args[i] = be32_to_cpup(imap - newintsize + i); -+ out_irq->args_count = intsize = newintsize; - addrsize = newaddrsize; -- intsize = newintsize; -- intspec = imap - intsize; -- addr = intspec - addrsize; - - skiplevel: - /* Iterate again with new parent */ -@@ -263,7 +262,7 @@ int of_irq_parse_raw(struct device_node - } - fail: - of_node_put(ipar); -- of_node_put(old); -+ of_node_put(out_irq->np); - of_node_put(newpar); - - return -EINVAL; -@@ -276,15 +275,16 @@ EXPORT_SYMBOL_GPL(of_irq_parse_raw); - * @index: index of the interrupt to resolve - * @out_irq: structure of_irq filled by this function - * -- * This function resolves an interrupt, walking the tree, for a given -- * device-tree node. It's the high level pendant to of_irq_parse_raw(). -+ * This function resolves an interrupt for a node by walking the interrupt tree, -+ * finding which interrupt controller node it is attached to, and returning the -+ * interrupt specifier that can be used to retrieve a Linux IRQ number. - */ - int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq) - { - struct device_node *p; - const __be32 *intspec, *tmp, *addr; - u32 intsize, intlen; -- int res = -EINVAL; -+ int i, res = -EINVAL; - - pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index); - -@@ -326,9 +326,15 @@ int of_irq_parse_one(struct device_node - if ((index + 1) * intsize > intlen) - goto out; - -- /* Get new specifier and map it */ -- res = of_irq_parse_raw(p, intspec + index * intsize, intsize, -- addr, out_irq); -+ /* Copy intspec into irq structure */ -+ intspec += index * intsize; -+ out_irq->np = p; -+ out_irq->args_count = intsize; -+ for (i = 0; i < intsize; i++) -+ out_irq->args[i] = be32_to_cpup(intspec++); -+ -+ /* Check if there are any interrupt-map translations to process */ -+ res = of_irq_parse_raw(addr, out_irq); - out: - of_node_put(p); - return res; ---- a/drivers/of/of_pci_irq.c -+++ b/drivers/of/of_pci_irq.c -@@ -85,9 +85,12 @@ int of_irq_parse_pci(const struct pci_de - pdev = ppdev; - } - -+ out_irq->np = ppnode; -+ out_irq->args_count = 1; -+ out_irq->args[0] = lspec; - lspec_be = cpu_to_be32(lspec); - laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8)); -- laddr[1] = laddr[2] = cpu_to_be32(0); -- return of_irq_parse_raw(ppnode, &lspec_be, 1, laddr, out_irq); -+ laddr[1] = laddr[2] = cpu_to_be32(0); -+ return of_irq_parse_raw(laddr, out_irq); - } - EXPORT_SYMBOL_GPL(of_irq_parse_pci); ---- a/include/linux/of_irq.h -+++ b/include/linux/of_irq.h -@@ -31,10 +31,7 @@ static inline int of_irq_parse_oldworld( - } - #endif /* CONFIG_PPC32 && CONFIG_PPC_PMAC */ - -- --extern int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec, -- u32 ointsize, const __be32 *addr, -- struct of_phandle_args *out_irq); -+extern int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq); - extern int of_irq_parse_one(struct device_node *device, int index, - struct of_phandle_args *out_irq); - extern unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data); |