2013-10-15 20:39:36

by Grant Likely

[permalink] [raw]
Subject: [RFC 0/9] of: refactor IRQ parsing and add interrupts-extended implementation

Hi everyone.

This series is mostly a set of cleanup to the interrupt parsing code.
Some of it merely clarification, like the renames of of_irq_map_*, some
to tighten up the API by using of_phandle_args, and some to prepare for
the last patch in the series.

Of all these patches, the last one is probably the only one likely to be
controversial. It adds a new way of specifying interrupts. If a device
gets wired up to multiple interrupt controllers, the interrupts-extended
property allows the device to specify multiple connections without
redirecting through an interrupt-map node which can be rather difficult
to understand. In a lot of cases, an interrupts-extended property is a
whole lot easier to use.

Please take a look and comment. We'll probably discuss the
interrupts-extended binding in Edinburgh at the DT workshop in a few
weeks.


2013-10-15 20:39:44

by Grant Likely

[permalink] [raw]
Subject: [RFC 5/9] of: Add helper for printing an of_phandle_args structure

It is sometimes useful for debug to get the contents of an
of_phandle_args structure out into the kernel log.

Signed-off-by: Grant Likely <[email protected]>
---
drivers/of/base.c | 9 +++++++++
drivers/of/irq.c | 6 +++---
include/linux/of.h | 1 +
3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 3ae106d..021db96 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1185,6 +1185,15 @@ int of_property_count_strings(struct device_node *np, const char *propname)
}
EXPORT_SYMBOL_GPL(of_property_count_strings);

+void of_print_phandle_args(const char *msg, const struct of_phandle_args *args)
+{
+ int i;
+ printk("%s %s", msg, of_node_full_name(args->np));
+ for (i = 0; i < args->args_count; i++)
+ printk(i ? ",%08x" : ":%08x", args->args[i]);
+ printk("\n");
+}
+
static int __of_parse_phandle_with_args(const struct device_node *np,
const char *list_name,
const char *cells_name,
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 0ed5ed4..ddea945 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -101,9 +101,9 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
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(out_irq->np), out_irq->args[0], out_irq->args[1],
- out_irq->args_count);
+#ifdef DEBUG
+ of_print_phandle_args("of_irq_parse_raw: ", out_irq);
+#endif

ipar = of_node_get(out_irq->np);

diff --git a/include/linux/of.h b/include/linux/of.h
index f95aee3..374e035 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -275,6 +275,7 @@ extern int of_n_size_cells(struct device_node *np);
extern const struct of_device_id *of_match_node(
const struct of_device_id *matches, const struct device_node *node);
extern int of_modalias_node(struct device_node *node, char *modalias, int len);
+extern void of_print_phandle_args(const char *msg, const struct of_phandle_args *args);
extern struct device_node *of_parse_phandle(const struct device_node *np,
const char *phandle_name,
int index);
--
1.8.1.2

2013-10-15 20:39:57

by Grant Likely

[permalink] [raw]
Subject: [RFC 7/9] of/irq: Create of_irq_parse_and_map_pci() to consolidate arch code.

Several architectures open code effectively the same code block for
finding and mapping PCI irqs. This patch consolidates it down to a
single function.

Signed-off-by: Grant Likely <[email protected]>
Cc: Russell King <[email protected]>
Cc: Michal Simek <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
---
arch/arm/mach-integrator/pci_v3.c | 17 +----------------
arch/mips/pci/fixup-lantiq.c | 12 +-----------
arch/mips/pci/pci-rt3883.c | 22 +---------------------
arch/x86/kernel/devicetree.c | 7 +------
drivers/of/of_pci_irq.c | 25 +++++++++++++++++++++++++
drivers/pci/host/pci-mvebu.c | 14 +-------------
include/linux/of_pci.h | 1 +
7 files changed, 31 insertions(+), 67 deletions(-)

diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index bb3aeb3..a87e510 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -835,21 +835,6 @@ static struct hw_pci pci_v3 __initdata = {

#ifdef CONFIG_OF

-static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin)
-{
- struct of_phandle_args oirq;
- int ret;
-
- ret = of_irq_parse_pci(dev, &oirq);
- if (ret) {
- dev_err(&dev->dev, "of_irq_parse_pci() %d\n", ret);
- /* Proper return code 0 == NO_IRQ */
- return 0;
- }
-
- return irq_create_of_mapping(&oirq);
-}
-
static int __init pci_v3_dtprobe(struct platform_device *pdev,
struct device_node *np)
{
@@ -918,7 +903,7 @@ static int __init pci_v3_dtprobe(struct platform_device *pdev,
return -EINVAL;
}

- pci_v3.map_irq = pci_v3_map_irq_dt;
+ pci_v3.map_irq = of_irq_parse_and_map_pci;
pci_common_init_dev(&pdev->dev, &pci_v3);

return 0;
diff --git a/arch/mips/pci/fixup-lantiq.c b/arch/mips/pci/fixup-lantiq.c
index aef60e7..c2ce41e 100644
--- a/arch/mips/pci/fixup-lantiq.c
+++ b/arch/mips/pci/fixup-lantiq.c
@@ -25,15 +25,5 @@ int pcibios_plat_dev_init(struct pci_dev *dev)

int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
- struct of_phandle_args dev_irq;
- int irq;
-
- if (of_irq_parse_pci(dev, &dev_irq)) {
- dev_err(&dev->dev, "trying to map irq for unknown slot:%d pin:%d\n",
- slot, pin);
- return 0;
- }
- irq = irq_create_of_mapping(&dev_irq);
- dev_info(&dev->dev, "SLOT:%d PIN:%d IRQ:%d\n", slot, pin, irq);
- return irq;
+ return of_irq_parse_and_map_pci(dev, slot, pin);
}
diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c
index eadc431..adeff2b 100644
--- a/arch/mips/pci/pci-rt3883.c
+++ b/arch/mips/pci/pci-rt3883.c
@@ -583,27 +583,7 @@ err_put_intc_node:

int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
- struct of_phandle_args dev_irq;
- int err;
- int irq;
-
- err = of_irq_parse_pci(dev, &dev_irq);
- if (err) {
- pr_err("pci %s: unable to get irq map, err=%d\n",
- pci_name((struct pci_dev *) dev), err);
- return 0;
- }
-
- irq = irq_create_of_mapping(&dev_irq);
-
- if (irq == 0)
- pr_crit("pci %s: no irq found for pin %u\n",
- pci_name((struct pci_dev *) dev), pin);
- else
- pr_info("pci %s: using irq %d for pin %u\n",
- pci_name((struct pci_dev *) dev), irq, pin);
-
- return irq;
+ return of_irq_parse_and_map_pci(dev, slot, pin);
}

int pcibios_plat_dev_init(struct pci_dev *dev)
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index d39948f..69c826a 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -105,7 +105,6 @@ struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)

static int x86_of_pci_irq_enable(struct pci_dev *dev)
{
- struct of_phandle_args oirq;
u32 virq;
int ret;
u8 pin;
@@ -116,11 +115,7 @@ static int x86_of_pci_irq_enable(struct pci_dev *dev)
if (!pin)
return 0;

- ret = of_irq_parse_pci(dev, &oirq);
- if (ret)
- return ret;
-
- virq = irq_create_of_mapping(&oirq);
+ virq = of_irq_parse_and_map_pci(dev, 0, 0);
if (virq == 0)
return -EINVAL;
dev->irq = virq;
diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c
index 303afeb..8e92acd 100644
--- a/drivers/of/of_pci_irq.c
+++ b/drivers/of/of_pci_irq.c
@@ -94,3 +94,28 @@ int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq
return of_irq_parse_raw(laddr, out_irq);
}
EXPORT_SYMBOL_GPL(of_irq_parse_pci);
+
+/**
+ * of_irq_parse_and_map_pci() - Decode a PCI irq from the device tree and map to a virq
+ * @dev: The pci device needing an irq
+ * @slot: PCI slot number; passed when used as map_irq callback. Unused
+ * @pin: PCI irq pin number; passed when used as map_irq callback. Unused
+ *
+ * @slot and @pin are unused, but included in the function so that this
+ * function can be used directly as the map_irq callback to pci_fixup_irqs().
+ */
+int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ struct of_phandle_args oirq;
+ int ret;
+
+ ret = of_irq_parse_pci(dev, &oirq);
+ if (ret) {
+ dev_err(&dev->dev, "of_irq_parse_pci() failed with rc=%d\n", ret);
+ return 0; /* Proper return code 0 == NO_IRQ */
+ }
+
+ return irq_create_of_mapping(&oirq);
+}
+EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci);
+
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 3a8d01e..07ddb3a 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -645,18 +645,6 @@ static int __init mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
return 1;
}

-static int __init mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
- struct of_phandle_args oirq;
- int ret;
-
- ret = of_irq_parse_pci(dev, &oirq);
- if (ret)
- return ret;
-
- return irq_create_of_mapping(&oirq);
-}
-
static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
{
struct mvebu_pcie *pcie = sys_to_pcie(sys);
@@ -705,7 +693,7 @@ static void __init mvebu_pcie_enable(struct mvebu_pcie *pcie)
hw.private_data = (void **)&pcie;
hw.setup = mvebu_pcie_setup;
hw.scan = mvebu_pcie_scan_bus;
- hw.map_irq = mvebu_pcie_map_irq;
+ hw.map_irq = of_irq_parse_and_map_pci;
hw.ops = &mvebu_pcie_ops;
hw.align_resource = mvebu_pcie_align_resource;

diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index f297237..1a1f5ff 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -7,6 +7,7 @@
struct pci_dev;
struct of_phandle_args;
int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq);
+int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);

struct device_node;
struct device_node *of_pci_find_child_device(struct device_node *parent,
--
1.8.1.2

2013-10-15 20:39:41

by Grant Likely

[permalink] [raw]
Subject: [RFC 4/9] 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 <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
---
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(-)

diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c
index 8904046..b97f6f3 100644
--- a/arch/powerpc/platforms/fsl_uli1575.c
+++ b/arch/powerpc/platforms/fsl_uli1575.c
@@ -322,7 +322,6 @@ static void hpcd_final_uli5288(struct pci_dev *dev)
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 pci_dev *dev)
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);
}

diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 84184c4..0ed5ed4 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -80,31 +80,32 @@ struct device_node *of_irq_find_parent(struct device_node *child)
/**
* 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 *parent, const __be32 *intspec,

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 *parent, const __be32 *intspec,

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 *parent, const __be32 *intspec,
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 *parent, const __be32 *intspec,

/* 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 *parent, const __be32 *intspec,
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 *parent, const __be32 *intspec,
}
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);

@@ -320,9 +320,15 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar
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;
diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c
index ee3293d..303afeb 100644
--- 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_dev *pdev, struct of_phandle_args *out_irq
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);
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index 3bbba8d..c0d6dfe 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -31,10 +31,7 @@ static inline int of_irq_parse_oldworld(struct device_node *device, int index,
}
#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);
--
1.8.1.2

2013-10-15 20:40:50

by Grant Likely

[permalink] [raw]
Subject: [RFC 8/9] microblaze/pci: Drop PowerPC-ism from irq parsing

The Microblaze PCI code copied the PowerPC irq handling, but powerpc
needs to handle broken device trees that are not present on Microblaze.
This patch removes the powerpc special case and replaces it with a
direct of_irq_parse_and_map_pci() call.

Signed-off-by: Grant Likely <[email protected]>
Cc: Michal Simek <[email protected]>
---
arch/microblaze/include/asm/pci.h | 2 --
arch/microblaze/pci/pci-common.c | 71 +--------------------------------------
2 files changed, 1 insertion(+), 72 deletions(-)

diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h
index d52abb6..935f9be 100644
--- a/arch/microblaze/include/asm/pci.h
+++ b/arch/microblaze/include/asm/pci.h
@@ -127,8 +127,6 @@ extern void of_scan_pci_bridge(struct device_node *node,
extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus);

-extern int pci_read_irq_line(struct pci_dev *dev);
-
extern int pci_bus_find_capability(struct pci_bus *bus,
unsigned int devfn, int cap);

diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 60b386c..5060fc5 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -193,75 +193,6 @@ void pcibios_set_master(struct pci_dev *dev)
}

/*
- * Reads the interrupt pin to determine if interrupt is use by card.
- * If the interrupt is used, then gets the interrupt line from the
- * openfirmware and sets it in the pci_dev and pci_config line.
- */
-int pci_read_irq_line(struct pci_dev *pci_dev)
-{
- struct of_phandle_args oirq;
- unsigned int virq;
-
- /* The current device-tree that iSeries generates from the HV
- * PCI informations doesn't contain proper interrupt routing,
- * and all the fallback would do is print out crap, so we
- * don't attempt to resolve the interrupts here at all, some
- * iSeries specific fixup does it.
- *
- * In the long run, we will hopefully fix the generated device-tree
- * instead.
- */
- pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev));
-
-#ifdef DEBUG
- memset(&oirq, 0xff, sizeof(oirq));
-#endif
- /* Try to get a mapping from the device-tree */
- if (of_irq_parse_pci(pci_dev, &oirq)) {
- u8 line, pin;
-
- /* If that fails, lets fallback to what is in the config
- * space and map that through the default controller. We
- * also set the type to level low since that's what PCI
- * interrupts are. If your platform does differently, then
- * either provide a proper interrupt tree or don't use this
- * function.
- */
- if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
- return -1;
- if (pin == 0)
- return -1;
- if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
- line == 0xff || line == 0) {
- return -1;
- }
- pr_debug(" No map ! Using line %d (pin %d) from PCI config\n",
- line, pin);
-
- virq = irq_create_mapping(NULL, line);
- if (virq)
- irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
- } else {
- pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
- oirq.args_count, oirq.args[0], oirq.args[1],
- of_node_full_name(oirq.np));
-
- virq = irq_create_of_mapping(&oirq);
- }
- if (!virq) {
- pr_debug(" Failed to map !\n");
- return -1;
- }
-
- pr_debug(" Mapped to linux irq %d\n", virq);
-
- pci_dev->irq = virq;
-
- return 0;
-}
-EXPORT_SYMBOL(pci_read_irq_line);
-
-/*
* Platform support for /proc/bus/pci/X/Y mmap()s,
* modelled on the sparc64 implementation by Dave Miller.
* -- paulus.
@@ -959,7 +890,7 @@ void pcibios_setup_bus_devices(struct pci_bus *bus)
dev->dev.archdata.dma_data = (void *)PCI_DRAM_OFFSET;

/* Read default IRQs and fixup if necessary */
- pci_read_irq_line(dev);
+ dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
}
}

--
1.8.1.2

2013-10-15 20:41:13

by Grant Likely

[permalink] [raw]
Subject: [RFC 6/9] of: Add testcases for interrupt parsing

This patch extends the DT selftest code with some test cases for the
interrupt parsing functions.

Signed-off-by: Grant Likely <[email protected]>
---
arch/arm/boot/dts/testcases/tests-interrupts.dtsi | 41 ++++++++++
arch/arm/boot/dts/testcases/tests.dtsi | 1 +
drivers/of/selftest.c | 91 +++++++++++++++++++++--
3 files changed, 127 insertions(+), 6 deletions(-)
create mode 100644 arch/arm/boot/dts/testcases/tests-interrupts.dtsi

