diff options
author | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
---|---|---|
committer | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
commit | 871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch) | |
tree | 8718f573808810c2a1e8cb8fb6ac469093ca2784 /ANDROID_3.4.5/arch/m68k/q40 | |
parent | 9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff) | |
download | FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2 FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip |
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized.
Changes are basically to make it look like kernel structure.
Diffstat (limited to 'ANDROID_3.4.5/arch/m68k/q40')
-rw-r--r-- | ANDROID_3.4.5/arch/m68k/q40/Makefile | 5 | ||||
-rw-r--r-- | ANDROID_3.4.5/arch/m68k/q40/README | 138 | ||||
-rw-r--r-- | ANDROID_3.4.5/arch/m68k/q40/config.c | 346 | ||||
-rw-r--r-- | ANDROID_3.4.5/arch/m68k/q40/q40ints.c | 326 |
4 files changed, 0 insertions, 815 deletions
diff --git a/ANDROID_3.4.5/arch/m68k/q40/Makefile b/ANDROID_3.4.5/arch/m68k/q40/Makefile deleted file mode 100644 index 27eb4279..00000000 --- a/ANDROID_3.4.5/arch/m68k/q40/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for Linux arch/m68k/q40 source directory -# - -obj-y := config.o q40ints.o diff --git a/ANDROID_3.4.5/arch/m68k/q40/README b/ANDROID_3.4.5/arch/m68k/q40/README deleted file mode 100644 index 93f4c4cd..00000000 --- a/ANDROID_3.4.5/arch/m68k/q40/README +++ /dev/null @@ -1,138 +0,0 @@ -Linux for the Q40 -================= - -You may try http://www.geocities.com/SiliconValley/Bay/2602/ for -some up to date information. Booter and other tools will be also -available from this place or http://ftp.uni-erlangen.de/pub/unix/Linux/680x0/q40/ -and mirrors. - -Hints to documentation usually refer to the linux source tree in -/usr/src/linux/Documentation unless URL given. - -It seems IRQ unmasking can't be safely done on a Q40. IRQ probing -is not implemented - do not try it! (See below) - -For a list of kernel command-line options read the documentation for the -particular device drivers. - -The floppy imposes a very high interrupt load on the CPU, approx 30K/s. -When something blocks interrupts (HD) it will lose some of them, so far -this is not known to have caused any data loss. On highly loaded systems -it can make the floppy very slow or practically stop. Other Q40 OS' simply -poll the floppy for this reason - something that can't be done in Linux. -Only possible cure is getting a 82072 controller with fifo instead of -the 8272A. - -drivers used by the Q40, apart from the very obvious (console etc.): - drivers/char/q40_keyb.c # use PC keymaps for national keyboards - serial.c # normal PC driver - any speed - lp.c # printer driver - genrtc.c # RTC - char/joystick/* # most of this should work, not - # in default config.in - block/q40ide.c # startup for ide - ide* # see Documentation/ide/ide.txt - floppy.c # normal PC driver, DMA emu in asm/floppy.h - # and arch/m68k/kernel/entry.S - # see drivers/block/README.fd - net/ne.c - video/q40fb.c - parport/* - sound/dmasound_core.c - dmasound_q40.c - -Various other PC drivers can be enabled simply by adding them to -arch/m68k/config.in, especially 8 bit devices should be without any -problems. For cards using 16bit io/mem more care is required, like -checking byte order issues, hacking memcpy_*_io etc. - - -Debugging -========= - -Upon startup the kernel will usually output "ABCQGHIJ" into the SRAM, -preceded by the booter signature. This is a trace just in case something -went wrong during earliest setup stages of head.S. -**Changed** to preserve SRAM contents by default, this is only done when -requested - SRAM must start with '%LX$' signature to do this. '-d' option -to 'lxx' loader enables this. - -SRAM can also be used as additional console device, use debug=mem. -This will save kernel startup msgs into SRAM, the screen will display -only the penguin - and shell prompt if it gets that far.. -Unfortunately only 2000 bytes are available. - -Serial console works and can also be used for debugging, see loader_txt - -Most problems seem to be caused by fawlty or badly configured io-cards or -hard drives anyway. -Make sure to configure the parallel port as SPP and remove IRQ/DMA jumpers -for first testing. The Q40 does not support DMA and may have trouble with -parallel ports version of interrupts. - - -Q40 Hardware Description -======================== - -This is just an overview, see asm-m68k/* for details ask if you have any -questions. - -The Q40 consists of a 68040@40 MHz, 1MB video RAM, up to 32MB RAM, AT-style -keyboard interface, 1 Programmable LED, 2x8bit DACs and up to 1MB ROM, 1MB -shadow ROM. -The Q60 has any of 68060 or 68LC060 and up to 128 MB RAM. - -Most interfacing like floppy, IDE, serial and parallel ports is done via ISA -slots. The ISA io and mem range is mapped (sparse&byteswapped!) into separate -regions of the memory. -The main interrupt register IIRQ_REG will indicate whether an IRQ was internal -or from some ISA devices, EIRQ_REG can distinguish up to 8 ISA IRQs. - -The Q40 custom chip is programmable to provide 2 periodic timers: - - 50 or 200 Hz - level 2, !!THIS CAN'T BE DISABLED!! - - 10 or 20 KHz - level 4, used for dma-sound - -Linux uses the 200 Hz interrupt for timer and beep by default. - - -Interrupts -========== - -q40 master chip handles only a subset of level triggered interrupts. - -Linux has some requirements wrt interrupt architecture, these are -to my knowledge: - (a) interrupt handler must not be reentered even when sti() is called - from within handler - (b) working enable/disable_irq - -Luckily these requirements are only important for drivers shared -with other architectures - ide,serial,parallel, ethernet. -q40ints.c now contains a trivial hack for (a), (b) is more difficult -because only irq's 4-15 can be disabled - and only all of them at once. -Thus disable_irq() can effectively block the machine if the driver goes -asleep. -One thing to keep in mind when hacking around the interrupt code is -that there is no way to find out which IRQ caused a request, [EI]IRQ_REG -displays current state of the various IRQ lines. - -Keyboard -======== - -q40 receives AT make/break codes from the keyboard, these are translated to -the PC scancodes x86 Linux uses. So by theory every national keyboard should -work just by loading the appropriate x86 keytable - see any national-HOWTO. - -Unfortunately the AT->PC translation isn't quite trivial and even worse, my -documentation of it is absolutely minimal - thus some exotic keys may not -behave exactly as expected. - -There is still hope that it can be fixed completely though. If you encounter -problems, email me ideally this: - - exact keypress/release sequence - - 'showkey -s' run on q40, non-X session - - 'showkey -s' run on a PC, non-X session - - AT codes as displayed by the q40 debugging ROM -btw if the showkey output from PC and Q40 doesn't differ then you have some -classic configuration problem - don't send me anything in this case - diff --git a/ANDROID_3.4.5/arch/m68k/q40/config.c b/ANDROID_3.4.5/arch/m68k/q40/config.c deleted file mode 100644 index 8a1ce327..00000000 --- a/ANDROID_3.4.5/arch/m68k/q40/config.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * arch/m68k/q40/config.c - * - * Copyright (C) 1999 Richard Zidlicky - * - * originally based on: - * - * linux/bvme/config.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive - * for more details. - */ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/tty.h> -#include <linux/console.h> -#include <linux/linkage.h> -#include <linux/init.h> -#include <linux/major.h> -#include <linux/serial_reg.h> -#include <linux/rtc.h> -#include <linux/vt_kern.h> -#include <linux/bcd.h> -#include <linux/platform_device.h> - -#include <asm/io.h> -#include <asm/rtc.h> -#include <asm/bootinfo.h> -#include <asm/pgtable.h> -#include <asm/setup.h> -#include <asm/irq.h> -#include <asm/traps.h> -#include <asm/machdep.h> -#include <asm/q40_master.h> - -extern void q40_init_IRQ(void); -static void q40_get_model(char *model); -extern void q40_sched_init(irq_handler_t handler); - -static unsigned long q40_gettimeoffset(void); -static int q40_hwclk(int, struct rtc_time *); -static unsigned int q40_get_ss(void); -static int q40_set_clock_mmss(unsigned long); -static int q40_get_rtc_pll(struct rtc_pll_info *pll); -static int q40_set_rtc_pll(struct rtc_pll_info *pll); - -extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/); - -static void q40_mem_console_write(struct console *co, const char *b, - unsigned int count); - -extern int ql_ticks; - -static struct console q40_console_driver = { - .name = "debug", - .write = q40_mem_console_write, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - - -/* early debugging function:*/ -extern char *q40_mem_cptr; /*=(char *)0xff020000;*/ -static int _cpleft; - -static void q40_mem_console_write(struct console *co, const char *s, - unsigned int count) -{ - const char *p = s; - - if (count < _cpleft) { - while (count-- > 0) { - *q40_mem_cptr = *p++; - q40_mem_cptr += 4; - _cpleft--; - } - } -} - -static int __init q40_debug_setup(char *arg) -{ - /* useful for early debugging stages - writes kernel messages into SRAM */ - if (MACH_IS_Q40 && !strncmp(arg, "mem", 3)) { - /*printk("using NVRAM debug, q40_mem_cptr=%p\n",q40_mem_cptr);*/ - _cpleft = 2000 - ((long)q40_mem_cptr-0xff020000) / 4; - register_console(&q40_console_driver); - } - return 0; -} - -early_param("debug", q40_debug_setup); - -#if 0 -void printq40(char *str) -{ - int l = strlen(str); - char *p = q40_mem_cptr; - - while (l-- > 0 && _cpleft-- > 0) { - *p = *str++; - p += 4; - } - q40_mem_cptr = p; -} -#endif - -static int halted; - -#ifdef CONFIG_HEARTBEAT -static void q40_heartbeat(int on) -{ - if (halted) - return; - - if (on) - Q40_LED_ON(); - else - Q40_LED_OFF(); -} -#endif - -static void q40_reset(void) -{ - halted = 1; - printk("\n\n*******************************************\n" - "Called q40_reset : press the RESET button!!\n" - "*******************************************\n"); - Q40_LED_ON(); - while (1) - ; -} - -static void q40_halt(void) -{ - halted = 1; - printk("\n\n*******************\n" - " Called q40_halt\n" - "*******************\n"); - Q40_LED_ON(); - while (1) - ; -} - -static void q40_get_model(char *model) -{ - sprintf(model, "Q40"); -} - -static unsigned int serports[] = -{ - 0x3f8,0x2f8,0x3e8,0x2e8,0 -}; - -static void q40_disable_irqs(void) -{ - unsigned i, j; - - j = 0; - while ((i = serports[j++])) - outb(0, i + UART_IER); - master_outb(0, EXT_ENABLE_REG); - master_outb(0, KEY_IRQ_ENABLE_REG); -} - -void __init config_q40(void) -{ - mach_sched_init = q40_sched_init; - - mach_init_IRQ = q40_init_IRQ; - mach_gettimeoffset = q40_gettimeoffset; - mach_hwclk = q40_hwclk; - mach_get_ss = q40_get_ss; - mach_get_rtc_pll = q40_get_rtc_pll; - mach_set_rtc_pll = q40_set_rtc_pll; - mach_set_clock_mmss = q40_set_clock_mmss; - - mach_reset = q40_reset; - mach_get_model = q40_get_model; - -#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) - mach_beep = q40_mksound; -#endif -#ifdef CONFIG_HEARTBEAT - mach_heartbeat = q40_heartbeat; -#endif - mach_halt = q40_halt; - - /* disable a few things that SMSQ might have left enabled */ - q40_disable_irqs(); - - /* no DMA at all, but ide-scsi requires it.. make sure - * all physical RAM fits into the boundary - otherwise - * allocator may play costly and useless tricks */ - mach_max_dma_address = 1024*1024*1024; -} - - -int q40_parse_bootinfo(const struct bi_record *rec) -{ - return 1; -} - - -static unsigned long q40_gettimeoffset(void) -{ - return 5000 * (ql_ticks != 0); -} - - -/* - * Looks like op is non-zero for setting the clock, and zero for - * reading the clock. - * - * struct hwclk_time { - * unsigned sec; 0..59 - * unsigned min; 0..59 - * unsigned hour; 0..23 - * unsigned day; 1..31 - * unsigned mon; 0..11 - * unsigned year; 00... - * int wday; 0..6, 0 is Sunday, -1 means unknown/don't set - * }; - */ - -static int q40_hwclk(int op, struct rtc_time *t) -{ - if (op) { - /* Write.... */ - Q40_RTC_CTRL |= Q40_RTC_WRITE; - - Q40_RTC_SECS = bin2bcd(t->tm_sec); - Q40_RTC_MINS = bin2bcd(t->tm_min); - Q40_RTC_HOUR = bin2bcd(t->tm_hour); - Q40_RTC_DATE = bin2bcd(t->tm_mday); - Q40_RTC_MNTH = bin2bcd(t->tm_mon + 1); - Q40_RTC_YEAR = bin2bcd(t->tm_year%100); - if (t->tm_wday >= 0) - Q40_RTC_DOW = bin2bcd(t->tm_wday+1); - - Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); - } else { - /* Read.... */ - Q40_RTC_CTRL |= Q40_RTC_READ; - - t->tm_year = bcd2bin (Q40_RTC_YEAR); - t->tm_mon = bcd2bin (Q40_RTC_MNTH)-1; - t->tm_mday = bcd2bin (Q40_RTC_DATE); - t->tm_hour = bcd2bin (Q40_RTC_HOUR); - t->tm_min = bcd2bin (Q40_RTC_MINS); - t->tm_sec = bcd2bin (Q40_RTC_SECS); - - Q40_RTC_CTRL &= ~(Q40_RTC_READ); - - if (t->tm_year < 70) - t->tm_year += 100; - t->tm_wday = bcd2bin(Q40_RTC_DOW)-1; - } - - return 0; -} - -static unsigned int q40_get_ss(void) -{ - return bcd2bin(Q40_RTC_SECS); -} - -/* - * Set the minutes and seconds from seconds value 'nowtime'. Fail if - * clock is out by > 30 minutes. Logic lifted from atari code. - */ - -static int q40_set_clock_mmss(unsigned long nowtime) -{ - int retval = 0; - short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; - - int rtc_minutes; - - rtc_minutes = bcd2bin(Q40_RTC_MINS); - - if ((rtc_minutes < real_minutes ? - real_minutes - rtc_minutes : - rtc_minutes - real_minutes) < 30) { - Q40_RTC_CTRL |= Q40_RTC_WRITE; - Q40_RTC_MINS = bin2bcd(real_minutes); - Q40_RTC_SECS = bin2bcd(real_seconds); - Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); - } else - retval = -1; - - return retval; -} - - -/* get and set PLL calibration of RTC clock */ -#define Q40_RTC_PLL_MASK ((1<<5)-1) -#define Q40_RTC_PLL_SIGN (1<<5) - -static int q40_get_rtc_pll(struct rtc_pll_info *pll) -{ - int tmp = Q40_RTC_CTRL; - - pll->pll_value = tmp & Q40_RTC_PLL_MASK; - if (tmp & Q40_RTC_PLL_SIGN) - pll->pll_value = -pll->pll_value; - pll->pll_max = 31; - pll->pll_min = -31; - pll->pll_posmult = 512; - pll->pll_negmult = 256; - pll->pll_clock = 125829120; - - return 0; -} - -static int q40_set_rtc_pll(struct rtc_pll_info *pll) -{ - if (!pll->pll_ctrl) { - /* the docs are a bit unclear so I am doublesetting */ - /* RTC_WRITE here ... */ - int tmp = (pll->pll_value & 31) | (pll->pll_value<0 ? 32 : 0) | - Q40_RTC_WRITE; - Q40_RTC_CTRL |= Q40_RTC_WRITE; - Q40_RTC_CTRL = tmp; - Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); - return 0; - } else - return -EINVAL; -} - -static __init int q40_add_kbd_device(void) -{ - struct platform_device *pdev; - - if (!MACH_IS_Q40) - return -ENODEV; - - pdev = platform_device_register_simple("q40kbd", -1, NULL, 0); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - - return 0; -} -arch_initcall(q40_add_kbd_device); diff --git a/ANDROID_3.4.5/arch/m68k/q40/q40ints.c b/ANDROID_3.4.5/arch/m68k/q40/q40ints.c deleted file mode 100644 index 513f9bb1..00000000 --- a/ANDROID_3.4.5/arch/m68k/q40/q40ints.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * arch/m68k/q40/q40ints.c - * - * Copyright (C) 1999,2001 Richard Zidlicky - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * - * .. used to be loosely based on bvme6000ints.c - * - */ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/irq.h> - -#include <asm/ptrace.h> -#include <asm/traps.h> - -#include <asm/q40_master.h> -#include <asm/q40ints.h> - -/* - * Q40 IRQs are defined as follows: - * 3,4,5,6,7,10,11,14,15 : ISA dev IRQs - * 16-31: reserved - * 32 : keyboard int - * 33 : frame int (50/200 Hz periodic timer) - * 34 : sample int (10/20 KHz periodic timer) - * -*/ - -static void q40_irq_handler(unsigned int, struct pt_regs *fp); -static void q40_irq_enable(struct irq_data *data); -static void q40_irq_disable(struct irq_data *data); - -unsigned short q40_ablecount[35]; -unsigned short q40_state[35]; - -static unsigned int q40_irq_startup(struct irq_data *data) -{ - unsigned int irq = data->irq; - - /* test for ISA ints not implemented by HW */ - switch (irq) { - case 1: case 2: case 8: case 9: - case 11: case 12: case 13: - printk("%s: ISA IRQ %d not implemented by HW\n", __func__, irq); - /* FIXME return -ENXIO; */ - } - return 0; -} - -static void q40_irq_shutdown(struct irq_data *data) -{ -} - -static struct irq_chip q40_irq_chip = { - .name = "q40", - .irq_startup = q40_irq_startup, - .irq_shutdown = q40_irq_shutdown, - .irq_enable = q40_irq_enable, - .irq_disable = q40_irq_disable, -}; - -/* - * void q40_init_IRQ (void) - * - * Parameters: None - * - * Returns: Nothing - * - * This function is called during kernel startup to initialize - * the q40 IRQ handling routines. - */ - -static int disabled; - -void __init q40_init_IRQ(void) -{ - m68k_setup_irq_controller(&q40_irq_chip, handle_simple_irq, 1, - Q40_IRQ_MAX); - - /* setup handler for ISA ints */ - m68k_setup_auto_interrupt(q40_irq_handler); - - m68k_irq_startup_irq(IRQ_AUTO_2); - m68k_irq_startup_irq(IRQ_AUTO_4); - - /* now enable some ints.. */ - master_outb(1, EXT_ENABLE_REG); /* ISA IRQ 5-15 */ - - /* make sure keyboard IRQ is disabled */ - master_outb(0, KEY_IRQ_ENABLE_REG); -} - - -/* - * this stuff doesn't really belong here.. - */ - -int ql_ticks; /* 200Hz ticks since last jiffie */ -static int sound_ticks; - -#define SVOL 45 - -void q40_mksound(unsigned int hz, unsigned int ticks) -{ - /* for now ignore hz, except that hz==0 switches off sound */ - /* simply alternate the ampl (128-SVOL)-(128+SVOL)-..-.. at 200Hz */ - if (hz == 0) { - if (sound_ticks) - sound_ticks = 1; - - *DAC_LEFT = 128; - *DAC_RIGHT = 128; - - return; - } - /* sound itself is done in q40_timer_int */ - if (sound_ticks == 0) - sound_ticks = 1000; /* pretty long beep */ - sound_ticks = ticks << 1; -} - -static irq_handler_t q40_timer_routine; - -static irqreturn_t q40_timer_int (int irq, void * dev) -{ - ql_ticks = ql_ticks ? 0 : 1; - if (sound_ticks) { - unsigned char sval=(sound_ticks & 1) ? 128-SVOL : 128+SVOL; - sound_ticks--; - *DAC_LEFT=sval; - *DAC_RIGHT=sval; - } - - if (!ql_ticks) - q40_timer_routine(irq, dev); - return IRQ_HANDLED; -} - -void q40_sched_init (irq_handler_t timer_routine) -{ - int timer_irq; - - q40_timer_routine = timer_routine; - timer_irq = Q40_IRQ_FRAME; - - if (request_irq(timer_irq, q40_timer_int, 0, - "timer", q40_timer_int)) - panic("Couldn't register timer int"); - - master_outb(-1, FRAME_CLEAR_REG); - master_outb( 1, FRAME_RATE_REG); -} - - -/* - * tables to translate bits into IRQ numbers - * it is a good idea to order the entries by priority - * -*/ - -struct IRQ_TABLE{ unsigned mask; int irq ;}; -#if 0 -static struct IRQ_TABLE iirqs[]={ - {Q40_IRQ_FRAME_MASK,Q40_IRQ_FRAME}, - {Q40_IRQ_KEYB_MASK,Q40_IRQ_KEYBOARD}, - {0,0}}; -#endif -static struct IRQ_TABLE eirqs[] = { - { .mask = Q40_IRQ3_MASK, .irq = 3 }, /* ser 1 */ - { .mask = Q40_IRQ4_MASK, .irq = 4 }, /* ser 2 */ - { .mask = Q40_IRQ14_MASK, .irq = 14 }, /* IDE 1 */ - { .mask = Q40_IRQ15_MASK, .irq = 15 }, /* IDE 2 */ - { .mask = Q40_IRQ6_MASK, .irq = 6 }, /* floppy, handled elsewhere */ - { .mask = Q40_IRQ7_MASK, .irq = 7 }, /* par */ - { .mask = Q40_IRQ5_MASK, .irq = 5 }, - { .mask = Q40_IRQ10_MASK, .irq = 10 }, - {0,0} -}; - -/* complain only this many times about spurious ints : */ -static int ccleirq=60; /* ISA dev IRQs*/ -/*static int cclirq=60;*/ /* internal */ - -/* FIXME: add shared ints,mask,unmask,probing.... */ - -#define IRQ_INPROGRESS 1 -/*static unsigned short saved_mask;*/ -//static int do_tint=0; - -#define DEBUG_Q40INT -/*#define IP_USE_DISABLE *//* would be nice, but crashes ???? */ - -static int mext_disabled=0; /* ext irq disabled by master chip? */ -static int aliased_irq=0; /* how many times inside handler ?*/ - - -/* got interrupt, dispatch to ISA or keyboard/timer IRQs */ -static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) -{ - unsigned mir, mer; - int i; - -//repeat: - mir = master_inb(IIRQ_REG); -#ifdef CONFIG_BLK_DEV_FD - if ((mir & Q40_IRQ_EXT_MASK) && - (master_inb(EIRQ_REG) & Q40_IRQ6_MASK)) { - floppy_hardint(); - return; - } -#endif - switch (irq) { - case 4: - case 6: - do_IRQ(Q40_IRQ_SAMPLE, fp); - return; - } - if (mir & Q40_IRQ_FRAME_MASK) { - do_IRQ(Q40_IRQ_FRAME, fp); - master_outb(-1, FRAME_CLEAR_REG); - } - if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) { - mer = master_inb(EIRQ_REG); - for (i = 0; eirqs[i].mask; i++) { - if (mer & eirqs[i].mask) { - irq = eirqs[i].irq; -/* - * There is a little mess wrt which IRQ really caused this irq request. The - * main problem is that IIRQ_REG and EIRQ_REG reflect the state when they - * are read - which is long after the request came in. In theory IRQs should - * not just go away but they occasionally do - */ - if (irq > 4 && irq <= 15 && mext_disabled) { - /*aliased_irq++;*/ - goto iirq; - } - if (q40_state[irq] & IRQ_INPROGRESS) { - /* some handlers do local_irq_enable() for irq latency reasons, */ - /* however reentering an active irq handler is not permitted */ -#ifdef IP_USE_DISABLE - /* in theory this is the better way to do it because it still */ - /* lets through eg the serial irqs, unfortunately it crashes */ - disable_irq(irq); - disabled = 1; -#else - /*printk("IRQ_INPROGRESS detected for irq %d, disabling - %s disabled\n", - irq, disabled ? "already" : "not yet"); */ - fp->sr = (((fp->sr) & (~0x700))+0x200); - disabled = 1; -#endif - goto iirq; - } - q40_state[irq] |= IRQ_INPROGRESS; - do_IRQ(irq, fp); - q40_state[irq] &= ~IRQ_INPROGRESS; - - /* naively enable everything, if that fails than */ - /* this function will be reentered immediately thus */ - /* getting another chance to disable the IRQ */ - - if (disabled) { -#ifdef IP_USE_DISABLE - if (irq > 4) { - disabled = 0; - enable_irq(irq); - } -#else - disabled = 0; - /*printk("reenabling irq %d\n", irq); */ -#endif - } -// used to do 'goto repeat;' here, this delayed bh processing too long - return; - } - } - if (mer && ccleirq > 0 && !aliased_irq) { - printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer); - ccleirq--; - } - } - iirq: - mir = master_inb(IIRQ_REG); - /* should test whether keyboard irq is really enabled, doing it in defhand */ - if (mir & Q40_IRQ_KEYB_MASK) - do_IRQ(Q40_IRQ_KEYBOARD, fp); - - return; -} - -void q40_irq_enable(struct irq_data *data) -{ - unsigned int irq = data->irq; - - if (irq >= 5 && irq <= 15) { - mext_disabled--; - if (mext_disabled > 0) - printk("q40_irq_enable : nested disable/enable\n"); - if (mext_disabled == 0) - master_outb(1, EXT_ENABLE_REG); - } -} - - -void q40_irq_disable(struct irq_data *data) -{ - unsigned int irq = data->irq; - - /* disable ISA iqs : only do something if the driver has been - * verified to be Q40 "compatible" - right now IDE, NE2K - * Any driver should not attempt to sleep across disable_irq !! - */ - - if (irq >= 5 && irq <= 15) { - master_outb(0, EXT_ENABLE_REG); - mext_disabled++; - if (mext_disabled > 1) - printk("disable_irq nesting count %d\n",mext_disabled); - } -} |