drivers/pinctrl/qcom/tlmm-test.c
Source file repositories/reference/linux-study-clean/drivers/pinctrl/qcom/tlmm-test.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pinctrl/qcom/tlmm-test.c- Extension
.c- Size
- 17903 bytes
- Lines
- 709
- Domain
- Driver Families
- Bucket
- drivers/pinctrl
- 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
kunit/test.hlinux/delay.hlinux/gpio/consumer.hlinux/interrupt.hlinux/kernel.hlinux/module.hlinux/of.hlinux/of_address.hlinux/of_irq.hlinux/pinctrl/consumer.hlinux/platform_device.hlinux/slab.h
Detected Declarations
struct tlmm_test_privfunction tlmm_output_lowfunction tlmm_output_highfunction tlmm_test_intr_fnfunction tlmm_test_intr_thread_fnfunction tlmm_test_request_hard_irqfunction tlmm_test_request_threaded_irqfunction tlmm_test_silentfunction tlmm_test_silent_risingfunction tlmm_test_silent_fallingfunction tlmm_test_silent_lowfunction tlmm_test_silent_highfunction tlmm_test_risingfunction tlmm_test_fallingfunction tlmm_test_lowfunction tlmm_test_highfunction tlmm_test_falling_in_handlerfunction tlmm_test_rising_in_handlerfunction tlmm_test_thread_risingfunction tlmm_test_thread_fallingfunction tlmm_test_thread_highfunction tlmm_test_thread_lowfunction tlmm_test_thread_rising_in_handlerfunction tlmm_test_thread_falling_in_handlerfunction tlmm_test_rising_while_disabledfunction tlmm_test_initfunction tlmm_reg_basefunction tlmm_test_init_suitefunction tlmm_test_exit_suite
Annotated Snippet
struct tlmm_test_priv {
atomic_t intr_count;
atomic_t thread_count;
unsigned int intr_op;
atomic_t intr_op_remain;
unsigned int thread_op;
atomic_t thread_op_remain;
};
/* Operation masks for @intr_op and @thread_op */
#define TLMM_TEST_COUNT BIT(0)
#define TLMM_TEST_OUTPUT_LOW BIT(1)
#define TLMM_TEST_OUTPUT_HIGH BIT(2)
#define TLMM_TEST_THEN_HIGH BIT(3)
#define TLMM_TEST_THEN_LOW BIT(4)
#define TLMM_TEST_WAKE_THREAD BIT(5)
static void tlmm_output_low(void)
{
writel(tlmm_suite.low_val, tlmm_suite.reg);
readl(tlmm_suite.reg);
}
static void tlmm_output_high(void)
{
writel(tlmm_suite.high_val, tlmm_suite.reg);
readl(tlmm_suite.reg);
}
static irqreturn_t tlmm_test_intr_fn(int irq, void *dev_id)
{
struct tlmm_test_priv *priv = dev_id;
if (priv->intr_op & TLMM_TEST_COUNT)
atomic_inc(&priv->intr_count);
if (priv->intr_op & TLMM_TEST_OUTPUT_LOW)
tlmm_output_low();
if (priv->intr_op & TLMM_TEST_OUTPUT_HIGH)
tlmm_output_high();
if (atomic_dec_if_positive(&priv->intr_op_remain) > 0) {
udelay(1);
if (priv->intr_op & TLMM_TEST_THEN_LOW)
tlmm_output_low();
if (priv->intr_op & TLMM_TEST_THEN_HIGH)
tlmm_output_high();
}
return priv->intr_op & TLMM_TEST_WAKE_THREAD ? IRQ_WAKE_THREAD : IRQ_HANDLED;
}
static irqreturn_t tlmm_test_intr_thread_fn(int irq, void *dev_id)
{
struct tlmm_test_priv *priv = dev_id;
if (priv->thread_op & TLMM_TEST_COUNT)
atomic_inc(&priv->thread_count);
if (priv->thread_op & TLMM_TEST_OUTPUT_LOW)
tlmm_output_low();
if (priv->thread_op & TLMM_TEST_OUTPUT_HIGH)
tlmm_output_high();
if (atomic_dec_if_positive(&priv->thread_op_remain) > 0) {
udelay(1);
if (priv->thread_op & TLMM_TEST_THEN_LOW)
tlmm_output_low();
if (priv->thread_op & TLMM_TEST_THEN_HIGH)
tlmm_output_high();
}
return IRQ_HANDLED;
}
static void tlmm_test_request_hard_irq(struct kunit *test, unsigned long irqflags)
{
struct tlmm_test_priv *priv = test->priv;
int ret;
ret = request_irq(tlmm_suite.irq, tlmm_test_intr_fn, irqflags, test->name, priv);
KUNIT_EXPECT_EQ(test, ret, 0);
}
static void tlmm_test_request_threaded_irq(struct kunit *test, unsigned long irqflags)
{
struct tlmm_test_priv *priv = test->priv;
Annotation
- Immediate include surface: `kunit/test.h`, `linux/delay.h`, `linux/gpio/consumer.h`, `linux/interrupt.h`, `linux/kernel.h`, `linux/module.h`, `linux/of.h`, `linux/of_address.h`.
- Detected declarations: `struct tlmm_test_priv`, `function tlmm_output_low`, `function tlmm_output_high`, `function tlmm_test_intr_fn`, `function tlmm_test_intr_thread_fn`, `function tlmm_test_request_hard_irq`, `function tlmm_test_request_threaded_irq`, `function tlmm_test_silent`, `function tlmm_test_silent_rising`, `function tlmm_test_silent_falling`.
- Atlas domain: Driver Families / drivers/pinctrl.
- 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.