From 3a14331c54239033aebd0445c6069c9ac94ee4f5 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 27 Feb 2023 09:58:07 +0000 Subject: [PATCH] add kernel/drivers/base/test --- kernel/drivers/base/test/.built-in.a.cmd | 1 kernel/drivers/base/test/modules.order | 0 kernel/drivers/base/test/test_async_driver_probe.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/drivers/base/test/built-in.a | 1 kernel/drivers/base/test/modules.builtin | 0 kernel/drivers/base/test/Kconfig | 10 +++ kernel/drivers/base/test/Makefile | 1 7 files changed, 174 insertions(+), 0 deletions(-) diff --git a/kernel/drivers/base/test/.built-in.a.cmd b/kernel/drivers/base/test/.built-in.a.cmd new file mode 100644 index 0000000..cd9b917 --- /dev/null +++ b/kernel/drivers/base/test/.built-in.a.cmd @@ -0,0 +1 @@ +cmd_drivers/base/test/built-in.a := rm -f drivers/base/test/built-in.a; /home/wjj/rk3568/rk356_linux4.19/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-ar rcSTPD drivers/base/test/built-in.a diff --git a/kernel/drivers/base/test/Kconfig b/kernel/drivers/base/test/Kconfig new file mode 100644 index 0000000..86e85da --- /dev/null +++ b/kernel/drivers/base/test/Kconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 +config TEST_ASYNC_DRIVER_PROBE + tristate "Build kernel module to test asynchronous driver probing" + depends on m + help + Enabling this option produces a kernel module that allows + testing asynchronous driver probing by the device core. + The module name will be test_async_driver_probe.ko + + If unsure say N. diff --git a/kernel/drivers/base/test/Makefile b/kernel/drivers/base/test/Makefile new file mode 100644 index 0000000..90477c5 --- /dev/null +++ b/kernel/drivers/base/test/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_TEST_ASYNC_DRIVER_PROBE) += test_async_driver_probe.o diff --git a/kernel/drivers/base/test/built-in.a b/kernel/drivers/base/test/built-in.a new file mode 100644 index 0000000..8b277f0 --- /dev/null +++ b/kernel/drivers/base/test/built-in.a @@ -0,0 +1 @@ +!<arch> diff --git a/kernel/drivers/base/test/modules.builtin b/kernel/drivers/base/test/modules.builtin new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/kernel/drivers/base/test/modules.builtin diff --git a/kernel/drivers/base/test/modules.order b/kernel/drivers/base/test/modules.order new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/kernel/drivers/base/test/modules.order diff --git a/kernel/drivers/base/test/test_async_driver_probe.c b/kernel/drivers/base/test/test_async_driver_probe.c new file mode 100644 index 0000000..e7f145d --- /dev/null +++ b/kernel/drivers/base/test/test_async_driver_probe.c @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2014 Google, Inc. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/hrtimer.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/time.h> + +#define TEST_PROBE_DELAY (5 * 1000) /* 5 sec */ +#define TEST_PROBE_THRESHOLD (TEST_PROBE_DELAY / 2) + +static int test_probe(struct platform_device *pdev) +{ + dev_info(&pdev->dev, "sleeping for %d msecs in probe\n", + TEST_PROBE_DELAY); + msleep(TEST_PROBE_DELAY); + dev_info(&pdev->dev, "done sleeping\n"); + + return 0; +} + +static struct platform_driver async_driver = { + .driver = { + .name = "test_async_driver", + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, + .probe = test_probe, +}; + +static struct platform_driver sync_driver = { + .driver = { + .name = "test_sync_driver", + .probe_type = PROBE_FORCE_SYNCHRONOUS, + }, + .probe = test_probe, +}; + +static struct platform_device *async_dev_1, *async_dev_2; +static struct platform_device *sync_dev_1; + +static int __init test_async_probe_init(void) +{ + ktime_t calltime, delta; + unsigned long long duration; + int error; + + pr_info("registering first asynchronous device...\n"); + + async_dev_1 = platform_device_register_simple("test_async_driver", 1, + NULL, 0); + if (IS_ERR(async_dev_1)) { + error = PTR_ERR(async_dev_1); + pr_err("failed to create async_dev_1: %d\n", error); + return error; + } + + pr_info("registering asynchronous driver...\n"); + calltime = ktime_get(); + error = platform_driver_register(&async_driver); + if (error) { + pr_err("Failed to register async_driver: %d\n", error); + goto err_unregister_async_dev_1; + } + + delta = ktime_sub(ktime_get(), calltime); + duration = (unsigned long long) ktime_to_ms(delta); + pr_info("registration took %lld msecs\n", duration); + if (duration > TEST_PROBE_THRESHOLD) { + pr_err("test failed: probe took too long\n"); + error = -ETIMEDOUT; + goto err_unregister_async_driver; + } + + pr_info("registering second asynchronous device...\n"); + calltime = ktime_get(); + async_dev_2 = platform_device_register_simple("test_async_driver", 2, + NULL, 0); + if (IS_ERR(async_dev_2)) { + error = PTR_ERR(async_dev_2); + pr_err("failed to create async_dev_2: %d\n", error); + goto err_unregister_async_driver; + } + + delta = ktime_sub(ktime_get(), calltime); + duration = (unsigned long long) ktime_to_ms(delta); + pr_info("registration took %lld msecs\n", duration); + if (duration > TEST_PROBE_THRESHOLD) { + pr_err("test failed: probe took too long\n"); + error = -ETIMEDOUT; + goto err_unregister_async_dev_2; + } + + pr_info("registering synchronous driver...\n"); + + error = platform_driver_register(&sync_driver); + if (error) { + pr_err("Failed to register async_driver: %d\n", error); + goto err_unregister_async_dev_2; + } + + pr_info("registering synchronous device...\n"); + calltime = ktime_get(); + sync_dev_1 = platform_device_register_simple("test_sync_driver", 1, + NULL, 0); + if (IS_ERR(sync_dev_1)) { + error = PTR_ERR(sync_dev_1); + pr_err("failed to create sync_dev_1: %d\n", error); + goto err_unregister_sync_driver; + } + + delta = ktime_sub(ktime_get(), calltime); + duration = (unsigned long long) ktime_to_ms(delta); + pr_info("registration took %lld msecs\n", duration); + if (duration < TEST_PROBE_THRESHOLD) { + pr_err("test failed: probe was too quick\n"); + error = -ETIMEDOUT; + goto err_unregister_sync_dev_1; + } + + pr_info("completed successfully"); + + return 0; + +err_unregister_sync_dev_1: + platform_device_unregister(sync_dev_1); + +err_unregister_sync_driver: + platform_driver_unregister(&sync_driver); + +err_unregister_async_dev_2: + platform_device_unregister(async_dev_2); + +err_unregister_async_driver: + platform_driver_unregister(&async_driver); + +err_unregister_async_dev_1: + platform_device_unregister(async_dev_1); + + return error; +} +module_init(test_async_probe_init); + +static void __exit test_async_probe_exit(void) +{ + platform_driver_unregister(&async_driver); + platform_driver_unregister(&sync_driver); + platform_device_unregister(async_dev_1); + platform_device_unregister(async_dev_2); + platform_device_unregister(sync_dev_1); +} +module_exit(test_async_probe_exit); + +MODULE_DESCRIPTION("Test module for asynchronous driver probing"); +MODULE_AUTHOR("Dmitry Torokhov <dtor@chromium.org>"); +MODULE_LICENSE("GPL"); -- Gitblit v1.6.2