From: Ivan Lipski <[email protected]> [Why & How] amdgpu_dm_hpd_init() was changed to walk adev->dm.dc->links directly, so the two tests that left adev->dm.dc NULL now panic on a NULL dc dereference.
Give both tests a real DC via dm_test_alloc_dc_with_irq_service() with a dc_link and dc->links[0] / link_count = 1. Reviewed-by: Alex Hung <[email protected]> Signed-off-by: Ivan Lipski <[email protected]> Signed-off-by: Ray Wu <[email protected]> --- .../amdgpu_dm/tests/amdgpu_dm_irq_test.c | 48 ++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) 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 a139890b7cd5..18a2409c5a69 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 @@ -2035,14 +2035,27 @@ static void dm_test_outbox_init_null_dc(struct kunit *test) static void dm_test_hpd_init_empty_connectors(struct kunit *test) { struct amdgpu_device *adev; + struct dc_link *link; + struct dc *dc; adev = dm_kunit_alloc_adev(test); /* - * With an empty connector list the per-connector loop is skipped and - * the initial clear loop relies on amdgpu_dm_irq_set() being a no-op - * for a NULL dc, so init must complete without touching the DC. + * The initial clear loop walks adev->dm.dc->links, so a DC with a + * populated irq service is required. With an empty connector list the + * per-connector loop is skipped, so init must complete after only the + * clear loop runs. */ + dc = dm_test_alloc_dc_with_irq_service(test, &dm_test_irq_service_funcs_dcn10); + adev->dm.dc = dc; + + link = kunit_kzalloc(test, sizeof(*link), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, link); + link->irq_source_hpd = DC_IRQ_SOURCE_HPD1; + link->irq_source_hpd_rx = DC_IRQ_SOURCE_HPD1RX; + dc->links[0] = link; + dc->link_count = 1; + amdgpu_dm_hpd_init(adev); } @@ -2070,13 +2083,17 @@ static void dm_test_hpd_init_fini_with_connectors(struct kunit *test) struct drm_connector *wbconn; struct amdgpu_device *adev; struct dc_link *link; + struct dc *dc; adev = dm_kunit_alloc_adev(test); + /* The clear loop walks dc->links, so set up a DC with an irq service. */ + dc = dm_test_alloc_dc_with_irq_service(test, &dm_test_irq_service_funcs_dcn10); + adev->dm.dc = dc; + /* * num_hpd = 0 forces irq_type >= num_hpd so the loop takes the HW - * fallback (amdgpu_dm_irq_set()) instead of amdgpu_irq_get(); with a - * NULL dc that fallback is a safe no-op. + * fallback (amdgpu_dm_irq_set()) instead of amdgpu_irq_get(). */ adev->mode_info.num_hpd = 0; @@ -2102,8 +2119,10 @@ static void dm_test_hpd_init_fini_with_connectors(struct kunit *test) link->irq_source_hpd = DC_IRQ_SOURCE_HPD1; link->irq_source_hpd_rx = DC_IRQ_SOURCE_HPD1RX; aconn->dc_link = link; + dc->links[0] = link; + dc->link_count = 1; - /* DC is absent (NULL), so the HW writes are NULL-safe no-ops. */ + /* The irq service stubs accept the HW writes without register access. */ amdgpu_dm_hpd_init(adev); amdgpu_dm_hpd_fini(adev); } @@ -2117,10 +2136,15 @@ static void dm_test_hpd_init_fini_analog_connector(struct kunit *test) struct amdgpu_dm_connector *aconn; struct amdgpu_device *adev; struct dc_link *link; + struct dc *dc; adev = dm_kunit_alloc_adev(test); adev->mode_info.num_hpd = 0; + /* The clear loop walks dc->links, so set up a DC with an irq service. */ + dc = dm_test_alloc_dc_with_irq_service(test, &dm_test_irq_service_funcs_dcn10); + adev->dm.dc = dc; + aconn = kunit_kzalloc(test, sizeof(*aconn), GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, aconn); KUNIT_ASSERT_EQ(test, drm_connector_init(&adev->ddev, &aconn->base, @@ -2136,6 +2160,8 @@ static void dm_test_hpd_init_fini_analog_connector(struct kunit *test) /* An analog connector id makes the loop request polling. */ link->link_id.id = CONNECTOR_ID_VGA; aconn->dc_link = link; + dc->links[0] = link; + dc->link_count = 1; /* use_polling becomes true, so init must enable KMS polling. */ amdgpu_dm_hpd_init(adev); @@ -2155,9 +2181,14 @@ static void dm_test_hpd_init_fini_irq_ref(struct kunit *test) struct amdgpu_dm_connector *aconn; struct amdgpu_device *adev; struct dc_link *link; + struct dc *dc; adev = dm_kunit_alloc_adev(test); + /* The clear loop walks dc->links, so set up a DC with an irq service. */ + dc = dm_test_alloc_dc_with_irq_service(test, &dm_test_irq_service_funcs_dcn10); + adev->dm.dc = dc; + /* * num_hpd >= 1 makes irq_type (0) < num_hpd, so the loop takes the * amdgpu_irq_get()/amdgpu_irq_put() branch instead of the @@ -2180,6 +2211,8 @@ static void dm_test_hpd_init_fini_irq_ref(struct kunit *test) link->irq_source_hpd = DC_IRQ_SOURCE_HPD1; link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID; aconn->dc_link = link; + dc->links[0] = link; + dc->link_count = 1; amdgpu_dm_hpd_init(adev); amdgpu_dm_hpd_fini(adev); @@ -2200,6 +2233,9 @@ static void dm_test_hpd_init_skips_connector_without_link(struct kunit *test) adev = dm_kunit_alloc_adev(test); adev->mode_info.num_hpd = 0; + /* The clear loop walks dc->links, so set up a DC with an irq service. */ + adev->dm.dc = dm_test_alloc_dc_with_irq_service(test, &dm_test_irq_service_funcs_dcn10); + aconn = kunit_kzalloc(test, sizeof(*aconn), GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, aconn); KUNIT_ASSERT_EQ(test, drm_connector_init(&adev->ddev, &aconn->base, -- 2.43.0
