From: 沈睿汀 Date: Thu, 29 Apr 2010 09:12:25 +0000 (+0000) Subject: update for gpio X-Git-Tag: firefly_0821_release~11586 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=65d56d9355193cddeb91ea2c5cbef040eab66fd0;p=firefly-linux-kernel-4.4.55.git update for gpio --- diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 50de0f5750d8..57f3042cf9d2 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1204,6 +1204,8 @@ int gpio_direction_output(unsigned gpio, int value) spin_lock_irqsave(&gpio_lock, flags); + if (value !=0 && value !=1) + goto fail; if (!gpio_is_valid(gpio)) goto fail; chip = desc->chip; @@ -1248,6 +1250,70 @@ fail: } EXPORT_SYMBOL_GPL(gpio_direction_output); +/* +gpio pull up or pull down +value = 0, normal +value = 1, pull up +value = 2, pull down +*/ +int gpio_pull_updown(unsigned gpio, unsigned value) +{ + unsigned long flags; + struct gpio_chip *chip; + struct gpio_desc *desc = &gpio_desc[gpio]; + int status = -EINVAL; + + spin_lock_irqsave(&gpio_lock, flags); + + if (value >3) + goto fail; + if (!gpio_is_valid(gpio)) + goto fail; + chip = desc->chip; + if (!chip || !chip->get || !chip->pull_updown) + goto fail; + gpio -= chip->base; + if (gpio >= chip->ngpio) + goto fail; + status = gpio_ensure_requested(desc, gpio); + if (status < 0) + goto fail; + + /* now we know the gpio is valid and chip won't vanish */ + + spin_unlock_irqrestore(&gpio_lock, flags); + + might_sleep_if(extra_checks && chip->can_sleep); + + if (status) { + status = chip->request(chip, gpio); + if (status < 0) { + pr_debug("GPIO-%d: chip request fail, %d\n", + chip->base + gpio, status); + /* and it's not available to anyone else ... + * gpio_request() is the fully clean solution. + */ + goto lose; + } + } + if(chip->pull_updown) + { + status = chip->pull_updown(chip, gpio,value); + if (status == 0) + clear_bit(FLAG_IS_OUT, &desc->flags); + } + +lose: + return status; +fail: + spin_unlock_irqrestore(&gpio_lock, flags); + if (status) + pr_debug("%s: gpio-%d status %d\n", + __func__, gpio, status); + return status; +} +EXPORT_SYMBOL_GPL(gpio_pull_updown); + /* I/O calls are only valid after configuration completed; the relevant * "is this a valid GPIO" error checks should already have been done. @@ -1283,7 +1349,9 @@ EXPORT_SYMBOL_GPL(gpio_direction_output); int __gpio_get_value(unsigned gpio) { struct gpio_chip *chip; - + + if (!gpio_is_valid(gpio)) + return -1; chip = gpio_to_chip(gpio); WARN_ON(extra_checks && chip->can_sleep); return chip->get ? chip->get(chip, gpio - chip->base) : 0; @@ -1303,6 +1371,10 @@ void __gpio_set_value(unsigned gpio, int value) { struct gpio_chip *chip; + if(value !=0 && value !=1) + return; + if (!gpio_is_valid(gpio)) + return; chip = gpio_to_chip(gpio); WARN_ON(extra_checks && chip->can_sleep); chip->set(chip, gpio - chip->base, value); @@ -1340,9 +1412,13 @@ EXPORT_SYMBOL_GPL(__gpio_cansleep); int __gpio_to_irq(unsigned gpio) { struct gpio_chip *chip; - + + if (!gpio_is_valid(gpio)) + return -1; + chip = gpio_to_chip(gpio); - return chip->to_irq ? chip->to_irq(chip, gpio - chip->base) : -ENXIO; + + return chip->to_irq ? chip->to_irq(chip, gpio - chip->base) : -1; } EXPORT_SYMBOL_GPL(__gpio_to_irq); diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 66d6106a2067..f68ea6e02b7e 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -89,14 +89,17 @@ struct gpio_chip { unsigned offset, int value); void (*set)(struct gpio_chip *chip, unsigned offset, int value); + + int (*pull_updown)(struct gpio_chip *chip, + unsigned offset, unsigned value); int (*to_irq)(struct gpio_chip *chip, unsigned offset); void (*dbg_show)(struct seq_file *s, struct gpio_chip *chip); - int base; - u16 ngpio; + int base;// GPIOX_Y£¨ÆäÖУ¬X=0/1;Y=A/B/C/D£©µÄµÚÒ»¸öPINµÄÂß¼­Î»Öà + u16 ngpio;//GPIOX_Y£¨ÆäÖУ¬X=0/1;Y=A/B/C/D£©µÄPIN×ÜÊý char **names; unsigned can_sleep:1; unsigned exported:1; @@ -119,7 +122,7 @@ extern void gpio_free(unsigned gpio); extern int gpio_direction_input(unsigned gpio); extern int gpio_direction_output(unsigned gpio, int value); - +extern int gpio_pull_updown(unsigned gpio, unsigned value); extern int gpio_get_value_cansleep(unsigned gpio); extern void gpio_set_value_cansleep(unsigned gpio, int value);