diff options
Diffstat (limited to 'drivers/gpio/gpiolib.c')
| -rw-r--r-- | drivers/gpio/gpiolib.c | 52 | 
1 files changed, 32 insertions, 20 deletions
| diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index ff0fd655729f..86ef3461ec06 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; @@ -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; @@ -1757,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)  { @@ -1765,16 +1774,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_debug("%s: missing set() or set_debounce() operations\n", +			__func__); +		return -ENOTSUPP; +	} + +	spin_lock_irqsave(&gpio_lock, flags);  	status = gpio_ensure_requested(desc);  	if (status < 0) | 
