summaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2008-12-25 18:17:34 +0900
committerPaul Mundt <lethal@linux-sh.org>2009-01-27 14:49:10 +0900
commit69edbba0021a48fe034849501513930f6175cb5d (patch)
tree51499128883b2e84bce5dcaa78e6e943c37eeb40 /arch/sh/kernel
parent3292094e88ce6b76714dad8ec4b43d7c5c12ada2 (diff)
sh: use gpiolib
This patch updates the SuperH gpio code to make use of gpiolib. The gpiolib callbacks get() and set() are lockless, but we use our own spinlock for the other operations to make sure hardware register bitfield accesses stay atomic. Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/Makefile_322
-rw-r--r--arch/sh/kernel/Makefile_642
-rw-r--r--arch/sh/kernel/gpio.c106
3 files changed, 55 insertions, 55 deletions
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32
index 2e1b86e16ab..7e7d22b5b4c 100644
--- a/arch/sh/kernel/Makefile_32
+++ b/arch/sh/kernel/Makefile_32
@@ -27,7 +27,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
obj-$(CONFIG_KPROBES) += kprobes.o
-obj-$(CONFIG_GENERIC_GPIO) += gpio.o
+obj-$(CONFIG_ARCH_REQUIRE_GPIOLIB) += gpio.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
obj-$(CONFIG_DUMP_CODE) += disassemble.o
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64
index fe425d7f687..cbcbbb6c049 100644
--- a/arch/sh/kernel/Makefile_64
+++ b/arch/sh/kernel/Makefile_64
@@ -15,6 +15,6 @@ obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
-obj-$(CONFIG_GENERIC_GPIO) += gpio.o
+obj-$(CONFIG_ARCH_REQUIRE_GPIOLIB) += gpio.o
EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/gpio.c b/arch/sh/kernel/gpio.c
index 28013567372..d22e5af699f 100644
--- a/arch/sh/kernel/gpio.c
+++ b/arch/sh/kernel/gpio.c
@@ -19,22 +19,6 @@
#include <linux/bitops.h>
#include <linux/gpio.h>
-static struct pinmux_info *registered_gpio;
-
-static struct pinmux_info *gpio_controller(unsigned gpio)
-{
- if (!registered_gpio)
- return NULL;
-
- if (gpio < registered_gpio->first_gpio)
- return NULL;
-
- if (gpio > registered_gpio->last_gpio)
- return NULL;
-
- return registered_gpio;
-}
-
static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
{
if (enum_id < r->begin)
@@ -398,9 +382,14 @@ static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
static DEFINE_SPINLOCK(gpio_lock);
-int __gpio_request(unsigned gpio)
+static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
{
- struct pinmux_info *gpioc = gpio_controller(gpio);
+ return container_of(chip, struct pinmux_info, chip);
+}
+
+static int sh_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct pinmux_info *gpioc = chip_to_pinmux(chip);
struct pinmux_data_reg *dummy;
unsigned long flags;
int i, ret, pinmux_type;
@@ -412,30 +401,30 @@ int __gpio_request(unsigned gpio)
spin_lock_irqsave(&gpio_lock, flags);
- if ((gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
+ if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
goto err_unlock;
/* setup pin function here if no data is associated with pin */
- if (get_data_reg(gpioc, gpio, &dummy, &i) != 0)
+ if (get_data_reg(gpioc, offset, &dummy, &i) != 0)
pinmux_type = PINMUX_TYPE_FUNCTION;
else
pinmux_type = PINMUX_TYPE_GPIO;
if (pinmux_type == PINMUX_TYPE_FUNCTION) {
- if (pinmux_config_gpio(gpioc, gpio,
+ if (pinmux_config_gpio(gpioc, offset,
pinmux_type,
GPIO_CFG_DRYRUN) != 0)
goto err_unlock;
- if (pinmux_config_gpio(gpioc, gpio,
+ if (pinmux_config_gpio(gpioc, offset,
pinmux_type,
GPIO_CFG_REQ) != 0)
BUG();
}
- gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
- gpioc->gpios[gpio].flags |= pinmux_type;
+ gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
+ gpioc->gpios[offset].flags |= pinmux_type;
ret = 0;
err_unlock:
@@ -443,11 +432,10 @@ int __gpio_request(unsigned gpio)
err_out:
return ret;
}
-EXPORT_SYMBOL(__gpio_request);
-void gpio_free(unsigned gpio)
+static void sh_gpio_free(struct gpio_chip *chip, unsigned offset)
{
- struct pinmux_info *gpioc = gpio_controller(gpio);
+ struct pinmux_info *gpioc = chip_to_pinmux(chip);
unsigned long flags;
int pinmux_type;
@@ -456,14 +444,13 @@ void gpio_free(unsigned gpio)
spin_lock_irqsave(&gpio_lock, flags);
- pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
- pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
- gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
- gpioc->gpios[gpio].flags |= PINMUX_TYPE_NONE;
+ pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE;
+ pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE);
+ gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
+ gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE;
spin_unlock_irqrestore(&gpio_lock, flags);
}
-EXPORT_SYMBOL(gpio_free);
static int pinmux_direction(struct pinmux_info *gpioc,
unsigned gpio, int new_pinmux_type)
@@ -507,21 +494,20 @@ static int pinmux_direction(struct pinmux_info *gpioc,
return ret;
}
-int gpio_direction_input(unsigned gpio)
+static int sh_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
- struct pinmux_info *gpioc = gpio_controller(gpio);
+ struct pinmux_info *gpioc = chip_to_pinmux(chip);
unsigned long flags;
int ret;
spin_lock_irqsave(&gpio_lock, flags);
- ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_INPUT);
+ ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
spin_unlock_irqrestore(&gpio_lock, flags);
return ret;
}
-EXPORT_SYMBOL(gpio_direction_input);
-static void __gpio_set_value(struct pinmux_info *gpioc,
+static void sh_gpio_set_value(struct pinmux_info *gpioc,
unsigned gpio, int value)
{
struct pinmux_data_reg *dr = NULL;
@@ -533,22 +519,22 @@ static void __gpio_set_value(struct pinmux_info *gpioc,
gpio_write_bit(dr, bit, value);
}
-int gpio_direction_output(unsigned gpio, int value)
+static int sh_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
{
- struct pinmux_info *gpioc = gpio_controller(gpio);
+ struct pinmux_info *gpioc = chip_to_pinmux(chip);
unsigned long flags;
int ret;
- __gpio_set_value(gpioc, gpio, value);
+ sh_gpio_set_value(gpioc, offset, value);
spin_lock_irqsave(&gpio_lock, flags);
- ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_OUTPUT);
+ ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
spin_unlock_irqrestore(&gpio_lock, flags);
return ret;
}
-EXPORT_SYMBOL(gpio_direction_output);
-static int __gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
+static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
{
struct pinmux_data_reg *dr = NULL;
int bit = 0;
@@ -561,24 +547,38 @@ static int __gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
return gpio_read_reg(dr->reg, dr->reg_width, 1, bit);
}
-int gpio_get_value(unsigned gpio)
+static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
{
- return __gpio_get_value(gpio_controller(gpio), gpio);
+ return sh_gpio_get_value(chip_to_pinmux(chip), offset);
}
-EXPORT_SYMBOL(gpio_get_value);
-void gpio_set_value(unsigned gpio, int value)
+static void sh_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
- __gpio_set_value(gpio_controller(gpio), gpio, value);
+ sh_gpio_set_value(chip_to_pinmux(chip), offset, value);
}
-EXPORT_SYMBOL(gpio_set_value);
int register_pinmux(struct pinmux_info *pip)
{
- registered_gpio = pip;
- setup_data_regs(pip);
- pr_info("pinmux: %s handling gpio %d -> %d\n",
+ struct gpio_chip *chip = &pip->chip;
+
+ pr_info("sh pinmux: %s handling gpio %d -> %d\n",
pip->name, pip->first_gpio, pip->last_gpio);
- return 0;
+ setup_data_regs(pip);
+
+ chip->request = sh_gpio_request;
+ chip->free = sh_gpio_free;
+ chip->direction_input = sh_gpio_direction_input;
+ chip->get = sh_gpio_get;
+ chip->direction_output = sh_gpio_direction_output;
+ chip->set = sh_gpio_set;
+
+ WARN_ON(pip->first_gpio != 0); /* needs testing */
+
+ chip->label = pip->name;
+ chip->owner = THIS_MODULE;
+ chip->base = pip->first_gpio;
+ chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
+
+ return gpiochip_add(chip);
}