drivers/w1/masters/omap_hdq.c
Source file repositories/reference/linux-study-clean/drivers/w1/masters/omap_hdq.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/w1/masters/omap_hdq.c- Extension
.c- Size
- 17197 bytes
- Lines
- 682
- Domain
- Driver Families
- Bucket
- drivers/w1
- 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.
- 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/kernel.hlinux/module.hlinux/platform_device.hlinux/interrupt.hlinux/slab.hlinux/err.hlinux/io.hlinux/sched.hlinux/pm_runtime.hlinux/of.hlinux/w1.h
Detected Declarations
struct hdq_datafunction hdq_reg_infunction hdq_reg_outfunction hdq_reg_mergefunction hdq_wait_for_flagfunction hdq_reset_irqstatusfunction hdq_write_bytefunction hdq_isrfunction omap_w1_search_busfunction omap_hdq_breakfunction hdq_read_bytefunction omap_w1_tripletfunction omap_w1_reset_busfunction omap_w1_read_bytefunction omap_w1_write_bytefunction omap_hdq_runtime_suspendfunction omap_hdq_runtime_resumefunction omap_hdq_probefunction omap_hdq_remove
Annotated Snippet
struct hdq_data {
struct device *dev;
void __iomem *hdq_base;
/* lock read/write/break operations */
struct mutex hdq_mutex;
/* interrupt status and a lock for it */
u8 hdq_irqstatus;
spinlock_t hdq_spinlock;
/* mode: 0-HDQ 1-W1 */
int mode;
};
/* HDQ register I/O routines */
static inline u8 hdq_reg_in(struct hdq_data *hdq_data, u32 offset)
{
return __raw_readl(hdq_data->hdq_base + offset);
}
static inline void hdq_reg_out(struct hdq_data *hdq_data, u32 offset, u8 val)
{
__raw_writel(val, hdq_data->hdq_base + offset);
}
static inline u8 hdq_reg_merge(struct hdq_data *hdq_data, u32 offset,
u8 val, u8 mask)
{
u8 new_val = (__raw_readl(hdq_data->hdq_base + offset) & ~mask)
| (val & mask);
__raw_writel(new_val, hdq_data->hdq_base + offset);
return new_val;
}
/*
* Wait for one or more bits in flag change.
* HDQ_FLAG_SET: wait until any bit in the flag is set.
* HDQ_FLAG_CLEAR: wait until all bits in the flag are cleared.
* return 0 on success and -ETIMEDOUT in the case of timeout.
*/
static int hdq_wait_for_flag(struct hdq_data *hdq_data, u32 offset,
u8 flag, u8 flag_set, u8 *status)
{
int ret = 0;
unsigned long timeout = jiffies + OMAP_HDQ_TIMEOUT;
if (flag_set == OMAP_HDQ_FLAG_CLEAR) {
/* wait for the flag clear */
while (((*status = hdq_reg_in(hdq_data, offset)) & flag)
&& time_before(jiffies, timeout)) {
schedule_timeout_uninterruptible(1);
}
if (*status & flag)
ret = -ETIMEDOUT;
} else if (flag_set == OMAP_HDQ_FLAG_SET) {
/* wait for the flag set */
while (!((*status = hdq_reg_in(hdq_data, offset)) & flag)
&& time_before(jiffies, timeout)) {
schedule_timeout_uninterruptible(1);
}
if (!(*status & flag))
ret = -ETIMEDOUT;
} else
return -EINVAL;
return ret;
}
/* Clear saved irqstatus after using an interrupt */
static u8 hdq_reset_irqstatus(struct hdq_data *hdq_data, u8 bits)
{
unsigned long irqflags;
u8 status;
spin_lock_irqsave(&hdq_data->hdq_spinlock, irqflags);
status = hdq_data->hdq_irqstatus;
/* this is a read-modify-write */
hdq_data->hdq_irqstatus &= ~bits;
spin_unlock_irqrestore(&hdq_data->hdq_spinlock, irqflags);
return status;
}
/* write out a byte and fill *status with HDQ_INT_STATUS */
static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status)
{
int ret;
u8 tmp_status;
ret = mutex_lock_interruptible(&hdq_data->hdq_mutex);
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/platform_device.h`, `linux/interrupt.h`, `linux/slab.h`, `linux/err.h`, `linux/io.h`, `linux/sched.h`.
- Detected declarations: `struct hdq_data`, `function hdq_reg_in`, `function hdq_reg_out`, `function hdq_reg_merge`, `function hdq_wait_for_flag`, `function hdq_reset_irqstatus`, `function hdq_write_byte`, `function hdq_isr`, `function omap_w1_search_bus`, `function omap_hdq_break`.
- Atlas domain: Driver Families / drivers/w1.
- Implementation status: source 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.