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
