/* * Setup pointers to hardware-dependent routines. * * 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. * * Copyright (C) 1996, 1997, 1998 by Ralf Baechle */ #include #include #include #include #include #include #include #include #include #include #include "utils.h" extern char CommandLine[]; extern void pci_setup(void); #ifdef CONFIG_KGDB int remote_debug = 0; #endif const char *get_system_type(void) { return "HP LaserJet"; /* But which exactly? */ } static void (*timer_interrupt_service) (int irq, void *dev_id, struct pt_regs * regs) = NULL; static void andros_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { if (!(*((volatile unsigned int *) 0xbfea0010) & 0x20)) // mask = pend & en return; /* clear timer interrupt */ { unsigned int tmr = *((volatile unsigned int *) 0xbfe90040); // ctl bits *((volatile unsigned int *) 0xbfe90040) = tmr; // write to ack *((volatile unsigned int *) 0xbfea000c) = 0x20; // sys int ack } /* service interrupt */ timer_interrupt_service(irq, dev_id, regs); } static void harmony_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { if (!(*((volatile unsigned int *) 0xbff63000) & 0x01)) return; // big sys int reg, 01-timer did it if (!(*((volatile unsigned int *) 0xbff610a4) & 0x01)) return; // local small int reg, 01-timer0 did it *((volatile unsigned int *) 0xbff610a4) = 1; // ack local timer0 bit *((volatile unsigned int *) 0xbff63000) = 1; // ack global timer bit /* service interrupt */ timer_interrupt_service(irq, dev_id, regs); } #define ASIC_IRQ_NUMBER 2 static void __init hp_time_init(struct irqaction *irq) { timer_interrupt_service = irq->handler; if (GetAsicId() == AndrosAsic) { //*((volatile unsigned int*)0xbfe90000) = 0x2f; // set by bootloader to 0x20 // prescaler *((volatile unsigned int *) 0xbfe90040) = 0x21; // 20-res of 1kHz,1-int ack // control *((volatile unsigned int *) 0xbfe90048) = 0x09; // 09-reload val // reload *((volatile unsigned int *) 0xbfe90044) = 0x09; // 09-count val // count *((volatile unsigned int *) 0xbfe90040) = 0x2f; // 8-int enable,4-reload en,2-count down en,1-int-ack irq->handler = andros_timer_interrupt; irq->flags |= SA_INTERRUPT | SA_SHIRQ; printk("setting up timer in hp_time_init\n"); setup_irq(ASIC_IRQ_NUMBER, irq); // enable timer interrupt *((volatile unsigned int *) 0xbfea0000) = 0x20; } else if (GetAsicId() == HarmonyAsic) { *((volatile unsigned int *) 0xbff61000) = 99; // prescaler, 100Mz sys clk *((volatile unsigned int *) 0xbff61028) = 0x09; // reload reg *((volatile unsigned int *) 0xbff61024) = 0x09; // count reg *((volatile unsigned int *) 0xbff61020) = 0x0b; // 80-1khz res on timer, 2 reload en, 1 - count down en irq->handler = harmony_timer_interrupt; irq->flags |= SA_INTERRUPT | SA_SHIRQ; setup_irq(ASIC_IRQ_NUMBER, irq); *((volatile unsigned int *) 0xbff610a0) |= 1; // turn on timer0 } else if (GetAsicId() == UnknownAsic) printk("Unknown asic in hp_time_init()\n"); else printk("Unsupported asic in hp_time_init()\n"); } static void hplj_restart(void) { if (GetAsicId() == AndrosAsic) *((volatile unsigned int *) 0xbfe900c0) = 0; if (GetAsicId() == HarmonyAsic) *((volatile unsigned int *) 0xbff62030) = 0; printk("Restart Failed ... halting instead\n"); while (1); } static void hplj_halt(void) { while (1); } static void __init hp_setup(void) { #ifdef CONFIG_PCI pci_setup(); #endif _machine_restart = (void (*)(char *)) hplj_restart; _machine_halt = hplj_halt; _machine_power_off = hplj_halt; board_timer_setup = hp_time_init; #ifdef CONFIG_KGDB remote_debug = (strstr(CommandLine, "kgdb") != NULL); #endif printk("HP SETUP\n"); } early_initcall(hp_setup);