Day 13 - Debounce + Workqueue + Event-driven Driver¶
📅 Date¶
2026-XX-XX
🎯 Summary¶
Today I implemented a complete event-driven GPIO driver with:
- IRQ handling
- Software debounce using workqueue
- Ring buffer event queue
- Blocking read + poll support
This is a major step toward real Linux driver design.
🔧 What I Built¶
Architecture:
Features:
- Interrupt-driven button detection
- Debounce filtering
- Multiple event buffering
- Non-blocking I/O support
- poll/select support
💡 Key Learnings¶
1. ISR Design¶
- Keep ISR minimal
- Defer work to bottom half
2. Debounce Strategy¶
- Delay sampling
- Compare with last stable state
3. Event Queue¶
- Ring buffer prevents data loss
- Producer/consumer separation
4. Synchronization¶
- mutex protects shared data
- volatile is NOT needed
- lockless check is acceptable in kernel
5. wait queue + poll¶
- wait_event → blocking read
- wake_up → notify user space
- poll → event-driven model
⚠️ Issues & Fixes¶
Issue 1: GPIO logic reversed¶
- Cause: GPIO_ACTIVE_LOW
- Fix: Understand gpiod logical mapping
Issue 2: race concern (head/tail)¶
- Found that:
- lockless check is acceptable
- kernel design allows it
🚀 What I Achieved¶
This driver now resembles:
- input subsystem behavior
- event-driven Linux drivers
- real production design pattern
🔜 Next Step¶
- Event timestamp
- Multi-event read
- sysfs config (debounce_ms)
- epoll stress testing