The bridge chip has an enable gpio which of course can enable/disable the bridge. Most the time this gpio is connected directly to the host but sometimes it is connected to a reset controller chip and the host controlls the reset controller chip instead. This commit adds the support to handle that. Therefore we need either the reset controller or a gpio to be present and valid. The behaviour is changed in that way that a gpio or a reset controller have to be successfully requested else the driver probe fails, like the current behaviour. Signed-off-by: Marco Felsch <m.felsch@xxxxxxxxxxxxxx> --- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c index 3c1dc16985b5..7b232a4f8bcb 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -35,6 +35,7 @@ #include <linux/property.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> +#include <linux/reset.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> @@ -146,6 +147,7 @@ struct sn65dsi83 { struct drm_bridge *panel_bridge; struct gpio_desc *enable_gpio; struct regulator *vcc; + struct reset_control *reset; int dsi_lanes; bool lvds_dual_link; bool lvds_dual_link_even_odd_swap; @@ -350,6 +352,7 @@ static void sn65dsi83_atomic_enable(struct drm_bridge *bridge, /* Deassert reset */ gpiod_set_value(ctx->enable_gpio, 1); + reset_control_deassert(ctx->reset); usleep_range(1000, 1100); /* Get the LVDS format from the bridge state. */ @@ -511,6 +514,7 @@ static void sn65dsi83_atomic_disable(struct drm_bridge *bridge, /* Put the chip in reset, pull EN line low, and assure 10ms reset low timing. */ gpiod_set_value(ctx->enable_gpio, 0); + reset_control_assert(ctx->reset); usleep_range(10000, 11000); ret = regulator_disable(ctx->vcc); @@ -760,6 +764,13 @@ static int sn65dsi83_probe(struct i2c_client *client, return dev_err_probe(ctx->dev, PTR_ERR(ctx->enable_gpio), "Failed to get GPIO\n"); + /* Or use a external reset chip to do so */ + ctx->reset = devm_reset_control_get_optional(ctx->dev, NULL); + if (IS_ERR(ctx->reset)) + return dev_err_probe(ctx->dev, PTR_ERR(ctx->reset), + "Failed to get reset\n"); + reset_control_assert(ctx->reset); + usleep_range(10000, 11000); ret = sn65dsi83_parse_dt(ctx, model); -- 2.30.2