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:
Родитель
d48b97b403
Коммит
b4c4c6ee93
|
@ -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 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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче