Lines Matching +full:- +full:resets
1 // SPDX-License-Identifier: GPL-2.0-or-later
17 #include <linux/reset-controller.h>
27 * struct reset_control - a reset control
39 * only used for shared resets, which means that the value
55 * struct reset_control_array - an array of reset controls
68 if (rcdev->dev) in rcdev_name()
69 return dev_name(rcdev->dev); in rcdev_name()
71 if (rcdev->of_node) in rcdev_name()
72 return rcdev->of_node->full_name; in rcdev_name()
78 * of_reset_simple_xlate - translate reset_spec to the reset line number
90 if (reset_spec->args[0] >= rcdev->nr_resets) in of_reset_simple_xlate()
91 return -EINVAL; in of_reset_simple_xlate()
93 return reset_spec->args[0]; in of_reset_simple_xlate()
97 * reset_controller_register - register a reset controller device
102 if (!rcdev->of_xlate) { in reset_controller_register()
103 rcdev->of_reset_n_cells = 1; in reset_controller_register()
104 rcdev->of_xlate = of_reset_simple_xlate; in reset_controller_register()
107 INIT_LIST_HEAD(&rcdev->reset_control_head); in reset_controller_register()
110 list_add(&rcdev->list, &reset_controller_list); in reset_controller_register()
118 * reset_controller_unregister - unregister a reset controller device
124 list_del(&rcdev->list); in reset_controller_unregister()
135 * devm_reset_controller_register - resource managed reset_controller_register()
152 return -ENOMEM; in devm_reset_controller_register()
168 * reset_controller_add_lookup - register a set of lookup entries
182 if (!entry->dev_id || !entry->provider) { in reset_controller_add_lookup()
188 list_add_tail(&entry->list, &reset_lookup_list); in reset_controller_add_lookup()
199 static int reset_control_array_reset(struct reset_control_array *resets) in reset_control_array_reset() argument
203 for (i = 0; i < resets->num_rstcs; i++) { in reset_control_array_reset()
204 ret = reset_control_reset(resets->rstc[i]); in reset_control_array_reset()
212 static int reset_control_array_rearm(struct reset_control_array *resets) in reset_control_array_rearm() argument
217 for (i = 0; i < resets->num_rstcs; i++) { in reset_control_array_rearm()
218 rstc = resets->rstc[i]; in reset_control_array_rearm()
224 return -EINVAL; in reset_control_array_rearm()
226 if (rstc->shared) { in reset_control_array_rearm()
227 if (WARN_ON(atomic_read(&rstc->deassert_count) != 0)) in reset_control_array_rearm()
228 return -EINVAL; in reset_control_array_rearm()
230 if (!rstc->acquired) in reset_control_array_rearm()
231 return -EPERM; in reset_control_array_rearm()
235 for (i = 0; i < resets->num_rstcs; i++) { in reset_control_array_rearm()
236 rstc = resets->rstc[i]; in reset_control_array_rearm()
238 if (rstc && rstc->shared) in reset_control_array_rearm()
239 WARN_ON(atomic_dec_return(&rstc->triggered_count) < 0); in reset_control_array_rearm()
245 static int reset_control_array_assert(struct reset_control_array *resets) in reset_control_array_assert() argument
249 for (i = 0; i < resets->num_rstcs; i++) { in reset_control_array_assert()
250 ret = reset_control_assert(resets->rstc[i]); in reset_control_array_assert()
258 while (i--) in reset_control_array_assert()
259 reset_control_deassert(resets->rstc[i]); in reset_control_array_assert()
263 static int reset_control_array_deassert(struct reset_control_array *resets) in reset_control_array_deassert() argument
267 for (i = 0; i < resets->num_rstcs; i++) { in reset_control_array_deassert()
268 ret = reset_control_deassert(resets->rstc[i]); in reset_control_array_deassert()
276 while (i--) in reset_control_array_deassert()
277 reset_control_assert(resets->rstc[i]); in reset_control_array_deassert()
281 static int reset_control_array_acquire(struct reset_control_array *resets) in reset_control_array_acquire() argument
286 for (i = 0; i < resets->num_rstcs; i++) { in reset_control_array_acquire()
287 err = reset_control_acquire(resets->rstc[i]); in reset_control_array_acquire()
295 while (i--) in reset_control_array_acquire()
296 reset_control_release(resets->rstc[i]); in reset_control_array_acquire()
301 static void reset_control_array_release(struct reset_control_array *resets) in reset_control_array_release() argument
305 for (i = 0; i < resets->num_rstcs; i++) in reset_control_array_release()
306 reset_control_release(resets->rstc[i]); in reset_control_array_release()
311 return rstc->array; in reset_control_is_array()
315 * reset_control_reset - reset the controlled device
320 * a no-op.
335 return -EINVAL; in reset_control_reset()
340 if (!rstc->rcdev->ops->reset) in reset_control_reset()
341 return -ENOTSUPP; in reset_control_reset()
343 if (rstc->shared) { in reset_control_reset()
344 if (WARN_ON(atomic_read(&rstc->deassert_count) != 0)) in reset_control_reset()
345 return -EINVAL; in reset_control_reset()
347 if (atomic_inc_return(&rstc->triggered_count) != 1) in reset_control_reset()
350 if (!rstc->acquired) in reset_control_reset()
351 return -EPERM; in reset_control_reset()
354 ret = rstc->rcdev->ops->reset(rstc->rcdev, rstc->id); in reset_control_reset()
355 if (rstc->shared && ret) in reset_control_reset()
356 atomic_dec(&rstc->triggered_count); in reset_control_reset()
363 * reset_control_bulk_reset - reset the controlled devices in order
387 * reset_control_rearm - allow shared reset line to be re-triggered"
407 return -EINVAL; in reset_control_rearm()
412 if (rstc->shared) { in reset_control_rearm()
413 if (WARN_ON(atomic_read(&rstc->deassert_count) != 0)) in reset_control_rearm()
414 return -EINVAL; in reset_control_rearm()
416 WARN_ON(atomic_dec_return(&rstc->triggered_count) < 0); in reset_control_rearm()
418 if (!rstc->acquired) in reset_control_rearm()
419 return -EPERM; in reset_control_rearm()
427 * reset_control_assert - asserts the reset line
448 return -EINVAL; in reset_control_assert()
453 if (rstc->shared) { in reset_control_assert()
454 if (WARN_ON(atomic_read(&rstc->triggered_count) != 0)) in reset_control_assert()
455 return -EINVAL; in reset_control_assert()
457 if (WARN_ON(atomic_read(&rstc->deassert_count) == 0)) in reset_control_assert()
458 return -EINVAL; in reset_control_assert()
460 if (atomic_dec_return(&rstc->deassert_count) != 0) in reset_control_assert()
467 if (!rstc->rcdev->ops->assert) in reset_control_assert()
475 if (!rstc->rcdev->ops->assert) in reset_control_assert()
476 return -ENOTSUPP; in reset_control_assert()
478 if (!rstc->acquired) { in reset_control_assert()
480 rcdev_name(rstc->rcdev), rstc->id); in reset_control_assert()
481 return -EPERM; in reset_control_assert()
485 return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id); in reset_control_assert()
490 * reset_control_bulk_assert - asserts the reset lines in order
495 * If an assertion fails, already asserted resets are deasserted again.
513 while (i--) in reset_control_bulk_assert()
520 * reset_control_deassert - deasserts the reset line
536 return -EINVAL; in reset_control_deassert()
541 if (rstc->shared) { in reset_control_deassert()
542 if (WARN_ON(atomic_read(&rstc->triggered_count) != 0)) in reset_control_deassert()
543 return -EINVAL; in reset_control_deassert()
545 if (atomic_inc_return(&rstc->deassert_count) != 1) in reset_control_deassert()
548 if (!rstc->acquired) { in reset_control_deassert()
550 rcdev_name(rstc->rcdev), rstc->id); in reset_control_deassert()
551 return -EPERM; in reset_control_deassert()
557 * that it handles self-deasserting reset lines via .reset(). In that in reset_control_deassert()
560 * return -ENOTSUPP. in reset_control_deassert()
562 if (!rstc->rcdev->ops->deassert) in reset_control_deassert()
565 return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id); in reset_control_deassert()
570 * reset_control_bulk_deassert - deasserts the reset lines in reverse order
575 * If a deassertion fails, already deasserted resets are asserted again.
584 for (i = num_rstcs - 1; i >= 0; i--) { in reset_control_bulk_deassert()
600 * reset_control_status - returns a negative errno if not supported, a
611 return -EINVAL; in reset_control_status()
613 if (rstc->rcdev->ops->status) in reset_control_status()
614 return rstc->rcdev->ops->status(rstc->rcdev, rstc->id); in reset_control_status()
616 return -ENOTSUPP; in reset_control_status()
621 * reset_control_acquire() - acquires a reset control for exclusive use
625 * that exclusive resets are requested as acquired by default. In order for a
648 return -EINVAL; in reset_control_acquire()
655 if (rstc->acquired) { in reset_control_acquire()
660 list_for_each_entry(rc, &rstc->rcdev->reset_control_head, list) { in reset_control_acquire()
661 if (rstc != rc && rstc->id == rc->id) { in reset_control_acquire()
662 if (rc->acquired) { in reset_control_acquire()
664 return -EBUSY; in reset_control_acquire()
669 rstc->acquired = true; in reset_control_acquire()
677 * reset_control_bulk_acquire - acquires reset controls for exclusive use
700 while (i--) in reset_control_bulk_acquire()
707 * reset_control_release() - releases exclusive access to a reset control
724 rstc->acquired = false; in reset_control_release()
729 * reset_control_bulk_release() - releases exclusive access to reset controls
756 list_for_each_entry(rstc, &rcdev->reset_control_head, list) { in __reset_control_get_internal()
757 if (rstc->id == index) { in __reset_control_get_internal()
763 if (!rstc->shared && !shared && !acquired) in __reset_control_get_internal()
766 if (WARN_ON(!rstc->shared || !shared)) in __reset_control_get_internal()
767 return ERR_PTR(-EBUSY); in __reset_control_get_internal()
769 kref_get(&rstc->refcnt); in __reset_control_get_internal()
776 return ERR_PTR(-ENOMEM); in __reset_control_get_internal()
778 if (!try_module_get(rcdev->owner)) { in __reset_control_get_internal()
780 return ERR_PTR(-ENODEV); in __reset_control_get_internal()
783 rstc->rcdev = rcdev; in __reset_control_get_internal()
784 list_add(&rstc->list, &rcdev->reset_control_head); in __reset_control_get_internal()
785 rstc->id = index; in __reset_control_get_internal()
786 kref_init(&rstc->refcnt); in __reset_control_get_internal()
787 rstc->acquired = acquired; in __reset_control_get_internal()
788 rstc->shared = shared; in __reset_control_get_internal()
800 module_put(rstc->rcdev->owner); in __reset_control_release()
802 list_del(&rstc->list); in __reset_control_release()
813 kref_put(&rstc->refcnt, __reset_control_release); in __reset_control_put_internal()
827 return ERR_PTR(-EINVAL); in __of_reset_control_get()
831 "reset-names", id); in __of_reset_control_get()
832 if (index == -EILSEQ) in __of_reset_control_get()
835 return optional ? NULL : ERR_PTR(-ENOENT); in __of_reset_control_get()
838 ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", in __of_reset_control_get()
840 if (ret == -EINVAL) in __of_reset_control_get()
848 if (args.np == r->of_node) { in __of_reset_control_get()
855 rstc = ERR_PTR(-EPROBE_DEFER); in __of_reset_control_get()
859 if (WARN_ON(args.args_count != rcdev->of_reset_n_cells)) { in __of_reset_control_get()
860 rstc = ERR_PTR(-EINVAL); in __of_reset_control_get()
864 rstc_id = rcdev->of_xlate(rcdev, &args); in __of_reset_control_get()
889 if (!rcdev->dev) in __reset_controller_by_name()
892 if (!strcmp(name, dev_name(rcdev->dev))) in __reset_controller_by_name()
911 if (strcmp(lookup->dev_id, dev_id)) in __reset_control_get_from_lookup()
914 if ((!con_id && !lookup->con_id) || in __reset_control_get_from_lookup()
915 ((con_id && lookup->con_id) && in __reset_control_get_from_lookup()
916 !strcmp(con_id, lookup->con_id))) { in __reset_control_get_from_lookup()
918 rcdev = __reset_controller_by_name(lookup->provider); in __reset_control_get_from_lookup()
923 return ERR_PTR(-EPROBE_DEFER); in __reset_control_get_from_lookup()
927 lookup->index, in __reset_control_get_from_lookup()
937 return optional ? NULL : ERR_PTR(-ENOENT); in __reset_control_get_from_lookup()
947 return ERR_PTR(-EINVAL); in __reset_control_get()
949 if (dev->of_node) in __reset_control_get()
950 return __of_reset_control_get(dev->of_node, id, index, shared, in __reset_control_get()
977 while (i--) in __reset_control_bulk_get()
984 static void reset_control_array_put(struct reset_control_array *resets) in reset_control_array_put() argument
989 for (i = 0; i < resets->num_rstcs; i++) in reset_control_array_put()
990 __reset_control_put_internal(resets->rstc[i]); in reset_control_array_put()
992 kfree(resets); in reset_control_array_put()
996 * reset_control_put - free the reset controller
1016 * reset_control_bulk_put - free the reset controllers
1023 while (num_rstcs--) in reset_control_bulk_put()
1043 return ERR_PTR(-ENOMEM); in __devm_reset_control_get()
1067 reset_control_bulk_put(devres->num_rstcs, devres->rstcs); in devm_reset_control_bulk_release()
1080 return -ENOMEM; in __devm_reset_control_bulk_get()
1088 ptr->num_rstcs = num_rstcs; in __devm_reset_control_bulk_get()
1089 ptr->rstcs = rstcs; in __devm_reset_control_bulk_get()
1097 * __device_reset - find reset controller associated with the device
1116 return optional ? 0 : -ENOENT; in __device_reset()
1119 return -EIO; in __device_reset()
1140 * of_reset_control_get_count - Count number of resets available with a device
1142 * @node: device node that contains 'resets'.
1152 return -EINVAL; in of_reset_control_get_count()
1154 count = of_count_phandle_with_args(node, "resets", "#reset-cells"); in of_reset_control_get_count()
1156 count = -ENOENT; in of_reset_control_get_count()
1162 * of_reset_control_array_get - Get a list of reset controls using
1177 struct reset_control_array *resets; in of_reset_control_array_get() local
1185 resets = kzalloc(struct_size(resets, rstc, num), GFP_KERNEL); in of_reset_control_array_get()
1186 if (!resets) in of_reset_control_array_get()
1187 return ERR_PTR(-ENOMEM); in of_reset_control_array_get()
1194 resets->rstc[i] = rstc; in of_reset_control_array_get()
1196 resets->num_rstcs = num; in of_reset_control_array_get()
1197 resets->base.array = true; in of_reset_control_array_get()
1199 return &resets->base; in of_reset_control_array_get()
1203 while (--i >= 0) in of_reset_control_array_get()
1204 __reset_control_put_internal(resets->rstc[i]); in of_reset_control_array_get()
1207 kfree(resets); in of_reset_control_array_get()
1214 * devm_reset_control_array_get - Resource managed reset control array get
1220 * The reset control array APIs are intended for a list of resets
1234 return ERR_PTR(-ENOMEM); in devm_reset_control_array_get()
1236 rstc = of_reset_control_array_get(dev->of_node, shared, optional, true); in devm_reset_control_array_get()
1256 return -EINVAL; in reset_control_get_count_from_lookup()
1262 if (!strcmp(lookup->dev_id, dev_id)) in reset_control_get_count_from_lookup()
1269 count = -ENOENT; in reset_control_get_count_from_lookup()
1275 * reset_control_get_count - Count number of resets available with a device
1277 * @dev: device for which to return the number of resets
1284 if (dev->of_node) in reset_control_get_count()
1285 return of_reset_control_get_count(dev->of_node); in reset_control_get_count()