diff --git a/arch/arm/boot/dts/testcases/tests-interrupts.dtsi b/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
new file mode 100644
index 0000000..6ecda71
--- /dev/null
+++ b/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
@@ -0,0 +1,41 @@
+
+/ {
+ testcase-data {
+ interrupts {
+ #address-cells = <0>;
+ test_intc0: intc0 {
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ test_intc1: intc1 {
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ test_intc2: intc2 {
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ test_intmap0: intmap0 {
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ interrupt-map = <1 &test_intc0 9>,
+ <2 &test_intc1 10 11 12>,
+ <3 &test_intc2 13 14>,
+ <4 &test_intc2 15 16>;
+ };
+
+ interrupts0 {
+ interrupt-parent = <&test_intc0>;
+ interrupts = <1>, <2>, <3>, <4>;
+ };
+
+ interrupts1 {
+ interrupt-parent = <&test_intmap0>;
+ interrupts = <1>, <2>, <3>, <4>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/testcases/tests.dtsi b/arch/arm/boot/dts/testcases/tests.dtsi
index a7c5067..3f123ec 100644
--- a/arch/arm/boot/dts/testcases/tests.dtsi
+++ b/arch/arm/boot/dts/testcases/tests.dtsi
@@ -1 +1,2 @@
/include/ "tests-phandle.dtsi"
+/include/ "tests-interrupts.dtsi"
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c
index 0eb5c38..9c80f0b 100644
--- a/drivers/of/selftest.c
+++ b/drivers/of/selftest.c
@@ -9,18 +9,24 @@
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_irq.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/device.h>

-static bool selftest_passed = true;
+static struct selftest_results {
+ int passed;
+ int failed;
+} selftest_results;
+
#define selftest(result, fmt, ...) { \
if (!(result)) { \
- pr_err("FAIL %s:%i " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \
- selftest_passed = false; \
+ selftest_results.failed++; \
+ pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \
} else { \
- pr_info("pass %s:%i\n", __FILE__, __LINE__); \
+ selftest_results.passed++; \
+ pr_debug("pass %s():%i\n", __func__, __LINE__); \
} \
}

@@ -131,7 +137,6 @@ static void __init of_selftest_property_match_string(void)
struct device_node *np;
int rc;

- pr_info("start\n");
np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
if (!np) {
pr_err("No testcase data in device tree\n");
@@ -154,6 +159,78 @@ static void __init of_selftest_property_match_string(void)
selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc);
}

+static void __init of_selftest_parse_interrupts(void)
+{
+ struct device_node *np;
+ struct of_phandle_args args;
+ int i, rc;
+
+ np = of_find_node_by_path("/testcase-data/interrupts/interrupts0");
+ if (!np) {
+ pr_err("missing testcase data\n");
+ return;
+ }
+
+ for (i = 0; i < 4; i++) {
+ bool passed = true;
+ args.args_count = 0;
+ rc = of_irq_parse_one(np, i, &args);
+
+ passed &= !rc;
+ passed &= (args.args_count == 1);
+ passed &= (args.args[0] == (i + 1));
+
+ selftest(passed, "index %i - data error on node %s rc=%i\n",
+ i, args.np->full_name, rc);
+ }
+ of_node_put(np);
+
+ np = of_find_node_by_path("/testcase-data/interrupts/interrupts1");
+ if (!np) {
+ pr_err("missing testcase data\n");
+ return;
+ }
+
+ for (i = 0; i < 4; i++) {
+ bool passed = true;
+ args.args_count = 0;
+ rc = of_irq_parse_one(np, i, &args);
+
+ /* Test the values from tests-phandle.dtsi */
+ switch (i) {
+ case 0:
+ passed &= !rc;
+ passed &= (args.args_count == 1);
+ passed &= (args.args[0] == 9);
+ break;
+ case 1:
+ passed &= !rc;
+ passed &= (args.args_count == 3);
+ passed &= (args.args[0] == 10);
+ passed &= (args.args[1] == 11);
+ passed &= (args.args[2] == 12);
+ break;
+ case 2:
+ passed &= !rc;
+ passed &= (args.args_count == 2);
+ passed &= (args.args[0] == 13);
+ passed &= (args.args[1] == 14);
+ break;
+ case 3:
+ passed &= !rc;
+ passed &= (args.args_count == 2);
+ passed &= (args.args[0] == 15);
+ passed &= (args.args[1] == 16);
+ break;
+ default:
+ passed = false;
+ }
+ selftest(passed, "index %i - data error on node %s rc=%i\n",
+ i, args.np->full_name, rc);
+ }
+ of_node_put(np);
+}
+
static int __init of_selftest(void)
{
struct device_node *np;
@@ -168,7 +245,9 @@ static int __init of_selftest(void)
pr_info("start of selftest - you will see error messages\n");
of_selftest_parse_phandle_with_args();
of_selftest_property_match_string();
- pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL");
+ of_selftest_parse_interrupts();
+ pr_info("end of selftest - %i passed, %i failed\n",
+ selftest_results.passed, selftest_results.failed);
return 0;
}
late_initcall(of_selftest);
--
1.8.1.2

2013-10-15 20:41:11

by Grant Likely

[permalink] [raw]
Subject: [RFC 9/9] of/irq: create interrupts-extended property

The standard interrupts property in device tree can only handle
interrupts coming from a single interrupt parent. If a device is wired
to multiple interrupt controllers, then it needs to be attached to a
node with an interrupt-map property to demux the interrupt specifiers
which is confusing. It would be a lot easier if there was a form of the
interrupts property that allows for a separate interrupt phandle for
each interrupt specifier.

This patch does exactly that by creating a new interrupts-extended
property which reuses the phandle+arguments pattern used by GPIOs and
other core bindings.

Signed-off-by: Grant Likely <[email protected]>
Cc: Rob Herring <[email protected]>
---
.../bindings/interrupt-controller/interrupts.txt | 29 +++++++--
arch/arm/boot/dts/testcases/tests-interrupts.dtsi | 16 +++++
arch/arm/boot/dts/versatile-ab.dts | 2 +-
arch/arm/boot/dts/versatile-pb.dts | 2 +-
drivers/of/irq.c | 16 +++--
drivers/of/selftest.c | 70 ++++++++++++++++++++++
6 files changed, 122 insertions(+), 13 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
index 72a06c0..1486497 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
@@ -4,16 +4,33 @@ Specifying interrupt information for devices
1) Interrupt client nodes
-------------------------

-Nodes that describe devices which generate interrupts must contain an
-"interrupts" property. This property must contain a list of interrupt
-specifiers, one per output interrupt. The format of the interrupt specifier is
-determined by the interrupt controller to which the interrupts are routed; see
-section 2 below for details.
+Nodes that describe devices which generate interrupts must contain an either an
+"interrupts" property or an "interrupts-extended" property. These properties
+contain a list of interrupt specifiers, one per output interrupt. The format of
+the interrupt specifier is determined by the interrupt controller to which the
+interrupts are routed; see section 2 below for details.
+
+ Example:
+ interrupt-parent = <&intc1>;
+ interrupts = <5 0>, <6 0>;

The "interrupt-parent" property is used to specify the controller to which
interrupts are routed and contains a single phandle referring to the interrupt
controller node. This property is inherited, so it may be specified in an
-interrupt client node or in any of its parent nodes.
+interrupt client node or in any of its parent nodes. Interrupts listed in the
+"interrupts" property are always in reference to the node's interrupt parent.
+
+The "interrupts-extended" property is a special form for use when a node needs
+to reference multiple interrupt parents. Each entry in this property contains
+both the parent phandle and the interrupt specifier. "interrupts-extended"
+should only be used when a device has multiple interrupt parents.
+
+ Example:
+ interrupts-extended = <&intc1 5 1>, <&intc2 1 0>;
+
+A device node may contain either "interrupts" or "interrupts-extended", but not
+both. If both properties are present, then the operating system should log an
+error and use only the data in "interrupts".

2) Interrupt controller nodes
-----------------------------
diff --git a/arch/arm/boot/dts/testcases/tests-interrupts.dtsi b/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
index 6ecda71..560d6bf 100644
--- a/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
+++ b/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
@@ -27,6 +27,12 @@
<4 &test_intc2 15 16>;
};

+ test_intmap1: intmap1 {
+ #interrupt-cells = <2>;
+ #address-cells = <0>;
+ interrupt-map = <1 2 &test_intc0 15>;
+ };
+
interrupts0 {
interrupt-parent = <&test_intc0>;
interrupts = <1>, <2>, <3>, <4>;
@@ -36,6 +42,16 @@
interrupt-parent = <&test_intmap0>;
interrupts = <1>, <2>, <3>, <4>;
};
+
+ interrupts-extended0 {
+ interrupts-extended = <&test_intc0 1>,
+ <&test_intc1 2 3 4>,
+ <&test_intc2 5 6>,
+ <&test_intmap0 1>,
+ <&test_intmap0 2>,
+ <&test_intmap0 3>,
+ <&test_intmap1 1 2>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts
index dde75ae..e01e5a0 100644
--- a/arch/arm/boot/dts/versatile-ab.dts
+++ b/arch/arm/boot/dts/versatile-ab.dts
@@ -185,7 +185,7 @@
mmc@5000 {
compatible = "arm,primecell";
reg = < 0x5000 0x1000>;
- interrupts = <22 34>;
+ interrupts-extended = <&vic 22 &sic 2>;
};
kmi@6000 {
compatible = "arm,pl050", "arm,primecell";
diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts
index 7e81752..f43907c 100644
--- a/arch/arm/boot/dts/versatile-pb.dts
+++ b/arch/arm/boot/dts/versatile-pb.dts
@@ -41,7 +41,7 @@
mmc@b000 {
compatible = "arm,primecell";
reg = <0xb000 0x1000>;
- interrupts = <23 34>;
+ interrupts-extended = <&vic 23 &sic 2>;
};
};
};
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index ddea945..c01f60e 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -292,17 +292,23 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar
if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
return of_irq_parse_oldworld(device, index, out_irq);

+ /* Get the reg property (if any) */
+ addr = of_get_property(device, "reg", NULL);
+
/* Get the interrupts property */
intspec = of_get_property(device, "interrupts", &intlen);
- if (intspec == NULL)
- return -EINVAL;
+ if (intspec == NULL) {
+ /* Try the new-style interrupts-extended */
+ res = of_parse_phandle_with_args(device, "interrupts-extended",
+ "#interrupt-cells", index, out_irq);
+ if (res)
+ return -EINVAL;
+ return of_irq_parse_raw(addr, out_irq);
+ }
intlen /= sizeof(*intspec);

pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen);

- /* Get the reg property (if any) */
- addr = of_get_property(device, "reg", NULL);
-
/* Look for the interrupt parent. */
p = of_irq_find_parent(device);
if (p == NULL)
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c
index 9c80f0b..e21012b 100644
--- a/drivers/of/selftest.c
+++ b/drivers/of/selftest.c
@@ -231,6 +231,75 @@ static void __init of_selftest_parse_interrupts(void)
of_node_put(np);
}

+static void __init of_selftest_parse_interrupts_extended(void)
+{
+ struct device_node *np;
+ struct of_phandle_args args;
+ int i, rc;
+
+ np = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0");
+ if (!np) {
+ pr_err("missing testcase data\n");
+ return;
+ }
+
+ for (i = 0; i < 7; i++) {
+ bool passed = true;
+ rc = of_irq_parse_one(np, i, &args);
+
+ /* Test the values from tests-phandle.dtsi */
+ switch (i) {
+ case 0:
+ passed &= !rc;
+ passed &= (args.args_count == 1);
+ passed &= (args.args[0] == 1);
+ break;
+ case 1:
+ passed &= !rc;
+ passed &= (args.args_count == 3);
+ passed &= (args.args[0] == 2);
+ passed &= (args.args[1] == 3);
+ passed &= (args.args[2] == 4);
+ break;
+ case 2:
+ passed &= !rc;
+ passed &= (args.args_count == 2);
+ passed &= (args.args[0] == 5);
+ passed &= (args.args[1] == 6);
+ break;
+ case 3:
+ passed &= !rc;
+ passed &= (args.args_count == 1);
+ passed &= (args.args[0] == 9);
+ break;
+ case 4:
+ passed &= !rc;
+ passed &= (args.args_count == 3);
+ passed &= (args.args[0] == 10);
+ passed &= (args.args[1] == 11);
+ passed &= (args.args[2] == 12);
+ break;
+ case 5:
+ passed &= !rc;
+ passed &= (args.args_count == 2);
+ passed &= (args.args[0] == 13);
+ passed &= (args.args[1] == 14);
+ break;
+ case 6:
+ passed &= !rc;
+ passed &= (args.args_count == 1);
+ passed &= (args.args[0] == 15);
+ break;
+ default:
+ passed = false;
+ }
+
+ selftest(passed, "index %i - data error on node %s rc=%i\n",
+ i, args.np->full_name, rc);
+ }
+ of_node_put(np);
+}
+
static int __init of_selftest(void)
{
struct device_node *np;
@@ -246,6 +315,7 @@ static int __init of_selftest(void)
of_selftest_parse_phandle_with_args();
of_selftest_property_match_string();
of_selftest_parse_interrupts();
+ of_selftest_parse_interrupts_extended();
pr_info("end of selftest - %i passed, %i failed\n",
selftest_results.passed, selftest_results.failed);
return 0;
--
1.8.1.2

2013-10-15 20:42:05

by Grant Likely

[permalink] [raw]
Subject: [RFC 2/9] of/irq: Replace of_irq with of_phandle_args

struct of_irq and struct of_phandle_args are exactly the same structure.
This patch makes the kernel use of_phandle_args everywhere. This in
itself isn't a big deal, but it makes some follow-on patches simpler.

Signed-off-by: Grant Likely <[email protected]>
Cc: Russell King <[email protected]>
Cc: Michal Simek <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
---
arch/arm/mach-integrator/pci_v3.c | 5 ++---
arch/microblaze/pci/pci-common.c | 9 ++++-----
arch/mips/pci/fixup-lantiq.c | 5 ++---
arch/mips/pci/pci-rt3883.c | 6 ++----
arch/powerpc/kernel/pci-common.c | 9 ++++-----
arch/powerpc/platforms/cell/celleb_scc_pciex.c | 5 ++---
arch/powerpc/platforms/cell/celleb_scc_sio.c | 5 ++---
arch/powerpc/platforms/cell/spider-pic.c | 6 +++---
arch/powerpc/platforms/cell/spu_manage.c | 12 ++++++------
arch/powerpc/platforms/fsl_uli1575.c | 8 +++-----
arch/powerpc/platforms/powermac/pic.c | 8 ++++----
arch/powerpc/platforms/pseries/event_sources.c | 7 +++----
arch/powerpc/sysdev/mpic_msi.c | 6 +++---
arch/x86/kernel/devicetree.c | 5 ++---
drivers/of/irq.c | 15 +++++++--------
drivers/of/of_pci_irq.c | 2 +-
drivers/pci/host/pci-mvebu.c | 5 ++---
include/linux/of_irq.h | 24 ++++--------------------
include/linux/of_pci.h | 4 ++--
19 files changed, 58 insertions(+), 88 deletions(-)

diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 0f496cc..2d6b4da 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -837,7 +837,7 @@ static struct hw_pci pci_v3 __initdata = {

static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin)
{
- struct of_irq oirq;
+ struct of_phandle_args oirq;
int ret;

ret = of_irq_parse_pci(dev, &oirq);
@@ -847,8 +847,7 @@ static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin)
return 0;
}

- return irq_create_of_mapping(oirq.controller, oirq.specifier,
- oirq.size);
+ return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
}

