aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorMatt Fleming <mjf@gentoo.org>2008-12-14 07:02:26 -0500
committerPaul Mundt <lethal@linux-sh.org>2008-12-22 04:44:06 -0500
commite85a47744bbdfbcc65c94b2af67499f861c6fa42 (patch)
treec37699b7741c3d97fdf01e68914a3383f408c69a /arch/sh
parentbd0a22d21f26864792a0e49c20f5bd25d6c335e4 (diff)
sh: Convert Dreamcast support from hw_interrupt_type to irq_chip
Switch the dreamcast IRQ code over to the irq_chip way of doing things, so that we can set GENERIC_HARDIRQS_NO__DO_IRQ for all SuperH boards. Also, whilst I'm here change some things to make checkpatch.pl happy: - Indent with tabs, not with spaces - Include <linux/io.h>, not <asm/io.h> - Fix the multi-line comment style - Fix some typos in the comments Tested-by: Adrian McMenamin <adrian@newgolddream.dyndns.info> Signed-off-by: Matt Fleming <mjf@gentoo.org> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/boards/mach-dreamcast/irq.c192
-rw-r--r--arch/sh/boards/mach-dreamcast/setup.c5
2 files changed, 91 insertions, 106 deletions
diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c
index 67bdc33dd411..f55fc8e795e9 100644
--- a/arch/sh/boards/mach-dreamcast/irq.c
+++ b/arch/sh/boards/mach-dreamcast/irq.c
@@ -10,106 +10,90 @@
10 */ 10 */
11 11
12#include <linux/irq.h> 12#include <linux/irq.h>
13#include <asm/io.h> 13#include <linux/io.h>
14#include <asm/irq.h> 14#include <asm/irq.h>
15#include <mach/sysasic.h> 15#include <mach/sysasic.h>
16 16
17/* Dreamcast System ASIC Hardware Events - 17/*
18 18 * Dreamcast System ASIC Hardware Events -
19 The Dreamcast's System ASIC (a.k.a. Holly) is responsible for receiving 19 *
20 hardware events from system peripherals and triggering an SH7750 IRQ. 20 * The Dreamcast's System ASIC (a.k.a. Holly) is responsible for receiving
21 Hardware events can trigger IRQs 13, 11, or 9 depending on which bits are 21 * hardware events from system peripherals and triggering an SH7750 IRQ.
22 set in the Event Mask Registers (EMRs). When a hardware event is 22 * Hardware events can trigger IRQs 13, 11, or 9 depending on which bits are
23 triggered, it's corresponding bit in the Event Status Registers (ESRs) 23 * set in the Event Mask Registers (EMRs). When a hardware event is
24 is set, and that bit should be rewritten to the ESR to acknowledge that 24 * triggered, its corresponding bit in the Event Status Registers (ESRs)
25 event. 25 * is set, and that bit should be rewritten to the ESR to acknowledge that
26 26 * event.
27 There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908. Event 27 *
28 types can be found in include/asm-sh/dreamcast/sysasic.h. There are three 28 * There are three 32-bit ESRs located at 0xa05f6900 - 0xa05f6908. Event
29 groups of EMRs that parallel the ESRs. Each EMR group corresponds to an 29 * types can be found in arch/sh/include/mach-dreamcast/mach/sysasic.h.
30 IRQ, so 0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928 30 * There are three groups of EMRs that parallel the ESRs. Each EMR group
31 triggers IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9. 31 * corresponds to an IRQ, so 0xa05f6910 - 0xa05f6918 triggers IRQ 13,
32 32 * 0xa05f6920 - 0xa05f6928 triggers IRQ 11, and 0xa05f6930 - 0xa05f6938
33 In the kernel, these events are mapped to virtual IRQs so that drivers can 33 * triggers IRQ 9.
34 respond to them as they would a normal interrupt. In order to keep this 34 *
35 mapping simple, the events are mapped as: 35 * In the kernel, these events are mapped to virtual IRQs so that drivers can
36 36 * respond to them as they would a normal interrupt. In order to keep this
37 6900/6910 - Events 0-31, IRQ 13 37 * mapping simple, the events are mapped as:
38 6904/6924 - Events 32-63, IRQ 11 38 *
39 6908/6938 - Events 64-95, IRQ 9 39 * 6900/6910 - Events 0-31, IRQ 13
40 40 * 6904/6924 - Events 32-63, IRQ 11
41*/ 41 * 6908/6938 - Events 64-95, IRQ 9
42 *
43 */
42 44
43#define ESR_BASE 0x005f6900 /* Base event status register */ 45#define ESR_BASE 0x005f6900 /* Base event status register */
44#define EMR_BASE 0x005f6910 /* Base event mask register */ 46#define EMR_BASE 0x005f6910 /* Base event mask register */
45 47
46/* Helps us determine the EMR group that this event belongs to: 0 = 0x6910, 48/*
47 1 = 0x6920, 2 = 0x6930; also determine the event offset */ 49 * Helps us determine the EMR group that this event belongs to: 0 = 0x6910,
50 * 1 = 0x6920, 2 = 0x6930; also determine the event offset.
51 */
48#define LEVEL(event) (((event) - HW_EVENT_IRQ_BASE) / 32) 52#define LEVEL(event) (((event) - HW_EVENT_IRQ_BASE) / 32)
49 53
50/* Return the hardware event's bit positon within the EMR/ESR */ 54/* Return the hardware event's bit positon within the EMR/ESR */
51#define EVENT_BIT(event) (((event) - HW_EVENT_IRQ_BASE) & 31) 55#define EVENT_BIT(event) (((event) - HW_EVENT_IRQ_BASE) & 31)
52 56
53/* For each of these *_irq routines, the IRQ passed in is the virtual IRQ 57/*
54 (logically mapped to the corresponding bit for the hardware event). */ 58 * For each of these *_irq routines, the IRQ passed in is the virtual IRQ
59 * (logically mapped to the corresponding bit for the hardware event).
60 */
55 61
56/* Disable the hardware event by masking its bit in its EMR */ 62/* Disable the hardware event by masking its bit in its EMR */
57static inline void disable_systemasic_irq(unsigned int irq) 63static inline void disable_systemasic_irq(unsigned int irq)
58{ 64{
59 __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2); 65 __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
60 __u32 mask; 66 __u32 mask;
61 67
62 mask = inl(emr); 68 mask = inl(emr);
63 mask &= ~(1 << EVENT_BIT(irq)); 69 mask &= ~(1 << EVENT_BIT(irq));
64 outl(mask, emr); 70 outl(mask, emr);
65} 71}
66 72
67/* Enable the hardware event by setting its bit in its EMR */ 73/* Enable the hardware event by setting its bit in its EMR */
68static inline void enable_systemasic_irq(unsigned int irq) 74static inline void enable_systemasic_irq(unsigned int irq)
69{ 75{
70 __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2); 76 __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
71 __u32 mask; 77 __u32 mask;
72 78
73 mask = inl(emr); 79 mask = inl(emr);
74 mask |= (1 << EVENT_BIT(irq)); 80 mask |= (1 << EVENT_BIT(irq));
75 outl(mask, emr); 81 outl(mask, emr);
76} 82}
77 83
78/* Acknowledge a hardware event by writing its bit back to its ESR */ 84/* Acknowledge a hardware event by writing its bit back to its ESR */
79static void ack_systemasic_irq(unsigned int irq) 85static void mask_ack_systemasic_irq(unsigned int irq)
80{
81 __u32 esr = ESR_BASE + (LEVEL(irq) << 2);
82 disable_systemasic_irq(irq);
83 outl((1 << EVENT_BIT(irq)), esr);
84}
85
86/* After a IRQ has been ack'd and responded to, it needs to be renabled */
87static void end_systemasic_irq(unsigned int irq)
88{
89 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
90 enable_systemasic_irq(irq);
91}
92
93static unsigned int startup_systemasic_irq(unsigned int irq)
94{
95 enable_systemasic_irq(irq);
96
97 return 0;
98}
99
100static void shutdown_systemasic_irq(unsigned int irq)
101{ 86{
102 disable_systemasic_irq(irq); 87 __u32 esr = ESR_BASE + (LEVEL(irq) << 2);
88 disable_systemasic_irq(irq);
89 outl((1 << EVENT_BIT(irq)), esr);
103} 90}
104 91
105struct hw_interrupt_type systemasic_int = { 92struct irq_chip systemasic_int = {
106 .typename = "System ASIC", 93 .name = "System ASIC",
107 .startup = startup_systemasic_irq, 94 .mask = disable_systemasic_irq,
108 .shutdown = shutdown_systemasic_irq, 95 .mask_ack = mask_ack_systemasic_irq,
109 .enable = enable_systemasic_irq, 96 .unmask = enable_systemasic_irq,
110 .disable = disable_systemasic_irq,
111 .ack = ack_systemasic_irq,
112 .end = end_systemasic_irq,
113}; 97};
114 98
115/* 99/*
@@ -117,37 +101,37 @@ struct hw_interrupt_type systemasic_int = {
117 */ 101 */
118int systemasic_irq_demux(int irq) 102int systemasic_irq_demux(int irq)
119{ 103{
120 __u32 emr, esr, status, level; 104 __u32 emr, esr, status, level;
121 __u32 j, bit; 105 __u32 j, bit;
122 106
123 switch (irq) { 107 switch (irq) {
124 case 13: 108 case 13:
125 level = 0; 109 level = 0;
126 break; 110 break;
127 case 11: 111 case 11:
128 level = 1; 112 level = 1;
129 break; 113 break;
130 case 9: 114 case 9:
131 level = 2; 115 level = 2;
132 break; 116 break;
133 default: 117 default:
134 return irq; 118 return irq;
135 } 119 }
136 emr = EMR_BASE + (level << 4) + (level << 2); 120 emr = EMR_BASE + (level << 4) + (level << 2);
137 esr = ESR_BASE + (level << 2); 121 esr = ESR_BASE + (level << 2);
138 122
139 /* Mask the ESR to filter any spurious, unwanted interrupts */ 123 /* Mask the ESR to filter any spurious, unwanted interrupts */
140 status = inl(esr); 124 status = inl(esr);
141 status &= inl(emr); 125 status &= inl(emr);
142 126
143 /* Now scan and find the first set bit as the event to map */ 127 /* Now scan and find the first set bit as the event to map */
144 for (bit = 1, j = 0; j < 32; bit <<= 1, j++) { 128 for (bit = 1, j = 0; j < 32; bit <<= 1, j++) {
145 if (status & bit) { 129 if (status & bit) {
146 irq = HW_EVENT_IRQ_BASE + j + (level << 5); 130 irq = HW_EVENT_IRQ_BASE + j + (level << 5);
147 return irq; 131 return irq;
148 } 132 }
149 } 133 }
150 134
151 /* Not reached */ 135 /* Not reached */
152 return irq; 136 return irq;
153} 137}
diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c
index 7d944fc75e93..d1bee4884cd6 100644
--- a/arch/sh/boards/mach-dreamcast/setup.c
+++ b/arch/sh/boards/mach-dreamcast/setup.c
@@ -28,7 +28,7 @@
28#include <asm/machvec.h> 28#include <asm/machvec.h>
29#include <mach/sysasic.h> 29#include <mach/sysasic.h>
30 30
31extern struct hw_interrupt_type systemasic_int; 31extern struct irq_chip systemasic_int;
32extern void aica_time_init(void); 32extern void aica_time_init(void);
33extern int gapspci_init(void); 33extern int gapspci_init(void);
34extern int systemasic_irq_demux(int); 34extern int systemasic_irq_demux(int);
@@ -47,7 +47,8 @@ static void __init dreamcast_setup(char **cmdline_p)
47 47
48 /* Assign all virtual IRQs to the System ASIC int. handler */ 48 /* Assign all virtual IRQs to the System ASIC int. handler */
49 for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) 49 for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
50 irq_desc[i].chip = &systemasic_int; 50 set_irq_chip_and_handler(i, &systemasic_int,
51 handle_level_irq);
51 52
52 board_time_init = aica_time_init; 53 board_time_init = aica_time_init;
53 54