Skip to content

Day 13 - Debounce + Bottom Half (Workqueue / Timer)

Overview

In this chapter, we improve the GPIO interrupt driver by introducing:

  • Software debounce using delayed work
  • Proper top half / bottom half design
  • Event-driven architecture with stable input

Why Debounce is Needed

Mechanical buttons do not produce clean transitions.

Instead of:

0 → 1

We often get:

0 → 1 → 0 → 1 → 1 → 0 → 1

This is called bounce.


Design Approach

We implement debounce using:

IRQ (top half)
schedule delayed work
bottom half (process context)
read stable GPIO value
generate event (if changed)

Top Half vs Bottom Half

Top Half (ISR)

Responsibilities:

  • Triggered by hardware interrupt
  • Must be fast and non-blocking
  • Cannot sleep

Implementation:

mod_delayed_work(system_wq, &mydev->btn_dwork, delay);

Bottom Half (Delayed Work)

Responsibilities:

  • Runs in process context
  • Can sleep
  • Performs debounce and event generation

Key API:

gpiod_get_value_cansleep()

Debounce Logic

Core idea:

if (new_value != last_reported_state)
    generate event

This ensures:

  • No duplicate events
  • Only stable transitions are reported

Event Flow

Complete pipeline:

GPIO IRQ
 → ISR (top half)
 → delayed work (bottom half)
 → update event state
 → wake_up_interruptible()
 → read() / poll()
 → user space

Logical vs Raw GPIO

With Device Tree:

GPIO_ACTIVE_LOW

Kernel automatically converts:

Physical Level Logical Value
LOW 1 (pressed)
HIGH 0 (released)

Driver should always expose:

pressed / released (logical)

Key Kernel APIs

Workqueue

INIT_DELAYED_WORK()
mod_delayed_work()
cancel_delayed_work_sync()

Wait Queue

wait_event_interruptible()
wake_up_interruptible()

Poll

poll_wait()
POLLIN | POLLRDNORM

Design Guidelines

  • Keep ISR minimal
  • Use bottom half for heavy work
  • Always debounce GPIO input
  • Expose logical state to user space
  • Avoid duplicate events

Summary

Day13 transforms the driver into a more realistic Linux design:

  • Interrupt-safe
  • Debounced
  • Event-driven
  • User-space friendly

This is a foundation for real input drivers.