aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert@linux-m68k.org>2011-04-21 16:50:52 -0400
committerGeert Uytterhoeven <geert@linux-m68k.org>2011-11-08 16:35:49 -0500
commit4936f63cb790e265eb30a1e1630bb90bd6af0e7a (patch)
tree9cd5da60334940b4d6b190a10262f02823b06aa5 /arch
parent5a2394534b160ce18f9a705cf9de40e77648f8a2 (diff)
m68k/irq: Add genirq support
Disabled on all platforms for now Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org> [v1] Acked-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/m68k/Kconfig17
-rw-r--r--arch/m68k/include/asm/hardirq.h5
-rw-r--r--arch/m68k/include/asm/irq.h41
-rw-r--r--arch/m68k/kernel/Makefile9
-rw-r--r--arch/m68k/kernel/ints.c52
5 files changed, 112 insertions, 12 deletions
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 6c28582fb98f..a7597e119ab0 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -84,6 +84,23 @@ config MMU_SUN3
84 bool 84 bool
85 depends on MMU && !MMU_MOTOROLA 85 depends on MMU && !MMU_MOTOROLA
86 86
87config USE_GENERIC_HARDIRQS
88 bool "Use genirq"
89 depends on MMU
90 depends on !AMIGA
91 depends on !ATARI
92 depends on !MAC
93 depends on !APOLLO
94 depends on !MVME147
95 depends on !MVME16x
96 depends on !BVME6000
97 depends on !HP300
98 depends on !SUN3X
99 depends on !Q40
100 depends on !SUN3
101 select HAVE_GENERIC_HARDIRQS
102 select GENERIC_IRQ_SHOW
103
87menu "Platform setup" 104menu "Platform setup"
88 105
89source arch/m68k/Kconfig.cpu 106source arch/m68k/Kconfig.cpu
diff --git a/arch/m68k/include/asm/hardirq.h b/arch/m68k/include/asm/hardirq.h
index 870e5347155b..db30ed276878 100644
--- a/arch/m68k/include/asm/hardirq.h
+++ b/arch/m68k/include/asm/hardirq.h
@@ -18,6 +18,11 @@
18 18
19#ifdef CONFIG_MMU 19#ifdef CONFIG_MMU
20 20
21static inline void ack_bad_irq(unsigned int irq)
22{
23 pr_crit("unexpected IRQ trap at vector %02x\n", irq);
24}
25
21/* entry.S is sensitive to the offsets of these fields */ 26/* entry.S is sensitive to the offsets of these fields */
22typedef struct { 27typedef struct {
23 unsigned int __softirq_pending; 28 unsigned int __softirq_pending;
diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h
index 9a2bae8ef5b7..518e61f2fccb 100644
--- a/arch/m68k/include/asm/irq.h
+++ b/arch/m68k/include/asm/irq.h
@@ -27,11 +27,6 @@
27 27
28#ifdef CONFIG_MMU 28#ifdef CONFIG_MMU
29 29
30#include <linux/linkage.h>
31#include <linux/hardirq.h>
32#include <linux/irqreturn.h>
33#include <linux/spinlock_types.h>
34
35/* 30/*
36 * Interrupt source definitions 31 * Interrupt source definitions
37 * General interrupt sources are the level 1-7. 32 * General interrupt sources are the level 1-7.
@@ -54,10 +49,6 @@
54 49
55#define IRQ_USER 8 50#define IRQ_USER 8
56 51
57extern unsigned int irq_canonicalize(unsigned int irq);
58
59struct pt_regs;
60
61/* 52/*
62 * various flags for request_irq() - the Amiga now uses the standard 53 * various flags for request_irq() - the Amiga now uses the standard
63 * mechanism like all other architectures - IRQF_DISABLED and 54 * mechanism like all other architectures - IRQF_DISABLED and
@@ -71,6 +62,15 @@ struct pt_regs;
71#define IRQ_FLG_STD (0x8000) /* internally used */ 62#define IRQ_FLG_STD (0x8000) /* internally used */
72#endif 63#endif
73 64
65#ifndef CONFIG_GENERIC_HARDIRQS
66
67#include <linux/linkage.h>
68#include <linux/hardirq.h>
69#include <linux/irqreturn.h>
70#include <linux/spinlock_types.h>
71
72struct pt_regs;
73
74/* 74/*
75 * This structure is used to chain together the ISRs for a particular 75 * This structure is used to chain together the ISRs for a particular
76 * interrupt source (if it supports chaining). 76 * interrupt source (if it supports chaining).
@@ -121,10 +121,33 @@ extern void m68k_setup_irq_chip(struct irq_chip *, unsigned int, unsigned int);
121extern void generic_handle_irq(unsigned int); 121extern void generic_handle_irq(unsigned int);
122asmlinkage void do_IRQ(int irq, struct pt_regs *regs); 122asmlinkage void do_IRQ(int irq, struct pt_regs *regs);
123 123
124#else /* CONFIG_GENERIC_HARDIRQS */
125
126struct irq_data;
127struct irq_chip;
128struct irq_desc;
129extern unsigned int m68k_irq_startup(struct irq_data *data);
130extern unsigned int m68k_irq_startup_irq(unsigned int irq);
131extern void m68k_irq_shutdown(struct irq_data *data);
132extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int,
133 struct pt_regs *));
134extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
135 void (*handler)(unsigned int,
136 struct pt_regs *));
137extern void m68k_setup_irq_controller(struct irq_chip *,
138 void (*handle)(unsigned int irq,
139 struct irq_desc *desc),
140 unsigned int irq, unsigned int cnt);
141
142#endif /* CONFIG_GENERIC_HARDIRQS */
143
144extern unsigned int irq_canonicalize(unsigned int irq);
145
124#else 146#else
125#define irq_canonicalize(irq) (irq) 147#define irq_canonicalize(irq) (irq)
126#endif /* CONFIG_MMU */ 148#endif /* CONFIG_MMU */
127 149
128asmlinkage void do_IRQ(int irq, struct pt_regs *regs); 150asmlinkage void do_IRQ(int irq, struct pt_regs *regs);
151extern atomic_t irq_err_count;
129 152
130#endif /* _M68K_IRQ_H_ */ 153#endif /* _M68K_IRQ_H_ */
diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile
index e7f0f2e5ad44..141425785c4e 100644
--- a/arch/m68k/kernel/Makefile
+++ b/arch/m68k/kernel/Makefile
@@ -9,13 +9,18 @@ extra-y += vmlinux.lds
9obj-y := entry.o m68k_ksyms.o module.o process.o ptrace.o setup.o signal.o \ 9obj-y := entry.o m68k_ksyms.o module.o process.o ptrace.o setup.o signal.o \
10 sys_m68k.o syscalltable.o time.o traps.o 10 sys_m68k.o syscalltable.o time.o traps.o
11 11
12obj-$(CONFIG_MMU) += ints.o devres.o vectors.o 12obj-$(CONFIG_MMU) += ints.o vectors.o
13devres-$(CONFIG_MMU) = ../../../kernel/irq/devres.o 13devres-$(CONFIG_MMU) = ../../../kernel/irq/devres.o
14 14
15ifndef CONFIG_MMU_SUN3 15ifndef CONFIG_MMU_SUN3
16obj-y += dma.o 16obj-y += dma.o
17endif 17endif
18ifndef CONFIG_MMU 18ifndef CONFIG_MMU
19obj-y += init_task.o irq.o 19obj-y += init_task.o
20endif
21ifdef CONFIG_GENERIC_HARDIRQS
22obj-y += irq.o
23else
24obj-y += devres.o
20endif 25endif
21 26
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
index f6a469865125..cea439f9819b 100644
--- a/arch/m68k/kernel/ints.c
+++ b/arch/m68k/kernel/ints.c
@@ -31,6 +31,7 @@ extern u32 auto_irqhandler_fixup[];
31extern u32 user_irqhandler_fixup[]; 31extern u32 user_irqhandler_fixup[];
32extern u16 user_irqvec_fixup[]; 32extern u16 user_irqvec_fixup[];
33 33
34#ifndef CONFIG_GENERIC_HARDIRQS
34/* table for system interrupt handlers */ 35/* table for system interrupt handlers */
35static struct irq_data *irq_list[NR_IRQS]; 36static struct irq_data *irq_list[NR_IRQS];
36static struct irq_chip *irq_chip[NR_IRQS]; 37static struct irq_chip *irq_chip[NR_IRQS];
@@ -41,6 +42,8 @@ static inline int irq_set_chip(unsigned int irq, struct irq_chip *chip)
41 irq_chip[irq] = chip; 42 irq_chip[irq] = chip;
42 return 0; 43 return 0;
43} 44}
45#define irq_set_chip_and_handler(irq, chip, dummy) irq_set_chip(irq, chip)
46#endif /* !CONFIG_GENERIC_HARDIRQS */
44 47
45static int m68k_first_user_vec; 48static int m68k_first_user_vec;
46 49
@@ -56,8 +59,10 @@ static struct irq_chip user_irq_chip = {
56 .irq_shutdown = m68k_irq_shutdown, 59 .irq_shutdown = m68k_irq_shutdown,
57}; 60};
58 61
62#ifndef CONFIG_GENERIC_HARDIRQS
59#define NUM_IRQ_NODES 100 63#define NUM_IRQ_NODES 100
60static struct irq_data nodes[NUM_IRQ_NODES]; 64static struct irq_data nodes[NUM_IRQ_NODES];
65#endif /* !CONFIG_GENERIC_HARDIRQS */
61 66
62/* 67/*
63 * void init_IRQ(void) 68 * void init_IRQ(void)
@@ -81,7 +86,7 @@ void __init init_IRQ(void)
81 } 86 }
82 87
83 for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++) 88 for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++)
84 irq_set_chip(i, &auto_irq_chip); 89 irq_set_chip_and_handler(i, &auto_irq_chip, handle_simple_irq);
85 90
86 mach_init_IRQ(); 91 mach_init_IRQ();
87} 92}
@@ -128,6 +133,35 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
128 flush_icache(); 133 flush_icache();
129} 134}
130 135
136#ifdef CONFIG_GENERIC_HARDIRQS
137
138/**
139 * m68k_setup_irq_controller
140 * @chip: irq chip which controls specified irq
141 * @handle: flow handler which handles specified irq
142 * @irq: first irq to be managed by the controller
143 * @cnt: number of irqs to be managed by the controller
144 *
145 * Change the controller for the specified range of irq, which will be used to
146 * manage these irq. auto/user irq already have a default controller, which can
147 * be changed as well, but the controller probably should use m68k_irq_startup/
148 * m68k_irq_shutdown.
149 */
150void m68k_setup_irq_controller(struct irq_chip *chip,
151 irq_flow_handler_t handle, unsigned int irq,
152 unsigned int cnt)
153{
154 int i;
155
156 for (i = 0; i < cnt; i++) {
157 irq_set_chip(irq + i, chip);
158 if (handle)
159 irq_set_handler(irq + i, handle);
160 }
161}
162
163#else /* !CONFIG_GENERIC_HARDIRQS */
164
131/** 165/**
132 * m68k_setup_irq_chip 166 * m68k_setup_irq_chip
133 * @contr: irq controller which controls specified irq 167 * @contr: irq controller which controls specified irq
@@ -316,6 +350,8 @@ void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq")));
316 350
317EXPORT_SYMBOL(disable_irq_nosync); 351EXPORT_SYMBOL(disable_irq_nosync);
318 352
353#endif /* !CONFIG_GENERIC_HARDIRQS */
354
319unsigned int m68k_irq_startup_irq(unsigned int irq) 355unsigned int m68k_irq_startup_irq(unsigned int irq)
320{ 356{
321 if (irq <= IRQ_AUTO_7) 357 if (irq <= IRQ_AUTO_7)
@@ -341,6 +377,8 @@ void m68k_irq_shutdown(struct irq_data *data)
341} 377}
342 378
343 379
380#ifndef CONFIG_GENERIC_HARDIRQS
381
344/* 382/*
345 * Do we need these probe functions on the m68k? 383 * Do we need these probe functions on the m68k?
346 * 384 *
@@ -367,6 +405,7 @@ int probe_irq_off (unsigned long irqs)
367} 405}
368 406
369EXPORT_SYMBOL(probe_irq_off); 407EXPORT_SYMBOL(probe_irq_off);
408#endif /* CONFIG_GENERIC_HARDIRQS */
370 409
371unsigned int irq_canonicalize(unsigned int irq) 410unsigned int irq_canonicalize(unsigned int irq)
372{ 411{
@@ -379,6 +418,7 @@ unsigned int irq_canonicalize(unsigned int irq)
379 418
380EXPORT_SYMBOL(irq_canonicalize); 419EXPORT_SYMBOL(irq_canonicalize);
381 420
421#ifndef CONFIG_GENERIC_HARDIRQS
382void generic_handle_irq(unsigned int irq) 422void generic_handle_irq(unsigned int irq)
383{ 423{
384 struct irq_data *node; 424 struct irq_data *node;
@@ -428,3 +468,13 @@ void init_irq_proc(void)
428 /* Insert /proc/irq driver here */ 468 /* Insert /proc/irq driver here */
429} 469}
430#endif 470#endif
471
472#else /* CONFIG_GENERIC_HARDIRQS */
473
474asmlinkage void handle_badint(struct pt_regs *regs)
475{
476 atomic_inc(&irq_err_count);
477 pr_warn("unexpected interrupt from %u\n", regs->vector);
478}
479
480#endif /* CONFIG_GENERIC_HARDIRQS */