OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [arch/] [s390/] [kernel/] [s390_ext.c] - Blame information for rev 63

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 63 marcus.erl
/*
2
 *  arch/s390/kernel/s390_ext.c
3
 *
4
 *  S390 version
5
 *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
6
 *    Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com),
7
 *               Martin Schwidefsky (schwidefsky@de.ibm.com)
8
 */
9
 
10
#include <linux/module.h>
11
#include <linux/kernel.h>
12
#include <linux/slab.h>
13
#include <linux/errno.h>
14
#include <linux/kernel_stat.h>
15
#include <linux/interrupt.h>
16
 
17
#include <asm/lowcore.h>
18
#include <asm/s390_ext.h>
19
#include <asm/irq_regs.h>
20
#include <asm/irq.h>
21
 
22
/*
23
 * ext_int_hash[index] is the start of the list for all external interrupts
24
 * that hash to this index. With the current set of external interrupts
25
 * (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000
26
 * iucv and 0x2603 pfault) this is always the first element.
27
 */
28
ext_int_info_t *ext_int_hash[256] = { NULL, };
29
 
30
static inline int ext_hash(__u16 code)
31
{
32
        return (code + (code >> 9)) & 0xff;
33
}
34
 
35
int register_external_interrupt(__u16 code, ext_int_handler_t handler)
36
{
37
        ext_int_info_t *p;
38
        int index;
39
 
40
        p = kmalloc(sizeof(ext_int_info_t), GFP_ATOMIC);
41
        if (p == NULL)
42
                return -ENOMEM;
43
        p->code = code;
44
        p->handler = handler;
45
        index = ext_hash(code);
46
        p->next = ext_int_hash[index];
47
        ext_int_hash[index] = p;
48
        return 0;
49
}
50
 
51
int register_early_external_interrupt(__u16 code, ext_int_handler_t handler,
52
                                      ext_int_info_t *p)
53
{
54
        int index;
55
 
56
        if (p == NULL)
57
                return -EINVAL;
58
        p->code = code;
59
        p->handler = handler;
60
        index = ext_hash(code);
61
        p->next = ext_int_hash[index];
62
        ext_int_hash[index] = p;
63
        return 0;
64
}
65
 
66
int unregister_external_interrupt(__u16 code, ext_int_handler_t handler)
67
{
68
        ext_int_info_t *p, *q;
69
        int index;
70
 
71
        index = ext_hash(code);
72
        q = NULL;
73
        p = ext_int_hash[index];
74
        while (p != NULL) {
75
                if (p->code == code && p->handler == handler)
76
                        break;
77
                q = p;
78
                p = p->next;
79
        }
80
        if (p == NULL)
81
                return -ENOENT;
82
        if (q != NULL)
83
                q->next = p->next;
84
        else
85
                ext_int_hash[index] = p->next;
86
        kfree(p);
87
        return 0;
88
}
89
 
90
int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
91
                                        ext_int_info_t *p)
92
{
93
        ext_int_info_t *q;
94
        int index;
95
 
96
        if (p == NULL || p->code != code || p->handler != handler)
97
                return -EINVAL;
98
        index = ext_hash(code);
99
        q = ext_int_hash[index];
100
        if (p != q) {
101
                while (q != NULL) {
102
                        if (q->next == p)
103
                                break;
104
                        q = q->next;
105
                }
106
                if (q == NULL)
107
                        return -ENOENT;
108
                q->next = p->next;
109
        } else
110
                ext_int_hash[index] = p->next;
111
        return 0;
112
}
113
 
114
void do_extint(struct pt_regs *regs, unsigned short code)
115
{
116
        ext_int_info_t *p;
117
        int index;
118
        struct pt_regs *old_regs;
119
 
120
        old_regs = set_irq_regs(regs);
121
        irq_enter();
122
        asm volatile ("mc 0,0");
123
        if (S390_lowcore.int_clock >= S390_lowcore.jiffy_timer)
124
                /**
125
                 * Make sure that the i/o interrupt did not "overtake"
126
                 * the last HZ timer interrupt.
127
                 */
128
                account_ticks(S390_lowcore.int_clock);
129
        kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
130
        index = ext_hash(code);
131
        for (p = ext_int_hash[index]; p; p = p->next) {
132
                if (likely(p->code == code))
133
                        p->handler(code);
134
        }
135
        irq_exit();
136
        set_irq_regs(old_regs);
137
}
138
 
139
EXPORT_SYMBOL(register_external_interrupt);
140
EXPORT_SYMBOL(unregister_external_interrupt);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.