summaryrefslogtreecommitdiff
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2011-03-25 00:43:54 +0300
committerKumar Gala <galak@kernel.crashing.org>2011-05-19 10:14:27 +0400
commit22d168ce60272ca112e86e58c5ebde82f20f9c83 (patch)
tree9be17df8b4173c7e0fa380614ae5ba3bcbe594b9 /arch/powerpc/sysdev
parentc281739f5988af1f86ef06e92485aec25b8c8c4f (diff)
downloadlinux-22d168ce60272ca112e86e58c5ebde82f20f9c83.tar.xz
powerpc/mpic: parse 4-cell intspec types other than zero
Signed-off-by: Scott Wood <scottwood@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/mpic.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 824a94fc413b..0a3c1c20115c 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -6,6 +6,7 @@
* with various broken implementations of this HW.
*
* Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
+ * Copyright 2010-2011 Freescale Semiconductor, Inc.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
@@ -1023,6 +1024,7 @@ static int mpic_host_xlate(struct irq_host *h, struct device_node *ct,
irq_hw_number_t *out_hwirq, unsigned int *out_flags)
{
+ struct mpic *mpic = h->host_data;
static unsigned char map_mpic_senses[4] = {
IRQ_TYPE_EDGE_RISING,
IRQ_TYPE_LEVEL_LOW,
@@ -1031,7 +1033,38 @@ static int mpic_host_xlate(struct irq_host *h, struct device_node *ct,
};
*out_hwirq = intspec[0];
- if (intsize > 1) {
+ if (intsize >= 4 && (mpic->flags & MPIC_FSL)) {
+ /*
+ * Freescale MPIC with extended intspec:
+ * First two cells are as usual. Third specifies
+ * an "interrupt type". Fourth is type-specific data.
+ *
+ * See Documentation/devicetree/bindings/powerpc/fsl/mpic.txt
+ */
+ switch (intspec[2]) {
+ case 0:
+ case 1: /* no EISR/EIMR support for now, treat as shared IRQ */
+ break;
+ case 2:
+ if (intspec[0] >= ARRAY_SIZE(mpic->ipi_vecs))
+ return -EINVAL;
+
+ *out_hwirq = mpic->ipi_vecs[intspec[0]];
+ break;
+ case 3:
+ if (intspec[0] >= ARRAY_SIZE(mpic->timer_vecs))
+ return -EINVAL;
+
+ *out_hwirq = mpic->timer_vecs[intspec[0]];
+ break;
+ default:
+ pr_debug("%s: unknown irq type %u\n",
+ __func__, intspec[2]);
+ return -EINVAL;
+ }
+
+ *out_flags = map_mpic_senses[intspec[1] & 3];
+ } else if (intsize > 1) {
u32 mask = 0x3;
/* Apple invented a new race of encoding on machines with
@@ -1130,6 +1163,8 @@ struct mpic * __init mpic_alloc(struct device_node *node,
/* Check for "big-endian" in device-tree */
if (node && of_get_property(node, "big-endian", NULL) != NULL)
mpic->flags |= MPIC_BIG_ENDIAN;
+ if (node && of_device_is_compatible(node, "fsl,mpic"))
+ mpic->flags |= MPIC_FSL;
/* Look for protected sources */
if (node) {