#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