All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kishon Vijay Abraham I <kishon@ti.com>
To: u-boot@lists.denx.de
Subject: [PATCH 1/2] reset: Do not return NULL on error for devm_reset_control_get_optional()
Date: Fri, 14 May 2021 10:48:00 +0530	[thread overview]
Message-ID: <59c891bf-1810-61e3-8711-4d5642631e93@ti.com> (raw)
In-Reply-To: <CAPnjgZ1u7CYYj34Z2eDCKrH0Q1Nx-_978enWzb9-S80z85w-5w@mail.gmail.com>

Hi Simon,

On 14/05/21 5:26 am, Simon Glass wrote:
> Hi Kishon,
> 
> On Thu, 13 May 2021 at 00:15, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>>
>> Hi Simon,
>>
>> On 11/05/21 10:09 pm, Simon Glass wrote:
>>> Hi Kishon,
>>>
>>> On Tue, 11 May 2021 at 00:26, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>>>>
>>>> Hi Simon,
>>>>
>>>> On 07/05/21 10:04 pm, Simon Glass wrote:
>>>>> Hi Kishon,
>>>>>
>>>>> On Fri, 7 May 2021 at 05:02, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>>>>>>
>>>>>> In order for client to know whether it was able to successfully get a
>>>>>> reset controller or not, do not return NULL on error for
>>>>>> devm_reset_control_get_optional() and
>>>>>> devm_reset_bulk_get_optional_by_node().
>>>>>>
>>>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>>>> ---
>>>>>>  drivers/reset/reset-uclass.c       | 16 ++--------------
>>>>>>  drivers/reset/sandbox-reset-test.c |  2 +-
>>>>>>  2 files changed, 3 insertions(+), 15 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c
>>>>>> index ac89eaf098..906f58ce3d 100644
>>>>>> --- a/drivers/reset/reset-uclass.c
>>>>>> +++ b/drivers/reset/reset-uclass.c
>>>>>> @@ -299,12 +299,7 @@ struct reset_ctl *devm_reset_control_get(struct udevice *dev, const char *id)
>>>>>>  struct reset_ctl *devm_reset_control_get_optional(struct udevice *dev,
>>>>>>                                                   const char *id)
>>>>>>  {
>>>>>> -       struct reset_ctl *r = devm_reset_control_get(dev, id);
>>>>>> -
>>>>>> -       if (IS_ERR(r))
>>>>>> -               return NULL;
>>>>>> -
>>>>>> -       return r;
>>>>>> +       return devm_reset_control_get(dev, id);
>>>>>>  }
>>>>>
>>>>> We need to get some updates to the API (function comments in the
>>>>> header) here. I'm not sure what the intent is.
>>>>
>>>> right, that has to be fixed.
>>>>>
>>>>> I thought these functions were going to return a valid (but possibly
>>>>> empty) reset_ctl always?
>>>>
>>>> I thought about it again and felt it might not be correct to return
>>>> reset_ctl always. The reset control is optional only if the consumer
>>>> node doesn't have populated reset properties.
>>>>
>>>> If we always return valid reset_ctl possibly with it's dev member
>>>> initialized or not initialized, it would not be possible to tell it's
>>>> not initialized because of the absence of reset property or due to some
>>>> other valid error.
>>>
>>> reset_valid() should check if dev is NULL or not, like with clock and
>>> GPIO. Is that enough?
>>
>> clock compares with ENODATA and return "0" (code snippet below). For
>> reset we are modifying this to return ENODATA itself and use it for
>> comparing in the reset APIs.
>>
>> int clk_get_optional_nodev(ofnode node, const char *name, struct clk *clk)
>> {
>>         int ret;
>>
>>         ret = clk_get_by_name_nodev(node, name, clk);
>>         if (ret == -ENODATA)
>>                 return 0;
>>
>>         return ret;
>> }
>>
> 
> We must just be talking at cross-purposes. The function you show above
> returns an error code, so there is no need for the caller to check clk
> if an error is returned. For the -ENODATA case, note that
> clk_get_by_name_nodev() sets clk->dev to NULL, thus ensuring that
> clk_valid() works as expected.

hmm, I pointed to the wrong function from clk-uclass. The below clk
function is similar to our reset usecase

struct clk *devm_clk_get_optional(struct udevice *dev, const char *id)
{
	struct clk *clk = devm_clk_get(dev, id);

	if (PTR_ERR(clk) == -ENODATA)
		return NULL;

	return clk;
}

For this case, clk_valid() works because it checks for "clk" pointer and
for ENODATA case (get_optional), the client will have clk = NULL and
pass NULL to all the clock APIs.

IIUC, you don't prefer returning NULL to client on ENODATA (or any other
error)? And that's why unlike devm_clk_get_optional() which returns NULL
on ENODATA, $patch directly returns devm_reset_control_get().

So for reset it could return
	1) valid reset_ctl pointer with dev initialized
	2) -ENOMEM (if allocation of reset_ctl itself fails)
	3) -ENODATA (if reset-names is not populated in DT)
	4) -ENOENT/-EINVAL (for other DT errors)

clk-uclass has a separate class of APIs that ends with _nodev(). Here
the client allocates memory for clk and let clk framework populate
clk->dev. For the other APIs where clk framework itself returns clk
pointer, there is no case where clk framework returns a valid clk
pointer but without clk->dev initialized (the second case is what we
deal in reset).

Since reset at this point doesn't deal with _nodev(), the latter case
above for clk is what should be considered (i.e reset returns valid
reset_ctrl pointer with dev initialized or return an error value).

So again coming back to the return values mentioned above [ 1) valid
reset, 2) -ENOMEM, 3) -ENODATA, 4) -ENOENT/-EINVAL ].

For get_optional()
  1) Should we return NULL on -ENODATA (similar to devm_clk_get_optional())?
  2) If we decide to return error value instead of NULL, the check would
simply move to client and reset_valid(). i.e The client would check
return value of get_optional() and if it's -ENODDATA, it's not going to
error out and will also pass -ENODATA to reset APIs. The reset APIs will
check again if it's ENODATA and handle it gracefully (to be done in
reset_valid()).
  3) We return NULL for optional() similar to devm_clk_get_optional()
and not consider the _nodev() APIs. Here reset_valid() will only check
if reset_ctrl is NULL or not.
> 
> But all of your patches are about a function that returns a pointer,
> which is a different thing....

Sorry about this. I pointed to the wrong function creating more confusion.
> 
>> I can add reset_valid() and add the conditional checks corresponding to
>> the changes made for reset (like return -ENODATA instead of 0).
> 
> I'm a bit lost at this point...will look at what you send.

I hope I've explained the differences between clk and reset above.
Please see and provide your feedback.

Thanks
Kishon

  reply	other threads:[~2021-05-14  5:18 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-07 11:02 [PATCH 0/2] reset: Fix the behavior of optional reset Kishon Vijay Abraham I
2021-05-07 11:02 ` [PATCH 1/2] reset: Do not return NULL on error for devm_reset_control_get_optional() Kishon Vijay Abraham I
2021-05-07 16:34   ` Simon Glass
2021-05-11  6:26     ` Kishon Vijay Abraham I
2021-05-11 16:39       ` Simon Glass
2021-05-13  6:15         ` Kishon Vijay Abraham I
2021-05-13 23:56           ` Simon Glass
2021-05-14  5:18             ` Kishon Vijay Abraham I [this message]
2021-06-08 10:40               ` Pratyush Yadav
2021-06-19 17:32                 ` Simon Glass
2021-05-07 11:02 ` [PATCH 2/2] reset: Let reset API's handle gracefully if reset_ctl is -ENODATA Kishon Vijay Abraham I
2021-05-07 16:34   ` Simon Glass
2021-05-13  6:30     ` Kishon Vijay Abraham I
2021-05-13 17:00       ` Simon Glass

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=59c891bf-1810-61e3-8711-4d5642631e93@ti.com \
    --to=kishon@ti.com \
    --cc=u-boot@lists.denx.de \
    /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.