devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Marc Zyngier <marc.zyngier-5wv7dgnIgG8@public.gmane.org>
To: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org,
	tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
	b.galvani-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-meson-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org,
	drake-6IF/jdPJHihWk0Htik3J/w@public.gmane.org,
	jerry.cao-LpR1jeaWuhtBDgjK7y7TUQ@public.gmane.org,
	victor.wan-LpR1jeaWuhtBDgjK7y7TUQ@public.gmane.org
Cc: Carlo Caione <carlo-6IF/jdPJHihWk0Htik3J/w@public.gmane.org>
Subject: Re: [PATCH v3 4/6] pinctrl: meson: Enable GPIO IRQs
Date: Tue, 01 Dec 2015 19:16:33 +0000	[thread overview]
Message-ID: <565DF211.8000005@arm.com> (raw)
In-Reply-To: <1448987062-31225-5-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>

On 01/12/15 16:24, Carlo Caione wrote:
> From: Carlo Caione <carlo-6IF/jdPJHihWk0Htik3J/w@public.gmane.org>
> 
> On Meson8 and Meson8b SoCs there are 8 independent filtered GPIO
> interrupt modules that can be programmed to use any of the GPIOs in the
> chip as an interrupt source.
> 
> For each GPIO IRQ we have:
> 
> GPIOs --> [mux]--> [polarity]--> [filter]--> [edge select]--> GIC
> 
> The eight GPIO interrupts respond to mask/unmask/clear/etc.. just like
> any other interrupt in the chip. The difference for the GPIO interrupts
> is that they can be filtered and conditioned.
> 
> This patch adds support for the external GPIOs interrupts and enables
> them for Meson8 and Meson8b SoCs.
> 
> Signed-off-by: Carlo Caione <carlo-6IF/jdPJHihWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Beniamino Galvani <b.galvani-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>  drivers/pinctrl/Kconfig                    |   1 +
>  drivers/pinctrl/meson/Makefile             |   2 +-
>  drivers/pinctrl/meson/irqchip-gpio-meson.c | 321 +++++++++++++++++++++++++++++
>  drivers/pinctrl/meson/pinctrl-meson.c      |  30 +++
>  drivers/pinctrl/meson/pinctrl-meson.h      |  15 ++
>  5 files changed, 368 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/pinctrl/meson/irqchip-gpio-meson.c
> 

[...]

