root/kernel/irq/autoprobe.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. probe_irq_on
  2. probe_irq_mask
  3. probe_irq_off

   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 unsigned long probe_irq_on(void)
  31 {
  32         struct irq_desc *desc;
  33         unsigned long mask = 0;
  34         int i;
  35 
  36         /*
  37          * quiesce the kernel, or at least the asynchronous portion
  38          */
  39         async_synchronize_full();
  40         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         for_each_irq_desc_reverse(i, desc) {
  46                 raw_spin_lock_irq(&desc->lock);
  47                 if (!desc->action && irq_settings_can_probe(desc)) {
  48                         /*
  49                          * Some chips need to know about probing in
  50                          * progress:
  51                          */
  52                         if (desc->irq_data.chip->irq_set_type)
  53                                 desc->irq_data.chip->irq_set_type(&desc->irq_data,
  54                                                          IRQ_TYPE_PROBE);
  55                         irq_activate_and_startup(desc, IRQ_NORESEND);
  56                 }
  57                 raw_spin_unlock_irq(&desc->lock);
  58         }
  59 
  60         /* Wait for longstanding interrupts to trigger. */
  61         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         for_each_irq_desc_reverse(i, desc) {
  69                 raw_spin_lock_irq(&desc->lock);
  70                 if (!desc->action && irq_settings_can_probe(desc)) {
  71                         desc->istate |= IRQS_AUTODETECT | IRQS_WAITING;
  72                         if (irq_activate_and_startup(desc, IRQ_NORESEND))
  73                                 desc->istate |= IRQS_PENDING;
  74                 }
  75                 raw_spin_unlock_irq(&desc->lock);
  76         }
  77 
  78         /*
  79          * Wait for spurious interrupts to trigger
  80          */
  81         msleep(100);
  82 
  83         /*
  84          * Now filter out any obviously spurious interrupts
  85          */
  86         for_each_irq_desc(i, desc) {
  87                 raw_spin_lock_irq(&desc->lock);
  88 
  89                 if (desc->istate & IRQS_AUTODETECT) {
  90                         /* It triggered already - consider it spurious. */
  91                         if (!(desc->istate & IRQS_WAITING)) {
  92                                 desc->istate &= ~IRQS_AUTODETECT;
  93                                 irq_shutdown_and_deactivate(desc);
  94                         } else
  95                                 if (i < 32)
  96                                         mask |= 1 << i;
  97                 }
  98                 raw_spin_unlock_irq(&desc->lock);
  99         }
 100 
 101         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 unsigned int probe_irq_mask(unsigned long val)
 118 {
 119         unsigned int mask = 0;
 120         struct irq_desc *desc;
 121         int i;
 122 
 123         for_each_irq_desc(i, desc) {
 124                 raw_spin_lock_irq(&desc->lock);
 125                 if (desc->istate & IRQS_AUTODETECT) {
 126                         if (i < 16 && !(desc->istate & IRQS_WAITING))
 127                                 mask |= 1 << i;
 128 
 129                         desc->istate &= ~IRQS_AUTODETECT;
 130                         irq_shutdown_and_deactivate(desc);
 131                 }
 132                 raw_spin_unlock_irq(&desc->lock);
 133         }
 134         mutex_unlock(&probing_active);
 135 
 136         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 int probe_irq_off(unsigned long val)
 158 {
 159         int i, irq_found = 0, nr_of_irqs = 0;
 160         struct irq_desc *desc;
 161 
 162         for_each_irq_desc(i, desc) {
 163                 raw_spin_lock_irq(&desc->lock);
 164 
 165                 if (desc->istate & IRQS_AUTODETECT) {
 166                         if (!(desc->istate & IRQS_WAITING)) {
 167                                 if (!nr_of_irqs)
 168                                         irq_found = i;
 169                                 nr_of_irqs++;
 170                         }
 171                         desc->istate &= ~IRQS_AUTODETECT;
 172                         irq_shutdown_and_deactivate(desc);
 173                 }
 174                 raw_spin_unlock_irq(&desc->lock);
 175         }
 176         mutex_unlock(&probing_active);
 177 
 178         if (nr_of_irqs > 1)
 179                 irq_found = -irq_found;
 180 
 181         return irq_found;
 182 }
 183 EXPORT_SYMBOL(probe_irq_off);
 184 

/* [<][>][^][v][top][bottom][index][help] */