From: James S. <jsi...@us...> - 2001-10-29 17:37:04
|
Update of /cvsroot/linux-mips/linux/arch/mips/philips/nino In directory usw-pr-cvs1:/tmp/cvs-serv8130/philips/nino Modified Files: irq.c prom.c setup.c time.c Log Message: Nino updates. Index: irq.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/philips/nino/irq.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- irq.c 2001/10/26 22:30:51 1.3 +++ irq.c 2001/10/29 17:37:01 1.4 @@ -1,65 +1,24 @@ /* - * irq.c: Fine grained interrupt handling for Nino + * include/arch/mips/philips/nino/irq.c * * Copyright (C) 2001 Steven J. Hill (sj...@re...) */ #include <linux/init.h> - -#include <linux/errno.h> -#include <linux/kernel_stat.h> -#include <linux/signal.h> #include <linux/sched.h> -#include <linux/types.h> #include <linux/interrupt.h> #include <linux/irq.h> -#include <linux/ioport.h> -#include <linux/timex.h> -#include <linux/slab.h> -#include <linux/random.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> - -#include <asm/bitops.h> -#include <asm/bootinfo.h> -#include <asm/io.h> #include <asm/irq.h> #include <asm/mipsregs.h> -#include <asm/system.h> - -#include <asm/ptrace.h> -#include <asm/processor.h> #include <asm/tx3912.h> -/* - * Linux has a controller-independent x86 interrupt architecture. - * every controller has a 'controller-template', that is used - * by the main code to do the right thing. Each driver-visible - * interrupt source is transparently wired to the apropriate - * controller. Thus drivers need not be aware of the - * interrupt-controller. - * - * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC, - * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC. - * (IO-APICs assumed to be messaging to Pentium local-APICs) - * - * the code is designed to be easily extended with new/different - * interrupt controllers, without having to do assembly magic. - */ - -extern asmlinkage void ninoIRQ(void); extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs); -extern void init_generic_irq(void); static void enable_irq4(unsigned int irq) { - unsigned long flags; - - save_and_cli(flags); if(irq == 0) { IntEnable5 |= INT5_PERIODICINT; IntEnable6 |= INT6_PERIODICINT; } - restore_flags(flags); } static unsigned int startup_irq4(unsigned int irq) @@ -71,15 +30,11 @@ static void disable_irq4(unsigned int irq) { - unsigned long flags; - - save_and_cli(flags); if(irq == 0) { - IntEnable6 &= ~INT6_PERIODICINT; - IntClear5 |= INT5_PERIODICINT; - IntClear6 |= INT6_PERIODICINT; + IntEnable6 &= ~INT6_PERIODICINT; + IntClear5 |= INT5_PERIODICINT; + IntClear6 |= INT6_PERIODICINT; } - restore_flags(flags); } #define shutdown_irq4 disable_irq4 @@ -92,7 +47,7 @@ } static struct hw_interrupt_type irq4_type = { - "IRQ4", + "MIPS", startup_irq4, shutdown_irq4, enable_irq4, @@ -113,7 +68,7 @@ /* if irq == -1, then the interrupt has already been cleared */ if(irq == -1) { - printk("IRQ6 Status Register = 0x%08x\n", IntStatus6); + printk("IRQ6 Status Register = 0x%08lx\n", IntStatus6); goto end; } @@ -126,21 +81,11 @@ static void enable_irq2(unsigned int irq) { - unsigned long flags; - - save_and_cli(flags); + set_cp0_status(STATUSF_IP4); if(irq == 2 || irq == 3) { - IntEnable1 = 0x00000000; - IntEnable2 = 0xfffff000; - IntEnable3 = 0x00000000; - IntEnable4 = 0x00000000; - IntClear1 = 0xffffffff; IntClear2 = 0xffffffff; - IntClear3 = 0xffffffff; - IntClear4 = 0xffffffff; - IntClear5 = 0xffffffff; + IntEnable2 = 0xfffff000; } - restore_flags(flags); } static unsigned int startup_irq2(unsigned int irq) @@ -152,19 +97,7 @@ static void disable_irq2(unsigned int irq) { - unsigned long flags; - - save_and_cli(flags); - IntEnable1 = 0x00000000; - IntEnable2 = 0x00000000; - IntEnable3 = 0x00000000; - IntEnable4 = 0x00000000; - IntClear1 = 0xffffffff; - IntClear2 = 0xffffffff; - IntClear3 = 0xffffffff; - IntClear4 = 0xffffffff; - IntClear5 = 0xffffffff; - restore_flags(flags); + clear_cp0_status(STATUSF_IP4); } #define shutdown_irq2 disable_irq2 @@ -177,7 +110,7 @@ } static struct hw_interrupt_type irq2_type = { - "IRQ2", + "MIPS", startup_irq2, shutdown_irq2, enable_irq2, @@ -202,6 +135,7 @@ /* if irq == -1, then the interrupt has already been cleared */ if (irq == -1) { + printk("EEK\n"); IntClear1 = 0xffffffff; IntClear3 = 0xffffffff; IntClear4 = 0xffffffff; @@ -219,7 +153,7 @@ void irq_bad(struct pt_regs *regs) { /* This should never happen */ - printk("Invalid interrupt, spinning...\n"); + printk("Stray interrupt, spinning...\n"); printk(" CAUSE register = 0x%08lx\n", regs->cp0_cause); printk("STATUS register = 0x%08lx\n", regs->cp0_status); printk(" EPC register = 0x%08lx\n", regs->cp0_epc); @@ -228,30 +162,32 @@ void __init nino_irq_setup(void) { + extern asmlinkage void ninoIRQ(void); + extern void init_generic_irq(void); + unsigned int i; - /* Disable interrupts */ - IntEnable1 = 0x00000000; - IntEnable2 = 0x00000000; - IntEnable3 = 0x00000000; - IntEnable4 = 0x00000000; - IntEnable5 = 0x00000000; - IntEnable6 = 0x00000000; + /* Disable all hardware interrupts */ + change_cp0_status(ST0_IM, 0x00); - /* Clear interrupts */ + /* Clear any pending interrupts */ IntClear1 = 0xffffffff; IntClear2 = 0xffffffff; IntClear3 = 0xffffffff; IntClear4 = 0xffffffff; IntClear5 = 0xffffffff; - /* Change location of exception vector table */ - change_cp0_status(ST0_BEV, 0); + /* FIXME: disable interrupts 1,3,4 */ + IntEnable1 = 0x00000000; + IntEnable2 = 0xfffff000; + IntEnable3 = 0x00000000; + IntEnable4 = 0x00000000; + IntEnable5 = 0xffffffff; /* Initialize IRQ vector table */ init_generic_irq(); - /* Initialize hardware IRQ structure */ + /* Initialize IRQ action handlers */ for (i = 0; i < 16; i++) { hw_irq_controller *handler = NULL; if (i == 0) @@ -269,6 +205,12 @@ /* Set up the external interrupt exception vector */ set_except_vector(0, ninoIRQ); + + /* Enable high priority interrupts */ + IntEnable6 = (INT6_GLOBALEN | 0xffff); + + /* Enable interrupts */ + change_cp0_status(ST0_IM, IE_IRQ2 | IE_IRQ4); } void (*irq_setup)(void); Index: prom.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/philips/nino/prom.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 --- prom.c 2001/06/22 02:29:32 1.1.1.1 +++ prom.c 2001/10/29 17:37:01 1.2 @@ -20,26 +20,19 @@ char arcs_cmdline[COMMAND_LINE_SIZE]; #ifdef CONFIG_FB_TX3912 -extern u_long tx3912fb_paddr; -extern u_long tx3912fb_vaddr; -extern u_long tx3912fb_size; +extern unsigned long tx3912fb_paddr; +extern unsigned long tx3912fb_vaddr; +extern unsigned long tx3912fb_size; #endif /* Do basic initialization */ void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) { - u_long free_end, mem_size; - u_int i; + unsigned long mem_size; + unsigned int i; - /* - * collect args and prepare cmd_line - */ - for (i = 1; i < argc; i++) { - strcat(arcs_cmdline, argv[i]); - if (i < (argc - 1)) - strcat(arcs_cmdline, " "); - } + strcpy(arcs_cmdline, "console=tty0 console=ttyS0,115200"); mips_machgroup = MACH_GROUP_PHILIPS; mips_machtype = MACH_PHILIPS_NINO; @@ -53,6 +46,9 @@ #endif #ifdef CONFIG_FB_TX3912 +{ + unsigned long free_end; + /* * The LCD controller requires that the framebuffer * start address fall within a 1MB segment and is @@ -70,6 +66,7 @@ */ tx3912fb_paddr = PHYSADDR(free_end); tx3912fb_vaddr = KSEG1ADDR(free_end); +} #else add_memory_region(0, mem_size, BOOT_MEM_RAM); #endif Index: setup.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/philips/nino/setup.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- setup.c 2001/10/26 22:30:51 1.2 +++ setup.c 2001/10/29 17:37:01 1.3 @@ -10,6 +10,7 @@ * Interrupt and exception initialization for Philips Nino. */ #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/sched.h> #include <asm/addrspace.h> #include <asm/io.h> @@ -18,7 +19,7 @@ #include <asm/time.h> #include <asm/tx3912.h> -void nino_machine_restart(char *command) +static void nino_machine_restart(char *command) { static void (*back_to_prom)(void) = (void (*)(void)) 0xbfc00000; @@ -26,13 +27,13 @@ back_to_prom(); } -void nino_machine_halt(void) +static void nino_machine_halt(void) { printk("Nino halted.\n"); while(1); } -void nino_machine_power_off(void) +static void nino_machine_power_off(void) { printk("Nino halted. Please turn off power.\n"); while(1); @@ -56,35 +57,26 @@ outl(scratch, TX3912_CLK_CTRL_BASE); } -extern int setup_irq(unsigned int irq, struct irqaction *irqaction); - static __init void nino_timer_setup(struct irqaction *irq) { + irq->dev_id = (void *) irq; setup_irq(0, irq); - - /* Enable all hardware interrupts */ - set_cp0_status(IE_IRQ5 | IE_IRQ4 | IE_IRQ3 | - IE_IRQ2 | IE_IRQ1 | IE_IRQ0); - - /* Enable all the high priority interrupts */ - IntEnable6 = (INT6_GLOBALEN | 0xffff); - } -extern void nino_irq_setup(void); -extern void nino_wait(void); - void __init nino_setup(void) { + extern void nino_irq_setup(void); + extern void nino_wait(void); + irq_setup = nino_irq_setup; - mips_io_port_base = KSEG1ADDR(0xb0c00000); + mips_io_port_base = KSEG1ADDR(0x10c00000); + _machine_restart = nino_machine_restart; + _machine_halt = nino_machine_halt; + _machine_power_off = nino_machine_power_off; + board_time_init = nino_time_init; board_timer_setup = nino_timer_setup; - - _machine_restart = nino_machine_restart; - _machine_halt = nino_machine_halt; - _machine_power_off = nino_machine_power_off; cpu_wait = nino_wait; Index: time.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/philips/nino/time.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- time.c 2001/10/26 22:30:51 1.2 +++ time.c 2001/10/29 17:37:01 1.3 @@ -29,8 +29,8 @@ static struct timeval xbase; -void (*board_time_init)(void) = NULL; -void (*board_timer_setup)(struct irqaction *irq) = NULL; +void (*board_time_init) (void) = NULL; +void (*board_timer_setup) (struct irqaction * irq) = NULL; #define USECS_PER_JIFFY (1000000/HZ) @@ -41,10 +41,10 @@ static unsigned long do_gettimeoffset(void) { - /* - * This is a kludge - */ - return 0; + /* + * This is a kludge + */ + return 0; } static @@ -57,7 +57,7 @@ do { *high = RTChigh & RTC_HIGHMASK; *low = RTClow; - } while (*high != (RTChigh & RTC_HIGHMASK) || RTClow!=*low); + } while (*high != (RTChigh & RTC_HIGHMASK) || RTClow != *low); } /* @@ -65,71 +65,71 @@ */ void do_gettimeofday(struct timeval *tv) { - unsigned long flags; - unsigned long high, low; + unsigned long flags; + unsigned long high, low; - read_lock_irqsave(&xtime_lock, flags); - // 40 bit RTC, driven by 32khz source: - // +-----------+-----------------------------------------+ - // | HHHH.HHHH | LLLL.LLLL.LLLL.LLLL.LMMM.MMMM.MMMM.MMMM | - // +-----------+-----------------------------------------+ - readRTC(&high,&low); - tv->tv_sec = (high << 17) | (low >> 15); - tv->tv_usec = (low % 32768) * 1953 / 64; - tv->tv_sec += xbase.tv_sec; - tv->tv_usec += xbase.tv_usec; + read_lock_irqsave(&xtime_lock, flags); + // 40 bit RTC, driven by 32khz source: + // +-----------+-----------------------------------------+ + // | HHHH.HHHH | LLLL.LLLL.LLLL.LLLL.LMMM.MMMM.MMMM.MMMM | + // +-----------+-----------------------------------------+ + readRTC(&high, &low); + tv->tv_sec = (high << 17) | (low >> 15); + tv->tv_usec = (low % 32768) * 1953 / 64; + tv->tv_sec += xbase.tv_sec; + tv->tv_usec += xbase.tv_usec; - tv->tv_usec += do_gettimeoffset(); + tv->tv_usec += do_gettimeoffset(); - /* - * xtime is atomically updated in timer_bh. lost_ticks is - * nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; + /* + * xtime is atomically updated in timer_bh. lost_ticks is + * nonzero if the timer bottom half hasnt executed yet. + */ + if (jiffies - wall_jiffies) + tv->tv_usec += USECS_PER_JIFFY; - read_unlock_irqrestore(&xtime_lock, flags); + read_unlock_irqrestore(&xtime_lock, flags); - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; - } + if (tv->tv_usec >= 1000000) { + tv->tv_usec -= 1000000; + tv->tv_sec++; + } } void do_settimeofday(struct timeval *tv) { - write_lock_irq(&xtime_lock); - /* This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! - */ - tv->tv_usec -= do_gettimeoffset(); + write_lock_irq(&xtime_lock); + /* This is revolting. We need to set the xtime.tv_usec + * correctly. However, the value in this location is + * is value at the last tick. + * Discover what correction gettimeofday + * would have done, and then undo it! + */ + tv->tv_usec -= do_gettimeoffset(); - if (tv->tv_usec < 0) { - tv->tv_usec += 1000000; - tv->tv_sec--; - } + if (tv->tv_usec < 0) { + tv->tv_usec += 1000000; + tv->tv_sec--; + } - /* reset RTC to 0 (real time is xbase + RTC) */ - xbase = *tv; - RTCtimerControl |= TIM_RTCCLEAR; - RTCtimerControl &= ~TIM_RTCCLEAR; - RTCalarmHigh = RTCalarmLow = ~0UL; + /* reset RTC to 0 (real time is xbase + RTC) */ + xbase = *tv; + RTCtimerControl |= TIM_RTCCLEAR; + RTCtimerControl &= ~TIM_RTCCLEAR; + RTCalarmHigh = RTCalarmLow = ~0UL; - xtime = *tv; - time_state = TIME_BAD; - time_maxerror = MAXPHASE; - time_esterror = MAXPHASE; - write_unlock_irq(&xtime_lock); + xtime = *tv; + time_state = TIME_BAD; + time_maxerror = MAXPHASE; + time_esterror = MAXPHASE; + write_unlock_irq(&xtime_lock); } static int set_rtc_mmss(unsigned long nowtime) { - int retval = 0; + int retval = 0; - return retval; + return retval; } /* last time the cmos clock got updated */ @@ -142,78 +142,77 @@ int do_write = 1; -static void -timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { #ifdef POLL_STATUS - static unsigned long old_IntStatus1 = 0; - static unsigned long old_IntStatus3 = 0; - static unsigned long old_IntStatus4 = 0; - static unsigned long old_IntStatus5 = 0; - static int counter = 0; - int i; + static unsigned long old_IntStatus1 = 0; + static unsigned long old_IntStatus3 = 0; + static unsigned long old_IntStatus4 = 0; + static unsigned long old_IntStatus5 = 0; + static int counter = 0; + int i; - new_spircv = SPIData & 0xff; - if ((old_spircv != new_spircv) && (new_spircv != 0xff)) { - printk( "SPIData changed: %x\n", new_spircv ); - } - old_spircv = new_spircv; - if (do_write) - SPIData = 0; + new_spircv = SPIData & 0xff; + if ((old_spircv != new_spircv) && (new_spircv != 0xff)) { + printk("SPIData changed: %x\n", new_spircv); + } + old_spircv = new_spircv; + if (do_write) + SPIData = 0; #endif - if (!user_mode(regs)) { - if (prof_buffer && current->pid) { - extern int _stext; - unsigned long pc = regs->cp0_epc; + if (!user_mode(regs)) { + if (prof_buffer && current->pid) { + extern int _stext; + unsigned long pc = regs->cp0_epc; - pc -= (unsigned long) &_stext; - pc >>= prof_shift; - /* - * Dont ignore out-of-bounds pc values silently, - * put them into the last histogram slot, so if - * present, they will show up as a sharp peak. - */ - if (pc > prof_len - 1) - pc = prof_len - 1; - atomic_inc((atomic_t *) & prof_buffer[pc]); - } - } + pc -= (unsigned long) &_stext; + pc >>= prof_shift; + /* + * Dont ignore out-of-bounds pc values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + if (pc > prof_len - 1) + pc = prof_len - 1; + atomic_inc((atomic_t *) & prof_buffer[pc]); + } + } - /* - * aaaand... action! - */ - do_timer(regs); + /* + * aaaand... action! + */ + do_timer(regs); - /* - * If we have an externally syncronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - */ - if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 && - xtime.tv_usec > 500000 - (tick >> 1) && - xtime.tv_usec < 500000 + (tick >> 1)) - { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ - } + /* + * If we have an externally syncronized Linux clock, then update + * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be + * called as close as possible to 500 ms before the new second starts. + */ + if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 + && xtime.tv_usec > 500000 - (tick >> 1) + && xtime.tv_usec < 500000 + (tick >> 1)) { + if (set_rtc_mmss(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else + last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ + } } -static struct irqaction irq0 = {timer_interrupt, SA_INTERRUPT, 0, - "timer", NULL, NULL}; +static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, + "timer", NULL, NULL +}; int __init time_init(void) { - struct timeval starttime; + struct timeval starttime; - starttime.tv_sec = mktime(2000, 1, 1, 0, 0, 0); - starttime.tv_usec = 0; - do_settimeofday(&starttime); + starttime.tv_sec = mktime(2000, 1, 1, 0, 0, 0); + starttime.tv_usec = 0; + do_settimeofday(&starttime); - board_time_init(); - board_timer_setup(&irq0); + board_time_init(); + board_timer_setup(&irq0); - return 0; + return 0; } |