MLK-14665 video: fbdev: mxc: mipi dsi: Customize gpio reset function
authorLiu Ying <victor.liu@nxp.com>
Thu, 20 Apr 2017 03:08:32 +0000 (11:08 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:22:01 +0000 (15:22 -0500)
The mxc display driver framework doesn't support deferral probe.
The following initialization process may cause the mipi dsi driver
deferral probe, however.
pinctrl-imx6 - arch_initcall
gpio-mxc - subsys_initcall
gpio-reset - arch_initcall

This patch customizes gpio reset function so that we can remove
the code to use the reset logic provided by the gpio-reset driver.
Also, the gpio-reset driver is not in the upstreaming kernel,
so it would be good not to use it if possible.

Signed-off-by: Liu Ying <victor.liu@nxp.com>
arch/arm/boot/dts/imx6qdl-sabresd.dtsi
drivers/video/fbdev/mxc/mipi_dsi.c

index 04e0d2b..d56c067 100644 (file)
                compatible = "fsl,mxc_v4l2_output";
                status = "okay";
        };
-
-       mipi_dsi_reset: mipi-dsi-reset {
-               compatible = "gpio-reset";
-               reset-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
-               reset-delay-us = <50>;
-               #reset-cells = <0>;
-       };
 };
 
 &audmux {
        disp_id = <1>;
        lcd_panel = "TRULY-WVGA";
        disp-power-on-supply = <&reg_mipi_dsi_pwr_on>;
-       resets = <&mipi_dsi_reset>;
+       reset-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
+       reset-delay-us = <50>;
        status = "okay";
 };
 
index d17d19a..4e189cd 100644 (file)
@@ -26,8 +26,8 @@
 #include <linux/mxcfb.h>
 #include <linux/backlight.h>
 #include <linux/of_device.h>
+#include <linux/of_gpio.h>
 #include <linux/regulator/consumer.h>
-#include <linux/reset.h>
 #include <linux/spinlock.h>
 #include <linux/delay.h>
 #include <video/mipi_display.h>
@@ -728,6 +728,52 @@ static struct mxc_dispdrv_driver mipi_dsi_drv = {
        .setup  = mipi_dsi_setup,
 };
 
+static int device_reset(struct device *dev)
+{
+       struct device_node *np = dev->of_node;
+       enum of_gpio_flags flags;
+       unsigned long gpio_flags;
+       unsigned int gpio;
+       bool initially_in_reset;
+       bool active_low;
+       s32 delay_us;
+       int ret;
+
+       gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &flags);
+       if (gpio == -EPROBE_DEFER) {
+               return gpio;
+       } else if (!gpio_is_valid(gpio)) {
+               dev_err(dev, "invalid reset gpio: %d\n", gpio);
+               return gpio;
+       }
+
+       active_low = flags & OF_GPIO_ACTIVE_LOW;
+
+       ret = of_property_read_u32(np, "reset-delay-us", &delay_us);
+       if (ret < 0 || delay_us < 0) {
+               dev_err(dev, "invalid reset delay\n");
+               return -EINVAL;
+       }
+
+       initially_in_reset = of_property_read_bool(np, "initially-in-reset");
+       if (active_low ^ initially_in_reset)
+               gpio_flags = GPIOF_OUT_INIT_HIGH;
+       else
+               gpio_flags = GPIOF_OUT_INIT_LOW;
+
+       ret = devm_gpio_request_one(dev, gpio, gpio_flags, NULL);
+       if (ret < 0) {
+               dev_err(dev, "failed to request gpio %d: %d\n", gpio, ret);
+               return ret;
+       }
+
+       gpio_set_value_cansleep(gpio, active_low ? 0 : 1);
+       udelay(delay_us);
+       gpio_set_value_cansleep(gpio, active_low ? 1 : 0);
+
+       return 0;
+}
+
 static int imx6q_mipi_dsi_get_mux(int dev_id, int disp_id)
 {
        if (dev_id > 1 || disp_id > 1)