drm/amd/display: Add register and unregister tests for connector

Add KUnit coverage for amdgpu_dm_connector_late_register() and
amdgpu_dm_connector_unregister(): non-DP late register succeeds and
non-DP unregister is a no-op.

Assisted-by: Copilot:Claude-Opus-4.8
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Bhawanpreet Lakha <bhawanpreet.lakha@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Bhawanpreet Lakha 2026-06-24 15:35:51 -04:00 committed by Alex Deucher
parent ab9fb27380
commit 663c4a8216
3 changed files with 76 additions and 2 deletions

View File

@ -1802,7 +1802,7 @@ int amdgpu_dm_connector_atomic_get_property(struct drm_connector *connector,
}
EXPORT_IF_KUNIT(amdgpu_dm_connector_atomic_get_property);
static void amdgpu_dm_connector_unregister(struct drm_connector *connector)
STATIC_IFN_KUNIT void amdgpu_dm_connector_unregister(struct drm_connector *connector)
{
struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector);
@ -1812,6 +1812,7 @@ static void amdgpu_dm_connector_unregister(struct drm_connector *connector)
cec_notifier_conn_unregister(amdgpu_dm_connector->notifier);
drm_dp_aux_unregister(&amdgpu_dm_connector->dm_dp_aux.aux);
}
EXPORT_IF_KUNIT(amdgpu_dm_connector_unregister);
static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
{
@ -1915,7 +1916,7 @@ amdgpu_dm_connector_atomic_duplicate_state(struct drm_connector *connector)
}
EXPORT_IF_KUNIT(amdgpu_dm_connector_atomic_duplicate_state);
static int
STATIC_IFN_KUNIT int
amdgpu_dm_connector_late_register(struct drm_connector *connector)
{
struct amdgpu_dm_connector *amdgpu_dm_connector =
@ -1945,6 +1946,7 @@ amdgpu_dm_connector_late_register(struct drm_connector *connector)
return 0;
}
EXPORT_IF_KUNIT(amdgpu_dm_connector_late_register);
static void amdgpu_dm_connector_funcs_force(struct drm_connector *connector)
{

View File

@ -168,6 +168,8 @@ enum drm_connector_status
amdgpu_dm_connector_poll(struct amdgpu_dm_connector *aconnector, bool force);
enum drm_connector_status
amdgpu_dm_connector_detect(struct drm_connector *connector, bool force);
void amdgpu_dm_connector_unregister(struct drm_connector *connector);
int amdgpu_dm_connector_late_register(struct drm_connector *connector);
enum display_content_type
get_output_content_type(const struct drm_connector_state *connector_state);
bool adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_out,

View File

@ -3923,6 +3923,72 @@ static void dm_test_poll_dac_load_returns_cached(struct kunit *test)
(int)connector_status_connected);
}
/* Tests for amdgpu_dm_connector_late_register() and _unregister() */
/*
* Build an amdgpu_dm_connector embedded in an amdgpu_device so drm_to_adev()
* resolves. A VGA connector keeps amdgpu_dm_should_create_sysfs() false (sysfs
* and DP AUX branches skipped) and bl_idx == -1 turns backlight registration
* into a no-op, leaving the register/unregister bookkeeping safe to exercise.
*/
static struct amdgpu_dm_connector *dm_test_reg_connector(struct kunit *test)
{
struct amdgpu_device *adev;
struct amdgpu_dm_connector *aconnector;
struct drm_device *drm;
struct device *dev;
dev = drm_kunit_helper_alloc_device(test);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*adev),
offsetof(struct amdgpu_device, ddev),
DRIVER_MODESET);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
aconnector = kunit_kzalloc(test, sizeof(*aconnector), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, aconnector);
KUNIT_ASSERT_EQ(test,
drmm_connector_init(drm, &aconnector->base,
&dm_test_connector_funcs,
DRM_MODE_CONNECTOR_VGA, NULL), 0);
aconnector->bl_idx = -1;
return aconnector;
}
/**
* dm_test_late_register_non_dp_succeeds - Test late_register on a plain connector
* @test: The KUnit test context
*
* With sysfs, backlight and DP AUX registration all skipped, late_register
* completes successfully.
*/
static void dm_test_late_register_non_dp_succeeds(struct kunit *test)
{
struct amdgpu_dm_connector *aconnector = dm_test_reg_connector(test);
KUNIT_EXPECT_EQ(test,
amdgpu_dm_connector_late_register(&aconnector->base), 0);
}
/**
* dm_test_unregister_non_dp_noop - Test unregister tolerates an unregistered connector
* @test: The KUnit test context
*
* No sysfs group was created, the CEC notifier is NULL and the DP AUX channel
* was never registered, so unregister must be a safe no-op.
*/
static void dm_test_unregister_non_dp_noop(struct kunit *test)
{
struct amdgpu_dm_connector *aconnector = dm_test_reg_connector(test);
KUNIT_EXPECT_FALSE(test, amdgpu_dm_should_create_sysfs(aconnector));
amdgpu_dm_connector_unregister(&aconnector->base);
}
static struct kunit_case amdgpu_dm_connector_tests[] = {
/* get_subconnector_type */
KUNIT_CASE(dm_test_subconnector_type_none),
@ -4131,6 +4197,10 @@ static struct kunit_case amdgpu_dm_connector_tests[] = {
KUNIT_CASE(dm_test_detect_no_sink),
/* amdgpu_dm_connector_poll */
KUNIT_CASE(dm_test_poll_dac_load_returns_cached),
/* amdgpu_dm_connector_late_register */
KUNIT_CASE(dm_test_late_register_non_dp_succeeds),
/* amdgpu_dm_connector_unregister */
KUNIT_CASE(dm_test_unregister_non_dp_noop),
{}
};