]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.19
authorSasha Levin <sashal@kernel.org>
Thu, 17 Aug 2023 14:52:49 +0000 (10:52 -0400)
committerSasha Levin <sashal@kernel.org>
Thu, 17 Aug 2023 14:52:49 +0000 (10:52 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
54 files changed:
queue-4.19/alsa-emu10k1-roll-up-loops-in-dsp-setup-code-for-aud.patch [new file with mode: 0644]
queue-4.19/block-fix-signed-int-overflow-in-amiga-partition-sup.patch [new file with mode: 0644]
queue-4.19/bluetooth-l2cap-fix-use-after-free.patch [new file with mode: 0644]
queue-4.19/drm-amdgpu-fix-potential-fence-use-after-free-v2.patch [new file with mode: 0644]
queue-4.19/drm-radeon-fix-integer-overflow-in-radeon_cs_parser_.patch [new file with mode: 0644]
queue-4.19/fs-jfs-check-for-read-only-mounted-filesystem-in-txb.patch [new file with mode: 0644]
queue-4.19/fs-jfs-fix-null-ptr-deref-read-in-txbegin.patch [new file with mode: 0644]
queue-4.19/fs-jfs-fix-ubsan-array-index-out-of-bounds-in-dballo.patch [new file with mode: 0644]
queue-4.19/gfs2-fix-possible-data-races-in-gfs2_show_options.patch [new file with mode: 0644]
queue-4.19/hid-add-quirk-for-03f0-464a-hp-elite-presenter-mouse.patch [new file with mode: 0644]
queue-4.19/iio-adc-stx104-implement-and-utilize-register-struct.patch [new file with mode: 0644]
queue-4.19/iio-adc-stx104-utilize-iomap-interface.patch [new file with mode: 0644]
queue-4.19/iio-add-addac-subdirectory.patch [new file with mode: 0644]
queue-4.19/iio-addac-stx104-fix-race-condition-for-stx104_write.patch [new file with mode: 0644]
queue-4.19/iio-addac-stx104-fix-race-condition-when-converting-.patch [new file with mode: 0644]
queue-4.19/ima-allow-fix-uml-builds.patch [new file with mode: 0644]
queue-4.19/irqchip-mips-gic-get-rid-of-the-reliance-on-irq_cpu_.patch [new file with mode: 0644]
queue-4.19/irqchip-mips-gic-use-raw-spinlock-for-gic_lock.patch [new file with mode: 0644]
queue-4.19/media-platform-mediatek-vpu-fix-null-ptr-dereference.patch [new file with mode: 0644]
queue-4.19/media-v4l2-mem2mem-add-lock-to-protect-parameter-num.patch [new file with mode: 0644]
queue-4.19/mips-dec-prom-address-warray-bounds-warning.patch [new file with mode: 0644]
queue-4.19/mmc-bcm2835-fix-deferred-probing.patch [new file with mode: 0644]
queue-4.19/mmc-meson-gx-remove-redundant-mmc_request_done-call-.patch [new file with mode: 0644]
queue-4.19/mmc-meson-gx-remove-useless-lock.patch [new file with mode: 0644]
queue-4.19/mmc-remove-dev_err-usage-after-platform_get_irq.patch [new file with mode: 0644]
queue-4.19/mmc-sdhci-spear-fix-deferred-probing.patch [new file with mode: 0644]
queue-4.19/mmc-sunxi-fix-deferred-probing.patch [new file with mode: 0644]
queue-4.19/mmc-tmio-move-tmio_mmc_set_clock-to-platform-hook.patch [new file with mode: 0644]
queue-4.19/mmc-tmio-replace-tmio_mmc_clk_stop-calls-with-tmio_m.patch [new file with mode: 0644]
queue-4.19/mmc-uniphier-sd-add-uniphier-sd-emmc-controller-driv.patch [new file with mode: 0644]
queue-4.19/nfsd-remove-incorrect-check-in-nfsd4_validate_statei.patch [new file with mode: 0644]
queue-4.19/nfsd4-kill-warnings-on-testing-stateids-with-mismatc.patch [new file with mode: 0644]
queue-4.19/pci-endpoint-add-helper-to-get-first-unreserved-bar.patch [new file with mode: 0644]
queue-4.19/pci-endpoint-add-new-pci_epc_ops-to-get-epc-features.patch [new file with mode: 0644]
queue-4.19/pci-endpoint-add-support-to-specify-alignment-for-bu.patch [new file with mode: 0644]
queue-4.19/pci-pci-epf-test-remove-setting-epf_bar-flags-in-fun.patch [new file with mode: 0644]
queue-4.19/pci-pci-epf-test-use-pci_epc_get_features-to-get-epc.patch [new file with mode: 0644]
queue-4.19/pci-rockchip-populate-get_features-dw_pcie_ep_ops.patch [new file with mode: 0644]
queue-4.19/pci-rockchip-set-address-alignment-for-endpoint-mode.patch [new file with mode: 0644]
queue-4.19/pcmcia-rsrc_nonstatic-fix-memory-leak-in-nonstatic_r.patch [new file with mode: 0644]
queue-4.19/powerpc-64s-radix-fix-soft-dirty-tracking.patch [new file with mode: 0644]
queue-4.19/powerpc-mm-dump-block-address-translation-on-book3s-.patch [new file with mode: 0644]
queue-4.19/powerpc-mm-dump-segment-registers-on-book3s-32.patch [new file with mode: 0644]
queue-4.19/powerpc-mm-move-pgtable_t-into-platform-headers.patch [new file with mode: 0644]
queue-4.19/powerpc-mm-move-platform-specific-mmu-xxx.h-in-platf.patch [new file with mode: 0644]
queue-4.19/powerpc-move-page-table-dump-files-in-a-dedicated-su.patch [new file with mode: 0644]
queue-4.19/quota-fix-warning-in-dqgrab.patch [new file with mode: 0644]
queue-4.19/quota-properly-disable-quotas-when-add_dquot_ref-fai.patch [new file with mode: 0644]
queue-4.19/selftests-forwarding-tc_flower-relax-success-criteri.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/udf-fix-uninitialized-array-access-for-some-pathname.patch [new file with mode: 0644]
queue-4.19/usb-dwc3-qcom-add-helper-functions-to-enable-disable.patch [new file with mode: 0644]
queue-4.19/usb-dwc3-qcom-fix-null-deref-on-suspend.patch [new file with mode: 0644]
queue-4.19/x86-topology-fix-erroneous-smp_num_siblings-on-intel.patch [new file with mode: 0644]

diff --git a/queue-4.19/alsa-emu10k1-roll-up-loops-in-dsp-setup-code-for-aud.patch b/queue-4.19/alsa-emu10k1-roll-up-loops-in-dsp-setup-code-for-aud.patch
new file mode 100644 (file)
index 0000000..dc637f8
--- /dev/null
@@ -0,0 +1,153 @@
+From 5c2ebe2661a7d9e5372d7333a2ed1ad27b61d459 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 May 2023 19:39:05 +0200
+Subject: ALSA: emu10k1: roll up loops in DSP setup code for Audigy
+
+From: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
+
+[ Upstream commit 8cabf83c7aa54530e699be56249fb44f9505c4f3 ]
+
+There is no apparent reason for the massive code duplication.
+
+Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
+Link: https://lore.kernel.org/r/20230510173917.3073107-3-oswald.buddenhagen@gmx.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/emu10k1/emufx.c | 112 +++-----------------------------------
+ 1 file changed, 9 insertions(+), 103 deletions(-)
+
+diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
+index 1f25e6d029d82..84d98c098b744 100644
+--- a/sound/pci/emu10k1/emufx.c
++++ b/sound/pci/emu10k1/emufx.c
+@@ -1550,14 +1550,8 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
+       gpr += 2;
+       /* Master volume (will be renamed later) */
+-      A_OP(icode, &ptr, iMAC0, A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS));
+-      A_OP(icode, &ptr, iMAC0, A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS));
+-      A_OP(icode, &ptr, iMAC0, A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS));
+-      A_OP(icode, &ptr, iMAC0, A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS));
+-      A_OP(icode, &ptr, iMAC0, A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS));
+-      A_OP(icode, &ptr, iMAC0, A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS));
+-      A_OP(icode, &ptr, iMAC0, A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS));
+-      A_OP(icode, &ptr, iMAC0, A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS));
++      for (z = 0; z < 8; z++)
++              A_OP(icode, &ptr, iMAC0, A_GPR(playback+z+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+z+SND_EMU10K1_PLAYBACK_CHANNELS));
+       snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
+       gpr += 2;
+@@ -1641,102 +1635,14 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
+                       dev_dbg(emu->card->dev, "emufx.c: gpr=0x%x, tmp=0x%x\n",
+                              gpr, tmp);
+                       */
+-                      /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */
+-                      /* A_P16VIN(0) is delayed by one sample,
+-                       * so all other A_P16VIN channels will need to also be delayed
+-                       */
+-                      /* Left ADC in. 1 of 2 */
+                       snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
+-                      /* Right ADC in 1 of 2 */
+-                      gpr_map[gpr++] = 0x00000000;
+-                      /* Delaying by one sample: instead of copying the input
+-                       * value A_P16VIN to output A_FXBUS2 as in the first channel,
+-                       * we use an auxiliary register, delaying the value by one
+-                       * sample
+-                       */
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) );
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
+-                      gpr_map[gpr++] = 0x00000000;
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) );
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000);
+-                      gpr_map[gpr++] = 0x00000000;
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) );
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000);
+-                      /* For 96kHz mode */
+-                      /* Left ADC in. 2 of 2 */
+-                      gpr_map[gpr++] = 0x00000000;
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) );
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000);
+-                      /* Right ADC in 2 of 2 */
+-                      gpr_map[gpr++] = 0x00000000;
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) );
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000);
+-                      gpr_map[gpr++] = 0x00000000;
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) );
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000);
+-                      gpr_map[gpr++] = 0x00000000;
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) );
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000);
+-                      /* Pavel Hofman - we still have voices, A_FXBUS2s, and
+-                       * A_P16VINs available -
+-                       * let's add 8 more capture channels - total of 16
+-                       */
+-                      gpr_map[gpr++] = 0x00000000;
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+-                                                                bit_shifter16,
+-                                                                A_GPR(gpr - 1),
+-                                                                A_FXBUS2(0x10));
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8),
+-                           A_C_00000000, A_C_00000000);
+-                      gpr_map[gpr++] = 0x00000000;
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+-                                                                bit_shifter16,
+-                                                                A_GPR(gpr - 1),
+-                                                                A_FXBUS2(0x12));
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9),
+-                           A_C_00000000, A_C_00000000);
+-                      gpr_map[gpr++] = 0x00000000;
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+-                                                                bit_shifter16,
+-                                                                A_GPR(gpr - 1),
+-                                                                A_FXBUS2(0x14));
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa),
+-                           A_C_00000000, A_C_00000000);
+-                      gpr_map[gpr++] = 0x00000000;
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+-                                                                bit_shifter16,
+-                                                                A_GPR(gpr - 1),
+-                                                                A_FXBUS2(0x16));
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb),
+-                           A_C_00000000, A_C_00000000);
+-                      gpr_map[gpr++] = 0x00000000;
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+-                                                                bit_shifter16,
+-                                                                A_GPR(gpr - 1),
+-                                                                A_FXBUS2(0x18));
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc),
+-                           A_C_00000000, A_C_00000000);
+-                      gpr_map[gpr++] = 0x00000000;
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+-                                                                bit_shifter16,
+-                                                                A_GPR(gpr - 1),
+-                                                                A_FXBUS2(0x1a));
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd),
+-                           A_C_00000000, A_C_00000000);
+-                      gpr_map[gpr++] = 0x00000000;
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+-                                                                bit_shifter16,
+-                                                                A_GPR(gpr - 1),
+-                                                                A_FXBUS2(0x1c));
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe),
+-                           A_C_00000000, A_C_00000000);
+-                      gpr_map[gpr++] = 0x00000000;
+-                      snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+-                                                                bit_shifter16,
+-                                                                A_GPR(gpr - 1),
+-                                                                A_FXBUS2(0x1e));
+-                      A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf),
+-                           A_C_00000000, A_C_00000000);
++                      /* A_P16VIN(0) is delayed by one sample, so all other A_P16VIN channels
++                       * will need to also be delayed; we use an auxiliary register for that. */
++                      for (z = 1; z < 0x10; z++) {
++                              snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr), A_FXBUS2(z * 2) );
++                              A_OP(icode, &ptr, iACC3, A_GPR(gpr), A_P16VIN(z), A_C_00000000, A_C_00000000);
++                              gpr_map[gpr++] = 0x00000000;
++                      }
+               }
+ #if 0
+-- 
+2.40.1
+
diff --git a/queue-4.19/block-fix-signed-int-overflow-in-amiga-partition-sup.patch b/queue-4.19/block-fix-signed-int-overflow-in-amiga-partition-sup.patch
new file mode 100644 (file)
index 0000000..f191b3e
--- /dev/null
@@ -0,0 +1,73 @@
+From b3db5bacad32a2e7f2e66447b3310f21f2cb152e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 08:17:23 +1200
+Subject: block: fix signed int overflow in Amiga partition support
+
+From: Michael Schmitz <schmitzmic@gmail.com>
+
+[ Upstream commit fc3d092c6bb48d5865fec15ed5b333c12f36288c ]
+
+The Amiga partition parser module uses signed int for partition sector
+address and count, which will overflow for disks larger than 1 TB.
+
+Use sector_t as type for sector address and size to allow using disks
+up to 2 TB without LBD support, and disks larger than 2 TB with LBD.
+
+This bug was reported originally in 2012, and the fix was created by
+the RDB author, Joanne Dow <jdow@earthlink.net>. A patch had been
+discussed and reviewed on linux-m68k at that time but never officially
+submitted. This patch differs from Joanne's patch only in its use of
+sector_t instead of unsigned int. No checking for overflows is done
+(see patch 3 of this series for that).
+
+Reported-by: Martin Steigerwald <Martin@lichtvoll.de>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=43511
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Message-ID: <201206192146.09327.Martin@lichtvoll.de>
+Cc: <stable@vger.kernel.org> # 5.2
+Signed-off-by: Michael Schmitz <schmitzmic@gmail.com>
+Tested-by: Martin Steigerwald <Martin@lichtvoll.de>
+Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20230620201725.7020-2-schmitzmic@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/partitions/amiga.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/block/partitions/amiga.c b/block/partitions/amiga.c
+index 560936617d9c1..4a4160221183b 100644
+--- a/block/partitions/amiga.c
++++ b/block/partitions/amiga.c
+@@ -32,7 +32,8 @@ int amiga_partition(struct parsed_partitions *state)
+       unsigned char *data;
+       struct RigidDiskBlock *rdb;
+       struct PartitionBlock *pb;
+-      int start_sect, nr_sects, blk, part, res = 0;
++      sector_t start_sect, nr_sects;
++      int blk, part, res = 0;
+       int blksize = 1;        /* Multiplier for disk block size */
+       int slot = 1;
+       char b[BDEVNAME_SIZE];
+@@ -100,14 +101,14 @@ int amiga_partition(struct parsed_partitions *state)
+               /* Tell Kernel about it */
+-              nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 -
+-                          be32_to_cpu(pb->pb_Environment[9])) *
++              nr_sects = ((sector_t)be32_to_cpu(pb->pb_Environment[10]) + 1 -
++                         be32_to_cpu(pb->pb_Environment[9])) *
+                          be32_to_cpu(pb->pb_Environment[3]) *
+                          be32_to_cpu(pb->pb_Environment[5]) *
+                          blksize;
+               if (!nr_sects)
+                       continue;
+-              start_sect = be32_to_cpu(pb->pb_Environment[9]) *
++              start_sect = (sector_t)be32_to_cpu(pb->pb_Environment[9]) *
+                            be32_to_cpu(pb->pb_Environment[3]) *
+                            be32_to_cpu(pb->pb_Environment[5]) *
+                            blksize;
+-- 
+2.40.1
+
diff --git a/queue-4.19/bluetooth-l2cap-fix-use-after-free.patch b/queue-4.19/bluetooth-l2cap-fix-use-after-free.patch
new file mode 100644 (file)
index 0000000..aab62a4
--- /dev/null
@@ -0,0 +1,41 @@
+From bf66bf13724ac68d7ab5383887f0a31ffa7cda02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 May 2023 17:04:15 -0700
+Subject: Bluetooth: L2CAP: Fix use-after-free
+
+From: Zhengping Jiang <jiangzp@google.com>
+
+[ Upstream commit f752a0b334bb95fe9b42ecb511e0864e2768046f ]
+
+Fix potential use-after-free in l2cap_le_command_rej.
+
+Signed-off-by: Zhengping Jiang <jiangzp@google.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index fcc471f921895..9346fae5d664b 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -5705,9 +5705,14 @@ static inline int l2cap_le_command_rej(struct l2cap_conn *conn,
+       if (!chan)
+               goto done;
++      chan = l2cap_chan_hold_unless_zero(chan);
++      if (!chan)
++              goto done;
++
+       l2cap_chan_lock(chan);
+       l2cap_chan_del(chan, ECONNREFUSED);
+       l2cap_chan_unlock(chan);
++      l2cap_chan_put(chan);
+ done:
+       mutex_unlock(&conn->chan_lock);
+-- 
+2.40.1
+
diff --git a/queue-4.19/drm-amdgpu-fix-potential-fence-use-after-free-v2.patch b/queue-4.19/drm-amdgpu-fix-potential-fence-use-after-free-v2.patch
new file mode 100644 (file)
index 0000000..bf97f85
--- /dev/null
@@ -0,0 +1,52 @@
+From f49632c56ca0d84e311ee22e688ea83c3d4abc4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Jun 2023 18:10:47 -0700
+Subject: drm/amdgpu: Fix potential fence use-after-free v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: shanzhulig <shanzhulig@gmail.com>
+
+[ Upstream commit 2e54154b9f27262efd0cb4f903cc7d5ad1fe9628 ]
+
+fence Decrements the reference count before exiting.
+Avoid Race Vulnerabilities for fence use-after-free.
+
+v2 (chk): actually fix the use after free and not just move it.
+
+Signed-off-by: shanzhulig <shanzhulig@gmail.com>
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+index e667bcf64bc7f..70e446c2acf82 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -1502,15 +1502,15 @@ static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev,
+                       continue;
+               r = dma_fence_wait_timeout(fence, true, timeout);
++              if (r > 0 && fence->error)
++                      r = fence->error;
++
+               dma_fence_put(fence);
+               if (r < 0)
+                       return r;
+               if (r == 0)
+                       break;
+-
+-              if (fence->error)
+-                      return fence->error;
+       }
+       memset(wait, 0, sizeof(*wait));
+-- 
+2.40.1
+
diff --git a/queue-4.19/drm-radeon-fix-integer-overflow-in-radeon_cs_parser_.patch b/queue-4.19/drm-radeon-fix-integer-overflow-in-radeon_cs_parser_.patch
new file mode 100644 (file)
index 0000000..60b6652
--- /dev/null
@@ -0,0 +1,41 @@
+From b47e989f06e1e4fad09ee421ce3def8c2f09e1c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 20:20:58 +0800
+Subject: drm/radeon: Fix integer overflow in radeon_cs_parser_init
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: hackyzh002 <hackyzh002@gmail.com>
+
+[ Upstream commit f828b681d0cd566f86351c0b913e6cb6ed8c7b9c ]
+
+The type of size is unsigned, if size is 0x40000000, there will be an
+integer overflow, size will be zero after size *= sizeof(uint32_t),
+will cause uninitialized memory to be referenced later
+
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: hackyzh002 <hackyzh002@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/radeon_cs.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
+index 1ae31dbc61c64..5e61abb3dce5c 100644
+--- a/drivers/gpu/drm/radeon/radeon_cs.c
++++ b/drivers/gpu/drm/radeon/radeon_cs.c
+@@ -265,7 +265,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
+ {
+       struct drm_radeon_cs *cs = data;
+       uint64_t *chunk_array_ptr;
+-      unsigned size, i;
++      u64 size;
++      unsigned i;
+       u32 ring = RADEON_CS_RING_GFX;
+       s32 priority = 0;
+-- 
+2.40.1
+
diff --git a/queue-4.19/fs-jfs-check-for-read-only-mounted-filesystem-in-txb.patch b/queue-4.19/fs-jfs-check-for-read-only-mounted-filesystem-in-txb.patch
new file mode 100644 (file)
index 0000000..559ade8
--- /dev/null
@@ -0,0 +1,39 @@
+From b13da086c1415e12a25aa12f5f7ec94c9b611455 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Jun 2023 19:17:08 +0530
+Subject: FS: JFS: Check for read-only mounted filesystem in txBegin
+
+From: Immad Mir <mirimmad17@gmail.com>
+
+[ Upstream commit 95e2b352c03b0a86c5717ba1d24ea20969abcacc ]
+
+ This patch adds a check for read-only mounted filesystem
+ in txBegin before starting a transaction potentially saving
+ from NULL pointer deref.
+
+Signed-off-by: Immad Mir <mirimmad17@gmail.com>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/jfs_txnmgr.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
+index 78789c5ed36b0..e10db01f253b8 100644
+--- a/fs/jfs/jfs_txnmgr.c
++++ b/fs/jfs/jfs_txnmgr.c
+@@ -367,6 +367,11 @@ tid_t txBegin(struct super_block *sb, int flag)
+       jfs_info("txBegin: flag = 0x%x", flag);
+       log = JFS_SBI(sb)->log;
++      if (!log) {
++              jfs_error(sb, "read-only filesystem\n");
++              return 0;
++      }
++
+       TXN_LOCK();
+       INCREMENT(TxStat.txBegin);
+-- 
+2.40.1
+
diff --git a/queue-4.19/fs-jfs-fix-null-ptr-deref-read-in-txbegin.patch b/queue-4.19/fs-jfs-fix-null-ptr-deref-read-in-txbegin.patch
new file mode 100644 (file)
index 0000000..bcda606
--- /dev/null
@@ -0,0 +1,44 @@
+From f81faa8296c2f86d2d0356d97484a1d430e38676 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Jun 2023 19:14:01 +0530
+Subject: FS: JFS: Fix null-ptr-deref Read in txBegin
+
+From: Immad Mir <mirimmad17@gmail.com>
+
+[ Upstream commit 47cfdc338d674d38f4b2f22b7612cc6a2763ba27 ]
+
+ Syzkaller reported an issue where txBegin may be called
+ on a superblock in a read-only mounted filesystem which leads
+ to NULL pointer deref. This could be solved by checking if
+ the filesystem is read-only before calling txBegin, and returning
+ with appropiate error code.
+
+Reported-By: syzbot+f1faa20eec55e0c8644c@syzkaller.appspotmail.com
+Link: https://syzkaller.appspot.com/bug?id=be7e52c50c5182cc09a09ea6fc456446b2039de3
+
+Signed-off-by: Immad Mir <mirimmad17@gmail.com>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/namei.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
+index 14528c0ffe635..c2c439acbb780 100644
+--- a/fs/jfs/namei.c
++++ b/fs/jfs/namei.c
+@@ -811,6 +811,11 @@ static int jfs_link(struct dentry *old_dentry,
+       if (rc)
+               goto out;
++      if (isReadOnly(ip)) {
++              jfs_error(ip->i_sb, "read-only filesystem\n");
++              return -EROFS;
++      }
++
+       tid = txBegin(ip->i_sb, 0);
+       mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT);
+-- 
+2.40.1
+
diff --git a/queue-4.19/fs-jfs-fix-ubsan-array-index-out-of-bounds-in-dballo.patch b/queue-4.19/fs-jfs-fix-ubsan-array-index-out-of-bounds-in-dballo.patch
new file mode 100644 (file)
index 0000000..1806789
--- /dev/null
@@ -0,0 +1,86 @@
+From 369b1936a7022319258d11058e05559240f13c1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 00:07:03 +0530
+Subject: fs: jfs: Fix UBSAN: array-index-out-of-bounds in dbAllocDmapLev
+
+From: Yogesh <yogi.kernel@gmail.com>
+
+[ Upstream commit 4e302336d5ca1767a06beee7596a72d3bdc8d983 ]
+
+Syzkaller reported the following issue:
+
+UBSAN: array-index-out-of-bounds in fs/jfs/jfs_dmap.c:1965:6
+index -84 is out of range for type 's8[341]' (aka 'signed char[341]')
+CPU: 1 PID: 4995 Comm: syz-executor146 Not tainted 6.4.0-rc6-syzkaller-00037-gb6dad5178cea #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/27/2023
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x1e7/0x2d0 lib/dump_stack.c:106
+ ubsan_epilogue lib/ubsan.c:217 [inline]
+ __ubsan_handle_out_of_bounds+0x11c/0x150 lib/ubsan.c:348
+ dbAllocDmapLev+0x3e5/0x430 fs/jfs/jfs_dmap.c:1965
+ dbAllocCtl+0x113/0x920 fs/jfs/jfs_dmap.c:1809
+ dbAllocAG+0x28f/0x10b0 fs/jfs/jfs_dmap.c:1350
+ dbAlloc+0x658/0xca0 fs/jfs/jfs_dmap.c:874
+ dtSplitUp fs/jfs/jfs_dtree.c:974 [inline]
+ dtInsert+0xda7/0x6b00 fs/jfs/jfs_dtree.c:863
+ jfs_create+0x7b6/0xbb0 fs/jfs/namei.c:137
+ lookup_open fs/namei.c:3492 [inline]
+ open_last_lookups fs/namei.c:3560 [inline]
+ path_openat+0x13df/0x3170 fs/namei.c:3788
+ do_filp_open+0x234/0x490 fs/namei.c:3818
+ do_sys_openat2+0x13f/0x500 fs/open.c:1356
+ do_sys_open fs/open.c:1372 [inline]
+ __do_sys_openat fs/open.c:1388 [inline]
+ __se_sys_openat fs/open.c:1383 [inline]
+ __x64_sys_openat+0x247/0x290 fs/open.c:1383
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+RIP: 0033:0x7f1f4e33f7e9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 14 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 c0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007ffc21129578 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
+RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f1f4e33f7e9
+RDX: 000000000000275a RSI: 0000000020000040 RDI: 00000000ffffff9c
+RBP: 00007f1f4e2ff080 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 00007f1f4e2ff110
+R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
+ </TASK>
+
+The bug occurs when the dbAllocDmapLev()function attempts to access
+dp->tree.stree[leafidx + LEAFIND] while the leafidx value is negative.
+
+To rectify this, the patch introduces a safeguard within the
+dbAllocDmapLev() function. A check has been added to verify if leafidx is
+negative. If it is, the function immediately returns an I/O error, preventing
+any further execution that could potentially cause harm.
+
+Tested via syzbot.
+
+Reported-by: syzbot+853a6f4dfa3cf37d3aea@syzkaller.appspotmail.com
+Link: https://syzkaller.appspot.com/bug?extid=ae2f5a27a07ae44b0f17
+Signed-off-by: Yogesh <yogi.kernel@gmail.com>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/jfs_dmap.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
+index 07b9df8938f29..63ad6b1d575a5 100644
+--- a/fs/jfs/jfs_dmap.c
++++ b/fs/jfs/jfs_dmap.c
+@@ -2040,6 +2040,9 @@ dbAllocDmapLev(struct bmap * bmp,
+       if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx))
+               return -ENOSPC;
++      if (leafidx < 0)
++              return -EIO;
++
+       /* determine the block number within the file system corresponding
+        * to the leaf at which free space was found.
+        */
+-- 
+2.40.1
+
diff --git a/queue-4.19/gfs2-fix-possible-data-races-in-gfs2_show_options.patch b/queue-4.19/gfs2-fix-possible-data-races-in-gfs2_show_options.patch
new file mode 100644 (file)
index 0000000..2a5c108
--- /dev/null
@@ -0,0 +1,86 @@
+From ebec742dc0cea69366abb536403c832c4193fe01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 11:06:37 +0800
+Subject: gfs2: Fix possible data races in gfs2_show_options()
+
+From: Tuo Li <islituo@gmail.com>
+
+[ Upstream commit 6fa0a72cbbe45db4ed967a51f9e6f4e3afe61d20 ]
+
+Some fields such as gt_logd_secs of the struct gfs2_tune are accessed
+without holding the lock gt_spin in gfs2_show_options():
+
+  val = sdp->sd_tune.gt_logd_secs;
+  if (val != 30)
+    seq_printf(s, ",commit=%d", val);
+
+And thus can cause data races when gfs2_show_options() and other functions
+such as gfs2_reconfigure() are concurrently executed:
+
+  spin_lock(&gt->gt_spin);
+  gt->gt_logd_secs = newargs->ar_commit;
+
+To fix these possible data races, the lock sdp->sd_tune.gt_spin is
+acquired before accessing the fields of gfs2_tune and released after these
+accesses.
+
+Further changes by Andreas:
+
+- Don't hold the spin lock over the seq_printf operations.
+
+Reported-by: BassCheck <bass@buaa.edu.cn>
+Signed-off-by: Tuo Li <islituo@gmail.com>
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/super.c | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
+index bb0eaa4638e3c..29157f7d9663d 100644
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -1374,7 +1374,14 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root)
+ {
+       struct gfs2_sbd *sdp = root->d_sb->s_fs_info;
+       struct gfs2_args *args = &sdp->sd_args;
+-      int val;
++      unsigned int logd_secs, statfs_slow, statfs_quantum, quota_quantum;
++
++      spin_lock(&sdp->sd_tune.gt_spin);
++      logd_secs = sdp->sd_tune.gt_logd_secs;
++      quota_quantum = sdp->sd_tune.gt_quota_quantum;
++      statfs_quantum = sdp->sd_tune.gt_statfs_quantum;
++      statfs_slow = sdp->sd_tune.gt_statfs_slow;
++      spin_unlock(&sdp->sd_tune.gt_spin);
+       if (is_ancestor(root, sdp->sd_master_dir))
+               seq_puts(s, ",meta");
+@@ -1429,17 +1436,14 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root)
+       }
+       if (args->ar_discard)
+               seq_puts(s, ",discard");
+-      val = sdp->sd_tune.gt_logd_secs;
+-      if (val != 30)
+-              seq_printf(s, ",commit=%d", val);
+-      val = sdp->sd_tune.gt_statfs_quantum;
+-      if (val != 30)
+-              seq_printf(s, ",statfs_quantum=%d", val);
+-      else if (sdp->sd_tune.gt_statfs_slow)
++      if (logd_secs != 30)
++              seq_printf(s, ",commit=%d", logd_secs);
++      if (statfs_quantum != 30)
++              seq_printf(s, ",statfs_quantum=%d", statfs_quantum);
++      else if (statfs_slow)
+               seq_puts(s, ",statfs_quantum=0");
+-      val = sdp->sd_tune.gt_quota_quantum;
+-      if (val != 60)
+-              seq_printf(s, ",quota_quantum=%d", val);
++      if (quota_quantum != 60)
++              seq_printf(s, ",quota_quantum=%d", quota_quantum);
+       if (args->ar_statfs_percent)
+               seq_printf(s, ",statfs_percent=%d", args->ar_statfs_percent);
+       if (args->ar_errors != GFS2_ERRORS_DEFAULT) {
+-- 
+2.40.1
+
diff --git a/queue-4.19/hid-add-quirk-for-03f0-464a-hp-elite-presenter-mouse.patch b/queue-4.19/hid-add-quirk-for-03f0-464a-hp-elite-presenter-mouse.patch
new file mode 100644 (file)
index 0000000..4ad108a
--- /dev/null
@@ -0,0 +1,54 @@
+From 8b2928c86cf74a5e698ca990f6bba7570780deb2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 15:40:08 +0200
+Subject: HID: add quirk for 03f0:464a HP Elite Presenter Mouse
+
+From: Marco Morandini <marco.morandini@polimi.it>
+
+[ Upstream commit 0db117359e47750d8bd310d19f13e1c4ef7fc26a ]
+
+HP Elite Presenter Mouse HID Record Descriptor shows
+two mouses (Repord ID 0x1 and 0x2), one keypad (Report ID 0x5),
+two Consumer Controls (Report IDs 0x6 and 0x3).
+Previous to this commit it registers one mouse, one keypad
+and one Consumer Control, and it was usable only as a
+digitl laser pointer (one of the two mouses). This patch defines
+the 464a USB device ID and enables the HID_QUIRK_MULTI_INPUT
+quirk for it, allowing to use the device both as a mouse
+and a digital laser pointer.
+
+Signed-off-by: Marco Morandini <marco.morandini@polimi.it>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-ids.h    | 1 +
+ drivers/hid/hid-quirks.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index c0ba8d6f4978f..a9d6f8acf70b5 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -571,6 +571,7 @@
+ #define USB_DEVICE_ID_UGCI_FIGHTING   0x0030
+ #define USB_VENDOR_ID_HP              0x03f0
++#define USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A          0x464a
+ #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A 0x0a4a
+ #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a
+ #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE                0x134a
+diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
+index 8de294aa3184a..a2ab338166e61 100644
+--- a/drivers/hid/hid-quirks.c
++++ b/drivers/hid/hid-quirks.c
+@@ -98,6 +98,7 @@ static const struct hid_device_id hid_quirks[] = {
+       { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096), HID_QUIRK_NO_INIT_REPORTS },
+       { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293), HID_QUIRK_ALWAYS_POLL },
+       { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A), HID_QUIRK_ALWAYS_POLL },
++      { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A), HID_QUIRK_MULTI_INPUT },
+       { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL },
+       { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
+       { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL },
+-- 
+2.40.1
+
diff --git a/queue-4.19/iio-adc-stx104-implement-and-utilize-register-struct.patch b/queue-4.19/iio-adc-stx104-implement-and-utilize-register-struct.patch
new file mode 100644 (file)
index 0000000..117b6c0
--- /dev/null
@@ -0,0 +1,213 @@
+From 01a0b9adf5bdd86d3a9e7fc0b24eb114f2fc8e47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 13:21:24 -0400
+Subject: iio: adc: stx104: Implement and utilize register structures
+
+From: William Breathitt Gray <william.gray@linaro.org>
+
+[ Upstream commit 6cfd14c54b1f42f29097244c1b6208f8268d7d5b ]
+
+Reduce magic numbers and improve code readability by implementing and
+utilizing named register data structures.
+
+Tested-by: Fred Eckert <Frede@cmslaser.com>
+Signed-off-by: William Breathitt Gray <william.gray@linaro.org>
+Link: https://lore.kernel.org/r/8cb91d5b53e57b066120e42ea07000d6c7ef5543.1657213745.git.william.gray@linaro.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 4f9b80aefb9e ("iio: addac: stx104: Fix race condition when converting analog-to-digital")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/stx104.c | 74 +++++++++++++++++++++++++++-------------
+ 1 file changed, 50 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/iio/adc/stx104.c b/drivers/iio/adc/stx104.c
+index bdc4281d9fdaf..c25523ecebab2 100644
+--- a/drivers/iio/adc/stx104.c
++++ b/drivers/iio/adc/stx104.c
+@@ -24,6 +24,7 @@
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/spinlock.h>
++#include <linux/types.h>
+ #define STX104_OUT_CHAN(chan) {                               \
+       .type = IIO_VOLTAGE,                            \
+@@ -52,14 +53,36 @@ static unsigned int num_stx104;
+ module_param_hw_array(base, uint, ioport, &num_stx104, 0);
+ MODULE_PARM_DESC(base, "Apex Embedded Systems STX104 base addresses");
++/**
++ * struct stx104_reg - device register structure
++ * @ssr_ad:   Software Strobe Register and ADC Data
++ * @achan:    ADC Channel
++ * @dio:      Digital I/O
++ * @dac:      DAC Channels
++ * @cir_asr:  Clear Interrupts and ADC Status
++ * @acr:      ADC Control
++ * @pccr_fsh: Pacer Clock Control and FIFO Status MSB
++ * @acfg:     ADC Configuration
++ */
++struct stx104_reg {
++      u16 ssr_ad;
++      u8 achan;
++      u8 dio;
++      u16 dac[2];
++      u8 cir_asr;
++      u8 acr;
++      u8 pccr_fsh;
++      u8 acfg;
++};
++
+ /**
+  * struct stx104_iio - IIO device private data structure
+  * @chan_out_states:  channels' output states
+- * @base:             base port address of the IIO device
++ * @reg:              I/O address offset for the device registers
+  */
+ struct stx104_iio {
+       unsigned int chan_out_states[STX104_NUM_OUT_CHAN];
+-      void __iomem *base;
++      struct stx104_reg __iomem *reg;
+ };
+ /**
+@@ -72,7 +95,7 @@ struct stx104_iio {
+ struct stx104_gpio {
+       struct gpio_chip chip;
+       spinlock_t lock;
+-      void __iomem *base;
++      u8 __iomem *base;
+       unsigned int out_state;
+ };
+@@ -80,6 +103,7 @@ static int stx104_read_raw(struct iio_dev *indio_dev,
+       struct iio_chan_spec const *chan, int *val, int *val2, long mask)
+ {
+       struct stx104_iio *const priv = iio_priv(indio_dev);
++      struct stx104_reg __iomem *const reg = priv->reg;
+       unsigned int adc_config;
+       int adbu;
+       int gain;
+@@ -87,7 +111,7 @@ static int stx104_read_raw(struct iio_dev *indio_dev,
+       switch (mask) {
+       case IIO_CHAN_INFO_HARDWAREGAIN:
+               /* get gain configuration */
+-              adc_config = ioread8(priv->base + 11);
++              adc_config = ioread8(&reg->acfg);
+               gain = adc_config & 0x3;
+               *val = 1 << gain;
+@@ -99,24 +123,26 @@ static int stx104_read_raw(struct iio_dev *indio_dev,
+               }
+               /* select ADC channel */
+-              iowrite8(chan->channel | (chan->channel << 4), priv->base + 2);
++              iowrite8(chan->channel | (chan->channel << 4), &reg->achan);
+-              /* trigger ADC sample capture and wait for completion */
+-              iowrite8(0, priv->base);
+-              while (ioread8(priv->base + 8) & BIT(7));
++              /* trigger ADC sample capture by writing to the 8-bit
++               * Software Strobe Register and wait for completion
++               */
++              iowrite8(0, &reg->ssr_ad);
++              while (ioread8(&reg->cir_asr) & BIT(7));
+-              *val = ioread16(priv->base);
++              *val = ioread16(&reg->ssr_ad);
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_OFFSET:
+               /* get ADC bipolar/unipolar configuration */
+-              adc_config = ioread8(priv->base + 11);
++              adc_config = ioread8(&reg->acfg);
+               adbu = !(adc_config & BIT(2));
+               *val = -32768 * adbu;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               /* get ADC bipolar/unipolar and gain configuration */
+-              adc_config = ioread8(priv->base + 11);
++              adc_config = ioread8(&reg->acfg);
+               adbu = !(adc_config & BIT(2));
+               gain = adc_config & 0x3;
+@@ -138,16 +164,16 @@ static int stx104_write_raw(struct iio_dev *indio_dev,
+               /* Only four gain states (x1, x2, x4, x8) */
+               switch (val) {
+               case 1:
+-                      iowrite8(0, priv->base + 11);
++                      iowrite8(0, &priv->reg->acfg);
+                       break;
+               case 2:
+-                      iowrite8(1, priv->base + 11);
++                      iowrite8(1, &priv->reg->acfg);
+                       break;
+               case 4:
+-                      iowrite8(2, priv->base + 11);
++                      iowrite8(2, &priv->reg->acfg);
+                       break;
+               case 8:
+-                      iowrite8(3, priv->base + 11);
++                      iowrite8(3, &priv->reg->acfg);
+                       break;
+               default:
+                       return -EINVAL;
+@@ -161,7 +187,7 @@ static int stx104_write_raw(struct iio_dev *indio_dev,
+                               return -EINVAL;
+                       priv->chan_out_states[chan->channel] = val;
+-                      iowrite16(val, priv->base + 4 + 2 * chan->channel);
++                      iowrite16(val, &priv->reg->dac[chan->channel]);
+                       return 0;
+               }
+@@ -315,15 +341,15 @@ static int stx104_probe(struct device *dev, unsigned int id)
+       }
+       priv = iio_priv(indio_dev);
+-      priv->base = devm_ioport_map(dev, base[id], STX104_EXTENT);
+-      if (!priv->base)
++      priv->reg = devm_ioport_map(dev, base[id], STX104_EXTENT);
++      if (!priv->reg)
+               return -ENOMEM;
+       indio_dev->info = &stx104_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       /* determine if differential inputs */
+-      if (ioread8(priv->base + 8) & BIT(5)) {
++      if (ioread8(&priv->reg->cir_asr) & BIT(5)) {
+               indio_dev->num_channels = ARRAY_SIZE(stx104_channels_diff);
+               indio_dev->channels = stx104_channels_diff;
+       } else {
+@@ -335,14 +361,14 @@ static int stx104_probe(struct device *dev, unsigned int id)
+       indio_dev->dev.parent = dev;
+       /* configure device for software trigger operation */
+-      iowrite8(0, priv->base + 9);
++      iowrite8(0, &priv->reg->acr);
+       /* initialize gain setting to x1 */
+-      iowrite8(0, priv->base + 11);
++      iowrite8(0, &priv->reg->acfg);
+       /* initialize DAC output to 0V */
+-      iowrite16(0, priv->base + 4);
+-      iowrite16(0, priv->base + 6);
++      iowrite16(0, &priv->reg->dac[0]);
++      iowrite16(0, &priv->reg->dac[1]);
+       stx104gpio->chip.label = dev_name(dev);
+       stx104gpio->chip.parent = dev;
+@@ -357,7 +383,7 @@ static int stx104_probe(struct device *dev, unsigned int id)
+       stx104gpio->chip.get_multiple = stx104_gpio_get_multiple;
+       stx104gpio->chip.set = stx104_gpio_set;
+       stx104gpio->chip.set_multiple = stx104_gpio_set_multiple;
+-      stx104gpio->base = priv->base + 3;
++      stx104gpio->base = &priv->reg->dio;
+       stx104gpio->out_state = 0x0;
+       spin_lock_init(&stx104gpio->lock);
+-- 
+2.40.1
+
diff --git a/queue-4.19/iio-adc-stx104-utilize-iomap-interface.patch b/queue-4.19/iio-adc-stx104-utilize-iomap-interface.patch
new file mode 100644 (file)
index 0000000..eedbace
--- /dev/null
@@ -0,0 +1,206 @@
+From 78c12340236da83257794603494c7af355be3fdd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 May 2022 13:30:59 -0400
+Subject: iio: adc: stx104: Utilize iomap interface
+
+From: William Breathitt Gray <william.gray@linaro.org>
+
+[ Upstream commit 73b8390cc27e096ab157be261ccc4eaaa6db87af ]
+
+This driver doesn't need to access I/O ports directly via inb()/outb()
+and friends. This patch abstracts such access by calling ioport_map()
+to enable the use of more typical ioread8()/iowrite8() I/O memory
+accessor calls.
+
+Suggested-by: David Laight <David.Laight@ACULAB.COM>
+Signed-off-by: William Breathitt Gray <william.gray@linaro.org>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/64673797df382c52fc32fce24348b25a0b05e73a.1652201921.git.william.gray@linaro.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 4f9b80aefb9e ("iio: addac: stx104: Fix race condition when converting analog-to-digital")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/stx104.c | 56 +++++++++++++++++++++-------------------
+ 1 file changed, 29 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/iio/adc/stx104.c b/drivers/iio/adc/stx104.c
+index 0662ca199eb0b..bdc4281d9fdaf 100644
+--- a/drivers/iio/adc/stx104.c
++++ b/drivers/iio/adc/stx104.c
+@@ -59,7 +59,7 @@ MODULE_PARM_DESC(base, "Apex Embedded Systems STX104 base addresses");
+  */
+ struct stx104_iio {
+       unsigned int chan_out_states[STX104_NUM_OUT_CHAN];
+-      unsigned int base;
++      void __iomem *base;
+ };
+ /**
+@@ -72,7 +72,7 @@ struct stx104_iio {
+ struct stx104_gpio {
+       struct gpio_chip chip;
+       spinlock_t lock;
+-      unsigned int base;
++      void __iomem *base;
+       unsigned int out_state;
+ };
+@@ -87,7 +87,7 @@ static int stx104_read_raw(struct iio_dev *indio_dev,
+       switch (mask) {
+       case IIO_CHAN_INFO_HARDWAREGAIN:
+               /* get gain configuration */
+-              adc_config = inb(priv->base + 11);
++              adc_config = ioread8(priv->base + 11);
+               gain = adc_config & 0x3;
+               *val = 1 << gain;
+@@ -99,24 +99,24 @@ static int stx104_read_raw(struct iio_dev *indio_dev,
+               }
+               /* select ADC channel */
+-              outb(chan->channel | (chan->channel << 4), priv->base + 2);
++              iowrite8(chan->channel | (chan->channel << 4), priv->base + 2);
+               /* trigger ADC sample capture and wait for completion */
+-              outb(0, priv->base);
+-              while (inb(priv->base + 8) & BIT(7));
++              iowrite8(0, priv->base);
++              while (ioread8(priv->base + 8) & BIT(7));
+-              *val = inw(priv->base);
++              *val = ioread16(priv->base);
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_OFFSET:
+               /* get ADC bipolar/unipolar configuration */
+-              adc_config = inb(priv->base + 11);
++              adc_config = ioread8(priv->base + 11);
+               adbu = !(adc_config & BIT(2));
+               *val = -32768 * adbu;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               /* get ADC bipolar/unipolar and gain configuration */
+-              adc_config = inb(priv->base + 11);
++              adc_config = ioread8(priv->base + 11);
+               adbu = !(adc_config & BIT(2));
+               gain = adc_config & 0x3;
+@@ -138,16 +138,16 @@ static int stx104_write_raw(struct iio_dev *indio_dev,
+               /* Only four gain states (x1, x2, x4, x8) */
+               switch (val) {
+               case 1:
+-                      outb(0, priv->base + 11);
++                      iowrite8(0, priv->base + 11);
+                       break;
+               case 2:
+-                      outb(1, priv->base + 11);
++                      iowrite8(1, priv->base + 11);
+                       break;
+               case 4:
+-                      outb(2, priv->base + 11);
++                      iowrite8(2, priv->base + 11);
+                       break;
+               case 8:
+-                      outb(3, priv->base + 11);
++                      iowrite8(3, priv->base + 11);
+                       break;
+               default:
+                       return -EINVAL;
+@@ -161,7 +161,7 @@ static int stx104_write_raw(struct iio_dev *indio_dev,
+                               return -EINVAL;
+                       priv->chan_out_states[chan->channel] = val;
+-                      outw(val, priv->base + 4 + 2 * chan->channel);
++                      iowrite16(val, priv->base + 4 + 2 * chan->channel);
+                       return 0;
+               }
+@@ -230,7 +230,7 @@ static int stx104_gpio_get(struct gpio_chip *chip, unsigned int offset)
+       if (offset >= 4)
+               return -EINVAL;
+-      return !!(inb(stx104gpio->base) & BIT(offset));
++      return !!(ioread8(stx104gpio->base) & BIT(offset));
+ }
+ static int stx104_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
+@@ -238,7 +238,7 @@ static int stx104_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
+ {
+       struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip);
+-      *bits = inb(stx104gpio->base);
++      *bits = ioread8(stx104gpio->base);
+       return 0;
+ }
+@@ -260,7 +260,7 @@ static void stx104_gpio_set(struct gpio_chip *chip, unsigned int offset,
+       else
+               stx104gpio->out_state &= ~mask;
+-      outb(stx104gpio->out_state, stx104gpio->base);
++      iowrite8(stx104gpio->out_state, stx104gpio->base);
+       spin_unlock_irqrestore(&stx104gpio->lock, flags);
+ }
+@@ -287,7 +287,7 @@ static void stx104_gpio_set_multiple(struct gpio_chip *chip,
+       stx104gpio->out_state &= ~*mask;
+       stx104gpio->out_state |= *mask & *bits;
+-      outb(stx104gpio->out_state, stx104gpio->base);
++      iowrite8(stx104gpio->out_state, stx104gpio->base);
+       spin_unlock_irqrestore(&stx104gpio->lock, flags);
+ }
+@@ -314,11 +314,16 @@ static int stx104_probe(struct device *dev, unsigned int id)
+               return -EBUSY;
+       }
++      priv = iio_priv(indio_dev);
++      priv->base = devm_ioport_map(dev, base[id], STX104_EXTENT);
++      if (!priv->base)
++              return -ENOMEM;
++
+       indio_dev->info = &stx104_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       /* determine if differential inputs */
+-      if (inb(base[id] + 8) & BIT(5)) {
++      if (ioread8(priv->base + 8) & BIT(5)) {
+               indio_dev->num_channels = ARRAY_SIZE(stx104_channels_diff);
+               indio_dev->channels = stx104_channels_diff;
+       } else {
+@@ -329,18 +334,15 @@ static int stx104_probe(struct device *dev, unsigned int id)
+       indio_dev->name = dev_name(dev);
+       indio_dev->dev.parent = dev;
+-      priv = iio_priv(indio_dev);
+-      priv->base = base[id];
+-
+       /* configure device for software trigger operation */
+-      outb(0, base[id] + 9);
++      iowrite8(0, priv->base + 9);
+       /* initialize gain setting to x1 */
+-      outb(0, base[id] + 11);
++      iowrite8(0, priv->base + 11);
+       /* initialize DAC output to 0V */
+-      outw(0, base[id] + 4);
+-      outw(0, base[id] + 6);
++      iowrite16(0, priv->base + 4);
++      iowrite16(0, priv->base + 6);
+       stx104gpio->chip.label = dev_name(dev);
+       stx104gpio->chip.parent = dev;
+@@ -355,7 +357,7 @@ static int stx104_probe(struct device *dev, unsigned int id)
+       stx104gpio->chip.get_multiple = stx104_gpio_get_multiple;
+       stx104gpio->chip.set = stx104_gpio_set;
+       stx104gpio->chip.set_multiple = stx104_gpio_set_multiple;
+-      stx104gpio->base = base[id] + 3;
++      stx104gpio->base = priv->base + 3;
+       stx104gpio->out_state = 0x0;
+       spin_lock_init(&stx104gpio->lock);
+-- 
+2.40.1
+
diff --git a/queue-4.19/iio-add-addac-subdirectory.patch b/queue-4.19/iio-add-addac-subdirectory.patch
new file mode 100644 (file)
index 0000000..4aff009
--- /dev/null
@@ -0,0 +1,78 @@
+From 38d6fea16ab4e19911c67a8e5d0203e9b8c25d64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Dec 2021 13:40:43 +0200
+Subject: iio: add addac subdirectory
+
+From: Cosmin Tanislav <demonsingur@gmail.com>
+
+[ Upstream commit b62e2e1763cda3a6c494ed754317f19be1249297 ]
+
+For IIO devices that expose both ADC and DAC functionality.
+
+Signed-off-by: Cosmin Tanislav <cosmin.tanislav@analog.com>
+Link: https://lore.kernel.org/r/20211205114045.173612-2-cosmin.tanislav@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 4f9b80aefb9e ("iio: addac: stx104: Fix race condition when converting analog-to-digital")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/Kconfig        | 1 +
+ drivers/iio/Makefile       | 1 +
+ drivers/iio/addac/Kconfig  | 8 ++++++++
+ drivers/iio/addac/Makefile | 6 ++++++
+ 4 files changed, 16 insertions(+)
+ create mode 100644 drivers/iio/addac/Kconfig
+ create mode 100644 drivers/iio/addac/Makefile
+
+diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
+index d08aeb41cd078..810e72e4e8b7d 100644
+--- a/drivers/iio/Kconfig
++++ b/drivers/iio/Kconfig
+@@ -70,6 +70,7 @@ config IIO_TRIGGERED_EVENT
+ source "drivers/iio/accel/Kconfig"
+ source "drivers/iio/adc/Kconfig"
++source "drivers/iio/addac/Kconfig"
+ source "drivers/iio/afe/Kconfig"
+ source "drivers/iio/amplifiers/Kconfig"
+ source "drivers/iio/chemical/Kconfig"
+diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
+index cb5993251381e..a60d0cbfe4cd2 100644
+--- a/drivers/iio/Makefile
++++ b/drivers/iio/Makefile
+@@ -15,6 +15,7 @@ obj-$(CONFIG_IIO_TRIGGERED_EVENT) += industrialio-triggered-event.o
+ obj-y += accel/
+ obj-y += adc/
++obj-y += addac/
+ obj-y += afe/
+ obj-y += amplifiers/
+ obj-y += buffer/
+diff --git a/drivers/iio/addac/Kconfig b/drivers/iio/addac/Kconfig
+new file mode 100644
+index 0000000000000..2e64d7755d5ea
+--- /dev/null
++++ b/drivers/iio/addac/Kconfig
+@@ -0,0 +1,8 @@
++#
++# ADC DAC drivers
++#
++# When adding new entries keep the list in alphabetical order
++
++menu "Analog to digital and digital to analog converters"
++
++endmenu
+diff --git a/drivers/iio/addac/Makefile b/drivers/iio/addac/Makefile
+new file mode 100644
+index 0000000000000..b888b9ee12da0
+--- /dev/null
++++ b/drivers/iio/addac/Makefile
+@@ -0,0 +1,6 @@
++# SPDX-License-Identifier: GPL-2.0
++#
++# Makefile for industrial I/O ADDAC drivers
++#
++
++# When adding new entries keep the list in alphabetical order
+-- 
+2.40.1
+
diff --git a/queue-4.19/iio-addac-stx104-fix-race-condition-for-stx104_write.patch b/queue-4.19/iio-addac-stx104-fix-race-condition-for-stx104_write.patch
new file mode 100644 (file)
index 0000000..b3abbe5
--- /dev/null
@@ -0,0 +1,74 @@
+From f2770b749c9896c514acf77cd4370c57ca851e60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Apr 2023 10:40:10 -0400
+Subject: iio: addac: stx104: Fix race condition for stx104_write_raw()
+
+From: William Breathitt Gray <william.gray@linaro.org>
+
+[ Upstream commit 9740827468cea80c42db29e7171a50e99acf7328 ]
+
+The priv->chan_out_states array and actual DAC value can become
+mismatched if stx104_write_raw() is called concurrently. Prevent such a
+race condition by utilizing a mutex.
+
+Fixes: 97a445dad37a ("iio: Add IIO support for the DAC on the Apex Embedded Systems STX104")
+Signed-off-by: William Breathitt Gray <william.gray@linaro.org>
+Link: https://lore.kernel.org/r/c95c9a77fcef36b2a052282146950f23bbc1ebdc.1680790580.git.william.gray@linaro.org
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 4f9b80aefb9e ("iio: addac: stx104: Fix race condition when converting analog-to-digital")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/stx104.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/iio/adc/stx104.c b/drivers/iio/adc/stx104.c
+index c25523ecebab2..78e87d1aaaefb 100644
+--- a/drivers/iio/adc/stx104.c
++++ b/drivers/iio/adc/stx104.c
+@@ -23,6 +23,7 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
++#include <linux/mutex.h>
+ #include <linux/spinlock.h>
+ #include <linux/types.h>
+@@ -77,10 +78,12 @@ struct stx104_reg {
+ /**
+  * struct stx104_iio - IIO device private data structure
++ * @lock: synchronization lock to prevent I/O race conditions
+  * @chan_out_states:  channels' output states
+  * @reg:              I/O address offset for the device registers
+  */
+ struct stx104_iio {
++      struct mutex lock;
+       unsigned int chan_out_states[STX104_NUM_OUT_CHAN];
+       struct stx104_reg __iomem *reg;
+ };
+@@ -186,9 +189,12 @@ static int stx104_write_raw(struct iio_dev *indio_dev,
+                       if ((unsigned int)val > 65535)
+                               return -EINVAL;
++                      mutex_lock(&priv->lock);
++
+                       priv->chan_out_states[chan->channel] = val;
+                       iowrite16(val, &priv->reg->dac[chan->channel]);
++                      mutex_unlock(&priv->lock);
+                       return 0;
+               }
+               return -EINVAL;
+@@ -360,6 +366,8 @@ static int stx104_probe(struct device *dev, unsigned int id)
+       indio_dev->name = dev_name(dev);
+       indio_dev->dev.parent = dev;
++      mutex_init(&priv->lock);
++
+       /* configure device for software trigger operation */
+       iowrite8(0, &priv->reg->acr);
+-- 
+2.40.1
+
diff --git a/queue-4.19/iio-addac-stx104-fix-race-condition-when-converting-.patch b/queue-4.19/iio-addac-stx104-fix-race-condition-when-converting-.patch
new file mode 100644 (file)
index 0000000..4d4daf3
--- /dev/null
@@ -0,0 +1,50 @@
+From 469195b93471bed37b6ff7d9a81c6f8f9e427690 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Apr 2023 10:40:11 -0400
+Subject: iio: addac: stx104: Fix race condition when converting
+ analog-to-digital
+
+From: William Breathitt Gray <william.gray@linaro.org>
+
+[ Upstream commit 4f9b80aefb9e2f542a49d9ec087cf5919730e1dd ]
+
+The ADC conversion procedure requires several device I/O operations
+performed in a particular sequence. If stx104_read_raw() is called
+concurrently, the ADC conversion procedure could be clobbered. Prevent
+such a race condition by utilizing a mutex.
+
+Fixes: 4075a283ae83 ("iio: stx104: Add IIO support for the ADC channels")
+Signed-off-by: William Breathitt Gray <william.gray@linaro.org>
+Link: https://lore.kernel.org/r/2ae5e40eed5006ca735e4c12181a9ff5ced65547.1680790580.git.william.gray@linaro.org
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/stx104.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/iio/adc/stx104.c b/drivers/iio/adc/stx104.c
+index 78e87d1aaaefb..49aeb76212fd0 100644
+--- a/drivers/iio/adc/stx104.c
++++ b/drivers/iio/adc/stx104.c
+@@ -125,6 +125,8 @@ static int stx104_read_raw(struct iio_dev *indio_dev,
+                       return IIO_VAL_INT;
+               }
++              mutex_lock(&priv->lock);
++
+               /* select ADC channel */
+               iowrite8(chan->channel | (chan->channel << 4), &reg->achan);
+@@ -135,6 +137,8 @@ static int stx104_read_raw(struct iio_dev *indio_dev,
+               while (ioread8(&reg->cir_asr) & BIT(7));
+               *val = ioread16(&reg->ssr_ad);
++
++              mutex_unlock(&priv->lock);
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_OFFSET:
+               /* get ADC bipolar/unipolar configuration */
+-- 
+2.40.1
+
diff --git a/queue-4.19/ima-allow-fix-uml-builds.patch b/queue-4.19/ima-allow-fix-uml-builds.patch
new file mode 100644 (file)
index 0000000..956f98b
--- /dev/null
@@ -0,0 +1,56 @@
+From df9d89da2061d1cdc29a5604ea48f38d81030fb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Feb 2023 19:27:03 -0800
+Subject: IMA: allow/fix UML builds
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 644f17412f5acf01a19af9d04a921937a2bc86c6 ]
+
+UML supports HAS_IOMEM since 0bbadafdc49d (um: allow disabling
+NO_IOMEM).
+
+Current IMA build on UML fails on allmodconfig (with TCG_TPM=m):
+
+ld: security/integrity/ima/ima_queue.o: in function `ima_add_template_entry':
+ima_queue.c:(.text+0x2d9): undefined reference to `tpm_pcr_extend'
+ld: security/integrity/ima/ima_init.o: in function `ima_init':
+ima_init.c:(.init.text+0x43f): undefined reference to `tpm_default_chip'
+ld: security/integrity/ima/ima_crypto.o: in function `ima_calc_boot_aggregate_tfm':
+ima_crypto.c:(.text+0x1044): undefined reference to `tpm_pcr_read'
+ld: ima_crypto.c:(.text+0x10d8): undefined reference to `tpm_pcr_read'
+
+Modify the IMA Kconfig entry so that it selects TCG_TPM if HAS_IOMEM
+is set, regardless of the UML Kconfig setting.
+This updates TCG_TPM from =m to =y and fixes the linker errors.
+
+Fixes: f4a0391dfa91 ("ima: fix Kconfig dependencies")
+Cc: Stable <stable@vger.kernel.org> # v5.14+
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Fabio Estevam <festevam@gmail.com>
+Cc: Richard Weinberger <richard@nod.at>
+Cc: Anton Ivanov <anton.ivanov@cambridgegreys.com>
+Cc: Johannes Berg <johannes@sipsolutions.net>
+Cc: linux-um@lists.infradead.org
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/ima/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
+index 3ec45028a8c54..cd32fe3311afe 100644
+--- a/security/integrity/ima/Kconfig
++++ b/security/integrity/ima/Kconfig
+@@ -7,7 +7,7 @@ config IMA
+       select CRYPTO_HMAC
+       select CRYPTO_SHA1
+       select CRYPTO_HASH_INFO
+-      select TCG_TPM if HAS_IOMEM && !UML
++      select TCG_TPM if HAS_IOMEM
+       select TCG_TIS if TCG_TPM && X86
+       select TCG_CRB if TCG_TPM && ACPI
+       select TCG_IBMVTPM if TCG_TPM && PPC_PSERIES
+-- 
+2.40.1
+
diff --git a/queue-4.19/irqchip-mips-gic-get-rid-of-the-reliance-on-irq_cpu_.patch b/queue-4.19/irqchip-mips-gic-get-rid-of-the-reliance-on-irq_cpu_.patch
new file mode 100644 (file)
index 0000000..f11baeb
--- /dev/null
@@ -0,0 +1,102 @@
+From 783736785dd7f5d88565e7c874dccbd1b284ec30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Oct 2021 18:04:13 +0100
+Subject: irqchip/mips-gic: Get rid of the reliance on irq_cpu_online()
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit dd098a0e031928cf88c89f7577d31821e1f0e6de ]
+
+The MIPS GIC driver uses irq_cpu_online() to go and program the
+per-CPU interrupts. However, this method iterates over all IRQs
+in the system, despite only 3 per-CPU interrupts being of interest.
+
+Let's be terribly bold and do the iteration ourselves. To ensure
+mutual exclusion, hold the gic_lock spinlock that is otherwise
+taken while dealing with these interrupts.
+
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Tested-by: Serge Semin <fancer.lancer@gmail.com>
+Link: https://lore.kernel.org/r/20211021170414.3341522-3-maz@kernel.org
+Stable-dep-of: 3d6a0e4197c0 ("irqchip/mips-gic: Use raw spinlock for gic_lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-mips-gic.c | 37 ++++++++++++++++++++++++----------
+ 1 file changed, 26 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
+index f3985469c2211..6b8c3dd0f76f4 100644
+--- a/drivers/irqchip/irq-mips-gic.c
++++ b/drivers/irqchip/irq-mips-gic.c
+@@ -380,24 +380,35 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
+       spin_unlock_irqrestore(&gic_lock, flags);
+ }
+-static void gic_all_vpes_irq_cpu_online(struct irq_data *d)
++static void gic_all_vpes_irq_cpu_online(void)
+ {
+-      struct gic_all_vpes_chip_data *cd;
+-      unsigned int intr;
++      static const unsigned int local_intrs[] = {
++              GIC_LOCAL_INT_TIMER,
++              GIC_LOCAL_INT_PERFCTR,
++              GIC_LOCAL_INT_FDC,
++      };
++      unsigned long flags;
++      int i;
+-      intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
+-      cd = irq_data_get_irq_chip_data(d);
++      spin_lock_irqsave(&gic_lock, flags);
+-      write_gic_vl_map(mips_gic_vx_map_reg(intr), cd->map);
+-      if (cd->mask)
+-              write_gic_vl_smask(BIT(intr));
++      for (i = 0; i < ARRAY_SIZE(local_intrs); i++) {
++              unsigned int intr = local_intrs[i];
++              struct gic_all_vpes_chip_data *cd;
++
++              cd = &gic_all_vpes_chip_data[intr];
++              write_gic_vl_map(mips_gic_vx_map_reg(intr), cd->map);
++              if (cd->mask)
++                      write_gic_vl_smask(BIT(intr));
++      }
++
++      spin_unlock_irqrestore(&gic_lock, flags);
+ }
+ static struct irq_chip gic_all_vpes_local_irq_controller = {
+       .name                   = "MIPS GIC Local",
+       .irq_mask               = gic_mask_local_irq_all_vpes,
+       .irq_unmask             = gic_unmask_local_irq_all_vpes,
+-      .irq_cpu_online         = gic_all_vpes_irq_cpu_online,
+ };
+ static void __gic_irq_dispatch(void)
+@@ -476,6 +487,10 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
+       intr = GIC_HWIRQ_TO_LOCAL(hwirq);
+       map = GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin;
++      /*
++       * If adding support for more per-cpu interrupts, keep the the
++       * array in gic_all_vpes_irq_cpu_online() in sync.
++       */
+       switch (intr) {
+       case GIC_LOCAL_INT_TIMER:
+               /* CONFIG_MIPS_CMP workaround (see __gic_init) */
+@@ -662,8 +677,8 @@ static int gic_cpu_startup(unsigned int cpu)
+       /* Clear all local IRQ masks (ie. disable all local interrupts) */
+       write_gic_vl_rmask(~0);
+-      /* Invoke irq_cpu_online callbacks to enable desired interrupts */
+-      irq_cpu_online();
++      /* Enable desired interrupts */
++      gic_all_vpes_irq_cpu_online();
+       return 0;
+ }
+-- 
+2.40.1
+
diff --git a/queue-4.19/irqchip-mips-gic-use-raw-spinlock-for-gic_lock.patch b/queue-4.19/irqchip-mips-gic-use-raw-spinlock-for-gic_lock.patch
new file mode 100644 (file)
index 0000000..29f4905
--- /dev/null
@@ -0,0 +1,163 @@
+From feb545b8c1569af0c5b6425f3ce4399cb2fc5865 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Apr 2023 11:31:56 +0100
+Subject: irqchip/mips-gic: Use raw spinlock for gic_lock
+
+From: Jiaxun Yang <jiaxun.yang@flygoat.com>
+
+[ Upstream commit 3d6a0e4197c04599d75d85a608c8bb16a630a38c ]
+
+Since we may hold gic_lock in hardirq context, use raw spinlock
+makes more sense given that it is for low-level interrupt handling
+routine and the critical section is small.
+
+Fixes BUG:
+
+[    0.426106] =============================
+[    0.426257] [ BUG: Invalid wait context ]
+[    0.426422] 6.3.0-rc7-next-20230421-dirty #54 Not tainted
+[    0.426638] -----------------------------
+[    0.426766] swapper/0/1 is trying to lock:
+[    0.426954] ffffffff8104e7b8 (gic_lock){....}-{3:3}, at: gic_set_type+0x30/08
+
+Fixes: 95150ae8b330 ("irqchip: mips-gic: Implement irq_set_type callback")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
+Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
+Tested-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20230424103156.66753-3-jiaxun.yang@flygoat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-mips-gic.c | 30 +++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
+index 6b8c3dd0f76f4..dd9b111038b06 100644
+--- a/drivers/irqchip/irq-mips-gic.c
++++ b/drivers/irqchip/irq-mips-gic.c
+@@ -48,7 +48,7 @@ void __iomem *mips_gic_base;
+ DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks);
+-static DEFINE_SPINLOCK(gic_lock);
++static DEFINE_RAW_SPINLOCK(gic_lock);
+ static struct irq_domain *gic_irq_domain;
+ static struct irq_domain *gic_ipi_domain;
+ static int gic_shared_intrs;
+@@ -207,7 +207,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
+       irq = GIC_HWIRQ_TO_SHARED(d->hwirq);
+-      spin_lock_irqsave(&gic_lock, flags);
++      raw_spin_lock_irqsave(&gic_lock, flags);
+       switch (type & IRQ_TYPE_SENSE_MASK) {
+       case IRQ_TYPE_EDGE_FALLING:
+               pol = GIC_POL_FALLING_EDGE;
+@@ -247,7 +247,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
+       else
+               irq_set_chip_handler_name_locked(d, &gic_level_irq_controller,
+                                                handle_level_irq, NULL);
+-      spin_unlock_irqrestore(&gic_lock, flags);
++      raw_spin_unlock_irqrestore(&gic_lock, flags);
+       return 0;
+ }
+@@ -265,7 +265,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
+               return -EINVAL;
+       /* Assumption : cpumask refers to a single CPU */
+-      spin_lock_irqsave(&gic_lock, flags);
++      raw_spin_lock_irqsave(&gic_lock, flags);
+       /* Re-route this IRQ */
+       write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpu)));
+@@ -276,7 +276,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
+               set_bit(irq, per_cpu_ptr(pcpu_masks, cpu));
+       irq_data_update_effective_affinity(d, cpumask_of(cpu));
+-      spin_unlock_irqrestore(&gic_lock, flags);
++      raw_spin_unlock_irqrestore(&gic_lock, flags);
+       return IRQ_SET_MASK_OK;
+ }
+@@ -354,12 +354,12 @@ static void gic_mask_local_irq_all_vpes(struct irq_data *d)
+       cd = irq_data_get_irq_chip_data(d);
+       cd->mask = false;
+-      spin_lock_irqsave(&gic_lock, flags);
++      raw_spin_lock_irqsave(&gic_lock, flags);
+       for_each_online_cpu(cpu) {
+               write_gic_vl_other(mips_cm_vp_id(cpu));
+               write_gic_vo_rmask(BIT(intr));
+       }
+-      spin_unlock_irqrestore(&gic_lock, flags);
++      raw_spin_unlock_irqrestore(&gic_lock, flags);
+ }
+ static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
+@@ -372,12 +372,12 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
+       cd = irq_data_get_irq_chip_data(d);
+       cd->mask = true;
+-      spin_lock_irqsave(&gic_lock, flags);
++      raw_spin_lock_irqsave(&gic_lock, flags);
+       for_each_online_cpu(cpu) {
+               write_gic_vl_other(mips_cm_vp_id(cpu));
+               write_gic_vo_smask(BIT(intr));
+       }
+-      spin_unlock_irqrestore(&gic_lock, flags);
++      raw_spin_unlock_irqrestore(&gic_lock, flags);
+ }
+ static void gic_all_vpes_irq_cpu_online(void)
+@@ -390,7 +390,7 @@ static void gic_all_vpes_irq_cpu_online(void)
+       unsigned long flags;
+       int i;
+-      spin_lock_irqsave(&gic_lock, flags);
++      raw_spin_lock_irqsave(&gic_lock, flags);
+       for (i = 0; i < ARRAY_SIZE(local_intrs); i++) {
+               unsigned int intr = local_intrs[i];
+@@ -402,7 +402,7 @@ static void gic_all_vpes_irq_cpu_online(void)
+                       write_gic_vl_smask(BIT(intr));
+       }
+-      spin_unlock_irqrestore(&gic_lock, flags);
++      raw_spin_unlock_irqrestore(&gic_lock, flags);
+ }
+ static struct irq_chip gic_all_vpes_local_irq_controller = {
+@@ -432,11 +432,11 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
+       data = irq_get_irq_data(virq);
+-      spin_lock_irqsave(&gic_lock, flags);
++      raw_spin_lock_irqsave(&gic_lock, flags);
+       write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);
+       write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu)));
+       irq_data_update_effective_affinity(data, cpumask_of(cpu));
+-      spin_unlock_irqrestore(&gic_lock, flags);
++      raw_spin_unlock_irqrestore(&gic_lock, flags);
+       return 0;
+ }
+@@ -529,12 +529,12 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
+       if (!gic_local_irq_is_routable(intr))
+               return -EPERM;
+-      spin_lock_irqsave(&gic_lock, flags);
++      raw_spin_lock_irqsave(&gic_lock, flags);
+       for_each_online_cpu(cpu) {
+               write_gic_vl_other(mips_cm_vp_id(cpu));
+               write_gic_vo_map(mips_gic_vx_map_reg(intr), map);
+       }
+-      spin_unlock_irqrestore(&gic_lock, flags);
++      raw_spin_unlock_irqrestore(&gic_lock, flags);
+       return 0;
+ }
+-- 
+2.40.1
+
diff --git a/queue-4.19/media-platform-mediatek-vpu-fix-null-ptr-dereference.patch b/queue-4.19/media-platform-mediatek-vpu-fix-null-ptr-dereference.patch
new file mode 100644 (file)
index 0000000..011aea6
--- /dev/null
@@ -0,0 +1,51 @@
+From b88cd36a1e94e801cef71aaf2c8d602d95fc9552 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 May 2023 13:11:47 +0100
+Subject: media: platform: mediatek: vpu: fix NULL ptr dereference
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+[ Upstream commit 3df55cd773e8603b623425cc97b05e542854ad27 ]
+
+If pdev is NULL, then it is still dereferenced.
+
+This fixes this smatch warning:
+
+drivers/media/platform/mediatek/vpu/mtk_vpu.c:570 vpu_load_firmware() warn: address of NULL pointer 'pdev'
+
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Cc: Yunfei Dong <yunfei.dong@mediatek.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mtk-vpu/mtk_vpu.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c
+index 9b57fb2857285..46ec1f2699aa7 100644
+--- a/drivers/media/platform/mtk-vpu/mtk_vpu.c
++++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c
+@@ -537,16 +537,18 @@ static int load_requested_vpu(struct mtk_vpu *vpu,
+ int vpu_load_firmware(struct platform_device *pdev)
+ {
+       struct mtk_vpu *vpu;
+-      struct device *dev = &pdev->dev;
++      struct device *dev;
+       struct vpu_run *run;
+       const struct firmware *vpu_fw = NULL;
+       int ret;
+       if (!pdev) {
+-              dev_err(dev, "VPU platform device is invalid\n");
++              pr_err("VPU platform device is invalid\n");
+               return -EINVAL;
+       }
++      dev = &pdev->dev;
++
+       vpu = platform_get_drvdata(pdev);
+       run = &vpu->run;
+-- 
+2.40.1
+
diff --git a/queue-4.19/media-v4l2-mem2mem-add-lock-to-protect-parameter-num.patch b/queue-4.19/media-v4l2-mem2mem-add-lock-to-protect-parameter-num.patch
new file mode 100644 (file)
index 0000000..639999f
--- /dev/null
@@ -0,0 +1,69 @@
+From 40c201c4158807ce01d9c26148cbeb6722ca4cd9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Apr 2023 16:17:40 +0800
+Subject: media: v4l2-mem2mem: add lock to protect parameter num_rdy
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yunfei Dong <yunfei.dong@mediatek.com>
+
+[ Upstream commit 56b5c3e67b0f9af3f45cf393be048ee8d8a92694 ]
+
+Getting below error when using KCSAN to check the driver. Adding lock to
+protect parameter num_rdy when getting the value with function:
+v4l2_m2m_num_src_bufs_ready/v4l2_m2m_num_dst_bufs_ready.
+
+kworker/u16:3: [name:report&]BUG: KCSAN: data-race in v4l2_m2m_buf_queue
+kworker/u16:3: [name:report&]
+
+kworker/u16:3: [name:report&]read-write to 0xffffff8105f35b94 of 1 bytes by task 20865 on cpu 7:
+kworker/u16:3:  v4l2_m2m_buf_queue+0xd8/0x10c
+
+Signed-off-by: Pina Chen <pina.chen@mediatek.com>
+Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/media/v4l2-mem2mem.h | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
+index d655720e16a15..62c67e9e190c0 100644
+--- a/include/media/v4l2-mem2mem.h
++++ b/include/media/v4l2-mem2mem.h
+@@ -405,7 +405,14 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx,
+ static inline
+ unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
+ {
+-      return m2m_ctx->out_q_ctx.num_rdy;
++      unsigned int num_buf_rdy;
++      unsigned long flags;
++
++      spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
++      num_buf_rdy = m2m_ctx->out_q_ctx.num_rdy;
++      spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
++
++      return num_buf_rdy;
+ }
+ /**
+@@ -417,7 +424,14 @@ unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
+ static inline
+ unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
+ {
+-      return m2m_ctx->cap_q_ctx.num_rdy;
++      unsigned int num_buf_rdy;
++      unsigned long flags;
++
++      spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags);
++      num_buf_rdy = m2m_ctx->cap_q_ctx.num_rdy;
++      spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags);
++
++      return num_buf_rdy;
+ }
+ /**
+-- 
+2.40.1
+
diff --git a/queue-4.19/mips-dec-prom-address-warray-bounds-warning.patch b/queue-4.19/mips-dec-prom-address-warray-bounds-warning.patch
new file mode 100644 (file)
index 0000000..c46cd73
--- /dev/null
@@ -0,0 +1,54 @@
+From ccf3d6017197970c2a17a3d970844de937b2e5cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Jun 2023 17:43:57 -0600
+Subject: MIPS: dec: prom: Address -Warray-bounds warning
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit 7b191b9b55df2a844bd32d1d380f47a7df1c2896 ]
+
+Zero-length arrays are deprecated, and we are replacing them with flexible
+array members instead. So, replace zero-length array with flexible-array
+member in struct memmap.
+
+Address the following warning found after building (with GCC-13) mips64
+with decstation_64_defconfig:
+In function 'rex_setup_memory_region',
+    inlined from 'prom_meminit' at arch/mips/dec/prom/memory.c:91:3:
+arch/mips/dec/prom/memory.c:72:31: error: array subscript i is outside array bounds of 'unsigned char[0]' [-Werror=array-bounds=]
+   72 |                 if (bm->bitmap[i] == 0xff)
+      |                     ~~~~~~~~~~^~~
+In file included from arch/mips/dec/prom/memory.c:16:
+./arch/mips/include/asm/dec/prom.h: In function 'prom_meminit':
+./arch/mips/include/asm/dec/prom.h:73:23: note: while referencing 'bitmap'
+   73 |         unsigned char bitmap[0];
+
+This helps with the ongoing efforts to globally enable -Warray-bounds.
+
+This results in no differences in binary output.
+
+Link: https://github.com/KSPP/linux/issues/79
+Link: https://github.com/KSPP/linux/issues/323
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/include/asm/dec/prom.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/mips/include/asm/dec/prom.h b/arch/mips/include/asm/dec/prom.h
+index 09538ff5e9245..6f0405ba27d6d 100644
+--- a/arch/mips/include/asm/dec/prom.h
++++ b/arch/mips/include/asm/dec/prom.h
+@@ -74,7 +74,7 @@ static inline bool prom_is_rex(u32 magic)
+  */
+ typedef struct {
+       int pagesize;
+-      unsigned char bitmap[0];
++      unsigned char bitmap[];
+ } memmap;
+-- 
+2.40.1
+
diff --git a/queue-4.19/mmc-bcm2835-fix-deferred-probing.patch b/queue-4.19/mmc-bcm2835-fix-deferred-probing.patch
new file mode 100644 (file)
index 0000000..fe1406c
--- /dev/null
@@ -0,0 +1,44 @@
+From 42a2baffe81d41706371f8a900d0cc33baa787a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Jun 2023 23:36:11 +0300
+Subject: mmc: bcm2835: fix deferred probing
+
+From: Sergey Shtylyov <s.shtylyov@omp.ru>
+
+[ Upstream commit 71150ac12558bcd9d75e6e24cf7c872c2efd80f3 ]
+
+The driver overrides the error codes and IRQ0 returned by platform_get_irq()
+to -EINVAL, so if it returns -EPROBE_DEFER, the driver will fail the probe
+permanently instead of the deferred probing. Switch to propagating the error
+codes upstream.  Since commit ce753ad1549c ("platform: finally disallow IRQ0
+in platform_get_irq() and its ilk") IRQ0 is no longer returned by those APIs,
+so we now can safely ignore it...
+
+Fixes: 660fc733bd74 ("mmc: bcm2835: Add new driver for the sdhost controller.")
+Cc: stable@vger.kernel.org # v5.19+
+Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Link: https://lore.kernel.org/r/20230617203622.6812-2-s.shtylyov@omp.ru
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/bcm2835.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
+index 11026474dda47..2b3ff4be7ae07 100644
+--- a/drivers/mmc/host/bcm2835.c
++++ b/drivers/mmc/host/bcm2835.c
+@@ -1417,8 +1417,8 @@ static int bcm2835_probe(struct platform_device *pdev)
+       host->max_clk = clk_get_rate(clk);
+       host->irq = platform_get_irq(pdev, 0);
+-      if (host->irq <= 0) {
+-              ret = -EINVAL;
++      if (host->irq < 0) {
++              ret = host->irq;
+               goto err;
+       }
+-- 
+2.40.1
+
diff --git a/queue-4.19/mmc-meson-gx-remove-redundant-mmc_request_done-call-.patch b/queue-4.19/mmc-meson-gx-remove-redundant-mmc_request_done-call-.patch
new file mode 100644 (file)
index 0000000..f8535ff
--- /dev/null
@@ -0,0 +1,107 @@
+From 3ec73050704ec7d9f7659012445d9210aa478ebc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jun 2023 10:27:12 +0200
+Subject: mmc: meson-gx: remove redundant mmc_request_done() call from irq
+ context
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Martin Hundebøll <martin@geanix.com>
+
+[ Upstream commit 3c40eb8145325b0f5b93b8a169146078cb2c49d6 ]
+
+The call to mmc_request_done() can schedule, so it must not be called
+from irq context. Wake the irq thread if it needs to be called, and let
+its existing logic do its work.
+
+Fixes the following kernel bug, which appears when running an RT patched
+kernel on the AmLogic Meson AXG A113X SoC:
+[   11.111407] BUG: scheduling while atomic: kworker/0:1H/75/0x00010001
+[   11.111438] Modules linked in:
+[   11.111451] CPU: 0 PID: 75 Comm: kworker/0:1H Not tainted 6.4.0-rc3-rt2-rtx-00081-gfd07f41ed6b4-dirty #1
+[   11.111461] Hardware name: RTX AXG A113X Linux Platform Board (DT)
+[   11.111469] Workqueue: kblockd blk_mq_run_work_fn
+[   11.111492] Call trace:
+[   11.111497]  dump_backtrace+0xac/0xe8
+[   11.111510]  show_stack+0x18/0x28
+[   11.111518]  dump_stack_lvl+0x48/0x60
+[   11.111530]  dump_stack+0x18/0x24
+[   11.111537]  __schedule_bug+0x4c/0x68
+[   11.111548]  __schedule+0x80/0x574
+[   11.111558]  schedule_loop+0x2c/0x50
+[   11.111567]  schedule_rtlock+0x14/0x20
+[   11.111576]  rtlock_slowlock_locked+0x468/0x730
+[   11.111587]  rt_spin_lock+0x40/0x64
+[   11.111596]  __wake_up_common_lock+0x5c/0xc4
+[   11.111610]  __wake_up+0x18/0x24
+[   11.111620]  mmc_blk_mq_req_done+0x68/0x138
+[   11.111633]  mmc_request_done+0x104/0x118
+[   11.111644]  meson_mmc_request_done+0x38/0x48
+[   11.111654]  meson_mmc_irq+0x128/0x1f0
+[   11.111663]  __handle_irq_event_percpu+0x70/0x114
+[   11.111674]  handle_irq_event_percpu+0x18/0x4c
+[   11.111683]  handle_irq_event+0x80/0xb8
+[   11.111691]  handle_fasteoi_irq+0xa4/0x120
+[   11.111704]  handle_irq_desc+0x20/0x38
+[   11.111712]  generic_handle_domain_irq+0x1c/0x28
+[   11.111721]  gic_handle_irq+0x8c/0xa8
+[   11.111735]  call_on_irq_stack+0x24/0x4c
+[   11.111746]  do_interrupt_handler+0x88/0x94
+[   11.111757]  el1_interrupt+0x34/0x64
+[   11.111769]  el1h_64_irq_handler+0x18/0x24
+[   11.111779]  el1h_64_irq+0x64/0x68
+[   11.111786]  __add_wait_queue+0x0/0x4c
+[   11.111795]  mmc_blk_rw_wait+0x84/0x118
+[   11.111804]  mmc_blk_mq_issue_rq+0x5c4/0x654
+[   11.111814]  mmc_mq_queue_rq+0x194/0x214
+[   11.111822]  blk_mq_dispatch_rq_list+0x3ac/0x528
+[   11.111834]  __blk_mq_sched_dispatch_requests+0x340/0x4d0
+[   11.111847]  blk_mq_sched_dispatch_requests+0x38/0x70
+[   11.111858]  blk_mq_run_work_fn+0x3c/0x70
+[   11.111865]  process_one_work+0x17c/0x1f0
+[   11.111876]  worker_thread+0x1d4/0x26c
+[   11.111885]  kthread+0xe4/0xf4
+[   11.111894]  ret_from_fork+0x10/0x20
+
+Fixes: 51c5d8447bd7 ("MMC: meson: initial support for GX platforms")
+Cc: stable@vger.kernel.org
+Signed-off-by: Martin Hundebøll <martin@geanix.com>
+Link: https://lore.kernel.org/r/20230607082713.517157-1-martin@geanix.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/meson-gx-mmc.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
+index 313aff92b97c9..a3e5be81b4660 100644
+--- a/drivers/mmc/host/meson-gx-mmc.c
++++ b/drivers/mmc/host/meson-gx-mmc.c
+@@ -1067,11 +1067,8 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
+       if (status & (IRQ_END_OF_CHAIN | IRQ_RESP_STATUS)) {
+               if (data && !cmd->error)
+                       data->bytes_xfered = data->blksz * data->blocks;
+-              if (meson_mmc_bounce_buf_read(data) ||
+-                  meson_mmc_get_next_command(cmd))
+-                      ret = IRQ_WAKE_THREAD;
+-              else
+-                      ret = IRQ_HANDLED;
++
++              return IRQ_WAKE_THREAD;
+       }
+ out:
+@@ -1086,9 +1083,6 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
+               writel(start, host->regs + SD_EMMC_START);
+       }
+-      if (ret == IRQ_HANDLED)
+-              meson_mmc_request_done(host->mmc, cmd->mrq);
+-
+       return ret;
+ }
+-- 
+2.40.1
+
diff --git a/queue-4.19/mmc-meson-gx-remove-useless-lock.patch b/queue-4.19/mmc-meson-gx-remove-useless-lock.patch
new file mode 100644 (file)
index 0000000..7c4eb37
--- /dev/null
@@ -0,0 +1,69 @@
+From 9f9d0e3644e24e7aab6eee0aaa5c2e79ce59c29d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Dec 2018 16:18:26 +0100
+Subject: mmc: meson-gx: remove useless lock
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit 83076d2268c72d123f3d1eaf186a9f56ec1b943a ]
+
+The spinlock is only used within the irq handler so it does not
+seem very useful.
+
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: 3c40eb814532 ("mmc: meson-gx: remove redundant mmc_request_done() call from irq context")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/meson-gx-mmc.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
+index dba98c2886f26..313aff92b97c9 100644
+--- a/drivers/mmc/host/meson-gx-mmc.c
++++ b/drivers/mmc/host/meson-gx-mmc.c
+@@ -26,7 +26,6 @@
+ #include <linux/of_device.h>
+ #include <linux/platform_device.h>
+ #include <linux/ioport.h>
+-#include <linux/spinlock.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/mmc/host.h>
+ #include <linux/mmc/mmc.h>
+@@ -159,7 +158,6 @@ struct meson_host {
+       struct  mmc_host        *mmc;
+       struct  mmc_command     *cmd;
+-      spinlock_t lock;
+       void __iomem *regs;
+       struct clk *core_clk;
+       struct clk *mmc_clk;
+@@ -1042,8 +1040,6 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
+       if (WARN_ON(!host) || WARN_ON(!host->cmd))
+               return IRQ_NONE;
+-      spin_lock(&host->lock);
+-
+       cmd = host->cmd;
+       data = cmd->data;
+       cmd->error = 0;
+@@ -1093,7 +1089,6 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
+       if (ret == IRQ_HANDLED)
+               meson_mmc_request_done(host->mmc, cmd->mrq);
+-      spin_unlock(&host->lock);
+       return ret;
+ }
+@@ -1246,8 +1241,6 @@ static int meson_mmc_probe(struct platform_device *pdev)
+       host->dev = &pdev->dev;
+       dev_set_drvdata(&pdev->dev, host);
+-      spin_lock_init(&host->lock);
+-
+       /* Get regulators and the supported OCR mask */
+       host->vqmmc_enabled = false;
+       ret = mmc_regulator_get_supply(mmc);
+-- 
+2.40.1
+
diff --git a/queue-4.19/mmc-remove-dev_err-usage-after-platform_get_irq.patch b/queue-4.19/mmc-remove-dev_err-usage-after-platform_get_irq.patch
new file mode 100644 (file)
index 0000000..f271b31
--- /dev/null
@@ -0,0 +1,204 @@
+From 5ef212e99d146c29d618d71f0704fe8737c9b128 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Jul 2019 11:15:29 -0700
+Subject: mmc: Remove dev_err() usage after platform_get_irq()
+
+From: Stephen Boyd <swboyd@chromium.org>
+
+[ Upstream commit 9a7957d0c9557f7780cdda970a2530d6351bd861 ]
+
+We don't need dev_err() messages when platform_get_irq() fails now that
+platform_get_irq() prints an error message itself when something goes
+wrong. Let's remove these prints with a simple semantic patch.
+
+// <smpl>
+@@
+expression ret;
+struct platform_device *E;
+@@
+
+ret =
+(
+platform_get_irq(E, ...)
+|
+platform_get_irq_byname(E, ...)
+);
+
+if ( \( ret < 0 \| ret <= 0 \) )
+{
+(
+-if (ret != -EPROBE_DEFER)
+-{ ...
+-dev_err(...);
+-... }
+|
+...
+-dev_err(...);
+)
+...
+}
+// </smpl>
+
+While we're here, remove braces on if statements that only have one
+statement (manually).
+
+Cc: Ulf Hansson <ulf.hansson@linaro.org>
+Cc: linux-mmc@vger.kernel.org
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Stephen Boyd <swboyd@chromium.org>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: 71150ac12558 ("mmc: bcm2835: fix deferred probing")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/bcm2835.c       | 1 -
+ drivers/mmc/host/jz4740_mmc.c    | 1 -
+ drivers/mmc/host/meson-gx-mmc.c  | 1 -
+ drivers/mmc/host/mxcmmc.c        | 4 +---
+ drivers/mmc/host/s3cmci.c        | 1 -
+ drivers/mmc/host/sdhci-msm.c     | 2 --
+ drivers/mmc/host/sdhci-pltfm.c   | 1 -
+ drivers/mmc/host/sdhci-s3c.c     | 4 +---
+ drivers/mmc/host/sdhci_f_sdh30.c | 4 +---
+ drivers/mmc/host/uniphier-sd.c   | 4 +---
+ 10 files changed, 4 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
+index 5301302fb5310..11026474dda47 100644
+--- a/drivers/mmc/host/bcm2835.c
++++ b/drivers/mmc/host/bcm2835.c
+@@ -1418,7 +1418,6 @@ static int bcm2835_probe(struct platform_device *pdev)
+       host->irq = platform_get_irq(pdev, 0);
+       if (host->irq <= 0) {
+-              dev_err(dev, "get IRQ failed\n");
+               ret = -EINVAL;
+               goto err;
+       }
+diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
+index 864338e308e2b..b8fb518c6db01 100644
+--- a/drivers/mmc/host/jz4740_mmc.c
++++ b/drivers/mmc/host/jz4740_mmc.c
+@@ -1060,7 +1060,6 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
+       host->irq = platform_get_irq(pdev, 0);
+       if (host->irq < 0) {
+               ret = host->irq;
+-              dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
+               goto err_free_host;
+       }
+diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
+index a3e5be81b4660..28f07d4100433 100644
+--- a/drivers/mmc/host/meson-gx-mmc.c
++++ b/drivers/mmc/host/meson-gx-mmc.c
+@@ -1272,7 +1272,6 @@ static int meson_mmc_probe(struct platform_device *pdev)
+       host->irq = platform_get_irq(pdev, 0);
+       if (host->irq <= 0) {
+-              dev_err(&pdev->dev, "failed to get interrupt resource.\n");
+               ret = -EINVAL;
+               goto free_host;
+       }
+diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
+index 6215feb976e32..a0e8ac9124455 100644
+--- a/drivers/mmc/host/mxcmmc.c
++++ b/drivers/mmc/host/mxcmmc.c
+@@ -1017,10 +1017,8 @@ static int mxcmci_probe(struct platform_device *pdev)
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       irq = platform_get_irq(pdev, 0);
+-      if (irq < 0) {
+-              dev_err(&pdev->dev, "failed to get IRQ: %d\n", irq);
++      if (irq < 0)
+               return irq;
+-      }
+       mmc = mmc_alloc_host(sizeof(*host), &pdev->dev);
+       if (!mmc)
+diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
+index f774936043129..ca2239ea6d96d 100644
+--- a/drivers/mmc/host/s3cmci.c
++++ b/drivers/mmc/host/s3cmci.c
+@@ -1661,7 +1661,6 @@ static int s3cmci_probe(struct platform_device *pdev)
+       host->irq = platform_get_irq(pdev, 0);
+       if (host->irq <= 0) {
+-              dev_err(&pdev->dev, "failed to get interrupt resource.\n");
+               ret = -EINVAL;
+               goto probe_iounmap;
+       }
+diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
+index 4970cd40813b2..feede31fab47d 100644
+--- a/drivers/mmc/host/sdhci-msm.c
++++ b/drivers/mmc/host/sdhci-msm.c
+@@ -1914,8 +1914,6 @@ static int sdhci_msm_probe(struct platform_device *pdev)
+       /* Setup IRQ for handling power/voltage tasks with PMIC */
+       msm_host->pwr_irq = platform_get_irq_byname(pdev, "pwr_irq");
+       if (msm_host->pwr_irq < 0) {
+-              dev_err(&pdev->dev, "Get pwr_irq failed (%d)\n",
+-                      msm_host->pwr_irq);
+               ret = msm_host->pwr_irq;
+               goto clk_disable;
+       }
+diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
+index 02bea6159d792..ac380c54bd170 100644
+--- a/drivers/mmc/host/sdhci-pltfm.c
++++ b/drivers/mmc/host/sdhci-pltfm.c
+@@ -131,7 +131,6 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+-              dev_err(&pdev->dev, "failed to get IRQ number\n");
+               ret = irq;
+               goto err;
+       }
+diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
+index 9ef89d00970e1..936d88a33a675 100644
+--- a/drivers/mmc/host/sdhci-s3c.c
++++ b/drivers/mmc/host/sdhci-s3c.c
+@@ -493,10 +493,8 @@ static int sdhci_s3c_probe(struct platform_device *pdev)
+       }
+       irq = platform_get_irq(pdev, 0);
+-      if (irq < 0) {
+-              dev_err(dev, "no irq specified\n");
++      if (irq < 0)
+               return irq;
+-      }
+       host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c));
+       if (IS_ERR(host)) {
+diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
+index ca9e05440da1d..ee8160d6015ea 100644
+--- a/drivers/mmc/host/sdhci_f_sdh30.c
++++ b/drivers/mmc/host/sdhci_f_sdh30.c
+@@ -122,10 +122,8 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev)
+       u32 reg = 0;
+       irq = platform_get_irq(pdev, 0);
+-      if (irq < 0) {
+-              dev_err(dev, "%s: no irq specified\n", __func__);
++      if (irq < 0)
+               return irq;
+-      }
+       host = sdhci_alloc_host(dev, sizeof(struct f_sdhost_priv));
+       if (IS_ERR(host))
+diff --git a/drivers/mmc/host/uniphier-sd.c b/drivers/mmc/host/uniphier-sd.c
+index 10e7b30c792a2..2e57bbb0883f8 100644
+--- a/drivers/mmc/host/uniphier-sd.c
++++ b/drivers/mmc/host/uniphier-sd.c
+@@ -552,10 +552,8 @@ static int uniphier_sd_probe(struct platform_device *pdev)
+       int irq, ret;
+       irq = platform_get_irq(pdev, 0);
+-      if (irq < 0) {
+-              dev_err(dev, "failed to get IRQ number");
++      if (irq < 0)
+               return irq;
+-      }
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+-- 
+2.40.1
+
diff --git a/queue-4.19/mmc-sdhci-spear-fix-deferred-probing.patch b/queue-4.19/mmc-sdhci-spear-fix-deferred-probing.patch
new file mode 100644 (file)
index 0000000..04b19a8
--- /dev/null
@@ -0,0 +1,46 @@
+From 4e092284044f9ae0209daad56be089aa2238cae4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Jun 2023 23:36:19 +0300
+Subject: mmc: sdhci-spear: fix deferred probing
+
+From: Sergey Shtylyov <s.shtylyov@omp.ru>
+
+[ Upstream commit 8d0caeedcd05a721f3cc2537b0ea212ec4027307 ]
+
+The driver overrides the error codes and IRQ0 returned by platform_get_irq()
+to -EINVAL, so if it returns -EPROBE_DEFER, the driver will fail the probe
+permanently instead of the deferred probing. Switch to propagating the error
+codes upstream.  Since commit ce753ad1549c ("platform: finally disallow IRQ0
+in platform_get_irq() and its ilk") IRQ0 is no longer returned by those APIs,
+so we now can safely ignore it...
+
+Fixes: 682798a596a6 ("mmc: sdhci-spear: Handle return value of platform_get_irq")
+Cc: stable@vger.kernel.org # v5.19+
+Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/20230617203622.6812-10-s.shtylyov@omp.ru
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-spear.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
+index 9247d51f2eed2..705cc51861599 100644
+--- a/drivers/mmc/host/sdhci-spear.c
++++ b/drivers/mmc/host/sdhci-spear.c
+@@ -82,8 +82,8 @@ static int sdhci_probe(struct platform_device *pdev)
+       host->hw_name = "sdhci";
+       host->ops = &sdhci_pltfm_ops;
+       host->irq = platform_get_irq(pdev, 0);
+-      if (host->irq <= 0) {
+-              ret = -EINVAL;
++      if (host->irq < 0) {
++              ret = host->irq;
+               goto err_host;
+       }
+       host->quirks = SDHCI_QUIRK_BROKEN_ADMA;
+-- 
+2.40.1
+
diff --git a/queue-4.19/mmc-sunxi-fix-deferred-probing.patch b/queue-4.19/mmc-sunxi-fix-deferred-probing.patch
new file mode 100644 (file)
index 0000000..cea8de2
--- /dev/null
@@ -0,0 +1,45 @@
+From 4c388718c453114fa90be46d83f35a513e3cc82a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Jun 2023 23:36:21 +0300
+Subject: mmc: sunxi: fix deferred probing
+
+From: Sergey Shtylyov <s.shtylyov@omp.ru>
+
+[ Upstream commit c2df53c5806cfd746dae08e07bc8c4ad247c3b70 ]
+
+The driver overrides the error codes and IRQ0 returned by platform_get_irq()
+to -EINVAL, so if it returns -EPROBE_DEFER, the driver will fail the probe
+permanently instead of the deferred probing. Switch to propagating the error
+codes upstream.  Since commit ce753ad1549c ("platform: finally disallow IRQ0
+in platform_get_irq() and its ilk") IRQ0 is no longer returned by those APIs,
+so we now can safely ignore it...
+
+Fixes: 2408a08583d2 ("mmc: sunxi-mmc: Handle return value of platform_get_irq")
+Cc: stable@vger.kernel.org # v5.19+
+Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Link: https://lore.kernel.org/r/20230617203622.6812-12-s.shtylyov@omp.ru
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sunxi-mmc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
+index 757eb175611fb..bc3f8a1df10cc 100644
+--- a/drivers/mmc/host/sunxi-mmc.c
++++ b/drivers/mmc/host/sunxi-mmc.c
+@@ -1308,8 +1308,8 @@ static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host,
+               return ret;
+       host->irq = platform_get_irq(pdev, 0);
+-      if (host->irq <= 0) {
+-              ret = -EINVAL;
++      if (host->irq < 0) {
++              ret = host->irq;
+               goto error_disable_mmc;
+       }
+-- 
+2.40.1
+
diff --git a/queue-4.19/mmc-tmio-move-tmio_mmc_set_clock-to-platform-hook.patch b/queue-4.19/mmc-tmio-move-tmio_mmc_set_clock-to-platform-hook.patch
new file mode 100644 (file)
index 0000000..d811841
--- /dev/null
@@ -0,0 +1,380 @@
+From f825417593b25af3423223450901b46ccc0bf1dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Aug 2018 13:44:16 +0900
+Subject: mmc: tmio: move tmio_mmc_set_clock() to platform hook
+
+From: Masahiro Yamada <yamada.masahiro@socionext.com>
+
+[ Upstream commit 0196c8db8363f7627df6f78615271ae0ba430500 ]
+
+tmio_mmc_set_clock() is full of quirks because different SoC vendors
+extended this in different ways.
+
+The original IP defines the divisor range 1/2 ... 1/512.
+
+ bit 7 is set:    1/512
+ bit 6 is set:    1/256
+   ...
+ bit 0 is set:    1/4
+ all bits clear:  1/2
+
+It is platform-dependent how to achieve the 1/1 clock.
+
+I guess the TMIO-MFD variant uses the clock selector outside of this IP,
+as far as I see tmio_core_mmc_clk_div() in drivers/mfd/tmio_core.c
+
+I guess bit[7:0]=0xff is Renesas-specific extension.
+
+Socionext (and Panasonic) uses bit 10 (CLKSEL) for 1/1.  Also, newer
+versions of UniPhier SoC variants use bit 16 for 1/1024.
+
+host->clk_update() is only used by the Renesas variants, whereas
+host->set_clk_div() is only used by the TMIO-MFD variants.
+
+To cope with this mess, promote tmio_mmc_set_clock() to a new
+platform hook ->set_clock(), and melt the old two hooks into it.
+
+Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
+Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: 71150ac12558 ("mmc: bcm2835: fix deferred probing")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/renesas_sdhi_core.c | 62 ++++++++++++++++++-
+ drivers/mmc/host/tmio_mmc.c          | 48 +++++++++++++++
+ drivers/mmc/host/tmio_mmc.h          |  4 +-
+ drivers/mmc/host/tmio_mmc_core.c     | 92 +++-------------------------
+ 4 files changed, 117 insertions(+), 89 deletions(-)
+
+diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
+index eabfcb5bbafff..a2c44cc8e2e7c 100644
+--- a/drivers/mmc/host/renesas_sdhi_core.c
++++ b/drivers/mmc/host/renesas_sdhi_core.c
+@@ -155,6 +155,66 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
+       return ret == 0 ? best_freq : clk_get_rate(priv->clk);
+ }
++static void renesas_sdhi_clk_start(struct tmio_mmc_host *host)
++{
++      sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
++              sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
++
++      /* HW engineers overrode docs: no sleep needed on R-Car2+ */
++      if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2))
++              usleep_range(10000, 11000);
++}
++
++static void renesas_sdhi_clk_stop(struct tmio_mmc_host *host)
++{
++      sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
++              sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
++
++      /* HW engineers overrode docs: no sleep needed on R-Car2+ */
++      if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2))
++              usleep_range(10000, 11000);
++}
++
++static void renesas_sdhi_set_clock(struct tmio_mmc_host *host,
++                                 unsigned int new_clock)
++{
++      u32 clk = 0, clock;
++
++      if (new_clock == 0) {
++              renesas_sdhi_clk_stop(host);
++              return;
++      }
++      /*
++       * Both HS400 and HS200/SD104 set 200MHz, but some devices need to
++       * set 400MHz to distinguish the CPG settings in HS400.
++       */
++      if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 &&
++          host->pdata->flags & TMIO_MMC_HAVE_4TAP_HS400 &&
++          new_clock == 200000000)
++              new_clock = 400000000;
++
++      clock = renesas_sdhi_clk_update(host, new_clock) / 512;
++
++      for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1)
++              clock <<= 1;
++
++      /* 1/1 clock is option */
++      if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) && ((clk >> 22) & 0x1)) {
++              if (!(host->mmc->ios.timing == MMC_TIMING_MMC_HS400))
++                      clk |= 0xff;
++              else
++                      clk &= ~0xff;
++      }
++
++      sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
++                      sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
++      sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK);
++      if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2))
++              usleep_range(10000, 11000);
++
++      renesas_sdhi_clk_start(host);
++}
++
+ static void renesas_sdhi_clk_disable(struct tmio_mmc_host *host)
+ {
+       struct renesas_sdhi *priv = host_to_priv(host);
+@@ -621,8 +681,8 @@ int renesas_sdhi_probe(struct platform_device *pdev,
+       host->write16_hook      = renesas_sdhi_write16_hook;
+       host->clk_enable        = renesas_sdhi_clk_enable;
+-      host->clk_update        = renesas_sdhi_clk_update;
+       host->clk_disable       = renesas_sdhi_clk_disable;
++      host->set_clock         = renesas_sdhi_set_clock;
+       host->multi_io_quirk    = renesas_sdhi_multi_io_quirk;
+       host->dma_ops           = dma_ops;
+diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
+index 43a2ea5cff24f..b031a776c12e0 100644
+--- a/drivers/mmc/host/tmio_mmc.c
++++ b/drivers/mmc/host/tmio_mmc.c
+@@ -13,6 +13,7 @@
+  * published by the Free Software Foundation.
+  */
++#include <linux/delay.h>
+ #include <linux/device.h>
+ #include <linux/mfd/core.h>
+ #include <linux/mfd/tmio.h>
+@@ -23,6 +24,52 @@
+ #include "tmio_mmc.h"
++static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
++{
++      sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
++              sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
++
++      usleep_range(10000, 11000);
++      sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
++      usleep_range(10000, 11000);
++}
++
++static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
++{
++      sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
++      usleep_range(10000, 11000);
++
++      sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
++              sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
++
++      usleep_range(10000, 11000);
++}
++
++static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
++                             unsigned int new_clock)
++{
++      u32 clk = 0, clock;
++
++      if (new_clock == 0) {
++              tmio_mmc_clk_stop(host);
++              return;
++      }
++
++      clock = host->mmc->f_min;
++
++      for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1)
++              clock <<= 1;
++
++      host->pdata->set_clk_div(host->pdev, (clk >> 22) & 1);
++
++      sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
++                      sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
++      sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK);
++      usleep_range(10000, 11000);
++
++      tmio_mmc_clk_start(host);
++}
++
+ #ifdef CONFIG_PM_SLEEP
+ static int tmio_mmc_suspend(struct device *dev)
+ {
+@@ -100,6 +147,7 @@ static int tmio_mmc_probe(struct platform_device *pdev)
+       /* SD control register space size is 0x200, 0x400 for bus_shift=1 */
+       host->bus_shift = resource_size(res) >> 10;
++      host->set_clock = tmio_mmc_set_clock;
+       host->mmc->f_max = pdata->hclk;
+       host->mmc->f_min = pdata->hclk / 512;
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index 7c40a7e1fea1c..358aa258cb159 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -133,7 +133,6 @@ struct tmio_mmc_host {
+       /* Callbacks for clock / power control */
+       void (*set_pwr)(struct platform_device *host, int state);
+-      void (*set_clk_div)(struct platform_device *host, int state);
+       /* pio related stuff */
+       struct scatterlist      *sg_ptr;
+@@ -170,10 +169,9 @@ struct tmio_mmc_host {
+       /* Mandatory callback */
+       int (*clk_enable)(struct tmio_mmc_host *host);
++      void (*set_clock)(struct tmio_mmc_host *host, unsigned int clock);
+       /* Optional callbacks */
+-      unsigned int (*clk_update)(struct tmio_mmc_host *host,
+-                                 unsigned int new_clock);
+       void (*clk_disable)(struct tmio_mmc_host *host);
+       int (*multi_io_quirk)(struct mmc_card *card,
+                             unsigned int direction, int blk_size);
+diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
+index 195f45a84282e..f819757e125e0 100644
+--- a/drivers/mmc/host/tmio_mmc_core.c
++++ b/drivers/mmc/host/tmio_mmc_core.c
+@@ -161,83 +161,6 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+       }
+ }
+-static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
+-{
+-      sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
+-              sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+-
+-      /* HW engineers overrode docs: no sleep needed on R-Car2+ */
+-      if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2))
+-              usleep_range(10000, 11000);
+-
+-      if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) {
+-              sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
+-              usleep_range(10000, 11000);
+-      }
+-}
+-
+-static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
+-{
+-      if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) {
+-              sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
+-              usleep_range(10000, 11000);
+-      }
+-
+-      sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
+-              sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+-
+-      /* HW engineers overrode docs: no sleep needed on R-Car2+ */
+-      if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2))
+-              usleep_range(10000, 11000);
+-}
+-
+-static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
+-                             unsigned int new_clock)
+-{
+-      u32 clk = 0, clock;
+-
+-      if (new_clock == 0) {
+-              tmio_mmc_clk_stop(host);
+-              return;
+-      }
+-      /*
+-       * Both HS400 and HS200/SD104 set 200MHz, but some devices need to
+-       * set 400MHz to distinguish the CPG settings in HS400.
+-       */
+-      if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 &&
+-          host->pdata->flags & TMIO_MMC_HAVE_4TAP_HS400 &&
+-          new_clock == 200000000)
+-              new_clock = 400000000;
+-
+-      if (host->clk_update)
+-              clock = host->clk_update(host, new_clock) / 512;
+-      else
+-              clock = host->mmc->f_min;
+-
+-      for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1)
+-              clock <<= 1;
+-
+-      /* 1/1 clock is option */
+-      if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) &&
+-          ((clk >> 22) & 0x1)) {
+-              if (!(host->mmc->ios.timing == MMC_TIMING_MMC_HS400))
+-                      clk |= 0xff;
+-              else
+-                      clk &= ~0xff;
+-      }
+-
+-      if (host->set_clk_div)
+-              host->set_clk_div(host->pdev, (clk >> 22) & 1);
+-
+-      sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
+-                      sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+-      sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK);
+-      if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2))
+-              usleep_range(10000, 11000);
+-
+-      tmio_mmc_clk_start(host);
+-}
+-
+ static void tmio_mmc_reset(struct tmio_mmc_host *host)
+ {
+       /* FIXME - should we set stop clock reg here */
+@@ -1051,15 +974,15 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+       switch (ios->power_mode) {
+       case MMC_POWER_OFF:
+               tmio_mmc_power_off(host);
+-              tmio_mmc_set_clock(host, 0);
++              host->set_clock(host, 0);
+               break;
+       case MMC_POWER_UP:
+               tmio_mmc_power_on(host, ios->vdd);
+-              tmio_mmc_set_clock(host, ios->clock);
++              host->set_clock(host, ios->clock);
+               tmio_mmc_set_bus_width(host, ios->bus_width);
+               break;
+       case MMC_POWER_ON:
+-              tmio_mmc_set_clock(host, ios->clock);
++              host->set_clock(host, ios->clock);
+               tmio_mmc_set_bus_width(host, ios->bus_width);
+               break;
+       }
+@@ -1245,7 +1168,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
+       int ret;
+       /*
+-       * Check the sanity of mmc->f_min to prevent tmio_mmc_set_clock() from
++       * Check the sanity of mmc->f_min to prevent host->set_clock() from
+        * looping forever...
+        */
+       if (mmc->f_min == 0)
+@@ -1255,7 +1178,6 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
+               _host->write16_hook = NULL;
+       _host->set_pwr = pdata->set_pwr;
+-      _host->set_clk_div = pdata->set_clk_div;
+       ret = tmio_mmc_init_ocr(_host);
+       if (ret < 0)
+@@ -1318,7 +1240,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
+       if (pdata->flags & TMIO_MMC_SDIO_IRQ)
+               _host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
+-      tmio_mmc_set_clock(_host, 0);
++      _host->set_clock(_host, 0);
+       tmio_mmc_reset(_host);
+       _host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, CTL_IRQ_MASK);
+@@ -1402,7 +1324,7 @@ int tmio_mmc_host_runtime_suspend(struct device *dev)
+       tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL);
+       if (host->clk_cache)
+-              tmio_mmc_set_clock(host, 0);
++              host->set_clock(host, 0);
+       tmio_mmc_clk_disable(host);
+@@ -1423,7 +1345,7 @@ int tmio_mmc_host_runtime_resume(struct device *dev)
+       tmio_mmc_clk_enable(host);
+       if (host->clk_cache)
+-              tmio_mmc_set_clock(host, host->clk_cache);
++              host->set_clock(host, host->clk_cache);
+       if (host->native_hotplug)
+               tmio_mmc_enable_mmc_irqs(host,
+-- 
+2.40.1
+
diff --git a/queue-4.19/mmc-tmio-replace-tmio_mmc_clk_stop-calls-with-tmio_m.patch b/queue-4.19/mmc-tmio-replace-tmio_mmc_clk_stop-calls-with-tmio_m.patch
new file mode 100644 (file)
index 0000000..8d7d63a
--- /dev/null
@@ -0,0 +1,56 @@
+From 3c65f1223c864e1ea3c06f506b709cbe217ca63b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Aug 2018 13:44:15 +0900
+Subject: mmc: tmio: replace tmio_mmc_clk_stop() calls with
+ tmio_mmc_set_clock()
+
+From: Masahiro Yamada <yamada.masahiro@socionext.com>
+
+[ Upstream commit 74005a01f1ff66f98bf24163297932144d4da1ae ]
+
+tmio_mmc_clk_stop(host) is equivalent to tmio_mmc_set_clock(host, 0).
+This replacement is needed for the next commit.
+
+Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
+Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: 71150ac12558 ("mmc: bcm2835: fix deferred probing")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/tmio_mmc_core.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
+index 33c9ca8f14a97..195f45a84282e 100644
+--- a/drivers/mmc/host/tmio_mmc_core.c
++++ b/drivers/mmc/host/tmio_mmc_core.c
+@@ -1051,7 +1051,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+       switch (ios->power_mode) {
+       case MMC_POWER_OFF:
+               tmio_mmc_power_off(host);
+-              tmio_mmc_clk_stop(host);
++              tmio_mmc_set_clock(host, 0);
+               break;
+       case MMC_POWER_UP:
+               tmio_mmc_power_on(host, ios->vdd);
+@@ -1318,7 +1318,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
+       if (pdata->flags & TMIO_MMC_SDIO_IRQ)
+               _host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
+-      tmio_mmc_clk_stop(_host);
++      tmio_mmc_set_clock(_host, 0);
+       tmio_mmc_reset(_host);
+       _host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, CTL_IRQ_MASK);
+@@ -1402,7 +1402,7 @@ int tmio_mmc_host_runtime_suspend(struct device *dev)
+       tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL);
+       if (host->clk_cache)
+-              tmio_mmc_clk_stop(host);
++              tmio_mmc_set_clock(host, 0);
+       tmio_mmc_clk_disable(host);
+-- 
+2.40.1
+
diff --git a/queue-4.19/mmc-uniphier-sd-add-uniphier-sd-emmc-controller-driv.patch b/queue-4.19/mmc-uniphier-sd-add-uniphier-sd-emmc-controller-driv.patch
new file mode 100644 (file)
index 0000000..3d9db65
--- /dev/null
@@ -0,0 +1,812 @@
+From c343ea70c67bf61df8e1046119d24453efc8475c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Aug 2018 13:44:18 +0900
+Subject: mmc: uniphier-sd: add UniPhier SD/eMMC controller driver
+
+From: Masahiro Yamada <yamada.masahiro@socionext.com>
+
+[ Upstream commit 3fd784f745dd1747863775a99ec749619ee6759c ]
+
+Here is another TMIO MMC variant found in Socionext UniPhier SoCs.
+
+As commit b6147490e6aa ("mmc: tmio: split core functionality, DMA and
+MFD glue") said, these MMC controllers use the IP from Panasonic.
+
+However, the MMC controller in the TMIO (Toshiba Mobile IO) MFD chip
+was the first upstreamed user of this IP.  The common driver code
+for this IP is now called 'tmio-mmc-core' in Linux although it is a
+historical misnomer.
+
+Anyway, this driver select's MMC_TMIO_CORE to borrow the common code
+from tmio-mmc-core.c
+
+Older UniPhier SoCs (LD4, Pro4, sLD8) support the external DMA engine
+like renesas_sdhi_sys_dmac.c.  The difference is UniPhier SoCs use a
+single DMA channel whereas Renesas chips request separate channels for
+RX and TX.
+
+Newer UniPhier SoCs (Pro5 and later) support the internal DMA engine
+like renesas_sdhi_internal_dmac.c  The register map is almost the same,
+so I guess Renesas and Socionext use the same internal DMA hardware.
+The main difference is, the register offsets are doubled for Renesas.
+
+                        Renesas      Socionext
+                        SDHI         UniPhier
+  DM_CM_DTRAN_MODE      0x820        0x410
+  DM_CM_DTRAN_CTRL      0x828        0x414
+  DM_CM_RST             0x830        0x418
+  DM_CM_INFO1           0x840        0x420
+  DM_CM_INFO1_MASK      0x848        0x424
+  DM_CM_INFO2           0x850        0x428
+  DM_CM_INFO2_MASK      0x858        0x42c
+  DM_DTRAN_ADDR         0x880        0x440
+  DM_DTRAN_ADDREX        ---         0x444
+
+This comes from the difference of host->bus_shift; 2 for Renesas SoCs,
+and 1 for UniPhier SoCs.  Also, the datasheet for UniPhier SoCs defines
+DM_DTRAN_ADDR and DM_DTRAN_ADDREX as two separate registers.
+
+It could be possible to factor out the DMA common code by introducing
+some hooks to cope with platform quirks, but this patch does not touch
+that for now.
+
+Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
+Acked-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: 71150ac12558 ("mmc: bcm2835: fix deferred probing")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ MAINTAINERS                    |   1 +
+ drivers/mmc/host/Kconfig       |  10 +
+ drivers/mmc/host/Makefile      |   1 +
+ drivers/mmc/host/uniphier-sd.c | 693 +++++++++++++++++++++++++++++++++
+ 4 files changed, 705 insertions(+)
+ create mode 100644 drivers/mmc/host/uniphier-sd.c
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 59003315a9597..1827d859491b5 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -2195,6 +2195,7 @@ F:       drivers/clk/uniphier/
+ F:    drivers/gpio/gpio-uniphier.c
+ F:    drivers/i2c/busses/i2c-uniphier*
+ F:    drivers/irqchip/irq-uniphier-aidet.c
++F:    drivers/mmc/host/uniphier-sd.c
+ F:    drivers/pinctrl/uniphier/
+ F:    drivers/reset/reset-uniphier.c
+ F:    drivers/tty/serial/8250/8250_uniphier.c
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index 2c11944686cf9..f45dd8223526f 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -630,6 +630,16 @@ config MMC_SDHI_INTERNAL_DMAC
+         using on-chip bus mastering. This supports the controllers
+         found in arm64 based SoCs.
++config MMC_UNIPHIER
++      tristate "UniPhier SD/eMMC Host Controller support"
++      depends on ARCH_UNIPHIER || COMPILE_TEST
++      depends on OF
++      select MMC_TMIO_CORE
++      help
++        This provides support for the SD/eMMC controller found in
++        UniPhier SoCs. The eMMC variant of this controller is used
++        only for 32-bit SoCs.
++
+ config MMC_CB710
+       tristate "ENE CB710 MMC/SD Interface support"
+       depends on PCI
+diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
+index ce8398e6f2c0e..a835d1a0546d2 100644
+--- a/drivers/mmc/host/Makefile
++++ b/drivers/mmc/host/Makefile
+@@ -42,6 +42,7 @@ obj-$(CONFIG_MMC_TMIO_CORE)  += tmio_mmc_core.o
+ obj-$(CONFIG_MMC_SDHI)                += renesas_sdhi_core.o
+ obj-$(CONFIG_MMC_SDHI_SYS_DMAC)               += renesas_sdhi_sys_dmac.o
+ obj-$(CONFIG_MMC_SDHI_INTERNAL_DMAC)  += renesas_sdhi_internal_dmac.o
++obj-$(CONFIG_MMC_UNIPHIER)    += uniphier-sd.o
+ obj-$(CONFIG_MMC_CB710)               += cb710-mmc.o
+ obj-$(CONFIG_MMC_VIA_SDMMC)   += via-sdmmc.o
+ octeon-mmc-objs := cavium.o cavium-octeon.o
+diff --git a/drivers/mmc/host/uniphier-sd.c b/drivers/mmc/host/uniphier-sd.c
+new file mode 100644
+index 0000000000000..10e7b30c792a2
+--- /dev/null
++++ b/drivers/mmc/host/uniphier-sd.c
+@@ -0,0 +1,693 @@
++// SPDX-License-Identifier: GPL-2.0
++//
++// Copyright (C) 2017-2018 Socionext Inc.
++//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
++
++#include <linux/bitfield.h>
++#include <linux/bitops.h>
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/dma-mapping.h>
++#include <linux/mfd/tmio.h>
++#include <linux/mmc/host.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/platform_device.h>
++#include <linux/reset.h>
++
++#include "tmio_mmc.h"
++
++#define   UNIPHIER_SD_CLK_CTL_DIV1024         BIT(16)
++#define   UNIPHIER_SD_CLK_CTL_DIV1            BIT(10)
++#define   UNIPHIER_SD_CLKCTL_OFFEN            BIT(9)  // auto SDCLK stop
++#define UNIPHIER_SD_CC_EXT_MODE               0x1b0
++#define   UNIPHIER_SD_CC_EXT_MODE_DMA         BIT(1)
++#define UNIPHIER_SD_HOST_MODE         0x1c8
++#define UNIPHIER_SD_VOLT              0x1e4
++#define   UNIPHIER_SD_VOLT_MASK                       GENMASK(1, 0)
++#define   UNIPHIER_SD_VOLT_OFF                        0
++#define   UNIPHIER_SD_VOLT_330                        1       // 3.3V signal
++#define   UNIPHIER_SD_VOLT_180                        2       // 1.8V signal
++#define UNIPHIER_SD_DMA_MODE          0x410
++#define   UNIPHIER_SD_DMA_MODE_DIR_MASK               GENMASK(17, 16)
++#define   UNIPHIER_SD_DMA_MODE_DIR_TO_DEV     0
++#define   UNIPHIER_SD_DMA_MODE_DIR_FROM_DEV   1
++#define   UNIPHIER_SD_DMA_MODE_WIDTH_MASK     GENMASK(5, 4)
++#define   UNIPHIER_SD_DMA_MODE_WIDTH_8                0
++#define   UNIPHIER_SD_DMA_MODE_WIDTH_16               1
++#define   UNIPHIER_SD_DMA_MODE_WIDTH_32               2
++#define   UNIPHIER_SD_DMA_MODE_WIDTH_64               3
++#define   UNIPHIER_SD_DMA_MODE_ADDR_INC               BIT(0)  // 1: inc, 0: fixed
++#define UNIPHIER_SD_DMA_CTL           0x414
++#define   UNIPHIER_SD_DMA_CTL_START   BIT(0)  // start DMA (auto cleared)
++#define UNIPHIER_SD_DMA_RST           0x418
++#define   UNIPHIER_SD_DMA_RST_CH1     BIT(9)
++#define   UNIPHIER_SD_DMA_RST_CH0     BIT(8)
++#define UNIPHIER_SD_DMA_ADDR_L                0x440
++#define UNIPHIER_SD_DMA_ADDR_H                0x444
++
++/*
++ * IP is extended to support various features: built-in DMA engine,
++ * 1/1024 divisor, etc.
++ */
++#define UNIPHIER_SD_CAP_EXTENDED_IP           BIT(0)
++/* RX channel of the built-in DMA controller is broken (Pro5) */
++#define UNIPHIER_SD_CAP_BROKEN_DMA_RX         BIT(1)
++
++struct uniphier_sd_priv {
++      struct tmio_mmc_data tmio_data;
++      struct pinctrl *pinctrl;
++      struct pinctrl_state *pinstate_default;
++      struct pinctrl_state *pinstate_uhs;
++      struct clk *clk;
++      struct reset_control *rst;
++      struct reset_control *rst_br;
++      struct reset_control *rst_hw;
++      struct dma_chan *chan;
++      enum dma_data_direction dma_dir;
++      unsigned long clk_rate;
++      unsigned long caps;
++};
++
++static void *uniphier_sd_priv(struct tmio_mmc_host *host)
++{
++      return container_of(host->pdata, struct uniphier_sd_priv, tmio_data);
++}
++
++static void uniphier_sd_dma_endisable(struct tmio_mmc_host *host, int enable)
++{
++      sd_ctrl_write16(host, CTL_DMA_ENABLE, DMA_ENABLE_DMASDRW);
++}
++
++/* external DMA engine */
++static void uniphier_sd_external_dma_issue(unsigned long arg)
++{
++      struct tmio_mmc_host *host = (void *)arg;
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++
++      uniphier_sd_dma_endisable(host, 1);
++      dma_async_issue_pending(priv->chan);
++}
++
++static void uniphier_sd_external_dma_callback(void *param,
++                                      const struct dmaengine_result *result)
++{
++      struct tmio_mmc_host *host = param;
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++      unsigned long flags;
++
++      dma_unmap_sg(mmc_dev(host->mmc), host->sg_ptr, host->sg_len,
++                   priv->dma_dir);
++
++      spin_lock_irqsave(&host->lock, flags);
++
++      if (result->result == DMA_TRANS_NOERROR) {
++              /*
++               * When the external DMA engine is enabled, strangely enough,
++               * the DATAEND flag can be asserted even if the DMA engine has
++               * not been kicked yet.  Enable the TMIO_STAT_DATAEND irq only
++               * after we make sure the DMA engine finishes the transfer,
++               * hence, in this callback.
++               */
++              tmio_mmc_enable_mmc_irqs(host, TMIO_STAT_DATAEND);
++      } else {
++              host->data->error = -ETIMEDOUT;
++              tmio_mmc_do_data_irq(host);
++      }
++
++      spin_unlock_irqrestore(&host->lock, flags);
++}
++
++static void uniphier_sd_external_dma_start(struct tmio_mmc_host *host,
++                                         struct mmc_data *data)
++{
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++      enum dma_transfer_direction dma_tx_dir;
++      struct dma_async_tx_descriptor *desc;
++      dma_cookie_t cookie;
++      int sg_len;
++
++      if (!priv->chan)
++              goto force_pio;
++
++      if (data->flags & MMC_DATA_READ) {
++              priv->dma_dir = DMA_FROM_DEVICE;
++              dma_tx_dir = DMA_DEV_TO_MEM;
++      } else {
++              priv->dma_dir = DMA_TO_DEVICE;
++              dma_tx_dir = DMA_MEM_TO_DEV;
++      }
++
++      sg_len = dma_map_sg(mmc_dev(host->mmc), host->sg_ptr, host->sg_len,
++                          priv->dma_dir);
++      if (sg_len == 0)
++              goto force_pio;
++
++      desc = dmaengine_prep_slave_sg(priv->chan, host->sg_ptr, sg_len,
++                                     dma_tx_dir, DMA_CTRL_ACK);
++      if (!desc)
++              goto unmap_sg;
++
++      desc->callback_result = uniphier_sd_external_dma_callback;
++      desc->callback_param = host;
++
++      cookie = dmaengine_submit(desc);
++      if (cookie < 0)
++              goto unmap_sg;
++
++      return;
++
++unmap_sg:
++      dma_unmap_sg(mmc_dev(host->mmc), host->sg_ptr, host->sg_len,
++                   priv->dma_dir);
++force_pio:
++      host->force_pio = true;
++      uniphier_sd_dma_endisable(host, 0);
++}
++
++static void uniphier_sd_external_dma_enable(struct tmio_mmc_host *host,
++                                          bool enable)
++{
++}
++
++static void uniphier_sd_external_dma_request(struct tmio_mmc_host *host,
++                                           struct tmio_mmc_data *pdata)
++{
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++      struct dma_chan *chan;
++
++      chan = dma_request_chan(mmc_dev(host->mmc), "rx-tx");
++      if (IS_ERR(chan)) {
++              dev_warn(mmc_dev(host->mmc),
++                       "failed to request DMA channel. falling back to PIO\n");
++              return; /* just use PIO even for -EPROBE_DEFER */
++      }
++
++      /* this driver uses a single channel for both RX an TX */
++      priv->chan = chan;
++      host->chan_rx = chan;
++      host->chan_tx = chan;
++
++      tasklet_init(&host->dma_issue, uniphier_sd_external_dma_issue,
++                   (unsigned long)host);
++}
++
++static void uniphier_sd_external_dma_release(struct tmio_mmc_host *host)
++{
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++
++      if (priv->chan)
++              dma_release_channel(priv->chan);
++}
++
++static void uniphier_sd_external_dma_abort(struct tmio_mmc_host *host)
++{
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++
++      uniphier_sd_dma_endisable(host, 0);
++
++      if (priv->chan)
++              dmaengine_terminate_sync(priv->chan);
++}
++
++static void uniphier_sd_external_dma_dataend(struct tmio_mmc_host *host)
++{
++      uniphier_sd_dma_endisable(host, 0);
++
++      tmio_mmc_do_data_irq(host);
++}
++
++static const struct tmio_mmc_dma_ops uniphier_sd_external_dma_ops = {
++      .start = uniphier_sd_external_dma_start,
++      .enable = uniphier_sd_external_dma_enable,
++      .request = uniphier_sd_external_dma_request,
++      .release = uniphier_sd_external_dma_release,
++      .abort = uniphier_sd_external_dma_abort,
++      .dataend = uniphier_sd_external_dma_dataend,
++};
++
++static void uniphier_sd_internal_dma_issue(unsigned long arg)
++{
++      struct tmio_mmc_host *host = (void *)arg;
++      unsigned long flags;
++
++      spin_lock_irqsave(&host->lock, flags);
++      tmio_mmc_enable_mmc_irqs(host, TMIO_STAT_DATAEND);
++      spin_unlock_irqrestore(&host->lock, flags);
++
++      uniphier_sd_dma_endisable(host, 1);
++      writel(UNIPHIER_SD_DMA_CTL_START, host->ctl + UNIPHIER_SD_DMA_CTL);
++}
++
++static void uniphier_sd_internal_dma_start(struct tmio_mmc_host *host,
++                                         struct mmc_data *data)
++{
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++      struct scatterlist *sg = host->sg_ptr;
++      dma_addr_t dma_addr;
++      unsigned int dma_mode_dir;
++      u32 dma_mode;
++      int sg_len;
++
++      if (WARN_ON(host->sg_len != 1))
++              goto force_pio;
++
++      if (!IS_ALIGNED(sg->offset, 8))
++              goto force_pio;
++
++      if (data->flags & MMC_DATA_READ) {
++              priv->dma_dir = DMA_FROM_DEVICE;
++              dma_mode_dir = UNIPHIER_SD_DMA_MODE_DIR_FROM_DEV;
++      } else {
++              priv->dma_dir = DMA_TO_DEVICE;
++              dma_mode_dir = UNIPHIER_SD_DMA_MODE_DIR_TO_DEV;
++      }
++
++      sg_len = dma_map_sg(mmc_dev(host->mmc), sg, 1, priv->dma_dir);
++      if (sg_len == 0)
++              goto force_pio;
++
++      dma_mode = FIELD_PREP(UNIPHIER_SD_DMA_MODE_DIR_MASK, dma_mode_dir);
++      dma_mode |= FIELD_PREP(UNIPHIER_SD_DMA_MODE_WIDTH_MASK,
++                             UNIPHIER_SD_DMA_MODE_WIDTH_64);
++      dma_mode |= UNIPHIER_SD_DMA_MODE_ADDR_INC;
++
++      writel(dma_mode, host->ctl + UNIPHIER_SD_DMA_MODE);
++
++      dma_addr = sg_dma_address(data->sg);
++      writel(lower_32_bits(dma_addr), host->ctl + UNIPHIER_SD_DMA_ADDR_L);
++      writel(upper_32_bits(dma_addr), host->ctl + UNIPHIER_SD_DMA_ADDR_H);
++
++      return;
++force_pio:
++      host->force_pio = true;
++      uniphier_sd_dma_endisable(host, 0);
++}
++
++static void uniphier_sd_internal_dma_enable(struct tmio_mmc_host *host,
++                                          bool enable)
++{
++}
++
++static void uniphier_sd_internal_dma_request(struct tmio_mmc_host *host,
++                                           struct tmio_mmc_data *pdata)
++{
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++
++      /*
++       * Due to a hardware bug, Pro5 cannot use DMA for RX.
++       * We can still use DMA for TX, but PIO for RX.
++       */
++      if (!(priv->caps & UNIPHIER_SD_CAP_BROKEN_DMA_RX))
++              host->chan_rx = (void *)0xdeadbeaf;
++
++      host->chan_tx = (void *)0xdeadbeaf;
++
++      tasklet_init(&host->dma_issue, uniphier_sd_internal_dma_issue,
++                   (unsigned long)host);
++}
++
++static void uniphier_sd_internal_dma_release(struct tmio_mmc_host *host)
++{
++      /* Each value is set to zero to assume "disabling" each DMA */
++      host->chan_rx = NULL;
++      host->chan_tx = NULL;
++}
++
++static void uniphier_sd_internal_dma_abort(struct tmio_mmc_host *host)
++{
++      u32 tmp;
++
++      uniphier_sd_dma_endisable(host, 0);
++
++      tmp = readl(host->ctl + UNIPHIER_SD_DMA_RST);
++      tmp &= ~(UNIPHIER_SD_DMA_RST_CH1 | UNIPHIER_SD_DMA_RST_CH0);
++      writel(tmp, host->ctl + UNIPHIER_SD_DMA_RST);
++
++      tmp |= UNIPHIER_SD_DMA_RST_CH1 | UNIPHIER_SD_DMA_RST_CH0;
++      writel(tmp, host->ctl + UNIPHIER_SD_DMA_RST);
++}
++
++static void uniphier_sd_internal_dma_dataend(struct tmio_mmc_host *host)
++{
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++
++      uniphier_sd_dma_endisable(host, 0);
++      dma_unmap_sg(mmc_dev(host->mmc), host->sg_ptr, 1, priv->dma_dir);
++
++      tmio_mmc_do_data_irq(host);
++}
++
++static const struct tmio_mmc_dma_ops uniphier_sd_internal_dma_ops = {
++      .start = uniphier_sd_internal_dma_start,
++      .enable = uniphier_sd_internal_dma_enable,
++      .request = uniphier_sd_internal_dma_request,
++      .release = uniphier_sd_internal_dma_release,
++      .abort = uniphier_sd_internal_dma_abort,
++      .dataend = uniphier_sd_internal_dma_dataend,
++};
++
++static int uniphier_sd_clk_enable(struct tmio_mmc_host *host)
++{
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++      struct mmc_host *mmc = host->mmc;
++      int ret;
++
++      ret = clk_prepare_enable(priv->clk);
++      if (ret)
++              return ret;
++
++      ret = clk_set_rate(priv->clk, ULONG_MAX);
++      if (ret)
++              goto disable_clk;
++
++      priv->clk_rate = clk_get_rate(priv->clk);
++
++      /* If max-frequency property is set, use it. */
++      if (!mmc->f_max)
++              mmc->f_max = priv->clk_rate;
++
++      /*
++       * 1/512 is the finest divisor in the original IP.  Newer versions
++       * also supports 1/1024 divisor. (UniPhier-specific extension)
++       */
++      if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP)
++              mmc->f_min = priv->clk_rate / 1024;
++      else
++              mmc->f_min = priv->clk_rate / 512;
++
++      ret = reset_control_deassert(priv->rst);
++      if (ret)
++              goto disable_clk;
++
++      ret = reset_control_deassert(priv->rst_br);
++      if (ret)
++              goto assert_rst;
++
++      return 0;
++
++assert_rst:
++      reset_control_assert(priv->rst);
++disable_clk:
++      clk_disable_unprepare(priv->clk);
++
++      return ret;
++}
++
++static void uniphier_sd_clk_disable(struct tmio_mmc_host *host)
++{
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++
++      reset_control_assert(priv->rst_br);
++      reset_control_assert(priv->rst);
++      clk_disable_unprepare(priv->clk);
++}
++
++static void uniphier_sd_hw_reset(struct tmio_mmc_host *host)
++{
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++
++      reset_control_assert(priv->rst_hw);
++      /* For eMMC, minimum is 1us but give it 9us for good measure */
++      udelay(9);
++      reset_control_deassert(priv->rst_hw);
++      /* For eMMC, minimum is 200us but give it 300us for good measure */
++      usleep_range(300, 1000);
++}
++
++static void uniphier_sd_set_clock(struct tmio_mmc_host *host,
++                                unsigned int clock)
++{
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++      unsigned long divisor;
++      u32 tmp;
++
++      tmp = readl(host->ctl + (CTL_SD_CARD_CLK_CTL << 1));
++
++      /* stop the clock before changing its rate to avoid a glitch signal */
++      tmp &= ~CLK_CTL_SCLKEN;
++      writel(tmp, host->ctl + (CTL_SD_CARD_CLK_CTL << 1));
++
++      if (clock == 0)
++              return;
++
++      tmp &= ~UNIPHIER_SD_CLK_CTL_DIV1024;
++      tmp &= ~UNIPHIER_SD_CLK_CTL_DIV1;
++      tmp &= ~CLK_CTL_DIV_MASK;
++
++      divisor = priv->clk_rate / clock;
++
++      /*
++       * In the original IP, bit[7:0] represents the divisor.
++       * bit7 set: 1/512, ... bit0 set:1/4, all bits clear: 1/2
++       *
++       * The IP does not define a way to achieve 1/1.  For UniPhier variants,
++       * bit10 is used for 1/1.  Newer versions of UniPhier variants use
++       * bit16 for 1/1024.
++       */
++      if (divisor <= 1)
++              tmp |= UNIPHIER_SD_CLK_CTL_DIV1;
++      else if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP && divisor > 512)
++              tmp |= UNIPHIER_SD_CLK_CTL_DIV1024;
++      else
++              tmp |= roundup_pow_of_two(divisor) >> 2;
++
++      writel(tmp, host->ctl + (CTL_SD_CARD_CLK_CTL << 1));
++
++      tmp |= CLK_CTL_SCLKEN;
++      writel(tmp, host->ctl + (CTL_SD_CARD_CLK_CTL << 1));
++}
++
++static void uniphier_sd_host_init(struct tmio_mmc_host *host)
++{
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++      u32 val;
++
++      /*
++       * Connected to 32bit AXI.
++       * This register holds settings for SoC-specific internal bus
++       * connection.  What is worse, the register spec was changed,
++       * breaking the backward compatibility.  Write an appropriate
++       * value depending on a flag associated with a compatible string.
++       */
++      if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP)
++              val = 0x00000101;
++      else
++              val = 0x00000000;
++
++      writel(val, host->ctl + UNIPHIER_SD_HOST_MODE);
++
++      val = 0;
++      /*
++       * If supported, the controller can automatically
++       * enable/disable the clock line to the card.
++       */
++      if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP)
++              val |= UNIPHIER_SD_CLKCTL_OFFEN;
++
++      writel(val, host->ctl + (CTL_SD_CARD_CLK_CTL << 1));
++}
++
++static int uniphier_sd_start_signal_voltage_switch(struct mmc_host *mmc,
++                                                 struct mmc_ios *ios)
++{
++      struct tmio_mmc_host *host = mmc_priv(mmc);
++      struct uniphier_sd_priv *priv = uniphier_sd_priv(host);
++      struct pinctrl_state *pinstate;
++      u32 val, tmp;
++
++      switch (ios->signal_voltage) {
++      case MMC_SIGNAL_VOLTAGE_330:
++              val = UNIPHIER_SD_VOLT_330;
++              pinstate = priv->pinstate_default;
++              break;
++      case MMC_SIGNAL_VOLTAGE_180:
++              val = UNIPHIER_SD_VOLT_180;
++              pinstate = priv->pinstate_uhs;
++              break;
++      default:
++              return -ENOTSUPP;
++      }
++
++      tmp = readl(host->ctl + UNIPHIER_SD_VOLT);
++      tmp &= ~UNIPHIER_SD_VOLT_MASK;
++      tmp |= FIELD_PREP(UNIPHIER_SD_VOLT_MASK, val);
++      writel(tmp, host->ctl + UNIPHIER_SD_VOLT);
++
++      pinctrl_select_state(priv->pinctrl, pinstate);
++
++      return 0;
++}
++
++static int uniphier_sd_uhs_init(struct tmio_mmc_host *host,
++                              struct uniphier_sd_priv *priv)
++{
++      priv->pinctrl = devm_pinctrl_get(mmc_dev(host->mmc));
++      if (IS_ERR(priv->pinctrl))
++              return PTR_ERR(priv->pinctrl);
++
++      priv->pinstate_default = pinctrl_lookup_state(priv->pinctrl,
++                                                    PINCTRL_STATE_DEFAULT);
++      if (IS_ERR(priv->pinstate_default))
++              return PTR_ERR(priv->pinstate_default);
++
++      priv->pinstate_uhs = pinctrl_lookup_state(priv->pinctrl, "uhs");
++      if (IS_ERR(priv->pinstate_uhs))
++              return PTR_ERR(priv->pinstate_uhs);
++
++      host->ops.start_signal_voltage_switch =
++                                      uniphier_sd_start_signal_voltage_switch;
++
++      return 0;
++}
++
++static int uniphier_sd_probe(struct platform_device *pdev)
++{
++      struct device *dev = &pdev->dev;
++      struct uniphier_sd_priv *priv;
++      struct tmio_mmc_data *tmio_data;
++      struct tmio_mmc_host *host;
++      int irq, ret;
++
++      irq = platform_get_irq(pdev, 0);
++      if (irq < 0) {
++              dev_err(dev, "failed to get IRQ number");
++              return irq;
++      }
++
++      priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
++      if (!priv)
++              return -ENOMEM;
++
++      priv->caps = (unsigned long)of_device_get_match_data(dev);
++
++      priv->clk = devm_clk_get(dev, NULL);
++      if (IS_ERR(priv->clk)) {
++              dev_err(dev, "failed to get clock\n");
++              return PTR_ERR(priv->clk);
++      }
++
++      priv->rst = devm_reset_control_get_shared(dev, "host");
++      if (IS_ERR(priv->rst)) {
++              dev_err(dev, "failed to get host reset\n");
++              return PTR_ERR(priv->rst);
++      }
++
++      /* old version has one more reset */
++      if (!(priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP)) {
++              priv->rst_br = devm_reset_control_get_shared(dev, "bridge");
++              if (IS_ERR(priv->rst_br)) {
++                      dev_err(dev, "failed to get bridge reset\n");
++                      return PTR_ERR(priv->rst_br);
++              }
++      }
++
++      tmio_data = &priv->tmio_data;
++      tmio_data->flags |= TMIO_MMC_32BIT_DATA_PORT;
++
++      host = tmio_mmc_host_alloc(pdev, tmio_data);
++      if (IS_ERR(host))
++              return PTR_ERR(host);
++
++      if (host->mmc->caps & MMC_CAP_HW_RESET) {
++              priv->rst_hw = devm_reset_control_get_exclusive(dev, "hw");
++              if (IS_ERR(priv->rst_hw)) {
++                      dev_err(dev, "failed to get hw reset\n");
++                      ret = PTR_ERR(priv->rst_hw);
++                      goto free_host;
++              }
++              host->hw_reset = uniphier_sd_hw_reset;
++      }
++
++      if (host->mmc->caps & MMC_CAP_UHS) {
++              ret = uniphier_sd_uhs_init(host, priv);
++              if (ret) {
++                      dev_warn(dev,
++                               "failed to setup UHS (error %d).  Disabling UHS.",
++                               ret);
++                      host->mmc->caps &= ~MMC_CAP_UHS;
++              }
++      }
++
++      ret = devm_request_irq(dev, irq, tmio_mmc_irq, IRQF_SHARED,
++                             dev_name(dev), host);
++      if (ret)
++              goto free_host;
++
++      if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP)
++              host->dma_ops = &uniphier_sd_internal_dma_ops;
++      else
++              host->dma_ops = &uniphier_sd_external_dma_ops;
++
++      host->bus_shift = 1;
++      host->clk_enable = uniphier_sd_clk_enable;
++      host->clk_disable = uniphier_sd_clk_disable;
++      host->set_clock = uniphier_sd_set_clock;
++
++      ret = uniphier_sd_clk_enable(host);
++      if (ret)
++              goto free_host;
++
++      uniphier_sd_host_init(host);
++
++      tmio_data->ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34;
++      if (host->mmc->caps & MMC_CAP_UHS)
++              tmio_data->ocr_mask |= MMC_VDD_165_195;
++
++      tmio_data->max_segs = 1;
++      tmio_data->max_blk_count = U16_MAX;
++
++      ret = tmio_mmc_host_probe(host);
++      if (ret)
++              goto free_host;
++
++      return 0;
++
++free_host:
++      tmio_mmc_host_free(host);
++
++      return ret;
++}
++
++static int uniphier_sd_remove(struct platform_device *pdev)
++{
++      struct tmio_mmc_host *host = platform_get_drvdata(pdev);
++
++      tmio_mmc_host_remove(host);
++      uniphier_sd_clk_disable(host);
++
++      return 0;
++}
++
++static const struct of_device_id uniphier_sd_match[] = {
++      {
++              .compatible = "socionext,uniphier-sd-v2.91",
++      },
++      {
++              .compatible = "socionext,uniphier-sd-v3.1",
++              .data = (void *)(UNIPHIER_SD_CAP_EXTENDED_IP |
++                               UNIPHIER_SD_CAP_BROKEN_DMA_RX),
++      },
++      {
++              .compatible = "socionext,uniphier-sd-v3.1.1",
++              .data = (void *)UNIPHIER_SD_CAP_EXTENDED_IP,
++      },
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, uniphier_sd_match);
++
++static struct platform_driver uniphier_sd_driver = {
++      .probe = uniphier_sd_probe,
++      .remove = uniphier_sd_remove,
++      .driver = {
++              .name = "uniphier-sd",
++              .of_match_table = uniphier_sd_match,
++      },
++};
++module_platform_driver(uniphier_sd_driver);
++
++MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
++MODULE_DESCRIPTION("UniPhier SD/eMMC host controller driver");
++MODULE_LICENSE("GPL v2");
+-- 
+2.40.1
+
diff --git a/queue-4.19/nfsd-remove-incorrect-check-in-nfsd4_validate_statei.patch b/queue-4.19/nfsd-remove-incorrect-check-in-nfsd4_validate_statei.patch
new file mode 100644 (file)
index 0000000..7254b90
--- /dev/null
@@ -0,0 +1,43 @@
+From 4f26a1c4edd1c5752c89413fb4a5f437874ab4b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Jul 2023 08:38:37 -0400
+Subject: nfsd: Remove incorrect check in nfsd4_validate_stateid
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit f75546f58a70da5cfdcec5a45ffc377885ccbee8 ]
+
+If the client is calling TEST_STATEID, then it is because some event
+occurred that requires it to check all the stateids for validity and
+call FREE_STATEID on the ones that have been revoked. In this case,
+either the stateid exists in the list of stateids associated with that
+nfs4_client, in which case it should be tested, or it does not. There
+are no additional conditions to be considered.
+
+Reported-by: "Frank Ch. Eigler" <fche@redhat.com>
+Fixes: 7df302f75ee2 ("NFSD: TEST_STATEID should not return NFS4ERR_STALE_STATEID")
+Cc: stable@vger.kernel.org # v5.7+
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4state.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index 653ba2ffd4339..35aa2db611b65 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -4998,8 +4998,6 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
+       if (ZERO_STATEID(stateid) || ONE_STATEID(stateid) ||
+               CLOSE_STATEID(stateid))
+               return status;
+-      if (!same_clid(&stateid->si_opaque.so_clid, &cl->cl_clientid))
+-              return status;
+       spin_lock(&cl->cl_lock);
+       s = find_stateid_locked(cl, stateid);
+       if (!s)
+-- 
+2.40.1
+
diff --git a/queue-4.19/nfsd4-kill-warnings-on-testing-stateids-with-mismatc.patch b/queue-4.19/nfsd4-kill-warnings-on-testing-stateids-with-mismatc.patch
new file mode 100644 (file)
index 0000000..f81611c
--- /dev/null
@@ -0,0 +1,45 @@
+From 33da0f6ccbb96fe6e52d9343ac6d62d8c8be5b47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Mar 2020 10:18:49 -0400
+Subject: nfsd4: kill warnings on testing stateids with mismatched clientids
+
+From: J. Bruce Fields <bfields@redhat.com>
+
+[ Upstream commit 663e36f07666ff924012defa521f88875f6e5402 ]
+
+It's normal for a client to test a stateid from a previous instance,
+e.g. after a network partition.
+
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Reviewed-by: Benjamin Coddington <bcodding@redhat.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Stable-dep-of: f75546f58a70 ("nfsd: Remove incorrect check in nfsd4_validate_stateid")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4state.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index 78191320f8e21..653ba2ffd4339 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -4998,15 +4998,8 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
+       if (ZERO_STATEID(stateid) || ONE_STATEID(stateid) ||
+               CLOSE_STATEID(stateid))
+               return status;
+-      /* Client debugging aid. */
+-      if (!same_clid(&stateid->si_opaque.so_clid, &cl->cl_clientid)) {
+-              char addr_str[INET6_ADDRSTRLEN];
+-              rpc_ntop((struct sockaddr *)&cl->cl_addr, addr_str,
+-                               sizeof(addr_str));
+-              pr_warn_ratelimited("NFSD: client %s testing state ID "
+-                                      "with incorrect client ID\n", addr_str);
++      if (!same_clid(&stateid->si_opaque.so_clid, &cl->cl_clientid))
+               return status;
+-      }
+       spin_lock(&cl->cl_lock);
+       s = find_stateid_locked(cl, stateid);
+       if (!s)
+-- 
+2.40.1
+
diff --git a/queue-4.19/pci-endpoint-add-helper-to-get-first-unreserved-bar.patch b/queue-4.19/pci-endpoint-add-helper-to-get-first-unreserved-bar.patch
new file mode 100644 (file)
index 0000000..b19d95d
--- /dev/null
@@ -0,0 +1,72 @@
+From a15ca4dc80ee6fe71010ff55e80ab03771f66da6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jan 2019 16:45:05 +0530
+Subject: PCI: endpoint: Add helper to get first unreserved BAR
+
+From: Kishon Vijay Abraham I <kishon@ti.com>
+
+[ Upstream commit 1e9efe6c9976552e88c6e6feaca3a78b8cf5aaf6 ]
+
+Add a helper function pci_epc_get_first_free_bar() to get the first
+unreserved BAR that can be used for endpoint function.
+
+Tested-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Stable-dep-of: 7e6689b34a81 ("PCI: rockchip: Set address alignment for endpoint mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/pci-epc-core.c | 23 +++++++++++++++++++++++
+ include/linux/pci-epc.h             |  2 ++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
+index 5a099479d9aba..e4712a0f249cb 100644
+--- a/drivers/pci/endpoint/pci-epc-core.c
++++ b/drivers/pci/endpoint/pci-epc-core.c
+@@ -83,6 +83,29 @@ struct pci_epc *pci_epc_get(const char *epc_name)
+ }
+ EXPORT_SYMBOL_GPL(pci_epc_get);
++/**
++ * pci_epc_get_first_free_bar() - helper to get first unreserved BAR
++ * @epc_features: pci_epc_features structure that holds the reserved bar bitmap
++ *
++ * Invoke to get the first unreserved BAR that can be used for endpoint
++ * function. For any incorrect value in reserved_bar return '0'.
++ */
++unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
++                                      *epc_features)
++{
++      int free_bar;
++
++      if (!epc_features)
++              return 0;
++
++      free_bar = ffz(epc_features->reserved_bar);
++      if (free_bar > 5)
++              return 0;
++
++      return free_bar;
++}
++EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar);
++
+ /**
+  * pci_epc_get_features() - get the features supported by EPC
+  * @epc: the features supported by *this* EPC device will be returned
+diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
+index fcd5e50475468..dcaecf715b1cf 100644
+--- a/include/linux/pci-epc.h
++++ b/include/linux/pci-epc.h
+@@ -183,6 +183,8 @@ int pci_epc_start(struct pci_epc *epc);
+ void pci_epc_stop(struct pci_epc *epc);
+ const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
+                                                   u8 func_no);
++unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features
++                                      *epc_features);
+ struct pci_epc *pci_epc_get(const char *epc_name);
+ void pci_epc_put(struct pci_epc *epc);
+-- 
+2.40.1
+
diff --git a/queue-4.19/pci-endpoint-add-new-pci_epc_ops-to-get-epc-features.patch b/queue-4.19/pci-endpoint-add-new-pci_epc_ops-to-get-epc-features.patch
new file mode 100644 (file)
index 0000000..6600f63
--- /dev/null
@@ -0,0 +1,115 @@
+From 62bdf7eced9f5325b8c7c00018eec9cf7c85650f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jan 2019 16:44:59 +0530
+Subject: PCI: endpoint: Add new pci_epc_ops to get EPC features
+
+From: Kishon Vijay Abraham I <kishon@ti.com>
+
+[ Upstream commit 41cb8d189c9d4964df52a6f497cab7b301ae831b ]
+
+Add a new pci_epc_ops ->get_features() to get the features
+supported by the EPC. Since EPC can provide different features to
+different functions, the ->get_features() ops takes _func_no_ as
+an argument.
+
+Tested-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Stable-dep-of: 7e6689b34a81 ("PCI: rockchip: Set address alignment for endpoint mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/pci-epc-core.c | 30 +++++++++++++++++++++++++++++
+ include/linux/pci-epc.h             | 22 +++++++++++++++++++++
+ 2 files changed, 52 insertions(+)
+
+diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
+index 094dcc3203b8d..5a099479d9aba 100644
+--- a/drivers/pci/endpoint/pci-epc-core.c
++++ b/drivers/pci/endpoint/pci-epc-core.c
+@@ -83,6 +83,36 @@ struct pci_epc *pci_epc_get(const char *epc_name)
+ }
+ EXPORT_SYMBOL_GPL(pci_epc_get);
++/**
++ * pci_epc_get_features() - get the features supported by EPC
++ * @epc: the features supported by *this* EPC device will be returned
++ * @func_no: the features supported by the EPC device specific to the
++ *         endpoint function with func_no will be returned
++ *
++ * Invoke to get the features provided by the EPC which may be
++ * specific to an endpoint function. Returns pci_epc_features on success
++ * and NULL for any failures.
++ */
++const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
++                                                  u8 func_no)
++{
++      const struct pci_epc_features *epc_features;
++      unsigned long flags;
++
++      if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
++              return NULL;
++
++      if (!epc->ops->get_features)
++              return NULL;
++
++      spin_lock_irqsave(&epc->lock, flags);
++      epc_features = epc->ops->get_features(epc, func_no);
++      spin_unlock_irqrestore(&epc->lock, flags);
++
++      return epc_features;
++}
++EXPORT_SYMBOL_GPL(pci_epc_get_features);
++
+ /**
+  * pci_epc_stop() - stop the PCI link
+  * @epc: the link of the EPC device that has to be stopped
+diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
+index 931fda3e5e0d9..fcd5e50475468 100644
+--- a/include/linux/pci-epc.h
++++ b/include/linux/pci-epc.h
+@@ -59,6 +59,8 @@ struct pci_epc_ops {
+                            enum pci_epc_irq_type type, u16 interrupt_num);
+       int     (*start)(struct pci_epc *epc);
+       void    (*stop)(struct pci_epc *epc);
++      const struct pci_epc_features* (*get_features)(struct pci_epc *epc,
++                                                     u8 func_no);
+       struct module *owner;
+ };
+@@ -103,6 +105,24 @@ struct pci_epc {
+       unsigned int                    features;
+ };
++/**
++ * struct pci_epc_features - features supported by a EPC device per function
++ * @linkup_notifier: indicate if the EPC device can notify EPF driver on link up
++ * @msi_capable: indicate if the endpoint function has MSI capability
++ * @msix_capable: indicate if the endpoint function has MSI-X capability
++ * @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver
++ * @bar_fixed_64bit: bitmap to indicate fixed 64bit BARs
++ * @bar_fixed_size: Array specifying the size supported by each BAR
++ */
++struct pci_epc_features {
++      unsigned int    linkup_notifier : 1;
++      unsigned int    msi_capable : 1;
++      unsigned int    msix_capable : 1;
++      u8      reserved_bar;
++      u8      bar_fixed_64bit;
++      u64     bar_fixed_size[BAR_5 + 1];
++};
++
+ #define EPC_FEATURE_NO_LINKUP_NOTIFIER                BIT(0)
+ #define EPC_FEATURE_BAR_MASK                  (BIT(1) | BIT(2) | BIT(3))
+ #define EPC_FEATURE_MSIX_AVAILABLE            BIT(4)
+@@ -161,6 +181,8 @@ int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
+                     enum pci_epc_irq_type type, u16 interrupt_num);
+ int pci_epc_start(struct pci_epc *epc);
+ void pci_epc_stop(struct pci_epc *epc);
++const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
++                                                  u8 func_no);
+ struct pci_epc *pci_epc_get(const char *epc_name);
+ void pci_epc_put(struct pci_epc *epc);
+-- 
+2.40.1
+
diff --git a/queue-4.19/pci-endpoint-add-support-to-specify-alignment-for-bu.patch b/queue-4.19/pci-endpoint-add-support-to-specify-alignment-for-bu.patch
new file mode 100644 (file)
index 0000000..fc05aa9
--- /dev/null
@@ -0,0 +1,135 @@
+From f6001f24c202da6845f12873e32dc7f63c7e653f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2019 15:09:39 +0530
+Subject: PCI: endpoint: Add support to specify alignment for buffers allocated
+ to BARs
+
+From: Kishon Vijay Abraham I <kishon@ti.com>
+
+[ Upstream commit 2a9a801620efac92885fc9cd53594c0b9aba87a4 ]
+
+The address that is allocated using pci_epf_alloc_space() is
+directly written to the target address of the Inbound Address
+Translation unit (ie the HW component implementing inbound address
+decoding) on endpoint controllers.
+
+Designware IP [1] has a configuration parameter (CX_ATU_MIN_REGION_SIZE
+[2]) which has 64KB as default value and the lower 16 bits of the Base,
+Limit and Target registers of the Inbound ATU are fixed to zero. If the
+programmed memory address is not aligned to 64 KB boundary this causes
+memory corruption.
+
+Modify pci_epf_alloc_space() API to take alignment size as argument in
+order to allocate buffers to be mapped to BARs with an alignment that
+suits the platform where they are used.
+
+Add an 'align' parameter to epc_features which can be used by platform
+drivers to specify the BAR allocation alignment requirements and use
+this while invoking pci_epf_alloc_space().
+
+[1] "I/O and MEM Match Modes" section in DesignWare Cores PCI Express
+     Controller Databook version 4.90a
+[2]  http://www.ti.com/lit/ug/spruid7c/spruid7c.pdf
+
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Stable-dep-of: 7e6689b34a81 ("PCI: rockchip: Set address alignment for endpoint mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-test.c |  5 +++--
+ drivers/pci/endpoint/pci-epf-core.c           | 10 ++++++++--
+ include/linux/pci-epc.h                       |  2 ++
+ include/linux/pci-epf.h                       |  3 ++-
+ 4 files changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index 5cde41afb9a73..a87e7ddcff9de 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -437,7 +437,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
+       epc_features = epf_test->epc_features;
+       base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg),
+-                                 test_reg_bar);
++                                 test_reg_bar, epc_features->align);
+       if (!base) {
+               dev_err(dev, "Failed to allocated register space\n");
+               return -ENOMEM;
+@@ -451,7 +451,8 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
+               if (!!(epc_features->reserved_bar & (1 << bar)))
+                       continue;
+-              base = pci_epf_alloc_space(epf, bar_size[bar], bar);
++              base = pci_epf_alloc_space(epf, bar_size[bar], bar,
++                                         epc_features->align);
+               if (!base)
+                       dev_err(dev, "Failed to allocate space for BAR%d\n",
+                               bar);
+diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
+index 825fa24427a39..7f16b436e1cba 100644
+--- a/drivers/pci/endpoint/pci-epf-core.c
++++ b/drivers/pci/endpoint/pci-epf-core.c
+@@ -109,10 +109,12 @@ EXPORT_SYMBOL_GPL(pci_epf_free_space);
+  * pci_epf_alloc_space() - allocate memory for the PCI EPF register space
+  * @size: the size of the memory that has to be allocated
+  * @bar: the BAR number corresponding to the allocated register space
++ * @align: alignment size for the allocation region
+  *
+  * Invoke to allocate memory for the PCI EPF register space.
+  */
+-void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar)
++void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
++                        size_t align)
+ {
+       void *space;
+       struct device *dev = epf->epc->dev.parent;
+@@ -120,7 +122,11 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar)
+       if (size < 128)
+               size = 128;
+-      size = roundup_pow_of_two(size);
++
++      if (align)
++              size = ALIGN(size, align);
++      else
++              size = roundup_pow_of_two(size);
+       space = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL);
+       if (!space) {
+diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
+index dcaecf715b1cf..a9b31ef810faf 100644
+--- a/include/linux/pci-epc.h
++++ b/include/linux/pci-epc.h
+@@ -113,6 +113,7 @@ struct pci_epc {
+  * @reserved_bar: bitmap to indicate reserved BAR unavailable to function driver
+  * @bar_fixed_64bit: bitmap to indicate fixed 64bit BARs
+  * @bar_fixed_size: Array specifying the size supported by each BAR
++ * @align: alignment size required for BAR buffer allocation
+  */
+ struct pci_epc_features {
+       unsigned int    linkup_notifier : 1;
+@@ -121,6 +122,7 @@ struct pci_epc_features {
+       u8      reserved_bar;
+       u8      bar_fixed_64bit;
+       u64     bar_fixed_size[BAR_5 + 1];
++      size_t  align;
+ };
+ #define EPC_FEATURE_NO_LINKUP_NOTIFIER                BIT(0)
+diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
+index ec02f58758c84..2d6f075566824 100644
+--- a/include/linux/pci-epf.h
++++ b/include/linux/pci-epf.h
+@@ -149,7 +149,8 @@ void pci_epf_destroy(struct pci_epf *epf);
+ int __pci_epf_register_driver(struct pci_epf_driver *driver,
+                             struct module *owner);
+ void pci_epf_unregister_driver(struct pci_epf_driver *driver);
+-void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar);
++void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
++                        size_t align);
+ void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar);
+ int pci_epf_bind(struct pci_epf *epf);
+ void pci_epf_unbind(struct pci_epf *epf);
+-- 
+2.40.1
+
diff --git a/queue-4.19/pci-pci-epf-test-remove-setting-epf_bar-flags-in-fun.patch b/queue-4.19/pci-pci-epf-test-remove-setting-epf_bar-flags-in-fun.patch
new file mode 100644 (file)
index 0000000..1dfc9fc
--- /dev/null
@@ -0,0 +1,39 @@
+From 6a539b42cb7a89d3c63bc8fee76603c1e4e45be8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jan 2019 16:45:07 +0530
+Subject: PCI: pci-epf-test: Remove setting epf_bar flags in function driver
+
+From: Kishon Vijay Abraham I <kishon@ti.com>
+
+[ Upstream commit 0342e9a797db42a7d4d083d10b5d3f38b0cfc193 ]
+
+Now that pci_epf_alloc_space() sets BAR MEM TYPE flags as 64Bit or
+32Bit based on size, remove setting it in function driver.
+
+Tested-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Stable-dep-of: 7e6689b34a81 ("PCI: rockchip: Set address alignment for endpoint mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-test.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index 09a1e449cd1c6..878e5c97963cb 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -406,10 +406,6 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
+       for (bar = BAR_0; bar <= BAR_5; bar++) {
+               epf_bar = &epf->bar[bar];
+-              epf_bar->flags |= upper_32_bits(epf_bar->size) ?
+-                      PCI_BASE_ADDRESS_MEM_TYPE_64 :
+-                      PCI_BASE_ADDRESS_MEM_TYPE_32;
+-
+               ret = pci_epc_set_bar(epc, epf->func_no, epf_bar);
+               if (ret) {
+                       pci_epf_free_space(epf, epf_test->reg[bar], bar);
+-- 
+2.40.1
+
diff --git a/queue-4.19/pci-pci-epf-test-use-pci_epc_get_features-to-get-epc.patch b/queue-4.19/pci-pci-epf-test-use-pci_epc_get_features-to-get-epc.patch
new file mode 100644 (file)
index 0000000..64a8b5d
--- /dev/null
@@ -0,0 +1,207 @@
+From bd1175a424859cb6bfcabe731f157c40b6674df4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jan 2019 16:45:09 +0530
+Subject: PCI: pci-epf-test: Use pci_epc_get_features() to get EPC features
+
+From: Kishon Vijay Abraham I <kishon@ti.com>
+
+[ Upstream commit 2c04c5b8eef797dca99699cfb55ff42dd3c12c23 ]
+
+Use pci_epc_get_features() to get EPC features such as linkup
+notifier support, MSI/MSIX capable, BAR configuration etc and use it
+for configuring pci-epf-test. Since these features are now obtained
+directly from EPC driver, remove pci_epf_test_data which was initially
+added to have EPC features in endpoint function driver.
+
+Tested-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Stable-dep-of: 7e6689b34a81 ("PCI: rockchip: Set address alignment for endpoint mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-test.c | 87 ++++++++++++-------
+ 1 file changed, 54 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index 878e5c97963cb..5cde41afb9a73 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -47,9 +47,8 @@ struct pci_epf_test {
+       void                    *reg[6];
+       struct pci_epf          *epf;
+       enum pci_barno          test_reg_bar;
+-      bool                    linkup_notifier;
+-      bool                    msix_available;
+       struct delayed_work     cmd_handler;
++      const struct pci_epc_features *epc_features;
+ };
+ struct pci_epf_test_reg {
+@@ -71,11 +70,6 @@ static struct pci_epf_header test_header = {
+       .interrupt_pin  = PCI_INTERRUPT_INTA,
+ };
+-struct pci_epf_test_data {
+-      enum pci_barno  test_reg_bar;
+-      bool            linkup_notifier;
+-};
+-
+ static size_t bar_size[] = { 512, 512, 1024, 16384, 131072, 1048576 };
+ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
+@@ -402,10 +396,16 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
+       struct device *dev = &epf->dev;
+       struct pci_epf_test *epf_test = epf_get_drvdata(epf);
+       enum pci_barno test_reg_bar = epf_test->test_reg_bar;
++      const struct pci_epc_features *epc_features;
++
++      epc_features = epf_test->epc_features;
+       for (bar = BAR_0; bar <= BAR_5; bar++) {
+               epf_bar = &epf->bar[bar];
++              if (!!(epc_features->reserved_bar & (1 << bar)))
++                      continue;
++
+               ret = pci_epc_set_bar(epc, epf->func_no, epf_bar);
+               if (ret) {
+                       pci_epf_free_space(epf, epf_test->reg[bar], bar);
+@@ -432,6 +432,9 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
+       void *base;
+       int bar;
+       enum pci_barno test_reg_bar = epf_test->test_reg_bar;
++      const struct pci_epc_features *epc_features;
++
++      epc_features = epf_test->epc_features;
+       base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg),
+                                  test_reg_bar);
+@@ -444,6 +447,10 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
+       for (bar = BAR_0; bar <= BAR_5; bar++) {
+               if (bar == test_reg_bar)
+                       continue;
++
++              if (!!(epc_features->reserved_bar & (1 << bar)))
++                      continue;
++
+               base = pci_epf_alloc_space(epf, bar_size[bar], bar);
+               if (!base)
+                       dev_err(dev, "Failed to allocate space for BAR%d\n",
+@@ -454,25 +461,50 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
+       return 0;
+ }
++static void pci_epf_configure_bar(struct pci_epf *epf,
++                                const struct pci_epc_features *epc_features)
++{
++      struct pci_epf_bar *epf_bar;
++      bool bar_fixed_64bit;
++      int i;
++
++      for (i = BAR_0; i <= BAR_5; i++) {
++              epf_bar = &epf->bar[i];
++              bar_fixed_64bit = !!(epc_features->bar_fixed_64bit & (1 << i));
++              if (bar_fixed_64bit)
++                      epf_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
++              if (epc_features->bar_fixed_size[i])
++                      bar_size[i] = epc_features->bar_fixed_size[i];
++      }
++}
++
+ static int pci_epf_test_bind(struct pci_epf *epf)
+ {
+       int ret;
+       struct pci_epf_test *epf_test = epf_get_drvdata(epf);
+       struct pci_epf_header *header = epf->header;
++      const struct pci_epc_features *epc_features;
++      enum pci_barno test_reg_bar = BAR_0;
+       struct pci_epc *epc = epf->epc;
+       struct device *dev = &epf->dev;
++      bool linkup_notifier = false;
++      bool msix_capable = false;
++      bool msi_capable = true;
+       if (WARN_ON_ONCE(!epc))
+               return -EINVAL;
+-      if (epc->features & EPC_FEATURE_NO_LINKUP_NOTIFIER)
+-              epf_test->linkup_notifier = false;
+-      else
+-              epf_test->linkup_notifier = true;
+-
+-      epf_test->msix_available = epc->features & EPC_FEATURE_MSIX_AVAILABLE;
++      epc_features = pci_epc_get_features(epc, epf->func_no);
++      if (epc_features) {
++              linkup_notifier = epc_features->linkup_notifier;
++              msix_capable = epc_features->msix_capable;
++              msi_capable = epc_features->msi_capable;
++              test_reg_bar = pci_epc_get_first_free_bar(epc_features);
++              pci_epf_configure_bar(epf, epc_features);
++      }
+-      epf_test->test_reg_bar = EPC_FEATURE_GET_BAR(epc->features);
++      epf_test->test_reg_bar = test_reg_bar;
++      epf_test->epc_features = epc_features;
+       ret = pci_epc_write_header(epc, epf->func_no, header);
+       if (ret) {
+@@ -488,13 +520,15 @@ static int pci_epf_test_bind(struct pci_epf *epf)
+       if (ret)
+               return ret;
+-      ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts);
+-      if (ret) {
+-              dev_err(dev, "MSI configuration failed\n");
+-              return ret;
++      if (msi_capable) {
++              ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts);
++              if (ret) {
++                      dev_err(dev, "MSI configuration failed\n");
++                      return ret;
++              }
+       }
+-      if (epf_test->msix_available) {
++      if (msix_capable) {
+               ret = pci_epc_set_msix(epc, epf->func_no, epf->msix_interrupts);
+               if (ret) {
+                       dev_err(dev, "MSI-X configuration failed\n");
+@@ -502,7 +536,7 @@ static int pci_epf_test_bind(struct pci_epf *epf)
+               }
+       }
+-      if (!epf_test->linkup_notifier)
++      if (!linkup_notifier)
+               queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work);
+       return 0;
+@@ -519,17 +553,6 @@ static int pci_epf_test_probe(struct pci_epf *epf)
+ {
+       struct pci_epf_test *epf_test;
+       struct device *dev = &epf->dev;
+-      const struct pci_epf_device_id *match;
+-      struct pci_epf_test_data *data;
+-      enum pci_barno test_reg_bar = BAR_0;
+-      bool linkup_notifier = true;
+-
+-      match = pci_epf_match_device(pci_epf_test_ids, epf);
+-      data = (struct pci_epf_test_data *)match->driver_data;
+-      if (data) {
+-              test_reg_bar = data->test_reg_bar;
+-              linkup_notifier = data->linkup_notifier;
+-      }
+       epf_test = devm_kzalloc(dev, sizeof(*epf_test), GFP_KERNEL);
+       if (!epf_test)
+@@ -537,8 +560,6 @@ static int pci_epf_test_probe(struct pci_epf *epf)
+       epf->header = &test_header;
+       epf_test->epf = epf;
+-      epf_test->test_reg_bar = test_reg_bar;
+-      epf_test->linkup_notifier = linkup_notifier;
+       INIT_DELAYED_WORK(&epf_test->cmd_handler, pci_epf_test_cmd_handler);
+-- 
+2.40.1
+
diff --git a/queue-4.19/pci-rockchip-populate-get_features-dw_pcie_ep_ops.patch b/queue-4.19/pci-rockchip-populate-get_features-dw_pcie_ep_ops.patch
new file mode 100644 (file)
index 0000000..20d24eb
--- /dev/null
@@ -0,0 +1,55 @@
+From 1af927614d7669730343e869536001fa06c08749 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Jan 2019 16:45:03 +0530
+Subject: PCI: rockchip: Populate ->get_features() dw_pcie_ep_ops
+
+From: Kishon Vijay Abraham I <kishon@ti.com>
+
+[ Upstream commit 146221768c74bbd969f968b61ec95a0254a6b311 ]
+
+Populate ->get_features() dw_pcie_ep_ops to return the EPC features
+supported by Rockchip PCIe endpoint controller.
+
+Tested-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Stable-dep-of: 7e6689b34a81 ("PCI: rockchip: Set address alignment for endpoint mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-rockchip-ep.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
+index 4d3a589af1296..48b4a1c35523f 100644
+--- a/drivers/pci/controller/pcie-rockchip-ep.c
++++ b/drivers/pci/controller/pcie-rockchip-ep.c
+@@ -483,6 +483,18 @@ static int rockchip_pcie_ep_start(struct pci_epc *epc)
+       return 0;
+ }
++static const struct pci_epc_features rockchip_pcie_epc_features = {
++      .linkup_notifier = false,
++      .msi_capable = true,
++      .msix_capable = false,
++};
++
++static const struct pci_epc_features*
++rockchip_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
++{
++      return &rockchip_pcie_epc_features;
++}
++
+ static const struct pci_epc_ops rockchip_pcie_epc_ops = {
+       .write_header   = rockchip_pcie_ep_write_header,
+       .set_bar        = rockchip_pcie_ep_set_bar,
+@@ -493,6 +505,7 @@ static const struct pci_epc_ops rockchip_pcie_epc_ops = {
+       .get_msi        = rockchip_pcie_ep_get_msi,
+       .raise_irq      = rockchip_pcie_ep_raise_irq,
+       .start          = rockchip_pcie_ep_start,
++      .get_features   = rockchip_pcie_ep_get_features,
+ };
+ static int rockchip_pcie_parse_ep_dt(struct rockchip_pcie *rockchip,
+-- 
+2.40.1
+
diff --git a/queue-4.19/pci-rockchip-set-address-alignment-for-endpoint-mode.patch b/queue-4.19/pci-rockchip-set-address-alignment-for-endpoint-mode.patch
new file mode 100644 (file)
index 0000000..90428a0
--- /dev/null
@@ -0,0 +1,40 @@
+From a9072cf071373984db4fbd54bbb2c45b96c06188 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Apr 2023 09:46:58 +0200
+Subject: PCI: rockchip: Set address alignment for endpoint mode
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+[ Upstream commit 7e6689b34a815bd379dfdbe9855d36f395ef056c ]
+
+The address translation unit of the rockchip EP controller does not use
+the lower 8 bits of a PCIe-space address to map local memory. Thus we
+must set the align feature field to 256 to let the user know about this
+constraint.
+
+Link: https://lore.kernel.org/r/20230418074700.1083505-12-rick.wertenbroek@gmail.com
+Fixes: cf590b078391 ("PCI: rockchip: Add EP driver for Rockchip PCIe controller")
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Rick Wertenbroek <rick.wertenbroek@gmail.com>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-rockchip-ep.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
+index 48b4a1c35523f..d6e9013936446 100644
+--- a/drivers/pci/controller/pcie-rockchip-ep.c
++++ b/drivers/pci/controller/pcie-rockchip-ep.c
+@@ -487,6 +487,7 @@ static const struct pci_epc_features rockchip_pcie_epc_features = {
+       .linkup_notifier = false,
+       .msi_capable = true,
+       .msix_capable = false,
++      .align = 256,
+ };
+ static const struct pci_epc_features*
+-- 
+2.40.1
+
diff --git a/queue-4.19/pcmcia-rsrc_nonstatic-fix-memory-leak-in-nonstatic_r.patch b/queue-4.19/pcmcia-rsrc_nonstatic-fix-memory-leak-in-nonstatic_r.patch
new file mode 100644 (file)
index 0000000..d4b6e5d
--- /dev/null
@@ -0,0 +1,66 @@
+From 12de82c1f0c4f743500b127c5b6ad680c851075c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 20:45:29 +0200
+Subject: pcmcia: rsrc_nonstatic: Fix memory leak in
+ nonstatic_release_resource_db()
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit c85fd9422fe0f5d667305efb27f56d09eab120b0 ]
+
+When nonstatic_release_resource_db() frees all resources associated
+with an PCMCIA socket, it forgets to free socket_data too, causing
+a memory leak observable with kmemleak:
+
+unreferenced object 0xc28d1000 (size 64):
+  comm "systemd-udevd", pid 297, jiffies 4294898478 (age 194.484s)
+  hex dump (first 32 bytes):
+    00 00 00 00 00 00 00 00 f0 85 0e c3 00 00 00 00  ................
+    00 00 00 00 0c 10 8d c2 00 00 00 00 00 00 00 00  ................
+  backtrace:
+    [<ffda4245>] __kmem_cache_alloc_node+0x2d7/0x4a0
+    [<7e51f0c8>] kmalloc_trace+0x31/0xa4
+    [<d52b4ca0>] nonstatic_init+0x24/0x1a4 [pcmcia_rsrc]
+    [<a2f13e08>] pcmcia_register_socket+0x200/0x35c [pcmcia_core]
+    [<a728be1b>] yenta_probe+0x4d8/0xa70 [yenta_socket]
+    [<c48fac39>] pci_device_probe+0x99/0x194
+    [<84b7c690>] really_probe+0x181/0x45c
+    [<8060fe6e>] __driver_probe_device+0x75/0x1f4
+    [<b9b76f43>] driver_probe_device+0x28/0xac
+    [<648b766f>] __driver_attach+0xeb/0x1e4
+    [<6e9659eb>] bus_for_each_dev+0x61/0xb4
+    [<25a669f3>] driver_attach+0x1e/0x28
+    [<d8671d6b>] bus_add_driver+0x102/0x20c
+    [<df0d323c>] driver_register+0x5b/0x120
+    [<942cd8a4>] __pci_register_driver+0x44/0x4c
+    [<e536027e>] __UNIQUE_ID___addressable_cleanup_module188+0x1c/0xfffff000 [iTCO_vendor_support]
+
+Fix this by freeing socket_data too.
+
+Tested on a Acer Travelmate 4002WLMi by manually binding/unbinding
+the yenta_cardbus driver (yenta_socket).
+
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Message-ID: <20230512184529.5094-1-W_Armin@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pcmcia/rsrc_nonstatic.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
+index 123420cac6b54..b75b12c2c702d 100644
+--- a/drivers/pcmcia/rsrc_nonstatic.c
++++ b/drivers/pcmcia/rsrc_nonstatic.c
+@@ -1056,6 +1056,8 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
+               q = p->next;
+               kfree(p);
+       }
++
++      kfree(data);
+ }
+-- 
+2.40.1
+
diff --git a/queue-4.19/powerpc-64s-radix-fix-soft-dirty-tracking.patch b/queue-4.19/powerpc-64s-radix-fix-soft-dirty-tracking.patch
new file mode 100644 (file)
index 0000000..cf7008d
--- /dev/null
@@ -0,0 +1,61 @@
+From eea2d6aa84aed635e7dfd151fd07f33d4b7956c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 May 2023 21:42:24 +1000
+Subject: powerpc/64s/radix: Fix soft dirty tracking
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit 66b2ca086210732954a7790d63d35542936fc664 ]
+
+It was reported that soft dirty tracking doesn't work when using the
+Radix MMU.
+
+The tracking is supposed to work by clearing the soft dirty bit for a
+mapping and then write protecting the PTE. If/when the page is written
+to, a page fault occurs and the soft dirty bit is added back via
+pte_mkdirty(). For example in wp_page_reuse():
+
+       entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+       if (ptep_set_access_flags(vma, vmf->address, vmf->pte, entry, 1))
+               update_mmu_cache(vma, vmf->address, vmf->pte);
+
+Unfortunately on radix _PAGE_SOFTDIRTY is being dropped by
+radix__ptep_set_access_flags(), called from ptep_set_access_flags(),
+meaning the soft dirty bit is not set even though the page has been
+written to.
+
+Fix it by adding _PAGE_SOFTDIRTY to the set of bits that are able to be
+changed in radix__ptep_set_access_flags().
+
+Fixes: b0b5e9b13047 ("powerpc/mm/radix: Add radix pte #defines")
+Cc: stable@vger.kernel.org # v4.7+
+Reported-by: Dan Horák <dan@danny.cz>
+Link: https://lore.kernel.org/r/20230511095558.56663a50f86bdc4cd97700b7@danny.cz
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230511114224.977423-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/pgtable-radix.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
+index 9ee235fca4278..75cbedaac5d26 100644
+--- a/arch/powerpc/mm/pgtable-radix.c
++++ b/arch/powerpc/mm/pgtable-radix.c
+@@ -1041,8 +1041,8 @@ void radix__ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep,
+                                 pte_t entry, unsigned long address, int psize)
+ {
+       struct mm_struct *mm = vma->vm_mm;
+-      unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED |
+-                                            _PAGE_RW | _PAGE_EXEC);
++      unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_SOFT_DIRTY |
++                                            _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
+       unsigned long change = pte_val(entry) ^ pte_val(*ptep);
+       /*
+-- 
+2.40.1
+
diff --git a/queue-4.19/powerpc-mm-dump-block-address-translation-on-book3s-.patch b/queue-4.19/powerpc-mm-dump-block-address-translation-on-book3s-.patch
new file mode 100644 (file)
index 0000000..a3eb2b7
--- /dev/null
@@ -0,0 +1,256 @@
+From 6b94d52bb965d57cd503294d03df13b3be61f62c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Dec 2018 17:40:25 +0000
+Subject: powerpc/mm: dump block address translation on book3s/32
+
+From: Christophe Leroy <christophe.leroy@c-s.fr>
+
+[ Upstream commit 7c91efce1608325634494b25ff6491320208e457 ]
+
+This patch adds a debugfs file to dump block address translation:
+
+~# cat /sys/kernel/debug/powerpc/block_address_translation
+---[ Instruction Block Address Translations ]---
+0:         -
+1:         -
+2: 0xc0000000-0xcfffffff 0x00000000 Kernel EXEC coherent
+3: 0xd0000000-0xdfffffff 0x10000000 Kernel EXEC coherent
+4:         -
+5:         -
+6:         -
+7:         -
+
+---[ Data Block Address Translations ]---
+0:         -
+1:         -
+2: 0xc0000000-0xcfffffff 0x00000000 Kernel RW coherent
+3: 0xd0000000-0xdfffffff 0x10000000 Kernel RW coherent
+4:         -
+5:         -
+6:         -
+7:         -
+
+Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Stable-dep-of: 66b2ca086210 ("powerpc/64s/radix: Fix soft dirty tracking")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/book3s/32/mmu-hash.h |   4 +
+ arch/powerpc/mm/Makefile                      |   2 +-
+ arch/powerpc/mm/dump_bats.c                   | 173 ++++++++++++++++++
+ 3 files changed, 178 insertions(+), 1 deletion(-)
+ create mode 100644 arch/powerpc/mm/dump_bats.c
+
+diff --git a/arch/powerpc/include/asm/book3s/32/mmu-hash.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
+index 5bd26c218b94f..958b18cecc96a 100644
+--- a/arch/powerpc/include/asm/book3s/32/mmu-hash.h
++++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
+@@ -34,8 +34,12 @@
+ #define BAT_PHYS_ADDR(x) ((u32)((x & 0x00000000fffe0000ULL) | \
+                               ((x & 0x0000000e00000000ULL) >> 24) | \
+                               ((x & 0x0000000100000000ULL) >> 30)))
++#define PHYS_BAT_ADDR(x) (((u64)(x) & 0x00000000fffe0000ULL) | \
++                        (((u64)(x) << 24) & 0x0000000e00000000ULL) | \
++                        (((u64)(x) << 30) & 0x0000000100000000ULL))
+ #else
+ #define BAT_PHYS_ADDR(x) (x)
++#define PHYS_BAT_ADDR(x) ((x) & 0xfffe0000)
+ #endif
+ struct ppc_bat {
+diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
+index d2784730c0e5d..8ace67f002752 100644
+--- a/arch/powerpc/mm/Makefile
++++ b/arch/powerpc/mm/Makefile
+@@ -47,7 +47,7 @@ ifdef CONFIG_PPC_PTDUMP
+ obj-$(CONFIG_4xx)             += dump_linuxpagetables-generic.o
+ obj-$(CONFIG_PPC_8xx)         += dump_linuxpagetables-8xx.o
+ obj-$(CONFIG_PPC_BOOK3E_MMU)  += dump_linuxpagetables-generic.o
+-obj-$(CONFIG_PPC_BOOK3S_32)   += dump_linuxpagetables-generic.o dump_sr.o
++obj-$(CONFIG_PPC_BOOK3S_32)   += dump_linuxpagetables-generic.o dump_bats.o dump_sr.o
+ obj-$(CONFIG_PPC_BOOK3S_64)   += dump_linuxpagetables-book3s64.o
+ endif
+ obj-$(CONFIG_PPC_HTDUMP)      += dump_hashpagetable.o
+diff --git a/arch/powerpc/mm/dump_bats.c b/arch/powerpc/mm/dump_bats.c
+new file mode 100644
+index 0000000000000..a0d23e96e841a
+--- /dev/null
++++ b/arch/powerpc/mm/dump_bats.c
+@@ -0,0 +1,173 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright 2018, Christophe Leroy CS S.I.
++ * <christophe.leroy@c-s.fr>
++ *
++ * This dumps the content of BATS
++ */
++
++#include <asm/debugfs.h>
++#include <asm/pgtable.h>
++#include <asm/cpu_has_feature.h>
++
++static char *pp_601(int k, int pp)
++{
++      if (pp == 0)
++              return k ? "NA" : "RWX";
++      if (pp == 1)
++              return k ? "ROX" : "RWX";
++      if (pp == 2)
++              return k ? "RWX" : "RWX";
++      return k ? "ROX" : "ROX";
++}
++
++static void bat_show_601(struct seq_file *m, int idx, u32 lower, u32 upper)
++{
++      u32 blpi = upper & 0xfffe0000;
++      u32 k = (upper >> 2) & 3;
++      u32 pp = upper & 3;
++      phys_addr_t pbn = PHYS_BAT_ADDR(lower);
++      u32 bsm = lower & 0x3ff;
++      u32 size = (bsm + 1) << 17;
++
++      seq_printf(m, "%d: ", idx);
++      if (!(lower & 0x40)) {
++              seq_puts(m, "        -\n");
++              return;
++      }
++
++      seq_printf(m, "0x%08x-0x%08x ", blpi, blpi + size - 1);
++#ifdef CONFIG_PHYS_64BIT
++      seq_printf(m, "0x%016llx ", pbn);
++#else
++      seq_printf(m, "0x%08x ", pbn);
++#endif
++
++      seq_printf(m, "Kernel %s User %s", pp_601(k & 2, pp), pp_601(k & 1, pp));
++
++      if (lower & _PAGE_WRITETHRU)
++              seq_puts(m, "write through ");
++      if (lower & _PAGE_NO_CACHE)
++              seq_puts(m, "no cache ");
++      if (lower & _PAGE_COHERENT)
++              seq_puts(m, "coherent ");
++      seq_puts(m, "\n");
++}
++
++#define BAT_SHOW_601(_m, _n, _l, _u) bat_show_601(_m, _n, mfspr(_l), mfspr(_u))
++
++static int bats_show_601(struct seq_file *m, void *v)
++{
++      seq_puts(m, "---[ Block Address Translation ]---\n");
++
++      BAT_SHOW_601(m, 0, SPRN_IBAT0L, SPRN_IBAT0U);
++      BAT_SHOW_601(m, 1, SPRN_IBAT1L, SPRN_IBAT1U);
++      BAT_SHOW_601(m, 2, SPRN_IBAT2L, SPRN_IBAT2U);
++      BAT_SHOW_601(m, 3, SPRN_IBAT3L, SPRN_IBAT3U);
++
++      return 0;
++}
++
++static void bat_show_603(struct seq_file *m, int idx, u32 lower, u32 upper, bool is_d)
++{
++      u32 bepi = upper & 0xfffe0000;
++      u32 bl = (upper >> 2) & 0x7ff;
++      u32 k = upper & 3;
++      phys_addr_t brpn = PHYS_BAT_ADDR(lower);
++      u32 size = (bl + 1) << 17;
++
++      seq_printf(m, "%d: ", idx);
++      if (k == 0) {
++              seq_puts(m, "        -\n");
++              return;
++      }
++
++      seq_printf(m, "0x%08x-0x%08x ", bepi, bepi + size - 1);
++#ifdef CONFIG_PHYS_64BIT
++      seq_printf(m, "0x%016llx ", brpn);
++#else
++      seq_printf(m, "0x%08x ", brpn);
++#endif
++
++      if (k == 1)
++              seq_puts(m, "User ");
++      else if (k == 2)
++              seq_puts(m, "Kernel ");
++      else
++              seq_puts(m, "Kernel/User ");
++
++      if (lower & BPP_RX)
++              seq_puts(m, is_d ? "RO " : "EXEC ");
++      else if (lower & BPP_RW)
++              seq_puts(m, is_d ? "RW " : "EXEC ");
++      else
++              seq_puts(m, is_d ? "NA " : "NX   ");
++
++      if (lower & _PAGE_WRITETHRU)
++              seq_puts(m, "write through ");
++      if (lower & _PAGE_NO_CACHE)
++              seq_puts(m, "no cache ");
++      if (lower & _PAGE_COHERENT)
++              seq_puts(m, "coherent ");
++      if (lower & _PAGE_GUARDED)
++              seq_puts(m, "guarded ");
++      seq_puts(m, "\n");
++}
++
++#define BAT_SHOW_603(_m, _n, _l, _u, _d) bat_show_603(_m, _n, mfspr(_l), mfspr(_u), _d)
++
++static int bats_show_603(struct seq_file *m, void *v)
++{
++      seq_puts(m, "---[ Instruction Block Address Translation ]---\n");
++
++      BAT_SHOW_603(m, 0, SPRN_IBAT0L, SPRN_IBAT0U, false);
++      BAT_SHOW_603(m, 1, SPRN_IBAT1L, SPRN_IBAT1U, false);
++      BAT_SHOW_603(m, 2, SPRN_IBAT2L, SPRN_IBAT2U, false);
++      BAT_SHOW_603(m, 3, SPRN_IBAT3L, SPRN_IBAT3U, false);
++      if (mmu_has_feature(MMU_FTR_USE_HIGH_BATS)) {
++              BAT_SHOW_603(m, 4, SPRN_IBAT4L, SPRN_IBAT4U, false);
++              BAT_SHOW_603(m, 5, SPRN_IBAT5L, SPRN_IBAT5U, false);
++              BAT_SHOW_603(m, 6, SPRN_IBAT6L, SPRN_IBAT6U, false);
++              BAT_SHOW_603(m, 7, SPRN_IBAT7L, SPRN_IBAT7U, false);
++      }
++
++      seq_puts(m, "\n---[ Data Block Address Translation ]---\n");
++
++      BAT_SHOW_603(m, 0, SPRN_DBAT0L, SPRN_DBAT0U, true);
++      BAT_SHOW_603(m, 1, SPRN_DBAT1L, SPRN_DBAT1U, true);
++      BAT_SHOW_603(m, 2, SPRN_DBAT2L, SPRN_DBAT2U, true);
++      BAT_SHOW_603(m, 3, SPRN_DBAT3L, SPRN_DBAT3U, true);
++      if (mmu_has_feature(MMU_FTR_USE_HIGH_BATS)) {
++              BAT_SHOW_603(m, 4, SPRN_DBAT4L, SPRN_DBAT4U, true);
++              BAT_SHOW_603(m, 5, SPRN_DBAT5L, SPRN_DBAT5U, true);
++              BAT_SHOW_603(m, 6, SPRN_DBAT6L, SPRN_DBAT6U, true);
++              BAT_SHOW_603(m, 7, SPRN_DBAT7L, SPRN_DBAT7U, true);
++      }
++
++      return 0;
++}
++
++static int bats_open(struct inode *inode, struct file *file)
++{
++      if (cpu_has_feature(CPU_FTR_601))
++              return single_open(file, bats_show_601, NULL);
++
++      return single_open(file, bats_show_603, NULL);
++}
++
++static const struct file_operations bats_fops = {
++      .open           = bats_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = single_release,
++};
++
++static int __init bats_init(void)
++{
++      struct dentry *debugfs_file;
++
++      debugfs_file = debugfs_create_file("block_address_translation", 0400,
++                                         powerpc_debugfs_root, NULL, &bats_fops);
++      return debugfs_file ? 0 : -ENOMEM;
++}
++device_initcall(bats_init);
+-- 
+2.40.1
+
diff --git a/queue-4.19/powerpc-mm-dump-segment-registers-on-book3s-32.patch b/queue-4.19/powerpc-mm-dump-segment-registers-on-book3s-32.patch
new file mode 100644 (file)
index 0000000..b3cdcdf
--- /dev/null
@@ -0,0 +1,130 @@
+From 8f066e89dffcf8a6e82e3025ac11e42fdb988270 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Nov 2018 17:06:43 +0000
+Subject: powerpc/mm: dump segment registers on book3s/32
+
+From: Christophe Leroy <christophe.leroy@c-s.fr>
+
+[ Upstream commit 0261a508c9fcb33e60f09cac42032f85c31e2039 ]
+
+This patch creates a debugfs file to see content of
+segment registers
+
+  # cat /sys/kernel/debug/segment_registers
+  ---[ User Segments ]---
+  0x00000000-0x0fffffff Kern key 1 User key 1 VSID 0xade2b0
+  0x10000000-0x1fffffff Kern key 1 User key 1 VSID 0xade3c1
+  0x20000000-0x2fffffff Kern key 1 User key 1 VSID 0xade4d2
+  0x30000000-0x3fffffff Kern key 1 User key 1 VSID 0xade5e3
+  0x40000000-0x4fffffff Kern key 1 User key 1 VSID 0xade6f4
+  0x50000000-0x5fffffff Kern key 1 User key 1 VSID 0xade805
+  0x60000000-0x6fffffff Kern key 1 User key 1 VSID 0xade916
+  0x70000000-0x7fffffff Kern key 1 User key 1 VSID 0xadea27
+  0x80000000-0x8fffffff Kern key 1 User key 1 VSID 0xadeb38
+  0x90000000-0x9fffffff Kern key 1 User key 1 VSID 0xadec49
+  0xa0000000-0xafffffff Kern key 1 User key 1 VSID 0xaded5a
+  0xb0000000-0xbfffffff Kern key 1 User key 1 VSID 0xadee6b
+
+  ---[ Kernel Segments ]---
+  0xc0000000-0xcfffffff Kern key 0 User key 1 VSID 0x000ccc
+  0xd0000000-0xdfffffff Kern key 0 User key 1 VSID 0x000ddd
+  0xe0000000-0xefffffff Kern key 0 User key 1 VSID 0x000eee
+  0xf0000000-0xffffffff Kern key 0 User key 1 VSID 0x000fff
+
+Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
+[mpe: Move it under /sys/kernel/debug/powerpc, make sr_init() __init]
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Stable-dep-of: 66b2ca086210 ("powerpc/64s/radix: Fix soft dirty tracking")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/Makefile  |  2 +-
+ arch/powerpc/mm/dump_sr.c | 64 +++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 65 insertions(+), 1 deletion(-)
+ create mode 100644 arch/powerpc/mm/dump_sr.c
+
+diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
+index 3c844bdd16c4e..d2784730c0e5d 100644
+--- a/arch/powerpc/mm/Makefile
++++ b/arch/powerpc/mm/Makefile
+@@ -47,7 +47,7 @@ ifdef CONFIG_PPC_PTDUMP
+ obj-$(CONFIG_4xx)             += dump_linuxpagetables-generic.o
+ obj-$(CONFIG_PPC_8xx)         += dump_linuxpagetables-8xx.o
+ obj-$(CONFIG_PPC_BOOK3E_MMU)  += dump_linuxpagetables-generic.o
+-obj-$(CONFIG_PPC_BOOK3S_32)   += dump_linuxpagetables-generic.o
++obj-$(CONFIG_PPC_BOOK3S_32)   += dump_linuxpagetables-generic.o dump_sr.o
+ obj-$(CONFIG_PPC_BOOK3S_64)   += dump_linuxpagetables-book3s64.o
+ endif
+ obj-$(CONFIG_PPC_HTDUMP)      += dump_hashpagetable.o
+diff --git a/arch/powerpc/mm/dump_sr.c b/arch/powerpc/mm/dump_sr.c
+new file mode 100644
+index 0000000000000..501843664bb91
+--- /dev/null
++++ b/arch/powerpc/mm/dump_sr.c
+@@ -0,0 +1,64 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright 2018, Christophe Leroy CS S.I.
++ * <christophe.leroy@c-s.fr>
++ *
++ * This dumps the content of Segment Registers
++ */
++
++#include <asm/debugfs.h>
++
++static void seg_show(struct seq_file *m, int i)
++{
++      u32 val = mfsrin(i << 28);
++
++      seq_printf(m, "0x%01x0000000-0x%01xfffffff ", i, i);
++      seq_printf(m, "Kern key %d ", (val >> 30) & 1);
++      seq_printf(m, "User key %d ", (val >> 29) & 1);
++      if (val & 0x80000000) {
++              seq_printf(m, "Device 0x%03x", (val >> 20) & 0x1ff);
++              seq_printf(m, "-0x%05x", val & 0xfffff);
++      } else {
++              if (val & 0x10000000)
++                      seq_puts(m, "No Exec ");
++              seq_printf(m, "VSID 0x%06x", val & 0xffffff);
++      }
++      seq_puts(m, "\n");
++}
++
++static int sr_show(struct seq_file *m, void *v)
++{
++      int i;
++
++      seq_puts(m, "---[ User Segments ]---\n");
++      for (i = 0; i < TASK_SIZE >> 28; i++)
++              seg_show(m, i);
++
++      seq_puts(m, "\n---[ Kernel Segments ]---\n");
++      for (; i < 16; i++)
++              seg_show(m, i);
++
++      return 0;
++}
++
++static int sr_open(struct inode *inode, struct file *file)
++{
++      return single_open(file, sr_show, NULL);
++}
++
++static const struct file_operations sr_fops = {
++      .open           = sr_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = single_release,
++};
++
++static int __init sr_init(void)
++{
++      struct dentry *debugfs_file;
++
++      debugfs_file = debugfs_create_file("segment_registers", 0400,
++                                         powerpc_debugfs_root, NULL, &sr_fops);
++      return debugfs_file ? 0 : -ENOMEM;
++}
++device_initcall(sr_init);
+-- 
+2.40.1
+
diff --git a/queue-4.19/powerpc-mm-move-pgtable_t-into-platform-headers.patch b/queue-4.19/powerpc-mm-move-pgtable_t-into-platform-headers.patch
new file mode 100644 (file)
index 0000000..94eacf1
--- /dev/null
@@ -0,0 +1,121 @@
+From 44ac7236ce509367e6726dbc9d07063b1ab71466 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Nov 2018 14:06:57 +0000
+Subject: powerpc/mm: Move pgtable_t into platform headers
+
+From: Christophe Leroy <christophe.leroy@c-s.fr>
+
+[ Upstream commit d09780f3a8d48fd49136d7bae8f0ae30de7f261a ]
+
+This patch move pgtable_t into platform headers.
+
+It gets rid of the CONFIG_PPC_64K_PAGES case for PPC64
+as nohash/64 doesn't support CONFIG_PPC_64K_PAGES.
+
+Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Stable-dep-of: 66b2ca086210 ("powerpc/64s/radix: Fix soft dirty tracking")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/book3s/32/mmu-hash.h |  2 ++
+ arch/powerpc/include/asm/book3s/64/mmu.h      |  9 +++++++++
+ arch/powerpc/include/asm/nohash/32/mmu.h      |  4 ++++
+ arch/powerpc/include/asm/nohash/64/mmu.h      |  4 ++++
+ arch/powerpc/include/asm/page.h               | 14 --------------
+ 5 files changed, 19 insertions(+), 14 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/book3s/32/mmu-hash.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
+index e38c91388c40f..5bd26c218b94f 100644
+--- a/arch/powerpc/include/asm/book3s/32/mmu-hash.h
++++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h
+@@ -42,6 +42,8 @@ struct ppc_bat {
+       u32 batu;
+       u32 batl;
+ };
++
++typedef struct page *pgtable_t;
+ #endif /* !__ASSEMBLY__ */
+ /*
+diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h
+index 9c8c669a6b6a3..488e7ed07e967 100644
+--- a/arch/powerpc/include/asm/book3s/64/mmu.h
++++ b/arch/powerpc/include/asm/book3s/64/mmu.h
+@@ -2,6 +2,8 @@
+ #ifndef _ASM_POWERPC_BOOK3S_64_MMU_H_
+ #define _ASM_POWERPC_BOOK3S_64_MMU_H_
++#include <asm/page.h>
++
+ #ifndef __ASSEMBLY__
+ /*
+  * Page size definition
+@@ -24,6 +26,13 @@ struct mmu_psize_def {
+ };
+ extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
++/*
++ * For BOOK3s 64 with 4k and 64K linux page size
++ * we want to use pointers, because the page table
++ * actually store pfn
++ */
++typedef pte_t *pgtable_t;
++
+ #endif /* __ASSEMBLY__ */
+ /* 64-bit classic hash table MMU */
+diff --git a/arch/powerpc/include/asm/nohash/32/mmu.h b/arch/powerpc/include/asm/nohash/32/mmu.h
+index af0e8b54876ab..f61f933a4cd8c 100644
+--- a/arch/powerpc/include/asm/nohash/32/mmu.h
++++ b/arch/powerpc/include/asm/nohash/32/mmu.h
+@@ -16,4 +16,8 @@
+ #include <asm/nohash/32/mmu-8xx.h>
+ #endif
++#ifndef __ASSEMBLY__
++typedef struct page *pgtable_t;
++#endif
++
+ #endif /* _ASM_POWERPC_NOHASH_32_MMU_H_ */
+diff --git a/arch/powerpc/include/asm/nohash/64/mmu.h b/arch/powerpc/include/asm/nohash/64/mmu.h
+index 87871d027b75e..e6585480dfc40 100644
+--- a/arch/powerpc/include/asm/nohash/64/mmu.h
++++ b/arch/powerpc/include/asm/nohash/64/mmu.h
+@@ -5,4 +5,8 @@
+ /* Freescale Book-E software loaded TLB or Book-3e (ISA 2.06+) MMU */
+ #include <asm/nohash/mmu-book3e.h>
++#ifndef __ASSEMBLY__
++typedef struct page *pgtable_t;
++#endif
++
+ #endif /* _ASM_POWERPC_NOHASH_64_MMU_H_ */
+diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
+index f6a1265face29..ddfb4b965e5bd 100644
+--- a/arch/powerpc/include/asm/page.h
++++ b/arch/powerpc/include/asm/page.h
+@@ -335,20 +335,6 @@ void arch_free_page(struct page *page, int order);
+ #endif
+ struct vm_area_struct;
+-#ifdef CONFIG_PPC_BOOK3S_64
+-/*
+- * For BOOK3s 64 with 4k and 64K linux page size
+- * we want to use pointers, because the page table
+- * actually store pfn
+- */
+-typedef pte_t *pgtable_t;
+-#else
+-#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC64)
+-typedef pte_t *pgtable_t;
+-#else
+-typedef struct page *pgtable_t;
+-#endif
+-#endif
+ #include <asm-generic/memory_model.h>
+ #endif /* __ASSEMBLY__ */
+-- 
+2.40.1
+
diff --git a/queue-4.19/powerpc-mm-move-platform-specific-mmu-xxx.h-in-platf.patch b/queue-4.19/powerpc-mm-move-platform-specific-mmu-xxx.h-in-platf.patch
new file mode 100644 (file)
index 0000000..c82ba5c
--- /dev/null
@@ -0,0 +1,166 @@
+From 4818ce449f5d5c01fec316ecd27178841dcaba62 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Nov 2018 14:06:55 +0000
+Subject: powerpc/mm: move platform specific mmu-xxx.h in platform directories
+
+From: Christophe Leroy <christophe.leroy@c-s.fr>
+
+[ Upstream commit 994da93d196866f914c9d64aafb86e95e3decbb2 ]
+
+The purpose of this patch is to move platform specific
+mmu-xxx.h files in platform directories like pte-xxx.h files.
+
+In the meantime this patch creates common nohash and
+nohash/32 + nohash/64 mmu.h files for future common parts.
+
+Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
+Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Stable-dep-of: 66b2ca086210 ("powerpc/64s/radix: Fix soft dirty tracking")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/mmu.h                | 14 ++------------
+ .../include/asm/{ => nohash/32}/mmu-40x.h     |  0
+ .../include/asm/{ => nohash/32}/mmu-44x.h     |  0
+ .../include/asm/{ => nohash/32}/mmu-8xx.h     |  0
+ arch/powerpc/include/asm/nohash/32/mmu.h      | 19 +++++++++++++++++++
+ arch/powerpc/include/asm/nohash/64/mmu.h      |  8 ++++++++
+ .../include/asm/{ => nohash}/mmu-book3e.h     |  0
+ arch/powerpc/include/asm/nohash/mmu.h         | 11 +++++++++++
+ arch/powerpc/kernel/cpu_setup_fsl_booke.S     |  2 +-
+ arch/powerpc/kvm/e500.h                       |  2 +-
+ 10 files changed, 42 insertions(+), 14 deletions(-)
+ rename arch/powerpc/include/asm/{ => nohash/32}/mmu-40x.h (100%)
+ rename arch/powerpc/include/asm/{ => nohash/32}/mmu-44x.h (100%)
+ rename arch/powerpc/include/asm/{ => nohash/32}/mmu-8xx.h (100%)
+ create mode 100644 arch/powerpc/include/asm/nohash/32/mmu.h
+ create mode 100644 arch/powerpc/include/asm/nohash/64/mmu.h
+ rename arch/powerpc/include/asm/{ => nohash}/mmu-book3e.h (100%)
+ create mode 100644 arch/powerpc/include/asm/nohash/mmu.h
+
+diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
+index 13ea441ac5319..2b396de45e9ec 100644
+--- a/arch/powerpc/include/asm/mmu.h
++++ b/arch/powerpc/include/asm/mmu.h
+@@ -326,18 +326,8 @@ static inline void mmu_early_init_devtree(void) { }
+ #if defined(CONFIG_PPC_STD_MMU_32)
+ /* 32-bit classic hash table MMU */
+ #include <asm/book3s/32/mmu-hash.h>
+-#elif defined(CONFIG_40x)
+-/* 40x-style software loaded TLB */
+-#  include <asm/mmu-40x.h>
+-#elif defined(CONFIG_44x)
+-/* 44x-style software loaded TLB */
+-#  include <asm/mmu-44x.h>
+-#elif defined(CONFIG_PPC_BOOK3E_MMU)
+-/* Freescale Book-E software loaded TLB or Book-3e (ISA 2.06+) MMU */
+-#  include <asm/mmu-book3e.h>
+-#elif defined (CONFIG_PPC_8xx)
+-/* Motorola/Freescale 8xx software loaded TLB */
+-#  include <asm/mmu-8xx.h>
++#elif defined(CONFIG_PPC_MMU_NOHASH)
++#include <asm/nohash/mmu.h>
+ #endif
+ #endif /* __KERNEL__ */
+diff --git a/arch/powerpc/include/asm/mmu-40x.h b/arch/powerpc/include/asm/nohash/32/mmu-40x.h
+similarity index 100%
+rename from arch/powerpc/include/asm/mmu-40x.h
+rename to arch/powerpc/include/asm/nohash/32/mmu-40x.h
+diff --git a/arch/powerpc/include/asm/mmu-44x.h b/arch/powerpc/include/asm/nohash/32/mmu-44x.h
+similarity index 100%
+rename from arch/powerpc/include/asm/mmu-44x.h
+rename to arch/powerpc/include/asm/nohash/32/mmu-44x.h
+diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/nohash/32/mmu-8xx.h
+similarity index 100%
+rename from arch/powerpc/include/asm/mmu-8xx.h
+rename to arch/powerpc/include/asm/nohash/32/mmu-8xx.h
+diff --git a/arch/powerpc/include/asm/nohash/32/mmu.h b/arch/powerpc/include/asm/nohash/32/mmu.h
+new file mode 100644
+index 0000000000000..af0e8b54876ab
+--- /dev/null
++++ b/arch/powerpc/include/asm/nohash/32/mmu.h
+@@ -0,0 +1,19 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef _ASM_POWERPC_NOHASH_32_MMU_H_
++#define _ASM_POWERPC_NOHASH_32_MMU_H_
++
++#if defined(CONFIG_40x)
++/* 40x-style software loaded TLB */
++#include <asm/nohash/32/mmu-40x.h>
++#elif defined(CONFIG_44x)
++/* 44x-style software loaded TLB */
++#include <asm/nohash/32/mmu-44x.h>
++#elif defined(CONFIG_PPC_BOOK3E_MMU)
++/* Freescale Book-E software loaded TLB or Book-3e (ISA 2.06+) MMU */
++#include <asm/nohash/mmu-book3e.h>
++#elif defined (CONFIG_PPC_8xx)
++/* Motorola/Freescale 8xx software loaded TLB */
++#include <asm/nohash/32/mmu-8xx.h>
++#endif
++
++#endif /* _ASM_POWERPC_NOHASH_32_MMU_H_ */
+diff --git a/arch/powerpc/include/asm/nohash/64/mmu.h b/arch/powerpc/include/asm/nohash/64/mmu.h
+new file mode 100644
+index 0000000000000..87871d027b75e
+--- /dev/null
++++ b/arch/powerpc/include/asm/nohash/64/mmu.h
+@@ -0,0 +1,8 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef _ASM_POWERPC_NOHASH_64_MMU_H_
++#define _ASM_POWERPC_NOHASH_64_MMU_H_
++
++/* Freescale Book-E software loaded TLB or Book-3e (ISA 2.06+) MMU */
++#include <asm/nohash/mmu-book3e.h>
++
++#endif /* _ASM_POWERPC_NOHASH_64_MMU_H_ */
+diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/nohash/mmu-book3e.h
+similarity index 100%
+rename from arch/powerpc/include/asm/mmu-book3e.h
+rename to arch/powerpc/include/asm/nohash/mmu-book3e.h
+diff --git a/arch/powerpc/include/asm/nohash/mmu.h b/arch/powerpc/include/asm/nohash/mmu.h
+new file mode 100644
+index 0000000000000..a037cb1efb57e
+--- /dev/null
++++ b/arch/powerpc/include/asm/nohash/mmu.h
+@@ -0,0 +1,11 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef _ASM_POWERPC_NOHASH_MMU_H_
++#define _ASM_POWERPC_NOHASH_MMU_H_
++
++#ifdef CONFIG_PPC64
++#include <asm/nohash/64/mmu.h>
++#else
++#include <asm/nohash/32/mmu.h>
++#endif
++
++#endif /* _ASM_POWERPC_NOHASH_MMU_H_ */
+diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+index 8d142e5d84cd0..5fbc890d10943 100644
+--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
++++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+@@ -17,7 +17,7 @@
+ #include <asm/processor.h>
+ #include <asm/cputable.h>
+ #include <asm/ppc_asm.h>
+-#include <asm/mmu-book3e.h>
++#include <asm/nohash/mmu-book3e.h>
+ #include <asm/asm-offsets.h>
+ #include <asm/mpc85xx.h>
+diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
+index 94f04fcb373e1..962ee90a0dfea 100644
+--- a/arch/powerpc/kvm/e500.h
++++ b/arch/powerpc/kvm/e500.h
+@@ -20,7 +20,7 @@
+ #define KVM_E500_H
+ #include <linux/kvm_host.h>
+-#include <asm/mmu-book3e.h>
++#include <asm/nohash/mmu-book3e.h>
+ #include <asm/tlb.h>
+ #include <asm/cputhreads.h>
+-- 
+2.40.1
+
diff --git a/queue-4.19/powerpc-move-page-table-dump-files-in-a-dedicated-su.patch b/queue-4.19/powerpc-move-page-table-dump-files-in-a-dedicated-su.patch
new file mode 100644 (file)
index 0000000..fd142f7
--- /dev/null
@@ -0,0 +1,175 @@
+From 316cc85929ef2989c932a46f34aa022f42837b07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Feb 2019 12:28:36 +0000
+Subject: powerpc: Move page table dump files in a dedicated subdirectory
+
+From: Christophe Leroy <christophe.leroy@c-s.fr>
+
+[ Upstream commit e66c3209c7fd17209ccc4cbbee8b1b1bd5c438dd ]
+
+This patch moves the files related to page table dump in a
+dedicated subdirectory.
+
+The purpose is to clean a bit arch/powerpc/mm by regrouping
+multiple files handling a dedicated function.
+
+Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
+[mpe: Shorten the file names while we're at it]
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Stable-dep-of: 66b2ca086210 ("powerpc/64s/radix: Fix soft dirty tracking")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/Kconfig.debug                             |  4 ----
+ arch/powerpc/mm/Makefile                               | 10 +---------
+ .../mm/{dump_linuxpagetables-8xx.c => ptdump/8xx.c}    |  2 +-
+ arch/powerpc/mm/ptdump/Makefile                        |  9 +++++++++
+ arch/powerpc/mm/{dump_bats.c => ptdump/bats.c}         |  0
+ .../book3s64.c}                                        |  2 +-
+ .../{dump_hashpagetable.c => ptdump/hashpagetable.c}   |  0
+ .../mm/{dump_linuxpagetables.c => ptdump/ptdump.c}     |  2 +-
+ .../mm/{dump_linuxpagetables.h => ptdump/ptdump.h}     |  0
+ arch/powerpc/mm/{dump_sr.c => ptdump/segment_regs.c}   |  0
+ .../shared.c}                                          |  2 +-
+ 11 files changed, 14 insertions(+), 17 deletions(-)
+ rename arch/powerpc/mm/{dump_linuxpagetables-8xx.c => ptdump/8xx.c} (97%)
+ create mode 100644 arch/powerpc/mm/ptdump/Makefile
+ rename arch/powerpc/mm/{dump_bats.c => ptdump/bats.c} (100%)
+ rename arch/powerpc/mm/{dump_linuxpagetables-book3s64.c => ptdump/book3s64.c} (98%)
+ rename arch/powerpc/mm/{dump_hashpagetable.c => ptdump/hashpagetable.c} (100%)
+ rename arch/powerpc/mm/{dump_linuxpagetables.c => ptdump/ptdump.c} (99%)
+ rename arch/powerpc/mm/{dump_linuxpagetables.h => ptdump/ptdump.h} (100%)
+ rename arch/powerpc/mm/{dump_sr.c => ptdump/segment_regs.c} (100%)
+ rename arch/powerpc/mm/{dump_linuxpagetables-generic.c => ptdump/shared.c} (97%)
+
+diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
+index 923b3b794d13f..1f54bb93b5cc7 100644
+--- a/arch/powerpc/Kconfig.debug
++++ b/arch/powerpc/Kconfig.debug
+@@ -368,10 +368,6 @@ config PPC_PTDUMP
+         If you are unsure, say N.
+-config PPC_HTDUMP
+-      def_bool y
+-      depends on PPC_PTDUMP && PPC_BOOK3S_64
+-
+ config PPC_FAST_ENDIAN_SWITCH
+       bool "Deprecated fast endian-switch syscall"
+         depends on DEBUG_KERNEL && PPC_BOOK3S_64
+diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
+index 8ace67f002752..d4648a1e6e6c1 100644
+--- a/arch/powerpc/mm/Makefile
++++ b/arch/powerpc/mm/Makefile
+@@ -42,13 +42,5 @@ obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
+ obj-$(CONFIG_HIGHMEM)         += highmem.o
+ obj-$(CONFIG_PPC_COPRO_BASE)  += copro_fault.o
+ obj-$(CONFIG_SPAPR_TCE_IOMMU) += mmu_context_iommu.o
+-obj-$(CONFIG_PPC_PTDUMP)      += dump_linuxpagetables.o
+-ifdef CONFIG_PPC_PTDUMP
+-obj-$(CONFIG_4xx)             += dump_linuxpagetables-generic.o
+-obj-$(CONFIG_PPC_8xx)         += dump_linuxpagetables-8xx.o
+-obj-$(CONFIG_PPC_BOOK3E_MMU)  += dump_linuxpagetables-generic.o
+-obj-$(CONFIG_PPC_BOOK3S_32)   += dump_linuxpagetables-generic.o dump_bats.o dump_sr.o
+-obj-$(CONFIG_PPC_BOOK3S_64)   += dump_linuxpagetables-book3s64.o
+-endif
+-obj-$(CONFIG_PPC_HTDUMP)      += dump_hashpagetable.o
++obj-$(CONFIG_PPC_PTDUMP)      += ptdump/
+ obj-$(CONFIG_PPC_MEM_KEYS)    += pkeys.o
+diff --git a/arch/powerpc/mm/dump_linuxpagetables-8xx.c b/arch/powerpc/mm/ptdump/8xx.c
+similarity index 97%
+rename from arch/powerpc/mm/dump_linuxpagetables-8xx.c
+rename to arch/powerpc/mm/ptdump/8xx.c
+index 33f52a97975b4..80b4f73f7fdc2 100644
+--- a/arch/powerpc/mm/dump_linuxpagetables-8xx.c
++++ b/arch/powerpc/mm/ptdump/8xx.c
+@@ -7,7 +7,7 @@
+ #include <linux/kernel.h>
+ #include <asm/pgtable.h>
+-#include "dump_linuxpagetables.h"
++#include "ptdump.h"
+ static const struct flag_info flag_array[] = {
+       {
+diff --git a/arch/powerpc/mm/ptdump/Makefile b/arch/powerpc/mm/ptdump/Makefile
+new file mode 100644
+index 0000000000000..712762be3cb11
+--- /dev/null
++++ b/arch/powerpc/mm/ptdump/Makefile
+@@ -0,0 +1,9 @@
++# SPDX-License-Identifier: GPL-2.0
++
++obj-y += ptdump.o
++
++obj-$(CONFIG_4xx)             += shared.o
++obj-$(CONFIG_PPC_8xx)         += 8xx.o
++obj-$(CONFIG_PPC_BOOK3E_MMU)  += shared.o
++obj-$(CONFIG_PPC_BOOK3S_32)   += shared.o bats.o segment_regs.o
++obj-$(CONFIG_PPC_BOOK3S_64)   += book3s64.o hashpagetable.o
+diff --git a/arch/powerpc/mm/dump_bats.c b/arch/powerpc/mm/ptdump/bats.c
+similarity index 100%
+rename from arch/powerpc/mm/dump_bats.c
+rename to arch/powerpc/mm/ptdump/bats.c
+diff --git a/arch/powerpc/mm/dump_linuxpagetables-book3s64.c b/arch/powerpc/mm/ptdump/book3s64.c
+similarity index 98%
+rename from arch/powerpc/mm/dump_linuxpagetables-book3s64.c
+rename to arch/powerpc/mm/ptdump/book3s64.c
+index a637e612b2055..0bce5b85d0112 100644
+--- a/arch/powerpc/mm/dump_linuxpagetables-book3s64.c
++++ b/arch/powerpc/mm/ptdump/book3s64.c
+@@ -7,7 +7,7 @@
+ #include <linux/kernel.h>
+ #include <asm/pgtable.h>
+-#include "dump_linuxpagetables.h"
++#include "ptdump.h"
+ static const struct flag_info flag_array[] = {
+       {
+diff --git a/arch/powerpc/mm/dump_hashpagetable.c b/arch/powerpc/mm/ptdump/hashpagetable.c
+similarity index 100%
+rename from arch/powerpc/mm/dump_hashpagetable.c
+rename to arch/powerpc/mm/ptdump/hashpagetable.c
+diff --git a/arch/powerpc/mm/dump_linuxpagetables.c b/arch/powerpc/mm/ptdump/ptdump.c
+similarity index 99%
+rename from arch/powerpc/mm/dump_linuxpagetables.c
+rename to arch/powerpc/mm/ptdump/ptdump.c
+index 6aa41669ac1ae..76be98988578d 100644
+--- a/arch/powerpc/mm/dump_linuxpagetables.c
++++ b/arch/powerpc/mm/ptdump/ptdump.c
+@@ -28,7 +28,7 @@
+ #include <asm/page.h>
+ #include <asm/pgalloc.h>
+-#include "dump_linuxpagetables.h"
++#include "ptdump.h"
+ #ifdef CONFIG_PPC32
+ #define KERN_VIRT_START       0
+diff --git a/arch/powerpc/mm/dump_linuxpagetables.h b/arch/powerpc/mm/ptdump/ptdump.h
+similarity index 100%
+rename from arch/powerpc/mm/dump_linuxpagetables.h
+rename to arch/powerpc/mm/ptdump/ptdump.h
+diff --git a/arch/powerpc/mm/dump_sr.c b/arch/powerpc/mm/ptdump/segment_regs.c
+similarity index 100%
+rename from arch/powerpc/mm/dump_sr.c
+rename to arch/powerpc/mm/ptdump/segment_regs.c
+diff --git a/arch/powerpc/mm/dump_linuxpagetables-generic.c b/arch/powerpc/mm/ptdump/shared.c
+similarity index 97%
+rename from arch/powerpc/mm/dump_linuxpagetables-generic.c
+rename to arch/powerpc/mm/ptdump/shared.c
+index fed6923bcb46e..1cda3d91c6c26 100644
+--- a/arch/powerpc/mm/dump_linuxpagetables-generic.c
++++ b/arch/powerpc/mm/ptdump/shared.c
+@@ -7,7 +7,7 @@
+ #include <linux/kernel.h>
+ #include <asm/pgtable.h>
+-#include "dump_linuxpagetables.h"
++#include "ptdump.h"
+ static const struct flag_info flag_array[] = {
+       {
+-- 
+2.40.1
+
diff --git a/queue-4.19/quota-fix-warning-in-dqgrab.patch b/queue-4.19/quota-fix-warning-in-dqgrab.patch
new file mode 100644 (file)
index 0000000..673f230
--- /dev/null
@@ -0,0 +1,104 @@
+From c755c6874f94cf27a32550b59f636a6933b2e05f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 22:07:31 +0800
+Subject: quota: fix warning in dqgrab()
+
+From: Ye Bin <yebin10@huawei.com>
+
+[ Upstream commit d6a95db3c7ad160bc16b89e36449705309b52bcb ]
+
+There's issue as follows when do fault injection:
+WARNING: CPU: 1 PID: 14870 at include/linux/quotaops.h:51 dquot_disable+0x13b7/0x18c0
+Modules linked in:
+CPU: 1 PID: 14870 Comm: fsconfig Not tainted 6.3.0-next-20230505-00006-g5107a9c821af-dirty #541
+RIP: 0010:dquot_disable+0x13b7/0x18c0
+RSP: 0018:ffffc9000acc79e0 EFLAGS: 00010246
+RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff88825e41b980
+RDX: 0000000000000000 RSI: ffff88825e41b980 RDI: 0000000000000002
+RBP: ffff888179f68000 R08: ffffffff82087ca7 R09: 0000000000000000
+R10: 0000000000000001 R11: ffffed102f3ed026 R12: ffff888179f68130
+R13: ffff888179f68110 R14: dffffc0000000000 R15: ffff888179f68118
+FS:  00007f450a073740(0000) GS:ffff88882fc00000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007ffe96f2efd8 CR3: 000000025c8ad000 CR4: 00000000000006e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+ dquot_load_quota_sb+0xd53/0x1060
+ dquot_resume+0x172/0x230
+ ext4_reconfigure+0x1dc6/0x27b0
+ reconfigure_super+0x515/0xa90
+ __x64_sys_fsconfig+0xb19/0xd20
+ do_syscall_64+0x39/0xb0
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Above issue may happens as follows:
+ProcessA              ProcessB                    ProcessC
+sys_fsconfig
+  vfs_fsconfig_locked
+   reconfigure_super
+     ext4_remount
+      dquot_suspend -> suspend all type quota
+
+                 sys_fsconfig
+                  vfs_fsconfig_locked
+                    reconfigure_super
+                     ext4_remount
+                      dquot_resume
+                       ret = dquot_load_quota_sb
+                        add_dquot_ref
+                                           do_open  -> open file O_RDWR
+                                            vfs_open
+                                             do_dentry_open
+                                              get_write_access
+                                               atomic_inc_unless_negative(&inode->i_writecount)
+                                              ext4_file_open
+                                               dquot_file_open
+                                                dquot_initialize
+                                                  __dquot_initialize
+                                                   dqget
+                                                   atomic_inc(&dquot->dq_count);
+
+                          __dquot_initialize
+                           __dquot_initialize
+                            dqget
+                             if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
+                               ext4_acquire_dquot
+                               -> Return error DQ_ACTIVE_B flag isn't set
+                         dquot_disable
+                         invalidate_dquots
+                          if (atomic_read(&dquot->dq_count))
+                           dqgrab
+                            WARN_ON_ONCE(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
+                             -> Trigger warning
+
+In the above scenario, 'dquot->dq_flags' has no DQ_ACTIVE_B is normal when
+dqgrab().
+To solve above issue just replace the dqgrab() use in invalidate_dquots() with
+atomic_inc(&dquot->dq_count).
+
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Message-Id: <20230605140731.2427629-3-yebin10@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/quota/dquot.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index 0d3ffc727bb00..303987d29b9c9 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -540,7 +540,7 @@ static void invalidate_dquots(struct super_block *sb, int type)
+                       continue;
+               /* Wait for dquot users */
+               if (atomic_read(&dquot->dq_count)) {
+-                      dqgrab(dquot);
++                      atomic_inc(&dquot->dq_count);
+                       spin_unlock(&dq_list_lock);
+                       /*
+                        * Once dqput() wakes us up, we know it's time to free
+-- 
+2.40.1
+
diff --git a/queue-4.19/quota-properly-disable-quotas-when-add_dquot_ref-fai.patch b/queue-4.19/quota-properly-disable-quotas-when-add_dquot_ref-fai.patch
new file mode 100644 (file)
index 0000000..667e4af
--- /dev/null
@@ -0,0 +1,43 @@
+From 002bb0459ab3e97da35be94efeba998549ad4c55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 22:07:30 +0800
+Subject: quota: Properly disable quotas when add_dquot_ref() fails
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 6a4e3363792e30177cc3965697e34ddcea8b900b ]
+
+When add_dquot_ref() fails (usually due to IO error or ENOMEM), we want
+to disable quotas we are trying to enable. However dquot_disable() call
+was passed just the flags we are enabling so in case flags ==
+DQUOT_USAGE_ENABLED dquot_disable() call will just fail with EINVAL
+instead of properly disabling quotas. Fix the problem by always passing
+DQUOT_LIMITS_ENABLED | DQUOT_USAGE_ENABLED to dquot_disable() in this
+case.
+
+Reported-and-tested-by: Ye Bin <yebin10@huawei.com>
+Reported-by: syzbot+e633c79ceaecbf479854@syzkaller.appspotmail.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+Message-Id: <20230605140731.2427629-2-yebin10@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/quota/dquot.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index 770a2b1434856..0d3ffc727bb00 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -2407,7 +2407,8 @@ int dquot_load_quota_sb(struct super_block *sb, int type, int format_id,
+       error = add_dquot_ref(sb, type);
+       if (error)
+-              dquot_disable(sb, type, flags);
++              dquot_disable(sb, type,
++                            DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
+       return error;
+ out_fmt:
+-- 
+2.40.1
+
diff --git a/queue-4.19/selftests-forwarding-tc_flower-relax-success-criteri.patch b/queue-4.19/selftests-forwarding-tc_flower-relax-success-criteri.patch
new file mode 100644 (file)
index 0000000..186edcf
--- /dev/null
@@ -0,0 +1,61 @@
+From 246326823d374cfece35d20a216d737fa1733b85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Aug 2023 17:14:58 +0300
+Subject: selftests: forwarding: tc_flower: Relax success criterion
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 9ee37e53e7687654b487fc94e82569377272a7a8 ]
+
+The test checks that filters that match on source or destination MAC
+were only hit once. A host can send more than one packet with a given
+source or destination MAC, resulting in failures.
+
+Fix by relaxing the success criterion and instead check that the filters
+were not hit zero times. Using tc_check_at_least_x_packets() is also an
+option, but it is not available in older kernels.
+
+Fixes: 07e5c75184a1 ("selftests: forwarding: Introduce tc flower matching tests")
+Reported-by: Mirsad Todorovac <mirsad.todorovac@alu.unizg.hr>
+Closes: https://lore.kernel.org/netdev/adc5e40d-d040-a65e-eb26-edf47dac5b02@alu.unizg.hr/
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Tested-by: Mirsad Todorovac <mirsad.todorovac@alu.unizg.hr>
+Reviewed-by: Hangbin Liu <liuhangbin@gmail.com>
+Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
+Link: https://lore.kernel.org/r/20230808141503.4060661-13-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/tc_flower.sh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/tc_flower.sh b/tools/testing/selftests/net/forwarding/tc_flower.sh
+index 20d1077e5a3de..85faef980887a 100755
+--- a/tools/testing/selftests/net/forwarding/tc_flower.sh
++++ b/tools/testing/selftests/net/forwarding/tc_flower.sh
+@@ -48,8 +48,8 @@ match_dst_mac_test()
+       tc_check_packets "dev $h2 ingress" 101 1
+       check_fail $? "Matched on a wrong filter"
+-      tc_check_packets "dev $h2 ingress" 102 1
+-      check_err $? "Did not match on correct filter"
++      tc_check_packets "dev $h2 ingress" 102 0
++      check_fail $? "Did not match on correct filter"
+       tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
+       tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
+@@ -74,8 +74,8 @@ match_src_mac_test()
+       tc_check_packets "dev $h2 ingress" 101 1
+       check_fail $? "Matched on a wrong filter"
+-      tc_check_packets "dev $h2 ingress" 102 1
+-      check_err $? "Did not match on correct filter"
++      tc_check_packets "dev $h2 ingress" 102 0
++      check_fail $? "Did not match on correct filter"
+       tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower
+       tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower
+-- 
+2.40.1
+
index 2a0e9374557da7ef497314c4a2bc9caf9bcd6415..6f1777a14f9b482bd2aaa2e6b6e86c0e03ed4c2f 100644 (file)
@@ -1 +1,54 @@
 lib-mpi-eliminate-unused-umul_ppmm-definitions-for-mips.patch
+selftests-forwarding-tc_flower-relax-success-criteri.patch
+drm-radeon-fix-integer-overflow-in-radeon_cs_parser_.patch
+alsa-emu10k1-roll-up-loops-in-dsp-setup-code-for-aud.patch
+quota-properly-disable-quotas-when-add_dquot_ref-fai.patch
+quota-fix-warning-in-dqgrab.patch
+hid-add-quirk-for-03f0-464a-hp-elite-presenter-mouse.patch
+udf-fix-uninitialized-array-access-for-some-pathname.patch
+fs-jfs-fix-ubsan-array-index-out-of-bounds-in-dballo.patch
+mips-dec-prom-address-warray-bounds-warning.patch
+fs-jfs-fix-null-ptr-deref-read-in-txbegin.patch
+fs-jfs-check-for-read-only-mounted-filesystem-in-txb.patch
+media-v4l2-mem2mem-add-lock-to-protect-parameter-num.patch
+media-platform-mediatek-vpu-fix-null-ptr-dereference.patch
+gfs2-fix-possible-data-races-in-gfs2_show_options.patch
+pcmcia-rsrc_nonstatic-fix-memory-leak-in-nonstatic_r.patch
+bluetooth-l2cap-fix-use-after-free.patch
+drm-amdgpu-fix-potential-fence-use-after-free-v2.patch
+ima-allow-fix-uml-builds.patch
+iio-add-addac-subdirectory.patch
+iio-adc-stx104-utilize-iomap-interface.patch
+iio-adc-stx104-implement-and-utilize-register-struct.patch
+iio-addac-stx104-fix-race-condition-for-stx104_write.patch
+iio-addac-stx104-fix-race-condition-when-converting-.patch
+powerpc-mm-move-platform-specific-mmu-xxx.h-in-platf.patch
+powerpc-mm-move-pgtable_t-into-platform-headers.patch
+powerpc-mm-dump-segment-registers-on-book3s-32.patch
+powerpc-mm-dump-block-address-translation-on-book3s-.patch
+powerpc-move-page-table-dump-files-in-a-dedicated-su.patch
+powerpc-64s-radix-fix-soft-dirty-tracking.patch
+x86-topology-fix-erroneous-smp_num_siblings-on-intel.patch
+irqchip-mips-gic-get-rid-of-the-reliance-on-irq_cpu_.patch
+irqchip-mips-gic-use-raw-spinlock-for-gic_lock.patch
+usb-dwc3-qcom-add-helper-functions-to-enable-disable.patch
+usb-dwc3-qcom-fix-null-deref-on-suspend.patch
+mmc-meson-gx-remove-useless-lock.patch
+mmc-meson-gx-remove-redundant-mmc_request_done-call-.patch
+mmc-sdhci-spear-fix-deferred-probing.patch
+mmc-tmio-replace-tmio_mmc_clk_stop-calls-with-tmio_m.patch
+mmc-tmio-move-tmio_mmc_set_clock-to-platform-hook.patch
+mmc-uniphier-sd-add-uniphier-sd-emmc-controller-driv.patch
+mmc-remove-dev_err-usage-after-platform_get_irq.patch
+mmc-bcm2835-fix-deferred-probing.patch
+mmc-sunxi-fix-deferred-probing.patch
+block-fix-signed-int-overflow-in-amiga-partition-sup.patch
+pci-endpoint-add-new-pci_epc_ops-to-get-epc-features.patch
+pci-rockchip-populate-get_features-dw_pcie_ep_ops.patch
+pci-endpoint-add-helper-to-get-first-unreserved-bar.patch
+pci-pci-epf-test-remove-setting-epf_bar-flags-in-fun.patch
+pci-pci-epf-test-use-pci_epc_get_features-to-get-epc.patch
+pci-endpoint-add-support-to-specify-alignment-for-bu.patch
+pci-rockchip-set-address-alignment-for-endpoint-mode.patch
+nfsd4-kill-warnings-on-testing-stateids-with-mismatc.patch
+nfsd-remove-incorrect-check-in-nfsd4_validate_statei.patch
diff --git a/queue-4.19/udf-fix-uninitialized-array-access-for-some-pathname.patch b/queue-4.19/udf-fix-uninitialized-array-access-for-some-pathname.patch
new file mode 100644 (file)
index 0000000..b9bd182
--- /dev/null
@@ -0,0 +1,39 @@
+From bbaa7a6630c53e59fd397ac57291ce0b9a32cbd2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 11:32:35 +0200
+Subject: udf: Fix uninitialized array access for some pathnames
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 028f6055c912588e6f72722d89c30b401bbcf013 ]
+
+For filenames that begin with . and are between 2 and 5 characters long,
+UDF charset conversion code would read uninitialized memory in the
+output buffer. The only practical impact is that the name may be prepended a
+"unification hash" when it is not actually needed but still it is good
+to fix this.
+
+Reported-by: syzbot+cd311b1e43cc25f90d18@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/000000000000e2638a05fe9dc8f9@google.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/udf/unicode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c
+index 5fcfa96463ebb..85521d6b02370 100644
+--- a/fs/udf/unicode.c
++++ b/fs/udf/unicode.c
+@@ -247,7 +247,7 @@ static int udf_name_from_CS0(struct super_block *sb,
+       }
+       if (translate) {
+-              if (str_o_len <= 2 && str_o[0] == '.' &&
++              if (str_o_len > 0 && str_o_len <= 2 && str_o[0] == '.' &&
+                   (str_o_len == 1 || str_o[1] == '.'))
+                       needsCRC = 1;
+               if (needsCRC) {
+-- 
+2.40.1
+
diff --git a/queue-4.19/usb-dwc3-qcom-add-helper-functions-to-enable-disable.patch b/queue-4.19/usb-dwc3-qcom-add-helper-functions-to-enable-disable.patch
new file mode 100644 (file)
index 0000000..8c4dcf9
--- /dev/null
@@ -0,0 +1,108 @@
+From d6b90837ba12f656707c7faa566fe8c5b74eb2f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 10:00:52 +0530
+Subject: usb: dwc3: qcom: Add helper functions to enable,disable wake irqs
+
+From: Sandeep Maheswaram <quic_c_sanm@quicinc.com>
+
+[ Upstream commit 360e8230516de94d74d30c64f0cdcf228b8e8b67 ]
+
+Adding helper functions to enable,disable wake irqs to make
+the code simple and readable.
+
+Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
+Reviewed-by: Pavankumar Kondeti <quic_pkondeti@quicinc.com>
+Signed-off-by: Sandeep Maheswaram <quic_c_sanm@quicinc.com>
+Signed-off-by: Krishna Kurapati <quic_kriskura@quicinc.com>
+Link: https://lore.kernel.org/r/1655094654-24052-4-git-send-email-quic_kriskura@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: d2d69354226d ("USB: dwc3: qcom: fix NULL-deref on suspend")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/dwc3-qcom.c | 58 ++++++++++++++++--------------------
+ 1 file changed, 26 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
+index 58e1bc3a77d80..cbf9286d4c46f 100644
+--- a/drivers/usb/dwc3/dwc3-qcom.c
++++ b/drivers/usb/dwc3/dwc3-qcom.c
+@@ -181,50 +181,44 @@ static bool dwc3_qcom_is_host(struct dwc3_qcom *qcom)
+       return dwc->xhci;
+ }
++static void dwc3_qcom_enable_wakeup_irq(int irq)
++{
++      if (!irq)
++              return;
++
++      enable_irq(irq);
++      enable_irq_wake(irq);
++}
++
++static void dwc3_qcom_disable_wakeup_irq(int irq)
++{
++      if (!irq)
++              return;
++
++      disable_irq_wake(irq);
++      disable_irq_nosync(irq);
++}
++
+ static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom)
+ {
+-      if (qcom->hs_phy_irq) {
+-              disable_irq_wake(qcom->hs_phy_irq);
+-              disable_irq_nosync(qcom->hs_phy_irq);
+-      }
++      dwc3_qcom_disable_wakeup_irq(qcom->hs_phy_irq);
+-      if (qcom->dp_hs_phy_irq) {
+-              disable_irq_wake(qcom->dp_hs_phy_irq);
+-              disable_irq_nosync(qcom->dp_hs_phy_irq);
+-      }
++      dwc3_qcom_disable_wakeup_irq(qcom->dp_hs_phy_irq);
+-      if (qcom->dm_hs_phy_irq) {
+-              disable_irq_wake(qcom->dm_hs_phy_irq);
+-              disable_irq_nosync(qcom->dm_hs_phy_irq);
+-      }
++      dwc3_qcom_disable_wakeup_irq(qcom->dm_hs_phy_irq);
+-      if (qcom->ss_phy_irq) {
+-              disable_irq_wake(qcom->ss_phy_irq);
+-              disable_irq_nosync(qcom->ss_phy_irq);
+-      }
++      dwc3_qcom_disable_wakeup_irq(qcom->ss_phy_irq);
+ }
+ static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom)
+ {
+-      if (qcom->hs_phy_irq) {
+-              enable_irq(qcom->hs_phy_irq);
+-              enable_irq_wake(qcom->hs_phy_irq);
+-      }
++      dwc3_qcom_enable_wakeup_irq(qcom->hs_phy_irq);
+-      if (qcom->dp_hs_phy_irq) {
+-              enable_irq(qcom->dp_hs_phy_irq);
+-              enable_irq_wake(qcom->dp_hs_phy_irq);
+-      }
++      dwc3_qcom_enable_wakeup_irq(qcom->dp_hs_phy_irq);
+-      if (qcom->dm_hs_phy_irq) {
+-              enable_irq(qcom->dm_hs_phy_irq);
+-              enable_irq_wake(qcom->dm_hs_phy_irq);
+-      }
++      dwc3_qcom_enable_wakeup_irq(qcom->dm_hs_phy_irq);
+-      if (qcom->ss_phy_irq) {
+-              enable_irq(qcom->ss_phy_irq);
+-              enable_irq_wake(qcom->ss_phy_irq);
+-      }
++      dwc3_qcom_enable_wakeup_irq(qcom->ss_phy_irq);
+ }
+ static int dwc3_qcom_suspend(struct dwc3_qcom *qcom)
+-- 
+2.40.1
+
diff --git a/queue-4.19/usb-dwc3-qcom-fix-null-deref-on-suspend.patch b/queue-4.19/usb-dwc3-qcom-fix-null-deref-on-suspend.patch
new file mode 100644 (file)
index 0000000..4c1aa67
--- /dev/null
@@ -0,0 +1,68 @@
+From 7acfa55cf503ce72254d08687a3aa73139a8b5f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jun 2023 12:05:39 +0200
+Subject: USB: dwc3: qcom: fix NULL-deref on suspend
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit d2d69354226de0b333d4405981f3d9c41ba8430a ]
+
+The Qualcomm dwc3 glue driver is currently accessing the driver data of
+the child core device during suspend and on wakeup interrupts. This is
+clearly a bad idea as the child may not have probed yet or could have
+been unbound from its driver.
+
+The first such layering violation was part of the initial version of the
+driver, but this was later made worse when the hack that accesses the
+driver data of the grand child xhci device to configure the wakeup
+interrupts was added.
+
+Fixing this properly is not that easily done, so add a sanity check to
+make sure that the child driver data is non-NULL before dereferencing it
+for now.
+
+Note that this relies on subtleties like the fact that driver core is
+making sure that the parent is not suspended while the child is probing.
+
+Reported-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/all/20230325165217.31069-4-manivannan.sadhasivam@linaro.org/
+Fixes: d9152161b4bf ("usb: dwc3: Add Qualcomm DWC3 glue layer driver")
+Fixes: 6895ea55c385 ("usb: dwc3: qcom: Configure wakeup interrupts during suspend")
+Cc: stable@vger.kernel.org     # 3.18: a872ab303d5d: "usb: dwc3: qcom: fix use-after-free on runtime-PM wakeup"
+Cc: Sandeep Maheswaram <quic_c_sanm@quicinc.com>
+Cc: Krishna Kurapati <quic_kriskura@quicinc.com>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Message-ID: <20230607100540.31045-2-johan+linaro@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/dwc3-qcom.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
+index cbf9286d4c46f..0f090188e265b 100644
+--- a/drivers/usb/dwc3/dwc3-qcom.c
++++ b/drivers/usb/dwc3/dwc3-qcom.c
+@@ -176,7 +176,16 @@ static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom)
+ /* Only usable in contexts where the role can not change. */
+ static bool dwc3_qcom_is_host(struct dwc3_qcom *qcom)
+ {
+-      struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
++      struct dwc3 *dwc;
++
++      /*
++       * FIXME: Fix this layering violation.
++       */
++      dwc = platform_get_drvdata(qcom->dwc3);
++
++      /* Core driver may not have probed yet. */
++      if (!dwc)
++              return false;
+       return dwc->xhci;
+ }
+-- 
+2.40.1
+
diff --git a/queue-4.19/x86-topology-fix-erroneous-smp_num_siblings-on-intel.patch b/queue-4.19/x86-topology-fix-erroneous-smp_num_siblings-on-intel.patch
new file mode 100644 (file)
index 0000000..4d69bd8
--- /dev/null
@@ -0,0 +1,96 @@
+From c429b416c053eab6a839cd6d138e8381f67f65f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Mar 2023 09:56:40 +0800
+Subject: x86/topology: Fix erroneous smp_num_siblings on Intel Hybrid
+ platforms
+
+From: Zhang Rui <rui.zhang@intel.com>
+
+[ Upstream commit edc0a2b5957652f4685ef3516f519f84807087db ]
+
+Traditionally, all CPUs in a system have identical numbers of SMT
+siblings.  That changes with hybrid processors where some logical CPUs
+have a sibling and others have none.
+
+Today, the CPU boot code sets the global variable smp_num_siblings when
+every CPU thread is brought up. The last thread to boot will overwrite
+it with the number of siblings of *that* thread. That last thread to
+boot will "win". If the thread is a Pcore, smp_num_siblings == 2.  If it
+is an Ecore, smp_num_siblings == 1.
+
+smp_num_siblings describes if the *system* supports SMT.  It should
+specify the maximum number of SMT threads among all cores.
+
+Ensure that smp_num_siblings represents the system-wide maximum number
+of siblings by always increasing its value. Never allow it to decrease.
+
+On MeteorLake-P platform, this fixes a problem that the Ecore CPUs are
+not updated in any cpu sibling map because the system is treated as an
+UP system when probing Ecore CPUs.
+
+Below shows part of the CPU topology information before and after the
+fix, for both Pcore and Ecore CPU (cpu0 is Pcore, cpu 12 is Ecore).
+...
+-/sys/devices/system/cpu/cpu0/topology/package_cpus:000fff
+-/sys/devices/system/cpu/cpu0/topology/package_cpus_list:0-11
++/sys/devices/system/cpu/cpu0/topology/package_cpus:3fffff
++/sys/devices/system/cpu/cpu0/topology/package_cpus_list:0-21
+...
+-/sys/devices/system/cpu/cpu12/topology/package_cpus:001000
+-/sys/devices/system/cpu/cpu12/topology/package_cpus_list:12
++/sys/devices/system/cpu/cpu12/topology/package_cpus:3fffff
++/sys/devices/system/cpu/cpu12/topology/package_cpus_list:0-21
+
+Notice that the "before" 'package_cpus_list' has only one CPU.  This
+means that userspace tools like lscpu will see a little laptop like
+an 11-socket system:
+
+-Core(s) per socket:  1
+-Socket(s):           11
++Core(s) per socket:  16
++Socket(s):           1
+
+This is also expected to make the scheduler do rather wonky things
+too.
+
+[ dhansen: remove CPUID detail from changelog, add end user effects ]
+
+CC: stable@kernel.org
+Fixes: bbb65d2d365e ("x86: use cpuid vector 0xb when available for detecting cpu topology")
+Fixes: 95f3d39ccf7a ("x86/cpu/topology: Provide detect_extended_topology_early()")
+Suggested-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/all/20230323015640.27906-1-rui.zhang%40intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/topology.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c
+index 71ca064e37948..31fe56a90cbf8 100644
+--- a/arch/x86/kernel/cpu/topology.c
++++ b/arch/x86/kernel/cpu/topology.c
+@@ -44,7 +44,7 @@ int detect_extended_topology_early(struct cpuinfo_x86 *c)
+        * initial apic id, which also represents 32-bit extended x2apic id.
+        */
+       c->initial_apicid = edx;
+-      smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
++      smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx));
+ #endif
+       return 0;
+ }
+@@ -68,7 +68,8 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
+        * Populate HT related information from sub-leaf level 0.
+        */
+       cpuid_count(0xb, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
+-      core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
++      core_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
++      smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx));
+       core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
+       sub_index = 1;
+-- 
+2.40.1
+