diff options
-rw-r--r-- | arch/powerpc/include/asm/mpic.h | 2 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 37 |
2 files changed, 38 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h index 7005ee0b074d..25a0cb3a79f3 100644 --- a/arch/powerpc/include/asm/mpic.h +++ b/arch/powerpc/include/asm/mpic.h | |||
@@ -371,6 +371,8 @@ struct mpic | |||
371 | * NOTE: This flag trumps MPIC_WANTS_RESET. | 371 | * NOTE: This flag trumps MPIC_WANTS_RESET. |
372 | */ | 372 | */ |
373 | #define MPIC_NO_RESET 0x00004000 | 373 | #define MPIC_NO_RESET 0x00004000 |
374 | /* Freescale MPIC (compatible includes "fsl,mpic") */ | ||
375 | #define MPIC_FSL 0x00008000 | ||
374 | 376 | ||
375 | /* MPIC HW modification ID */ | 377 | /* MPIC HW modification ID */ |
376 | #define MPIC_REGSET_MASK 0xf0000000 | 378 | #define MPIC_REGSET_MASK 0xf0000000 |
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 @@ | |||
6 | * with various broken implementations of this HW. | 6 | * with various broken implementations of this HW. |
7 | * | 7 | * |
8 | * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. | 8 | * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. |
9 | * Copyright 2010-2011 Freescale Semiconductor, Inc. | ||
9 | * | 10 | * |
10 | * This file is subject to the terms and conditions of the GNU General Public | 11 | * This file is subject to the terms and conditions of the GNU General Public |
11 | * License. See the file COPYING in the main directory of this archive | 12 | * 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, | |||
1023 | irq_hw_number_t *out_hwirq, unsigned int *out_flags) | 1024 | irq_hw_number_t *out_hwirq, unsigned int *out_flags) |
1024 | 1025 | ||
1025 | { | 1026 | { |
1027 | struct mpic *mpic = h->host_data; | ||
1026 | static unsigned char map_mpic_senses[4] = { | 1028 | static unsigned char map_mpic_senses[4] = { |
1027 | IRQ_TYPE_EDGE_RISING, | 1029 | IRQ_TYPE_EDGE_RISING, |
1028 | IRQ_TYPE_LEVEL_LOW, | 1030 | IRQ_TYPE_LEVEL_LOW, |
@@ -1031,7 +1033,38 @@ static int mpic_host_xlate(struct irq_host *h, struct device_node *ct, | |||
1031 | }; | 1033 | }; |
1032 | 1034 | ||
1033 | *out_hwirq = intspec[0]; | 1035 | *out_hwirq = intspec[0]; |
1034 | if (intsize > 1) { | 1036 | if (intsize >= 4 && (mpic->flags & MPIC_FSL)) { |
1037 | /* | ||
1038 | * Freescale MPIC with extended intspec: | ||
1039 | * First two cells are as usual. Third specifies | ||
1040 | * an "interrupt type". Fourth is type-specific data. | ||
1041 | * | ||
1042 | * See Documentation/devicetree/bindings/powerpc/fsl/mpic.txt | ||
1043 | */ | ||
1044 | switch (intspec[2]) { | ||
1045 | case 0: | ||
1046 | case 1: /* no EISR/EIMR support for now, treat as shared IRQ */ | ||
1047 | break; | ||
1048 | case 2: | ||
1049 | if (intspec[0] >= ARRAY_SIZE(mpic->ipi_vecs)) | ||
1050 | return -EINVAL; | ||
1051 | |||
1052 | *out_hwirq = mpic->ipi_vecs[intspec[0]]; | ||
1053 | break; | ||
1054 | case 3: | ||
1055 | if (intspec[0] >= ARRAY_SIZE(mpic->timer_vecs)) | ||
1056 | return -EINVAL; | ||
1057 | |||
1058 | *out_hwirq = mpic->timer_vecs[intspec[0]]; | ||
1059 | break; | ||
1060 | default: | ||
1061 | pr_debug("%s: unknown irq type %u\n", | ||
1062 | __func__, intspec[2]); | ||
1063 | return -EINVAL; | ||
1064 | } | ||
1065 | |||
1066 | *out_flags = map_mpic_senses[intspec[1] & 3]; | ||
1067 | } else if (intsize > 1) { | ||
1035 | u32 mask = 0x3; | 1068 | u32 mask = 0x3; |
1036 | 1069 | ||
1037 | /* Apple invented a new race of encoding on machines with | 1070 | /* Apple invented a new race of encoding on machines with |
@@ -1130,6 +1163,8 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
1130 | /* Check for "big-endian" in device-tree */ | 1163 | /* Check for "big-endian" in device-tree */ |
1131 | if (node && of_get_property(node, "big-endian", NULL) != NULL) | 1164 | if (node && of_get_property(node, "big-endian", NULL) != NULL) |
1132 | mpic->flags |= MPIC_BIG_ENDIAN; | 1165 | mpic->flags |= MPIC_BIG_ENDIAN; |
1166 | if (node && of_device_is_compatible(node, "fsl,mpic")) | ||
1167 | mpic->flags |= MPIC_FSL; | ||
1133 | 1168 | ||
1134 | /* Look for protected sources */ | 1169 | /* Look for protected sources */ |
1135 | if (node) { | 1170 | if (node) { |