[parisc-linux-cvs] pa51: print message to LCD at shutdown

Helge Deller deller@gmx.de
Sun, 1 Jul 2001 01:49:35 +0200


Index: Makefile
===================================================================
RCS file: /home/cvs/parisc/linux/Makefile,v
retrieving revision 1.82
diff -u -r1.82 Makefile
--- Makefile	2001/06/29 22:15:40	1.82
+++ Makefile	2001/06/30 23:44:22
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -pa50
+EXTRAVERSION = -pa51
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
Index: arch/parisc/kernel/firmware.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/firmware.c,v
retrieving revision 1.27
diff -u -r1.27 firmware.c
--- firmware.c	2001/05/11 15:39:04	1.27
+++ firmware.c	2001/06/30 23:44:22
@@ -149,10 +149,12 @@
         int retval;
 
         spin_lock_irq(&pdc_lock);
+        memcpy(&pdc_result, chassis_info, sizeof(*chassis_info));
+        memcpy(&pdc_result2, led_info, sizeof(*led_info));
         retval = mem_pdc_call(PDC_CHASSIS, PDC_RETURN_CHASSIS_INFO,
                               __pa(pdc_result), __pa(pdc_result2), len);
-	memcpy(chassis_info, pdc_result, sizeof(*chassis_info));
-	memcpy(led_info, pdc_result2, sizeof(*led_info));
+        memcpy(chassis_info, pdc_result, sizeof(*chassis_info));
+        memcpy(led_info, pdc_result2, sizeof(*led_info));
         spin_unlock_irq(&pdc_lock);
 
         return retval;
Index: arch/parisc/kernel/led.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/led.c,v
retrieving revision 1.19
diff -u -r1.19 led.c
--- led.c	2001/06/29 22:15:41	1.19
+++ led.c	2001/06/30 23:44:22
@@ -2,7 +2,7 @@
  *    Chassis LCD/LED driver for HP-PARISC workstations
  *
  *      (c) Copyright 2000 Red Hat Software
- *      (c) Copyright 2000 Helge Deller <hdeller@redhat.com>
+ *      (c) Copyright 2000-2001 Helge Deller <hdeller@redhat.com>
  *
  *      This program is free software; you can redistribute it and/or modify
  *      it under the terms of the GNU General Public License as published by
@@ -85,8 +85,8 @@
 #define KITTYHAWK_LCD_CMD  (0xfffffffff0190000UL) /* 64bit-ready */
 #define KITTYHAWK_LCD_DATA (KITTYHAWK_LCD_CMD+1)
 
-
-/* lcd_info is pre-initialized to the values needed to program KittyHawk LCD's */
+/* lcd_info is pre-initialized to the values needed to program KittyHawk LCD's 
+ * HP seems to have used Sharp/Hitachi HD44780 LCDs most of the time. */
 static struct pdc_chassis_lcd_info_ret_block
 lcd_info __attribute__((aligned(8))) =
 {
@@ -306,19 +306,9 @@
 	static unsigned char lastleds;
 
 	/* exit, if not initialized */
-	if (!led_func_ptr)
+	if (led_stop || !led_func_ptr)
 	    return;
 
-	/* if the system shuts down update the LED HZ times and exit */
-	if (led_stop) {
-		if (led_stop > HZ)
-			return;
-		led_stop++;
-		lastleds = 0;
-		currentleds = 0xff;
-		goto update;
-	}
-	
 	/* increment the local counters */
 	++count;
 	if (++count_HZ == HZ)
@@ -367,7 +357,6 @@
 	    currentleds &= ~LED_DISK_IO;
 #endif
 
-update:
 	/* update the LCD/LEDs */
 	if (currentleds != lastleds) {
 	    led_func_ptr(currentleds);
@@ -392,11 +381,28 @@
 
 static int led_halt(struct notifier_block *nb, unsigned long event, void *buf) 
 {
-	if ((event != SYS_RESTART) && (event != SYS_HALT) &&
-	    (event != SYS_POWER_OFF))
-		return NOTIFY_DONE;
+	char *txt;
+	
+	switch (event) {
+	case SYS_RESTART:	txt = "SYSTEM RESTART";
+				break;
+	case SYS_HALT:		txt = "SYSTEM HALT";
+				break;
+	case SYS_POWER_OFF:	txt = "SYSTEM POWER OFF";
+				break;
+	default:		return NOTIFY_DONE;
+	}
 	
+	/* stop the LED/LCD interrupt handler */
 	led_stop = 1;
+	mdelay(1 + 999 / HZ);
+
+	if (lcd_info.model == DISPLAY_MODEL_LCD)
+		lcd_print(txt);
+	else
+		if (led_func_ptr)
+			led_func_ptr(0xff); /* turn all LEDs ON */
+	
 	unregister_reboot_notifier(&led_notifier);
 	return NOTIFY_OK;
 }
@@ -422,10 +428,12 @@
 	switch (lcd_info.model) {
 	case DISPLAY_MODEL_LCD:
 		LCD_DATA_REG = data_reg;
-		led_func_ptr = led_LCD_driver;
 		printk(KERN_INFO "LCD display at %p,%p registered\n", 
 			LCD_CMD_REG , LCD_DATA_REG);
+		led_stop = 1;
+		led_func_ptr = led_LCD_driver;
 		lcd_print( "Linux " UTS_RELEASE );
+		led_stop = 0;
 		break;
 
 	case DISPLAY_MODEL_LASI:
@@ -447,7 +455,9 @@
 		return 1;
 	}
 	
-	initialized++; /* mark the LCD/LED driver now as initialized */
+	/* mark the LCD/LED driver now as initialized and 
+	 * register to the reboot notifier chain */
+	initialized++;
 	register_reboot_notifier(&led_notifier);
 	
 	return 0;
@@ -483,19 +493,21 @@
    ** 
    ** lcd_print()
    ** 
-   ** Displays the given string on the LCD-Display of newer machines
-   **
-   ** TODO:
+   ** Displays the given string on the LCD-Display of newer machines.
+   ** lcd_print() ensures to not be interrupted by the interrupt handler
+   ** led_interrupt_func() with usage of the led_stop variable.
    **
-   ** - _NEVER_ execute at the same time as led_LCD_driver() !!!!
-   ** -
  */
 int lcd_print( char *str )
 {
 	int i;
 
-	if (lcd_info.model != DISPLAY_MODEL_LCD || !led_func_ptr)
+	if (!led_func_ptr || lcd_info.model != DISPLAY_MODEL_LCD)
 	    return 0;
+	
+	/* temporarily disable the interrupt handler */
+	led_stop++;
+	mdelay(1 + 999 / HZ);
 
 	/* Set LCD Cursor to 1st character */
 	gsc_writeb(lcd_info.reset_cmd1, LCD_CMD_REG);
@@ -509,6 +521,9 @@
 		gsc_writeb(' ', LCD_DATA_REG);
 	    udelay(lcd_info.min_cmd_delay);
 	}
+	
+	/* re-enable the interrupt handler */
+	led_stop--;
 
 	return lcd_info.lcd_width;
 }
@@ -539,9 +554,6 @@
 		printk(KERN_INFO "%s: KittyHawk-Machine (hversion 0x%x) found, "
 				"LED detection skipped.\n", __FILE__, CPU_HVERSION);
 		goto found;	/* use the preinitialized values of lcd_info */
-
-	default:
-		break;
 	}
 
 	/* initialize the struct, so that we can check for valid return values */
