|  | /* | 
|  | * include/asm-v850/rte_cb.c -- Midas lab RTE-CB series of evaluation boards | 
|  | * | 
|  | *  Copyright (C) 2001,02,03  NEC Electronics Corporation | 
|  | *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org> | 
|  | * | 
|  | * 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. | 
|  | * | 
|  | * Written by Miles Bader <miles@gnu.org> | 
|  | */ | 
|  |  | 
|  | #include <linux/init.h> | 
|  | #include <linux/irq.h> | 
|  | #include <linux/fs.h> | 
|  | #include <linux/module.h> | 
|  | #include <linux/kernel.h> | 
|  |  | 
|  | #include <asm/machdep.h> | 
|  | #include <asm/v850e_uart.h> | 
|  |  | 
|  | #include "mach.h" | 
|  |  | 
|  | static void led_tick (void); | 
|  |  | 
|  | /* LED access routines.  */ | 
|  | extern unsigned read_leds (int pos, char *buf, int len); | 
|  | extern unsigned write_leds (int pos, const char *buf, int len); | 
|  |  | 
|  | #ifdef CONFIG_RTE_CB_MULTI | 
|  | extern void multi_init (void); | 
|  | #endif | 
|  |  | 
|  |  | 
|  | void __init rte_cb_early_init (void) | 
|  | { | 
|  | v850e_intc_disable_irqs (); | 
|  |  | 
|  | #ifdef CONFIG_RTE_CB_MULTI | 
|  | multi_init (); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | void __init mach_setup (char **cmdline) | 
|  | { | 
|  | #ifdef CONFIG_RTE_MB_A_PCI | 
|  | /* Probe for Mother-A, and print a message if we find it.  */ | 
|  | *(volatile unsigned long *)MB_A_SRAM_ADDR = 0xDEADBEEF; | 
|  | if (*(volatile unsigned long *)MB_A_SRAM_ADDR == 0xDEADBEEF) { | 
|  | *(volatile unsigned long *)MB_A_SRAM_ADDR = 0x12345678; | 
|  | if (*(volatile unsigned long *)MB_A_SRAM_ADDR == 0x12345678) | 
|  | printk (KERN_INFO | 
|  | "          NEC SolutionGear/Midas lab" | 
|  | " RTE-MOTHER-A motherboard\n"); | 
|  | } | 
|  | #endif /* CONFIG_RTE_MB_A_PCI */ | 
|  |  | 
|  | mach_tick = led_tick; | 
|  | } | 
|  |  | 
|  | void machine_restart (char *__unused) | 
|  | { | 
|  | #ifdef CONFIG_RESET_GUARD | 
|  | disable_reset_guard (); | 
|  | #endif | 
|  | asm ("jmp r0"); /* Jump to the reset vector.  */ | 
|  | } | 
|  |  | 
|  | /* This says `HALt.' in LEDese.  */ | 
|  | static unsigned char halt_leds_msg[] = { 0x76, 0x77, 0x38, 0xF8 }; | 
|  |  | 
|  | void machine_halt (void) | 
|  | { | 
|  | #ifdef CONFIG_RESET_GUARD | 
|  | disable_reset_guard (); | 
|  | #endif | 
|  |  | 
|  | /* Ignore all interrupts.  */ | 
|  | local_irq_disable (); | 
|  |  | 
|  | /* Write a little message.  */ | 
|  | write_leds (0, halt_leds_msg, sizeof halt_leds_msg); | 
|  |  | 
|  | /* Really halt.  */ | 
|  | for (;;) | 
|  | asm ("halt; nop; nop; nop; nop; nop"); | 
|  | } | 
|  |  | 
|  | void machine_power_off (void) | 
|  | { | 
|  | machine_halt (); | 
|  | } | 
|  |  | 
|  |  | 
|  | /* Animated LED display for timer tick.  */ | 
|  |  | 
|  | #define TICK_UPD_FREQ	6 | 
|  | static int tick_frames[][10] = { | 
|  | { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, -1 }, | 
|  | { 0x63, 0x5c, -1 }, | 
|  | { 0x5c, 0x00, -1 }, | 
|  | { 0x63, 0x00, -1 }, | 
|  | { -1 } | 
|  | }; | 
|  |  | 
|  | static void led_tick () | 
|  | { | 
|  | static unsigned counter = 0; | 
|  |  | 
|  | if (++counter == (HZ / TICK_UPD_FREQ)) { | 
|  | /* Which frame we're currently displaying for each digit.  */ | 
|  | static unsigned frame_nums[LED_NUM_DIGITS] = { 0 }; | 
|  | /* Display image.  */ | 
|  | static unsigned char image[LED_NUM_DIGITS] = { 0 }; | 
|  | unsigned char prev_image[LED_NUM_DIGITS]; | 
|  | int write_to_leds = 1; /* true if we should actually display */ | 
|  | int digit; | 
|  |  | 
|  | /* We check to see if the physical LEDs contains what we last | 
|  | wrote to them; if not, we suppress display (this is so that | 
|  | users can write to the LEDs, and not have their output | 
|  | overwritten).  As a special case, we start writing again if | 
|  | all the LEDs are blank, or our display image is all zeros | 
|  | (indicating that this is the initial update, when the actual | 
|  | LEDs might contain random data).  */ | 
|  | read_leds (0, prev_image, LED_NUM_DIGITS); | 
|  | for (digit = 0; digit < LED_NUM_DIGITS; digit++) | 
|  | if (image[digit] != prev_image[digit] | 
|  | && image[digit] && prev_image[digit]) | 
|  | { | 
|  | write_to_leds = 0; | 
|  | break; | 
|  | } | 
|  |  | 
|  | /* Update display image.  */ | 
|  | for (digit = 0; | 
|  | digit < LED_NUM_DIGITS && tick_frames[digit][0] >= 0; | 
|  | digit++) | 
|  | { | 
|  | int frame = tick_frames[digit][frame_nums[digit]]; | 
|  | if (frame < 0) { | 
|  | image[digit] = tick_frames[digit][0]; | 
|  | frame_nums[digit] = 1; | 
|  | } else { | 
|  | image[digit] = frame; | 
|  | frame_nums[digit]++; | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (write_to_leds) | 
|  | /* Write the display image to the physical LEDs.  */ | 
|  | write_leds (0, image, LED_NUM_DIGITS); | 
|  |  | 
|  | counter = 0; | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | /* Mother-A interrupts.  */ | 
|  |  | 
|  | #ifdef CONFIG_RTE_GBUS_INT | 
|  |  | 
|  | #define L GBUS_INT_PRIORITY_LOW | 
|  | #define M GBUS_INT_PRIORITY_MEDIUM | 
|  | #define H GBUS_INT_PRIORITY_HIGH | 
|  |  | 
|  | static struct gbus_int_irq_init gbus_irq_inits[] = { | 
|  | #ifdef CONFIG_RTE_MB_A_PCI | 
|  | { "MB_A_LAN",	IRQ_MB_A_LAN,		1,		     1, L }, | 
|  | { "MB_A_PCI1",	IRQ_MB_A_PCI1(0),	IRQ_MB_A_PCI1_NUM,   1, L }, | 
|  | { "MB_A_PCI2",	IRQ_MB_A_PCI2(0),	IRQ_MB_A_PCI2_NUM,   1, L }, | 
|  | { "MB_A_EXT",	IRQ_MB_A_EXT(0),	IRQ_MB_A_EXT_NUM,    1, L }, | 
|  | { "MB_A_USB_OC",IRQ_MB_A_USB_OC(0),	IRQ_MB_A_USB_OC_NUM, 1, L }, | 
|  | { "MB_A_PCMCIA_OC",IRQ_MB_A_PCMCIA_OC,	1,		     1, L }, | 
|  | #endif | 
|  | { 0 } | 
|  | }; | 
|  | #define NUM_GBUS_IRQ_INITS (ARRAY_SIZE(gbus_irq_inits) - 1) | 
|  |  | 
|  | static struct hw_interrupt_type gbus_hw_itypes[NUM_GBUS_IRQ_INITS]; | 
|  |  | 
|  | #endif /* CONFIG_RTE_GBUS_INT */ | 
|  |  | 
|  |  | 
|  | void __init rte_cb_init_irqs (void) | 
|  | { | 
|  | #ifdef CONFIG_RTE_GBUS_INT | 
|  | gbus_int_init_irqs (); | 
|  | gbus_int_init_irq_types (gbus_irq_inits, gbus_hw_itypes); | 
|  | #endif /* CONFIG_RTE_GBUS_INT */ | 
|  | } |