# rtai_irqops.h

    00001 /*
    00002 COPYRIGHT (C) 2001 Guennadi Liakhovetski, DSA GmbH (gl@dsa-ac.de)
    00003
    00004 This library is free software; you can redistribute it and/or
    00005 modify it under the terms of the GNU Lesser General Public
    00006 License as published by the Free Software Foundation; either
    00007 version 2 of the License, or (at your option) any later version.
    00008
    00009 This library is distributed in the hope that it will be useful,
    00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00012 Lesser General Public License for more details.
    00013
    00014 You should have received a copy of the GNU Lesser General Public
    00015 License along with this library; if not, write to the Free Software
    00016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
    00017 */
    00018
    00019 #ifndef _ASM_IRQOPS_H
    00020 #define _ASM_IRQOPS_H
    00021
    00022 typedef struct {
    00023         struct list_head pending;
    00024         volatile int pend_count;
    00025 } linux_irq_t;
    00026
    00027 static linux_irq_t linux_irqs[NR_IRQS];
    00028
    00029 #define INC_WRAP(x,y) do { x = ++(x) & ((y)-1); } while (0)
    00030
    00031 static inline int llffnz( unsigned long long ull )
    00032 {
    00033         return ((unsigned long *)&ull)[0] ?
    00034                 ffnz( ((unsigned long *)&ull)[0] ) :
    00035                 ( ((unsigned long *)&ull)[1] ?
    00036                   ffnz( ((unsigned long *)&ull)[1] ) + 32 :
    00037                   -1 );
    00038 }
    00039
    00040 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
    00041 #define linux_unmasked(desc) ((desc)->enabled)
    00042 #else
    00043 #define linux_unmasked(desc) (!((desc)->masked || (desc)->disable_depth))
    00044 #endif
    00045
    00046 /* Called with interrupts hard-disabled */
    00047 static inline int have_pending_irq( void )
    00048 {
    00049         linux_irq_t *irq_p;
    00050         struct list_head *listhead_p;
    00051         struct irqdesc *desc;
    00052         int irq;
    00053
    00054         list_for_each(listhead_p, &global.pending_linux_irq) {
    00055                 irq_p = list_entry(listhead_p, linux_irq_t, pending);
    00056                 irq = irq_p - linux_irqs;
    00057                 desc = irq_desc + irq;
    00058                 if (linux_unmasked(desc) &&
    00059                     !(isdemuxirq(irq) && irq_desc[ARCH_MUX_IRQ].running))
    00060                         return irq;
    00061         }
    00062         return NO_IRQ;
    00063 }
    00064
    00065 static inline int have_pending_srq( void )
    00066 {
    00067         return ((global.pending_srqs & ~global.active_srqs) != 0);
    00068 }
    00069
    00070 static inline int active_irq(unsigned int irq)
    00071 {
    00072         return !linux_unmasked(irq_desc + irq);
    00073 }
    00074
    00075 static inline unsigned int pending_srq( void )
    00076 {
    00077         return llffnz(global.pending_srqs & ~global.active_srqs);
    00078 }
    00079
    00080 void rt_pend_linux_irq(unsigned int irq)
    00081 {
    00082         if (!linux_irqs[irq].pend_count++)
    00083                 list_add_tail(&linux_irqs[irq].pending, &global.pending_linux_irq);
    00084 }
    00085
    00086 static inline void clear_pending_irq( unsigned int irq )
    00087 {
    00088         linux_irqs[irq].pend_count = 0;
    00089         list_del(&linux_irqs[irq].pending);
    00090 }
    00091
    00092 static inline void activate_srq( unsigned int srq )
    00093 {
    00094         set_bit(srq, &global.active_srqs);
    00095 }
    00096
    00097 static inline void deactivate_srq( unsigned int srq )
    00098 {
    00099         clear_bit(srq, &global.active_srqs);
    00100 }
    00101
    00102 void rt_pend_linux_srq(unsigned int srq)
    00103 {
    00104         if ( srq < 0 || srq >= NR_SYSRQS ) {
    00105                 printk( "Invalid SRQ! (pend:) %d\n", srq );
    00106                 return;
    00107         }
    00108         set_bit(srq, &global.pending_srqs);
    00109 }
    00110
    00111 static inline void clear_pending_srq( unsigned int srq )
    00112 {
    00113         if ( srq < 0 || srq >= NR_SYSRQS ) {
    00114                 printk( "Invalid SRQ! (clear:) %d\n", srq );
    00115                 return;
    00116         }
    00117         clear_bit(srq, &global.pending_srqs);
    00118 }
    00119
    00120 static inline void init_pending_srqs( void )
    00121 {
    00122         global.pending_srqs = global.active_srqs = 0;
    00123 }
    00124 #endif