From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Grant Likely <grant.likely@secretlab.ca>
Cc: linux-kernel@vger.kernel.org, Milton Miller <miltonm@bga.com>,
Paul Mundt <lethal@linux-sh.org>,
Thomas Gleixner <tglx@linutronix.de>,
Rob Herring <rob.herring@calxeda.com>
Subject: Re: [PATCH 03/12] irqdomain: Support for static IRQ mapping and association.
Date: Sat, 16 Jun 2012 15:58:39 +1000 [thread overview]
Message-ID: <1339826319.9220.221.camel@pasglop> (raw)
In-Reply-To: <1339822897-15840-4-git-send-email-grant.likely@secretlab.ca>
On Fri, 2012-06-15 at 23:01 -0600, Grant Likely wrote:
> From: Paul Mundt <lethal@linux-sh.org>
>
> This adds a new strict mapping API for supporting creation of linux IRQs
> at existing positions within the domain. The new routines are as follows:
>
> For dynamic allocation and insertion to specified ranges:
>
> - irq_create_identity_mapping()
> - irq_create_strict_mappings()
How does that differ from NOMAP ? Any reason to add that rather than use
NOMAP and some offset built into the PIC driver ?
Cheers,
Ben.
> These will allocate and associate a range of linux IRQs at the specified
> location. This can be used by controllers that have their own static linux IRQ
> definitions to map a hwirq range to, as well as for platforms that wish to
> establish 1:1 identity mapping between linux and hwirq space.
>
> For insertion to specified ranges by platforms that do their own irq_desc
> management:
>
> - irq_domain_associate()
> - irq_domain_associate_many()
>
> These in turn call back in to the domain's ->map() routine, for further
> processing by the platform. Disassociation of IRQs get handled through
> irq_dispose_mapping() as normal.
>
> With these in place it should be possible to begin migration of legacy IRQ
> domains to linear ones, without requiring special handling for static vs
> dynamic IRQ definitions in DT vs non-DT paths. This also makes it possible
> for domains with static mappings to adopt whichever tree model best fits
> their needs, rather than simply restricting them to linear revmaps.
>
> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
> [grant.likely: Reorganized irq_domain_associate{,_many} to have all logic in one place]
> [grant.likely: Add error checking for unallocated irq_descs at associate time]
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Rob Herring <rob.herring@calxeda.com>
> ---
> include/linux/irqdomain.h | 19 ++++++++
> kernel/irq/irqdomain.c | 106 +++++++++++++++++++++++++++++++++++----------
> 2 files changed, 102 insertions(+), 23 deletions(-)
>
> diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
> index 5abb533..3425631 100644
> --- a/include/linux/irqdomain.h
> +++ b/include/linux/irqdomain.h
> @@ -144,12 +144,31 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
>
> extern void irq_domain_remove(struct irq_domain *host);
>
> +extern int irq_domain_associate_many(struct irq_domain *domain,
> + unsigned int irq_base,
> + irq_hw_number_t hwirq_base, int count);
> +static inline int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
> + irq_hw_number_t hwirq)
> +{
> + return irq_domain_associate_many(domain, irq, hwirq, 1);
> +}
> +
> extern unsigned int irq_create_mapping(struct irq_domain *host,
> irq_hw_number_t hwirq);
> extern void irq_dispose_mapping(unsigned int virq);
> extern unsigned int irq_find_mapping(struct irq_domain *host,
> irq_hw_number_t hwirq);
> extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
> +extern int irq_create_strict_mappings(struct irq_domain *domain,
> + unsigned int irq_base,
> + irq_hw_number_t hwirq_base, int count);
> +
> +static inline int irq_create_identity_mapping(struct irq_domain *host,
> + irq_hw_number_t hwirq)
> +{
> + return irq_create_strict_mappings(host, hwirq, hwirq, 1);
> +}
> +
> extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
> irq_hw_number_t hwirq);
> extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index 5c36722..1a8f3d2 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -379,34 +379,56 @@ static void irq_domain_disassociate_many(struct irq_domain *domain,
> }
> }
>
> -static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
> - irq_hw_number_t hwirq)
> +int irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base,
> + irq_hw_number_t hwirq_base, int count)
> {
> - struct irq_data *irq_data = irq_get_irq_data(virq);
> + unsigned int virq = irq_base;
> + irq_hw_number_t hwirq = hwirq_base;
> + int i;
>
> - irq_data->hwirq = hwirq;
> - irq_data->domain = domain;
> - if (domain->ops->map(domain, virq, hwirq)) {
> - pr_debug("irq-%i==>hwirq-0x%lx mapping failed\n", virq, hwirq);
> - irq_data->domain = NULL;
> - irq_data->hwirq = 0;
> - return -1;
> - }
> + for (i = 0; i < count; i++) {
> + struct irq_data *irq_data = irq_get_irq_data(virq + i);
>
> - switch (domain->revmap_type) {
> - case IRQ_DOMAIN_MAP_LINEAR:
> - if (hwirq < domain->revmap_data.linear.size)
> - domain->revmap_data.linear.revmap[hwirq] = virq;
> - break;
> - case IRQ_DOMAIN_MAP_TREE:
> - irq_radix_revmap_insert(domain, virq, hwirq);
> - break;
> - }
> + if (WARN(!irq_data, "error: irq_desc not allocated; "
> + "irq=%i hwirq=0x%x\n", virq + i, (int)hwirq + i))
> + return -EINVAL;
> + if (WARN(irq_data->domain, "error: irq_desc already associated; "
> + "irq=%i hwirq=0x%x\n", virq + i, (int)hwirq + i))
> + return -EINVAL;
> + };
>
> - irq_clear_status_flags(virq, IRQ_NOREQUEST);
> + for (i = 0; i < count; i++, virq++, hwirq++) {
> + struct irq_data *irq_data = irq_get_irq_data(virq);
> +
> + irq_data->hwirq = hwirq;
> + irq_data->domain = domain;
> + if (domain->ops->map(domain, virq, hwirq)) {
> + pr_debug("irq-%i==>hwirq-0x%lx mapping failed\n", virq, hwirq);
> + irq_data->domain = NULL;
> + irq_data->hwirq = 0;
> + goto err_unmap;
> + }
> +
> + switch (domain->revmap_type) {
> + case IRQ_DOMAIN_MAP_LINEAR:
> + if (hwirq < domain->revmap_data.linear.size)
> + domain->revmap_data.linear.revmap[hwirq] = virq;
> + break;
> + case IRQ_DOMAIN_MAP_TREE:
> + irq_radix_revmap_insert(domain, virq, hwirq);
> + break;
> + }
> +
> + irq_clear_status_flags(virq, IRQ_NOREQUEST);
> + }
>
> return 0;
> +
> + err_unmap:
> + irq_domain_disassociate_many(domain, irq_base, i);
> + return -EINVAL;
> }
> +EXPORT_SYMBOL_GPL(irq_domain_associate_many);
>
> /**
> * irq_create_direct_mapping() - Allocate an irq for direct mapping
> @@ -439,7 +461,7 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
> }
> pr_debug("create_direct obtained virq %d\n", virq);
>
> - if (irq_setup_virq(domain, virq, virq)) {
> + if (irq_domain_associate(domain, virq, virq)) {
> irq_free_desc(virq);
> return 0;
> }
> @@ -500,7 +522,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
> return 0;
> }
>
> - if (irq_setup_virq(domain, virq, hwirq)) {
> + if (irq_domain_associate(domain, virq, hwirq)) {
> irq_free_desc(virq);
> return 0;
> }
> @@ -512,6 +534,44 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
> }
> EXPORT_SYMBOL_GPL(irq_create_mapping);
>
> +/**
> + * irq_create_strict_mappings() - Map a range of hw irqs to fixed linux irqs
> + * @domain: domain owning the interrupt range
> + * @irq_base: beginning of linux IRQ range
> + * @hwirq_base: beginning of hardware IRQ range
> + * @count: Number of interrupts to map
> + *
> + * This routine is used for allocating and mapping a range of hardware
> + * irqs to linux irqs where the linux irq numbers are at pre-defined
> + * locations. For use by controllers that already have static mappings
> + * to insert in to the domain.
> + *
> + * Non-linear users can use irq_create_identity_mapping() for IRQ-at-a-time
> + * domain insertion.
> + *
> + * 0 is returned upon success, while any failure to establish a static
> + * mapping is treated as an error.
> + */
> +int irq_create_strict_mappings(struct irq_domain *domain, unsigned int irq_base,
> + irq_hw_number_t hwirq_base, int count)
> +{
> + int ret;
> +
> + ret = irq_alloc_descs(irq_base, irq_base, count,
> + of_node_to_nid(domain->of_node));
> + if (unlikely(ret < 0))
> + return ret;
> +
> + ret = irq_domain_associate_many(domain, irq_base, hwirq_base, count);
> + if (unlikely(ret < 0)) {
> + irq_free_descs(irq_base, count);
> + return ret;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(irq_create_strict_mappings);
> +
> unsigned int irq_create_of_mapping(struct device_node *controller,
> const u32 *intspec, unsigned int intsize)
> {
next prev parent reply other threads:[~2012-06-16 5:59 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-16 5:01 [PATCH 00/12] irqdomain cleanup and refactoring Grant Likely
2012-06-16 5:01 ` [PATCH 01/12] irqdomain: Split disassociating code into separate function Grant Likely
2012-06-16 5:57 ` Benjamin Herrenschmidt
2012-06-16 5:01 ` [PATCH 02/12] irqdomain: Always update revmap when setting up a virq Grant Likely
2012-06-16 5:57 ` Benjamin Herrenschmidt
2012-06-16 5:01 ` [PATCH 03/12] irqdomain: Support for static IRQ mapping and association Grant Likely
2012-06-16 5:58 ` Benjamin Herrenschmidt [this message]
2012-06-17 22:16 ` Grant Likely
2012-06-16 5:01 ` [PATCH 04/12] irqdomain: Eliminate dedicated radix lookup functions Grant Likely
2012-06-16 5:56 ` Benjamin Herrenschmidt
2012-06-16 6:12 ` Grant Likely
2012-06-17 21:58 ` Grant Likely
2012-06-16 5:01 ` [PATCH 05/12] irqdomain: Fix irq_create_direct_mapping() to test irq_domain type Grant Likely
2012-06-16 5:01 ` [PATCH 06/12] irqdomain: eliminate slow-path revmap lookups Grant Likely
2012-06-16 5:01 ` [PATCH 07/12] irqdomain: Make ops->map hook optional Grant Likely
2012-06-16 5:59 ` Benjamin Herrenschmidt
2012-06-16 5:01 ` [PATCH 08/12] irqdomain: Replace LEGACY mapping with LINEAR Grant Likely
2012-06-16 6:01 ` Benjamin Herrenschmidt
2012-06-16 6:16 ` Grant Likely
2012-06-18 12:23 ` Mark Brown
2012-06-16 5:01 ` [PATCH 09/12] irqdomain: Reserve IRQs for legacy domain Grant Likely
2012-06-16 5:01 ` [PATCH 10/12] irqdomain: Add debugging message Grant Likely
2012-06-16 6:02 ` Benjamin Herrenschmidt
2012-06-16 5:01 ` [PATCH 11/12] irqdomain: reorganize revmap data Grant Likely
2012-06-16 6:06 ` Benjamin Herrenschmidt
2012-06-16 6:19 ` Grant Likely
2012-06-16 6:20 ` Grant Likely
2012-06-16 5:01 ` [PATCH 12/12] irqdomain: merge linear and tree reverse mappings Grant Likely
2012-06-18 12:28 ` [PATCH 00/12] irqdomain cleanup and refactoring Mark Brown
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=1339826319.9220.221.camel@pasglop \
--to=benh@kernel.crashing.org \
--cc=grant.likely@secretlab.ca \
--cc=lethal@linux-sh.org \
--cc=linux-kernel@vger.kernel.org \
--cc=miltonm@bga.com \
--cc=rob.herring@calxeda.com \
--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.