static int __init pci_v3_dtprobe(struct platform_device *pdev,
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 4d5b1a9..c9302c4 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -199,7 +199,7 @@ void pcibios_set_master(struct pci_dev *dev)
*/
int pci_read_irq_line(struct pci_dev *pci_dev)
{
- struct of_irq oirq;
+ struct of_phandle_args oirq;
unsigned int virq;

/* The current device-tree that iSeries generates from the HV
@@ -243,11 +243,10 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
} else {
pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
- oirq.size, oirq.specifier[0], oirq.specifier[1],
- of_node_full_name(oirq.controller));
+ oirq.args_count, oirq.args[0], oirq.args[1],
+ of_node_full_name(oirq.np));

- virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
- oirq.size);
+ virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
}
if (!virq) {
pr_debug(" Failed to map !\n");
diff --git a/arch/mips/pci/fixup-lantiq.c b/arch/mips/pci/fixup-lantiq.c
index 2e8dbfe..81ff0b5 100644
--- a/arch/mips/pci/fixup-lantiq.c
+++ b/arch/mips/pci/fixup-lantiq.c
@@ -25,7 +25,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)

int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
- struct of_irq dev_irq;
+ struct of_phandle_args dev_irq;
int irq;

if (of_irq_parse_pci(dev, &dev_irq)) {
@@ -33,8 +33,7 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
slot, pin);
return 0;
}
- irq = irq_create_of_mapping(dev_irq.controller, dev_irq.specifier,
- dev_irq.size);
+ irq = irq_create_of_mapping(dev_irq.np, dev_irq.args, dev_irq.args_count);
dev_info(&dev->dev, "SLOT:%d PIN:%d IRQ:%d\n", slot, pin, irq);
return irq;
}
diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c
index cae92a0..0f08a5b 100644
--- a/arch/mips/pci/pci-rt3883.c
+++ b/arch/mips/pci/pci-rt3883.c
@@ -583,7 +583,7 @@ err_put_intc_node:

int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
- struct of_irq dev_irq;
+ struct of_phandle_args dev_irq;
int err;
int irq;

@@ -594,9 +594,7 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
return 0;
}

- irq = irq_create_of_mapping(dev_irq.controller,
- dev_irq.specifier,
- dev_irq.size);
+ irq = irq_create_of_mapping(dev_irq.np, dev_irq.args, dev_irq.args_count);

if (irq == 0)
pr_crit("pci %s: no irq found for pin %u\n",
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 2f41854..96c4623 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -228,7 +228,7 @@ int pcibios_add_platform_entries(struct pci_dev *pdev)
*/
static int pci_read_irq_line(struct pci_dev *pci_dev)
{
- struct of_irq oirq;
+ struct of_phandle_args oirq;
unsigned int virq;

pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev));
@@ -263,11 +263,10 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)
irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
} else {
pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
- oirq.size, oirq.specifier[0], oirq.specifier[1],
- of_node_full_name(oirq.controller));
+ oirq.args_count, oirq.args[0], oirq.args[1],
+ of_node_full_name(oirq.np));

- virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
- oirq.size);
+ virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
}
if(virq == NO_IRQ) {
pr_debug(" Failed to map !\n");
diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
index 40bc371..e8d34d1 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
@@ -486,7 +486,7 @@ static __init int celleb_setup_pciex(struct device_node *node,
struct pci_controller *phb)
{
struct resource r;
- struct of_irq oirq;
+ struct of_phandle_args oirq;
int virq;

/* SMMIO registers; used inside this file */
@@ -511,8 +511,7 @@ static __init int celleb_setup_pciex(struct device_node *node,
pr_err("PCIEXC:Failed to map irq\n");
goto error;
}
- virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
- oirq.size);
+ virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
if (request_irq(virq, pciex_handle_internal_irq,
0, "pciex", (void *)phb)) {
pr_err("PCIEXC:Failed to request irq\n");
diff --git a/arch/powerpc/platforms/cell/celleb_scc_sio.c b/arch/powerpc/platforms/cell/celleb_scc_sio.c
index 96388b2..06046d5 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_sio.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_sio.c
@@ -45,7 +45,7 @@ static int __init txx9_serial_init(void)
struct device_node *node;
int i;
struct uart_port req;
- struct of_irq irq;
+ struct of_phandle_args irq;
struct resource res;

for_each_compatible_node(node, "serial", "toshiba,sio-scc") {
@@ -66,8 +66,7 @@ static int __init txx9_serial_init(void)
#ifdef CONFIG_SERIAL_TXX9_CONSOLE
req.membase = ioremap(req.mapbase, 0x24);
#endif
- req.irq = irq_create_of_mapping(irq.controller,
- irq.specifier, irq.size);
+ req.irq = irq_create_of_mapping(irq.np, irq.args, irq.args_count);
req.flags |= UPF_IOREMAP | UPF_BUGGY_UART
/*HAVE_CTS_LINE*/;
req.uartclk = 83300000;
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index b491f40..6e842fd 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -235,10 +235,10 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
/* First, we check whether we have a real "interrupts" in the device
* tree in case the device-tree is ever fixed
*/
- struct of_irq oirq;
+ struct of_phandle_args oirq;
if (of_irq_parse_one(pic->host->of_node, 0, &oirq) == 0) {
- virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
- oirq.size);
+ virq = irq_create_of_mapping(oirq.np, oirq.args,
+ oirq.args_count);
return virq;
}

diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c
index e6cdb81..e9eb4f8 100644
--- a/arch/powerpc/platforms/cell/spu_manage.c
+++ b/arch/powerpc/platforms/cell/spu_manage.c
@@ -177,7 +177,7 @@ out:

static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
{
- struct of_irq oirq;
+ struct of_phandle_args oirq;
int ret;
int i;

@@ -188,10 +188,10 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
goto err;
}
ret = -EINVAL;
- pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0],
- oirq.controller->full_name);
- spu->irqs[i] = irq_create_of_mapping(oirq.controller,
- oirq.specifier, oirq.size);
+ pr_debug(" irq %d no 0x%x on %s\n", i, oirq.args[0],
+ oirq.np->full_name);
+ spu->irqs[i] = irq_create_of_mapping(oirq.np,
+ oirq.args, oirq.args_count);
if (spu->irqs[i] == NO_IRQ) {
pr_debug("spu_new: failed to map it !\n");
goto err;
@@ -200,7 +200,7 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
return 0;

err:
- pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier,
+ pr_debug("failed to map irq %x for spu %s\n", *oirq.args,
spu->name);
for (; i >= 0; i--) {
if (spu->irqs[i] != NO_IRQ)
diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c
index ac539c1..288226d 100644
--- a/arch/powerpc/platforms/fsl_uli1575.c
+++ b/arch/powerpc/platforms/fsl_uli1575.c
@@ -321,8 +321,8 @@ static void hpcd_final_uli5288(struct pci_dev *dev)
{
struct pci_controller *hose = pci_bus_to_host(dev->bus);
struct device_node *hosenode = hose ? hose->dn : NULL;
- struct of_irq oirq;
- int virq, pin = 2;
+ struct of_phandle_args oirq;
+ int pin = 2;
u32 laddr[3];

if (!machine_is(mpc86xx_hpcd))
@@ -334,9 +334,7 @@ static void hpcd_final_uli5288(struct pci_dev *dev)
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);
- virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
- oirq.size);
- dev->irq = virq;
+ dev->irq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
}

DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, hpcd_quirk_uli1575);
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 720663e..4c24bf6 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -394,7 +394,7 @@ static void __init pmac_pic_probe_oldstyle(void)
}

int of_irq_parse_oldworld(struct device_node *device, int index,
- struct of_irq *out_irq)
+ struct of_phandle_args *out_irq)
{
const u32 *ints = NULL;
int intlen;
@@ -422,9 +422,9 @@ int of_irq_parse_oldworld(struct device_node *device, int index,
if (index >= intlen)
return -EINVAL;

- out_irq->controller = NULL;
- out_irq->specifier[0] = ints[index];
- out_irq->size = 1;
+ out_irq->np = NULL;
+ out_irq->args[0] = ints[index];
+ out_irq->args_count = 1;

return 0;
}
diff --git a/arch/powerpc/platforms/pseries/event_sources.c b/arch/powerpc/platforms/pseries/event_sources.c
index 850c18c..6dcf9cc 100644
--- a/arch/powerpc/platforms/pseries/event_sources.c
+++ b/arch/powerpc/platforms/pseries/event_sources.c
@@ -25,7 +25,7 @@ void request_event_sources_irqs(struct device_node *np,
const char *name)
{
int i, index, count = 0;
- struct of_irq oirq;
+ struct of_phandle_args oirq;
const u32 *opicprop;
unsigned int opicplen;
unsigned int virqs[16];
@@ -59,9 +59,8 @@ void request_event_sources_irqs(struct device_node *np,
index++) {
if (count > 15)
break;
- virqs[count] = irq_create_of_mapping(oirq.controller,
- oirq.specifier,
- oirq.size);
+ virqs[count] = irq_create_of_mapping(oirq.np, oirq.args,
+ oirq.args_count);
if (virqs[count] == NO_IRQ) {
pr_err("event-sources: Unable to allocate "
"interrupt number for %s\n",
diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c
index 463e3a7..7dc39f3 100644
--- a/arch/powerpc/sysdev/mpic_msi.c
+++ b/arch/powerpc/sysdev/mpic_msi.c
@@ -35,7 +35,7 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
const struct irq_domain_ops *ops = mpic->irqhost->ops;
struct device_node *np;
int flags, index, i;
- struct of_irq oirq;
+ struct of_phandle_args oirq;

pr_debug("mpic: found U3, guessing msi allocator setup\n");

@@ -64,8 +64,8 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)

index = 0;
while (of_irq_parse_one(np, index++, &oirq) == 0) {
- ops->xlate(mpic->irqhost, NULL, oirq.specifier,
- oirq.size, &hwirq, &flags);
+ ops->xlate(mpic->irqhost, NULL, oirq.args,
+ oirq.args_count, &hwirq, &flags);
msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq);
}
}
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 3ac6398..0098698 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -105,7 +105,7 @@ struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)

static int x86_of_pci_irq_enable(struct pci_dev *dev)
{
- struct of_irq oirq;
+ struct of_phandle_args oirq;
u32 virq;
int ret;
u8 pin;
@@ -120,8 +120,7 @@ static int x86_of_pci_irq_enable(struct pci_dev *dev)
if (ret)
return ret;

- virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
- oirq.size);
+ virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
if (virq == 0)
return -EINVAL;
dev->irq = virq;
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 410aa24..a7db38a 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -36,13 +36,12 @@
*/
unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
{
- struct of_irq oirq;
+ struct of_phandle_args oirq;

if (of_irq_parse_one(dev, index, &oirq))
return 0;

- return irq_create_of_mapping(oirq.controller, oirq.specifier,
- oirq.size);
+ return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
}
EXPORT_SYMBOL_GPL(irq_of_parse_and_map);

@@ -94,7 +93,7 @@ struct device_node *of_irq_find_parent(struct device_node *child)
* node exist for the parent.
*/
int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec,
- u32 ointsize, const __be32 *addr, struct of_irq *out_irq)
+ u32 ointsize, const __be32 *addr, struct of_phandle_args *out_irq)
{
struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
const __be32 *tmp, *imap, *imask;
@@ -156,10 +155,10 @@ int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec,
NULL) {
pr_debug(" -> got it !\n");
for (i = 0; i < intsize; i++)
- out_irq->specifier[i] =
+ out_irq->args[i] =
of_read_number(intspec +i, 1);
- out_irq->size = intsize;
- out_irq->controller = ipar;
+ out_irq->args_count = intsize;
+ out_irq->np = ipar;
of_node_put(old);
return 0;
}
@@ -280,7 +279,7 @@ EXPORT_SYMBOL_GPL(of_irq_parse_raw);
* 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().
*/
-int of_irq_parse_one(struct device_node *device, int index, struct of_irq *out_irq)
+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;
diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c
index dceec10..ee3293d 100644
--- a/drivers/of/of_pci_irq.c
+++ b/drivers/of/of_pci_irq.c
@@ -15,7 +15,7 @@
* PCI tree until an device-node is found, at which point it will finish
* resolving using the OF tree walking.
*/
-int of_irq_parse_pci(const struct pci_dev *pdev, struct of_irq *out_irq)
+int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
{
struct device_node *dn, *ppnode;
struct pci_dev *ppdev;
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 05f8180..c5e57f8 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -647,15 +647,14 @@ static int __init mvebu_pcie_setup(int nr, struct pci_sys_data *sys)

static int __init mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
- struct of_irq oirq;
+ struct of_phandle_args oirq;
int ret;

ret = of_irq_parse_pci(dev, &oirq);
if (ret)
return ret;

- return irq_create_of_mapping(oirq.controller, oirq.specifier,
- oirq.size);
+ return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
}

static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index a00bc71..8d9f855 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -8,22 +8,6 @@
#include <linux/ioport.h>
#include <linux/of.h>

-/**
- * of_irq - container for device_node/irq_specifier pair for an irq controller
- * @controller: pointer to interrupt controller device tree node
- * @size: size of interrupt specifier
- * @specifier: array of cells @size long specifing the specific interrupt
- *
- * This structure is returned when an interrupt is mapped. The controller
- * field needs to be put() after use
- */
-#define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */
-struct of_irq {
- struct device_node *controller; /* Interrupt controller node */
- u32 size; /* Specifier size */
- u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
-};
-
typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *);

/*
@@ -36,12 +20,12 @@ typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *);
extern unsigned int of_irq_workarounds;
extern struct device_node *of_irq_dflt_pic;
extern int of_irq_parse_oldworld(struct device_node *device, int index,
- struct of_irq *out_irq);
+ struct of_phandle_args *out_irq);
#else /* CONFIG_PPC32 && CONFIG_PPC_PMAC */
#define of_irq_workarounds (0)
#define of_irq_dflt_pic (NULL)
static inline int of_irq_parse_oldworld(struct device_node *device, int index,
- struct of_irq *out_irq)
+ struct of_phandle_args *out_irq)
{
return -EINVAL;
}
@@ -50,9 +34,9 @@ static inline int of_irq_parse_oldworld(struct device_node *device, int index,

extern int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec,
u32 ointsize, const __be32 *addr,
- struct of_irq *out_irq);
+ struct of_phandle_args *out_irq);
extern int of_irq_parse_one(struct device_node *device, int index,
- struct of_irq *out_irq);
+ struct of_phandle_args *out_irq);
extern unsigned int irq_create_of_mapping(struct device_node *controller,
const u32 *intspec,
unsigned int intsize);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index 839ba20..f297237 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -5,8 +5,8 @@
#include <linux/msi.h>

struct pci_dev;
-struct of_irq;
-int of_irq_parse_pci(const struct pci_dev *pdev, struct of_irq *out_irq);
+struct of_phandle_args;
+int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq);

struct device_node;
struct device_node *of_pci_find_child_device(struct device_node *parent,
--
1.8.1.2

2013-10-15 20:42:01

by Grant Likely

[permalink] [raw]
Subject: [RFC 3/9] of/irq: simplify args to irq_create_of_mapping

All the callers of irq_create_of_mapping() pass the contents of a struct
of_phandle_args structure to the function. Since all the callers already
have an of_phandle_args pointer, why not pass it directly to
irq_create_of_mapping()?

Signed-off-by: Grant Likely <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Russell King <[email protected]>
Cc: Michal Simek <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
---
arch/arm/mach-integrator/pci_v3.c | 2 +-
arch/microblaze/pci/pci-common.c | 2 +-
arch/mips/pci/fixup-lantiq.c | 2 +-
arch/mips/pci/pci-rt3883.c | 2 +-
arch/powerpc/kernel/pci-common.c | 2 +-
arch/powerpc/platforms/cell/celleb_scc_pciex.c | 2 +-
arch/powerpc/platforms/cell/celleb_scc_sio.c | 2 +-
arch/powerpc/platforms/cell/spider-pic.c | 7 ++-----
arch/powerpc/platforms/cell/spu_manage.c | 3 +--
arch/powerpc/platforms/fsl_uli1575.c | 2 +-
arch/powerpc/platforms/pseries/event_sources.c | 3 +--
arch/x86/kernel/devicetree.c | 2 +-
drivers/of/irq.c | 2 +-
drivers/pci/host/pci-mvebu.c | 2 +-
include/linux/of_irq.h | 4 +---
kernel/irq/irqdomain.c | 13 ++++++-------
16 files changed, 22 insertions(+), 30 deletions(-)

diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 2d6b4da..bb3aeb3 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -847,7 +847,7 @@ static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin)
return 0;
}

