--- nslu2-io.c.old 2da1d3f5c0aa0804c5769588337077ddcb35c5e9 +++ linux-2.6.12.2/arch/arm/mach-ixp4xx/nslu2-io.c e895da638b4aae16a11fafe52ae0b063645a9a12 @@ -158,6 +158,8 @@ #define LED_DISK2 3 #define LED_ALL 4 +static int nslu2_shutdown_in_progress = 0; + static unsigned long init_jiffy = 0; //jiffies at init time static unsigned long rb_presses = 0; //number of reset button presses static unsigned long ontime = 50; @@ -503,40 +505,20 @@ static irqreturn_t n2pb_handler (int irq, void *dev_id, struct pt_regs *regs) { void *ret; - - wake_up(&n2pb_waitq); - remove_proc_entry(PWR_OFF_STR, NULL); //no parent - n2_buzz(N2_BEEP_PITCH_MED, N2_BEEP_DUR_MED); - ret = create_proc_entry(PWR_OFF_STR, 0, NULL); - nslu2_io_debug((KERN_DEBUG "cpe ret = %p\n", ret)); - -// WARNING: This is RUDE...it unconditionally pulls the power plug. -// Your data will be at risk...since this is just a test system -// I am leaving it enabled...eventually userland needs to get the -// message, do an orderly shutdown and use an ioctl or something in -// /proc/powerdowm to actually have us pull the plug. - - machine_power_off(); - + if (!nslu2_shutdown_in_progress++) { + wake_up(&n2pb_waitq); + remove_proc_entry(PWR_OFF_STR, NULL); //no parent + n2_buzz(N2_BEEP_PITCH_HIGH, N2_BEEP_DUR_SHORT); // Short, high-pitched "OK" + ret = create_proc_entry(PWR_OFF_STR, 0, NULL); + nslu2_io_debug((KERN_DEBUG "Powerbutton pressed. Shutting down. cpe ret = %p\n", ret)); + kill_proc(1,SIGINT,1); // Signal init to shut down + } else { + n2_buzz(N2_BEEP_PITCH_LOW, N2_BEEP_DUR_MED); // Make a scary noise! + nslu2_io_debug((KERN_DEBUG "Powerbutton pressed while already in shutdown")); // Whine! + } return IRQ_HANDLED; } -//================================================================================================== -// -//static void do_rb_timeout(unsigned long data) -//{ -// int i; -// -// for (i = 0; i < rb_presses; i++) -// n2_buzz(N2_BEEP_PITCH_MED,N2_BEEP_DUR_SHORT); -// return; -//} -// -//================================================================================================== -// does nothing -- waiting for userland to define -// This thing is sorta braindead...edge triggered IRQs aren't available in the drivers yet...so -// we hang in a loop until the button is no longer pressed - struct testr { int ctl; long param; @@ -544,72 +526,11 @@ static irqreturn_t n2rb_handler (int irq, void *dev_id, struct pt_regs *regs) { +// This doesn't reset the NSLU2. It powers it off. Close enough, since reset is unreliable - static struct testr test[] = { - { N2LM_ALL_OFF,0 }, - { N2LM_ON,0 }, - { N2LM_OFF,0 }, - { N2LM_ON,1 }, - { N2LM_ALL_OFF,1 }, - { N2LM_ON,2 }, - { N2LM_OFF,2 }, - { N2LM_ON,3 }, - { N2LM_OFF,3 }, - { N2LM_BLINK,0 }, - { N2LM_OFF,0 }, - { N2LM_BLINK,1 }, - { N2LM_OFF,1 }, - { N2LM_BLINK,2 }, - { N2LM_OFF,2 }, - { N2LM_BLINK,3 }, - { N2LM_OFF,3 }, - { N2LM_ALL_OFF,0 }, - { N2LM_ALT,1 }, - { N2LM_OFF,1 }, - { N2LM_ALL_ON,0 } - }; - - nslu2_io_debug(("Reset Entry IRQ =%d Presses = %d Jiffies = %08lx\tIO = %x\tIOW = %x\n", irq, rb_presses, jiffies, (int)_IO('M',rb_presses), (int)_IOW('M',rb_presses,long))); - wake_up(&n2rb_waitq); - while ((*IXP4XX_GPIO_GPINR & GPIO_RB_BM) == 0) - ; //wait for button release - - if (rb_presses > 20) - rb_presses = 0; - tone = (rb_presses * 50) + 200; - ontime = (rb_presses*10) + 100; - offtime = 500 - (rb_presses*20); - nslu2_io_debug(("Ontime = %d\tOfftime = %d\tTone = %d\n",ontime,offtime,tone)); - rb_presses++; - - n2bz_ioctl(NULL,NULL, N2BZ_BEEPS, rb_presses); - n2lm_ioctl(NULL,NULL, test[rb_presses].ctl, test[rb_presses].param); -// if (rb_presses == 0) { -// init_jiffy = jiffies; -// init_timer (&n2rb_timer); -// n2rb_timer.function = do_rb_timeout; -// }; -// -// if (rb_presses == 8) -// rb_presses = 0; -// if (rb_presses & 1) -// n2lm_ledon(test[rb_presses]); -// else -// n2lm_ledoff(test[rb_presses]); -// -// n2rb_timer.expires = (jiffies + RB_DELAY); -// add_timer (&n2rb_timer); -// if (rb_presses < 5) { -// if (rb_presses > 0) -// n2lm_ledoff(rb_presses); -// n2lm_ledon(++rb_presses); -// n2lm_timer_start(rb_presses); -// }; - - nslu2_io_debug((KERN_DEBUG "Reset Exit IRQ=%d Presses= %d Jiffies= %08lx\n", irq, rb_presses, jiffies)); - return IRQ_HANDLED; - + machine_power_off(); + return IRQ_HANDLED; // So we don't get a nobody cared error :-P } //==================================================================================================