1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

properly handling shared-interrupts in hardware and linux-driver

Discussion in 'Embedded' started by markus schorer, Jan 7, 2004.

  1. 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
     
    markus schorer, Jan 7, 2004
    #1
    1. Advertisements

  2. markus schorer

    Thad Smith Guest

    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
     
    Thad Smith, Jan 7, 2004
    #2
    1. Advertisements

  3. hi,

    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.
    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.
    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
     
    markus schorer, Jan 8, 2004
    #3
  4. markus schorer

    Thad Smith Guest

    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
     
    Thad Smith, Jan 8, 2004
    #4
  5. i should have stressed "afaics" a bit more. you're right. ;-)
     
    markus schorer, Jan 9, 2004
    #5
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.