sound/pci/ctxfi/cttimer.c
Source file repositories/reference/linux-study-clean/sound/pci/ctxfi/cttimer.c
File Facts
- System
- Linux kernel
- Corpus path
sound/pci/ctxfi/cttimer.c- Extension
.c- Size
- 10546 bytes
- Lines
- 423
- Domain
- Driver Families
- Bucket
- sound/pci
- 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.
- 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/slab.hlinux/math64.hlinux/moduleparam.hsound/core.hsound/pcm.hctatc.hcthardware.hcttimer.h
Detected Declarations
struct ct_timer_opsstruct ct_timer_instancestruct ct_timerfunction ct_systimer_callbackfunction ct_systimer_initfunction ct_systimer_startfunction ct_systimer_stopfunction ct_systimer_preparefunction ct_xfitimer_irq_rearmfunction ct_xfitimer_irq_stopfunction ct_xfitimer_get_wcfunction snd_pcm_period_elapsedfunction ct_xfitimer_check_periodfunction ct_xfitimer_callbackfunction ct_xfitimer_preparefunction ct_xfitimer_updatefunction ct_xfitimer_startfunction scoped_guardfunction ct_xfitimer_stopfunction scoped_guardfunction ct_xfitimer_free_globalfunction ct_timer_instance_newfunction scoped_guardfunction ct_timer_preparefunction ct_timer_startfunction ct_timer_stopfunction ct_timer_instance_freefunction scoped_guardfunction ct_timer_interruptfunction ct_timer_free
Annotated Snippet
struct ct_timer_ops {
void (*init)(struct ct_timer_instance *);
void (*prepare)(struct ct_timer_instance *);
void (*start)(struct ct_timer_instance *);
void (*stop)(struct ct_timer_instance *);
void (*free_instance)(struct ct_timer_instance *);
void (*interrupt)(struct ct_timer *);
void (*free_global)(struct ct_timer *);
};
/* timer instance -- assigned to each PCM stream */
struct ct_timer_instance {
spinlock_t lock;
struct ct_timer *timer_base;
struct ct_atc_pcm *apcm;
struct snd_pcm_substream *substream;
struct timer_list timer;
struct list_head instance_list;
struct list_head running_list;
unsigned int position;
unsigned int frag_count;
unsigned int running:1;
unsigned int need_update:1;
};
/* timer instance manager */
struct ct_timer {
spinlock_t lock; /* global timer lock (for xfitimer) */
spinlock_t list_lock; /* lock for instance list */
struct ct_atc *atc;
const struct ct_timer_ops *ops;
struct list_head instance_head;
struct list_head running_head;
unsigned int wc; /* current wallclock */
unsigned int irq_handling:1; /* in IRQ handling */
unsigned int reprogram:1; /* need to reprogram the internval */
unsigned int running:1; /* global timer running */
};
/*
* system-timer-based updates
*/
static void ct_systimer_callback(struct timer_list *t)
{
struct ct_timer_instance *ti = timer_container_of(ti, t, timer);
struct snd_pcm_substream *substream = ti->substream;
struct snd_pcm_runtime *runtime = substream->runtime;
struct ct_atc_pcm *apcm = ti->apcm;
unsigned int period_size = runtime->period_size;
unsigned int buffer_size = runtime->buffer_size;
unsigned int position, dist, interval;
position = substream->ops->pointer(substream);
dist = (position + buffer_size - ti->position) % buffer_size;
if (dist >= period_size ||
position / period_size != ti->position / period_size) {
apcm->interrupt(apcm);
ti->position = position;
}
/* Add extra HZ*5/1000 to avoid overrun issue when recording
* at 8kHz in 8-bit format or at 88kHz in 24-bit format. */
interval = ((period_size - (position % period_size))
* HZ + (runtime->rate - 1)) / runtime->rate + HZ * 5 / 1000;
guard(spinlock_irqsave)(&ti->lock);
if (ti->running)
mod_timer(&ti->timer, jiffies + interval);
}
static void ct_systimer_init(struct ct_timer_instance *ti)
{
timer_setup(&ti->timer, ct_systimer_callback, 0);
}
static void ct_systimer_start(struct ct_timer_instance *ti)
{
struct snd_pcm_runtime *runtime = ti->substream->runtime;
guard(spinlock_irqsave)(&ti->lock);
ti->running = 1;
mod_timer(&ti->timer,
jiffies + (runtime->period_size * HZ +
(runtime->rate - 1)) / runtime->rate);
}
static void ct_systimer_stop(struct ct_timer_instance *ti)
{
guard(spinlock_irqsave)(&ti->lock);
ti->running = 0;
Annotation
- Immediate include surface: `linux/slab.h`, `linux/math64.h`, `linux/moduleparam.h`, `sound/core.h`, `sound/pcm.h`, `ctatc.h`, `cthardware.h`, `cttimer.h`.
- Detected declarations: `struct ct_timer_ops`, `struct ct_timer_instance`, `struct ct_timer`, `function ct_systimer_callback`, `function ct_systimer_init`, `function ct_systimer_start`, `function ct_systimer_stop`, `function ct_systimer_prepare`, `function ct_xfitimer_irq_rearm`, `function ct_xfitimer_irq_stop`.
- Atlas domain: Driver Families / sound/pci.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.