add preliminary support for Storm SL3512 based devices, not ready yet
[openwrt/openwrt.git] / target / linux / storm / patches / 1001-arch.patch
1 Index: linux-2.6.23.16/arch/arm/Kconfig
2 ===================================================================
3 --- linux-2.6.23.16.orig/arch/arm/Kconfig 2008-03-13 17:46:04.000791190 +0200
4 +++ linux-2.6.23.16/arch/arm/Kconfig 2008-03-13 17:48:24.508798285 +0200
5 @@ -220,6 +220,9 @@
6 help
7 This enables support for the Cirrus EP93xx series of CPUs.
8
9 +config ARCH_SL2312
10 + bool "SL2312"
11 +
12 config ARCH_FOOTBRIDGE
13 bool "FootBridge"
14 select FOOTBRIDGE
15 @@ -414,6 +417,8 @@
16
17 source "arch/arm/mach-footbridge/Kconfig"
18
19 +source "arch/arm/mach-sl2312/Kconfig"
20 +
21 source "arch/arm/mach-integrator/Kconfig"
22
23 source "arch/arm/mach-iop32x/Kconfig"
24 @@ -549,6 +554,16 @@
25 config PCI_SYSCALL
26 def_bool PCI
27
28 +config SL2312_LPC
29 + bool "LPC Host Support"
30 + depends on ARCH_SL2312
31 + help
32 +
33 +config SL2312_LPC_IT8712
34 + bool "IT8712 Support"
35 + depends on ARCH_SL2312 && SL2312_LPC
36 + help
37 +
38 # Select the host bridge type
39 config PCI_HOST_VIA82C505
40 bool
41 @@ -988,6 +1003,10 @@
42 source "drivers/mtd/Kconfig"
43 endif
44
45 +if ARCH_SL2312
46 +source "drivers/telephony/Kconfig"
47 +endif
48 +
49 source "drivers/parport/Kconfig"
50
51 source "drivers/pnp/Kconfig"
52 @@ -997,7 +1016,7 @@
53 if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \
54 || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
55 || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
56 - || ARCH_IXP23XX
57 + || ARCH_IXP23XX || ARCH_SL2312
58 source "drivers/ide/Kconfig"
59 endif
60
61 Index: linux-2.6.23.16/arch/arm/Makefile
62 ===================================================================
63 --- linux-2.6.23.16.orig/arch/arm/Makefile 2008-03-13 17:46:04.500819685 +0200
64 +++ linux-2.6.23.16/arch/arm/Makefile 2008-03-13 17:48:24.508798285 +0200
65 @@ -72,6 +72,7 @@
66 tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi
67 tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi
68 tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi
69 +tune-$(CONFIG_CPU_FA52X) :=-mtune=arm9tdmi
70 tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110
71 tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100
72 tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
73 @@ -111,6 +112,7 @@
74 machine-$(CONFIG_ARCH_PXA) := pxa
75 machine-$(CONFIG_ARCH_L7200) := l7200
76 machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
77 + machine-$(CONFIG_ARCH_SL2312) := sl2312
78 textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000
79 machine-$(CONFIG_ARCH_CLPS711X) := clps711x
80 machine-$(CONFIG_ARCH_IOP32X) := iop32x
81 Index: linux-2.6.23.16/arch/arm/boot/compressed/Makefile
82 ===================================================================
83 --- linux-2.6.23.16.orig/arch/arm/boot/compressed/Makefile 2008-03-13 17:46:04.500819685 +0200
84 +++ linux-2.6.23.16/arch/arm/boot/compressed/Makefile 2008-03-13 17:48:24.508798285 +0200
85 @@ -19,6 +19,10 @@
86 OBJS += head-shark.o ofw-shark.o
87 endif
88
89 +ifeq ($(CONFIG_ARCH_SL2312),y)
90 +OBJS += head-sl2312.o
91 +endif
92 +
93 ifeq ($(CONFIG_ARCH_L7200),y)
94 OBJS += head-l7200.o
95 endif
96 Index: linux-2.6.23.16/arch/arm/boot/compressed/head-sl2312.S
97 ===================================================================
98 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
99 +++ linux-2.6.23.16/arch/arm/boot/compressed/head-sl2312.S 2008-03-13 17:48:24.508798285 +0200
100 @@ -0,0 +1,6 @@
101 +#include <asm/mach-types.h>
102 +#include <asm/arch/sl2312.h>
103 +
104 + .section ".start", "ax"
105 + mov r7, #MACH_TYPE_SL2312
106 +
107 Index: linux-2.6.23.16/arch/arm/boot/compressed/head.S
108 ===================================================================
109 --- linux-2.6.23.16.orig/arch/arm/boot/compressed/head.S 2008-03-13 17:46:04.500819685 +0200
110 +++ linux-2.6.23.16/arch/arm/boot/compressed/head.S 2008-03-13 17:48:24.508798285 +0200
111 @@ -57,6 +57,17 @@
112 mov \rb, #0x50000000
113 add \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
114 .endm
115 +/*****************************************************
116 + * for Storlink SoC
117 + *****************************************************/
118 +#elif defined(CONFIG_ARCH_SL2312)
119 + .macro loadsp, rb
120 + mov \rb, #0x16000000
121 + .endm
122 + .macro writeb, rb
123 + strb \rb, [r3, #0]
124 + .endm
125 +/****************************************************/
126 #else
127 .macro loadsp, rb
128 addruart \rb
129 @@ -116,7 +127,28 @@
130 .rept 8
131 mov r0, r0
132 .endr
133 -
134 +/*****************************************************************************
135 + * for Storlink Soc -- on chip UART
136 + *****************************************************************************/
137 +#ifndef CONFIG_SERIAL_IT8712 // Jason test
138 +@ mov r3, #0x22000000
139 + mov r3, #0x42000000
140 + mov r11, #0x80
141 + strb r11, [r3, #0xc]
142 + mov r11, #0x0
143 + strb r11, [r3, #0x4]
144 +#ifndef CONFIG_SL3516_ASIC
145 + mov r11, #0x9C /*0x9c->19200 0x4E->38400 0x34->57600 */
146 +#else
147 + mov r11, #0x9C /* 0x61 for 30MHz on GeminiA chip*/
148 +#endif
149 + strb r11, [r3, #0x0]
150 + mov r11, #0x03
151 + strb r11, [r3, #0xc]
152 + mov r11, #0xFB
153 + strb r11, [r3, #0x18]
154 +#endif
155 +/*****************************************************************************/
156 b 1f
157 .word 0x016f2818 @ Magic numbers to help the loader
158 .word start @ absolute load/run zImage address
159 @@ -458,6 +490,39 @@
160 mcr p15, 0, r0, c7, c5, 4 @ ISB
161 mov pc, r12
162
163 +/*****************************************************************************
164 + * for Storlink Soc -- CPU cache
165 + *****************************************************************************/
166 +__fa526_cache_on:
167 + mov r12, lr
168 + bl __setup_mmu
169 + mov r0, #0
170 + mcr p15, 0, r0, c7, c6, 0 @ Invalidate D cache
171 + mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache
172 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
173 + mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
174 + mcr p15, 0, r3, c2, c0, 0 @ load page table pointer
175 + mov r0, #-1
176 + mcr p15, 0, r0, c3, c0, 0 @ load domain access register
177 + mrc p15, 0, r0, c1, c0, 0
178 + mov r0, r0
179 + mov r0, r0
180 +#ifndef CONFIG_CPU_DCACHE_DISABLE
181 + orr r0, r0, #0x0004 @ .... .... .... .1..
182 +#endif
183 +#ifndef CONFIG_CPU_ICACHE_DISABLE
184 + orr r0, r0, #0x1000 @ ...1 .... .... ....
185 +#endif
186 +
187 +#ifndef DEBUG
188 + orr r0, r0, #0x0039 @ Write buffer, mmu
189 +#endif
190 + mcr p15, 0, r0, c1, c0
191 + mov r0, r0
192 + mov r0, r0
193 + mov pc, r12
194 +/********************************************************************************/
195 +
196 __arm6_mmu_cache_on:
197 mov r12, lr
198 bl __setup_mmu
199 @@ -625,6 +690,16 @@
200
201 @ These match on the architecture ID
202
203 +/*****************************************************************************
204 + * for Storlink Soc -- CPU architecture ID
205 + *****************************************************************************/
206 + .word 0x66015261 @ FA526
207 + .word 0xff01fff1
208 + b __fa526_cache_on
209 + b __fa526_cache_off
210 + b __fa526_cache_flush
211 +/*****************************************************************************/
212 +
213 .word 0x00020000 @ ARMv4T
214 .word 0x000f0000
215 b __armv4_mmu_cache_on
216 @@ -712,6 +787,23 @@
217 mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB
218 mov pc, r12
219
220 +/*****************************************************************************
221 + * for Storlink Soc -- CPU cache
222 + *****************************************************************************/
223 +__fa526_cache_off:
224 + mrc p15, 0, r0, c1, c0
225 + bic r0, r0, #0x000d
226 + mov r1, #0
227 + mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache
228 + mcr p15, 0, r1, c7, c10, 4 @ drain WB
229 + mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
230 + mov r0, #0
231 + mcr p15, 0, r0, c7, c5, 0 @ invalidate whole cache v4
232 + mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB v4
233 + mov pc, lr
234 +/*****************************************************************************/
235 +
236 +
237 __arm6_mmu_cache_off:
238 mov r0, #0x00000030 @ ARM6 control reg.
239 b __armv3_mmu_cache_off
240 @@ -759,6 +851,17 @@
241 mcr p15, 0, ip, c7, c10, 4 @ drain WB
242 mov pc, lr
243
244 +/*****************************************************************************
245 + * for Storlink Soc -- CPU cache
246 + *****************************************************************************/
247 +__fa526_cache_flush:
248 + mov r1, #0
249 + mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache
250 + mcr p15, 0, r1, c7, c5, 0 @ flush I cache
251 + mcr p15, 0, r1, c7, c10, 4 @ drain WB
252 + mov pc, lr
253 +/*****************************************************************************/
254 +
255
256 __armv6_mmu_cache_flush:
257 mov r1, #0
258 Index: linux-2.6.23.16/arch/arm/boot/compressed/it8712.h
259 ===================================================================
260 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
261 +++ linux-2.6.23.16/arch/arm/boot/compressed/it8712.h 2008-03-13 17:48:24.508798285 +0200
262 @@ -0,0 +1,25 @@
263 +
264 +#ifndef __IT8712_H__
265 +#define __IT8712_H__
266 +
267 +#include "asm/arch/sl2312.h"
268 +
269 +#define IT8712_IO_BASE SL2312_LPC_IO_BASE
270 +//#define IT8712_IO_BASE 0x27000000
271 +// Device LDN
272 +#define LDN_SERIAL1 0x01
273 +#define LDN_SERIAL2 0x02
274 +#define LDN_PARALLEL 0x03
275 +#define LDN_KEYBOARD 0x05
276 +#define LDN_MOUSE 0x06
277 +#define LDN_GPIO 0x07
278 +
279 +#define IT8712_UART1_PORT 0x3F8
280 +#define IT8712_UART2_PORT 0x2F8
281 +
282 +#define IT8712_GPIO_BASE 0x800 // 0x800-0x804 for GPIO set1-set5
283 +
284 +void LPCSetConfig(char LdnNumber, char Index, char data);
285 +char LPCGetConfig(char LdnNumber, char Index);
286 +
287 +#endif
288 Index: linux-2.6.23.16/arch/arm/boot/compressed/misc.c
289 ===================================================================
290 --- linux-2.6.23.16.orig/arch/arm/boot/compressed/misc.c 2008-03-13 17:46:04.500819685 +0200
291 +++ linux-2.6.23.16/arch/arm/boot/compressed/misc.c 2008-03-13 17:48:24.508798285 +0200
292 @@ -30,7 +30,7 @@
293 #include <asm/arch/uncompress.h>
294
295 #ifdef CONFIG_DEBUG_ICEDCC
296 -
297 +#include "it8712.h"
298 #ifdef CONFIG_CPU_V6
299
300 static void icedcc_putc(int ch)
301 @@ -69,6 +69,7 @@
302 #define flush() do { } while (0)
303 #endif
304
305 +#if 0
306 static void putstr(const char *ptr)
307 {
308 char c;
309 @@ -81,11 +82,36 @@
310
311 flush();
312 }
313 +#endif
314
315 #endif
316
317 #define __ptr_t void *
318
319 +#ifdef CONFIG_SERIAL_IT8712
320 +unsigned int it8712_uart_base;
321 +#define UART_RX 0
322 +#define UART_TX 0
323 +#define UART_DLL 0
324 +#define UART_TRG 0
325 +#define UART_DLM 1
326 +#define UART_IER 1
327 +#define UART_FCTR 1
328 +#define UART_IIR 2
329 +#define UART_FCR 2
330 +#define UART_EFR 2
331 +#define UART_LCR 3
332 +#define UART_MCR 4
333 +#define UART_LSR 5
334 +#define UART_MSR 6
335 +#define UART_SCR 7
336 +#define UART_EMSR 7
337 +void LPCEnterMBPnP(void);
338 +void LPCExitMBPnP(void);
339 +int SearchIT8712(void);
340 +int InitLPCInterface(void);
341 +#endif
342 +
343 /*
344 * Optimised C version of memzero for the ARM.
345 */
346 @@ -346,6 +372,9 @@
347 decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
348 int arch_id)
349 {
350 +#ifdef CONFIG_SERIAL_IT8712
351 + unsigned char *addr;
352 +#endif
353 output_data = (uch *)output_start; /* Points to kernel start */
354 free_mem_ptr = free_mem_ptr_p;
355 free_mem_ptr_end = free_mem_ptr_end_p;
356 @@ -353,6 +382,33 @@
357
358 arch_decomp_setup();
359
360 +#ifdef CONFIG_SERIAL_IT8712
361 +
362 + InitLPCInterface();
363 + LPCSetConfig(0, 0x02, 0x01);
364 + LPCSetConfig(LDN_SERIAL1, 0x30, 0x1);
365 + LPCSetConfig(LDN_SERIAL1, 0x23, 0x0);
366 + it8712_uart_base = IT8712_IO_BASE;
367 + it8712_uart_base += ((LPCGetConfig(LDN_SERIAL1, 0x60) << 8) + LPCGetConfig(LDN_SERIAL1, 0x61));
368 +
369 + do {
370 + addr = (unsigned char *)(it8712_uart_base + UART_LCR) ;
371 + *addr = 0x80;
372 + // Set Baud Rate
373 + addr = (unsigned char *)(it8712_uart_base+UART_DLL);
374 + *addr = 0x06 ;
375 + addr = (unsigned char *)(it8712_uart_base+UART_DLM);
376 + *addr = 0x00 ;
377 +
378 + addr = (unsigned char *)(it8712_uart_base+UART_LCR); // LCR
379 + *addr = 0x07 ;
380 + addr = (unsigned char *)(it8712_uart_base+UART_MCR); // MCR
381 + *addr = 0x08 ;
382 + addr = (unsigned char *)(it8712_uart_base+UART_FCR); // FCR
383 + *addr = 0x01 ;
384 + } while(0);
385 +#endif
386 +
387 makecrc();
388 putstr("Uncompressing Linux...");
389 gunzip();
390 @@ -374,4 +430,119 @@
391 return 0;
392 }
393 #endif
394 +
395 +#ifdef CONFIG_SERIAL_IT8712
396 +
397 +#define LPC_KEY_ADDR (unsigned char *)(SL2312_LPC_IO_BASE + 0x2e)
398 +#define LPC_DATA_ADDR (unsigned char *)(SL2312_LPC_IO_BASE + 0x2f)
399 +#define LPC_BUS_CTRL *( unsigned char*) (SL2312_LPC_HOST_BASE + 0)
400 +#define LPC_BUS_STATUS *( unsigned char*) (SL2312_LPC_HOST_BASE + 2)
401 +#define LPC_SERIAL_IRQ_CTRL *( unsigned char*) (SL2312_LPC_HOST_BASE + 4)
402 +
403 +char LPCGetConfig(char LdnNumber, char Index)
404 +{
405 + char rtn;
406 + unsigned char *addr ;
407 +
408 + LPCEnterMBPnP(); // Enter IT8712 MB PnP mode
409 +
410 + addr = LPC_KEY_ADDR;
411 + *addr = 0x07 ;
412 +
413 + addr = LPC_DATA_ADDR;
414 + *addr = LdnNumber ;
415 +
416 + addr = LPC_KEY_ADDR;
417 + *addr = Index ;
418 +
419 + addr = LPC_DATA_ADDR ;
420 + rtn = *addr ;
421 +
422 + LPCExitMBPnP();
423 + return rtn;
424 +
425 +}
426 +
427 +void LPCSetConfig(char LdnNumber, char Index, char data)
428 +{
429 + unsigned char *addr;
430 + LPCEnterMBPnP(); // Enter IT8712 MB PnP mode
431 + addr = LPC_KEY_ADDR;
432 + *addr = 0x07;
433 + addr = LPC_DATA_ADDR;
434 + *addr = LdnNumber;
435 + addr = LPC_KEY_ADDR;
436 + *addr = Index;
437 + addr = LPC_DATA_ADDR;
438 + *addr = data;
439 +
440 + LPCExitMBPnP();
441 +}
442 +
443 +//unsigned char key[4] ;
444 +void LPCEnterMBPnP(void)
445 +{
446 + unsigned char *addr;
447 + addr = LPC_KEY_ADDR;
448 + unsigned char key[4] = {0x87, 0x01, 0x55, 0x55};
449 +
450 + do {
451 + *addr = key[0];
452 + *addr = key[1];
453 + *addr = key[2];
454 + *addr = key[3];
455 + }while(0);
456 +}
457 +
458 +void LPCExitMBPnP(void)
459 +{
460 + unsigned char *addr;
461 + addr = LPC_KEY_ADDR;
462 + *addr = 0x02 ;
463 +
464 + addr = LPC_DATA_ADDR;
465 + *addr = 0x02 ;
466 +}
467 +
468 +int InitLPCInterface(void)
469 +{
470 + int i;
471 + LPC_BUS_CTRL = 0xc0;
472 + LPC_SERIAL_IRQ_CTRL = 0xc0;
473 +
474 + for(i=0;i<0x2000;i++) ;
475 +
476 + LPC_SERIAL_IRQ_CTRL = 0x80;
477 + if (!SearchIT8712()) ;
478 +// while(1);
479 + return 0;
480 +}
481 +
482 +int SearchIT8712(void)
483 +{
484 + unsigned char Id1, Id2;
485 + unsigned short Id;
486 + unsigned char *addr;
487 +
488 + LPCEnterMBPnP();
489 + addr = LPC_KEY_ADDR;
490 + *addr = 0x20 ;
491 + addr = LPC_DATA_ADDR;
492 + Id1 = *addr ;
493 +
494 + addr = LPC_KEY_ADDR;
495 + *addr = 0x21 ;
496 + addr = LPC_DATA_ADDR;
497 + Id2 = *addr ;
498 +
499 + Id = (Id1 << 8) | Id2;
500 + LPCExitMBPnP();
501 +
502 + if (Id == 0x8712)
503 + return 1;
504 + else
505 + return 0;
506 +}
507 +
508 +#endif
509
510 Index: linux-2.6.23.16/arch/arm/kernel/entry-armv.S
511 ===================================================================
512 --- linux-2.6.23.16.orig/arch/arm/kernel/entry-armv.S 2008-03-13 17:46:04.500819685 +0200
513 +++ linux-2.6.23.16/arch/arm/kernel/entry-armv.S 2008-03-13 17:48:24.508798285 +0200
514 @@ -18,6 +18,8 @@
515 #include <asm/memory.h>
516 #include <asm/glue.h>
517 #include <asm/vfpmacros.h>
518 +#include <asm/arch/irqs.h>
519 +#include <asm/hardware.h>
520 #include <asm/arch/entry-macro.S>
521 #include <asm/thread_notify.h>
522
523 Index: linux-2.6.23.16/arch/arm/kernel/irq.c
524 ===================================================================
525 --- linux-2.6.23.16.orig/arch/arm/kernel/irq.c 2008-03-13 17:46:04.500819685 +0200
526 +++ linux-2.6.23.16/arch/arm/kernel/irq.c 2008-03-13 17:48:24.508798285 +0200
527 @@ -40,6 +40,8 @@
528 #include <asm/system.h>
529 #include <asm/mach/time.h>
530
531 +extern int fixup_irq(unsigned int irq);
532 +
533 /*
534 * No architecture-specific irq_finish function defined in arm/arch/irqs.h.
535 */
536 @@ -111,8 +113,11 @@
537 asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
538 {
539 struct pt_regs *old_regs = set_irq_regs(regs);
540 - struct irq_desc *desc = irq_desc + irq;
541 +// struct irq_desc *desc = irq_desc + irq;
542 + struct irq_desc *desc;
543
544 + irq = fixup_irq(irq);
545 + desc = irq_desc + irq;
546 /*
547 * Some hardware gives randomly wrong interrupts. Rather
548 * than crashing, do something sensible.
549 Index: linux-2.6.23.16/arch/arm/kernel/process.c
550 ===================================================================
551 --- linux-2.6.23.16.orig/arch/arm/kernel/process.c 2008-03-13 17:46:04.500819685 +0200
552 +++ linux-2.6.23.16/arch/arm/kernel/process.c 2008-03-13 17:48:24.508798285 +0200
553 @@ -117,7 +117,7 @@
554 void (*pm_idle)(void);
555 EXPORT_SYMBOL(pm_idle);
556
557 -void (*pm_power_off)(void);
558 +//void (*pm_power_off)(void);
559 EXPORT_SYMBOL(pm_power_off);
560
561 void (*arm_pm_restart)(char str) = arm_machine_restart;
562 @@ -188,13 +188,37 @@
563
564 void machine_halt(void)
565 {
566 + unsigned int reg_v;
567 +
568 + printk("arch_power_off\n");
569 +
570 + reg_v = readl(IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04);
571 + reg_v &= ~0x00000002;
572 + reg_v |= 0x1;
573 + mdelay(5);
574 + // Power off
575 + __raw_writel( reg_v, IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04);
576 +
577 }
578
579
580 void machine_power_off(void)
581 {
582 - if (pm_power_off)
583 + unsigned int reg_v;
584 +
585 +// if (pm_power_off)
586 + if (&pm_power_off!=NULL)
587 pm_power_off();
588 +
589 + printk("arch_power_off\n");
590 +
591 + reg_v = readl(IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04);
592 + reg_v &= ~0x00000002;
593 + reg_v |= 0x1;
594 + mdelay(5);
595 + // Power off
596 + __raw_writel( reg_v, IO_ADDRESS(SL2312_POWER_CTRL_BASE) + 0x04);
597 +
598 }
599
600 void machine_restart(char * __unused)
601 Index: linux-2.6.23.16/arch/arm/kernel/time.c
602 ===================================================================
603 --- linux-2.6.23.16.orig/arch/arm/kernel/time.c 2008-03-13 17:46:04.500819685 +0200
604 +++ linux-2.6.23.16/arch/arm/kernel/time.c 2008-03-13 17:48:24.508798285 +0200
605 @@ -502,8 +502,13 @@
606
607 device_initcall(timer_init_sysfs);
608
609 +extern unsigned int rtc_get_time_second(void);
610 +
611 void __init time_init(void)
612 {
613 +#ifdef CONFIG_SL2312_RTC
614 + xtime.tv_sec = rtc_get_time_second() ;
615 +#endif
616 #ifndef CONFIG_GENERIC_TIME
617 if (system_timer->offset == NULL)
618 system_timer->offset = dummy_gettimeoffset;
619 Index: linux-2.6.23.16/arch/arm/mach-sl2312/Kconfig
620 ===================================================================
621 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
622 +++ linux-2.6.23.16/arch/arm/mach-sl2312/Kconfig 2008-03-13 17:48:24.508798285 +0200
623 @@ -0,0 +1,33 @@
624 +
625 +menu "SL2312"
626 +
627 +config SL3516_ASIC
628 + bool "SL3516 ASIC version"
629 + depends on ARCH_SL2312
630 + help
631 + This option to select AISC or FPGA
632 +config PCI
633 + bool "SL2312 PCI"
634 + depends on ARCH_SL2312
635 + help
636 + This option to enable Storlink PCI controller
637 +
638 +config SL2312_LPC
639 + bool "SL2312 LPC"
640 + depends on ARCH_SL2312
641 + help
642 + This option to enable Low Pin Count controller
643 +
644 +config SL2312_USB
645 + bool "SL2312 USB"
646 + depends on ARCH_SL2312
647 + help
648 + This option to enable USB OTG host controller
649 +
650 +config GEMINI_IPI
651 + bool "Gemini IPI test"
652 + depends on ARCH_SL2312
653 + help
654 + Enable this option to test dual cpu Inter-Processor-Interrupt
655 +endmenu
656 +
657 Index: linux-2.6.23.16/arch/arm/mach-sl2312/Makefile
658 ===================================================================
659 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
660 +++ linux-2.6.23.16/arch/arm/mach-sl2312/Makefile 2008-03-13 17:48:24.508798285 +0200
661 @@ -0,0 +1,16 @@
662 +#
663 +# Makefile for the linux kernel.
664 +#
665 +
666 +# Object file lists.
667 +
668 +obj-y := arch.o irq.o mm.o time.o sl3516_device.o
669 +obj-m :=
670 +obj-n :=
671 +
672 +
673 +obj-$(CONFIG_PCI) += pci.o
674 +obj-$(CONFIG_SL2312_LPC) += lpc.o
675 +obj-$(CONFIG_SL2312_USB) += sl2312-otg.o # sl2312-otg-1.o
676 +obj-$(CONFIG_GEMINI_XOR_ACCE) += xor.o
677 +obj-$(CONFIG_GEMINI_IPI) += gemini_ipi.o
678 Index: linux-2.6.23.16/arch/arm/mach-sl2312/Makefile.boot
679 ===================================================================
680 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
681 +++ linux-2.6.23.16/arch/arm/mach-sl2312/Makefile.boot 2008-03-13 17:48:24.508798285 +0200
682 @@ -0,0 +1,5 @@
683 + zreladdr-y := 0x00008000
684 +params_phys-y := 0x00508100
685 +#params_phys-y := 0x00008100
686 +initrd_phys-y := 0x00800000
687 +
688 Index: linux-2.6.23.16/arch/arm/mach-sl2312/arch.c
689 ===================================================================
690 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
691 +++ linux-2.6.23.16/arch/arm/mach-sl2312/arch.c 2008-03-13 17:48:24.508798285 +0200
692 @@ -0,0 +1,72 @@
693 +/*
694 + * linux/arch/arm/mach-epxa10db/arch.c
695 + *
696 + * Copyright (C) 2000 Deep Blue Solutions Ltd
697 + * Copyright (C) 2001 Altera Corporation
698 + *
699 + * This program is free software; you can redistribute it and/or modify
700 + * it under the terms of the GNU General Public License as published by
701 + * the Free Software Foundation; either version 2 of the License, or
702 + * (at your option) any later version.
703 + *
704 + * This program is distributed in the hope that it will be useful,
705 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
706 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
707 + * GNU General Public License for more details.
708 + *
709 + * You should have received a copy of the GNU General Public License
710 + * along with this program; if not, write to the Free Software
711 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
712 + */
713 +#include <linux/types.h>
714 +#include <linux/init.h>
715 +
716 +#include <asm/hardware.h>
717 +#include <asm/setup.h>
718 +#include <asm/mach-types.h>
719 +#include <asm/mach/time.h>
720 +#include <asm/mach/arch.h>
721 +
722 +extern void sl2312_map_io(void);
723 +extern void sl2312_init_irq(void);
724 +extern unsigned long sl2312_gettimeoffset (void);
725 +extern void __init sl2312_time_init(void);
726 +
727 +static struct sys_timer sl2312_timer = {
728 + .init = sl2312_time_init,
729 + .offset = sl2312_gettimeoffset,
730 +};
731 +
732 +static void __init
733 +sl2312_fixup(struct machine_desc *desc, struct tag *tags,
734 + char **cmdline, struct meminfo *mi)
735 +{
736 + mi->nr_banks = 1;
737 + mi->bank[0].start = 0;
738 +#ifdef CONFIG_GEMINI_IPI
739 + mi->bank[0].size = (64*1024*1024); // 128M
740 +#else
741 + mi->bank[0].size = (128*1024*1024); // 128M
742 +#endif
743 + mi->bank[0].node = 0;
744 +}
745 +
746 +/* MACHINE_START(SL2312, "GeminiA")
747 + MAINTAINER("Storlink Semi")
748 + BOOT_MEM(0x00000000, 0x90000000, 0xf0000000)
749 + FIXUP(sl2312_fixup)
750 + MAPIO(sl2312_map_io)
751 + INITIRQ(sl2312_init_irq)
752 + .timer = &sl2312_timer,
753 +MACHINE_END */
754 +
755 +MACHINE_START(SL2312, "GeminiA")
756 + /* .phys_ram = 0x00000000, */
757 + .phys_io = 0x7fffc000,
758 + .io_pg_offst = ((0xffffc000) >> 18) & 0xfffc,
759 + .boot_params = 0x100,
760 + .fixup = sl2312_fixup,
761 + .map_io = sl2312_map_io,
762 + .init_irq = sl2312_init_irq,
763 + .timer = &sl2312_timer,
764 +MACHINE_END
765 Index: linux-2.6.23.16/arch/arm/mach-sl2312/gemini_ipi.c
766 ===================================================================
767 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
768 +++ linux-2.6.23.16/arch/arm/mach-sl2312/gemini_ipi.c 2008-03-15 16:53:01.339687322 +0200
769 @@ -0,0 +1,593 @@
770 +/*
771 + * FILE NAME sl_cir.c
772 + *
773 + * BRIEF MODULE DESCRIPTION
774 + * IPI Driver for CPU1.
775 + *
776 + * Author: StorLink, Corp.
777 + * Jason Lee
778 + *
779 + * Copyright 2002~2006 StorLink, Corp.
780 + *
781 + * This program is free software; you can redistribute it and/or modify it
782 + * under the terms of the GNU General Public License as published by the
783 + * Free Software Foundation; either version 2 of the License, or (at your
784 + * option) any later version.
785 + *
786 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
787 + * WARRANTIES, INCLUDING, BUT NOT LIMit8712D TO, THE IMPLIED WARRANTIES OF
788 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
789 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
790 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
791 + * NOT LIMit8712D TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
792 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
793 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
794 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
795 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
796 + *
797 + * You should have received a copy of the GNU General Public License along
798 + * with this program; if not, writ8712 to the Free Software Foundation, Inc.,
799 + * 675 Mass Ave, Cambridge, MA 02139, USA.
800 + */
801 +
802 +#include <linux/module.h>
803 +#include <linux/types.h>
804 +#include <linux/kernel.h>
805 +#include <linux/miscdevice.h>
806 +#include <linux/init.h>
807 +#include <linux/pagemap.h>
808 +#include <asm/uaccess.h>
809 +#include <linux/ioport.h>
810 +#include <linux/sched.h>
811 +#include <linux/delay.h>
812 +#include <linux/fs.h>
813 +#include <linux/interrupt.h>
814 +#include <asm/io.h>
815 +#include <asm/delay.h>
816 +#include <linux/signal.h>
817 +#include <asm/arch/sl2312.h>
818 +#include <asm/arch/int_ctrl.h>
819 +#include <asm/arch/ipi.h>
820 +#include <linux/dma-mapping.h>
821 +
822 +
823 +#include <linux/mm.h>
824 +
825 +#include <linux/bootmem.h>
826 +
827 +#include <asm/hardware.h>
828 +#include <asm/page.h>
829 +#include <asm/setup.h>
830 +#include <asm/pgtable.h>
831 +#include <asm/pgalloc.h>
832 +
833 +#include <asm/mach/map.h>
834 +
835 +
836 +static int sl_ipi_debug = 1 ;
837 +#define DEB(x) if(sl_ipi_debug>=1) x
838 +
839 +#define SRAM_PTR IO_ADDRESS(SL2312_SRAM_BASE)
840 +volatile JSCALE_REQ_T *req=(JSCALE_REQ_T*)SRAM_PTR;
841 +volatile JSCALE_RSP_T *rsp=(JSCALE_RSP_T*)(SRAM_PTR+0x20);
842 +
843 +unsigned int jscale_status=0;
844 +
845 +#define JSCALE_WAIT 0
846 +#define XXXXXX_WAIT 1
847 +#define MAX_WAIT_Q 8
848 +wait_queue_head_t gemini_ipi_wait[MAX_WAIT_Q];
849 +
850 +#define DRAMCTL_DMA_CTL 0X20
851 +#define DRAMCTL_DMA_SA 0X24
852 +#define DRAMCTL_DMA_DA 0X28
853 +#define DRAMCTL_DMA_CNT 0X2C
854 +#define MEMCPY_UNIT 0x40000
855 +int hw_memcpy(const void *to, const void *from, unsigned int bytes)
856 +{
857 + unsigned int reg_a,reg_d;
858 + int count = bytes,i=0;
859 +
860 + consistent_sync((unsigned int *)to, bytes, DMA_BIDIRECTIONAL);
861 + consistent_sync((unsigned int *)from,bytes, DMA_TO_DEVICE);
862 +
863 + DEB(printk("hwmemcpy:count %d\n",count));
864 + while(count>0){
865 + // SA
866 + reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_SA;
867 + reg_d = (unsigned int )__virt_to_phys(from) + i*MEMCPY_UNIT;
868 + DEB(printk("hwmemcpy:from 0x%08x\n",reg_d));
869 + writel(reg_d,reg_a);
870 + // DA
871 + reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_DA;
872 + reg_d = (unsigned int )__virt_to_phys(to) + i*MEMCPY_UNIT;
873 + writel(reg_d,reg_a);
874 + DEB(printk("hwmemcpy:to 0x%08x\n",reg_d));
875 + // byte count
876 + reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_CNT;
877 + reg_d = (count>=MEMCPY_UNIT)?MEMCPY_UNIT:count;
878 + writel(reg_d,reg_a);
879 + // start DMA
880 + reg_a = IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_CTL;
881 + writel(0x80000001,reg_a);
882 +
883 + do{
884 + cond_resched();
885 +// msleep(4);
886 + reg_d = readl(IO_ADDRESS(SL2312_DRAM_CTRL_BASE)+DRAMCTL_DMA_CTL);
887 + }while(reg_d&0x1);
888 +
889 + count -= MEMCPY_UNIT;
890 + i++;
891 + }
892 +
893 + return bytes;
894 +}
895 +
896 +static irqreturn_t ipi_interrupt()
897 +{
898 + unsigned int id=getcpuid(),tmp;
899 +
900 + //dmac_inv_range(__phys_to_virt(SL2312_SRAM_BASE),__phys_to_virt(SHAREADDR)+0x2000);
901 +
902 +
903 + // Clear Interrupt
904 + if(id==CPU0) {
905 + tmp = readl(CPU1_STATUS);
906 + tmp &= ~CPU_IPI_BIT_MASK;
907 + writel(tmp,CPU1_STATUS);
908 + }
909 + else{
910 + tmp = readl(CPU0_STATUS);
911 + tmp &= ~CPU_IPI_BIT_MASK;
912 + writel(tmp,CPU0_STATUS);
913 + }
914 +
915 + //
916 + DEB(printk("ipi interrupt:0x%x\n",rsp->status));
917 + switch(rsp->status){
918 + case JSCALE_STATUS_OK:
919 +
920 + break;
921 + case JSCALE_UNKNOWN_MSG_TYPE:
922 +
923 + break;
924 + case JSCALE_FAILED_FILE_SIZE:
925 +
926 + break;
927 + case JSCALE_FAILED_MALLOC:
928 +
929 + break;
930 + case JSCALE_FAILED_FORMAT:
931 +
932 + break;
933 + case JSCALE_DECODE_ERROR:
934 +
935 + break;
936 +
937 + }
938 + jscale_status = rsp->status;
939 +// wake_up(&gemini_ipi_wait[JSCALE_WAIT]);
940 +
941 + return IRQ_HANDLED;
942 +}
943 +
944 +static int gemini_ipi_open(struct inode *inode, struct file *file)
945 +{
946 + DEB(printk("ipi open\n"));
947 + return 0;
948 +}
949 +
950 +
951 +static int gemini_ipi_release(struct inode *inode, struct file *file)
952 +{
953 + DEB(printk("ipi release\n"));
954 + return 0;
955 +}
956 +
957 +
958 +static int gemini_ipi_ioctl(struct inode *inode, struct file *file,
959 + unsigned int cmd, unsigned long arg)
960 +{
961 + JSCALE_RSP_T tmp;
962 +
963 + switch(cmd) {
964 + case GEMINI_IPI_JSCALE_REQ:
965 + DEB(printk("ipi:ioctl jscale request %dX%d Q:%d\n",req->ScaledImageWidth,req->ScaledImageHeight,req->ScaledImageQuality));
966 + if (copy_from_user(req, (JSCALE_REQ_T *)arg, sizeof(JSCALE_REQ_T)))
967 + return -EFAULT;
968 + req->hdr.type = IPC_JSCALE_REQ_MSG;
969 + req->hdr.length = sizeof(JSCALE_REQ_T);
970 + req->input_location = CPU_1_DATA_OFFSET;
971 + req->output_location = CPU_1_DATA_OFFSET;
972 + break;
973 + case GEMINI_IPI_JSCALE_STAT:
974 + DEB(printk("ipi:ioctl jscale stat \n"));
975 + if(jscale_status==JSCALE_BUSY){ // not yet
976 + tmp.status = JSCALE_BUSY;
977 + if (copy_to_user((JSCALE_RSP_T *)arg,&tmp, sizeof(JSCALE_RSP_T)))
978 + return -EFAULT;
979 + }
980 + else{ // finish or error
981 + if (copy_to_user((JSCALE_RSP_T *)arg,rsp, sizeof(JSCALE_RSP_T)))
982 + return -EFAULT;
983 + }
984 + break;
985 + default:
986 + printk("IPI: Error IOCTL number\n");
987 + return -ENOIOCTLCMD;
988 + }
989 +
990 + return 0;
991 +}
992 +
993 +#define SRAM_SIZE 0x2000
994 +static ssize_t gemini_ipi_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos)
995 +{
996 + int i=0,tmp=0,j;
997 + const char *ptr=(unsigned int)__phys_to_virt(CPU_1_MEM_BASE+CPU_1_DATA_OFFSET);
998 + DEB(printk("ipi:write 0x%x to 0x%x length:%d\n",&buf,ptr,count));
999 + memcpy(ptr,buf,count);
1000 + consistent_sync(ptr,count, DMA_TO_DEVICE);
1001 + //hw_memcpy(ptr,&buf,count);
1002 +
1003 +/* if(count>SRAM_SIZE){
1004 + for(i=0;i<(count/SRAM_SIZE);i++)
1005 + raid_memcpy(ptr+i*SRAM_SIZE,buf+i*SRAM_SIZE,SRAM_SIZE);
1006 + if(count%SRAM_SIZE)
1007 + raid_memcpy(ptr+i*SRAM_SIZE,buf+i*SRAM_SIZE,count%SRAM_SIZE);
1008 + }
1009 + else
1010 + raid_memcpy(ptr,buf,count);
1011 +*/
1012 +
1013 +/* for(i=0;i<count;i++){
1014 + if(buf[i]!=ptr[i])
1015 + printk("ipi error:offset %d valud %x[should %x]\n",i,ptr[i],buf[i]);
1016 + }
1017 +
1018 + printk("===========input buf===============\n");
1019 + for(i=0;i<64;i+=16){
1020 + for(j=0;j<16;j++)
1021 + printk("%02x ",buf[i+j]);
1022 + printk("\n");
1023 + cond_resched();
1024 + }
1025 + printk("===========output buf==============\n");
1026 + for(i=0;i<64;i+=16){
1027 + for(j=0;j<16;j++)
1028 + printk("%02x ",ptr[i+j]);
1029 + printk("\n");
1030 + cond_resched();
1031 + }
1032 +*/
1033 + // send irq for CPU1
1034 + tmp |= CPU_IPI_BIT_MASK;
1035 + writel(tmp,CPU0_STATUS);
1036 + jscale_status = JSCALE_BUSY;
1037 +
1038 + return count;
1039 +}
1040 +
1041 +static ssize_t gemini_ipi_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
1042 +{
1043 + int i=0;
1044 + const char *ptr=(unsigned int )__phys_to_virt(CPU_1_MEM_BASE+CPU_1_DATA_OFFSET);
1045 +
1046 + consistent_sync(ptr,length, DMA_FROM_DEVICE);
1047 + memcpy(buf,ptr,length);
1048 + DEB(printk("ipi:read 0x%x to 0x%x length:%d\n",ptr,buf,length));
1049 +
1050 + //consistent_sync((unsigned int *)ptr,0x2000, DMA_FROM_DEVICE); // invalid
1051 + //hw_memcpy(buf,ptr,length);
1052 +
1053 + // need encoded file size ********
1054 +/* if(count>SRAM_SIZE){
1055 + for(i=0;i<(count/SRAM_SIZE);i++)
1056 + raid_memcpy(buf+i*SRAM_SIZE,p_mbox->message+i*SRAM_SIZE,SRAM_SIZE);
1057 + if(count%0xFFFF)
1058 + raid_memcpy(buf+i*SRAM_SIZE,p_mbox->message+i*SRAM_SIZE,length%SRAM_SIZE);
1059 + }
1060 + else
1061 + raid_memcpy(buf,p_mbox->message,length);
1062 +*/
1063 + return length;
1064 +}
1065 +
1066 +void do_mapping_read(struct address_space *mapping,
1067 + struct file_ra_state *_ra,
1068 + struct file *filp,
1069 + loff_t *ppos,
1070 + read_descriptor_t *desc,
1071 + read_actor_t actor)
1072 +{
1073 + struct inode *inode = mapping->host;
1074 + unsigned long index;
1075 + unsigned long end_index;
1076 + unsigned long offset;
1077 + unsigned long last_index;
1078 + unsigned long next_index;
1079 + unsigned long prev_index;
1080 + loff_t isize;
1081 + struct page *cached_page;
1082 + int error;
1083 + struct file_ra_state ra = *_ra;
1084 +
1085 + cached_page = NULL;
1086 + index = *ppos >> PAGE_CACHE_SHIFT;
1087 + next_index = index;
1088 + prev_index = ra.prev_page;
1089 + last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
1090 + offset = *ppos & ~PAGE_CACHE_MASK;
1091 +
1092 + isize = i_size_read(inode);
1093 + if (!isize)
1094 + goto out;
1095 +
1096 + end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
1097 + for (;;) {
1098 + struct page *page;
1099 + unsigned long nr, ret;
1100 +
1101 + /* nr is the maximum number of bytes to copy from this page */
1102 + nr = PAGE_CACHE_SIZE;
1103 + if (index >= end_index) {
1104 + if (index > end_index)
1105 + goto out;
1106 + nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
1107 + if (nr <= offset) {
1108 + goto out;
1109 + }
1110 + }
1111 + nr = nr - offset;
1112 +
1113 + cond_resched();
1114 + if (index == next_index)
1115 + next_index = page_cache_readahead(mapping, &ra, filp,
1116 + index, last_index - index);
1117 +
1118 +find_page:
1119 + page = find_get_page(mapping, index);
1120 + if (unlikely(page == NULL)) {
1121 + handle_ra_miss(mapping, &ra, index);
1122 + goto no_cached_page;
1123 + }
1124 + if (!PageUptodate(page))
1125 + goto page_not_up_to_date;
1126 +page_ok:
1127 +
1128 + /* If users can be writing to this page using arbitrary
1129 + * virtual addresses, take care about potential aliasing
1130 + * before reading the page on the kernel side.
1131 + */
1132 + if (mapping_writably_mapped(mapping))
1133 + flush_dcache_page(page);
1134 +
1135 + /*
1136 + * When (part of) the same page is read multiple times
1137 + * in succession, only mark it as accessed the first time.
1138 + */
1139 + if (prev_index != index)
1140 + mark_page_accessed(page);
1141 + prev_index = index;
1142 +
1143 + /*
1144 + * Ok, we have the page, and it's up-to-date, so
1145 + * now we can copy it to user space...
1146 + *
1147 + * The actor routine returns how many bytes were actually used..
1148 + * NOTE! This may not be the same as how much of a user buffer
1149 + * we filled up (we may be padding etc), so we can only update
1150 + * "pos" here (the actor routine has to update the user buffer
1151 + * pointers and the remaining count).
1152 + */
1153 + ret = actor(desc, page, offset, nr);
1154 + offset += ret;
1155 + index += offset >> PAGE_CACHE_SHIFT;
1156 + offset &= ~PAGE_CACHE_MASK;
1157 +
1158 + page_cache_release(page);
1159 + if (ret == nr && desc->count)
1160 + continue;
1161 + goto out;
1162 +
1163 +page_not_up_to_date:
1164 + /* Get exclusive access to the page ... */
1165 + lock_page(page);
1166 +
1167 + /* Did it get unhashed before we got the lock? */
1168 + if (!page->mapping) {
1169 + unlock_page(page);
1170 + page_cache_release(page);
1171 + continue;
1172 + }
1173 +
1174 + /* Did somebody else fill it already? */
1175 + if (PageUptodate(page)) {
1176 + unlock_page(page);
1177 + goto page_ok;
1178 + }
1179 +
1180 +readpage:
1181 + /* Start the actual read. The read will unlock the page. */
1182 + error = mapping->a_ops->readpage(filp, page);
1183 +
1184 + if (unlikely(error))
1185 + goto readpage_error;
1186 +
1187 + if (!PageUptodate(page)) {
1188 + lock_page(page);
1189 + if (!PageUptodate(page)) {
1190 + if (page->mapping == NULL) {
1191 + /*
1192 + * invalidate_inode_pages got it
1193 + */
1194 + unlock_page(page);
1195 + page_cache_release(page);
1196 + goto find_page;
1197 + }
1198 + unlock_page(page);
1199 + error = -EIO;
1200 + goto readpage_error;
1201 + }
1202 + unlock_page(page);
1203 + }
1204 +
1205 + /*
1206 + * i_size must be checked after we have done ->readpage.
1207 + *
1208 + * Checking i_size after the readpage allows us to calculate
1209 + * the correct value for "nr", which means the zero-filled
1210 + * part of the page is not copied back to userspace (unless
1211 + * another truncate extends the file - this is desired though).
1212 + */
1213 + isize = i_size_read(inode);
1214 + end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
1215 + if (unlikely(!isize || index > end_index)) {
1216 + page_cache_release(page);
1217 + goto out;
1218 + }
1219 +
1220 + /* nr is the maximum number of bytes to copy from this page */
1221 + nr = PAGE_CACHE_SIZE;
1222 + if (index == end_index) {
1223 + nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
1224 + if (nr <= offset) {
1225 + page_cache_release(page);
1226 + goto out;
1227 + }
1228 + }
1229 + nr = nr - offset;
1230 + goto page_ok;
1231 +
1232 +readpage_error:
1233 + /* UHHUH! A synchronous read error occurred. Report it */
1234 + desc->error = error;
1235 + page_cache_release(page);
1236 + goto out;
1237 +
1238 +no_cached_page:
1239 + /*
1240 + * Ok, it wasn't cached, so we need to create a new
1241 + * page..
1242 + */
1243 + if (!cached_page) {
1244 + cached_page = page_cache_alloc_cold(mapping);
1245 + if (!cached_page) {
1246 + desc->error = -ENOMEM;
1247 + goto out;
1248 + }
1249 + }
1250 + error = add_to_page_cache_lru(cached_page, mapping,
1251 + index, GFP_KERNEL);
1252 + if (error) {
1253 + if (error == -EEXIST)
1254 + goto find_page;
1255 + desc->error = error;
1256 + goto out;
1257 + }
1258 + page = cached_page;
1259 + cached_page = NULL;
1260 + goto readpage;
1261 + }
1262 +
1263 +out:
1264 + *_ra = ra;
1265 +
1266 + *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
1267 + if (cached_page)
1268 + page_cache_release(cached_page);
1269 + if (filp)
1270 + file_accessed(filp);
1271 +}
1272 +
1273 +int ipi_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
1274 +{
1275 + ssize_t written;
1276 + unsigned long count = desc->count;
1277 + struct file *file = desc->arg.data;
1278 + unsigned int *ptr_to=(unsigned int)__phys_to_virt(CPU_1_MEM_BASE+CPU_1_DATA_OFFSET) + desc->written;
1279 + void *ptr_from;
1280 +
1281 + if (size > count)
1282 + size = count;
1283 +
1284 + ptr_from = page_address(page)+offset;
1285 + written = memcpy(ptr_to,ptr_from,size);
1286 +
1287 + if (written < 0) {
1288 + desc->error = written;
1289 + written = 0;
1290 + }
1291 + desc->count = count - written;
1292 + desc->written += written;
1293 + return written;
1294 +}
1295 +
1296 +ssize_t gemini_ipi_sendfile(struct file *in_file, loff_t *ppos,
1297 + size_t count, read_actor_t actor, void *TARGET)
1298 +{
1299 + read_descriptor_t desc;
1300 +
1301 + if (!count)
1302 + return 0;
1303 +
1304 + desc.written = 0;
1305 + desc.count = count;
1306 + desc.arg.data = TARGET;
1307 + desc.error = 0;
1308 +
1309 + do_mapping_read(in_file->f_mapping,&in_file->f_ra,in_file, ppos, &desc, ipi_send_actor);
1310 +
1311 + if (desc.written)
1312 + return desc.written;
1313 + return desc.error;
1314 +}
1315 +static struct file_operations gemini_ipi_fops = {
1316 + .owner = THIS_MODULE,
1317 + .ioctl = gemini_ipi_ioctl,
1318 + .open = gemini_ipi_open,
1319 + .release= gemini_ipi_release,
1320 + .write = gemini_ipi_write,
1321 + .read = gemini_ipi_read,
1322 + .sendfile = gemini_ipi_sendfile,
1323 +};
1324 +
1325 +#ifndef STORLINK_IPI
1326 +#define STORLINK_IPI 242 // Documents/devices.txt suggest to use 240~255 for local driver!!
1327 +#endif
1328 +
1329 +static struct miscdevice gemini_ipi_miscdev =
1330 +{
1331 + STORLINK_IPI,
1332 + "slave_ipc",
1333 + &gemini_ipi_fops
1334 +};
1335 +
1336 +int __init sl_ipi_init(void)
1337 +{
1338 +
1339 + printk("Gemini IPI Driver Initialization...\n");
1340 + printk("REQ Head :0x%x(phy:0x%x)\n",(unsigned int)req,(unsigned int)SL2312_SRAM_BASE);
1341 + printk("RSP Head :0x%x(phy:0x%x)\n",(unsigned int)rsp,(unsigned int)SL2312_SRAM_BASE+0x20);
1342 + 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);
1343 +
1344 + misc_register(&gemini_ipi_miscdev);
1345 +
1346 + if (request_irq(IRQ_CPU0_IP_IRQ_OFFSET, ipi_interrupt, SA_INTERRUPT, "ipi", NULL))
1347 + printk("Error: Register IRQ for Storlink IPI failed\n");
1348 +
1349 + return 0;
1350 +}
1351 +
1352 +void __exit sl_ipi_exit(void)
1353 +{
1354 +
1355 +}
1356 +
1357 +module_init(sl_ipi_init);
1358 +module_exit(sl_ipi_exit);
1359 +
1360 +MODULE_AUTHOR("Jason Lee <jason@storlink.com.tw>");
1361 +MODULE_DESCRIPTION("Storlink IPI driver");
1362 +MODULE_LICENSE("GPL");
1363 Index: linux-2.6.23.16/arch/arm/mach-sl2312/hw_xor.h
1364 ===================================================================
1365 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1366 +++ linux-2.6.23.16/arch/arm/mach-sl2312/hw_xor.h 2008-03-13 17:48:24.508798285 +0200
1367 @@ -0,0 +1,573 @@
1368 +/*
1369 +* linux/include/asm-arm/xor.h
1370 +*
1371 +* Copyright (C) 2001 Storlink Semi.
1372 +* Jason Lee <jason@storlink.com.tw>
1373 +*
1374 +*/
1375 +#include <asm/arch/sl2312.h>
1376 +#include <asm/io.h>
1377 +//#include <linux/compatmac.h>
1378 +
1379 +#undef BIG_ENDIAN
1380 +#define CPU 0
1381 +#define DMA 1
1382 +
1383 +#define DESC_NO 8
1384 +#define TX_DESC_NUM DESC_NO
1385 +#define RX_DESC_NUM DESC_NO
1386 +
1387 +#define RAID_BASE_ADDR IO_ADDRESS(SL2312_RAID_BASE)
1388 +
1389 +#define SRAM_PAR_0k 0
1390 +#define SRAM_PAR_4k 1
1391 +#define SRAM_PAR_8k 2
1392 +#define SRAM_PAR_16k 3
1393 +#define SRAM_PAR_SIZE SRAM_PAR_8k
1394 +
1395 +#define RUNNING 0x1
1396 +#define COMPLETE 0x2
1397 +#define ERROR 0x4
1398 +
1399 +#define CMD_XOR 0x0
1400 +#define CMD_FILL 0x1
1401 +#define CMD_CPY 0x3
1402 +#define CMD_CHK 0x4
1403 +
1404 +enum RAID_DMA_REGISTER {
1405 + RAID_DMA_DEVICE_ID = 0xff00,
1406 + RAID_DMA_STATUS = 0xff04,
1407 + RAID_FCHDMA_CTRL = 0xff08,
1408 + RAID_FCHDMA_FIRST_DESC = 0xff0C,
1409 + RAID_FCHDMA_CURR_DESC = 0xff10,
1410 + RAID_STRDMA_CTRL = 0xff14,
1411 + RAID_STRDMA_FIRST_DESC = 0xff18,
1412 + RAID_STRDMA_CURR_DESC = 0xff1C,
1413 + RAID_TX_FLG_REG = 0xff24,
1414 + RAID_RX_FLG_REG = 0xff34,
1415 + RAID_PCR = 0xff50,
1416 + SMC_CMD_REG = 0xff60,
1417 + SMC_STATUS_REG = 0xff64
1418 + };
1419 +
1420 +enum RAID_FUNC_MODE {
1421 + RAID_XOR = 0,
1422 + RAID_MIX = 2,
1423 + RAID_SRAM = 3,
1424 + RAID_ENDIAN = 4,
1425 + RAID_MEM_BLK = 5,
1426 + RAID_MEM2MEM = 7,
1427 + RAID_BUF_SIZE = 8,
1428 + RAID_ERR_TEST = 9,
1429 + RAID_BURST = 10,
1430 + RAID_BUS = 11
1431 + };
1432 +
1433 +typedef struct reg_info {
1434 + int mask;
1435 + char err[32];
1436 + int offset;
1437 +} REG_INFO;
1438 +
1439 +/********************************************************/
1440 +/* the definition of RAID DMA Module Register */
1441 +/********************************************************/
1442 +typedef union
1443 +{
1444 + unsigned int bit32;
1445 + struct bits_ff00
1446 + {
1447 + #ifdef BIG_ENDIAN
1448 + unsigned int : 8;
1449 + unsigned int teytPerr : 4; /* define protocol error under tsPErrI*/
1450 + unsigned int reytPerr : 14; /* define protocol error under rsPErrI */
1451 + unsigned int device_id : 12;
1452 + unsigned int revision_id : 4;
1453 + #else
1454 + unsigned int revision_id : 4;
1455 + unsigned int device_id : 12;
1456 + unsigned int reytPerr : 14; /* define protocol error under rsPErrI */
1457 + unsigned int teytPerr : 4; /* define protocol error under tsPErrI*/
1458 + unsigned int : 8;
1459 + #endif
1460 + } bits;
1461 +} RAID_DMA_DEVICE_ID_T;
1462 +
1463 +typedef union
1464 +{
1465 + unsigned int bits32;
1466 + struct bits_ff04
1467 + {
1468 + #ifdef BIG_ENDIAN
1469 + unsigned int tsFinishI : 1; /* owner bit error interrupt */
1470 + unsigned int tsDErrI : 1; /* AHB bus error interrupt */
1471 + unsigned int tsPErrI : 1; /* RAID XOR fetch descriptor protocol error interrupt */
1472 + unsigned int tsEODI : 1; /* RAID XOR fetch DMA end of descriptor interrupt */
1473 + unsigned int tsEOFI : 1; /* RAID XOR fetch DMA end of frame interrupt */
1474 + unsigned int rsFinishI : 1; /* owner bit error interrupt */
1475 + unsigned int rsDErrI : 1; /* AHB bus error while RAID XOR store interrupt */
1476 + unsigned int rsPErrI : 1; /* RAID XOR store descriptor protocol error interrupt */
1477 + unsigned int rsEODI : 1; /* RAID XOR store DMA end of descriptor interrupt */
1478 + unsigned int rsEOFI : 1; /* RAID XOR store DMA end of frame interrupt */
1479 + unsigned int inter : 8; /* pattern check error interrupt */
1480 + unsigned int : 5;
1481 + unsigned int Loopback : 1; /* loopback */
1482 + unsigned int intEnable : 8; /*pattern check error interrupt enable */
1483 + #else
1484 + unsigned int intEnable : 8; /*pattern check error interrupt enable */
1485 + unsigned int Loopback : 1; /* loopback */
1486 + unsigned int : 5;
1487 + unsigned int inter : 8; /* pattern check error interrupt */
1488 + unsigned int rsEOFI : 1; /* RAID XOR store DMA end of frame interrupt */
1489 + unsigned int rsEODI : 1; /* RAID XOR store DMA end of descriptor interrupt */
1490 + unsigned int rsPErrI : 1; /* RAID XOR store descriptor protocol error interrupt */
1491 + unsigned int rsDErrI : 1; /* AHB bus error while RAID XOR store interrupt */
1492 + unsigned int rsFinishI : 1; /* owner bit error interrupt */
1493 + unsigned int tsEOFI : 1; /* RAID XOR fetch DMA end of frame interrupt */
1494 + unsigned int tsEODI : 1; /* RAID XOR fetch DMA end of descriptor interrupt */
1495 + unsigned int tsPErrI : 1; /* RAID XOR fetch descriptor protocol error interrupt */
1496 + unsigned int tsDErrI : 1; /* AHB bus error interrupt */
1497 + unsigned int tsFinishI : 1; /* owner bit error interrupt */
1498 + #endif
1499 + } bits;
1500 +} RAID_DMA_STATUS_T;
1501 +
1502 +
1503 +typedef union
1504 +{
1505 + unsigned int bits32;
1506 + struct bits_ff08
1507 + {
1508 + #ifdef BIG_ENDIAN
1509 + unsigned int td_start : 1; /* Start DMA transfer */
1510 + unsigned int td_continue : 1; /* Continue DMA operation */
1511 + unsigned int td_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
1512 + unsigned int : 1;
1513 + unsigned int td_prot : 4; /* DMA protection control */
1514 + unsigned int td_burst_size : 2; /* DMA max burst size for every AHB request */
1515 + unsigned int td_bus : 2; /* peripheral bus width */
1516 + unsigned int td_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */
1517 + unsigned int td_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
1518 + unsigned int td_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */
1519 + unsigned int td_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */
1520 + unsigned int td_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */
1521 + unsigned int td_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */
1522 + unsigned int : 14;
1523 + #else
1524 + unsigned int : 14;
1525 + unsigned int td_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */
1526 + unsigned int td_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */
1527 + unsigned int td_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */
1528 + unsigned int td_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */
1529 + unsigned int td_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
1530 + unsigned int td_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */
1531 + unsigned int td_bus : 2; /* peripheral bus width;0 - 8 bits;1 - 16 bits */
1532 + unsigned int td_burst_size : 2; /* TxDMA max burst size for every AHB request */
1533 + unsigned int td_prot : 4; /* TxDMA protection control */
1534 + unsigned int : 1;
1535 + unsigned int td_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
1536 + unsigned int td_continue : 1; /* Continue DMA operation */
1537 + unsigned int td_start : 1; /* Start DMA transfer */
1538 + #endif
1539 + } bits;
1540 +} RAID_TXDMA_CTRL_T;
1541 +
1542 +typedef union
1543 +{
1544 + unsigned int bits32;
1545 + struct bits_ff0c
1546 + {
1547 + #ifdef BIG_ENDIAN
1548 + unsigned int td_first_des_ptr : 28;/* first descriptor address */
1549 + unsigned int td_busy : 1;/* 1-TxDMA busy; 0-TxDMA idle */
1550 + unsigned int : 3;
1551 + #else
1552 + unsigned int : 3;
1553 + unsigned int td_busy : 1;/* 1-TxDMA busy; 0-TxDMA idle */
1554 + unsigned int td_first_des_ptr : 28;/* first descriptor address */
1555 + #endif
1556 + } bits;
1557 +} RAID_TXDMA_FIRST_DESC_T;
1558 +
1559 +typedef union
1560 +{
1561 + unsigned int bits32;
1562 + struct bits_ff10
1563 + {
1564 + #ifdef BIG_ENDIAN
1565 + unsigned int ndar : 28; /* next descriptor address */
1566 + unsigned int eofie : 1; /* end of frame interrupt enable */
1567 + unsigned int : 1;
1568 + unsigned int sof_eof : 2;
1569 + #else
1570 + unsigned int sof_eof : 2;
1571 + unsigned int : 1;
1572 + unsigned int eofie : 1; /* end of frame interrupt enable */
1573 + unsigned int ndar : 28; /* next descriptor address */
1574 + #endif
1575 + } bits;
1576 +} RAID_TXDMA_CURR_DESC_T;
1577 +
1578 +typedef union
1579 +{
1580 + unsigned int bits32;
1581 + struct bits_ff14
1582 + {
1583 + #ifdef BIG_ENDIAN
1584 + unsigned int rd_start : 1; /* Start DMA transfer */
1585 + unsigned int rd_continue : 1; /* Continue DMA operation */
1586 + unsigned int rd_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
1587 + unsigned int : 1;
1588 + unsigned int rd_prot : 4; /* DMA protection control */
1589 + unsigned int rd_burst_size : 2; /* DMA max burst size for every AHB request */
1590 + unsigned int rd_bus : 2; /* peripheral bus width;0 - 8 bits;1 - 16 bits */
1591 + unsigned int rd_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */
1592 + unsigned int rd_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
1593 + unsigned int rd_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */
1594 + unsigned int rd_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */
1595 + unsigned int rd_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */
1596 + unsigned int rd_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */
1597 + unsigned int : 14;
1598 + #else
1599 + unsigned int : 14;
1600 + unsigned int rd_eof_en : 1; /* End of frame interrupt Enable;1-enable;0-mask */
1601 + unsigned int rd_eod_en : 1; /* End of Descriptor interrupt Enable;1-enable;0-mask */
1602 + unsigned int rd_perr_en : 1; /* Protocol Failure Interrupt Enable;1-enable;0-mask */
1603 + unsigned int rd_fail_en : 1; /* DMA Fail Interrupt Enable;1-enable;0-mask */
1604 + unsigned int rd_finish_en : 1; /* DMA Finish Event Interrupt Enable;1-enable;0-mask */
1605 + unsigned int rd_endian : 1; /* AHB Endian. 0-little endian; 1-big endian */
1606 + unsigned int rd_bus : 2; /* peripheral bus width;0 - 8 bits;1 - 16 bits */
1607 + unsigned int rd_burst_size : 2; /* DMA max burst size for every AHB request */
1608 + unsigned int rd_prot : 4; /* DMA protection control */
1609 + unsigned int : 1;
1610 + unsigned int rd_chain_mode : 1; /* Descriptor Chain Mode;1-Descriptor Chain mode, 0-Direct DMA mode*/
1611 + unsigned int rd_continue : 1; /* Continue DMA operation */
1612 + unsigned int rd_start : 1; /* Start DMA transfer */
1613 + #endif
1614 + } bits;
1615 +} RAID_RXDMA_CTRL_T;
1616 +
1617 +typedef union
1618 +{
1619 + unsigned int bits32;
1620 + struct bits_ff18
1621 + {
1622 + #ifdef BIG_ENDIAN
1623 + unsigned int rd_first_des_ptr : 28;/* first descriptor address */
1624 + unsigned int rd_busy : 1;/* 1-RxDMA busy; 0-RxDMA idle */
1625 + unsigned int : 3;
1626 + #else
1627 + unsigned int : 3;
1628 + unsigned int rd_busy : 1;/* 1-RxDMA busy; 0-RxDMA idle */
1629 + unsigned int rd_first_des_ptr : 28;/* first descriptor address */
1630 + #endif
1631 + } bits;
1632 +} RAID_RXDMA_FIRST_DESC_T;
1633 +
1634 +typedef union
1635 +{
1636 + unsigned int bits32;
1637 + struct bits_ff1c
1638 + {
1639 + #ifdef BIG_ENDIAN
1640 + unsigned int ndar : 28; /* next descriptor address */
1641 + unsigned int eofie : 1; /* end of frame interrupt enable */
1642 + unsigned int dec : 1; /* AHB bus address increment(0)/decrement(1) */
1643 + unsigned int sof_eof : 2;
1644 + #else
1645 + unsigned int sof_eof : 2;
1646 + unsigned int dec : 1; /* AHB bus address increment(0)/decrement(1) */
1647 + unsigned int eofie : 1; /* end of frame interrupt enable */
1648 + unsigned int ndar : 28; /* next descriptor address */
1649 + #endif
1650 + } bits;
1651 +} RAID_RXDMA_CURR_DESC_T;
1652 +
1653 +typedef union
1654 +{
1655 + unsigned int bit32;
1656 + struct bits_ff50
1657 + {
1658 + unsigned int pat : 32; /* data for pattern check */
1659 + } bits;
1660 +} RAID_PACR_T;
1661 +
1662 +/******************************************************/
1663 +/* the definition of DMA Descriptor Register */
1664 +/******************************************************/
1665 +typedef struct raid_descriptor_t
1666 +{
1667 + union func_ctrl_t
1668 + {
1669 + unsigned int bit32;
1670 + struct bits_0000
1671 + {
1672 + #ifdef BIG_ENDIAN
1673 + unsigned int own : 1; /* owner bit */
1674 + unsigned int derr : 1; /* data error during processing this descriptor */
1675 + unsigned int perr : 1; /* protocol error during processing this descriptor */
1676 + unsigned int raid_ctrl_status : 7; /* pass RAID XOR fetch/store control status to CPU */
1677 + unsigned int desc_cnt : 6;
1678 + unsigned int buffer_size : 16; /* transfer buffer size associated with current description*/
1679 + #else
1680 + unsigned int buffer_size : 16; /* transfer buffer size associated with current description*/
1681 + unsigned int desc_cnt : 6;
1682 + unsigned int raid_ctrl_status : 7; /* pass RAID XOR fetch/store control status to CPU */
1683 + unsigned int perr : 1; /* protocol error during processing this descriptor */
1684 + unsigned int derr : 1; /* data error during processing this descriptor */
1685 + unsigned int own : 1; /* owner bit */
1686 + #endif
1687 + } bits;
1688 + } func_ctrl;
1689 +
1690 + union flg_status_t
1691 + {
1692 + unsigned int bits32;
1693 + struct bit_004
1694 + {
1695 + #ifdef BIG_ENDIAN
1696 + unsigned int bcc : 16;
1697 + unsigned int : 13
1698 + unsigned int mode : 3;
1699 + #else
1700 + unsigned int mode : 3;
1701 + unsigned int : 13;
1702 + unsigned int bcc : 16;
1703 + #endif
1704 + } bits_cmd_status;
1705 + } flg_status; //Sanders
1706 +
1707 + unsigned int buf_addr;
1708 +
1709 + union next_desc_addr_t
1710 + {
1711 + unsigned int bits32;
1712 + struct bits_000c
1713 + {
1714 + #ifdef BIG_ENDIAN
1715 + unsigned int ndar : 28; /* next descriptor address */
1716 + unsigned int eofie : 1; /* end of frame interrupt enable */
1717 + unsigned int : 1;
1718 + unsigned int sof_eof : 2; /* the position of the descriptor in chain */
1719 + #else
1720 + unsigned int sof_eof : 2; /* the position of the descriptor in chain */
1721 + unsigned int : 1;
1722 + unsigned int eofie : 1; /* end of frame interrupt enable */
1723 + unsigned int ndar : 28; /* next descriptor address */
1724 + #endif
1725 + } bits;
1726 + } next_desc_addr;
1727 +} RAID_DESCRIPTOR_T;
1728 +
1729 +/******************************************************/
1730 +/* the offset of RAID SMC register */
1731 +/******************************************************/
1732 +enum RAID_SMC_REGISTER {
1733 + RAID_SMC_CMD_REG = 0xff60,
1734 + RAID_SMC_STATUS_REG = 0xff64
1735 + };
1736 +
1737 +/******************************************************/
1738 +/* the definition of RAID SMC module register */
1739 +/******************************************************/
1740 +typedef union
1741 +{
1742 + unsigned int bits32;
1743 + struct bits_ff60
1744 + {
1745 + #ifdef BIG_ENDIAN
1746 + unsigned int pat_mode : 2; /* partition mode selection */
1747 + unsigned int : 14;
1748 + unsigned int device_id : 12;
1749 + unsigned int revision_id : 4;
1750 + #else
1751 + unsigned int revision_id : 4;
1752 + unsigned int device_id : 12;
1753 + unsigned int : 14;
1754 + unsigned int pat_mode : 2; /* partition mode selection */
1755 + #endif
1756 + } bits;
1757 +} RAID_SMC_CMD;
1758 +
1759 +typedef union
1760 +{
1761 + unsigned int bits32;
1762 + struct bits_ff64
1763 + {
1764 + #ifdef BIG_ENDIAN
1765 + unsigned int addr_err1 : 1; /* address is out of range for controller 1 */
1766 + unsigned int ahb_err1 : 1; /* AHB bus error for controller 1 */
1767 + unsigned int : 14;
1768 + unsigned int addr_err2 : 1; /* address is out of range for controller 2 */
1769 + unsigned int ahb_err2 : 1; /* AHB bus error for controller 2 */
1770 + unsigned int : 14;
1771 + #else
1772 + unsigned int : 14;
1773 + unsigned int ahb_err2 : 1; /* AHB bus error for controller 2 */
1774 + unsigned int addr_err2 : 1; /* address is out of range for controller 2 */
1775 + unsigned int : 14;
1776 + unsigned int ahb_err1 : 1; /* AHB bus error for controller 1 */
1777 + unsigned int addr_err1 : 1; /* address is out of range for controller 1 */
1778 + #endif
1779 + } bits;
1780 +} RAID_SMC_STATUS;
1781 +
1782 +typedef struct RAID_S
1783 +{
1784 + const char *device_name;
1785 + wait_queue_head_t wait;
1786 + unsigned int busy;
1787 + int irq;
1788 + unsigned int status;
1789 + RAID_DESCRIPTOR_T *tx_desc; /* point to virtual TX descriptor address */
1790 + RAID_DESCRIPTOR_T *rx_desc; /* point ot virtual RX descriptor address */
1791 + RAID_DESCRIPTOR_T *tx_cur_desc; /* current TX descriptor */
1792 + RAID_DESCRIPTOR_T *rx_cur_desc; /* current RX descriptor */
1793 + RAID_DESCRIPTOR_T *tx_finished_desc;
1794 + RAID_DESCRIPTOR_T *rx_finished_desc;
1795 + RAID_DESCRIPTOR_T *tx_first_desc;
1796 + RAID_DESCRIPTOR_T *rx_first_desc;
1797 +
1798 +// unsigned int *tx_buf[TX_DESC_NUM];
1799 + unsigned int *rx_desc_dma; // physical address of rx_descript
1800 + unsigned int *tx_desc_dma; // physical address of tx_descript
1801 + unsigned int *rx_bufs_dma;
1802 + unsigned int *tx_bufs_dma;
1803 +
1804 +} RAID_T;
1805 +
1806 +struct reg_ioctl
1807 +{
1808 + unsigned int reg_addr;
1809 + unsigned int val_in;
1810 + unsigned int val_out;
1811 +};
1812 +
1813 +typedef struct dma_ctrl {
1814 + int sram;
1815 + int prot;
1816 + int burst;
1817 + int bus;
1818 + int endian;
1819 + int mode;
1820 +} DMA_CTRL;
1821 +
1822 +
1823 +#ifdef XOR_SW_FILL_IN
1824 +
1825 +#define __XOR(a1, a2) a1 ^= a2
1826 +
1827 +#define GET_BLOCK_2(dst) \
1828 + __asm__("ldmia %0, {%1, %2}" \
1829 + : "=r" (dst), "=r" (a1), "=r" (a2) \
1830 + : "0" (dst))
1831 +
1832 +#define GET_BLOCK_4(dst) \
1833 + __asm__("ldmia %0, {%1, %2, %3, %4}" \
1834 + : "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \
1835 + : "0" (dst))
1836 +
1837 +#define XOR_BLOCK_2(src) \
1838 + __asm__("ldmia %0!, {%1, %2}" \
1839 + : "=r" (src), "=r" (b1), "=r" (b2) \
1840 + : "0" (src)); \
1841 + __XOR(a1, b1); __XOR(a2, b2);
1842 +
1843 +#define XOR_BLOCK_4(src) \
1844 + __asm__("ldmia %0!, {%1, %2, %3, %4}" \
1845 + : "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \
1846 + : "0" (src)); \
1847 + __XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4)
1848 +
1849 +#define PUT_BLOCK_2(dst) \
1850 + __asm__ __volatile__("stmia %0!, {%2, %3}" \
1851 + : "=r" (dst) \
1852 + : "0" (dst), "r" (a1), "r" (a2))
1853 +
1854 +#define PUT_BLOCK_4(dst) \
1855 + __asm__ __volatile__("stmia %0!, {%2, %3, %4, %5}" \
1856 + : "=r" (dst) \
1857 + : "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4))
1858 +
1859 +static void
1860 +xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
1861 +{
1862 + unsigned int lines = bytes / sizeof(unsigned long) / 4;
1863 + register unsigned int a1 __asm__("r4");
1864 + register unsigned int a2 __asm__("r5");
1865 + register unsigned int a3 __asm__("r6");
1866 + register unsigned int a4 __asm__("r7");
1867 + register unsigned int b1 __asm__("r8");
1868 + register unsigned int b2 __asm__("r9");
1869 + register unsigned int b3 __asm__("ip");
1870 + register unsigned int b4 __asm__("lr");
1871 +
1872 + do {
1873 + GET_BLOCK_4(p1);
1874 + XOR_BLOCK_4(p2);
1875 + PUT_BLOCK_4(p1);
1876 + } while (--lines);
1877 +}
1878 +
1879 +static void
1880 +xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
1881 + unsigned long *p3)
1882 +{
1883 + unsigned int lines = bytes / sizeof(unsigned long) / 4;
1884 + register unsigned int a1 __asm__("r4");
1885 + register unsigned int a2 __asm__("r5");
1886 + register unsigned int a3 __asm__("r6");
1887 + register unsigned int a4 __asm__("r7");
1888 + register unsigned int b1 __asm__("r8");
1889 + register unsigned int b2 __asm__("r9");
1890 + register unsigned int b3 __asm__("ip");
1891 + register unsigned int b4 __asm__("lr");
1892 +
1893 + do {
1894 + GET_BLOCK_4(p1);
1895 + XOR_BLOCK_4(p2);
1896 + XOR_BLOCK_4(p3);
1897 + PUT_BLOCK_4(p1);
1898 + } while (--lines);
1899 +}
1900 +
1901 +static void
1902 +xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
1903 + unsigned long *p3, unsigned long *p4)
1904 +{
1905 + unsigned int lines = bytes / sizeof(unsigned long) / 2;
1906 + register unsigned int a1 __asm__("r8");
1907 + register unsigned int a2 __asm__("r9");
1908 + register unsigned int b1 __asm__("ip");
1909 + register unsigned int b2 __asm__("lr");
1910 +
1911 + do {
1912 + GET_BLOCK_2(p1);
1913 + XOR_BLOCK_2(p2);
1914 + XOR_BLOCK_2(p3);
1915 + XOR_BLOCK_2(p4);
1916 + PUT_BLOCK_2(p1);
1917 + } while (--lines);
1918 +}
1919 +
1920 +static void
1921 +xor_arm4regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
1922 + unsigned long *p3, unsigned long *p4, unsigned long *p5)
1923 +{
1924 + unsigned int lines = bytes / sizeof(unsigned long) / 2;
1925 + register unsigned int a1 __asm__("r8");
1926 + register unsigned int a2 __asm__("r9");
1927 + register unsigned int b1 __asm__("ip");
1928 + register unsigned int b2 __asm__("lr");
1929 +
1930 + do {
1931 + GET_BLOCK_2(p1);
1932 + XOR_BLOCK_2(p2);
1933 + XOR_BLOCK_2(p3);
1934 + XOR_BLOCK_2(p4);
1935 + XOR_BLOCK_2(p5);
1936 + PUT_BLOCK_2(p1);
1937 + } while (--lines);
1938 +}
1939 +#endif //XOR_SW_FILL_IN
1940 +
1941 Index: linux-2.6.23.16/arch/arm/mach-sl2312/irq.c
1942 ===================================================================
1943 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1944 +++ linux-2.6.23.16/arch/arm/mach-sl2312/irq.c 2008-03-14 11:58:14.702460322 +0200
1945 @@ -0,0 +1,202 @@
1946 +/*
1947 + * linux/arch/arm/mach-epxa10db/irq.c
1948 + *
1949 + * Copyright (C) 2001 Altera Corporation
1950 + *
1951 + * This program is free software; you can redistribute it and/or modify
1952 + * it under the terms of the GNU General Public License as published by
1953 + * the Free Software Foundation; either version 2 of the License, or
1954 + * (at your option) any later version.
1955 + *
1956 + * This program is distributed in the hope that it will be useful,
1957 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1958 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1959 + * GNU General Public License for more details.
1960 + *
1961 + * You should have received a copy of the GNU General Public License
1962 + * along with this program; if not, write to the Free Software
1963 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1964 + */
1965 +#include <linux/init.h>
1966 +#include <linux/ioport.h>
1967 +#include <linux/stddef.h>
1968 +#include <linux/list.h>
1969 +#include <linux/sched.h>
1970 +#include <asm/hardware.h>
1971 +#include <asm/irq.h>
1972 +#include <asm/io.h>
1973 +#include <asm/mach/irq.h>
1974 +#include <asm/arch/platform.h>
1975 +#include <asm/arch/int_ctrl.h>
1976 +
1977 +#ifdef CONFIG_PCI
1978 +#include <asm/arch/pci.h>
1979 +#endif
1980 +
1981 +int fixup_irq(unsigned int irq)
1982 +{
1983 +#ifdef CONFIG_PCI
1984 + if (irq == IRQ_PCI) {
1985 + return sl2312_pci_get_int_src();
1986 + }
1987 +#endif
1988 + return irq;
1989 +}
1990 +
1991 +static void sl2312_ack_irq(unsigned int irq)
1992 +{
1993 + __raw_writel(1 << irq, IRQ_CLEAR(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
1994 +}
1995 +
1996 +static void sl2312_mask_irq(unsigned int irq)
1997 +{
1998 + unsigned int mask;
1999 +
2000 +#ifdef CONFIG_PCI
2001 + if (irq >= PCI_IRQ_OFFSET)
2002 + {
2003 + mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2004 + mask &= ~IRQ_PCI_MASK ;
2005 + __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2006 + sl2312_pci_mask_irq(irq - PCI_IRQ_OFFSET);
2007 + }
2008 + else
2009 +#endif
2010 + if(irq >= FIQ_OFFSET)
2011 + {
2012 + mask = __raw_readl(FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2013 + mask &= ~(1 << (irq - FIQ_OFFSET));
2014 + __raw_writel(mask, FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2015 + }
2016 + else
2017 + {
2018 + mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2019 + mask &= ~(1 << irq);
2020 + __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2021 + }
2022 +
2023 +}
2024 +
2025 +static void sl2312_unmask_irq(unsigned int irq)
2026 +{
2027 + unsigned int mask;
2028 +
2029 +#ifdef CONFIG_PCI
2030 + if (irq >= PCI_IRQ_OFFSET)
2031 + {
2032 + mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2033 + mask |= IRQ_PCI_MASK ;
2034 + __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2035 + sl2312_pci_unmask_irq(irq - PCI_IRQ_OFFSET);
2036 + }
2037 + else
2038 +#endif
2039 + if(irq >= FIQ_OFFSET)
2040 + {
2041 + mask = __raw_readl(FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2042 + mask |= (1 << (irq - FIQ_OFFSET));
2043 + __raw_writel(mask, FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2044 + }
2045 + else
2046 + {
2047 + mask = __raw_readl(IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2048 + mask |= (1 << irq);
2049 + __raw_writel(mask, IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2050 + }
2051 +}
2052 +
2053 +static struct irq_chip sl2312_level_irq = {
2054 + .ack = sl2312_mask_irq,
2055 + .mask = sl2312_mask_irq,
2056 + .unmask = sl2312_unmask_irq,
2057 +// .set_type = ixp4xx_set_irq_type,
2058 +};
2059 +
2060 +static struct irq_chip sl2312_edge_irq = {
2061 + .ack = sl2312_ack_irq,
2062 + .mask = sl2312_mask_irq,
2063 + .unmask = sl2312_unmask_irq,
2064 +// .set_type = ixp4xx_set_irq_type,
2065 +};
2066 +
2067 +static struct resource irq_resource = {
2068 + .name = "irq_handler",
2069 + .start = IO_ADDRESS(SL2312_INTERRUPT_BASE),
2070 + .end = IO_ADDRESS(FIQ_STATUS(SL2312_INTERRUPT_BASE))+4,
2071 +};
2072 +
2073 +void __init sl2312_init_irq(void)
2074 +{
2075 + unsigned int i, mode, level;
2076 +
2077 + request_resource(&iomem_resource, &irq_resource);
2078 +
2079 + for (i = 0; i < NR_IRQS; i++)
2080 + {
2081 + if((i>=IRQ_TIMER1 && i<=IRQ_TIMER3)||(i>=IRQ_SERIRQ0 && i<=IRQ_SERIRQ_MAX))
2082 + {
2083 + set_irq_chip(i, &sl2312_edge_irq);
2084 + set_irq_handler(i, handle_edge_irq);
2085 + }
2086 + else
2087 + {
2088 + set_irq_chip(i, &sl2312_level_irq);
2089 + set_irq_handler(i,handle_level_irq);
2090 + }
2091 + set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
2092 + }
2093 +
2094 + /* Disable all interrupt */
2095 + __raw_writel(0,IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2096 + __raw_writel(0,FIQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2097 +
2098 + /* Set interrupt mode */
2099 + /* emac & ipsec type is level trigger and high active */
2100 + mode = __raw_readl(IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2101 + level = __raw_readl(IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2102 +
2103 + mode &= ~IRQ_GMAC0_MASK;
2104 + level &= ~IRQ_GMAC0_MASK;
2105 +
2106 + mode &= ~IRQ_GMAC1_MASK;
2107 + level &= ~IRQ_GMAC1_MASK;
2108 +
2109 + mode &= ~IRQ_IPSEC_MASK;
2110 + level &= ~IRQ_IPSEC_MASK;
2111 +
2112 + // for IDE0,1, high active and level trigger
2113 + mode &= ~IRQ_IDE0_MASK;
2114 + level &= ~IRQ_IDE0_MASK;
2115 + mode &= ~IRQ_IDE1_MASK;
2116 + level &= ~IRQ_IDE1_MASK;
2117 +
2118 +
2119 + // for PCI, high active and level trigger
2120 + mode &= ~IRQ_PCI_MASK;
2121 + level &= ~IRQ_PCI_MASK;
2122 +
2123 + // for USB, high active and level trigger
2124 + mode &= ~IRQ_USB0_MASK;
2125 + level &= ~IRQ_USB0_MASK;
2126 +
2127 + mode &= ~IRQ_USB1_MASK;
2128 + level &= ~IRQ_USB1_MASK;
2129 +
2130 + // for LPC, high active and edge trigger
2131 + mode |= 0xffff0000;
2132 + level &= 0x0000ffff;
2133 +
2134 + // for GPIO, high active and level trigger
2135 + mode &= ~(IRQ_GPIO_MASK);
2136 + level &= ~(IRQ_GPIO_MASK);
2137 +
2138 + mode &= ~(IRQ_GPIO1_MASK);
2139 + level &= ~(IRQ_GPIO1_MASK);
2140 +
2141 + mode &= ~(IRQ_GPIO2_MASK);
2142 + level &= ~(IRQ_GPIO2_MASK);
2143 +
2144 + __raw_writel(mode,IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2145 + __raw_writel(level,IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
2146 +
2147 +}
2148 Index: linux-2.6.23.16/arch/arm/mach-sl2312/lpc.c
2149 ===================================================================
2150 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2151 +++ linux-2.6.23.16/arch/arm/mach-sl2312/lpc.c 2008-03-13 17:48:24.508798285 +0200
2152 @@ -0,0 +1,125 @@
2153 +/*
2154 + *
2155 + * BRIEF MODULE DESCRIPTION
2156 + * ITE Semi IT8712 Super I/O functions.
2157 + *
2158 + * Copyright 2001 MontaVista Software Inc.
2159 + * Author: MontaVista Software, Inc.
2160 + * ppopov@mvista.com or source@mvista.com
2161 + *
2162 + * This program is free software; you can redistribute it and/or modify it
2163 + * under the terms of the GNU General Public License as published by the
2164 + * Free Software Foundation; either version 2 of the License, or (at your
2165 + * option) any later version.
2166 + *
2167 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2168 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2169 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
2170 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2171 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2172 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2173 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2174 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2175 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2176 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2177 + *
2178 + * You should have received a copy of the GNU General Public License along
2179 + * with this program; if not, write to the Free Software Foundation, Inc.,
2180 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2181 + */
2182 +#include <linux/kernel.h>
2183 +#include <linux/delay.h>
2184 +#include <asm/io.h>
2185 +#include <asm/types.h>
2186 +#include <asm/arch/it8712.h>
2187 +#include <linux/init.h>
2188 +#include <asm/arch/hardware.h>
2189 +
2190 +#ifndef TRUE
2191 +#define TRUE 1
2192 +#endif
2193 +
2194 +#ifndef FALSE
2195 +#define FALSE 0
2196 +#endif
2197 +
2198 +
2199 +// MB PnP configuration register
2200 +#define LPC_KEY_ADDR (IO_ADDRESS(SL2312_LPC_IO_BASE) + 0x2e)
2201 +#define LPC_DATA_ADDR (IO_ADDRESS(SL2312_LPC_IO_BASE) + 0x2f)
2202 +
2203 +#define LPC_BUS_CTRL *(volatile unsigned char*) (IO_ADDRESS(SL2312_LPC_HOST_BASE) + 0)
2204 +#define LPC_BUS_STATUS *(volatile unsigned char*) (IO_ADDRESS(SL2312_LPC_HOST_BASE) + 2)
2205 +#define LPC_SERIAL_IRQ_CTRL *(volatile unsigned char*) (IO_ADDRESS(SL2312_LPC_HOST_BASE) + 4)
2206 +
2207 +int it8712_exist;
2208 +
2209 +static void LPCEnterMBPnP(void)
2210 +{
2211 + int i;
2212 + unsigned char key[4] = {0x87, 0x01, 0x55, 0x55};
2213 +
2214 + for (i = 0; i<4; i++)
2215 + outb(key[i], LPC_KEY_ADDR);
2216 +
2217 +}
2218 +
2219 +static void LPCExitMBPnP(void)
2220 +{
2221 + outb(0x02, LPC_KEY_ADDR);
2222 + outb(0x02, LPC_DATA_ADDR);
2223 +}
2224 +
2225 +void LPCSetConfig(char LdnNumber, char Index, char data)
2226 +{
2227 + LPCEnterMBPnP(); // Enter IT8712 MB PnP mode
2228 + outb(0x07, LPC_KEY_ADDR);
2229 + outb(LdnNumber, LPC_DATA_ADDR);
2230 + outb(Index, LPC_KEY_ADDR);
2231 + outb(data, LPC_DATA_ADDR);
2232 + LPCExitMBPnP();
2233 +}
2234 +
2235 +char LPCGetConfig(char LdnNumber, char Index)
2236 +{
2237 + char rtn;
2238 +
2239 + LPCEnterMBPnP(); // Enter IT8712 MB PnP mode
2240 + outb(0x07, LPC_KEY_ADDR);
2241 + outb(LdnNumber, LPC_DATA_ADDR);
2242 + outb(Index, LPC_KEY_ADDR);
2243 + rtn = inb(LPC_DATA_ADDR);
2244 + LPCExitMBPnP();
2245 + return rtn;
2246 +}
2247 +
2248 +static int SearchIT8712(void)
2249 +{
2250 + unsigned char Id1, Id2;
2251 + unsigned short Id;
2252 +
2253 + LPCEnterMBPnP();
2254 + outb(0x20, LPC_KEY_ADDR); /* chip id byte 1 */
2255 + Id1 = inb(LPC_DATA_ADDR);
2256 + outb(0x21, LPC_KEY_ADDR); /* chip id byte 2 */
2257 + Id2 = inb(LPC_DATA_ADDR);
2258 + Id = (Id1 << 8) | Id2;
2259 + LPCExitMBPnP();
2260 + if (Id == 0x8712)
2261 + return TRUE;
2262 + else
2263 + return FALSE;
2264 +}
2265 +
2266 +int InitLPCInterface(void)
2267 +{
2268 + LPC_BUS_CTRL = 0xc0;
2269 + LPC_SERIAL_IRQ_CTRL = 0xc0;
2270 + mdelay(1); // wait for 1 serial IRQ cycle
2271 + LPC_SERIAL_IRQ_CTRL = 0x80;
2272 + it8712_exist = SearchIT8712();
2273 + printk("IT8712 %s exist\n", it8712_exist?"":"doesn't");
2274 + return 0;
2275 +}
2276 +
2277 +//__initcall(InitLPCInterface);
2278 Index: linux-2.6.23.16/arch/arm/mach-sl2312/mm.c
2279 ===================================================================
2280 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2281 +++ linux-2.6.23.16/arch/arm/mach-sl2312/mm.c 2008-03-13 17:48:24.508798285 +0200
2282 @@ -0,0 +1,80 @@
2283 +/*
2284 + * linux/arch/arm/mach-epxa10db/mm.c
2285 + *
2286 + * MM routines for Altera'a Epxa10db board
2287 + *
2288 + * Copyright (C) 2001 Altera Corporation
2289 + *
2290 + * This program is free software; you can redistribute it and/or modify
2291 + * it under the terms of the GNU General Public License as published by
2292 + * the Free Software Foundation; either version 2 of the License, or
2293 + * (at your option) any later version.
2294 + *
2295 + * This program is distributed in the hope that it will be useful,
2296 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2297 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2298 + * GNU General Public License for more details.
2299 + *
2300 + * You should have received a copy of the GNU General Public License
2301 + * along with this program; if not, write to the Free Software
2302 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2303 + */
2304 +#include <linux/sched.h>
2305 +#include <linux/mm.h>
2306 +#include <linux/init.h>
2307 +
2308 +#include <asm/hardware.h>
2309 +#include <asm/io.h>
2310 +#include <asm/pgtable.h>
2311 +#include <asm/page.h>
2312 +#include <asm/sizes.h>
2313 +
2314 +#include <asm/mach/map.h>
2315 +
2316 +/* Page table mapping for I/O region */
2317 +static struct map_desc sl2312_io_desc[] __initdata = {
2318 +#ifdef CONFIG_GEMINI_IPI
2319 +{__phys_to_virt(CPU_1_MEM_BASE), __phys_to_pfn(CPU_1_MEM_BASE), SZ_64M, MT_MEMORY},
2320 +#endif
2321 +{IO_ADDRESS(SL2312_SRAM_BASE), __phys_to_pfn(SL2312_SRAM_BASE), SZ_512K, MT_DEVICE},
2322 +{IO_ADDRESS(SL2312_DRAM_CTRL_BASE), __phys_to_pfn(SL2312_DRAM_CTRL_BASE), SZ_512K, MT_DEVICE},
2323 +{IO_ADDRESS(SL2312_GLOBAL_BASE), __phys_to_pfn(SL2312_GLOBAL_BASE), SZ_512K, MT_DEVICE},
2324 +{IO_ADDRESS(SL2312_WAQTCHDOG_BASE), __phys_to_pfn(SL2312_WAQTCHDOG_BASE), SZ_512K, MT_DEVICE},
2325 +{IO_ADDRESS(SL2312_UART_BASE), __phys_to_pfn(SL2312_UART_BASE), SZ_512K, MT_DEVICE},
2326 +{IO_ADDRESS(SL2312_TIMER_BASE), __phys_to_pfn(SL2312_TIMER_BASE), SZ_512K, MT_DEVICE},
2327 +{IO_ADDRESS(SL2312_LCD_BASE), __phys_to_pfn(SL2312_LCD_BASE), SZ_512K, MT_DEVICE},
2328 +{IO_ADDRESS(SL2312_RTC_BASE), __phys_to_pfn(SL2312_RTC_BASE), SZ_512K, MT_DEVICE},
2329 +{IO_ADDRESS(SL2312_SATA_BASE), __phys_to_pfn(SL2312_SATA_BASE), SZ_512K, MT_DEVICE},
2330 +{IO_ADDRESS(SL2312_LPC_HOST_BASE), __phys_to_pfn(SL2312_LPC_HOST_BASE), SZ_512K, MT_DEVICE},
2331 +{IO_ADDRESS(SL2312_LPC_IO_BASE), __phys_to_pfn(SL2312_LPC_IO_BASE), SZ_512K, MT_DEVICE},
2332 +{IO_ADDRESS(SL2312_INTERRUPT_BASE), __phys_to_pfn(SL2312_INTERRUPT_BASE), SZ_512K, MT_DEVICE},
2333 +{IO_ADDRESS(SL2312_INTERRUPT1_BASE), __phys_to_pfn(SL2312_INTERRUPT1_BASE), SZ_512K, MT_DEVICE},
2334 +{IO_ADDRESS(SL2312_SSP_CTRL_BASE), __phys_to_pfn(SL2312_SSP_CTRL_BASE), SZ_512K, MT_DEVICE},
2335 +{IO_ADDRESS(SL2312_POWER_CTRL_BASE), __phys_to_pfn(SL2312_POWER_CTRL_BASE), SZ_512K, MT_DEVICE},
2336 +{IO_ADDRESS(SL2312_CIR_BASE), __phys_to_pfn(SL2312_CIR_BASE), SZ_512K, MT_DEVICE},
2337 +{IO_ADDRESS(SL2312_GPIO_BASE), __phys_to_pfn(SL2312_GPIO_BASE), SZ_512K, MT_DEVICE},
2338 +{IO_ADDRESS(SL2312_GPIO_BASE1), __phys_to_pfn(SL2312_GPIO_BASE1), SZ_512K, MT_DEVICE},
2339 +{IO_ADDRESS(SL2312_GPIO_BASE2), __phys_to_pfn(SL2312_GPIO_BASE2), SZ_512K, MT_DEVICE},
2340 +{IO_ADDRESS(SL2312_PCI_IO_BASE), __phys_to_pfn(SL2312_PCI_IO_BASE), SZ_512K, MT_DEVICE},
2341 +{IO_ADDRESS(SL2312_PCI_MEM_BASE), __phys_to_pfn(SL2312_PCI_MEM_BASE), SZ_512K, MT_DEVICE},
2342 +#ifdef CONFIG_NET_SL351X
2343 +{IO_ADDRESS(SL2312_TOE_BASE), __phys_to_pfn(SL2312_TOE_BASE) , SZ_512K, MT_DEVICE},
2344 +#endif
2345 +{IO_ADDRESS(SL2312_GMAC0_BASE), __phys_to_pfn(SL2312_GMAC0_BASE), SZ_512K, MT_DEVICE},
2346 +{IO_ADDRESS(SL2312_GMAC1_BASE), __phys_to_pfn(SL2312_GMAC1_BASE), SZ_512K, MT_DEVICE},
2347 +{IO_ADDRESS(SL2312_SECURITY_BASE), __phys_to_pfn(SL2312_SECURITY_BASE), SZ_512K, MT_DEVICE},
2348 +{IO_ADDRESS(SL2312_IDE0_BASE), __phys_to_pfn(SL2312_IDE0_BASE), SZ_512K, MT_DEVICE},
2349 +{IO_ADDRESS(SL2312_IDE1_BASE), __phys_to_pfn(SL2312_IDE1_BASE), SZ_512K, MT_DEVICE},
2350 +{IO_ADDRESS(SL2312_RAID_BASE), __phys_to_pfn(SL2312_RAID_BASE), SZ_512K, MT_DEVICE},
2351 +{IO_ADDRESS(SL2312_FLASH_CTRL_BASE), __phys_to_pfn(SL2312_FLASH_CTRL_BASE), SZ_512K, MT_DEVICE},
2352 +{IO_ADDRESS(SL2312_DRAM_CTRL_BASE), __phys_to_pfn(SL2312_DRAM_CTRL_BASE), SZ_512K, MT_DEVICE},
2353 +{IO_ADDRESS(SL2312_GENERAL_DMA_BASE), __phys_to_pfn(SL2312_GENERAL_DMA_BASE), SZ_512K, MT_DEVICE},
2354 +{IO_ADDRESS(SL2312_USB0_BASE), __phys_to_pfn(SL2312_USB_BASE), SZ_512K, MT_DEVICE},
2355 +{IO_ADDRESS(SL2312_USB1_BASE), __phys_to_pfn(SL2312_USB1_BASE), SZ_512K, MT_DEVICE},
2356 +{FLASH_VADDR(SL2312_FLASH_BASE), __phys_to_pfn(SL2312_FLASH_BASE), SZ_16M, MT_DEVICE},
2357 +};
2358 +
2359 +void __init sl2312_map_io(void)
2360 +{
2361 + iotable_init(sl2312_io_desc, ARRAY_SIZE(sl2312_io_desc));
2362 +}
2363 Index: linux-2.6.23.16/arch/arm/mach-sl2312/pci.c
2364 ===================================================================
2365 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2366 +++ linux-2.6.23.16/arch/arm/mach-sl2312/pci.c 2008-03-14 12:56:27.401497897 +0200
2367 @@ -0,0 +1,359 @@
2368 +/*
2369 + * linux/arch/arm/mach-sl2312/pci_sl2312.c
2370 + *
2371 + * PCI functions for sl2312 host PCI bridge
2372 + *
2373 + * Copyright (C) 2003 StorLink Corp.
2374 + *
2375 + * This program is free software; you can redistribute it and/or modify
2376 + * it under the terms of the GNU General Public License as published by
2377 + * the Free Software Foundation; either version 2 of the License, or
2378 + * (at your option) any later version.
2379 + *
2380 + * This program is distributed in the hope that it will be useful,
2381 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2382 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2383 + * GNU General Public License for more details.
2384 + *
2385 + * You should have received a copy of the GNU General Public License
2386 + * along with this program; if not, write to the Free Software
2387 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2388 + */
2389 +#include <linux/sched.h>
2390 +#include <linux/kernel.h>
2391 +#include <linux/pci.h>
2392 +#include <linux/ptrace.h>
2393 +#include <linux/slab.h>
2394 +#include <linux/ioport.h>
2395 +#include <linux/interrupt.h>
2396 +#include <linux/spinlock.h>
2397 +#include <linux/init.h>
2398 +
2399 +#include <asm/sizes.h>
2400 +#include <asm/hardware.h>
2401 +#include <asm/irq.h>
2402 +#include <asm/system.h>
2403 +#include <asm/mach/pci.h>
2404 +#include <asm/mach/irq.h>
2405 +#include <asm/mach-types.h>
2406 +
2407 +#include <asm/arch/pci.h>
2408 +
2409 +//#define DEBUG
2410 +
2411 +// sl2312 PCI bridge access routines
2412 +
2413 +#define PCI_IOSIZE_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE)))
2414 +#define PCI_PROT_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x04))
2415 +#define PCI_CTRL_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x08))
2416 +#define PCI_SOFTRST_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x10))
2417 +#define PCI_CONFIG_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x28))
2418 +#define PCI_DATA_REG (*(volatile unsigned long *) (IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x2C))
2419 +
2420 +static spinlock_t sl2312_pci_lock = SPIN_LOCK_UNLOCKED;
2421 +// for initialize PCI devices
2422 +struct resource pci_ioport_resource = {
2423 + .name = "PCI I/O Space",
2424 + .start = IO_ADDRESS(SL2312_PCI_IO_BASE) + 0x100,
2425 + .end = IO_ADDRESS(SL2312_PCI_IO_BASE) + SZ_512K - 1,
2426 + .flags = IORESOURCE_IO,
2427 +};
2428 +struct resource pci_iomem_resource = {
2429 + .name = "PCI Mem Space",
2430 + .start = SL2312_PCI_MEM_BASE,
2431 + .end = SL2312_PCI_MEM_BASE + SZ_128M - 1,
2432 + .flags = IORESOURCE_MEM,
2433 +};
2434 +
2435 +static int sl2312_read_config(struct pci_bus *bus, unsigned int devfn, int where,int size, u32 *val)
2436 +{
2437 + unsigned long addr,data;
2438 + unsigned long flags;
2439 +
2440 + spin_lock_irqsave(&sl2312_pci_lock, flags);
2441 + addr = 0x80000000 | (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | (where & ~3);
2442 + PCI_CONFIG_REG = addr;
2443 + data = PCI_DATA_REG;
2444 +
2445 + switch (size) {
2446 + case 1:
2447 + *val = (u8) (data >> ((where & 0x03) * 8));
2448 + break;
2449 + case 2:
2450 + *val = (u16) (data >> ((where & 0x02) * 8));
2451 + break;
2452 + case 4:
2453 + *val = data;
2454 + if ((where >= 0x10) && (where <= 0x24)) {
2455 + if ((*val & 0xfff00000) == SL2312_PCI_IO_BASE) {
2456 + *val &= 0x000fffff;
2457 + *val |= IO_ADDRESS(SL2312_PCI_IO_BASE);
2458 + }
2459 + }
2460 + break;
2461 + }
2462 + spin_unlock_irqrestore(&sl2312_pci_lock, flags);
2463 +// printk("READ==>slot=%d fn=%d where=%d value=%x\n",PCI_SLOT(devfn),PCI_FUNC(devfn),where,*val);
2464 + return PCIBIOS_SUCCESSFUL;
2465 +}
2466 +
2467 +static int sl2312_write_config(struct pci_bus *bus, unsigned int devfn, int where,int size, u32 val)
2468 +{
2469 + unsigned long addr,data;
2470 + unsigned long flags;
2471 +
2472 + spin_lock_irqsave(&sl2312_pci_lock, flags);
2473 + addr = 0x80000000 | (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | (where & ~3);
2474 + PCI_CONFIG_REG = addr;
2475 + data = PCI_DATA_REG;
2476 +
2477 + switch (size) {
2478 + case 1:
2479 + data &= ~(0xff << ((where & 0x03) * 8));
2480 + data |= (val << ((where & 0x03) * 8));
2481 + PCI_DATA_REG = data;
2482 + break;
2483 + case 2:
2484 + data &= ~(0xffff << ((where & 0x02) * 8));
2485 + data |= (val << ((where & 0x02) * 8));
2486 + PCI_DATA_REG = data;
2487 + break;
2488 + case 4:
2489 + if ((where >= 0x10) && (where <= 0x24)) {
2490 + if ((val & 0xfff00000) == IO_ADDRESS(SL2312_PCI_IO_BASE)) {
2491 + val &= 0x000fffff;
2492 + val |= SL2312_PCI_IO_BASE;
2493 + }
2494 + }
2495 + PCI_DATA_REG = val;
2496 + break;
2497 + }
2498 + spin_unlock_irqrestore(&sl2312_pci_lock, flags);
2499 +
2500 +// printk("WRITE==> slot=%d fn=%d where=%d value=%x \n",PCI_SLOT(devfn),PCI_FUNC(devfn),where,val);
2501 + return PCIBIOS_SUCCESSFUL;
2502 +}
2503 +
2504 +static struct pci_ops sl2312_pci_ops = {
2505 + .read = sl2312_read_config,
2506 + .write = sl2312_write_config,
2507 +};
2508 +
2509 +
2510 +int __init sl2312_pci_setup_resources(struct resource **resource)
2511 +{
2512 + PCI_IOSIZE_REG = 0; // 1M IO size
2513 + PCI_CTRL_REG = 0x06;
2514 +
2515 + resource[0] = &pci_ioport_resource;
2516 + resource[1] = &pci_iomem_resource;
2517 + resource[2] = NULL;
2518 +
2519 + return 1;
2520 +}
2521 +
2522 +//static int sl2312_pci_fault(unsigned long addr, struct pt_regs *regs)
2523 +//{
2524 +// return 1;
2525 +//}
2526 +
2527 +
2528 +/**********************************************************************
2529 + * MASK(disable) PCI interrupt
2530 + * 0: PCI INTA, 1: PCI INTB, ... // for Linux interrupt routing
2531 + * 16: PERR // for PCI module internal use
2532 + * 17: SERR,.. respect to PCI CTRL2 REG
2533 + **********************************************************************/
2534 +void sl2312_pci_mask_irq(unsigned int irq)
2535 +{
2536 + struct pci_bus bus;
2537 + unsigned int tmp;
2538 +
2539 + bus.number = 0;
2540 + sl2312_read_config(&bus, 0, SL2312_PCI_CTRL2, 4, &tmp);
2541 + if (irq < 16) { // for linux int routing
2542 + tmp &= ~(1 << (irq + 16 + 6));
2543 + }
2544 + else {
2545 + tmp &= ~(1 << irq);
2546 + }
2547 + sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
2548 +}
2549 +
2550 +/* UNMASK(enable) PCI interrupt */
2551 +void sl2312_pci_unmask_irq(unsigned int irq)
2552 +{
2553 + struct pci_bus bus;
2554 + unsigned int tmp;
2555 +
2556 + bus.number = 0;
2557 + sl2312_read_config(&bus, 0, SL2312_PCI_CTRL2, 4, &tmp);
2558 + if (irq < 16) { // for linux int routing
2559 + tmp |= (1 << (irq + 16 + 6));
2560 + }
2561 + else {
2562 + tmp |= (1 << irq);
2563 + }
2564 + sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
2565 +}
2566 +
2567 +/* Get PCI interrupt source */
2568 +int sl2312_pci_get_int_src(void)
2569 +{
2570 + struct pci_bus bus;
2571 + unsigned int tmp=0;
2572 +
2573 + bus.number = 0;
2574 + sl2312_read_config(&bus, 0, SL2312_PCI_CTRL2, 4, &tmp);
2575 + if (tmp & (1 << 28)) { // PCI INTA
2576 + sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
2577 + return IRQ_PCI_INTA;
2578 + }
2579 + if (tmp & (1 << 29)) { // PCI INTB
2580 + sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
2581 + return IRQ_PCI_INTB;
2582 + }
2583 + if (tmp & (1 << 30)) { // PCI INTC
2584 + sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
2585 + return IRQ_PCI_INTC;
2586 + }
2587 + if (tmp & (1 << 31)) { // PCI INTD
2588 + sl2312_write_config(&bus, 0, SL2312_PCI_CTRL2, 4, tmp);
2589 + return IRQ_PCI_INTD;
2590 + }
2591 + // otherwise, it should be a PCI error
2592 + return IRQ_PCI;
2593 +}
2594 +
2595 +static irqreturn_t sl2312_pci_irq(int irq, void *devid)
2596 +{
2597 + struct irq_desc *desc;
2598 + struct irqaction *action;
2599 + int retval = 0;
2600 +
2601 + return 1;
2602 +
2603 + irq = sl2312_pci_get_int_src();
2604 + desc = &irq_desc[irq];
2605 + action = desc->action;
2606 + do {
2607 + retval |= action->handler(irq, devid);
2608 + action = action->next;
2609 + } while (action);
2610 +
2611 + return 1;
2612 +}
2613 +
2614 +//extern int (*external_fault)(unsigned long addr, struct pt_regs *regs);
2615 +
2616 +void __init sl2312_pci_preinit(void)
2617 +{
2618 + struct pci_bus bus;
2619 + unsigned long flags;
2620 + unsigned int temp;
2621 + int ret;
2622 +
2623 + /*
2624 + * Hook in our fault handler for PCI errors
2625 + */
2626 +// external_fault = sl2312_pci_fault;
2627 +
2628 + spin_lock_irqsave(&sl2312_pci_lock, flags);
2629 +
2630 + /*
2631 + * Grab the PCI interrupt.
2632 + */
2633 + ret = request_irq(IRQ_PCI, sl2312_pci_irq, 0, "sl2312 pci int", NULL);
2634 + if (ret)
2635 + printk(KERN_ERR "PCI: unable to grab PCI error "
2636 + "interrupt: %d\n", ret);
2637 +
2638 + spin_unlock_irqrestore(&sl2312_pci_lock, flags);
2639 +
2640 + // setup pci bridge
2641 + bus.number = 0; /* device 0, function 0 */
2642 + temp = (SL2312_PCI_DMA_MEM1_BASE & 0xfff00000) | (SL2312_PCI_DMA_MEM1_SIZE << 16);
2643 + sl2312_write_config(&bus, 0, SL2312_PCI_MEM1_BASE_SIZE, 4, temp);
2644 +}
2645 +
2646 +/*
2647 + * No swizzle on SL2312
2648 + */
2649 +static u8 __init sl2312_pci_swizzle(struct pci_dev *dev, u8 *pinp)
2650 +{
2651 + return PCI_SLOT(dev->devfn);
2652 +}
2653 +
2654 +/*
2655 + * map the specified device/slot/pin to an IRQ. This works out such
2656 + * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
2657 + */
2658 +static int __init sl2312_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
2659 +{
2660 + int intnr = ((slot + (pin - 1)) & 3) + 4; /* the IRQ number of PCI bridge */
2661 +
2662 + // printk("%s : slot = %d pin = %d \n",__func__,slot,pin);
2663 + switch (slot)
2664 + {
2665 + case 12:
2666 + if (pin==1)
2667 + {
2668 + intnr = 3;
2669 + }
2670 + else
2671 + {
2672 + intnr = 0;
2673 + }
2674 + break;
2675 + case 11:
2676 + intnr = (2 + (pin - 1)) & 3;
2677 + break;
2678 + case 10:
2679 + intnr = (1 + (pin - 1)) & 3;
2680 + break;
2681 + case 9:
2682 + intnr = (pin - 1) & 3;
2683 + break;
2684 + }
2685 +// if (slot == 10)
2686 +// intnr = (1 + (pin - 1)) & 3;
2687 +// else if (slot == 9)
2688 +// intnr = (pin - 1) & 3;
2689 + return (IRQ_PCI_INTA + intnr);
2690 +}
2691 +
2692 +struct pci_bus * __init sl2312_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
2693 +{
2694 + return (pci_scan_bus(0, &sl2312_pci_ops, sysdata));
2695 +
2696 +}
2697 +
2698 +int __init sl2312_pci_setup(int nr, struct pci_sys_data *sys)
2699 +{
2700 + int ret = 0;
2701 +
2702 + if (nr == 0) {
2703 + ret = sl2312_pci_setup_resources(sys->resource);
2704 + }
2705 +
2706 + return ret;
2707 +}
2708 +
2709 +
2710 +struct hw_pci sl2312_pci __initdata = {
2711 + .setup = sl2312_pci_setup,
2712 + .preinit = sl2312_pci_preinit,
2713 + .nr_controllers = 1,
2714 + .swizzle = sl2312_pci_swizzle,
2715 + .map_irq = sl2312_pci_map_irq,
2716 + .scan = sl2312_pci_scan_bus,
2717 +};
2718 +
2719 +static int __init sl2312_pci_init(void)
2720 +{
2721 + if (machine_is_sl2312())
2722 + pci_common_init(&sl2312_pci);
2723 + return 0;
2724 +}
2725 +
2726 +subsys_initcall(sl2312_pci_init);
2727 Index: linux-2.6.23.16/arch/arm/mach-sl2312/sl2312-otg-1.c
2728 ===================================================================
2729 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2730 +++ linux-2.6.23.16/arch/arm/mach-sl2312/sl2312-otg-1.c 2008-03-15 16:53:18.340655940 +0200
2731 @@ -0,0 +1,64 @@
2732 +/*
2733 + * linux/arch/arm/mach-pxa/sl2312.c
2734 + *
2735 + * Author: Nicolas Pitre
2736 + * Created: Nov 05, 2002
2737 + * Copyright: MontaVista Software Inc.
2738 + *
2739 + * Code specific to sl2312 aka Bulverde.
2740 + *
2741 + * This program is free software; you can redistribute it and/or modify
2742 + * it under the terms of the GNU General Public License version 2 as
2743 + * published by the Free Software Foundation.
2744 + */
2745 +#include <linux/module.h>
2746 +#include <linux/kernel.h>
2747 +#include <linux/init.h>
2748 +#include <linux/pm.h>
2749 +#include <linux/device.h>
2750 +#include "asm/arch/sl2312.h"
2751 +#include "asm/arch/irqs.h"
2752 +#include <asm/hardware.h>
2753 +#include <asm/irq.h>
2754 +#include <linux/platform_device.h>
2755 +
2756 +/*
2757 + * device registration specific to sl2312.
2758 + */
2759 +
2760 +static u64 sl2312_dmamask_1 = 0xffffffffUL;
2761 +
2762 +static struct resource sl2312_otg_resources_1[] = {
2763 + [0] = {
2764 + .start = 0x69000000,
2765 + .end = 0x69000fff,
2766 + .flags = IORESOURCE_MEM,
2767 + },
2768 + [1] = {
2769 + .start = IRQ_USB1,
2770 + .end = IRQ_USB1,
2771 + .flags = IORESOURCE_IRQ,
2772 + },
2773 +};
2774 +
2775 +static struct platform_device ehci_1_device = {
2776 + .name = "ehci-hcd-FOTG2XX",
2777 + .id = -1,
2778 + .dev = {
2779 + .dma_mask = &sl2312_dmamask_1,
2780 + .coherent_dma_mask = 0xffffffff,
2781 + },
2782 + .num_resources = ARRAY_SIZE(sl2312_otg_resources_1),
2783 + .resource = sl2312_otg_resources_1,
2784 +};
2785 +
2786 +static struct platform_device *devices[] __initdata = {
2787 + &ehci_1_device,
2788 +};
2789 +
2790 +static int __init sl2312_1_init(void)
2791 +{
2792 + return platform_add_devices(devices, ARRAY_SIZE(devices));
2793 +}
2794 +
2795 +subsys_initcall(sl2312_1_init);
2796 Index: linux-2.6.23.16/arch/arm/mach-sl2312/sl2312-otg.c
2797 ===================================================================
2798 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2799 +++ linux-2.6.23.16/arch/arm/mach-sl2312/sl2312-otg.c 2008-03-14 12:33:51.324219457 +0200
2800 @@ -0,0 +1,87 @@
2801 +/*
2802 + * linux/arch/arm/mach-pxa/sl2312.c
2803 + *
2804 + * Author: Nicolas Pitre
2805 + * Created: Nov 05, 2002
2806 + * Copyright: MontaVista Software Inc.
2807 + *
2808 + * Code specific to sl2312 aka Bulverde.
2809 + *
2810 + * This program is free software; you can redistribute it and/or modify
2811 + * it under the terms of the GNU General Public License version 2 as
2812 + * published by the Free Software Foundation.
2813 + */
2814 +#include <linux/module.h>
2815 +#include <linux/kernel.h>
2816 +#include <linux/init.h>
2817 +#include <linux/pm.h>
2818 +#include <linux/device.h>
2819 +#include "asm/arch/sl2312.h"
2820 +#include "asm/arch/irqs.h"
2821 +#include <asm/hardware.h>
2822 +#include <asm/irq.h>
2823 +#include <linux/platform_device.h>
2824 +
2825 +/*
2826 + * device registration specific to sl2312.
2827 + */
2828 +
2829 +static u64 sl2312_dmamask = 0xffffffffUL;
2830 +
2831 +static struct resource sl2312_otg_resources_1[] = {
2832 + [0] = {
2833 + .start = 0x68000000,
2834 + .end = 0x68000fff,
2835 + .flags = IORESOURCE_MEM,
2836 + },
2837 + [1] = {
2838 + .start = IRQ_USB0,
2839 + .end = IRQ_USB0,
2840 + .flags = IORESOURCE_IRQ,
2841 + },
2842 +};
2843 +static struct resource sl2312_otg_resources_2[] = {
2844 + [2] = {
2845 + .start = 0x69000000,
2846 + .end = 0x69000fff,
2847 + .flags = IORESOURCE_MEM,
2848 + },
2849 + [3] = {
2850 + .start = IRQ_USB1,
2851 + .end = IRQ_USB1,
2852 + .flags = IORESOURCE_IRQ,
2853 + },
2854 +};
2855 +
2856 +static struct platform_device ehci_device_1 = {
2857 + .name = "ehci-hcd-FOTG2XX",
2858 + .id = 1,
2859 + .dev = {
2860 + .dma_mask = &sl2312_dmamask,
2861 + .coherent_dma_mask = 0xffffffff,
2862 + },
2863 + .num_resources = ARRAY_SIZE(sl2312_otg_resources_1),
2864 + .resource = sl2312_otg_resources_1,
2865 +};
2866 +
2867 +static struct platform_device ehci_device_2 = {
2868 + .name = "ehci-hcd-FOTG2XX",
2869 + .id = 2,
2870 + .dev = {
2871 + .dma_mask = &sl2312_dmamask,
2872 + .coherent_dma_mask = 0xffffffff,
2873 + },
2874 + .num_resources = ARRAY_SIZE(sl2312_otg_resources_2),
2875 + .resource = sl2312_otg_resources_2,
2876 +};
2877 +
2878 +static struct platform_device *devices[] __initdata = {
2879 + &ehci_device_1, /* &ehci_device_2, */
2880 +};
2881 +
2882 +static int __init sl2312_init(void)
2883 +{
2884 + return platform_add_devices(devices, ARRAY_SIZE(devices));
2885 +}
2886 +
2887 +subsys_initcall(sl2312_init);
2888 Index: linux-2.6.23.16/arch/arm/mach-sl2312/sl3516_device.c
2889 ===================================================================
2890 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2891 +++ linux-2.6.23.16/arch/arm/mach-sl2312/sl3516_device.c 2008-03-14 12:19:14.774267722 +0200
2892 @@ -0,0 +1,89 @@
2893 +/*
2894 + * linux/arch/arm/mach-2312/sl3516_device.c
2895 + *
2896 + * Author: Nicolas Pitre
2897 + * Created: Nov 05, 2002
2898 + * Copyright: MontaVista Software Inc.
2899 + *
2900 + * Code specific to sl2312 aka Bulverde.
2901 + *
2902 + * This program is free software; you can redistribute it and/or modify
2903 + * it under the terms of the GNU General Public License version 2 as
2904 + * published by the Free Software Foundation.
2905 + */
2906 +#include <linux/module.h>
2907 +#include <linux/kernel.h>
2908 +#include <linux/init.h>
2909 +#include <linux/pm.h>
2910 +#include <linux/device.h>
2911 +#include <linux/platform_device.h>
2912 +#include "asm/arch/sl2312.h"
2913 +#include "asm/arch/irqs.h"
2914 +#include <asm/hardware.h>
2915 +#include <asm/irq.h>
2916 +
2917 +/*
2918 + * device registration specific to sl2312.
2919 + */
2920 +
2921 +static u64 sl3516_dmamask = 0xffffffffUL;
2922 +
2923 +static struct resource sl3516_sata_resources[] = {
2924 + [0] = {
2925 + .start = 0x63400000,
2926 + .end = 0x63400040,
2927 + .flags = IORESOURCE_MEM,
2928 + },
2929 + [1] = {
2930 + .start = IRQ_IDE1,
2931 + .end = IRQ_IDE1,
2932 + .flags = IORESOURCE_IRQ,
2933 + },
2934 +};
2935 +
2936 +static struct platform_device sata_device = {
2937 + .name = "lepus-sata",
2938 + .id = -1,
2939 + .dev = {
2940 + .dma_mask = &sl3516_dmamask,
2941 + .coherent_dma_mask = 0xffffffff,
2942 + },
2943 + .num_resources = ARRAY_SIZE(sl3516_sata_resources),
2944 + .resource = sl3516_sata_resources,
2945 +};
2946 +
2947 +static struct resource sl3516_sata0_resources[] = {
2948 + [0] = {
2949 + .start = 0x63000000,
2950 + .end = 0x63000040,
2951 + .flags = IORESOURCE_MEM,
2952 + },
2953 + [1] = {
2954 + .start = IRQ_IDE0,
2955 + .end = IRQ_IDE0,
2956 + .flags = IORESOURCE_IRQ,
2957 + },
2958 +};
2959 +
2960 +static struct platform_device sata0_device = {
2961 + .name = "lepus-sata0",
2962 + .id = -1,
2963 + .dev = {
2964 + .dma_mask = &sl3516_dmamask,
2965 + .coherent_dma_mask = 0xffffffff,
2966 + },
2967 + .num_resources = ARRAY_SIZE(sl3516_sata0_resources),
2968 + .resource = sl3516_sata0_resources,
2969 +};
2970 +
2971 +static struct platform_device *sata_devices[] __initdata = {
2972 + &sata_device,
2973 + &sata0_device,
2974 +};
2975 +
2976 +static int __init sl3516_init(void)
2977 +{
2978 + return platform_add_devices(sata_devices, ARRAY_SIZE(sata_devices));
2979 +}
2980 +
2981 +subsys_initcall(sl3516_init);
2982 Index: linux-2.6.23.16/arch/arm/mach-sl2312/time.c
2983 ===================================================================
2984 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2985 +++ linux-2.6.23.16/arch/arm/mach-sl2312/time.c 2008-03-14 12:16:06.263525107 +0200
2986 @@ -0,0 +1,134 @@
2987 +/*
2988 + * linux/include/asm-arm/arch-epxa10db/time.h
2989 + *
2990 + * Copyright (C) 2001 Altera Corporation
2991 + *
2992 + * This program is free software; you can redistribute it and/or modify
2993 + * it under the terms of the GNU General Public License as published by
2994 + * the Free Software Foundation; either version 2 of the License, or
2995 + * (at your option) any later version.
2996 + *
2997 + * This program is distributed in the hope that it will be useful,
2998 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2999 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3000 + * GNU General Public License for more details.
3001 + *
3002 + * You should have received a copy of the GNU General Public License
3003 + * along with this program; if not, write to the Free Software
3004 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3005 + */
3006 +#include <linux/interrupt.h>
3007 +#include <linux/irq.h>
3008 +#include <asm/io.h>
3009 +#include <asm/system.h>
3010 +#include <asm/leds.h>
3011 +#include <asm/arch/hardware.h>
3012 +#include <asm/mach/time.h>
3013 +#define TIMER_TYPE (volatile unsigned int*)
3014 +#include <asm/arch/timer.h>
3015 +// #define FIQ_PLUS 1
3016 +
3017 +
3018 +/*
3019 + * IRQ handler for the timer
3020 + */
3021 +static irqreturn_t sl2312_timer_interrupt(int irq, void *dev_id)
3022 +{
3023 +// unsigned int led;
3024 + // ...clear the interrupt
3025 +#ifdef FIQ_PLUS
3026 + *((volatile unsigned int *)FIQ_CLEAR(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER1_MASK);
3027 +#else
3028 + *((volatile unsigned int *)IRQ_CLEAR(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER2_MASK);
3029 +#endif
3030 +
3031 +#if 0
3032 + if(!(jiffies % HZ))
3033 + {
3034 + led = jiffies / HZ;
3035 +// printk("ticks %x \n", led);
3036 + }
3037 + do_leds();
3038 + do_timer(regs);
3039 + do_profile(regs);
3040 +#endif
3041 + timer_tick();
3042 + return IRQ_HANDLED;
3043 +}
3044 +
3045 +static struct irqaction sl2312_timer_irq = {
3046 + .name = "SL2312 Timer Tick",
3047 + .flags = IRQF_DISABLED | IRQF_TIMER,
3048 + .handler = sl2312_timer_interrupt,
3049 +};
3050 +
3051 +unsigned long sl2312_gettimeoffset (void)
3052 +{
3053 + return 0L;
3054 +}
3055 +
3056 +/*
3057 + * Set up timer interrupt, and return the current time in seconds.
3058 + */
3059 +void __init sl2312_time_init(void)
3060 +{
3061 + // For clock rate adjusting
3062 + unsigned int tick_rate=0;
3063 +
3064 +#ifdef CONFIG_SL3516_ASIC
3065 + unsigned int clock_rate_base = 130000000;
3066 + unsigned int reg_v=0;
3067 +
3068 + //--> Add by jason for clock adjust
3069 + reg_v = readl(IO_ADDRESS((SL2312_GLOBAL_BASE+GLOBAL_STATUS)));
3070 + reg_v >>= 15;
3071 + tick_rate = (clock_rate_base + (reg_v & 0x07)*10000000);
3072 +
3073 + // FPGA use AHB bus tick rate
3074 + printk("Bus: %dMHz",tick_rate/1000000);
3075 +
3076 + tick_rate /= 6; // APB bus run AHB*(1/6)
3077 +
3078 + switch((reg_v>>3)&3){
3079 + case 0: printk("(1/1)\n") ;
3080 + break;
3081 + case 1: printk("(3/2)\n") ;
3082 + break;
3083 + case 2: printk("(24/13)\n") ;
3084 + break;
3085 + case 3: printk("(2/1)\n") ;
3086 + break;
3087 + }
3088 + //<--
3089 +#else
3090 + printk("Bus: %dMHz(1/1)\n",CLOCK_TICK_RATE/1000000); // FPGA use 20MHz
3091 + tick_rate = CLOCK_TICK_RATE;
3092 +#endif
3093 +
3094 +
3095 + /*
3096 + * Make irqs happen for the system timer
3097 + */
3098 + // initialize timer interrupt
3099 + // low active and edge trigger
3100 +#ifdef FIQ_PLUS
3101 + *((volatile unsigned int *)FIQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER1_MASK);
3102 + *((volatile unsigned int *)FIQ_LEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER1_MASK);
3103 + setup_irq(IRQ_TIMER1, &sl2312_timer_irq);
3104 + /* Start the timer */
3105 + *TIMER_COUNT(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(tick_rate/HZ);
3106 + *TIMER_LOAD(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(tick_rate/HZ);
3107 + *TIMER_CR(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(TIMER_1_CR_ENABLE_MSK|TIMER_1_CR_INT_MSK);
3108 +#else
3109 + *((volatile unsigned int *)IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER2_MASK);
3110 + *((volatile unsigned int *)IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_TIMER2_MASK);
3111 + setup_irq(IRQ_TIMER2, &sl2312_timer_irq);
3112 + /* Start the timer */
3113 + *TIMER_COUNT(IO_ADDRESS(SL2312_TIMER2_BASE))=(unsigned int)(tick_rate/HZ);
3114 + *TIMER_LOAD(IO_ADDRESS(SL2312_TIMER2_BASE))=(unsigned int)(tick_rate/HZ);
3115 + *TIMER_CR(IO_ADDRESS(SL2312_TIMER1_BASE))=(unsigned int)(TIMER_2_CR_ENABLE_MSK|TIMER_2_CR_INT_MSK);
3116 +#endif
3117 +
3118 +}
3119 +
3120 +
3121 Index: linux-2.6.23.16/arch/arm/mach-sl2312/xor.c
3122 ===================================================================
3123 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3124 +++ linux-2.6.23.16/arch/arm/mach-sl2312/xor.c 2008-03-13 17:48:24.508798285 +0200
3125 @@ -0,0 +1,1200 @@
3126 +/*
3127 + * arch/arm/mach-sl2312/xor.c
3128 + *
3129 + * Support functions for the Gemini Soc. This is
3130 + * a HW XOR unit that is specifically designed for use with RAID5
3131 + * applications. This driver provides an interface that is used by
3132 + * the Linux RAID stack.
3133 + *
3134 + * Original Author: Jason Lee<jason@storlink.com.tw>
3135 + *
3136 + * Contributors:Sanders<sanders@storlink.com.tw>
3137 + Jason Lee<jason@storlink.com.tw>
3138 + *
3139 + *
3140 + * Maintainer: Jason Lee<jason@storlink.com.tw>
3141 + *
3142 + * Copyright (C) 2005 Storlink Corporation
3143 + *
3144 + * This program is free software; you can redistribute it and/or modify
3145 + * it under the terms of the GNU General Public License version 2 as
3146 + * published by the Free Software Foundation.
3147 + *
3148 + *
3149 + * History: (06/25/2005, DJ) Initial Creation
3150 + *
3151 + * Versing 1.0.0 Initial version
3152 + */
3153 +
3154 +#include <linux/types.h>
3155 +#include <linux/init.h>
3156 +#include <linux/sched.h>
3157 +#include <linux/spinlock.h>
3158 +#include <linux/slab.h>
3159 +#include <linux/errno.h>
3160 +#include <linux/interrupt.h>
3161 +#include <linux/sched.h>
3162 +#include <linux/wait.h>
3163 +#include <linux/list.h>
3164 +#include <linux/pci.h>
3165 +#include <linux/delay.h>
3166 +#include <linux/dma-mapping.h>
3167 +#include <linux/mm.h>
3168 +#include <asm/irq.h>
3169 +#include <asm/delay.h>
3170 +#include <asm/uaccess.h>
3171 +#include <asm/cacheflush.h>
3172 +#include <asm/hardware.h>
3173 +#include <asm/arch/xor.h>
3174 +#include <asm/pci.h>
3175 +#include <linux/version.h>
3176 +
3177 +/*
3178 + * pick up local definitions
3179 + */
3180 +#define XOR_SW_FILL_IN
3181 +#include "hw_xor.h"
3182 +
3183 +
3184 +//#define XOR_DEBUG
3185 +//#define XOR_TEST 1
3186 +#ifdef XOR_TEST
3187 +#define TEST_ITERATION 1000
3188 +#define SPIN_WAIT 1
3189 +#endif
3190 +#ifdef XOR_DEBUG
3191 +#define DPRINTK(s, args...) printk("Gemini XOR: " s "\n", ## args)
3192 +#define DENTER() DPRINTK("Entered...\n");
3193 +#define DEXIT() DPRINTK("Exited...\n");
3194 +#else
3195 +#define DPRINTK(s, args...)
3196 +#define DENTER()
3197 +#define DEXIT()
3198 +#endif
3199 +
3200 +//#define SPIN_WAIT
3201 +
3202 +/* globals */
3203 +static RAID_T tp;
3204 +static RAID_TXDMA_CTRL_T txdma_ctrl;
3205 +RAID_RXDMA_CTRL_T rxdma_ctrl;
3206 +
3207 +//#ifndef SPIN_WAIT
3208 +static spinlock_t raid_lock;
3209 +//#endif
3210 +
3211 +static unsigned int tx_desc_virtual_base;
3212 +static unsigned int rx_desc_virtual_base;
3213 +RAID_DESCRIPTOR_T *tx_desc_ptr;
3214 +RAID_DESCRIPTOR_T *rx_desc_ptr;
3215 +
3216 +/* static prototypes */
3217 +#define DMA_MALLOC(size,handle) pci_alloc_consistent(NULL,size,handle)
3218 +#define DMA_MFREE(mem,size,handle) pci_free_consistent(NULL,size,mem,handle)
3219 +
3220 +static int gemini_xor_init_desc(void);
3221 +
3222 +static unsigned int raid_read_reg(unsigned int offset)
3223 +{
3224 + unsigned int reg_val;
3225 +
3226 + reg_val = readl(RAID_BASE_ADDR + offset);
3227 + return (reg_val);
3228 +}
3229 +
3230 +static void raid_write_reg(unsigned int offset,unsigned int data,unsigned int bit_mask)
3231 +{
3232 + unsigned int reg_val;
3233 + unsigned int *addr;
3234 +
3235 + reg_val = ( raid_read_reg(offset) & (~bit_mask) ) | (data & bit_mask);
3236 + addr = (unsigned int *)(RAID_BASE_ADDR + offset);
3237 + writel(reg_val,addr);
3238 + return;
3239 +}
3240 +
3241 +#ifndef SPIN_WAIT
3242 +__inline__ void xor_queue_descriptor(void)
3243 +{
3244 + unsigned int flags,status=1;
3245 +
3246 + DPRINTK("Going to sleep");
3247 +
3248 + while(status){
3249 + yield();
3250 + //schedule();
3251 + spin_lock_irqsave(&raid_lock,flags);
3252 + status = tp.busy;
3253 + spin_unlock_irqrestore(&raid_lock, flags);
3254 + }
3255 +// tp.status = COMPLETE;
3256 + DPRINTK("woken up!");
3257 +
3258 +}
3259 +#endif
3260 +
3261 +#ifdef SPIN_WAIT
3262 +static void gemini_xor_isr(int d_n)
3263 +#else
3264 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28)
3265 +static void gemini_xor_isr(int irq, void *dev_id, struct pt_regs *regs)
3266 +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
3267 +static irqreturn_t gemini_xor_isr(int irq, void *dev_instance, struct pt_regs *regs)
3268 +#endif
3269 +#endif
3270 +{
3271 +
3272 + unsigned int err;
3273 + RAID_DMA_STATUS_T dma_status;
3274 +// RAID_DESCRIPTOR_T *rdesc,*tdesc;
3275 +// unsigned int *paddr;
3276 +
3277 + dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS);
3278 +#ifdef SPIN_WAIT
3279 + while( (dma_status.bits32& (1<<31) ) ==0 ){
3280 + udelay(1);
3281 + dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS);
3282 + }
3283 +
3284 +/* tdesc = tp.tx_first_desc;
3285 + rdesc = tp.rx_first_desc;
3286 + for(d_n;d_n>0;d_n--){
3287 + if( tdesc->func_ctrl.bits.own == DMA ){
3288 + paddr = tdesc;
3289 + printk("error tx desc:0x%x\n",*paddr++);
3290 + printk("error tx desc:0x%x\n",*paddr++);
3291 + printk("error tx desc:0s%x\n",*paddr++);
3292 + printk("error tx desc:0x%x\n",*paddr);
3293 + while(1);
3294 + }
3295 + tdesc = (RAID_DESCRIPTOR_T *)((tdesc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3296 + }
3297 +
3298 + if( rdesc->func_ctrl.bits.own == DMA ){
3299 + paddr = rdesc;
3300 + printk("error rx desc:0x%x\n",*paddr++);
3301 + printk("error rx desc:0x%x\n",*paddr++);
3302 + printk("error rx desc:0s%x\n",*paddr++);
3303 + printk("error rx desc:0x%x\n",*paddr);
3304 + while(1);
3305 + }
3306 +*/
3307 +#endif
3308 +
3309 + if(dma_status.bits32 & ((1<<31)|(1<<26))){
3310 + // if no bug , we can turn off rx finish interrupt
3311 + dma_status.bits32 = raid_read_reg(RAID_DMA_STATUS);
3312 + err = raid_read_reg(RAID_DMA_DEVICE_ID);
3313 + tp.busy = 0;
3314 +
3315 + if(err&0x00FF0000){
3316 + tp.status = ERROR;
3317 + printk("XOR:<HW>%s error code %x\n",(err&0x00F00000)?"tx":"rx",err);
3318 +
3319 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28)
3320 + return ;
3321 +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
3322 +#ifndef SPIN_WAIT
3323 + return IRQ_RETVAL(IRQ_HANDLED);
3324 +#endif
3325 +#endif
3326 + }
3327 + // 16~19 rx error code
3328 + // 20~23 tx error codd
3329 +
3330 + dma_status.bits.tsFinishI = 1;
3331 + dma_status.bits.rsFinishI = 1;
3332 + raid_write_reg(RAID_DMA_STATUS, dma_status.bits32,0x84000000); // clear INT
3333 +
3334 +// printk("xor %d\n",d_n);
3335 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28)
3336 + return ;
3337 +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
3338 +#ifndef SPIN_WAIT
3339 + return IRQ_RETVAL(IRQ_HANDLED);
3340 +#endif
3341 +#endif
3342 + }
3343 +
3344 + #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,28)
3345 + return ;
3346 + #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
3347 + #ifndef SPIN_WAIT
3348 + printk("XOR: DMA status register(0x%8x)\n",dma_status.bits32);
3349 + return IRQ_RETVAL(IRQ_HANDLED);
3350 + #endif
3351 + #endif
3352 +}
3353 +
3354 +void
3355 +xor_gemini_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
3356 +{
3357 + int status=0;
3358 + unsigned int flags;
3359 +
3360 + if(bytes > (1<<(SRAM_PAR_SIZE+11))){
3361 + printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
3362 + }
3363 +
3364 + spin_lock_irqsave(&raid_lock,flags);
3365 + while(tp.status != COMPLETE){
3366 + spin_unlock_irqrestore(&raid_lock, flags);
3367 + //printk("XOR yield2\n");
3368 +#ifdef XOR_SW_FILL_IN
3369 + xor_arm4regs_2(bytes,p1,p2);
3370 + return ;
3371 +#else
3372 + yield();
3373 +#endif
3374 + }
3375 + spin_unlock_irqrestore(&raid_lock, flags);
3376 + tp.status = RUNNING;
3377 +
3378 + // flush the cache to memory before H/W XOR touches them
3379 + consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);
3380 + consistent_sync(p2, bytes, DMA_TO_DEVICE);
3381 +
3382 +
3383 + tp.tx_desc = tp.tx_first_desc;
3384 + tp.rx_desc = tp.rx_first_desc;
3385 + if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
3386 + // prepare tx descript
3387 + raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff);
3388 + tp.tx_desc->buf_addr = (unsigned int)__pa(p1); // physical address
3389 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3390 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 2; // first descript
3391 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3392 + tp.tx_desc->flg_status.bits32 = 0x00020000;
3393 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3394 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3395 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3396 + wmb();
3397 + tp.tx_desc = tp.tx_cur_desc;
3398 + tp.tx_desc->buf_addr = (unsigned int)__pa(p2); // pysical address
3399 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3400 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 1; // last descript
3401 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3402 + tp.tx_desc->flg_status.bits32 = 0x00010000;
3403 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3404 + tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
3405 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); // keep last descript
3406 +
3407 + wmb();
3408 + // prepare rx descript
3409 + raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFf);
3410 + tp.rx_desc->buf_addr = (unsigned int)__pa(p1);
3411 + tp.rx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3412 + tp.rx_desc->flg_status.bits32 = 0; // link data from XOR
3413 +// tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3414 + tp.rx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3415 + tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
3416 +
3417 + }
3418 + else{
3419 + /* no free tx descriptor */
3420 + printk("XOR:no free tx descript");
3421 + return ;
3422 + }
3423 +
3424 + // change status
3425 +// tp.status = RUNNING;
3426 + status = tp.busy = 1;
3427 +
3428 + // start tx DMA
3429 + rxdma_ctrl.bits.rd_start = 1;
3430 + // start rx DMA
3431 + txdma_ctrl.bits.td_start = 1;
3432 +
3433 + raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
3434 + raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);
3435 +
3436 +#ifdef SPIN_WAIT
3437 + gemini_xor_isr(2);
3438 +#else
3439 + xor_queue_descriptor();
3440 +#endif
3441 +
3442 + tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*2) ;
3443 + tp.status = COMPLETE;
3444 +// tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) ;
3445 +// tp.rx_desc = tp.rx_first_desc ;
3446 +// tp.rx_desc->func_ctrl.bits.own = DMA;
3447 +
3448 +}
3449 +
3450 +void
3451 +xor_gemini_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
3452 + unsigned long *p3)
3453 +{
3454 + int status=0;
3455 + unsigned int flags;
3456 +
3457 + if(bytes > (1<<(SRAM_PAR_SIZE+11))){
3458 + printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
3459 + }
3460 +
3461 + spin_lock_irqsave(&raid_lock,flags);
3462 + if(tp.status != COMPLETE){
3463 + spin_unlock_irqrestore(&raid_lock, flags);
3464 + //printk("XOR yield3\n");
3465 +#ifdef XOR_SW_FILL_IN
3466 + xor_arm4regs_3(bytes,p1,p2,p3);
3467 + return;
3468 +#else
3469 + yield();
3470 +#endif
3471 + }
3472 + spin_unlock_irqrestore(&raid_lock, flags);
3473 + tp.status = RUNNING;
3474 +
3475 + // flush the cache to memory before H/W XOR touches them
3476 + consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);
3477 + consistent_sync(p2, bytes, DMA_TO_DEVICE);
3478 + consistent_sync(p3, bytes, DMA_TO_DEVICE);
3479 +
3480 + tp.tx_desc = tp.tx_first_desc;
3481 + tp.rx_desc = tp.rx_first_desc;
3482 + if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
3483 + // prepare tx descript
3484 + raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff);
3485 + tp.tx_desc->buf_addr = (unsigned int)__pa(p1); // physical address
3486 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3487 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 2; // first descript
3488 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3489 + tp.tx_desc->flg_status.bits32 = 0x00020000;
3490 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3491 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3492 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3493 +
3494 + tp.tx_desc = tp.tx_cur_desc;
3495 + tp.tx_desc->buf_addr = (unsigned int)__pa(p2); // pysical address
3496 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3497 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript
3498 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3499 + tp.tx_desc->flg_status.bits32 = 0x0000000;
3500 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3501 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3502 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3503 +
3504 + tp.tx_desc = tp.tx_cur_desc;
3505 + tp.tx_desc->buf_addr = (unsigned int)__pa(p3); // pysical address
3506 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3507 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 1; // last descript
3508 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3509 + tp.tx_desc->flg_status.bits32 = 0x00010000;
3510 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3511 + tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
3512 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); // keep last descript
3513 +
3514 + // prepare rx descript
3515 + raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFf);
3516 + tp.rx_desc->buf_addr = (unsigned int)__pa(p1);
3517 + tp.rx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3518 + tp.rx_desc->flg_status.bits32 = 0; // link data from XOR
3519 +// tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3520 + tp.rx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3521 + tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
3522 +
3523 + }
3524 + else{
3525 + /* no free tx descriptor */
3526 + printk("XOR:no free tx descript \n");
3527 + return ;
3528 + }
3529 +
3530 + // change status
3531 +// tp.status = RUNNING;
3532 + status = tp.busy = 1;
3533 +
3534 + // start tx DMA
3535 + rxdma_ctrl.bits.rd_start = 1;
3536 + // start rx DMA
3537 + txdma_ctrl.bits.td_start = 1;
3538 + wmb();
3539 + raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
3540 + raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);
3541 +
3542 +#ifdef SPIN_WAIT
3543 + gemini_xor_isr(3);
3544 +#else
3545 + xor_queue_descriptor();
3546 +#endif
3547 + tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*3) | 0x0B;
3548 + tp.status = COMPLETE;
3549 +// tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) | 0x0B;
3550 + //tp.rx_desc = tp.rx_first_desc ;
3551 +// tp.rx_desc->func_ctrl.bits.own = DMA;
3552 +
3553 +}
3554 +
3555 +void
3556 +xor_gemini_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
3557 + unsigned long *p3, unsigned long *p4)
3558 +{
3559 + int status=0;
3560 + unsigned int flags;
3561 +
3562 + if(bytes > (1<<(SRAM_PAR_SIZE+11))){
3563 + printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
3564 + }
3565 +
3566 + spin_lock_irqsave(&raid_lock,flags);
3567 + if(tp.status != COMPLETE){
3568 + spin_unlock_irqrestore(&raid_lock, flags);
3569 + //printk("S\n");
3570 +#ifdef XOR_SW_FILL_IN
3571 + xor_arm4regs_4(bytes,p1,p2,p3,p4);
3572 + return;
3573 +#else
3574 + msleep(1);
3575 + yield();
3576 +#endif
3577 + }
3578 + spin_unlock_irqrestore(&raid_lock, flags);
3579 +
3580 + tp.status = RUNNING;
3581 +
3582 + // flush the cache to memory before H/W XOR touches them
3583 + consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);
3584 + consistent_sync(p2, bytes, DMA_TO_DEVICE);
3585 + consistent_sync(p3, bytes, DMA_TO_DEVICE);
3586 + consistent_sync(p4, bytes, DMA_TO_DEVICE);
3587 +
3588 + tp.tx_desc = tp.tx_first_desc;
3589 + tp.rx_desc = tp.rx_first_desc;
3590 + if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
3591 + // prepare tx descript
3592 + raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff);
3593 + tp.tx_desc->buf_addr = (unsigned int)__pa(p1); // physical address
3594 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3595 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 2; // first descript
3596 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3597 + tp.tx_desc->flg_status.bits32 = 0x00020000;
3598 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3599 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3600 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3601 +
3602 + tp.tx_desc = tp.tx_cur_desc;
3603 + tp.tx_cur_desc->buf_addr = (unsigned int)__pa(p2); // pysical address
3604 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3605 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript
3606 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3607 + tp.tx_desc->flg_status.bits32 = 0x00000000;
3608 + tp.tx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3609 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3610 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3611 +
3612 + tp.tx_desc = tp.tx_cur_desc;
3613 + tp.tx_desc->buf_addr = (unsigned int)__pa(p3); // pysical address
3614 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3615 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript
3616 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3617 + tp.tx_desc->flg_status.bits32 = 0x00000000;
3618 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3619 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3620 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3621 +
3622 +
3623 + tp.tx_desc = tp.tx_cur_desc;
3624 + tp.tx_desc->buf_addr = (unsigned int)__pa(p4); // pysical address
3625 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3626 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 1; // last descript
3627 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3628 + tp.tx_desc->flg_status.bits32 = 0x00010000;
3629 +// tp.tx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3630 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3631 + tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
3632 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base); // keep last descript
3633 +
3634 + // prepare rx descript
3635 + raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFF);
3636 + tp.rx_desc->buf_addr = (unsigned int)__pa(p1);
3637 + tp.rx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3638 + tp.rx_desc->flg_status.bits32 = 0; // link data from XOR
3639 +// tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3640 + tp.rx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3641 + tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
3642 +
3643 + }
3644 + else{
3645 + /* no free tx descriptor */
3646 + printk("XOR:no free tx descript");
3647 + return ;
3648 + }
3649 +
3650 + // change status
3651 +// tp.status = RUNNING;
3652 + status = tp.busy = 1;
3653 +
3654 + // start tx DMA
3655 + rxdma_ctrl.bits.rd_start = 1;
3656 + // start rx DMA
3657 + txdma_ctrl.bits.td_start = 1;
3658 + wmb();
3659 + raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
3660 + raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);
3661 +
3662 +#ifdef SPIN_WAIT
3663 + gemini_xor_isr(4);
3664 +#else
3665 + xor_queue_descriptor();
3666 +#endif
3667 +
3668 + tp.tx_desc->next_desc_addr.bits32 = ((unsigned long)tp.tx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*4) | 0x0B;
3669 + tp.status = COMPLETE;
3670 +// tp.rx_desc->next_desc_addr.bits32 = ((unsigned long)tp.rx_first_desc - tx_desc_virtual_base + sizeof(RAID_DESCRIPTOR_T)*1) | 0x0B;
3671 + //tp.rx_desc = tp.rx_first_desc ;
3672 +// tp.rx_desc->func_ctrl.bits.own = DMA;
3673 +
3674 +}
3675 +
3676 +void
3677 +xor_gemini_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
3678 + unsigned long *p3, unsigned long *p4, unsigned long *p5)
3679 +{
3680 +
3681 + int status=0;
3682 + unsigned int flags;
3683 +
3684 +
3685 + if(bytes > (1<<(SRAM_PAR_SIZE+11))){
3686 + printk("XOR: out of SRAM partition!![0x%x]\n",(unsigned int)bytes);
3687 + }
3688 +
3689 + spin_lock_irqsave(&raid_lock,flags);
3690 + while(tp.status != COMPLETE){
3691 + spin_unlock_irqrestore(&raid_lock, flags);
3692 + //printk("XOR yield5\n");
3693 +#ifdef XOR_SW_FILL_IN
3694 + xor_arm4regs_5(bytes,p1,p2,p3,p4,p5);
3695 + return;
3696 +#else
3697 + msleep(1);
3698 + yield();
3699 +#endif
3700 + }
3701 + spin_unlock_irqrestore(&raid_lock, flags);
3702 + tp.status = RUNNING;
3703 +
3704 + // flush the cache to memory before H/W XOR touches them
3705 + consistent_sync(p1, bytes, DMA_BIDIRECTIONAL);
3706 + consistent_sync(p2, bytes, DMA_TO_DEVICE);
3707 + consistent_sync(p3, bytes, DMA_TO_DEVICE);
3708 + consistent_sync(p4, bytes, DMA_TO_DEVICE);
3709 + consistent_sync(p5, bytes, DMA_TO_DEVICE);
3710 +
3711 + tp.tx_desc = tp.tx_first_desc;
3712 + tp.rx_desc = tp.rx_first_desc;
3713 + if((tp.tx_desc->func_ctrl.bits.own == CPU)/*&&(tp.rx_desc->func_ctrl.bits.own == DMA)*/){
3714 + // prepare tx descript
3715 + raid_write_reg(RAID_FCHDMA_CURR_DESC,(unsigned int)tp.tx_desc-tx_desc_virtual_base,0xffffffff);
3716 + tp.tx_desc->buf_addr = (unsigned int)__pa(p1); // physical address
3717 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3718 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 2; // first descript
3719 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3720 + tp.tx_desc->flg_status.bits32 = 0x00020000;
3721 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3722 + wmb();
3723 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3724 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3725 +
3726 + tp.tx_desc = tp.tx_cur_desc;
3727 + tp.tx_desc->buf_addr = (unsigned int)__pa(p2); // pysical address
3728 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3729 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript
3730 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3731 + tp.tx_desc->flg_status.bits32 = 0x00000000;
3732 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3733 + wmb();
3734 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3735 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3736 +
3737 + tp.tx_desc = tp.tx_cur_desc;
3738 + tp.tx_desc->buf_addr = (unsigned int)__pa(p3); // pysical address
3739 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3740 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript
3741 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3742 + tp.tx_desc->flg_status.bits32 = 0x00000000;
3743 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3744 + wmb();
3745 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3746 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3747 +
3748 + tp.tx_desc = tp.tx_cur_desc;
3749 + tp.tx_desc->buf_addr = (unsigned int)__pa(p4); // pysical address
3750 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3751 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 0; // first descript
3752 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3753 + tp.tx_desc->flg_status.bits32 = 0x00000000;
3754 + tp.tx_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3755 + wmb();
3756 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3757 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3758 +
3759 +
3760 + tp.tx_desc = tp.tx_cur_desc;
3761 + tp.tx_desc->buf_addr = (unsigned int)__pa(p5); // pysical address
3762 + tp.tx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3763 +// tp.tx_desc->flg_status.bits_cmd_status.bcc = 1; // last descript
3764 +// tp.tx_desc->flg_status.bits_cmd_status.mode = 0; // only support XOR command
3765 +// tp.tx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3766 + tp.tx_desc->flg_status.bits32 = 0x00010000;
3767 + tp.tx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3768 + tp.tx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
3769 + tp.tx_cur_desc = (RAID_DESCRIPTOR_T *)((tp.tx_desc->next_desc_addr.bits32 & 0xfffffff0)+tx_desc_virtual_base);
3770 + tp.tx_finished_desc = tp.tx_desc; // keep last descript
3771 +
3772 + // prepare rx descript
3773 + raid_write_reg(RAID_STRDMA_CURR_DESC,(unsigned int)tp.rx_desc-rx_desc_virtual_base,0xFFFFFFFF);
3774 + tp.rx_desc->buf_addr = (unsigned int)__pa(p1);
3775 + tp.rx_desc->func_ctrl.bits.buffer_size = bytes; /* total frame byte count */
3776 + tp.rx_desc->flg_status.bits32 = 0; // link data from XOR
3777 +// tp.rx_cur_desc->next_desc_addr.bits.sof_eof = 0x03; /*only one descriptor*/
3778 + tp.rx_desc->func_ctrl.bits.own = DMA; /* set owner bit */
3779 + tp.rx_desc->next_desc_addr.bits32 = 0x0000000b;// end of descript
3780 +
3781 + }
3782 + else{
3783 + /* no free tx descriptor */
3784 + printk("XOR:no free tx descript");
3785 + return ;
3786 + }
3787 +
3788 + // change status
3789 +// tp.status = RUNNING;
3790 + status = tp.busy = 1;
3791 +
3792 + // start tx DMA
3793 + rxdma_ctrl.bits.rd_start = 1;
3794 + // start rx DMA
3795 + txdma_ctrl.bits.td_start = 1;
3796 + wmb();
3797 + raid_write_reg(RAID_FCHDMA_CTRL, txdma_ctrl.bits32,0x80000000);
3798 + raid_write_reg(RAID_STRDMA_CTRL, rxdma_ctrl.bits32,0x80000000);
3799 +
3800 +#ifdef SPIN_WAIT
3801 + gemini_xor_isr(5);
3802 +#else
3803 + xor_queue_descriptor();
3804 +#endif