Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1ae432c authored by Michael Schmitz's avatar Michael Schmitz Committed by Geert Uytterhoeven
Browse files

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: default avatarMichael Schmitz <schmitz@debian.org>
Signed-off-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
parent 84b16b7b
Loading
Loading
Loading
Loading
+70 −0
Original line number Diff line number Diff line
@@ -121,6 +121,62 @@ static struct irq_chip atari_irq_chip = {
	.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)
 *
@@ -198,6 +254,20 @@ void __init atari_init_IRQ(void)
	/* Initialize the PSG: all sounds off, both ports output */
	sound_ym.rd_data_reg_sel = 7;
	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);
}


+9 −0
Original line number Diff line number Diff line
@@ -94,6 +94,15 @@
#define IRQ_SCCA_RX	     (52)
#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_TICKS 246	    /* to make sched_time = 99.902... HZ */