diff options
Diffstat (limited to 'drivers/gpu/drm/selftests/drm_selftest.c')
-rw-r--r-- | drivers/gpu/drm/selftests/drm_selftest.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/drivers/gpu/drm/selftests/drm_selftest.c b/drivers/gpu/drm/selftests/drm_selftest.c new file mode 100644 index 000000000000..e29ed9faef5b --- /dev/null +++ b/drivers/gpu/drm/selftests/drm_selftest.c @@ -0,0 +1,109 @@ +/* + * Copyright © 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include <linux/compiler.h> + +#define selftest(name, func) __idx_##name, +enum { +#include TESTS +}; +#undef selftest + +#define selftest(n, f) [__idx_##n] = { .name = #n, .func = f }, +static struct drm_selftest { + bool enabled; + const char *name; + int (*func)(void *); +} selftests[] = { +#include TESTS +}; +#undef selftest + +/* Embed the line number into the parameter name so that we can order tests */ +#define param(n) __PASTE(igt__, __PASTE(__PASTE(__LINE__, __), n)) +#define selftest_0(n, func, id) \ +module_param_named(id, selftests[__idx_##n].enabled, bool, 0400); +#define selftest(n, func) selftest_0(n, func, param(n)) +#include TESTS +#undef selftest + +static void set_default_test_all(struct drm_selftest *st, unsigned long count) +{ + unsigned long i; + + for (i = 0; i < count; i++) + if (st[i].enabled) + return; + + for (i = 0; i < count; i++) + st[i].enabled = true; +} + +static int run_selftests(struct drm_selftest *st, + unsigned long count, + void *data) +{ + int err = 0; + + set_default_test_all(st, count); + + /* Tests are listed in natural order in drm_*_selftests.h */ + for (; count--; st++) { + if (!st->enabled) + continue; + + pr_debug("drm: Running %s\n", st->name); + err = st->func(data); + if (err) + break; + } + + if (WARN(err > 0 || err == -ENOTTY, + "%s returned %d, conflicting with selftest's magic values!\n", + st->name, err)) + err = -1; + + rcu_barrier(); + return err; +} + +static int __maybe_unused +__drm_subtests(const char *caller, + const struct drm_subtest *st, + int count, + void *data) +{ + int err; + + for (; count--; st++) { + pr_debug("Running %s/%s\n", caller, st->name); + err = st->func(data); + if (err) { + pr_err("%s: %s failed with error %d\n", + caller, st->name, err); + return err; + } + } + + return 0; +} |