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