devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Marc Zyngier <marc.zyngier-5wv7dgnIgG8@public.gmane.org>
To: Alexander Stein
	<alexander.stein-93q1YBGzJSMe9JSWTWOYM3xStJ4P+DSV@public.gmane.org>,
	Rasmus Villemoes
	<rasmus.villemoes-rjjw5hvvQKZaa/9Udqfwiw@public.gmane.org>
Cc: Thomas Gleixner <tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>,
	Jason Cooper <jason-NLaQJdtUoK4Be96aLqz0jA@public.gmane.org>,
	Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [RFC] irqchip: add support for LS1021A external interrupt lines
Date: Fri, 8 Dec 2017 16:09:09 +0000	[thread overview]
Message-ID: <9eab29c0-3347-635c-af92-4e8429064ed3@arm.com> (raw)
In-Reply-To: <2278177.dEyeroM47a@ws-stein>

On 08/12/17 15:11, Alexander Stein wrote:
> Hi Rasmus,
> 
> thanks for your effort. unfortunatly I won't be able to test it currently :(
> But some comments below.
> 
> On Friday, December 8, 2017, 3:33:00 PM CET Rasmus Villemoes wrote:
>> The LS1021A allows inverting the polarity of six interrupt lines
>> IRQ[0:5] via the scfg_intpcr register, effectively allowing
>> IRQ_TYPE_LEVEL_LOW and IRQ_TYPE_EDGE_FALLING for those. We just need to
>> check the type, set the relevant bit in INTPCR accordingly, and fixup
>> the type argument before calling the GIC's irq_set_type.
>>
>> In fact, the power-on-reset value of the INTPCR register is so that all
>> six lines have their polarity inverted. Hence any hardware connected to
>> those lines is unusable without this: If the line is indeed active low,
>> the generic GIC code will reject an irq spec with IRQ_TYPE_LEVEL_LOW,
>> while if the line is active high, we must obviously disable the polarity
>> inversion before unmasking the interrupt.
>>
>> I suspect other layerscape SOCs may have something similar, but I have
>> neither hardware nor documentation.
>>
>> Since we only need to keep a single pointer in the chip_data (the syscon
>> regmap), the code could be a little simpler by dropping the struct
>> extirq_chip_data and just store the regmap directly - but I don't know
>> if I do need to add a lock or something else to the chip_data, so for
>> this RFC I've kept the struct.
>>
>> Signed-off-by: Rasmus Villemoes <rasmus.villemoes-rjjw5hvvQKZaa/9Udqfwiw@public.gmane.org>
>> ---
>> Marc, Alexander, thanks a lot for your hints. This is what I came up
>> with, mostly just copy-pasted from the mtk-sysirq case. I've tested
>> that it works as expected on my board.
>>
>>  .../interrupt-controller/fsl,ls1021a-extirq.txt    |  19 +++
>>  drivers/irqchip/Makefile                           |   1 +
>>  drivers/irqchip/irq-ls1021a.c                      | 157 +++++++++++++++++++++
>>  3 files changed, 177 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/fsl,ls1021a-extirq.txt
>>  create mode 100644 drivers/irqchip/irq-ls1021a.c
>>
>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls1021a-extirq.txt b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls1021a-extirq.txt
>> new file mode 100644
>> index 000000000000..53b04b6e1a80
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls1021a-extirq.txt
>> @@ -0,0 +1,19 @@
>> +* Freescale LS1021A external IRQs
>> +
>> +The LS1021A supports inverting the polarity of six external interrupt lines.
>> +
>> +Required properties:
>> +- compatible: should be "fsl,ls1021a-extirq"
>> +- interrupt-controller: Identifies the node as an interrupt controller
>> +- #interrupt-cells: Use the same format as specified by GIC in arm,gic.txt.
> 
> Do you really need 3 interrupt-cells here? As you've written below you don't
> support PPI anyway the 1st flag might be dropped then. So support just 2 cells:
> * IRQ number (IRQ0 - IRQ5)
> * IRQ flags

