drivers/input/serio/ps2-gpio.c
Source file repositories/reference/linux-study-clean/drivers/input/serio/ps2-gpio.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/input/serio/ps2-gpio.c- Extension
.c- Size
- 12509 bytes
- Lines
- 505
- Domain
- Driver Families
- Bucket
- drivers/input
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/gpio/consumer.hlinux/interrupt.hlinux/module.hlinux/serio.hlinux/slab.hlinux/platform_device.hlinux/workqueue.hlinux/completion.hlinux/mutex.hlinux/preempt.hlinux/property.hlinux/of.hlinux/jiffies.hlinux/delay.hlinux/timekeeping.h
Detected Declarations
struct ps2_gpio_datafunction ps2_gpio_openfunction ps2_gpio_closefunction __ps2_gpio_writefunction ps2_gpio_writefunction ps2_gpio_tx_work_fnfunction ps2_gpio_irq_rxfunction ps2_gpio_irq_txfunction ps2_gpio_irqfunction ps2_gpio_get_propsfunction ps2_gpio_probefunction ps2_gpio_remove
Annotated Snippet
struct ps2_gpio_data {
struct device *dev;
struct serio *serio;
unsigned char mode;
struct gpio_desc *gpio_clk;
struct gpio_desc *gpio_data;
bool write_enable;
int irq;
ktime_t t_irq_now;
ktime_t t_irq_last;
struct {
unsigned char cnt;
unsigned char byte;
} rx;
struct {
unsigned char cnt;
unsigned char byte;
ktime_t t_xfer_start;
ktime_t t_xfer_end;
struct completion complete;
struct mutex mutex;
struct delayed_work work;
} tx;
};
static int ps2_gpio_open(struct serio *serio)
{
struct ps2_gpio_data *drvdata = serio->port_data;
drvdata->t_irq_last = 0;
drvdata->tx.t_xfer_end = 0;
enable_irq(drvdata->irq);
return 0;
}
static void ps2_gpio_close(struct serio *serio)
{
struct ps2_gpio_data *drvdata = serio->port_data;
flush_delayed_work(&drvdata->tx.work);
disable_irq(drvdata->irq);
}
static int __ps2_gpio_write(struct serio *serio, unsigned char val)
{
struct ps2_gpio_data *drvdata = serio->port_data;
disable_irq_nosync(drvdata->irq);
gpiod_direction_output(drvdata->gpio_clk, 0);
drvdata->mode = PS2_MODE_TX;
drvdata->tx.byte = val;
schedule_delayed_work(&drvdata->tx.work, usecs_to_jiffies(200));
return 0;
}
static int ps2_gpio_write(struct serio *serio, unsigned char val)
{
struct ps2_gpio_data *drvdata = serio->port_data;
int ret = 0;
if (in_task()) {
guard(mutex)(&drvdata->tx.mutex);
__ps2_gpio_write(serio, val);
if (!wait_for_completion_timeout(&drvdata->tx.complete,
msecs_to_jiffies(10000)))
ret = SERIO_TIMEOUT;
} else {
__ps2_gpio_write(serio, val);
}
return ret;
}
static void ps2_gpio_tx_work_fn(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
struct ps2_gpio_data *drvdata = container_of(dwork,
struct ps2_gpio_data,
tx.work);
drvdata->tx.t_xfer_start = ktime_get();
enable_irq(drvdata->irq);
gpiod_direction_output(drvdata->gpio_data, 0);
gpiod_direction_input(drvdata->gpio_clk);
}
Annotation
- Immediate include surface: `linux/gpio/consumer.h`, `linux/interrupt.h`, `linux/module.h`, `linux/serio.h`, `linux/slab.h`, `linux/platform_device.h`, `linux/workqueue.h`, `linux/completion.h`.
- Detected declarations: `struct ps2_gpio_data`, `function ps2_gpio_open`, `function ps2_gpio_close`, `function __ps2_gpio_write`, `function ps2_gpio_write`, `function ps2_gpio_tx_work_fn`, `function ps2_gpio_irq_rx`, `function ps2_gpio_irq_tx`, `function ps2_gpio_irq`, `function ps2_gpio_get_props`.
- Atlas domain: Driver Families / drivers/input.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.