linux/arch/powerpc/include/asm/hw_irq.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
   3 */
   4#ifndef _ASM_POWERPC_HW_IRQ_H
   5#define _ASM_POWERPC_HW_IRQ_H
   6
   7#ifdef __KERNEL__
   8
   9#include <linux/errno.h>
  10#include <linux/compiler.h>
  11#include <asm/ptrace.h>
  12#include <asm/processor.h>
  13
  14#ifdef CONFIG_PPC64
  15
  16/*
  17 * PACA flags in paca->irq_happened.
  18 *
  19 * This bits are set when interrupts occur while soft-disabled
  20 * and allow a proper replay. Additionally, PACA_IRQ_HARD_DIS
  21 * is set whenever we manually hard disable.
  22 */
  23#define PACA_IRQ_HARD_DIS       0x01
  24#define PACA_IRQ_DBELL          0x02
  25#define PACA_IRQ_EE             0x04
  26#define PACA_IRQ_DEC            0x08 /* Or FIT */
  27#define PACA_IRQ_EE_EDGE        0x10 /* BookE only */
  28#define PACA_IRQ_HMI            0x20
  29
  30#endif /* CONFIG_PPC64 */
  31
  32#ifndef __ASSEMBLY__
  33
  34extern void __replay_interrupt(unsigned int vector);
  35
  36extern void timer_interrupt(struct pt_regs *);
  37extern void performance_monitor_exception(struct pt_regs *regs);
  38extern void WatchdogException(struct pt_regs *regs);
  39extern void unknown_exception(struct pt_regs *regs);
  40
  41#ifdef CONFIG_PPC64
  42#include <asm/paca.h>
  43
  44static inline unsigned long arch_local_save_flags(void)
  45{
  46        unsigned long flags;
  47
  48        asm volatile(
  49                "lbz %0,%1(13)"
  50                : "=r" (flags)
  51                : "i" (offsetof(struct paca_struct, soft_enabled)));
  52
  53        return flags;
  54}
  55
  56static inline unsigned long arch_local_irq_disable(void)
  57{
  58        unsigned long flags, zero;
  59
  60        asm volatile(
  61                "li %1,0; lbz %0,%2(13); stb %1,%2(13)"
  62                : "=r" (flags), "=&r" (zero)
  63                : "i" (offsetof(struct paca_struct, soft_enabled))
  64                : "memory");
  65
  66        return flags;
  67}
  68
  69extern void arch_local_irq_restore(unsigned long);
  70
  71static inline void arch_local_irq_enable(void)
  72{
  73        arch_local_irq_restore(1);
  74}
  75
  76static inline unsigned long arch_local_irq_save(void)
  77{
  78        return arch_local_irq_disable();
  79}
  80
  81static inline bool arch_irqs_disabled_flags(unsigned long flags)
  82{
  83        return flags == 0;
  84}
  85
  86static inline bool arch_irqs_disabled(void)
  87{
  88        return arch_irqs_disabled_flags(arch_local_save_flags());
  89}
  90
  91#ifdef CONFIG_PPC_BOOK3E
  92#define __hard_irq_enable()     asm volatile("wrteei 1" : : : "memory")
  93#define __hard_irq_disable()    asm volatile("wrteei 0" : : : "memory")
  94#else
  95#define __hard_irq_enable()     __mtmsrd(local_paca->kernel_msr | MSR_EE, 1)
  96#define __hard_irq_disable()    __mtmsrd(local_paca->kernel_msr, 1)
  97#endif
  98
  99#define hard_irq_disable()      do {                    \
 100        u8 _was_enabled;                                \
 101        __hard_irq_disable();                           \
 102        _was_enabled = local_paca->soft_enabled;        \
 103        local_paca->soft_enabled = 0;                   \
 104        local_paca->irq_happened |= PACA_IRQ_HARD_DIS;  \
 105        if (_was_enabled)                               \
 106                trace_hardirqs_off();                   \
 107} while(0)
 108
 109static inline bool lazy_irq_pending(void)
 110{
 111        return !!(get_paca()->irq_happened & ~PACA_IRQ_HARD_DIS);
 112}
 113
 114/*
 115 * This is called by asynchronous interrupts to conditionally
 116 * re-enable hard interrupts when soft-disabled after having
 117 * cleared the source of the interrupt
 118 */
 119static inline void may_hard_irq_enable(void)
 120{
 121        get_paca()->irq_happened &= ~PACA_IRQ_HARD_DIS;
 122        if (!(get_paca()->irq_happened & PACA_IRQ_EE))
 123                __hard_irq_enable();
 124}
 125
 126static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
 127{
 128        return !regs->softe;
 129}
 130
 131extern bool prep_irq_for_idle(void);
 132
 133#else /* CONFIG_PPC64 */
 134
 135#define SET_MSR_EE(x)   mtmsr(x)
 136
 137static inline unsigned long arch_local_save_flags(void)
 138{
 139        return mfmsr();
 140}
 141
 142static inline void arch_local_irq_restore(unsigned long flags)
 143{
 144#if defined(CONFIG_BOOKE)
 145        asm volatile("wrtee %0" : : "r" (flags) : "memory");
 146#else
 147        mtmsr(flags);
 148#endif
 149}
 150
 151static inline unsigned long arch_local_irq_save(void)
 152{
 153        unsigned long flags = arch_local_save_flags();
 154#ifdef CONFIG_BOOKE
 155        asm volatile("wrteei 0" : : : "memory");
 156#else
 157        SET_MSR_EE(flags & ~MSR_EE);
 158#endif
 159        return flags;
 160}
 161
 162static inline void arch_local_irq_disable(void)
 163{
 164#ifdef CONFIG_BOOKE
 165        asm volatile("wrteei 0" : : : "memory");
 166#else
 167        arch_local_irq_save();
 168#endif
 169}
 170
 171static inline void arch_local_irq_enable(void)
 172{
 173#ifdef CONFIG_BOOKE
 174        asm volatile("wrteei 1" : : : "memory");
 175#else
 176        unsigned long msr = mfmsr();
 177        SET_MSR_EE(msr | MSR_EE);
 178#endif
 179}
 180
 181static inline bool arch_irqs_disabled_flags(unsigned long flags)
 182{
 183        return (flags & MSR_EE) == 0;
 184}
 185
 186static inline bool arch_irqs_disabled(void)
 187{
 188        return arch_irqs_disabled_flags(arch_local_save_flags());
 189}
 190
 191#define hard_irq_disable()              arch_local_irq_disable()
 192
 193static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
 194{
 195        return !(regs->msr & MSR_EE);
 196}
 197
 198static inline void may_hard_irq_enable(void) { }
 199
 200#endif /* CONFIG_PPC64 */
 201
 202#define ARCH_IRQ_INIT_FLAGS     IRQ_NOREQUEST
 203
 204/*
 205 * interrupt-retrigger: should we handle this via lost interrupts and IPIs
 206 * or should we not care like we do now ? --BenH.
 207 */
 208struct irq_chip;
 209
 210#endif  /* __ASSEMBLY__ */
 211#endif  /* __KERNEL__ */
 212#endif  /* _ASM_POWERPC_HW_IRQ_H */
 213