diff options
author | Douglas Anderson <dianders@chromium.org> | 2021-07-12 18:00:44 +0300 |
---|---|---|
committer | Douglas Anderson <dianders@chromium.org> | 2021-07-13 16:38:37 +0300 |
commit | 072ed3431f5ba20cccdaf57ee950e36b8693e235 (patch) | |
tree | e33f1dfe19e5f8d37a4f722c5016fff88de70aab /drivers | |
parent | bbeb7461c7eed2c5a9a5e6174f388d8bda2b42e9 (diff) | |
download | linux-072ed3431f5ba20cccdaf57ee950e36b8693e235.tar.xz |
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
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/drm_dp_helper.c | 113 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_panel.c | 108 |
2 files changed, 113 insertions, 108 deletions
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 24bbc710c825..e8eec20ab364 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -33,9 +33,17 @@ #include <drm/drm_print.h> #include <drm/drm_vblank.h> #include <drm/drm_dp_mst_helper.h> +#include <drm/drm_panel.h> #include "drm_crtc_helper_internal.h" +struct dp_aux_backlight { + struct backlight_device *base; + struct drm_dp_aux *aux; + struct drm_edp_backlight_info info; + bool enabled; +}; + /** * DOC: dp helpers * @@ -3462,3 +3470,108 @@ drm_edp_backlight_init(struct drm_dp_aux *aux, struct drm_edp_backlight_info *bl return 0; } EXPORT_SYMBOL(drm_edp_backlight_init); + +#if IS_BUILTIN(CONFIG_BACKLIGHT_CLASS_DEVICE) || \ + (IS_MODULE(CONFIG_DRM_KMS_HELPER) && IS_MODULE(CONFIG_BACKLIGHT_CLASS_DEVICE)) + +static int dp_aux_backlight_update_status(struct backlight_device *bd) +{ + struct dp_aux_backlight *bl = bl_get_data(bd); + u16 brightness = backlight_get_brightness(bd); + int ret = 0; + + if (!backlight_is_blank(bd)) { + if (!bl->enabled) { + drm_edp_backlight_enable(bl->aux, &bl->info, brightness); + bl->enabled = true; + return 0; + } + ret = drm_edp_backlight_set_level(bl->aux, &bl->info, brightness); + } else { + if (bl->enabled) { + drm_edp_backlight_disable(bl->aux, &bl->info); + bl->enabled = false; + } + } + + return ret; +} + +static const struct backlight_ops dp_aux_bl_ops = { + .update_status = dp_aux_backlight_update_status, +}; + +/** + * drm_panel_dp_aux_backlight - create and use DP AUX backlight + * @panel: DRM panel + * @aux: The DP AUX channel to use + * + * Use this function to create and handle backlight if your panel + * supports backlight control over DP AUX channel using DPCD + * registers as per VESA's standard backlight control interface. + * + * When the panel is enabled backlight will be enabled after a + * successful call to &drm_panel_funcs.enable() + * + * When the panel is disabled backlight will be disabled before the + * call to &drm_panel_funcs.disable(). + * + * A typical implementation for a panel driver supporting backlight + * control over DP AUX will call this function at probe time. + * Backlight will then be handled transparently without requiring + * any intervention from the driver. + * + * drm_panel_dp_aux_backlight() must be called after the call to drm_panel_init(). + * + * Return: 0 on success or a negative error code on failure. + */ +int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux) +{ + struct dp_aux_backlight *bl; + struct backlight_properties props = { 0 }; + u16 current_level; + u8 current_mode; + u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]; + int ret; + + if (!panel || !panel->dev || !aux) + return -EINVAL; + + ret = drm_dp_dpcd_read(aux, DP_EDP_DPCD_REV, edp_dpcd, + EDP_DISPLAY_CTL_CAP_SIZE); + if (ret < 0) + return ret; + + if (!drm_edp_backlight_supported(edp_dpcd)) { + DRM_DEV_INFO(panel->dev, "DP AUX backlight is not supported\n"); + return 0; + } + + bl = devm_kzalloc(panel->dev, sizeof(*bl), GFP_KERNEL); + if (!bl) + return -ENOMEM; + + bl->aux = aux; + + ret = drm_edp_backlight_init(aux, &bl->info, 0, edp_dpcd, + ¤t_level, ¤t_mode); + if (ret < 0) + return ret; + + props.type = BACKLIGHT_RAW; + props.brightness = current_level; + props.max_brightness = bl->info.max; + + bl->base = devm_backlight_device_register(panel->dev, "dp_aux_backlight", + panel->dev, bl, + &dp_aux_bl_ops, &props); + if (IS_ERR(bl->base)) + return PTR_ERR(bl->base); + + panel->backlight = bl->base; + + return 0; +} +EXPORT_SYMBOL(drm_panel_dp_aux_backlight); + +#endif diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c index 4fa1e3bb1b78..f634371c717a 100644 --- a/drivers/gpu/drm/drm_panel.c +++ b/drivers/gpu/drm/drm_panel.c @@ -26,20 +26,12 @@ #include <linux/module.h> #include <drm/drm_crtc.h> -#include <drm/drm_dp_helper.h> #include <drm/drm_panel.h> #include <drm/drm_print.h> static DEFINE_MUTEX(panel_lock); static LIST_HEAD(panel_list); -struct dp_aux_backlight { - struct backlight_device *base; - struct drm_dp_aux *aux; - struct drm_edp_backlight_info info; - bool enabled; -}; - /** * DOC: drm panel * @@ -350,106 +342,6 @@ int drm_panel_of_backlight(struct drm_panel *panel) return 0; } EXPORT_SYMBOL(drm_panel_of_backlight); - -static int dp_aux_backlight_update_status(struct backlight_device *bd) -{ - struct dp_aux_backlight *bl = bl_get_data(bd); - u16 brightness = backlight_get_brightness(bd); - int ret = 0; - - if (!backlight_is_blank(bd)) { - if (!bl->enabled) { - drm_edp_backlight_enable(bl->aux, &bl->info, brightness); - bl->enabled = true; - return 0; - } - ret = drm_edp_backlight_set_level(bl->aux, &bl->info, brightness); - } else { - if (bl->enabled) { - drm_edp_backlight_disable(bl->aux, &bl->info); - bl->enabled = false; - } - } - - return ret; -} - -static const struct backlight_ops dp_aux_bl_ops = { - .update_status = dp_aux_backlight_update_status, -}; - -/** - * drm_panel_dp_aux_backlight - create and use DP AUX backlight - * @panel: DRM panel - * @aux: The DP AUX channel to use - * - * Use this function to create and handle backlight if your panel - * supports backlight control over DP AUX channel using DPCD - * registers as per VESA's standard backlight control interface. - * - * When the panel is enabled backlight will be enabled after a - * successful call to &drm_panel_funcs.enable() - * - * When the panel is disabled backlight will be disabled before the - * call to &drm_panel_funcs.disable(). - * - * A typical implementation for a panel driver supporting backlight - * control over DP AUX will call this function at probe time. - * Backlight will then be handled transparently without requiring - * any intervention from the driver. - * - * drm_panel_dp_aux_backlight() must be called after the call to drm_panel_init(). - * - * Return: 0 on success or a negative error code on failure. - */ -int drm_panel_dp_aux_backlight(struct drm_panel *panel, struct drm_dp_aux *aux) -{ - struct dp_aux_backlight *bl; - struct backlight_properties props = { 0 }; - u16 current_level; - u8 current_mode; - u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]; - int ret; - - if (!panel || !panel->dev || !aux) - return -EINVAL; - - ret = drm_dp_dpcd_read(aux, DP_EDP_DPCD_REV, edp_dpcd, - EDP_DISPLAY_CTL_CAP_SIZE); - if (ret < 0) - return ret; - - if (!drm_edp_backlight_supported(edp_dpcd)) { - DRM_DEV_INFO(panel->dev, "DP AUX backlight is not supported\n"); - return 0; - } - - bl = devm_kzalloc(panel->dev, sizeof(*bl), GFP_KERNEL); - if (!bl) - return -ENOMEM; - - bl->aux = aux; - - ret = drm_edp_backlight_init(aux, &bl->info, 0, edp_dpcd, - ¤t_level, ¤t_mode); - if (ret < 0) - return ret; - - props.type = BACKLIGHT_RAW; - props.brightness = current_level; - props.max_brightness = bl->info.max; - - bl->base = devm_backlight_device_register(panel->dev, "dp_aux_backlight", - panel->dev, bl, - &dp_aux_bl_ops, &props); - if (IS_ERR(bl->base)) - return PTR_ERR(bl->base); - - panel->backlight = bl->base; - - return 0; -} -EXPORT_SYMBOL(drm_panel_dp_aux_backlight); #endif MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); |