mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 14:33:24 -04:00
driver core: platform: tests: add test cases for correct swnode removal
Extend the kunit module for platform devices with test cases verifying that the same software node can be added to platform devices repeatedly. Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> Link: https://patch.msgid.link/20260716-swnode-remove-on-dev-unreg-v8-5-5c2b8cc38c28@oss.qualcomm.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
This commit is contained in:
committed by
Danilo Krummrich
parent
7d80509ff0
commit
397f0a3958
@@ -1,12 +1,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <kunit/fwnode.h>
|
||||
#include <kunit/platform_device.h>
|
||||
#include <kunit/resource.h>
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/device/bus.h>
|
||||
#include <linux/fwnode.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
#define DEVICE_NAME "test"
|
||||
|
||||
@@ -253,9 +256,186 @@ static struct kunit_suite platform_device_match_test_suite = {
|
||||
.test_cases = platform_device_match_tests,
|
||||
};
|
||||
|
||||
static int platform_device_swnode_test_probe(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver platform_swnode_test_driver = {
|
||||
.probe = platform_device_swnode_test_probe,
|
||||
.driver = {
|
||||
.name = DEVICE_NAME,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct software_node platform_device_test_swnode = { };
|
||||
|
||||
/*
|
||||
* Check that reusing a software node works correctly. If the call to
|
||||
* platform_device_register_full() fails after adding the secondary firmware
|
||||
* node, the software node must be unregistered in the device's release()
|
||||
* callback or the subsequent call to platform_device_register_full() will fail
|
||||
* with -EBUSY due to the software node already having been registered.
|
||||
*/
|
||||
static void platform_device_swnode_add_twice(struct kunit *test)
|
||||
{
|
||||
struct platform_device_info pdevinfo;
|
||||
struct platform_device *pdev;
|
||||
struct fwnode_handle *fwnode;
|
||||
bool bound = false;
|
||||
int ret;
|
||||
|
||||
fwnode = kunit_kzalloc(test, sizeof(*fwnode), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode);
|
||||
|
||||
ret = kunit_platform_driver_register(test, &platform_swnode_test_driver);
|
||||
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||
|
||||
fwnode_init(fwnode, NULL);
|
||||
pdevinfo = (struct platform_device_info){
|
||||
.name = DEVICE_NAME,
|
||||
.id = PLATFORM_DEVID_NONE,
|
||||
.fwnode = fwnode,
|
||||
.swnode = &platform_device_test_swnode,
|
||||
};
|
||||
|
||||
pdev = platform_device_register_full(&pdevinfo);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
|
||||
|
||||
wait_for_device_probe();
|
||||
scoped_guard(device, &pdev->dev)
|
||||
bound = device_is_bound(&pdev->dev);
|
||||
|
||||
KUNIT_ASSERT_TRUE(test, bound);
|
||||
|
||||
platform_device_unregister(pdev);
|
||||
|
||||
pdev = platform_device_register_full(&pdevinfo);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
|
||||
|
||||
wait_for_device_probe();
|
||||
scoped_guard(device, &pdev->dev)
|
||||
bound = device_is_bound(&pdev->dev);
|
||||
|
||||
KUNIT_ASSERT_TRUE(test, bound);
|
||||
|
||||
platform_device_unregister(pdev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that passing a software node as the primary firmware node of the
|
||||
* platform device does not result in it being unregistered by the call to
|
||||
* device_remove_software_node() in its release path.
|
||||
*/
|
||||
static void platform_device_swnode_as_primary(struct kunit *test)
|
||||
{
|
||||
struct platform_device_info pdevinfo;
|
||||
struct platform_device *pdev;
|
||||
struct fwnode_handle *fwnode;
|
||||
bool bound = false;
|
||||
int ret;
|
||||
|
||||
ret = kunit_platform_driver_register(test, &platform_swnode_test_driver);
|
||||
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||
|
||||
fwnode = kunit_software_node_register(test, &platform_device_test_swnode);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode);
|
||||
|
||||
pdevinfo = (struct platform_device_info){
|
||||
.name = DEVICE_NAME,
|
||||
.id = PLATFORM_DEVID_NONE,
|
||||
.fwnode = fwnode,
|
||||
};
|
||||
|
||||
pdev = platform_device_register_full(&pdevinfo);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
|
||||
|
||||
wait_for_device_probe();
|
||||
scoped_guard(device, &pdev->dev)
|
||||
bound = device_is_bound(&pdev->dev);
|
||||
|
||||
KUNIT_ASSERT_TRUE(test, bound);
|
||||
|
||||
platform_device_unregister(pdev);
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, software_node_fwnode(&platform_device_test_swnode));
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that passing two software nodes to platform_device_register_full()
|
||||
* fails.
|
||||
*/
|
||||
static void platform_device_two_swnodes(struct kunit *test)
|
||||
{
|
||||
static const struct property_entry properties[] = {
|
||||
PROPERTY_ENTRY_U32("foo", 42),
|
||||
{ }
|
||||
};
|
||||
|
||||
struct platform_device_info pdevinfo;
|
||||
struct platform_device *pdev;
|
||||
struct fwnode_handle *fwnode;
|
||||
int ret;
|
||||
|
||||
ret = kunit_platform_driver_register(test, &platform_swnode_test_driver);
|
||||
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||
|
||||
fwnode = kunit_software_node_register(test, &platform_device_test_swnode);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode);
|
||||
|
||||
pdevinfo = (struct platform_device_info){
|
||||
.name = DEVICE_NAME,
|
||||
.id = PLATFORM_DEVID_NONE,
|
||||
.fwnode = fwnode,
|
||||
.swnode = &platform_device_test_swnode,
|
||||
};
|
||||
|
||||
pdev = platform_device_register_full(&pdevinfo);
|
||||
KUNIT_ASSERT_TRUE(test, IS_ERR(pdev));
|
||||
KUNIT_ASSERT_EQ_MSG(test, PTR_ERR(pdev), -EINVAL,
|
||||
"Expected errno == -EINVAL, got: %pe", pdev);
|
||||
|
||||
pdevinfo = (struct platform_device_info){
|
||||
.name = DEVICE_NAME,
|
||||
.id = PLATFORM_DEVID_NONE,
|
||||
.swnode = &platform_device_test_swnode,
|
||||
.properties = properties,
|
||||
};
|
||||
|
||||
pdev = platform_device_register_full(&pdevinfo);
|
||||
KUNIT_ASSERT_TRUE(test, IS_ERR(pdev));
|
||||
KUNIT_ASSERT_EQ_MSG(test, PTR_ERR(pdev), -EINVAL,
|
||||
"Expected errno == -EINVAL, got: %pe", pdev);
|
||||
|
||||
pdevinfo = (struct platform_device_info){
|
||||
.name = DEVICE_NAME,
|
||||
.id = PLATFORM_DEVID_NONE,
|
||||
.fwnode = fwnode,
|
||||
.properties = properties,
|
||||
};
|
||||
|
||||
pdev = platform_device_register_full(&pdevinfo);
|
||||
KUNIT_ASSERT_TRUE(test, IS_ERR(pdev));
|
||||
KUNIT_ASSERT_EQ_MSG(test, PTR_ERR(pdev), -EINVAL,
|
||||
"Expected errno == -EINVAL, got: %pe", pdev);
|
||||
}
|
||||
|
||||
static struct kunit_case platform_device_swnode_tests[] = {
|
||||
KUNIT_CASE(platform_device_swnode_add_twice),
|
||||
KUNIT_CASE(platform_device_swnode_as_primary),
|
||||
KUNIT_CASE(platform_device_two_swnodes),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite platform_device_swnode_test_suite = {
|
||||
.name = "platform-device-swnode",
|
||||
.test_cases = platform_device_swnode_tests,
|
||||
};
|
||||
|
||||
kunit_test_suites(
|
||||
&platform_device_devm_test_suite,
|
||||
&platform_device_match_test_suite,
|
||||
&platform_device_swnode_test_suite,
|
||||
);
|
||||
|
||||
MODULE_DESCRIPTION("Test module for platform devices");
|
||||
|
||||
Reference in New Issue
Block a user