linux/drivers/base/test/test_async_driver_probe.c
<<
>>
Prefs
   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");
 170