From: Bhawanpreet Lakha <[email protected]>

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 <[email protected]>
Signed-off-by: Bhawanpreet Lakha <[email protected]>
Signed-off-by: Wayne Lin <[email protected]>
---
 .../display/amdgpu_dm/amdgpu_dm_connector.c   |  6 +-
 .../display/amdgpu_dm/amdgpu_dm_connector.h   |  2 +
 .../tests/amdgpu_dm_connector_test.c          | 70 +++++++++++++++++++
 3 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
index 94118f7f67c6..131387524aa9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
@@ -1764,7 +1764,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);
 
@@ -1774,6 +1774,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)
 {
@@ -1877,7 +1878,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 =
@@ -1907,6 +1908,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)
 {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.h
index 8c4ba5a90ade..f7057e83b4d5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.h
@@ -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,
diff --git 
a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
index f38706e4d1c2..645347994734 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
@@ -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),
        {}
 };
 
-- 
2.43.0

Reply via email to