/*
 *    Chassis LCD/LED driver for HP-PARISC workstations
 *
 *      (c) Copyright 2000 Red Hat Software
 *      (c) Copyright 2000 Helge Deller <hdeller@redhat.com>
 *      (c) Copyright 2001-2005 Helge Deller <deller@gmx.de>
 *      (c) Copyright 2001 Randolph Chung <tausq@debian.org>
 *
 *      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
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 * TODO:
 *	- speed-up calculations with inlined assembler
 *	- interface to write to second row of LCD from /proc (if technically possible)
 *
 * Changes:
 *      - Audit copy_from_user in led_proc_write.
 *                                Daniele Bellucci <bellucda@tiscali.it>
 *	- Switch from using a tasklet to a work queue, so the led_LCD_driver
 *	  	can sleep.
 *	  			  David Pye <dmp@davidmpye.dyndns.org>
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/stddef.h>	/* for offsetof() */
#include <linux/init.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/utsname.h>
#include <linux/capability.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/in.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/reboot.h>
#include <linux/proc_fs.h>
#include <linux/ctype.h>
#include <linux/blkdev.h>
#include <linux/workqueue.h>
#include <linux/rcupdate.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/hardware.h>
#include <asm/param.h>		/* HZ */
#include <asm/led.h>
#include <asm/pdc.h>
#include <asm/uaccess.h>

/* The control of the LEDs and LCDs on PARISC-machines have to be done 
   completely in software. The necessary calculations are done in a work queue
   task which is scheduled regularly, and since the calculations may consume a 
   relatively large amount of CPU time, some of the calculations can be 
   turned off with the following variables (controlled via procfs) */

static int led_type __read_mostly = -1;
static unsigned char lastleds;	/* LED state from most recent update */
static unsigned int led_heartbeat __read_mostly = 1;
static unsigned int led_diskio    __read_mostly = 1;
static unsigned int led_lanrxtx   __read_mostly = 1;
static char lcd_text[32]          __read_mostly;
static char lcd_text_default[32]  __read_mostly;


static struct workqueue_struct *led_wq;
static void led_work_func(void *);
static DECLARE_WORK(led_task, led_work_func, NULL);

#if 0
#define DPRINTK(x)	printk x
#else
#define DPRINTK(x)
#endif

struct lcd_block {
	unsigned char command;	/* stores the command byte      */
	unsigned char on;	/* value for turning LED on     */
	unsigned char off;	/* value for turning LED off    */
};

/* Structure returned by PDC_RETURN_CHASSIS_INFO */
/* NOTE: we use unsigned long:16 two times, since the following member 
   lcd_cmd_reg_addr needs to be 64bit aligned on 64bit PA2.0-machines */
struct pdc_chassis_lcd_info_ret_block {
	unsigned long model:16;		/* DISPLAY_MODEL_XXXX */
	unsigned long lcd_width:16;	/* width of the LCD in chars (DISPLAY_MODEL_LCD only) */
	unsigned long lcd_cmd_reg_addr;	/* ptr to LCD cmd-register & data ptr for LED */
	unsigned long lcd_data_reg_addr; /* ptr to LCD data-register (LCD only) */
	unsigned int min_cmd_delay;	/* delay in uS after cmd-write (LCD only) */
	unsigned char reset_cmd1;	/* command #1 for writing LCD string (LCD only) */
	unsigned char reset_cmd2;	/* command #2 for writing LCD string (LCD only) */
	unsigned char act_enable;	/* 0 = no activity (LCD only) */
	struct lcd_block heartbeat;
	struct lcd_block disk_io;
	struct lcd_block lan_rcv;
	struct lcd_block lan_tx;
	char _pad;
};


/* LCD_CMD and LCD_DATA for KittyHawk machines */
#define KITTYHAWK_LCD_CMD  F_EXTEND(0xf0190000UL) /* 64bit-ready */
#define KITTYHAWK_LCD_DATA (KITTYHAWK_LCD_CMD+1)

/* 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))) __read_mostly =
{
	.model =		DISPLAY_MODEL_LCD,
	.lcd_width =		16,
	.lcd_cmd_reg_addr =	KITTYHAWK_LCD_CMD,
	.lcd_data_reg_addr =	KITTYHAWK_LCD_DATA,
	.min_cmd_delay =	40,
	.reset_cmd1 =		0x80,
	.reset_cmd2 =		0xc0,
};


/* direct access to some of the lcd_info variables */
#define LCD_CMD_REG	lcd_info.lcd_cmd_reg_addr	 
#define LCD_DATA_REG	lcd_info.lcd_data_reg_addr	 
#define LED_DATA_REG	lcd_info.lcd_cmd_reg_addr	/* LASI & ASP only */

