* [PATCH][MIPS]: AR7 GPIO
@ 2008-01-12 17:18 Matteo Croce
2008-01-13 12:21 ` Atsushi Nemoto
2008-01-13 12:32 ` Atsushi Nemoto
0 siblings, 2 replies; 3+ messages in thread
From: Matteo Croce @ 2008-01-12 17:18 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: linux-mips, florian, nbd, ejka, nico, ralf, akpm
This new patch caches addresses as suggested by Atsushi Nemoto
Signed-off-by: Matteo Croce <technoboy85@gmail.com>
Signed-off-by: Nicolas Thill <nico@openwrt.org>
Signed-off-by: Florian Fainelli <florian@openwrt.org>
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index ef1ed5d..307b8c8 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -904,6 +904,15 @@ config MWAVE
To compile this driver as a module, choose M here: the
module will be called mwave.
+config AR7_GPIO
+ tristate "TI AR7 GPIO Support"
+ depends on AR7
+ help
+ Give userspace access to the GPIO pins on the Texas Instruments AR7
+ processors.
+
+ If compiled as a module, it will be called ar7_gpio.
+
config SCx200_GPIO
tristate "NatSemi SCx200 GPIO Support"
depends on SCx200
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 07304d5..15b479d 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -89,6 +89,7 @@ obj-$(CONFIG_COBALT_LCD) += lcd.o
obj-$(CONFIG_PPDEV) += ppdev.o
obj-$(CONFIG_NWBUTTON) += nwbutton.o
obj-$(CONFIG_NWFLASH) += nwflash.o
+obj-$(CONFIG_AR7_GPIO) += ar7_gpio.o
obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o
obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o
diff --git a/drivers/char/ar7_gpio.c b/drivers/char/ar7_gpio.c
new file mode 100644
index 0000000..16460cd
--- /dev/null
+++ b/drivers/char/ar7_gpio.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2007 Nicolas Thill <nico@openwrt.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/cdev.h>
+#include <gpio.h>
+
+#define DRVNAME "ar7_gpio"
+#define LONGNAME "TI AR7 GPIOs Driver"
+
+MODULE_AUTHOR("Nicolas Thill <nico@openwrt.org>");
+MODULE_DESCRIPTION(LONGNAME);
+MODULE_LICENSE("GPL");
+
+static int ar7_gpio_major;
+
+static ssize_t ar7_gpio_write(struct file *file, const char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ int pin = iminor(file->f_dentry->d_inode);
+ size_t i;
+
+ for (i = 0; i < len; ++i) {
+ char c;
+ if (get_user(c, buf + i))
+ return -EFAULT;
+ switch (c) {
+ case '0':
+ gpio_set_value(pin, 0);
+ break;
+ case '1':
+ gpio_set_value(pin, 1);
+ break;
+ case 'd':
+ case 'D':
+ ar7_gpio_disable(pin);
+ break;
+ case 'e':
+ case 'E':
+ ar7_gpio_enable(pin);
+ break;
+ case 'i':
+ case 'I':
+ case '<':
+ gpio_direction_input(pin);
+ break;
+ case 'o':
+ case 'O':
+ case '>':
+ gpio_direction_output(pin, 0);
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return len;
+}
+
+static ssize_t ar7_gpio_read(struct file *file, char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ int pin = iminor(file->f_dentry->d_inode);
+ int value;
+
+ value = gpio_get_value(pin);
+ if (put_user(value ? '1' : '0', buf))
+ return -EFAULT;
+
+ return 1;
+}
+
+static int ar7_gpio_open(struct inode *inode, struct file *file)
+{
+ int m = iminor(inode);
+
+ if (m >= AR7_GPIO_MAX)
+ return -EINVAL;
+
+ return nonseekable_open(inode, file);
+}
+
+static int ar7_gpio_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static const struct file_operations ar7_gpio_fops = {
+ .owner = THIS_MODULE,
+ .write = ar7_gpio_write,
+ .read = ar7_gpio_read,
+ .open = ar7_gpio_open,
+ .release = ar7_gpio_release,
+ .llseek = no_llseek,
+};
+
+static struct platform_device *ar7_gpio_device;
+
+static int __init ar7_gpio_init(void)
+{
+ int rc;
+
+ ar7_gpio_device = platform_device_alloc(DRVNAME, -1);
+ if (!ar7_gpio_device)
+ return -ENOMEM;
+
+ rc = platform_device_add(ar7_gpio_device);
+ if (rc < 0)
+ goto out_put;
+
+ rc = register_chrdev(ar7_gpio_major, DRVNAME, &ar7_gpio_fops);
+ if (rc < 0)
+ goto out_put;
+
+ ar7_gpio_major = rc;
+
+ rc = 0;
+
+ goto out;
+
+out_put:
+ platform_device_put(ar7_gpio_device);
+out:
+ return rc;
+}
+
+static void __exit ar7_gpio_exit(void)
+{
+ unregister_chrdev(ar7_gpio_major, DRVNAME);
+ platform_device_unregister(ar7_gpio_device);
+}
+
+module_init(ar7_gpio_init);
+module_exit(ar7_gpio_exit);
diff --git a/include/asm-mips/ar7/gpio.h b/include/asm-mips/ar7/gpio.h
new file mode 100644
index 0000000..cc6f898
--- /dev/null
+++ b/include/asm-mips/ar7/gpio.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007 Florian Fainelli <florian@openwrt.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __AR7_GPIO_H__
+#define __AR7_GPIO_H__
+#include <asm/ar7/ar7.h>
+
+#define AR7_GPIO_MAX 32
+
+extern int gpio_request(unsigned gpio, const char *label);
+extern void gpio_free(unsigned gpio);
+
+/* Common GPIO layer */
+static inline int gpio_get_value(unsigned gpio)
+{
+ static unsigned addr;
+
+ if (!addr) {
+ void __iomem *gpio_in = (void __iomem *)
+ KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_INPUT);
+ addr = readl(gpio_in);
+ }
+
+ return addr & (1 << gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ static void __iomem *gpio_out;
+ unsigned tmp;
+
+ if (!gpio_out)
+ gpio_out = (void __iomem *)
+ KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_OUTPUT);
+
+ tmp = readl(gpio_out) & ~(1 << gpio);
+ if (value)
+ tmp |= 1 << gpio;
+ writel(tmp, gpio_out);
+}
+
+static inline int gpio_direction_input(unsigned gpio)
+{
+ void __iomem *gpio_dir =
+ (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_DIR);
+
+ if (gpio >= AR7_GPIO_MAX)
+ return -EINVAL;
+
+ writel(readl(gpio_dir) | (1 << gpio), gpio_dir);
+
+ return 0;
+}
+
+static inline int gpio_direction_output(unsigned gpio, int value)
+{
+ void __iomem *gpio_dir =
+ (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_DIR);
+
+ if (gpio >= AR7_GPIO_MAX)
+ return -EINVAL;
+
+ gpio_set_value(gpio, value);
+ writel(readl(gpio_dir) & ~(1 << gpio), gpio_dir);
+
+ return 0;
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+ return -EINVAL;
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+ return -EINVAL;
+}
+
+/* Board specific GPIO functions */
+static inline int ar7_gpio_enable(unsigned gpio)
+{
+ void __iomem *gpio_en =
+ (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_ENABLE);
+
+ writel(readl(gpio_en) | (1 << gpio), gpio_en);
+
+ return 0;
+}
+
+static inline int ar7_gpio_disable(unsigned gpio)
+{
+ void __iomem *gpio_en =
+ (void __iomem *)KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_ENABLE);
+
+ writel(readl(gpio_en) & ~(1 << gpio), gpio_en);
+
+ return 0;
+}
+
+#include <asm-generic/gpio.h>
+
+#endif
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH][MIPS]: AR7 GPIO
2008-01-12 17:18 [PATCH][MIPS]: AR7 GPIO Matteo Croce
@ 2008-01-13 12:21 ` Atsushi Nemoto
2008-01-13 12:32 ` Atsushi Nemoto
1 sibling, 0 replies; 3+ messages in thread
From: Atsushi Nemoto @ 2008-01-13 12:21 UTC (permalink / raw)
To: technoboy85; +Cc: linux-mips, florian, nbd, ejka, nico, ralf, akpm
On Sat, 12 Jan 2008 18:18:02 +0100, Matteo Croce <technoboy85@gmail.com> wrote:
> This new patch caches addresses as suggested by Atsushi Nemoto
Well, I cannot remember any suggestion about caches. I just said you
should kill all volatiles.
> +static inline int gpio_get_value(unsigned gpio)
> +{
> + static unsigned addr;
> +
> + if (!addr) {
> + void __iomem *gpio_in = (void __iomem *)
> + KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_INPUT);
> + addr = readl(gpio_in);
> + }
> +
> + return addr & (1 << gpio);
> +}
Anyway, this is absolutely broken. You are caching the GPIO value,
not the address.
---
Atsushi Nemoto
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH][MIPS]: AR7 GPIO
2008-01-12 17:18 [PATCH][MIPS]: AR7 GPIO Matteo Croce
2008-01-13 12:21 ` Atsushi Nemoto
@ 2008-01-13 12:32 ` Atsushi Nemoto
1 sibling, 0 replies; 3+ messages in thread
From: Atsushi Nemoto @ 2008-01-13 12:32 UTC (permalink / raw)
To: technoboy85; +Cc: linux-mips, florian, nbd, ejka, nico, ralf, akpm
On Sat, 12 Jan 2008 18:18:02 +0100, Matteo Croce <technoboy85@gmail.com> wrote:
> +static inline void gpio_set_value(unsigned gpio, int value)
> +{
> + static void __iomem *gpio_out;
> + unsigned tmp;
> +
> + if (!gpio_out)
> + gpio_out = (void __iomem *)
> + KSEG1ADDR(AR7_REGS_GPIO + AR7_GPIO_OUTPUT);
> +
> + tmp = readl(gpio_out) & ~(1 << gpio);
> + if (value)
> + tmp |= 1 << gpio;
> + writel(tmp, gpio_out);
> +}
It seems the compiler can calculate gpio_out value at compile time.
So I think caching it just make the function slower.
---
Atsushi Nemoto
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2008-01-13 12:33 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-12 17:18 [PATCH][MIPS]: AR7 GPIO Matteo Croce
2008-01-13 12:21 ` Atsushi Nemoto
2008-01-13 12:32 ` Atsushi Nemoto
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.