/*
 *    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 led_halt(struct notifier_block *nb, unsigned long event, void *buf) 
{
	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;
	}
	
	/* 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 */
	
	unregister_reboot_notifier(&led_notifier);
	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;
}

#ifdef CONFIG_PROC_FS
module_init(led_create_procfs)
#endif