- return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ return irq_create_of_mapping(&oirq);
}

static int __init pci_v3_dtprobe(struct platform_device *pdev,
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index c9302c4..60b386c 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -246,7 +246,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
oirq.args_count, oirq.args[0], oirq.args[1],
of_node_full_name(oirq.np));

- virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ virq = irq_create_of_mapping(&oirq);
}
if (!virq) {
pr_debug(" Failed to map !\n");
diff --git a/arch/mips/pci/fixup-lantiq.c b/arch/mips/pci/fixup-lantiq.c
index 81ff0b5..aef60e7 100644
--- a/arch/mips/pci/fixup-lantiq.c
+++ b/arch/mips/pci/fixup-lantiq.c
@@ -33,7 +33,7 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
slot, pin);
return 0;
}
- irq = irq_create_of_mapping(dev_irq.np, dev_irq.args, dev_irq.args_count);
+ irq = irq_create_of_mapping(&dev_irq);
dev_info(&dev->dev, "SLOT:%d PIN:%d IRQ:%d\n", slot, pin, irq);
return irq;
}
diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c
index 0f08a5b..eadc431 100644
--- a/arch/mips/pci/pci-rt3883.c
+++ b/arch/mips/pci/pci-rt3883.c
@@ -594,7 +594,7 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
return 0;
}

- irq = irq_create_of_mapping(dev_irq.np, dev_irq.args, dev_irq.args_count);
+ irq = irq_create_of_mapping(&dev_irq);

if (irq == 0)
pr_crit("pci %s: no irq found for pin %u\n",
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 96c4623..a1e3e40 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -266,7 +266,7 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)
oirq.args_count, oirq.args[0], oirq.args[1],
of_node_full_name(oirq.np));

- virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ virq = irq_create_of_mapping(&oirq);
}
if(virq == NO_IRQ) {
pr_debug(" Failed to map !\n");
diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
index e8d34d1..b3ea96d 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
@@ -511,7 +511,7 @@ static __init int celleb_setup_pciex(struct device_node *node,
pr_err("PCIEXC:Failed to map irq\n");
goto error;
}
- virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ virq = irq_create_of_mapping(&oirq);
if (request_irq(virq, pciex_handle_internal_irq,
0, "pciex", (void *)phb)) {
pr_err("PCIEXC:Failed to request irq\n");
diff --git a/arch/powerpc/platforms/cell/celleb_scc_sio.c b/arch/powerpc/platforms/cell/celleb_scc_sio.c
index 06046d5..c8eb571 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_sio.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_sio.c
@@ -66,7 +66,7 @@ static int __init txx9_serial_init(void)
#ifdef CONFIG_SERIAL_TXX9_CONSOLE
req.membase = ioremap(req.mapbase, 0x24);
#endif
- req.irq = irq_create_of_mapping(irq.np, irq.args, irq.args_count);
+ req.irq = irq_create_of_mapping(&irq);
req.flags |= UPF_IOREMAP | UPF_BUGGY_UART
/*HAVE_CTS_LINE*/;
req.uartclk = 83300000;
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 6e842fd..d206804 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -236,11 +236,8 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
* tree in case the device-tree is ever fixed
*/
struct of_phandle_args oirq;
- if (of_irq_parse_one(pic->host->of_node, 0, &oirq) == 0) {
- virq = irq_create_of_mapping(oirq.np, oirq.args,
- oirq.args_count);
- return virq;
- }
+ if (of_irq_parse_one(pic->host->of_node, 0, &oirq) == 0)
+ return irq_create_of_mapping(&oirq);

/* Now do the horrible hacks */
tmp = of_get_property(pic->host->of_node, "#interrupt-cells", NULL);
diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c
index e9eb4f8..c3327f3 100644
--- a/arch/powerpc/platforms/cell/spu_manage.c
+++ b/arch/powerpc/platforms/cell/spu_manage.c
@@ -190,8 +190,7 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
ret = -EINVAL;
pr_debug(" irq %d no 0x%x on %s\n", i, oirq.args[0],
oirq.np->full_name);
- spu->irqs[i] = irq_create_of_mapping(oirq.np,
- oirq.args, oirq.args_count);
+ spu->irqs[i] = irq_create_of_mapping(&oirq);
if (spu->irqs[i] == NO_IRQ) {
pr_debug("spu_new: failed to map it !\n");
goto err;
diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c
index 288226d..8904046 100644
--- a/arch/powerpc/platforms/fsl_uli1575.c
+++ b/arch/powerpc/platforms/fsl_uli1575.c
@@ -334,7 +334,7 @@ static void hpcd_final_uli5288(struct pci_dev *dev)
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);
- dev->irq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ dev->irq = irq_create_of_mapping(&oirq);
}

DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, hpcd_quirk_uli1575);
diff --git a/arch/powerpc/platforms/pseries/event_sources.c b/arch/powerpc/platforms/pseries/event_sources.c
index 6dcf9cc..18380e8 100644
--- a/arch/powerpc/platforms/pseries/event_sources.c
+++ b/arch/powerpc/platforms/pseries/event_sources.c
@@ -59,8 +59,7 @@ void request_event_sources_irqs(struct device_node *np,
index++) {
if (count > 15)
break;
- virqs[count] = irq_create_of_mapping(oirq.np, oirq.args,
- oirq.args_count);
+ virqs[count] = irq_create_of_mapping(&oirq);
if (virqs[count] == NO_IRQ) {
pr_err("event-sources: Unable to allocate "
"interrupt number for %s\n",
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 0098698..d39948f 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -120,7 +120,7 @@ static int x86_of_pci_irq_enable(struct pci_dev *dev)
if (ret)
return ret;

- virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ virq = irq_create_of_mapping(&oirq);
if (virq == 0)
return -EINVAL;
dev->irq = virq;
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index a7db38a..84184c4 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -41,7 +41,7 @@ unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
if (of_irq_parse_one(dev, index, &oirq))
return 0;

- return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ return irq_create_of_mapping(&oirq);
}
EXPORT_SYMBOL_GPL(irq_of_parse_and_map);

diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index c5e57f8..3a8d01e 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -654,7 +654,7 @@ static int __init mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
if (ret)
return ret;

- return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ return irq_create_of_mapping(&oirq);
}

static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index 8d9f855..3bbba8d 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -37,9 +37,7 @@ extern int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec,
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 device_node *controller,
- const u32 *intspec,
- unsigned int intsize);
+extern unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data);
extern int of_irq_to_resource(struct device_node *dev, int index,
struct resource *r);
extern int of_irq_count(struct device_node *dev);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 706724e..cf68bb36 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -465,27 +465,26 @@ int irq_create_strict_mappings(struct irq_domain *domain, unsigned int irq_base,
}
EXPORT_SYMBOL_GPL(irq_create_strict_mappings);

-unsigned int irq_create_of_mapping(struct device_node *controller,
- const u32 *intspec, unsigned int intsize)
+unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data)
{
struct irq_domain *domain;
irq_hw_number_t hwirq;
unsigned int type = IRQ_TYPE_NONE;
unsigned int virq;

- domain = controller ? irq_find_host(controller) : irq_default_domain;
+ domain = irq_data->np ? irq_find_host(irq_data->np) : irq_default_domain;
if (!domain) {
pr_warn("no irq domain found for %s !\n",
- of_node_full_name(controller));
+ of_node_full_name(irq_data->np));
return 0;
}

/* If domain has no translation, then we assume interrupt line */
if (domain->ops->xlate == NULL)
- hwirq = intspec[0];
+ hwirq = irq_data->args[0];
else {
- if (domain->ops->xlate(domain, controller, intspec, intsize,
- &hwirq, &type))
+ if (domain->ops->xlate(domain, irq_data->np, irq_data->args,
+ irq_data->args_count, &hwirq, &type))
return 0;
}

--
1.8.1.2

2013-10-15 20:42:37

by Grant Likely

[permalink] [raw]
Subject: [RFC 1/9] of/irq: Rename of_irq_map_* functions to of_irq_parse_*

The OF irq handling code has been overloading the term 'map' to refer to
both parsing the data in the device tree and mapping it to the internal
linux irq system. This is probably because the device tree does have the
concept of an 'interrupt-map' function for translating interrupt
references from one node to another, but 'map' is still confusing when
the primary purpose of some of the functions are to parse the DT data.

This patch renames all the of_irq_map_* functions to of_irq_parse_*
which makes it clear that there is a difference between the parsing
phase and the mapping phase. Kernel code can make use of just the
parsing or just the mapping support as needed by the subsystem.

The patch was generated mechanically with a handful of sed commands.

Signed-off-by: Grant Likely <[email protected]>
Cc: Michal Simek <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
---
arch/arm/mach-integrator/pci_v3.c | 4 ++--
arch/microblaze/pci/pci-common.c | 2 +-
arch/mips/pci/fixup-lantiq.c | 2 +-
arch/mips/pci/pci-rt3883.c | 2 +-
arch/powerpc/kernel/pci-common.c | 2 +-
arch/powerpc/platforms/cell/celleb_scc_pciex.c | 2 +-
arch/powerpc/platforms/cell/celleb_scc_sio.c | 2 +-
arch/powerpc/platforms/cell/spider-pic.c | 2 +-
arch/powerpc/platforms/cell/spu_manage.c | 2 +-
arch/powerpc/platforms/fsl_uli1575.c | 2 +-
arch/powerpc/platforms/powermac/pic.c | 2 +-
arch/powerpc/platforms/pseries/event_sources.c | 2 +-
arch/powerpc/sysdev/mpic_msi.c | 2 +-
arch/x86/kernel/devicetree.c | 2 +-
drivers/of/address.c | 4 ++--
drivers/of/irq.c | 28 +++++++++++++-------------
drivers/of/of_pci_irq.c | 10 ++++-----
drivers/pci/host/pci-mvebu.c | 2 +-
include/linux/of_irq.h | 8 ++++----
include/linux/of_pci.h | 2 +-
20 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index bef1005..0f496cc 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -840,9 +840,9 @@ static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin)
struct of_irq oirq;
int ret;