#define LED_HASLCD 1
#define LED_NOLCD  0

/* The workqueue must be created at init-time */
static int start_task(void) 
{	
	/* Display the default text now */
	if (led_type == LED_HASLCD) lcd_print( lcd_text_default );

	/* Create the work queue and queue the LED task */
	led_wq = create_singlethread_workqueue("led_wq");	
	queue_work(led_wq, &led_task);

	return 0;
}

device_initcall(start_task);

/* ptr to LCD/LED-specific function */
static void (*led_func_ptr) (unsigned char) __read_mostly;

#ifdef CONFIG_PROC_FS
static int led_proc_read(char *page, char **start, off_t off, int count, 
	int *eof, void *data)
{
	char *out = page;
	int len;

	switch ((long)data)
	{
	case LED_NOLCD:
		out += sprintf(out, "Heartbeat: %d\n", led_heartbeat);
		out += sprintf(out, "Disk IO: %d\n", led_diskio);
		out += sprintf(out, "LAN Rx/Tx: %d\n", led_lanrxtx);
		break;
	case LED_HASLCD:
		out += sprintf(out, "%s\n", lcd_text);
		break;
	default:
		*eof = 1;
		return 0;
	}

	len = out - page - off;
	if (len < count) {
		*eof = 1;
		if (len <= 0) return 0;
	} else {
		len = count;
	}
	*start = page + off;
	return len;
}

static int led_proc_write(struct file *file, const char *buf, 
	unsigned long count, void *data)
{
	char *cur, lbuf[count + 1];
	int d;

	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;

	memset(lbuf, 0, count + 1);

	if (copy_from_user(lbuf, buf, count))
		return -EFAULT;

	cur = lbuf;

	/* skip initial spaces */
	while (*cur && isspace(*cur))
	{
		cur++;
	}

	switch ((long)data)
	{
	case LED_NOLCD:
		d = *cur++ - '0';
		if (d != 0 && d != 1) goto parse_error;
		led_heartbeat = d;

		if (*cur++ != ' ') goto parse_error;

		d = *cur++ - '0';
		if (d != 0 && d != 1) goto parse_error;
		led_diskio = d;

		if (*cur++ != ' ') goto parse_error;

		d = *cur++ - '0';
		if (d != 0 && d != 1) goto parse_error;
		led_lanrxtx = d;

		break;
	case LED_HASLCD:
		if (*cur && cur[strlen(cur)-1] == '\n')
			cur[strlen(cur)-1] = 0;
		if (*cur == 0) 
			cur = lcd_text_default;
		lcd_print(cur);
		break;
	default:
		return 0;
	}
	
	return count;

parse_error:
	if ((long)data == LED_NOLCD)
		printk(KERN_CRIT "Parse error: expect \"n n n\" (n == 0 or 1) for heartbeat,\ndisk io and lan tx/rx indicators\n");
	return -EINVAL;
}

