Commit 6fa6c8e2 authored by Grant Likely's avatar Grant Likely

irq_domain: Move irq_virq_count into NOMAP revmap

This patch replaces the old global setting of irq_virq_count that is only
used by the NOMAP mapping and instead uses a revmap_data property so that
the maximum NOMAP allocation can be set per NOMAP irq_domain.

There is exactly one user of irq_virq_count in-tree right now: PS3.
Also, irq_virq_count is only useful for the NOMAP mapping.  So,
instead of having a single global irq_virq_count values, this change
drops it entirely and added a max_irq argument to irq_domain_add_nomap().
That makes it a property of an individual nomap irq domain instead of
a global system settting.
Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
Tested-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>
parent 15e06bf6
...@@ -392,7 +392,7 @@ static int axon_msi_probe(struct platform_device *device) ...@@ -392,7 +392,7 @@ static int axon_msi_probe(struct platform_device *device)
} }
memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
msic->irq_domain = irq_domain_add_nomap(dn, &msic_host_ops, msic); msic->irq_domain = irq_domain_add_nomap(dn, 0, &msic_host_ops, msic);
if (!msic->irq_domain) { if (!msic->irq_domain) {
printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n", printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
dn->full_name); dn->full_name);
......
...@@ -239,7 +239,7 @@ void __init beatic_init_IRQ(void) ...@@ -239,7 +239,7 @@ void __init beatic_init_IRQ(void)
ppc_md.get_irq = beatic_get_irq; ppc_md.get_irq = beatic_get_irq;
/* Allocate an irq host */ /* Allocate an irq host */
beatic_host = irq_domain_add_nomap(NULL, &beatic_pic_host_ops, NULL); beatic_host = irq_domain_add_nomap(NULL, 0, &beatic_pic_host_ops, NULL);
BUG_ON(beatic_host == NULL); BUG_ON(beatic_host == NULL);
irq_set_default_host(beatic_host); irq_set_default_host(beatic_host);
} }
......
...@@ -192,7 +192,7 @@ static int psurge_secondary_ipi_init(void) ...@@ -192,7 +192,7 @@ static int psurge_secondary_ipi_init(void)
{ {
int rc = -ENOMEM; int rc = -ENOMEM;
psurge_host = irq_domain_add_nomap(NULL, &psurge_host_ops, NULL); psurge_host = irq_domain_add_nomap(NULL, 0, &psurge_host_ops, NULL);
if (psurge_host) if (psurge_host)
psurge_secondary_virq = irq_create_direct_mapping(psurge_host); psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
......
...@@ -753,9 +753,8 @@ void __init ps3_init_IRQ(void) ...@@ -753,9 +753,8 @@ void __init ps3_init_IRQ(void)
unsigned cpu; unsigned cpu;
struct irq_domain *host; struct irq_domain *host;
host = irq_domain_add_nomap(NULL, &ps3_host_ops, NULL); host = irq_domain_add_nomap(NULL, PS3_PLUG_MAX + 1, &ps3_host_ops, NULL);
irq_set_default_host(host); irq_set_default_host(host);
irq_set_virq_count(PS3_PLUG_MAX + 1);
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
struct ps3_private *pd = &per_cpu(ps3_private, cpu); struct ps3_private *pd = &per_cpu(ps3_private, cpu);
......
...@@ -98,6 +98,9 @@ struct irq_domain { ...@@ -98,6 +98,9 @@ struct irq_domain {
unsigned int size; unsigned int size;
unsigned int *revmap; unsigned int *revmap;
} linear; } linear;
struct {
unsigned int max_irq;
} nomap;
struct radix_tree_root tree; struct radix_tree_root tree;
} revmap_data; } revmap_data;
const struct irq_domain_ops *ops; const struct irq_domain_ops *ops;
...@@ -120,6 +123,7 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node, ...@@ -120,6 +123,7 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
const struct irq_domain_ops *ops, const struct irq_domain_ops *ops,
void *host_data); void *host_data);
struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
unsigned int max_irq,
const struct irq_domain_ops *ops, const struct irq_domain_ops *ops,
void *host_data); void *host_data);
struct irq_domain *irq_domain_add_tree(struct device_node *of_node, struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
...@@ -128,7 +132,6 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node, ...@@ -128,7 +132,6 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
extern struct irq_domain *irq_find_host(struct device_node *node); 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_default_host(struct irq_domain *host);
extern void irq_set_virq_count(unsigned int count);
static inline struct irq_domain *irq_domain_add_legacy_isa( static inline struct irq_domain *irq_domain_add_legacy_isa(
struct device_node *of_node, struct device_node *of_node,
...@@ -140,7 +143,6 @@ static inline struct irq_domain *irq_domain_add_legacy_isa( ...@@ -140,7 +143,6 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
} }
extern struct irq_domain *irq_find_host(struct device_node *node); 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_default_host(struct irq_domain *host);
extern void irq_set_virq_count(unsigned int count);
extern unsigned int irq_create_mapping(struct irq_domain *host, extern unsigned int irq_create_mapping(struct irq_domain *host,
......
...@@ -23,7 +23,6 @@ static LIST_HEAD(irq_domain_list); ...@@ -23,7 +23,6 @@ static LIST_HEAD(irq_domain_list);
static DEFINE_MUTEX(irq_domain_mutex); static DEFINE_MUTEX(irq_domain_mutex);
static DEFINE_MUTEX(revmap_trees_mutex); static DEFINE_MUTEX(revmap_trees_mutex);
static unsigned int irq_virq_count = NR_IRQS;
static struct irq_domain *irq_default_domain; static struct irq_domain *irq_default_domain;
/** /**
...@@ -184,13 +183,16 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node, ...@@ -184,13 +183,16 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
} }
struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
unsigned int max_irq,
const struct irq_domain_ops *ops, const struct irq_domain_ops *ops,
void *host_data) void *host_data)
{ {
struct irq_domain *domain = irq_domain_alloc(of_node, struct irq_domain *domain = irq_domain_alloc(of_node,
IRQ_DOMAIN_MAP_NOMAP, ops, host_data); IRQ_DOMAIN_MAP_NOMAP, ops, host_data);
if (domain) if (domain) {
domain->revmap_data.nomap.max_irq = max_irq ? max_irq : ~0;
irq_domain_add(domain); irq_domain_add(domain);
}
return domain; return domain;
} }
...@@ -262,22 +264,6 @@ void irq_set_default_host(struct irq_domain *domain) ...@@ -262,22 +264,6 @@ void irq_set_default_host(struct irq_domain *domain)
irq_default_domain = domain; irq_default_domain = domain;
} }
/**
* irq_set_virq_count() - Set the maximum number of linux irqs
* @count: number of linux irqs, capped with NR_IRQS
*
* This is mainly for use by platforms like iSeries who want to program
* the virtual irq number in the controller to avoid the reverse mapping
*/
void irq_set_virq_count(unsigned int count)
{
pr_debug("irq: Trying to set virq count to %d\n", count);
BUG_ON(count < NUM_ISA_INTERRUPTS);
if (count < NR_IRQS)
irq_virq_count = count;
}
static int irq_setup_virq(struct irq_domain *domain, unsigned int virq, static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
irq_hw_number_t hwirq) irq_hw_number_t hwirq)
{ {
...@@ -320,13 +306,12 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain) ...@@ -320,13 +306,12 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
pr_debug("irq: create_direct virq allocation failed\n"); pr_debug("irq: create_direct virq allocation failed\n");
return 0; return 0;
} }
if (virq >= irq_virq_count) { if (virq >= domain->revmap_data.nomap.max_irq) {
pr_err("ERROR: no free irqs available below %i maximum\n", pr_err("ERROR: no free irqs available below %i maximum\n",
irq_virq_count); domain->revmap_data.nomap.max_irq);
irq_free_desc(virq); irq_free_desc(virq);
return 0; return 0;
} }
pr_debug("irq: create_direct obtained virq %d\n", virq); pr_debug("irq: create_direct obtained virq %d\n", virq);
if (irq_setup_virq(domain, virq, virq)) { if (irq_setup_virq(domain, virq, virq)) {
...@@ -378,7 +363,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain, ...@@ -378,7 +363,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
return irq_domain_legacy_revmap(domain, hwirq); return irq_domain_legacy_revmap(domain, hwirq);
/* Allocate a virtual interrupt number */ /* Allocate a virtual interrupt number */
hint = hwirq % irq_virq_count; hint = hwirq % nr_irqs;
if (hint == 0) if (hint == 0)
hint++; hint++;
virq = irq_alloc_desc_from(hint, 0); virq = irq_alloc_desc_from(hint, 0);
...@@ -516,7 +501,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain, ...@@ -516,7 +501,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
irq_hw_number_t hwirq) irq_hw_number_t hwirq)
{ {
unsigned int i; unsigned int i;
unsigned int hint = hwirq % irq_virq_count; unsigned int hint = hwirq % nr_irqs;
/* Look for default domain if nececssary */ /* Look for default domain if nececssary */
if (domain == NULL) if (domain == NULL)
...@@ -537,7 +522,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain, ...@@ -537,7 +522,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
if (data && (data->domain == domain) && (data->hwirq == hwirq)) if (data && (data->domain == domain) && (data->hwirq == hwirq))
return i; return i;
i++; i++;
if (i >= irq_virq_count) if (i >= nr_irqs)
i = 1; i = 1;
} while(i != hint); } while(i != hint);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment