Skip to content

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:

IRQ → workqueue → event queue → wait queue → user space

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