Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1b6fba45 authored by Hans Verkuil's avatar Hans Verkuil Committed by Archit Taneja
Browse files

drm/bridge: adv7511/33: Fix adv7511_cec_init() failure handling



If the device tree for a board did not specify a cec clock, then
adv7511_cec_init would return an error, which would cause adv7511_probe()
to fail and thus there is no HDMI output.

There is no need to have adv7511_probe() fail if the CEC initialization
fails, so just change adv7511_cec_init() to a void function. In addition,
adv7511_cec_init() should just return silently if the cec clock isn't
found and show a message for any other errors.

An otherwise correct cleanup patch from Dan Carpenter turned this broken
failure handling into a kernel Oops, so bisection points to commit
7af35b0a ("drm/kirin: Checking for IS_ERR() instead of NULL") rather
than 3b1b9750 ("drm: adv7511/33: add HDMI CEC support").

Based on earlier patches from Arnd and John.

Reported-by: default avatarNaresh Kamboju <naresh.kamboju@linaro.org>
Cc: Xinliang Liu <xinliang.liu@linaro.org>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Cc: Sean Paul <seanpaul@chromium.org>
Cc: Archit Taneja <architt@codeaurora.org>
Cc: John Stultz <john.stultz@linaro.org>
Link: https://bugs.linaro.org/show_bug.cgi?id=3345
Link: https://lkft.validation.linaro.org/scheduler/job/48017#L3551


Fixes: 7af35b0a ("drm/kirin: Checking for IS_ERR() instead of NULL")
Fixes: 3b1b9750 ("drm: adv7511/33: add HDMI CEC support")
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Tested-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: default avatarJohn Stultz <john.stultz@linaro.org>
Signed-off-by: default avatarArchit Taneja <architt@codeaurora.org>
Link: https://patchwork.freedesktop.org/patch/msgid/9097b2a4-b6b9-5fca-e039-0a17694b1143@xs4all.nl
parent 52dd0650
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -372,9 +372,18 @@ struct adv7511 {
};

#ifdef CONFIG_DRM_I2C_ADV7511_CEC
int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511,
		     unsigned int offset);
int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511);
void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1);
#else
static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
{
	unsigned int offset = adv7511->type == ADV7533 ?
						ADV7533_REG_CEC_OFFSET : 0;

	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset,
		     ADV7511_CEC_CTRL_POWER_DOWN);
	return 0;
}
#endif

#ifdef CONFIG_DRM_I2C_ADV7533
+22 −10
Original line number Diff line number Diff line
@@ -300,18 +300,21 @@ static int adv7511_cec_parse_dt(struct device *dev, struct adv7511 *adv7511)
	return 0;
}

int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511,
		     unsigned int offset)
int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
{
	unsigned int offset = adv7511->type == ADV7533 ?
						ADV7533_REG_CEC_OFFSET : 0;
	int ret = adv7511_cec_parse_dt(dev, adv7511);

	if (ret)
		return ret;
		goto err_cec_parse_dt;

	adv7511->cec_adap = cec_allocate_adapter(&adv7511_cec_adap_ops,
		adv7511, dev_name(dev), CEC_CAP_DEFAULTS, ADV7511_MAX_ADDRS);
	if (IS_ERR(adv7511->cec_adap))
		return PTR_ERR(adv7511->cec_adap);
	if (IS_ERR(adv7511->cec_adap)) {
		ret = PTR_ERR(adv7511->cec_adap);
		goto err_cec_alloc;
	}

	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 0);
	/* cec soft reset */
@@ -329,9 +332,18 @@ int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511,
		     ((adv7511->cec_clk_freq / 750000) - 1) << 2);

	ret = cec_register_adapter(adv7511->cec_adap, dev);
	if (ret) {
	if (ret)
		goto err_cec_register;
	return 0;

err_cec_register:
	cec_delete_adapter(adv7511->cec_adap);
	adv7511->cec_adap = NULL;
	}
	return ret;
err_cec_alloc:
	dev_info(dev, "Initializing CEC failed with error %d, disabling CEC\n",
		 ret);
err_cec_parse_dt:
	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset,
		     ADV7511_CEC_CTRL_POWER_DOWN);
	return ret == -EPROBE_DEFER ? ret : 0;
}
+4 −13
Original line number Diff line number Diff line
@@ -1084,7 +1084,6 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
	struct device *dev = &i2c->dev;
	unsigned int main_i2c_addr = i2c->addr << 1;
	unsigned int edid_i2c_addr = main_i2c_addr + 4;
	unsigned int offset;
	unsigned int val;
	int ret;

@@ -1192,24 +1191,16 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
	if (adv7511->type == ADV7511)
		adv7511_set_link_config(adv7511, &link_config);

	ret = adv7511_cec_init(dev, adv7511);
	if (ret)
		goto err_unregister_cec;

	adv7511->bridge.funcs = &adv7511_bridge_funcs;
	adv7511->bridge.of_node = dev->of_node;

	drm_bridge_add(&adv7511->bridge);

	adv7511_audio_init(dev, adv7511);

	offset = adv7511->type == ADV7533 ? ADV7533_REG_CEC_OFFSET : 0;

#ifdef CONFIG_DRM_I2C_ADV7511_CEC
	ret = adv7511_cec_init(dev, adv7511, offset);
	if (ret)
		goto err_unregister_cec;
#else
	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset,
		     ADV7511_CEC_CTRL_POWER_DOWN);
#endif

	return 0;

err_unregister_cec: