Skip to content

Commit

Permalink
reset: replace boolean parameters with flags parameter
Browse files Browse the repository at this point in the history
Introduce enum reset_control_flags and replace the list of boolean
parameters to the internal reset_control_get functions with a single
flags parameter, before adding more boolean options.

The separate boolean parameters have been shown to be error prone in
the past. See for example commit a57f68d ("reset: Fix devm bulk
optional exclusive control getter").

Acked-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Link: https://lore.kernel.org/r/20240925-reset-get-deasserted-v2-1-b3601bbd0458@pengutronix.de
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
  • Loading branch information
Philipp Zabel committed Oct 1, 2024
1 parent 5f79c4b commit dad35f7
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 93 deletions.
71 changes: 40 additions & 31 deletions drivers/reset/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -773,12 +773,19 @@ EXPORT_SYMBOL_GPL(reset_control_bulk_release);

static struct reset_control *
__reset_control_get_internal(struct reset_controller_dev *rcdev,
unsigned int index, bool shared, bool acquired)
unsigned int index, enum reset_control_flags flags)
{
bool shared = flags & RESET_CONTROL_FLAGS_BIT_SHARED;
bool acquired = flags & RESET_CONTROL_FLAGS_BIT_ACQUIRED;
struct reset_control *rstc;

lockdep_assert_held(&reset_list_mutex);

/* Expect callers to filter out OPTIONAL and DEASSERTED bits */
if (WARN_ON(flags & ~(RESET_CONTROL_FLAGS_BIT_SHARED |
RESET_CONTROL_FLAGS_BIT_ACQUIRED)))
return ERR_PTR(-EINVAL);

list_for_each_entry(rstc, &rcdev->reset_control_head, list) {
if (rstc->id == index) {
/*
Expand Down Expand Up @@ -994,8 +1001,9 @@ static struct reset_controller_dev *__reset_find_rcdev(const struct of_phandle_a

struct reset_control *
__of_reset_control_get(struct device_node *node, const char *id, int index,
bool shared, bool optional, bool acquired)
enum reset_control_flags flags)
{
bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
bool gpio_fallback = false;
struct reset_control *rstc;
struct reset_controller_dev *rcdev;
Expand Down Expand Up @@ -1059,8 +1067,10 @@ __of_reset_control_get(struct device_node *node, const char *id, int index,
goto out_unlock;
}

flags &= ~RESET_CONTROL_FLAGS_BIT_OPTIONAL;

/* reset_list_mutex also protects the rcdev's reset_control list */
rstc = __reset_control_get_internal(rcdev, rstc_id, shared, acquired);
rstc = __reset_control_get_internal(rcdev, rstc_id, flags);

out_unlock:
mutex_unlock(&reset_list_mutex);
Expand Down Expand Up @@ -1091,8 +1101,9 @@ __reset_controller_by_name(const char *name)

static struct reset_control *
__reset_control_get_from_lookup(struct device *dev, const char *con_id,
bool shared, bool optional, bool acquired)
enum reset_control_flags flags)
{
bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
const struct reset_control_lookup *lookup;
struct reset_controller_dev *rcdev;
const char *dev_id = dev_name(dev);
Expand All @@ -1116,9 +1127,11 @@ __reset_control_get_from_lookup(struct device *dev, const char *con_id,
return ERR_PTR(-EPROBE_DEFER);
}

flags &= ~RESET_CONTROL_FLAGS_BIT_OPTIONAL;

rstc = __reset_control_get_internal(rcdev,
lookup->index,
shared, acquired);
flags);
mutex_unlock(&reset_list_mutex);
break;
}
Expand All @@ -1133,30 +1146,29 @@ __reset_control_get_from_lookup(struct device *dev, const char *con_id,
}

struct reset_control *__reset_control_get(struct device *dev, const char *id,
int index, bool shared, bool optional,
bool acquired)
int index, enum reset_control_flags flags)
{
bool shared = flags & RESET_CONTROL_FLAGS_BIT_SHARED;
bool acquired = flags & RESET_CONTROL_FLAGS_BIT_ACQUIRED;

if (WARN_ON(shared && acquired))
return ERR_PTR(-EINVAL);

if (dev->of_node)
return __of_reset_control_get(dev->of_node, id, index, shared,
optional, acquired);
return __of_reset_control_get(dev->of_node, id, index, flags);

return __reset_control_get_from_lookup(dev, id, shared, optional,
acquired);
return __reset_control_get_from_lookup(dev, id, flags);
}
EXPORT_SYMBOL_GPL(__reset_control_get);

