diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 61e688882643..54fb4c9e4f7b 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -4,6 +4,7 @@
  *
  * Copyright 2013 Philipp Zabel, Pengutronix
  */
+#include <linux/acpi.h>
 #include <linux/atomic.h>
 #include <linux/device.h>
 #include <linux/err.h>
@@ -67,29 +68,49 @@ 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->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
+ * @rargs: fwnode reset line specifier
  *
- * This static translation function is used by default if of_xlate in
+ * This static translation function is used by default if fwnode_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 *rargs)
 {
-	if (reset_spec->args[0] >= rcdev->nr_resets)
+	if (rargs->args[0] >= rcdev->nr_resets)
 		return -EINVAL;
 
-	return reset_spec->args[0];
+	return rargs->args[0];
+}
+
+/**
+ * fwnode_of_reset_xlate - convert fwnode reference args for of_xlate call
+ * @rcdev: a pointer to the reset controller device
+ * @rargs: fwnode reset line specifier
+ *
+ * This static translation function is used by default for fwnode_xlate if
+ * of_xlate in * :c:type:`reset_controller_dev` is set. It allows to keep
+ * compatibility with device-tree compatible reset drivers by converting the
+ * fwnode_reference_args to of_phandle_args and calling of_xlate.
+ */
+static int fwnode_of_reset_xlate(struct reset_controller_dev *rcdev,
+				 const struct fwnode_reference_args *rargs)
+{
+	struct of_phandle_args of_args;
+
+	of_phandle_args_from_fwnode_reference_args(&of_args, rargs);
+
+	return rcdev->of_xlate(rcdev, &of_args);
 }
 
 /**
@@ -98,9 +119,24 @@ static int of_reset_simple_xlate(struct reset_controller_dev *rcdev,
  */
 int reset_controller_register(struct reset_controller_dev *rcdev)
 {
-	if (!rcdev->of_xlate) {
-		rcdev->of_reset_n_cells = 1;
-		rcdev->of_xlate = of_reset_simple_xlate;
+	if (!rcdev->fwnode) {
+		rcdev->fwnode = of_fwnode_handle(rcdev->of_node);
+	} else {
+		if (is_acpi_node(rcdev->fwnode))
+			return -EINVAL;
+	}
+
+	if (rcdev->of_xlate) {
+		if (rcdev->fwnode_xlate)
+			return -EINVAL;
+
+		rcdev->fwnode_xlate = fwnode_of_reset_xlate;
+		rcdev->fwnode_reset_n_cells = rcdev->of_reset_n_cells;
+	}
+
+	if (!rcdev->fwnode_xlate) {
+		rcdev->fwnode_reset_n_cells = 1;
+		rcdev->fwnode_xlate = fwnode_reset_simple_xlate;
 	}
 
 	INIT_LIST_HEAD(&rcdev->reset_control_head);
@@ -810,29 +846,28 @@ static void __reset_control_put_internal(struct reset_control *rstc)
 }
 
 struct reset_control *
-__of_reset_control_get(struct device_node *node, const char *id, int index,
-		       bool shared, bool optional, bool acquired)
+__fwnode_reset_control_get(struct fwnode_handle *fwnode, const char *id,
+			   int index, bool shared, bool optional, bool acquired)
 {
 	struct reset_control *rstc;
 	struct reset_controller_dev *r, *rcdev;
-	struct of_phandle_args args;
+	struct fwnode_reference_args args;
 	int rstc_id;
 	int ret;
 
-	if (!node)
+	if (!fwnode || is_acpi_node(fwnode))
 		return ERR_PTR(-EINVAL);
 
 	if (id) {
-		index = of_property_match_string(node,
-						 "reset-names", id);
-		if (index == -EILSEQ)
+		index = fwnode_property_match_string(fwnode, "reset-names", id);
+		if (index == -EILSEQ || index == -ENOMEM || index == -EOVERFLOW)
 			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)
@@ -841,7 +876,7 @@ __of_reset_control_get(struct device_node *node, const char *id, int index,
 	mutex_lock(&reset_list_mutex);
 	rcdev = NULL;
 	list_for_each_entry(r, &reset_controller_list, list) {
-		if (args.np == r->of_node) {
+		if (args.fwnode == r->fwnode) {
 			rcdev = r;
 			break;
 		}
@@ -852,12 +887,12 @@ __of_reset_control_get(struct device_node *node, const char *id, int index,
 		goto out;
 	}
 
-	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;
 	}
 
-	rstc_id = rcdev->of_xlate(rcdev, &args);
+	rstc_id = rcdev->fwnode_xlate(rcdev, &args);
 	if (rstc_id < 0) {
 		rstc = ERR_PTR(rstc_id);
 		goto out;
@@ -868,10 +903,19 @@ __of_reset_control_get(struct device_node *node, const char *id, int index,
 
 out:
 	mutex_unlock(&reset_list_mutex);
-	of_node_put(args.np);
+	fwnode_handle_put(args.fwnode);
 
 	return rstc;
 }
+EXPORT_SYMBOL_GPL(__fwnode_reset_control_get);
+
+struct reset_control *
+__of_reset_control_get(struct device_node *node, const char *id, int index,
+		       bool shared, bool optional, bool acquired)
+{
+	return __fwnode_reset_control_get(of_fwnode_handle(node), id, index,
+					  shared, optional, acquired);
+}
 EXPORT_SYMBOL_GPL(__of_reset_control_get);
 
 static struct reset_controller_dev *
@@ -942,9 +986,9 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id,
 	if (WARN_ON(shared && acquired))
 		return ERR_PTR(-EINVAL);
 
-	if (dev->of_node)
-		return __of_reset_control_get(dev->of_node, id, index, shared,
-					      optional, acquired);
+	if (dev_fwnode(dev))
+		return __fwnode_reset_control_get(dev_fwnode(dev), id, index,
+						  shared, optional, acquired);
 
 	return __reset_control_get_from_lookup(dev, id, shared, optional,
 					       acquired);
diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h
index 0fa4f60e1186..c0ba4dae2e90 100644
--- a/include/linux/reset-controller.h
+++ b/include/linux/reset-controller.h
@@ -24,7 +24,9 @@ struct reset_control_ops {
 
 struct module;
 struct device_node;
+struct fwnode_handle;
 struct of_phandle_args;
+struct fwnode_reference_args;
 
 /**
  * struct reset_control_lookup - represents a single lookup entry
@@ -60,10 +62,20 @@ struct reset_control_lookup {
  * @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
+ * @fwnode: corresponding firmware node as reference target
  * @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. If set,
+ *            fwnode_xlate will be set with :c:func:`fwnode_of_reset_xlate`.
+ *            Note that only either one of of_xlate or fwnode_xlate should be
+ *            provided but not both.
+ * @fwnode_reset_n_cells: number of cells in reset line reference specifiers
+ * @fwnode_xlate: translation function to translate from reference specifier as
+ *                found in the firmware node description to id as given to the
+ *                reset control ops, defaults to
+ *                :c:func:`fwnode_reset_simple_xlate`.
+ *                Note that only either one of of_xlate or fwnode_xlate should
+ *                be provided but not both.
  * @nr_resets: number of reset controls in this reset controller device
  */
 struct reset_controller_dev {
@@ -73,9 +85,13 @@ struct reset_controller_dev {
 	struct list_head reset_control_head;
 	struct device *dev;
 	struct device_node *of_node;
+	struct fwnode_handle *fwnode;
 	int of_reset_n_cells;
 	int (*of_xlate)(struct reset_controller_dev *rcdev,
 			const struct of_phandle_args *reset_spec);
+	int fwnode_reset_n_cells;
+	int (*fwnode_xlate)(struct reset_controller_dev *rcdev,
+			    const struct fwnode_reference_args *reset_spec);
 	unsigned int nr_resets;
 };
 
diff --git a/include/linux/reset.h b/include/linux/reset.h
index 8a21b5756c3e..0f0fe9408180 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -8,6 +8,7 @@
 
 struct device;
 struct device_node;
+struct fwnode_handle;
 struct reset_control;
 
 /**
@@ -41,6 +42,10 @@ 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 *__fwnode_reset_control_get(struct fwnode_handle *node,
+						 const char *id, int index,
+						 bool shared, bool optional,
+						 bool acquired);
 struct reset_control *__of_reset_control_get(struct device_node *node,
 				     const char *id, int index, bool shared,
 				     bool optional, bool acquired);
@@ -114,6 +119,15 @@ static inline int __device_reset(struct device *dev, bool optional)
 	return optional ? 0 : -ENOTSUPP;
 }
 
+static inline
+struct reset_control *__fwnode_reset_control_get(struct fwnode_handle *node,
+						 const char *id, int index,
+						 bool shared, bool optional,
+						 bool acquired)
+{
+	return optional ? NULL : ERR_PTR(-ENOTSUPP);
+}
+
 static inline struct reset_control *__of_reset_control_get(
 					struct device_node *node,
 					const char *id, int index, bool shared,
