From: Stephen Boyd <sboyd@kernel.org>
To: Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@kernel.org>
Cc: linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org,
patches@lists.linux.dev,
Brendan Higgins <brendan.higgins@linux.dev>,
David Gow <davidgow@google.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
"Rafael J . Wysocki" <rafael@kernel.org>,
Richard Weinberger <richard@nod.at>,
Anton Ivanov <anton.ivanov@cambridgegreys.com>,
Johannes Berg <johannes@sipsolutions.net>,
Vincent Whitchurch <vincent.whitchurch@axis.com>,
Rob Herring <robh+dt@kernel.org>,
Frank Rowand <frowand.list@gmail.com>,
Christian Marangi <ansuelsmth@gmail.com>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
devicetree@vger.kernel.org, linux-um@lists.infradead.org,
linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com
Subject: [PATCH 3/8] kunit: Add test managed platform_device/driver APIs
Date: Wed, 1 Mar 2023 17:38:16 -0800 [thread overview]
Message-ID: <20230302013822.1808711-4-sboyd@kernel.org> (raw)
In-Reply-To: <20230302013822.1808711-1-sboyd@kernel.org>
Introduce KUnit resource wrappers around platform_driver_register(),
platform_device_alloc(), and platform_device_add() so that test authors
can register platform drivers/devices from their tests and have the
drivers/devices automatically be unregistered when the test is done.
This makes test setup code simpler when a platform driver or platform
device is needed. Add a few test cases at the same time to make sure the
APIs work as intended.
Cc: Brendan Higgins <brendan.higgins@linux.dev>
Cc: David Gow <davidgow@google.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
Should this be moved to drivers/base/ and called platform_kunit.c?
The include/kunit/platform_driver.h could also be
kunit/platform_device.h to match linux/platform_device.h if that is more
familiar.
And I'm not super certain about allocating a driver structure and
embedding it in a wrapper struct. Maybe the code should just use
kunit_get_current_test() instead?
include/kunit/platform_driver.h | 15 +++
lib/kunit/Makefile | 6 +
lib/kunit/platform_driver-test.c | 107 ++++++++++++++++
lib/kunit/platform_driver.c | 207 +++++++++++++++++++++++++++++++
4 files changed, 335 insertions(+)
create mode 100644 include/kunit/platform_driver.h
create mode 100644 lib/kunit/platform_driver-test.c
create mode 100644 lib/kunit/platform_driver.c
diff --git a/include/kunit/platform_driver.h b/include/kunit/platform_driver.h
new file mode 100644
index 000000000000..dc211ff8f893
--- /dev/null
+++ b/include/kunit/platform_driver.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _KUNIT_PLATFORM_DRIVER_H
+#define _KUNIT_PLATFORM_DRIVER_H
+
+struct kunit;
+struct platform_device;
+struct platform_driver;
+
+struct platform_device *
+kunit_platform_device_alloc(struct kunit *test, const char *name, int id);
+int kunit_platform_device_add(struct kunit *test, struct platform_device *pdev);
+
+int kunit_platform_driver_register(struct kunit *test, struct platform_driver *drv);
+
+#endif
diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile
index 29aff6562b42..5964d8231ff5 100644
--- a/lib/kunit/Makefile
+++ b/lib/kunit/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_KUNIT) += kunit.o
+# Core KUnit code
kunit-objs += test.o \
resource.o \
string-stream.o \
@@ -11,7 +12,12 @@ ifeq ($(CONFIG_KUNIT_DEBUGFS),y)
kunit-objs += debugfs.o
endif
+# KUnit helpers
+kunit-objs += platform_driver.o
+
+# KUnit tests
obj-$(CONFIG_KUNIT_TEST) += kunit-test.o
+obj-$(CONFIG_KUNIT_TEST) += platform_driver-test.o
# string-stream-test compiles built-in only.
ifeq ($(CONFIG_KUNIT_TEST),y)
diff --git a/lib/kunit/platform_driver-test.c b/lib/kunit/platform_driver-test.c
new file mode 100644
index 000000000000..c926fe01b40a
--- /dev/null
+++ b/lib/kunit/platform_driver-test.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit test for platform driver infrastructure.
+ */
+
+#include <linux/platform_device.h>
+
+#include <kunit/platform_driver.h>
+#include <kunit/test.h>
+
+/*
+ * Test that kunit_platform_device_alloc() creates a platform device.
+ */
+static void kunit_platform_device_alloc_test(struct kunit *test)
+{
+ KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
+ kunit_platform_device_alloc(test, "kunit-platform", 1));
+}
+
+/*
+ * Test that kunit_platform_device_add() registers a platform device on the
+ * platform bus with the proper name and id.
+ */
+static void kunit_platform_device_add_test(struct kunit *test)
+{
+ struct platform_device *pdev;
+ const char *name = "kunit-platform";
+ const int id = -1;
+
+ pdev = kunit_platform_device_alloc(test, name, id);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
+
+ KUNIT_EXPECT_EQ(test, 0, kunit_platform_device_add(test, pdev));
+ KUNIT_EXPECT_TRUE(test, dev_is_platform(&pdev->dev));
+ KUNIT_EXPECT_STREQ(test, pdev->name, name);
+ KUNIT_EXPECT_EQ(test, pdev->id, id);
+}
+
+static struct kunit_case kunit_platform_device_test_cases[] = {
+ KUNIT_CASE(kunit_platform_device_alloc_test),
+ KUNIT_CASE(kunit_platform_device_add_test),
+ {}
+};
+
+static struct kunit_suite kunit_platform_device_suite = {
+ .name = "kunit_platform_device",
+ .test_cases = kunit_platform_device_test_cases,
+};
+
+struct kunit_platform_driver_test_context {
+ struct platform_driver pdrv;
+ const char *data;
+};
+
+static inline struct kunit_platform_driver_test_context *
+to_test_context(struct platform_device *pdev)
+{
+ return container_of(to_platform_driver(pdev->dev.driver),
+ struct kunit_platform_driver_test_context,
+ pdrv);
+}
+
+static int kunit_platform_driver_probe(struct platform_device *pdev)
+{
+ struct kunit_platform_driver_test_context *ctx;
+
+ ctx = to_test_context(pdev);
+ ctx->data = "test data";
+
+ return 0;
+}
+
+/* Test that kunit_platform_driver_register() registers a driver that probes. */
+static void kunit_platform_driver_register_test(struct kunit *test)
+{
+ struct platform_device *pdev;
+ struct kunit_platform_driver_test_context *ctx;
+
+ ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ pdev = kunit_platform_device_alloc(test, "kunit-platform", -1);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
+ KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(test, pdev));
+
+ ctx->pdrv.probe = kunit_platform_driver_probe;
+ ctx->pdrv.driver.name = "kunit-platform";
+ ctx->pdrv.driver.owner = THIS_MODULE;
+
+ KUNIT_EXPECT_EQ(test, 0, kunit_platform_driver_register(test, &ctx->pdrv));
+ KUNIT_EXPECT_STREQ(test, ctx->data, "test data");
+}
+
+static struct kunit_case kunit_platform_driver_test_cases[] = {
+ KUNIT_CASE(kunit_platform_driver_register_test),
+ {}
+};
+
+static struct kunit_suite kunit_platform_driver_suite = {
+ .name = "kunit_platform_driver",
+ .test_cases = kunit_platform_driver_test_cases,
+};
+
+kunit_test_suites(&kunit_platform_device_suite,
+ &kunit_platform_driver_suite);
+
+MODULE_LICENSE("GPL");
diff --git a/lib/kunit/platform_driver.c b/lib/kunit/platform_driver.c
new file mode 100644
index 000000000000..11d155114936
--- /dev/null
+++ b/lib/kunit/platform_driver.c
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test managed platform driver
+ */
+
+#include <linux/device/driver.h>
+#include <linux/platform_device.h>
+
+#include <kunit/resource.h>
+
+struct kunit_platform_device_alloc_params {
+ const char *name;
+ int id;
+};
+
+static int kunit_platform_device_alloc_init(struct kunit_resource *res, void *context)
+{
+ struct kunit_platform_device_alloc_params *params = context;
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc(params->name, params->id);
+ if (!pdev)
+ return -ENOMEM;
+
+ res->data = pdev;
+
+ return 0;
+}
+
+static void kunit_platform_device_alloc_exit(struct kunit_resource *res)
+{
+ struct platform_device *pdev = res->data;
+
+ platform_device_put(pdev);
+}
+
+/**
+ * kunit_platform_device_alloc() - Allocate a KUnit test managed platform device
+ * @test: test context
+ * @dev: platform device to alloc
+ *
+ * Register a test managed platform device. The device is put when the test completes.
+ *
+ * Returns: 0 on success, negative errno on failure.
+ */
+struct platform_device *
+kunit_platform_device_alloc(struct kunit *test, const char *name, int id)
+{
+ struct platform_device *pdev;
+ struct kunit_platform_device_alloc_params params = {
+ .name = name,
+ .id = id,
+ };
+
+ pdev = kunit_alloc_resource(test,
+ kunit_platform_device_alloc_init,
+ kunit_platform_device_alloc_exit,
+ GFP_KERNEL, ¶ms);
+ if (!pdev)
+ return ERR_PTR(-ENOMEM);
+
+ return pdev;
+}
+EXPORT_SYMBOL_GPL(kunit_platform_device_alloc);
+
+static int kunit_platform_device_add_init(struct kunit_resource *res, void *context)
+{
+ struct platform_device *pdev = context;
+ int ret;
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+ platform_device_put(pdev);
+ return ret;
+ }
+ res->data = pdev;
+
+ return 0;
+}
+
+static void kunit_platform_device_add_exit(struct kunit_resource *res)
+{
+ struct platform_device *pdev = res->data;
+
+ platform_device_unregister(pdev);
+}
+
+/**
+ * kunit_platform_device_add() - Register a KUnit test managed platform device
+ * @test: test context
+ * @dev: platform device to add
+ *
+ * Register a test managed platform device. The device is unregistered when the
+ * test completes.
+ *
+ * Returns: 0 on success, negative errno on failure.
+ */
+int kunit_platform_device_add(struct kunit *test, struct platform_device *pdev)
+{
+ struct platform_device *res;
+
+ res = kunit_alloc_resource(test,
+ kunit_platform_device_add_init,
+ kunit_platform_device_add_exit,
+ GFP_KERNEL, pdev);
+ if (!res)
+ return -EINVAL;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(kunit_platform_device_add);
+
+static int kunit_platform_driver_register_init(struct kunit_resource *res, void *context)
+{
+ struct platform_driver *drv = context;
+ int ret;
+
+ ret = platform_driver_register(drv);
+ if (ret)
+ return ret;
+ res->data = drv;
+
+ /*
+ * Wait for the driver to probe (or at least flush out of the deferred
+ * workqueue)
+ */
+ wait_for_device_probe();
+
+ return 0;
+}
+
+static void kunit_platform_driver_register_exit(struct kunit_resource *res)
+{
+ struct platform_driver *drv = res->data;
+
+ platform_driver_unregister(drv);
+}
+
+/**
+ * kunit_platform_driver_register() - Register a KUnit test managed platform driver
+ * @test: test context
+ * @drv: platform driver to register
+ *
+ * Register a test managed platform driver. This allows callers to embed the
+ * @drv in a container structure and use container_of() in the probe function
+ * to pass information to kunit tests. It can be assumed that the driver has
+ * probed when this function returns.
+ *
+ * Example:
+ *
+ * .. code-block:: c
+ *
+ * struct kunit_test_context {
+ * struct platform_driver pdrv;
+ * const char *data;
+ * };
+ *
+ * static inline struct kunit_test_context *
+ * to_test_context(struct platform_device *pdev)
+ * {
+ * return container_of(to_platform_driver(pdev->dev.driver),
+ * struct kunit_test_context,
+ * pdrv);
+ * }
+ *
+ * static int kunit_platform_driver_probe(struct platform_device *pdev)
+ * {
+ * struct kunit_test_context *ctx;
+ *
+ * ctx = to_test_context(pdev);
+ * ctx->data = "test data";
+ *
+ * return 0;
+ * }
+ *
+ * static void kunit_platform_driver_test(struct kunit *test)
+ * {
+ * struct kunit_test_context *ctx;
+ *
+ * ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
+ * KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+ *
+ * ctx->pdrv.probe = kunit_platform_driver_probe;
+ * ctx->pdrv.driver.name = "kunit-platform";
+ * ctx->pdrv.driver.owner = THIS_MODULE;
+ *
+ * KUNIT_EXPECT_EQ(test, 0, kunit_platform_driver_register(test, &ctx->pdrv));
+ * KUNIT_EXPECT_STREQ(test, ctx->data, "test data");
+ * }
+ *
+ * Returns: 0 on success, negative errno on failure.
+ */
+int kunit_platform_driver_register(struct kunit *test,
+ struct platform_driver *drv)
+{
+ struct platform_driver *res;
+
+ res = kunit_alloc_resource(test,
+ kunit_platform_driver_register_init,
+ kunit_platform_driver_register_exit,
+ GFP_KERNEL, drv);
+ if (!res)
+ return -EINVAL;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(kunit_platform_driver_register);
--
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git
WARNING: multiple messages have this Message-ID (diff)
From: Stephen Boyd <sboyd@kernel.org>
To: Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@kernel.org>
Cc: linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org,
patches@lists.linux.dev,
Brendan Higgins <brendan.higgins@linux.dev>,
David Gow <davidgow@google.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
"Rafael J . Wysocki" <rafael@kernel.org>,
Richard Weinberger <richard@nod.at>,
Anton Ivanov <anton.ivanov@cambridgegreys.com>,
Johannes Berg <johannes@sipsolutions.net>,
Vincent Whitchurch <vincent.whitchurch@axis.com>,
Rob Herring <robh+dt@kernel.org>,
Frank Rowand <frowand.list@gmail.com>,
Christian Marangi <ansuelsmth@gmail.com>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
devicetree@vger.kernel.org, linux-um@lists.infradead.org,
linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com
Subject: [PATCH 3/8] kunit: Add test managed platform_device/driver APIs
Date: Wed, 1 Mar 2023 17:38:16 -0800 [thread overview]
Message-ID: <20230302013822.1808711-4-sboyd@kernel.org> (raw)
In-Reply-To: <20230302013822.1808711-1-sboyd@kernel.org>
Introduce KUnit resource wrappers around platform_driver_register(),
platform_device_alloc(), and platform_device_add() so that test authors
can register platform drivers/devices from their tests and have the
drivers/devices automatically be unregistered when the test is done.
This makes test setup code simpler when a platform driver or platform
device is needed. Add a few test cases at the same time to make sure the
APIs work as intended.
Cc: Brendan Higgins <brendan.higgins@linux.dev>
Cc: David Gow <davidgow@google.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
Should this be moved to drivers/base/ and called platform_kunit.c?
The include/kunit/platform_driver.h could also be
kunit/platform_device.h to match linux/platform_device.h if that is more
familiar.
And I'm not super certain about allocating a driver structure and
embedding it in a wrapper struct. Maybe the code should just use
kunit_get_current_test() instead?
include/kunit/platform_driver.h | 15 +++
lib/kunit/Makefile | 6 +
lib/kunit/platform_driver-test.c | 107 ++++++++++++++++
lib/kunit/platform_driver.c | 207 +++++++++++++++++++++++++++++++
4 files changed, 335 insertions(+)
create mode 100644 include/kunit/platform_driver.h
create mode 100644 lib/kunit/platform_driver-test.c
create mode 100644 lib/kunit/platform_driver.c
diff --git a/include/kunit/platform_driver.h b/include/kunit/platform_driver.h
new file mode 100644
index 000000000000..dc211ff8f893
--- /dev/null
+++ b/include/kunit/platform_driver.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _KUNIT_PLATFORM_DRIVER_H
+#define _KUNIT_PLATFORM_DRIVER_H
+
+struct kunit;
+struct platform_device;
+struct platform_driver;
+
+struct platform_device *
+kunit_platform_device_alloc(struct kunit *test, const char *name, int id);
+int kunit_platform_device_add(struct kunit *test, struct platform_device *pdev);
+
+int kunit_platform_driver_register(struct kunit *test, struct platform_driver *drv);
+
+#endif
diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile
index 29aff6562b42..5964d8231ff5 100644
--- a/lib/kunit/Makefile
+++ b/lib/kunit/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_KUNIT) += kunit.o
+# Core KUnit code
kunit-objs += test.o \
resource.o \
string-stream.o \
@@ -11,7 +12,12 @@ ifeq ($(CONFIG_KUNIT_DEBUGFS),y)
kunit-objs += debugfs.o
endif
+# KUnit helpers
+kunit-objs += platform_driver.o
+
+# KUnit tests
obj-$(CONFIG_KUNIT_TEST) += kunit-test.o
+obj-$(CONFIG_KUNIT_TEST) += platform_driver-test.o
# string-stream-test compiles built-in only.
ifeq ($(CONFIG_KUNIT_TEST),y)
diff --git a/lib/kunit/platform_driver-test.c b/lib/kunit/platform_driver-test.c
new file mode 100644
index 000000000000..c926fe01b40a
--- /dev/null
+++ b/lib/kunit/platform_driver-test.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit test for platform driver infrastructure.
+ */
+
+#include <linux/platform_device.h>
+
+#include <kunit/platform_driver.h>
+#include <kunit/test.h>
+
+/*
+ * Test that kunit_platform_device_alloc() creates a platform device.
+ */
+static void kunit_platform_device_alloc_test(struct kunit *test)
+{
+ KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
+ kunit_platform_device_alloc(test, "kunit-platform", 1));
+}
+
+/*
+ * Test that kunit_platform_device_add() registers a platform device on the
+ * platform bus with the proper name and id.
+ */
+static void kunit_platform_device_add_test(struct kunit *test)
+{
+ struct platform_device *pdev;
+ const char *name = "kunit-platform";
+ const int id = -1;
+
+ pdev = kunit_platform_device_alloc(test, name, id);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
+
+ KUNIT_EXPECT_EQ(test, 0, kunit_platform_device_add(test, pdev));
+ KUNIT_EXPECT_TRUE(test, dev_is_platform(&pdev->dev));
+ KUNIT_EXPECT_STREQ(test, pdev->name, name);
+ KUNIT_EXPECT_EQ(test, pdev->id, id);
+}
+
+static struct kunit_case kunit_platform_device_test_cases[] = {
+ KUNIT_CASE(kunit_platform_device_alloc_test),
+ KUNIT_CASE(kunit_platform_device_add_test),
+ {}
+};
+
+static struct kunit_suite kunit_platform_device_suite = {
+ .name = "kunit_platform_device",
+ .test_cases = kunit_platform_device_test_cases,
+};
+
+struct kunit_platform_driver_test_context {
+ struct platform_driver pdrv;
+ const char *data;
+};
+
+static inline struct kunit_platform_driver_test_context *
+to_test_context(struct platform_device *pdev)
+{
+ return container_of(to_platform_driver(pdev->dev.driver),
+ struct kunit_platform_driver_test_context,
+ pdrv);
+}
+
+static int kunit_platform_driver_probe(struct platform_device *pdev)
+{
+ struct kunit_platform_driver_test_context *ctx;
+
+ ctx = to_test_context(pdev);
+ ctx->data = "test data";
+
+ return 0;
+}
+
+/* Test that kunit_platform_driver_register() registers a driver that probes. */
+static void kunit_platform_driver_register_test(struct kunit *test)
+{
+ struct platform_device *pdev;
+ struct kunit_platform_driver_test_context *ctx;
+
+ ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+
+ pdev = kunit_platform_device_alloc(test, "kunit-platform", -1);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
+ KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(test, pdev));
+
+ ctx->pdrv.probe = kunit_platform_driver_probe;
+ ctx->pdrv.driver.name = "kunit-platform";
+ ctx->pdrv.driver.owner = THIS_MODULE;
+
+ KUNIT_EXPECT_EQ(test, 0, kunit_platform_driver_register(test, &ctx->pdrv));
+ KUNIT_EXPECT_STREQ(test, ctx->data, "test data");
+}
+
+static struct kunit_case kunit_platform_driver_test_cases[] = {
+ KUNIT_CASE(kunit_platform_driver_register_test),
+ {}
+};
+
+static struct kunit_suite kunit_platform_driver_suite = {
+ .name = "kunit_platform_driver",
+ .test_cases = kunit_platform_driver_test_cases,
+};
+
+kunit_test_suites(&kunit_platform_device_suite,
+ &kunit_platform_driver_suite);
+
+MODULE_LICENSE("GPL");
diff --git a/lib/kunit/platform_driver.c b/lib/kunit/platform_driver.c
new file mode 100644
index 000000000000..11d155114936
--- /dev/null
+++ b/lib/kunit/platform_driver.c
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test managed platform driver
+ */
+
+#include <linux/device/driver.h>
+#include <linux/platform_device.h>
+
+#include <kunit/resource.h>
+
+struct kunit_platform_device_alloc_params {
+ const char *name;
+ int id;
+};
+
+static int kunit_platform_device_alloc_init(struct kunit_resource *res, void *context)
+{
+ struct kunit_platform_device_alloc_params *params = context;
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc(params->name, params->id);
+ if (!pdev)
+ return -ENOMEM;
+
+ res->data = pdev;
+
+ return 0;
+}
+
+static void kunit_platform_device_alloc_exit(struct kunit_resource *res)
+{
+ struct platform_device *pdev = res->data;
+
+ platform_device_put(pdev);
+}
+
+/**
+ * kunit_platform_device_alloc() - Allocate a KUnit test managed platform device
+ * @test: test context
+ * @dev: platform device to alloc
+ *
+ * Register a test managed platform device. The device is put when the test completes.
+ *
+ * Returns: 0 on success, negative errno on failure.
+ */
+struct platform_device *
+kunit_platform_device_alloc(struct kunit *test, const char *name, int id)
+{
+ struct platform_device *pdev;
+ struct kunit_platform_device_alloc_params params = {
+ .name = name,
+ .id = id,
+ };
+
+ pdev = kunit_alloc_resource(test,
+ kunit_platform_device_alloc_init,
+ kunit_platform_device_alloc_exit,
+ GFP_KERNEL, ¶ms);
+ if (!pdev)
+ return ERR_PTR(-ENOMEM);
+
+ return pdev;
+}
+EXPORT_SYMBOL_GPL(kunit_platform_device_alloc);
+
+static int kunit_platform_device_add_init(struct kunit_resource *res, void *context)
+{
+ struct platform_device *pdev = context;
+ int ret;
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+ platform_device_put(pdev);
+ return ret;
+ }
+ res->data = pdev;
+
+ return 0;
+}
+
+static void kunit_platform_device_add_exit(struct kunit_resource *res)
+{
+ struct platform_device *pdev = res->data;
+
+ platform_device_unregister(pdev);
+}
+
+/**
+ * kunit_platform_device_add() - Register a KUnit test managed platform device
+ * @test: test context
+ * @dev: platform device to add
+ *
+ * Register a test managed platform device. The device is unregistered when the
+ * test completes.
+ *
+ * Returns: 0 on success, negative errno on failure.
+ */
+int kunit_platform_device_add(struct kunit *test, struct platform_device *pdev)
+{
+ struct platform_device *res;
+
+ res = kunit_alloc_resource(test,
+ kunit_platform_device_add_init,
+ kunit_platform_device_add_exit,
+ GFP_KERNEL, pdev);
+ if (!res)
+ return -EINVAL;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(kunit_platform_device_add);
+
+static int kunit_platform_driver_register_init(struct kunit_resource *res, void *context)
+{
+ struct platform_driver *drv = context;
+ int ret;
+
+ ret = platform_driver_register(drv);
+ if (ret)
+ return ret;
+ res->data = drv;
+
+ /*
+ * Wait for the driver to probe (or at least flush out of the deferred
+ * workqueue)
+ */
+ wait_for_device_probe();
+
+ return 0;
+}
+
+static void kunit_platform_driver_register_exit(struct kunit_resource *res)
+{
+ struct platform_driver *drv = res->data;
+
+ platform_driver_unregister(drv);
+}
+
+/**
+ * kunit_platform_driver_register() - Register a KUnit test managed platform driver
+ * @test: test context
+ * @drv: platform driver to register
+ *
+ * Register a test managed platform driver. This allows callers to embed the
+ * @drv in a container structure and use container_of() in the probe function
+ * to pass information to kunit tests. It can be assumed that the driver has
+ * probed when this function returns.
+ *
+ * Example:
+ *
+ * .. code-block:: c
+ *
+ * struct kunit_test_context {
+ * struct platform_driver pdrv;
+ * const char *data;
+ * };
+ *
+ * static inline struct kunit_test_context *
+ * to_test_context(struct platform_device *pdev)
+ * {
+ * return container_of(to_platform_driver(pdev->dev.driver),
+ * struct kunit_test_context,
+ * pdrv);
+ * }
+ *
+ * static int kunit_platform_driver_probe(struct platform_device *pdev)
+ * {
+ * struct kunit_test_context *ctx;
+ *
+ * ctx = to_test_context(pdev);
+ * ctx->data = "test data";
+ *
+ * return 0;
+ * }
+ *
+ * static void kunit_platform_driver_test(struct kunit *test)
+ * {
+ * struct kunit_test_context *ctx;
+ *
+ * ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
+ * KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
+ *
+ * ctx->pdrv.probe = kunit_platform_driver_probe;
+ * ctx->pdrv.driver.name = "kunit-platform";
+ * ctx->pdrv.driver.owner = THIS_MODULE;
+ *
+ * KUNIT_EXPECT_EQ(test, 0, kunit_platform_driver_register(test, &ctx->pdrv));
+ * KUNIT_EXPECT_STREQ(test, ctx->data, "test data");
+ * }
+ *
+ * Returns: 0 on success, negative errno on failure.
+ */
+int kunit_platform_driver_register(struct kunit *test,
+ struct platform_driver *drv)
+{
+ struct platform_driver *res;
+
+ res = kunit_alloc_resource(test,
+ kunit_platform_driver_register_init,
+ kunit_platform_driver_register_exit,
+ GFP_KERNEL, drv);
+ if (!res)
+ return -EINVAL;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(kunit_platform_driver_register);
--
https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/
https://git.kernel.org/pub/scm/linux/kernel/git/sboyd/spmi.git
_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um
next prev parent reply other threads:[~2023-03-02 1:38 UTC|newest]
Thread overview: 120+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-02 1:38 [PATCH 0/8] clk: Add kunit tests for fixed rate and parent data Stephen Boyd
2023-03-02 1:38 ` Stephen Boyd
2023-03-02 1:38 ` [PATCH 1/8] dt-bindings: Add linux,kunit binding Stephen Boyd
2023-03-02 1:38 ` Stephen Boyd
2023-03-03 7:14 ` David Gow
2023-03-03 7:14 ` David Gow
2023-03-03 7:49 ` Geert Uytterhoeven
2023-03-03 7:49 ` Geert Uytterhoeven
2023-03-09 23:12 ` Stephen Boyd
2023-03-09 23:12 ` Stephen Boyd
2023-03-10 7:55 ` David Gow
2023-03-10 7:55 ` David Gow
2023-03-02 1:38 ` [PATCH 2/8] of: Enable DTB loading on UML for KUnit tests Stephen Boyd
2023-03-02 1:38 ` Stephen Boyd
2023-03-03 7:15 ` David Gow
2023-03-03 7:15 ` David Gow
2023-03-09 23:19 ` Stephen Boyd
2023-03-09 23:19 ` Stephen Boyd
2023-03-10 8:09 ` David Gow
2023-03-10 8:09 ` David Gow
2023-03-10 23:34 ` Stephen Boyd
2023-03-10 23:34 ` Stephen Boyd
2023-03-11 6:42 ` David Gow
2023-03-11 6:42 ` David Gow
2023-03-13 16:02 ` Frank Rowand
2023-03-13 16:02 ` Frank Rowand
2023-03-14 4:28 ` Frank Rowand
2023-03-14 4:28 ` Frank Rowand
2023-03-15 7:04 ` David Gow
2023-03-15 7:04 ` David Gow
2023-03-15 21:35 ` Frank Rowand
2023-03-15 21:35 ` Frank Rowand
2023-03-16 0:45 ` Frank Rowand
2023-03-16 0:45 ` Frank Rowand
2023-03-16 4:15 ` David Gow
2023-03-16 4:15 ` David Gow
2023-03-21 20:56 ` Stephen Boyd
2023-03-21 20:56 ` Stephen Boyd
2023-03-08 19:46 ` Rob Herring
2023-03-08 19:46 ` Rob Herring
2023-03-02 1:38 ` Stephen Boyd [this message]
2023-03-02 1:38 ` [PATCH 3/8] kunit: Add test managed platform_device/driver APIs Stephen Boyd
2023-03-03 7:15 ` David Gow
2023-03-03 7:15 ` David Gow
2023-03-03 14:35 ` Maxime Ripard
2023-03-03 14:35 ` Maxime Ripard
2023-03-09 23:31 ` Stephen Boyd
2023-03-09 23:31 ` Stephen Boyd
2023-03-15 8:27 ` Maxime Ripard
2023-03-15 8:27 ` Maxime Ripard
2023-03-09 23:25 ` Stephen Boyd
2023-03-09 23:25 ` Stephen Boyd
2023-03-10 8:19 ` David Gow
2023-03-10 8:19 ` David Gow
2023-03-02 1:38 ` [PATCH 4/8] clk: Add test managed clk provider/consumer APIs Stephen Boyd
2023-03-02 1:38 ` Stephen Boyd
2023-03-03 7:15 ` David Gow
2023-03-03 7:15 ` David Gow
2023-03-10 23:21 ` Stephen Boyd
2023-03-10 23:21 ` Stephen Boyd
2023-03-11 6:32 ` David Gow
2023-03-11 6:32 ` David Gow
2023-03-21 14:32 ` Maxime Ripard
2023-03-21 14:32 ` Maxime Ripard
2023-03-02 1:38 ` [PATCH 5/8] dt-bindings: kunit: Add fixed rate clk consumer test Stephen Boyd
2023-03-02 1:38 ` Stephen Boyd
2023-03-02 1:38 ` [PATCH 6/8] clk: Add KUnit tests for clk fixed rate basic type Stephen Boyd
2023-03-02 1:38 ` Stephen Boyd
2023-03-02 1:38 ` [PATCH 7/8] dt-bindings: clk: Add KUnit clk_parent_data test Stephen Boyd
2023-03-02 1:38 ` Stephen Boyd
2023-03-02 1:38 ` [PATCH 8/8] clk: Add KUnit tests for clks registered with struct clk_parent_data Stephen Boyd
2023-03-02 1:38 ` Stephen Boyd
2023-03-02 8:13 ` [PATCH 0/8] clk: Add kunit tests for fixed rate and parent data David Gow
2023-03-02 8:13 ` David Gow
2023-03-02 17:32 ` Rob Herring
2023-03-02 17:32 ` Rob Herring
2023-03-02 19:27 ` Stephen Boyd
2023-03-02 19:27 ` Stephen Boyd
2023-03-02 19:47 ` Geert Uytterhoeven
2023-03-02 19:47 ` Geert Uytterhoeven
2023-03-05 3:32 ` Frank Rowand
2023-03-05 3:32 ` Frank Rowand
2023-03-05 9:26 ` Geert Uytterhoeven
2023-03-05 9:26 ` Geert Uytterhoeven
2023-03-06 5:32 ` Frank Rowand
2023-03-06 5:32 ` Frank Rowand
2023-03-04 15:04 ` Frank Rowand
2023-03-04 15:04 ` Frank Rowand
2023-03-07 21:53 ` Stephen Boyd
2023-03-07 21:53 ` Stephen Boyd
2023-03-04 14:48 ` Frank Rowand
2023-03-04 14:48 ` Frank Rowand
2023-03-02 17:13 ` Rob Herring
2023-03-02 17:13 ` Rob Herring
2023-03-02 19:44 ` Stephen Boyd
2023-03-02 19:44 ` Stephen Boyd
2023-03-02 20:18 ` Rob Herring
2023-03-02 20:18 ` Rob Herring
2023-03-02 23:57 ` Stephen Boyd
2023-03-02 23:57 ` Stephen Boyd
2023-03-04 15:39 ` Frank Rowand
2023-03-04 15:39 ` Frank Rowand
2023-03-06 12:53 ` Rob Herring
2023-03-06 12:53 ` Rob Herring
2023-03-06 15:03 ` Frank Rowand
2023-03-06 15:03 ` Frank Rowand
2023-03-04 15:37 ` Frank Rowand
2023-03-04 15:37 ` Frank Rowand
2023-03-04 15:33 ` Frank Rowand
2023-03-04 15:33 ` Frank Rowand
2023-03-03 14:38 ` Maxime Ripard
2023-03-03 14:38 ` Maxime Ripard
2023-03-07 22:37 ` Stephen Boyd
2023-03-07 22:37 ` Stephen Boyd
2023-03-04 15:50 ` Frank Rowand
2023-03-04 15:50 ` Frank Rowand
2023-03-10 7:48 ` David Gow
2023-03-10 7:48 ` David Gow
2023-03-13 15:30 ` Frank Rowand
2023-03-13 15:30 ` Frank Rowand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230302013822.1808711-4-sboyd@kernel.org \
--to=sboyd@kernel.org \
--cc=ansuelsmth@gmail.com \
--cc=anton.ivanov@cambridgegreys.com \
--cc=brendan.higgins@linux.dev \
--cc=davidgow@google.com \
--cc=devicetree@vger.kernel.org \
--cc=frowand.list@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=johannes@sipsolutions.net \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=kunit-dev@googlegroups.com \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-um@lists.infradead.org \
--cc=mturquette@baylibre.com \
--cc=patches@lists.linux.dev \
--cc=rafael@kernel.org \
--cc=richard@nod.at \
--cc=robh+dt@kernel.org \
--cc=vincent.whitchurch@axis.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.