26 #include <linux/module.h>
27 #include <linux/stddef.h>
29 #include <linux/types.h>
31 #include <linux/utsname.h>
32 #include <linux/capability.h>
34 #include <linux/netdevice.h>
39 #include <linux/reboot.h>
42 #include <linux/ctype.h>
47 #include <asm/processor.h>
49 #include <asm/param.h>
52 #include <asm/uaccess.h>
61 static unsigned char lastleds;
75 #define DPRINTK(x) printk x
107 #define KITTYHAWK_LCD_CMD F_EXTEND(0xf0190000UL)
108 #define KITTYHAWK_LCD_DATA (KITTYHAWK_LCD_CMD+1)
126 #define LCD_CMD_REG lcd_info.lcd_cmd_reg_addr
127 #define LCD_DATA_REG lcd_info.lcd_data_reg_addr
128 #define LED_DATA_REG lcd_info.lcd_cmd_reg_addr
134 static int start_task(
void)
140 if (lcd_no_led_support)
return 0;
152 static void (*led_func_ptr) (
unsigned char) __read_mostly;
154 #ifdef CONFIG_PROC_FS
155 static int led_proc_show(
struct seq_file *
m,
void *
v)
160 seq_printf(m,
"Heartbeat: %d\n", led_heartbeat);
162 seq_printf(m,
"LAN Rx/Tx: %d\n", led_lanrxtx);
179 static ssize_t led_proc_write(
struct file *file,
const char *
buf,
182 void *
data = PDE(file->
f_path.dentry->d_inode)->data;
189 if (count >=
sizeof(lbuf))
190 count =
sizeof(lbuf)-1;
202 if (d != 0 && d != 1)
goto parse_error;
205 if (*cur++ !=
' ')
goto parse_error;
208 if (d != 0 && d != 1)
goto parse_error;
211 if (*cur++ !=
' ')
goto parse_error;
214 if (d != 0 && d != 1)
goto parse_error;
219 if (*cur && cur[
strlen(cur)-1] ==
'\n')
222 cur = lcd_text_default;
233 printk(
KERN_CRIT "Parse error: expect \"n n n\" (n == 0 or 1) for heartbeat,\ndisk io and lan tx/rx indicators\n");
239 .open = led_proc_open,
243 .write = led_proc_write,
246 static int __init led_create_procfs(
void)
254 if (!proc_pdc_root)
return -1;
256 if (!lcd_no_led_support)
279 #define LED_DATA 0x01
280 #define LED_STROBE 0x02
281 static void led_ASP_driver(
unsigned char leds)
286 for (i = 0; i < 8; i++) {
288 value = (leds & 0x80) >> 7;
301 static void led_LASI_driver(
unsigned char leds)
313 static void led_LCD_driver(
unsigned char leds)
327 unsigned int msec_cmd_delay = 1 + (lcd_info.min_cmd_delay / 1000);
331 if ((leds & mask[i]) != (lastleds & mask[
i]))
336 gsc_writeb( leds & mask[i] ? blockp[i]->
on :
352 static __inline__ int led_get_net_activity(
void)
357 static u64 rx_total_last, tx_total_last;
358 u64 rx_total, tx_total;
362 rx_total = tx_total = 0;
369 struct in_device *in_dev = __in_dev_get_rcu(dev);
370 if (!in_dev || !in_dev->ifa_list)
372 if (ipv4_is_loopback(in_dev->ifa_list->ifa_local))
382 if (rx_total != rx_total_last) {
383 rx_total_last = rx_total;
387 if (tx_total != tx_total_last) {
388 tx_total_last = tx_total;
404 static __inline__ int led_get_diskio_activity(
void)
406 static unsigned long last_pgpgin, last_pgpgout;
410 all_vm_events(events);
414 changed = (events[
PGPGIN] != last_pgpgin) ||
415 (events[
PGPGOUT] != last_pgpgout);
416 last_pgpgin = events[
PGPGIN];
417 last_pgpgout = events[
PGPGOUT];
434 #define HEARTBEAT_LEN (HZ*10/100)
435 #define HEARTBEAT_2ND_RANGE_START (HZ*28/100)
436 #define HEARTBEAT_2ND_RANGE_END (HEARTBEAT_2ND_RANGE_START + HEARTBEAT_LEN)
438 #define LED_UPDATE_INTERVAL (1 + (HZ*19/1000))
442 static unsigned long last_jiffies;
443 static unsigned long count_HZ;
444 unsigned char currentleds = 0;
451 count_HZ +=
jiffies - last_jiffies;
456 if (
likely(led_heartbeat))
467 if (
likely(led_lanrxtx)) currentleds |= led_get_net_activity();
468 if (
likely(led_diskio)) currentleds |= led_get_diskio_activity();
475 currentleds = (count_HZ <= (
HZ/2)) ? 0 : 0xff;
478 if (count_HZ <= (
HZ/2))
485 if (currentleds != lastleds)
487 led_func_ptr(currentleds);
488 lastleds = currentleds;
502 static int led_halt(
struct notifier_block *,
unsigned long,
void *);
505 .notifier_call = led_halt,
507 static int notifier_disabled = 0;
513 if (notifier_disabled)
516 notifier_disabled = 1;
524 default:
return NOTIFY_DONE;
555 if (initialized || !data_reg)
558 lcd_info.model = model;
561 switch (lcd_info.model) {
566 led_func_ptr = led_LCD_driver;
572 led_func_ptr = led_LASI_driver;
579 led_func_ptr = led_ASP_driver;
587 __func__, lcd_info.model);
617 switch (lcd_info.model) {
651 strlcpy(lcd_text, str,
sizeof(lcd_text));
655 udelay(lcd_info.min_cmd_delay);
658 for (i=0; i < lcd_info.lcd_width; i++) {
663 udelay(lcd_info.min_cmd_delay);
671 return lcd_info.lcd_width;
691 snprintf(lcd_text_default,
sizeof(lcd_text_default),
692 "Linux %s", init_utsname()->
release);
703 lcd_no_led_support = 1;
714 "lcd_width=%d, cmd_delay=%u,\n"
715 "%s: sizecnt=%d, actcnt=%ld, maxcnt=%ld\n",
716 __FILE__, lcd_info.model,
719 lcd_info.lcd_width, lcd_info.min_cmd_delay,
720 __FILE__,
sizeof(lcd_info),
722 DPRINTK((
KERN_INFO "%s: cmd=%p, data=%p, reset1=%x, reset2=%x, act_enable=%d\n",
723 __FILE__, lcd_info.lcd_cmd_reg_addr,
724 lcd_info.lcd_data_reg_addr, lcd_info.reset_cmd1,
725 lcd_info.reset_cmd2, lcd_info.act_enable ));
731 switch (lcd_info.model) {
736 if (!lcd_info.act_enable) {
747 if (chassis_info.
actcnt != 8 && chassis_info.
actcnt != 32)
763 DPRINTK((
KERN_INFO "pdc_chassis_info call failed with retval = %d\n", ret));
771 static void __exit led_exit(
void)
777 #ifdef CONFIG_PROC_FS