From a3d88c92a1d7ebbe1e956fd9f0f37bc383f2571b Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 19 Jul 2013 16:12:50 +0900 Subject: gpiolib: replace strict_strtol() with kstrtol() The usage of strict_strtol() is not preferred, because strict_strtol() is obsolete. Thus, kstrtol() should be used. Signed-off-by: Jingoo Han Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpio/gpiolib.c') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index ff0fd655729f..d6413b2e0844 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -349,7 +349,7 @@ static ssize_t gpio_value_store(struct device *dev, else { long value; - status = strict_strtol(buf, 0, &value); + status = kstrtol(buf, 0, &value); if (status == 0) { if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) value = !value; @@ -570,7 +570,7 @@ static ssize_t gpio_active_low_store(struct device *dev, } else { long value; - status = strict_strtol(buf, 0, &value); + status = kstrtol(buf, 0, &value); if (status == 0) status = sysfs_set_active_low(desc, dev, value != 0); } @@ -652,7 +652,7 @@ static ssize_t export_store(struct class *class, struct gpio_desc *desc; int status; - status = strict_strtol(buf, 0, &gpio); + status = kstrtol(buf, 0, &gpio); if (status < 0) goto done; @@ -694,7 +694,7 @@ static ssize_t unexport_store(struct class *class, struct gpio_desc *desc; int status; - status = strict_strtol(buf, 0, &gpio); + status = kstrtol(buf, 0, &gpio); if (status < 0) goto done; -- cgit v1.2.3 From be1a4b13089b1e18da83a549d49163ccad3c19ba Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 30 Aug 2013 09:41:45 +0200 Subject: gpio: improve error path in gpiolib At several places the gpiolib will proceed to handle a GPIO descriptor even if it's ->chip member is NULL and no gpiochip is associated. Fix this by checking that both the descriptor cookie *and* the chip pointer are valid. Also bail out earlier with more specific diagnostic messages on missing operations for setting as input/output or debounce. ChangeLog v1->v2: - Also return -EIO on gpiod_set_debounce() with missing operations in the vtable - Fix indentations. Suggested-by: Alexandre Courbot Acked-by: Alexandre Courbot Reviewed-by: Frank Rowand Cc: Tim Bird Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'drivers/gpio/gpiolib.c') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index d6413b2e0844..0cbdddab4ff2 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1398,7 +1398,7 @@ static int gpiod_request(struct gpio_desc *desc, const char *label) int status = -EPROBE_DEFER; unsigned long flags; - if (!desc) { + if (!desc || !desc->chip) { pr_warn("%s: invalid GPIO\n", __func__); return -EINVAL; } @@ -1406,8 +1406,6 @@ static int gpiod_request(struct gpio_desc *desc, const char *label) spin_lock_irqsave(&gpio_lock, flags); chip = desc->chip; - if (chip == NULL) - goto done; if (!try_module_get(chip->owner)) goto done; @@ -1630,16 +1628,20 @@ static int gpiod_direction_input(struct gpio_desc *desc) int status = -EINVAL; int offset; - if (!desc) { + if (!desc || !desc->chip) { pr_warn("%s: invalid GPIO\n", __func__); return -EINVAL; } + chip = desc->chip; + if (!chip->get || !chip->direction_input) { + pr_warn("%s: missing get() or direction_input() operations\n", + __func__); + return -EIO; + } + spin_lock_irqsave(&gpio_lock, flags); - chip = desc->chip; - if (!chip || !chip->get || !chip->direction_input) - goto fail; status = gpio_ensure_requested(desc); if (status < 0) goto fail; @@ -1691,7 +1693,7 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value) int status = -EINVAL; int offset; - if (!desc) { + if (!desc || !desc->chip) { pr_warn("%s: invalid GPIO\n", __func__); return -EINVAL; } @@ -1704,11 +1706,15 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value) if (!value && test_bit(FLAG_OPEN_SOURCE, &desc->flags)) return gpiod_direction_input(desc); + chip = desc->chip; + if (!chip->set || !chip->direction_output) { + pr_warn("%s: missing set() or direction_output() operations\n", + __func__); + return -EIO; + } + spin_lock_irqsave(&gpio_lock, flags); - chip = desc->chip; - if (!chip || !chip->set || !chip->direction_output) - goto fail; status = gpio_ensure_requested(desc); if (status < 0) goto fail; @@ -1765,16 +1771,19 @@ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce) int status = -EINVAL; int offset; - if (!desc) { + if (!desc || !desc->chip) { pr_warn("%s: invalid GPIO\n", __func__); return -EINVAL; } - spin_lock_irqsave(&gpio_lock, flags); - chip = desc->chip; - if (!chip || !chip->set || !chip->set_debounce) - goto fail; + if (!chip->set || !chip->set_debounce) { + pr_warn("%s: missing set() or set_debounce() operations\n", + __func__); + return -EIO; + } + + spin_lock_irqsave(&gpio_lock, flags); status = gpio_ensure_requested(desc); if (status < 0) -- cgit v1.2.3 From 65d876564e989b63b0f769e0e06b9830db97b2d9 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 4 Sep 2013 14:17:08 +0200 Subject: gpio: return -ENOTSUPP if debounce cannot be set It appears some drivers are using gpio_set_debounce() opportunistically, i.e. without knowing whether it works or not. (Example: input/keyboard/gpio_keys.c) to account for this use case, return -ENOTSUPP and do not print any warnings in this case. Took a round over the other gpio_set_debounce() consumers to make sure that none of them are relying on the returned error code to be something specific. Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/gpio/gpiolib.c') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 0cbdddab4ff2..86ef3461ec06 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1763,6 +1763,9 @@ EXPORT_SYMBOL_GPL(gpio_direction_output); * gpio_set_debounce - sets @debounce time for a @gpio * @gpio: the gpio to set debounce time * @debounce: debounce time is microseconds + * + * returns -ENOTSUPP if the controller does not support setting + * debounce. */ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce) { @@ -1778,9 +1781,9 @@ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce) chip = desc->chip; if (!chip->set || !chip->set_debounce) { - pr_warn("%s: missing set() or set_debounce() operations\n", + pr_debug("%s: missing set() or set_debounce() operations\n", __func__); - return -EIO; + return -ENOTSUPP; } spin_lock_irqsave(&gpio_lock, flags); -- cgit v1.2.3