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