Messages in this thread | | | Subject | Re: [PATCH v2 1/4] gpio: gpiolib: Allow GPIO IRQs to lazy disable | From | Maulik Shah <> | Date | Wed, 27 May 2020 16:56:14 +0530 |
| |
Hi,
On 5/27/2020 3:14 PM, Stephen Boyd wrote: > Quoting Maulik Shah (2020-05-23 10:11:10) >> With 'commit 461c1a7d4733 ("gpiolib: override irq_enable/disable")' gpiolib >> overrides irqchip's irq_enable and irq_disable callbacks. If irq_disable >> callback is implemented then genirq takes unlazy path to disable irq. >> >> Underlying irqchip may not want to implement irq_disable callback to lazy >> disable irq when client drivers invokes disable_irq(). By overriding >> irq_disable callback, gpiolib ends up always unlazy disabling IRQ. >> >> Allow gpiolib to lazy disable IRQs by overriding irq_disable callback only >> if irqchip implemented irq_disable. In cases where irq_disable is not >> implemented irq_mask is overridden. Similarly override irq_enable callback >> only if irqchip implemented irq_enable otherwise irq_unmask is overridden. >> >> Fixes: 461c1a7d47 (gpiolib: override irq_enable/disable) > This isn't a proper Fixes line. Should have quotes > > Fixes: 461c1a7d4733 ("gpiolib: override irq_enable/disable") Thanks for pointing this, i will address in next revision. > >> Signed-off-by: Maulik Shah <mkshah@codeaurora.org> >> --- >> drivers/gpio/gpiolib.c | 55 +++++++++++++++++++++++++++++---------------- >> include/linux/gpio/driver.h | 13 +++++++++++ >> 2 files changed, 49 insertions(+), 19 deletions(-) >> >> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c >> index eaa0e20..3810cd0 100644 >> --- a/drivers/gpio/gpiolib.c >> +++ b/drivers/gpio/gpiolib.c >> @@ -2465,32 +2465,37 @@ static void gpiochip_irq_relres(struct irq_data *d) >> gpiochip_relres_irq(gc, d->hwirq); >> } >> >> +static void gpiochip_irq_mask(struct irq_data *d) >> +{ >> + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); >> + >> + if (gc->irq.irq_mask) >> + gc->irq.irq_mask(d); >> + gpiochip_disable_irq(gc, d->hwirq); > How does this work in the lazy case when I want to drive the GPIO? Say I > have a GPIO that is also an interrupt. The code would look like > > struct gpio_desc *gpio = gpiod_get(...) > unsigned int girq = gpiod_to_irq(gpio) > > request_irq(girq, ...); > > disable_irq(girq); > gpiod_direction_output(gpio, 1); > > In the lazy case genirq wouldn't call the mask function until the first > interrupt arrived on the GPIO line. If that never happened then wouldn't > we be blocked in gpiod_direction_output() when the test_bit() sees > FLAG_USED_AS_IRQ? Or do we need irqs to be released before driving > gpios?
The client driver can decide to unlazy disable IRQ with below API...
irq_set_status_flags(girq, IRQ_DISABLE_UNLAZY);
This will immediatly invoke mask function (unlazy disable) from genirq, even though irq_disable is not implemented.
Thanks, Maulik > >> +} >> + >> +static void gpiochip_irq_unmask(struct irq_data *d) >> +{ >> + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); >> + >> + gpiochip_enable_irq(gc, d->hwirq); >> + if (gc->irq.irq_unmask) >> + gc->irq.irq_unmask(d); >> +} >> +
-- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
| |