From: Alex Hung <[email protected]>

[WHAT]
Add KUnit tests for handle_hpd_irq_helper() covering a failing
dc_link_detect_connection_type() and the early return taken when a
debounce re-detect is already scheduled. Also arm the debounce work in
the stale-prev-sink test so mod_delayed_work() re-schedules.

[HOW]
Both build on dm_test_setup_hpd_irq_helper() and override only the
link_srv stubs they need. The pending-debounce test arms the work ten
seconds out and spies on dc_link_detect() to prove it was skipped.

Assisted-by: Copilot:Claude-Opus-5
Reviewed-by: Bhawanpreet Lakha <[email protected]>
Signed-off-by: Alex Hung <[email protected]>
Signed-off-by: Ivan Lipski <[email protected]>
---
 .../amdgpu_dm/tests/amdgpu_dm_irq_test.c      | 79 +++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c
index b398be878c932..c335ac0e2a6f5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c
@@ -58,6 +58,17 @@ static bool dm_test_detect_link_false(struct dc_link *link,
        return false;
 }
 
+/* Spy on dc_link_detect() to prove the debounce early-return skipped it. */
+static int dm_test_detect_link_count;
+
+static bool dm_test_detect_link_false_count(struct dc_link *link,
+                                           enum dc_detect_reason reason)
+{
+       dm_test_detect_link_count++;
+
+       return false;
+}
+
 static bool dm_test_detect_connection_single(struct dc_link *link,
                                             enum dc_connection_type *type)
 {
@@ -66,6 +77,12 @@ static bool dm_test_detect_connection_single(struct dc_link 
*link,
        return true;
 }
 
+static bool dm_test_detect_connection_fail(struct dc_link *link,
+                                          enum dc_connection_type *type)
+{
+       return false;
+}
+
 /* Recording stubs for the dm_handle_hpd_rx_offload_work() DP-IRQ branches. */
 static int dm_test_automated_test_count;
 static int dm_test_handle_link_loss_count;
@@ -2607,6 +2624,9 @@ static void 
dm_test_handle_hpd_irq_helper_debounce_schedule(struct kunit *test)
  * When the debounce branch is taken and a stale hdmi_prev_sink is already
  * cached from a previous HPD, it must be released before caching the current
  * local_sink. This exercises the dc_sink_release() of the previous sink.
+ *
+ * An already-armed debounce work also makes mod_delayed_work() re-schedule
+ * rather than queue.
  */
 static void dm_test_handle_hpd_irq_helper_debounce_release_prev(struct kunit 
*test)
 {
@@ -2628,6 +2648,10 @@ static void 
dm_test_handle_hpd_irq_helper_debounce_release_prev(struct kunit *te
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, aconn->hdmi_prev_sink);
        KUNIT_ASSERT_PTR_NE(test, aconn->hdmi_prev_sink, link->local_sink);
 
+       KUNIT_ASSERT_TRUE(test,
+                         schedule_delayed_work(&aconn->hdmi_hpd_debounce_work,
+                                               10 * HZ));
+
        handle_hpd_irq_helper(aconn, DETECT_REASON_HPD);
 
        /* Stale sink replaced by the current local_sink. */
@@ -2662,6 +2686,59 @@ static void 
dm_test_handle_hpd_irq_helper_detect_false(struct kunit *test)
        KUNIT_EXPECT_FALSE(test, aconn->fake_enable);
 }
 
+/**
+ * dm_test_handle_hpd_irq_helper_detect_type_fails - Test detect failure 
logging
+ * @test: The KUnit test context
+ *
+ * When dc_link_detect_connection_type() itself fails the helper logs an error
+ * and carries on with the connection type left as none, so it still falls
+ * through to the immediate-detect branch.
+ */
+static void dm_test_handle_hpd_irq_helper_detect_type_fails(struct kunit *test)
+{
+       struct amdgpu_dm_connector *aconn;
+       struct link_service *link_srv;
+
+       aconn = dm_test_setup_hpd_irq_helper(test, &link_srv);
+       link_srv->detect_connection_type = dm_test_detect_connection_fail;
+       link_srv->detect_link = dm_test_detect_link_false;
+       aconn->fake_enable = true;
+
+       handle_hpd_irq_helper(aconn, DETECT_REASON_HPD);
+
+       KUNIT_EXPECT_FALSE(test, aconn->fake_enable);
+}
+
+/**
+ * dm_test_handle_hpd_irq_helper_debounce_pending - Test pending-debounce exit
+ * @test: The KUnit test context
+ *
+ * A debounce re-detect that is already scheduled owns the connector state, so
+ * an HPD that would otherwise detect immediately must return early and leave
+ * dc_link_detect() untouched.
+ */
+static void dm_test_handle_hpd_irq_helper_debounce_pending(struct kunit *test)
+{
+       struct amdgpu_dm_connector *aconn;
+       struct link_service *link_srv;
+
+       dm_test_detect_link_count = 0;
+
+       aconn = dm_test_setup_hpd_irq_helper(test, &link_srv);
+       link_srv->detect_link = dm_test_detect_link_false_count;
+
+       /* Arm the debounce work far enough out that it cannot run here. */
+       KUNIT_ASSERT_TRUE(test,
+                         schedule_delayed_work(&aconn->hdmi_hpd_debounce_work,
+                                               10 * HZ));
+
+       handle_hpd_irq_helper(aconn, DETECT_REASON_HPD);
+
+       KUNIT_EXPECT_EQ(test, dm_test_detect_link_count, 0);
+
+       cancel_delayed_work_sync(&aconn->hdmi_hpd_debounce_work);
+}
+
 /* Tests for handle_hpd_rx_irq()/schedule_hpd_rx_offload_work() */
 
 /**
@@ -4331,6 +4408,8 @@ static struct kunit_case amdgpu_dm_irq_tests[] = {
        KUNIT_CASE(dm_test_handle_hpd_irq_helper_debounce_schedule),
        KUNIT_CASE(dm_test_handle_hpd_irq_helper_debounce_release_prev),
        KUNIT_CASE(dm_test_handle_hpd_irq_helper_detect_false),
+       KUNIT_CASE(dm_test_handle_hpd_irq_helper_detect_type_fails),
+       KUNIT_CASE(dm_test_handle_hpd_irq_helper_debounce_pending),
        /* handle_hpd_rx_irq/schedule_hpd_rx_offload_work */
        KUNIT_CASE(dm_test_handle_hpd_rx_irq_disabled),
        KUNIT_CASE(dm_test_handle_hpd_rx_irq_no_left_work),
-- 
2.43.0

Reply via email to