drivers/comedi/drivers/comedi_8254.c
Source file repositories/reference/linux-study-clean/drivers/comedi/drivers/comedi_8254.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/comedi/drivers/comedi_8254.c- Extension
.c- Size
- 19951 bytes
- Lines
- 730
- Domain
- Driver Families
- Bucket
- drivers/comedi
- 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.
- 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/slab.hlinux/io.hlinux/comedi/comedidev.hlinux/comedi/comedi_8254.h
Detected Declarations
function comedi_8254_readfunction i8254_io16_cbfunction i8254_io32_cbfunction i8254_mmio8_cbfunction i8254_mmio16_cbfunction i8254_mmio32_cbfunction __i8254_readfunction __i8254_writefunction comedi_8254_statusfunction comedi_8254_readfunction comedi_8254_writefunction comedi_8254_set_modefunction comedi_8254_loadfunction comedi_8254_pacer_enablefunction comedi_8254_update_divisorsfunction comedi_8254_cascade_ns_to_timerfunction comedi_8254_ns_to_timerfunction comedi_8254_set_busyfunction comedi_8254_insn_readfunction comedi_8254_insn_writefunction comedi_8254_insn_configfunction comedi_8254_subdevice_initexport comedi_8254_statusexport comedi_8254_readexport comedi_8254_writeexport comedi_8254_set_modeexport comedi_8254_loadexport comedi_8254_pacer_enableexport comedi_8254_update_divisorsexport comedi_8254_cascade_ns_to_timerexport comedi_8254_ns_to_timerexport comedi_8254_set_busyexport comedi_8254_subdevice_initexport comedi_8254_io_allocexport comedi_8254_mm_alloc
Annotated Snippet
if (ns <= *nanosec && ns > ns_glb) {
ns_glb = ns;
d1_glb = d1;
d2_glb = d2;
}
if (ns >= *nanosec && ns < ns_lub) {
ns_lub = ns;
d1_lub = d1;
d2_lub = d2;
}
}
}
switch (flags & CMDF_ROUND_MASK) {
case CMDF_ROUND_NEAREST:
default:
ns_high = d1_lub * d2_lub * i8254->osc_base;
ns_low = d1_glb * d2_glb * i8254->osc_base;
if (ns_high - *nanosec < *nanosec - ns_low) {
d1 = d1_lub;
d2 = d2_lub;
} else {
d1 = d1_glb;
d2 = d2_glb;
}
break;
case CMDF_ROUND_UP:
d1 = d1_lub;
d2 = d2_lub;
break;
case CMDF_ROUND_DOWN:
d1 = d1_glb;
d2 = d2_glb;
break;
}
*nanosec = d1 * d2 * i8254->osc_base;
i8254->next_div1 = d1;
i8254->next_div2 = d2;
}
EXPORT_SYMBOL_GPL(comedi_8254_cascade_ns_to_timer);
/**
* comedi_8254_ns_to_timer - calculate the divisor value for nanosec timing
* @i8254: comedi_8254 struct for the timer
* @nanosec: the desired ns time
* @flags: comedi_cmd flags
*/
void comedi_8254_ns_to_timer(struct comedi_8254 *i8254,
unsigned int *nanosec, unsigned int flags)
{
unsigned int divisor;
switch (flags & CMDF_ROUND_MASK) {
default:
case CMDF_ROUND_NEAREST:
divisor = DIV_ROUND_CLOSEST(*nanosec, i8254->osc_base);
break;
case CMDF_ROUND_UP:
divisor = DIV_ROUND_UP(*nanosec, i8254->osc_base);
break;
case CMDF_ROUND_DOWN:
divisor = *nanosec / i8254->osc_base;
break;
}
if (divisor < 2)
divisor = 2;
if (divisor > I8254_MAX_COUNT)
divisor = I8254_MAX_COUNT;
*nanosec = divisor * i8254->osc_base;
i8254->next_div = divisor;
}
EXPORT_SYMBOL_GPL(comedi_8254_ns_to_timer);
/**
* comedi_8254_set_busy - set/clear the "busy" flag for a given counter
* @i8254: comedi_8254 struct for the timer
* @counter: the counter number
* @busy: set/clear flag
*/
void comedi_8254_set_busy(struct comedi_8254 *i8254,
unsigned int counter, bool busy)
{
if (counter < 3)
i8254->busy[counter] = busy;
}
EXPORT_SYMBOL_GPL(comedi_8254_set_busy);
static int comedi_8254_insn_read(struct comedi_device *dev,
Annotation
- Immediate include surface: `linux/module.h`, `linux/slab.h`, `linux/io.h`, `linux/comedi/comedidev.h`, `linux/comedi/comedi_8254.h`.
- Detected declarations: `function comedi_8254_read`, `function i8254_io16_cb`, `function i8254_io32_cb`, `function i8254_mmio8_cb`, `function i8254_mmio16_cb`, `function i8254_mmio32_cb`, `function __i8254_read`, `function __i8254_write`, `function comedi_8254_status`, `function comedi_8254_read`.
- Atlas domain: Driver Families / drivers/comedi.
- Implementation status: integration implementation candidate.
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.