diff options
Diffstat (limited to 'arch/powerpc/kernel/irq.c')
| -rw-r--r-- | arch/powerpc/kernel/irq.c | 47 | 
1 files changed, 22 insertions, 25 deletions
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 30817d9b20c..d3ce67cf03b 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -53,6 +53,8 @@  #include <linux/bootmem.h>  #include <linux/pci.h>  #include <linux/debugfs.h> +#include <linux/of.h> +#include <linux/of_irq.h>  #include <asm/uaccess.h>  #include <asm/system.h> @@ -64,6 +66,8 @@  #include <asm/ptrace.h>  #include <asm/machdep.h>  #include <asm/udbg.h> +#include <asm/dbell.h> +  #ifdef CONFIG_PPC64  #include <asm/paca.h>  #include <asm/firmware.h> @@ -153,14 +157,28 @@ notrace void raw_local_irq_restore(unsigned long en)  	if (get_hard_enabled())  		return; +#if defined(CONFIG_BOOKE) && defined(CONFIG_SMP) +	/* Check for pending doorbell interrupts and resend to ourself */ +	doorbell_check_self(); +#endif +  	/*  	 * Need to hard-enable interrupts here.  Since currently disabled,  	 * no need to take further asm precautions against preemption; but  	 * use local_paca instead of get_paca() to avoid preemption checking.  	 */  	local_paca->hard_enabled = en; + +#ifndef CONFIG_BOOKE +	/* On server, re-trigger the decrementer if it went negative since +	 * some processors only trigger on edge transitions of the sign bit. +	 * +	 * BookE has a level sensitive decrementer (latches in TSR) so we +	 * don't need that +	 */  	if ((int)mfspr(SPRN_DEC) < 0)  		mtspr(SPRN_DEC, 1); +#endif /* CONFIG_BOOKE */  	/*  	 * Force the delivery of pending soft-disabled interrupts on PS3. @@ -295,7 +313,10 @@ void fixup_irqs(const struct cpumask *map)  	for_each_irq(irq) {  		desc = irq_to_desc(irq); -		if (desc && desc->status & IRQ_PER_CPU) +		if (!desc) +			continue; + +		if (desc->status & IRQ_PER_CPU)  			continue;  		cpumask_and(mask, desc->affinity, map); @@ -317,7 +338,6 @@ void fixup_irqs(const struct cpumask *map)  }  #endif -#ifdef CONFIG_IRQSTACKS  static inline void handle_one_irq(unsigned int irq)  {  	struct thread_info *curtp, *irqtp; @@ -358,12 +378,6 @@ static inline void handle_one_irq(unsigned int irq)  	if (irqtp->flags)  		set_bits(irqtp->flags, &curtp->flags);  } -#else -static inline void handle_one_irq(unsigned int irq) -{ -	generic_handle_irq(irq); -} -#endif  static inline void check_stack_overflow(void)  { @@ -455,7 +469,6 @@ void exc_lvl_ctx_init(void)  }  #endif -#ifdef CONFIG_IRQSTACKS  struct thread_info *softirq_ctx[NR_CPUS] __read_mostly;  struct thread_info *hardirq_ctx[NR_CPUS] __read_mostly; @@ -492,10 +505,6 @@ static inline void do_softirq_onstack(void)  	irqtp->task = NULL;  } -#else -#define do_softirq_onstack()	__do_softirq() -#endif /* CONFIG_IRQSTACKS */ -  void do_softirq(void)  {  	unsigned long flags; @@ -813,18 +822,6 @@ unsigned int irq_create_of_mapping(struct device_node *controller,  }  EXPORT_SYMBOL_GPL(irq_create_of_mapping); -unsigned int irq_of_parse_and_map(struct device_node *dev, int index) -{ -	struct of_irq oirq; - -	if (of_irq_map_one(dev, index, &oirq)) -		return NO_IRQ; - -	return irq_create_of_mapping(oirq.controller, oirq.specifier, -				     oirq.size); -} -EXPORT_SYMBOL_GPL(irq_of_parse_and_map); -  void irq_dispose_mapping(unsigned int virq)  {  	struct irq_host *host;  | 
