zoukankan      html  css  js  c++  java
  • 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);
  • 相关阅读:
    Educational Codeforces Round 20 A. Maximal Binary Matrix(模拟)
    SCU 4440 Rectangle (思维+暴力)
    poj 2799 IP Networks (模拟/水题)
    Uva 10629 Huge Mods (指数循环节)
    FUZ 1759 Super A^B mod C (指数循环节/模板)
    Uva 11149 Power of Matrix (倍增法/模板)
    poj 3863&&Gym
    Codeforces 392C Yet Another Number Sequence (矩阵快速幂+二项式展开)
    Uva 11029 Leading and Trailing (求n^k前3位和后3位)
    Uva 10006 Carmichael Numbers (快速幂)
  • 原文地址:https://www.cnblogs.com/hello2mhb/p/3279322.html
Copyright © 2011-2022 走看看