LJ Archive
/*
 * This function only counts interrupts, and is used for probing
 */
Static void skel_trial_fn(int irq, struct pt_regs *unused)
{
  int i;
  Skel_Hw *board;
  for (i=0, board=skel_hw; i<skel_boards; board++, i++)
      if (board->irq==irq)
          break;
  if (i==cxg_boards) /* not mine... shouldn't happen */
      return;
  skel_acknowledge_the_interrupt()
  board->irqcount++;
}
/*
 * the autodetection function, which probes the possible interrupt lines
 */
Static int skel_find(Skel_Hw *board)
{
  if ( failed_first_probe )
      return -ENODEV;
  /* do any more probing here... */
  if ( failed_last_probe )
      return -ENODEV;
  /* found */
  if (board==skel_hw && skel_irq>=0) { /* first board, and explicit irq */
      board->hwirq=skel_irq; /* trust it */
      board->irq=-1;
  } else {
      static int tryings[]={3,4,5,7,-1}; /* irq lines to try */
      int i, trial, err;
      for (i=0; (trial=tryings[i]) >= 0; i++) {
          if (request_irq(trial, skel_trial_fn, SA_INTERRUPT, "skel") != 0)
              continue; /* irq line busy */
          board->hwirq = board->irq = trial;
          board->irqcount = 0;
          tell_the_device_to_generate_interrupts
          sleep_for_enough_time
          tell_the_device_NOT_to_generate_interrupts
          free_irq(board->irq);
          board->irq = -1;
          if (board->irqcount > 0) /* did I get interrupts on this line?
          */
              break;
          else
              board->hwirq = -1;
      }
  }
  if (board->hwirq == -1) {
      printk(KERN_NOTICE "skel: found board but no irq line\n");
      return -EADDRNOTAVAIL; /* or accept it, at your will */
  }
  return 0; /* all right */
}
LJ Archive