Message ID | CACRpkdZpRSrt4u_h11ROavVFZDh6OYJ49gJ6eD0y4gGuOxzMYg@mail.gmail.com |
---|---|
State | New |
Headers | show |
On Wed, Jul 6, 2016 at 11:07 AM, Grygorii Strashko <grygorii.strashko@ti.com> wrote: > first of all for slow GPIO controllers (like pcf857x) it might be unsafe to call > .direction_input() from .irq_request_resources() callback because it > will be called in atomic context under raw_spin_lock_irqsave(). > > > __setup_irq > |- raw_spin_lock_irqsave() > |- irq_request_resources() > |- [ __irq_set_trigger() ] > |- [ irq_startup() ] > |- [ __enable_irq() ] > |- raw_spin_unlock_irqrestore() > > [and it can be unsafe for fast GPIO chips also ;( , for example if it's > required to do some kind of PM management actions before accessing HW - most of > drivers expect their GPIOchip callbacks to be called only after gpiochip.request() or > .irq_startup().] > > In my opinion this change breaks orthogonality of IRQchip vs GPIOchip interfaces > because it adds and (what is more important) hides call of GPIOchip callback > from inside IRQchip interface somewhere in the depths of gpiolib framework. > As result, GPIO drivers lose possibility to properly handle GPIO vs IRQ interface's > differences like: locking, slow vs fast, hw specific settings, features of frameworks. > > I propose to revert it, sry, Aw typical, you are right. OK I'll take this patch and it's fixes out of the GPIO tree :( Yours, Linus Walleij -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index 681c93fb9e70..68fb0147caf4 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -221,7 +221,20 @@ static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip, struct gpio_rcar_priv *p = gpiochip_get_data(chip); unsigned long flags; - /* follow steps in the GPIO documentation for + spin_lock_irqsave(&p->lock, flags); + + /* Select Input Mode or Output Mode in INOUTSEL */ + gpio_rcar_modify_bit(p, INOUTSEL, gpio, output); + + spin_unlock_irqrestore(&p->lock, flags); +} + +static int gpio_rcar_request(struct gpio_chip *chip, unsigned offset) +{ + struct gpio_rcar_priv *p = gpiochip_get_data(chip); + + /* + * follow steps in the GPIO documentation for * "Setting General Output Mode" and * "Setting General Input Mode"