]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/linux/nslu2-kernel/2.6.14/50-nslu2-general.patch
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / linux / nslu2-kernel / 2.6.14 / 50-nslu2-general.patch
1 diff -urN linux-2.6.14-rc2/arch/arm/mach-ixp4xx/Makefile test3/arch/arm/mach-ixp4xx/Makefile
2 --- linux-2.6.14-rc2/arch/arm/mach-ixp4xx/Makefile      2005-09-17 12:42:02.000000000 +0200
3 +++ test3/arch/arm/mach-ixp4xx/Makefile 2005-09-24 13:21:35.000000000 +0200
4 @@ -8,4 +8,5 @@
5  obj-$(CONFIG_MACH_IXDPG425)    += ixdpg425-pci.o coyote-setup.o
6  obj-$(CONFIG_ARCH_ADI_COYOTE)  += coyote-pci.o coyote-setup.o
7  obj-$(CONFIG_MACH_GTWX5715)    += gtwx5715-pci.o gtwx5715-setup.o
8 +obj-$(CONFIG_MACH_NSLU2)       += nslu2-pci.o nslu2-setup.o nslu2-io.o nslu2-rtc.o
9  
10 diff -urN linux-2.6.14-rc2/arch/arm/mach-ixp4xx/nslu2-io.c test3/arch/arm/mach-ixp4xx/nslu2-io.c
11 --- linux-2.6.14-rc2/arch/arm/mach-ixp4xx/nslu2-io.c    1970-01-01 01:00:00.000000000 +0100
12 +++ test3/arch/arm/mach-ixp4xx/nslu2-io.c       2005-09-24 15:44:08.000000000 +0200
13 @@ -0,0 +1,696 @@
14 +//=============================================================================
15 +//
16 +// n2-io.c version 0.1.7
17 +// Author: Karen Spearel <kas11 at tampabay.rr.com>
18 +// please report problems/bugs directly to the address above
19 +//
20 +// Boilerplate to be added "real soon now"...it is and has always been GPL'ed per
21 +// MODULE_LICENSE but is offered without warrantee of any sort..use at your own risk
22 +//
23 +// NOTE: THIS IS INCOMPLETE.  INCLUDED ONLY TO KEEP FROM BREAKING THE BUILD,
24 +// IT BEEPS AND SENDS A MESSAGE TO /proc/poweroff.  EVENTUALLY IT
25 +// WILL TALK TO THE n2_pbd DAEMON.  EVENTUALLY THE LED DRIVER
26 +// WILL TALK TO SOME USERLAND APP BUT ***NOT*** SET_LEDS.
27 +// 
28 +//=============================================================================
29 +//     GPIO            Function        State
30 +//     0               Red LED         Status          
31 +//     1               Green LED       Ready = 1
32 +//     2               Disk 2 LED      On = 0
33 +//     3               Disk 1 LED      On = 0
34 +//     4               Buzzer
35 +//     5               Power Button    Pressed = 1
36 +//     8               Power Down      Output = 1 powers down NSLU2
37 +//     12              Reset           Pressed = 0
38 +
39 +#include <linux/config.h>
40 +#include <linux/version.h>
41 +#include <linux/module.h>
42 +#include <linux/utsname.h>
43 +#include <linux/kernel.h>
44 +#include <linux/major.h>
45 +#include <linux/string.h>
46 +#include <linux/proc_fs.h>
47 +#include <linux/slab.h>
48 +#include <linux/init.h>
49 +#include <linux/errno.h>
50 +#include <linux/fs.h>
51 +#include <linux/miscdevice.h>
52 +#include <linux/device.h>
53 +#include <linux/interrupt.h>
54 +#include <linux/moduleparam.h>
55 +#include <linux/timer.h>
56 +#include <linux/reboot.h>
57 +
58 +#include <asm/system.h>
59 +#include <asm/uaccess.h>
60 +#include <asm/hardware.h>
61 +#include <asm-arm/irq.h>
62 +#include <asm-arm/delay.h>
63 +#include <asm-arm/signal.h>
64 +
65 +/* Set this to 1 to output lots of debug messages. */
66 +#define NSLU2_IO_DEBUG 0
67 +
68 +#if NSLU2_IO_DEBUG
69 +#define nslu2_io_debug(args) printk args
70 +#else
71 +#define nslu2_io_debug(args) ((void)0)
72 +#endif
73 +
74 +#define VERSION                        "0.1.7"
75 +
76 +#define NSLU2RB_MAJOR          60              //rbuttons
77 +#define NSLU2PB_MAJOR          61              //pbuttons
78 +#define        NSLU2BZ_MAJOR           62              //buzzer
79 +#define NSLU2LM_MAJOR          126
80 +
81 +#define NSLU2_BEEP_DUR_LONG    2000
82 +#define NSLU2_BEEP_DUR_MED     400
83 +#define NSLU2_BEEP_DUR_SHORT   100
84 +#define NSLU2_BEEP_PITCH_HIGH  250
85 +#define NSLU2_BEEP_PITCH_MED   500
86 +#define NSLU2_BEEP_PITCH_LOW   1000
87 +#define NSLU2_LONG_DELAY       30000
88 +
89 +#define NSLU2_BZ_GPIO          4
90 +#define NSLU2_PB_GPIO          5
91 +#define NSLU2_PO_GPIO          8               //power off
92 +#define NSLU2_RB_GPIO          12
93 +
94 +#define NSLU2_PB_IRQ           22              //gpio5
95 +#define        NSLU2_RB_IRQ            29              //gpio12
96 +
97 +#define GPIO_BZ_BM             0x0010  //b0000 0000 0001 0000
98 +#define GPIO_PB_BM             0x0020  //b0000 0000 0010 0000
99 +#define GPIO_PO_BM             0x0100  //b0000 0001 0000 0000
100 +#define GPIO_RB_BM             0x1000  //b0001 0000 0000 0000
101 +
102 +#define RB_DELAY               50
103 +#define PB_DELAY               20
104 +
105 +#define PWR_OFF_STR            "poweroff"
106 +
107 +
108 +// ioctls -- 'M" is used for sound cards...we don't got one so it seems safe
109 +
110 +#define NSLU2BZ_BEEP_STOP              _IO('M',0)       //stop multi-beep at end of audible
111 +#define NSLU2BZ_BEEP           _IO('M',1)       //one beep at current defaults
112 +#define NSLU2BZ_BEEPS          _IOW('M',3,long) //param beeps at current defaults
113 +#define NSLU2BZ_TONESET                _IOW('M',4,long) //set tone: range is high=250 to low=2000
114 +#define NSLU2BZ_ONTIME         _IOW('M',5,long) //ontime for multi-beeps in jiffies
115 +#define        NSLU2BZ_SILENTTIME              _IOW('M',6,long) //offtime for multi-beeps in jiffies
116 +#define NSLU2BZ_REPEATCNT              _IOW('M',7,long) //number of repeats for multi-beeps 0 = forever
117 +#define NSLU2BZ_COMBINED               _IOW('M',8,long) //combine all params in a long
118 +
119 +#define NSLU2LM_OFF            _IOW('M',32,long)
120 +#define NSLU2LM_ON                     _IOW('M',33,long)
121 +#define NSLU2LM_BLINK          _IOW('M',34,long)
122 +#define NSLU2LM_ALT            _IOW('M',35,long)
123 +#define NSLU2LM_ALL_ON         _IO('M',36)
124 +#define NSLU2LM_ALL_OFF                _IO('M',37)
125 +
126 +#define PHYS_LEDS              4
127 +#define BLINK_DELAY            25
128 +
129 +//  OR Masks to turn these LEDs ON
130 +
131 +#define        RS_RED_ON       0x00000001      //0b0000 0000 0000 0010
132 +#define        RS_GRN_ON       0x00000002      //0b0000 0000 0000 0001
133 +#define RS_YEL_ON      0x00000003      //0b0000 0000 0000 0011
134 +
135 +// AND Masks to turn these LEDs OFF
136 +
137 +#define        RS_RED_OFF      0xfffffffe      //0b1111 1111 1111 1101
138 +#define        RS_GRN_OFF      0xfffffffd      //0b1111 1111 1111 1110
139 +#define RS_YEL_OFF     0xfffffffc      //0b1111 1111 1111 1100
140 +
141 +// AND Masks to turn these LEDs ON
142 +
143 +#define DISK1_ON       0xfffffff7      //0b1111 1111 1111 0111
144 +#define        DISK2_ON        0xfffffffb      //0b1111 1111 1111 1011
145 +
146 +// Or Masks to turn these LEDs OFF
147 +
148 +#define DISK1_OFF      0x00000008      //0b0000 0000 0000 1000
149 +#define        DISK2_OFF       0x00000004      //0b0000 0000 0000 0100 
150 +
151 +// EOR masks for toggling LEDs on/off
152 +
153 +#define RS_RG_ALT      0x00000003      //eor mask to toggle rs rg bits
154 +#define RS_GRN_TGL     0x00000002
155 +#define RS_RED_TGL     0x00000001
156 +#define DISK1_TGL      0x00000008
157 +#define DISK2_TGL      0x00000004
158 +
159 +// The LED names for switches
160 +
161 +#define LED_RS_RED     0
162 +#define LED_RS_GRN     1
163 +#define        LED_DISK1       2
164 +#define LED_DISK2      3
165 +#define LED_ALL                4
166 +
167 +static int nslu2_shutdown_in_progress = 0;
168 +
169 +static unsigned long init_jiffy = 0;           /* jiffies at init time */
170 +static unsigned long ontime = 50;
171 +static unsigned long offtime = 450;
172 +static unsigned long bz_repeatcnt = 10;
173 +static unsigned long tone = 1000;
174 +
175 +DECLARE_WAIT_QUEUE_HEAD(n2rb_waitq);
176 +DECLARE_WAIT_QUEUE_HEAD(n2pb_waitq);
177 +
178 +static struct timer_list n2lm_rsg_timer;       //rs green 
179 +static struct timer_list n2lm_rsr_timer;       //rs red
180 +static struct timer_list n2lm_d1_timer;                //drive 1
181 +static struct timer_list n2lm_d2_timer;                //drive 2
182 +static struct timer_list n2rb_timer;
183 +static struct timer_list n2pb_timer;
184 +static struct timer_list n2bz_timer;           //beeper
185 +
186 +// sysfs class
187 +static struct class *n2lm_class;
188 +
189 +//==================================================================================================
190 +//
191 +// Blinking is handled entirely by the 4 timer handlers.  On timeout, the bit in the
192 +// GPIO output register is xor'd with a mask corresponding to the selected led which simply
193 +// flips that bit.  No record of what any of the other leds is doing is needed.
194 +//
195 +//==================================================================================================
196 +// this blinks rs green or green/yellow if rs red is on
197 +static void n2lm_rsg_handler(unsigned long data)
198 +{
199 +       *IXP4XX_GPIO_GPOUTR ^= RS_GRN_TGL;                      //flip the led
200 +       n2lm_rsg_timer.expires = jiffies + BLINK_DELAY;         //next timeout
201 +       add_timer(&n2lm_rsg_timer);                             //reinit timer
202 +       return;
203 +}
204 +
205 +// this blinks or alternates rs red green... inited wit green on/red off
206 +static void n2lm_rsr_handler(unsigned long data)
207 +{
208 +       *IXP4XX_GPIO_GPOUTR ^= n2lm_rsr_timer.data;
209 +       n2lm_rsr_timer.expires = jiffies + BLINK_DELAY;
210 +       add_timer(&n2lm_rsr_timer);
211 +       return; 
212 +}
213 +// blinks disk 1
214 +static void n2lm_d1_handler(unsigned long data)
215 +{
216 +       *IXP4XX_GPIO_GPOUTR ^= DISK1_TGL;
217 +       n2lm_d1_timer.expires = jiffies + BLINK_DELAY;
218 +       add_timer(&n2lm_d1_timer);
219 +       return;
220 +}
221 +// blinks disk 2
222 +static void n2lm_d2_handler(unsigned long data)
223 +{
224 +       *IXP4XX_GPIO_GPOUTR ^= DISK2_TGL;
225 +       n2lm_d2_timer.expires = jiffies + BLINK_DELAY;
226 +       add_timer(&n2lm_d2_timer);
227 +       return;
228 +}
229 +
230 +//==================================================================================================
231 +
232 +static void n2lm_timer_start(unsigned long led)
233 +{
234 +
235 +       nslu2_io_debug((KERN_DEBUG "timer: %ld\n",led));
236 +
237 +       switch(led) {
238 +               case LED_RS_RED:
239 +                       n2lm_rsr_timer.expires = jiffies + BLINK_DELAY;
240 +                       add_timer(&n2lm_rsr_timer);
241 +                       break;
242 +
243 +               case LED_RS_GRN:
244 +                       n2lm_rsg_timer.expires = jiffies + BLINK_DELAY;
245 +                       add_timer(&n2lm_rsg_timer);
246 +                       break;
247 +
248 +               case LED_DISK1:
249 +                       n2lm_d1_timer.expires = jiffies + BLINK_DELAY;
250 +                       add_timer(&n2lm_d1_timer);
251 +                       break;
252 +
253 +               case LED_DISK2:
254 +                       n2lm_d2_timer.expires = jiffies + BLINK_DELAY; 
255 +                       add_timer(&n2lm_d2_timer);
256 +                       break;
257 +
258 +               default:
259 +                       break;
260 +       }
261 +       return;
262 +}
263 +
264 +//==================================================================================================
265 +
266 +static void n2lm_timer_stop(unsigned long led)
267 +{
268 +       switch (led) {
269 +               case LED_RS_RED:
270 +                       del_timer(&n2lm_rsr_timer);
271 +                       break;
272 +               case LED_RS_GRN:
273 +                       del_timer(&n2lm_rsg_timer);
274 +                       break;
275 +               case LED_DISK1:
276 +                       del_timer(&n2lm_d1_timer);
277 +                       break;
278 +               case LED_DISK2: 
279 +                       del_timer(&n2lm_d2_timer);
280 +                       break;
281 +               default:
282 +                       break;
283 +       }
284 +       return;
285 +}
286 +
287 +//--------------------------------------------------------------------------------------------------
288 +
289 +static void n2lm_timer_stop_all(void)
290 +{
291 +       del_timer(&n2lm_rsg_timer);
292 +       del_timer(&n2lm_rsr_timer);
293 +       del_timer(&n2lm_d1_timer); 
294 +       del_timer(&n2lm_d2_timer);
295 +       return;
296 +}
297 +//--------------------------------------------------------------------------------------------------
298 +
299 +static void n2lm_ledon(unsigned long led)
300 +{
301 +
302 +       nslu2_io_debug((KERN_DEBUG "ledon: %ld\n", led));
303 +
304 +       switch (led) {
305 +               case LED_RS_RED:        
306 +                       *IXP4XX_GPIO_GPOUTR |= RS_RED_ON;       //1
307 +                       return;
308 +               case LED_RS_GRN:
309 +                       *IXP4XX_GPIO_GPOUTR |= RS_GRN_ON;       //2
310 +                       return;
311 +               case LED_DISK1:
312 +                       *IXP4XX_GPIO_GPOUTR &= DISK1_ON;        //0xfffffff7
313 +                       return;
314 +               case LED_DISK2: 
315 +                       *IXP4XX_GPIO_GPOUTR &= DISK2_ON;        //0xfffffffb
316 +                       return;
317 +               case LED_ALL:                                   //all green
318 +                       *IXP4XX_GPIO_GPOUTR |= RS_GRN_ON;
319 +                       *IXP4XX_GPIO_GPOUTR &= (DISK1_ON & DISK2_ON);
320 +                       return; 
321 +       }
322 +}
323 +
324 +//--------------------------------------------------------------------------------------------------
325 +
326 +static void n2lm_ledoff(unsigned long led)
327 +{
328 +
329 +       switch (led) {
330 +               case LED_RS_RED:        
331 +                       *IXP4XX_GPIO_GPOUTR &= RS_RED_OFF;      //0xffffffffe
332 +                       return;
333 +               case LED_RS_GRN:
334 +                       *IXP4XX_GPIO_GPOUTR &= RS_GRN_OFF;      //0xfffffffd
335 +                       return;
336 +               case LED_DISK1:
337 +                       *IXP4XX_GPIO_GPOUTR |= DISK1_OFF;       //0x00000008
338 +                       return;
339 +               case LED_DISK2: 
340 +                       *IXP4XX_GPIO_GPOUTR |= DISK2_OFF;       //0x00000004
341 +                       return;
342 +               case LED_ALL:
343 +                       *IXP4XX_GPIO_GPOUTR &= (RS_GRN_OFF & RS_RED_OFF);
344 +                       *IXP4XX_GPIO_GPOUTR |= (DISK1_OFF | DISK2_OFF);
345 +       }
346 +}
347 +
348 +//==================================================================================================
349 +
350 +static int n2lm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long led)
351 +{
352 +
353 +       nslu2_io_debug((KERN_DEBUG "cmd=%d, led=%ld\n", cmd, led));
354 +       
355 +       if (led < 0 || led >= PHYS_LEDS)
356 +               return -EINVAL;
357 +
358 +       switch (cmd ) {
359 +               case NSLU2LM_ON:
360 +                       n2lm_timer_stop(led);
361 +                       n2lm_ledon(led);
362 +                       break;
363 +                       
364 +               case NSLU2LM_OFF:
365 +                       n2lm_timer_stop(led);
366 +                       n2lm_ledoff(led);
367 +                       break;
368 +                       
369 +               case NSLU2LM_BLINK:
370 +                       n2lm_ledon(led);
371 +                       if (led == LED_RS_RED)
372 +                               n2lm_rsr_timer.data = RS_RED_TGL;
373 +                       n2lm_timer_start(led);
374 +                       break;
375 +
376 +               case NSLU2LM_ALT:
377 +                       if (led == LED_RS_RED)
378 +                       {
379 +                               n2lm_ledon(LED_RS_GRN);
380 +                               n2lm_ledoff(LED_RS_RED);
381 +                               n2lm_rsr_timer.data = RS_RG_ALT;
382 +                               n2lm_timer_start(LED_RS_RED);
383 +                               break;
384 +                       } else
385 +                               return -EINVAL;
386 +               
387 +               case NSLU2LM_ALL_ON:
388 +                       n2lm_timer_stop_all();
389 +                       n2lm_ledon(LED_ALL);
390 +                       break;
391 +               
392 +               case NSLU2LM_ALL_OFF:
393 +                       n2lm_timer_stop_all();
394 +                       n2lm_ledoff(LED_ALL);
395 +                       break;
396 +               
397 +               default:
398 +                       return -EINVAL;
399 +       }
400 +
401 +       return 0;
402 +}
403 +
404 +static struct file_operations n2lm_fops = {
405 +       .owner          = THIS_MODULE,
406 +       .ioctl          = n2lm_ioctl,
407 +};
408 +//==================================================================================================
409 +// We can't do anything fancy here since the system tick rate is far below that required to
410 +// generate a desirable tone.  Therefore we haven't much choice but to use a busy loop until
411 +// I get up to speed on the timers.  The saving grace is that for the normal uses, nothing 
412 +// important should be haprepening. 
413 +//==================================================================================================
414 +
415 +static void n2_buzz(int tone_delay, int duration)
416 +{
417 +       int i;
418 +
419 +       *IXP4XX_GPIO_GPOER &= ~GPIO_BZ_BM;
420 +               
421 +       for (i = 1; i < duration; i++) {
422 +               *IXP4XX_GPIO_GPOUTR &= ~GPIO_BZ_BM;
423 +               udelay(tone_delay);
424 +               *IXP4XX_GPIO_GPOUTR |= GPIO_BZ_BM;
425 +               udelay(tone_delay);
426 +       }
427 +       *IXP4XX_GPIO_GPOER |= GPIO_BZ_BM;
428 +
429 +       return;
430 +}
431 +//=================================================================================================
432 +
433 +// this handles the buzzer duty cycle
434 +static void n2bz_handler(unsigned long data)
435 +{
436 +       if (--bz_repeatcnt > 0) {                       //if just one beep left to do
437 +               n2bz_timer.expires = jiffies + ontime + offtime;        //next timeout
438 +               add_timer(&n2bz_timer);                                 //reinit timer
439 +       }
440 +       n2_buzz(tone/2, ontime);
441 +       nslu2_io_debug((KERN_DEBUG "Count = %d\tOntime = %d\n", bz_repeatcnt, ontime));
442 +       return;
443 +}
444 +
445 +//==================================================================================================
446 +
447 +static int n2bz_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param)
448 +{
449 +       switch (cmd) {
450 +               case NSLU2BZ_BEEP:
451 +                       n2_buzz(tone/2, ontime);
452 +                       break;
453 +       
454 +               case NSLU2BZ_BEEP_STOP:
455 +                       del_timer(&n2bz_timer);
456 +                       break;
457 +
458 +               case NSLU2BZ_BEEPS:
459 +                       if (param == 0)
460 +                               bz_repeatcnt = 0xffffffff;
461 +                       else
462 +                               bz_repeatcnt = param;
463 +                       n2bz_handler(0);
464 +                       break;
465 +       
466 +               case NSLU2BZ_TONESET:
467 +                       if (param >= 250 && param <= 2000)
468 +                               tone = param;
469 +                       break;
470 +
471 +               case NSLU2BZ_ONTIME:
472 +                       if (param > 4 && param < 201)
473 +                               ontime = param;
474 +                       break;
475 +
476 +               case NSLU2BZ_SILENTTIME:
477 +                       if (param > ontime)                     //enforce a reasonable duty cycle
478 +                               offtime = param;
479 +                       else
480 +                               offtime = ontime;
481 +                       break;
482 +
483 +               case NSLU2BZ_REPEATCNT:
484 +                       if (param == 0)
485 +                               bz_repeatcnt = 0xffffffff;
486 +                       else
487 +                               bz_repeatcnt = param;
488 +                       break;
489 +
490 +               case NSLU2BZ_COMBINED:
491 +                       bz_repeatcnt =  (param & 0xF0000000) >> 28;     //repeat 1 - 16
492 +                       ontime =        (param & 0x0FF00000) >> 20;     //ontime 1 - 256 jiffies
493 +                       offtime =       (param & 0x000FFF00) >> 8;      //offtime 1 - 4095 jiffies
494 +                       tone =          (param & 0x000000FF) << 4;      //tone (1 - 255) * 16
495 +                       break;
496 +
497 +               default:
498 +                       break;
499 +       }
500 +       return 0;
501 +}
502 +
503 +static struct file_operations n2bz_fops = {
504 +       .owner          = THIS_MODULE,
505 +       .ioctl          = n2bz_ioctl,
506 +};
507 +
508 +//==================================================================================================
509 +               
510 +static irqreturn_t n2pb_handler (int irq, void *dev_id, struct pt_regs *regs)
511 +{
512 +       void *ret;
513 +       if (!nslu2_shutdown_in_progress++) {                    
514 +               wake_up(&n2pb_waitq);   
515 +               remove_proc_entry(PWR_OFF_STR, NULL);           //no parent     
516 +               n2_buzz(NSLU2_BEEP_PITCH_HIGH, NSLU2_BEEP_DUR_SHORT); // Short, high-pitched "OK"
517 +               ret = create_proc_entry(PWR_OFF_STR, 0, NULL);
518 +               nslu2_io_debug((KERN_DEBUG "Powerbutton pressed. Shutting down. cpe ret = %p\n", ret));
519 +               kill_proc(1,SIGINT,1);                          // Signal init to shut down
520 +       } else {
521 +               n2_buzz(NSLU2_BEEP_PITCH_LOW, NSLU2_BEEP_DUR_MED);    // Make a scary noise!
522 +               nslu2_io_debug((KERN_DEBUG "Powerbutton pressed while already in shutdown")); // Whine!
523 +       }                                
524 +       return IRQ_HANDLED;
525 +}
526 +
527 +struct testr {
528 +       int     ctl;
529 +       long    param;
530 +};
531 +
532 +static irqreturn_t n2rb_handler (int irq, void *dev_id, struct pt_regs *regs)
533 +{
534 +//     This doesn't reset the NSLU2. It powers it off. Close enough, since reset is unreliable
535 +
536 +       wake_up(&n2rb_waitq);   
537 +       machine_power_off();
538 +       return IRQ_HANDLED;             // So we don't get a nobody cared error :-P
539 +}
540 +
541 +//==================================================================================================
542 +//  What to do here is majorly undetermined...
543 +
544 +static int n2rb_read (struct file *filp, char __user *buffer, size_t count, loff_t *ppos)
545 +{
546 +       printk(KERN_DEBUG "Reset Button Wait\n");
547 +       interruptible_sleep_on(&n2rb_waitq);
548 +       return copy_to_user(buffer, "reset", 5) ? -EFAULT : 5;
549 +
550 +}
551 +
552 +//==================================================================================================
553 +//  What to do here is majorly undetermined...
554 +
555 +static int n2pb_read (struct file *filp, char __user *buffer, size_t count, loff_t *ppos)
556 +{
557 +       printk(KERN_DEBUG "Power Button Wait\n");
558 +       interruptible_sleep_on(&n2pb_waitq);
559 +       return copy_to_user(buffer, "poweroff", 8) ? -EFAULT : 8;
560 +
561 +}
562 +
563 +//--------------------------------------------------------------------------------------------------
564 +
565 +static struct file_operations n2rb_fops = {
566 +       .owner          = THIS_MODULE,
567 +       .read           = n2rb_read,
568 +};
569 +
570 +//--------------------------------------------------------------------------------------------------
571 +
572 +static struct file_operations n2pb_fops = {
573 +       .owner          = THIS_MODULE,
574 +       .read           = n2pb_read,
575 +};
576 +
577 +//==================================================================================================
578 +
579 +static void n2iom_initarch(void)
580 +{
581 +       printk(KERN_DEBUG "setup_interrupts - jiffies=%ld init_jiffy=%ld\n", jiffies, init_jiffy);
582 +
583 +       *IXP4XX_GPIO_GPISR = 0x20400000;        // read the 2 irqs to clr
584 +       set_irq_type(NSLU2_RB_IRQ, IRQT_LOW);
585 +       set_irq_type(NSLU2_PB_IRQ, IRQT_HIGH);
586 +
587 +       gpio_line_isr_clear(NSLU2_RB_GPIO);
588 +       gpio_line_isr_clear(NSLU2_PB_GPIO);
589 +
590 +       
591 +       init_timer(&n2lm_rsg_timer);
592 +       init_timer(&n2lm_rsr_timer);
593 +       init_timer(&n2lm_d1_timer);
594 +       init_timer(&n2lm_d2_timer);
595 +//     init_timer(&n2rb_timer);
596 +//     init_timer(&n2pb_timer);
597 +       init_timer(&n2bz_timer);
598 +
599 +       n2lm_rsr_timer.function = n2lm_rsr_handler;
600 +       n2lm_rsg_timer.function = n2lm_rsg_handler;
601 +       n2lm_d2_timer.function = n2lm_d2_handler;
602 +       n2lm_d1_timer.function = n2lm_d1_handler;
603 +       n2bz_timer.function = n2bz_handler;
604 +       n2lm_rsr_timer.data = n2lm_rsg_timer.data = n2lm_d1_timer.data = n2lm_d2_timer.data = n2bz_timer.data = 0;
605 +
606 +       *IXP4XX_GPIO_GPOER &= 0xfffffff0;       //enable gpio 0-3
607 +       *IXP4XX_GPIO_GPOUTR |= 0x00000003;      //turn off the leds
608 +       *IXP4XX_GPIO_GPOUTR &= 0xfffffffc;
609 +       n2lm_ledon(LED_ALL);
610 +       n2_buzz(NSLU2_BEEP_PITCH_MED, NSLU2_BEEP_DUR_SHORT);
611 +       n2lm_ledoff(LED_ALL);
612 +// Default the Ready/Status to Red during kernel boot, Turn Green at the end of sysvinit
613 +       n2lm_ledon(LED_RS_RED);
614 +
615 +       return;
616 +}
617 +
618 +//==================================================================================================
619 +
620 +static int __init n2iom_init(void)
621 +{
622 +       printk(KERN_INFO "NSLU2 I/O driver  %s\n", VERSION);
623 +       
624 +       init_jiffy = jiffies;
625 +       printk(KERN_DEBUG "init_jiffy=%ld\n",init_jiffy);
626 +       n2iom_initarch();
627 +
628 +       n2lm_class = class_create(THIS_MODULE, "nslu2");
629 +
630 +       if (register_chrdev(NSLU2RB_MAJOR, "n2_rbm", &n2pb_fops) < 0) {
631 +               printk(KERN_DEBUG "Reset Button Major %d not available\n", NSLU2RB_MAJOR);
632 +               return -EBUSY;
633 +       }
634 +       else {
635 +               class_device_create(n2lm_class, MKDEV(NSLU2RB_MAJOR, 0), NULL, "rbuttons");
636 +       }
637 +       if (register_chrdev(NSLU2PB_MAJOR, "n2_pbm", &n2rb_fops) < 0) {
638 +               printk(KERN_DEBUG "Power Button Major %d not available\n", NSLU2PB_MAJOR);
639 +               return -EBUSY;
640 +       }
641 +       else {
642 +               class_device_create(n2lm_class, MKDEV(NSLU2PB_MAJOR, 0), NULL, "pbuttons");
643 +       }
644 +       if (register_chrdev(NSLU2LM_MAJOR, "n2_ledm", &n2lm_fops) < 0) {
645 +               printk(KERN_DEBUG "Led Manager Major %d not available\n", NSLU2LM_MAJOR);
646 +               return -EBUSY;
647 +       }
648 +       else {
649 +               class_device_create(n2lm_class, MKDEV(NSLU2LM_MAJOR, 0), NULL, "leds");
650 +       }
651 +       if (register_chrdev(NSLU2BZ_MAJOR, "n2_bzm", &n2bz_fops) < 0) {
652 +               printk(KERN_DEBUG "Buzzer Major %d not available\n", NSLU2BZ_MAJOR);
653 +               return -EBUSY;
654 +       }
655 +       else {
656 +               class_device_create(n2lm_class, MKDEV(NSLU2BZ_MAJOR, 0), NULL, "buzzer");
657 +       }
658 +
659 +       if (request_irq(NSLU2_RB_IRQ, &n2rb_handler,
660 +                       SA_INTERRUPT, "NSLU2 reset button", NULL) < 0) {
661 +               printk(KERN_DEBUG "Reset Button IRQ %d not available\n", NSLU2_RB_IRQ);
662 +               return -EIO;
663 +       }
664 +       if (request_irq(NSLU2_PB_IRQ, &n2pb_handler,
665 +                       SA_INTERRUPT, "NSLU2 power button", NULL) < 0) {
666 +               printk(KERN_DEBUG "Power Button IRQ %d not available\n", NSLU2_PB_IRQ);
667 +               return -EIO;    
668 +       }
669 +       
670 +       enable_irq(NSLU2_PB_IRQ);
671 +       enable_irq(NSLU2_RB_IRQ);
672 +
673 +       return 0;
674 +}
675 +
676 +//==================================================================================================
677 +
678 +static void __exit n2iom_exit(void)
679 +{
680 +       remove_proc_entry(PWR_OFF_STR, NULL);
681 +       del_timer(&n2rb_timer);
682 +       free_irq(NSLU2_RB_IRQ,NULL);
683 +       unregister_chrdev(NSLU2PB_MAJOR, "n2pb");
684 +       class_device_destroy(n2lm_class, MKDEV(NSLU2PB_MAJOR, 0));
685 +       del_timer(&n2pb_timer); 
686 +       free_irq(NSLU2_PB_IRQ, NULL);
687 +       unregister_chrdev(NSLU2RB_MAJOR, "n2rb" );
688 +       class_device_destroy(n2lm_class, MKDEV(NSLU2RB_MAJOR, 0));
689 +       del_timer(&n2lm_rsg_timer);
690 +       del_timer(&n2lm_rsr_timer);
691 +       del_timer(&n2lm_d1_timer);
692 +       del_timer(&n2lm_d2_timer);      
693 +       unregister_chrdev(NSLU2LM_MAJOR, "n2lm" );
694 +       class_device_destroy(n2lm_class, MKDEV(NSLU2LM_MAJOR, 0));
695 +       unregister_chrdev(NSLU2BZ_MAJOR, "n2bz");
696 +       class_device_destroy(n2lm_class, MKDEV(NSLU2BZ_MAJOR, 0));
697 +       class_destroy(n2lm_class);
698 +}
699 +
700 +module_init (n2iom_init);
701 +module_exit (n2iom_exit);
702 +
703 +MODULE_AUTHOR("Karen Spearel <kas11@tampabay.rr.com>");
704 +MODULE_DESCRIPTION("NSLU2 I/O driver");
705 +MODULE_LICENSE("GPL");
706 +static int debug = 7;
707 +module_param(debug, int, 0644);
708 +MODULE_PARM_DESC(debug, "Debugging enabled = 8");
709 +
710 diff -urN linux-2.6.14-rc2/arch/arm/mach-ixp4xx/nslu2-pci.c test3/arch/arm/mach-ixp4xx/nslu2-pci.c
711 --- linux-2.6.14-rc2/arch/arm/mach-ixp4xx/nslu2-pci.c   1970-01-01 01:00:00.000000000 +0100
712 +++ test3/arch/arm/mach-ixp4xx/nslu2-pci.c      2005-09-24 15:19:54.000000000 +0200
713 @@ -0,0 +1,83 @@
714 +/*
715 + * arch/arm/mach-ixp4xx/nslu2-pci.c
716 + *
717 + * NSLU2 board-level PCI initialization
718 + *
719 + * based on ixdp425-pci.c:
720 + *     Copyright (C) 2002 Intel Corporation.
721 + *     Copyright (C) 2003-2004 MontaVista Software, Inc.
722 + *
723 + * Maintainer: http://www.nslu2-linux.org/
724 + *
725 + * This program is free software; you can redistribute it and/or modify
726 + * it under the terms of the GNU General Public License version 2 as
727 + * published by the Free Software Foundation.
728 + *
729 + */
730 +// GPIO 8 is used as the power input so is not free for use as a PCI IRQ
731 +// However, all the common PCI setup code presumes the standard 4 PCI
732 +// interrupts are available.  So we compromise...we don't enable the
733 +// IRQ on Pin 8 but we let
734 +
735 +#include <linux/config.h>
736 +#include <linux/pci.h>
737 +#include <linux/init.h>
738 +#include <linux/delay.h>
739 +
740 +#include <asm/mach/pci.h>
741 +#include <asm/irq.h>
742 +#include <asm/hardware.h>
743 +#include <asm/mach-types.h>
744 +
745 +void __init nslu2_pci_preinit(void)
746 +{
747 +       set_irq_type(IRQ_NSLU2_PCI_INTA, IRQT_LOW);
748 +       set_irq_type(IRQ_NSLU2_PCI_INTB, IRQT_LOW);
749 +       set_irq_type(IRQ_NSLU2_PCI_INTC, IRQT_LOW);
750 +
751 +       gpio_line_isr_clear(NSLU2_PCI_INTA_PIN);
752 +       gpio_line_isr_clear(NSLU2_PCI_INTB_PIN);
753 +       gpio_line_isr_clear(NSLU2_PCI_INTC_PIN);
754 +
755 +       /* INTD is not configured. Unused? */
756 +
757 +       ixp4xx_pci_preinit();
758 +}
759 +
760 +static int __init nslu2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
761 +{
762 +       static int pci_irq_table[NSLU2_PCI_IRQ_LINES] = {
763 +               IRQ_NSLU2_PCI_INTA,
764 +               IRQ_NSLU2_PCI_INTB,
765 +               IRQ_NSLU2_PCI_INTC,
766 +       };
767 +
768 +       int irq = -1;
769 +
770 +       if (slot >= 1 && slot <= NSLU2_PCI_MAX_DEV &&
771 +               pin >= 1 && pin <= NSLU2_PCI_IRQ_LINES) {
772 +                       irq = pci_irq_table[
773 +                               (slot + pin - 2) % 3];
774 +       }
775 +
776 +       return irq;
777 +}
778 +
779 +struct hw_pci __initdata nslu2_pci = {
780 +       .nr_controllers = 1,
781 +       .preinit        = nslu2_pci_preinit,
782 +       .swizzle        = pci_std_swizzle,
783 +       .setup          = ixp4xx_setup,
784 +       .scan           = ixp4xx_scan_bus,
785 +       .map_irq        = nslu2_map_irq,
786 +};
787 +
788 +int __init nslu2_pci_init(void) /* monkey see, monkey do */
789 +{
790 +       if (machine_is_nslu2())
791 +               pci_common_init(&nslu2_pci);
792 +
793 +       return 0;
794 +}
795 +
796 +subsys_initcall(nslu2_pci_init);
797 diff -urN linux-2.6.14-rc2/arch/arm/mach-ixp4xx/nslu2-rtc.c test3/arch/arm/mach-ixp4xx/nslu2-rtc.c
798 --- linux-2.6.14-rc2/arch/arm/mach-ixp4xx/nslu2-rtc.c   1970-01-01 01:00:00.000000000 +0100
799 +++ test3/arch/arm/mach-ixp4xx/nslu2-rtc.c      2005-09-24 17:35:55.000000000 +0200
800 @@ -0,0 +1,108 @@
801 +/*
802 + * arch/arm/mach-ixp4xx/nslu2-rtc.c
803 + *
804 + * NSL2 RTC driver
805 + *
806 + * Copyright (C) 2005 Tower Technologies
807 + *
808 + * based on x1205-rtc.c  
809 + *  Copyright (C) 2004 Karen Spearel
810 + *
811 + * Author: Alessandro Zummo <a.zummo@towertech.it>
812 + * Maintainers: http://www.nslu2-linux.org/
813 + *
814 + * This program is free software; you can redistribute it and/or modify
815 + * it under the terms of the GNU General Public License version 2 as
816 + * published by the Free Software Foundation.
817 + *
818 + */
819 +
820 +#include <linux/module.h>
821 +#include <linux/time.h>
822 +#include <linux/rtc.h>
823 +#include <linux/init.h>
824 +
825 +#include <linux/x1205.h>
826 +
827 +#include <asm/rtc.h>
828 +
829 +
830 +extern int (*set_rtc)(void);
831 +
832 +static int nslu2_set_rtc(void)
833 +{
834 +       struct rtc_time new_tm, old_tm;
835 +       unsigned long cur_secs = xtime.tv_sec;
836 +
837 +       if (x1205_do_command(X1205_CMD_GETDATETIME, &old_tm))
838 +               return 0;
839 +
840 +       /* FIXME      xtime.tv_nsec = old_tm.tm_sec * 10000000; */
841 +       new_tm.tm_sec  = cur_secs % 60;
842 +       cur_secs /= 60;
843 +       new_tm.tm_min  = cur_secs % 60;
844 +       cur_secs /= 60;
845 +       new_tm.tm_hour = cur_secs % 24;
846 +
847 +       /*
848 +       * avoid writing when we're going to change the day
849 +       * of the month.  We will retry in the next minute.
850 +       * This basically means that if the RTC must not drift
851 +       * by more than 1 minute in 11 minutes.
852 +       */
853 +       if ((old_tm.tm_hour == 23 && old_tm.tm_min == 59) ||
854 +           (new_tm.tm_hour == 23 && new_tm.tm_min == 59))
855 +               return 1;
856 +
857 +       return x1205_do_command(X1205_CMD_SETTIME, &new_tm);
858 +}
859 +
860 +static int rtc_read_alarm(struct rtc_wkalrm *alrm)
861 +{
862 +       return x1205_do_command(X1205_CMD_GETALARM, &alrm->time);
863 +}
864 +
865 +static inline int rtc_set_alarm(struct rtc_wkalrm *alrm)
866 +{
867 +       return x1205_do_command(X1205_CMD_SETALARM, &alrm->time);
868 +}
869 +
870 +static int rtc_read_time(struct rtc_time *tm)
871 +{
872 +       return x1205_do_command(X1205_CMD_GETDATETIME, tm);
873 +}
874 +
875 +static int rtc_set_time(struct rtc_time *tm)
876 +{
877 +       return x1205_do_command(X1205_CMD_SETDATETIME, tm);
878 +}
879 +
880 +static struct rtc_ops rtc_ops = {
881 +       .owner          = THIS_MODULE,
882 +       .read_time      = rtc_read_time,
883 +       .set_time       = rtc_set_time,
884 +       .read_alarm     = rtc_read_alarm,
885 +       .set_alarm      = rtc_set_alarm,
886 +};
887 +
888 +static int __init nslu2_rtc_init(void)
889 +{
890 +       int ret = register_rtc(&rtc_ops);
891 +
892 +       if (ret)
893 +               return ret;
894 +
895 +       set_rtc = nslu2_set_rtc;
896 +
897 +       return 0;
898 +}
899 +
900 +static void __exit nslu2_rtc_exit(void)
901 +{
902 +       set_rtc = NULL;
903 +
904 +       unregister_rtc(&rtc_ops);
905 +}
906 +
907 +module_init(nslu2_rtc_init);
908 +module_exit(nslu2_rtc_exit);
909 diff -urN linux-2.6.14-rc2/arch/arm/mach-ixp4xx/nslu2-setup.c test3/arch/arm/mach-ixp4xx/nslu2-setup.c
910 --- linux-2.6.14-rc2/arch/arm/mach-ixp4xx/nslu2-setup.c 1970-01-01 01:00:00.000000000 +0100
911 +++ test3/arch/arm/mach-ixp4xx/nslu2-setup.c    2005-09-24 17:27:31.000000000 +0200
912 @@ -0,0 +1,145 @@
913 +/*
914 + * arch/arm/mach-ixp4xx/nslu2-setup.c
915 + *
916 + * NSLU2 board-setup
917 + *
918 + * based ixdp425-setup.c:
919 + *      Copyright (C) 2003-2004 MontaVista Software, Inc.
920 + *
921 + * Author: Mark Rakes <mrakes at mac.com>
922 + * Maintainers: http://www.nslu2-linux.org/
923 + *
924 + * Fixed missing init_time in MACHINE_START kas11 10/22/04
925 + * Changed to conform to new style __init ixdp425 kas11 10/22/04 
926 + */
927 +
928 +#include <linux/kernel.h>
929 +#include <linux/init.h>
930 +#include <linux/device.h>
931 +#include <linux/serial.h>
932 +#include <linux/tty.h>
933 +#include <linux/serial_8250.h>
934 +
935 +#include <asm/types.h>
936 +#include <asm/setup.h>
937 +#include <asm/memory.h>
938 +#include <asm/hardware.h>
939 +#include <asm/mach-types.h>
940 +#include <asm/irq.h>
941 +#include <asm/mach/arch.h>
942 +#include <asm/mach/flash.h>
943 +
944 +static struct flash_platform_data nslu2_flash_data = {
945 +       .map_name       = "cfi_probe",
946 +       .width          = 2,
947 +};
948 +
949 +static struct resource nslu2_flash_resource = {
950 +       .start          = NSLU2_FLASH_BASE,
951 +       .end            = NSLU2_FLASH_BASE + NSLU2_FLASH_SIZE,
952 +       .flags          = IORESOURCE_MEM,
953 +};
954 +
955 +static struct platform_device nslu2_flash = {
956 +       .name           = "IXP4XX-Flash",
957 +       .id             = 0,
958 +       .dev            = {
959 +               .platform_data = &nslu2_flash_data,
960 +       },
961 +       .num_resources  = 1,
962 +       .resource       = &nslu2_flash_resource,
963 +};
964 +
965 +static struct ixp4xx_i2c_pins nslu2_i2c_gpio_pins = {
966 +       .sda_pin        = NSLU2_SDA_PIN,
967 +       .scl_pin        = NSLU2_SCL_PIN,
968 +};
969 +
970 +static struct platform_device nslu2_i2c_controller = {
971 +       .name           = "IXP4XX-I2C",
972 +       .id             = 0,
973 +       .dev            = {
974 +               .platform_data = &nslu2_i2c_gpio_pins,
975 +       },
976 +       .num_resources  = 0
977 +};
978 +
979 +static struct resource nslu2_uart_resources[] = {
980 +       {
981 +               .start          = IXP4XX_UART1_BASE_PHYS,
982 +               .end            = IXP4XX_UART1_BASE_PHYS + 0x0fff,
983 +               .flags          = IORESOURCE_MEM
984 +       },
985 +       {
986 +               .start          = IXP4XX_UART2_BASE_PHYS,
987 +               .end            = IXP4XX_UART2_BASE_PHYS + 0x0fff,
988 +               .flags          = IORESOURCE_MEM
989 +       }
990 +};
991 +
992 +static struct plat_serial8250_port nslu2_uart_data[] = {
993 +       {
994 +               .mapbase        = IXP4XX_UART1_BASE_PHYS,
995 +               .membase        = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
996 +               .irq            = IRQ_IXP4XX_UART1,
997 +               .flags          = UPF_BOOT_AUTOCONF,
998 +               .iotype         = UPIO_MEM,
999 +               .regshift       = 2,
1000 +               .uartclk        = IXP4XX_UART_XTAL,
1001 +       },
1002 +       {
1003 +               .mapbase        = IXP4XX_UART2_BASE_PHYS,
1004 +               .membase        = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
1005 +               .irq            = IRQ_IXP4XX_UART2,
1006 +               .flags          = UPF_BOOT_AUTOCONF,
1007 +               .iotype         = UPIO_MEM,
1008 +               .regshift       = 2,
1009 +               .uartclk        = IXP4XX_UART_XTAL,
1010 +       },
1011 +       { }
1012 +};
1013 +
1014 +static struct platform_device nslu2_uart = {
1015 +       .name                   = "serial8250",
1016 +       .id                     = PLAT8250_DEV_PLATFORM,
1017 +       .dev.platform_data      = nslu2_uart_data,
1018 +       .num_resources          = 2,
1019 +       .resource               = nslu2_uart_resources
1020 +};
1021 +
1022 +static struct platform_device *nslu2_devices[] __initdata = {
1023 +       &nslu2_i2c_controller,
1024 +       &nslu2_flash,
1025 +       &nslu2_uart
1026 +};
1027 +
1028 +static void n2_power_off(void)
1029 +{
1030 +        /* This causes the box to drop the power and go dead. */
1031 +#define GPIO_PO_BM              0x0100  //b0000 0001 0000 0000
1032 +        *IXP4XX_GPIO_GPOER &= ~GPIO_PO_BM;     /* enable the pwr cntl gpio */
1033 +        *IXP4XX_GPIO_GPOUTR |= GPIO_PO_BM;      /* do the deed */
1034 +}
1035 +
1036 +static void __init nslu2_init(void)
1037 +{
1038 +       /* NSLU2 has a 33.00 MHZ crystal, we need to cope with that */
1039 +/*     ixp4xx_ticks_per_usec = NSLU2_CLOCK_TICKS_PER_USEC;*/
1040 +
1041 +       ixp4xx_sys_init();
1042 +
1043 +       pm_power_off = n2_power_off;
1044 +       platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices));
1045 +}
1046 +
1047 +MACHINE_START(NSLU2, "Linksys NSLU2")
1048 +       /* Maintainer: www.nslu2-linux.org */
1049 +       .phys_ram       = PHYS_OFFSET,
1050 +       .phys_io        = IXP4XX_PERIPHERAL_BASE_PHYS,
1051 +       .io_pg_offst    = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
1052 +       .boot_params    = 0x00000100,
1053 +       .map_io         = ixp4xx_map_io,
1054 +       .init_irq       = ixp4xx_init_irq, /* FIXME: all irq are off here */
1055 +        .timer          = &ixp4xx_timer,
1056 +       .init_machine   = nslu2_init,
1057 +MACHINE_END