All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marc Zyngier <maz@kernel.org>
To: Maulik Shah <mkshah@codeaurora.org>
Cc: tglx@linutronix.de, linux-kernel@vger.kernel.org,
	linux-arm-msm@vger.kernel.org, linux-gpio@vger.kernel.org,
	bjorn.andersson@linaro.org, linus.walleij@linaro.org,
	tkjos@google.com, lsrao@codeaurora.org
Subject: Re: [PATCH v2 3/3] irqchip/qcom-pdc: Start getting rid of the GPIO_NO_WAKE_IRQ
Date: Fri, 20 Aug 2021 16:38:51 +0100	[thread overview]
Message-ID: <87k0kgqg6s.wl-maz@kernel.org> (raw)
In-Reply-To: <1629373993-13370-4-git-send-email-mkshah@codeaurora.org>

On Thu, 19 Aug 2021 12:53:13 +0100,
Maulik Shah <mkshah@codeaurora.org> wrote:
> 
> From: Marc Zyngier <maz@kernel.org>
> 
> gpio_to_irq() reports error at irq_domain_trim_hierarchy() for non
> wakeup capable GPIOs that do not have dedicated interrupt at GIC.
> 
> Since PDC irqchip do not allocate irq at parent GIC domain for such
> GPIOs indicate same by using irq_domain_disconnect_hierarchy() for
> PDC and parent GIC domains.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> Signed-off-by: Maulik Shah <mkshah@codeaurora.org>
> [mkshah: Add loop to disconnect for all parents]
> Tested-by: Maulik Shah <mkshah@codeaurora.org>
> ---
>  drivers/irqchip/qcom-pdc.c | 75 +++++++++++-----------------------------------
>  1 file changed, 18 insertions(+), 57 deletions(-)
> 
> diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c
> index 32d5920..696afca 100644
> --- a/drivers/irqchip/qcom-pdc.c
> +++ b/drivers/irqchip/qcom-pdc.c
> @@ -53,26 +53,6 @@ static u32 pdc_reg_read(int reg, u32 i)
>  	return readl_relaxed(pdc_base + reg + i * sizeof(u32));
>  }
>  
> -static int qcom_pdc_gic_get_irqchip_state(struct irq_data *d,
> -					  enum irqchip_irq_state which,
> -					  bool *state)
> -{
> -	if (d->hwirq == GPIO_NO_WAKE_IRQ)
> -		return 0;
> -
> -	return irq_chip_get_parent_state(d, which, state);
> -}
> -
> -static int qcom_pdc_gic_set_irqchip_state(struct irq_data *d,
> -					  enum irqchip_irq_state which,
> -					  bool value)
> -{
> -	if (d->hwirq == GPIO_NO_WAKE_IRQ)
> -		return 0;
> -
> -	return irq_chip_set_parent_state(d, which, value);
> -}
> -
>  static void pdc_enable_intr(struct irq_data *d, bool on)
>  {
>  	int pin_out = d->hwirq;
> @@ -91,38 +71,16 @@ static void pdc_enable_intr(struct irq_data *d, bool on)
>  
>  static void qcom_pdc_gic_disable(struct irq_data *d)
>  {
> -	if (d->hwirq == GPIO_NO_WAKE_IRQ)
> -		return;
> -
>  	pdc_enable_intr(d, false);
>  	irq_chip_disable_parent(d);
>  }
>  
>  static void qcom_pdc_gic_enable(struct irq_data *d)
>  {
> -	if (d->hwirq == GPIO_NO_WAKE_IRQ)
> -		return;
> -
>  	pdc_enable_intr(d, true);
>  	irq_chip_enable_parent(d);
>  }
>  
> -static void qcom_pdc_gic_mask(struct irq_data *d)
> -{
> -	if (d->hwirq == GPIO_NO_WAKE_IRQ)
> -		return;
> -
> -	irq_chip_mask_parent(d);
> -}
> -
> -static void qcom_pdc_gic_unmask(struct irq_data *d)
> -{
> -	if (d->hwirq == GPIO_NO_WAKE_IRQ)
> -		return;
> -
> -	irq_chip_unmask_parent(d);
> -}
> -
>  /*
>   * GIC does not handle falling edge or active low. To allow falling edge and
>   * active low interrupts to be handled at GIC, PDC has an inverter that inverts
> @@ -159,14 +117,10 @@ enum pdc_irq_config_bits {
>   */
>  static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
>  {
> -	int pin_out = d->hwirq;
>  	enum pdc_irq_config_bits pdc_type;
>  	enum pdc_irq_config_bits old_pdc_type;
>  	int ret;
>  
> -	if (pin_out == GPIO_NO_WAKE_IRQ)
> -		return 0;
> -
>  	switch (type) {
>  	case IRQ_TYPE_EDGE_RISING:
>  		pdc_type = PDC_EDGE_RISING;
> @@ -191,8 +145,8 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
>  		return -EINVAL;
>  	}
>  
> -	old_pdc_type = pdc_reg_read(IRQ_i_CFG, pin_out);
> -	pdc_reg_write(IRQ_i_CFG, pin_out, pdc_type);
> +	old_pdc_type = pdc_reg_read(IRQ_i_CFG, d->hwirq);
> +	pdc_reg_write(IRQ_i_CFG, d->hwirq, pdc_type);
>  
>  	ret = irq_chip_set_type_parent(d, type);
>  	if (ret)
> @@ -216,12 +170,12 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
>  static struct irq_chip qcom_pdc_gic_chip = {
>  	.name			= "PDC",
>  	.irq_eoi		= irq_chip_eoi_parent,
> -	.irq_mask		= qcom_pdc_gic_mask,
> -	.irq_unmask		= qcom_pdc_gic_unmask,
> +	.irq_mask		= irq_chip_mask_parent,
> +	.irq_unmask		= irq_chip_unmask_parent,
>  	.irq_disable		= qcom_pdc_gic_disable,
>  	.irq_enable		= qcom_pdc_gic_enable,
> -	.irq_get_irqchip_state	= qcom_pdc_gic_get_irqchip_state,
> -	.irq_set_irqchip_state	= qcom_pdc_gic_set_irqchip_state,
> +	.irq_get_irqchip_state	= irq_chip_get_parent_state,
> +	.irq_set_irqchip_state	= irq_chip_set_parent_state,
>  	.irq_retrigger		= irq_chip_retrigger_hierarchy,
>  	.irq_set_type		= qcom_pdc_gic_set_type,
>  	.flags			= IRQCHIP_MASK_ON_SUSPEND |
> @@ -282,7 +236,7 @@ static int qcom_pdc_alloc(struct irq_domain *domain, unsigned int virq,
>  
>  	parent_hwirq = get_parent_hwirq(hwirq);
>  	if (parent_hwirq == PDC_NO_PARENT_IRQ)
> -		return 0;
> +		return irq_domain_disconnect_hierarchy(domain->parent, virq);
>  
>  	if (type & IRQ_TYPE_EDGE_BOTH)
>  		type = IRQ_TYPE_EDGE_RISING;
> @@ -314,22 +268,29 @@ static int qcom_pdc_gpio_alloc(struct irq_domain *domain, unsigned int virq,
>  	irq_hw_number_t hwirq, parent_hwirq;
>  	unsigned int type;
>  	int ret;
> +	struct irq_domain *parent;
>  
>  	ret = qcom_pdc_translate(domain, fwspec, &hwirq, &type);
>  	if (ret)
>  		return ret;
>  
> +	if (hwirq == GPIO_NO_WAKE_IRQ) {
> +		for (parent = domain; parent; parent = parent->parent) {
> +			ret = irq_domain_disconnect_hierarchy(parent, virq);
> +			if (ret)
> +				return ret;
> +		}
> +		return 0;
> +	}
> +

No, this is wrong. Please read the documentation for
irq_domain_disconnect_hierarchy(): the disconnect can only take place
*once* per interrupt, right at the point where you need to terminate
the hierarchy.

irq_domain_trim_hierarchy() should already do the right thing by
iterating over the domains and free the unused irq_data.

	M.

-- 
Without deviation from the norm, progress is not possible.

  reply	other threads:[~2021-08-20 15:38 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-19 11:53 [PATCH v2 0/3] Start getting rid of the GPIO_NO_WAKE_IRQ Maulik Shah
2021-08-19 11:53 ` [PATCH v2 1/3] irqdomain: Export irq_domain_disconnect_hierarchy() Maulik Shah
2021-08-19 11:53 ` [PATCH v2 2/3] irqdomain: Fix irq_domain_trim_hierarchy() Maulik Shah
2021-08-20 15:54   ` Marc Zyngier
2021-08-19 11:53 ` [PATCH v2 3/3] irqchip/qcom-pdc: Start getting rid of the GPIO_NO_WAKE_IRQ Maulik Shah
2021-08-20 15:38   ` Marc Zyngier [this message]
2021-08-23  7:55     ` Maulik Shah

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=87k0kgqg6s.wl-maz@kernel.org \
    --to=maz@kernel.org \
    --cc=bjorn.andersson@linaro.org \
    --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=mkshah@codeaurora.org \
    --cc=tglx@linutronix.de \
    --cc=tkjos@google.com \
    /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.