diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3407-drm-amd-display-refactor-gpio-to-allocate-hw_contain.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3407-drm-amd-display-refactor-gpio-to-allocate-hw_contain.patch | 812 |
1 files changed, 812 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3407-drm-amd-display-refactor-gpio-to-allocate-hw_contain.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3407-drm-amd-display-refactor-gpio-to-allocate-hw_contain.patch new file mode 100644 index 00000000..dc20f736 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3407-drm-amd-display-refactor-gpio-to-allocate-hw_contain.patch @@ -0,0 +1,812 @@ +From c88c69c8487f0424fa6a08b35d3a92fa4b01cf91 Mon Sep 17 00:00:00 2001 +From: Su Sung Chung <Su.Chung@amd.com> +Date: Mon, 8 Jul 2019 11:31:39 -0400 +Subject: [PATCH 3407/4256] 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> +--- + .../dc/gpio/dce110/hw_factory_dce110.c | 18 +++-- + .../dc/gpio/dce120/hw_factory_dce120.c | 14 ++-- + .../display/dc/gpio/dce80/hw_factory_dce80.c | 14 ++-- + .../display/dc/gpio/dcn10/hw_factory_dcn10.c | 12 +-- + .../display/dc/gpio/dcn20/hw_factory_dcn20.c | 12 +-- + .../dc/gpio/diagnostics/hw_factory_diag.c | 9 +-- + .../gpu/drm/amd/display/dc/gpio/gpio_base.c | 74 ++++++++++++++++++- + .../drm/amd/display/dc/gpio/gpio_service.c | 51 ++++++------- + .../drm/amd/display/dc/gpio/gpio_service.h | 6 +- + drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c | 26 ++++--- + drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.h | 5 +- + .../gpu/drm/amd/display/dc/gpio/hw_factory.h | 48 ++++++------ + .../gpu/drm/amd/display/dc/gpio/hw_generic.c | 32 ++++---- + .../gpu/drm/amd/display/dc/gpio/hw_generic.h | 6 +- + drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.c | 31 ++++---- + drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.h | 5 +- + drivers/gpu/drm/amd/display/dc/inc/hw/gpio.h | 10 +++ + .../drm/amd/display/include/gpio_interface.h | 9 +++ + 18 files changed, 245 insertions(+), 137 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dce110/hw_factory_dce110.c b/drivers/gpu/drm/amd/display/dc/gpio/dce110/hw_factory_dce110.c +index 20d81bca119c..66e4841f41e4 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/dce110/hw_factory_dce110.c ++++ b/drivers/gpu/drm/amd/display/dc/gpio/dce110/hw_factory_dce110.c +@@ -24,9 +24,15 @@ + */ + + #include "dm_services.h" ++ + #include "include/gpio_types.h" + #include "../hw_factory.h" + ++#include "../hw_gpio.h" ++#include "../hw_ddc.h" ++#include "../hw_hpd.h" ++#include "../hw_generic.h" ++ + #include "hw_factory_dce110.h" + + #include "dce/dce_11_0_d.h" +@@ -143,12 +149,12 @@ static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en) + } + + static const struct hw_factory_funcs funcs = { +- .create_ddc_data = dal_hw_ddc_create, +- .create_ddc_clock = dal_hw_ddc_create, +- .create_generic = NULL, +- .create_hpd = dal_hw_hpd_create, +- .create_sync = NULL, +- .create_gsl = NULL, ++ .init_ddc_data = dal_hw_ddc_init, ++ .init_generic = NULL, ++ .init_hpd = dal_hw_hpd_init, ++ .get_ddc_pin = dal_hw_ddc_get_pin, ++ .get_hpd_pin = dal_hw_hpd_get_pin, ++ .get_generic_pin = NULL, + .define_hpd_registers = define_hpd_registers, + .define_ddc_registers = define_ddc_registers + }; +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_factory_dce120.c b/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_factory_dce120.c +index ea3f888e5c65..cf98aa827a9a 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_factory_dce120.c ++++ b/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_factory_dce120.c +@@ -27,10 +27,10 @@ + #include "include/gpio_types.h" + #include "../hw_factory.h" + +- + #include "../hw_gpio.h" + #include "../hw_ddc.h" + #include "../hw_hpd.h" ++#include "../hw_generic.h" + + #include "hw_factory_dce120.h" + +@@ -164,12 +164,12 @@ static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en) + + /* fucntion table */ + static const struct hw_factory_funcs funcs = { +- .create_ddc_data = dal_hw_ddc_create, +- .create_ddc_clock = dal_hw_ddc_create, +- .create_generic = NULL, +- .create_hpd = dal_hw_hpd_create, +- .create_sync = NULL, +- .create_gsl = NULL, ++ .init_ddc_data = dal_hw_ddc_init, ++ .init_generic = NULL, ++ .init_hpd = dal_hw_hpd_init, ++ .get_ddc_pin = dal_hw_ddc_get_pin, ++ .get_hpd_pin = dal_hw_hpd_get_pin, ++ .get_generic_pin = NULL, + .define_hpd_registers = define_hpd_registers, + .define_ddc_registers = define_ddc_registers + }; +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dce80/hw_factory_dce80.c b/drivers/gpu/drm/amd/display/dc/gpio/dce80/hw_factory_dce80.c +index 48b67866377e..496d3ffb74bb 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/dce80/hw_factory_dce80.c ++++ b/drivers/gpu/drm/amd/display/dc/gpio/dce80/hw_factory_dce80.c +@@ -32,10 +32,12 @@ + #include "../hw_gpio.h" + #include "../hw_ddc.h" + #include "../hw_hpd.h" ++#include "../hw_generic.h" + + #include "dce/dce_8_0_d.h" + #include "dce/dce_8_0_sh_mask.h" + ++ + #define REG(reg_name)\ + mm ## reg_name + +@@ -147,12 +149,12 @@ static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en) + } + + static const struct hw_factory_funcs funcs = { +- .create_ddc_data = dal_hw_ddc_create, +- .create_ddc_clock = dal_hw_ddc_create, +- .create_generic = NULL, +- .create_hpd = dal_hw_hpd_create, +- .create_sync = NULL, +- .create_gsl = NULL, ++ .init_ddc_data = dal_hw_ddc_init, ++ .init_generic = NULL, ++ .init_hpd = dal_hw_hpd_init, ++ .get_ddc_pin = dal_hw_ddc_get_pin, ++ .get_hpd_pin = dal_hw_hpd_get_pin, ++ .get_generic_pin = NULL, + .define_hpd_registers = define_hpd_registers, + .define_ddc_registers = define_ddc_registers + }; +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c +index 5711f30cf848..b38c96c9fed3 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c ++++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c +@@ -196,12 +196,12 @@ static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en) + + /* fucntion table */ + static const struct hw_factory_funcs funcs = { +- .create_ddc_data = dal_hw_ddc_create, +- .create_ddc_clock = dal_hw_ddc_create, +- .create_generic = dal_hw_generic_create, +- .create_hpd = dal_hw_hpd_create, +- .create_sync = NULL, +- .create_gsl = NULL, ++ .init_ddc_data = dal_hw_ddc_init, ++ .init_generic = dal_hw_generic_init, ++ .init_hpd = dal_hw_hpd_init, ++ .get_ddc_pin = dal_hw_ddc_get_pin, ++ .get_hpd_pin = dal_hw_hpd_get_pin, ++ .get_generic_pin = dal_hw_generic_get_pin, + .define_hpd_registers = define_hpd_registers, + .define_ddc_registers = define_ddc_registers, + .define_generic_registers = define_generic_registers +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c +index afb7c0f111bf..43a440385b43 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c ++++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c +@@ -212,12 +212,12 @@ static void define_generic_registers(struct hw_gpio_pin *pin, uint32_t en) + + /* fucntion table */ + static const struct hw_factory_funcs funcs = { +- .create_ddc_data = dal_hw_ddc_create, +- .create_ddc_clock = dal_hw_ddc_create, +- .create_generic = dal_hw_generic_create, +- .create_hpd = dal_hw_hpd_create, +- .create_sync = NULL, +- .create_gsl = NULL, ++ .init_ddc_data = dal_hw_ddc_init, ++ .init_generic = dal_hw_generic_init, ++ .init_hpd = dal_hw_hpd_init, ++ .get_ddc_pin = dal_hw_ddc_get_pin, ++ .get_hpd_pin = dal_hw_hpd_get_pin, ++ .get_generic_pin = dal_hw_generic_get_pin, + .define_hpd_registers = define_hpd_registers, + .define_ddc_registers = define_ddc_registers, + .define_generic_registers = define_generic_registers, +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c b/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c +index f15288c3986e..df68430aeb0c 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c ++++ b/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c +@@ -42,12 +42,9 @@ + + /* function table */ + static const struct hw_factory_funcs funcs = { +- .create_ddc_data = NULL, +- .create_ddc_clock = NULL, +- .create_generic = NULL, +- .create_hpd = NULL, +- .create_sync = NULL, +- .create_gsl = NULL, ++ .init_ddc_data = NULL, ++ .init_generic = NULL, ++ .init_hpd = NULL, + }; + + void dal_hw_factory_diag_fpga_init(struct hw_factory *factory) +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c +index cf76ea2d9f5a..c6f1a7c3affd 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c ++++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c +@@ -65,10 +65,14 @@ enum gpio_result dal_gpio_open_ex( + return GPIO_RESULT_ALREADY_OPENED; + } + ++ // No action if allocation failed during gpio construct ++ if (!gpio->hw_container.ddc) { ++ ASSERT_CRITICAL(false); ++ return GPIO_RESULT_NON_SPECIFIC_ERROR; ++ } + gpio->mode = mode; + +- return dal_gpio_service_open( +- gpio->service, gpio->id, gpio->en, mode, &gpio->pin); ++ return dal_gpio_service_open(gpio); + } + + enum gpio_result dal_gpio_get_value( +@@ -229,6 +233,21 @@ enum gpio_pin_output_state dal_gpio_get_output_state( + return gpio->output_state; + } + ++struct hw_ddc *dal_gpio_get_ddc(struct gpio *gpio) ++{ ++ return gpio->hw_container.ddc; ++} ++ ++struct hw_hpd *dal_gpio_get_hpd(struct gpio *gpio) ++{ ++ return gpio->hw_container.hpd; ++} ++ ++struct hw_generic *dal_gpio_get_generic(struct gpio *gpio) ++{ ++ return gpio->hw_container.generic; ++} ++ + void dal_gpio_close( + struct gpio *gpio) + { +@@ -265,6 +284,30 @@ struct gpio *dal_gpio_create( + gpio->mode = GPIO_MODE_UNKNOWN; + gpio->output_state = output_state; + ++ //initialize hw_container union based on id ++ switch (gpio->id) { ++ case GPIO_ID_DDC_DATA: ++ gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en); ++ break; ++ case GPIO_ID_DDC_CLOCK: ++ gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en); ++ break; ++ case GPIO_ID_GENERIC: ++ gpio->service->factory.funcs->init_generic(&gpio->hw_container.generic, service->ctx, id, en); ++ break; ++ case GPIO_ID_HPD: ++ gpio->service->factory.funcs->init_hpd(&gpio->hw_container.hpd, service->ctx, id, en); ++ break; ++ // TODO: currently gpio for sync and gsl does not get created, might need it later ++ case GPIO_ID_SYNC: ++ break; ++ case GPIO_ID_GSL: ++ break; ++ default: ++ ASSERT_CRITICAL(false); ++ gpio->pin = NULL; ++ } ++ + return gpio; + } + +@@ -278,6 +321,33 @@ void dal_gpio_destroy( + + dal_gpio_close(*gpio); + ++ switch ((*gpio)->id) { ++ case GPIO_ID_DDC_DATA: ++ kfree((*gpio)->hw_container.ddc); ++ (*gpio)->hw_container.ddc = NULL; ++ break; ++ case GPIO_ID_DDC_CLOCK: ++ //TODO: might want to change it to init_ddc_clock ++ kfree((*gpio)->hw_container.ddc); ++ (*gpio)->hw_container.ddc = NULL; ++ break; ++ case GPIO_ID_GENERIC: ++ kfree((*gpio)->hw_container.generic); ++ (*gpio)->hw_container.generic = NULL; ++ break; ++ case GPIO_ID_HPD: ++ kfree((*gpio)->hw_container.hpd); ++ (*gpio)->hw_container.hpd = NULL; ++ break; ++ // TODO: currently gpio for sync and gsl does not get created, might need it later ++ case GPIO_ID_SYNC: ++ break; ++ case GPIO_ID_GSL: ++ break; ++ default: ++ break; ++ } ++ + kfree(*gpio); + + *gpio = NULL; +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 80f938e68285..30028223f8bc 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c ++++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +@@ -288,13 +288,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); +@@ -308,51 +310,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; + } + +@@ -374,11 +368,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) + { +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.h b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.h +index 0c678af75331..b9775a131ecd 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.h ++++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.h +@@ -42,11 +42,7 @@ struct gpio_service { + }; + + 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); + + void dal_gpio_service_close( + struct gpio_service *service, +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c +index 49a99248e7f6..e1c84a2f7298 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c ++++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c +@@ -25,6 +25,7 @@ + + #include "dm_services.h" + ++#include "include/gpio_interface.h" + #include "include/gpio_types.h" + #include "hw_gpio.h" + #include "hw_ddc.h" +@@ -42,6 +43,8 @@ + #define REG(reg)\ + (ddc->regs->reg) + ++struct gpio; ++ + static void destruct( + struct hw_ddc *pin) + { +@@ -224,24 +227,29 @@ static void construct( + ddc->base.base.funcs = &funcs; + } + +-struct hw_gpio_pin *dal_hw_ddc_create( ++void dal_hw_ddc_init( ++ struct hw_ddc **hw_ddc, + struct dc_context *ctx, + enum gpio_id id, + uint32_t en) + { +- struct hw_ddc *pin; +- + if ((en < GPIO_DDC_LINE_MIN) || (en > GPIO_DDC_LINE_MAX)) { + ASSERT_CRITICAL(false); +- return NULL; ++ *hw_ddc = NULL; + } + +- pin = kzalloc(sizeof(struct hw_ddc), GFP_KERNEL); +- if (!pin) { ++ *hw_ddc = kzalloc(sizeof(struct hw_ddc), GFP_KERNEL); ++ if (!*hw_ddc) { + ASSERT_CRITICAL(false); +- return NULL; ++ return; + } + +- construct(pin, id, en, ctx); +- return &pin->base.base; ++ construct(*hw_ddc, id, en, ctx); ++} ++ ++struct hw_gpio_pin *dal_hw_ddc_get_pin(struct gpio *gpio) ++{ ++ struct hw_ddc *hw_ddc = dal_gpio_get_ddc(gpio); ++ ++ return &hw_ddc->base.base; + } +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.h b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.h +index 9690e2a885d7..cc30e65df431 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.h ++++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.h +@@ -38,9 +38,12 @@ struct hw_ddc { + #define HW_DDC_FROM_BASE(hw_gpio) \ + container_of((HW_GPIO_FROM_BASE(hw_gpio)), struct hw_ddc, base) + +-struct hw_gpio_pin *dal_hw_ddc_create( ++void dal_hw_ddc_init( ++ struct hw_ddc **hw_ddc, + struct dc_context *ctx, + enum gpio_id id, + uint32_t en); + ++struct hw_gpio_pin *dal_hw_ddc_get_pin(struct gpio *gpio); ++ + #endif +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.h b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.h +index 7017c9337348..e15b037f3bcd 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.h ++++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.h +@@ -28,35 +28,35 @@ + + struct hw_gpio_pin; + struct hw_hpd; ++struct hw_ddc; ++struct hw_generic; ++struct gpio; + + struct hw_factory { + uint32_t number_of_pins[GPIO_ID_COUNT]; + + const struct hw_factory_funcs { +- struct hw_gpio_pin *(*create_ddc_data)( +- struct dc_context *ctx, +- enum gpio_id id, +- uint32_t en); +- struct hw_gpio_pin *(*create_ddc_clock)( +- struct dc_context *ctx, +- enum gpio_id id, +- uint32_t en); +- struct hw_gpio_pin *(*create_generic)( +- struct dc_context *ctx, +- enum gpio_id id, +- uint32_t en); +- struct hw_gpio_pin *(*create_hpd)( +- struct dc_context *ctx, +- enum gpio_id id, +- uint32_t en); +- struct hw_gpio_pin *(*create_sync)( +- struct dc_context *ctx, +- enum gpio_id id, +- uint32_t en); +- struct hw_gpio_pin *(*create_gsl)( +- struct dc_context *ctx, +- enum gpio_id id, +- uint32_t en); ++ void (*init_ddc_data)( ++ struct hw_ddc **hw_ddc, ++ struct dc_context *ctx, ++ enum gpio_id id, ++ uint32_t en); ++ void (*init_generic)( ++ struct hw_generic **hw_generic, ++ struct dc_context *ctx, ++ enum gpio_id id, ++ uint32_t en); ++ void (*init_hpd)( ++ struct hw_hpd **hw_hpd, ++ struct dc_context *ctx, ++ enum gpio_id id, ++ uint32_t en); ++ struct hw_gpio_pin *(*get_hpd_pin)( ++ struct gpio *gpio); ++ struct hw_gpio_pin *(*get_ddc_pin)( ++ struct gpio *gpio); ++ struct hw_gpio_pin *(*get_generic_pin)( ++ struct gpio *gpio); + void (*define_hpd_registers)( + struct hw_gpio_pin *pin, + uint32_t en); +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c +index ea0a1fc8cf23..f039c5982ac8 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c ++++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c +@@ -25,6 +25,7 @@ + + #include "dm_services.h" + ++#include "include/gpio_interface.h" + #include "include/gpio_types.h" + #include "hw_gpio.h" + #include "hw_generic.h" +@@ -41,6 +42,8 @@ + #define REG(reg)\ + (generic->regs->reg) + ++struct gpio; ++ + static void dal_hw_generic_construct( + struct hw_generic *pin, + enum gpio_id id, +@@ -104,29 +107,30 @@ static void construct( + generic->base.base.funcs = &funcs; + } + +-struct hw_gpio_pin *dal_hw_generic_create( ++void dal_hw_generic_init( ++ struct hw_generic **hw_generic, + struct dc_context *ctx, + enum gpio_id id, + uint32_t en) + { +- struct hw_generic *generic; +- +- if (id != GPIO_ID_GENERIC) { ++ if ((en < GPIO_DDC_LINE_MIN) || (en > GPIO_DDC_LINE_MAX)) { + ASSERT_CRITICAL(false); +- return NULL; ++ *hw_generic = NULL; + } + +- if ((en < GPIO_GENERIC_MIN) || (en > GPIO_GENERIC_MAX)) { ++ *hw_generic = kzalloc(sizeof(struct hw_generic), GFP_KERNEL); ++ if (!*hw_generic) { + ASSERT_CRITICAL(false); +- return NULL; ++ return; + } + +- generic = kzalloc(sizeof(struct hw_generic), GFP_KERNEL); +- if (!generic) { +- ASSERT_CRITICAL(false); +- return NULL; +- } ++ construct(*hw_generic, id, en, ctx); ++} ++ ++ ++struct hw_gpio_pin *dal_hw_generic_get_pin(struct gpio *gpio) ++{ ++ struct hw_generic *hw_generic = dal_gpio_get_generic(gpio); + +- construct(generic, id, en, ctx); +- return &generic->base.base; ++ return &hw_generic->base.base; + } +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.h b/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.h +index 3ea1c13e3ea6..bd6ffeb5e9df 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.h ++++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.h +@@ -27,6 +27,7 @@ + #define __DAL_HW_generic_H__ + + #include "generic_regs.h" ++#include "hw_gpio.h" + + struct hw_generic { + struct hw_gpio base; +@@ -38,9 +39,12 @@ struct hw_generic { + #define HW_GENERIC_FROM_BASE(hw_gpio) \ + container_of((HW_GPIO_FROM_BASE(hw_gpio)), struct hw_generic, base) + +-struct hw_gpio_pin *dal_hw_generic_create( ++void dal_hw_generic_init( ++ struct hw_generic **hw_generic, + struct dc_context *ctx, + enum gpio_id id, + uint32_t en); + ++struct hw_gpio_pin *dal_hw_generic_get_pin(struct gpio *gpio); ++ + #endif +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.c +index 784feccc5853..88798cf3965e 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.c ++++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.c +@@ -25,6 +25,7 @@ + + #include "dm_services.h" + ++#include "include/gpio_interface.h" + #include "include/gpio_types.h" + #include "hw_gpio.h" + #include "hw_hpd.h" +@@ -41,6 +42,8 @@ + #define REG(reg)\ + (hpd->regs->reg) + ++struct gpio; ++ + static void dal_hw_hpd_construct( + struct hw_hpd *pin, + enum gpio_id id, +@@ -134,29 +137,29 @@ static void construct( + hpd->base.base.funcs = &funcs; + } + +-struct hw_gpio_pin *dal_hw_hpd_create( ++void dal_hw_hpd_init( ++ struct hw_hpd **hw_hpd, + struct dc_context *ctx, + enum gpio_id id, + uint32_t en) + { +- struct hw_hpd *hpd; +- +- if (id != GPIO_ID_HPD) { ++ if ((en < GPIO_DDC_LINE_MIN) || (en > GPIO_DDC_LINE_MAX)) { + ASSERT_CRITICAL(false); +- return NULL; ++ *hw_hpd = NULL; + } + +- if ((en < GPIO_HPD_MIN) || (en > GPIO_HPD_MAX)) { ++ *hw_hpd = kzalloc(sizeof(struct hw_hpd), GFP_KERNEL); ++ if (!*hw_hpd) { + ASSERT_CRITICAL(false); +- return NULL; ++ return; + } + +- hpd = kzalloc(sizeof(struct hw_hpd), GFP_KERNEL); +- if (!hpd) { +- ASSERT_CRITICAL(false); +- return NULL; +- } ++ construct(*hw_hpd, id, en, ctx); ++} ++ ++struct hw_gpio_pin *dal_hw_hpd_get_pin(struct gpio *gpio) ++{ ++ struct hw_hpd *hw_hpd = dal_gpio_get_hpd(gpio); + +- construct(hpd, id, en, ctx); +- return &hpd->base.base; ++ return &hw_hpd->base.base; + } +diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.h b/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.h +index 4ab7a208f781..e7d8b3bb016c 100644 +--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.h ++++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.h +@@ -38,9 +38,12 @@ struct hw_hpd { + #define HW_HPD_FROM_BASE(hw_gpio) \ + container_of((HW_GPIO_FROM_BASE(hw_gpio)), struct hw_hpd, base) + +-struct hw_gpio_pin *dal_hw_hpd_create( ++void dal_hw_hpd_init( ++ struct hw_hpd **hw_hpd, + struct dc_context *ctx, + enum gpio_id id, + uint32_t en); + ++struct hw_gpio_pin *dal_hw_hpd_get_pin(struct gpio *gpio); ++ + #endif +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/gpio.h b/drivers/gpu/drm/amd/display/dc/inc/hw/gpio.h +index 90d0148430fb..5253dc8b15f8 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw/gpio.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/gpio.h +@@ -28,12 +28,22 @@ + + #include "gpio_types.h" + ++ ++union gpio_hw_container { ++ struct hw_ddc *ddc; ++ struct hw_generic *generic; ++ struct hw_hpd *hpd; ++}; ++ + struct gpio { + struct gpio_service *service; + struct hw_gpio_pin *pin; + enum gpio_id id; + uint32_t en; ++ ++ union gpio_hw_container hw_container; + enum gpio_mode mode; ++ + /* when GPIO comes from VBIOS, it has defined output state */ + enum gpio_pin_output_state output_state; + }; +diff --git a/drivers/gpu/drm/amd/display/include/gpio_interface.h b/drivers/gpu/drm/amd/display/include/gpio_interface.h +index 7de64195dc33..5e888a093c16 100644 +--- a/drivers/gpu/drm/amd/display/include/gpio_interface.h ++++ b/drivers/gpu/drm/amd/display/include/gpio_interface.h +@@ -93,8 +93,17 @@ enum sync_source dal_gpio_get_sync_source( + enum gpio_pin_output_state dal_gpio_get_output_state( + const struct gpio *gpio); + ++struct hw_ddc *dal_gpio_get_ddc(struct gpio *gpio); ++ ++struct hw_hpd *dal_gpio_get_hpd(struct gpio *gpio); ++ ++struct hw_generic *dal_gpio_get_generic(struct gpio *gpio); ++ + /* Close the handle */ + void dal_gpio_close( + struct gpio *gpio); + ++ ++ ++ + #endif +-- +2.17.1 + |