#pragma once #include #include #include //-------------- 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 ); }