[kernel] bug#94: marked as done (Softpower-switch on 712s)

PA-RISC Linux bug Tracking System daniel_frazier@hp.com
Wed, 26 Jun 2002 16:33:03 -0600 (MDT)


X-PA-RISC Linux-PR-Message: closed 94

Your message dated Thu, 27 Jun 2002 00:23:34 +0200
with message-id <200206270023.34963.deller@gmx.de>
and subject line [parisc-linux-cvs] linux deller
has caused the attached bug report to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

dann frazier
(administrator, PA-RISC Linux bugs database)

--------------------------------------
Received: (at submit) by bugs.parisc-linux.org; 26 Mar 2001 09:10:49 +0000
>From maswan@acc.umu.se  Mon Mar 26 02:10:49 2001
Received: from khan.acc.umu.se (khan.acc.umu.se [130.239.18.139])
	by dsl2.external.hp.com (Postfix) with ESMTP id 990B1482A
	for <submit@bugs.parisc-linux.org>; Mon, 26 Mar 2001 02:10:48 -0700 (MST)
Received: from uggla.acc.umu.se (maswan@uggla.acc.umu.se [130.239.18.210])
	by khan.acc.umu.se (8.11.2/8.11.2) with ESMTP id f2Q9AQS05563
	for <submit@bugs.parisc-linux.org>; Mon, 26 Mar 2001 11:10:31 +0200 (MEST)
Date: Mon, 26 Mar 2001 11:10:26 +0200 (MEST)
From: Mattias Wadenstein <maswan@acc.umu.se>
To: <submit@bugs.parisc-linux.org>
Subject: Softpower-switch on 712s
Message-ID: <Pine.GSO.4.33.0103261051560.15002-100000@uggla.acc.umu.se>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII

Package: kernel
Severity: wishlist

This is something that happens easily due to various reasons:

Sending BOOTP requests.... OK
IP-Config: Got BOOTP answer from 130.239.18.162, my address is 130.239.18.169
NET4: Unix domain sockets 1.0/SMP for Linux NETPC 100005/2 on 130.239.18.162
Root-NFS: Server returned error -13 while mounting /tftpboot/130.239.18.169
VFS: Unable to mountpanic: VFS: Unable to mount root fs on 02:00


It would have been pleasant to be able to be able to restart the machine
with less than pulling the plug.

I don't know if this is resonable to implement, but it is a wishlist item.

/Mattias Wadenstein


---------------------------------------
Received: (at 94-done) by bugs.parisc-linux.org; 26 Jun 2002 22:24:00 +0000
>From deller@gmx.de  Wed Jun 26 16:23:59 2002
Received: from mail.gmx.net (mail.gmx.net [213.165.64.20])
	by dsl2.external.hp.com (Postfix) with SMTP id E41B14831
	for <94-done@bugs.parisc-linux.org>; Wed, 26 Jun 2002 16:23:57 -0600 (MDT)
Received: (qmail 22945 invoked by uid 0); 26 Jun 2002 22:23:53 -0000
Received: from pd9e084c5.dip.t-dialin.net (HELO P100.helgenet.de) (217.224.132.197)
  by mail.gmx.net (mp002-rz3) with SMTP; 26 Jun 2002 22:23:53 -0000
From: Helge Deller <deller@gmx.de>
To: parisc-linux-cvs@lists.parisc-linux.org,
	94-done@bugs.parisc-linux.org
Subject: Re: [parisc-linux-cvs] linux deller
Date: Thu, 27 Jun 2002 00:23:34 +0200
User-Agent: KMail/1.4.5
References: <20020626222033.18C5E4831@dsl2.external.hp.com>
In-Reply-To: <20020626222033.18C5E4831@dsl2.external.hp.com>
MIME-Version: 1.0
Content-Type: Multipart/Mixed;
  boundary="Boundary-00=_m7jG9Ny9Z1+7wmF"
Message-Id: <200206270023.34963.deller@gmx.de>


--Boundary-00=_m7jG9Ny9Z1+7wmF
Content-Type: text/plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 8bit
Content-Disposition: inline

On Thursday 27 June 2002 00:20, Helge Deller wrote:
> CVSROOT:	/var/cvs
> Module name:	linux
> Changes by:	deller	02/06/26 16:20:32
>
> Modified files:
> 	.              : Makefile
> 	arch/parisc/kernel: power.c time.c
> 	include/asm-parisc: irq.h
>
> Log message:
> 2.4.18-pa42:
> - fix a long out-standing reboot-bug:
> - added re-enabling of soft-power switch in the panic notifier chain. This
> allows us now to reboot the machine if we got a panic. This never worked
> before and helps to debug kernel-problems without pulling the power cable.
> Closes bug #94 and similiar bug reports.
> - now use tasklets for checking the soft-power switch instead of a function
> pointer - added full License


