/* * 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 */ }