aboutsummaryrefslogtreecommitdiff
path: root/arch/sh/boards/mach-dreamcast/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/boards/mach-dreamcast/irq.c')
-rw-r--r--arch/sh/boards/mach-dreamcast/irq.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c
index f55fc8e795e..2789647abeb 100644
--- a/arch/sh/boards/mach-dreamcast/irq.c
+++ b/arch/sh/boards/mach-dreamcast/irq.c
@@ -8,10 +8,11 @@
* This file is part of the LinuxDC project (www.linuxdc.org)
* Released under the terms of the GNU GPL v2.0
*/
-
#include <linux/irq.h>
#include <linux/io.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
+#include <linux/export.h>
+#include <linux/err.h>
#include <mach/sysasic.h>
/*
@@ -51,7 +52,7 @@
*/
#define LEVEL(event) (((event) - HW_EVENT_IRQ_BASE) / 32)
-/* Return the hardware event's bit positon within the EMR/ESR */
+/* Return the hardware event's bit position within the EMR/ESR */
#define EVENT_BIT(event) (((event) - HW_EVENT_IRQ_BASE) & 31)
/*
@@ -60,8 +61,9 @@
*/
/* Disable the hardware event by masking its bit in its EMR */
-static inline void disable_systemasic_irq(unsigned int irq)
+static inline void disable_systemasic_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
__u32 mask;
@@ -71,8 +73,9 @@ static inline void disable_systemasic_irq(unsigned int irq)
}
/* Enable the hardware event by setting its bit in its EMR */
-static inline void enable_systemasic_irq(unsigned int irq)
+static inline void enable_systemasic_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
__u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
__u32 mask;
@@ -82,18 +85,19 @@ static inline void enable_systemasic_irq(unsigned int irq)
}
/* Acknowledge a hardware event by writing its bit back to its ESR */
-static void mask_ack_systemasic_irq(unsigned int irq)
+static void mask_ack_systemasic_irq(struct irq_data *data)
{
+ unsigned int irq = data->irq;
__u32 esr = ESR_BASE + (LEVEL(irq) << 2);
- disable_systemasic_irq(irq);
+ disable_systemasic_irq(data);
outl((1 << EVENT_BIT(irq)), esr);
}
struct irq_chip systemasic_int = {
.name = "System ASIC",
- .mask = disable_systemasic_irq,
- .mask_ack = mask_ack_systemasic_irq,
- .unmask = enable_systemasic_irq,
+ .irq_mask = disable_systemasic_irq,
+ .irq_mask_ack = mask_ack_systemasic_irq,
+ .irq_unmask = enable_systemasic_irq,
};
/*
@@ -135,3 +139,18 @@ int systemasic_irq_demux(int irq)
/* Not reached */
return irq;
}
+
+void systemasic_irq_init(void)
+{
+ int irq_base, i;
+
+ irq_base = irq_alloc_descs(HW_EVENT_IRQ_BASE, HW_EVENT_IRQ_BASE,
+ HW_EVENT_IRQ_MAX - HW_EVENT_IRQ_BASE, -1);
+ if (IS_ERR_VALUE(irq_base)) {
+ pr_err("%s: failed hooking irqs\n", __func__);
+ return;
+ }
+
+ for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
+ irq_set_chip_and_handler(i, &systemasic_int, handle_level_irq);
+}