gpio_free() : Release ownership
-----------------------------------------------------------------------------------
int
gpio_request
(unsigned gpio,
const
char
*label)
{
struct
gpio_desc *desc;
struct
gpio_chip *chip;
int
status = -EPROBE_DEFER;
unsigned
long
flags;
spin_lock_irqsave(&gpio_lock, flags);
if
(!gpio_is_valid(gpio)) {
status = -EINVAL;
goto
done;
}
desc = &gpio_desc[gpio];
chip = desc->chip;
if
(chip == NULL)
goto
done;
if
(!try_module_get(chip->owner))
goto
done;
/* NOTE: gpio_request() can be called in early boot,
* before IRQs are enabled, for non-sleeping (SOC) GPIOs.
*/
if
(test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
desc_set_label(desc, label ? :
"?"
);
status = 0;
}
else
{
status = -EBUSY;
module_put(chip->owner);
goto
done;
}
if
(chip->request) {
/* chip->request may sleep */
spin_unlock_irqrestore(&gpio_lock, flags);
status = chip->request(chip, gpio - chip->base);
spin_lock_irqsave(&gpio_lock, flags);
if
(status < 0) {
desc_set_label(desc, NULL);
module_put(chip->owner);
clear_bit(FLAG_REQUESTED, &desc->flags);
goto
done;
}
}
if
(chip->get_direction) {
/* chip->get_direction may sleep */
spin_unlock_irqrestore(&gpio_lock, flags);
gpio_get_direction(gpio);
spin_lock_irqsave(&gpio_lock, flags);
}
done:
if
(status)
pr_debug(
"gpio_request: gpio-%d (%s) status %d\n"
,
gpio, label ? :
"?"
, status);
spin_unlock_irqrestore(&gpio_lock, flags);
return
status;
}
EXPORT_SYMBOL_GPL(gpio_request);
-----------------------------------------------------------------------------------
void gpio_free(unsigned gpio)
{
unsigned long flags;
struct gpio_desc *desc;
struct gpio_chip *chip;
might_sleep();
if (!gpio_is_valid(gpio)) {
WARN_ON(extra_checks);
return;
}
gpio_unexport(gpio);
spin_lock_irqsave(&gpio_lock, flags);
desc = &gpio_desc[gpio];
chip = desc->chip;
if (chip && test_bit(FLAG_REQUESTED, &desc->flags)) {
if (chip->free) {
spin_unlock_irqrestore(&gpio_lock, flags);
might_sleep_if(extra_checks && chip->can_sleep);
chip->free(chip, gpio - chip->base);
spin_lock_irqsave(&gpio_lock, flags);
}
desc_set_label(desc, NULL);
module_put(desc->chip->owner);
clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
clear_bit(FLAG_REQUESTED, &desc->flags);
} else
WARN_ON(extra_checks);
spin_unlock_irqrestore(&gpio_lock, flags);
}
EXPORT_SYMBOL_GPL(gpio_free);
-----------------------------------------------------------------------------------
Refer to:
4. https://chromium.googlesource.com/chromiumos/third_party/kernel-next/+/chromeos-3.18-test/drivers/gpio/gpiolib.c
5. http://www.cnblogs.com/hello2mhb/p/3279322.html
沒有留言:
張貼留言