diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/reset/reset-uclass.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c index 307a29705f..9a5c9c91b9 100644 --- a/drivers/reset/reset-uclass.c +++ b/drivers/reset/reset-uclass.c @@ -81,6 +81,40 @@ int reset_get_by_index(struct udevice *dev, int index, return 0; } +int reset_get_bulk(struct udevice *dev, struct reset_ctl_bulk *bulk) +{ + int i, ret, err, count; + + bulk->count = 0; + + count = dev_count_phandle_with_args(dev, "resets", "#reset-cells"); + if (!count) + return 0; + + bulk->resets = devm_kcalloc(dev, count, sizeof(struct reset_ctl), + GFP_KERNEL); + if (!bulk->resets) + return -ENOMEM; + + for (i = 0; i < count; i++) { + ret = reset_get_by_index(dev, i, &bulk->resets[i]); + if (ret < 0) + goto bulk_get_err; + + ++bulk->count; + } + + return 0; + +bulk_get_err: + err = reset_release_all(bulk->resets, bulk->count); + if (err) + debug("%s: could release all resets for %p\n", + __func__, dev); + + return ret; +} + int reset_get_by_name(struct udevice *dev, const char *name, struct reset_ctl *reset_ctl) { @@ -126,6 +160,19 @@ int reset_assert(struct reset_ctl *reset_ctl) return ops->rst_assert(reset_ctl); } +int reset_assert_bulk(struct reset_ctl_bulk *bulk) +{ + int i, ret; + + for (i = 0; i < bulk->count; i++) { + ret = reset_assert(&bulk->resets[i]); + if (ret < 0) + return ret; + } + + return 0; +} + int reset_deassert(struct reset_ctl *reset_ctl) { struct reset_ops *ops = reset_dev_ops(reset_ctl->dev); @@ -135,6 +182,19 @@ int reset_deassert(struct reset_ctl *reset_ctl) return ops->rst_deassert(reset_ctl); } +int reset_deassert_bulk(struct reset_ctl_bulk *bulk) +{ + int i, ret; + + for (i = 0; i < bulk->count; i++) { + ret = reset_deassert(&bulk->resets[i]); + if (ret < 0) + return ret; + } + + return 0; +} + int reset_release_all(struct reset_ctl *reset_ctl, int count) { int i, ret; |