linux/arch/arc/include/asm/irqflags-arcv2.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 * published by the Free Software Foundation.
   7 */
   8
   9#ifndef __ASM_IRQFLAGS_ARCV2_H
  10#define __ASM_IRQFLAGS_ARCV2_H
  11
  12#include <asm/arcregs.h>
  13
  14/* status32 Bits */
  15#define STATUS_AD_BIT   19   /* Disable Align chk: core supports non-aligned */
  16#define STATUS_IE_BIT   31
  17
  18#define STATUS_AD_MASK          (1<<STATUS_AD_BIT)
  19#define STATUS_IE_MASK          (1<<STATUS_IE_BIT)
  20
  21/* status32 Bits as encoded/expected by CLRI/SETI */
  22#define CLRI_STATUS_IE_BIT      4
  23
  24#define CLRI_STATUS_E_MASK      0xF
  25#define CLRI_STATUS_IE_MASK     (1 << CLRI_STATUS_IE_BIT)
  26
  27#define AUX_USER_SP             0x00D
  28#define AUX_IRQ_CTRL            0x00E
  29#define AUX_IRQ_ACT             0x043   /* Active Intr across all levels */
  30#define AUX_IRQ_LVL_PEND        0x200   /* Pending Intr across all levels */
  31#define AUX_IRQ_HINT            0x201   /* For generating Soft Interrupts */
  32#define AUX_IRQ_PRIORITY        0x206
  33#define ICAUSE                  0x40a
  34#define AUX_IRQ_SELECT          0x40b
  35#define AUX_IRQ_ENABLE          0x40c
  36
  37/* Was Intr taken in User Mode */
  38#define AUX_IRQ_ACT_BIT_U       31
  39
  40/*
  41 * User space should be interruptable even by lowest prio interrupt
  42 * Safe even if actual interrupt priorities is fewer or even one
  43 */
  44#define ARCV2_IRQ_DEF_PRIO      15
  45
  46/* seed value for status register */
  47#define ISA_INIT_STATUS_BITS    (STATUS_IE_MASK | STATUS_AD_MASK | \
  48                                        (ARCV2_IRQ_DEF_PRIO << 1))
  49
  50/* SLEEP needs default irq priority (<=) which can interrupt the doze */
  51#define ISA_SLEEP_ARG           (0x10 | ARCV2_IRQ_DEF_PRIO)
  52
  53#ifndef __ASSEMBLY__
  54
  55/*
  56 * Save IRQ state and disable IRQs
  57 */
  58static inline long arch_local_irq_save(void)
  59{
  60        unsigned long flags;
  61
  62        __asm__ __volatile__("  clri %0 \n" : "=r" (flags) : : "memory");
  63
  64        return flags;
  65}
  66
  67/*
  68 * restore saved IRQ state
  69 */
  70static inline void arch_local_irq_restore(unsigned long flags)
  71{
  72        __asm__ __volatile__("  seti %0 \n" : : "r" (flags) : "memory");
  73}
  74
  75/*
  76 * Unconditionally Enable IRQs
  77 */
  78static inline void arch_local_irq_enable(void)
  79{
  80        unsigned int irqact = read_aux_reg(AUX_IRQ_ACT);
  81
  82        if (irqact & 0xffff)
  83                write_aux_reg(AUX_IRQ_ACT, irqact & ~0xffff);
  84
  85        __asm__ __volatile__("  seti    \n" : : : "memory");
  86}
  87
  88/*
  89 * Unconditionally Disable IRQs
  90 */
  91static inline void arch_local_irq_disable(void)
  92{
  93        __asm__ __volatile__("  clri    \n" : : : "memory");
  94}
  95
  96/*
  97 * save IRQ state
  98 */
  99static inline long arch_local_save_flags(void)
 100{
 101        unsigned long temp;
 102
 103        __asm__ __volatile__(
 104        "       lr  %0, [status32]      \n"
 105        : "=&r"(temp)
 106        :
 107        : "memory");
 108
 109        /* To be compatible with irq_save()/irq_restore()
 110         * encode the irq bits as expected by CLRI/SETI
 111         * (this was needed to make CONFIG_TRACE_IRQFLAGS work)
 112         */
 113        temp = (1 << 5) |
 114                ((!!(temp & STATUS_IE_MASK)) << CLRI_STATUS_IE_BIT) |
 115                (temp & CLRI_STATUS_E_MASK);
 116        return temp;
 117}
 118
 119/*
 120 * Query IRQ state
 121 */
 122static inline int arch_irqs_disabled_flags(unsigned long flags)
 123{
 124        return !(flags & CLRI_STATUS_IE_MASK);
 125}
 126
 127static inline int arch_irqs_disabled(void)
 128{
 129        return arch_irqs_disabled_flags(arch_local_save_flags());
 130}
 131
 132static inline void arc_softirq_trigger(int irq)
 133{
 134        write_aux_reg(AUX_IRQ_HINT, irq);
 135}
 136
 137static inline void arc_softirq_clear(int irq)
 138{
 139        write_aux_reg(AUX_IRQ_HINT, 0);
 140}
 141
 142#else
 143
 144#ifdef CONFIG_TRACE_IRQFLAGS
 145
 146.macro TRACE_ASM_IRQ_DISABLE
 147        bl      trace_hardirqs_off
 148.endm
 149
 150.macro TRACE_ASM_IRQ_ENABLE
 151        bl      trace_hardirqs_on
 152.endm
 153
 154#else
 155
 156.macro TRACE_ASM_IRQ_DISABLE
 157.endm
 158
 159.macro TRACE_ASM_IRQ_ENABLE
 160.endm
 161
 162#endif
 163.macro IRQ_DISABLE  scratch
 164        clri
 165        TRACE_ASM_IRQ_DISABLE
 166.endm
 167
 168.macro IRQ_ENABLE  scratch
 169        TRACE_ASM_IRQ_ENABLE
 170        seti
 171.endm
 172
 173#endif  /* __ASSEMBLY__ */
 174
 175#endif
 176