--- /dev/null
+From a523ef731ac6674dc07574f31bf44cc5bfa14e4d Mon Sep 17 00:00:00 2001
+From: Lukasz Majczak <lma@semihalf.com>
+Date: Thu, 15 Apr 2021 14:43:47 +0200
+Subject: ASoC: Intel: kbl_da7219_max98927: Fix kabylake_ssp_fixup function
+
+From: Lukasz Majczak <lma@semihalf.com>
+
+commit a523ef731ac6674dc07574f31bf44cc5bfa14e4d upstream.
+
+kabylake_ssp_fixup function uses snd_soc_dpcm to identify the
+codecs DAIs. The HW parameters are changed based on the codec DAI of the
+stream. The earlier approach to get snd_soc_dpcm was using container_of()
+macro on snd_pcm_hw_params.
+
+The structures have been modified over time and snd_soc_dpcm does not have
+snd_pcm_hw_params as a reference but as a copy. This causes the current
+driver to crash when used.
+
+This patch changes the way snd_soc_dpcm is extracted. snd_soc_pcm_runtime
+holds 2 dpcm instances (one for playback and one for capture). 2 codecs
+on the SSP are dmic (capture) and speakers (playback). Based on the
+stream direction, snd_soc_dpcm is extracted from snd_soc_pcm_runtime.
+
+Tested for all use cases of the driver.
+Based on similar fix in kbl_rt5663_rt5514_max98927.c
+from Harsha Priya <harshapriya.n@intel.com> and
+Vamshi Krishna Gopal <vamshi.krishna.gopal@intel.com>
+
+Cc: <stable@vger.kernel.org> # 5.4+
+Signed-off-by: Lukasz Majczak <lma@semihalf.com>
+Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210415124347.475432-1-lma@semihalf.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/intel/boards/kbl_da7219_max98927.c | 38 +++++++++++++++++++++------
+ 1 file changed, 30 insertions(+), 8 deletions(-)
+
+--- a/sound/soc/intel/boards/kbl_da7219_max98927.c
++++ b/sound/soc/intel/boards/kbl_da7219_max98927.c
+@@ -282,12 +282,34 @@ static int kabylake_ssp_fixup(struct snd
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+ struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+- struct snd_soc_dpcm *dpcm = container_of(
+- params, struct snd_soc_dpcm, hw_params);
+- struct snd_soc_dai_link *fe_dai_link = dpcm->fe->dai_link;
+- struct snd_soc_dai_link *be_dai_link = dpcm->be->dai_link;
++ struct snd_soc_dpcm *dpcm, *rtd_dpcm = NULL;
+
+ /*
++ * The following loop will be called only for playback stream
++ * In this platform, there is only one playback device on every SSP
++ */
++ for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_PLAYBACK, dpcm) {
++ rtd_dpcm = dpcm;
++ break;
++ }
++
++ /*
++ * This following loop will be called only for capture stream
++ * In this platform, there is only one capture device on every SSP
++ */
++ for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_CAPTURE, dpcm) {
++ rtd_dpcm = dpcm;
++ break;
++ }
++
++ if (!rtd_dpcm)
++ return -EINVAL;
++
++ /*
++ * The above 2 loops are mutually exclusive based on the stream direction,
++ * thus rtd_dpcm variable will never be overwritten
++ */
++ /*
+ * Topology for kblda7219m98373 & kblmax98373 supports only S24_LE,
+ * where as kblda7219m98927 & kblmax98927 supports S16_LE by default.
+ * Skipping the port wise FE and BE configuration for kblda7219m98373 &
+@@ -309,9 +331,9 @@ static int kabylake_ssp_fixup(struct snd
+ /*
+ * The ADSP will convert the FE rate to 48k, stereo, 24 bit
+ */
+- if (!strcmp(fe_dai_link->name, "Kbl Audio Port") ||
+- !strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") ||
+- !strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) {
++ if (!strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Port") ||
++ !strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Headset Playback") ||
++ !strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Capture Port")) {
+ rate->min = rate->max = 48000;
+ channels->min = channels->max = 2;
+ snd_mask_none(fmt);
+@@ -322,7 +344,7 @@ static int kabylake_ssp_fixup(struct snd
+ * The speaker on the SSP0 supports S16_LE and not S24_LE.
+ * thus changing the mask here
+ */
+- if (!strcmp(be_dai_link->name, "SSP0-Codec"))
++ if (!strcmp(rtd_dpcm->be->dai_link->name, "SSP0-Codec"))
+ snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
+
+ return 0;
--- /dev/null
+From d58970da324732686529655c21791cef0ee547c4 Mon Sep 17 00:00:00 2001
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Date: Fri, 12 Mar 2021 12:02:30 -0600
+Subject: ASoC: samsung: tm2_wm5110: check of of_parse return value
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+commit d58970da324732686529655c21791cef0ee547c4 upstream.
+
+cppcheck warning:
+
+sound/soc/samsung/tm2_wm5110.c:605:6: style: Variable 'ret' is
+reassigned a value before the old one has been
+used. [redundantAssignment]
+ ret = devm_snd_soc_register_component(dev, &tm2_component,
+ ^
+sound/soc/samsung/tm2_wm5110.c:554:7: note: ret is assigned
+ ret = of_parse_phandle_with_args(dev->of_node, "i2s-controller",
+ ^
+sound/soc/samsung/tm2_wm5110.c:605:6: note: ret is overwritten
+ ret = devm_snd_soc_register_component(dev, &tm2_component,
+ ^
+
+The args is a stack variable, so it could have junk (uninitialized)
+therefore args.np could have a non-NULL and random value even though
+property was missing. Later could trigger invalid pointer dereference.
+
+There's no need to check for args.np because args.np won't be
+initialized on errors.
+
+Fixes: 8d1513cef51a ("ASoC: samsung: Add support for HDMI audio on TM2 board")
+Cc: <stable@vger.kernel.org>
+Suggested-by: Krzysztof Kozlowski <krzk@kernel.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210312180231.2741-2-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/samsung/tm2_wm5110.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/samsung/tm2_wm5110.c
++++ b/sound/soc/samsung/tm2_wm5110.c
+@@ -553,7 +553,7 @@ static int tm2_probe(struct platform_dev
+
+ ret = of_parse_phandle_with_args(dev->of_node, "i2s-controller",
+ cells_name, i, &args);
+- if (!args.np) {
++ if (ret) {
+ dev_err(dev, "i2s-controller property parse error: %d\n", i);
+ ret = -EINVAL;
+ goto dai_node_put;
--- /dev/null
+From f626ca682912fab55dff15469ce893ae16b65c7e Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@orcam.me.uk>
+Date: Wed, 10 Mar 2021 13:03:09 +0100
+Subject: FDDI: defxx: Bail out gracefully with unassigned PCI resource for CSR
+
+From: Maciej W. Rozycki <macro@orcam.me.uk>
+
+commit f626ca682912fab55dff15469ce893ae16b65c7e upstream.
+
+Recent versions of the PCI Express specification have deprecated support
+for I/O transactions and actually some PCIe host bridges, such as Power
+Systems Host Bridge 4 (PHB4), do not implement them.
+
+For those systems the PCI BARs that request a mapping in the I/O space
+have the length recorded in the corresponding PCI resource set to zero,
+which makes it unassigned:
+
+# lspci -s 0031:02:04.0 -v
+0031:02:04.0 FDDI network controller: Digital Equipment Corporation PCI-to-PDQ Interface Chip [PFI] FDDI (DEFPA) (rev 02)
+ Subsystem: Digital Equipment Corporation FDDIcontroller/PCI (DEFPA)
+ Flags: bus master, medium devsel, latency 136, IRQ 57, NUMA node 8
+ Memory at 620c080020000 (32-bit, non-prefetchable) [size=128]
+ I/O ports at <unassigned> [disabled]
+ Memory at 620c080030000 (32-bit, non-prefetchable) [size=64K]
+ Capabilities: [50] Power Management version 2
+ Kernel driver in use: defxx
+ Kernel modules: defxx
+
+#
+
+Regardless the driver goes ahead and requests it (here observed with a
+Raptor Talos II POWER9 system), resulting in an odd /proc/ioport entry:
+
+# cat /proc/ioports
+00000000-ffffffffffffffff : 0031:02:04.0
+#
+
+Furthermore, the system gets confused as the driver actually continues
+and pokes at those locations, causing a flood of messages being output
+to the system console by the underlying system firmware, like:
+
+defxx: v1.11 2014/07/01 Lawrence V. Stefani and others
+defxx 0031:02:04.0: enabling device (0140 -> 0142)
+LPC[000]: Got SYNC no-response error. Error address reg: 0xd0010000
+IPMI: dropping non severe PEL event
+LPC[000]: Got SYNC no-response error. Error address reg: 0xd0010014
+IPMI: dropping non severe PEL event
+LPC[000]: Got SYNC no-response error. Error address reg: 0xd0010014
+IPMI: dropping non severe PEL event
+
+and so on and so on (possibly intermixed actually, as there's no locking
+between the kernel and the firmware in console port access with this
+particular system, but cleaned up above for clarity), and once some 10k
+of such pairs of the latter two messages have been produced an interace
+eventually shows up in a useless state:
+
+0031:02:04.0: DEFPA at I/O addr = 0x0, IRQ = 57, Hardware addr = 00-00-00-00-00-00
+
+This was not expected to happen as resource handling was added to the
+driver a while ago, because it was not known at that time that a PCI
+system would be possible that cannot assign port I/O resources, and
+oddly enough `request_region' does not fail, which would have caught it.
+
+Correct the problem then by checking for the length of zero for the CSR
+resource and bail out gracefully refusing to register an interface if
+that turns out to be the case, producing messages like:
+
+defxx: v1.11 2014/07/01 Lawrence V. Stefani and others
+0031:02:04.0: Cannot use I/O, no address set, aborting
+0031:02:04.0: Recompile driver with "CONFIG_DEFXX_MMIO=y"
+
+Keep the original check for the EISA MMIO resource as implemented,
+because in that case the length is hardwired to 0x400 as a consequence
+of how the compare/mask address decoding works in the ESIC chip and it
+is only the base address that is set to zero if MMIO has been disabled
+for the adapter in EISA configuration, which in turn could be a valid
+bus address in a legacy-free system implementing PCI, especially for
+port I/O.
+
+Where the EISA MMIO resource has been disabled for the adapter in EISA
+configuration this arrangement keeps producing messages like:
+
+eisa 00:05: EISA: slot 5: DEC3002 detected
+defxx: v1.11 2014/07/01 Lawrence V. Stefani and others
+00:05: Cannot use MMIO, no address set, aborting
+00:05: Recompile driver with "CONFIG_DEFXX_MMIO=n"
+00:05: Or run ECU and set adapter's MMIO location
+
+with the last two lines now swapped for easier handling in the driver.
+
+There is no need to check for and catch the case of a port I/O resource
+not having been assigned for EISA as the adapter uses the slot-specific
+I/O space, which gets assigned by how EISA has been specified and maps
+directly to the particular slot an option card has been placed in. And
+the EISA variant of the adapter has additional registers that are only
+accessible via the port I/O space anyway.
+
+While at it factor out the error message calls into helpers and fix an
+argument order bug with the `pr_err' call now in `dfx_register_res_err'.
+
+Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Fixes: 4d0438e56a8f ("defxx: Clean up DEFEA resource management")
+Cc: stable@vger.kernel.org # v3.19+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/fddi/defxx.c | 47 ++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 30 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/fddi/defxx.c
++++ b/drivers/net/fddi/defxx.c
+@@ -495,6 +495,25 @@ static const struct net_device_ops dfx_n
+ .ndo_set_mac_address = dfx_ctl_set_mac_address,
+ };
+
++static void dfx_register_res_alloc_err(const char *print_name, bool mmio,
++ bool eisa)
++{
++ pr_err("%s: Cannot use %s, no address set, aborting\n",
++ print_name, mmio ? "MMIO" : "I/O");
++ pr_err("%s: Recompile driver with \"CONFIG_DEFXX_MMIO=%c\"\n",
++ print_name, mmio ? 'n' : 'y');
++ if (eisa && mmio)
++ pr_err("%s: Or run ECU and set adapter's MMIO location\n",
++ print_name);
++}
++
++static void dfx_register_res_err(const char *print_name, bool mmio,
++ unsigned long start, unsigned long len)
++{
++ pr_err("%s: Cannot reserve %s resource 0x%lx @ 0x%lx, aborting\n",
++ print_name, mmio ? "MMIO" : "I/O", len, start);
++}
++
+ /*
+ * ================
+ * = dfx_register =
+@@ -568,15 +587,12 @@ static int dfx_register(struct device *b
+ dev_set_drvdata(bdev, dev);
+
+ dfx_get_bars(bdev, bar_start, bar_len);
+- if (dfx_bus_eisa && dfx_use_mmio && bar_start[0] == 0) {
+- pr_err("%s: Cannot use MMIO, no address set, aborting\n",
+- print_name);
+- pr_err("%s: Run ECU and set adapter's MMIO location\n",
+- print_name);
+- pr_err("%s: Or recompile driver with \"CONFIG_DEFXX_MMIO=n\""
+- "\n", print_name);
++ if (bar_len[0] == 0 ||
++ (dfx_bus_eisa && dfx_use_mmio && bar_start[0] == 0)) {
++ dfx_register_res_alloc_err(print_name, dfx_use_mmio,
++ dfx_bus_eisa);
+ err = -ENXIO;
+- goto err_out;
++ goto err_out_disable;
+ }
+
+ if (dfx_use_mmio)
+@@ -585,18 +601,16 @@ static int dfx_register(struct device *b
+ else
+ region = request_region(bar_start[0], bar_len[0], print_name);
+ if (!region) {
+- pr_err("%s: Cannot reserve %s resource 0x%lx @ 0x%lx, "
+- "aborting\n", dfx_use_mmio ? "MMIO" : "I/O", print_name,
+- (long)bar_len[0], (long)bar_start[0]);
++ dfx_register_res_err(print_name, dfx_use_mmio,
++ bar_start[0], bar_len[0]);
+ err = -EBUSY;
+ goto err_out_disable;
+ }
+ if (bar_start[1] != 0) {
+ region = request_region(bar_start[1], bar_len[1], print_name);
+ if (!region) {
+- pr_err("%s: Cannot reserve I/O resource "
+- "0x%lx @ 0x%lx, aborting\n", print_name,
+- (long)bar_len[1], (long)bar_start[1]);
++ dfx_register_res_err(print_name, 0,
++ bar_start[1], bar_len[1]);
+ err = -EBUSY;
+ goto err_out_csr_region;
+ }
+@@ -604,9 +618,8 @@ static int dfx_register(struct device *b
+ if (bar_start[2] != 0) {
+ region = request_region(bar_start[2], bar_len[2], print_name);
+ if (!region) {
+- pr_err("%s: Cannot reserve I/O resource "
+- "0x%lx @ 0x%lx, aborting\n", print_name,
+- (long)bar_len[2], (long)bar_start[2]);
++ dfx_register_res_err(print_name, 0,
++ bar_start[2], bar_len[2]);
+ err = -EBUSY;
+ goto err_out_bh_region;
+ }
--- /dev/null
+From 4e102429f3dc62dce546f6107e34a4284634196d Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Sun, 21 Mar 2021 18:29:56 +0000
+Subject: iio:accel:adis16201: Fix wrong axis assignment that prevents loading
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit 4e102429f3dc62dce546f6107e34a4284634196d upstream.
+
+Whilst running some basic tests as part of writing up the dt-bindings for
+this driver (to follow), it became clear it doesn't actually load
+currently.
+
+iio iio:device1: tried to double register : in_incli_x_index
+adis16201 spi0.0: Failed to create buffer sysfs interfaces
+adis16201: probe of spi0.0 failed with error -16
+
+Looks like a cut and paste / update bug. Fixes tag obviously not accurate
+but we don't want to bother carry thing back to before the driver moved
+out of staging.
+
+Fixes: 591298e54cea ("Staging: iio: accel: adis16201: Move adis16201 driver out of staging")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: <Stable@vger.kernel.org>
+Cc: Himanshu Jha <himanshujha199640@gmail.com>
+Cc: Nuno Sá <nuno.sa@analog.com>
+Reviewed-by: Alexandru Ardelean <ardeleanalex@gmail.com>
+Link: https://lore.kernel.org/r/20210321182956.844652-1-jic23@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/accel/adis16201.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/accel/adis16201.c
++++ b/drivers/iio/accel/adis16201.c
+@@ -215,7 +215,7 @@ static const struct iio_chan_spec adis16
+ ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC_REG, ADIS16201_SCAN_AUX_ADC, 0, 12),
+ ADIS_INCLI_CHAN(X, ADIS16201_XINCL_OUT_REG, ADIS16201_SCAN_INCLI_X,
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
+- ADIS_INCLI_CHAN(X, ADIS16201_YINCL_OUT_REG, ADIS16201_SCAN_INCLI_Y,
++ ADIS_INCLI_CHAN(Y, ADIS16201_YINCL_OUT_REG, ADIS16201_SCAN_INCLI_Y,
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
+ IIO_CHAN_SOFT_TIMESTAMP(7)
+ };
--- /dev/null
+From 404a8ef512587b2460107d3272c17a89aef75edf Mon Sep 17 00:00:00 2001
+From: Sudhakar Panneerselvam <sudhakar.panneerselvam@oracle.com>
+Date: Tue, 13 Apr 2021 04:08:29 +0000
+Subject: md/bitmap: wait for external bitmap writes to complete during tear down
+
+From: Sudhakar Panneerselvam <sudhakar.panneerselvam@oracle.com>
+
+commit 404a8ef512587b2460107d3272c17a89aef75edf upstream.
+
+NULL pointer dereference was observed in super_written() when it tries
+to access the mddev structure.
+
+[The below stack trace is from an older kernel, but the problem described
+in this patch applies to the mainline kernel.]
+
+[ 1194.474861] task: ffff8fdd20858000 task.stack: ffffb99d40790000
+[ 1194.488000] RIP: 0010:super_written+0x29/0xe1
+[ 1194.499688] RSP: 0018:ffff8ffb7fcc3c78 EFLAGS: 00010046
+[ 1194.512477] RAX: 0000000000000000 RBX: ffff8ffb7bf4a000 RCX: ffff8ffb78991048
+[ 1194.527325] RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff8ffb56b8a200
+[ 1194.542576] RBP: ffff8ffb7fcc3c90 R08: 000000000000000b R09: 0000000000000000
+[ 1194.558001] R10: ffff8ffb56b8a298 R11: 0000000000000000 R12: ffff8ffb56b8a200
+[ 1194.573070] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
+[ 1194.588117] FS: 0000000000000000(0000) GS:ffff8ffb7fcc0000(0000) knlGS:0000000000000000
+[ 1194.604264] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 1194.617375] CR2: 00000000000002b8 CR3: 00000021e040a002 CR4: 00000000007606e0
+[ 1194.632327] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 1194.647865] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[ 1194.663316] PKRU: 55555554
+[ 1194.674090] Call Trace:
+[ 1194.683735] <IRQ>
+[ 1194.692948] bio_endio+0xae/0x135
+[ 1194.703580] blk_update_request+0xad/0x2fa
+[ 1194.714990] blk_update_bidi_request+0x20/0x72
+[ 1194.726578] __blk_end_bidi_request+0x2c/0x4d
+[ 1194.738373] __blk_end_request_all+0x31/0x49
+[ 1194.749344] blk_flush_complete_seq+0x377/0x383
+[ 1194.761550] flush_end_io+0x1dd/0x2a7
+[ 1194.772910] blk_finish_request+0x9f/0x13c
+[ 1194.784544] scsi_end_request+0x180/0x25c
+[ 1194.796149] scsi_io_completion+0xc8/0x610
+[ 1194.807503] scsi_finish_command+0xdc/0x125
+[ 1194.818897] scsi_softirq_done+0x81/0xde
+[ 1194.830062] blk_done_softirq+0xa4/0xcc
+[ 1194.841008] __do_softirq+0xd9/0x29f
+[ 1194.851257] irq_exit+0xe6/0xeb
+[ 1194.861290] do_IRQ+0x59/0xe3
+[ 1194.871060] common_interrupt+0x1c6/0x382
+[ 1194.881988] </IRQ>
+[ 1194.890646] RIP: 0010:cpuidle_enter_state+0xdd/0x2a5
+[ 1194.902532] RSP: 0018:ffffb99d40793e68 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff43
+[ 1194.917317] RAX: ffff8ffb7fce27c0 RBX: ffff8ffb7fced800 RCX: 000000000000001f
+[ 1194.932056] RDX: 0000000000000000 RSI: 0000000000000004 RDI: 0000000000000000
+[ 1194.946428] RBP: ffffb99d40793ea0 R08: 0000000000000004 R09: 0000000000002ed2
+[ 1194.960508] R10: 0000000000002664 R11: 0000000000000018 R12: 0000000000000003
+[ 1194.974454] R13: 000000000000000b R14: ffffffff925715a0 R15: 0000011610120d5a
+[ 1194.988607] ? cpuidle_enter_state+0xcc/0x2a5
+[ 1194.999077] cpuidle_enter+0x17/0x19
+[ 1195.008395] call_cpuidle+0x23/0x3a
+[ 1195.017718] do_idle+0x172/0x1d5
+[ 1195.026358] cpu_startup_entry+0x73/0x75
+[ 1195.035769] start_secondary+0x1b9/0x20b
+[ 1195.044894] secondary_startup_64+0xa5/0xa5
+[ 1195.084921] RIP: super_written+0x29/0xe1 RSP: ffff8ffb7fcc3c78
+[ 1195.096354] CR2: 00000000000002b8
+
+bio in the above stack is a bitmap write whose completion is invoked after
+the tear down sequence sets the mddev structure to NULL in rdev.
+
+During tear down, there is an attempt to flush the bitmap writes, but for
+external bitmaps, there is no explicit wait for all the bitmap writes to
+complete. For instance, md_bitmap_flush() is called to flush the bitmap
+writes, but the last call to md_bitmap_daemon_work() in md_bitmap_flush()
+could generate new bitmap writes for which there is no explicit wait to
+complete those writes. The call to md_bitmap_update_sb() will return
+simply for external bitmaps and the follow-up call to md_update_sb() is
+conditional and may not get called for external bitmaps. This results in a
+kernel panic when the completion routine, super_written() is called which
+tries to reference mddev in the rdev that has been set to
+NULL(in unbind_rdev_from_array() by tear down sequence).
+
+The solution is to call md_super_wait() for external bitmaps after the
+last call to md_bitmap_daemon_work() in md_bitmap_flush() to ensure there
+are no pending bitmap writes before proceeding with the tear down.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Sudhakar Panneerselvam <sudhakar.panneerselvam@oracle.com>
+Reviewed-by: Zhao Heming <heming.zhao@suse.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/md/md-bitmap.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -1726,6 +1726,8 @@ void md_bitmap_flush(struct mddev *mddev
+ md_bitmap_daemon_work(mddev);
+ bitmap->daemon_lastrun -= sleep;
+ md_bitmap_daemon_work(mddev);
++ if (mddev->bitmap_info.external)
++ md_super_wait(mddev);
+ md_bitmap_update_sb(bitmap);
+ }
+
--- /dev/null
+From c15b99ae2ba9ea30da3c7cd4765b8a4707e530a6 Mon Sep 17 00:00:00 2001
+From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
+Date: Sat, 6 Mar 2021 20:17:24 -0800
+Subject: MIPS: pci-mt7620: fix PLL lock check
+
+From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
+
+commit c15b99ae2ba9ea30da3c7cd4765b8a4707e530a6 upstream.
+
+Upstream a long-standing OpenWrt patch [0] that fixes MT7620 PCIe PLL
+lock check. The existing code checks the wrong register bit: PPLL_SW_SET
+is not defined in PPLL_CFG1 and bit 31 of PPLL_CFG1 is marked as reserved
+in the MT7620 Programming Guide. The correct bit to check for PLL lock
+is PPLL_LD (bit 23).
+
+Also reword the error message for clarity.
+
+Without this change it is unlikely that this driver ever worked with
+mainline kernel.
+
+[0]: https://lists.infradead.org/pipermail/lede-commits/2017-July/004441.html
+
+Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
+Cc: John Crispin <john@phrozen.org>
+Cc: linux-mips@vger.kernel.org
+Cc: linux-mediatek@lists.infradead.org
+Cc: linux-kernel@vger.kernel.org
+Cc: stable@vger.kernel.org
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/mips/pci/pci-mt7620.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/arch/mips/pci/pci-mt7620.c
++++ b/arch/mips/pci/pci-mt7620.c
+@@ -30,6 +30,7 @@
+ #define RALINK_GPIOMODE 0x60
+
+ #define PPLL_CFG1 0x9c
++#define PPLL_LD BIT(23)
+
+ #define PPLL_DRV 0xa0
+ #define PDRV_SW_SET BIT(31)
+@@ -239,8 +240,8 @@ static int mt7620_pci_hw_init(struct pla
+ rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
+ mdelay(100);
+
+- if (!(rt_sysc_r32(PPLL_CFG1) & PDRV_SW_SET)) {
+- dev_err(&pdev->dev, "MT7620 PPLL unlock\n");
++ if (!(rt_sysc_r32(PPLL_CFG1) & PPLL_LD)) {
++ dev_err(&pdev->dev, "pcie PLL not locked, aborting init\n");
+ reset_control_assert(rstpcie0);
+ rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+ return -1;
--- /dev/null
+From 8e98b697006d749d745d3b174168a877bb96c500 Mon Sep 17 00:00:00 2001
+From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
+Date: Tue, 13 Apr 2021 20:12:33 -0700
+Subject: MIPS: pci-rt2880: fix slot 0 configuration
+
+From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
+
+commit 8e98b697006d749d745d3b174168a877bb96c500 upstream.
+
+pci_fixup_irqs() used to call pcibios_map_irq on every PCI device, which
+for RT2880 included bus 0 slot 0. After pci_fixup_irqs() got removed,
+only slots/funcs with devices attached would be called. While arguably
+the right thing, that left no chance for this driver to ever initialize
+slot 0, effectively bricking PCI and USB on RT2880 devices such as the
+Belkin F5D8235-4 v1.
+
+Slot 0 configuration needs to happen after PCI bus enumeration, but
+before any device at slot 0x11 (func 0 or 1) is talked to. That was
+determined empirically by testing on a Belkin F5D8235-4 v1 device. A
+minimal BAR 0 config write followed by read, then setting slot 0
+PCI_COMMAND to MASTER | IO | MEMORY is all that seems to be required for
+proper functionality.
+
+Tested by ensuring that full- and high-speed USB devices get enumerated
+on the Belkin F5D8235-4 v1 (with an out of tree DTS file from OpenWrt).
+
+Fixes: 04c81c7293df ("MIPS: PCI: Replace pci_fixup_irqs() call with host bridge IRQ mapping hooks")
+Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
+Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Cc: Tobias Wolf <dev-NTEO@vplace.de>
+Cc: <stable@vger.kernel.org> # v4.14+
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/mips/pci/pci-rt2880.c | 37 ++++++++++++++++++++++++-------------
+ 1 file changed, 24 insertions(+), 13 deletions(-)
+
+--- a/arch/mips/pci/pci-rt2880.c
++++ b/arch/mips/pci/pci-rt2880.c
+@@ -180,7 +180,6 @@ static inline void rt2880_pci_write_u32(
+
+ int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+ {
+- u16 cmd;
+ int irq = -1;
+
+ if (dev->bus->number != 0)
+@@ -188,8 +187,6 @@ int pcibios_map_irq(const struct pci_dev
+
+ switch (PCI_SLOT(dev->devfn)) {
+ case 0x00:
+- rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
+- (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);
+ break;
+ case 0x11:
+ irq = RT288X_CPU_IRQ_PCI;
+@@ -201,16 +198,6 @@ int pcibios_map_irq(const struct pci_dev
+ break;
+ }
+
+- pci_write_config_byte((struct pci_dev *) dev,
+- PCI_CACHE_LINE_SIZE, 0x14);
+- pci_write_config_byte((struct pci_dev *) dev, PCI_LATENCY_TIMER, 0xFF);
+- pci_read_config_word((struct pci_dev *) dev, PCI_COMMAND, &cmd);
+- cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+- PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK |
+- PCI_COMMAND_SERR | PCI_COMMAND_WAIT | PCI_COMMAND_PARITY;
+- pci_write_config_word((struct pci_dev *) dev, PCI_COMMAND, cmd);
+- pci_write_config_byte((struct pci_dev *) dev, PCI_INTERRUPT_LINE,
+- dev->irq);
+ return irq;
+ }
+
+@@ -251,6 +238,30 @@ static int rt288x_pci_probe(struct platf
+
+ int pcibios_plat_dev_init(struct pci_dev *dev)
+ {
++ static bool slot0_init;
++
++ /*
++ * Nobody seems to initialize slot 0, but this platform requires it, so
++ * do it once when some other slot is being enabled. The PCI subsystem
++ * should configure other slots properly, so no need to do anything
++ * special for those.
++ */
++ if (!slot0_init && dev->bus->number == 0) {
++ u16 cmd;
++ u32 bar0;
++
++ slot0_init = true;
++
++ pci_bus_write_config_dword(dev->bus, 0, PCI_BASE_ADDRESS_0,
++ 0x08000000);
++ pci_bus_read_config_dword(dev->bus, 0, PCI_BASE_ADDRESS_0,
++ &bar0);
++
++ pci_bus_read_config_word(dev->bus, 0, PCI_COMMAND, &cmd);
++ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
++ pci_bus_write_config_word(dev->bus, 0, PCI_COMMAND, cmd);
++ }
++
+ return 0;
+ }
+
--- /dev/null
+From 3641762c1c9c7cfd84a7061a0a73054f09b412e3 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 17 Feb 2021 11:24:59 +0100
+Subject: misc: lis3lv02d: Fix false-positive WARN on various HP models
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 3641762c1c9c7cfd84a7061a0a73054f09b412e3 upstream.
+
+Before this commit lis3lv02d_get_pwron_wait() had a WARN_ONCE() to catch
+a potential divide by 0. WARN macros should only be used to catch internal
+kernel bugs and that is not the case here. We have been receiving a lot of
+bug reports about kernel backtraces caused by this WARN.
+
+The div value being checked comes from the lis3->odrs[] array. Which
+is sized to be a power-of-2 matching the number of bits in lis3->odr_mask.
+
+The only lis3 model where this array is not entirely filled with non zero
+values. IOW the only model where we can hit the div == 0 check is the
+3dc ("8 bits 3DC sensor") model:
+
+int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000};
+
+Note the 0 value at index 0, according to the datasheet an odr index of 0
+means "Power-down mode". HP typically uses a lis3 accelerometer for HDD
+fall protection. What I believe is happening here is that on newer
+HP devices, which only contain a SDD, the BIOS is leaving the lis3 device
+powered-down since it is not used for HDD fall protection.
+
+Note that the lis3_3dc_rates array initializer only specifies 10 values,
+which matches the datasheet. So it also contains 6 zero values at the end.
+
+Replace the WARN with a normal check, which treats an odr index of 0
+as power-down and uses a normal dev_err() to report the error in case
+odr index point past the initialized part of the array.
+
+Fixes: 1510dd5954be ("lis3lv02d: avoid divide by zero due to unchecked")
+Cc: stable@vger.kernel.org
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=785814
+BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1817027
+BugLink: https://bugs.centos.org/view.php?id=10720
+Link: https://lore.kernel.org/r/20210217102501.31758-1-hdegoede@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/misc/lis3lv02d/lis3lv02d.c | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+--- a/drivers/misc/lis3lv02d/lis3lv02d.c
++++ b/drivers/misc/lis3lv02d/lis3lv02d.c
+@@ -208,7 +208,7 @@ static int lis3_3dc_rates[16] = {0, 1, 1
+ static int lis3_3dlh_rates[4] = {50, 100, 400, 1000};
+
+ /* ODR is Output Data Rate */
+-static int lis3lv02d_get_odr(struct lis3lv02d *lis3)
++static int lis3lv02d_get_odr_index(struct lis3lv02d *lis3)
+ {
+ u8 ctrl;
+ int shift;
+@@ -216,15 +216,23 @@ static int lis3lv02d_get_odr(struct lis3
+ lis3->read(lis3, CTRL_REG1, &ctrl);
+ ctrl &= lis3->odr_mask;
+ shift = ffs(lis3->odr_mask) - 1;
+- return lis3->odrs[(ctrl >> shift)];
++ return (ctrl >> shift);
+ }
+
+ static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3)
+ {
+- int div = lis3lv02d_get_odr(lis3);
++ int odr_idx = lis3lv02d_get_odr_index(lis3);
++ int div = lis3->odrs[odr_idx];
+
+- if (WARN_ONCE(div == 0, "device returned spurious data"))
++ if (div == 0) {
++ if (odr_idx == 0) {
++ /* Power-down mode, not sampling no need to sleep */
++ return 0;
++ }
++
++ dev_err(&lis3->pdev->dev, "Error unknown odrs-index: %d\n", odr_idx);
+ return -ENXIO;
++ }
+
+ /* LIS3 power on delay is quite long */
+ msleep(lis3->pwron_delay / div);
+@@ -807,9 +815,12 @@ static ssize_t lis3lv02d_rate_show(struc
+ struct device_attribute *attr, char *buf)
+ {
+ struct lis3lv02d *lis3 = dev_get_drvdata(dev);
++ int odr_idx;
+
+ lis3lv02d_sysfs_poweron(lis3);
+- return sprintf(buf, "%d\n", lis3lv02d_get_odr(lis3));
++
++ odr_idx = lis3lv02d_get_odr_index(lis3);
++ return sprintf(buf, "%d\n", lis3->odrs[odr_idx]);
+ }
+
+ static ssize_t lis3lv02d_rate_set(struct device *dev,
--- /dev/null
+From b2192cfeba8481224da0a4ec3b4a7ccd80b1623b Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Fri, 2 Apr 2021 21:17:42 +0900
+Subject: misc: vmw_vmci: explicitly initialize vmci_datagram payload
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit b2192cfeba8481224da0a4ec3b4a7ccd80b1623b upstream.
+
+KMSAN complains that vmci_check_host_caps() left the payload part of
+check_msg uninitialized.
+
+ =====================================================
+ BUG: KMSAN: uninit-value in kmsan_check_memory+0xd/0x10
+ CPU: 1 PID: 1 Comm: swapper/0 Tainted: G B 5.11.0-rc7+ #4
+ Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 02/27/2020
+ Call Trace:
+ dump_stack+0x21c/0x280
+ kmsan_report+0xfb/0x1e0
+ kmsan_internal_check_memory+0x202/0x520
+ kmsan_check_memory+0xd/0x10
+ iowrite8_rep+0x86/0x380
+ vmci_guest_probe_device+0xf0b/0x1e70
+ pci_device_probe+0xab3/0xe70
+ really_probe+0xd16/0x24d0
+ driver_probe_device+0x29d/0x3a0
+ device_driver_attach+0x25a/0x490
+ __driver_attach+0x78c/0x840
+ bus_for_each_dev+0x210/0x340
+ driver_attach+0x89/0xb0
+ bus_add_driver+0x677/0xc40
+ driver_register+0x485/0x8e0
+ __pci_register_driver+0x1ff/0x350
+ vmci_guest_init+0x3e/0x41
+ vmci_drv_init+0x1d6/0x43f
+ do_one_initcall+0x39c/0x9a0
+ do_initcall_level+0x1d7/0x259
+ do_initcalls+0x127/0x1cb
+ do_basic_setup+0x33/0x36
+ kernel_init_freeable+0x29a/0x3ed
+ kernel_init+0x1f/0x840
+ ret_from_fork+0x1f/0x30
+
+ Uninit was created at:
+ kmsan_internal_poison_shadow+0x5c/0xf0
+ kmsan_slab_alloc+0x8d/0xe0
+ kmem_cache_alloc+0x84f/0xe30
+ vmci_guest_probe_device+0xd11/0x1e70
+ pci_device_probe+0xab3/0xe70
+ really_probe+0xd16/0x24d0
+ driver_probe_device+0x29d/0x3a0
+ device_driver_attach+0x25a/0x490
+ __driver_attach+0x78c/0x840
+ bus_for_each_dev+0x210/0x340
+ driver_attach+0x89/0xb0
+ bus_add_driver+0x677/0xc40
+ driver_register+0x485/0x8e0
+ __pci_register_driver+0x1ff/0x350
+ vmci_guest_init+0x3e/0x41
+ vmci_drv_init+0x1d6/0x43f
+ do_one_initcall+0x39c/0x9a0
+ do_initcall_level+0x1d7/0x259
+ do_initcalls+0x127/0x1cb
+ do_basic_setup+0x33/0x36
+ kernel_init_freeable+0x29a/0x3ed
+ kernel_init+0x1f/0x840
+ ret_from_fork+0x1f/0x30
+
+ Bytes 28-31 of 36 are uninitialized
+ Memory access of size 36 starts at ffff8881675e5f00
+ =====================================================
+
+Fixes: 1f166439917b69d3 ("VMCI: guest side driver implementation.")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Link: https://lore.kernel.org/r/20210402121742.3917-2-penguin-kernel@I-love.SAKURA.ne.jp
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/misc/vmw_vmci/vmci_guest.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/misc/vmw_vmci/vmci_guest.c
++++ b/drivers/misc/vmw_vmci/vmci_guest.c
+@@ -168,7 +168,7 @@ static int vmci_check_host_caps(struct p
+ VMCI_UTIL_NUM_RESOURCES * sizeof(u32);
+ struct vmci_datagram *check_msg;
+
+- check_msg = kmalloc(msg_size, GFP_KERNEL);
++ check_msg = kzalloc(msg_size, GFP_KERNEL);
+ if (!check_msg) {
+ dev_err(&pdev->dev, "%s: Insufficient memory\n", __func__);
+ return -ENOMEM;
--- /dev/null
+From 376565b9717c30cd58ad33860fa42697615fa2e4 Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Fri, 2 Apr 2021 21:17:41 +0900
+Subject: misc: vmw_vmci: explicitly initialize vmci_notify_bm_set_msg struct
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit 376565b9717c30cd58ad33860fa42697615fa2e4 upstream.
+
+KMSAN complains that the vmci_use_ppn64() == false path in
+vmci_dbell_register_notification_bitmap() left upper 32bits of
+bitmap_set_msg.bitmap_ppn64 member uninitialized.
+
+ =====================================================
+ BUG: KMSAN: uninit-value in kmsan_check_memory+0xd/0x10
+ CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.11.0-rc7+ #4
+ Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 02/27/2020
+ Call Trace:
+ dump_stack+0x21c/0x280
+ kmsan_report+0xfb/0x1e0
+ kmsan_internal_check_memory+0x484/0x520
+ kmsan_check_memory+0xd/0x10
+ iowrite8_rep+0x86/0x380
+ vmci_send_datagram+0x150/0x280
+ vmci_dbell_register_notification_bitmap+0x133/0x1e0
+ vmci_guest_probe_device+0xcab/0x1e70
+ pci_device_probe+0xab3/0xe70
+ really_probe+0xd16/0x24d0
+ driver_probe_device+0x29d/0x3a0
+ device_driver_attach+0x25a/0x490
+ __driver_attach+0x78c/0x840
+ bus_for_each_dev+0x210/0x340
+ driver_attach+0x89/0xb0
+ bus_add_driver+0x677/0xc40
+ driver_register+0x485/0x8e0
+ __pci_register_driver+0x1ff/0x350
+ vmci_guest_init+0x3e/0x41
+ vmci_drv_init+0x1d6/0x43f
+ do_one_initcall+0x39c/0x9a0
+ do_initcall_level+0x1d7/0x259
+ do_initcalls+0x127/0x1cb
+ do_basic_setup+0x33/0x36
+ kernel_init_freeable+0x29a/0x3ed
+ kernel_init+0x1f/0x840
+ ret_from_fork+0x1f/0x30
+
+ Local variable ----bitmap_set_msg@vmci_dbell_register_notification_bitmap created at:
+ vmci_dbell_register_notification_bitmap+0x50/0x1e0
+ vmci_dbell_register_notification_bitmap+0x50/0x1e0
+
+ Bytes 28-31 of 32 are uninitialized
+ Memory access of size 32 starts at ffff88810098f570
+ =====================================================
+
+Fixes: 83e2ec765be03e8a ("VMCI: doorbell implementation.")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Link: https://lore.kernel.org/r/20210402121742.3917-1-penguin-kernel@I-love.SAKURA.ne.jp
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/misc/vmw_vmci/vmci_doorbell.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/misc/vmw_vmci/vmci_doorbell.c
++++ b/drivers/misc/vmw_vmci/vmci_doorbell.c
+@@ -326,7 +326,7 @@ int vmci_dbell_host_context_notify(u32 s
+ bool vmci_dbell_register_notification_bitmap(u64 bitmap_ppn)
+ {
+ int result;
+- struct vmci_notify_bm_set_msg bitmap_set_msg;
++ struct vmci_notify_bm_set_msg bitmap_set_msg = { };
+
+ bitmap_set_msg.hdr.dst = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID,
+ VMCI_SET_NOTIFY_BITMAP);
--- /dev/null
+From e00dc69b5f17c444a38cd9745a0f76bc989b3af4 Mon Sep 17 00:00:00 2001
+From: Arun Easi <aeasi@marvell.com>
+Date: Fri, 9 Apr 2021 14:51:53 -0700
+Subject: PCI: Allow VPD access for QLogic ISP2722
+
+From: Arun Easi <aeasi@marvell.com>
+
+commit e00dc69b5f17c444a38cd9745a0f76bc989b3af4 upstream.
+
+0d5370d1d852 ("PCI: Prevent VPD access for QLogic ISP2722") disabled access
+to VPD of the ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter because
+reading past the end of the VPD caused NMIs.
+
+104daa71b396 ("PCI: Determine actual VPD size on first access") limits
+reads to the actual size of VPD, which should prevent these NMIs.
+
+104daa71b396 was merged *before* 0d5370d1d852, but we think the testing
+that prompted 0d5370d1d852 ("PCI: Prevent VPD access for QLogic ISP2722")
+was done with a kernel that lacked 104daa71b396. See [1, 2].
+
+Remove the quirk added by 0d5370d1d852 ("PCI: Prevent VPD access for QLogic
+ISP2722") so customers can read the HBA VPD.
+
+[1] https://lore.kernel.org/linux-pci/alpine.LRH.2.21.9999.2012161641230.28924@irv1user01.caveonetworks.com/
+[2] https://lore.kernel.org/linux-pci/alpine.LRH.2.21.9999.2104071535110.13940@irv1user01.caveonetworks.com/
+[bhelgaas: commit log]
+Link: https://lore.kernel.org/r/20210409215153.16569-2-aeasi@marvell.com
+Signed-off-by: Arun Easi <aeasi@marvell.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: stable@vger.kernel.org # v4.6+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/vpd.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/pci/vpd.c
++++ b/drivers/pci/vpd.c
+@@ -570,7 +570,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LS
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x005f, quirk_blacklist_vpd);
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, PCI_ANY_ID,
+ quirk_blacklist_vpd);
+-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_QLOGIC, 0x2261, quirk_blacklist_vpd);
+ /*
+ * The Amazon Annapurna Labs 0x0031 device id is reused for other non Root Port
+ * device types, so the quirk is registered for the PCI_CLASS_BRIDGE_PCI class.
--- /dev/null
+From 5b4f5757f83be34d1428a1ffbb68d4a1966e9aae Mon Sep 17 00:00:00 2001
+From: Kishon Vijay Abraham I <kishon@ti.com>
+Date: Fri, 19 Mar 2021 18:11:16 +0530
+Subject: phy: cadence: Sierra: Fix PHY power_on sequence
+
+From: Kishon Vijay Abraham I <kishon@ti.com>
+
+commit 5b4f5757f83be34d1428a1ffbb68d4a1966e9aae upstream.
+
+Commit 44d30d622821d ("phy: cadence: Add driver for Sierra PHY")
+de-asserts PHY_RESET even before the configurations are loaded in
+phy_init(). However PHY_RESET should be de-asserted only after
+all the configurations has been initialized, instead of de-asserting
+in probe. Fix it here.
+
+Fixes: 44d30d622821d ("phy: cadence: Add driver for Sierra PHY")
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Cc: <stable@vger.kernel.org> # v5.4+
+Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
+Link: https://lore.kernel.org/r/20210319124128.13308-2-kishon@ti.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/cadence/phy-cadence-sierra.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/phy/cadence/phy-cadence-sierra.c
++++ b/drivers/phy/cadence/phy-cadence-sierra.c
+@@ -125,6 +125,12 @@ static int cdns_sierra_phy_on(struct phy
+ {
+ struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
+
++ ret = reset_control_deassert(sp->phy_rst);
++ if (ret) {
++ dev_err(dev, "Failed to take the PHY out of reset\n");
++ return ret;
++ }
++
+ /* Take the PHY lane group out of reset */
+ return reset_control_deassert(ins->lnk_rst);
+ }
+@@ -271,7 +277,6 @@ static int cdns_sierra_phy_probe(struct
+
+ pm_runtime_enable(dev);
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+- reset_control_deassert(sp->phy_rst);
+ return PTR_ERR_OR_ZERO(phy_provider);
+
+ put_child:
staging-fwserial-fix-tiocsserial-jiffies-conversions.patch
tty-moxa-fix-tiocsserial-permission-check.patch
staging-fwserial-fix-tiocsserial-permission-check.patch
+usb-typec-tcpm-address-incorrect-values-of-tcpm-psy-for-fixed-supply.patch
+usb-typec-tcpm-address-incorrect-values-of-tcpm-psy-for-pps-supply.patch
+usb-typec-tcpm-update-power-supply-once-partner-accepts.patch
+usb-xhci-mtk-remove-or-operator-for-setting-schedule-parameters.patch
+usb-xhci-mtk-improve-bandwidth-scheduling-with-tt.patch
+asoc-samsung-tm2_wm5110-check-of-of_parse-return-value.patch
+asoc-intel-kbl_da7219_max98927-fix-kabylake_ssp_fixup-function.patch
+mips-pci-mt7620-fix-pll-lock-check.patch
+mips-pci-rt2880-fix-slot-0-configuration.patch
+fddi-defxx-bail-out-gracefully-with-unassigned-pci-resource-for-csr.patch
+pci-allow-vpd-access-for-qlogic-isp2722.patch
+iio-accel-adis16201-fix-wrong-axis-assignment-that-prevents-loading.patch
+phy-cadence-sierra-fix-phy-power_on-sequence.patch
+misc-lis3lv02d-fix-false-positive-warn-on-various-hp-models.patch
+misc-vmw_vmci-explicitly-initialize-vmci_notify_bm_set_msg-struct.patch
+misc-vmw_vmci-explicitly-initialize-vmci_datagram-payload.patch
+md-bitmap-wait-for-external-bitmap-writes-to-complete-during-tear-down.patch
--- /dev/null
+From f3dedafb8263ca4791a92a23f5230068f5bde008 Mon Sep 17 00:00:00 2001
+From: Badhri Jagan Sridharan <badhri@google.com>
+Date: Wed, 7 Apr 2021 13:07:18 -0700
+Subject: usb: typec: tcpm: Address incorrect values of tcpm psy for fixed supply
+
+From: Badhri Jagan Sridharan <badhri@google.com>
+
+commit f3dedafb8263ca4791a92a23f5230068f5bde008 upstream.
+
+tcpm_pd_build_request overwrites current_limit and supply_voltage
+even before port partner accepts the requests. This leaves stale
+values in current_limit and supply_voltage that get exported by
+"tcpm-source-psy-". Solving this problem by caching the request
+values of current limit/supply voltage in req_current_limit
+and req_supply_voltage. current_limit/supply_voltage gets updated
+once the port partner accepts the request.
+
+Fixes: f2a8aa053c176 ("typec: tcpm: Represent source supply through power_supply")
+Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
+Cc: stable <stable@vger.kernel.org>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20210407200723.1914388-1-badhri@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/tcpm/tcpm.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -285,7 +285,10 @@ struct tcpm_port {
+ unsigned int operating_snk_mw;
+ bool update_sink_caps;
+
+- /* Requested current / voltage */
++ /* Requested current / voltage to the port partner */
++ u32 req_current_limit;
++ u32 req_supply_voltage;
++ /* Actual current / voltage limit of the local port */
+ u32 current_limit;
+ u32 supply_voltage;
+
+@@ -1724,8 +1727,8 @@ static void tcpm_pd_ctrl_request(struct
+ case SNK_TRANSITION_SINK:
+ if (port->vbus_present) {
+ tcpm_set_current_limit(port,
+- port->current_limit,
+- port->supply_voltage);
++ port->req_current_limit,
++ port->req_supply_voltage);
+ port->explicit_contract = true;
+ tcpm_set_state(port, SNK_READY, 0);
+ } else {
+@@ -1797,8 +1800,8 @@ static void tcpm_pd_ctrl_request(struct
+ break;
+ case SNK_NEGOTIATE_PPS_CAPABILITIES:
+ port->pps_data.active = true;
+- port->supply_voltage = port->pps_data.out_volt;
+- port->current_limit = port->pps_data.op_curr;
++ port->req_supply_voltage = port->pps_data.out_volt;
++ port->req_current_limit = port->pps_data.op_curr;
+ tcpm_set_state(port, SNK_TRANSITION_SINK, 0);
+ break;
+ case SOFT_RESET_SEND:
+@@ -2402,8 +2405,8 @@ static int tcpm_pd_build_request(struct
+ flags & RDO_CAP_MISMATCH ? " [mismatch]" : "");
+ }
+
+- port->current_limit = ma;
+- port->supply_voltage = mv;
++ port->req_current_limit = ma;
++ port->req_supply_voltage = mv;
+
+ return 0;
+ }
--- /dev/null
+From e3a0720224873587954b55d193d5b4abb14f0443 Mon Sep 17 00:00:00 2001
+From: Badhri Jagan Sridharan <badhri@google.com>
+Date: Wed, 7 Apr 2021 13:07:19 -0700
+Subject: usb: typec: tcpm: Address incorrect values of tcpm psy for pps supply
+
+From: Badhri Jagan Sridharan <badhri@google.com>
+
+commit e3a0720224873587954b55d193d5b4abb14f0443 upstream.
+
+tcpm_pd_select_pps_apdo overwrites port->pps_data.min_volt,
+port->pps_data.max_volt, port->pps_data.max_curr even before
+port partner accepts the requests. This leaves incorrect values
+in current_limit and supply_voltage that get exported by
+"tcpm-source-psy-". Solving this problem by caching the request
+values in req_min_volt, req_max_volt, req_max_curr, req_out_volt,
+req_op_curr. min_volt, max_volt, max_curr gets updated once the
+partner accepts the request. current_limit, supply_voltage gets updated
+once local port's tcpm enters SNK_TRANSITION_SINK when the accepted
+current_limit and supply_voltage is enforced.
+
+Fixes: f2a8aa053c176 ("typec: tcpm: Represent source supply through power_supply")
+Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
+Cc: stable <stable@vger.kernel.org>
+Reviewed-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20210407200723.1914388-2-badhri@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/tcpm/tcpm.c | 88 +++++++++++++++++++++++++-----------------
+ 1 file changed, 53 insertions(+), 35 deletions(-)
+
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -181,12 +181,27 @@ struct pd_mode_data {
+ struct typec_altmode_desc altmode_desc[ALTMODE_DISCOVERY_MAX];
+ };
+
++/*
++ * @min_volt: Actual min voltage at the local port
++ * @req_min_volt: Requested min voltage to the port partner
++ * @max_volt: Actual max voltage at the local port
++ * @req_max_volt: Requested max voltage to the port partner
++ * @max_curr: Actual max current at the local port
++ * @req_max_curr: Requested max current of the port partner
++ * @req_out_volt: Requested output voltage to the port partner
++ * @req_op_curr: Requested operating current to the port partner
++ * @supported: Parter has atleast one APDO hence supports PPS
++ * @active: PPS mode is active
++ */
+ struct pd_pps_data {
+ u32 min_volt;
++ u32 req_min_volt;
+ u32 max_volt;
++ u32 req_max_volt;
+ u32 max_curr;
+- u32 out_volt;
+- u32 op_curr;
++ u32 req_max_curr;
++ u32 req_out_volt;
++ u32 req_op_curr;
+ bool supported;
+ bool active;
+ };
+@@ -1767,8 +1782,8 @@ static void tcpm_pd_ctrl_request(struct
+ break;
+ case SNK_NEGOTIATE_PPS_CAPABILITIES:
+ /* Revert data back from any requested PPS updates */
+- port->pps_data.out_volt = port->supply_voltage;
+- port->pps_data.op_curr = port->current_limit;
++ port->pps_data.req_out_volt = port->supply_voltage;
++ port->pps_data.req_op_curr = port->current_limit;
+ port->pps_status = (type == PD_CTRL_WAIT ?
+ -EAGAIN : -EOPNOTSUPP);
+ tcpm_set_state(port, SNK_READY, 0);
+@@ -1800,8 +1815,11 @@ static void tcpm_pd_ctrl_request(struct
+ break;
+ case SNK_NEGOTIATE_PPS_CAPABILITIES:
+ port->pps_data.active = true;
+- port->req_supply_voltage = port->pps_data.out_volt;
+- port->req_current_limit = port->pps_data.op_curr;
++ port->pps_data.min_volt = port->pps_data.req_min_volt;
++ port->pps_data.max_volt = port->pps_data.req_max_volt;
++ port->pps_data.max_curr = port->pps_data.req_max_curr;
++ port->req_supply_voltage = port->pps_data.req_out_volt;
++ port->req_current_limit = port->pps_data.req_op_curr;
+ tcpm_set_state(port, SNK_TRANSITION_SINK, 0);
+ break;
+ case SOFT_RESET_SEND:
+@@ -2315,16 +2333,16 @@ static unsigned int tcpm_pd_select_pps_a
+ src = port->source_caps[src_pdo];
+ snk = port->snk_pdo[snk_pdo];
+
+- port->pps_data.min_volt = max(pdo_pps_apdo_min_voltage(src),
+- pdo_pps_apdo_min_voltage(snk));
+- port->pps_data.max_volt = min(pdo_pps_apdo_max_voltage(src),
+- pdo_pps_apdo_max_voltage(snk));
+- port->pps_data.max_curr = min_pps_apdo_current(src, snk);
+- port->pps_data.out_volt = min(port->pps_data.max_volt,
+- max(port->pps_data.min_volt,
+- port->pps_data.out_volt));
+- port->pps_data.op_curr = min(port->pps_data.max_curr,
+- port->pps_data.op_curr);
++ port->pps_data.req_min_volt = max(pdo_pps_apdo_min_voltage(src),
++ pdo_pps_apdo_min_voltage(snk));
++ port->pps_data.req_max_volt = min(pdo_pps_apdo_max_voltage(src),
++ pdo_pps_apdo_max_voltage(snk));
++ port->pps_data.req_max_curr = min_pps_apdo_current(src, snk);
++ port->pps_data.req_out_volt = min(port->pps_data.max_volt,
++ max(port->pps_data.min_volt,
++ port->pps_data.req_out_volt));
++ port->pps_data.req_op_curr = min(port->pps_data.max_curr,
++ port->pps_data.req_op_curr);
+ power_supply_changed(port->psy);
+ }
+
+@@ -2452,10 +2470,10 @@ static int tcpm_pd_build_pps_request(str
+ tcpm_log(port, "Invalid APDO selected!");
+ return -EINVAL;
+ }
+- max_mv = port->pps_data.max_volt;
+- max_ma = port->pps_data.max_curr;
+- out_mv = port->pps_data.out_volt;
+- op_ma = port->pps_data.op_curr;
++ max_mv = port->pps_data.req_max_volt;
++ max_ma = port->pps_data.req_max_curr;
++ out_mv = port->pps_data.req_out_volt;
++ op_ma = port->pps_data.req_op_curr;
+ break;
+ default:
+ tcpm_log(port, "Invalid PDO selected!");
+@@ -2502,8 +2520,8 @@ static int tcpm_pd_build_pps_request(str
+ tcpm_log(port, "Requesting APDO %d: %u mV, %u mA",
+ src_pdo_index, out_mv, op_ma);
+
+- port->pps_data.op_curr = op_ma;
+- port->pps_data.out_volt = out_mv;
++ port->pps_data.req_op_curr = op_ma;
++ port->pps_data.req_out_volt = out_mv;
+
+ return 0;
+ }
+@@ -4174,7 +4192,7 @@ static int tcpm_try_role(const struct ty
+ return ret;
+ }
+
+-static int tcpm_pps_set_op_curr(struct tcpm_port *port, u16 op_curr)
++static int tcpm_pps_set_op_curr(struct tcpm_port *port, u16 req_op_curr)
+ {
+ unsigned int target_mw;
+ int ret;
+@@ -4192,22 +4210,22 @@ static int tcpm_pps_set_op_curr(struct t
+ goto port_unlock;
+ }
+
+- if (op_curr > port->pps_data.max_curr) {
++ if (req_op_curr > port->pps_data.max_curr) {
+ ret = -EINVAL;
+ goto port_unlock;
+ }
+
+- target_mw = (op_curr * port->pps_data.out_volt) / 1000;
++ target_mw = (req_op_curr * port->supply_voltage) / 1000;
+ if (target_mw < port->operating_snk_mw) {
+ ret = -EINVAL;
+ goto port_unlock;
+ }
+
+ /* Round down operating current to align with PPS valid steps */
+- op_curr = op_curr - (op_curr % RDO_PROG_CURR_MA_STEP);
++ req_op_curr = req_op_curr - (req_op_curr % RDO_PROG_CURR_MA_STEP);
+
+ reinit_completion(&port->pps_complete);
+- port->pps_data.op_curr = op_curr;
++ port->pps_data.req_op_curr = req_op_curr;
+ port->pps_status = 0;
+ port->pps_pending = true;
+ tcpm_set_state(port, SNK_NEGOTIATE_PPS_CAPABILITIES, 0);
+@@ -4229,7 +4247,7 @@ swap_unlock:
+ return ret;
+ }
+
+-static int tcpm_pps_set_out_volt(struct tcpm_port *port, u16 out_volt)
++static int tcpm_pps_set_out_volt(struct tcpm_port *port, u16 req_out_volt)
+ {
+ unsigned int target_mw;
+ int ret;
+@@ -4247,23 +4265,23 @@ static int tcpm_pps_set_out_volt(struct
+ goto port_unlock;
+ }
+
+- if (out_volt < port->pps_data.min_volt ||
+- out_volt > port->pps_data.max_volt) {
++ if (req_out_volt < port->pps_data.min_volt ||
++ req_out_volt > port->pps_data.max_volt) {
+ ret = -EINVAL;
+ goto port_unlock;
+ }
+
+- target_mw = (port->pps_data.op_curr * out_volt) / 1000;
++ target_mw = (port->current_limit * req_out_volt) / 1000;
+ if (target_mw < port->operating_snk_mw) {
+ ret = -EINVAL;
+ goto port_unlock;
+ }
+
+ /* Round down output voltage to align with PPS valid steps */
+- out_volt = out_volt - (out_volt % RDO_PROG_VOLT_MV_STEP);
++ req_out_volt = req_out_volt - (req_out_volt % RDO_PROG_VOLT_MV_STEP);
+
+ reinit_completion(&port->pps_complete);
+- port->pps_data.out_volt = out_volt;
++ port->pps_data.req_out_volt = req_out_volt;
+ port->pps_status = 0;
+ port->pps_pending = true;
+ tcpm_set_state(port, SNK_NEGOTIATE_PPS_CAPABILITIES, 0);
+@@ -4312,8 +4330,8 @@ static int tcpm_pps_activate(struct tcpm
+
+ /* Trigger PPS request or move back to standard PDO contract */
+ if (activate) {
+- port->pps_data.out_volt = port->supply_voltage;
+- port->pps_data.op_curr = port->current_limit;
++ port->pps_data.req_out_volt = port->supply_voltage;
++ port->pps_data.req_op_curr = port->current_limit;
+ tcpm_set_state(port, SNK_NEGOTIATE_PPS_CAPABILITIES, 0);
+ } else {
+ tcpm_set_state(port, SNK_NEGOTIATE_CAPABILITIES, 0);
--- /dev/null
+From 4050f2683f2c3151dc3dd1501ac88c57caf810ff Mon Sep 17 00:00:00 2001
+From: Badhri Jagan Sridharan <badhri@google.com>
+Date: Wed, 7 Apr 2021 13:07:20 -0700
+Subject: usb: typec: tcpm: update power supply once partner accepts
+
+From: Badhri Jagan Sridharan <badhri@google.com>
+
+commit 4050f2683f2c3151dc3dd1501ac88c57caf810ff upstream.
+
+power_supply_changed needs to be called to notify clients
+after the partner accepts the requested values for the pps
+case.
+
+Also, remove the redundant power_supply_changed at the end
+of the tcpm_reset_port as power_supply_changed is already
+called right after usb_type is changed.
+
+Fixes: f2a8aa053c176 ("typec: tcpm: Represent source supply through power_supply")
+Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
+Cc: stable <stable@vger.kernel.org>
+Reviewed-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20210407200723.1914388-3-badhri@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/tcpm/tcpm.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -1820,6 +1820,7 @@ static void tcpm_pd_ctrl_request(struct
+ port->pps_data.max_curr = port->pps_data.req_max_curr;
+ port->req_supply_voltage = port->pps_data.req_out_volt;
+ port->req_current_limit = port->pps_data.req_op_curr;
++ power_supply_changed(port->psy);
+ tcpm_set_state(port, SNK_TRANSITION_SINK, 0);
+ break;
+ case SOFT_RESET_SEND:
+@@ -2343,7 +2344,6 @@ static unsigned int tcpm_pd_select_pps_a
+ port->pps_data.req_out_volt));
+ port->pps_data.req_op_curr = min(port->pps_data.max_curr,
+ port->pps_data.req_op_curr);
+- power_supply_changed(port->psy);
+ }
+
+ return src_pdo;
+@@ -2743,8 +2743,6 @@ static void tcpm_reset_port(struct tcpm_
+ port->try_src_count = 0;
+ port->try_snk_count = 0;
+ port->usb_type = POWER_SUPPLY_USB_TYPE_C;
+-
+- power_supply_changed(port->psy);
+ }
+
+ static void tcpm_detach(struct tcpm_port *port)
--- /dev/null
+From e19ee44a3d07c232f9241024dab1ebd0748cdf5f Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Mon, 8 Mar 2021 10:51:51 +0800
+Subject: usb: xhci-mtk: improve bandwidth scheduling with TT
+
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+
+commit e19ee44a3d07c232f9241024dab1ebd0748cdf5f upstream.
+
+When the USB headset is plug into an external hub, sometimes
+can't set config due to not enough bandwidth, so need improve
+LS/FS INT/ISOC bandwidth scheduling with TT.
+
+Fixes: 54f6a8af3722 ("usb: xhci-mtk: skip dropping bandwidth of unchecked endpoints")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Yaqii Wu <yaqii.wu@mediatek.com>
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Link: https://lore.kernel.org/r/2f30e81400a59afef5f8231c98149169c7520519.1615170625.git.chunfeng.yun@mediatek.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-mtk-sch.c | 74 ++++++++++++++++++++++++++++++++--------
+ drivers/usb/host/xhci-mtk.h | 6 ++-
+ 2 files changed, 64 insertions(+), 16 deletions(-)
+
+--- a/drivers/usb/host/xhci-mtk-sch.c
++++ b/drivers/usb/host/xhci-mtk-sch.c
+@@ -378,6 +378,31 @@ static void update_bus_bw(struct mu3h_sc
+ sch_ep->allocated = used;
+ }
+
++static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
++{
++ struct mu3h_sch_tt *tt = sch_ep->sch_tt;
++ u32 num_esit, tmp;
++ int base;
++ int i, j;
++
++ num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
++ for (i = 0; i < num_esit; i++) {
++ base = offset + i * sch_ep->esit;
++
++ /*
++ * Compared with hs bus, no matter what ep type,
++ * the hub will always delay one uframe to send data
++ */
++ for (j = 0; j < sch_ep->cs_count; j++) {
++ tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe;
++ if (tmp > FS_PAYLOAD_MAX)
++ return -ERANGE;
++ }
++ }
++
++ return 0;
++}
++
+ static int check_sch_tt(struct usb_device *udev,
+ struct mu3h_sch_ep_info *sch_ep, u32 offset)
+ {
+@@ -402,7 +427,7 @@ static int check_sch_tt(struct usb_devic
+ return -ERANGE;
+
+ for (i = 0; i < sch_ep->cs_count; i++)
+- if (test_bit(offset + i, tt->split_bit_map))
++ if (test_bit(offset + i, tt->ss_bit_map))
+ return -ERANGE;
+
+ } else {
+@@ -432,7 +457,7 @@ static int check_sch_tt(struct usb_devic
+ cs_count = 7; /* HW limit */
+
+ for (i = 0; i < cs_count + 2; i++) {
+- if (test_bit(offset + i, tt->split_bit_map))
++ if (test_bit(offset + i, tt->ss_bit_map))
+ return -ERANGE;
+ }
+
+@@ -448,24 +473,44 @@ static int check_sch_tt(struct usb_devic
+ sch_ep->num_budget_microframes = sch_ep->esit;
+ }
+
+- return 0;
++ return check_fs_bus_bw(sch_ep, offset);
+ }
+
+ static void update_sch_tt(struct usb_device *udev,
+- struct mu3h_sch_ep_info *sch_ep)
++ struct mu3h_sch_ep_info *sch_ep, bool used)
+ {
+ struct mu3h_sch_tt *tt = sch_ep->sch_tt;
+ u32 base, num_esit;
++ int bw_updated;
++ int bits;
+ int i, j;
+
+ num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
++ bits = (sch_ep->ep_type == ISOC_OUT_EP) ? sch_ep->cs_count : 1;
++
++ if (used)
++ bw_updated = sch_ep->bw_cost_per_microframe;
++ else
++ bw_updated = -sch_ep->bw_cost_per_microframe;
++
+ for (i = 0; i < num_esit; i++) {
+ base = sch_ep->offset + i * sch_ep->esit;
+- for (j = 0; j < sch_ep->num_budget_microframes; j++)
+- set_bit(base + j, tt->split_bit_map);
++
++ for (j = 0; j < bits; j++) {
++ if (used)
++ set_bit(base + j, tt->ss_bit_map);
++ else
++ clear_bit(base + j, tt->ss_bit_map);
++ }
++
++ for (j = 0; j < sch_ep->cs_count; j++)
++ tt->fs_bus_bw[base + j] += bw_updated;
+ }
+
+- list_add_tail(&sch_ep->tt_endpoint, &tt->ep_list);
++ if (used)
++ list_add_tail(&sch_ep->tt_endpoint, &tt->ep_list);
++ else
++ list_del(&sch_ep->tt_endpoint);
+ }
+
+ static int check_sch_bw(struct usb_device *udev,
+@@ -535,7 +580,7 @@ static int check_sch_bw(struct usb_devic
+ if (!tt_offset_ok)
+ return -ERANGE;
+
+- update_sch_tt(udev, sch_ep);
++ update_sch_tt(udev, sch_ep, 1);
+ }
+
+ /* update bus bandwidth info */
+@@ -548,15 +593,16 @@ static void destroy_sch_ep(struct usb_de
+ struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
+ {
+ /* only release ep bw check passed by check_sch_bw() */
+- if (sch_ep->allocated)
++ if (sch_ep->allocated) {
+ update_bus_bw(sch_bw, sch_ep, 0);
++ if (sch_ep->sch_tt)
++ update_sch_tt(udev, sch_ep, 0);
++ }
+
+- list_del(&sch_ep->endpoint);
+-
+- if (sch_ep->sch_tt) {
+- list_del(&sch_ep->tt_endpoint);
++ if (sch_ep->sch_tt)
+ drop_tt(udev);
+- }
++
++ list_del(&sch_ep->endpoint);
+ kfree(sch_ep);
+ }
+
+--- a/drivers/usb/host/xhci-mtk.h
++++ b/drivers/usb/host/xhci-mtk.h
+@@ -20,13 +20,15 @@
+ #define XHCI_MTK_MAX_ESIT 64
+
+ /**
+- * @split_bit_map: used to avoid split microframes overlay
++ * @ss_bit_map: used to avoid start split microframes overlay
++ * @fs_bus_bw: array to keep track of bandwidth already used for FS
+ * @ep_list: Endpoints using this TT
+ * @usb_tt: usb TT related
+ * @tt_port: TT port number
+ */
+ struct mu3h_sch_tt {
+- DECLARE_BITMAP(split_bit_map, XHCI_MTK_MAX_ESIT);
++ DECLARE_BITMAP(ss_bit_map, XHCI_MTK_MAX_ESIT);
++ u32 fs_bus_bw[XHCI_MTK_MAX_ESIT];
+ struct list_head ep_list;
+ struct usb_tt *usb_tt;
+ int tt_port;
--- /dev/null
+From 5fa5827566e3affa1657ccf9b22706c06a5d021a Mon Sep 17 00:00:00 2001
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Date: Mon, 8 Mar 2021 10:51:50 +0800
+Subject: usb: xhci-mtk: remove or operator for setting schedule parameters
+
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+
+commit 5fa5827566e3affa1657ccf9b22706c06a5d021a upstream.
+
+Side effect may happen if use or operator to set schedule parameters
+when the parameters are already set before. Set them directly due to
+other bits are reserved.
+
+Fixes: 54f6a8af3722 ("usb: xhci-mtk: skip dropping bandwidth of unchecked endpoints")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Link: https://lore.kernel.org/r/d287899e6beb2fc1bfb8900c75a872f628ecde55.1615170625.git.chunfeng.yun@mediatek.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-mtk-sch.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/xhci-mtk-sch.c
++++ b/drivers/usb/host/xhci-mtk-sch.c
+@@ -643,7 +643,7 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd
+ */
+ if (usb_endpoint_xfer_int(&ep->desc)
+ || usb_endpoint_xfer_isoc(&ep->desc))
+- ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(1));
++ ep_ctx->reserved[0] = cpu_to_le32(EP_BPKTS(1));
+
+ return 0;
+ }
+@@ -730,10 +730,10 @@ int xhci_mtk_check_bandwidth(struct usb_
+ list_move_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
+
+ ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
+- ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts)
++ ep_ctx->reserved[0] = cpu_to_le32(EP_BPKTS(sch_ep->pkts)
+ | EP_BCSCOUNT(sch_ep->cs_count)
+ | EP_BBM(sch_ep->burst_mode));
+- ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset)
++ ep_ctx->reserved[1] = cpu_to_le32(EP_BOFFSET(sch_ep->offset)
+ | EP_BREPEAT(sch_ep->repeat));
+
+ xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n",