summaryrefslogtreecommitdiffstats
path: root/arch/m68k/kernel
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert@linux-m68k.org>2011-04-21 22:50:52 +0200
committerGeert Uytterhoeven <geert@linux-m68k.org>2011-11-08 22:35:49 +0100
commit4936f63cb790e265eb30a1e1630bb90bd6af0e7a (patch)
tree9cd5da60334940b4d6b190a10262f02823b06aa5 /arch/m68k/kernel
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/m68k/kernel')
-rw-r--r--arch/m68k/kernel/Makefile9
-rw-r--r--arch/m68k/kernel/ints.c52
2 files changed, 58 insertions, 3 deletions
diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile
index e7f0f2e5ad4..141425785c4 100644
--- a/arch/m68k/kernel/Makefile
+++ b/arch/m68k/kernel/Makefile
@@ -9,13 +9,18 @@ extra-y += vmlinux.lds
obj-y := entry.o m68k_ksyms.o module.o process.o ptrace.o setup.o signal.o \
sys_m68k.o syscalltable.o time.o traps.o
-obj-$(CONFIG_MMU) += ints.o devres.o vectors.o
+obj-$(CONFIG_MMU) += ints.o vectors.o
devres-$(CONFIG_MMU) = ../../../kernel/irq/devres.o
ifndef CONFIG_MMU_SUN3
obj-y += dma.o
endif
ifndef CONFIG_MMU
-obj-y += init_task.o irq.o
+obj-y += init_task.o
+endif
+ifdef CONFIG_GENERIC_HARDIRQS
+obj-y += irq.o
+else
+obj-y += devres.o
endif
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
index f6a46986512..cea439f9819 100644
--- a/arch/m68k/kernel/ints.c
+++ b/arch/m68k/kernel/ints.c
@@ -31,6 +31,7 @@ extern u32 auto_irqhandler_fixup[];
extern u32 user_irqhandler_fixup[];
extern u16 user_irqvec_fixup[];
+#ifndef CONFIG_GENERIC_HARDIRQS
/* table for system interrupt handlers */
static struct irq_data *irq_list[NR_IRQS];
static struct irq_chip *irq_chip[NR_IRQS];
@@ -41,6 +42,8 @@ static inline int irq_set_chip(unsigned int irq, struct irq_chip *chip)
irq_chip[irq] = chip;
return 0;
}
+#define irq_set_chip_and_handler(irq, chip, dummy) irq_set_chip(irq, chip)
+#endif /* !CONFIG_GENERIC_HARDIRQS */
static int m68k_first_user_vec;
@@ -56,8 +59,10 @@ static struct irq_chip user_irq_chip = {
.irq_shutdown = m68k_irq_shutdown,
};
+#ifndef CONFIG_GENERIC_HARDIRQS
#define NUM_IRQ_NODES 100
static struct irq_data nodes[NUM_IRQ_NODES];
+#endif /* !CONFIG_GENERIC_HARDIRQS */
/*
* void init_IRQ(void)
@@ -81,7 +86,7 @@ void __init init_IRQ(void)
}
for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++)
- irq_set_chip(i, &auto_irq_chip);
+ irq_set_chip_and_handler(i, &auto_irq_chip, handle_simple_irq);
mach_init_IRQ();
}
@@ -128,6 +133,35 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
flush_icache();
}
+#ifdef CONFIG_GENERIC_HARDIRQS
+
+/**
+ * m68k_setup_irq_controller
+ * @chip: irq chip which controls specified irq
+ * @handle: flow handler which handles specified irq
+ * @irq: first irq to be managed by the controller
+ * @cnt: number of irqs to be managed by the controller
+ *
+ * Change the controller for the specified range of irq, which will be used to
+ * manage these irq. auto/user irq already have a default controller, which can
+ * be changed as well, but the controller probably should use m68k_irq_startup/
+ * m68k_irq_shutdown.
+ */
+void m68k_setup_irq_controller(struct irq_chip *chip,
+ irq_flow_handler_t handle, unsigned int irq,
+ unsigned int cnt)
+{
+ int i;
+
+ for (i = 0; i < cnt; i++) {
+ irq_set_chip(irq + i, chip);
+ if (handle)
+ irq_set_handler(irq + i, handle);
+ }
+}
+
+#else /* !CONFIG_GENERIC_HARDIRQS */
+
/**
* m68k_setup_irq_chip
* @contr: irq controller which controls specified irq
@@ -316,6 +350,8 @@ void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq")));
EXPORT_SYMBOL(disable_irq_nosync);
+#endif /* !CONFIG_GENERIC_HARDIRQS */
+
unsigned int m68k_irq_startup_irq(unsigned int irq)
{
if (irq <= IRQ_AUTO_7)
@@ -341,6 +377,8 @@ void m68k_irq_shutdown(struct irq_data *data)
}
+#ifndef CONFIG_GENERIC_HARDIRQS
+
/*
* Do we need these probe functions on the m68k?
*
@@ -367,6 +405,7 @@ int probe_irq_off (unsigned long irqs)
}
EXPORT_SYMBOL(probe_irq_off);
+#endif /* CONFIG_GENERIC_HARDIRQS */
unsigned int irq_canonicalize(unsigned int irq)
{
@@ -379,6 +418,7 @@ unsigned int irq_canonicalize(unsigned int irq)
EXPORT_SYMBOL(irq_canonicalize);
+#ifndef CONFIG_GENERIC_HARDIRQS
void generic_handle_irq(unsigned int irq)
{
struct irq_data *node;
@@ -428,3 +468,13 @@ void init_irq_proc(void)
/* Insert /proc/irq driver here */
}
#endif
+
+#else /* CONFIG_GENERIC_HARDIRQS */
+
+asmlinkage void handle_badint(struct pt_regs *regs)
+{
+ atomic_inc(&irq_err_count);
+ pr_warn("unexpected interrupt from %u\n", regs->vector);
+}
+
+#endif /* CONFIG_GENERIC_HARDIRQS */