From: Maulik Shah <mkshah@codeaurora.org>
To: bjorn.andersson@linaro.org, maz@kernel.org,
linus.walleij@linaro.org, swboyd@chromium.org,
evgreen@chromium.org, mka@chromium.org
Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
linux-gpio@vger.kernel.org, agross@kernel.org,
tglx@linutronix.de, jason@lakedaemon.net, dianders@chromium.org,
rnayak@codeaurora.org, ilina@codeaurora.org,
lsrao@codeaurora.org, Maulik Shah <mkshah@codeaurora.org>
Subject: [PATCH 1/4] gpio: gpiolib: Allow GPIO IRQs to lazy disable
Date: Fri, 22 May 2020 18:49:26 +0530 [thread overview]
Message-ID: <1590153569-21706-2-git-send-email-mkshah@codeaurora.org> (raw)
In-Reply-To: <1590153569-21706-1-git-send-email-mkshah@codeaurora.org>
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)
Signed-off-by: Maulik Shah <mkshah@codeaurora.org>
---
drivers/gpio/gpiolib.c | 59 +++++++++++++++++++++++++++++----------------
include/linux/gpio/driver.h | 13 ++++++++++
2 files changed, 51 insertions(+), 21 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index eaa0e20..a8fdc74 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2465,33 +2465,38 @@ 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 *chip = irq_data_get_irq_chip_data(d);
+
+ if (chip->irq.irq_mask)
+ chip->irq.irq_mask(d);
+ gpiochip_disable_irq(chip, d->hwirq);
+}
+
+static void gpiochip_irq_unmask(struct irq_data *d)
+{
+ struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+
+ gpiochip_enable_irq(chip, d->hwirq);
+ if (chip->irq.irq_unmask)
+ chip->irq.irq_unmask(d);
+}
+
static void gpiochip_irq_enable(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_enable)
- gc->irq.irq_enable(d);
- else
- gc->irq.chip->irq_unmask(d);
+ gpiochip_enable_irq(chip, d->hwirq);
+ chip->irq.irq_enable(d);
}
static void gpiochip_irq_disable(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- /*
- * Since we override .irq_disable() we need to mimic the
- * behaviour of __irq_disable() in irq/chip.c.
- * First call .irq_disable() if it exists, else mimic the
- * behaviour of mask_irq() which calls .irq_mask() if
- * it exists.
- */
- if (gc->irq.irq_disable)
- gc->irq.irq_disable(d);
- else if (gc->irq.chip->irq_mask)
- gc->irq.chip->irq_mask(d);
- gpiochip_disable_irq(gc, d->hwirq);
+ chip->irq.irq_disable(d);
+ gpiochip_disable_irq(chip, d->hwirq);
}
static void gpiochip_set_irq_hooks(struct gpio_chip *gc)
@@ -2515,10 +2520,22 @@ static void gpiochip_set_irq_hooks(struct gpio_chip *gc)
"detected irqchip that is shared with multiple gpiochips: please fix the driver.\n");
return;
}
- gc->irq.irq_enable = irqchip->irq_enable;
- gc->irq.irq_disable = irqchip->irq_disable;
- irqchip->irq_enable = gpiochip_irq_enable;
- irqchip->irq_disable = gpiochip_irq_disable;
+
+ if (irqchip->irq_disable) {
+ gpiochip->irq.irq_disable = irqchip->irq_disable;
+ irqchip->irq_disable = gpiochip_irq_disable;
+ } else {
+ gpiochip->irq.irq_mask = irqchip->irq_mask;
+ irqchip->irq_mask = gpiochip_irq_mask;
+ }
+
+ if (irqchip->irq_enable) {
+ gpiochip->irq.irq_enable = irqchip->irq_enable;
+ irqchip->irq_enable = gpiochip_irq_enable;
+ } else {
+ gpiochip->irq.irq_unmask = irqchip->irq_unmask;
+ irqchip->irq_unmask = gpiochip_irq_unmask;
+ }
}
/**
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 8c41ae4..c8bcaf3 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -253,6 +253,19 @@ struct gpio_irq_chip {
* Store old irq_chip irq_disable callback
*/
void (*irq_disable)(struct irq_data *data);
+ /**
+ * @irq_unmask:
+ *
+ * Store old irq_chip irq_unmask callback
+ */
+ void (*irq_unmask)(struct irq_data *data);
+
+ /**
+ * @irq_mask:
+ *
+ * Store old irq_chip irq_mask callback
+ */
+ void (*irq_mask)(struct irq_data *data);
};
/**
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
next prev parent reply other threads:[~2020-05-22 13:20 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-22 13:19 [PATCH 0/4] irqchip: qcom: pdc: Introduce irq_set_wake call Maulik Shah
2020-05-22 13:19 ` Maulik Shah [this message]
2020-05-23 9:42 ` [PATCH 1/4] gpio: gpiolib: Allow GPIO IRQs to lazy disable Marc Zyngier
2020-05-23 17:06 ` Maulik Shah
2020-05-23 12:30 ` kbuild test robot
2020-05-23 12:30 ` kbuild test robot
2020-05-22 13:19 ` [PATCH 2/4] pinctrl: qcom: Remove irq_disable callback from msmgpio irqchip Maulik Shah
2020-05-22 13:19 ` [PATCH 3/4] pinctrl: qcom: Add msmgpio irqchip flags Maulik Shah
2020-05-22 13:19 ` [PATCH 4/4] irqchip: qcom-pdc: Introduce irq_set_wake call Maulik Shah
2020-05-25 11:34 ` [PATCH 0/4] irqchip: qcom: pdc: " Linus Walleij
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1590153569-21706-2-git-send-email-mkshah@codeaurora.org \
--to=mkshah@codeaurora.org \
--cc=agross@kernel.org \
--cc=bjorn.andersson@linaro.org \
--cc=dianders@chromium.org \
--cc=evgreen@chromium.org \
--cc=ilina@codeaurora.org \
--cc=jason@lakedaemon.net \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lsrao@codeaurora.org \
--cc=maz@kernel.org \
--cc=mka@chromium.org \
--cc=rnayak@codeaurora.org \
--cc=swboyd@chromium.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.