diff options
Diffstat (limited to 'drivers/gpu/drm/bridge/sii902x.c')
-rw-r--r-- | drivers/gpu/drm/bridge/sii902x.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c index b1ab4ab09532..60373d7eb220 100644 --- a/drivers/gpu/drm/bridge/sii902x.c +++ b/drivers/gpu/drm/bridge/sii902x.c @@ -137,7 +137,9 @@ static int sii902x_get_modes(struct drm_connector *connector) struct sii902x *sii902x = connector_to_sii902x(connector); struct regmap *regmap = sii902x->regmap; u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24; + struct device *dev = &sii902x->i2c->dev; unsigned long timeout; + unsigned int retries; unsigned int status; struct edid *edid; int num = 0; @@ -159,7 +161,7 @@ static int sii902x_get_modes(struct drm_connector *connector) time_before(jiffies, timeout)); if (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD)) { - dev_err(&sii902x->i2c->dev, "failed to acquire the i2c bus\n"); + dev_err(dev, "failed to acquire the i2c bus\n"); return -ETIMEDOUT; } @@ -179,9 +181,19 @@ static int sii902x_get_modes(struct drm_connector *connector) if (ret) return ret; - ret = regmap_read(regmap, SII902X_SYS_CTRL_DATA, &status); + /* + * Sometimes the I2C bus can stall after failure to use the + * EDID channel. Retry a few times to see if things clear + * up, else continue anyway. + */ + retries = 5; + do { + ret = regmap_read(regmap, SII902X_SYS_CTRL_DATA, + &status); + retries--; + } while (ret && retries); if (ret) - return ret; + dev_err(dev, "failed to read status (%d)\n", ret); ret = regmap_update_bits(regmap, SII902X_SYS_CTRL_DATA, SII902X_SYS_CTRL_DDC_BUS_REQ | @@ -201,7 +213,7 @@ static int sii902x_get_modes(struct drm_connector *connector) if (status & (SII902X_SYS_CTRL_DDC_BUS_REQ | SII902X_SYS_CTRL_DDC_BUS_GRTD)) { - dev_err(&sii902x->i2c->dev, "failed to release the i2c bus\n"); + dev_err(dev, "failed to release the i2c bus\n"); return -ETIMEDOUT; } |