Fix pbutton to signal init, so it shuts down safely (Requires upgraded sysvinit)
authorOyvind Repvik <nail@nslu2-linux.org>
Fri, 12 Aug 2005 06:03:19 +0000 (06:03 +0000)
committerOpenEmbedded Project <openembedded-devel@lists.openembedded.org>
Fri, 12 Aug 2005 06:03:19 +0000 (06:03 +0000)
Fix rbutton to do machine_power_off(), since reset if unreliable.

packages/linux/nslu2-kernel/2.6/nslu2-io_rpbutton.patch [new file with mode: 0644]
packages/linux/nslu2-kernel_2.6.12.2.bb

diff --git a/packages/linux/nslu2-kernel/2.6/nslu2-io_rpbutton.patch b/packages/linux/nslu2-kernel/2.6/nslu2-io_rpbutton.patch
new file mode 100644 (file)
index 0000000..b5ce101
--- /dev/null
@@ -0,0 +1,139 @@
+--- 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
+ }
+ //==================================================================================================
index 177fa8c..a536e86 100644 (file)
@@ -1,5 +1,5 @@
 # Kernel for NSLU2
-PR = "r8"
+PR = "r9"
 include nslu2-kernel.inc
 
 # N2K_EXTRA_PATCHES - list of patches to apply (can include
@@ -23,4 +23,5 @@ N2K_PATCHES = "\
        file://mtd-shutdown.patch;patch=1 \
        file://missing-exports.patch;patch=1 \
        file://timer.patch;patch=1 \
+       file://nslu2-io_rpbutton.patch;patch=1 \
 "