转载地址:http://www.cnblogs.com/hello2mhb/p/3279322.html
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);
Logo

更多推荐