static int __init led_create_procfs(void)
{
	struct proc_dir_entry *proc_pdc_root = NULL;
	struct proc_dir_entry *ent;

	if (led_type == -1) return -1;

	proc_pdc_root = proc_mkdir("pdc", 0);
	if (!proc_pdc_root) return -1;
	proc_pdc_root->owner = THIS_MODULE;
	ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
	if (!ent) return -1;
	ent->nlink = 1;
	ent->data = (void *)LED_NOLCD; /* LED */
	ent->read_proc = led_proc_read;
	ent->write_proc = led_proc_write;
	ent->owner = THIS_MODULE;

	if (led_type == LED_HASLCD)
	{
		ent = create_proc_entry("lcd", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
		if (!ent) return -1;
		ent->nlink = 1;
		ent->data = (void *)LED_HASLCD; /* LCD */
		ent->read_proc = led_proc_read;
		ent->write_proc = led_proc_write;
		ent->owner = THIS_MODULE;
	}

	return 0;
}
#endif

/*
   ** 
   ** led_ASP_driver()
   ** 
 */
#define	LED_DATA	0x01	/* data to shift (0:on 1:off) */
#define	LED_STROBE	0x02	/* strobe to clock data */
static void led_ASP_driver(unsigned char leds)
{
	int i;

	leds = ~leds;
	for (i = 0; i < 8; i++) {
		unsigned char value;
		value = (leds & 0x80) >> 7;
		gsc_writeb( value,		 LED_DATA_REG );
		gsc_writeb( value | LED_STROBE,	 LED_DATA_REG );
		leds <<= 1;
	}
}


/*
   ** 
   ** led_LASI_driver()
   ** 
 */
static void led_LASI_driver(unsigned char leds)
{
	leds = ~leds;
	gsc_writeb( leds, LED_DATA_REG );
}


/*
   ** 
   ** led_LCD_driver()
   **   
 */
static void led_LCD_driver(unsigned char leds)
{
	static int i;
	static unsigned char mask[4] = { LED_HEARTBEAT, LED_DISK_IO,
		LED_LAN_RCV, LED_LAN_TX };
	
	static struct lcd_block * blockp[4] = {
		&lcd_info.heartbeat,
		&lcd_info.disk_io,
		&lcd_info.lan_rcv,
		&lcd_info.lan_tx
	};

	/* Convert min_cmd_delay to milliseconds */
	unsigned int msec_cmd_delay = 1 + (lcd_info.min_cmd_delay / 1000);
	
	for (i=0; i<4; ++i) 
	{
		if ((leds & mask[i]) != (lastleds & mask[i])) 
		{
			gsc_writeb( blockp[i]->command, LCD_CMD_REG );
			msleep(msec_cmd_delay);
			
			gsc_writeb( leds & mask[i] ? blockp[i]->on : 
					blockp[i]->off, LCD_DATA_REG );
			msleep(msec_cmd_delay);
		}
	}
}


/*
   ** 
   ** led_get_net_activity()
   ** 
   ** calculate if there was TX- or RX-throughput on the network interfaces
   ** (analog to dev_get_info() from net/core/dev.c)
   **   
 */
static __inline__ int led_get_net_activity(void)
{ 
#ifndef CONFIG_NET
	return 0;
#else
	static unsigned long rx_total_last, tx_total_last;
	unsigned long rx_total, tx_total;
	struct net_device *dev;
	int retval;

	rx_total = tx_total = 0;
	
	/* we are running as a workqueue task, so locking dev_base 
	 * for reading should be OK */
	read_lock(&dev_base_lock);
	rcu_read_lock();
	for (dev = dev_base; dev; dev = dev->next) {
	    struct net_device_stats *stats;
	    struct in_device *in_dev = __in_dev_get_rcu(dev);
	    if (!in_dev || !in_dev->ifa_list)
		continue;
	    if (LOOPBACK(in_dev->ifa_list->ifa_local))
		continue;
	    if (!dev->get_stats) 
		continue;
	    stats = dev->get_stats(dev);
	    rx_total += stats->rx_packets;
	    tx_total += stats->tx_packets;
	}
	rcu_read_unlock();
	read_unlock(&dev_base_lock);

	retval = 0;

	if (rx_total != rx_total_last) {
		rx_total_last = rx_total;
		retval |= LED_LAN_RCV;
	}

	if (tx_total != tx_total_last) {
		tx_total_last = tx_total;
		retval |= LED_LAN_TX;
	}

	return retval;
#endif
}


/*
   ** 
   ** led_get_diskio_activity()
   ** 
   ** calculate if there was disk-io in the system
   **   
 */
static __inline__ int led_get_diskio_activity(void)
{	
	static unsigned long last_pgpgin, last_pgpgout;
	struct page_state pgstat;
	int changed;

	get_full_page_state(&pgstat); /* get no of sectors in & out */

	/* Just use a very simple calculation here. Do not care about overflow,
	   since we only want to know if there was activity or not. */
	changed = (pgstat.pgpgin != last_pgpgin) || (pgstat.pgpgout != last_pgpgout);
	last_pgpgin  = pgstat.pgpgin;
	last_pgpgout = pgstat.pgpgout;

	return (changed ? LED_DISK_IO : 0);
}



/*
   ** led_work_func()
   ** 
   ** manages when and which chassis LCD/LED gets updated

    TODO:
    - display load average (older machines like 715/64 have 4 "free" LED's for that)
    - optimizations
 */

#define HEARTBEAT_LEN (HZ*10/100)
#define HEARTBEAT_2ND_RANGE_START (HZ*28/100)
#define HEARTBEAT_2ND_RANGE_END   (HEARTBEAT_2ND_RANGE_START + HEARTBEAT_LEN)

#define LED_UPDATE_INTERVAL (1 + (HZ*19/1000))

static void led_work_func (void *unused)
{
	static unsigned long last_jiffies;
	static unsigned long count_HZ; /* counter in range 0..HZ */
	unsigned char currentleds = 0; /* stores current value of the LEDs */

	/* exit if not initialized */
	if (!led_func_ptr)
	    return;

	/* increment the heartbeat timekeeper */
	count_HZ += jiffies - last_jiffies;
	last_jiffies = jiffies;
	if (count_HZ >= HZ)
	    count_HZ = 0;

	if (likely(led_heartbeat))
	{
		/* flash heartbeat-LED like a real heart
		 * (2 x short then a long delay)
		 */
		if (count_HZ < HEARTBEAT_LEN || 
				(count_HZ >= HEARTBEAT_2ND_RANGE_START &&
				count_HZ < HEARTBEAT_2ND_RANGE_END)) 
			currentleds |= LED_HEARTBEAT;
	}

	if (likely(led_lanrxtx))  currentleds |= led_get_net_activity();
	if (likely(led_diskio))   currentleds |= led_get_diskio_activity();

	/* blink all LEDs twice a second if we got an Oops (HPMC) */
	if (unlikely(oops_in_progress)) 
		currentleds = (count_HZ<=(HZ/2)) ? 0 : 0xff;

	if (currentleds != lastleds)
	{
		led_func_ptr(currentleds);	/* Update the LCD/LEDs */
		lastleds = currentleds;
	}

	queue_delayed_work(led_wq, &led_task, LED_UPDATE_INTERVAL);
}

/*
   ** led_halt()
   ** 
   ** called by the reboot notifier chain at shutdown and stops all
   ** LED/LCD activities.
   ** 
 */

static int led_halt(struct notifier_block *, unsigned long, void *);

static struct notifier_block led_notifier = {
	.notifier_call = led_halt,
};
static int notifier_disabled = 0;

static int led_halt(struct notifier_block *nb, unsigned long event, void *buf) 
{
	char *txt;

	if (notifier_disabled)
		return NOTIFY_OK;

	notifier_disabled = 1;
	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;
	}
	
	/* Cancel the work item and delete the queue */
	if (led_wq) {
		cancel_rearming_delayed_workqueue(led_wq, &led_task);
		destroy_workqueue(led_wq);
		led_wq = NULL;
	}
 
	if (lcd_info.model == DISPLAY_MODEL_LCD)
		lcd_print(txt);
	else
		if (led_func_ptr)
			led_func_ptr(0xff); /* turn all LEDs ON */
	
	return NOTIFY_OK;
}

/*
   ** register_led_driver()
   ** 
   ** registers an external LED or LCD for usage by this driver.
   ** currently only LCD-, LASI- and ASP-style LCD/LED's are supported.
   ** 
 */

int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long data_reg)
{
	static int initialized;
	
	if (initialized || !data_reg)
		return 1;
	
	lcd_info.model = model;		/* store the values */
	LCD_CMD_REG = (cmd_reg == LED_CMD_REG_NONE) ? 0 : cmd_reg;

	switch (lcd_info.model) {
	case DISPLAY_MODEL_LCD:
		LCD_DATA_REG = data_reg;
		printk(KERN_INFO "LCD display at %lx,%lx registered\n", 
			LCD_CMD_REG , LCD_DATA_REG);
		led_func_ptr = led_LCD_driver;
		led_type = LED_HASLCD;
		break;

	case DISPLAY_MODEL_LASI:
		LED_DATA_REG = data_reg;
		led_func_ptr = led_LASI_driver;
		printk(KERN_INFO "LED display at %lx registered\n", LED_DATA_REG);
		led_type = LED_NOLCD;
		break;

	case DISPLAY_MODEL_OLD_ASP:
		LED_DATA_REG = data_reg;
		led_func_ptr = led_ASP_driver;
		printk(KERN_INFO "LED (ASP-style) display at %lx registered\n", 
		    LED_DATA_REG);
		led_type = LED_NOLCD;
		break;

	default:
		printk(KERN_ERR "%s: Wrong LCD/LED model %d !\n",
		       __FUNCTION__, lcd_info.model);
		return 1;
	}
	
	/* mark the LCD/LED driver now as initialized and 
	 * register to the reboot notifier chain */
	initialized++;
	register_reboot_notifier(&led_notifier);

	/* Ensure the work is queued */
	if (led_wq) {
		queue_work(led_wq, &led_task);
	}

	return 0;
}

/*
   ** register_led_regions()
   ** 
   ** register_led_regions() registers the LCD/LED regions for /procfs.
   ** At bootup - where the initialisation of the LCD/LED normally happens - 
   ** not all internal structures of request_region() are properly set up,
   ** so that we delay the led-registration until after busdevices_init() 
   ** has been executed.
   **
 */