The convention for irqchip stacked on top of a GIC is to keep the
interrupt specifier the same. It makes the maintenance if the DT much
easier, and doesn't hurt at all.

> 
>> +- interrupt-parent: phandle of GIC.
>> +- syscon: phandle of Supplemental Configuration Unit (scfg).
>> +
>> +Example:
>> +		extirq: interrupt-controller@15701ac {
>> +			compatible = "fsl,ls1021a-extirq";
>> +			#interrupt-cells = <3>;
>> +			interrupt-controller;
>> +			interrupt-parent = <&gic>;
>> +			syscon = <&scfg>;
>> +		};
>> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
>> index b842dfdc903f..d4576dce24b2 100644
>> --- a/drivers/irqchip/Makefile
>> +++ b/drivers/irqchip/Makefile
>> @@ -80,3 +80,4 @@ obj-$(CONFIG_ARCH_ASPEED)		+= irq-aspeed-vic.o irq-aspeed-i2c-ic.o
>>  obj-$(CONFIG_STM32_EXTI) 		+= irq-stm32-exti.o
>>  obj-$(CONFIG_QCOM_IRQ_COMBINER)		+= qcom-irq-combiner.o
>>  obj-$(CONFIG_IRQ_UNIPHIER_AIDET)	+= irq-uniphier-aidet.o
>> +obj-$(CONFIG_SOC_LS1021A)		+= irq-ls1021a.o
> 
> I guess this should be kept sorted alphabetically.

There is no such requirement. But grouping it next to the other FSL
irqchip would make more sense.

> 
>> diff --git a/drivers/irqchip/irq-ls1021a.c b/drivers/irqchip/irq-ls1021a.c
>> new file mode 100644
>> index 000000000000..2ec4fc023549
>> --- /dev/null
>> +++ b/drivers/irqchip/irq-ls1021a.c
>> @@ -0,0 +1,157 @@
>> +#define pr_fmt(fmt) "irq-ls1021a: " fmt
>> +
>> +#include <linux/irq.h>
>> +#include <linux/irqchip.h>
>> +#include <linux/irqdomain.h>
>> +#include <linux/of.h>
>> +#include <linux/of_irq.h>
>> +#include <linux/of_address.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/regmap.h>
>> +#include <linux/slab.h>
>> +
>> +#define INTPCR_REG 0x01ac
>> +#define NIRQ 6
>> +
>> +struct extirq_chip_data {
>> +	struct regmap *syscon;
>> +};
>> +
>> +static int
>> +ls1021a_extirq_set_type(struct irq_data *data, unsigned int type)
>> +{
>> +	irq_hw_number_t hwirq = data->hwirq;
>> +	struct extirq_chip_data *chip_data = data->chip_data;
>> +	u32 value, mask;
>> +	int ret;
>> +
>> +	mask = 1U << (31 - hwirq);
> 
> Is this really correct? IRQ0 is still at bit position 0. Don't be mislead
> by the left most position in the register layout. This is just strange way
> to express bit-endian access.
> Anyway, please use BIT(x) instead.
> 
>> +	if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) {
>> +		if (type == IRQ_TYPE_LEVEL_LOW)
>> +			type = IRQ_TYPE_LEVEL_HIGH;
>> +		else
>> +			type = IRQ_TYPE_EDGE_RISING;
>> +		value = mask;
>> +	} else {
>> +		value = 0;
>> +	}
>> +
>> +	/* Don't do the INTPCR_REG update if the parent irq_set_type will EINVAL. */
>> +	if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
>> +		return -EINVAL;
> 
> I wonder if it is better to call data->parent_data->chip->irq_set_type(data, type)
> here instead and call regmap if this suceeded.

Not really. In both cases, you need to evaluate the failure (which is
not don here). So ordering doesn't matter. What actually matters is
error handling and atomicity (in this case, making sure that drivers
cannot observe an interrupt flood between the two reconfigurations).

