diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index e48fded3e414..5dda3f11129a 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -406,9 +406,90 @@ static bool pwm_backlight_is_linear(struct platform_pwm_backlight_data *data)
 	return true;
 }

+/*
+ * Inherit the initial power state from the hardware.
+ *
+ * This function provides the features necessary to achieve a flicker-free boot
+ * sequence regardless of the initial state of the backlight.
+ *
+ * There are two factors that affect the behaviour of this function.
+ *
+ * 1. Whether the backlight was on or off when the kernel was booted.  We
+ *    currently determine the state of the backlight by checking if the PWM is
+ *    enabled, whether the regulator (if there is one) is enabled and whether
+ *    the enable_gpio (if there is one) is asserted.  All must be enabled for
+ *    the backlight to be on.
+ *
+ * 2. Whether the backlight is linked to a display device. This matters because
+ *    when there is a linked display is will automatically handle the
+ *    backlight as part of its own blank/unblanking.
+ *
+ * This gives us four possible cases.
+ *
+ * Backlight initially off, display linked:
+ *
+ *   The backlight must remain off (a.k.a. FB_BLANK_POWERDOWN) during and after
+ *   the backlight probe. This allows a splash screen to be drawn before the
+ *   backlight is enabled by the display driver. This avoids a flicker when the
+ *   backlight comes on (which typically changes the black level slightly)
+ *   before the splash image has been drawn.
+ *
+ * Backlight initially on, display linked:
+ *
+ *   The backlight must remain on (a.k.a. FB_BLANK_UNBLANK) during and after
+ *   the backlight probe.  This allows a bootloader to show a splash screen and
+ *   for the display system (including the backlight) to continue showing the
+ *   splash image until the kernel is ready to take over the display and draw
+ *   something else.
+ *
+ * Backlight initially off, no display:
+ *
+ *   The backlight must transition from off to on (a.k.a. FB_BLANK_UNBLANK)
+ *   during the backlight probe. This is largely a legacy case. We must
+ *   unblank the backlight at boot because some userspaces are not
+ *   capable of changing the power state of a free-standing backlight
+ *   (they only know how to set the brightness level).
+ *
+ * Backlight initially on, no display:
+ *
+ *   Identical to the initially on, display linked case.
+ *
+ * Note: In both cases where backlight is initially off then we must
+ *       explicitly deassert the enable_gpio in order to ensure we
+ *       honour the post_pwm_on_delay when the backlight is eventually
+ *       activated.  This is required regardless of both the initial state of
+ *       the enable pin and whether we intend to activate the backlight during
+ *       the probe.
+ */
 static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
 {
-	struct device_node *node = pb->dev->of_node;
+	struct device_node *node = pb->dev->of_node; bool active = true;
+
+	/*
+	 * If the enable GPIO is present, observable (either as input
+	 * or output) and off then the backlight is not currently active.
+	 */
+	if (pb->enable_gpio && gpiod_get_value_cansleep(pb->enable_gpio) == 0)
+		active = false;
+
+	if (!regulator_is_enabled(pb->power_supply))
+		active = false;
+
+	if (!pwm_is_enabled(pb->pwm))
+		active = false;
+
+	/*
+	 * Synchronize the enable_gpio with the observed state of the
+	 * hardware.
+	 */
+	if (pb->enable_gpio)
+		gpiod_direction_output(pb->enable_gpio, active);
+
+	/*
+	 * Do not change pb->enabled here! pb->enabled essentially
+	 * tells us if we own one of the regulator's use counts and
+	 * right now we do not.
+	 */

 	/* Not booted with device tree or no phandle link to the node */
 	if (!node || !node->phandle)
@@ -420,20 +501,7 @@ static int pwm_backlight_initial_power_state(const struct pwm_bl_data *pb)
 	 * assume that another driver will enable the backlight at the
 	 * appropriate time. Therefore, if it is disabled, keep it so.
 	 */
-
-	/* if the enable GPIO is disabled, do not enable the backlight */
-	if (pb->enable_gpio && gpiod_get_value_cansleep(pb->enable_gpio) == 0)
-		return FB_BLANK_POWERDOWN;
-
-	/* The regulator is disabled, do not enable the backlight */
-	if (!regulator_is_enabled(pb->power_supply))
-		return FB_BLANK_POWERDOWN;
-
-	/* The PWM is disabled, keep it like this */
-	if (!pwm_is_enabled(pb->pwm))
-		return FB_BLANK_POWERDOWN;
-
-	return FB_BLANK_UNBLANK;
+	return active ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
 }

 static int pwm_backlight_probe(struct platform_device *pdev)
@@ -486,18 +554,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 		goto err_alloc;
 	}

-	/*
-	 * If the GPIO is not known to be already configured as output, that
-	 * is, if gpiod_get_direction returns either 1 or -EINVAL, change the
-	 * direction to output and set the GPIO as active.
-	 * Do not force the GPIO to active when it was already output as it
-	 * could cause backlight flickering or we would enable the backlight too
-	 * early. Leave the decision of the initial backlight state for later.
-	 */
-	if (pb->enable_gpio &&
-	    gpiod_get_direction(pb->enable_gpio) != 0)
-		gpiod_direction_output(pb->enable_gpio, 1);
-
 	pb->power_supply = devm_regulator_get(&pdev->dev, "power");
 	if (IS_ERR(pb->power_supply)) {
 		ret = PTR_ERR(pb->power_supply);
