--- /dev/null
+From f6033c5e333238f299c3ae03fac8cc1365b23b77 Mon Sep 17 00:00:00 2001
+From: Xiyu Yang <xiyuyang19@fudan.edu.cn>
+Date: Tue, 21 Apr 2020 10:54:11 +0800
+Subject: btrfs: fix block group leak when removing fails
+
+From: Xiyu Yang <xiyuyang19@fudan.edu.cn>
+
+commit f6033c5e333238f299c3ae03fac8cc1365b23b77 upstream.
+
+btrfs_remove_block_group() invokes btrfs_lookup_block_group(), which
+returns a local reference of the block group that contains the given
+bytenr to "block_group" with increased refcount.
+
+When btrfs_remove_block_group() returns, "block_group" becomes invalid,
+so the refcount should be decreased to keep refcount balanced.
+
+The reference counting issue happens in several exception handling paths
+of btrfs_remove_block_group(). When those error scenarios occur such as
+btrfs_alloc_path() returns NULL, the function forgets to decrease its
+refcnt increased by btrfs_lookup_block_group() and will cause a refcnt
+leak.
+
+Fix this issue by jumping to "out_put_group" label and calling
+btrfs_put_block_group() when those error scenarios occur.
+
+CC: stable@vger.kernel.org # 4.4+
+Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
+Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/extent-tree.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -10554,7 +10554,7 @@ int btrfs_remove_block_group(struct btrf
+ path = btrfs_alloc_path();
+ if (!path) {
+ ret = -ENOMEM;
+- goto out;
++ goto out_put_group;
+ }
+
+ /*
+@@ -10591,7 +10591,7 @@ int btrfs_remove_block_group(struct btrf
+ ret = btrfs_orphan_add(trans, BTRFS_I(inode));
+ if (ret) {
+ btrfs_add_delayed_iput(inode);
+- goto out;
++ goto out_put_group;
+ }
+ clear_nlink(inode);
+ /* One for the block groups ref */
+@@ -10614,13 +10614,13 @@ int btrfs_remove_block_group(struct btrf
+
+ ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
+ if (ret < 0)
+- goto out;
++ goto out_put_group;
+ if (ret > 0)
+ btrfs_release_path(path);
+ if (ret == 0) {
+ ret = btrfs_del_item(trans, tree_root, path);
+ if (ret)
+- goto out;
++ goto out_put_group;
+ btrfs_release_path(path);
+ }
+
+@@ -10778,9 +10778,9 @@ int btrfs_remove_block_group(struct btrf
+
+ ret = remove_block_group_free_space(trans, fs_info, block_group);
+ if (ret)
+- goto out;
++ goto out_put_group;
+
+- btrfs_put_block_group(block_group);
++ /* Once for the block groups rbtree */
+ btrfs_put_block_group(block_group);
+
+ ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
+@@ -11037,6 +11037,10 @@ int btrfs_init_space_info(struct btrfs_f
+ flags = BTRFS_BLOCK_GROUP_DATA;
+ ret = create_space_info(fs_info, flags, &space_info);
+ }
++
++out_put_group:
++ /* Once for the lookup reference */
++ btrfs_put_block_group(block_group);
+ out:
+ return ret;
+ }
--- /dev/null
+From f135cea30de5f74d5bfb5116682073841fb4af8f Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Thu, 23 Apr 2020 16:30:53 +0100
+Subject: btrfs: fix partial loss of prealloc extent past i_size after fsync
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit f135cea30de5f74d5bfb5116682073841fb4af8f upstream.
+
+When we have an inode with a prealloc extent that starts at an offset
+lower than the i_size and there is another prealloc extent that starts at
+an offset beyond i_size, we can end up losing part of the first prealloc
+extent (the part that starts at i_size) and have an implicit hole if we
+fsync the file and then have a power failure.
+
+Consider the following example with comments explaining how and why it
+happens.
+
+ $ mkfs.btrfs -f /dev/sdb
+ $ mount /dev/sdb /mnt
+
+ # Create our test file with 2 consecutive prealloc extents, each with a
+ # size of 128Kb, and covering the range from 0 to 256Kb, with a file
+ # size of 0.
+ $ xfs_io -f -c "falloc -k 0 128K" /mnt/foo
+ $ xfs_io -c "falloc -k 128K 128K" /mnt/foo
+
+ # Fsync the file to record both extents in the log tree.
+ $ xfs_io -c "fsync" /mnt/foo
+
+ # Now do a redudant extent allocation for the range from 0 to 64Kb.
+ # This will merely increase the file size from 0 to 64Kb. Instead we
+ # could also do a truncate to set the file size to 64Kb.
+ $ xfs_io -c "falloc 0 64K" /mnt/foo
+
+ # Fsync the file, so we update the inode item in the log tree with the
+ # new file size (64Kb). This also ends up setting the number of bytes
+ # for the first prealloc extent to 64Kb. This is done by the truncation
+ # at btrfs_log_prealloc_extents().
+ # This means that if a power failure happens after this, a write into
+ # the file range 64Kb to 128Kb will not use the prealloc extent and
+ # will result in allocation of a new extent.
+ $ xfs_io -c "fsync" /mnt/foo
+
+ # Now set the file size to 256K with a truncate and then fsync the file.
+ # Since no changes happened to the extents, the fsync only updates the
+ # i_size in the inode item at the log tree. This results in an implicit
+ # hole for the file range from 64Kb to 128Kb, something which fsck will
+ # complain when not using the NO_HOLES feature if we replay the log
+ # after a power failure.
+ $ xfs_io -c "truncate 256K" -c "fsync" /mnt/foo
+
+So instead of always truncating the log to the inode's current i_size at
+btrfs_log_prealloc_extents(), check first if there's a prealloc extent
+that starts at an offset lower than the i_size and with a length that
+crosses the i_size - if there is one, just make sure we truncate to a
+size that corresponds to the end offset of that prealloc extent, so
+that we don't lose the part of that extent that starts at i_size if a
+power failure happens.
+
+A test case for fstests follows soon.
+
+Fixes: 31d11b83b96f ("Btrfs: fix duplicate extents after fsync of file with prealloc extents")
+CC: stable@vger.kernel.org # 4.14+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/tree-log.c | 43 ++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 40 insertions(+), 3 deletions(-)
+
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -4155,6 +4155,9 @@ static int btrfs_log_prealloc_extents(st
+ const u64 ino = btrfs_ino(inode);
+ struct btrfs_path *dst_path = NULL;
+ bool dropped_extents = false;
++ u64 truncate_offset = i_size;
++ struct extent_buffer *leaf;
++ int slot;
+ int ins_nr = 0;
+ int start_slot;
+ int ret;
+@@ -4169,9 +4172,43 @@ static int btrfs_log_prealloc_extents(st
+ if (ret < 0)
+ goto out;
+
++ /*
++ * We must check if there is a prealloc extent that starts before the
++ * i_size and crosses the i_size boundary. This is to ensure later we
++ * truncate down to the end of that extent and not to the i_size, as
++ * otherwise we end up losing part of the prealloc extent after a log
++ * replay and with an implicit hole if there is another prealloc extent
++ * that starts at an offset beyond i_size.
++ */
++ ret = btrfs_previous_item(root, path, ino, BTRFS_EXTENT_DATA_KEY);
++ if (ret < 0)
++ goto out;
++
++ if (ret == 0) {
++ struct btrfs_file_extent_item *ei;
++
++ leaf = path->nodes[0];
++ slot = path->slots[0];
++ ei = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
++
++ if (btrfs_file_extent_type(leaf, ei) ==
++ BTRFS_FILE_EXTENT_PREALLOC) {
++ u64 extent_end;
++
++ btrfs_item_key_to_cpu(leaf, &key, slot);
++ extent_end = key.offset +
++ btrfs_file_extent_num_bytes(leaf, ei);
++
++ if (extent_end > i_size)
++ truncate_offset = extent_end;
++ }
++ } else {
++ ret = 0;
++ }
++
+ while (true) {
+- struct extent_buffer *leaf = path->nodes[0];
+- int slot = path->slots[0];
++ leaf = path->nodes[0];
++ slot = path->slots[0];
+
+ if (slot >= btrfs_header_nritems(leaf)) {
+ if (ins_nr > 0) {
+@@ -4209,7 +4246,7 @@ static int btrfs_log_prealloc_extents(st
+ ret = btrfs_truncate_inode_items(trans,
+ root->log_root,
+ &inode->vfs_inode,
+- i_size,
++ truncate_offset,
+ BTRFS_EXTENT_DATA_KEY);
+ } while (ret == -EAGAIN);
+ if (ret)
--- /dev/null
+From 6292b8efe32e6be408af364132f09572aed14382 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Thu, 23 Apr 2020 18:17:43 +0300
+Subject: drm/edid: Fix off-by-one in DispID DTD pixel clock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit 6292b8efe32e6be408af364132f09572aed14382 upstream.
+
+The DispID DTD pixel clock is documented as:
+"00 00 00 h → FF FF FF h | Pixel clock ÷ 10,000 0.01 → 167,772.16 Mega Pixels per Sec"
+Which seems to imply that we to add one to the raw value.
+
+Reality seems to agree as there are tiled displays in the wild
+which currently show a 10kHz difference in the pixel clock
+between the tiles (one tile gets its mode from the base EDID,
+the other from the DispID block).
+
+Cc: stable@vger.kernel.org
+References: https://gitlab.freedesktop.org/drm/intel/-/issues/27
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20200423151743.18767-1-ville.syrjala@linux.intel.com
+Reviewed-by: Manasi Navare <manasi.d.navare@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_edid.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/drm_edid.c
++++ b/drivers/gpu/drm/drm_edid.c
+@@ -4502,7 +4502,7 @@ static struct drm_display_mode *drm_mode
+ struct drm_display_mode *mode;
+ unsigned pixel_clock = (timings->pixel_clock[0] |
+ (timings->pixel_clock[1] << 8) |
+- (timings->pixel_clock[2] << 16));
++ (timings->pixel_clock[2] << 16)) + 1;
+ unsigned hactive = (timings->hactive[0] | timings->hactive[1] << 8) + 1;
+ unsigned hblank = (timings->hblank[0] | timings->hblank[1] << 8) + 1;
+ unsigned hsync = (timings->hsync[0] | (timings->hsync[1] & 0x7f) << 8) + 1;
--- /dev/null
+From 85e9b88af1e6164f19ec71381efd5e2bcfc17620 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Mon, 27 Apr 2020 08:32:46 +0300
+Subject: drm/qxl: qxl_release leak in qxl_draw_dirty_fb()
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit 85e9b88af1e6164f19ec71381efd5e2bcfc17620 upstream.
+
+ret should be changed to release allocated struct qxl_release
+
+Cc: stable@vger.kernel.org
+Fixes: 8002db6336dd ("qxl: convert qxl driver to proper use for reservations")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/22cfd55f-07c8-95d0-a2f7-191b7153c3d4@virtuozzo.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/qxl/qxl_draw.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/qxl/qxl_draw.c
++++ b/drivers/gpu/drm/qxl/qxl_draw.c
+@@ -348,9 +348,10 @@ void qxl_draw_dirty_fb(struct qxl_device
+ goto out_release_backoff;
+
+ rects = drawable_set_clipping(qdev, num_clips, clips_bo);
+- if (!rects)
++ if (!rects) {
++ ret = -EINVAL;
+ goto out_release_backoff;
+-
++ }
+ drawable = (struct qxl_drawable *)qxl_release_map(qdev, release);
+
+ drawable->clip.type = SPICE_CLIP_TYPE_RECTS;
--- /dev/null
+From a65aa9c3676ffccb21361d52fcfedd5b5ff387d7 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Mon, 27 Apr 2020 08:32:51 +0300
+Subject: drm/qxl: qxl_release leak in qxl_hw_surface_alloc()
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit a65aa9c3676ffccb21361d52fcfedd5b5ff387d7 upstream.
+
+Cc: stable@vger.kernel.org
+Fixes: 8002db6336dd ("qxl: convert qxl driver to proper use for reservations")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/2e5a13ae-9ab2-5401-aa4d-03d5f5593423@virtuozzo.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/qxl/qxl_cmd.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/qxl/qxl_cmd.c
++++ b/drivers/gpu/drm/qxl/qxl_cmd.c
+@@ -504,9 +504,10 @@ int qxl_hw_surface_alloc(struct qxl_devi
+ return ret;
+
+ ret = qxl_release_reserve_list(release, true);
+- if (ret)
++ if (ret) {
++ qxl_release_free(qdev, release);
+ return ret;
+-
++ }
+ cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release);
+ cmd->type = QXL_SURFACE_CMD_CREATE;
+ cmd->flags = QXL_SURF_FLAG_KEEP_DATA;
--- /dev/null
+From 933db73351d359f74b14f4af095808260aff11f9 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Wed, 29 Apr 2020 12:01:24 +0300
+Subject: drm/qxl: qxl_release use after free
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit 933db73351d359f74b14f4af095808260aff11f9 upstream.
+
+qxl_release should not be accesses after qxl_push_*_ring_release() calls:
+userspace driver can process submitted command quickly, move qxl_release
+into release_ring, generate interrupt and trigger garbage collector.
+
+It can lead to crashes in qxl driver or trigger memory corruption
+in some kmalloc-192 slab object
+
+Gerd Hoffmann proposes to swap the qxl_release_fence_buffer_objects() +
+qxl_push_{cursor,command}_ring_release() calls to close that race window.
+
+cc: stable@vger.kernel.org
+Fixes: f64122c1f6ad ("drm: add new QXL driver. (v1.4)")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/fa17b338-66ae-f299-68fe-8d32419d9071@virtuozzo.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/qxl/qxl_cmd.c | 5 ++---
+ drivers/gpu/drm/qxl/qxl_display.c | 6 +++---
+ drivers/gpu/drm/qxl/qxl_draw.c | 2 +-
+ drivers/gpu/drm/qxl/qxl_ioctl.c | 5 +----
+ 4 files changed, 7 insertions(+), 11 deletions(-)
+
+--- a/drivers/gpu/drm/qxl/qxl_cmd.c
++++ b/drivers/gpu/drm/qxl/qxl_cmd.c
+@@ -533,8 +533,8 @@ int qxl_hw_surface_alloc(struct qxl_devi
+ /* no need to add a release to the fence for this surface bo,
+ since it is only released when we ask to destroy the surface
+ and it would never signal otherwise */
+- qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
+ qxl_release_fence_buffer_objects(release);
++ qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
+
+ surf->hw_surf_alloc = true;
+ spin_lock(&qdev->surf_id_idr_lock);
+@@ -576,9 +576,8 @@ int qxl_hw_surface_dealloc(struct qxl_de
+ cmd->surface_id = id;
+ qxl_release_unmap(qdev, release, &cmd->release_info);
+
+- qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
+-
+ qxl_release_fence_buffer_objects(release);
++ qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
+
+ return 0;
+ }
+--- a/drivers/gpu/drm/qxl/qxl_display.c
++++ b/drivers/gpu/drm/qxl/qxl_display.c
+@@ -533,8 +533,8 @@ static int qxl_primary_apply_cursor(stru
+ cmd->u.set.visible = 1;
+ qxl_release_unmap(qdev, release, &cmd->release_info);
+
+- qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
+ qxl_release_fence_buffer_objects(release);
++ qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
+
+ return ret;
+
+@@ -701,8 +701,8 @@ static void qxl_cursor_atomic_update(str
+ cmd->u.position.y = plane->state->crtc_y + fb->hot_y;
+
+ qxl_release_unmap(qdev, release, &cmd->release_info);
+- qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
+ qxl_release_fence_buffer_objects(release);
++ qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
+
+ if (old_cursor_bo)
+ qxl_bo_unref(&old_cursor_bo);
+@@ -747,8 +747,8 @@ static void qxl_cursor_atomic_disable(st
+ cmd->type = QXL_CURSOR_HIDE;
+ qxl_release_unmap(qdev, release, &cmd->release_info);
+
+- qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
+ qxl_release_fence_buffer_objects(release);
++ qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
+ }
+
+ static int qxl_plane_prepare_fb(struct drm_plane *plane,
+--- a/drivers/gpu/drm/qxl/qxl_draw.c
++++ b/drivers/gpu/drm/qxl/qxl_draw.c
+@@ -382,8 +382,8 @@ void qxl_draw_dirty_fb(struct qxl_device
+ }
+ qxl_bo_kunmap(clips_bo);
+
+- qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
+ qxl_release_fence_buffer_objects(release);
++ qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
+
+ out_release_backoff:
+ if (ret)
+--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
++++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
+@@ -257,11 +257,8 @@ static int qxl_process_single_command(st
+ apply_surf_reloc(qdev, &reloc_info[i]);
+ }
+
++ qxl_release_fence_buffer_objects(release);
+ ret = qxl_push_command_ring_release(qdev, release, cmd->type, true);
+- if (ret)
+- qxl_release_backoff_reserve_list(release);
+- else
+- qxl_release_fence_buffer_objects(release);
+
+ out_free_bos:
+ out_free_release:
--- /dev/null
+From 1a8eb6b373c2af6533c13d1ea11f504e5010ed9a Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Wed, 22 Apr 2020 14:16:29 +0300
+Subject: mmc: sdhci-pci: Fix eMMC driver strength for BYT-based controllers
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit 1a8eb6b373c2af6533c13d1ea11f504e5010ed9a upstream.
+
+BIOS writers have begun the practice of setting 40 ohm eMMC driver strength
+even though the eMMC may not support it, on the assumption that the kernel
+will validate the value against the eMMC (Extended CSD DRIVER_STRENGTH
+[offset 197]) and revert to the default 50 ohm value if 40 ohm is invalid.
+
+This is done to avoid changing the value for different boards.
+
+Putting aside the merits of this approach, it is clear the eMMC's mask
+of supported driver strengths is more reliable than the value provided
+by BIOS. Add validation accordingly.
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Fixes: 51ced59cc02e ("mmc: sdhci-pci: Use ACPI DSM to get driver strength for some Intel devices")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20200422111629.4899-1-adrian.hunter@intel.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sdhci-pci-core.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/mmc/host/sdhci-pci-core.c
++++ b/drivers/mmc/host/sdhci-pci-core.c
+@@ -490,6 +490,9 @@ static int intel_select_drive_strength(s
+ struct sdhci_pci_slot *slot = sdhci_priv(host);
+ struct intel_host *intel_host = sdhci_pci_priv(slot);
+
++ if (!(mmc_driver_type_mask(intel_host->drv_strength) & card_drv))
++ return 0;
++
+ return intel_host->drv_strength;
+ }
+
--- /dev/null
+From bb32e1987bc55ce1db400faf47d85891da3c9b9f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <marek.behun@nic.cz>
+Date: Mon, 20 Apr 2020 10:04:44 +0200
+Subject: mmc: sdhci-xenon: fix annoying 1.8V regulator warning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <marek.behun@nic.cz>
+
+commit bb32e1987bc55ce1db400faf47d85891da3c9b9f upstream.
+
+For some reason the Host Control2 register of the Xenon SDHCI controller
+sometimes reports the bit representing 1.8V signaling as 0 when read
+after it was written as 1. Subsequent read reports 1.
+
+This causes the sdhci_start_signal_voltage_switch function to report
+ 1.8V regulator output did not become stable
+
+When CONFIG_PM is enabled, the host is suspended and resumend many
+times, and in each resume the switch to 1.8V is called, and so the
+kernel log reports this message annoyingly often.
+
+Do an empty read of the Host Control2 register in Xenon's
+.voltage_switch method to circumvent this.
+
+This patch fixes this particular problem on Turris MOX.
+
+Signed-off-by: Marek Behún <marek.behun@nic.cz>
+Fixes: 8d876bf472db ("mmc: sdhci-xenon: wait 5ms after set 1.8V...")
+Cc: stable@vger.kernel.org # v4.16+
+Link: https://lore.kernel.org/r/20200420080444.25242-1-marek.behun@nic.cz
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sdhci-xenon.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/mmc/host/sdhci-xenon.c
++++ b/drivers/mmc/host/sdhci-xenon.c
+@@ -238,6 +238,16 @@ static void xenon_voltage_switch(struct
+ {
+ /* Wait for 5ms after set 1.8V signal enable bit */
+ usleep_range(5000, 5500);
++
++ /*
++ * For some reason the controller's Host Control2 register reports
++ * the bit representing 1.8V signaling as 0 when read after it was
++ * written as 1. Subsequent read reports 1.
++ *
++ * Since this may cause some issues, do an empty read of the Host
++ * Control2 register here to circumvent this.
++ */
++ sdhci_readw(host, SDHCI_HOST_CONTROL2);
+ }
+
+ static const struct sdhci_ops sdhci_xenon_ops = {
ext4-fix-special-inode-number-checks-in-__ext4_iget.patch
+drm-edid-fix-off-by-one-in-dispid-dtd-pixel-clock.patch
+drm-qxl-qxl_release-leak-in-qxl_draw_dirty_fb.patch
+drm-qxl-qxl_release-leak-in-qxl_hw_surface_alloc.patch
+drm-qxl-qxl_release-use-after-free.patch
+btrfs-fix-block-group-leak-when-removing-fails.patch
+btrfs-fix-partial-loss-of-prealloc-extent-past-i_size-after-fsync.patch
+mmc-sdhci-xenon-fix-annoying-1.8v-regulator-warning.patch
+mmc-sdhci-pci-fix-emmc-driver-strength-for-byt-based-controllers.patch