0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/irq.h>
0009 #include <linux/module.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/delay.h>
0012 #include <linux/async.h>
0013
0014 #include "internals.h"
0015
0016
0017
0018
0019
0020
0021 static DEFINE_MUTEX(probing_active);
0022
0023
0024
0025
0026
0027
0028
0029
0030 unsigned long probe_irq_on(void)
0031 {
0032 struct irq_desc *desc;
0033 unsigned long mask = 0;
0034 int i;
0035
0036
0037
0038
0039 async_synchronize_full();
0040 mutex_lock(&probing_active);
0041
0042
0043
0044
0045 for_each_irq_desc_reverse(i, desc) {
0046 raw_spin_lock_irq(&desc->lock);
0047 if (!desc->action && irq_settings_can_probe(desc)) {
0048
0049
0050
0051
0052 if (desc->irq_data.chip->irq_set_type)
0053 desc->irq_data.chip->irq_set_type(&desc->irq_data,
0054 IRQ_TYPE_PROBE);
0055 irq_activate_and_startup(desc, IRQ_NORESEND);
0056 }
0057 raw_spin_unlock_irq(&desc->lock);
0058 }
0059
0060
0061 msleep(20);
0062
0063
0064
0065
0066
0067
0068 for_each_irq_desc_reverse(i, desc) {
0069 raw_spin_lock_irq(&desc->lock);
0070 if (!desc->action && irq_settings_can_probe(desc)) {
0071 desc->istate |= IRQS_AUTODETECT | IRQS_WAITING;
0072 if (irq_activate_and_startup(desc, IRQ_NORESEND))
0073 desc->istate |= IRQS_PENDING;
0074 }
0075 raw_spin_unlock_irq(&desc->lock);
0076 }
0077
0078
0079
0080
0081 msleep(100);
0082
0083
0084
0085
0086 for_each_irq_desc(i, desc) {
0087 raw_spin_lock_irq(&desc->lock);
0088
0089 if (desc->istate & IRQS_AUTODETECT) {
0090
0091 if (!(desc->istate & IRQS_WAITING)) {
0092 desc->istate &= ~IRQS_AUTODETECT;
0093 irq_shutdown_and_deactivate(desc);
0094 } else
0095 if (i < 32)
0096 mask |= 1 << i;
0097 }
0098 raw_spin_unlock_irq(&desc->lock);
0099 }
0100
0101 return mask;
0102 }
0103 EXPORT_SYMBOL(probe_irq_on);
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 unsigned int probe_irq_mask(unsigned long val)
0118 {
0119 unsigned int mask = 0;
0120 struct irq_desc *desc;
0121 int i;
0122
0123 for_each_irq_desc(i, desc) {
0124 raw_spin_lock_irq(&desc->lock);
0125 if (desc->istate & IRQS_AUTODETECT) {
0126 if (i < 16 && !(desc->istate & IRQS_WAITING))
0127 mask |= 1 << i;
0128
0129 desc->istate &= ~IRQS_AUTODETECT;
0130 irq_shutdown_and_deactivate(desc);
0131 }
0132 raw_spin_unlock_irq(&desc->lock);
0133 }
0134 mutex_unlock(&probing_active);
0135
0136 return mask & val;
0137 }
0138 EXPORT_SYMBOL(probe_irq_mask);
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 int probe_irq_off(unsigned long val)
0158 {
0159 int i, irq_found = 0, nr_of_irqs = 0;
0160 struct irq_desc *desc;
0161
0162 for_each_irq_desc(i, desc) {
0163 raw_spin_lock_irq(&desc->lock);
0164
0165 if (desc->istate & IRQS_AUTODETECT) {
0166 if (!(desc->istate & IRQS_WAITING)) {
0167 if (!nr_of_irqs)
0168 irq_found = i;
0169 nr_of_irqs++;
0170 }
0171 desc->istate &= ~IRQS_AUTODETECT;
0172 irq_shutdown_and_deactivate(desc);
0173 }
0174 raw_spin_unlock_irq(&desc->lock);
0175 }
0176 mutex_unlock(&probing_active);
0177
0178 if (nr_of_irqs > 1)
0179 irq_found = -irq_found;
0180
0181 return irq_found;
0182 }
0183 EXPORT_SYMBOL(probe_irq_off);
0184