From: Rob Herring <robherring2@gmail.com>
To: Grant Likely <grant.likely@secretlab.ca>
Cc: sfr@canb.auug.org.au, Russell King <linux@arm.linux.org.uk>,
linux-kernel@vger.kernel.org,
Thomas Gleixner <tglx@linutronix.de>,
linuxppc-dev@lists.ozlabs.org
Subject: Re: [RFC 13/14] irq_domain: Remove 'new' irq_domain in favour of the ppc one
Date: Wed, 11 Jan 2012 15:15:59 -0600 [thread overview]
Message-ID: <4F0DFC0F.2090005@gmail.com> (raw)
In-Reply-To: <1326313337-24603-14-git-send-email-grant.likely@secretlab.ca>
Grant,
On 01/11/2012 02:22 PM, Grant Likely wrote:
> This patch removes the simplistic implementation of irq_domains and enables
> the powerpc infrastructure for all irq_domain users. The powerpc
> infrastructure includes support for complex mappings between Linux and
> hardware irq numbers, and can manage allocation of irq_descs.
>
> This patch also converts the few users of irq_domain_add()/irq_domain_del()
> to call irq_domain_add_legacy() instead.
So what is the non-legacy way? Legacy implies we don't want to do it
that way. I guess until we remove all non-DT platforms with GIC we are
stuck with legacy. That seems like it could be a ways out until we get
there.
Rob
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> arch/arm/common/gic.c | 83 +++++++-----------
> arch/arm/common/vic.c | 16 +---
> arch/arm/include/asm/hardware/gic.h | 4 +-
> arch/arm/include/asm/hardware/vic.h | 2 +
> arch/arm/mach-exynos/common.c | 2 +-
> arch/arm/mach-versatile/core.c | 5 +-
> drivers/mfd/twl-core.c | 12 +--
> include/linux/irqdomain.h | 42 +---------
> kernel/irq/irqdomain.c | 161 +++--------------------------------
> 9 files changed, 64 insertions(+), 263 deletions(-)
>
> diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
> index 156bc03..d839168 100644
> --- a/arch/arm/common/gic.c
> +++ b/arch/arm/common/gic.c
> @@ -50,7 +50,6 @@ union gic_base {
> };
>
> struct gic_chip_data {
> - unsigned int irq_offset;
> union gic_base dist_base;
> union gic_base cpu_base;
> #ifdef CONFIG_CPU_PM
> @@ -60,9 +59,7 @@ struct gic_chip_data {
> u32 __percpu *saved_ppi_enable;
> u32 __percpu *saved_ppi_conf;
> #endif
> -#ifdef CONFIG_IRQ_DOMAIN
> - struct irq_domain domain;
> -#endif
> + struct irq_domain *domain;
> unsigned int gic_irqs;
> #ifdef CONFIG_GIC_NON_BANKED
> void __iomem *(*get_base)(union gic_base *);
> @@ -281,7 +278,7 @@ asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
> irqnr = irqstat & ~0x1c00;
>
> if (likely(irqnr > 15 && irqnr < 1021)) {
> - irqnr = irq_domain_to_irq(&gic->domain, irqnr);
> + irqnr = irq_find_mapping(gic->domain, irqnr);
> handle_IRQ(irqnr, regs);
> continue;
> }
> @@ -313,8 +310,8 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
> if (gic_irq == 1023)
> goto out;
>
> - cascade_irq = irq_domain_to_irq(&chip_data->domain, gic_irq);
> - if (unlikely(gic_irq < 32 || gic_irq > 1020 || cascade_irq >= NR_IRQS))
> + cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
> + if (unlikely(gic_irq < 32 || gic_irq > 1020))
> do_bad_IRQ(cascade_irq, desc);
> else
> generic_handle_irq(cascade_irq);
> @@ -347,10 +344,9 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
>
> static void __init gic_dist_init(struct gic_chip_data *gic)
> {
> - unsigned int i, irq;
> + unsigned int i;
> u32 cpumask;
> unsigned int gic_irqs = gic->gic_irqs;
> - struct irq_domain *domain = &gic->domain;
> void __iomem *base = gic_data_dist_base(gic);
> u32 cpu = 0;
>
> @@ -389,23 +385,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
> for (i = 32; i < gic_irqs; i += 32)
> writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
>
> - /*
> - * Setup the Linux IRQ subsystem.
> - */
> - irq_domain_for_each_irq(domain, i, irq) {
> - if (i < 32) {
> - irq_set_percpu_devid(irq);
> - irq_set_chip_and_handler(irq, &gic_chip,
> - handle_percpu_devid_irq);
> - set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
> - } else {
> - irq_set_chip_and_handler(irq, &gic_chip,
> - handle_fasteoi_irq);
> - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> - }
> - irq_set_chip_data(irq, gic);
> - }
> -
> writel_relaxed(1, base + GIC_DIST_CTRL);
> }
>
> @@ -621,7 +600,23 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
> }
> #endif
>
> -#ifdef CONFIG_OF
> +static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
> + irq_hw_number_t hw)
> +{
> + if (hw < 32) {
> + irq_set_percpu_devid(irq);
> + irq_set_chip_and_handler(irq, &gic_chip,
> + handle_percpu_devid_irq);
> + set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
> + } else {
> + irq_set_chip_and_handler(irq, &gic_chip,
> + handle_fasteoi_irq);
> + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> + }
> + irq_set_chip_data(irq, d->host_data);
> + return 0;
> +}
> +
> static int gic_irq_domain_xlate(struct irq_domain *d,
> struct device_node *controller,
> const u32 *intspec, unsigned int intsize,
> @@ -642,26 +637,23 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
> *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
> return 0;
> }
> -#endif
>
> struct irq_domain_ops gic_irq_domain_ops = {
> -#ifdef CONFIG_OF
> + .map = gic_irq_domain_map,
> .xlate = gic_irq_domain_xlate,
> -#endif
> };
>
> void __init gic_init_bases(unsigned int gic_nr, int irq_start,
> void __iomem *dist_base, void __iomem *cpu_base,
> - u32 percpu_offset)
> + u32 percpu_offset, struct device_node *node)
> {
> + irq_hw_number_t hwirq_base;
> struct gic_chip_data *gic;
> - struct irq_domain *domain;
> int gic_irqs;
>
> BUG_ON(gic_nr >= MAX_GIC_NR);
>
> gic = &gic_data[gic_nr];
> - domain = &gic->domain;
> #ifdef CONFIG_GIC_NON_BANKED
> if (percpu_offset) { /* Frankein-GIC without banked registers... */
> unsigned int cpu;
> @@ -697,10 +689,10 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
> * For primary GICs, skip over SGIs.
> * For secondary GICs, skip over PPIs, too.
> */
> - domain->hwirq_base = 32;
> + hwirq_base = 32;
> if (gic_nr == 0) {
> if ((irq_start & 31) > 0) {
> - domain->hwirq_base = 16;
> + hwirq_base = 16;
> if (irq_start != -1)
> irq_start = (irq_start & ~31) + 16;
> }
> @@ -716,17 +708,11 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
> gic_irqs = 1020;
> gic->gic_irqs = gic_irqs;
>
> - domain->nr_irq = gic_irqs - domain->hwirq_base;
> - domain->irq_base = irq_alloc_descs(irq_start, 16, domain->nr_irq,
> - numa_node_id());
> - if (IS_ERR_VALUE(domain->irq_base)) {
> - WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
> - irq_start);
> - domain->irq_base = irq_start;
> - }
> - domain->host_data = gic;
> - domain->ops = &gic_irq_domain_ops;
> - irq_domain_add(domain);
> + gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_start,
> + hwirq_base, &gic_irq_domain_ops);
> + if (WARN_ON(!gic->domain))
> + return;
> + gic->domain->host_data = gic;
>
> gic_chip.flags |= gic_arch_extn.flags;
> gic_dist_init(gic);
> @@ -771,7 +757,6 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent)
> void __iomem *dist_base;
> u32 percpu_offset;
> int irq;
> - struct irq_domain *domain = &gic_data[gic_cnt].domain;
>
> if (WARN_ON(!node))
> return -ENODEV;
> @@ -785,9 +770,7 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent)
> if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
> percpu_offset = 0;
>
> - domain->of_node = of_node_get(node);
> -
> - gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset);
> + gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node);
>
> if (parent) {
> irq = irq_of_parse_and_map(node, 0);
> diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
> index dcb004a..b9b1827 100644
> --- a/arch/arm/common/vic.c
> +++ b/arch/arm/common/vic.c
> @@ -56,7 +56,7 @@ struct vic_device {
> u32 int_enable;
> u32 soft_int;
> u32 protect;
> - struct irq_domain domain;
> + struct irq_domain *domain;
> };
>
> /* we cannot allocate memory when VICs are initially registered */
> @@ -192,14 +192,8 @@ static void __init vic_register(void __iomem *base, unsigned int irq,
> v->resume_sources = resume_sources;
> v->irq = irq;
> vic_id++;
> -
> - v->domain.irq_base = irq;
> - v->domain.nr_irq = 32;
> -#ifdef CONFIG_OF_IRQ
> - v->domain.of_node = of_node_get(node);
> -#endif /* CONFIG_OF */
> - v->domain.ops = &irq_domain_simple_ops;
> - irq_domain_add(&v->domain);
> + v->domain = irq_domain_add_legacy(node, 32, irq, 0,
> + &irq_domain_simple_ops);
> }
>
> static void vic_ack_irq(struct irq_data *d)
> @@ -348,7 +342,7 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
> vic_register(base, irq_start, 0, node);
> }
>
> -static void __init __vic_init(void __iomem *base, unsigned int irq_start,
> +void __init __vic_init(void __iomem *base, unsigned int irq_start,
> u32 vic_sources, u32 resume_sources,
> struct device_node *node)
> {
> @@ -444,7 +438,7 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs)
> stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
> while (stat) {
> irq = ffs(stat) - 1;
> - handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs);
> + handle_IRQ(irq_find_mapping(vic->domain, irq), regs);
> stat &= ~(1 << irq);
> handled = 1;
> }
> diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
> index 4bdfe00..4b1ce6c 100644
> --- a/arch/arm/include/asm/hardware/gic.h
> +++ b/arch/arm/include/asm/hardware/gic.h
> @@ -39,7 +39,7 @@ struct device_node;
> extern struct irq_chip gic_arch_extn;
>
> void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *,
> - u32 offset);
> + u32 offset, struct device_node *);
> int gic_of_init(struct device_node *node, struct device_node *parent);
> void gic_secondary_init(unsigned int);
> void gic_handle_irq(struct pt_regs *regs);
> @@ -49,7 +49,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
> static inline void gic_init(unsigned int nr, int start,
> void __iomem *dist , void __iomem *cpu)
> {
> - gic_init_bases(nr, start, dist, cpu, 0);
> + gic_init_bases(nr, start, dist, cpu, 0, NULL);
> }
>
> #endif
> diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
> index f42ebd6..e14af1a 100644
> --- a/arch/arm/include/asm/hardware/vic.h
> +++ b/arch/arm/include/asm/hardware/vic.h
> @@ -47,6 +47,8 @@
> struct device_node;
> struct pt_regs;
>
> +void __vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,
> + u32 resume_sources, struct device_node *node);
> void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
> int vic_of_init(struct device_node *node, struct device_node *parent);
> void vic_handle_irq(struct pt_regs *regs);
> diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
> index 0f22997..b0cf428 100644
> --- a/arch/arm/mach-exynos/common.c
> +++ b/arch/arm/mach-exynos/common.c
> @@ -399,7 +399,7 @@ void __init exynos4_init_irq(void)
> gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
>
> if (!of_have_populated_dt())
> - gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset);
> + gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset, NULL);
> #ifdef CONFIG_OF
> else
> of_irq_init(exynos4_dt_irq_match);
> diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
> index 02b7b93..e924f15 100644
> --- a/arch/arm/mach-versatile/core.c
> +++ b/arch/arm/mach-versatile/core.c
> @@ -98,8 +98,9 @@ static const struct of_device_id sic_of_match[] __initconst = {
>
> void __init versatile_init_irq(void)
> {
> - vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0);
> - irq_domain_generate_simple(vic_of_match, VERSATILE_VIC_BASE, IRQ_VIC_START);
> + __vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0,
> + of_find_matching_node_by_address(NULL, vic_of_match,
> + VERSATILE_VIC_BASE));
>
> writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
>
> diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
> index e04e04dd..aab236f 100644
> --- a/drivers/mfd/twl-core.c
> +++ b/drivers/mfd/twl-core.c
> @@ -263,8 +263,6 @@ struct twl_client {
>
> static struct twl_client twl_modules[TWL_NUM_SLAVES];
>
> -static struct irq_domain domain;
> -
> /* mapping the module id to slave id and base address */
> struct twl_mapping {
> unsigned char sid; /* Slave ID */
> @@ -1225,14 +1223,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
>
> pdata->irq_base = status;
> pdata->irq_end = pdata->irq_base + nr_irqs;
> -
> - domain.irq_base = pdata->irq_base;
> - domain.nr_irq = nr_irqs;
> -#ifdef CONFIG_OF_IRQ
> - domain.of_node = of_node_get(node);
> - domain.ops = &irq_domain_simple_ops;
> -#endif
> - irq_domain_add(&domain);
> + irq_domain_add_legacy(node, nr_irqs, pdata->irq_base, 0,
> + &irq_domain_simple_ops);
>
> if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
> dev_dbg(&client->dev, "can't talk I2C?\n");
> diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
> index 6fb3531..7c25e7c 100644
> --- a/include/linux/irqdomain.h
> +++ b/include/linux/irqdomain.h
> @@ -116,20 +116,15 @@ struct irq_domain {
> void *host_data;
> irq_hw_number_t inval_irq;
>
> - unsigned int irq_base;
> - unsigned int nr_irq;
> - unsigned int hwirq_base;
> -
> /* Optional device node pointer */
> struct device_node *of_node;
> };
>
> #ifdef CONFIG_IRQ_DOMAIN
> -#ifdef CONFIG_PPC
> struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
> unsigned int size,
> unsigned int first_irq,
> - unsigned int first_hwirq,
> + irq_hw_number_t first_hwirq,
> struct irq_domain_ops *ops);
> struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
> unsigned int size,
> @@ -146,9 +141,8 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
> struct device_node *of_node,
> struct irq_domain_ops *ops)
> {
> - return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS-1, 1, 1, ops);
> + return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops);
> }
> -
> extern struct irq_domain *irq_find_host(struct device_node *node);
> extern void irq_set_default_host(struct irq_domain *host);
> extern void irq_set_virq_count(unsigned int count);
> @@ -167,38 +161,7 @@ extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
> extern unsigned int irq_linear_revmap(struct irq_domain *host,
> irq_hw_number_t hwirq);
>
> -#else /* CONFIG_PPC */
> -
> -/**
> - * irq_domain_to_irq() - Translate from a hardware irq to a linux irq number
> - *
> - * Returns the linux irq number associated with a hardware irq. By default,
> - * the mapping is irq == domain->irq_base + hwirq, but this mapping can
> - * be overridden if the irq_domain implements a .to_irq() hook.
> - */
> -static inline unsigned int irq_domain_to_irq(struct irq_domain *d,
> - unsigned long hwirq)
> -{
> - if (d->ops->to_irq)
> - return d->ops->to_irq(d, hwirq);
> - if (WARN_ON(hwirq < d->hwirq_base))
> - return 0;
> - return d->irq_base + hwirq - d->hwirq_base;
> -}
> -
> -#define irq_domain_for_each_hwirq(d, hw) \
> - for (hw = d->hwirq_base; hw < d->hwirq_base + d->nr_irq; hw++)
> -
> -#define irq_domain_for_each_irq(d, hw, irq) \
> - for (hw = d->hwirq_base, irq = irq_domain_to_irq(d, hw); \
> - hw < d->hwirq_base + d->nr_irq; \
> - hw++, irq = irq_domain_to_irq(d, hw))
> -
> -extern void irq_domain_add(struct irq_domain *domain);
> -extern void irq_domain_del(struct irq_domain *domain);
> -
> extern struct irq_domain_ops irq_domain_simple_ops;
> -
> #if defined(CONFIG_OF_IRQ)
> extern void irq_domain_add_simple(struct device_node *controller, int irq_base);
> extern void irq_domain_generate_simple(const struct of_device_id *match,
> @@ -207,7 +170,6 @@ extern void irq_domain_generate_simple(const struct of_device_id *match,
> static inline void irq_domain_generate_simple(const struct of_device_id *match,
> u64 phys_base, unsigned int irq_start) { }
> #endif /* !CONFIG_OF_IRQ */
> -#endif /* !CONFIG_PPC */
> #endif /* CONFIG_IRQ_DOMAIN */
>
> #endif /* _LINUX_IRQDOMAIN_H */
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index d4759d0..b90a32e 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -11,7 +11,6 @@
> static LIST_HEAD(irq_domain_list);
> static DEFINE_MUTEX(irq_domain_mutex);
>
> -#ifdef CONFIG_PPC
> static DEFINE_MUTEX(revmap_trees_mutex);
> static unsigned int irq_virq_count = NR_IRQS;
> static struct irq_domain *irq_default_domain;
> @@ -79,7 +78,7 @@ static struct irq_domain *irq_domain_add(struct device_node *of_node,
> struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
> unsigned int size,
> unsigned int first_irq,
> - unsigned int first_hwirq,
> + irq_hw_number_t first_hwirq,
> struct irq_domain_ops *ops)
> {
> struct irq_domain *domain;
> @@ -661,124 +660,11 @@ static int __init irq_debugfs_init(void)
> __initcall(irq_debugfs_init);
> #endif /* CONFIG_VIRQ_DEBUG */
>
> -#else /* CONFIG_PPC */
> -
> -/**
> - * irq_domain_add() - Register an irq_domain
> - * @domain: ptr to initialized irq_domain structure
> - *
> - * Registers an irq_domain structure. The irq_domain must at a minimum be
> - * initialized with an ops structure pointer, and either a ->to_irq hook or
> - * a valid irq_base value. Everything else is optional.
> - */
> -void irq_domain_add(struct irq_domain *domain)
> -{
> - struct irq_data *d;
> - int hwirq, irq;
> -
> - /*
> - * This assumes that the irq_domain owner has already allocated
> - * the irq_descs. This block will be removed when support for dynamic
> - * allocation of irq_descs is added to irq_domain.
> - */
> - irq_domain_for_each_irq(domain, hwirq, irq) {
> - d = irq_get_irq_data(irq);
> - if (!d) {
> - WARN(1, "error: assigning domain to non existant irq_desc");
> - return;
> - }
> - if (d->domain) {
> - /* things are broken; just report, don't clean up */
> - WARN(1, "error: irq_desc already assigned to a domain");
> - return;
> - }
> - d->domain = domain;
> - d->hwirq = hwirq;
> - }
> -
> - mutex_lock(&irq_domain_mutex);
> - list_add(&domain->link, &irq_domain_list);
> - mutex_unlock(&irq_domain_mutex);
> -}
> -
> -/**
> - * irq_domain_del() - Unregister an irq_domain
> - * @domain: ptr to registered irq_domain.
> - */
> -void irq_domain_del(struct irq_domain *domain)
> -{
> - struct irq_data *d;
> - int hwirq, irq;
> -
> - mutex_lock(&irq_domain_mutex);
> - list_del(&domain->link);
> - mutex_unlock(&irq_domain_mutex);
> -
> - /* Clear the irq_domain assignments */
> - irq_domain_for_each_irq(domain, hwirq, irq) {
> - d = irq_get_irq_data(irq);
> - d->domain = NULL;
> - }
> -}
> -
> -#if defined(CONFIG_OF_IRQ)
> -/**
> - * irq_create_of_mapping() - Map a linux irq number from a DT interrupt spec
> - *
> - * Used by the device tree interrupt mapping code to translate a device tree
> - * interrupt specifier to a valid linux irq number. Returns either a valid
> - * linux IRQ number or 0.
> - *
> - * When the caller no longer need the irq number returned by this function it
> - * should arrange to call irq_dispose_mapping().
> - */
> -unsigned int irq_create_of_mapping(struct device_node *controller,
> - const u32 *intspec, unsigned int intsize)
> +int irq_domain_simple_map(struct irq_domain *d, unsigned int irq,
> + irq_hw_number_t hwirq)
> {
> - struct irq_domain *domain;
> - unsigned long hwirq;
> - unsigned int irq, type;
> - int rc = -EINVAL;
> -
> - /* Find a domain which can translate the irq spec */
> - mutex_lock(&irq_domain_mutex);
> - list_for_each_entry(domain, &irq_domain_list, link) {
> - if (!domain->ops->xlate)
> - continue;
> - rc = domain->ops->xlate(domain, controller,
> - intspec, intsize, &hwirq, &type);
> - if (rc == 0)
> - break;
> - }
> - mutex_unlock(&irq_domain_mutex);
> -
> - if (rc != 0)
> - return 0;
> -
> - irq = irq_domain_to_irq(domain, hwirq);
> - if (type != IRQ_TYPE_NONE)
> - irq_set_irq_type(irq, type);
> - pr_debug("%s: mapped hwirq=%i to irq=%i, flags=%x\n",
> - controller->full_name, (int)hwirq, irq, type);
> - return irq;
> -}
> -EXPORT_SYMBOL_GPL(irq_create_of_mapping);
> -
> -/**
> - * irq_dispose_mapping() - Discard a mapping created by irq_create_of_mapping()
> - * @irq: linux irq number to be discarded
> - *
> - * Calling this function indicates the caller no longer needs a reference to
> - * the linux irq number returned by a prior call to irq_create_of_mapping().
> - */
> -void irq_dispose_mapping(unsigned int irq)
> -{
> - /*
> - * nothing yet; will be filled when support for dynamic allocation of
> - * irq_descs is added to irq_domain
> - */
> + return 0;
> }
> -EXPORT_SYMBOL_GPL(irq_dispose_mapping);
>
> int irq_domain_simple_xlate(struct irq_domain *d,
> struct device_node *controller,
> @@ -789,10 +675,6 @@ int irq_domain_simple_xlate(struct irq_domain *d,
> return -EINVAL;
> if (intsize < 1)
> return -EINVAL;
> - if (d->nr_irq && ((intspec[0] < d->hwirq_base) ||
> - (intspec[0] >= d->hwirq_base + d->nr_irq)))
> - return -EINVAL;
> -
> *out_hwirq = intspec[0];
> *out_type = IRQ_TYPE_NONE;
> if (intsize > 1)
> @@ -800,23 +682,17 @@ int irq_domain_simple_xlate(struct irq_domain *d,
> return 0;
> }
>
> -/**
> - * irq_domain_create_simple() - Set up a 'simple' translation range
> - */
> +struct irq_domain_ops irq_domain_simple_ops = {
> + .map = irq_domain_simple_map,
> + .xlate = irq_domain_simple_xlate,
> +};
> +EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
> +
> +#ifdef CONFIG_OF_IRQ
> void irq_domain_add_simple(struct device_node *controller, int irq_base)
> {
> - struct irq_domain *domain;
> -
> - domain = kzalloc(sizeof(*domain), GFP_KERNEL);
> - if (!domain) {
> - WARN_ON(1);
> - return;
> - }
> -
> - domain->irq_base = irq_base;
> - domain->of_node = of_node_get(controller);
> - domain->ops = &irq_domain_simple_ops;
> - irq_domain_add(domain);
> + irq_domain_add_legacy(controller, 32, irq_base, 0,
> + &irq_domain_simple_ops);
> }
> EXPORT_SYMBOL_GPL(irq_domain_add_simple);
>
> @@ -831,13 +707,4 @@ void irq_domain_generate_simple(const struct of_device_id *match,
> irq_domain_add_simple(node, irq_start);
> }
> EXPORT_SYMBOL_GPL(irq_domain_generate_simple);
> -#endif /* CONFIG_OF_IRQ */
> -
> -struct irq_domain_ops irq_domain_simple_ops = {
> -#ifdef CONFIG_OF_IRQ
> - .xlate = irq_domain_simple_xlate,
> -#endif /* CONFIG_OF_IRQ */
> -};
> -EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
> -
> -#endif /* !CONFIG_PPC */
> +#endif
WARNING: multiple messages have this Message-ID (diff)
From: Rob Herring <robherring2@gmail.com>
To: Grant Likely <grant.likely@secretlab.ca>
Cc: linux-kernel@vger.kernel.org,
Benjamin Herrenschmidt <benh@kernel.crashing.org>,
Thomas Gleixner <tglx@linutronix.de>,
linuxppc-dev@lists.ozlabs.org,
Russell King <linux@arm.linux.org.uk>,
sfr@canb.auug.org.au
Subject: Re: [RFC 13/14] irq_domain: Remove 'new' irq_domain in favour of the ppc one
Date: Wed, 11 Jan 2012 15:15:59 -0600 [thread overview]
Message-ID: <4F0DFC0F.2090005@gmail.com> (raw)
In-Reply-To: <1326313337-24603-14-git-send-email-grant.likely@secretlab.ca>
Grant,
On 01/11/2012 02:22 PM, Grant Likely wrote:
> This patch removes the simplistic implementation of irq_domains and enables
> the powerpc infrastructure for all irq_domain users. The powerpc
> infrastructure includes support for complex mappings between Linux and
> hardware irq numbers, and can manage allocation of irq_descs.
>
> This patch also converts the few users of irq_domain_add()/irq_domain_del()
> to call irq_domain_add_legacy() instead.
So what is the non-legacy way? Legacy implies we don't want to do it
that way. I guess until we remove all non-DT platforms with GIC we are
stuck with legacy. That seems like it could be a ways out until we get
there.
Rob
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> arch/arm/common/gic.c | 83 +++++++-----------
> arch/arm/common/vic.c | 16 +---
> arch/arm/include/asm/hardware/gic.h | 4 +-
> arch/arm/include/asm/hardware/vic.h | 2 +
> arch/arm/mach-exynos/common.c | 2 +-
> arch/arm/mach-versatile/core.c | 5 +-
> drivers/mfd/twl-core.c | 12 +--
> include/linux/irqdomain.h | 42 +---------
> kernel/irq/irqdomain.c | 161 +++--------------------------------
> 9 files changed, 64 insertions(+), 263 deletions(-)
>
> diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
> index 156bc03..d839168 100644
> --- a/arch/arm/common/gic.c
> +++ b/arch/arm/common/gic.c
> @@ -50,7 +50,6 @@ union gic_base {
> };
>
> struct gic_chip_data {
> - unsigned int irq_offset;
> union gic_base dist_base;
> union gic_base cpu_base;
> #ifdef CONFIG_CPU_PM
> @@ -60,9 +59,7 @@ struct gic_chip_data {
> u32 __percpu *saved_ppi_enable;
> u32 __percpu *saved_ppi_conf;
> #endif
> -#ifdef CONFIG_IRQ_DOMAIN
> - struct irq_domain domain;
> -#endif
> + struct irq_domain *domain;
> unsigned int gic_irqs;
> #ifdef CONFIG_GIC_NON_BANKED
> void __iomem *(*get_base)(union gic_base *);
> @@ -281,7 +278,7 @@ asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
> irqnr = irqstat & ~0x1c00;
>
> if (likely(irqnr > 15 && irqnr < 1021)) {
> - irqnr = irq_domain_to_irq(&gic->domain, irqnr);
> + irqnr = irq_find_mapping(gic->domain, irqnr);
> handle_IRQ(irqnr, regs);
> continue;
> }
> @@ -313,8 +310,8 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
> if (gic_irq == 1023)
> goto out;
>
> - cascade_irq = irq_domain_to_irq(&chip_data->domain, gic_irq);
> - if (unlikely(gic_irq < 32 || gic_irq > 1020 || cascade_irq >= NR_IRQS))
> + cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
> + if (unlikely(gic_irq < 32 || gic_irq > 1020))
> do_bad_IRQ(cascade_irq, desc);
> else
> generic_handle_irq(cascade_irq);
> @@ -347,10 +344,9 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
>
> static void __init gic_dist_init(struct gic_chip_data *gic)
> {
> - unsigned int i, irq;
> + unsigned int i;
> u32 cpumask;
> unsigned int gic_irqs = gic->gic_irqs;
> - struct irq_domain *domain = &gic->domain;
> void __iomem *base = gic_data_dist_base(gic);
> u32 cpu = 0;
>
> @@ -389,23 +385,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
> for (i = 32; i < gic_irqs; i += 32)
> writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
>
> - /*
> - * Setup the Linux IRQ subsystem.
> - */
> - irq_domain_for_each_irq(domain, i, irq) {
> - if (i < 32) {
> - irq_set_percpu_devid(irq);
> - irq_set_chip_and_handler(irq, &gic_chip,
> - handle_percpu_devid_irq);
> - set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
> - } else {
> - irq_set_chip_and_handler(irq, &gic_chip,
> - handle_fasteoi_irq);
> - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> - }
> - irq_set_chip_data(irq, gic);
> - }
> -
> writel_relaxed(1, base + GIC_DIST_CTRL);
> }
>
> @@ -621,7 +600,23 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
> }
> #endif
>
> -#ifdef CONFIG_OF
> +static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
> + irq_hw_number_t hw)
> +{
> + if (hw < 32) {
> + irq_set_percpu_devid(irq);
> + irq_set_chip_and_handler(irq, &gic_chip,
> + handle_percpu_devid_irq);
> + set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
> + } else {
> + irq_set_chip_and_handler(irq, &gic_chip,
> + handle_fasteoi_irq);
> + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> + }
> + irq_set_chip_data(irq, d->host_data);
> + return 0;
> +}
> +
> static int gic_irq_domain_xlate(struct irq_domain *d,
> struct device_node *controller,
> const u32 *intspec, unsigned int intsize,
> @@ -642,26 +637,23 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
> *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
> return 0;
> }
> -#endif
>
> struct irq_domain_ops gic_irq_domain_ops = {
> -#ifdef CONFIG_OF
> + .map = gic_irq_domain_map,
> .xlate = gic_irq_domain_xlate,
> -#endif
> };
>
> void __init gic_init_bases(unsigned int gic_nr, int irq_start,
> void __iomem *dist_base, void __iomem *cpu_base,
> - u32 percpu_offset)
> + u32 percpu_offset, struct device_node *node)
> {
> + irq_hw_number_t hwirq_base;
> struct gic_chip_data *gic;
> - struct irq_domain *domain;
> int gic_irqs;
>
> BUG_ON(gic_nr >= MAX_GIC_NR);
>
> gic = &gic_data[gic_nr];
> - domain = &gic->domain;
> #ifdef CONFIG_GIC_NON_BANKED
> if (percpu_offset) { /* Frankein-GIC without banked registers... */
> unsigned int cpu;
> @@ -697,10 +689,10 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
> * For primary GICs, skip over SGIs.
> * For secondary GICs, skip over PPIs, too.
> */
> - domain->hwirq_base = 32;
> + hwirq_base = 32;
> if (gic_nr == 0) {
> if ((irq_start & 31) > 0) {
> - domain->hwirq_base = 16;
> + hwirq_base = 16;
> if (irq_start != -1)
> irq_start = (irq_start & ~31) + 16;
> }
> @@ -716,17 +708,11 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
> gic_irqs = 1020;
> gic->gic_irqs = gic_irqs;
>
> - domain->nr_irq = gic_irqs - domain->hwirq_base;
> - domain->irq_base = irq_alloc_descs(irq_start, 16, domain->nr_irq,
> - numa_node_id());
> - if (IS_ERR_VALUE(domain->irq_base)) {
> - WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
> - irq_start);
> - domain->irq_base = irq_start;
> - }
> - domain->host_data = gic;
> - domain->ops = &gic_irq_domain_ops;
> - irq_domain_add(domain);
> + gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_start,
> + hwirq_base, &gic_irq_domain_ops);
> + if (WARN_ON(!gic->domain))
> + return;
> + gic->domain->host_data = gic;
>
> gic_chip.flags |= gic_arch_extn.flags;
> gic_dist_init(gic);
> @@ -771,7 +757,6 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent)
> void __iomem *dist_base;
> u32 percpu_offset;
> int irq;
> - struct irq_domain *domain = &gic_data[gic_cnt].domain;
>
> if (WARN_ON(!node))
> return -ENODEV;
> @@ -785,9 +770,7 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent)
> if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
> percpu_offset = 0;
>
> - domain->of_node = of_node_get(node);
> -
> - gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset);
> + gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node);
>
> if (parent) {
> irq = irq_of_parse_and_map(node, 0);
> diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
> index dcb004a..b9b1827 100644
> --- a/arch/arm/common/vic.c
> +++ b/arch/arm/common/vic.c
> @@ -56,7 +56,7 @@ struct vic_device {
> u32 int_enable;
> u32 soft_int;
> u32 protect;
> - struct irq_domain domain;
> + struct irq_domain *domain;
> };
>
> /* we cannot allocate memory when VICs are initially registered */
> @@ -192,14 +192,8 @@ static void __init vic_register(void __iomem *base, unsigned int irq,
> v->resume_sources = resume_sources;
> v->irq = irq;
> vic_id++;
> -
> - v->domain.irq_base = irq;
> - v->domain.nr_irq = 32;
> -#ifdef CONFIG_OF_IRQ
> - v->domain.of_node = of_node_get(node);
> -#endif /* CONFIG_OF */
> - v->domain.ops = &irq_domain_simple_ops;
> - irq_domain_add(&v->domain);
> + v->domain = irq_domain_add_legacy(node, 32, irq, 0,
> + &irq_domain_simple_ops);
> }
>
> static void vic_ack_irq(struct irq_data *d)
> @@ -348,7 +342,7 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
> vic_register(base, irq_start, 0, node);
> }
>
> -static void __init __vic_init(void __iomem *base, unsigned int irq_start,
> +void __init __vic_init(void __iomem *base, unsigned int irq_start,
> u32 vic_sources, u32 resume_sources,
> struct device_node *node)
> {
> @@ -444,7 +438,7 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs)
> stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
> while (stat) {
> irq = ffs(stat) - 1;
> - handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs);
> + handle_IRQ(irq_find_mapping(vic->domain, irq), regs);
> stat &= ~(1 << irq);
> handled = 1;
> }
> diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
> index 4bdfe00..4b1ce6c 100644
> --- a/arch/arm/include/asm/hardware/gic.h
> +++ b/arch/arm/include/asm/hardware/gic.h
> @@ -39,7 +39,7 @@ struct device_node;
> extern struct irq_chip gic_arch_extn;
>
> void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *,
> - u32 offset);
> + u32 offset, struct device_node *);
> int gic_of_init(struct device_node *node, struct device_node *parent);
> void gic_secondary_init(unsigned int);
> void gic_handle_irq(struct pt_regs *regs);
> @@ -49,7 +49,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
> static inline void gic_init(unsigned int nr, int start,
> void __iomem *dist , void __iomem *cpu)
> {
> - gic_init_bases(nr, start, dist, cpu, 0);
> + gic_init_bases(nr, start, dist, cpu, 0, NULL);
> }
>
> #endif
> diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
> index f42ebd6..e14af1a 100644
> --- a/arch/arm/include/asm/hardware/vic.h
> +++ b/arch/arm/include/asm/hardware/vic.h
> @@ -47,6 +47,8 @@
> struct device_node;
> struct pt_regs;
>
> +void __vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,
> + u32 resume_sources, struct device_node *node);
> void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
> int vic_of_init(struct device_node *node, struct device_node *parent);
> void vic_handle_irq(struct pt_regs *regs);
> diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
> index 0f22997..b0cf428 100644
> --- a/arch/arm/mach-exynos/common.c
> +++ b/arch/arm/mach-exynos/common.c
> @@ -399,7 +399,7 @@ void __init exynos4_init_irq(void)
> gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
>
> if (!of_have_populated_dt())
> - gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset);
> + gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset, NULL);
> #ifdef CONFIG_OF
> else
> of_irq_init(exynos4_dt_irq_match);
> diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
> index 02b7b93..e924f15 100644
> --- a/arch/arm/mach-versatile/core.c
> +++ b/arch/arm/mach-versatile/core.c
> @@ -98,8 +98,9 @@ static const struct of_device_id sic_of_match[] __initconst = {
>
> void __init versatile_init_irq(void)
> {
> - vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0);
> - irq_domain_generate_simple(vic_of_match, VERSATILE_VIC_BASE, IRQ_VIC_START);
> + __vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0,
> + of_find_matching_node_by_address(NULL, vic_of_match,
> + VERSATILE_VIC_BASE));
>
> writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
>
> diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
> index e04e04dd..aab236f 100644
> --- a/drivers/mfd/twl-core.c
> +++ b/drivers/mfd/twl-core.c
> @@ -263,8 +263,6 @@ struct twl_client {
>
> static struct twl_client twl_modules[TWL_NUM_SLAVES];
>
> -static struct irq_domain domain;
> -
> /* mapping the module id to slave id and base address */
> struct twl_mapping {
> unsigned char sid; /* Slave ID */
> @@ -1225,14 +1223,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
>
> pdata->irq_base = status;
> pdata->irq_end = pdata->irq_base + nr_irqs;
> -
> - domain.irq_base = pdata->irq_base;
> - domain.nr_irq = nr_irqs;
> -#ifdef CONFIG_OF_IRQ
> - domain.of_node = of_node_get(node);
> - domain.ops = &irq_domain_simple_ops;
> -#endif
> - irq_domain_add(&domain);
> + irq_domain_add_legacy(node, nr_irqs, pdata->irq_base, 0,
> + &irq_domain_simple_ops);
>
> if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
> dev_dbg(&client->dev, "can't talk I2C?\n");
> diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
> index 6fb3531..7c25e7c 100644
> --- a/include/linux/irqdomain.h
> +++ b/include/linux/irqdomain.h
> @@ -116,20 +116,15 @@ struct irq_domain {
> void *host_data;
> irq_hw_number_t inval_irq;
>
> - unsigned int irq_base;
> - unsigned int nr_irq;
> - unsigned int hwirq_base;
> -
> /* Optional device node pointer */
> struct device_node *of_node;
> };
>
> #ifdef CONFIG_IRQ_DOMAIN
> -#ifdef CONFIG_PPC
> struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
> unsigned int size,
> unsigned int first_irq,
> - unsigned int first_hwirq,
> + irq_hw_number_t first_hwirq,
> struct irq_domain_ops *ops);
> struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
> unsigned int size,
> @@ -146,9 +141,8 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
> struct device_node *of_node,
> struct irq_domain_ops *ops)
> {
> - return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS-1, 1, 1, ops);
> + return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops);
> }
> -
> extern struct irq_domain *irq_find_host(struct device_node *node);
> extern void irq_set_default_host(struct irq_domain *host);
> extern void irq_set_virq_count(unsigned int count);
> @@ -167,38 +161,7 @@ extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
> extern unsigned int irq_linear_revmap(struct irq_domain *host,
> irq_hw_number_t hwirq);
>
> -#else /* CONFIG_PPC */
> -
> -/**
> - * irq_domain_to_irq() - Translate from a hardware irq to a linux irq number
> - *
> - * Returns the linux irq number associated with a hardware irq. By default,
> - * the mapping is irq == domain->irq_base + hwirq, but this mapping can
> - * be overridden if the irq_domain implements a .to_irq() hook.
> - */
> -static inline unsigned int irq_domain_to_irq(struct irq_domain *d,
> - unsigned long hwirq)
> -{
> - if (d->ops->to_irq)
> - return d->ops->to_irq(d, hwirq);
> - if (WARN_ON(hwirq < d->hwirq_base))
> - return 0;
> - return d->irq_base + hwirq - d->hwirq_base;
> -}
> -
> -#define irq_domain_for_each_hwirq(d, hw) \
> - for (hw = d->hwirq_base; hw < d->hwirq_base + d->nr_irq; hw++)
> -
> -#define irq_domain_for_each_irq(d, hw, irq) \
> - for (hw = d->hwirq_base, irq = irq_domain_to_irq(d, hw); \
> - hw < d->hwirq_base + d->nr_irq; \
> - hw++, irq = irq_domain_to_irq(d, hw))
> -
> -extern void irq_domain_add(struct irq_domain *domain);
> -extern void irq_domain_del(struct irq_domain *domain);
> -
> extern struct irq_domain_ops irq_domain_simple_ops;
> -
> #if defined(CONFIG_OF_IRQ)
> extern void irq_domain_add_simple(struct device_node *controller, int irq_base);
> extern void irq_domain_generate_simple(const struct of_device_id *match,
> @@ -207,7 +170,6 @@ extern void irq_domain_generate_simple(const struct of_device_id *match,
> static inline void irq_domain_generate_simple(const struct of_device_id *match,
> u64 phys_base, unsigned int irq_start) { }
> #endif /* !CONFIG_OF_IRQ */
> -#endif /* !CONFIG_PPC */
> #endif /* CONFIG_IRQ_DOMAIN */
>
> #endif /* _LINUX_IRQDOMAIN_H */
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index d4759d0..b90a32e 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -11,7 +11,6 @@
> static LIST_HEAD(irq_domain_list);
> static DEFINE_MUTEX(irq_domain_mutex);
>
> -#ifdef CONFIG_PPC
> static DEFINE_MUTEX(revmap_trees_mutex);
> static unsigned int irq_virq_count = NR_IRQS;
> static struct irq_domain *irq_default_domain;
> @@ -79,7 +78,7 @@ static struct irq_domain *irq_domain_add(struct device_node *of_node,
> struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
> unsigned int size,
> unsigned int first_irq,
> - unsigned int first_hwirq,
> + irq_hw_number_t first_hwirq,
> struct irq_domain_ops *ops)
> {
> struct irq_domain *domain;
> @@ -661,124 +660,11 @@ static int __init irq_debugfs_init(void)
> __initcall(irq_debugfs_init);
> #endif /* CONFIG_VIRQ_DEBUG */
>
> -#else /* CONFIG_PPC */
> -
> -/**
> - * irq_domain_add() - Register an irq_domain
> - * @domain: ptr to initialized irq_domain structure
> - *
> - * Registers an irq_domain structure. The irq_domain must at a minimum be
> - * initialized with an ops structure pointer, and either a ->to_irq hook or
> - * a valid irq_base value. Everything else is optional.
> - */
> -void irq_domain_add(struct irq_domain *domain)
> -{
> - struct irq_data *d;
> - int hwirq, irq;
> -
> - /*
> - * This assumes that the irq_domain owner has already allocated
> - * the irq_descs. This block will be removed when support for dynamic
> - * allocation of irq_descs is added to irq_domain.
> - */
> - irq_domain_for_each_irq(domain, hwirq, irq) {
> - d = irq_get_irq_data(irq);
> - if (!d) {
> - WARN(1, "error: assigning domain to non existant irq_desc");
> - return;
> - }
> - if (d->domain) {
> - /* things are broken; just report, don't clean up */
> - WARN(1, "error: irq_desc already assigned to a domain");
> - return;
> - }
> - d->domain = domain;
> - d->hwirq = hwirq;
> - }
> -
> - mutex_lock(&irq_domain_mutex);
> - list_add(&domain->link, &irq_domain_list);
> - mutex_unlock(&irq_domain_mutex);
> -}
> -
> -/**
> - * irq_domain_del() - Unregister an irq_domain
> - * @domain: ptr to registered irq_domain.
> - */
> -void irq_domain_del(struct irq_domain *domain)
> -{
> - struct irq_data *d;
> - int hwirq, irq;
> -
> - mutex_lock(&irq_domain_mutex);
> - list_del(&domain->link);
> - mutex_unlock(&irq_domain_mutex);
> -
> - /* Clear the irq_domain assignments */
> - irq_domain_for_each_irq(domain, hwirq, irq) {
> - d = irq_get_irq_data(irq);
> - d->domain = NULL;
> - }
> -}
> -
> -#if defined(CONFIG_OF_IRQ)
> -/**
> - * irq_create_of_mapping() - Map a linux irq number from a DT interrupt spec
> - *
> - * Used by the device tree interrupt mapping code to translate a device tree
> - * interrupt specifier to a valid linux irq number. Returns either a valid
> - * linux IRQ number or 0.
> - *
> - * When the caller no longer need the irq number returned by this function it
> - * should arrange to call irq_dispose_mapping().
> - */
> -unsigned int irq_create_of_mapping(struct device_node *controller,
> - const u32 *intspec, unsigned int intsize)
> +int irq_domain_simple_map(struct irq_domain *d, unsigned int irq,
> + irq_hw_number_t hwirq)
> {
> - struct irq_domain *domain;
> - unsigned long hwirq;
> - unsigned int irq, type;
> - int rc = -EINVAL;
> -
> - /* Find a domain which can translate the irq spec */
> - mutex_lock(&irq_domain_mutex);
> - list_for_each_entry(domain, &irq_domain_list, link) {
> - if (!domain->ops->xlate)
> - continue;
> - rc = domain->ops->xlate(domain, controller,
> - intspec, intsize, &hwirq, &type);
> - if (rc == 0)
> - break;
> - }
> - mutex_unlock(&irq_domain_mutex);
> -
> - if (rc != 0)
> - return 0;
> -
> - irq = irq_domain_to_irq(domain, hwirq);
> - if (type != IRQ_TYPE_NONE)
> - irq_set_irq_type(irq, type);
> - pr_debug("%s: mapped hwirq=%i to irq=%i, flags=%x\n",
> - controller->full_name, (int)hwirq, irq, type);
> - return irq;
> -}
> -EXPORT_SYMBOL_GPL(irq_create_of_mapping);
> -
> -/**
> - * irq_dispose_mapping() - Discard a mapping created by irq_create_of_mapping()
> - * @irq: linux irq number to be discarded
> - *
> - * Calling this function indicates the caller no longer needs a reference to
> - * the linux irq number returned by a prior call to irq_create_of_mapping().
> - */
> -void irq_dispose_mapping(unsigned int irq)
> -{
> - /*
> - * nothing yet; will be filled when support for dynamic allocation of
> - * irq_descs is added to irq_domain
> - */
> + return 0;
> }
> -EXPORT_SYMBOL_GPL(irq_dispose_mapping);
>
> int irq_domain_simple_xlate(struct irq_domain *d,
> struct device_node *controller,
> @@ -789,10 +675,6 @@ int irq_domain_simple_xlate(struct irq_domain *d,
> return -EINVAL;
> if (intsize < 1)
> return -EINVAL;
> - if (d->nr_irq && ((intspec[0] < d->hwirq_base) ||
> - (intspec[0] >= d->hwirq_base + d->nr_irq)))
> - return -EINVAL;
> -
> *out_hwirq = intspec[0];
> *out_type = IRQ_TYPE_NONE;
> if (intsize > 1)
> @@ -800,23 +682,17 @@ int irq_domain_simple_xlate(struct irq_domain *d,
> return 0;
> }
>
> -/**
> - * irq_domain_create_simple() - Set up a 'simple' translation range
> - */
> +struct irq_domain_ops irq_domain_simple_ops = {
> + .map = irq_domain_simple_map,
> + .xlate = irq_domain_simple_xlate,
> +};
> +EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
> +
> +#ifdef CONFIG_OF_IRQ
> void irq_domain_add_simple(struct device_node *controller, int irq_base)
> {
> - struct irq_domain *domain;
> -
> - domain = kzalloc(sizeof(*domain), GFP_KERNEL);
> - if (!domain) {
> - WARN_ON(1);
> - return;
> - }
> -
> - domain->irq_base = irq_base;
> - domain->of_node = of_node_get(controller);
> - domain->ops = &irq_domain_simple_ops;
> - irq_domain_add(domain);
> + irq_domain_add_legacy(controller, 32, irq_base, 0,
> + &irq_domain_simple_ops);
> }
> EXPORT_SYMBOL_GPL(irq_domain_add_simple);
>
> @@ -831,13 +707,4 @@ void irq_domain_generate_simple(const struct of_device_id *match,
> irq_domain_add_simple(node, irq_start);
> }
> EXPORT_SYMBOL_GPL(irq_domain_generate_simple);
> -#endif /* CONFIG_OF_IRQ */
> -
> -struct irq_domain_ops irq_domain_simple_ops = {
> -#ifdef CONFIG_OF_IRQ
> - .xlate = irq_domain_simple_xlate,
> -#endif /* CONFIG_OF_IRQ */
> -};
> -EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
> -
> -#endif /* !CONFIG_PPC */
> +#endif
next prev parent reply other threads:[~2012-01-11 21:16 UTC|newest]
Thread overview: 84+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-11 20:22 [RFC 0/14] Finish up irq_domain generalization Grant Likely
2012-01-11 20:22 ` [RFC 01/14] dt: Make irqdomain less verbose Grant Likely
2012-01-11 20:22 ` Grant Likely
2012-01-11 20:22 ` [RFC 02/14] irq_domain: Make irq_domain structure match powerpc's irq_host Grant Likely
2012-01-11 20:22 ` Grant Likely
2012-01-11 20:22 ` [RFC 03/14] irq_domain: convert microblaze from irq_host to irq_domain Grant Likely
2012-01-11 20:22 ` Grant Likely
2012-01-11 20:22 ` [RFC 04/14] irq_domain/powerpc: Use common irq_domain structure instead of irq_host Grant Likely
2012-01-11 20:22 ` Grant Likely
2012-01-11 20:22 ` [RFC 05/14] irq_domain/powerpc: eliminate irq_map; use irq_alloc_desc() instead Grant Likely
2012-01-11 20:22 ` Grant Likely
2012-01-11 20:22 ` [RFC 06/14] irq_domain/powerpc: Eliminate virq_is_host() Grant Likely
2012-01-11 20:22 ` Grant Likely
2012-01-12 10:17 ` Milton Miller
2012-01-18 0:38 ` Grant Likely
2012-01-18 0:38 ` Grant Likely
2012-01-18 21:25 ` Grant Likely
2012-01-11 20:22 ` [RFC 07/14] irq_domain: Move irq_domain code from powerpc to kernel/irq Grant Likely
2012-01-11 20:22 ` Grant Likely
2012-01-11 20:22 ` [RFC 08/14] irqdomain: remove NO_IRQ from irq domain code Grant Likely
2012-01-11 20:22 ` Grant Likely
2012-01-11 20:22 ` [RFC 09/14] irq_domain: Remove references to old irq_host names Grant Likely
2012-01-11 20:22 ` Grant Likely
2012-01-11 20:22 ` [RFC 10/14] irq_domain: Replace irq_alloc_host() with revmap-specific initializers Grant Likely
2012-01-11 20:22 ` Grant Likely
2012-01-11 20:22 ` [RFC 11/14] powerpc: Eliminate NO_IRQ usage Grant Likely
2012-01-11 20:22 ` Grant Likely
2013-07-25 21:58 ` Geert Uytterhoeven
2013-07-25 21:58 ` Geert Uytterhoeven
2013-07-26 3:56 ` Grant Likely
2013-07-26 3:56 ` Grant Likely
2013-08-23 13:18 ` Geert Uytterhoeven
2013-08-23 13:18 ` Geert Uytterhoeven
2013-08-23 13:22 ` Geert Uytterhoeven
2013-08-23 13:22 ` Geert Uytterhoeven
2012-01-11 20:22 ` [RFC 12/14] irq_domain: Add support for base irq and hwirq in legacy mappings Grant Likely
2012-01-11 20:22 ` Grant Likely
2012-01-13 0:37 ` Rob Herring
2012-01-13 0:37 ` Rob Herring
2012-01-13 0:53 ` Grant Likely
2012-01-13 0:53 ` Grant Likely
2012-01-11 20:22 ` [RFC 13/14] irq_domain: Remove 'new' irq_domain in favour of the ppc one Grant Likely
2012-01-11 20:22 ` Grant Likely
2012-01-11 21:15 ` Rob Herring [this message]
2012-01-11 21:15 ` Rob Herring
2012-01-11 21:27 ` Grant Likely
2012-01-11 21:27 ` Grant Likely
2012-01-13 0:31 ` Rob Herring
2012-01-13 0:31 ` Rob Herring
2012-01-13 0:31 ` Rob Herring
2012-01-13 0:47 ` Grant Likely
2012-01-13 0:47 ` Grant Likely
2012-01-13 0:47 ` Grant Likely
2012-01-13 0:53 ` Rob Herring
2012-01-13 0:53 ` Rob Herring
2012-01-13 0:53 ` Rob Herring
2012-01-13 2:20 ` Grant Likely
2012-01-13 2:20 ` Grant Likely
2012-01-13 2:20 ` Grant Likely
2012-01-17 2:43 ` Michael Bohan
2012-01-17 2:43 ` Michael Bohan
2012-01-17 2:43 ` Michael Bohan
2012-01-17 2:43 ` Michael Bohan
2012-01-17 3:42 ` Benjamin Herrenschmidt
2012-01-17 3:42 ` Benjamin Herrenschmidt
2012-01-17 3:42 ` Benjamin Herrenschmidt
2012-01-18 0:28 ` Grant Likely
2012-01-18 0:28 ` Grant Likely
2012-01-18 0:28 ` Grant Likely
2012-01-18 2:16 ` Benjamin Herrenschmidt
2012-01-18 2:16 ` Benjamin Herrenschmidt
2012-01-18 2:16 ` Benjamin Herrenschmidt
2012-01-18 6:50 ` Grant Likely
2012-01-18 6:50 ` Grant Likely
2012-01-11 20:22 ` [RFC 14/14] irq_domain: Remove irq_domain_add_simple() Grant Likely
2012-01-11 20:22 ` Grant Likely
2012-01-11 21:39 ` [RFC 0/14] Finish up irq_domain generalization Randy Dunlap
2012-01-11 21:39 ` Randy Dunlap
2012-01-11 20:50 ` Grant Likely
2012-01-11 20:50 ` Grant Likely
2012-01-11 21:23 ` Grant Likely
2012-01-11 21:23 ` Grant Likely
2012-01-11 22:48 ` Randy Dunlap
2012-01-11 22:48 ` Randy Dunlap
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=4F0DFC0F.2090005@gmail.com \
--to=robherring2@gmail.com \
--cc=grant.likely@secretlab.ca \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@arm.linux.org.uk \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=sfr@canb.auug.org.au \
--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.