Commit a83479545d0e693da0886fd28d041d3a5c1bc966
Committed by
Ralf Baechle
1 parent
bc45eb8950
Exists in
master
and in
7 other branches
[MIPS] VR41xx: unsigned irq cannot be negative
Signed-off-by: Roel Kluin <roel.kluin@gmail.com> Acked-by: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Showing 1 changed file with 4 additions and 2 deletions Inline Diff
arch/mips/vr41xx/common/irq.c
1 | /* | 1 | /* |
2 | * Interrupt handing routines for NEC VR4100 series. | 2 | * Interrupt handing routines for NEC VR4100 series. |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2005-2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
10 | * | 10 | * |
11 | * This program is distributed in the hope that it will be useful, | 11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | 22 | ||
23 | #include <asm/irq_cpu.h> | 23 | #include <asm/irq_cpu.h> |
24 | #include <asm/system.h> | 24 | #include <asm/system.h> |
25 | #include <asm/vr41xx/irq.h> | 25 | #include <asm/vr41xx/irq.h> |
26 | 26 | ||
27 | typedef struct irq_cascade { | 27 | typedef struct irq_cascade { |
28 | int (*get_irq)(unsigned int); | 28 | int (*get_irq)(unsigned int); |
29 | } irq_cascade_t; | 29 | } irq_cascade_t; |
30 | 30 | ||
31 | static irq_cascade_t irq_cascade[NR_IRQS] __cacheline_aligned; | 31 | static irq_cascade_t irq_cascade[NR_IRQS] __cacheline_aligned; |
32 | 32 | ||
33 | static struct irqaction cascade_irqaction = { | 33 | static struct irqaction cascade_irqaction = { |
34 | .handler = no_action, | 34 | .handler = no_action, |
35 | .mask = CPU_MASK_NONE, | 35 | .mask = CPU_MASK_NONE, |
36 | .name = "cascade", | 36 | .name = "cascade", |
37 | }; | 37 | }; |
38 | 38 | ||
39 | int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int)) | 39 | int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int)) |
40 | { | 40 | { |
41 | int retval = 0; | 41 | int retval = 0; |
42 | 42 | ||
43 | if (irq >= NR_IRQS) | 43 | if (irq >= NR_IRQS) |
44 | return -EINVAL; | 44 | return -EINVAL; |
45 | 45 | ||
46 | if (irq_cascade[irq].get_irq != NULL) | 46 | if (irq_cascade[irq].get_irq != NULL) |
47 | free_irq(irq, NULL); | 47 | free_irq(irq, NULL); |
48 | 48 | ||
49 | irq_cascade[irq].get_irq = get_irq; | 49 | irq_cascade[irq].get_irq = get_irq; |
50 | 50 | ||
51 | if (get_irq != NULL) { | 51 | if (get_irq != NULL) { |
52 | retval = setup_irq(irq, &cascade_irqaction); | 52 | retval = setup_irq(irq, &cascade_irqaction); |
53 | if (retval < 0) | 53 | if (retval < 0) |
54 | irq_cascade[irq].get_irq = NULL; | 54 | irq_cascade[irq].get_irq = NULL; |
55 | } | 55 | } |
56 | 56 | ||
57 | return retval; | 57 | return retval; |
58 | } | 58 | } |
59 | 59 | ||
60 | EXPORT_SYMBOL_GPL(cascade_irq); | 60 | EXPORT_SYMBOL_GPL(cascade_irq); |
61 | 61 | ||
62 | static void irq_dispatch(unsigned int irq) | 62 | static void irq_dispatch(unsigned int irq) |
63 | { | 63 | { |
64 | irq_cascade_t *cascade; | 64 | irq_cascade_t *cascade; |
65 | struct irq_desc *desc; | 65 | struct irq_desc *desc; |
66 | 66 | ||
67 | if (irq >= NR_IRQS) { | 67 | if (irq >= NR_IRQS) { |
68 | atomic_inc(&irq_err_count); | 68 | atomic_inc(&irq_err_count); |
69 | return; | 69 | return; |
70 | } | 70 | } |
71 | 71 | ||
72 | cascade = irq_cascade + irq; | 72 | cascade = irq_cascade + irq; |
73 | if (cascade->get_irq != NULL) { | 73 | if (cascade->get_irq != NULL) { |
74 | unsigned int source_irq = irq; | 74 | unsigned int source_irq = irq; |
75 | int ret; | ||
75 | desc = irq_desc + source_irq; | 76 | desc = irq_desc + source_irq; |
76 | if (desc->chip->mask_ack) | 77 | if (desc->chip->mask_ack) |
77 | desc->chip->mask_ack(source_irq); | 78 | desc->chip->mask_ack(source_irq); |
78 | else { | 79 | else { |
79 | desc->chip->mask(source_irq); | 80 | desc->chip->mask(source_irq); |
80 | desc->chip->ack(source_irq); | 81 | desc->chip->ack(source_irq); |
81 | } | 82 | } |
82 | irq = cascade->get_irq(irq); | 83 | ret = cascade->get_irq(irq); |
83 | if (irq < 0) | 84 | irq = ret; |
85 | if (ret < 0) | ||
84 | atomic_inc(&irq_err_count); | 86 | atomic_inc(&irq_err_count); |
85 | else | 87 | else |
86 | irq_dispatch(irq); | 88 | irq_dispatch(irq); |
87 | if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) | 89 | if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) |
88 | desc->chip->unmask(source_irq); | 90 | desc->chip->unmask(source_irq); |
89 | } else | 91 | } else |
90 | do_IRQ(irq); | 92 | do_IRQ(irq); |
91 | } | 93 | } |
92 | 94 | ||
93 | asmlinkage void plat_irq_dispatch(void) | 95 | asmlinkage void plat_irq_dispatch(void) |
94 | { | 96 | { |
95 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | 97 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; |
96 | 98 | ||
97 | if (pending & CAUSEF_IP7) | 99 | if (pending & CAUSEF_IP7) |
98 | do_IRQ(TIMER_IRQ); | 100 | do_IRQ(TIMER_IRQ); |
99 | else if (pending & 0x7800) { | 101 | else if (pending & 0x7800) { |
100 | if (pending & CAUSEF_IP3) | 102 | if (pending & CAUSEF_IP3) |
101 | irq_dispatch(INT1_IRQ); | 103 | irq_dispatch(INT1_IRQ); |
102 | else if (pending & CAUSEF_IP4) | 104 | else if (pending & CAUSEF_IP4) |
103 | irq_dispatch(INT2_IRQ); | 105 | irq_dispatch(INT2_IRQ); |
104 | else if (pending & CAUSEF_IP5) | 106 | else if (pending & CAUSEF_IP5) |
105 | irq_dispatch(INT3_IRQ); | 107 | irq_dispatch(INT3_IRQ); |
106 | else if (pending & CAUSEF_IP6) | 108 | else if (pending & CAUSEF_IP6) |
107 | irq_dispatch(INT4_IRQ); | 109 | irq_dispatch(INT4_IRQ); |
108 | } else if (pending & CAUSEF_IP2) | 110 | } else if (pending & CAUSEF_IP2) |
109 | irq_dispatch(INT0_IRQ); | 111 | irq_dispatch(INT0_IRQ); |
110 | else if (pending & CAUSEF_IP0) | 112 | else if (pending & CAUSEF_IP0) |
111 | do_IRQ(MIPS_SOFTINT0_IRQ); | 113 | do_IRQ(MIPS_SOFTINT0_IRQ); |
112 | else if (pending & CAUSEF_IP1) | 114 | else if (pending & CAUSEF_IP1) |
113 | do_IRQ(MIPS_SOFTINT1_IRQ); | 115 | do_IRQ(MIPS_SOFTINT1_IRQ); |
114 | else | 116 | else |
115 | spurious_interrupt(); | 117 | spurious_interrupt(); |
116 | } | 118 | } |
117 | 119 | ||
118 | void __init arch_init_irq(void) | 120 | void __init arch_init_irq(void) |
119 | { | 121 | { |
120 | mips_cpu_irq_init(); | 122 | mips_cpu_irq_init(); |
121 | } | 123 | } |
122 | 124 |