diff options
author | Michael Schmitz <schmitzmic@gmail.com> | 2013-04-05 20:26:37 -0400 |
---|---|---|
committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2013-04-16 15:09:21 -0400 |
commit | b1ae432c5e3d682d86a88fc798a9ed2469c14a7a (patch) | |
tree | 5ec9395eff73162d842802019604ca3058f32e46 | |
parent | 84b16b7b0d5c818fadc731a69965dc76dce0c91e (diff) |
m68k/atari: use dedicated irq_chip for timer D interrupts
Add a special irq_chip for the Atari MFP timer D interrupt,
which is used as a polling timer for EtherNEC and NetUSBee
Signed-off-by: Michael Schmitz <schmitz@debian.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
-rw-r--r-- | arch/m68k/atari/ataints.c | 70 | ||||
-rw-r--r-- | arch/m68k/include/asm/atariints.h | 9 |
2 files changed, 79 insertions, 0 deletions
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c index 3f41092d1b70..f699c829e594 100644 --- a/arch/m68k/atari/ataints.c +++ b/arch/m68k/atari/ataints.c | |||
@@ -122,6 +122,62 @@ static struct irq_chip atari_irq_chip = { | |||
122 | }; | 122 | }; |
123 | 123 | ||
124 | /* | 124 | /* |
125 | * ST-MFP timer D chained interrupts - each driver gets its own timer | ||
126 | * interrupt instance. | ||
127 | */ | ||
128 | |||
129 | struct mfptimerbase { | ||
130 | volatile struct MFP *mfp; | ||
131 | unsigned char mfp_mask, mfp_data; | ||
132 | unsigned short int_mask; | ||
133 | int handler_irq, mfptimer_irq, server_irq; | ||
134 | char *name; | ||
135 | } stmfp_base = { | ||
136 | .mfp = &st_mfp, | ||
137 | .int_mask = 0x0, | ||
138 | .handler_irq = IRQ_MFP_TIMD, | ||
139 | .mfptimer_irq = IRQ_MFP_TIMER1, | ||
140 | .name = "MFP Timer D" | ||
141 | }; | ||
142 | |||
143 | static irqreturn_t mfptimer_handler(int irq, void *dev_id) | ||
144 | { | ||
145 | struct mfptimerbase *base = dev_id; | ||
146 | int mach_irq; | ||
147 | unsigned char ints; | ||
148 | |||
149 | mach_irq = base->mfptimer_irq; | ||
150 | ints = base->int_mask; | ||
151 | for (; ints; mach_irq++, ints >>= 1) { | ||
152 | if (ints & 1) | ||
153 | generic_handle_irq(mach_irq); | ||
154 | } | ||
155 | return IRQ_HANDLED; | ||
156 | } | ||
157 | |||
158 | |||
159 | static void atari_mfptimer_enable(struct irq_data *data) | ||
160 | { | ||
161 | int mfp_num = data->irq - IRQ_MFP_TIMER1; | ||
162 | stmfp_base.int_mask |= 1 << mfp_num; | ||
163 | atari_enable_irq(IRQ_MFP_TIMD); | ||
164 | } | ||
165 | |||
166 | static void atari_mfptimer_disable(struct irq_data *data) | ||
167 | { | ||
168 | int mfp_num = data->irq - IRQ_MFP_TIMER1; | ||
169 | stmfp_base.int_mask &= ~(1 << mfp_num); | ||
170 | if (!stmfp_base.int_mask) | ||
171 | atari_disable_irq(IRQ_MFP_TIMD); | ||
172 | } | ||
173 | |||
174 | static struct irq_chip atari_mfptimer_chip = { | ||
175 | .name = "timer_d", | ||
176 | .irq_enable = atari_mfptimer_enable, | ||
177 | .irq_disable = atari_mfptimer_disable, | ||
178 | }; | ||
179 | |||
180 | /* | ||
125 | * void atari_init_IRQ (void) | 181 | * void atari_init_IRQ (void) |
126 | * | 182 | * |
127 | * Parameters: None | 183 | * Parameters: None |
@@ -198,6 +254,20 @@ void __init atari_init_IRQ(void) | |||
198 | /* Initialize the PSG: all sounds off, both ports output */ | 254 | /* Initialize the PSG: all sounds off, both ports output */ |
199 | sound_ym.rd_data_reg_sel = 7; | 255 | sound_ym.rd_data_reg_sel = 7; |
200 | sound_ym.wd_data = 0xff; | 256 | sound_ym.wd_data = 0xff; |
257 | |||
258 | m68k_setup_irq_controller(&atari_mfptimer_chip, handle_simple_irq, | ||
259 | IRQ_MFP_TIMER1, 8); | ||
260 | |||
261 | /* prepare timer D data for use as poll interrupt */ | ||
262 | /* set Timer D data Register - needs to be > 0 */ | ||
263 | st_mfp.tim_dt_d = 254; /* < 100 Hz */ | ||
264 | /* start timer D, div = 1:100 */ | ||
265 | st_mfp.tim_ct_cd = (st_mfp.tim_ct_cd & 0xf0) | 0x6; | ||
266 | |||
267 | /* request timer D dispatch handler */ | ||
268 | if (request_irq(IRQ_MFP_TIMD, mfptimer_handler, IRQF_SHARED, | ||
269 | stmfp_base.name, &stmfp_base)) | ||
270 | pr_err("Couldn't register %s interrupt\n", stmfp_base.name); | ||
201 | } | 271 | } |
202 | 272 | ||
203 | 273 | ||
diff --git a/arch/m68k/include/asm/atariints.h b/arch/m68k/include/asm/atariints.h index 5fc13bdf9044..8f71504956cd 100644 --- a/arch/m68k/include/asm/atariints.h +++ b/arch/m68k/include/asm/atariints.h | |||
@@ -94,6 +94,15 @@ | |||
94 | #define IRQ_SCCA_RX (52) | 94 | #define IRQ_SCCA_RX (52) |
95 | #define IRQ_SCCA_SPCOND (54) | 95 | #define IRQ_SCCA_SPCOND (54) |
96 | 96 | ||
97 | /* shared MFP timer D interrupts - hires timer for EtherNEC et al. */ | ||
98 | #define IRQ_MFP_TIMER1 (64) | ||
99 | #define IRQ_MFP_TIMER2 (65) | ||
100 | #define IRQ_MFP_TIMER3 (66) | ||
101 | #define IRQ_MFP_TIMER4 (67) | ||
102 | #define IRQ_MFP_TIMER5 (68) | ||
103 | #define IRQ_MFP_TIMER6 (69) | ||
104 | #define IRQ_MFP_TIMER7 (70) | ||
105 | #define IRQ_MFP_TIMER8 (71) | ||
97 | 106 | ||
98 | #define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */ | 107 | #define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */ |
99 | #define INT_TICKS 246 /* to make sched_time = 99.902... HZ */ | 108 | #define INT_TICKS 246 /* to make sched_time = 99.902... HZ */ |