--Boundary-00=_m7jG9Ny9Z1+7wmF
Content-Type: text/plain;
  charset="iso-8859-1";
  name="diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="diff"

Index: Makefile
===================================================================
RCS file: /var/cvs/linux/Makefile,v
retrieving revision 1.312
diff -u -p -r1.312 Makefile
--- Makefile	2002/06/25 20:53:16	1.312
+++ Makefile	2002/06/26 22:14:59
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 18
-EXTRAVERSION = -pa41
+EXTRAVERSION = -pa42
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
Index: arch/parisc/kernel/power.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/power.c,v
retrieving revision 1.8
diff -u -p -r1.8 power.c
--- arch/parisc/kernel/power.c	2002/04/22 00:04:10	1.8
+++ arch/parisc/kernel/power.c	2002/06/26 22:14:59
@@ -1,28 +1,46 @@
 /*
- *  linux/arch/parisc/kernel/power.c
- *  HP PARISC soft power switch support driver
+ * linux/arch/parisc/kernel/power.c
+ * HP PARISC soft power switch support driver
  *
- *  Copyright (C) 2001-2002 Helge Deller <deller@gmx.de>
+ * Copyright (c) 2001-2002 Helge Deller <deller@gmx.de>
+ * All rights reserved.
  *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *
+ *
  * 
  *  HINT:
  *  Support of the soft power switch button may be enabled or disabled at
  *  runtime through the "/proc/sys/kernel/power" procfs entry.
- *  
- */
+ */ 
 
-/*
- * TODO:
- * - use tasklets instead of calling it from the timer-interrupt function
- * - after a special amount of time just turn the machine off (killing init may have failed!)
- * - ....
- */
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
@@ -64,9 +82,11 @@
 
 static void deferred_poweroff(void *dummy)
 {
-	extern int cad_pid;	/* kernel/sys.c */
-	kill_proc(cad_pid, SIGINT, 1);
-	/* machine_power_off(); */
+	extern int cad_pid;	/* from kernel/sys.c */
+	if (kill_proc(cad_pid, SIGINT, 1)) {
+		/* just in case killing init process failed */
+		machine_power_off();
+	}
 }
 
 /*
@@ -113,6 +133,9 @@ static void process_shutdown(void)
 }
 
 
+/* main power switch tasklet struct (scheduled from time.c) */
+DECLARE_TASKLET_DISABLED(power_tasklet, NULL, 0);
+
 /* soft power switch enabled/disabled */
 #ifdef CONFIG_PROC_FS
 static int pwrsw_enabled = 1;
@@ -120,23 +143,20 @@ static int pwrsw_enabled = 1;
 #define pwrsw_enabled (1)
 #endif
 
-/* soft power switch function ptr */
-void (*check_soft_power)(void);
-
-
 /*
  * On gecko style machines (e.g. 712/xx and 715/xx) 
  * the power switch status is stored in Bit 0 ("the highest bit")
  * of CPU diagnose register 25.
  * 
  */
