diff options
23 files changed, 1217 insertions, 402 deletions
diff --git a/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml b/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml index c1b800a10b53..66650ef8f772 100644 --- a/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml +++ b/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml @@ -17,7 +17,9 @@ properties: compatible: oneOf: - items: - - const: renesas,r9a09g056-usb2phy-reset # RZ/V2N + - enum: + - renesas,r9a09g047-usb2phy-reset # RZ/G3E + - renesas,r9a09g056-usb2phy-reset # RZ/V2N - const: renesas,r9a09g057-usb2phy-reset - const: renesas,r9a09g057-usb2phy-reset # RZ/V2H(P) @@ -37,6 +39,9 @@ properties: '#reset-cells': const: 0 + '#mux-state-cells': + const: 1 + required: - compatible - reg @@ -44,6 +49,7 @@ required: - resets - power-domains - '#reset-cells' + - '#mux-state-cells' additionalProperties: false @@ -58,4 +64,5 @@ examples: resets = <&cpg 0xaf>; power-domains = <&cpg>; #reset-cells = <0>; + #mux-state-cells = <1>; }; diff --git a/Documentation/devicetree/bindings/soc/cix/cix,sky1-system-control.yaml b/Documentation/devicetree/bindings/soc/cix/cix,sky1-system-control.yaml new file mode 100644 index 000000000000..a01a515222c6 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/cix/cix,sky1-system-control.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/cix/cix,sky1-system-control.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cix Sky1 SoC system control register region + +maintainers: + - Gary Yang <gary.yang@cixtech.com> + +description: + An wide assortment of registers of the system controller on Sky1 SoC, + including resets, usb, wakeup sources and so on. + +properties: + compatible: + items: + - enum: + - cix,sky1-system-control + - cix,sky1-s5-system-control + - const: syscon + + reg: + maxItems: 1 + + '#reset-cells': + const: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + syscon@4160000 { + compatible = "cix,sky1-system-control", "syscon"; + reg = <0x4160000 0x100>; + #reset-cells = <1>; + }; diff --git a/Documentation/driver-api/reset.rst b/Documentation/driver-api/reset.rst index f773100daaa4..7a6571849664 100644 --- a/Documentation/driver-api/reset.rst +++ b/Documentation/driver-api/reset.rst @@ -198,7 +198,6 @@ query the reset line status using reset_control_status(). reset_control_rearm reset_control_put of_reset_control_get_count - of_reset_control_array_get devm_reset_control_array_get reset_control_get_count diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 7ce151f6a7e4..2fda1d9622f4 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -257,6 +257,8 @@ config RESET_RZG2L_USBPHY_CTRL config RESET_RZV2H_USB2PHY tristate "Renesas RZ/V2H(P) (and similar SoCs) USB2PHY Reset driver" depends on ARCH_RENESAS || COMPILE_TEST + select AUXILIARY_BUS + select REGMAP_MMIO help Support for USB2PHY Port reset Control found on the RZ/V2H(P) SoC (and similar SoCs). @@ -291,6 +293,13 @@ config RESET_SIMPLE - SiFive FU740 SoCs - Sophgo SoCs +config RESET_SKY1 + bool "Cix Sky1 reset controller" + depends on ARCH_CIX || COMPILE_TEST + select REGMAP_MMIO + help + This enables the reset controller for Cix Sky1. + config RESET_SOCFPGA bool "SoCFPGA Reset Driver" if COMPILE_TEST && (!ARM || !ARCH_INTEL_SOCFPGA) default ARM && ARCH_INTEL_SOCFPGA diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index fc0cc99f8514..d1b8c66e5086 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o obj-$(CONFIG_RESET_RZV2H_USB2PHY) += reset-rzv2h-usb2phy.o obj-$(CONFIG_RESET_SCMI) += reset-scmi.o obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o +obj-$(CONFIG_RESET_SKY1) += reset-sky1.o obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o diff --git a/drivers/reset/core.c b/drivers/reset/core.c index fceec45c8afc..38e189d04d09 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -12,6 +12,7 @@ #include <linux/device.h> #include <linux/err.h> #include <linux/export.h> +#include <linux/fwnode.h> #include <linux/gpio/driver.h> #include <linux/gpio/machine.h> #include <linux/gpio/property.h> @@ -20,9 +21,11 @@ #include <linux/kref.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/property.h> #include <linux/reset.h> #include <linux/reset-controller.h> #include <linux/slab.h> +#include <linux/srcu.h> static DEFINE_MUTEX(reset_list_mutex); static LIST_HEAD(reset_controller_list); @@ -36,6 +39,7 @@ static DEFINE_IDA(reset_gpio_ida); * struct reset_control - a reset control * @rcdev: a pointer to the reset controller device * this reset control belongs to + * @srcu: protects the rcdev pointer from removal during consumer access * @list: list entry for the rcdev's reset controller list * @id: ID of the reset controller in the reset * controller device @@ -47,9 +51,11 @@ static DEFINE_IDA(reset_gpio_ida); * @triggered_count: Number of times this reset line has been reset. Currently * only used for shared resets, which means that the value * will be either 0 or 1. + * @lock: serializes the internals of reset_control_acquire() */ struct reset_control { - struct reset_controller_dev *rcdev; + struct reset_controller_dev __rcu *rcdev; + struct srcu_struct srcu; struct list_head list; unsigned int id; struct kref refcnt; @@ -58,6 +64,7 @@ struct reset_control { bool array; atomic_t deassert_count; atomic_t triggered_count; + struct mutex lock; }; /** @@ -74,14 +81,16 @@ struct reset_control_array { /** * struct reset_gpio_lookup - lookup key for ad-hoc created reset-gpio devices - * @of_args: phandle to the reset controller with all the args like GPIO number + * @ref_args: Reference to the reset controller with all the args like GPIO number * @swnode: Software node containing the reference to the GPIO provider * @list: list entry for the reset_gpio_lookup_list + * @adev: Auxiliary device representing the reset controller */ struct reset_gpio_lookup { - struct of_phandle_args of_args; + struct fwnode_reference_args ref_args; struct fwnode_handle *swnode; struct list_head list; + struct auxiliary_device adev; }; static const char *rcdev_name(struct reset_controller_dev *rcdev) @@ -89,27 +98,24 @@ static const char *rcdev_name(struct reset_controller_dev *rcdev) if (rcdev->dev) return dev_name(rcdev->dev); - if (rcdev->of_node) - return rcdev->of_node->full_name; - - if (rcdev->of_args) - return rcdev->of_args->np->full_name; + if (rcdev->fwnode) + return fwnode_get_name(rcdev->fwnode); return NULL; } /** - * of_reset_simple_xlate - translate reset_spec to the reset line number + * fwnode_reset_simple_xlate - translate reset_spec to the reset line number * @rcdev: a pointer to the reset controller device - * @reset_spec: reset line specifier as found in the device tree + * @reset_spec: reset line specifier as found in firmware * - * This static translation function is used by default if of_xlate in - * :c:type:`reset_controller_dev` is not set. It is useful for all reset - * controllers with 1:1 mapping, where reset lines can be indexed by number - * without gaps. + * This static translation function is used by default if neither fwnode_xlate + * not of_xlate in :c:type:`reset_controller_dev` is not set. It is useful for + * all reset controllers with 1:1 mapping, where reset lines can be indexed by + * number without gaps. */ -static int of_reset_simple_xlate(struct reset_controller_dev *rcdev, - const struct of_phandle_args *reset_spec) +static int fwnode_reset_simple_xlate(struct reset_controller_dev *rcdev, + const struct fwnode_reference_args *reset_spec) { if (reset_spec->args[0] >= rcdev->nr_resets) return -EINVAL; @@ -123,33 +129,71 @@ static int of_reset_simple_xlate(struct reset_controller_dev *rcdev, */ int reset_controller_register(struct reset_controller_dev *rcdev) { - if (rcdev->of_node && rcdev->of_args) + if ((rcdev->of_node && rcdev->fwnode) || (rcdev->of_xlate && rcdev->fwnode_xlate)) return -EINVAL; - if (!rcdev->of_xlate) { - rcdev->of_reset_n_cells = 1; - rcdev->of_xlate = of_reset_simple_xlate; + if (rcdev->of_node && !rcdev->fwnode) + rcdev->fwnode = of_fwnode_handle(rcdev->of_node); + + if (!rcdev->fwnode) { + rcdev->fwnode = dev_fwnode(rcdev->dev); + if (!rcdev->fwnode) + return -EINVAL; + } + + if (rcdev->of_xlate) + rcdev->fwnode_reset_n_cells = rcdev->of_reset_n_cells; + + if (!rcdev->fwnode_xlate && !rcdev->of_xlate) { + rcdev->fwnode_xlate = fwnode_reset_simple_xlate; + rcdev->fwnode_reset_n_cells = 1; } INIT_LIST_HEAD(&rcdev->reset_control_head); + mutex_init(&rcdev->lock); + + guard(mutex)(&reset_list_mutex); - mutex_lock(&reset_list_mutex); list_add(&rcdev->list, &reset_controller_list); - mutex_unlock(&reset_list_mutex); return 0; } EXPORT_SYMBOL_GPL(reset_controller_register); +static void reset_controller_remove(struct reset_controller_dev *rcdev, + struct reset_control *rstc) +{ + lockdep_assert_held(&rcdev->lock); + + list_del(&rstc->list); + module_put(rcdev->owner); + put_device(rcdev->dev); +} + /** * reset_controller_unregister - unregister a reset controller device * @rcdev: a pointer to the reset controller device */ void reset_controller_unregister(struct reset_controller_dev *rcdev) { - mutex_lock(&reset_list_mutex); - list_del(&rcdev->list); - mutex_unlock(&reset_list_mutex); + struct reset_control *rstc, *pos; + + scoped_guard(mutex, &reset_list_mutex) + list_del(&rcdev->list); + + scoped_guard(mutex, &rcdev->lock) { + /* + * Numb but don't free the remaining reset control handles that are + * still held by consumers. + */ + list_for_each_entry_safe(rstc, pos, &rcdev->reset_control_head, list) { + rcu_assign_pointer(rstc->rcdev, NULL); + synchronize_srcu(&rstc->srcu); + reset_controller_remove(rcdev, rstc); + } + } + + mutex_destroy(&rcdev->lock); } EXPORT_SYMBOL_GPL(reset_controller_unregister); @@ -326,6 +370,7 @@ static inline bool reset_control_is_array(struct reset_control *rstc) */ int reset_control_reset(struct reset_control *rstc) { + struct reset_controller_dev *rcdev; int ret; if (!rstc) @@ -337,7 +382,13 @@ int reset_control_reset(struct reset_control *rstc) if (reset_control_is_array(rstc)) return reset_control_array_reset(rstc_to_array(rstc)); - if (!rstc->rcdev->ops->reset) + guard(srcu)(&rstc->srcu); + + rcdev = srcu_dereference(rstc->rcdev, &rstc->srcu); + if (!rcdev) + return -ENODEV; + + if (!rcdev->ops->reset) return -ENOTSUPP; if (rstc->shared) { @@ -351,7 +402,7 @@ int reset_control_reset(struct reset_control *rstc) return -EPERM; } - ret = rstc->rcdev->ops->reset(rstc->rcdev, rstc->id); + ret = rcdev->ops->reset(rcdev, rstc->id); if (rstc->shared && ret) atomic_dec(&rstc->triggered_count); @@ -384,7 +435,7 @@ int reset_control_bulk_reset(int num_rstcs, EXPORT_SYMBOL_GPL(reset_control_bulk_reset); /** - * reset_control_rearm - allow shared reset line to be re-triggered" + * reset_control_rearm - allow shared reset line to be re-triggered * @rstc: reset controller * * On a shared reset line the actual reset pulse is only triggered once for the @@ -441,6 +492,8 @@ EXPORT_SYMBOL_GPL(reset_control_rearm); */ int reset_control_assert(struct reset_control *rstc) { + struct reset_controller_dev *rcdev; + if (!rstc) return 0; @@ -450,6 +503,12 @@ int reset_control_assert(struct reset_control *rstc) if (reset_control_is_array(rstc)) return reset_control_array_assert(rstc_to_array(rstc)); + guard(srcu)(&rstc->srcu); + + rcdev = srcu_dereference(rstc->rcdev, &rstc->srcu); + if (!rcdev) + return -ENODEV; + if (rstc->shared) { if (WARN_ON(atomic_read(&rstc->triggered_count) != 0)) return -EINVAL; @@ -464,7 +523,7 @@ int reset_control_assert(struct reset_control *rstc) * Shared reset controls allow the reset line to be in any state * after this call, so doing nothing is a valid option. */ - if (!rstc->rcdev->ops->assert) + if (!rcdev->ops->assert) return 0; } else { /* @@ -472,17 +531,17 @@ int reset_control_assert(struct reset_control *rstc) * is no way to guarantee that the reset line is asserted after * this call. */ - if (!rstc->rcdev->ops->assert) + if (!rcdev->ops->assert) return -ENOTSUPP; if (!rstc->acquired) { WARN(1, "reset %s (ID: %u) is not acquired\n", - rcdev_name(rstc->rcdev), rstc->id); + rcdev_name(rcdev), rstc->id); return -EPERM; } } - return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id); + return rcdev->ops->assert(rcdev, rstc->id); } EXPORT_SYMBOL_GPL(reset_control_assert); @@ -529,6 +588,8 @@ EXPORT_SYMBOL_GPL(reset_control_bulk_assert); */ int reset_control_deassert(struct reset_control *rstc) { + struct reset_controller_dev *rcdev; + if (!rstc) return 0; @@ -538,6 +599,12 @@ int reset_control_deassert(struct reset_control *rstc) if (reset_control_is_array(rstc)) return reset_control_array_deassert(rstc_to_array(rstc)); + guard(srcu)(&rstc->srcu); + + rcdev = srcu_dereference(rstc->rcdev, &rstc->srcu); + if (!rcdev) + return -ENODEV; + if (rstc->shared) { if (WARN_ON(atomic_read(&rstc->triggered_count) != 0)) return -EINVAL; @@ -547,7 +614,7 @@ int reset_control_deassert(struct reset_control *rstc) } else { if (!rstc->acquired) { WARN(1, "reset %s (ID: %u) is not acquired\n", - rcdev_name(rstc->rcdev), rstc->id); + rcdev_name(rcdev), rstc->id); return -EPERM; } } @@ -559,10 +626,10 @@ int reset_control_deassert(struct reset_control *rstc) * case, the reset controller driver should implement .deassert() and * return -ENOTSUPP. */ - if (!rstc->rcdev->ops->deassert) + if (!rcdev->ops->deassert) return 0; - return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id); + return rcdev->ops->deassert(rcdev, rstc->id); } EXPORT_SYMBOL_GPL(reset_control_deassert); @@ -604,14 +671,22 @@ EXPORT_SYMBOL_GPL(reset_control_bulk_deassert); */ int reset_control_status(struct reset_control *rstc) { + struct reset_controller_dev *rcdev; + if (!rstc) return 0; if (WARN_ON(IS_ERR(rstc)) || reset_control_is_array(rstc)) return -EINVAL; - if (rstc->rcdev->ops->status) - return rstc->rcdev->ops->status(rstc->rcdev, rstc->id); + guard(srcu)(&rstc->srcu); + + rcdev = srcu_dereference(rstc->rcdev, &rstc->srcu); + if (!rcdev) + return -ENODEV; + + if (rcdev->ops->status) + return rcdev->ops->status(rcdev, rstc->id); return -ENOTSUPP; } @@ -639,6 +714,7 @@ EXPORT_SYMBOL_GPL(reset_control_status); */ int reset_control_acquire(struct reset_control *rstc) { + struct reset_controller_dev *rcdev; struct reset_control *rc; if (!rstc) @@ -650,25 +726,28 @@ int reset_control_acquire(struct reset_control *rstc) if (reset_control_is_array(rstc)) return reset_control_array_acquire(rstc_to_array(rstc)); - mutex_lock(&reset_list_mutex); + guard(mutex)(&rstc->lock); - if (rstc->acquired) { - mutex_unlock(&reset_list_mutex); + if (rstc->acquired) return 0; - } - list_for_each_entry(rc, &rstc->rcdev->reset_control_head, list) { - if (rstc != rc && rstc->id == rc->id) { - if (rc->acquired) { - mutex_unlock(&reset_list_mutex); - return -EBUSY; + guard(srcu)(&rstc->srcu); + + rcdev = srcu_dereference(rstc->rcdev, &rstc->srcu); + if (!rcdev) + return -ENODEV; + + scoped_guard(mutex, &rcdev->lock) { + list_for_each_entry(rc, &rcdev->reset_control_head, list) { + if (rstc != rc && rstc->id == rc->id) { + if (rc->acquired) + return -EBUSY; } } } rstc->acquired = true; - mutex_unlock(&reset_list_mutex); return 0; } EXPORT_SYMBOL_GPL(reset_control_acquire); @@ -752,8 +831,9 @@ __reset_control_get_internal(struct reset_controller_dev *rcdev, bool shared = flags & RESET_CONTROL_FLAGS_BIT_SHARED; bool acquired = flags & RESET_CONTROL_FLAGS_BIT_ACQUIRED; struct reset_control *rstc; + int ret; - lockdep_assert_held(&reset_list_mutex); + lockdep_assert_held(&rcdev->lock); /* Expect callers to filter out OPTIONAL and DEASSERTED bits */ if (WARN_ON(flags & ~(RESET_CONTROL_FLAGS_BIT_SHARED | @@ -782,15 +862,23 @@ __reset_control_get_internal(struct reset_controller_dev *rcdev, if (!rstc) return ERR_PTR(-ENOMEM); + ret = init_srcu_struct(&rstc->srcu); + if (ret) { + kfree(rstc); + return ERR_PTR(ret); + } + if (!try_module_get(rcdev->owner)) { + cleanup_srcu_struct(&rstc->srcu); kfree(rstc); return ERR_PTR(-ENODEV); } - rstc->rcdev = rcdev; + rcu_assign_pointer(rstc->rcdev, rcdev); list_add(&rstc->list, &rcdev->reset_control_head); rstc->id = index; kref_init(&rstc->refcnt); + mutex_init(&rstc->lock); rstc->acquired = acquired; rstc->shared = shared; get_device(rcdev->dev); @@ -802,77 +890,133 @@ static void __reset_control_release(struct kref *kref) { struct reset_control *rstc = container_of(kref, struct reset_control, refcnt); + struct reset_controller_dev *rcdev; - lockdep_assert_held(&reset_list_mutex); + lockdep_assert_held(&rstc->srcu); - module_put(rstc->rcdev->owner); + rcdev = rcu_replace_pointer(rstc->rcdev, NULL, true); + if (rcdev) { + lockdep_assert_held(&rcdev->lock); + reset_controller_remove(rcdev, rstc); + } - list_del(&rstc->list); - put_device(rstc->rcdev->dev); - kfree(rstc); + mutex_destroy(&rstc->lock); } -static void __reset_control_put_internal(struct reset_control *rstc) +static void reset_control_put_internal(struct reset_control *rstc) { - lockdep_assert_held(&reset_list_mutex); + struct reset_controller_dev *rcdev; + int ret = 0; if (IS_ERR_OR_NULL(rstc)) return; - kref_put(&rstc->refcnt, __reset_control_release); + scoped_guard(srcu, &rstc->srcu) { + rcdev = srcu_dereference(rstc->rcdev, &rstc->srcu); + if (!rcdev) + /* Already released. */ + return; + + guard(mutex)(&rcdev->lock); + ret = kref_put(&rstc->refcnt, __reset_control_release); + } + + if (ret) { + synchronize_srcu(&rstc->srcu); + cleanup_srcu_struct(&rstc->srcu); + kfree(rstc); + } } static void reset_gpio_aux_device_release(struct device *dev) { - struct auxiliary_device *adev = to_auxiliary_dev(dev); - - kfree(adev); + WARN(1, "reset-gpio device %s should never have been removed", dev_name(dev)); } -static int reset_add_gpio_aux_device(struct device *parent, - struct fwnode_handle *swnode, - int id, void *pdata) +static int reset_create_gpio_aux_device(struct reset_gpio_lookup *rgpio_dev, + struct device *parent) { - struct auxiliary_device *adev; - int ret; + struct auxiliary_device *adev = &rgpio_dev->adev; + int ret, id; - adev = kzalloc_obj(*adev); - if (!adev) + id = ida_alloc(&reset_gpio_ida, GFP_KERNEL); + if (id < 0) return -ENOMEM; adev->id = id; adev->name = "gpio"; adev->dev.parent = parent; - adev->dev.platform_data = pdata; + adev->dev.platform_data = &rgpio_dev->ref_args; adev->dev.release = reset_gpio_aux_device_release; - device_set_node(&adev->dev, swnode); + device_set_node(&adev->dev, rgpio_dev->swnode); ret = auxiliary_device_init(adev); if (ret) { - kfree(adev); + ida_free(&reset_gpio_ida, id); return ret; } ret = __auxiliary_device_add(adev, "reset"); if (ret) { auxiliary_device_uninit(adev); - kfree(adev); + ida_free(&reset_gpio_ida, id); return ret; } - return ret; + return 0; +} + +static void reset_gpio_add_devlink(struct fwnode_handle *fwnode, + struct reset_gpio_lookup *rgpio_dev) +{ + struct device *consumer; + + /* + * We must use get_dev_from_fwnode() and not ref_find_device_by_node() + * because the latter only considers the platform bus while we want to + * get consumers of any kind that can be associated with firmware + * nodes: auxiliary, soundwire, etc. + */ + consumer = get_dev_from_fwnode(fwnode); + if (consumer) { + if (!device_link_add(consumer, &rgpio_dev->adev.dev, + DL_FLAG_AUTOREMOVE_CONSUMER)) + pr_warn("Failed to create a device link between reset-gpio and its consumer"); + + put_device(consumer); + } + /* + * else { } + * + * TODO: If ever there's a case where we need to support shared + * reset-gpios retrieved from a device node for which there's no + * device present yet, this is where we'd set up a notifier waiting + * for the device to appear in the system. This would be a lot of code + * that would go unused for now so let's cross that bridge when and if + * we get there. + */ +} + +/* TODO: move it out into drivers/base/ */ +static bool fwnode_reference_args_equal(const struct fwnode_reference_args *left, + const struct fwnode_reference_args *right) +{ + return left->fwnode == right->fwnode && left->nargs == right->nargs && + !memcmp(left->args, right->args, sizeof(left->args[0]) * left->nargs); } /* - * @args: phandle to the GPIO provider with all the args like GPIO number + * @np: OF-node associated with the consumer + * @args: Reference to the GPIO provider with all the args like GPIO number */ -static int __reset_add_reset_gpio_device(const struct of_phandle_args *args) +static int __reset_add_reset_gpio_device(struct fwnode_handle *fwnode, + const struct fwnode_reference_args *args) { struct property_entry properties[3] = { }; - unsigned int offset, of_flags, lflags; + unsigned int offset, flags, lflags; struct reset_gpio_lookup *rgpio_dev; struct device *parent; - int id, ret, prop = 0; + int ret, prop = 0; /* * Currently only #gpio-cells=2 is supported with the meaning of: @@ -880,7 +1024,7 @@ static int __reset_add_reset_gpio_device(const struct of_phandle_args *args) * args[1]: GPIO flags * TODO: Handle other cases. */ - if (args->args_count != 2) + if (args->nargs != 2) return -ENOENT; /* @@ -891,7 +1035,7 @@ static int __reset_add_reset_gpio_device(const struct of_phandle_args *args) lockdep_assert_not_held(&reset_list_mutex); offset = args->args[0]; - of_flags = args->args[1]; + flags = args->args[1]; /* * Later we map GPIO flags between OF and Linux, however not all @@ -901,90 +1045,89 @@ static int __reset_add_reset_gpio_device(const struct of_phandle_args *args) * FIXME: Find a better way of translating OF flags to GPIO lookup * flags. */ - if (of_flags > GPIO_ACTIVE_LOW) { + if (flags > GPIO_ACTIVE_LOW) { pr_err("reset-gpio code does not support GPIO flags %u for GPIO %u\n", - of_flags, offset); + flags, offset); return -EINVAL; } struct gpio_device *gdev __free(gpio_device_put) = - gpio_device_find_by_fwnode(of_fwnode_handle(args->np)); + gpio_device_find_by_fwnode(args->fwnode); if (!gdev) return -EPROBE_DEFER; guard(mutex)(&reset_gpio_lookup_mutex); list_for_each_entry(rgpio_dev, &reset_gpio_lookup_list, list) { - if (args->np == rgpio_dev->of_args.np) { - if (of_phandle_args_equal(args, &rgpio_dev->of_args)) - return 0; /* Already on the list, done */ + if (fwnode_reference_args_equal(args, &rgpio_dev->ref_args)) { + /* + * Already on the list, create the device link + * and stop here. + */ + reset_gpio_add_devlink(fwnode, rgpio_dev); + return 0; } } - lflags = GPIO_PERSISTENT | (of_flags & GPIO_ACTIVE_LOW); + lflags = GPIO_PERSISTENT | (flags & GPIO_ACTIVE_LOW); parent = gpio_device_to_device(gdev); properties[prop++] = PROPERTY_ENTRY_STRING("compatible", "reset-gpio"); properties[prop++] = PROPERTY_ENTRY_GPIO("reset-gpios", parent->fwnode, offset, lflags); - id = ida_alloc(&reset_gpio_ida, GFP_KERNEL); - if (id < 0) - return id; - /* Not freed on success, because it is persisent subsystem data. */ rgpio_dev = kzalloc_obj(*rgpio_dev); - if (!rgpio_dev) { - ret = -ENOMEM; - goto err_ida_free; - } + if (!rgpio_dev) + return -ENOMEM; - rgpio_dev->of_args = *args; + rgpio_dev->ref_args = *args; /* - * We keep the device_node reference, but of_args.np is put at the end - * of __of_reset_control_get(), so get it one more time. + * We keep the fwnode_handle reference, but ref_args.fwnode is put at + * the end of __fwnode_reset_control_get(), so get it one more time. * Hold reference as long as rgpio_dev memory is valid. */ - of_node_get(rgpio_dev->of_args.np); + fwnode_handle_get(rgpio_dev->ref_args.fwnode); rgpio_dev->swnode = fwnode_create_software_node(properties, NULL); if (IS_ERR(rgpio_dev->swnode)) { ret = PTR_ERR(rgpio_dev->swnode); - goto err_put_of_node; + goto err_put_fwnode; } - ret = reset_add_gpio_aux_device(parent, rgpio_dev->swnode, id, - &rgpio_dev->of_args); + ret = reset_create_gpio_aux_device(rgpio_dev, parent); if (ret) goto err_del_swnode; + reset_gpio_add_devlink(fwnode, rgpio_dev); list_add(&rgpio_dev->list, &reset_gpio_lookup_list); return 0; err_del_swnode: fwnode_remove_software_node(rgpio_dev->swnode); -err_put_of_node: - of_node_put(rgpio_dev->of_args.np); +err_put_fwnode: + fwnode_handle_put(rgpio_dev->ref_args.fwnode); kfree(rgpio_dev); -err_ida_free: - ida_free(&reset_gpio_ida, id); return ret; } -static struct reset_controller_dev *__reset_find_rcdev(const struct of_phandle_args *args, - bool gpio_fallback) +static struct reset_controller_dev * +__reset_find_rcdev(const struct fwnode_reference_args *args, bool gpio_fallback) { + struct fwnode_reference_args *rc_args; struct reset_controller_dev *rcdev; lockdep_assert_held(&reset_list_mutex); list_for_each_entry(rcdev, &reset_controller_list, list) { - if (gpio_fallback) { - if (rcdev->of_args && of_phandle_args_equal(args, - rcdev->of_args)) + if (gpio_fallback && rcdev->dev && + device_is_compatible(rcdev->dev, "reset-gpio")) { + rc_args = dev_get_platdata(rcdev->dev); + + if (fwnode_reference_args_equal(args, rc_args)) return rcdev; } else { - if (args->np == rcdev->of_node) + if (args->fwnode == rcdev->fwnode) return rcdev; } } @@ -993,31 +1136,31 @@ 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, - enum reset_control_flags flags) +__fwnode_reset_control_get(struct fwnode_handle *fwnode, const char *id, int index, + enum reset_control_flags flags) { bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL; bool gpio_fallback = false; - struct reset_control *rstc; + struct reset_control *rstc = ERR_PTR(-EINVAL); struct reset_controller_dev *rcdev; - struct of_phandle_args args; - int rstc_id; + struct fwnode_reference_args args; + struct of_phandle_args of_args; + int rstc_id = -EINVAL; int ret; - if (!node) + if (!fwnode) return ERR_PTR(-EINVAL); if (id) { - index = of_property_match_string(node, - "reset-names", id); + index = fwnode_property_match_string(fwnode, "reset-names", id); if (index == -EILSEQ) return ERR_PTR(index); if (index < 0) return optional ? NULL : ERR_PTR(-ENOENT); } - ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", - index, &args); + ret = fwnode_property_get_reference_args(fwnode, "resets", "#reset-cells", + 0, index, &args); if (ret == -EINVAL) return ERR_PTR(ret); if (ret) { @@ -1028,51 +1171,65 @@ __of_reset_control_get(struct device_node *node, const char *id, int index, * There can be only one reset-gpio for regular devices, so * don't bother with the "reset-gpios" phandle index. */ - ret = of_parse_phandle_with_args(node, "reset-gpios", "#gpio-cells", - 0, &args); + ret = fwnode_property_get_reference_args(fwnode, "reset-gpios", + "#gpio-cells", 0, 0, &args); if (ret) return optional ? NULL : ERR_PTR(ret); gpio_fallback = true; - ret = __reset_add_reset_gpio_device(&args); + ret = __reset_add_reset_gpio_device(fwnode, &args); if (ret) { - rstc = ERR_PTR(ret); - goto out_put; + fwnode_handle_put(args.fwnode); + return ERR_PTR(ret); } } - mutex_lock(&reset_list_mutex); + guard(mutex)(&reset_list_mutex); + rcdev = __reset_find_rcdev(&args, gpio_fallback); if (!rcdev) { rstc = ERR_PTR(-EPROBE_DEFER); - goto out_unlock; + goto out_put; } - if (WARN_ON(args.args_count != rcdev->of_reset_n_cells)) { + if (WARN_ON(args.nargs != rcdev->fwnode_reset_n_cells)) { rstc = ERR_PTR(-EINVAL); - goto out_unlock; + goto out_put; } - rstc_id = rcdev->of_xlate(rcdev, &args); + if (rcdev->of_xlate && is_of_node(fwnode)) { + ret = of_parse_phandle_with_args(to_of_node(fwnode), + gpio_fallback ? "reset-gpios" : "resets", + gpio_fallback ? "#gpio-cells" : "#reset-cells", + gpio_fallback ? 0 : index, + &of_args); + if (ret) { + rstc = ERR_PTR(ret); + goto out_put; + } + + rstc_id = rcdev->of_xlate(rcdev, &of_args); + of_node_put(of_args.np); + } else if (rcdev->fwnode_xlate) { + rstc_id = rcdev->fwnode_xlate(rcdev, &args); + } if (rstc_id < 0) { rstc = ERR_PTR(rstc_id); - goto out_unlock; + goto out_put; } 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, flags); + scoped_guard(mutex, &rcdev->lock) + rstc = __reset_control_get_internal(rcdev, rstc_id, flags); -out_unlock: - mutex_unlock(&reset_list_mutex); out_put: - of_node_put(args.np); + fwnode_handle_put(args.fwnode); return rstc; } -EXPORT_SYMBOL_GPL(__of_reset_control_get); +EXPORT_SYMBOL_GPL(__fwnode_reset_control_get); struct reset_control *__reset_control_get(struct device *dev, const char *id, int index, enum reset_control_flags flags) @@ -1080,12 +1237,13 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id, bool shared = flags & RESET_CONTROL_FLAGS_BIT_SHARED; bool acquired = flags & RESET_CONTROL_FLAGS_BIT_ACQUIRED; bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL; + struct fwnode_handle *fwnode = dev_fwnode(dev); if (WARN_ON(shared && acquired)) return ERR_PTR(-EINVAL); - if (dev->of_node) - return __of_reset_control_get(dev->of_node, id, index, flags); + if (fwnode) + return __fwnode_reset_control_get(fwnode, id, index, flags); return optional ? NULL : ERR_PTR(-ENOENT); } @@ -1108,10 +1266,9 @@ int __reset_control_bulk_get(struct device *dev, int num_rstcs, return 0; err: - mutex_lock(&reset_list_mutex); while (i--) - __reset_control_put_internal(rstcs[i].rstc); - mutex_unlock(&reset_list_mutex); + reset_control_put_internal(rstcs[i].rstc); + return ret; } EXPORT_SYMBOL_GPL(__reset_control_bulk_get); @@ -1120,10 +1277,8 @@ static void reset_control_array_put(struct reset_control_array *resets) { int i; - mutex_lock(&reset_list_mutex); for (i = 0; i < resets->num_rstcs; i++) - __reset_control_put_internal(resets->rstc[i]); - mutex_unlock(&reset_list_mutex); + reset_control_put_internal(resets->rstc[i]); kfree(resets); } @@ -1141,9 +1296,7 @@ void reset_control_put(struct reset_control *rstc) return; } - mutex_lock(&reset_list_mutex); - __reset_control_put_internal(rstc); - mutex_unlock(&reset_list_mutex); + reset_control_put_internal(rstc); } EXPORT_SYMBOL_GPL(reset_control_put); @@ -1154,10 +1307,8 @@ EXPORT_SYMBOL_GPL(reset_control_put); */ void reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs) { - mutex_lock(&reset_list_mutex); while (num_rstcs--) - __reset_control_put_internal(rstcs[num_rstcs].rstc); - mutex_unlock(&reset_list_mutex); + reset_control_put_internal(rstcs[num_rstcs].rstc); } EXPORT_SYMBOL_GPL(reset_control_bulk_put); @@ -1318,21 +1469,35 @@ EXPORT_SYMBOL_GPL(__device_reset); */ /** - * of_reset_control_get_count - Count number of resets available with a device + * fwnode_reset_control_get_count - Count number of resets available with a device * - * @node: device node that contains 'resets'. + * @fwnode: firmware node that contains 'resets'. * * Returns positive reset count on success, or error number on failure and * on count being zero. */ -static int of_reset_control_get_count(struct device_node *node) +static int fwnode_reset_control_get_count(struct fwnode_handle *fwnode) { - int count; + struct fwnode_reference_args args; + int count = 0, ret; - if (!node) + if (!fwnode) return -EINVAL; - count = of_count_phandle_with_args(node, "resets", "#reset-cells"); + for (;;) { + ret = fwnode_property_get_reference_args(fwnode, "resets", "#reset-cells", + 0, count, &args); + if (ret) { + if (ret == -ENOENT) + break; + + return ret; + } + + fwnode_handle_put(args.fwnode); + count++; + } + if (count == 0) count = -ENOENT; @@ -1340,23 +1505,24 @@ static int of_reset_control_get_count(struct device_node *node) } /** - * of_reset_control_array_get - Get a list of reset controls using - * device node. + * fwnode_reset_control_array_get - Get a list of reset controls using + * a firmware node. * - * @np: device node for the device that requests the reset controls array + * @fwnode: firmware node for the device that requests the reset controls array * @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, enum reset_control_flags flags) +fwnode_reset_control_array_get(struct fwnode_handle *fwnode, + 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; - num = of_reset_control_get_count(np); + num = fwnode_reset_control_get_count(fwnode); if (num < 0) return optional ? NULL : ERR_PTR(num); @@ -1366,7 +1532,7 @@ of_reset_control_array_get(struct device_node *np, enum reset_control_flags flag resets->num_rstcs = num; for (i = 0; i < num; i++) { - rstc = __of_reset_control_get(np, NULL, i, flags); + rstc = __fwnode_reset_control_get(fwnode, NULL, i, flags); if (IS_ERR(rstc)) goto err_rst; resets->rstc[i] = rstc; @@ -1376,16 +1542,14 @@ of_reset_control_array_get(struct device_node *np, enum reset_control_flags flag return &resets->base; err_rst: - mutex_lock(&reset_list_mutex); while (--i >= 0) - __reset_control_put_internal(resets->rstc[i]); - mutex_unlock(&reset_list_mutex); + reset_control_put_internal(resets->rstc[i]); kfree(resets); return rstc; } -EXPORT_SYMBOL_GPL(of_reset_control_array_get); +EXPORT_SYMBOL_GPL(fwnode_reset_control_array_get); /** * devm_reset_control_array_get - Resource managed reset control array get @@ -1409,7 +1573,7 @@ devm_reset_control_array_get(struct device *dev, enum reset_control_flags flags) if (!ptr) return ERR_PTR(-ENOMEM); - rstc = of_reset_control_array_get(dev->of_node, flags); + rstc = fwnode_reset_control_array_get(dev_fwnode(dev), flags); if (IS_ERR_OR_NULL(rstc)) { devres_free(ptr); return rstc; @@ -1432,8 +1596,10 @@ EXPORT_SYMBOL_GPL(devm_reset_control_array_get); */ int reset_control_get_count(struct device *dev) { - if (dev->of_node) - return of_reset_control_get_count(dev->of_node); + struct fwnode_handle *fwnode = dev_fwnode(dev); + + if (fwnode) + return fwnode_reset_control_get_count(fwnode); return -ENOENT; } diff --git a/drivers/reset/reset-ath79.c b/drivers/reset/reset-ath79.c index b5d620132052..4c4e69eb32bb 100644 --- a/drivers/reset/reset-ath79.c +++ b/drivers/reset/reset-ath79.c @@ -15,7 +15,6 @@ struct ath79_reset { struct reset_controller_dev rcdev; - struct notifier_block restart_nb; void __iomem *base; spinlock_t lock; }; @@ -72,11 +71,9 @@ static const struct reset_control_ops ath79_reset_ops = { .status = ath79_reset_status, }; -static int ath79_reset_restart_handler(struct notifier_block *nb, - unsigned long action, void *data) +static int ath79_reset_restart_handler(struct sys_off_data *data) { - struct ath79_reset *ath79_reset = - container_of(nb, struct ath79_reset, restart_nb); + struct ath79_reset *ath79_reset = data->cb_data; ath79_reset_assert(&ath79_reset->rcdev, FULL_CHIP_RESET); @@ -108,10 +105,7 @@ static int ath79_reset_probe(struct platform_device *pdev) if (err) return err; - ath79_reset->restart_nb.notifier_call = ath79_reset_restart_handler; - ath79_reset->restart_nb.priority = 128; - - err = register_restart_handler(&ath79_reset->restart_nb); + err = devm_register_restart_handler(&pdev->dev, ath79_reset_restart_handler, ath79_reset); if (err) dev_warn(&pdev->dev, "Failed to register restart handler\n"); diff --git a/drivers/reset/reset-gpio.c b/drivers/reset/reset-gpio.c index 0a1610d9e78a..26aa2c3a2e68 100644 --- a/drivers/reset/reset-gpio.c +++ b/drivers/reset/reset-gpio.c @@ -4,7 +4,7 @@ #include <linux/gpio/consumer.h> #include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of.h> +#include <linux/property.h> #include <linux/reset-controller.h> struct reset_gpio_priv { @@ -46,34 +46,22 @@ static const struct reset_control_ops reset_gpio_ops = { .status = reset_gpio_status, }; -static int reset_gpio_of_xlate(struct reset_controller_dev *rcdev, - const struct of_phandle_args *reset_spec) +static int reset_gpio_fwnode_xlate(struct reset_controller_dev *rcdev, + const struct fwnode_reference_args *reset_spec) { return reset_spec->args[0]; } -static void reset_gpio_of_node_put(void *data) -{ - of_node_put(data); -} - static int reset_gpio_probe(struct auxiliary_device *adev, const struct auxiliary_device_id *id) { struct device *dev = &adev->dev; - struct of_phandle_args *platdata = dev_get_platdata(dev); struct reset_gpio_priv *priv; - int ret; - - if (!platdata) - return -EINVAL; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - auxiliary_set_drvdata(adev, &priv->rc); - priv->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(priv->reset)) return dev_err_probe(dev, PTR_ERR(priv->reset), @@ -82,15 +70,10 @@ static int reset_gpio_probe(struct auxiliary_device *adev, priv->rc.ops = &reset_gpio_ops; priv->rc.owner = THIS_MODULE; priv->rc.dev = dev; - priv->rc.of_args = platdata; - ret = devm_add_action_or_reset(dev, reset_gpio_of_node_put, - priv->rc.of_node); - if (ret) - return ret; /* Cells to match GPIO specifier, but it's not really used */ - priv->rc.of_reset_n_cells = 2; - priv->rc.of_xlate = reset_gpio_of_xlate; + priv->rc.fwnode_reset_n_cells = 2; + priv->rc.fwnode_xlate = reset_gpio_fwnode_xlate; priv->rc.nr_resets = 1; return devm_reset_controller_register(dev, &priv->rc); diff --git a/drivers/reset/reset-intel-gw.c b/drivers/reset/reset-intel-gw.c index a5ce3350cb5e..0db64cc8a282 100644 --- a/drivers/reset/reset-intel-gw.c +++ b/drivers/reset/reset-intel-gw.c @@ -28,7 +28,6 @@ struct intel_reset_soc { struct intel_reset_data { struct reset_controller_dev rcdev; - struct notifier_block restart_nb; const struct intel_reset_soc *soc_data; struct regmap *regmap; struct device *dev; @@ -153,12 +152,10 @@ static int intel_reset_xlate(struct reset_controller_dev *rcdev, return id; } -static int intel_reset_restart_handler(struct notifier_block *nb, - unsigned long action, void *data) +static int intel_reset_restart_handler(struct sys_off_data *data) { - struct intel_reset_data *reset_data; + struct intel_reset_data *reset_data = data->cb_data; - reset_data = container_of(nb, struct intel_reset_data, restart_nb); intel_assert_device(&reset_data->rcdev, reset_data->reboot_id); return NOTIFY_DONE; @@ -215,9 +212,7 @@ static int intel_reset_probe(struct platform_device *pdev) if (data->soc_data->legacy) data->reboot_id |= FIELD_PREP(STAT_BIT_OFFSET_MASK, rb_id[2]); - data->restart_nb.notifier_call = intel_reset_restart_handler; - data->restart_nb.priority = 128; - register_restart_handler(&data->restart_nb); + devm_register_restart_handler(&pdev->dev, intel_reset_restart_handler, data); return 0; } diff --git a/drivers/reset/reset-lpc18xx.c b/drivers/reset/reset-lpc18xx.c index e42b2f24a93d..8ac9f237e1ce 100644 --- a/drivers/reset/reset-lpc18xx.c +++ b/drivers/reset/reset-lpc18xx.c @@ -31,7 +31,6 @@ struct lpc18xx_rgu_data { struct reset_controller_dev rcdev; - struct notifier_block restart_nb; struct clk *clk_delay; struct clk *clk_reg; void __iomem *base; @@ -41,11 +40,9 @@ struct lpc18xx_rgu_data { #define to_rgu_data(p) container_of(p, struct lpc18xx_rgu_data, rcdev) -static int lpc18xx_rgu_restart(struct notifier_block *nb, unsigned long mode, - void *cmd) +static int lpc18xx_rgu_restart(struct sys_off_data *data) { - struct lpc18xx_rgu_data *rc = container_of(nb, struct lpc18xx_rgu_data, - restart_nb); + struct lpc18xx_rgu_data *rc = data->cb_data; writel(BIT(LPC18XX_RGU_CORE_RST), rc->base + LPC18XX_RGU_CTRL0); mdelay(2000); @@ -178,9 +175,8 @@ static int lpc18xx_rgu_probe(struct platform_device *pdev) if (ret) return dev_err_probe(&pdev->dev, ret, "unable to register device\n"); - rc->restart_nb.priority = 192, - rc->restart_nb.notifier_call = lpc18xx_rgu_restart, - ret = register_restart_handler(&rc->restart_nb); + ret = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART, 192, + lpc18xx_rgu_restart, rc); if (ret) dev_warn(&pdev->dev, "failed to register restart handler\n"); diff --git a/drivers/reset/reset-ma35d1.c b/drivers/reset/reset-ma35d1.c index 54e53863c98a..4ee901f00132 100644 --- a/drivers/reset/reset-ma35d1.c +++ b/drivers/reset/reset-ma35d1.c @@ -19,7 +19,6 @@ struct ma35d1_reset_data { struct reset_controller_dev rcdev; - struct notifier_block restart_handler; void __iomem *base; /* protect registers against concurrent read-modify-write */ spinlock_t lock; @@ -125,10 +124,9 @@ static const struct { [MA35D1_RESET_SSPCC] = {0x2C, 31} }; -static int ma35d1_restart_handler(struct notifier_block *this, unsigned long mode, void *cmd) +static int ma35d1_restart_handler(struct sys_off_data *sys_off_data) { - struct ma35d1_reset_data *data = - container_of(this, struct ma35d1_reset_data, restart_handler); + struct ma35d1_reset_data *data = sys_off_data->cb_data; u32 id = MA35D1_RESET_CHIP; writel_relaxed(BIT(ma35d1_reset_map[id].bit), @@ -213,11 +211,10 @@ static int ma35d1_reset_probe(struct platform_device *pdev) reset_data->rcdev.nr_resets = MA35D1_RESET_COUNT; reset_data->rcdev.ops = &ma35d1_reset_ops; reset_data->rcdev.of_node = dev->of_node; - reset_data->restart_handler.notifier_call = ma35d1_restart_handler; - reset_data->restart_handler.priority = 192; spin_lock_init(&reset_data->lock); - err = register_restart_handler(&reset_data->restart_handler); + err = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART, 192, + ma35d1_restart_handler, reset_data); if (err) dev_warn(&pdev->dev, "failed to register restart handler\n"); diff --git a/drivers/reset/reset-npcm.c b/drivers/reset/reset-npcm.c index 4070a4b6663f..a762d0215e76 100644 --- a/drivers/reset/reset-npcm.c +++ b/drivers/reset/reset-npcm.c @@ -89,7 +89,6 @@ static const struct npcm_reset_info npxm8xx_reset_info[] = { struct npcm_rc_data { struct reset_controller_dev rcdev; - struct notifier_block restart_nb; const struct npcm_reset_info *info; struct regmap *gcr_regmap; u32 sw_reset_number; @@ -100,11 +99,9 @@ struct npcm_rc_data { #define to_rc_data(p) container_of(p, struct npcm_rc_data, rcdev) -static int npcm_rc_restart(struct notifier_block *nb, unsigned long mode, - void *cmd) +static int npcm_rc_restart(struct sys_off_data *data) { - struct npcm_rc_data *rc = container_of(nb, struct npcm_rc_data, - restart_nb); + struct npcm_rc_data *rc = data->cb_data; writel(NPCM_SWRST << rc->sw_reset_number, rc->base + NPCM_SWRSTR); mdelay(1000); @@ -472,9 +469,8 @@ static int npcm_rc_probe(struct platform_device *pdev) if (!of_property_read_u32(pdev->dev.of_node, "nuvoton,sw-reset-number", &rc->sw_reset_number)) { if (rc->sw_reset_number && rc->sw_reset_number < 5) { - rc->restart_nb.priority = 192; - rc->restart_nb.notifier_call = npcm_rc_restart; - ret = register_restart_handler(&rc->restart_nb); + ret = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART, 192, + npcm_rc_restart, rc); if (ret) { dev_warn(&pdev->dev, "failed to register restart handler\n"); return ret; diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c index 32bc268c9149..fd75d9601a3b 100644 --- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c +++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c @@ -136,6 +136,9 @@ static int rzg2l_usbphy_ctrl_set_pwrrdy(struct regmap_field *pwrrdy, { u32 val = power_on ? 0 : 1; + if (!pwrrdy) + return 0; + /* The initialization path guarantees that the mask is 1 bit long. */ return regmap_field_update_bits(pwrrdy, 1, val); } @@ -347,4 +350,4 @@ module_platform_driver(rzg2l_usbphy_ctrl_driver); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Renesas RZ/G2L USBPHY Control"); -MODULE_AUTHOR("biju.das.jz@bp.renesas.com>"); +MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>"); diff --git a/drivers/reset/reset-rzv2h-usb2phy.c b/drivers/reset/reset-rzv2h-usb2phy.c index ae643575b067..d96042e28cd5 100644 --- a/drivers/reset/reset-rzv2h-usb2phy.c +++ b/drivers/reset/reset-rzv2h-usb2phy.c @@ -5,42 +5,39 @@ * Copyright (C) 2025 Renesas Electronics Corporation */ -#include <linux/cleanup.h> +#include <linux/auxiliary_bus.h> #include <linux/delay.h> +#include <linux/idr.h> #include <linux/io.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/regmap.h> #include <linux/reset.h> #include <linux/reset-controller.h> -struct rzv2h_usb2phy_regval { - u16 reg; - u16 val; -}; +static DEFINE_IDA(auxiliary_ids); struct rzv2h_usb2phy_reset_of_data { - const struct rzv2h_usb2phy_regval *init_vals; - unsigned int init_val_count; + const struct reg_sequence *init_seq; + unsigned int init_nseq; + + const struct reg_sequence *assert_seq; + unsigned int assert_nseq; + + const struct reg_sequence *deassert_seq; + unsigned int deassert_nseq; u16 reset_reg; - u16 reset_assert_val; - u16 reset_deassert_val; u16 reset_status_bits; - u16 reset_release_val; - - u16 reset2_reg; - u16 reset2_acquire_val; - u16 reset2_release_val; }; struct rzv2h_usb2phy_reset_priv { const struct rzv2h_usb2phy_reset_of_data *data; - void __iomem *base; + struct regmap *regmap; struct device *dev; struct reset_controller_dev rcdev; - spinlock_t lock; /* protects register accesses */ }; static inline struct rzv2h_usb2phy_reset_priv @@ -49,81 +46,31 @@ static inline struct rzv2h_usb2phy_reset_priv return container_of(rcdev, struct rzv2h_usb2phy_reset_priv, rcdev); } -/* This function must be called only after pm_runtime_resume_and_get() has been called */ -static void rzv2h_usbphy_assert_helper(struct rzv2h_usb2phy_reset_priv *priv) -{ - const struct rzv2h_usb2phy_reset_of_data *data = priv->data; - - scoped_guard(spinlock, &priv->lock) { - writel(data->reset2_acquire_val, priv->base + data->reset2_reg); - writel(data->reset_assert_val, priv->base + data->reset_reg); - } - - usleep_range(11, 20); -} - static int rzv2h_usbphy_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) { struct rzv2h_usb2phy_reset_priv *priv = rzv2h_usbphy_rcdev_to_priv(rcdev); - struct device *dev = priv->dev; - int ret; - - ret = pm_runtime_resume_and_get(dev); - if (ret) { - dev_err(dev, "pm_runtime_resume_and_get failed\n"); - return ret; - } - - rzv2h_usbphy_assert_helper(priv); - pm_runtime_put(dev); - - return 0; + return regmap_multi_reg_write(priv->regmap, priv->data->assert_seq, + priv->data->assert_nseq); } static int rzv2h_usbphy_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) { struct rzv2h_usb2phy_reset_priv *priv = rzv2h_usbphy_rcdev_to_priv(rcdev); - const struct rzv2h_usb2phy_reset_of_data *data = priv->data; - struct device *dev = priv->dev; - int ret; - - ret = pm_runtime_resume_and_get(dev); - if (ret) { - dev_err(dev, "pm_runtime_resume_and_get failed\n"); - return ret; - } - scoped_guard(spinlock, &priv->lock) { - writel(data->reset_deassert_val, priv->base + data->reset_reg); - writel(data->reset2_release_val, priv->base + data->reset2_reg); - writel(data->reset_release_val, priv->base + data->reset_reg); - } - - pm_runtime_put(dev); - - return 0; + return regmap_multi_reg_write(priv->regmap, priv->data->deassert_seq, + priv->data->deassert_nseq); } static int rzv2h_usbphy_reset_status(struct reset_controller_dev *rcdev, unsigned long id) { struct rzv2h_usb2phy_reset_priv *priv = rzv2h_usbphy_rcdev_to_priv(rcdev); - struct device *dev = priv->dev; - int ret; u32 reg; - ret = pm_runtime_resume_and_get(dev); - if (ret) { - dev_err(dev, "pm_runtime_resume_and_get failed\n"); - return ret; - } - - reg = readl(priv->base + priv->data->reset_reg); - - pm_runtime_put(dev); + regmap_read(priv->regmap, priv->data->reset_reg, ®); return (reg & priv->data->reset_status_bits) == priv->data->reset_status_bits; } @@ -141,12 +88,52 @@ static int rzv2h_usb2phy_reset_of_xlate(struct reset_controller_dev *rcdev, return 0; } +static void rzv2h_usb2phy_reset_ida_free(void *data) +{ + struct auxiliary_device *adev = data; + + ida_free(&auxiliary_ids, adev->id); +} + +static int rzv2h_usb2phy_reset_mux_register(struct device *dev, + const char *mux_name) +{ + struct auxiliary_device *adev; + int id; + + id = ida_alloc(&auxiliary_ids, GFP_KERNEL); + if (id < 0) + return id; + + adev = __devm_auxiliary_device_create(dev, dev->driver->name, + mux_name, NULL, id); + if (!adev) { + ida_free(&auxiliary_ids, id); + return -ENOMEM; + } + + return devm_add_action_or_reset(dev, rzv2h_usb2phy_reset_ida_free, adev); +} + +static const struct regmap_config rzv2h_usb2phy_reset_regconf = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .can_sleep = true, +}; + +static void rzv2h_usb2phy_reset_pm_runtime_put(void *data) +{ + pm_runtime_put(data); +} + static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev) { const struct rzv2h_usb2phy_reset_of_data *data; struct rzv2h_usb2phy_reset_priv *priv; struct device *dev = &pdev->dev; struct reset_control *rstc; + void __iomem *base; int error; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -156,17 +143,19 @@ static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev) data = of_device_get_match_data(dev); priv->data = data; priv->dev = dev; - priv->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + priv->regmap = devm_regmap_init_mmio(dev, base, &rzv2h_usb2phy_reset_regconf); + if (IS_ERR(priv->regmap)) + return PTR_ERR(priv->regmap); rstc = devm_reset_control_get_shared_deasserted(dev, NULL); if (IS_ERR(rstc)) return dev_err_probe(dev, PTR_ERR(rstc), "failed to get deasserted reset\n"); - spin_lock_init(&priv->lock); - error = devm_pm_runtime_enable(dev); if (error) return dev_err_probe(dev, error, "Failed to enable pm_runtime\n"); @@ -175,13 +164,14 @@ static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev) if (error) return dev_err_probe(dev, error, "pm_runtime_resume_and_get failed\n"); - for (unsigned int i = 0; i < data->init_val_count; i++) - writel(data->init_vals[i].val, priv->base + data->init_vals[i].reg); - - /* keep usb2phy in asserted state */ - rzv2h_usbphy_assert_helper(priv); + error = devm_add_action_or_reset(dev, rzv2h_usb2phy_reset_pm_runtime_put, + dev); + if (error) + return dev_err_probe(dev, error, "unable to register cleanup action\n"); - pm_runtime_put(dev); + error = regmap_multi_reg_write(priv->regmap, data->init_seq, data->init_nseq); + if (error) + return dev_err_probe(dev, error, "failed to initialize PHY registers\n"); priv->rcdev.ops = &rzv2h_usbphy_reset_ops; priv->rcdev.of_reset_n_cells = 0; @@ -190,30 +180,47 @@ static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev) priv->rcdev.of_node = dev->of_node; priv->rcdev.dev = dev; - return devm_reset_controller_register(dev, &priv->rcdev); + error = devm_reset_controller_register(dev, &priv->rcdev); + if (error) + return dev_err_probe(dev, error, "could not register reset controller\n"); + + error = rzv2h_usb2phy_reset_mux_register(dev, "vbenctl"); + if (error) + return dev_err_probe(dev, error, "could not register aux mux\n"); + + return 0; } /* * initialization values required to prepare the PHY to receive * assert and deassert requests. */ -static const struct rzv2h_usb2phy_regval rzv2h_init_vals[] = { - { .reg = 0xc10, .val = 0x67c }, - { .reg = 0xc14, .val = 0x1f }, - { .reg = 0x600, .val = 0x909 }, +static const struct reg_sequence rzv2h_init_seq[] = { + { .reg = 0xc10, .def = 0x67c }, + { .reg = 0xc14, .def = 0x01f }, + { .reg = 0x600, .def = 0x909 }, +}; + +static const struct reg_sequence rzv2h_assert_seq[] = { + { .reg = 0xb04, .def = 0x303 }, + { .reg = 0x000, .def = 0x206, .delay_us = 11 }, +}; + +static const struct reg_sequence rzv2h_deassert_seq[] = { + { .reg = 0x000, .def = 0x200 }, + { .reg = 0xb04, .def = 0x003 }, + { .reg = 0x000, .def = 0x000 }, }; static const struct rzv2h_usb2phy_reset_of_data rzv2h_reset_of_data = { - .init_vals = rzv2h_init_vals, - .init_val_count = ARRAY_SIZE(rzv2h_init_vals), + .init_seq = rzv2h_init_seq, + .init_nseq = ARRAY_SIZE(rzv2h_init_seq), + .assert_seq = rzv2h_assert_seq, + .assert_nseq = ARRAY_SIZE(rzv2h_assert_seq), + .deassert_seq = rzv2h_deassert_seq, + .deassert_nseq = ARRAY_SIZE(rzv2h_deassert_seq), .reset_reg = 0, - .reset_assert_val = 0x206, .reset_status_bits = BIT(2), - .reset_deassert_val = 0x200, - .reset_release_val = 0x0, - .reset2_reg = 0xb04, - .reset2_acquire_val = 0x303, - .reset2_release_val = 0x3, }; static const struct of_device_id rzv2h_usb2phy_reset_of_match[] = { diff --git a/drivers/reset/reset-sky1.c b/drivers/reset/reset-sky1.c new file mode 100644 index 000000000000..78e80a533c39 --- /dev/null +++ b/drivers/reset/reset-sky1.c @@ -0,0 +1,367 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * + * CIX System Reset Controller (SRC) driver + * + * Author: Jerry Zhu <jerry.zhu@cixtech.com> + */ + +#include <linux/delay.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/reset-controller.h> + +#include <dt-bindings/reset/cix,sky1-system-control.h> +#include <dt-bindings/reset/cix,sky1-s5-system-control.h> + +#define SKY1_RESET_SLEEP_MIN_US 50 +#define SKY1_RESET_SLEEP_MAX_US 100 + +struct sky1_src_signal { + unsigned int offset; + unsigned int bit; +}; + +struct sky1_src_variant { + const struct sky1_src_signal *signals; + unsigned int signals_num; +}; + +struct sky1_src { + struct reset_controller_dev rcdev; + const struct sky1_src_signal *signals; + struct regmap *regmap; +}; + +enum { + CSU_PM_RESET = 0x304, + SENSORFUSION_RESET = 0x308, + SENSORFUSION_NOC_RESET = 0x30c, + RESET_GROUP0_S0_DOMAIN_0 = 0x400, + RESET_GROUP0_S0_DOMAIN_1 = 0x404, + RESET_GROUP1_USB_PHYS = 0x408, + RESET_GROUP1_USB_CONTROLLERS = 0x40c, + RESET_GROUP0_RCSU = 0x800, + RESET_GROUP1_RCSU = 0x804, +}; + +static const struct sky1_src_signal sky1_src_signals[] = { + /* reset group1 for s0 domain modules */ + [SKY1_CSU_PM_RESET_N] = { CSU_PM_RESET, BIT(0) }, + [SKY1_SENSORFUSION_RESET_N] = { SENSORFUSION_RESET, BIT(0) }, + [SKY1_SENSORFUSION_NOC_RESET_N] = { SENSORFUSION_NOC_RESET, BIT(0) }, + [SKY1_DDRC_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(0) }, + [SKY1_GIC_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(1) }, + [SKY1_CI700_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(2) }, + [SKY1_SYS_NI700_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(3) }, + [SKY1_MM_NI700_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(4) }, + [SKY1_PCIE_NI700_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(5) }, + [SKY1_GPU_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(6) }, + [SKY1_NPUTOP_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(7) }, + [SKY1_NPUCORE0_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(8) }, + [SKY1_NPUCORE1_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(9) }, + [SKY1_NPUCORE2_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(10) }, + [SKY1_VPU_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(11) }, + [SKY1_ISP_SRESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(12) }, + [SKY1_ISP_ARESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(13) }, + [SKY1_ISP_HRESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(14) }, + [SKY1_ISP_GDCRESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(15) }, + [SKY1_DPU_RESET0_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(16) }, + [SKY1_DPU_RESET1_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(17) }, + [SKY1_DPU_RESET2_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(18) }, + [SKY1_DPU_RESET3_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(19) }, + [SKY1_DPU_RESET4_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(20) }, + [SKY1_DP_RESET0_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(21) }, + [SKY1_DP_RESET1_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(22) }, + [SKY1_DP_RESET2_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(23) }, + [SKY1_DP_RESET3_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(24) }, + [SKY1_DP_RESET4_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(25) }, + [SKY1_DP_PHY_RST_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(26) }, + + /* reset group1 for s0 domain modules */ + [SKY1_AUDIO_HIFI5_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(0) }, + [SKY1_AUDIO_HIFI5_NOC_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(1) }, + [SKY1_CSIDPHY_PRST0_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(2) }, + [SKY1_CSIDPHY_CMNRST0_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(3) }, + [SKY1_CSI0_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(4) }, + [SKY1_CSIDPHY_PRST1_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(5) }, + [SKY1_CSIDPHY_CMNRST1_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(6) }, + [SKY1_CSI1_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(7) }, + [SKY1_CSI2_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(8) }, + [SKY1_CSI3_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(9) }, + [SKY1_CSIBRDGE0_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(10) }, + [SKY1_CSIBRDGE1_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(11) }, + [SKY1_CSIBRDGE2_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(12) }, + [SKY1_CSIBRDGE3_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(13) }, + [SKY1_GMAC0_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(14) }, + [SKY1_GMAC1_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(15) }, + [SKY1_PCIE0_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(16) }, + [SKY1_PCIE1_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(17) }, + [SKY1_PCIE2_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(18) }, + [SKY1_PCIE3_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(19) }, + [SKY1_PCIE4_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(20) }, + + /* reset group1 for usb phys */ + [SKY1_USB_DP_PHY0_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(0) }, + [SKY1_USB_DP_PHY1_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(1) }, + [SKY1_USB_DP_PHY2_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(2) }, + [SKY1_USB_DP_PHY3_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(3) }, + [SKY1_USB_DP_PHY0_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(4) }, + [SKY1_USB_DP_PHY1_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(5) }, + [SKY1_USB_DP_PHY2_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(6) }, + [SKY1_USB_DP_PHY3_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(7) }, + [SKY1_USBPHY_SS_PST_N] = { RESET_GROUP1_USB_PHYS, BIT(8) }, + [SKY1_USBPHY_SS_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(9) }, + [SKY1_USBPHY_HS0_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(10) }, + [SKY1_USBPHY_HS1_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(11) }, + [SKY1_USBPHY_HS2_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(12) }, + [SKY1_USBPHY_HS3_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(13) }, + [SKY1_USBPHY_HS4_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(14) }, + [SKY1_USBPHY_HS5_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(15) }, + [SKY1_USBPHY_HS6_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(16) }, + [SKY1_USBPHY_HS7_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(17) }, + [SKY1_USBPHY_HS8_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(18) }, + [SKY1_USBPHY_HS9_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(19) }, + + /* reset group1 for usb controllers */ + [SKY1_USBC_SS0_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(0) }, + [SKY1_USBC_SS1_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(1) }, + [SKY1_USBC_SS2_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(2) }, + [SKY1_USBC_SS3_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(3) }, + [SKY1_USBC_SS4_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(4) }, + [SKY1_USBC_SS5_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(5) }, + [SKY1_USBC_SS0_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(6) }, + [SKY1_USBC_SS1_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(7) }, + [SKY1_USBC_SS2_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(8) }, + [SKY1_USBC_SS3_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(9) }, + [SKY1_USBC_SS4_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(10) }, + [SKY1_USBC_SS5_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(11) }, + [SKY1_USBC_HS0_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(12) }, + [SKY1_USBC_HS1_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(13) }, + [SKY1_USBC_HS2_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(14) }, + [SKY1_USBC_HS3_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(15) }, + [SKY1_USBC_HS0_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(16) }, + [SKY1_USBC_HS1_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(17) }, + [SKY1_USBC_HS2_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(18) }, + [SKY1_USBC_HS3_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(19) }, + + /* reset group0 for rcsu */ + [SKY1_AUDIO_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(0) }, + [SKY1_CI700_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(1) }, + [SKY1_CSI_RCSU0_RESET_N] = { RESET_GROUP0_RCSU, BIT(2) }, + [SKY1_CSI_RCSU1_RESET_N] = { RESET_GROUP0_RCSU, BIT(3) }, + [SKY1_CSU_PM_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(4) }, + [SKY1_DDR_BROADCAST_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(5) }, + [SKY1_DDR_CTRL_RCSU_0_RESET_N] = { RESET_GROUP0_RCSU, BIT(6) }, + [SKY1_DDR_CTRL_RCSU_1_RESET_N] = { RESET_GROUP0_RCSU, BIT(7) }, + [SKY1_DDR_CTRL_RCSU_2_RESET_N] = { RESET_GROUP0_RCSU, BIT(8) }, + [SKY1_DDR_CTRL_RCSU_3_RESET_N] = { RESET_GROUP0_RCSU, BIT(9) }, + [SKY1_DDR_TZC400_RCSU_0_RESET_N] = { RESET_GROUP0_RCSU, BIT(10) }, + [SKY1_DDR_TZC400_RCSU_1_RESET_N] = { RESET_GROUP0_RCSU, BIT(11) }, + [SKY1_DDR_TZC400_RCSU_2_RESET_N] = { RESET_GROUP0_RCSU, BIT(12) }, + [SKY1_DDR_TZC400_RCSU_3_RESET_N] = { RESET_GROUP0_RCSU, BIT(13) }, + [SKY1_DP0_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(14) }, + [SKY1_DP1_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(15) }, + [SKY1_DP2_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(16) }, + [SKY1_DP3_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(17) }, + [SKY1_DP4_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(18) }, + [SKY1_DPU0_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(19) }, + [SKY1_DPU1_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(20) }, + [SKY1_DPU2_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(21) }, + [SKY1_DPU3_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(22) }, + [SKY1_DPU4_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(23) }, + [SKY1_DSU_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(24) }, + [SKY1_FCH_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(25) }, + [SKY1_GICD_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(26) }, + [SKY1_GMAC_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(27) }, + [SKY1_GPU_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(28) }, + [SKY1_ISP_RCSU0_RESET_N] = { RESET_GROUP0_RCSU, BIT(29) }, + [SKY1_ISP_RCSU1_RESET_N] = { RESET_GROUP0_RCSU, BIT(30) }, + [SKY1_NI700_MMHUB_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(31) }, + + /* reset group1 for rcsu */ + [SKY1_NPU_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(0) }, + [SKY1_NI700_PCIE_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(1) }, + [SKY1_PCIE_X421_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(2) }, + [SKY1_PCIE_X8_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(3) }, + [SKY1_SF_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(4) }, + [SKY1_RCSU_SMMU_MMHUB_RESET_N] = { RESET_GROUP1_RCSU, BIT(5) }, + [SKY1_RCSU_SMMU_PCIEHUB_RESET_N] = { RESET_GROUP1_RCSU, BIT(6) }, + [SKY1_RCSU_SYSHUB_RESET_N] = { RESET_GROUP1_RCSU, BIT(7) }, + [SKY1_NI700_SMN_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(8) }, + [SKY1_NI700_SYSHUB_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(9) }, + [SKY1_RCSU_USB2_HOST0_RESET_N] = { RESET_GROUP1_RCSU, BIT(10) }, + [SKY1_RCSU_USB2_HOST1_RESET_N] = { RESET_GROUP1_RCSU, BIT(11) }, + [SKY1_RCSU_USB2_HOST2_RESET_N] = { RESET_GROUP1_RCSU, BIT(12) }, + [SKY1_RCSU_USB2_HOST3_RESET_N] = { RESET_GROUP1_RCSU, BIT(13) }, + [SKY1_RCSU_USB3_TYPEA_DRD_RESET_N] = { RESET_GROUP1_RCSU, BIT(14) }, + [SKY1_RCSU_USB3_TYPEC_DRD_RESET_N] = { RESET_GROUP1_RCSU, BIT(15) }, + [SKY1_RCSU_USB3_TYPEC_HOST0_RESET_N] = { RESET_GROUP1_RCSU, BIT(16) }, + [SKY1_RCSU_USB3_TYPEC_HOST1_RESET_N] = { RESET_GROUP1_RCSU, BIT(17) }, + [SKY1_RCSU_USB3_TYPEC_HOST2_RESET_N] = { RESET_GROUP1_RCSU, BIT(18) }, + [SKY1_VPU_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(19) }, +}; + +static const struct sky1_src_variant variant_sky1 = { + .signals = sky1_src_signals, + .signals_num = ARRAY_SIZE(sky1_src_signals), +}; + +enum { + FCH_SW_RST_FUNC = 0x8, + FCH_SW_RST_BUS = 0xc, + FCH_SW_XSPI = 0x10, +}; + +static const struct sky1_src_signal sky1_src_fch_signals[] = { + /* resets for fch_sw_rst_func */ + [SW_I3C0_RST_FUNC_G_N] = { FCH_SW_RST_FUNC, BIT(0) }, + [SW_I3C0_RST_FUNC_I_N] = { FCH_SW_RST_FUNC, BIT(1) }, + [SW_I3C1_RST_FUNC_G_N] = { FCH_SW_RST_FUNC, BIT(2) }, + [SW_I3C1_RST_FUNC_I_N] = { FCH_SW_RST_FUNC, BIT(3) }, + [SW_UART0_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(4) }, + [SW_UART1_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(5) }, + [SW_UART2_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(6) }, + [SW_UART3_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(7) }, + [SW_TIMER_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(20) }, + + /* resets for fch_sw_rst_bus */ + [SW_I3C0_RST_APB_N] = { FCH_SW_RST_BUS, BIT(0) }, + [SW_I3C1_RST_APB_N] = { FCH_SW_RST_BUS, BIT(1) }, + [SW_DMA_RST_AXI_N] = { FCH_SW_RST_BUS, BIT(2) }, + [SW_UART0_RST_APB_N] = { FCH_SW_RST_BUS, BIT(4) }, + [SW_UART1_RST_APB_N] = { FCH_SW_RST_BUS, BIT(5) }, + [SW_UART2_RST_APB_N] = { FCH_SW_RST_BUS, BIT(6) }, + [SW_UART3_RST_APB_N] = { FCH_SW_RST_BUS, BIT(7) }, + [SW_SPI0_RST_APB_N] = { FCH_SW_RST_BUS, BIT(8) }, + [SW_SPI1_RST_APB_N] = { FCH_SW_RST_BUS, BIT(9) }, + [SW_I2C0_RST_APB_N] = { FCH_SW_RST_BUS, BIT(12) }, + [SW_I2C1_RST_APB_N] = { FCH_SW_RST_BUS, BIT(13) }, + [SW_I2C2_RST_APB_N] = { FCH_SW_RST_BUS, BIT(14) }, + [SW_I2C3_RST_APB_N] = { FCH_SW_RST_BUS, BIT(15) }, + [SW_I2C4_RST_APB_N] = { FCH_SW_RST_BUS, BIT(16) }, + [SW_I2C5_RST_APB_N] = { FCH_SW_RST_BUS, BIT(17) }, + [SW_I2C6_RST_APB_N] = { FCH_SW_RST_BUS, BIT(18) }, + [SW_I2C7_RST_APB_N] = { FCH_SW_RST_BUS, BIT(19) }, + [SW_GPIO_RST_APB_N] = { FCH_SW_RST_BUS, BIT(21) }, + + /* resets for fch_sw_xspi */ + [SW_XSPI_REG_RST_N] = { FCH_SW_XSPI, BIT(0) }, + [SW_XSPI_SYS_RST_N] = { FCH_SW_XSPI, BIT(1) }, +}; + +static const struct sky1_src_variant variant_sky1_fch = { + .signals = sky1_src_fch_signals, + .signals_num = ARRAY_SIZE(sky1_src_fch_signals), +}; + +static struct sky1_src *to_sky1_src(struct reset_controller_dev *rcdev) +{ + return container_of(rcdev, struct sky1_src, rcdev); +} + +static int sky1_reset_set(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) +{ + struct sky1_src *sky1src = to_sky1_src(rcdev); + const struct sky1_src_signal *signal = &sky1src->signals[id]; + unsigned int value = assert ? 0 : signal->bit; + + return regmap_update_bits(sky1src->regmap, + signal->offset, signal->bit, value); +} + +static int sky1_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + sky1_reset_set(rcdev, id, true); + usleep_range(SKY1_RESET_SLEEP_MIN_US, + SKY1_RESET_SLEEP_MAX_US); + return 0; +} + +static int sky1_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + sky1_reset_set(rcdev, id, false); + usleep_range(SKY1_RESET_SLEEP_MIN_US, + SKY1_RESET_SLEEP_MAX_US); + return 0; +} + +static int sky1_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + sky1_reset_assert(rcdev, id); + sky1_reset_deassert(rcdev, id); + return 0; +} + +static int sky1_reset_status(struct reset_controller_dev *rcdev, + unsigned long id) +{ + unsigned int value = 0; + struct sky1_src *sky1src = to_sky1_src(rcdev); + const struct sky1_src_signal *signal = &sky1src->signals[id]; + + regmap_read(sky1src->regmap, signal->offset, &value); + return !(value & signal->bit); +} + +static const struct reset_control_ops sky1_src_ops = { + .reset = sky1_reset, + .assert = sky1_reset_assert, + .deassert = sky1_reset_deassert, + .status = sky1_reset_status +}; + +static int sky1_reset_probe(struct platform_device *pdev) +{ + struct sky1_src *sky1src; + struct device *dev = &pdev->dev; + const struct sky1_src_variant *variant; + + sky1src = devm_kzalloc(dev, sizeof(*sky1src), GFP_KERNEL); + if (!sky1src) + return -ENOMEM; + + variant = of_device_get_match_data(dev); + + sky1src->regmap = device_node_to_regmap(dev->of_node); + if (IS_ERR(sky1src->regmap)) { + return dev_err_probe(dev, PTR_ERR(sky1src->regmap), + "Unable to get sky1-src regmap"); + } + + sky1src->signals = variant->signals; + sky1src->rcdev.owner = THIS_MODULE; + sky1src->rcdev.nr_resets = variant->signals_num; + sky1src->rcdev.ops = &sky1_src_ops; + sky1src->rcdev.of_node = dev->of_node; + sky1src->rcdev.dev = dev; + + return devm_reset_controller_register(dev, &sky1src->rcdev); +} + +static const struct of_device_id sky1_sysreg_of_match[] = { + { .compatible = "cix,sky1-system-control", .data = &variant_sky1_fch}, + { .compatible = "cix,sky1-s5-system-control", .data = &variant_sky1}, + {}, +}; +MODULE_DEVICE_TABLE(of, sky1_sysreg_of_match); + +static struct platform_driver sky1_reset_driver = { + .probe = sky1_reset_probe, + .driver = { + .name = "cix,sky1-rst", + .of_match_table = sky1_sysreg_of_match, + }, +}; +module_platform_driver(sky1_reset_driver) + +MODULE_AUTHOR("Jerry Zhu <jerry.zhu@cixtech.com>"); +MODULE_DESCRIPTION("Cix Sky1 reset driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/reset/reset-sunplus.c b/drivers/reset/reset-sunplus.c index df58decab64d..58b087433759 100644 --- a/drivers/reset/reset-sunplus.c +++ b/drivers/reset/reset-sunplus.c @@ -100,7 +100,6 @@ static const u32 sp_resets[] = { struct sp_reset { struct reset_controller_dev rcdev; - struct notifier_block notifier; void __iomem *base; }; @@ -154,10 +153,9 @@ static const struct reset_control_ops sp_reset_ops = { .status = sp_reset_status, }; -static int sp_restart(struct notifier_block *nb, unsigned long mode, - void *cmd) +static int sp_restart(struct sys_off_data *data) { - struct sp_reset *reset = container_of(nb, struct sp_reset, notifier); + struct sp_reset *reset = data->cb_data; sp_reset_assert(&reset->rcdev, 0); sp_reset_deassert(&reset->rcdev, 0); @@ -189,10 +187,8 @@ static int sp_reset_probe(struct platform_device *pdev) if (ret) return ret; - reset->notifier.notifier_call = sp_restart; - reset->notifier.priority = 192; - - return register_restart_handler(&reset->notifier); + return devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART, + 192, sp_restart, reset); } static const struct of_device_id sp_reset_dt_ids[] = { diff --git a/drivers/reset/spacemit/reset-spacemit-k3.c b/drivers/reset/spacemit/reset-spacemit-k3.c index e9e32e4c1ba5..9841f5e057b2 100644 --- a/drivers/reset/spacemit/reset-spacemit-k3.c +++ b/drivers/reset/spacemit/reset-spacemit-k3.c @@ -112,16 +112,21 @@ static const struct ccu_reset_data k3_apmu_resets[] = { [RESET_APMU_SDH0] = RESET_DATA(APMU_SDH0_CLK_RES_CTRL, 0, BIT(1)), [RESET_APMU_SDH1] = RESET_DATA(APMU_SDH1_CLK_RES_CTRL, 0, BIT(1)), [RESET_APMU_SDH2] = RESET_DATA(APMU_SDH2_CLK_RES_CTRL, 0, BIT(1)), - [RESET_APMU_USB2] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, - BIT(1)|BIT(2)|BIT(3)), - [RESET_APMU_USB3_PORTA] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, - BIT(5)|BIT(6)|BIT(7)), - [RESET_APMU_USB3_PORTB] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, - BIT(9)|BIT(10)|BIT(11)), - [RESET_APMU_USB3_PORTC] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, - BIT(13)|BIT(14)|BIT(15)), - [RESET_APMU_USB3_PORTD] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, - BIT(17)|BIT(18)|BIT(19)), + [RESET_APMU_USB2_AHB] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(1)), + [RESET_APMU_USB2_VCC] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(2)), + [RESET_APMU_USB2_PHY] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(3)), + [RESET_APMU_USB3_A_AHB] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(5)), + [RESET_APMU_USB3_A_VCC] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(6)), + [RESET_APMU_USB3_A_PHY] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(7)), + [RESET_APMU_USB3_B_AHB] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(9)), + [RESET_APMU_USB3_B_VCC] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(10)), + [RESET_APMU_USB3_B_PHY] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(11)), + [RESET_APMU_USB3_C_AHB] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(13)), + [RESET_APMU_USB3_C_VCC] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(14)), + [RESET_APMU_USB3_C_PHY] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(15)), + [RESET_APMU_USB3_D_AHB] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(17)), + [RESET_APMU_USB3_D_VCC] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(18)), + [RESET_APMU_USB3_D_PHY] = RESET_DATA(APMU_USB_CLK_RES_CTRL, 0, BIT(19)), [RESET_APMU_QSPI] = RESET_DATA(APMU_QSPI_CLK_RES_CTRL, 0, BIT(1)), [RESET_APMU_QSPI_BUS] = RESET_DATA(APMU_QSPI_CLK_RES_CTRL, 0, BIT(0)), [RESET_APMU_DMA] = RESET_DATA(APMU_DMA_CLK_RES_CTRL, 0, BIT(0)), @@ -151,10 +156,12 @@ static const struct ccu_reset_data k3_apmu_resets[] = { [RESET_APMU_CPU7_SW] = RESET_DATA(APMU_PMU_CC2_AP, BIT(26), 0), [RESET_APMU_C1_MPSUB_SW] = RESET_DATA(APMU_PMU_CC2_AP, BIT(28), 0), [RESET_APMU_MPSUB_DBG] = RESET_DATA(APMU_PMU_CC2_AP, BIT(29), 0), - [RESET_APMU_UCIE] = RESET_DATA(APMU_UCIE_CTRL, - BIT(1) | BIT(2) | BIT(3), 0), - [RESET_APMU_RCPU] = RESET_DATA(APMU_RCPU_CLK_RES_CTRL, 0, - BIT(3) | BIT(2) | BIT(0)), + [RESET_APMU_UCIE_IP] = RESET_DATA(APMU_UCIE_CTRL, BIT(1), 0), + [RESET_APMU_UCIE_HOT] = RESET_DATA(APMU_UCIE_CTRL, BIT(2), 0), + [RESET_APMU_UCIE_MON] = RESET_DATA(APMU_UCIE_CTRL, BIT(3), 0), + [RESET_APMU_RCPU_AUDIO_SYS] = RESET_DATA(APMU_RCPU_CLK_RES_CTRL, 0, BIT(0)), + [RESET_APMU_RCPU_MCU_CORE] = RESET_DATA(APMU_RCPU_CLK_RES_CTRL, 0, BIT(2)), + [RESET_APMU_RCPU_AUDIO_APMU] = RESET_DATA(APMU_RCPU_CLK_RES_CTRL, 0, BIT(3)), [RESET_APMU_DSI4LN2_ESCCLK] = RESET_DATA(APMU_LCD_CLK_RES_CTRL3, 0, BIT(3)), [RESET_APMU_DSI4LN2_LCD_SW] = RESET_DATA(APMU_LCD_CLK_RES_CTRL3, 0, BIT(4)), [RESET_APMU_DSI4LN2_LCD_MCLK] = RESET_DATA(APMU_LCD_CLK_RES_CTRL4, 0, BIT(9)), @@ -164,16 +171,21 @@ static const struct ccu_reset_data k3_apmu_resets[] = { [RESET_APMU_UFS_ACLK] = RESET_DATA(APMU_UFS_CLK_RES_CTRL, 0, BIT(0)), [RESET_APMU_EDP0] = RESET_DATA(APMU_LCD_EDP_CTRL, 0, BIT(0)), [RESET_APMU_EDP1] = RESET_DATA(APMU_LCD_EDP_CTRL, 0, BIT(16)), - [RESET_APMU_PCIE_PORTA] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_A, 0, - BIT(5) | BIT(4) | BIT(3)), - [RESET_APMU_PCIE_PORTB] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_B, 0, - BIT(5) | BIT(4) | BIT(3)), - [RESET_APMU_PCIE_PORTC] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_C, 0, - BIT(5) | BIT(4) | BIT(3)), - [RESET_APMU_PCIE_PORTD] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_D, 0, - BIT(5) | BIT(4) | BIT(3)), - [RESET_APMU_PCIE_PORTE] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_E, 0, - BIT(5) | BIT(4) | BIT(3)), + [RESET_APMU_PCIE_A_DBI] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_A, 0, BIT(3)), + [RESET_APMU_PCIE_A_SLAVE] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_A, 0, BIT(4)), + [RESET_APMU_PCIE_A_MASTER] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_A, 0, BIT(5)), + [RESET_APMU_PCIE_B_DBI] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_B, 0, BIT(3)), + [RESET_APMU_PCIE_B_SLAVE] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_B, 0, BIT(4)), + [RESET_APMU_PCIE_B_MASTER] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_B, 0, BIT(5)), + [RESET_APMU_PCIE_C_DBI] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_C, 0, BIT(3)), + [RESET_APMU_PCIE_C_SLAVE] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_C, 0, BIT(4)), + [RESET_APMU_PCIE_C_MASTER] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_C, 0, BIT(5)), + [RESET_APMU_PCIE_D_DBI] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_D, 0, BIT(3)), + [RESET_APMU_PCIE_D_SLAVE] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_D, 0, BIT(4)), + [RESET_APMU_PCIE_D_MASTER] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_D, 0, BIT(5)), + [RESET_APMU_PCIE_E_DBI] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_E, 0, BIT(3)), + [RESET_APMU_PCIE_E_SLAVE] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_E, 0, BIT(4)), + [RESET_APMU_PCIE_E_MASTER] = RESET_DATA(APMU_PCIE_CLK_RES_CTRL_E, 0, BIT(5)), [RESET_APMU_EMAC0] = RESET_DATA(APMU_EMAC0_CLK_RES_CTRL, 0, BIT(1)), [RESET_APMU_EMAC1] = RESET_DATA(APMU_EMAC1_CLK_RES_CTRL, 0, BIT(1)), [RESET_APMU_EMAC2] = RESET_DATA(APMU_EMAC2_CLK_RES_CTRL, 0, BIT(1)), diff --git a/drivers/reset/sti/reset-syscfg.c b/drivers/reset/sti/reset-syscfg.c index 2324060b747c..38f78d78fa4f 100644 --- a/drivers/reset/sti/reset-syscfg.c +++ b/drivers/reset/sti/reset-syscfg.c @@ -41,7 +41,7 @@ struct syscfg_reset_channel { struct syscfg_reset_controller { struct reset_controller_dev rst; bool active_low; - struct syscfg_reset_channel *channels; + struct syscfg_reset_channel channels[]; }; #define to_syscfg_reset_controller(_rst) \ @@ -135,15 +135,10 @@ static int syscfg_reset_controller_register(struct device *dev, struct syscfg_reset_controller *rc; int i, err; - rc = devm_kzalloc(dev, sizeof(*rc), GFP_KERNEL); + rc = devm_kzalloc(dev, struct_size(rc, channels, data->nr_channels), GFP_KERNEL); if (!rc) return -ENOMEM; - rc->channels = devm_kcalloc(dev, data->nr_channels, - sizeof(*rc->channels), GFP_KERNEL); - if (!rc->channels) - return -ENOMEM; - rc->rst.ops = &syscfg_reset_ops; rc->rst.of_node = dev->of_node; rc->rst.nr_resets = data->nr_channels; diff --git a/include/dt-bindings/reset/cix,sky1-s5-system-control.h b/include/dt-bindings/reset/cix,sky1-s5-system-control.h new file mode 100644 index 000000000000..808bbcbe0c98 --- /dev/null +++ b/include/dt-bindings/reset/cix,sky1-s5-system-control.h @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* Author: Jerry Zhu <jerry.zhu@cixtech.com> */ +#ifndef DT_BINDING_RESET_CIX_SKY1_S5_SYSTEM_CONTROL_H +#define DT_BINDING_RESET_CIX_SKY1_S5_SYSTEM_CONTROL_H + +/* reset for csu_pm */ +#define SKY1_CSU_PM_RESET_N 0 +#define SKY1_SENSORFUSION_RESET_N 1 +#define SKY1_SENSORFUSION_NOC_RESET_N 2 + +/* reset group0 for s0 domain modules */ +#define SKY1_DDRC_RESET_N 3 +#define SKY1_GIC_RESET_N 4 +#define SKY1_CI700_RESET_N 5 +#define SKY1_SYS_NI700_RESET_N 6 +#define SKY1_MM_NI700_RESET_N 7 +#define SKY1_PCIE_NI700_RESET_N 8 +#define SKY1_GPU_RESET_N 9 +#define SKY1_NPUTOP_RESET_N 10 +#define SKY1_NPUCORE0_RESET_N 11 +#define SKY1_NPUCORE1_RESET_N 12 +#define SKY1_NPUCORE2_RESET_N 13 +#define SKY1_VPU_RESET_N 14 +#define SKY1_ISP_SRESET_N 15 +#define SKY1_ISP_ARESET_N 16 +#define SKY1_ISP_HRESET_N 17 +#define SKY1_ISP_GDCRESET_N 18 +#define SKY1_DPU_RESET0_N 19 +#define SKY1_DPU_RESET1_N 20 +#define SKY1_DPU_RESET2_N 21 +#define SKY1_DPU_RESET3_N 22 +#define SKY1_DPU_RESET4_N 23 +#define SKY1_DP_RESET0_N 24 +#define SKY1_DP_RESET1_N 25 +#define SKY1_DP_RESET2_N 26 +#define SKY1_DP_RESET3_N 27 +#define SKY1_DP_RESET4_N 28 +#define SKY1_DP_PHY_RST_N 29 + +/* reset group1 for s0 domain modules */ +#define SKY1_AUDIO_HIFI5_RESET_N 30 +#define SKY1_AUDIO_HIFI5_NOC_RESET_N 31 +#define SKY1_CSIDPHY_PRST0_N 32 +#define SKY1_CSIDPHY_CMNRST0_N 33 +#define SKY1_CSI0_RST_N 34 +#define SKY1_CSIDPHY_PRST1_N 35 +#define SKY1_CSIDPHY_CMNRST1_N 36 +#define SKY1_CSI1_RST_N 37 +#define SKY1_CSI2_RST_N 38 +#define SKY1_CSI3_RST_N 39 +#define SKY1_CSIBRDGE0_RST_N 40 +#define SKY1_CSIBRDGE1_RST_N 41 +#define SKY1_CSIBRDGE2_RST_N 42 +#define SKY1_CSIBRDGE3_RST_N 43 +#define SKY1_GMAC0_RST_N 44 +#define SKY1_GMAC1_RST_N 45 +#define SKY1_PCIE0_RESET_N 46 +#define SKY1_PCIE1_RESET_N 47 +#define SKY1_PCIE2_RESET_N 48 +#define SKY1_PCIE3_RESET_N 49 +#define SKY1_PCIE4_RESET_N 50 + +/* reset group1 for usb phys */ +#define SKY1_USB_DP_PHY0_PRST_N 51 +#define SKY1_USB_DP_PHY1_PRST_N 52 +#define SKY1_USB_DP_PHY2_PRST_N 53 +#define SKY1_USB_DP_PHY3_PRST_N 54 +#define SKY1_USB_DP_PHY0_RST_N 55 +#define SKY1_USB_DP_PHY1_RST_N 56 +#define SKY1_USB_DP_PHY2_RST_N 57 +#define SKY1_USB_DP_PHY3_RST_N 58 +#define SKY1_USBPHY_SS_PST_N 59 +#define SKY1_USBPHY_SS_RST_N 60 +#define SKY1_USBPHY_HS0_PRST_N 61 +#define SKY1_USBPHY_HS1_PRST_N 62 +#define SKY1_USBPHY_HS2_PRST_N 63 +#define SKY1_USBPHY_HS3_PRST_N 64 +#define SKY1_USBPHY_HS4_PRST_N 65 +#define SKY1_USBPHY_HS5_PRST_N 66 +#define SKY1_USBPHY_HS6_PRST_N 67 +#define SKY1_USBPHY_HS7_PRST_N 68 +#define SKY1_USBPHY_HS8_PRST_N 69 +#define SKY1_USBPHY_HS9_PRST_N 70 + +/* reset group1 for usb controllers */ +#define SKY1_USBC_SS0_PRST_N 71 +#define SKY1_USBC_SS1_PRST_N 72 +#define SKY1_USBC_SS2_PRST_N 73 +#define SKY1_USBC_SS3_PRST_N 74 +#define SKY1_USBC_SS4_PRST_N 75 +#define SKY1_USBC_SS5_PRST_N 76 +#define SKY1_USBC_SS0_RST_N 77 +#define SKY1_USBC_SS1_RST_N 78 +#define SKY1_USBC_SS2_RST_N 79 +#define SKY1_USBC_SS3_RST_N 80 +#define SKY1_USBC_SS4_RST_N 81 +#define SKY1_USBC_SS5_RST_N 82 +#define SKY1_USBC_HS0_PRST_N 83 +#define SKY1_USBC_HS1_PRST_N 84 +#define SKY1_USBC_HS2_PRST_N 85 +#define SKY1_USBC_HS3_PRST_N 86 +#define SKY1_USBC_HS0_RST_N 87 +#define SKY1_USBC_HS1_RST_N 88 +#define SKY1_USBC_HS2_RST_N 89 +#define SKY1_USBC_HS3_RST_N 90 + +/* reset group0 for rcsu */ +#define SKY1_AUDIO_RCSU_RESET_N 91 +#define SKY1_CI700_RCSU_RESET_N 92 +#define SKY1_CSI_RCSU0_RESET_N 93 +#define SKY1_CSI_RCSU1_RESET_N 94 +#define SKY1_CSU_PM_RCSU_RESET_N 95 +#define SKY1_DDR_BROADCAST_RCSU_RESET_N 96 +#define SKY1_DDR_CTRL_RCSU_0_RESET_N 97 +#define SKY1_DDR_CTRL_RCSU_1_RESET_N 98 +#define SKY1_DDR_CTRL_RCSU_2_RESET_N 99 +#define SKY1_DDR_CTRL_RCSU_3_RESET_N 100 +#define SKY1_DDR_TZC400_RCSU_0_RESET_N 101 +#define SKY1_DDR_TZC400_RCSU_1_RESET_N 102 +#define SKY1_DDR_TZC400_RCSU_2_RESET_N 103 +#define SKY1_DDR_TZC400_RCSU_3_RESET_N 104 +#define SKY1_DP0_RCSU_RESET_N 105 +#define SKY1_DP1_RCSU_RESET_N 106 +#define SKY1_DP2_RCSU_RESET_N 107 +#define SKY1_DP3_RCSU_RESET_N 108 +#define SKY1_DP4_RCSU_RESET_N 109 +#define SKY1_DPU0_RCSU_RESET_N 110 +#define SKY1_DPU1_RCSU_RESET_N 111 +#define SKY1_DPU2_RCSU_RESET_N 112 +#define SKY1_DPU3_RCSU_RESET_N 113 +#define SKY1_DPU4_RCSU_RESET_N 114 +#define SKY1_DSU_RCSU_RESET_N 115 +#define SKY1_FCH_RCSU_RESET_N 116 +#define SKY1_GICD_RCSU_RESET_N 117 +#define SKY1_GMAC_RCSU_RESET_N 118 +#define SKY1_GPU_RCSU_RESET_N 119 +#define SKY1_ISP_RCSU0_RESET_N 120 +#define SKY1_ISP_RCSU1_RESET_N 121 +#define SKY1_NI700_MMHUB_RCSU_RESET_N 122 + +/* reset group1 for rcsu */ +#define SKY1_NPU_RCSU_RESET_N 123 +#define SKY1_NI700_PCIE_RCSU_RESET_N 124 +#define SKY1_PCIE_X421_RCSU_RESET_N 125 +#define SKY1_PCIE_X8_RCSU_RESET_N 126 +#define SKY1_SF_RCSU_RESET_N 127 +#define SKY1_RCSU_SMMU_MMHUB_RESET_N 128 +#define SKY1_RCSU_SMMU_PCIEHUB_RESET_N 129 +#define SKY1_RCSU_SYSHUB_RESET_N 130 +#define SKY1_NI700_SMN_RCSU_RESET_N 131 +#define SKY1_NI700_SYSHUB_RCSU_RESET_N 132 +#define SKY1_RCSU_USB2_HOST0_RESET_N 133 +#define SKY1_RCSU_USB2_HOST1_RESET_N 134 +#define SKY1_RCSU_USB2_HOST2_RESET_N 135 +#define SKY1_RCSU_USB2_HOST3_RESET_N 136 +#define SKY1_RCSU_USB3_TYPEA_DRD_RESET_N 137 +#define SKY1_RCSU_USB3_TYPEC_DRD_RESET_N 138 +#define SKY1_RCSU_USB3_TYPEC_HOST0_RESET_N 139 +#define SKY1_RCSU_USB3_TYPEC_HOST1_RESET_N 140 +#define SKY1_RCSU_USB3_TYPEC_HOST2_RESET_N 141 +#define SKY1_VPU_RCSU_RESET_N 142 + +#endif diff --git a/include/dt-bindings/reset/cix,sky1-system-control.h b/include/dt-bindings/reset/cix,sky1-system-control.h new file mode 100644 index 000000000000..7a16fc4ef3b5 --- /dev/null +++ b/include/dt-bindings/reset/cix,sky1-system-control.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* Author: Jerry Zhu <jerry.zhu@cixtech.com> */ +#ifndef DT_BINDING_RESET_CIX_SKY1_SYSTEM_CONTROL_H +#define DT_BINDING_RESET_CIX_SKY1_SYSTEM_CONTROL_H + +/* func reset for sky1 fch */ +#define SW_I3C0_RST_FUNC_G_N 0 +#define SW_I3C0_RST_FUNC_I_N 1 +#define SW_I3C1_RST_FUNC_G_N 2 +#define SW_I3C1_RST_FUNC_I_N 3 +#define SW_UART0_RST_FUNC_N 4 +#define SW_UART1_RST_FUNC_N 5 +#define SW_UART2_RST_FUNC_N 6 +#define SW_UART3_RST_FUNC_N 7 +#define SW_TIMER_RST_FUNC_N 8 + +/* apb reset for sky1 fch */ +#define SW_I3C0_RST_APB_N 9 +#define SW_I3C1_RST_APB_N 10 +#define SW_DMA_RST_AXI_N 11 +#define SW_UART0_RST_APB_N 12 +#define SW_UART1_RST_APB_N 13 +#define SW_UART2_RST_APB_N 14 +#define SW_UART3_RST_APB_N 15 +#define SW_SPI0_RST_APB_N 16 +#define SW_SPI1_RST_APB_N 17 +#define SW_I2C0_RST_APB_N 18 +#define SW_I2C1_RST_APB_N 19 +#define SW_I2C2_RST_APB_N 20 +#define SW_I2C3_RST_APB_N 21 +#define SW_I2C4_RST_APB_N 22 +#define SW_I2C5_RST_APB_N 23 +#define SW_I2C6_RST_APB_N 24 +#define SW_I2C7_RST_APB_N 25 +#define SW_GPIO_RST_APB_N 26 + +/* fch rst for xspi */ +#define SW_XSPI_REG_RST_N 27 +#define SW_XSPI_SYS_RST_N 28 + +#endif diff --git a/include/dt-bindings/reset/spacemit,k3-resets.h b/include/dt-bindings/reset/spacemit,k3-resets.h index 79ac1c22b7b5..dc1ef009ba79 100644 --- a/include/dt-bindings/reset/spacemit,k3-resets.h +++ b/include/dt-bindings/reset/spacemit,k3-resets.h @@ -97,11 +97,11 @@ #define RESET_APMU_SDH0 13 #define RESET_APMU_SDH1 14 #define RESET_APMU_SDH2 15 -#define RESET_APMU_USB2 16 -#define RESET_APMU_USB3_PORTA 17 -#define RESET_APMU_USB3_PORTB 18 -#define RESET_APMU_USB3_PORTC 19 -#define RESET_APMU_USB3_PORTD 20 +#define RESET_APMU_USB2_AHB 16 +#define RESET_APMU_USB2_VCC 17 +#define RESET_APMU_USB2_PHY 18 +#define RESET_APMU_USB3_A_AHB 19 +#define RESET_APMU_USB3_A_VCC 20 #define RESET_APMU_QSPI 21 #define RESET_APMU_QSPI_BUS 22 #define RESET_APMU_DMA 23 @@ -132,8 +132,8 @@ #define RESET_APMU_CPU7_SW 48 #define RESET_APMU_C1_MPSUB_SW 49 #define RESET_APMU_MPSUB_DBG 50 -#define RESET_APMU_UCIE 51 -#define RESET_APMU_RCPU 52 +#define RESET_APMU_USB3_A_PHY 51 /* USB3 A */ +#define RESET_APMU_USB3_B_AHB 52 #define RESET_APMU_DSI4LN2_ESCCLK 53 #define RESET_APMU_DSI4LN2_LCD_SW 54 #define RESET_APMU_DSI4LN2_LCD_MCLK 55 @@ -143,16 +143,40 @@ #define RESET_APMU_UFS_ACLK 59 #define RESET_APMU_EDP0 60 #define RESET_APMU_EDP1 61 -#define RESET_APMU_PCIE_PORTA 62 -#define RESET_APMU_PCIE_PORTB 63 -#define RESET_APMU_PCIE_PORTC 64 -#define RESET_APMU_PCIE_PORTD 65 -#define RESET_APMU_PCIE_PORTE 66 +#define RESET_APMU_USB3_B_VCC 62 /* USB3 B */ +#define RESET_APMU_USB3_B_PHY 63 +#define RESET_APMU_USB3_C_AHB 64 +#define RESET_APMU_USB3_C_VCC 65 +#define RESET_APMU_USB3_C_PHY 66 #define RESET_APMU_EMAC0 67 #define RESET_APMU_EMAC1 68 #define RESET_APMU_EMAC2 69 #define RESET_APMU_ESPI_MCLK 70 #define RESET_APMU_ESPI_SCLK 71 +#define RESET_APMU_USB3_D_AHB 72 /* USB3 D */ +#define RESET_APMU_USB3_D_VCC 73 +#define RESET_APMU_USB3_D_PHY 74 +#define RESET_APMU_UCIE_IP 75 +#define RESET_APMU_UCIE_HOT 76 +#define RESET_APMU_UCIE_MON 77 +#define RESET_APMU_RCPU_AUDIO_SYS 78 +#define RESET_APMU_RCPU_MCU_CORE 79 +#define RESET_APMU_RCPU_AUDIO_APMU 80 +#define RESET_APMU_PCIE_A_DBI 81 +#define RESET_APMU_PCIE_A_SLAVE 82 +#define RESET_APMU_PCIE_A_MASTER 83 +#define RESET_APMU_PCIE_B_DBI 84 +#define RESET_APMU_PCIE_B_SLAVE 85 +#define RESET_APMU_PCIE_B_MASTER 86 +#define RESET_APMU_PCIE_C_DBI 87 +#define RESET_APMU_PCIE_C_SLAVE 88 +#define RESET_APMU_PCIE_C_MASTER 89 +#define RESET_APMU_PCIE_D_DBI 90 +#define RESET_APMU_PCIE_D_SLAVE 91 +#define RESET_APMU_PCIE_D_MASTER 92 +#define RESET_APMU_PCIE_E_DBI 93 +#define RESET_APMU_PCIE_E_SLAVE 94 +#define RESET_APMU_PCIE_E_MASTER 95 /* DCIU resets*/ #define RESET_DCIU_HDMA 0 diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h index 46514cb1b9e0..52a5a4e81f18 100644 --- a/include/linux/reset-controller.h +++ b/include/linux/reset-controller.h @@ -3,7 +3,10 @@ #define _LINUX_RESET_CONTROLLER_H_ #include <linux/list.h> +#include <linux/mutex.h> +struct fwnode_handle; +struct fwnode_reference_args; struct reset_controller_dev; /** @@ -35,14 +38,16 @@ struct of_phandle_args; * @reset_control_head: head of internal list of requested reset controls * @dev: corresponding driver model device struct * @of_node: corresponding device tree node as phandle target - * @of_args: for reset-gpios controllers: corresponding phandle args with - * of_node and GPIO number complementing of_node; either this or - * of_node should be present * @of_reset_n_cells: number of cells in reset line specifiers * @of_xlate: translation function to translate from specifier as found in the - * device tree to id as given to the reset control ops, defaults - * to :c:func:`of_reset_simple_xlate`. + * device tree to id as given to the reset control ops + * @fwnode: firmware node associated with this device + * @fwnode_reset_n_cells: number of cells in reset line specifiers + * @fwnode_xlate: translation function to translate from firmware specifier to + * id as given to the reset control ops, defaults to + * :c:func:`fwnode_reset_simple_xlate` * @nr_resets: number of reset controls in this reset controller device + * @lock: protects the reset control list from concurrent access */ struct reset_controller_dev { const struct reset_control_ops *ops; @@ -51,11 +56,15 @@ struct reset_controller_dev { struct list_head reset_control_head; struct device *dev; struct device_node *of_node; - const struct of_phandle_args *of_args; int of_reset_n_cells; int (*of_xlate)(struct reset_controller_dev *rcdev, const struct of_phandle_args *reset_spec); + struct fwnode_handle *fwnode; + int fwnode_reset_n_cells; + int (*fwnode_xlate)(struct reset_controller_dev *rcdev, + const struct fwnode_reference_args *reset_spec); unsigned int nr_resets; + struct mutex lock; }; #if IS_ENABLED(CONFIG_RESET_CONTROLLER) diff --git a/include/linux/reset.h b/include/linux/reset.h index 44f9e3415f92..9c391cf0c822 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -5,10 +5,12 @@ #include <linux/bits.h> #include <linux/err.h> #include <linux/errno.h> +#include <linux/of.h> #include <linux/types.h> struct device; struct device_node; +struct fwnode_handle; struct reset_control; /** @@ -84,7 +86,7 @@ int reset_control_bulk_deassert(int num_rstcs, struct reset_control_bulk_data *r int reset_control_bulk_acquire(int num_rstcs, struct reset_control_bulk_data *rstcs); void reset_control_bulk_release(int num_rstcs, struct reset_control_bulk_data *rstcs); -struct reset_control *__of_reset_control_get(struct device_node *node, +struct reset_control *__fwnode_reset_control_get(struct fwnode_handle *fwnode, const char *id, int index, enum reset_control_flags flags); struct reset_control *__reset_control_get(struct device *dev, const char *id, int index, enum reset_control_flags flags); @@ -103,7 +105,8 @@ int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs, struct reset_control *devm_reset_control_array_get(struct device *dev, enum reset_control_flags flags); -struct reset_control *of_reset_control_array_get(struct device_node *np, enum reset_control_flags); +struct reset_control *fwnode_reset_control_array_get(struct fwnode_handle *fwnode, + enum reset_control_flags); int reset_control_get_count(struct device *dev); @@ -152,8 +155,8 @@ static inline int __device_reset(struct device *dev, bool optional) return optional ? 0 : -ENOTSUPP; } -static inline struct reset_control *__of_reset_control_get( - struct device_node *node, +static inline struct reset_control *__fwnode_reset_control_get( + struct fwnode_handle *fwnode, const char *id, int index, enum reset_control_flags flags) { bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL; @@ -242,7 +245,7 @@ devm_reset_control_array_get(struct device *dev, enum reset_control_flags flags) } static inline struct reset_control * -of_reset_control_array_get(struct device_node *np, enum reset_control_flags flags) +fwnode_reset_control_array_get(struct fwnode_handle *fwnode, enum reset_control_flags flags) { bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL; @@ -500,7 +503,8 @@ reset_control_bulk_get_optional_shared(struct device *dev, int num_rstcs, static inline struct reset_control *of_reset_control_get_exclusive( struct device_node *node, const char *id) { - return __of_reset_control_get(node, id, 0, RESET_CONTROL_EXCLUSIVE); + return __fwnode_reset_control_get(of_fwnode_handle(node), id, 0, + RESET_CONTROL_EXCLUSIVE); } /** @@ -520,7 +524,8 @@ static inline struct reset_control *of_reset_control_get_exclusive( static inline struct reset_control *of_reset_control_get_optional_exclusive( struct device_node *node, const char *id) { - return __of_reset_control_get(node, id, 0, RESET_CONTROL_OPTIONAL_EXCLUSIVE); + return __fwnode_reset_control_get(of_fwnode_handle(node), id, 0, + RESET_CONTROL_OPTIONAL_EXCLUSIVE); } /** @@ -545,7 +550,8 @@ static inline struct reset_control *of_reset_control_get_optional_exclusive( static inline struct reset_control *of_reset_control_get_shared( struct device_node *node, const char *id) { - return __of_reset_control_get(node, id, 0, RESET_CONTROL_SHARED); + return __fwnode_reset_control_get(of_fwnode_handle(node), id, 0, + RESET_CONTROL_SHARED); } /** @@ -562,7 +568,8 @@ static inline struct reset_control *of_reset_control_get_shared( static inline struct reset_control *of_reset_control_get_exclusive_by_index( struct device_node *node, int index) { - return __of_reset_control_get(node, NULL, index, RESET_CONTROL_EXCLUSIVE); + return __fwnode_reset_control_get(of_fwnode_handle(node), NULL, index, + RESET_CONTROL_EXCLUSIVE); } /** @@ -590,7 +597,8 @@ static inline struct reset_control *of_reset_control_get_exclusive_by_index( static inline struct reset_control *of_reset_control_get_shared_by_index( struct device_node *node, int index) { - return __of_reset_control_get(node, NULL, index, RESET_CONTROL_SHARED); + return __fwnode_reset_control_get(of_fwnode_handle(node), NULL, index, + RESET_CONTROL_SHARED); } /** @@ -1032,30 +1040,35 @@ devm_reset_control_array_get_optional_shared(struct device *dev) static inline struct reset_control * of_reset_control_array_get_exclusive(struct device_node *node) { - return of_reset_control_array_get(node, RESET_CONTROL_EXCLUSIVE); + return fwnode_reset_control_array_get(of_fwnode_handle(node), + RESET_CONTROL_EXCLUSIVE); } static inline struct reset_control * of_reset_control_array_get_exclusive_released(struct device_node *node) { - return of_reset_control_array_get(node, RESET_CONTROL_EXCLUSIVE_RELEASED); + return fwnode_reset_control_array_get(of_fwnode_handle(node), + RESET_CONTROL_EXCLUSIVE_RELEASED); } static inline struct reset_control * of_reset_control_array_get_shared(struct device_node *node) { - return of_reset_control_array_get(node, RESET_CONTROL_SHARED); + return fwnode_reset_control_array_get(of_fwnode_handle(node), + RESET_CONTROL_SHARED); } static inline struct reset_control * of_reset_control_array_get_optional_exclusive(struct device_node *node) { - return of_reset_control_array_get(node, RESET_CONTROL_OPTIONAL_EXCLUSIVE); + return fwnode_reset_control_array_get(of_fwnode_handle(node), + RESET_CONTROL_OPTIONAL_EXCLUSIVE); } static inline struct reset_control * of_reset_control_array_get_optional_shared(struct device_node *node) { - return of_reset_control_array_get(node, RESET_CONTROL_OPTIONAL_SHARED); + return fwnode_reset_control_array_get(of_fwnode_handle(node), + RESET_CONTROL_OPTIONAL_SHARED); } #endif |
