uboot/arch/m68k/lib/interrupts.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2000-2004
   4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   5 *
   6 * (C) Copyright 2007 Freescale Semiconductor Inc
   7 * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
   8 */
   9
  10#include <common.h>
  11#include <irq_func.h>
  12#include <watchdog.h>
  13#include <asm/processor.h>
  14#include <asm/immap.h>
  15#include <asm/ptrace.h>
  16
  17#define NR_IRQS         (CONFIG_SYS_NUM_IRQS)
  18
  19/*
  20 * Interrupt vector functions.
  21 */
  22struct interrupt_action {
  23        interrupt_handler_t *handler;
  24        void *arg;
  25};
  26
  27static struct interrupt_action irq_vecs[NR_IRQS];
  28
  29static __inline__ unsigned short get_sr (void)
  30{
  31        unsigned short sr;
  32
  33        asm volatile ("move.w %%sr,%0":"=r" (sr):);
  34
  35        return sr;
  36}
  37
  38static __inline__ void set_sr (unsigned short sr)
  39{
  40        asm volatile ("move.w %0,%%sr"::"r" (sr));
  41}
  42
  43/************************************************************************/
  44/*
  45 * Install and free an interrupt handler
  46 */
  47void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg)
  48{
  49        if ((vec < 0) || (vec >= NR_IRQS)) {
  50                printf ("irq_install_handler: wrong interrupt vector %d\n",
  51                        vec);
  52                return;
  53        }
  54
  55        irq_vecs[vec].handler = handler;
  56        irq_vecs[vec].arg = arg;
  57}
  58
  59void irq_free_handler(int vec)
  60{
  61        if ((vec < 0) || (vec >= NR_IRQS)) {
  62                return;
  63        }
  64
  65        irq_vecs[vec].handler = NULL;
  66        irq_vecs[vec].arg = NULL;
  67}
  68
  69void enable_interrupts(void)
  70{
  71        unsigned short sr;
  72
  73        sr = get_sr ();
  74        set_sr (sr & ~0x0700);
  75}
  76
  77int disable_interrupts(void)
  78{
  79        unsigned short sr;
  80
  81        sr = get_sr ();
  82        set_sr (sr | 0x0700);
  83
  84        return ((sr & 0x0700) == 0);    /* return true, if interrupts were enabled before */
  85}
  86
  87void int_handler (struct pt_regs *fp)
  88{
  89        int vec;
  90
  91        vec = (fp->vector >> 2) & 0xff;
  92        if (vec > 0x40)
  93                vec -= 0x40;
  94
  95        if (irq_vecs[vec].handler != NULL) {
  96                irq_vecs[vec].handler (irq_vecs[vec].arg);
  97        } else {
  98                printf ("\nBogus External Interrupt Vector %d\n", vec);
  99        }
 100}
 101