Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0 2 : : /* 3 : : * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar 4 : : * 5 : : * This file contains the interrupt probing code and driver APIs. 6 : : */ 7 : : 8 : : #include <linux/irq.h> 9 : : #include <linux/module.h> 10 : : #include <linux/interrupt.h> 11 : : #include <linux/delay.h> 12 : : #include <linux/async.h> 13 : : 14 : : #include "internals.h" 15 : : 16 : : /* 17 : : * Autodetection depends on the fact that any interrupt that 18 : : * comes in on to an unassigned handler will get stuck with 19 : : * "IRQS_WAITING" cleared and the interrupt disabled. 20 : : */ 21 : : static DEFINE_MUTEX(probing_active); 22 : : 23 : : /** 24 : : * probe_irq_on - begin an interrupt autodetect 25 : : * 26 : : * Commence probing for an interrupt. The interrupts are scanned 27 : : * and a mask of potential interrupt lines is returned. 28 : : * 29 : : */ 30 : 0 : unsigned long probe_irq_on(void) 31 : : { 32 : 0 : struct irq_desc *desc; 33 : 0 : unsigned long mask = 0; 34 : 0 : int i; 35 : : 36 : : /* 37 : : * quiesce the kernel, or at least the asynchronous portion 38 : : */ 39 : 0 : async_synchronize_full(); 40 : 0 : mutex_lock(&probing_active); 41 : : /* 42 : : * something may have generated an irq long ago and we want to 43 : : * flush such a longstanding irq before considering it as spurious. 44 : : */ 45 [ # # # # ]: 0 : for_each_irq_desc_reverse(i, desc) { 46 : 0 : raw_spin_lock_irq(&desc->lock); 47 [ # # # # ]: 0 : if (!desc->action && irq_settings_can_probe(desc)) { 48 : : /* 49 : : * Some chips need to know about probing in 50 : : * progress: 51 : : */ 52 [ # # ]: 0 : if (desc->irq_data.chip->irq_set_type) 53 : 0 : desc->irq_data.chip->irq_set_type(&desc->irq_data, 54 : : IRQ_TYPE_PROBE); 55 : 0 : irq_activate_and_startup(desc, IRQ_NORESEND); 56 : : } 57 : 0 : raw_spin_unlock_irq(&desc->lock); 58 : : } 59 : : 60 : : /* Wait for longstanding interrupts to trigger. */ 61 : 0 : msleep(20); 62 : : 63 : : /* 64 : : * enable any unassigned irqs 65 : : * (we must startup again here because if a longstanding irq 66 : : * happened in the previous stage, it may have masked itself) 67 : : */ 68 [ # # # # ]: 0 : for_each_irq_desc_reverse(i, desc) { 69 : 0 : raw_spin_lock_irq(&desc->lock); 70 [ # # # # ]: 0 : if (!desc->action && irq_settings_can_probe(desc)) { 71 : 0 : desc->istate |= IRQS_AUTODETECT | IRQS_WAITING; 72 [ # # ]: 0 : if (irq_activate_and_startup(desc, IRQ_NORESEND)) 73 : 0 : desc->istate |= IRQS_PENDING; 74 : : } 75 : 0 : raw_spin_unlock_irq(&desc->lock); 76 : : } 77 : : 78 : : /* 79 : : * Wait for spurious interrupts to trigger 80 : : */ 81 : 0 : msleep(100); 82 : : 83 : : /* 84 : : * Now filter out any obviously spurious interrupts 85 : : */ 86 [ # # # # ]: 0 : for_each_irq_desc(i, desc) { 87 : 0 : raw_spin_lock_irq(&desc->lock); 88 : : 89 [ # # ]: 0 : if (desc->istate & IRQS_AUTODETECT) { 90 : : /* It triggered already - consider it spurious. */ 91 [ # # ]: 0 : if (!(desc->istate & IRQS_WAITING)) { 92 : 0 : desc->istate &= ~IRQS_AUTODETECT; 93 : 0 : irq_shutdown_and_deactivate(desc); 94 : : } else 95 [ # # ]: 0 : if (i < 32) 96 : 0 : mask |= 1 << i; 97 : : } 98 : 0 : raw_spin_unlock_irq(&desc->lock); 99 : : } 100 : : 101 : 0 : return mask; 102 : : } 103 : : EXPORT_SYMBOL(probe_irq_on); 104 : : 105 : : /** 106 : : * probe_irq_mask - scan a bitmap of interrupt lines 107 : : * @val: mask of interrupts to consider 108 : : * 109 : : * Scan the interrupt lines and return a bitmap of active 110 : : * autodetect interrupts. The interrupt probe logic state 111 : : * is then returned to its previous value. 112 : : * 113 : : * Note: we need to scan all the irq's even though we will 114 : : * only return autodetect irq numbers - just so that we reset 115 : : * them all to a known state. 116 : : */ 117 : 0 : unsigned int probe_irq_mask(unsigned long val) 118 : : { 119 : 0 : unsigned int mask = 0; 120 : 0 : struct irq_desc *desc; 121 : 0 : int i; 122 : : 123 [ # # # # ]: 0 : for_each_irq_desc(i, desc) { 124 : 0 : raw_spin_lock_irq(&desc->lock); 125 [ # # ]: 0 : if (desc->istate & IRQS_AUTODETECT) { 126 [ # # # # ]: 0 : if (i < 16 && !(desc->istate & IRQS_WAITING)) 127 : 0 : mask |= 1 << i; 128 : : 129 : 0 : desc->istate &= ~IRQS_AUTODETECT; 130 : 0 : irq_shutdown_and_deactivate(desc); 131 : : } 132 : 0 : raw_spin_unlock_irq(&desc->lock); 133 : : } 134 : 0 : mutex_unlock(&probing_active); 135 : : 136 : 0 : return mask & val; 137 : : } 138 : : EXPORT_SYMBOL(probe_irq_mask); 139 : : 140 : : /** 141 : : * probe_irq_off - end an interrupt autodetect 142 : : * @val: mask of potential interrupts (unused) 143 : : * 144 : : * Scans the unused interrupt lines and returns the line which 145 : : * appears to have triggered the interrupt. If no interrupt was 146 : : * found then zero is returned. If more than one interrupt is 147 : : * found then minus the first candidate is returned to indicate 148 : : * their is doubt. 149 : : * 150 : : * The interrupt probe logic state is returned to its previous 151 : : * value. 152 : : * 153 : : * BUGS: When used in a module (which arguably shouldn't happen) 154 : : * nothing prevents two IRQ probe callers from overlapping. The 155 : : * results of this are non-optimal. 156 : : */ 157 : 0 : int probe_irq_off(unsigned long val) 158 : : { 159 : 0 : int i, irq_found = 0, nr_of_irqs = 0; 160 : 0 : struct irq_desc *desc; 161 : : 162 [ # # # # ]: 0 : for_each_irq_desc(i, desc) { 163 : 0 : raw_spin_lock_irq(&desc->lock); 164 : : 165 [ # # ]: 0 : if (desc->istate & IRQS_AUTODETECT) { 166 [ # # ]: 0 : if (!(desc->istate & IRQS_WAITING)) { 167 [ # # ]: 0 : if (!nr_of_irqs) 168 : 0 : irq_found = i; 169 : 0 : nr_of_irqs++; 170 : : } 171 : 0 : desc->istate &= ~IRQS_AUTODETECT; 172 : 0 : irq_shutdown_and_deactivate(desc); 173 : : } 174 : 0 : raw_spin_unlock_irq(&desc->lock); 175 : : } 176 : 0 : mutex_unlock(&probing_active); 177 : : 178 [ # # ]: 0 : if (nr_of_irqs > 1) 179 : 0 : irq_found = -irq_found; 180 : : 181 : 0 : return irq_found; 182 : : } 183 : : EXPORT_SYMBOL(probe_irq_off); 184 : :