@@ -550,14 +562,19 @@
 
 	if (pdc_chassis_info(&chassis_info, &lcd_info, sizeof(lcd_info)) == PDC_OK) {
 		DPRINTK((KERN_INFO "%s: chassis info: model=%d (%s), "
-			 "lcd_width=%d, cmd_delay=%u, "
-			 "sizecnt=%d, actcnt=%ld, maxcnt=%ld\n",
-		         __FUNCTION__, lcd_info.model, 
+			 "lcd_width=%d, cmd_delay=%u,\n"
+			 "%s: sizecnt=%d, actcnt=%ld, maxcnt=%ld\n",
+		         __FILE__, lcd_info.model,
 			 (lcd_info.model==DISPLAY_MODEL_LCD) ? "LCD" :
-			  (lcd_info.model==DISPLAY_MODEL_LASI) ? "LED" : "unknown",  
+			  (lcd_info.model==DISPLAY_MODEL_LASI) ? "LED" : "unknown",
 			 lcd_info.lcd_width, lcd_info.min_cmd_delay,
-			 sizeof(lcd_info), chassis_info.actcnt, chassis_info.maxcnt));
-
+			 __FILE__, sizeof(lcd_info), 
+			 chassis_info.actcnt, chassis_info.maxcnt));
+		DPRINTK((KERN_INFO "%s: cmd=%p, data=%p, reset1=%x, reset2=%x, act_enable=%d\n",
+			__FILE__, lcd_info.lcd_cmd_reg_addr, 
+			lcd_info.lcd_data_reg_addr, lcd_info.reset_cmd1,  
+			lcd_info.reset_cmd2, lcd_info.act_enable ));
+	
 		/* check the results. Some machines have a buggy PDC */
 		if (chassis_info.actcnt <= 0 || chassis_info.actcnt != chassis_info.maxcnt)
 			goto not_found;
@@ -567,6 +584,10 @@
 			if (chassis_info.actcnt < 
 				offsetof(struct pdc_chassis_lcd_info_ret_block, _pad)-1)
 				goto not_found;
+			if (!lcd_info.act_enable) {
+				DPRINTK((KERN_INFO "PDC prohibited usage of the LCD.\n"));
+				goto not_found;
+			}
 			break;
 
 		case DISPLAY_MODEL_NONE:	/* no LED or LCD available */
@@ -579,7 +600,7 @@
 			break;
 
 		default:
-			printk(KERN_WARNING "Unknown LCD/LED model %d\n",
+			printk(KERN_WARNING "PDC reported unknown LCD/LED model %d\n",
 			       lcd_info.model);
 			goto not_found;
 		} /* switch() */
Index: arch/parisc/kernel/process.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/process.c,v
retrieving revision 1.36
diff -u -r1.36 process.c
--- process.c	2001/04/06 05:10:54	1.36
+++ process.c	2001/06/30 23:44:22
@@ -146,11 +146,6 @@
 }
 
 
-void machine_heartbeat(void)
-{
-}
-
-
 /*
  * Create a kernel thread
  */