uboot/lib_m68k/interrupts.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000-2004
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * (C) Copyright 2007 Freescale Semiconductor Inc
   6 * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
   7 *
   8 * See file CREDITS for list of people who contributed to this
   9 * project.
  10 *
  11 * This program is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU General Public License as
  13 * published by the Free Software Foundation; either version 2 of
  14 * the License, or (at your option) any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 * GNU General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24 * MA 02111-1307 USA
  25 */
  26
  27#include <common.h>
  28#include <watchdog.h>
  29#include <asm/processor.h>
  30#include <asm/immap.h>
  31
  32#define NR_IRQS         (CONFIG_SYS_NUM_IRQS)
  33
  34/*
  35 * Interrupt vector functions.
  36 */
  37struct interrupt_action {
  38        interrupt_handler_t *handler;
  39        void *arg;
  40};
  41
  42static struct interrupt_action irq_vecs[NR_IRQS];
  43
  44static __inline__ unsigned short get_sr (void)
  45{
  46        unsigned short sr;
  47
  48        asm volatile ("move.w %%sr,%0":"=r" (sr):);
  49
  50        return sr;
  51}
  52
  53static __inline__ void set_sr (unsigned short sr)
  54{
  55        asm volatile ("move.w %0,%%sr"::"r" (sr));
  56}
  57
  58/************************************************************************/
  59/*
  60 * Install and free an interrupt handler
  61 */
  62void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
  63{
  64        if ((vec < 0) || (vec >= NR_IRQS)) {
  65                printf ("irq_install_handler: wrong interrupt vector %d\n",
  66                        vec);
  67                return;
  68        }
  69
  70        irq_vecs[vec].handler = handler;
  71        irq_vecs[vec].arg = arg;
  72}
  73
  74void irq_free_handler (int vec)
  75{
  76        if ((vec < 0) || (vec >= NR_IRQS)) {
  77                return;
  78        }
  79
  80        irq_vecs[vec].handler = NULL;
  81        irq_vecs[vec].arg = NULL;
  82}
  83
  84void enable_interrupts (void)
  85{
  86        unsigned short sr;
  87
  88        sr = get_sr ();
  89        set_sr (sr & ~0x0700);
  90}
  91
  92int disable_interrupts (void)
  93{
  94        unsigned short sr;
  95
  96        sr = get_sr ();
  97        set_sr (sr | 0x0700);
  98
  99        return ((sr & 0x0700) == 0);    /* return TRUE, if interrupts were enabled before */
 100}
 101
 102void int_handler (struct pt_regs *fp)
 103{
 104        int vec;
 105
 106        vec = (fp->vector >> 2) & 0xff;
 107        if (vec > 0x40)
 108                vec -= 0x40;
 109
 110        if (irq_vecs[vec].handler != NULL) {
 111                irq_vecs[vec].handler (irq_vecs[vec].arg);
 112        } else {
 113                printf ("\nBogus External Interrupt Vector %d\n", vec);
 114        }
 115}
 116