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 26 static 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 36 static 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 44 static 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 52 static struct platform_device *async_dev_1, *async_dev_2; 53 static struct platform_device *sync_dev_1; 54 55 static 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 138 err_unregister_sync_dev_1: 139 platform_device_unregister(sync_dev_1); 140 141 err_unregister_sync_driver: 142 platform_driver_unregister(&sync_driver); 143 144 err_unregister_async_dev_2: 145 platform_device_unregister(async_dev_2); 146 147 err_unregister_async_driver: 148 platform_driver_unregister(&async_driver); 149 150 err_unregister_async_dev_1: 151 platform_device_unregister(async_dev_1); 152 153 return error; 154 } 155 module_init(test_async_probe_init); 156 157 static 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 } 165 module_exit(test_async_probe_exit); 166 167 MODULE_DESCRIPTION("Test module for asynchronous driver probing"); 168 MODULE_AUTHOR("Dmitry Torokhov <dtor@chromium.org>"); 169 MODULE_LICENSE("GPL"); 170