This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

gpio_free() disables gpio value ?

Guru 20755 points

Hello,

We encounter strange behavior with gpio kernel APIs.

I am using gpio output pin as following:

gpio_request(93, "lcd_reset"); // Set up the gpioButton
gpio_direction_output(93, 1);
gpio_set_value(93,1); // Set the button GPIO to be an input
msleep(10);
gpio_set_value(93,0); // Set the button GPIO to be an input
msleep(10);
gpio_set_value(93,1); // Set the button GPIO to be an input
msleep(10);

But if I add gpio_free(93) as last command, then it seems that gpio is disables (not yet validated with scope, but the LCD stops functioning):

gpio_request(93, "lcd_reset"); // Set up the gpioButton
gpio_direction_output(93, 1);
gpio_set_value(93,1); // Set the button GPIO to be an input
msleep(10);
gpio_set_value(93,0); // Set the button GPIO to be an input
msleep(10);
gpio_set_value(93,1); // Set the button GPIO to be an input
msleep(10);
gpio_free(93) 

I'm not sure why. Isn't it supposed to keep it's value ?

This can also explain strange behavior with have with LCD that's get reset.

Seems that on passing from u-boot to Linux gpio (or other modules?) value is changed ?

Is this related to the options of sysc_flag (SYSC_HAS_SOFTRESET |SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS ...)

Thank you!

Ran

  • Hello,

    Look at the gpio controller driver and see at the ops for example in gpio:

    bank->chip.free = omap_gpio_free;

    static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
    {
        struct gpio_bank *bank = gpiochip_get_data(chip);
        unsigned long flags;

        raw_spin_lock_irqsave(&bank->lock, flags);
        bank->mod_usage &= ~(BIT(offset));
        if (!LINE_USED(bank->irq_usage, offset)) {
            omap_set_gpio_direction(bank, offset, 1);
            omap_clear_gpio_debounce(bank, offset);
        }
        omap_disable_gpio_module(bank, offset);
        raw_spin_unlock_irqrestore(&bank->lock, flags);

        /*
         * If this is the last gpio to be freed in the bank,
         * disable the bank module.
         */
        if (!BANK_USED(bank))
            pm_runtime_put(bank->dev);
    }

    So what you need to do is either use the gpio line in kernel until you are using it (call gpio_free during module exit/app exit) or change the controller driver to not to change its direction on gpio_free().

    Cheers,

    --Prabhakar Lad

  • Hi Prabhakar,

    Thank you very much.
    Is there anything which can explain a change in gpio when passing form u-boot to linux ?
    We rather that the gpios and other interfaces won't change their values.

    Thank you,
    Ran
  • Hello,

    Refer to this post e2e.ti.com/.../559951 in where gpio controller is not reset in linux so the gpio will have same values set in by the u-boot.

    Cheers,
    --Prabhakar Lad