]> git.baikalelectronics.ru Git - kernel.git/commitdiff
video: fbdev: imxfb: ensure balanced regulator usage
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Mon, 23 Mar 2020 21:16:26 +0000 (22:16 +0100)
committerBartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Fri, 17 Apr 2020 13:50:07 +0000 (15:50 +0200)
The fbdev framework doesn't care to call the .set_power callback only on
changes. So the driver has to care for itself that the regulator doesn't
get disabled more often than enabled.

This fixes the regulator warning

unbalanced disables for lcd supply

which can be triggered by doing

echo 4 > /sys/class/lcd/imxfb-lcd/lcd_power

twice.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200323211626.24812-1-u.kleine-koenig@pengutronix.de
drivers/video/fbdev/imxfb.c

index 370bf2553d43320ebb7036383a250b5f919cc43f..884b16efa7e8a93eae6d3b628e11d46142373d30 100644 (file)
@@ -172,6 +172,7 @@ struct imxfb_info {
        int                     num_modes;
 
        struct regulator        *lcd_pwr;
+       int                     lcd_pwr_enabled;
 };
 
 static const struct platform_device_id imxfb_devtype[] = {
@@ -801,16 +802,30 @@ static int imxfb_lcd_get_power(struct lcd_device *lcddev)
        return FB_BLANK_UNBLANK;
 }
 
+static int imxfb_regulator_set(struct imxfb_info *fbi, int enable)
+{
+       int ret;
+
+       if (enable == fbi->lcd_pwr_enabled)
+               return 0;
+
+       if (enable)
+               ret = regulator_enable(fbi->lcd_pwr);
+       else
+               ret = regulator_disable(fbi->lcd_pwr);
+
+       if (ret == 0)
+               fbi->lcd_pwr_enabled = enable;
+
+       return ret;
+}
+
 static int imxfb_lcd_set_power(struct lcd_device *lcddev, int power)
 {
        struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev);
 
-       if (!IS_ERR(fbi->lcd_pwr)) {
-               if (power == FB_BLANK_UNBLANK)
-                       return regulator_enable(fbi->lcd_pwr);
-               else
-                       return regulator_disable(fbi->lcd_pwr);
-       }
+       if (!IS_ERR(fbi->lcd_pwr))
+               return imxfb_regulator_set(fbi, power == FB_BLANK_UNBLANK);
 
        return 0;
 }