source: rtems/c/src/lib/libbsp/sparc/shared/include/genirq.h @ 8670c464

5
Last change on this file since 8670c464 was 8670c464, checked in by Daniel Hellstrom <daniel@…>, on May 5, 2017 at 1:42:45 PM

leon, genirq: SMP support for PCI peripherals

The common interrupt layer for GRLIB PCI perihperals is prepared for SMP
support by this patch. The existing locking (interrupt disabling) is
replaced by a new requirement on the user to implement locking before
calling the genirq API. This approach avoids taking more locks than
necessary.

The split up of the locks also introduces that the user must allocate
memory to describe ISR handlers, to avoid calling malloc()/free() while
possessing a spin-lock and interrupts are globally disabled.

  • Property mode set to 100644
File size: 4.5 KB
Line 
1/* General Shared Interrupt handling function interface
2 *
3 * The functions does not manipulate the IRQ controller or the
4 * interrupt level of the CPU. It simply helps the caller with
5 * managing shared interrupts where multiple interrupt routines
6 * share on interrupt vector/number.
7 *
8 * COPYRIGHT (c) 2008.
9 * Cobham Gaisler AB.
10 *
11 * The license and distribution terms for this file may be
12 * found in the file LICENSE in this distribution or at
13 * http://www.rtems.org/license/LICENSE.
14 */
15
16#ifndef __GENIRQ_H__
17#define __GENIRQ_H__
18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23typedef void (*genirq_handler)(void *arg);
24typedef void* genirq_t;
25
26struct genirq_stats {
27        unsigned int    irq_cnt;
28};
29
30/* Initialize the genirq interface. Must be the first function
31 * called.
32 *
33 * Returns zero on success, otherwise failure.
34 */
35extern genirq_t genirq_init(int number_of_irqs);
36
37/* Free the dynamically allocated memory that the genirq interface has
38 * allocated. Also the handlers will be freed.
39 *
40 * Returns zero on success, otherwise failure.
41 */
42extern void genirq_destroy(genirq_t d);
43
44/* Check IRQ number validity
45 *
46 * Returns zero for valid IRQ numbers, -1 of invalid IRQ numbers.
47 */
48extern int genirq_check(genirq_t d, int irq);
49
50/* Allocate one ISR handler and initialize it. Input to genirq_register().
51 *
52 * \param isr    The interrupt service routine called upon IRQ
53 * \param arg    The argument given to isr() when called.
54 *
55 * Returns a pointer on success, on failure NULL is returned.
56 */
57extern void *genirq_alloc_handler(genirq_handler isr, void *arg);
58
59/* Free handler memory */
60#define genirq_free_handler(handler) free(handler)
61
62/* Register shared interrupt handler previously initialized with
63 * genirq_alloc_handler().
64 *
65 * NOTE: internal list structures are accessed and needs to be protected by
66 *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
67 *
68 * \param irq    The interrupt number to register ISR on
69 * \param handler Install the pre- allocated and initialized handler.
70 *
71 * Return Values
72 * -1  = Failed
73 * 0   = Handler registered Successfully, first handler on this IRQ
74 * 1   = Handler registered Successfully, _not_ first handler on this IRQ
75 */
76extern int genirq_register(genirq_t d, int irq, void *handler);
77
78/* Unregister an previous registered interrupt handler. It is the user's
79 * responsibility to free the handler returned by genirq_unregister().
80 *
81 * NOTE: internal list structures are accessed and needs to be protected by
82 *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
83 *
84 * Return Values
85 * NULL    = ISR not registered before or unable to unregister enabled ISR
86 * Pointer = ISR sucessfully unregistered. Returned is the handler pointer
87 *           previously allocated with genirq_alloc_handler().
88 */
89extern void *genirq_unregister(genirq_t d, int irq,
90                                genirq_handler isr, void *arg);
91
92/* Enables IRQ only for this isr[arg] combination. Records if this
93 * is the first interrupt enable, only then must interrupts be enabled
94 * on the interrupt controller.
95 *
96 * NOTE: internal list structures are accessed and needs to be protected by
97 *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
98 *
99 * Return values
100 *  -1 = Failure, for example isr[arg] not registered on this irq
101 *  0  = IRQ must be enabled, it is the first IRQ handler to be enabled
102 *  1  = IRQ has already been enabled, either by isr[arg] or by another handler
103 */
104extern int genirq_enable(genirq_t d, int irq, genirq_handler isr, void *arg);
105
106/* Disables IRQ only for this isr[arg] combination. Records if this
107 * is the only interrupt handler that is enabled on this IRQ, only then
108 * must interrupts be disabled on the interrupt controller.
109 *
110 * NOTE: internal list structures are accessed and needs to be protected by
111 *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
112 *
113 * Return values
114 *  -1 = Failure, for example isr[arg] not registered on this irq
115 *  0  = IRQ must be disabled, no ISR are enabled for this IRQ
116 *  1  = ISR has already been disabled, or other ISRs are still enabled
117 */
118extern int genirq_disable(genirq_t d, int irq, genirq_handler isr, void *arg);
119
120/* Must be called by user when an IRQ has fired, the argument 'irq'
121 * is the IRQ number of the IRQ which was fired.
122 *
123 * NOTE: internal list structures are accessed and needs to be protected by
124 *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
125 */
126extern void genirq_doirq(genirq_t d, int irq);
127
128#ifdef __cplusplus
129}
130#endif
131
132#endif
Note: See TracBrowser for help on using the repository browser.