> 
>> +	/* regmap does internal locking, but do we need to provide our
>> +	 * own across the parent irq_set_type call? */
>> +	regmap_update_bits(chip_data->syscon, INTPCR_REG, mask, value);
>> +
>> +	data = data->parent_data;
>> +	ret = data->chip->irq_set_type(data, type);
>> +
>> +	return ret;
>> +}
>> +
>> +static struct irq_chip extirq_chip = {
>> +	.name			= "LS1021A_EXTIRQ",
>> +	.irq_mask		= irq_chip_mask_parent,
>> +	.irq_unmask		= irq_chip_unmask_parent,
>> +	.irq_eoi		= irq_chip_eoi_parent,
>> +	.irq_set_type		= ls1021a_extirq_set_type,
>> +	.irq_retrigger		= irq_chip_retrigger_hierarchy,
>> +	.irq_set_affinity	= irq_chip_set_affinity_parent,
>> +};
>> +
>> +static int
>> +ls1021a_extirq_domain_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
>> +				unsigned long *hwirq, unsigned int *type)
>> +{
>> +	if (!is_of_node(fwspec->fwnode))
>> +		return -EINVAL;
>> +
>> +	if (fwspec->param_count != 3)
>> +		return -EINVAL;
>> +
>> +	/* No PPI should point to this domain */
>> +	if (fwspec->param[0] != 0)
>> +		return -EINVAL;
>> +
>> +	*hwirq = fwspec->param[1];
> 
> Is a check for the hwirq value required here? I'm not an expert on
> irqchip API, so I just wonder.

In general, the driver is not in the business of validating the DT. But
that wouldn't hurt...

> 
>> +	*type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
>> +	return 0;
>> +}
>> +
>> +static int
>> +ls1021a_extirq_domain_alloc(struct irq_domain *domain, unsigned int virq,
>> +			    unsigned int nr_irqs, void *arg)
>> +{
>> +	static const unsigned xlate[NIRQ] = {163,164,165,167,168,169};
>     ^^^^^^
> No need for static here.

Why would you store this on the stack each time you enter the function?
That's the wrong construct (these values should come from DT), but
static is perfectly fine.

[...]

>> +	domain_parent = irq_find_host(parent);
>> +	if (!domain_parent) {
>> +		pr_err("interrupt-parent not found\n");
>> +		return -EINVAL;
>> +	}
> 
> Mh, does this mean if GIC has not been probed, this probe is not deferred?
> Is there an API to check for that?

This is not a normal driver, there is not deferred probing. You'd get
this error if the kernel had gone really wrong.

> 
>> +	chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL);
> 				^^^^^^^
> 				devm_kzalloc
>> +	if (!chip_data)
>> +		return -ENOMEM;
>> +
>> +	chip_data->syscon = syscon_regmap_lookup_by_phandle(node, "syscon");
>> +	if (IS_ERR(chip_data->syscon)) {
>> +		ret = PTR_ERR(chip_data->syscon);
>> +		goto out_free_chip;
>> +	}
>> +
>> +	domain = irq_domain_add_hierarchy(domain_parent, 0, NIRQ, node,
>> +					  &extirq_domain_ops, chip_data);
>> +	if (!domain) {
>> +		ret = -ENOMEM;
>> +		goto out_free_chip;
>> +	}
>> +
>> +	return 0;
>> +
>> +out_free_chip:
>> +	kfree(chip_data);
>> +	return ret;
> 
> Using devm_kzalloc this label can be skipped.

Show me the struct device.

