drivers/counter/rz-mtu3-cnt.c
Source file repositories/reference/linux-study-clean/drivers/counter/rz-mtu3-cnt.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/counter/rz-mtu3-cnt.c- Extension
.c- Size
- 24483 bytes
- Lines
- 910
- Domain
- Driver Families
- Bucket
- drivers/counter
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk.hlinux/counter.hlinux/mfd/rz-mtu3.hlinux/module.hlinux/platform_device.hlinux/pm_runtime.hlinux/types.h
Detected Declarations
struct rz_mtu3_cntfunction rz_mtu3_get_hw_chfunction rz_mtu3_is_counter_invalidfunction rz_mtu3_lock_if_counter_is_validfunction rz_mtu3_lock_if_count_is_enabledfunction rz_mtu3_count_readfunction rz_mtu3_count_writefunction rz_mtu3_count_function_read_helperfunction rz_mtu3_count_function_readfunction rz_mtu3_count_function_writefunction rz_mtu3_count_direction_readfunction rz_mtu3_count_ceiling_readfunction rz_mtu3_count_ceiling_writefunction rz_mtu3_32bit_cnt_settingfunction rz_mtu3_16bit_cnt_settingfunction rz_mtu3_initialize_counterfunction rz_mtu3_terminate_counterfunction rz_mtu3_count_enable_readfunction rz_mtu3_count_enable_writefunction rz_mtu3_lock_if_ch0_is_enabledfunction rz_mtu3_cascade_counts_enable_getfunction rz_mtu3_cascade_counts_enable_setfunction rz_mtu3_ext_input_phase_clock_select_getfunction rz_mtu3_ext_input_phase_clock_select_setfunction rz_mtu3_action_readfunction rz_mtu3_cnt_pm_runtime_suspendfunction rz_mtu3_cnt_pm_runtime_resumefunction rz_mtu3_cnt_pm_disablefunction rz_mtu3_cnt_probe
Annotated Snippet
struct rz_mtu3_cnt {
struct clk *clk;
struct mutex lock;
struct rz_mtu3_channel *ch;
bool count_is_enabled[RZ_MTU3_MAX_LOGICAL_CNTR_CHANNELS];
union {
u16 mtu_16bit_max[RZ_MTU3_MAX_HW_CNTR_CHANNELS];
u32 mtu_32bit_max;
};
};
static const enum counter_function rz_mtu3_count_functions[] = {
COUNTER_FUNCTION_QUADRATURE_X4,
COUNTER_FUNCTION_PULSE_DIRECTION,
COUNTER_FUNCTION_QUADRATURE_X2_B,
};
static inline size_t rz_mtu3_get_hw_ch(const size_t id)
{
return (id == RZ_MTU3_32_BIT_CH) ? 0 : id;
}
static inline struct rz_mtu3_channel *rz_mtu3_get_ch(struct counter_device *counter, int id)
{
struct rz_mtu3_cnt *const priv = counter_priv(counter);
const size_t ch_id = rz_mtu3_get_hw_ch(id);
return &priv->ch[ch_id];
}
static bool rz_mtu3_is_counter_invalid(struct counter_device *counter, int id)
{
struct rz_mtu3_cnt *const priv = counter_priv(counter);
unsigned long tmdr;
pm_runtime_get_sync(counter->parent);
tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
pm_runtime_put(counter->parent);
if (id == RZ_MTU3_32_BIT_CH && test_bit(RZ_MTU3_TMDR3_LWA, &tmdr))
return false;
if (id != RZ_MTU3_32_BIT_CH && !test_bit(RZ_MTU3_TMDR3_LWA, &tmdr))
return false;
return true;
}
static int rz_mtu3_lock_if_counter_is_valid(struct counter_device *counter,
struct rz_mtu3_channel *const ch,
struct rz_mtu3_cnt *const priv,
int id)
{
mutex_lock(&priv->lock);
if (ch->is_busy && !priv->count_is_enabled[id]) {
mutex_unlock(&priv->lock);
return -EINVAL;
}
if (rz_mtu3_is_counter_invalid(counter, id)) {
mutex_unlock(&priv->lock);
return -EBUSY;
}
return 0;
}
static int rz_mtu3_lock_if_count_is_enabled(struct rz_mtu3_channel *const ch,
struct rz_mtu3_cnt *const priv,
int id)
{
mutex_lock(&priv->lock);
if (ch->is_busy && !priv->count_is_enabled[id]) {
mutex_unlock(&priv->lock);
return -EINVAL;
}
return 0;
}
static int rz_mtu3_count_read(struct counter_device *counter,
struct counter_count *count, u64 *val)
{
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
struct rz_mtu3_cnt *const priv = counter_priv(counter);
int ret;
ret = rz_mtu3_lock_if_counter_is_valid(counter, ch, priv, count->id);
Annotation
- Immediate include surface: `linux/clk.h`, `linux/counter.h`, `linux/mfd/rz-mtu3.h`, `linux/module.h`, `linux/platform_device.h`, `linux/pm_runtime.h`, `linux/types.h`.
- Detected declarations: `struct rz_mtu3_cnt`, `function rz_mtu3_get_hw_ch`, `function rz_mtu3_is_counter_invalid`, `function rz_mtu3_lock_if_counter_is_valid`, `function rz_mtu3_lock_if_count_is_enabled`, `function rz_mtu3_count_read`, `function rz_mtu3_count_write`, `function rz_mtu3_count_function_read_helper`, `function rz_mtu3_count_function_read`, `function rz_mtu3_count_function_write`.
- Atlas domain: Driver Families / drivers/counter.
- 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.