Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1/*
  2 * Copyright (C) 2014 Google, Inc.
  3 *
  4 * This program is free software; you can redistribute it and/or modify
  5 * it under the terms of the GNU General Public License version 2 as
  6 * published by the Free Software Foundation.
  7 *
  8 * This program is distributed in the hope that it will be useful,
  9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 11 * GNU General Public License for more details.
 12 */
 13
 14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 15
 16#include <linux/delay.h>
 17#include <linux/init.h>
 18#include <linux/hrtimer.h>
 19#include <linux/module.h>
 20#include <linux/platform_device.h>
 21#include <linux/time.h>
 22
 23#define TEST_PROBE_DELAY	(5 * 1000)	/* 5 sec */
 24#define TEST_PROBE_THRESHOLD	(TEST_PROBE_DELAY / 2)
 25
 26static int test_probe(struct platform_device *pdev)
 27{
 28	dev_info(&pdev->dev, "sleeping for %d msecs in probe\n",
 29		 TEST_PROBE_DELAY);
 30	msleep(TEST_PROBE_DELAY);
 31	dev_info(&pdev->dev, "done sleeping\n");
 32
 33	return 0;
 34}
 35
 36static struct platform_driver async_driver = {
 37	.driver = {
 38		.name = "test_async_driver",
 39		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
 40	},
 41	.probe = test_probe,
 42};
 43
 44static struct platform_driver sync_driver = {
 45	.driver = {
 46		.name = "test_sync_driver",
 47		.probe_type = PROBE_FORCE_SYNCHRONOUS,
 48	},
 49	.probe = test_probe,
 50};
 51
 52static struct platform_device *async_dev_1, *async_dev_2;
 53static struct platform_device *sync_dev_1;
 54
 55static int __init test_async_probe_init(void)
 56{
 57	ktime_t calltime, delta;
 58	unsigned long long duration;
 59	int error;
 60
 61	pr_info("registering first asynchronous device...\n");
 62
 63	async_dev_1 = platform_device_register_simple("test_async_driver", 1,
 64						      NULL, 0);
 65	if (IS_ERR(async_dev_1)) {
 66		error = PTR_ERR(async_dev_1);
 67		pr_err("failed to create async_dev_1: %d", error);
 68		return error;
 69	}
 70
 71	pr_info("registering asynchronous driver...\n");
 72	calltime = ktime_get();
 73	error = platform_driver_register(&async_driver);
 74	if (error) {
 75		pr_err("Failed to register async_driver: %d\n", error);
 76		goto err_unregister_async_dev_1;
 77	}
 78
 79	delta = ktime_sub(ktime_get(), calltime);
 80	duration = (unsigned long long) ktime_to_ms(delta);
 81	pr_info("registration took %lld msecs\n", duration);
 82	if (duration > TEST_PROBE_THRESHOLD) {
 83		pr_err("test failed: probe took too long\n");
 84		error = -ETIMEDOUT;
 85		goto err_unregister_async_driver;
 86	}
 87
 88	pr_info("registering second asynchronous device...\n");
 89	calltime = ktime_get();
 90	async_dev_2 = platform_device_register_simple("test_async_driver", 2,
 91						      NULL, 0);
 92	if (IS_ERR(async_dev_2)) {
 93		error = PTR_ERR(async_dev_2);
 94		pr_err("failed to create async_dev_2: %d", error);
 95		goto err_unregister_async_driver;
 96	}
 97
 98	delta = ktime_sub(ktime_get(), calltime);
 99	duration = (unsigned long long) ktime_to_ms(delta);
100	pr_info("registration took %lld msecs\n", duration);
101	if (duration > TEST_PROBE_THRESHOLD) {
102		pr_err("test failed: probe took too long\n");
103		error = -ETIMEDOUT;
104		goto err_unregister_async_dev_2;
105	}
106
107	pr_info("registering synchronous driver...\n");
108
109	error = platform_driver_register(&sync_driver);
110	if (error) {
111		pr_err("Failed to register async_driver: %d\n", error);
112		goto err_unregister_async_dev_2;
113	}
114
115	pr_info("registering synchronous device...\n");
116	calltime = ktime_get();
117	sync_dev_1 = platform_device_register_simple("test_sync_driver", 1,
118						     NULL, 0);
119	if (IS_ERR(sync_dev_1)) {
120		error = PTR_ERR(sync_dev_1);
121		pr_err("failed to create sync_dev_1: %d", error);
122		goto err_unregister_sync_driver;
123	}
124
125	delta = ktime_sub(ktime_get(), calltime);
126	duration = (unsigned long long) ktime_to_ms(delta);
127	pr_info("registration took %lld msecs\n", duration);
128	if (duration < TEST_PROBE_THRESHOLD) {
129		pr_err("test failed: probe was too quick\n");
130		error = -ETIMEDOUT;
131		goto err_unregister_sync_dev_1;
132	}
133
134	pr_info("completed successfully");
135
136	return 0;
137
138err_unregister_sync_dev_1:
139	platform_device_unregister(sync_dev_1);
140
141err_unregister_sync_driver:
142	platform_driver_unregister(&sync_driver);
143
144err_unregister_async_dev_2:
145	platform_device_unregister(async_dev_2);
146
147err_unregister_async_driver:
148	platform_driver_unregister(&async_driver);
149
150err_unregister_async_dev_1:
151	platform_device_unregister(async_dev_1);
152
153	return error;
154}
155module_init(test_async_probe_init);
156
157static void __exit test_async_probe_exit(void)
158{
159	platform_driver_unregister(&async_driver);
160	platform_driver_unregister(&sync_driver);
161	platform_device_unregister(async_dev_1);
162	platform_device_unregister(async_dev_2);
163	platform_device_unregister(sync_dev_1);
164}
165module_exit(test_async_probe_exit);
166
167MODULE_DESCRIPTION("Test module for asynchronous driver probing");
168MODULE_AUTHOR("Dmitry Torokhov <dtor@chromium.org>");
169MODULE_LICENSE("GPL");