-static void check_soft_power_gecko(void)
+static void gecko_tasklet_func(unsigned long unused)
 {
 	if (!pwrsw_enabled)
 		return;
 
 	if (__getDIAG(25) & 0x80000000) {
 		/* power switch button not pressed or released again */
+		/* Warning: Some machines do never reset this DIAG flag! */
 		shutdown_timer = 0;
 	} else {
 		process_shutdown();
@@ -150,9 +170,8 @@ static void check_soft_power_gecko(void)
  * real I/O location at soft_power_reg.
  * Bit 31 ("the lowest bit) is the status of the power switch.
  */
-static unsigned long soft_power_reg;
 
-static void check_soft_power_polling(void)
+static void polling_tasklet_func(unsigned long soft_power_reg)
 {
         unsigned long current_status;
 	
@@ -186,6 +205,7 @@ static void powerfail_interrupt(int code
 /* 
  * /proc filesystem support 
  */
+
 #ifdef CONFIG_SYSCTL
 static int power_proc_read(char *page, char **start, off_t off, int count, 
 	int *eof, void *data)
@@ -242,7 +262,7 @@ static struct proc_dir_entry *ent;
 
 static void __init power_create_procfs(void)
 {
-	if (!check_soft_power)
+	if (!power_tasklet.func)
 		return;
 	
 	ent = create_proc_entry(SYSCTL_FILENAME, S_IFREG|S_IRUGO|S_IWUSR, 0);
@@ -266,10 +286,29 @@ static void __exit power_remove_procfs(v
 
 
 
+/* parisc_panic_event() is called by the panic handler.
+ * As soon as a panic occurs, our tasklets above will not be
+ * executed any longer. This function then re-enables the 
+ * soft-power switch and allows the user to switch off the system
+ */
+static int parisc_panic_event(struct notifier_block *this,
+		unsigned long event, void *ptr)
+{
+	/* re-enable the soft-power switch */
+	pdc_soft_power_button(0);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block parisc_panic_block = {
+	notifier_call: parisc_panic_event,
+	priority: INT_MAX,
+};
+
 
 static int __init power_init(void)
 {
 	unsigned long ret;
+	unsigned long soft_power_reg = 0;
 
 #if 0
 	request_irq( IRQ_FROM_REGION(CPU_IRQ_REGION)+2, &powerfail_interrupt,
@@ -281,38 +320,51 @@ static int __init power_init(void)
 	if (ret == PDC_OK)
 		ret = pdc_soft_power_button(1);
 	if (ret != PDC_OK)
-		soft_power_reg = (unsigned long) -1;
+		soft_power_reg = -1UL;
 	
-	switch ((long) soft_power_reg) {
+	switch (soft_power_reg) {
 	case 0:		printk(KERN_INFO "Gecko-style soft power switch enabled.\n");
-			check_soft_power = check_soft_power_gecko;
+			power_tasklet.func = gecko_tasklet_func;
 			break;
 			
-	case -1:	printk(KERN_INFO "Soft power switch support not available.\n");
+	case -1UL:	printk(KERN_INFO "Soft power switch support not available.\n");
 			return -ENODEV;
 	
 	default:	printk(KERN_INFO "Soft power switch enabled, polling @ 0x%08lx.\n",
 				soft_power_reg);
-			check_soft_power = check_soft_power_polling;
+			power_tasklet.data = soft_power_reg;
+			power_tasklet.func = polling_tasklet_func;
 	}
 
+	/* Register a call for panic conditions. */
+	notifier_chain_register(&panic_notifier_list, &parisc_panic_block);
+
 	power_create_procfs();
+	tasklet_enable(&power_tasklet);
 
 	return 0;
 }
 
 static void __exit power_exit(void)
 {
+	if (!power_tasklet.func)
+		return;
+
+	tasklet_disable(&power_tasklet);
+	notifier_chain_unregister(&panic_notifier_list, &parisc_panic_block);
 	power_remove_procfs();
-	check_soft_power = NULL;
+	power_tasklet.func = NULL;
+	pdc_soft_power_button(0);
 }
 
 module_init(power_init);
 module_exit(power_exit);
 
+
 MODULE_AUTHOR("Helge Deller");
 MODULE_DESCRIPTION("Soft power switch driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("Dual BSD/GPL");
+
 
 EXPORT_NO_SYMBOLS;
 
Index: arch/parisc/kernel/time.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/time.c,v
retrieving revision 1.23
diff -u -p -r1.23 time.c
--- arch/parisc/kernel/time.c	2002/05/30 16:18:15	1.23
+++ arch/parisc/kernel/time.c	2002/06/26 22:14:59
@@ -116,8 +116,8 @@ void timer_interrupt(int irq, void *dev_
 #endif
 
 	/* check soft power switch status */
-	if (check_soft_power)
-		check_soft_power();
+	if (cpu == 0 && !atomic_read(&led_tasklet.count))
+		tasklet_schedule(&power_tasklet);
 }
 
 /*** converted from ia64 ***/
Index: include/asm-parisc/irq.h
===================================================================
RCS file: /var/cvs/linux/include/asm-parisc/irq.h,v
retrieving revision 1.21
diff -u -p -r1.21 irq.h
--- include/asm-parisc/irq.h	2001/12/04 02:12:40	1.21
+++ include/asm-parisc/irq.h	2002/06/26 22:14:59
@@ -92,6 +92,6 @@ extern unsigned int txn_alloc_data(int, 
 extern unsigned long txn_alloc_addr(int);
 
 /* soft power switch support (power.c) */
-extern void (*check_soft_power)(void);
+extern struct tasklet_struct power_tasklet;
 
 #endif	/* _ASM_PARISC_IRQ_H */

--Boundary-00=_m7jG9Ny9Z1+7wmF--