00001 00041 #include <compiler.h> 00042 #include <interrupt.h> 00043 #include <softirq.h> 00044 #include <util.h> 00045 00046 #include <app/softirq.h> 00047 00048 struct softirq_desc { 00049 softirq_handler_t handler; 00050 void *data; 00051 }; 00052 00057 unsigned long softirq_priv_status; 00058 00059 static struct softirq_desc softirq_table[SOFTIRQ_NR_IDS]; 00060 00067 void softirq_set_handler(unsigned int id, softirq_handler_t handler, void *data) 00068 { 00069 struct softirq_desc *desc; 00070 00071 build_assert(ARRAY_LEN(softirq_table) 00072 <= 8 * sizeof(softirq_priv_status)); 00073 assert(id < ARRAY_LEN(softirq_table)); 00074 assert(handler); 00075 00076 desc = &softirq_table[id]; 00077 desc->handler = handler; 00078 desc->data = data; 00079 } 00080 00094 void softirq_priv_do_pending(void) 00095 { 00096 struct softirq_desc *desc; 00097 unsigned int id; 00098 00099 assert(!cpu_irq_is_enabled()); 00100 assert(!(sysreg_read(SR) & (SYSREG_SR_IM(0) | SYSREG_SR_IM(1) 00101 | SYSREG_SR_IM(2) | SYSREG_SR_IM(3)))); 00102 assert(softirq_priv_status); 00103 00104 do { 00105 id = __ffs(softirq_priv_status); 00106 assert(id < ARRAY_LEN(softirq_table)); 00107 clear_bit(id, &softirq_priv_status); 00108 00109 cpu_irq_enable(); 00110 00111 desc = &softirq_table[id]; 00112 assert(desc->handler); 00113 desc->handler(desc->data); 00114 00115 cpu_irq_disable(); 00116 } while (softirq_priv_status); 00117 00118 assert(!cpu_irq_is_enabled()); 00119 } 00120 00129 void softirq_enable(void) 00130 { 00131 assert(cpu_irq_is_enabled()); 00132 00133 cpu_irq_disable(); 00134 if (softirq_priv_status) 00135 softirq_priv_do_pending(); 00136 avr32_clear_sr_bit(SYSREG_SR_T_BIT); 00137 cpu_irq_enable(); 00138 }
1.5.8