/*
* 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 */
}
Copyright © 1994 - 2019 Linux Journal. All rights reserved.