From: Dmitry Osipenko <digetx@gmail.com>
To: Thierry Reding <thierry.reding@gmail.com>,
Jonathan Hunter <jonathanh@nvidia.com>,
Mark Brown <broonie@kernel.org>, Takashi Iwai <tiwai@suse.com>,
Jaroslav Kysela <perex@perex.cz>,
Philipp Zabel <p.zabel@pengutronix.de>,
Paul Fertser <fercerpav@gmail.com>
Cc: linux-tegra@vger.kernel.org, devicetree@vger.kernel.org,
alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org
Subject: [PATCH v5 04/17] reset: Add reset_control_bulk API
Date: Sun, 14 Mar 2021 18:44:46 +0300 [thread overview]
Message-ID: <20210314154459.15375-5-digetx@gmail.com> (raw)
In-Reply-To: <20210314154459.15375-1-digetx@gmail.com>
From: Philipp Zabel <p.zabel@pengutronix.de>
Follow the clock and regulator subsystems' lead and add a bulk API
for reset controls.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Tested-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/reset/core.c | 215 ++++++++++++++++++++++++++++
include/linux/reset.h | 315 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 530 insertions(+)
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index dbf881b586d9..71c1c8264b2d 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -358,6 +358,30 @@ int reset_control_reset(struct reset_control *rstc)
}
EXPORT_SYMBOL_GPL(reset_control_reset);
+/**
+ * reset_control_bulk_reset - reset the controlled devices in order
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset controls set
+ *
+ * Issue a reset on all provided reset controls, in order.
+ *
+ * See also: reset_control_reset()
+ */
+int reset_control_bulk_reset(int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ int ret, i;
+
+ for (i = 0; i < num_rstcs; i++) {
+ ret = reset_control_reset(rstcs[i].rstc);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(reset_control_bulk_reset);
+
/**
* reset_control_rearm - allow shared reset line to be re-triggered"
* @rstc: reset controller
@@ -461,6 +485,36 @@ int reset_control_assert(struct reset_control *rstc)
}
EXPORT_SYMBOL_GPL(reset_control_assert);
+/**
+ * reset_control_bulk_assert - asserts the reset lines in order
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset controls set
+ *
+ * Assert the reset lines for all provided reset controls, in order.
+ * If an assertion fails, already asserted resets are deasserted again.
+ *
+ * See also: reset_control_assert()
+ */
+int reset_control_bulk_assert(int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ int ret, i;
+
+ for (i = 0; i < num_rstcs; i++) {
+ ret = reset_control_assert(rstcs[i].rstc);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+
+err:
+ while (i--)
+ reset_control_deassert(rstcs[i].rstc);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(reset_control_bulk_assert);
+
/**
* reset_control_deassert - deasserts the reset line
* @rstc: reset controller
@@ -511,6 +565,36 @@ int reset_control_deassert(struct reset_control *rstc)
}
EXPORT_SYMBOL_GPL(reset_control_deassert);
+/**
+ * reset_control_bulk_deassert - deasserts the reset lines in reverse order
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset controls set
+ *
+ * Deassert the reset lines for all provided reset controls, in reverse order.
+ * If a deassertion fails, already deasserted resets are asserted again.
+ *
+ * See also: reset_control_deassert()
+ */
+int reset_control_bulk_deassert(int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ int ret, i;
+
+ for (i = num_rstcs - 1; i >= 0; i--) {
+ ret = reset_control_deassert(rstcs[i].rstc);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+
+err:
+ while (i < num_rstcs)
+ reset_control_assert(rstcs[i++].rstc);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(reset_control_bulk_deassert);
+
/**
* reset_control_status - returns a negative errno if not supported, a
* positive value if the reset line is asserted, or zero if the reset
@@ -588,6 +672,36 @@ int reset_control_acquire(struct reset_control *rstc)
}
EXPORT_SYMBOL_GPL(reset_control_acquire);
+/**
+ * reset_control_bulk_acquire - acquires reset controls for exclusive use
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset controls set
+ *
+ * This is used to explicitly acquire reset controls requested with
+ * reset_control_bulk_get_exclusive_release() for temporary exclusive use.
+ *
+ * See also: reset_control_acquire(), reset_control_bulk_release()
+ */
+int reset_control_bulk_acquire(int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ int ret, i;
+
+ for (i = 0; i < num_rstcs; i++) {
+ ret = reset_control_acquire(rstcs[i].rstc);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+
+err:
+ while (i--)
+ reset_control_release(rstcs[i].rstc);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(reset_control_bulk_acquire);
+
/**
* reset_control_release() - releases exclusive access to a reset control
* @rstc: reset control
@@ -610,6 +724,26 @@ void reset_control_release(struct reset_control *rstc)
}
EXPORT_SYMBOL_GPL(reset_control_release);
+/**
+ * reset_control_bulk_release() - releases exclusive access to reset controls
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset controls set
+ *
+ * Releases exclusive access right to reset controls previously obtained by a
+ * call to reset_control_bulk_acquire().
+ *
+ * See also: reset_control_release(), reset_control_bulk_acquire()
+ */
+void reset_control_bulk_release(int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ int i;
+
+ for (i = 0; i < num_rstcs; i++)
+ reset_control_release(rstcs[i].rstc);
+}
+EXPORT_SYMBOL_GPL(reset_control_bulk_release);
+
static struct reset_control *__reset_control_get_internal(
struct reset_controller_dev *rcdev,
unsigned int index, bool shared, bool acquired)
@@ -814,6 +948,32 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id,
}
EXPORT_SYMBOL_GPL(__reset_control_get);
+int __reset_control_bulk_get(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs,
+ bool shared, bool optional, bool acquired)
+{
+ int ret, i;
+
+ for (i = 0; i < num_rstcs; i++) {
+ rstcs[i].rstc = __reset_control_get(dev, rstcs[i].id, 0,
+ shared, optional, acquired);
+ if (IS_ERR(rstcs[i].rstc)) {
+ ret = PTR_ERR(rstcs[i].rstc);
+ goto err;
+ }
+ }
+
+ return 0;
+
+err:
+ mutex_lock(&reset_list_mutex);
+ while (i--)
+ __reset_control_put_internal(rstcs[i].rstc);
+ mutex_unlock(&reset_list_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__reset_control_bulk_get);
+
static void reset_control_array_put(struct reset_control_array *resets)
{
int i;
@@ -845,6 +1005,23 @@ void reset_control_put(struct reset_control *rstc)
}
EXPORT_SYMBOL_GPL(reset_control_put);
+/**
+ * reset_control_bulk_put - free the reset controllers
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset controls set
+ */
+void reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs)
+{
+ mutex_lock(&reset_list_mutex);
+ while (num_rstcs--) {
+ if (IS_ERR_OR_NULL(rstcs[num_rstcs].rstc))
+ continue;
+ __reset_control_put_internal(rstcs[num_rstcs].rstc);
+ }
+ mutex_unlock(&reset_list_mutex);
+}
+EXPORT_SYMBOL_GPL(reset_control_bulk_put);
+
static void devm_reset_control_release(struct device *dev, void *res)
{
reset_control_put(*(struct reset_control **)res);
@@ -874,6 +1051,44 @@ struct reset_control *__devm_reset_control_get(struct device *dev,
}
EXPORT_SYMBOL_GPL(__devm_reset_control_get);
+struct reset_control_bulk_devres {
+ int num_rstcs;
+ struct reset_control_bulk_data *rstcs;
+};
+
+static void devm_reset_control_bulk_release(struct device *dev, void *res)
+{
+ struct reset_control_bulk_devres *devres = res;
+
+ reset_control_bulk_put(devres->num_rstcs, devres->rstcs);
+}
+
+int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs,
+ bool shared, bool optional, bool acquired)
+{
+ struct reset_control_bulk_devres *ptr;
+ int ret;
+
+ ptr = devres_alloc(devm_reset_control_bulk_release, sizeof(*ptr),
+ GFP_KERNEL);
+ if (!ptr)
+ return -ENOMEM;
+
+ ret = __reset_control_bulk_get(dev, num_rstcs, rstcs, shared, optional, acquired);
+ if (ret < 0) {
+ devres_free(ptr);
+ return ret;
+ }
+
+ ptr->num_rstcs = num_rstcs;
+ ptr->rstcs = rstcs;
+ devres_add(dev, ptr);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(__devm_reset_control_bulk_get);
+
/**
* __device_reset - find reset controller associated with the device
* and perform reset
diff --git a/include/linux/reset.h b/include/linux/reset.h
index b9109efa2a5c..46e6372cb431 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -10,6 +10,21 @@ struct device;
struct device_node;
struct reset_control;
+/**
+ * struct reset_control_bulk_data - Data used for bulk reset control operations.
+ *
+ * @id: reset control consumer ID
+ * @rstc: struct reset_control * to store the associated reset control
+ *
+ * The reset APIs provide a series of reset_control_bulk_*() API calls as
+ * a convenience to consumers which require multiple reset controls.
+ * This structure is used to manage data for these calls.
+ */
+struct reset_control_bulk_data {
+ const char *id;
+ struct reset_control *rstc;
+};
+
#ifdef CONFIG_RESET_CONTROLLER
int reset_control_reset(struct reset_control *rstc);
@@ -20,6 +35,12 @@ int reset_control_status(struct reset_control *rstc);
int reset_control_acquire(struct reset_control *rstc);
void reset_control_release(struct reset_control *rstc);
+int reset_control_bulk_reset(int num_rstcs, struct reset_control_bulk_data *rstcs);
+int reset_control_bulk_assert(int num_rstcs, struct reset_control_bulk_data *rstcs);
+int reset_control_bulk_deassert(int num_rstcs, struct reset_control_bulk_data *rstcs);
+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,
const char *id, int index, bool shared,
bool optional, bool acquired);
@@ -27,10 +48,18 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id,
int index, bool shared,
bool optional, bool acquired);
void reset_control_put(struct reset_control *rstc);
+int __reset_control_bulk_get(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs,
+ bool shared, bool optional, bool acquired);
+void reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs);
+
int __device_reset(struct device *dev, bool optional);
struct reset_control *__devm_reset_control_get(struct device *dev,
const char *id, int index, bool shared,
bool optional, bool acquired);
+int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs,
+ bool shared, bool optional, bool acquired);
struct reset_control *devm_reset_control_array_get(struct device *dev,
bool shared, bool optional);
@@ -96,6 +125,48 @@ static inline struct reset_control *__reset_control_get(
return optional ? NULL : ERR_PTR(-ENOTSUPP);
}
+static inline int
+reset_control_bulk_reset(int num_rstcs, struct reset_control_bulk_data *rstcs)
+{
+ return 0;
+}
+
+static inline int
+reset_control_bulk_assert(int num_rstcs, struct reset_control_bulk_data *rstcs)
+{
+ return 0;
+}
+
+static inline int
+reset_control_bulk_deassert(int num_rstcs, struct reset_control_bulk_data *rstcs)
+{
+ return 0;
+}
+
+static inline int
+reset_control_bulk_acquire(int num_rstcs, struct reset_control_bulk_data *rstcs)
+{
+ return 0;
+}
+
+static inline void
+reset_control_bulk_release(int num_rstcs, struct reset_control_bulk_data *rstcs)
+{
+}
+
+static inline int
+__reset_control_bulk_get(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs,
+ bool shared, bool optional, bool acquired)
+{
+ return optional ? 0 : -EOPNOTSUPP;
+}
+
+static inline void
+reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs)
+{
+}
+
static inline struct reset_control *__devm_reset_control_get(
struct device *dev, const char *id,
int index, bool shared, bool optional,
@@ -104,6 +175,14 @@ static inline struct reset_control *__devm_reset_control_get(
return optional ? NULL : ERR_PTR(-ENOTSUPP);
}
+static inline int
+__devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs,
+ bool shared, bool optional, bool acquired)
+{
+ return optional ? 0 : -EOPNOTSUPP;
+}
+
static inline struct reset_control *
devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
{
@@ -155,6 +234,23 @@ __must_check reset_control_get_exclusive(struct device *dev, const char *id)
return __reset_control_get(dev, id, 0, false, false, true);
}
+/**
+ * reset_control_bulk_get_exclusive - Lookup and obtain exclusive references to
+ * multiple reset controllers.
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Fills the rstcs array with pointers to exclusive reset controls and
+ * returns 0, or an IS_ERR() condition containing errno.
+ */
+static inline int __must_check
+reset_control_bulk_get_exclusive(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, true);
+}
+
/**
* reset_control_get_exclusive_released - Lookup and obtain a temoprarily
* exclusive reference to a reset
@@ -176,6 +272,48 @@ __must_check reset_control_get_exclusive_released(struct device *dev,
return __reset_control_get(dev, id, 0, false, false, false);
}
+/**
+ * reset_control_bulk_get_exclusive_released - Lookup and obtain temporarily
+ * exclusive references to multiple reset
+ * controllers.
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Fills the rstcs array with pointers to exclusive reset controls and
+ * returns 0, or an IS_ERR() condition containing errno.
+ * reset-controls returned by this function must be acquired via
+ * reset_control_bulk_acquire() before they can be used and should be released
+ * via reset_control_bulk_release() afterwards.
+ */
+static inline int __must_check
+reset_control_bulk_get_exclusive_released(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, false);
+}
+
+/**
+ * reset_control_bulk_get_optional_exclusive_released - Lookup and obtain optional
+ * temporarily exclusive references to multiple
+ * reset controllers.
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Optional variant of reset_control_bulk_get_exclusive_released(). If the
+ * requested reset is not specified in the device tree, this function returns 0
+ * instead of an error and missing rtsc is set to NULL.
+ *
+ * See reset_control_bulk_get_exclusive_released() for more information.
+ */
+static inline int __must_check
+reset_control_bulk_get_optional_exclusive_released(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, false);
+}
+
/**
* reset_control_get_shared - Lookup and obtain a shared reference to a
* reset controller.
@@ -204,6 +342,23 @@ static inline struct reset_control *reset_control_get_shared(
return __reset_control_get(dev, id, 0, true, false, false);
}
+/**
+ * reset_control_bulk_get_shared - Lookup and obtain shared references to
+ * multiple reset controllers.
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Fills the rstcs array with pointers to shared reset controls and
+ * returns 0, or an IS_ERR() condition containing errno.
+ */
+static inline int __must_check
+reset_control_bulk_get_shared(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, true, false, false);
+}
+
/**
* reset_control_get_optional_exclusive - optional reset_control_get_exclusive()
* @dev: device to be reset by the controller
@@ -221,6 +376,26 @@ static inline struct reset_control *reset_control_get_optional_exclusive(
return __reset_control_get(dev, id, 0, false, true, true);
}
+/**
+ * reset_control_bulk_get_optional_exclusive - optional
+ * reset_control_bulk_get_exclusive()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Optional variant of reset_control_bulk_get_exclusive(). If any of the
+ * requested resets are not specified in the device tree, this function sets
+ * them to NULL instead of returning an error.
+ *
+ * See reset_control_bulk_get_exclusive() for more information.
+ */
+static inline int __must_check
+reset_control_bulk_get_optional_exclusive(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, true);
+}
+
/**
* reset_control_get_optional_shared - optional reset_control_get_shared()
* @dev: device to be reset by the controller
@@ -238,6 +413,26 @@ static inline struct reset_control *reset_control_get_optional_shared(
return __reset_control_get(dev, id, 0, true, true, false);
}
+/**
+ * reset_control_bulk_get_optional_shared - optional
+ * reset_control_bulk_get_shared()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Optional variant of reset_control_bulk_get_shared(). If the requested resets
+ * are not specified in the device tree, this function sets them to NULL
+ * instead of returning an error.
+ *
+ * See reset_control_bulk_get_shared() for more information.
+ */
+static inline int __must_check
+reset_control_bulk_get_optional_shared(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, true, true, false);
+}
+
/**
* of_reset_control_get_exclusive - Lookup and obtain an exclusive reference
* to a reset controller.
@@ -343,6 +538,26 @@ __must_check devm_reset_control_get_exclusive(struct device *dev,
return __devm_reset_control_get(dev, id, 0, false, false, true);
}
+/**
+ * devm_reset_control_bulk_get_exclusive - resource managed
+ * reset_control_bulk_get_exclusive()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Managed reset_control_bulk_get_exclusive(). For reset controllers returned
+ * from this function, reset_control_put() is called automatically on driver
+ * detach.
+ *
+ * See reset_control_bulk_get_exclusive() for more information.
+ */
+static inline int __must_check
+devm_reset_control_bulk_get_exclusive(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, true);
+}
+
/**
* devm_reset_control_get_exclusive_released - resource managed
* reset_control_get_exclusive_released()
@@ -362,6 +577,26 @@ __must_check devm_reset_control_get_exclusive_released(struct device *dev,
return __devm_reset_control_get(dev, id, 0, false, false, false);
}
+/**
+ * devm_reset_control_bulk_get_exclusive_released - resource managed
+ * reset_control_bulk_get_exclusive_released()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Managed reset_control_bulk_get_exclusive_released(). For reset controllers
+ * returned from this function, reset_control_put() is called automatically on
+ * driver detach.
+ *
+ * See reset_control_bulk_get_exclusive_released() for more information.
+ */
+static inline int __must_check
+devm_reset_control_bulk_get_exclusive_released(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, false);
+}
+
/**
* devm_reset_control_get_optional_exclusive_released - resource managed
* reset_control_get_optional_exclusive_released()
@@ -381,6 +616,26 @@ __must_check devm_reset_control_get_optional_exclusive_released(struct device *d
return __devm_reset_control_get(dev, id, 0, false, true, false);
}
+/**
+ * devm_reset_control_bulk_get_optional_exclusive_released - resource managed
+ * reset_control_bulk_optional_get_exclusive_released()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Managed reset_control_bulk_optional_get_exclusive_released(). For reset
+ * controllers returned from this function, reset_control_put() is called
+ * automatically on driver detach.
+ *
+ * See reset_control_bulk_optional_get_exclusive_released() for more information.
+ */
+static inline int __must_check
+devm_reset_control_bulk_get_optional_exclusive_released(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, false);
+}
+
/**
* devm_reset_control_get_shared - resource managed reset_control_get_shared()
* @dev: device to be reset by the controller
@@ -396,6 +651,26 @@ static inline struct reset_control *devm_reset_control_get_shared(
return __devm_reset_control_get(dev, id, 0, true, false, false);
}
+/**
+ * devm_reset_control_bulk_get_shared - resource managed
+ * reset_control_bulk_get_shared()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Managed reset_control_bulk_get_shared(). For reset controllers returned
+ * from this function, reset_control_put() is called automatically on driver
+ * detach.
+ *
+ * See reset_control_bulk_get_shared() for more information.
+ */
+static inline int __must_check
+devm_reset_control_bulk_get_shared(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, true, false, false);
+}
+
/**
* devm_reset_control_get_optional_exclusive - resource managed
* reset_control_get_optional_exclusive()
@@ -414,6 +689,26 @@ static inline struct reset_control *devm_reset_control_get_optional_exclusive(
return __devm_reset_control_get(dev, id, 0, false, true, true);
}
+/**
+ * devm_reset_control_bulk_get_optional_exclusive - resource managed
+ * reset_control_bulk_get_optional_exclusive()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Managed reset_control_bulk_get_optional_exclusive(). For reset controllers
+ * returned from this function, reset_control_put() is called automatically on
+ * driver detach.
+ *
+ * See reset_control_bulk_get_optional_exclusive() for more information.
+ */
+static inline int __must_check
+devm_reset_control_bulk_get_optional_exclusive(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, true, false, true);
+}
+
/**
* devm_reset_control_get_optional_shared - resource managed
* reset_control_get_optional_shared()
@@ -432,6 +727,26 @@ static inline struct reset_control *devm_reset_control_get_optional_shared(
return __devm_reset_control_get(dev, id, 0, true, true, false);
}
+/**
+ * devm_reset_control_bulk_get_optional_shared - resource managed
+ * reset_control_bulk_get_optional_shared()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Managed reset_control_bulk_get_optional_shared(). For reset controllers
+ * returned from this function, reset_control_put() is called automatically on
+ * driver detach.
+ *
+ * See reset_control_bulk_get_optional_shared() for more information.
+ */
+static inline int __must_check
+devm_reset_control_bulk_get_optional_shared(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, true, true, false);
+}
+
/**
* devm_reset_control_get_exclusive_by_index - resource managed
* reset_control_get_exclusive()
--
2.30.2
WARNING: multiple messages have this Message-ID (diff)
From: Dmitry Osipenko <digetx@gmail.com>
To: Thierry Reding <thierry.reding@gmail.com>,
Jonathan Hunter <jonathanh@nvidia.com>,
Mark Brown <broonie@kernel.org>, Takashi Iwai <tiwai@suse.com>,
Jaroslav Kysela <perex@perex.cz>,
Philipp Zabel <p.zabel@pengutronix.de>,
Paul Fertser <fercerpav@gmail.com>
Cc: alsa-devel@alsa-project.org, devicetree@vger.kernel.org,
linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v5 04/17] reset: Add reset_control_bulk API
Date: Sun, 14 Mar 2021 18:44:46 +0300 [thread overview]
Message-ID: <20210314154459.15375-5-digetx@gmail.com> (raw)
In-Reply-To: <20210314154459.15375-1-digetx@gmail.com>
From: Philipp Zabel <p.zabel@pengutronix.de>
Follow the clock and regulator subsystems' lead and add a bulk API
for reset controls.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Tested-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/reset/core.c | 215 ++++++++++++++++++++++++++++
include/linux/reset.h | 315 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 530 insertions(+)
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index dbf881b586d9..71c1c8264b2d 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -358,6 +358,30 @@ int reset_control_reset(struct reset_control *rstc)
}
EXPORT_SYMBOL_GPL(reset_control_reset);
+/**
+ * reset_control_bulk_reset - reset the controlled devices in order
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset controls set
+ *
+ * Issue a reset on all provided reset controls, in order.
+ *
+ * See also: reset_control_reset()
+ */
+int reset_control_bulk_reset(int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ int ret, i;
+
+ for (i = 0; i < num_rstcs; i++) {
+ ret = reset_control_reset(rstcs[i].rstc);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(reset_control_bulk_reset);
+
/**
* reset_control_rearm - allow shared reset line to be re-triggered"
* @rstc: reset controller
@@ -461,6 +485,36 @@ int reset_control_assert(struct reset_control *rstc)
}
EXPORT_SYMBOL_GPL(reset_control_assert);
+/**
+ * reset_control_bulk_assert - asserts the reset lines in order
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset controls set
+ *
+ * Assert the reset lines for all provided reset controls, in order.
+ * If an assertion fails, already asserted resets are deasserted again.
+ *
+ * See also: reset_control_assert()
+ */
+int reset_control_bulk_assert(int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ int ret, i;
+
+ for (i = 0; i < num_rstcs; i++) {
+ ret = reset_control_assert(rstcs[i].rstc);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+
+err:
+ while (i--)
+ reset_control_deassert(rstcs[i].rstc);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(reset_control_bulk_assert);
+
/**
* reset_control_deassert - deasserts the reset line
* @rstc: reset controller
@@ -511,6 +565,36 @@ int reset_control_deassert(struct reset_control *rstc)
}
EXPORT_SYMBOL_GPL(reset_control_deassert);
+/**
+ * reset_control_bulk_deassert - deasserts the reset lines in reverse order
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset controls set
+ *
+ * Deassert the reset lines for all provided reset controls, in reverse order.
+ * If a deassertion fails, already deasserted resets are asserted again.
+ *
+ * See also: reset_control_deassert()
+ */
+int reset_control_bulk_deassert(int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ int ret, i;
+
+ for (i = num_rstcs - 1; i >= 0; i--) {
+ ret = reset_control_deassert(rstcs[i].rstc);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+
+err:
+ while (i < num_rstcs)
+ reset_control_assert(rstcs[i++].rstc);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(reset_control_bulk_deassert);
+
/**
* reset_control_status - returns a negative errno if not supported, a
* positive value if the reset line is asserted, or zero if the reset
@@ -588,6 +672,36 @@ int reset_control_acquire(struct reset_control *rstc)
}
EXPORT_SYMBOL_GPL(reset_control_acquire);
+/**
+ * reset_control_bulk_acquire - acquires reset controls for exclusive use
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset controls set
+ *
+ * This is used to explicitly acquire reset controls requested with
+ * reset_control_bulk_get_exclusive_release() for temporary exclusive use.
+ *
+ * See also: reset_control_acquire(), reset_control_bulk_release()
+ */
+int reset_control_bulk_acquire(int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ int ret, i;
+
+ for (i = 0; i < num_rstcs; i++) {
+ ret = reset_control_acquire(rstcs[i].rstc);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+
+err:
+ while (i--)
+ reset_control_release(rstcs[i].rstc);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(reset_control_bulk_acquire);
+
/**
* reset_control_release() - releases exclusive access to a reset control
* @rstc: reset control
@@ -610,6 +724,26 @@ void reset_control_release(struct reset_control *rstc)
}
EXPORT_SYMBOL_GPL(reset_control_release);
+/**
+ * reset_control_bulk_release() - releases exclusive access to reset controls
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset controls set
+ *
+ * Releases exclusive access right to reset controls previously obtained by a
+ * call to reset_control_bulk_acquire().
+ *
+ * See also: reset_control_release(), reset_control_bulk_acquire()
+ */
+void reset_control_bulk_release(int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ int i;
+
+ for (i = 0; i < num_rstcs; i++)
+ reset_control_release(rstcs[i].rstc);
+}
+EXPORT_SYMBOL_GPL(reset_control_bulk_release);
+
static struct reset_control *__reset_control_get_internal(
struct reset_controller_dev *rcdev,
unsigned int index, bool shared, bool acquired)
@@ -814,6 +948,32 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id,
}
EXPORT_SYMBOL_GPL(__reset_control_get);
+int __reset_control_bulk_get(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs,
+ bool shared, bool optional, bool acquired)
+{
+ int ret, i;
+
+ for (i = 0; i < num_rstcs; i++) {
+ rstcs[i].rstc = __reset_control_get(dev, rstcs[i].id, 0,
+ shared, optional, acquired);
+ if (IS_ERR(rstcs[i].rstc)) {
+ ret = PTR_ERR(rstcs[i].rstc);
+ goto err;
+ }
+ }
+
+ return 0;
+
+err:
+ mutex_lock(&reset_list_mutex);
+ while (i--)
+ __reset_control_put_internal(rstcs[i].rstc);
+ mutex_unlock(&reset_list_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__reset_control_bulk_get);
+
static void reset_control_array_put(struct reset_control_array *resets)
{
int i;
@@ -845,6 +1005,23 @@ void reset_control_put(struct reset_control *rstc)
}
EXPORT_SYMBOL_GPL(reset_control_put);
+/**
+ * reset_control_bulk_put - free the reset controllers
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset controls set
+ */
+void reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs)
+{
+ mutex_lock(&reset_list_mutex);
+ while (num_rstcs--) {
+ if (IS_ERR_OR_NULL(rstcs[num_rstcs].rstc))
+ continue;
+ __reset_control_put_internal(rstcs[num_rstcs].rstc);
+ }
+ mutex_unlock(&reset_list_mutex);
+}
+EXPORT_SYMBOL_GPL(reset_control_bulk_put);
+
static void devm_reset_control_release(struct device *dev, void *res)
{
reset_control_put(*(struct reset_control **)res);
@@ -874,6 +1051,44 @@ struct reset_control *__devm_reset_control_get(struct device *dev,
}
EXPORT_SYMBOL_GPL(__devm_reset_control_get);
+struct reset_control_bulk_devres {
+ int num_rstcs;
+ struct reset_control_bulk_data *rstcs;
+};
+
+static void devm_reset_control_bulk_release(struct device *dev, void *res)
+{
+ struct reset_control_bulk_devres *devres = res;
+
+ reset_control_bulk_put(devres->num_rstcs, devres->rstcs);
+}
+
+int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs,
+ bool shared, bool optional, bool acquired)
+{
+ struct reset_control_bulk_devres *ptr;
+ int ret;
+
+ ptr = devres_alloc(devm_reset_control_bulk_release, sizeof(*ptr),
+ GFP_KERNEL);
+ if (!ptr)
+ return -ENOMEM;
+
+ ret = __reset_control_bulk_get(dev, num_rstcs, rstcs, shared, optional, acquired);
+ if (ret < 0) {
+ devres_free(ptr);
+ return ret;
+ }
+
+ ptr->num_rstcs = num_rstcs;
+ ptr->rstcs = rstcs;
+ devres_add(dev, ptr);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(__devm_reset_control_bulk_get);
+
/**
* __device_reset - find reset controller associated with the device
* and perform reset
diff --git a/include/linux/reset.h b/include/linux/reset.h
index b9109efa2a5c..46e6372cb431 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -10,6 +10,21 @@ struct device;
struct device_node;
struct reset_control;
+/**
+ * struct reset_control_bulk_data - Data used for bulk reset control operations.
+ *
+ * @id: reset control consumer ID
+ * @rstc: struct reset_control * to store the associated reset control
+ *
+ * The reset APIs provide a series of reset_control_bulk_*() API calls as
+ * a convenience to consumers which require multiple reset controls.
+ * This structure is used to manage data for these calls.
+ */
+struct reset_control_bulk_data {
+ const char *id;
+ struct reset_control *rstc;
+};
+
#ifdef CONFIG_RESET_CONTROLLER
int reset_control_reset(struct reset_control *rstc);
@@ -20,6 +35,12 @@ int reset_control_status(struct reset_control *rstc);
int reset_control_acquire(struct reset_control *rstc);
void reset_control_release(struct reset_control *rstc);
+int reset_control_bulk_reset(int num_rstcs, struct reset_control_bulk_data *rstcs);
+int reset_control_bulk_assert(int num_rstcs, struct reset_control_bulk_data *rstcs);
+int reset_control_bulk_deassert(int num_rstcs, struct reset_control_bulk_data *rstcs);
+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,
const char *id, int index, bool shared,
bool optional, bool acquired);
@@ -27,10 +48,18 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id,
int index, bool shared,
bool optional, bool acquired);
void reset_control_put(struct reset_control *rstc);
+int __reset_control_bulk_get(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs,
+ bool shared, bool optional, bool acquired);
+void reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs);
+
int __device_reset(struct device *dev, bool optional);
struct reset_control *__devm_reset_control_get(struct device *dev,
const char *id, int index, bool shared,
bool optional, bool acquired);
+int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs,
+ bool shared, bool optional, bool acquired);
struct reset_control *devm_reset_control_array_get(struct device *dev,
bool shared, bool optional);
@@ -96,6 +125,48 @@ static inline struct reset_control *__reset_control_get(
return optional ? NULL : ERR_PTR(-ENOTSUPP);
}
+static inline int
+reset_control_bulk_reset(int num_rstcs, struct reset_control_bulk_data *rstcs)
+{
+ return 0;
+}
+
+static inline int
+reset_control_bulk_assert(int num_rstcs, struct reset_control_bulk_data *rstcs)
+{
+ return 0;
+}
+
+static inline int
+reset_control_bulk_deassert(int num_rstcs, struct reset_control_bulk_data *rstcs)
+{
+ return 0;
+}
+
+static inline int
+reset_control_bulk_acquire(int num_rstcs, struct reset_control_bulk_data *rstcs)
+{
+ return 0;
+}
+
+static inline void
+reset_control_bulk_release(int num_rstcs, struct reset_control_bulk_data *rstcs)
+{
+}
+
+static inline int
+__reset_control_bulk_get(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs,
+ bool shared, bool optional, bool acquired)
+{
+ return optional ? 0 : -EOPNOTSUPP;
+}
+
+static inline void
+reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs)
+{
+}
+
static inline struct reset_control *__devm_reset_control_get(
struct device *dev, const char *id,
int index, bool shared, bool optional,
@@ -104,6 +175,14 @@ static inline struct reset_control *__devm_reset_control_get(
return optional ? NULL : ERR_PTR(-ENOTSUPP);
}
+static inline int
+__devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs,
+ bool shared, bool optional, bool acquired)
+{
+ return optional ? 0 : -EOPNOTSUPP;
+}
+
static inline struct reset_control *
devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
{
@@ -155,6 +234,23 @@ __must_check reset_control_get_exclusive(struct device *dev, const char *id)
return __reset_control_get(dev, id, 0, false, false, true);
}
+/**
+ * reset_control_bulk_get_exclusive - Lookup and obtain exclusive references to
+ * multiple reset controllers.
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Fills the rstcs array with pointers to exclusive reset controls and
+ * returns 0, or an IS_ERR() condition containing errno.
+ */
+static inline int __must_check
+reset_control_bulk_get_exclusive(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, true);
+}
+
/**
* reset_control_get_exclusive_released - Lookup and obtain a temoprarily
* exclusive reference to a reset
@@ -176,6 +272,48 @@ __must_check reset_control_get_exclusive_released(struct device *dev,
return __reset_control_get(dev, id, 0, false, false, false);
}
+/**
+ * reset_control_bulk_get_exclusive_released - Lookup and obtain temporarily
+ * exclusive references to multiple reset
+ * controllers.
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Fills the rstcs array with pointers to exclusive reset controls and
+ * returns 0, or an IS_ERR() condition containing errno.
+ * reset-controls returned by this function must be acquired via
+ * reset_control_bulk_acquire() before they can be used and should be released
+ * via reset_control_bulk_release() afterwards.
+ */
+static inline int __must_check
+reset_control_bulk_get_exclusive_released(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, false);
+}
+
+/**
+ * reset_control_bulk_get_optional_exclusive_released - Lookup and obtain optional
+ * temporarily exclusive references to multiple
+ * reset controllers.
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Optional variant of reset_control_bulk_get_exclusive_released(). If the
+ * requested reset is not specified in the device tree, this function returns 0
+ * instead of an error and missing rtsc is set to NULL.
+ *
+ * See reset_control_bulk_get_exclusive_released() for more information.
+ */
+static inline int __must_check
+reset_control_bulk_get_optional_exclusive_released(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, false);
+}
+
/**
* reset_control_get_shared - Lookup and obtain a shared reference to a
* reset controller.
@@ -204,6 +342,23 @@ static inline struct reset_control *reset_control_get_shared(
return __reset_control_get(dev, id, 0, true, false, false);
}
+/**
+ * reset_control_bulk_get_shared - Lookup and obtain shared references to
+ * multiple reset controllers.
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Fills the rstcs array with pointers to shared reset controls and
+ * returns 0, or an IS_ERR() condition containing errno.
+ */
+static inline int __must_check
+reset_control_bulk_get_shared(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, true, false, false);
+}
+
/**
* reset_control_get_optional_exclusive - optional reset_control_get_exclusive()
* @dev: device to be reset by the controller
@@ -221,6 +376,26 @@ static inline struct reset_control *reset_control_get_optional_exclusive(
return __reset_control_get(dev, id, 0, false, true, true);
}
+/**
+ * reset_control_bulk_get_optional_exclusive - optional
+ * reset_control_bulk_get_exclusive()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Optional variant of reset_control_bulk_get_exclusive(). If any of the
+ * requested resets are not specified in the device tree, this function sets
+ * them to NULL instead of returning an error.
+ *
+ * See reset_control_bulk_get_exclusive() for more information.
+ */
+static inline int __must_check
+reset_control_bulk_get_optional_exclusive(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, true);
+}
+
/**
* reset_control_get_optional_shared - optional reset_control_get_shared()
* @dev: device to be reset by the controller
@@ -238,6 +413,26 @@ static inline struct reset_control *reset_control_get_optional_shared(
return __reset_control_get(dev, id, 0, true, true, false);
}
+/**
+ * reset_control_bulk_get_optional_shared - optional
+ * reset_control_bulk_get_shared()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Optional variant of reset_control_bulk_get_shared(). If the requested resets
+ * are not specified in the device tree, this function sets them to NULL
+ * instead of returning an error.
+ *
+ * See reset_control_bulk_get_shared() for more information.
+ */
+static inline int __must_check
+reset_control_bulk_get_optional_shared(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, true, true, false);
+}
+
/**
* of_reset_control_get_exclusive - Lookup and obtain an exclusive reference
* to a reset controller.
@@ -343,6 +538,26 @@ __must_check devm_reset_control_get_exclusive(struct device *dev,
return __devm_reset_control_get(dev, id, 0, false, false, true);
}
+/**
+ * devm_reset_control_bulk_get_exclusive - resource managed
+ * reset_control_bulk_get_exclusive()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Managed reset_control_bulk_get_exclusive(). For reset controllers returned
+ * from this function, reset_control_put() is called automatically on driver
+ * detach.
+ *
+ * See reset_control_bulk_get_exclusive() for more information.
+ */
+static inline int __must_check
+devm_reset_control_bulk_get_exclusive(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, true);
+}
+
/**
* devm_reset_control_get_exclusive_released - resource managed
* reset_control_get_exclusive_released()
@@ -362,6 +577,26 @@ __must_check devm_reset_control_get_exclusive_released(struct device *dev,
return __devm_reset_control_get(dev, id, 0, false, false, false);
}
+/**
+ * devm_reset_control_bulk_get_exclusive_released - resource managed
+ * reset_control_bulk_get_exclusive_released()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Managed reset_control_bulk_get_exclusive_released(). For reset controllers
+ * returned from this function, reset_control_put() is called automatically on
+ * driver detach.
+ *
+ * See reset_control_bulk_get_exclusive_released() for more information.
+ */
+static inline int __must_check
+devm_reset_control_bulk_get_exclusive_released(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, false);
+}
+
/**
* devm_reset_control_get_optional_exclusive_released - resource managed
* reset_control_get_optional_exclusive_released()
@@ -381,6 +616,26 @@ __must_check devm_reset_control_get_optional_exclusive_released(struct device *d
return __devm_reset_control_get(dev, id, 0, false, true, false);
}
+/**
+ * devm_reset_control_bulk_get_optional_exclusive_released - resource managed
+ * reset_control_bulk_optional_get_exclusive_released()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Managed reset_control_bulk_optional_get_exclusive_released(). For reset
+ * controllers returned from this function, reset_control_put() is called
+ * automatically on driver detach.
+ *
+ * See reset_control_bulk_optional_get_exclusive_released() for more information.
+ */
+static inline int __must_check
+devm_reset_control_bulk_get_optional_exclusive_released(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, false);
+}
+
/**
* devm_reset_control_get_shared - resource managed reset_control_get_shared()
* @dev: device to be reset by the controller
@@ -396,6 +651,26 @@ static inline struct reset_control *devm_reset_control_get_shared(
return __devm_reset_control_get(dev, id, 0, true, false, false);
}
+/**
+ * devm_reset_control_bulk_get_shared - resource managed
+ * reset_control_bulk_get_shared()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Managed reset_control_bulk_get_shared(). For reset controllers returned
+ * from this function, reset_control_put() is called automatically on driver
+ * detach.
+ *
+ * See reset_control_bulk_get_shared() for more information.
+ */
+static inline int __must_check
+devm_reset_control_bulk_get_shared(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, true, false, false);
+}
+
/**
* devm_reset_control_get_optional_exclusive - resource managed
* reset_control_get_optional_exclusive()
@@ -414,6 +689,26 @@ static inline struct reset_control *devm_reset_control_get_optional_exclusive(
return __devm_reset_control_get(dev, id, 0, false, true, true);
}
+/**
+ * devm_reset_control_bulk_get_optional_exclusive - resource managed
+ * reset_control_bulk_get_optional_exclusive()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Managed reset_control_bulk_get_optional_exclusive(). For reset controllers
+ * returned from this function, reset_control_put() is called automatically on
+ * driver detach.
+ *
+ * See reset_control_bulk_get_optional_exclusive() for more information.
+ */
+static inline int __must_check
+devm_reset_control_bulk_get_optional_exclusive(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, true, false, true);
+}
+
/**
* devm_reset_control_get_optional_shared - resource managed
* reset_control_get_optional_shared()
@@ -432,6 +727,26 @@ static inline struct reset_control *devm_reset_control_get_optional_shared(
return __devm_reset_control_get(dev, id, 0, true, true, false);
}
+/**
+ * devm_reset_control_bulk_get_optional_shared - resource managed
+ * reset_control_bulk_get_optional_shared()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Managed reset_control_bulk_get_optional_shared(). For reset controllers
+ * returned from this function, reset_control_put() is called automatically on
+ * driver detach.
+ *
+ * See reset_control_bulk_get_optional_shared() for more information.
+ */
+static inline int __must_check
+devm_reset_control_bulk_get_optional_shared(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, true, true, false);
+}
+
/**
* devm_reset_control_get_exclusive_by_index - resource managed
* reset_control_get_exclusive()
--
2.30.2
next prev parent reply other threads:[~2021-03-14 15:50 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-14 15:44 [PATCH v5 00/17] Fix reset controls and RPM of NVIDIA Tegra ASoC drivers Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 01/17] ASoC: tegra20: ac97: Add reset control Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 02/17] ASoC: tegra20: i2s: " Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 03/17] ASoC: tegra30: i2s: Restore hardware state on runtime PM resume Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko [this message]
2021-03-14 15:44 ` [PATCH v5 04/17] reset: Add reset_control_bulk API Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 05/17] ASoC: tegra30: ahub: Switch to use reset-bulk API Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 06/17] ASoC: tegra20: spdif: Correct driver removal order Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 07/17] ASoC: tegra20: spdif: Remove handing of disabled runtime PM Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 08/17] ASoC: tegra20: i2s: Add system level suspend-resume callbacks Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 09/17] ASoC: tegra20: i2s: Correct driver removal order Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 10/17] ASoC: tegra20: i2s: Use devm_clk_get() Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 11/17] ASoC: tegra20: i2s: Remove handing of disabled runtime PM Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 12/17] ASoC: tegra30: i2s: Correct driver removal order Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 13/17] ASoC: tegra30: i2s: Use devm_clk_get() Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 14/17] ASoC: tegra30: i2s: Remove handing of disabled runtime PM Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 15/17] ASoC: tegra30: ahub: Reset global variable Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 16/17] ASoC: tegra30: ahub: Correct suspend-resume callbacks Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-14 15:44 ` [PATCH v5 17/17] ASoC: tegra30: ahub: Remove handing of disabled runtime PM Dmitry Osipenko
2021-03-14 15:44 ` Dmitry Osipenko
2021-03-17 17:20 ` [PATCH v5 00/17] Fix reset controls and RPM of NVIDIA Tegra ASoC drivers Dmitry Osipenko
2021-03-17 17:20 ` Dmitry Osipenko
2021-03-17 17:54 ` Mark Brown
2021-03-17 17:54 ` Mark Brown
2021-03-17 18:12 ` Dmitry Osipenko
2021-03-17 18:12 ` Dmitry Osipenko
2021-03-18 18:33 ` Mark Brown
2021-03-18 18:36 ` Mark Brown
2021-03-18 18:36 ` Mark Brown
2021-03-18 18:33 ` Mark Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210314154459.15375-5-digetx@gmail.com \
--to=digetx@gmail.com \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=fercerpav@gmail.com \
--cc=jonathanh@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
--cc=p.zabel@pengutronix.de \
--cc=perex@perex.cz \
--cc=thierry.reding@gmail.com \
--cc=tiwai@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.