zmatt icon

uio-irq.h

zmatt | PRO | 03/03/23 02:23:53 PM UTC (Edited) | 0 ⭐ | 683 👁️ | Never ⏰ | []
C++ |

1.42 KB

|

None

|

0 👍

/

0 👎

#pragma once
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
 
//-------------- UIO interrupt handling --------------------------------------//
//
// All functions here return 0 on success or negated errno on failure.
//
// The uio device has an event-counter, initialized to zero at device creation.
// Whenever an irq is recognized the counter is incremented and the fd becomes
// readable.  You read the event counter from the fd to rearm the mechanism.
//
inline int uio_wfi( int fd, uint32_t *counter_out = nullptr )
{
    uint32_t tmp;  // in case caller doesn't care about the counter
    ssize_t n = read( fd, counter_out ?: &tmp, sizeof *counter_out );
    if( n < 0 )
        return -errno;
    assert( (size_t)n == sizeof *counter_out );
    return 0;
}
 
 
// Driver-specific irq control.
//
inline int uio_irqcontrol( int fd, uint32_t value )
{
    ssize_t n = write( fd, &value, sizeof value );
    if( n < 0 )
        return -errno;
    assert( (size_t)n == sizeof value );
    return 0;
}
 
 
// Generic IRQ control used by some uio drivers, notably uio_pdrv_genirq.
//
// Note that uio_pdrv_genirq automatically disables the irq when it triggers,
// and you'll need to reenable it yourself each time.
//
// See https://pastebin.com/x0sUKmKa for more details.
//
inline int uio_generic_irqenable( int fd )
{
    return uio_irqcontrol( fd, 1 );
}
inline int uio_generic_irqdisable( int fd )
{
    return uio_irqcontrol( fd, 0 );
}

Comments