Lines Matching +full:reset +full:- +full:controller

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Reset Controller framework
15 #include <linux/reset.h>
16 #include <linux/reset-controller.h>
26 * struct reset_control - a reset control
27 * @rcdev: a pointer to the reset controller device
28 * this reset control belongs to
29 * @list: list entry for the rcdev's reset controller list
30 * @id: ID of the reset controller in the reset
31 * controller device
35 * @array: Is this an array of reset controls (1)?
36 * @deassert_count: Number of times this reset line has been deasserted
37 * @triggered_count: Number of times this reset line has been reset. Currently
54 * struct reset_control_array - an array of reset controls
55 * @base: reset control for compatibility with reset control API functions
56 * @num_rstcs: number of reset controls
57 * @rstc: array of reset controls
67 if (rcdev->dev) in rcdev_name()
68 return dev_name(rcdev->dev); in rcdev_name()
70 if (rcdev->of_node) in rcdev_name()
71 return rcdev->of_node->full_name; in rcdev_name()
77 * of_reset_simple_xlate - translate reset_spec to the reset line number
78 * @rcdev: a pointer to the reset controller device
79 * @reset_spec: reset line specifier as found in the device tree
82 * :c:type:`reset_controller_dev` is not set. It is useful for all reset
83 * controllers with 1:1 mapping, where reset lines can be indexed by number
89 if (reset_spec->args[0] >= rcdev->nr_resets) in of_reset_simple_xlate()
90 return -EINVAL; in of_reset_simple_xlate()
92 return reset_spec->args[0]; in of_reset_simple_xlate()
96 * reset_controller_register - register a reset controller device
97 * @rcdev: a pointer to the initialized reset controller device
101 if (!rcdev->of_xlate) { in reset_controller_register()
102 rcdev->of_reset_n_cells = 1; in reset_controller_register()
103 rcdev->of_xlate = of_reset_simple_xlate; in reset_controller_register()
106 INIT_LIST_HEAD(&rcdev->reset_control_head); in reset_controller_register()
109 list_add(&rcdev->list, &reset_controller_list); in reset_controller_register()
117 * reset_controller_unregister - unregister a reset controller device
118 * @rcdev: a pointer to the reset controller device
123 list_del(&rcdev->list); in reset_controller_unregister()
134 * devm_reset_controller_register - resource managed reset_controller_register()
135 * @dev: device that is registering this reset controller
136 * @rcdev: a pointer to the initialized reset controller device
138 * Managed reset_controller_register(). For reset controllers registered by
151 return -ENOMEM; in devm_reset_controller_register()
167 * reset_controller_add_lookup - register a set of lookup entries
168 * @lookup: array of reset lookup entries
181 if (!entry->dev_id || !entry->provider) { in reset_controller_add_lookup()
182 pr_warn("%s(): reset lookup entry badly specified, skipping\n", in reset_controller_add_lookup()
187 list_add_tail(&entry->list, &reset_lookup_list); in reset_controller_add_lookup()
202 for (i = 0; i < resets->num_rstcs; i++) { in reset_control_array_reset()
203 ret = reset_control_reset(resets->rstc[i]); in reset_control_array_reset()
215 for (i = 0; i < resets->num_rstcs; i++) { in reset_control_array_assert()
216 ret = reset_control_assert(resets->rstc[i]); in reset_control_array_assert()
224 while (i--) in reset_control_array_assert()
225 reset_control_deassert(resets->rstc[i]); in reset_control_array_assert()
233 for (i = 0; i < resets->num_rstcs; i++) { in reset_control_array_deassert()
234 ret = reset_control_deassert(resets->rstc[i]); in reset_control_array_deassert()
242 while (i--) in reset_control_array_deassert()
243 reset_control_assert(resets->rstc[i]); in reset_control_array_deassert()
252 for (i = 0; i < resets->num_rstcs; i++) { in reset_control_array_acquire()
253 err = reset_control_acquire(resets->rstc[i]); in reset_control_array_acquire()
261 while (i--) in reset_control_array_acquire()
262 reset_control_release(resets->rstc[i]); in reset_control_array_acquire()
271 for (i = 0; i < resets->num_rstcs; i++) in reset_control_array_release()
272 reset_control_release(resets->rstc[i]); in reset_control_array_release()
277 return rstc->array; in reset_control_is_array()
281 * reset_control_reset - reset the controlled device
282 * @rstc: reset controller
284 * On a shared reset line the actual reset pulse is only triggered once for the
286 * a no-op.
287 * Consumers must not use reset_control_(de)assert on shared reset lines when
290 * If rstc is NULL it is an optional reset and the function will just
301 return -EINVAL; in reset_control_reset()
306 if (!rstc->rcdev->ops->reset) in reset_control_reset()
307 return -ENOTSUPP; in reset_control_reset()
309 if (rstc->shared) { in reset_control_reset()
310 if (WARN_ON(atomic_read(&rstc->deassert_count) != 0)) in reset_control_reset()
311 return -EINVAL; in reset_control_reset()
313 if (atomic_inc_return(&rstc->triggered_count) != 1) in reset_control_reset()
316 if (!rstc->acquired) in reset_control_reset()
317 return -EPERM; in reset_control_reset()
320 ret = rstc->rcdev->ops->reset(rstc->rcdev, rstc->id); in reset_control_reset()
321 if (rstc->shared && ret) in reset_control_reset()
322 atomic_dec(&rstc->triggered_count); in reset_control_reset()
329 * reset_control_assert - asserts the reset line
330 * @rstc: reset controller
332 * Calling this on an exclusive reset controller guarantees that the reset
333 * will be asserted. When called on a shared reset controller the line may
336 * For shared reset controls a driver cannot expect the hw's registers and
337 * internal state to be reset, but must be prepared for this to happen.
338 * Consumers must not use reset_control_reset on shared reset lines when
341 * If rstc is NULL it is an optional reset and the function will just
350 return -EINVAL; in reset_control_assert()
355 if (rstc->shared) { in reset_control_assert()
356 if (WARN_ON(atomic_read(&rstc->triggered_count) != 0)) in reset_control_assert()
357 return -EINVAL; in reset_control_assert()
359 if (WARN_ON(atomic_read(&rstc->deassert_count) == 0)) in reset_control_assert()
360 return -EINVAL; in reset_control_assert()
362 if (atomic_dec_return(&rstc->deassert_count) != 0) in reset_control_assert()
366 * Shared reset controls allow the reset line to be in any state in reset_control_assert()
369 if (!rstc->rcdev->ops->assert) in reset_control_assert()
373 * If the reset controller does not implement .assert(), there in reset_control_assert()
374 * is no way to guarantee that the reset line is asserted after in reset_control_assert()
377 if (!rstc->rcdev->ops->assert) in reset_control_assert()
378 return -ENOTSUPP; in reset_control_assert()
380 if (!rstc->acquired) { in reset_control_assert()
381 WARN(1, "reset %s (ID: %u) is not acquired\n", in reset_control_assert()
382 rcdev_name(rstc->rcdev), rstc->id); in reset_control_assert()
383 return -EPERM; in reset_control_assert()
387 return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id); in reset_control_assert()
392 * reset_control_deassert - deasserts the reset line
393 * @rstc: reset controller
395 * After calling this function, the reset is guaranteed to be deasserted.
396 * Consumers must not use reset_control_reset on shared reset lines when
399 * If rstc is NULL it is an optional reset and the function will just
408 return -EINVAL; in reset_control_deassert()
413 if (rstc->shared) { in reset_control_deassert()
414 if (WARN_ON(atomic_read(&rstc->triggered_count) != 0)) in reset_control_deassert()
415 return -EINVAL; in reset_control_deassert()
417 if (atomic_inc_return(&rstc->deassert_count) != 1) in reset_control_deassert()
420 if (!rstc->acquired) { in reset_control_deassert()
421 WARN(1, "reset %s (ID: %u) is not acquired\n", in reset_control_deassert()
422 rcdev_name(rstc->rcdev), rstc->id); in reset_control_deassert()
423 return -EPERM; in reset_control_deassert()
428 * If the reset controller does not implement .deassert(), we assume in reset_control_deassert()
429 * that it handles self-deasserting reset lines via .reset(). In that in reset_control_deassert()
430 * case, the reset lines are deasserted by default. If that is not the in reset_control_deassert()
431 * case, the reset controller driver should implement .deassert() and in reset_control_deassert()
432 * return -ENOTSUPP. in reset_control_deassert()
434 if (!rstc->rcdev->ops->deassert) in reset_control_deassert()
437 return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id); in reset_control_deassert()
442 * reset_control_status - returns a negative errno if not supported, a
443 * positive value if the reset line is asserted, or zero if the reset
444 * line is not asserted or if the desc is NULL (optional reset).
445 * @rstc: reset controller
453 return -EINVAL; in reset_control_status()
455 if (rstc->rcdev->ops->status) in reset_control_status()
456 return rstc->rcdev->ops->status(rstc->rcdev, rstc->id); in reset_control_status()
458 return -ENOTSUPP; in reset_control_status()
463 * reset_control_acquire() - acquires a reset control for exclusive use
464 * @rstc: reset control
466 * This is used to explicitly acquire a reset control for exclusive use. Note
468 * second consumer to be able to control the reset, the first consumer has to
470 * reset_control_get_exclusive_released() to obtain an instance of the reset
471 * control. Such reset controls are not acquired by default.
473 * Consumers implementing shared access to an exclusive reset need to follow
475 * a reset they must acquire exclusive access using reset_control_acquire().
476 * After they are done operating the reset, they must release exclusive access
478 * access to the reset as long as another consumer hasn't released a reset.
490 return -EINVAL; in reset_control_acquire()
497 if (rstc->acquired) { in reset_control_acquire()
502 list_for_each_entry(rc, &rstc->rcdev->reset_control_head, list) { in reset_control_acquire()
503 if (rstc != rc && rstc->id == rc->id) { in reset_control_acquire()
504 if (rc->acquired) { in reset_control_acquire()
506 return -EBUSY; in reset_control_acquire()
511 rstc->acquired = true; in reset_control_acquire()
519 * reset_control_release() - releases exclusive access to a reset control
520 * @rstc: reset control
522 * Releases exclusive access right to a reset control previously obtained by a
536 rstc->acquired = false; in reset_control_release()
548 list_for_each_entry(rstc, &rcdev->reset_control_head, list) { in __reset_control_get_internal()
549 if (rstc->id == index) { in __reset_control_get_internal()
553 * controlled reset line. in __reset_control_get_internal()
555 if (!rstc->shared && !shared && !acquired) in __reset_control_get_internal()
558 if (WARN_ON(!rstc->shared || !shared)) in __reset_control_get_internal()
559 return ERR_PTR(-EBUSY); in __reset_control_get_internal()
561 kref_get(&rstc->refcnt); in __reset_control_get_internal()
568 return ERR_PTR(-ENOMEM); in __reset_control_get_internal()
570 try_module_get(rcdev->owner); in __reset_control_get_internal()
572 rstc->rcdev = rcdev; in __reset_control_get_internal()
573 list_add(&rstc->list, &rcdev->reset_control_head); in __reset_control_get_internal()
574 rstc->id = index; in __reset_control_get_internal()
575 kref_init(&rstc->refcnt); in __reset_control_get_internal()
576 rstc->acquired = acquired; in __reset_control_get_internal()
577 rstc->shared = shared; in __reset_control_get_internal()
589 module_put(rstc->rcdev->owner); in __reset_control_release()
591 list_del(&rstc->list); in __reset_control_release()
599 kref_put(&rstc->refcnt, __reset_control_release); in __reset_control_put_internal()
613 return ERR_PTR(-EINVAL); in __of_reset_control_get()
617 "reset-names", id); in __of_reset_control_get()
618 if (index == -EILSEQ) in __of_reset_control_get()
621 return optional ? NULL : ERR_PTR(-ENOENT); in __of_reset_control_get()
624 ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", in __of_reset_control_get()
626 if (ret == -EINVAL) in __of_reset_control_get()
634 if (args.np == r->of_node) { in __of_reset_control_get()
641 rstc = ERR_PTR(-EPROBE_DEFER); in __of_reset_control_get()
645 if (WARN_ON(args.args_count != rcdev->of_reset_n_cells)) { in __of_reset_control_get()
646 rstc = ERR_PTR(-EINVAL); in __of_reset_control_get()
650 rstc_id = rcdev->of_xlate(rcdev, &args); in __of_reset_control_get()
675 if (!rcdev->dev) in __reset_controller_by_name()
678 if (!strcmp(name, dev_name(rcdev->dev))) in __reset_controller_by_name()
697 if (strcmp(lookup->dev_id, dev_id)) in __reset_control_get_from_lookup()
700 if ((!con_id && !lookup->con_id) || in __reset_control_get_from_lookup()
701 ((con_id && lookup->con_id) && in __reset_control_get_from_lookup()
702 !strcmp(con_id, lookup->con_id))) { in __reset_control_get_from_lookup()
704 rcdev = __reset_controller_by_name(lookup->provider); in __reset_control_get_from_lookup()
708 /* Reset provider may not be ready yet. */ in __reset_control_get_from_lookup()
709 return ERR_PTR(-EPROBE_DEFER); in __reset_control_get_from_lookup()
713 lookup->index, in __reset_control_get_from_lookup()
723 return optional ? NULL : ERR_PTR(-ENOENT); in __reset_control_get_from_lookup()
733 return ERR_PTR(-EINVAL); in __reset_control_get()
735 if (dev->of_node) in __reset_control_get()
736 return __of_reset_control_get(dev->of_node, id, index, shared, in __reset_control_get()
749 for (i = 0; i < resets->num_rstcs; i++) in reset_control_array_put()
750 __reset_control_put_internal(resets->rstc[i]); in reset_control_array_put()
756 * reset_control_put - free the reset controller
757 * @rstc: reset controller
789 return ERR_PTR(-ENOMEM); in __devm_reset_control_get()
805 * device_reset - find reset controller associated with the device
806 * and perform reset
807 * @dev: device to be reset by the controller
808 * @optional: whether it is optional to reset the device
811 * This is useful for the common case of devices with single, dedicated reset
832 * APIs to manage an array of reset controls.
836 * of_reset_control_get_count - Count number of resets available with a device
840 * Returns positive reset count on success, or error number on failure and
848 return -EINVAL; in of_reset_control_get_count()
850 count = of_count_phandle_with_args(node, "resets", "#reset-cells"); in of_reset_control_get_count()
852 count = -ENOENT; in of_reset_control_get_count()
858 * of_reset_control_array_get - Get a list of reset controls using
861 * @np: device node for the device that requests the reset controls array
862 * @shared: whether reset controls are shared or not
863 * @optional: whether it is optional to get the reset controls
864 * @acquired: only one reset control may be acquired for a given controller
883 return ERR_PTR(-ENOMEM); in of_reset_control_array_get()
890 resets->rstc[i] = rstc; in of_reset_control_array_get()
892 resets->num_rstcs = num; in of_reset_control_array_get()
893 resets->base.array = true; in of_reset_control_array_get()
895 return &resets->base; in of_reset_control_array_get()
899 while (--i >= 0) in of_reset_control_array_get()
900 __reset_control_put_internal(resets->rstc[i]); in of_reset_control_array_get()
910 * devm_reset_control_array_get - Resource managed reset control array get
912 * @dev: device that requests the list of reset controls
913 * @shared: whether reset controls are shared or not
914 * @optional: whether it is optional to get the reset controls
916 * The reset control array APIs are intended for a list of resets
930 return ERR_PTR(-ENOMEM); in devm_reset_control_array_get()
932 rstc = of_reset_control_array_get(dev->of_node, shared, optional, true); in devm_reset_control_array_get()
952 return -EINVAL; in reset_control_get_count_from_lookup()
958 if (!strcmp(lookup->dev_id, dev_id)) in reset_control_get_count_from_lookup()
965 count = -ENOENT; in reset_control_get_count_from_lookup()
971 * reset_control_get_count - Count number of resets available with a device
975 * Returns positive reset count on success, or error number on failure and
980 if (dev->of_node) in reset_control_get_count()
981 return of_reset_control_get_count(dev->of_node); in reset_control_get_count()