drivers/mfd/ipaq-micro.c
Source file repositories/reference/linux-study-clean/drivers/mfd/ipaq-micro.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mfd/ipaq-micro.c- Extension
.c- Size
- 11107 bytes
- Lines
- 443
- Domain
- Driver Families
- Bucket
- drivers/mfd
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/module.hlinux/init.hlinux/interrupt.hlinux/pm.hlinux/delay.hlinux/device.hlinux/platform_device.hlinux/io.hlinux/mfd/core.hlinux/mfd/ipaq-micro.hlinux/string.hlinux/string_choices.hlinux/random.hlinux/slab.hlinux/list.hmach/hardware.h
Detected Declarations
function ipaq_micro_trigger_txfunction ipaq_micro_tx_msgfunction micro_rx_msgfunction micro_process_charfunction micro_rx_charsfunction ipaq_micro_get_versionfunction ipaq_micro_eeprom_readfunction ipaq_micro_to_u16function ipaq_micro_eeprom_dumpfunction micro_tx_charsfunction micro_reset_commfunction micro_serial_isrfunction micro_resumefunction micro_probeexport ipaq_micro_tx_msg
Annotated Snippet
if (micro->msg && micro->msg->id == id) {
struct ipaq_micro_msg *msg = micro->msg;
memcpy(msg->rx_data, data, len);
msg->rx_len = len;
complete(µ->msg->ack);
if (!list_empty(µ->queue)) {
micro->msg = list_entry(micro->queue.next,
struct ipaq_micro_msg,
node);
list_del_init(µ->msg->node);
ipaq_micro_trigger_tx(micro);
} else
micro->msg = NULL;
dev_dbg(micro->dev, "OK RX message 0x%02x\n", id);
} else {
dev_err(micro->dev,
"out of band RX message 0x%02x\n", id);
if (!micro->msg)
dev_info(micro->dev, "no message queued\n");
else
dev_info(micro->dev, "expected message %02x\n",
micro->msg->id);
}
break;
case MSG_KEYBOARD:
if (micro->key)
micro->key(micro->key_data, len, data);
else
dev_dbg(micro->dev, "key message ignored, no handle\n");
break;
case MSG_TOUCHSCREEN:
if (micro->ts)
micro->ts(micro->ts_data, len, data);
else
dev_dbg(micro->dev, "touchscreen message ignored, no handle\n");
break;
default:
dev_err(micro->dev,
"unknown msg %d [%d] %*ph\n", id, len, len, data);
break;
}
spin_unlock(µ->lock);
}
static void micro_process_char(struct ipaq_micro *micro, u8 ch)
{
struct ipaq_micro_rxdev *rx = µ->rx;
switch (rx->state) {
case STATE_SOF: /* Looking for SOF */
if (ch == CHAR_SOF)
rx->state = STATE_ID; /* Next byte is the id and len */
break;
case STATE_ID: /* Looking for id and len byte */
rx->id = (ch & 0xf0) >> 4;
rx->len = (ch & 0x0f);
rx->index = 0;
rx->chksum = ch;
rx->state = (rx->len > 0) ? STATE_DATA : STATE_CHKSUM;
break;
case STATE_DATA: /* Looking for 'len' data bytes */
rx->chksum += ch;
rx->buf[rx->index] = ch;
if (++rx->index == rx->len)
rx->state = STATE_CHKSUM;
break;
case STATE_CHKSUM: /* Looking for the checksum */
if (ch == rx->chksum)
micro_rx_msg(micro, rx->id, rx->len, rx->buf);
rx->state = STATE_SOF;
break;
}
}
static void micro_rx_chars(struct ipaq_micro *micro)
{
u32 status, ch;
while ((status = readl(micro->base + UTSR1)) & UTSR1_RNE) {
ch = readl(micro->base + UTDR);
if (status & UTSR1_PRE)
dev_err(micro->dev, "rx: parity error\n");
else if (status & UTSR1_FRE)
dev_err(micro->dev, "rx: framing error\n");
else if (status & UTSR1_ROR)
dev_err(micro->dev, "rx: overrun error\n");
micro_process_char(micro, ch);
}
}
Annotation
- Immediate include surface: `linux/module.h`, `linux/init.h`, `linux/interrupt.h`, `linux/pm.h`, `linux/delay.h`, `linux/device.h`, `linux/platform_device.h`, `linux/io.h`.
- Detected declarations: `function ipaq_micro_trigger_tx`, `function ipaq_micro_tx_msg`, `function micro_rx_msg`, `function micro_process_char`, `function micro_rx_chars`, `function ipaq_micro_get_version`, `function ipaq_micro_eeprom_read`, `function ipaq_micro_to_u16`, `function ipaq_micro_eeprom_dump`, `function micro_tx_chars`.
- Atlas domain: Driver Families / drivers/mfd.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.