22 * linux/drivers/parisc/power.c
33 * HP PARISC soft power switch support driver
44 *
5- * Copyright (c) 2001-2005 Helge Deller <deller@gmx.de>
5+ * Copyright (c) 2001-2007 Helge Deller <deller@gmx.de>
66 * All rights reserved.
77 *
88 *
2929 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3030 *
3131 *
32- *
3332 * HINT:
3433 * Support of the soft power switch button may be enabled or disabled at
3534 * runtime through the "/proc/sys/kernel/power" procfs entry.
3837#include <linux/module.h>
3938#include <linux/init.h>
4039#include <linux/kernel.h>
41- #include <linux/string.h>
4240#include <linux/notifier.h>
4341#include <linux/reboot.h>
4442#include <linux/sched.h>
45- #include <linux/interrupt.h>
46- #include <linux/workqueue.h>
43+ #include <linux/kthread.h>
4744
4845#include <asm/pdc.h>
4946#include <asm/io.h>
5047#include <asm/led.h>
51- #include <asm/uaccess.h>
5248
49+ #define DRIVER_NAME "powersw"
50+ #define KTHREAD_NAME "kpowerswd"
5351
54- #ifdef DEBUG
55- # define DPRINTK (x ...) printk(x)
56- #else
57- # define DPRINTK (x ...)
58- #endif
59-
60-
61- /* filename in /proc which can be used to enable/disable the power switch */
62- #define SYSCTL_FILENAME "sys/kernel/power"
52+ /* how often should the power button be polled ? */
53+ #define POWERSWITCH_POLL_PER_SEC 2
6354
55+ /* how long does the power button needs to be down until we react ? */
56+ #define POWERSWITCH_DOWN_SEC 2
6457
58+ /* assembly code to access special registers */
59+ /* taken from PCXL ERS page 82 */
6560#define DIAG_CODE (code ) (0x14000000 + ((code)<<5))
6661
67- /* this will go to processor.h or any other place... */
68- /* taken from PCXL ERS page 82 */
6962#define MFCPU_X (rDiagReg , t_ch , t_th , code ) \
7063 (DIAG_CODE(code) + ((rDiagReg)<<21) + ((t_ch)<<16) + ((t_th)<<0) )
7164
7669#define __getDIAG (dr ) ( { \
7770 register unsigned long __res asm("r28");\
7871 __asm__ __volatile__ ( \
79- ".word %1\n nop\n " : "=&r" (__res) : "i" (MFCPU_T(dr,28)) \
72+ ".word %1" : "=&r" (__res) : "i" (MFCPU_T(dr,28) ) \
8073 ); \
8174 __res; \
8275} )
8376
84-
85- static void deferred_poweroff (struct work_struct * unused )
86- {
87- if (kill_cad_pid (SIGINT , 1 )) {
88- /* just in case killing init process failed */
89- machine_power_off ();
90- }
91- }
92-
93- /*
94- * This function gets called from interrupt context.
95- * As it's called within an interrupt, it wouldn't sync if we don't
96- * use schedule_work().
97- */
98-
99- static DECLARE_WORK (poweroff_work , deferred_poweroff ) ;
100-
101- static void poweroff (void )
102- {
103- static int powering_off __read_mostly ;
104-
105- if (powering_off )
106- return ;
107-
108- powering_off ++ ;
109- schedule_work (& poweroff_work );
110- }
111-
112-
113- /* local time-counter for shutdown */
77+ /* local shutdown counter */
11478static int shutdown_timer __read_mostly ;
11579
11680/* check, give feedback and start shutdown after one second */
11781static void process_shutdown (void )
11882{
11983 if (shutdown_timer == 0 )
120- DPRINTK ( KERN_INFO " Shutdown requested...\n" );
84+ printk ( KERN_ALERT KTHREAD_NAME ": Shutdown requested...\n" );
12185
12286 shutdown_timer ++ ;
12387
12488 /* wait until the button was pressed for 1 second */
125- if (shutdown_timer == HZ ) {
126- #if defined (DEBUG ) || defined(CONFIG_CHASSIS_LCD_LED )
127- static char msg [] = "Shutting down..." ;
128- #endif
129- DPRINTK (KERN_INFO "%s\n" , msg );
89+ if (shutdown_timer == (POWERSWITCH_DOWN_SEC * POWERSWITCH_POLL_PER_SEC )) {
90+ static const char msg [] = "Shutting down..." ;
91+ printk (KERN_INFO KTHREAD_NAME ": %s\n" , msg );
13092 lcd_print (msg );
131- poweroff ();
93+
94+ /* send kill signal */
95+ if (kill_cad_pid (SIGINT , 1 )) {
96+ /* just in case killing init process failed */
97+ if (pm_power_off )
98+ pm_power_off ();
99+ }
132100 }
133101}
134102
135103
136- /* main power switch tasklet struct (scheduled from time.c) */
137- DECLARE_TASKLET_DISABLED (power_tasklet , NULL , 0 );
104+ /* main power switch task struct */
105+ static struct task_struct * power_task ;
106+
107+ /* filename in /proc which can be used to enable/disable the power switch */
108+ #define SYSCTL_FILENAME "sys/kernel/power"
138109
139110/* soft power switch enabled/disabled */
140111int pwrsw_enabled __read_mostly = 1 ;
141112
142- /*
143- * On gecko style machines (e.g. 712/xx and 715/xx)
144- * the power switch status is stored in Bit 0 ("the highest bit")
145- * of CPU diagnose register 25.
146- *
147- */
148- static void gecko_tasklet_func (unsigned long unused )
113+ /* main kernel thread worker. It polls the button state */
114+ static int kpowerswd (void * param )
149115{
150- if (unlikely (!pwrsw_enabled ))
151- return ;
152-
153- if (__getDIAG (25 ) & 0x80000000 ) {
154- /* power switch button not pressed or released again */
155- /* Warning: Some machines do never reset this DIAG flag! */
156- shutdown_timer = 0 ;
157- } else {
158- process_shutdown ();
159- }
160- }
161-
116+ __set_current_state (TASK_RUNNING );
117+
118+ do {
119+ int button_not_pressed ;
120+ unsigned long soft_power_reg = (unsigned long ) param ;
121+
122+ schedule_timeout_interruptible (pwrsw_enabled ? HZ : HZ /POWERSWITCH_POLL_PER_SEC );
123+ __set_current_state (TASK_RUNNING );
124+
125+ if (unlikely (!pwrsw_enabled ))
126+ continue ;
127+
128+ if (soft_power_reg ) {
129+ /*
130+ * Non-Gecko-style machines:
131+ * Check the power switch status which is read from the
132+ * real I/O location at soft_power_reg.
133+ * Bit 31 ("the lowest bit) is the status of the power switch.
134+ * This bit is "1" if the button is NOT pressed.
135+ */
136+ button_not_pressed = (gsc_readl (soft_power_reg ) & 0x1 );
137+ } else {
138+ /*
139+ * On gecko style machines (e.g. 712/xx and 715/xx)
140+ * the power switch status is stored in Bit 0 ("the highest bit")
141+ * of CPU diagnose register 25.
142+ * Warning: Some machines never reset the DIAG flag, even if
143+ * the button has been released again.
144+ */
145+ button_not_pressed = (__getDIAG (25 ) & 0x80000000 );
146+ }
147+
148+ if (likely (button_not_pressed )) {
149+ if (unlikely (shutdown_timer && /* avoid writing if not necessary */
150+ shutdown_timer < (POWERSWITCH_DOWN_SEC * POWERSWITCH_POLL_PER_SEC ))) {
151+ shutdown_timer = 0 ;
152+ printk (KERN_INFO KTHREAD_NAME ": Shutdown request aborted.\n" );
153+ }
154+ } else
155+ process_shutdown ();
156+
157+
158+ } while (!kthread_should_stop ());
162159
163-
164- /*
165- * Check the power switch status which is read from the
166- * real I/O location at soft_power_reg.
167- * Bit 31 ("the lowest bit) is the status of the power switch.
168- */
169-
170- static void polling_tasklet_func (unsigned long soft_power_reg )
171- {
172- unsigned long current_status ;
173-
174- if (unlikely (!pwrsw_enabled ))
175- return ;
176-
177- current_status = gsc_readl (soft_power_reg );
178- if (current_status & 0x1 ) {
179- /* power switch button not pressed */
180- shutdown_timer = 0 ;
181- } else {
182- process_shutdown ();
183- }
160+ return 0 ;
184161}
185162
186163
@@ -220,7 +197,7 @@ static struct notifier_block parisc_panic_block = {
220197static int __init power_init (void )
221198{
222199 unsigned long ret ;
223- unsigned long soft_power_reg = 0 ;
200+ unsigned long soft_power_reg ;
224201
225202#if 0
226203 request_irq ( IRQ_FROM_REGION (CPU_IRQ_REGION )+ 2 , & powerfail_interrupt ,
@@ -235,44 +212,44 @@ static int __init power_init(void)
235212 soft_power_reg = -1UL ;
236213
237214 switch (soft_power_reg ) {
238- case 0 : printk (KERN_INFO "Gecko-style soft power switch enabled.\n" );
239- power_tasklet .func = gecko_tasklet_func ;
215+ case 0 : printk (KERN_INFO DRIVER_NAME ": Gecko-style soft power switch enabled.\n" );
240216 break ;
241217
242- case -1UL : printk (KERN_INFO " Soft power switch support not available.\n" );
218+ case -1UL : printk (KERN_INFO DRIVER_NAME ": Soft power switch support not available.\n" );
243219 return - ENODEV ;
244220
245- default : printk (KERN_INFO " Soft power switch enabled, polling @ 0x%08lx.\n" ,
221+ default : printk (KERN_INFO DRIVER_NAME ": Soft power switch at 0x%08lx enabled .\n" ,
246222 soft_power_reg );
247- power_tasklet .data = soft_power_reg ;
248- power_tasklet .func = polling_tasklet_func ;
223+ }
224+
225+ power_task = kthread_run (kpowerswd , (void * )soft_power_reg , KTHREAD_NAME );
226+ if (IS_ERR (power_task )) {
227+ printk (KERN_ERR DRIVER_NAME ": thread creation failed. Driver not loaded.\n" );
228+ pdc_soft_power_button (0 );
229+ return - EIO ;
249230 }
250231
251232 /* Register a call for panic conditions. */
252233 atomic_notifier_chain_register (& panic_notifier_list ,
253234 & parisc_panic_block );
254235
255- tasklet_enable (& power_tasklet );
256-
257236 return 0 ;
258237}
259238
260239static void __exit power_exit (void )
261240{
262- if (!power_tasklet .func )
263- return ;
241+ kthread_stop (power_task );
264242
265- tasklet_disable (& power_tasklet );
266243 atomic_notifier_chain_unregister (& panic_notifier_list ,
267244 & parisc_panic_block );
268- power_tasklet . func = NULL ;
245+
269246 pdc_soft_power_button (0 );
270247}
271248
272- module_init (power_init );
249+ arch_initcall (power_init );
273250module_exit (power_exit );
274251
275252
276- MODULE_AUTHOR ("Helge Deller" );
253+ MODULE_AUTHOR ("Helge Deller <deller@gmx.de> " );
277254MODULE_DESCRIPTION ("Soft power switch driver" );
278255MODULE_LICENSE ("Dual BSD/GPL" );
0 commit comments