>>even your code (a far as i can see) does not handle all cases:
i should have stressed "afaics" a bit more. you're right. ;-)
>
> needed. In what scenario do you envision a failure? I don't see any.
>
> Thad
Reply by Thad Smith●January 8, 20042004-01-08
markus schorer wrote:
> > If you need to write your own, can you use something like this?
> >
> > InterruptDispatch:
> > repeat
> > acknowledge interrupt -- allows new interrupts to be latched
> > anynew = false
> > for all attached devices
> > if device service request
> > anynew = true
> > handle device interrupt
> > reset device request
> > end for
> > until not anynew
> > return from interrupt
> > end
>
> this is not possible. the kernel does call every registered drivers
> int-handler once for every hw-int.
>
> even your code (a far as i can see) does not handle all cases:
> if you get an int on device 1 while device 3 is checked ("if device
> service request") you won't get "anynew=true", nor receive another
> interrupt (as you still are in int context).
The repeat loop will stay active until all devices report no service
needed. In what scenario do you envision a failure? I don't see any.
Let's say that you get a request for device 1, service it, then get
another request for device 1 when checking other devices. Since device
1 was originally serviced, anynew=true was set for that occurrence and
the devices are rescanned.
It is possible to exit the repeat loop with an interrupt request, but
since by then the interrupt has been acknowledged and determined to have
been clear, any new request will generate a new interrupt request which
will cause the interrupt handler to be reentered as soon as it exits, so
you won't loose the request.
As far as solving the problem in your original context, see if you can
find a Linux driver guru. ;-)
Thad
Reply by markus schorer●January 8, 20042004-01-08
hi,
Thad Smith wrote:
>
> Level detect is more robust than edge detect when interrupts are
> shared. Can you use level detect interrupts?
the problem is, that i'm mixing an int from a ir-remote (that i can
clear immediately) and i2c-devices (that i can not even service in
int-context nor clear the int request). therefore i need to get
an int on every edge of the int requests to be able to decide which
int has been triggered and which one is queued for service.
all of this is connected to a single pc104/isa interrupt.
>
> I am not familiar with Linux, but if you are using it, I presume that it
> would include some code to support shared interrupts.
there is support. you register several int-handlers for a single
interrupt. but i can not control (nor do i know) in what sequence the
handlers are executed (and who is the last one). i can not loop over
all int handlers.
i believe i have to get the int-reqs delayed (in hardware) until the cpu
has left int-context.
> If you need to write your own, can you use something like this?
>
> InterruptDispatch:
> repeat
> acknowledge interrupt -- allows new interrupts to be latched
> anynew = false
> for all attached devices
> if device service request
> anynew = true
> handle device interrupt
> reset device request
> end for
> until not anynew
> return from interrupt
> end
this is not possible. the kernel does call every registered drivers
int-handler once for every hw-int.
even your code (a far as i can see) does not handle all cases:
if you get an int on device 1 while device 3 is checked ("if device
service request") you won't get "anynew=true", nor receive another
interrupt (as you still are in int context).
markus
Reply by Thad Smith●January 7, 20042004-01-07
Markus schorer wrote:
> i have an interrupt-related problem on a self-designed pc104-board:
>
> i have several int-sources connected to a register and an edge-detector.
> if an edge is detected an int is raised. the shared isr's then check
> the register to see if they need to service their device. the int is
> cleared by writing to the register.
Level detect is more robust than edge detect when interrupts are
shared. Can you use level detect interrupts?
I am not familiar with Linux, but if you are using it, I presume that it
would include some code to support shared interrupts.
If you need to write your own, can you use something like this?
InterruptDispatch:
repeat
acknowledge interrupt -- allows new interrupts to be latched
anynew = false
for all attached devices
if device service request
anynew = true
handle device interrupt
reset device request
end for
until not anynew
return from interrupt
end
Basically this stays in the dispatcher until a scan has been made with
no new interrupts. The interrupt is acknowledged before testing, so
that if a new request occurs after the associated device has been
tested, it will trigger a new interrupt. When you exit, you know that
the interrupt line has been cleared since the interrupt was
acknowledged, thereby triggering a new interrupt on a new request.
Thad
Reply by markus schorer●January 7, 20042004-01-07
hi all,
i have an interrupt-related problem on a self-designed pc104-board:
i have several int-sources connected to a register and an edge-detector.
if an edge is detected an int is raised. the shared isr's then check
the register to see if they need to service their device. the int is
cleared by writing to the register.
my problem: sometimes no more ints are generated. reloading a driver
(and thus clearing the int-request) cures this.
the problem seems to be, that every isr clears the int-request (i want
the drivers to be totally independent) and a new int arrives while being
in the int-context. this way the int request is raised but never
serviced in the system isr. with resetting the int req as late as
possible in the isr's, i can reduce the window for this bug.
a solution i can think of is a state machine that queues interrupts.
states would be:
idle goto wait when int raised else stay idle
wait raise int-req,
wait for some cycles for a clear-int, if expiring goto
idle (deactivate int),
if another int-req is received goto queued
queued deassert int-req,
wait for some cycles for a clear-int, if expiring raise int
and goto wait, if another int is received stay queued and
retrigger wait-time
this should queue and delay the int requests. the delay needs to be
longer than every isr's start to clear-req time.
any other ideas?
btw, the above logic is (will) be integrated in an isplsi 1016 from
lattice.
regards,
markus