asle_set_backlight() needs to accept backlight request only if the firmware controls the backlight. It used the following expression for this purpose: acpi_video_get_backlight_type() == acpi_backlight_native This expression works well in practice, but has two semantic problems. One is that it actually determines if a backlight device which directly modifies hardware registers ("native backlight") exists. It is possible that a device which does not have backlight at all incorrectly triggers asle_set_backlight(), and the expression does not cover such a case. Another problem is that acpi_video_get_backlight_type() always return acpi_backlight_vendor in reality if CONFIG_ACPI_VIDEO is unset. It means even its ability to determine the existence of native backlight is somewhat limited. This change introduces a new function backlight_device_non_raw_exists(), which returns if the firmware is controlling the backlight, and is always available if backlight support is enabled. Signed-off-by: Akihiko Odaki <akihiko.odaki@xxxxxxxxxx> --- drivers/gpu/drm/i915/display/intel_opregion.c | 3 ++- drivers/video/backlight/backlight.c | 18 ++++++++++++++++++ include/linux/backlight.h | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c index caa07ef34f21..82ea02ab94c2 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.c +++ b/drivers/gpu/drm/i915/display/intel_opregion.c @@ -26,6 +26,7 @@ */ #include <linux/acpi.h> +#include <linux/backlight.h> #include <linux/dmi.h> #include <linux/firmware.h> #include <acpi/video.h> @@ -467,7 +468,7 @@ static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp) drm_dbg(&dev_priv->drm, "bclp = 0x%08x\n", bclp); - if (acpi_video_get_backlight_type() == acpi_backlight_native) { + if (!backlight_device_non_raw_exists()) { drm_dbg_kms(&dev_priv->drm, "opregion backlight request ignored\n"); return 0; diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index b788ff3d0f45..4f0ce463e250 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -516,6 +516,24 @@ struct backlight_device *backlight_device_get_by_name(const char *name) } EXPORT_SYMBOL(backlight_device_get_by_name); +bool backlight_device_non_raw_exists(void) +{ + bool found = false; + struct backlight_device *bd; + + mutex_lock(&backlight_dev_list_mutex); + list_for_each_entry(bd, &backlight_dev_list, entry) { + if (bd->props.type != BACKLIGHT_RAW) { + found = true; + break; + } + } + mutex_unlock(&backlight_dev_list_mutex); + + return found; +} +EXPORT_SYMBOL(backlight_device_non_raw_exists); + /* deprecated - use devm_backlight_device_unregister() */ void backlight_device_unregister(struct backlight_device *bd) { diff --git a/include/linux/backlight.h b/include/linux/backlight.h index 614653e07e3a..364ef6f99a9e 100644 --- a/include/linux/backlight.h +++ b/include/linux/backlight.h @@ -444,6 +444,7 @@ int backlight_register_notifier(struct notifier_block *nb); int backlight_unregister_notifier(struct notifier_block *nb); struct backlight_device *backlight_device_get_by_name(const char *name); struct backlight_device *backlight_device_get_by_type(enum backlight_type type); +bool backlight_device_non_raw_exists(void); int backlight_device_set_brightness(struct backlight_device *bd, unsigned long brightness); -- 2.37.3