root/arch/alpha/kernel/irq_alpha.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dummy_perf
  2. do_entInt
  3. common_init_isa_dma
  4. init_IRQ
  5. process_mcheck_info
  6. init_rtc_irq

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Alpha specific irq code.
   4  */
   5 
   6 #include <linux/init.h>
   7 #include <linux/sched.h>
   8 #include <linux/irq.h>
   9 #include <linux/kernel_stat.h>
  10 #include <linux/module.h>
  11 
  12 #include <asm/machvec.h>
  13 #include <asm/dma.h>
  14 #include <asm/perf_event.h>
  15 #include <asm/mce.h>
  16 
  17 #include "proto.h"
  18 #include "irq_impl.h"
  19 
  20 /* Hack minimum IPL during interrupt processing for broken hardware.  */
  21 #ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK
  22 int __min_ipl;
  23 EXPORT_SYMBOL(__min_ipl);
  24 #endif
  25 
  26 /*
  27  * Performance counter hook.  A module can override this to
  28  * do something useful.
  29  */
  30 static void
  31 dummy_perf(unsigned long vector, struct pt_regs *regs)
  32 {
  33         irq_err_count++;
  34         printk(KERN_CRIT "Performance counter interrupt!\n");
  35 }
  36 
  37 void (*perf_irq)(unsigned long, struct pt_regs *) = dummy_perf;
  38 EXPORT_SYMBOL(perf_irq);
  39 
  40 /*
  41  * The main interrupt entry point.
  42  */
  43 
  44 asmlinkage void 
  45 do_entInt(unsigned long type, unsigned long vector,
  46           unsigned long la_ptr, struct pt_regs *regs)
  47 {
  48         struct pt_regs *old_regs;
  49 
  50         /*
  51          * Disable interrupts during IRQ handling.
  52          * Note that there is no matching local_irq_enable() due to
  53          * severe problems with RTI at IPL0 and some MILO PALcode
  54          * (namely LX164).
  55          */
  56         local_irq_disable();
  57         switch (type) {
  58         case 0:
  59 #ifdef CONFIG_SMP
  60                 handle_ipi(regs);
  61                 return;
  62 #else
  63                 irq_err_count++;
  64                 printk(KERN_CRIT "Interprocessor interrupt? "
  65                        "You must be kidding!\n");
  66 #endif
  67                 break;
  68         case 1:
  69                 old_regs = set_irq_regs(regs);
  70                 handle_irq(RTC_IRQ);
  71                 set_irq_regs(old_regs);
  72                 return;
  73         case 2:
  74                 old_regs = set_irq_regs(regs);
  75                 alpha_mv.machine_check(vector, la_ptr);
  76                 set_irq_regs(old_regs);
  77                 return;
  78         case 3:
  79                 old_regs = set_irq_regs(regs);
  80                 alpha_mv.device_interrupt(vector);
  81                 set_irq_regs(old_regs);
  82                 return;
  83         case 4:
  84                 perf_irq(la_ptr, regs);
  85                 return;
  86         default:
  87                 printk(KERN_CRIT "Hardware intr %ld %lx? Huh?\n",
  88                        type, vector);
  89         }
  90         printk(KERN_CRIT "PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
  91 }
  92 
  93 void __init
  94 common_init_isa_dma(void)
  95 {
  96         outb(0, DMA1_RESET_REG);
  97         outb(0, DMA2_RESET_REG);
  98         outb(0, DMA1_CLR_MASK_REG);
  99         outb(0, DMA2_CLR_MASK_REG);
 100 }
 101 
 102 void __init
 103 init_IRQ(void)
 104 {
 105         /* Just in case the platform init_irq() causes interrupts/mchecks
 106            (as is the case with RAWHIDE, at least).  */
 107         wrent(entInt, 0);
 108 
 109         alpha_mv.init_irq();
 110 }
 111 
 112 /*
 113  * machine error checks
 114  */
 115 #define MCHK_K_TPERR           0x0080
 116 #define MCHK_K_TCPERR          0x0082
 117 #define MCHK_K_HERR            0x0084
 118 #define MCHK_K_ECC_C           0x0086
 119 #define MCHK_K_ECC_NC          0x0088
 120 #define MCHK_K_OS_BUGCHECK     0x008A
 121 #define MCHK_K_PAL_BUGCHECK    0x0090
 122 
 123 #ifndef CONFIG_SMP
 124 struct mcheck_info __mcheck_info;
 125 #endif
 126 
 127 void
 128 process_mcheck_info(unsigned long vector, unsigned long la_ptr,
 129                     const char *machine, int expected)
 130 {
 131         struct el_common *mchk_header;
 132         const char *reason;
 133 
 134         /*
 135          * See if the machine check is due to a badaddr() and if so,
 136          * ignore it.
 137          */
 138 
 139 #ifdef CONFIG_VERBOSE_MCHECK
 140         if (alpha_verbose_mcheck > 1) {
 141                 printk(KERN_CRIT "%s machine check %s\n", machine,
 142                        expected ? "expected." : "NOT expected!!!");
 143         }
 144 #endif
 145 
 146         if (expected) {
 147                 int cpu = smp_processor_id();
 148                 mcheck_expected(cpu) = 0;
 149                 mcheck_taken(cpu) = 1;
 150                 return;
 151         }
 152 
 153         mchk_header = (struct el_common *)la_ptr;
 154 
 155         printk(KERN_CRIT "%s machine check: vector=0x%lx pc=0x%lx code=0x%x\n",
 156                machine, vector, get_irq_regs()->pc, mchk_header->code);
 157 
 158         switch (mchk_header->code) {
 159         /* Machine check reasons.  Defined according to PALcode sources.  */
 160         case 0x80: reason = "tag parity error"; break;
 161         case 0x82: reason = "tag control parity error"; break;
 162         case 0x84: reason = "generic hard error"; break;
 163         case 0x86: reason = "correctable ECC error"; break;
 164         case 0x88: reason = "uncorrectable ECC error"; break;
 165         case 0x8A: reason = "OS-specific PAL bugcheck"; break;
 166         case 0x90: reason = "callsys in kernel mode"; break;
 167         case 0x96: reason = "i-cache read retryable error"; break;
 168         case 0x98: reason = "processor detected hard error"; break;
 169         
 170         /* System specific (these are for Alcor, at least): */
 171         case 0x202: reason = "system detected hard error"; break;
 172         case 0x203: reason = "system detected uncorrectable ECC error"; break;
 173         case 0x204: reason = "SIO SERR occurred on PCI bus"; break;
 174         case 0x205: reason = "parity error detected by core logic"; break;
 175         case 0x206: reason = "SIO IOCHK occurred on ISA bus"; break;
 176         case 0x207: reason = "non-existent memory error"; break;
 177         case 0x208: reason = "MCHK_K_DCSR"; break;
 178         case 0x209: reason = "PCI SERR detected"; break;
 179         case 0x20b: reason = "PCI data parity error detected"; break;
 180         case 0x20d: reason = "PCI address parity error detected"; break;
 181         case 0x20f: reason = "PCI master abort error"; break;
 182         case 0x211: reason = "PCI target abort error"; break;
 183         case 0x213: reason = "scatter/gather PTE invalid error"; break;
 184         case 0x215: reason = "flash ROM write error"; break;
 185         case 0x217: reason = "IOA timeout detected"; break;
 186         case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break;
 187         case 0x21b: reason = "EISA fail-safe timer timeout"; break;
 188         case 0x21d: reason = "EISA bus time-out"; break;
 189         case 0x21f: reason = "EISA software generated NMI"; break;
 190         case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break;
 191         default: reason = "unknown"; break;
 192         }
 193 
 194         printk(KERN_CRIT "machine check type: %s%s\n",
 195                reason, mchk_header->retry ? " (retryable)" : "");
 196 
 197         dik_show_regs(get_irq_regs(), NULL);
 198 
 199 #ifdef CONFIG_VERBOSE_MCHECK
 200         if (alpha_verbose_mcheck > 1) {
 201                 /* Dump the logout area to give all info.  */
 202                 unsigned long *ptr = (unsigned long *)la_ptr;
 203                 long i;
 204                 for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
 205                         printk(KERN_CRIT "   +%8lx %016lx %016lx\n",
 206                                i*sizeof(long), ptr[i], ptr[i+1]);
 207                 }
 208         }
 209 #endif /* CONFIG_VERBOSE_MCHECK */
 210 }
 211 
 212 /*
 213  * The special RTC interrupt type.  The interrupt itself was
 214  * processed by PALcode, and comes in via entInt vector 1.
 215  */
 216 
 217 struct irqaction timer_irqaction = {
 218         .handler        = rtc_timer_interrupt,
 219         .name           = "timer",
 220 };
 221 
 222 void __init
 223 init_rtc_irq(void)
 224 {
 225         irq_set_chip_and_handler_name(RTC_IRQ, &dummy_irq_chip,
 226                                       handle_percpu_irq, "RTC");
 227         setup_irq(RTC_IRQ, &timer_irqaction);
 228 }
 229 
 230 /* Dummy irqactions.  */
 231 struct irqaction isa_cascade_irqaction = {
 232         .handler        = no_action,
 233         .name           = "isa-cascade"
 234 };
 235 
 236 struct irqaction timer_cascade_irqaction = {
 237         .handler        = no_action,
 238         .name           = "timer-cascade"
 239 };
 240 
 241 struct irqaction halt_switch_irqaction = {
 242         .handler        = no_action,
 243         .name           = "halt-switch"
 244 };

/* [<][>][^][v][top][bottom][index][help] */