--- a/sys/dev/drm/amd/display/dc/gpio/gpio_service.c +++ b/sys/dev/drm/amd/display/dc/gpio/gpio_service.c @@ -241,36 +241,53 @@ enum gpio_result dal_gpio_service_open( struct hw_gpio_pin *pin; if (!service->busyness[id]) { ASSERT_CRITICAL(false); return GPIO_RESULT_OPEN_FAILED; } + if (en >= service->factory.number_of_pins[id]) { + ASSERT_CRITICAL(false); + return GPIO_RESULT_INVALID_DATA; + } + switch (id) { case GPIO_ID_DDC_DATA: + if (!service->factory.funcs->create_ddc_data) { + ASSERT_CRITICAL(false); + return GPIO_RESULT_NON_SPECIFIC_ERROR; + } pin = service->factory.funcs->create_ddc_data( service->ctx, id, en); - service->factory.funcs->define_ddc_registers(pin, en); break; case GPIO_ID_DDC_CLOCK: + if (!service->factory.funcs->create_ddc_clock) { + ASSERT_CRITICAL(false); + return GPIO_RESULT_NON_SPECIFIC_ERROR; + } pin = service->factory.funcs->create_ddc_clock( service->ctx, id, en); - service->factory.funcs->define_ddc_registers(pin, en); break; case GPIO_ID_GENERIC: + if (!service->factory.funcs->create_generic) { + ASSERT_CRITICAL(false); + return GPIO_RESULT_NON_SPECIFIC_ERROR; + } pin = service->factory.funcs->create_generic( service->ctx, id, en); break; case GPIO_ID_HPD: + if (!service->factory.funcs->create_hpd) { + ASSERT_CRITICAL(false); + return GPIO_RESULT_NON_SPECIFIC_ERROR; + } pin = service->factory.funcs->create_hpd( service->ctx, id, en); - service->factory.funcs->define_hpd_registers(pin, en); break; case GPIO_ID_SYNC: + if (!service->factory.funcs->create_sync) { + ASSERT_CRITICAL(false); + return GPIO_RESULT_NON_SPECIFIC_ERROR; + } pin = service->factory.funcs->create_sync( service->ctx, id, en); break; case GPIO_ID_GSL: + if (!service->factory.funcs->create_gsl) { + ASSERT_CRITICAL(false); + return GPIO_RESULT_NON_SPECIFIC_ERROR; + } pin = service->factory.funcs->create_gsl( service->ctx, id, en); break; default: ASSERT_CRITICAL(false); return GPIO_RESULT_NON_SPECIFIC_ERROR; @@ -281,6 +298,19 @@ enum gpio_result dal_gpio_service_open( return GPIO_RESULT_NON_SPECIFIC_ERROR; } + /* register tables can only be defined for a successfully created pin */ + switch (id) { + case GPIO_ID_DDC_DATA: + case GPIO_ID_DDC_CLOCK: + service->factory.funcs->define_ddc_registers(pin, en); + break; + case GPIO_ID_HPD: + service->factory.funcs->define_hpd_registers(pin, en); + break; + default: + break; + } + if (!pin->funcs->open(pin, mode)) { ASSERT_CRITICAL(false); dal_gpio_service_close(service, &pin); return GPIO_RESULT_OPEN_FAILED; }