提交 7e066489 编写于 作者: L Linus Torvalds

Merge tag 'irqdomain-for-linus' of git://git.secretlab.ca/git/linux-2.6

Pull irqdomain bug fixes from Grant Likely:
 "This branch fixes a bug in irq_create_mapping() where an error return
  from irq_alloc_desc_from() gets ignored.

  It also removes irq_virq_count to fix a bug on powerpc where the
  irqdomain code does not find irqs allocated above the CONFIG_NR_IRQS
  boundary.

  The remaining patches get rid of an completely pointless export and
  fix some minor bugs in the irqdomain debug output."

* tag 'irqdomain-for-linus' of git://git.secretlab.ca/git/linux-2.6:
  irq_domain: Move irq_virq_count into NOMAP revmap
  irqdomain: Fix debugfs formatting
  irq_domain: correct the debugfs file name
  irq: Kill pointless irqd_to_hw export
  irq/irq_domain: Quit ignoring error returns from irq_alloc_desc_from().
...@@ -42,10 +42,6 @@ ...@@ -42,10 +42,6 @@
/* This number is used when no interrupt has been assigned */ /* This number is used when no interrupt has been assigned */
#define NO_IRQ 0 #define NO_IRQ 0
struct irq_data;
extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
extern irq_hw_number_t virq_to_hw(unsigned int virq);
extern void __init init_pic_c64xplus(void); extern void __init init_pic_c64xplus(void);
extern void init_IRQ(void); extern void init_IRQ(void);
......
...@@ -130,16 +130,3 @@ int arch_show_interrupts(struct seq_file *p, int prec) ...@@ -130,16 +130,3 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count); seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
return 0; return 0;
} }
irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
{
return d->hwirq;
}
EXPORT_SYMBOL_GPL(irqd_to_hwirq);
irq_hw_number_t virq_to_hw(unsigned int virq)
{
struct irq_data *irq_data = irq_get_irq_data(virq);
return WARN_ON(!irq_data) ? 0 : irq_data->hwirq;
}
EXPORT_SYMBOL_GPL(virq_to_hw);
...@@ -33,8 +33,6 @@ extern atomic_t ppc_n_lost_interrupts; ...@@ -33,8 +33,6 @@ extern atomic_t ppc_n_lost_interrupts;
/* Same thing, used by the generic IRQ code */ /* Same thing, used by the generic IRQ code */
#define NR_IRQS_LEGACY NUM_ISA_INTERRUPTS #define NR_IRQS_LEGACY NUM_ISA_INTERRUPTS
struct irq_data;
extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
extern irq_hw_number_t virq_to_hw(unsigned int virq); extern irq_hw_number_t virq_to_hw(unsigned int virq);
/** /**
......
...@@ -560,12 +560,6 @@ void do_softirq(void) ...@@ -560,12 +560,6 @@ void do_softirq(void)
local_irq_restore(flags); local_irq_restore(flags);
} }
irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
{
return d->hwirq;
}
EXPORT_SYMBOL_GPL(irqd_to_hwirq);
irq_hw_number_t virq_to_hw(unsigned int virq) irq_hw_number_t virq_to_hw(unsigned int virq)
{ {
struct irq_data *irq_data = irq_get_irq_data(virq); struct irq_data *irq_data = irq_get_irq_data(virq);
......
...@@ -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);
......
...@@ -263,6 +263,11 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) ...@@ -263,6 +263,11 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS; d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS;
} }
static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
{
return d->hwirq;
}
/** /**
* struct irq_chip - hardware interrupt chip descriptor * struct irq_chip - hardware interrupt chip descriptor
* *
......
...@@ -42,12 +42,6 @@ struct of_device_id; ...@@ -42,12 +42,6 @@ struct of_device_id;
/* Number of irqs reserved for a legacy isa controller */ /* Number of irqs reserved for a legacy isa controller */
#define NUM_ISA_INTERRUPTS 16 #define NUM_ISA_INTERRUPTS 16
/* This type is the placeholder for a hardware interrupt number. It has to
* be big enough to enclose whatever representation is used by a given
* platform.
*/
typedef unsigned long irq_hw_number_t;
/** /**
* struct irq_domain_ops - Methods for irq_domain objects * struct irq_domain_ops - Methods for irq_domain objects
* @match: Match an interrupt controller device node to a host, returns * @match: Match an interrupt controller device node to a host, returns
...@@ -104,6 +98,9 @@ struct irq_domain { ...@@ -104,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;
...@@ -126,6 +123,7 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node, ...@@ -126,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,
...@@ -134,7 +132,6 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node, ...@@ -134,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,
...@@ -146,7 +143,6 @@ static inline struct irq_domain *irq_domain_add_legacy_isa( ...@@ -146,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,
......
...@@ -210,6 +210,12 @@ typedef u32 phys_addr_t; ...@@ -210,6 +210,12 @@ typedef u32 phys_addr_t;
typedef phys_addr_t resource_size_t; typedef phys_addr_t resource_size_t;
/*
* This type is the placeholder for a hardware interrupt number. It has to be
* big enough to enclose whatever representation is used by a given platform.
*/
typedef unsigned long irq_hw_number_t;
typedef struct { typedef struct {
int counter; int counter;
} atomic_t; } atomic_t;
......
...@@ -62,7 +62,7 @@ config IRQ_DOMAIN_DEBUG ...@@ -62,7 +62,7 @@ config IRQ_DOMAIN_DEBUG
help help
This option will show the mapping relationship between hardware irq This option will show the mapping relationship between hardware irq
numbers and Linux irq numbers. The mapping is exposed via debugfs numbers and Linux irq numbers. The mapping is exposed via debugfs
in the file "virq_mapping". in the file "irq_domain_mapping".
If you don't know what this means you don't need it. If you don't know what this means you don't need it.
......
...@@ -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)) {
...@@ -350,7 +335,8 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain) ...@@ -350,7 +335,8 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
unsigned int irq_create_mapping(struct irq_domain *domain, unsigned int irq_create_mapping(struct irq_domain *domain,
irq_hw_number_t hwirq) irq_hw_number_t hwirq)
{ {
unsigned int virq, hint; unsigned int hint;
int virq;
pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq); pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq);
...@@ -377,13 +363,13 @@ unsigned int irq_create_mapping(struct irq_domain *domain, ...@@ -377,13 +363,13 @@ 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);
if (!virq) if (virq <= 0)
virq = irq_alloc_desc_from(1, 0); virq = irq_alloc_desc_from(1, 0);
if (!virq) { if (virq <= 0) {
pr_debug("irq: -> virq allocation failed\n"); pr_debug("irq: -> virq allocation failed\n");
return 0; return 0;
} }
...@@ -515,7 +501,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain, ...@@ -515,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)
...@@ -536,7 +522,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain, ...@@ -536,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;
...@@ -642,8 +628,8 @@ static int virq_debug_show(struct seq_file *m, void *private) ...@@ -642,8 +628,8 @@ static int virq_debug_show(struct seq_file *m, void *private)
void *data; void *data;
int i; int i;
seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq", seq_printf(m, "%-5s %-7s %-15s %-*s %s\n", "irq", "hwirq",
"chip name", "chip data", "domain name"); "chip name", 2 * sizeof(void *) + 2, "chip data", "domain name");
for (i = 1; i < nr_irqs; i++) { for (i = 1; i < nr_irqs; i++) {
desc = irq_to_desc(i); desc = irq_to_desc(i);
...@@ -666,7 +652,7 @@ static int virq_debug_show(struct seq_file *m, void *private) ...@@ -666,7 +652,7 @@ static int virq_debug_show(struct seq_file *m, void *private)
seq_printf(m, "%-15s ", p); seq_printf(m, "%-15s ", p);
data = irq_desc_get_chip_data(desc); data = irq_desc_get_chip_data(desc);
seq_printf(m, "0x%16p ", data); seq_printf(m, data ? "0x%p " : " %p ", data);
if (desc->irq_data.domain && desc->irq_data.domain->of_node) if (desc->irq_data.domain && desc->irq_data.domain->of_node)
p = desc->irq_data.domain->of_node->full_name; p = desc->irq_data.domain->of_node->full_name;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册