int __reset_control_bulk_get(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs,
bool shared, bool optional, bool acquired)
enum reset_control_flags flags)
{
int ret, i;

for (i = 0; i < num_rstcs; i++) {
rstcs[i].rstc = __reset_control_get(dev, rstcs[i].id, 0,
shared, optional, acquired);
rstcs[i].rstc = __reset_control_get(dev, rstcs[i].id, 0, flags);
if (IS_ERR(rstcs[i].rstc)) {
ret = PTR_ERR(rstcs[i].rstc);
goto err;
Expand Down Expand Up @@ -1226,7 +1238,7 @@ static void devm_reset_control_release(struct device *dev, void *res)

struct reset_control *
__devm_reset_control_get(struct device *dev, const char *id, int index,
bool shared, bool optional, bool acquired)
enum reset_control_flags flags)
{
struct reset_control **ptr, *rstc;

Expand All @@ -1235,7 +1247,7 @@ __devm_reset_control_get(struct device *dev, const char *id, int index,
if (!ptr)
return ERR_PTR(-ENOMEM);

rstc = __reset_control_get(dev, id, index, shared, optional, acquired);
rstc = __reset_control_get(dev, id, index, flags);
if (IS_ERR_OR_NULL(rstc)) {
devres_free(ptr);
return rstc;
Expand All @@ -1262,7 +1274,7 @@ static void devm_reset_control_bulk_release(struct device *dev, void *res)

int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs,
bool shared, bool optional, bool acquired)
enum reset_control_flags flags)
{
struct reset_control_bulk_devres *ptr;
int ret;
Expand All @@ -1272,7 +1284,7 @@ int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
if (!ptr)
return -ENOMEM;

ret = __reset_control_bulk_get(dev, num_rstcs, rstcs, shared, optional, acquired);
ret = __reset_control_bulk_get(dev, num_rstcs, rstcs, flags);
if (ret < 0) {
devres_free(ptr);
return ret;
Expand All @@ -1298,6 +1310,7 @@ EXPORT_SYMBOL_GPL(__devm_reset_control_bulk_get);
*/
int __device_reset(struct device *dev, bool optional)
{
enum reset_control_flags flags;
struct reset_control *rstc;
int ret;

Expand All @@ -1313,7 +1326,8 @@ int __device_reset(struct device *dev, bool optional)
}
#endif

rstc = __reset_control_get(dev, NULL, 0, 0, optional, true);
flags = optional ? RESET_CONTROL_OPTIONAL_EXCLUSIVE : RESET_CONTROL_EXCLUSIVE;
rstc = __reset_control_get(dev, NULL, 0, flags);
if (IS_ERR(rstc))
return PTR_ERR(rstc);

Expand Down Expand Up @@ -1356,17 +1370,14 @@ static int of_reset_control_get_count(struct device_node *node)
* device node.
*
* @np: device node for the device that requests the reset controls array
* @shared: whether reset controls are shared or not
* @optional: whether it is optional to get the reset controls
* @acquired: only one reset control may be acquired for a given controller
* and ID
* @flags: whether reset controls are shared, optional, acquired
*
* Returns pointer to allocated reset_control on success or error on failure
*/
struct reset_control *
of_reset_control_array_get(struct device_node *np, bool shared, bool optional,
bool acquired)
of_reset_control_array_get(struct device_node *np, enum reset_control_flags flags)
{
bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
struct reset_control_array *resets;
struct reset_control *rstc;
int num, i;
Expand All @@ -1381,8 +1392,7 @@ of_reset_control_array_get(struct device_node *np, bool shared, bool optional,
resets->num_rstcs = num;

for (i = 0; i < num; i++) {
rstc = __of_reset_control_get(np, NULL, i, shared, optional,
acquired);
rstc = __of_reset_control_get(np, NULL, i, flags);
if (IS_ERR(rstc))
goto err_rst;
resets->rstc[i] = rstc;
Expand All @@ -1407,8 +1417,7 @@ EXPORT_SYMBOL_GPL(of_reset_control_array_get);
* devm_reset_control_array_get - Resource managed reset control array get
*
* @dev: device that requests the list of reset controls
* @shared: whether reset controls are shared or not
* @optional: whether it is optional to get the reset controls
* @flags: whether reset controls are shared, optional, acquired
*
* The reset control array APIs are intended for a list of resets
* that just have to be asserted or deasserted, without any
Expand All @@ -1417,7 +1426,7 @@ EXPORT_SYMBOL_GPL(of_reset_control_array_get);
* Returns pointer to allocated reset_control on success or error on failure
*/
struct reset_control *
devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
devm_reset_control_array_get(struct device *dev, enum reset_control_flags flags)
{
struct reset_control **ptr, *rstc;

Expand All @@ -1426,7 +1435,7 @@ devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
if (!ptr)
return ERR_PTR(-ENOMEM);

rstc = of_reset_control_array_get(dev->of_node, shared, optional, true);
rstc = of_reset_control_array_get(dev->of_node, flags);
if (IS_ERR_OR_NULL(rstc)) {
devres_free(ptr);
return rstc;
Expand Down
Loading

0 comments on commit dad35f7

Please sign in to comment.