Thank you Edwin, I will test your solution and say you what happens.
Have a nice day. Maxime --- In [email protected], Edwin van den Oetelaar <[EMAIL PROTECTED]> wrote: > > maxime_coquelin schreef: > > Hi everybody, > > > > For my project, I need to use the PA0 pin as an interrupt to handle > > the \int pin of the pcf8574 chip (which is a I2C-8-bit controller). I > > have used the work done by calzo(Foxdoc.pdf on lugman.net, thank's to > > him). > > I succeed in building the module and the IRQ is well requested. To do > > that, I have to invert the \int pin of the pcf8574. > > > > The problem I have is that the interrupt is handeld on the high state > > (and not on the front), so, when a logic state change on the pcf8574, > > the PA0 pin goes to high, and it generates thousand of interrupts, > > whereas I need only one. > > > > Here is the code made by Calzo : > > > > #include <linux/interrupt.h> > > #include <linux/module.h> > > #include <asm/io.h> //provide access to GPIO port and other > > MODULE_LICENSE("DUAL GPL/BSD"); > > MODULE_VERSION("0.1"); > > #define IRQ_PA_MASK 0x01 //interrupt sul pulsante > > static DEFINE_SPINLOCK(gpio_lock_irq); > > > > /***** FUNZIONE DI INTERRUPT ****** > > * In questa funzione viene disabilitata temporaneamente la > > * possibilità di ricevere altri interrupt fino a che non è > > * soddisfatta la funzione seguente > > * ********************************/ > > static irqreturn_t > > irqPA_interrupt(int irq, void *dev_id, struct pt_regs *regs) > > { > > *R_IRQ_MASK1_CLR = 0; > > *R_PORT_PA_DATA = 0; //fondamentale! > > printk(KERN_ALERT "calzo - irq servito\n"); > > return IRQ_HANDLED; > > } > > /**************************************** > > * INITIALIZATION & CLEANUP functions > > ****************************************/ > > /// Funzione di inizializzazione del modulo > > int irqPA_init_module(void) { > > if (request_irq(PA_IRQ_NBR, irqPA_interrupt, > > SA_INTERRUPT,"calzo gpio PA interrupt", NULL)) > > { > > printk(KERN_CRIT "err: PA irq for gpio (calzo)\n"); > > return -ERESTART; > > } > > //setto su quale pin vi è línterrupt valido > > *R_IRQ_MASK1_SET = IRQ_PA_MASK; > > return 0; > > } > > ///Funzione di scaricamento del modulo > > void irqPA_cleanup_module(void) { > > spin_lock_irq(&gpio_lock_irq); > > *R_IRQ_MASK1_SET = 0; > > *R_IRQ_MASK1_CLR = 0; > > free_irq(PA_IRQ_NBR, NULL); > > spin_unlock_irq(&gpio_lock_irq); > > } > > /*************************************** > > * INIT & EXIT > > ***************************************/ > > module_init(irqPA_init_module); > > module_exit(irqPA_cleanup_module); > > > > Do you understand my problem? And do you see how to disable the irq > > once one is received? > > > > Thank's in advance. > > > > Maxime Coquelin > > > > > I see your problem. > What I can tell it works like this : > 1) you get an interrupt, you set flag and disable further interrupts > from this pin > 2) you read the contents of your pc8574 which clears the interrupt (from > tasklet) > 3) you reset flag and enable interrupts again (from tasklet) > note: you can not lose events this way from your i2c device if you > enable interrupts again directly after the > read from the device. The device will keep on interrupting you again > until you do a i2c read or write. > > Just my opinion, you should also talk to john Crispin, he knows about > this stuff. > check out page 274 of Linux Device Drivers 3rd edition and the functions > local_irq_save(unsigned long flags); > local_irq_restore(unsigned long flags); > You might want to split this in a top and bottom half (page 275) using a > tasklet. > > Good luck, > Edwin van den Oetelaar >
