rename and renumber storm patches
[openwrt/openwrt.git] / target / linux / storm / patches / 001-arch.patch
diff --git a/target/linux/storm/patches/001-arch.patch b/target/linux/storm/patches/001-arch.patch
new file mode 100644 (file)
index 0000000..b0461d4
--- /dev/null
@@ -0,0 +1,8864 @@
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -220,6 +220,9 @@
+       help
+         This enables support for the Cirrus EP93xx series of CPUs.
++config ARCH_SL2312
++    bool "SL2312"
++
+ config ARCH_FOOTBRIDGE
+       bool "FootBridge"
+       select FOOTBRIDGE
+@@ -414,6 +417,8 @@
+ source "arch/arm/mach-footbridge/Kconfig"
++source "arch/arm/mach-sl2312/Kconfig"
++
+ source "arch/arm/mach-integrator/Kconfig"
+ source "arch/arm/mach-iop32x/Kconfig"
+@@ -549,6 +554,16 @@
+ config PCI_SYSCALL
+       def_bool PCI
++config SL2312_LPC
++    bool "LPC Host Support"
++    depends on ARCH_SL2312
++    help
++
++config SL2312_LPC_IT8712
++    bool "IT8712 Support"
++    depends on ARCH_SL2312 && SL2312_LPC
++    help
++
+ # Select the host bridge type
+ config PCI_HOST_VIA82C505
+       bool
+@@ -988,6 +1003,10 @@
+ source "drivers/mtd/Kconfig"
+ endif
++if ARCH_SL2312
++source "drivers/telephony/Kconfig"
++endif
++
+ source "drivers/parport/Kconfig"
+ source "drivers/pnp/Kconfig"
+@@ -997,7 +1016,7 @@
+ if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \
+       || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
+       || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
+-      || ARCH_IXP23XX
++      || ARCH_IXP23XX || ARCH_SL2312
+ source "drivers/ide/Kconfig"
+ endif
+--- a/arch/arm/Makefile
++++ b/arch/arm/Makefile
+@@ -72,6 +72,7 @@
+ tune-$(CONFIG_CPU_ARM922T)    :=-mtune=arm9tdmi
+ tune-$(CONFIG_CPU_ARM925T)    :=-mtune=arm9tdmi
+ tune-$(CONFIG_CPU_ARM926T)    :=-mtune=arm9tdmi
++tune-$(CONFIG_CPU_FA52X)    :=-mtune=arm9tdmi
+ tune-$(CONFIG_CPU_SA110)      :=-mtune=strongarm110
+ tune-$(CONFIG_CPU_SA1100)     :=-mtune=strongarm1100
+ tune-$(CONFIG_CPU_XSCALE)     :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
+@@ -111,6 +112,7 @@
+  machine-$(CONFIG_ARCH_PXA)      := pxa
+  machine-$(CONFIG_ARCH_L7200)    := l7200
+  machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
++ machine-$(CONFIG_ARCH_SL2312)     := sl2312
+  textofs-$(CONFIG_ARCH_CLPS711X)   := 0x00028000
+  machine-$(CONFIG_ARCH_CLPS711X)   := clps711x
+  machine-$(CONFIG_ARCH_IOP32X)           := iop32x
+--- a/arch/arm/boot/compressed/Makefile
++++ b/arch/arm/boot/compressed/Makefile
+@@ -19,6 +19,10 @@
+ OBJS          += head-shark.o ofw-shark.o
+ endif
++ifeq ($(CONFIG_ARCH_SL2312),y)
++OBJS          += head-sl2312.o
++endif
++
+ ifeq ($(CONFIG_ARCH_L7200),y)
+ OBJS          += head-l7200.o
+ endif
+--- /dev/null
++++ b/arch/arm/boot/compressed/head-sl2312.S
+@@ -0,0 +1,6 @@
++#include <asm/mach-types.h>
++#include <asm/arch/sl2312.h>
++
++              .section        ".start", "ax"
++              mov     r7, #MACH_TYPE_SL2312
++
+--- a/arch/arm/boot/compressed/head.S
++++ b/arch/arm/boot/compressed/head.S
+@@ -57,6 +57,17 @@
+               mov     \rb, #0x50000000
+               add     \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
+               .endm
++/*****************************************************
++ *      for Storlink SoC
++ *****************************************************/
++#elif defined(CONFIG_ARCH_SL2312)
++              .macro  loadsp, rb
++              mov     \rb, #0x16000000
++              .endm
++              .macro  writeb, rb
++              strb    \rb, [r3, #0]
++              .endm
++/****************************************************/
+ #else
+               .macro  loadsp, rb
+               addruart \rb
+@@ -116,7 +127,28 @@
+               .rept   8
+               mov     r0, r0
+               .endr
+-
++/*****************************************************************************
++ *  for Storlink Soc -- on chip UART
++ *****************************************************************************/
++#ifndef CONFIG_SERIAL_IT8712          // Jason test
++@                mov     r3, #0x22000000
++                mov     r3, #0x42000000
++                mov     r11, #0x80
++                strb    r11, [r3, #0xc]
++                mov     r11, #0x0
++                strb    r11, [r3, #0x4]
++#ifndef CONFIG_SL3516_ASIC
++                mov     r11, #0x9C            /*0x9c->19200 0x4E->38400 0x34->57600 */
++#else
++              mov     r11, #0x9C              /* 0x61 for 30MHz on GeminiA chip*/
++#endif
++                strb    r11, [r3, #0x0]
++                mov     r11, #0x03
++                strb    r11, [r3, #0xc]
++                      mov     r11, #0xFB
++                strb    r11, [r3, #0x18]
++#endif
++/*****************************************************************************/
+               b       1f
+               .word   0x016f2818              @ Magic numbers to help the loader
+               .word   start                   @ absolute load/run zImage address
+@@ -458,6 +490,39 @@
+               mcr     p15, 0, r0, c7, c5, 4   @ ISB
+               mov     pc, r12
++/*****************************************************************************
++ *  for Storlink Soc -- CPU cache
++ *****************************************************************************/
++__fa526_cache_on:
++                mov     r12, lr
++                bl      __setup_mmu
++                mov     r0, #0
++                mcr     p15, 0, r0, c7, c6, 0   @ Invalidate D cache
++                mcr     p15, 0, r0, c7, c5, 0   @ Invalidate I cache
++                mcr     p15, 0, r0, c7, c10, 4  @ drain write buffer
++                mcr     p15, 0, r0, c8, c7, 0   @ flush I,D TLBs
++                mcr     p15, 0, r3, c2, c0, 0   @ load page table pointer
++                mov     r0, #-1
++                mcr     p15, 0, r0, c3, c0, 0   @ load domain access register
++                mrc     p15, 0, r0, c1, c0, 0
++                mov     r0, r0
++                mov     r0, r0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++        orr     r0, r0, #0x0004                 @ .... .... .... .1..
++#endif
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++        orr     r0, r0, #0x1000                 @ ...1 .... .... ....
++#endif
++
++#ifndef DEBUG
++                orr     r0, r0, #0x0039         @ Write buffer, mmu
++#endif
++                mcr     p15, 0, r0, c1, c0
++                mov     r0, r0
++                mov     r0, r0
++                mov     pc, r12
++/********************************************************************************/
++
+ __arm6_mmu_cache_on:
+               mov     r12, lr
+               bl      __setup_mmu
+@@ -625,6 +690,16 @@
+               @ These match on the architecture ID
++/*****************************************************************************
++ *  for Storlink Soc -- CPU architecture ID
++ *****************************************************************************/
++        .word   0x66015261              @ FA526
++        .word   0xff01fff1
++        b       __fa526_cache_on
++        b       __fa526_cache_off
++        b       __fa526_cache_flush
++/*****************************************************************************/
++
+               .word   0x00020000              @ ARMv4T
+               .word   0x000f0000
+               b       __armv4_mmu_cache_on
+@@ -712,6 +787,23 @@
+               mcr     p15, 0, r0, c8, c7, 0   @ invalidate whole TLB
+               mov     pc, r12
++/*****************************************************************************
++ *  for Storlink Soc -- CPU cache
++ *****************************************************************************/
++__fa526_cache_off:
++        mrc     p15, 0, r0, c1, c0
++        bic     r0, r0, #0x000d
++        mov     r1, #0
++        mcr     p15, 0, r1, c7, c14, 0  @ clean and invalidate D cache
++        mcr     p15, 0, r1, c7, c10, 4  @ drain WB
++        mcr     p15, 0, r0, c1, c0      @ turn MMU and cache off
++        mov     r0, #0
++        mcr     p15, 0, r0, c7, c5, 0   @ invalidate whole cache v4
++        mcr     p15, 0, r0, c8, c7, 0   @ invalidate whole TLB v4
++        mov     pc, lr
++/*****************************************************************************/
++
++
+ __arm6_mmu_cache_off:
+               mov     r0, #0x00000030         @ ARM6 control reg.
+               b       __armv3_mmu_cache_off
+@@ -759,6 +851,17 @@
+               mcr     p15, 0, ip, c7, c10, 4  @ drain WB
+               mov     pc, lr
+               
++/*****************************************************************************
++ *  for Storlink Soc -- CPU cache
++ *****************************************************************************/
++__fa526_cache_flush:
++                mov     r1, #0
++                mcr     p15, 0, r1, c7, c14, 0  @ clean and invalidate D cache
++                mcr     p15, 0, r1, c7, c5, 0   @ flush I cache
++                mcr     p15, 0, r1, c7, c10, 4  @ drain WB
++                mov     pc, lr
++/*****************************************************************************/
++
+ __armv6_mmu_cache_flush:
+               mov     r1, #0
+--- /dev/null
++++ b/arch/arm/boot/compressed/it8712.h
+@@ -0,0 +1,25 @@
++
++#ifndef __IT8712_H__
++#define __IT8712_H__
++
++#include "asm/arch/sl2312.h"
++
++#define IT8712_IO_BASE                        SL2312_LPC_IO_BASE
++//#define IT8712_IO_BASE                      0x27000000
++// Device LDN
++#define LDN_SERIAL1                           0x01
++#define LDN_SERIAL2                           0x02
++#define LDN_PARALLEL                  0x03
++#define LDN_KEYBOARD                  0x05
++#define LDN_MOUSE                             0x06
++#define LDN_GPIO                              0x07
++
++#define IT8712_UART1_PORT             0x3F8
++#define IT8712_UART2_PORT             0x2F8
++
++#define IT8712_GPIO_BASE              0x800   // 0x800-0x804 for GPIO set1-set5
++
++void LPCSetConfig(char LdnNumber, char Index, char data);
++char LPCGetConfig(char LdnNumber, char Index);
++
++#endif
+--- a/arch/arm/boot/compressed/misc.c
++++ b/arch/arm/boot/compressed/misc.c
+@@ -30,7 +30,7 @@
+ #include <asm/arch/uncompress.h>
+ #ifdef CONFIG_DEBUG_ICEDCC
+-
++#include "it8712.h"
+ #ifdef CONFIG_CPU_V6
+ static void icedcc_putc(int ch)
+@@ -69,6 +69,7 @@
+ #define flush()       do { } while (0)
+ #endif
++#if 0
+ static void putstr(const char *ptr)
+ {
+       char c;
+@@ -81,11 +82,36 @@
+       flush();
+ }
++#endif
+ #endif
+ #define __ptr_t void *
++#ifdef CONFIG_SERIAL_IT8712
++unsigned int it8712_uart_base;
++#define UART_RX         0
++#define UART_TX         0
++#define UART_DLL        0
++#define UART_TRG        0
++#define UART_DLM        1
++#define UART_IER        1
++#define UART_FCTR       1
++#define UART_IIR        2
++#define UART_FCR        2
++#define UART_EFR        2
++#define UART_LCR        3
++#define UART_MCR        4
++#define UART_LSR        5
++#define UART_MSR        6
++#define UART_SCR        7
++#define UART_EMSR       7
++void LPCEnterMBPnP(void);
++void LPCExitMBPnP(void);
++int SearchIT8712(void);
++int InitLPCInterface(void);
++#endif
++
+ /*
+  * Optimised C version of memzero for the ARM.
+  */
+@@ -346,6 +372,9 @@
+ decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
+                 int arch_id)
+ {
++#ifdef CONFIG_SERIAL_IT8712
++        unsigned char *addr;
++#endif
+       output_data             = (uch *)output_start;  /* Points to kernel start */
+       free_mem_ptr            = free_mem_ptr_p;
+       free_mem_ptr_end        = free_mem_ptr_end_p;
+@@ -353,6 +382,33 @@
+       arch_decomp_setup();
++#ifdef CONFIG_SERIAL_IT8712
++
++        InitLPCInterface();
++        LPCSetConfig(0, 0x02, 0x01);
++        LPCSetConfig(LDN_SERIAL1, 0x30, 0x1);
++        LPCSetConfig(LDN_SERIAL1, 0x23, 0x0);
++        it8712_uart_base = IT8712_IO_BASE;
++        it8712_uart_base += ((LPCGetConfig(LDN_SERIAL1, 0x60) << 8) + LPCGetConfig(LDN_SERIAL1, 0x61));
++
++        do {
++        addr = (unsigned char *)(it8712_uart_base + UART_LCR) ;
++        *addr = 0x80;
++        // Set Baud Rate
++        addr = (unsigned char *)(it8712_uart_base+UART_DLL);
++        *addr = 0x06 ;
++        addr = (unsigned char *)(it8712_uart_base+UART_DLM);
++        *addr = 0x00 ;
++
++        addr = (unsigned char *)(it8712_uart_base+UART_LCR);    // LCR
++        *addr = 0x07 ;
++        addr = (unsigned char *)(it8712_uart_base+UART_MCR);    // MCR
++        *addr = 0x08 ;
++        addr = (unsigned char *)(it8712_uart_base+UART_FCR);    // FCR
++        *addr = 0x01 ;
++      } while(0);
++#endif
++
+       makecrc();
+       putstr("Uncompressing Linux...");
+       gunzip();
+@@ -374,4 +430,119 @@
+       return 0;
+ }
+ #endif
++
++#ifdef CONFIG_SERIAL_IT8712
++
++#define LPC_KEY_ADDR    (unsigned char *)(SL2312_LPC_IO_BASE + 0x2e)
++#define LPC_DATA_ADDR   (unsigned char *)(SL2312_LPC_IO_BASE + 0x2f)
++#define LPC_BUS_CTRL                    *( unsigned char*) (SL2312_LPC_HOST_BASE + 0)
++#define LPC_BUS_STATUS                  *( unsigned char*) (SL2312_LPC_HOST_BASE + 2)
++#define LPC_SERIAL_IRQ_CTRL             *( unsigned char*) (SL2312_LPC_HOST_BASE + 4)
++
++char LPCGetConfig(char LdnNumber, char Index)
++{
++        char rtn;
++        unsigned char *addr ;
++
++        LPCEnterMBPnP();                                // Enter IT8712 MB PnP mode
++
++        addr = LPC_KEY_ADDR;
++        *addr = 0x07 ;
++
++        addr = LPC_DATA_ADDR;
++        *addr = LdnNumber ;
++
++        addr = LPC_KEY_ADDR;
++        *addr = Index ;
++
++        addr = LPC_DATA_ADDR ;
++        rtn = *addr ;
++
++        LPCExitMBPnP();
++        return rtn;
++
++}
++
++void LPCSetConfig(char LdnNumber, char Index, char data)
++{
++        unsigned char *addr;
++        LPCEnterMBPnP();                                // Enter IT8712 MB PnP mode
++        addr = LPC_KEY_ADDR;
++        *addr = 0x07;
++        addr = LPC_DATA_ADDR;
++        *addr = LdnNumber;
++        addr = LPC_KEY_ADDR;
++        *addr = Index;
++        addr = LPC_DATA_ADDR;
++        *addr = data;
++
++        LPCExitMBPnP();
++}
++
++//unsigned char key[4] ;
++void LPCEnterMBPnP(void)
++{
++        unsigned char *addr;
++        addr = LPC_KEY_ADDR;
++        unsigned char key[4] = {0x87, 0x01, 0x55, 0x55};
++
++              do {
++              *addr = key[0];
++              *addr = key[1];
++              *addr = key[2];
++              *addr = key[3];
++              }while(0);
++}
++
++void LPCExitMBPnP(void)
++{
++        unsigned char *addr;
++        addr = LPC_KEY_ADDR;
++        *addr = 0x02 ;
++
++        addr = LPC_DATA_ADDR;
++        *addr = 0x02 ;
++}
++
++int InitLPCInterface(void)
++{
++        int i;
++        LPC_BUS_CTRL = 0xc0;
++        LPC_SERIAL_IRQ_CTRL = 0xc0;
++
++        for(i=0;i<0x2000;i++) ;
++
++        LPC_SERIAL_IRQ_CTRL = 0x80;
++        if (!SearchIT8712()) ;
++//                    while(1);
++        return 0;
++}
++
++int SearchIT8712(void)
++{
++        unsigned char Id1, Id2;
++        unsigned short Id;
++        unsigned char *addr;
++
++        LPCEnterMBPnP();
++        addr = LPC_KEY_ADDR;
++        *addr = 0x20 ;
++        addr = LPC_DATA_ADDR;
++        Id1 = *addr ;
++
++        addr = LPC_KEY_ADDR;
++        *addr = 0x21 ;
++        addr = LPC_DATA_ADDR;
++        Id2 = *addr ;
++
++        Id = (Id1 << 8) | Id2;
++        LPCExitMBPnP();
++
++        if (Id == 0x8712)
++                return 1;
++        else
++                return 0;
++}
++
++#endif
+       
+--- a/arch/arm/kernel/entry-armv.S
++++ b/arch/arm/kernel/entry-armv.S
+@@ -18,6 +18,8 @@
+ #include <asm/memory.h>
+ #include <asm/glue.h>
+ #include <asm/vfpmacros.h>
++#include <asm/arch/irqs.h>
++#include <asm/hardware.h>
+ #include <asm/arch/entry-macro.S>
+ #include <asm/thread_notify.h>
+--- a/arch/arm/kernel/irq.c
++++ b/arch/arm/kernel/irq.c
+@@ -40,6 +40,8 @@
+ #include <asm/system.h>
+ #include <asm/mach/time.h>
++extern int fixup_irq(unsigned int irq);
++
+ /*
+  * No architecture-specific irq_finish function defined in arm/arch/irqs.h.
+  */
+@@ -111,8 +113,11 @@
+ asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
+ {
+       struct pt_regs *old_regs = set_irq_regs(regs);
+-      struct irq_desc *desc = irq_desc + irq;
++//    struct irq_desc *desc = irq_desc + irq;
++      struct irq_desc *desc;
++      irq = fixup_irq(irq);
++      desc = irq_desc + irq;
+       /*
+        * Some hardware gives randomly wrong interrupts.  Rather
+        * than crashing, do something sensible.
+--- a/arch/arm/kernel/process.c
++++ b/arch/arm/kernel/process.c
+@@ -117,7 +117,7 @@
+ void (*pm_idle)(void);
+ EXPORT_SYMBOL(pm_idle);
+-void (*pm_power_off)(void);
++//void (*pm_power_off)(void);
+ EXPORT_SYMBOL(pm_power_off);
+ void (*arm_pm_restart)(char str) = arm_machine_restart;
+@@ -188,13 +188,37 @@
+ void machine_halt(void)
+ {
++      unsigned int reg_v;
++
++      printk("arch_power_off\n");
++
++      reg_v = readl(IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04);
++      reg_v &= ~0x00000002;
++      reg_v |= 0x1;
++      mdelay(5);
++      // Power off
++      __raw_writel( reg_v, IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04);
++
+ }
+ void machine_power_off(void)
+ {
+-      if (pm_power_off)
++      unsigned int reg_v;
++
++//    if (pm_power_off)
++      if (&pm_power_off!=NULL)
+               pm_power_off();
++
++      printk("arch_power_off\n");
++
++      reg_v = readl(IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04);
++      reg_v &= ~0x00000002;
++      reg_v |= 0x1;
++      mdelay(5);
++      // Power off
++      __raw_writel( reg_v, IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04);
++
+ }
+ void machine_restart(char * __unused)
+--- a/arch/arm/kernel/time.c
++++ b/arch/arm/kernel/time.c
+@@ -502,8 +502,13 @@
+ device_initcall(timer_init_sysfs);
++extern unsigned int rtc_get_time_second(void);
++
+ void __init time_init(void)
+ {
++#ifdef CONFIG_SL2312_RTC
++      xtime.tv_sec  = rtc_get_time_second() ;
++#endif
+ #ifndef CONFIG_GENERIC_TIME
+       if (system_timer->offset == NULL)
+               system_timer->offset = dummy_gettimeoffset;
+--- /dev/null
++++ b/arch/arm/mach-sl2312/Kconfig
+@@ -0,0 +1,33 @@
++
++menu "SL2312"
++
++config SL3516_ASIC
++      bool "SL3516 ASIC version"
++      depends on ARCH_SL2312
++      help
++        This option to select AISC or FPGA
++config PCI
++       bool "SL2312 PCI"
++       depends on ARCH_SL2312
++       help
++         This option to enable Storlink PCI controller
++
++config SL2312_LPC
++       bool "SL2312 LPC"
++       depends on ARCH_SL2312
++       help
++         This option to enable Low Pin Count controller
++
++config SL2312_USB
++       bool "SL2312 USB"
++       depends on ARCH_SL2312
++       help
++         This option to enable USB OTG host controller
++
++config GEMINI_IPI
++       bool "Gemini IPI test"
++       depends on ARCH_SL2312
++       help
++       Enable this option to test dual cpu Inter-Processor-Interrupt
++endmenu
++
+--- /dev/null
++++ b/arch/arm/mach-sl2312/Makefile
+@@ -0,0 +1,16 @@
++#
++# Makefile for the linux kernel.
++#
++
++# Object file lists.
++
++obj-y                 := arch.o irq.o mm.o time.o sl3516_device.o
++obj-m                 :=
++obj-n                 :=
++
++
++obj-$(CONFIG_PCI) += pci.o
++obj-$(CONFIG_SL2312_LPC) += lpc.o
++obj-$(CONFIG_SL2312_USB) += sl2312-otg.o # sl2312-otg-1.o
++obj-$(CONFIG_GEMINI_XOR_ACCE) += xor.o
++obj-$(CONFIG_GEMINI_IPI)      += gemini_ipi.o
+--- /dev/null
++++ b/arch/arm/mach-sl2312/Makefile.boot
+@@ -0,0 +1,5 @@
++   zreladdr-y := 0x00008000
++params_phys-y := 0x00508100
++#params_phys-y        := 0x00008100
++initrd_phys-y := 0x00800000
++
+--- /dev/null
++++ b/arch/arm/mach-sl2312/arch.c
+@@ -0,0 +1,72 @@
++/*
++ *  linux/arch/arm/mach-epxa10db/arch.c
++ *
++ *  Copyright (C) 2000 Deep Blue Solutions Ltd
++ *  Copyright (C) 2001 Altera Corporation
++ *
++ * 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 program is distributed in the hope that 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
++ */
++#include <linux/types.h>
++#include <linux/init.h>
++
++#include <asm/hardware.h>
++#include <asm/setup.h>
++#include <asm/mach-types.h>
++#include <asm/mach/time.h>
++#include <asm/mach/arch.h>
++
++extern void sl2312_map_io(void);
++extern void sl2312_init_irq(void);
++extern unsigned long sl2312_gettimeoffset (void);
++extern void __init sl2312_time_init(void);
++
++static struct sys_timer sl2312_timer = {
++      .init           = sl2312_time_init,
++      .offset         = sl2312_gettimeoffset,
++};
++
++static void __init
++sl2312_fixup(struct machine_desc *desc, struct tag *tags,
++                 char **cmdline, struct meminfo *mi)
++{
++        mi->nr_banks      = 1;
++        mi->bank[0].start = 0;
++#ifdef CONFIG_GEMINI_IPI
++        mi->bank[0].size  = (64*1024*1024);  // 128M
++#else
++        mi->bank[0].size  = (128*1024*1024);  // 128M
++#endif
++        mi->bank[0].node  = 0;
++}
++
++/* MACHINE_START(SL2312, "GeminiA")
++      MAINTAINER("Storlink Semi")
++      BOOT_MEM(0x00000000, 0x90000000, 0xf0000000)
++        FIXUP(sl2312_fixup)
++      MAPIO(sl2312_map_io)
++      INITIRQ(sl2312_init_irq)
++      .timer = &sl2312_timer,
++MACHINE_END */
++
++MACHINE_START(SL2312, "GeminiA")
++      /* .phys_ram    = 0x00000000, */
++      .phys_io        = 0x7fffc000,
++      .io_pg_offst    = ((0xffffc000) >> 18) & 0xfffc,
++      .boot_params    = 0x100,
++      .fixup      = sl2312_fixup,
++      .map_io         = sl2312_map_io,
++      .init_irq       = sl2312_init_irq,
++      .timer          = &sl2312_timer,
++MACHINE_END
+--- /dev/null
++++ b/arch/arm/mach-sl2312/gemini_ipi.c
+@@ -0,0 +1,593 @@
++/*
++ * FILE NAME sl_cir.c
++ *
++ * BRIEF MODULE DESCRIPTION
++ *  IPI Driver for CPU1.
++ *
++ *  Author: StorLink, Corp.
++ *          Jason Lee
++ *
++ * Copyright 2002~2006 StorLink, Corp.
++ *
++ *  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  LIMit8712D  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 LIMit8712D   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, writ8712  to the Free Software Foundation, Inc.,
++ *  675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/miscdevice.h>
++#include <linux/init.h>
++#include <linux/pagemap.h>
++#include <asm/uaccess.h>
++#include <linux/ioport.h>
++#include <linux/sched.h>
++#include <linux/delay.h>
++#include <linux/fs.h>
++#include <linux/interrupt.h>
++#include <asm/io.h>
++#include <asm/delay.h>
++#include <linux/signal.h>
++#include <asm/arch/sl2312.h>
++#include <asm/arch/int_ctrl.h>
++#include <asm/arch/ipi.h>
++#include <linux/dma-mapping.h>
++
++
++#include <linux/mm.h>
++
++#include <linux/bootmem.h>
++
++#include <asm/hardware.h>
++#include <asm/page.h>
++#include <asm/setup.h>
++#include <asm/pgtable.h>
++#include <asm/pgalloc.h>
++
++#include <asm/mach/map.h>
++
++
++static int sl_ipi_debug = 1 ;
++#define DEB(x)  if(sl_ipi_debug>=1) x
++
++#define SRAM_PTR              IO_ADDRESS(SL2312_SRAM_BASE)
++volatile JSCALE_REQ_T *req=(JSCALE_REQ_T*)SRAM_PTR;
++volatile JSCALE_RSP_T *rsp=(JSCALE_RSP_T*)(SRAM_PTR+0x20);
++
++unsigned int jscale_status=0;
++
++#define JSCALE_WAIT   0
++#define XXXXXX_WAIT   1
++#define MAX_WAIT_Q    8
++wait_queue_head_t gemini_ipi_wait[MAX_WAIT_Q];
++
++#define DRAMCTL_DMA_CTL               0X20
++#define DRAMCTL_DMA_SA                0X24
++#define DRAMCTL_DMA_DA                0X28
++#define DRAMCTL_DMA_CNT               0X2C
++#define MEMCPY_UNIT           0x40000
++int hw_memcpy(const void *to, const void *from, unsigned int bytes)
++{
++      unsigned int reg_a,reg_d;
++      int count = bytes,i=0;
++
++      consistent_sync((unsigned int *)to, bytes, DMA_BIDIRECTIONAL);
++      consistent_sync((unsigned int *)from,bytes, DMA_TO_DEVICE);
++
++      DEB(printk("hwmemcpy:count %d\n",count));
++      while(count>0){
++              // SA
++              reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_SA;
++              reg_d = (unsigned int )__virt_to_phys(from) + i*MEMCPY_UNIT;
++              DEB(printk("hwmemcpy:from 0x%08x\n",reg_d));
++              writel(reg_d,reg_a);
++              // DA
++              reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_DA;
++              reg_d = (unsigned int )__virt_to_phys(to) + i*MEMCPY_UNIT;
++              writel(reg_d,reg_a);
++              DEB(printk("hwmemcpy:to 0x%08x\n",reg_d));
++              // byte count
++              reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_CNT;
++              reg_d = (count>=MEMCPY_UNIT)?MEMCPY_UNIT:count;
++              writel(reg_d,reg_a);
++              // start DMA
++              reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_CTL;
++              writel(0x80000001,reg_a);
++
++              do{
++                      cond_resched();
++//                    msleep(4);
++                      reg_d = readl(IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_CTL);
++              }while(reg_d&0x1);
++
++              count -= MEMCPY_UNIT;
++              i++;
++      }
++
++      return bytes;
++}
++
++static irqreturn_t ipi_interrupt()
++{
++      unsigned int id=getcpuid(),tmp;
++
++      //dmac_inv_range(__phys_to_virt(SL2312_SRAM_BASE),__phys_to_virt(SHAREADDR)+0x2000);
++
++
++      // Clear Interrupt
++      if(id==CPU0) {
++              tmp = readl(CPU1_STATUS);
++              tmp &= ~CPU_IPI_BIT_MASK;
++              writel(tmp,CPU1_STATUS);
++      }
++      else{
++              tmp = readl(CPU0_STATUS);
++              tmp &= ~CPU_IPI_BIT_MASK;
++              writel(tmp,CPU0_STATUS);
++      }
++
++      //
++      DEB(printk("ipi interrupt:0x%x\n",rsp->status));
++      switch(rsp->status){
++              case JSCALE_STATUS_OK:
++
++                      break;
++              case JSCALE_UNKNOWN_MSG_TYPE:
++
++                      break;
++              case JSCALE_FAILED_FILE_SIZE:
++
++                      break;
++              case JSCALE_FAILED_MALLOC:
++
++                      break;
++              case JSCALE_FAILED_FORMAT:
++
++                      break;
++              case JSCALE_DECODE_ERROR:
++
++                      break;
++
++      }
++      jscale_status = rsp->status;
++//    wake_up(&gemini_ipi_wait[JSCALE_WAIT]);
++
++      return IRQ_HANDLED;
++}
++
++static int gemini_ipi_open(struct inode *inode, struct file *file)
++{
++      DEB(printk("ipi open\n"));
++      return 0;
++}
++
++
++static int gemini_ipi_release(struct inode *inode, struct file *file)
++{
++      DEB(printk("ipi release\n"));
++      return 0;
++}
++
++
++static int gemini_ipi_ioctl(struct inode *inode, struct file *file,
++      unsigned int cmd, unsigned long arg)
++{
++      JSCALE_RSP_T tmp;
++
++      switch(cmd) {
++              case GEMINI_IPI_JSCALE_REQ:
++                      DEB(printk("ipi:ioctl jscale request %dX%d Q:%d\n",req->ScaledImageWidth,req->ScaledImageHeight,req->ScaledImageQuality));
++                      if (copy_from_user(req, (JSCALE_REQ_T *)arg, sizeof(JSCALE_REQ_T)))
++                              return -EFAULT;
++                      req->hdr.type = IPC_JSCALE_REQ_MSG;
++                      req->hdr.length = sizeof(JSCALE_REQ_T);
++                      req->input_location  = CPU_1_DATA_OFFSET;
++                      req->output_location = CPU_1_DATA_OFFSET;
++                      break;
++              case GEMINI_IPI_JSCALE_STAT:
++                      DEB(printk("ipi:ioctl jscale stat \n"));
++                      if(jscale_status==JSCALE_BUSY){                                         // not yet
++                              tmp.status = JSCALE_BUSY;
++                              if (copy_to_user((JSCALE_RSP_T *)arg,&tmp, sizeof(JSCALE_RSP_T)))
++                                      return -EFAULT;
++                      }
++                      else{                                                                                           // finish or error
++                              if (copy_to_user((JSCALE_RSP_T *)arg,rsp, sizeof(JSCALE_RSP_T)))
++                                      return -EFAULT;
++                      }
++                      break;
++              default:
++                      printk("IPI: Error IOCTL number\n");
++                      return -ENOIOCTLCMD;
++      }
++
++      return 0;
++}
++
++#define SRAM_SIZE     0x2000
++static ssize_t gemini_ipi_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos)
++{
++      int i=0,tmp=0,j;
++      const char *ptr=(unsigned int)__phys_to_virt(CPU_1_MEM_BASE+CPU_1_DATA_OFFSET);
++      DEB(printk("ipi:write 0x%x to 0x%x length:%d\n",&buf,ptr,count));
++      memcpy(ptr,buf,count);
++      consistent_sync(ptr,count, DMA_TO_DEVICE);
++      //hw_memcpy(ptr,&buf,count);
++
++/*    if(count>SRAM_SIZE){
++              for(i=0;i<(count/SRAM_SIZE);i++)
++                      raid_memcpy(ptr+i*SRAM_SIZE,buf+i*SRAM_SIZE,SRAM_SIZE);
++              if(count%SRAM_SIZE)
++                      raid_memcpy(ptr+i*SRAM_SIZE,buf+i*SRAM_SIZE,count%SRAM_SIZE);
++      }
++      else
++              raid_memcpy(ptr,buf,count);
++*/
++
++/*    for(i=0;i<count;i++){
++              if(buf[i]!=ptr[i])
++                      printk("ipi error:offset %d valud %x[should %x]\n",i,ptr[i],buf[i]);
++      }
++
++      printk("===========input buf===============\n");
++      for(i=0;i<64;i+=16){
++              for(j=0;j<16;j++)
++                      printk("%02x ",buf[i+j]);
++              printk("\n");
++              cond_resched();
++      }
++      printk("===========output buf==============\n");
++      for(i=0;i<64;i+=16){
++              for(j=0;j<16;j++)
++                      printk("%02x ",ptr[i+j]);
++              printk("\n");
++              cond_resched();
++      }
++*/
++      // send irq for CPU1
++      tmp |= CPU_IPI_BIT_MASK;
++      writel(tmp,CPU0_STATUS);
++      jscale_status = JSCALE_BUSY;
++
++      return count;
++}
++
++static ssize_t gemini_ipi_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
++{
++      int i=0;
++      const char *ptr=(unsigned int )__phys_to_virt(CPU_1_MEM_BASE+CPU_1_DATA_OFFSET);
++
++      consistent_sync(ptr,length, DMA_FROM_DEVICE);
++      memcpy(buf,ptr,length);
++      DEB(printk("ipi:read 0x%x to 0x%x length:%d\n",ptr,buf,length));
++
++      //consistent_sync((unsigned int *)ptr,0x2000, DMA_FROM_DEVICE);         // invalid
++      //hw_memcpy(buf,ptr,length);
++
++      // need encoded file size ********
++/*    if(count>SRAM_SIZE){
++              for(i=0;i<(count/SRAM_SIZE);i++)
++                      raid_memcpy(buf+i*SRAM_SIZE,p_mbox->message+i*SRAM_SIZE,SRAM_SIZE);
++              if(count%0xFFFF)
++                      raid_memcpy(buf+i*SRAM_SIZE,p_mbox->message+i*SRAM_SIZE,length%SRAM_SIZE);
++      }
++      else
++              raid_memcpy(buf,p_mbox->message,length);
++*/
++      return length;
++}
++
++void do_mapping_read(struct address_space *mapping,
++                           struct file_ra_state *_ra,
++                           struct file *filp,
++                           loff_t *ppos,
++                           read_descriptor_t *desc,
++                           read_actor_t actor)
++{
++      struct inode *inode = mapping->host;
++      unsigned long index;
++      unsigned long end_index;
++      unsigned long offset;
++      unsigned long last_index;
++      unsigned long next_index;
++      unsigned long prev_index;
++      loff_t isize;
++      struct page *cached_page;
++      int error;
++      struct file_ra_state ra = *_ra;
++
++      cached_page = NULL;
++      index = *ppos >> PAGE_CACHE_SHIFT;
++      next_index = index;
++      prev_index = ra.prev_page;
++      last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
++      offset = *ppos & ~PAGE_CACHE_MASK;
++
++      isize = i_size_read(inode);
++      if (!isize)
++              goto out;
++
++      end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
++      for (;;) {
++              struct page *page;
++              unsigned long nr, ret;
++
++              /* nr is the maximum number of bytes to copy from this page */
++              nr = PAGE_CACHE_SIZE;
++              if (index >= end_index) {
++                      if (index > end_index)
++                              goto out;
++                      nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
++                      if (nr <= offset) {
++                              goto out;
++                      }
++              }
++              nr = nr - offset;
++
++              cond_resched();
++              if (index == next_index)
++                      next_index = page_cache_readahead(mapping, &ra, filp,
++                                      index, last_index - index);
++
++find_page:
++              page = find_get_page(mapping, index);
++              if (unlikely(page == NULL)) {
++                      handle_ra_miss(mapping, &ra, index);
++                      goto no_cached_page;
++              }
++              if (!PageUptodate(page))
++                      goto page_not_up_to_date;
++page_ok:
++
++              /* If users can be writing to this page using arbitrary
++               * virtual addresses, take care about potential aliasing
++               * before reading the page on the kernel side.
++               */
++              if (mapping_writably_mapped(mapping))
++                      flush_dcache_page(page);
++
++              /*
++               * When (part of) the same page is read multiple times
++               * in succession, only mark it as accessed the first time.
++               */
++              if (prev_index != index)
++                      mark_page_accessed(page);
++              prev_index = index;
++
++              /*
++               * Ok, we have the page, and it's up-to-date, so
++               * now we can copy it to user space...
++               *
++               * The actor routine returns how many bytes were actually used..
++               * NOTE! This may not be the same as how much of a user buffer
++               * we filled up (we may be padding etc), so we can only update
++               * "pos" here (the actor routine has to update the user buffer
++               * pointers and the remaining count).
++               */
++              ret = actor(desc, page, offset, nr);
++              offset += ret;
++              index += offset >> PAGE_CACHE_SHIFT;
++              offset &= ~PAGE_CACHE_MASK;
++
++              page_cache_release(page);
++              if (ret == nr && desc->count)
++                      continue;
++              goto out;
++
++page_not_up_to_date:
++              /* Get exclusive access to the page ... */
++              lock_page(page);
++
++              /* Did it get unhashed before we got the lock? */
++              if (!page->mapping) {
++                      unlock_page(page);
++                      page_cache_release(page);
++                      continue;
++              }
++
++              /* Did somebody else fill it already? */
++              if (PageUptodate(page)) {
++                      unlock_page(page);
++                      goto page_ok;
++              }
++
++readpage:
++              /* Start the actual read. The read will unlock the page. */
++              error = mapping->a_ops->readpage(filp, page);
++
++              if (unlikely(error))
++                      goto readpage_error;
++
++              if (!PageUptodate(page)) {
++                      lock_page(page);
++                      if (!PageUptodate(page)) {
++                              if (page->mapping == NULL) {
++                                      /*
++                                       * invalidate_inode_pages got it
++                                       */
++                                      unlock_page(page);
++                                      page_cache_release(page);
++                                      goto find_page;
++                              }
++                              unlock_page(page);
++                              error = -EIO;
++                              goto readpage_error;
++                      }
++                      unlock_page(page);
++              }
++
++              /*
++               * i_size must be checked after we have done ->readpage.
++               *
++               * Checking i_size after the readpage allows us to calculate
++               * the correct value for "nr", which means the zero-filled
++               * part of the page is not copied back to userspace (unless
++               * another truncate extends the file - this is desired though).
++               */
++              isize = i_size_read(inode);
++              end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
++              if (unlikely(!isize || index > end_index)) {
++                      page_cache_release(page);
++                      goto out;
++              }
++
++              /* nr is the maximum number of bytes to copy from this page */
++              nr = PAGE_CACHE_SIZE;
++              if (index == end_index) {
++                      nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
++                      if (nr <= offset) {
++                              page_cache_release(page);
++                              goto out;
++                      }
++              }
++              nr = nr - offset;
++              goto page_ok;
++
++readpage_error:
++              /* UHHUH! A synchronous read error occurred. Report it */
++              desc->error = error;
++              page_cache_release(page);
++              goto out;
++
++no_cached_page:
++              /*
++               * Ok, it wasn't cached, so we need to create a new
++               * page..
++               */
++              if (!cached_page) {
++                      cached_page = page_cache_alloc_cold(mapping);
++                      if (!cached_page) {
++                              desc->error = -ENOMEM;
++                              goto out;
++                      }
++              }
++              error = add_to_page_cache_lru(cached_page, mapping,
++                                              index, GFP_KERNEL);
++              if (error) {
++                      if (error == -EEXIST)
++                              goto find_page;
++                      desc->error = error;
++                      goto out;
++              }
++              page = cached_page;
++              cached_page = NULL;
++              goto readpage;
++      }
++
++out:
++      *_ra = ra;
++
++      *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
++      if (cached_page)
++              page_cache_release(cached_page);
++      if (filp)
++              file_accessed(filp);
++}
++
++int ipi_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
++{
++      ssize_t written;
++      unsigned long count = desc->count;
++      struct file *file = desc->arg.data;
++      unsigned int *ptr_to=(unsigned int)__phys_to_virt(CPU_1_MEM_BASE+CPU_1_DATA_OFFSET) + desc->written;
++      void *ptr_from;
++
++      if (size > count)
++              size = count;
++
++      ptr_from = page_address(page)+offset;
++      written = memcpy(ptr_to,ptr_from,size);
++
++      if (written < 0) {
++              desc->error = written;
++              written = 0;
++      }
++      desc->count = count - written;
++      desc->written += written;
++      return written;
++}
++
++ssize_t gemini_ipi_sendfile(struct file *in_file, loff_t *ppos,
++                       size_t count, read_actor_t actor, void *TARGET)
++{
++      read_descriptor_t desc;
++
++      if (!count)
++              return 0;
++
++      desc.written = 0;
++      desc.count = count;
++      desc.arg.data = TARGET;
++      desc.error = 0;
++
++      do_mapping_read(in_file->f_mapping,&in_file->f_ra,in_file, ppos, &desc, ipi_send_actor);
++
++      if (desc.written)
++              return desc.written;
++      return desc.error;
++}
++static struct file_operations gemini_ipi_fops = {
++      .owner  =       THIS_MODULE,
++      .ioctl  =       gemini_ipi_ioctl,
++      .open   =       gemini_ipi_open,
++      .release=       gemini_ipi_release,
++      .write  =       gemini_ipi_write,
++      .read   =       gemini_ipi_read,
++      .sendfile = gemini_ipi_sendfile,
++};
++
++#ifndef STORLINK_IPI
++#define STORLINK_IPI  242             // Documents/devices.txt suggest to use 240~255 for local driver!!
++#endif
++
++static struct miscdevice gemini_ipi_miscdev =
++{
++      STORLINK_IPI,
++      "slave_ipc",
++      &gemini_ipi_fops
++};
++
++int __init sl_ipi_init(void)
++{
++
++      printk("Gemini IPI Driver Initialization...\n");
++      printk("REQ Head :0x%x(phy:0x%x)\n",(unsigned int)req,(unsigned int)SL2312_SRAM_BASE);
++      printk("RSP Head :0x%x(phy:0x%x)\n",(unsigned int)rsp,(unsigned int)SL2312_SRAM_BASE+0x20);
++      printk("Data buff:0x%x(phy:0x%x)\n",__phys_to_virt(CPU_1_MEM_BASE+CPU_1_DATA_OFFSET),CPU_1_MEM_BASE+CPU_1_DATA_OFFSET);
++
++      misc_register(&gemini_ipi_miscdev);
++
++      if (request_irq(IRQ_CPU0_IP_IRQ_OFFSET, ipi_interrupt, SA_INTERRUPT, "ipi", NULL))
++              printk("Error: Register IRQ for Storlink IPI failed\n");
++
++      return 0;
++}
++
++void __exit sl_ipi_exit(void)
++{
++
++}
++
++module_init(sl_ipi_init);
++module_exit(sl_ipi_exit);
++
++MODULE_AUTHOR("Jason Lee <jason@storlink.com.tw>");
++MODULE_DESCRIPTION("Storlink IPI driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/arch/arm/mach-sl2312/hw_xor.h
+@@ -0,0 +1,573 @@
++/*
++*  linux/include/asm-arm/xor.h
++*
++*  Copyright (C) 2001 Storlink Semi.
++*     Jason Lee <jason@storlink.com.tw>
++*
++*/
++#include <asm/arch/sl2312.h>
++#include <asm/io.h>
++//#include <linux/compatmac.h>
++
++#undef BIG_ENDIAN
++#define CPU           0
++#define DMA           1
++
++#define DESC_NO       8
++#define TX_DESC_NUM           DESC_NO
++#define RX_DESC_NUM           DESC_NO
++
++#define RAID_BASE_ADDR        IO_ADDRESS(SL2312_RAID_BASE)
++
++#define SRAM_PAR_0k           0
++#define SRAM_PAR_4k           1
++#define SRAM_PAR_8k           2
++#define SRAM_PAR_16k          3
++#define SRAM_PAR_SIZE SRAM_PAR_8k
++
++#define RUNNING               0x1
++#define COMPLETE      0x2
++#define ERROR                 0x4
++
++#define CMD_XOR               0x0
++#define CMD_FILL      0x1
++#define CMD_CPY               0x3
++#define CMD_CHK               0x4
++
++enum RAID_DMA_REGISTER {
++      RAID_DMA_DEVICE_ID              = 0xff00,
++      RAID_DMA_STATUS                 = 0xff04,
++      RAID_FCHDMA_CTRL                = 0xff08,
++      RAID_FCHDMA_FIRST_DESC  = 0xff0C,
++      RAID_FCHDMA_CURR_DESC   = 0xff10,
++      RAID_STRDMA_CTRL                = 0xff14,
++      RAID_STRDMA_FIRST_DESC  = 0xff18,
++      RAID_STRDMA_CURR_DESC   = 0xff1C,
++      RAID_TX_FLG_REG                 = 0xff24,
++      RAID_RX_FLG_REG                 = 0xff34,
++      RAID_PCR                                = 0xff50,
++      SMC_CMD_REG                             = 0xff60,
++      SMC_STATUS_REG                  = 0xff64
++      };
++
++enum RAID_FUNC_MODE {
++      RAID_XOR                        = 0,
++      RAID_MIX                        = 2,
++      RAID_SRAM                       = 3,
++      RAID_ENDIAN                     = 4,
++      RAID_MEM_BLK            = 5,
++      RAID_MEM2MEM            = 7,
++      RAID_BUF_SIZE           = 8,
++      RAID_ERR_TEST           = 9,
++      RAID_BURST                      = 10,
++      RAID_BUS                        = 11
++      };
++
++typedef struct reg_info {
++      int mask;
++      char err[32];
++      int offset;
++} REG_INFO;
++
++/********************************************************/
++/*    the definition of RAID DMA Module Register      */
++/********************************************************/
++typedef union
++{
++      unsigned int bit32;
++      struct bits_ff00
++      {
++              #ifdef BIG_ENDIAN
++              unsigned int                            : 8;
++              unsigned int teytPerr           : 4; /* define protocol error under tsPErrI*/
++              unsigned int reytPerr           : 14; /* define protocol error under rsPErrI */
++              unsigned int device_id          : 12;
++              unsigned int revision_id        : 4;
++              #else
++              unsigned int revision_id        : 4;
++              unsigned int device_id          : 12;
++              unsigned int reytPerr           : 14; /* define protocol error under rsPErrI */
++              unsigned int teytPerr           : 4; /* define protocol error under tsPErrI*/
++              unsigned int                            : 8;
++              #endif
++      } bits;
++} RAID_DMA_DEVICE_ID_T;
++
++typedef union
++{
++      unsigned int bits32;
++      struct bits_ff04
++      {
++              #ifdef BIG_ENDIAN
++              unsigned int tsFinishI          : 1; /* owner bit error interrupt */
++              unsigned int tsDErrI            : 1; /* AHB bus error interrupt */
++              unsigned int tsPErrI            : 1; /* RAID XOR fetch descriptor protocol error interrupt */
++              unsigned int tsEODI                     : 1; /* RAID XOR fetch DMA end of descriptor interrupt */
++              unsigned int tsEOFI                     : 1; /* RAID XOR fetch DMA end of frame interrupt */
++              unsigned int rsFinishI          : 1; /* owner bit error interrupt */
++              unsigned int rsDErrI            : 1; /* AHB bus error while RAID XOR store interrupt */
++              unsigned int rsPErrI            : 1; /* RAID XOR store descriptor protocol error interrupt */
++              unsigned int rsEODI                     : 1; /* RAID XOR store DMA end of descriptor interrupt */
++              unsigned int rsEOFI                     : 1; /* RAID XOR store DMA end of frame interrupt */
++              unsigned int inter                      : 8; /* pattern check error interrupt */
++              unsigned int                            : 5;
++              unsigned int Loopback           : 1; /* loopback */
++              unsigned int intEnable          : 8; /*pattern check error interrupt enable */
++              #else
++              unsigned int intEnable          : 8; /*pattern check error interrupt enable */
++              unsigned int Loopback           : 1; /* loopback */
++              unsigned int                            : 5;
++              unsigned int inter                      : 8; /* pattern check error interrupt */
++              unsigned int rsEOFI                     : 1; /* RAID XOR store DMA end of frame interrupt */
++              unsigned int rsEODI                     : 1; /* RAID XOR store DMA end of descriptor interrupt */
++              unsigned int rsPErrI            : 1; /* RAID XOR store descriptor protocol error interrupt */
++              unsigned int rsDErrI            : 1; /* AHB bus error while RAID XOR store interrupt */
++              unsigned int rsFinishI          : 1; /* owner bit error interrupt */
++              unsigned int tsEOFI                     : 1; /* RAID XOR fetch DMA end of frame interrupt */
++              unsigned int tsEODI                     : 1; /* RAID XOR fetch DMA end of descriptor interrupt */
++              unsigned int tsPErrI            : 1; /* RAID XOR fetch descriptor protocol error interrupt */
++              unsigned int tsDErrI            : 1; /* AHB bus error interrupt */
++              unsigned int tsFinishI          : 1; /* owner bit error interrupt */
++              #endif
++      } bits;
++} RAID_DMA_STATUS_T;
++
++
++typedef union
++{
++      unsigned int bits32;
++      struct bits_ff08
++      {
++              #ifdef BIG_ENDIAN
++              unsigned int td_start           :  1;   /* Start DMA transfer */
++              unsigned int td_continue        :  1;   /* Continue DMA operation */
++              unsigned int td_chain_mode      :  1;   /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
++              unsigned int                            :  1;
++              unsigned int td_prot            :  4;   /* DMA protection control */
++              unsigned int td_burst_size  :  2;       /* DMA max burst size for every AHB request */
++              unsigned int td_bus                 :  2;       /* peripheral bus width */
++              unsigned int td_endian          :  1;   /* AHB Endian. 0-little endian; 1-big endian */
++              unsigned int td_finish_en   :  1;       /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
++              unsigned int td_fail_en         :  1;   /* DMA Fail Interrupt Enable;1-enable;0-mask */
++              unsigned int td_perr_en         :  1;   /* Protocol Failure Interrupt Enable;1-enable;0-mask */
++              unsigned int td_eod_en          :  1;   /* End of Descriptor interrupt Enable;1-enable;0-mask */
++              unsigned int td_eof_en      :  1;   /* End of frame interrupt Enable;1-enable;0-mask */
++              unsigned int                            : 14;
++              #else
++              unsigned int                            : 14;
++              unsigned int td_eof_en      :  1;   /* End of frame interrupt Enable;1-enable;0-mask */
++              unsigned int td_eod_en          :  1;   /* End of Descriptor interrupt Enable;1-enable;0-mask */
++              unsigned int td_perr_en         :  1;   /* Protocol Failure Interrupt Enable;1-enable;0-mask */
++              unsigned int td_fail_en         :  1;   /* DMA Fail Interrupt Enable;1-enable;0-mask */
++              unsigned int td_finish_en   :  1;       /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
++              unsigned int td_endian          :  1;   /* AHB Endian. 0-little endian; 1-big endian */
++              unsigned int td_bus                 :  2;       /* peripheral bus width;0 - 8 bits;1 - 16 bits */
++              unsigned int td_burst_size  :  2;       /* TxDMA max burst size for every AHB request */
++              unsigned int td_prot            :  4;   /* TxDMA protection control */
++              unsigned int                            :  1;
++              unsigned int td_chain_mode      :  1;   /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
++              unsigned int td_continue        :  1;   /* Continue DMA operation */
++              unsigned int td_start           :  1;   /* Start DMA transfer */
++              #endif
++      } bits;
++} RAID_TXDMA_CTRL_T;
++
++typedef union
++{
++      unsigned int bits32;
++      struct bits_ff0c
++      {
++              #ifdef BIG_ENDIAN
++              unsigned int td_first_des_ptr   : 28;/* first descriptor address */
++              unsigned int td_busy                    :  1;/* 1-TxDMA busy; 0-TxDMA idle */
++              unsigned int                                    :  3;
++              #else
++              unsigned int                                    :  3;
++              unsigned int td_busy                    :  1;/* 1-TxDMA busy; 0-TxDMA idle */
++              unsigned int td_first_des_ptr   : 28;/* first descriptor address */
++              #endif
++      } bits;
++} RAID_TXDMA_FIRST_DESC_T;
++
++typedef union
++{
++      unsigned int bits32;
++      struct bits_ff10
++      {
++              #ifdef BIG_ENDIAN
++              unsigned int ndar                       : 28;   /* next descriptor address */
++              unsigned int eofie                      :  1;   /* end of frame interrupt enable */
++              unsigned int                            :  1;
++              unsigned int sof_eof            :  2;
++              #else
++              unsigned int sof_eof            :  2;
++              unsigned int                            :  1;
++              unsigned int eofie                      :  1;   /* end of frame interrupt enable */
++              unsigned int ndar                       : 28;   /* next descriptor address */
++              #endif
++      } bits;
++} RAID_TXDMA_CURR_DESC_T;
++
++typedef union
++{
++      unsigned int bits32;
++      struct bits_ff14
++      {
++              #ifdef BIG_ENDIAN
++              unsigned int rd_start           :  1;   /* Start DMA transfer */
++              unsigned int rd_continue        :  1;   /* Continue DMA operation */
++              unsigned int rd_chain_mode      :  1;   /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
++              unsigned int                            :  1;
++              unsigned int rd_prot            :  4;   /* DMA protection control */
++              unsigned int rd_burst_size  :  2;       /* DMA max burst size for every AHB request */
++              unsigned int rd_bus                 :  2;       /* peripheral bus width;0 - 8 bits;1 - 16 bits */
++              unsigned int rd_endian          :  1;   /* AHB Endian. 0-little endian; 1-big endian */
++              unsigned int rd_finish_en   :  1;       /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
++              unsigned int rd_fail_en         :  1;   /* DMA Fail Interrupt Enable;1-enable;0-mask */
++              unsigned int rd_perr_en         :  1;   /* Protocol Failure Interrupt Enable;1-enable;0-mask */
++              unsigned int rd_eod_en          :  1;   /* End of Descriptor interrupt Enable;1-enable;0-mask */
++              unsigned int rd_eof_en      :  1;   /* End of frame interrupt Enable;1-enable;0-mask */
++              unsigned int                            : 14;
++              #else
++              unsigned int                            : 14;
++              unsigned int rd_eof_en      :  1;   /* End of frame interrupt Enable;1-enable;0-mask */
++              unsigned int rd_eod_en          :  1;   /* End of Descriptor interrupt Enable;1-enable;0-mask */
++              unsigned int rd_perr_en         :  1;   /* Protocol Failure Interrupt Enable;1-enable;0-mask */
++              unsigned int rd_fail_en         :  1;   /* DMA Fail Interrupt Enable;1-enable;0-mask */
++              unsigned int rd_finish_en   :  1;       /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
++              unsigned int rd_endian          :  1;   /* AHB Endian. 0-little endian; 1-big endian */
++              unsigned int rd_bus                 :  2;       /* peripheral bus width;0 - 8 bits;1 - 16 bits */
++              unsigned int rd_burst_size  :  2;       /* DMA max burst size for every AHB request */
++              unsigned int rd_prot            :  4;   /* DMA protection control */
++              unsigned int                            :  1;
++              unsigned int rd_chain_mode      :  1;   /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
++              unsigned int rd_continue        :  1;   /* Continue DMA operation */
++              unsigned int rd_start           :  1;   /* Start DMA transfer */
++              #endif
++      } bits;
++} RAID_RXDMA_CTRL_T;
++
++typedef union
++{
++      unsigned int bits32;
++      struct bits_ff18
++      {
++              #ifdef BIG_ENDIAN
++              unsigned int rd_first_des_ptr   : 28;/* first descriptor address */
++              unsigned int rd_busy                    :  1;/* 1-RxDMA busy; 0-RxDMA idle */
++              unsigned int                                    :  3;
++              #else
++              unsigned int                                    :  3;
++              unsigned int rd_busy                    :  1;/* 1-RxDMA busy; 0-RxDMA idle */
++              unsigned int rd_first_des_ptr   : 28;/* first descriptor address */
++              #endif
++      } bits;
++} RAID_RXDMA_FIRST_DESC_T;
++
++typedef union
++{
++      unsigned int bits32;
++      struct bits_ff1c
++      {
++              #ifdef BIG_ENDIAN
++              unsigned int ndar                       : 28;   /* next descriptor address */
++              unsigned int eofie                      :  1;   /* end of frame interrupt enable */
++              unsigned int dec                        :  1;   /* AHB bus address increment(0)/decrement(1) */
++              unsigned int sof_eof            :  2;
++              #else
++              unsigned int sof_eof            :  2;
++              unsigned int dec                        :  1;   /* AHB bus address increment(0)/decrement(1) */
++              unsigned int eofie                      :  1;   /* end of frame interrupt enable */
++              unsigned int ndar                       : 28;   /* next descriptor address */
++              #endif
++      } bits;
++} RAID_RXDMA_CURR_DESC_T;
++
++typedef union
++{
++      unsigned int bit32;
++      struct bits_ff50
++      {
++              unsigned int pat                        : 32; /* data for pattern check */
++      } bits;
++} RAID_PACR_T;
++
++/******************************************************/
++/*    the definition of DMA Descriptor Register     */
++/******************************************************/
++typedef struct raid_descriptor_t
++{
++      union func_ctrl_t
++      {
++              unsigned int bit32;
++              struct bits_0000
++              {
++                      #ifdef BIG_ENDIAN
++                      unsigned int own                                : 1; /* owner bit */
++                      unsigned int derr                               : 1;    /* data error during processing this descriptor */
++                      unsigned int perr                               : 1;    /* protocol error during processing this descriptor */
++                      unsigned int raid_ctrl_status   : 7; /* pass RAID XOR fetch/store control status to CPU */
++                      unsigned int desc_cnt                   : 6;
++                      unsigned int buffer_size                : 16;   /* transfer buffer size associated with current description*/
++                      #else
++                      unsigned int buffer_size                : 16;   /* transfer buffer size associated with current description*/
++                      unsigned int desc_cnt                   : 6;
++                      unsigned int raid_ctrl_status   : 7; /* pass RAID XOR fetch/store control status to CPU */
++                      unsigned int perr                               : 1;    /* protocol error during processing this descriptor */
++                      unsigned int derr                               : 1;    /* data error during processing this descriptor */
++                      unsigned int own                                : 1; /* owner bit */
++                      #endif
++              } bits;
++      } func_ctrl;
++
++      union flg_status_t
++      {
++              unsigned int bits32;
++              struct bit_004
++              {
++                      #ifdef BIG_ENDIAN
++                      unsigned int bcc                : 16;
++                      unsigned int                    : 13
++                      unsigned int mode               : 3;
++                      #else
++                      unsigned int mode               : 3;
++                      unsigned int                    : 13;
++                      unsigned int bcc                : 16;
++                      #endif
++              } bits_cmd_status;
++      } flg_status;  //Sanders
++
++      unsigned int buf_addr;
++
++      union next_desc_addr_t
++      {
++              unsigned int bits32;
++              struct bits_000c
++              {
++                      #ifdef BIG_ENDIAN
++                      unsigned int ndar               : 28; /* next descriptor address */
++                      unsigned int eofie              : 1; /* end of frame interrupt enable */
++                      unsigned int                    : 1;
++                      unsigned int sof_eof    : 2; /* the position of the descriptor in chain */
++                      #else
++                      unsigned int sof_eof    : 2; /* the position of the descriptor in chain */
++                      unsigned int                    : 1;
++                      unsigned int eofie              : 1; /* end of frame interrupt enable */
++                      unsigned int ndar               : 28; /* next descriptor address */
++                      #endif
++              } bits;
++      } next_desc_addr;
++} RAID_DESCRIPTOR_T;
++
++/******************************************************/
++/*    the offset of RAID SMC register               */
++/******************************************************/
++enum RAID_SMC_REGISTER {
++      RAID_SMC_CMD_REG                = 0xff60,
++      RAID_SMC_STATUS_REG             = 0xff64
++      };
++
++/******************************************************/
++/*    the definition of RAID SMC module register    */
++/******************************************************/
++typedef union
++{
++      unsigned int bits32;
++      struct bits_ff60
++      {
++              #ifdef BIG_ENDIAN
++              unsigned int pat_mode           : 2; /* partition mode selection */
++              unsigned int                            : 14;
++              unsigned int device_id          : 12;
++              unsigned int revision_id        : 4;
++              #else
++              unsigned int revision_id        : 4;
++              unsigned int device_id          : 12;
++              unsigned int                            : 14;
++              unsigned int pat_mode           : 2; /* partition mode selection */
++              #endif
++      } bits;
++} RAID_SMC_CMD;
++
++typedef union
++{
++      unsigned int bits32;
++      struct bits_ff64
++      {
++              #ifdef BIG_ENDIAN
++              unsigned int addr_err1          : 1; /* address is out of range for controller 1 */
++              unsigned int ahb_err1           : 1; /* AHB bus error for controller 1 */
++              unsigned int                            : 14;
++              unsigned int addr_err2          : 1;    /* address is out of range for controller 2 */
++              unsigned int ahb_err2           : 1; /* AHB bus error for controller 2 */
++              unsigned int                            : 14;
++              #else
++              unsigned int                            : 14;
++              unsigned int ahb_err2           : 1; /* AHB bus error for controller 2 */
++              unsigned int addr_err2          : 1;    /* address is out of range for controller 2 */
++              unsigned int                            : 14;
++              unsigned int ahb_err1           : 1; /* AHB bus error for controller 1 */
++              unsigned int addr_err1          : 1; /* address is out of range for controller 1 */
++              #endif
++      } bits;
++} RAID_SMC_STATUS;
++
++typedef struct RAID_S
++{
++      const char *device_name;
++      wait_queue_head_t wait;
++      unsigned int busy;
++      int irq;
++      unsigned int status;
++      RAID_DESCRIPTOR_T *tx_desc;  /*   point to virtual TX descriptor address */
++      RAID_DESCRIPTOR_T *rx_desc;  /* point ot virtual RX descriptor address */
++      RAID_DESCRIPTOR_T *tx_cur_desc; /* current TX descriptor */
++      RAID_DESCRIPTOR_T *rx_cur_desc; /* current RX descriptor */
++      RAID_DESCRIPTOR_T *tx_finished_desc;
++      RAID_DESCRIPTOR_T *rx_finished_desc;
++      RAID_DESCRIPTOR_T *tx_first_desc;
++      RAID_DESCRIPTOR_T *rx_first_desc;
++
++//    unsigned int *tx_buf[TX_DESC_NUM];
++      unsigned int *rx_desc_dma;                      // physical address of rx_descript
++      unsigned int *tx_desc_dma;                      // physical address of tx_descript
++      unsigned int *rx_bufs_dma;
++      unsigned int *tx_bufs_dma;
++
++} RAID_T;
++
++struct reg_ioctl
++{
++      unsigned int reg_addr;
++      unsigned int val_in;
++      unsigned int val_out;
++};
++
++typedef struct dma_ctrl {
++      int sram;
++      int prot;
++      int burst;
++      int bus;
++      int endian;
++      int mode;
++} DMA_CTRL;
++
++
++#ifdef XOR_SW_FILL_IN
++
++#define __XOR(a1, a2) a1 ^= a2
++
++#define GET_BLOCK_2(dst) \
++      __asm__("ldmia  %0, {%1, %2}" \
++              : "=r" (dst), "=r" (a1), "=r" (a2) \
++              : "0" (dst))
++
++#define GET_BLOCK_4(dst) \
++      __asm__("ldmia  %0, {%1, %2, %3, %4}" \
++              : "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \
++              : "0" (dst))
++
++#define XOR_BLOCK_2(src) \
++      __asm__("ldmia  %0!, {%1, %2}" \
++              : "=r" (src), "=r" (b1), "=r" (b2) \
++              : "0" (src)); \
++      __XOR(a1, b1); __XOR(a2, b2);
++
++#define XOR_BLOCK_4(src) \
++      __asm__("ldmia  %0!, {%1, %2, %3, %4}" \
++              : "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \
++              : "0" (src)); \
++      __XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4)
++
++#define PUT_BLOCK_2(dst) \
++      __asm__ __volatile__("stmia     %0!, {%2, %3}" \
++              : "=r" (dst) \
++              : "0" (dst), "r" (a1), "r" (a2))
++
++#define PUT_BLOCK_4(dst) \
++      __asm__ __volatile__("stmia     %0!, {%2, %3, %4, %5}" \
++              : "=r" (dst) \
++              : "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4))
++
++static void
++xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
++{
++      unsigned int lines = bytes / sizeof(unsigned long) / 4;
++      register unsigned int a1 __asm__("r4");
++      register unsigned int a2 __asm__("r5");
++      register unsigned int a3 __asm__("r6");
++      register unsigned int a4 __asm__("r7");
++      register unsigned int b1 __asm__("r8");
++      register unsigned int b2 __asm__("r9");
++      register unsigned int b3 __asm__("ip");
++      register unsigned int b4 __asm__("lr");
++
++      do {
++              GET_BLOCK_4(p1);
++              XOR_BLOCK_4(p2);
++              PUT_BLOCK_4(p1);
++      } while (--lines);
++}
++
++static void
++xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++              unsigned long *p3)
++{
++      unsigned int lines = bytes / sizeof(unsigned long) / 4;
++      register unsigned int a1 __asm__("r4");
++      register unsigned int a2 __asm__("r5");
++      register unsigned int a3 __asm__("r6");
++      register unsigned int a4 __asm__("r7");
++      register unsigned int b1 __asm__("r8");
++      register unsigned int b2 __asm__("r9");
++      register unsigned int b3 __asm__("ip");
++      register unsigned int b4 __asm__("lr");
++
++      do {
++              GET_BLOCK_4(p1);
++              XOR_BLOCK_4(p2);
++              XOR_BLOCK_4(p3);
++              PUT_BLOCK_4(p1);
++      } while (--lines);
++}
++
++static void
++xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++              unsigned long *p3, unsigned long *p4)
++{
++      unsigned int lines = bytes / sizeof(unsigned long) / 2;
++      register unsigned int a1 __asm__("r8");
++      register unsigned int a2 __asm__("r9");
++      register unsigned int b1 __asm__("ip");
++      register unsigned int b2 __asm__("lr");
++
++      do {
++              GET_BLOCK_2(p1);
++              XOR_BLOCK_2(p2);
++              XOR_BLOCK_2(p3);
++              XOR_BLOCK_2(p4);
++              PUT_BLOCK_2(p1);
++      } while (--lines);
++}
++
++static void
++xor_arm4regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++              unsigned long *p3, unsigned long *p4, unsigned long *p5)
++{
++      unsigned int lines = bytes / sizeof(unsigned long) / 2;
++      register unsigned int a1 __asm__("r8");
++      register unsigned int a2 __asm__("r9");
++      register unsigned int b1 __asm__("ip");
++      register unsigned int b2 __asm__("lr");
++
++      do {
++              GET_BLOCK_2(p1);
++              XOR_BLOCK_2(p2);
++              XOR_BLOCK_2(p3);
++              XOR_BLOCK_2(p4);
++              XOR_BLOCK_2(p5);
++              PUT_BLOCK_2(p1);
++      } while (--lines);
++}
++#endif        //XOR_SW_FILL_IN
++
+--- /dev/null
++++ b/arch/arm/mach-sl2312/irq.c
+@@ -0,0 +1,202 @@
++/*
++ *  linux/arch/arm/mach-epxa10db/irq.c
++ *
++ *  Copyright (C) 2001 Altera Corporation
++ *
++ * 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 program is distributed in the hope that 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
++ */
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/stddef.h>
++#include <linux/list.h>
++#include <linux/sched.h>
++#include <asm/hardware.h>
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <asm/mach/irq.h>
++#include <asm/arch/platform.h>
++#include <asm/arch/int_ctrl.h>
++
++#ifdef CONFIG_PCI
++#include <asm/arch/pci.h>
++#endif
++
++int fixup_irq(unsigned int irq)
++{
++#ifdef CONFIG_PCI
++      if (irq == IRQ_PCI) {
++              return sl2312_pci_get_int_src();
++      }
++#endif
++      return irq;
++}
++
++static void sl2312_ack_irq(unsigned int irq)
++{
++   __raw_writel(1 << irq, IRQ_CLEAR(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++}
++
++static void sl2312_mask_irq(unsigned int irq)
++{
++      unsigned int mask;
++
++#ifdef CONFIG_PCI
++      if (irq >= PCI_IRQ_OFFSET)
++      {
++              mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++              mask &= ~IRQ_PCI_MASK ;
++              __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++              sl2312_pci_mask_irq(irq - PCI_IRQ_OFFSET);
++      }
++      else
++#endif
++      if(irq >= FIQ_OFFSET)
++      {
++           mask = __raw_readl(FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++           mask &= ~(1 << (irq - FIQ_OFFSET));
++           __raw_writel(mask, FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++        }
++        else
++        {
++           mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++           mask &= ~(1 << irq);
++           __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++        }
++
++}
++
++static void sl2312_unmask_irq(unsigned int irq)
++{
++      unsigned int mask;
++
++#ifdef CONFIG_PCI
++      if (irq >= PCI_IRQ_OFFSET)
++      {
++              mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++              mask |= IRQ_PCI_MASK ;
++              __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++              sl2312_pci_unmask_irq(irq - PCI_IRQ_OFFSET);
++      }
++      else
++#endif
++      if(irq >= FIQ_OFFSET)
++        {
++          mask = __raw_readl(FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++          mask |= (1 << (irq - FIQ_OFFSET));
++          __raw_writel(mask, FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++      }
++        else
++        {
++          mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++          mask |= (1 << irq);
++          __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++        }
++}
++
++static struct irq_chip sl2312_level_irq = {
++        .ack            = sl2312_mask_irq,
++        .mask           = sl2312_mask_irq,
++        .unmask         = sl2312_unmask_irq,
++//            .set_type       = ixp4xx_set_irq_type,
++};
++
++static struct irq_chip sl2312_edge_irq = {
++        .ack            = sl2312_ack_irq,
++        .mask           = sl2312_mask_irq,
++        .unmask         = sl2312_unmask_irq,
++//            .set_type       = ixp4xx_set_irq_type,
++};
++
++static struct resource irq_resource = {
++        .name   = "irq_handler",
++        .start  = IO_ADDRESS(SL2312_INTERRUPT_BASE),
++        .end    = IO_ADDRESS(FIQ_STATUS(SL2312_INTERRUPT_BASE))+4,
++};
++
++void __init sl2312_init_irq(void)
++{
++      unsigned int i, mode, level;
++
++    request_resource(&iomem_resource, &irq_resource);
++
++      for (i = 0; i < NR_IRQS; i++)
++      {
++          if((i>=IRQ_TIMER1 && i<=IRQ_TIMER3)||(i>=IRQ_SERIRQ0 && i<=IRQ_SERIRQ_MAX))
++        {
++              set_irq_chip(i, &sl2312_edge_irq);
++              set_irq_handler(i, handle_edge_irq);
++        }
++          else
++        {
++              set_irq_chip(i, &sl2312_level_irq);
++            set_irq_handler(i,handle_level_irq);
++        }
++        set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
++      }
++
++      /* Disable all interrupt */
++      __raw_writel(0,IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++      __raw_writel(0,FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++
++      /* Set interrupt mode */
++    /* emac & ipsec type is level trigger and high active */
++    mode = __raw_readl(IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++    level = __raw_readl(IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++
++      mode &= ~IRQ_GMAC0_MASK;
++      level &= ~IRQ_GMAC0_MASK;
++
++      mode &= ~IRQ_GMAC1_MASK;
++      level &= ~IRQ_GMAC1_MASK;
++
++      mode &= ~IRQ_IPSEC_MASK;
++      level &= ~IRQ_IPSEC_MASK;
++
++      // for IDE0,1, high active and level trigger
++      mode &= ~IRQ_IDE0_MASK;
++      level &= ~IRQ_IDE0_MASK;
++      mode &= ~IRQ_IDE1_MASK;
++      level &= ~IRQ_IDE1_MASK;
++
++
++      // for PCI, high active and level trigger
++      mode &= ~IRQ_PCI_MASK;
++      level &= ~IRQ_PCI_MASK;
++
++      // for USB, high active and level trigger
++      mode &= ~IRQ_USB0_MASK;
++      level &= ~IRQ_USB0_MASK;
++
++      mode &= ~IRQ_USB1_MASK;
++      level &= ~IRQ_USB1_MASK;
++
++      // for LPC, high active and edge trigger
++      mode |= 0xffff0000;
++      level &= 0x0000ffff;
++
++      // for GPIO, high active and level trigger
++      mode &= ~(IRQ_GPIO_MASK);
++      level &= ~(IRQ_GPIO_MASK);
++
++      mode &= ~(IRQ_GPIO1_MASK);
++      level &= ~(IRQ_GPIO1_MASK);
++
++      mode &= ~(IRQ_GPIO2_MASK);
++      level &= ~(IRQ_GPIO2_MASK);
++
++      __raw_writel(mode,IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++      __raw_writel(level,IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
++
++}
+--- /dev/null
++++ b/arch/arm/mach-sl2312/lpc.c
+@@ -0,0 +1,125 @@
++/*
++ *
++ * BRIEF MODULE DESCRIPTION
++ *    ITE Semi IT8712 Super I/O functions.
++ *
++ * Copyright 2001 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc.
++ *            ppopov@mvista.com or source@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/kernel.h>
++#include <linux/delay.h>
++#include <asm/io.h>
++#include <asm/types.h>
++#include <asm/arch/it8712.h>
++#include <linux/init.h>
++#include <asm/arch/hardware.h>
++
++#ifndef TRUE
++#define TRUE 1
++#endif
++
++#ifndef FALSE
++#define FALSE 0
++#endif
++
++
++// MB PnP configuration register
++#define LPC_KEY_ADDR  (IO_ADDRESS(SL2312_LPC_IO_BASE) + 0x2e)
++#define LPC_DATA_ADDR (IO_ADDRESS(SL2312_LPC_IO_BASE) + 0x2f)
++
++#define LPC_BUS_CTRL                  *(volatile unsigned char*) (IO_ADDRESS(SL2312_LPC_HOST_BASE) + 0)
++#define LPC_BUS_STATUS                        *(volatile unsigned char*) (IO_ADDRESS(SL2312_LPC_HOST_BASE) + 2)
++#define LPC_SERIAL_IRQ_CTRL           *(volatile unsigned char*) (IO_ADDRESS(SL2312_LPC_HOST_BASE) + 4)
++
++int it8712_exist;
++
++static void LPCEnterMBPnP(void)
++{
++      int i;
++      unsigned char key[4] = {0x87, 0x01, 0x55, 0x55};
++
++      for (i = 0; i<4; i++)
++              outb(key[i], LPC_KEY_ADDR);
++
++}
++
++static void LPCExitMBPnP(void)
++{
++      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;
++}
++
++static int SearchIT8712(void)
++{
++      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;
++}
++
++int InitLPCInterface(void)
++{
++      LPC_BUS_CTRL = 0xc0;
++      LPC_SERIAL_IRQ_CTRL = 0xc0;
++      mdelay(1);              // wait for 1 serial IRQ cycle
++      LPC_SERIAL_IRQ_CTRL = 0x80;
++      it8712_exist = SearchIT8712();
++      printk("IT8712 %s exist\n", it8712_exist?"":"doesn't");
++      return 0;
++}
++
++//__initcall(InitLPCInterface);
+--- /dev/null
++++ b/arch/arm/mach-sl2312/mm.c
+@@ -0,0 +1,80 @@
++/*
++ *  linux/arch/arm/mach-epxa10db/mm.c
++ *
++ *  MM routines for Altera'a Epxa10db board
++ *
++ *  Copyright (C) 2001 Altera Corporation
++ *
++ * 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 program is distributed in the hope that 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
++ */
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <linux/init.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/page.h>
++#include <asm/sizes.h>
++
++#include <asm/mach/map.h>
++
++/* Page table mapping for I/O region */
++static struct map_desc sl2312_io_desc[] __initdata = {
++#ifdef CONFIG_GEMINI_IPI
++{__phys_to_virt(CPU_1_MEM_BASE),         __phys_to_pfn(CPU_1_MEM_BASE),        SZ_64M,  MT_MEMORY},
++#endif
++{IO_ADDRESS(SL2312_SRAM_BASE),         __phys_to_pfn(SL2312_SRAM_BASE),        SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_DRAM_CTRL_BASE),    __phys_to_pfn(SL2312_DRAM_CTRL_BASE),   SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_GLOBAL_BASE),       __phys_to_pfn(SL2312_GLOBAL_BASE),      SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_WAQTCHDOG_BASE),    __phys_to_pfn(SL2312_WAQTCHDOG_BASE),   SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_UART_BASE),         __phys_to_pfn(SL2312_UART_BASE),        SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_TIMER_BASE),        __phys_to_pfn(SL2312_TIMER_BASE),       SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_LCD_BASE),          __phys_to_pfn(SL2312_LCD_BASE),         SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_RTC_BASE),          __phys_to_pfn(SL2312_RTC_BASE),         SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_SATA_BASE),         __phys_to_pfn(SL2312_SATA_BASE),        SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_LPC_HOST_BASE),     __phys_to_pfn(SL2312_LPC_HOST_BASE),    SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_LPC_IO_BASE),       __phys_to_pfn(SL2312_LPC_IO_BASE),      SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_INTERRUPT_BASE),    __phys_to_pfn(SL2312_INTERRUPT_BASE),   SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_INTERRUPT1_BASE),   __phys_to_pfn(SL2312_INTERRUPT1_BASE),  SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_SSP_CTRL_BASE),     __phys_to_pfn(SL2312_SSP_CTRL_BASE),    SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_POWER_CTRL_BASE),   __phys_to_pfn(SL2312_POWER_CTRL_BASE),  SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_CIR_BASE),          __phys_to_pfn(SL2312_CIR_BASE),         SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_GPIO_BASE),         __phys_to_pfn(SL2312_GPIO_BASE),        SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_GPIO_BASE1),        __phys_to_pfn(SL2312_GPIO_BASE1),       SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_GPIO_BASE2),        __phys_to_pfn(SL2312_GPIO_BASE2),       SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_PCI_IO_BASE),         __phys_to_pfn(SL2312_PCI_IO_BASE),      SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_PCI_MEM_BASE),        __phys_to_pfn(SL2312_PCI_MEM_BASE),     SZ_512K,  MT_DEVICE},
++#ifdef CONFIG_NET_SL351X
++{IO_ADDRESS(SL2312_TOE_BASE),         __phys_to_pfn(SL2312_TOE_BASE)       ,   SZ_512K,  MT_DEVICE},
++#endif
++{IO_ADDRESS(SL2312_GMAC0_BASE),              __phys_to_pfn(SL2312_GMAC0_BASE),           SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_GMAC1_BASE),              __phys_to_pfn(SL2312_GMAC1_BASE),           SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_SECURITY_BASE),     __phys_to_pfn(SL2312_SECURITY_BASE),    SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_IDE0_BASE),         __phys_to_pfn(SL2312_IDE0_BASE),        SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_IDE1_BASE),         __phys_to_pfn(SL2312_IDE1_BASE),        SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_RAID_BASE),         __phys_to_pfn(SL2312_RAID_BASE),        SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_FLASH_CTRL_BASE),   __phys_to_pfn(SL2312_FLASH_CTRL_BASE),  SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_DRAM_CTRL_BASE),    __phys_to_pfn(SL2312_DRAM_CTRL_BASE),   SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_GENERAL_DMA_BASE),  __phys_to_pfn(SL2312_GENERAL_DMA_BASE), SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_USB0_BASE),         __phys_to_pfn(SL2312_USB_BASE),         SZ_512K,  MT_DEVICE},
++{IO_ADDRESS(SL2312_USB1_BASE),         __phys_to_pfn(SL2312_USB1_BASE),        SZ_512K,  MT_DEVICE},
++{FLASH_VADDR(SL2312_FLASH_BASE),       __phys_to_pfn(SL2312_FLASH_BASE),       SZ_16M,    MT_DEVICE},
++};
++
++void __init sl2312_map_io(void)
++{
++      iotable_init(sl2312_io_desc, ARRAY_SIZE(sl2312_io_desc));
++}
+--- /dev/null
++++ b/arch/arm/mach-sl2312/pci.c
+@@ -0,0 +1,359 @@
++/*
++ *  linux/arch/arm/mach-sl2312/pci_sl2312.c
++ *
++ *  PCI functions for sl2312 host PCI bridge
++ *
++ *  Copyright (C) 2003 StorLink Corp.
++ *
++ * 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 program is distributed in the hope that 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
++ */
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/ptrace.h>
++#include <linux/slab.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/init.h>
++
++#include <asm/sizes.h>
++#include <asm/hardware.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++#include <asm/mach/pci.h>
++#include <asm/mach/irq.h>
++#include <asm/mach-types.h>
++
++#include <asm/arch/pci.h>
++
++//#define DEBUG
++
++// sl2312 PCI bridge access routines
++
++#define PCI_IOSIZE_REG        (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE)))
++#define PCI_PROT_REG  (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x04))
++#define PCI_CTRL_REG  (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x08))
++#define PCI_SOFTRST_REG       (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x10))
++#define PCI_CONFIG_REG        (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x28))
++#define PCI_DATA_REG  (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x2C))
++
++static spinlock_t sl2312_pci_lock = SPIN_LOCK_UNLOCKED;
++// for initialize PCI devices
++struct resource pci_ioport_resource = {
++              .name = "PCI I/O Space",
++              .start = IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x100,
++              .end = IO_ADDRESS(SL2312_PCI_IO_BASE) + SZ_512K - 1,
++              .flags = IORESOURCE_IO,
++};
++struct resource pci_iomem_resource = {
++              .name = "PCI Mem Space",
++              .start = SL2312_PCI_MEM_BASE,
++              .end = SL2312_PCI_MEM_BASE + SZ_128M - 1,
++              .flags = IORESOURCE_MEM,
++};
++
++static int sl2312_read_config(struct pci_bus *bus, unsigned int devfn, int where,int size, u32 *val)
++{
++      unsigned long addr,data;
++      unsigned long flags;
++
++      spin_lock_irqsave(&sl2312_pci_lock, flags);
++    addr = 0x80000000 | (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | (where & ~3);
++      PCI_CONFIG_REG = addr;
++      data = PCI_DATA_REG;
++
++      switch (size) {
++      case 1:
++          *val = (u8) (data >> ((where & 0x03) * 8));
++              break;
++      case 2:
++          *val = (u16) (data >> ((where & 0x02) * 8));
++              break;
++      case 4:
++          *val = data;
++      if ((where >= 0x10) && (where <= 0x24)) {
++              if ((*val & 0xfff00000) == SL2312_PCI_IO_BASE) {
++                      *val &= 0x000fffff;
++                      *val |= IO_ADDRESS(SL2312_PCI_IO_BASE);
++              }
++      }
++              break;
++      }
++      spin_unlock_irqrestore(&sl2312_pci_lock, flags);
++//    printk("READ==>slot=%d fn=%d where=%d value=%x\n",PCI_SLOT(devfn),PCI_FUNC(devfn),where,*val);
++      return PCIBIOS_SUCCESSFUL;
++}
++
++static int sl2312_write_config(struct pci_bus *bus, unsigned int devfn, int where,int size, u32 val)
++{
++      unsigned long addr,data;
++      unsigned long flags;
++
++      spin_lock_irqsave(&sl2312_pci_lock, flags);
++    addr = 0x80000000 | (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | (where & ~3);
++      PCI_CONFIG_REG = addr;
++      data = PCI_DATA_REG;
++
++      switch (size) {
++      case 1:
++      data &= ~(0xff << ((where & 0x03) * 8));
++      data |= (val << ((where & 0x03) * 8));
++      PCI_DATA_REG = data;
++              break;
++      case 2:
++      data &= ~(0xffff << ((where & 0x02) * 8));
++      data |= (val << ((where & 0x02) * 8));
++      PCI_DATA_REG = data;
++              break;
++      case 4:
++      if ((where >= 0x10) && (where <= 0x24)) {
++              if ((val & 0xfff00000) == IO_ADDRESS(SL2312_PCI_IO_BASE)) {
++                      val &= 0x000fffff;
++                      val |= SL2312_PCI_IO_BASE;
++              }
++      }
++          PCI_DATA_REG = val;
++              break;
++      }
++      spin_unlock_irqrestore(&sl2312_pci_lock, flags);
++
++//    printk("WRITE==> slot=%d fn=%d where=%d value=%x \n",PCI_SLOT(devfn),PCI_FUNC(devfn),where,val);
++      return PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops sl2312_pci_ops = {
++      .read   = sl2312_read_config,
++      .write  = sl2312_write_config,
++};
++
++
++int __init sl2312_pci_setup_resources(struct resource **resource)
++{
++      PCI_IOSIZE_REG = 0;             // 1M IO size
++      PCI_CTRL_REG = 0x06;
++
++      resource[0] = &pci_ioport_resource;
++      resource[1] = &pci_iomem_resource;
++      resource[2] = NULL;
++
++      return 1;
++}
++
++//static int sl2312_pci_fault(unsigned long addr, struct pt_regs *regs)
++//{
++//    return 1;
++//}
++
++
++/**********************************************************************
++ * MASK(disable) PCI interrupt
++ *    0: PCI INTA, 1: PCI INTB, ...           // for Linux interrupt routing
++ *   16: PERR                                                         // for PCI module internal use
++ *   17: SERR,.. respect to PCI CTRL2 REG
++ **********************************************************************/
++void sl2312_pci_mask_irq(unsigned int irq)
++{
++    struct pci_bus bus;
++      unsigned int tmp;
++
++    bus.number = 0;
++    sl2312_read_config(&bus, 0, SL2312_PCI_CTRL2, 4, &tmp);
++      if (irq < 16) {                                         // for linux int routing
++              tmp &= ~(1 << (irq + 16 + 6));
++      }
++      else {
++              tmp &= ~(1 << irq);
++      }
++    sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
++}
++
++/* UNMASK(enable) PCI interrupt */
++void sl2312_pci_unmask_irq(unsigned int irq)
++{
++    struct pci_bus bus;
++      unsigned int tmp;
++
++    bus.number = 0;
++    sl2312_read_config(&bus, 0, SL2312_PCI_CTRL2, 4, &tmp);
++      if (irq < 16) {                                         // for linux int routing
++              tmp |= (1 << (irq + 16 + 6));
++      }
++      else {
++              tmp |= (1 << irq);
++      }
++    sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
++}
++
++/* Get PCI interrupt source */
++int sl2312_pci_get_int_src(void)
++{
++    struct pci_bus bus;
++      unsigned int tmp=0;
++
++    bus.number = 0;
++    sl2312_read_config(&bus, 0, SL2312_PCI_CTRL2, 4, &tmp);
++      if (tmp & (1 << 28)) {          // PCI INTA
++        sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
++              return IRQ_PCI_INTA;
++      }
++      if (tmp & (1 << 29)) {          // PCI INTB
++        sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
++              return IRQ_PCI_INTB;
++      }
++      if (tmp & (1 << 30)) {          // PCI INTC
++        sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
++              return IRQ_PCI_INTC;
++      }
++      if (tmp & (1 << 31)) {          // PCI INTD
++        sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
++              return IRQ_PCI_INTD;
++      }
++      // otherwise, it should be a PCI error
++      return IRQ_PCI;
++}
++
++static irqreturn_t sl2312_pci_irq(int irq, void *devid)
++{
++    struct irq_desc *desc;
++      struct irqaction *action;
++      int retval = 0;
++
++    return 1;
++
++      irq = sl2312_pci_get_int_src();
++      desc = &irq_desc[irq];
++      action = desc->action;
++      do {
++              retval |= action->handler(irq, devid);
++              action = action->next;
++      } while (action);
++
++    return 1;
++}
++
++//extern int (*external_fault)(unsigned long addr, struct pt_regs *regs);
++
++void __init sl2312_pci_preinit(void)
++{
++    struct pci_bus bus;
++      unsigned long flags;
++      unsigned int temp;
++      int ret;
++
++      /*
++       * Hook in our fault handler for PCI errors
++       */
++//    external_fault = sl2312_pci_fault;
++
++      spin_lock_irqsave(&sl2312_pci_lock, flags);
++
++      /*
++       * Grab the PCI interrupt.
++       */
++      ret = request_irq(IRQ_PCI, sl2312_pci_irq, 0, "sl2312 pci int", NULL);
++      if (ret)
++              printk(KERN_ERR "PCI: unable to grab PCI error "
++                     "interrupt: %d\n", ret);
++
++      spin_unlock_irqrestore(&sl2312_pci_lock, flags);
++
++      // setup pci bridge
++    bus.number = 0;   /* device 0, function 0 */
++      temp = (SL2312_PCI_DMA_MEM1_BASE & 0xfff00000) | (SL2312_PCI_DMA_MEM1_SIZE << 16);
++    sl2312_write_config(&bus, 0, SL2312_PCI_MEM1_BASE_SIZE, 4, temp);
++}
++
++/*
++ *    No swizzle on SL2312
++ */
++static u8 __init sl2312_pci_swizzle(struct pci_dev *dev, u8 *pinp)
++{
++      return PCI_SLOT(dev->devfn);
++}
++
++/*
++ * map the specified device/slot/pin to an IRQ.  This works out such
++ * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
++ */
++static int __init sl2312_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
++{
++      int intnr = ((slot  + (pin - 1)) & 3) + 4;  /* the IRQ number of PCI bridge */
++
++      // printk("%s : slot = %d  pin = %d \n",__func__,slot,pin);
++    switch (slot)
++    {
++        case 12:
++              if (pin==1)
++              {
++                      intnr = 3;
++                  }
++                  else
++                  {
++                      intnr = 0;
++                  }
++            break;
++        case 11:
++                  intnr = (2 + (pin - 1)) & 3;
++            break;
++        case 10:
++                  intnr = (1 + (pin - 1)) & 3;
++            break;
++        case  9:
++                  intnr = (pin - 1) & 3;
++            break;
++    }
++//    if (slot == 10)
++//            intnr = (1 + (pin - 1)) & 3;
++//    else if (slot == 9)
++//            intnr = (pin - 1) & 3;
++      return (IRQ_PCI_INTA + intnr);
++}
++
++struct pci_bus * __init sl2312_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
++{
++      return (pci_scan_bus(0, &sl2312_pci_ops, sysdata));
++
++}
++
++int __init sl2312_pci_setup(int nr, struct pci_sys_data *sys)
++{
++      int ret = 0;
++
++      if (nr == 0) {
++              ret = sl2312_pci_setup_resources(sys->resource);
++      }
++
++      return ret;
++}
++
++
++struct hw_pci sl2312_pci __initdata = {
++      .setup          =       sl2312_pci_setup,
++      .preinit                =       sl2312_pci_preinit,
++      .nr_controllers =   1,
++      .swizzle                =       sl2312_pci_swizzle,
++      .map_irq                =       sl2312_pci_map_irq,
++      .scan           =   sl2312_pci_scan_bus,
++};
++
++static int __init sl2312_pci_init(void)
++{
++      if (machine_is_sl2312())
++              pci_common_init(&sl2312_pci);
++      return 0;
++}
++
++subsys_initcall(sl2312_pci_init);
+--- /dev/null
++++ b/arch/arm/mach-sl2312/sl2312-otg-1.c
+@@ -0,0 +1,64 @@
++/*
++ *  linux/arch/arm/mach-pxa/sl2312.c
++ *
++ *  Author:   Nicolas Pitre
++ *  Created:  Nov 05, 2002
++ *  Copyright:        MontaVista Software Inc.
++ *
++ * Code specific to sl2312 aka Bulverde.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/pm.h>
++#include <linux/device.h>
++#include "asm/arch/sl2312.h"
++#include "asm/arch/irqs.h"
++#include <asm/hardware.h>
++#include <asm/irq.h>
++#include <linux/platform_device.h>
++
++/*
++ * device registration specific to sl2312.
++ */
++
++static u64 sl2312_dmamask_1 = 0xffffffffUL;
++
++static struct resource sl2312_otg_resources_1[] = {
++      [0] = {
++              .start  = 0x69000000,
++              .end    = 0x69000fff,
++              .flags  = IORESOURCE_MEM,
++      },
++      [1] = {
++              .start  = IRQ_USB1,
++              .end    = IRQ_USB1,
++              .flags  = IORESOURCE_IRQ,
++      },
++};
++
++static struct platform_device ehci_1_device = {
++      .name           = "ehci-hcd-FOTG2XX",
++      .id             = -1,
++      .dev            = {
++              .dma_mask = &sl2312_dmamask_1,
++              .coherent_dma_mask = 0xffffffff,
++      },
++      .num_resources  = ARRAY_SIZE(sl2312_otg_resources_1),
++      .resource       = sl2312_otg_resources_1,
++};
++
++static struct platform_device *devices[] __initdata = {
++      &ehci_1_device,
++};
++
++static int __init sl2312_1_init(void)
++{
++      return platform_add_devices(devices, ARRAY_SIZE(devices));
++}
++
++subsys_initcall(sl2312_1_init);
+--- /dev/null
++++ b/arch/arm/mach-sl2312/sl2312-otg.c
+@@ -0,0 +1,87 @@
++/*
++ *  linux/arch/arm/mach-pxa/sl2312.c
++ *
++ *  Author:   Nicolas Pitre
++ *  Created:  Nov 05, 2002
++ *  Copyright:        MontaVista Software Inc.
++ *
++ * Code specific to sl2312 aka Bulverde.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/pm.h>
++#include <linux/device.h>
++#include "asm/arch/sl2312.h"
++#include "asm/arch/irqs.h"
++#include <asm/hardware.h>
++#include <asm/irq.h>
++#include <linux/platform_device.h>
++
++/*
++ * device registration specific to sl2312.
++ */
++
++static u64 sl2312_dmamask = 0xffffffffUL;
++
++static struct resource sl2312_otg_resources_1[] = {
++      [0] = {
++              .start  = 0x68000000,
++              .end    = 0x68000fff,
++              .flags  = IORESOURCE_MEM,
++      },
++      [1] = {
++              .start  = IRQ_USB0,
++              .end    = IRQ_USB0,
++              .flags  = IORESOURCE_IRQ,
++      },
++};
++static struct resource sl2312_otg_resources_2[] = {
++      [2] = {
++              .start  = 0x69000000,
++              .end    = 0x69000fff,
++              .flags  = IORESOURCE_MEM,
++      },
++      [3] = {
++              .start  = IRQ_USB1,
++              .end    = IRQ_USB1,
++              .flags  = IORESOURCE_IRQ,
++      },
++};
++
++static struct platform_device ehci_device_1 = {
++      .name           = "ehci-hcd-FOTG2XX",
++      .id             = 1,
++      .dev            = {
++              .dma_mask = &sl2312_dmamask,
++              .coherent_dma_mask = 0xffffffff,
++      },
++      .num_resources  = ARRAY_SIZE(sl2312_otg_resources_1),
++      .resource       = sl2312_otg_resources_1,
++};
++
++static struct platform_device ehci_device_2 = {
++      .name           = "ehci-hcd-FOTG2XX",
++      .id             = 2,
++      .dev            = {
++              .dma_mask = &sl2312_dmamask,
++              .coherent_dma_mask = 0xffffffff,
++      },
++      .num_resources  = ARRAY_SIZE(sl2312_otg_resources_2),
++      .resource       = sl2312_otg_resources_2,
++};
++
++static struct platform_device *devices[] __initdata = {
++      &ehci_device_1, /* &ehci_device_2, */
++};
++
++static int __init sl2312_init(void)
++{
++      return platform_add_devices(devices, ARRAY_SIZE(devices));
++}
++
++subsys_initcall(sl2312_init);
+--- /dev/null
++++ b/arch/arm/mach-sl2312/sl3516_device.c
+@@ -0,0 +1,89 @@
++/*
++ *  linux/arch/arm/mach-2312/sl3516_device.c
++ *
++ *  Author:   Nicolas Pitre
++ *  Created:  Nov 05, 2002
++ *  Copyright:        MontaVista Software Inc.
++ *
++ * Code specific to sl2312 aka Bulverde.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/pm.h>
++#include <linux/device.h>
++#include <linux/platform_device.h>
++#include "asm/arch/sl2312.h"
++#include "asm/arch/irqs.h"
++#include <asm/hardware.h>
++#include <asm/irq.h>
++
++/*
++ * device registration specific to sl2312.
++ */
++
++static u64 sl3516_dmamask = 0xffffffffUL;
++
++static struct resource sl3516_sata_resources[] = {
++      [0] = {
++              .start  = 0x63400000,
++              .end    = 0x63400040,
++              .flags  = IORESOURCE_MEM,
++      },
++      [1] = {
++              .start  = IRQ_IDE1,
++              .end    = IRQ_IDE1,
++              .flags  = IORESOURCE_IRQ,
++      },
++};
++
++static struct platform_device sata_device = {
++      .name           = "lepus-sata",
++      .id             = -1,
++      .dev            = {
++              .dma_mask = &sl3516_dmamask,
++              .coherent_dma_mask = 0xffffffff,
++      },
++      .num_resources  = ARRAY_SIZE(sl3516_sata_resources),
++      .resource       = sl3516_sata_resources,
++};
++
++static struct resource sl3516_sata0_resources[] = {
++      [0] = {
++              .start  = 0x63000000,
++              .end    = 0x63000040,
++              .flags  = IORESOURCE_MEM,
++      },
++      [1] = {
++              .start  = IRQ_IDE0,
++              .end    = IRQ_IDE0,
++              .flags  = IORESOURCE_IRQ,
++      },
++};
++
++static struct platform_device sata0_device = {
++      .name           = "lepus-sata0",
++      .id             = -1,
++      .dev            = {
++              .dma_mask = &sl3516_dmamask,
++              .coherent_dma_mask = 0xffffffff,
++      },
++      .num_resources  = ARRAY_SIZE(sl3516_sata0_resources),
++      .resource       = sl3516_sata0_resources,
++};
++
++static struct platform_device *sata_devices[] __initdata = {
++      &sata_device,
++      &sata0_device,
++};
++
++static int __init sl3516_init(void)
++{
++      return platform_add_devices(sata_devices, ARRAY_SIZE(sata_devices));
++}
++
++subsys_initcall(sl3516_init);
+--- /dev/null
++++ b/arch/arm/mach-sl2312/time.c
+@@ -0,0 +1,134 @@
++/*
++ *  linux/include/asm-arm/arch-epxa10db/time.h
++ *
++ *  Copyright (C) 2001 Altera Corporation
++ *
++ * 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 program is distributed in the hope that 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
++ */
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <asm/io.h>
++#include <asm/system.h>
++#include <asm/leds.h>
++#include <asm/arch/hardware.h>
++#include <asm/mach/time.h>
++#define TIMER_TYPE (volatile unsigned int*)
++#include <asm/arch/timer.h>
++// #define FIQ_PLUS     1
++
++
++/*
++ * IRQ handler for the timer
++ */
++static irqreturn_t sl2312_timer_interrupt(int irq, void *dev_id)
++{
++//        unsigned int led;
++      // ...clear the interrupt
++#ifdef FIQ_PLUS
++      *((volatile unsigned int *)FIQ_CLEAR(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER1_MASK);
++#else
++      *((volatile unsigned int *)IRQ_CLEAR(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER2_MASK);
++#endif
++
++#if 0
++        if(!(jiffies % HZ))
++        {
++            led = jiffies / HZ;
++//            printk("ticks %x \n", led);
++          }
++      do_leds();
++      do_timer(regs);
++      do_profile(regs);
++#endif
++    timer_tick();
++    return IRQ_HANDLED;
++}
++
++static struct irqaction sl2312_timer_irq = {
++      .name           = "SL2312 Timer Tick",
++      .flags          = IRQF_DISABLED | IRQF_TIMER,
++      .handler        = sl2312_timer_interrupt,
++};
++
++unsigned long sl2312_gettimeoffset (void)
++{
++    return 0L;
++}
++
++/*
++ * Set up timer interrupt, and return the current time in seconds.
++ */
++void __init sl2312_time_init(void)
++{
++      // For clock rate adjusting
++      unsigned int tick_rate=0;
++
++#ifdef CONFIG_SL3516_ASIC
++      unsigned int clock_rate_base = 130000000;
++      unsigned int reg_v=0;
++
++      //--> Add by jason for clock adjust
++      reg_v = readl(IO_ADDRESS((SL2312_GLOBAL_BASE+GLOBAL_STATUS)));
++      reg_v >>= 15;
++      tick_rate = (clock_rate_base + (reg_v & 0x07)*10000000);
++
++      //  FPGA use AHB bus tick rate
++      printk("Bus: %dMHz",tick_rate/1000000);
++
++      tick_rate /= 6;                         // APB bus run AHB*(1/6)
++
++      switch((reg_v>>3)&3){
++              case 0: printk("(1/1)\n") ;
++                                      break;
++              case 1: printk("(3/2)\n") ;
++                                      break;
++              case 2: printk("(24/13)\n") ;
++                                      break;
++              case 3: printk("(2/1)\n") ;
++                                      break;
++      }
++      //<--
++#else
++      printk("Bus: %dMHz(1/1)\n",CLOCK_TICK_RATE/1000000);            // FPGA use 20MHz
++      tick_rate = CLOCK_TICK_RATE;
++#endif
++
++
++      /*
++       * Make irqs happen for the system timer
++       */
++      // initialize timer interrupt
++      // low active and edge trigger
++#ifdef FIQ_PLUS
++      *((volatile unsigned int *)FIQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER1_MASK);
++      *((volatile unsigned int *)FIQ_LEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER1_MASK);
++      setup_irq(IRQ_TIMER1, &sl2312_timer_irq);
++      /* Start the timer */
++      *TIMER_COUNT(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(tick_rate/HZ);
++      *TIMER_LOAD(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(tick_rate/HZ);
++      *TIMER_CR(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(TIMER_1_CR_ENABLE_MSK|TIMER_1_CR_INT_MSK);
++#else
++      *((volatile unsigned int *)IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER2_MASK);
++      *((volatile unsigned int *)IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER2_MASK);
++      setup_irq(IRQ_TIMER2, &sl2312_timer_irq);
++      /* Start the timer */
++      *TIMER_COUNT(IO_ADDRESS(SL2312_TIMER2_BASE))=(unsigned int)(tick_rate/HZ);
++      *TIMER_LOAD(IO_ADDRESS(SL2312_TIMER2_BASE))=(unsigned int)(tick_rate/HZ);
++      *TIMER_CR(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(TIMER_2_CR_ENABLE_MSK|TIMER_2_CR_INT_MSK);
++#endif
++
++}
++
++
+--- /dev/null
++++ b/arch/arm/mach-sl2312/xor.c
+@@ -0,0 +1,1200 @@
++/*
++ * arch/arm/mach-sl2312/xor.c
++ *
++ * Support functions for the Gemini Soc. This is
++ * a HW XOR unit that is specifically designed for use with RAID5
++ * applications.  This driver provides an interface that is used by
++ * the Linux RAID stack.
++ *
++ * Original Author: Jason Lee<jason@storlink.com.tw>
++ *
++ * Contributors:Sanders<sanders@storlink.com.tw>
++                              Jason Lee<jason@storlink.com.tw>
++ *
++ *
++ * Maintainer: Jason Lee<jason@storlink.com.tw>
++ *
++ * Copyright (C) 2005 Storlink Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *
++ * History:   (06/25/2005, DJ) Initial Creation
++ *
++ *    Versing 1.0.0   Initial version
++ */
++
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/spinlock.h>
++#include <linux/slab.h>
++#include <linux/errno.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include <linux/wait.h>
++#include <linux/list.h>
++#include <linux/pci.h>
++#include <linux/delay.h>
++#include <linux/dma-mapping.h>
++#include <linux/mm.h>
++#include <asm/irq.h>
++#include <asm/delay.h>
++#include <asm/uaccess.h>
++#include <asm/cacheflush.h>
++#include <asm/hardware.h>
++#include <asm/arch/xor.h>
++#include <asm/pci.h>
++#include <linux/version.h>
++
++/*
++ * pick up local definitions
++ */
++#define XOR_SW_FILL_IN
++#include "hw_xor.h"
++
++
++//#define XOR_DEBUG
++//#define XOR_TEST    1
++#ifdef XOR_TEST
++#define TEST_ITERATION 1000
++#define SPIN_WAIT     1
++#endif
++#ifdef XOR_DEBUG
++#define DPRINTK(s, args...) printk("Gemini XOR: " s "\n", ## args)
++#define DENTER() DPRINTK("Entered...\n");
++#define DEXIT() DPRINTK("Exited...\n");
++#else
++#define DPRINTK(s, args...)
++#define DENTER()
++#define DEXIT()
++#endif
++
++//#define SPIN_WAIT
++
++/* globals */
++static RAID_T tp;
++static RAID_TXDMA_CTRL_T      txdma_ctrl;
++RAID_RXDMA_CTRL_T                     rxdma_ctrl;
++
++//#ifndef SPIN_WAIT
++static spinlock_t         raid_lock;
++//#endif
++
++static unsigned int     tx_desc_virtual_base;
++static unsigned int     rx_desc_virtual_base;
++RAID_DESCRIPTOR_T     *tx_desc_ptr;
++RAID_DESCRIPTOR_T     *rx_desc_ptr;
++
++/* static prototypes */
++#define DMA_MALLOC(size,handle)               pci_alloc_consistent(NULL,size,handle)
++#define DMA_MFREE(mem,size,handle)    pci_free_consistent(NULL,size,mem,handle)
++
++static int gemini_xor_init_desc(void);
++
++static unsigned int raid_read_reg(unsigned int offset)
++{
++    unsigned int    reg_val;
++
++    reg_val = readl(RAID_BASE_ADDR + offset);
++      return (reg_val);
++}
++
++static void raid_write_reg(unsigned int offset,unsigned int data,unsigned int bit_mask)
++{
++      unsigned int reg_val;
++    unsigned int *addr;
++
++      reg_val = ( raid_read_reg(offset) & (~bit_mask) ) | (data & bit_mask);
++      addr = (unsigned int *)(RAID_BASE_ADDR + offset);
++    writel(reg_val,addr);
++      return;
++}
++
++#ifndef SPIN_WAIT
++__inline__ void xor_queue_descriptor(void)
++{
++      unsigned int flags,status=1;
++
++      DPRINTK("Going to sleep");
++
++      while(status){
++              yield();
++              //schedule();
++              spin_lock_irqsave(&raid_lock,flags);
++              status = tp.busy;
++              spin_unlock_irqrestore(&raid_lock, flags);
++      }
++//    tp.status = COMPLETE;
++      DPRINTK("woken up!");
++
++}
++#endif
++
++#ifdef SPIN_WAIT
++static void gemini_xor_isr(int d_n)
++#else
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28)
++static void gemini_xor_isr(int irq, void *dev_id, struct pt_regs *regs)
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++static irqreturn_t gemini_xor_isr(int irq, void *dev_instance, struct pt_regs *regs)
++#endif
++#endif
++{
++
++      unsigned int err;
++      RAID_DMA_STATUS_T       dma_status;
++//    RAID_DESCRIPTOR_T *rdesc,*tdesc;
++//    unsigned int *paddr;
++
++      dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS);
++#ifdef SPIN_WAIT
++      while( (dma_status.bits32& (1<<31) ) ==0 ){
++              udelay(1);
++              dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS);
++      }
++
++/*    tdesc = tp.tx_first_desc;
++      rdesc = tp.rx_first_desc;
++      for(d_n;d_n>0;d_n--){
++              if( tdesc->func_ctrl.bits.own == DMA ){
++                      paddr = tdesc;
++                      printk("error tx desc:0x%x\n",*paddr++);
++                      printk("error tx desc:0x%x\n",*paddr++);
++                      printk("error tx desc:0s%x\n",*paddr++);
++                      printk("error tx desc:0x%x\n",*paddr);
++                      while(1);
++              }
++              tdesc = (RAID_DESCRIPTOR_T *)((tdesc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
++      }
++
++      if( rdesc->func_ctrl.bits.own == DMA ){
++              paddr = rdesc;
++              printk("error rx desc:0x%x\n",*paddr++);
++              printk("error rx desc:0x%x\n",*paddr++);
++              printk("error rx desc:0s%x\n",*paddr++);
++              printk("error rx desc:0x%x\n",*paddr);
++              while(1);
++      }
++*/
++#endif
++
++      if(dma_status.bits32 & ((1<<31)|(1<<26))){
++              // if no bug , we can turn off rx finish interrupt
++              dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS);
++              err = raid_read_reg(RAID_DMA_DEVICE_ID);
++              tp.busy = 0;
++
++              if(err&0x00FF0000){
++                      tp.status = ERROR;
++                      printk("XOR:<HW>%s error code %x\n",(err&0x00F00000)?"tx":"rx",err);
++
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28)
++                      return ;
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++#ifndef SPIN_WAIT
++                      return IRQ_RETVAL(IRQ_HANDLED);
++#endif
++#endif
++              }
++              // 16~19 rx error code
++              // 20~23 tx error codd
++
++              dma_status.bits.tsFinishI = 1;
++              dma_status.bits.rsFinishI = 1;
++              raid_write_reg(RAID_DMA_STATUS, dma_status.bits32,0x84000000);  // clear INT
++
++//            printk("xor %d\n",d_n);
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28)
++                      return ;
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++#ifndef SPIN_WAIT
++                      return IRQ_RETVAL(IRQ_HANDLED);
++#endif
++#endif
++      }
++
++      #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28)
++              return ;
++      #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
++      #ifndef SPIN_WAIT
++              printk("XOR: DMA status register(0x%8x)\n",dma_status.bits32);
++              return IRQ_RETVAL(IRQ_HANDLED);
++      #endif
++      #endif
++}
++
++void
++xor_gemini_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
++{
++      int status=0;
++      unsigned int flags;
++
++      if(bytes > (1<<(SRAM_PAR_SIZE+11))){
++              printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
++      }
++
++      spin_lock_irqsave(&raid_lock,flags);
++      while(tp.status != COMPLETE){
++              spin_unlock_irqrestore(&raid_lock, flags);
++              //printk("XOR yield2\n");
++#ifdef XOR_SW_FILL_IN
++              xor_arm4regs_2(bytes,p1,p2);
++              return ;
++#else
++              yield();
++#endif
++      }
++      spin_unlock_irqrestore(&raid_lock, flags);
++      tp.status = RUNNING;
++
++      // flush the cache to memory before H/W XOR touches them
++      consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);
++      consistent_sync(p2, bytes, DMA_TO_DEVICE);
++
++
++      tp.tx_desc = tp.tx_first_desc;
++      tp.rx_desc = tp.rx_first_desc;
++      if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
++              // prepare tx descript
++              raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff);
++              tp.tx_desc->buf_addr = (unsigned int)__pa(p1);          // physical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++//            tp.tx_desc->flg_status.bits_cmd_status.bcc = 2;                 // first descript
++//            tp.tx_desc->flg_status.bits_cmd_status.mode = 0;                // only support XOR command
++              tp.tx_desc->flg_status.bits32 = 0x00020000;
++      tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
++              wmb();
++      tp.tx_desc = tp.tx_cur_desc;
++      tp.tx_desc->buf_addr = (unsigned int)__pa(p2);          // pysical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++//            tp.tx_desc->flg_status.bits_cmd_status.bcc = 1;                 // last descript
++//            tp.tx_desc->flg_status.bits_cmd_status.mode = 0;                // only support XOR command
++              tp.tx_desc->flg_status.bits32 = 0x00010000;
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
++      tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);                                                  // keep last descript
++
++      wmb();
++      // prepare rx descript
++      raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFf);
++      tp.rx_desc->buf_addr = (unsigned int)__pa(p1);
++      tp.rx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++      tp.rx_desc->flg_status.bits32 = 0;                              // link data from XOR
++//            tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.rx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
++
++      }
++      else{
++              /* no free tx descriptor */
++              printk("XOR:no free tx descript");
++              return ;
++      }
++
++      // change status
++//    tp.status = RUNNING;
++      status = tp.busy = 1;
++
++      // start tx DMA
++      rxdma_ctrl.bits.rd_start = 1;
++      // start rx DMA
++      txdma_ctrl.bits.td_start = 1;
++
++      raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
++      raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);
++
++#ifdef SPIN_WAIT
++      gemini_xor_isr(2);
++#else
++      xor_queue_descriptor();
++#endif
++
++      tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*2) ;
++      tp.status = COMPLETE;
++//    tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ;
++//    tp.rx_desc = tp.rx_first_desc ;
++//    tp.rx_desc->func_ctrl.bits.own = DMA;
++
++}
++
++void
++xor_gemini_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++              unsigned long *p3)
++{
++      int status=0;
++      unsigned int flags;
++
++      if(bytes > (1<<(SRAM_PAR_SIZE+11))){
++              printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
++      }
++
++      spin_lock_irqsave(&raid_lock,flags);
++      if(tp.status != COMPLETE){
++              spin_unlock_irqrestore(&raid_lock, flags);
++              //printk("XOR yield3\n");
++#ifdef XOR_SW_FILL_IN
++              xor_arm4regs_3(bytes,p1,p2,p3);
++              return;
++#else
++              yield();
++#endif
++      }
++      spin_unlock_irqrestore(&raid_lock, flags);
++      tp.status = RUNNING;
++
++      // flush the cache to memory before H/W XOR touches them
++      consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);
++      consistent_sync(p2, bytes, DMA_TO_DEVICE);
++      consistent_sync(p3, bytes, DMA_TO_DEVICE);
++
++      tp.tx_desc = tp.tx_first_desc;
++      tp.rx_desc = tp.rx_first_desc;
++      if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
++              // prepare tx descript
++              raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff);
++              tp.tx_desc->buf_addr = (unsigned int)__pa(p1);          // physical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++//            tp.tx_desc->flg_status.bits_cmd_status.bcc = 2;                 // first descript
++//            tp.tx_desc->flg_status.bits_cmd_status.mode = 0;                // only support XOR command
++              tp.tx_desc->flg_status.bits32 = 0x00020000;
++      tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
++
++      tp.tx_desc = tp.tx_cur_desc;
++      tp.tx_desc->buf_addr = (unsigned int)__pa(p2);          // pysical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++//            tp.tx_desc->flg_status.bits_cmd_status.bcc = 0;                 // first descript
++//            tp.tx_desc->flg_status.bits_cmd_status.mode = 0;                // only support XOR command
++              tp.tx_desc->flg_status.bits32 = 0x0000000;
++      tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
++
++      tp.tx_desc = tp.tx_cur_desc;
++      tp.tx_desc->buf_addr = (unsigned int)__pa(p3);          // pysical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++//            tp.tx_desc->flg_status.bits_cmd_status.bcc = 1;                 // last descript
++//            tp.tx_desc->flg_status.bits_cmd_status.mode = 0;                // only support XOR command
++              tp.tx_desc->flg_status.bits32 = 0x00010000;
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
++      tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);                                                  // keep last descript
++
++      // prepare rx descript
++      raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFf);
++      tp.rx_desc->buf_addr = (unsigned int)__pa(p1);
++      tp.rx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++      tp.rx_desc->flg_status.bits32 = 0;                              // link data from XOR
++//            tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.rx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
++
++      }
++      else{
++              /* no free tx descriptor */
++              printk("XOR:no free tx descript \n");
++              return ;
++      }
++
++      // change status
++//    tp.status = RUNNING;
++      status = tp.busy = 1;
++
++      // start tx DMA
++      rxdma_ctrl.bits.rd_start = 1;
++      // start rx DMA
++      txdma_ctrl.bits.td_start = 1;
++      wmb();
++      raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
++      raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);
++
++#ifdef SPIN_WAIT
++      gemini_xor_isr(3);
++#else
++      xor_queue_descriptor();
++#endif
++      tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*3) | 0x0B;
++      tp.status = COMPLETE;
++//    tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) | 0x0B;
++      //tp.rx_desc = tp.rx_first_desc ;
++//    tp.rx_desc->func_ctrl.bits.own = DMA;
++
++}
++
++void
++xor_gemini_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++              unsigned long *p3, unsigned long *p4)
++{
++      int status=0;
++      unsigned int flags;
++
++      if(bytes > (1<<(SRAM_PAR_SIZE+11))){
++              printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
++      }
++
++      spin_lock_irqsave(&raid_lock,flags);
++      if(tp.status != COMPLETE){
++              spin_unlock_irqrestore(&raid_lock, flags);
++              //printk("S\n");
++#ifdef XOR_SW_FILL_IN
++              xor_arm4regs_4(bytes,p1,p2,p3,p4);
++              return;
++#else
++              msleep(1);
++              yield();
++#endif
++      }
++      spin_unlock_irqrestore(&raid_lock, flags);
++
++      tp.status = RUNNING;
++
++      // flush the cache to memory before H/W XOR touches them
++      consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);
++      consistent_sync(p2, bytes, DMA_TO_DEVICE);
++      consistent_sync(p3, bytes, DMA_TO_DEVICE);
++      consistent_sync(p4, bytes, DMA_TO_DEVICE);
++
++      tp.tx_desc = tp.tx_first_desc;
++      tp.rx_desc = tp.rx_first_desc;
++      if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
++              // prepare tx descript
++              raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff);
++              tp.tx_desc->buf_addr = (unsigned int)__pa(p1);          // physical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++//            tp.tx_desc->flg_status.bits_cmd_status.bcc = 2;                 // first descript
++//            tp.tx_desc->flg_status.bits_cmd_status.mode = 0;                // only support XOR command
++              tp.tx_desc->flg_status.bits32 = 0x00020000;
++      tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
++
++      tp.tx_desc = tp.tx_cur_desc;
++      tp.tx_cur_desc->buf_addr = (unsigned int)__pa(p2);              // pysical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++//            tp.tx_desc->flg_status.bits_cmd_status.bcc = 0;                 // first descript
++//            tp.tx_desc->flg_status.bits_cmd_status.mode = 0;                // only support XOR command
++              tp.tx_desc->flg_status.bits32 = 0x00000000;
++      tp.tx_cur_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
++
++      tp.tx_desc = tp.tx_cur_desc;
++      tp.tx_desc->buf_addr = (unsigned int)__pa(p3);          // pysical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++//            tp.tx_desc->flg_status.bits_cmd_status.bcc = 0;                 // first descript
++//            tp.tx_desc->flg_status.bits_cmd_status.mode = 0;                // only support XOR command
++              tp.tx_desc->flg_status.bits32 = 0x00000000;
++      tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
++
++
++      tp.tx_desc = tp.tx_cur_desc;
++      tp.tx_desc->buf_addr = (unsigned int)__pa(p4);          // pysical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++//            tp.tx_desc->flg_status.bits_cmd_status.bcc = 1;                 // last descript
++//            tp.tx_desc->flg_status.bits_cmd_status.mode = 0;                // only support XOR command
++              tp.tx_desc->flg_status.bits32 = 0x00010000;
++//            tp.tx_cur_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
++      tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);                                                  // keep last descript
++
++      // prepare rx descript
++      raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFF);
++      tp.rx_desc->buf_addr = (unsigned int)__pa(p1);
++      tp.rx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++      tp.rx_desc->flg_status.bits32 = 0;                              // link data from XOR
++//            tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.rx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
++
++      }
++      else{
++              /* no free tx descriptor */
++              printk("XOR:no free tx descript");
++              return ;
++      }
++
++      // change status
++//    tp.status = RUNNING;
++      status = tp.busy = 1;
++
++      // start tx DMA
++      rxdma_ctrl.bits.rd_start = 1;
++      // start rx DMA
++      txdma_ctrl.bits.td_start = 1;
++      wmb();
++      raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
++      raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);
++
++#ifdef SPIN_WAIT
++      gemini_xor_isr(4);
++#else
++      xor_queue_descriptor();
++#endif
++
++      tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*4) | 0x0B;
++      tp.status = COMPLETE;
++//    tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) | 0x0B;
++      //tp.rx_desc = tp.rx_first_desc ;
++//    tp.rx_desc->func_ctrl.bits.own = DMA;
++
++}
++
++void
++xor_gemini_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++              unsigned long *p3, unsigned long *p4, unsigned long *p5)
++{
++
++      int status=0;
++      unsigned int flags;
++
++
++      if(bytes > (1<<(SRAM_PAR_SIZE+11))){
++              printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
++      }
++
++      spin_lock_irqsave(&raid_lock,flags);
++      while(tp.status != COMPLETE){
++              spin_unlock_irqrestore(&raid_lock, flags);
++              //printk("XOR yield5\n");
++#ifdef XOR_SW_FILL_IN
++              xor_arm4regs_5(bytes,p1,p2,p3,p4,p5);
++              return;
++#else
++              msleep(1);
++              yield();
++#endif
++      }
++      spin_unlock_irqrestore(&raid_lock, flags);
++      tp.status = RUNNING;
++
++      // flush the cache to memory before H/W XOR touches them
++      consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);
++      consistent_sync(p2, bytes, DMA_TO_DEVICE);
++      consistent_sync(p3, bytes, DMA_TO_DEVICE);
++      consistent_sync(p4, bytes, DMA_TO_DEVICE);
++      consistent_sync(p5, bytes, DMA_TO_DEVICE);
++
++      tp.tx_desc = tp.tx_first_desc;
++      tp.rx_desc = tp.rx_first_desc;
++      if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
++              // prepare tx descript
++              raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff);
++              tp.tx_desc->buf_addr = (unsigned int)__pa(p1);          // physical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++//            tp.tx_desc->flg_status.bits_cmd_status.bcc = 2;                 // first descript
++//            tp.tx_desc->flg_status.bits_cmd_status.mode = 0;                // only support XOR command
++              tp.tx_desc->flg_status.bits32 = 0x00020000;
++      tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      wmb();
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
++
++      tp.tx_desc = tp.tx_cur_desc;
++      tp.tx_desc->buf_addr = (unsigned int)__pa(p2);          // pysical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++//            tp.tx_desc->flg_status.bits_cmd_status.bcc = 0;                 // first descript
++//            tp.tx_desc->flg_status.bits_cmd_status.mode = 0;                // only support XOR command
++              tp.tx_desc->flg_status.bits32 = 0x00000000;
++      tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      wmb();
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
++
++      tp.tx_desc = tp.tx_cur_desc;
++      tp.tx_desc->buf_addr = (unsigned int)__pa(p3);          // pysical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++//            tp.tx_desc->flg_status.bits_cmd_status.bcc = 0;                 // first descript
++//            tp.tx_desc->flg_status.bits_cmd_status.mode = 0;                // only support XOR command
++              tp.tx_desc->flg_status.bits32 = 0x00000000;
++      tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      wmb();
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
++
++              tp.tx_desc = tp.tx_cur_desc;
++      tp.tx_desc->buf_addr = (unsigned int)__pa(p4);          // pysical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++//            tp.tx_desc->flg_status.bits_cmd_status.bcc = 0;                 // first descript
++//            tp.tx_desc->flg_status.bits_cmd_status.mode = 0;                // only support XOR command
++              tp.tx_desc->flg_status.bits32 = 0x00000000;
++      tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      wmb();
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
++
++
++      tp.tx_desc = tp.tx_cur_desc;
++      tp.tx_desc->buf_addr = (unsigned int)__pa(p5);          // pysical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++//            tp.tx_desc->flg_status.bits_cmd_status.bcc = 1;                 // last descript
++//            tp.tx_desc->flg_status.bits_cmd_status.mode = 0;                // only support XOR command
++//            tp.tx_cur_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++              tp.tx_desc->flg_status.bits32 = 0x00010000;
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
++      tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
++      tp.tx_finished_desc = tp.tx_desc;                                                               // keep last descript
++
++      // prepare rx descript
++      raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFF);
++      tp.rx_desc->buf_addr = (unsigned int)__pa(p1);
++      tp.rx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++      tp.rx_desc->flg_status.bits32 = 0;                              // link data from XOR
++//            tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.rx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
++
++      }
++      else{
++              /* no free tx descriptor */
++              printk("XOR:no free tx descript");
++              return ;
++      }
++
++      // change status
++//    tp.status = RUNNING;
++      status = tp.busy = 1;
++
++      // start tx DMA
++      rxdma_ctrl.bits.rd_start = 1;
++      // start rx DMA
++      txdma_ctrl.bits.td_start = 1;
++      wmb();
++      raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
++      raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);
++
++#ifdef SPIN_WAIT
++      gemini_xor_isr(5);
++#else
++      xor_queue_descriptor();
++#endif
++
++      tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*5) | 0x0B;
++      tp.status = COMPLETE;
++//    tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) | 0x0B;
++      //tp.rx_desc = tp.rx_first_desc ;
++//    tp.rx_desc->func_ctrl.bits.own = DMA;
++
++}
++
++#ifdef XOR_TEST
++void
++raid_memset(unsigned int *p1, unsigned int pattern, unsigned int bytes)
++{
++      int status=0,i;
++
++      if(bytes > (1<<(SRAM_PAR_SIZE+11))){
++              printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
++      }
++
++      *p1 = pattern;
++
++      // flush the cache to memory before H/W XOR touches them
++      consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);
++
++      while(tp.status != COMPLETE){
++              DPRINTK("XOR yield\n");
++              //schedule();
++              yield();
++      }
++      tp.status = RUNNING;
++
++      tp.tx_desc = tp.tx_first_desc;
++      tp.rx_desc = tp.rx_first_desc;
++      if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
++              // prepare tx descript
++              raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xFFFFFFFF);
++              tp.tx_desc->buf_addr = (unsigned int)__pa(p1);          // physical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = 4;             /* total frame byte count */
++      tp.tx_desc->flg_status.bits_cmd_status.bcc = bytes;                     // bytes to fill
++      tp.tx_desc->flg_status.bits_cmd_status.mode = CMD_FILL;         // only support memory FILL command
++      tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;
++//            tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xFFFFFFF0)+tx_desc_virtual_base);
++
++      // prepare rx descript
++      raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFF);
++      tp.rx_desc->buf_addr = (unsigned int)__pa(p1);
++      tp.rx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++      tp.rx_desc->flg_status.bits32 = 0;                              // link data from XOR
++      tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.rx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++//            tp.rx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.rx_cur_desc->next_desc_addr.bits32 & 0xfffffff0)+rx_desc_virtual_base);
++      tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
++      tp.rx_finished_desc = tp.rx_desc;
++
++      }
++      else{
++              /* no free tx descriptor */
++              printk("XOR:no free tx descript");
++              return ;
++      }
++
++      // change status
++      //tp.status = RUNNING;
++      status = tp.busy = 1;
++
++      // start tx DMA
++      rxdma_ctrl.bits.rd_start = 1;
++      // start rx DMA
++      txdma_ctrl.bits.td_start = 1;
++
++      raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
++      raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);
++
++#ifdef SPIN_WAIT
++      gemini_xor_isr(2);
++#else
++      xor_queue_descriptor();
++#endif
++
++      for(i=1; i<(bytes/sizeof(int)); i++) {
++              if(p1[0]!=p1[i]){
++                      printk("pattern set error!\n");
++                      while(1);
++              }
++      }
++
++      tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ;
++      tp.status = COMPLETE;
++//    tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ;
++      //tp.rx_desc = tp.rx_first_desc ;
++//    tp.rx_desc->func_ctrl.bits.own = DMA;
++
++}
++#endif
++
++void
++raid_memcpy(unsigned int *to, unsigned int *from, unsigned int bytes)
++{
++      int status=0,i;
++
++      if(bytes > (1<<(SRAM_PAR_SIZE+11))){
++              printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
++      }
++
++      // flush the cache to memory before H/W XOR touches them
++      consistent_sync(to, bytes, DMA_BIDIRECTIONAL);
++      consistent_sync(from,bytes, DMA_TO_DEVICE);
++
++      while(tp.status != COMPLETE){
++              DPRINTK("XOR yield\n");
++              //schedule();
++              yield();
++      }
++      tp.status = RUNNING;
++
++      tp.tx_desc = tp.tx_first_desc;
++      tp.rx_desc = tp.rx_first_desc;
++      if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
++              // prepare tx descript
++              raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xFFFFFFFF);
++              tp.tx_desc->buf_addr = (unsigned int)__pa(from);                // physical address
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++      tp.tx_desc->flg_status.bits32 = CMD_CPY;                // only support memory FILL command
++      tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;
++//            tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xFFFFFFF0)+tx_desc_virtual_base);
++
++      // prepare rx descript
++      raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFF);
++      tp.rx_desc->buf_addr = (unsigned int)__pa(to);
++      tp.rx_desc->func_ctrl.bits.buffer_size = bytes;                 /* total frame byte count */
++      tp.rx_desc->flg_status.bits32 = 0;                              // link data from XOR
++      tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.rx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++//            tp.rx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.rx_cur_desc->next_desc_addr.bits32 & 0xfffffff0)+rx_desc_virtual_base);
++      tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
++
++      }
++      else{
++              /* no free tx descriptor */
++              printk("XOR:no free tx descript");
++              return ;
++      }
++
++      // change status
++      //tp.status = RUNNING;
++      status = tp.busy = 1;
++
++      // start tx DMA
++      rxdma_ctrl.bits.rd_start = 1;
++      // start rx DMA
++      txdma_ctrl.bits.td_start = 1;
++
++      raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
++      raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);
++
++#ifdef SPIN_WAIT
++      gemini_xor_isr(2);
++#else
++      xor_queue_descriptor();
++#endif
++
++#ifdef XOR_TEST
++      for(i=1; i<(bytes/sizeof(int)); i++) {
++              if(to[i]!=from[i]){
++                      printk("pattern check error!\n");
++                      printk("offset=0x%x p1=%x p2=%x\n",i*4,to[i],from[i]);
++                      while(1);
++              }
++      }
++#endif
++
++      tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ;
++      tp.status = COMPLETE;
++//    tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ;
++      //tp.rx_desc = tp.rx_first_desc ;
++//    tp.rx_desc->func_ctrl.bits.own = DMA;
++
++}
++EXPORT_SYMBOL(raid_memcpy);
++
++#ifdef XOR_TEST
++int
++raid_memchk(unsigned int *p1, unsigned int pattern, unsigned int bytes)
++{
++      int status=0;
++      RAID_DMA_STATUS_T       dma_status;
++
++      if(bytes > (1<<(SRAM_PAR_SIZE+11))){
++              printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
++      }
++
++      status = ((pattern&0xFFFF)%bytes )/4;
++      p1[status] = pattern;
++
++      while(tp.status != COMPLETE){
++              DPRINTK("XOR yield\n");
++              //schedule();
++              yield();
++      }
++      tp.status = RUNNING;
++
++      // flush the cache to memory before H/W XOR touches them
++      consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);
++
++      tp.tx_desc = tp.tx_first_desc;
++      if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
++              // prepare tx descript
++              raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xFFFFFFFF);
++              tp.tx_desc->buf_addr = (unsigned int)__pa(p1);          // physical address
++      tp.tx_desc->func_ctrl.bits.raid_ctrl_status = 0;
++      tp.tx_desc->func_ctrl.bits.buffer_size = bytes ;                /* total frame byte count */
++      tp.tx_desc->flg_status.bits32 = CMD_CHK;                // only support memory FILL command
++      tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03;          /*only one descriptor*/
++      tp.tx_desc->func_ctrl.bits.own = DMA;                           /* set owner bit */
++      tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;
++//            tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xFFFFFFF0)+tx_desc_virtual_base);
++
++      }
++      else{
++              /* no free tx descriptor */
++              printk("XOR:no free tx descript");
++              return -1;
++      }
++
++      // change status
++      //tp.status = RUNNING;
++      status = tp.busy = 1;
++
++      // start tx DMA
++      txdma_ctrl.bits.td_start = 1;
++
++      raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
++//    raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);
++
++#ifdef SPIN_WAIT
++      gemini_xor_isr(2);
++#else
++      xor_queue_descriptor();
++#endif
++
++//    dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS);
++//    if (dma_status.bits32 & (1<<15))        {
++
++      if((tp.tx_first_desc->func_ctrl.bits.raid_ctrl_status & 0x2)) {
++              status = 1;
++//            raid_write_reg(RAID_DMA_STATUS,0x00008000,0x00080000);
++      }
++      else{
++              status = 0;
++      }
++
++      tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ;
++      tp.status = COMPLETE;
++//    tp.rx_desc->func_ctrl.bits.own = DMA;
++      return status ;
++}
++#endif
++
++int __init gemini_xor_init(void)
++{
++      unsigned int res;
++      unsigned int *paddr1,*paddr2,*paddr3,i;
++      unsigned volatile char  *charact;
++      unsigned volatile short *two_char;
++      unsigned volatile int   *four_char;
++
++      // init descript
++      res = gemini_xor_init_desc();
++      if(res) {
++              printk("Init RAID Descript Fail!!\n");
++              return -res;
++      }
++
++      tp.device_name = "Gemini XOR Acceleration";
++
++      // request irq
++#ifndef SPIN_WAIT
++      res = request_irq(IRQ_RAID, gemini_xor_isr, SA_INTERRUPT, tp.device_name, NULL);
++#endif
++      if(res){
++              printk(KERN_ERR "%s: unable to request IRQ %d for "
++                     "HW XOR %d\n", tp.device_name, IRQ_RAID, res);
++              return -EBUSY;
++      }
++
++#ifdef XOR_TEST
++
++RETEST:
++      paddr1 = kmalloc(0x1000,GFP_KERNEL);
++      paddr2 = kmalloc(0x1000,GFP_KERNEL);
++      paddr3 = kmalloc(0x1000,GFP_KERNEL);
++      for(i=0;i<TEST_ITERATION;i++) {
++              printk("XOR test round %d\n",i);
++              for(res=0;res<(0x1000)/sizeof(int);res++){              // prepare data pattern
++                      paddr1[res]= readl(0xf62000ac);
++                      paddr2[res]= readl(0xf62000ac);
++              }
++              for(res=0;res<0x1000/sizeof(int);res++){                // calculate xor by software
++                      paddr3[res] = paddr1[res]^paddr2[res];
++              }
++              xor_gemini_2(0x1000,paddr1,paddr2);                             // calculate xor by hw
++              for(res=0;res<0x1000/sizeof(int);res++){                // check error
++                      if(paddr1[res]!=paddr3[res]){
++                              printk("XOR ERROR\n");
++                              printk("[%d][0x%x]=0x%x should be %x\n",res,&paddr1[res],paddr1[res],paddr3[res]);
++                              while(1);
++                      }
++              }
++      }
++      kfree(paddr1);
++      kfree(paddr2);
++      kfree(paddr3);
++
++
++      // memcpy test
++      paddr1 = kmalloc(0x4000,GFP_KERNEL);
++      for(i=0;i<TEST_ITERATION;i++) {
++              for(res=0;res<(0x4000)/sizeof(int);res++)
++                      paddr1[res]= readl(0xf62000ac);
++
++              printk("MEMCOPY round %d\n",i);
++              paddr2 = kmalloc(0x4000,GFP_KERNEL);
++              raid_memcpy(paddr2,paddr1,0x4000);
++              kfree(paddr2);
++      }
++      kfree(paddr1);
++
++      // memset test
++      for(i=0;i<TEST_ITERATION;i++) {
++              raid_memset(paddr1,0xFFFFFFFF,0x4000);
++              res = readl(0xf62000ac);
++              printk("MEMFILL fill 0x%x round %d\n",res,i);
++              paddr1 = kmalloc(0x4000,GFP_KERNEL);
++              raid_memset(paddr1,res,0x4000);
++              raid_memset(paddr1,0x0,0x4000);
++              kfree(paddr1);
++      }
++
++      paddr1 = kmalloc(0x4000,GFP_KERNEL);
++      for(i=0;i<TEST_ITERATION;i++){
++              raid_memset(paddr1, i,0x4000);
++              printk("Pattern check same ? ");
++              res = raid_memchk(paddr1, i,0x4000);
++              printk("%s\n",res?"Fail":"OK");
++              if(res) while(1);
++
++              printk("Pattern check diff ? ");
++              res = raid_memchk(paddr1,readl(0xf62000ac),0x4000);
++              printk("%s\n",res?"OK":"Fail");
++              if(!res)        while(1);
++      }
++      kfree(paddr1);
++
++      // SRAM test
++      raid_write_reg(RAID_PCR, 0,0x00000003);
++      for(i=0;i<TEST_ITERATION;i++) {
++              printk("SRAM test %d\n",i);
++              charact = 0xF7000000;
++              two_char = 0xF7000000;
++              four_char = 0xF7000000;
++              for(res=0;res<(16*1024)/sizeof(char);res++) {           // 8-bit access
++                      *charact++ = (unsigned char)res;
++              }
++              charact = 0xF7000000;
++              for(res=0;res<(16*1024)/sizeof(char);res++) {
++                      if(*charact++ != (unsigned char)res){
++                              printk("SRAM data error(8)\n");
++                              while(1);
++                      }
++              }
++
++              for(res=0;res<(16*1024)/sizeof(short);res++) {          // 16-bit access
++                      *two_char++ = (unsigned short)res;
++              }
++              two_char = 0xF7000000;
++              for(res=0;res<(16*1024)/sizeof(short);res++) {
++                      if(*two_char++ != (unsigned short)res){
++                              printk("SRAM data error(16)\n");
++                              while(1);
++                      }
++              }
++
++              for(res=0;res<(16*1024)/sizeof(int);res++) {            // 32-bit access
++                      *four_char++ = (unsigned int)res;
++              }
++              four_char = 0xF7000000;
++              for(res=0;res<(16*1024)/sizeof(int);res++) {
++                      if(*four_char++ != (unsigned int)res){
++                              printk("SRAM data error(32)\n");
++                              while(1);
++                      }
++              }
++      }
++      raid_write_reg(RAID_PCR, SRAM_PAR_SIZE,0x00000003);
++
++#endif
++      return 0;
++}
++
++void __exit gemini_xor_exit(void)
++{
++      DMA_MFREE(tp.tx_desc, TX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T),(unsigned int)tp.tx_desc_dma);
++      DMA_MFREE(tp.rx_desc, RX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T),(unsigned int)tp.rx_desc_dma);
++      free_irq(IRQ_RAID, NULL);
++}
++
++
++static int gemini_xor_init_desc(void)
++{
++      unsigned int i;
++      dma_addr_t          tx_first_desc_dma;
++      dma_addr_t          rx_first_desc_dma;
++      RAID_DMA_STATUS_T       dma_status;
++
++      printk("Initial RAID Descripter...\n");
++
++      tp.tx_desc = (RAID_DESCRIPTOR_T*)DMA_MALLOC(TX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T),(dma_addr_t *)&tp.tx_desc_dma);
++    tx_desc_virtual_base = (unsigned int)tp.tx_desc - (unsigned int)tp.tx_desc_dma;
++    memset(tp.tx_desc,0x00,TX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T));
++
++      tp.rx_desc = (RAID_DESCRIPTOR_T*)DMA_MALLOC(RX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T),(dma_addr_t *)&tp.rx_desc_dma);
++    rx_desc_virtual_base = (unsigned int)tp.rx_desc - (unsigned int)tp.rx_desc_dma;
++    memset(tp.rx_desc,0x00,RX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T));
++      printk("XOR:tx_desc = %08x\n",(unsigned int)tp.tx_desc);
++    printk("XOR:rx_desc = %08x\n",(unsigned int)tp.rx_desc);
++      printk("XOR:tx_desc_dma = %08x\n",(unsigned int)tp.tx_desc_dma);
++      printk("XOR:rx_desc_dma = %08x\n",(unsigned int)tp.rx_desc_dma);
++
++      if ((tp.tx_desc == NULL) || (tp.rx_desc == NULL)) {
++              if (tp.tx_desc)
++                      DMA_MFREE(tp.tx_desc, TX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T),(dma_addr_t)tp.tx_desc_dma);
++              if (tp.rx_desc)
++                      DMA_MFREE(tp.rx_desc, RX_DESC_NUM*sizeof(RAID_DESCRIPTOR_T),(dma_addr_t)tp.rx_desc_dma);
++              return -ENOMEM;
++      }
++
++      tp.tx_cur_desc = tp.tx_desc;  /* virtual address */
++      tp.tx_finished_desc = tp.tx_desc; /* virtual address */
++      tx_first_desc_dma = (dma_addr_t)tp.tx_desc_dma; /* physical address */
++      for (i = 1; i < TX_DESC_NUM; i++) {
++              tp.tx_desc->func_ctrl.bits.own = CPU;
++              tp.tx_desc->func_ctrl.bits.buffer_size = 0;
++              tp.tx_desc_dma = tp.tx_desc_dma + sizeof(RAID_DESCRIPTOR_T);
++//            tp.tx_desc->next_desc_addr.bits32 = (unsigned int)tp.tx_desc_dma | 0x0B;
++              tp.tx_desc->next_desc_addr.bits32 = ((unsigned int)tx_first_desc_dma | 0x0B) + i*0x10;
++              tp.tx_desc = &tp.tx_desc[1];
++      }
++      tp.tx_desc->func_ctrl.bits.own = DMA;
++      tp.tx_desc->next_desc_addr.bits32 = (unsigned int)tx_first_desc_dma|0x0b;
++      tp.tx_desc = tp.tx_cur_desc;
++      tp.tx_desc_dma = (unsigned int*)tx_first_desc_dma;
++      tp.tx_first_desc = tp.tx_desc ;
++
++      tp.rx_cur_desc = tp.rx_desc;  /* virtual address */
++      tp.rx_finished_desc = tp.rx_desc; /* virtual address */
++      rx_first_desc_dma = (dma_addr_t)tp.rx_desc_dma; /* physical address */
++      for (i = 1; i < RX_DESC_NUM; i++) {
++              tp.rx_desc->func_ctrl.bits.own = DMA;
++              tp.rx_desc->func_ctrl.bits.buffer_size = 0;
++              tp.rx_desc_dma = tp.rx_desc_dma + sizeof(RAID_DESCRIPTOR_T);
++//            tp.rx_desc->next_desc_addr.bits32 = (unsigned int)tp.rx_desc_dma | 0x0B;
++              tp.rx_desc->next_desc_addr.bits32 = ((unsigned int)rx_first_desc_dma | 0x0B) + i*0x10;
++              tp.rx_desc = &tp.rx_desc[1];
++      }
++      tp.rx_desc->func_ctrl.bits.own = DMA;
++      tp.rx_desc->next_desc_addr.bits32 = rx_first_desc_dma|0x0b;
++      tp.rx_desc = tp.rx_cur_desc;
++      tp.rx_desc_dma = (unsigned int*)rx_first_desc_dma;
++      tp.rx_first_desc = tp.rx_desc ;
++      tp.busy = 0;
++      tp.status = COMPLETE;
++
++      // Partition SRAM size
++      raid_write_reg(RAID_PCR, SRAM_PAR_SIZE,0x00000003);
++
++      // config tx DMA controler
++      txdma_ctrl.bits32 = 0;
++      txdma_ctrl.bits.td_start = 0;
++      txdma_ctrl.bits.td_continue = 1;
++      txdma_ctrl.bits.td_chain_mode = 1;
++      txdma_ctrl.bits.td_prot = 0;
++      txdma_ctrl.bits.td_burst_size = 1;
++      txdma_ctrl.bits.td_bus = 3;
++      txdma_ctrl.bits.td_endian = 0;
++      txdma_ctrl.bits.td_finish_en = 1;
++      txdma_ctrl.bits.td_fail_en = 1;
++      txdma_ctrl.bits.td_perr_en = 1;
++      txdma_ctrl.bits.td_eod_en = 0;  // enable tx descript
++      txdma_ctrl.bits.td_eof_en = 0;
++      raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0xFFFFFFFF);
++
++      // config rx DMA controler
++      rxdma_ctrl.bits32 = 0;
++      rxdma_ctrl.bits.rd_start = 0;
++      rxdma_ctrl.bits.rd_continue = 1;
++      rxdma_ctrl.bits.rd_chain_mode = 1;
++      rxdma_ctrl.bits.rd_prot = 0;
++      rxdma_ctrl.bits.rd_burst_size = 1;
++      rxdma_ctrl.bits.rd_bus = 3;
++      rxdma_ctrl.bits.rd_endian = 0;
++      rxdma_ctrl.bits.rd_finish_en = 0;
++      rxdma_ctrl.bits.rd_fail_en = 1;
++      rxdma_ctrl.bits.rd_perr_en = 1;
++      rxdma_ctrl.bits.rd_eod_en = 0;
++      rxdma_ctrl.bits.rd_eof_en = 0;
++      raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0xFFFFFFFF);
++
++      // enable interrupt
++      dma_status.bits32 = 3;  // enable RpInt
++      raid_write_reg(RAID_DMA_STATUS, dma_status.bits32,0xFFFFFFFF);
++
++      return 0;
++}
++
++module_init(gemini_xor_init);
++module_exit(gemini_xor_exit);
++
+--- a/arch/arm/mm/Kconfig
++++ b/arch/arm/mm/Kconfig
+@@ -187,6 +187,26 @@
+         Say Y if you want support for the ARM926T processor.
+         Otherwise, say N.
++###### for Storlink SoC ######
++config CPU_FA526
++      bool "FA526 processor"
++      depends on ARCH_SL2312
++      default y
++      select CPU_32v4
++      select CPU_ABRT_EV4
++      select CPU_CACHE_FA
++      select CPU_CACHE_VIVT
++      select CPU_CP15_MMU
++      select CPU_COPY_FA
++      select CPU_TLB_FA
++      select CPU_FA_BTB
++      help
++        The FA526 is a version of the ARM9 compatible processor, but with smaller
++        instruction and data caches. It is used in Storlink Sword device family.
++
++        Say Y if you want support for the FA526 processor.
++        Otherwise, say N.
++
+ # ARM940T
+ config CPU_ARM940T
+       bool "Support ARM940T processor" if ARCH_INTEGRATOR
+@@ -461,6 +481,9 @@
+ config CPU_CACHE_VIPT
+       bool
++config CPU_CACHE_FA
++      bool
++
+ if MMU
+ # The copy-page model
+ config CPU_COPY_V3
+@@ -475,6 +498,12 @@
+ config CPU_COPY_V6
+       bool
++config CPU_COPY_FA
++      bool
++
++config CPU_FA_BTB
++      bool
++
+ # This selects the TLB model
+ config CPU_TLB_V3
+       bool
+@@ -534,6 +563,14 @@
+ config IO_36
+       bool
++config CPU_TLB_FA
++      bool
++      help
++        //TODO
++        Faraday ARM FA526 architecture, unified TLB with writeback cache
++        and invalidate instruction cache entry. Branch target buffer is also
++        supported.
++
+ comment "Processor Features"
+ config ARM_THUMB
+@@ -600,7 +637,7 @@
+ config CPU_DCACHE_WRITETHROUGH
+       bool "Force write through D-cache"
+-      depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020) && !CPU_DCACHE_DISABLE
++      depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_FA526) && !CPU_DCACHE_DISABLE
+       default y if CPU_ARM925T
+       help
+         Say Y here to use the data cache in writethrough mode. Unless you
+--- a/arch/arm/mm/Makefile
++++ b/arch/arm/mm/Makefile
+@@ -32,6 +32,7 @@
+ obj-$(CONFIG_CPU_CACHE_V4WB)  += cache-v4wb.o
+ obj-$(CONFIG_CPU_CACHE_V6)    += cache-v6.o
+ obj-$(CONFIG_CPU_CACHE_V7)    += cache-v7.o
++obj-$(CONFIG_CPU_CACHE_FA)    += cache-fa.o
+ obj-$(CONFIG_CPU_COPY_V3)     += copypage-v3.o
+ obj-$(CONFIG_CPU_COPY_V4WT)   += copypage-v4wt.o
+@@ -40,6 +41,7 @@
+ obj-$(CONFIG_CPU_SA1100)      += copypage-v4mc.o
+ obj-$(CONFIG_CPU_XSCALE)      += copypage-xscale.o
+ obj-$(CONFIG_CPU_XSC3)                += copypage-xsc3.o
++obj-$(CONFIG_CPU_COPY_FA)     += copypage-fa.o
+ obj-$(CONFIG_CPU_TLB_V3)      += tlb-v3.o
+ obj-$(CONFIG_CPU_TLB_V4WT)    += tlb-v4.o
+@@ -47,6 +49,7 @@
+ obj-$(CONFIG_CPU_TLB_V4WBI)   += tlb-v4wbi.o
+ obj-$(CONFIG_CPU_TLB_V6)      += tlb-v6.o
+ obj-$(CONFIG_CPU_TLB_V7)      += tlb-v7.o
++obj-$(CONFIG_CPU_TLB_FA)      += tlb-fa.o
+ obj-$(CONFIG_CPU_ARM610)      += proc-arm6_7.o
+ obj-$(CONFIG_CPU_ARM710)      += proc-arm6_7.o
+@@ -60,6 +63,7 @@
+ obj-$(CONFIG_CPU_ARM926T)     += proc-arm926.o
+ obj-$(CONFIG_CPU_ARM940T)     += proc-arm940.o
+ obj-$(CONFIG_CPU_ARM946E)     += proc-arm946.o
++obj-$(CONFIG_CPU_FA526)               += proc-fa526.o
+ obj-$(CONFIG_CPU_ARM1020)     += proc-arm1020.o
+ obj-$(CONFIG_CPU_ARM1020E)    += proc-arm1020e.o
+ obj-$(CONFIG_CPU_ARM1022)     += proc-arm1022.o
+--- /dev/null
++++ b/arch/arm/mm/cache-fa.S
+@@ -0,0 +1,400 @@
++/*
++ *  linux/arch/arm/mm/cache-fa.S
++ *
++ *  Copyright (C) 2005 Faraday Corp.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  Processors: FA520 FA526 FA626     
++ * 03/31/2005 :       Luke Lee created, modified from cache-v4wb.S
++ * 04/06/2005 :       1. Read CR0-1 and determine the cache size dynamically,
++ *               to suit all Faraday CPU series
++ *            2. Fixed all functions
++ * 04/08/2005 :       insert CONFIG_CPU_ICACHE_DISABLE and CONFIG_CPU_DCACHE_DISABLE
++ * 04/12/2005 :       TODO: make this processor dependent or a self-modifying code to 
++ *            inline cache len/size info into the instructions, as reading cache 
++ *            size and len info in memory could cause another cache miss.
++ * 05/05/2005 :       Modify fa_flush_user_cache_range to comply APCS.
++ * 05/19/2005 :       Adjust for boundary conditions.
++ */
++#include <linux/linkage.h>
++#include <linux/init.h>
++#include <asm/hardware.h>
++#include <asm/page.h>
++#include "proc-macros.S"
++
++#define CACHE_DLINESIZE          16
++#ifdef CONFIG_SL3516_ASIC
++#define CACHE_DSIZE      8192
++#else
++#define CACHE_DSIZE      16384 
++#endif 
++#define CACHE_ILINESIZE          16
++#define CACHE_ISIZE      16384
++
++/* Luke Lee 04/06/2005 ins begin */
++/*
++ *    initialize_cache_info()
++ *
++ *    Automatic detection of DSIZE, DLEN, ISIZE, ILEN variables according to 
++ *    system register CR0-1
++ *    Destroyed register: r0, r1, r2, r3, ip
++ */
++      .align
++ENTRY(fa_initialize_cache_info)
++      mov     r3, #1                          @ r3 always = 1
++      adr     ip, __fa_cache_ilen
++      
++      mrc     p15, 0, r0, c0, c0, 1
++      /* ILEN */
++      and     r1, r0, #3                      @ bits [1:0]
++      add     r1, r1, #3                      @ cache line size is at least 8 bytes (2^3)
++      mov     r2, r3, lsl r1                  @ r2 = 1<<r1
++      str     r2, [ip], #4
++      /* ISIZE */
++      mov     r1, r0, lsr #6                  @ bits [8:6]
++      and     r1, r1, #7
++      add     r1, r1, #9                      @ cache size is at least 512 bytes (2^9)
++      mov     r2, r3, lsl r1
++      str     r2, [ip], #4
++      /* DLEN */
++      mov     r1, r0, lsr #12
++      and     r1, r1, #3                      @ bits [13:12]
++      add     r1, r1, #3                      @ cache line size is at least 8 bytes (2^3)
++      mov     r2, r3, lsl r1                  @ r2 = 1<<r1
++      str     r2, [ip], #4
++      /* DSIZE */
++      mov     r1, r0, lsr #18                 @ bits [20:18]
++      and     r1, r1, #7
++      add     r1, r1, #9                      @ cache size is at least 512 bytes (2^9)
++      mov     r2, r3, lsl r1
++      str     r2, [ip]
++      mov     pc, lr
++
++      /* Warning : Do not change the order ! Successive codes depends on this */
++      .align
++      .globl __fa_cache_ilen, __fa_cache_isize, __fa_cache_dlen, __fa_cache_dsize
++__fa_cache_ilen:
++      .word   0                               @ instruction cache line length
++__fa_cache_isize:
++      .word   0                               @ instruction cache size
++__fa_cache_dlen:
++      .word   0                               @ data cahce line length        
++__fa_cache_dsize:
++      .word   0                               @ data cache size
++
++/* Luke Lee 04/06/2005 ins end */
++
++/*
++ *    flush_user_cache_all()
++ *
++ *    Clean and invalidate all cache entries in a particular address
++ *    space.
++ */
++ENTRY(fa_flush_user_cache_all)
++      /* FALLTHROUGH */
++/*
++ *    flush_kern_cache_all()
++ *
++ *    Clean and invalidate the entire cache.
++ */
++ENTRY(fa_flush_kern_cache_all)
++/* Luke Lee 04/06/2005 mod ok */
++      mov     ip, #0
++      
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcr     p15, 0, ip, c7, c5, 0           @ invalidate I cache
++#endif
++      
++__flush_whole_cache:
++      
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      mov     ip, #0
++#  ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      mcr     p15, 0, ip, c7, c6, 0           @ invalidate D cache
++#  else
++      mcr     p15, 0, ip, c7,c14, 0           @ clean/invalidate D cache
++#  endif
++#endif /*CONFIG_CPU_DCACHE_DISABLE*/
++      
++#ifndef CONFIG_CPU_FA_WB_DISABLE      
++      mcr     p15, 0, ip, c7, c10, 4          @ drain write buffer
++#endif
++      
++#ifdef CONFIG_CPU_FA_BTB
++      mcr     p15, 0, ip, c7, c5, 6           @ invalidate BTB
++      nop
++      nop
++#endif
++      
++/* Luke Lee 04/06/2005 que todo tofix : should iscratchpad and dscratchpad be invalidated ? */
++      mov     pc, lr
++
++/*
++ *    flush_user_cache_range(start, end, flags)
++ *
++ *    Invalidate a range of cache entries in the specified
++ *    address space.
++ *
++ *    - start - start address (inclusive, page aligned)
++ *    - end   - end address (exclusive, page aligned)
++ *    - flags - vma_area_struct flags describing address space
++ */
++ENTRY(fa_flush_user_cache_range)
++
++/* Luke Lee 04/06/2005 mod ok */
++      /* Luke Lee 04/07/2005 ins 1 */
++      mov     ip, #0
++      sub     r3, r1, r0                      @ calculate total size
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      tst     r2, #VM_EXEC                    @ executable region?
++      mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
++#endif
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE     
++      /* Luke Lee 04/06/2005 ins 2 mod 1 */
++      cmp     r3, #CACHE_DSIZE                @ total size >= limit?
++      bhs     __flush_whole_cache             @ flush whole D cache
++
++      //debug_Aaron
++        bic     r0, r0, #CACHE_DLINESIZE-1  
++      mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate boundary D entry
++        bic     r1, r1, #CACHE_DLINESIZE-1  
++      mcr     p15, 0, r1, c7, c14, 1          @ clean and invalidate boundary D entry
++
++
++1:    /* Luke Lee 04/06/2005 del 2 ins 5 */
++      
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
++#else
++      mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
++#endif
++      /* Luke Lee 04/06/2005 mod 1 */
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      bls     1b                              @ Luke Lee 05/19/2005
++#endif        /* CONFIG_CPU_DCACHE_DISABLE */
++      
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++      tst     r2, #VM_EXEC
++      /* Luke Lee 04/06/2005 mod 1 tofix todo : ne->eq */
++      mcreq   p15, 0, r4, c7, c10, 4          @ drain write buffer
++#endif
++
++      /* Luke Lee 04/06/2005 ins block */
++#ifdef CONFIG_CPU_FA_BTB
++        tst     r2, #VM_EXEC
++      mov     ip, #0
++      mcrne   p15, 0, ip, c7, c5, 6           @ invalidate BTB
++      nop
++      nop
++#endif
++      mov     pc, lr
++
++/*
++ *    flush_kern_dcache_page(void *page)
++ *
++ *    Ensure no D cache aliasing occurs, either with itself or
++ *    the I cache
++ *
++ *    - addr  - page aligned address
++ */
++ENTRY(fa_flush_kern_dcache_page)
++      add     r1, r0, #PAGE_SZ
++      /* fall through */
++
++/*
++ *    coherent_kern_range(start, end)
++ *
++ *    Ensure coherency between the Icache and the Dcache in the
++ *    region described by start.  If you have non-snooping
++ *    Harvard caches, you need to implement this function.
++ *
++ *    - start  - virtual start address
++ *    - end    - virtual end address
++ */
++ENTRY(fa_coherent_kern_range)
++      /* fall through */
++
++/*
++ *    coherent_user_range(start, end)
++ *
++ *    Ensure coherency between the Icache and the Dcache in the
++ *    region described by start.  If you have non-snooping
++ *    Harvard caches, you need to implement this function.
++ *
++ *    - start  - virtual start address
++ *    - end    - virtual end address
++ */
++ENTRY(fa_coherent_user_range)
++
++/* Luke Lee 04/06/2005 mod ok */
++      /* Luke Lee 04/06/2005 ins 3 mod 1 */
++      bic     r0, r0, #CACHE_DLINESIZE-1
++
++ //debug_Aaron
++        bic     r0, r0, #CACHE_DLINESIZE-1
++        mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate boundary D entry
++        bic     r1, r1, #CACHE_DLINESIZE-1
++        mcr     p15, 0, r1, c7, c14, 1          @ clean and invalidate boundary D entry
++
++#if !(defined(CONFIG_CPU_DCACHE_DISABLE) && defined(CONFIG_CPU_ICACHE_DISABLE))
++1:    /* Luke Lee 04/06/2005 del 2 ins 5 mod 1 */
++#ifndef CONFIG_CPU_DCACHE_DISABLE     
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
++#else
++      mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
++#endif
++#endif /* CONFIG_CPU_DCACHE_DISABLE */
++      
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcr     p15, 0, r0, c7, c5, 1           @ invalidate I entry
++#endif
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      bls     1b                              @ Luke Lee 05/19/2005 blo->bls  
++#endif /* !(defined(CONFIG_CPU_DCACHE_DISABLE) && defined(CONFIG_CPU_ICACHE_DISABLE)) */
++
++      mov     ip, #0
++#ifdef CONFIG_CPU_FA_BTB
++      mcr     p15, 0, ip, c7, c5, 6           @ invalidate BTB
++      nop
++      nop
++#endif
++
++/* Luke Lee 04/08/2005 ins 1 skp 1 ins 1 */
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++#endif
++
++      mov     pc, lr
++
++/*
++ *    dma_inv_range(start, end)
++ *
++ *    Invalidate (discard) the specified virtual address range.
++ *    May not write back any entries.  If 'start' or 'end'
++ *    are not cache line aligned, those lines must be written
++ *    back.
++ *
++ *    - start  - virtual start address
++ *    - end    - virtual end address
++ */
++ENTRY(fa_dma_inv_range)
++
++/* Luke Lee 04/06/2005 mod ok */
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE     
++
++ //debug_Aaron
++        bic     r0, r0, #CACHE_DLINESIZE-1
++        mcr     p15, 0, r0, c7, c6, 1          @ invalidate boundary D entry
++        bic     r1, r1, #CACHE_DLINESIZE-1
++        mcr     p15, 0, r1, c7, c6, 1          @ invalidate boundary D entry
++
++      /* Luke Lee 04/06/2005 ins 4 mod 2 */
++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
++      tst     r0, #CACHE_DLINESIZE -1
++      bic     r0, r0, #CACHE_DLINESIZE -1
++
++//debug_Aaron
++      //mcrne p15, 0, r0, c7, c10, 1          @ clean boundary D entry
++
++      /* Luke Lee 04/06/2005 mod 1 */
++      /* Luke Lee 05/19/2005 always clean the end-point boundary mcrne->mcr */
++      ////tst r1, #CACHE_DLINESIZE -1
++      //mcr   p15, 0, r1, c7, c10, 1          @ clean boundary D entry
++      /* Luke Lee 04/06/2005 ins 1 */
++#else
++      bic     r0, r0, #CACHE_DLINESIZE -1     
++#endif
++
++//debug_Aaron 
++1:    mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
++//1:  mcr     p15, 0, r0, c7, c14, 1          @ clean and invalidate D entry
++
++      /* Luke Lee 04/06/2005 mod 1 */ 
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      bls     1b                              @ Luke Lee 05/19/2005 blo->bls
++#endif /* CONFIG_CPU_DCACHE_DISABLE */
++
++      /* Luke Lee 04/06/2005 ins 1 */         
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++      mov     r0, #0
++      mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
++#endif        
++
++      mov     pc, lr
++
++/*
++ *    dma_clean_range(start, end)
++ *
++ *    Clean (write back) the specified virtual address range.
++ *
++ *    - start  - virtual start address
++ *    - end    - virtual end address
++ */
++ENTRY(fa_dma_clean_range)
++
++/* Luke Lee 04/06/2005 mod ok */
++#ifndef CONFIG_CPU_DCACHE_DISABLE     
++
++ //debug_Aaron
++        bic     r0, r0, #CACHE_DLINESIZE-1
++        mcr     p15, 0, r0, c7, c10, 1          @ clean boundary D entry
++        bic     r1, r1, #CACHE_DLINESIZE-1
++        mcr     p15, 0, r1, c7, c10, 1          @ clean boundary D entry
++
++      /* Luke Lee 04/06/2005 ins 4 mod 2 */
++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
++      bic     r0, r0, #CACHE_DLINESIZE - 1
++
++//debug_Aaron
++1:    mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++//1:  mcr     p15, 0, r0, c7, c14, 1          @ clean D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      cmp     r0, r1
++      bls     1b                              @ Luke Lee 05/19/2005 blo->bls
++      /* Luke Lee 04/06/2005 ins 2 */
++#endif
++#endif /* CONFIG_CPU_DCACHE_DISABLE */
++
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++      mov     r0, #0  
++      mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
++#endif        
++
++      mov     pc, lr
++
++/*
++ *    dma_flush_range(start, end)
++ *
++ *    Clean and invalidate the specified virtual address range.
++ *
++ *    - start  - virtual start address
++ *    - end    - virtual end address
++ *
++ *    This is actually the same as fa_coherent_kern_range()
++ */
++      .globl  fa_dma_flush_range
++      .set    fa_dma_flush_range, fa_coherent_kern_range
++
++      __INITDATA
++
++      .type   fa_cache_fns, #object
++ENTRY(fa_cache_fns)
++      .long   fa_flush_kern_cache_all
++      .long   fa_flush_user_cache_all
++      .long   fa_flush_user_cache_range
++      .long   fa_coherent_kern_range
++      .long   fa_coherent_user_range
++      .long   fa_flush_kern_dcache_page
++      .long   fa_dma_inv_range
++      .long   fa_dma_clean_range
++      .long   fa_dma_flush_range
++      .size   fa_cache_fns, . - fa_cache_fns
+--- /dev/null
++++ b/arch/arm/mm/copypage-fa.S
+@@ -0,0 +1,106 @@
++/*
++ *  linux/arch/arm/lib/copypage-fa.S
++ *
++ *  Copyright (C) 2005 Faraday Corp.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  ASM optimised string functions
++ * 05/18/2005 :       Luke Lee created, modified from copypage-v4wb.S
++ */
++#include <linux/linkage.h>
++#include <linux/init.h>
++#include <asm/asm-offsets.h>
++
++      .text
++/*
++ * ARMv4 optimised copy_user_page for Faraday processors
++ *
++ * We flush the destination cache lines just before we write the data into the
++ * corresponding address.  Since the Dcache is read-allocate, this removes the
++ * Dcache aliasing issue.  The writes will be forwarded to the write buffer,
++ * and merged as appropriate.
++ *
++ * Note: We rely on all ARMv4 processors implementing the "invalidate D line"
++ * instruction.  If your processor does not supply this, you have to write your
++ * own copy_user_page that does the right thing.
++ *
++ * copy_user_page(to,from,vaddr)
++ */
++      .align  4
++ENTRY(fa_copy_user_page)
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      /* Write through */
++      stmfd   sp!, {r4, lr}                   @ 2
++      mov     r2, #PAGE_SZ/32                 @ 1
++
++      ldmia   r1!, {r3, r4, ip, lr}           @ 4
++1:    stmia   r0!, {r3, r4, ip, lr}           @ 4
++      ldmia   r1!, {r3, r4, ip, lr}           @ 4+1
++      subs    r2, r2, #1                      @ 1
++      stmia   r0!, {r3, r4, ip, lr}           @ 4
++      ldmneia r1!, {r3, r4, ip, lr}           @ 4
++      bne     1b                              @ 1
++
++      mcr     p15, 0, r2, c7, c7, 0           @ flush ID cache
++      ldmfd   sp!, {r4, pc}                   @ 3
++#else
++      /* Write back */
++      stmfd   sp!, {r4, lr}                   @ 2
++      mov     r2, #PAGE_SZ/32                 @ 1
++
++1:    ldmia   r1!, {r3, r4, ip, lr}           @ 4
++      mcr     p15, 0, r0, c7, c6, 1           @ 1   invalidate D line
++      stmia   r0!, {r3, r4, ip, lr}           @ 4
++      ldmia   r1!, {r3, r4, ip, lr}           @ 4
++      mcr     p15, 0, r0, c7, c6, 1           @ 1   invalidate D line
++      stmia   r0!, {r3, r4, ip, lr}           @ 4
++      subs    r2, r2, #1                      @ 1
++      bne     1b
++      mcr     p15, 0, r2, c7, c10, 4          @ 1   drain WB
++      ldmfd   sp!, {r4, pc}                   @ 3
++#endif
++
++/*
++ * ARMv4 optimised clear_user_page
++ *
++ * Same story as above.
++ */
++      .align  4
++ENTRY(fa_clear_user_page)
++      str     lr, [sp, #-4]!
++      mov     r1, #PAGE_SZ/32                 @ 1
++      mov     r2, #0                          @ 1
++      mov     r3, #0                          @ 1
++      mov     ip, #0                          @ 1
++      mov     lr, #0                          @ 1
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      /* Write through */
++1:    stmia   r0!, {r2, r3, ip, lr}           @ 4
++      stmia   r0!, {r2, r3, ip, lr}           @ 4
++      subs    r1, r1, #1                      @ 1
++      bne     1b                              @ 1
++
++      mcr     p15, 0, r1, c7, c7, 0           @ flush ID cache
++      ldr     pc, [sp], #4
++#else
++      /* Write back */
++1:    mcr     p15, 0, r0, c7, c6, 1           @ 1   invalidate D line
++      stmia   r0!, {r2, r3, ip, lr}           @ 4
++      mcr     p15, 0, r0, c7, c6, 1           @ 1   invalidate D line
++      stmia   r0!, {r2, r3, ip, lr}           @ 4
++      subs    r1, r1, #1                      @ 1
++      bne     1b                              @ 1
++      mcr     p15, 0, r1, c7, c10, 4          @ 1   drain WB
++      ldr     pc, [sp], #4
++#endif
++
++      __INITDATA
++
++      .type   fa_user_fns, #object
++ENTRY(fa_user_fns)
++      .long   fa_clear_user_page
++      .long   fa_copy_user_page
++      .size   fa_user_fns, . - fa_user_fns
+--- a/arch/arm/mm/init.c
++++ b/arch/arm/mm/init.c
+@@ -23,6 +23,7 @@
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
++#include <asm/arch/ipi.h>
+ #include "mm.h"
+@@ -252,6 +253,11 @@
+               initrd_end = initrd_start + phys_initrd_size;
+       }
+ #endif
++#ifdef CONFIG_GEMINI_IPI
++      printk("CPU ID:%d\n",getcpuid());
++//    reserve_bootmem_node(NODE_DATA(0), 0x400000, 0x400000);         //CPU0 space
++//    reserve_bootmem_node(NODE_DATA(0), SHAREADDR, SHARE_MEM_SIZE);          //share memory
++#endif
+       /*
+        * Finally, reserve any node zero regions.
+--- /dev/null
++++ b/arch/arm/mm/proc-fa526.S
+@@ -0,0 +1,407 @@
++/*
++ *  linux/arch/arm/mm/proc-fa526.S: MMU functions for FA526
++ *
++ *  Copyright (C) 2005 Faraday Corp.
++ *
++ * 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 program is distributed in the hope that 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
++ *
++ *
++ * These are the low level assembler for performing cache and TLB
++ * functions on the fa526.
++ *
++ *  Written by : Luke Lee
++ */
++#include <linux/linkage.h>
++#include <linux/init.h>
++#include <asm/assembler.h>
++#include <asm/pgtable.h>
++#include <asm/pgtable-hwdef.h>
++#include <asm/elf.h>
++#include <asm/hardware.h>
++#include <asm/page.h>
++#include <asm/ptrace.h>
++#include <asm/system.h>
++#include "proc-macros.S"
++
++#define CACHE_DLINESIZE          16
++
++      .text
++/*
++ * cpu_fa526_proc_init()
++ */
++ENTRY(cpu_fa526_proc_init)
++      /* MMU is already ON here, ICACHE, DCACHE conditionally disabled */
++
++        mov     r0, #1
++      nop
++      nop
++        mcr     p15, 0, r0, c1, c1, 0         @ turn-on ECR
++      nop
++      nop
++
++      mrc     p15, 0, r0, c1, c0, 0           @ read ctrl register
++
++#ifdef CONFIG_CPU_FA_BTB
++      orr     r0, r0, #CR_Z
++#else
++      bic     r0, r0, #CR_Z
++#endif
++#ifdef CONFIG_CPU_FA_WB_DISABLE
++      mov     r1, #0
++      mcr     p15, 0, r1, c7, c10, 4          @ drain write buffer
++      nop
++      nop
++      bic     r0, r0, #CR_W
++#else
++      orr     r0, r0, #CR_W
++#endif
++#ifdef CONFIG_CPU_DCACHE_DISABLE
++      bic     r0, r0, #CR_C
++#else
++      orr     r0, r0, #CR_C
++#endif
++#ifdef CONFIG_CPU_ICACHE_DISABLE
++      bic     r0, r0, #CR_I
++#else
++      orr     r0, r0, #CR_I
++#endif
++
++      nop
++      nop
++      mcr     p15, 0, r0, c1, c0, 0
++      nop
++      nop
++
++      mov     r5, lr
++      bl      fa_initialize_cache_info        @ destroy r0~r4
++      mov     pc, r5                          @ return
++
++
++/*
++ * cpu_fa526_proc_fin()
++ */
++ENTRY(cpu_fa526_proc_fin)
++      stmfd   sp!, {lr}
++      mov     ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
++      msr     cpsr_c, ip
++
++      bl      fa_flush_kern_cache_all
++      mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
++      bic     r0, r0, #0x1000                 @ ...i............
++      bic     r0, r0, #0x000e                 @ ............wca.
++      mcr     p15, 0, r0, c1, c0, 0           @ disable caches
++
++      nop
++      nop
++      ldmfd   sp!, {pc}
++
++/*
++ * cpu_fa526_reset(loc)
++ *
++ * Perform a soft reset of the system.  Put the CPU into the
++ * same state as it would be if it had been reset, and branch
++ * to what would be the reset vector.
++ *
++ * loc: location to jump to for soft reset
++ */
++      .align  4
++ENTRY(cpu_fa526_reset)
++      mov     ip, #0
++      mcr     p15, 0, ip, c7, c7, 0           @ invalidate I,D caches
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++#endif
++      mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
++      mrc     p15, 0, ip, c1, c0, 0           @ ctrl register
++      bic     ip, ip, #0x000f                 @ ............wcam
++      bic     ip, ip, #0x1100                 @ ...i...s........
++
++      bic     ip, ip, #0x0800                 @ BTB off
++      mcr     p15, 0, ip, c1, c0, 0           @ ctrl register
++      nop
++      nop
++      mov     pc, r0
++
++/*
++ * cpu_fa526_do_idle()
++ */
++      .align  4
++ENTRY(cpu_fa526_do_idle)
++
++#ifdef CONFIG_CPU_FA_IDLE
++      nop
++      nop
++      mcr     p15, 0, r0, c7, c0, 4           @ Wait for interrupt (IDLE mode)
++#endif
++      mov     pc, lr
++
++
++ENTRY(cpu_fa526_dcache_clean_area)
++
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
++1:    mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
++      add     r0, r0, #CACHE_DLINESIZE
++      subs    r1, r1, #CACHE_DLINESIZE
++      bhi     1b
++#endif
++#endif
++      mov     pc, lr
++
++
++/* =============================== PageTable ============================== */
++
++/*
++ * cpu_fa526_switch_mm(pgd)
++ *
++ * Set the translation base pointer to be as described by pgd.
++ *
++ * pgd: new page tables
++ */
++      .align  4
++
++      .globl  fault_address
++fault_address:
++      .long   0
++
++ENTRY(cpu_fa526_switch_mm)
++
++      mov     ip, #0
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      mcr     p15, 0, ip, c7, c6, 0           @ invalidate D cache
++#else
++      mcr     p15, 0, ip, c7, c14, 0          @ Clean and invalidate whole DCache
++#endif
++#endif /*CONFIG_CPU_DCACHE_DISABLE*/
++
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      mcr     p15, 0, ip, c7, c5, 0           @ invalidate I cache
++#endif
++
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++      mcr     p15, 0, ip, c7, c10, 4          @ drain WB
++#endif
++
++#ifdef CONFIG_CPU_FA_BTB
++      mcr     p15, 0, ip, c7, c5, 6           @ invalidate BTB since mm changed
++      nop
++      nop
++#endif
++      bic     r0, r0, #0xff                   @ clear bits [7:0]
++      bic     r0, r0, #0x3f00                 @ clear bits [13:8]
++      mcr     p15, 0, r0, c2, c0, 0           @ load page table pointer
++      mcr     p15, 0, ip, c8, c7, 0           @ invalidate UTLB
++      nop
++      nop
++      mov     pc, lr
++
++/*
++ * cpu_fa526_set_pte_ext(ptep, pte, ext)
++ *
++ * Set a PTE and flush it out
++ */
++      .align  4
++ENTRY(cpu_fa526_set_pte_ext)
++      str     r1, [r0], #-2048                @ linux version
++
++      eor     r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
++
++      bic     r2, r1, #PTE_SMALL_AP_MASK
++      bic     r2, r2, #PTE_TYPE_MASK
++      orr     r2, r2, #PTE_TYPE_SMALL
++
++      tst     r1, #L_PTE_USER                 @ User?
++      orrne   r2, r2, #PTE_SMALL_AP_URO_SRW
++
++      tst     r1, #L_PTE_WRITE | L_PTE_DIRTY  @ Write and Dirty?
++      orreq   r2, r2, #PTE_SMALL_AP_UNO_SRW
++
++      tst     r1, #L_PTE_PRESENT | L_PTE_YOUNG        @ Present and Young?
++      movne   r2, #0
++
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      eor     r3, r2, #0x0a                   @ C & small page?  1010
++      tst     r3, #0x0b                       @                  1011
++      biceq   r2, r2, #4
++#endif
++      str     r2, [r0]                        @ hardware version
++
++      mov     r2, #0
++      mcr     p15, 0, r2, c7, c10, 0          @ clean D cache all
++
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++      mcr     p15, 0, r2, c7, c10, 4          @ drain WB
++#endif
++#ifdef CONFIG_CPU_FA_BTB
++      mcr     p15, 0, r2, c7, c5, 6           @ invalidate BTB
++      nop
++      nop
++#endif
++      mov     pc, lr
++
++      __INIT
++
++      .type   __fa526_setup, #function
++__fa526_setup:
++      /* On return of this routine, r0 must carry correct flags for CFG register */
++      mov     r0, #0
++      mcr     p15, 0, r0, c7, c7              @ invalidate I,D caches on v4
++      mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer on v4
++      mcr     p15, 0, r0, c8, c7              @ invalidate I,D TLBs on v4
++
++      mcr     p15, 0, r0, c7, c5, 5           @ invalidate IScratchpad RAM
++
++        mov     r0, #1
++        mcr     p15, 0, r0, c1, c1, 0         @ turn-on ECR
++
++      mrc     p15, 0, r0, c9, c1, 0           @ DScratchpad
++      bic     r0, r0, #1
++      mcr     p15, 0, r0, c9, c1, 0
++      mrc     p15, 0, r0, c9, c1, 1           @ IScratchpad
++      bic     r0, r0, #1
++      mcr     p15, 0, r0, c9, c1, 1
++
++      mov     r0, #0
++      mcr     p15, 0, r0, c1, c1, 0           @ turn-off ECR
++
++#ifdef CONFIG_CPU_FA_BTB
++      mcr     p15, 0, r0, c7, c5, 6           @ invalidate BTB All
++      nop
++      nop
++#endif
++
++      mov     r0, #0x1f                       @ Domains 0, 1 = manager, 2 = client
++      mcr     p15, 0, r0, c3, c0              @ load domain access register
++
++      mrc     p15, 0, r0, c1, c0              @ get control register v4
++      ldr     r5, fa526_cr1_clear
++      bic     r0, r0, r5
++      ldr     r5, fa526_cr1_set
++      orr     r0, r0, r5
++
++#ifdef CONFIG_CPU_FA_BTB
++      orr     r0, r0, #CR_Z
++#else
++      bic     r0, r0, #CR_Z
++#endif
++#ifdef CONFIG_CPU_FA_WB_DISABLE
++      mov     r12, #0
++      mcr     p15, 0, r12, c7, c10, 4         @ drain write buffer
++      nop
++      nop
++      bic     r0, r0, #CR_W                   @ .... .... .... 1...
++#else
++      orr     r0, r0, #CR_W
++#endif
++
++      mov     pc, lr
++      .size   __fa526_setup, . - __fa526_setup
++
++      /*
++       * .RVI ZFRS BLDP WCAM
++       * ..11 0001 .111 1101
++       *
++       */
++      .type   fa526_cr1_clear, #object
++      .type   fa526_cr1_set, #object
++fa526_cr1_clear:
++      .word   0x3f3f
++fa526_cr1_set:
++      .word   0x317D
++
++      __INITDATA
++
++/*
++ * Purpose : Function pointers used to access above functions - all calls
++ *         come through these
++ */
++      .type   fa526_processor_functions, #object
++fa526_processor_functions:
++      .word   v4_early_abort
++      .word   cpu_fa526_proc_init
++      .word   cpu_fa526_proc_fin
++      .word   cpu_fa526_reset
++      .word   cpu_fa526_do_idle
++      .word   cpu_fa526_dcache_clean_area
++      .word   cpu_fa526_switch_mm
++      .word   cpu_fa526_set_pte_ext
++      .size   fa526_processor_functions, . - fa526_processor_functions
++
++      .section ".rodata"
++
++      .type   cpu_arch_name, #object
++cpu_arch_name:
++      .asciz  "armv4"
++      .size   cpu_arch_name, . - cpu_arch_name
++
++      .type   cpu_elf_name, #object
++cpu_elf_name:
++      .asciz  "v4"
++      .size   cpu_elf_name, . - cpu_elf_name
++
++      .type   cpu_fa526_name, #object
++cpu_fa526_name:
++      .ascii  "FA526"
++#ifndef CONFIG_CPU_ICACHE_DISABLE
++      .ascii  "i"
++#endif
++#ifndef CONFIG_CPU_DCACHE_DISABLE
++      .ascii  "d"
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++      .ascii  "(wt)"
++#else
++      .ascii  "(wb)"
++#endif
++#endif
++      .ascii  "\0"
++      .size   cpu_fa526_name, . - cpu_fa526_name
++
++      .align
++
++      .section ".proc.info.init", #alloc, #execinstr
++
++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
++#define __PMD_SECT_BUFFERABLE 0
++#else
++#define __PMD_SECT_BUFFERABLE PMD_SECT_BUFFERABLE
++#endif
++
++      .type   __fa526_proc_info,#object
++__fa526_proc_info:
++      .long   0x66015261
++      .long   0xff01fff1
++      .long   PMD_TYPE_SECT | \
++              __PMD_SECT_BUFFERABLE | \
++              PMD_SECT_CACHEABLE | \
++              PMD_BIT4 | \
++              PMD_SECT_AP_WRITE | \
++              PMD_SECT_AP_READ
++      .long   PMD_TYPE_SECT | \
++              PMD_BIT4 | \
++              PMD_SECT_AP_WRITE | \
++              PMD_SECT_AP_READ
++      b       __fa526_setup
++      .long   cpu_arch_name
++      .long   cpu_elf_name
++      .long   HWCAP_SWP | HWCAP_HALF
++      .long   cpu_fa526_name
++      .long   fa526_processor_functions
++      .long   fa_tlb_fns
++      .long   fa_user_fns
++      .long   fa_cache_fns
++      .size   __fa526_proc_info, . - __fa526_proc_info
++
++
+--- /dev/null
++++ b/arch/arm/mm/tlb-fa.S
+@@ -0,0 +1,96 @@
++/*
++ *  linux/arch/arm/mm/tlb-fa.S
++ *
++ *  Copyright (C) 2005 Faraday Corp.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ *  ARM architecture version 4, Faraday variation.
++ *  This assume an unified TLBs, with a write buffer, and branch target buffer (BTB)
++ *
++ *  Processors: FA520 FA526 FA626
++ *  03/31/2005 : Created by Luke Lee, modified from tlb-v4wbi.S
++ *  05/06/2005 : Fixed buggy CPU versions that did not invalidate the associated
++ *               data cache entries when invalidating TLB entries.
++ */
++#include <linux/linkage.h>
++#include <linux/init.h>
++#include <asm/asm-offsets.h>
++#include <asm/tlbflush.h>
++#include "proc-macros.S"
++
++
++/*
++ *    flush_user_tlb_range(start, end, mm)
++ *
++ *    Invalidate a range of TLB entries in the specified address space.
++ *
++ *    - start - range start address
++ *    - end   - range end address
++ *    - mm    - mm_struct describing address space
++ */
++      .align  4
++ENTRY(fa_flush_user_tlb_range)
++
++      vma_vm_mm ip, r2
++      act_mm  r3                              @ get current->active_mm
++      eors    r3, ip, r3                      @ == mm ?
++      movne   pc, lr                          @ no, we dont do anything
++      mov     r3, #0
++
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++      mcr     p15, 0, r3, c7, c10, 4          @ drain WB
++#endif
++
++      vma_vm_flags r2, r2
++      bic     r0, r0, #0x0ff
++      bic     r0, r0, #0xf00
++
++1:    mcr     p15, 0, r0, c8, c7, 1           @ invalidate UTLB entry
++      add     r0, r0, #PAGE_SZ
++      cmp     r0, r1
++      bls     1b                              @ Luke Lee 05/19/2005 blo -> bls
++
++#ifdef CONFIG_CPU_FA_BTB
++      mcr     p15, 0, r3, c7, c5, 6           @ invalidate BTB
++      nop
++      nop
++#endif
++      mov     pc, lr
++
++
++ENTRY(fa_flush_kern_tlb_range)
++      mov     r3, #0
++
++      mcr     p15, 0, r3, c7, c10, 0          @ clean Dcache all 06/03/2005
++
++#ifndef CONFIG_CPU_FA_WB_DISABLE
++      mcr     p15, 0, r3, c7, c10, 4          @ drain WB
++#endif
++
++      bic     r0, r0, #0x0ff
++      bic     r0, r0, #0xf00
++1:
++      mcr     p15, 0, r0, c8, c7, 1           @ invalidate UTLB entry
++      add     r0, r0, #PAGE_SZ
++      cmp     r0, r1
++      bls     1b                              @ Luke Lee 05/19/2005 blo -> bls
++
++#ifdef CONFIG_CPU_FA_BTB
++      mcr     p15, 0, r3, c7, c5, 6           @ invalidate BTB
++      nop
++      nop
++#endif
++      mov     pc, lr
++
++
++      __INITDATA
++
++      .type   fa_tlb_fns, #object
++ENTRY(fa_tlb_fns)
++      .long   fa_flush_user_tlb_range
++      .long   fa_flush_kern_tlb_range
++      .long   fa_tlb_flags
++      .size   fa_tlb_fns, . - fa_tlb_fns
+--- a/arch/arm/tools/mach-types
++++ b/arch/arm/tools/mach-types
+@@ -208,7 +208,8 @@
+ fester                        SA1100_FESTER           FESTER                  191
+ gpi                   ARCH_GPI                GPI                     192
+ smdk2410              ARCH_SMDK2410           SMDK2410                193
+-i519                  ARCH_I519               I519                    194
++#i519                 ARCH_I519               I519                    194
++sl2312          ARCH_SL2312         SL2312          194
+ nexio                 SA1100_NEXIO            NEXIO                   195
+ bitbox                        SA1100_BITBOX           BITBOX                  196
+ g200                  SA1100_G200             G200                    197
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/SL_gpio.h
+@@ -0,0 +1,59 @@
++#define GPIO_MINOR_LAST 31
++#define GPIO_MAJOR    120     // Experiemental
++
++#define GPIO_IRQ_NBR  12
++
++#define GPIOBASEADDR          (IO_ADDRESS(0x021000000))
++
++#define GPIODATAOUTOFF                0x00
++#define GPIODATAINOFF         0x04
++#define GPIOPINDIROFF         0x08
++#define GPIOPINBYPASSOFF      0x0C
++#define GPIODATASETOFF                0x10
++#define GPIODATACLEAROFF      0x14
++#define GPIOPINPULLENBOFF     0x18
++#define GPIOPINPULLTPOFF      0x1C
++#define GPIOINTRENBOFF                0x20
++#define GPIOINTRRAWSOFF               0x24
++#define GPIOINTRMASKEDSTATEOFF        0x28
++#define GPIOINTRMASKOFF               0x2C
++#define GPIOINTRCLEAROFF      0x30
++#define GPIOINTRTRIGGEROFF    0x34
++#define GPIOINTRBOTHOFF               0x38
++#define GPIOINTRRISENEGOFF    0x3C
++#define GPIOBNCEENBOFF                0x40
++#define GPIOBNCEPRESOFF               0x44
++
++#define GPIO_IOCTRL_SETDIR    0x20
++#define GPIO_IOCTRL_SET               0x40
++#define GPIO_IOCTRL_CLEAR     0x50
++#define GPIO_IOCTRL_ENBINT    0x60
++#define GPIO_IOCTRL_MASKINT   0x70
++#define GPIO_IOCTRL_LVLTRIG   0x75
++#define GPIO_IOCTRL_EDGINT    0x77
++#define GPIO_IOCTRL_EDGPOLINT 0x78
++#define GPIO_IOCTRL_BYPASS    0x30
++#define GPIO_IOCTRL_PRESCLK   0x80
++#define GPIO_IOCTRL_CLKVAL    0x90
++#define GPIO_IOCTRL_PULLENB   0xA0
++#define GPIO_IOCTRL_PULLTYPE  0xA8
++
++
++#define GPIO_MAJOR    120     /* experimental MAJOR number */
++                              // Minor - 0 : 31 gpio pins
++
++#define GPIO_SET      0x01
++#define GPIO_CLEAR    0x01
++
++#define GPIO_INPUT    0
++#define GPIO_OUTPUT   1
++#define GPIO_EDGEINTR         0
++#define GPIO_EDGESINGL        0
++#define GPIO_EDGEBOTH 1
++#define GPIO_POSITIVE 0
++#define GPIO_ENBINT   1
++#define GPIO_DISABLEMASK      1
++#define GPIO_PULLDOWN 0
++#define GPIO_PULLUP   1
++#define GPIO_ENABLEPULL       1
++#define GPIO_DISABLEPULL      0
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/debug-macro.S
+@@ -0,0 +1,20 @@
++/* linux/include/asm-arm/arch-ebsa110/debug-macro.S
++ *
++ * Debugging macro include header
++ *
++ *  Copyright (C) 1994-1999 Russell King
++ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++**/
++
++              .macro  addruart,rx
++              mov     \rx, #0x42000000
++              .endm
++
++#define UART_SHIFT    2
++#define FLOW_CONTROL
++#include <asm/hardware/debug-8250.S>
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/dma.h
+@@ -0,0 +1,28 @@
++/*
++ *  linux/include/asm-arm/arch-camelot/dma.h
++ *
++ *  Copyright (C) 1997,1998 Russell King
++ *
++ * 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 program is distributed in the hope that 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
++ */
++#ifndef __ASM_ARCH_DMA_H
++#define __ASM_ARCH_DMA_H
++
++#define MAX_DMA_ADDRESS               0xffffffff
++
++#define MAX_DMA_CHANNELS      0
++
++#endif /* _ASM_ARCH_DMA_H */
++
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/entry-macro.S
+@@ -0,0 +1,42 @@
++/*
++ * include/asm-arm/arch-arm/entry-macro.S
++ *
++ * Low-level IRQ helper macros for ebsa110 platform.
++ *
++ * This file is licensed under  the terms of the GNU General Public
++ * License version 2. This program is licensed "as is" without any
++ * warranty of any kind, whether express or implied.
++ */
++#include <asm/arch/platform.h>
++#include <asm/arch/int_ctrl.h>
++
++
++                .macro  disable_fiq
++                .endm
++
++                .macro  get_irqnr_preamble, base, tmp
++                .endm
++
++                .macro  arch_ret_to_user, tmp1, tmp2
++                .endm
++
++                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
++                ldr     \irqstat, =IRQ_STATUS(IO_ADDRESS(SL2312_INTERRUPT_BASE))
++                ldr     \irqnr,[\irqstat]
++                cmp     \irqnr,#0
++                beq     2313f
++                mov     \tmp,\irqnr
++                mov     \irqnr,#0
++2312:
++                tst     \tmp, #1
++                bne     2313f
++                add     \irqnr, \irqnr, #1
++                mov     \tmp, \tmp, lsr #1
++                cmp     \irqnr, #31
++                bcc     2312b
++2313:
++                .endm
++
++                .macro  irq_prio_table
++                .endm
++
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/flash.h
+@@ -0,0 +1,83 @@
++#ifndef __ASM_ARM_ARCH_FLASH_H
++#define __ASM_ARM_ARCH_FLASH_H
++
++#define FLASH_START                                     SL2312_FLASH_BASE
++#define SFLASH_SIZE                                   0x00400000
++#define SPAGE_SIZE                                    0x200
++#define BLOCK_ERASE                                   0x50
++#define BUFFER1_READ                                  0x54
++#define BUFFER2_READ                                  0x56
++#define PAGE_ERASE                                    0x81
++#define MAIN_MEMORY_PAGE_READ                         0x52
++#define MAIN_MEMORY_PROGRAM_BUFFER1                   0x82
++#define MAIN_MEMORY_PROGRAM_BUFFER2                   0x85
++#define BUFFER1_TO_MAIN_MEMORY                        0x83
++#define BUFFER2_TO_MAIN_MEMORY                        0x86
++#define MAIN_MEMORY_TO_BUFFER1                        0x53
++#define MAIN_MEMORY_TO_BUFFER2                        0x55
++#define BUFFER1_WRITE                                 0x84
++#define BUFFER2_WRITE                                 0x87
++#define AUTO_PAGE_REWRITE_BUFFER1                     0x58
++#define AUTO_PAGE_REWRITE_BUFFER2                     0x59
++#define READ_STATUS                                   0x57
++
++#define MAIN_MEMORY_PAGE_READ_SPI                     0xD2
++#define BUFFER1_READ_SPI                              0xD4
++#define BUFFER2_READ_SPI                              0xD6
++#define READ_STATUS_SPI                               0xD7
++
++#define       FLASH_ACCESS_OFFSET                             0x00000010
++#define       FLASH_ADDRESS_OFFSET                            0x00000014
++#define       FLASH_WRITE_DATA_OFFSET                         0x00000018
++#define       FLASH_READ_DATA_OFFSET                          0x00000018
++#define SERIAL_FLASH_CHIP1_EN            0x00010000  // 16th bit = 1
++#define SERIAL_FLASH_CHIP0_EN            0x00000000  // 16th bit = 0
++#define AT45DB321_PAGE_SHIFT                   0xa
++#define AT45DB642_PAGE_SHIFT                   0xb
++#define CONTINUOUS_MODE                        0x00008000
++
++#define FLASH_ACCESS_ACTION_OPCODE                      0x0000
++#define FLASH_ACCESS_ACTION_OPCODE_DATA                 0x0100
++#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS               0x0200
++#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS_DATA          0x0300
++#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS_X_DATA          0x0400
++#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS_2X_DATA         0x0500
++#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS_3X_DATA         0x0600
++#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS_4X_DATA         0x0700
++//#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS_X_DATA        0x0600
++//#define FLASH_ACCESS_ACTION_SHIFT_ADDRESS_4X_DATA       0x0700
++
++#define M25P80_PAGE_SIZE  0x100
++#define M25P80_SECTOR_SIZE  0x10000
++
++
++//#define M25P80_BULK_ERASE                                      1
++//#define M25P80_SECTOR_ERASE                                    2
++//#define M25P80_SECTOR_SIZE                                     0x10000
++
++#define M25P80_WRITE_ENABLE                           0x06
++#define M25P80_WRITE_DISABLE                          0x04
++#define M25P80_READ_STATUS                            0x05
++#define M25P80_WRITE_STATUS                           0x01
++#define M25P80_READ                                   0x03
++#define M25P80_FAST_READ                              0x0B
++#define M25P80_PAGE_PROGRAM                           0x02
++#define M25P80_SECTOR_ERASE                           0xD8
++#define M25P80_BULK_ERASE                             0xC7
++#define FLASH_ERR_OK                                                  0x0
++
++extern void address_to_page(__u32, __u16 *, __u16 *);
++extern void main_memory_page_read(__u8, __u16, __u16, __u8 *);
++extern void buffer_to_main_memory(__u8, __u16);
++extern void main_memory_to_buffer(__u8, __u16);
++extern void main_memory_page_program(__u8, __u16, __u16, __u8);
++extern void atmel_flash_read_page(__u32, __u8 *, __u32);
++extern void atmel_erase_page(__u8, __u16);
++extern void atmel_read_status(__u8, __u8 *);
++extern void atmel_flash_program_page(__u32, __u8 *, __u32);
++extern void atmel_buffer_write(__u8, __u16, __u8);
++extern void flash_delay(void);
++
++extern int m25p80_sector_erase(__u32 address, __u32 schip_en);
++
++#endif
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/gemini_cir.h
+@@ -0,0 +1,102 @@
++#ifndef _ASM_ARCH_CIR_H
++#define _ASM_ARCH_CIR_H
++#include <linux/ioctl.h>
++
++#define VCR_KEY_POWER         0x613E609F
++#define TV1_KEY_POWER         0x40040100
++#define TV1_KEY_POWER_EXT     0xBCBD
++#define RC5_KER_POWER         0x0CF3
++
++#define VCC_H_ACT_PER         (16-1)
++#define VCC_L_ACT_PER         (8-1)
++#define VCC_DATA_LEN          (32-1)
++#define TV1_H_ACT_PER         (8-1)
++#define TV1_L_ACT_PER         (4-1)
++#define TV1_DATA_LEN          (48-1)
++
++#define VCC_BAUD              540
++#define TV1_BAUD              430
++#ifdef  CONFIG_SL3516_ASIC
++#define       EXT_CLK                 60
++#else
++#define       EXT_CLK                 20
++#endif
++
++#define       NEC_PROTOCOL    0x0
++#define       RC5_PROTOCOL    0x1
++#define VCC_PROTOCOL  0x0
++#define TV1_PROTOCOL  0x01
++
++#ifndef       SL2312_CIR_BASE
++#define       SL2312_CIR_BASE         0x4C000000
++#endif
++#define       CIR_BASE_ADDR           IO_ADDRESS(SL2312_CIR_BASE)
++#define STORLINK_CIR_ID               0x00010400
++
++#define       CIR_IP_ID               *(volatile unsigned int *)(CIR_BASE_ADDR + 0x00)
++#define       CIR_CTR_REG             *(volatile unsigned int *)(CIR_BASE_ADDR + 0x04)
++#define       CIR_STATUS_REG          *(volatile unsigned int *)(CIR_BASE_ADDR + 0x08)
++#define       CIR_RX_REG              *(volatile unsigned int *)(CIR_BASE_ADDR + 0x0C)
++#define       CIR_RX_EXT_REG          *(volatile unsigned int *)(CIR_BASE_ADDR + 0x10)
++#define       CIR_PWR_REG             *(volatile unsigned int *)(CIR_BASE_ADDR + 0x14)
++#define       CIR_PWR_EXT_REG         *(volatile unsigned int *)(CIR_BASE_ADDR + 0x18)
++#define       CIR_TX_CTR_REG          *(volatile unsigned int *)(CIR_BASE_ADDR + 0x1C)
++#define       CIR_TX_FEQ_REG          *(volatile unsigned int *)(CIR_BASE_ADDR + 0x20)
++#define       CIR_TX_REG              *(volatile unsigned int *)(CIR_BASE_ADDR + 0x24)
++#define       CIR_TX_EXT_REG          *(volatile unsigned int *)(CIR_BASE_ADDR + 0x28)
++
++
++#ifndef       SL2312_POWER_CTRL_BASE
++#define       SL2312_POWER_CTRL_BASE          0x4B000000
++#endif
++
++#ifndef PWR_BASE_ADDR
++#define       PWR_BASE_ADDR           IO_ADDRESS(SL2312_POWER_CTRL_BASE)
++#endif
++#define       PWR_CTRL_ID             *(unsigned int*)(PWR_BASE_ADDR+0x00)
++#define       PWR_CTRL_REG            *(unsigned int*)(PWR_BASE_ADDR+0x04)
++#define       PWR_STATUS_REG          *(unsigned int*)(PWR_BASE_ADDR+0x08)
++
++
++#define BIT(x)                        (1<<x)
++#define TX_STATUS             BIT(3)
++
++#define       PWR_STAT_CIR            0x10
++#define       PWR_STAT_RTC            0x20
++#define       PWR_STAT_PUSH           0x40
++#define       PWR_SHUTDOWN            0x01
++
++#define CARR_FREQ             38000
++
++struct cir_ioctl_data {
++      __u32 data;
++};
++struct cir_ioctl_data48 {
++      __u32 timeout;
++      __u32 length;
++      __u8  ret;
++      __u32 data;
++      __u32 data_ext;
++};
++#define OLD_DATA                      0
++#define NEW_RECEIVE                   1
++
++#define       CIR_IOCTL_BASE          ('I'|'R')
++#define CIR_SET_BAUDRATE                      _IOW (CIR_IOCTL_BASE,  0, struct cir_ioctl_data)
++#define CIR_SET_HIGH_PERIOD                   _IOW (CIR_IOCTL_BASE,  1, struct cir_ioctl_data)
++#define CIR_SET_LOW_PERIOD                    _IOW (CIR_IOCTL_BASE,  2, struct cir_ioctl_data)
++#define CIR_SET_PROTOCOL                      _IOW (CIR_IOCTL_BASE,  3, struct cir_ioctl_data)
++#define CIR_SET_ENABLE_COMPARE                _IOW (CIR_IOCTL_BASE,  4, struct cir_ioctl_data)
++#define CIR_SET_ENABLE_DEMOD          _IOW (CIR_IOCTL_BASE,  5, struct cir_ioctl_data)
++#define CIR_SET_POWER_KEY                     _IOW (CIR_IOCTL_BASE,  6, struct cir_ioctl_data)
++#define CIR_GET_BAUDRATE                      _IOR (CIR_IOCTL_BASE,  7, struct cir_ioctl_data)
++#define CIR_GET_HIGH_PERIOD                   _IOR (CIR_IOCTL_BASE,  8 ,struct cir_ioctl_data)
++#define CIR_GET_LOW_PERIOD                    _IOR (CIR_IOCTL_BASE,  9 ,struct cir_ioctl_data)
++#define CIR_GET_PROTOCOL                      _IOR (CIR_IOCTL_BASE, 10, struct cir_ioctl_data)
++#define CIR_GET_ENABLE_COMPARE                _IOR (CIR_IOCTL_BASE, 11, struct cir_ioctl_data)
++#define CIR_GET_ENABLE_DEMOD          _IOR (CIR_IOCTL_BASE, 12, struct cir_ioctl_data)
++#define CIR_GET_POWER_KEY                     _IOR (CIR_IOCTL_BASE, 13, struct cir_ioctl_data)
++#define CIR_GET_DATA                          _IOWR (CIR_IOCTL_BASE, 14, struct cir_ioctl_data48)
++#define CIR_WAIT_INT_DATA                     _IOWR (CIR_IOCTL_BASE, 15, struct cir_ioctl_data48)
++
++#endif //_ASM_ARCH_CIR_H
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/gemini_gpio.h
+@@ -0,0 +1,77 @@
++/*
++ * FILE NAME gemini_gpio.h
++ *
++ * BRIEF MODULE DESCRIPTION
++ *    Generic Gemini GPIO
++ *
++ *  Author: Storlink Software [Device driver]
++ *          Jason Lee <jason@storlink.com.tw>
++ *
++ * Copyright 2005 Storlink Inc.
++ *
++ *  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.
++ */
++
++#ifndef __GEMINI_GPIO_H
++#define __GEMINI_GPIO_H
++
++#include <linux/ioctl.h>
++
++#define STATUS_HIGH   1
++#define STATUS_LOW    0
++#define DIRECT_OUT    1
++#define DIRECT_IN     0
++
++#define EDGE_TRIG     0
++#define RISING_EDGE   0
++#define FALL_EDGE     1
++#define SINGLE_EDGE   0
++#define BOTH_EDGE     1
++
++#define LEVEL_TRIG    1
++#define HIGH_ACTIVE   0
++#define LOW_ACTIVE    1
++
++struct gemini_gpio_ioctl_data {
++      __u32 pin;
++      __u8 status;                    // status or pin direction
++                                      // 0: status low or Input
++                                      // 1: status high or Output
++
++      /* these member are used to config GPIO interrupt parameter */
++      __u8    use_default;            // if not sure ,set this argument 1
++      __u8    trig_type;              // 0/1:edge/level triger ?
++      __u8    trig_polar;             // 0/1:rising/falling high/low active ?
++      __u8    trig_both;              // 0/1:single/both detect both ?
++};
++
++#define GEMINI_GPIO_IOCTL_BASE        'Z'
++
++#define GEMINI_SET_GPIO_PIN_DIR               _IOW (GEMINI_GPIO_IOCTL_BASE,16, struct gemini_gpio_ioctl_data)
++#define       GEMINI_SET_GPIO_PIN_STATUS      _IOW (GEMINI_GPIO_IOCTL_BASE,17, struct gemini_gpio_ioctl_data)
++#define       GEMINI_GET_GPIO_PIN_STATUS      _IOWR(GEMINI_GPIO_IOCTL_BASE,18, struct gemini_gpio_ioctl_data)
++#define GEMINI_WAIT_GPIO_PIN_INT      _IOWR(GEMINI_GPIO_IOCTL_BASE,19, struct gemini_gpio_ioctl_data)
++
++
++extern void init_gpio_int(__u32 pin,__u8 trig_type,__u8 trig_polar,__u8 trig_both);
++extern int request_gpio_irq(int bit,void (*handler)(int),char level,char high,char both);
++extern int free_gpio_irq(int bit);
++#endif
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/gemini_i2s.h
+@@ -0,0 +1,169 @@
++#ifndef __GEMINI_I2S_H__
++#define __GEMINI_I2S_H__
++#include <linux/ioctl.h>
++#include <linux/types.h>
++#include <asm/arch-sl2312/irqs.h>
++
++typedef __u16 UINT16;
++typedef __u32 UINT32;
++typedef __u8 UINT8;
++typedef __u8 BOOL;
++
++/***************************************/
++/* define GPIO module base address     */
++/***************************************/
++#define DMA_CONTROL_PHY_BASE  (IO_ADDRESS(SL2312_GENERAL_DMA_BASE))
++#define DMA_CONTROL_SSP_BASE  (IO_ADDRESS(SL2312_SSP_CTRL_BASE))
++#define SSP_INT                               IRQ_SSP
++#define GPIO_BASE_ADDR      (IO_ADDRESS(SL2312_GPIO_BASE))
++#define GPIO_BASE_ADDR1      (IO_ADDRESS(SL2312_GPIO_BASE1))
++#define GLOBAL_BASE      (IO_ADDRESS(SL2312_GLOBAL_BASE))
++
++/* define read/write register utility */
++#define READ_SSP_REG(offset)                  (__raw_readl(offset+DMA_CONTROL_SSP_BASE))
++#define WRITE_SSP_REG(offset,val)     (__raw_writel(val,offset+DMA_CONTROL_SSP_BASE))
++
++#define READ_GPIO_REG(offset)                 (__raw_readl(offset+GPIO_BASE_ADDR))
++#define WRITE_GPIO_REG(offset,val)    (__raw_writel(val,offset+GPIO_BASE_ADDR))
++
++#define READ_GPIO1_REG(offset)                        (__raw_readl(offset+GPIO_BASE_ADDR1))
++#define WRITE_GPIO1_REG(offset,val)   (__raw_writel(val,offset+GPIO_BASE_ADDR1))
++
++#define READ_DMA_REG(offset)                  (__raw_readl(offset+DMA_CONTROL_PHY_BASE))
++#define WRITE_DMA_REG(offset,val)     (__raw_writel(val,offset+DMA_CONTROL_PHY_BASE))
++
++#define READ_GLOBAL_REG(offset)                       (__raw_readl(offset+GLOBAL_BASE))
++#define WRITE_GLOBAL_REG(offset,val)  (__raw_writel(val,offset+GLOBAL_BASE))
++
++#define SSP_GPIO_INT          IRQ_GPIO
++
++#ifndef CONFIG_SL3516_ASIC
++#define SSP_GPIO_INT_BIT    0x00000400                                //GPIO[10] : SLIC interrupt pin
++
++#define GPIO_EECK          0x00000040         /*   SCK: GPIO[06]   */
++#define GPIO_EECS          0x00000080                 /*   SCS: GPIO[07]   */
++#define GPIO_MISO          0x00000200         /*   SDO: GPIO[09]   receive from 6996*/
++#define GPIO_MOSI          0x00000100         /*   SDI: GPIO[08]   send to 6996*/
++#define GPIO_MISO_BIT  9
++#else
++#define SSP_GPIO_INT_BIT    0x00000001                                //GPIO[0] : SLIC interrupt pin
++
++//#if 0
++//#define GPIO_EECK        0x80000000         /*   SCK: GPIO1[31]   */
++//#define GPIO_EECS        0x40000000                 /*   SCS: GPIO1[30]   */
++//#define GPIO_MISO        0x20000000         /*   SDO: GPIO1[29]   receive from 6996*/
++//#define GPIO_MOSI        0x10000000         /*   SDI: GPIO1[28]   send to 6996*/
++//#define GPIO_MISO_BIT       29
++//#else
++//#define GPIO_EECK        0x00000100         /*   SCK: GPIO1[08]   */
++//#define GPIO_EECS        0x08000000                 /*   SCS: GPIO1[27]   */
++//#define GPIO_MISO        0x00000080         /*   SDO: GPIO1[07]   receive from 6996*/
++//#define GPIO_MOSI        0x00000200         /*   SDI: GPIO1[09]   send to 6996*/
++//#define GPIO_MISO_BIT       7
++//#endif
++#endif
++
++
++enum GPIO_REG
++{
++      GPIO_DATA_OUT           = 0x00,
++      GPIO_DATA_IN            = 0x04,
++      GPIO_PIN_DIR            = 0x08,
++      GPIO_BY_PASS            = 0x0c,
++      GPIO_DATA_SET           = 0x10,
++      GPIO_DATA_CLEAR         = 0x14,
++      GPIO_INT_ENABLE     = 0x20,
++      GPIO_INT_RAWSTATE   = 0x24,
++      GPIO_INT_MASKSTATE  = 0x28,
++      GPIO_INT_MASK       = 0x2C,
++      GPIO_INT_CLEAR      = 0x30,
++      GPIO_INT_TRIGGER    = 0x34,
++      GPIO_INT_BOTH       = 0x38,
++      GPIO_INT_POLARITY   = 0x3C
++};
++
++typedef struct
++{
++      UINT32 src_addr;
++      UINT32 dst_addr;
++      UINT32 llp;
++      UINT32 ctrl_size;
++      UINT32 owner;
++}DMA_LLP_t;
++
++typedef struct
++{
++      UINT32 owner;
++      UINT32 src_addr;
++      UINT32 ctrl_size;
++}IOCTL_LLP_t;
++
++typedef unsigned char byte;
++typedef unsigned short word;
++typedef unsigned long dword;
++
++/* DMA Registers */
++#define       DMA_INT                                 0x00000000
++#define       DMA_INT_TC                              0x00000004
++#define       DMA_CFG                                 0x00000024
++#define       DMA_INT_TC_CLR                          0x00000008
++#define       DMA_TC                                          0x00000014
++#define       DMA_CSR                                         0x00000024
++#define       DMA_SYNC                                        0x00000028
++
++#define       DMA_CH2_CSR                             0x00000140
++#define       DMA_CH2_CFG                             0x00000144
++#define       DMA_CH2_SRC_ADDR                0x00000148
++#define       DMA_CH2_DST_ADDR                0x0000014c
++#define       DMA_CH2_LLP                             0x00000150
++#define       DMA_CH2_SIZE                            0x00000154
++
++#define       DMA_CH3_CSR                             0x00000160
++#define       DMA_CH3_CFG                             0x00000164
++#define       DMA_CH3_SRC_ADDR                0x00000168
++#define       DMA_CH3_DST_ADDR                0x0000016c
++#define       DMA_CH3_LLP                             0x00000170
++#define       DMA_CH3_SIZE                            0x00000174
++
++#define    SSP_DEVICE_ID                      0x00
++#define    SSP_CTRL_STATUS                    0x04
++#define          SSP_FRAME_CTRL           0x08
++#define    SSP_BAUD_RATE            0x0c
++#define    SSP_FRAME_CTRL2          0x10
++#define    SSP_FIFO_CTRL            0x14
++#define    SSP_TX_SLOT_VALID0       0x18
++#define    SSP_TX_SLOT_VALID1       0x1c
++#define    SSP_TX_SLOT_VALID2       0x20
++#define    SSP_TX_SLOT_VALID3       0x24
++#define    SSP_RX_SLOT_VALID0       0x28
++#define    SSP_RX_SLOT_VALID1       0x2c
++#define    SSP_RX_SLOT_VALID2       0x30
++#define    SSP_RX_SLOT_VALID3       0x34
++#define    SSP_SLOT_SIZE0           0x38
++#define    SSP_SLOT_SIZE1           0x3c
++#define    SSP_SLOT_SIZE2           0x40
++#define    SSP_SLOT_SIZE3           0x44
++#define    SSP_READ_PORT            0x48
++#define    SSP_WRITE_PORT           0x4c
++
++
++
++#define SSP_I2S_INIT_BUF                      _IO  ('q', 0x00)
++#define SSP_I2S_STOP_DMA                      _IO  ('q', 0x01)
++#define SSP_I2S_FILE_LEN                      _IOW  ('q', 0x2, int)
++/*
++#define SSP_GET_HOOK_STATUS                   _IOR  ('q', 0xC0, int)
++#define SSP_GET_LINEFEED                      _IOR  ('q', 0xC1, int)
++#define SSP_SET_LINEFEED                      _IOW  ('q', 0xC2, int)
++#define SSP_GET_REG                 _IOWR ('q', 0xC3, struct Ssp_reg *)
++#define SSP_SET_REG                 _IOWR ('q', 0xC4, struct Ssp_reg *)
++#define SSP_GEN_OFFHOOK_TONE          _IO   ('q', 0xC5)
++#define SSP_GEN_BUSY_TONE                     _IO   ('q', 0xC6)
++#define SSP_GEN_RINGBACK_TONE         _IO   ('q', 0xC7)
++#define SSP_GEN_CONGESTION_TONE               _IO   ('q', 0xC8)
++#define SSP_DISABLE_DIALTONE          _IO   ('q', 0xC9)
++#define SSP_PHONE_RING_START          _IO   ('q', 0xCA)
++*/
++
++
++#endif //__GEMINI_I2S_H__
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/gemini_ssp.h
+@@ -0,0 +1,263 @@
++/******************************************************************************
++ *    gemini_ssp.h
++ *
++ *
++ *****************************************************************************/
++
++#include <linux/types.h>
++#include <asm/arch-sl2312/irqs.h>
++#include <linux/phonedev.h>
++#include <linux/telephony.h>
++//#include "proslic.h"
++
++typedef __u16 UINT16;
++typedef __u32 UINT32;
++typedef __u8 UINT8;
++typedef __u8 BOOL;
++
++#define TRUE 1
++#define FALSE 0
++
++/***************************************/
++/* define GPIO module base address     */
++/***************************************/
++#define DMA_CONTROL_PHY_BASE  (IO_ADDRESS(SL2312_GENERAL_DMA_BASE))
++#define DMA_CONTROL_SSP_BASE  (IO_ADDRESS(SL2312_SSP_CTRL_BASE))
++#define SSP_INT                               IRQ_SSP
++#define GPIO_BASE_ADDR      (IO_ADDRESS(SL2312_GPIO_BASE))
++#define GPIO_BASE_ADDR1      (IO_ADDRESS(SL2312_GPIO_BASE1))
++#define GLOBAL_BASE      (IO_ADDRESS(SL2312_GLOBAL_BASE))
++
++/* define read/write register utility */
++#define READ_SSP_REG(offset)                  (__raw_readl(offset+DMA_CONTROL_SSP_BASE))
++#define WRITE_SSP_REG(offset,val)     (__raw_writel(val,offset+DMA_CONTROL_SSP_BASE))
++
++#define READ_GPIO_REG(offset)                 (__raw_readl(offset+GPIO_BASE_ADDR))
++#define WRITE_GPIO_REG(offset,val)    (__raw_writel(val,offset+GPIO_BASE_ADDR))
++
++#define READ_GPIO1_REG(offset)                        (__raw_readl(offset+GPIO_BASE_ADDR1))
++#define WRITE_GPIO1_REG(offset,val)   (__raw_writel(val,offset+GPIO_BASE_ADDR1))
++
++#define READ_DMA_REG(offset)                  (__raw_readl(offset+DMA_CONTROL_PHY_BASE))
++#define WRITE_DMA_REG(offset,val)     (__raw_writel(val,offset+DMA_CONTROL_PHY_BASE))
++
++#define READ_GLOBAL_REG(offset)                       (__raw_readl(offset+GLOBAL_BASE))
++#define WRITE_GLOBAL_REG(offset,val)  (__raw_writel(val,offset+GLOBAL_BASE))
++
++
++#define SSP_GPIO_INT          IRQ_GPIO
++
++#ifndef CONFIG_SL3516_ASIC
++#define SSP_GPIO_INT_BIT    0x00000400                                //GPIO[10] : SLIC interrupt pin
++
++#define GPIO_EECK          0x00000040         /*   SCK: GPIO[06]   */
++#define GPIO_EECS          0x00000080                 /*   SCS: GPIO[07]   */
++#define GPIO_MISO          0x00000200         /*   SDO: GPIO[09]   receive from 6996*/
++#define GPIO_MOSI          0x00000100         /*   SDI: GPIO[08]   send to 6996*/
++#define GPIO_MISO_BIT  9
++#else
++#define SSP_GPIO_INT_BIT    0x00000001                                //GPIO[0] : SLIC interrupt pin
++
++//#if 0
++//#define GPIO_EECK        0x80000000         /*   SCK: GPIO1[31]   */
++//#define GPIO_EECS        0x40000000                 /*   SCS: GPIO1[30]   */
++//#define GPIO_MISO        0x20000000         /*   SDO: GPIO1[29]   receive from 6996*/
++//#define GPIO_MOSI        0x10000000         /*   SDI: GPIO1[28]   send to 6996*/
++//#define GPIO_MISO_BIT       29
++//#else
++//#define GPIO_EECK        0x00000100         /*   SCK: GPIO1[08]   */
++//#define GPIO_EECS        0x08000000                 /*   SCS: GPIO1[27]   */
++//#define GPIO_MISO        0x00000080         /*   SDO: GPIO1[07]   receive from 6996*/
++//#define GPIO_MOSI        0x00000200         /*   SDI: GPIO1[09]   send to 6996*/
++//#define GPIO_MISO_BIT       7
++//#endif
++#endif
++
++
++enum GPIO_REG
++{
++      GPIO_DATA_OUT           = 0x00,
++      GPIO_DATA_IN            = 0x04,
++      GPIO_PIN_DIR            = 0x08,
++      GPIO_BY_PASS            = 0x0c,
++      GPIO_DATA_SET           = 0x10,
++      GPIO_DATA_CLEAR         = 0x14,
++      GPIO_INT_ENABLE     = 0x20,
++      GPIO_INT_RAWSTATE   = 0x24,
++      GPIO_INT_MASKSTATE  = 0x28,
++      GPIO_INT_MASK       = 0x2C,
++      GPIO_INT_CLEAR      = 0x30,
++      GPIO_INT_TRIGGER    = 0x34,
++      GPIO_INT_BOTH       = 0x38,
++      GPIO_INT_POLARITY   = 0x3C
++};
++
++
++#define SPI_ADD_LEN        7                  // bits of Address
++#define SPI_DAT_LEN        8                  // bits of Data
++
++
++
++//#ifdef MIDWAY_DIAG
++#define       DAISY_MODE      1
++#if (DAISY_MODE==1)
++#define NUMBER_OF_CHAN        2
++#else
++#define NUMBER_OF_CHAN        1
++#endif
++#define LLP_SIZE   8
++#define SBUF_SIZE  512 //0xff0 //2560
++#define DBUF_SIZE  SBUF_SIZE*NUMBER_OF_CHAN //0xff0 //2560
++#define TBUF_SIZE  (LLP_SIZE)*DBUF_SIZE
++#define DESC_NUM   1
++#define DTMF_NUM   20
++
++/* define owner bit of SSP */
++//data into SSP and transfer to AP==> SSP_Rx
++//data out of SSP and transfer to SLIC==> SSP_Tx
++#define CPU           0
++#define DMA           1
++
++#define DMA_DEMO   0
++#define DMA_NDEMO  1
++//#define DMA_NONE   2
++
++enum exceptions {
++      PROSLICiNSANE,
++      TIMEoUTpOWERuP,
++      TIMEoUTpOWERdOWN,
++      POWERlEAK,
++      TIPoRrINGgROUNDsHORT,
++      POWERaLARMQ1,
++      POWERaLARMQ2,
++      POWERaLARMQ3,
++      POWERaLARMQ4,
++      POWERaLARMQ5,
++      OWERaLARMQ6,
++      CM_CAL_ERR
++};
++
++typedef struct
++{
++      UINT32 src_addr;
++      UINT32 dst_addr;
++      UINT32 llp;
++      UINT32 ctrl_size;
++}DMA_LLP_t;
++
++typedef struct {
++      unsigned int own ;
++      char  *tbuf;
++      //UINT32 *LinkAddrT;
++      DMA_LLP_t LLPT[LLP_SIZE];
++}DMA_Tx_t;
++
++typedef struct {
++      unsigned int own ;
++      char  *rbuf;
++      //UINT32 *LinkAddrR;
++      DMA_LLP_t LLPR[LLP_SIZE];
++}DMA_Rx_t;
++
++//typedef struct {
++//    //UINT32 init_stat;
++//    struct chipStruct chipData ; /* Represents a proslics state, cached information, and timers */
++//    struct phone_device p;
++//
++//
++//}SSP_SLIC;
++
++
++
++/* DMA Registers */
++#define       DMA_INT                                 0x00000000
++#define       DMA_INT_TC                              0x00000004
++#define       DMA_CFG                                 0x00000024
++#define       DMA_INT_TC_CLR                          0x00000008
++#define       DMA_TC                                          0x00000014
++#define       DMA_CSR                                         0x00000024
++#define       DMA_SYNC                                        0x00000028
++
++#define       DMA_CH2_CSR                             0x00000140
++#define       DMA_CH2_CFG                             0x00000144
++#define       DMA_CH2_SRC_ADDR                0x00000148
++#define       DMA_CH2_DST_ADDR                0x0000014c
++#define       DMA_CH2_LLP                             0x00000150
++#define       DMA_CH2_SIZE                            0x00000154
++
++#define       DMA_CH3_CSR                             0x00000160
++#define       DMA_CH3_CFG                             0x00000164
++#define       DMA_CH3_SRC_ADDR                0x00000168
++#define       DMA_CH3_DST_ADDR                0x0000016c
++#define       DMA_CH3_LLP                             0x00000170
++#define       DMA_CH3_SIZE                            0x00000174
++
++#define    SSP_DEVICE_ID                      0x00
++#define    SSP_CTRL_STATUS                    0x04
++#define          SSP_FRAME_CTRL           0x08
++#define    SSP_BAUD_RATE            0x0c
++#define    SSP_FRAME_CTRL2          0x10
++#define    SSP_FIFO_CTRL            0x14
++#define    SSP_TX_SLOT_VALID0       0x18
++#define    SSP_TX_SLOT_VALID1       0x1c
++#define    SSP_TX_SLOT_VALID2       0x20
++#define    SSP_TX_SLOT_VALID3       0x24
++#define    SSP_RX_SLOT_VALID0       0x28
++#define    SSP_RX_SLOT_VALID1       0x2c
++#define    SSP_RX_SLOT_VALID2       0x30
++#define    SSP_RX_SLOT_VALID3       0x34
++#define    SSP_SLOT_SIZE0           0x38
++#define    SSP_SLOT_SIZE1           0x3c
++#define    SSP_SLOT_SIZE2           0x40
++#define    SSP_SLOT_SIZE3           0x44
++#define    SSP_READ_PORT            0x48
++#define    SSP_WRITE_PORT           0x4c
++
++
++void printFreq_Revision(int num);
++void SLIC_SPI_write(int num, UINT8 ,UINT8);
++UINT8 SLIC_SPI_read(int num, UINT8);
++void SLIC_SPI_write_bit(char);
++void SLIC_SPI_ind_write(int num, UINT8, UINT16);
++UINT16 SLIC_SPI_ind_read(int num, UINT8);
++void SLIC_SPI_CS_enable(UINT8);
++unsigned int SLIC_SPI_read_bit(void);
++void SLIC_SPI_pre_st(void);
++UINT32 ssp_init(void);
++UINT16 SLIC_SPI_get_identifier(int num);
++int selfTest(int num);
++void exception (int num, enum exceptions e);
++int SLIC_init(int num);
++UINT8 version(int num);
++UINT8 chipType (int num);
++void SLIC_init_ind_reg_set(int num);
++UINT8 powerUp(int num);
++UINT8 powerLeakTest(int num);
++void SLIC_init_reg_set(int num);
++int calibrate(int num);
++void goActive(int num);
++void clearInterrupts(int num);
++void setState(int num, int);
++UINT8 loopStatus(int num);
++int verifyIndirectRegisters(int num);
++int verifyIndirectReg(int num, UINT8 , UINT16);
++void sendProSLICID(int num);
++void disableOscillators(int num);
++UINT8 checkSum(int num, char * string );
++void fskInitialization (int num);
++void fskByte(int num, UINT8 c);
++void waitForInterrupt (int num);
++//void findNumber(void);
++UINT8 dtmfAction(int num);
++UINT8 digit(int num);
++void interrupt_init(void);
++//void gemini_slic_isr (int );
++int groundShort(int num);
++void clearAlarmBits(int num);
++void stopRinging(int num);
++void activateRinging(int num);
++void initializeLoopDebounceReg(int num);
++void busyJapan(int num) ;
++void ringBackJapan(int num) ;
++void stateMachine(int num);
++
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/hardware.h
+@@ -0,0 +1,47 @@
++/*
++ *  linux/include/asm-arm/arch-epxa10/hardware.h
++ *
++ *  This file contains the hardware definitions of the Integrator.
++ *
++ *  Copyright (C) 1999 ARM Limited.
++ *  Copyright (C) 2001 Altera Corporation
++ *
++ * 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 program is distributed in the hope that 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
++ */
++#ifndef __ASM_ARCH_HARDWARE_H
++#define __ASM_ARCH_HARDWARE_H
++
++#include <asm/arch/platform.h>
++
++#define pcibios_assign_all_busses()   1
++
++/*
++ * Where in virtual memory the IO devices (timers, system controllers
++ * and so on)
++ *
++ * macro to get at IO space when running virtually
++*/
++
++#define IO_ADDRESS(x)      (((x&0xfff00000)>>4)|(x & 0x000fffff)|0xF0000000)
++#define FLASH_VBASE         0xFE000000
++#define FLASH_SIZE 0x1000000// 8M
++#define FLASH_START         SL2312_FLASH_BASE
++#define FLASH_VADDR(x)      ((x & 0x00ffffff)|0xFE000000)       // flash virtual address
++
++#define PCIBIOS_MIN_IO                                        0x100           // 0x000-0x100 AHB reg and PCI config, data
++#define PCIBIOS_MIN_MEM                                       0
++
++#endif
++
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/int_ctrl.h
+@@ -0,0 +1,171 @@
++/*
++ *
++ *  This file contains the register definitions for the Excalibur
++ *  Timer TIMER00.
++ *
++ *  Copyright (C) 2001 Altera Corporation
++ *
++ * 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 program is distributed in the hope that 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
++ */
++
++#ifndef __INT_CTRL_H
++#define __INT_CTRL_H
++
++#define PCI_IRQ_OFFSET                          64    /* PCI start IRQ number */
++#define FIQ_OFFSET                32
++
++#define IRQ_SOURCE(base_addr)   (INT_CTRL_TYPE(base_addr  + 0x00))
++#define IRQ_MASK(base_addr)     (INT_CTRL_TYPE (base_addr  + 0x04 ))
++#define IRQ_CLEAR(base_addr)    (INT_CTRL_TYPE (base_addr  + 0x08 ))
++#define IRQ_TMODE(base_addr)    (INT_CTRL_TYPE (base_addr  + 0x0C ))
++#define IRQ_TLEVEL(base_addr)    (INT_CTRL_TYPE (base_addr  + 0x10 ))
++#define IRQ_STATUS(base_addr)   (INT_CTRL_TYPE (base_addr  + 0x14 ))
++#define FIQ_SOURCE(base_addr)   (INT_CTRL_TYPE (base_addr  + 0x20 ))
++#define FIQ_MASK(base_addr)     (INT_CTRL_TYPE (base_addr  + 0x24 ))
++#define FIQ_CLEAR(base_addr)    (INT_CTRL_TYPE (base_addr  + 0x28 ))
++#define FIQ_TMODE(base_addr)    (INT_CTRL_TYPE (base_addr  + 0x2C ))
++#define FIQ_LEVEL(base_addr)    (INT_CTRL_TYPE (base_addr  + 0x30 ))
++#define FIQ_STATUS(base_addr)   (INT_CTRL_TYPE (base_addr  + 0x34 ))
++
++#ifdef CONFIG_SL3516_ASIC
++#define       IRQ_SERIRQ0_OFFSET                      30
++#define       IRQ_PCID_OFFSET                         29
++#define       IRQ_PCIC_OFFSET                         28
++#define       IRQ_PCIB_OFFSET                         27
++#define IRQ_PWR_OFFSET                                        26
++#define IRQ_CIR_OFFSET                                                25
++#define       IRQ_GPIO2_OFFSET                        24
++#define       IRQ_GPIO1_OFFSET                        23
++#define       IRQ_GPIO_OFFSET                         22
++#define       IRQ_SSP_OFFSET                          21
++#define IRQ_LPC_OFFSET                      20
++#define IRQ_LCD_OFFSET                      19
++#define       IRQ_UART_OFFSET                         18
++#define       IRQ_RTC_OFFSET                                  17
++#define       IRQ_TIMER3_OFFSET                       16
++#define       IRQ_TIMER2_OFFSET                       15
++#define       IRQ_TIMER1_OFFSET                       14
++#define IRQ_FLASH_OFFSET                                      12
++#define       IRQ_USB1_OFFSET                         11
++#define IRQ_USB0_OFFSET                                               10
++#define       IRQ_DMA_OFFSET                          9
++#define       IRQ_PCI_OFFSET                          8
++#define       IRQ_IPSEC_OFFSET                        7
++#define       IRQ_RAID_OFFSET                     6
++#define       IRQ_IDE1_OFFSET                         5
++#define       IRQ_IDE0_OFFSET                         4
++#define       IRQ_WATCHDOG_OFFSET                 3
++#define       IRQ_GMAC1_OFFSET                    2
++#define IRQ_GMAC0_OFFSET                                      1
++#define       IRQ_CPU0_IP_IRQ_OFFSET              0
++
++#define       IRQ_SERIRQ0_MASK                        (1<<30)
++#define IRQ_PCID_MASK                                 (1<<29)
++#define IRQ_PCIC_MASK                                 (1<<28)
++#define IRQ_PCIB_MASK                                 (1<<27)
++#define IRQ_PWR_MASK                                  (1<<26)
++#define IRQ_CIR_MASK                                          (1<<25)
++#define       IRQ_GPIO2_MASK                          (1<<24)
++#define       IRQ_GPIO1_MASK                          (1<<23)
++#define       IRQ_GPIO_MASK                       (1<<22)
++#define       IRQ_SSP_MASK                        (1<<21)
++#define IRQ_LPC_MASK                        (1<<20)
++#define IRQ_LCD_MASK                        (1<<19)
++#define       IRQ_UART_MASK                       (1<<18)
++#define       IRQ_RTC_MASK                                (1<<17)
++#define       IRQ_TIMER3_MASK                     (1<<16)
++#define       IRQ_TIMER2_MASK                     (1<<15)
++#define       IRQ_TIMER1_MASK                     (1<<14)
++#define IRQ_FLASH_MASK                                            (1<<12)
++#define       IRQ_USB1_MASK                       (1<<11)
++#define IRQ_USB0_MASK                                     (1<<10)
++#define       IRQ_DMA_MASK                        (1<< 9)
++#define       IRQ_PCI_MASK                        (1<< 8)
++#define       IRQ_IPSEC_MASK                              (1<< 7)
++#define       IRQ_RAID_MASK                       (1<< 6)
++#define       IRQ_IDE1_MASK                       (1<< 5)
++#define       IRQ_IDE0_MASK                       (1<< 4)
++#define       IRQ_WATCHDOG_MASK                   (1<< 3)
++#define       IRQ_GMAC1_MASK                      (1<< 2)
++#define IRQ_GMAC0_MASK                                            (1<< 1)
++#define       IRQ_CPU0_IP_IRQ_MASK                (1<< 0)
++#else
++#define       IRQ_SERIRQ0_OFFSET                      30
++#define       IRQ_PCID_OFFSET                         29
++#define       IRQ_PCIC_OFFSET                         28
++#define       IRQ_PCIB_OFFSET                         27
++#define IRQ_PWR_OFFSET                                        26
++#define IRQ_CIR_OFFSET                                                25
++#define       IRQ_GPIO2_OFFSET                        24
++#define       IRQ_GPIO1_OFFSET                        23
++#define       IRQ_GPIO_OFFSET                         22
++#define       IRQ_SSP_OFFSET                          21
++#define IRQ_LPC_OFFSET                      20
++#define IRQ_LCD_OFFSET                      19
++#define       IRQ_UART_OFFSET                         18
++#define       IRQ_RTC_OFFSET                                  17
++#define       IRQ_TIMER3_OFFSET                       16
++#define       IRQ_TIMER2_OFFSET                       15
++#define       IRQ_TIMER1_OFFSET                       14
++#define IRQ_FLASH_OFFSET                                      12
++#define       IRQ_USB1_OFFSET                         11
++#define IRQ_USB0_OFFSET                                               10
++#define       IRQ_DMA_OFFSET                          9
++#define       IRQ_PCI_OFFSET                          8
++#define       IRQ_IPSEC_OFFSET                        7
++#define       IRQ_RAID_OFFSET                     6
++#define       IRQ_IDE1_OFFSET                         5
++#define       IRQ_IDE0_OFFSET                         4
++#define       IRQ_WATCHDOG_OFFSET                 3
++#define       IRQ_GMAC1_OFFSET                    2
++#define IRQ_GMAC0_OFFSET                                      1
++#define       IRQ_CPU0_IP_IRQ_OFFSET              0
++
++#define       IRQ_SERIRQ0_MASK                        (1<<30)
++#define IRQ_PCID_MASK                                 (1<<29)
++#define IRQ_PCIC_MASK                                 (1<<28)
++#define IRQ_PCIB_MASK                                 (1<<27)
++#define IRQ_PWR_MASK                                  (1<<26)
++#define IRQ_CIR_MASK                                          (1<<25)
++#define       IRQ_GPIO2_MASK                          (1<<24)
++#define       IRQ_GPIO1_MASK                          (1<<23)
++#define       IRQ_GPIO_MASK                       (1<<22)
++#define       IRQ_SSP_MASK                        (1<<21)
++#define IRQ_LPC_MASK                        (1<<20)
++#define IRQ_LCD_MASK                        (1<<19)
++#define       IRQ_UART_MASK                       (1<<18)
++#define       IRQ_RTC_MASK                                (1<<17)
++#define       IRQ_TIMER3_MASK                     (1<<16)
++#define       IRQ_TIMER2_MASK                     (1<<15)
++#define       IRQ_TIMER1_MASK                     (1<<14)
++#define IRQ_FLASH_MASK                                            (1<<12)
++#define       IRQ_USB1_MASK                       (1<<11)
++#define IRQ_USB0_MASK                                     (1<<10)
++#define       IRQ_DMA_MASK                        (1<< 9)
++#define       IRQ_PCI_MASK                        (1<< 8)
++#define       IRQ_IPSEC_MASK                              (1<< 7)
++#define       IRQ_RAID_MASK                       (1<< 6)
++#define       IRQ_IDE1_MASK                       (1<< 5)
++#define       IRQ_IDE0_MASK                       (1<< 4)
++#define       IRQ_WATCHDOG_MASK                   (1<< 3)
++#define       IRQ_GMAC1_MASK                      (1<< 2)
++#define IRQ_GMAC0_MASK                                            (1<< 1)
++#define       IRQ_CPU0_IP_IRQ_MASK                (1<< 0)
++#endif
++
++
++#endif /* __INT_CTRL_H */
++
++
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/io.h
+@@ -0,0 +1,50 @@
++/*
++ *  linux/include/asm-arm/arch-epxa10db/io.h
++ *
++ *  Copyright (C) 1999 ARM Limited
++ *
++ * 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 program is distributed in the hope that 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
++ */
++#ifndef __ASM_ARM_ARCH_IO_H
++#define __ASM_ARM_ARCH_IO_H
++
++#define IO_SPACE_LIMIT 0xffffffff
++
++
++/*
++ * Generic virtual read/write
++ */
++/*
++#define __arch_getw(a)                (*(volatile unsigned short *)(a))
++#define __arch_putw(v,a)      (*(volatile unsigned short *)(a) = (v))
++*/
++/*#define outsw   __arch_writesw
++#define outsl   __arch_writesl
++#define outsb   __arch_writesb
++#define insb    __arch_readsb
++#define insw    __arch_readsw
++#define insl    __arch_readsl*/
++
++#define __io(a)                       (a)
++#define __mem_pci(a)            (a)
++/*
++#define __arch_getw(a)                        (*(volatile unsigned short  *)(a))
++#define __arch_putw(v,a)              (*(volatile unsigned short *)(a) = (v))
++*/
++#define iomem_valid_addr(off,size) (1)
++#define iomem_to_phys(off) (off)
++
++
++#endif
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/ipi.h
+@@ -0,0 +1,189 @@
++/*
++ *  linux/include/asm-arm/arch-sl2312/system.h
++ *
++ *  Copyright (C) 1999 ARM Limited
++ *  Copyright (C) 2000 Deep Blue Solutions Ltd
++ *  Copyright (C) 2001 Altera Corporation
++ *
++ * 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 program is distributed in the hope that 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
++ */
++#ifndef __ASM_ARCH_IPI_H
++#define __ASM_ARCH_IPI_H
++#include <asm/io.h>
++
++//#define spin_lock(x)        spin_lock_dt(x)
++//#define spin_unlock(x)      spin_unlock_dt(x)
++
++#define SWAP_OFFSET                                                   0x400000
++#define SWAP_SIZE                                                     0x400000
++
++#define SHARE_MEM_ADDR                                                0x2000000
++#define SHARE_MEM_SIZE                                                1024*1024
++
++
++//--> Add by jason for IPI testing
++// memory layout for maste & slave bin
++#define MASTERTEXT      0x8000
++#define SLAVETEXT             0x108000
++#define SHARESIZE             0x4000
++#define SHAREADDR             SHARE_MEM_ADDR // starting 8M
++
++// CPU1 reset release
++#define GLOBAL_BASE           IO_ADDRESS(0x40000000)
++#define GLOBAL_SOFTRESET      (GLOBAL_BASE + 0x0C)
++#define CPU1_RESET_BIT_MASK     0x40000000
++
++// IPI , need to redefine the folliwing,  bug
++#define CPU0_STATUS                   (GLOBAL_BASE + 0x0038)
++#define CPU1_STATUS                   (GLOBAL_BASE + 0x003C)
++#define CPU_IPI_BIT_MASK    0x80000000
++
++/* Your basic SMP spinlocks, allowing only a single CPU anywhere
++*/
++typedef struct {
++       volatile unsigned int lock;
++} spinlock_dt;
++
++
++#define         MASTER_BIT      0x01
++#define         SLAVE_BIT       0x02
++#define         HEART_BIT       0x04
++#define         IPI0_IRQ_BIT    0x08
++#define         IPI0_FIQ_BIT    0x10
++#define         IPI1_IRQ_BIT    0x20
++#define         IPI1_FIQ_BIT    0x40
++
++#define IRQ     0
++#define FIQ     1
++#define DONE    0xff
++
++#define         CPU0            0x0
++#define         CPU1            0x1
++
++#define         MAXCHAR         128*1024
++typedef struct  {
++       int flag;
++       int uart_flag;
++       int cnt;
++       spinlock_dt lk;
++       char message[MAXCHAR];
++}s_mailbox;
++
++// JScale proj definition
++typedef struct {
++      u16             type;                           // message Type
++      u16             length;                         // message length, including message header
++} IPC_MSG_HDR_T;
++
++typedef struct{
++      IPC_MSG_HDR_T   hdr;
++      u32                             input_location;
++      u32                             input_size;
++      u32                             output_location;
++      u16                     ScaledImageWidth;
++      u16                     ScaledImageHeight;
++      u8                      ScaledImageQuality;
++      u8                      MaintainResultionRatio;
++      u8                      TwoStepScaling;
++      u8                      InputFormat;
++      u8                              verbose;
++      u8                              reserved[3];
++} JSCALE_REQ_T;
++
++typedef struct{
++      IPC_MSG_HDR_T   hdr;
++      u32                             status;
++      u32                             code;
++      u32                             output_size;
++} JSCALE_RSP_T;
++
++#define IPC_JSCALE_REQ_MSG                    0       // JScale request from CPU-0 to CPU-1
++#define IPC_JSCALE_RSP_MSG                    1       // JScale response from CPU-1 to CPU-0
++
++enum {
++      JSCALE_STATUS_OK = 0,
++      JSCALE_UNKNOWN_MSG_TYPE,
++      JSCALE_FAILED_FILE_SIZE,
++      JSCALE_FAILED_MALLOC,
++      JSCALE_FAILED_FORMAT,
++      JSCALE_DECODE_ERROR,
++      JSCALE_BUSY,
++};
++// <-- JScale
++
++#define GEMINI_IPI_IOCTL_BASE 'Z'
++#define GEMINI_IPI_JSCALE_REQ         _IOW (GEMINI_IPI_IOCTL_BASE,0,JSCALE_REQ_T)
++#define GEMINI_IPI_JSCALE_STAT                _IOR (GEMINI_IPI_IOCTL_BASE,1,JSCALE_RSP_T)
++
++
++/*
++* Simple spin lock operations.
++*
++*/
++
++#define spin_is_locked_dt(x)((x)->lock != 0)
++
++static inline int test_and_set_dt(spinlock_dt *lock)
++{
++unsigned long tmp;
++__asm__ __volatile__(
++"swp     %0, %2, [%1]\n"
++: "=&r" (tmp)
++: "r" (&lock->lock), "r" (1)
++: "cc", "memory");
++
++return tmp;
++}
++
++static inline void spin_lock_dt(spinlock_dt *lock)
++{
++
++unsigned long tmp;
++__asm__ __volatile__(
++"1:     ldr   %0, [%1]\n"
++"teq     %0, #0\n"
++"swpeq   %0, %2, [%1]\n"
++"       teqeq   %0, #0\n"
++"       bne     1b"
++       : "=&r" (tmp)
++       : "r" (&lock->lock), "r" (1)
++       : "cc", "memory");
++}
++
++static inline void spin_unlock_dt(spinlock_dt *lock)
++{
++       __asm__ __volatile__(
++"       str     %1, [%0]"
++       :
++       : "r" (&lock->lock), "r" (0)
++       : "cc", "memory");
++}
++
++static inline int getcpuid(void)
++{
++       int cpuid;
++
++      __asm__(
++"mrc p8, 0, r0, c0, c0, 0\n"
++"mov %0, r0"
++       :"=r"(cpuid)
++       :
++       :"r0");
++       return (cpuid & 0x07);
++}
++
++
++
++#endif
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/irq.h
+@@ -0,0 +1,23 @@
++/*
++ *  linux/include/asm-arm/arch-sl2312/irq.h
++ *
++ *  Copyright (C) 1999 ARM Limited
++ *
++ * 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 program is distributed in the hope that 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
++ */
++
++ // Since we have PCI interrupt which the interrupt line is pseudo
++ // we need do some fixup
++int fixup_irq(int irq);
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/irqs.h
+@@ -0,0 +1,102 @@
++/*
++ *  linux/include/asm-arm/arch-camelot/irqs.h
++ *
++ *  Copyright (C) 2001 Altera Corporation
++ *
++ * 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 program is distributed in the hope that 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
++ */
++
++/* Use the Excalibur chip definitions */
++#define INT_CTRL_TYPE
++#include "asm/arch/int_ctrl.h"
++
++#ifdef CONFIG_SL3516_ASIC
++#define       IRQ_SERIRQ_MAX                                  31
++#define       IRQ_SERIRQ1                                             31
++#define       IRQ_SERIRQ0                     30
++#define       IRQ_PCID                                29
++#define       IRQ_PCIC                        28
++#define       IRQ_PCIB                                27
++#define IRQ_PWR                                                       26
++#define IRQ_CIR                                                       25
++#define       IRQ_GPIO2                       24
++#define       IRQ_GPIO1                       23
++#define       IRQ_GPIO                                22
++#define       IRQ_SSP                         21
++#define IRQ_LPC                         20
++#define IRQ_LCD                         19
++#define       IRQ_UART                                18
++#define       IRQ_RTC                                 17
++#define       IRQ_TIMER3                      16
++#define       IRQ_TIMER2                      15
++#define       IRQ_TIMER1                      14
++#define IRQ_FLASH                                             12
++#define       IRQ_USB1                        11
++#define IRQ_USB0                                              10
++#define       IRQ_DMA                         9
++#define       IRQ_PCI                                 8
++#define       IRQ_IPSEC                               7
++#define       IRQ_RAID                        6
++#define       IRQ_IDE1                        5
++#define       IRQ_IDE0                                4
++#define       IRQ_WATCHDOG                    3
++#define       IRQ_GMAC1                       2
++#define IRQ_GMAC0                                             1
++#define       IRQ_CPU0_IP_IRQ                 0
++#else
++#define       IRQ_SERIRQ_MAX                                  31
++#define       IRQ_SERIRQ1                                             31
++#define       IRQ_SERIRQ0                     30
++#define       IRQ_PCID                                29
++#define       IRQ_PCIC                        28
++#define       IRQ_PCIB                                27
++#define IRQ_PWR                                                       26
++#define IRQ_CIR                                                       25
++#define       IRQ_GPIO2                       24
++#define       IRQ_GPIO1                       23
++#define       IRQ_GPIO                                22
++#define       IRQ_SSP                         21
++#define IRQ_LPC                         20
++#define IRQ_LCD                         19
++#define       IRQ_UART                                18
++#define       IRQ_RTC                                 17
++#define       IRQ_TIMER3                      16
++#define       IRQ_TIMER2                      15
++#define       IRQ_TIMER1                      14
++#define IRQ_FLASH                                             12
++#define       IRQ_USB1                        11
++#define IRQ_USB0                                              10
++#define       IRQ_DMA                         9
++#define       IRQ_PCI                                 8
++#define       IRQ_IPSEC                               7
++#define       IRQ_RAID                        6
++#define       IRQ_IDE1                        5
++#define       IRQ_IDE0                                4
++#define       IRQ_WATCHDOG                    3
++#define       IRQ_GMAC1                       2
++#define IRQ_GMAC0                                             1
++#endif
++
++#define ARCH_TIMER_IRQ                               IRQ_TIMER2   /* for MV 4.0 */
++
++#define IRQ_PCI_INTA                                 PCI_IRQ_OFFSET + 0
++#define IRQ_PCI_INTB                                 PCI_IRQ_OFFSET + 1
++#define IRQ_PCI_INTC                                 PCI_IRQ_OFFSET + 2
++#define IRQ_PCI_INTD                                 PCI_IRQ_OFFSET + 3
++
++#define NR_IRQS                           (IRQ_PCI_INTD + 4)
++
++
++
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/it8712.h
+@@ -0,0 +1,24 @@
++
++#ifndef __IT8712_H__
++#define __IT8712_H__
++
++#include "asm/arch/sl2312.h"
++
++#define IT8712_IO_BASE                        SL2312_LPC_IO_BASE
++// Device LDN
++#define LDN_SERIAL1                           0x01
++#define LDN_SERIAL2                           0x02
++#define LDN_PARALLEL                  0x03
++#define LDN_KEYBOARD                  0x05
++#define LDN_MOUSE                             0x06
++#define LDN_GPIO                              0x07
++
++#define IT8712_UART1_PORT             0x3F8
++#define IT8712_UART2_PORT             0x2F8
++
++#define IT8712_GPIO_BASE              0x800   // 0x800-0x804 for GPIO set1-set5
++
++void LPCSetConfig(char LdnNumber, char Index, char data);
++char LPCGetConfig(char LdnNumber, char Index);
++
++#endif
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/memory.h
+@@ -0,0 +1,38 @@
++/*
++ *  linux/include/asm-arm/arch-sl2312/memory.h
++ *
++ *  Copyright (C) 2001 Altera Corporation
++ *
++ * 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 program is distributed in the hope that 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
++ */
++#ifndef __ASM_ARCH_MMU_H
++#define __ASM_ARCH_MMU_H
++
++/*
++ * Physical DRAM offset.
++ */
++#define PHYS_OFFSET   UL(0x00000000)
++
++/*
++ * Virtual view <-> DMA view memory address translations
++ * virt_to_bus: Used to translate the virtual address to an
++ *              address suitable to be passed to set_dma_addr
++ * bus_to_virt: Used to convert an address for DMA operations
++ *              to an address that the kernel can use.
++ */
++#define __virt_to_bus(x)      (x - PAGE_OFFSET + /*SDRAM_BASE*/0)
++#define __bus_to_virt(x)      (x - /*SDRAM_BASE*/0 + PAGE_OFFSET)
++
++#endif
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/param.h
+@@ -0,0 +1,20 @@
++/*
++ *  linux/include/asm-arm/arch-epxa10db/param.h
++ *
++ *  Copyright (C) 1999 ARM Limited
++ *
++ * 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 program is distributed in the hope that 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
++ */
++
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/pci.h
+@@ -0,0 +1,18 @@
++
++#ifndef __SL2312_PCI_H__
++#define __SL2312_PCI_H__
++
++#define SL2312_PCI_PMC                                0x40
++#define SL2312_PCI_PMCSR                      0x44
++#define SL2312_PCI_CTRL1                      0x48
++#define SL2312_PCI_CTRL2                      0x4c
++#define SL2312_PCI_MEM1_BASE_SIZE     0x50
++#define SL2312_PCI_MEM2_BASE_SIZE     0x54
++#define SL2312_PCI_MEM3_BASE_SIZE     0x58
++
++
++void sl2312_pci_mask_irq(unsigned int irq);
++void sl2312_pci_unmask_irq(unsigned int irq);
++int sl2312_pci_get_int_src(void);
++
++#endif
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/platform.h
+@@ -0,0 +1,7 @@
++#ifndef PLATFORM_H
++#define PLATFORM_H
++#include "sl2312.h"
++
++#define MAXIRQNUM 68
++#endif
++
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/preempt.h
+@@ -0,0 +1,63 @@
++/*
++ * include/asm-arm/arch-sl2312/preempt.h
++ *
++ * Timing support for preempt-stats, kfi, ilatency patches
++ *
++ * Author: dsingleton <dsingleton@mvista.com>
++ *
++ * 2001-2004 (c) MontaVista Software, Inc. This file is licensed under
++ * the terms of the GNU General Public License version 2. This program
++ * is licensed "as is" without any warranty of any kind, whether express
++ * or implied.
++ */
++
++#ifndef _ASM_ARCH_PREEMT_H
++#define _ASM_ARCH_PREEMT_H
++
++#include <asm/arch/hardware.h>
++#include <asm/arch/sl2312.h>
++
++static inline unsigned long clock_diff(unsigned long start, unsigned long stop)
++{
++        return (start - stop);
++}
++
++static inline unsigned int readclock(void)
++{
++      unsigned int    x;
++
++      x = readl(IO_ADDRESS(SL2312_TIMER2_BASE));
++      return x;
++}
++
++static inline unsigned __ticks_per_usec(void)
++{
++#ifdef CONFIG_SL3516_ASIC
++      unsigned int ahb_clock_rate_base=130;  /* unit = MHz*/
++      unsigned int reg_v=0;
++      unsigned int ticks_usec;
++
++      reg_v = readl(IO_ADDRESS((SL2312_GLOBAL_BASE+4)));
++      reg_v >>=15;
++      ticks_usec = (ahb_clock_rate_base + (reg_v & 0x07)*10)>>2;
++
++#else
++      unsigned int ticks_usec=20;
++#endif
++
++    return ticks_usec;
++}
++
++/*
++ * timer 1 runs @ 6Mhz  6 ticks = 1 microsecond
++ * and is configed as a count down timer.
++ */
++#define TICKS_PER_USEC                    __ticks_per_usec()
++#define ARCH_PREDEFINES_TICKS_PER_USEC
++
++#define clock_to_usecs(x)         ((x) / TICKS_PER_USEC)
++
++#define INTERRUPTS_ENABLED(x)   (!(x & PSR_I_BIT))
++
++#endif
++
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/sl2312.h
+@@ -0,0 +1,254 @@
++#ifndef __sl2312_h
++#define __sl2312_h
++
++/****************************************************************************
++ * Copyright  Storlink Corp 2002-2003.  All rights reserved.                *
++ *--------------------------------------------------------------------------*
++ * Name:board.s                                                             *
++ * Description:  SL231x specfic define                                      *
++ * Author: Plus Chen                                                        *
++ * Version: 0.9 Create
++ ****************************************************************************/
++
++/*
++  CPE address map;
++
++               +====================================================
++    0x00000000 | FLASH
++    0x0FFFFFFF |
++               |====================================================
++    0x10000000 | SDRAM
++    0x1FFFFFFF |
++               |====================================================
++    0x20000000 | Global Registers        0x20000000-0x20FFFFFF
++               | EMAC and DMA            0x21000000-0x21FFFFFF
++               | UART Module             0x22000000-0x22FFFFFF
++               | Timer Module            0x23000000-0x23FFFFFF
++               | Interrupt Module        0x24000000-0x24FFFFFF
++               | RTC Module              0x25000000-0x25FFFFFF
++               | LPC Host Controller     0x26000000-0x26FFFFFF
++               | LPC Peripherial IO      0x27000000-0x27FFFFFF
++               | WatchDog Timer          0x28000000-0x28FFFFFF
++    0x2FFFFFFF | Reserved                0x29000000-0x29FFFFFF
++               |=====================================================
++    0x30000000 | PCI IO, Configuration Registers
++    0x3FFFFFFF |
++               |=====================================================
++    0x40000000 | PCI Memory
++    0x4FFFFFFF |
++               |=====================================================
++    0x50000000 | Ethernet MAC and DMA    0x50000000-0x50FFFFFF
++               | Security and DMA        0x51000000-0x51FFFFFF
++               | IDE Channel 0 Register  0x52000000-0x527FFFFF
++               | IDE Channel 1 Register  0x52800000-0x52FFFFFF
++               | USB Register            0x53000000-0x53FFFFFF
++               | Flash Controller        0x54000000-0x54FFFFFF
++               | DRAM Controller         0x55000000-0x55FFFFFF
++    0x5FFFFFFF | Reserved                0x56000000-0x5FFFFFFF
++               |=====================================================
++    0x60000000 | Reserved
++    0x6FFFFFFF |
++               |=====================================================
++    0x70000000 | FLASH shadow Memory
++    0x7FFFFFFF |
++               |=====================================================
++    0x80000000 | Big Endian of memory    0x00000000-0x7FFFFFFF
++    0xFFFFFFFF |
++               +=====================================================
++*/
++
++
++
++/*-------------------------------------------------------------------------------
++ Memory Map definitions
++-------------------------------------------------------------------------------- */
++#define TEST          1
++#if 0
++
++static inline int GETCPUID()
++{
++       int cpuid;
++      __asm__(
++"mrc p8, 0, r0, c0, c0, 0\n"
++"mov %0, r0"
++       :"=r"(cpuid)
++       :
++       :"r0");
++       return (cpuid & 0x07);
++}
++#endif
++#define SL2312_SRAM_BASE                0x70000000       //  SRAM base after remap
++#define SL2312_DRAM_BASE                0x00000000       //  DRAM base after remap
++#define SL2312_RAM_BASE                 0x10000000       //  RAM code base before remap
++#define SL2312_FLASH_BASE                 0x30000000
++#define SL2312_ROM_BASE                 0x30000000
++#define SL2312_GLOBAL_BASE              0x40000000
++#define SL2312_WAQTCHDOG_BASE           0x41000000
++#define SL2312_UART_BASE                0x42000000
++#define SL2312_TIMER_BASE               0x43000000
++#define SL2312_LCD_BASE                 0x44000000
++#define SL2312_RTC_BASE                 0x45000000
++#define SL2312_SATA_BASE                0x46000000
++#define SL2312_LPC_HOST_BASE            0x47000000
++#define SL2312_LPC_IO_BASE              0x47800000
++// #define SL2312_INTERRUPT_BASE           0x48000000
++#define SL2312_INTERRUPT0_BASE          0x48000000
++#define SL2312_INTERRUPT1_BASE          0x49000000
++//#define SL2312_INTERRUPT_BASE               ((getcpuid()==0)?SL2312_INTERRUPT0_BASE:SL2312_INTERRUPT1_BASE)
++#define SL2312_INTERRUPT_BASE             0x48000000
++#define SL2312_SSP_CTRL_BASE            0x4A000000
++#define SL2312_POWER_CTRL_BASE          0x4B000000
++#define SL2312_CIR_BASE                 0x4C000000
++#define SL2312_GPIO_BASE                0x4D000000
++#define SL2312_GPIO_BASE1               0x4E000000
++#define SL2312_GPIO_BASE2               0x4F000000
++#define SL2312_PCI_IO_BASE              0x50000000
++#define SL2312_PCI_MEM_BASE             0x58000000
++#ifdef  CONFIG_NET_SL351X
++#define SL2312_TOE_BASE                 0x60000000
++#define SL2312_GMAC0_BASE               0x6000A000
++#define SL2312_GMAC1_BASE               0x6000E000
++#else
++#define SL2312_GMAC0_BASE               0x60000000
++#define SL2312_GMAC1_BASE               0x61000000
++#endif
++#define SL2312_SECURITY_BASE            0x62000000
++#define SL2312_IDE0_BASE                0x63000000
++#define SL2312_IDE1_BASE                      0x63400000
++#define SL2312_RAID_BASE                0x64000000
++#define SL2312_FLASH_CTRL_BASE          0x65000000
++#define SL2312_DRAM_CTRL_BASE           0x66000000
++#define SL2312_GENERAL_DMA_BASE         0x67000000
++#define SL2312_USB_BASE                 0x68000000
++#define SL2312_USB0_BASE                0x68000000
++#define SL2312_USB1_BASE                0x69000000
++#define SL2312_FLASH_SHADOW             0x30000000
++#define SL2312_BIG_ENDIAN_BASE                        0x80000000
++
++#ifdef CONFIG_GEMINI_IPI
++#define CPU_1_MEM_BASE                        0x4000000                               // 64 MB
++#define CPU_1_DATA_OFFSET             0x4000000-0x300000              // Offset 61 MB
++#endif
++
++#define SL2312_TIMER1_BASE              SL2312_TIMER_BASE
++#define SL2312_TIMER2_BASE              (SL2312_TIMER_BASE + 0x10)
++#define SL2312_TIMER3_BASE              (SL2312_TIMER_BASE + 0x20)
++
++#define SL2312_PCI_DMA_MEM1_BASE              0x00000000
++#define SL2312_PCI_DMA_MEM2_BASE              0x00000000
++#define SL2312_PCI_DMA_MEM3_BASE              0x00000000
++#define SL2312_PCI_DMA_MEM1_SIZE              7
++#define SL2312_PCI_DMA_MEM2_SIZE              6
++#define SL2312_PCI_DMA_MEM3_SIZE              6
++
++/*-------------------------------------------------------------------------------
++ Global Module
++---------------------------------------------------------------------------------*/
++#define GLOBAL_ID                       0x00
++#define GLOBAL_CHIP_ID                  0x002311
++#define GLOBAL_CHIP_REV                 0xA0
++#define GLOBAL_STATUS                   0x04
++#define GLOBAL_CONTROL                  0x1C
++#define GLOBAL_REMAP_BIT                0x01
++#define GLOBAL_RESET_REG              0x0C
++#define GLOBAL_MISC_REG                                       0x30
++#define PFLASH_SHARE_BIT                              0x02
++
++#define GLOBAL_RESET          (1<<31)
++#define RESET_CPU1                    (1<<30)
++#define RESET_SATA1                   (1<<27)
++#define RESET_SATA0                   (1<<26)
++#define RESET_CIR                     (1<<25)
++#define RESET_EXT_DEV         (1<<24)
++#define RESET_WD                      (1<<23)
++#define RESET_GPIO2                   (1<<22)
++#define RESET_GPIO1                   (1<<21)
++#define RESET_GPIO0                   (1<<20)
++#define RESET_SSP                     (1<<19)
++#define RESET_UART                    (1<<18)
++#define RESET_TIMER                   (1<<17)
++#define RESET_RTC                     (1<<16)
++#define RESET_INT0                    (1<<15)
++#define RESET_INT1                    (1<<14)
++#define RESET_LCD                     (1<<13)
++#define RESET_LPC                     (1<<12)
++#define RESET_APB                     (1<<11)
++#define RESET_DMA                     (1<<10)
++#define RESET_USB1                    (1<<9 )
++#define RESET_USB0                    (1<<8 )
++#define RESET_PCI                     (1<<7 )
++#define RESET_GMAC1                   (1<<6 )
++#define RESET_GMAC0                   (1<<5 )
++#define RESET_IPSEC                   (1<<4 )
++#define RESET_RAID                    (1<<3 )
++#define RESET_IDE                     (1<<2 )
++#define RESET_FLASH                   (1<<1 )
++#define RESET_DRAM                    (1<<0 )
++
++
++
++
++
++
++
++
++/*-------------------------------------------------------------------------------
++ DRAM Module
++---------------------------------------------------------------------------------*/
++#define DRAM_SIZE_32M                   0x2000000
++#define DRAM_SIZE_64M                   0x4000000
++#define DRAM_SIZE_128M                  0x8000000
++
++#define DRAM_SIZE                       DRAM_SIZE_128M
++
++#define DRAM_SDRMR                      0x00
++#define SDRMR_DISABLE_DLL               0x80010000
++
++/*------------------------------------------------------------------------------
++ Share Pin Flag
++--------------------------------------------------------------------------------*/
++#ifdef CONFIG_SL2312_SHARE_PIN
++#define FLASH_SHARE_BIT                    0
++#define UART_SHARE_BIT                     1
++#define EMAC_SHARE_BIT                     2
++#define IDE_RW_SHARE_BIT                   3
++#define IDE_CMD_SHARE_BIT                  4
++#endif
++/*-------------------------------------------------------------------------------
++ System Clock
++---------------------------------------------------------------------------------*/
++
++#ifndef SYS_CLK
++#ifdef CONFIG_SL3516_ASIC
++#define SYS_CLK                         150000000
++#else
++#define SYS_CLK                       20000000
++#endif
++#endif
++
++#define AHB_CLK                       SYS_CLK
++#define MAX_TIMER                     3
++#ifndef APB_CLK
++#ifdef CONFIG_SL3516_ASIC
++#define APB_CLK                       (SYS_CLK / 6)
++#else
++#define APB_CLK                               SYS_CLK
++#endif
++#endif
++
++#ifdef CONFIG_SL3516_ASIC
++#define UART_CLK                        48000000      // 30000000 for GeminiA chip, else 48000000
++#else
++#define UART_CLK                      48000000
++#endif
++
++#define SL2312_BAUD_115200              (UART_CLK / 1843200)
++#define SL2312_BAUD_57600               (UART_CLK / 921600)
++#define SL2312_BAUD_38400                     (UART_CLK / 614400)
++#define SL2312_BAUD_19200               (UART_CLK / 307200)
++#define SL2312_BAUD_14400               (UART_CLK / 230400)
++#define SL2312_BAUD_9600                (UART_CLK / 153600)
++
++#endif
++
++
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/sl2312_ipsec.h
+@@ -0,0 +1,684 @@
++#ifndef _IPSEC_DIAG_H
++#define _IPSEC_DIAG_H
++
++#include <linux/scatterlist.h>
++
++#define BIG_ENDIAN    0
++
++#define IPSEC_TEST    0
++#define ZERO_COPY     1
++
++#define UINT unsigned int
++#define BYTE unsigned char
++
++/* define cipher algorithm */
++enum CIPHER {
++      DES_ECB_E       =20,
++      TDES_ECB_E      =21,
++      AES_ECB_E       =22,
++      DES_CBC_E       =24,
++      TDES_CBC_E      =25,
++      AES_CBC_E       =26,
++
++      DES_ECB_D       =27,
++      TDES_ECB_D      =28,
++      AES_ECB_D       =29,
++      DES_CBC_D       =31,
++      TDES_CBC_D      =32,
++      AES_CBC_D       =33,
++      A_SHA1      =12,
++      A_HMAC_SHA1 =13,
++      A_MD5       =14,
++      A_HMAC_MD5  =15,
++};
++
++// opMode
++#define CIPHER_ENC    0x1
++#define CIPHER_DEC    0x3
++#define AUTH          0x4
++#define ENC_AUTH      0x5
++#define AUTH_DEC      0x7
++
++// cipherAlgorithm
++#define CBC_DES       0x4
++#define CBC_3DES      0x5
++#define CBC_AES       0x6
++#define ECB_DES       0x0
++#define ECB_3DES      0x1
++#define ECB_AES       0x2
++
++// authAlgorithm
++#define SHA1         0
++#define MD5          1
++#define HMAC_SHA1    2
++#define HMAC_MD5     3
++#define FCS          4
++
++//cipher mode
++#define ECB          0
++#define CBC          1
++
++// authMode
++#define AUTH_APPEND  0
++#define AUTH_CHKVAL  1
++
++/******************************************************/
++/*          the offset of IPSEC DMA register          */
++/******************************************************/
++enum IPSEC_DMA_REGISTER {
++      IPSEC_DMA_DEVICE_ID             = 0xff00,
++      IPSEC_DMA_STATUS                = 0xff04,
++      IPSEC_TXDMA_CTRL                = 0xff08,
++      IPSEC_TXDMA_FIRST_DESC  = 0xff0c,
++      IPSEC_TXDMA_CURR_DESC   = 0xff10,
++      IPSEC_RXDMA_CTRL                = 0xff14,
++      IPSEC_RXDMA_FIRST_DESC  = 0xff18,
++      IPSEC_RXDMA_CURR_DESC   = 0xff1c,
++      IPSEC_TXDMA_BUF_ADDR    = 0xff28,
++      IPSEC_RXDMA_BUF_ADDR    = 0xff38,
++      IPSEC_RXDMA_BUF_SIZE            = 0xff30,
++};
++
++#define IPSEC_STATUS_REG    0x00a8
++#define IPSEC_RAND_NUM_REG  0x00ac
++
++/******************************************************/
++/* the field definition of IPSEC DMA Module Register  */
++/******************************************************/
++typedef union
++{
++      unsigned int bits32;
++      struct bit2_ff00
++      {
++#if (BIG_ENDIAN==1)
++              unsigned int p_wclk             :  4;   /* DMA_APB write clock period */
++              unsigned int p_rclk             :  4;   /* DMA_APB read clock period */
++              unsigned int                            :  8;
++              unsigned int device_id          : 12;
++              unsigned int revision_id        :  4;
++#else
++              unsigned int revision_id        :  4;
++              unsigned int device_id          : 12;
++              unsigned int                            :  8;
++              unsigned int p_rclk             :  4;   /* DMA_APB read clock period */
++              unsigned int p_wclk             :  4;   /* DMA_APB write clock period */
++#endif
++      } bits;
++} IPSEC_DMA_DEVICE_ID_T;
++
++typedef union
++{
++      unsigned int bits32;
++      struct bit2_ff04
++      {
++#if (BIG_ENDIAN==1)
++              unsigned int ts_finish          :  1;   /* finished tx interrupt */
++              unsigned int ts_derr            :  1;   /* AHB Bus Error while tx */
++              unsigned int ts_perr            :  1;   /* Tx Descriptor protocol error */
++              unsigned int ts_eodi            :  1;   /* TxDMA end of descriptor interrupt */
++              unsigned int ts_eofi            :  1;   /* TxDMA end of frame interrupt */
++              unsigned int rs_finish          :  1;   /* finished rx interrupt */
++              unsigned int rs_derr            :  1;   /* AHB Bus Error while rx */
++              unsigned int rs_perr            :  1;   /* Rx Descriptor protocol error */
++              unsigned int rs_eodi            :  1;   /* RxDMA end of descriptor interrupt */
++              unsigned int rs_eofi            :  1;   /* RxDMA end of frame interrupt */
++        unsigned int intr           :  8;   /* Peripheral interrupt */
++              unsigned int dma_reset          :  1;   /* write 1 to this bit will cause DMA HClk domain soft reset */
++              unsigned int peri_reset         :  1;   /* write 1 to this bit will cause DMA PClk domain soft reset */
++              unsigned int                            :  3;
++              unsigned int loop_back          :  1;   /* loopback TxDMA to RxDMA */
++        unsigned int intr_enable    :  8;   /* Peripheral Interrupt Enable */
++#else
++        unsigned int intr_enable    :  8;   /* Peripheral Interrupt Enable */
++              unsigned int loop_back          :  1;   /* loopback TxDMA to RxDMA */
++              unsigned int                            :  3;
++              unsigned int peri_reset         :  1;   /* write 1 to this bit will cause DMA PClk domain soft reset */
++              unsigned int dma_reset          :  1;   /* write 1 to this bit will cause DMA HClk domain soft reset */
++        unsigned int intr           :  8;   /* Peripheral interrupt */
++              unsigned int rs_eofi            :  1;   /* RxDMA end of frame interrupt */
++              unsigned int rs_eodi            :  1;   /* RxDMA end of descriptor interrupt */
++              unsigned int rs_perr            :  1;   /* Rx Descriptor protocol error */
++              unsigned int rs_derr            :  1;   /* AHB Bus Error while rx */
++              unsigned int rs_finish          :  1;   /* finished rx interrupt */
++              unsigned int ts_eofi            :  1;   /* TxDMA end of frame interrupt */
++              unsigned int ts_eodi            :  1;   /* TxDMA end of descriptor interrupt */
++              unsigned int ts_perr            :  1;   /* Tx Descriptor protocol error */
++              unsigned int ts_derr            :  1;   /* AHB Bus Error while tx */
++              unsigned int ts_finish          :  1;   /* finished tx interrupt */
++#endif
++      } bits;
++} IPSEC_DMA_STATUS_T;
++
++typedef union
++{
++      unsigned int bits32;
++      struct bit2_ff08
++      {
++#if (BIG_ENDIAN==1)
++              unsigned int td_start           :  1;   /* Start DMA transfer */
++              unsigned int td_continue        :  1;   /* Continue DMA operation */
++              unsigned int td_chain_mode      :  1;   /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
++              unsigned int                            :  1;
++              unsigned int td_prot            :  4;   /* TxDMA protection control */
++              unsigned int td_burst_size  :  2;       /* TxDMA max burst size for every AHB request */
++              unsigned int td_bus                 :  2;       /* peripheral bus width;0 - 8 bits;1 - 16 bits */
++              unsigned int td_endian          :  1;   /* AHB Endian. 0-little endian; 1-big endian */
++              unsigned int td_finish_en   :  1;       /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
++              unsigned int td_fail_en         :  1;   /* DMA Fail Interrupt Enable;1-enable;0-mask */
++              unsigned int td_perr_en         :  1;   /* Protocol Failure Interrupt Enable;1-enable;0-mask */
++              unsigned int td_eod_en          :  1;   /* End of Descriptor interrupt Enable;1-enable;0-mask */
++              unsigned int td_eof_en      :  1;   /* End of frame interrupt Enable;1-enable;0-mask */
++              unsigned int                            : 14;
++#else
++              unsigned int                            : 14;
++              unsigned int td_eof_en      :  1;   /* End of frame interrupt Enable;1-enable;0-mask */
++              unsigned int td_eod_en          :  1;   /* End of Descriptor interrupt Enable;1-enable;0-mask */
++              unsigned int td_perr_en         :  1;   /* Protocol Failure Interrupt Enable;1-enable;0-mask */
++              unsigned int td_fail_en         :  1;   /* DMA Fail Interrupt Enable;1-enable;0-mask */
++              unsigned int td_finish_en   :  1;       /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
++              unsigned int td_endian          :  1;   /* AHB Endian. 0-little endian; 1-big endian */
++              unsigned int td_bus                 :  2;       /* peripheral bus width;0 - 8 bits;1 - 16 bits */
++              unsigned int td_burst_size  :  2;       /* TxDMA max burst size for every AHB request */
++              unsigned int td_prot            :  4;   /* TxDMA protection control */
++              unsigned int                            :  1;
++              unsigned int td_chain_mode      :  1;   /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
++              unsigned int td_continue        :  1;   /* Continue DMA operation */
++              unsigned int td_start           :  1;   /* Start DMA transfer */
++#endif
++      } bits;
++} IPSEC_TXDMA_CTRL_T;
++
++typedef union
++{
++      unsigned int bits32;
++      struct bit2_ff0c
++      {
++#if (BIG_ENDIAN==1)
++              unsigned int td_first_des_ptr   : 28;/* first descriptor address */
++              unsigned int td_busy                    :  1;/* 1-TxDMA busy; 0-TxDMA idle */
++              unsigned int                                    :  3;
++#else
++              unsigned int                                    :  3;
++              unsigned int td_busy                    :  1;/* 1-TxDMA busy; 0-TxDMA idle */
++              unsigned int td_first_des_ptr   : 28;/* first descriptor address */
++#endif
++      } bits;
++} IPSEC_TXDMA_FIRST_DESC_T;
++
++typedef union
++{
++      unsigned int bits32;
++      struct bit2_ff10
++      {
++#if (BIG_ENDIAN==1)
++              unsigned int ndar                       : 28;   /* next descriptor address */
++              unsigned int eofie                      :  1;   /* end of frame interrupt enable */
++              unsigned int dec                        :  1;   /* AHB bus address increment(0)/decrement(1) */
++              unsigned int sof_eof            :  2;
++#else
++              unsigned int sof_eof            :  2;
++              unsigned int dec                        :  1;   /* AHB bus address increment(0)/decrement(1) */
++              unsigned int eofie                      :  1;   /* end of frame interrupt enable */
++              unsigned int ndar                       : 28;   /* next descriptor address */
++#endif
++      } bits;
++} IPSEC_TXDMA_CURR_DESC_T;
++
++
++typedef union
++{
++      unsigned int bits32;
++      struct bit2_ff14
++      {
++#if (BIG_ENDIAN==1)
++              unsigned int rd_start           :  1;   /* Start DMA transfer */
++              unsigned int rd_continue        :  1;   /* Continue DMA operation */
++              unsigned int rd_chain_mode      :  1;   /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
++              unsigned int                            :  1;
++              unsigned int rd_prot            :  4;   /* DMA protection control */
++              unsigned int rd_burst_size  :  2;       /* DMA max burst size for every AHB request */
++              unsigned int rd_bus                 :  2;       /* peripheral bus width;0 - 8 bits;1 - 16 bits */
++              unsigned int rd_endian          :  1;   /* AHB Endian. 0-little endian; 1-big endian */
++              unsigned int rd_finish_en   :  1;       /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
++              unsigned int rd_fail_en         :  1;   /* DMA Fail Interrupt Enable;1-enable;0-mask */
++              unsigned int rd_perr_en         :  1;   /* Protocol Failure Interrupt Enable;1-enable;0-mask */
++              unsigned int rd_eod_en          :  1;   /* End of Descriptor interrupt Enable;1-enable;0-mask */
++              unsigned int rd_eof_en      :  1;   /* End of frame interrupt Enable;1-enable;0-mask */
++              unsigned int                            : 14;
++#else
++              unsigned int                            : 14;
++              unsigned int rd_eof_en      :  1;   /* End of frame interrupt Enable;1-enable;0-mask */
++              unsigned int rd_eod_en          :  1;   /* End of Descriptor interrupt Enable;1-enable;0-mask */
++              unsigned int rd_perr_en         :  1;   /* Protocol Failure Interrupt Enable;1-enable;0-mask */
++              unsigned int rd_fail_en         :  1;   /* DMA Fail Interrupt Enable;1-enable;0-mask */
++              unsigned int rd_finish_en   :  1;       /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
++              unsigned int rd_endian          :  1;   /* AHB Endian. 0-little endian; 1-big endian */
++              unsigned int rd_bus                 :  2;       /* peripheral bus width;0 - 8 bits;1 - 16 bits */
++              unsigned int rd_burst_size  :  2;       /* DMA max burst size for every AHB request */
++              unsigned int rd_prot            :  4;   /* DMA protection control */
++              unsigned int                            :  1;
++              unsigned int rd_chain_mode      :  1;   /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
++              unsigned int rd_continue        :  1;   /* Continue DMA operation */
++              unsigned int rd_start           :  1;   /* Start DMA transfer */
++#endif
++      } bits;
++} IPSEC_RXDMA_CTRL_T;
++
++typedef union
++{
++      unsigned int bits32;
++      struct bit2_ff18
++      {
++#if (BIG_ENDIAN==1)
++              unsigned int rd_first_des_ptr   : 28;/* first descriptor address */
++              unsigned int rd_busy                    :  1;/* 1-RxDMA busy; 0-RxDMA idle */
++              unsigned int                                    :  3;
++#else
++              unsigned int                                    :  3;
++              unsigned int rd_busy                    :  1;/* 1-RxDMA busy; 0-RxDMA idle */
++              unsigned int rd_first_des_ptr   : 28;/* first descriptor address */
++#endif
++      } bits;
++} IPSEC_RXDMA_FIRST_DESC_T;
++
++typedef union
++{
++      unsigned int bits32;
++      struct bit2_ff1c
++      {
++#if (BIG_ENDIAN==1)
++              unsigned int ndar                       : 28;   /* next descriptor address */
++              unsigned int eofie                      :  1;   /* end of frame interrupt enable */
++              unsigned int dec                        :  1;   /* AHB bus address increment(0)/decrement(1) */
++              unsigned int sof_eof            :  2;
++#else
++              unsigned int sof_eof            :  2;
++              unsigned int dec                        :  1;   /* AHB bus address increment(0)/decrement(1) */
++              unsigned int eofie                      :  1;   /* end of frame interrupt enable */
++              unsigned int ndar                       : 28;   /* next descriptor address */
++#endif
++      } bits;
++} IPSEC_RXDMA_CURR_DESC_T;
++
++
++
++/******************************************************/
++/*    the field definition of IPSEC module Register   */
++/******************************************************/
++typedef union
++{
++      unsigned int id;
++      struct bit_0000
++      {
++#if (BIG_ENDIAN==1)
++              unsigned int device_id          : 28;
++              unsigned int revision_id        :  4;
++#else
++              unsigned int revision_id        :  4;
++              unsigned int device_id          : 28;
++#endif
++      } bits;
++} IPSEC_ID_T;
++
++typedef union
++{
++    unsigned int control;
++    struct bit_0004
++    {
++#if (BIG_ENDIAN==1)
++        unsigned int op_mode            :  4; /* Operation Mode for the IPSec Module */
++        unsigned int                    :  1;
++        unsigned int cipher_algorithm   :  3;
++        unsigned int aesnk              :  4; /* AES Key Size */
++        unsigned int mix_key_sel        :  1; /* 0:use rCipherKey0-3  1:use Key Mixer */
++        unsigned int                    :  2;
++        unsigned int fcs_stream_copy    :  1; /* enable authentication stream copy */
++        unsigned int auth_mode          :  1; /* 0-Append or 1-Check Authentication Result */
++        unsigned int auth_algorithm     :  3;
++        unsigned int                    :  1;
++        unsigned int auth_check_len     :  3; /* Number of 32-bit words to be check or appended */
++                                              /* by the authentication module */
++        unsigned int process_id         :  8; /* Used to identify process.This number will be */
++                                              /* copied to the descriptor status of received packet*/
++#else
++        unsigned int process_id         :  8; /* Used to identify process.This number will be */
++                                              /* copied to the descriptor status of received packet*/
++        unsigned int auth_check_len     :  3; /* Number of 32-bit words to be check or appended */
++                                              /* by the authentication module */
++        unsigned int                    :  1;
++        unsigned int auth_algorithm     :  3;
++        unsigned int auth_mode          :  1; /* 0-Append or 1-Check Authentication Result */
++        unsigned int fcs_stream_copy    :  1; /* enable authentication stream copy */
++        unsigned int                    :  2;
++        unsigned int mix_key_sel        :  1; /* 0:use rCipherKey0-3  1:use Key Mixer */
++        unsigned int aesnk              :  4; /* AES Key Size */
++        unsigned int cipher_algorithm   :  3;
++        unsigned int                    :  1;
++        unsigned int op_mode            :  4; /* Operation Mode for the IPSec Module */
++#endif
++    } bits;
++} IPSEC_CONTROL_T;
++
++
++typedef union
++{
++    unsigned int cipher_packet;
++    struct bit_0008
++    {
++#if (BIG_ENDIAN==1)
++        unsigned int cipher_header_len    : 16; /* The header length to be skipped by the cipher */
++        unsigned int cipher_algorithm_len : 16; /* The length of message body to be encrypted/decrypted */
++#else
++        unsigned int cipher_algorithm_len : 16; /* The length of message body to be encrypted/decrypted */
++        unsigned int cipher_header_len    : 16; /* The header length to be skipped by the cipher */
++#endif
++    } bits;
++} IPSEC_CIPHER_PACKET_T;
++
++typedef union
++{
++    unsigned int auth_packet;
++    struct bit_000c
++    {
++#if (BIG_ENDIAN==1)
++        unsigned int auth_header_len    : 16; /* The header length that is to be skipped by the authenticator */
++        unsigned int auth_algorithm_len : 16; /* The length of message body that is to be authenticated */
++#else
++        unsigned int auth_algorithm_len : 16; /* The length of message body that is to be authenticated */
++        unsigned int auth_header_len    : 16; /* The header length that is to be skipped by the authenticator */
++#endif
++    } bits;
++} IPSEC_AUTH_PACKET_T;
++
++typedef union
++{
++    unsigned int status;
++    struct bit_00a8
++    {
++#if (BIG_ENDIAN==1)
++        unsigned int auth_cmp_rslt  :  1; /* Authentication Compare result */
++        unsigned int wep_crc_ok     :  1; /* WEP ICV compare result */
++        unsigned int tkip_mic_ok    :  1; /* TKIP Mic compare result */
++        unsigned int ccm_mic_ok     :  1; /* CCM Mic compare result */
++        unsigned int                : 16;
++        unsigned int parser_err_code:  4; /* Authentication Compare result */
++        unsigned int auth_err_code  :  4; /* Authentication module error code */
++        unsigned int cipher_err_code:  4; /* Cipher module erroe code */
++#else
++        unsigned int cipher_err_code:  4; /* Cipher module erroe code */
++        unsigned int auth_err_code  :  4; /* Authentication module error code */
++        unsigned int parser_err_code:  4; /* Authentication Compare result */
++        unsigned int                : 16;
++        unsigned int ccm_mic_ok     :  1; /* CCM Mic compare result */
++        unsigned int tkip_mic_ok    :  1; /* TKIP Mic compare result */
++        unsigned int wep_crc_ok     :  1; /* WEP ICV compare result */
++        unsigned int auth_cmp_rslt  :  1; /* Authentication Compare result */
++#endif
++    } bits;
++} IPSEC_STATUS_T;
++
++
++
++/************************************************************************/
++/*              IPSec Descriptor Format                                 */
++/************************************************************************/
++typedef struct descriptor_t
++{
++      union frame_control_t
++      {
++              unsigned int bits32;
++              struct bits_0000
++              {
++#if (BIG_ENDIAN==1)
++                      unsigned int own                : 1;    /* owner bit. 0-CPU, 1-DMA */
++                      unsigned int derr               : 1;    /* data error during processing this descriptor */
++                      unsigned int perr               : 1;    /* protocol error during processing this descriptor */
++                      unsigned int            : 1;    /* authentication compare result */
++                      unsigned int            : 6;    /* checksum[15:8] */
++                      unsigned int desc_count : 6;    /* number of descriptors used for the current frame */
++                      unsigned int buffer_size:16;    /* transfer buffer size associated with current description*/
++#else
++                      unsigned int buffer_size:16;    /* transfer buffer size associated with current description*/
++                      unsigned int desc_count : 6;    /* number of descriptors used for the current frame */
++                      unsigned int            : 6;    /* checksum[15:8] */
++                      unsigned int            : 1;    /* authentication compare result */
++                      unsigned int perr               : 1;    /* protocol error during processing this descriptor */
++                      unsigned int derr               : 1;    /* data error during processing this descriptor */
++                      unsigned int own                : 1;    /* owner bit. 0-CPU, 1-DMA */
++#endif
++              } bits;
++      } frame_ctrl;
++
++      union flag_status_t
++      {
++              unsigned int bits32;
++              struct bits_0004
++              {
++#if (BIG_ENDIAN==1)
++//            unsigned int checksum   : 8; /* checksum[7:0] */
++                      unsigned int            : 4;
++                      unsigned int auth_result: 1;
++                      unsigned int wep_crc_ok : 1;
++                      unsigned int tkip_mic_ok: 1;
++                      unsigned int ccmp_mic_ok: 1;
++                      unsigned int process_id : 8;
++                      unsigned int frame_count:16;
++#else
++                      unsigned int frame_count:16;
++                      unsigned int process_id : 8;
++                      unsigned int ccmp_mic_ok: 1;
++                      unsigned int tkip_mic_ok: 1;
++                      unsigned int wep_crc_ok : 1;
++                      unsigned int auth_result: 1;
++                      unsigned int            : 4;
++//            unsigned int checksum   : 8; /* checksum[7:0] */
++#endif
++              } bits_rx_status;
++
++              struct bits_0005
++              {
++#if (BIG_ENDIAN==1)
++            unsigned int            : 8;
++                      unsigned int process_id : 8;
++                      unsigned int frame_count:16;
++#else
++                      unsigned int frame_count:16;
++                      unsigned int process_id : 8;
++            unsigned int            : 8;
++#endif
++              } bits_tx_status;
++
++              struct bits_0006
++              {
++#if (BIG_ENDIAN==1)
++                      unsigned int            :22;
++                      unsigned int tqflag     :10;
++#else
++                      unsigned int tqflag     :10;
++                      unsigned int            :22;
++#endif
++              } bits_tx_flag;
++      } flag_status;
++
++      unsigned int buf_adr;   /* data buffer address */
++
++      union next_desc_t
++      {
++              unsigned int next_descriptor;
++              struct bits_000c
++              {
++#if (BIG_ENDIAN==1)
++                      unsigned int ndar               :28;    /* next descriptor address */
++                      unsigned int eofie              : 1;    /* end of frame interrupt enable */
++                      unsigned int dec                : 1;    /* AHB bus address. 0-increment; 1-decrement */
++                      unsigned int sof_eof    : 2;    /* 00-the linking descriptor   01-the last descriptor of a frame*/
++                                                      /* 10-the first descriptor of a frame    11-only one descriptor for a frame*/
++#else
++                      unsigned int sof_eof    : 2;    /* 00-the linking descriptor   01-the last descriptor of a frame*/
++                                                      /* 10-the first descriptor of a frame    11-only one descriptor for a frame*/
++                      unsigned int dec                : 1;    /* AHB bus address. 0-increment; 1-decrement */
++                      unsigned int eofie              : 1;    /* end of frame interrupt enable */
++                      unsigned int ndar               :28;    /* next descriptor address */
++#endif
++              } bits;
++      } next_desc;
++} IPSEC_DESCRIPTOR_T;
++
++
++typedef struct IPSEC_S
++{
++    unsigned char       *tx_bufs;
++    unsigned char       *rx_bufs;
++      IPSEC_DESCRIPTOR_T      *tx_desc;           /* point to virtual TX descriptor address*/
++      IPSEC_DESCRIPTOR_T      *rx_desc;           /* point to virtual RX descriptor address*/
++      IPSEC_DESCRIPTOR_T      *tx_cur_desc;   /* point to current TX descriptor */
++      IPSEC_DESCRIPTOR_T      *rx_cur_desc;   /* point to current RX descriptor */
++      IPSEC_DESCRIPTOR_T  *tx_finished_desc;
++      IPSEC_DESCRIPTOR_T  *rx_finished_desc;
++      dma_addr_t          rx_desc_dma;        /* physical RX descriptor address */
++      dma_addr_t          tx_desc_dma;    /* physical TX descriptor address */
++      dma_addr_t          rx_bufs_dma;    /* physical RX descriptor address */
++      dma_addr_t          tx_bufs_dma;    /* physical TX descriptor address */
++} IPSEC_T;
++
++
++/*=====================================================================================================*/
++/*  Data Structure of IPSEC Control Packet  */
++/*=====================================================================================================*/
++typedef struct IPSEC_ECB_AUTH_S
++{
++    IPSEC_CONTROL_T         control; /* control parameter */
++    IPSEC_CIPHER_PACKET_T   cipher; /* cipher packet parameter */
++    IPSEC_AUTH_PACKET_T     auth;   /* authentication packet parameter */
++    unsigned char           cipher_key[8*4];
++    unsigned char           auth_check_val[5*4];
++} IPSEC_ECB_AUTH_T;
++
++typedef struct IPSEC_CBC_AUTH_S
++{
++    IPSEC_CONTROL_T         control; /* control parameter */
++    IPSEC_CIPHER_PACKET_T   cipher; /* cipher packet parameter */
++    IPSEC_AUTH_PACKET_T     auth;   /* authentication packet parameter */
++    unsigned char           cipher_iv[4*4];
++    unsigned char           cipher_key[8*4];
++    unsigned char           auth_check_val[5*4];
++} IPSEC_CBC_AUTH_T;
++
++typedef struct IPSEC_ECB_HMAC_AUTH_S
++{
++    IPSEC_CONTROL_T         control; /* control parameter */
++    IPSEC_CIPHER_PACKET_T   cipher; /* cipher packet parameter */
++    IPSEC_AUTH_PACKET_T     auth;   /* authentication packet parameter */
++    unsigned char           cipher_key[8*4];
++    unsigned char           auth_key[16*4];
++    unsigned char           auth_check_val[5*4];
++} IPSEC_ECB_AUTH_HMAC_T;
++
++typedef struct IPSEC_CBC_HMAC_AUTH_S
++{
++    IPSEC_CONTROL_T         control; /* control parameter */
++    IPSEC_CIPHER_PACKET_T   cipher; /* cipher packet parameter */
++    IPSEC_AUTH_PACKET_T     auth;   /* authentication packet parameter */
++    unsigned char           cipher_iv[4*4];
++    unsigned char           cipher_key[8*4];
++    unsigned char           auth_key[16*4];
++    unsigned char           auth_check_val[5*4];
++} IPSEC_CBC_AUTH_HMAC_T;
++
++typedef struct IPSEC_HMAC_AUTH_S
++{
++    IPSEC_CONTROL_T         control; /* control parameter */
++    IPSEC_AUTH_PACKET_T     auth;   /* authentication packet parameter */
++    unsigned char           auth_key[16*4];
++    unsigned char           auth_check_val[5*4];
++} IPSEC_HMAC_AUTH_T;
++
++typedef union
++{
++    unsigned char auth_pkt[28];
++
++    struct IPSEC_AUTH_S
++    {
++        IPSEC_CONTROL_T         control; /* control parameter(4-byte) */
++        IPSEC_AUTH_PACKET_T     auth;   /* authentication packet parameter(4-byte) */
++        unsigned char           auth_check_val[5*4];
++    } var;
++} IPSEC_AUTH_T;
++
++typedef struct IPSEC_CIPHER_CBC_S
++{
++    IPSEC_CONTROL_T         control; /* control parameter */
++    IPSEC_CIPHER_PACKET_T   cipher; /* cipher packet parameter */
++    unsigned char           cipher_iv[4*4];
++    unsigned char           cipher_key[8*4];
++} IPSEC_CIPHER_CBC_T;
++
++typedef struct IPSEC_CIPHER_ECB_S
++{
++    IPSEC_CONTROL_T         control; /* control parameter */
++    IPSEC_CIPHER_PACKET_T   cipher; /* cipher packet parameter */
++    unsigned char           cipher_key[8*4];
++} IPSEC_CIPHER_ECB_T;
++
++
++/****************************************************************************
++ *                          Structure Definition                            *
++ ****************************************************************************/
++struct IPSEC_PACKET_S
++{
++    unsigned int    op_mode;            /* CIPHER_ENC(1),CIPHER_DEC(3),AUTH(4),ENC_AUTH(5),AUTH_DEC(7) */
++    unsigned int    cipher_algorithm;   /* ECB_DES(0),ECB_3DES(1),ECB_AES(2),CBC_DES(4),CBC_3DES(5),CBC_AES(6) */
++    unsigned int    auth_algorithm;     /* SHA1(0),MD5(1),HMAC_SHA1(2),HMAC_MD5(3),FCS(4) */
++    unsigned int    auth_result_mode;   /* AUTH_APPEND(0),AUTH_CHKVAL(1) */
++    unsigned int    process_id;         /* Used to identify the process */
++    unsigned int    auth_header_len;    /* Header length to be skipped by the authenticator */
++    unsigned int    auth_algorithm_len; /* Length of message body that is to be authenticated */
++    unsigned int    cipher_header_len;  /* Header length to be skipped by the cipher */
++    unsigned int    cipher_algorithm_len;   /* Length of message body to be encrypted or decrypted */
++    unsigned char   iv[16];             /* Initial vector used for DES,3DES,AES */
++    unsigned int    iv_size;            /* Initial vector size */
++    unsigned char   auth_key[64];       /* authentication key */
++    unsigned int    auth_key_size;      /* authentication key size */
++    unsigned char   cipher_key[32];     /* cipher key */
++    unsigned int    cipher_key_size;    /* cipher key size */
++    struct scatterlist *in_packet;         /* input_packet buffer pointer */
++    //unsigned char           *in_packet;         /* input_packet buffer pointer */
++    unsigned int    pkt_len;            /* input total packet length */
++    unsigned char   auth_checkval[20];  /* Authentication check value/FCS check value */
++    struct IPSEC_PACKET_S *next,*prev;        /* pointer to next/previous operation to perform on buffer */
++    void (*callback)(struct IPSEC_PACKET_S *); /* function to call when done authentication/cipher */
++    unsigned char   *out_packet;        /* output_packet buffer pointer */
++    //struct scatterlist *out_packet;        /* output_packet buffer pointer */
++    unsigned int    out_pkt_len;        /* output total packet length */
++    unsigned int    auth_cmp_result;    /* authentication compare result */
++    unsigned int    checksum;           /* checksum value */
++    unsigned int    status;             /* ipsec return status. 0:success, others:fail */
++#if (IPSEC_TEST == 1)
++    unsigned char    *sw_packet;         /* for test only */
++    unsigned int    sw_pkt_len;         /* for test only */
++#endif
++} ;
++
++/*****************************************************************************
++ * Function    : ipsec_crypto_hw_process
++ * Description : This function processes H/W authentication and cipher.
++ *       Input : op_info - the authentication and cipher information for IPSec module.
++ *      Output : none.
++ *      Return : 0 - success, others - failure.
++ *****************************************************************************/
++int ipsec_crypto_hw_process(struct IPSEC_PACKET_S  *op_info);
++
++int ipsec_get_cipher_algorithm(unsigned char *alg_name,unsigned int alg_mode);
++int ipsec_get_auth_algorithm(unsigned char *alg_name,unsigned int alg_mode);
++#if 0
++void ipsec_sw_authentication(char *data,unsigned int data_len,char *authkey,char authAlgorithm,char *auth_result);
++void ipsec_sw_cipher(unsigned char *pt,unsigned int pt_len, unsigned char *cipher_key, unsigned int key_size,
++                            unsigned char *iv,unsigned int cipherAlgorithm,unsigned char *ct);
++void ipsec_sw_auth_cipher(unsigned int op_mode,char *data,unsigned int data_len,
++                                BYTE *auth_key,char authAlgorithm,char *auth_result,
++                                char *pt, unsigned int pt_len,char *cipher_key, int key_size,
++                                char *iv, char cipherAlgorithm,char *ct);
++#endif
++
++
++#endif
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/sl_random.h
+@@ -0,0 +1,2 @@
++#define RANDOM_ADD            (IO_ADDRESS (0x051000000) + 0x0AC)
++
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/system.h
+@@ -0,0 +1,54 @@
++/*
++ *  linux/include/asm-arm/arch-sl2312/system.h
++ *
++ *  Copyright (C) 1999 ARM Limited
++ *  Copyright (C) 2000 Deep Blue Solutions Ltd
++ *  Copyright (C) 2001 Altera Corporation
++ *
++ * 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 program is distributed in the hope that 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
++ */
++#ifndef __ASM_ARCH_SYSTEM_H
++#define __ASM_ARCH_SYSTEM_H
++
++#include <asm/arch/platform.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/it8712.h>
++#include <asm/io.h>
++
++static void arch_idle(void)
++{
++      /*
++       * This should do all the clock switching
++       * and wait for interrupt tricks
++       */
++      cpu_do_idle();
++}
++
++extern __inline__ void arch_reset(char mode)
++{
++      __raw_writel( (int) GLOBAL_RESET|RESET_CPU1, IO_ADDRESS(SL2312_GLOBAL_BASE) + GLOBAL_RESET_REG);
++}
++
++
++void (*pm_power_off)(void);
++//{
++//    printk("arch_power_off\n");
++
++      // Power off
++//    __raw_writel( (int) 0x00000001, IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04);
++
++//}
++
++#endif
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/timer.h
+@@ -0,0 +1,53 @@
++/*
++ *
++ *  This file contains the register definitions for the Excalibur
++ *  Timer TIMER00.
++ *
++ *  Copyright (C) 2001 Altera Corporation
++ *
++ * 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 program is distributed in the hope that 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
++ */
++#ifndef __TIMER_H
++#define __TIMER_H
++
++/*
++ * Register definitions for the timers
++ */
++
++#define TIMER_COUNT(BASE_ADDR)          (TIMER_TYPE (BASE_ADDR  + 0x00 ))
++#define TIMER_LOAD(BASE_ADDR)           (TIMER_TYPE (BASE_ADDR  + 0x04 ))
++#define TIMER_MATCH1(BASE_ADDR)         (TIMER_TYPE (BASE_ADDR  + 0x08 ))
++#define TIMER_MATCH2(BASE_ADDR)         (TIMER_TYPE (BASE_ADDR  + 0x0C ))
++#define TIMER_CR(BASE_ADDR)             (TIMER_TYPE (BASE_ADDR  + 0x30 ))
++#define TIMER_1_CR_ENABLE_MSK                     (0x00000001)
++#define TIMER_1_CR_ENABLE_OFST                    (0)
++#define TIMER_1_CR_CLOCK_MSK                      (0x00000002)
++#define TIMER_1_CR_CLOCK_OFST                     (1)
++#define TIMER_1_CR_INT_MSK                    (0x00000004)
++#define TIMER_1_CR_INT_OFST               (2)
++#define TIMER_2_CR_ENABLE_MSK                     (0x00000008)
++#define TIMER_2_CR_ENABLE_OFST                    (3)
++#define TIMER_2_CR_CLOCK_MSK                      (0x00000010)
++#define TIMER_2_CR_CLOCK_OFST                     (4)
++#define TIMER_2_CR_INT_MSK                    (0x00000020)
++#define TIMER_2_CR_INT_OFST               (5)
++#define TIMER_3_CR_ENABLE_MSK                     (0x00000040)
++#define TIMER_3_CR_ENABLE_OFST                    (6)
++#define TIMER_3_CR_CLOCK_MSK                      (0x00000080)
++#define TIMER_3_CR_CLOCK_OFST                     (7)
++#define TIMER_3_CR_INT_MSK                    (0x00000100)
++#define TIMER_3_CR_INT_OFST               (8)
++
++#endif /* __TIMER00_H */
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/timex.h
+@@ -0,0 +1,29 @@
++/*
++ *  linux/include/asm-arm/arch-epxa10db/timex.h
++ *
++ *  Excalibur timex specifications
++ *
++ *  Copyright (C) 2001 Altera Corporation
++ *
++ * 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 program is distributed in the hope that 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
++ */
++
++/*
++ * ??
++ */
++#include <asm/arch/sl2312.h>
++
++#define CLOCK_TICK_RATE               APB_CLK
++
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/uart.h
+@@ -0,0 +1,100 @@
++/* *
++ *  Copyright (C) 2001 Altera Corporation
++ *
++ * 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 program is distributed in the hope that 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
++ */
++#ifndef __UART_H
++#define __UART_H
++
++/*
++ * Register definitions for the UART
++ */
++
++#define UART_TX_FIFO_SIZE      (15)
++
++#define UART_RBR(BASE_ADDR) (UART_TYPE (BASE_ADDR  + 0x00))  // read
++#define UART_THR(BASE_ADDR) (UART_TYPE (BASE_ADDR  + 0x00))  // write
++#define UART_IER(BASE_ADDR) (UART_TYPE (BASE_ADDR  + 0x04))
++#define UART_IER_MS                                 (0x08)
++#define UART_IER_RLS                                (0x04)
++#define UART_IER_TE                                 (0x02)
++#define UART_IER_DR                                 (0x01)
++#define UART_IIR(BASE_ADDR) (UART_TYPE (BASE_ADDR  + 0x08))   // read
++#define UART_IIR_NONE                             (0x01)      /* No interrupt pending */
++#define UART_IIR_RLS                              (0x06)      /* Receive Line Status */
++#define UART_IIR_DR                               (0x04)      /* Receive Data Ready */
++#define UART_IIR_TIMEOUT                          (0x0c)      /* Receive Time Out */
++#define UART_IIR_TE                               (0x02)      /* THR Empty */
++#define UART_IIR_MODEM                            (0x00)      /* Modem Status */
++#define UART_FCR(BASE_ADDR) (UART_TYPE (BASE_ADDR  + 0x08))  // write
++#define UART_FCR_FE                               (0x01)      /* FIFO Enable */
++#define UART_FCR_RXFR                             (0x02)      /* Rx FIFO Reset */
++#define UART_FCR_TXFR                             (0x04)      /* Tx FIFO Reset */
++#define UART_FCR_FIFO_1C                            (0x00)
++#define UART_FCR_FIFO_4C                            (0x40)
++#define UART_FCR_FIFO_8C                            (0x80)
++#define UART_FCR_FIFO_14C                           (0xC0)
++#define UART_LCR(BASE_ADDR) (UART_TYPE (BASE_ADDR  + 0x0C))
++#define UART_LCR_MSK                                (0x03)
++#define UART_LCR_LEN5                             (0x00)
++#define UART_LCR_LEN6                             (0x01)
++#define UART_LCR_LEN7                             (0x02)
++#define UART_LCR_LEN8                             (0x03)
++#define UART_LCR_STOP                             (0x04)
++#define UART_LCR_EVEN                             (0x18)      /* Even Parity */
++#define UART_LCR_ODD                              (0x08)      /* Odd Parity */
++#define UART_LCR_PE                               (0x08)      /* Parity Enable */
++#define UART_LCR_SETBREAK                         (0x40)      /* Set Break condition */
++#define UART_LCR_STICKPARITY                      (0x20)      /* Stick Parity Enable */
++#define UART_LCR_DLAB                             (0x80)      /* Divisor Latch Access Bit */
++#define UART_MCR(BASE_ADDR) (UART_TYPE (BASE_ADDR  + 0x10))
++#define UART_MCR_DTR                              (0x1)       /* Data Terminal Ready */
++#define UART_MCR_RTS                              (0x2)       /* Request to Send */
++#define UART_MCR_OUT1                             (0x4)       /* output       1 */
++#define UART_MCR_OUT2                             (0x8)       /* output2 or global interrupt enable */
++#define UART_MCR_LPBK                             (0x10)      /* loopback mode */
++#define UART_MCR_MASK                               (0xE3)
++#define UART_LSR(BASE_ADDR) (UART_TYPE (BASE_ADDR  + 0x14))
++#define UART_LSR_DR                               (0x01)      /* Data Ready */
++#define UART_LSR_OE                               (0x02)      /* Overrun Error */
++#define UART_LSR_PE                               (0x04)      /* Parity Error */
++#define UART_LSR_FE                               (0x08)      /* Framing Error */
++#define UART_LSR_BI                                 (0x10)            /* Break Interrupt */
++#define UART_LSR_THRE                               (0x20)            /* THR Empty */
++#define UART_LSR_TE                                 (0x40)            /* Transmitte Empty */
++#define UART_LSR_DE                                 (0x80)            /* FIFO Data Error */
++#define UART_MSR(BASE_ADDR) (UART_TYPE (BASE_ADDR  + 0x18))
++#define UART_MSR_DELTACTS                         (0x01)      /* Delta CTS */
++#define UART_MSR_DELTADSR                         (0x02)      /* Delta DSR */
++#define UART_MSR_TERI                             (0x04)      /* Trailing Edge RI */
++#define UART_MSR_DELTACD                          (0x08)      /* Delta CD */
++#define UART_MSR_CTS                              (0x10)      /* Clear To Send */
++#define UART_MSR_DSR                              (0x20)      /* Data Set Ready */
++#define UART_MSR_RI                               (0x40)      /* Ring Indicator */
++#define UART_MSR_DCD                              (0x80)      /* Data Carrier Detect */
++#define UART_SPR(BASE_ADDR) (UART_TYPE (BASE_ADDR  + 0x1C))
++#define UART_DIV_LO(BASE_ADDR) (UART_TYPE (BASE_ADDR  + 0x0))
++#define UART_DIV_HI(BASE_ADDR) (UART_TYPE (BASE_ADDR  + 0x4))
++#define UART_PSR(BASE_ADDR) (UART_TYPE (BASE_ADDR  + 0x8))
++#define UART_MDR(BASE_ADDR) (UART_TYPE (BASE_ADDR  + 0x20))
++#define UART_MDR_SERIAL                             (0x0)
++
++#define UART_MSR_DDCD 0x08    /* Delta DCD */
++#define UART_MSR_DDSR 0x02    /* Delta DSR */
++#define UART_MSR_DCTS 0x01    /* Delta CTS */
++#define UART_MSR_ANY_DELTA 0x0F       /* Any of the delta bits! */
++
++
++#endif /* __UART_H */
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/uncompress.h
+@@ -0,0 +1,94 @@
++/*
++ *  linux/include/asm-arm/arch-epxa10db/uncompress.h
++ *
++ *  Copyright (C) 1999 ARM Limited
++ *  Copyright (C) 2001 Altera Corporation
++ *
++ * 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 program is distributed in the hope that 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
++ */
++#include "asm/arch/platform.h"
++#include "asm/arch/hardware.h"
++#define UART_TYPE (volatile unsigned int*)
++#ifndef CONFIG_SERIAL_IT8712
++#include "asm/arch/uart.h"
++#endif
++extern unsigned int it8712_uart_base;
++
++/*
++ * This does not append a newline
++ */
++static void putstr(const char *s)
++{
++
++#ifdef CONFIG_SERIAL_IT8712
++
++      unsigned char *base,*status,stat;
++      int i ;
++
++      status = (unsigned char*)it8712_uart_base + 5;
++      base = (unsigned char*)it8712_uart_base ;
++
++      while (*s) {
++
++              stat = *status;
++              while (!(stat&0x20)) {                          // check status
++                      for(i=0;i<0x10;i++)     ;
++                      status = (unsigned char*)it8712_uart_base + 5;
++                      stat = *status ;
++              }
++
++              *base = *s;
++              barrier();
++
++              if (*s == '\n') {
++                      stat = *status;
++                      while (!(stat&0x20)) {                  // check status
++                              for(i=0;i<0x10;i++)     ;
++                              status = (unsigned char*)it8712_uart_base + 5;
++                              stat = *status ;
++              }
++
++                      barrier();
++                      *base = '\r';
++              }
++              s++;
++      }
++
++#else
++      while (*s) {
++              while (!(*UART_LSR(SL2312_UART_BASE) &
++                       UART_LSR_THRE));
++                     barrier();
++
++              *UART_THR(SL2312_UART_BASE) = *s;
++
++              if (*s == '\n') {
++                      while (!(*UART_LSR(SL2312_UART_BASE) &
++                               UART_LSR_THRE));
++                              barrier();
++
++                      *UART_THR(SL2312_UART_BASE) = '\r';
++              }
++              s++;
++      }
++#endif
++}
++
++/*
++ * nothing to do
++ */
++#define arch_decomp_setup()
++
++#define arch_decomp_wdog()
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/vmalloc.h
+@@ -0,0 +1,36 @@
++/*
++ *  linux/include/asm-arm/arch-epxa10db/vmalloc.h
++ *
++ *  Copyright (C) 2000 Russell King.
++ *
++ * 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 program is distributed in the hope that 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
++ */
++
++/*
++ * Just any arbitrary offset to the start of the vmalloc VM area: the
++ * current 8MB value just means that there will be a 8MB "hole" after the
++ * physical memory until the kernel virtual memory starts.  That means that
++ * any out-of-bounds memory accesses will hopefully be caught.
++ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
++ * area for the same reason. ;)
++ */
++#define VMALLOC_OFFSET          (8*1024*1024)
++#define VMALLOC_START   (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
++#define VMALLOC_VMADDR(x) ((unsigned long)(x))
++#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
++
++//#define MODULE_START    (PAGE_OFFSET - 16*1048576)
++//#define MODULE_END      (PAGE_OFFSET)
++
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/watchdog.h
+@@ -0,0 +1,58 @@
++#ifndef __WATCHDOG_H
++#define __WATCHDOG_H
++
++#define WATCHDOG_BASE                   (IO_ADDRESS (SL2312_WAQTCHDOG_BASE))
++#define WATCHDOG_COUNTER                  (WATCHDOG_BASE + 0x00)
++#define WATCHDOG_LOAD                     (WATCHDOG_BASE + 0x04)
++#define WATCHDOG_RESTART                  (WATCHDOG_BASE + 0x08)
++#define WATCHDOG_CR                       (WATCHDOG_BASE + 0x0C)
++#define WATCHDOG_STATUS                   (WATCHDOG_BASE + 0x10)
++#define WATCHDOG_CLEAR                    (WATCHDOG_BASE + 0x14)
++#define WATCHDOG_INTRLEN                  (WATCHDOG_BASE + 0x18)
++
++#define WATCHDOG_WDENABLE_MSK                   (0x00000001)
++#define WATCHDOG_WDENABLE_OFST                  (0)
++#define WATCHDOG_WDRST_MSK              (0x00000002)
++#define WATCHDOG_WDRST_OFST             (1)
++#define WATCHDOG_WDINTR_MSK             (0x00000004)
++#define WATCHDOG_WDINTR_OFST            (2)
++#define WATCHDOG_WDEXT_MSK              (0x00000008)
++#define WATCHDOG_WDEXT_OFST             (3)
++#define WATCHDOG_WDCLOCK_MSK            (0x00000010)
++#define WATCHDOG_WDCLOCK_OFST                   (4)
++#define WATCHDOG_CR_MASK                  (0x0000001F)
++
++#define WATCHDOG_CLEAR_STATUS             0x1
++#define WATCHDOG_ENABLE                   1
++#define WATCHDOG_DISABLE                  0
++#define WATCHDOG_RESTART_VALUE            0x5AB9
++
++#define WATCHDOG_MINOR                          130
++
++#define WATCHDOG_IOCTRL_DISABLE                 0x01
++#define WATCHDOG_IOCTRL_SETTIME                 0x02
++#define WATCHDOG_IOCTRL_ENABLE                  0x03
++#define WATCHDOG_IOCTRL_RESTART                 0x04
++
++#define WATCHDOG_TIMEOUT_SCALE            APB_CLK
++#define WATCHDOG_TIMEOUT_MARGIN           30
++#define WATCHDOG_DRIVER_OPEN              1
++#define WATCHDOG_DRIVER_CLOSE             0
++
++
++static void     watchdog_disable(void);
++static void     watchdog_enable(void);
++static int      watchdog_open(struct inode *, struct file *);
++static int      watchdog_release(struct inode *, struct file *);
++static ssize_t  watchdog_read(struct file *, char *, size_t, loff_t *);
++static ssize_t  watchdog_write(struct file *, const char *, size_t, loff_t *);
++static int      watchdog_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
++#ifdef WATCHDOG_TEST
++static void watchdog_fire(int, void *, struct pt_regs *);
++#endif
++
++
++
++
++
++#endif
+--- /dev/null
++++ b/include/asm-arm/arch-sl2312/xor.h
+@@ -0,0 +1,29 @@
++/*
++ * include/asm-arm/arch-sl2312/xor.h
++ *
++ * Copyright (C) 2005 Storlink Corp.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef _ASM_ARCH_XOR_H
++#define _ASM_ARCH_XOR_H
++
++/*
++ * Function prototypes
++ */
++void xor_gemini_2(unsigned long bytes, unsigned long *p1, unsigned long *p2);
++
++void xor_gemini_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++                           unsigned long *p3);
++
++void xor_gemini_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++                           unsigned long *p3, unsigned long *p4);
++
++void xor_gemini_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++                           unsigned long *p3, unsigned long *p4, unsigned long *p5);
++
++#endif /* _ASM_ARCH_XOR_H */
++
+--- a/include/asm-arm/cacheflush.h
++++ b/include/asm-arm/cacheflush.h
+@@ -46,6 +46,18 @@
+ # define MULTI_CACHE 1
+ #endif
++/***********************************************************************
++ *             Storlink SoC -- Cache
++ ***********************************************************************/
++#if defined(CONFIG_CPU_FA526)
++# ifdef _CACHE
++#  define MULTI_CACHE 1
++# else
++#  define _CACHE fa
++# endif
++#endif
++/***********************************************************************/
++
+ #if defined(CONFIG_CPU_ARM926T)
+ # ifdef _CACHE
+ #  define MULTI_CACHE 1
+--- a/include/asm-arm/page.h
++++ b/include/asm-arm/page.h
+@@ -74,6 +74,18 @@
+ # endif
+ #endif
++/***********************************************************************
++ *             Storlink SoC -- flash
++ ***********************************************************************/
++#ifdef CONFIG_CPU_COPY_FA
++# ifdef _USER
++#  define MULTI_USER 1
++# else
++#  define _USER fa
++# endif
++#endif
++/***********************************************************************/
++
+ #ifdef CONFIG_CPU_SA1100
+ # ifdef _USER
+ #  define MULTI_USER 1
+--- a/include/asm-arm/proc-fns.h
++++ b/include/asm-arm/proc-fns.h
+@@ -89,6 +89,14 @@
+ #   define CPU_NAME cpu_arm922
+ #  endif
+ # endif
++# ifdef CONFIG_CPU_FA526
++#  ifdef CPU_NAME
++#   undef  MULTI_CPU
++#   define MULTI_CPU
++#  else
++#   define CPU_NAME cpu_fa526
++#  endif
++# endif
+ # ifdef CONFIG_CPU_ARM925T
+ #  ifdef CPU_NAME
+ #   undef  MULTI_CPU
+--- a/include/asm-arm/tlbflush.h
++++ b/include/asm-arm/tlbflush.h
+@@ -39,6 +39,8 @@
+ #define TLB_V6_D_ASID (1 << 17)
+ #define TLB_V6_I_ASID (1 << 18)
++#define TLB_DINVAL      (1 << 28)
++#define TLB_BTB         (1 << 29)
+ #define TLB_DCLEAN    (1 << 30)
+ #define TLB_WB                (1 << 31)
+@@ -52,6 +54,7 @@
+  *      v4wb  - ARMv4 with write buffer without I TLB flush entry instruction
+  *      v4wbi - ARMv4 with write buffer with I TLB flush entry instruction
+  *      v6wbi - ARMv6 with write buffer with I TLB flush entry instruction
++ *    fa    - ARMv4 with write buffer with UTLB and branch target buffer (BTB)
+  */
+ #undef _TLB
+ #undef MULTI_TLB
+@@ -86,6 +89,44 @@
+ # define v4_always_flags      (-1UL)
+ #endif
++#ifdef CONFIG_CPU_FA_BTB
++#define __TLB_BTB      TLB_BTB
++#else
++#define __TLB_BTB      0
++#endif
++
++#ifdef CONFIG_CPU_FA_WB_DISABLE
++#define __TLB_WB       0
++#else
++#define __TLB_WB       TLB_WB
++#endif
++
++/* Fix buggy CPU which doesn't invalidate Dcache properly */
++#ifdef CONFIG_CPU_FA520
++#define __TLB_DINVAL   TLB_DINVAL
++#elif defined(CONFIG_CPU_FA526)
++//#define __TLB_DINVAL   TLB_DINVAL
++#define __TLB_DINVAL   0
++#else
++#define __TLB_DINVAL   0
++#endif
++
++#define fa_tlb_flags  (__TLB_WB | __TLB_BTB | __TLB_DINVAL | TLB_DCLEAN | \
++                         TLB_V4_U_FULL | TLB_V4_U_PAGE)
++
++#ifdef CONFIG_CPU_TLB_FA
++# define fa_possible_flags    fa_tlb_flags
++# define fa_always_flags      fa_tlb_flags
++# ifdef _TLB
++#  define MULTI_TLB 1
++# else
++#  define _TLB fa
++# endif
++#else
++# define fa_possible_flags    0
++# define fa_always_flags      (-1UL)
++#endif
++
+ #define v4wbi_tlb_flags       (TLB_WB | TLB_DCLEAN | \
+                        TLB_V4_I_FULL | TLB_V4_D_FULL | \
+                        TLB_V4_I_PAGE | TLB_V4_D_PAGE)
+@@ -246,12 +287,14 @@
+                                v4_possible_flags | \
+                                v4wbi_possible_flags | \
+                                v4wb_possible_flags | \
++                 fa_possible_flags | \
+                                v6wbi_possible_flags)
+ #define always_tlb_flags      (v3_always_flags & \
+                                v4_always_flags & \
+                                v4wbi_always_flags & \
+                                v4wb_always_flags & \
++                 fa_always_flags & \
+                                v6wbi_always_flags)
+ #define tlb_flag(f)   ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
+@@ -261,6 +304,9 @@
+       const int zero = 0;
+       const unsigned int __tlb_flag = __cpu_tlb_flags;
++      if (tlb_flag(TLB_DINVAL))
++              asm("mcr%? p15, 0, %0, c7, c14, 0" : : "r" (zero));
++
+       if (tlb_flag(TLB_WB))
+               dsb();
+@@ -281,6 +327,13 @@
+               dsb();
+               isb();
+       }
++
++      if (tlb_flag(TLB_BTB))
++      {
++        asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero));
++              asm("mov r0, r0" : : );
++              asm("mov r0, r0" : : );
++      }
+ }
+ static inline void local_flush_tlb_mm(struct mm_struct *mm)
+@@ -289,6 +342,9 @@
+       const int asid = ASID(mm);
+       const unsigned int __tlb_flag = __cpu_tlb_flags;
++      if (tlb_flag(TLB_DINVAL))
++              asm("mcr%? p15, 0, %0, c7, c14, 0" : : "r" (zero));
++
+       if (tlb_flag(TLB_WB))
+               dsb();
+@@ -317,6 +373,14 @@
+               asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+               dsb();
+       }
++
++      if (tlb_flag(TLB_BTB))
++      {
++        asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero));
++              asm("mov r0, r0" : : );
++              asm("mov r0, r0" : : );
++      }
++
+ }
+ static inline void
+@@ -327,6 +391,9 @@
+       uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm);
++      if (tlb_flag(TLB_DINVAL))
++        asm("mcr%? p15, 0, %0, c7, c14, 0" : : "r" (zero)); // clean & invalidate data cache all
++
+       if (tlb_flag(TLB_WB))
+               dsb();
+@@ -357,6 +424,13 @@
+               asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+               dsb();
+       }
++
++      if (tlb_flag(TLB_BTB))
++      {
++        asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero));
++              asm("mov r0, r0" : : );
++              asm("mov r0, r0" : : );
++      }
+ }
+ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
+@@ -366,6 +440,9 @@
+       kaddr &= PAGE_MASK;
++      if (tlb_flag(TLB_DINVAL))
++        asm("mcr%? p15, 0, %0, c7, c14, 0" : : "r" (zero));
++
+       if (tlb_flag(TLB_WB))
+               dsb();
+@@ -386,6 +463,12 @@
+               asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc");
+       if (tlb_flag(TLB_V6_I_PAGE))
+               asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
++      if (tlb_flag(TLB_BTB))
++      {
++        asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero));
++              asm("mov r0, r0" : : );
++              asm("mov r0, r0" : : );
++      }
+       if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
+                    TLB_V6_I_PAGE | TLB_V6_D_PAGE |
+@@ -412,6 +495,7 @@
+  */
+ static inline void flush_pmd_entry(pmd_t *pmd)
+ {
++      const unsigned int zero = 0;
+       const unsigned int __tlb_flag = __cpu_tlb_flags;
+       if (tlb_flag(TLB_DCLEAN))
+@@ -419,15 +503,30 @@
+                       : : "r" (pmd) : "cc");
+       if (tlb_flag(TLB_WB))
+               dsb();
++
++      if (tlb_flag(TLB_BTB)) // Luke Lee 05/16/2005
++      {
++        asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero));
++              asm("mov r0, r0" : : );
++              asm("mov r0, r0" : : );
++      }
+ }
+ static inline void clean_pmd_entry(pmd_t *pmd)
+ {
++    const unsigned int zero = 0; // Luke Lee 05/16/2005 ins 1
+       const unsigned int __tlb_flag = __cpu_tlb_flags;
+       if (tlb_flag(TLB_DCLEAN))
+               asm("mcr        p15, 0, %0, c7, c10, 1  @ flush_pmd"
+                       : : "r" (pmd) : "cc");
++
++      if (tlb_flag(TLB_BTB)) // Luke Lee 05/16/2005
++      {
++        asm("mcr%? p15, 0, %0, c7, c5, 6" : : "r" (zero));
++              asm("mov r0, r0" : : );
++              asm("mov r0, r0" : : );
++      }
+ }
+ #undef tlb_flag
+--- a/include/asm-arm/xor.h
++++ b/include/asm-arm/xor.h
+@@ -139,3 +139,18 @@
+               xor_speed(&xor_block_8regs);    \
+               xor_speed(&xor_block_32regs);   \
+       } while (0)
++
++#ifdef CONFIG_GEMINI_XOR_ACCE
++#include <asm/arch/xor.h>
++static struct xor_block_template xor_block_gemini = {
++      .name   = "gemini xor acceleration",
++      .do_2   = xor_gemini_2,
++      .do_3   = xor_gemini_3,
++      .do_4   = xor_gemini_4,
++      .do_5   = xor_gemini_5,};
++#undef XOR_TRY_TEMPLATES
++#define XOR_TRY_TEMPLATES                     \
++      do {                                    \
++      xor_speed(&xor_block_gemini); \
++      } while (0)
++#endif
+--- a/include/linux/apm_bios.h
++++ b/include/linux/apm_bios.h
+@@ -217,4 +217,24 @@
+ #define APM_IOC_STANDBY               _IO('A', 1)
+ #define APM_IOC_SUSPEND               _IO('A', 2)
++// add by jason for power control
++struct pwc_ioctl_data {
++      unsigned int action;    // sword struct
++      unsigned int data;      // stand shutdown time for PWC_SET_SHUT_TIME
++                              // stand shutdown source for PWC_WAIT_BTN
++};
++
++#define POWEROFF              0x01
++#define RESTORE_DEFAULT       0x02
++#define SYSTEM_REBOOT 0x04
++
++#define PWR_SRC_CIR           0x10
++#define PWR_SRC_RTC           0x20
++#define PWR_SRC_BTN           0x40
++
++#define       PWC_IOCTL_BASE                  'A'                             // use linux APM ioctl
++#define PWC_SET_SHUT_TIME             _IOW('A', 16, struct pwc_ioctl_data)
++#define PWC_WAIT_BTN                  _IOR('A', 17, struct pwc_ioctl_data)
++#define PWC_SHUTDOWN                  _IO ('A', 18)
++
+ #endif        /* LINUX_APM_H */
+--- a/kernel/time.c
++++ b/kernel/time.c
+@@ -76,6 +76,7 @@
+  * why not move it into the appropriate arch directory (for those
+  * architectures that need it).
+  */
++extern void rtc_set_time_second(unsigned int second);
+  
+ asmlinkage long sys_stime(time_t __user *tptr)
+ {
+@@ -87,6 +88,10 @@
+       tv.tv_nsec = 0;
++#ifdef CONFIG_SL2312_RTC
++    rtc_set_time_second(tv.tv_sec);
++#endif
++
+       err = security_settime(&tv, NULL);
+       if (err)
+               return err;