--- /dev/null
+From ae26c08e6c8071ba8febb0c7c0829da96c75248c Mon Sep 17 00:00:00 2001
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Date: Mon, 22 Nov 2021 17:22:54 -0600
+Subject: ALSA: intel-dsp-config: add quirk for CML devices based on ES8336 codec
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+commit ae26c08e6c8071ba8febb0c7c0829da96c75248c upstream.
+
+We've added quirks for ESS8336 but missed CML, add quirks for both LP
+and H versions.
+
+BugLink: https://github.com/thesofproject/linux/issues/3248
+Fixes: 9d36ceab9415 ("ALSA: intel-dsp-config: add quirk for APL/GLK/TGL devices based on ES8336 codec")
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20211122232254.23362-1-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/hda/intel-dsp-config.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/sound/hda/intel-dsp-config.c
++++ b/sound/hda/intel-dsp-config.c
+@@ -252,6 +252,11 @@ static const struct config_entry config_
+ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
+ .device = 0x02c8,
+ },
++ {
++ .flags = FLAG_SOF,
++ .device = 0x02c8,
++ .codec_hid = "ESSX8336",
++ },
+ /* Cometlake-H */
+ {
+ .flags = FLAG_SOF,
+@@ -276,6 +281,11 @@ static const struct config_entry config_
+ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
+ .device = 0x06c8,
+ },
++ {
++ .flags = FLAG_SOF,
++ .device = 0x06c8,
++ .codec_hid = "ESSX8336",
++ },
+ #endif
+
+ /* Icelake */
--- /dev/null
+From 35b6b28e69985eafb20b3b2c7bd6eca452b56b53 Mon Sep 17 00:00:00 2001
+From: Mark Rutland <mark.rutland@arm.com>
+Date: Mon, 29 Nov 2021 13:57:09 +0000
+Subject: arm64: ftrace: add missing BTIs
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+commit 35b6b28e69985eafb20b3b2c7bd6eca452b56b53 upstream.
+
+When branch target identifiers are in use, code reachable via an
+indirect branch requires a BTI landing pad at the branch target site.
+
+When building FTRACE_WITH_REGS atop patchable-function-entry, we miss
+BTIs at the start start of the `ftrace_caller` and `ftrace_regs_caller`
+trampolines, and when these are called from a module via a PLT (which
+will use a `BR X16`), we will encounter a BTI failure, e.g.
+
+| # insmod lkdtm.ko
+| lkdtm: No crash points registered, enable through debugfs
+| # echo function_graph > /sys/kernel/debug/tracing/current_tracer
+| # cat /sys/kernel/debug/provoke-crash/DIRECT
+| Unhandled 64-bit el1h sync exception on CPU0, ESR 0x34000001 -- BTI
+| CPU: 0 PID: 174 Comm: cat Not tainted 5.16.0-rc2-dirty #3
+| Hardware name: linux,dummy-virt (DT)
+| pstate: 60400405 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=jc)
+| pc : ftrace_caller+0x0/0x3c
+| lr : lkdtm_debugfs_open+0xc/0x20 [lkdtm]
+| sp : ffff800012e43b00
+| x29: ffff800012e43b00 x28: 0000000000000000 x27: ffff800012e43c88
+| x26: 0000000000000000 x25: 0000000000000000 x24: ffff0000c171f200
+| x23: ffff0000c27b1e00 x22: ffff0000c2265240 x21: ffff0000c23c8c30
+| x20: ffff8000090ba380 x19: 0000000000000000 x18: 0000000000000000
+| x17: 0000000000000000 x16: ffff80001002bb4c x15: 0000000000000000
+| x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000900ff0
+| x11: ffff0000c4166310 x10: ffff800012e43b00 x9 : ffff8000104f2384
+| x8 : 0000000000000001 x7 : 0000000000000000 x6 : 000000000000003f
+| x5 : 0000000000000040 x4 : ffff800012e43af0 x3 : 0000000000000001
+| x2 : ffff8000090b0000 x1 : ffff0000c171f200 x0 : ffff0000c23c8c30
+| Kernel panic - not syncing: Unhandled exception
+| CPU: 0 PID: 174 Comm: cat Not tainted 5.16.0-rc2-dirty #3
+| Hardware name: linux,dummy-virt (DT)
+| Call trace:
+| dump_backtrace+0x0/0x1a4
+| show_stack+0x24/0x30
+| dump_stack_lvl+0x68/0x84
+| dump_stack+0x1c/0x38
+| panic+0x168/0x360
+| arm64_exit_nmi.isra.0+0x0/0x80
+| el1h_64_sync_handler+0x68/0xd4
+| el1h_64_sync+0x78/0x7c
+| ftrace_caller+0x0/0x3c
+| do_dentry_open+0x134/0x3b0
+| vfs_open+0x38/0x44
+| path_openat+0x89c/0xe40
+| do_filp_open+0x8c/0x13c
+| do_sys_openat2+0xbc/0x174
+| __arm64_sys_openat+0x6c/0xbc
+| invoke_syscall+0x50/0x120
+| el0_svc_common.constprop.0+0xdc/0x100
+| do_el0_svc+0x84/0xa0
+| el0_svc+0x28/0x80
+| el0t_64_sync_handler+0xa8/0x130
+| el0t_64_sync+0x1a0/0x1a4
+| SMP: stopping secondary CPUs
+| Kernel Offset: disabled
+| CPU features: 0x0,00000f42,da660c5f
+| Memory Limit: none
+| ---[ end Kernel panic - not syncing: Unhandled exception ]---
+
+Fix this by adding the required `BTI C`, as we only require these to be
+reachable via BL for direct calls or BR X16/X17 for PLTs. For now, these
+are open-coded in the function prologue, matching the style of the
+`__hwasan_tag_mismatch` trampoline.
+
+In future we may wish to consider adding a new SYM_CODE_START_*()
+variant which has an implicit BTI.
+
+When ftrace is built atop mcount, the trampolines are marked with
+SYM_FUNC_START(), and so get an implicit BTI. We may need to change
+these over to SYM_CODE_START() in future for RELIABLE_STACKTRACE, in
+case we need to apply special care aroud the return address being
+rewritten.
+
+Fixes: 97fed779f2a6 ("arm64: bti: Provide Kconfig for kernel mode BTI")
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Will Deacon <will@kernel.org>
+Reviewed-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20211129135709.2274019-1-mark.rutland@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kernel/entry-ftrace.S | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/arm64/kernel/entry-ftrace.S
++++ b/arch/arm64/kernel/entry-ftrace.S
+@@ -77,11 +77,17 @@
+ .endm
+
+ SYM_CODE_START(ftrace_regs_caller)
++#ifdef BTI_C
++ BTI_C
++#endif
+ ftrace_regs_entry 1
+ b ftrace_common
+ SYM_CODE_END(ftrace_regs_caller)
+
+ SYM_CODE_START(ftrace_caller)
++#ifdef BTI_C
++ BTI_C
++#endif
+ ftrace_regs_entry 0
+ b ftrace_common
+ SYM_CODE_END(ftrace_caller)
--- /dev/null
+From e2b87a18a60c02d0dcd1de801d669587e516cc4d Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:37:02 +0530
+Subject: ASoC: tegra: Fix kcontrol put callback in ADMAIF
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+commit e2b87a18a60c02d0dcd1de801d669587e516cc4d upstream.
+
+The kcontrol put callback is expected to return 1 when there is change
+in HW or when the update is acknowledged by driver. This would ensure
+that change notifications are sent to subscribed applications. Update
+the ADMAIF driver accordingly.
+
+Fixes: f74028e159bb ("ASoC: tegra: Add Tegra210 based ADMAIF driver")
+Suggested-by: Jaroslav Kysela <perex@perex.cz>
+Suggested-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-8-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/tegra/tegra210_admaif.c | 138 ++++++++++++++++++++++++++++++--------
+ 1 file changed, 109 insertions(+), 29 deletions(-)
+
+--- a/sound/soc/tegra/tegra210_admaif.c
++++ b/sound/soc/tegra/tegra210_admaif.c
+@@ -424,46 +424,122 @@ static const struct snd_soc_dai_ops tegr
+ .trigger = tegra_admaif_trigger,
+ };
+
+-static int tegra_admaif_get_control(struct snd_kcontrol *kcontrol,
+- struct snd_ctl_elem_value *ucontrol)
++static int tegra210_admaif_pget_mono_to_stereo(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
+ {
+ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
+ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
++
++ ucontrol->value.enumerated.item[0] =
++ admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg];
++
++ return 0;
++}
++
++static int tegra210_admaif_pput_mono_to_stereo(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
+- unsigned int *uctl_val = &ucontrol->value.enumerated.item[0];
++ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
++ unsigned int value = ucontrol->value.enumerated.item[0];
+
+- if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
+- *uctl_val = admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg];
+- else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
+- *uctl_val = admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg];
+- else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
+- *uctl_val = admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg];
+- else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
+- *uctl_val = admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg];
++ if (value == admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg])
++ return 0;
++
++ admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
++
++ return 1;
++}
++
++static int tegra210_admaif_cget_mono_to_stereo(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
++ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
++
++ ucontrol->value.enumerated.item[0] =
++ admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg];
+
+ return 0;
+ }
+
+-static int tegra_admaif_put_control(struct snd_kcontrol *kcontrol,
+- struct snd_ctl_elem_value *ucontrol)
++static int tegra210_admaif_cput_mono_to_stereo(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
+ {
+ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
+ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg])
++ return 0;
++
++ admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
++
++ return 1;
++}
++
++static int tegra210_admaif_pget_stereo_to_mono(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
++ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
++
++ ucontrol->value.enumerated.item[0] =
++ admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg];
++
++ return 0;
++}
++
++static int tegra210_admaif_pput_stereo_to_mono(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
++ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
+ unsigned int value = ucontrol->value.enumerated.item[0];
+
+- if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
+- admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
+- else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
+- admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
+- else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
+- admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
+- else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
+- admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
++ if (value == admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg])
++ return 0;
++
++ admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
++
++ return 1;
++}
++
++static int tegra210_admaif_cget_stereo_to_mono(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
++ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
++
++ ucontrol->value.enumerated.item[0] =
++ admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg];
+
+ return 0;
+ }
+
++static int tegra210_admaif_cput_stereo_to_mono(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
++ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg])
++ return 0;
++
++ admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
++
++ return 1;
++}
++
+ static int tegra_admaif_dai_probe(struct snd_soc_dai *dai)
+ {
+ struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
+@@ -559,17 +635,21 @@ static const char * const tegra_admaif_m
+ }
+
+ #define TEGRA_ADMAIF_CIF_CTRL(reg) \
+- NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1,\
+- tegra_admaif_get_control, tegra_admaif_put_control, \
++ NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1, \
++ tegra210_admaif_pget_mono_to_stereo, \
++ tegra210_admaif_pput_mono_to_stereo, \
+ tegra_admaif_mono_conv_text), \
+- NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1,\
+- tegra_admaif_get_control, tegra_admaif_put_control, \
++ NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1, \
++ tegra210_admaif_pget_stereo_to_mono, \
++ tegra210_admaif_pput_stereo_to_mono, \
+ tegra_admaif_stereo_conv_text), \
+- NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1, \
+- tegra_admaif_get_control, tegra_admaif_put_control, \
++ NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1, \
++ tegra210_admaif_cget_mono_to_stereo, \
++ tegra210_admaif_cput_mono_to_stereo, \
+ tegra_admaif_mono_conv_text), \
+- NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1, \
+- tegra_admaif_get_control, tegra_admaif_put_control, \
++ NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1, \
++ tegra210_admaif_cget_stereo_to_mono, \
++ tegra210_admaif_cput_stereo_to_mono, \
+ tegra_admaif_stereo_conv_text)
+
+ static struct snd_kcontrol_new tegra210_admaif_controls[] = {
--- /dev/null
+From a4e37950c9e9b126f9cbee79b8ab94a94646dcf1 Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:37:06 +0530
+Subject: ASoC: tegra: Fix kcontrol put callback in AHUB
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+commit a4e37950c9e9b126f9cbee79b8ab94a94646dcf1 upstream.
+
+The kcontrol put callback is expected to return 1 when there is change
+in HW or when the update is acknowledged by driver. This would ensure
+that change notifications are sent to subscribed applications. Update
+the AHUB driver accordingly.
+
+Fixes: 16e1bcc2caf4 ("ASoC: tegra: Add Tegra210 based AHUB driver")
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Suggested-by: Jaroslav Kysela <perex@perex.cz>
+Suggested-by: Mark Brown <broonie@kernel.org>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-12-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/tegra/tegra210_ahub.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/sound/soc/tegra/tegra210_ahub.c
++++ b/sound/soc/tegra/tegra210_ahub.c
+@@ -62,6 +62,7 @@ static int tegra_ahub_put_value_enum(str
+ unsigned int *item = uctl->value.enumerated.item;
+ unsigned int value = e->values[item[0]];
+ unsigned int i, bit_pos, reg_idx = 0, reg_val = 0;
++ int change = 0;
+
+ if (item[0] >= e->items)
+ return -EINVAL;
+@@ -86,12 +87,14 @@ static int tegra_ahub_put_value_enum(str
+
+ /* Update widget power if state has changed */
+ if (snd_soc_component_test_bits(cmpnt, update[i].reg,
+- update[i].mask, update[i].val))
+- snd_soc_dapm_mux_update_power(dapm, kctl, item[0], e,
+- &update[i]);
++ update[i].mask,
++ update[i].val))
++ change |= snd_soc_dapm_mux_update_power(dapm, kctl,
++ item[0], e,
++ &update[i]);
+ }
+
+- return 0;
++ return change;
+ }
+
+ static struct snd_soc_dai_driver tegra210_ahub_dais[] = {
--- /dev/null
+From a347dfa10262fa0a10e2b1970ea0194e3d4a3251 Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:37:04 +0530
+Subject: ASoC: tegra: Fix kcontrol put callback in DMIC
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+commit a347dfa10262fa0a10e2b1970ea0194e3d4a3251 upstream.
+
+The kcontrol put callback is expected to return 1 when there is change
+in HW or when the update is acknowledged by driver. This would ensure
+that change notifications are sent to subscribed applications. Update
+the DMIC driver accordingly.
+
+Fixes: 8c8ff982e9e2 ("ASoC: tegra: Add Tegra210 based DMIC driver")
+Suggested-by: Jaroslav Kysela <perex@perex.cz>
+Suggested-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-10-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/tegra/tegra210_dmic.c | 183 ++++++++++++++++++++++++++++++++--------
+ 1 file changed, 149 insertions(+), 34 deletions(-)
+
+--- a/sound/soc/tegra/tegra210_dmic.c
++++ b/sound/soc/tegra/tegra210_dmic.c
+@@ -156,50 +156,162 @@ static int tegra210_dmic_hw_params(struc
+ return 0;
+ }
+
+-static int tegra210_dmic_get_control(struct snd_kcontrol *kcontrol,
++static int tegra210_dmic_get_boost_gain(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
++
++ ucontrol->value.integer.value[0] = dmic->boost_gain;
++
++ return 0;
++}
++
++static int tegra210_dmic_put_boost_gain(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
++ int value = ucontrol->value.integer.value[0];
++
++ if (value == dmic->boost_gain)
++ return 0;
++
++ dmic->boost_gain = value;
++
++ return 1;
++}
++
++static int tegra210_dmic_get_ch_select(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
++
++ ucontrol->value.enumerated.item[0] = dmic->ch_select;
++
++ return 0;
++}
++
++static int tegra210_dmic_put_ch_select(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == dmic->ch_select)
++ return 0;
++
++ dmic->ch_select = value;
++
++ return 1;
++}
++
++static int tegra210_dmic_get_mono_to_stereo(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
++
++ ucontrol->value.enumerated.item[0] = dmic->mono_to_stereo;
++
++ return 0;
++}
++
++static int tegra210_dmic_put_mono_to_stereo(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == dmic->mono_to_stereo)
++ return 0;
++
++ dmic->mono_to_stereo = value;
++
++ return 1;
++}
++
++static int tegra210_dmic_get_stereo_to_mono(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
++
++ ucontrol->value.enumerated.item[0] = dmic->stereo_to_mono;
++
++ return 0;
++}
++
++static int tegra210_dmic_put_stereo_to_mono(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == dmic->stereo_to_mono)
++ return 0;
++
++ dmic->stereo_to_mono = value;
++
++ return 1;
++}
++
++static int tegra210_dmic_get_osr_val(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+ {
+ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
+
+- if (strstr(kcontrol->id.name, "Boost Gain Volume"))
+- ucontrol->value.integer.value[0] = dmic->boost_gain;
+- else if (strstr(kcontrol->id.name, "Channel Select"))
+- ucontrol->value.enumerated.item[0] = dmic->ch_select;
+- else if (strstr(kcontrol->id.name, "Mono To Stereo"))
+- ucontrol->value.enumerated.item[0] = dmic->mono_to_stereo;
+- else if (strstr(kcontrol->id.name, "Stereo To Mono"))
+- ucontrol->value.enumerated.item[0] = dmic->stereo_to_mono;
+- else if (strstr(kcontrol->id.name, "OSR Value"))
+- ucontrol->value.enumerated.item[0] = dmic->osr_val;
+- else if (strstr(kcontrol->id.name, "LR Polarity Select"))
+- ucontrol->value.enumerated.item[0] = dmic->lrsel;
++ ucontrol->value.enumerated.item[0] = dmic->osr_val;
+
+ return 0;
+ }
+
+-static int tegra210_dmic_put_control(struct snd_kcontrol *kcontrol,
++static int tegra210_dmic_put_osr_val(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == dmic->osr_val)
++ return 0;
++
++ dmic->osr_val = value;
++
++ return 1;
++}
++
++static int tegra210_dmic_get_pol_sel(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+ {
+ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
+
+- if (strstr(kcontrol->id.name, "Boost Gain Volume"))
+- dmic->boost_gain = ucontrol->value.integer.value[0];
+- else if (strstr(kcontrol->id.name, "Channel Select"))
+- dmic->ch_select = ucontrol->value.enumerated.item[0];
+- else if (strstr(kcontrol->id.name, "Mono To Stereo"))
+- dmic->mono_to_stereo = ucontrol->value.enumerated.item[0];
+- else if (strstr(kcontrol->id.name, "Stereo To Mono"))
+- dmic->stereo_to_mono = ucontrol->value.enumerated.item[0];
+- else if (strstr(kcontrol->id.name, "OSR Value"))
+- dmic->osr_val = ucontrol->value.enumerated.item[0];
+- else if (strstr(kcontrol->id.name, "LR Polarity Select"))
+- dmic->lrsel = ucontrol->value.enumerated.item[0];
++ ucontrol->value.enumerated.item[0] = dmic->lrsel;
+
+ return 0;
+ }
+
++static int tegra210_dmic_put_pol_sel(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == dmic->lrsel)
++ return 0;
++
++ dmic->lrsel = value;
++
++ return 1;
++}
++
+ static const struct snd_soc_dai_ops tegra210_dmic_dai_ops = {
+ .hw_params = tegra210_dmic_hw_params,
+ };
+@@ -286,19 +398,22 @@ static const struct soc_enum tegra210_dm
+
+ static const struct snd_kcontrol_new tegra210_dmic_controls[] = {
+ SOC_SINGLE_EXT("Boost Gain Volume", 0, 0, MAX_BOOST_GAIN, 0,
+- tegra210_dmic_get_control, tegra210_dmic_put_control),
++ tegra210_dmic_get_boost_gain,
++ tegra210_dmic_put_boost_gain),
+ SOC_ENUM_EXT("Channel Select", tegra210_dmic_ch_enum,
+- tegra210_dmic_get_control, tegra210_dmic_put_control),
++ tegra210_dmic_get_ch_select, tegra210_dmic_put_ch_select),
+ SOC_ENUM_EXT("Mono To Stereo",
+- tegra210_dmic_mono_conv_enum, tegra210_dmic_get_control,
+- tegra210_dmic_put_control),
++ tegra210_dmic_mono_conv_enum,
++ tegra210_dmic_get_mono_to_stereo,
++ tegra210_dmic_put_mono_to_stereo),
+ SOC_ENUM_EXT("Stereo To Mono",
+- tegra210_dmic_stereo_conv_enum, tegra210_dmic_get_control,
+- tegra210_dmic_put_control),
++ tegra210_dmic_stereo_conv_enum,
++ tegra210_dmic_get_stereo_to_mono,
++ tegra210_dmic_put_stereo_to_mono),
+ SOC_ENUM_EXT("OSR Value", tegra210_dmic_osr_enum,
+- tegra210_dmic_get_control, tegra210_dmic_put_control),
++ tegra210_dmic_get_osr_val, tegra210_dmic_put_osr_val),
+ SOC_ENUM_EXT("LR Polarity Select", tegra210_dmic_lrsel_enum,
+- tegra210_dmic_get_control, tegra210_dmic_put_control),
++ tegra210_dmic_get_pol_sel, tegra210_dmic_put_pol_sel),
+ };
+
+ static const struct snd_soc_component_driver tegra210_dmic_compnt = {
--- /dev/null
+From d6202a57e79d102271d38c34481fedc9d4c79694 Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:37:05 +0530
+Subject: ASoC: tegra: Fix kcontrol put callback in DSPK
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+commit d6202a57e79d102271d38c34481fedc9d4c79694 upstream.
+
+The kcontrol put callback is expected to return 1 when there is change
+in HW or when the update is acknowledged by driver. This would ensure
+that change notifications are sent to subscribed applications. Update
+the DSPK driver accordingly.
+
+Fixes: 327ef6470266 ("ASoC: tegra: Add Tegra186 based DSPK driver")
+Suggested-by: Jaroslav Kysela <perex@perex.cz>
+Suggested-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-11-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/tegra/tegra186_dspk.c | 178 ++++++++++++++++++++++++++++++++--------
+ 1 file changed, 146 insertions(+), 32 deletions(-)
+
+--- a/sound/soc/tegra/tegra186_dspk.c
++++ b/sound/soc/tegra/tegra186_dspk.c
+@@ -26,50 +26,162 @@ static const struct reg_default tegra186
+ { TEGRA186_DSPK_CODEC_CTRL, 0x03000000 },
+ };
+
+-static int tegra186_dspk_get_control(struct snd_kcontrol *kcontrol,
++static int tegra186_dspk_get_fifo_th(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+ {
+ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
+ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec);
+
+- if (strstr(kcontrol->id.name, "FIFO Threshold"))
+- ucontrol->value.integer.value[0] = dspk->rx_fifo_th;
+- else if (strstr(kcontrol->id.name, "OSR Value"))
+- ucontrol->value.enumerated.item[0] = dspk->osr_val;
+- else if (strstr(kcontrol->id.name, "LR Polarity Select"))
+- ucontrol->value.enumerated.item[0] = dspk->lrsel;
+- else if (strstr(kcontrol->id.name, "Channel Select"))
+- ucontrol->value.enumerated.item[0] = dspk->ch_sel;
+- else if (strstr(kcontrol->id.name, "Mono To Stereo"))
+- ucontrol->value.enumerated.item[0] = dspk->mono_to_stereo;
+- else if (strstr(kcontrol->id.name, "Stereo To Mono"))
+- ucontrol->value.enumerated.item[0] = dspk->stereo_to_mono;
++ ucontrol->value.integer.value[0] = dspk->rx_fifo_th;
+
+ return 0;
+ }
+
+-static int tegra186_dspk_put_control(struct snd_kcontrol *kcontrol,
++static int tegra186_dspk_put_fifo_th(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+ {
+ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
+ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec);
++ int value = ucontrol->value.integer.value[0];
+
+- if (strstr(kcontrol->id.name, "FIFO Threshold"))
+- dspk->rx_fifo_th = ucontrol->value.integer.value[0];
+- else if (strstr(kcontrol->id.name, "OSR Value"))
+- dspk->osr_val = ucontrol->value.enumerated.item[0];
+- else if (strstr(kcontrol->id.name, "LR Polarity Select"))
+- dspk->lrsel = ucontrol->value.enumerated.item[0];
+- else if (strstr(kcontrol->id.name, "Channel Select"))
+- dspk->ch_sel = ucontrol->value.enumerated.item[0];
+- else if (strstr(kcontrol->id.name, "Mono To Stereo"))
+- dspk->mono_to_stereo = ucontrol->value.enumerated.item[0];
+- else if (strstr(kcontrol->id.name, "Stereo To Mono"))
+- dspk->stereo_to_mono = ucontrol->value.enumerated.item[0];
++ if (value == dspk->rx_fifo_th)
++ return 0;
++
++ dspk->rx_fifo_th = value;
++
++ return 1;
++}
++
++static int tegra186_dspk_get_osr_val(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec);
++
++ ucontrol->value.enumerated.item[0] = dspk->osr_val;
++
++ return 0;
++}
++
++static int tegra186_dspk_put_osr_val(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec);
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == dspk->osr_val)
++ return 0;
++
++ dspk->osr_val = value;
++
++ return 1;
++}
++
++static int tegra186_dspk_get_pol_sel(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec);
++
++ ucontrol->value.enumerated.item[0] = dspk->lrsel;
++
++ return 0;
++}
++
++static int tegra186_dspk_put_pol_sel(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec);
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == dspk->lrsel)
++ return 0;
++
++ dspk->lrsel = value;
++
++ return 1;
++}
++
++static int tegra186_dspk_get_ch_sel(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec);
++
++ ucontrol->value.enumerated.item[0] = dspk->ch_sel;
++
++ return 0;
++}
++
++static int tegra186_dspk_put_ch_sel(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec);
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == dspk->ch_sel)
++ return 0;
++
++ dspk->ch_sel = value;
++
++ return 1;
++}
++
++static int tegra186_dspk_get_mono_to_stereo(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec);
++
++ ucontrol->value.enumerated.item[0] = dspk->mono_to_stereo;
++
++ return 0;
++}
++
++static int tegra186_dspk_put_mono_to_stereo(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec);
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == dspk->mono_to_stereo)
++ return 0;
++
++ dspk->mono_to_stereo = value;
++
++ return 1;
++}
++
++static int tegra186_dspk_get_stereo_to_mono(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec);
++
++ ucontrol->value.enumerated.item[0] = dspk->stereo_to_mono;
+
+ return 0;
+ }
+
++static int tegra186_dspk_put_stereo_to_mono(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
++ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec);
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == dspk->stereo_to_mono)
++ return 0;
++
++ dspk->stereo_to_mono = value;
++
++ return 1;
++}
++
+ static int __maybe_unused tegra186_dspk_runtime_suspend(struct device *dev)
+ {
+ struct tegra186_dspk *dspk = dev_get_drvdata(dev);
+@@ -278,17 +390,19 @@ static const struct soc_enum tegra186_ds
+ static const struct snd_kcontrol_new tegrat186_dspk_controls[] = {
+ SOC_SINGLE_EXT("FIFO Threshold", SND_SOC_NOPM, 0,
+ TEGRA186_DSPK_RX_FIFO_DEPTH - 1, 0,
+- tegra186_dspk_get_control, tegra186_dspk_put_control),
++ tegra186_dspk_get_fifo_th, tegra186_dspk_put_fifo_th),
+ SOC_ENUM_EXT("OSR Value", tegra186_dspk_osr_enum,
+- tegra186_dspk_get_control, tegra186_dspk_put_control),
++ tegra186_dspk_get_osr_val, tegra186_dspk_put_osr_val),
+ SOC_ENUM_EXT("LR Polarity Select", tegra186_dspk_lrsel_enum,
+- tegra186_dspk_get_control, tegra186_dspk_put_control),
++ tegra186_dspk_get_pol_sel, tegra186_dspk_put_pol_sel),
+ SOC_ENUM_EXT("Channel Select", tegra186_dspk_ch_sel_enum,
+- tegra186_dspk_get_control, tegra186_dspk_put_control),
++ tegra186_dspk_get_ch_sel, tegra186_dspk_put_ch_sel),
+ SOC_ENUM_EXT("Mono To Stereo", tegra186_dspk_mono_conv_enum,
+- tegra186_dspk_get_control, tegra186_dspk_put_control),
++ tegra186_dspk_get_mono_to_stereo,
++ tegra186_dspk_put_mono_to_stereo),
+ SOC_ENUM_EXT("Stereo To Mono", tegra186_dspk_stereo_conv_enum,
+- tegra186_dspk_get_control, tegra186_dspk_put_control),
++ tegra186_dspk_get_stereo_to_mono,
++ tegra186_dspk_put_stereo_to_mono),
+ };
+
+ static const struct snd_soc_component_driver tegra186_dspk_cmpnt = {
--- /dev/null
+From f21a9df3f7cb0005947679d7b9237c90574e229a Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:37:03 +0530
+Subject: ASoC: tegra: Fix kcontrol put callback in I2S
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+commit f21a9df3f7cb0005947679d7b9237c90574e229a upstream.
+
+The kcontrol put callback is expected to return 1 when there is change
+in HW or when the update is acknowledged by driver. This would ensure
+that change notifications are sent to subscribed applications. Update
+the I2S driver accordingly.
+
+Fixes: c0bfa98349d1 ("ASoC: tegra: Add Tegra210 based I2S driver")
+Suggested-by: Jaroslav Kysela <perex@perex.cz>
+Suggested-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-9-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/tegra/tegra210_i2s.c | 322 ++++++++++++++++++++++++++++++-----------
+ 1 file changed, 236 insertions(+), 86 deletions(-)
+
+--- a/sound/soc/tegra/tegra210_i2s.c
++++ b/sound/soc/tegra/tegra210_i2s.c
+@@ -302,91 +302,235 @@ static int tegra210_i2s_set_tdm_slot(str
+ return 0;
+ }
+
+-static int tegra210_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai,
+- unsigned int ratio)
++static int tegra210_i2s_get_loopback(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
+ {
+- struct tegra210_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
+
+- i2s->bclk_ratio = ratio;
++ ucontrol->value.integer.value[0] = i2s->loopback;
+
+ return 0;
+ }
+
+-static int tegra210_i2s_get_control(struct snd_kcontrol *kcontrol,
+- struct snd_ctl_elem_value *ucontrol)
++static int tegra210_i2s_put_loopback(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
+ {
+ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
+ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++ int value = ucontrol->value.integer.value[0];
+
+- if (strstr(kcontrol->id.name, "Loopback"))
+- ucontrol->value.integer.value[0] = i2s->loopback;
+- else if (strstr(kcontrol->id.name, "FSYNC Width"))
+- ucontrol->value.integer.value[0] = i2s->fsync_width;
+- else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
+- ucontrol->value.enumerated.item[0] =
+- i2s->stereo_to_mono[I2S_TX_PATH];
+- else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
+- ucontrol->value.enumerated.item[0] =
+- i2s->mono_to_stereo[I2S_TX_PATH];
+- else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
+- ucontrol->value.enumerated.item[0] =
+- i2s->stereo_to_mono[I2S_RX_PATH];
+- else if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
+- ucontrol->value.enumerated.item[0] =
+- i2s->mono_to_stereo[I2S_RX_PATH];
+- else if (strstr(kcontrol->id.name, "Playback FIFO Threshold"))
+- ucontrol->value.integer.value[0] = i2s->rx_fifo_th;
+- else if (strstr(kcontrol->id.name, "BCLK Ratio"))
+- ucontrol->value.integer.value[0] = i2s->bclk_ratio;
+-
+- return 0;
+-}
+-
+-static int tegra210_i2s_put_control(struct snd_kcontrol *kcontrol,
+- struct snd_ctl_elem_value *ucontrol)
+-{
+- struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
+- struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
+-
+- if (strstr(kcontrol->id.name, "Loopback")) {
+- i2s->loopback = ucontrol->value.integer.value[0];
+-
+- regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL,
+- I2S_CTRL_LPBK_MASK,
+- i2s->loopback << I2S_CTRL_LPBK_SHIFT);
+-
+- } else if (strstr(kcontrol->id.name, "FSYNC Width")) {
+- /*
+- * Frame sync width is used only for FSYNC modes and not
+- * applicable for LRCK modes. Reset value for this field is "0",
+- * which means the width is one bit clock wide.
+- * The width requirement may depend on the codec and in such
+- * cases mixer control is used to update custom values. A value
+- * of "N" here means, width is "N + 1" bit clock wide.
+- */
+- i2s->fsync_width = ucontrol->value.integer.value[0];
+-
+- regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL,
+- I2S_CTRL_FSYNC_WIDTH_MASK,
+- i2s->fsync_width << I2S_FSYNC_WIDTH_SHIFT);
+-
+- } else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) {
+- i2s->stereo_to_mono[I2S_TX_PATH] =
+- ucontrol->value.enumerated.item[0];
+- } else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) {
+- i2s->mono_to_stereo[I2S_TX_PATH] =
+- ucontrol->value.enumerated.item[0];
+- } else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) {
+- i2s->stereo_to_mono[I2S_RX_PATH] =
+- ucontrol->value.enumerated.item[0];
+- } else if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) {
+- i2s->mono_to_stereo[I2S_RX_PATH] =
+- ucontrol->value.enumerated.item[0];
+- } else if (strstr(kcontrol->id.name, "Playback FIFO Threshold")) {
+- i2s->rx_fifo_th = ucontrol->value.integer.value[0];
+- } else if (strstr(kcontrol->id.name, "BCLK Ratio")) {
+- i2s->bclk_ratio = ucontrol->value.integer.value[0];
+- }
++ if (value == i2s->loopback)
++ return 0;
++
++ i2s->loopback = value;
++
++ regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, I2S_CTRL_LPBK_MASK,
++ i2s->loopback << I2S_CTRL_LPBK_SHIFT);
++
++ return 1;
++}
++
++static int tegra210_i2s_get_fsync_width(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++
++ ucontrol->value.integer.value[0] = i2s->fsync_width;
++
++ return 0;
++}
++
++static int tegra210_i2s_put_fsync_width(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++ int value = ucontrol->value.integer.value[0];
++
++ if (value == i2s->fsync_width)
++ return 0;
++
++ i2s->fsync_width = value;
++
++ /*
++ * Frame sync width is used only for FSYNC modes and not
++ * applicable for LRCK modes. Reset value for this field is "0",
++ * which means the width is one bit clock wide.
++ * The width requirement may depend on the codec and in such
++ * cases mixer control is used to update custom values. A value
++ * of "N" here means, width is "N + 1" bit clock wide.
++ */
++ regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL,
++ I2S_CTRL_FSYNC_WIDTH_MASK,
++ i2s->fsync_width << I2S_FSYNC_WIDTH_SHIFT);
++
++ return 1;
++}
++
++static int tegra210_i2s_cget_stereo_to_mono(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++
++ ucontrol->value.enumerated.item[0] = i2s->stereo_to_mono[I2S_TX_PATH];
++
++ return 0;
++}
++
++static int tegra210_i2s_cput_stereo_to_mono(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == i2s->stereo_to_mono[I2S_TX_PATH])
++ return 0;
++
++ i2s->stereo_to_mono[I2S_TX_PATH] = value;
++
++ return 1;
++}
++
++static int tegra210_i2s_cget_mono_to_stereo(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++
++ ucontrol->value.enumerated.item[0] = i2s->mono_to_stereo[I2S_TX_PATH];
++
++ return 0;
++}
++
++static int tegra210_i2s_cput_mono_to_stereo(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == i2s->mono_to_stereo[I2S_TX_PATH])
++ return 0;
++
++ i2s->mono_to_stereo[I2S_TX_PATH] = value;
++
++ return 1;
++}
++
++static int tegra210_i2s_pget_stereo_to_mono(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++
++ ucontrol->value.enumerated.item[0] = i2s->stereo_to_mono[I2S_RX_PATH];
++
++ return 0;
++}
++
++static int tegra210_i2s_pput_stereo_to_mono(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == i2s->stereo_to_mono[I2S_RX_PATH])
++ return 0;
++
++ i2s->stereo_to_mono[I2S_RX_PATH] = value;
++
++ return 1;
++}
++
++static int tegra210_i2s_pget_mono_to_stereo(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++
++ ucontrol->value.enumerated.item[0] = i2s->mono_to_stereo[I2S_RX_PATH];
++
++ return 0;
++}
++
++static int tegra210_i2s_pput_mono_to_stereo(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++ unsigned int value = ucontrol->value.enumerated.item[0];
++
++ if (value == i2s->mono_to_stereo[I2S_RX_PATH])
++ return 0;
++
++ i2s->mono_to_stereo[I2S_RX_PATH] = value;
++
++ return 1;
++}
++
++static int tegra210_i2s_pget_fifo_th(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++
++ ucontrol->value.integer.value[0] = i2s->rx_fifo_th;
++
++ return 0;
++}
++
++static int tegra210_i2s_pput_fifo_th(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++ int value = ucontrol->value.integer.value[0];
++
++ if (value == i2s->rx_fifo_th)
++ return 0;
++
++ i2s->rx_fifo_th = value;
++
++ return 1;
++}
++
++static int tegra210_i2s_get_bclk_ratio(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++
++ ucontrol->value.integer.value[0] = i2s->bclk_ratio;
++
++ return 0;
++}
++
++static int tegra210_i2s_put_bclk_ratio(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
++ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
++ int value = ucontrol->value.integer.value[0];
++
++ if (value == i2s->bclk_ratio)
++ return 0;
++
++ i2s->bclk_ratio = value;
++
++ return 1;
++}
++
++static int tegra210_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai,
++ unsigned int ratio)
++{
++ struct tegra210_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++
++ i2s->bclk_ratio = ratio;
+
+ return 0;
+ }
+@@ -604,22 +748,28 @@ static const struct soc_enum tegra210_i2
+ tegra210_i2s_stereo_conv_text);
+
+ static const struct snd_kcontrol_new tegra210_i2s_controls[] = {
+- SOC_SINGLE_EXT("Loopback", 0, 0, 1, 0, tegra210_i2s_get_control,
+- tegra210_i2s_put_control),
+- SOC_SINGLE_EXT("FSYNC Width", 0, 0, 255, 0, tegra210_i2s_get_control,
+- tegra210_i2s_put_control),
++ SOC_SINGLE_EXT("Loopback", 0, 0, 1, 0, tegra210_i2s_get_loopback,
++ tegra210_i2s_put_loopback),
++ SOC_SINGLE_EXT("FSYNC Width", 0, 0, 255, 0,
++ tegra210_i2s_get_fsync_width,
++ tegra210_i2s_put_fsync_width),
+ SOC_ENUM_EXT("Capture Stereo To Mono", tegra210_i2s_stereo_conv_enum,
+- tegra210_i2s_get_control, tegra210_i2s_put_control),
++ tegra210_i2s_cget_stereo_to_mono,
++ tegra210_i2s_cput_stereo_to_mono),
+ SOC_ENUM_EXT("Capture Mono To Stereo", tegra210_i2s_mono_conv_enum,
+- tegra210_i2s_get_control, tegra210_i2s_put_control),
++ tegra210_i2s_cget_mono_to_stereo,
++ tegra210_i2s_cput_mono_to_stereo),
+ SOC_ENUM_EXT("Playback Stereo To Mono", tegra210_i2s_stereo_conv_enum,
+- tegra210_i2s_get_control, tegra210_i2s_put_control),
++ tegra210_i2s_pget_mono_to_stereo,
++ tegra210_i2s_pput_mono_to_stereo),
+ SOC_ENUM_EXT("Playback Mono To Stereo", tegra210_i2s_mono_conv_enum,
+- tegra210_i2s_get_control, tegra210_i2s_put_control),
++ tegra210_i2s_pget_stereo_to_mono,
++ tegra210_i2s_pput_stereo_to_mono),
+ SOC_SINGLE_EXT("Playback FIFO Threshold", 0, 0, I2S_RX_FIFO_DEPTH - 1,
+- 0, tegra210_i2s_get_control, tegra210_i2s_put_control),
+- SOC_SINGLE_EXT("BCLK Ratio", 0, 0, INT_MAX, 0, tegra210_i2s_get_control,
+- tegra210_i2s_put_control),
++ 0, tegra210_i2s_pget_fifo_th, tegra210_i2s_pput_fifo_th),
++ SOC_SINGLE_EXT("BCLK Ratio", 0, 0, INT_MAX, 0,
++ tegra210_i2s_get_bclk_ratio,
++ tegra210_i2s_put_bclk_ratio),
+ };
+
+ static const struct snd_soc_dapm_widget tegra210_i2s_widgets[] = {
--- /dev/null
+From 884c6cb3b7030f75c46e55b9e625d2372708c306 Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:36:56 +0530
+Subject: ASoC: tegra: Fix wrong value type in ADMAIF
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+commit 884c6cb3b7030f75c46e55b9e625d2372708c306 upstream.
+
+The enum controls are expected to use enumerated value type.
+Update relevant references in control get/put callbacks.
+
+Fixes: f74028e159bb ("ASoC: tegra: Add Tegra210 based ADMAIF driver")
+Suggested-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-2-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/tegra/tegra210_admaif.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/tegra/tegra210_admaif.c
++++ b/sound/soc/tegra/tegra210_admaif.c
+@@ -430,7 +430,7 @@ static int tegra_admaif_get_control(stru
+ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
+ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
+- long *uctl_val = &ucontrol->value.integer.value[0];
++ unsigned int *uctl_val = &ucontrol->value.enumerated.item[0];
+
+ if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
+ *uctl_val = admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg];
+@@ -450,7 +450,7 @@ static int tegra_admaif_put_control(stru
+ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+ struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
+ struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
+- int value = ucontrol->value.integer.value[0];
++ unsigned int value = ucontrol->value.enumerated.item[0];
+
+ if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
+ admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
--- /dev/null
+From 559d234569a998a4004de1bd1f12da5487fb826e Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:36:58 +0530
+Subject: ASoC: tegra: Fix wrong value type in DMIC
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+commit 559d234569a998a4004de1bd1f12da5487fb826e upstream.
+
+The enum controls are expected to use enumerated value type.
+Update relevant references in control get/put callbacks.
+
+Fixes: 8c8ff982e9e2 ("ASoC: tegra: Add Tegra210 based DMIC driver")
+Suggested-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-4-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/tegra/tegra210_dmic.c | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+--- a/sound/soc/tegra/tegra210_dmic.c
++++ b/sound/soc/tegra/tegra210_dmic.c
+@@ -165,15 +165,15 @@ static int tegra210_dmic_get_control(str
+ if (strstr(kcontrol->id.name, "Boost Gain Volume"))
+ ucontrol->value.integer.value[0] = dmic->boost_gain;
+ else if (strstr(kcontrol->id.name, "Channel Select"))
+- ucontrol->value.integer.value[0] = dmic->ch_select;
++ ucontrol->value.enumerated.item[0] = dmic->ch_select;
+ else if (strstr(kcontrol->id.name, "Mono To Stereo"))
+- ucontrol->value.integer.value[0] = dmic->mono_to_stereo;
++ ucontrol->value.enumerated.item[0] = dmic->mono_to_stereo;
+ else if (strstr(kcontrol->id.name, "Stereo To Mono"))
+- ucontrol->value.integer.value[0] = dmic->stereo_to_mono;
++ ucontrol->value.enumerated.item[0] = dmic->stereo_to_mono;
+ else if (strstr(kcontrol->id.name, "OSR Value"))
+- ucontrol->value.integer.value[0] = dmic->osr_val;
++ ucontrol->value.enumerated.item[0] = dmic->osr_val;
+ else if (strstr(kcontrol->id.name, "LR Polarity Select"))
+- ucontrol->value.integer.value[0] = dmic->lrsel;
++ ucontrol->value.enumerated.item[0] = dmic->lrsel;
+
+ return 0;
+ }
+@@ -183,20 +183,19 @@ static int tegra210_dmic_put_control(str
+ {
+ struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+ struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
+- int value = ucontrol->value.integer.value[0];
+
+ if (strstr(kcontrol->id.name, "Boost Gain Volume"))
+- dmic->boost_gain = value;
++ dmic->boost_gain = ucontrol->value.integer.value[0];
+ else if (strstr(kcontrol->id.name, "Channel Select"))
+- dmic->ch_select = ucontrol->value.integer.value[0];
++ dmic->ch_select = ucontrol->value.enumerated.item[0];
+ else if (strstr(kcontrol->id.name, "Mono To Stereo"))
+- dmic->mono_to_stereo = value;
++ dmic->mono_to_stereo = ucontrol->value.enumerated.item[0];
+ else if (strstr(kcontrol->id.name, "Stereo To Mono"))
+- dmic->stereo_to_mono = value;
++ dmic->stereo_to_mono = ucontrol->value.enumerated.item[0];
+ else if (strstr(kcontrol->id.name, "OSR Value"))
+- dmic->osr_val = value;
++ dmic->osr_val = ucontrol->value.enumerated.item[0];
+ else if (strstr(kcontrol->id.name, "LR Polarity Select"))
+- dmic->lrsel = value;
++ dmic->lrsel = ucontrol->value.enumerated.item[0];
+
+ return 0;
+ }
--- /dev/null
+From 3aa0d5c8bb3f5ef622ec2764823f551a1f630711 Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:36:59 +0530
+Subject: ASoC: tegra: Fix wrong value type in DSPK
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+commit 3aa0d5c8bb3f5ef622ec2764823f551a1f630711 upstream.
+
+The enum controls are expected to use enumerated value type.
+Update relevant references in control get/put callbacks.
+
+Fixes: 327ef6470266 ("ASoC: tegra: Add Tegra186 based DSPK driver")
+Suggested-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-5-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/tegra/tegra186_dspk.c | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+--- a/sound/soc/tegra/tegra186_dspk.c
++++ b/sound/soc/tegra/tegra186_dspk.c
+@@ -35,15 +35,15 @@ static int tegra186_dspk_get_control(str
+ if (strstr(kcontrol->id.name, "FIFO Threshold"))
+ ucontrol->value.integer.value[0] = dspk->rx_fifo_th;
+ else if (strstr(kcontrol->id.name, "OSR Value"))
+- ucontrol->value.integer.value[0] = dspk->osr_val;
++ ucontrol->value.enumerated.item[0] = dspk->osr_val;
+ else if (strstr(kcontrol->id.name, "LR Polarity Select"))
+- ucontrol->value.integer.value[0] = dspk->lrsel;
++ ucontrol->value.enumerated.item[0] = dspk->lrsel;
+ else if (strstr(kcontrol->id.name, "Channel Select"))
+- ucontrol->value.integer.value[0] = dspk->ch_sel;
++ ucontrol->value.enumerated.item[0] = dspk->ch_sel;
+ else if (strstr(kcontrol->id.name, "Mono To Stereo"))
+- ucontrol->value.integer.value[0] = dspk->mono_to_stereo;
++ ucontrol->value.enumerated.item[0] = dspk->mono_to_stereo;
+ else if (strstr(kcontrol->id.name, "Stereo To Mono"))
+- ucontrol->value.integer.value[0] = dspk->stereo_to_mono;
++ ucontrol->value.enumerated.item[0] = dspk->stereo_to_mono;
+
+ return 0;
+ }
+@@ -53,20 +53,19 @@ static int tegra186_dspk_put_control(str
+ {
+ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
+ struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec);
+- int val = ucontrol->value.integer.value[0];
+
+ if (strstr(kcontrol->id.name, "FIFO Threshold"))
+- dspk->rx_fifo_th = val;
++ dspk->rx_fifo_th = ucontrol->value.integer.value[0];
+ else if (strstr(kcontrol->id.name, "OSR Value"))
+- dspk->osr_val = val;
++ dspk->osr_val = ucontrol->value.enumerated.item[0];
+ else if (strstr(kcontrol->id.name, "LR Polarity Select"))
+- dspk->lrsel = val;
++ dspk->lrsel = ucontrol->value.enumerated.item[0];
+ else if (strstr(kcontrol->id.name, "Channel Select"))
+- dspk->ch_sel = val;
++ dspk->ch_sel = ucontrol->value.enumerated.item[0];
+ else if (strstr(kcontrol->id.name, "Mono To Stereo"))
+- dspk->mono_to_stereo = val;
++ dspk->mono_to_stereo = ucontrol->value.enumerated.item[0];
+ else if (strstr(kcontrol->id.name, "Stereo To Mono"))
+- dspk->stereo_to_mono = val;
++ dspk->stereo_to_mono = ucontrol->value.enumerated.item[0];
+
+ return 0;
+ }
--- /dev/null
+From 8a2c2fa0c5331445c801e9241f2bb4e0e2a895a8 Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:36:57 +0530
+Subject: ASoC: tegra: Fix wrong value type in I2S
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+commit 8a2c2fa0c5331445c801e9241f2bb4e0e2a895a8 upstream.
+
+The enum controls are expected to use enumerated value type.
+Update relevant references in control get/put callbacks.
+
+Fixes: c0bfa98349d1 ("ASoC: tegra: Add Tegra210 based I2S driver")
+Suggested-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-3-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/tegra/tegra210_i2s.c | 42 +++++++++++++++++++++++------------------
+ 1 file changed, 24 insertions(+), 18 deletions(-)
+
+--- a/sound/soc/tegra/tegra210_i2s.c
++++ b/sound/soc/tegra/tegra210_i2s.c
+@@ -317,24 +317,27 @@ static int tegra210_i2s_get_control(stru
+ {
+ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
+ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
+- long *uctl_val = &ucontrol->value.integer.value[0];
+
+ if (strstr(kcontrol->id.name, "Loopback"))
+- *uctl_val = i2s->loopback;
++ ucontrol->value.integer.value[0] = i2s->loopback;
+ else if (strstr(kcontrol->id.name, "FSYNC Width"))
+- *uctl_val = i2s->fsync_width;
++ ucontrol->value.integer.value[0] = i2s->fsync_width;
+ else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
+- *uctl_val = i2s->stereo_to_mono[I2S_TX_PATH];
++ ucontrol->value.enumerated.item[0] =
++ i2s->stereo_to_mono[I2S_TX_PATH];
+ else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
+- *uctl_val = i2s->mono_to_stereo[I2S_TX_PATH];
++ ucontrol->value.enumerated.item[0] =
++ i2s->mono_to_stereo[I2S_TX_PATH];
+ else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
+- *uctl_val = i2s->stereo_to_mono[I2S_RX_PATH];
++ ucontrol->value.enumerated.item[0] =
++ i2s->stereo_to_mono[I2S_RX_PATH];
+ else if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
+- *uctl_val = i2s->mono_to_stereo[I2S_RX_PATH];
++ ucontrol->value.enumerated.item[0] =
++ i2s->mono_to_stereo[I2S_RX_PATH];
+ else if (strstr(kcontrol->id.name, "Playback FIFO Threshold"))
+- *uctl_val = i2s->rx_fifo_th;
++ ucontrol->value.integer.value[0] = i2s->rx_fifo_th;
+ else if (strstr(kcontrol->id.name, "BCLK Ratio"))
+- *uctl_val = i2s->bclk_ratio;
++ ucontrol->value.integer.value[0] = i2s->bclk_ratio;
+
+ return 0;
+ }
+@@ -344,10 +347,9 @@ static int tegra210_i2s_put_control(stru
+ {
+ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
+ struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
+- int value = ucontrol->value.integer.value[0];
+
+ if (strstr(kcontrol->id.name, "Loopback")) {
+- i2s->loopback = value;
++ i2s->loopback = ucontrol->value.integer.value[0];
+
+ regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL,
+ I2S_CTRL_LPBK_MASK,
+@@ -362,24 +364,28 @@ static int tegra210_i2s_put_control(stru
+ * cases mixer control is used to update custom values. A value
+ * of "N" here means, width is "N + 1" bit clock wide.
+ */
+- i2s->fsync_width = value;
++ i2s->fsync_width = ucontrol->value.integer.value[0];
+
+ regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL,
+ I2S_CTRL_FSYNC_WIDTH_MASK,
+ i2s->fsync_width << I2S_FSYNC_WIDTH_SHIFT);
+
+ } else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) {
+- i2s->stereo_to_mono[I2S_TX_PATH] = value;
++ i2s->stereo_to_mono[I2S_TX_PATH] =
++ ucontrol->value.enumerated.item[0];
+ } else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) {
+- i2s->mono_to_stereo[I2S_TX_PATH] = value;
++ i2s->mono_to_stereo[I2S_TX_PATH] =
++ ucontrol->value.enumerated.item[0];
+ } else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) {
+- i2s->stereo_to_mono[I2S_RX_PATH] = value;
++ i2s->stereo_to_mono[I2S_RX_PATH] =
++ ucontrol->value.enumerated.item[0];
+ } else if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) {
+- i2s->mono_to_stereo[I2S_RX_PATH] = value;
++ i2s->mono_to_stereo[I2S_RX_PATH] =
++ ucontrol->value.enumerated.item[0];
+ } else if (strstr(kcontrol->id.name, "Playback FIFO Threshold")) {
+- i2s->rx_fifo_th = value;
++ i2s->rx_fifo_th = ucontrol->value.integer.value[0];
+ } else if (strstr(kcontrol->id.name, "BCLK Ratio")) {
+- i2s->bclk_ratio = value;
++ i2s->bclk_ratio = ucontrol->value.integer.value[0];
+ }
+
+ return 0;
--- /dev/null
+From f4a8adbfe4841491b60c14fe610571e1422359f9 Mon Sep 17 00:00:00 2001
+From: Dongliang Mu <mudongliangabcd@gmail.com>
+Date: Tue, 30 Nov 2021 12:05:54 +0800
+Subject: dpaa2-eth: destroy workqueue at the end of remove function
+
+From: Dongliang Mu <mudongliangabcd@gmail.com>
+
+commit f4a8adbfe4841491b60c14fe610571e1422359f9 upstream.
+
+The commit c55211892f46 ("dpaa2-eth: support PTP Sync packet one-step
+timestamping") forgets to destroy workqueue at the end of remove
+function.
+
+Fix this by adding destroy_workqueue before fsl_mc_portal_free and
+free_netdev.
+
+Fixes: c55211892f46 ("dpaa2-eth: support PTP Sync packet one-step timestamping")
+Signed-off-by: Dongliang Mu <mudongliangabcd@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+@@ -4538,6 +4538,8 @@ static int dpaa2_eth_remove(struct fsl_m
+
+ fsl_mc_portal_free(priv->mc_io);
+
++ destroy_workqueue(priv->dpaa2_ptp_wq);
++
+ dev_dbg(net_dev->dev.parent, "Removed interface %s\n", net_dev->name);
+
+ free_netdev(net_dev);
--- /dev/null
+From b4d25abf9720b69a03465b09d0d62d1998ed6708 Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Wed, 3 Nov 2021 15:31:08 -0700
+Subject: drm/msm/a6xx: Allocate enough space for GMU registers
+
+From: Douglas Anderson <dianders@chromium.org>
+
+commit b4d25abf9720b69a03465b09d0d62d1998ed6708 upstream.
+
+In commit 142639a52a01 ("drm/msm/a6xx: fix crashstate capture for
+A650") we changed a6xx_get_gmu_registers() to read 3 sets of
+registers. Unfortunately, we didn't change the memory allocation for
+the array. That leads to a KASAN warning (this was on the chromeos-5.4
+kernel, which has the problematic commit backported to it):
+
+ BUG: KASAN: slab-out-of-bounds in _a6xx_get_gmu_registers+0x144/0x430
+ Write of size 8 at addr ffffff80c89432b0 by task A618-worker/209
+ CPU: 5 PID: 209 Comm: A618-worker Tainted: G W 5.4.156-lockdep #22
+ Hardware name: Google Lazor Limozeen without Touchscreen (rev5 - rev8) (DT)
+ Call trace:
+ dump_backtrace+0x0/0x248
+ show_stack+0x20/0x2c
+ dump_stack+0x128/0x1ec
+ print_address_description+0x88/0x4a0
+ __kasan_report+0xfc/0x120
+ kasan_report+0x10/0x18
+ __asan_report_store8_noabort+0x1c/0x24
+ _a6xx_get_gmu_registers+0x144/0x430
+ a6xx_gpu_state_get+0x330/0x25d4
+ msm_gpu_crashstate_capture+0xa0/0x84c
+ recover_worker+0x328/0x838
+ kthread_worker_fn+0x32c/0x574
+ kthread+0x2dc/0x39c
+ ret_from_fork+0x10/0x18
+
+ Allocated by task 209:
+ __kasan_kmalloc+0xfc/0x1c4
+ kasan_kmalloc+0xc/0x14
+ kmem_cache_alloc_trace+0x1f0/0x2a0
+ a6xx_gpu_state_get+0x164/0x25d4
+ msm_gpu_crashstate_capture+0xa0/0x84c
+ recover_worker+0x328/0x838
+ kthread_worker_fn+0x32c/0x574
+ kthread+0x2dc/0x39c
+ ret_from_fork+0x10/0x18
+
+Fixes: 142639a52a01 ("drm/msm/a6xx: fix crashstate capture for A650")
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://lore.kernel.org/r/20211103153049.1.Idfa574ccb529d17b69db3a1852e49b580132035c@changeid
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
+@@ -777,12 +777,12 @@ static void a6xx_get_gmu_registers(struc
+ struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+
+ a6xx_state->gmu_registers = state_kcalloc(a6xx_state,
+- 2, sizeof(*a6xx_state->gmu_registers));
++ 3, sizeof(*a6xx_state->gmu_registers));
+
+ if (!a6xx_state->gmu_registers)
+ return;
+
+- a6xx_state->nr_gmu_registers = 2;
++ a6xx_state->nr_gmu_registers = 3;
+
+ /* Get the CX GMU registers from AHB */
+ _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[0],
--- /dev/null
+From e4840d537c2c6b1189d4de16ee0f4820e069dcea Mon Sep 17 00:00:00 2001
+From: Rob Clark <robdclark@chromium.org>
+Date: Mon, 8 Nov 2021 10:01:22 -0800
+Subject: drm/msm: Do hw_init() before capturing GPU state
+
+From: Rob Clark <robdclark@chromium.org>
+
+commit e4840d537c2c6b1189d4de16ee0f4820e069dcea upstream.
+
+In particular, we need to ensure all the necessary blocks are switched
+to 64b mode (a5xx+) otherwise the high bits of the address of the BO to
+snapshot state into will be ignored, resulting in:
+
+ *** gpu fault: ttbr0=0000000000000000 iova=0000000000012000 dir=READ type=TRANSLATION source=CP (0,0,0,0)
+ platform 506a000.gmu: [drm:a6xx_gmu_set_oob] *ERROR* Timeout waiting for GMU OOB set BOOT_SLUMBER: 0x0
+
+Fixes: 4f776f4511c7 ("drm/msm/gpu: Convert the GPU show function to use the GPU state")
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Link: https://lore.kernel.org/r/20211108180122.487859-1-robdclark@gmail.com
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/msm/msm_debugfs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/msm/msm_debugfs.c
++++ b/drivers/gpu/drm/msm/msm_debugfs.c
+@@ -77,6 +77,7 @@ static int msm_gpu_open(struct inode *in
+ goto free_priv;
+
+ pm_runtime_get_sync(&gpu->pdev->dev);
++ msm_gpu_hw_init(gpu);
+ show_priv->state = gpu->funcs->gpu_state_get(gpu);
+ pm_runtime_put_sync(&gpu->pdev->dev);
+
--- /dev/null
+From 049cfff8d53a30cae3349ff71a4c01b7d9981bc2 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 17 Nov 2021 10:45:24 +0100
+Subject: drm/vc4: kms: Add missing drm_crtc_commit_put
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+commit 049cfff8d53a30cae3349ff71a4c01b7d9981bc2 upstream.
+
+Commit 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a
+commit") introduced a global state for the HVS, with each FIFO storing
+the current CRTC commit so that we can properly synchronize commits.
+
+However, the refcounting was off and we thus ended up leaking the
+drm_crtc_commit structure every commit. Add a drm_crtc_commit_put to
+prevent the leakage.
+
+Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Tested-by: Jian-Hong Pan <jhp@endlessos.org>
+Link: https://lore.kernel.org/r/20211117094527.146275-4-maxime@cerno.tech
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/vc4/vc4_kms.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -361,6 +361,7 @@ static void vc4_atomic_commit_tail(struc
+ struct vc4_crtc_state *vc4_crtc_state =
+ to_vc4_crtc_state(old_crtc_state);
+ unsigned int channel = vc4_crtc_state->assigned_channel;
++ struct drm_crtc_commit *commit;
+ int ret;
+
+ if (channel == VC4_HVS_CHANNEL_DISABLED)
+@@ -369,9 +370,15 @@ static void vc4_atomic_commit_tail(struc
+ if (!old_hvs_state->fifo_state[channel].in_use)
+ continue;
+
+- ret = drm_crtc_commit_wait(old_hvs_state->fifo_state[channel].pending_commit);
++ commit = old_hvs_state->fifo_state[channel].pending_commit;
++ if (!commit)
++ continue;
++
++ ret = drm_crtc_commit_wait(commit);
+ if (ret)
+ drm_err(dev, "Timed out waiting for commit\n");
++
++ drm_crtc_commit_put(commit);
+ }
+
+ if (vc4->hvs->hvs5)
--- /dev/null
+From d134c5ff71c7f2320fc7997f2fbbdedf0c76889a Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 17 Nov 2021 10:45:25 +0100
+Subject: drm/vc4: kms: Clear the HVS FIFO commit pointer once done
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+commit d134c5ff71c7f2320fc7997f2fbbdedf0c76889a upstream.
+
+Commit 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a
+commit") introduced a wait on the previous commit done on a given HVS
+FIFO.
+
+However, we never cleared that pointer once done. Since
+drm_crtc_commit_put can free the drm_crtc_commit structure directly if
+we were the last user, this means that it can lead to a use-after free
+if we were to duplicate the state, and that stale pointer would even be
+copied to the new state.
+
+Set the pointer to NULL once we're done with the wait so that we don't
+carry over a pointer to a free'd structure.
+
+Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Tested-by: Jian-Hong Pan <jhp@endlessos.org>
+Link: https://lore.kernel.org/r/20211117094527.146275-5-maxime@cerno.tech
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/vc4/vc4_kms.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -379,6 +379,7 @@ static void vc4_atomic_commit_tail(struc
+ drm_err(dev, "Timed out waiting for commit\n");
+
+ drm_crtc_commit_put(commit);
++ old_hvs_state->fifo_state[channel].pending_commit = NULL;
+ }
+
+ if (vc4->hvs->hvs5)
--- /dev/null
+From d354699e2292c60f25496d3c31ce4e7b1563b899 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 17 Nov 2021 10:45:26 +0100
+Subject: drm/vc4: kms: Don't duplicate pending commit
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+commit d354699e2292c60f25496d3c31ce4e7b1563b899 upstream.
+
+Our HVS global state, when duplicated, will also copy the pointer to the
+drm_crtc_commit (and increase the reference count) for each FIFO if the
+pointer is not NULL.
+
+However, our atomic_setup function will overwrite that pointer without
+putting the reference back leading to a memory leak.
+
+Since the commit is only relevant during the atomic commit process, it
+doesn't make sense to duplicate the reference to the commit anyway.
+Let's remove it.
+
+Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Tested-by: Jian-Hong Pan <jhp@endlessos.org>
+Link: https://lore.kernel.org/r/20211117094527.146275-6-maxime@cerno.tech
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/vc4/vc4_kms.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -676,12 +676,6 @@ vc4_hvs_channels_duplicate_state(struct
+
+ for (i = 0; i < HVS_NUM_CHANNELS; i++) {
+ state->fifo_state[i].in_use = old_state->fifo_state[i].in_use;
+-
+- if (!old_state->fifo_state[i].pending_commit)
+- continue;
+-
+- state->fifo_state[i].pending_commit =
+- drm_crtc_commit_get(old_state->fifo_state[i].pending_commit);
+ }
+
+ return &state->base;
--- /dev/null
+From 6052a3110be208e547a4a8aeb184446199a16e8a Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 17 Nov 2021 10:45:27 +0100
+Subject: drm/vc4: kms: Fix previous HVS commit wait
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+commit 6052a3110be208e547a4a8aeb184446199a16e8a upstream.
+
+Our current code is supposed to serialise the commits by waiting for all
+the drm_crtc_commits associated to the previous HVS state.
+
+However, assuming we have two CRTCs running and being configured and we
+configure each one alternately, we end up in a situation where we're
+not waiting at all.
+
+Indeed, starting with a state (state 0) where both CRTCs are running,
+and doing a commit (state 1) on the first CRTC (CRTC 0), we'll associate
+its commit to its assigned FIFO in vc4_hvs_state.
+
+If we get a new commit (state 2), this time affecting the second CRTC
+(CRTC 1), the DRM core will allow both commits to execute in parallel
+(assuming they don't have any share resources).
+
+Our code in vc4_atomic_commit_tail is supposed to make sure we only get
+one commit at a time and serialised by order of submission. It does so
+by using for_each_old_crtc_in_state, making sure that the CRTC has a
+FIFO assigned, is used, and has a commit pending. If it does, then we'll
+wait for the commit before going forward.
+
+During the transition from state 0 to state 1, as our old CRTC state we
+get the CRTC 0 state 0, its commit, we wait for it, everything works fine.
+
+During the transition from state 1 to state 2 though, the use of
+for_each_old_crtc_in_state is wrong. Indeed, while the code assumes it's
+returning the state of the CRTC in the old state (so CRTC 0 state 1), it
+actually returns the old state of the CRTC affected by the current
+commit, so CRTC 0 state 0 since it wasn't part of state 1.
+
+Due to this, if we alternate between the configuration of CRTC 0 and
+CRTC 1, we never actually wait for anything since we should be waiting
+on the other every time, but it never is affected by the previous
+commit.
+
+Change the logic to, at every commit, look at every FIFO in the previous
+HVS state, and if it's in use and has a commit associated to it, wait
+for that commit.
+
+Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Tested-by: Jian-Hong Pan <jhp@endlessos.org>
+Link: https://lore.kernel.org/r/20211117094527.146275-7-maxime@cerno.tech
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/vc4/vc4_kms.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -337,10 +337,10 @@ static void vc4_atomic_commit_tail(struc
+ struct drm_device *dev = state->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct vc4_hvs *hvs = vc4->hvs;
+- struct drm_crtc_state *old_crtc_state;
+ struct drm_crtc_state *new_crtc_state;
+ struct drm_crtc *crtc;
+ struct vc4_hvs_state *old_hvs_state;
++ unsigned int channel;
+ int i;
+
+ for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
+@@ -357,16 +357,10 @@ static void vc4_atomic_commit_tail(struc
+ if (IS_ERR(old_hvs_state))
+ return;
+
+- for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
+- struct vc4_crtc_state *vc4_crtc_state =
+- to_vc4_crtc_state(old_crtc_state);
+- unsigned int channel = vc4_crtc_state->assigned_channel;
++ for (channel = 0; channel < HVS_NUM_CHANNELS; channel++) {
+ struct drm_crtc_commit *commit;
+ int ret;
+
+- if (channel == VC4_HVS_CHANNEL_DISABLED)
+- continue;
+-
+ if (!old_hvs_state->fifo_state[channel].in_use)
+ continue;
+
--- /dev/null
+From f927767978d201d4ac023fcd797adbb963a6565d Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 17 Nov 2021 10:45:23 +0100
+Subject: drm/vc4: kms: Fix return code check
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+commit f927767978d201d4ac023fcd797adbb963a6565d upstream.
+
+The HVS global state functions return an error pointer, but in most
+cases we check if it's NULL, possibly resulting in an invalid pointer
+dereference.
+
+Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Tested-by: Jian-Hong Pan <jhp@endlessos.org>
+Link: https://lore.kernel.org/r/20211117094527.146275-3-maxime@cerno.tech
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/vc4/vc4_kms.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -354,7 +354,7 @@ static void vc4_atomic_commit_tail(struc
+ }
+
+ old_hvs_state = vc4_hvs_get_old_global_state(state);
+- if (!old_hvs_state)
++ if (IS_ERR(old_hvs_state))
+ return;
+
+ for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
+@@ -410,8 +410,8 @@ static int vc4_atomic_commit_setup(struc
+ unsigned int i;
+
+ hvs_state = vc4_hvs_get_new_global_state(state);
+- if (!hvs_state)
+- return -EINVAL;
++ if (WARN_ON(IS_ERR(hvs_state)))
++ return PTR_ERR(hvs_state);
+
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
+ struct vc4_crtc_state *vc4_crtc_state =
+@@ -762,8 +762,8 @@ static int vc4_pv_muxing_atomic_check(st
+ unsigned int i;
+
+ hvs_new_state = vc4_hvs_get_global_state(state);
+- if (!hvs_new_state)
+- return -EINVAL;
++ if (IS_ERR(hvs_new_state))
++ return PTR_ERR(hvs_new_state);
+
+ for (i = 0; i < ARRAY_SIZE(hvs_new_state->fifo_state); i++)
+ if (!hvs_new_state->fifo_state[i].in_use)
--- /dev/null
+From 0c980a006d3fbee86c4d0698f66d6f5381831787 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 17 Nov 2021 10:45:22 +0100
+Subject: drm/vc4: kms: Wait for the commit before increasing our clock rate
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+commit 0c980a006d3fbee86c4d0698f66d6f5381831787 upstream.
+
+Several DRM/KMS atomic commits can run in parallel if they affect
+different CRTC. These commits share the global HVS state, so we have
+some code to make sure we run commits in sequence. This synchronization
+code is one of the first thing that runs in vc4_atomic_commit_tail().
+
+Another constraints we have is that we need to make sure the HVS clock
+gets a boost during the commit. That code relies on clk_set_min_rate and
+will remove the old minimum and set a new one. We also need another,
+temporary, minimum for the duration of the commit.
+
+The algorithm is thus to set a temporary minimum, drop the previous
+one, do the commit, and finally set the minimum for the current mode.
+
+However, the part that sets the temporary minimum and drops the older
+one runs before the commit synchronization code.
+
+Thus, under the proper conditions, we can end up mixing up the minimums
+and ending up with the wrong one for our current step.
+
+To avoid it, let's move the clock setup in the protected section.
+
+Fixes: d7d96c00e585 ("drm/vc4: hvs: Boost the core clock during modeset")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Tested-by: Jian-Hong Pan <jhp@endlessos.org>
+Link: https://lore.kernel.org/r/20211117094527.146275-2-maxime@cerno.tech
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/vc4/vc4_kms.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -353,9 +353,6 @@ static void vc4_atomic_commit_tail(struc
+ vc4_hvs_mask_underrun(dev, vc4_crtc_state->assigned_channel);
+ }
+
+- if (vc4->hvs->hvs5)
+- clk_set_min_rate(hvs->core_clk, 500000000);
+-
+ old_hvs_state = vc4_hvs_get_old_global_state(state);
+ if (!old_hvs_state)
+ return;
+@@ -377,6 +374,9 @@ static void vc4_atomic_commit_tail(struc
+ drm_err(dev, "Timed out waiting for commit\n");
+ }
+
++ if (vc4->hvs->hvs5)
++ clk_set_min_rate(hvs->core_clk, 500000000);
++
+ drm_atomic_helper_commit_modeset_disables(dev, state);
+
+ vc4_ctm_commit(vc4, state);
--- /dev/null
+From 213f5f8f31f10aa1e83187ae20fb7fa4e626b724 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 1 Dec 2021 18:26:35 -0800
+Subject: ipv4: convert fib_num_tclassid_users to atomic_t
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit 213f5f8f31f10aa1e83187ae20fb7fa4e626b724 upstream.
+
+Before commit faa041a40b9f ("ipv4: Create cleanup helper for fib_nh")
+changes to net->ipv4.fib_num_tclassid_users were protected by RTNL.
+
+After the change, this is no longer the case, as free_fib_info_rcu()
+runs after rcu grace period, without rtnl being held.
+
+Fixes: faa041a40b9f ("ipv4: Create cleanup helper for fib_nh")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: David Ahern <dsahern@kernel.org>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/ip_fib.h | 2 +-
+ include/net/netns/ipv4.h | 2 +-
+ net/ipv4/fib_frontend.c | 2 +-
+ net/ipv4/fib_rules.c | 4 ++--
+ net/ipv4/fib_semantics.c | 4 ++--
+ 5 files changed, 7 insertions(+), 7 deletions(-)
+
+--- a/include/net/ip_fib.h
++++ b/include/net/ip_fib.h
+@@ -438,7 +438,7 @@ int fib_validate_source(struct sk_buff *
+ #ifdef CONFIG_IP_ROUTE_CLASSID
+ static inline int fib_num_tclassid_users(struct net *net)
+ {
+- return net->ipv4.fib_num_tclassid_users;
++ return atomic_read(&net->ipv4.fib_num_tclassid_users);
+ }
+ #else
+ static inline int fib_num_tclassid_users(struct net *net)
+--- a/include/net/netns/ipv4.h
++++ b/include/net/netns/ipv4.h
+@@ -65,7 +65,7 @@ struct netns_ipv4 {
+ bool fib_has_custom_local_routes;
+ bool fib_offload_disabled;
+ #ifdef CONFIG_IP_ROUTE_CLASSID
+- int fib_num_tclassid_users;
++ atomic_t fib_num_tclassid_users;
+ #endif
+ struct hlist_head *fib_table_hash;
+ struct sock *fibnl;
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -1582,7 +1582,7 @@ static int __net_init fib_net_init(struc
+ int error;
+
+ #ifdef CONFIG_IP_ROUTE_CLASSID
+- net->ipv4.fib_num_tclassid_users = 0;
++ atomic_set(&net->ipv4.fib_num_tclassid_users, 0);
+ #endif
+ error = ip_fib_net_init(net);
+ if (error < 0)
+--- a/net/ipv4/fib_rules.c
++++ b/net/ipv4/fib_rules.c
+@@ -264,7 +264,7 @@ static int fib4_rule_configure(struct fi
+ if (tb[FRA_FLOW]) {
+ rule4->tclassid = nla_get_u32(tb[FRA_FLOW]);
+ if (rule4->tclassid)
+- net->ipv4.fib_num_tclassid_users++;
++ atomic_inc(&net->ipv4.fib_num_tclassid_users);
+ }
+ #endif
+
+@@ -296,7 +296,7 @@ static int fib4_rule_delete(struct fib_r
+
+ #ifdef CONFIG_IP_ROUTE_CLASSID
+ if (((struct fib4_rule *)rule)->tclassid)
+- net->ipv4.fib_num_tclassid_users--;
++ atomic_dec(&net->ipv4.fib_num_tclassid_users);
+ #endif
+ net->ipv4.fib_has_custom_rules = true;
+
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -220,7 +220,7 @@ void fib_nh_release(struct net *net, str
+ {
+ #ifdef CONFIG_IP_ROUTE_CLASSID
+ if (fib_nh->nh_tclassid)
+- net->ipv4.fib_num_tclassid_users--;
++ atomic_dec(&net->ipv4.fib_num_tclassid_users);
+ #endif
+ fib_nh_common_release(&fib_nh->nh_common);
+ }
+@@ -632,7 +632,7 @@ int fib_nh_init(struct net *net, struct
+ #ifdef CONFIG_IP_ROUTE_CLASSID
+ nh->nh_tclassid = cfg->fc_flow;
+ if (nh->nh_tclassid)
+- net->ipv4.fib_num_tclassid_users++;
++ atomic_inc(&net->ipv4.fib_num_tclassid_users);
+ #endif
+ #ifdef CONFIG_IP_ROUTE_MULTIPATH
+ nh->fib_nh_weight = nh_weight;
--- /dev/null
+From f5cecf1d4c5ff76172928bc32e99ca56a5ca2f56 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C5=81ukasz=20Bartosik?= <lb@semihalf.com>
+Date: Wed, 10 Nov 2021 22:57:44 +0100
+Subject: iwlwifi: fix warnings produced by kernel debug options
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Łukasz Bartosik <lb@semihalf.com>
+
+commit f5cecf1d4c5ff76172928bc32e99ca56a5ca2f56 upstream.
+
+Fix warnings produced by:
+- lockdep_assert_wiphy() in function reg_process_self_managed_hint(),
+- wiphy_dereference() in function iwl_mvm_init_fw_regd().
+Both function are expected to be called in critical section.
+
+The warnings were discovered when running v5.15 kernel
+with debug options enabled:
+
+1)
+Hardware name: Google Delbin/Delbin
+RIP: 0010:reg_process_self_managed_hint+0x254/0x347 [cfg80211]
+...
+Call Trace:
+regulatory_set_wiphy_regd_sync+0x3d/0xb0
+iwl_mvm_init_mcc+0x49d/0x5a2
+iwl_op_mode_mvm_start+0x1b58/0x2507
+? iwl_mvm_reprobe_wk+0x94/0x94
+_iwl_op_mode_start+0x146/0x1a3
+iwl_opmode_register+0xda/0x13d
+init_module+0x28/0x1000
+
+2)
+drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c:263 suspicious rcu_dereference_protected() usage!
+...
+Hardware name: Google Delbin/Delbin, BIOS Google_Delbin
+Call Trace:
+dump_stack_lvl+0xb1/0xe6
+iwl_mvm_init_fw_regd+0x2e7/0x379
+iwl_mvm_init_mcc+0x2c6/0x5a2
+iwl_op_mode_mvm_start+0x1b58/0x2507
+? iwl_mvm_reprobe_wk+0x94/0x94
+_iwl_op_mode_start+0x146/0x1a3
+iwl_opmode_register+0xda/0x13d
+init_module+0x28/0x100
+
+Fixes: a05829a7222e ("cfg80211: avoid holding the RTNL when calling the driver")
+Signed-off-by: Łukasz Bartosik <lb@semihalf.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20211110215744.5487-1-lukasz.bartosik@semihalf.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+@@ -687,6 +687,7 @@ static int iwl_mvm_start_get_nvm(struct
+ int ret;
+
+ rtnl_lock();
++ wiphy_lock(mvm->hw->wiphy);
+ mutex_lock(&mvm->mutex);
+
+ ret = iwl_run_init_mvm_ucode(mvm);
+@@ -702,6 +703,7 @@ static int iwl_mvm_start_get_nvm(struct
+ iwl_mvm_stop_device(mvm);
+
+ mutex_unlock(&mvm->mutex);
++ wiphy_unlock(mvm->hw->wiphy);
+ rtnl_unlock();
+
+ if (ret < 0)
--- /dev/null
+From 6e53d6d26920d5221d3f4d4f5ffdd629ea69aa5c Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Thu, 18 Nov 2021 13:47:48 +0100
+Subject: mt76: mt7915: fix NULL pointer dereference in mt7915_get_phy_mode
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+commit 6e53d6d26920d5221d3f4d4f5ffdd629ea69aa5c upstream.
+
+Fix the following NULL pointer dereference in mt7915_get_phy_mode
+routine adding an ibss interface to the mt7915 driver.
+
+[ 101.137097] wlan0: Trigger new scan to find an IBSS to join
+[ 102.827039] wlan0: Creating new IBSS network, BSSID 26:a4:50:1a:6e:69
+[ 103.064756] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
+[ 103.073670] Mem abort info:
+[ 103.076520] ESR = 0x96000005
+[ 103.079614] EC = 0x25: DABT (current EL), IL = 32 bits
+[ 103.084934] SET = 0, FnV = 0
+[ 103.088042] EA = 0, S1PTW = 0
+[ 103.091215] Data abort info:
+[ 103.094104] ISV = 0, ISS = 0x00000005
+[ 103.098041] CM = 0, WnR = 0
+[ 103.101044] user pgtable: 4k pages, 39-bit VAs, pgdp=00000000460b1000
+[ 103.107565] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
+[ 103.116590] Internal error: Oops: 96000005 [#1] SMP
+[ 103.189066] CPU: 1 PID: 333 Comm: kworker/u4:3 Not tainted 5.10.75 #0
+[ 103.195498] Hardware name: MediaTek MT7622 RFB1 board (DT)
+[ 103.201124] Workqueue: phy0 ieee80211_iface_work [mac80211]
+[ 103.206695] pstate: 20000005 (nzCv daif -PAN -UAO -TCO BTYPE=--)
+[ 103.212705] pc : mt7915_get_phy_mode+0x68/0x120 [mt7915e]
+[ 103.218103] lr : mt7915_mcu_add_bss_info+0x11c/0x760 [mt7915e]
+[ 103.223927] sp : ffffffc011cdb9e0
+[ 103.227235] x29: ffffffc011cdb9e0 x28: ffffff8006563098
+[ 103.232545] x27: ffffff8005f4da22 x26: ffffff800685ac40
+[ 103.237855] x25: 0000000000000001 x24: 000000000000011f
+[ 103.243165] x23: ffffff8005f4e260 x22: ffffff8006567918
+[ 103.248475] x21: ffffff8005f4df80 x20: ffffff800685ac58
+[ 103.253785] x19: ffffff8006744400 x18: 0000000000000000
+[ 103.259094] x17: 0000000000000000 x16: 0000000000000001
+[ 103.264403] x15: 000899c3a2d9d2e4 x14: 000899bdc3c3a1c8
+[ 103.269713] x13: 0000000000000000 x12: 0000000000000000
+[ 103.275024] x11: ffffffc010e30c20 x10: 0000000000000000
+[ 103.280333] x9 : 0000000000000050 x8 : ffffff8006567d88
+[ 103.285642] x7 : ffffff8006563b5c x6 : ffffff8006563b44
+[ 103.290952] x5 : 0000000000000002 x4 : 0000000000000001
+[ 103.296262] x3 : 0000000000000001 x2 : 0000000000000001
+[ 103.301572] x1 : 0000000000000000 x0 : 0000000000000011
+[ 103.306882] Call trace:
+[ 103.309328] mt7915_get_phy_mode+0x68/0x120 [mt7915e]
+[ 103.314378] mt7915_bss_info_changed+0x198/0x200 [mt7915e]
+[ 103.319941] ieee80211_bss_info_change_notify+0x128/0x290 [mac80211]
+[ 103.326360] __ieee80211_sta_join_ibss+0x308/0x6c4 [mac80211]
+[ 103.332171] ieee80211_sta_create_ibss+0x8c/0x10c [mac80211]
+[ 103.337895] ieee80211_ibss_work+0x3dc/0x614 [mac80211]
+[ 103.343185] ieee80211_iface_work+0x388/0x3f0 [mac80211]
+[ 103.348495] process_one_work+0x288/0x690
+[ 103.352499] worker_thread+0x70/0x464
+[ 103.356157] kthread+0x144/0x150
+[ 103.359380] ret_from_fork+0x10/0x18
+[ 103.362952] Code: 394008c3 52800220 394000e4 7100007f (39400023)
+
+Fixes: 37f4ca907c46 ("mt76: mt7915: register per-phy HE capabilities for each interface")
+Fixes: e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Acked-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/ddae419a740f1fb9e48afd432035e9f394f512ee.1637239456.git.lorenzo@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -176,7 +176,7 @@ mt7915_get_phy_mode(struct ieee80211_vif
+ if (ht_cap->ht_supported)
+ mode |= PHY_MODE_GN;
+
+- if (he_cap->has_he)
++ if (he_cap && he_cap->has_he)
+ mode |= PHY_MODE_AX_24G;
+ } else if (band == NL80211_BAND_5GHZ) {
+ mode |= PHY_MODE_A;
+@@ -187,7 +187,7 @@ mt7915_get_phy_mode(struct ieee80211_vif
+ if (vht_cap->vht_supported)
+ mode |= PHY_MODE_AC;
+
+- if (he_cap->has_he)
++ if (he_cap && he_cap->has_he)
+ mode |= PHY_MODE_AX_5G;
+ }
+
--- /dev/null
+From 7a10d8c810cfad3e79372d7d1c77899d86cd6662 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Tue, 30 Nov 2021 09:01:55 -0800
+Subject: net: annotate data-races on txq->xmit_lock_owner
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit 7a10d8c810cfad3e79372d7d1c77899d86cd6662 upstream.
+
+syzbot found that __dev_queue_xmit() is reading txq->xmit_lock_owner
+without annotations.
+
+No serious issue there, let's document what is happening there.
+
+BUG: KCSAN: data-race in __dev_queue_xmit / __dev_queue_xmit
+
+write to 0xffff888139d09484 of 4 bytes by interrupt on cpu 0:
+ __netif_tx_unlock include/linux/netdevice.h:4437 [inline]
+ __dev_queue_xmit+0x948/0xf70 net/core/dev.c:4229
+ dev_queue_xmit_accel+0x19/0x20 net/core/dev.c:4265
+ macvlan_queue_xmit drivers/net/macvlan.c:543 [inline]
+ macvlan_start_xmit+0x2b3/0x3d0 drivers/net/macvlan.c:567
+ __netdev_start_xmit include/linux/netdevice.h:4987 [inline]
+ netdev_start_xmit include/linux/netdevice.h:5001 [inline]
+ xmit_one+0x105/0x2f0 net/core/dev.c:3590
+ dev_hard_start_xmit+0x72/0x120 net/core/dev.c:3606
+ sch_direct_xmit+0x1b2/0x7c0 net/sched/sch_generic.c:342
+ __dev_xmit_skb+0x83d/0x1370 net/core/dev.c:3817
+ __dev_queue_xmit+0x590/0xf70 net/core/dev.c:4194
+ dev_queue_xmit+0x13/0x20 net/core/dev.c:4259
+ neigh_hh_output include/net/neighbour.h:511 [inline]
+ neigh_output include/net/neighbour.h:525 [inline]
+ ip6_finish_output2+0x995/0xbb0 net/ipv6/ip6_output.c:126
+ __ip6_finish_output net/ipv6/ip6_output.c:191 [inline]
+ ip6_finish_output+0x444/0x4c0 net/ipv6/ip6_output.c:201
+ NF_HOOK_COND include/linux/netfilter.h:296 [inline]
+ ip6_output+0x10e/0x210 net/ipv6/ip6_output.c:224
+ dst_output include/net/dst.h:450 [inline]
+ NF_HOOK include/linux/netfilter.h:307 [inline]
+ ndisc_send_skb+0x486/0x610 net/ipv6/ndisc.c:508
+ ndisc_send_rs+0x3b0/0x3e0 net/ipv6/ndisc.c:702
+ addrconf_rs_timer+0x370/0x540 net/ipv6/addrconf.c:3898
+ call_timer_fn+0x2e/0x240 kernel/time/timer.c:1421
+ expire_timers+0x116/0x240 kernel/time/timer.c:1466
+ __run_timers+0x368/0x410 kernel/time/timer.c:1734
+ run_timer_softirq+0x2e/0x60 kernel/time/timer.c:1747
+ __do_softirq+0x158/0x2de kernel/softirq.c:558
+ __irq_exit_rcu kernel/softirq.c:636 [inline]
+ irq_exit_rcu+0x37/0x70 kernel/softirq.c:648
+ sysvec_apic_timer_interrupt+0x3e/0xb0 arch/x86/kernel/apic/apic.c:1097
+ asm_sysvec_apic_timer_interrupt+0x12/0x20
+
+read to 0xffff888139d09484 of 4 bytes by interrupt on cpu 1:
+ __dev_queue_xmit+0x5e3/0xf70 net/core/dev.c:4213
+ dev_queue_xmit_accel+0x19/0x20 net/core/dev.c:4265
+ macvlan_queue_xmit drivers/net/macvlan.c:543 [inline]
+ macvlan_start_xmit+0x2b3/0x3d0 drivers/net/macvlan.c:567
+ __netdev_start_xmit include/linux/netdevice.h:4987 [inline]
+ netdev_start_xmit include/linux/netdevice.h:5001 [inline]
+ xmit_one+0x105/0x2f0 net/core/dev.c:3590
+ dev_hard_start_xmit+0x72/0x120 net/core/dev.c:3606
+ sch_direct_xmit+0x1b2/0x7c0 net/sched/sch_generic.c:342
+ __dev_xmit_skb+0x83d/0x1370 net/core/dev.c:3817
+ __dev_queue_xmit+0x590/0xf70 net/core/dev.c:4194
+ dev_queue_xmit+0x13/0x20 net/core/dev.c:4259
+ neigh_resolve_output+0x3db/0x410 net/core/neighbour.c:1523
+ neigh_output include/net/neighbour.h:527 [inline]
+ ip6_finish_output2+0x9be/0xbb0 net/ipv6/ip6_output.c:126
+ __ip6_finish_output net/ipv6/ip6_output.c:191 [inline]
+ ip6_finish_output+0x444/0x4c0 net/ipv6/ip6_output.c:201
+ NF_HOOK_COND include/linux/netfilter.h:296 [inline]
+ ip6_output+0x10e/0x210 net/ipv6/ip6_output.c:224
+ dst_output include/net/dst.h:450 [inline]
+ NF_HOOK include/linux/netfilter.h:307 [inline]
+ ndisc_send_skb+0x486/0x610 net/ipv6/ndisc.c:508
+ ndisc_send_rs+0x3b0/0x3e0 net/ipv6/ndisc.c:702
+ addrconf_rs_timer+0x370/0x540 net/ipv6/addrconf.c:3898
+ call_timer_fn+0x2e/0x240 kernel/time/timer.c:1421
+ expire_timers+0x116/0x240 kernel/time/timer.c:1466
+ __run_timers+0x368/0x410 kernel/time/timer.c:1734
+ run_timer_softirq+0x2e/0x60 kernel/time/timer.c:1747
+ __do_softirq+0x158/0x2de kernel/softirq.c:558
+ __irq_exit_rcu kernel/softirq.c:636 [inline]
+ irq_exit_rcu+0x37/0x70 kernel/softirq.c:648
+ sysvec_apic_timer_interrupt+0x8d/0xb0 arch/x86/kernel/apic/apic.c:1097
+ asm_sysvec_apic_timer_interrupt+0x12/0x20
+ kcsan_setup_watchpoint+0x94/0x420 kernel/kcsan/core.c:443
+ folio_test_anon include/linux/page-flags.h:581 [inline]
+ PageAnon include/linux/page-flags.h:586 [inline]
+ zap_pte_range+0x5ac/0x10e0 mm/memory.c:1347
+ zap_pmd_range mm/memory.c:1467 [inline]
+ zap_pud_range mm/memory.c:1496 [inline]
+ zap_p4d_range mm/memory.c:1517 [inline]
+ unmap_page_range+0x2dc/0x3d0 mm/memory.c:1538
+ unmap_single_vma+0x157/0x210 mm/memory.c:1583
+ unmap_vmas+0xd0/0x180 mm/memory.c:1615
+ exit_mmap+0x23d/0x470 mm/mmap.c:3170
+ __mmput+0x27/0x1b0 kernel/fork.c:1113
+ mmput+0x3d/0x50 kernel/fork.c:1134
+ exit_mm+0xdb/0x170 kernel/exit.c:507
+ do_exit+0x608/0x17a0 kernel/exit.c:819
+ do_group_exit+0xce/0x180 kernel/exit.c:929
+ get_signal+0xfc3/0x1550 kernel/signal.c:2852
+ arch_do_signal_or_restart+0x8c/0x2e0 arch/x86/kernel/signal.c:868
+ handle_signal_work kernel/entry/common.c:148 [inline]
+ exit_to_user_mode_loop kernel/entry/common.c:172 [inline]
+ exit_to_user_mode_prepare+0x113/0x190 kernel/entry/common.c:207
+ __syscall_exit_to_user_mode_work kernel/entry/common.c:289 [inline]
+ syscall_exit_to_user_mode+0x20/0x40 kernel/entry/common.c:300
+ do_syscall_64+0x50/0xd0 arch/x86/entry/common.c:86
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+value changed: 0x00000000 -> 0xffffffff
+
+Reported by Kernel Concurrency Sanitizer on:
+CPU: 1 PID: 28712 Comm: syz-executor.0 Tainted: G W 5.16.0-rc1-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Link: https://lore.kernel.org/r/20211130170155.2331929-1-eric.dumazet@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/netdevice.h | 19 +++++++++++++------
+ net/core/dev.c | 5 ++++-
+ 2 files changed, 17 insertions(+), 7 deletions(-)
+
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -4403,7 +4403,8 @@ static inline u32 netif_msg_init(int deb
+ static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu)
+ {
+ spin_lock(&txq->_xmit_lock);
+- txq->xmit_lock_owner = cpu;
++ /* Pairs with READ_ONCE() in __dev_queue_xmit() */
++ WRITE_ONCE(txq->xmit_lock_owner, cpu);
+ }
+
+ static inline bool __netif_tx_acquire(struct netdev_queue *txq)
+@@ -4420,26 +4421,32 @@ static inline void __netif_tx_release(st
+ static inline void __netif_tx_lock_bh(struct netdev_queue *txq)
+ {
+ spin_lock_bh(&txq->_xmit_lock);
+- txq->xmit_lock_owner = smp_processor_id();
++ /* Pairs with READ_ONCE() in __dev_queue_xmit() */
++ WRITE_ONCE(txq->xmit_lock_owner, smp_processor_id());
+ }
+
+ static inline bool __netif_tx_trylock(struct netdev_queue *txq)
+ {
+ bool ok = spin_trylock(&txq->_xmit_lock);
+- if (likely(ok))
+- txq->xmit_lock_owner = smp_processor_id();
++
++ if (likely(ok)) {
++ /* Pairs with READ_ONCE() in __dev_queue_xmit() */
++ WRITE_ONCE(txq->xmit_lock_owner, smp_processor_id());
++ }
+ return ok;
+ }
+
+ static inline void __netif_tx_unlock(struct netdev_queue *txq)
+ {
+- txq->xmit_lock_owner = -1;
++ /* Pairs with READ_ONCE() in __dev_queue_xmit() */
++ WRITE_ONCE(txq->xmit_lock_owner, -1);
+ spin_unlock(&txq->_xmit_lock);
+ }
+
+ static inline void __netif_tx_unlock_bh(struct netdev_queue *txq)
+ {
+- txq->xmit_lock_owner = -1;
++ /* Pairs with READ_ONCE() in __dev_queue_xmit() */
++ WRITE_ONCE(txq->xmit_lock_owner, -1);
+ spin_unlock_bh(&txq->_xmit_lock);
+ }
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -4195,7 +4195,10 @@ static int __dev_queue_xmit(struct sk_bu
+ if (dev->flags & IFF_UP) {
+ int cpu = smp_processor_id(); /* ok because BHs are off */
+
+- if (txq->xmit_lock_owner != cpu) {
++ /* Other cpus might concurrently change txq->xmit_lock_owner
++ * to -1 or to their cpu id, but not to our id.
++ */
++ if (READ_ONCE(txq->xmit_lock_owner) != cpu) {
+ if (dev_xmit_recursion())
+ goto recursion_alert;
+
--- /dev/null
+From 88362ebfd7fb569c78d5cb507aa9d3c8fc203839 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Wed, 1 Dec 2021 20:17:20 -0800
+Subject: net: dsa: b53: Add SPI ID table
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+commit 88362ebfd7fb569c78d5cb507aa9d3c8fc203839 upstream.
+
+Currently autoloading for SPI devices does not use the DT ID table, it
+uses SPI modalises. Supporting OF modalises is going to be difficult if
+not impractical, an attempt was made but has been reverted, so ensure
+that module autoloading works for this driver by adding an id_table
+listing the SPI IDs for everything.
+
+Fixes: 96c8395e2166 ("spi: Revert modalias changes")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/dsa/b53/b53_spi.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_spi.c
++++ b/drivers/net/dsa/b53/b53_spi.c
+@@ -349,6 +349,19 @@ static const struct of_device_id b53_spi
+ };
+ MODULE_DEVICE_TABLE(of, b53_spi_of_match);
+
++static const struct spi_device_id b53_spi_ids[] = {
++ { .name = "bcm5325" },
++ { .name = "bcm5365" },
++ { .name = "bcm5395" },
++ { .name = "bcm5397" },
++ { .name = "bcm5398" },
++ { .name = "bcm53115" },
++ { .name = "bcm53125" },
++ { .name = "bcm53128" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(spi, b53_spi_ids);
++
+ static struct spi_driver b53_spi_driver = {
+ .driver = {
+ .name = "b53-switch",
+@@ -357,6 +370,7 @@ static struct spi_driver b53_spi_driver
+ .probe = b53_spi_probe,
+ .remove = b53_spi_remove,
+ .shutdown = b53_spi_shutdown,
++ .id_table = b53_spi_ids,
+ };
+
+ module_spi_driver(b53_spi_driver);
--- /dev/null
+From b83f5ac7d922e69a109261f5f940eebbd4e514c4 Mon Sep 17 00:00:00 2001
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Date: Mon, 29 Nov 2021 22:53:27 +0100
+Subject: net: marvell: mvpp2: Fix the computation of shared CPUs
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+commit b83f5ac7d922e69a109261f5f940eebbd4e514c4 upstream.
+
+'bitmap_fill()' fills a bitmap one 'long' at a time.
+It is likely that an exact number of bits is expected.
+
+Use 'bitmap_set()' instead in order not to set unexpected bits.
+
+Fixes: e531f76757eb ("net: mvpp2: handle cases where more CPUs are available than s/w threads")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -7457,7 +7457,7 @@ static int mvpp2_probe(struct platform_d
+
+ shared = num_present_cpus() - priv->nthreads;
+ if (shared > 0)
+- bitmap_fill(&priv->lock_map,
++ bitmap_set(&priv->lock_map, 0,
+ min_t(int, shared, MVPP2_MAX_THREADS));
+
+ for (i = 0; i < MVPP2_MAX_THREADS; i++) {
--- /dev/null
+From addad7643142f500080417dd7272f49b7a185570 Mon Sep 17 00:00:00 2001
+From: Zhou Qingyang <zhou1615@umn.edu>
+Date: Wed, 1 Dec 2021 00:44:38 +0800
+Subject: net/mlx4_en: Fix an use-after-free bug in mlx4_en_try_alloc_resources()
+
+From: Zhou Qingyang <zhou1615@umn.edu>
+
+commit addad7643142f500080417dd7272f49b7a185570 upstream.
+
+In mlx4_en_try_alloc_resources(), mlx4_en_copy_priv() is called and
+tmp->tx_cq will be freed on the error path of mlx4_en_copy_priv().
+After that mlx4_en_alloc_resources() is called and there is a dereference
+of &tmp->tx_cq[t][i] in mlx4_en_alloc_resources(), which could lead to
+a use after free problem on failure of mlx4_en_copy_priv().
+
+Fix this bug by adding a check of mlx4_en_copy_priv()
+
+This bug was found by a static analyzer. The analysis employs
+differential checking to identify inconsistent security operations
+(e.g., checks or kfrees) between two code paths and confirms that the
+inconsistent operations are not recovered in the current function or
+the callers, so they constitute bugs.
+
+Note that, as a bug found by static analysis, it can be a false
+positive or hard to trigger. Multiple researchers have cross-reviewed
+the bug.
+
+Builds with CONFIG_MLX4_EN=m show no new warnings,
+and our static analyzer no longer warns about this code.
+
+Fixes: ec25bc04ed8e ("net/mlx4_en: Add resilience in low memory systems")
+Signed-off-by: Zhou Qingyang <zhou1615@umn.edu>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Link: https://lore.kernel.org/r/20211130164438.190591-1-zhou1615@umn.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
++++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+@@ -2286,9 +2286,14 @@ int mlx4_en_try_alloc_resources(struct m
+ bool carry_xdp_prog)
+ {
+ struct bpf_prog *xdp_prog;
+- int i, t;
++ int i, t, ret;
+
+- mlx4_en_copy_priv(tmp, priv, prof);
++ ret = mlx4_en_copy_priv(tmp, priv, prof);
++ if (ret) {
++ en_warn(priv, "%s: mlx4_en_copy_priv() failed, return\n",
++ __func__);
++ return ret;
++ }
+
+ if (mlx4_en_alloc_resources(tmp)) {
+ en_warn(priv,
--- /dev/null
+From c65d638ab39034cbaa36773b980d28106cfc81fa Mon Sep 17 00:00:00 2001
+From: Raed Salem <raeds@nvidia.com>
+Date: Wed, 17 Nov 2021 13:33:57 +0200
+Subject: net/mlx5e: IPsec: Fix Software parser inner l3 type setting in case of encapsulation
+
+From: Raed Salem <raeds@nvidia.com>
+
+commit c65d638ab39034cbaa36773b980d28106cfc81fa upstream.
+
+Current code wrongly uses the skb->protocol field which reflects the
+outer l3 protocol to set the inner l3 type in Software Parser (SWP)
+fields settings in the ethernet segment (eseg) in flows where inner
+l3 exists like in Vxlan over ESP flow, the above method wrongly use
+the outer protocol type instead of the inner one. thus breaking cases
+where inner and outer headers have different protocols.
+
+Fix by setting the inner l3 type in SWP according to the inner l3 ip
+header version.
+
+Fixes: 2ac9cfe78223 ("net/mlx5e: IPSec, Add Innova IPSec offload TX data path")
+Signed-off-by: Raed Salem <raeds@nvidia.com>
+Reviewed-by: Maor Dickman <maord@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
+@@ -191,7 +191,7 @@ static void mlx5e_ipsec_set_swp(struct s
+ eseg->swp_inner_l3_offset = skb_inner_network_offset(skb) / 2;
+ eseg->swp_inner_l4_offset =
+ (skb->csum_start + skb->head - skb->data) / 2;
+- if (skb->protocol == htons(ETH_P_IPV6))
++ if (inner_ip_hdr(skb)->version == 6)
+ eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6;
+ break;
+ default:
--- /dev/null
+From 19f36edf14bcdb783aef3af8217df96f76a8ce34 Mon Sep 17 00:00:00 2001
+From: William Kucharski <william.kucharski@oracle.com>
+Date: Wed, 1 Dec 2021 07:45:22 -0700
+Subject: net/rds: correct socket tunable error in rds_tcp_tune()
+
+From: William Kucharski <william.kucharski@oracle.com>
+
+commit 19f36edf14bcdb783aef3af8217df96f76a8ce34 upstream.
+
+Correct an error where setting /proc/sys/net/rds/tcp/rds_tcp_rcvbuf would
+instead modify the socket's sk_sndbuf and would leave sk_rcvbuf untouched.
+
+Fixes: c6a58ffed536 ("RDS: TCP: Add sysctl tunables for sndbuf/rcvbuf on rds-tcp socket")
+Signed-off-by: William Kucharski <william.kucharski@oracle.com>
+Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rds/tcp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/rds/tcp.c
++++ b/net/rds/tcp.c
+@@ -500,7 +500,7 @@ void rds_tcp_tune(struct socket *sock)
+ sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
+ }
+ if (rtn->rcvbuf_size > 0) {
+- sk->sk_sndbuf = rtn->rcvbuf_size;
++ sk->sk_rcvbuf = rtn->rcvbuf_size;
+ sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
+ }
+ release_sock(sk);
--- /dev/null
+From 789b6cc2a5f9123b9c549b886fdc47c865cfe0ba Mon Sep 17 00:00:00 2001
+From: Dust Li <dust.li@linux.alibaba.com>
+Date: Wed, 1 Dec 2021 11:02:30 +0800
+Subject: net/smc: fix wrong list_del in smc_lgr_cleanup_early
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dust Li <dust.li@linux.alibaba.com>
+
+commit 789b6cc2a5f9123b9c549b886fdc47c865cfe0ba upstream.
+
+smc_lgr_cleanup_early() meant to delete the link
+group from the link group list, but it deleted
+the list head by mistake.
+
+This may cause memory corruption since we didn't
+remove the real link group from the list and later
+memseted the link group structure.
+We got a list corruption panic when testing:
+
+[ 231.277259] list_del corruption. prev->next should be ffff8881398a8000, but was 0000000000000000
+[ 231.278222] ------------[ cut here ]------------
+[ 231.278726] kernel BUG at lib/list_debug.c:53!
+[ 231.279326] invalid opcode: 0000 [#1] SMP NOPTI
+[ 231.279803] CPU: 0 PID: 5 Comm: kworker/0:0 Not tainted 5.10.46+ #435
+[ 231.280466] Hardware name: Alibaba Cloud ECS, BIOS 8c24b4c 04/01/2014
+[ 231.281248] Workqueue: events smc_link_down_work
+[ 231.281732] RIP: 0010:__list_del_entry_valid+0x70/0x90
+[ 231.282258] Code: 4c 60 82 e8 7d cc 6a 00 0f 0b 48 89 fe 48 c7 c7 88 4c
+60 82 e8 6c cc 6a 00 0f 0b 48 89 fe 48 c7 c7 c0 4c 60 82 e8 5b cc 6a 00 <0f>
+0b 48 89 fe 48 c7 c7 00 4d 60 82 e8 4a cc 6a 00 0f 0b cc cc cc
+[ 231.284146] RSP: 0018:ffffc90000033d58 EFLAGS: 00010292
+[ 231.284685] RAX: 0000000000000054 RBX: ffff8881398a8000 RCX: 0000000000000000
+[ 231.285415] RDX: 0000000000000001 RSI: ffff88813bc18040 RDI: ffff88813bc18040
+[ 231.286141] RBP: ffffffff8305ad40 R08: 0000000000000003 R09: 0000000000000001
+[ 231.286873] R10: ffffffff82803da0 R11: ffffc90000033b90 R12: 0000000000000001
+[ 231.287606] R13: 0000000000000000 R14: ffff8881398a8000 R15: 0000000000000003
+[ 231.288337] FS: 0000000000000000(0000) GS:ffff88813bc00000(0000) knlGS:0000000000000000
+[ 231.289160] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 231.289754] CR2: 0000000000e72058 CR3: 000000010fa96006 CR4: 00000000003706f0
+[ 231.290485] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 231.291211] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[ 231.291940] Call Trace:
+[ 231.292211] smc_lgr_terminate_sched+0x53/0xa0
+[ 231.292677] smc_switch_conns+0x75/0x6b0
+[ 231.293085] ? update_load_avg+0x1a6/0x590
+[ 231.293517] ? ttwu_do_wakeup+0x17/0x150
+[ 231.293907] ? update_load_avg+0x1a6/0x590
+[ 231.294317] ? newidle_balance+0xca/0x3d0
+[ 231.294716] smcr_link_down+0x50/0x1a0
+[ 231.295090] ? __wake_up_common_lock+0x77/0x90
+[ 231.295534] smc_link_down_work+0x46/0x60
+[ 231.295933] process_one_work+0x18b/0x350
+
+Fixes: a0a62ee15a829 ("net/smc: separate locks for SMCD and SMCR link group lists")
+Signed-off-by: Dust Li <dust.li@linux.alibaba.com>
+Acked-by: Karsten Graul <kgraul@linux.ibm.com>
+Reviewed-by: Tony Lu <tonylu@linux.alibaba.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/smc/smc_core.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/net/smc/smc_core.c
++++ b/net/smc/smc_core.c
+@@ -582,18 +582,17 @@ int smcd_nl_get_lgr(struct sk_buff *skb,
+ void smc_lgr_cleanup_early(struct smc_connection *conn)
+ {
+ struct smc_link_group *lgr = conn->lgr;
+- struct list_head *lgr_list;
+ spinlock_t *lgr_lock;
+
+ if (!lgr)
+ return;
+
+ smc_conn_free(conn);
+- lgr_list = smc_lgr_list_head(lgr, &lgr_lock);
++ smc_lgr_list_head(lgr, &lgr_lock);
+ spin_lock_bh(lgr_lock);
+ /* do not use this link group for new connections */
+- if (!list_empty(lgr_list))
+- list_del_init(lgr_list);
++ if (!list_empty(&lgr->list))
++ list_del_init(&lgr->list);
+ spin_unlock_bh(lgr_lock);
+ __smc_lgr_terminate(lgr, true);
+ }
--- /dev/null
+From 00e158fb91dfaff3f94746f260d11f1a4853506e Mon Sep 17 00:00:00 2001
+From: Tony Lu <tonylu@linux.alibaba.com>
+Date: Wed, 1 Dec 2021 14:42:16 +0800
+Subject: net/smc: Keep smc_close_final rc during active close
+
+From: Tony Lu <tonylu@linux.alibaba.com>
+
+commit 00e158fb91dfaff3f94746f260d11f1a4853506e upstream.
+
+When smc_close_final() returns error, the return code overwrites by
+kernel_sock_shutdown() in smc_close_active(). The return code of
+smc_close_final() is more important than kernel_sock_shutdown(), and it
+will pass to userspace directly.
+
+Fix it by keeping both return codes, if smc_close_final() raises an
+error, return it or kernel_sock_shutdown()'s.
+
+Link: https://lore.kernel.org/linux-s390/1f67548e-cbf6-0dce-82b5-10288a4583bd@linux.ibm.com/
+Fixes: 606a63c9783a ("net/smc: Ensure the active closing peer first closes clcsock")
+Suggested-by: Karsten Graul <kgraul@linux.ibm.com>
+Signed-off-by: Tony Lu <tonylu@linux.alibaba.com>
+Reviewed-by: Wen Gu <guwen@linux.alibaba.com>
+Acked-by: Karsten Graul <kgraul@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/smc/smc_close.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/net/smc/smc_close.c
++++ b/net/smc/smc_close.c
+@@ -195,6 +195,7 @@ int smc_close_active(struct smc_sock *sm
+ int old_state;
+ long timeout;
+ int rc = 0;
++ int rc1 = 0;
+
+ timeout = current->flags & PF_EXITING ?
+ 0 : sock_flag(sk, SOCK_LINGER) ?
+@@ -232,8 +233,11 @@ again:
+ /* actively shutdown clcsock before peer close it,
+ * prevent peer from entering TIME_WAIT state.
+ */
+- if (smc->clcsock && smc->clcsock->sk)
+- rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR);
++ if (smc->clcsock && smc->clcsock->sk) {
++ rc1 = kernel_sock_shutdown(smc->clcsock,
++ SHUT_RDWR);
++ rc = rc ? rc : rc1;
++ }
+ } else {
+ /* peer event has changed the state */
+ goto again;
--- /dev/null
+From f8e7dfd6fdabb831846ab1970a875746559d491b Mon Sep 17 00:00:00 2001
+From: Vincent Whitchurch <vincent.whitchurch@axis.com>
+Date: Fri, 26 Nov 2021 16:51:15 +0100
+Subject: net: stmmac: Avoid DMA_CHAN_CONTROL write if no Split Header support
+
+From: Vincent Whitchurch <vincent.whitchurch@axis.com>
+
+commit f8e7dfd6fdabb831846ab1970a875746559d491b upstream.
+
+The driver assumes that split headers can be enabled/disabled without
+stopping/starting the device, so it writes DMA_CHAN_CONTROL from
+stmmac_set_features(). However, on my system (IP v5.10a without Split
+Header support), simply writing DMA_CHAN_CONTROL when DMA is running
+(for example, with the commands below) leads to a TX watchdog timeout.
+
+ host$ socat TCP-LISTEN:1024,fork,reuseaddr - &
+ device$ ethtool -K eth0 tso off
+ device$ ethtool -K eth0 tso on
+ device$ dd if=/dev/zero bs=1M count=10 | socat - TCP4:host:1024
+ <tx watchdog timeout>
+
+Note that since my IP is configured without Split Header support, the
+driver always just reads and writes the same value to the
+DMA_CHAN_CONTROL register.
+
+I don't have access to any platforms with Split Header support so I
+don't know if these writes to the DMA_CHAN_CONTROL while DMA is running
+actually work properly on such systems. I could not find anything in
+the databook that says that DMA_CHAN_CONTROL should not be written when
+the DMA is running.
+
+But on systems without Split Header support, there is in any case no
+need to call enable_sph() in stmmac_set_features() at all since SPH can
+never be toggled, so we can avoid the watchdog timeout there by skipping
+this call.
+
+Fixes: 8c6fc097a2f4acf ("net: stmmac: gmac4+: Add Split Header support")
+Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -5531,8 +5531,6 @@ static int stmmac_set_features(struct ne
+ netdev_features_t features)
+ {
+ struct stmmac_priv *priv = netdev_priv(netdev);
+- bool sph_en;
+- u32 chan;
+
+ /* Keep the COE Type in case of csum is supporting */
+ if (features & NETIF_F_RXCSUM)
+@@ -5544,10 +5542,13 @@ static int stmmac_set_features(struct ne
+ */
+ stmmac_rx_ipc(priv, priv->hw);
+
+- sph_en = (priv->hw->rx_csum > 0) && priv->sph;
++ if (priv->sph_cap) {
++ bool sph_en = (priv->hw->rx_csum > 0) && priv->sph;
++ u32 chan;
+
+- for (chan = 0; chan < priv->plat->rx_queues_to_use; chan++)
+- stmmac_enable_sph(priv, priv->ioaddr, sph_en, chan);
++ for (chan = 0; chan < priv->plat->rx_queues_to_use; chan++)
++ stmmac_enable_sph(priv, priv->ioaddr, sph_en, chan);
++ }
+
+ return 0;
+ }
--- /dev/null
+From 817b653160db9852d5a0498a31f047e18ce27e5b Mon Sep 17 00:00:00 2001
+From: Sven Schuchmann <schuchmann@schleissheimer.de>
+Date: Sat, 27 Nov 2021 11:47:07 +0100
+Subject: net: usb: lan78xx: lan78xx_phy_init(): use PHY_POLL instead of "0" if no IRQ is available
+
+From: Sven Schuchmann <schuchmann@schleissheimer.de>
+
+commit 817b653160db9852d5a0498a31f047e18ce27e5b upstream.
+
+On most systems request for IRQ 0 will fail, phylib will print an error message
+and fall back to polling. To fix this set the phydev->irq to PHY_POLL if no IRQ
+is available.
+
+Fixes: cc89c323a30e ("lan78xx: Use irq_domain for phy interrupt from USB Int. EP")
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Sven Schuchmann <schuchmann@schleissheimer.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/lan78xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -2228,7 +2228,7 @@ static int lan78xx_phy_init(struct lan78
+ if (dev->domain_data.phyirq > 0)
+ phydev->irq = dev->domain_data.phyirq;
+ else
+- phydev->irq = 0;
++ phydev->irq = PHY_POLL;
+ netdev_dbg(dev->net, "phydev->irq = %d\n", phydev->irq);
+
+ /* set to AUTOMDIX */
--- /dev/null
+From e07a097b4986afb8f925d0bb32612e1d3e88ce15 Mon Sep 17 00:00:00 2001
+From: Zhou Qingyang <zhou1615@umn.edu>
+Date: Wed, 1 Dec 2021 00:50:39 +0800
+Subject: octeontx2-af: Fix a memleak bug in rvu_mbox_init()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhou Qingyang <zhou1615@umn.edu>
+
+commit e07a097b4986afb8f925d0bb32612e1d3e88ce15 upstream.
+
+In rvu_mbox_init(), mbox_regions is not freed or passed out
+under the switch-default region, which could lead to a memory leak.
+
+Fix this bug by changing 'return err' to 'goto free_regions'.
+
+This bug was found by a static analyzer. The analysis employs
+differential checking to identify inconsistent security operations
+(e.g., checks or kfrees) between two code paths and confirms that the
+inconsistent operations are not recovered in the current function or
+the callers, so they constitute bugs.
+
+Note that, as a bug found by static analysis, it can be a false
+positive or hard to trigger. Multiple researchers have cross-reviewed
+the bug.
+
+Builds with CONFIG_OCTEONTX2_AF=y show no new warnings,
+and our static analyzer no longer warns about this code.
+
+Fixes: 98c561116360 (“octeontx2-af: cn10k: Add mbox support for CN10K platform”)
+Signed-off-by: Zhou Qingyang <zhou1615@umn.edu>
+Link: https://lore.kernel.org/r/20211130165039.192426-1-zhou1615@umn.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/rvu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+@@ -2281,7 +2281,7 @@ static int rvu_mbox_init(struct rvu *rvu
+ goto free_regions;
+ break;
+ default:
+- return err;
++ goto free_regions;
+ }
+
+ mw->mbox_wq = alloc_workqueue(name,
--- /dev/null
+From beacff50edbd6c9659a6f15fc7f6126909fade29 Mon Sep 17 00:00:00 2001
+From: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+Date: Sun, 21 Nov 2021 04:16:08 +0000
+Subject: rxrpc: Fix rxrpc_local leak in rxrpc_lookup_peer()
+
+From: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+
+commit beacff50edbd6c9659a6f15fc7f6126909fade29 upstream.
+
+Need to call rxrpc_put_local() for peer candidate before kfree() as it
+holds a ref to rxrpc_local.
+
+[DH: v2: Changed to abstract the peer freeing code out into a function]
+
+Fixes: 9ebeddef58c4 ("rxrpc: rxrpc_peer needs to hold a ref on the rxrpc_local record")
+Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Marc Dionne <marc.dionne@auristor.com>
+cc: linux-afs@lists.infradead.org
+Link: https://lore.kernel.org/all/20211121041608.133740-2-eiichi.tsukata@nutanix.com/ # v1
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/peer_object.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/net/rxrpc/peer_object.c
++++ b/net/rxrpc/peer_object.c
+@@ -299,6 +299,12 @@ static struct rxrpc_peer *rxrpc_create_p
+ return peer;
+ }
+
++static void rxrpc_free_peer(struct rxrpc_peer *peer)
++{
++ rxrpc_put_local(peer->local);
++ kfree_rcu(peer, rcu);
++}
++
+ /*
+ * Set up a new incoming peer. There shouldn't be any other matching peers
+ * since we've already done a search in the list from the non-reentrant context
+@@ -365,7 +371,7 @@ struct rxrpc_peer *rxrpc_lookup_peer(str
+ spin_unlock_bh(&rxnet->peer_hash_lock);
+
+ if (peer)
+- kfree(candidate);
++ rxrpc_free_peer(candidate);
+ else
+ peer = candidate;
+ }
+@@ -420,8 +426,7 @@ static void __rxrpc_put_peer(struct rxrp
+ list_del_init(&peer->keepalive_link);
+ spin_unlock_bh(&rxnet->peer_hash_lock);
+
+- rxrpc_put_local(peer->local);
+- kfree_rcu(peer, rcu);
++ rxrpc_free_peer(peer);
+ }
+
+ /*
+@@ -457,8 +462,7 @@ void rxrpc_put_peer_locked(struct rxrpc_
+ if (n == 0) {
+ hash_del_rcu(&peer->hash_link);
+ list_del_init(&peer->keepalive_link);
+- rxrpc_put_local(peer->local);
+- kfree_rcu(peer, rcu);
++ rxrpc_free_peer(peer);
+ }
+ }
+
--- /dev/null
+From ca77fba821351190777b236ce749d7c4d353102e Mon Sep 17 00:00:00 2001
+From: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+Date: Sun, 21 Nov 2021 04:16:07 +0000
+Subject: rxrpc: Fix rxrpc_peer leak in rxrpc_look_up_bundle()
+
+From: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+
+commit ca77fba821351190777b236ce749d7c4d353102e upstream.
+
+Need to call rxrpc_put_peer() for bundle candidate before kfree() as it
+holds a ref to rxrpc_peer.
+
+[DH: v2: Changed to abstract out the bundle freeing code into a function]
+
+Fixes: 245500d853e9 ("rxrpc: Rewrite the client connection manager")
+Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Marc Dionne <marc.dionne@auristor.com>
+cc: linux-afs@lists.infradead.org
+Link: https://lore.kernel.org/r/20211121041608.133740-1-eiichi.tsukata@nutanix.com/ # v1
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/conn_client.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/net/rxrpc/conn_client.c
++++ b/net/rxrpc/conn_client.c
+@@ -135,16 +135,20 @@ struct rxrpc_bundle *rxrpc_get_bundle(st
+ return bundle;
+ }
+
++static void rxrpc_free_bundle(struct rxrpc_bundle *bundle)
++{
++ rxrpc_put_peer(bundle->params.peer);
++ kfree(bundle);
++}
++
+ void rxrpc_put_bundle(struct rxrpc_bundle *bundle)
+ {
+ unsigned int d = bundle->debug_id;
+ unsigned int u = atomic_dec_return(&bundle->usage);
+
+ _debug("PUT B=%x %u", d, u);
+- if (u == 0) {
+- rxrpc_put_peer(bundle->params.peer);
+- kfree(bundle);
+- }
++ if (u == 0)
++ rxrpc_free_bundle(bundle);
+ }
+
+ /*
+@@ -328,7 +332,7 @@ static struct rxrpc_bundle *rxrpc_look_u
+ return candidate;
+
+ found_bundle_free:
+- kfree(candidate);
++ rxrpc_free_bundle(candidate);
+ found_bundle:
+ rxrpc_get_bundle(bundle);
+ spin_unlock(&local->client_bundles_lock);
--- /dev/null
+From a05431b22be819d75db72ca3d44381d18a37b092 Mon Sep 17 00:00:00 2001
+From: Li Zhijian <lizhijian@cn.fujitsu.com>
+Date: Thu, 2 Dec 2021 10:28:41 +0800
+Subject: selftests: net: Correct case name
+
+From: Li Zhijian <lizhijian@cn.fujitsu.com>
+
+commit a05431b22be819d75db72ca3d44381d18a37b092 upstream.
+
+ipv6_addr_bind/ipv4_addr_bind are function names. Previously, bind test
+would not be run by default due to the wrong case names
+
+Fixes: 34d0302ab861 ("selftests: Add ipv6 address bind tests to fcnal-test")
+Fixes: 75b2b2b3db4c ("selftests: Add ipv4 address bind tests to fcnal-test")
+Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/net/fcnal-test.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/tools/testing/selftests/net/fcnal-test.sh
++++ b/tools/testing/selftests/net/fcnal-test.sh
+@@ -4002,8 +4002,8 @@ EOF
+ ################################################################################
+ # main
+
+-TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp ipv4_addr_bind ipv4_runtime ipv4_netfilter"
+-TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp ipv6_addr_bind ipv6_runtime ipv6_netfilter"
++TESTS_IPV4="ipv4_ping ipv4_tcp ipv4_udp ipv4_bind ipv4_runtime ipv4_netfilter"
++TESTS_IPV6="ipv6_ping ipv6_tcp ipv6_udp ipv6_bind ipv6_runtime ipv6_netfilter"
+ TESTS_OTHER="use_cases"
+
+ PAUSE_ON_FAIL=no
net-qlogic-qlcnic-fix-a-null-pointer-dereference-in-qlcnic_83xx_add_rings.patch
net-mpls-fix-notifications-when-deleting-a-device.patch
siphash-use-_unaligned-version-by-default.patch
+arm64-ftrace-add-missing-btis.patch
+iwlwifi-fix-warnings-produced-by-kernel-debug-options.patch
+net-mlx5e-ipsec-fix-software-parser-inner-l3-type-setting-in-case-of-encapsulation.patch
+net-mlx4_en-fix-an-use-after-free-bug-in-mlx4_en_try_alloc_resources.patch
+selftests-net-correct-case-name.patch
+net-dsa-b53-add-spi-id-table.patch
+mt76-mt7915-fix-null-pointer-dereference-in-mt7915_get_phy_mode.patch
+asoc-tegra-fix-wrong-value-type-in-admaif.patch
+asoc-tegra-fix-wrong-value-type-in-i2s.patch
+asoc-tegra-fix-wrong-value-type-in-dmic.patch
+asoc-tegra-fix-wrong-value-type-in-dspk.patch
+asoc-tegra-fix-kcontrol-put-callback-in-admaif.patch
+asoc-tegra-fix-kcontrol-put-callback-in-i2s.patch
+asoc-tegra-fix-kcontrol-put-callback-in-dmic.patch
+asoc-tegra-fix-kcontrol-put-callback-in-dspk.patch
+asoc-tegra-fix-kcontrol-put-callback-in-ahub.patch
+rxrpc-fix-rxrpc_peer-leak-in-rxrpc_look_up_bundle.patch
+rxrpc-fix-rxrpc_local-leak-in-rxrpc_lookup_peer.patch
+alsa-intel-dsp-config-add-quirk-for-cml-devices-based-on-es8336-codec.patch
+net-stmmac-avoid-dma_chan_control-write-if-no-split-header-support.patch
+net-usb-lan78xx-lan78xx_phy_init-use-phy_poll-instead-of-0-if-no-irq-is-available.patch
+net-marvell-mvpp2-fix-the-computation-of-shared-cpus.patch
+dpaa2-eth-destroy-workqueue-at-the-end-of-remove-function.patch
+octeontx2-af-fix-a-memleak-bug-in-rvu_mbox_init.patch
+net-annotate-data-races-on-txq-xmit_lock_owner.patch
+ipv4-convert-fib_num_tclassid_users-to-atomic_t.patch
+net-smc-fix-wrong-list_del-in-smc_lgr_cleanup_early.patch
+net-rds-correct-socket-tunable-error-in-rds_tcp_tune.patch
+net-smc-keep-smc_close_final-rc-during-active-close.patch
+drm-msm-a6xx-allocate-enough-space-for-gmu-registers.patch
+drm-msm-do-hw_init-before-capturing-gpu-state.patch
+drm-vc4-kms-wait-for-the-commit-before-increasing-our-clock-rate.patch
+drm-vc4-kms-fix-return-code-check.patch
+drm-vc4-kms-add-missing-drm_crtc_commit_put.patch
+drm-vc4-kms-clear-the-hvs-fifo-commit-pointer-once-done.patch
+drm-vc4-kms-don-t-duplicate-pending-commit.patch
+drm-vc4-kms-fix-previous-hvs-commit-wait.patch