Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Su Sung Chung and committed by
Alex Deucher
91db9311 37495fbd

+245 -137
+12 -6
drivers/gpu/drm/amd/display/dc/gpio/dce110/hw_factory_dce110.c
··· 24 24 */ 25 25 26 26 #include "dm_services.h" 27 + 27 28 #include "include/gpio_types.h" 28 29 #include "../hw_factory.h" 30 + 31 + #include "../hw_gpio.h" 32 + #include "../hw_ddc.h" 33 + #include "../hw_hpd.h" 34 + #include "../hw_generic.h" 29 35 30 36 #include "hw_factory_dce110.h" 31 37 ··· 149 143 } 150 144 151 145 static const struct hw_factory_funcs funcs = { 152 - .create_ddc_data = dal_hw_ddc_create, 153 - .create_ddc_clock = dal_hw_ddc_create, 154 - .create_generic = NULL, 155 - .create_hpd = dal_hw_hpd_create, 156 - .create_sync = NULL, 157 - .create_gsl = NULL, 146 + .init_ddc_data = dal_hw_ddc_init, 147 + .init_generic = NULL, 148 + .init_hpd = dal_hw_hpd_init, 149 + .get_ddc_pin = dal_hw_ddc_get_pin, 150 + .get_hpd_pin = dal_hw_hpd_get_pin, 151 + .get_generic_pin = NULL, 158 152 .define_hpd_registers = define_hpd_registers, 159 153 .define_ddc_registers = define_ddc_registers 160 154 };
+7 -7
drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_factory_dce120.c
··· 27 27 #include "include/gpio_types.h" 28 28 #include "../hw_factory.h" 29 29 30 - 31 30 #include "../hw_gpio.h" 32 31 #include "../hw_ddc.h" 33 32 #include "../hw_hpd.h" 33 + #include "../hw_generic.h" 34 34 35 35 #include "hw_factory_dce120.h" 36 36 ··· 164 164 165 165 /* fucntion table */ 166 166 static const struct hw_factory_funcs funcs = { 167 - .create_ddc_data = dal_hw_ddc_create, 168 - .create_ddc_clock = dal_hw_ddc_create, 169 - .create_generic = NULL, 170 - .create_hpd = dal_hw_hpd_create, 171 - .create_sync = NULL, 172 - .create_gsl = NULL, 167 + .init_ddc_data = dal_hw_ddc_init, 168 + .init_generic = NULL, 169 + .init_hpd = dal_hw_hpd_init, 170 + .get_ddc_pin = dal_hw_ddc_get_pin, 171 + .get_hpd_pin = dal_hw_hpd_get_pin, 172 + .get_generic_pin = NULL, 173 173 .define_hpd_registers = define_hpd_registers, 174 174 .define_ddc_registers = define_ddc_registers 175 175 };
+8 -6
drivers/gpu/drm/amd/display/dc/gpio/dce80/hw_factory_dce80.c
··· 32 32 #include "../hw_gpio.h" 33 33 #include "../hw_ddc.h" 34 34 #include "../hw_hpd.h" 35 + #include "../hw_generic.h" 35 36 36 37 #include "dce/dce_8_0_d.h" 37 38 #include "dce/dce_8_0_sh_mask.h" 39 + 38 40 39 41 #define REG(reg_name)\ 40 42 mm ## reg_name ··· 149 147 } 150 148 151 149 static const struct hw_factory_funcs funcs = { 152 - .create_ddc_data = dal_hw_ddc_create, 153 - .create_ddc_clock = dal_hw_ddc_create, 154 - .create_generic = NULL, 155 - .create_hpd = dal_hw_hpd_create, 156 - .create_sync = NULL, 157 - .create_gsl = NULL, 150 + .init_ddc_data = dal_hw_ddc_init, 151 + .init_generic = NULL, 152 + .init_hpd = dal_hw_hpd_init, 153 + .get_ddc_pin = dal_hw_ddc_get_pin, 154 + .get_hpd_pin = dal_hw_hpd_get_pin, 155 + .get_generic_pin = NULL, 158 156 .define_hpd_registers = define_hpd_registers, 159 157 .define_ddc_registers = define_ddc_registers 160 158 };
+6 -6
drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c
··· 196 196 197 197 /* fucntion table */ 198 198 static const struct hw_factory_funcs funcs = { 199 - .create_ddc_data = dal_hw_ddc_create, 200 - .create_ddc_clock = dal_hw_ddc_create, 201 - .create_generic = dal_hw_generic_create, 202 - .create_hpd = dal_hw_hpd_create, 203 - .create_sync = NULL, 204 - .create_gsl = NULL, 199 + .init_ddc_data = dal_hw_ddc_init, 200 + .init_generic = dal_hw_generic_init, 201 + .init_hpd = dal_hw_hpd_init, 202 + .get_ddc_pin = dal_hw_ddc_get_pin, 203 + .get_hpd_pin = dal_hw_hpd_get_pin, 204 + .get_generic_pin = dal_hw_generic_get_pin, 205 205 .define_hpd_registers = define_hpd_registers, 206 206 .define_ddc_registers = define_ddc_registers, 207 207 .define_generic_registers = define_generic_registers
+6 -6
drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c
··· 212 212 213 213 /* fucntion table */ 214 214 static const struct hw_factory_funcs funcs = { 215 - .create_ddc_data = dal_hw_ddc_create, 216 - .create_ddc_clock = dal_hw_ddc_create, 217 - .create_generic = dal_hw_generic_create, 218 - .create_hpd = dal_hw_hpd_create, 219 - .create_sync = NULL, 220 - .create_gsl = NULL, 215 + .init_ddc_data = dal_hw_ddc_init, 216 + .init_generic = dal_hw_generic_init, 217 + .init_hpd = dal_hw_hpd_init, 218 + .get_ddc_pin = dal_hw_ddc_get_pin, 219 + .get_hpd_pin = dal_hw_hpd_get_pin, 220 + .get_generic_pin = dal_hw_generic_get_pin, 221 221 .define_hpd_registers = define_hpd_registers, 222 222 .define_ddc_registers = define_ddc_registers, 223 223 .define_generic_registers = define_generic_registers,
+3 -6
drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c
··· 42 42 43 43 /* function table */ 44 44 static const struct hw_factory_funcs funcs = { 45 - .create_ddc_data = NULL, 46 - .create_ddc_clock = NULL, 47 - .create_generic = NULL, 48 - .create_hpd = NULL, 49 - .create_sync = NULL, 50 - .create_gsl = NULL, 45 + .init_ddc_data = NULL, 46 + .init_generic = NULL, 47 + .init_hpd = NULL, 51 48 }; 52 49 53 50 void dal_hw_factory_diag_fpga_init(struct hw_factory *factory)
+72 -2
drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c
··· 67 67 return GPIO_RESULT_ALREADY_OPENED; 68 68 } 69 69 70 + // No action if allocation failed during gpio construct 71 + if (!gpio->hw_container.ddc) { 72 + ASSERT_CRITICAL(false); 73 + return GPIO_RESULT_NON_SPECIFIC_ERROR; 74 + } 70 75 gpio->mode = mode; 71 76 72 - return dal_gpio_service_open( 73 - gpio->service, gpio->id, gpio->en, mode, &gpio->pin); 77 + return dal_gpio_service_open(gpio); 74 78 } 75 79 76 80 enum gpio_result dal_gpio_get_value( ··· 235 231 return gpio->output_state; 236 232 } 237 233 234 + struct hw_ddc *dal_gpio_get_ddc(struct gpio *gpio) 235 + { 236 + return gpio->hw_container.ddc; 237 + } 238 + 239 + struct hw_hpd *dal_gpio_get_hpd(struct gpio *gpio) 240 + { 241 + return gpio->hw_container.hpd; 242 + } 243 + 244 + struct hw_generic *dal_gpio_get_generic(struct gpio *gpio) 245 + { 246 + return gpio->hw_container.generic; 247 + } 248 + 238 249 void dal_gpio_close( 239 250 struct gpio *gpio) 240 251 { ··· 286 267 gpio->mode = GPIO_MODE_UNKNOWN; 287 268 gpio->output_state = output_state; 288 269 270 + //initialize hw_container union based on id 271 + switch (gpio->id) { 272 + case GPIO_ID_DDC_DATA: 273 + gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en); 274 + break; 275 + case GPIO_ID_DDC_CLOCK: 276 + gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en); 277 + break; 278 + case GPIO_ID_GENERIC: 279 + gpio->service->factory.funcs->init_generic(&gpio->hw_container.generic, service->ctx, id, en); 280 + break; 281 + case GPIO_ID_HPD: 282 + gpio->service->factory.funcs->init_hpd(&gpio->hw_container.hpd, service->ctx, id, en); 283 + break; 284 + // TODO: currently gpio for sync and gsl does not get created, might need it later 285 + case GPIO_ID_SYNC: 286 + break; 287 + case GPIO_ID_GSL: 288 + break; 289 + default: 290 + ASSERT_CRITICAL(false); 291 + gpio->pin = NULL; 292 + } 293 + 289 294 return gpio; 290 295 } 291 296 ··· 322 279 } 323 280 324 281 dal_gpio_close(*gpio); 282 + 283 + switch ((*gpio)->id) { 284 + case GPIO_ID_DDC_DATA: 285 + kfree((*gpio)->hw_container.ddc); 286 + (*gpio)->hw_container.ddc = NULL; 287 + break; 288 + case GPIO_ID_DDC_CLOCK: 289 + //TODO: might want to change it to init_ddc_clock 290 + kfree((*gpio)->hw_container.ddc); 291 + (*gpio)->hw_container.ddc = NULL; 292 + break; 293 + case GPIO_ID_GENERIC: 294 + kfree((*gpio)->hw_container.generic); 295 + (*gpio)->hw_container.generic = NULL; 296 + break; 297 + case GPIO_ID_HPD: 298 + kfree((*gpio)->hw_container.hpd); 299 + (*gpio)->hw_container.hpd = NULL; 300 + break; 301 + // TODO: currently gpio for sync and gsl does not get created, might need it later 302 + case GPIO_ID_SYNC: 303 + break; 304 + case GPIO_ID_GSL: 305 + break; 306 + default: 307 + break; 308 + } 325 309 326 310 kfree(*gpio); 327 311
+22 -29
drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
··· 290 290 } 291 291 292 292 enum gpio_result dal_gpio_service_open( 293 - struct gpio_service *service, 294 - enum gpio_id id, 295 - uint32_t en, 296 - enum gpio_mode mode, 297 - struct hw_gpio_pin **ptr) 293 + struct gpio *gpio) 298 294 { 299 - struct hw_gpio_pin *pin; 295 + struct gpio_service *service = gpio->service; 296 + enum gpio_id id = gpio->id; 297 + uint32_t en = gpio->en; 298 + enum gpio_mode mode = gpio->mode; 299 + 300 + struct hw_gpio_pin **pin = &gpio->pin; 301 + 300 302 301 303 if (!service->busyness[id]) { 302 304 ASSERT_CRITICAL(false); ··· 312 310 313 311 switch (id) { 314 312 case GPIO_ID_DDC_DATA: 315 - pin = service->factory.funcs->create_ddc_data( 316 - service->ctx, id, en); 317 - service->factory.funcs->define_ddc_registers(pin, en); 313 + *pin = service->factory.funcs->get_ddc_pin(gpio); 314 + service->factory.funcs->define_ddc_registers(*pin, en); 318 315 break; 319 316 case GPIO_ID_DDC_CLOCK: 320 - pin = service->factory.funcs->create_ddc_clock( 321 - service->ctx, id, en); 322 - service->factory.funcs->define_ddc_registers(pin, en); 317 + *pin = service->factory.funcs->get_ddc_pin(gpio); 318 + service->factory.funcs->define_ddc_registers(*pin, en); 323 319 break; 324 320 case GPIO_ID_GENERIC: 325 - pin = service->factory.funcs->create_generic( 326 - service->ctx, id, en); 327 - service->factory.funcs->define_generic_registers(pin, en); 321 + *pin = service->factory.funcs->get_generic_pin(gpio); 322 + service->factory.funcs->define_generic_registers(*pin, en); 328 323 break; 329 324 case GPIO_ID_HPD: 330 - pin = service->factory.funcs->create_hpd( 331 - service->ctx, id, en); 332 - service->factory.funcs->define_hpd_registers(pin, en); 325 + *pin = service->factory.funcs->get_hpd_pin(gpio); 326 + service->factory.funcs->define_hpd_registers(*pin, en); 333 327 break; 328 + 329 + //TODO: gsl and sync support? create_sync and create_gsl are NULL 334 330 case GPIO_ID_SYNC: 335 - pin = service->factory.funcs->create_sync( 336 - service->ctx, id, en); 337 - break; 338 331 case GPIO_ID_GSL: 339 - pin = service->factory.funcs->create_gsl( 340 - service->ctx, id, en); 341 332 break; 342 333 default: 343 334 ASSERT_CRITICAL(false); 344 335 return GPIO_RESULT_NON_SPECIFIC_ERROR; 345 336 } 346 337 347 - if (!pin) { 338 + if (!*pin) { 348 339 ASSERT_CRITICAL(false); 349 340 return GPIO_RESULT_NON_SPECIFIC_ERROR; 350 341 } 351 342 352 - if (!pin->funcs->open(pin, mode)) { 343 + if (!(*pin)->funcs->open(*pin, mode)) { 353 344 ASSERT_CRITICAL(false); 354 - dal_gpio_service_close(service, &pin); 345 + dal_gpio_service_close(service, pin); 355 346 return GPIO_RESULT_OPEN_FAILED; 356 347 } 357 348 358 349 set_pin_busy(service, id, en); 359 - *ptr = pin; 360 350 return GPIO_RESULT_OK; 361 351 } 362 352 ··· 370 376 371 377 pin->funcs->close(pin); 372 378 373 - pin->funcs->destroy(ptr); 379 + *ptr = NULL; 374 380 } 375 381 } 376 - 377 382 378 383 enum dc_irq_source dal_irq_get_source( 379 384 const struct gpio *irq)
+1 -5
drivers/gpu/drm/amd/display/dc/gpio/gpio_service.h
··· 42 42 }; 43 43 44 44 enum gpio_result dal_gpio_service_open( 45 - struct gpio_service *service, 46 - enum gpio_id id, 47 - uint32_t en, 48 - enum gpio_mode mode, 49 - struct hw_gpio_pin **ptr); 45 + struct gpio *gpio); 50 46 51 47 void dal_gpio_service_close( 52 48 struct gpio_service *service,
+17 -9
drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c
··· 28 28 29 29 #include "dm_services.h" 30 30 31 + #include "include/gpio_interface.h" 31 32 #include "include/gpio_types.h" 32 33 #include "hw_gpio.h" 33 34 #include "hw_ddc.h" ··· 45 44 ddc->base.base.ctx 46 45 #define REG(reg)\ 47 46 (ddc->regs->reg) 47 + 48 + struct gpio; 48 49 49 50 static void destruct( 50 51 struct hw_ddc *pin) ··· 230 227 ddc->base.base.funcs = &funcs; 231 228 } 232 229 233 - struct hw_gpio_pin *dal_hw_ddc_create( 230 + void dal_hw_ddc_init( 231 + struct hw_ddc **hw_ddc, 234 232 struct dc_context *ctx, 235 233 enum gpio_id id, 236 234 uint32_t en) 237 235 { 238 - struct hw_ddc *pin; 239 - 240 236 if ((en < GPIO_DDC_LINE_MIN) || (en > GPIO_DDC_LINE_MAX)) { 241 237 ASSERT_CRITICAL(false); 242 - return NULL; 238 + *hw_ddc = NULL; 243 239 } 244 240 245 - pin = kzalloc(sizeof(struct hw_ddc), GFP_KERNEL); 246 - if (!pin) { 241 + *hw_ddc = kzalloc(sizeof(struct hw_ddc), GFP_KERNEL); 242 + if (!*hw_ddc) { 247 243 ASSERT_CRITICAL(false); 248 - return NULL; 244 + return; 249 245 } 250 246 251 - construct(pin, id, en, ctx); 252 - return &pin->base.base; 247 + construct(*hw_ddc, id, en, ctx); 248 + } 249 + 250 + struct hw_gpio_pin *dal_hw_ddc_get_pin(struct gpio *gpio) 251 + { 252 + struct hw_ddc *hw_ddc = dal_gpio_get_ddc(gpio); 253 + 254 + return &hw_ddc->base.base; 253 255 }
+4 -1
drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.h
··· 38 38 #define HW_DDC_FROM_BASE(hw_gpio) \ 39 39 container_of((HW_GPIO_FROM_BASE(hw_gpio)), struct hw_ddc, base) 40 40 41 - struct hw_gpio_pin *dal_hw_ddc_create( 41 + void dal_hw_ddc_init( 42 + struct hw_ddc **hw_ddc, 42 43 struct dc_context *ctx, 43 44 enum gpio_id id, 44 45 uint32_t en); 46 + 47 + struct hw_gpio_pin *dal_hw_ddc_get_pin(struct gpio *gpio); 45 48 46 49 #endif
+24 -24
drivers/gpu/drm/amd/display/dc/gpio/hw_factory.h
··· 28 28 29 29 struct hw_gpio_pin; 30 30 struct hw_hpd; 31 + struct hw_ddc; 32 + struct hw_generic; 33 + struct gpio; 31 34 32 35 struct hw_factory { 33 36 uint32_t number_of_pins[GPIO_ID_COUNT]; 34 37 35 38 const struct hw_factory_funcs { 36 - struct hw_gpio_pin *(*create_ddc_data)( 37 - struct dc_context *ctx, 38 - enum gpio_id id, 39 - uint32_t en); 40 - struct hw_gpio_pin *(*create_ddc_clock)( 41 - struct dc_context *ctx, 42 - enum gpio_id id, 43 - uint32_t en); 44 - struct hw_gpio_pin *(*create_generic)( 45 - struct dc_context *ctx, 46 - enum gpio_id id, 47 - uint32_t en); 48 - struct hw_gpio_pin *(*create_hpd)( 49 - struct dc_context *ctx, 50 - enum gpio_id id, 51 - uint32_t en); 52 - struct hw_gpio_pin *(*create_sync)( 53 - struct dc_context *ctx, 54 - enum gpio_id id, 55 - uint32_t en); 56 - struct hw_gpio_pin *(*create_gsl)( 57 - struct dc_context *ctx, 58 - enum gpio_id id, 59 - uint32_t en); 39 + void (*init_ddc_data)( 40 + struct hw_ddc **hw_ddc, 41 + struct dc_context *ctx, 42 + enum gpio_id id, 43 + uint32_t en); 44 + void (*init_generic)( 45 + struct hw_generic **hw_generic, 46 + struct dc_context *ctx, 47 + enum gpio_id id, 48 + uint32_t en); 49 + void (*init_hpd)( 50 + struct hw_hpd **hw_hpd, 51 + struct dc_context *ctx, 52 + enum gpio_id id, 53 + uint32_t en); 54 + struct hw_gpio_pin *(*get_hpd_pin)( 55 + struct gpio *gpio); 56 + struct hw_gpio_pin *(*get_ddc_pin)( 57 + struct gpio *gpio); 58 + struct hw_gpio_pin *(*get_generic_pin)( 59 + struct gpio *gpio); 60 60 void (*define_hpd_registers)( 61 61 struct hw_gpio_pin *pin, 62 62 uint32_t en);
+18 -14
drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c
··· 27 27 28 28 #include "dm_services.h" 29 29 30 + #include "include/gpio_interface.h" 30 31 #include "include/gpio_types.h" 31 32 #include "hw_gpio.h" 32 33 #include "hw_generic.h" ··· 43 42 generic->base.base.ctx 44 43 #define REG(reg)\ 45 44 (generic->regs->reg) 45 + 46 + struct gpio; 46 47 47 48 static void dal_hw_generic_construct( 48 49 struct hw_generic *pin, ··· 109 106 generic->base.base.funcs = &funcs; 110 107 } 111 108 112 - struct hw_gpio_pin *dal_hw_generic_create( 109 + void dal_hw_generic_init( 110 + struct hw_generic **hw_generic, 113 111 struct dc_context *ctx, 114 112 enum gpio_id id, 115 113 uint32_t en) 116 114 { 117 - struct hw_generic *generic; 118 - 119 - if (id != GPIO_ID_GENERIC) { 115 + if ((en < GPIO_DDC_LINE_MIN) || (en > GPIO_DDC_LINE_MAX)) { 120 116 ASSERT_CRITICAL(false); 121 - return NULL; 117 + *hw_generic = NULL; 122 118 } 123 119 124 - if ((en < GPIO_GENERIC_MIN) || (en > GPIO_GENERIC_MAX)) { 120 + *hw_generic = kzalloc(sizeof(struct hw_generic), GFP_KERNEL); 121 + if (!*hw_generic) { 125 122 ASSERT_CRITICAL(false); 126 - return NULL; 123 + return; 127 124 } 128 125 129 - generic = kzalloc(sizeof(struct hw_generic), GFP_KERNEL); 130 - if (!generic) { 131 - ASSERT_CRITICAL(false); 132 - return NULL; 133 - } 126 + construct(*hw_generic, id, en, ctx); 127 + } 134 128 135 - construct(generic, id, en, ctx); 136 - return &generic->base.base; 129 + 130 + struct hw_gpio_pin *dal_hw_generic_get_pin(struct gpio *gpio) 131 + { 132 + struct hw_generic *hw_generic = dal_gpio_get_generic(gpio); 133 + 134 + return &hw_generic->base.base; 137 135 }
+5 -1
drivers/gpu/drm/amd/display/dc/gpio/hw_generic.h
··· 27 27 #define __DAL_HW_generic_H__ 28 28 29 29 #include "generic_regs.h" 30 + #include "hw_gpio.h" 30 31 31 32 struct hw_generic { 32 33 struct hw_gpio base; ··· 39 38 #define HW_GENERIC_FROM_BASE(hw_gpio) \ 40 39 container_of((HW_GPIO_FROM_BASE(hw_gpio)), struct hw_generic, base) 41 40 42 - struct hw_gpio_pin *dal_hw_generic_create( 41 + void dal_hw_generic_init( 42 + struct hw_generic **hw_generic, 43 43 struct dc_context *ctx, 44 44 enum gpio_id id, 45 45 uint32_t en); 46 + 47 + struct hw_gpio_pin *dal_hw_generic_get_pin(struct gpio *gpio); 46 48 47 49 #endif
+17 -14
drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.c
··· 27 27 28 28 #include "dm_services.h" 29 29 30 + #include "include/gpio_interface.h" 30 31 #include "include/gpio_types.h" 31 32 #include "hw_gpio.h" 32 33 #include "hw_hpd.h" ··· 43 42 hpd->base.base.ctx 44 43 #define REG(reg)\ 45 44 (hpd->regs->reg) 45 + 46 + struct gpio; 46 47 47 48 static void dal_hw_hpd_construct( 48 49 struct hw_hpd *pin, ··· 139 136 hpd->base.base.funcs = &funcs; 140 137 } 141 138 142 - struct hw_gpio_pin *dal_hw_hpd_create( 139 + void dal_hw_hpd_init( 140 + struct hw_hpd **hw_hpd, 143 141 struct dc_context *ctx, 144 142 enum gpio_id id, 145 143 uint32_t en) 146 144 { 147 - struct hw_hpd *hpd; 148 - 149 - if (id != GPIO_ID_HPD) { 145 + if ((en < GPIO_DDC_LINE_MIN) || (en > GPIO_DDC_LINE_MAX)) { 150 146 ASSERT_CRITICAL(false); 151 - return NULL; 147 + *hw_hpd = NULL; 152 148 } 153 149 154 - if ((en < GPIO_HPD_MIN) || (en > GPIO_HPD_MAX)) { 150 + *hw_hpd = kzalloc(sizeof(struct hw_hpd), GFP_KERNEL); 151 + if (!*hw_hpd) { 155 152 ASSERT_CRITICAL(false); 156 - return NULL; 153 + return; 157 154 } 158 155 159 - hpd = kzalloc(sizeof(struct hw_hpd), GFP_KERNEL); 160 - if (!hpd) { 161 - ASSERT_CRITICAL(false); 162 - return NULL; 163 - } 156 + construct(*hw_hpd, id, en, ctx); 157 + } 164 158 165 - construct(hpd, id, en, ctx); 166 - return &hpd->base.base; 159 + struct hw_gpio_pin *dal_hw_hpd_get_pin(struct gpio *gpio) 160 + { 161 + struct hw_hpd *hw_hpd = dal_gpio_get_hpd(gpio); 162 + 163 + return &hw_hpd->base.base; 167 164 }
+4 -1
drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.h
··· 38 38 #define HW_HPD_FROM_BASE(hw_gpio) \ 39 39 container_of((HW_GPIO_FROM_BASE(hw_gpio)), struct hw_hpd, base) 40 40 41 - struct hw_gpio_pin *dal_hw_hpd_create( 41 + void dal_hw_hpd_init( 42 + struct hw_hpd **hw_hpd, 42 43 struct dc_context *ctx, 43 44 enum gpio_id id, 44 45 uint32_t en); 46 + 47 + struct hw_gpio_pin *dal_hw_hpd_get_pin(struct gpio *gpio); 45 48 46 49 #endif
+10
drivers/gpu/drm/amd/display/dc/inc/hw/gpio.h
··· 28 28 29 29 #include "gpio_types.h" 30 30 31 + 32 + union gpio_hw_container { 33 + struct hw_ddc *ddc; 34 + struct hw_generic *generic; 35 + struct hw_hpd *hpd; 36 + }; 37 + 31 38 struct gpio { 32 39 struct gpio_service *service; 33 40 struct hw_gpio_pin *pin; 34 41 enum gpio_id id; 35 42 uint32_t en; 43 + 44 + union gpio_hw_container hw_container; 36 45 enum gpio_mode mode; 46 + 37 47 /* when GPIO comes from VBIOS, it has defined output state */ 38 48 enum gpio_pin_output_state output_state; 39 49 };
+9
drivers/gpu/drm/amd/display/include/gpio_interface.h
··· 93 93 enum gpio_pin_output_state dal_gpio_get_output_state( 94 94 const struct gpio *gpio); 95 95 96 + struct hw_ddc *dal_gpio_get_ddc(struct gpio *gpio); 97 + 98 + struct hw_hpd *dal_gpio_get_hpd(struct gpio *gpio); 99 + 100 + struct hw_generic *dal_gpio_get_generic(struct gpio *gpio); 101 + 96 102 /* Close the handle */ 97 103 void dal_gpio_close( 98 104 struct gpio *gpio); 105 + 106 + 107 + 99 108 100 109 #endif