Drop changes to mm/fault.c prevents from seeing kernel oops while restarting the...
[openwrt.git] / target / linux / rdc-2.6 / patches / 000-rdc_fixes.patch
1 diff -urN linux-2.6.17/arch/i386/Kconfig linux-2.6.17.new/arch/i386/Kconfig
2 --- linux-2.6.17/arch/i386/Kconfig      2006-06-18 03:49:35.000000000 +0200
3 +++ linux-2.6.17.new/arch/i386/Kconfig  2006-10-07 22:33:09.000000000 +0200
4 @@ -167,6 +167,14 @@
5           Only choose this option if you have such a system, otherwise you
6           should say N here.
7  
8 +config X86_RDC
9 +       bool "Support for RDC 3211 boards"
10 +       help
11 +         Support for RDC 3211 sustems. Say 'Y' here if ther kernel is 
12 +         supposed to run on an IA-32 RDC R3211 system.
13 +         Only choose this option if you have such as system, otherwise you
14 +         should say N here.
15 +
16  endchoice
17  
18  config ACPI_SRAT
19 diff -urN linux-2.6.17/arch/i386/kernel/time.c linux-2.6.17.new/arch/i386/kernel/time.c
20 --- linux-2.6.17/arch/i386/kernel/time.c        2006-06-18 03:49:35.000000000 +0200
21 +++ linux-2.6.17.new/arch/i386/kernel/time.c    2006-10-07 22:23:05.000000000 +0200
22 @@ -479,7 +479,8 @@
23                 return;
24         }
25  #endif
26 -       xtime.tv_sec = get_cmos_time();
27 +       /* RDC board does not have CMOS */
28 +       xtime.tv_sec = 0;
29         xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
30         set_normalized_timespec(&wall_to_monotonic,
31                 -xtime.tv_sec, -xtime.tv_nsec);
32 diff -urN linux-2.6.17/arch/i386/mach-rdc/led.c linux-2.6.17.new/arch/i386/mach-rdc/led.c
33 --- linux-2.6.17/arch/i386/mach-rdc/led.c       1970-01-01 01:00:00.000000000 +0100
34 +++ linux-2.6.17.new/arch/i386/mach-rdc/led.c   2006-10-07 23:55:59.000000000 +0200
35 @@ -0,0 +1,743 @@
36 +/*
37 + * LED interface for WP3200
38 + *
39 + * Copyright (C) 2002, by Allen Hung
40 + *
41 + */
42 +
43 +#include <linux/types.h>
44 +#include <linux/errno.h>
45 +#include <linux/ioport.h>
46 +#include <linux/fcntl.h>
47 +#include <linux/sched.h>
48 +#include <linux/module.h>
49 +#include <linux/proc_fs.h>
50 +#include <linux/init.h>
51 +#include <linux/timer.h>
52 +#include <asm/io.h>
53 +#include <asm/uaccess.h>
54 +#include <asm/system.h>                       
55 +#include <linux/reboot.h>
56 +
57 +#include "led.h"
58 +
59 +#define BUF_LEN                30
60 +
61 +struct LED_DATA  {
62 +    char sts_buf[BUF_LEN+1];
63 +    unsigned long sts;
64 +};
65 +
66 +struct LED_DATA led_data[LED_DEV_NUM];
67 +// sam 
68 +unsigned long ul_ledstat = 0xffffffff;
69 +
70 +
71 +static struct timer_list blink_timer[LED_DEV_NUM];
72 +// sam 01-30-2004 for watchdog
73 +static struct timer_list watchdog;
74 +// end sam
75 +static char cmd_buf[BUF_LEN+1];
76 +
77 +//------------------------------------------------------------
78 +static long atoh(char *p) 
79 +{
80 +    long v = 0, c;
81 +    while ( (c = *p++) )  {
82 +        if      ( c >= '0' && c <= '9' )  v = (v << 4) + c - '0';
83 +        else if ( c >= 'a' && c <= 'f' )  v = (v << 4) + c - 'a' + 0xA;
84 +        else if ( c >= 'A' && c <= 'F' )  v = (v << 4) + c - 'A' + 0xA;
85 +        else  break;
86 +    }
87 +    return v;
88 +}
89 +
90 +static int reset_flash_default(void *data)
91 +{
92 +       char *argv[3], *envp[1] = {NULL};
93 +       int i = 0;
94 +       
95 +       int reset_default=(int) data;
96 +
97 +       argv[i++] = "/bin/flash";
98 +    argv[i++] = "default";
99 +       argv[i] = NULL;
100 +    if(reset_default)
101 +               if (call_usermodehelper(argv[0], argv, envp, 1))
102 +               printk("failed to Reset to default\n");
103 +       machine_restart(0);
104 +       return 0;
105 +}
106 +
107 +// sam for ps 3205U -- using CSx1 (0xb0e00000)
108 +// bit map as following
109 +// BIT   1      2      3      4      5   
110 +//     POWER  WLEN   PORT1  PORT2  PORT3
111 +//
112 +// value 0 --> led on
113 +// value 1 --> led off
114 +
115 +#define _ROUTER_
116 +
117 +#ifdef _ROUTER_
118 +       #define LED_VAL         0x8000384C    // the data ofset of gpio 0~30
119 +#else
120 +       #define LED_VAL         0x80003888    // the ofset of gpio 31~58
121 +#endif
122 +#define GPIO_VAL       0x8000384C    // the offset of gpio 0-30 
123 +
124 +
125 +
126 +// sam 1-30-2004 LED status 
127 +// bit map as following
128 +// BIT 4:0  Link status   -->PHY Link ->1 = up, 0 = down
129 +#define LINK_STATUS     (*(unsigned long *)0xb2000014)
130 +#define WATCHDOG_VAL    (*(unsigned long *)0xb20000c0)
131 +#define WATCHDOG_PERIOD 500 // unit ms
132 +#define EXPIRE_TIME     300 // unit 10 ms
133 +#define CLEAR_TIMEER    0xffffa000l  // bit 14:0 -> count up timer, write 0 to clear
134 +#define ENABLE_WATCHDOG 0x80000000l  // bit 31 -> 1 enable , 0 disable watchdog
135 +#define WATCHDOG_SET_TMR_SHIFT 16    // bit 16:30 -> watchdog timer set
136 +// end sam
137 +
138
139 +//------------------------------------------------------------
140 +static void turn_led(int id, int on)
141 +{
142 +    unsigned long led_bit = 1 << (id);
143 +    unsigned long led_bit_val;
144 +
145 +    // since we define we have 8 led devices and use gpio 53, 55, 57, 58 
146 +    // which locate at bit21~26, so we  rotate left 20bit  
147 +       
148 +#ifdef _ROUTER_        
149 +    led_bit_val = led_bit;
150 +#else   
151 +    led_bit_val = led_bit << 20;
152 +#endif 
153 +       
154 +    switch ( on ) {
155 +      case 0:  
156 +                       ul_ledstat|=  led_bit_val;
157 +                       outl(LED_VAL, 0xcf8);
158 +                       outl(ul_ledstat, 0xcfc);        
159 +               break; // LED OFF
160 +      case 1:  
161 +                       ul_ledstat &= ~led_bit_val;
162 +                       outl(LED_VAL, 0xcf8);
163 +                       outl(ul_ledstat, 0xcfc);
164 +               break; // LED ON
165 +      case 2:  
166 +                       ul_ledstat ^=  led_bit_val;
167 +                       outl(LED_VAL, 0xcf8);
168 +                       outl(ul_ledstat, 0xcfc);
169 +               break; // LED inverse
170 +    }
171 +}
172 +
173 +
174 +static int led_flash[30]={20,10,100,5,5,150,100,5,5,50,20,50,50,20,60,5,20,10,30,10,5,10,50,2,5,5,5,70,10,50};//Erwin
175 +static unsigned int    wlan_counter;    //Erwin
176 +static void blink_wrapper(u_long id)
177 +{
178 +    u_long sts = led_data[id].sts;
179 +
180 +    if ( (sts & LED_BLINK_CMD) == LED_BLINK_CMD )  {
181 +       unsigned long period = sts & LED_BLINK_PERIOD;
182 +       if(period == 0xffff)            // BLINK random
183 +       {
184 +               blink_timer[id].expires = jiffies + 3*led_flash[wlan_counter%30]*HZ/1000;
185 +               wlan_counter++;
186 +       }
187 +       else
188 +               blink_timer[id].expires = jiffies + (period * HZ / 1000);
189 +       turn_led(id, 2);
190 +       add_timer(&blink_timer[id]);
191 +    }
192 +    else if ( sts == LED_ON || sts == LED_OFF )
193 +       turn_led(id, sts==LED_ON ? 1 : 0);
194 +}
195 +//------------------------------------------------------------
196 +static void get_token_str(char *str, char token[][21], int token_num)
197 +{
198 +    int t, i;
199 +
200 +    for ( t = 0 ; t < token_num ; t++ )  {
201 +       memset(token[t], 0, 21);
202 +       while ( *str == ' ' )  str++;
203 +       for ( i = 0 ; str[i] ; i++ )  {
204 +           if ( str[i] == '\t' || str[i] == ' ' || str[i] == '\n' )  break;
205 +           if ( i < 20 )  token[t][i] = str[i];
206 +       }
207 +       str += i;
208 +    }
209 +}
210 +
211 +//------------------------------------------------------------
212 +static void set_led_status_by_str(int id)
213 +{
214 +    char token[3][21], *p;
215 +
216 +    
217 +    get_token_str(led_data[id].sts_buf, token, 3);
218 +       
219 +    if ( strcmp(token[0], "LED") ) 
220 +       {
221 +        goto set_led_off;
222 +       }
223 +    if ( !strcmp(token[1], "ON") )  
224 +       {
225 +               
226 +       turn_led(id, 1);
227 +       led_data[id].sts = LED_ON;
228 +    }
229 +    else if ( !strcmp(token[1], "OFF") )  
230 +       {
231 +               
232 +           goto set_led_off;
233 +    }
234 +    else if ( !strcmp(token[1], "BLINK") ) 
235 +       {
236 +       unsigned int period = 0;
237 +       p = token[2];
238 +       if ( !strcmp(p, "FAST") )
239 +           period = LED_BLINK_FAST & LED_BLINK_PERIOD;
240 +       else if ( !strcmp(p, "SLOW") )
241 +           period = LED_BLINK_SLOW & LED_BLINK_PERIOD;
242 +       else if ( !strcmp(p, "EXTRA_SLOW") )
243 +           period = LED_BLINK_EXTRA_SLOW & LED_BLINK_PERIOD;
244 +       else if ( !strcmp(p, "RANDOM") )
245 +           period = LED_BLINK_RANDOM & LED_BLINK_PERIOD;
246 +       else if ( !strcmp(p, "OFF") )
247 +           goto set_led_off;
248 +       else if ( *p >= '0' && *p <= '9' )  
249 +       {
250 +               while ( *p >= '0' && *p <= '9' )
251 +               period = period * 10 + (*p++) - '0';
252 +//             if ( period > 10000 )  
253 +//                     period = 10000;
254 +       }
255 +       else
256 +               period = LED_BLINK & LED_BLINK_PERIOD;
257 +       
258 +       if ( period == 0 )
259 +           goto set_led_off;
260 +               
261 +       sprintf(led_data[id].sts_buf, "LED BLINK %d\n", period);
262 +       led_data[id].sts = LED_BLINK_CMD + period;
263 +       turn_led(id, 2);
264 +     // Set timer for next blink
265 +       del_timer(&blink_timer[id]);
266 +        blink_timer[id].function = blink_wrapper;
267 +        blink_timer[id].data = id;
268 +        init_timer(&blink_timer[id]);
269 +        
270 +       blink_timer[id].expires = jiffies + (1000 * HZ / 1000);
271 +        
272 +       add_timer(&blink_timer[id]);
273 +    }
274 +    else
275 +       {
276 +        goto set_led_off;
277 +       }
278 +    return;
279 +  set_led_off:
280 +    strcpy(led_data[id].sts_buf, "LED OFF\n");
281 +    led_data[id].sts = LED_OFF;
282 +    turn_led(id, 0);
283 +}
284 +
285 +//----------------------------------------------------------------------
286 +static int led_read_proc(char *buf, char **start, off_t fpos, int length, int *eof, void *data)
287 +{
288 +    int len, dev;
289 +
290 +    for ( len = dev = 0 ; dev < LED_DEV_NUM ; dev++ )  {
291 +       len += sprintf(buf+len, "%d: %s", dev, led_data[dev].sts_buf);
292 +    }
293 +    len = strlen(buf) - fpos;
294 +    if ( len <= 0 ) {
295 +       *start = buf;
296 +       *eof = 1;
297 +       return 0;
298 +    }
299 +    *start = buf + fpos;
300 +    if ( len <= length )   *eof = 1;
301 +    return len < length ? len : length;
302 +}
303 +
304 +//----------------------------------------------------------------------
305 +static int led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
306 +{
307 +    int id = (int)file->private_data;
308 +
309 +    switch ( cmd )  {
310 +      case LED_ON:
311 +       strcpy(led_data[id].sts_buf, "LED ON\n");
312 +       set_led_status_by_str(id);
313 +       break;
314 +      case LED_OFF:
315 +       strcpy(led_data[id].sts_buf, "LED OFF\n");
316 +       set_led_status_by_str(id);
317 +       break;
318 +      default:
319 +        if ( (cmd & LED_BLINK_CMD) != LED_BLINK_CMD )
320 +               {
321 +           break;
322 +               }
323 +      case LED_BLINK:
324 +      case LED_BLINK_FAST:
325 +      case LED_BLINK_SLOW:
326 +      case LED_BLINK_EXTRA_SLOW:
327 +      case LED_BLINK_RANDOM:
328 +        sprintf(led_data[id].sts_buf, "LED BLINK %d\n", (int)(cmd & LED_BLINK_PERIOD));
329 +       set_led_status_by_str(id);
330 +       break;
331 +    }
332 +    return 0;
333 +}
334 +
335 +static int led_open(struct inode *inode, struct file *file)
336 +{
337 +    int led_id = MINOR(inode->i_rdev);
338 +//    unsigned long led_bit = 1 << (led_id);
339 +
340 +    if ( led_id >= LED_DEV_NUM )
341 +        return -ENODEV;
342 +/* sam 12/02/2003
343 +    GPIO_SEL_I_O &= ~led_bit;   // 0 to GPIO
344 +    GPIO_O_EN |= (led_bit << 16);   // 0 to Output
345 +*/     
346 +       
347 +    file->private_data = (void*)led_id;
348 +    return 0;
349 +}
350 +
351 +static long led_read(struct file *file, char *buf, size_t count, loff_t *fpos)
352 +{
353 +    int  rem, len;
354 +    int  id = (int)file->private_data;
355 +    char *p = led_data[id].sts_buf;
356 +
357 +    len = strlen(p);
358 +    rem = len - *fpos;
359 +    if ( rem <= 0 )  {
360 +       *fpos = len;
361 +       return 0;
362 +    }
363 +    if ( rem > count )   rem = count;
364 +    memcpy(buf, p+(*fpos), rem);
365 +    *fpos += rem;
366 +    return rem;
367 +}
368 +
369 +static long led_write(struct file *file, char *buf, size_t count, loff_t *fpos)
370 +{
371 +    int  len;
372 +    int  id = (int)file->private_data;
373 +    char *p = id == REG_MINOR ? cmd_buf : led_data[id].sts_buf;
374 +    memset(p, 0, BUF_LEN);
375 +
376 +    p += *fpos;
377 +    len = 0;
378 +
379 +       
380 +    while ( count > 0 )  
381 +       {
382 +               
383 +       if ( *fpos < BUF_LEN )  
384 +               {
385 +           int c = *buf++;
386 +            p[len] = c>='a' && c<='z' ? c-'a'+'A' : c;
387 +        }
388 +       (*fpos)++;
389 +           len++;
390 +       count--;
391 +    }
392 +       // sam
393 +    set_led_status_by_str(id);
394 +       (*fpos) = 0;
395 +       //
396 +       
397 +    return len;
398 +}
399 +
400 +static int led_flush(struct file *file)
401 +{
402 +    int  id = (int)file->private_data;
403 +
404 +    if ( file->f_mode & FMODE_WRITE )
405 +       {
406 +       set_led_status_by_str(id);
407 +       }
408 +    return 0;
409 +}
410 +
411 +static struct file_operations led_fops = {
412 +    read:      led_read,
413 +    write:     led_write,
414 +    flush:     led_flush,
415 +    ioctl:     led_ioctl,
416 +    open:      led_open,
417 +};
418 +
419 +//----------------------------------------------
420 +static unsigned long *reg_addr;
421 +static int  dump_len;
422 +
423 +static int dump_content(char *buf)
424 +{
425 +    return 0;
426 +}
427 +
428 +static long gpio_read(struct file *file, char *buf, size_t count, loff_t *fpos)
429 +{
430 +    int  rem, len;
431 +    int  id = (int)file->private_data;
432 +    char temp[80*10];
433 +    unsigned long gpio_regval =0;
434 +
435 +       outl(GPIO_VAL, 0xcf8);
436 +    gpio_regval = inl(0xcfc);
437 +       gpio_regval |= 0x40;
438 +       outl(gpio_regval, 0xcfc);   // each in, need out 1 first
439 +       gpio_regval = inl(0xcfc);
440 +                                       
441 +       
442 +    // sam debug
443 +    //printk(KERN_ERR "gpio_id:%d, gpio_regval:%08X\n", id, gpio_regval);
444 +    //end sam 
445 +    
446 +    if ( id < GPIO_DEV_NUM )  {
447 +        int  gpio_bit = 1 << id;
448 +
449 +        len = sprintf(temp, "%d\n", (gpio_regval & gpio_bit) ? 1 : 0);
450 +    }
451 +    else   // REG device
452 +        len = dump_content(temp);
453 +    rem = len - *fpos;
454 +    if ( rem <= 0 )  {
455 +       *fpos = len;
456 +       return 0;
457 +    }
458 +    if ( rem > count )   rem = count;
459 +    memcpy(buf, temp+(*fpos), rem);
460 +    *fpos += rem;
461 +    return rem;
462 +}
463 +
464 +static int gpio_flush(struct file *file)
465 +{
466 +    return 0;
467 +}
468 +
469 +static int gpio_open(struct inode *inode, struct file *file)
470 +{
471 +    int id = MINOR(inode->i_rdev);
472 +    if ( id >= GPIO_DEV_NUM && id != REG_MINOR )
473 +        return -ENODEV;
474 +    file->private_data = (void*)id;
475 +    return 0;
476 +}
477 +
478 +static struct file_operations gpio_fops = {
479 +    read:      gpio_read,
480 +    open:      gpio_open,
481 +    flush:     gpio_flush,
482 +    write:     led_write,
483 +};
484 +
485 +// ---------------------------------------------
486 +//  sam 1-30-2004 LAN_STATUS Device
487 +
488 +//static unsigned long *reg_addr;
489 +//static int  dump_len;
490 +
491 +//static int lanSt_content(char *buf)
492 +//{
493 +//    int  i, j, len;
494 +//    unsigned long *p = (unsigned long *)0xb2000014;  // PHY_ST 
495 +// //    j = dump_len/4 + ((dump_len&3) ? 1 : 0);
496 +//    len = sprintf(buf, "Reg Addr = %08lX,  Value = \n", (unsigned long)p);
497 +// //    for ( i = 0 ; i < j ; i++, p++ )
498 +//    len += sprintf(buf+len,"%08lX\n", *p);
499 +    
500 +//    return len;
501 +//}
502 +
503 +#define MAC_IOBASE 0xe800 // Eth0
504 +#define PHY_ADDR   1      // For Eth0
505 +#define MII_STATUS_ADDR 1
506 +// where "id" value means which bit of PHY reg 1 we want to check  
507 +static long lanSt_read(struct file *file, char *buf, size_t count, loff_t *fpos)
508 +{
509 +    int  rem, len;
510 +//  unsigned long *p = (unsigned long *)0xb2000014;  // PHY_ST 
511 +    unsigned short status;
512 +    unsigned int   i = 0;
513 +    int  id = (int)file->private_data;
514 +    char temp[80*10];
515 +    
516 +    outw(0x2000 + MII_STATUS_ADDR + (PHY_ADDR << 8), MAC_IOBASE + 0x20);
517 +    do{}while( (i++ < 2048) && (inw(MAC_IOBASE+0x20) & 0x2000) );
518 +
519 +    status = inw(MAC_IOBASE + 0x24);
520 +    
521 +    // sam debug
522 +    //printk(KERN_ERR "PHY REG1 Status:%04x\n", status );
523 +    // end sam
524 +    
525 +    if ( id < LAN_DEV_NUM )  {
526 +        unsigned long lanSt_bit = 1 << id;
527 +//        len = lanSt_content(temp);
528 +        len = sprintf(temp, "%d\n",(status & lanSt_bit) ? 1 : 0);
529 +    }
530 +    else   // REG device
531 +    {
532 +        len = sprintf(temp, "-1\n");
533 +    }   
534 +    rem = len - *fpos;
535 +    if ( rem <= 0 )  {
536 +       *fpos = len;
537 +       return 0;
538 +    }
539 +    if ( rem > count )   rem = count;
540 +    memcpy(buf, temp+(*fpos), rem);
541 +    *fpos += rem;
542 +    return rem;
543 +}
544 +
545 +static int lanSt_flush(struct file *file)
546 +{
547 +    return 0;
548 +}
549 +
550 +static int lanSt_open(struct inode *inode, struct file *file)
551 +{
552 +    int id = MINOR(inode->i_rdev);
553 +    if ( id >= LAN_DEV_NUM && id != REG_MINOR )
554 +        return -ENODEV;
555 +    file->private_data = (void*)id;
556 +    return 0;
557 +}
558 +
559 +static struct file_operations lanSt_fops = {
560 +    read:      lanSt_read,
561 +    open:      lanSt_open,
562 +    flush:     lanSt_flush,
563 +    write:     led_write,
564 +};
565 +
566 +//----------------------------------------------
567 +static int SwResetPress = 0;
568 +static int SwResetCounter = 0;
569 +static int RebootFlag = 0;
570 +static void watchdog_wrapper(unsigned int period)
571 +{
572 +       // { RexHua add for restore default, by press SwReset 5 second, 2 sec to restart
573 +#if 0          // 
574 +       u_long reg;
575 +
576 +       outl(GPIO_VAL, 0xcf8);
577 +       reg = inl(0xcfc);
578 +       reg |= 0x40;
579 +       outl(reg, 0xcfc);       // each in, need out 1 first
580 +       reg = inl(0xcfc);
581 +
582 +       if( (reg & 0x40) == 0)
583 +       {
584 +               if(SwResetPress == 0)
585 +               {       
586 +                       SwResetCounter=0;
587 +                       strcpy(led_data[15].sts_buf, "LED BLINK 500\n" );
588 +                       set_led_status_by_str(15);
589 +               }
590 +               SwResetPress=1;
591 +               printk("SwReset press!\n");
592 +
593 +    }
594 +    else
595 +       {
596 +               if(SwResetPress=1)
597 +               {
598 +                       strcpy(led_data[15].sts_buf, "LED ON\n" );
599 +               set_led_status_by_str(15);
600 +               }
601 +               
602 +               SwResetPress=0;
603 +               if(RebootFlag == 1)
604 +                       machine_restart(0);
605 +       }
606 +
607 +       if(SwResetPress == 1)
608 +       {
609 +               if(SwResetCounter > 10)
610 +               {
611 +                       turn_led(15, 0);
612 +//                     kernel_thread(reset_flash_default, 1, SIGCHLD);
613 +                       reset_flash_default(1);
614 +                       turn_led(15, 1);
615 +               }
616 +               else if(SwResetCounter == 3)
617 +               {
618 +                       RebootFlag=1;
619 +                       strcpy(led_data[15].sts_buf, "LED BLINK 100\n" );
620 +                       set_led_status_by_str(15);
621 +               }
622 +       }               
623 +
624 +       SwResetCounter++;
625 +#endif
626 +       
627 +       // clear timer count
628 +       outl(0x80003844, 0xcf8);
629 +       outl(0x00800080, 0xcfc); // enable watchdog and set the timeout = 1.34s
630 +    //printk(KERN_ERR "wdt\n" );
631 +       watchdog.expires = jiffies + (period * HZ / 1000);
632 +       add_timer(&watchdog);
633 +}
634 +
635 +//----------------------------------------------
636 +static int init_status;
637 +
638 +#define INIT_REGION            0x01
639 +#define INIT_LED_REGISTER      0x02
640 +#define INIT_LED_PROC_READ     0x04
641 +#define INIT_GPIO_REGISTER     0x08
642 +// sam 1-30-2004 LAN_STATUS
643 +#define INIT_LAN_STATUS_REGISTER 0x10
644 +#define INIT_WATCHDOG_REGISTER 0x20
645 +
646 +static void led_exit(void)
647 +{
648 +    int id;
649 +    for ( id = 0 ; id < LED_DEV_NUM ; id++ )  {
650 +        del_timer(&blink_timer[id]);
651 +        turn_led(id, 0);
652 +    }
653 +    if ( init_status & INIT_LED_PROC_READ )
654 +       remove_proc_entry("driver/led", NULL);
655 +       
656 +    if ( init_status & INIT_LED_REGISTER )
657 +       unregister_chrdev(LED_MAJOR, "led");
658 +
659 +    if ( init_status & INIT_GPIO_REGISTER )
660 +       unregister_chrdev(GPIO_MAJOR, "gpio");
661 +    // sam 1-30-2004 
662 +    
663 +    if( init_status & INIT_LAN_STATUS_REGISTER )
664 +      unregister_chrdev(LAN_STATUS_MAJOR, "lanSt");
665 +    
666 +    if( init_status & INIT_WATCHDOG_REGISTER)
667 +       del_timer(&watchdog);
668 +    
669 +    
670 +    // end sam
671 +
672 +}
673 +
674 +static int __init led_init(void)
675 +{
676 +    int result, id, i, j;
677 +    unsigned long reg;
678 +    init_status = 0;
679 +       
680 +  //----- register device (LED)-------------------------
681 +  
682 +                                                                                        
683 +    result = register_chrdev(LED_MAJOR, "led", &led_fops);
684 +    if ( result < 0 )   {
685 +       printk(KERN_ERR "led: can't register char device\n" );
686 +       led_exit();
687 +       return result;
688 +    }
689 +    init_status |= INIT_LED_REGISTER;
690 +  //----- register device (GPIO)-------------------------
691 +    result = register_chrdev(GPIO_MAJOR, "gpio", &gpio_fops);
692 +    if ( result < 0 )   {
693 +       printk(KERN_ERR "gpio: can't register char device\n" );
694 +       led_exit();
695 +       return result;
696 +    }
697 +    init_status |= INIT_GPIO_REGISTER;
698 +    
699 +  // sam 1-30-2004 LAN Status
700 +  // ----- register device (LAN_STATUS)-------------------
701 +  
702 +  //--> sam 5-1802995
703 +  
704 +    result = register_chrdev(LAN_STATUS_MAJOR, "lanSt", &lanSt_fops);
705 +    if ( result < 0 )   {
706 +       printk(KERN_ERR "lanSt: can't register char device\n" );
707 +       led_exit();
708 +       return result;
709 +    }
710 +    init_status |= INIT_LAN_STATUS_REGISTER;
711 +  
712 +  // <-- end sam
713 +    
714 + // -----------init watchdog timer-------------------------
715 +        //del_timer(&blink_timer[id]);
716 +
717 +    outl(0x80003840, 0xcf8);
718 +    reg = inl(0xcfc);
719 +    reg |= 0x1600;         // ensable SRC bit 
720 +    outl(reg, 0xcfc);
721 +#ifdef _ROUTER_
722 +    outl(0x80003848, 0xcf8);
723 +    reg = inl(0xcfc);
724 +    reg |= 0x18040;            // enable GPIO, PowerLED:15, WLAN_LED0:16, SwReset:6 
725 +    outl(reg, 0xcfc);
726 +    
727 +    outl(0x8000384c, 0xcf8);
728 +    reg = inl(0xcfc);
729 +    reg |= 0x40;               // output SwReset:6 1, Set SwReset as Input 
730 +    outl(reg, 0xcfc);
731 +#endif
732 +    // sam debug
733 +    //reg = inl(0xcfc);
734 +    //printk(KERN_ERR "REG40:%08X\n", reg);
735 +    // end sam
736 +    outl(0x80003844, 0xcf8);
737 +    outl(0x00800080, 0xcfc); // enable watchdog and set the timeout = 1.34s
738 +    
739 +    watchdog.function = watchdog_wrapper;
740 +    watchdog.data = WATCHDOG_PERIOD;
741 +    init_timer(&watchdog);
742 +    watchdog.expires = jiffies + (WATCHDOG_PERIOD * HZ / 1000);
743 +    add_timer(&watchdog);
744 +    init_status |= INIT_WATCHDOG_REGISTER;
745 +
746 + // end sam   
747 + //------ read proc -------------------
748 +    if ( !create_proc_read_entry("driver/led", 0, 0, led_read_proc, NULL) )  {
749 +       printk(KERN_ERR "led: can't create /proc/driver/led\n");
750 +       led_exit();
751 +       return -ENOMEM;
752 +    }
753 +    init_status |= INIT_LED_PROC_READ;
754 +  //------------------------------
755 +//    reg_addr = (unsigned long *)0xB4000000;
756 +//    dump_len = 4;
757 +    
758 +    for ( id = 0 ; id < LED_DEV_NUM ; id++ )  {
759 +       strcpy(led_data[id].sts_buf, "LED ON\n" );
760 +       set_led_status_by_str(id);
761 +    }
762 +
763 +//    for (i = 0; i < 0xffff; i++)
764 +//         for (j = 0; j < 0x6000; j++);
765 +
766 +/* sam 5-18-2005 remark
767 +    for ( id = 0 ; id < LED_DEV_NUM ; id++ )  {
768 +        strcpy(led_data[id].sts_buf, "LED ON\n" );
769 +        set_led_status_by_str(id);
770 +    }
771 +*/    
772 +    printk(KERN_INFO "LED & GPIO & LAN Status Driver LED_VERSION \n");
773 +    return 0;
774 +}
775 +
776 +module_init(led_init);
777 +module_exit(led_exit);
778 +EXPORT_NO_SYMBOLS;
779 diff -urN linux-2.6.17/arch/i386/mach-rdc/led.h linux-2.6.17.new/arch/i386/mach-rdc/led.h
780 --- linux-2.6.17/arch/i386/mach-rdc/led.h       1970-01-01 01:00:00.000000000 +0100
781 +++ linux-2.6.17.new/arch/i386/mach-rdc/led.h   2006-10-07 22:28:32.000000000 +0200
782 @@ -0,0 +1,32 @@
783 +#ifndef _LED_H_INCLUDED
784 +#define _LED_H_INCLUDED
785 +
786 +#include <linux/config.h>
787 +
788 +#define LED_VERSION            "v1.0"
789 +#define LED_MAJOR              166
790 +#define LED_DEV_NUM            32 
791 +#define LED_GPIO_START         1
792 +#define GPIO_MAJOR             167
793 +#define GPIO_DEV_NUM           32
794 +#define REG_MINOR              128
795 +// sam 1-30-2004 for LAN_STATUS
796 +#define LAN_STATUS_MAJOR       168
797 +#define LAN_DEV_NUM            5
798 +// end sam
799 +
800 +//#define GPIO_IO_BASE        0xB4002480
801 +//#define GPIO_IO_BASE        ((unsigned long)0xb20000b8)
802 +//#define GPIO_IO_EXTENT               0x40
803 +
804 +#define LED_ON              0x010000
805 +#define LED_OFF             0x020000
806 +#define LED_BLINK_CMD       0x030000
807 +#define LED_BLINK_PERIOD    0x00FFFF
808 +#define LED_BLINK           (LED_BLINK_CMD|1000)
809 +#define LED_BLINK_FAST      (LED_BLINK_CMD|250)
810 +#define LED_BLINK_SLOW      (LED_BLINK_CMD|500)
811 +#define LED_BLINK_EXTRA_SLOW    (LED_BLINK_CMD|2000)
812 +#define LED_BLINK_RANDOM    (LED_BLINK_CMD|0xffff)
813 +
814 +#endif
815 diff -urN linux-2.6.17/arch/i386/mach-rdc/Makefile linux-2.6.17.new/arch/i386/mach-rdc/Makefile
816 --- linux-2.6.17/arch/i386/mach-rdc/Makefile    1970-01-01 01:00:00.000000000 +0100
817 +++ linux-2.6.17.new/arch/i386/mach-rdc/Makefile        2006-10-07 22:31:19.000000000 +0200
818 @@ -0,0 +1,5 @@
819 +#
820 +# Makefile for the linux kernel.
821 +#
822 +
823 +obj-$(CONFIG_X86_RDC)        := led.o
824 diff -urN linux-2.6.17/arch/i386/Makefile linux-2.6.17.new/arch/i386/Makefile
825 --- linux-2.6.17/arch/i386/Makefile     2006-06-18 03:49:35.000000000 +0200
826 +++ linux-2.6.17.new/arch/i386/Makefile 2006-10-07 23:56:13.000000000 +0200
827 @@ -80,6 +80,10 @@
828  mflags-$(CONFIG_X86_ES7000)    := -Iinclude/asm-i386/mach-es7000
829  mcore-$(CONFIG_X86_ES7000)     := mach-default
830  core-$(CONFIG_X86_ES7000)      := arch/i386/mach-es7000/
831 +# RDC subarch support
832 +mflags-$(CONFIG_X86_RDC)       := -Iinclude/asm-i386/mach-generic
833 +mcore-$(CONFIG_X86_RDC)                := mach-default
834 +core-$(CONFIG_X86_RDC)         := arch/i386/mach-rdc/
835  
836  # default subarch .h files
837  mflags-y += -Iinclude/asm-i386/mach-default