summaryrefslogtreecommitdiffstats
path: root/arch/mips/ite-boards
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-02-21 13:30:36 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-02-21 13:30:36 +0000
commit49a3beac398bd3e89dc4c8a5caff106cbd1e0cff (patch)
tree4f9a8bfdbe571a81ca63b73ae45c0b466661fb35 /arch/mips/ite-boards
parentb8d3cc7ceb61a07b865b420139477b91a4be202f (diff)
ITE 8172 patches from Pete Popov slightly hacked by me.
Diffstat (limited to 'arch/mips/ite-boards')
-rw-r--r--arch/mips/ite-boards/generic/.cvsignore2
-rw-r--r--arch/mips/ite-boards/generic/Makefile36
-rw-r--r--arch/mips/ite-boards/generic/dbg_io.c127
-rw-r--r--arch/mips/ite-boards/generic/int-handler.S61
-rw-r--r--arch/mips/ite-boards/generic/irq.c539
-rw-r--r--arch/mips/ite-boards/generic/it8172_cir.c171
-rw-r--r--arch/mips/ite-boards/generic/it8172_pci.c276
-rw-r--r--arch/mips/ite-boards/generic/it8172_rtc.c63
-rw-r--r--arch/mips/ite-boards/generic/it8172_setup.c311
-rw-r--r--arch/mips/ite-boards/generic/lpc.c144
-rw-r--r--arch/mips/ite-boards/generic/pmon_prom.c139
-rw-r--r--arch/mips/ite-boards/generic/puts.c144
-rw-r--r--arch/mips/ite-boards/generic/reset.c61
-rw-r--r--arch/mips/ite-boards/generic/time.c379
-rw-r--r--arch/mips/ite-boards/qed-4n-s01b/.cvsignore2
-rw-r--r--arch/mips/ite-boards/qed-4n-s01b/Makefile37
-rw-r--r--arch/mips/ite-boards/qed-4n-s01b/README2
-rw-r--r--arch/mips/ite-boards/qed-4n-s01b/init.c89
-rw-r--r--arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c197
19 files changed, 2780 insertions, 0 deletions
diff --git a/arch/mips/ite-boards/generic/.cvsignore b/arch/mips/ite-boards/generic/.cvsignore
new file mode 100644
index 000000000..857dd22e9
--- /dev/null
+++ b/arch/mips/ite-boards/generic/.cvsignore
@@ -0,0 +1,2 @@
+.depend
+.*.flags
diff --git a/arch/mips/ite-boards/generic/Makefile b/arch/mips/ite-boards/generic/Makefile
new file mode 100644
index 000000000..71d61ead8
--- /dev/null
+++ b/arch/mips/ite-boards/generic/Makefile
@@ -0,0 +1,36 @@
+#
+# Copyright 2000 MontaVista Software Inc.
+# Author: MontaVista Software, Inc.
+# ppopov@mvista.com or support@mvista.com
+#
+# Makefile for the ITE 8172 (qed-4n-s01b) board, generic files.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+all: it8172.o
+
+O_TARGET := it8172.o
+
+obj-y := it8172_rtc.o it8172_setup.o irq.o int-handler.o pmon_prom.o time.o lpc.o puts.o reset.o
+
+ifdef CONFIG_PCI
+obj-y += it8172_pci.o
+endif
+
+ifdef CONFIG_IT8172_CIR
+obj-y += it8172_cir.o
+endif
+
+ifdef CONFIG_REMOTE_DEBUG
+ obj-y += dbg_io.o
+endif
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/ite-boards/generic/dbg_io.c b/arch/mips/ite-boards/generic/dbg_io.c
new file mode 100644
index 000000000..76b0c1f70
--- /dev/null
+++ b/arch/mips/ite-boards/generic/dbg_io.c
@@ -0,0 +1,127 @@
+
+#include <linux/config.h>
+
+#ifdef CONFIG_REMOTE_DEBUG
+
+/* --- CONFIG --- */
+
+/* we need uint32 uint8 */
+/* #include "types.h" */
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+/* --- END OF CONFIG --- */
+
+#define UART16550_BAUD_2400 2400
+#define UART16550_BAUD_4800 4800
+#define UART16550_BAUD_9600 9600
+#define UART16550_BAUD_19200 19200
+#define UART16550_BAUD_38400 38400
+#define UART16550_BAUD_57600 57600
+#define UART16550_BAUD_115200 115200
+
+#define UART16550_PARITY_NONE 0
+#define UART16550_PARITY_ODD 0x08
+#define UART16550_PARITY_EVEN 0x18
+#define UART16550_PARITY_MARK 0x28
+#define UART16550_PARITY_SPACE 0x38
+
+#define UART16550_DATA_5BIT 0x0
+#define UART16550_DATA_6BIT 0x1
+#define UART16550_DATA_7BIT 0x2
+#define UART16550_DATA_8BIT 0x3
+
+#define UART16550_STOP_1BIT 0x0
+#define UART16550_STOP_2BIT 0x4
+
+/* ----------------------------------------------------- */
+
+/* === CONFIG === */
+
+/* [stevel] we use the IT8712 serial port for kgdb */
+#define DEBUG_BASE 0xB40003F8 /* 8712 serial port 1 base address */
+#define MAX_BAUD 115200
+
+/* === END OF CONFIG === */
+
+/* register offset */
+#define OFS_RCV_BUFFER 0
+#define OFS_TRANS_HOLD 0
+#define OFS_SEND_BUFFER 0
+#define OFS_INTR_ENABLE 1
+#define OFS_INTR_ID 2
+#define OFS_DATA_FORMAT 3
+#define OFS_LINE_CONTROL 3
+#define OFS_MODEM_CONTROL 4
+#define OFS_RS232_OUTPUT 4
+#define OFS_LINE_STATUS 5
+#define OFS_MODEM_STATUS 6
+#define OFS_RS232_INPUT 6
+#define OFS_SCRATCH_PAD 7
+
+#define OFS_DIVISOR_LSB 0
+#define OFS_DIVISOR_MSB 1
+
+
+/* memory-mapped read/write of the port */
+#define UART16550_READ(y) (*((volatile uint8*)(DEBUG_BASE + y)))
+#define UART16550_WRITE(y,z) ((*((volatile uint8*)(DEBUG_BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+ /* disable interrupts */
+ UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+ /* set up buad rate */
+ {
+ uint32 divisor;
+
+ /* set DIAB bit */
+ UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+ /* set divisor */
+ divisor = MAX_BAUD / baud;
+ UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+ UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00)>>8);
+
+ /* clear DIAB bit */
+ UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+ }
+
+ /* set data format */
+ UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+uint8 getDebugChar(void)
+{
+ if (!remoteDebugInitialized) {
+ remoteDebugInitialized = 1;
+ debugInit(UART16550_BAUD_115200,
+ UART16550_DATA_8BIT,
+ UART16550_PARITY_NONE,
+ UART16550_STOP_1BIT);
+ }
+
+ while((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+ return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+ if (!remoteDebugInitialized) {
+ remoteDebugInitialized = 1;
+ debugInit(UART16550_BAUD_115200,
+ UART16550_DATA_8BIT,
+ UART16550_PARITY_NONE,
+ UART16550_STOP_1BIT);
+ }
+
+ while ((UART16550_READ(OFS_LINE_STATUS) &0x20) == 0);
+ UART16550_WRITE(OFS_SEND_BUFFER, byte);
+ return 1;
+}
+
+#endif
diff --git a/arch/mips/ite-boards/generic/int-handler.S b/arch/mips/ite-boards/generic/int-handler.S
new file mode 100644
index 000000000..2997b7f3d
--- /dev/null
+++ b/arch/mips/ite-boards/generic/int-handler.S
@@ -0,0 +1,61 @@
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+ .text
+ .set macro
+ .set noat
+ .align 5
+
+NESTED(it8172_IRQ, PT_SIZE, sp)
+ SAVE_ALL
+ CLI # Important: mark KERNEL mode !
+
+ /* We're working with 'reorder' set at this point. */
+ /*
+ * Get pending interrupts
+ */
+
+ mfc0 t0,CP0_CAUSE # get pending interrupts
+ mfc0 t1,CP0_STATUS # get enabled interrupts
+ and t0,t1 # isolate allowed ones
+
+ andi t0,0xff00 # isolate pending bits
+ beqz t0, 3f # spurious interrupt
+
+ andi a0, t0, CAUSEF_IP7
+ beq a0, zero, 1f
+ move a0, sp
+ jal mips_timer_interrupt
+ j ret_from_irq
+ nop
+
+1:
+ andi a0, t0, CAUSEF_IP2 # the only int we expect at this time
+ beq a0, zero, 3f
+ move a0,sp
+ jal it8172_hw0_irqdispatch
+
+ mfc0 t0,CP0_STATUS # disable interrupts
+ ori t0,1
+ xori t0,1
+ mtc0 t0,CP0_STATUS
+ nop
+ nop
+ nop
+
+ la a1, ret_from_irq
+ jr a1
+ nop
+
+3:
+ move a0, sp
+ jal mips_spurious_interrupt
+ nop
+ la a1, ret_from_irq
+ jr a1
+ nop
+
+END(it8172_IRQ)
+
diff --git a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c
new file mode 100644
index 000000000..4a10e0b47
--- /dev/null
+++ b/arch/mips/ite-boards/generic/irq.c
@@ -0,0 +1,539 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * ITE 8172G interrupt/setup routines.
+ *
+ * Copyright 2000,2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or support@mvista.com
+ *
+ * Part of this file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/atlas/atlas_int.c.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/malloc.h>
+#include <linux/random.h>
+#include <linux/serial_reg.h>
+
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_int.h>
+#include <asm/it8172/it8172_dbg.h>
+
+#undef DEBUG_IRQ
+#ifdef DEBUG_IRQ
+/* note: prints function name for you */
+#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void breakpoint(void);
+#endif
+
+/* revisit */
+#define EXT_IRQ0_TO_IP 2 /* IP 2 */
+#define EXT_IRQ5_TO_IP 7 /* IP 7 */
+
+extern void set_debug_traps(void);
+extern void mips_timer_interrupt(int irq, struct pt_regs *regs);
+extern asmlinkage void it8172_IRQ(void);
+irq_cpustat_t irq_stat [NR_CPUS];
+unsigned int local_bh_count[NR_CPUS];
+unsigned int local_irq_count[NR_CPUS];
+unsigned long spurious_count = 0;
+irq_desc_t irq_desc[NR_IRQS];
+irq_desc_t *irq_desc_base=&irq_desc[0];
+
+struct it8172_intc_regs volatile *it8172_hw0_icregs
+ = (struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE));
+
+/* Function for careful CP0 interrupt mask access */
+static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
+{
+ unsigned long status = read_32bit_cp0_register(CP0_STATUS);
+ status &= ~((clr_mask & 0xFF) << 8);
+ status |= (set_mask & 0xFF) << 8;
+ write_32bit_cp0_register(CP0_STATUS, status);
+}
+
+static inline void mask_irq(unsigned int irq_nr)
+{
+ modify_cp0_intmask(irq_nr, 0);
+}
+
+static inline void unmask_irq(unsigned int irq_nr)
+{
+ modify_cp0_intmask(0, irq_nr);
+}
+
+void disable_irq(unsigned int irq_nr)
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+ mask_irq(irq_nr);
+ restore_flags(flags);
+}
+
+void enable_irq(unsigned int irq_nr)
+{
+ unsigned long flags;
+
+ save_and_cli(flags);
+ unmask_irq(irq_nr);
+ restore_flags(flags);
+}
+
+
+void disable_it8172_irq(unsigned int irq_nr)
+{
+ unsigned short mask;
+
+ DPRINTK("disable_it8172_irq %d\n", irq_nr);
+
+ if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
+ /* LPC interrupt */
+ DPRINTK("disable, before lpc_mask %x\n", it8172_hw0_icregs->lpc_mask);
+ it8172_hw0_icregs->lpc_mask |= (1 << (irq_nr - IT8172_LPC_IRQ_BASE));
+ DPRINTK("disable, after lpc_mask %x\n", it8172_hw0_icregs->lpc_mask);
+ }
+ else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
+ /* Local Bus interrupt */
+ DPRINTK("before lb_mask %x\n", it8172_hw0_icregs->lb_mask);
+ it8172_hw0_icregs->lb_mask |= (1 << (irq_nr - IT8172_LB_IRQ_BASE));
+ DPRINTK("after lb_mask %x\n", it8172_hw0_icregs->lb_mask);
+ }
+ else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
+ /* PCI and other interrupts */
+ DPRINTK("before pci_mask %x\n", it8172_hw0_icregs->pci_mask);
+ it8172_hw0_icregs->pci_mask |= (1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
+ DPRINTK("after pci_mask %x\n", it8172_hw0_icregs->pci_mask);
+ }
+ else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
+ /* NMI interrupts */
+ DPRINTK("before nmi_mask %x\n", it8172_hw0_icregs->nmi_mask);
+ it8172_hw0_icregs->nmi_mask |= (1 << (irq_nr - IT8172_NMI_IRQ_BASE));
+ DPRINTK("after nmi_mask %x\n", it8172_hw0_icregs->nmi_mask);
+ }
+ else {
+ panic("disable_it8172_irq: bad irq %d\n", irq_nr);
+ }
+}
+
+
+void enable_it8172_irq(unsigned int irq_nr)
+{
+ DPRINTK("enable_it8172_irq %d\n", irq_nr);
+ if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
+ /* LPC interrupt */
+ DPRINTK("enable, before lpc_mask %x\n", it8172_hw0_icregs->lpc_mask);
+ it8172_hw0_icregs->lpc_mask &= ~(1 << (irq_nr - IT8172_LPC_IRQ_BASE));
+ DPRINTK("enable, after lpc_mask %x\n", it8172_hw0_icregs->lpc_mask);
+ }
+ else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
+ /* Local Bus interrupt */
+ DPRINTK("before lb_mask %x\n", it8172_hw0_icregs->lb_mask);
+ it8172_hw0_icregs->lb_mask &= ~(1 << (irq_nr - IT8172_LB_IRQ_BASE));
+ DPRINTK("after lb_mask %x\n", it8172_hw0_icregs->lb_mask);
+ }
+ else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
+ /* PCI and other interrupts */
+ DPRINTK("before pci_mask %x\n", it8172_hw0_icregs->pci_mask);
+ it8172_hw0_icregs->pci_mask &= ~(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
+ DPRINTK("after pci_mask %x\n", it8172_hw0_icregs->pci_mask);
+ }
+ else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
+ /* NMI interrupts */
+ DPRINTK("before nmi_mask %x\n", it8172_hw0_icregs->nmi_mask);
+ it8172_hw0_icregs->nmi_mask &= ~(1 << (irq_nr - IT8172_NMI_IRQ_BASE));
+ DPRINTK("after nmi_mask %x\n", it8172_hw0_icregs->nmi_mask);
+ }
+ else {
+ panic("enable_it8172_irq: bad irq %d\n", irq_nr);
+ }
+}
+
+static unsigned int startup_ite_irq(unsigned int irq)
+{
+ enable_it8172_irq(irq);
+ return 0;
+}
+
+#define shutdown_ite_irq disable_it8172_irq
+#define mask_and_ack_ite_irq disable_it8172_irq
+
+static void end_ite_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ enable_it8172_irq(irq);
+}
+
+static struct hw_interrupt_type it8172_irq_type = {
+ "ITE8172",
+ startup_ite_irq,
+ shutdown_ite_irq,
+ enable_it8172_irq,
+ disable_it8172_irq,
+ mask_and_ack_ite_irq,
+ end_ite_irq,
+ NULL
+};
+
+
+int get_irq_list(char *buf)
+{
+ int i, len = 0, j;
+ struct irqaction * action;
+
+ len += sprintf(buf+len, " ");
+ for (j=0; j<smp_num_cpus; j++)
+ len += sprintf(buf+len, "CPU%d ",j);
+ *(char *)(buf+len++) = '\n';
+
+ for (i = 0 ; i < NR_IRQS ; i++) {
+ action = irq_desc[i].action;
+ if ( !action || !action->handler )
+ continue;
+ len += sprintf(buf+len, "%3d: ", i);
+ len += sprintf(buf+len, "%10u ", kstat_irqs(i));
+ if ( irq_desc[i].handler )
+ len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename );
+ else
+ len += sprintf(buf+len, " None ");
+ len += sprintf(buf+len, " %s",action->name);
+ for (action=action->next; action; action = action->next) {
+ len += sprintf(buf+len, ", %s", action->name);
+ }
+ len += sprintf(buf+len, "\n");
+ }
+ len += sprintf(buf+len, "BAD: %10lu\n", spurious_count);
+ return len;
+}
+
+asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
+{
+ struct irqaction *action;
+ int cpu;
+
+ cpu = smp_processor_id();
+ irq_enter(cpu, irq);
+
+ kstat.irqs[cpu][irq]++;
+#if 0
+ if (irq_desc[irq].handler && irq_desc[irq].handler->ack) {
+ // printk("invoking ack handler\n");
+ irq_desc[irq].handler->ack(irq);
+ }
+#endif
+
+ action = irq_desc[irq].action;
+
+ if (action && action->handler)
+ {
+ //mask_irq(1<<irq);
+ //printk("action->handler %x\n", action->handler);
+ disable_it8172_irq(irq);
+ //if (!(action->flags & SA_INTERRUPT)) __sti(); /* reenable ints */
+ do {
+ action->handler(irq, action->dev_id, regs);
+ action = action->next;
+ } while ( action );
+ //__cli(); /* disable ints */
+ if (irq_desc[irq].handler)
+ {
+ }
+ //unmask_irq(1<<irq);
+ enable_it8172_irq(irq);
+ }
+ else
+ {
+ spurious_count++;
+ printk("Unhandled interrupt %d, cause %x, disabled\n",
+ (unsigned)irq, (unsigned)regs->cp0_cause);
+ disable_it8172_irq(irq);
+ //disable_irq(1<<irq);
+ }
+ irq_exit(cpu, irq);
+}
+
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags, const char * devname, void *dev_id)
+{
+ struct irqaction *old, **p, *action;
+ unsigned long flags;
+
+ /*
+ * IP0 and IP1 are software interrupts. IP7 is typically the timer interrupt.
+ *
+ * The ITE QED-4N-S01B board has one single interrupt line going from
+ * the system controller to the CPU. It's connected to the CPU external
+ * irq pin 1, which is IP2. The interrupt numbers are listed in it8172_int.h;
+ * the ISA interrupts are numbered from 0 to 15, and the rest go from
+ * there.
+ */
+
+ //printk("request_irq: %d handler %x\n", irq, handler);
+ if (irq >= NR_IRQS)
+ return -EINVAL;
+
+ if (!handler)
+ {
+ /* Free */
+ for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next)
+ {
+ /* Found it - now free it */
+ save_flags(flags);
+ cli();
+ *p = action->next;
+ disable_it8172_irq(irq);
+ //disable_irq(1<<irq);
+ restore_flags(flags);
+ kfree(action);
+ return 0;
+ }
+ return -ENOENT;
+ }
+
+ action = (struct irqaction *)
+ kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+ if (!action)
+ return -ENOMEM;
+ memset(action, 0, sizeof(struct irqaction));
+
+ save_flags(flags);
+ cli();
+
+ action->handler = handler;
+ action->flags = irqflags;
+ action->mask = 0;
+ action->name = devname;
+ action->dev_id = dev_id;
+ action->next = NULL;
+
+ p = &irq_desc[irq].action;
+
+ if ((old = *p) != NULL) {
+ /* Can't share interrupts unless both agree to */
+ if (!(old->flags & action->flags & SA_SHIRQ))
+ return -EBUSY;
+ /* add new interrupt at end of irq queue */
+ do {
+ p = &old->next;
+ old = *p;
+ } while (old);
+ }
+ *p = action;
+ enable_it8172_irq(irq);
+ restore_flags(flags);
+#if 0
+ printk("request_irq: status %x cause %x\n",
+ read_32bit_cp0_register(CP0_STATUS), read_32bit_cp0_register(CP0_CAUSE));
+#endif
+ return 0;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+ request_irq(irq, NULL, 0, NULL, dev_id);
+}
+
+void enable_cpu_timer(void)
+{
+ enable_irq(1<<EXT_IRQ5_TO_IP); /* timer interrupt */
+}
+
+unsigned long probe_irq_on (void)
+{
+ return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+ return 0;
+}
+
+
+void __init init_IRQ(void)
+{
+ int i;
+
+ memset(irq_desc, 0, sizeof(irq_desc));
+ set_except_vector(0, it8172_IRQ);
+
+ /* mask all interrupts */
+ it8172_hw0_icregs->lb_mask = 0xffff;
+ it8172_hw0_icregs->lpc_mask = 0xffff;
+ it8172_hw0_icregs->pci_mask = 0xffff;
+ it8172_hw0_icregs->nmi_mask = 0xffff;
+
+ /* make all interrupts level triggered */
+ it8172_hw0_icregs->lb_trigger = 0;
+ it8172_hw0_icregs->lpc_trigger = 0;
+ it8172_hw0_icregs->pci_trigger = 0;
+ it8172_hw0_icregs->nmi_trigger = 0;
+
+ /* active level setting */
+ /* uart, keyboard, and mouse are active high */
+ it8172_hw0_icregs->lpc_level = (0x10 | 0x2 | 0x1000);
+ it8172_hw0_icregs->lb_level |= 0x20;
+
+ /* keyboard and mouse are edge triggered */
+ it8172_hw0_icregs->lpc_trigger |= (0x2 | 0x1000);
+
+
+#if 0
+ // Enable this piece of code to make internal USB interrupt
+ // edge triggered.
+ it8172_hw0_icregs->pci_trigger |=
+ (1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE));
+ it8172_hw0_icregs->pci_level &=
+ ~(1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE));
+#endif
+
+ for (i = 0; i <= IT8172_INT_END; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = 0;
+ irq_desc[i].depth = 1;
+ irq_desc[i].handler = &it8172_irq_type;
+ }
+
+ /*
+ * Enable external int line 2
+ * All ITE interrupts are masked for now.
+ */
+ enable_irq(1<<EXT_IRQ0_TO_IP);
+ //set_cp0_status(ST0_IM, IE_IRQ2);
+
+#ifdef CONFIG_REMOTE_DEBUG
+ /* If local serial I/O used for debug port, enter kgdb at once */
+ puts("Waiting for kgdb to connect...");
+ set_debug_traps();
+ breakpoint();
+#endif
+}
+
+void mips_spurious_interrupt(struct pt_regs *regs)
+{
+#if 1
+ return;
+#else
+ unsigned long status, cause;
+
+ printk("got spurious interrupt\n");
+ status = read_32bit_cp0_register(CP0_STATUS);
+ cause = read_32bit_cp0_register(CP0_CAUSE);
+ printk("status %x cause %x\n", status, cause);
+ printk("epc %x badvaddr %x \n", regs->cp0_epc, regs->cp0_badvaddr);
+// while(1);
+#endif
+}
+
+void it8172_hw0_irqdispatch(struct pt_regs *regs)
+{
+ int irq;
+ unsigned short intstatus, status;
+
+ intstatus = it8172_hw0_icregs->intstatus;
+ if (intstatus & 0x8) {
+ panic("Got NMI interrupt\n");
+ }
+ else if (intstatus & 0x4) {
+ /* PCI interrupt */
+ irq = 0;
+ status = it8172_hw0_icregs->pci_req;
+ while (!(status & 0x1)) {
+ irq++;
+ status >>= 1;
+ }
+ irq += IT8172_PCI_DEV_IRQ_BASE;
+ //printk("pci int %d\n", irq);
+ }
+ else if (intstatus & 0x1) {
+ /* Local Bus interrupt */
+ irq = 0;
+ status = it8172_hw0_icregs->lb_req;
+ while (!(status & 0x1)) {
+ irq++;
+ status >>= 1;
+ }
+ irq += IT8172_LB_IRQ_BASE;
+ //printk("lb int %d\n", irq);
+ }
+ else if (intstatus & 0x2) {
+ /* LPC interrupt */
+ /* Since some lpc interrupts are edge triggered,
+ * we could lose an interrupt this way because
+ * we acknowledge all ints at onces. Revisit.
+ */
+ status = it8172_hw0_icregs->lpc_req;
+ it8172_hw0_icregs->lpc_req = 0; /* acknowledge ints */
+ irq = 0;
+ while (!(status & 0x1)) {
+ irq++;
+ status >>= 1;
+ }
+ irq += IT8172_LPC_IRQ_BASE;
+ //printk("LPC int %d\n", irq);
+ }
+ else {
+ return;
+ }
+ do_IRQ(irq, regs);
+}
+
+void show_pending_irqs(void)
+{
+ fputs("intstatus: ");
+ put32(it8172_hw0_icregs->intstatus);
+ puts("");
+
+ fputs("pci_req: ");
+ put32(it8172_hw0_icregs->pci_req);
+ puts("");
+
+ fputs("lb_req: ");
+ put32(it8172_hw0_icregs->lb_req);
+ puts("");
+
+ fputs("lpc_req: ");
+ put32(it8172_hw0_icregs->lpc_req);
+ puts("");
+}
diff --git a/arch/mips/ite-boards/generic/it8172_cir.c b/arch/mips/ite-boards/generic/it8172_cir.c
new file mode 100644
index 000000000..a801e407d
--- /dev/null
+++ b/arch/mips/ite-boards/generic/it8172_cir.c
@@ -0,0 +1,171 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * IT8172 Consumer IR port generic routines.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or support@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_IT8172_CIR
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_cir.h>
+
+
+volatile struct it8172_cir_regs *cir_regs[NUM_CIR_PORTS] = {
+ (volatile struct it8172_cir_regs *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_CIR0_BASE)),
+ (volatile struct it8172_cir_regs *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_CIR1_BASE))};
+
+
+/*
+ * Initialize Consumer IR Port.
+ */
+int cir_port_init(struct cir_port *cir)
+{
+ int port = cir->port;
+ unsigned char data;
+
+ /* set baud rate */
+ cir_regs[port]->bdlr = cir->baud_rate & 0xff;
+ cir_regs[port]->bdhr = (cir->baud_rate >> 8) & 0xff;
+
+ /* set receiver control register */
+ cir_regs[port]->rcr = (CIR_SET_RDWOS(cir->rdwos) | CIR_SET_RXDCR(cir->rxdcr));
+
+ /* set carrier frequency register */
+ cir_regs[port]->cfr = (CIR_SET_CF(cir->cfq) | CIR_SET_HS(cir->hcfs));
+
+ /* set fifo threshold */
+ data = cir_regs[port]->mstcr & 0xf3;
+ data |= CIR_SET_FIFO_TL(cir->fifo_tl);
+ cir_regs[port]->mstcr = data;
+
+ clear_fifo(cir);
+ enable_receiver(cir);
+ disable_rx_demodulation(cir);
+
+ set_rx_active(cir);
+ int_enable(cir);
+ rx_int_enable(cir);
+
+ return 0;
+}
+
+
+void clear_fifo(struct cir_port *cir)
+{
+ cir_regs[cir->port]->mstcr |= CIR_FIFO_CLEAR;
+}
+
+void enable_receiver(struct cir_port *cir)
+{
+ cir_regs[cir->port]->rcr |= CIR_RXEN;
+}
+
+void disable_receiver(struct cir_port *cir)
+{
+ cir_regs[cir->port]->rcr &= ~CIR_RXEN;
+}
+
+void enable_rx_demodulation(struct cir_port *cir)
+{
+ cir_regs[cir->port]->rcr |= CIR_RXEND;
+}
+
+void disable_rx_demodulation(struct cir_port *cir)
+{
+ cir_regs[cir->port]->rcr &= ~CIR_RXEND;
+}
+
+void set_rx_active(struct cir_port *cir)
+{
+ cir_regs[cir->port]->rcr |= CIR_RXACT;
+}
+
+void int_enable(struct cir_port *cir)
+{
+ cir_regs[cir->port]->ier |= CIR_IEC;
+}
+
+void rx_int_enable(struct cir_port *cir)
+{
+ cir_regs[cir->port]->ier |= CIR_RDAIE;
+}
+
+void dump_regs(struct cir_port *cir)
+{
+ printk("mstcr %x ier %x iir %x cfr %x rcr %x tcr %x tfsr %x rfsr %x\n",
+ cir_regs[cir->port]->mstcr,
+ cir_regs[cir->port]->ier,
+ cir_regs[cir->port]->iir,
+ cir_regs[cir->port]->cfr,
+ cir_regs[cir->port]->rcr,
+ cir_regs[cir->port]->tcr,
+ cir_regs[cir->port]->tfsr,
+ cir_regs[cir->port]->rfsr);
+
+ while (cir_regs[cir->port]->iir & CIR_RDAI) {
+ printk("data %x\n", cir_regs[cir->port]->dr);
+ }
+}
+
+void dump_reg_addr(struct cir_port *cir)
+{
+ printk("dr %x mstcr %x ier %x iir %x cfr %x rcr %x tcr %x bdlr %x bdhr %x tfsr %x rfsr %x\n",
+ (unsigned)&cir_regs[cir->port]->dr,
+ (unsigned)&cir_regs[cir->port]->mstcr,
+ (unsigned)&cir_regs[cir->port]->ier,
+ (unsigned)&cir_regs[cir->port]->iir,
+ (unsigned)&cir_regs[cir->port]->cfr,
+ (unsigned)&cir_regs[cir->port]->rcr,
+ (unsigned)&cir_regs[cir->port]->tcr,
+ (unsigned)&cir_regs[cir->port]->bdlr,
+ (unsigned)&cir_regs[cir->port]->bdhr,
+ (unsigned)&cir_regs[cir->port]->tfsr,
+ (unsigned)&cir_regs[cir->port]->rfsr);
+}
+
+int cir_get_rx_count(struct cir_port *cir)
+{
+ return cir_regs[cir->port]->rfsr & CIR_RXFBC_MASK;
+}
+
+char cir_read_data(struct cir_port *cir)
+{
+ return cir_regs[cir->port]->dr;
+}
+
+char get_int_status(struct cir_port *cir)
+{
+ return cir_regs[cir->port]->iir;
+}
+#endif
diff --git a/arch/mips/ite-boards/generic/it8172_pci.c b/arch/mips/ite-boards/generic/it8172_pci.c
new file mode 100644
index 000000000..97eb6f1ee
--- /dev/null
+++ b/arch/mips/ite-boards/generic/it8172_pci.c
@@ -0,0 +1,276 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * IT8172 system controller specific pci support.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or support@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_pci.h>
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+#undef DEBUG
+#undef DEBUG_CONFIG_CYCLES
+
+static int
+it8172_pcibios_config_access(unsigned char access_type, struct pci_dev *dev,
+ unsigned char where, u32 *data)
+{
+ /*
+ * config cycles are on 4 byte boundary only
+ */
+ unsigned char bus = dev->bus->number;
+ unsigned char dev_fn = dev->devfn;
+
+#ifdef DEBUG_CONFIG_CYCLES
+ printk("it config: type %d dev %x bus %d dev_fn %x data %x\n",
+ access_type, dev, bus, dev_fn, *data);
+
+#endif
+
+ /* Setup address */
+ IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) |
+ (dev_fn << IT_FUNCNUM_SHF) | (where & ~0x3));
+
+
+ if (access_type == PCI_ACCESS_WRITE) {
+ IT_WRITE(IT_CONFDATA, *data);
+ }
+ else {
+ IT_READ(IT_CONFDATA, *data);
+ }
+
+ /*
+ * Revisit: check for master or target abort.
+ */
+ return 0;
+
+
+}
+
+
+/*
+ * We can't address 8 and 16 bit words directly. Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int
+it8172_pcibios_read_config_byte (struct pci_dev *dev, int where, u8 *val)
+{
+ u32 data = 0;
+
+ if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
+ return -1;
+
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+#ifdef DEBUG
+ printk("cfg read byte: bus %d dev_fn %x where %x: val %x\n",
+ dev->bus->number, dev->devfn, where, *val);
+#endif
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int
+it8172_pcibios_read_config_word (struct pci_dev *dev, int where, u16 *val)
+{
+ u32 data = 0;
+
+ if (where & 1)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
+ return -1;
+
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+#ifdef DEBUG
+ printk("cfg read word: bus %d dev_fn %x where %x: val %x\n",
+ dev->bus->number, dev->devfn, where, *val);
+#endif
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+it8172_pcibios_read_config_dword (struct pci_dev *dev, int where, u32 *val)
+{
+ u32 data = 0;
+
+ if (where & 3)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
+ return -1;
+
+ *val = data;
+#ifdef DEBUG
+ printk("cfg read dword: bus %d dev_fn %x where %x: val %x\n",
+ dev->bus->number, dev->devfn, where, *val);
+#endif
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int
+it8172_pcibios_write_config_byte (struct pci_dev *dev, int where, u8 val)
+{
+ u32 data = 0;
+
+ if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
+ return -1;
+
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+
+ if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
+ return -1;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+it8172_pcibios_write_config_word (struct pci_dev *dev, int where, u16 val)
+{
+ u32 data = 0;
+
+ if (where & 1)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
+ return -1;
+
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+
+ if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
+ return -1;
+
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+it8172_pcibios_write_config_dword(struct pci_dev *dev, int where, u32 val)
+{
+ if (where & 3)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &val))
+ return -1;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops it8172_pci_ops = {
+ it8172_pcibios_read_config_byte,
+ it8172_pcibios_read_config_word,
+ it8172_pcibios_read_config_dword,
+ it8172_pcibios_write_config_byte,
+ it8172_pcibios_write_config_word,
+ it8172_pcibios_write_config_dword
+};
+
+void __init pcibios_init(void)
+{
+
+ printk("PCI: Probing PCI hardware on host bus 0.\n");
+ pci_scan_bus(0, &it8172_pci_ops, NULL);
+}
+
+int __init
+pcibios_enable_device(struct pci_dev *dev)
+{
+ u16 cmd, old_cmd;
+ int idx;
+ struct resource *r;
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ old_cmd = cmd;
+ for(idx=0; idx<6; idx++) {
+ r = &dev->resource[idx];
+ if (!r->start && r->end) {
+ printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
+ return -EINVAL;
+ }
+ if (r->flags & IORESOURCE_IO)
+ cmd |= PCI_COMMAND_IO;
+ if (r->flags & IORESOURCE_MEM)
+ cmd |= PCI_COMMAND_MEMORY;
+ }
+ if (dev->resource[PCI_ROM_RESOURCE].start)
+ cmd |= PCI_COMMAND_MEMORY;
+ if (cmd != old_cmd) {
+ printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ }
+ return 0;
+}
+
+
+void __init
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+ printk("pcibios_align_resource\n");
+}
+
+char * __init
+pcibios_setup(char *str)
+{
+ /* Nothing to do for now. */
+
+ return str;
+}
+
+void __init
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+ struct resource *res, int resource)
+{
+ unsigned long where, size;
+ u32 reg;
+
+ where = PCI_BASE_ADDRESS_0 + (resource * 4);
+ size = res->end - res->start;
+ pci_read_config_dword(dev, where, &reg);
+ reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
+ pci_write_config_dword(dev, where, reg);
+}
+
+void __init pcibios_fixup_bus(struct pci_bus *b)
+{
+ printk("pcibios_fixup_bus\n");
+}
+#endif /* CONFIG_PCI */
diff --git a/arch/mips/ite-boards/generic/it8172_rtc.c b/arch/mips/ite-boards/generic/it8172_rtc.c
new file mode 100644
index 000000000..4ae1e7543
--- /dev/null
+++ b/arch/mips/ite-boards/generic/it8172_rtc.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or support@mvista.com
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * RTC routines for ITE8172 MC146818-compatible rtc chip.
+ *
+ */
+#include <asm/spinlock.h>
+#include <linux/mc146818rtc.h>
+#include <asm/it8172/it8172.h>
+
+#define IT8172_RTC_ADR_REG (IT8172_PCI_IO_BASE + IT_RTC_BASE)
+#define IT8172_RTC_DAT_REG (IT8172_RTC_ADR_REG + 1)
+
+static volatile char *rtc_adr_reg = KSEG1ADDR((volatile char *)IT8172_RTC_ADR_REG);
+static volatile char *rtc_dat_reg = KSEG1ADDR((volatile char *)IT8172_RTC_DAT_REG);
+
+unsigned char it8172_rtc_read_data(unsigned long addr)
+{
+ unsigned char retval;
+
+ *rtc_adr_reg = addr;
+ retval = *rtc_dat_reg;
+ return retval;
+}
+
+void it8172_rtc_write_data(unsigned char data, unsigned long addr)
+{
+ *rtc_adr_reg = addr;
+ *rtc_dat_reg = data;
+}
+
+static int it8172_rtc_bcd_mode(void)
+{
+ return 0;
+}
+
+struct rtc_ops it8172_rtc_ops = {
+ &it8172_rtc_read_data,
+ &it8172_rtc_write_data,
+ &it8172_rtc_bcd_mode
+};
diff --git a/arch/mips/ite-boards/generic/it8172_setup.c b/arch/mips/ite-boards/generic/it8172_setup.c
new file mode 100644
index 000000000..e111c71cc
--- /dev/null
+++ b/arch/mips/ite-boards/generic/it8172_setup.c
@@ -0,0 +1,311 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * IT8172/QED5231 board setup.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or support@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+#include <linux/serial_reg.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/it8172/it8172.h>
+#include <asm/it8712.h>
+#ifdef CONFIG_PC_KEYB
+#include <asm/keyboard.h>
+#endif
+
+#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
+extern void console_setup(char *, int *);
+char serial_console[20];
+#endif
+
+extern struct rtc_ops it8172_rtc_ops;
+extern struct resource ioport_resource;
+extern unsigned long mips_io_port_base;
+#ifdef CONFIG_BLK_DEV_IDE
+extern struct ide_ops std_ide_ops;
+extern struct ide_ops *ide_ops;
+#endif
+#ifdef CONFIG_PC_KEYB
+extern struct kbd_ops std_kbd_ops;
+int init_8712_keyboard(void);
+#endif
+
+extern int SearchIT8712(void);
+extern void InitLPCInterface(void);
+extern char * __init prom_getcmdline(void);
+extern void it8172_restart(void);
+extern void it8172_halt(void);
+extern void it8172_power_off(void);
+
+#ifdef CONFIG_IT8172_REVC
+struct {
+ struct resource ram;
+ struct resource pci_mem;
+ struct resource pci_io;
+ struct resource flash;
+ struct resource boot;
+} it8172_resources = {
+ { "RAM", 0, 0, IORESOURCE_MEM }, /* to be initted */
+ { "PCI Mem", 0x10000000, 0x13FFFFFF, IORESOURCE_MEM },
+ { "PCI I/O", 0x14000000, 0x17FFFFFF },
+ { "Flash", 0x08000000, 0x0CFFFFFF },
+ { "Boot ROM", 0x1FC00000, 0x1FFFFFFF }
+};
+#else
+struct {
+ struct resource ram;
+ struct resource pci_mem0;
+ struct resource pci_mem1;
+ struct resource pci_io;
+ struct resource pci_mem2;
+ struct resource pci_mem3;
+ struct resource flash;
+ struct resource boot;
+} it8172_resources = {
+ { "RAM", 0, 0, IORESOURCE_MEM }, /* to be initted */
+ { "PCI Mem0", 0x0C000000, 0x0FFFFFFF, IORESOURCE_MEM },
+ { "PCI Mem1", 0x10000000, 0x13FFFFFF, IORESOURCE_MEM },
+ { "PCI I/O", 0x14000000, 0x17FFFFFF },
+ { "PCI Mem2", 0x1A000000, 0x1BFFFFFF, IORESOURCE_MEM },
+ { "PCI Mem3", 0x1C000000, 0x1FBFFFFF, IORESOURCE_MEM },
+ { "Flash", 0x08000000, 0x0CFFFFFF },
+ { "Boot ROM", 0x1FC00000, 0x1FFFFFFF }
+};
+#endif
+
+
+void __init it8172_init_ram_resource(unsigned long memsize)
+{
+ it8172_resources.ram.end = memsize;
+}
+
+void __init it8172_setup(void)
+{
+#ifdef CONFIG_BLK_DEV_IT8172
+ unsigned short dsr;
+#endif
+ char *argptr;
+
+ argptr = prom_getcmdline();
+#ifdef CONFIG_SERIAL_CONSOLE
+ if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) {
+ strcpy(serial_console, "ttyS0,115200");
+ console_setup(serial_console, NULL);
+ }
+#endif
+
+ set_cp0_status(ST0_FR,0);
+ rtc_ops = &it8172_rtc_ops;
+
+ _machine_restart = it8172_restart;
+ _machine_halt = it8172_halt;
+ _machine_power_off = it8172_power_off;
+
+ /*
+ * IO/MEM resources.
+ *
+ * revisit this area.
+ */
+ mips_io_port_base = KSEG1;
+ ioport_resource.start = it8172_resources.pci_io.start;
+ ioport_resource.end = it8172_resources.pci_io.end;
+#ifdef CONFIG_IT8172_REVC
+ iomem_resource.start = it8172_resources.pci_mem.start;
+ iomem_resource.end = it8172_resources.pci_mem.end;
+#else
+ iomem_resource.start = it8172_resources.pci_mem0.start;
+ iomem_resource.end = it8172_resources.pci_mem3.end;
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+#endif
+
+#ifdef CONFIG_BLK_DEV_IT8172
+ /*
+ * Pull IDE device out of standby mode.
+ */
+ IT_IO_READ16(IT_PM_DSR, dsr);
+ dsr &= ~IT_PM_DSR_IDESB;
+ IT_IO_WRITE16(IT_PM_DSR, dsr);
+
+ ide_ops = &std_ide_ops;
+#endif
+
+#ifdef CONFIG_FB
+ conswitchp = &dummy_con;
+#endif
+
+ InitLPCInterface();
+
+#ifdef CONFIG_MIPS_ITE8172
+ if (SearchIT8712()) {
+ printk("Found IT8712 Super IO\n");
+ // enable IT8712 serial port
+ LPCSetConfig(LDN_SERIAL1, 0x30, 0x01); /* enable */
+ LPCSetConfig(LDN_SERIAL1, 0x23, 0x01); /* clock selection */
+#ifdef CONFIG_PC_KEYB
+ if (init_8712_keyboard()) {
+ printk("Unable to initialize keyboard\n");
+ LPCSetConfig(LDN_KEYBOARD, 0x30, 0x0); /* disable keyboard */
+ }
+ else {
+ LPCSetConfig(LDN_KEYBOARD, 0x30, 0x1); /* enable keyboard */
+ LPCSetConfig(LDN_KEYBOARD, 0xf0, 0x2);
+ LPCSetConfig(LDN_KEYBOARD, 0x71, 0x3);
+
+ LPCSetConfig(LDN_MOUSE, 0x30, 0x1); /* enable mouse */
+
+ LPCSetConfig(0x4, 0x30, 0x1);
+ LPCSetConfig(0x4, 0xf4, LPCGetConfig(0x4, 0xf4) | 0x80);
+
+ if ((LPCGetConfig(LDN_KEYBOARD, 0x30) == 0) ||
+ (LPCGetConfig(LDN_MOUSE, 0x30) == 0))
+ printk("Error: keyboard or mouse not enabled\n");
+
+ kbd_ops = &std_kbd_ops;
+ }
+#endif
+ }
+ else {
+ printk("IT8712 Super IO not found\n");
+ }
+#endif
+
+#ifdef CONFIG_IT8172_CIR
+ {
+ unsigned long data;
+ //printk("Enabling CIR0\n");
+ IT_IO_READ16(IT_PM_DSR, data);
+ data &= ~IT_PM_DSR_CIR0SB;
+ IT_IO_WRITE16(IT_PM_DSR, data);
+ //printk("DSR register: %x\n", (unsigned)IT_IO_READ16(IT_PM_DSR, data));
+ }
+#endif
+#ifdef CONFIG_IT8172_SCR0
+ {
+ unsigned i;
+ /* Enable Smart Card Reader 0 */
+ /* First power it up */
+ IT_IO_READ16(IT_PM_DSR, i);
+ i &= ~IT_PM_DSR_SCR0SB;
+ IT_IO_WRITE16(IT_PM_DSR, i);
+ /* Then initialize its registers */
+ outb(( IT_SCR_SFR_GATE_UART_OFF << IT_SCR_SFR_GATE_UART_BIT
+ |IT_SCR_SFR_FET_CHARGE_213_US << IT_SCR_SFR_FET_CHARGE_BIT
+ |IT_SCR_SFR_CARD_FREQ_3_5_MHZ << IT_SCR_SFR_CARD_FREQ_BIT
+ |IT_SCR_SFR_FET_ACTIVE_INVERT << IT_SCR_SFR_FET_ACTIVE_BIT
+ |IT_SCR_SFR_ENABLE_ON << IT_SCR_SFR_ENABLE_BIT),
+ IT8172_PCI_IO_BASE + IT_SCR0_BASE + IT_SCR_SFR);
+ outb(IT_SCR_SCDR_RESET_MODE_ASYNC << IT_SCR_SCDR_RESET_MODE_BIT,
+ IT8172_PCI_IO_BASE + IT_SCR0_BASE + IT_SCR_SCDR);
+ }
+#endif /* CONFIG_IT8172_SCR0 */
+#ifdef CONFIG_IT8172_SCR1
+ {
+ unsigned i;
+ /* Enable Smart Card Reader 1 */
+ /* First power it up */
+ IT_IO_READ16(IT_PM_DSR, i);
+ i &= ~IT_PM_DSR_SCR1SB;
+ IT_IO_WRITE16(IT_PM_DSR, i);
+ /* Then initialize its registers */
+ outb(( IT_SCR_SFR_GATE_UART_OFF << IT_SCR_SFR_GATE_UART_BIT
+ |IT_SCR_SFR_FET_CHARGE_213_US << IT_SCR_SFR_FET_CHARGE_BIT
+ |IT_SCR_SFR_CARD_FREQ_3_5_MHZ << IT_SCR_SFR_CARD_FREQ_BIT
+ |IT_SCR_SFR_FET_ACTIVE_INVERT << IT_SCR_SFR_FET_ACTIVE_BIT
+ |IT_SCR_SFR_ENABLE_ON << IT_SCR_SFR_ENABLE_BIT),
+ IT8172_PCI_IO_BASE + IT_SCR1_BASE + IT_SCR_SFR);
+ outb(IT_SCR_SCDR_RESET_MODE_ASYNC << IT_SCR_SCDR_RESET_MODE_BIT,
+ IT8172_PCI_IO_BASE + IT_SCR1_BASE + IT_SCR_SCDR);
+ }
+#endif /* CONFIG_IT8172_SCR1 */
+}
+
+
+#ifdef CONFIG_PC_KEYB
+/*
+ * According to the ITE Special BIOS Note for waking up the
+ * keyboard controller...
+ */
+int init_8712_keyboard()
+{
+ unsigned int cmd_port = 0x14000064;
+ unsigned int data_port = 0x14000060;
+ unsigned char data;
+ int i;
+
+ printk("8712 keyboard init");
+
+ outb(0xaa, cmd_port); /* send self-test cmd */
+ i = 0;
+ while (!(inb(cmd_port) & 0x1)) { /* wait output buffer full */
+ i++;
+ if (i > 0xffffff)
+ return 1;
+ }
+
+ data = inb(data_port);
+ outb(0xcb, cmd_port); /* set ps2 mode */
+ while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
+ i++;
+ if (i > 0xffffff)
+ return 1;
+ }
+ outb(0x01, data_port);
+ while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
+ i++;
+ if (i > 0xffffff)
+ return 1;
+ }
+
+ outb(0x60, cmd_port); /* write 8042 command byte */
+ while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
+ i++;
+ if (i > 0xffffff)
+ return 1;
+ }
+ outb(0x45, data_port); /* at interface, keyboard enabled, system flag */
+ while (inb(cmd_port) & 0x2) { /* wait while input buffer full */
+ i++;
+ if (i > 0xffffff)
+ return 1;
+ }
+
+ outb(0xae, cmd_port); /* enable interface */
+ return 0;
+}
+#endif
diff --git a/arch/mips/ite-boards/generic/lpc.c b/arch/mips/ite-boards/generic/lpc.c
new file mode 100644
index 000000000..0887c6354
--- /dev/null
+++ b/arch/mips/ite-boards/generic/lpc.c
@@ -0,0 +1,144 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * ITE Semi IT8712 Super I/O functions.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or support@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <asm/io.h>
+#include <asm/types.h>
+#include <asm/it8712.h>
+#include <asm/it8172/it8172.h>
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+void LPCEnterMBPnP()
+{
+ int i;
+ unsigned char key[4] = {0x87, 0x01, 0x55, 0x55};
+
+ for (i = 0; i<4; i++)
+ outb(key[i], LPC_KEY_ADDR);
+
+}
+
+void LPCExitMBPnP()
+{
+ outb(0x02, LPC_KEY_ADDR);
+ outb(0x02, LPC_DATA_ADDR);
+}
+
+void LPCSetConfig(char LdnNumber, char Index, char data)
+{
+ LPCEnterMBPnP(); // Enter IT8712 MB PnP mode
+ outb(0x07, LPC_KEY_ADDR);
+ outb(LdnNumber, LPC_DATA_ADDR);
+ outb(Index, LPC_KEY_ADDR);
+ outb(data, LPC_DATA_ADDR);
+ LPCExitMBPnP();
+}
+
+char LPCGetConfig(char LdnNumber, char Index)
+{
+ char rtn;
+
+ LPCEnterMBPnP(); // Enter IT8712 MB PnP mode
+ outb(0x07, LPC_KEY_ADDR);
+ outb(LdnNumber, LPC_DATA_ADDR);
+ outb(Index, LPC_KEY_ADDR);
+ rtn = inb(LPC_DATA_ADDR);
+ LPCExitMBPnP();
+ return rtn;
+}
+
+int SearchIT8712()
+{
+ unsigned char Id1, Id2;
+ unsigned short Id;
+
+ LPCEnterMBPnP();
+ outb(0x20, LPC_KEY_ADDR); /* chip id byte 1 */
+ Id1 = inb(LPC_DATA_ADDR);
+ outb(0x21, LPC_KEY_ADDR); /* chip id byte 2 */
+ Id2 = inb(LPC_DATA_ADDR);
+ Id = (Id1 << 8) | Id2;
+ LPCExitMBPnP();
+ if (Id == 0x8712)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void InitLPCInterface()
+{
+ unsigned char bus, dev_fn;
+ unsigned long data;
+
+ bus = 0;
+ dev_fn = 1<<3 | 4;
+
+
+ /* pci cmd, SERR# Enable */
+ IT_WRITE(IT_CONFADDR,
+ (bus << IT_BUSNUM_SHF) |
+ (dev_fn << IT_FUNCNUM_SHF) |
+ ((0x4 / 4) << IT_REGNUM_SHF));
+ IT_READ(IT_CONFDATA, data);
+ data |= 0x0100;
+ IT_WRITE(IT_CONFADDR,
+ (bus << IT_BUSNUM_SHF) |
+ (dev_fn << IT_FUNCNUM_SHF) |
+ ((0x4 / 4) << IT_REGNUM_SHF));
+ IT_WRITE(IT_CONFDATA, data);
+
+ /* setup serial irq control register */
+ IT_WRITE(IT_CONFADDR,
+ (bus << IT_BUSNUM_SHF) |
+ (dev_fn << IT_FUNCNUM_SHF) |
+ ((0x48 / 4) << IT_REGNUM_SHF));
+ IT_READ(IT_CONFDATA, data);
+ data = (data & 0xffff00ff) | 0xc400;
+ IT_WRITE(IT_CONFADDR,
+ (bus << IT_BUSNUM_SHF) |
+ (dev_fn << IT_FUNCNUM_SHF) |
+ ((0x48 / 4) << IT_REGNUM_SHF));
+ IT_WRITE(IT_CONFDATA, data);
+
+
+ /* Enable I/O Space Subtractive Decode */
+ /* default 0x4C is 0x3f220000 */
+ IT_WRITE(IT_CONFADDR,
+ (bus << IT_BUSNUM_SHF) |
+ (dev_fn << IT_FUNCNUM_SHF) |
+ ((0x4C / 4) << IT_REGNUM_SHF));
+ IT_WRITE(IT_CONFDATA, 0x3f2200f3);
+}
diff --git a/arch/mips/ite-boards/generic/pmon_prom.c b/arch/mips/ite-boards/generic/pmon_prom.c
new file mode 100644
index 000000000..695e68e5d
--- /dev/null
+++ b/arch/mips/ite-boards/generic/pmon_prom.c
@@ -0,0 +1,139 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * PROM library initialisation code, assuming a version of
+ * pmon is the boot code.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or support@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/xx files.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+/* #define DEBUG_CMDLINE */
+
+char arcs_cmdline[COMMAND_LINE_SIZE];
+int prom_argc;
+char **prom_argv, **prom_envp;
+
+typedef struct
+{
+ char *name;
+/* char *val; */
+}t_env_var;
+
+
+char * __init prom_getcmdline(void)
+{
+ return &(arcs_cmdline[0]);
+}
+
+void __init prom_init_cmdline(void)
+{
+ char *cp;
+ int actr;
+
+ actr = 1; /* Always ignore argv[0] */
+
+ cp = &(arcs_cmdline[0]);
+ while(actr < prom_argc) {
+ strcpy(cp, prom_argv[actr]);
+ cp += strlen(prom_argv[actr]);
+ *cp++ = ' ';
+ actr++;
+ }
+ if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+ --cp;
+ *cp = '\0';
+
+}
+
+
+char *prom_getenv(char *envname)
+{
+ /*
+ * Return a pointer to the given environment variable.
+ * Environment variables are stored in the form of "memsize=64".
+ */
+
+ t_env_var *env = (t_env_var *)prom_envp;
+ int i;
+
+ i = strlen(envname);
+
+ while(env->name) {
+ if(strncmp(envname, env->name, i) == 0) {
+ return(env->name + strlen(envname) + 1);
+ }
+ env++;
+ }
+ return(NULL);
+}
+
+static inline unsigned char str2hexnum(unsigned char c)
+{
+ if(c >= '0' && c <= '9')
+ return c - '0';
+ if(c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ return 0; /* foo */
+}
+
+int __init page_is_ram(unsigned long pagenr)
+{
+ return 1;
+}
+
+void prom_free_prom_memory (void)
+{
+}
+
+unsigned long __init prom_get_memsize(void)
+{
+ char *memsize_str;
+ unsigned int memsize;
+
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str) {
+ printk("memsize unknown: setting to 32MB\n");
+ memsize = 32;
+ } else {
+#ifdef DEBUG
+ printk("prom_memsize: %s\n", memsize_str);
+#endif
+ memsize = simple_strtol(memsize_str, NULL, 0);
+ }
+ return memsize;
+}
diff --git a/arch/mips/ite-boards/generic/puts.c b/arch/mips/ite-boards/generic/puts.c
new file mode 100644
index 000000000..4ff7ebffc
--- /dev/null
+++ b/arch/mips/ite-boards/generic/puts.c
@@ -0,0 +1,144 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Low level uart routines to directly access a 16550 uart.
+ *
+ * Copyright 2000,2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or support@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+
+#define SERIAL_BASE 0xB4011800 /* it8172 */
+#define SER_CMD 5
+#define SER_DATA 0x00
+#define TX_BUSY 0x20
+
+#define TIMEOUT 0xffff
+#undef SLOW_DOWN
+
+static const char digits[16] = "0123456789abcdef";
+static volatile unsigned char * const com1 = (unsigned char *)SERIAL_BASE;
+
+
+#ifdef SLOW_DOWN
+static inline void slow_down()
+{
+ int k;
+ for (k=0; k<10000; k++);
+}
+#else
+#define slow_down()
+#endif
+
+void
+putch(const unsigned char c)
+{
+ unsigned char ch;
+ int i = 0;
+
+ do {
+ ch = com1[SER_CMD];
+ slow_down();
+ i++;
+ if (i>TIMEOUT) {
+ break;
+ }
+ } while (0 == (ch & TX_BUSY));
+ com1[SER_DATA] = c;
+}
+
+void
+puts(unsigned char *cp)
+{
+ unsigned char ch;
+ int i = 0;
+
+ while (*cp) {
+ do {
+ ch = com1[SER_CMD];
+ slow_down();
+ i++;
+ if (i>TIMEOUT) {
+ break;
+ }
+ } while (0 == (ch & TX_BUSY));
+ com1[SER_DATA] = *cp++;
+ }
+ putch('\r');
+ putch('\n');
+}
+
+void
+fputs(unsigned char *cp)
+{
+ unsigned char ch;
+ int i = 0;
+
+ while (*cp) {
+
+ do {
+ ch = com1[SER_CMD];
+ slow_down();
+ i++;
+ if (i>TIMEOUT) {
+ break;
+ }
+ } while (0 == (ch & TX_BUSY));
+ com1[SER_DATA] = *cp++;
+ }
+}
+
+
+void
+put64(uint64_t ul)
+{
+ int cnt;
+ unsigned ch;
+
+ cnt = 16; /* 16 nibbles in a 64 bit long */
+ putch('0');
+ putch('x');
+ do {
+ cnt--;
+ ch = (unsigned char)(ul >> cnt * 4) & 0x0F;
+ putch(digits[ch]);
+ } while (cnt > 0);
+}
+
+void
+put32(unsigned u)
+{
+ int cnt;
+ unsigned ch;
+
+ cnt = 8; /* 8 nibbles in a 32 bit long */
+ putch('0');
+ putch('x');
+ do {
+ cnt--;
+ ch = (unsigned char)(u >> cnt * 4) & 0x0F;
+ putch(digits[ch]);
+ } while (cnt > 0);
+}
diff --git a/arch/mips/ite-boards/generic/reset.c b/arch/mips/ite-boards/generic/reset.c
new file mode 100644
index 000000000..22bcf79ff
--- /dev/null
+++ b/arch/mips/ite-boards/generic/reset.c
@@ -0,0 +1,61 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * ITE 8172 reset routines.
+ *
+ * Copyright (C) 1997, 2001 Ralf Baechle
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or support@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+void it8172_restart(char *command)
+{
+ set_cp0_status((ST0_BEV | ST0_ERL), (ST0_BEV | ST0_ERL));
+ set_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+ flush_cache_all();
+ write_32bit_cp0_register(CP0_WIRED, 0);
+ __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+void it8172_halt(void)
+{
+ printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+ while (1)
+ __asm__(".set\tmips3\n\t"
+ "wait\n\t"
+ ".set\tmips0");
+}
+
+void it8172_power_off(void)
+{
+ it8172_halt();
+}
diff --git a/arch/mips/ite-boards/generic/time.c b/arch/mips/ite-boards/generic/time.c
new file mode 100644
index 000000000..fc294490b
--- /dev/null
+++ b/arch/mips/ite-boards/generic/time.c
@@ -0,0 +1,379 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Setting up the clock on the MIPS boards.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+
+#include <asm/mipsregs.h>
+#include <asm/ptrace.h>
+#include <asm/it8172/it8172_int.h>
+
+#include <linux/mc146818rtc.h>
+#include <linux/timex.h>
+
+extern void enable_cpu_timer(void);
+extern volatile unsigned long wall_jiffies;
+extern rwlock_t xtime_lock;
+
+unsigned long missed_heart_beats = 0;
+static long last_rtc_update = 0;
+static unsigned long r4k_offset; /* Amount to increment compare reg each time */
+static unsigned long r4k_cur; /* What counter should be at next timer irq */
+static unsigned int timer_tick_count=0;
+
+static inline void ack_r4ktimer(unsigned long newval)
+{
+ write_32bit_cp0_register(CP0_COMPARE, newval);
+}
+
+
+/*
+ * In order to set the CMOS clock precisely, set_rtc_mmss has to be
+ * called 500 ms after the second nowtime has started, because when
+ * nowtime is written into the registers of the CMOS clock, it will
+ * jump to the next second precisely 500 ms later. Check the Motorola
+ * MC146818A or Dallas DS12887 data sheet for details.
+ *
+ * BUG: This routine does not handle hour overflow properly; it just
+ * sets the minutes. Usually you won't notice until after reboot!
+ */
+static int set_rtc_mmss(unsigned long nowtime)
+{
+ int retval = 0;
+ int real_seconds, real_minutes, cmos_minutes;
+ unsigned char save_control, save_freq_select;
+
+ save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
+ CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
+
+ save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
+ CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+ cmos_minutes = CMOS_READ(RTC_MINUTES);
+
+ /*
+ * since we're only adjusting minutes and seconds,
+ * don't interfere with hour overflow. This avoids
+ * messing with unknown time zones but requires your
+ * RTC not to be off by more than 15 minutes
+ */
+ real_seconds = nowtime % 60;
+ real_minutes = nowtime / 60;
+ if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+ real_minutes += 30; /* correct for half hour time zone */
+ real_minutes %= 60;
+
+ if (abs(real_minutes - cmos_minutes) < 30) {
+ CMOS_WRITE(real_seconds,RTC_SECONDS);
+ CMOS_WRITE(real_minutes,RTC_MINUTES);
+ } else {
+ printk(KERN_WARNING
+ "set_rtc_mmss: can't update from %d to %d\n",
+ cmos_minutes, real_minutes);
+ retval = -1;
+ }
+
+ /* The following flags have to be released exactly in this order,
+ * otherwise the DS12887 (popular MC146818A clone with integrated
+ * battery and quartz) will not reset the oscillator and will not
+ * update precisely 500 ms later. You won't find this mentioned in
+ * the Dallas Semiconductor data sheets, but who believes data
+ * sheets anyway ... -- Markus Kuhn
+ */
+ CMOS_WRITE(save_control, RTC_CONTROL);
+ CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+
+ return retval;
+}
+
+
+/*
+ * There are a lot of conceptually broken versions of the MIPS timer interrupt
+ * handler floating around. This one is rather different, but the algorithm
+ * is provably more robust.
+ */
+void mips_timer_interrupt(struct pt_regs *regs)
+{
+ if (r4k_offset == 0)
+ goto null;
+
+ do {
+ kstat.irqs[0][MIPS_CPU_TIMER_IRQ]++;
+ do_timer(regs);
+
+ /* Historical comment/code:
+ * RTC time of day s updated approx. every 11
+ * minutes. Because of how the numbers work out
+ * we need to make absolutely sure we do this update
+ * within 500ms before the * next second starts,
+ * thus the following code.
+ */
+ read_lock(&xtime_lock);
+ if ((time_status & STA_UNSYNC) == 0
+ && 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 {
+ /* do it again in 60 s */
+ last_rtc_update = xtime.tv_sec - 600;
+ }
+ read_unlock(&xtime_lock);
+
+ r4k_cur += r4k_offset;
+ ack_r4ktimer(r4k_cur);
+
+ } while (((unsigned long)read_32bit_cp0_register(CP0_COUNT)
+ - r4k_cur) < 0x7fffffff);
+
+ return;
+
+null:
+ ack_r4ktimer(0);
+}
+
+/*
+ * Figure out the r4k offset, the amount to increment the compare
+ * register for each time tick.
+ * Use the RTC to calculate offset.
+ */
+static unsigned long __init cal_r4koff(void)
+{
+ unsigned long count;
+ unsigned int flags;
+
+ __save_and_cli(flags);
+
+ /* Start counter exactly on falling edge of update flag */
+ while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+ while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+ /* Start r4k counter. */
+ write_32bit_cp0_register(CP0_COUNT, 0);
+
+ /* Read counter exactly on falling edge of update flag */
+ while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+ while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+ count = read_32bit_cp0_register(CP0_COUNT);
+
+ /* restore interrupts */
+ __restore_flags(flags);
+
+ return (count / HZ);
+}
+
+static unsigned long __init get_mips_time(void)
+{
+ unsigned int year, mon, day, hour, min, sec;
+ unsigned char save_control;
+
+ save_control = CMOS_READ(RTC_CONTROL);
+
+ /* Freeze it. */
+ CMOS_WRITE(save_control | RTC_SET, RTC_CONTROL);
+
+ /* Read regs. */
+ sec = CMOS_READ(RTC_SECONDS);
+ min = CMOS_READ(RTC_MINUTES);
+ hour = CMOS_READ(RTC_HOURS);
+
+ if (!(save_control & RTC_24H))
+ {
+ if ((hour & 0xf) == 0xc)
+ hour &= 0x80;
+ if (hour & 0x80)
+ hour = (hour & 0xf) + 12;
+ }
+ day = CMOS_READ(RTC_DAY_OF_MONTH);
+ mon = CMOS_READ(RTC_MONTH);
+ year = CMOS_READ(RTC_YEAR);
+
+ /* Unfreeze clock. */
+ CMOS_WRITE(save_control, RTC_CONTROL);
+
+ if ((year += 1900) < 1970)
+ year += 100;
+
+ return mktime(year, mon, day, hour, min, sec);
+}
+
+void __init time_init(void)
+{
+ unsigned int est_freq, flags;
+
+ /* Set Data mode - binary. */
+ CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
+
+ printk("calculating r4koff... ");
+ r4k_offset = cal_r4koff();
+ printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
+
+ est_freq = 2*r4k_offset*HZ;
+ est_freq += 5000; /* round */
+ est_freq -= est_freq%10000;
+ printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
+ (est_freq%1000000)*100/1000000);
+ r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
+
+ write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
+
+ enable_cpu_timer();
+
+ /* Read time from the RTC chipset. */
+ write_lock_irqsave (&xtime_lock, flags);
+ xtime.tv_sec = get_mips_time();
+ xtime.tv_usec = 0;
+ write_unlock_irqrestore(&xtime_lock, flags);
+}
+
+/* This is for machines which generate the exact clock. */
+#define USECS_PER_JIFFY (1000000/HZ)
+
+/* Cycle counter value at the previous timer interrupt.. */
+
+static unsigned int timerhi = 0, timerlo = 0;
+
+/*
+ * FIXME: Does playing with the RP bit in c0_status interfere with this code?
+ */
+static unsigned long do_fast_gettimeoffset(void)
+{
+ u32 count;
+ unsigned long res, tmp;
+
+ /* Last jiffy when do_fast_gettimeoffset() was called. */
+ static unsigned long last_jiffies=0;
+ unsigned long quotient;
+
+ /*
+ * Cached "1/(clocks per usec)*2^32" value.
+ * It has to be recalculated once each jiffy.
+ */
+ static unsigned long cached_quotient=0;
+
+ tmp = jiffies;
+
+ quotient = cached_quotient;
+
+ if (tmp && last_jiffies != tmp) {
+ last_jiffies = tmp;
+ __asm__(".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ ".set\tmips3\n\t"
+ "lwu\t%0,%2\n\t"
+ "dsll32\t$1,%1,0\n\t"
+ "or\t$1,$1,%0\n\t"
+ "ddivu\t$0,$1,%3\n\t"
+ "mflo\t$1\n\t"
+ "dsll32\t%0,%4,0\n\t"
+ "nop\n\t"
+ "ddivu\t$0,%0,$1\n\t"
+ "mflo\t%0\n\t"
+ ".set\tmips0\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=&r" (quotient)
+ :"r" (timerhi),
+ "m" (timerlo),
+ "r" (tmp),
+ "r" (USECS_PER_JIFFY)
+ :"$1");
+ cached_quotient = quotient;
+ }
+
+ /* Get last timer tick in absolute kernel time */
+ count = read_32bit_cp0_register(CP0_COUNT);
+
+ /* .. relative to previous jiffy (32 bits is enough) */
+ count -= timerlo;
+
+ __asm__("multu\t%1,%2\n\t"
+ "mfhi\t%0"
+ :"=r" (res)
+ :"r" (count),
+ "r" (quotient));
+
+ /*
+ * Due to possible jiffies inconsistencies, we need to check
+ * the result so that we'll get a timer that is monotonic.
+ */
+ if (res >= USECS_PER_JIFFY)
+ res = USECS_PER_JIFFY-1;
+
+ return res;
+}
+
+void do_gettimeofday(struct timeval *tv)
+{
+ unsigned int flags;
+
+ read_lock_irqsave (&xtime_lock, flags);
+ *tv = xtime;
+ tv->tv_usec += do_fast_gettimeoffset();
+
+ /*
+ * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
+ * 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);
+
+ 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_fast_gettimeoffset();
+
+ if (tv->tv_usec < 0) {
+ tv->tv_usec += 1000000;
+ tv->tv_sec--;
+ }
+
+ xtime = *tv;
+ time_adjust = 0; /* stop active adjtime() */
+ time_status |= STA_UNSYNC;
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_esterror = NTP_PHASE_LIMIT;
+
+ write_unlock_irq (&xtime_lock);
+}
diff --git a/arch/mips/ite-boards/qed-4n-s01b/.cvsignore b/arch/mips/ite-boards/qed-4n-s01b/.cvsignore
new file mode 100644
index 000000000..857dd22e9
--- /dev/null
+++ b/arch/mips/ite-boards/qed-4n-s01b/.cvsignore
@@ -0,0 +1,2 @@
+.depend
+.*.flags
diff --git a/arch/mips/ite-boards/qed-4n-s01b/Makefile b/arch/mips/ite-boards/qed-4n-s01b/Makefile
new file mode 100644
index 000000000..3929a0c34
--- /dev/null
+++ b/arch/mips/ite-boards/qed-4n-s01b/Makefile
@@ -0,0 +1,37 @@
+#
+# Copyright 2000 MontaVista Software Inc.
+# Author: MontaVista Software, Inc.
+# ppopov@mvista.com or support@mvista.com
+#
+# Makefile for the ITE 8172 (qed-4n-s01b) board, board
+# specific files.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+all: ite.o
+
+O_TARGET := ite.o
+
+obj-y := init.o
+
+ifdef CONFIG_PCI
+obj-y += pci_fixup.o
+endif
+
+ifdef CONFIG_BLK_DEV_INITRD
+obj-y += le_ramdisk.o
+endif
+
+
+dep:
+ $(CPP) -M *.c > .depend
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/ite-boards/qed-4n-s01b/README b/arch/mips/ite-boards/qed-4n-s01b/README
new file mode 100644
index 000000000..fb4b5197e
--- /dev/null
+++ b/arch/mips/ite-boards/qed-4n-s01b/README
@@ -0,0 +1,2 @@
+This is an ITE (www.iteusa.com) eval board for the ITE 8172G
+system controller, with a QED 5231 CPU.
diff --git a/arch/mips/ite-boards/qed-4n-s01b/init.c b/arch/mips/ite-boards/qed-4n-s01b/init.c
new file mode 100644
index 000000000..5599b31dc
--- /dev/null
+++ b/arch/mips/ite-boards/qed-4n-s01b/init.c
@@ -0,0 +1,89 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * IT8172/QED5231 board setup.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or support@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_dbg.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+
+extern char _end;
+extern void __init prom_init_cmdline(void);
+extern unsigned long __init prom_get_memsize(void);
+extern void __init it8172_init_ram_resource(unsigned long memsize);
+
+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
+
+int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
+{
+ unsigned long mem_size, free_start, free_end, bootmap_size;
+ unsigned long pcicr;
+
+ prom_argc = argc;
+ prom_argv = argv;
+ prom_envp = envp;
+
+ puts("ITE board running...");
+
+ mips_machgroup = MACH_GROUP_ITE;
+ mips_machtype = MACH_QED_4N_S01B; /* ITE board name/number */
+
+ prom_init_cmdline();
+ mem_size = prom_get_memsize();
+
+ printk("Memory size: %dMB\n", (unsigned)mem_size);
+
+ mem_size <<= 20; /* MB */
+
+ /*
+ * make the entire physical memory visible to pci bus masters
+ */
+ IT_READ(IT_MC_PCICR, pcicr);
+ pcicr &= ~0x1f;
+ pcicr |= (mem_size - 1) >> 22;
+ IT_WRITE(IT_MC_PCICR, pcicr);
+
+ it8172_init_ram_resource(mem_size);
+ add_memory_region(0, 20 << 20, BOOT_MEM_RAM);
+
+ return 0;
+}
diff --git a/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c b/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c
new file mode 100644
index 000000000..befceffa3
--- /dev/null
+++ b/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c
@@ -0,0 +1,197 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Board specific pci fixups.
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or support@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/it8172/it8172.h>
+#include <asm/it8172/it8172_pci.h>
+#include <asm/it8172/it8172_int.h>
+
+void __init board_int_line_fixup(struct pci_dev *dev)
+{
+ unsigned int slot, func;
+ unsigned char pin;
+ const int internal_func_irqs[7] = {
+ IT8172_AC97_IRQ,
+ IT8172_DMA_IRQ,
+ IT8172_CDMA_IRQ,
+ IT8172_USB_IRQ,
+ IT8172_BRIDGE_MASTER_IRQ,
+ IT8172_IDE_IRQ,
+ IT8172_MC68K_IRQ
+ };
+
+#ifdef DEBUG
+ printk("board_int_line_fixup bus %d\n", dev->bus->number);
+#endif
+ if (dev->bus->number != 0)
+ return;
+
+ pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+
+#ifdef DEBUG
+ pci_read_config_dword(dev, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
+#endif
+
+ slot = PCI_SLOT(dev->devfn);
+ func = PCI_FUNC(dev->devfn);
+
+ switch (slot) {
+ case 0x01:
+ /*
+ * Internal device 1 is actually 7 different internal
+ * devices on the IT8172G (a multi-function device).
+ */
+ if (func < 7)
+ dev->irq = internal_func_irqs[func];
+ break;
+ case 0x10:
+ switch (pin) {
+ case 1: /* pin A */
+ dev->irq = IT8172_PCI_INTA_IRQ;
+ break;
+ case 2: /* pin B */
+ dev->irq = IT8172_PCI_INTB_IRQ;
+ break;
+ case 3: /* pin C */
+ dev->irq = IT8172_PCI_INTC_IRQ;
+ break;
+ case 4: /* pin D */
+ dev->irq = IT8172_PCI_INTD_IRQ;
+ break;
+ default:
+ dev->irq = 0xff;
+ break;
+
+ }
+ break;
+ case 0x11:
+ switch (pin) {
+ case 1: /* pin A */
+ dev->irq = IT8172_PCI_INTA_IRQ;
+ break;
+ case 2: /* pin B */
+ dev->irq = IT8172_PCI_INTB_IRQ;
+ break;
+ case 3: /* pin C */
+ dev->irq = IT8172_PCI_INTC_IRQ;
+ break;
+ case 4: /* pin D */
+ dev->irq = IT8172_PCI_INTD_IRQ;
+ break;
+ default:
+ dev->irq = 0xff;
+ break;
+
+ }
+ break;
+ case 0x12:
+ switch (pin) {
+ case 1: /* pin A */
+ dev->irq = IT8172_PCI_INTB_IRQ;
+ break;
+ case 2: /* pin B */
+ dev->irq = IT8172_PCI_INTC_IRQ;
+ break;
+ case 3: /* pin C */
+ dev->irq = IT8172_PCI_INTD_IRQ;
+ break;
+ case 4: /* pin D */
+ dev->irq = IT8172_PCI_INTA_IRQ;
+ break;
+ default:
+ dev->irq = 0xff;
+ break;
+
+ }
+ break;
+ case 0x13:
+ switch (pin) {
+ case 1: /* pin A */
+ dev->irq = IT8172_PCI_INTC_IRQ;
+ break;
+ case 2: /* pin B */
+ dev->irq = IT8172_PCI_INTD_IRQ;
+ break;
+ case 3: /* pin C */
+ dev->irq = IT8172_PCI_INTA_IRQ;
+ break;
+ case 4: /* pin D */
+ dev->irq = IT8172_PCI_INTB_IRQ;
+ break;
+ default:
+ dev->irq = 0xff;
+ break;
+
+ }
+ break;
+ case 0x14:
+ switch (pin) {
+ case 1: /* pin A */
+ dev->irq = IT8172_PCI_INTD_IRQ;
+ break;
+ case 2: /* pin B */
+ dev->irq = IT8172_PCI_INTA_IRQ;
+ break;
+ case 3: /* pin C */
+ dev->irq = IT8172_PCI_INTB_IRQ;
+ break;
+ case 4: /* pin D */
+ dev->irq = IT8172_PCI_INTC_IRQ;
+ break;
+ default:
+ dev->irq = 0xff;
+ break;
+
+ }
+ break;
+ default:
+ return;
+ }
+
+#ifdef DEBUG
+ printk("irq fixup: slot %d, vendor %x, int line %d, int number %d\n",
+ slot, vendor, pin, dev->irq);
+#endif
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+
+}
+
+struct pci_fixup pcibios_fixups[] = {
+ { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, board_int_line_fixup },
+ { 0 }
+};
+#endif