When of_reset_control_get() is called without connection ID it returns -ENOENT when the 'resets' property doesn't exists or is an empty entry. However when a connection ID is given it returns -EINVAL when the 'resets' property doesn't exists or the requested name can't be found. This is because the error code returned by of_property_match_string() is just passed down as an index to of_parse_phandle_with_args(), which then returns -EINVAL. To get a consistent return value with both code paths we must return -ENOENT when of_property_match_string() fails. Signed-off-by: Alban Bedel <albeu@free.fr> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> [afa: ported from Linux 3d81216fde465e76c5eae98f61d3666163634395] Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> --- drivers/reset/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 4355c3415eb0..93fbaeccafd2 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -236,8 +236,11 @@ struct reset_control *of_reset_control_get(struct device_node *node, { int index = 0; - if (id) + if (id) { index = of_property_match_string(node, "reset-names", id); + if (index < 0) + return ERR_PTR(-ENOENT); + } return of_reset_control_get_by_index(node, index); } -- 2.30.2
Make porting kernel code easier by providing a compatible reset_control_get_optional() function. Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> --- include/linux/reset.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/linux/reset.h b/include/linux/reset.h index d0677b1d9f63..91e9cdfb3279 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -73,4 +73,10 @@ static inline int device_reset_all(struct device_d *dev) #endif /* CONFIG_RESET_CONTROLLER */ +static inline struct reset_control *reset_control_get_optional(struct device_d *dev, const char *id) +{ + struct reset_control *rstc = reset_control_get(dev, id); + return rstc == ERR_PTR(-ENOENT) ? NULL : rstc; +} + #endif -- 2.30.2
We have a nearly equivalent of_reset_control_get_count(). Rename it and adjust the prototype to make kernel code easier to port. Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> --- drivers/reset/core.c | 10 +++++----- include/linux/reset.h | 7 +++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 93fbaeccafd2..b252f94d6eb9 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -157,14 +157,14 @@ int reset_control_deassert(struct reset_control *rstc) EXPORT_SYMBOL_GPL(reset_control_deassert); /** - * of_reset_control_count - Count reset lines - * @node: device node + * reset_control_get_count - Count reset lines + * @dev: device * * Returns number of resets, 0 if none specified */ -static int of_reset_control_count(struct device_node *node) +int reset_control_get_count(struct device_d *dev) { - return of_count_phandle_with_args(node, "resets", "#reset-cells"); + return of_count_phandle_with_args(dev->device_node, "resets", "#reset-cells"); } /** @@ -357,7 +357,7 @@ int device_reset_all(struct device_d *dev) struct reset_control *rstc; int ret, i; - for (i = 0; i < of_reset_control_count(dev->device_node); i++) { + for (i = 0; i < reset_control_get_count(dev); i++) { int ret; rstc = of_reset_control_get_by_index(dev->device_node, i); diff --git a/include/linux/reset.h b/include/linux/reset.h index 91e9cdfb3279..c1282a84c72c 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -24,6 +24,8 @@ int __must_check device_reset_us(struct device_d *dev, int us); int __must_check device_reset_all(struct device_d *dev); +int reset_control_get_count(struct device_d *dev); + #else static inline int reset_control_status(struct reset_control *rstc) @@ -71,6 +73,11 @@ static inline int device_reset_all(struct device_d *dev) return 0; } +static inline int reset_control_get_count(struct device_d *dev) +{ + return 0; +} + #endif /* CONFIG_RESET_CONTROLLER */ static inline struct reset_control *reset_control_get_optional(struct device_d *dev, const char *id) -- 2.30.2
On Fri, Aug 05, 2022 at 02:59:29PM +0200, Ahmad Fatoum wrote: > When of_reset_control_get() is called without connection ID it returns > -ENOENT when the 'resets' property doesn't exists or is an empty entry. > However when a connection ID is given it returns -EINVAL when the 'resets' > property doesn't exists or the requested name can't be found. This is > because the error code returned by of_property_match_string() is just > passed down as an index to of_parse_phandle_with_args(), which then > returns -EINVAL. > > To get a consistent return value with both code paths we must return > -ENOENT when of_property_match_string() fails. > Signed-off-by: Alban Bedel <albeu@free.fr> > Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> > [afa: ported from Linux 3d81216fde465e76c5eae98f61d3666163634395] > Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> > --- > drivers/reset/core.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) Applied, thanks Sascha > > diff --git a/drivers/reset/core.c b/drivers/reset/core.c > index 4355c3415eb0..93fbaeccafd2 100644 > --- a/drivers/reset/core.c > +++ b/drivers/reset/core.c > @@ -236,8 +236,11 @@ struct reset_control *of_reset_control_get(struct device_node *node, > { > int index = 0; > > - if (id) > + if (id) { > index = of_property_match_string(node, "reset-names", id); > + if (index < 0) > + return ERR_PTR(-ENOENT); > + } > > return of_reset_control_get_by_index(node, index); > } > -- > 2.30.2 > > > -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |