All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hans Verkuil <hverkuil@xs4all.nl>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Arnd Bergmann <arnd@arndb.de>, Bhumika Goyal <bhumirks@gmail.com>,
	David Airlie <airlied@linux.ie>,
	lkml <linux-kernel@vger.kernel.org>,
	dri-devel@lists.freedesktop.org,
	Hans Verkuil <hans.verkuil@cisco.com>,
	Dan Carpenter <dan.carpenter@oracle.com>,
	John Stultz <john.stultz@linaro.org>
Subject: Re: [PATCHv2] drm: adv7511/33: Fix adv7511_cec_init() failure handling
Date: Tue, 21 Nov 2017 09:18:31 +0100	[thread overview]
Message-ID: <c811de94-1e2f-c91f-d336-6f28f1cb1c90@xs4all.nl> (raw)
In-Reply-To: <2716873.T4RGvjZqqn@avalon>

On 11/21/2017 07:48 AM, Laurent Pinchart wrote:
> Hi Hans,
> 
> Thank you for the patch.
> 
> On Monday, 20 November 2017 22:57:34 EET Hans Verkuil wrote:
>> 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.
> 
> I don't think that's correct. You at least need to defer probing if the clock 
> is specified in DT but has no provider available yet. For other errors I agree 
> that we can still initialize the ADV7511 in a degraded mode without CEC 
> support, although I would prefer to also error out in case of invalid DT to 
> ensure that DT errors are caught as early as possible.

Ah yes, probe deferring, I forgot about that. I'll make a v3.
The only other possible error is ENOENT for when no CEC clock is defined,
which just means it should continue without CEC (i.e. this is not an error).

I'll make a v3, also incorporating your other comments below.

Regards,

	Hans

> 
>> An otherwise correct cleanup patch from Dan Carpenter turned this broken
>> failure handling into a kernel Oops, so bisection points to commit
>> 7af35b0addbc ("drm/kirin: Checking for IS_ERR() instead of NULL") rather
>> than 3b1b975003e4 ("drm: adv7511/33: add HDMI CEC support").
>>
>> Based on earlier patches from Arnd and John.
>>
>> Reported-by: Naresh 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: 7af35b0addbc ("drm/kirin: Checking for IS_ERR() instead of NULL")
>> Fixes: 3b1b975003e4 ("drm: adv7511/33: add HDMI CEC support")
>> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
>> Tested-by: Hans Verkuil <hans.verkuil@cisco.com>
>> ---
>> This rework of Arnd and John's patches goes a bit further and makes
>> cec_init a void function and just silently exits if there is no cec clock
>> defined in the dts. I'm sure that's the reason why the kirin board failed
>> on this. BTW: if the kirin board DOES support cec, then it would be nice
>> if it can be hooked up in the dts!
>>
>> Tested with my Dragonboard and Renesas Koelsch board.
>>
>> Change since my previous RFC PATCH:
>>
>> - added static inline adv7511_cec_init to avoid #ifdef in the probe function
>> as suggested by John Stultz.
>>
>> Regards,
>>
>> 	Hans
>> ---
>> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h
>> b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 543a5eb91624..16051bfa5578
>> 100644
>> --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
>> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
>> @@ -374,9 +374,17 @@ struct adv7511 {
>>  };
>>
>>  #ifdef CONFIG_DRM_I2C_ADV7511_CEC
>> -int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511,
>> -		     unsigned int offset);
>> +void adv7511_cec_init(struct device *dev, struct adv7511 *adv7511,
>> +		      unsigned int offset);
>>  void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1);
>> +#else
>> +static inline void adv7511_cec_init(struct device *dev,
>> +				    struct adv7511 *adv7511,
>> +				    unsigned int offset)
>> +{
>> +	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset,
>> +		     ADV7511_CEC_CTRL_POWER_DOWN);
>> +}
>>  #endif
>>
>>  #ifdef CONFIG_DRM_I2C_ADV7533
>> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
>> b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c index
>> b33d730e4d73..c1cd471d31fa 100644
>> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
>> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
>> @@ -300,18 +300,20 @@ 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)
>> +void adv7511_cec_init(struct device *dev, struct adv7511 *adv7511,
>> +		      unsigned int offset)
>>  {
>>  	int ret = adv7511_cec_parse_dt(dev, adv7511);
>>
>>  	if (ret)
>> -		return ret;
>> +		goto disable_cec;
>>
>>  	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 fail;
>> +	}
>>
>>  	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 0);
>>  	/* cec soft reset */
>> @@ -329,9 +331,15 @@ 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) {
>> -		cec_delete_adapter(adv7511->cec_adap);
>> -		adv7511->cec_adap = NULL;
>> -	}
>> -	return ret;
>> +	if (!ret)
>> +		return;
> 
> This confused me for an instant, I think a goto error_cec_delete would be 
> clearer, but that's up to you (maybe I just wasn't awake enough).
> 
>> +	cec_delete_adapter(adv7511->cec_adap);
>> +	adv7511->cec_adap = NULL;
>> +
>> +fail:
> 
> Nitpicking, I'd name this error to match the labels in the probe function.
> 
>> +	dev_info(dev, "Initializing CEC failed with error %d, disabling CEC\n",
>> +		 ret);
>> +disable_cec:
>> +	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset,
>> +		     ADV7511_CEC_CTRL_POWER_DOWN);
>>  }
>> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
>> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index
>> 3a33075dbb22..2eb465827bcd 100644
>> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
>> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
>> @@ -1200,15 +1200,7 @@ static int adv7511_probe(struct i2c_client *i2c,
>> const struct i2c_device_id *id) 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
>> +	adv7511_cec_init(dev, adv7511, offset);
> 
> Now that the offset is only passed to this function, how about computing it in 
> adv7511_cec_init() to store as much CEC code as possible in drivers/gpu/drm/
> bridge/adv7511/adv7511_cec.c ?
> 
>>
>>  	return 0;
> 

WARNING: multiple messages have this Message-ID (diff)
From: Hans Verkuil <hverkuil@xs4all.nl>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Arnd Bergmann <arnd@arndb.de>, David Airlie <airlied@linux.ie>,
	lkml <linux-kernel@vger.kernel.org>,
	dri-devel@lists.freedesktop.org,
	Hans Verkuil <hans.verkuil@cisco.com>,
	Dan Carpenter <dan.carpenter@oracle.com>,
	Bhumika Goyal <bhumirks@gmail.com>
Subject: Re: [PATCHv2] drm: adv7511/33: Fix adv7511_cec_init() failure handling
Date: Tue, 21 Nov 2017 09:18:31 +0100	[thread overview]
Message-ID: <c811de94-1e2f-c91f-d336-6f28f1cb1c90@xs4all.nl> (raw)
In-Reply-To: <2716873.T4RGvjZqqn@avalon>

On 11/21/2017 07:48 AM, Laurent Pinchart wrote:
> Hi Hans,
> 
> Thank you for the patch.
> 
> On Monday, 20 November 2017 22:57:34 EET Hans Verkuil wrote:
>> 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.
> 
> I don't think that's correct. You at least need to defer probing if the clock 
> is specified in DT but has no provider available yet. For other errors I agree 
> that we can still initialize the ADV7511 in a degraded mode without CEC 
> support, although I would prefer to also error out in case of invalid DT to 
> ensure that DT errors are caught as early as possible.

Ah yes, probe deferring, I forgot about that. I'll make a v3.
The only other possible error is ENOENT for when no CEC clock is defined,
which just means it should continue without CEC (i.e. this is not an error).

I'll make a v3, also incorporating your other comments below.

Regards,

	Hans

> 
>> An otherwise correct cleanup patch from Dan Carpenter turned this broken
>> failure handling into a kernel Oops, so bisection points to commit
>> 7af35b0addbc ("drm/kirin: Checking for IS_ERR() instead of NULL") rather
>> than 3b1b975003e4 ("drm: adv7511/33: add HDMI CEC support").
>>
>> Based on earlier patches from Arnd and John.
>>
>> Reported-by: Naresh 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: 7af35b0addbc ("drm/kirin: Checking for IS_ERR() instead of NULL")
>> Fixes: 3b1b975003e4 ("drm: adv7511/33: add HDMI CEC support")
>> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
>> Tested-by: Hans Verkuil <hans.verkuil@cisco.com>
>> ---
>> This rework of Arnd and John's patches goes a bit further and makes
>> cec_init a void function and just silently exits if there is no cec clock
>> defined in the dts. I'm sure that's the reason why the kirin board failed
>> on this. BTW: if the kirin board DOES support cec, then it would be nice
>> if it can be hooked up in the dts!
>>
>> Tested with my Dragonboard and Renesas Koelsch board.
>>
>> Change since my previous RFC PATCH:
>>
>> - added static inline adv7511_cec_init to avoid #ifdef in the probe function
>> as suggested by John Stultz.
>>
>> Regards,
>>
>> 	Hans
>> ---
>> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h
>> b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 543a5eb91624..16051bfa5578
>> 100644
>> --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
>> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
>> @@ -374,9 +374,17 @@ struct adv7511 {
>>  };
>>
>>  #ifdef CONFIG_DRM_I2C_ADV7511_CEC
>> -int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511,
>> -		     unsigned int offset);
>> +void adv7511_cec_init(struct device *dev, struct adv7511 *adv7511,
>> +		      unsigned int offset);
>>  void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1);
>> +#else
>> +static inline void adv7511_cec_init(struct device *dev,
>> +				    struct adv7511 *adv7511,
>> +				    unsigned int offset)
>> +{
>> +	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset,
>> +		     ADV7511_CEC_CTRL_POWER_DOWN);
>> +}
>>  #endif
>>
>>  #ifdef CONFIG_DRM_I2C_ADV7533
>> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
>> b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c index
>> b33d730e4d73..c1cd471d31fa 100644
>> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
>> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
>> @@ -300,18 +300,20 @@ 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)
>> +void adv7511_cec_init(struct device *dev, struct adv7511 *adv7511,
>> +		      unsigned int offset)
>>  {
>>  	int ret = adv7511_cec_parse_dt(dev, adv7511);
>>
>>  	if (ret)
>> -		return ret;
>> +		goto disable_cec;
>>
>>  	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 fail;
>> +	}
>>
>>  	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 0);
>>  	/* cec soft reset */
>> @@ -329,9 +331,15 @@ 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) {
>> -		cec_delete_adapter(adv7511->cec_adap);
>> -		adv7511->cec_adap = NULL;
>> -	}
>> -	return ret;
>> +	if (!ret)
>> +		return;
> 
> This confused me for an instant, I think a goto error_cec_delete would be 
> clearer, but that's up to you (maybe I just wasn't awake enough).
> 
>> +	cec_delete_adapter(adv7511->cec_adap);
>> +	adv7511->cec_adap = NULL;
>> +
>> +fail:
> 
> Nitpicking, I'd name this error to match the labels in the probe function.
> 
>> +	dev_info(dev, "Initializing CEC failed with error %d, disabling CEC\n",
>> +		 ret);
>> +disable_cec:
>> +	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset,
>> +		     ADV7511_CEC_CTRL_POWER_DOWN);
>>  }
>> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
>> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index
>> 3a33075dbb22..2eb465827bcd 100644
>> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
>> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
>> @@ -1200,15 +1200,7 @@ static int adv7511_probe(struct i2c_client *i2c,
>> const struct i2c_device_id *id) 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
>> +	adv7511_cec_init(dev, adv7511, offset);
> 
> Now that the offset is only passed to this function, how about computing it in 
> adv7511_cec_init() to store as much CEC code as possible in drivers/gpu/drm/
> bridge/adv7511/adv7511_cec.c ?
> 
>>
>>  	return 0;
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2017-11-21  8:18 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-15 12:37 [PATCH] [RFT] drm: adv7511/33: fix adv7511_cec_init() failure handling Arnd Bergmann
2017-11-15 12:37 ` Arnd Bergmann
2017-11-15 12:58 ` Hans Verkuil
2017-11-15 12:58   ` Hans Verkuil
2017-11-16 16:42   ` Naresh Kamboju
2017-11-16 21:50 ` John Stultz
2017-11-16 21:50   ` John Stultz
2017-11-16 22:20   ` John Stultz
2017-11-16 22:20     ` John Stultz
2017-11-16 22:23     ` John Stultz
2017-11-16 22:23       ` John Stultz
2017-11-16 22:59     ` [RFC][PATCH] drm: adv7511/33: Fix " John Stultz
2017-11-16 22:59       ` John Stultz
2017-11-26 12:56       ` Archit Taneja
2017-11-28 21:32         ` John Stultz
2017-11-28 21:32           ` John Stultz
2017-11-29  5:05           ` Archit Taneja
2017-11-29  5:05             ` Archit Taneja
2017-11-29  8:15             ` Arnd Bergmann
2017-11-17  8:43     ` [RFC] [PATCH] " Hans Verkuil
2017-11-17  8:43       ` Hans Verkuil
2017-11-20 15:05       ` Hans Verkuil
2017-11-20 15:05         ` Hans Verkuil
2017-11-20 15:06         ` Hans Verkuil
2017-11-20 20:13       ` John Stultz
2017-11-20 20:13         ` John Stultz
2017-11-20 20:57     ` [PATCHv2] " Hans Verkuil
2017-11-20 20:57       ` Hans Verkuil
2017-11-20 23:12       ` John Stultz
2017-11-20 23:12         ` John Stultz
2017-11-21  6:48       ` Laurent Pinchart
2017-11-21  8:18         ` Hans Verkuil [this message]
2017-11-21  8:18           ` Hans Verkuil
2017-11-21  8:17     ` [PATCHv3] " Hans Verkuil
2017-11-21  8:17       ` Hans Verkuil
2017-11-21  8:22       ` Laurent Pinchart
2017-11-23  0:22       ` John Stultz
2017-11-23  0:22         ` John Stultz
2017-11-30  7:02         ` Archit Taneja
2017-11-30  7:02           ` Archit Taneja

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c811de94-1e2f-c91f-d336-6f28f1cb1c90@xs4all.nl \
    --to=hverkuil@xs4all.nl \
    --cc=airlied@linux.ie \
    --cc=arnd@arndb.de \
    --cc=bhumirks@gmail.com \
    --cc=dan.carpenter@oracle.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hans.verkuil@cisco.com \
    --cc=john.stultz@linaro.org \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.