Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:42

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /* General Shared Interrupt handling function interface 
0004  *
0005  * The functions does not manipulate the IRQ controller or the 
0006  * interrupt level of the CPU. It simply helps the caller with
0007  * managing shared interrupts where multiple interrupt routines
0008  * share on interrupt vector/number.
0009  *
0010  * COPYRIGHT (c) 2008.
0011  * Cobham Gaisler AB.
0012  *
0013  * Redistribution and use in source and binary forms, with or without
0014  * modification, are permitted provided that the following conditions
0015  * are met:
0016  * 1. Redistributions of source code must retain the above copyright
0017  *    notice, this list of conditions and the following disclaimer.
0018  * 2. Redistributions in binary form must reproduce the above copyright
0019  *    notice, this list of conditions and the following disclaimer in the
0020  *    documentation and/or other materials provided with the distribution.
0021  *
0022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0025  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0032  * POSSIBILITY OF SUCH DAMAGE.
0033  */
0034 
0035 #ifndef __GENIRQ_H__
0036 #define __GENIRQ_H__
0037 
0038 #ifdef __cplusplus
0039 extern "C" {
0040 #endif
0041 
0042 typedef void (*genirq_handler)(void *arg);
0043 typedef void* genirq_t;
0044 
0045 struct genirq_stats {
0046     unsigned int    irq_cnt;
0047 };
0048 
0049 /* Initialize the genirq interface. Must be the first function
0050  * called.
0051  *
0052  * Returns zero on success, otherwise failure.
0053  */
0054 extern genirq_t genirq_init(int number_of_irqs);
0055 
0056 /* Free the dynamically allocated memory that the genirq interface has 
0057  * allocated. Also the handlers will be freed.
0058  *
0059  * Returns zero on success, otherwise failure.
0060  */
0061 extern void genirq_destroy(genirq_t d);
0062 
0063 /* Check IRQ number validity 
0064  * 
0065  * Returns zero for valid IRQ numbers, -1 of invalid IRQ numbers.
0066  */
0067 extern int genirq_check(genirq_t d, int irq);
0068 
0069 /* Allocate one ISR handler and initialize it. Input to genirq_register().
0070  *
0071  * \param isr    The interrupt service routine called upon IRQ
0072  * \param arg    The argument given to isr() when called.
0073  *
0074  * Returns a pointer on success, on failure NULL is returned.
0075  */
0076 extern void *genirq_alloc_handler(genirq_handler isr, void *arg);
0077 
0078 /* Free handler memory */
0079 #define genirq_free_handler(handler) free(handler)
0080 
0081 /* Register shared interrupt handler previously initialized with
0082  * genirq_alloc_handler().
0083  *
0084  * NOTE: internal list structures are accessed and needs to be protected by
0085  *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
0086  *
0087  * \param irq    The interrupt number to register ISR on
0088  * \param handler Install the pre- allocated and initialized handler.
0089  *
0090  * Return Values
0091  * -1  = Failed
0092  * 0   = Handler registered Successfully, first handler on this IRQ
0093  * 1   = Handler registered Successfully, _not_ first handler on this IRQ
0094  */
0095 extern int genirq_register(genirq_t d, int irq, void *handler);
0096 
0097 /* Unregister an previous registered interrupt handler. It is the user's
0098  * responsibility to free the handler returned by genirq_unregister().
0099  *
0100  * NOTE: internal list structures are accessed and needs to be protected by
0101  *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
0102  *
0103  * Return Values
0104  * NULL    = ISR not registered before or unable to unregister enabled ISR
0105  * Pointer = ISR sucessfully unregistered. Returned is the handler pointer
0106  *           previously allocated with genirq_alloc_handler().
0107  */
0108 extern void *genirq_unregister(genirq_t d, int irq,
0109                 genirq_handler isr, void *arg);
0110 
0111 /* Enables IRQ only for this isr[arg] combination. Records if this 
0112  * is the first interrupt enable, only then must interrupts be enabled
0113  * on the interrupt controller.
0114  *
0115  * NOTE: internal list structures are accessed and needs to be protected by
0116  *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
0117  *
0118  * Return values
0119  *  -1 = Failure, for example isr[arg] not registered on this irq
0120  *  0  = IRQ must be enabled, it is the first IRQ handler to be enabled
0121  *  1  = IRQ has already been enabled, either by isr[arg] or by another handler
0122  */
0123 extern int genirq_enable(genirq_t d, int irq, genirq_handler isr, void *arg);
0124 
0125 /* Disables IRQ only for this isr[arg] combination. Records if this 
0126  * is the only interrupt handler that is enabled on this IRQ, only then
0127  * must interrupts be disabled on the interrupt controller.
0128  *
0129  * NOTE: internal list structures are accessed and needs to be protected by
0130  *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
0131  *
0132  * Return values
0133  *  -1 = Failure, for example isr[arg] not registered on this irq
0134  *  0  = IRQ must be disabled, no ISR are enabled for this IRQ
0135  *  1  = ISR has already been disabled, or other ISRs are still enabled
0136  */
0137 extern int genirq_disable(genirq_t d, int irq, genirq_handler isr, void *arg);
0138 
0139 /* Must be called by user when an IRQ has fired, the argument 'irq' 
0140  * is the IRQ number of the IRQ which was fired.
0141  *
0142  * NOTE: internal list structures are accessed and needs to be protected by
0143  *       spin-locks/IRQ disable by the user to guarantee a correct behaviour.
0144  */
0145 extern void genirq_doirq(genirq_t d, int irq);
0146 
0147 #ifdef __cplusplus
0148 }
0149 #endif
0150 
0151 #endif