Skip to content

Commit

Permalink
Merge tag 'irqdomain-for-linus' of git://git.secretlab.ca/git/linux-2.6
Browse files Browse the repository at this point in the history
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().
  • Loading branch information
Linus Torvalds committed Apr 12, 2012
2 parents 4abb663 + 6fa6c8e commit 7e06648
Show file tree
Hide file tree
Showing 13 changed files with 36 additions and 69 deletions.
4 changes: 0 additions & 4 deletions arch/c6x/include/asm/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@
/* This number is used when no interrupt has been assigned */
#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_IRQ(void);
Expand Down
13 changes: 0 additions & 13 deletions arch/c6x/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
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);
2 changes: 0 additions & 2 deletions arch/powerpc/include/asm/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ extern atomic_t ppc_n_lost_interrupts;
/* Same thing, used by the generic IRQ code */
#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);

/**
Expand Down
6 changes: 0 additions & 6 deletions arch/powerpc/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,12 +560,6 @@ void do_softirq(void)
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)
{
struct irq_data *irq_data = irq_get_irq_data(virq);
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/cell/axon_msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ static int axon_msi_probe(struct platform_device *device)
}
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) {
printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
dn->full_name);
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/cell/beat_interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ void __init beatic_init_IRQ(void)
ppc_md.get_irq = beatic_get_irq;

/* 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);
irq_set_default_host(beatic_host);
}
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/powermac/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ static int psurge_secondary_ipi_init(void)
{
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)
psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
Expand Down
3 changes: 1 addition & 2 deletions arch/powerpc/platforms/ps3/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -753,9 +753,8 @@ void __init ps3_init_IRQ(void)
unsigned cpu;
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_virq_count(PS3_PLUG_MAX + 1);

for_each_possible_cpu(cpu) {
struct ps3_private *pd = &per_cpu(ps3_private, cpu);
Expand Down
5 changes: 5 additions & 0 deletions include/linux/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,11 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
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
*
Expand Down
12 changes: 4 additions & 8 deletions include/linux/irqdomain.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ struct of_device_id;
/* Number of irqs reserved for a legacy isa controller */
#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
* @match: Match an interrupt controller device node to a host, returns
Expand Down Expand Up @@ -104,6 +98,9 @@ struct irq_domain {
unsigned int size;
unsigned int *revmap;
} linear;
struct {
unsigned int max_irq;
} nomap;
struct radix_tree_root tree;
} revmap_data;
const struct irq_domain_ops *ops;
Expand All @@ -126,6 +123,7 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
const struct irq_domain_ops *ops,
void *host_data);
struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
unsigned int max_irq,
const struct irq_domain_ops *ops,
void *host_data);
struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
Expand All @@ -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 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(
struct device_node *of_node,
Expand All @@ -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 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,
Expand Down
6 changes: 6 additions & 0 deletions include/linux/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ typedef u32 phys_addr_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 {
int counter;
} atomic_t;
Expand Down
2 changes: 1 addition & 1 deletion kernel/irq/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ config IRQ_DOMAIN_DEBUG
help
This option will show the mapping relationship between hardware irq
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.

Expand Down
46 changes: 16 additions & 30 deletions kernel/irq/irqdomain.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ static LIST_HEAD(irq_domain_list);
static DEFINE_MUTEX(irq_domain_mutex);

static DEFINE_MUTEX(revmap_trees_mutex);
static unsigned int irq_virq_count = NR_IRQS;
static struct irq_domain *irq_default_domain;

/**
Expand Down Expand Up @@ -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,
unsigned int max_irq,
const struct irq_domain_ops *ops,
void *host_data)
{
struct irq_domain *domain = irq_domain_alloc(of_node,
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);
}
return domain;
}

Expand Down Expand Up @@ -262,22 +264,6 @@ void irq_set_default_host(struct irq_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,
irq_hw_number_t hwirq)
{
Expand Down Expand Up @@ -320,13 +306,12 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
pr_debug("irq: create_direct virq allocation failed\n");
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",
irq_virq_count);
domain->revmap_data.nomap.max_irq);
irq_free_desc(virq);
return 0;
}

pr_debug("irq: create_direct obtained virq %d\n", virq);

if (irq_setup_virq(domain, virq, virq)) {
Expand All @@ -350,7 +335,8 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
unsigned int irq_create_mapping(struct irq_domain *domain,
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);

Expand All @@ -377,13 +363,13 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
return irq_domain_legacy_revmap(domain, hwirq);

/* Allocate a virtual interrupt number */
hint = hwirq % irq_virq_count;
hint = hwirq % nr_irqs;
if (hint == 0)
hint++;
virq = irq_alloc_desc_from(hint, 0);
if (!virq)
if (virq <= 0)
virq = irq_alloc_desc_from(1, 0);
if (!virq) {
if (virq <= 0) {
pr_debug("irq: -> virq allocation failed\n");
return 0;
}
Expand Down Expand Up @@ -515,7 +501,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
irq_hw_number_t hwirq)
{
unsigned int i;
unsigned int hint = hwirq % irq_virq_count;
unsigned int hint = hwirq % nr_irqs;

/* Look for default domain if nececssary */
if (domain == NULL)
Expand All @@ -536,7 +522,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
if (data && (data->domain == domain) && (data->hwirq == hwirq))
return i;
i++;
if (i >= irq_virq_count)
if (i >= nr_irqs)
i = 1;
} while(i != hint);
return 0;
Expand Down Expand Up @@ -642,8 +628,8 @@ static int virq_debug_show(struct seq_file *m, void *private)
void *data;
int i;

seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq",
"chip name", "chip data", "domain name");
seq_printf(m, "%-5s %-7s %-15s %-*s %s\n", "irq", "hwirq",
"chip name", 2 * sizeof(void *) + 2, "chip data", "domain name");

for (i = 1; i < nr_irqs; i++) {
desc = irq_to_desc(i);
Expand All @@ -666,7 +652,7 @@ static int virq_debug_show(struct seq_file *m, void *private)
seq_printf(m, "%-15s ", p);

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)
p = desc->irq_data.domain->of_node->full_name;
Expand Down

0 comments on commit 7e06648

Please sign in to comment.