summaryrefslogtreecommitdiff
path: root/packages/linux/linux-2.6.18/avr32-gpio-dev.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/linux/linux-2.6.18/avr32-gpio-dev.patch')
-rw-r--r--packages/linux/linux-2.6.18/avr32-gpio-dev.patch548
1 files changed, 0 insertions, 548 deletions
diff --git a/packages/linux/linux-2.6.18/avr32-gpio-dev.patch b/packages/linux/linux-2.6.18/avr32-gpio-dev.patch
deleted file mode 100644
index 43971cf4e6..0000000000
--- a/packages/linux/linux-2.6.18/avr32-gpio-dev.patch
+++ /dev/null
@@ -1,548 +0,0 @@
----
- arch/avr32/mach-at32ap/Kconfig | 8
- arch/avr32/mach-at32ap/pio.c | 499 ++++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 506 insertions(+), 1 deletion(-)
-
-Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c
-===================================================================
---- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/pio.c 2006-11-29 16:22:14.000000000 +0100
-+++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c 2006-11-29 16:29:20.000000000 +0100
-@@ -22,7 +22,7 @@
-
- struct pio_device {
- void __iomem *regs;
-- const struct platform_device *pdev;
-+ struct platform_device *pdev;
- struct clk *clk;
- u32 pinmux_mask;
- u32 gpio_mask;
-@@ -119,6 +119,34 @@ fail:
- dump_stack();
- }
-
-+static unsigned int pio_id(struct pio_device *pio)
-+{
-+ return pio - pio_dev;
-+}
-+
-+static void __enable_gpio(struct pio_device *pio, u32 mask)
-+{
-+ pio_writel(pio, PUER, mask);
-+ pio_writel(pio, ODR, mask);
-+ pio_writel(pio, PER, mask);
-+}
-+
-+static void __disable_gpio(struct pio_device *pio, u32 mask)
-+{
-+ pio_writel(pio, PUER, mask);
-+ pio_writel(pio, ODR, mask);
-+}
-+
-+static void pio_dealloc_mask(struct pio_device *pio, u32 mask)
-+{
-+ u32 old, new;
-+
-+ do {
-+ old = pio->pinmux_mask;
-+ new = old & ~mask;
-+ } while (cmpxchg(&pio->pinmux_mask, old, new) != old);
-+}
-+
- /* GPIO API */
-
- int gpio_request(unsigned int gpio, const char *label)
-@@ -210,6 +238,475 @@ void gpio_set_value(unsigned int gpio, i
- }
- EXPORT_SYMBOL(gpio_set_value);
-
-+#ifdef CONFIG_PIO_DEV
-+#include <linux/configfs.h>
-+#include <linux/cdev.h>
-+#include <linux/uaccess.h>
-+
-+#define GPIO_DEV_MAX 8
-+
-+static struct class *gpio_dev_class;
-+static dev_t gpio_devt;
-+
-+struct gpio_item {
-+ spinlock_t lock;
-+
-+ /* Too bad we don't have committable items... */
-+ int enabled;
-+
-+ struct pio_device *pio;
-+ u32 pin_mask;
-+
-+ int id;
-+ struct class_device *gpio_dev;
-+ struct cdev char_dev;
-+ struct config_item item;
-+};
-+
-+struct gpio_attribute {
-+ struct configfs_attribute attr;
-+ ssize_t (*show)(struct gpio_item *, char *);
-+ ssize_t (*store)(struct gpio_item *, const char *, size_t);
-+};
-+
-+static int gpio_dev_open(struct inode *inode, struct file *file)
-+{
-+ struct gpio_item *gpio = container_of(inode->i_cdev,
-+ struct gpio_item,
-+ char_dev);
-+
-+ config_item_get(&gpio->item);
-+ file->private_data = gpio;
-+ return 0;
-+}
-+
-+static int gpio_dev_release(struct inode *inode, struct file *file)
-+{
-+ struct gpio_item *gpio = file->private_data;
-+
-+ config_item_put(&gpio->item);
-+ return 0;
-+}
-+
-+static ssize_t gpio_dev_read(struct file *file, char __user *buf,
-+ size_t count, loff_t *offset)
-+{
-+ struct gpio_item *gpio = file->private_data;
-+ u32 value;
-+
-+ value = pio_readl(gpio->pio, PDSR) & gpio->pin_mask;
-+
-+ count = min(count, (size_t)4);
-+ if (copy_to_user(buf, &value, count))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t gpio_dev_write(struct file *file, const char __user *buf,
-+ size_t count, loff_t *offset)
-+{
-+ struct gpio_item *gpio = file->private_data;
-+ u32 value = 0;
-+ u32 mask = ~0UL;
-+
-+ count = min(count, (size_t)4);
-+ if (copy_from_user(&value, buf, count))
-+ return -EFAULT;
-+
-+ /* Assuming big endian */
-+ mask <<= (4 - count) * 8;
-+ mask &= gpio->pin_mask;
-+
-+ pio_writel(gpio->pio, CODR, ~value & mask);
-+ pio_writel(gpio->pio, SODR, value & mask);
-+
-+ return count;
-+}
-+
-+static struct file_operations gpio_dev_fops = {
-+ .owner = THIS_MODULE,
-+ .llseek = no_llseek,
-+ .open = gpio_dev_open,
-+ .release = gpio_dev_release,
-+ .read = gpio_dev_read,
-+ .write = gpio_dev_write,
-+};
-+
-+static struct gpio_item *to_gpio_item(struct config_item *item)
-+{
-+ return item ? container_of(item, struct gpio_item, item) : NULL;
-+}
-+
-+static ssize_t gpio_show_gpio_id(struct gpio_item *gpio, char *page)
-+{
-+ if (gpio->pio)
-+ return sprintf(page, "%u\n", pio_id(gpio->pio));
-+ else
-+ return sprintf(page, "-1\n");
-+}
-+
-+static ssize_t gpio_store_gpio_id(struct gpio_item *gpio,
-+ const char *page, size_t count)
-+{
-+ unsigned long id;
-+ char *p = (char *)page;
-+ ssize_t ret = -EINVAL;
-+
-+ id = simple_strtoul(p, &p, 0);
-+ if (!p || (*p && (*p != '\n')))
-+ return -EINVAL;
-+
-+ /* Switching PIO is not allowed when live... */
-+ spin_lock(&gpio->lock);
-+ if (!gpio->enabled) {
-+ ret = -ENXIO;
-+ if ((id < MAX_NR_PIO_DEVICES) && pio_dev[id].regs) {
-+ gpio->pio = &pio_dev[id];
-+ ret = count;
-+ }
-+ }
-+ spin_unlock(&gpio->lock);
-+
-+ return ret;
-+}
-+
-+static ssize_t gpio_show_pin_mask(struct gpio_item *gpio, char *page)
-+{
-+ return sprintf(page, "0x%08x\n", gpio->pin_mask);
-+}
-+
-+static ssize_t gpio_store_pin_mask(struct gpio_item *gpio,
-+ const char *page, size_t count)
-+{
-+ struct pio_device *pio;
-+ u32 old_mask, new_mask;
-+ u32 old, new;
-+ char *p = (char *)page;
-+ ssize_t ret = -EINVAL;
-+
-+ new_mask = simple_strtoul(p, &p, 0);
-+ if (!p || (*p && (*p != '\n')))
-+ return -EINVAL;
-+
-+ /*
-+ * Must have a PIO before we can start allocating pins, but we
-+ * must not be live.
-+ */
-+ spin_lock(&gpio->lock);
-+ pio = gpio->pio;
-+ if (!pio || gpio->enabled)
-+ goto out;
-+
-+ ret = -EBUSY;
-+ old_mask = gpio->pin_mask;
-+ do {
-+ old = pio->pinmux_mask;
-+ if ((old & ~old_mask) & new_mask)
-+ goto out;
-+
-+ new = (old & ~old_mask) | new_mask;
-+ } while (cmpxchg(&pio->pinmux_mask, old, new) != old);
-+
-+ gpio->pin_mask = new_mask;
-+ __disable_gpio(pio, old_mask);
-+ __enable_gpio(pio, new_mask);
-+ ret = count;
-+
-+out:
-+ spin_unlock(&gpio->lock);
-+ return ret;
-+}
-+
-+static ssize_t gpio_show_oe_mask(struct gpio_item *gpio, char *page)
-+{
-+ u32 mask = 0;
-+
-+ spin_lock(&gpio->lock);
-+ if (gpio->pio) {
-+ mask = pio_readl(gpio->pio, OSR);
-+ mask &= gpio->pin_mask;
-+ }
-+ spin_unlock(&gpio->lock);
-+
-+ return sprintf(page, "0x%08x\n", mask);
-+}
-+
-+static ssize_t gpio_store_oe_mask(struct gpio_item *gpio,
-+ const char *page, size_t count)
-+{
-+ u32 mask;
-+ char *p = (char *)page;
-+ ssize_t ret = -EINVAL;
-+
-+ mask = simple_strtoul(p, &p, 0);
-+ if (!p || (*p && (*p != '\n')))
-+ return -EINVAL;
-+
-+ spin_lock(&gpio->lock);
-+ if (gpio->pio) {
-+ mask &= gpio->pin_mask;
-+ pio_writel(gpio->pio, ODR, mask ^ gpio->pin_mask);
-+ pio_writel(gpio->pio, OER, mask);
-+ ret = count;
-+ }
-+ spin_unlock(&gpio->lock);
-+
-+ return ret;
-+}
-+
-+static ssize_t gpio_show_enabled(struct gpio_item *gpio, char *page)
-+{
-+ return sprintf(page, "%d\n", gpio->enabled);
-+}
-+
-+static ssize_t gpio_store_enabled(struct gpio_item *gpio,
-+ const char *page, size_t count)
-+{
-+ char *p = (char *)page;
-+ int enabled;
-+ int ret;
-+
-+ enabled = simple_strtoul(p, &p, 0);
-+ if (!p || (*p && (*p != '\n')))
-+ return -EINVAL;
-+
-+ /* make it a boolean value */
-+ enabled = !!enabled;
-+
-+ if (gpio->enabled == enabled)
-+ /* Already enabled; do nothing. */
-+ return count;
-+
-+ BUG_ON(gpio->id >= GPIO_DEV_MAX);
-+
-+ if (!enabled) {
-+ class_device_unregister(gpio->gpio_dev);
-+ cdev_del(&gpio->char_dev);
-+ }
-+
-+ /* Disallow any updates to gpio_id or pin_mask */
-+ spin_lock(&gpio->lock);
-+ gpio->enabled = enabled;
-+ spin_unlock(&gpio->lock);
-+
-+ if (!enabled)
-+ return count;
-+
-+ cdev_init(&gpio->char_dev, &gpio_dev_fops);
-+ gpio->char_dev.owner = THIS_MODULE;
-+ ret = cdev_add(&gpio->char_dev, MKDEV(MAJOR(gpio_devt), gpio->id), 1);
-+ if (ret < 0)
-+ goto err_cdev_add;
-+ gpio->gpio_dev = class_device_create(gpio_dev_class, NULL,
-+ MKDEV(MAJOR(gpio_devt), gpio->id),
-+ &gpio->pio->pdev->dev,
-+ "gpio%d", gpio->id);
-+ if (IS_ERR(gpio->gpio_dev)) {
-+ printk(KERN_ERR "failed to create gpio%d\n", gpio->id);
-+ ret = PTR_ERR(gpio->gpio_dev);
-+ goto err_class_dev;
-+ }
-+
-+ printk(KERN_INFO "created gpio%d (pio%d/0x%08x) as (%d:%d)\n",
-+ gpio->id, pio_id(gpio->pio), gpio->pin_mask,
-+ MAJOR(gpio->gpio_dev->devt), MINOR(gpio->gpio_dev->devt));
-+
-+ return 0;
-+
-+err_class_dev:
-+ cdev_del(&gpio->char_dev);
-+err_cdev_add:
-+ spin_lock(&gpio->lock);
-+ gpio->enabled = 0;
-+ spin_unlock(&gpio->lock);
-+
-+ return ret;
-+}
-+
-+static struct gpio_attribute gpio_item_attr_gpio_id = {
-+ .attr = {
-+ .ca_owner = THIS_MODULE,
-+ .ca_name = "gpio_id",
-+ .ca_mode = S_IRUGO | S_IWUSR,
-+ },
-+ .show = gpio_show_gpio_id,
-+ .store = gpio_store_gpio_id,
-+};
-+static struct gpio_attribute gpio_item_attr_pin_mask = {
-+ .attr = {
-+ .ca_owner = THIS_MODULE,
-+ .ca_name = "pin_mask",
-+ .ca_mode = S_IRUGO | S_IWUSR,
-+ },
-+ .show = gpio_show_pin_mask,
-+ .store = gpio_store_pin_mask,
-+};
-+static struct gpio_attribute gpio_item_attr_oe_mask = {
-+ .attr = {
-+ .ca_owner = THIS_MODULE,
-+ .ca_name = "oe_mask",
-+ .ca_mode = S_IRUGO | S_IWUSR,
-+ },
-+ .show = gpio_show_oe_mask,
-+ .store = gpio_store_oe_mask,
-+};
-+static struct gpio_attribute gpio_item_attr_enabled = {
-+ .attr = {
-+ .ca_owner = THIS_MODULE,
-+ .ca_name = "enabled",
-+ .ca_mode = S_IRUGO | S_IWUSR,
-+ },
-+ .show = gpio_show_enabled,
-+ .store = gpio_store_enabled,
-+};
-+
-+static struct configfs_attribute *gpio_item_attrs[] = {
-+ &gpio_item_attr_gpio_id.attr,
-+ &gpio_item_attr_pin_mask.attr,
-+ &gpio_item_attr_oe_mask.attr,
-+ &gpio_item_attr_enabled.attr,
-+ NULL,
-+};
-+
-+static ssize_t gpio_show_attr(struct config_item *item,
-+ struct configfs_attribute *attr,
-+ char *page)
-+{
-+ struct gpio_item *gpio_item = to_gpio_item(item);
-+ struct gpio_attribute *gpio_attr
-+ = container_of(attr, struct gpio_attribute, attr);
-+ ssize_t ret = 0;
-+
-+ if (gpio_attr->show)
-+ ret = gpio_attr->show(gpio_item, page);
-+ return ret;
-+}
-+
-+static ssize_t gpio_store_attr(struct config_item *item,
-+ struct configfs_attribute *attr,
-+ const char *page, size_t count)
-+{
-+ struct gpio_item *gpio_item = to_gpio_item(item);
-+ struct gpio_attribute *gpio_attr
-+ = container_of(attr, struct gpio_attribute, attr);
-+ ssize_t ret = -EINVAL;
-+
-+ if (gpio_attr->store)
-+ ret = gpio_attr->store(gpio_item, page, count);
-+ return ret;
-+}
-+
-+static void gpio_release(struct config_item *item)
-+{
-+ kfree(to_gpio_item(item));
-+}
-+
-+static struct configfs_item_operations gpio_item_ops = {
-+ .release = gpio_release,
-+ .show_attribute = gpio_show_attr,
-+ .store_attribute = gpio_store_attr,
-+};
-+
-+static struct config_item_type gpio_item_type = {
-+ .ct_item_ops = &gpio_item_ops,
-+ .ct_attrs = gpio_item_attrs,
-+ .ct_owner = THIS_MODULE,
-+};
-+
-+static struct config_item *gpio_make_item(struct config_group *group,
-+ const char *name)
-+{
-+ static int next_id;
-+ struct gpio_item *gpio;
-+
-+ if (next_id >= GPIO_DEV_MAX)
-+ return NULL;
-+
-+ gpio = kzalloc(sizeof(struct gpio_item), GFP_KERNEL);
-+ if (!gpio)
-+ return NULL;
-+
-+ gpio->id = next_id++;
-+ config_item_init_type_name(&gpio->item, name, &gpio_item_type);
-+ spin_lock_init(&gpio->lock);
-+
-+ return &gpio->item;
-+}
-+
-+static void gpio_drop_item(struct config_group *group,
-+ struct config_item *item)
-+{
-+ struct gpio_item *gpio = to_gpio_item(item);
-+ struct pio_device *pio;
-+
-+ spin_lock(&gpio->lock);
-+ if (gpio->enabled) {
-+ class_device_unregister(gpio->gpio_dev);
-+ cdev_del(&gpio->char_dev);
-+ }
-+
-+ pio = gpio->pio;
-+ if (pio) {
-+ __disable_gpio(pio, gpio->pin_mask);
-+ pio_dealloc_mask(pio, gpio->pin_mask);
-+ gpio->pio = NULL;
-+ }
-+ spin_unlock(&gpio->lock);
-+}
-+
-+static struct configfs_group_operations gpio_group_ops = {
-+ .make_item = gpio_make_item,
-+ .drop_item = gpio_drop_item,
-+};
-+
-+static struct config_item_type gpio_group_type = {
-+ .ct_group_ops = &gpio_group_ops,
-+ .ct_owner = THIS_MODULE,
-+};
-+
-+static struct configfs_subsystem gpio_subsys = {
-+ .su_group = {
-+ .cg_item = {
-+ .ci_namebuf = "gpio",
-+ .ci_type = &gpio_group_type,
-+ },
-+ },
-+};
-+
-+static int __init pio_init_dev(void)
-+{
-+ int err;
-+
-+ gpio_dev_class = class_create(THIS_MODULE, "gpio-dev");
-+ if (IS_ERR(gpio_dev_class)) {
-+ err = PTR_ERR(gpio_dev_class);
-+ goto err_class_create;
-+ }
-+
-+ err = alloc_chrdev_region(&gpio_devt, 0, GPIO_DEV_MAX, "gpio");
-+ if (err < 0)
-+ goto err_alloc_chrdev;
-+
-+ /* Configfs initialization */
-+ config_group_init(&gpio_subsys.su_group);
-+ init_MUTEX(&gpio_subsys.su_sem);
-+ err = configfs_register_subsystem(&gpio_subsys);
-+ if (err)
-+ goto err_register_subsys;
-+
-+ return 0;
-+
-+err_register_subsys:
-+ unregister_chrdev_region(gpio_devt, GPIO_DEV_MAX);
-+err_alloc_chrdev:
-+ class_destroy(gpio_dev_class);
-+err_class_create:
-+ printk(KERN_WARNING "Failed to initialize gpio /dev interface\n");
-+ return err;
-+}
-+late_initcall(pio_init_dev);
-+#endif /* CONFIG_PIO_DEV */
-+
- static int __init pio_probe(struct platform_device *pdev)
- {
- struct pio_device *pio = NULL;
-Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/Kconfig
-===================================================================
---- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/Kconfig 2006-11-29 16:23:31.000000000 +0100
-+++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/Kconfig 2006-11-29 16:24:35.000000000 +0100
-@@ -2,6 +2,14 @@ if PLATFORM_AT32AP
-
- menu "Atmel AVR32 AP options"
-
-+config PIO_DEV
-+ bool "PIO /dev interface"
-+ select CONFIGFS_FS
-+ default y
-+ help
-+ Say `Y' to enable a /dev interface to the Parallel I/O
-+ Controller.
-+
- endmenu
-
- endif