Thanks,

	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

  reply	other threads:[~2017-12-08 16:09 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <48d2d08c-c57a-ce49-5958-0fd5ad4a2dc7@arm.com>
2017-12-08 14:33 ` [RFC] irqchip: add support for LS1021A external interrupt lines Rasmus Villemoes
     [not found]   ` <1512743580-15358-1-git-send-email-rasmus.villemoes-rjjw5hvvQKZaa/9Udqfwiw@public.gmane.org>
2017-12-08 15:11     ` Alexander Stein
2017-12-08 16:09       ` Marc Zyngier [this message]
2017-12-11  9:08         ` Rasmus Villemoes
     [not found]           ` <58297576-cc32-819d-c6b3-7d1355095482-rjjw5hvvQKZaa/9Udqfwiw@public.gmane.org>
2017-12-11  9:45             ` Alexander Stein
2017-12-11 10:02               ` Alexander Stein
2017-12-11 13:45                 ` Rasmus Villemoes
2017-12-11 14:06                   ` Rasmus Villemoes
     [not found]                     ` <7badefae-a952-7839-0bfe-dcd09ea1204f-rjjw5hvvQKZaa/9Udqfwiw@public.gmane.org>
2017-12-11 14:38                       ` Alexander Stein
2017-12-08 16:02     ` Marc Zyngier
     [not found]       ` <da843420-cede-e787-838d-1fd48e3ca7dd-5wv7dgnIgG8@public.gmane.org>
2017-12-11  9:30         ` Rasmus Villemoes
     [not found]           ` <563e0aaa-faf9-ae6a-ccd4-2aa89d7e457b-rjjw5hvvQKZaa/9Udqfwiw@public.gmane.org>
2017-12-11 18:29             ` Marc Zyngier
2017-12-12 23:28     ` Rob Herring
2017-12-15 22:55       ` Rasmus Villemoes
     [not found]         ` <62c4af0c-ffe5-23c9-9ef6-2e4b8ab90050-rjjw5hvvQKZaa/9Udqfwiw@public.gmane.org>
2017-12-21 22:45           ` Rob Herring
     [not found]   ` <1513758631-19909-1-git-send-email-rasmus.villemoes@prevas.dk>
     [not found]     ` <1513758631-19909-1-git-send-email-rasmus.villemoes-rjjw5hvvQKZaa/9Udqfwiw@public.gmane.org>
2017-12-20  8:30       ` [PATCH v2 2/2] dt/bindings: Add bindings for Layerscape external irqs Rasmus Villemoes
     [not found]         ` <1513758631-19909-2-git-send-email-rasmus.villemoes-rjjw5hvvQKZaa/9Udqfwiw@public.gmane.org>
2017-12-21 22:44           ` Rob Herring
     [not found]     ` <20180122092133.23177-1-rasmus.villemoes@prevas.dk>
2018-01-22  9:21       ` [PATCH v3 " Rasmus Villemoes
2018-01-24 15:28         ` Marc Zyngier
     [not found]       ` <20180125150230.7234-1-rasmus.villemoes@prevas.dk>
     [not found]         ` <20180125150230.7234-1-rasmus.villemoes-rjjw5hvvQKZaa/9Udqfwiw@public.gmane.org>
2018-01-25 15:02           ` [PATCH v4 " Rasmus Villemoes
     [not found]             ` <20180125150230.7234-2-rasmus.villemoes-rjjw5hvvQKZaa/9Udqfwiw@public.gmane.org>
2018-02-05  6:07               ` Rob Herring
2018-02-08 15:08                 ` Rasmus Villemoes
     [not found]                   ` <15ac0da3-e85b-c6be-366a-368934752018-rjjw5hvvQKZaa/9Udqfwiw@public.gmane.org>
2018-02-09  9:47                     ` Marc Zyngier
     [not found]         ` <20180223210901.23480-1-rasmus.villemoes@prevas.dk>
2018-02-23 21:09           ` [PATCH v5 " Rasmus Villemoes
2018-03-02 19:49             ` Rob Herring
2018-05-04  8:07               ` Rasmus Villemoes

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=9eab29c0-3347-635c-af92-4e8429064ed3@arm.com \
    --to=marc.zyngier-5wv7dgnigg8@public.gmane.org \
    --cc=alexander.stein-93q1YBGzJSMe9JSWTWOYM3xStJ4P+DSV@public.gmane.org \
    --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=jason-NLaQJdtUoK4Be96aLqz0jA@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=mark.rutland-5wv7dgnIgG8@public.gmane.org \
    --cc=rasmus.villemoes-rjjw5hvvQKZaa/9Udqfwiw@public.gmane.org \
    --cc=robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=tglx-hfZtesqFncYOwBW4kG4KsQ@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).