summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/shared/include/genirq.h
blob: 673be173b131a0bc97edf93f18f49bc61a5f84c0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* General Shared Interrupt handling function interface 
 *
 * The functions does not manipulate the IRQ controller or the 
 * interrupt level of the CPU. It simply helps the caller with
 * managing shared interrupts where multiple interrupt routines
 * share on interrupt vector/number.
 *
 * COPYRIGHT (c) 2008.
 * Cobham Gaisler AB.
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rtems.org/license/LICENSE.
 */

#ifndef __GENIRQ_H__
#define __GENIRQ_H__

#ifdef __cplusplus
extern "C" {
#endif

typedef void (*genirq_handler)(void *arg);
typedef void* genirq_t;

struct genirq_stats {
	unsigned int	irq_cnt;
};

/* Initialize the genirq interface. Must be the first function
 * called.
 *
 * Returns zero on success, otherwise failure.
 */
extern genirq_t genirq_init(int number_of_irqs);

/* Free the dynamically allocated memory that the genirq interface has 
 * allocated. Also the handlers will be freed.
 *
 * Returns zero on success, otherwise failure.
 */
extern void genirq_destroy(genirq_t d);

/* Check IRQ number validity 
 * 
 * Returns zero for valid IRQ numbers, -1 of invalid IRQ numbers.
 */
extern int genirq_check(genirq_t d, int irq);

/* Allocate one ISR handler and initialize it. Input to genirq_register().
 *
 * \param isr    The interrupt service routine called upon IRQ
 * \param arg    The argument given to isr() when called.
 *
 * Returns a pointer on success, on failure NULL is returned.
 */
extern void *genirq_alloc_handler(genirq_handler isr, void *arg);

/* Free handler memory */
#define genirq_free_handler(handler) free(handler)

/* Register shared interrupt handler previously initialized with
 * genirq_alloc_handler().
 *
 * NOTE: internal list structures are accessed and needs to be protected by
 *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
 *
 * \param irq    The interrupt number to register ISR on
 * \param handler Install the pre- allocated and initialized handler.
 *
 * Return Values
 * -1  = Failed
 * 0   = Handler registered Successfully, first handler on this IRQ
 * 1   = Handler registered Successfully, _not_ first handler on this IRQ
 */
extern int genirq_register(genirq_t d, int irq, void *handler);

/* Unregister an previous registered interrupt handler. It is the user's
 * responsibility to free the handler returned by genirq_unregister().
 *
 * NOTE: internal list structures are accessed and needs to be protected by
 *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
 *
 * Return Values
 * NULL    = ISR not registered before or unable to unregister enabled ISR
 * Pointer = ISR sucessfully unregistered. Returned is the handler pointer
 *           previously allocated with genirq_alloc_handler().
 */
extern void *genirq_unregister(genirq_t d, int irq,
				genirq_handler isr, void *arg);

/* Enables IRQ only for this isr[arg] combination. Records if this 
 * is the first interrupt enable, only then must interrupts be enabled
 * on the interrupt controller.
 *
 * NOTE: internal list structures are accessed and needs to be protected by
 *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
 *
 * Return values
 *  -1 = Failure, for example isr[arg] not registered on this irq
 *  0  = IRQ must be enabled, it is the first IRQ handler to be enabled
 *  1  = IRQ has already been enabled, either by isr[arg] or by another handler
 */
extern int genirq_enable(genirq_t d, int irq, genirq_handler isr, void *arg);

/* Disables IRQ only for this isr[arg] combination. Records if this 
 * is the only interrupt handler that is enabled on this IRQ, only then
 * must interrupts be disabled on the interrupt controller.
 *
 * NOTE: internal list structures are accessed and needs to be protected by
 *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
 *
 * Return values
 *  -1 = Failure, for example isr[arg] not registered on this irq
 *  0  = IRQ must be disabled, no ISR are enabled for this IRQ
 *  1  = ISR has already been disabled, or other ISRs are still enabled
 */
extern int genirq_disable(genirq_t d, int irq, genirq_handler isr, void *arg);

/* Must be called by user when an IRQ has fired, the argument 'irq' 
 * is the IRQ number of the IRQ which was fired.
 *
 * NOTE: internal list structures are accessed and needs to be protected by
 *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
 */
extern void genirq_doirq(genirq_t d, int irq);

#ifdef __cplusplus
}
#endif

#endif