- ret = of_irq_map_pci(dev, &oirq);
+ ret = of_irq_parse_pci(dev, &oirq);
if (ret) {
- dev_err(&dev->dev, "of_irq_map_pci() %d\n", ret);
+ dev_err(&dev->dev, "of_irq_parse_pci() %d\n", ret);
/* Proper return code 0 == NO_IRQ */
return 0;
}
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 1b93bf0..4d5b1a9 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -217,7 +217,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
memset(&oirq, 0xff, sizeof(oirq));
#endif
/* Try to get a mapping from the device-tree */
- if (of_irq_map_pci(pci_dev, &oirq)) {
+ if (of_irq_parse_pci(pci_dev, &oirq)) {
u8 line, pin;

/* If that fails, lets fallback to what is in the config
diff --git a/arch/mips/pci/fixup-lantiq.c b/arch/mips/pci/fixup-lantiq.c
index 6c829df..2e8dbfe 100644
--- a/arch/mips/pci/fixup-lantiq.c
+++ b/arch/mips/pci/fixup-lantiq.c
@@ -28,7 +28,7 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
struct of_irq dev_irq;
int irq;

- if (of_irq_map_pci(dev, &dev_irq)) {
+ if (of_irq_parse_pci(dev, &dev_irq)) {
dev_err(&dev->dev, "trying to map irq for unknown slot:%d pin:%d\n",
slot, pin);
return 0;
diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c
index 95c9d41..cae92a0 100644
--- a/arch/mips/pci/pci-rt3883.c
+++ b/arch/mips/pci/pci-rt3883.c
@@ -587,7 +587,7 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
int err;
int irq;

- err = of_irq_map_pci(dev, &dev_irq);
+ err = of_irq_parse_pci(dev, &dev_irq);
if (err) {
pr_err("pci %s: unable to get irq map, err=%d\n",
pci_name((struct pci_dev *) dev), err);
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 905a24b..2f41854 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -237,7 +237,7 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)
memset(&oirq, 0xff, sizeof(oirq));
#endif
/* Try to get a mapping from the device-tree */
- if (of_irq_map_pci(pci_dev, &oirq)) {
+ if (of_irq_parse_pci(pci_dev, &oirq)) {
u8 line, pin;

/* If that fails, lets fallback to what is in the config
diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
index 14be2bd..40bc371 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
@@ -507,7 +507,7 @@ static __init int celleb_setup_pciex(struct device_node *node,
phb->ops = &scc_pciex_pci_ops;

/* internal interrupt handler */
- if (of_irq_map_one(node, 1, &oirq)) {
+ if (of_irq_parse_one(node, 1, &oirq)) {
pr_err("PCIEXC:Failed to map irq\n");
goto error;
}
diff --git a/arch/powerpc/platforms/cell/celleb_scc_sio.c b/arch/powerpc/platforms/cell/celleb_scc_sio.c
index 9c339ec..96388b2 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_sio.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_sio.c
@@ -53,7 +53,7 @@ static int __init txx9_serial_init(void)
if (!(txx9_serial_bitmap & (1<<i)))
continue;

- if (of_irq_map_one(node, i, &irq))
+ if (of_irq_parse_one(node, i, &irq))
continue;
if (of_address_to_resource(node,
txx9_scc_tab[i].index, &res))
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 8e29944..b491f40 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -236,7 +236,7 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
* tree in case the device-tree is ever fixed
*/
struct of_irq oirq;
- if (of_irq_map_one(pic->host->of_node, 0, &oirq) == 0) {
+ if (of_irq_parse_one(pic->host->of_node, 0, &oirq) == 0) {
virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
oirq.size);
return virq;
diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c
index 2bb6977..e6cdb81 100644
--- a/arch/powerpc/platforms/cell/spu_manage.c
+++ b/arch/powerpc/platforms/cell/spu_manage.c
@@ -182,7 +182,7 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
int i;

for (i=0; i < 3; i++) {
- ret = of_irq_map_one(np, i, &oirq);
+ ret = of_irq_parse_one(np, i, &oirq);
if (ret) {
pr_debug("spu_new: failed to get irq %d\n", i);
goto err;
diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c
index 92ac9b5..ac539c1 100644
--- a/arch/powerpc/platforms/fsl_uli1575.c
+++ b/arch/powerpc/platforms/fsl_uli1575.c
@@ -333,7 +333,7 @@ static void hpcd_final_uli5288(struct pci_dev *dev)

laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(31, 0) << 8);
laddr[1] = laddr[2] = 0;
- of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq);
+ of_irq_parse_raw(hosenode, &pin, 1, laddr, &oirq);
virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
oirq.size);
dev->irq = virq;
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 31036b5..720663e 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -393,7 +393,7 @@ static void __init pmac_pic_probe_oldstyle(void)
#endif
}

-int of_irq_map_oldworld(struct device_node *device, int index,
+int of_irq_parse_oldworld(struct device_node *device, int index,
struct of_irq *out_irq)
{
const u32 *ints = NULL;
diff --git a/arch/powerpc/platforms/pseries/event_sources.c b/arch/powerpc/platforms/pseries/event_sources.c
index 2605c31..850c18c 100644
--- a/arch/powerpc/platforms/pseries/event_sources.c
+++ b/arch/powerpc/platforms/pseries/event_sources.c
@@ -55,7 +55,7 @@ void request_event_sources_irqs(struct device_node *np,
/* Else use normal interrupt tree parsing */
else {
/* First try to do a proper OF tree parsing */
- for (index = 0; of_irq_map_one(np, index, &oirq) == 0;
+ for (index = 0; of_irq_parse_one(np, index, &oirq) == 0;
index++) {
if (count > 15)
break;
diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c
index bbf342c..463e3a7 100644
--- a/arch/powerpc/sysdev/mpic_msi.c
+++ b/arch/powerpc/sysdev/mpic_msi.c
@@ -63,7 +63,7 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
pr_debug("mpic: mapping hwirqs for %s\n", np->full_name);

index = 0;
- while (of_irq_map_one(np, index++, &oirq) == 0) {
+ while (of_irq_parse_one(np, index++, &oirq) == 0) {
ops->xlate(mpic->irqhost, NULL, oirq.specifier,
oirq.size, &hwirq, &flags);
msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq);
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 376dc78..3ac6398 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -116,7 +116,7 @@ static int x86_of_pci_irq_enable(struct pci_dev *dev)
if (!pin)
return 0;

- ret = of_irq_map_pci(dev, &oirq);
+ ret = of_irq_parse_pci(dev, &oirq);
if (ret)
return ret;

diff --git a/drivers/of/address.c b/drivers/of/address.c
index 71180b9..994f293 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -532,12 +532,12 @@ static u64 __of_translate_address(struct device_node *dev,
pbus->count_cells(dev, &pna, &pns);
if (!OF_CHECK_COUNTS(pna, pns)) {
printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
- dev->full_name);
+ of_node_full_name(dev));
break;
}

pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
- pbus->name, pna, pns, parent->full_name);
+ pbus->name, pna, pns, of_node_full_name(parent));

/* Apply bus translation */
if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 90068f9..410aa24 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -31,14 +31,14 @@
* @dev: Device node of the device whose interrupt is to be mapped
* @index: Index of the interrupt to map
*
- * This function is a wrapper that chains of_irq_map_one() and
+ * This function is a wrapper that chains of_irq_parse_one() and
* irq_create_of_mapping() to make things easier to callers
*/
unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
{
struct of_irq oirq;

- if (of_irq_map_one(dev, index, &oirq))
+ if (of_irq_parse_one(dev, index, &oirq))
return 0;

return irq_create_of_mapping(oirq.controller, oirq.specifier,
@@ -79,7 +79,7 @@ struct device_node *of_irq_find_parent(struct device_node *child)
}

/**
- * of_irq_map_raw - Low level interrupt tree parsing
+ * 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
@@ -93,7 +93,7 @@ struct device_node *of_irq_find_parent(struct device_node *child)
* properties, for example when resolving PCI interrupts when no device
* node exist for the parent.
*/
-int of_irq_map_raw(struct device_node *parent, const __be32 *intspec,
+int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec,
u32 ointsize, const __be32 *addr, struct of_irq *out_irq)
{
struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
@@ -101,7 +101,7 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec,
u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
int imaplen, match, i;

- pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
+ 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);

@@ -126,7 +126,7 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec,
goto fail;
}

- pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize);
+ pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize);

if (ointsize != intsize)
return -EINVAL;
@@ -269,29 +269,29 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec,

return -EINVAL;
}
-EXPORT_SYMBOL_GPL(of_irq_map_raw);
+EXPORT_SYMBOL_GPL(of_irq_parse_raw);

/**
- * of_irq_map_one - Resolve an interrupt for a device
+ * of_irq_parse_one - Resolve an interrupt for a device
* @device: the device whose interrupt is to be resolved
* @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_map_raw().
+ * device-tree node. It's the high level pendant to of_irq_parse_raw().
*/
-int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
+int of_irq_parse_one(struct device_node *device, int index, struct of_irq *out_irq)
{
struct device_node *p;
const __be32 *intspec, *tmp, *addr;
u32 intsize, intlen;
int res = -EINVAL;

- pr_debug("of_irq_map_one: dev=%s, index=%d\n", of_node_full_name(device), index);
+ pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index);

/* OldWorld mac stuff is "special", handle out of line */
if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
- return of_irq_map_oldworld(device, index, out_irq);
+ return of_irq_parse_oldworld(device, index, out_irq);

/* Get the interrupts property */
intspec = of_get_property(device, "interrupts", &intlen);
@@ -322,13 +322,13 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
goto out;

/* Get new specifier and map it */
- res = of_irq_map_raw(p, intspec + index * intsize, intsize,
+ res = of_irq_parse_raw(p, intspec + index * intsize, intsize,
addr, out_irq);
out:
of_node_put(p);
return res;
}
-EXPORT_SYMBOL_GPL(of_irq_map_one);
+EXPORT_SYMBOL_GPL(of_irq_parse_one);

/**
* of_irq_to_resource - Decode a node's IRQ and return it as a resource
diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c
index 6770538..dceec10 100644
--- a/drivers/of/of_pci_irq.c
+++ b/drivers/of/of_pci_irq.c
@@ -5,7 +5,7 @@
#include <asm/prom.h>

/**
- * of_irq_map_pci - Resolve the interrupt for a PCI device
+ * of_irq_parse_pci - Resolve the interrupt for a PCI device
* @pdev: the device whose interrupt is to be resolved
* @out_irq: structure of_irq filled by this function
*
@@ -15,7 +15,7 @@
* PCI tree until an device-node is found, at which point it will finish
* resolving using the OF tree walking.
*/
-int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq)
+int of_irq_parse_pci(const struct pci_dev *pdev, struct of_irq *out_irq)
{
struct device_node *dn, *ppnode;
struct pci_dev *ppdev;
@@ -30,7 +30,7 @@ int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq)
*/
dn = pci_device_to_OF_node(pdev);
if (dn) {
- rc = of_irq_map_one(dn, 0, out_irq);
+ rc = of_irq_parse_one(dn, 0, out_irq);
if (!rc)
return rc;
}
@@ -88,6 +88,6 @@ int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq)
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_map_raw(ppnode, &lspec_be, 1, laddr, out_irq);
+ return of_irq_parse_raw(ppnode, &lspec_be, 1, laddr, out_irq);
}
-EXPORT_SYMBOL_GPL(of_irq_map_pci);
+EXPORT_SYMBOL_GPL(of_irq_parse_pci);
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 729d5a1..05f8180 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -650,7 +650,7 @@ static int __init mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
struct of_irq oirq;
int ret;

- ret = of_irq_map_pci(dev, &oirq);
+ ret = of_irq_parse_pci(dev, &oirq);
if (ret)
return ret;

diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index fcd63ba..a00bc71 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -35,12 +35,12 @@ typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *);
#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC)
extern unsigned int of_irq_workarounds;
extern struct device_node *of_irq_dflt_pic;
-extern int of_irq_map_oldworld(struct device_node *device, int index,
+extern int of_irq_parse_oldworld(struct device_node *device, int index,
struct of_irq *out_irq);
#else /* CONFIG_PPC32 && CONFIG_PPC_PMAC */
#define of_irq_workarounds (0)
#define of_irq_dflt_pic (NULL)
-static inline int of_irq_map_oldworld(struct device_node *device, int index,
+static inline int of_irq_parse_oldworld(struct device_node *device, int index,
struct of_irq *out_irq)
{
return -EINVAL;
@@ -48,10 +48,10 @@ static inline int of_irq_map_oldworld(struct device_node *device, int index,
#endif /* CONFIG_PPC32 && CONFIG_PPC_PMAC */


-extern int of_irq_map_raw(struct device_node *parent, const __be32 *intspec,
+extern int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec,
u32 ointsize, const __be32 *addr,
struct of_irq *out_irq);
-extern int of_irq_map_one(struct device_node *device, int index,
+extern int of_irq_parse_one(struct device_node *device, int index,
struct of_irq *out_irq);
extern unsigned int irq_create_of_mapping(struct device_node *controller,
const u32 *intspec,
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index fd9c408..839ba20 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -6,7 +6,7 @@

struct pci_dev;
struct of_irq;
-int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq);
+int of_irq_parse_pci(const struct pci_dev *pdev, struct of_irq *out_irq);

struct device_node;
struct device_node *of_pci_find_child_device(struct device_node *parent,
--
1.8.1.2

2013-10-16 10:47:46

by Michal Simek

[permalink] [raw]
Subject: Re: [RFC 1/9] of/irq: Rename of_irq_map_* functions to of_irq_parse_*

On 10/15/2013 10:39 PM, Grant Likely wrote:
> The OF irq handling code has been overloading the term 'map' to refer to
> both parsing the data in the device tree and mapping it to the internal
> linux irq system. This is probably because the device tree does have the
> concept of an 'interrupt-map' function for translating interrupt
> references from one node to another, but 'map' is still confusing when
> the primary purpose of some of the functions are to parse the DT data.
>
> This patch renames all the of_irq_map_* functions to of_irq_parse_*
> which makes it clear that there is a difference between the parsing
> phase and the mapping phase. Kernel code can make use of just the
> parsing or just the mapping support as needed by the subsystem.
>
> The patch was generated mechanically with a handful of sed commands.
>
> Signed-off-by: Grant Likely <[email protected]>
> Cc: Michal Simek <[email protected]>
> Cc: Ralf Baechle <[email protected]>
> Cc: Benjamin Herrenschmidt <[email protected]>
> ---
> arch/arm/mach-integrator/pci_v3.c | 4 ++--
> arch/microblaze/pci/pci-common.c | 2 +-
> arch/mips/pci/fixup-lantiq.c | 2 +-
> arch/mips/pci/pci-rt3883.c | 2 +-
> arch/powerpc/kernel/pci-common.c | 2 +-
> arch/powerpc/platforms/cell/celleb_scc_pciex.c | 2 +-
> arch/powerpc/platforms/cell/celleb_scc_sio.c | 2 +-
> arch/powerpc/platforms/cell/spider-pic.c | 2 +-
> arch/powerpc/platforms/cell/spu_manage.c | 2 +-
> arch/powerpc/platforms/fsl_uli1575.c | 2 +-
> arch/powerpc/platforms/powermac/pic.c | 2 +-
> arch/powerpc/platforms/pseries/event_sources.c | 2 +-
> arch/powerpc/sysdev/mpic_msi.c | 2 +-
> arch/x86/kernel/devicetree.c | 2 +-
> drivers/of/address.c | 4 ++--
> drivers/of/irq.c | 28 +++++++++++++-------------
> drivers/of/of_pci_irq.c | 10 ++++-----
> drivers/pci/host/pci-mvebu.c | 2 +-
> include/linux/of_irq.h | 8 ++++----
> include/linux/of_pci.h | 2 +-
> 20 files changed, 42 insertions(+), 42 deletions(-)

I have go through microblaze changes in this series and all are fine.

For Microblaze changes. I expect you have already compiled that
without any warning.

Acked-by: Michal Simek <[email protected]>

Thanks,
Michal

--
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: http://www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform



Attachments:
signature.asc (263.00 B)
OpenPGP digital signature

2013-10-17 17:30:41

by Tony Lindgren

[permalink] [raw]
Subject: Re: [RFC 0/9] of: refactor IRQ parsing and add interrupts-extended implementation

* Grant Likely <[email protected]> [131015 13:43]:
> Hi everyone.
>
> This series is mostly a set of cleanup to the interrupt parsing code.
> Some of it merely clarification, like the renames of of_irq_map_*, some
> to tighten up the API by using of_phandle_args, and some to prepare for
> the last patch in the series.
>
> Of all these patches, the last one is probably the only one likely to be
> controversial. It adds a new way of specifying interrupts. If a device
> gets wired up to multiple interrupt controllers, the interrupts-extended
> property allows the device to specify multiple connections without
> redirecting through an interrupt-map node which can be rather difficult
> to understand. In a lot of cases, an interrupts-extended property is a
> whole lot easier to use.

Oh that's too diplomatic :) How about something like this instead:

"Device tree is currently badly broken where in order to support
interrupts from multiple interrupt controllers the device needs
to do the opposite of describing hardware, and lie about itself
being an interrupt controller to use the interrupt-map property."

Anyways, gave this series a try, and the interrupts-extended binding
works for me for the multiple interrupt controllers issue :)

Tony

2013-10-17 17:33:14

by Tony Lindgren

[permalink] [raw]
Subject: Re: [RFC 9/9] of/irq: create interrupts-extended property

* Grant Likely <[email protected]> [131015 13:43]:
> The standard interrupts property in device tree can only handle
> interrupts coming from a single interrupt parent. If a device is wired
> to multiple interrupt controllers, then it needs to be attached to a
> node with an interrupt-map property to demux the interrupt specifiers
> which is confusing. It would be a lot easier if there was a form of the
> interrupts property that allows for a separate interrupt phandle for
> each interrupt specifier.
>
> This patch does exactly that by creating a new interrupts-extended
> property which reuses the phandle+arguments pattern used by GPIOs and
> other core bindings.
>
> Signed-off-by: Grant Likely <[email protected]>
> Cc: Rob Herring <[email protected]>

Works for me and solves the issue for devices with interrupts
from multiple interrupt controllers:

Acked-by: Tony Lindgren <[email protected]>

2013-10-27 13:46:13

by Grant Likely

[permalink] [raw]
Subject: Re: [RFC 9/9] of/irq: create interrupts-extended property

On Tue, 15 Oct 2013 21:39:23 +0100, Grant Likely <[email protected]> wrote:
> The standard interrupts property in device tree can only handle
> interrupts coming from a single interrupt parent. If a device is wired
> to multiple interrupt controllers, then it needs to be attached to a
> node with an interrupt-map property to demux the interrupt specifiers
> which is confusing. It would be a lot easier if there was a form of the
> interrupts property that allows for a separate interrupt phandle for
> each interrupt specifier.
>
> This patch does exactly that by creating a new interrupts-extended
> property which reuses the phandle+arguments pattern used by GPIOs and
> other core bindings.
>
> Signed-off-by: Grant Likely <[email protected]>
> Cc: Rob Herring <[email protected]>

Alright, I want to merge this one. I've got an Ack from Tony, general
agreement from an in person converstaion from Ben (aside from wishing he
could think of a better property name), and various rumblings of
approval from anyone I talked to about it at ksummit. I'd like to have
something more that that to put into the commit text. Please take a look
and let me know if you agree/disagree with this binding.

g.

> ---
> .../bindings/interrupt-controller/interrupts.txt | 29 +++++++--
> arch/arm/boot/dts/testcases/tests-interrupts.dtsi | 16 +++++
> arch/arm/boot/dts/versatile-ab.dts | 2 +-
> arch/arm/boot/dts/versatile-pb.dts | 2 +-
> drivers/of/irq.c | 16 +++--
> drivers/of/selftest.c | 70 ++++++++++++++++++++++
> 6 files changed, 122 insertions(+), 13 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
> index 72a06c0..1486497 100644
> --- a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
> +++ b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
> @@ -4,16 +4,33 @@ Specifying interrupt information for devices
> 1) Interrupt client nodes
> -------------------------
>
> -Nodes that describe devices which generate interrupts must contain an
> -"interrupts" property. This property must contain a list of interrupt
> -specifiers, one per output interrupt. The format of the interrupt specifier is
> -determined by the interrupt controller to which the interrupts are routed; see
> -section 2 below for details.
> +Nodes that describe devices which generate interrupts must contain an either an
> +"interrupts" property or an "interrupts-extended" property. These properties
> +contain a list of interrupt specifiers, one per output interrupt. The format of
> +the interrupt specifier is determined by the interrupt controller to which the
> +interrupts are routed; see section 2 below for details.
> +
> + Example:
> + interrupt-parent = <&intc1>;
> + interrupts = <5 0>, <6 0>;
>
> The "interrupt-parent" property is used to specify the controller to which
> interrupts are routed and contains a single phandle referring to the interrupt
> controller node. This property is inherited, so it may be specified in an
> -interrupt client node or in any of its parent nodes.
> +interrupt client node or in any of its parent nodes. Interrupts listed in the
> +"interrupts" property are always in reference to the node's interrupt parent.
> +
> +The "interrupts-extended" property is a special form for use when a node needs
> +to reference multiple interrupt parents. Each entry in this property contains
> +both the parent phandle and the interrupt specifier. "interrupts-extended"
> +should only be used when a device has multiple interrupt parents.
> +
> + Example:
> + interrupts-extended = <&intc1 5 1>, <&intc2 1 0>;
> +
> +A device node may contain either "interrupts" or "interrupts-extended", but not
> +both. If both properties are present, then the operating system should log an
> +error and use only the data in "interrupts".
>
> 2) Interrupt controller nodes
> -----------------------------
> diff --git a/arch/arm/boot/dts/testcases/tests-interrupts.dtsi b/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
> index 6ecda71..560d6bf 100644
> --- a/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
> +++ b/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
> @@ -27,6 +27,12 @@
> <4 &test_intc2 15 16>;
> };
>
> + test_intmap1: intmap1 {
> + #interrupt-cells = <2>;
> + #address-cells = <0>;
> + interrupt-map = <1 2 &test_intc0 15>;
> + };
> +
> interrupts0 {
> interrupt-parent = <&test_intc0>;
> interrupts = <1>, <2>, <3>, <4>;
> @@ -36,6 +42,16 @@
> interrupt-parent = <&test_intmap0>;
> interrupts = <1>, <2>, <3>, <4>;
> };
> +
> + interrupts-extended0 {
> + interrupts-extended = <&test_intc0 1>,
> + <&test_intc1 2 3 4>,
> + <&test_intc2 5 6>,
> + <&test_intmap0 1>,
> + <&test_intmap0 2>,
> + <&test_intmap0 3>,
> + <&test_intmap1 1 2>;
> + };
> };
> };
> };
> diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts
> index dde75ae..e01e5a0 100644
> --- a/arch/arm/boot/dts/versatile-ab.dts
> +++ b/arch/arm/boot/dts/versatile-ab.dts
> @@ -185,7 +185,7 @@
> mmc@5000 {
> compatible = "arm,primecell";
> reg = < 0x5000 0x1000>;
> - interrupts = <22 34>;
> + interrupts-extended = <&vic 22 &sic 2>;
> };
> kmi@6000 {
> compatible = "arm,pl050", "arm,primecell";
> diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts
> index 7e81752..f43907c 100644
> --- a/arch/arm/boot/dts/versatile-pb.dts
> +++ b/arch/arm/boot/dts/versatile-pb.dts
> @@ -41,7 +41,7 @@
> mmc@b000 {
> compatible = "arm,primecell";
> reg = <0xb000 0x1000>;
> - interrupts = <23 34>;
> + interrupts-extended = <&vic 23 &sic 2>;
> };
> };
> };
> diff --git a/drivers/of/irq.c b/drivers/of/irq.c
> index ddea945..c01f60e 100644
> --- a/drivers/of/irq.c
> +++ b/drivers/of/irq.c
> @@ -292,17 +292,23 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar
> if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
> return of_irq_parse_oldworld(device, index, out_irq);
>
> + /* Get the reg property (if any) */
> + addr = of_get_property(device, "reg", NULL);
> +
> /* Get the interrupts property */
> intspec = of_get_property(device, "interrupts", &intlen);
> - if (intspec == NULL)
> - return -EINVAL;
> + if (intspec == NULL) {
> + /* Try the new-style interrupts-extended */
> + res = of_parse_phandle_with_args(device, "interrupts-extended",
> + "#interrupt-cells", index, out_irq);
> + if (res)
> + return -EINVAL;
> + return of_irq_parse_raw(addr, out_irq);
> + }
> intlen /= sizeof(*intspec);
>
> pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen);
>
> - /* Get the reg property (if any) */
> - addr = of_get_property(device, "reg", NULL);
> -
> /* Look for the interrupt parent. */
> p = of_irq_find_parent(device);
> if (p == NULL)
> diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c
> index 9c80f0b..e21012b 100644
> --- a/drivers/of/selftest.c
> +++ b/drivers/of/selftest.c
> @@ -231,6 +231,75 @@ static void __init of_selftest_parse_interrupts(void)
> of_node_put(np);
> }
>
> +static void __init of_selftest_parse_interrupts_extended(void)
> +{
> + struct device_node *np;
> + struct of_phandle_args args;
> + int i, rc;
> +
> + np = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0");
> + if (!np) {
> + pr_err("missing testcase data\n");
> + return;
> + }
> +
> + for (i = 0; i < 7; i++) {
> + bool passed = true;
> + rc = of_irq_parse_one(np, i, &args);
> +
> + /* Test the values from tests-phandle.dtsi */
> + switch (i) {
> + case 0:
> + passed &= !rc;
> + passed &= (args.args_count == 1);
> + passed &= (args.args[0] == 1);
> + break;
> + case 1:
> + passed &= !rc;
> + passed &= (args.args_count == 3);
> + passed &= (args.args[0] == 2);
> + passed &= (args.args[1] == 3);
> + passed &= (args.args[2] == 4);
> + break;
> + case 2:
> + passed &= !rc;
> + passed &= (args.args_count == 2);
> + passed &= (args.args[0] == 5);
> + passed &= (args.args[1] == 6);
> + break;
> + case 3:
> + passed &= !rc;
> + passed &= (args.args_count == 1);
> + passed &= (args.args[0] == 9);
> + break;
> + case 4:
> + passed &= !rc;
> + passed &= (args.args_count == 3);
> + passed &= (args.args[0] == 10);
> + passed &= (args.args[1] == 11);
> + passed &= (args.args[2] == 12);
> + break;
> + case 5:
> + passed &= !rc;
> + passed &= (args.args_count == 2);
> + passed &= (args.args[0] == 13);
> + passed &= (args.args[1] == 14);
> + break;
> + case 6:
> + passed &= !rc;
> + passed &= (args.args_count == 1);
> + passed &= (args.args[0] == 15);
> + break;
> + default:
> + passed = false;
> + }
> +
> + selftest(passed, "index %i - data error on node %s rc=%i\n",
> + i, args.np->full_name, rc);
> + }
> + of_node_put(np);
> +}
> +
> static int __init of_selftest(void)
> {
> struct device_node *np;
> @@ -246,6 +315,7 @@ static int __init of_selftest(void)
> of_selftest_parse_phandle_with_args();
> of_selftest_property_match_string();
> of_selftest_parse_interrupts();
> + of_selftest_parse_interrupts_extended();
> pr_info("end of selftest - %i passed, %i failed\n",
> selftest_results.passed, selftest_results.failed);
> return 0;
> --
> 1.8.1.2
>

2013-10-27 20:24:11

by Rob Herring

[permalink] [raw]
Subject: Re: [RFC 9/9] of/irq: create interrupts-extended property

On Sun, Oct 27, 2013 at 8:46 AM, Grant Likely <[email protected]> wrote:
> On Tue, 15 Oct 2013 21:39:23 +0100, Grant Likely <[email protected]> wrote:
>> The standard interrupts property in device tree can only handle
>> interrupts coming from a single interrupt parent. If a device is wired
>> to multiple interrupt controllers, then it needs to be attached to a
>> node with an interrupt-map property to demux the interrupt specifiers
>> which is confusing. It would be a lot easier if there was a form of the
>> interrupts property that allows for a separate interrupt phandle for
>> each interrupt specifier.
>>
>> This patch does exactly that by creating a new interrupts-extended
>> property which reuses the phandle+arguments pattern used by GPIOs and
>> other core bindings.
>>
>> Signed-off-by: Grant Likely <[email protected]>
>> Cc: Rob Herring <[email protected]>
>
> Alright, I want to merge this one. I've got an Ack from Tony, general
> agreement from an in person converstaion from Ben (aside from wishing he
> could think of a better property name), and various rumblings of
> approval from anyone I talked to about it at ksummit. I'd like to have
> something more that that to put into the commit text. Please take a look
> and let me know if you agree/disagree with this binding.

I think it looks fine, but I'll throw out an alternative proposal.
Simply allow for interrupt-parent to be an array in equal size to
interrupts property. Then it is a minimal change to the existing
binding:

interrupt-parent = <&intc1>, <&intc2>;
interrupts = <5 0>, <6 0>;

Of course interrupts-extended is more inline with standard patterns
for bindings.

Rob

2013-10-28 03:17:05

by Mark Rutland

[permalink] [raw]
Subject: Re: [RFC 9/9] of/irq: create interrupts-extended property

On Sun, Oct 27, 2013 at 08:24:08PM +0000, Rob Herring wrote:
> On Sun, Oct 27, 2013 at 8:46 AM, Grant Likely <[email protected]> wrote:
> > On Tue, 15 Oct 2013 21:39:23 +0100, Grant Likely <[email protected]> wrote:
> >> The standard interrupts property in device tree can only handle
> >> interrupts coming from a single interrupt parent. If a device is wired
> >> to multiple interrupt controllers, then it needs to be attached to a
> >> node with an interrupt-map property to demux the interrupt specifiers
> >> which is confusing. It would be a lot easier if there was a form of the
> >> interrupts property that allows for a separate interrupt phandle for
> >> each interrupt specifier.
> >>
> >> This patch does exactly that by creating a new interrupts-extended
> >> property which reuses the phandle+arguments pattern used by GPIOs and
> >> other core bindings.
> >>
> >> Signed-off-by: Grant Likely <[email protected]>
> >> Cc: Rob Herring <[email protected]>
> >
> > Alright, I want to merge this one. I've got an Ack from Tony, general
> > agreement from an in person converstaion from Ben (aside from wishing he
> > could think of a better property name), and various rumblings of
> > approval from anyone I talked to about it at ksummit. I'd like to have
> > something more that that to put into the commit text. Please take a look
> > and let me know if you agree/disagree with this binding.

The only comment I have is that I'm not keen on the name (it's a bit generic
and we might want to extend the interrupts binding in future), but I'm happy to
leave that as a matter of personal taste.

