From 7ab34b89649a41b96661ec234ddd7dd6167ab7af Mon Sep 17 00:00:00 2001
From: markus <markus@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Date: Tue, 27 Jan 2009 14:02:38 +0000
Subject: [PATCH] - added some extra flags to read more information - added
 automagic device generation /dev/cs5535_gpioX

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@14220 3c298f89-4303-0410-b956-a3cf2f4a3e73
---
 .../patches-2.6.28/924-cs5535_gpio.patch      | 102 ++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100644 target/linux/generic-2.6/patches-2.6.28/924-cs5535_gpio.patch

diff --git a/target/linux/generic-2.6/patches-2.6.28/924-cs5535_gpio.patch b/target/linux/generic-2.6/patches-2.6.28/924-cs5535_gpio.patch
new file mode 100644
index 000000000..94b9e21c2
--- /dev/null
+++ b/target/linux/generic-2.6/patches-2.6.28/924-cs5535_gpio.patch
@@ -0,0 +1,102 @@
+--- ../../cs5535_gpio.c.orig	2009-01-07 10:16:12.000000000 +0100
++++ linux-2.6.28/drivers/char/cs5535_gpio.c	2009-01-07 10:13:54.000000000 +0100
+@@ -15,6 +15,7 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/cdev.h>
++#include <linux/device.h>
+ #include <linux/ioport.h>
+ #include <linux/pci.h>
+ #include <linux/smp_lock.h>
+@@ -48,6 +49,7 @@
+ MODULE_DEVICE_TABLE(pci, divil_pci);
+ 
+ static struct cdev cs5535_gpio_cdev;
++static struct class *cs5535_gpio_class;
+ 
+ /* reserve 32 entries even though some aren't usable */
+ #define CS5535_GPIO_COUNT	32
+@@ -66,9 +68,14 @@
+ 	{ 0x30, 0x00, '1', '0' },	/* GPIOx_READ_BACK / GPIOx_OUT_VAL */
+ 	{ 0x20, 0x20, 'I', 'i' },	/* GPIOx_IN_EN */
+ 	{ 0x04, 0x04, 'O', 'o' },	/* GPIOx_OUT_EN */
++	{ 0x10, 0x10, 'A', 'a' },	/* GPIOx_OUT_AUX1_SEL */
++	{ 0x14, 0x14, 'B', 'b' },	/* GPIOx_OUT_AUX2_SEL */
+ 	{ 0x08, 0x08, 't', 'T' },	/* GPIOx_OUT_OD_EN */
+ 	{ 0x18, 0x18, 'P', 'p' },	/* GPIOx_OUT_PU_EN */
+ 	{ 0x1c, 0x1c, 'D', 'd' },	/* GPIOx_OUT_PD_EN */
++	{ 0x24, 0x24, 'N', 'n' },	/* GPIOx_IN_INV_EN */
++	{ 0x0c, 0x0c, 'X', 'x' },	/* GPIOx_OUT_INV_EN */
++	{ 0x00, 0x00, 'H', 'L' },	/* GPIOx_OUT_VAL */
+ };
+ 
+ 
+@@ -177,7 +184,7 @@
+ {
+ 	dev_t	dev_id;
+ 	u32	low, hi;
+-	int	retval;
++	int	retval, i;
+ 
+ 	if (pci_dev_present(divil_pci) == 0) {
+ 		printk(KERN_WARNING NAME ": DIVIL not found\n");
+@@ -232,23 +239,54 @@
+ 		major = MAJOR(dev_id);
+ 	}
+ 
+-	if (retval) {
+-		release_region(gpio_base, CS5535_GPIO_SIZE);
+-		return -1;
+-	}
++	if (retval)
++		goto error;
+ 
+ 	printk(KERN_DEBUG NAME ": base=%#x mask=%#lx major=%d\n",
+ 	       gpio_base, mask, major);
+ 
+ 	cdev_init(&cs5535_gpio_cdev, &cs5535_gpio_fops);
+-	cdev_add(&cs5535_gpio_cdev, dev_id, CS5535_GPIO_COUNT);
++	retval = cdev_add(&cs5535_gpio_cdev, dev_id, CS5535_GPIO_COUNT);
++	if (retval) {
++		kobject_put(&cs5535_gpio_cdev.kobj);
++		goto error_region;
++	}
++
++	cs5535_gpio_class = class_create(THIS_MODULE, "cs5535_gpio");
++	if (IS_ERR(cs5535_gpio_class)) {
++		printk(KERN_ERR "Error creating cs5535_gpio class\n");
++		cdev_del(&cs5535_gpio_cdev);
++		retval = PTR_ERR(cs5535_gpio_class);
++		goto error_region;
++	}
++
++	for (i = 0; i < CS5535_GPIO_COUNT; i++) {
++		if (mask & (1<<i)) {
++			device_create(cs5535_gpio_class, NULL, MKDEV(major, i), NULL, "cs5535_gpio%d", i);
++		}
++	}
+ 
+ 	return 0;
++
++error_region:
++	unregister_chrdev_region(dev_id, CS5535_GPIO_COUNT);
++error:
++	release_region(gpio_base, CS5535_GPIO_SIZE);
++	return retval;
+ }
+ 
+ static void __exit cs5535_gpio_cleanup(void)
+ {
+ 	dev_t dev_id = MKDEV(major, 0);
++	int i;
++
++	for (i = 0; i < CS5535_GPIO_COUNT; i++) {
++		if (mask & (1<<i)) {
++			device_destroy(cs5535_gpio_class, MKDEV(major, i));
++		}
++	}
++
++	class_destroy(cs5535_gpio_class);
+ 
+ 	cdev_del(&cs5535_gpio_cdev);
+ 	unregister_chrdev_region(dev_id, CS5535_GPIO_COUNT);
-- 
2.20.1