18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * arch/m68k/atari/ataints.c -- Atari Linux interrupt handling code
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * 5/2/94 Roman Hodek:
58c2ecf20Sopenharmony_ci *  Added support for TT interrupts; setup for TT SCU (may someone has
68c2ecf20Sopenharmony_ci *  twiddled there and we won't get the right interrupts :-()
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci *  Major change: The device-independent code in m68k/ints.c didn't know
98c2ecf20Sopenharmony_ci *  about non-autovec ints yet. It hardcoded the number of possible ints to
108c2ecf20Sopenharmony_ci *  7 (IRQ1...IRQ7). But the Atari has lots of non-autovec ints! I made the
118c2ecf20Sopenharmony_ci *  number of possible ints a constant defined in interrupt.h, which is
128c2ecf20Sopenharmony_ci *  47 for the Atari. So we can call request_irq() for all Atari interrupts
138c2ecf20Sopenharmony_ci *  just the normal way. Additionally, all vectors >= 48 are initialized to
148c2ecf20Sopenharmony_ci *  call trap() instead of inthandler(). This must be changed here, too.
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci * 1995-07-16 Lars Brinkhoff <f93labr@dd.chalmers.se>:
178c2ecf20Sopenharmony_ci *  Corrected a bug in atari_add_isr() which rejected all SCC
188c2ecf20Sopenharmony_ci *  interrupt sources if there were no TT MFP!
198c2ecf20Sopenharmony_ci *
208c2ecf20Sopenharmony_ci * 12/13/95: New interface functions atari_level_triggered_int() and
218c2ecf20Sopenharmony_ci *  atari_register_vme_int() as support for level triggered VME interrupts.
228c2ecf20Sopenharmony_ci *
238c2ecf20Sopenharmony_ci * 02/12/96: (Roman)
248c2ecf20Sopenharmony_ci *  Total rewrite of Atari interrupt handling, for new scheme see comments
258c2ecf20Sopenharmony_ci *  below.
268c2ecf20Sopenharmony_ci *
278c2ecf20Sopenharmony_ci * 1996-09-03 lars brinkhoff <f93labr@dd.chalmers.se>:
288c2ecf20Sopenharmony_ci *  Added new function atari_unregister_vme_int(), and
298c2ecf20Sopenharmony_ci *  modified atari_register_vme_int() as well as IS_VALID_INTNO()
308c2ecf20Sopenharmony_ci *  to work with it.
318c2ecf20Sopenharmony_ci *
328c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
338c2ecf20Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
348c2ecf20Sopenharmony_ci * for more details.
358c2ecf20Sopenharmony_ci *
368c2ecf20Sopenharmony_ci */
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#include <linux/types.h>
398c2ecf20Sopenharmony_ci#include <linux/kernel.h>
408c2ecf20Sopenharmony_ci#include <linux/kernel_stat.h>
418c2ecf20Sopenharmony_ci#include <linux/init.h>
428c2ecf20Sopenharmony_ci#include <linux/seq_file.h>
438c2ecf20Sopenharmony_ci#include <linux/module.h>
448c2ecf20Sopenharmony_ci#include <linux/irq.h>
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#include <asm/traps.h>
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci#include <asm/atarihw.h>
498c2ecf20Sopenharmony_ci#include <asm/atariints.h>
508c2ecf20Sopenharmony_ci#include <asm/atari_stdma.h>
518c2ecf20Sopenharmony_ci#include <asm/irq.h>
528c2ecf20Sopenharmony_ci#include <asm/entry.h>
538c2ecf20Sopenharmony_ci#include <asm/io.h>
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci/*
578c2ecf20Sopenharmony_ci * Atari interrupt handling scheme:
588c2ecf20Sopenharmony_ci * --------------------------------
598c2ecf20Sopenharmony_ci *
608c2ecf20Sopenharmony_ci * All interrupt source have an internal number (defined in
618c2ecf20Sopenharmony_ci * <asm/atariints.h>): Autovector interrupts are 1..7, then follow ST-MFP,
628c2ecf20Sopenharmony_ci * TT-MFP, SCC, and finally VME interrupts. Vector numbers for the latter can
638c2ecf20Sopenharmony_ci * be allocated by atari_register_vme_int().
648c2ecf20Sopenharmony_ci */
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci/*
678c2ecf20Sopenharmony_ci * Bitmap for free interrupt vector numbers
688c2ecf20Sopenharmony_ci * (new vectors starting from 0x70 can be allocated by
698c2ecf20Sopenharmony_ci * atari_register_vme_int())
708c2ecf20Sopenharmony_ci */
718c2ecf20Sopenharmony_cistatic int free_vme_vec_bitmap;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci/* GK:
748c2ecf20Sopenharmony_ci * HBL IRQ handler for Falcon. Nobody needs it :-)
758c2ecf20Sopenharmony_ci * ++andreas: raise ipl to disable further HBLANK interrupts.
768c2ecf20Sopenharmony_ci */
778c2ecf20Sopenharmony_ciasmlinkage void falcon_hblhandler(void);
788c2ecf20Sopenharmony_ciasm(".text\n"
798c2ecf20Sopenharmony_ci__ALIGN_STR "\n\t"
808c2ecf20Sopenharmony_ci"falcon_hblhandler:\n\t"
818c2ecf20Sopenharmony_ci	"orw	#0x200,%sp@\n\t"	/* set saved ipl to 2 */
828c2ecf20Sopenharmony_ci	"rte");
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ciextern void atari_microwire_cmd(int cmd);
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_cistatic unsigned int atari_irq_startup(struct irq_data *data)
878c2ecf20Sopenharmony_ci{
888c2ecf20Sopenharmony_ci	unsigned int irq = data->irq;
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	m68k_irq_startup(data);
918c2ecf20Sopenharmony_ci	atari_turnon_irq(irq);
928c2ecf20Sopenharmony_ci	atari_enable_irq(irq);
938c2ecf20Sopenharmony_ci	return 0;
948c2ecf20Sopenharmony_ci}
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_cistatic void atari_irq_shutdown(struct irq_data *data)
978c2ecf20Sopenharmony_ci{
988c2ecf20Sopenharmony_ci	unsigned int irq = data->irq;
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	atari_disable_irq(irq);
1018c2ecf20Sopenharmony_ci	atari_turnoff_irq(irq);
1028c2ecf20Sopenharmony_ci	m68k_irq_shutdown(data);
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci	if (irq == IRQ_AUTO_4)
1058c2ecf20Sopenharmony_ci	    vectors[VEC_INT4] = falcon_hblhandler;
1068c2ecf20Sopenharmony_ci}
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_cistatic void atari_irq_enable(struct irq_data *data)
1098c2ecf20Sopenharmony_ci{
1108c2ecf20Sopenharmony_ci	atari_enable_irq(data->irq);
1118c2ecf20Sopenharmony_ci}
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_cistatic void atari_irq_disable(struct irq_data *data)
1148c2ecf20Sopenharmony_ci{
1158c2ecf20Sopenharmony_ci	atari_disable_irq(data->irq);
1168c2ecf20Sopenharmony_ci}
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_cistatic struct irq_chip atari_irq_chip = {
1198c2ecf20Sopenharmony_ci	.name		= "atari",
1208c2ecf20Sopenharmony_ci	.irq_startup	= atari_irq_startup,
1218c2ecf20Sopenharmony_ci	.irq_shutdown	= atari_irq_shutdown,
1228c2ecf20Sopenharmony_ci	.irq_enable	= atari_irq_enable,
1238c2ecf20Sopenharmony_ci	.irq_disable	= atari_irq_disable,
1248c2ecf20Sopenharmony_ci};
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci/*
1278c2ecf20Sopenharmony_ci * ST-MFP timer D chained interrupts - each driver gets its own timer
1288c2ecf20Sopenharmony_ci * interrupt instance.
1298c2ecf20Sopenharmony_ci */
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_cistruct mfptimerbase {
1328c2ecf20Sopenharmony_ci	volatile struct MFP *mfp;
1338c2ecf20Sopenharmony_ci	unsigned char mfp_mask, mfp_data;
1348c2ecf20Sopenharmony_ci	unsigned short int_mask;
1358c2ecf20Sopenharmony_ci	int handler_irq, mfptimer_irq, server_irq;
1368c2ecf20Sopenharmony_ci	char *name;
1378c2ecf20Sopenharmony_ci} stmfp_base = {
1388c2ecf20Sopenharmony_ci	.mfp		= &st_mfp,
1398c2ecf20Sopenharmony_ci	.int_mask	= 0x0,
1408c2ecf20Sopenharmony_ci	.handler_irq	= IRQ_MFP_TIMD,
1418c2ecf20Sopenharmony_ci	.mfptimer_irq	= IRQ_MFP_TIMER1,
1428c2ecf20Sopenharmony_ci	.name		= "MFP Timer D"
1438c2ecf20Sopenharmony_ci};
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_cistatic irqreturn_t mfp_timer_d_handler(int irq, void *dev_id)
1468c2ecf20Sopenharmony_ci{
1478c2ecf20Sopenharmony_ci	struct mfptimerbase *base = dev_id;
1488c2ecf20Sopenharmony_ci	int mach_irq;
1498c2ecf20Sopenharmony_ci	unsigned char ints;
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci	mach_irq = base->mfptimer_irq;
1528c2ecf20Sopenharmony_ci	ints = base->int_mask;
1538c2ecf20Sopenharmony_ci	for (; ints; mach_irq++, ints >>= 1) {
1548c2ecf20Sopenharmony_ci		if (ints & 1)
1558c2ecf20Sopenharmony_ci			generic_handle_irq(mach_irq);
1568c2ecf20Sopenharmony_ci	}
1578c2ecf20Sopenharmony_ci	return IRQ_HANDLED;
1588c2ecf20Sopenharmony_ci}
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_cistatic void atari_mfptimer_enable(struct irq_data *data)
1628c2ecf20Sopenharmony_ci{
1638c2ecf20Sopenharmony_ci	int mfp_num = data->irq - IRQ_MFP_TIMER1;
1648c2ecf20Sopenharmony_ci	stmfp_base.int_mask |= 1 << mfp_num;
1658c2ecf20Sopenharmony_ci	atari_enable_irq(IRQ_MFP_TIMD);
1668c2ecf20Sopenharmony_ci}
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_cistatic void atari_mfptimer_disable(struct irq_data *data)
1698c2ecf20Sopenharmony_ci{
1708c2ecf20Sopenharmony_ci	int mfp_num = data->irq - IRQ_MFP_TIMER1;
1718c2ecf20Sopenharmony_ci	stmfp_base.int_mask &= ~(1 << mfp_num);
1728c2ecf20Sopenharmony_ci	if (!stmfp_base.int_mask)
1738c2ecf20Sopenharmony_ci		atari_disable_irq(IRQ_MFP_TIMD);
1748c2ecf20Sopenharmony_ci}
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_cistatic struct irq_chip atari_mfptimer_chip = {
1778c2ecf20Sopenharmony_ci	.name		= "timer_d",
1788c2ecf20Sopenharmony_ci	.irq_enable	= atari_mfptimer_enable,
1798c2ecf20Sopenharmony_ci	.irq_disable	= atari_mfptimer_disable,
1808c2ecf20Sopenharmony_ci};
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci/*
1848c2ecf20Sopenharmony_ci * EtherNAT CPLD interrupt handling
1858c2ecf20Sopenharmony_ci * CPLD interrupt register is at phys. 0x80000023
1868c2ecf20Sopenharmony_ci * Need this mapped in at interrupt startup time
1878c2ecf20Sopenharmony_ci * Possibly need this mapped on demand anyway -
1888c2ecf20Sopenharmony_ci * EtherNAT USB driver needs to disable IRQ before
1898c2ecf20Sopenharmony_ci * startup!
1908c2ecf20Sopenharmony_ci */
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_cistatic unsigned char *enat_cpld;
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_cistatic unsigned int atari_ethernat_startup(struct irq_data *data)
1958c2ecf20Sopenharmony_ci{
1968c2ecf20Sopenharmony_ci	int enat_num = 140 - data->irq + 1;
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	m68k_irq_startup(data);
1998c2ecf20Sopenharmony_ci	/*
2008c2ecf20Sopenharmony_ci	* map CPLD interrupt register
2018c2ecf20Sopenharmony_ci	*/
2028c2ecf20Sopenharmony_ci	if (!enat_cpld)
2038c2ecf20Sopenharmony_ci		enat_cpld = (unsigned char *)ioremap((ATARI_ETHERNAT_PHYS_ADDR+0x23), 0x2);
2048c2ecf20Sopenharmony_ci	/*
2058c2ecf20Sopenharmony_ci	 * do _not_ enable the USB chip interrupt here - causes interrupt storm
2068c2ecf20Sopenharmony_ci	 * and triggers dead interrupt watchdog
2078c2ecf20Sopenharmony_ci	 * Need to reset the USB chip to a sane state in early startup before
2088c2ecf20Sopenharmony_ci	 * removing this hack
2098c2ecf20Sopenharmony_ci	 */
2108c2ecf20Sopenharmony_ci	if (enat_num == 1)
2118c2ecf20Sopenharmony_ci		*enat_cpld |= 1 << enat_num;
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci	return 0;
2148c2ecf20Sopenharmony_ci}
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_cistatic void atari_ethernat_enable(struct irq_data *data)
2178c2ecf20Sopenharmony_ci{
2188c2ecf20Sopenharmony_ci	int enat_num = 140 - data->irq + 1;
2198c2ecf20Sopenharmony_ci	/*
2208c2ecf20Sopenharmony_ci	* map CPLD interrupt register
2218c2ecf20Sopenharmony_ci	*/
2228c2ecf20Sopenharmony_ci	if (!enat_cpld)
2238c2ecf20Sopenharmony_ci		enat_cpld = (unsigned char *)ioremap((ATARI_ETHERNAT_PHYS_ADDR+0x23), 0x2);
2248c2ecf20Sopenharmony_ci	*enat_cpld |= 1 << enat_num;
2258c2ecf20Sopenharmony_ci}
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_cistatic void atari_ethernat_disable(struct irq_data *data)
2288c2ecf20Sopenharmony_ci{
2298c2ecf20Sopenharmony_ci	int enat_num = 140 - data->irq + 1;
2308c2ecf20Sopenharmony_ci	/*
2318c2ecf20Sopenharmony_ci	* map CPLD interrupt register
2328c2ecf20Sopenharmony_ci	*/
2338c2ecf20Sopenharmony_ci	if (!enat_cpld)
2348c2ecf20Sopenharmony_ci		enat_cpld = (unsigned char *)ioremap((ATARI_ETHERNAT_PHYS_ADDR+0x23), 0x2);
2358c2ecf20Sopenharmony_ci	*enat_cpld &= ~(1 << enat_num);
2368c2ecf20Sopenharmony_ci}
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_cistatic void atari_ethernat_shutdown(struct irq_data *data)
2398c2ecf20Sopenharmony_ci{
2408c2ecf20Sopenharmony_ci	int enat_num = 140 - data->irq + 1;
2418c2ecf20Sopenharmony_ci	if (enat_cpld) {
2428c2ecf20Sopenharmony_ci		*enat_cpld &= ~(1 << enat_num);
2438c2ecf20Sopenharmony_ci		iounmap(enat_cpld);
2448c2ecf20Sopenharmony_ci		enat_cpld = NULL;
2458c2ecf20Sopenharmony_ci	}
2468c2ecf20Sopenharmony_ci}
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_cistatic struct irq_chip atari_ethernat_chip = {
2498c2ecf20Sopenharmony_ci	.name		= "ethernat",
2508c2ecf20Sopenharmony_ci	.irq_startup	= atari_ethernat_startup,
2518c2ecf20Sopenharmony_ci	.irq_shutdown	= atari_ethernat_shutdown,
2528c2ecf20Sopenharmony_ci	.irq_enable	= atari_ethernat_enable,
2538c2ecf20Sopenharmony_ci	.irq_disable	= atari_ethernat_disable,
2548c2ecf20Sopenharmony_ci};
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci/*
2578c2ecf20Sopenharmony_ci * void atari_init_IRQ (void)
2588c2ecf20Sopenharmony_ci *
2598c2ecf20Sopenharmony_ci * Parameters:	None
2608c2ecf20Sopenharmony_ci *
2618c2ecf20Sopenharmony_ci * Returns:	Nothing
2628c2ecf20Sopenharmony_ci *
2638c2ecf20Sopenharmony_ci * This function should be called during kernel startup to initialize
2648c2ecf20Sopenharmony_ci * the atari IRQ handling routines.
2658c2ecf20Sopenharmony_ci */
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_civoid __init atari_init_IRQ(void)
2688c2ecf20Sopenharmony_ci{
2698c2ecf20Sopenharmony_ci	m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER);
2708c2ecf20Sopenharmony_ci	m68k_setup_irq_controller(&atari_irq_chip, handle_simple_irq, 1,
2718c2ecf20Sopenharmony_ci				  NUM_ATARI_SOURCES - 1);
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci	/* Initialize the MFP(s) */
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci#ifdef ATARI_USE_SOFTWARE_EOI
2768c2ecf20Sopenharmony_ci	st_mfp.vec_adr  = 0x48;	/* Software EOI-Mode */
2778c2ecf20Sopenharmony_ci#else
2788c2ecf20Sopenharmony_ci	st_mfp.vec_adr  = 0x40;	/* Automatic EOI-Mode */
2798c2ecf20Sopenharmony_ci#endif
2808c2ecf20Sopenharmony_ci	st_mfp.int_en_a = 0x00;	/* turn off MFP-Ints */
2818c2ecf20Sopenharmony_ci	st_mfp.int_en_b = 0x00;
2828c2ecf20Sopenharmony_ci	st_mfp.int_mk_a = 0xff;	/* no Masking */
2838c2ecf20Sopenharmony_ci	st_mfp.int_mk_b = 0xff;
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_ci	if (ATARIHW_PRESENT(TT_MFP)) {
2868c2ecf20Sopenharmony_ci#ifdef ATARI_USE_SOFTWARE_EOI
2878c2ecf20Sopenharmony_ci		tt_mfp.vec_adr  = 0x58;		/* Software EOI-Mode */
2888c2ecf20Sopenharmony_ci#else
2898c2ecf20Sopenharmony_ci		tt_mfp.vec_adr  = 0x50;		/* Automatic EOI-Mode */
2908c2ecf20Sopenharmony_ci#endif
2918c2ecf20Sopenharmony_ci		tt_mfp.int_en_a = 0x00;		/* turn off MFP-Ints */
2928c2ecf20Sopenharmony_ci		tt_mfp.int_en_b = 0x00;
2938c2ecf20Sopenharmony_ci		tt_mfp.int_mk_a = 0xff;		/* no Masking */
2948c2ecf20Sopenharmony_ci		tt_mfp.int_mk_b = 0xff;
2958c2ecf20Sopenharmony_ci	}
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_ci	if (ATARIHW_PRESENT(SCC) && !atari_SCC_reset_done) {
2988c2ecf20Sopenharmony_ci		atari_scc.cha_a_ctrl = 9;
2998c2ecf20Sopenharmony_ci		MFPDELAY();
3008c2ecf20Sopenharmony_ci		atari_scc.cha_a_ctrl = (char) 0xc0; /* hardware reset */
3018c2ecf20Sopenharmony_ci	}
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	if (ATARIHW_PRESENT(SCU)) {
3048c2ecf20Sopenharmony_ci		/* init the SCU if present */
3058c2ecf20Sopenharmony_ci		tt_scu.sys_mask = 0x10;		/* enable VBL (for the cursor) and
3068c2ecf20Sopenharmony_ci									 * disable HSYNC interrupts (who
3078c2ecf20Sopenharmony_ci									 * needs them?)  MFP and SCC are
3088c2ecf20Sopenharmony_ci									 * enabled in VME mask
3098c2ecf20Sopenharmony_ci									 */
3108c2ecf20Sopenharmony_ci		tt_scu.vme_mask = 0x60;		/* enable MFP and SCC ints */
3118c2ecf20Sopenharmony_ci	} else {
3128c2ecf20Sopenharmony_ci		/* If no SCU and no Hades, the HSYNC interrupt needs to be
3138c2ecf20Sopenharmony_ci		 * disabled this way. (Else _inthandler in kernel/sys_call.S
3148c2ecf20Sopenharmony_ci		 * gets overruns)
3158c2ecf20Sopenharmony_ci		 */
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ci		vectors[VEC_INT2] = falcon_hblhandler;
3188c2ecf20Sopenharmony_ci		vectors[VEC_INT4] = falcon_hblhandler;
3198c2ecf20Sopenharmony_ci	}
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci	if (ATARIHW_PRESENT(PCM_8BIT) && ATARIHW_PRESENT(MICROWIRE)) {
3228c2ecf20Sopenharmony_ci		/* Initialize the LM1992 Sound Controller to enable
3238c2ecf20Sopenharmony_ci		   the PSG sound.  This is misplaced here, it should
3248c2ecf20Sopenharmony_ci		   be in an atasound_init(), that doesn't exist yet. */
3258c2ecf20Sopenharmony_ci		atari_microwire_cmd(MW_LM1992_PSG_HIGH);
3268c2ecf20Sopenharmony_ci	}
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_ci	stdma_init();
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci	/* Initialize the PSG: all sounds off, both ports output */
3318c2ecf20Sopenharmony_ci	sound_ym.rd_data_reg_sel = 7;
3328c2ecf20Sopenharmony_ci	sound_ym.wd_data = 0xff;
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci	m68k_setup_irq_controller(&atari_mfptimer_chip, handle_simple_irq,
3358c2ecf20Sopenharmony_ci				  IRQ_MFP_TIMER1, 8);
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_ci	irq_set_status_flags(IRQ_MFP_TIMER1, IRQ_IS_POLLED);
3388c2ecf20Sopenharmony_ci	irq_set_status_flags(IRQ_MFP_TIMER2, IRQ_IS_POLLED);
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci	/* prepare timer D data for use as poll interrupt */
3418c2ecf20Sopenharmony_ci	/* set Timer D data Register - needs to be > 0 */
3428c2ecf20Sopenharmony_ci	st_mfp.tim_dt_d = 254;	/* < 100 Hz */
3438c2ecf20Sopenharmony_ci	/* start timer D, div = 1:100 */
3448c2ecf20Sopenharmony_ci	st_mfp.tim_ct_cd = (st_mfp.tim_ct_cd & 0xf0) | 0x6;
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_ci	/* request timer D dispatch handler */
3478c2ecf20Sopenharmony_ci	if (request_irq(IRQ_MFP_TIMD, mfp_timer_d_handler, IRQF_SHARED,
3488c2ecf20Sopenharmony_ci			stmfp_base.name, &stmfp_base))
3498c2ecf20Sopenharmony_ci		pr_err("Couldn't register %s interrupt\n", stmfp_base.name);
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci	/*
3528c2ecf20Sopenharmony_ci	 * EtherNAT ethernet / USB interrupt handlers
3538c2ecf20Sopenharmony_ci	 */
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_ci	m68k_setup_irq_controller(&atari_ethernat_chip, handle_simple_irq,
3568c2ecf20Sopenharmony_ci				  139, 2);
3578c2ecf20Sopenharmony_ci}
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ci/*
3618c2ecf20Sopenharmony_ci * atari_register_vme_int() returns the number of a free interrupt vector for
3628c2ecf20Sopenharmony_ci * hardware with a programmable int vector (probably a VME board).
3638c2ecf20Sopenharmony_ci */
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ciunsigned int atari_register_vme_int(void)
3668c2ecf20Sopenharmony_ci{
3678c2ecf20Sopenharmony_ci	int i;
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_ci	for (i = 0; i < 32; i++)
3708c2ecf20Sopenharmony_ci		if ((free_vme_vec_bitmap & (1 << i)) == 0)
3718c2ecf20Sopenharmony_ci			break;
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci	if (i == 16)
3748c2ecf20Sopenharmony_ci		return 0;
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci	free_vme_vec_bitmap |= 1 << i;
3778c2ecf20Sopenharmony_ci	return VME_SOURCE_BASE + i;
3788c2ecf20Sopenharmony_ci}
3798c2ecf20Sopenharmony_ciEXPORT_SYMBOL(atari_register_vme_int);
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_civoid atari_unregister_vme_int(unsigned int irq)
3838c2ecf20Sopenharmony_ci{
3848c2ecf20Sopenharmony_ci	if (irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) {
3858c2ecf20Sopenharmony_ci		irq -= VME_SOURCE_BASE;
3868c2ecf20Sopenharmony_ci		free_vme_vec_bitmap &= ~(1 << irq);
3878c2ecf20Sopenharmony_ci	}
3888c2ecf20Sopenharmony_ci}
3898c2ecf20Sopenharmony_ciEXPORT_SYMBOL(atari_unregister_vme_int);
3908c2ecf20Sopenharmony_ci
3918c2ecf20Sopenharmony_ci
392