summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2020-01-27 12:44:53 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2020-02-10 09:42:43 +0100
commit9fcd7fcd5c6028a77b6339c48a0d90f7f2dd3955 (patch)
tree5074536f670259b80681f45c3c3f7ae37d0d207b /drivers
parent4795bcd85d0a1281609e90b8eb26bef9bd82545f (diff)
downloadbarebox-9fcd7fcd5c6028a77b6339c48a0d90f7f2dd3955.tar.gz
barebox-9fcd7fcd5c6028a77b6339c48a0d90f7f2dd3955.tar.xz
gpiolib: introduce helper functions working on gpio_info structs
gpioinfo_*() assume their gpio_info pointer parameter to be valid and don't ensure the gpio to be requested. This drops several checks for being requested and allows further extensions to work with unrequested gpios. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/gpiolib.c137
1 files changed, 97 insertions, 40 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 6789ffd218..cfa77360b3 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -48,6 +48,11 @@ static struct gpio_info *gpio_to_desc(unsigned gpio)
return NULL;
}
+static unsigned gpioinfo_chip_offset(struct gpio_info *gi)
+{
+ return (gi - gpio_desc) - gi->chip->base;
+}
+
static int gpio_adjust_value(struct gpio_info *gi,
int value)
{
@@ -57,16 +62,10 @@ static int gpio_adjust_value(struct gpio_info *gi,
return !!value ^ gi->active_low;
}
-int gpio_request(unsigned gpio, const char *label)
+static int gpioinfo_request(struct gpio_info *gi, const char *label)
{
- struct gpio_info *gi = gpio_to_desc(gpio);
int ret;
- if (!gi) {
- ret = -ENODEV;
- goto done;
- }
-
if (gi->requested) {
ret = -EBUSY;
goto done;
@@ -75,7 +74,8 @@ int gpio_request(unsigned gpio, const char *label)
ret = 0;
if (gi->chip->ops->request) {
- ret = gi->chip->ops->request(gi->chip, gpio - gi->chip->base);
+ ret = gi->chip->ops->request(gi->chip,
+ gpioinfo_chip_offset(gi));
if (ret)
goto done;
}
@@ -86,8 +86,8 @@ int gpio_request(unsigned gpio, const char *label)
done:
if (ret)
- pr_err("_gpio_request: gpio-%d (%s) status %d\n",
- gpio, label ? : "?", ret);
+ pr_err("_gpio_request: gpio-%ld (%s) status %d\n",
+ gi - gpio_desc, label ? : "?", ret);
return ret;
}
@@ -126,18 +126,26 @@ int gpio_find_by_name(const char *name)
return -ENOENT;
}
-void gpio_free(unsigned gpio)
+int gpio_request(unsigned gpio, const char *label)
{
struct gpio_info *gi = gpio_to_desc(gpio);
- if (!gi)
- return;
+ if (!gi) {
+ pr_err("_gpio_request: gpio-%d (%s) status %d\n",
+ gpio, label ? : "?", -ENODEV);
+ return -ENODEV;
+ }
+
+ return gpioinfo_request(gi, label);
+}
+static void gpioinfo_free(struct gpio_info *gi)
+{
if (!gi->requested)
return;
if (gi->chip->ops->free)
- gi->chip->ops->free(gi->chip, gpio - gi->chip->base);
+ gi->chip->ops->free(gi->chip, gpioinfo_chip_offset(gi));
gi->requested = false;
gi->active_low = false;
@@ -145,6 +153,22 @@ void gpio_free(unsigned gpio)
gi->label = NULL;
}
+void gpio_free(unsigned gpio)
+{
+ struct gpio_info *gi = gpio_to_desc(gpio);
+
+ if (!gi)
+ return;
+
+ gpioinfo_free(gi);
+}
+
+static void gpioinfo_set_value(struct gpio_info *gi, int value)
+{
+ if (gi->chip->ops->set)
+ gi->chip->ops->set(gi->chip, gpioinfo_chip_offset(gi), value);
+}
+
void gpio_set_value(unsigned gpio, int value)
{
struct gpio_info *gi = gpio_to_desc(gpio);
@@ -155,8 +179,7 @@ void gpio_set_value(unsigned gpio, int value)
if (gpio_ensure_requested(gi, gpio))
return;
- if (gi->chip->ops->set)
- gi->chip->ops->set(gi->chip, gpio - gi->chip->base, value);
+ gpioinfo_set_value(gi, value);
}
EXPORT_SYMBOL(gpio_set_value);
@@ -171,6 +194,14 @@ void gpio_set_active(unsigned gpio, bool value)
}
EXPORT_SYMBOL(gpio_set_active);
+static int gpioinfo_get_value(struct gpio_info *gi)
+{
+ if (!gi->chip->ops->get)
+ return -ENOSYS;
+
+ return gi->chip->ops->get(gi->chip, gpioinfo_chip_offset(gi));
+}
+
int gpio_get_value(unsigned gpio)
{
struct gpio_info *gi = gpio_to_desc(gpio);
@@ -183,9 +214,7 @@ int gpio_get_value(unsigned gpio)
if (ret)
return ret;
- if (!gi->chip->ops->get)
- return -ENOSYS;
- return gi->chip->ops->get(gi->chip, gpio - gi->chip->base);
+ return gpioinfo_get_value(gi);
}
EXPORT_SYMBOL(gpio_get_value);
@@ -200,6 +229,15 @@ int gpio_is_active(unsigned gpio)
}
EXPORT_SYMBOL(gpio_is_active);
+static int gpioinfo_direction_output(struct gpio_info *gi, int value)
+{
+ if (!gi->chip->ops->direction_output)
+ return -ENOSYS;
+
+ return gi->chip->ops->direction_output(gi->chip,
+ gpioinfo_chip_offset(gi), value);
+}
+
int gpio_direction_output(unsigned gpio, int value)
{
struct gpio_info *gi = gpio_to_desc(gpio);
@@ -212,13 +250,15 @@ int gpio_direction_output(unsigned gpio, int value)
if (ret)
return ret;
- if (!gi->chip->ops->direction_output)
- return -ENOSYS;
- return gi->chip->ops->direction_output(gi->chip, gpio - gi->chip->base,
- value);
+ return gpioinfo_direction_output(gi, value);
}
EXPORT_SYMBOL(gpio_direction_output);
+static int gpioinfo_direction_active(struct gpio_info *gi, bool value)
+{
+ return gpioinfo_direction_output(gi, gpio_adjust_value(gi, value));
+}
+
int gpio_direction_active(unsigned gpio, bool value)
{
struct gpio_info *gi = gpio_to_desc(gpio);
@@ -226,10 +266,19 @@ int gpio_direction_active(unsigned gpio, bool value)
if (!gi)
return -ENODEV;
- return gpio_direction_output(gpio, gpio_adjust_value(gi, value));
+ return gpioinfo_direction_active(gi, value);
}
EXPORT_SYMBOL(gpio_direction_active);
+static int gpioinfo_direction_input(struct gpio_info *gi)
+{
+ if (!gi->chip->ops->direction_input)
+ return -ENOSYS;
+
+ return gi->chip->ops->direction_input(gi->chip,
+ gpioinfo_chip_offset(gi));
+}
+
int gpio_direction_input(unsigned gpio)
{
struct gpio_info *gi = gpio_to_desc(gpio);
@@ -242,22 +291,14 @@ int gpio_direction_input(unsigned gpio)
if (ret)
return ret;
- if (!gi->chip->ops->direction_input)
- return -ENOSYS;
- return gi->chip->ops->direction_input(gi->chip, gpio - gi->chip->base);
+ return gpioinfo_direction_input(gi);
}
EXPORT_SYMBOL(gpio_direction_input);
-/**
- * gpio_request_one - request a single GPIO with initial configuration
- * @gpio: the GPIO number
- * @flags: GPIO configuration as specified by GPIOF_*
- * @label: a literal description string of this GPIO
- */
-int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
+static int gpioinfo_request_one(struct gpio_info *gi, unsigned long flags,
+ const char *label)
{
int err;
- struct gpio_info *gi = gpio_to_desc(gpio);
/*
* Not all of the flags below are mulit-bit, but, for the sake
@@ -269,24 +310,40 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
const bool init_active = (flags & GPIOF_INIT_ACTIVE) == GPIOF_INIT_ACTIVE;
const bool init_high = (flags & GPIOF_INIT_HIGH) == GPIOF_INIT_HIGH;
- err = gpio_request(gpio, label);
+ err = gpioinfo_request(gi, label);
if (err)
return err;
gi->active_low = active_low;
if (dir_in)
- err = gpio_direction_input(gpio);
+ err = gpioinfo_direction_input(gi);
else if (logical)
- err = gpio_direction_active(gpio, init_active);
+ err = gpioinfo_direction_active(gi, init_active);
else
- err = gpio_direction_output(gpio, init_high);
+ err = gpioinfo_direction_output(gi, init_high);
if (err)
- gpio_free(gpio);
+ gpioinfo_free(gi);
return err;
}
+
+/**
+ * gpio_request_one - request a single GPIO with initial configuration
+ * @gpio: the GPIO number
+ * @flags: GPIO configuration as specified by GPIOF_*
+ * @label: a literal description string of this GPIO
+ */
+int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
+{
+ struct gpio_info *gi = gpio_to_desc(gpio);
+
+ if (!gi)
+ return -ENODEV;
+
+ return gpioinfo_request_one(gi, flags, label);
+}
EXPORT_SYMBOL_GPL(gpio_request_one);
/**