From: Greg B. <gb...@po...> - 2001-03-01 02:26:11
|
"M. R. Brown" wrote: > G'day > Does anyone know a nice, clean way (or not so clean) to handle multiple > incoming interrupts from within controller-specific (e.g. setup_xxx.c) > code? irq_demux() doesn't cut it as it only returns one int per IRQ (but > I receive at least one normal int and two NMIs per IRQ), and even if I > wanted to queue ints within irq_demux, the semantics wouldn't work as I > have no pt_regs structure with which to call handle_IRQ_event. > > Reading other archs and linuxsh sources didn't help, has anyone had to > deal with this? > I had to muck about with IRQ handling to get PCMCIA working right. It seems to me there's a fairly strong assumption in the code that one hardware IRQ = one software IRQ handler called. This assumption seems to break when interrupt muxing hardware is used, but actually it doesn't because of the way muxes work. What normally happens with muxed IRQ is: 1. mux hardware gets interrupt from module A 2. mux hw gets interrupt from module B 3. mux hardware sends IRQ to CPU by asserting its IRQ line 4. CPU services IRQ. Linux masks the IRQ line from the mux (through the hw_interrupt_type) and calls irq_demux() 5. irq_demux() reads a register from the mux, sees that module A has generated an interrupt, clears that bit in the register, and returns the (virtual) IRQ number for module A. 6. Linux calls registered handlers for the module A IRQ number. 7. Linux unmasks the IRQ line from the mux (again through hw_interrupt_type) 8. The mux at this point knows that the interrupt from module A has been serviced by the CPU, but that another interrupt from module B is still pending, so it has kept the IRQ line to the CPU asserted. This immediately triggers another IRQ in the CPU. 9. Linux repeats steps 4-7, this time dispatching registered handlers for the virtual IRQ number for module B. 10. The mux has now had both interrupts serviced and finally de-asserts its IRQ line to the CPU, so its all over. In other words, this relies on the interrupt mux hardware being able to sensibly store state for its various modules, which is a fairly basic requirement. The above sequence describes how the interrupt controller in the HD64465 companion chip works. If you have some hardware that behaves differently, you might need to do something different; otherwise you can use the existing Linux arrangement. Certainly by setting up your own hw_interrupt_type and irq_demux() you can do all sorts of clever things, but the question is: do you need to? Can you explain a bit more about your setup? Greg. -- These are my opinions not PPIs. |