~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/arch/openrisc/cpu/interrupts.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2011, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
 
3
 * (C) Copyright 2011, Julius Baxter <julius@opencores.org>
 
4
 *
 
5
 * SPDX-License-Identifier:     GPL-2.0+
 
6
 */
 
7
 
 
8
#include <common.h>
 
9
#include <asm/types.h>
 
10
#include <asm/ptrace.h>
 
11
#include <asm/system.h>
 
12
#include <asm/openrisc_exc.h>
 
13
 
 
14
struct irq_action {
 
15
        interrupt_handler_t *handler;
 
16
        void *arg;
 
17
        int count;
 
18
};
 
19
 
 
20
static struct irq_action handlers[32];
 
21
 
 
22
void interrupt_handler(void)
 
23
{
 
24
        int irq;
 
25
 
 
26
        while ((irq = ffs(mfspr(SPR_PICSR)))) {
 
27
                if (handlers[--irq].handler) {
 
28
                        handlers[irq].handler(handlers[irq].arg);
 
29
                        handlers[irq].count++;
 
30
                } else {
 
31
                        /* disable the interrupt */
 
32
                        mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1 << irq));
 
33
                        printf("Unhandled interrupt: %d\n", irq);
 
34
                }
 
35
                /* clear the interrupt */
 
36
                mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1 << irq));
 
37
        }
 
38
}
 
39
 
 
40
int interrupt_init(void)
 
41
{
 
42
        /* install handler for external interrupt exception */
 
43
        exception_install_handler(EXC_EXT_IRQ, interrupt_handler);
 
44
        /* Enable interrupts in supervisor register */
 
45
        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
 
46
 
 
47
        return 0;
 
48
}
 
49
 
 
50
void enable_interrupts(void)
 
51
{
 
52
        /* Set interrupt enable bit in supervisor register */
 
53
        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
 
54
        /* Enable timer exception */
 
55
        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_TEE);
 
56
}
 
57
 
 
58
int disable_interrupts(void)
 
59
{
 
60
        /* Clear interrupt enable bit in supervisor register */
 
61
        mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_IEE);
 
62
        /* Disable timer exception */
 
63
        mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_TEE);
 
64
 
 
65
        return 0;
 
66
}
 
67
 
 
68
void irq_install_handler(int irq, interrupt_handler_t *handler, void *arg)
 
69
{
 
70
        if (irq < 0 || irq > 31)
 
71
                return;
 
72
 
 
73
        handlers[irq].handler = handler;
 
74
        handlers[irq].arg = arg;
 
75
}
 
76
 
 
77
void irq_free_handler(int irq)
 
78
{
 
79
        if (irq < 0 || irq > 31)
 
80
                return;
 
81
 
 
82
        handlers[irq].handler = 0;
 
83
        handlers[irq].arg = 0;
 
84
}
 
85
 
 
86
#if defined(CONFIG_CMD_IRQ)
 
87
int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
88
{
 
89
        int i;
 
90
 
 
91
        printf("\nInterrupt-Information:\n\n");
 
92
        printf("Nr  Routine   Arg       Count\n");
 
93
        printf("-----------------------------\n");
 
94
 
 
95
        for (i = 0; i < 32; i++) {
 
96
                if (handlers[i].handler) {
 
97
                        printf("%02d  %08lx  %08lx  %d\n",
 
98
                                i,
 
99
                                (ulong)handlers[i].handler,
 
100
                                (ulong)handlers[i].arg,
 
101
                                handlers[i].count);
 
102
                }
 
103
        }
 
104
        printf("\n");
 
105
 
 
106
        return 0;
 
107
}
 
108
#endif