diff options
author | Su Sung Chung <Su.Chung@amd.com> | 2019-07-08 11:31:39 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-08-15 10:53:55 -0500 |
commit | 91db9311945f01901ddb9813ce11364de214a156 (patch) | |
tree | 1afec6692b3e5f2a29036ab0b889bf558adf91ac /drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c | |
parent | 37495fbdf12d1bce30dbc228c901ef45eba35739 (diff) | |
download | linux-91db9311945f01901ddb9813ce11364de214a156.tar.gz linux-91db9311945f01901ddb9813ce11364de214a156.tar.bz2 linux-91db9311945f01901ddb9813ce11364de214a156.zip |
drm/amd/display: refactor gpio to allocate hw_container in constructor
[why]
if dynamic allocation fails during gpio_open, it will cause crash due to
page fault.
[how]
handle allocation when gpio object gets created and prevent from calling
gpio_open if allocation failed
Signed-off-by: Su Sung Chung <Su.Chung@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c | 51 |
1 files changed, 22 insertions, 29 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c index a7bc3ee5dfec..d03165e71dc6 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c @@ -290,13 +290,15 @@ enum gpio_result dal_gpio_service_unlock( } enum gpio_result dal_gpio_service_open( - struct gpio_service *service, - enum gpio_id id, - uint32_t en, - enum gpio_mode mode, - struct hw_gpio_pin **ptr) + struct gpio *gpio) { - struct hw_gpio_pin *pin; + struct gpio_service *service = gpio->service; + enum gpio_id id = gpio->id; + uint32_t en = gpio->en; + enum gpio_mode mode = gpio->mode; + + struct hw_gpio_pin **pin = &gpio->pin; + if (!service->busyness[id]) { ASSERT_CRITICAL(false); @@ -310,51 +312,43 @@ enum gpio_result dal_gpio_service_open( switch (id) { case GPIO_ID_DDC_DATA: - pin = service->factory.funcs->create_ddc_data( - service->ctx, id, en); - service->factory.funcs->define_ddc_registers(pin, en); + *pin = service->factory.funcs->get_ddc_pin(gpio); + service->factory.funcs->define_ddc_registers(*pin, en); break; case GPIO_ID_DDC_CLOCK: - pin = service->factory.funcs->create_ddc_clock( - service->ctx, id, en); - service->factory.funcs->define_ddc_registers(pin, en); + *pin = service->factory.funcs->get_ddc_pin(gpio); + service->factory.funcs->define_ddc_registers(*pin, en); break; case GPIO_ID_GENERIC: - pin = service->factory.funcs->create_generic( - service->ctx, id, en); - service->factory.funcs->define_generic_registers(pin, en); + *pin = service->factory.funcs->get_generic_pin(gpio); + service->factory.funcs->define_generic_registers(*pin, en); break; case GPIO_ID_HPD: - pin = service->factory.funcs->create_hpd( - service->ctx, id, en); - service->factory.funcs->define_hpd_registers(pin, en); + *pin = service->factory.funcs->get_hpd_pin(gpio); + service->factory.funcs->define_hpd_registers(*pin, en); break; + + //TODO: gsl and sync support? create_sync and create_gsl are NULL case GPIO_ID_SYNC: - pin = service->factory.funcs->create_sync( - service->ctx, id, en); - break; case GPIO_ID_GSL: - pin = service->factory.funcs->create_gsl( - service->ctx, id, en); break; default: ASSERT_CRITICAL(false); return GPIO_RESULT_NON_SPECIFIC_ERROR; } - if (!pin) { + if (!*pin) { ASSERT_CRITICAL(false); return GPIO_RESULT_NON_SPECIFIC_ERROR; } - if (!pin->funcs->open(pin, mode)) { + if (!(*pin)->funcs->open(*pin, mode)) { ASSERT_CRITICAL(false); - dal_gpio_service_close(service, &pin); + dal_gpio_service_close(service, pin); return GPIO_RESULT_OPEN_FAILED; } set_pin_busy(service, id, en); - *ptr = pin; return GPIO_RESULT_OK; } @@ -376,11 +370,10 @@ void dal_gpio_service_close( pin->funcs->close(pin); - pin->funcs->destroy(ptr); + *ptr = NULL; } } - enum dc_irq_source dal_irq_get_source( const struct gpio *irq) { |