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: Grant Likely <grant.likely@secretlab.ca> Tested-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Milton Miller <miltonm@bga.com>
This commit is contained in:
parent
15e06bf64f
commit
6fa6c8e25e
@ -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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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 {
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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(
|
|||||||
}
|
}
|
||||||
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);
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user