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>
This commit is contained in:
parent
84b16b7b0d
commit
b1ae432c5e
@ -121,6 +121,62 @@ static struct irq_chip atari_irq_chip = {
|
|||||||
.irq_disable = atari_irq_disable,
|
.irq_disable = atari_irq_disable,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ST-MFP timer D chained interrupts - each driver gets its own timer
|
||||||
|
* interrupt instance.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct mfptimerbase {
|
||||||
|
volatile struct MFP *mfp;
|
||||||
|
unsigned char mfp_mask, mfp_data;
|
||||||
|
unsigned short int_mask;
|
||||||
|
int handler_irq, mfptimer_irq, server_irq;
|
||||||
|
char *name;
|
||||||
|
} stmfp_base = {
|
||||||
|
.mfp = &st_mfp,
|
||||||
|
.int_mask = 0x0,
|
||||||
|
.handler_irq = IRQ_MFP_TIMD,
|
||||||
|
.mfptimer_irq = IRQ_MFP_TIMER1,
|
||||||
|
.name = "MFP Timer D"
|
||||||
|
};
|
||||||
|
|
||||||
|
static irqreturn_t mfptimer_handler(int irq, void *dev_id)
|
||||||
|
{
|
||||||
|
struct mfptimerbase *base = dev_id;
|
||||||
|
int mach_irq;
|
||||||
|
unsigned char ints;
|
||||||
|
|
||||||
|
mach_irq = base->mfptimer_irq;
|
||||||
|
ints = base->int_mask;
|
||||||
|
for (; ints; mach_irq++, ints >>= 1) {
|
||||||
|
if (ints & 1)
|
||||||
|
generic_handle_irq(mach_irq);
|
||||||
|
}
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void atari_mfptimer_enable(struct irq_data *data)
|
||||||
|
{
|
||||||
|
int mfp_num = data->irq - IRQ_MFP_TIMER1;
|
||||||
|
stmfp_base.int_mask |= 1 << mfp_num;
|
||||||
|
atari_enable_irq(IRQ_MFP_TIMD);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void atari_mfptimer_disable(struct irq_data *data)
|
||||||
|
{
|
||||||
|
int mfp_num = data->irq - IRQ_MFP_TIMER1;
|
||||||
|
stmfp_base.int_mask &= ~(1 << mfp_num);
|
||||||
|
if (!stmfp_base.int_mask)
|
||||||
|
atari_disable_irq(IRQ_MFP_TIMD);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irq_chip atari_mfptimer_chip = {
|
||||||
|
.name = "timer_d",
|
||||||
|
.irq_enable = atari_mfptimer_enable,
|
||||||
|
.irq_disable = atari_mfptimer_disable,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void atari_init_IRQ (void)
|
* void atari_init_IRQ (void)
|
||||||
*
|
*
|
||||||
@ -198,6 +254,20 @@ void __init atari_init_IRQ(void)
|
|||||||
/* Initialize the PSG: all sounds off, both ports output */
|
/* Initialize the PSG: all sounds off, both ports output */
|
||||||
sound_ym.rd_data_reg_sel = 7;
|
sound_ym.rd_data_reg_sel = 7;
|
||||||
sound_ym.wd_data = 0xff;
|
sound_ym.wd_data = 0xff;
|
||||||
|
|
||||||
|
m68k_setup_irq_controller(&atari_mfptimer_chip, handle_simple_irq,
|
||||||
|
IRQ_MFP_TIMER1, 8);
|
||||||
|
|
||||||
|
/* prepare timer D data for use as poll interrupt */
|
||||||
|
/* set Timer D data Register - needs to be > 0 */
|
||||||
|
st_mfp.tim_dt_d = 254; /* < 100 Hz */
|
||||||
|
/* start timer D, div = 1:100 */
|
||||||
|
st_mfp.tim_ct_cd = (st_mfp.tim_ct_cd & 0xf0) | 0x6;
|
||||||
|
|
||||||
|
/* request timer D dispatch handler */
|
||||||
|
if (request_irq(IRQ_MFP_TIMD, mfptimer_handler, IRQF_SHARED,
|
||||||
|
stmfp_base.name, &stmfp_base))
|
||||||
|
pr_err("Couldn't register %s interrupt\n", stmfp_base.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,6 +94,15 @@
|
|||||||
#define IRQ_SCCA_RX (52)
|
#define IRQ_SCCA_RX (52)
|
||||||
#define IRQ_SCCA_SPCOND (54)
|
#define IRQ_SCCA_SPCOND (54)
|
||||||
|
|
||||||
|
/* shared MFP timer D interrupts - hires timer for EtherNEC et al. */
|
||||||
|
#define IRQ_MFP_TIMER1 (64)
|
||||||
|
#define IRQ_MFP_TIMER2 (65)
|
||||||
|
#define IRQ_MFP_TIMER3 (66)
|
||||||
|
#define IRQ_MFP_TIMER4 (67)
|
||||||
|
#define IRQ_MFP_TIMER5 (68)
|
||||||
|
#define IRQ_MFP_TIMER6 (69)
|
||||||
|
#define IRQ_MFP_TIMER7 (70)
|
||||||
|
#define IRQ_MFP_TIMER8 (71)
|
||||||
|
|
||||||
#define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */
|
#define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */
|
||||||
#define INT_TICKS 246 /* to make sched_time = 99.902... HZ */
|
#define INT_TICKS 246 /* to make sched_time = 99.902... HZ */
|
||||||
|
Loading…
Reference in New Issue
Block a user