The best alternative I could come up with was parented-interrupts, but that
could be misinterpreted as describing the relationship backwards (i.e. this
device is the parent for those interrupts).

>
> I think it looks fine, but I'll throw out an alternative proposal.
> Simply allow for interrupt-parent to be an array in equal size to
> interrupts property. Then it is a minimal change to the existing
> binding:
>
> interrupt-parent = <&intc1>, <&intc2>;
> interrupts = <5 0>, <6 0>;

I'd prefer the interrupts-extended approach.

This might not matter, but if you have an existing driver with two interrupts,
and you attempt to describe the situation this way, e.g.

intc1: interrupt_controller1 {
compatible = "vendor,interrupt-controller";
#interrupt-cells = <1>;
};

intc2: interrupt_controller2 {
compatible = "vendor,another-interrupt-controller";
#interrupt-cells = <2>;
};

dev {
compatible = "vendor,some-device";
interrupt-parent = <&intc1>, <&intc2>;
interrupts = <5>, <65 73>;
};

The existing driver may read interrupts as two interrupts for intc1, and
believe it's been successful when it has not, and one of those interrupts might
never fire. That would be very bad for a timer for example.

Additionally it makes the interrupts list difficult for a human to read, as you
need to match it with an entry in another list (this problem exists with other
parallel properties like interrupt-names too, but we can't do much better
there).

It's also easy to make a typo (e.g. an extra cell in an interrupt) that will
parse as valid when you don't expect it to. At least with the phandle in the
list it's less likely to happen.

>
> Of course interrupts-extended is more inline with standard patterns
> for bindings.

I think for this reason alone it should be preferable. Unless I'm mistaken it
would be identical to the clock bindings pattern with a uniformly named
phandle+args property and a parallel -names property. I don't think the gpio
style ${NAME}-interrupts would easily fit here.

Thanks,
Mark.

2013-10-28 06:54:51

by Kumar Gala

[permalink] [raw]
Subject: Re: [RFC 9/9] of/irq: create interrupts-extended property


On Oct 15, 2013, at 3:39 PM, Grant Likely wrote:

> The standard interrupts property in device tree can only handle
> interrupts coming from a single interrupt parent. If a device is wired
> to multiple interrupt controllers, then it needs to be attached to a
> node with an interrupt-map property to demux the interrupt specifiers
> which is confusing. It would be a lot easier if there was a form of the
> interrupts property that allows for a separate interrupt phandle for
> each interrupt specifier.
>
> This patch does exactly that by creating a new interrupts-extended
> property which reuses the phandle+arguments pattern used by GPIOs and
> other core bindings.
>
> Signed-off-by: Grant Likely <[email protected]>
> Cc: Rob Herring <[email protected]>
> ---
> .../bindings/interrupt-controller/interrupts.txt | 29 +++++++--
> arch/arm/boot/dts/testcases/tests-interrupts.dtsi | 16 +++++
> arch/arm/boot/dts/versatile-ab.dts | 2 +-
> arch/arm/boot/dts/versatile-pb.dts | 2 +-
> drivers/of/irq.c | 16 +++--
> drivers/of/selftest.c | 70 ++++++++++++++++++++++
> 6 files changed, 122 insertions(+), 13 deletions(-)

Acked-by: Kumar Gala <[email protected]>

[ I think the patch should be split up so we aren't touching versatile dts as part of it ]

- k

--
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

2013-10-28 06:55:25

by Kumar Gala

[permalink] [raw]
Subject: Re: [RFC 9/9] of/irq: create interrupts-extended property


On Oct 27, 2013, at 10:16 PM, Mark Rutland wrote:

> On Sun, Oct 27, 2013 at 08:24:08PM +0000, Rob Herring wrote:
>> On Sun, Oct 27, 2013 at 8:46 AM, Grant Likely <[email protected]> wrote:
>>> On Tue, 15 Oct 2013 21:39:23 +0100, Grant Likely <[email protected]> wrote:
>>>> The standard interrupts property in device tree can only handle
>>>> interrupts coming from a single interrupt parent. If a device is wired
>>>> to multiple interrupt controllers, then it needs to be attached to a
>>>> node with an interrupt-map property to demux the interrupt specifiers
>>>> which is confusing. It would be a lot easier if there was a form of the
>>>> interrupts property that allows for a separate interrupt phandle for
>>>> each interrupt specifier.
>>>>
>>>> This patch does exactly that by creating a new interrupts-extended
>>>> property which reuses the phandle+arguments pattern used by GPIOs and
>>>> other core bindings.
>>>>
>>>> Signed-off-by: Grant Likely <[email protected]>
>>>> Cc: Rob Herring <[email protected]>
>>>
>>> Alright, I want to merge this one. I've got an Ack from Tony, general
>>> agreement from an in person converstaion from Ben (aside from wishing he
>>> could think of a better property name), and various rumblings of
>>> approval from anyone I talked to about it at ksummit. I'd like to have
>>> something more that that to put into the commit text. Please take a look
>>> and let me know if you agree/disagree with this binding.
>
> The only comment I have is that I'm not keen on the name (it's a bit generic
> and we might want to extend the interrupts binding in future), but I'm happy to
> leave that as a matter of personal taste.
>
> The best alternative I could come up with was parented-interrupts, but that
> could be misinterpreted as describing the relationship backwards (i.e. this
> device is the parent for those interrupts).

I think we seem to all agree the name sucks, but can't come up with anything better.

