Commit b4c4c6ee authored by Jonas Bonn's avatar Jonas Bonn

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: default avatarJonas Bonn <jonas@southpole.se>
parent d48b97b4
......@@ -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
......
......@@ -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 void __init or1k_irq_init(void)
{
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
/* Disable all interrupts until explicitly requested */
mtspr(SPR_PICMR, (0UL));
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);
gc = irq_alloc_generic_chip("or1k-PIC", 1, 0, 0, handle_level_irq);
ct = gc->chip_types;
return 0;
}
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;
static const struct irq_domain_ops or1k_irq_domain_ops = {
.xlate = irq_domain_xlate_onecell,
.map = or1k_map,
};
/* The OR1K PIC can handle both level and edge trigged
* interrupts in roughly the same manner
/*
* 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.
*/
#if 0
/* FIXME: chip.type??? */
ct->chip.type = IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_MASK;
#endif
static void __init or1k_irq_init(void)
{
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);
irq_setup_generic_chip(gc, IRQ_MSK(NR_IRQS), 0,
IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
/* Disable all interrupts until explicitly requested */
mtspr(SPR_PICMR, (0UL));
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);
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