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

drm/dp: Move panel DP AUX backlight support to drm_dp_helper

We were getting a depmod error:
depmod: ERROR: Cycle detected: drm_kms_helper -> drm -> drm_kms_helper

It looks like the rule is that drm_kms_helper can call into drm, but
drm can't call into drm_kms_helper. That means we've got to move the
DP AUX backlight support into drm_dp_helper.

NOTE: as part of this, I didn't try to do any renames of the main
registration function. Even though it's in the drm_dp_helper, it still
feels very parallel to drm_panel_of_backlight().

Fixes: 10f7b40e4f30 ("drm/panel: add basic DP AUX backlight support")
Reported-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reported-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Rajeev Nandan <rajeevny@codeaurora.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20210712075933.v2.1.I23eb4cc5a680341e7b3e791632a635566fa5806a@changeid

+129 -116
+113
drivers/gpu/drm/drm_dp_helper.c
··· 33 33 #include <drm/drm_print.h> 34 34 #include <drm/drm_vblank.h> 35 35 #include <drm/drm_dp_mst_helper.h> 36 + #include <drm/drm_panel.h> 36 37 37 38 #include "drm_crtc_helper_internal.h" 39 + 40 + struct dp_aux_backlight { 41 + struct backlight_device *base; 42 + struct drm_dp_aux *aux; 43 + struct drm_edp_backlight_info info; 44 + bool enabled; 45 + }; 38 46 39 47 /** 40 48 * DOC: dp helpers ··· 3470 3462 return 0; 3471 3463 } 3472 3464 EXPORT_SYMBOL(drm_edp_backlight_init); 3465 + 3466 + #if IS_BUILTIN(CONFIG_BACKLIGHT_CLASS_DEVICE) || \ 3467 + (IS_MODULE(CONFIG_DRM_KMS_HELPER) && IS_MODULE(CONFIG_BACKLIGHT_CLASS_DEVICE)) 3468 + 3469 + static int dp_aux_backlight_update_status(struct backlight_device *bd) 3470 + { 3471 + struct dp_aux_backlight *bl = bl_get_data(bd); 3472 + u16 brightness = backlight_get_brightness(bd); 3473 + int ret = 0; 3474 + 3475 + if (!backlight_is_blank(bd)) { 3476 + if (!bl->enabled) { 3477 + drm_edp_backlight_enable(bl->aux, &bl->info, brightness); 3478 + bl->enabled = true; 3479 + return 0; 3480 + } 3481 + ret = drm_edp_backlight_set_level(bl->aux, &bl->info, brightness); 3482 + } else { 3483 + if (bl->enabled) { 3484 + drm_edp_backlight_disable(bl->aux, &bl->info); 3485 + bl->enabled = false; 3486 + } 3487 + } 3488 + 3489 + return ret; 3490 + } 3491 + 3492 + static const struct backlight_ops dp_aux_bl_ops = { 3493 + .update_status = dp_aux_backlight_update_status, 3494 + }; 3495 + 3496 + /** 3497 + * drm_panel_dp_aux_backlight - create and use DP AUX backlight 3498 + * @panel: DRM panel 3499 + * @aux: The DP AUX channel to use 3500 + * 3501 + * Use this function to create and handle backlight if your panel 3502 + * supports backlight control over DP AUX channel using DPCD 3503 + * registers as per VESA's standard backlight control interface. 3504 + * 3505 + * When the panel is enabled backlight will be enabled after a 3506 + * successful call to &drm_panel_funcs.enable() 3507 + * 3508 + * When the panel is disabled backlight will be disabled before the 3509 + * call to &drm_panel_funcs.disable(). 3510 + * 3511 + * A typical implementation for a panel driver supporting backlight 3512 + * control over DP AUX will call this function at probe time. 3513 + * Backlight will then be handled transparently without requiring 3514 + * any intervention from the driver. 3515 + * 3516 + * drm_panel_dp_aux_backlight() must be called after the call to drm_panel_init(). 3517 + * 3518 + * Return: 0 on success or a negative error code on failure. 3519 + */ 3520 + int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux) 3521 + { 3522 + struct dp_aux_backlight *bl; 3523 + struct backlight_properties props = { 0 }; 3524 + u16 current_level; 3525 + u8 current_mode; 3526 + u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]; 3527 + int ret; 3528 + 3529 + if (!panel || !panel->dev || !aux) 3530 + return -EINVAL; 3531 + 3532 + ret = drm_dp_dpcd_read(aux, DP_EDP_DPCD_REV, edp_dpcd, 3533 + EDP_DISPLAY_CTL_CAP_SIZE); 3534 + if (ret < 0) 3535 + return ret; 3536 + 3537 + if (!drm_edp_backlight_supported(edp_dpcd)) { 3538 + DRM_DEV_INFO(panel->dev, "DP AUX backlight is not supported\n"); 3539 + return 0; 3540 + } 3541 + 3542 + bl = devm_kzalloc(panel->dev, sizeof(*bl), GFP_KERNEL); 3543 + if (!bl) 3544 + return -ENOMEM; 3545 + 3546 + bl->aux = aux; 3547 + 3548 + ret = drm_edp_backlight_init(aux, &bl->info, 0, edp_dpcd, 3549 + &current_level, &current_mode); 3550 + if (ret < 0) 3551 + return ret; 3552 + 3553 + props.type = BACKLIGHT_RAW; 3554 + props.brightness = current_level; 3555 + props.max_brightness = bl->info.max; 3556 + 3557 + bl->base = devm_backlight_device_register(panel->dev, "dp_aux_backlight", 3558 + panel->dev, bl, 3559 + &dp_aux_bl_ops, &props); 3560 + if (IS_ERR(bl->base)) 3561 + return PTR_ERR(bl->base); 3562 + 3563 + panel->backlight = bl->base; 3564 + 3565 + return 0; 3566 + } 3567 + EXPORT_SYMBOL(drm_panel_dp_aux_backlight); 3568 + 3569 + #endif
-108
drivers/gpu/drm/drm_panel.c
··· 26 26 #include <linux/module.h> 27 27 28 28 #include <drm/drm_crtc.h> 29 - #include <drm/drm_dp_helper.h> 30 29 #include <drm/drm_panel.h> 31 30 #include <drm/drm_print.h> 32 31 33 32 static DEFINE_MUTEX(panel_lock); 34 33 static LIST_HEAD(panel_list); 35 - 36 - struct dp_aux_backlight { 37 - struct backlight_device *base; 38 - struct drm_dp_aux *aux; 39 - struct drm_edp_backlight_info info; 40 - bool enabled; 41 - }; 42 34 43 35 /** 44 36 * DOC: drm panel ··· 342 350 return 0; 343 351 } 344 352 EXPORT_SYMBOL(drm_panel_of_backlight); 345 - 346 - static int dp_aux_backlight_update_status(struct backlight_device *bd) 347 - { 348 - struct dp_aux_backlight *bl = bl_get_data(bd); 349 - u16 brightness = backlight_get_brightness(bd); 350 - int ret = 0; 351 - 352 - if (!backlight_is_blank(bd)) { 353 - if (!bl->enabled) { 354 - drm_edp_backlight_enable(bl->aux, &bl->info, brightness); 355 - bl->enabled = true; 356 - return 0; 357 - } 358 - ret = drm_edp_backlight_set_level(bl->aux, &bl->info, brightness); 359 - } else { 360 - if (bl->enabled) { 361 - drm_edp_backlight_disable(bl->aux, &bl->info); 362 - bl->enabled = false; 363 - } 364 - } 365 - 366 - return ret; 367 - } 368 - 369 - static const struct backlight_ops dp_aux_bl_ops = { 370 - .update_status = dp_aux_backlight_update_status, 371 - }; 372 - 373 - /** 374 - * drm_panel_dp_aux_backlight - create and use DP AUX backlight 375 - * @panel: DRM panel 376 - * @aux: The DP AUX channel to use 377 - * 378 - * Use this function to create and handle backlight if your panel 379 - * supports backlight control over DP AUX channel using DPCD 380 - * registers as per VESA's standard backlight control interface. 381 - * 382 - * When the panel is enabled backlight will be enabled after a 383 - * successful call to &drm_panel_funcs.enable() 384 - * 385 - * When the panel is disabled backlight will be disabled before the 386 - * call to &drm_panel_funcs.disable(). 387 - * 388 - * A typical implementation for a panel driver supporting backlight 389 - * control over DP AUX will call this function at probe time. 390 - * Backlight will then be handled transparently without requiring 391 - * any intervention from the driver. 392 - * 393 - * drm_panel_dp_aux_backlight() must be called after the call to drm_panel_init(). 394 - * 395 - * Return: 0 on success or a negative error code on failure. 396 - */ 397 - int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux) 398 - { 399 - struct dp_aux_backlight *bl; 400 - struct backlight_properties props = { 0 }; 401 - u16 current_level; 402 - u8 current_mode; 403 - u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]; 404 - int ret; 405 - 406 - if (!panel || !panel->dev || !aux) 407 - return -EINVAL; 408 - 409 - ret = drm_dp_dpcd_read(aux, DP_EDP_DPCD_REV, edp_dpcd, 410 - EDP_DISPLAY_CTL_CAP_SIZE); 411 - if (ret < 0) 412 - return ret; 413 - 414 - if (!drm_edp_backlight_supported(edp_dpcd)) { 415 - DRM_DEV_INFO(panel->dev, "DP AUX backlight is not supported\n"); 416 - return 0; 417 - } 418 - 419 - bl = devm_kzalloc(panel->dev, sizeof(*bl), GFP_KERNEL); 420 - if (!bl) 421 - return -ENOMEM; 422 - 423 - bl->aux = aux; 424 - 425 - ret = drm_edp_backlight_init(aux, &bl->info, 0, edp_dpcd, 426 - &current_level, &current_mode); 427 - if (ret < 0) 428 - return ret; 429 - 430 - props.type = BACKLIGHT_RAW; 431 - props.brightness = current_level; 432 - props.max_brightness = bl->info.max; 433 - 434 - bl->base = devm_backlight_device_register(panel->dev, "dp_aux_backlight", 435 - panel->dev, bl, 436 - &dp_aux_bl_ops, &props); 437 - if (IS_ERR(bl->base)) 438 - return PTR_ERR(bl->base); 439 - 440 - panel->backlight = bl->base; 441 - 442 - return 0; 443 - } 444 - EXPORT_SYMBOL(drm_panel_dp_aux_backlight); 445 353 #endif 446 354 447 355 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
+16
include/drm/drm_dp_helper.h
··· 30 30 31 31 struct drm_device; 32 32 struct drm_dp_aux; 33 + struct drm_panel; 33 34 34 35 /* 35 36 * Unless otherwise noted, all values are from the DP 1.1a spec. Note that ··· 2200 2199 int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl, 2201 2200 u16 level); 2202 2201 int drm_edp_backlight_disable(struct drm_dp_aux *aux, const struct drm_edp_backlight_info *bl); 2202 + 2203 + #if IS_ENABLED(CONFIG_DRM_KMS_HELPER) && (IS_BUILTIN(CONFIG_BACKLIGHT_CLASS_DEVICE) || \ 2204 + (IS_MODULE(CONFIG_DRM_KMS_HELPER) && IS_MODULE(CONFIG_BACKLIGHT_CLASS_DEVICE))) 2205 + 2206 + int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux); 2207 + 2208 + #else 2209 + 2210 + static inline int drm_panel_dp_aux_backlight(struct drm_panel *panel, 2211 + struct drm_dp_aux *aux) 2212 + { 2213 + return 0; 2214 + } 2215 + 2216 + #endif 2203 2217 2204 2218 #ifdef CONFIG_DRM_DP_CEC 2205 2219 void drm_dp_cec_irq(struct drm_dp_aux *aux);
-8
include/drm/drm_panel.h
··· 32 32 struct device_node; 33 33 struct drm_connector; 34 34 struct drm_device; 35 - struct drm_dp_aux; 36 35 struct drm_panel; 37 36 struct display_timing; 38 37 ··· 208 209 #if IS_ENABLED(CONFIG_DRM_PANEL) && (IS_BUILTIN(CONFIG_BACKLIGHT_CLASS_DEVICE) || \ 209 210 (IS_MODULE(CONFIG_DRM) && IS_MODULE(CONFIG_BACKLIGHT_CLASS_DEVICE))) 210 211 int drm_panel_of_backlight(struct drm_panel *panel); 211 - int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux); 212 212 #else 213 213 static inline int drm_panel_of_backlight(struct drm_panel *panel) 214 - { 215 - return 0; 216 - } 217 - 218 - static inline int drm_panel_dp_aux_backlight(struct drm_panel *panel, 219 - struct drm_dp_aux *aux) 220 214 { 221 215 return 0; 222 216 }