>> I think it looks fine, but I'll throw out an alternative proposal.
>> Simply allow for interrupt-parent to be an array in equal size to
>> interrupts property. Then it is a minimal change to the existing
>> binding:
>>
>> interrupt-parent = <&intc1>, <&intc2>;
>> interrupts = <5 0>, <6 0>;
>
> I'd prefer the interrupts-extended approach.
>
> This might not matter, but if you have an existing driver with two interrupts,
> and you attempt to describe the situation this way, e.g.
>
> intc1: interrupt_controller1 {
> compatible = "vendor,interrupt-controller";
> #interrupt-cells = <1>;
> };
>
> intc2: interrupt_controller2 {
> compatible = "vendor,another-interrupt-controller";
> #interrupt-cells = <2>;
> };
>
> dev {
> compatible = "vendor,some-device";
> interrupt-parent = <&intc1>, <&intc2>;
> interrupts = <5>, <65 73>;
> };
>
> The existing driver may read interrupts as two interrupts for intc1, and
> believe it's been successful when it has not, and one of those interrupts might
> never fire. That would be very bad for a timer for example.
>
> Additionally it makes the interrupts list difficult for a human to read, as you
> need to match it with an entry in another list (this problem exists with other
> parallel properties like interrupt-names too, but we can't do much better
> there).
>
> It's also easy to make a typo (e.g. an extra cell in an interrupt) that will
> parse as valid when you don't expect it to. At least with the phandle in the
> list it's less likely to happen.

I agreed, I'd assume that in Rob's suggestion the length of interrupt-parent & interrupts would have to match so you'd have:

dev {
compatible = "vendor,some-device";
interrupt-parent = <&intc1>, <&intc2>, <&intc2>;
interrupts = <5>, <65 73>;
};

>
>>
>> Of course interrupts-extended is more inline with standard patterns
>> for bindings.
>
> I think for this reason alone it should be preferable. Unless I'm mistaken it
> would be identical to the clock bindings pattern with a uniformly named
> phandle+args property and a parallel -names property. I don't think the gpio
> style ${NAME}-interrupts would easily fit here.
>
> Thanks,
> Mark.

- k

2013-10-28 21:55:17

by Stephen Warren

[permalink] [raw]
Subject: Re: [RFC 9/9] of/irq: create interrupts-extended property

On 10/27/2013 07:46 AM, Grant Likely wrote:
> On Tue, 15 Oct 2013 21:39:23 +0100, Grant Likely <[email protected]> wrote:
>> The standard interrupts property in device tree can only handle
>> interrupts coming from a single interrupt parent. If a device is wired
>> to multiple interrupt controllers, then it needs to be attached to a
>> node with an interrupt-map property to demux the interrupt specifiers
>> which is confusing. It would be a lot easier if there was a form of the
>> interrupts property that allows for a separate interrupt phandle for
>> each interrupt specifier.
>>
>> This patch does exactly that by creating a new interrupts-extended
>> property which reuses the phandle+arguments pattern used by GPIOs and
>> other core bindings.
>>
>> Signed-off-by: Grant Likely <[email protected]>
>> Cc: Rob Herring <[email protected]>
>
> Alright, I want to merge this one. I've got an Ack from Tony, general
> agreement from an in person converstaion from Ben (aside from wishing he
> could think of a better property name), and various rumblings of
> approval from anyone I talked to about it at ksummit. I'd like to have
> something more that that to put into the commit text. Please take a look
> and let me know if you agree/disagree with this binding.

The new binding makes sense to me. So, the binding,
Acked-by: Stephen Warren <[email protected]>

A couple of minor perhaps bikesheddy comments below.

>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt

>> +Nodes that describe devices which generate interrupts must contain an either an
>> +"interrupts" property or an "interrupts-extended" property. These properties

"interrupts-ex" would be shorter, although I guess slightly harder to
guess its purpose, unless you're familiar with "ex" in symbol names.

...
>> +A device node may contain either "interrupts" or "interrupts-extended", but not
>> +both. If both properties are present, then the operating system should log an
>> +error

That sounds rather like prescribing SW behaviour, which I thought DT
bindings shouldn't do?

>> and use only the data in "interrupts".

... so perhaps that's better phrased as:

A device node may contain either "interrupts" or "interrupts-extended",
but not both. If both properties are present, the data in "interrupts"
takes precedence.

2013-10-28 22:49:26

by Mark Rutland

[permalink] [raw]
Subject: Re: [RFC 9/9] of/irq: create interrupts-extended property

On Mon, Oct 28, 2013 at 09:47:44PM +0000, Stephen Warren wrote:
> On 10/27/2013 07:46 AM, Grant Likely wrote:
> > On Tue, 15 Oct 2013 21:39:23 +0100, Grant Likely <[email protected]> wrote:
> >> The standard interrupts property in device tree can only handle
> >> interrupts coming from a single interrupt parent. If a device is wired
> >> to multiple interrupt controllers, then it needs to be attached to a
> >> node with an interrupt-map property to demux the interrupt specifiers
> >> which is confusing. It would be a lot easier if there was a form of the
> >> interrupts property that allows for a separate interrupt phandle for
> >> each interrupt specifier.
> >>
> >> This patch does exactly that by creating a new interrupts-extended
> >> property which reuses the phandle+arguments pattern used by GPIOs and
> >> other core bindings.
> >>
> >> Signed-off-by: Grant Likely <[email protected]>
> >> Cc: Rob Herring <[email protected]>
> >
> > Alright, I want to merge this one. I've got an Ack from Tony, general
> > agreement from an in person converstaion from Ben (aside from wishing he
> > could think of a better property name), and various rumblings of
> > approval from anyone I talked to about it at ksummit. I'd like to have
> > something more that that to put into the commit text. Please take a look
> > and let me know if you agree/disagree with this binding.
>
> The new binding makes sense to me. So, the binding,
> Acked-by: Stephen Warren <[email protected]>
>
> A couple of minor perhaps bikesheddy comments below.
>
> >> diff --git a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
>
> >> +Nodes that describe devices which generate interrupts must contain an either an
> >> +"interrupts" property or an "interrupts-extended" property. These properties
>
> "interrupts-ex" would be shorter, although I guess slightly harder to
> guess its purpose, unless you're familiar with "ex" in symbol names.

I'd prefer a more precise name. IMO "-extended" is preferable to "-ex".

>
> ...
> >> +A device node may contain either "interrupts" or "interrupts-extended", but not
> >> +both. If both properties are present, then the operating system should log an
> >> +error
>
> That sounds rather like prescribing SW behaviour, which I thought DT
> bindings shouldn't do?

I think recommending a behaviour relating to parsing is valid. Parsing notes in
bindings make it very easy to write an extensible binding. I think if we'd just
stated that having both properties was invalid you would not have a problem?

>
> >> and use only the data in "interrupts".
>
> ... so perhaps that's better phrased as:
>
> A device node may contain either "interrupts" or "interrupts-extended",
> but not both. If both properties are present, the data in "interrupts"
> takes precedence.
>

This sounds reasonable to me, but I'd definitely want the kernel to scream
(though I appreciate that's separate from the binding details).

Thanks,
Mark.

2013-10-28 23:17:06

by Benjamin Herrenschmidt

[permalink] [raw]
Subject: Re: [RFC 9/9] of/irq: create interrupts-extended property

On Mon, 2013-10-28 at 15:47 -0600, Stephen Warren wrote:

> "interrupts-ex" would be shorter, although I guess slightly harder to
> guess its purpose, unless you're familiar with "ex" in symbol names.
>
> ...
> >> +A device node may contain either "interrupts" or "interrupts-extended", but not
> >> +both. If both properties are present, then the operating system should log an
> >> +error
>
> That sounds rather like prescribing SW behaviour, which I thought DT
> bindings shouldn't do?
>
> >> and use only the data in "interrupts".
>
> ... so perhaps that's better phrased as:
>
> A device node may contain either "interrupts" or "interrupts-extended",
> but not both. If both properties are present, the data in "interrupts"
> takes precedence.

So let's add a coat of paint to this shed :-)

Either it's an error, or we have a precedence rule. If it's an error
then there is no point having a precedence rule, the DT is broken and
might be in all sort of other ways, the precedence is pointless, there's
no telling what property is correct.

However, if we have a precedence rule, then it should be the other way
around, interrupts-extended takes precedence.

A concrete example:

A device has two interrupts "INT0" and "INT1". One goes to PICA, the
other one to PICB,
the first one is necessary for basic use, the second one is only
necessary for some advanced/new functionality.

It makes sense in this case to have the device-tree do:

interrupts = < INT0 >;
interrupt-parent = <&PICA>;
interrupts-extended = <&PICA, INT0, &PICB, INT1>;

Because that way:

- An old kernel which doesn't understand interrupts-extended but *also*
only uses the first interrupt (doesn't exploit the advanced/new
functionalities) will work by picking up interrupts+interrupt-parent,

- A newer kernel which does understand interrupts-extended can then
make use of it to support the advanced/new functionalities.

Cheers,
Ben.

2013-10-29 00:09:36

by Grant Likely

[permalink] [raw]
Subject: Re: [RFC 9/9] of/irq: create interrupts-extended property

On Mon, 28 Oct 2013 01:54:38 -0500, Kumar Gala <[email protected]> wrote:
>
> On Oct 15, 2013, at 3:39 PM, Grant Likely wrote:
>
> > The standard interrupts property in device tree can only handle
> > interrupts coming from a single interrupt parent. If a device is wired
> > to multiple interrupt controllers, then it needs to be attached to a
> > node with an interrupt-map property to demux the interrupt specifiers
> > which is confusing. It would be a lot easier if there was a form of the
> > interrupts property that allows for a separate interrupt phandle for
> > each interrupt specifier.
> >
> > This patch does exactly that by creating a new interrupts-extended
> > property which reuses the phandle+arguments pattern used by GPIOs and
> > other core bindings.
> >
> > Signed-off-by: Grant Likely <[email protected]>
> > Cc: Rob Herring <[email protected]>
> > ---
> > .../bindings/interrupt-controller/interrupts.txt | 29 +++++++--
> > arch/arm/boot/dts/testcases/tests-interrupts.dtsi | 16 +++++
> > arch/arm/boot/dts/versatile-ab.dts | 2 +-
> > arch/arm/boot/dts/versatile-pb.dts | 2 +-
> > drivers/of/irq.c | 16 +++--
> > drivers/of/selftest.c | 70 ++++++++++++++++++++++
> > 6 files changed, 122 insertions(+), 13 deletions(-)
>
> Acked-by: Kumar Gala <[email protected]>
>
> [ I think the patch should be split up so we aren't touching versatile dts as part of it ]

No problem, I'll do that.

g.

2013-10-29 16:23:34

by Olof Johansson

[permalink] [raw]
Subject: Re: [RFC 4/9] of/irq: Refactor interrupt-map parsing

Hi,

On Tue, Oct 15, 2013 at 1:39 PM, Grant Likely <[email protected]> wrote:
> 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 <[email protected]>
> Cc: Benjamin Herrenschmidt <[email protected]>

This patch stopped exynos/arndale from booting when it hit next (i.e.
last night). I bisected down to this commit.

It seems that the platform is getting stuck calibrating delay loop,
i.e. it is not getting interrupts. Let me know if you want me to
collect more data of some sort.


-Olof

2013-10-31 01:19:58

by Ming Lei

[permalink] [raw]
Subject: Re: [RFC 4/9] of/irq: Refactor interrupt-map parsing

On Wed, Oct 30, 2013 at 12:23 AM, Olof Johansson <[email protected]> wrote:
> Hi,
>
> On Tue, Oct 15, 2013 at 1:39 PM, Grant Likely <[email protected]> wrote:
>> 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 <[email protected]>
>> Cc: Benjamin Herrenschmidt <[email protected]>
>
> This patch stopped exynos/arndale from booting when it hit next (i.e.
> last night). I bisected down to this commit.

+1, :-)

>
> It seems that the platform is getting stuck calibrating delay loop,
> i.e. it is not getting interrupts. Let me know if you want me to
> collect more data of some sort.



Thanks,
--
Ming Lei

2013-10-31 18:57:36

by Olof Johansson

[permalink] [raw]
Subject: Re: [RFC 4/9] of/irq: Refactor interrupt-map parsing

On Wed, Oct 30, 2013 at 02:25:21PM -0700, Grant Likely wrote:
> (Sorry for HTML mail)
>
> Can you put #define DEBUG at the top of drivers/of/irq.c and send me the
> log output from before and after the commit?

Here you go, quite verbose log below.

Looks like we're tripping the "no reg passed in" checks, not sure if related.



After:

[arndale 01:05] [ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
[arndale 01:05] [ 0.000000] Preemptible hierarchical RCU implementation.
[arndale 01:05] [ 0.000000] NR_IRQS:16 nr_irqs:16 16
[arndale 01:05] [ 0.000000] of_irq_init: init arm,cortex-a9-gic @ c1569754, parent (null)
[arndale 01:05] [ 0.000000] of_irq_init: init samsung,exynos4210-combiner @ c1569608, parent c1569754
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=0
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000000...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=1
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000001...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=2
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000002...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=3
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000003...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=4
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000004...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=5
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000005...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=6
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000006...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=7
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000007...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=8
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000008...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=9
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000009...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=10
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000000a...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=11
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000000b...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=12
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000000c...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=13
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000000d...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=14
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000000e...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=15
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000000f...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=16
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000010...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=17
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000011...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=18
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000012...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=19
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000013...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=20
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000014...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=21
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000015...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=22
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000016...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=23
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000017...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=24
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000018...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=25
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000019...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=26
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000001a...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=27
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000001b...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=28
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000001c...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=29
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000001d...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=30
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000001e...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=31
[arndale 01:05] [ 0.000000] intspec=0 intlen=96
[arndale 01:05] [ 0.000000] intsize=3 intlen=96
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000001f...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] Exynos5250: clock setup completed, armclk=1000000000
[arndale 01:05] [ 0.000000] Exynos: Audss: clock setup completed
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/timer, index=0
[arndale 01:05] [ 0.000000] intspec=1 intlen=12
[arndale 01:05] [ 0.000000] intsize=3 intlen=12
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000001 0x0000000d...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> no reg passed in when needed !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/timer, index=1
[arndale 01:05] [ 0.000000] intspec=1 intlen=12
[arndale 01:05] [ 0.000000] intsize=3 intlen=12
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000001 0x0000000e...],ointsize=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> no reg passed in when needed !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/timer, index=2
[arndale 01:05] [ 0.000000] intspec=1 intlen=12
[arndale 01:05] [ 0.000000] intsize=3 intlen=12
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000001 0x0000000b...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> no reg passed in when needed !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/timer, index=3
[arndale 01:05] [ 0.000000] intspec=1 intlen=12
[arndale 01:05] [ 0.000000] intsize=3 intlen=12
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000001 0x0000000a...],ointsize=3
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 01:05] [ 0.000000] -> addrsize=1
[arndale 01:05] [ 0.000000] -> no reg passed in when needed !
[arndale 01:05] [ 0.000000] arch_timer: No interrupt available, giving up
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=0
[arndale 01:05] [ 0.000000] intspec=0 intlen=12
[arndale 01:05] [ 0.000000] intsize=2 intlen=12
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000000 0x00000000...],ointsize=2
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 01:05] [ 0.000000] -> addrsize=0
[arndale 01:05] [ 0.000000] -> match=1 (imaplen=30)
[arndale 01:05] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 01:05] [ 0.000000] -> imaplen=27
[arndale 01:05] [ 0.000000] -> new parent: /interrupt-controller@10440000
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=0
[arndale 01:05] [ 0.000000] intspec=0 intlen=12
[arndale 01:05] [ 0.000000] intsize=2 intlen=12
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000000 0x00000000...],ointsize=2
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 01:05] [ 0.000000] -> addrsize=0
[arndale 01:05] [ 0.000000] -> match=1 (imaplen=30)
[arndale 01:05] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 01:05] [ 0.000000] -> imaplen=27
[arndale 01:05] [ 0.000000] -> new parent: /interrupt-controller@10440000
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=1
[arndale 01:05] [ 0.000000] intspec=0 intlen=12
[arndale 01:05] [ 0.000000] intsize=2 intlen=12
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000001 0x00000000...],ointsize=2
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 01:05] [ 0.000000] -> addrsize=0
[arndale 01:05] [ 0.000000] -> match=1 (imaplen=30)
[arndale 01:05] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 01:05] [ 0.000000] -> imaplen=27
[arndale 01:05] [ 0.000000] -> new parent: /interrupt-controller@10440000
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=2
[arndale 01:05] [ 0.000000] intspec=0 intlen=12
[arndale 01:05] [ 0.000000] intsize=2 intlen=12
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000002 0x00000000...],ointsize=2
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 01:05] [ 0.000000] -> addrsize=0
[arndale 01:05] [ 0.000000] -> match=1 (imaplen=30)
[arndale 01:05] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 01:05] [ 0.000000] -> imaplen=27
[arndale 01:05] [ 0.000000] -> new parent: /interrupt-controller@10440000
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=3
[arndale 01:05] [ 0.000000] intspec=0 intlen=12
[arndale 01:05] [ 0.000000] intsize=2 intlen=12
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000003 0x00000000...],ointsize=2
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 01:05] [ 0.000000] -> addrsize=0
[arndale 01:05] [ 0.000000] -> match=1 (imaplen=30)
[arndale 01:05] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 01:05] [ 0.000000] -> imaplen=27
[arndale 01:05] [ 0.000000] -> new parent: /interrupt-controller@10440000
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=4
[arndale 01:05] [ 0.000000] intspec=0 intlen=12
[arndale 01:05] [ 0.000000] intsize=2 intlen=12
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000004 0x00000000...],ointsize=2
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 01:05] [ 0.000000] -> addrsize=0
[arndale 01:05] [ 0.000000] -> match=1 (imaplen=30)
[arndale 01:05] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 01:05] [ 0.000000] -> imaplen=27
[arndale 01:05] [ 0.000000] -> new parent: /interrupt-controller@10440000
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=5
[arndale 01:05] [ 0.000000] intspec=0 intlen=12
[arndale 01:05] [ 0.000000] intsize=2 intlen=12
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000005 0x00000000...],ointsize=2
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 01:05] [ 0.000000] -> addrsize=0
[arndale 01:05] [ 0.000000] -> match=1 (imaplen=30)
[arndale 01:05] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 01:05] [ 0.000000] -> imaplen=27
[arndale 01:05] [ 0.000000] -> new parent: /interrupt-controller@10440000
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=6
[arndale 01:05] [ 0.000000] intspec=0 intlen=12
[arndale 01:05] [ 0.000000] intsize=2 intlen=12
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=4
[arndale 01:05] [ 0.000000] intspec=0 intlen=12
[arndale 01:05] [ 0.000000] intsize=2 intlen=12
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000004 0x00000000...],ointsize=2
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 01:05] [ 0.000000] -> addrsize=0
[arndale 01:05] [ 0.000000] -> match=1 (imaplen=30)
[arndale 01:05] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 01:05] [ 0.000000] -> imaplen=27
[arndale 01:05] [ 0.000000] -> new parent: /interrupt-controller@10440000
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=5
[arndale 01:05] [ 0.000000] intspec=0 intlen=12
[arndale 01:05] [ 0.000000] intsize=2 intlen=12
[arndale 01:05] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000005 0x00000000...],ointsize=2
[arndale 01:05] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 01:05] [ 0.000000] -> addrsize=0
[arndale 01:05] [ 0.000000] -> match=1 (imaplen=30)
[arndale 01:05] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 01:05] [ 0.000000] -> imaplen=27
[arndale 01:05] [ 0.000000] -> new parent: /interrupt-controller@10440000
[arndale 01:05] [ 0.000000] -> got it !
[arndale 01:05] [ 0.000000] genirq: Flags mismatch irq 347. 00015200 (mct_comp_irq) vs. 00014a00 (mct_tick0)
[arndale 01:05] [ 0.000000] sched_clock: 32 bits at 200 Hz, resolution 5000000ns, wraps every 4294967291ms
[arndale 01:05] [ 0.000000] Console: colour dummy device 80x30
[arndale 01:05] [ 0.000000] Calibrating delay loop...
[arndale 01:05] got exception: timeout



