Linux下GPIO驅動(四) ----gpio_request();gpio_free();


//gpio_request申請gpio口

int gpio_request(unsigned gpio, const char *label)
{
    struct gpio_desc    *desc;
    struct gpio_chip    *chip;
    int            status = -EINVAL;
    unsigned long        flags;

    spin_lock_irqsave(&gpio_lock, flags); // gpio_lock是自旋鎖,上鎖,保存FLAG在flags變量
    if (!gpio_is_valid(gpio))
        goto done;
    desc = &gpio_desc[gpio];
    chip = desc->chip;
    if (chip == NULL)
        goto done;

    if (!try_module_get(chip->owner)) // 該函數用於增加模塊使用計數;若返回為0,表示調用失敗,希望使用的模塊沒有被加載或正在被卸載中       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) { // 原子操作,將flags的第FLAG_REQUESTED位置1,並返回其原值        
desc_set_label(desc, label ? : "?");
// 如果原來的值是0, 執行desc_set_label, 對desc->chip.label賦值,如果label有定義,直接用定義,比如上面的“temporary”,否則用“?”
status = 0;
} else { status = -EBUSY; module_put(chip->owner); // 該函數用於減少模塊使用計數goto done; } if (chip->request) {// chip->request在linux初始化時是沒有指向的 /* chip->request may sleep */ spin_unlock_irqrestore(&gpio_lock, flags);// 如果chip->request不為0, 解鎖,因為后面調用的chip->request有可能睡眠
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); } } 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);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM