From b671ad2befe37131af380183760862d5cbad858d Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 21 Sep 2005 16:52:55 -0500 Subject: [PATCH] powerpc: merged hw_irq.h Merged hw_irq.h between ppc32 & ppc64. Added support to use the Book-E wrtee[i] instructions that allow modifying MSR[EE] atomically. Additionally, added get_irq_desc() macros to ppc32 to allow mask_irq(), unmask_irq(), and ack_irq() to be common between ppc32 & ppc64. Note: because 64-bit Book-E implementations only have a 32-bit MSR the macro's for Book-E need to come before the PPC64 macro's to ensure the right thing happends for 64-bit Book-E processors. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- include/asm-powerpc/hw_irq.h | 115 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 include/asm-powerpc/hw_irq.h (limited to 'include/asm-powerpc/hw_irq.h') diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h new file mode 100644 index 00000000000..605a65e4206 --- /dev/null +++ b/include/asm-powerpc/hw_irq.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 1999 Cort Dougan + */ +#ifndef _ASM_POWERPC_HW_IRQ_H +#define _ASM_POWERPC_HW_IRQ_H + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include + +extern void timer_interrupt(struct pt_regs *); +extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); + +#ifdef CONFIG_PPC_ISERIES + +extern unsigned long local_get_flags(void); +extern unsigned long local_irq_disable(void); +extern void local_irq_restore(unsigned long); + +#define local_irq_enable() local_irq_restore(1) +#define local_save_flags(flags) ((flags) = local_get_flags()) +#define local_irq_save(flags) ((flags) = local_irq_disable()) + +#define irqs_disabled() (local_get_flags() == 0) + +#else + +#if defined(CONFIG_BOOKE) +#define SET_MSR_EE(x) mtmsr(x) +#define local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory") +#elif defined(__powerpc64__) +#define SET_MSR_EE(x) __mtmsrd(x, 1) +#define local_irq_restore(flags) do { \ + __asm__ __volatile__("": : :"memory"); \ + __mtmsrd((flags), 1); \ +} while(0) +#else +#define SET_MSR_EE(x) mtmsr(x) +#define local_irq_restore(flags) mtmsr(flags) +#endif + +static inline void local_irq_disable(void) +{ +#ifdef CONFIG_BOOKE + __asm__ __volatile__("wrteei 0": : :"memory"); +#else + unsigned long msr; + __asm__ __volatile__("": : :"memory"); + msr = mfmsr(); + SET_MSR_EE(msr & ~MSR_EE); +#endif +} + +static inline void local_irq_enable(void) +{ +#ifdef CONFIG_BOOKE + __asm__ __volatile__("wrteei 1": : :"memory"); +#else + unsigned long msr; + __asm__ __volatile__("": : :"memory"); + msr = mfmsr(); + SET_MSR_EE(msr | MSR_EE); +#endif +} + +static inline void local_irq_save_ptr(unsigned long *flags) +{ + unsigned long msr; + msr = mfmsr(); + *flags = msr; +#ifdef CONFIG_BOOKE + __asm__ __volatile__("wrteei 0": : :"memory"); +#else + SET_MSR_EE(msr & ~MSR_EE); +#endif + __asm__ __volatile__("": : :"memory"); +} + +#define local_save_flags(flags) ((flags) = mfmsr()) +#define local_irq_save(flags) local_irq_save_ptr(&flags) +#define irqs_disabled() ((mfmsr() & MSR_EE) == 0) + +#endif /* CONFIG_PPC_ISERIES */ + +#define mask_irq(irq) \ + ({ \ + irq_desc_t *desc = get_irq_desc(irq); \ + if (desc->handler && desc->handler->disable) \ + desc->handler->disable(irq); \ + }) +#define unmask_irq(irq) \ + ({ \ + irq_desc_t *desc = get_irq_desc(irq); \ + if (desc->handler && desc->handler->enable) \ + desc->handler->enable(irq); \ + }) +#define ack_irq(irq) \ + ({ \ + irq_desc_t *desc = get_irq_desc(irq); \ + if (desc->handler && desc->handler->ack) \ + desc->handler->ack(irq); \ + }) + +/* Should we handle this via lost interrupts and IPIs or should we don't care like + * we do now ? --BenH. + */ +struct hw_interrupt_type; +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {} + +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_HW_IRQ_H */ -- cgit v1.2.3