openrisc: implement irqdomains

This moves OpenRISC to using the irqdomain infrastructure.  This doesn't
fundamentally change anything other than that it will be easier to have
multiple interrupt controllers in the future.

Signed-off-by: Jonas Bonn <jonas@southpole.se>
This commit is contained in:
Jonas Bonn 2012-04-06 12:52:54 +02:00
parent d48b97b403
commit b4c4c6ee93
2 changed files with 48 additions and 32 deletions

View file

@ -7,6 +7,7 @@ config OPENRISC
def_bool y
select OF
select OF_EARLY_FLATTREE
select IRQ_DOMAIN
select HAVE_MEMBLOCK
select ARCH_WANT_OPTIONAL_GPIOLIB
select HAVE_ARCH_TRACEHOOK

View file

@ -24,7 +24,7 @@
#include <linux/seq_file.h>
#include <linux/kernel_stat.h>
#include <linux/export.h>
#include <linux/irqdomain.h>
#include <linux/irqflags.h>
/* read interrupt enabled status */
@ -98,6 +98,7 @@ static void or1k_pic_mask_ack(struct irq_data *data)
#endif
}
#if 0
static int or1k_pic_set_type(struct irq_data *data, unsigned int flow_type)
{
/* There's nothing to do in the PIC configuration when changing
@ -107,43 +108,64 @@ static int or1k_pic_set_type(struct irq_data *data, unsigned int flow_type)
return irq_setup_alt_chip(data, flow_type);
}
#endif
static struct irq_chip or1k_dev = {
.name = "or1k-PIC",
.irq_unmask = or1k_pic_unmask,
.irq_mask = or1k_pic_mask,
.irq_ack = or1k_pic_ack,
.irq_mask_ack = or1k_pic_mask_ack,
};
static struct irq_domain *root_domain;
static inline int pic_get_irq(int first)
{
int irq;
int hwirq;
irq = ffs(mfspr(SPR_PICSR) >> first);
hwirq = ffs(mfspr(SPR_PICSR) >> first);
if (!hwirq)
return NO_IRQ;
else
hwirq = hwirq + first -1;
return irq ? irq + first - 1 : NO_IRQ;
return irq_find_mapping(root_domain, hwirq);
}
static int or1k_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
{
irq_set_chip_and_handler_name(irq, &or1k_dev,
handle_level_irq, "level");
irq_set_status_flags(irq, IRQ_LEVEL | IRQ_NOPROBE);
return 0;
}
static const struct irq_domain_ops or1k_irq_domain_ops = {
.xlate = irq_domain_xlate_onecell,
.map = or1k_map,
};
/*
* This sets up the IRQ domain for the PIC built in to the OpenRISC
* 1000 CPU. This is the "root" domain as these are the interrupts
* that directly trigger an exception in the CPU.
*/
static void __init or1k_irq_init(void)
{
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
struct device_node *intc = NULL;
/* The interrupt controller device node is mandatory */
intc = of_find_compatible_node(NULL, NULL, "opencores,or1k-pic");
BUG_ON(!intc);
/* Disable all interrupts until explicitly requested */
mtspr(SPR_PICMR, (0UL));
gc = irq_alloc_generic_chip("or1k-PIC", 1, 0, 0, handle_level_irq);
ct = gc->chip_types;
ct->chip.irq_unmask = or1k_pic_unmask;
ct->chip.irq_mask = or1k_pic_mask;
ct->chip.irq_ack = or1k_pic_ack;
ct->chip.irq_mask_ack = or1k_pic_mask_ack;
ct->chip.irq_set_type = or1k_pic_set_type;
/* The OR1K PIC can handle both level and edge trigged
* interrupts in roughly the same manner
*/
#if 0
/* FIXME: chip.type??? */
ct->chip.type = IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_MASK;
#endif
irq_setup_generic_chip(gc, IRQ_MSK(NR_IRQS), 0,
IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
root_domain = irq_domain_add_linear(intc, 32,
&or1k_irq_domain_ops, NULL);
}
void __init init_IRQ(void)
@ -164,10 +186,3 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
irq_exit();
set_irq_regs(old_regs);
}
unsigned int irq_create_of_mapping(struct device_node *controller,
const u32 *intspec, unsigned int intsize)
{
return intspec[0];
}
EXPORT_SYMBOL_GPL(irq_create_of_mapping);