File Index
Files and directories
Sign in
FILE

tlmm-test.c

File preview with syntax highlighting.

linux-6.19.14/drivers/pinctrl/qcom/tlmm-test.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
  4 */
  5
  6#define pr_fmt(fmt) "tlmm-test: " fmt
  7
  8#include <kunit/test.h>
  9#include <linux/delay.h>
 10#include <linux/gpio/consumer.h>
 11#include <linux/interrupt.h>
 12#include <linux/kernel.h>
 13#include <linux/module.h>
 14#include <linux/of.h>
 15#include <linux/of_address.h>
 16#include <linux/of_irq.h>
 17#include <linux/pinctrl/consumer.h>
 18#include <linux/platform_device.h>
 19#include <linux/slab.h>
 20
 21/*
 22 * This TLMM test module serves the purpose of validating that the TLMM driver
 23 * (pinctrl-msm) delivers expected number of interrupts in response to changing
 24 * GPIO state.
 25 *
 26 * To achieve this without external equipment the test takes a module parameter
 27 * "gpio", which the tester is expected to specify an unused and non-connected
 28 * pin. The GPIO state is then driven by adjusting the bias of the pin, at
 29 * suitable times through the different test cases.
 30 *
 31 * Upon execution, the test initialization will find the TLMM node (subject to
 32 * tlmm_of_match[] allow listing) and create the necessary references
 33 * dynamically, rather then relying on e.g. Devicetree and phandles.
 34 */
 35
 36#define MSM_PULL_MASK		GENMASK(2, 0)
 37#define MSM_PULL_DOWN		1
 38#define MSM_PULL_UP		3
 39#define TLMM_REG_SIZE		0x1000
 40
 41static int tlmm_test_gpio = -1;
 42static char *tlmm_reg_name = "default_region";
 43
 44module_param_named(gpio, tlmm_test_gpio, int, 0600);
 45module_param_named(name, tlmm_reg_name, charp, 0600);
 46
 47static struct {
 48	void __iomem *base;
 49	void __iomem *reg;
 50	int irq;
 51
 52	u32 low_val;
 53	u32 high_val;
 54} tlmm_suite;
 55
 56/**
 57 * struct tlmm_test_priv - Per-test context
 58 * @intr_count:		number of times hard handler was hit with TLMM_TEST_COUNT op set
 59 * @thread_count:	number of times thread handler was hit with TLMM_TEST_COUNT op set
 60 * @intr_op:		operations to be performed by the hard IRQ handler
 61 * @intr_op_remain:	number of times the TLMM_TEST_THEN_* operations should be
 62 *			performed by the hard IRQ handler
 63 * @thread_op:		operations to be performed by the threaded IRQ handler
 64 * @thread_op_remain:	number of times the TLMM_TEST_THEN_* operations should
 65 *			be performed by the threaded IRQ handler
 66 */
 67struct tlmm_test_priv {
 68	atomic_t intr_count;
 69	atomic_t thread_count;
 70
 71	unsigned int intr_op;
 72	atomic_t intr_op_remain;
 73
 74	unsigned int thread_op;
 75	atomic_t thread_op_remain;
 76};
 77
 78/* Operation masks for @intr_op and @thread_op */
 79#define TLMM_TEST_COUNT		BIT(0)
 80#define TLMM_TEST_OUTPUT_LOW	BIT(1)
 81#define TLMM_TEST_OUTPUT_HIGH	BIT(2)
 82#define TLMM_TEST_THEN_HIGH	BIT(3)
 83#define TLMM_TEST_THEN_LOW	BIT(4)
 84#define TLMM_TEST_WAKE_THREAD	BIT(5)
 85
 86static void tlmm_output_low(void)
 87{
 88	writel(tlmm_suite.low_val, tlmm_suite.reg);
 89	readl(tlmm_suite.reg);
 90}
 91
 92static void tlmm_output_high(void)
 93{
 94	writel(tlmm_suite.high_val, tlmm_suite.reg);
 95	readl(tlmm_suite.reg);
 96}
 97
 98static irqreturn_t tlmm_test_intr_fn(int irq, void *dev_id)
 99{
100	struct tlmm_test_priv *priv = dev_id;
101
102	if (priv->intr_op & TLMM_TEST_COUNT)
103		atomic_inc(&priv->intr_count);
104
105	if (priv->intr_op & TLMM_TEST_OUTPUT_LOW)
106		tlmm_output_low();
107	if (priv->intr_op & TLMM_TEST_OUTPUT_HIGH)
108		tlmm_output_high();
109
110	if (atomic_dec_if_positive(&priv->intr_op_remain) > 0) {
111		udelay(1);
112
113		if (priv->intr_op & TLMM_TEST_THEN_LOW)
114			tlmm_output_low();
115		if (priv->intr_op & TLMM_TEST_THEN_HIGH)
116			tlmm_output_high();
117	}
118
119	return priv->intr_op & TLMM_TEST_WAKE_THREAD ? IRQ_WAKE_THREAD : IRQ_HANDLED;
120}
121
122static irqreturn_t tlmm_test_intr_thread_fn(int irq, void *dev_id)
123{
124	struct tlmm_test_priv *priv = dev_id;
125
126	if (priv->thread_op & TLMM_TEST_COUNT)
127		atomic_inc(&priv->thread_count);
128
129	if (priv->thread_op & TLMM_TEST_OUTPUT_LOW)
130		tlmm_output_low();
131	if (priv->thread_op & TLMM_TEST_OUTPUT_HIGH)
132		tlmm_output_high();
133
134	if (atomic_dec_if_positive(&priv->thread_op_remain) > 0) {
135		udelay(1);
136		if (priv->thread_op & TLMM_TEST_THEN_LOW)
137			tlmm_output_low();
138		if (priv->thread_op & TLMM_TEST_THEN_HIGH)
139			tlmm_output_high();
140	}
141
142	return IRQ_HANDLED;
143}
144
145static void tlmm_test_request_hard_irq(struct kunit *test, unsigned long irqflags)
146{
147	struct tlmm_test_priv *priv = test->priv;
148	int ret;
149
150	ret = request_irq(tlmm_suite.irq, tlmm_test_intr_fn, irqflags, test->name, priv);
151	KUNIT_EXPECT_EQ(test, ret, 0);
152}
153
154static void tlmm_test_request_threaded_irq(struct kunit *test, unsigned long irqflags)
155{
156	struct tlmm_test_priv *priv = test->priv;
157	int ret;
158
159	ret = request_threaded_irq(tlmm_suite.irq,
160				   tlmm_test_intr_fn, tlmm_test_intr_thread_fn,
161				   irqflags, test->name, priv);
162
163	KUNIT_EXPECT_EQ(test, ret, 0);
164}
165
166static void tlmm_test_silent(struct kunit *test, unsigned long irqflags)
167{
168	struct tlmm_test_priv *priv = test->priv;
169
170	priv->intr_op = TLMM_TEST_COUNT;
171
172	/* GPIO line at non-triggering level */
173	if (irqflags == IRQF_TRIGGER_LOW || irqflags == IRQF_TRIGGER_FALLING)
174		tlmm_output_high();
175	else
176		tlmm_output_low();
177
178	tlmm_test_request_hard_irq(test, irqflags);
179	msleep(100);
180	free_irq(tlmm_suite.irq, priv);
181
182	KUNIT_ASSERT_EQ(test, atomic_read(&priv->intr_count), 0);
183}
184
185/*
186 * Test that no RISING interrupts are triggered on a silent pin
187 */
188static void tlmm_test_silent_rising(struct kunit *test)
189{
190	tlmm_test_silent(test, IRQF_TRIGGER_RISING);
191}
192
193/*
194 * Test that no FALLING interrupts are triggered on a silent pin
195 */
196static void tlmm_test_silent_falling(struct kunit *test)
197{
198	tlmm_test_silent(test, IRQF_TRIGGER_FALLING);
199}
200
201/*
202 * Test that no LOW interrupts are triggered on a silent pin
203 */
204static void tlmm_test_silent_low(struct kunit *test)
205{
206	tlmm_test_silent(test, IRQF_TRIGGER_LOW);
207}
208
209/*
210 * Test that no HIGH interrupts are triggered on a silent pin
211 */
212static void tlmm_test_silent_high(struct kunit *test)
213{
214	tlmm_test_silent(test, IRQF_TRIGGER_HIGH);
215}
216
217/*
218 * Square wave with 10 high pulses, assert that we get 10 rising interrupts
219 */
220static void tlmm_test_rising(struct kunit *test)
221{
222	struct tlmm_test_priv *priv = test->priv;
223	int i;
224
225	priv->intr_op = TLMM_TEST_COUNT;
226
227	tlmm_output_low();
228
229	tlmm_test_request_hard_irq(test, IRQF_TRIGGER_RISING);
230	for (i = 0; i < 10; i++) {
231		tlmm_output_low();
232		msleep(20);
233		tlmm_output_high();
234		msleep(20);
235	}
236
237	free_irq(tlmm_suite.irq, priv);
238
239	KUNIT_ASSERT_EQ(test, atomic_read(&priv->intr_count), 10);
240}
241
242/*
243 * Square wave with 10 low pulses, assert that we get 10 falling interrupts
244 */
245static void tlmm_test_falling(struct kunit *test)
246{
247	struct tlmm_test_priv *priv = test->priv;
248	int i;
249
250	priv->intr_op = TLMM_TEST_COUNT;
251
252	tlmm_output_high();
253
254	tlmm_test_request_hard_irq(test, IRQF_TRIGGER_FALLING);
255	for (i = 0; i < 10; i++) {
256		tlmm_output_high();
257		msleep(20);
258		tlmm_output_low();
259		msleep(20);
260	}
261	free_irq(tlmm_suite.irq, priv);
262
263	KUNIT_ASSERT_EQ(test, atomic_read(&priv->intr_count), 10);
264}
265
266/*
267 * Drive line low 10 times, handler drives it high to "clear the interrupt
268 * source", assert we get 10 interrupts
269 */
270static void tlmm_test_low(struct kunit *test)
271{
272	struct tlmm_test_priv *priv = test->priv;
273	int i;
274
275	priv->intr_op = TLMM_TEST_COUNT | TLMM_TEST_OUTPUT_HIGH;
276	atomic_set(&priv->intr_op_remain, 9);
277
278	tlmm_output_high();
279
280	tlmm_test_request_hard_irq(test, IRQF_TRIGGER_LOW);
281	for (i = 0; i < 10; i++) {
282		msleep(20);
283		tlmm_output_low();
284	}
285	msleep(100);
286	free_irq(tlmm_suite.irq, priv);
287
288	KUNIT_ASSERT_EQ(test, atomic_read(&priv->intr_count), 10);
289}
290
291/*
292 * Drive line high 10 times, handler drives it low to "clear the interrupt
293 * source", assert we get 10 interrupts
294 */
295static void tlmm_test_high(struct kunit *test)
296{
297	struct tlmm_test_priv *priv = test->priv;
298	int i;
299
300	priv->intr_op = TLMM_TEST_COUNT | TLMM_TEST_OUTPUT_LOW;
301	atomic_set(&priv->intr_op_remain, 9);
302
303	tlmm_output_low();
304
305	tlmm_test_request_hard_irq(test, IRQF_TRIGGER_HIGH);
306	for (i = 0; i < 10; i++) {
307		msleep(20);
308		tlmm_output_high();
309	}
310	msleep(100);
311	free_irq(tlmm_suite.irq, priv);
312
313	KUNIT_ASSERT_EQ(test, atomic_read(&priv->intr_count), 10);
314}
315
316/*
317 * Handler drives GPIO high to "clear the interrupt source", then low to
318 * simulate a new interrupt, repeated 10 times, assert we get 10 interrupts
319 */
320static void tlmm_test_falling_in_handler(struct kunit *test)
321{
322	struct tlmm_test_priv *priv = test->priv;
323
324	priv->intr_op = TLMM_TEST_COUNT | TLMM_TEST_OUTPUT_HIGH | TLMM_TEST_THEN_LOW;
325	atomic_set(&priv->intr_op_remain, 10);
326
327	tlmm_output_high();
328
329	tlmm_test_request_hard_irq(test, IRQF_TRIGGER_FALLING);
330	msleep(20);
331	tlmm_output_low();
332	msleep(100);
333	free_irq(tlmm_suite.irq, priv);
334
335	KUNIT_ASSERT_EQ(test, atomic_read(&priv->intr_count), 10);
336}
337
338/*
339 * Handler drives GPIO low to "clear the interrupt source", then high to
340 * simulate a new interrupt, repeated 10 times, assert we get 10 interrupts
341 */
342static void tlmm_test_rising_in_handler(struct kunit *test)
343{
344	struct tlmm_test_priv *priv = test->priv;
345
346	priv->intr_op = TLMM_TEST_COUNT | TLMM_TEST_OUTPUT_LOW | TLMM_TEST_THEN_HIGH;
347	atomic_set(&priv->intr_op_remain, 10);
348
349	tlmm_output_low();
350
351	tlmm_test_request_hard_irq(test, IRQF_TRIGGER_RISING);
352	msleep(20);
353	tlmm_output_high();
354	msleep(100);
355	free_irq(tlmm_suite.irq, priv);
356
357	KUNIT_ASSERT_EQ(test, atomic_read(&priv->intr_count), 10);
358}
359
360/*
361 * Square wave with 10 high pulses, assert that we get 10 rising hard and
362 * 10 threaded interrupts
363 */
364static void tlmm_test_thread_rising(struct kunit *test)
365{
366	struct tlmm_test_priv *priv = test->priv;
367	int i;
368
369	priv->intr_op = TLMM_TEST_COUNT | TLMM_TEST_WAKE_THREAD;
370	priv->thread_op = TLMM_TEST_COUNT;
371
372	tlmm_output_low();
373
374	tlmm_test_request_threaded_irq(test, IRQF_TRIGGER_RISING);
375	for (i = 0; i < 10; i++) {
376		tlmm_output_low();
377		msleep(20);
378		tlmm_output_high();
379		msleep(20);
380	}
381	free_irq(tlmm_suite.irq, priv);
382
383	KUNIT_ASSERT_EQ(test, atomic_read(&priv->intr_count), 10);
384	KUNIT_ASSERT_EQ(test, atomic_read(&priv->thread_count), 10);
385}
386
387/*
388 * Square wave with 10 low pulses, assert that we get 10 falling interrupts
389 */
390static void tlmm_test_thread_falling(struct kunit *test)
391{
392	struct tlmm_test_priv *priv = test->priv;
393	int i;
394
395	priv->intr_op = TLMM_TEST_COUNT | TLMM_TEST_WAKE_THREAD;
396	priv->thread_op = TLMM_TEST_COUNT;
397
398	tlmm_output_high();
399
400	tlmm_test_request_threaded_irq(test, IRQF_TRIGGER_FALLING);
401	for (i = 0; i < 10; i++) {
402		tlmm_output_high();
403		msleep(20);
404		tlmm_output_low();
405		msleep(20);
406	}
407	free_irq(tlmm_suite.irq, priv);
408
409	KUNIT_ASSERT_EQ(test, atomic_read(&priv->intr_count), 10);
410	KUNIT_ASSERT_EQ(test, atomic_read(&priv->thread_count), 10);
411}
412
413/*
414 * Drive line high 10 times, threaded handler drives it low to "clear the
415 * interrupt source", assert we get 10 interrupts
416 */
417static void tlmm_test_thread_high(struct kunit *test)
418{
419	struct tlmm_test_priv *priv = test->priv;
420	int i;
421
422	priv->intr_op = TLMM_TEST_COUNT | TLMM_TEST_WAKE_THREAD;
423	priv->thread_op = TLMM_TEST_COUNT | TLMM_TEST_OUTPUT_LOW;
424
425	tlmm_output_low();
426
427	tlmm_test_request_threaded_irq(test, IRQF_TRIGGER_HIGH | IRQF_ONESHOT);
428	for (i = 0; i < 10; i++) {
429		tlmm_output_high();
430		msleep(20);
431	}
432	free_irq(tlmm_suite.irq, priv);
433
434	KUNIT_ASSERT_EQ(test, atomic_read(&priv->intr_count), 10);
435	KUNIT_ASSERT_EQ(test, atomic_read(&priv->thread_count), 10);
436}
437
438/*
439 * Drive line low 10 times, threaded handler drives it high to "clear the
440 * interrupt source", assert we get 10 interrupts
441 */
442static void tlmm_test_thread_low(struct kunit *test)
443{
444	struct tlmm_test_priv *priv = test->priv;
445	int i;
446
447	priv->intr_op = TLMM_TEST_COUNT | TLMM_TEST_WAKE_THREAD;
448	priv->thread_op = TLMM_TEST_COUNT | TLMM_TEST_OUTPUT_HIGH;
449
450	tlmm_output_high();
451
452	tlmm_test_request_threaded_irq(test, IRQF_TRIGGER_LOW | IRQF_ONESHOT);
453	for (i = 0; i < 10; i++) {
454		tlmm_output_low();
455		msleep(20);
456	}
457	free_irq(tlmm_suite.irq, priv);
458
459	KUNIT_ASSERT_EQ(test, atomic_read(&priv->intr_count), 10);
460	KUNIT_ASSERT_EQ(test, atomic_read(&priv->thread_count), 10);
461}
462
463/*
464 * Handler drives GPIO low to "clear the interrupt source", then high in the
465 * threaded handler to simulate a new interrupt, repeated 10 times, assert we
466 * get 10 interrupts
467 */
468static void tlmm_test_thread_rising_in_handler(struct kunit *test)
469{
470	struct tlmm_test_priv *priv = test->priv;
471
472	priv->intr_op = TLMM_TEST_COUNT | TLMM_TEST_OUTPUT_LOW | TLMM_TEST_WAKE_THREAD;
473	priv->thread_op = TLMM_TEST_COUNT | TLMM_TEST_THEN_HIGH;
474	atomic_set(&priv->thread_op_remain, 10);
475
476	tlmm_output_low();
477
478	tlmm_test_request_threaded_irq(test, IRQF_TRIGGER_RISING);
479	msleep(20);
480	tlmm_output_high();
481	msleep(100);
482	free_irq(tlmm_suite.irq, priv);
483
484	KUNIT_ASSERT_EQ(test, atomic_read(&priv->intr_count), 10);
485	KUNIT_ASSERT_EQ(test, atomic_read(&priv->thread_count), 10);
486}
487
488/*
489 * Handler drives GPIO high to "clear the interrupt source", then low in the
490 * threaded handler to simulate a new interrupt, repeated 10 times, assert we
491 * get 10 interrupts
492 */
493static void tlmm_test_thread_falling_in_handler(struct kunit *test)
494{
495	struct tlmm_test_priv *priv = test->priv;
496
497	priv->intr_op = TLMM_TEST_COUNT | TLMM_TEST_OUTPUT_HIGH | TLMM_TEST_WAKE_THREAD;
498	priv->thread_op = TLMM_TEST_COUNT | TLMM_TEST_THEN_LOW;
499	atomic_set(&priv->thread_op_remain, 10);
500
501	tlmm_output_high();
502
503	tlmm_test_request_threaded_irq(test, IRQF_TRIGGER_FALLING);
504	msleep(20);
505	tlmm_output_low();
506	msleep(100);
507	free_irq(tlmm_suite.irq, priv);
508
509	KUNIT_ASSERT_EQ(test, atomic_read(&priv->intr_count), 10);
510	KUNIT_ASSERT_EQ(test, atomic_read(&priv->thread_count), 10);
511}
512
513/*
514 * Validate that edge interrupts occurring while irq is disabled is delivered
515 * once the interrupt is reenabled.
516 */
517static void tlmm_test_rising_while_disabled(struct kunit *test)
518{
519	struct tlmm_test_priv *priv = test->priv;
520	unsigned int after_edge;
521	unsigned int before_edge;
522
523	priv->intr_op = TLMM_TEST_COUNT;
524	atomic_set(&priv->thread_op_remain, 10);
525
526	tlmm_output_low();
527
528	tlmm_test_request_hard_irq(test, IRQF_TRIGGER_RISING);
529	msleep(20);
530
531	disable_irq(tlmm_suite.irq);
532	before_edge = atomic_read(&priv->intr_count);
533
534	tlmm_output_high();
535	msleep(20);
536	after_edge = atomic_read(&priv->intr_count);
537
538	msleep(20);
539	enable_irq(tlmm_suite.irq);
540	msleep(20);
541
542	free_irq(tlmm_suite.irq, priv);
543
544	KUNIT_ASSERT_EQ(test, before_edge, 0);
545	KUNIT_ASSERT_EQ(test, after_edge, 0);
546	KUNIT_ASSERT_EQ(test, atomic_read(&priv->intr_count), 1);
547}
548
549static int tlmm_test_init(struct kunit *test)
550{
551	struct tlmm_test_priv *priv;
552
553	priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
554	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
555
556	atomic_set(&priv->intr_count, 0);
557	atomic_set(&priv->thread_count, 0);
558
559	atomic_set(&priv->intr_op_remain, 0);
560	atomic_set(&priv->thread_op_remain, 0);
561
562	test->priv = priv;
563
564	return 0;
565}
566
567/*
568 * NOTE: When adding compatibles to this list, ensure that TLMM_REG_SIZE and
569 * pull configuration values are supported and correct.
570 */
571static const struct of_device_id tlmm_of_match[] = {
572	{ .compatible = "qcom,sc8280xp-tlmm" },
573	{ .compatible = "qcom,x1e80100-tlmm" },
574	{}
575};
576
577static int tlmm_reg_base(struct device_node *tlmm, struct resource *res)
578{
579	const char **reg_names;
580	int count;
581	int ret;
582	int i;
583
584	count = of_property_count_strings(tlmm, "reg-names");
585	if (count <= 0) {
586		pr_err("failed to find tlmm reg name\n");
587		return count;
588	}
589
590	reg_names = kcalloc(count, sizeof(char *), GFP_KERNEL);
591	if (!reg_names)
592		return -ENOMEM;
593
594	ret = of_property_read_string_array(tlmm, "reg-names", reg_names, count);
595	if (ret != count) {
596		kfree(reg_names);
597		return -EINVAL;
598	}
599
600	if (!strcmp(tlmm_reg_name, "default_region")) {
601		ret = of_address_to_resource(tlmm, 0, res);
602	} else {
603		for (i = 0; i < count; i++) {
604			if (!strcmp(reg_names[i], tlmm_reg_name)) {
605				ret = of_address_to_resource(tlmm, i, res);
606				break;
607			}
608		}
609		if (i == count)
610			ret = -EINVAL;
611	}
612
613	kfree(reg_names);
614
615	return ret;
616}
617
618static int tlmm_test_init_suite(struct kunit_suite *suite)
619{
620	struct of_phandle_args args = {};
621	struct resource res;
622	int ret;
623	u32 val;
624
625	if (tlmm_test_gpio < 0) {
626		pr_err("use the tlmm-test.gpio module parameter to specify which GPIO to use\n");
627		return -EINVAL;
628	}
629
630	struct device_node *tlmm __free(device_node) = of_find_matching_node(NULL, tlmm_of_match);
631	if (!tlmm) {
632		pr_err("failed to find tlmm node\n");
633		return -EINVAL;
634	}
635
636	ret = tlmm_reg_base(tlmm, &res);
637	if (ret < 0)
638		return ret;
639
640	tlmm_suite.base = ioremap(res.start, resource_size(&res));
641	if (!tlmm_suite.base)
642		return -ENOMEM;
643
644	args.np = tlmm;
645	args.args_count = 2;
646	args.args[0] = tlmm_test_gpio;
647	args.args[1] = 0;
648
649	tlmm_suite.irq = irq_create_of_mapping(&args);
650	if (!tlmm_suite.irq) {
651		pr_err("failed to map TLMM irq %d\n", args.args[0]);
652		goto err_unmap;
653	}
654
655	tlmm_suite.reg = tlmm_suite.base + tlmm_test_gpio * TLMM_REG_SIZE;
656	val = readl(tlmm_suite.reg) & ~MSM_PULL_MASK;
657	tlmm_suite.low_val = val | MSM_PULL_DOWN;
658	tlmm_suite.high_val = val | MSM_PULL_UP;
659
660	return 0;
661
662err_unmap:
663	iounmap(tlmm_suite.base);
664	tlmm_suite.base = NULL;
665	return -EINVAL;
666}
667
668static void tlmm_test_exit_suite(struct kunit_suite *suite)
669{
670	irq_dispose_mapping(tlmm_suite.irq);
671	iounmap(tlmm_suite.base);
672
673	tlmm_suite.base = NULL;
674	tlmm_suite.irq = -1;
675}
676
677static struct kunit_case tlmm_test_cases[] = {
678	KUNIT_CASE(tlmm_test_silent_rising),
679	KUNIT_CASE(tlmm_test_silent_falling),
680	KUNIT_CASE(tlmm_test_silent_low),
681	KUNIT_CASE(tlmm_test_silent_high),
682	KUNIT_CASE(tlmm_test_rising),
683	KUNIT_CASE(tlmm_test_falling),
684	KUNIT_CASE(tlmm_test_high),
685	KUNIT_CASE(tlmm_test_low),
686	KUNIT_CASE(tlmm_test_rising_in_handler),
687	KUNIT_CASE(tlmm_test_falling_in_handler),
688	KUNIT_CASE(tlmm_test_thread_rising),
689	KUNIT_CASE(tlmm_test_thread_falling),
690	KUNIT_CASE(tlmm_test_thread_high),
691	KUNIT_CASE(tlmm_test_thread_low),
692	KUNIT_CASE(tlmm_test_thread_rising_in_handler),
693	KUNIT_CASE(tlmm_test_thread_falling_in_handler),
694	KUNIT_CASE(tlmm_test_rising_while_disabled),
695	{}
696};
697
698static struct kunit_suite tlmm_test_suite = {
699	.name = "tlmm-test",
700	.init = tlmm_test_init,
701	.suite_init = tlmm_test_init_suite,
702	.suite_exit = tlmm_test_exit_suite,
703	.test_cases = tlmm_test_cases,
704};
705
706kunit_test_suites(&tlmm_test_suite);
707
708MODULE_DESCRIPTION("Qualcomm TLMM test");
709MODULE_LICENSE("GPL");
~/ Read-only file preview.