> +static int meson_irq_domain_alloc(struct irq_domain *domain, unsigned int irq,
> +				  unsigned int nr_irqs, void *arg)
> +{
> +	struct meson_pinctrl *pc = domain->host_data;
> +	struct irq_fwspec *irq_data = arg;
> +	struct irq_fwspec gic_data;
> +	irq_hw_number_t hwirq;
> +	int index, ret, i;
> +
> +	if (irq_data->param_count != 2)
> +		return -EINVAL;
> +
> +	hwirq = irq_data->param[0];
> +	dev_dbg(pc->dev, "%s irq %d, nr %d, hwirq %lu\n",
> +			__func__, irq, nr_irqs, hwirq);
> +
> +	for (i = 0; i < nr_irqs; i++) {
> +		index = meson_map_gic_irq(domain, hwirq + i);
> +		if (index < 0)
> +			return index;
> +
> +		irq_domain_set_hwirq_and_chip(domain, irq + i,
> +					      hwirq + i,
> +					      &meson_irq_chip,
> +					      pc);
> +
> +		gic_data.param_count = 3;
> +		gic_data.fwnode = domain->parent->fwnode;
> +		gic_data.param[0] = 0; /* SPI */
> +		gic_data.param[1] = pc->gic_irqs[index];
> +		gic_data.param[1] = IRQ_TYPE_EDGE_RISING;

That feels quite wrong. Hardcoding the trigger like this and hoping for
a set_type to set it right at a later time is just asking for trouble.
Why can't you use the trigger type that has been provided by the
interrupt descriptor?

> +
> +		ret = irq_domain_alloc_irqs_parent(domain, irq + i, nr_irqs,
> +						   &gic_data);
> +	}
> +
> +	return 0;
> +}
> +
> +static void meson_irq_domain_free(struct irq_domain *domain, unsigned int irq,
> +				  unsigned int nr_irqs)
> +{
> +	struct meson_pinctrl *pc = domain->host_data;
> +	struct irq_data *irq_data;
> +	int index, i;
> +
> +	spin_lock(&pc->lock);
> +	for (i = 0; i < nr_irqs; i++) {
> +		irq_data = irq_domain_get_irq_data(domain, irq + i);
> +		index = meson_get_gic_irq(pc, irq_data->hwirq);
> +		if (index < 0)
> +			continue;
> +		pc->irq_map[index] = IRQ_FREE;
> +	}
> +	spin_unlock(&pc->lock);
> +
> +	irq_domain_free_irqs_parent(domain, irq, nr_irqs);
> +}
> +
> +static int meson_irq_domain_translate(struct irq_domain *d,
> +				      struct irq_fwspec *fwspec,
> +				      unsigned long *hwirq,
> +				      unsigned int *type)
> +{
> +	if (is_of_node(fwspec->fwnode)) {
> +		if (fwspec->param_count != 2)
> +			return -EINVAL;
> +
> +		*hwirq = fwspec->param[0];
> +		*type = fwspec->param[1];
> +
> +		return 0;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static struct irq_domain_ops meson_irq_domain_ops = {
> +	.alloc		= meson_irq_domain_alloc,
> +	.free		= meson_irq_domain_free,
> +	.translate	= meson_irq_domain_translate,
> +};
> +
> +int meson_gpio_irq_init(struct meson_pinctrl *pc)
> +{
> +	struct device_node *node = pc->dev->of_node;
> +	struct device_node *parent_node;
> +	struct irq_domain *parent_domain;
> +	const __be32 *irqs;
> +	int i, size;
> +
> +	parent_node = of_irq_find_parent(node);
> +	if (!parent_node) {
> +		dev_err(pc->dev, "can't find parent interrupt controller\n");
> +		return -EINVAL;
> +	}
> +
> +	parent_domain = irq_find_host(parent_node);
> +	if (!parent_domain) {
> +		dev_err(pc->dev, "can't find parent IRQ domain\n");
> +		return -EINVAL;
> +	}
> +
> +	pc->reg_irq = meson_map_resource(pc, node, "irq");
> +	if (!pc->reg_irq) {
> +		dev_err(pc->dev, "can't find irq registers\n");
> +		return -EINVAL;
> +	}
> +
> +	irqs = of_get_property(node, "amlogic,irqs-gpio", &size);
> +	if (!irqs) {
> +		dev_err(pc->dev, "no parent interrupts specified\n");
> +		return -EINVAL;
> +	}
> +	pc->num_gic_irqs = size / sizeof(__be32);
> +
> +	pc->irq_map = devm_kmalloc(pc->dev, sizeof(int) * pc->num_gic_irqs,
> +				   GFP_KERNEL);
> +	if (!pc->irq_map)
> +		return -ENOMEM;
> +
> +	pc->gic_irqs = devm_kzalloc(pc->dev, sizeof(int) * pc->num_gic_irqs,
> +				    GFP_KERNEL);
> +	if (!pc->gic_irqs)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < pc->num_gic_irqs; i++) {
> +		pc->irq_map[i] = IRQ_FREE;
> +		of_property_read_u32_index(node, "amlogic,irqs-gpio", i,
> +					   &pc->gic_irqs[i]);
> +	}
> +
> +	pc->irq_domain = irq_domain_add_hierarchy(parent_domain, 0,
> +						  pc->data->last_pin,
> +						  node, &meson_irq_domain_ops,
> +						  pc);
> +	if (!pc->irq_domain)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
> index 0c5655b..894b9ad 100644
> --- a/drivers/pinctrl/meson/pinctrl-meson.c
> +++ b/drivers/pinctrl/meson/pinctrl-meson.c
> @@ -540,6 +540,30 @@ static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio)
>  	return !!(val & BIT(bit));
>  }
>  
> +static int meson_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
> +{
> +	struct meson_domain *domain = to_meson_domain(chip);
> +	struct meson_pinctrl *pc = domain->pinctrl;
> +	struct meson_bank *bank;
> +	struct irq_fwspec irq_data;
> +	unsigned int hwirq, irq;
> +
> +	hwirq = domain->data->pin_base + offset;
> +
> +	if (meson_get_bank(domain, hwirq, &bank))
> +		return -ENXIO;
> +
> +	irq_data.param_count = 2;
> +	irq_data.param[0] = hwirq;
> +
> +	/* dummy. It will be changed later in meson_irq_set_type */
> +	irq_data.param[1] = IRQ_TYPE_EDGE_RISING;

Blah. Worse than I though... How do you end-up here? Why can't you
obtain the corresponding of_phandle_args instead of making things up?
This looks mad. Do you really need this?

	M.
-- 
Jazz is not dead. It just smells funny...
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2015-12-01 19:16 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-01 16:24 [PATCH v3 0/6] pinctrl: meson: enable support for external GPIO interrupts Carlo Caione
     [not found] ` <1448987062-31225-1-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
2015-12-01 16:24   ` [PATCH v3 1/6] of/irq: Export of_irq_find_parent again Carlo Caione
     [not found]     ` <1448987062-31225-2-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
2015-12-03 15:14       ` Rob Herring
2015-12-01 16:24   ` [PATCH v3 2/6] pinctrl: meson: Update pinctrl data with GPIO IRQ info Carlo Caione
2015-12-01 16:24   ` [PATCH v3 3/6] pinctrl: meson: Make helper functions public Carlo Caione
2015-12-01 16:24   ` [PATCH v3 4/6] pinctrl: meson: Enable GPIO IRQs Carlo Caione
     [not found]     ` <1448987062-31225-5-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
2015-12-01 19:16       ` Marc Zyngier [this message]
     [not found]         ` <565DF211.8000005-5wv7dgnIgG8@public.gmane.org>
2015-12-01 19:41           ` Carlo Caione
     [not found]             ` <CAOQ7t2YN8Ey1vZO4yrn9SdbR7FzPNVY-HGRBZOctLgK1vHo9VA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-12-02  9:03               ` Marc Zyngier
     [not found]                 ` <565EB3D8.5070400-5wv7dgnIgG8@public.gmane.org>
2015-12-02 11:37                   ` Carlo Caione
     [not found]                     ` <CAL9uMOE1orp8zQABMOW0eFMuZ9XcGfLF1RLOwurEcN-csxfGtg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-12-02 11:47                       ` Marc Zyngier
2015-12-01 16:24   ` [PATCH v3 5/6] pinctrl: dt-binding: Extend meson documentation with GPIO IRQs support Carlo Caione
     [not found]     ` <1448987062-31225-6-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
2015-12-02 15:30       ` Rob Herring
2015-12-02 15:44         ` Carlo Caione
2015-12-01 16:24   ` [PATCH v3 6/6] ARM: meson: DTS: Enable GPIO IRQs Carlo Caione
2015-12-10 17:31   ` [PATCH v3 0/6] pinctrl: meson: enable support for external GPIO interrupts 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=565DF211.8000005@arm.com \
    --to=marc.zyngier-5wv7dgnigg8@public.gmane.org \
    --cc=b.galvani-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=carlo-6IF/jdPJHihWk0Htik3J/w@public.gmane.org \
    --cc=carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org \
    --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=drake-6IF/jdPJHihWk0Htik3J/w@public.gmane.org \
    --cc=jerry.cao-LpR1jeaWuhtBDgjK7y7TUQ@public.gmane.org \
    --cc=jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org \
    --cc=linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-meson-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org \
    --cc=robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org \
    --cc=victor.wan-LpR1jeaWuhtBDgjK7y7TUQ@public.gmane.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).