diff options
author | Linus Torvalds | 2021-04-30 12:48:14 -0700 |
---|---|---|
committer | Linus Torvalds | 2021-04-30 12:48:14 -0700 |
commit | b71428d7ab333a157216a1d73c8c82a178efada9 (patch) | |
tree | 94d268210d84948d5984f2fbe7d890c4aed1fabe /drivers/reset | |
parent | 95275402f66e88c56144a2d859c13594b651b29b (diff) | |
parent | 2e6a731296be9d356fdccee9fb6ae345dad96438 (diff) |
Merge tag 'sound-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"No surprises in this development cycle, and most of work is about the
fixes and the improvements of the existing code, while a new LED
control layer and a few new drivers have been introduced.
Here are some highlights:
Core:
- A common mute-LED framework was introduced. It is used by HD-audio
for now, more adaption will follow later. The former "Mic Mute-LED
Mode" mixer control has been replaced with the corresponding sysfs
now.
- User-control management was changed to count consumed bytes instead
of capping by number of elements; this will allow more controls in
the normal usage pattern while avoiding the possible memory
exhaustion DoS
ASoC:
- Continued refactoring and cleanups in ASoC core and generic card
drivers
- Wide range of small cppcheck and warning fixes
- New drivers for Freescale i.MX DMA over rpmsg, Mediatek MT6358
accessory detection, and Realtek RT1019, RT1316, RT711 and RT715
USB-audio:
- Continued improvements and fixes of the implicit feedback mode,
including better support for Pioneer and Roland/BOSS devices
HD-audio:
- Default back to non-buffer preallocation on x86
- Cirrus codec improvements, more quirks for Realtek codecs
Others:
- New virtio sound driver
- FireWire Bebob updates"
* tag 'sound-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (587 commits)
ALSA: hda/conexant: Re-order CX5066 quirk table entries
ALSA: hda/realtek: Remove redundant entry for ALC861 Haier/Uniwill devices
ALSA: hda/realtek: Re-order ALC662 quirk table entries
ALSA: hda/realtek: Re-order remaining ALC269 quirk table entries
ALSA: hda/realtek: Re-order ALC269 Lenovo quirk table entries
ALSA: hda/realtek: Re-order ALC269 Sony quirk table entries
ALSA: hda/realtek: Re-order ALC269 ASUS quirk table entries
ALSA: hda/realtek: Re-order ALC269 Dell quirk table entries
ALSA: hda/realtek: Re-order ALC269 Acer quirk table entries
ALSA: hda/realtek: Re-order ALC269 HP quirk table entries
ALSA: hda/realtek: Re-order ALC882 Clevo quirk table entries
ALSA: hda/realtek: Re-order ALC882 Sony quirk table entries
ALSA: hda/realtek: Re-order ALC882 Acer quirk table entries
ALSA: usb-audio: Remove redundant assignment to len
ALSA: hda/realtek: Add quirk for Intel Clevo PCx0Dx
ALSA: virtio: fix kernel-doc
ALSA: hda/cirrus: Use CS8409 filter to fix abnormal sounds on Bullseye
ALSA: hda/cirrus: Set Initial DMIC volume for Bullseye to -26 dB
ALSA: sb: Fix two use after free in snd_sb_qsound_build
ALSA: emu8000: Fix a use after free in snd_emu8000_create_mixer
...
Diffstat (limited to 'drivers/reset')
-rw-r--r-- | drivers/reset/core.c | 215 |
1 files changed, 215 insertions, 0 deletions
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 @@ -359,6 +359,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 * @@ -462,6 +486,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 * @@ -512,6 +566,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 * line is not asserted or if the desc is NULL (optional reset). @@ -589,6 +673,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 |