--- /dev/null
+From 16cd8aa76c3ca1874f848f19b91edbac878dd628 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Apr 2023 11:37:37 +0200
+Subject: i2c: ocores: generate stop condition after timeout in polling mode
+
+From: Gregor Herburger <gregor.herburger@tq-group.com>
+
+[ Upstream commit f8160d3b35fc94491bb0cb974dbda310ef96c0e2 ]
+
+In polling mode, no stop condition is generated after a timeout. This
+causes SCL to remain low and thereby block the bus. If this happens
+during a transfer it can cause slaves to misinterpret the subsequent
+transfer and return wrong values.
+
+To solve this, pass the ETIMEDOUT error up from ocores_process_polling()
+instead of setting STATE_ERROR directly. The caller is adjusted to call
+ocores_process_timeout() on error both in polling and in IRQ mode, which
+will set STATE_ERROR and generate a stop condition.
+
+Fixes: 69c8c0c0efa8 ("i2c: ocores: add polling interface")
+Signed-off-by: Gregor Herburger <gregor.herburger@tq-group.com>
+Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+Acked-by: Peter Korsgaard <peter@korsgaard.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Federico Vaga <federico.vaga@cern.ch>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-ocores.c | 35 ++++++++++++++++++---------------
+ 1 file changed, 19 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
+index ca8b3ecfa93d1..1c3595c8a761a 100644
+--- a/drivers/i2c/busses/i2c-ocores.c
++++ b/drivers/i2c/busses/i2c-ocores.c
+@@ -343,18 +343,18 @@ static int ocores_poll_wait(struct ocores_i2c *i2c)
+ * ocores_isr(), we just add our polling code around it.
+ *
+ * It can run in atomic context
++ *
++ * Return: 0 on success, -ETIMEDOUT on timeout
+ */
+-static void ocores_process_polling(struct ocores_i2c *i2c)
++static int ocores_process_polling(struct ocores_i2c *i2c)
+ {
+- while (1) {
+- irqreturn_t ret;
+- int err;
++ irqreturn_t ret;
++ int err = 0;
+
++ while (1) {
+ err = ocores_poll_wait(i2c);
+- if (err) {
+- i2c->state = STATE_ERROR;
++ if (err)
+ break; /* timeout */
+- }
+
+ ret = ocores_isr(-1, i2c);
+ if (ret == IRQ_NONE)
+@@ -365,13 +365,15 @@ static void ocores_process_polling(struct ocores_i2c *i2c)
+ break;
+ }
+ }
++
++ return err;
+ }
+
+ static int ocores_xfer_core(struct ocores_i2c *i2c,
+ struct i2c_msg *msgs, int num,
+ bool polling)
+ {
+- int ret;
++ int ret = 0;
+ u8 ctrl;
+
+ ctrl = oc_getreg(i2c, OCI2C_CONTROL);
+@@ -389,15 +391,16 @@ static int ocores_xfer_core(struct ocores_i2c *i2c,
+ oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
+
+ if (polling) {
+- ocores_process_polling(i2c);
++ ret = ocores_process_polling(i2c);
+ } else {
+- ret = wait_event_timeout(i2c->wait,
+- (i2c->state == STATE_ERROR) ||
+- (i2c->state == STATE_DONE), HZ);
+- if (ret == 0) {
+- ocores_process_timeout(i2c);
+- return -ETIMEDOUT;
+- }
++ if (wait_event_timeout(i2c->wait,
++ (i2c->state == STATE_ERROR) ||
++ (i2c->state == STATE_DONE), HZ) == 0)
++ ret = -ETIMEDOUT;
++ }
++ if (ret) {
++ ocores_process_timeout(i2c);
++ return ret;
+ }
+
+ return (i2c->state == STATE_DONE) ? num : -EIO;
+--
+2.39.2
+
--- /dev/null
+From 0440fd5e35d98780a2fcec0f2858cc05779427d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Nov 2020 18:21:55 +0000
+Subject: mtd: ubi: wl: Fix a couple of kernel-doc issues
+
+From: Lee Jones <lee.jones@linaro.org>
+
+[ Upstream commit ab4e4de9fd8b469823a645f05f2c142e9270b012 ]
+
+Fixes the following W=1 kernel build warning(s):
+
+ drivers/mtd/ubi/wl.c:584: warning: Function parameter or member 'nested' not described in 'schedule_erase'
+ drivers/mtd/ubi/wl.c:1075: warning: Excess function parameter 'shutdown' description in '__erase_worker'
+
+Cc: Richard Weinberger <richard@nod.at>
+Cc: Miquel Raynal <miquel.raynal@bootlin.com>
+Cc: Vignesh Raghavendra <vigneshr@ti.com>
+Cc: linux-mtd@lists.infradead.org
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20201109182206.3037326-13-lee.jones@linaro.org
+Stable-dep-of: f773f0a331d6 ("ubi: Fix deadlock caused by recursively holding work_sem")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/wl.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
+index 4f88433d4adc7..28110cd4400b5 100644
+--- a/drivers/mtd/ubi/wl.c
++++ b/drivers/mtd/ubi/wl.c
+@@ -576,6 +576,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
+ * @vol_id: the volume ID that last used this PEB
+ * @lnum: the last used logical eraseblock number for the PEB
+ * @torture: if the physical eraseblock has to be tortured
++ * @nested: denotes whether the work_sem is already held in read mode
+ *
+ * This function returns zero in case of success and a %-ENOMEM in case of
+ * failure.
+@@ -1060,8 +1061,6 @@ static int ensure_wear_leveling(struct ubi_device *ubi, int nested)
+ * __erase_worker - physical eraseblock erase worker function.
+ * @ubi: UBI device description object
+ * @wl_wrk: the work object
+- * @shutdown: non-zero if the worker has to free memory and exit
+- * because the WL sub-system is shutting down
+ *
+ * This function erases a physical eraseblock and perform torture testing if
+ * needed. It also takes care about marking the physical eraseblock bad if
+--
+2.39.2
+
drm-panel-orientation-quirks-add-quirk-for-lenovo-yo.patch
verify_pefile-relax-wrapper-length-check.patch
asymmetric_keys-log-on-fatal-failures-in-pe-pkcs7.patch
+mtd-ubi-wl-fix-a-couple-of-kernel-doc-issues.patch
+ubi-fix-deadlock-caused-by-recursively-holding-work_.patch
+ubi-fix-failure-attaching-when-vid_hdr-offset-equals.patch
+i2c-ocores-generate-stop-condition-after-timeout-in-.patch
--- /dev/null
+From e825d740a2b8c68aeb5b39ab04b500733c3a4a3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 4 Mar 2023 09:41:41 +0800
+Subject: ubi: Fix deadlock caused by recursively holding work_sem
+
+From: ZhaoLong Wang <wangzhaolong1@huawei.com>
+
+[ Upstream commit f773f0a331d6c41733b17bebbc1b6cae12e016f5 ]
+
+During the processing of the bgt, if the sync_erase() return -EBUSY
+or some other error code in __erase_worker(),schedule_erase() called
+again lead to the down_read(ubi->work_sem) hold twice and may get
+block by down_write(ubi->work_sem) in ubi_update_fastmap(),
+which cause deadlock.
+
+ ubi bgt other task
+ do_work
+ down_read(&ubi->work_sem) ubi_update_fastmap
+ erase_worker # Blocked by down_read
+ __erase_worker down_write(&ubi->work_sem)
+ schedule_erase
+ schedule_ubi_work
+ down_read(&ubi->work_sem)
+
+Fix this by changing input parameter @nested of the schedule_erase() to
+'true' to avoid recursively acquiring the down_read(&ubi->work_sem).
+
+Also, fix the incorrect comment about @nested parameter of the
+schedule_erase() because when down_write(ubi->work_sem) is held, the
+@nested is also need be true.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217093
+Fixes: 2e8f08deabbc ("ubi: Fix races around ubi_refill_pools()")
+Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/wl.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
+index 28110cd4400b5..fd0e8f948c3da 100644
+--- a/drivers/mtd/ubi/wl.c
++++ b/drivers/mtd/ubi/wl.c
+@@ -576,7 +576,7 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
+ * @vol_id: the volume ID that last used this PEB
+ * @lnum: the last used logical eraseblock number for the PEB
+ * @torture: if the physical eraseblock has to be tortured
+- * @nested: denotes whether the work_sem is already held in read mode
++ * @nested: denotes whether the work_sem is already held
+ *
+ * This function returns zero in case of success and a %-ENOMEM in case of
+ * failure.
+@@ -1110,7 +1110,7 @@ static int __erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk)
+ int err1;
+
+ /* Re-schedule the LEB for erasure */
+- err1 = schedule_erase(ubi, e, vol_id, lnum, 0, false);
++ err1 = schedule_erase(ubi, e, vol_id, lnum, 0, true);
+ if (err1) {
+ spin_lock(&ubi->wl_lock);
+ wl_entry_destroy(ubi, e);
+--
+2.39.2
+
--- /dev/null
+From 78295f107d5e71840da8aa65da48df40fb5d3bea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Mar 2023 09:33:08 +0800
+Subject: ubi: Fix failure attaching when vid_hdr offset equals to (sub)page
+ size
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit 1e020e1b96afdecd20680b5b5be2a6ffc3d27628 ]
+
+Following process will make ubi attaching failed since commit
+1b42b1a36fc946 ("ubi: ensure that VID header offset ... size"):
+
+ID="0xec,0xa1,0x00,0x15" # 128M 128KB 2KB
+modprobe nandsim id_bytes=$ID
+flash_eraseall /dev/mtd0
+modprobe ubi mtd="0,2048" # set vid_hdr offset as 2048 (one page)
+(dmesg):
+ ubi0 error: ubi_attach_mtd_dev [ubi]: VID header offset 2048 too large.
+ UBI error: cannot attach mtd0
+ UBI error: cannot initialize UBI, error -22
+
+Rework original solution, the key point is making sure
+'vid_hdr_shift + UBI_VID_HDR_SIZE < ubi->vid_hdr_alsize',
+so we should check vid_hdr_shift rather not vid_hdr_offset.
+Then, ubi still support (sub)page aligined VID header offset.
+
+Fixes: 1b42b1a36fc946 ("ubi: ensure that VID header offset ... size")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Tested-by: Nicolas Schichan <nschichan@freebox.fr>
+Tested-by: Miquel Raynal <miquel.raynal@bootlin.com> # v5.10, v4.19
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/build.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
+index 13f8292ceea52..f29ed9102ce91 100644
+--- a/drivers/mtd/ubi/build.c
++++ b/drivers/mtd/ubi/build.c
+@@ -644,12 +644,6 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024)
+ ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size);
+ ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size);
+
+- if (ubi->vid_hdr_offset && ((ubi->vid_hdr_offset + UBI_VID_HDR_SIZE) >
+- ubi->vid_hdr_alsize)) {
+- ubi_err(ubi, "VID header offset %d too large.", ubi->vid_hdr_offset);
+- return -EINVAL;
+- }
+-
+ dbg_gen("min_io_size %d", ubi->min_io_size);
+ dbg_gen("max_write_size %d", ubi->max_write_size);
+ dbg_gen("hdrs_min_io_size %d", ubi->hdrs_min_io_size);
+@@ -667,6 +661,21 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024)
+ ubi->vid_hdr_aloffset;
+ }
+
++ /*
++ * Memory allocation for VID header is ubi->vid_hdr_alsize
++ * which is described in comments in io.c.
++ * Make sure VID header shift + UBI_VID_HDR_SIZE not exceeds
++ * ubi->vid_hdr_alsize, so that all vid header operations
++ * won't access memory out of bounds.
++ */
++ if ((ubi->vid_hdr_shift + UBI_VID_HDR_SIZE) > ubi->vid_hdr_alsize) {
++ ubi_err(ubi, "Invalid VID header offset %d, VID header shift(%d)"
++ " + VID header size(%zu) > VID header aligned size(%d).",
++ ubi->vid_hdr_offset, ubi->vid_hdr_shift,
++ UBI_VID_HDR_SIZE, ubi->vid_hdr_alsize);
++ return -EINVAL;
++ }
++
+ /* Similar for the data offset */
+ ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE;
+ ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size);
+--
+2.39.2
+