Before:


Huh, before this change we end up using pre-calculated elay loop:


[arndale 00:58] [ 0.000000] Preemptible hierarchical RCU implementation.
[arndale 00:58] [ 0.000000] NR_IRQS:16 nr_irqs:16 16
[arndale 00:58] [ 0.000000] of_irq_init: init arm,cortex-a9-gic @ c1569754, parent (null)
[arndale 00:58] [ 0.000000] of_irq_init: init samsung,exynos4210-combiner @ c1569608, parent c1569754
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=0
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000000...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=1
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000001...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=2
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000002...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=3
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000003...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=4
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000004...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=5
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000005...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=6
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000006...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=7
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000007...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=8
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000008...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=9
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000009...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=10
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000000a...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=11
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000000b...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=12
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000000c...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=13
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000000d...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=14
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000000e...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=15
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000000f...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=16
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000010...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=17
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000011...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=18
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000012...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=19
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000013...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=20
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000014...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=21
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000015...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=22
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000016...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=23
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000017...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=24
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000018...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=25
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x00000019...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=26
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000001a...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=27
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000001b...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=28
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000001c...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=29
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000001d...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=30
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000001e...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/interrupt-controller@10440000, index=31
[arndale 00:58] [ 0.000000] intspec=0 intlen=96
[arndale 00:58] [ 0.000000] intsize=3 intlen=96
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000000 0x0000001f...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] Exynos5250: clock setup completed, armclk=1000000000
[arndale 00:58] [ 0.000000] Exynos: Audss: clock setup completed
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/timer, index=0
[arndale 00:58] [ 0.000000] intspec=1 intlen=12
[arndale 00:58] [ 0.000000] intsize=3 intlen=12
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000001 0x0000000d...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/timer, index=1
[arndale 00:58] [ 0.000000] intspec=1 intlen=12
[arndale 00:58] [ 0.000000] intsize=3 intlen=12
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000001 0x0000000e...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/timer, index=2
[arndale 00:58] [ 0.000000] intspec=1 intlen=12
[arndale 00:58] [ 0.000000] intsize=3 intlen=12
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000001 0x0000000b...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/timer, index=3
[arndale 00:58] [ 0.000000] intspec=1 intlen=12
[arndale 00:58] [ 0.000000] intsize=3 intlen=12
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/interrupt-controller@10481000,intspec=[0x00000001 0x0000000a...],ointsize=3
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/interrupt-controller@10481000, size=3
[arndale 00:58] [ 0.000000] -> addrsize=1
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] Architected cp15 timer(s) running at 24.00MHz (phys).
[arndale 00:58] [ 0.000000] Switching to timer-based delay loop
[arndale 00:58] [ 0.000000] sched_clock: ARM arch timer >56 bits at 24000kHz, resolution 41ns
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=0
[arndale 00:58] [ 0.000000] intspec=0 intlen=12
[arndale 00:58] [ 0.000000] intsize=2 intlen=12
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000000 0x00000000...],ointsize=2
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 00:58] [ 0.000000] -> addrsize=0
[arndale 00:58] [ 0.000000] -> match=1 (imaplen=30)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=27
[arndale 00:58] [ 0.000000] -> new parent: /interrupt-controller@10440000
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=0
[arndale 00:58] [ 0.000000] intspec=0 intlen=12
[arndale 00:58] [ 0.000000] intsize=2 intlen=12
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000000 0x00000000...],ointsize=2
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 00:58] [ 0.000000] -> addrsize=0
[arndale 00:58] [ 0.000000] -> match=1 (imaplen=30)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=27
[arndale 00:58] [ 0.000000] -> new parent: /interrupt-controller@10440000
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=1
[arndale 00:58] [ 0.000000] intspec=0 intlen=12
[arndale 00:58] [ 0.000000] intsize=2 intlen=12
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000001 0x00000000...],ointsize=2
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 00:58] [ 0.000000] -> addrsize=0
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=30)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=27
[arndale 00:58] [ 0.000000] -> match=1 (imaplen=25)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=22
[arndale 00:58] [ 0.000000] -> new parent: /interrupt-controller@10440000
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=2
[arndale 00:58] [ 0.000000] intspec=0 intlen=12
[arndale 00:58] [ 0.000000] intsize=2 intlen=12
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000002 0x00000000...],ointsize=2
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 00:58] [ 0.000000] -> addrsize=0
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=30)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=27
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=25)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=22
[arndale 00:58] [ 0.000000] -> match=1 (imaplen=20)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=17
[arndale 00:58] [ 0.000000] -> new parent: /interrupt-controller@10440000
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=3
[arndale 00:58] [ 0.000000] intspec=0 intlen=12
[arndale 00:58] [ 0.000000] intsize=2 intlen=12
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000003 0x00000000...],ointsize=2
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 00:58] [ 0.000000] -> addrsize=0
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=30)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=27
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=25)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=22
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=20)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=17
[arndale 00:58] [ 0.000000] -> match=1 (imaplen=15)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=12
[arndale 00:58] [ 0.000000] -> new parent: /interrupt-controller@10440000
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=4
[arndale 00:58] [ 0.000000] intspec=0 intlen=12
[arndale 00:58] [ 0.000000] intsize=2 intlen=12
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000004 0x00000000...],ointsize=2
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 00:58] [ 0.000000] -> addrsize=0
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=30)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=27
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=25)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=22
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=20)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=17
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=15)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=12
[arndale 00:58] [ 0.000000] -> match=1 (imaplen=10)
[arndale 00:58] [ 0.000000] -> newintsize=3, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=6
[arndale 00:58] [ 0.000000] -> new parent: /interrupt-controller@10481000
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=5
[arndale 00:58] [ 0.000000] intspec=0 intlen=12
[arndale 00:58] [ 0.000000] intsize=2 intlen=12
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000005 0x00000000...],ointsize=2
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 00:58] [ 0.000000] -> addrsize=0
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=30)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=27
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=25)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=22
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=20)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=17
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=15)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=12
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=10)
[arndale 00:58] [ 0.000000] -> newintsize=3, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=6
[arndale 00:58] [ 0.000000] -> match=1 (imaplen=4)
[arndale 00:58] [ 0.000000] -> newintsize=3, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=0
[arndale 00:58] [ 0.000000] -> new parent: /interrupt-controller@10481000
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=6
[arndale 00:58] [ 0.000000] intspec=0 intlen=12
[arndale 00:58] [ 0.000000] intsize=2 intlen=12
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=4
[arndale 00:58] [ 0.000000] intspec=0 intlen=12
[arndale 00:58] [ 0.000000] intsize=2 intlen=12
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000004 0x00000000...],ointsize=2
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 00:58] [ 0.000000] -> addrsize=0
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=30)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=27
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=25)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=22
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=20)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=17
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=15)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=12
[arndale 00:58] [ 0.000000] -> match=1 (imaplen=10)
[arndale 00:58] [ 0.000000] -> newintsize=3, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=6
[arndale 00:58] [ 0.000000] -> new parent: /interrupt-controller@10481000
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] of_irq_parse_one: dev=/mct@101C0000, index=5
[arndale 00:58] [ 0.000000] intspec=0 intlen=12
[arndale 00:58] [ 0.000000] intsize=2 intlen=12
[arndale 00:58] [ 0.000000] of_irq_parse_raw: par=/mct@101C0000/mct-map,intspec=[0x00000005 0x00000000...],ointsize=2
[arndale 00:58] [ 0.000000] of_irq_parse_raw: ipar=/mct@101C0000/mct-map, size=2
[arndale 00:58] [ 0.000000] -> addrsize=0
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=30)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=27
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=25)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=22
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=20)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=17
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=15)
[arndale 00:58] [ 0.000000] -> newintsize=2, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=12
[arndale 00:58] [ 0.000000] -> match=0 (imaplen=10)
[arndale 00:58] [ 0.000000] -> newintsize=3, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=6
[arndale 00:58] [ 0.000000] -> match=1 (imaplen=4)
[arndale 00:58] [ 0.000000] -> newintsize=3, newaddrsize=0
[arndale 00:58] [ 0.000000] -> imaplen=0
[arndale 00:58] [ 0.000000] -> new parent: /interrupt-controller@10481000
[arndale 00:58] [ 0.000000] -> got it !
[arndale 00:58] [ 0.000000] sched_clock: 32 bits at 200 Hz, resolution 5000000ns, wraps every 4294967291ms
[arndale 00:58] [ 0.000000] Console: colour dummy device 80x30
[arndale 00:58] [ 0.012702] Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=120000)
[arndale 00:58] [ 0.022934] pid_max: default: 32768 minimum: 301

2013-10-31 20:45:16

by Stephen Warren

[permalink] [raw]
Subject: Re: [RFC 4/9] of/irq: Refactor interrupt-map parsing [CPU hotplug clockevents issue]

On 10/15/2013 02:39 PM, Grant Likely wrote:
> 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.

This commit appears to cause kernel error spew while performing CPU
hotplug operations on Tegra114. For example, see the log at the end of
this message.

I guess this boot-time message is the clue:

[ 0.000000] arch_timer: No interrupt available, giving up

which corresponds to this diff in /proc/interrupts:

> - 27: 2929 2216 2027 1922 GIC 27 arch_timer

The relevant DT node is probably:

> timer {
> compatible = "arm,armv7-timer";
> interrupts =
> <GIC_PPI 13
> (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> <GIC_PPI 14
> (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> <GIC_PPI 11
> (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> <GIC_PPI 10
> (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
> };

I guess this is a similar problem to that which Olof reported; there's
no reg property in that node, yet #size-cells=<0> since the timer node
is a direct child of the root node.

Hotplug error spew:

> root@localhost:~# ./cpuonline.py
> echo 0 > /sys/devices/system/cpu/cpu2/online
> [ 46.753347] CPU2: shutdown
> echo 0 > /sys/devices/system/cpu/cpu1/online
> [ 48.848007] CPU1: shutdown
> echo 0 > /sys/devices/system/cpu/cpu3/online
> [ 50.897720] CPU3: shutdown
> echo 1 > /sys/devices/system/cpu/cpu1/online
> [ 52.949980] CPU1: Booted secondary processor
> [ 52.961188] Clockevents: could not switch to one-shot mode: dummy_timer is not functional.
> [ 52.969566] Could not switch to high resolution mode on CPU 1
> echo 1 > /sys/devices/system/cpu/cpu2/online
> [ 54.999852] CPU2: Booted secondary processor
> [ 55.011164] Clockevents: could not switch to one-shot mode: dummy_timer is not functional.
> [ 55.019543] Could not switch to high resolution mode on CPU 2
> echo 0 > /sys/devices/system/cpu/cpu1/online
> [ 57.048730] CPU1: shutdown
> echo 1 > /sys/devices/system/cpu/cpu3/online
> [ 59.088927] CPU3: Booted secondary processor
> [ 59.101149] Clockevents: could not switch to one-shot mode: dummy_timer is not functional.
> [ 59.109517] Could not switch to high resolution mode on CPU 3
> echo 1 > /sys/devices/system/cpu/cpu1/online
> [ 61.129737] CPU1: Booted secondary processor
> [ 61.141161] Clockevents: could not switch to one-shot mode: dummy_timer is not functional.
> [ 61.149540] Could not switch to high resolution mode on CPU 1