void __init register_led_regions(void)
{
	switch (lcd_info.model) {
	case DISPLAY_MODEL_LCD:
		request_mem_region((unsigned long)LCD_CMD_REG,  1, "lcd_cmd");
		request_mem_region((unsigned long)LCD_DATA_REG, 1, "lcd_data");
		break;
	case DISPLAY_MODEL_LASI:
	case DISPLAY_MODEL_OLD_ASP:
		request_mem_region((unsigned long)LED_DATA_REG, 1, "led_data");
		break;
	}
}


/*
   ** 
   ** lcd_print()
   ** 
   ** Displays the given string on the LCD-Display of newer machines.
   ** lcd_print() disables/enables the timer-based led work queue to
   ** avoid a race condition while writing the CMD/DATA register pair.
   **
 */
int lcd_print( char *str )
{
	int i;

	if (!led_func_ptr || lcd_info.model != DISPLAY_MODEL_LCD)
	    return 0;
	
	/* temporarily disable the led work task */
	if (led_wq)
		cancel_rearming_delayed_workqueue(led_wq, &led_task);

	/* copy display string to buffer for procfs */
	strlcpy(lcd_text, str, sizeof(lcd_text));

	/* Set LCD Cursor to 1st character */
	gsc_writeb(lcd_info.reset_cmd1, LCD_CMD_REG);
	udelay(lcd_info.min_cmd_delay);

	/* Print the string */
	for (i=0; i < lcd_info.lcd_width; i++) {
	    if (str && *str)
		gsc_writeb(*str++, LCD_DATA_REG);
	    else
		gsc_writeb(' ', LCD_DATA_REG);
	    udelay(lcd_info.min_cmd_delay);
	}
	
	/* re-queue the work */
	if (led_wq) {
		queue_work(led_wq, &led_task);
	}

	return lcd_info.lcd_width;
}

/*
   ** led_init()
   ** 
   ** led_init() is called very early in the bootup-process from setup.c 
   ** and asks the PDC for an usable chassis LCD or LED.
   ** If the PDC doesn't return any info, then the LED
   ** is detected by lasi.c or asp.c and registered with the
   ** above functions lasi_led_init() or asp_led_init().
   ** KittyHawk machines have often a buggy PDC, so that
   ** we explicitly check for those machines here.
 */

int __init led_init(void)
{
	struct pdc_chassis_info chassis_info;
	int ret;

	snprintf(lcd_text_default, sizeof(lcd_text_default),
		"Linux %s", system_utsname.release);

	/* Work around the buggy PDC of KittyHawk-machines */
	switch (CPU_HVERSION) {
	case 0x580:		/* KittyHawk DC2-100 (K100) */
	case 0x581:		/* KittyHawk DC3-120 (K210) */
	case 0x582:		/* KittyHawk DC3 100 (K400) */
	case 0x583:		/* KittyHawk DC3 120 (K410) */
	case 0x58B:		/* KittyHawk DC2 100 (K200) */
		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 */
	}

	/* initialize the struct, so that we can check for valid return values */
	lcd_info.model = DISPLAY_MODEL_NONE;
	chassis_info.actcnt = chassis_info.maxcnt = 0;

	ret = pdc_chassis_info(&chassis_info, &lcd_info, sizeof(lcd_info));
	if (ret == PDC_OK) {
		DPRINTK((KERN_INFO "%s: chassis info: model=%d (%s), "
			 "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.lcd_width, lcd_info.min_cmd_delay,
			 __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;

		switch (lcd_info.model) {
		case DISPLAY_MODEL_LCD:		/* LCD display */
			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 */
			printk(KERN_INFO "PDC reported no LCD or LED.\n");
			goto not_found;

		case DISPLAY_MODEL_LASI:	/* Lasi style 8 bit LED display */
			if (chassis_info.actcnt != 8 && chassis_info.actcnt != 32)
				goto not_found;
			break;

		default:
			printk(KERN_WARNING "PDC reported unknown LCD/LED model %d\n",
			       lcd_info.model);
			goto not_found;
		} /* switch() */

found:
		/* register the LCD/LED driver */
		register_led_driver(lcd_info.model, LCD_CMD_REG, LCD_DATA_REG);
		return 0;

	} else { /* if() */
		DPRINTK((KERN_INFO "pdc_chassis_info call failed with retval = %d\n", ret));
	}

not_found:
	lcd_info.model = DISPLAY_MODEL_NONE;
	return 1;
}

static void __exit led_exit(void)
{
	unregister_reboot_notifier(&led_notifier);
	return;
}

#ifdef CONFIG_PROC_FS
module_init(led_create_procfs)
#endif
