diff options
Diffstat (limited to 'arch/openrisc/kernel/irq.c')
| -rw-r--r-- | arch/openrisc/kernel/irq.c | 83 | 
1 files changed, 47 insertions, 36 deletions
diff --git a/arch/openrisc/kernel/irq.c b/arch/openrisc/kernel/irq.c index 4bfead22095..e935b9d8eee 100644 --- a/arch/openrisc/kernel/irq.c +++ b/arch/openrisc/kernel/irq.c @@ -14,17 +14,13 @@   *      2 of the License, or (at your option) any later version.   */ -#include <linux/ptrace.h> -#include <linux/errno.h>  #include <linux/interrupt.h>  #include <linux/init.h>  #include <linux/of.h>  #include <linux/ftrace.h>  #include <linux/irq.h> -#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 +94,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 +104,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) + +static int or1k_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)  { -	struct irq_chip_generic *gc; -	struct irq_chip_type *ct; +	irq_set_chip_and_handler_name(irq, &or1k_dev, +				      handle_level_irq, "level"); +	irq_set_status_flags(irq, IRQ_LEVEL | IRQ_NOPROBE); -	/* Disable all interrupts until explicitly requested */ -	mtspr(SPR_PICMR, (0UL)); +	return 0; +} -	gc = irq_alloc_generic_chip("or1k-PIC", 1, 0, 0, handle_level_irq); -	ct = gc->chip_types; +static const struct irq_domain_ops or1k_irq_domain_ops = { +	.xlate = irq_domain_xlate_onecell, +	.map = or1k_map, +}; -	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; +/* + * 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 device_node *intc = NULL; -	/* 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 +	/* 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 +182,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);  |