--- /dev/null
+From 2c291bf82c8fdf24e70529143689b11e507eca85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Jul 2022 21:08:18 -0400
+Subject: 9p: Add client parameter to p9_req_put()
+
+From: Kent Overstreet <kent.overstreet@gmail.com>
+
+[ Upstream commit 8b11ff098af42b1fa57fc817daadd53c8b244a0c ]
+
+This is to aid in adding mempools, in the next patch.
+
+Link: https://lkml.kernel.org/r/20220704014243.153050-2-kent.overstreet@gmail.com
+Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
+Cc: Eric Van Hensbergen <ericvh@gmail.com>
+Cc: Latchesar Ionkov <lucho@ionkov.net>
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/9p/client.h | 2 +-
+ net/9p/client.c | 12 ++++++------
+ net/9p/trans_fd.c | 12 ++++++------
+ net/9p/trans_rdma.c | 2 +-
+ net/9p/trans_virtio.c | 4 ++--
+ net/9p/trans_xen.c | 2 +-
+ 6 files changed, 17 insertions(+), 17 deletions(-)
+
+diff --git a/include/net/9p/client.h b/include/net/9p/client.h
+index c038c2d73dae..cb78e0e33332 100644
+--- a/include/net/9p/client.h
++++ b/include/net/9p/client.h
+@@ -235,7 +235,7 @@ static inline int p9_req_try_get(struct p9_req_t *r)
+ return refcount_inc_not_zero(&r->refcount);
+ }
+
+-int p9_req_put(struct p9_req_t *r);
++int p9_req_put(struct p9_client *c, struct p9_req_t *r);
+
+ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status);
+
+diff --git a/net/9p/client.c b/net/9p/client.c
+index 0ee48e8b7220..a36a40137caa 100644
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -341,7 +341,7 @@ struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
+ if (!p9_req_try_get(req))
+ goto again;
+ if (req->tc.tag != tag) {
+- p9_req_put(req);
++ p9_req_put(c, req);
+ goto again;
+ }
+ }
+@@ -367,10 +367,10 @@ static int p9_tag_remove(struct p9_client *c, struct p9_req_t *r)
+ spin_lock_irqsave(&c->lock, flags);
+ idr_remove(&c->reqs, tag);
+ spin_unlock_irqrestore(&c->lock, flags);
+- return p9_req_put(r);
++ return p9_req_put(c, r);
+ }
+
+-int p9_req_put(struct p9_req_t *r)
++int p9_req_put(struct p9_client *c, struct p9_req_t *r)
+ {
+ if (refcount_dec_and_test(&r->refcount)) {
+ p9_fcall_fini(&r->tc);
+@@ -423,7 +423,7 @@ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
+
+ wake_up(&req->wq);
+ p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc.tag);
+- p9_req_put(req);
++ p9_req_put(c, req);
+ }
+ EXPORT_SYMBOL(p9_client_cb);
+
+@@ -706,7 +706,7 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
+ reterr:
+ p9_tag_remove(c, req);
+ /* We have to put also the 2nd reference as it won't be used */
+- p9_req_put(req);
++ p9_req_put(c, req);
+ return ERR_PTR(err);
+ }
+
+@@ -743,7 +743,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
+ err = c->trans_mod->request(c, req);
+ if (err < 0) {
+ /* write won't happen */
+- p9_req_put(req);
++ p9_req_put(c, req);
+ if (err != -ERESTARTSYS && err != -EFAULT)
+ c->status = Disconnected;
+ goto recalc_sigpending;
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index 8f8f95e39b03..007c3f45fe05 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -378,7 +378,7 @@ static void p9_read_work(struct work_struct *work)
+ m->rc.sdata = NULL;
+ m->rc.offset = 0;
+ m->rc.capacity = 0;
+- p9_req_put(m->rreq);
++ p9_req_put(m->client, m->rreq);
+ m->rreq = NULL;
+ }
+
+@@ -492,7 +492,7 @@ static void p9_write_work(struct work_struct *work)
+ m->wpos += err;
+ if (m->wpos == m->wsize) {
+ m->wpos = m->wsize = 0;
+- p9_req_put(m->wreq);
++ p9_req_put(m->client, m->wreq);
+ m->wreq = NULL;
+ }
+
+@@ -695,7 +695,7 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
+ if (req->status == REQ_STATUS_UNSENT) {
+ list_del(&req->req_list);
+ req->status = REQ_STATUS_FLSHD;
+- p9_req_put(req);
++ p9_req_put(client, req);
+ ret = 0;
+ }
+ spin_unlock(&client->lock);
+@@ -722,7 +722,7 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
+ list_del(&req->req_list);
+ req->status = REQ_STATUS_FLSHD;
+ spin_unlock(&client->lock);
+- p9_req_put(req);
++ p9_req_put(client, req);
+
+ return 0;
+ }
+@@ -883,12 +883,12 @@ static void p9_conn_destroy(struct p9_conn *m)
+ p9_mux_poll_stop(m);
+ cancel_work_sync(&m->rq);
+ if (m->rreq) {
+- p9_req_put(m->rreq);
++ p9_req_put(m->client, m->rreq);
+ m->rreq = NULL;
+ }
+ cancel_work_sync(&m->wq);
+ if (m->wreq) {
+- p9_req_put(m->wreq);
++ p9_req_put(m->client, m->wreq);
+ m->wreq = NULL;
+ }
+
+diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c
+index 88e563826674..d817d3745238 100644
+--- a/net/9p/trans_rdma.c
++++ b/net/9p/trans_rdma.c
+@@ -350,7 +350,7 @@ send_done(struct ib_cq *cq, struct ib_wc *wc)
+ c->busa, c->req->tc.size,
+ DMA_TO_DEVICE);
+ up(&rdma->sq_sem);
+- p9_req_put(c->req);
++ p9_req_put(client, c->req);
+ kfree(c);
+ }
+
+diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
+index b24a4fb0f0a2..147972bf2e79 100644
+--- a/net/9p/trans_virtio.c
++++ b/net/9p/trans_virtio.c
+@@ -199,7 +199,7 @@ static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
+ /* Reply won't come, so drop req ref */
+ static int p9_virtio_cancelled(struct p9_client *client, struct p9_req_t *req)
+ {
+- p9_req_put(req);
++ p9_req_put(client, req);
+ return 0;
+ }
+
+@@ -523,7 +523,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
+ kvfree(out_pages);
+ if (!kicked) {
+ /* reply won't come */
+- p9_req_put(req);
++ p9_req_put(client, req);
+ }
+ return err;
+ }
+diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
+index 77883b6788cd..4cf0c78d4d22 100644
+--- a/net/9p/trans_xen.c
++++ b/net/9p/trans_xen.c
+@@ -163,7 +163,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
+ ring->intf->out_prod = prod;
+ spin_unlock_irqrestore(&ring->lock, flags);
+ notify_remote_via_irq(ring->irq);
+- p9_req_put(p9_req);
++ p9_req_put(client, p9_req);
+
+ return 0;
+ }
+--
+2.35.1
+
--- /dev/null
+From 2c21a551e67f8f6b7c6d2c6db60b7011fd637811 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Jul 2022 21:02:49 -0400
+Subject: 9p: Drop kref usage
+
+From: Kent Overstreet <kent.overstreet@gmail.com>
+
+[ Upstream commit 6cda12864cb0f99810a5809e11e3ee5b102c9a47 ]
+
+An upcoming patch is going to require passing the client through
+p9_req_put() -> p9_req_free(), but that's awkward with the kref
+indirection - so this patch switches to using refcount_t directly.
+
+Link: https://lkml.kernel.org/r/20220704014243.153050-1-kent.overstreet@gmail.com
+Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
+Cc: Eric Van Hensbergen <ericvh@gmail.com>
+Cc: Latchesar Ionkov <lucho@ionkov.net>
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/9p/client.h | 6 +++---
+ net/9p/client.c | 19 ++++++++-----------
+ 2 files changed, 11 insertions(+), 14 deletions(-)
+
+diff --git a/include/net/9p/client.h b/include/net/9p/client.h
+index ec1d1706f43c..c038c2d73dae 100644
+--- a/include/net/9p/client.h
++++ b/include/net/9p/client.h
+@@ -76,7 +76,7 @@ enum p9_req_status_t {
+ struct p9_req_t {
+ int status;
+ int t_err;
+- struct kref refcount;
++ refcount_t refcount;
+ wait_queue_head_t wq;
+ struct p9_fcall tc;
+ struct p9_fcall rc;
+@@ -227,12 +227,12 @@ struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag);
+
+ static inline void p9_req_get(struct p9_req_t *r)
+ {
+- kref_get(&r->refcount);
++ refcount_inc(&r->refcount);
+ }
+
+ static inline int p9_req_try_get(struct p9_req_t *r)
+ {
+- return kref_get_unless_zero(&r->refcount);
++ return refcount_inc_not_zero(&r->refcount);
+ }
+
+ int p9_req_put(struct p9_req_t *r);
+diff --git a/net/9p/client.c b/net/9p/client.c
+index 8bba0d9cf975..0ee48e8b7220 100644
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -305,7 +305,7 @@ p9_tag_alloc(struct p9_client *c, int8_t type, unsigned int max_size)
+ * callback), so p9_client_cb eats the second ref there
+ * as the pointer is duplicated directly by virtqueue_add_sgs()
+ */
+- refcount_set(&req->refcount.refcount, 2);
++ refcount_set(&req->refcount, 2);
+
+ return req;
+
+@@ -370,18 +370,15 @@ static int p9_tag_remove(struct p9_client *c, struct p9_req_t *r)
+ return p9_req_put(r);
+ }
+
+-static void p9_req_free(struct kref *ref)
+-{
+- struct p9_req_t *r = container_of(ref, struct p9_req_t, refcount);
+-
+- p9_fcall_fini(&r->tc);
+- p9_fcall_fini(&r->rc);
+- kmem_cache_free(p9_req_cache, r);
+-}
+-
+ int p9_req_put(struct p9_req_t *r)
+ {
+- return kref_put(&r->refcount, p9_req_free);
++ if (refcount_dec_and_test(&r->refcount)) {
++ p9_fcall_fini(&r->tc);
++ p9_fcall_fini(&r->rc);
++ kmem_cache_free(p9_req_cache, r);
++ return 1;
++ }
++ return 0;
+ }
+ EXPORT_SYMBOL(p9_req_put);
+
+--
+2.35.1
+
--- /dev/null
+From 850e4cf438191d1778a5fce46666794a197e5216 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 16:05:26 -0700
+Subject: ACPI: APEI: Fix _EINJ vs EFI_MEMORY_SP
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit b13a3e5fd40b7d1b394c5ecbb5eb301a4c38e7b2 ]
+
+When a platform marks a memory range as "special purpose" it is not
+onlined as System RAM by default. However, it is still suitable for
+error injection. Add IORES_DESC_SOFT_RESERVED to einj_error_inject() as
+a permissible memory type in the sanity checking of the arguments to
+_EINJ.
+
+Fixes: 262b45ae3ab4 ("x86/efi: EFI soft reservation to E820 enumeration")
+Reviewed-by: Tony Luck <tony.luck@intel.com>
+Reported-by: Omar Avelar <omar.avelar@intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/apei/einj.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
+index 95cc2a9f3e05..49b5e317e916 100644
+--- a/drivers/acpi/apei/einj.c
++++ b/drivers/acpi/apei/einj.c
+@@ -546,6 +546,8 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
+ != REGION_INTERSECTS) &&
+ (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY)
+ != REGION_INTERSECTS) &&
++ (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_SOFT_RESERVED)
++ != REGION_INTERSECTS) &&
+ !arch_is_platform_page(base_addr)))
+ return -EINVAL;
+
+--
+2.35.1
+
--- /dev/null
+From 5f88a030b5d31975d552684fef27be712f807235 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 11:25:44 +0200
+Subject: ACPI: EC: Drop the EC_FLAGS_IGNORE_DSDT_GPE quirk
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit f7090e0ef360d674f08a22fab90e4e209fb1f658 ]
+
+It seems that these quirks are no longer necessary since
+commit 69b957c26b32 ("ACPI: EC: Fix possible issues related to EC
+initialization order"), which has fixed this in a generic manner.
+
+There are 3 commits adding DMI entries with this quirk (adding multiple
+DMI entries per commit). 2/3 commits are from before the generic fix.
+
+Which leaves commit 6306f0431914 ("ACPI: EC: Make more Asus laptops
+use ECDT _GPE"), which was committed way after the generic fix.
+But this was just due to slow upstreaming of it. This commit stems
+from Endless from 15 Aug 2017 (committed upstream 20 May 2021):
+https://github.com/endlessm/linux/pull/288
+
+The current code should work fine without this:
+
+ 1. The EC_FLAGS_IGNORE_DSDT_GPE flag is only checked in ec_parse_device(),
+ like this:
+
+ if (boot_ec && boot_ec_is_ecdt && EC_FLAGS_IGNORE_DSDT_GPE) {
+ ec->gpe = boot_ec->gpe;
+ } else {
+ /* parse GPE */
+ }
+
+ 2. ec_parse_device() is only called from acpi_ec_add() and
+ acpi_ec_dsdt_probe()
+
+ 3. acpi_ec_dsdt_probe() starts with:
+
+ if (boot_ec)
+ return;
+
+ so it only calls ec_parse_device() when boot_ec == NULL, meaning that
+ the quirk never triggers for this call. So only the call in
+ acpi_ec_add() matters.
+
+ 4. acpi_ec_add() does the following after the ec_parse_device() call:
+
+ if (boot_ec && ec->command_addr == boot_ec->command_addr &&
+ ec->data_addr == boot_ec->data_addr &&
+ !EC_FLAGS_TRUST_DSDT_GPE) {
+ /*
+ * Trust PNP0C09 namespace location rather than
+ * ECDT ID. But trust ECDT GPE rather than _GPE
+ * because of ASUS quirks, so do not change
+ * boot_ec->gpe to ec->gpe.
+ */
+ boot_ec->handle = ec->handle;
+ acpi_handle_debug(ec->handle, "duplicated.\n");
+ acpi_ec_free(ec);
+ ec = boot_ec;
+ }
+
+The quirk only matters if boot_ec != NULL and EC_FLAGS_TRUST_DSDT_GPE
+is never set at the same time as EC_FLAGS_IGNORE_DSDT_GPE.
+
+That means that if the addresses match we always enter this if block and
+then only the ec->handle part of the data stored in ec by ec_parse_device()
+is used and the rest is thrown away, after which ec is made to point
+to boot_ec, at which point ec->gpe == boot_ec->gpe, so the same result
+as with the quirk set, independent of the value of the quirk.
+
+Also note the comment in this block which indicates that the gpe result
+from ec_parse_device() is deliberately not taken to deal with buggy
+Asus laptops and all DMI quirks setting EC_FLAGS_IGNORE_DSDT_GPE are for
+Asus laptops.
+
+Based on the above I believe that unless on some quirked laptops
+the ECDT and DSDT EC addresses do not match we can drop the quirk.
+
+I've checked dmesg output to ensure the ECDT and DSDT EC addresses match
+for quirked models using https://linux-hardware.org hw-probe reports.
+
+I've been able to confirm that the addresses match for the following
+models this way: GL702VMK, X505BA, X505BP, X550VXK, X580VD.
+Whereas for the following models I could find any dmesg output:
+FX502VD, FX502VE, X542BA, X542BP.
+
+Note the models without dmesg all were submitted in patches with a batch
+of models and other models from the same batch checkout ok.
+
+This, combined with that all the code adding the quirks was written before
+the generic fix makes me believe that it is safe to remove this quirk now.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Daniel Drake <drake@endlessos.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/ec.c | 75 ++++++-----------------------------------------
+ 1 file changed, 9 insertions(+), 66 deletions(-)
+
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index f6a022892ee0..488c9ec0da0b 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -180,7 +180,6 @@ static struct workqueue_struct *ec_wq;
+ static struct workqueue_struct *ec_query_wq;
+
+ static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */
+-static int EC_FLAGS_IGNORE_DSDT_GPE; /* Needs ECDT GPE as correction setting */
+ static int EC_FLAGS_TRUST_DSDT_GPE; /* Needs DSDT GPE as correction setting */
+ static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
+
+@@ -1407,24 +1406,16 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
+ if (ec->data_addr == 0 || ec->command_addr == 0)
+ return AE_OK;
+
+- if (boot_ec && boot_ec_is_ecdt && EC_FLAGS_IGNORE_DSDT_GPE) {
+- /*
+- * Always inherit the GPE number setting from the ECDT
+- * EC.
+- */
+- ec->gpe = boot_ec->gpe;
+- } else {
+- /* Get GPE bit assignment (EC events). */
+- /* TODO: Add support for _GPE returning a package */
+- status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
+- if (ACPI_SUCCESS(status))
+- ec->gpe = tmp;
++ /* Get GPE bit assignment (EC events). */
++ /* TODO: Add support for _GPE returning a package */
++ status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
++ if (ACPI_SUCCESS(status))
++ ec->gpe = tmp;
++ /*
++ * Errors are non-fatal, allowing for ACPI Reduced Hardware
++ * platforms which use GpioInt instead of GPE.
++ */
+
+- /*
+- * Errors are non-fatal, allowing for ACPI Reduced Hardware
+- * platforms which use GpioInt instead of GPE.
+- */
+- }
+ /* Use the global lock for all EC transactions? */
+ tmp = 0;
+ acpi_evaluate_integer(handle, "_GLK", NULL, &tmp);
+@@ -1862,60 +1853,12 @@ static int ec_honor_dsdt_gpe(const struct dmi_system_id *id)
+ return 0;
+ }
+
+-/*
+- * Some DSDTs contain wrong GPE setting.
+- * Asus FX502VD/VE, GL702VMK, X550VXK, X580VD
+- * https://bugzilla.kernel.org/show_bug.cgi?id=195651
+- */
+-static int ec_honor_ecdt_gpe(const struct dmi_system_id *id)
+-{
+- pr_debug("Detected system needing ignore DSDT GPE setting.\n");
+- EC_FLAGS_IGNORE_DSDT_GPE = 1;
+- return 0;
+-}
+-
+ static const struct dmi_system_id ec_dmi_table[] __initconst = {
+ {
+ ec_correct_ecdt, "MSI MS-171F", {
+ DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MS-171F"),}, NULL},
+ {
+- ec_honor_ecdt_gpe, "ASUS FX502VD", {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "FX502VD"),}, NULL},
+- {
+- ec_honor_ecdt_gpe, "ASUS FX502VE", {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "FX502VE"),}, NULL},
+- {
+- ec_honor_ecdt_gpe, "ASUS GL702VMK", {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "GL702VMK"),}, NULL},
+- {
+- ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BA", {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "X505BA"),}, NULL},
+- {
+- ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BP", {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "X505BP"),}, NULL},
+- {
+- ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BA", {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "X542BA"),}, NULL},
+- {
+- ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BP", {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "X542BP"),}, NULL},
+- {
+- ec_honor_ecdt_gpe, "ASUS X550VXK", {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "X550VXK"),}, NULL},
+- {
+- ec_honor_ecdt_gpe, "ASUS X580VD", {
+- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+- DMI_MATCH(DMI_PRODUCT_NAME, "X580VD"),}, NULL},
+- {
+ /* https://bugzilla.kernel.org/show_bug.cgi?id=209989 */
+ ec_honor_dsdt_gpe, "HP Pavilion Gaming Laptop 15-cx0xxx", {
+ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+--
+2.35.1
+
--- /dev/null
+From 4a2fb0598395a7cb19e37cca2797269545261f52 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 11:25:43 +0200
+Subject: ACPI: EC: Remove duplicate ThinkPad X1 Carbon 6th entry from DMI
+ quirks
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 0dd6db359e5f206cbf1dd1fd40dd211588cd2725 ]
+
+Somehow the "ThinkPad X1 Carbon 6th" entry ended up twice in the
+struct dmi_system_id acpi_ec_no_wakeup[] array. Remove one of
+the entries.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/ec.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index a1b871a418f8..f6a022892ee0 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -2207,13 +2207,6 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = {
+ DMI_MATCH(DMI_PRODUCT_FAMILY, "Thinkpad X1 Carbon 6th"),
+ },
+ },
+- {
+- .ident = "ThinkPad X1 Carbon 6th",
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+- DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Carbon 6th"),
+- },
+- },
+ {
+ .ident = "ThinkPad X1 Yoga 3rd",
+ .matches = {
+--
+2.35.1
+
--- /dev/null
+From 6824b15fc80e6e2b0842c382c06989e267a50132 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jun 2022 21:21:27 +0800
+Subject: ACPI: LPSS: Fix missing check in register_device_clock()
+
+From: huhai <huhai@kylinos.cn>
+
+[ Upstream commit b4f1f61ed5928b1128e60e38d0dffa16966f06dc ]
+
+register_device_clock() misses a check for platform_device_register_simple().
+Add a check to fix it.
+
+Signed-off-by: huhai <huhai@kylinos.cn>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpi_lpss.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
+index fbe0756259c5..c4d4d21391d7 100644
+--- a/drivers/acpi/acpi_lpss.c
++++ b/drivers/acpi/acpi_lpss.c
+@@ -422,6 +422,9 @@ static int register_device_clock(struct acpi_device *adev,
+ if (!lpss_clk_dev)
+ lpt_register_clock_device();
+
++ if (IS_ERR(lpss_clk_dev))
++ return PTR_ERR(lpss_clk_dev);
++
+ clk_data = platform_get_drvdata(lpss_clk_dev);
+ if (!clk_data)
+ return -ENODEV;
+--
+2.35.1
+
--- /dev/null
+From 75fe205046b82f2a9811789c97f5bf8ba4d58d70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jun 2022 15:42:48 +0800
+Subject: ACPI: PM: save NVS memory for Lenovo G40-45
+
+From: Manyi Li <limanyi@uniontech.com>
+
+[ Upstream commit 4b7ef7b05afcde44142225c184bf43a0cd9e2178 ]
+
+[821d6f0359b0614792ab8e2fb93b503e25a65079] is to make machines
+produced from 2012 to now not saving NVS region to accelerate S3.
+
+But, Lenovo G40-45, a platform released in 2015, still needs NVS memory
+saving during S3. A quirk is introduced for this platform.
+
+Signed-off-by: Manyi Li <limanyi@uniontech.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/sleep.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
+index 3147702710af..1ec3238e2cdc 100644
+--- a/drivers/acpi/sleep.c
++++ b/drivers/acpi/sleep.c
+@@ -360,6 +360,14 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "80E3"),
+ },
+ },
++ {
++ .callback = init_nvs_save_s3,
++ .ident = "Lenovo G40-45",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "80E1"),
++ },
++ },
+ /*
+ * ThinkPad X1 Tablet(2016) cannot do suspend-to-idle using
+ * the Low Power S0 Idle firmware interface (see
+--
+2.35.1
+
--- /dev/null
+From 22ce1555dfe036fe88e2dc43b52d6fd23216ee46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 19:24:58 -0300
+Subject: ACPI: processor/idle: Annotate more functions to live in cpuidle
+ section
+
+From: Guilherme G. Piccoli <gpiccoli@igalia.com>
+
+[ Upstream commit 409dfdcaffb266acfc1f33529a26b1443c9332d4 ]
+
+Commit 6727ad9e206c ("nmi_backtrace: generate one-line reports for idle cpus")
+introduced a new text section called cpuidle; with that, we have a mechanism
+to add idling functions in such section and skip them from nmi_backtrace
+output, since they're useless and potentially flooding for such report.
+
+Happens that inlining might cause some real idle functions to end-up
+outside of such section; this is currently the case of ACPI processor_idle
+driver; the functions acpi_idle_enter_* do inline acpi_idle_do_entry(),
+hence they stay out of the cpuidle section.
+Fix that by marking such functions to also live in the cpuidle section.
+
+Fixes: 6727ad9e206c ("nmi_backtrace: generate one-line reports for idle cpus")
+Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/processor_idle.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
+index eb95e188d62b..573ba7f617e8 100644
+--- a/drivers/acpi/processor_idle.c
++++ b/drivers/acpi/processor_idle.c
+@@ -602,7 +602,7 @@ static DEFINE_RAW_SPINLOCK(c3_lock);
+ * @cx: Target state context
+ * @index: index of target state
+ */
+-static int acpi_idle_enter_bm(struct cpuidle_driver *drv,
++static int __cpuidle acpi_idle_enter_bm(struct cpuidle_driver *drv,
+ struct acpi_processor *pr,
+ struct acpi_processor_cx *cx,
+ int index)
+@@ -659,7 +659,7 @@ static int acpi_idle_enter_bm(struct cpuidle_driver *drv,
+ return index;
+ }
+
+-static int acpi_idle_enter(struct cpuidle_device *dev,
++static int __cpuidle acpi_idle_enter(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+ {
+ struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
+@@ -688,7 +688,7 @@ static int acpi_idle_enter(struct cpuidle_device *dev,
+ return index;
+ }
+
+-static int acpi_idle_enter_s2idle(struct cpuidle_device *dev,
++static int __cpuidle acpi_idle_enter_s2idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+ {
+ struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
+--
+2.35.1
+
--- /dev/null
+From bf6c27efbe7ee814a2e9491283a573525b34d80f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 21:16:11 +0200
+Subject: ACPI: video: Use native backlight on Dell Inspiron N4010
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 03c440a26cba6cfa540d65924e9db86fcea362b2 ]
+
+The Dell Inspiron N4010 does not have ACPI backlight control,
+so acpi_video_get_backlight_type()'s heuristics return vendor as
+the type to use.
+
+But the vendor interface is broken, where as the native (intel_backlight)
+works well, add a quirk to use native.
+
+Link: https://lore.kernel.org/regressions/CALF=6jEe5G8+r1Wo0vvz4GjNQQhdkLT5p8uCHn6ZXhg4nsOWow@mail.gmail.com/
+Reported-and-tested-by: Ben Greening <bgreening@gmail.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/video_detect.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
+index 6615f59ab7fd..5d7f38016a24 100644
+--- a/drivers/acpi/video_detect.c
++++ b/drivers/acpi/video_detect.c
+@@ -347,6 +347,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"),
+ },
+ },
++ {
++ .callback = video_detect_force_native,
++ /* Dell Inspiron N4010 */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron N4010"),
++ },
++ },
+ {
+ .callback = video_detect_force_native,
+ /* Dell Vostro V131 */
+--
+2.35.1
+
--- /dev/null
+From c175dd04f4c0ca09f4da29d6ae86fea467c9a880 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jun 2022 11:40:59 +0200
+Subject: ACPI: VIOT: Fix ACS setup
+
+From: Eric Auger <eric.auger@redhat.com>
+
+[ Upstream commit 3dcb861dbc6ab101838a1548b1efddd00ca3c3ec ]
+
+Currently acpi_viot_init() gets called after the pci
+device has been scanned and pci_enable_acs() has been called.
+So pci_request_acs() fails to be taken into account leading
+to wrong single iommu group topologies when dealing with
+multi-function root ports for instance.
+
+We cannot simply move the acpi_viot_init() earlier, similarly
+as the IORT init because the VIOT parsing relies on the pci
+scan. However we can detect VIOT is present earlier and in
+such a case, request ACS. Introduce a new acpi_viot_early_init()
+routine that allows to call pci_request_acs() before the scan.
+
+While at it, guard the call to pci_request_acs() with #ifdef
+CONFIG_PCI.
+
+Fixes: 3cf485540e7b ("ACPI: Add driver for the VIOT table")
+Signed-off-by: Eric Auger <eric.auger@redhat.com>
+Reported-by: Jin Liu <jinl@redhat.com>
+Reviewed-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
+Tested-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/bus.c | 1 +
+ drivers/acpi/viot.c | 26 ++++++++++++++++++++------
+ include/linux/acpi_viot.h | 2 ++
+ 3 files changed, 23 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
+index 6c735cfa7d43..ef7858393a3c 100644
+--- a/drivers/acpi/bus.c
++++ b/drivers/acpi/bus.c
+@@ -1373,6 +1373,7 @@ static int __init acpi_init(void)
+
+ pci_mmcfg_late_init();
+ acpi_iort_init();
++ acpi_viot_early_init();
+ acpi_hest_init();
+ acpi_ghes_init();
+ acpi_scan_init();
+diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c
+index d2256326c73a..647f11cf165d 100644
+--- a/drivers/acpi/viot.c
++++ b/drivers/acpi/viot.c
+@@ -248,6 +248,26 @@ static int __init viot_parse_node(const struct acpi_viot_header *hdr)
+ return ret;
+ }
+
++/**
++ * acpi_viot_early_init - Test the presence of VIOT and enable ACS
++ *
++ * If the VIOT does exist, ACS must be enabled. This cannot be
++ * done in acpi_viot_init() which is called after the bus scan
++ */
++void __init acpi_viot_early_init(void)
++{
++#ifdef CONFIG_PCI
++ acpi_status status;
++ struct acpi_table_header *hdr;
++
++ status = acpi_get_table(ACPI_SIG_VIOT, 0, &hdr);
++ if (ACPI_FAILURE(status))
++ return;
++ pci_request_acs();
++ acpi_put_table(hdr);
++#endif
++}
++
+ /**
+ * acpi_viot_init - Parse the VIOT table
+ *
+@@ -319,12 +339,6 @@ static int viot_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
+ epid = ((domain_nr - ep->segment_start) << 16) +
+ dev_id - ep->bdf_start + ep->endpoint_id;
+
+- /*
+- * If we found a PCI range managed by the viommu, we're
+- * the one that has to request ACS.
+- */
+- pci_request_acs();
+-
+ return viot_dev_iommu_init(&pdev->dev, ep->viommu,
+ epid);
+ }
+diff --git a/include/linux/acpi_viot.h b/include/linux/acpi_viot.h
+index 1eb8ee5b0e5f..a5a122431563 100644
+--- a/include/linux/acpi_viot.h
++++ b/include/linux/acpi_viot.h
+@@ -6,9 +6,11 @@
+ #include <linux/acpi.h>
+
+ #ifdef CONFIG_ACPI_VIOT
++void __init acpi_viot_early_init(void);
+ void __init acpi_viot_init(void);
+ int viot_iommu_configure(struct device *dev);
+ #else
++static inline void acpi_viot_early_init(void) {}
+ static inline void acpi_viot_init(void) {}
+ static inline int viot_iommu_configure(struct device *dev)
+ {
+--
+2.35.1
+
--- /dev/null
+From c4259947d12a36a35a02bb284ec1e0a676c503b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 21:09:09 -0400
+Subject: android: binder: stop saving a pointer to the VMA
+
+From: Liam R. Howlett <Liam.Howlett@oracle.com>
+
+[ Upstream commit a43cfc87caaf46710c8027a8c23b8a55f1078f19 ]
+
+Do not record a pointer to a VMA outside of the mmap_lock for later use.
+This is unsafe and there are a number of failure paths *after* the
+recorded VMA pointer may be freed during setup. There is no callback to
+the driver to clear the saved pointer from generic mm code. Furthermore,
+the VMA pointer may become stale if any number of VMA operations end up
+freeing the VMA so saving it was fragile to being with.
+
+Instead, change the binder_alloc struct to record the start address of the
+VMA and use vma_lookup() to get the vma when needed. Add lockdep
+mmap_lock checks on updates to the vma pointer to ensure the lock is held
+and depend on that lock for synchronization of readers and writers - which
+was already the case anyways, so the smp_wmb()/smp_rmb() was not
+necessary.
+
+[akpm@linux-foundation.org: fix drivers/android/binder_alloc_selftest.c]
+Link: https://lkml.kernel.org/r/20220621140212.vpkio64idahetbyf@revolver
+Fixes: da1b9564e85b ("android: binder: fix the race mmap and alloc_new_buf_locked")
+Reported-by: syzbot+58b51ac2b04e388ab7b0@syzkaller.appspotmail.com
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Christian Brauner (Microsoft) <brauner@kernel.org>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Hridya Valsaraju <hridya@google.com>
+Cc: Joel Fernandes <joel@joelfernandes.org>
+Cc: Martijn Coenen <maco@android.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Todd Kjos <tkjos@android.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/android/binder_alloc.c | 30 ++++++++++++-------------
+ drivers/android/binder_alloc.h | 2 +-
+ drivers/android/binder_alloc_selftest.c | 2 +-
+ 3 files changed, 16 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
+index 2ac1008a5f39..a93a7d2a8caf 100644
+--- a/drivers/android/binder_alloc.c
++++ b/drivers/android/binder_alloc.c
+@@ -213,7 +213,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
+
+ if (mm) {
+ mmap_read_lock(mm);
+- vma = alloc->vma;
++ vma = vma_lookup(mm, alloc->vma_addr);
+ }
+
+ if (!vma && need_mm) {
+@@ -313,16 +313,15 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
+ static inline void binder_alloc_set_vma(struct binder_alloc *alloc,
+ struct vm_area_struct *vma)
+ {
+- if (vma)
++ unsigned long vm_start = 0;
++
++ if (vma) {
++ vm_start = vma->vm_start;
+ alloc->vma_vm_mm = vma->vm_mm;
+- /*
+- * If we see alloc->vma is not NULL, buffer data structures set up
+- * completely. Look at smp_rmb side binder_alloc_get_vma.
+- * We also want to guarantee new alloc->vma_vm_mm is always visible
+- * if alloc->vma is set.
+- */
+- smp_wmb();
+- alloc->vma = vma;
++ }
++
++ mmap_assert_write_locked(alloc->vma_vm_mm);
++ alloc->vma_addr = vm_start;
+ }
+
+ static inline struct vm_area_struct *binder_alloc_get_vma(
+@@ -330,11 +329,9 @@ static inline struct vm_area_struct *binder_alloc_get_vma(
+ {
+ struct vm_area_struct *vma = NULL;
+
+- if (alloc->vma) {
+- /* Look at description in binder_alloc_set_vma */
+- smp_rmb();
+- vma = alloc->vma;
+- }
++ if (alloc->vma_addr)
++ vma = vma_lookup(alloc->vma_vm_mm, alloc->vma_addr);
++
+ return vma;
+ }
+
+@@ -817,7 +814,8 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc)
+
+ buffers = 0;
+ mutex_lock(&alloc->mutex);
+- BUG_ON(alloc->vma);
++ BUG_ON(alloc->vma_addr &&
++ vma_lookup(alloc->vma_vm_mm, alloc->vma_addr));
+
+ while ((n = rb_first(&alloc->allocated_buffers))) {
+ buffer = rb_entry(n, struct binder_buffer, rb_node);
+diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h
+index 7dea57a84c79..1e4fd37af5e0 100644
+--- a/drivers/android/binder_alloc.h
++++ b/drivers/android/binder_alloc.h
+@@ -100,7 +100,7 @@ struct binder_lru_page {
+ */
+ struct binder_alloc {
+ struct mutex mutex;
+- struct vm_area_struct *vma;
++ unsigned long vma_addr;
+ struct mm_struct *vma_vm_mm;
+ void __user *buffer;
+ struct list_head buffers;
+diff --git a/drivers/android/binder_alloc_selftest.c b/drivers/android/binder_alloc_selftest.c
+index c2b323bc3b3a..43a881073a42 100644
+--- a/drivers/android/binder_alloc_selftest.c
++++ b/drivers/android/binder_alloc_selftest.c
+@@ -287,7 +287,7 @@ void binder_selftest_alloc(struct binder_alloc *alloc)
+ if (!binder_selftest_run)
+ return;
+ mutex_lock(&binder_selftest_lock);
+- if (!binder_selftest_run || !alloc->vma)
++ if (!binder_selftest_run || !alloc->vma_addr)
+ goto done;
+ pr_info("STARTED\n");
+ binder_selftest_alloc_offset(alloc, end_offset, 0);
+--
+2.35.1
+
--- /dev/null
+From 70196b23e3aed2b9da5430c7cb350bf4333fc3e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 14:17:32 +0100
+Subject: arch: make TRACE_IRQFLAGS_NMI_SUPPORT generic
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit 4510bffb4d0246cdcc1f14c7367c026b807a862d ]
+
+On most architectures, IRQ flag tracing is disabled in NMI context, and
+architectures need to define and select TRACE_IRQFLAGS_NMI_SUPPORT in
+order to enable this.
+
+Commit:
+
+ 859d069ee1ddd878 ("lockdep: Prepare for NMI IRQ state tracking")
+
+Permitted IRQ flag tracing in NMI context, allowing lockdep to work in
+NMI context where an architecture had suitable entry logic. At the time,
+most architectures did not have such suitable entry logic, and this broke
+lockdep on such architectures. Thus, this was partially disabled in
+commit:
+
+ ed00495333ccc80f ("locking/lockdep: Fix TRACE_IRQFLAGS vs. NMIs")
+
+... with architectures needing to select TRACE_IRQFLAGS_NMI_SUPPORT to
+enable IRQ flag tracing in NMI context.
+
+Currently TRACE_IRQFLAGS_NMI_SUPPORT is defined under
+arch/x86/Kconfig.debug. Move it to arch/Kconfig so architectures can
+select it without having to provide their own definition.
+
+Since the regular TRACE_IRQFLAGS_SUPPORT is selected by
+arch/x86/Kconfig, the select of TRACE_IRQFLAGS_NMI_SUPPORT is moved
+there too.
+
+There should be no functional change as a result of this patch.
+
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20220511131733.4074499-2-mark.rutland@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/Kconfig | 3 +++
+ arch/x86/Kconfig | 1 +
+ arch/x86/Kconfig.debug | 3 ---
+ 3 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/arch/Kconfig b/arch/Kconfig
+index 31c4fdc4a4ba..ab45e0f6c21b 100644
+--- a/arch/Kconfig
++++ b/arch/Kconfig
+@@ -214,6 +214,9 @@ config HAVE_FUNCTION_DESCRIPTORS
+ config TRACE_IRQFLAGS_SUPPORT
+ bool
+
++config TRACE_IRQFLAGS_NMI_SUPPORT
++ bool
++
+ #
+ # An arch should select this if it provides all these things:
+ #
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index ce1f5a876cfe..04a9865dbdbf 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -272,6 +272,7 @@ config X86
+ select SYSCTL_EXCEPTION_TRACE
+ select THREAD_INFO_IN_TASK
+ select TRACE_IRQFLAGS_SUPPORT
++ select TRACE_IRQFLAGS_NMI_SUPPORT
+ select USER_STACKTRACE_SUPPORT
+ select VIRT_TO_BUS
+ select HAVE_ARCH_KCSAN if X86_64
+diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
+index d3a6f74a94bd..d4d6db4dde22 100644
+--- a/arch/x86/Kconfig.debug
++++ b/arch/x86/Kconfig.debug
+@@ -1,8 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0
+
+-config TRACE_IRQFLAGS_NMI_SUPPORT
+- def_bool y
+-
+ config EARLY_PRINTK_USB
+ bool
+
+--
+2.35.1
+
--- /dev/null
+From 125d2832f1b1c12fccad34cb11ba4e00a2049218 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 12:13:25 +0400
+Subject: ARM: bcm: Fix refcount leak in bcm_kona_smc_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit cb23389a2458c2e4bfd6c86a513cbbe1c4d35e76 ]
+
+of_find_matching_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: b8eb35fd594a ("ARM: bcm281xx: Add L2 cache enable code")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-bcm/bcm_kona_smc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-bcm/bcm_kona_smc.c b/arch/arm/mach-bcm/bcm_kona_smc.c
+index 43829e49ad93..347bfb7f03e2 100644
+--- a/arch/arm/mach-bcm/bcm_kona_smc.c
++++ b/arch/arm/mach-bcm/bcm_kona_smc.c
+@@ -52,6 +52,7 @@ int __init bcm_kona_smc_init(void)
+ return -ENODEV;
+
+ prop_val = of_get_address(node, 0, &prop_size, NULL);
++ of_node_put(node);
+ if (!prop_val)
+ return -EINVAL;
+
+--
+2.35.1
+
--- /dev/null
+From a44cc41574a1ef187a9718b1ee54d579d3ff2c46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 29 May 2022 12:49:25 +0200
+Subject: ARM: dts: ast2500-evb: fix board compatible
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 30b276fca5c0644f3cb17bceb1bd6a626c670184 ]
+
+The AST2500 EVB board should have dedicated compatible.
+
+Fixes: 02440622656d ("arm/dst: Add Aspeed ast2500 device tree")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220529104928.79636-4-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/aspeed-ast2500-evb.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/aspeed-ast2500-evb.dts b/arch/arm/boot/dts/aspeed-ast2500-evb.dts
+index 1d24b394ea4c..a497dd135491 100644
+--- a/arch/arm/boot/dts/aspeed-ast2500-evb.dts
++++ b/arch/arm/boot/dts/aspeed-ast2500-evb.dts
+@@ -5,7 +5,7 @@
+
+ / {
+ model = "AST2500 EVB";
+- compatible = "aspeed,ast2500";
++ compatible = "aspeed,ast2500-evb", "aspeed,ast2500";
+
+ aliases {
+ serial4 = &uart5;
+--
+2.35.1
+
--- /dev/null
+From 19fa90c4378802b3264e0a9fd0318cb766001e5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 29 May 2022 12:49:27 +0200
+Subject: ARM: dts: ast2600-evb-a1: fix board compatible
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 33c39140cc298e0d4e36083cb9a665a837773a60 ]
+
+The AST2600 EVB A1 board should have dedicated compatible.
+
+Fixes: a72955180372 ("ARM: dts: aspeed: ast2600evb: Add dts file for A1 and A0")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220529104928.79636-6-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts b/arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts
+index dd7148060c4a..d0a5c2ff0fec 100644
+--- a/arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts
++++ b/arch/arm/boot/dts/aspeed-ast2600-evb-a1.dts
+@@ -5,6 +5,7 @@
+
+ / {
+ model = "AST2600 A1 EVB";
++ compatible = "aspeed,ast2600-evb-a1", "aspeed,ast2600";
+
+ /delete-node/regulator-vcc-sdhci0;
+ /delete-node/regulator-vcc-sdhci1;
+--
+2.35.1
+
--- /dev/null
+From 28d578e9715127547269cce33f213435f91228de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 29 May 2022 12:49:26 +0200
+Subject: ARM: dts: ast2600-evb: fix board compatible
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit aa5e06208500a0db41473caebdee5a2e81d5a277 ]
+
+The AST2600 EVB board should have dedicated compatible.
+
+Fixes: 2ca5646b5c2f ("ARM: dts: aspeed: Add AST2600 and EVB")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220529104928.79636-5-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/aspeed-ast2600-evb.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/aspeed-ast2600-evb.dts b/arch/arm/boot/dts/aspeed-ast2600-evb.dts
+index 788448cdd6b3..b8e55bf167aa 100644
+--- a/arch/arm/boot/dts/aspeed-ast2600-evb.dts
++++ b/arch/arm/boot/dts/aspeed-ast2600-evb.dts
+@@ -8,7 +8,7 @@
+
+ / {
+ model = "AST2600 EVB";
+- compatible = "aspeed,ast2600";
++ compatible = "aspeed,ast2600-evb-a1", "aspeed,ast2600";
+
+ aliases {
+ serial4 = &uart5;
+--
+2.35.1
+
--- /dev/null
+From 8d04e8b836613e96d60511af107176589e50c899 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jun 2022 00:00:29 +0200
+Subject: ARM: dts: BCM5301X: Add DT for Meraki MR26
+
+From: Christian Lamparter <chunkeey@gmail.com>
+
+[ Upstream commit 935327a73553001f8d81375c76985d05f604507f ]
+
+Meraki MR26 is an EOL wireless access point featuring a
+PoE ethernet port and two dual-band 3x3 MIMO 802.11n
+radios and 1x1 dual-band WIFI dedicated to scanning.
+
+Thank you Amir for the unit and PSU.
+
+Hardware info:
+SOC : Broadcom BCM53015A1KFEBG (dual-core Cortex-A9 CPU at 800 MHz)
+RAM : SK Hynix Inc. H5TQ1G63EFR, 1 GBit DDR3 SDRAM = 128 MiB
+NAND : Spansion S34ML01G100TF100, 1 GBit SLC NAND Flash = 128 MiB
+ETH : 1 GBit Ethernet Port - PoE (TPS23754 PoE Interface)
+WIFI0 : Broadcom BCM43431KMLG, BCM43431 802.11 abgn (3x3:3)
+WIFI1 : Broadcom BCM43431KMLG, BCM43431 802.11 abgn (3x3:3)
+WIFI2 : Broadcom BCM43428 "Air Marshal" 802.11 abgn (1x1:1)
+BUTTON: One reset key behind a small hole next to the Ethernet Port
+LEDS : One amber (fault), one white (indicator) LED, separate RGB-LED
+MISC : Atmel AT24C64 8KiB EEPROM i2c
+ : Ti INA219 26V, 12-bit, i2c output current/voltage/power monitor
+
+SERIAL:
+ WARNING: The serial port needs a TTL/RS-232 3V3 level converter!
+ The Serial setting is 115200-8-N-1. The board has a populated
+ right angle 1x4 0.1" pinheader.
+ The pinout is: VCC (next to J3, has the pin 1 indicator), RX, TX, GND.
+
+Odd stuff:
+
+- uboot does not support lzma compression, but gzip'd uImage/DTB work.
+- uboot claims to support FIT, but fails to pass the DTB to the kernel.
+ Appending the dtb after the kernel image works.
+- RGB-controller is supported through an external userspace program.
+- The ubi partition contains a "board-config" volume. It stores the
+ MAC Address (0x66 in binary) and Serial No. (0x7c alpha-numerical).
+- SoC's temperature sensor always reports that it is on fire.
+ This causes the system to immediately shutdown! Looking at reported
+ "418 degree Celsius" suggests that this sensor is not working.
+
+WIFI:
+b43 is able to initialize all three WIFIs @ 802.11bg.
+| b43-phy0: Broadcom 43431 WLAN found (core revision 29)
+| bcma-pci-bridge 0000:01:00.0: bus1: Switched to core: 0x812
+| b43-phy0: Found PHY: Analog 9, Type 7 (HT), Revision 1
+| b43-phy0: Found Radio: Manuf 0x17F, ID 0x2059, Revision 0, Version 1
+| b43-phy0 warning: 5 GHz band is unsupported on this PHY
+| b43-phy1: Broadcom 43431 WLAN found (core revision 29)
+| bcma-pci-bridge 0001:01:00.0: bus2: Switched to core: 0x812
+| b43-phy1: Found PHY: Analog 9, Type 7 (HT), Revision 1
+| b43-phy1: Found Radio: Manuf 0x17F, ID 0x2059, Revision 0, Version 1
+| b43-phy1 warning: 5 GHz band is unsupported on this PHY
+| b43-phy2: Broadcom 43228 WLAN found (core revision 30)
+| bcma-pci-bridge 0002:01:00.0: bus3: Switched to core: 0x812
+| b43-phy2: Found PHY: Analog 9, Type 4 (N), Revision 16
+| b43-phy2: Found Radio: Manuf 0x17F, ID 0x2057, Revision 9, Version 1
+| Broadcom 43xx driver loaded [ Features: NL ]
+
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/Makefile | 1 +
+ arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 166 +++++++++++++++++++++
+ 2 files changed, 167 insertions(+)
+ create mode 100644 arch/arm/boot/dts/bcm53015-meraki-mr26.dts
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index 7c16f8a2b738..13d788d1e6dc 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -133,6 +133,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
+ bcm47094-luxul-xwr-3150-v1.dtb \
+ bcm47094-netgear-r8500.dtb \
+ bcm47094-phicomm-k3.dtb \
++ bcm53015-meraki-mr26.dtb \
+ bcm53016-meraki-mr32.dtb \
+ bcm94708.dtb \
+ bcm94709.dtb \
+diff --git a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
+new file mode 100644
+index 000000000000..14f58033efeb
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
+@@ -0,0 +1,166 @@
++// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
++/*
++ * Broadcom BCM470X / BCM5301X ARM platform code.
++ * DTS for Meraki MR26 / Codename: Venom
++ *
++ * Copyright (C) 2022 Christian Lamparter <chunkeey@gmail.com>
++ */
++
++/dts-v1/;
++
++#include "bcm4708.dtsi"
++#include "bcm5301x-nand-cs0-bch8.dtsi"
++#include <dt-bindings/leds/common.h>
++
++/ {
++ compatible = "meraki,mr26", "brcm,bcm53015", "brcm,bcm4708";
++ model = "Meraki MR26";
++
++ memory@0 {
++ reg = <0x00000000 0x08000000>;
++ device_type = "memory";
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ led-0 {
++ function = LED_FUNCTION_FAULT;
++ color = <LED_COLOR_ID_AMBER>;
++ gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
++ panic-indicator;
++ };
++ led-1 {
++ function = LED_FUNCTION_INDICATOR;
++ color = <LED_COLOR_ID_WHITE>;
++ gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
++ };
++ };
++
++ keys {
++ compatible = "gpio-keys";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ key-restart {
++ label = "Reset";
++ linux,code = <KEY_RESTART>;
++ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
++ };
++ };
++};
++
++&uart0 {
++ clock-frequency = <50000000>;
++ /delete-property/ clocks;
++};
++
++&uart1 {
++ status = "disabled";
++};
++
++&gmac0 {
++ status = "okay";
++};
++
++&gmac1 {
++ status = "disabled";
++};
++&gmac2 {
++ status = "disabled";
++};
++&gmac3 {
++ status = "disabled";
++};
++
++&nandcs {
++ nand-ecc-algo = "hw";
++
++ partitions {
++ compatible = "fixed-partitions";
++ #address-cells = <0x1>;
++ #size-cells = <0x1>;
++
++ partition@0 {
++ label = "u-boot";
++ reg = <0x0 0x200000>;
++ read-only;
++ };
++
++ partition@200000 {
++ label = "u-boot-env";
++ reg = <0x200000 0x200000>;
++ /* empty */
++ };
++
++ partition@400000 {
++ label = "u-boot-backup";
++ reg = <0x400000 0x200000>;
++ /* empty */
++ };
++
++ partition@600000 {
++ label = "u-boot-env-backup";
++ reg = <0x600000 0x200000>;
++ /* empty */
++ };
++
++ partition@800000 {
++ label = "ubi";
++ reg = <0x800000 0x7780000>;
++ };
++ };
++};
++
++&srab {
++ status = "okay";
++
++ ports {
++ port@0 {
++ reg = <0>;
++ label = "poe";
++ };
++
++ port@5 {
++ reg = <5>;
++ label = "cpu";
++ ethernet = <&gmac0>;
++
++ fixed-link {
++ speed = <1000>;
++ duplex-full;
++ };
++ };
++ };
++};
++
++&i2c0 {
++ status = "okay";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinmux_i2c>;
++
++ clock-frequency = <100000>;
++
++ ina219@40 {
++ compatible = "ti,ina219"; /* PoE power */
++ reg = <0x40>;
++ shunt-resistor = <60000>; /* = 60 mOhms */
++ };
++
++ eeprom@56 {
++ compatible = "atmel,24c64";
++ reg = <0x56>;
++ pagesize = <32>;
++ read-only;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ /* it's empty */
++ };
++};
++
++&thermal {
++ status = "disabled";
++ /* does not work, reads 418 degree Celsius */
++};
+--
+2.35.1
+
--- /dev/null
+From bc0273f94385e957fad664cd630f101f28cd4116 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:33:51 +0200
+Subject: ARM: dts: imx6ul: add missing properties for sram
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 5655699cf5cff9f4c4ee703792156bdd05d1addf ]
+
+All 3 properties are required by sram.yaml. Fixes the dtbs_check
+warning:
+sram@900000: '#address-cells' is a required property
+sram@900000: '#size-cells' is a required property
+sram@900000: 'ranges' is a required property
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6ul.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
+index afeec01f6522..1d435a46fc5c 100644
+--- a/arch/arm/boot/dts/imx6ul.dtsi
++++ b/arch/arm/boot/dts/imx6ul.dtsi
+@@ -149,6 +149,9 @@ soc {
+ ocram: sram@900000 {
+ compatible = "mmio-sram";
+ reg = <0x00900000 0x20000>;
++ ranges = <0 0x00900000 0x20000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
+ };
+
+ intc: interrupt-controller@a01000 {
+--
+2.35.1
+
--- /dev/null
+From 714f337799018f348b2f410806dd14c9d666ffef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:33:52 +0200
+Subject: ARM: dts: imx6ul: change operating-points to uint32-matrix
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit edb67843983bbdf61b4c8c3c50618003d38bb4ae ]
+
+operating-points is a uint32-matrix as per opp-v1.yaml. Change it
+accordingly. While at it, change fsl,soc-operating-points as well,
+although there is no bindings file (yet). But they should have the same
+format. Fixes the dt_binding_check warning:
+cpu@0: operating-points:0: [696000, 1275000, 528000, 1175000, 396000,
+1025000, 198000, 950000] is too long
+cpu@0: operating-points:0: Additional items are not allowed (528000,
+1175000, 396000, 1025000, 198000, 950000 were unexpected)
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6ul.dtsi | 22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
+index 1d435a46fc5c..2fcbd9d91521 100644
+--- a/arch/arm/boot/dts/imx6ul.dtsi
++++ b/arch/arm/boot/dts/imx6ul.dtsi
+@@ -64,20 +64,18 @@ cpu0: cpu@0 {
+ clock-frequency = <696000000>;
+ clock-latency = <61036>; /* two CLK32 periods */
+ #cooling-cells = <2>;
+- operating-points = <
++ operating-points =
+ /* kHz uV */
+- 696000 1275000
+- 528000 1175000
+- 396000 1025000
+- 198000 950000
+- >;
+- fsl,soc-operating-points = <
++ <696000 1275000>,
++ <528000 1175000>,
++ <396000 1025000>,
++ <198000 950000>;
++ fsl,soc-operating-points =
+ /* KHz uV */
+- 696000 1275000
+- 528000 1175000
+- 396000 1175000
+- 198000 1175000
+- >;
++ <696000 1275000>,
++ <528000 1175000>,
++ <396000 1175000>,
++ <198000 1175000>;
+ clocks = <&clks IMX6UL_CLK_ARM>,
+ <&clks IMX6UL_CLK_PLL2_BUS>,
+ <&clks IMX6UL_CLK_PLL2_PFD2>,
+--
+2.35.1
+
--- /dev/null
+From d4e1daaadea11c1a2bc6757cea9ba7d0b2473cdb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:33:55 +0200
+Subject: ARM: dts: imx6ul: fix csi node compatible
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit e0aca931a2c7c29c88ebf37f9c3cd045e083483d ]
+
+"fsl,imx6ul-csi" was never listed as compatible to "fsl,imx7-csi", neither
+in yaml bindings, nor previous txt binding. Remove the imx7 part. Fixes
+the dt schema check warning:
+csi@21c4000: compatible: 'oneOf' conditional failed, one must be fixed:
+['fsl,imx6ul-csi', 'fsl,imx7-csi'] is too long
+Additional items are not allowed ('fsl,imx7-csi' was unexpected)
+'fsl,imx8mm-csi' was expected
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6ul.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
+index df8b4ad62418..367657a9a99f 100644
+--- a/arch/arm/boot/dts/imx6ul.dtsi
++++ b/arch/arm/boot/dts/imx6ul.dtsi
+@@ -999,7 +999,7 @@ cpu_speed_grade: speed-grade@10 {
+ };
+
+ csi: csi@21c4000 {
+- compatible = "fsl,imx6ul-csi", "fsl,imx7-csi";
++ compatible = "fsl,imx6ul-csi";
+ reg = <0x021c4000 0x4000>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_CSI>;
+--
+2.35.1
+
--- /dev/null
+From dbe45ca6b840973ad3281ec600b1d069cd452ff0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:33:53 +0200
+Subject: ARM: dts: imx6ul: fix keypad compatible
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 7d15e0c9a515494af2e3199741cdac7002928a0e ]
+
+According to binding, the compatible shall only contain imx6ul and imx21
+compatibles. Fixes the dt_binding_check warning:
+keypad@20b8000: compatible: 'oneOf' conditional failed, one must be fixed:
+['fsl,imx6ul-kpp', 'fsl,imx6q-kpp', 'fsl,imx21-kpp'] is too long
+Additional items are not allowed ('fsl,imx6q-kpp', 'fsl,imx21-kpp' were
+unexpected)
+Additional items are not allowed ('fsl,imx21-kpp' was unexpected)
+'fsl,imx21-kpp' was expected
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6ul.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
+index 2fcbd9d91521..df8b4ad62418 100644
+--- a/arch/arm/boot/dts/imx6ul.dtsi
++++ b/arch/arm/boot/dts/imx6ul.dtsi
+@@ -544,7 +544,7 @@ fec2: ethernet@20b4000 {
+ };
+
+ kpp: keypad@20b8000 {
+- compatible = "fsl,imx6ul-kpp", "fsl,imx6q-kpp", "fsl,imx21-kpp";
++ compatible = "fsl,imx6ul-kpp", "fsl,imx21-kpp";
+ reg = <0x020b8000 0x4000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_KPP>;
+--
+2.35.1
+
--- /dev/null
+From 53f5533f1a8a78d4d25877ba90b3aaf75724dd07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:33:56 +0200
+Subject: ARM: dts: imx6ul: fix lcdif node compatible
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 1a884d17ca324531634cce82e9f64c0302bdf7de ]
+
+In yaml binding "fsl,imx6ul-lcdif" is listed as compatible to imx6sx-lcdif,
+but not imx28-lcdif. Change the list accordingly. Fixes the
+dt_binding_check warning:
+lcdif@21c8000: compatible: 'oneOf' conditional failed, one must be fixed:
+['fsl,imx6ul-lcdif', 'fsl,imx28-lcdif'] is too long
+Additional items are not allowed ('fsl,imx28-lcdif' was unexpected)
+'fsl,imx6ul-lcdif' is not one of ['fsl,imx23-lcdif', 'fsl,imx28-lcdif',
+'fsl,imx6sx-lcdif']
+'fsl,imx6sx-lcdif' was expected
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6ul.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
+index 367657a9a99f..bc6548058d8c 100644
+--- a/arch/arm/boot/dts/imx6ul.dtsi
++++ b/arch/arm/boot/dts/imx6ul.dtsi
+@@ -1008,7 +1008,7 @@ csi: csi@21c4000 {
+ };
+
+ lcdif: lcdif@21c8000 {
+- compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
++ compatible = "fsl,imx6ul-lcdif", "fsl,imx6sx-lcdif";
+ reg = <0x021c8000 0x4000>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,
+--
+2.35.1
+
--- /dev/null
+From bbaf28a441d96e5604afb235af3957528b7dcdc6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:33:57 +0200
+Subject: ARM: dts: imx6ul: fix qspi node compatible
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 0c6cf86e1ab433b2d421880fdd9c6e954f404948 ]
+
+imx6ul is not compatible to imx6sx, both have different erratas.
+Fixes the dt_binding_check warning:
+spi@21e0000: compatible: 'oneOf' conditional failed, one must be fixed:
+['fsl,imx6ul-qspi', 'fsl,imx6sx-qspi'] is too long
+Additional items are not allowed ('fsl,imx6sx-qspi' was unexpected)
+'fsl,imx6ul-qspi' is not one of ['fsl,ls1043a-qspi']
+'fsl,imx6ul-qspi' is not one of ['fsl,imx8mq-qspi']
+'fsl,ls1021a-qspi' was expected
+'fsl,imx7d-qspi' was expected
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6ul.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
+index bc6548058d8c..eca8bf89ab88 100644
+--- a/arch/arm/boot/dts/imx6ul.dtsi
++++ b/arch/arm/boot/dts/imx6ul.dtsi
+@@ -1029,7 +1029,7 @@ pxp: pxp@21cc000 {
+ qspi: spi@21e0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+- compatible = "fsl,imx6ul-qspi", "fsl,imx6sx-qspi";
++ compatible = "fsl,imx6ul-qspi";
+ reg = <0x021e0000 0x4000>, <0x60000000 0x10000000>;
+ reg-names = "QuadSPI", "QuadSPI-memory";
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+--
+2.35.1
+
--- /dev/null
+From 2a3329dd073093e6ae3cf844abbba2218b273efd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 May 2022 15:47:23 +0200
+Subject: ARM: dts: imx7d-colibri-emmc: add cpu1 supply
+
+From: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+
+[ Upstream commit ba28db60d34271e8a3cf4d7158d71607e8b1e57f ]
+
+Each cpu-core is supposed to list its supply separately, add supply for
+cpu1.
+
+Fixes: 2d7401f8632f ("ARM: dts: imx7d: Add cpu1 supply")
+Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx7d-colibri-emmc.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi b/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi
+index af39e5370fa1..045e4413d339 100644
+--- a/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi
++++ b/arch/arm/boot/dts/imx7d-colibri-emmc.dtsi
+@@ -13,6 +13,10 @@ memory@80000000 {
+ };
+ };
+
++&cpu1 {
++ cpu-supply = <®_DCDC2>;
++};
++
+ &gpio6 {
+ gpio-line-names = "",
+ "",
+--
+2.35.1
+
--- /dev/null
+From 9a765296350a39f26ffa6b8bbb86a2ab703ba8c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 13:56:18 +0200
+Subject: ARM: dts: qcom-apq8074-dragonboard: Use &labels
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit 9f440d17e2309c7d14eba0898c775be6d6e6d6b7 ]
+
+Use &labels to align with the style used in new DTS and apply tiny
+style fixes.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+[bjorn: Rebased ontop of Krzysztof's underscore fixes]
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220415115633.575010-9-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../arm/boot/dts/qcom-apq8074-dragonboard.dts | 605 +++++++++---------
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +-
+ 2 files changed, 296 insertions(+), 311 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+index 9076a24408c6..f114debe4d95 100644
+--- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
++++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+@@ -16,331 +16,316 @@ aliases {
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
++};
++
++&blsp1_uart2 {
++ status = "okay";
++};
++
++&blsp2_i2c5 {
++ status = "okay";
++ clock-frequency = <200000>;
++
++ pinctrl-0 = <&i2c11_pins>;
++ pinctrl-names = "default";
++
++ eeprom: eeprom@52 {
++ compatible = "atmel,24c128";
++ reg = <0x52>;
++ pagesize = <32>;
++ read-only;
++ };
++};
++
++&otg {
++ status = "okay";
+
+- soc {
+- serial@f991e000 {
++ phys = <&usb_hs2_phy>;
++ phy-select = <&tcsr 0xb000 1>;
++ extcon = <&smbb>, <&usb_id>;
++ vbus-supply = <&chg_otg>;
++ hnp-disable;
++ srp-disable;
++ adp-disable;
++
++ ulpi {
++ phy@b {
+ status = "okay";
++ v3p3-supply = <&pm8941_l24>;
++ v1p8-supply = <&pm8941_l6>;
++ extcon = <&smbb>;
++ qcom,init-seq = /bits/ 8 <0x1 0x63>;
++ };
++ };
++};
++
++&rpm_requests {
++ pm8841-regulators {
++ pm8841_s1: s1 {
++ regulator-min-microvolt = <675000>;
++ regulator-max-microvolt = <1050000>;
+ };
+
+- sdhci@f9824900 {
+- bus-width = <8>;
+- non-removable;
+- status = "okay";
++ pm8841_s2: s2 {
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1050000>;
++ };
++
++ pm8841_s3: s3 {
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1050000>;
++ };
+
+- vmmc-supply = <&pm8941_l20>;
+- vqmmc-supply = <&pm8941_s3>;
++ pm8841_s4: s4 {
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1050000>;
++ };
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc1_pin_a>;
++ pm8941-regulators {
++ vdd_l1_l3-supply = <&pm8941_s1>;
++ vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
++ vdd_l4_l11-supply = <&pm8941_s1>;
++ vdd_l5_l7-supply = <&pm8941_s2>;
++ vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
++ vin_5vs-supply = <&pm8941_5v>;
++
++ pm8941_s1: s1 {
++ regulator-min-microvolt = <1300000>;
++ regulator-max-microvolt = <1300000>;
++ regulator-always-on;
++ regulator-boot-on;
+ };
+
+- sdhci@f98a4900 {
+- cd-gpios = <&tlmm 62 0x1>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
+- bus-width = <4>;
+- status = "okay";
++ pm8941_s2: s2 {
++ regulator-min-microvolt = <2150000>;
++ regulator-max-microvolt = <2150000>;
++ regulator-boot-on;
++ };
+
+- vmmc-supply = <&pm8941_l21>;
+- vqmmc-supply = <&pm8941_l13>;
++ pm8941_s3: s3 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ regulator-boot-on;
+ };
+
+- usb@f9a55000 {
+- status = "okay";
+- phys = <&usb_hs2_phy>;
+- phy-select = <&tcsr 0xb000 1>;
+- extcon = <&smbb>, <&usb_id>;
+- vbus-supply = <&chg_otg>;
+- hnp-disable;
+- srp-disable;
+- adp-disable;
+- ulpi {
+- phy@b {
+- status = "okay";
+- v3p3-supply = <&pm8941_l24>;
+- v1p8-supply = <&pm8941_l6>;
+- extcon = <&smbb>;
+- qcom,init-seq = /bits/ 8 <0x1 0x63>;
+- };
+- };
+- };
+-
+-
+- pinctrl@fd510000 {
+- i2c11_pins: i2c11 {
+- mux {
+- pins = "gpio83", "gpio84";
+- function = "blsp_i2c11";
+- };
+- };
+-
+- spi8_default: spi8_default {
+- mosi {
+- pins = "gpio45";
+- function = "blsp_spi8";
+- };
+- miso {
+- pins = "gpio46";
+- function = "blsp_spi8";
+- };
+- cs {
+- pins = "gpio47";
+- function = "blsp_spi8";
+- };
+- clk {
+- pins = "gpio48";
+- function = "blsp_spi8";
+- };
+- };
+-
+- sdhc1_pin_a: sdhc1-pin-active {
+- clk {
+- pins = "sdc1_clk";
+- drive-strength = <16>;
+- bias-disable;
+- };
+-
+- cmd-data {
+- pins = "sdc1_cmd", "sdc1_data";
+- drive-strength = <10>;
+- bias-pull-up;
+- };
+- };
+-
+- sdhc2_cd_pin_a: sdhc2-cd-pin-active {
+- pins = "gpio62";
+- function = "gpio";
+-
+- drive-strength = <2>;
+- bias-disable;
+- };
+-
+- sdhc2_pin_a: sdhc2-pin-active {
+- clk {
+- pins = "sdc2_clk";
+- drive-strength = <10>;
+- bias-disable;
+- };
+-
+- cmd-data {
+- pins = "sdc2_cmd", "sdc2_data";
+- drive-strength = <6>;
+- bias-pull-up;
+- };
+- };
+- };
+-
+- i2c@f9967000 {
+- status = "okay";
+- clock-frequency = <200000>;
+- pinctrl-0 = <&i2c11_pins>;
+- pinctrl-names = "default";
++ pm8941_l1: l1 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ pm8941_l2: l2 {
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
++ };
++
++ pm8941_l3: l3 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
++ };
++
++ pm8941_l4: l4 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
++ };
++
++ pm8941_l5: l5 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ pm8941_l6: l6 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
++ };
++
++ pm8941_l7: l7 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
++ };
++
++ pm8941_l8: l8 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ pm8941_l9: l9 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ };
++
++ pm8941_l10: l10 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ };
++
++ pm8941_l11: l11 {
++ regulator-min-microvolt = <1300000>;
++ regulator-max-microvolt = <1300000>;
++ };
++
++ pm8941_l12: l12 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ pm8941_l13: l13 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-boot-on;
++ };
++
++ pm8941_l14: l14 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ pm8941_l15: l15 {
++ regulator-min-microvolt = <2050000>;
++ regulator-max-microvolt = <2050000>;
++ };
++
++ pm8941_l16: l16 {
++ regulator-min-microvolt = <2700000>;
++ regulator-max-microvolt = <2700000>;
++ };
++
++ pm8941_l17: l17 {
++ regulator-min-microvolt = <2700000>;
++ regulator-max-microvolt = <2700000>;
++ };
++
++ pm8941_l18: l18 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++
++ pm8941_l19: l19 {
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-always-on;
++ };
++
++ pm8941_l20: l20 {
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-system-load = <200000>;
++ regulator-allow-set-load;
++ regulator-boot-on;
++ };
++
++ pm8941_l21: l21 {
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-boot-on;
++ };
++
++ pm8941_l22: l22 {
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3000000>;
++ };
++
++ pm8941_l23: l23 {
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3000000>;
++ };
++
++ pm8941_l24: l24 {
++ regulator-min-microvolt = <3075000>;
++ regulator-max-microvolt = <3075000>;
++ regulator-boot-on;
++ };
++ };
++};
++
++&sdhc_1 {
++ status = "okay";
++
++ vmmc-supply = <&pm8941_l20>;
++ vqmmc-supply = <&pm8941_s3>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhc1_pin_a>;
++};
++
++&sdhc_2 {
++ status = "okay";
++ cd-gpios = <&tlmm 62 0x1>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
++
++ vmmc-supply = <&pm8941_l21>;
++ vqmmc-supply = <&pm8941_l13>;
++};
++
++&tlmm {
++ i2c11_pins: i2c11 {
++ mux {
++ pins = "gpio83", "gpio84";
++ function = "blsp_i2c11";
++ };
++ };
++
++ spi8_default: spi8_default {
++ mosi {
++ pins = "gpio45";
++ function = "blsp_spi8";
++ };
++ miso {
++ pins = "gpio46";
++ function = "blsp_spi8";
++ };
++ cs {
++ pins = "gpio47";
++ function = "blsp_spi8";
++ };
++ clk {
++ pins = "gpio48";
++ function = "blsp_spi8";
++ };
++ };
++
++ sdhc1_pin_a: sdhc1-pin-active {
++ clk {
++ pins = "sdc1_clk";
++ drive-strength = <16>;
++ bias-disable;
++ };
+
+- eeprom: eeprom@52 {
+- compatible = "atmel,24c128";
+- reg = <0x52>;
+- pagesize = <32>;
+- read-only;
+- };
++ cmd-data {
++ pins = "sdc1_cmd", "sdc1_data";
++ drive-strength = <10>;
++ bias-pull-up;
+ };
+ };
+
+- smd {
+- rpm {
+- rpm-requests {
+- pm8841-regulators {
+- s1 {
+- regulator-min-microvolt = <675000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- s2 {
+- regulator-min-microvolt = <500000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- s3 {
+- regulator-min-microvolt = <500000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <500000>;
+- regulator-max-microvolt = <1050000>;
+- };
+- };
+-
+- pm8941-regulators {
+- vdd_l1_l3-supply = <&pm8941_s1>;
+- vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+- vdd_l4_l11-supply = <&pm8941_s1>;
+- vdd_l5_l7-supply = <&pm8941_s2>;
+- vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
+- vin_5vs-supply = <&pm8941_5v>;
+-
+- s1 {
+- regulator-min-microvolt = <1300000>;
+- regulator-max-microvolt = <1300000>;
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- s2 {
+- regulator-min-microvolt = <2150000>;
+- regulator-max-microvolt = <2150000>;
+- regulator-boot-on;
+- };
+-
+- s3 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l3 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-boot-on;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-boot-on;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- regulator-always-on;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <1300000>;
+- regulator-max-microvolt = <1300000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-boot-on;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l19 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- regulator-always-on;
+- };
+-
+- l20 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-allow-set-load;
+- regulator-boot-on;
+- regulator-system-load = <200000>;
+- };
+-
+- l21 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-boot-on;
+- };
+-
+- l22 {
+- regulator-min-microvolt = <3000000>;
+- regulator-max-microvolt = <3000000>;
+- };
+-
+- l23 {
+- regulator-min-microvolt = <3000000>;
+- regulator-max-microvolt = <3000000>;
+- };
+-
+- l24 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+-
+- regulator-boot-on;
+- };
+- };
+- };
++ sdhc2_cd_pin_a: sdhc2-cd-pin-active {
++ pins = "gpio62";
++ function = "gpio";
++
++ drive-strength = <2>;
++ bias-disable;
++ };
++
++ sdhc2_pin_a: sdhc2-pin-active {
++ clk {
++ pins = "sdc2_clk";
++ drive-strength = <10>;
++ bias-disable;
++ };
++
++ cmd-data {
++ pins = "sdc2_cmd", "sdc2_data";
++ drive-strength = <6>;
++ bias-pull-up;
+ };
+ };
+ };
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index 2182d2755926..ad05f0665035 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -1612,7 +1612,7 @@ rpm {
+ qcom,ipc = <&apcs 8 0>;
+ qcom,smd-edge = <15>;
+
+- rpm-requests {
++ rpm_requests: rpm-requests {
+ compatible = "qcom,rpm-msm8974";
+ qcom,smd-channels = "rpm_requests";
+
+--
+2.35.1
+
--- /dev/null
+From 75aa33a15914f7d880c2799fc82a77aee19e20c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Apr 2022 22:10:32 +0200
+Subject: ARM: dts: qcom: do not use underscore in node name
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 43cdc159d203eb6d02b312409e634a3fa06632ac ]
+
+Align RPM requests node with DT schema by using hyphen instead of
+underscore.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+[bjorn: Fixed up qcom-{apq8074,msm8974}-*.dts to match the qcom-msm8974.dtsi]
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220401201035.189106-8-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-apq8064.dtsi | 8 ++++----
+ arch/arm/boot/dts/qcom-apq8074-dragonboard.dts | 2 +-
+ arch/arm/boot/dts/qcom-apq8084.dtsi | 2 +-
+ arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts | 2 +-
+ arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts | 2 +-
+ arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 2 +-
+ arch/arm/boot/dts/qcom-msm8974-sony-xperia-amami.dts | 2 +-
+ arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts | 2 +-
+ arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts | 2 +-
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +-
+ 10 files changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
+index a1c8ae516d21..33a4d3441959 100644
+--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
++++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
+@@ -227,7 +227,7 @@ smem {
+ smd {
+ compatible = "qcom,smd";
+
+- modem@0 {
++ modem-edge {
+ interrupts = <0 37 IRQ_TYPE_EDGE_RISING>;
+
+ qcom,ipc = <&l2cc 8 3>;
+@@ -236,7 +236,7 @@ modem@0 {
+ status = "disabled";
+ };
+
+- q6@1 {
++ q6-edge {
+ interrupts = <0 90 IRQ_TYPE_EDGE_RISING>;
+
+ qcom,ipc = <&l2cc 8 15>;
+@@ -245,7 +245,7 @@ q6@1 {
+ status = "disabled";
+ };
+
+- dsps@3 {
++ dsps-edge {
+ interrupts = <0 138 IRQ_TYPE_EDGE_RISING>;
+
+ qcom,ipc = <&sps_sic_non_secure 0x4080 0>;
+@@ -254,7 +254,7 @@ dsps@3 {
+ status = "disabled";
+ };
+
+- riva@6 {
++ riva-edge {
+ interrupts = <0 198 IRQ_TYPE_EDGE_RISING>;
+
+ qcom,ipc = <&l2cc 8 25>;
+diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+index 83793b835d40..e2b4e4fc6377 100644
+--- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
++++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+@@ -147,7 +147,7 @@ eeprom: eeprom@52 {
+
+ smd {
+ rpm {
+- rpm_requests {
++ rpm-requests {
+ pm8841-regulators {
+ s1 {
+ regulator-min-microvolt = <675000>;
+diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi
+index 52240fc7a1a6..da50a1a0197f 100644
+--- a/arch/arm/boot/dts/qcom-apq8084.dtsi
++++ b/arch/arm/boot/dts/qcom-apq8084.dtsi
+@@ -470,7 +470,7 @@ rpm {
+ qcom,ipc = <&apcs 8 0>;
+ qcom,smd-edge = <15>;
+
+- rpm_requests {
++ rpm-requests {
+ compatible = "qcom,rpm-apq8084";
+ qcom,smd-channels = "rpm_requests";
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+index 6d77e0f8ca4d..9dbfc9f8646a 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+@@ -57,7 +57,7 @@ vibrator {
+
+ smd {
+ rpm {
+- rpm_requests {
++ rpm-requests {
+ pm8841-regulators {
+ s1 {
+ regulator-min-microvolt = <675000>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+index 6d5fb60e798f..5fbdba73c07f 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+@@ -42,7 +42,7 @@ volume-down {
+
+ smd {
+ rpm {
+- rpm_requests {
++ rpm-requests {
+ pm8841-regulators {
+ s1 {
+ regulator-min-microvolt = <675000>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+index 6e036a440532..1f630120c01f 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+@@ -54,7 +54,7 @@ volume-up {
+
+ smd {
+ rpm {
+- rpm_requests {
++ rpm-requests {
+ pma8084-regulators {
+ compatible = "qcom,rpm-pma8084-regulators";
+ status = "okay";
+diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-amami.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-amami.dts
+index 79e2cfbbb1ba..8cace789fb26 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-amami.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-amami.dts
+@@ -60,7 +60,7 @@ memory@0 {
+
+ smd {
+ rpm {
+- rpm_requests {
++ rpm-requests {
+ pm8841-regulators {
+ s1 {
+ regulator-min-microvolt = <675000>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
+index e66937e3f7dd..3c4a7d760ba9 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
+@@ -55,7 +55,7 @@ volume-up {
+
+ smd {
+ rpm {
+- rpm_requests {
++ rpm-requests {
+ pm8941-regulators {
+ vdd_l1_l3-supply = <&pm8941_s1>;
+ vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
+index a62e5c25b23c..f4a2e2560777 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
+@@ -60,7 +60,7 @@ memory@0 {
+
+ smd {
+ rpm {
+- rpm_requests {
++ rpm-requests {
+ pm8841-regulators {
+ s1 {
+ regulator-min-microvolt = <675000>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index 412d94736c35..08497783757a 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -1614,7 +1614,7 @@ rpm {
+ qcom,ipc = <&apcs 8 0>;
+ qcom,smd-edge = <15>;
+
+- rpm_requests {
++ rpm-requests {
+ compatible = "qcom,rpm-msm8974";
+ qcom,smd-channels = "rpm_requests";
+
+--
+2.35.1
+
--- /dev/null
+From 0cee7390d3e96c4c5c82dd5737e9b6c1128e8217 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 7 May 2022 21:49:12 +0200
+Subject: ARM: dts: qcom: mdm9615: add missing PMIC GPIO reg
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit dc590cdc31f636ea15658f1206c3e380a53fb78e ]
+
+'reg' property is required in SSBI children:
+ qcom-mdm9615-wp8548-mangoh-green.dtb: gpio@150: 'reg' is a required property
+
+Fixes: 2c5e596524e7 ("ARM: dts: Add MDM9615 dtsi")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220507194913.261121-11-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-mdm9615.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/boot/dts/qcom-mdm9615.dtsi b/arch/arm/boot/dts/qcom-mdm9615.dtsi
+index 4d4f37cebf21..96a66862875c 100644
+--- a/arch/arm/boot/dts/qcom-mdm9615.dtsi
++++ b/arch/arm/boot/dts/qcom-mdm9615.dtsi
+@@ -321,6 +321,7 @@ rtc@11d {
+
+ pmicgpio: gpio@150 {
+ compatible = "qcom,pm8018-gpio", "qcom,ssbi-gpio";
++ reg = <0x150>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-controller;
+--
+2.35.1
+
--- /dev/null
+From 5a051d2cd0896f3dc2c8435a24266d099bfd4044 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 19:18:41 +0200
+Subject: ARM: dts: qcom: msm8974: add required ranges to OCMEM
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 7a16ea7f3a5ec0f30b146b058c273b7a9c8ceadf ]
+
+The OCMEM bindings require ranges property.
+
+Fixes: a2cc991ed634 ("ARM: dts: qcom: msm8974: add ocmem node")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Luca Weiss <luca@z3ntu.xyz>
+Tested-by: Luca Weiss <luca@z3ntu.xyz>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220607171848.535128-7-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index ed3e46e7f96d..7a25d313e4fb 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -1369,6 +1369,7 @@ ocmem@fdd00000 {
+ reg = <0xfdd00000 0x2000>,
+ <0xfec00000 0x180000>;
+ reg-names = "ctrl", "mem";
++ ranges = <0 0xfec00000 0x180000>;
+ clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>,
+ <&mmcc OCMEMCX_OCMEMNOC_CLK>;
+ clock-names = "core", "iface";
+--
+2.35.1
+
--- /dev/null
+From 32d0fde0153c930a1d106bb430b18c2e2762676a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 13:56:23 +0200
+Subject: ARM: dts: qcom-msm8974-castor: Use &labels
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit 598a1e333224e73ae8f078ed6aa8dcd416cfb490 ]
+
+Use &labels to align with the style used in new DTS and apply tiny
+style fixes.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+[bjorn: Rebased ontop of Krzysztof's fixes]
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220415115633.575010-14-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../dts/qcom-msm8974-sony-xperia-castor.dts | 988 +++++++++---------
+ 1 file changed, 481 insertions(+), 507 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
+index 352689237140..687f6149268c 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
+@@ -53,186 +53,6 @@ volume-up {
+ };
+ };
+
+- smd {
+- rpm {
+- rpm-requests {
+- pm8941-regulators {
+- vdd_l1_l3-supply = <&pm8941_s1>;
+- vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+- vdd_l4_l11-supply = <&pm8941_s1>;
+- vdd_l5_l7-supply = <&pm8941_s2>;
+- vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
+- vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
+- vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
+- vdd_l21-supply = <&vreg_boost>;
+-
+- s1 {
+- regulator-min-microvolt = <1300000>;
+- regulator-max-microvolt = <1300000>;
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- s2 {
+- regulator-min-microvolt = <2150000>;
+- regulator-max-microvolt = <2150000>;
+- regulator-boot-on;
+- };
+-
+- s3 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- regulator-always-on;
+- regulator-boot-on;
+-
+- regulator-system-load = <154000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <5000000>;
+- regulator-max-microvolt = <5000000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-boot-on;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-boot-on;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <1300000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-boot-on;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l19 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l20 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-allow-set-load;
+- regulator-boot-on;
+- regulator-allow-set-load;
+- regulator-system-load = <500000>;
+- };
+-
+- l21 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-boot-on;
+- };
+-
+- l22 {
+- regulator-min-microvolt = <3000000>;
+- regulator-max-microvolt = <3000000>;
+- };
+-
+- l23 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l24 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+-
+- regulator-boot-on;
+- };
+- };
+- };
+- };
+- };
+-
+ vreg_bl_vddio: lcd-backlight-vddio {
+ compatible = "regulator-fixed";
+ regulator-name = "vreg_bl_vddio";
+@@ -277,447 +97,601 @@ vreg_wlan: wlan-regulator {
+ };
+ };
+
+-&soc {
+- sdhci@f9824900 {
+- status = "okay";
++&blsp1_uart2 {
++ status = "okay";
+
+- vmmc-supply = <&pm8941_l20>;
+- vqmmc-supply = <&pm8941_s3>;
+-
+- bus-width = <8>;
+- non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&blsp1_uart2_pin_a>;
++};
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc1_pin_a>;
+- };
++&blsp2_i2c2 {
++ status = "okay";
++ clock-frequency = <355000>;
+
+- sdhci@f9864900 {
+- status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c8_pins>;
+
+- max-frequency = <100000000>;
+- non-removable;
+- vmmc-supply = <&vreg_wlan>;
++ synaptics@2c {
++ compatible = "syna,rmi4-i2c";
++ reg = <0x2c>;
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc3_pin_a>;
++ interrupt-parent = <&tlmm>;
++ interrupts = <86 IRQ_TYPE_EDGE_FALLING>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+- bcrmf@1 {
+- compatible = "brcm,bcm4339-fmac", "brcm,bcm4329-fmac";
+- reg = <1>;
++ vdd-supply = <&pm8941_l22>;
++ vio-supply = <&pm8941_lvs3>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&ts_int_pin>;
+
+- brcm,drive-strength = <10>;
++ syna,startup-delay-ms = <10>;
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&wlan_sleep_clk_pin>;
++ rmi-f01@1 {
++ reg = <0x1>;
++ syna,nosleep = <1>;
+ };
+- };
+
+- sdhci@f98a4900 {
+- status = "okay";
++ rmi-f11@11 {
++ reg = <0x11>;
++ syna,f11-flip-x = <1>;
++ syna,sensor-type = <1>;
++ };
++ };
++};
+
+- bus-width = <4>;
++&blsp2_i2c5 {
++ status = "okay";
++ clock-frequency = <355000>;
+
+- vmmc-supply = <&pm8941_l21>;
+- vqmmc-supply = <&pm8941_l13>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c11_pins>;
+
+- cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
++ lp8566_wled: backlight@2c {
++ compatible = "ti,lp8556";
++ reg = <0x2c>;
++ power-supply = <&vreg_bl_vddio>;
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
++ bl-name = "backlight";
++ dev-ctrl = /bits/ 8 <0x05>;
++ init-brt = /bits/ 8 <0x3f>;
++ rom_a0h {
++ rom-addr = /bits/ 8 <0xa0>;
++ rom-val = /bits/ 8 <0xff>;
++ };
++ rom_a1h {
++ rom-addr = /bits/ 8 <0xa1>;
++ rom-val = /bits/ 8 <0x3f>;
++ };
++ rom_a2h {
++ rom-addr = /bits/ 8 <0xa2>;
++ rom-val = /bits/ 8 <0x20>;
++ };
++ rom_a3h {
++ rom-addr = /bits/ 8 <0xa3>;
++ rom-val = /bits/ 8 <0x5e>;
++ };
++ rom_a4h {
++ rom-addr = /bits/ 8 <0xa4>;
++ rom-val = /bits/ 8 <0x02>;
++ };
++ rom_a5h {
++ rom-addr = /bits/ 8 <0xa5>;
++ rom-val = /bits/ 8 <0x04>;
++ };
++ rom_a6h {
++ rom-addr = /bits/ 8 <0xa6>;
++ rom-val = /bits/ 8 <0x80>;
++ };
++ rom_a7h {
++ rom-addr = /bits/ 8 <0xa7>;
++ rom-val = /bits/ 8 <0xf7>;
++ };
++ rom_a9h {
++ rom-addr = /bits/ 8 <0xa9>;
++ rom-val = /bits/ 8 <0x80>;
++ };
++ rom_aah {
++ rom-addr = /bits/ 8 <0xaa>;
++ rom-val = /bits/ 8 <0x0f>;
++ };
++ rom_aeh {
++ rom-addr = /bits/ 8 <0xae>;
++ rom-val = /bits/ 8 <0x0f>;
++ };
+ };
++};
++
++&blsp2_uart1 {
++ status = "okay";
+
+- serial@f991e000 {
+- status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&blsp2_uart7_pin_a>;
++
++ bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ max-speed = <3000000>;
+
+ pinctrl-names = "default";
+- pinctrl-0 = <&blsp1_uart2_pin_a>;
++ pinctrl-0 = <&bt_host_wake_pin>,
++ <&bt_dev_wake_pin>,
++ <&bt_reg_on_pin>;
++
++ host-wakeup-gpios = <&tlmm 95 GPIO_ACTIVE_HIGH>;
++ device-wakeup-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
++ shutdown-gpios = <&pm8941_gpios 16 GPIO_ACTIVE_HIGH>;
+ };
++};
+
+- serial@f995d000 {
+- status = "ok";
++&otg {
++ status = "okay";
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&blsp2_uart7_pin_a>;
++ phys = <&usb_hs1_phy>;
++ phy-select = <&tcsr 0xb000 0>;
++ extcon = <&smbb>, <&usb_id>;
++ vbus-supply = <&chg_otg>;
+
+- bluetooth {
+- compatible = "brcm,bcm43438-bt";
+- max-speed = <3000000>;
++ hnp-disable;
++ srp-disable;
++ adp-disable;
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&bt_host_wake_pin>,
+- <&bt_dev_wake_pin>,
+- <&bt_reg_on_pin>;
++ ulpi {
++ phy@a {
++ status = "okay";
+
+- host-wakeup-gpios = <&tlmm 95 GPIO_ACTIVE_HIGH>;
+- device-wakeup-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
+- shutdown-gpios = <&pm8941_gpios 16 GPIO_ACTIVE_HIGH>;
++ v1p8-supply = <&pm8941_l6>;
++ v3p3-supply = <&pm8941_l24>;
++
++ extcon = <&smbb>;
++ qcom,init-seq = /bits/ 8 <0x1 0x64>;
+ };
+ };
++};
+
+- usb@f9a55000 {
+- status = "okay";
++&pm8941_coincell {
++ status = "okay";
+
+- phys = <&usb_hs1_phy>;
+- phy-select = <&tcsr 0xb000 0>;
+- extcon = <&smbb>, <&usb_id>;
+- vbus-supply = <&chg_otg>;
++ qcom,rset-ohms = <2100>;
++ qcom,vset-millivolts = <3000>;
++};
+
+- hnp-disable;
+- srp-disable;
+- adp-disable;
++&pm8941_gpios {
++ gpio_keys_pin_a: gpio-keys-active {
++ pins = "gpio2", "gpio5";
++ function = "normal";
+
+- ulpi {
+- phy@a {
+- status = "okay";
++ bias-pull-up;
++ power-source = <PM8941_GPIO_S3>;
++ };
+
+- v1p8-supply = <&pm8941_l6>;
+- v3p3-supply = <&pm8941_l24>;
++ bt_reg_on_pin: bt-reg-on {
++ pins = "gpio16";
++ function = "normal";
+
+- extcon = <&smbb>;
+- qcom,init-seq = /bits/ 8 <0x1 0x64>;
+- };
+- };
++ output-low;
++ power-source = <PM8941_GPIO_S3>;
+ };
+
+- pinctrl@fd510000 {
+- blsp1_uart2_pin_a: blsp1-uart2-pin-active {
+- rx {
+- pins = "gpio5";
+- function = "blsp_uart2";
++ wlan_sleep_clk_pin: wl-sleep-clk {
++ pins = "gpio17";
++ function = "func2";
+
+- drive-strength = <2>;
+- bias-pull-up;
+- };
++ output-high;
++ power-source = <PM8941_GPIO_S3>;
++ };
+
+- tx {
+- pins = "gpio4";
+- function = "blsp_uart2";
++ wlan_regulator_pin: wl-reg-active {
++ pins = "gpio18";
++ function = "normal";
+
+- drive-strength = <4>;
+- bias-disable;
+- };
+- };
++ bias-disable;
++ power-source = <PM8941_GPIO_S3>;
++ };
+
+- blsp2_uart7_pin_a: blsp2-uart7-pin-active {
+- tx {
+- pins = "gpio41";
+- function = "blsp_uart7";
++ lcd_dcdc_en_pin_a: lcd-dcdc-en-active {
++ pins = "gpio20";
++ function = "normal";
+
+- drive-strength = <2>;
+- bias-disable;
+- };
++ bias-disable;
++ power-source = <PM8941_GPIO_S3>;
++ input-disable;
++ output-low;
++ };
+
+- rx {
+- pins = "gpio42";
+- function = "blsp_uart7";
++};
+
+- drive-strength = <2>;
+- bias-pull-up;
+- };
++&rpm_requests {
++ pm8941-regulators {
++ vdd_l1_l3-supply = <&pm8941_s1>;
++ vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
++ vdd_l4_l11-supply = <&pm8941_s1>;
++ vdd_l5_l7-supply = <&pm8941_s2>;
++ vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
++ vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
++ vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
++ vdd_l21-supply = <&vreg_boost>;
++
++ pm8941_s1: s1 {
++ regulator-min-microvolt = <1300000>;
++ regulator-max-microvolt = <1300000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
+
+- cts {
+- pins = "gpio43";
+- function = "blsp_uart7";
++ pm8941_s2: s2 {
++ regulator-min-microvolt = <2150000>;
++ regulator-max-microvolt = <2150000>;
++ regulator-boot-on;
++ };
+
+- drive-strength = <2>;
+- bias-pull-up;
+- };
++ pm8941_s3: s3 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-system-load = <154000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
+
+- rts {
+- pins = "gpio44";
+- function = "blsp_uart7";
++ pm8941_s4: s4 {
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ };
+
+- drive-strength = <2>;
+- bias-disable;
+- };
++ pm8941_l1: l1 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
++ regulator-always-on;
++ regulator-boot-on;
+ };
+
+- i2c8_pins: i2c8 {
+- mux {
+- pins = "gpio47", "gpio48";
+- function = "blsp_i2c8";
++ pm8941_l2: l2 {
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
++ };
+
+- drive-strength = <2>;
+- bias-disable;
+- };
++ pm8941_l3: l3 {
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
+ };
+
+- i2c11_pins: i2c11 {
+- mux {
+- pins = "gpio83", "gpio84";
+- function = "blsp_i2c11";
++ pm8941_l4: l4 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
++ };
+
+- drive-strength = <2>;
+- bias-disable;
+- };
++ pm8941_l5: l5 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
+ };
+
+- lcd_backlight_en_pin_a: lcd-backlight-vddio {
+- pins = "gpio69";
+- drive-strength = <10>;
+- output-low;
+- bias-disable;
++ pm8941_l6: l6 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
+ };
+
+- sdhc1_pin_a: sdhc1-pin-active {
+- clk {
+- pins = "sdc1_clk";
+- drive-strength = <16>;
+- bias-disable;
+- };
++ pm8941_l7: l7 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
++ };
+
+- cmd-data {
+- pins = "sdc1_cmd", "sdc1_data";
+- drive-strength = <10>;
+- bias-pull-up;
+- };
++ pm8941_l8: l8 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
+ };
+
+- sdhc2_cd_pin_a: sdhc2-cd-pin-active {
+- pins = "gpio62";
+- function = "gpio";
++ pm8941_l9: l9 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ };
+
+- drive-strength = <2>;
+- bias-disable;
+- };
++ pm8941_l11: l11 {
++ regulator-min-microvolt = <1300000>;
++ regulator-max-microvolt = <1350000>;
++ };
+
+- sdhc2_pin_a: sdhc2-pin-active {
+- clk {
+- pins = "sdc2_clk";
+- drive-strength = <6>;
+- bias-disable;
+- };
++ pm8941_l12: l12 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
+
+- cmd-data {
+- pins = "sdc2_cmd", "sdc2_data";
+- drive-strength = <6>;
+- bias-pull-up;
+- };
++ pm8941_l13: l13 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-boot-on;
+ };
+
+- sdhc3_pin_a: sdhc3-pin-active {
+- clk {
+- pins = "gpio40";
+- function = "sdc3";
++ pm8941_l14: l14 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
+
+- drive-strength = <10>;
+- bias-disable;
+- };
++ pm8941_l15: l15 {
++ regulator-min-microvolt = <2050000>;
++ regulator-max-microvolt = <2050000>;
++ };
+
+- cmd {
+- pins = "gpio39";
+- function = "sdc3";
++ pm8941_l16: l16 {
++ regulator-min-microvolt = <2700000>;
++ regulator-max-microvolt = <2700000>;
++ };
++
++ pm8941_l17: l17 {
++ regulator-min-microvolt = <2700000>;
++ regulator-max-microvolt = <2700000>;
++ };
+
+- drive-strength = <10>;
+- bias-pull-up;
+- };
++ pm8941_l18: l18 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
+
+- data {
+- pins = "gpio35", "gpio36", "gpio37", "gpio38";
+- function = "sdc3";
++ pm8941_l19: l19 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
+
+- drive-strength = <10>;
+- bias-pull-up;
+- };
++ pm8941_l20: l20 {
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-system-load = <500000>;
++ regulator-allow-set-load;
++ regulator-boot-on;
+ };
+
+- ts_int_pin: synaptics {
+- pin {
+- pins = "gpio86";
+- function = "gpio";
++ pm8941_l21: l21 {
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-boot-on;
++ };
+
+- drive-strength = <2>;
+- bias-disable;
+- input-enable;
+- };
++ pm8941_l22: l22 {
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3000000>;
+ };
+
+- bt_host_wake_pin: bt-host-wake {
+- pins = "gpio95";
+- function = "gpio";
++ pm8941_l23: l23 {
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ };
+
+- drive-strength = <2>;
+- bias-disable;
+- output-low;
++ pm8941_l24: l24 {
++ regulator-min-microvolt = <3075000>;
++ regulator-max-microvolt = <3075000>;
++ regulator-boot-on;
+ };
++ };
++};
+
+- bt_dev_wake_pin: bt-dev-wake {
+- pins = "gpio96";
+- function = "gpio";
++&sdhc_1 {
++ status = "okay";
++
++ vmmc-supply = <&pm8941_l20>;
++ vqmmc-supply = <&pm8941_s3>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhc1_pin_a>;
++};
++
++&sdhc_2 {
++ status = "okay";
++
++ vmmc-supply = <&pm8941_l21>;
++ vqmmc-supply = <&pm8941_l13>;
++
++ cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
++};
++
++&sdhc_3 {
++ status = "okay";
++
++ max-frequency = <100000000>;
++ vmmc-supply = <&vreg_wlan>;
++ non-removable;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhc3_pin_a>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ bcrmf@1 {
++ compatible = "brcm,bcm4339-fmac", "brcm,bcm4329-fmac";
++ reg = <1>;
++
++ brcm,drive-strength = <10>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&wlan_sleep_clk_pin>;
++ };
++};
++
++&smbb {
++ qcom,fast-charge-safe-current = <1500000>;
++ qcom,fast-charge-current-limit = <1500000>;
++ qcom,dc-current-limit = <1800000>;
++ qcom,fast-charge-safe-voltage = <4400000>;
++ qcom,fast-charge-high-threshold-voltage = <4350000>;
++ qcom,fast-charge-low-threshold-voltage = <3400000>;
++ qcom,auto-recharge-threshold-voltage = <4200000>;
++ qcom,minimum-input-voltage = <4300000>;
++};
++
++&tlmm {
++ blsp1_uart2_pin_a: blsp1-uart2-pin-active {
++ rx {
++ pins = "gpio5";
++ function = "blsp_uart2";
+
+ drive-strength = <2>;
++ bias-pull-up;
++ };
++
++ tx {
++ pins = "gpio4";
++ function = "blsp_uart2";
++
++ drive-strength = <4>;
+ bias-disable;
+ };
+ };
+
+- i2c@f9964000 {
+- status = "okay";
++ blsp2_uart7_pin_a: blsp2-uart7-pin-active {
++ tx {
++ pins = "gpio41";
++ function = "blsp_uart7";
+
+- clock-frequency = <355000>;
+- qcom,src-freq = <50000000>;
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c8_pins>;
++ drive-strength = <2>;
++ bias-disable;
++ };
+
+- synaptics@2c {
+- compatible = "syna,rmi4-i2c";
+- reg = <0x2c>;
++ rx {
++ pins = "gpio42";
++ function = "blsp_uart7";
+
+- interrupt-parent = <&tlmm>;
+- interrupts = <86 IRQ_TYPE_EDGE_FALLING>;
++ drive-strength = <2>;
++ bias-pull-up;
++ };
+
+- #address-cells = <1>;
+- #size-cells = <0>;
++ cts {
++ pins = "gpio43";
++ function = "blsp_uart7";
+
+- vdd-supply = <&pm8941_l22>;
+- vio-supply = <&pm8941_lvs3>;
++ drive-strength = <2>;
++ bias-pull-up;
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&ts_int_pin>;
++ rts {
++ pins = "gpio44";
++ function = "blsp_uart7";
+
+- syna,startup-delay-ms = <10>;
++ drive-strength = <2>;
++ bias-disable;
++ };
++ };
+
+- rmi-f01@1 {
+- reg = <0x1>;
+- syna,nosleep = <1>;
+- };
++ i2c8_pins: i2c8 {
++ mux {
++ pins = "gpio47", "gpio48";
++ function = "blsp_i2c8";
+
+- rmi-f11@11 {
+- reg = <0x11>;
+- syna,f11-flip-x = <1>;
+- syna,sensor-type = <1>;
+- };
++ drive-strength = <2>;
++ bias-disable;
+ };
+ };
+
+- i2c@f9967000 {
+- status = "okay";
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c11_pins>;
+- clock-frequency = <355000>;
+- qcom,src-freq = <50000000>;
+-
+- lp8566_wled: backlight@2c {
+- compatible = "ti,lp8556";
+- reg = <0x2c>;
+- power-supply = <&vreg_bl_vddio>;
+-
+- bl-name = "backlight";
+- dev-ctrl = /bits/ 8 <0x05>;
+- init-brt = /bits/ 8 <0x3f>;
+- rom_a0h {
+- rom-addr = /bits/ 8 <0xa0>;
+- rom-val = /bits/ 8 <0xff>;
+- };
+- rom_a1h {
+- rom-addr = /bits/ 8 <0xa1>;
+- rom-val = /bits/ 8 <0x3f>;
+- };
+- rom_a2h {
+- rom-addr = /bits/ 8 <0xa2>;
+- rom-val = /bits/ 8 <0x20>;
+- };
+- rom_a3h {
+- rom-addr = /bits/ 8 <0xa3>;
+- rom-val = /bits/ 8 <0x5e>;
+- };
+- rom_a4h {
+- rom-addr = /bits/ 8 <0xa4>;
+- rom-val = /bits/ 8 <0x02>;
+- };
+- rom_a5h {
+- rom-addr = /bits/ 8 <0xa5>;
+- rom-val = /bits/ 8 <0x04>;
+- };
+- rom_a6h {
+- rom-addr = /bits/ 8 <0xa6>;
+- rom-val = /bits/ 8 <0x80>;
+- };
+- rom_a7h {
+- rom-addr = /bits/ 8 <0xa7>;
+- rom-val = /bits/ 8 <0xf7>;
+- };
+- rom_a9h {
+- rom-addr = /bits/ 8 <0xa9>;
+- rom-val = /bits/ 8 <0x80>;
+- };
+- rom_aah {
+- rom-addr = /bits/ 8 <0xaa>;
+- rom-val = /bits/ 8 <0x0f>;
+- };
+- rom_aeh {
+- rom-addr = /bits/ 8 <0xae>;
+- rom-val = /bits/ 8 <0x0f>;
+- };
++ i2c11_pins: i2c11 {
++ mux {
++ pins = "gpio83", "gpio84";
++ function = "blsp_i2c11";
++
++ drive-strength = <2>;
++ bias-disable;
+ };
+ };
+-};
+
+-&spmi_bus {
+- pm8941@0 {
+- charger@1000 {
+- qcom,fast-charge-safe-current = <1500000>;
+- qcom,fast-charge-current-limit = <1500000>;
+- qcom,dc-current-limit = <1800000>;
+- qcom,fast-charge-safe-voltage = <4400000>;
+- qcom,fast-charge-high-threshold-voltage = <4350000>;
+- qcom,fast-charge-low-threshold-voltage = <3400000>;
+- qcom,auto-recharge-threshold-voltage = <4200000>;
+- qcom,minimum-input-voltage = <4300000>;
++ lcd_backlight_en_pin_a: lcd-backlight-vddio {
++ pins = "gpio69";
++ drive-strength = <10>;
++ output-low;
++ bias-disable;
++ };
++
++ sdhc1_pin_a: sdhc1-pin-active {
++ clk {
++ pins = "sdc1_clk";
++ drive-strength = <16>;
++ bias-disable;
+ };
+
+- gpios@c000 {
+- gpio_keys_pin_a: gpio-keys-active {
+- pins = "gpio2", "gpio5";
+- function = "normal";
++ cmd-data {
++ pins = "sdc1_cmd", "sdc1_data";
++ drive-strength = <10>;
++ bias-pull-up;
++ };
++ };
+
+- bias-pull-up;
+- power-source = <PM8941_GPIO_S3>;
+- };
++ sdhc2_cd_pin_a: sdhc2-cd-pin-active {
++ pins = "gpio62";
++ function = "gpio";
+
+- bt_reg_on_pin: bt-reg-on {
+- pins = "gpio16";
+- function = "normal";
++ drive-strength = <2>;
++ bias-disable;
++ };
+
+- output-low;
+- power-source = <PM8941_GPIO_S3>;
+- };
++ sdhc2_pin_a: sdhc2-pin-active {
++ clk {
++ pins = "sdc2_clk";
++ drive-strength = <6>;
++ bias-disable;
++ };
+
+- wlan_sleep_clk_pin: wl-sleep-clk {
+- pins = "gpio17";
+- function = "func2";
++ cmd-data {
++ pins = "sdc2_cmd", "sdc2_data";
++ drive-strength = <6>;
++ bias-pull-up;
++ };
++ };
+
+- output-high;
+- power-source = <PM8941_GPIO_S3>;
+- };
++ sdhc3_pin_a: sdhc3-pin-active {
++ clk {
++ pins = "gpio40";
++ function = "sdc3";
+
+- wlan_regulator_pin: wl-reg-active {
+- pins = "gpio18";
+- function = "normal";
++ drive-strength = <10>;
++ bias-disable;
++ };
+
+- bias-disable;
+- power-source = <PM8941_GPIO_S3>;
+- };
++ cmd {
++ pins = "gpio39";
++ function = "sdc3";
+
+- lcd_dcdc_en_pin_a: lcd-dcdc-en-active {
+- pins = "gpio20";
+- function = "normal";
++ drive-strength = <10>;
++ bias-pull-up;
++ };
+
+- bias-disable;
+- power-source = <PM8941_GPIO_S3>;
+- input-disable;
+- output-low;
+- };
++ data {
++ pins = "gpio35", "gpio36", "gpio37", "gpio38";
++ function = "sdc3";
+
++ drive-strength = <10>;
++ bias-pull-up;
+ };
++ };
+
+- coincell@2800 {
+- status = "okay";
+- qcom,rset-ohms = <2100>;
+- qcom,vset-millivolts = <3000>;
++ ts_int_pin: synaptics {
++ pin {
++ pins = "gpio86";
++ function = "gpio";
++
++ drive-strength = <2>;
++ bias-disable;
++ input-enable;
+ };
+ };
++
++ bt_host_wake_pin: bt-host-wake {
++ pins = "gpio95";
++ function = "gpio";
++
++ drive-strength = <2>;
++ bias-disable;
++ output-low;
++ };
++
++ bt_dev_wake_pin: bt-dev-wake {
++ pins = "gpio96";
++ function = "gpio";
++
++ drive-strength = <2>;
++ bias-disable;
++ };
+ };
+--
+2.35.1
+
--- /dev/null
+From 9c9b836774e9d0dbb56b99c1de122053b33af048 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 13:56:26 +0200
+Subject: ARM: dts: qcom-msm8974: Convert ADSP to a MMIO device
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit 2daa785817dd35172b856c30fc5148b2773b6891 ]
+
+The cx-supply has been removed as it's supposed to be set on a
+per-board basis.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220415115633.575010-17-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 60 ++++++++++++++---------------
+ 1 file changed, 30 insertions(+), 30 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index ea3491d47b9f..e6c9782e4670 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -341,36 +341,6 @@ timer {
+ clock-frequency = <19200000>;
+ };
+
+- remoteproc_adsp: adsp-pil {
+- compatible = "qcom,msm8974-adsp-pil";
+-
+- interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>,
+- <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+- <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+- <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+- <&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack";
+-
+- cx-supply = <&pm8841_s2>;
+-
+- clocks = <&xo_board>;
+- clock-names = "xo";
+-
+- memory-region = <&adsp_region>;
+-
+- qcom,smem-states = <&adsp_smp2p_out 0>;
+- qcom,smem-state-names = "stop";
+-
+- smd-edge {
+- interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
+-
+- qcom,ipc = <&apcs 8 8>;
+- qcom,smd-edge = <1>;
+-
+- label = "lpass";
+- };
+- };
+-
+ smem {
+ compatible = "qcom,smem";
+
+@@ -1592,6 +1562,36 @@ dsi0_phy: dsi-phy@fd922a00 {
+ };
+ };
+
++ remoteproc_adsp: remoteproc@fe200000 {
++ compatible = "qcom,msm8974-adsp-pil";
++ reg = <0xfe200000 0x100>;
++
++ interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>,
++ <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
++ <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
++ <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
++ <&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack";
++
++ clocks = <&xo_board>;
++ clock-names = "xo";
++
++ memory-region = <&adsp_region>;
++
++ qcom,smem-states = <&adsp_smp2p_out 0>;
++ qcom,smem-state-names = "stop";
++
++ smd-edge {
++ interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
++
++ qcom,ipc = <&apcs 8 8>;
++ qcom,smd-edge = <1>;
++ label = "lpass";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ };
++ };
++
+ imem: imem@fe805000 {
+ status = "disabled";
+ compatible = "syscon", "simple-mfd";
+--
+2.35.1
+
--- /dev/null
+From b14a0dfa1b60f0cda5fabb284556d9014d311c52 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 14:44:18 +0200
+Subject: ARM: dts: qcom: msm8974: Disable remoteprocs by default
+
+From: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
+
+[ Upstream commit 8d8be8dd7c1f5d50f84ecc7a6a41962da48c6164 ]
+
+The remoteproc configuration in qcom-msm8974.dtsi is incomplete because
+it lacks the regulator supplies that should be added in the board DT
+files. Some of the msm8974 boards are currently missing the regulator
+supplies and should have the remoteprocs disabled to avoid making use
+of the incomplete configuration.
+
+This also fixes dtbs_check warnings after moving "qcom,msm8974-mss-pil"
+to DT schema, which rightfully complains that the -supply properties
+are missing for some boards:
+
+qcom-apq8074-dragonboard.dtb:
+remoteproc@fc880000: 'pll-supply' is a required property
+ From schema: remoteproc/qcom,msm8916-mss-pil.yaml
+remoteproc@fc880000: 'mss-supply' is a required property
+ From schema: remoteproc/qcom,msm8916-mss-pil.yaml
+remoteproc@fc880000: 'oneOf' conditional failed, one must be fixed:
+ 'power-domains' is a required property
+ 'power-domain-names' is a required property, or
+ 'cx-supply' is a required property
+ 'mx-supply' is a required property
+
+Cc: Luca Weiss <luca@z3ntu.xyz>
+Cc: Konrad Dybcio <konrad.dybcio@somainline.org>
+Fixes: f300826d27be ("ARM: dts: qcom-msm8974: Sort and clean up nodes")
+Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220712124421.3129206-4-stephan.gerhold@kernkonzept.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts | 2 ++
+ arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 2 ++
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 4 ++++
+ 3 files changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+index 32975f56f896..085591183592 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+@@ -132,10 +132,12 @@ wcnss {
+ };
+
+ &remoteproc_adsp {
++ status = "okay";
+ cx-supply = <&pm8841_s2>;
+ };
+
+ &remoteproc_mss {
++ status = "okay";
+ cx-supply = <&pm8841_s2>;
+ mss-supply = <&pm8841_s3>;
+ mx-supply = <&pm8841_s1>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+index 3b1ea8c24f57..9ef5a68747f1 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+@@ -467,10 +467,12 @@ fuelgauge_pin: fuelgauge-int-pin {
+ };
+
+ &remoteproc_adsp {
++ status = "okay";
+ cx-supply = <&pma8084_s2>;
+ };
+
+ &remoteproc_mss {
++ status = "okay";
+ cx-supply = <&pma8084_s2>;
+ mss-supply = <&pma8084_s6>;
+ mx-supply = <&pma8084_s1>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index 7a25d313e4fb..05a36566bd52 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -1150,6 +1150,8 @@ remoteproc_mss: remoteproc@fc880000 {
+ qcom,smem-states = <&modem_smp2p_out 0>;
+ qcom,smem-state-names = "stop";
+
++ status = "disabled";
++
+ mba {
+ memory-region = <&mba_region>;
+ };
+@@ -1401,6 +1403,8 @@ remoteproc_adsp: remoteproc@fe200000 {
+ qcom,smem-states = <&adsp_smp2p_out 0>;
+ qcom,smem-state-names = "stop";
+
++ status = "disabled";
++
+ smd-edge {
+ interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
+
+--
+2.35.1
+
--- /dev/null
+From 862de340e697e6e0d7d843c50db0cf08ed978918 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 13:56:14 +0200
+Subject: ARM: dts: qcom-msm8974*: Fix I2C labels
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit bb167546d06847a8729c973fe5165a231fd5c39d ]
+
+Fix up the label names and add missing ones.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220415115633.575010-5-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index 689ddaabf463..6e99903bb5f9 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -959,7 +959,7 @@ msmgpio: pinctrl@fd510000 {
+ interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+- i2c@f9923000 {
++ blsp1_i2c1: i2c@f9923000 {
+ status = "disabled";
+ compatible = "qcom,i2c-qup-v2.1.1";
+ reg = <0xf9923000 0x1000>;
+@@ -970,7 +970,7 @@ i2c@f9923000 {
+ #size-cells = <0>;
+ };
+
+- i2c@f9924000 {
++ blsp1_i2c2: i2c@f9924000 {
+ status = "disabled";
+ compatible = "qcom,i2c-qup-v2.1.1";
+ reg = <0xf9924000 0x1000>;
+@@ -981,7 +981,7 @@ i2c@f9924000 {
+ #size-cells = <0>;
+ };
+
+- blsp_i2c3: i2c@f9925000 {
++ blsp1_i2c3: i2c@f9925000 {
+ status = "disabled";
+ compatible = "qcom,i2c-qup-v2.1.1";
+ reg = <0xf9925000 0x1000>;
+@@ -992,7 +992,7 @@ blsp_i2c3: i2c@f9925000 {
+ #size-cells = <0>;
+ };
+
+- blsp_i2c6: i2c@f9928000 {
++ blsp1_i2c6: i2c@f9928000 {
+ status = "disabled";
+ compatible = "qcom,i2c-qup-v2.1.1";
+ reg = <0xf9928000 0x1000>;
+@@ -1003,7 +1003,7 @@ blsp_i2c6: i2c@f9928000 {
+ #size-cells = <0>;
+ };
+
+- blsp_i2c8: i2c@f9964000 {
++ blsp2_i2c2: i2c@f9964000 {
+ status = "disabled";
+ compatible = "qcom,i2c-qup-v2.1.1";
+ reg = <0xf9964000 0x1000>;
+@@ -1014,7 +1014,7 @@ blsp_i2c8: i2c@f9964000 {
+ #size-cells = <0>;
+ };
+
+- blsp_i2c11: i2c@f9967000 {
++ blsp2_i2c5: i2c@f9967000 {
+ status = "disabled";
+ compatible = "qcom,i2c-qup-v2.1.1";
+ reg = <0xf9967000 0x1000>;
+@@ -1027,7 +1027,7 @@ blsp_i2c11: i2c@f9967000 {
+ dma-names = "tx", "rx";
+ };
+
+- blsp_i2c12: i2c@f9968000 {
++ blsp2_i2c6: i2c@f9968000 {
+ status = "disabled";
+ compatible = "qcom,i2c-qup-v2.1.1";
+ reg = <0xf9968000 0x1000>;
+--
+2.35.1
+
--- /dev/null
+From 57ed6deceb9d1654dcca2843013024c4f709cfb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 May 2022 10:36:18 +0200
+Subject: ARM: dts: qcom-msm8974: fix irq type on blsp2_uart1
+
+From: Luca Weiss <luca@z3ntu.xyz>
+
+[ Upstream commit ab1489017aa7a9f02e24bee73cf9ec8079cd3909 ]
+
+IRQ_TYPE_NONE is invalid, so use the correct interrupt type.
+
+Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
+Fixes: b05f82b152c9 ("ARM: dts: qcom: msm8974: Add blsp2_uart7 for bluetooth on sirius")
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220522083618.17894-1-luca@z3ntu.xyz
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index 0091a4c29fff..ed3e46e7f96d 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -562,7 +562,7 @@ blsp2_dma: dma-controller@f9944000 {
+ blsp2_uart1: serial@f995d000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0xf995d000 0x1000>;
+- interrupts = <GIC_SPI 113 IRQ_TYPE_NONE>;
++ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc GCC_BLSP2_UART1_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
+ clock-names = "core", "iface";
+ status = "disabled";
+--
+2.35.1
+
--- /dev/null
+From 26a5f3fc239c3883e513c4d84b337d0ed2085c7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 13:56:13 +0200
+Subject: ARM: dts: qcom-msm8974*: Fix UART naming
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit b905c34ae7db6b564589f02fa7eac7afaa0294e9 ]
+
+It's either uart10, or blsp2_uart4, not blsp2_uart10, as there aren't 10
+UARTs on BLSP2. Fix the naming to align with what's done in arm64/qcom.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220415115633.575010-4-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts | 6 +++---
+ arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 10 +++++-----
+ arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts | 2 +-
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 6 +++---
+ 4 files changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+index 5fbdba73c07f..dd2d0647d4be 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+@@ -12,7 +12,7 @@ / {
+
+ aliases {
+ serial0 = &blsp1_uart1;
+- serial1 = &blsp2_uart10;
++ serial1 = &blsp2_uart4;
+ };
+
+ chosen {
+@@ -395,7 +395,7 @@ shutdown {
+ };
+ };
+
+- blsp2_uart10_pin_a: blsp2-uart10-pin-active {
++ blsp2_uart4_pin_a: blsp2-uart4-pin-active {
+ tx {
+ pins = "gpio53";
+ function = "blsp_uart10";
+@@ -473,7 +473,7 @@ serial@f9960000 {
+ status = "okay";
+
+ pinctrl-names = "default";
+- pinctrl-0 = <&blsp2_uart10_pin_a>;
++ pinctrl-0 = <&blsp2_uart4_pin_a>;
+
+ bluetooth {
+ compatible = "brcm,bcm43438-bt";
+diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+index 1f630120c01f..95ae30d06554 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+@@ -358,13 +358,13 @@ serial@f991e000 {
+ status = "okay";
+ };
+
+- /* blsp2_uart8 */
++ /* blsp2_uart2 */
+ serial@f995e000 {
+ status = "okay";
+
+ pinctrl-names = "default", "sleep";
+- pinctrl-0 = <&blsp2_uart8_pins_active>;
+- pinctrl-1 = <&blsp2_uart8_pins_sleep>;
++ pinctrl-0 = <&blsp2_uart2_pins_active>;
++ pinctrl-1 = <&blsp2_uart2_pins_sleep>;
+
+ bluetooth {
+ compatible = "brcm,bcm43540-bt";
+@@ -380,14 +380,14 @@ bluetooth {
+ };
+
+ pinctrl@fd510000 {
+- blsp2_uart8_pins_active: blsp2-uart8-pins-active {
++ blsp2_uart2_pins_active: blsp2-uart2-pins-active {
+ pins = "gpio45", "gpio46", "gpio47", "gpio48";
+ function = "blsp_uart8";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+- blsp2_uart8_pins_sleep: blsp2-uart8-pins-sleep {
++ blsp2_uart2_pins_sleep: blsp2-uart2-pins-sleep {
+ pins = "gpio45", "gpio46", "gpio47", "gpio48";
+ function = "gpio";
+ drive-strength = <2>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
+index 3c4a7d760ba9..e27b360951fd 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
+@@ -11,7 +11,7 @@ / {
+
+ aliases {
+ serial0 = &blsp1_uart2;
+- serial1 = &blsp2_uart7;
++ serial1 = &blsp2_uart1;
+ };
+
+ chosen {
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index 08497783757a..689ddaabf463 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -715,7 +715,7 @@ blsp1_uart2: serial@f991e000 {
+ status = "disabled";
+ };
+
+- blsp2_uart7: serial@f995d000 {
++ blsp2_uart1: serial@f995d000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0xf995d000 0x1000>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_NONE>;
+@@ -724,7 +724,7 @@ blsp2_uart7: serial@f995d000 {
+ status = "disabled";
+ };
+
+- blsp2_uart8: serial@f995e000 {
++ blsp2_uart2: serial@f995e000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0xf995e000 0x1000>;
+ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+@@ -733,7 +733,7 @@ blsp2_uart8: serial@f995e000 {
+ status = "disabled";
+ };
+
+- blsp2_uart10: serial@f9960000 {
++ blsp2_uart4: serial@f9960000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0xf9960000 0x1000>;
+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+--
+2.35.1
+
--- /dev/null
+From f2f3eccdd8545af1f40e20ac13c39ef0b5866e93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 13:56:15 +0200
+Subject: ARM: dts: qcom-msm8974: Fix up mdss nodes
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit 4de36f7b6d0e7e792d36800ac6c5e3392b59573a ]
+
+Fix up formatting, move status=disabled to the end where it belongs,
+rename DSI PHY label to match newer DTs, use tabs where possible,
+unwrap lines where wrapping is not necessary and don't disable mdp,
+as MDSS is useless without it.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220415115633.575010-6-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 77 +++++++++++++----------------
+ 1 file changed, 34 insertions(+), 43 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index 6e99903bb5f9..2d54d18310da 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -1461,35 +1461,29 @@ opp-27000000 {
+ };
+
+ mdss: mdss@fd900000 {
+- status = "disabled";
+-
+ compatible = "qcom,mdss";
+- reg = <0xfd900000 0x100>,
+- <0xfd924000 0x1000>;
+- reg-names = "mdss_phys",
+- "vbif_phys";
++ reg = <0xfd900000 0x100>, <0xfd924000 0x1000>;
++ reg-names = "mdss_phys", "vbif_phys";
+
+ power-domains = <&mmcc MDSS_GDSC>;
+
+ clocks = <&mmcc MDSS_AHB_CLK>,
+- <&mmcc MDSS_AXI_CLK>,
+- <&mmcc MDSS_VSYNC_CLK>;
+- clock-names = "iface",
+- "bus",
+- "vsync";
++ <&mmcc MDSS_AXI_CLK>,
++ <&mmcc MDSS_VSYNC_CLK>;
++ clock-names = "iface", "bus", "vsync";
+
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
++ status = "disabled";
++
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ mdp: mdp@fd900000 {
+- status = "disabled";
+-
+ compatible = "qcom,mdp5";
+ reg = <0xfd900100 0x22000>;
+ reg-names = "mdp_phys";
+@@ -1501,10 +1495,7 @@ mdp: mdp@fd900000 {
+ <&mmcc MDSS_AXI_CLK>,
+ <&mmcc MDSS_MDP_CLK>,
+ <&mmcc MDSS_VSYNC_CLK>;
+- clock-names = "iface",
+- "bus",
+- "core",
+- "vsync";
++ clock-names = "iface", "bus", "core", "vsync";
+
+ interconnects = <&mmssnoc MNOC_MAS_MDP_PORT0 &bimc BIMC_SLV_EBI_CH0>;
+ interconnect-names = "mdp0-mem";
+@@ -1523,8 +1514,6 @@ mdp5_intf1_out: endpoint {
+ };
+
+ dsi0: dsi@fd922800 {
+- status = "disabled";
+-
+ compatible = "qcom,mdss-dsi-ctrl";
+ reg = <0xfd922800 0x1f8>;
+ reg-names = "dsi_ctrl";
+@@ -1532,29 +1521,32 @@ dsi0: dsi@fd922800 {
+ interrupt-parent = <&mdss>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
+
+- assigned-clocks = <&mmcc BYTE0_CLK_SRC>,
+- <&mmcc PCLK0_CLK_SRC>;
+- assigned-clock-parents = <&dsi_phy0 0>,
+- <&dsi_phy0 1>;
++ assigned-clocks = <&mmcc BYTE0_CLK_SRC>, <&mmcc PCLK0_CLK_SRC>;
++ assigned-clock-parents = <&dsi0_phy 0>, <&dsi0_phy 1>;
+
+ clocks = <&mmcc MDSS_MDP_CLK>,
+- <&mmcc MDSS_AHB_CLK>,
+- <&mmcc MDSS_AXI_CLK>,
+- <&mmcc MDSS_BYTE0_CLK>,
+- <&mmcc MDSS_PCLK0_CLK>,
+- <&mmcc MDSS_ESC0_CLK>,
+- <&mmcc MMSS_MISC_AHB_CLK>;
++ <&mmcc MDSS_AHB_CLK>,
++ <&mmcc MDSS_AXI_CLK>,
++ <&mmcc MDSS_BYTE0_CLK>,
++ <&mmcc MDSS_PCLK0_CLK>,
++ <&mmcc MDSS_ESC0_CLK>,
++ <&mmcc MMSS_MISC_AHB_CLK>;
+ clock-names = "mdp_core",
+- "iface",
+- "bus",
+- "byte",
+- "pixel",
+- "core",
+- "core_mmss";
+-
+- phys = <&dsi_phy0>;
++ "iface",
++ "bus",
++ "byte",
++ "pixel",
++ "core",
++ "core_mmss";
++
++ phys = <&dsi0_phy>;
+ phy-names = "dsi-phy";
+
++ status = "disabled";
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+@@ -1574,23 +1566,22 @@ dsi0_out: endpoint {
+ };
+ };
+
+- dsi_phy0: dsi-phy@fd922a00 {
+- status = "disabled";
+-
++ dsi0_phy: dsi-phy@fd922a00 {
+ compatible = "qcom,dsi-phy-28nm-hpm";
+ reg = <0xfd922a00 0xd4>,
+ <0xfd922b00 0x280>,
+ <0xfd922d80 0x30>;
+ reg-names = "dsi_pll",
+- "dsi_phy",
+- "dsi_phy_regulator";
++ "dsi_phy",
++ "dsi_phy_regulator";
+
+ #clock-cells = <1>;
+ #phy-cells = <0>;
+- qcom,dsi-phy-index = <0>;
+
+ clocks = <&mmcc MDSS_AHB_CLK>, <&xo_board>;
+ clock-names = "iface", "ref";
++
++ status = "disabled";
+ };
+ };
+
+--
+2.35.1
+
--- /dev/null
+From dcb4adcac6577858b7f7ddaffb3d749ebecf0615 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 13:56:16 +0200
+Subject: ARM: dts: qcom-msm8974: Fix up SDHCI nodes
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit 64cf62683b5398e46cf967c308be95685137626a ]
+
+- Add missing labels (and remove their redefinition from klte)
+- Commonize bus-width
+- Add non-removable on sdhc_1, as it's supposed to have an eMMC on it
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220415115633.575010-7-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts | 4 ++--
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 13 ++++++++++---
+ 2 files changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+index 95ae30d06554..3ee2508b20fb 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+@@ -534,7 +534,7 @@ te {
+ };
+ };
+
+- sdhc_1: sdhci@f9824900 {
++ sdhci@f9824900 {
+ status = "okay";
+
+ vmmc-supply = <&pma8084_l20>;
+@@ -547,7 +547,7 @@ sdhc_1: sdhci@f9824900 {
+ pinctrl-0 = <&sdhc1_pin_a>;
+ };
+
+- sdhc_2: sdhci@f9864900 {
++ sdhci@f9864900 {
+ status = "okay";
+
+ max-frequency = <100000000>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index 2d54d18310da..d8a1ba5b845c 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -742,7 +742,7 @@ blsp2_uart4: serial@f9960000 {
+ status = "disabled";
+ };
+
+- sdhci@f9824900 {
++ sdhc_1: sdhci@f9824900 {
+ compatible = "qcom,msm8974-sdhci", "qcom,sdhci-msm-v4";
+ reg = <0xf9824900 0x11c>, <0xf9824000 0x800>;
+ reg-names = "hc_mem", "core_mem";
+@@ -753,10 +753,13 @@ sdhci@f9824900 {
+ <&gcc GCC_SDCC1_AHB_CLK>,
+ <&xo_board>;
+ clock-names = "core", "iface", "xo";
++ bus-width = <8>;
++ non-removable;
++
+ status = "disabled";
+ };
+
+- sdhci@f9864900 {
++ sdhc_3: sdhci@f9864900 {
+ compatible = "qcom,msm8974-sdhci", "qcom,sdhci-msm-v4";
+ reg = <0xf9864900 0x11c>, <0xf9864000 0x800>;
+ reg-names = "hc_mem", "core_mem";
+@@ -767,10 +770,12 @@ sdhci@f9864900 {
+ <&gcc GCC_SDCC3_AHB_CLK>,
+ <&xo_board>;
+ clock-names = "core", "iface", "xo";
++ bus-width = <4>;
++
+ status = "disabled";
+ };
+
+- sdhci@f98a4900 {
++ sdhc_2: sdhci@f98a4900 {
+ compatible = "qcom,msm8974-sdhci", "qcom,sdhci-msm-v4";
+ reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>;
+ reg-names = "hc_mem", "core_mem";
+@@ -781,6 +786,8 @@ sdhci@f98a4900 {
+ <&gcc GCC_SDCC2_AHB_CLK>,
+ <&xo_board>;
+ clock-names = "core", "iface", "xo";
++ bus-width = <4>;
++
+ status = "disabled";
+ };
+
+--
+2.35.1
+
--- /dev/null
+From d5e29d1fc785b60f8ac337c1a36b908a228b01ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Apr 2022 23:42:43 +0200
+Subject: ARM: dts: qcom: msm8974-FP2: Add supplies for remoteprocs
+
+From: Luca Weiss <luca@z3ntu.xyz>
+
+[ Upstream commit fb5e339fb1bc9eb7f34b341d995e4ab39c03588e ]
+
+Those were removed from msm8974.dtsi as part of a recent cleanup commit,
+so add them back for FP2.
+
+Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220421214243.352469-3-luca@z3ntu.xyz
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+index d6799a1b820b..32975f56f896 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+@@ -131,6 +131,17 @@ wcnss {
+ };
+ };
+
++&remoteproc_adsp {
++ cx-supply = <&pm8841_s2>;
++};
++
++&remoteproc_mss {
++ cx-supply = <&pm8841_s2>;
++ mss-supply = <&pm8841_s3>;
++ mx-supply = <&pm8841_s1>;
++ pll-supply = <&pm8941_l12>;
++};
++
+ &rpm_requests {
+ pm8841-regulators {
+ compatible = "qcom,rpm-pm8841-regulators";
+--
+2.35.1
+
--- /dev/null
+From 51c3875f8d09ec8ed4e137b338b1914f8d418dda Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 13:56:19 +0200
+Subject: ARM: dts: qcom-msm8974-fp2: Use &labels
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit 409ab7dc57c41d9db54d221f4d247e229ba34cf9 ]
+
+Use &labels to align with the style used in new DTS and apply tiny
+style fixes.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+[bjorn: Rebased on top of Krzysztof underscore fixes]
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220415115633.575010-10-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/qcom-msm8974-fairphone-fp2.dts | 577 +++++++++---------
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +-
+ 2 files changed, 276 insertions(+), 303 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+index 1e947bab06b6..38e48ea021d9 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+@@ -5,7 +5,6 @@
+ #include <dt-bindings/input/input.h>
+ #include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+
+-
+ / {
+ model = "Fairphone 2";
+ compatible = "fairphone,fp2", "qcom,msm8974";
+@@ -54,356 +53,330 @@ vibrator {
+ enable-gpios = <&tlmm 86 GPIO_ACTIVE_HIGH>;
+ vcc-supply = <&pm8941_l18>;
+ };
++};
++
++&blsp1_uart2 {
++ status = "okay";
++};
++
++&imem {
++ status = "okay";
++
++ reboot-mode {
++ mode-normal = <0x77665501>;
++ mode-bootloader = <0x77665500>;
++ mode-recovery = <0x77665502>;
++ };
++};
++
++&otg {
++ status = "okay";
++
++ phys = <&usb_hs1_phy>;
++ phy-select = <&tcsr 0xb000 0>;
++ extcon = <&smbb>, <&usb_id>;
++ vbus-supply = <&chg_otg>;
+
+- smd {
+- rpm {
+- rpm-requests {
+- pm8841-regulators {
+- s1 {
+- regulator-min-microvolt = <675000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- s2 {
+- regulator-min-microvolt = <500000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- s3 {
+- regulator-min-microvolt = <1050000>;
+- regulator-max-microvolt = <1050000>;
+- };
+- };
+-
+- pm8941-regulators {
+- vdd_l1_l3-supply = <&pm8941_s1>;
+- vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+- vdd_l4_l11-supply = <&pm8941_s1>;
+- vdd_l5_l7-supply = <&pm8941_s2>;
+- vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
+- vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
+- vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
+- vdd_l21-supply = <&vreg_boost>;
+-
+- s1 {
+- regulator-min-microvolt = <1300000>;
+- regulator-max-microvolt = <1300000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- s2 {
+- regulator-min-microvolt = <2150000>;
+- regulator-max-microvolt = <2150000>;
+-
+- regulator-boot-on;
+- };
+-
+- s3 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l3 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-boot-on;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-boot-on;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-boot-on;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l19 {
+- regulator-min-microvolt = <2900000>;
+- regulator-max-microvolt = <3350000>;
+- };
+-
+- l20 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-boot-on;
+- regulator-system-load = <200000>;
+- regulator-allow-set-load;
+- };
+-
+- l21 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-boot-on;
+- };
+-
+- l22 {
+- regulator-min-microvolt = <3000000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l23 {
+- regulator-min-microvolt = <3000000>;
+- regulator-max-microvolt = <3000000>;
+- };
+-
+- l24 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+-
+- regulator-boot-on;
+- };
+- };
+- };
++ hnp-disable;
++ srp-disable;
++ adp-disable;
++
++ ulpi {
++ phy@a {
++ status = "okay";
++
++ v1p8-supply = <&pm8941_l6>;
++ v3p3-supply = <&pm8941_l24>;
++
++ extcon = <&smbb>;
++ qcom,init-seq = /bits/ 8 <0x1 0x64>;
+ };
+ };
+ };
+
+-&soc {
+- serial@f991e000 {
+- status = "okay";
++&pm8941_gpios {
++ gpio_keys_pin_a: gpio-keys-active {
++ pins = "gpio1", "gpio2", "gpio5";
++ function = "normal";
++
++ bias-pull-up;
++ power-source = <PM8941_GPIO_S3>;
+ };
++};
+
+- remoteproc@fb21b000 {
+- status = "okay";
++&pronto {
++ status = "okay";
+
+- vddmx-supply = <&pm8841_s1>;
+- vddcx-supply = <&pm8841_s2>;
++ vddmx-supply = <&pm8841_s1>;
++ vddcx-supply = <&pm8841_s2>;
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&wcnss_pin_a>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&wcnss_pin_a>;
+
+- smd-edge {
+- qcom,remote-pid = <4>;
+- label = "pronto";
++ smd-edge {
++ qcom,remote-pid = <4>;
++ label = "pronto";
+
+- wcnss {
+- status = "okay";
+- };
++ wcnss {
++ status = "okay";
+ };
+ };
++};
++
++&rpm_requests {
++ pm8841-regulators {
++ pm8841_s1: s1 {
++ regulator-min-microvolt = <675000>;
++ regulator-max-microvolt = <1050000>;
++ };
+
+- pinctrl@fd510000 {
+- sdhc1_pin_a: sdhc1-pin-active {
+- clk {
+- pins = "sdc1_clk";
+- drive-strength = <16>;
+- bias-disable;
+- };
++ pm8841_s2: s2 {
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1050000>;
++ };
+
+- cmd-data {
+- pins = "sdc1_cmd", "sdc1_data";
+- drive-strength = <10>;
+- bias-pull-up;
+- };
++ pm8841_s3: s3 {
++ regulator-min-microvolt = <1050000>;
++ regulator-max-microvolt = <1050000>;
+ };
++ };
+
+- sdhc2_pin_a: sdhc2-pin-active {
+- clk {
+- pins = "sdc2_clk";
+- drive-strength = <10>;
+- bias-disable;
+- };
++ pm8941-regulators {
++ vdd_l1_l3-supply = <&pm8941_s1>;
++ vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
++ vdd_l4_l11-supply = <&pm8941_s1>;
++ vdd_l5_l7-supply = <&pm8941_s2>;
++ vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
++ vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
++ vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
++ vdd_l21-supply = <&vreg_boost>;
++
++ pm8941_s1: s1 {
++ regulator-min-microvolt = <1300000>;
++ regulator-max-microvolt = <1300000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
+
+- cmd-data {
+- pins = "sdc2_cmd", "sdc2_data";
+- drive-strength = <6>;
+- bias-pull-up;
+- };
++ pm8941_s2: s2 {
++ regulator-min-microvolt = <2150000>;
++ regulator-max-microvolt = <2150000>;
++ regulator-boot-on;
+ };
+
+- wcnss_pin_a: wcnss-pin-active {
+- wlan {
+- pins = "gpio36", "gpio37", "gpio38", "gpio39", "gpio40";
+- function = "wlan";
++ pm8941_s3: s3 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
+
+- drive-strength = <6>;
+- bias-pull-down;
+- };
++ pm8941_l1: l1 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
+
+- bt {
+- pins = "gpio35", "gpio43", "gpio44";
+- function = "bt";
++ pm8941_l2: l2 {
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
++ };
+
+- drive-strength = <2>;
+- bias-pull-down;
+- };
++ pm8941_l3: l3 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
++ };
+
+- fm {
+- pins = "gpio41", "gpio42";
+- function = "fm";
++ pm8941_l4: l4 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
++ };
+
+- drive-strength = <2>;
+- bias-pull-down;
+- };
++ pm8941_l5: l5 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
+ };
+- };
+
+- sdhci@f9824900 {
+- status = "okay";
++ pm8941_l6: l6 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
++ };
+
+- vmmc-supply = <&pm8941_l20>;
+- vqmmc-supply = <&pm8941_s3>;
++ pm8941_l7: l7 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
++ };
+
+- bus-width = <8>;
+- non-removable;
++ pm8941_l8: l8 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc1_pin_a>;
+- };
++ pm8941_l9: l9 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ };
+
+- sdhci@f98a4900 {
+- status = "okay";
++ pm8941_l10: l10 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ };
+
+- vmmc-supply = <&pm8941_l21>;
+- vqmmc-supply = <&pm8941_l13>;
++ pm8941_l11: l11 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1350000>;
++ };
+
+- bus-width = <4>;
++ pm8941_l12: l12 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc2_pin_a>;
++ pm8941_l13: l13 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-boot-on;
++ };
++
++ pm8941_l14: l14 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ pm8941_l15: l15 {
++ regulator-min-microvolt = <2050000>;
++ regulator-max-microvolt = <2050000>;
++ };
++
++ pm8941_l16: l16 {
++ regulator-min-microvolt = <2700000>;
++ regulator-max-microvolt = <2700000>;
++ };
++
++ pm8941_l17: l17 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++
++ pm8941_l18: l18 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++
++ pm8941_l19: l19 {
++ regulator-min-microvolt = <2900000>;
++ regulator-max-microvolt = <3350000>;
++ };
++
++ pm8941_l20: l20 {
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-system-load = <200000>;
++ regulator-allow-set-load;
++ regulator-boot-on;
++ };
++
++ pm8941_l21: l21 {
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-boot-on;
++ };
++
++ pm8941_l22: l22 {
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ pm8941_l23: l23 {
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3000000>;
++ };
++
++ pm8941_l24: l24 {
++ regulator-min-microvolt = <3075000>;
++ regulator-max-microvolt = <3075000>;
++ regulator-boot-on;
++ };
+ };
++};
+
+- usb@f9a55000 {
+- status = "okay";
++&sdhc_1 {
++ status = "okay";
+
+- phys = <&usb_hs1_phy>;
+- phy-select = <&tcsr 0xb000 0>;
+- extcon = <&smbb>, <&usb_id>;
+- vbus-supply = <&chg_otg>;
++ vmmc-supply = <&pm8941_l20>;
++ vqmmc-supply = <&pm8941_s3>;
+
+- hnp-disable;
+- srp-disable;
+- adp-disable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhc1_pin_a>;
++};
++
++&sdhc_2 {
++ status = "okay";
+
+- ulpi {
+- phy@a {
+- status = "okay";
++ vmmc-supply = <&pm8941_l21>;
++ vqmmc-supply = <&pm8941_l13>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhc2_pin_a>;
++};
+
+- v1p8-supply = <&pm8941_l6>;
+- v3p3-supply = <&pm8941_l24>;
++&tlmm {
++ sdhc1_pin_a: sdhc1-pin-active {
++ clk {
++ pins = "sdc1_clk";
++ drive-strength = <16>;
++ bias-disable;
++ };
+
+- extcon = <&smbb>;
+- qcom,init-seq = /bits/ 8 <0x1 0x64>;
+- };
++ cmd-data {
++ pins = "sdc1_cmd", "sdc1_data";
++ drive-strength = <10>;
++ bias-pull-up;
+ };
+ };
+
+- imem@fe805000 {
+- status = "okay";
++ sdhc2_pin_a: sdhc2-pin-active {
++ clk {
++ pins = "sdc2_clk";
++ drive-strength = <10>;
++ bias-disable;
++ };
+
+- reboot-mode {
+- mode-normal = <0x77665501>;
+- mode-bootloader = <0x77665500>;
+- mode-recovery = <0x77665502>;
++ cmd-data {
++ pins = "sdc2_cmd", "sdc2_data";
++ drive-strength = <6>;
++ bias-pull-up;
+ };
+ };
+-};
+
+-&spmi_bus {
+- pm8941@0 {
+- gpios@c000 {
+- gpio_keys_pin_a: gpio-keys-active {
+- pins = "gpio1", "gpio2", "gpio5";
+- function = "normal";
++ wcnss_pin_a: wcnss-pin-active {
++ wlan {
++ pins = "gpio36", "gpio37", "gpio38", "gpio39", "gpio40";
++ function = "wlan";
++
++ drive-strength = <6>;
++ bias-pull-down;
++ };
++
++ bt {
++ pins = "gpio35", "gpio43", "gpio44";
++ function = "bt";
++
++ drive-strength = <2>;
++ bias-pull-down;
++ };
++
++ fm {
++ pins = "gpio41", "gpio42";
++ function = "fm";
+
+- bias-pull-up;
+- power-source = <PM8941_GPIO_S3>;
+- };
++ drive-strength = <2>;
++ bias-pull-down;
+ };
+ };
+ };
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index ad05f0665035..f1278d39ff6c 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -1592,7 +1592,7 @@ dsi0_phy: dsi-phy@fd922a00 {
+ };
+ };
+
+- imem@fe805000 {
++ imem: imem@fe805000 {
+ status = "disabled";
+ compatible = "syscon", "simple-mfd";
+ reg = <0xfe805000 0x1000>;
+--
+2.35.1
+
--- /dev/null
+From ed4f33c5cbf972c123806ee72da39457379e7e20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 13:56:22 +0200
+Subject: ARM: dts: qcom-msm8974-{"hon","am"}ami: Commonize and modernize the
+ DTs
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit 5c554c2d67a8c6c43a1fb542cbc73c33ff04c344 ]
+
+Sony Xperia Z1 and Z1 compact are almost identical, and that shows in
+their DTs. Commonize the repeating parts and modernize the DTs to use
+labels.
+
+As a bonus, Z1C gains touchscreen support in this commit, as it was
+present on Z1 already.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+[bjorn: Rebased on top of Krzysztof's fixes]
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220415115633.575010-13-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../dts/qcom-msm8974-sony-xperia-amami.dts | 432 +---------------
+ .../dts/qcom-msm8974-sony-xperia-honami.dts | 479 +-----------------
+ .../dts/qcom-msm8974-sony-xperia-rhine.dtsi | 449 ++++++++++++++++
+ arch/arm/boot/dts/qcom-pm8941.dtsi | 2 +-
+ 4 files changed, 456 insertions(+), 906 deletions(-)
+ create mode 100644 arch/arm/boot/dts/qcom-msm8974-sony-xperia-rhine.dtsi
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-amami.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-amami.dts
+index 6545917dd489..68d5626bf491 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-amami.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-amami.dts
+@@ -1,435 +1,13 @@
+ // SPDX-License-Identifier: GPL-2.0
+-#include "qcom-msm8974.dtsi"
+-#include "qcom-pm8841.dtsi"
+-#include "qcom-pm8941.dtsi"
+-#include <dt-bindings/gpio/gpio.h>
+-#include <dt-bindings/input/input.h>
+-#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
++#include "qcom-msm8974-sony-xperia-rhine.dtsi"
+
+ / {
+ model = "Sony Xperia Z1 Compact";
+ compatible = "sony,xperia-amami", "qcom,msm8974";
+-
+- aliases {
+- serial0 = &blsp1_uart2;
+- };
+-
+- chosen {
+- stdout-path = "serial0:115200n8";
+- };
+-
+- gpio-keys {
+- compatible = "gpio-keys";
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&gpio_keys_pin_a>;
+-
+- volume-down {
+- label = "volume_down";
+- gpios = <&pm8941_gpios 2 GPIO_ACTIVE_LOW>;
+- linux,input-type = <1>;
+- linux,code = <KEY_VOLUMEDOWN>;
+- };
+-
+- camera-snapshot {
+- label = "camera_snapshot";
+- gpios = <&pm8941_gpios 3 GPIO_ACTIVE_LOW>;
+- linux,input-type = <1>;
+- linux,code = <KEY_CAMERA>;
+- };
+-
+- camera-focus {
+- label = "camera_focus";
+- gpios = <&pm8941_gpios 4 GPIO_ACTIVE_LOW>;
+- linux,input-type = <1>;
+- linux,code = <KEY_CAMERA_FOCUS>;
+- };
+-
+- volume-up {
+- label = "volume_up";
+- gpios = <&pm8941_gpios 5 GPIO_ACTIVE_LOW>;
+- linux,input-type = <1>;
+- linux,code = <KEY_VOLUMEUP>;
+- };
+- };
+-
+- memory@0 {
+- reg = <0 0x40000000>, <0x40000000 0x40000000>;
+- device_type = "memory";
+- };
+-
+- smd {
+- rpm {
+- rpm-requests {
+- pm8841-regulators {
+- s1 {
+- regulator-min-microvolt = <675000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- s2 {
+- regulator-min-microvolt = <500000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- s3 {
+- regulator-min-microvolt = <500000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <500000>;
+- regulator-max-microvolt = <1050000>;
+- };
+- };
+-
+- pm8941-regulators {
+- vdd_l1_l3-supply = <&pm8941_s1>;
+- vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+- vdd_l4_l11-supply = <&pm8941_s1>;
+- vdd_l5_l7-supply = <&pm8941_s2>;
+- vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
+- vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
+- vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
+- vdd_l21-supply = <&vreg_boost>;
+-
+- s1 {
+- regulator-min-microvolt = <1300000>;
+- regulator-max-microvolt = <1300000>;
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- s2 {
+- regulator-min-microvolt = <2150000>;
+- regulator-max-microvolt = <2150000>;
+- regulator-boot-on;
+- };
+-
+- s3 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <5000000>;
+- regulator-max-microvolt = <5000000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-boot-on;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-boot-on;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <1300000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-boot-on;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l19 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l20 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-allow-set-load;
+- regulator-boot-on;
+- regulator-system-load = <200000>;
+- };
+-
+- l21 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-boot-on;
+- };
+-
+- l22 {
+- regulator-min-microvolt = <3000000>;
+- regulator-max-microvolt = <3000000>;
+- };
+-
+- l23 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l24 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+-
+- regulator-boot-on;
+- };
+- };
+- };
+- };
+- };
+ };
+
+-&soc {
+- sdhci@f9824900 {
+- status = "okay";
+-
+- vmmc-supply = <&pm8941_l20>;
+- vqmmc-supply = <&pm8941_s3>;
+-
+- bus-width = <8>;
+- non-removable;
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc1_pin_a>;
+- };
+-
+- sdhci@f98a4900 {
+- status = "okay";
+-
+- bus-width = <4>;
+-
+- vmmc-supply = <&pm8941_l21>;
+- vqmmc-supply = <&pm8941_l13>;
+-
+- cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
+- };
+-
+- serial@f991e000 {
+- status = "okay";
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&blsp1_uart2_pin_a>;
+- };
+-
+-
+- pinctrl@fd510000 {
+- blsp1_uart2_pin_a: blsp1-uart2-pin-active {
+- rx {
+- pins = "gpio5";
+- function = "blsp_uart2";
+-
+- drive-strength = <2>;
+- bias-pull-up;
+- };
+-
+- tx {
+- pins = "gpio4";
+- function = "blsp_uart2";
+-
+- drive-strength = <4>;
+- bias-disable;
+- };
+- };
+-
+- i2c2_pins: i2c2 {
+- mux {
+- pins = "gpio6", "gpio7";
+- function = "blsp_i2c2";
+-
+- drive-strength = <2>;
+- bias-disable;
+- };
+- };
+-
+- sdhc1_pin_a: sdhc1-pin-active {
+- clk {
+- pins = "sdc1_clk";
+- drive-strength = <16>;
+- bias-disable;
+- };
+-
+- cmd-data {
+- pins = "sdc1_cmd", "sdc1_data";
+- drive-strength = <10>;
+- bias-pull-up;
+- };
+- };
+-
+- sdhc2_cd_pin_a: sdhc2-cd-pin-active {
+- pins = "gpio62";
+- function = "gpio";
+-
+- drive-strength = <2>;
+- bias-disable;
+- };
+-
+- sdhc2_pin_a: sdhc2-pin-active {
+- clk {
+- pins = "sdc2_clk";
+- drive-strength = <10>;
+- bias-disable;
+- };
+-
+- cmd-data {
+- pins = "sdc2_cmd", "sdc2_data";
+- drive-strength = <6>;
+- bias-pull-up;
+- };
+- };
+- };
+-
+- dma-controller@f9944000 {
+- qcom,controlled-remotely;
+- };
+-
+- usb@f9a55000 {
+- status = "okay";
+-
+- phys = <&usb_hs1_phy>;
+- phy-select = <&tcsr 0xb000 0>;
+- extcon = <&smbb>, <&usb_id>;
+- vbus-supply = <&chg_otg>;
+-
+- hnp-disable;
+- srp-disable;
+- adp-disable;
+-
+- ulpi {
+- phy@a {
+- status = "okay";
+-
+- v1p8-supply = <&pm8941_l6>;
+- v3p3-supply = <&pm8941_l24>;
+-
+- extcon = <&smbb>;
+- qcom,init-seq = /bits/ 8 <0x1 0x64>;
+- };
+- };
+- };
+-};
+-
+-&spmi_bus {
+- pm8941@0 {
+- charger@1000 {
+- qcom,fast-charge-safe-current = <1300000>;
+- qcom,fast-charge-current-limit = <1300000>;
+- qcom,dc-current-limit = <1300000>;
+- qcom,fast-charge-safe-voltage = <4400000>;
+- qcom,fast-charge-high-threshold-voltage = <4350000>;
+- qcom,fast-charge-low-threshold-voltage = <3400000>;
+- qcom,auto-recharge-threshold-voltage = <4200000>;
+- qcom,minimum-input-voltage = <4300000>;
+- };
+-
+- gpios@c000 {
+- gpio_keys_pin_a: gpio-keys-active {
+- pins = "gpio2", "gpio3", "gpio4", "gpio5";
+- function = "normal";
+-
+- bias-pull-up;
+- power-source = <PM8941_GPIO_S3>;
+- };
+- };
+-
+- coincell@2800 {
+- status = "okay";
+- qcom,rset-ohms = <2100>;
+- qcom,vset-millivolts = <3000>;
+- };
+- };
+-
+- pm8941@1 {
+- wled@d800 {
+- status = "okay";
+-
+- qcom,cs-out;
+- qcom,current-limit = <20>;
+- qcom,current-boost-limit = <805>;
+- qcom,switching-freq = <1600>;
+- qcom,ovp = <29>;
+- qcom,num-strings = <2>;
+- };
+- };
++&smbb {
++ qcom,fast-charge-safe-current = <1300000>;
++ qcom,fast-charge-current-limit = <1300000>;
++ qcom,dc-current-limit = <1300000>;
+ };
+diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
+index 313c755f590f..ea6a941d8f8c 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
+@@ -1,484 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0
+-#include "qcom-msm8974.dtsi"
+-#include "qcom-pm8841.dtsi"
+-#include "qcom-pm8941.dtsi"
+-#include <dt-bindings/gpio/gpio.h>
+-#include <dt-bindings/input/input.h>
+-#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
++#include "qcom-msm8974-sony-xperia-rhine.dtsi"
+
+ / {
+ model = "Sony Xperia Z1";
+ compatible = "sony,xperia-honami", "qcom,msm8974";
+-
+- aliases {
+- serial0 = &blsp1_uart2;
+- };
+-
+- chosen {
+- stdout-path = "serial0:115200n8";
+- };
+-
+- gpio-keys {
+- compatible = "gpio-keys";
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&gpio_keys_pin_a>;
+-
+- volume-down {
+- label = "volume_down";
+- gpios = <&pm8941_gpios 2 GPIO_ACTIVE_LOW>;
+- linux,input-type = <1>;
+- linux,code = <KEY_VOLUMEDOWN>;
+- };
+-
+- camera-snapshot {
+- label = "camera_snapshot";
+- gpios = <&pm8941_gpios 3 GPIO_ACTIVE_LOW>;
+- linux,input-type = <1>;
+- linux,code = <KEY_CAMERA>;
+- };
+-
+- camera-focus {
+- label = "camera_focus";
+- gpios = <&pm8941_gpios 4 GPIO_ACTIVE_LOW>;
+- linux,input-type = <1>;
+- linux,code = <KEY_CAMERA_FOCUS>;
+- };
+-
+- volume-up {
+- label = "volume_up";
+- gpios = <&pm8941_gpios 5 GPIO_ACTIVE_LOW>;
+- linux,input-type = <1>;
+- linux,code = <KEY_VOLUMEUP>;
+- };
+- };
+-
+- memory@0 {
+- reg = <0 0x40000000>, <0x40000000 0x40000000>;
+- device_type = "memory";
+- };
+-
+- smd {
+- rpm {
+- rpm-requests {
+- pm8841-regulators {
+- s1 {
+- regulator-min-microvolt = <675000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- s2 {
+- regulator-min-microvolt = <500000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- s3 {
+- regulator-min-microvolt = <500000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <500000>;
+- regulator-max-microvolt = <1050000>;
+- };
+- };
+-
+- pm8941-regulators {
+- vdd_l1_l3-supply = <&pm8941_s1>;
+- vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+- vdd_l4_l11-supply = <&pm8941_s1>;
+- vdd_l5_l7-supply = <&pm8941_s2>;
+- vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
+- vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
+- vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
+- vdd_l21-supply = <&vreg_boost>;
+-
+- s1 {
+- regulator-min-microvolt = <1300000>;
+- regulator-max-microvolt = <1300000>;
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- s2 {
+- regulator-min-microvolt = <2150000>;
+- regulator-max-microvolt = <2150000>;
+- regulator-boot-on;
+- };
+-
+- s3 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <5000000>;
+- regulator-max-microvolt = <5000000>;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-boot-on;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-boot-on;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <1300000>;
+- regulator-max-microvolt = <1350000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-boot-on;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l19 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l20 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-allow-set-load;
+- regulator-boot-on;
+- regulator-system-load = <200000>;
+- };
+-
+- l21 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-boot-on;
+- };
+-
+- l22 {
+- regulator-min-microvolt = <3000000>;
+- regulator-max-microvolt = <3000000>;
+- };
+-
+- l23 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2800000>;
+- };
+-
+- l24 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+-
+- regulator-boot-on;
+- };
+- };
+- };
+- };
+- };
+-};
+-
+-&soc {
+- usb@f9a55000 {
+- status = "okay";
+-
+- phys = <&usb_hs1_phy>;
+- phy-select = <&tcsr 0xb000 0>;
+- extcon = <&smbb>, <&usb_id>;
+- vbus-supply = <&chg_otg>;
+-
+- hnp-disable;
+- srp-disable;
+- adp-disable;
+-
+- ulpi {
+- phy@a {
+- status = "okay";
+-
+- v1p8-supply = <&pm8941_l6>;
+- v3p3-supply = <&pm8941_l24>;
+-
+- extcon = <&smbb>;
+- qcom,init-seq = /bits/ 8 <0x1 0x64>;
+- };
+- };
+- };
+-
+- sdhci@f9824900 {
+- status = "okay";
+-
+- vmmc-supply = <&pm8941_l20>;
+- vqmmc-supply = <&pm8941_s3>;
+-
+- bus-width = <8>;
+- non-removable;
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc1_pin_a>;
+- };
+-
+- sdhci@f98a4900 {
+- status = "okay";
+-
+- bus-width = <4>;
+-
+- vmmc-supply = <&pm8941_l21>;
+- vqmmc-supply = <&pm8941_l13>;
+-
+- cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
+- };
+-
+- serial@f991e000 {
+- status = "okay";
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&blsp1_uart2_pin_a>;
+- };
+-
+- i2c@f9924000 {
+- status = "okay";
+-
+- clock-frequency = <355000>;
+- qcom,src-freq = <50000000>;
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c2_pins>;
+-
+- synaptics@2c {
+- compatible = "syna,rmi4-i2c";
+- reg = <0x2c>;
+-
+- interrupts-extended = <&tlmm 61 IRQ_TYPE_EDGE_FALLING>;
+-
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- vdd-supply = <&pm8941_l22>;
+- vio-supply = <&pm8941_lvs3>;
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&ts_int_pin>;
+-
+- syna,startup-delay-ms = <10>;
+-
+- rmi4-f01@1 {
+- reg = <0x1>;
+- syna,nosleep-mode = <1>;
+- };
+-
+- rmi4-f11@11 {
+- reg = <0x11>;
+- touchscreen-inverted-x;
+- syna,sensor-type = <1>;
+- };
+- };
+- };
+-
+- pinctrl@fd510000 {
+- blsp1_uart2_pin_a: blsp1-uart2-pin-active {
+- rx {
+- pins = "gpio5";
+- function = "blsp_uart2";
+-
+- drive-strength = <2>;
+- bias-pull-up;
+- };
+-
+- tx {
+- pins = "gpio4";
+- function = "blsp_uart2";
+-
+- drive-strength = <4>;
+- bias-disable;
+- };
+- };
+-
+- i2c2_pins: i2c2 {
+- mux {
+- pins = "gpio6", "gpio7";
+- function = "blsp_i2c2";
+-
+- drive-strength = <2>;
+- bias-disable;
+- };
+- };
+-
+- sdhc1_pin_a: sdhc1-pin-active {
+- clk {
+- pins = "sdc1_clk";
+- drive-strength = <16>;
+- bias-disable;
+- };
+-
+- cmd-data {
+- pins = "sdc1_cmd", "sdc1_data";
+- drive-strength = <10>;
+- bias-pull-up;
+- };
+- };
+-
+- sdhc2_cd_pin_a: sdhc2-cd-pin-active {
+- pins = "gpio62";
+- function = "gpio";
+-
+- drive-strength = <2>;
+- bias-disable;
+- };
+-
+- sdhc2_pin_a: sdhc2-pin-active {
+- clk {
+- pins = "sdc2_clk";
+- drive-strength = <10>;
+- bias-disable;
+- };
+-
+- cmd-data {
+- pins = "sdc2_cmd", "sdc2_data";
+- drive-strength = <6>;
+- bias-pull-up;
+- };
+- };
+-
+- ts_int_pin: touch-int {
+- pin {
+- pins = "gpio61";
+- function = "gpio";
+-
+- drive-strength = <2>;
+- bias-disable;
+- input-enable;
+- };
+- };
+- };
+-
+- dma-controller@f9944000 {
+- qcom,controlled-remotely;
+- };
+-};
+-
+-&spmi_bus {
+- pm8941@0 {
+- charger@1000 {
+- qcom,fast-charge-safe-current = <1500000>;
+- qcom,fast-charge-current-limit = <1500000>;
+- qcom,dc-current-limit = <1800000>;
+- qcom,fast-charge-safe-voltage = <4400000>;
+- qcom,fast-charge-high-threshold-voltage = <4350000>;
+- qcom,fast-charge-low-threshold-voltage = <3400000>;
+- qcom,auto-recharge-threshold-voltage = <4200000>;
+- qcom,minimum-input-voltage = <4300000>;
+- };
+-
+- gpios@c000 {
+- gpio_keys_pin_a: gpio-keys-active {
+- pins = "gpio2", "gpio3", "gpio4", "gpio5";
+- function = "normal";
+-
+- bias-pull-up;
+- power-source = <PM8941_GPIO_S3>;
+- };
+- };
+-
+- coincell@2800 {
+- status = "okay";
+- qcom,rset-ohms = <2100>;
+- qcom,vset-millivolts = <3000>;
+- };
+- };
+-
+- pm8941@1 {
+- wled@d800 {
+- status = "okay";
+-
+- qcom,cs-out;
+- qcom,current-limit = <20>;
+- qcom,current-boost-limit = <805>;
+- qcom,switching-freq = <1600>;
+- qcom,ovp = <29>;
+- qcom,num-strings = <2>;
+- };
+- };
+ };
+diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-rhine.dtsi b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-rhine.dtsi
+new file mode 100644
+index 000000000000..87ec3694add9
+--- /dev/null
++++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-rhine.dtsi
+@@ -0,0 +1,449 @@
++// SPDX-License-Identifier: GPL-2.0
++#include "qcom-msm8974.dtsi"
++#include "qcom-pm8841.dtsi"
++#include "qcom-pm8941.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
++#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
++
++/ {
++ aliases {
++ serial0 = &blsp1_uart2;
++ };
++
++ chosen {
++ stdout-path = "serial0:115200n8";
++ };
++
++ gpio-keys {
++ compatible = "gpio-keys";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&gpio_keys_pin_a>;
++
++ volume-down {
++ label = "volume_down";
++ gpios = <&pm8941_gpios 2 GPIO_ACTIVE_LOW>;
++ linux,input-type = <1>;
++ linux,code = <KEY_VOLUMEDOWN>;
++ };
++
++ camera-snapshot {
++ label = "camera_snapshot";
++ gpios = <&pm8941_gpios 3 GPIO_ACTIVE_LOW>;
++ linux,input-type = <1>;
++ linux,code = <KEY_CAMERA>;
++ };
++
++ camera-focus {
++ label = "camera_focus";
++ gpios = <&pm8941_gpios 4 GPIO_ACTIVE_LOW>;
++ linux,input-type = <1>;
++ linux,code = <KEY_CAMERA_FOCUS>;
++ };
++
++ volume-up {
++ label = "volume_up";
++ gpios = <&pm8941_gpios 5 GPIO_ACTIVE_LOW>;
++ linux,input-type = <1>;
++ linux,code = <KEY_VOLUMEUP>;
++ };
++ };
++};
++
++&blsp1_i2c2 {
++ status = "okay";
++ clock-frequency = <355000>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c2_pins>;
++
++ synaptics@2c {
++ compatible = "syna,rmi4-i2c";
++ reg = <0x2c>;
++
++ interrupts-extended = <&tlmm 61 IRQ_TYPE_EDGE_FALLING>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ vdd-supply = <&pm8941_l22>;
++ vio-supply = <&pm8941_lvs3>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&ts_int_pin>;
++
++ syna,startup-delay-ms = <10>;
++
++ rmi4-f01@1 {
++ reg = <0x1>;
++ syna,nosleep-mode = <1>;
++ };
++
++ rmi4-f11@11 {
++ reg = <0x11>;
++ touchscreen-inverted-x;
++ syna,sensor-type = <1>;
++ };
++ };
++};
++
++&blsp1_uart2 {
++ status = "okay";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&blsp1_uart2_pin_a>;
++};
++
++&blsp2_dma {
++ qcom,controlled-remotely;
++};
++
++&otg {
++ status = "okay";
++
++ phys = <&usb_hs1_phy>;
++ phy-select = <&tcsr 0xb000 0>;
++ extcon = <&smbb>, <&usb_id>;
++ vbus-supply = <&chg_otg>;
++
++ hnp-disable;
++ srp-disable;
++ adp-disable;
++
++ ulpi {
++ phy@a {
++ status = "okay";
++
++ v1p8-supply = <&pm8941_l6>;
++ v3p3-supply = <&pm8941_l24>;
++
++ extcon = <&smbb>;
++ qcom,init-seq = /bits/ 8 <0x1 0x64>;
++ };
++ };
++};
++
++&pm8941_coincell {
++ status = "okay";
++ qcom,rset-ohms = <2100>;
++ qcom,vset-millivolts = <3000>;
++};
++
++&pm8941_gpios {
++ gpio_keys_pin_a: gpio-keys-active {
++ pins = "gpio2", "gpio3", "gpio4", "gpio5";
++ function = "normal";
++
++ bias-pull-up;
++ power-source = <PM8941_GPIO_S3>;
++ };
++};
++
++&pm8941_wled {
++ status = "okay";
++
++ qcom,cs-out;
++ qcom,current-limit = <20>;
++ qcom,current-boost-limit = <805>;
++ qcom,switching-freq = <1600>;
++ qcom,ovp = <29>;
++ qcom,num-strings = <2>;
++};
++
++&rpm_requests {
++ pm8841-regulators {
++ pm8841_s1: s1 {
++ regulator-min-microvolt = <675000>;
++ regulator-max-microvolt = <1050000>;
++ };
++
++ pm8841_s2: s2 {
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1050000>;
++ };
++
++ pm8841_s3: s3 {
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1050000>;
++ };
++
++ pm8841_s4: s4 {
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1050000>;
++ };
++ };
++
++ pm8941-regulators {
++ vdd_l1_l3-supply = <&pm8941_s1>;
++ vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
++ vdd_l4_l11-supply = <&pm8941_s1>;
++ vdd_l5_l7-supply = <&pm8941_s2>;
++ vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
++ vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
++ vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
++ vdd_l21-supply = <&vreg_boost>;
++
++ pm8941_s1: s1 {
++ regulator-min-microvolt = <1300000>;
++ regulator-max-microvolt = <1300000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ pm8941_s2: s2 {
++ regulator-min-microvolt = <2150000>;
++ regulator-max-microvolt = <2150000>;
++ regulator-boot-on;
++ };
++
++ pm8941_s3: s3 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ pm8941_s4: s4 {
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ };
++
++ pm8941_l1: l1 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ pm8941_l2: l2 {
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
++ };
++
++ pm8941_l3: l3 {
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
++ };
++
++ pm8941_l4: l4 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
++ };
++
++ pm8941_l5: l5 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ pm8941_l6: l6 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
++ };
++
++ pm8941_l7: l7 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
++ };
++
++ pm8941_l8: l8 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ pm8941_l9: l9 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ };
++
++ pm8941_l11: l11 {
++ regulator-min-microvolt = <1300000>;
++ regulator-max-microvolt = <1350000>;
++ };
++
++ pm8941_l12: l12 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ pm8941_l13: l13 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-boot-on;
++ };
++
++ pm8941_l14: l14 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ pm8941_l15: l15 {
++ regulator-min-microvolt = <2050000>;
++ regulator-max-microvolt = <2050000>;
++ };
++
++ pm8941_l16: l16 {
++ regulator-min-microvolt = <2700000>;
++ regulator-max-microvolt = <2700000>;
++ };
++
++ pm8941_l17: l17 {
++ regulator-min-microvolt = <2700000>;
++ regulator-max-microvolt = <2700000>;
++ };
++
++ pm8941_l18: l18 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++
++ pm8941_l19: l19 {
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ pm8941_l20: l20 {
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-system-load = <200000>;
++ regulator-allow-set-load;
++ regulator-boot-on;
++ };
++
++ pm8941_l21: l21 {
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-boot-on;
++ };
++
++ pm8941_l22: l22 {
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3000000>;
++ };
++
++ pm8941_l23: l23 {
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ };
++
++ pm8941_l24: l24 {
++ regulator-min-microvolt = <3075000>;
++ regulator-max-microvolt = <3075000>;
++ regulator-boot-on;
++ };
++ };
++};
++
++&sdhc_1 {
++ status = "okay";
++
++ vmmc-supply = <&pm8941_l20>;
++ vqmmc-supply = <&pm8941_s3>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhc1_pin_a>;
++};
++
++&sdhc_2 {
++ status = "okay";
++
++ vmmc-supply = <&pm8941_l21>;
++ vqmmc-supply = <&pm8941_l13>;
++
++ cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
++};
++
++&smbb {
++ qcom,fast-charge-safe-current = <1500000>;
++ qcom,fast-charge-current-limit = <1500000>;
++ qcom,dc-current-limit = <1800000>;
++ qcom,fast-charge-safe-voltage = <4400000>;
++ qcom,fast-charge-high-threshold-voltage = <4350000>;
++ qcom,fast-charge-low-threshold-voltage = <3400000>;
++ qcom,auto-recharge-threshold-voltage = <4200000>;
++ qcom,minimum-input-voltage = <4300000>;
++};
++
++&tlmm {
++ ts_int_pin: touch-int {
++ pin {
++ pins = "gpio61";
++ function = "gpio";
++
++ drive-strength = <2>;
++ bias-disable;
++ input-enable;
++ };
++ };
++
++ blsp1_uart2_pin_a: blsp1-uart2-pin-active {
++ rx {
++ pins = "gpio5";
++ function = "blsp_uart2";
++
++ drive-strength = <2>;
++ bias-pull-up;
++ };
++
++ tx {
++ pins = "gpio4";
++ function = "blsp_uart2";
++
++ drive-strength = <4>;
++ bias-disable;
++ };
++ };
++
++ i2c2_pins: i2c2 {
++ mux {
++ pins = "gpio6", "gpio7";
++ function = "blsp_i2c2";
++
++ drive-strength = <2>;
++ bias-disable;
++ };
++ };
++
++ sdhc1_pin_a: sdhc1-pin-active {
++ clk {
++ pins = "sdc1_clk";
++ drive-strength = <16>;
++ bias-disable;
++ };
++
++ cmd-data {
++ pins = "sdc1_cmd", "sdc1_data";
++ drive-strength = <10>;
++ bias-pull-up;
++ };
++ };
++
++ sdhc2_cd_pin_a: sdhc2-cd-pin-active {
++ pins = "gpio62";
++ function = "gpio";
++
++ drive-strength = <2>;
++ bias-disable;
++ };
++
++ sdhc2_pin_a: sdhc2-pin-active {
++ clk {
++ pins = "sdc2_clk";
++ drive-strength = <10>;
++ bias-disable;
++ };
++
++ cmd-data {
++ pins = "sdc2_cmd", "sdc2_data";
++ drive-strength = <6>;
++ bias-pull-up;
++ };
++ };
++};
+diff --git a/arch/arm/boot/dts/qcom-pm8941.dtsi b/arch/arm/boot/dts/qcom-pm8941.dtsi
+index da00b8f5eecd..cdd2bdb77b32 100644
+--- a/arch/arm/boot/dts/qcom-pm8941.dtsi
++++ b/arch/arm/boot/dts/qcom-pm8941.dtsi
+@@ -131,7 +131,7 @@ pm8941_iadc: iadc@3600 {
+ qcom,external-resistor-micro-ohms = <10000>;
+ };
+
+- coincell@2800 {
++ pm8941_coincell: coincell@2800 {
+ compatible = "qcom,pm8941-coincell";
+ reg = <0x2800>;
+ status = "disabled";
+--
+2.35.1
+
--- /dev/null
+From 3c2f727b56a7ecb259f5823ba38fd7e4809fa546 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 13:56:21 +0200
+Subject: ARM: dts: qcom-msm8974-klte: Use &labels
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit 1d59524b9181e17110ae7b809c62a6a66f336fd6 ]
+
+Use &labels to align with the style used in new DTS and apply tiny
+style fixes.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+[bjorn: Rebased on top of Krzysztof's fixes]
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220415115633.575010-12-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/qcom-msm8974-samsung-klte.dts | 1202 ++++++++---------
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 4 +-
+ 2 files changed, 585 insertions(+), 621 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+index 60244e0c37ba..3b1ea8c24f57 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+@@ -13,7 +13,7 @@ / {
+ aliases {
+ serial0 = &blsp1_uart1;
+ mmc0 = &sdhc_1; /* SDC1 eMMC slot */
+- mmc1 = &sdhc_2; /* SDC2 SD card slot */
++ mmc1 = &sdhc_3; /* SDC2 SD card slot */
+ };
+
+ chosen {
+@@ -52,197 +52,6 @@ volume-up {
+ };
+ };
+
+- smd {
+- rpm {
+- rpm-requests {
+- pma8084-regulators {
+- compatible = "qcom,rpm-pma8084-regulators";
+- status = "okay";
+-
+- pma8084_s1: s1 {
+- regulator-min-microvolt = <675000>;
+- regulator-max-microvolt = <1050000>;
+- regulator-always-on;
+- };
+-
+- pma8084_s2: s2 {
+- regulator-min-microvolt = <500000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- pma8084_s3: s3 {
+- regulator-min-microvolt = <1300000>;
+- regulator-max-microvolt = <1300000>;
+- };
+-
+- pma8084_s4: s4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- pma8084_s5: s5 {
+- regulator-min-microvolt = <2150000>;
+- regulator-max-microvolt = <2150000>;
+- };
+-
+- pma8084_s6: s6 {
+- regulator-min-microvolt = <1050000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- pma8084_l1: l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- pma8084_l2: l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- pma8084_l3: l3 {
+- regulator-min-microvolt = <1050000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- pma8084_l4: l4 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- pma8084_l5: l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- pma8084_l6: l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- pma8084_l7: l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- pma8084_l8: l8 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- pma8084_l9: l9 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- pma8084_l10: l10 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- pma8084_l11: l11 {
+- regulator-min-microvolt = <1300000>;
+- regulator-max-microvolt = <1300000>;
+- };
+-
+- pma8084_l12: l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- regulator-always-on;
+- };
+-
+- pma8084_l13: l13 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- pma8084_l14: l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- pma8084_l15: l15 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- pma8084_l16: l16 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-
+- pma8084_l17: l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- pma8084_l18: l18 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- pma8084_l19: l19 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- pma8084_l20: l20 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-allow-set-load;
+- regulator-system-load = <200000>;
+- };
+-
+- pma8084_l21: l21 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-allow-set-load;
+- regulator-system-load = <200000>;
+- };
+-
+- pma8084_l22: l22 {
+- regulator-min-microvolt = <3000000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- pma8084_l23: l23 {
+- regulator-min-microvolt = <3000000>;
+- regulator-max-microvolt = <3000000>;
+- };
+-
+- pma8084_l24: l24 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+- };
+-
+- pma8084_l25: l25 {
+- regulator-min-microvolt = <2100000>;
+- regulator-max-microvolt = <2100000>;
+- };
+-
+- pma8084_l26: l26 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- pma8084_l27: l27 {
+- regulator-min-microvolt = <1000000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- pma8084_lvs1: lvs1 {};
+- pma8084_lvs2: lvs2 {};
+- pma8084_lvs3: lvs3 {};
+- pma8084_lvs4: lvs4 {};
+-
+- pma8084_5vs1: 5vs1 {};
+- };
+- };
+- };
+- };
+-
+ i2c-gpio-touchkey {
+ compatible = "i2c-gpio";
+ #address-cells = <1>;
+@@ -347,562 +156,717 @@ vreg_panel: panel-regulator {
+ };
+
+ /delete-node/ vreg-boost;
+-
+- adsp-pil {
+- cx-supply = <&pma8084_s2>;
+- };
+ };
+
+-&soc {
+- serial@f991e000 {
+- status = "okay";
+- };
++&blsp1_i2c2 {
++ status = "okay";
+
+- /* blsp2_uart2 */
+- serial@f995e000 {
+- status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c2_pins>;
+
+- pinctrl-names = "default", "sleep";
+- pinctrl-0 = <&blsp2_uart2_pins_active>;
+- pinctrl-1 = <&blsp2_uart2_pins_sleep>;
++ touchscreen@20 {
++ compatible = "syna,rmi4-i2c";
++ reg = <0x20>;
+
+- bluetooth {
+- compatible = "brcm,bcm43540-bt";
+- max-speed = <3000000>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&bt_pins>;
+- device-wakeup-gpios = <&tlmm 91 GPIO_ACTIVE_HIGH>;
+- shutdown-gpios = <&gpio_expander 9 GPIO_ACTIVE_HIGH>;
+- interrupt-parent = <&tlmm>;
+- interrupts = <75 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "host-wakeup";
+- };
+- };
++ interrupt-parent = <&pma8084_gpios>;
++ interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
+
+- pinctrl@fd510000 {
+- blsp2_uart2_pins_active: blsp2-uart2-pins-active {
+- pins = "gpio45", "gpio46", "gpio47", "gpio48";
+- function = "blsp_uart8";
+- drive-strength = <8>;
+- bias-disable;
++ vdd-supply = <&max77826_ldo13>;
++ vio-supply = <&pma8084_lvs2>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&touch_pin>;
++
++ syna,startup-delay-ms = <100>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ rmi4-f01@1 {
++ reg = <0x1>;
++ syna,nosleep-mode = <1>;
+ };
+
+- blsp2_uart2_pins_sleep: blsp2-uart2-pins-sleep {
+- pins = "gpio45", "gpio46", "gpio47", "gpio48";
+- function = "gpio";
+- drive-strength = <2>;
+- bias-pull-down;
++ rmi4-f12@12 {
++ reg = <0x12>;
++ syna,sensor-type = <1>;
+ };
++ };
++};
++
++&blsp1_i2c6 {
++ status = "okay";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c6_pins>;
+
+- bt_pins: bt-pins {
+- hostwake {
+- pins = "gpio75";
+- function = "gpio";
+- drive-strength = <16>;
+- input-enable;
++ pmic@60 {
++ reg = <0x60>;
++ compatible = "maxim,max77826";
++
++ regulators {
++ max77826_ldo1: LDO1 {
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
+ };
+
+- devwake {
+- pins = "gpio91";
+- function = "gpio";
+- drive-strength = <2>;
++ max77826_ldo2: LDO2 {
++ regulator-min-microvolt = <1000000>;
++ regulator-max-microvolt = <1000000>;
+ };
+- };
+
+- sdhc1_pin_a: sdhc1-pin-active {
+- clk {
+- pins = "sdc1_clk";
+- drive-strength = <4>;
+- bias-disable;
++ max77826_ldo3: LDO3 {
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
+ };
+
+- cmd-data {
+- pins = "sdc1_cmd", "sdc1_data";
+- drive-strength = <4>;
+- bias-pull-up;
++ max77826_ldo4: LDO4 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
+ };
+- };
+
+- sdhc2_pin_a: sdhc2-pin-active {
+- clk-cmd-data {
+- pins = "gpio35", "gpio36", "gpio37", "gpio38",
+- "gpio39", "gpio40";
+- function = "sdc3";
+- drive-strength = <8>;
+- bias-disable;
++ max77826_ldo5: LDO5 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
+ };
+- };
+
+- sdhc2_cd_pin: sdhc2-cd {
+- pins = "gpio62";
+- function = "gpio";
++ max77826_ldo6: LDO6 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++ };
+
+- drive-strength = <2>;
+- bias-disable;
+- };
++ max77826_ldo7: LDO7 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
+
+- sdhc3_pin_a: sdhc3-pin-active {
+- clk {
+- pins = "sdc2_clk";
+- drive-strength = <6>;
+- bias-disable;
++ max77826_ldo8: LDO8 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
+ };
+
+- cmd-data {
+- pins = "sdc2_cmd", "sdc2_data";
+- drive-strength = <6>;
+- bias-pull-up;
++ max77826_ldo9: LDO9 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
+ };
+- };
+
+- i2c2_pins: i2c2 {
+- mux {
+- pins = "gpio6", "gpio7";
+- function = "blsp_i2c2";
++ max77826_ldo10: LDO10 {
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2950000>;
++ };
+
+- drive-strength = <2>;
+- bias-disable;
++ max77826_ldo11: LDO11 {
++ regulator-min-microvolt = <2700000>;
++ regulator-max-microvolt = <2950000>;
+ };
+- };
+
+- i2c6_pins: i2c6 {
+- mux {
+- pins = "gpio29", "gpio30";
+- function = "blsp_i2c6";
++ max77826_ldo12: LDO12 {
++ regulator-min-microvolt = <2500000>;
++ regulator-max-microvolt = <3300000>;
++ };
+
+- drive-strength = <2>;
+- bias-disable;
++ max77826_ldo13: LDO13 {
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
+ };
+- };
+
+- i2c12_pins: i2c12 {
+- mux {
+- pins = "gpio87", "gpio88";
+- function = "blsp_i2c12";
++ max77826_ldo14: LDO14 {
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
+
+- drive-strength = <2>;
+- bias-disable;
++ max77826_ldo15: LDO15 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
+ };
+- };
+
+- i2c_touchkey_pins: i2c-touchkey {
+- mux {
+- pins = "gpio95", "gpio96";
+- function = "gpio";
+- input-enable;
+- bias-pull-up;
++ max77826_buck: BUCK {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
+ };
+- };
+
+- i2c_led_gpioex_pins: i2c-led-gpioex {
+- mux {
+- pins = "gpio120", "gpio121";
+- function = "gpio";
+- input-enable;
+- bias-pull-down;
++ max77826_buckboost: BUCKBOOST {
++ regulator-min-microvolt = <3400000>;
++ regulator-max-microvolt = <3400000>;
+ };
+ };
++ };
++};
+
+- gpioex_pin: gpioex {
+- res {
+- pins = "gpio145";
+- function = "gpio";
++&blsp1_uart2 {
++ status = "okay";
++};
+
+- bias-pull-up;
+- drive-strength = <2>;
+- };
+- };
++&blsp2_i2c6 {
++ status = "okay";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c12_pins>;
++
++ fuelgauge@36 {
++ compatible = "maxim,max17048";
++ reg = <0x36>;
++
++ maxim,double-soc;
++ maxim,rcomp = /bits/ 8 <0x56>;
++
++ interrupt-parent = <&pma8084_gpios>;
++ interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&fuelgauge_pin>;
++ };
++};
+
+- wifi_pin: wifi {
+- int {
+- pins = "gpio92";
+- function = "gpio";
++&blsp2_uart2 {
++ status = "okay";
+
+- input-enable;
+- bias-pull-down;
++ pinctrl-names = "default", "sleep";
++ pinctrl-0 = <&blsp2_uart2_pins_active>;
++ pinctrl-1 = <&blsp2_uart2_pins_sleep>;
++
++ bluetooth {
++ compatible = "brcm,bcm43540-bt";
++ max-speed = <3000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&bt_pins>;
++ device-wakeup-gpios = <&tlmm 91 GPIO_ACTIVE_HIGH>;
++ shutdown-gpios = <&gpio_expander 9 GPIO_ACTIVE_HIGH>;
++ interrupt-parent = <&tlmm>;
++ interrupts = <75 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "host-wakeup";
++ };
++};
++
++&dsi0 {
++ status = "okay";
++
++ vdda-supply = <&pma8084_l2>;
++ vdd-supply = <&pma8084_l22>;
++ vddio-supply = <&pma8084_l12>;
++
++ panel: panel@0 {
++ reg = <0>;
++ compatible = "samsung,s6e3fa2";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&panel_te_pin &panel_rst_pin>;
++
++ iovdd-supply = <&pma8084_lvs4>;
++ vddr-supply = <&vreg_panel>;
++
++ reset-gpios = <&pma8084_gpios 17 GPIO_ACTIVE_LOW>;
++ te-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
++
++ port {
++ panel_in: endpoint {
++ remote-endpoint = <&dsi0_out>;
+ };
+ };
++ };
++};
+
+- panel_te_pin: panel {
+- te {
+- pins = "gpio12";
+- function = "mdp_vsync";
++&dsi0_out {
++ remote-endpoint = <&panel_in>;
++ data-lanes = <0 1 2 3>;
++};
+
+- drive-strength = <2>;
+- bias-disable;
+- };
++&dsi0_phy {
++ status = "okay";
++
++ vddio-supply = <&pma8084_l12>;
++};
++
++&gpu {
++ status = "okay";
++};
++
++&mdss {
++ status = "okay";
++};
++
++&otg {
++ status = "okay";
++
++ phys = <&usb_hs1_phy>;
++ phy-select = <&tcsr 0xb000 0>;
++
++ hnp-disable;
++ srp-disable;
++ adp-disable;
++
++ ulpi {
++ phy@a {
++ status = "okay";
++
++ v1p8-supply = <&pma8084_l6>;
++ v3p3-supply = <&pma8084_l24>;
++
++ qcom,init-seq = /bits/ 8 <0x1 0x64>;
+ };
+ };
++};
+
+- sdhci@f9824900 {
+- status = "okay";
++&pma8084_gpios {
++ gpio_keys_pin_a: gpio-keys-active {
++ pins = "gpio2", "gpio3", "gpio5";
++ function = "normal";
+
+- vmmc-supply = <&pma8084_l20>;
+- vqmmc-supply = <&pma8084_s4>;
++ bias-pull-up;
++ power-source = <PMA8084_GPIO_S4>;
++ };
+
+- bus-width = <8>;
+- non-removable;
++ touchkey_pin: touchkey-int-pin {
++ pins = "gpio6";
++ function = "normal";
++ bias-disable;
++ input-enable;
++ power-source = <PMA8084_GPIO_S4>;
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc1_pin_a>;
++ touch_pin: touchscreen-int-pin {
++ pins = "gpio8";
++ function = "normal";
++ bias-disable;
++ input-enable;
++ power-source = <PMA8084_GPIO_S4>;
+ };
+
+- sdhci@f9864900 {
+- status = "okay";
++ panel_en_pin: panel-en-pin {
++ pins = "gpio14";
++ function = "normal";
++ bias-pull-up;
++ power-source = <PMA8084_GPIO_S4>;
++ qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
++ };
+
+- max-frequency = <100000000>;
++ wlan_sleep_clk_pin: wlan-sleep-clk-pin {
++ pins = "gpio16";
++ function = "func2";
+
+- vmmc-supply = <&pma8084_l21>;
+- vqmmc-supply = <&pma8084_l13>;
++ output-high;
++ power-source = <PMA8084_GPIO_S4>;
++ qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
++ };
+
+- bus-width = <4>;
++ panel_rst_pin: panel-rst-pin {
++ pins = "gpio17";
++ function = "normal";
++ bias-disable;
++ power-source = <PMA8084_GPIO_S4>;
++ qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
++ };
+
+- /* cd-gpio is intentionally disabled. If enabled, an SD card
+- * present during boot is not initialized correctly. Without
+- * cd-gpios the driver resorts to polling, so hotplug works.
+- */
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc2_pin_a /* &sdhc2_cd_pin */>;
+- // cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
++ fuelgauge_pin: fuelgauge-int-pin {
++ pins = "gpio21";
++ function = "normal";
++ bias-disable;
++ input-enable;
++ power-source = <PMA8084_GPIO_S4>;
+ };
++};
+
+- sdhci@f98a4900 {
+- status = "okay";
++&remoteproc_adsp {
++ cx-supply = <&pma8084_s2>;
++};
+
+- #address-cells = <1>;
+- #size-cells = <0>;
++&remoteproc_mss {
++ cx-supply = <&pma8084_s2>;
++ mss-supply = <&pma8084_s6>;
++ mx-supply = <&pma8084_s1>;
++ pll-supply = <&pma8084_l12>;
++};
+
+- max-frequency = <100000000>;
++&rpm_requests {
++ pma8084-regulators {
++ compatible = "qcom,rpm-pma8084-regulators";
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc3_pin_a>;
++ pma8084_s1: s1 {
++ regulator-min-microvolt = <675000>;
++ regulator-max-microvolt = <1050000>;
++ regulator-always-on;
++ };
+
+- vmmc-supply = <&vreg_wlan>;
+- vqmmc-supply = <&pma8084_s4>;
++ pma8084_s2: s2 {
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1050000>;
++ };
+
+- bus-width = <4>;
+- non-removable;
++ pma8084_s3: s3 {
++ regulator-min-microvolt = <1300000>;
++ regulator-max-microvolt = <1300000>;
++ };
+
+- wifi@1 {
+- reg = <1>;
+- compatible = "brcm,bcm4329-fmac";
++ pma8084_s4: s4 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
+
+- interrupt-parent = <&tlmm>;
+- interrupts = <92 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "host-wake";
++ pma8084_s5: s5 {
++ regulator-min-microvolt = <2150000>;
++ regulator-max-microvolt = <2150000>;
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&wlan_sleep_clk_pin &wifi_pin>;
++ pma8084_s6: s6 {
++ regulator-min-microvolt = <1050000>;
++ regulator-max-microvolt = <1050000>;
+ };
+- };
+
+- usb@f9a55000 {
+- status = "okay";
++ pma8084_l1: l1 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
++ };
+
+- phys = <&usb_hs1_phy>;
+- phy-select = <&tcsr 0xb000 0>;
+- /*extcon = <&smbb>, <&usb_id>;*/
+- /*vbus-supply = <&chg_otg>;*/
++ pma8084_l2: l2 {
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
++ };
+
+- hnp-disable;
+- srp-disable;
+- adp-disable;
++ pma8084_l3: l3 {
++ regulator-min-microvolt = <1050000>;
++ regulator-max-microvolt = <1200000>;
++ };
+
+- ulpi {
+- phy@a {
+- status = "okay";
++ pma8084_l4: l4 {
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1225000>;
++ };
+
+- v1p8-supply = <&pma8084_l6>;
+- v3p3-supply = <&pma8084_l24>;
++ pma8084_l5: l5 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
+
+- /*extcon = <&smbb>;*/
+- qcom,init-seq = /bits/ 8 <0x1 0x64>;
+- };
++ pma8084_l6: l6 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
+ };
+- };
+
+- i2c@f9924000 {
+- status = "okay";
++ pma8084_l7: l7 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c2_pins>;
++ pma8084_l8: l8 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
+
+- touchscreen@20 {
+- compatible = "syna,rmi4-i2c";
+- reg = <0x20>;
++ pma8084_l9: l9 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ };
+
+- interrupt-parent = <&pma8084_gpios>;
+- interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
++ pma8084_l10: l10 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ };
+
+- vdd-supply = <&max77826_ldo13>;
+- vio-supply = <&pma8084_lvs2>;
++ pma8084_l11: l11 {
++ regulator-min-microvolt = <1300000>;
++ regulator-max-microvolt = <1300000>;
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&touch_pin>;
++ pma8084_l12: l12 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ };
+
+- syna,startup-delay-ms = <100>;
++ pma8084_l13: l13 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ };
+
+- #address-cells = <1>;
+- #size-cells = <0>;
++ pma8084_l14: l14 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
+
+- rmi4-f01@1 {
+- reg = <0x1>;
+- syna,nosleep-mode = <1>;
+- };
++ pma8084_l15: l15 {
++ regulator-min-microvolt = <2050000>;
++ regulator-max-microvolt = <2050000>;
++ };
+
+- rmi4-f12@12 {
+- reg = <0x12>;
+- syna,sensor-type = <1>;
+- };
++ pma8084_l16: l16 {
++ regulator-min-microvolt = <2700000>;
++ regulator-max-microvolt = <2700000>;
+ };
+- };
+
+- i2c@f9928000 {
+- status = "okay";
++ pma8084_l17: l17 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c6_pins>;
+-
+- pmic@60 {
+- reg = <0x60>;
+- compatible = "maxim,max77826";
+-
+- regulators {
+- max77826_ldo1: LDO1 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- max77826_ldo2: LDO2 {
+- regulator-min-microvolt = <1000000>;
+- regulator-max-microvolt = <1000000>;
+- };
+-
+- max77826_ldo3: LDO3 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- max77826_ldo4: LDO4 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- max77826_ldo5: LDO5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- max77826_ldo6: LDO6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- max77826_ldo7: LDO7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- max77826_ldo8: LDO8 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- max77826_ldo9: LDO9 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- max77826_ldo10: LDO10 {
+- regulator-min-microvolt = <2800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- max77826_ldo11: LDO11 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- max77826_ldo12: LDO12 {
+- regulator-min-microvolt = <2500000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- max77826_ldo13: LDO13 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- max77826_ldo14: LDO14 {
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- max77826_ldo15: LDO15 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- max77826_buck: BUCK {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- max77826_buckboost: BUCKBOOST {
+- regulator-min-microvolt = <3400000>;
+- regulator-max-microvolt = <3400000>;
+- };
+- };
++ pma8084_l18: l18 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
+ };
+- };
+
+- i2c@f9968000 {
+- status = "okay";
++ pma8084_l19: l19 {
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c12_pins>;
++ pma8084_l20: l20 {
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-system-load = <200000>;
++ regulator-allow-set-load;
++ };
+
+- fuelgauge@36 {
+- compatible = "maxim,max17048";
+- reg = <0x36>;
++ pma8084_l21: l21 {
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-system-load = <200000>;
++ regulator-allow-set-load;
++ };
+
+- maxim,double-soc;
+- maxim,rcomp = /bits/ 8 <0x56>;
++ pma8084_l22: l22 {
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3300000>;
++ };
+
+- interrupt-parent = <&pma8084_gpios>;
+- interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
++ pma8084_l23: l23 {
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3000000>;
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&fuelgauge_pin>;
++ pma8084_l24: l24 {
++ regulator-min-microvolt = <3075000>;
++ regulator-max-microvolt = <3075000>;
+ };
++
++ pma8084_l25: l25 {
++ regulator-min-microvolt = <2100000>;
++ regulator-max-microvolt = <2100000>;
++ };
++
++ pma8084_l26: l26 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2050000>;
++ };
++
++ pma8084_l27: l27 {
++ regulator-min-microvolt = <1000000>;
++ regulator-max-microvolt = <1225000>;
++ };
++
++ pma8084_lvs1: lvs1 {};
++ pma8084_lvs2: lvs2 {};
++ pma8084_lvs3: lvs3 {};
++ pma8084_lvs4: lvs4 {};
++
++ pma8084_5vs1: 5vs1 {};
+ };
++};
++
++&sdhc_1 {
++ status = "okay";
++
++ vmmc-supply = <&pma8084_l20>;
++ vqmmc-supply = <&pma8084_s4>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhc1_pin_a>;
++};
++
++&sdhc_2 {
++ status = "okay";
++ max-frequency = <100000000>;
+
+- adreno@fdb00000 {
+- status = "ok";
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhc3_pin_a>;
++
++ vmmc-supply = <&vreg_wlan>;
++ vqmmc-supply = <&pma8084_s4>;
++
++ non-removable;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ wifi@1 {
++ reg = <1>;
++ compatible = "brcm,bcm4329-fmac";
++
++ interrupt-parent = <&tlmm>;
++ interrupts = <92 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "host-wake";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&wlan_sleep_clk_pin &wifi_pin>;
+ };
++};
+
+- mdss@fd900000 {
+- status = "ok";
++&sdhc_3 {
++ status = "okay";
++ max-frequency = <100000000>;
++
++ vmmc-supply = <&pma8084_l21>;
++ vqmmc-supply = <&pma8084_l13>;
++
++ /*
++ * cd-gpio is intentionally disabled. If enabled, an SD card
++ * present during boot is not initialized correctly. Without
++ * cd-gpios the driver resorts to polling, so hotplug works.
++ */
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhc2_pin_a /* &sdhc2_cd_pin */>;
++ /* cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>; */
++};
+
+- mdp@fd900000 {
+- status = "ok";
+- };
++&tlmm {
++ blsp2_uart2_pins_active: blsp2-uart2-pins-active {
++ pins = "gpio45", "gpio46", "gpio47", "gpio48";
++ function = "blsp_uart8";
++ drive-strength = <8>;
++ bias-disable;
++ };
+
+- dsi@fd922800 {
+- status = "ok";
++ blsp2_uart2_pins_sleep: blsp2-uart2-pins-sleep {
++ pins = "gpio45", "gpio46", "gpio47", "gpio48";
++ function = "gpio";
++ drive-strength = <2>;
++ bias-pull-down;
++ };
+
+- vdda-supply = <&pma8084_l2>;
+- vdd-supply = <&pma8084_l22>;
+- vddio-supply = <&pma8084_l12>;
++ bt_pins: bt-pins {
++ hostwake {
++ pins = "gpio75";
++ function = "gpio";
++ drive-strength = <16>;
++ input-enable;
++ };
+
+- #address-cells = <1>;
+- #size-cells = <0>;
++ devwake {
++ pins = "gpio91";
++ function = "gpio";
++ drive-strength = <2>;
++ };
++ };
+
+- ports {
+- port@1 {
+- endpoint {
+- remote-endpoint = <&panel_in>;
+- data-lanes = <0 1 2 3>;
+- };
+- };
+- };
++ sdhc1_pin_a: sdhc1-pin-active {
++ clk {
++ pins = "sdc1_clk";
++ drive-strength = <4>;
++ bias-disable;
++ };
+
+- panel: panel@0 {
+- reg = <0>;
+- compatible = "samsung,s6e3fa2";
++ cmd-data {
++ pins = "sdc1_cmd", "sdc1_data";
++ drive-strength = <4>;
++ bias-pull-up;
++ };
++ };
++
++ sdhc2_pin_a: sdhc2-pin-active {
++ clk-cmd-data {
++ pins = "gpio35", "gpio36", "gpio37", "gpio38",
++ "gpio39", "gpio40";
++ function = "sdc3";
++ drive-strength = <8>;
++ bias-disable;
++ };
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&panel_te_pin &panel_rst_pin>;
++ sdhc2_cd_pin: sdhc2-cd {
++ pins = "gpio62";
++ function = "gpio";
+
+- iovdd-supply = <&pma8084_lvs4>;
+- vddr-supply = <&vreg_panel>;
++ drive-strength = <2>;
++ bias-disable;
++ };
+
+- reset-gpios = <&pma8084_gpios 17 GPIO_ACTIVE_LOW>;
+- te-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
++ sdhc3_pin_a: sdhc3-pin-active {
++ clk {
++ pins = "sdc2_clk";
++ drive-strength = <6>;
++ bias-disable;
++ };
+
+- port {
+- panel_in: endpoint {
+- remote-endpoint = <&dsi0_out>;
+- };
+- };
+- };
++ cmd-data {
++ pins = "sdc2_cmd", "sdc2_data";
++ drive-strength = <6>;
++ bias-pull-up;
+ };
++ };
+
+- dsi-phy@fd922a00 {
+- status = "ok";
++ i2c2_pins: i2c2 {
++ mux {
++ pins = "gpio6", "gpio7";
++ function = "blsp_i2c2";
+
+- vddio-supply = <&pma8084_l12>;
++ drive-strength = <2>;
++ bias-disable;
+ };
+ };
+
+- remoteproc@fc880000 {
+- cx-supply = <&pma8084_s2>;
+- mss-supply = <&pma8084_s6>;
+- mx-supply = <&pma8084_s1>;
+- pll-supply = <&pma8084_l12>;
++ i2c6_pins: i2c6 {
++ mux {
++ pins = "gpio29", "gpio30";
++ function = "blsp_i2c6";
++
++ drive-strength = <2>;
++ bias-disable;
++ };
+ };
+-};
+
+-&spmi_bus {
+- pma8084@0 {
+- gpios@c000 {
+- gpio_keys_pin_a: gpio-keys-active {
+- pins = "gpio2", "gpio3", "gpio5";
+- function = "normal";
++ i2c12_pins: i2c12 {
++ mux {
++ pins = "gpio87", "gpio88";
++ function = "blsp_i2c12";
+
+- bias-pull-up;
+- power-source = <PMA8084_GPIO_S4>;
+- };
++ drive-strength = <2>;
++ bias-disable;
++ };
++ };
+
+- touchkey_pin: touchkey-int-pin {
+- pins = "gpio6";
+- function = "normal";
+- bias-disable;
+- input-enable;
+- power-source = <PMA8084_GPIO_S4>;
+- };
++ i2c_touchkey_pins: i2c-touchkey {
++ mux {
++ pins = "gpio95", "gpio96";
++ function = "gpio";
++ input-enable;
++ bias-pull-up;
++ };
++ };
+
+- touch_pin: touchscreen-int-pin {
+- pins = "gpio8";
+- function = "normal";
+- bias-disable;
+- input-enable;
+- power-source = <PMA8084_GPIO_S4>;
+- };
++ i2c_led_gpioex_pins: i2c-led-gpioex {
++ mux {
++ pins = "gpio120", "gpio121";
++ function = "gpio";
++ input-enable;
++ bias-pull-down;
++ };
++ };
+
+- panel_en_pin: panel-en-pin {
+- pins = "gpio14";
+- function = "normal";
+- bias-pull-up;
+- power-source = <PMA8084_GPIO_S4>;
+- qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+- };
++ gpioex_pin: gpioex {
++ res {
++ pins = "gpio145";
++ function = "gpio";
+
+- wlan_sleep_clk_pin: wlan-sleep-clk-pin {
+- pins = "gpio16";
+- function = "func2";
++ bias-pull-up;
++ drive-strength = <2>;
++ };
++ };
+
+- output-high;
+- power-source = <PMA8084_GPIO_S4>;
+- qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
+- };
++ wifi_pin: wifi {
++ int {
++ pins = "gpio92";
++ function = "gpio";
+
+- panel_rst_pin: panel-rst-pin {
+- pins = "gpio17";
+- function = "normal";
+- bias-disable;
+- power-source = <PMA8084_GPIO_S4>;
+- qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+- };
++ input-enable;
++ bias-pull-down;
++ };
++ };
+
++ panel_te_pin: panel {
++ te {
++ pins = "gpio12";
++ function = "mdp_vsync";
+
+- fuelgauge_pin: fuelgauge-int-pin {
+- pins = "gpio21";
+- function = "normal";
+- bias-disable;
+- input-enable;
+- power-source = <PMA8084_GPIO_S4>;
+- };
++ drive-strength = <2>;
++ bias-disable;
+ };
+ };
+ };
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index f1278d39ff6c..ea3491d47b9f 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -341,7 +341,7 @@ timer {
+ clock-frequency = <19200000>;
+ };
+
+- adsp-pil {
++ remoteproc_adsp: adsp-pil {
+ compatible = "qcom,msm8974-adsp-pil";
+
+ interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>,
+@@ -842,7 +842,7 @@ rng@f9bff000 {
+ clock-names = "core";
+ };
+
+- remoteproc@fc880000 {
++ remoteproc_mss: remoteproc@fc880000 {
+ compatible = "qcom,msm8974-mss-pil";
+ reg = <0xfc880000 0x100>, <0xfc820000 0x020>;
+ reg-names = "qdsp6", "rmb";
+--
+2.35.1
+
--- /dev/null
+From d13e89263b2be4724b0a46beb4abeb51fd9b5fb2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Apr 2022 22:10:29 +0200
+Subject: ARM: dts: qcom: msm8974-lge-nexus5: move gpio-keys out of soc
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit d3eff0e174e5feecb8f45cf630a30f47f02f921c ]
+
+The GPIO keys are not part of SoC and they should be defined inside of
+the root node.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220401201035.189106-5-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../qcom-msm8974-lge-nexus5-hammerhead.dts | 42 +++++++++----------
+ 1 file changed, 21 insertions(+), 21 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+index 069136170198..6d5fb60e798f 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+@@ -19,6 +19,27 @@ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
++ gpio-keys {
++ compatible = "gpio-keys";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&gpio_keys_pin_a>;
++
++ volume-up {
++ label = "volume_up";
++ gpios = <&pm8941_gpios 2 GPIO_ACTIVE_LOW>;
++ linux,input-type = <1>;
++ linux,code = <KEY_VOLUMEUP>;
++ };
++
++ volume-down {
++ label = "volume_down";
++ gpios = <&pm8941_gpios 3 GPIO_ACTIVE_LOW>;
++ linux,input-type = <1>;
++ linux,code = <KEY_VOLUMEDOWN>;
++ };
++ };
++
+ smd {
+ rpm {
+ rpm_requests {
+@@ -448,27 +469,6 @@ bcrmf@1 {
+ };
+ };
+
+- gpio-keys {
+- compatible = "gpio-keys";
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&gpio_keys_pin_a>;
+-
+- volume-up {
+- label = "volume_up";
+- gpios = <&pm8941_gpios 2 GPIO_ACTIVE_LOW>;
+- linux,input-type = <1>;
+- linux,code = <KEY_VOLUMEUP>;
+- };
+-
+- volume-down {
+- label = "volume_down";
+- gpios = <&pm8941_gpios 3 GPIO_ACTIVE_LOW>;
+- linux,input-type = <1>;
+- linux,code = <KEY_VOLUMEDOWN>;
+- };
+- };
+-
+ serial@f9960000 {
+ status = "okay";
+
+--
+2.35.1
+
--- /dev/null
+From 4cec0e042e39e1458c370e2c595e0fab1833effa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 13:56:20 +0200
+Subject: ARM: dts: qcom-msm8974-lge-nexus5: Use &labels
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit 1c1574e24990e9f9d753958745b8274874241158 ]
+
+Use &labels to align with the style used in new DTS and apply tiny
+style fixes.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+[bjorn: Rebased on top of Krzysztof's fixes]
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220415115633.575010-11-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../qcom-msm8974-lge-nexus5-hammerhead.dts | 1110 ++++++++---------
+ 1 file changed, 536 insertions(+), 574 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+index 4154ffb207ac..a1cae3d453c2 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+@@ -40,209 +40,6 @@ volume-down {
+ };
+ };
+
+- smd {
+- rpm {
+- rpm-requests {
+- pm8841-regulators {
+- s1 {
+- regulator-min-microvolt = <675000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- s2 {
+- regulator-min-microvolt = <500000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- s3 {
+- regulator-min-microvolt = <1050000>;
+- regulator-max-microvolt = <1050000>;
+- };
+-
+- s4 {
+- regulator-min-microvolt = <815000>;
+- regulator-max-microvolt = <900000>;
+- };
+- };
+-
+- pm8941-regulators {
+- vdd_l1_l3-supply = <&pm8941_s1>;
+- vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+- vdd_l4_l11-supply = <&pm8941_s1>;
+- vdd_l5_l7-supply = <&pm8941_s2>;
+- vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
+- vdd_l8_l16_l18_l19-supply = <&vreg_vph_pwr>;
+- vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
+- vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
+- vdd_l21-supply = <&vreg_boost>;
+-
+- s1 {
+- regulator-min-microvolt = <1300000>;
+- regulator-max-microvolt = <1300000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- s2 {
+- regulator-min-microvolt = <2150000>;
+- regulator-max-microvolt = <2150000>;
+-
+- regulator-boot-on;
+- };
+-
+- s3 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l1 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l2 {
+- regulator-min-microvolt = <1200000>;
+- regulator-max-microvolt = <1200000>;
+- };
+-
+- l3 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l4 {
+- regulator-min-microvolt = <1225000>;
+- regulator-max-microvolt = <1225000>;
+- };
+-
+- l5 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l6 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-boot-on;
+- };
+-
+- l7 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-boot-on;
+- };
+-
+- l8 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l9 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l10 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+- };
+-
+- l11 {
+- regulator-min-microvolt = <1300000>;
+- regulator-max-microvolt = <1300000>;
+- };
+-
+- l12 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+-
+- regulator-always-on;
+- regulator-boot-on;
+- };
+-
+- l13 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-boot-on;
+- };
+-
+- l14 {
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <1800000>;
+- };
+-
+- l15 {
+- regulator-min-microvolt = <2050000>;
+- regulator-max-microvolt = <2050000>;
+- };
+-
+- l16 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
+- };
+-
+- l17 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l18 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
+- };
+-
+- l19 {
+- regulator-min-microvolt = <3000000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l20 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-boot-on;
+- regulator-system-load = <200000>;
+- regulator-allow-set-load;
+- };
+-
+- l21 {
+- regulator-min-microvolt = <2950000>;
+- regulator-max-microvolt = <2950000>;
+-
+- regulator-boot-on;
+- };
+-
+- l22 {
+- regulator-min-microvolt = <3000000>;
+- regulator-max-microvolt = <3300000>;
+- };
+-
+- l23 {
+- regulator-min-microvolt = <3000000>;
+- regulator-max-microvolt = <3000000>;
+- };
+-
+- l24 {
+- regulator-min-microvolt = <3075000>;
+- regulator-max-microvolt = <3075000>;
+-
+- regulator-boot-on;
+- };
+- };
+- };
+- };
+- };
+-
+ vreg_wlan: wlan-regulator {
+ compatible = "regulator-fixed";
+
+@@ -258,504 +55,669 @@ vreg_wlan: wlan-regulator {
+ };
+ };
+
+-&soc {
+- serial@f991d000 {
+- status = "okay";
++&blsp1_i2c1 {
++ status = "okay";
++ clock-frequency = <100000>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c1_pins>;
++
++ charger: bq24192@6b {
++ compatible = "ti,bq24192";
++ reg = <0x6b>;
++ interrupts-extended = <&spmi_bus 0 0xd5 0 IRQ_TYPE_EDGE_FALLING>;
++
++ omit-battery-class;
++
++ usb_otg_vbus: usb-otg-vbus { };
+ };
+
+- pinctrl@fd510000 {
+- sdhc1_pin_a: sdhc1-pin-active {
+- clk {
+- pins = "sdc1_clk";
+- drive-strength = <16>;
+- bias-disable;
+- };
++ fuelgauge: max17048@36 {
++ compatible = "maxim,max17048";
++ reg = <0x36>;
+
+- cmd-data {
+- pins = "sdc1_cmd", "sdc1_data";
+- drive-strength = <10>;
+- bias-pull-up;
+- };
+- };
++ maxim,double-soc;
++ maxim,rcomp = /bits/ 8 <0x4d>;
+
+- sdhc2_pin_a: sdhc2-pin-active {
+- clk {
+- pins = "sdc2_clk";
+- drive-strength = <6>;
+- bias-disable;
+- };
++ interrupt-parent = <&tlmm>;
++ interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+
+- cmd-data {
+- pins = "sdc2_cmd", "sdc2_data";
+- drive-strength = <6>;
+- bias-pull-up;
+- };
+- };
++ pinctrl-names = "default";
++ pinctrl-0 = <&fuelgauge_pin>;
+
+- i2c1_pins: i2c1 {
+- mux {
+- pins = "gpio2", "gpio3";
+- function = "blsp_i2c1";
++ maxim,alert-low-soc-level = <2>;
++ };
++};
+
+- drive-strength = <2>;
+- bias-disable;
+- };
+- };
++&blsp1_i2c2 {
++ status = "okay";
++ clock-frequency = <355000>;
+
+- i2c2_pins: i2c2 {
+- mux {
+- pins = "gpio6", "gpio7";
+- function = "blsp_i2c2";
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c2_pins>;
+
+- drive-strength = <2>;
+- bias-disable;
+- };
++ synaptics@70 {
++ compatible = "syna,rmi4-i2c";
++ reg = <0x70>;
++
++ interrupts-extended = <&tlmm 5 IRQ_TYPE_EDGE_FALLING>;
++ vdd-supply = <&pm8941_l22>;
++ vio-supply = <&pm8941_lvs3>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&touch_pin>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ rmi4-f01@1 {
++ reg = <0x1>;
++ syna,nosleep-mode = <1>;
+ };
+
+- i2c3_pins: i2c3 {
+- mux {
+- pins = "gpio10", "gpio11";
+- function = "blsp_i2c3";
+- drive-strength = <2>;
+- bias-disable;
+- };
++ rmi4-f12@12 {
++ reg = <0x12>;
++ syna,sensor-type = <1>;
+ };
++ };
++};
+
+- i2c11_pins: i2c11 {
+- mux {
+- pins = "gpio83", "gpio84";
+- function = "blsp_i2c11";
++&blsp1_i2c3 {
++ status = "okay";
++ clock-frequency = <100000>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c3_pins>;
++
++ avago_apds993@39 {
++ compatible = "avago,apds9930";
++ reg = <0x39>;
++ interrupts-extended = <&tlmm 61 IRQ_TYPE_EDGE_FALLING>;
++ vdd-supply = <&pm8941_l17>;
++ vddio-supply = <&pm8941_lvs1>;
++ led-max-microamp = <100000>;
++ amstaos,proximity-diodes = <0>;
++ };
++};
+
+- drive-strength = <2>;
+- bias-disable;
+- };
++&blsp2_i2c5 {
++ status = "okay";
++ clock-frequency = <355000>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c11_pins>;
++
++ led-controller@38 {
++ compatible = "ti,lm3630a";
++ status = "okay";
++ reg = <0x38>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ led@0 {
++ reg = <0>;
++ led-sources = <0 1>;
++ label = "lcd-backlight";
++ default-brightness = <200>;
+ };
++ };
++};
++
++&blsp2_i2c6 {
++ status = "okay";
++ clock-frequency = <100000>;
+
+- i2c12_pins: i2c12 {
+- mux {
+- pins = "gpio87", "gpio88";
+- function = "blsp_i2c12";
+- drive-strength = <2>;
+- bias-disable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c12_pins>;
++
++ mpu6515@68 {
++ compatible = "invensense,mpu6515";
++ reg = <0x68>;
++ interrupts-extended = <&tlmm 73 IRQ_TYPE_EDGE_FALLING>;
++ vddio-supply = <&pm8941_lvs1>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&mpu6515_pin>;
++
++ mount-matrix = "0", "-1", "0",
++ "-1", "0", "0",
++ "0", "0", "1";
++
++ i2c-gate {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ ak8963@f {
++ compatible = "asahi-kasei,ak8963";
++ reg = <0x0f>;
++ gpios = <&tlmm 67 0>;
++ vid-supply = <&pm8941_lvs1>;
++ vdd-supply = <&pm8941_l17>;
+ };
+- };
+
+- mpu6515_pin: mpu6515 {
+- irq {
+- pins = "gpio73";
+- function = "gpio";
+- bias-disable;
+- input-enable;
++ bmp280@76 {
++ compatible = "bosch,bmp280";
++ reg = <0x76>;
++ vdda-supply = <&pm8941_lvs1>;
++ vddd-supply = <&pm8941_l17>;
+ };
+ };
++ };
++};
+
+- touch_pin: touch {
+- int {
+- pins = "gpio5";
+- function = "gpio";
++&blsp1_uart1 {
++ status = "okay";
++};
+
+- drive-strength = <2>;
+- bias-disable;
+- input-enable;
+- };
++&blsp2_uart4 {
++ status = "okay";
+
+- reset {
+- pins = "gpio8";
+- function = "gpio";
++ pinctrl-names = "default";
++ pinctrl-0 = <&blsp2_uart4_pin_a>;
+
+- drive-strength = <2>;
+- bias-pull-up;
+- };
+- };
++ bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ max-speed = <3000000>;
+
+- panel_pin: panel {
+- te {
+- pins = "gpio12";
+- function = "mdp_vsync";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bt_pin>;
+
+- drive-strength = <2>;
+- bias-disable;
+- };
+- };
++ host-wakeup-gpios = <&tlmm 42 GPIO_ACTIVE_HIGH>;
++ device-wakeup-gpios = <&tlmm 62 GPIO_ACTIVE_HIGH>;
++ shutdown-gpios = <&tlmm 41 GPIO_ACTIVE_HIGH>;
++ };
++};
+
+- bt_pin: bt {
+- hostwake {
+- pins = "gpio42";
+- function = "gpio";
+- };
++&dsi0 {
++ status = "okay";
+
+- devwake {
+- pins = "gpio62";
+- function = "gpio";
+- };
++ vdda-supply = <&pm8941_l2>;
++ vdd-supply = <&pm8941_lvs3>;
++ vddio-supply = <&pm8941_l12>;
++
++ panel: panel@0 {
++ reg = <0>;
++ compatible = "lg,acx467akm-7";
+
+- shutdown {
+- pins = "gpio41";
+- function = "gpio";
++ pinctrl-names = "default";
++ pinctrl-0 = <&panel_pin>;
++
++ port {
++ panel_in: endpoint {
++ remote-endpoint = <&dsi0_out>;
+ };
+ };
++ };
++};
+
+- blsp2_uart4_pin_a: blsp2-uart4-pin-active {
+- tx {
+- pins = "gpio53";
+- function = "blsp_uart10";
++&dsi0_out {
++ remote-endpoint = <&panel_in>;
++ data-lanes = <0 1 2 3>;
++};
+
+- drive-strength = <2>;
+- bias-disable;
+- };
++&dsi0_phy {
++ status = "okay";
+
+- rx {
+- pins = "gpio54";
+- function = "blsp_uart10";
++ vddio-supply = <&pm8941_l12>;
++};
+
+- drive-strength = <2>;
+- bias-pull-up;
+- };
++&mdss {
++ status = "okay";
++};
+
+- cts {
+- pins = "gpio55";
+- function = "blsp_uart10";
++&otg {
++ status = "okay";
+
+- drive-strength = <2>;
+- bias-pull-up;
+- };
++ phys = <&usb_hs1_phy>;
++ phy-select = <&tcsr 0xb000 0>;
+
+- rts {
+- pins = "gpio56";
+- function = "blsp_uart10";
++ extcon = <&charger>, <&usb_id>;
++ vbus-supply = <&usb_otg_vbus>;
+
+- drive-strength = <2>;
+- bias-disable;
+- };
++ hnp-disable;
++ srp-disable;
++ adp-disable;
++
++ ulpi {
++ phy@a {
++ status = "okay";
++
++ v1p8-supply = <&pm8941_l6>;
++ v3p3-supply = <&pm8941_l24>;
++
++ qcom,init-seq = /bits/ 8 <0x1 0x64>;
+ };
+ };
++};
+
+- sdhci@f9824900 {
+- status = "okay";
++&pm8941_gpios {
++ gpio_keys_pin_a: gpio-keys-active {
++ pins = "gpio2", "gpio3";
++ function = "normal";
+
+- vmmc-supply = <&pm8941_l20>;
+- vqmmc-supply = <&pm8941_s3>;
++ bias-pull-up;
++ power-source = <PM8941_GPIO_S3>;
++ };
+
+- bus-width = <8>;
+- non-removable;
++ fuelgauge_pin: fuelgauge-int {
++ pins = "gpio9";
++ function = "normal";
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc1_pin_a>;
++ bias-disable;
++ input-enable;
++ power-source = <PM8941_GPIO_S3>;
+ };
+
+- sdhci@f98a4900 {
+- status = "okay";
++ wlan_sleep_clk_pin: wl-sleep-clk {
++ pins = "gpio16";
++ function = "func2";
++
++ output-high;
++ power-source = <PM8941_GPIO_S3>;
++ };
+
+- max-frequency = <100000000>;
+- bus-width = <4>;
+- non-removable;
+- vmmc-supply = <&vreg_wlan>;
+- vqmmc-supply = <&pm8941_s3>;
++ wlan_regulator_pin: wl-reg-active {
++ pins = "gpio17";
++ function = "normal";
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdhc2_pin_a>;
++ bias-disable;
++ power-source = <PM8941_GPIO_S3>;
++ };
+
+- #address-cells = <1>;
+- #size-cells = <0>;
++ otg {
++ gpio-hog;
++ gpios = <35 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "otg-gpio";
++ };
++};
++
++&rpm_requests {
++ pm8841-regulators {
++ pm8841_s1: s1 {
++ regulator-min-microvolt = <675000>;
++ regulator-max-microvolt = <1050000>;
++ };
+
+- bcrmf@1 {
+- compatible = "brcm,bcm4339-fmac", "brcm,bcm4329-fmac";
+- reg = <1>;
++ pm8841_s2: s2 {
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1050000>;
++ };
+
+- brcm,drive-strength = <10>;
++ pm8841_s3: s3 {
++ regulator-min-microvolt = <1050000>;
++ regulator-max-microvolt = <1050000>;
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&wlan_sleep_clk_pin>;
++ pm8841_s4: s4 {
++ regulator-min-microvolt = <815000>;
++ regulator-max-microvolt = <900000>;
+ };
+ };
+
+- serial@f9960000 {
+- status = "okay";
++ pm8941-regulators {
++ vdd_l1_l3-supply = <&pm8941_s1>;
++ vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
++ vdd_l4_l11-supply = <&pm8941_s1>;
++ vdd_l5_l7-supply = <&pm8941_s2>;
++ vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
++ vdd_l8_l16_l18_l19-supply = <&vreg_vph_pwr>;
++ vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
++ vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
++ vdd_l21-supply = <&vreg_boost>;
++
++ pm8941_s1: s1 {
++ regulator-min-microvolt = <1300000>;
++ regulator-max-microvolt = <1300000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&blsp2_uart4_pin_a>;
++ pm8941_s2: s2 {
++ regulator-min-microvolt = <2150000>;
++ regulator-max-microvolt = <2150000>;
++ regulator-boot-on;
++ };
+
+- bluetooth {
+- compatible = "brcm,bcm43438-bt";
+- max-speed = <3000000>;
++ pm8941_s3: s3 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&bt_pin>;
++ pm8941_l1: l1 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
+
+- host-wakeup-gpios = <&tlmm 42 GPIO_ACTIVE_HIGH>;
+- device-wakeup-gpios = <&tlmm 62 GPIO_ACTIVE_HIGH>;
+- shutdown-gpios = <&tlmm 41 GPIO_ACTIVE_HIGH>;
++ pm8941_l2: l2 {
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
+ };
+- };
+
+- i2c@f9967000 {
+- status = "okay";
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c11_pins>;
+- clock-frequency = <355000>;
+- qcom,src-freq = <50000000>;
++ pm8941_l3: l3 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
++ };
+
+- led-controller@38 {
+- compatible = "ti,lm3630a";
+- status = "okay";
+- reg = <0x38>;
++ pm8941_l4: l4 {
++ regulator-min-microvolt = <1225000>;
++ regulator-max-microvolt = <1225000>;
++ };
+
+- #address-cells = <1>;
+- #size-cells = <0>;
++ pm8941_l5: l5 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
+
+- led@0 {
+- reg = <0>;
+- led-sources = <0 1>;
+- label = "lcd-backlight";
+- default-brightness = <200>;
+- };
++ pm8941_l6: l6 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
+ };
+- };
+
+- i2c@f9968000 {
+- status = "okay";
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c12_pins>;
+- clock-frequency = <100000>;
+- qcom,src-freq = <50000000>;
+-
+- mpu6515@68 {
+- compatible = "invensense,mpu6515";
+- reg = <0x68>;
+- interrupts-extended = <&tlmm 73 IRQ_TYPE_EDGE_FALLING>;
+- vddio-supply = <&pm8941_lvs1>;
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&mpu6515_pin>;
+-
+- mount-matrix = "0", "-1", "0",
+- "-1", "0", "0",
+- "0", "0", "1";
+-
+- i2c-gate {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- ak8963@f {
+- compatible = "asahi-kasei,ak8963";
+- reg = <0x0f>;
+- gpios = <&tlmm 67 0>;
+- vid-supply = <&pm8941_lvs1>;
+- vdd-supply = <&pm8941_l17>;
+- };
+-
+- bmp280@76 {
+- compatible = "bosch,bmp280";
+- reg = <0x76>;
+- vdda-supply = <&pm8941_lvs1>;
+- vddd-supply = <&pm8941_l17>;
+- };
+- };
++ pm8941_l7: l7 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
+ };
+- };
+
+- i2c@f9923000 {
+- status = "okay";
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c1_pins>;
+- clock-frequency = <100000>;
+- qcom,src-freq = <50000000>;
++ pm8941_l8: l8 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
+
+- charger: bq24192@6b {
+- compatible = "ti,bq24192";
+- reg = <0x6b>;
+- interrupts-extended = <&spmi_bus 0 0xd5 0 IRQ_TYPE_EDGE_FALLING>;
++ pm8941_l9: l9 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ };
+
+- omit-battery-class;
++ pm8941_l10: l10 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ };
+
+- usb_otg_vbus: usb-otg-vbus { };
++ pm8941_l11: l11 {
++ regulator-min-microvolt = <1300000>;
++ regulator-max-microvolt = <1300000>;
+ };
+
+- fuelgauge: max17048@36 {
+- compatible = "maxim,max17048";
+- reg = <0x36>;
++ pm8941_l12: l12 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ pm8941_l13: l13 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-boot-on;
++ };
++
++ pm8941_l14: l14 {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
++ pm8941_l15: l15 {
++ regulator-min-microvolt = <2050000>;
++ regulator-max-microvolt = <2050000>;
++ };
++
++ pm8941_l16: l16 {
++ regulator-min-microvolt = <2700000>;
++ regulator-max-microvolt = <2700000>;
++ };
++
++ pm8941_l17: l17 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++
++ pm8941_l18: l18 {
++ regulator-min-microvolt = <2850000>;
++ regulator-max-microvolt = <2850000>;
++ };
++
++ pm8941_l19: l19 {
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3300000>;
++ };
+
+- maxim,double-soc;
+- maxim,rcomp = /bits/ 8 <0x4d>;
++ pm8941_l20: l20 {
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-system-load = <200000>;
++ regulator-allow-set-load;
++ regulator-boot-on;
++ };
++
++ pm8941_l21: l21 {
++ regulator-min-microvolt = <2950000>;
++ regulator-max-microvolt = <2950000>;
++ regulator-boot-on;
++ };
+
+- interrupt-parent = <&tlmm>;
+- interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
++ pm8941_l22: l22 {
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3300000>;
++ };
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&fuelgauge_pin>;
++ pm8941_l23: l23 {
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3000000>;
++ };
+
+- maxim,alert-low-soc-level = <2>;
++ pm8941_l24: l24 {
++ regulator-min-microvolt = <3075000>;
++ regulator-max-microvolt = <3075000>;
++ regulator-boot-on;
+ };
+ };
++};
+
+- i2c@f9924000 {
+- status = "okay";
++&sdhc_1 {
++ status = "okay";
+
+- clock-frequency = <355000>;
+- qcom,src-freq = <50000000>;
++ vmmc-supply = <&pm8941_l20>;
++ vqmmc-supply = <&pm8941_s3>;
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c2_pins>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhc1_pin_a>;
++};
+
+- synaptics@70 {
+- compatible = "syna,rmi4-i2c";
+- reg = <0x70>;
++&sdhc_2 {
++ status = "okay";
+
+- interrupts-extended = <&tlmm 5 IRQ_TYPE_EDGE_FALLING>;
+- vdd-supply = <&pm8941_l22>;
+- vio-supply = <&pm8941_lvs3>;
++ max-frequency = <100000000>;
++ vmmc-supply = <&vreg_wlan>;
++ vqmmc-supply = <&pm8941_s3>;
++ non-removable;
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&touch_pin>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhc2_pin_a>;
+
+- #address-cells = <1>;
+- #size-cells = <0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
+
+- rmi4-f01@1 {
+- reg = <0x1>;
+- syna,nosleep-mode = <1>;
+- };
++ bcrmf@1 {
++ compatible = "brcm,bcm4339-fmac", "brcm,bcm4329-fmac";
++ reg = <1>;
+
+- rmi4-f12@12 {
+- reg = <0x12>;
+- syna,sensor-type = <1>;
+- };
++ brcm,drive-strength = <10>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&wlan_sleep_clk_pin>;
++ };
++};
++
++&tlmm {
++ sdhc1_pin_a: sdhc1-pin-active {
++ clk {
++ pins = "sdc1_clk";
++ drive-strength = <16>;
++ bias-disable;
++ };
++
++ cmd-data {
++ pins = "sdc1_cmd", "sdc1_data";
++ drive-strength = <10>;
++ bias-pull-up;
+ };
+ };
+
+- i2c@f9925000 {
+- status = "okay";
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c3_pins>;
+- clock-frequency = <100000>;
+- qcom,src-freq = <50000000>;
++ sdhc2_pin_a: sdhc2-pin-active {
++ clk {
++ pins = "sdc2_clk";
++ drive-strength = <6>;
++ bias-disable;
++ };
+
+- avago_apds993@39 {
+- compatible = "avago,apds9930";
+- reg = <0x39>;
+- interrupts-extended = <&tlmm 61 IRQ_TYPE_EDGE_FALLING>;
+- vdd-supply = <&pm8941_l17>;
+- vddio-supply = <&pm8941_lvs1>;
+- led-max-microamp = <100000>;
+- amstaos,proximity-diodes = <0>;
++ cmd-data {
++ pins = "sdc2_cmd", "sdc2_data";
++ drive-strength = <6>;
++ bias-pull-up;
+ };
+ };
+
+- usb@f9a55000 {
+- status = "okay";
++ i2c1_pins: i2c1 {
++ mux {
++ pins = "gpio2", "gpio3";
++ function = "blsp_i2c1";
+
+- phys = <&usb_hs1_phy>;
+- phy-select = <&tcsr 0xb000 0>;
++ drive-strength = <2>;
++ bias-disable;
++ };
++ };
+
+- extcon = <&charger>, <&usb_id>;
+- vbus-supply = <&usb_otg_vbus>;
++ i2c2_pins: i2c2 {
++ mux {
++ pins = "gpio6", "gpio7";
++ function = "blsp_i2c2";
+
+- hnp-disable;
+- srp-disable;
+- adp-disable;
++ drive-strength = <2>;
++ bias-disable;
++ };
++ };
+
+- ulpi {
+- phy@a {
+- status = "okay";
++ i2c3_pins: i2c3 {
++ mux {
++ pins = "gpio10", "gpio11";
++ function = "blsp_i2c3";
++ drive-strength = <2>;
++ bias-disable;
++ };
++ };
+
+- v1p8-supply = <&pm8941_l6>;
+- v3p3-supply = <&pm8941_l24>;
++ i2c11_pins: i2c11 {
++ mux {
++ pins = "gpio83", "gpio84";
++ function = "blsp_i2c11";
+
+- qcom,init-seq = /bits/ 8 <0x1 0x64>;
+- };
++ drive-strength = <2>;
++ bias-disable;
+ };
+ };
+
+- mdss@fd900000 {
+- status = "okay";
++ i2c12_pins: i2c12 {
++ mux {
++ pins = "gpio87", "gpio88";
++ function = "blsp_i2c12";
++ drive-strength = <2>;
++ bias-disable;
++ };
++ };
+
+- mdp@fd900000 {
+- status = "okay";
++ mpu6515_pin: mpu6515 {
++ irq {
++ pins = "gpio73";
++ function = "gpio";
++ bias-disable;
++ input-enable;
+ };
++ };
+
+- dsi@fd922800 {
+- status = "okay";
++ touch_pin: touch {
++ int {
++ pins = "gpio5";
++ function = "gpio";
+
+- vdda-supply = <&pm8941_l2>;
+- vdd-supply = <&pm8941_lvs3>;
+- vddio-supply = <&pm8941_l12>;
++ drive-strength = <2>;
++ bias-disable;
++ input-enable;
++ };
+
+- #address-cells = <1>;
+- #size-cells = <0>;
++ reset {
++ pins = "gpio8";
++ function = "gpio";
+
+- ports {
+- port@1 {
+- endpoint {
+- remote-endpoint = <&panel_in>;
+- data-lanes = <0 1 2 3>;
+- };
+- };
+- };
++ drive-strength = <2>;
++ bias-pull-up;
++ };
++ };
+
+- panel: panel@0 {
+- reg = <0>;
+- compatible = "lg,acx467akm-7";
++ panel_pin: panel {
++ te {
++ pins = "gpio12";
++ function = "mdp_vsync";
+
+- pinctrl-names = "default";
+- pinctrl-0 = <&panel_pin>;
++ drive-strength = <2>;
++ bias-disable;
++ };
++ };
+
+- port {
+- panel_in: endpoint {
+- remote-endpoint = <&dsi0_out>;
+- };
+- };
+- };
++ bt_pin: bt {
++ hostwake {
++ pins = "gpio42";
++ function = "gpio";
+ };
+
+- dsi-phy@fd922a00 {
+- status = "okay";
++ devwake {
++ pins = "gpio62";
++ function = "gpio";
++ };
+
+- vddio-supply = <&pm8941_l12>;
++ shutdown {
++ pins = "gpio41";
++ function = "gpio";
+ };
+ };
+-};
+
+-&spmi_bus {
+- pm8941@0 {
+- gpios@c000 {
+- gpio_keys_pin_a: gpio-keys-active {
+- pins = "gpio2", "gpio3";
+- function = "normal";
++ blsp2_uart4_pin_a: blsp2-uart4-pin-active {
++ tx {
++ pins = "gpio53";
++ function = "blsp_uart10";
+
+- bias-pull-up;
+- power-source = <PM8941_GPIO_S3>;
+- };
+-
+- fuelgauge_pin: fuelgauge-int {
+- pins = "gpio9";
+- function = "normal";
++ drive-strength = <2>;
++ bias-disable;
++ };
+
+- bias-disable;
+- input-enable;
+- power-source = <PM8941_GPIO_S3>;
+- };
++ rx {
++ pins = "gpio54";
++ function = "blsp_uart10";
+
+- wlan_sleep_clk_pin: wl-sleep-clk {
+- pins = "gpio16";
+- function = "func2";
++ drive-strength = <2>;
++ bias-pull-up;
++ };
+
+- output-high;
+- power-source = <PM8941_GPIO_S3>;
+- };
++ cts {
++ pins = "gpio55";
++ function = "blsp_uart10";
+
+- wlan_regulator_pin: wl-reg-active {
+- pins = "gpio17";
+- function = "normal";
++ drive-strength = <2>;
++ bias-pull-up;
++ };
+
+- bias-disable;
+- power-source = <PM8941_GPIO_S3>;
+- };
++ rts {
++ pins = "gpio56";
++ function = "blsp_uart10";
+
+- otg {
+- gpio-hog;
+- gpios = <35 GPIO_ACTIVE_HIGH>;
+- output-high;
+- line-name = "otg-gpio";
+- };
++ drive-strength = <2>;
++ bias-disable;
+ };
+ };
+ };
+--
+2.35.1
+
--- /dev/null
+From 4d8465a08ef74ecd29459421c37a5cf2729816fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 13:56:17 +0200
+Subject: ARM: dts: qcom-msm8974*: Rename msmgpio to tlmm
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit 087c9704d5bb322dd5db52938416caeaf4cdc3c3 ]
+
+Rename the label to match new the style used in newer DTs.
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220415115633.575010-8-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../arm/boot/dts/qcom-apq8074-dragonboard.dts | 2 +-
+ .../boot/dts/qcom-msm8974-fairphone-fp2.dts | 2 +-
+ .../qcom-msm8974-lge-nexus5-hammerhead.dts | 18 ++++++++---------
+ .../boot/dts/qcom-msm8974-samsung-klte.dts | 20 +++++++++----------
+ .../dts/qcom-msm8974-sony-xperia-amami.dts | 2 +-
+ .../dts/qcom-msm8974-sony-xperia-castor.dts | 10 +++++-----
+ .../dts/qcom-msm8974-sony-xperia-honami.dts | 4 ++--
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 4 ++--
+ 8 files changed, 31 insertions(+), 31 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+index e2b4e4fc6377..9076a24408c6 100644
+--- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
++++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+@@ -35,7 +35,7 @@ sdhci@f9824900 {
+ };
+
+ sdhci@f98a4900 {
+- cd-gpios = <&msmgpio 62 0x1>;
++ cd-gpios = <&tlmm 62 0x1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
+ bus-width = <4>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+index 9dbfc9f8646a..1e947bab06b6 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+@@ -51,7 +51,7 @@ volume-up {
+
+ vibrator {
+ compatible = "gpio-vibrator";
+- enable-gpios = <&msmgpio 86 GPIO_ACTIVE_HIGH>;
++ enable-gpios = <&tlmm 86 GPIO_ACTIVE_HIGH>;
+ vcc-supply = <&pm8941_l18>;
+ };
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+index dd2d0647d4be..4154ffb207ac 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+@@ -250,7 +250,7 @@ vreg_wlan: wlan-regulator {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+- gpio = <&msmgpio 26 GPIO_ACTIVE_HIGH>;
++ gpio = <&tlmm 26 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+@@ -482,9 +482,9 @@ bluetooth {
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_pin>;
+
+- host-wakeup-gpios = <&msmgpio 42 GPIO_ACTIVE_HIGH>;
+- device-wakeup-gpios = <&msmgpio 62 GPIO_ACTIVE_HIGH>;
+- shutdown-gpios = <&msmgpio 41 GPIO_ACTIVE_HIGH>;
++ host-wakeup-gpios = <&tlmm 42 GPIO_ACTIVE_HIGH>;
++ device-wakeup-gpios = <&tlmm 62 GPIO_ACTIVE_HIGH>;
++ shutdown-gpios = <&tlmm 41 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+@@ -522,7 +522,7 @@ i2c@f9968000 {
+ mpu6515@68 {
+ compatible = "invensense,mpu6515";
+ reg = <0x68>;
+- interrupts-extended = <&msmgpio 73 IRQ_TYPE_EDGE_FALLING>;
++ interrupts-extended = <&tlmm 73 IRQ_TYPE_EDGE_FALLING>;
+ vddio-supply = <&pm8941_lvs1>;
+
+ pinctrl-names = "default";
+@@ -538,7 +538,7 @@ i2c-gate {
+ ak8963@f {
+ compatible = "asahi-kasei,ak8963";
+ reg = <0x0f>;
+- gpios = <&msmgpio 67 0>;
++ gpios = <&tlmm 67 0>;
+ vid-supply = <&pm8941_lvs1>;
+ vdd-supply = <&pm8941_l17>;
+ };
+@@ -577,7 +577,7 @@ fuelgauge: max17048@36 {
+ maxim,double-soc;
+ maxim,rcomp = /bits/ 8 <0x4d>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-names = "default";
+@@ -600,7 +600,7 @@ synaptics@70 {
+ compatible = "syna,rmi4-i2c";
+ reg = <0x70>;
+
+- interrupts-extended = <&msmgpio 5 IRQ_TYPE_EDGE_FALLING>;
++ interrupts-extended = <&tlmm 5 IRQ_TYPE_EDGE_FALLING>;
+ vdd-supply = <&pm8941_l22>;
+ vio-supply = <&pm8941_lvs3>;
+
+@@ -632,7 +632,7 @@ i2c@f9925000 {
+ avago_apds993@39 {
+ compatible = "avago,apds9930";
+ reg = <0x39>;
+- interrupts-extended = <&msmgpio 61 IRQ_TYPE_EDGE_FALLING>;
++ interrupts-extended = <&tlmm 61 IRQ_TYPE_EDGE_FALLING>;
+ vdd-supply = <&pm8941_l17>;
+ vddio-supply = <&pm8941_lvs1>;
+ led-max-microamp = <100000>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+index 3ee2508b20fb..60244e0c37ba 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+@@ -247,8 +247,8 @@ i2c-gpio-touchkey {
+ compatible = "i2c-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+- sda-gpios = <&msmgpio 95 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+- scl-gpios = <&msmgpio 96 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
++ sda-gpios = <&tlmm 95 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
++ scl-gpios = <&tlmm 96 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c_touchkey_pins>;
+
+@@ -272,8 +272,8 @@ i2c-gpio-led {
+ compatible = "i2c-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+- scl-gpios = <&msmgpio 121 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+- sda-gpios = <&msmgpio 120 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
++ scl-gpios = <&tlmm 121 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
++ sda-gpios = <&tlmm 120 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c_led_gpioex_pins>;
+
+@@ -291,7 +291,7 @@ gpio_expander: gpio@20 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpioex_pin>;
+
+- reset-gpios = <&msmgpio 145 GPIO_ACTIVE_LOW>;
++ reset-gpios = <&tlmm 145 GPIO_ACTIVE_LOW>;
+ };
+
+ led-controller@30 {
+@@ -371,9 +371,9 @@ bluetooth {
+ max-speed = <3000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_pins>;
+- device-wakeup-gpios = <&msmgpio 91 GPIO_ACTIVE_HIGH>;
++ device-wakeup-gpios = <&tlmm 91 GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&gpio_expander 9 GPIO_ACTIVE_HIGH>;
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <75 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "host-wakeup";
+ };
+@@ -563,7 +563,7 @@ sdhci@f9864900 {
+ */
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhc2_pin_a /* &sdhc2_cd_pin */>;
+- // cd-gpios = <&msmgpio 62 GPIO_ACTIVE_LOW>;
++ // cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
+ };
+
+ sdhci@f98a4900 {
+@@ -587,7 +587,7 @@ wifi@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <92 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "host-wake";
+
+@@ -818,7 +818,7 @@ panel: panel@0 {
+ vddr-supply = <&vreg_panel>;
+
+ reset-gpios = <&pma8084_gpios 17 GPIO_ACTIVE_LOW>;
+- te-gpios = <&msmgpio 12 GPIO_ACTIVE_HIGH>;
++ te-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
+
+ port {
+ panel_in: endpoint {
+diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-amami.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-amami.dts
+index 8cace789fb26..6545917dd489 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-amami.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-amami.dts
+@@ -280,7 +280,7 @@ sdhci@f98a4900 {
+ vmmc-supply = <&pm8941_l21>;
+ vqmmc-supply = <&pm8941_l13>;
+
+- cd-gpios = <&msmgpio 62 GPIO_ACTIVE_LOW>;
++ cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
+index e27b360951fd..352689237140 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
+@@ -239,7 +239,7 @@ vreg_bl_vddio: lcd-backlight-vddio {
+ regulator-min-microvolt = <3150000>;
+ regulator-max-microvolt = <3150000>;
+
+- gpio = <&msmgpio 69 0>;
++ gpio = <&tlmm 69 0>;
+ enable-active-high;
+
+ vin-supply = <&pm8941_s3>;
+@@ -323,7 +323,7 @@ sdhci@f98a4900 {
+ vmmc-supply = <&pm8941_l21>;
+ vqmmc-supply = <&pm8941_l13>;
+
+- cd-gpios = <&msmgpio 62 GPIO_ACTIVE_LOW>;
++ cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
+@@ -351,8 +351,8 @@ bluetooth {
+ <&bt_dev_wake_pin>,
+ <&bt_reg_on_pin>;
+
+- host-wakeup-gpios = <&msmgpio 95 GPIO_ACTIVE_HIGH>;
+- device-wakeup-gpios = <&msmgpio 96 GPIO_ACTIVE_HIGH>;
++ host-wakeup-gpios = <&tlmm 95 GPIO_ACTIVE_HIGH>;
++ device-wakeup-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&pm8941_gpios 16 GPIO_ACTIVE_HIGH>;
+ };
+ };
+@@ -566,7 +566,7 @@ synaptics@2c {
+ compatible = "syna,rmi4-i2c";
+ reg = <0x2c>;
+
+- interrupt-parent = <&msmgpio>;
++ interrupt-parent = <&tlmm>;
+ interrupts = <86 IRQ_TYPE_EDGE_FALLING>;
+
+ #address-cells = <1>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
+index f4a2e2560777..313c755f590f 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts
+@@ -305,7 +305,7 @@ sdhci@f98a4900 {
+ vmmc-supply = <&pm8941_l21>;
+ vqmmc-supply = <&pm8941_l13>;
+
+- cd-gpios = <&msmgpio 62 GPIO_ACTIVE_LOW>;
++ cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdhc2_pin_a>, <&sdhc2_cd_pin_a>;
+@@ -331,7 +331,7 @@ synaptics@2c {
+ compatible = "syna,rmi4-i2c";
+ reg = <0x2c>;
+
+- interrupts-extended = <&msmgpio 61 IRQ_TYPE_EDGE_FALLING>;
++ interrupts-extended = <&tlmm 61 IRQ_TYPE_EDGE_FALLING>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index d8a1ba5b845c..2182d2755926 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -955,11 +955,11 @@ wifi {
+ };
+ };
+
+- msmgpio: pinctrl@fd510000 {
++ tlmm: pinctrl@fd510000 {
+ compatible = "qcom,msm8974-pinctrl";
+ reg = <0xfd510000 0x4000>;
+ gpio-controller;
+- gpio-ranges = <&msmgpio 0 0 146>;
++ gpio-ranges = <&tlmm 0 0 146>;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+--
+2.35.1
+
--- /dev/null
+From 83a38cbef9f8dabe653a152952400ac72f17c723 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Apr 2022 22:10:30 +0200
+Subject: ARM: dts: qcom: msm8974-samsung-klte: move gpio-keys out of soc
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit c19865df6b142276ec4371ad534a1eb6fef5782d ]
+
+The GPIO keys are not part of SoC and they should be defined inside of
+the root node.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220401201035.189106-6-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/qcom-msm8974-samsung-klte.dts | 64 +++++++++----------
+ 1 file changed, 32 insertions(+), 32 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+index 96e1c978b878..6e036a440532 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts
+@@ -20,6 +20,38 @@ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
++ gpio-keys {
++ compatible = "gpio-keys";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&gpio_keys_pin_a>;
++
++ volume-down {
++ label = "volume_down";
++ gpios = <&pma8084_gpios 2 GPIO_ACTIVE_LOW>;
++ linux,input-type = <1>;
++ linux,code = <KEY_VOLUMEDOWN>;
++ debounce-interval = <15>;
++ };
++
++ home-key {
++ label = "home_key";
++ gpios = <&pma8084_gpios 3 GPIO_ACTIVE_LOW>;
++ linux,input-type = <1>;
++ linux,code = <KEY_HOMEPAGE>;
++ wakeup-source;
++ debounce-interval = <15>;
++ };
++
++ volume-up {
++ label = "volume_up";
++ gpios = <&pma8084_gpios 5 GPIO_ACTIVE_LOW>;
++ linux,input-type = <1>;
++ linux,code = <KEY_VOLUMEUP>;
++ debounce-interval = <15>;
++ };
++ };
++
+ smd {
+ rpm {
+ rpm_requests {
+@@ -347,38 +379,6 @@ bluetooth {
+ };
+ };
+
+- gpio-keys {
+- compatible = "gpio-keys";
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&gpio_keys_pin_a>;
+-
+- volume-down {
+- label = "volume_down";
+- gpios = <&pma8084_gpios 2 GPIO_ACTIVE_LOW>;
+- linux,input-type = <1>;
+- linux,code = <KEY_VOLUMEDOWN>;
+- debounce-interval = <15>;
+- };
+-
+- home-key {
+- label = "home_key";
+- gpios = <&pma8084_gpios 3 GPIO_ACTIVE_LOW>;
+- linux,input-type = <1>;
+- linux,code = <KEY_HOMEPAGE>;
+- wakeup-source;
+- debounce-interval = <15>;
+- };
+-
+- volume-up {
+- label = "volume_up";
+- gpios = <&pma8084_gpios 5 GPIO_ACTIVE_LOW>;
+- linux,input-type = <1>;
+- linux,code = <KEY_VOLUMEUP>;
+- debounce-interval = <15>;
+- };
+- };
+-
+ pinctrl@fd510000 {
+ blsp2_uart8_pins_active: blsp2-uart8-pins-active {
+ pins = "gpio45", "gpio46", "gpio47", "gpio48";
+--
+2.35.1
+
--- /dev/null
+From b03714edd61995af264a9214e3877d0b0a345bcb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 13:56:27 +0200
+Subject: ARM: dts: qcom-msm8974: Sort and clean up nodes
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit f300826d27be7f7f671c922bf57007c98c683590 ]
+
+- Remove regulators from the SoC DTSI
+- cpu_pmu{} -> pmu{}
+- move modem/iris regulators out of here; only FP2 used them
+- tcsr_mutex is moved out of /soc
+
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+[bjorn: Rebased on top of Krzysztof's fixes]
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220415115633.575010-18-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../arm/boot/dts/qcom-apq8074-dragonboard.dts | 4 +
+ .../boot/dts/qcom-msm8974-fairphone-fp2.dts | 12 +
+ .../qcom-msm8974-lge-nexus5-hammerhead.dts | 7 +
+ .../dts/qcom-msm8974-sony-xperia-castor.dts | 4 +
+ .../dts/qcom-msm8974-sony-xperia-rhine.dtsi | 6 +
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 1414 ++++++++---------
+ 6 files changed, 709 insertions(+), 738 deletions(-)
+
+diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+index f114debe4d95..f47020cf7a90 100644
+--- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
++++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+@@ -61,6 +61,8 @@ phy@b {
+
+ &rpm_requests {
+ pm8841-regulators {
++ compatible = "qcom,rpm-pm8841-regulators";
++
+ pm8841_s1: s1 {
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <1050000>;
+@@ -83,6 +85,8 @@ pm8841_s4: s4 {
+ };
+
+ pm8941-regulators {
++ compatible = "qcom,rpm-pm8941-regulators";
++
+ vdd_l1_l3-supply = <&pm8941_s1>;
+ vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+ vdd_l4_l11-supply = <&pm8941_s1>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+index 38e48ea021d9..d6799a1b820b 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-fairphone-fp2.dts
+@@ -109,10 +109,18 @@ &pronto {
+
+ vddmx-supply = <&pm8841_s1>;
+ vddcx-supply = <&pm8841_s2>;
++ vddpx-supply = <&pm8941_s3>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&wcnss_pin_a>;
+
++ iris {
++ vddxo-supply = <&pm8941_l6>;
++ vddrfa-supply = <&pm8941_l11>;
++ vddpa-supply = <&pm8941_l19>;
++ vdddig-supply = <&pm8941_s3>;
++ };
++
+ smd-edge {
+ qcom,remote-pid = <4>;
+ label = "pronto";
+@@ -125,6 +133,8 @@ wcnss {
+
+ &rpm_requests {
+ pm8841-regulators {
++ compatible = "qcom,rpm-pm8841-regulators";
++
+ pm8841_s1: s1 {
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <1050000>;
+@@ -142,6 +152,8 @@ pm8841_s3: s3 {
+ };
+
+ pm8941-regulators {
++ compatible = "qcom,rpm-pm8941-regulators";
++
+ vdd_l1_l3-supply = <&pm8941_s1>;
+ vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+ vdd_l4_l11-supply = <&pm8941_s1>;
+diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+index a1cae3d453c2..6537950c30ba 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+@@ -334,6 +334,8 @@ otg {
+
+ &rpm_requests {
+ pm8841-regulators {
++ compatible = "qcom,rpm-pm8841-regulators";
++
+ pm8841_s1: s1 {
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <1050000>;
+@@ -356,6 +358,8 @@ pm8841_s4: s4 {
+ };
+
+ pm8941-regulators {
++ compatible = "qcom,rpm-pm8941-regulators";
++
+ vdd_l1_l3-supply = <&pm8941_s1>;
+ vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+ vdd_l4_l11-supply = <&pm8941_s1>;
+@@ -517,6 +521,9 @@ pm8941_l24: l24 {
+ regulator-max-microvolt = <3075000>;
+ regulator-boot-on;
+ };
++
++ pm8941_lvs1: lvs1 {};
++ pm8941_lvs3: lvs3 {};
+ };
+ };
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
+index 687f6149268c..b8b6447b3217 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
++++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-castor.dts
+@@ -304,6 +304,8 @@ lcd_dcdc_en_pin_a: lcd-dcdc-en-active {
+
+ &rpm_requests {
+ pm8941-regulators {
++ compatible = "qcom,rpm-pm8941-regulators";
++
+ vdd_l1_l3-supply = <&pm8941_s1>;
+ vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+ vdd_l4_l11-supply = <&pm8941_s1>;
+@@ -465,6 +467,8 @@ pm8941_l24: l24 {
+ regulator-max-microvolt = <3075000>;
+ regulator-boot-on;
+ };
++
++ pm8941_lvs3: lvs3 {};
+ };
+ };
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-rhine.dtsi b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-rhine.dtsi
+index 87ec3694add9..870e0aeb4d05 100644
+--- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-rhine.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-rhine.dtsi
+@@ -153,6 +153,8 @@ &pm8941_wled {
+
+ &rpm_requests {
+ pm8841-regulators {
++ compatible = "qcom,rpm-pm8841-regulators";
++
+ pm8841_s1: s1 {
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <1050000>;
+@@ -175,6 +177,8 @@ pm8841_s4: s4 {
+ };
+
+ pm8941-regulators {
++ compatible = "qcom,rpm-pm8941-regulators";
++
+ vdd_l1_l3-supply = <&pm8941_s1>;
+ vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+ vdd_l4_l11-supply = <&pm8941_s1>;
+@@ -335,6 +339,8 @@ pm8941_l24: l24 {
+ regulator-max-microvolt = <3075000>;
+ regulator-boot-on;
+ };
++
++ pm8941_lvs3: lvs3 {};
+ };
+ };
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index e6c9782e4670..0091a4c29fff 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -16,57 +16,17 @@ / {
+ compatible = "qcom,msm8974";
+ interrupt-parent = <&intc>;
+
+- reserved-memory {
+- #address-cells = <1>;
+- #size-cells = <1>;
+- ranges;
+-
+- mpss_region: mpss@8000000 {
+- reg = <0x08000000 0x5100000>;
+- no-map;
+- };
+-
+- mba_region: mba@d100000 {
+- reg = <0x0d100000 0x100000>;
+- no-map;
+- };
+-
+- wcnss_region: wcnss@d200000 {
+- reg = <0x0d200000 0xa00000>;
+- no-map;
+- };
+-
+- adsp_region: adsp@dc00000 {
+- reg = <0x0dc00000 0x1900000>;
+- no-map;
+- };
+-
+- venus@f500000 {
+- reg = <0x0f500000 0x500000>;
+- no-map;
+- };
+-
+- smem_region: smem@fa00000 {
+- reg = <0xfa00000 0x200000>;
+- no-map;
+- };
+-
+- tz@fc00000 {
+- reg = <0x0fc00000 0x160000>;
+- no-map;
+- };
+-
+- rfsa@fd60000 {
+- reg = <0x0fd60000 0x20000>;
+- no-map;
++ clocks {
++ xo_board: xo_board {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <19200000>;
+ };
+
+- rmtfs@fd80000 {
+- compatible = "qcom,rmtfs-mem";
+- reg = <0x0fd80000 0x180000>;
+- no-map;
+-
+- qcom,client-id = <1>;
++ sleep_clk: sleep_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <32768>;
+ };
+ };
+
+@@ -136,211 +96,78 @@ CPU_SPC: spc {
+ };
+ };
+
++ firmware {
++ scm {
++ compatible = "qcom,scm";
++ clocks = <&gcc GCC_CE1_CLK>, <&gcc GCC_CE1_AXI_CLK>, <&gcc GCC_CE1_AHB_CLK>;
++ clock-names = "core", "bus", "iface";
++ };
++ };
++
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x0>;
+ };
+
+- thermal-zones {
+- cpu0-thermal {
+- polling-delay-passive = <250>;
+- polling-delay = <1000>;
+-
+- thermal-sensors = <&tsens 5>;
+-
+- trips {
+- cpu_alert0: trip0 {
+- temperature = <75000>;
+- hysteresis = <2000>;
+- type = "passive";
+- };
+- cpu_crit0: trip1 {
+- temperature = <110000>;
+- hysteresis = <2000>;
+- type = "critical";
+- };
+- };
+- };
+-
+- cpu1-thermal {
+- polling-delay-passive = <250>;
+- polling-delay = <1000>;
+-
+- thermal-sensors = <&tsens 6>;
+-
+- trips {
+- cpu_alert1: trip0 {
+- temperature = <75000>;
+- hysteresis = <2000>;
+- type = "passive";
+- };
+- cpu_crit1: trip1 {
+- temperature = <110000>;
+- hysteresis = <2000>;
+- type = "critical";
+- };
+- };
+- };
+-
+- cpu2-thermal {
+- polling-delay-passive = <250>;
+- polling-delay = <1000>;
++ pmu {
++ compatible = "qcom,krait-pmu";
++ interrupts = <GIC_PPI 7 0xf04>;
++ };
+
+- thermal-sensors = <&tsens 7>;
++ reserved-memory {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges;
+
+- trips {
+- cpu_alert2: trip0 {
+- temperature = <75000>;
+- hysteresis = <2000>;
+- type = "passive";
+- };
+- cpu_crit2: trip1 {
+- temperature = <110000>;
+- hysteresis = <2000>;
+- type = "critical";
+- };
+- };
++ mpss_region: mpss@8000000 {
++ reg = <0x08000000 0x5100000>;
++ no-map;
+ };
+
+- cpu3-thermal {
+- polling-delay-passive = <250>;
+- polling-delay = <1000>;
+-
+- thermal-sensors = <&tsens 8>;
+-
+- trips {
+- cpu_alert3: trip0 {
+- temperature = <75000>;
+- hysteresis = <2000>;
+- type = "passive";
+- };
+- cpu_crit3: trip1 {
+- temperature = <110000>;
+- hysteresis = <2000>;
+- type = "critical";
+- };
+- };
++ mba_region: mba@d100000 {
++ reg = <0x0d100000 0x100000>;
++ no-map;
+ };
+
+- q6-dsp-thermal {
+- polling-delay-passive = <250>;
+- polling-delay = <1000>;
+-
+- thermal-sensors = <&tsens 1>;
+-
+- trips {
+- q6_dsp_alert0: trip-point0 {
+- temperature = <90000>;
+- hysteresis = <2000>;
+- type = "hot";
+- };
+- };
++ wcnss_region: wcnss@d200000 {
++ reg = <0x0d200000 0xa00000>;
++ no-map;
+ };
+
+- modemtx-thermal {
+- polling-delay-passive = <250>;
+- polling-delay = <1000>;
+-
+- thermal-sensors = <&tsens 2>;
+-
+- trips {
+- modemtx_alert0: trip-point0 {
+- temperature = <90000>;
+- hysteresis = <2000>;
+- type = "hot";
+- };
+- };
++ adsp_region: adsp@dc00000 {
++ reg = <0x0dc00000 0x1900000>;
++ no-map;
+ };
+
+- video-thermal {
+- polling-delay-passive = <250>;
+- polling-delay = <1000>;
+-
+- thermal-sensors = <&tsens 3>;
+-
+- trips {
+- video_alert0: trip-point0 {
+- temperature = <95000>;
+- hysteresis = <2000>;
+- type = "hot";
+- };
+- };
++ venus_region: memory@f500000 {
++ reg = <0x0f500000 0x500000>;
++ no-map;
+ };
+
+- wlan-thermal {
+- polling-delay-passive = <250>;
+- polling-delay = <1000>;
+-
+- thermal-sensors = <&tsens 4>;
+-
+- trips {
+- wlan_alert0: trip-point0 {
+- temperature = <105000>;
+- hysteresis = <2000>;
+- type = "hot";
+- };
+- };
++ smem_region: smem@fa00000 {
++ reg = <0xfa00000 0x200000>;
++ no-map;
+ };
+
+- gpu-top-thermal {
+- polling-delay-passive = <250>;
+- polling-delay = <1000>;
+-
+- thermal-sensors = <&tsens 9>;
+-
+- trips {
+- gpu1_alert0: trip-point0 {
+- temperature = <90000>;
+- hysteresis = <2000>;
+- type = "hot";
+- };
+- };
++ tz_region: memory@fc00000 {
++ reg = <0x0fc00000 0x160000>;
++ no-map;
+ };
+
+- gpu-bottom-thermal {
+- polling-delay-passive = <250>;
+- polling-delay = <1000>;
+-
+- thermal-sensors = <&tsens 10>;
+-
+- trips {
+- gpu2_alert0: trip-point0 {
+- temperature = <90000>;
+- hysteresis = <2000>;
+- type = "hot";
+- };
+- };
++ rfsa_mem: memory@fd60000 {
++ reg = <0x0fd60000 0x20000>;
++ no-map;
+ };
+- };
+-
+- cpu-pmu {
+- compatible = "qcom,krait-pmu";
+- interrupts = <GIC_PPI 7 0xf04>;
+- };
+
+- clocks {
+- xo_board: xo_board {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-frequency = <19200000>;
+- };
++ rmtfs@fd80000 {
++ compatible = "qcom,rmtfs-mem";
++ reg = <0x0fd80000 0x180000>;
++ no-map;
+
+- sleep_clk: sleep_clk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-frequency = <32768>;
++ qcom,client-id = <1>;
+ };
+ };
+
+- timer {
+- compatible = "arm,armv7-timer";
+- interrupts = <GIC_PPI 2 0xf08>,
+- <GIC_PPI 3 0xf08>,
+- <GIC_PPI 4 0xf08>,
+- <GIC_PPI 1 0xf08>;
+- clock-frequency = <19200000>;
+- };
+-
+ smem {
+ compatible = "qcom,smem";
+
+@@ -467,11 +294,23 @@ wcnss_smsm: wcnss@7 {
+ };
+ };
+
+- firmware {
+- scm {
+- compatible = "qcom,scm";
+- clocks = <&gcc GCC_CE1_CLK>, <&gcc GCC_CE1_AXI_CLK>, <&gcc GCC_CE1_AHB_CLK>;
+- clock-names = "core", "bus", "iface";
++ smd {
++ compatible = "qcom,smd";
++
++ rpm {
++ interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
++ qcom,ipc = <&apcs 8 0>;
++ qcom,smd-edge = <15>;
++
++ rpm_requests: rpm_requests {
++ compatible = "qcom,rpm-msm8974";
++ qcom,smd-channels = "rpm_requests";
++
++ rpmcc: clock-controller {
++ compatible = "qcom,rpmcc-msm8974", "qcom,rpmcc";
++ #clock-cells = <1>;
++ };
++ };
+ };
+ };
+
+@@ -494,31 +333,6 @@ apcs: syscon@f9011000 {
+ reg = <0xf9011000 0x1000>;
+ };
+
+- qfprom: qfprom@fc4bc000 {
+- #address-cells = <1>;
+- #size-cells = <1>;
+- compatible = "qcom,qfprom";
+- reg = <0xfc4bc000 0x1000>;
+- tsens_calib: calib@d0 {
+- reg = <0xd0 0x18>;
+- };
+- tsens_backup: backup@440 {
+- reg = <0x440 0x10>;
+- };
+- };
+-
+- tsens: thermal-sensor@fc4a9000 {
+- compatible = "qcom,msm8974-tsens";
+- reg = <0xfc4a9000 0x1000>, /* TM */
+- <0xfc4a8000 0x1000>; /* SROT */
+- nvmem-cells = <&tsens_calib>, <&tsens_backup>;
+- nvmem-cell-names = "calib", "calib_backup";
+- #qcom,sensors = <11>;
+- interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "uplow";
+- #thermal-sensor-cells = <1>;
+- };
+-
+ timer@f9020000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+@@ -624,94 +438,6 @@ acc3: clock-controller@f90b8000 {
+ reg = <0xf90b8000 0x1000>, <0xf9008000 0x1000>;
+ };
+
+- restart@fc4ab000 {
+- compatible = "qcom,pshold";
+- reg = <0xfc4ab000 0x4>;
+- };
+-
+- gcc: clock-controller@fc400000 {
+- compatible = "qcom,gcc-msm8974";
+- #clock-cells = <1>;
+- #reset-cells = <1>;
+- #power-domain-cells = <1>;
+- reg = <0xfc400000 0x4000>;
+- };
+-
+- tcsr: syscon@fd4a0000 {
+- compatible = "syscon";
+- reg = <0xfd4a0000 0x10000>;
+- };
+-
+- tcsr_mutex_block: syscon@fd484000 {
+- compatible = "syscon";
+- reg = <0xfd484000 0x2000>;
+- };
+-
+- mmcc: clock-controller@fd8c0000 {
+- compatible = "qcom,mmcc-msm8974";
+- #clock-cells = <1>;
+- #reset-cells = <1>;
+- #power-domain-cells = <1>;
+- reg = <0xfd8c0000 0x6000>;
+- };
+-
+- tcsr_mutex: tcsr-mutex {
+- compatible = "qcom,tcsr-mutex";
+- syscon = <&tcsr_mutex_block 0 0x80>;
+-
+- #hwlock-cells = <1>;
+- };
+-
+- rpm_msg_ram: memory@fc428000 {
+- compatible = "qcom,rpm-msg-ram";
+- reg = <0xfc428000 0x4000>;
+- };
+-
+- blsp1_uart1: serial@f991d000 {
+- compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+- reg = <0xf991d000 0x1000>;
+- interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&gcc GCC_BLSP1_UART1_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
+- clock-names = "core", "iface";
+- status = "disabled";
+- };
+-
+- blsp1_uart2: serial@f991e000 {
+- compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+- reg = <0xf991e000 0x1000>;
+- interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
+- clock-names = "core", "iface";
+- status = "disabled";
+- };
+-
+- blsp2_uart1: serial@f995d000 {
+- compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+- reg = <0xf995d000 0x1000>;
+- interrupts = <GIC_SPI 113 IRQ_TYPE_NONE>;
+- clocks = <&gcc GCC_BLSP2_UART1_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
+- clock-names = "core", "iface";
+- status = "disabled";
+- };
+-
+- blsp2_uart2: serial@f995e000 {
+- compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+- reg = <0xf995e000 0x1000>;
+- interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&gcc GCC_BLSP2_UART2_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
+- clock-names = "core", "iface";
+- status = "disabled";
+- };
+-
+- blsp2_uart4: serial@f9960000 {
+- compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+- reg = <0xf9960000 0x1000>;
+- interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&gcc GCC_BLSP2_UART4_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
+- clock-names = "core", "iface";
+- status = "disabled";
+- };
+-
+ sdhc_1: sdhci@f9824900 {
+ compatible = "qcom,msm8974-sdhci", "qcom,sdhci-msm-v4";
+ reg = <0xf9824900 0x11c>, <0xf9824000 0x800>;
+@@ -758,182 +484,25 @@ sdhc_2: sdhci@f98a4900 {
+ clock-names = "core", "iface", "xo";
+ bus-width = <4>;
+
+- status = "disabled";
+- };
+-
+- otg: usb@f9a55000 {
+- compatible = "qcom,ci-hdrc";
+- reg = <0xf9a55000 0x200>,
+- <0xf9a55200 0x200>;
+- interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&gcc GCC_USB_HS_AHB_CLK>,
+- <&gcc GCC_USB_HS_SYSTEM_CLK>;
+- clock-names = "iface", "core";
+- assigned-clocks = <&gcc GCC_USB_HS_SYSTEM_CLK>;
+- assigned-clock-rates = <75000000>;
+- resets = <&gcc GCC_USB_HS_BCR>;
+- reset-names = "core";
+- phy_type = "ulpi";
+- dr_mode = "otg";
+- ahb-burst-config = <0>;
+- phy-names = "usb-phy";
+- status = "disabled";
+- #reset-cells = <1>;
+-
+- ulpi {
+- usb_hs1_phy: phy@a {
+- compatible = "qcom,usb-hs-phy-msm8974",
+- "qcom,usb-hs-phy";
+- #phy-cells = <0>;
+- clocks = <&xo_board>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>;
+- clock-names = "ref", "sleep";
+- resets = <&gcc GCC_USB2A_PHY_BCR>, <&otg 0>;
+- reset-names = "phy", "por";
+- status = "disabled";
+- };
+-
+- usb_hs2_phy: phy@b {
+- compatible = "qcom,usb-hs-phy-msm8974",
+- "qcom,usb-hs-phy";
+- #phy-cells = <0>;
+- clocks = <&xo_board>, <&gcc GCC_USB2B_PHY_SLEEP_CLK>;
+- clock-names = "ref", "sleep";
+- resets = <&gcc GCC_USB2B_PHY_BCR>, <&otg 1>;
+- reset-names = "phy", "por";
+- status = "disabled";
+- };
+- };
+- };
+-
+- rng@f9bff000 {
+- compatible = "qcom,prng";
+- reg = <0xf9bff000 0x200>;
+- clocks = <&gcc GCC_PRNG_AHB_CLK>;
+- clock-names = "core";
+- };
+-
+- remoteproc_mss: remoteproc@fc880000 {
+- compatible = "qcom,msm8974-mss-pil";
+- reg = <0xfc880000 0x100>, <0xfc820000 0x020>;
+- reg-names = "qdsp6", "rmb";
+-
+- interrupts-extended = <&intc GIC_SPI 24 IRQ_TYPE_EDGE_RISING>,
+- <&modem_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+- <&modem_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+- <&modem_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+- <&modem_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack";
+-
+- clocks = <&gcc GCC_MSS_Q6_BIMC_AXI_CLK>,
+- <&gcc GCC_MSS_CFG_AHB_CLK>,
+- <&gcc GCC_BOOT_ROM_AHB_CLK>,
+- <&xo_board>;
+- clock-names = "iface", "bus", "mem", "xo";
+-
+- resets = <&gcc GCC_MSS_RESTART>;
+- reset-names = "mss_restart";
+-
+- cx-supply = <&pm8841_s2>;
+- mss-supply = <&pm8841_s3>;
+- mx-supply = <&pm8841_s1>;
+- pll-supply = <&pm8941_l12>;
+-
+- qcom,halt-regs = <&tcsr_mutex_block 0x1180 0x1200 0x1280>;
+-
+- qcom,smem-states = <&modem_smp2p_out 0>;
+- qcom,smem-state-names = "stop";
+-
+- mba {
+- memory-region = <&mba_region>;
+- };
+-
+- mpss {
+- memory-region = <&mpss_region>;
+- };
+-
+- smd-edge {
+- interrupts = <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>;
+-
+- qcom,ipc = <&apcs 8 12>;
+- qcom,smd-edge = <0>;
+-
+- label = "modem";
+- };
+- };
+-
+- pronto: remoteproc@fb21b000 {
+- compatible = "qcom,pronto-v2-pil", "qcom,pronto";
+- reg = <0xfb204000 0x2000>, <0xfb202000 0x1000>, <0xfb21b000 0x3000>;
+- reg-names = "ccu", "dxe", "pmu";
+-
+- memory-region = <&wcnss_region>;
+-
+- interrupts-extended = <&intc GIC_SPI 149 IRQ_TYPE_EDGE_RISING>,
+- <&wcnss_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+- <&wcnss_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+- <&wcnss_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+- <&wcnss_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack";
+-
+- vddpx-supply = <&pm8941_s3>;
+-
+- qcom,smem-states = <&wcnss_smp2p_out 0>;
+- qcom,smem-state-names = "stop";
+-
+- status = "disabled";
+-
+- iris {
+- compatible = "qcom,wcn3680";
+-
+- clocks = <&rpmcc RPM_SMD_CXO_A2>;
+- clock-names = "xo";
+-
+- vddxo-supply = <&pm8941_l6>;
+- vddrfa-supply = <&pm8941_l11>;
+- vddpa-supply = <&pm8941_l19>;
+- vdddig-supply = <&pm8941_s3>;
+- };
+-
+- smd-edge {
+- interrupts = <GIC_SPI 142 IRQ_TYPE_EDGE_RISING>;
+-
+- qcom,ipc = <&apcs 8 17>;
+- qcom,smd-edge = <6>;
+-
+- wcnss {
+- compatible = "qcom,wcnss";
+- qcom,smd-channels = "WCNSS_CTRL";
+- status = "disabled";
+-
+- qcom,mmio = <&pronto>;
+-
+- bt {
+- compatible = "qcom,wcnss-bt";
+- };
+-
+- wifi {
+- compatible = "qcom,wcnss-wlan";
+-
+- interrupts = <GIC_SPI 145 IRQ_TYPE_EDGE_RISING>,
+- <GIC_SPI 146 IRQ_TYPE_EDGE_RISING>;
+- interrupt-names = "tx", "rx";
++ status = "disabled";
++ };
+
+- qcom,smem-states = <&apps_smsm 10>, <&apps_smsm 9>;
+- qcom,smem-state-names = "tx-enable", "tx-rings-empty";
+- };
+- };
+- };
++ blsp1_uart1: serial@f991d000 {
++ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
++ reg = <0xf991d000 0x1000>;
++ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&gcc GCC_BLSP1_UART1_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
++ clock-names = "core", "iface";
++ status = "disabled";
+ };
+
+- tlmm: pinctrl@fd510000 {
+- compatible = "qcom,msm8974-pinctrl";
+- reg = <0xfd510000 0x4000>;
+- gpio-controller;
+- gpio-ranges = <&tlmm 0 0 146>;
+- #gpio-cells = <2>;
+- interrupt-controller;
+- #interrupt-cells = <2>;
+- interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
++ blsp1_uart2: serial@f991e000 {
++ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
++ reg = <0xf991e000 0x1000>;
++ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
++ clock-names = "core", "iface";
++ status = "disabled";
+ };
+
+ blsp1_i2c1: i2c@f9923000 {
+@@ -980,6 +549,43 @@ blsp1_i2c6: i2c@f9928000 {
+ #size-cells = <0>;
+ };
+
++ blsp2_dma: dma-controller@f9944000 {
++ compatible = "qcom,bam-v1.4.0";
++ reg = <0xf9944000 0x19000>;
++ interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&gcc GCC_BLSP2_AHB_CLK>;
++ clock-names = "bam_clk";
++ #dma-cells = <1>;
++ qcom,ee = <0>;
++ };
++
++ blsp2_uart1: serial@f995d000 {
++ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
++ reg = <0xf995d000 0x1000>;
++ interrupts = <GIC_SPI 113 IRQ_TYPE_NONE>;
++ clocks = <&gcc GCC_BLSP2_UART1_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
++ clock-names = "core", "iface";
++ status = "disabled";
++ };
++
++ blsp2_uart2: serial@f995e000 {
++ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
++ reg = <0xf995e000 0x1000>;
++ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&gcc GCC_BLSP2_UART2_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
++ clock-names = "core", "iface";
++ status = "disabled";
++ };
++
++ blsp2_uart4: serial@f9960000 {
++ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
++ reg = <0xf9960000 0x1000>;
++ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&gcc GCC_BLSP2_UART4_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
++ clock-names = "core", "iface";
++ status = "disabled";
++ };
++
+ blsp2_i2c2: i2c@f9964000 {
+ status = "disabled";
+ compatible = "qcom,i2c-qup-v2.1.1";
+@@ -1015,93 +621,110 @@ blsp2_i2c6: i2c@f9968000 {
+ #size-cells = <0>;
+ };
+
+- spmi_bus: spmi@fc4cf000 {
+- compatible = "qcom,spmi-pmic-arb";
+- reg-names = "core", "intr", "cnfg";
+- reg = <0xfc4cf000 0x1000>,
+- <0xfc4cb000 0x1000>,
+- <0xfc4ca000 0x1000>;
+- interrupt-names = "periph_irq";
+- interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+- qcom,ee = <0>;
+- qcom,channel = <0>;
+- #address-cells = <2>;
+- #size-cells = <0>;
+- interrupt-controller;
+- #interrupt-cells = <4>;
++ otg: usb@f9a55000 {
++ compatible = "qcom,ci-hdrc";
++ reg = <0xf9a55000 0x200>,
++ <0xf9a55200 0x200>;
++ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&gcc GCC_USB_HS_AHB_CLK>,
++ <&gcc GCC_USB_HS_SYSTEM_CLK>;
++ clock-names = "iface", "core";
++ assigned-clocks = <&gcc GCC_USB_HS_SYSTEM_CLK>;
++ assigned-clock-rates = <75000000>;
++ resets = <&gcc GCC_USB_HS_BCR>;
++ reset-names = "core";
++ phy_type = "ulpi";
++ dr_mode = "otg";
++ ahb-burst-config = <0>;
++ phy-names = "usb-phy";
++ status = "disabled";
++ #reset-cells = <1>;
++
++ ulpi {
++ usb_hs1_phy: phy@a {
++ compatible = "qcom,usb-hs-phy-msm8974",
++ "qcom,usb-hs-phy";
++ #phy-cells = <0>;
++ clocks = <&xo_board>, <&gcc GCC_USB2A_PHY_SLEEP_CLK>;
++ clock-names = "ref", "sleep";
++ resets = <&gcc GCC_USB2A_PHY_BCR>, <&otg 0>;
++ reset-names = "phy", "por";
++ status = "disabled";
++ };
++
++ usb_hs2_phy: phy@b {
++ compatible = "qcom,usb-hs-phy-msm8974",
++ "qcom,usb-hs-phy";
++ #phy-cells = <0>;
++ clocks = <&xo_board>, <&gcc GCC_USB2B_PHY_SLEEP_CLK>;
++ clock-names = "ref", "sleep";
++ resets = <&gcc GCC_USB2B_PHY_BCR>, <&otg 1>;
++ reset-names = "phy", "por";
++ status = "disabled";
++ };
++ };
+ };
+
+- blsp2_dma: dma-controller@f9944000 {
+- compatible = "qcom,bam-v1.4.0";
+- reg = <0xf9944000 0x19000>;
+- interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&gcc GCC_BLSP2_AHB_CLK>;
+- clock-names = "bam_clk";
+- #dma-cells = <1>;
+- qcom,ee = <0>;
++ rng@f9bff000 {
++ compatible = "qcom,prng";
++ reg = <0xf9bff000 0x200>;
++ clocks = <&gcc GCC_PRNG_AHB_CLK>;
++ clock-names = "core";
+ };
+
+- etr@fc322000 {
+- compatible = "arm,coresight-tmc", "arm,primecell";
+- reg = <0xfc322000 0x1000>;
++ pronto: remoteproc@fb21b000 {
++ compatible = "qcom,pronto-v2-pil", "qcom,pronto";
++ reg = <0xfb204000 0x2000>, <0xfb202000 0x1000>, <0xfb21b000 0x3000>;
++ reg-names = "ccu", "dxe", "pmu";
+
+- clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+- clock-names = "apb_pclk", "atclk";
++ memory-region = <&wcnss_region>;
+
+- in-ports {
+- port {
+- etr_in: endpoint {
+- remote-endpoint = <&replicator_out0>;
+- };
+- };
+- };
+- };
++ interrupts-extended = <&intc GIC_SPI 149 IRQ_TYPE_EDGE_RISING>,
++ <&wcnss_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
++ <&wcnss_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
++ <&wcnss_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
++ <&wcnss_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack";
+
+- tpiu@fc318000 {
+- compatible = "arm,coresight-tpiu", "arm,primecell";
+- reg = <0xfc318000 0x1000>;
++ qcom,smem-states = <&wcnss_smp2p_out 0>;
++ qcom,smem-state-names = "stop";
+
+- clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+- clock-names = "apb_pclk", "atclk";
++ status = "disabled";
+
+- in-ports {
+- port {
+- tpiu_in: endpoint {
+- remote-endpoint = <&replicator_out1>;
+- };
+- };
++ iris {
++ compatible = "qcom,wcn3680";
++
++ clocks = <&rpmcc RPM_SMD_CXO_A2>;
++ clock-names = "xo";
+ };
+- };
+
+- replicator@fc31c000 {
+- compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+- reg = <0xfc31c000 0x1000>;
++ smd-edge {
++ interrupts = <GIC_SPI 142 IRQ_TYPE_EDGE_RISING>;
+
+- clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+- clock-names = "apb_pclk", "atclk";
++ qcom,ipc = <&apcs 8 17>;
++ qcom,smd-edge = <6>;
+
+- out-ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
++ wcnss {
++ compatible = "qcom,wcnss";
++ qcom,smd-channels = "WCNSS_CTRL";
++ status = "disabled";
+
+- port@0 {
+- reg = <0>;
+- replicator_out0: endpoint {
+- remote-endpoint = <&etr_in>;
+- };
+- };
+- port@1 {
+- reg = <1>;
+- replicator_out1: endpoint {
+- remote-endpoint = <&tpiu_in>;
++ qcom,mmio = <&pronto>;
++
++ bt {
++ compatible = "qcom,wcnss-bt";
+ };
+- };
+- };
+
+- in-ports {
+- port {
+- replicator_in: endpoint {
+- remote-endpoint = <&etf_out>;
++ wifi {
++ compatible = "qcom,wcnss-wlan";
++
++ interrupts = <GIC_SPI 145 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 146 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "tx", "rx";
++
++ qcom,smem-states = <&apps_smsm 10>, <&apps_smsm 9>;
++ qcom,smem-state-names = "tx-enable",
++ "tx-rings-empty";
+ };
+ };
+ };
+@@ -1131,37 +754,19 @@ etf_in: endpoint {
+ };
+ };
+
+- funnel@fc31b000 {
+- compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+- reg = <0xfc31b000 0x1000>;
++ tpiu@fc318000 {
++ compatible = "arm,coresight-tpiu", "arm,primecell";
++ reg = <0xfc318000 0x1000>;
+
+ clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "atclk";
+
+ in-ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- /*
+- * Not described input ports:
+- * 0 - connected trought funnel to Audio, Modem and
+- * Resource and Power Manager CPU's
+- * 2...7 - not-connected
+- */
+- port@1 {
+- reg = <1>;
+- merger_in1: endpoint {
+- remote-endpoint = <&funnel1_out>;
+- };
+- };
+- };
+-
+- out-ports {
+ port {
+- merger_out: endpoint {
+- remote-endpoint = <&etf_in>;
++ tpiu_in: endpoint {
++ remote-endpoint = <&replicator_out1>;
+ };
+- };
++ };
+ };
+ };
+
+@@ -1203,9 +808,9 @@ funnel1_out: endpoint {
+ };
+ };
+
+- funnel@fc345000 { /* KPSS funnel only 4 inputs are used */
++ funnel@fc31b000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+- reg = <0xfc345000 0x1000>;
++ reg = <0xfc31b000 0x1000>;
+
+ clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "atclk";
+@@ -1214,36 +819,74 @@ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
++ /*
++ * Not described input ports:
++ * 0 - connected trought funnel to Audio, Modem and
++ * Resource and Power Manager CPU's
++ * 2...7 - not-connected
++ */
++ port@1 {
++ reg = <1>;
++ merger_in1: endpoint {
++ remote-endpoint = <&funnel1_out>;
++ };
++ };
++ };
++
++ out-ports {
++ port {
++ merger_out: endpoint {
++ remote-endpoint = <&etf_in>;
++ };
++ };
++ };
++ };
++
++ replicator@fc31c000 {
++ compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
++ reg = <0xfc31c000 0x1000>;
++
++ clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
++ clock-names = "apb_pclk", "atclk";
++
++ out-ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
+ port@0 {
+ reg = <0>;
+- kpss_in0: endpoint {
+- remote-endpoint = <&etm0_out>;
++ replicator_out0: endpoint {
++ remote-endpoint = <&etr_in>;
+ };
+ };
+ port@1 {
+ reg = <1>;
+- kpss_in1: endpoint {
+- remote-endpoint = <&etm1_out>;
+- };
+- };
+- port@2 {
+- reg = <2>;
+- kpss_in2: endpoint {
+- remote-endpoint = <&etm2_out>;
++ replicator_out1: endpoint {
++ remote-endpoint = <&tpiu_in>;
+ };
+ };
+- port@3 {
+- reg = <3>;
+- kpss_in3: endpoint {
+- remote-endpoint = <&etm3_out>;
++ };
++
++ in-ports {
++ port {
++ replicator_in: endpoint {
++ remote-endpoint = <&etf_out>;
+ };
+ };
+ };
++ };
+
+- out-ports {
++ etr@fc322000 {
++ compatible = "arm,coresight-tmc", "arm,primecell";
++ reg = <0xfc322000 0x1000>;
++
++ clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
++ clock-names = "apb_pclk", "atclk";
++
++ in-ports {
+ port {
+- kpss_out: endpoint {
+- remote-endpoint = <&funnel1_in5>;
++ etr_in: endpoint {
++ remote-endpoint = <&replicator_out0>;
+ };
+ };
+ };
+@@ -1321,25 +964,66 @@ etm3_out: endpoint {
+ };
+ };
+
+- ocmem@fdd00000 {
+- compatible = "qcom,msm8974-ocmem";
+- reg = <0xfdd00000 0x2000>,
+- <0xfec00000 0x180000>;
+- reg-names = "ctrl",
+- "mem";
+- clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>,
+- <&mmcc OCMEMCX_OCMEMNOC_CLK>;
+- clock-names = "core",
+- "iface";
++ /* KPSS funnel, only 4 inputs are used */
++ funnel@fc345000 {
++ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
++ reg = <0xfc345000 0x1000>;
+
+- #address-cells = <1>;
+- #size-cells = <1>;
++ clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
++ clock-names = "apb_pclk", "atclk";
+
+- gmu_sram: gmu-sram@0 {
+- reg = <0x0 0x100000>;
++ in-ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ kpss_in0: endpoint {
++ remote-endpoint = <&etm0_out>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ kpss_in1: endpoint {
++ remote-endpoint = <&etm1_out>;
++ };
++ };
++ port@2 {
++ reg = <2>;
++ kpss_in2: endpoint {
++ remote-endpoint = <&etm2_out>;
++ };
++ };
++ port@3 {
++ reg = <3>;
++ kpss_in3: endpoint {
++ remote-endpoint = <&etm3_out>;
++ };
++ };
++ };
++
++ out-ports {
++ port {
++ kpss_out: endpoint {
++ remote-endpoint = <&funnel1_in5>;
++ };
++ };
+ };
+ };
+
++ gcc: clock-controller@fc400000 {
++ compatible = "qcom,gcc-msm8974";
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ #power-domain-cells = <1>;
++ reg = <0xfc400000 0x4000>;
++ };
++
++ rpm_msg_ram: memory@fc428000 {
++ compatible = "qcom,rpm-msg-ram";
++ reg = <0xfc428000 0x4000>;
++ };
++
+ bimc: interconnect@fc380000 {
+ reg = <0xfc380000 0x6a000>;
+ compatible = "qcom,msm8974-bimc";
+@@ -1394,47 +1078,123 @@ cnoc: interconnect@fc480000 {
+ <&rpmcc RPM_SMD_CNOC_A_CLK>;
+ };
+
+- gpu: adreno@fdb00000 {
+- status = "disabled";
++ tsens: thermal-sensor@fc4a9000 {
++ compatible = "qcom,msm8974-tsens";
++ reg = <0xfc4a9000 0x1000>, /* TM */
++ <0xfc4a8000 0x1000>; /* SROT */
++ nvmem-cells = <&tsens_calib>, <&tsens_backup>;
++ nvmem-cell-names = "calib", "calib_backup";
++ #qcom,sensors = <11>;
++ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "uplow";
++ #thermal-sensor-cells = <1>;
++ };
+
+- compatible = "qcom,adreno-330.1",
+- "qcom,adreno";
+- reg = <0xfdb00000 0x10000>;
+- reg-names = "kgsl_3d0_reg_memory";
+- interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "kgsl_3d0_irq";
+- clock-names = "core",
+- "iface",
+- "mem_iface";
+- clocks = <&mmcc OXILI_GFX3D_CLK>,
+- <&mmcc OXILICX_AHB_CLK>,
+- <&mmcc OXILICX_AXI_CLK>;
+- sram = <&gmu_sram>;
+- power-domains = <&mmcc OXILICX_GDSC>;
+- operating-points-v2 = <&gpu_opp_table>;
++ restart@fc4ab000 {
++ compatible = "qcom,pshold";
++ reg = <0xfc4ab000 0x4>;
++ };
+
+- interconnects = <&mmssnoc MNOC_MAS_GRAPHICS_3D &bimc BIMC_SLV_EBI_CH0>,
+- <&ocmemnoc OCMEM_VNOC_MAS_GFX3D &ocmemnoc OCMEM_SLV_OCMEM>;
+- interconnect-names = "gfx-mem",
+- "ocmem";
++ qfprom: qfprom@fc4bc000 {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ compatible = "qcom,qfprom";
++ reg = <0xfc4bc000 0x1000>;
++ tsens_calib: calib@d0 {
++ reg = <0xd0 0x18>;
++ };
++ tsens_backup: backup@440 {
++ reg = <0x440 0x10>;
++ };
++ };
+
+- // iommus = <&gpu_iommu 0>;
++ spmi_bus: spmi@fc4cf000 {
++ compatible = "qcom,spmi-pmic-arb";
++ reg-names = "core", "intr", "cnfg";
++ reg = <0xfc4cf000 0x1000>,
++ <0xfc4cb000 0x1000>,
++ <0xfc4ca000 0x1000>;
++ interrupt-names = "periph_irq";
++ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
++ qcom,ee = <0>;
++ qcom,channel = <0>;
++ #address-cells = <2>;
++ #size-cells = <0>;
++ interrupt-controller;
++ #interrupt-cells = <4>;
++ };
+
+- gpu_opp_table: opp_table {
+- compatible = "operating-points-v2";
++ remoteproc_mss: remoteproc@fc880000 {
++ compatible = "qcom,msm8974-mss-pil";
++ reg = <0xfc880000 0x100>, <0xfc820000 0x020>;
++ reg-names = "qdsp6", "rmb";
+
+- opp-320000000 {
+- opp-hz = /bits/ 64 <320000000>;
+- };
++ interrupts-extended = <&intc GIC_SPI 24 IRQ_TYPE_EDGE_RISING>,
++ <&modem_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
++ <&modem_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
++ <&modem_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
++ <&modem_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack";
+
+- opp-200000000 {
+- opp-hz = /bits/ 64 <200000000>;
+- };
++ clocks = <&gcc GCC_MSS_Q6_BIMC_AXI_CLK>,
++ <&gcc GCC_MSS_CFG_AHB_CLK>,
++ <&gcc GCC_BOOT_ROM_AHB_CLK>,
++ <&xo_board>;
++ clock-names = "iface", "bus", "mem", "xo";
++
++ resets = <&gcc GCC_MSS_RESTART>;
++ reset-names = "mss_restart";
++
++ qcom,halt-regs = <&tcsr_mutex_block 0x1180 0x1200 0x1280>;
++
++ qcom,smem-states = <&modem_smp2p_out 0>;
++ qcom,smem-state-names = "stop";
++
++ mba {
++ memory-region = <&mba_region>;
++ };
++
++ mpss {
++ memory-region = <&mpss_region>;
++ };
++
++ smd-edge {
++ interrupts = <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>;
++
++ qcom,ipc = <&apcs 8 12>;
++ qcom,smd-edge = <0>;
++
++ label = "modem";
++ };
++ };
++
++ tcsr_mutex_block: syscon@fd484000 {
++ compatible = "syscon";
++ reg = <0xfd484000 0x2000>;
++ };
++
++ tcsr: syscon@fd4a0000 {
++ compatible = "syscon";
++ reg = <0xfd4a0000 0x10000>;
++ };
++
++ tlmm: pinctrl@fd510000 {
++ compatible = "qcom,msm8974-pinctrl";
++ reg = <0xfd510000 0x4000>;
++ gpio-controller;
++ gpio-ranges = <&tlmm 0 0 146>;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
++ };
+
+- opp-27000000 {
+- opp-hz = /bits/ 64 <27000000>;
+- };
+- };
++ mmcc: clock-controller@fd8c0000 {
++ compatible = "qcom,mmcc-msm8974";
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ #power-domain-cells = <1>;
++ reg = <0xfd8c0000 0x6000>;
+ };
+
+ mdss: mdss@fd900000 {
+@@ -1562,6 +1322,65 @@ dsi0_phy: dsi-phy@fd922a00 {
+ };
+ };
+
++ gpu: adreno@fdb00000 {
++ compatible = "qcom,adreno-330.1", "qcom,adreno";
++ reg = <0xfdb00000 0x10000>;
++ reg-names = "kgsl_3d0_reg_memory";
++
++ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "kgsl_3d0_irq";
++
++ clocks = <&mmcc OXILI_GFX3D_CLK>,
++ <&mmcc OXILICX_AHB_CLK>,
++ <&mmcc OXILICX_AXI_CLK>;
++ clock-names = "core", "iface", "mem_iface";
++
++ sram = <&gmu_sram>;
++ power-domains = <&mmcc OXILICX_GDSC>;
++ operating-points-v2 = <&gpu_opp_table>;
++
++ interconnects = <&mmssnoc MNOC_MAS_GRAPHICS_3D &bimc BIMC_SLV_EBI_CH0>,
++ <&ocmemnoc OCMEM_VNOC_MAS_GFX3D &ocmemnoc OCMEM_SLV_OCMEM>;
++ interconnect-names = "gfx-mem", "ocmem";
++
++ // iommus = <&gpu_iommu 0>;
++
++ status = "disabled";
++
++ gpu_opp_table: opp_table {
++ compatible = "operating-points-v2";
++
++ opp-320000000 {
++ opp-hz = /bits/ 64 <320000000>;
++ };
++
++ opp-200000000 {
++ opp-hz = /bits/ 64 <200000000>;
++ };
++
++ opp-27000000 {
++ opp-hz = /bits/ 64 <27000000>;
++ };
++ };
++ };
++
++ ocmem@fdd00000 {
++ compatible = "qcom,msm8974-ocmem";
++ reg = <0xfdd00000 0x2000>,
++ <0xfec00000 0x180000>;
++ reg-names = "ctrl", "mem";
++ clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>,
++ <&mmcc OCMEMCX_OCMEMNOC_CLK>;
++ clock-names = "core", "iface";
++
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ gmu_sram: gmu-sram@0 {
++ reg = <0x0 0x100000>;
++ };
++ };
++
+ remoteproc_adsp: remoteproc@fe200000 {
+ compatible = "qcom,msm8974-adsp-pil";
+ reg = <0xfe200000 0x100>;
+@@ -1604,76 +1423,194 @@ reboot-mode {
+ };
+ };
+
+- smd {
+- compatible = "qcom,smd";
++ tcsr_mutex: tcsr-mutex {
++ compatible = "qcom,tcsr-mutex";
++ syscon = <&tcsr_mutex_block 0 0x80>;
+
+- rpm {
+- interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
+- qcom,ipc = <&apcs 8 0>;
+- qcom,smd-edge = <15>;
++ #hwlock-cells = <1>;
++ };
+
+- rpm_requests: rpm-requests {
+- compatible = "qcom,rpm-msm8974";
+- qcom,smd-channels = "rpm_requests";
++ thermal-zones {
++ cpu0-thermal {
++ polling-delay-passive = <250>;
++ polling-delay = <1000>;
+
+- rpmcc: clock-controller {
+- compatible = "qcom,rpmcc-msm8974", "qcom,rpmcc";
+- #clock-cells = <1>;
++ thermal-sensors = <&tsens 5>;
++
++ trips {
++ cpu_alert0: trip0 {
++ temperature = <75000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++ cpu_crit0: trip1 {
++ temperature = <110000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
++ };
++
++ cpu1-thermal {
++ polling-delay-passive = <250>;
++ polling-delay = <1000>;
++
++ thermal-sensors = <&tsens 6>;
++
++ trips {
++ cpu_alert1: trip0 {
++ temperature = <75000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++ cpu_crit1: trip1 {
++ temperature = <110000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
++ };
++
++ cpu2-thermal {
++ polling-delay-passive = <250>;
++ polling-delay = <1000>;
++
++ thermal-sensors = <&tsens 7>;
++
++ trips {
++ cpu_alert2: trip0 {
++ temperature = <75000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++ cpu_crit2: trip1 {
++ temperature = <110000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
++ };
++
++ cpu3-thermal {
++ polling-delay-passive = <250>;
++ polling-delay = <1000>;
++
++ thermal-sensors = <&tsens 8>;
++
++ trips {
++ cpu_alert3: trip0 {
++ temperature = <75000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++ cpu_crit3: trip1 {
++ temperature = <110000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
++ };
++
++ q6-dsp-thermal {
++ polling-delay-passive = <250>;
++ polling-delay = <1000>;
++
++ thermal-sensors = <&tsens 1>;
++
++ trips {
++ q6_dsp_alert0: trip-point0 {
++ temperature = <90000>;
++ hysteresis = <2000>;
++ type = "hot";
++ };
++ };
++ };
++
++ modemtx-thermal {
++ polling-delay-passive = <250>;
++ polling-delay = <1000>;
++
++ thermal-sensors = <&tsens 2>;
++
++ trips {
++ modemtx_alert0: trip-point0 {
++ temperature = <90000>;
++ hysteresis = <2000>;
++ type = "hot";
++ };
++ };
++ };
++
++ video-thermal {
++ polling-delay-passive = <250>;
++ polling-delay = <1000>;
++
++ thermal-sensors = <&tsens 3>;
++
++ trips {
++ video_alert0: trip-point0 {
++ temperature = <95000>;
++ hysteresis = <2000>;
++ type = "hot";
++ };
++ };
++ };
++
++ wlan-thermal {
++ polling-delay-passive = <250>;
++ polling-delay = <1000>;
++
++ thermal-sensors = <&tsens 4>;
++
++ trips {
++ wlan_alert0: trip-point0 {
++ temperature = <105000>;
++ hysteresis = <2000>;
++ type = "hot";
+ };
++ };
++ };
++
++ gpu-top-thermal {
++ polling-delay-passive = <250>;
++ polling-delay = <1000>;
++
++ thermal-sensors = <&tsens 9>;
+
+- pm8841-regulators {
+- compatible = "qcom,rpm-pm8841-regulators";
+-
+- pm8841_s1: s1 {};
+- pm8841_s2: s2 {};
+- pm8841_s3: s3 {};
+- pm8841_s4: s4 {};
+- pm8841_s5: s5 {};
+- pm8841_s6: s6 {};
+- pm8841_s7: s7 {};
+- pm8841_s8: s8 {};
++ trips {
++ gpu1_alert0: trip-point0 {
++ temperature = <90000>;
++ hysteresis = <2000>;
++ type = "hot";
+ };
++ };
++ };
++
++ gpu-bottom-thermal {
++ polling-delay-passive = <250>;
++ polling-delay = <1000>;
++
++ thermal-sensors = <&tsens 10>;
+
+- pm8941-regulators {
+- compatible = "qcom,rpm-pm8941-regulators";
+-
+- pm8941_s1: s1 {};
+- pm8941_s2: s2 {};
+- pm8941_s3: s3 {};
+-
+- pm8941_l1: l1 {};
+- pm8941_l2: l2 {};
+- pm8941_l3: l3 {};
+- pm8941_l4: l4 {};
+- pm8941_l5: l5 {};
+- pm8941_l6: l6 {};
+- pm8941_l7: l7 {};
+- pm8941_l8: l8 {};
+- pm8941_l9: l9 {};
+- pm8941_l10: l10 {};
+- pm8941_l11: l11 {};
+- pm8941_l12: l12 {};
+- pm8941_l13: l13 {};
+- pm8941_l14: l14 {};
+- pm8941_l15: l15 {};
+- pm8941_l16: l16 {};
+- pm8941_l17: l17 {};
+- pm8941_l18: l18 {};
+- pm8941_l19: l19 {};
+- pm8941_l20: l20 {};
+- pm8941_l21: l21 {};
+- pm8941_l22: l22 {};
+- pm8941_l23: l23 {};
+- pm8941_l24: l24 {};
+-
+- pm8941_lvs1: lvs1 {};
+- pm8941_lvs2: lvs2 {};
+- pm8941_lvs3: lvs3 {};
++ trips {
++ gpu2_alert0: trip-point0 {
++ temperature = <90000>;
++ hysteresis = <2000>;
++ type = "hot";
+ };
+ };
+ };
+ };
+
++ timer {
++ compatible = "arm,armv7-timer";
++ interrupts = <GIC_PPI 2 0xf08>,
++ <GIC_PPI 3 0xf08>,
++ <GIC_PPI 4 0xf08>,
++ <GIC_PPI 1 0xf08>;
++ clock-frequency = <19200000>;
++ };
++
+ vreg_boost: vreg-boost {
+ compatible = "regulator-fixed";
+
+@@ -1690,6 +1627,7 @@ vreg_boost: vreg-boost {
+ pinctrl-names = "default";
+ pinctrl-0 = <&boost_bypass_n_pin>;
+ };
++
+ vreg_vph_pwr: vreg-vph-pwr {
+ compatible = "regulator-fixed";
+ regulator-name = "vph-pwr";
+--
+2.35.1
+
--- /dev/null
+From ec4a500d44a5dbb706d0a9172e8c9c4a1f584353 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 13:27:02 +0200
+Subject: ARM: dts: qcom: pm8841: add required thermal-sensor-cells
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit e2759fa0676c9a32bbddb9aff955b54bb35066ad ]
+
+The PM8841 temperature sensor has to define thermal-sensor-cells.
+
+Fixes: dab8134ca072 ("ARM: dts: qcom: Add PM8841 functions device nodes")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220608112702.80873-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-pm8841.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/boot/dts/qcom-pm8841.dtsi b/arch/arm/boot/dts/qcom-pm8841.dtsi
+index 2caf71eacb52..b5cdde034d18 100644
+--- a/arch/arm/boot/dts/qcom-pm8841.dtsi
++++ b/arch/arm/boot/dts/qcom-pm8841.dtsi
+@@ -24,6 +24,7 @@ temp-alarm@2400 {
+ compatible = "qcom,spmi-temp-alarm";
+ reg = <0x2400>;
+ interrupts = <4 0x24 0 IRQ_TYPE_EDGE_RISING>;
++ #thermal-sensor-cells = <0>;
+ };
+ };
+
+--
+2.35.1
+
--- /dev/null
+From cf62880428cadaefb3e9dabe822e80b19571f817 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Apr 2022 07:51:17 +0200
+Subject: ARM: dts: qcom: replace gcc PXO with pxo_board fixed clock
+
+From: Ansuel Smith <ansuelsmth@gmail.com>
+
+[ Upstream commit eb9e93937756a05787977875830c0dc482cb57e0 ]
+
+Replace gcc PXO phandle to pxo_board fixed clock declared in the dts.
+gcc driver doesn't provide PXO_SRC as it's a fixed-clock. This cause a
+kernel panic if any driver actually try to use it.
+
+Fixes: 40cf5c884a96 ("ARM: dts: qcom: add L2CC and RPM for IPQ8064")
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220430055118.1947-2-ansuelsmth@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-ipq8064.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
+index 8cb04aa8ed2f..326793ae3738 100644
+--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
++++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
+@@ -782,7 +782,7 @@ tcsr: syscon@1a400000 {
+ l2cc: clock-controller@2011000 {
+ compatible = "qcom,kpss-gcc", "syscon";
+ reg = <0x2011000 0x1000>;
+- clocks = <&gcc PLL8_VOTE>, <&gcc PXO_SRC>;
++ clocks = <&gcc PLL8_VOTE>, <&pxo_board>;
+ clock-names = "pll8_vote", "pxo";
+ clock-output-names = "acpu_l2_aux";
+ };
+--
+2.35.1
+
--- /dev/null
+From 3a47a8b67b8a34a051075bf836053036296a5c0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 13:38:40 +0530
+Subject: ARM: dts: qcom: sdx55: Fix the IRQ trigger type for UART
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit ae500b351ab0006d933d804a2b7507fe1e98cecc ]
+
+The trigger type should be LEVEL_HIGH. So fix it!
+
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220530080842.37024-2-manivannan.sadhasivam@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-sdx55.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/qcom-sdx55.dtsi b/arch/arm/boot/dts/qcom-sdx55.dtsi
+index d455795da44c..b75e672c239d 100644
+--- a/arch/arm/boot/dts/qcom-sdx55.dtsi
++++ b/arch/arm/boot/dts/qcom-sdx55.dtsi
+@@ -206,7 +206,7 @@ gcc: clock-controller@100000 {
+ blsp1_uart3: serial@831000 {
+ compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+ reg = <0x00831000 0x200>;
+- interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_LOW>;
++ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc 30>,
+ <&gcc 9>;
+ clock-names = "core", "iface";
+--
+2.35.1
+
--- /dev/null
+From d6f897294f0225878d91622ba5d4b3a56d21ca17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jun 2022 22:42:49 +0200
+Subject: ARM: dts: ux500: Fix Codina accelerometer mounting matrix
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit 0b2152e428ab91533a02888ff24e52e788dc4637 ]
+
+This was fixed wrong so fix it again. Now verified by using
+iio-sensor-proxy monitor-sensor test program.
+
+Link: https://lore.kernel.org/r/20220611204249.472250-1-linus.walleij@linaro.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/ste-ux500-samsung-codina.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-codina.dts b/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
+index 1c1725d31c7c..0a10fb0a3741 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
+@@ -566,8 +566,8 @@ lisd3dh@19 {
+ reg = <0x19>;
+ vdd-supply = <&ab8500_ldo_aux1_reg>; // 3V
+ vddio-supply = <&ab8500_ldo_aux2_reg>; // 1.8V
+- mount-matrix = "0", "-1", "0",
+- "1", "0", "0",
++ mount-matrix = "0", "1", "0",
++ "-1", "0", "0",
+ "0", "0", "1";
+ };
+ };
+--
+2.35.1
+
--- /dev/null
+From 7260a9689d5d00cf364dd0bf14ecee23fbf0dc9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jun 2022 22:51:38 +0200
+Subject: ARM: dts: ux500: Fix Gavini accelerometer mounting matrix
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit e24c75f02a81d6ddac0072cbd7a03e799c19d558 ]
+
+This was fixed wrong so fix it. Now verified by using
+iio-sensor-proxy monitor-sensor test program.
+
+Link: https://lore.kernel.org/r/20220611205138.491513-1-linus.walleij@linaro.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/ste-ux500-samsung-gavini.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts b/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
+index fd170974765f..149838b5f9c1 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
+@@ -523,8 +523,8 @@ i2c-gate {
+ accelerometer@18 {
+ compatible = "bosch,bma222e";
+ reg = <0x18>;
+- mount-matrix = "0", "1", "0",
+- "-1", "0", "0",
++ mount-matrix = "0", "-1", "0",
++ "1", "0", "0",
+ "0", "0", "1";
+ vddio-supply = <&ab8500_ldo_aux2_reg>; // 1.8V
+ vdd-supply = <&ab8500_ldo_aux1_reg>; // 3V
+--
+2.35.1
+
--- /dev/null
+From 9bb7b120d625559460b6628dd9bc5733069b7a74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 10:35:16 +0200
+Subject: ARM: dts: ux500: Fix Janice accelerometer mounting matrix
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit 013fda41c03e6bcb3dc416669187b609e9e5fdbc ]
+
+This was fixed wrong so fix it again. Now verified by using
+iio-sensor-proxy monitor-sensor test program.
+
+Link: https://lore.kernel.org/r/20220609083516.329281-1-linus.walleij@linaro.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/ste-ux500-samsung-janice.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-janice.dts b/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
+index 42762bfcd878..2069efb252a7 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
+@@ -610,8 +610,8 @@ i2c-gate {
+ accelerometer@8 {
+ compatible = "bosch,bma222";
+ reg = <0x08>;
+- mount-matrix = "0", "1", "0",
+- "-1", "0", "0",
++ mount-matrix = "0", "-1", "0",
++ "1", "0", "0",
+ "0", "0", "1";
+ vddio-supply = <&ab8500_ldo_aux2_reg>; // 1.8V
+ vdd-supply = <&ab8500_ldo_aux1_reg>; // 3V
+--
+2.35.1
+
--- /dev/null
+From 7443e951a20f46bd0cc954681a304926a72610da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Jul 2022 23:51:48 +0100
+Subject: ARM: findbit: fix overflowing offset
+
+From: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+
+[ Upstream commit ec85bd369fd2bfaed6f45dd678706429d4f75b48 ]
+
+When offset is larger than the size of the bit array, we should not
+attempt to access the array as we can perform an access beyond the
+end of the array. Fix this by changing the pre-condition.
+
+Using "cmp r2, r1; bhs ..." covers us for the size == 0 case, since
+this will always take the branch when r1 is zero, irrespective of
+the value of r2. This means we can fix this bug without adding any
+additional code!
+
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/lib/findbit.S | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S
+index b5e8b9ae4c7d..7fd3600db8ef 100644
+--- a/arch/arm/lib/findbit.S
++++ b/arch/arm/lib/findbit.S
+@@ -40,8 +40,8 @@ ENDPROC(_find_first_zero_bit_le)
+ * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
+ */
+ ENTRY(_find_next_zero_bit_le)
+- teq r1, #0
+- beq 3b
++ cmp r2, r1
++ bhs 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ ARM( ldrb r3, [r0, r2, lsr #3] )
+@@ -81,8 +81,8 @@ ENDPROC(_find_first_bit_le)
+ * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
+ */
+ ENTRY(_find_next_bit_le)
+- teq r1, #0
+- beq 3b
++ cmp r2, r1
++ bhs 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ ARM( ldrb r3, [r0, r2, lsr #3] )
+@@ -115,8 +115,8 @@ ENTRY(_find_first_zero_bit_be)
+ ENDPROC(_find_first_zero_bit_be)
+
+ ENTRY(_find_next_zero_bit_be)
+- teq r1, #0
+- beq 3b
++ cmp r2, r1
++ bhs 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ eor r3, r2, #0x18 @ big endian byte ordering
+@@ -149,8 +149,8 @@ ENTRY(_find_first_bit_be)
+ ENDPROC(_find_first_bit_be)
+
+ ENTRY(_find_next_bit_be)
+- teq r1, #0
+- beq 3b
++ cmp r2, r1
++ bhs 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ eor r3, r2, #0x18 @ big endian byte ordering
+--
+2.35.1
+
--- /dev/null
+From ca0daa8ef78d9a2f1074760df84e99749eeb23ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 22:58:03 +0800
+Subject: ARM: OMAP2+: display: Fix refcount leak bug
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 50b87a32a79bca6e275918a711fb8cc55e16d739 ]
+
+In omapdss_init_fbdev(), of_find_node_by_name() will return a node
+pointer with refcount incremented. We should use of_node_put() when
+it is not used anymore.
+
+Signed-off-by: Liang He <windhl@126.com>
+Message-Id: <20220617145803.4050918-1-windhl@126.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap2/display.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
+index 21413a9b7b6c..eb09a25e3b45 100644
+--- a/arch/arm/mach-omap2/display.c
++++ b/arch/arm/mach-omap2/display.c
+@@ -211,6 +211,7 @@ static int __init omapdss_init_fbdev(void)
+ node = of_find_node_by_name(NULL, "omap4_padconf_global");
+ if (node)
+ omap4_dsi_mux_syscon = syscon_node_to_regmap(node);
++ of_node_put(node);
+
+ return 0;
+ }
+--
+2.35.1
+
--- /dev/null
+From 0f55877b9e2e7a193069978abb0d4d6b1818cfac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 11:37:24 +0400
+Subject: ARM: OMAP2+: Fix refcount leak in omap3xxx_prm_late_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 942228fbf5d4901112178b93d41225be7c0dd9de ]
+
+of_find_matching_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 1e037794f7f0 ("ARM: OMAP3+: PRM: register interrupt information from DT")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Message-Id: <20220526073724.21169-1-linmq006@gmail.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap2/prm3xxx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
+index 1b442b128569..63e73e9b82bc 100644
+--- a/arch/arm/mach-omap2/prm3xxx.c
++++ b/arch/arm/mach-omap2/prm3xxx.c
+@@ -708,6 +708,7 @@ static int omap3xxx_prm_late_init(void)
+ }
+
+ irq_num = of_irq_get(np, 0);
++ of_node_put(np);
+ if (irq_num == -EPROBE_DEFER)
+ return irq_num;
+
+--
+2.35.1
+
--- /dev/null
+From 50e9b6ddf49c8620ac2fd5d7dd94b5a1ddd5ec1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 08:48:58 +0400
+Subject: ARM: OMAP2+: Fix refcount leak in omapdss_init_of
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 9705db1eff38d6b9114121f9e253746199b759c9 ]
+
+omapdss_find_dss_of_node() calls of_find_compatible_node() to get device
+node. of_find_compatible_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when done.
+Add missing of_node_put() in later error path and normal path.
+
+Fixes: e0c827aca0730 ("drm/omap: Populate DSS children in omapdss driver")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Message-Id: <20220601044858.3352-1-linmq006@gmail.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap2/display.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
+index eb09a25e3b45..8d829f3dafe7 100644
+--- a/arch/arm/mach-omap2/display.c
++++ b/arch/arm/mach-omap2/display.c
+@@ -260,11 +260,13 @@ static int __init omapdss_init_of(void)
+
+ if (!pdev) {
+ pr_err("Unable to find DSS platform device\n");
++ of_node_put(node);
+ return -ENODEV;
+ }
+
+ r = of_platform_populate(node, NULL, NULL, &pdev->dev);
+ put_device(&pdev->dev);
++ of_node_put(node);
+ if (r) {
+ pr_err("Unable to populate DSS submodule devices\n");
+ return r;
+--
+2.35.1
+
--- /dev/null
+From 2ef7119064c928dea10128af9c0c7c4d834dc270 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jun 2022 10:06:03 +0800
+Subject: ARM: OMAP2+: pdata-quirks: Fix refcount leak bug
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 5cdbab96bab314c6f2f5e4e8b8a019181328bf5f ]
+
+In pdata_quirks_init_clocks(), the loop contains
+of_find_node_by_name() but without corresponding of_node_put().
+
+Signed-off-by: Liang He <windhl@126.com>
+Message-Id: <20220618020603.4055792-1-windhl@126.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-omap2/pdata-quirks.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
+index e7fd29a502a0..af9d8c432af0 100644
+--- a/arch/arm/mach-omap2/pdata-quirks.c
++++ b/arch/arm/mach-omap2/pdata-quirks.c
+@@ -551,6 +551,8 @@ pdata_quirks_init_clocks(const struct of_device_id *omap_dt_match_table)
+
+ of_platform_populate(np, omap_dt_match_table,
+ omap_auxdata_lookup, NULL);
++
++ of_node_put(np);
+ }
+ }
+
+--
+2.35.1
+
--- /dev/null
+From cffff3fe9e4531b0e8a23c6cbddc537c77e904c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 20:18:04 +0800
+Subject: ARM: shmobile: rcar-gen2: Increase refcount for new reference
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 75a185fb92e58ccd3670258d8d3b826bd2fa6d29 ]
+
+In rcar_gen2_regulator_quirk(), for_each_matching_node_and_match() will
+automatically increase and decrease the refcount. However, we should
+call of_node_get() for the new reference created in 'quirk->np'.
+Besides, we also should call of_node_put() before the 'quirk' being
+freed.
+
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220701121804.234223-1-windhl@126.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
+index 09ef73b99dd8..ba44cec5e59a 100644
+--- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
++++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
+@@ -125,6 +125,7 @@ static int regulator_quirk_notify(struct notifier_block *nb,
+
+ list_for_each_entry_safe(pos, tmp, &quirk_list, list) {
+ list_del(&pos->list);
++ of_node_put(pos->np);
+ kfree(pos);
+ }
+
+@@ -174,11 +175,12 @@ static int __init rcar_gen2_regulator_quirk(void)
+ memcpy(&quirk->i2c_msg, id->data, sizeof(quirk->i2c_msg));
+
+ quirk->id = id;
+- quirk->np = np;
++ quirk->np = of_node_get(np);
+ quirk->i2c_msg.addr = addr;
+
+ ret = of_irq_parse_one(np, 0, argsa);
+ if (ret) { /* Skip invalid entry and continue */
++ of_node_put(np);
+ kfree(quirk);
+ continue;
+ }
+@@ -225,6 +227,7 @@ static int __init rcar_gen2_regulator_quirk(void)
+ err_mem:
+ list_for_each_entry_safe(pos, tmp, &quirk_list, list) {
+ list_del(&pos->list);
++ of_node_put(pos->np);
+ kfree(pos);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From d51a570e53d2d0497bbdbcec160fbe8b286689fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 12:13:32 +0100
+Subject: arm64: cpufeature: Allow different PMU versions in ID_DFR0_EL1
+
+From: Alexandru Elisei <alexandru.elisei@arm.com>
+
+[ Upstream commit 506506cad3947b942425b119ffa2b06715d5d804 ]
+
+Commit b20d1ba3cf4b ("arm64: cpufeature: allow for version discrepancy in
+PMU implementations") made it possible to run Linux on a machine with PMUs
+with different versions without tainting the kernel. The patch relaxed the
+restriction only for the ID_AA64DFR0_EL1.PMUVer field, and missed doing the
+same for ID_DFR0_EL1.PerfMon , which also reports the PMU version, but for
+the AArch32 state.
+
+For example, with Linux running on two clusters with different PMU
+versions, the kernel is tainted when bringing up secondaries with the
+following message:
+
+[ 0.097027] smp: Bringing up secondary CPUs ...
+[..]
+[ 0.142805] Detected PIPT I-cache on CPU4
+[ 0.142805] CPU features: SANITY CHECK: Unexpected variation in SYS_ID_DFR0_EL1. Boot CPU: 0x00000004011088, CPU4: 0x00000005011088
+[ 0.143555] CPU features: Unsupported CPU feature variation detected.
+[ 0.143702] GICv3: CPU4: found redistributor 10000 region 0:0x000000002f180000
+[ 0.143702] GICv3: CPU4: using allocated LPI pending table @0x00000008800d0000
+[ 0.144888] CPU4: Booted secondary processor 0x0000010000 [0x410fd0f0]
+
+The boot CPU implements FEAT_PMUv3p1 (ID_DFR0_EL1.PerfMon, bits 27:24, is
+0b0100), but CPU4, part of the other cluster, implements FEAT_PMUv3p4
+(ID_DFR0_EL1.PerfMon = 0b0101).
+
+Treat the PerfMon field as FTR_NONSTRICT and FTR_EXACT to pass the sanity
+check and to match how PMUVer is treated for the 64bit ID register.
+
+Fixes: b20d1ba3cf4b ("arm64: cpufeature: allow for version discrepancy in PMU implementations")
+Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
+Link: https://lore.kernel.org/r/20220617111332.203061-1-alexandru.elisei@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/cpufeature.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
+index 5357ba7ea3c7..a54f34aa36e0 100644
+--- a/arch/arm64/kernel/cpufeature.c
++++ b/arch/arm64/kernel/cpufeature.c
+@@ -541,7 +541,7 @@ static const struct arm64_ftr_bits ftr_id_pfr2[] = {
+
+ static const struct arm64_ftr_bits ftr_id_dfr0[] = {
+ /* [31:28] TraceFilt */
+- S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_PERFMON_SHIFT, 4, 0xf),
++ S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_DFR0_PERFMON_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_MPROFDBG_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_MMAPTRC_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_COPTRC_SHIFT, 4, 0),
+--
+2.35.1
+
--- /dev/null
+From 80ac07dcf017cb6b7d1f13a9464fe70ebf1c0022 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 17:24:46 +0100
+Subject: arm64: Do not forget syscall when starting a new thread.
+
+From: Francis Laniel <flaniel@linux.microsoft.com>
+
+[ Upstream commit de6921856f99c11d3986c6702d851e1328d4f7f6 ]
+
+Enable tracing of the execve*() system calls with the
+syscalls:sys_exit_execve tracepoint by removing the call to
+forget_syscall() when starting a new thread and preserving the value of
+regs->syscallno across exec.
+
+Signed-off-by: Francis Laniel <flaniel@linux.microsoft.com>
+Link: https://lore.kernel.org/r/20220608162447.666494-2-flaniel@linux.microsoft.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/processor.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
+index 6b1a12c23fe7..7058bf047fa5 100644
+--- a/arch/arm64/include/asm/processor.h
++++ b/arch/arm64/include/asm/processor.h
+@@ -250,8 +250,9 @@ void tls_preserve_current_state(void);
+
+ static inline void start_thread_common(struct pt_regs *regs, unsigned long pc)
+ {
++ s32 previous_syscall = regs->syscallno;
+ memset(regs, 0, sizeof(*regs));
+- forget_syscall(regs);
++ regs->syscallno = previous_syscall;
+ regs->pc = pc;
+
+ if (system_uses_irq_prio_masking())
+--
+2.35.1
+
--- /dev/null
+From 66fc48efc86a9de9268e613d5957639d024bd65b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Jul 2022 08:28:15 -0500
+Subject: arm64: dts: allwinner: a64: orangepi-win: Fix LED node name
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit b8eb2df19fbf97aa1e950cf491232c2e3bef8357 ]
+
+"status" does not match any pattern in the gpio-leds binding. Rename the
+node to the preferred pattern. This fixes a `make dtbs_check` error.
+
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Link: https://lore.kernel.org/r/20220702132816.46456-1-samuel@sholland.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
+index c519d9fa6967..3d2c68d58f49 100644
+--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
+@@ -40,7 +40,7 @@ hdmi_con_in: endpoint {
+ leds {
+ compatible = "gpio-leds";
+
+- status {
++ led-0 {
+ label = "orangepi:green:status";
+ gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>; /* PH11 */
+ };
+--
+2.35.1
+
--- /dev/null
+From a6ddbf53e8deb4e57ccafad09fa763108b9fa441 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jun 2022 09:58:32 +0900
+Subject: arm64: dts: exynosautov9: correct spi11 pin names
+
+From: Chanho Park <chanho61.park@samsung.com>
+
+[ Upstream commit ba205449828f47f80532a1453beef5eed2982176 ]
+
+They should be started with "gpp5-".
+
+Fixes: 31bbac5263aa ("arm64: dts: exynos: add initial support for exynosautov9 SoC")
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220627005832.8709-1-chanho61.park@samsung.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi
+index ef0349d1c3d0..68f4a0fae7cf 100644
+--- a/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi
++++ b/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi
+@@ -1089,21 +1089,21 @@ spi10_cs_func: spi10-cs-func-pins {
+
+ /* PERIC1 USI11_SPI */
+ spi11_bus: spi11-pins {
+- samsung,pins = "gpp3-6", "gpp3-5", "gpp3-4";
++ samsung,pins = "gpp5-6", "gpp5-5", "gpp5-4";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ spi11_cs: spi11-cs-pins {
+- samsung,pins = "gpp3-7";
++ samsung,pins = "gpp5-7";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+ };
+
+ spi11_cs_func: spi11-cs-func-pins {
+- samsung,pins = "gpp3-7";
++ samsung,pins = "gpp5-7";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+--
+2.35.1
+
--- /dev/null
+From 616937ffaef4c59c8d6391c3e96d3afac9c2f752 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jun 2022 13:16:57 +0200
+Subject: arm64: dts: mt7622: fix BPI-R64 WPS button
+
+From: Nick Hainke <vincent@systemli.org>
+
+[ Upstream commit c98e6e683632386a3bd284acda4342e68aec4c41 ]
+
+The bananapi R64 (BPI-R64) experiences wrong WPS button signals.
+In OpenWrt pushing the WPS button while powering on the device will set
+it to recovery mode. Currently, this also happens without any user
+interaction. In particular, the wrong signals appear while booting the
+device or restarting it, e.g. after doing a system upgrade. If the
+device is in recovery mode the user needs to manually power cycle or
+restart it.
+
+The official BPI-R64 sources set the WPS button to GPIO_ACTIVE_LOW in
+the device tree. This setting seems to suppress the unwanted WPS button
+press signals. So this commit changes the button from GPIO_ACTIVE_HIGH to
+GPIO_ACTIVE_LOW.
+
+The official BPI-R64 sources can be found on
+https://github.com/BPI-SINOVOIP/BPI-R64-openwrt
+
+Fixes: 0b6286dd96c0 ("arm64: dts: mt7622: add bananapi BPI-R64 board")
+
+Suggested-by: INAGAKI Hiroshi <musashino.open@gmail.com>
+Signed-off-by: Nick Hainke <vincent@systemli.org>
+Link: https://lore.kernel.org/r/20220630111746.4098-1-vincent@systemli.org
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+index 2b9bf8dd14ec..7538918c7a82 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -49,7 +49,7 @@ factory {
+ wps {
+ label = "wps";
+ linux,code = <KEY_WPS_BUTTON>;
+- gpios = <&pio 102 GPIO_ACTIVE_HIGH>;
++ gpios = <&pio 102 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+--
+2.35.1
+
--- /dev/null
+From c613ae3594e3b47cd5bda702e2def250af55c03d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 19:31:50 -0400
+Subject: arm64: dts: mt8192: Fix idle-states entry-method
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit 2e599740f7e423ee89fb027896cb2635dd43784f ]
+
+The entry-method property of the idle-states node should be "psci" as
+described in the idle-states binding, since this is already the value of
+enable-method in the CPU nodes. Fix it to get rid of a dtbs_check
+warning.
+
+Fixes: 9260918d3a4f ("arm64: dts: mt8192: Add cpu-idle-states")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20220617233150.2466344-3-nfraprado@collabora.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8192.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+index 12972828832e..96439a4bce09 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+@@ -170,7 +170,7 @@ l3_0: l3-cache {
+ };
+
+ idle-states {
+- entry-method = "arm,psci";
++ entry-method = "psci";
+ cpu_sleep_l: cpu-sleep-l {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x00010001>;
+--
+2.35.1
+
--- /dev/null
+From 06c2d50227790d9c21c774729554db1c978bbd73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 19:31:49 -0400
+Subject: arm64: dts: mt8192: Fix idle-states nodes naming scheme
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit 399e23ad51caaf62400a531c9268ad3c453c3d76 ]
+
+Tweak the name of the idle-states subnodes so that they follow the
+binding pattern, getting rid of dtbs_check warnings.
+
+Only the usage of "-" in the name was necessary, but "off" was also
+exchanged for "sleep" since that seems to be a more common wording in
+other dts files.
+
+Fixes: 9260918d3a4f ("arm64: dts: mt8192: Add cpu-idle-states")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20220617233150.2466344-2-nfraprado@collabora.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8192.dtsi | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+index bcecc7484453..12972828832e 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+@@ -41,7 +41,7 @@ cpu0: cpu@0 {
+ reg = <0x000>;
+ enable-method = "psci";
+ clock-frequency = <1701000000>;
+- cpu-idle-states = <&cpuoff_l &clusteroff_l>;
++ cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>;
+ next-level-cache = <&l2_0>;
+ capacity-dmips-mhz = <530>;
+ };
+@@ -52,7 +52,7 @@ cpu1: cpu@100 {
+ reg = <0x100>;
+ enable-method = "psci";
+ clock-frequency = <1701000000>;
+- cpu-idle-states = <&cpuoff_l &clusteroff_l>;
++ cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>;
+ next-level-cache = <&l2_0>;
+ capacity-dmips-mhz = <530>;
+ };
+@@ -63,7 +63,7 @@ cpu2: cpu@200 {
+ reg = <0x200>;
+ enable-method = "psci";
+ clock-frequency = <1701000000>;
+- cpu-idle-states = <&cpuoff_l &clusteroff_l>;
++ cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>;
+ next-level-cache = <&l2_0>;
+ capacity-dmips-mhz = <530>;
+ };
+@@ -74,7 +74,7 @@ cpu3: cpu@300 {
+ reg = <0x300>;
+ enable-method = "psci";
+ clock-frequency = <1701000000>;
+- cpu-idle-states = <&cpuoff_l &clusteroff_l>;
++ cpu-idle-states = <&cpu_sleep_l &cluster_sleep_l>;
+ next-level-cache = <&l2_0>;
+ capacity-dmips-mhz = <530>;
+ };
+@@ -85,7 +85,7 @@ cpu4: cpu@400 {
+ reg = <0x400>;
+ enable-method = "psci";
+ clock-frequency = <2171000000>;
+- cpu-idle-states = <&cpuoff_b &clusteroff_b>;
++ cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>;
+ next-level-cache = <&l2_1>;
+ capacity-dmips-mhz = <1024>;
+ };
+@@ -96,7 +96,7 @@ cpu5: cpu@500 {
+ reg = <0x500>;
+ enable-method = "psci";
+ clock-frequency = <2171000000>;
+- cpu-idle-states = <&cpuoff_b &clusteroff_b>;
++ cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>;
+ next-level-cache = <&l2_1>;
+ capacity-dmips-mhz = <1024>;
+ };
+@@ -107,7 +107,7 @@ cpu6: cpu@600 {
+ reg = <0x600>;
+ enable-method = "psci";
+ clock-frequency = <2171000000>;
+- cpu-idle-states = <&cpuoff_b &clusteroff_b>;
++ cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>;
+ next-level-cache = <&l2_1>;
+ capacity-dmips-mhz = <1024>;
+ };
+@@ -118,7 +118,7 @@ cpu7: cpu@700 {
+ reg = <0x700>;
+ enable-method = "psci";
+ clock-frequency = <2171000000>;
+- cpu-idle-states = <&cpuoff_b &clusteroff_b>;
++ cpu-idle-states = <&cpu_sleep_b &cluster_sleep_b>;
+ next-level-cache = <&l2_1>;
+ capacity-dmips-mhz = <1024>;
+ };
+@@ -171,7 +171,7 @@ l3_0: l3-cache {
+
+ idle-states {
+ entry-method = "arm,psci";
+- cpuoff_l: cpuoff_l {
++ cpu_sleep_l: cpu-sleep-l {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x00010001>;
+ local-timer-stop;
+@@ -179,7 +179,7 @@ cpuoff_l: cpuoff_l {
+ exit-latency-us = <140>;
+ min-residency-us = <780>;
+ };
+- cpuoff_b: cpuoff_b {
++ cpu_sleep_b: cpu-sleep-b {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x00010001>;
+ local-timer-stop;
+@@ -187,7 +187,7 @@ cpuoff_b: cpuoff_b {
+ exit-latency-us = <145>;
+ min-residency-us = <720>;
+ };
+- clusteroff_l: clusteroff_l {
++ cluster_sleep_l: cluster-sleep-l {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x01010002>;
+ local-timer-stop;
+@@ -195,7 +195,7 @@ clusteroff_l: clusteroff_l {
+ exit-latency-us = <155>;
+ min-residency-us = <860>;
+ };
+- clusteroff_b: clusteroff_b {
++ cluster_sleep_b: cluster-sleep-b {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x01010002>;
+ local-timer-stop;
+--
+2.35.1
+
--- /dev/null
+From ee3cdcb6382834d1d859e9275c198e622199d880 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 May 2022 15:19:15 +0200
+Subject: arm64: dts: qcom: add missing AOSS QMP compatible fallback
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 6ba93ba9f63fbc44c3a6af7fe6f2536d009cfd5a ]
+
+The AOSS QMP bindings expect all compatibles to be followed by fallback
+"qcom,aoss-qmp" because all of these are actually compatible with each
+other. This fixes dtbs_check warnings like:
+
+ sm8250-hdk.dtb: power-controller@c300000: compatible: ['qcom,sm8250-aoss-qmp'] is too short
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220504131923.214367-6-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc7180.dtsi | 2 +-
+ arch/arm64/boot/dts/qcom/sc7280.dtsi | 2 +-
+ arch/arm64/boot/dts/qcom/sm8150.dtsi | 2 +-
+ arch/arm64/boot/dts/qcom/sm8250.dtsi | 2 +-
+ arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +-
+ 5 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi
+index e9fb3c9a2d6e..120db2d0a309 100644
+--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
+@@ -3219,7 +3219,7 @@ aoss_reset: reset-controller@c2a0000 {
+ };
+
+ aoss_qmp: power-controller@c300000 {
+- compatible = "qcom,sc7180-aoss-qmp";
++ compatible = "qcom,sc7180-aoss-qmp", "qcom,aoss-qmp";
+ reg = <0 0x0c300000 0 0x400>;
+ interrupts = <GIC_SPI 389 IRQ_TYPE_EDGE_RISING>;
+ mboxes = <&apss_shared 0>;
+diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+index 8a4fd614d0a1..7925c8561117 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+@@ -3467,7 +3467,7 @@ aoss_reset: reset-controller@c2a0000 {
+ };
+
+ aoss_qmp: power-controller@c300000 {
+- compatible = "qcom,sc7280-aoss-qmp";
++ compatible = "qcom,sc7280-aoss-qmp", "qcom,aoss-qmp";
+ reg = <0 0x0c300000 0 0x400>;
+ interrupts-extended = <&ipcc IPCC_CLIENT_AOP
+ IPCC_MPROC_SIGNAL_GLINK_QMP
+diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+index d4f288edf3c9..6edb3986a473 100644
+--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+@@ -3382,7 +3382,7 @@ camnoc_virt: interconnect@ac00000 {
+ };
+
+ aoss_qmp: power-controller@c300000 {
+- compatible = "qcom,sm8150-aoss-qmp";
++ compatible = "qcom,sm8150-aoss-qmp", "qcom,aoss-qmp";
+ reg = <0x0 0x0c300000 0x0 0x400>;
+ interrupts = <GIC_SPI 389 IRQ_TYPE_EDGE_RISING>;
+ mboxes = <&apss_shared 0>;
+diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+index ed4e288c921f..1d62b2130e04 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+@@ -3475,7 +3475,7 @@ tsens1: thermal-sensor@c265000 {
+ };
+
+ aoss_qmp: power-controller@c300000 {
+- compatible = "qcom,sm8250-aoss-qmp";
++ compatible = "qcom,sm8250-aoss-qmp", "qcom,aoss-qmp";
+ reg = <0 0x0c300000 0 0x400>;
+ interrupts-extended = <&ipcc IPCC_CLIENT_AOP
+ IPCC_MPROC_SIGNAL_GLINK_QMP
+diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+index d843a550314a..ee6c202ab68c 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+@@ -1537,7 +1537,7 @@ tsens1: thermal-sensor@c265000 {
+ };
+
+ aoss_qmp: power-controller@c300000 {
+- compatible = "qcom,sm8350-aoss-qmp";
++ compatible = "qcom,sm8350-aoss-qmp", "qcom,aoss-qmp";
+ reg = <0 0x0c300000 0 0x400>;
+ interrupts-extended = <&ipcc IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_GLINK_QMP
+ IRQ_TYPE_EDGE_RISING>;
+--
+2.35.1
+
--- /dev/null
+From 407e683f6d0babbd412509afbfb5f7159a65e4a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jun 2022 14:06:42 +0200
+Subject: arm64: dts: qcom: ipq8074: fix NAND node name
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit b39961659ffc3c3a9e3d0d43b0476547b5f35d49 ]
+
+Per schema it should be nand-controller@79b0000 instead of nand@79b0000.
+Fix it to match nand-controller.yaml requirements.
+
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220621120642.518575-1-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+index 8d4e0e193439..664fba3632b1 100644
+--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+@@ -534,7 +534,7 @@ qpic_bam: dma-controller@7984000 {
+ status = "disabled";
+ };
+
+- qpic_nand: nand@79b0000 {
++ qpic_nand: nand-controller@79b0000 {
+ compatible = "qcom,ipq8074-nand";
+ reg = <0x079b0000 0x10000>;
+ #address-cells = <1>;
+--
+2.35.1
+
--- /dev/null
+From bd18654bebc08d06378d432061062d44247c326a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 19:47:40 +0530
+Subject: arm64: dts: qcom: msm8916: Fix typo in pronto remoteproc node
+
+From: Sireesh Kodali <sireeshkodali1@gmail.com>
+
+[ Upstream commit 5458d6f2827cd30218570f266b8d238417461f2f ]
+
+The smem-state properties for the pronto node were incorrectly labelled,
+reading `qcom,state*` rather than `qcom,smem-state*`. Fix that, allowing
+the stop state to be used.
+
+Fixes: 88106096cbf8 ("ARM: dts: msm8916: Add and enable wcnss node")
+Signed-off-by: Sireesh Kodali <sireeshkodali1@gmail.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Stephan Gerhold <stephan@gerhold.net>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220526141740.15834-3-sireeshkodali1@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8916.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+index e34963505e07..7ecd747dc624 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+@@ -1758,8 +1758,8 @@ pronto: remoteproc@a21b000 {
+ <&rpmpd MSM8916_VDDMX>;
+ power-domain-names = "cx", "mx";
+
+- qcom,state = <&wcnss_smp2p_out 0>;
+- qcom,state-names = "stop";
++ qcom,smem-states = <&wcnss_smp2p_out 0>;
++ qcom,smem-state-names = "stop";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&wcnss_pin_a>;
+--
+2.35.1
+
--- /dev/null
+From 150afc2adcae69c90716161b344b34aaad26ce0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 10:19:34 +0300
+Subject: arm64: dts: qcom: msm8996: correct #clock-cells for QMP PHY nodes
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit b874fff9a7683df30e5aff16d5a85b1f8a43aa5d ]
+
+The commit 82d61e19fccb ("arm64: dts: qcom: msm8996: Move '#clock-cells'
+to QMP PHY child node") moved the '#clock-cells' properties to the child
+nodes. However it missed the fact that the property must have been set
+to <0> (as all pipe clocks use of_clk_hw_simple_get as the xlate
+function. Also the mentioned commit didn't add '#clock-cells' properties
+to second and third PCIe PHY nodes. Correct both these mistakes:
+
+- Set '#clock-cells' to <0>,
+- Add the property to pciephy_1 and pciephy_2 nodes.
+
+Fixes: 82d61e19fccb ("arm64: dts: qcom: msm8996: Move '#clock-cells' to QMP PHY child node")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220620071936.1558906-3-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8996.dtsi | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+index b9a48cfd760f..078edf46de2b 100644
+--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+@@ -603,7 +603,7 @@ pciephy_0: phy@35000 {
+ <0x00035400 0x1dc>;
+ #phy-cells = <0>;
+
+- #clock-cells = <1>;
++ #clock-cells = <0>;
+ clock-output-names = "pcie_0_pipe_clk_src";
+ clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
+ clock-names = "pipe0";
+@@ -617,6 +617,7 @@ pciephy_1: phy@36000 {
+ <0x00036400 0x1dc>;
+ #phy-cells = <0>;
+
++ #clock-cells = <0>;
+ clock-output-names = "pcie_1_pipe_clk_src";
+ clocks = <&gcc GCC_PCIE_1_PIPE_CLK>;
+ clock-names = "pipe1";
+@@ -630,6 +631,7 @@ pciephy_2: phy@37000 {
+ <0x00037400 0x1dc>;
+ #phy-cells = <0>;
+
++ #clock-cells = <0>;
+ clock-output-names = "pcie_2_pipe_clk_src";
+ clocks = <&gcc GCC_PCIE_2_PIPE_CLK>;
+ clock-names = "pipe2";
+@@ -2659,7 +2661,7 @@ ssusb_phy_0: phy@7410200 {
+ <0x07410600 0x1a8>;
+ #phy-cells = <0>;
+
+- #clock-cells = <1>;
++ #clock-cells = <0>;
+ clock-output-names = "usb3_phy_pipe_clk_src";
+ clocks = <&gcc GCC_USB3_PHY_PIPE_CLK>;
+ clock-names = "pipe0";
+--
+2.35.1
+
--- /dev/null
+From a9fec3d4cd74bee9b660bff74447b58e81e308d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 7 May 2022 17:36:27 +0200
+Subject: arm64: dts: qcom: msm8998: Make regulator voltages multiple of
+ step-size
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit 2aa54fa87cca1fa43870a9caf4fcce00eb087fa5 ]
+
+These voltages are not a multiple of the given step-size 8000 (with base
+voltage 1664000) in pm8998_pldo, resulting in PLDO regulators l18 and
+l22 failing to validate and in turn not probing the rpm-pm8998-regulator
+driver:
+
+ l18: unsupportable voltage constraints 2856000-2848000uV
+ qcom_rpm_smd_regulator rpm-glink:rpm-requests:pm8998-regulators: l18: devm_regulator_register() failed, ret=-22
+
+Round the voltages down for the sake of erring on the safe side, leaving
+a comment in place to document this discrepancy wrt downstream sources.
+
+Fixes: 390883af89d2 ("arm64: dts: qcom: msm8998: Introduce support for Sony Yoshino platform")
+Reported-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220507153627.1478268-1-marijn.suijten@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../dts/qcom/msm8998-sony-xperia-yoshino-poplar.dts | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-poplar.dts b/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-poplar.dts
+index 4a1f98a21031..c21333aa73c2 100644
+--- a/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-poplar.dts
++++ b/arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino-poplar.dts
+@@ -26,11 +26,13 @@ &lab {
+ };
+
+ &vreg_l18a_2p85 {
+- regulator-min-microvolt = <2850000>;
+- regulator-max-microvolt = <2850000>;
++ /* Note: Round-down from 2850000 to be a multiple of PLDO step-size 8000 */
++ regulator-min-microvolt = <2848000>;
++ regulator-max-microvolt = <2848000>;
+ };
+
+ &vreg_l22a_2p85 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
++ /* Note: Round-down from 2700000 to be a multiple of PLDO step-size 8000 */
++ regulator-min-microvolt = <2696000>;
++ regulator-max-microvolt = <2696000>;
+ };
+--
+2.35.1
+
--- /dev/null
+From 74bc2c0f9ca18d54c8e367d5172d40629962bb81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 14:00:38 +0530
+Subject: arm64: dts: qcom: qcs404: Fix incorrect USB2 PHYs assignment
+
+From: Sumit Garg <sumit.garg@linaro.org>
+
+[ Upstream commit 58577966a42fc0b660b5e2c7c9e5a2241363ea83 ]
+
+Currently the DT for QCS404 SoC has setup for 2 USB2 PHYs with one each
+assigned to USB3 controller and USB2 controller. This assignment is
+incorrect which only works by luck: as when each USB HCI comes up it
+configures the *other* controllers PHY which is enough to make them
+happy. If, for any reason, we were to disable one of the controllers then
+both would stop working.
+
+This was a difficult inconsistency to be caught which was found while
+trying to enable USB support in u-boot. So with all the required drivers
+ported to u-boot, I couldn't get the same USB storage device enumerated
+in u-boot which was being enumerated fine by the kernel.
+
+The root cause of the problem came out to be that I wasn't enabling USB2
+PHY: "usb2_phy_prim" in u-boot. Then I realised that via simply disabling
+the same USB2 PHY currently assigned to USB2 host controller in the
+kernel disabled enumeration for USB3 host controller as well.
+
+So fix this inconsistency by correctly assigning USB2 PHYs.
+
+Fixes: 9375e7d719b3 ("arm64: dts: qcom: qcs404: Add USB devices and PHYs")
+Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
+Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220711083038.1518529-1-sumit.garg@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/qcs404.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi
+index 3f06f7cd3cf2..65d71adee345 100644
+--- a/arch/arm64/boot/dts/qcom/qcs404.dtsi
++++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi
+@@ -548,7 +548,7 @@ dwc3@7580000 {
+ compatible = "snps,dwc3";
+ reg = <0x07580000 0xcd00>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+- phys = <&usb2_phy_sec>, <&usb3_phy>;
++ phys = <&usb2_phy_prim>, <&usb3_phy>;
+ phy-names = "usb2-phy", "usb3-phy";
+ snps,has-lpm-erratum;
+ snps,hird-threshold = /bits/ 8 <0x10>;
+@@ -577,7 +577,7 @@ dwc3@78c0000 {
+ compatible = "snps,dwc3";
+ reg = <0x078c0000 0xcc00>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+- phys = <&usb2_phy_prim>;
++ phys = <&usb2_phy_sec>;
+ phy-names = "usb2-phy";
+ snps,has-lpm-erratum;
+ snps,hird-threshold = /bits/ 8 <0x10>;
+--
+2.35.1
+
--- /dev/null
+From 00e7b76cc2ac83d92b7fb181167c10441c56cb10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 May 2022 12:33:07 -0700
+Subject: arm64: dts: qcom: sc7180: Remove ipa_fw_mem node on trogdor
+
+From: Stephen Boyd <swboyd@chromium.org>
+
+[ Upstream commit e60414644cf3a703e10ed4429c15263095945ffe ]
+
+We don't use this carveout on trogdor boards, and having it defined in
+the sc7180 SoC file causes an overlap message to be printed at boot.
+
+ OF: reserved mem: OVERLAP DETECTED!
+ memory@86000000 (0x0000000086000000--0x000000008ec00000) overlaps with memory@8b700000 (0x000000008b700000--0x000000008b710000)
+
+Delete the node in the trogdor dtsi file to fix the overlap problem and
+remove the error message.
+
+Cc: Alex Elder <elder@linaro.org>
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Fixes: 310b266655a3 ("arm64: dts: qcom: sc7180: define ipa_fw_mem node")
+Signed-off-by: Stephen Boyd <swboyd@chromium.org>
+Reviewed-by: Alex Elder <elder@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220517193307.3034602-1-swboyd@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+index 732e1181af48..262224504921 100644
+--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+@@ -42,6 +42,7 @@ charger-crit {
+ */
+
+ /delete-node/ &hyp_mem;
++/delete-node/ &ipa_fw_mem;
+ /delete-node/ &xbl_mem;
+ /delete-node/ &aop_mem;
+ /delete-node/ &sec_apps_mem;
+--
+2.35.1
+
--- /dev/null
+From 5a236b18f18e1b51e456dae97360e9430999786b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 13:40:19 +0200
+Subject: arm64: dts: qcom: sc7280: drop PCIe PHY clock index
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit 531c738fb36069d60aff267a0b25533a35d59fd0 ]
+
+The QMP PCIe PHY provides a single clock so drop the redundant clock
+index.
+
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Fixes: bd7d507935ca ("arm64: dts: qcom: sc7280: Add pcie clock support")
+Fixes: 92e0ee9f83b3 ("arm64: dts: qcom: sc7280: Add PCIe and PHY related nodes")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220705114032.22787-2-johan+linaro@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc7280.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+index 7925c8561117..86898d0b4124 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+@@ -810,7 +810,7 @@ gcc: clock-controller@100000 {
+ reg = <0 0x00100000 0 0x1f0000>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>,
+- <0>, <&pcie1_lane 0>,
++ <0>, <&pcie1_lane>,
+ <0>, <0>, <0>, <0>;
+ clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk",
+ "pcie_0_pipe_clk", "pcie_1_pipe_clk",
+@@ -1914,7 +1914,7 @@ pcie1_lane: lanes@1c0e200 {
+ clock-names = "pipe0";
+
+ #phy-cells = <0>;
+- #clock-cells = <1>;
++ #clock-cells = <0>;
+ clock-output-names = "pcie_1_pipe_clk";
+ };
+ };
+--
+2.35.1
+
--- /dev/null
+From 86b6b6f9bc8832360d14e190cde7cf92b9d66449 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 08:42:22 +0200
+Subject: arm64: dts: qcom: sc7280: fix PCIe clock reference
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit 330fc08dbdd913ac37a31f8aec1a88f68e39ae39 ]
+
+The recent commit that dropped the PCIe PHY clock index failed to update
+the PCIe node reference.
+
+Fixes: 531c738fb360 ("arm64: dts: qcom: sc7280: drop PCIe PHY clock index")
+Reported-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220707064222.15717-1-johan+linaro@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc7280.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+index 86898d0b4124..793ac9715da2 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+@@ -1839,7 +1839,7 @@ pcie1: pci@1c08000 {
+
+ clocks = <&gcc GCC_PCIE_1_PIPE_CLK>,
+ <&gcc GCC_PCIE_1_PIPE_CLK_SRC>,
+- <&pcie1_lane 0>,
++ <&pcie1_lane>,
+ <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_PCIE_1_AUX_CLK>,
+ <&gcc GCC_PCIE_1_CFG_AHB_CLK>,
+--
+2.35.1
+
--- /dev/null
+From e1e761bd330cbdf6e68184e451036b3e7a123d82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 23:27:00 +0300
+Subject: arm64: dts: qcom: sdm630: disable GPU by default
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 1c047919763b4548381d1ab3320af1df66ab83df ]
+
+The SoC's device tree file disables gpucc and adreno's SMMU by default.
+So let's disable the GPU too. Moreover it looks like SMMU might be not
+usable without additional patches (which means that GPU is unusable
+too). No board uses GPU at this moment.
+
+Fixes: 5cf69dcbec8b ("arm64: dts: qcom: sdm630: Add Adreno 508 GPU configuration")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220521202708.1509308-4-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm630.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+index 240293592ef9..45eaaa6a4a74 100644
+--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+@@ -1050,6 +1050,8 @@ adreno_gpu: gpu@5000000 {
+
+ operating-points-v2 = <&gpu_sdm630_opp_table>;
+
++ status = "disabled";
++
+ gpu_sdm630_opp_table: opp-table {
+ compatible = "operating-points-v2";
+ opp-775000000 {
+--
+2.35.1
+
--- /dev/null
+From 7ee51f5c00bc6b69d813921bf67bb8225b153b3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 23:27:04 +0300
+Subject: arm64: dts: qcom: sdm630: fix gpu's interconnect path
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 3cd1c4f41d64a40ea6bc4575ae28e37542123d77 ]
+
+ICC path for the GPU incorrectly states <&gnoc 1 &bimc 5>, which is
+a path from SLAVE_GNOC_BIMC to SLAVE_EBI. According to the downstream
+kernel sources, the GPU uses MASTER_OXILI here, which is equivalent to
+<&bimc 1 ...>.
+
+While we are at it, use defined names instead of the numbers for this
+interconnect path.
+
+Fixes: 5cf69dcbec8b ("arm64: dts: qcom: sdm630: Add Adreno 508 GPU configuration")
+Reported-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220521202708.1509308-8-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm630.dtsi | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+index 984d212edae6..a33638a1cb44 100644
+--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+@@ -8,6 +8,7 @@
+ #include <dt-bindings/clock/qcom,gpucc-sdm660.h>
+ #include <dt-bindings/clock/qcom,mmcc-sdm660.h>
+ #include <dt-bindings/clock/qcom,rpmcc.h>
++#include <dt-bindings/interconnect/qcom,sdm660.h>
+ #include <dt-bindings/power/qcom-rpmpd.h>
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+@@ -1045,7 +1046,7 @@ adreno_gpu: gpu@5000000 {
+ nvmem-cells = <&gpu_speed_bin>;
+ nvmem-cell-names = "speed_bin";
+
+- interconnects = <&gnoc 1 &bimc 5>;
++ interconnects = <&bimc MASTER_OXILI &bimc SLAVE_EBI>;
+ interconnect-names = "gfx-mem";
+
+ operating-points-v2 = <&gpu_sdm630_opp_table>;
+--
+2.35.1
+
--- /dev/null
+From e2944fea3c3c655a80ac536c6a1fad6d64cea9a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 23:27:01 +0300
+Subject: arm64: dts: qcom: sdm630: fix the qusb2phy ref clock
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 924bbd8dd60e094344711c3526a5b308d71dc008 ]
+
+According to the downstram DT file, the qusb2phy ref clock should be
+GCC_RX0_USB2_CLKREF_CLK, not GCC_RX1_USB2_CLKREF_CLK.
+
+Fixes: c65a4ed2ea8b ("arm64: dts: qcom: sdm630: Add USB configuration")
+Cc: Konrad Dybcio <konrad.dybcio@somainline.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220521202708.1509308-5-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm630.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+index 45eaaa6a4a74..984d212edae6 100644
+--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+@@ -1262,7 +1262,7 @@ qusb2phy: phy@c012000 {
+ #phy-cells = <0>;
+
+ clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+- <&gcc GCC_RX1_USB2_CLKREF_CLK>;
++ <&gcc GCC_RX0_USB2_CLKREF_CLK>;
+ clock-names = "cfg_ahb", "ref";
+
+ resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
+--
+2.35.1
+
--- /dev/null
+From 895f30c2a4cd6b16847e44787a144867ec367207 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 23:27:05 +0300
+Subject: arm64: dts: qcom: sdm636-sony-xperia-ganges-mermaid: correct sdc2
+ pinconf
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 3a04cec9cba393abfe70fc62e523f381c9baec2e ]
+
+Fix the device tree node in the &sdc2_state_on override. The sdm630 uses
+'clk' rather than 'pinconf-clk'.
+
+Fixes: 4c1d849ec047 ("arm64: dts: qcom: sdm630-xperia: Retire sdm630-sony-xperia-ganges.dtsi")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220521202708.1509308-9-dmitry.baryshkov@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts b/arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts
+index b96da53f2f1e..58f687fc49e0 100644
+--- a/arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts
++++ b/arch/arm64/boot/dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts
+@@ -19,7 +19,7 @@ / {
+ };
+
+ &sdc2_state_on {
+- pinconf-clk {
++ clk {
+ drive-strength = <14>;
+ };
+ };
+--
+2.35.1
+
--- /dev/null
+From cfbee5aed18ff14d8b171e5ea16244553ad10619 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 23:12:12 +0200
+Subject: arm64: dts: qcom: sdm845-akatsuki: Round down l22a regulator voltage
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit 4148a9eeb15152865d60b0913d96beb7ca166f9a ]
+
+2700000 is not a multiple of pmic4_pldo's step size of 8000 (with base
+voltage 1664000), resulting in pm8998-rpmh-regulators not probing. Just
+as we did with MSM8998's Sony Yoshino Poplar [1], round the voltages
+down to err on the cautious side and leave a comment in place to
+document this discrepancy wrt downstream sources.
+
+[1]: https://lore.kernel.org/linux-arm-msm/20220507153627.1478268-1-marijn.suijten@somainline.org/
+
+Fixes: 30a7f99befc6 ("arm64: dts: qcom: Add support for SONY Xperia XZ2 / XZ2C / XZ3 (Tama platform)")
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220620211212.269956-1-marijn.suijten@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts
+index 8a0d94e7f598..2f5e12deaada 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama-akatsuki.dts
+@@ -19,8 +19,9 @@ &vreg_l14a_1p8 {
+ };
+
+ &vreg_l22a_2p8 {
+- regulator-min-microvolt = <2700000>;
+- regulator-max-microvolt = <2700000>;
++ /* Note: Round-down from 2700000 to be a multiple of PLDO step-size 8000 */
++ regulator-min-microvolt = <2696000>;
++ regulator-max-microvolt = <2696000>;
+ };
+
+ &vreg_l28a_2p8 {
+--
+2.35.1
+
--- /dev/null
+From ebe1a45252d8a64f4e6d4e12339e8079de2c80b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 12:03:34 +0200
+Subject: arm64: dts: qcom: sm6125: Append -state suffix to pinctrl nodes
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit cbfb5668aece448877fa7826cde81c9d06f4a4ac ]
+
+According to qcom,sm6125-pinctrl.yaml all nodes inside the tlmm must be
+suffixed by -state:
+
+ qcom/sm6125-sony-xperia-seine-pdx201.dtb: pinctrl@500000: 'sdc2-off', 'sdc2-on' do not match any of the regexes: '-state$', 'pinctrl-[0-9]+'
+
+The label names have been updated to match, going from sdc2_state_X to
+sdc2_X_state.
+
+Fixes: cff4bbaf2a2d ("arm64: dts: qcom: Add support for SM6125")
+Fixes: 82e1783890b7 ("arm64: dts: qcom: sm6125: Add support for Sony Xperia 10II")
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220508100336.127176-2-marijn.suijten@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts | 4 ++--
+ arch/arm64/boot/dts/qcom/sm6125.dtsi | 8 ++++----
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
+index 4916e6c8b625..038970c0b68e 100644
+--- a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
++++ b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
+@@ -88,7 +88,7 @@ &hsusb_phy1 {
+ status = "okay";
+ };
+
+-&sdc2_state_off {
++&sdc2_off_state {
+ sd-cd {
+ pins = "gpio98";
+ drive-strength = <2>;
+@@ -96,7 +96,7 @@ sd-cd {
+ };
+ };
+
+-&sdc2_state_on {
++&sdc2_on_state {
+ sd-cd {
+ pins = "gpio98";
+ drive-strength = <2>;
+diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi
+index 3fadf5196c4d..e601b9bfdc04 100644
+--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi
+@@ -386,7 +386,7 @@ tlmm: pinctrl@500000 {
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+- sdc2_state_off: sdc2-off {
++ sdc2_off_state: sdc2-off-state {
+ clk {
+ pins = "sdc2_clk";
+ drive-strength = <2>;
+@@ -406,7 +406,7 @@ data {
+ };
+ };
+
+- sdc2_state_on: sdc2-on {
++ sdc2_on_state: sdc2-on-state {
+ clk {
+ pins = "sdc2_clk";
+ drive-strength = <16>;
+@@ -490,8 +490,8 @@ sdhc_2: sdhci@4784000 {
+ <&xo_board>;
+ clock-names = "iface", "core", "xo";
+
+- pinctrl-0 = <&sdc2_state_on>;
+- pinctrl-1 = <&sdc2_state_off>;
++ pinctrl-0 = <&sdc2_on_state>;
++ pinctrl-1 = <&sdc2_off_state>;
+ pinctrl-names = "default", "sleep";
+
+ power-domains = <&rpmpd SM6125_VDDCX>;
+--
+2.35.1
+
--- /dev/null
+From 611476dcd1ee4f53f3124b5aa387ae6fde2c5915 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 12:03:33 +0200
+Subject: arm64: dts: qcom: sm6125: Move sdc2 pinctrl from seine-pdx201 to
+ sm6125
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit 6990640a93ba4e76dd62ca3ea1082a7354db09d7 ]
+
+Both the sdc2-on and sdc2-off pinctrl nodes are used by the
+sdhci@4784000 node in sm6125.dtsi. Surprisingly sdc2-off is defined in
+sm6125, yet its sdc2-on counterpart is only defined in board-specific DT
+for the Sony Seine PDX201 board/device resulting in an "undefined label
+&sdc2_state_on" error if sm6125.dtsi were included elsewhere.
+This sm6125 base dtsi should not rely on externally defined labels; the
+properties referencing it should then also be written externally.
+Since the sdc2-on pin configuration is board-independent just like
+sdc2-off, move it from seine-pdx201.dts into sm6125.dtsi.
+
+The SDCard-detect pin (gpio98) is however board-specific, and remains as
+an overwrite in seine-pdx201.dts for both the on and off state.
+
+As a drive-by cleanup, reorder bias- and drive-strength properties.
+
+Fixes: cff4bbaf2a2d ("arm64: dts: qcom: Add support for SM6125")
+Fixes: 82e1783890b7 ("arm64: dts: qcom: sm6125: Add support for Sony Xperia 10II")
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220508100336.127176-1-marijn.suijten@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../qcom/sm6125-sony-xperia-seine-pdx201.dts | 34 +++++--------------
+ arch/arm64/boot/dts/qcom/sm6125.dtsi | 24 +++++++++++--
+ 2 files changed, 30 insertions(+), 28 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
+index 871ccbba445b..4916e6c8b625 100644
+--- a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
++++ b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
+@@ -91,8 +91,16 @@ &hsusb_phy1 {
+ &sdc2_state_off {
+ sd-cd {
+ pins = "gpio98";
++ drive-strength = <2>;
+ bias-disable;
++ };
++};
++
++&sdc2_state_on {
++ sd-cd {
++ pins = "gpio98";
+ drive-strength = <2>;
++ bias-pull-up;
+ };
+ };
+
+@@ -102,32 +110,6 @@ &sdhc_1 {
+
+ &tlmm {
+ gpio-reserved-ranges = <22 2>, <28 6>;
+-
+- sdc2_state_on: sdc2-on {
+- clk {
+- pins = "sdc2_clk";
+- bias-disable;
+- drive-strength = <16>;
+- };
+-
+- cmd {
+- pins = "sdc2_cmd";
+- bias-pull-up;
+- drive-strength = <10>;
+- };
+-
+- data {
+- pins = "sdc2_data";
+- bias-pull-up;
+- drive-strength = <10>;
+- };
+-
+- sd-cd {
+- pins = "gpio98";
+- bias-pull-up;
+- drive-strength = <2>;
+- };
+- };
+ };
+
+ &usb3 {
+diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi
+index e81b2a7794fb..3fadf5196c4d 100644
+--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi
+@@ -389,20 +389,40 @@ tlmm: pinctrl@500000 {
+ sdc2_state_off: sdc2-off {
+ clk {
+ pins = "sdc2_clk";
+- bias-disable;
+ drive-strength = <2>;
++ bias-disable;
+ };
+
+ cmd {
+ pins = "sdc2_cmd";
++ drive-strength = <2>;
+ bias-pull-up;
++ };
++
++ data {
++ pins = "sdc2_data";
+ drive-strength = <2>;
++ bias-pull-up;
++ };
++ };
++
++ sdc2_state_on: sdc2-on {
++ clk {
++ pins = "sdc2_clk";
++ drive-strength = <16>;
++ bias-disable;
++ };
++
++ cmd {
++ pins = "sdc2_cmd";
++ drive-strength = <10>;
++ bias-pull-up;
+ };
+
+ data {
+ pins = "sdc2_data";
++ drive-strength = <10>;
+ bias-pull-up;
+- drive-strength = <2>;
+ };
+ };
+ };
+--
+2.35.1
+
--- /dev/null
+From d5391cf1b49a3aa72d1f23011a1b8152a15e381e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 13:40:20 +0200
+Subject: arm64: dts: qcom: sm8250: add missing PCIe PHY clock-cells
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit d9fd162ce764c227fcfd4242f6c1639895a9481f ]
+
+Add the missing '#clock-cells' properties to the PCIe QMP PHY nodes.
+
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Fixes: e53bdfc00977 ("arm64: dts: qcom: sm8250: Add PCIe support")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220705114032.22787-3-johan+linaro@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8250.dtsi | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+index 1d62b2130e04..9afd8b3da3a1 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+@@ -1883,6 +1883,8 @@ pcie0_lane: phy@1c06200 {
+ clock-names = "pipe0";
+
+ #phy-cells = <0>;
++
++ #clock-cells = <0>;
+ clock-output-names = "pcie_0_pipe_clk";
+ };
+ };
+@@ -1989,6 +1991,8 @@ pcie1_lane: phy@1c0e200 {
+ clock-names = "pipe0";
+
+ #phy-cells = <0>;
++
++ #clock-cells = <0>;
+ clock-output-names = "pcie_1_pipe_clk";
+ };
+ };
+@@ -2095,6 +2099,8 @@ pcie2_lane: phy@1c16200 {
+ clock-names = "pipe0";
+
+ #phy-cells = <0>;
++
++ #clock-cells = <0>;
+ clock-output-names = "pcie_2_pipe_clk";
+ };
+ };
+--
+2.35.1
+
--- /dev/null
+From 106d91b54509f1b47d8d4a271f55fb6ca8ab1d98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 26 Jun 2022 12:57:59 +0200
+Subject: arm64: dts: qcom: timer should use only 32-bit size
+
+From: David Heidelberg <david@ixit.cz>
+
+[ Upstream commit 458ebdbb8e5d596a462d8125cec74142ff5dfa97 ]
+
+There's no reason the timer needs > 32-bits of address or size.
+Since we using 32-bit size, we need to define ranges properly.
+
+Fixes warnings as:
+```
+arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dt.yaml: timer@17c90000: #size-cells:0:0: 1 was expected
+ From schema: Documentation/devicetree/bindings/timer/arm,arch_timer_mmio.yaml
+```
+
+Signed-off-by: David Heidelberg <david@ixit.cz>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220626105800.35586-1-david@ixit.cz
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq6018.dtsi | 22 +++++++++++-----------
+ arch/arm64/boot/dts/qcom/sc7180.dtsi | 22 +++++++++++-----------
+ arch/arm64/boot/dts/qcom/sc7280.dtsi | 22 +++++++++++-----------
+ arch/arm64/boot/dts/qcom/sdm845.dtsi | 22 +++++++++++-----------
+ arch/arm64/boot/dts/qcom/sm6350.dtsi | 22 +++++++++++-----------
+ arch/arm64/boot/dts/qcom/sm8150.dtsi | 22 +++++++++++-----------
+ arch/arm64/boot/dts/qcom/sm8250.dtsi | 22 +++++++++++-----------
+ arch/arm64/boot/dts/qcom/sm8350.dtsi | 22 +++++++++++-----------
+ arch/arm64/boot/dts/qcom/sm8450.dtsi | 22 +++++++++++-----------
+ 9 files changed, 99 insertions(+), 99 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+index aac56575e30d..5cdec104d899 100644
+--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+@@ -525,9 +525,9 @@ timer {
+ };
+
+ timer@b120000 {
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0 0 0 0x10000000>;
+ compatible = "arm,armv7-timer-mem";
+ reg = <0x0 0x0b120000 0x0 0x1000>;
+
+@@ -535,49 +535,49 @@ frame@b120000 {
+ frame-number = <0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x0b121000 0x0 0x1000>,
+- <0x0 0x0b122000 0x0 0x1000>;
++ reg = <0x0b121000 0x1000>,
++ <0x0b122000 0x1000>;
+ };
+
+ frame@b123000 {
+ frame-number = <1>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0xb123000 0x0 0x1000>;
++ reg = <0x0b123000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b124000 {
+ frame-number = <2>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x0b124000 0x0 0x1000>;
++ reg = <0x0b124000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b125000 {
+ frame-number = <3>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x0b125000 0x0 0x1000>;
++ reg = <0x0b125000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b126000 {
+ frame-number = <4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x0b126000 0x0 0x1000>;
++ reg = <0x0b126000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b127000 {
+ frame-number = <5>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x0b127000 0x0 0x1000>;
++ reg = <0x0b127000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@b128000 {
+ frame-number = <6>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x0b128000 0x0 0x1000>;
++ reg = <0x0b128000 0x1000>;
+ status = "disabled";
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi
+index e1c46b80f14a..e9fb3c9a2d6e 100644
+--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
+@@ -3388,9 +3388,9 @@ watchdog@17c10000 {
+ };
+
+ timer@17c20000{
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0 0 0 0x20000000>;
+ compatible = "arm,armv7-timer-mem";
+ reg = <0 0x17c20000 0 0x1000>;
+
+@@ -3398,49 +3398,49 @@ frame@17c21000 {
+ frame-number = <0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17c21000 0 0x1000>,
+- <0 0x17c22000 0 0x1000>;
++ reg = <0x17c21000 0x1000>,
++ <0x17c22000 0x1000>;
+ };
+
+ frame@17c23000 {
+ frame-number = <1>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17c23000 0 0x1000>;
++ reg = <0x17c23000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c25000 {
+ frame-number = <2>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17c25000 0 0x1000>;
++ reg = <0x17c25000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c27000 {
+ frame-number = <3>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17c27000 0 0x1000>;
++ reg = <0x17c27000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c29000 {
+ frame-number = <4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17c29000 0 0x1000>;
++ reg = <0x17c29000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c2b000 {
+ frame-number = <5>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17c2b000 0 0x1000>;
++ reg = <0x17c2b000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c2d000 {
+ frame-number = <6>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17c2d000 0 0x1000>;
++ reg = <0x17c2d000 0x1000>;
+ status = "disabled";
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+index f0b64be63c21..8a4fd614d0a1 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+@@ -4395,9 +4395,9 @@ watchdog@17c10000 {
+ };
+
+ timer@17c20000 {
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0 0 0 0x20000000>;
+ compatible = "arm,armv7-timer-mem";
+ reg = <0 0x17c20000 0 0x1000>;
+
+@@ -4405,49 +4405,49 @@ frame@17c21000 {
+ frame-number = <0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17c21000 0 0x1000>,
+- <0 0x17c22000 0 0x1000>;
++ reg = <0x17c21000 0x1000>,
++ <0x17c22000 0x1000>;
+ };
+
+ frame@17c23000 {
+ frame-number = <1>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17c23000 0 0x1000>;
++ reg = <0x17c23000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c25000 {
+ frame-number = <2>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17c25000 0 0x1000>;
++ reg = <0x17c25000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c27000 {
+ frame-number = <3>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17c27000 0 0x1000>;
++ reg = <0x17c27000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c29000 {
+ frame-number = <4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17c29000 0 0x1000>;
++ reg = <0x17c29000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c2b000 {
+ frame-number = <5>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17c2b000 0 0x1000>;
++ reg = <0x17c2b000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c2d000 {
+ frame-number = <6>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17c2d000 0 0x1000>;
++ reg = <0x17c2d000 0x1000>;
+ status = "disabled";
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+index ad21cf465c98..cd0029ff8246 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+@@ -4942,9 +4942,9 @@ slimbam: dma-controller@17184000 {
+ };
+
+ timer@17c90000 {
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0 0 0 0x20000000>;
+ compatible = "arm,armv7-timer-mem";
+ reg = <0 0x17c90000 0 0x1000>;
+
+@@ -4952,49 +4952,49 @@ frame@17ca0000 {
+ frame-number = <0>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17ca0000 0 0x1000>,
+- <0 0x17cb0000 0 0x1000>;
++ reg = <0x17ca0000 0x1000>,
++ <0x17cb0000 0x1000>;
+ };
+
+ frame@17cc0000 {
+ frame-number = <1>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17cc0000 0 0x1000>;
++ reg = <0x17cc0000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17cd0000 {
+ frame-number = <2>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17cd0000 0 0x1000>;
++ reg = <0x17cd0000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17ce0000 {
+ frame-number = <3>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17ce0000 0 0x1000>;
++ reg = <0x17ce0000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17cf0000 {
+ frame-number = <4>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17cf0000 0 0x1000>;
++ reg = <0x17cf0000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17d00000 {
+ frame-number = <5>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17d00000 0 0x1000>;
++ reg = <0x17d00000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17d10000 {
+ frame-number = <6>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0 0x17d10000 0 0x1000>;
++ reg = <0x17d10000 0x1000>;
+ status = "disabled";
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi
+index d7c9edff19f7..c31fe27a46f2 100644
+--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi
+@@ -1090,57 +1090,57 @@ timer@17c20000 {
+ compatible = "arm,armv7-timer-mem";
+ reg = <0x0 0x17c20000 0x0 0x1000>;
+ clock-frequency = <19200000>;
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0 0 0 0x20000000>;
+
+ frame@17c21000 {
+ frame-number = <0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c21000 0x0 0x1000>,
+- <0x0 0x17c22000 0x0 0x1000>;
++ reg = <0x17c21000 0x1000>,
++ <0x17c22000 0x1000>;
+ };
+
+ frame@17c23000 {
+ frame-number = <1>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c23000 0x0 0x1000>;
++ reg = <0x17c23000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c25000 {
+ frame-number = <2>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c25000 0x0 0x1000>;
++ reg = <0x17c25000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c27000 {
+ frame-number = <3>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c27000 0x0 0x1000>;
++ reg = <0x17c27000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c29000 {
+ frame-number = <4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c29000 0x0 0x1000>;
++ reg = <0x17c29000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c2b000 {
+ frame-number = <5>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c2b000 0x0 0x1000>;
++ reg = <0x17c2b000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c2d000 {
+ frame-number = <6>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c2d000 0x0 0x1000>;
++ reg = <0x17c2d000 0x1000>;
+ status = "disabled";
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+index 15f3bf2e7ea0..d4f288edf3c9 100644
+--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+@@ -3608,9 +3608,9 @@ watchdog@17c10000 {
+ };
+
+ timer@17c20000 {
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0 0 0 0x20000000>;
+ compatible = "arm,armv7-timer-mem";
+ reg = <0x0 0x17c20000 0x0 0x1000>;
+ clock-frequency = <19200000>;
+@@ -3619,49 +3619,49 @@ frame@17c21000{
+ frame-number = <0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c21000 0x0 0x1000>,
+- <0x0 0x17c22000 0x0 0x1000>;
++ reg = <0x17c21000 0x1000>,
++ <0x17c22000 0x1000>;
+ };
+
+ frame@17c23000 {
+ frame-number = <1>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c23000 0x0 0x1000>;
++ reg = <0x17c23000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c25000 {
+ frame-number = <2>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c25000 0x0 0x1000>;
++ reg = <0x17c25000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c27000 {
+ frame-number = <3>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c26000 0x0 0x1000>;
++ reg = <0x17c26000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c29000 {
+ frame-number = <4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c29000 0x0 0x1000>;
++ reg = <0x17c29000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c2b000 {
+ frame-number = <5>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c2b000 0x0 0x1000>;
++ reg = <0x17c2b000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c2d000 {
+ frame-number = <6>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c2d000 0x0 0x1000>;
++ reg = <0x17c2d000 0x1000>;
+ status = "disabled";
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+index 1304b86af1a0..ed4e288c921f 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+@@ -4528,9 +4528,9 @@ watchdog@17c10000 {
+ };
+
+ timer@17c20000 {
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0 0 0 0x20000000>;
+ compatible = "arm,armv7-timer-mem";
+ reg = <0x0 0x17c20000 0x0 0x1000>;
+ clock-frequency = <19200000>;
+@@ -4539,49 +4539,49 @@ frame@17c21000 {
+ frame-number = <0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c21000 0x0 0x1000>,
+- <0x0 0x17c22000 0x0 0x1000>;
++ reg = <0x17c21000 0x1000>,
++ <0x17c22000 0x1000>;
+ };
+
+ frame@17c23000 {
+ frame-number = <1>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c23000 0x0 0x1000>;
++ reg = <0x17c23000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c25000 {
+ frame-number = <2>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c25000 0x0 0x1000>;
++ reg = <0x17c25000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c27000 {
+ frame-number = <3>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c27000 0x0 0x1000>;
++ reg = <0x17c27000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c29000 {
+ frame-number = <4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c29000 0x0 0x1000>;
++ reg = <0x17c29000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c2b000 {
+ frame-number = <5>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c2b000 0x0 0x1000>;
++ reg = <0x17c2b000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c2d000 {
+ frame-number = <6>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c2d000 0x0 0x1000>;
++ reg = <0x17c2d000 0x1000>;
+ status = "disabled";
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+index 20f850b94158..d843a550314a 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+@@ -1752,9 +1752,9 @@ intc: interrupt-controller@17a00000 {
+
+ timer@17c20000 {
+ compatible = "arm,armv7-timer-mem";
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0 0 0 0x20000000>;
+ reg = <0x0 0x17c20000 0x0 0x1000>;
+ clock-frequency = <19200000>;
+
+@@ -1762,49 +1762,49 @@ frame@17c21000 {
+ frame-number = <0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c21000 0x0 0x1000>,
+- <0x0 0x17c22000 0x0 0x1000>;
++ reg = <0x17c21000 0x1000>,
++ <0x17c22000 0x1000>;
+ };
+
+ frame@17c23000 {
+ frame-number = <1>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c23000 0x0 0x1000>;
++ reg = <0x17c23000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c25000 {
+ frame-number = <2>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c25000 0x0 0x1000>;
++ reg = <0x17c25000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c27000 {
+ frame-number = <3>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c27000 0x0 0x1000>;
++ reg = <0x17c27000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c29000 {
+ frame-number = <4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c29000 0x0 0x1000>;
++ reg = <0x17c29000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c2b000 {
+ frame-number = <5>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c2b000 0x0 0x1000>;
++ reg = <0x17c2b000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17c2d000 {
+ frame-number = <6>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17c2d000 0x0 0x1000>;
++ reg = <0x17c2d000 0x1000>;
+ status = "disabled";
+ };
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+index 7a14eb89e4ca..e5fe694b7be6 100644
+--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+@@ -1203,9 +1203,9 @@ intc: interrupt-controller@17100000 {
+
+ timer@17420000 {
+ compatible = "arm,armv7-timer-mem";
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0 0 0 0x20000000>;
+ reg = <0x0 0x17420000 0x0 0x1000>;
+ clock-frequency = <19200000>;
+
+@@ -1213,49 +1213,49 @@ frame@17421000 {
+ frame-number = <0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17421000 0x0 0x1000>,
+- <0x0 0x17422000 0x0 0x1000>;
++ reg = <0x17421000 0x1000>,
++ <0x17422000 0x1000>;
+ };
+
+ frame@17423000 {
+ frame-number = <1>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17423000 0x0 0x1000>;
++ reg = <0x17423000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17425000 {
+ frame-number = <2>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17425000 0x0 0x1000>;
++ reg = <0x17425000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17427000 {
+ frame-number = <3>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17427000 0x0 0x1000>;
++ reg = <0x17427000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@17429000 {
+ frame-number = <4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x17429000 0x0 0x1000>;
++ reg = <0x17429000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@1742b000 {
+ frame-number = <5>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x1742b000 0x0 0x1000>;
++ reg = <0x1742b000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@1742d000 {
+ frame-number = <6>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+- reg = <0x0 0x1742d000 0x0 0x1000>;
++ reg = <0x1742d000 0x1000>;
+ status = "disabled";
+ };
+ };
+--
+2.35.1
+
--- /dev/null
+From f6b9db0793682221b011441b0fae3b73d707c3fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 12:14:06 +0200
+Subject: arm64: dts: renesas: beacon: Fix regulator node names
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 7512af9f78dedea7e04225f665dad6750df7d095 ]
+
+Currently there are two nodes named "regulator_camera". This causes the
+former to be overwritten by the latter.
+
+Fix this by renaming them to unique names, using the preferred hyphen
+instead of an underscore.
+
+While at it, update the name of the audio regulator (which was added in
+the same commit) to use a hyphen.
+
+Fixes: a1d8a344f1ca0709 ("arm64: dts: renesas: Introduce r8a774a1-beacon-rzg2m-kit")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/a9ac82bdf108162487289d091c53a9b3de393f13.1652263918.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
+index 5ad6cd1864c1..c289d2bb5122 100644
+--- a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
++++ b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
+@@ -146,7 +146,7 @@ rgb_panel: endpoint {
+ };
+ };
+
+- reg_audio: regulator_audio {
++ reg_audio: regulator-audio {
+ compatible = "regulator-fixed";
+ regulator-name = "audio-1.8V";
+ regulator-min-microvolt = <1800000>;
+@@ -174,7 +174,7 @@ reg_lcd_reset: regulator-lcd-reset {
+ vin-supply = <®_lcd>;
+ };
+
+- reg_cam0: regulator_camera {
++ reg_cam0: regulator-cam0 {
+ compatible = "regulator-fixed";
+ regulator-name = "reg_cam0";
+ regulator-min-microvolt = <1800000>;
+@@ -183,7 +183,7 @@ reg_cam0: regulator_camera {
+ enable-active-high;
+ };
+
+- reg_cam1: regulator_camera {
++ reg_cam1: regulator-cam1 {
+ compatible = "regulator-fixed";
+ regulator-name = "reg_cam1";
+ regulator-min-microvolt = <1800000>;
+--
+2.35.1
+
--- /dev/null
+From 3f7c0fcbd424c91f0156a7913fc657a654e7676a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 16:04:26 +0200
+Subject: arm64: dts: renesas: Fix thermal-sensors on single-zone sensors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 62e8a53431145e06e503b71625a34eaa87b72b2c ]
+
+"make dtbs_check":
+
+ arch/arm64/boot/dts/renesas/r8a774c0-cat874.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[74], [0]] is too long
+ arch/arm64/boot/dts/renesas/r8a774c0-ek874.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[79], [0]] is too long
+ arch/arm64/boot/dts/renesas/r8a774c0-ek874-idk-2121wr.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[82], [0]] is too long
+ arch/arm64/boot/dts/renesas/r8a774c0-ek874-mipi-2.1.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[87], [0]] is too long
+ arch/arm64/boot/dts/renesas/r8a77990-ebisu.dtb: thermal-zones: cpu-thermal:thermal-sensors: [[105], [0]] is too long
+ From schema: Documentation/devicetree/bindings/thermal/thermal-zones.yaml
+
+Indeed, the thermal sensors on R-Car E3 and RZ/G2E support only a single
+zone, hence #thermal-sensor-cells = <0>.
+
+Fix this by dropping the bogus zero cell from the thermal sensor
+specifiers.
+
+Fixes: 8fa7d18f9ee2dc20 ("arm64: dts: renesas: r8a77990: Create thermal zone to support IPA")
+Fixes: 8438bfda9d768157 ("arm64: dts: renesas: r8a774c0: Create thermal zone to support IPA")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Link: https://lore.kernel.org/r/28b812fdd1fc3698311fac984ab8b91d3d655c1c.1655301684.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/r8a774c0.dtsi | 2 +-
+ arch/arm64/boot/dts/renesas/r8a77990.dtsi | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+index e123c8d1bab9..337efbeda5a9 100644
+--- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+@@ -1956,7 +1956,7 @@ thermal-zones {
+ cpu-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <0>;
+- thermal-sensors = <&thermal 0>;
++ thermal-sensors = <&thermal>;
+ sustainable-power = <717>;
+
+ cooling-maps {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+index 7e0f1aab2135..155589f67e1b 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+@@ -2117,7 +2117,7 @@ thermal-zones {
+ cpu-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <0>;
+- thermal-sensors = <&thermal 0>;
++ thermal-sensors = <&thermal>;
+ sustainable-power = <717>;
+
+ cooling-maps {
+--
+2.35.1
+
--- /dev/null
+From 87a55ef6f10b7348342eba9a42022887c5fd2e87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 11:36:58 +0200
+Subject: arm64: dts: renesas: r8a779m8: Drop operating points above 1.5 GHz
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit f48cb21a28c07d0754d5f2f85444cfb0e7b1fd05 ]
+
+The highest-performance mode for the Cortex-A57 CPU cores supported on
+R-Car H3Ne (R8A779M8) is the Power Optimized (1.5 GHz) mode. The Normal
+(1.6 GHz) and High Performance (1.7 GHz) modes are not supported.
+
+Hence drop the "turbo-mode" entries from the operating points table
+inherited from r8a77951.dtsi.
+
+Fixes: 6e87525d751fac57 ("arm64: dts: renesas: Add Renesas R8A779M8 SoC support")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/aeb4530f7fbac8329b334dcb169382c836a5f32d.1655458564.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/r8a779m8.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a779m8.dtsi b/arch/arm64/boot/dts/renesas/r8a779m8.dtsi
+index 752440b0c40f..750bd8ccdb7f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a779m8.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a779m8.dtsi
+@@ -10,3 +10,8 @@
+ / {
+ compatible = "renesas,r8a779m8", "renesas,r8a7795";
+ };
++
++&cluster0_opp {
++ /delete-node/ opp-1600000000;
++ /delete-node/ opp-1700000000;
++};
+--
+2.35.1
+
--- /dev/null
+From 9cba04e6cfd311ff4b11ba4b0a03e2a8694e7ce0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jun 2022 11:30:24 +0100
+Subject: arm64: dts: renesas: r9a07g054l2-smarc: Correct SoC name in comment
+
+From: Chris Paterson <chris.paterson2@renesas.com>
+
+[ Upstream commit d1273f541ab409242e08da6bb836bb564021274c ]
+
+This dts is for the RZ/V2L SMARC EVK, not RZ/G2L.
+
+Fixes: f91c4c74796a ("arm64: dts: renesas: Add initial device tree for RZ/V2L SMARC EVK")
+Signed-off-by: Chris Paterson <chris.paterson2@renesas.com>
+Link: https://lore.kernel.org/r/20220623103024.24222-1-chris.paterson2@renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts b/arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts
+index fc334b4c2aa4..d2848cbfc6c0 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts
++++ b/arch/arm64/boot/dts/renesas/r9a07g054l2-smarc.dts
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+ /*
+- * Device Tree Source for the RZ/G2L SMARC EVK board
++ * Device Tree Source for the RZ/V2L SMARC EVK board
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ */
+--
+2.35.1
+
--- /dev/null
+From 2caecdc542a5ded3d078ce49ea924df5e1a97000 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 17:15:23 +0100
+Subject: arm64: errata: Remove AES hwcap for COMPAT tasks
+
+From: James Morse <james.morse@arm.com>
+
+[ Upstream commit 44b3834b2eed595af07021b1c64e6f9bc396398b ]
+
+Cortex-A57 and Cortex-A72 have an erratum where an interrupt that
+occurs between a pair of AES instructions in aarch32 mode may corrupt
+the ELR. The task will subsequently produce the wrong AES result.
+
+The AES instructions are part of the cryptographic extensions, which are
+optional. User-space software will detect the support for these
+instructions from the hwcaps. If the platform doesn't support these
+instructions a software implementation should be used.
+
+Remove the hwcap bits on affected parts to indicate user-space should
+not use the AES instructions.
+
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: James Morse <james.morse@arm.com>
+Link: https://lore.kernel.org/r/20220714161523.279570-3-james.morse@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/arm64/silicon-errata.rst | 4 ++++
+ arch/arm64/Kconfig | 16 ++++++++++++++++
+ arch/arm64/kernel/cpu_errata.c | 16 ++++++++++++++++
+ arch/arm64/kernel/cpufeature.c | 14 +++++++++++++-
+ arch/arm64/tools/cpucaps | 1 +
+ 5 files changed, 50 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
+index d27db84d585e..0b4235b1f8c4 100644
+--- a/Documentation/arm64/silicon-errata.rst
++++ b/Documentation/arm64/silicon-errata.rst
+@@ -82,10 +82,14 @@ stable kernels.
+ +----------------+-----------------+-----------------+-----------------------------+
+ | ARM | Cortex-A57 | #1319537 | ARM64_ERRATUM_1319367 |
+ +----------------+-----------------+-----------------+-----------------------------+
++| ARM | Cortex-A57 | #1742098 | ARM64_ERRATUM_1742098 |
+++----------------+-----------------+-----------------+-----------------------------+
+ | ARM | Cortex-A72 | #853709 | N/A |
+ +----------------+-----------------+-----------------+-----------------------------+
+ | ARM | Cortex-A72 | #1319367 | ARM64_ERRATUM_1319367 |
+ +----------------+-----------------+-----------------+-----------------------------+
++| ARM | Cortex-A72 | #1655431 | ARM64_ERRATUM_1742098 |
+++----------------+-----------------+-----------------+-----------------------------+
+ | ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 |
+ +----------------+-----------------+-----------------+-----------------------------+
+ | ARM | Cortex-A76 | #1188873,1418040| ARM64_ERRATUM_1418040 |
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index 20ea89d9ac2f..b2d5a1e8eda3 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -500,6 +500,22 @@ config ARM64_ERRATUM_834220
+
+ If unsure, say Y.
+
++config ARM64_ERRATUM_1742098
++ bool "Cortex-A57/A72: 1742098: ELR recorded incorrectly on interrupt taken between cryptographic instructions in a sequence"
++ depends on COMPAT
++ default y
++ help
++ This option removes the AES hwcap for aarch32 user-space to
++ workaround erratum 1742098 on Cortex-A57 and Cortex-A72.
++
++ Affected parts may corrupt the AES state if an interrupt is
++ taken between a pair of AES instructions. These instructions
++ are only present if the cryptography extensions are present.
++ All software should have a fallback implementation for CPUs
++ that don't implement the cryptography extensions.
++
++ If unsure, say Y.
++
+ config ARM64_ERRATUM_845719
+ bool "Cortex-A53: 845719: a load might read incorrect data"
+ depends on COMPAT
+diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
+index a0f3d0aaa3c5..27baa41c46ca 100644
+--- a/arch/arm64/kernel/cpu_errata.c
++++ b/arch/arm64/kernel/cpu_errata.c
+@@ -395,6 +395,14 @@ static struct midr_range trbe_write_out_of_range_cpus[] = {
+ };
+ #endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */
+
++#ifdef CONFIG_ARM64_ERRATUM_1742098
++static struct midr_range broken_aarch32_aes[] = {
++ MIDR_RANGE(MIDR_CORTEX_A57, 0, 1, 0xf, 0xf),
++ MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
++ {},
++};
++#endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */
++
+ const struct arm64_cpu_capabilities arm64_errata[] = {
+ #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
+ {
+@@ -657,6 +665,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
+ /* Cortex-A510 r0p0 - r0p1 */
+ ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 1)
+ },
++#endif
++#ifdef CONFIG_ARM64_ERRATUM_1742098
++ {
++ .desc = "ARM erratum 1742098",
++ .capability = ARM64_WORKAROUND_1742098,
++ CAP_MIDR_RANGE_LIST(broken_aarch32_aes),
++ .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
++ },
+ #endif
+ {
+ }
+diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
+index 2cb9cc9e0eff..5357ba7ea3c7 100644
+--- a/arch/arm64/kernel/cpufeature.c
++++ b/arch/arm64/kernel/cpufeature.c
+@@ -79,6 +79,7 @@
+ #include <asm/cpufeature.h>
+ #include <asm/cpu_ops.h>
+ #include <asm/fpsimd.h>
++#include <asm/hwcap.h>
+ #include <asm/insn.h>
+ #include <asm/kvm_host.h>
+ #include <asm/mmu_context.h>
+@@ -1921,6 +1922,14 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
+ }
+ #endif /* CONFIG_ARM64_MTE */
+
++static void elf_hwcap_fixup(void)
++{
++#ifdef CONFIG_ARM64_ERRATUM_1742098
++ if (cpus_have_const_cap(ARM64_WORKAROUND_1742098))
++ compat_elf_hwcap2 &= ~COMPAT_HWCAP2_AES;
++#endif /* ARM64_ERRATUM_1742098 */
++}
++
+ #ifdef CONFIG_KVM
+ static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, int __unused)
+ {
+@@ -3033,8 +3042,10 @@ void __init setup_cpu_features(void)
+ setup_system_capabilities();
+ setup_elf_hwcaps(arm64_elf_hwcaps);
+
+- if (system_supports_32bit_el0())
++ if (system_supports_32bit_el0()) {
+ setup_elf_hwcaps(compat_elf_hwcaps);
++ elf_hwcap_fixup();
++ }
+
+ if (system_uses_ttbr0_pan())
+ pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n");
+@@ -3086,6 +3097,7 @@ static int enable_mismatched_32bit_el0(unsigned int cpu)
+ cpu_active_mask);
+ get_cpu_device(lucky_winner)->offline_disabled = true;
+ setup_elf_hwcaps(compat_elf_hwcaps);
++ elf_hwcap_fixup();
+ pr_info("Asymmetric 32-bit EL0 support detected on CPU %u; CPU hot-unplug disabled on CPU %u\n",
+ cpu, lucky_winner);
+ return 0;
+diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
+index 3ed418f70e3b..8cd6088f8875 100644
+--- a/arch/arm64/tools/cpucaps
++++ b/arch/arm64/tools/cpucaps
+@@ -58,6 +58,7 @@ WORKAROUND_1418040
+ WORKAROUND_1463225
+ WORKAROUND_1508412
+ WORKAROUND_1542419
++WORKAROUND_1742098
+ WORKAROUND_1902691
+ WORKAROUND_2038923
+ WORKAROUND_2064142
+--
+2.35.1
+
--- /dev/null
+From a10c2470e530e95460d9bef33fe594fefb8d0a3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Apr 2022 19:27:46 +0100
+Subject: arm64: Expand ESR_ELx_WFx_ISS_TI to match its ARMv8.7 definition
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit 6a437208cb942a2dd98f7e1c3fd347ed3d425ffc ]
+
+Starting with FEAT_WFXT in ARMv8.7, the TI field in the ISS
+that is reported on a WFx trap is expanded by one bit to
+allow the description of WFET and WFIT.
+
+Special care is taken to exclude the WFxT bit from the mask
+used to match WFI so that it also matches WFIT when trapped from
+EL0.
+
+Reviewed-by: Joey Gouly <joey.gouly@arm.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Acked-by: Catalin Marinas <catalin.marinas@arm.com>
+Link: https://lore.kernel.org/r/20220419182755.601427-2-maz@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/esr.h | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
+index d52a0b269ee8..65c2201b11b2 100644
+--- a/arch/arm64/include/asm/esr.h
++++ b/arch/arm64/include/asm/esr.h
+@@ -133,7 +133,8 @@
+ #define ESR_ELx_CV (UL(1) << 24)
+ #define ESR_ELx_COND_SHIFT (20)
+ #define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT)
+-#define ESR_ELx_WFx_ISS_TI (UL(1) << 0)
++#define ESR_ELx_WFx_ISS_TI (UL(3) << 0)
++#define ESR_ELx_WFx_ISS_WFxT (UL(2) << 0)
+ #define ESR_ELx_WFx_ISS_WFI (UL(0) << 0)
+ #define ESR_ELx_WFx_ISS_WFE (UL(1) << 0)
+ #define ESR_ELx_xVC_IMM_MASK ((1UL << 16) - 1)
+@@ -146,7 +147,8 @@
+ #define DISR_EL1_ESR_MASK (ESR_ELx_AET | ESR_ELx_EA | ESR_ELx_FSC)
+
+ /* ESR value templates for specific events */
+-#define ESR_ELx_WFx_MASK (ESR_ELx_EC_MASK | ESR_ELx_WFx_ISS_TI)
++#define ESR_ELx_WFx_MASK (ESR_ELx_EC_MASK | \
++ (ESR_ELx_WFx_ISS_TI & ~ESR_ELx_WFx_ISS_WFxT))
+ #define ESR_ELx_WFx_WFI_VAL ((ESR_ELx_EC_WFx << ESR_ELx_EC_SHIFT) | \
+ ESR_ELx_WFx_ISS_WFI)
+
+--
+2.35.1
+
--- /dev/null
+From f20ac7c1646c07963b9c019a16cd3d7de880dab9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Jul 2022 05:43:19 +0000
+Subject: arm64: fix oops in concurrently setting insn_emulation sysctls
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: haibinzhang (张海斌) <haibinzhang@tencent.com>
+
+[ Upstream commit af483947d472eccb79e42059276c4deed76f99a6 ]
+
+emulation_proc_handler() changes table->data for proc_dointvec_minmax
+and can generate the following Oops if called concurrently with itself:
+
+ | Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
+ | Internal error: Oops: 96000006 [#1] SMP
+ | Call trace:
+ | update_insn_emulation_mode+0xc0/0x148
+ | emulation_proc_handler+0x64/0xb8
+ | proc_sys_call_handler+0x9c/0xf8
+ | proc_sys_write+0x18/0x20
+ | __vfs_write+0x20/0x48
+ | vfs_write+0xe4/0x1d0
+ | ksys_write+0x70/0xf8
+ | __arm64_sys_write+0x20/0x28
+ | el0_svc_common.constprop.0+0x7c/0x1c0
+ | el0_svc_handler+0x2c/0xa0
+ | el0_svc+0x8/0x200
+
+To fix this issue, keep the table->data as &insn->current_mode and
+use container_of() to retrieve the insn pointer. Another mutex is
+used to protect against the current_mode update but not for retrieving
+insn_emulation as table->data is no longer changing.
+
+Co-developed-by: hewenliang <hewenliang4@huawei.com>
+Signed-off-by: hewenliang <hewenliang4@huawei.com>
+Signed-off-by: Haibin Zhang <haibinzhang@tencent.com>
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Link: https://lore.kernel.org/r/20220128090324.2727688-1-hewenliang4@huawei.com
+Link: https://lore.kernel.org/r/9A004C03-250B-46C5-BF39-782D7551B00E@tencent.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/armv8_deprecated.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
+index 6875a16b09d2..fb0e7c7b2e20 100644
+--- a/arch/arm64/kernel/armv8_deprecated.c
++++ b/arch/arm64/kernel/armv8_deprecated.c
+@@ -59,6 +59,7 @@ struct insn_emulation {
+ static LIST_HEAD(insn_emulation);
+ static int nr_insn_emulated __initdata;
+ static DEFINE_RAW_SPINLOCK(insn_emulation_lock);
++static DEFINE_MUTEX(insn_emulation_mutex);
+
+ static void register_emulation_hooks(struct insn_emulation_ops *ops)
+ {
+@@ -207,10 +208,10 @@ static int emulation_proc_handler(struct ctl_table *table, int write,
+ loff_t *ppos)
+ {
+ int ret = 0;
+- struct insn_emulation *insn = (struct insn_emulation *) table->data;
++ struct insn_emulation *insn = container_of(table->data, struct insn_emulation, current_mode);
+ enum insn_emulation_mode prev_mode = insn->current_mode;
+
+- table->data = &insn->current_mode;
++ mutex_lock(&insn_emulation_mutex);
+ ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+
+ if (ret || !write || prev_mode == insn->current_mode)
+@@ -223,7 +224,7 @@ static int emulation_proc_handler(struct ctl_table *table, int write,
+ update_insn_emulation_mode(insn, INSN_UNDEF);
+ }
+ ret:
+- table->data = insn;
++ mutex_unlock(&insn_emulation_mutex);
+ return ret;
+ }
+
+@@ -247,7 +248,7 @@ static void __init register_insn_emulation_sysctl(void)
+ sysctl->maxlen = sizeof(int);
+
+ sysctl->procname = insn->ops->name;
+- sysctl->data = insn;
++ sysctl->data = &insn->current_mode;
+ sysctl->extra1 = &insn->min;
+ sysctl->extra2 = &insn->max;
+ sysctl->proc_handler = emulation_proc_handler;
+--
+2.35.1
+
--- /dev/null
+From ed98b3d9c91a5815fb0465d50a37a9e961f6ea22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 16:21:41 +0100
+Subject: arm64: kasan: Revert "arm64: mte: reset the page tag in page->flags"
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+[ Upstream commit 20794545c14692094a882d2221c251c4573e6adf ]
+
+This reverts commit e5b8d9218951e59df986f627ec93569a0d22149b.
+
+Pages mapped in user-space with PROT_MTE have the allocation tags either
+zeroed or copied/restored to some user values. In order for the kernel
+to access such pages via page_address(), resetting the tag in
+page->flags was necessary. This tag resetting was deferred to
+set_pte_at() -> mte_sync_page_tags() but it can race with another CPU
+reading the flags (via page_to_virt()):
+
+P0 (mte_sync_page_tags): P1 (memcpy from virt_to_page):
+ Rflags!=0xff
+ Wflags=0xff
+ DMB (doesn't help)
+ Wtags=0
+ Rtags=0 // fault
+
+Since now the post_alloc_hook() function resets the page->flags tag when
+unpoisoning is skipped for user pages (including the __GFP_ZEROTAGS
+case), revert the arm64 commit calling page_kasan_tag_reset().
+
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
+Cc: Andrey Konovalov <andreyknvl@gmail.com>
+Cc: Peter Collingbourne <pcc@google.com>
+Reviewed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
+Acked-by: Andrey Konovalov <andreyknvl@gmail.com>
+Link: https://lore.kernel.org/r/20220610152141.2148929-5-catalin.marinas@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/hibernate.c | 5 -----
+ arch/arm64/kernel/mte.c | 9 ---------
+ arch/arm64/mm/copypage.c | 9 ---------
+ arch/arm64/mm/mteswap.c | 9 ---------
+ 4 files changed, 32 deletions(-)
+
+diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
+index 6328308be272..7754ef328657 100644
+--- a/arch/arm64/kernel/hibernate.c
++++ b/arch/arm64/kernel/hibernate.c
+@@ -300,11 +300,6 @@ static void swsusp_mte_restore_tags(void)
+ unsigned long pfn = xa_state.xa_index;
+ struct page *page = pfn_to_online_page(pfn);
+
+- /*
+- * It is not required to invoke page_kasan_tag_reset(page)
+- * at this point since the tags stored in page->flags are
+- * already restored.
+- */
+ mte_restore_page_tags(page_address(page), tags);
+
+ mte_free_tag_storage(tags);
+diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
+index d502703e8373..d565ae25e48f 100644
+--- a/arch/arm64/kernel/mte.c
++++ b/arch/arm64/kernel/mte.c
+@@ -47,15 +47,6 @@ static void mte_sync_page_tags(struct page *page, pte_t old_pte,
+ if (!pte_is_tagged)
+ return;
+
+- page_kasan_tag_reset(page);
+- /*
+- * We need smp_wmb() in between setting the flags and clearing the
+- * tags because if another thread reads page->flags and builds a
+- * tagged address out of it, there is an actual dependency to the
+- * memory access, but on the current thread we do not guarantee that
+- * the new page->flags are visible before the tags were updated.
+- */
+- smp_wmb();
+ mte_clear_page_tags(page_address(page));
+ }
+
+diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
+index 0dea80bf6de4..24913271e898 100644
+--- a/arch/arm64/mm/copypage.c
++++ b/arch/arm64/mm/copypage.c
+@@ -23,15 +23,6 @@ void copy_highpage(struct page *to, struct page *from)
+
+ if (system_supports_mte() && test_bit(PG_mte_tagged, &from->flags)) {
+ set_bit(PG_mte_tagged, &to->flags);
+- page_kasan_tag_reset(to);
+- /*
+- * We need smp_wmb() in between setting the flags and clearing the
+- * tags because if another thread reads page->flags and builds a
+- * tagged address out of it, there is an actual dependency to the
+- * memory access, but on the current thread we do not guarantee that
+- * the new page->flags are visible before the tags were updated.
+- */
+- smp_wmb();
+ mte_copy_page_tags(kto, kfrom);
+ }
+ }
+diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c
+index a9e50e930484..4334dec93bd4 100644
+--- a/arch/arm64/mm/mteswap.c
++++ b/arch/arm64/mm/mteswap.c
+@@ -53,15 +53,6 @@ bool mte_restore_tags(swp_entry_t entry, struct page *page)
+ if (!tags)
+ return false;
+
+- page_kasan_tag_reset(page);
+- /*
+- * We need smp_wmb() in between setting the flags and clearing the
+- * tags because if another thread reads page->flags and builds a
+- * tagged address out of it, there is an actual dependency to the
+- * memory access, but on the current thread we do not guarantee that
+- * the new page->flags are visible before the tags were updated.
+- */
+- smp_wmb();
+ mte_restore_page_tags(page_address(page), tags);
+
+ return true;
+--
+2.35.1
+
--- /dev/null
+From ec22025920bf09986b074ccfef576604b7f2d0af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 14:17:33 +0100
+Subject: arm64: select TRACE_IRQFLAGS_NMI_SUPPORT
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit 3381da254fab37ba08c4b7c4f19b4ee28b1a27ec ]
+
+Due to an oversight, on arm64 lockdep IRQ state tracking doesn't work as
+intended in NMI context. This demonstrably results in bogus warnings
+from lockdep, and in theory could mask a variety of issues.
+
+On arm64, we've consistently tracked IRQ flag state for NMIs (and
+saved/restored the state of the interrupted context) since commit:
+
+ f0cd5ac1e4c53cb6 ("arm64: entry: fix NMI {user, kernel}->kernel transitions")
+
+That commit fixed most lockdep issues with NMI by virtue of the
+save/restore of the lockdep state of the interrupted context. However,
+for lockdep IRQ state tracking to consistently take effect in NMI
+context it has been necessary to select TRACE_IRQFLAGS_NMI_SUPPORT since
+commit:
+
+ ed00495333ccc80f ("locking/lockdep: Fix TRACE_IRQFLAGS vs. NMIs")
+
+As arm64 does not select TRACE_IRQFLAGS_NMI_SUPPORT, this means that the
+lockdep state can be stale in NMI context, and some uses of that state
+can consume stale data.
+
+When an NMI is taken arm64 entry code will call arm64_enter_nmi(). This
+will enter NMI context via __nmi_enter() before calling
+lockdep_hardirqs_off() to inform lockdep that IRQs have been masked.
+Where TRACE_IRQFLAGS_NMI_SUPPORT is not selected, lockdep_hardirqs_off()
+will not update lockdep state if called in NMI context. Thus if IRQs
+were enabled in the original context, lockdep will continue to believe
+that IRQs are enabled despite the call to lockdep_hardirqs_off().
+
+However, the lockdep_assert_*() checks do take effect in NMI context,
+and will consume the stale lockdep state. If an NMI is taken from a
+context which had IRQs enabled, and during the handling of the NMI
+something calls lockdep_assert_irqs_disabled(), this will result in a
+spurious warning based upon the stale lockdep state.
+
+This can be seen when using perf with GICv3 pseudo-NMIs. Within the perf
+NMI handler we may attempt a uaccess to record the userspace callchain,
+and is this faults the el1_abort() call in the nested context will call
+exit_to_kernel_mode() when returning, which has a
+lockdep_assert_irqs_disabled() assertion:
+
+| # ./perf record -a -g sh
+| ------------[ cut here ]------------
+| WARNING: CPU: 0 PID: 164 at arch/arm64/kernel/entry-common.c:73 exit_to_kernel_mode+0x118/0x1ac
+| Modules linked in:
+| CPU: 0 PID: 164 Comm: perf Not tainted 5.18.0-rc5 #1
+| Hardware name: linux,dummy-virt (DT)
+| pstate: 004003c5 (nzcv DAIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+| pc : exit_to_kernel_mode+0x118/0x1ac
+| lr : el1_abort+0x80/0xbc
+| sp : ffff8000080039f0
+| pmr_save: 000000f0
+| x29: ffff8000080039f0 x28: ffff6831054e4980 x27: ffff683103adb400
+| x26: 0000000000000000 x25: 0000000000000001 x24: 0000000000000001
+| x23: 00000000804000c5 x22: 00000000000000c0 x21: 0000000000000001
+| x20: ffffbd51e635ec44 x19: ffff800008003a60 x18: 0000000000000000
+| x17: ffffaadf98d23000 x16: ffff800008004000 x15: 0000ffffd14f25c0
+| x14: 0000000000000000 x13: 00000000000018eb x12: 0000000000000040
+| x11: 000000000000001e x10: 000000002b820020 x9 : 0000000100110000
+| x8 : 000000000045cac0 x7 : 0000ffffd14f25c0 x6 : ffffbd51e639b000
+| x5 : 00000000000003e5 x4 : ffffbd51e58543b0 x3 : 0000000000000001
+| x2 : ffffaadf98d23000 x1 : ffff6831054e4980 x0 : 0000000100110000
+| Call trace:
+| exit_to_kernel_mode+0x118/0x1ac
+| el1_abort+0x80/0xbc
+| el1h_64_sync_handler+0xa4/0xd0
+| el1h_64_sync+0x74/0x78
+| __arch_copy_from_user+0xa4/0x230
+| get_perf_callchain+0x134/0x1e4
+| perf_callchain+0x7c/0xa0
+| perf_prepare_sample+0x414/0x660
+| perf_event_output_forward+0x80/0x180
+| __perf_event_overflow+0x70/0x13c
+| perf_event_overflow+0x1c/0x30
+| armv8pmu_handle_irq+0xe8/0x160
+| armpmu_dispatch_irq+0x2c/0x70
+| handle_percpu_devid_fasteoi_nmi+0x7c/0xbc
+| generic_handle_domain_nmi+0x3c/0x60
+| gic_handle_irq+0x1dc/0x310
+| call_on_irq_stack+0x2c/0x54
+| do_interrupt_handler+0x80/0x94
+| el1_interrupt+0xb0/0xe4
+| el1h_64_irq_handler+0x18/0x24
+| el1h_64_irq+0x74/0x78
+| lockdep_hardirqs_off+0x50/0x120
+| trace_hardirqs_off+0x38/0x214
+| _raw_spin_lock_irq+0x98/0xa0
+| pipe_read+0x1f8/0x404
+| new_sync_read+0x140/0x150
+| vfs_read+0x190/0x1dc
+| ksys_read+0xdc/0xfc
+| __arm64_sys_read+0x20/0x30
+| invoke_syscall+0x48/0x114
+| el0_svc_common.constprop.0+0x158/0x17c
+| do_el0_svc+0x28/0x90
+| el0_svc+0x60/0x150
+| el0t_64_sync_handler+0xa4/0x130
+| el0t_64_sync+0x19c/0x1a0
+| irq event stamp: 483
+| hardirqs last enabled at (483): [<ffffbd51e636aa24>] _raw_spin_unlock_irqrestore+0xa4/0xb0
+| hardirqs last disabled at (482): [<ffffbd51e636acd0>] _raw_spin_lock_irqsave+0xb0/0xb4
+| softirqs last enabled at (468): [<ffffbd51e5216f58>] put_cpu_fpsimd_context+0x28/0x70
+| softirqs last disabled at (466): [<ffffbd51e5216ed4>] get_cpu_fpsimd_context+0x0/0x5c
+| ---[ end trace 0000000000000000 ]---
+
+Note that as lockdep_assert_irqs_disabled() uses WARN_ON_ONCE(), and
+this uses a BRK, the warning is logged with the real PSTATE at the time
+of the warning, which clearly has DAIF.I set, meaning IRQs (and
+pseudo-NMIs) were definitely masked and the warning is spurious.
+
+Fix this by selecting TRACE_IRQFLAGS_NMI_SUPPORT such that the existing
+entry tracking takes effect, as we had originally intended when the
+arm64 entry code was fixed for transitions to/from NMI.
+
+Arguably the lockdep_assert_*() functions should have the same NMI
+checks as the rest of the code to prevent spurious warnings when
+TRACE_IRQFLAGS_NMI_SUPPORT is not selected, but the real fix for any
+architecture is to explicitly handle the transitions to/from NMI in the
+entry code.
+
+Fixes: f0cd5ac1e4c5 ("arm64: entry: fix NMI {user, kernel}->kernel transitions")
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20220511131733.4074499-3-mark.rutland@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index b2d5a1e8eda3..54cf6faf339c 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -223,6 +223,7 @@ config ARM64
+ select THREAD_INFO_IN_TASK
+ select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD
+ select TRACE_IRQFLAGS_SUPPORT
++ select TRACE_IRQFLAGS_NMI_SUPPORT
+ help
+ ARM 64-bit (AArch64) Linux support.
+
+--
+2.35.1
+
--- /dev/null
+From 90ce6aeef36a780fe376438f47820aa3e737fbce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jun 2022 14:59:45 +0000
+Subject: arm64: tegra: Fix SDMMC1 CD on P2888
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Tamás Szűcs <tszucs@protonmail.ch>
+
+[ Upstream commit b415bb7c976f1d595ed752001c0938f702645dab ]
+
+Hook SDMMC1 CD up with CVM GPIO02 (SOC_GPIO11) used for card detection on J4
+(uSD socket) on the carrier.
+
+Fixes: ef633bfc21e9 ("arm64: tegra: Enable card detect for SD card on P2888")
+Signed-off-by: Tamás Szűcs <tszucs@protonmail.ch>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
+index a7d7cfd66379..b0f9393dd39c 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
+@@ -75,7 +75,7 @@ eeprom@50 {
+
+ /* SDMMC1 (SD/MMC) */
+ mmc@3400000 {
+- cd-gpios = <&gpio TEGRA194_MAIN_GPIO(A, 0) GPIO_ACTIVE_LOW>;
++ cd-gpios = <&gpio TEGRA194_MAIN_GPIO(G, 7) GPIO_ACTIVE_LOW>;
+ };
+
+ /* SDMMC4 (eMMC) */
+--
+2.35.1
+
--- /dev/null
+From 70a9c7653799a3517896f826c79ac245d7e573db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jun 2022 16:23:00 +0300
+Subject: arm64: tegra: Mark BPMP channels as no-memory-wc
+
+From: Mikko Perttunen <mperttunen@nvidia.com>
+
+[ Upstream commit 61192a9d8a6367ae1b8234876941b037910a2459 ]
+
+The Tegra SYSRAM contains regions access to which is restricted to
+certain hardware blocks on the system, and speculative accesses to
+those will cause issues.
+
+Patch 'misc: sram: Only map reserved areas in Tegra SYSRAM' attempted
+to resolve this by only mapping the regions specified in the device
+tree on the assumption that there are no such restricted areas within
+the 64K-aligned area of memory that contains the memory we wish to map.
+
+Turns out this assumption is wrong, as there are such areas above the
+4K pages described in the device trees. As such, we need to use the
+bigger hammer that is no-memory-wc, which causes the memory to be
+mapped as Device memory to which speculative accesses are disallowed.
+
+As such, the previous patch in the series,
+ 'firmware: tegra: bpmp: do only aligned access to IPC memory area',
+is required with this patch to make the BPMP driver only issue aligned
+memory accesses as those are also required with Device memory.
+
+Fixes: fec29bf04994 ("misc: sram: Only map reserved areas in Tegra SYSRAM")
+Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
+Reviewed-by: Yousaf Kaukab <ykaukab@suse.de>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/nvidia/tegra186.dtsi | 1 +
+ arch/arm64/boot/dts/nvidia/tegra194.dtsi | 1 +
+ arch/arm64/boot/dts/nvidia/tegra234.dtsi | 1 +
+ 3 files changed, 3 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+index e9b40f5d79ec..77c597a6386f 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+@@ -1807,6 +1807,7 @@ sram@30000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x0 0x30000000 0x50000>;
++ no-memory-wc;
+
+ cpu_bpmp_tx: sram@4e000 {
+ reg = <0x4e000 0x1000>;
+diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+index 751ebe5e9506..61465eb6cccd 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+@@ -2648,6 +2648,7 @@ sram@40000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x0 0x40000000 0x50000>;
++ no-memory-wc;
+
+ cpu_bpmp_tx: sram@4e000 {
+ reg = <0x4e000 0x1000>;
+diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+index aaace605bdaa..9916b87fa83f 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+@@ -1264,6 +1264,7 @@ sram@40000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x0 0x40000000 0x80000>;
++ no-memory-wc;
+
+ cpu_bpmp_tx: sram@70000 {
+ reg = <0x70000 0x1000>;
+--
+2.35.1
+
--- /dev/null
+From e19282096a05de932877368998e009dbab019662 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 22:43:08 +0800
+Subject: ASoC: audio-graph-card: Add of_node_put() in fail path
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 65fb8e2ef3531a6e950060fca6e551c923fb0f0e ]
+
+In asoc_simple_parse_dai(), we should call of_node_put() for the
+reference returned by of_graph_get_port_parent() in fail path.
+
+Fixes: ae30a694da4c ("ASoC: simple-card-utils: add asoc_simple_card_parse_dai()")
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220721144308.1301587-1-windhl@126.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/generic/audio-graph-card.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
+index 2b598af8feef..b327372f2e4a 100644
+--- a/sound/soc/generic/audio-graph-card.c
++++ b/sound/soc/generic/audio-graph-card.c
+@@ -158,8 +158,10 @@ static int asoc_simple_parse_dai(struct device_node *ep,
+ * if he unbinded CPU or Codec.
+ */
+ ret = snd_soc_get_dai_name(&args, &dlc->dai_name);
+- if (ret < 0)
++ if (ret < 0) {
++ of_node_put(node);
+ return ret;
++ }
+
+ dlc->of_node = node;
+
+--
+2.35.1
+
--- /dev/null
+From dd00e4dc8a7ba04570687aba442655bf43836098 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 22:18:01 +0800
+Subject: ASoC: audio-graph-card2: Add of_node_put() in fail path
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 8ebc4dd8250fd1cb5da2869c0fe6ae3686fe41e9 ]
+
+In asoc_simple_parse_dai(), we should call of_node_put() for the
+reference returned by of_graph_get_port_parent() in fail path.
+
+Fixes: 6e5f68fe3f2d ("ASoC: add Audio Graph Card2 driver")
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220722141801.1304854-1-windhl@126.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/generic/audio-graph-card2.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c
+index ba3551d9a040..da782403316f 100644
+--- a/sound/soc/generic/audio-graph-card2.c
++++ b/sound/soc/generic/audio-graph-card2.c
+@@ -445,8 +445,10 @@ static int asoc_simple_parse_dai(struct device_node *ep,
+ * if he unbinded CPU or Codec.
+ */
+ ret = snd_soc_get_dai_name(&args, &dlc->dai_name);
+- if (ret < 0)
++ if (ret < 0) {
++ of_node_put(node);
+ return ret;
++ }
+
+ dlc->of_node = node;
+
+--
+2.35.1
+
--- /dev/null
+From d684683460fc7c0ed7a5d2eef57015a2294c28b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 15:12:00 +0800
+Subject: ASoc: audio-graph-card2: Fix refcount leak bug in __graph_get_type()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit eda26893dabfc6da7a1e1ff5f8628ed9faab3ab9 ]
+
+We should call of_node_put() for the reference before its replacement
+as it returned by of_get_parent() which has increased the refcount.
+Besides, we should also call of_node_put() before return.
+
+Fixes: c8c74939f791 ("ASoC: audio-graph-card2: add Multi CPU/Codec support")
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220713071200.366729-1-windhl@126.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/generic/audio-graph-card2.c | 35 +++++++++++++++++++--------
+ 1 file changed, 25 insertions(+), 10 deletions(-)
+
+diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c
+index 328af836cf53..ba3551d9a040 100644
+--- a/sound/soc/generic/audio-graph-card2.c
++++ b/sound/soc/generic/audio-graph-card2.c
+@@ -229,7 +229,8 @@ enum graph_type {
+
+ static enum graph_type __graph_get_type(struct device_node *lnk)
+ {
+- struct device_node *np;
++ struct device_node *np, *parent_np;
++ enum graph_type ret;
+
+ /*
+ * target {
+@@ -240,19 +241,33 @@ static enum graph_type __graph_get_type(struct device_node *lnk)
+ * };
+ */
+ np = of_get_parent(lnk);
+- if (of_node_name_eq(np, "ports"))
+- np = of_get_parent(np);
++ if (of_node_name_eq(np, "ports")) {
++ parent_np = of_get_parent(np);
++ of_node_put(np);
++ np = parent_np;
++ }
+
+- if (of_node_name_eq(np, GRAPH_NODENAME_MULTI))
+- return GRAPH_MULTI;
++ if (of_node_name_eq(np, GRAPH_NODENAME_MULTI)) {
++ ret = GRAPH_MULTI;
++ goto out_put;
++ }
+
+- if (of_node_name_eq(np, GRAPH_NODENAME_DPCM))
+- return GRAPH_DPCM;
++ if (of_node_name_eq(np, GRAPH_NODENAME_DPCM)) {
++ ret = GRAPH_DPCM;
++ goto out_put;
++ }
+
+- if (of_node_name_eq(np, GRAPH_NODENAME_C2C))
+- return GRAPH_C2C;
++ if (of_node_name_eq(np, GRAPH_NODENAME_C2C)) {
++ ret = GRAPH_C2C;
++ goto out_put;
++ }
++
++ ret = GRAPH_NORMAL;
++
++out_put:
++ of_node_put(np);
++ return ret;
+
+- return GRAPH_NORMAL;
+ }
+
+ static enum graph_type graph_get_type(struct asoc_simple_priv *priv,
+--
+2.35.1
+
--- /dev/null
+From e8ff03d90ae87a8f2b24781bce884e9c03193181 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 05:18:14 +0000
+Subject: ASoC: audio-graph-card2.c: use of_property_read_u32() for rate
+
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+
+[ Upstream commit 817a62108dfacebd548e38451bf0e7eee023e97f ]
+
+Audio Graph Card2 is using of_get_property(), but it should use
+of_property_read_u32() to getting rate. Otherwise the setting will be
+strange value. This patch fixup it.
+
+Fixes: c3a15c92a67b701 ("ASoC: audio-graph-card2: add Codec2Codec support")
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Link: https://lore.kernel.org/r/87h741s961.wl-kuninori.morimoto.gx@renesas.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/generic/audio-graph-card2.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c
+index c0f3907a01fd..328af836cf53 100644
+--- a/sound/soc/generic/audio-graph-card2.c
++++ b/sound/soc/generic/audio-graph-card2.c
+@@ -856,7 +856,7 @@ int audio_graph2_link_c2c(struct asoc_simple_priv *priv,
+ struct device_node *port0, *port1, *ports;
+ struct device_node *codec0_port, *codec1_port;
+ struct device_node *ep0, *ep1;
+- u32 val;
++ u32 val = 0;
+ int ret = -EINVAL;
+
+ /*
+@@ -880,7 +880,8 @@ int audio_graph2_link_c2c(struct asoc_simple_priv *priv,
+ ports = of_get_parent(port0);
+ port1 = of_get_next_child(ports, lnk);
+
+- if (!of_get_property(ports, "rate", &val)) {
++ of_property_read_u32(ports, "rate", &val);
++ if (!val) {
+ struct device *dev = simple_priv_to_dev(priv);
+
+ dev_err(dev, "Codec2Codec needs rate settings\n");
+--
+2.35.1
+
--- /dev/null
+From 194a1a25712a7db697de839d11bcbe63c5e7ae68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 May 2022 17:47:12 +0800
+Subject: ASoC: codecs: da7210: add check for i2c_add_driver
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 82fa8f581a954ddeec1602bed9f8b4a09d100e6e ]
+
+As i2c_add_driver could return error if fails, it should be
+better to check the return value.
+However, if the CONFIG_I2C and CONFIG_SPI_MASTER are both true,
+the return value of i2c_add_driver will be covered by
+spi_register_driver.
+Therefore, it is necessary to add check and return error if fails.
+
+Fixes: aa0e25caafb7 ("ASoC: da7210: Add support for spi regmap")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20220531094712.2376759-1-jiasheng@iscas.ac.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/da7210.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
+index 8af344b2fdbf..d75d15006f64 100644
+--- a/sound/soc/codecs/da7210.c
++++ b/sound/soc/codecs/da7210.c
+@@ -1336,6 +1336,8 @@ static int __init da7210_modinit(void)
+ int ret = 0;
+ #if IS_ENABLED(CONFIG_I2C)
+ ret = i2c_add_driver(&da7210_i2c_driver);
++ if (ret)
++ return ret;
+ #endif
+ #if defined(CONFIG_SPI_MASTER)
+ ret = spi_register_driver(&da7210_spi_driver);
+--
+2.35.1
+
--- /dev/null
+From 3fd6e5d0e156e6632dd224d880dba1635042a649 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 12:19:00 +0100
+Subject: ASoC: codecs: msm8916-wcd-digital: move gains from SX_TLV to S8_TLV
+
+From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+
+[ Upstream commit 5babb012c847beb6c8c7108fd78f650b7a2c6054 ]
+
+move all the digital gains form using SX_TLV to S8_TLV, these gains are
+actually 8 bit gains with 7th signed bit and ranges from -84dB to +40dB
+
+rest of the Qualcomm wcd codecs uses these properly.
+
+Fixes: ef8a4757a6db ("ASoC: msm8916-wcd-digital: Add sidetone support")
+Fixes: 150db8c5afa1 ("ASoC: codecs: Add msm8916-wcd digital codec")
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20220609111901.318047-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/msm8916-wcd-digital.c | 46 +++++++++++++-------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c
+index 20a07c92b2fc..098a58990f07 100644
+--- a/sound/soc/codecs/msm8916-wcd-digital.c
++++ b/sound/soc/codecs/msm8916-wcd-digital.c
+@@ -328,8 +328,8 @@ static const struct snd_kcontrol_new rx1_mix2_inp1_mux = SOC_DAPM_ENUM(
+ static const struct snd_kcontrol_new rx2_mix2_inp1_mux = SOC_DAPM_ENUM(
+ "RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum);
+
+-/* Digital Gain control -38.4 dB to +38.4 dB in 0.3 dB steps */
+-static const DECLARE_TLV_DB_SCALE(digital_gain, -3840, 30, 0);
++/* Digital Gain control -84 dB to +40 dB in 1 dB steps */
++static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400);
+
+ /* Cutoff Freq for High Pass Filter at -3dB */
+ static const char * const hpf_cutoff_text[] = {
+@@ -510,15 +510,15 @@ static int wcd_iir_filter_info(struct snd_kcontrol *kcontrol,
+
+ static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = {
+ SOC_SINGLE_S8_TLV("RX1 Digital Volume", LPASS_CDC_RX1_VOL_CTL_B2_CTL,
+- -128, 127, digital_gain),
++ -84, 40, digital_gain),
+ SOC_SINGLE_S8_TLV("RX2 Digital Volume", LPASS_CDC_RX2_VOL_CTL_B2_CTL,
+- -128, 127, digital_gain),
++ -84, 40, digital_gain),
+ SOC_SINGLE_S8_TLV("RX3 Digital Volume", LPASS_CDC_RX3_VOL_CTL_B2_CTL,
+- -128, 127, digital_gain),
++ -84, 40, digital_gain),
+ SOC_SINGLE_S8_TLV("TX1 Digital Volume", LPASS_CDC_TX1_VOL_CTL_GAIN,
+- -128, 127, digital_gain),
++ -84, 40, digital_gain),
+ SOC_SINGLE_S8_TLV("TX2 Digital Volume", LPASS_CDC_TX2_VOL_CTL_GAIN,
+- -128, 127, digital_gain),
++ -84, 40, digital_gain),
+ SOC_ENUM("TX1 HPF Cutoff", tx1_hpf_cutoff_enum),
+ SOC_ENUM("TX2 HPF Cutoff", tx2_hpf_cutoff_enum),
+ SOC_SINGLE("TX1 HPF Switch", LPASS_CDC_TX1_MUX_CTL, 3, 1, 0),
+@@ -553,22 +553,22 @@ static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = {
+ WCD_IIR_FILTER_CTL("IIR2 Band3", IIR2, BAND3),
+ WCD_IIR_FILTER_CTL("IIR2 Band4", IIR2, BAND4),
+ WCD_IIR_FILTER_CTL("IIR2 Band5", IIR2, BAND5),
+- SOC_SINGLE_SX_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL,
+- 0, -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL,
++ -84, 40, digital_gain),
+
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 5d50220041f25d78da21a4ffd072fc04a5b7515b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 12:19:01 +0100
+Subject: ASoC: codecs: wcd9335: move gains from SX_TLV to S8_TLV
+
+From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+
+[ Upstream commit 2fbe0953732e06b471cdedbf6f615b84235580d8 ]
+
+move all the digital gains form using SX_TLV to S8_TLV, these gains are
+actually 8 bit gains with 7th signed bit and ranges from -84dB to +40dB
+
+rest of the Qualcomm wcd codecs uses these properly.
+
+Fixes: 8c4f021d806a ("ASoC: wcd9335: add basic controls")
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20220609111901.318047-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/wcd9335.c | 81 +++++++++++++++++---------------------
+ 1 file changed, 36 insertions(+), 45 deletions(-)
+
+diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
+index aa685980a97b..b7c5bfc44127 100644
+--- a/sound/soc/codecs/wcd9335.c
++++ b/sound/soc/codecs/wcd9335.c
+@@ -2259,51 +2259,42 @@ static int wcd9335_rx_hph_mode_put(struct snd_kcontrol *kc,
+
+ static const struct snd_kcontrol_new wcd9335_snd_controls[] = {
+ /* -84dB min - 40dB max */
+- SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume",
+- WCD9335_CDC_RX0_RX_VOL_MIX_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume",
+- WCD9335_CDC_RX1_RX_VOL_MIX_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume",
+- WCD9335_CDC_RX2_RX_VOL_MIX_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume",
+- WCD9335_CDC_RX3_RX_VOL_MIX_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume",
+- WCD9335_CDC_RX4_RX_VOL_MIX_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume",
+- WCD9335_CDC_RX5_RX_VOL_MIX_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume",
+- WCD9335_CDC_RX6_RX_VOL_MIX_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume",
+- WCD9335_CDC_RX7_RX_VOL_MIX_CTL,
+- 0, -84, 40, digital_gain),
+- SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume",
+- WCD9335_CDC_RX8_RX_VOL_MIX_CTL,
+- 0, -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX0 Mix Digital Volume", WCD9335_CDC_RX0_RX_VOL_MIX_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX1 Mix Digital Volume", WCD9335_CDC_RX1_RX_VOL_MIX_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX2 Mix Digital Volume", WCD9335_CDC_RX2_RX_VOL_MIX_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX3 Mix Digital Volume", WCD9335_CDC_RX3_RX_VOL_MIX_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX4 Mix Digital Volume", WCD9335_CDC_RX4_RX_VOL_MIX_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX5 Mix Digital Volume", WCD9335_CDC_RX5_RX_VOL_MIX_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX6 Mix Digital Volume", WCD9335_CDC_RX6_RX_VOL_MIX_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX7 Mix Digital Volume", WCD9335_CDC_RX7_RX_VOL_MIX_CTL,
++ -84, 40, digital_gain),
++ SOC_SINGLE_S8_TLV("RX8 Mix Digital Volume", WCD9335_CDC_RX8_RX_VOL_MIX_CTL,
++ -84, 40, digital_gain),
+ SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum),
+ SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum),
+ SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum),
+--
+2.35.1
+
--- /dev/null
+From caea522604c8ccf97825ba7bb3b081162ad5ef67 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jun 2022 14:00:22 +0100
+Subject: ASoC: codecs: wsa881x: handle timeouts in resume path
+
+From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+
+[ Upstream commit cf6af24b54903f9f70c29b3e5b19cb72cc862d60 ]
+
+Currently we do not check if SoundWire slave initialization timeout
+expired before continuing to access its registers.
+
+Its possible that the registers are not accessible if timeout is
+expired. Handle this by returning timeout in resume path.
+
+Reported-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Fixes: 8dd552458361 ("ASoC: codecs: wsa881x: add runtime pm support")
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20220630130023.9308-1-srinivas.kandagatla@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/wsa881x.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c
+index 616b26c70c3b..649c7e73f774 100644
+--- a/sound/soc/codecs/wsa881x.c
++++ b/sound/soc/codecs/wsa881x.c
+@@ -1174,11 +1174,17 @@ static int __maybe_unused wsa881x_runtime_resume(struct device *dev)
+ struct sdw_slave *slave = dev_to_sdw_dev(dev);
+ struct regmap *regmap = dev_get_regmap(dev, NULL);
+ struct wsa881x_priv *wsa881x = dev_get_drvdata(dev);
++ unsigned long time;
+
+ gpiod_direction_output(wsa881x->sd_n, 1);
+
+- wait_for_completion_timeout(&slave->initialization_complete,
+- msecs_to_jiffies(WSA881X_PROBE_TIMEOUT));
++ time = wait_for_completion_timeout(&slave->initialization_complete,
++ msecs_to_jiffies(WSA881X_PROBE_TIMEOUT));
++ if (!time) {
++ dev_err(dev, "Initialization not complete, timed out\n");
++ gpiod_direction_output(wsa881x->sd_n, 0);
++ return -ETIMEDOUT;
++ }
+
+ regcache_cache_only(regmap, false);
+ regcache_sync(regmap);
+--
+2.35.1
+
--- /dev/null
+From f21f047eb6e7d96d5cd2bca26e6bcddf6609f0e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 17:10:43 +0400
+Subject: ASoC: cros_ec_codec: Fix refcount leak in
+ cros_ec_codec_platform_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 0a034d93ee929a9ea89f3fa5f1d8492435b9ee6e ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: b6bc07d4360d ("ASoC: cros_ec_codec: support WoV")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Link: https://lore.kernel.org/r/20220603131043.38907-1-linmq006@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/cros_ec_codec.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c
+index 9b92e1a0d1a3..43561ff1bb8d 100644
+--- a/sound/soc/codecs/cros_ec_codec.c
++++ b/sound/soc/codecs/cros_ec_codec.c
+@@ -994,6 +994,7 @@ static int cros_ec_codec_platform_probe(struct platform_device *pdev)
+ dev_dbg(dev, "ap_shm_phys_addr=%#llx len=%#x\n",
+ priv->ap_shm_phys_addr, priv->ap_shm_len);
+ }
++ of_node_put(node);
+ }
+ #endif
+
+--
+2.35.1
+
--- /dev/null
+From 0913b0b7f4837d37b1ad25bb40ab4c27df217c23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 18:29:51 +0800
+Subject: ASoC: fsl-asoc-card: force cast the asrc_format type
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit 6c7b077dad62178c33f9a3ae17f90d6b0bf6e2e5 ]
+
+Fix sparse warning:
+sound/soc/fsl/fsl-asoc-card.c:833:45: sparse: warning: incorrect type in argument 3 (different base types)
+sound/soc/fsl/fsl-asoc-card.c:833:45: sparse: expected unsigned int [usertype] *out_value
+sound/soc/fsl/fsl-asoc-card.c:833:45: sparse: got restricted snd_pcm_format_t *
+
+Fixes: 859e364302c5 ("ASoC: fsl-asoc-card: Support new property fsl, asrc-format")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1658399393-28777-4-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl-asoc-card.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
+index d9a0d4768c4d..c836848ef0a6 100644
+--- a/sound/soc/fsl/fsl-asoc-card.c
++++ b/sound/soc/fsl/fsl-asoc-card.c
+@@ -537,6 +537,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
+ struct device *codec_dev = NULL;
+ const char *codec_dai_name;
+ const char *codec_dev_name;
++ u32 asrc_fmt = 0;
+ u32 width;
+ int ret;
+
+@@ -829,8 +830,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
+ goto asrc_fail;
+ }
+
+- ret = of_property_read_u32(asrc_np, "fsl,asrc-format",
+- &priv->asrc_format);
++ ret = of_property_read_u32(asrc_np, "fsl,asrc-format", &asrc_fmt);
++ priv->asrc_format = (__force snd_pcm_format_t)asrc_fmt;
+ if (ret) {
+ /* Fallback to old binding; translate to asrc_format */
+ ret = of_property_read_u32(asrc_np, "fsl,asrc-width",
+--
+2.35.1
+
--- /dev/null
+From f1f952ca278c4795979100fe742d023a4054fb7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 18:29:50 +0800
+Subject: ASoC: fsl_asrc: force cast the asrc_format type
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit c49932726de24405d45516b3f8ad2735714fdf05 ]
+
+Fix sparse warning:
+sound/soc/fsl/fsl_asrc.c:1177:60: sparse: warning: incorrect type in argument 3 (different base types)
+sound/soc/fsl/fsl_asrc.c:1177:60: sparse: expected unsigned int [usertype] *out_value
+sound/soc/fsl/fsl_asrc.c:1177:60: sparse: got restricted snd_pcm_format_t *
+sound/soc/fsl/fsl_asrc.c:1200:47: sparse: warning: restricted snd_pcm_format_t degrades to integer
+
+Fixes: 4520af41fd21 ("ASoC: fsl_asrc: Support new property fsl,asrc-format")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1658399393-28777-3-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_asrc.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
+index d7d1536a4f37..44dcbf49456c 100644
+--- a/sound/soc/fsl/fsl_asrc.c
++++ b/sound/soc/fsl/fsl_asrc.c
+@@ -1066,6 +1066,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
+ struct resource *res;
+ void __iomem *regs;
+ int irq, ret, i;
++ u32 asrc_fmt = 0;
+ u32 map_idx;
+ char tmp[16];
+ u32 width;
+@@ -1174,7 +1175,8 @@ static int fsl_asrc_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+- ret = of_property_read_u32(np, "fsl,asrc-format", &asrc->asrc_format);
++ ret = of_property_read_u32(np, "fsl,asrc-format", &asrc_fmt);
++ asrc->asrc_format = (__force snd_pcm_format_t)asrc_fmt;
+ if (ret) {
+ ret = of_property_read_u32(np, "fsl,asrc-width", &width);
+ if (ret) {
+@@ -1197,7 +1199,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
+ }
+ }
+
+- if (!(FSL_ASRC_FORMATS & (1ULL << asrc->asrc_format))) {
++ if (!(FSL_ASRC_FORMATS & pcm_format_to_bits(asrc->asrc_format))) {
+ dev_warn(&pdev->dev, "unsupported width, use default S24_LE\n");
+ asrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
+ }
+--
+2.35.1
+
--- /dev/null
+From d577a806ea9135e2a6ac7db0c436832773f1aedd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 18:29:52 +0800
+Subject: ASoC: fsl_easrc: use snd_pcm_format_t type for sample_format
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit de27216cf2d645c2fd14e513707bdcd54e5b1de4 ]
+
+Fix sparse warning:
+sound/soc/fsl/fsl_easrc.c:562:33: sparse: warning: restricted snd_pcm_format_t degrades to integer
+sound/soc/fsl/fsl_easrc.c:563:34: sparse: warning: restricted snd_pcm_format_t degrades to integer
+sound/soc/fsl/fsl_easrc.c:565:38: sparse: warning: restricted snd_pcm_format_t degrades to integer
+sound/soc/fsl/fsl_easrc.c:566:39: sparse: warning: restricted snd_pcm_format_t degrades to integer
+sound/soc/fsl/fsl_easrc.c:608:33: sparse: warning: restricted snd_pcm_format_t degrades to integer
+sound/soc/fsl/fsl_easrc.c:609:34: sparse: warning: restricted snd_pcm_format_t degrades to integer
+sound/soc/fsl/fsl_easrc.c:615:40: sparse: warning: restricted snd_pcm_format_t degrades to integer
+sound/soc/fsl/fsl_easrc.c:616:41: sparse: warning: restricted snd_pcm_format_t degrades to integer
+
+sound/soc/fsl/fsl_easrc.c:1465:51: sparse: warning: incorrect type in assignment (different base types)
+sound/soc/fsl/fsl_easrc.c:1465:51: sparse: expected unsigned int sample_format
+sound/soc/fsl/fsl_easrc.c:1465:51: sparse: got restricted snd_pcm_format_t [usertype] format
+sound/soc/fsl/fsl_easrc.c:1467:52: sparse: warning: incorrect type in assignment (different base types)
+sound/soc/fsl/fsl_easrc.c:1467:52: sparse: expected unsigned int sample_format
+sound/soc/fsl/fsl_easrc.c:1467:52: sparse: got restricted snd_pcm_format_t [usertype] asrc_format
+sound/soc/fsl/fsl_easrc.c:1470:52: sparse: warning: incorrect type in assignment (different base types)
+sound/soc/fsl/fsl_easrc.c:1470:52: sparse: expected unsigned int sample_format
+sound/soc/fsl/fsl_easrc.c:1470:52: sparse: got restricted snd_pcm_format_t [usertype] format
+sound/soc/fsl/fsl_easrc.c:1472:51: sparse: warning: incorrect type in assignment (different base types)
+sound/soc/fsl/fsl_easrc.c:1472:51: sparse: expected unsigned int sample_format
+sound/soc/fsl/fsl_easrc.c:1472:51: sparse: got restricted snd_pcm_format_t [usertype] asrc_format
+sound/soc/fsl/fsl_easrc.c:1484:41: sparse: warning: incorrect type in argument 2 (different base types)
+sound/soc/fsl/fsl_easrc.c:1484:41: sparse: expected restricted snd_pcm_format_t [usertype] *in_raw_format
+sound/soc/fsl/fsl_easrc.c:1484:41: sparse: got unsigned int *
+sound/soc/fsl/fsl_easrc.c:1485:41: sparse: warning: incorrect type in argument 3 (different base types)
+sound/soc/fsl/fsl_easrc.c:1485:41: sparse: expected restricted snd_pcm_format_t [usertype] *out_raw_format
+sound/soc/fsl/fsl_easrc.c:1485:41: sparse: got unsigned int *
+sound/soc/fsl/fsl_easrc.c:1937:60: sparse: warning: incorrect type in argument 3 (different base types)
+sound/soc/fsl/fsl_easrc.c:1937:60: sparse: expected unsigned int [usertype] *out_value
+sound/soc/fsl/fsl_easrc.c:1937:60: sparse: got restricted snd_pcm_format_t *
+sound/soc/fsl/fsl_easrc.c:1943:49: sparse: warning: restricted snd_pcm_format_t degrades to integer
+
+Fixes: 955ac624058f ("ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1658399393-28777-5-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_easrc.c | 9 ++++++---
+ sound/soc/fsl/fsl_easrc.h | 2 +-
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
+index be14f84796cb..cf0e10d17dbe 100644
+--- a/sound/soc/fsl/fsl_easrc.c
++++ b/sound/soc/fsl/fsl_easrc.c
+@@ -476,7 +476,8 @@ static int fsl_easrc_prefilter_config(struct fsl_asrc *easrc,
+ struct fsl_asrc_pair *ctx;
+ struct device *dev;
+ u32 inrate, outrate, offset = 0;
+- u32 in_s_rate, out_s_rate, in_s_fmt, out_s_fmt;
++ u32 in_s_rate, out_s_rate;
++ snd_pcm_format_t in_s_fmt, out_s_fmt;
+ int ret, i;
+
+ if (!easrc)
+@@ -1873,6 +1874,7 @@ static int fsl_easrc_probe(struct platform_device *pdev)
+ struct resource *res;
+ struct device_node *np;
+ void __iomem *regs;
++ u32 asrc_fmt = 0;
+ int ret, irq;
+
+ easrc = devm_kzalloc(dev, sizeof(*easrc), GFP_KERNEL);
+@@ -1933,13 +1935,14 @@ static int fsl_easrc_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+- ret = of_property_read_u32(np, "fsl,asrc-format", &easrc->asrc_format);
++ ret = of_property_read_u32(np, "fsl,asrc-format", &asrc_fmt);
++ easrc->asrc_format = (__force snd_pcm_format_t)asrc_fmt;
+ if (ret) {
+ dev_err(dev, "failed to asrc format\n");
+ return ret;
+ }
+
+- if (!(FSL_EASRC_FORMATS & (1ULL << easrc->asrc_format))) {
++ if (!(FSL_EASRC_FORMATS & (pcm_format_to_bits(easrc->asrc_format)))) {
+ dev_warn(dev, "unsupported format, switching to S24_LE\n");
+ easrc->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
+ }
+diff --git a/sound/soc/fsl/fsl_easrc.h b/sound/soc/fsl/fsl_easrc.h
+index 30620d56252c..5b8469757c12 100644
+--- a/sound/soc/fsl/fsl_easrc.h
++++ b/sound/soc/fsl/fsl_easrc.h
+@@ -569,7 +569,7 @@ struct fsl_easrc_io_params {
+ unsigned int access_len;
+ unsigned int fifo_wtmk;
+ unsigned int sample_rate;
+- unsigned int sample_format;
++ snd_pcm_format_t sample_format;
+ unsigned int norm_rate;
+ };
+
+--
+2.35.1
+
--- /dev/null
+From f556366f1a7acdfc01ab59daec1966e9d2ba7e01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 22:05:43 -0300
+Subject: ASoC: imx-audmux: Silence a clang warning
+
+From: Fabio Estevam <festevam@gmail.com>
+
+[ Upstream commit 2f4a8171da06609bb6a063630ed546ee3d93dad7 ]
+
+Change the of_device_get_match_data() cast to (uintptr_t)
+to silence the following clang warning:
+
+sound/soc/fsl/imx-audmux.c:301:16: warning: cast to smaller integer type 'enum imx_audmux_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: 6a8b8b582db1 ("ASoC: imx-audmux: Remove unused .id_table")
+Signed-off-by: Fabio Estevam <festevam@gmail.com>
+Link: https://lore.kernel.org/r/20220526010543.1164793-1-festevam@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/imx-audmux.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
+index dfa05d40b276..a8e5e0f57faf 100644
+--- a/sound/soc/fsl/imx-audmux.c
++++ b/sound/soc/fsl/imx-audmux.c
+@@ -298,7 +298,7 @@ static int imx_audmux_probe(struct platform_device *pdev)
+ audmux_clk = NULL;
+ }
+
+- audmux_type = (enum imx_audmux_type)of_device_get_match_data(&pdev->dev);
++ audmux_type = (uintptr_t)of_device_get_match_data(&pdev->dev);
+
+ switch (audmux_type) {
+ case IMX31_AUDMUX:
+--
+2.35.1
+
--- /dev/null
+From a5fd6c5560694895f832112ec9d34ea60b170224 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 17:42:55 +0800
+Subject: ASoC: imx-card: Fix DSD/PDM mclk frequency
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit c0fabd12a8570cb932f13d9388f3d887ad44369b ]
+
+The DSD/PDM rate not only DSD64/128/256/512, which are the
+multiple rate of 44.1kHz, but also support the multiple
+rate of 8kHz, so can't force all mclk frequency to be
+22579200Hz, need to assign the frequency according to
+rate.
+
+Fixes: aa736700f42f ("ASoC: imx-card: Add imx-card machine driver")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1657100575-8261-1-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/imx-card.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c
+index 6f8efd838fcc..c0eb218a254b 100644
+--- a/sound/soc/fsl/imx-card.c
++++ b/sound/soc/fsl/imx-card.c
+@@ -17,6 +17,9 @@
+
+ #include "fsl_sai.h"
+
++#define IMX_CARD_MCLK_22P5792MHZ 22579200
++#define IMX_CARD_MCLK_24P576MHZ 24576000
++
+ enum codec_type {
+ CODEC_DUMMY = 0,
+ CODEC_AK5558 = 1,
+@@ -353,9 +356,14 @@ static int imx_aif_hw_params(struct snd_pcm_substream *substream,
+ mclk_freq = akcodec_get_mclk_rate(substream, params, slots, slot_width);
+ else
+ mclk_freq = params_rate(params) * slots * slot_width;
+- /* Use the maximum freq from DSD512 (512*44100 = 22579200) */
+- if (format_is_dsd(params))
+- mclk_freq = 22579200;
++
++ if (format_is_dsd(params)) {
++ /* Use the maximum freq from DSD512 (512*44100 = 22579200) */
++ if (!(params_rate(params) % 11025))
++ mclk_freq = IMX_CARD_MCLK_22P5792MHZ;
++ else
++ mclk_freq = IMX_CARD_MCLK_24P576MHZ;
++ }
+
+ ret = snd_soc_dai_set_sysclk(cpu_dai, link_data->cpu_sysclk_id, mclk_freq,
+ SND_SOC_CLOCK_OUT);
+--
+2.35.1
+
--- /dev/null
+From fedd2a2dc2156f0cad8c825e19da6f79360afdcb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 18:29:53 +0800
+Subject: ASoC: imx-card: use snd_pcm_format_t type for asrc_format
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit 409a8652e909e323c715f3088e6c3133e37c8881 ]
+
+Fix sparse warning:
+sound/soc/fsl/imx-card.c:653:59: sparse: warning: incorrect type in assignment (different base types)
+sound/soc/fsl/imx-card.c:653:59: sparse: expected unsigned int [usertype] asrc_format
+sound/soc/fsl/imx-card.c:653:59: sparse: got restricted snd_pcm_format_t [usertype]
+sound/soc/fsl/imx-card.c:655:59: sparse: warning: incorrect type in assignment (different base types)
+sound/soc/fsl/imx-card.c:655:59: sparse: expected unsigned int [usertype] asrc_format
+sound/soc/fsl/imx-card.c:655:59: sparse: got restricted snd_pcm_format_t [usertype]
+
+Fixes: aa736700f42f ("ASoC: imx-card: Add imx-card machine driver")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1658399393-28777-6-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/imx-card.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c
+index c0eb218a254b..4a8609b0d700 100644
+--- a/sound/soc/fsl/imx-card.c
++++ b/sound/soc/fsl/imx-card.c
+@@ -118,7 +118,7 @@ struct imx_card_data {
+ struct snd_soc_card card;
+ int num_dapm_routes;
+ u32 asrc_rate;
+- u32 asrc_format;
++ snd_pcm_format_t asrc_format;
+ };
+
+ static struct imx_akcodec_fs_mul ak4458_fs_mul[] = {
+@@ -474,7 +474,7 @@ static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+
+ mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+ snd_mask_none(mask);
+- snd_mask_set(mask, data->asrc_format);
++ snd_mask_set(mask, (__force unsigned int)data->asrc_format);
+
+ return 0;
+ }
+@@ -493,6 +493,7 @@ static int imx_card_parse_of(struct imx_card_data *data)
+ struct dai_link_data *link_data;
+ struct of_phandle_args args;
+ int ret, num_links;
++ u32 asrc_fmt = 0;
+ u32 width;
+
+ ret = snd_soc_of_parse_card_name(card, "model");
+@@ -639,7 +640,8 @@ static int imx_card_parse_of(struct imx_card_data *data)
+ goto err;
+ }
+
+- ret = of_property_read_u32(args.np, "fsl,asrc-format", &data->asrc_format);
++ ret = of_property_read_u32(args.np, "fsl,asrc-format", &asrc_fmt);
++ data->asrc_format = (__force snd_pcm_format_t)asrc_fmt;
+ if (ret) {
+ /* Fallback to old binding; translate to asrc_format */
+ ret = of_property_read_u32(args.np, "fsl,asrc-width", &width);
+--
+2.35.1
+
--- /dev/null
+From 8be024b088d0f288b200bea6a5591145fbbbf900 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 14:49:08 -0500
+Subject: ASoC: Intel: sof_rt5682: Perform quirk check first in card late probe
+
+From: Yong Zhi <yong.zhi@intel.com>
+
+[ Upstream commit 371a3f01fc1862c23fae35cb2c98ffb2eec143f1 ]
+
+The check of sof_rt5682_quirk should not be skipped unless the HDMI
+handling code exits with error, fix by moving the quirk check to the front.
+
+Fixes: 94d2d0897474 ("ASoC: Intel: Boards: tgl_max98373: add dai_trigger function")
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Signed-off-by: Yong Zhi <yong.zhi@intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20220725194909.145418-10-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/sof_rt5682.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c
+index 7126fcb63d90..d9f83b04be87 100644
+--- a/sound/soc/intel/boards/sof_rt5682.c
++++ b/sound/soc/intel/boards/sof_rt5682.c
+@@ -435,6 +435,15 @@ static int sof_card_late_probe(struct snd_soc_card *card)
+ int err;
+ int i = 0;
+
++ if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) {
++ /* Disable Left and Right Spk pin after boot */
++ snd_soc_dapm_disable_pin(dapm, "Left Spk");
++ snd_soc_dapm_disable_pin(dapm, "Right Spk");
++ err = snd_soc_dapm_sync(dapm);
++ if (err < 0)
++ return err;
++ }
++
+ /* HDMI is not supported by SOF on Baytrail/CherryTrail */
+ if (is_legacy_cpu || !ctx->idisp_codec)
+ return 0;
+@@ -468,15 +477,6 @@ static int sof_card_late_probe(struct snd_soc_card *card)
+ i++;
+ }
+
+- if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) {
+- /* Disable Left and Right Spk pin after boot */
+- snd_soc_dapm_disable_pin(dapm, "Left Spk");
+- snd_soc_dapm_disable_pin(dapm, "Right Spk");
+- err = snd_soc_dapm_sync(dapm);
+- if (err < 0)
+- return err;
+- }
+-
+ return hdac_hdmi_jack_port_init(component, &card->dapm);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From ca106f465458e41471573299a56e6da6e344b346 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Jul 2022 12:08:13 +0300
+Subject: ASoC: mchp-spdifrx: disable end of block interrupt on failures
+
+From: Claudiu Beznea <claudiu.beznea@microchip.com>
+
+[ Upstream commit 768ac4f12ca0fda935f58eb8c5120e9d795bc6e3 ]
+
+Disable end of block interrupt in case of wait for completion timeout
+or errors to undo previously enable operation (done in
+mchp_spdifrx_isr_blockend_en()). Otherwise we can end up with an
+unbalanced reference counter for this interrupt.
+
+Fixes: ef265c55c1ac ("ASoC: mchp-spdifrx: add driver for SPDIF RX")
+Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Link: https://lore.kernel.org/r/20220727090814.2446111-2-claudiu.beznea@microchip.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/atmel/mchp-spdifrx.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c
+index 5fc968483f2c..a7baa0385ec5 100644
+--- a/sound/soc/atmel/mchp-spdifrx.c
++++ b/sound/soc/atmel/mchp-spdifrx.c
+@@ -288,15 +288,17 @@ static void mchp_spdifrx_isr_blockend_en(struct mchp_spdifrx_dev *dev)
+ spin_unlock_irqrestore(&dev->blockend_lock, flags);
+ }
+
+-/* called from atomic context only */
++/* called from atomic/non-atomic context */
+ static void mchp_spdifrx_isr_blockend_dis(struct mchp_spdifrx_dev *dev)
+ {
+- spin_lock(&dev->blockend_lock);
++ unsigned long flags;
++
++ spin_lock_irqsave(&dev->blockend_lock, flags);
+ dev->blockend_refcount--;
+ /* don't enable BLOCKEND interrupt if it's already enabled */
+ if (dev->blockend_refcount == 0)
+ regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND);
+- spin_unlock(&dev->blockend_lock);
++ spin_unlock_irqrestore(&dev->blockend_lock, flags);
+ }
+
+ static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id)
+@@ -575,6 +577,7 @@ static int mchp_spdifrx_subcode_ch_get(struct mchp_spdifrx_dev *dev,
+ if (ret <= 0) {
+ dev_dbg(dev->dev, "user data for channel %d timeout\n",
+ channel);
++ mchp_spdifrx_isr_blockend_dis(dev);
+ return ret;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 4032ced56b0202138211591a41964122a5da97c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 07:41:42 +0400
+Subject: ASoC: mediatek: mt8173: Fix refcount leak in
+ mt8173_rt5650_rt5676_dev_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit ae4f11c1ed2d67192fdf3d89db719ee439827c11 ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Fix missing of_node_put() in error paths.
+
+Fixes: 94319ba10eca ("ASoC: mediatek: Use platform_of_node for machine drivers")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220602034144.60159-1-linmq006@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+index 5716d9299066..c1e8633a74a7 100644
+--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
++++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+@@ -256,14 +256,16 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
+ if (!mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node) {
+ dev_err(&pdev->dev,
+ "Property 'audio-codec' missing or invalid\n");
+- return -EINVAL;
++ ret = -EINVAL;
++ goto put_node;
+ }
+ mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node =
+ of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1);
+ if (!mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node) {
+ dev_err(&pdev->dev,
+ "Property 'audio-codec' missing or invalid\n");
+- return -EINVAL;
++ ret = -EINVAL;
++ goto put_node;
+ }
+ mt8173_rt5650_rt5676_codec_conf[0].dlc.of_node =
+ mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node;
+@@ -276,13 +278,15 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
+ if (!mt8173_rt5650_rt5676_dais[DAI_LINK_HDMI_I2S].codecs->of_node) {
+ dev_err(&pdev->dev,
+ "Property 'audio-codec' missing or invalid\n");
+- return -EINVAL;
++ ret = -EINVAL;
++ goto put_node;
+ }
+
+ card->dev = &pdev->dev;
+
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+
++put_node:
+ of_node_put(platform_node);
+ return ret;
+ }
+--
+2.35.1
+
--- /dev/null
+From 830c1ac3e845b7dd30aa2e83f40deea8cae57781 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 16:42:41 +0400
+Subject: ASoC: mediatek: mt8173-rt5650: Fix refcount leak in
+ mt8173_rt5650_dev_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit efe2178d1a32492f99e7f1f2568eea5c88a85729 ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Fix refcount leak in some error paths.
+
+Fixes: 0f83f9296d5c ("ASoC: mediatek: Add machine driver for ALC5650 codec")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220603124243.31358-1-linmq006@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/mediatek/mt8173/mt8173-rt5650.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+index fc164f4f95f8..487807ee7019 100644
+--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
++++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+@@ -280,7 +280,8 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
+ if (!mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node) {
+ dev_err(&pdev->dev,
+ "Property 'audio-codec' missing or invalid\n");
+- return -EINVAL;
++ ret = -EINVAL;
++ goto put_platform_node;
+ }
+ mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node =
+ mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node;
+@@ -293,7 +294,7 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
+ dev_err(&pdev->dev,
+ "%s codec_capture_dai name fail %d\n",
+ __func__, ret);
+- return ret;
++ goto put_platform_node;
+ }
+ mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[1].dai_name =
+ codec_capture_dai;
+@@ -315,12 +316,14 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
+ if (!mt8173_rt5650_dais[DAI_LINK_HDMI_I2S].codecs->of_node) {
+ dev_err(&pdev->dev,
+ "Property 'audio-codec' missing or invalid\n");
+- return -EINVAL;
++ ret = -EINVAL;
++ goto put_platform_node;
+ }
+ card->dev = &pdev->dev;
+
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+
++put_platform_node:
+ of_node_put(platform_node);
+ return ret;
+ }
+--
+2.35.1
+
--- /dev/null
+From 3a31f28c01b0a89e32629f12d510a69421f9e7ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 18:20:13 +0800
+Subject: ASoC: mt6359: Fix refcount leak bug
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit a8d5df69e2ec702d979f7d04ed519caf8691a032 ]
+
+In mt6359_parse_dt() and mt6359_accdet_parse_dt(), we should call
+of_node_put() for the reference returned by of_get_child_by_name()
+which has increased the refcount.
+
+Fixes: 683530285316 ("ASoC: mt6359: fix failed to parse DT properties")
+Fixes: eef07b9e0925 ("ASoC: mediatek: mt6359: add MT6359 accdet jack driver")
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220713102013.367336-1-windhl@126.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/mt6359-accdet.c | 1 +
+ sound/soc/codecs/mt6359.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/sound/soc/codecs/mt6359-accdet.c b/sound/soc/codecs/mt6359-accdet.c
+index 6d3d170144a0..c190628e2905 100644
+--- a/sound/soc/codecs/mt6359-accdet.c
++++ b/sound/soc/codecs/mt6359-accdet.c
+@@ -675,6 +675,7 @@ static int mt6359_accdet_parse_dt(struct mt6359_accdet *priv)
+ sizeof(struct three_key_threshold));
+ }
+
++ of_node_put(node);
+ dev_warn(priv->dev, "accdet caps=%x\n", priv->caps);
+
+ return 0;
+diff --git a/sound/soc/codecs/mt6359.c b/sound/soc/codecs/mt6359.c
+index f8532aa7e4aa..9a9c8555f720 100644
+--- a/sound/soc/codecs/mt6359.c
++++ b/sound/soc/codecs/mt6359.c
+@@ -2780,6 +2780,7 @@ static int mt6359_parse_dt(struct mt6359_priv *priv)
+
+ ret = of_property_read_u32(np, "mediatek,mic-type-2",
+ &priv->mux_select[MUX_MIC_TYPE_2]);
++ of_node_put(np);
+ if (ret) {
+ dev_info(priv->dev,
+ "%s() failed to read mic-type-2, use default (%d)\n",
+--
+2.35.1
+
--- /dev/null
+From c59801507f646fc6cfff508910fe8b9914d5397f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 12:34:15 +0400
+Subject: ASoC: mt6797-mt6351: Fix refcount leak in mt6797_mt6351_dev_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 7472eb8d7dd12b6b9b1a4f4527719cc9c7f5965f ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: f0ab0bf250da ("ASoC: add mt6797-mt6351 driver and config option")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220603083417.9011-1-linmq006@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/mediatek/mt6797/mt6797-mt6351.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/mediatek/mt6797/mt6797-mt6351.c b/sound/soc/mediatek/mt6797/mt6797-mt6351.c
+index 496f32bcfb5e..d2f6213a6bfc 100644
+--- a/sound/soc/mediatek/mt6797/mt6797-mt6351.c
++++ b/sound/soc/mediatek/mt6797/mt6797-mt6351.c
+@@ -217,7 +217,8 @@ static int mt6797_mt6351_dev_probe(struct platform_device *pdev)
+ if (!codec_node) {
+ dev_err(&pdev->dev,
+ "Property 'audio-codec' missing or invalid\n");
+- return -EINVAL;
++ ret = -EINVAL;
++ goto put_platform_node;
+ }
+ for_each_card_prelinks(card, i, dai_link) {
+ if (dai_link->codecs->name)
+@@ -230,6 +231,9 @@ static int mt6797_mt6351_dev_probe(struct platform_device *pdev)
+ dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
+ __func__, ret);
+
++ of_node_put(codec_node);
++put_platform_node:
++ of_node_put(platform_node);
+ return ret;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 8415b1127f79cd6bc55ddf2b18ca1622642caf3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Jul 2022 10:01:09 +0800
+Subject: ASoC: qcom: Fix missing of_node_put() in
+ asoc_qcom_lpass_cpu_platform_probe()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit f507c0c67dac57d2bcd5dcae4b6139b0305d8957 ]
+
+We should call of_node_put() for the reference 'dsp_of_node' returned by
+of_parse_phandle() which will increase the refcount.
+
+Fixes: 9bae4880acee ("ASoC: qcom: move ipq806x specific bits out of lpass driver.")
+Co-authored-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220702020109.263980-1-windhl@126.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/qcom/lpass-cpu.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
+index e6846ad2b5fa..964eb07f46d6 100644
+--- a/sound/soc/qcom/lpass-cpu.c
++++ b/sound/soc/qcom/lpass-cpu.c
+@@ -1090,6 +1090,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
+ dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0);
+ if (dsp_of_node) {
+ dev_err(dev, "DSP exists and holds audio resources\n");
++ of_node_put(dsp_of_node);
+ return -EBUSY;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 43a27c720bd5992d452bc3bcf744480dfe1b7823 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 11:02:22 +0200
+Subject: ASoC: qcom: q6dsp: Fix an off-by-one in q6adm_alloc_copp()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 673f58f62ca6fc98979d1cf3fe89c3ff33f29b2e ]
+
+find_first_zero_bit() returns MAX_COPPS_PER_PORT at max here.
+So 'idx' should be tested with ">=" or the test can't match.
+
+Fixes: 7b20b2be51e1 ("ASoC: qdsp6: q6adm: Add q6adm driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/0fca3271649736053eb9649d87e1ca01b056be40.1658394124.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/qcom/qdsp6/q6adm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/qcom/qdsp6/q6adm.c b/sound/soc/qcom/qdsp6/q6adm.c
+index 72c5719f1d25..a0678e8cf20a 100644
+--- a/sound/soc/qcom/qdsp6/q6adm.c
++++ b/sound/soc/qcom/qdsp6/q6adm.c
+@@ -217,7 +217,7 @@ static struct q6copp *q6adm_alloc_copp(struct q6adm *adm, int port_idx)
+ idx = find_first_zero_bit(&adm->copp_bitmap[port_idx],
+ MAX_COPPS_PER_PORT);
+
+- if (idx > MAX_COPPS_PER_PORT)
++ if (idx >= MAX_COPPS_PER_PORT)
+ return ERR_PTR(-EBUSY);
+
+ c = kzalloc(sizeof(*c), GFP_ATOMIC);
+--
+2.35.1
+
--- /dev/null
+From 95ef5e0afaf337c8e9c689de5ba2ea3be45655e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jun 2022 14:53:45 -0400
+Subject: ASoC: samsung: change gpiod_speaker_power and rx1950_audio from
+ global to static variables
+
+From: Tom Rix <trix@redhat.com>
+
+[ Upstream commit d2294461b90e0c5b3bbfaaf2c8baff4fd3e2bb13 ]
+
+sparse reports
+sound/soc/samsung/rx1950_uda1380.c:131:18: warning: symbol 'gpiod_speaker_power' was not declared. Should it be static?
+sound/soc/samsung/rx1950_uda1380.c:231:24: warning: symbol 'rx1950_audio' was not declared. Should it be static?
+
+Both gpiod_speaker_power and rx1950_audio are only used in rx1950_uda1380.c,
+so their storage class specifiers should be static.
+
+Fixes: 83d74e354200 ("ASoC: samsung: rx1950: turn into platform driver")
+Signed-off-by: Tom Rix <trix@redhat.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220629185345.910406-1-trix@redhat.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/samsung/rx1950_uda1380.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
+index 6ea1c8cc9167..2820097b00b9 100644
+--- a/sound/soc/samsung/rx1950_uda1380.c
++++ b/sound/soc/samsung/rx1950_uda1380.c
+@@ -128,7 +128,7 @@ static int rx1950_startup(struct snd_pcm_substream *substream)
+ &hw_rates);
+ }
+
+-struct gpio_desc *gpiod_speaker_power;
++static struct gpio_desc *gpiod_speaker_power;
+
+ static int rx1950_spk_power(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+@@ -227,7 +227,7 @@ static int rx1950_probe(struct platform_device *pdev)
+ return devm_snd_soc_register_card(dev, &rx1950_asoc);
+ }
+
+-struct platform_driver rx1950_audio = {
++static struct platform_driver rx1950_audio = {
+ .driver = {
+ .name = "rx1950-audio",
+ .pm = &snd_soc_pm_ops,
+--
+2.35.1
+
--- /dev/null
+From 2a3455d38da33a71b0f493e6f75b9a09584345d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 17:06:39 +0400
+Subject: ASoC: samsung: Fix error handling in aries_audio_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 3e2649c5e8643bea0867bb1dd970fedadb0eb7f3 ]
+
+of_get_child_by_name() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+This function is missing of_node_put(cpu) in the error path.
+Fix this by goto out label. of_node_put() will check NULL pointer.
+
+Fixes: 7a3a7671fa6c ("ASoC: samsung: Add driver for Aries boards")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220603130640.37624-1-linmq006@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/samsung/aries_wm8994.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/samsung/aries_wm8994.c b/sound/soc/samsung/aries_wm8994.c
+index 83acbe57b248..a0825da9fff9 100644
+--- a/sound/soc/samsung/aries_wm8994.c
++++ b/sound/soc/samsung/aries_wm8994.c
+@@ -628,8 +628,10 @@ static int aries_audio_probe(struct platform_device *pdev)
+ return -EINVAL;
+
+ codec = of_get_child_by_name(dev->of_node, "codec");
+- if (!codec)
+- return -EINVAL;
++ if (!codec) {
++ ret = -EINVAL;
++ goto out;
++ }
+
+ for_each_card_prelinks(card, i, dai_link) {
+ dai_link->codecs->of_node = of_parse_phandle(codec,
+--
+2.35.1
+
--- /dev/null
+From eb51bd88b1504684f7dcec2a2ac73159ebb2d55b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jun 2022 16:19:00 +0200
+Subject: ASoC: samsung: h1940_uda1380: include proepr GPIO consumer header
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit bd10b0dafdcf0ec1677cad70101e1f97b9e28f2e ]
+
+h1940_uda1380 uses gpiod*/GPIOD* so it should include GPIO consumer
+header.
+
+Fixes: 9666e27f90b9 ("ASoC: samsung: h1940: turn into platform driver")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220627141900.470469-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/samsung/h1940_uda1380.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
+index c994e67d1eaf..ca086243fcfd 100644
+--- a/sound/soc/samsung/h1940_uda1380.c
++++ b/sound/soc/samsung/h1940_uda1380.c
+@@ -8,7 +8,7 @@
+ // Based on version from Arnaud Patard <arnaud.patard@rtp-net.org>
+
+ #include <linux/types.h>
+-#include <linux/gpio.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/module.h>
+
+ #include <sound/soc.h>
+--
+2.35.1
+
--- /dev/null
+From ca9344fd4d2447daa1aa5b822b1558f7602c8f49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 16:01:03 +0300
+Subject: ASoC: SOF: ipc3-topology: Prevent double freeing of ipc_control_data
+ via load_bytes
+
+From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+
+[ Upstream commit d5bd47f3ca124058a8e87eae4508afeda2132611 ]
+
+We have sanity checks for byte controls and if any of the fail the locally
+allocated scontrol->ipc_control_data is freed up, but not set to NULL.
+
+On a rollback path of the error the higher level code will also try to free
+the scontrol->ipc_control_data which will eventually going to lead to
+memory corruption as double freeing memory is not a good thing.
+
+Fixes: b5cee8feb1d4 ("ASoC: SOF: topology: Make control parsing IPC agnostic")
+Reported-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Reviewed-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20220712130103.31514-1-peter.ujfalusi@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/ipc3-topology.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c
+index 80fb82ece38d..74c230fbcf68 100644
+--- a/sound/soc/sof/ipc3-topology.c
++++ b/sound/soc/sof/ipc3-topology.c
+@@ -1629,6 +1629,7 @@ static int sof_ipc3_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_
+ return 0;
+ err:
+ kfree(scontrol->ipc_control_data);
++ scontrol->ipc_control_data = NULL;
+ return ret;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From ecebb60fbfa0b3612fa701da0f6e49dda39efd51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 11:35:44 +0300
+Subject: ASoC: SOF: make ctx_store and ctx_restore as optional
+
+From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+
+[ Upstream commit 03f69725749f453b9a4d454a92805f8eb5f095c2 ]
+
+Commit 657774acd00f ("ASoC: SOF: Make sof_suspend/resume IPC agnostic")
+did not marked ctx_store and ctx_restore as Optional.
+
+Fixes: 657774acd00f ("ASoC: SOF: Make sof_suspend/resume IPC agnostic")
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20220610083549.16773-2-peter.ujfalusi@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/sof-priv.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
+index c856f0d84e49..f369242dd975 100644
+--- a/sound/soc/sof/sof-priv.h
++++ b/sound/soc/sof/sof-priv.h
+@@ -364,8 +364,8 @@ struct snd_sof_ipc_msg {
+
+ /**
+ * struct sof_ipc_pm_ops - IPC-specific PM ops
+- * @ctx_save: Function pointer for context save
+- * @ctx_restore: Function pointer for context restore
++ * @ctx_save: Optional function pointer for context save
++ * @ctx_restore: Optional function pointer for context restore
+ */
+ struct sof_ipc_pm_ops {
+ int (*ctx_save)(struct snd_sof_dev *sdev);
+--
+2.35.1
+
--- /dev/null
+From 0b8a1d1c82d014bdfe45f36ece226bd5ea17e785 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 15:39:04 -0500
+Subject: ASoC: SOF: mediatek: fix mt8195 StatvectorSel wrong setting
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: YC Hung <yc.hung@mediatek.com>
+
+[ Upstream commit 99bad468846f7a255dcfc95454401c83ae02e89b ]
+
+Fix StatVectorSel wrong setting.
+
+Fixes: b7f6503830 ("ASoC: SOF: mediatek: Add fw loader and mt8195 dsp ops to load firmware")
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Signed-off-by: YC Hung <yc.hung@mediatek.com>
+Reviewed-by: Li-Yu Yu <afg984@gmail.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: KuanHsun Cheng <Allen-KH.Cheng@mediatek.com>
+Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Link: https://lore.kernel.org/r/20220708203904.29214-3-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/mediatek/mt8195/mt8195-loader.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/sof/mediatek/mt8195/mt8195-loader.c b/sound/soc/sof/mediatek/mt8195/mt8195-loader.c
+index ed18d6379e92..ef2664c3cd47 100644
+--- a/sound/soc/sof/mediatek/mt8195/mt8195-loader.c
++++ b/sound/soc/sof/mediatek/mt8195/mt8195-loader.c
+@@ -21,7 +21,7 @@ void sof_hifixdsp_boot_sequence(struct snd_sof_dev *sdev, u32 boot_addr)
+
+ /* pull high StatVectorSel to use AltResetVec (set bit4 to 1) */
+ snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, DSP_RESET_SW,
+- DSP_RESET_SW, DSP_RESET_SW);
++ STATVECTOR_SEL, STATVECTOR_SEL);
+
+ /* toggle DReset & BReset */
+ /* pull high DReset & BReset */
+--
+2.35.1
+
--- /dev/null
+From 4ee9bda5ed42ea1e701d3cfedb903866f66d603b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 May 2022 10:27:26 +0300
+Subject: ath10k: do not enforce interrupt trigger type
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 1ee6c5abebd3cacf2ac4378d0ed4f57fd4850421 ]
+
+Interrupt line can be configured on different hardware in different way,
+even inverted. Therefore driver should not enforce specific trigger
+type - edge rising - but instead rely on Devicetree to configure it.
+
+All Qualcomm DTSI with WCN3990 define the interrupt type as level high,
+so the mismatch between DTSI and driver causes rebind issues:
+
+ $ echo 18800000.wifi > /sys/bus/platform/drivers/ath10k_snoc/unbind
+ $ echo 18800000.wifi > /sys/bus/platform/drivers/ath10k_snoc/bind
+ [ 44.763114] irq: type mismatch, failed to map hwirq-446 for interrupt-controller@17a00000!
+ [ 44.763130] ath10k_snoc 18800000.wifi: error -ENXIO: IRQ index 0 not found
+ [ 44.763140] ath10k_snoc 18800000.wifi: failed to initialize resource: -6
+
+Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.2.0.c8-00009-QCAHLSWSC8180XMTPLZ-1
+Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.2.0-01387-QCAHLSWMTPLZ-1
+
+Fixes: c963a683e701 ("ath10k: add resource init and deinit for WCN3990")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Tested-by: Steev Klimaszewski <steev@kali.org>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220513151516.357549-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath10k/snoc.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c
+index 8328966a0471..603dc7bebc0c 100644
+--- a/drivers/net/wireless/ath/ath10k/snoc.c
++++ b/drivers/net/wireless/ath/ath10k/snoc.c
+@@ -1249,13 +1249,12 @@ static void ath10k_snoc_init_napi(struct ath10k *ar)
+ static int ath10k_snoc_request_irq(struct ath10k *ar)
+ {
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+- int irqflags = IRQF_TRIGGER_RISING;
+ int ret, id;
+
+ for (id = 0; id < CE_COUNT_MAX; id++) {
+ ret = request_irq(ar_snoc->ce_irqs[id].irq_line,
+- ath10k_snoc_per_engine_handler,
+- irqflags, ce_name[id], ar);
++ ath10k_snoc_per_engine_handler, 0,
++ ce_name[id], ar);
+ if (ret) {
+ ath10k_err(ar,
+ "failed to register IRQ handler for CE %d: %d\n",
+--
+2.35.1
+
--- /dev/null
+From e9a93e7aa89e6a2f7356ba1956323b22029eee84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 17:59:29 +0530
+Subject: ath11k: Avoid REO CMD failed prints during firmware recovery
+
+From: Manikanta Pubbisetty <quic_mpubbise@quicinc.com>
+
+[ Upstream commit 0ab52b2bd7be8fd49c8ade7703c1faa15359c6c5 ]
+
+Currently when firmware recovery is in progress, we do not queue REO
+commands to the firmware, instead -ESHUTDOWN will be returned to the
+caller leading to a failure print on the console. The REO command in
+the problem scenario is sent for all tids of a peer in which case we
+will have 16 failure prints on the console for a single peer. For an
+AP usecase, this count would be even higher in a worst case scenario.
+Since these commands are bound to fail during firmware recovery, it
+is better to avoid printing these failures and thereby avoid message
+flooding on the console.
+
+Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1
+
+Fixes: 8ee8d38ca472 ("ath11k: Fix crash during firmware recovery on reo cmd ring access")
+Signed-off-by: Manikanta Pubbisetty <quic_mpubbise@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220602122929.18896-1-quic_mpubbise@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/dp_rx.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
+index 049774cc158c..b3e133add1ce 100644
+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
+@@ -835,8 +835,9 @@ void ath11k_peer_rx_tid_delete(struct ath11k *ar,
+ HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd,
+ ath11k_dp_rx_tid_del_func);
+ if (ret) {
+- ath11k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n",
+- tid, ret);
++ if (ret != -ESHUTDOWN)
++ ath11k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n",
++ tid, ret);
+ dma_unmap_single(ar->ab->dev, rx_tid->paddr, rx_tid->size,
+ DMA_BIDIRECTIONAL);
+ kfree(rx_tid->vaddr);
+--
+2.35.1
+
--- /dev/null
+From cb9a91edddde8da46d029207195aafc3036f44ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 17:26:21 +0530
+Subject: ath11k: Fix incorrect debug_mask mappings
+
+From: Manikanta Pubbisetty <quic_mpubbise@quicinc.com>
+
+[ Upstream commit 9331f7d3c54a263bede5055e106e40b28d0bd937 ]
+
+Currently a couple of debug_mask entries are mapped to the same value,
+this could enable unintended driver logging. If enabling DP_TX logs was
+the intention, then this could also enable PCI logs flooding the dmesg
+buffer or vice versa. Fix this by correctly assigning the debug masks.
+
+Found during code review.
+
+Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1
+
+Fixes: aa2092a9bab3f ("ath11k: add raw mode and software crypto support")
+Signed-off-by: Manikanta Pubbisetty <quic_mpubbise@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220602115621.15339-1-quic_mpubbise@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/debug.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/debug.h b/drivers/net/wireless/ath/ath11k/debug.h
+index fbbd5fe02aa8..91545640c47b 100644
+--- a/drivers/net/wireless/ath/ath11k/debug.h
++++ b/drivers/net/wireless/ath/ath11k/debug.h
+@@ -23,8 +23,8 @@ enum ath11k_debug_mask {
+ ATH11K_DBG_TESTMODE = 0x00000400,
+ ATH11k_DBG_HAL = 0x00000800,
+ ATH11K_DBG_PCI = 0x00001000,
+- ATH11K_DBG_DP_TX = 0x00001000,
+- ATH11K_DBG_DP_RX = 0x00002000,
++ ATH11K_DBG_DP_TX = 0x00002000,
++ ATH11K_DBG_DP_RX = 0x00004000,
+ ATH11K_DBG_ANY = 0xffffffff,
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 247174d9e61bd42e0a982f85619ff74e93aa3335 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 May 2022 16:32:58 +0200
+Subject: ath11k: fix IRQ affinity warning on shutdown
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit 3bd0c69653ac636eae8872aacdcd4156f772f928 ]
+
+Make sure to clear the IRQ affinity hint also on shutdown to avoid
+triggering a WARN_ON_ONCE() in __free_irq() when stopping MHI while
+using a single MSI vector.
+
+Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
+
+Fixes: e94b07493da3 ("ath11k: Set IRQ affinity to CPU0 in case of one MSI vector")
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220523143258.24818-1-johan+linaro@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/pci.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
+index 8a3ff12057e8..e2382c8595b6 100644
+--- a/drivers/net/wireless/ath/ath11k/pci.c
++++ b/drivers/net/wireless/ath/ath11k/pci.c
+@@ -1566,7 +1566,9 @@ static void ath11k_pci_remove(struct pci_dev *pdev)
+ static void ath11k_pci_shutdown(struct pci_dev *pdev)
+ {
+ struct ath11k_base *ab = pci_get_drvdata(pdev);
++ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
+
++ ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);
+ ath11k_pci_power_down(ab);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From d56047a16f1ce5fe78142ce4853e6a255ad13167 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 28 May 2022 16:25:16 +0200
+Subject: ath11k: fix missing skb drop on htc_tx_completion error
+
+From: Christian 'Ansuel' Marangi <ansuelsmth@gmail.com>
+
+[ Upstream commit e5646fe3b7ef739c392e59da7db6adf5e1fdef42 ]
+
+On htc_tx_completion error the skb is not dropped. This is wrong since
+the completion_handler logic expect the skb to be consumed anyway even
+when an error is triggered. Not freeing the skb on error is a memory
+leak since the skb won't be freed anywere else. Correctly free the
+packet on eid >= ATH11K_HTC_EP_COUNT before returning.
+
+Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
+
+Fixes: f951380a6022 ("ath11k: Disabling credit flow for WMI path")
+Signed-off-by: Christian 'Ansuel' Marangi <ansuelsmth@gmail.com>
+Reviewed-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220528142516.20819-2-ansuelsmth@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/htc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/htc.c b/drivers/net/wireless/ath/ath11k/htc.c
+index 6913b7494b9b..2de1e953a539 100644
+--- a/drivers/net/wireless/ath/ath11k/htc.c
++++ b/drivers/net/wireless/ath/ath11k/htc.c
+@@ -258,8 +258,10 @@ void ath11k_htc_tx_completion_handler(struct ath11k_base *ab,
+ u8 eid;
+
+ eid = ATH11K_SKB_CB(skb)->eid;
+- if (eid >= ATH11K_HTC_EP_COUNT)
++ if (eid >= ATH11K_HTC_EP_COUNT) {
++ dev_kfree_skb_any(skb);
+ return;
++ }
+
+ ep = &htc->endpoint[eid];
+ spin_lock_bh(&htc->tx_lock);
+--
+2.35.1
+
--- /dev/null
+From 86c2f3e8caf88e8c159704bd6719500f205f2df5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 May 2022 15:33:16 +0300
+Subject: ath11k: fix netdev open race
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit d4ba1ff87b17e81686ada8f429300876f55f95ad ]
+
+Make sure to allocate resources needed before registering the device.
+
+This specifically avoids having a racing open() trigger a BUG_ON() in
+mod_timer() when ath11k_mac_op_start() is called before the
+mon_reap_timer as been set up.
+
+I did not see this issue with next-20220310, but I hit it on every probe
+with next-20220511. Perhaps some timing changed in between.
+
+Here's the backtrace:
+
+[ 51.346947] kernel BUG at kernel/time/timer.c:990!
+[ 51.346958] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
+...
+[ 51.578225] Call trace:
+[ 51.583293] __mod_timer+0x298/0x390
+[ 51.589518] mod_timer+0x14/0x20
+[ 51.595368] ath11k_mac_op_start+0x41c/0x4a0 [ath11k]
+[ 51.603165] drv_start+0x38/0x60 [mac80211]
+[ 51.610110] ieee80211_do_open+0x29c/0x7d0 [mac80211]
+[ 51.617945] ieee80211_open+0x60/0xb0 [mac80211]
+[ 51.625311] __dev_open+0x100/0x1c0
+[ 51.631420] __dev_change_flags+0x194/0x210
+[ 51.638214] dev_change_flags+0x24/0x70
+[ 51.644646] do_setlink+0x228/0xdb0
+[ 51.650723] __rtnl_newlink+0x460/0x830
+[ 51.657162] rtnl_newlink+0x4c/0x80
+[ 51.663229] rtnetlink_rcv_msg+0x124/0x390
+[ 51.669917] netlink_rcv_skb+0x58/0x130
+[ 51.676314] rtnetlink_rcv+0x18/0x30
+[ 51.682460] netlink_unicast+0x250/0x310
+[ 51.688960] netlink_sendmsg+0x19c/0x3e0
+[ 51.695458] ____sys_sendmsg+0x220/0x290
+[ 51.701938] ___sys_sendmsg+0x7c/0xc0
+[ 51.708148] __sys_sendmsg+0x68/0xd0
+[ 51.714254] __arm64_sys_sendmsg+0x28/0x40
+[ 51.720900] invoke_syscall+0x48/0x120
+
+Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
+
+Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
+Fixes: 840c36fa727a ("ath11k: dp: stop rx pktlog before suspend")
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220517103436.15867-1-johan+linaro@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/core.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
+index 90a5df1fbdbd..0106e529f3c5 100644
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -903,23 +903,23 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab)
+ return ret;
+ }
+
+- ret = ath11k_mac_register(ab);
++ ret = ath11k_dp_pdev_alloc(ab);
+ if (ret) {
+- ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
++ ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
+ goto err_pdev_debug;
+ }
+
+- ret = ath11k_dp_pdev_alloc(ab);
++ ret = ath11k_mac_register(ab);
+ if (ret) {
+- ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
+- goto err_mac_unregister;
++ ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
++ goto err_dp_pdev_free;
+ }
+
+ ret = ath11k_thermal_register(ab);
+ if (ret) {
+ ath11k_err(ab, "could not register thermal device: %d\n",
+ ret);
+- goto err_dp_pdev_free;
++ goto err_mac_unregister;
+ }
+
+ ret = ath11k_spectral_init(ab);
+@@ -932,10 +932,10 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab)
+
+ err_thermal_unregister:
+ ath11k_thermal_unregister(ab);
+-err_dp_pdev_free:
+- ath11k_dp_pdev_free(ab);
+ err_mac_unregister:
+ ath11k_mac_unregister(ab);
++err_dp_pdev_free:
++ ath11k_dp_pdev_free(ab);
+ err_pdev_debug:
+ ath11k_debugfs_pdev_destroy(ab);
+
+--
+2.35.1
+
--- /dev/null
+From 3c8cbdc1ce48569d2ddb2ccbdfd777b2011b7d09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 21:43:59 +0300
+Subject: ath9k: fix use-after-free in ath9k_hif_usb_rx_cb
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+[ Upstream commit 0ac4827f78c7ffe8eef074bc010e7e34bc22f533 ]
+
+Syzbot reported use-after-free Read in ath9k_hif_usb_rx_cb() [0]. The
+problem was in incorrect htc_handle->drv_priv initialization.
+
+Probable call trace which can trigger use-after-free:
+
+ath9k_htc_probe_device()
+ /* htc_handle->drv_priv = priv; */
+ ath9k_htc_wait_for_target() <--- Failed
+ ieee80211_free_hw() <--- priv pointer is freed
+
+<IRQ>
+...
+ath9k_hif_usb_rx_cb()
+ ath9k_hif_usb_rx_stream()
+ RX_STAT_INC() <--- htc_handle->drv_priv access
+
+In order to not add fancy protection for drv_priv we can move
+htc_handle->drv_priv initialization at the end of the
+ath9k_htc_probe_device() and add helper macro to make
+all *_STAT_* macros NULL safe, since syzbot has reported related NULL
+deref in that macros [1]
+
+Link: https://syzkaller.appspot.com/bug?id=6ead44e37afb6866ac0c7dd121b4ce07cb665f60 [0]
+Link: https://syzkaller.appspot.com/bug?id=b8101ffcec107c0567a0cd8acbbacec91e9ee8de [1]
+Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
+Reported-and-tested-by: syzbot+03110230a11411024147@syzkaller.appspotmail.com
+Reported-and-tested-by: syzbot+c6dde1f690b60e0b9fbe@syzkaller.appspotmail.com
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/d57bbedc857950659bfacac0ab48790c1eda00c8.1655145743.git.paskripkin@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/htc.h | 10 +++++-----
+ drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 ++-
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
+index 6b45e63fae4b..e3d546ef71dd 100644
+--- a/drivers/net/wireless/ath/ath9k/htc.h
++++ b/drivers/net/wireless/ath/ath9k/htc.h
+@@ -327,11 +327,11 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
+ }
+
+ #ifdef CONFIG_ATH9K_HTC_DEBUGFS
+-
+-#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
+-#define TX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a)
+-#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++)
+-#define RX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a)
++#define __STAT_SAFE(expr) (hif_dev->htc_handle->drv_priv ? (expr) : 0)
++#define TX_STAT_INC(c) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
++#define TX_STAT_ADD(c, a) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a)
++#define RX_STAT_INC(c) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++)
++#define RX_STAT_ADD(c, a) __STAT_SAFE(hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a)
+ #define CAB_STAT_INC priv->debug.tx_stats.cab_queued++
+
+ #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
+diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+index ff61ae34ecdf..07ac88fb1c57 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+@@ -944,7 +944,6 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
+ priv->hw = hw;
+ priv->htc = htc_handle;
+ priv->dev = dev;
+- htc_handle->drv_priv = priv;
+ SET_IEEE80211_DEV(hw, priv->dev);
+
+ ret = ath9k_htc_wait_for_target(priv);
+@@ -965,6 +964,8 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
+ if (ret)
+ goto err_init;
+
++ htc_handle->drv_priv = priv;
++
+ return 0;
+
+ err_init:
+--
+2.35.1
+
--- /dev/null
+From 692ed53337cde4a881fc3091db70f90df1517ea9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Jul 2022 22:18:21 -0700
+Subject: ax25: fix incorrect dev_tracker usage
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit d7c4c9e075f8cc6d88d277bc24e5d99297f03c06 ]
+
+While investigating a separate rose issue [1], and enabling
+CONFIG_NET_DEV_REFCNT_TRACKER=y, Bernard reported an orthogonal ax25 issue [2]
+
+An ax25_dev can be used by one (or many) struct ax25_cb.
+We thus need different dev_tracker, one per struct ax25_cb.
+
+After this patch is applied, we are able to focus on rose.
+
+[1] https://lore.kernel.org/netdev/fb7544a1-f42e-9254-18cc-c9b071f4ca70@free.fr/
+
+[2]
+[ 205.798723] reference already released.
+[ 205.798732] allocated in:
+[ 205.798734] ax25_bind+0x1a2/0x230 [ax25]
+[ 205.798747] __sys_bind+0xea/0x110
+[ 205.798753] __x64_sys_bind+0x18/0x20
+[ 205.798758] do_syscall_64+0x5c/0x80
+[ 205.798763] entry_SYSCALL_64_after_hwframe+0x44/0xae
+[ 205.798768] freed in:
+[ 205.798770] ax25_release+0x115/0x370 [ax25]
+[ 205.798778] __sock_release+0x42/0xb0
+[ 205.798782] sock_close+0x15/0x20
+[ 205.798785] __fput+0x9f/0x260
+[ 205.798789] ____fput+0xe/0x10
+[ 205.798792] task_work_run+0x64/0xa0
+[ 205.798798] exit_to_user_mode_prepare+0x18b/0x190
+[ 205.798804] syscall_exit_to_user_mode+0x26/0x40
+[ 205.798808] do_syscall_64+0x69/0x80
+[ 205.798812] entry_SYSCALL_64_after_hwframe+0x44/0xae
+[ 205.798827] ------------[ cut here ]------------
+[ 205.798829] WARNING: CPU: 2 PID: 2605 at lib/ref_tracker.c:136 ref_tracker_free.cold+0x60/0x81
+[ 205.798837] Modules linked in: rose netrom mkiss ax25 rfcomm cmac algif_hash algif_skcipher af_alg bnep snd_hda_codec_hdmi nls_iso8859_1 i915 rtw88_8821ce rtw88_8821c x86_pkg_temp_thermal rtw88_pci intel_powerclamp rtw88_core snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio coretemp snd_hda_intel kvm_intel snd_intel_dspcfg mac80211 snd_hda_codec kvm i2c_algo_bit drm_buddy drm_dp_helper btusb drm_kms_helper snd_hwdep btrtl snd_hda_core btbcm joydev crct10dif_pclmul btintel crc32_pclmul ghash_clmulni_intel mei_hdcp btmtk intel_rapl_msr aesni_intel bluetooth input_leds snd_pcm crypto_simd syscopyarea processor_thermal_device_pci_legacy sysfillrect cryptd intel_soc_dts_iosf snd_seq sysimgblt ecdh_generic fb_sys_fops rapl libarc4 processor_thermal_device intel_cstate processor_thermal_rfim cec snd_timer ecc snd_seq_device cfg80211 processor_thermal_mbox mei_me processor_thermal_rapl mei rc_core at24 snd intel_pch_thermal intel_rapl_common ttm soundcore int340x_thermal_zone video
+[ 205.798948] mac_hid acpi_pad sch_fq_codel ipmi_devintf ipmi_msghandler drm msr parport_pc ppdev lp parport ramoops pstore_blk reed_solomon pstore_zone efi_pstore ip_tables x_tables autofs4 hid_generic usbhid hid i2c_i801 i2c_smbus r8169 xhci_pci ahci libahci realtek lpc_ich xhci_pci_renesas [last unloaded: ax25]
+[ 205.798992] CPU: 2 PID: 2605 Comm: ax25ipd Not tainted 5.18.11-F6BVP #3
+[ 205.798996] Hardware name: To be filled by O.E.M. To be filled by O.E.M./CK3, BIOS 5.011 09/16/2020
+[ 205.798999] RIP: 0010:ref_tracker_free.cold+0x60/0x81
+[ 205.799005] Code: e8 d2 01 9b ff 83 7b 18 00 74 14 48 c7 c7 2f d7 ff 98 e8 10 6e fc ff 8b 7b 18 e8 b8 01 9b ff 4c 89 ee 4c 89 e7 e8 5d fd 07 00 <0f> 0b b8 ea ff ff ff e9 30 05 9b ff 41 0f b6 f7 48 c7 c7 a0 fa 4e
+[ 205.799008] RSP: 0018:ffffaf5281073958 EFLAGS: 00010286
+[ 205.799011] RAX: 0000000080000000 RBX: ffff9a0bd687ebe0 RCX: 0000000000000000
+[ 205.799014] RDX: 0000000000000001 RSI: 0000000000000282 RDI: 00000000ffffffff
+[ 205.799016] RBP: ffffaf5281073a10 R08: 0000000000000003 R09: fffffffffffd5618
+[ 205.799019] R10: 0000000000ffff10 R11: 000000000000000f R12: ffff9a0bc53384d0
+[ 205.799022] R13: 0000000000000282 R14: 00000000ae000001 R15: 0000000000000001
+[ 205.799024] FS: 0000000000000000(0000) GS:ffff9a0d0f300000(0000) knlGS:0000000000000000
+[ 205.799028] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 205.799031] CR2: 00007ff6b8311554 CR3: 000000001ac10004 CR4: 00000000001706e0
+[ 205.799033] Call Trace:
+[ 205.799035] <TASK>
+[ 205.799038] ? ax25_dev_device_down+0xd9/0x1b0 [ax25]
+[ 205.799047] ? ax25_device_event+0x9f/0x270 [ax25]
+[ 205.799055] ? raw_notifier_call_chain+0x49/0x60
+[ 205.799060] ? call_netdevice_notifiers_info+0x52/0xa0
+[ 205.799065] ? dev_close_many+0xc8/0x120
+[ 205.799070] ? unregister_netdevice_many+0x13d/0x890
+[ 205.799073] ? unregister_netdevice_queue+0x90/0xe0
+[ 205.799076] ? unregister_netdev+0x1d/0x30
+[ 205.799080] ? mkiss_close+0x7c/0xc0 [mkiss]
+[ 205.799084] ? tty_ldisc_close+0x2e/0x40
+[ 205.799089] ? tty_ldisc_hangup+0x137/0x210
+[ 205.799092] ? __tty_hangup.part.0+0x208/0x350
+[ 205.799098] ? tty_vhangup+0x15/0x20
+[ 205.799103] ? pty_close+0x127/0x160
+[ 205.799108] ? tty_release+0x139/0x5e0
+[ 205.799112] ? __fput+0x9f/0x260
+[ 205.799118] ax25_dev_device_down+0xd9/0x1b0 [ax25]
+[ 205.799126] ax25_device_event+0x9f/0x270 [ax25]
+[ 205.799135] raw_notifier_call_chain+0x49/0x60
+[ 205.799140] call_netdevice_notifiers_info+0x52/0xa0
+[ 205.799146] dev_close_many+0xc8/0x120
+[ 205.799152] unregister_netdevice_many+0x13d/0x890
+[ 205.799157] unregister_netdevice_queue+0x90/0xe0
+[ 205.799161] unregister_netdev+0x1d/0x30
+[ 205.799165] mkiss_close+0x7c/0xc0 [mkiss]
+[ 205.799170] tty_ldisc_close+0x2e/0x40
+[ 205.799173] tty_ldisc_hangup+0x137/0x210
+[ 205.799178] __tty_hangup.part.0+0x208/0x350
+[ 205.799184] tty_vhangup+0x15/0x20
+[ 205.799188] pty_close+0x127/0x160
+[ 205.799193] tty_release+0x139/0x5e0
+[ 205.799199] __fput+0x9f/0x260
+[ 205.799203] ____fput+0xe/0x10
+[ 205.799208] task_work_run+0x64/0xa0
+[ 205.799213] do_exit+0x33b/0xab0
+[ 205.799217] ? __handle_mm_fault+0xc4f/0x15f0
+[ 205.799224] do_group_exit+0x35/0xa0
+[ 205.799228] __x64_sys_exit_group+0x18/0x20
+[ 205.799232] do_syscall_64+0x5c/0x80
+[ 205.799238] ? handle_mm_fault+0xba/0x290
+[ 205.799242] ? debug_smp_processor_id+0x17/0x20
+[ 205.799246] ? fpregs_assert_state_consistent+0x26/0x50
+[ 205.799251] ? exit_to_user_mode_prepare+0x49/0x190
+[ 205.799256] ? irqentry_exit_to_user_mode+0x9/0x20
+[ 205.799260] ? irqentry_exit+0x33/0x40
+[ 205.799263] ? exc_page_fault+0x87/0x170
+[ 205.799268] ? asm_exc_page_fault+0x8/0x30
+[ 205.799273] entry_SYSCALL_64_after_hwframe+0x44/0xae
+[ 205.799277] RIP: 0033:0x7ff6b80eaca1
+[ 205.799281] Code: Unable to access opcode bytes at RIP 0x7ff6b80eac77.
+[ 205.799283] RSP: 002b:00007fff6dfd4738 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
+[ 205.799287] RAX: ffffffffffffffda RBX: 00007ff6b8215a00 RCX: 00007ff6b80eaca1
+[ 205.799290] RDX: 000000000000003c RSI: 00000000000000e7 RDI: 0000000000000001
+[ 205.799293] RBP: 0000000000000001 R08: ffffffffffffff80 R09: 0000000000000028
+[ 205.799295] R10: 0000000000000000 R11: 0000000000000246 R12: 00007ff6b8215a00
+[ 205.799298] R13: 0000000000000000 R14: 00007ff6b821aee8 R15: 00007ff6b821af00
+[ 205.799304] </TASK>
+
+Fixes: feef318c855a ("ax25: fix UAF bugs of net_device caused by rebinding operation")
+Reported-by: Bernard F6BVP <f6bvp@free.fr>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Duoming Zhou <duoming@zju.edu.cn>
+Link: https://lore.kernel.org/r/20220728051821.3160118-1-eric.dumazet@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ax25.h | 1 +
+ net/ax25/af_ax25.c | 4 ++--
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/ax25.h b/include/net/ax25.h
+index a427a05672e2..f8cf3629a419 100644
+--- a/include/net/ax25.h
++++ b/include/net/ax25.h
+@@ -236,6 +236,7 @@ typedef struct ax25_cb {
+ ax25_address source_addr, dest_addr;
+ ax25_digi *digipeat;
+ ax25_dev *ax25_dev;
++ netdevice_tracker dev_tracker;
+ unsigned char iamdigi;
+ unsigned char state, modulus, pidincl;
+ unsigned short vs, vr, va;
+diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
+index 4c7030ed8d33..5b5363c99ed5 100644
+--- a/net/ax25/af_ax25.c
++++ b/net/ax25/af_ax25.c
+@@ -1065,7 +1065,7 @@ static int ax25_release(struct socket *sock)
+ del_timer_sync(&ax25->t3timer);
+ del_timer_sync(&ax25->idletimer);
+ }
+- dev_put_track(ax25_dev->dev, &ax25_dev->dev_tracker);
++ dev_put_track(ax25_dev->dev, &ax25->dev_tracker);
+ ax25_dev_put(ax25_dev);
+ }
+
+@@ -1146,7 +1146,7 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+
+ if (ax25_dev) {
+ ax25_fillin_cb(ax25, ax25_dev);
+- dev_hold_track(ax25_dev->dev, &ax25_dev->dev_tracker, GFP_ATOMIC);
++ dev_hold_track(ax25_dev->dev, &ax25->dev_tracker, GFP_ATOMIC);
+ }
+
+ done:
+--
+2.35.1
+
--- /dev/null
+From ccfde46325a73e142e5511540891dfe5f75eb982 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 18:20:41 +0000
+Subject: binder: fix redefinition of seq_file attributes
+
+From: Carlos Llamas <cmllamas@google.com>
+
+[ Upstream commit b7e241bbff24f9e106bf616408fd58bcedc44bae ]
+
+The patchset in [1] exported some definitions to binder_internal.h in
+order to make the debugfs entries such as 'stats' and 'transaction_log'
+available in a binderfs instance. However, the DEFINE_SHOW_ATTRIBUTE
+macro expands into a static function/variable pair, which in turn get
+redefined each time a source file includes this internal header.
+
+This problem was made evident after a report from the kernel test robot
+<lkp@intel.com> where several W=1 build warnings are seen in downstream
+kernels. See the following example:
+
+ include/../drivers/android/binder_internal.h:111:23: warning: 'binder_stats_fops' defined but not used [-Wunused-const-variable=]
+ 111 | DEFINE_SHOW_ATTRIBUTE(binder_stats);
+ | ^~~~~~~~~~~~
+ include/linux/seq_file.h:174:37: note: in definition of macro 'DEFINE_SHOW_ATTRIBUTE'
+ 174 | static const struct file_operations __name ## _fops = { \
+ | ^~~~~~
+
+This patch fixes the above issues by moving back the definitions into
+binder.c and instead creates an array of the debugfs entries which is
+more convenient to share with binderfs and iterate through.
+
+ [1] https://lore.kernel.org/all/20190903161655.107408-1-hridya@google.com/
+
+Fixes: 0e13e452dafc ("binder: Add stats, state and transactions files")
+Fixes: 03e2e07e3814 ("binder: Make transaction_log available in binderfs")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Carlos Llamas <cmllamas@google.com>
+Link: https://lore.kernel.org/r/20220701182041.2134313-1-cmllamas@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/android/binder.c | 114 +++++++++++++++++++++---------
+ drivers/android/binder_internal.h | 46 +++---------
+ drivers/android/binderfs.c | 47 +++---------
+ 3 files changed, 100 insertions(+), 107 deletions(-)
+
+diff --git a/drivers/android/binder.c b/drivers/android/binder.c
+index f3b639e89dd8..5243fe0eb402 100644
+--- a/drivers/android/binder.c
++++ b/drivers/android/binder.c
+@@ -170,8 +170,32 @@ static inline void binder_stats_created(enum binder_stat_types type)
+ atomic_inc(&binder_stats.obj_created[type]);
+ }
+
+-struct binder_transaction_log binder_transaction_log;
+-struct binder_transaction_log binder_transaction_log_failed;
++struct binder_transaction_log_entry {
++ int debug_id;
++ int debug_id_done;
++ int call_type;
++ int from_proc;
++ int from_thread;
++ int target_handle;
++ int to_proc;
++ int to_thread;
++ int to_node;
++ int data_size;
++ int offsets_size;
++ int return_error_line;
++ uint32_t return_error;
++ uint32_t return_error_param;
++ char context_name[BINDERFS_MAX_NAME + 1];
++};
++
++struct binder_transaction_log {
++ atomic_t cur;
++ bool full;
++ struct binder_transaction_log_entry entry[32];
++};
++
++static struct binder_transaction_log binder_transaction_log;
++static struct binder_transaction_log binder_transaction_log_failed;
+
+ static struct binder_transaction_log_entry *binder_transaction_log_add(
+ struct binder_transaction_log *log)
+@@ -6084,8 +6108,7 @@ static void print_binder_proc_stats(struct seq_file *m,
+ print_binder_stats(m, " ", &proc->stats);
+ }
+
+-
+-int binder_state_show(struct seq_file *m, void *unused)
++static int state_show(struct seq_file *m, void *unused)
+ {
+ struct binder_proc *proc;
+ struct binder_node *node;
+@@ -6124,7 +6147,7 @@ int binder_state_show(struct seq_file *m, void *unused)
+ return 0;
+ }
+
+-int binder_stats_show(struct seq_file *m, void *unused)
++static int stats_show(struct seq_file *m, void *unused)
+ {
+ struct binder_proc *proc;
+
+@@ -6140,7 +6163,7 @@ int binder_stats_show(struct seq_file *m, void *unused)
+ return 0;
+ }
+
+-int binder_transactions_show(struct seq_file *m, void *unused)
++static int transactions_show(struct seq_file *m, void *unused)
+ {
+ struct binder_proc *proc;
+
+@@ -6196,7 +6219,7 @@ static void print_binder_transaction_log_entry(struct seq_file *m,
+ "\n" : " (incomplete)\n");
+ }
+
+-int binder_transaction_log_show(struct seq_file *m, void *unused)
++static int transaction_log_show(struct seq_file *m, void *unused)
+ {
+ struct binder_transaction_log *log = m->private;
+ unsigned int log_cur = atomic_read(&log->cur);
+@@ -6228,6 +6251,45 @@ const struct file_operations binder_fops = {
+ .release = binder_release,
+ };
+
++DEFINE_SHOW_ATTRIBUTE(state);
++DEFINE_SHOW_ATTRIBUTE(stats);
++DEFINE_SHOW_ATTRIBUTE(transactions);
++DEFINE_SHOW_ATTRIBUTE(transaction_log);
++
++const struct binder_debugfs_entry binder_debugfs_entries[] = {
++ {
++ .name = "state",
++ .mode = 0444,
++ .fops = &state_fops,
++ .data = NULL,
++ },
++ {
++ .name = "stats",
++ .mode = 0444,
++ .fops = &stats_fops,
++ .data = NULL,
++ },
++ {
++ .name = "transactions",
++ .mode = 0444,
++ .fops = &transactions_fops,
++ .data = NULL,
++ },
++ {
++ .name = "transaction_log",
++ .mode = 0444,
++ .fops = &transaction_log_fops,
++ .data = &binder_transaction_log,
++ },
++ {
++ .name = "failed_transaction_log",
++ .mode = 0444,
++ .fops = &transaction_log_fops,
++ .data = &binder_transaction_log_failed,
++ },
++ {} /* terminator */
++};
++
+ static int __init init_binder_device(const char *name)
+ {
+ int ret;
+@@ -6273,36 +6335,18 @@ static int __init binder_init(void)
+ atomic_set(&binder_transaction_log_failed.cur, ~0U);
+
+ binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL);
+- if (binder_debugfs_dir_entry_root)
++ if (binder_debugfs_dir_entry_root) {
++ const struct binder_debugfs_entry *db_entry;
++
++ binder_for_each_debugfs_entry(db_entry)
++ debugfs_create_file(db_entry->name,
++ db_entry->mode,
++ binder_debugfs_dir_entry_root,
++ db_entry->data,
++ db_entry->fops);
++
+ binder_debugfs_dir_entry_proc = debugfs_create_dir("proc",
+ binder_debugfs_dir_entry_root);
+-
+- if (binder_debugfs_dir_entry_root) {
+- debugfs_create_file("state",
+- 0444,
+- binder_debugfs_dir_entry_root,
+- NULL,
+- &binder_state_fops);
+- debugfs_create_file("stats",
+- 0444,
+- binder_debugfs_dir_entry_root,
+- NULL,
+- &binder_stats_fops);
+- debugfs_create_file("transactions",
+- 0444,
+- binder_debugfs_dir_entry_root,
+- NULL,
+- &binder_transactions_fops);
+- debugfs_create_file("transaction_log",
+- 0444,
+- binder_debugfs_dir_entry_root,
+- &binder_transaction_log,
+- &binder_transaction_log_fops);
+- debugfs_create_file("failed_transaction_log",
+- 0444,
+- binder_debugfs_dir_entry_root,
+- &binder_transaction_log_failed,
+- &binder_transaction_log_fops);
+ }
+
+ if (!IS_ENABLED(CONFIG_ANDROID_BINDERFS) &&
+diff --git a/drivers/android/binder_internal.h b/drivers/android/binder_internal.h
+index d6b6b8cb7346..1ade9799c8d5 100644
+--- a/drivers/android/binder_internal.h
++++ b/drivers/android/binder_internal.h
+@@ -107,41 +107,19 @@ static inline int __init init_binderfs(void)
+ }
+ #endif
+
+-int binder_stats_show(struct seq_file *m, void *unused);
+-DEFINE_SHOW_ATTRIBUTE(binder_stats);
+-
+-int binder_state_show(struct seq_file *m, void *unused);
+-DEFINE_SHOW_ATTRIBUTE(binder_state);
+-
+-int binder_transactions_show(struct seq_file *m, void *unused);
+-DEFINE_SHOW_ATTRIBUTE(binder_transactions);
+-
+-int binder_transaction_log_show(struct seq_file *m, void *unused);
+-DEFINE_SHOW_ATTRIBUTE(binder_transaction_log);
+-
+-struct binder_transaction_log_entry {
+- int debug_id;
+- int debug_id_done;
+- int call_type;
+- int from_proc;
+- int from_thread;
+- int target_handle;
+- int to_proc;
+- int to_thread;
+- int to_node;
+- int data_size;
+- int offsets_size;
+- int return_error_line;
+- uint32_t return_error;
+- uint32_t return_error_param;
+- char context_name[BINDERFS_MAX_NAME + 1];
++struct binder_debugfs_entry {
++ const char *name;
++ umode_t mode;
++ const struct file_operations *fops;
++ void *data;
+ };
+
+-struct binder_transaction_log {
+- atomic_t cur;
+- bool full;
+- struct binder_transaction_log_entry entry[32];
+-};
++extern const struct binder_debugfs_entry binder_debugfs_entries[];
++
++#define binder_for_each_debugfs_entry(entry) \
++ for ((entry) = binder_debugfs_entries; \
++ (entry)->name; \
++ (entry)++)
+
+ enum binder_stat_types {
+ BINDER_STAT_PROC,
+@@ -575,6 +553,4 @@ struct binder_object {
+ };
+ };
+
+-extern struct binder_transaction_log binder_transaction_log;
+-extern struct binder_transaction_log binder_transaction_log_failed;
+ #endif /* _LINUX_BINDER_INTERNAL_H */
+diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c
+index e3605cdd4335..6d717ed76766 100644
+--- a/drivers/android/binderfs.c
++++ b/drivers/android/binderfs.c
+@@ -621,6 +621,7 @@ static int init_binder_features(struct super_block *sb)
+ static int init_binder_logs(struct super_block *sb)
+ {
+ struct dentry *binder_logs_root_dir, *dentry, *proc_log_dir;
++ const struct binder_debugfs_entry *db_entry;
+ struct binderfs_info *info;
+ int ret = 0;
+
+@@ -631,43 +632,15 @@ static int init_binder_logs(struct super_block *sb)
+ goto out;
+ }
+
+- dentry = binderfs_create_file(binder_logs_root_dir, "stats",
+- &binder_stats_fops, NULL);
+- if (IS_ERR(dentry)) {
+- ret = PTR_ERR(dentry);
+- goto out;
+- }
+-
+- dentry = binderfs_create_file(binder_logs_root_dir, "state",
+- &binder_state_fops, NULL);
+- if (IS_ERR(dentry)) {
+- ret = PTR_ERR(dentry);
+- goto out;
+- }
+-
+- dentry = binderfs_create_file(binder_logs_root_dir, "transactions",
+- &binder_transactions_fops, NULL);
+- if (IS_ERR(dentry)) {
+- ret = PTR_ERR(dentry);
+- goto out;
+- }
+-
+- dentry = binderfs_create_file(binder_logs_root_dir,
+- "transaction_log",
+- &binder_transaction_log_fops,
+- &binder_transaction_log);
+- if (IS_ERR(dentry)) {
+- ret = PTR_ERR(dentry);
+- goto out;
+- }
+-
+- dentry = binderfs_create_file(binder_logs_root_dir,
+- "failed_transaction_log",
+- &binder_transaction_log_fops,
+- &binder_transaction_log_failed);
+- if (IS_ERR(dentry)) {
+- ret = PTR_ERR(dentry);
+- goto out;
++ binder_for_each_debugfs_entry(db_entry) {
++ dentry = binderfs_create_file(binder_logs_root_dir,
++ db_entry->name,
++ db_entry->fops,
++ db_entry->data);
++ if (IS_ERR(dentry)) {
++ ret = PTR_ERR(dentry);
++ goto out;
++ }
+ }
+
+ proc_log_dir = binderfs_create_dir(binder_logs_root_dir, "proc");
+--
+2.35.1
+
--- /dev/null
+From 9162012c2e613f9c2f0687af935356dd418d950f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 17:08:08 +0800
+Subject: blk-mq: don't create hctx debugfs dir until q->debugfs_dir is created
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit f3ec5d11554778c24ac8915e847223ed71d104fc ]
+
+blk_mq_debugfs_register_hctx() can be called by blk_mq_update_nr_hw_queues
+when gendisk isn't added yet, such as nvme tcp.
+
+Fixes the warning of 'debugfs: Directory 'hctx0' with parent '/' already present!'
+which can be observed reliably when running blktests nvme/005.
+
+Fixes: 6cfc0081b046 ("blk-mq: no need to check return value of debugfs_create functions")
+Reported-by: Yi Zhang <yi.zhang@redhat.com>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Tested-by: Yi Zhang <yi.zhang@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20220711090808.259682-1-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq-debugfs.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c
+index aa0349e9f083..34bee263936c 100644
+--- a/block/blk-mq-debugfs.c
++++ b/block/blk-mq-debugfs.c
+@@ -737,6 +737,9 @@ void blk_mq_debugfs_register_hctx(struct request_queue *q,
+ char name[20];
+ int i;
+
++ if (!q->debugfs_dir)
++ return;
++
+ snprintf(name, sizeof(name), "hctx%u", hctx->queue_num);
+ hctx->debugfs_dir = debugfs_create_dir(name, q->debugfs_dir);
+
+--
+2.35.1
+
--- /dev/null
+From 0cd621ffd75d4aba5b1cdf593aaf18527ac7c4b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 11:06:36 -0700
+Subject: blktrace: Trace remapped requests correctly
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 22c80aac882f712897b88b7ea8f5a74ea19019df ]
+
+Trace the remapped operation and its flags instead of only the data
+direction of remapped operations. This issue was detected by analyzing
+the warnings reported by sparse related to the new blk_opf_t type.
+
+Reviewed-by: Jun'ichi Nomura <junichi.nomura@nec.com>
+Cc: Mike Snitzer <snitzer@kernel.org>
+Cc: Mike Christie <michael.christie@oracle.com>
+Cc: Li Zefan <lizf@cn.fujitsu.com>
+Cc: Chaitanya Kulkarni <kch@nvidia.com>
+Fixes: 1b9a9ab78b0a ("blktrace: use op accessors")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20220714180729.1065367-11-bvanassche@acm.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/blktrace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
+index 4d5629196d01..f22219495541 100644
+--- a/kernel/trace/blktrace.c
++++ b/kernel/trace/blktrace.c
+@@ -1059,7 +1059,7 @@ static void blk_add_trace_rq_remap(void *ignore, struct request *rq, dev_t dev,
+ r.sector_from = cpu_to_be64(from);
+
+ __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq),
+- rq_data_dir(rq), 0, BLK_TA_REMAP, 0,
++ req_op(rq), rq->cmd_flags, BLK_TA_REMAP, 0,
+ sizeof(r), &r, blk_trace_request_get_cgid(rq));
+ rcu_read_unlock();
+ }
+--
+2.35.1
+
--- /dev/null
+From 456888a357dcb8e2bd1f81df1fe719171bb0e37b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 12:58:21 -0700
+Subject: block/bio: remove duplicate append pages code
+
+From: Keith Busch <kbusch@kernel.org>
+
+[ Upstream commit c58c0074c54c2e2bb3bb0d5a4d8896bb660cc8bc ]
+
+The getting pages setup for zone append and normal IO are identical. Use
+common code for each.
+
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20220610195830.3574005-3-kbusch@fb.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bio.c | 102 ++++++++++++++++++++++------------------------------
+ 1 file changed, 42 insertions(+), 60 deletions(-)
+
+diff --git a/block/bio.c b/block/bio.c
+index fd73ee03d57e..6f6e6e23889c 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -1129,6 +1129,37 @@ static void bio_put_pages(struct page **pages, size_t size, size_t off)
+ put_page(pages[i]);
+ }
+
++static int bio_iov_add_page(struct bio *bio, struct page *page,
++ unsigned int len, unsigned int offset)
++{
++ bool same_page = false;
++
++ if (!__bio_try_merge_page(bio, page, len, offset, &same_page)) {
++ if (WARN_ON_ONCE(bio_full(bio, len)))
++ return -EINVAL;
++ __bio_add_page(bio, page, len, offset);
++ return 0;
++ }
++
++ if (same_page)
++ put_page(page);
++ return 0;
++}
++
++static int bio_iov_add_zone_append_page(struct bio *bio, struct page *page,
++ unsigned int len, unsigned int offset)
++{
++ struct request_queue *q = bdev_get_queue(bio->bi_bdev);
++ bool same_page = false;
++
++ if (bio_add_hw_page(q, bio, page, len, offset,
++ queue_max_zone_append_sectors(q), &same_page) != len)
++ return -EINVAL;
++ if (same_page)
++ put_page(page);
++ return 0;
++}
++
+ #define PAGE_PTRS_PER_BVEC (sizeof(struct bio_vec) / sizeof(struct page *))
+
+ /**
+@@ -1147,7 +1178,6 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+ unsigned short entries_left = bio->bi_max_vecs - bio->bi_vcnt;
+ struct bio_vec *bv = bio->bi_io_vec + bio->bi_vcnt;
+ struct page **pages = (struct page **)bv;
+- bool same_page = false;
+ ssize_t size, left;
+ unsigned len, i;
+ size_t offset;
+@@ -1156,7 +1186,7 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+ * Move page array up in the allocated memory for the bio vecs as far as
+ * possible so that we can start filling biovecs from the beginning
+ * without overwriting the temporary page array.
+- */
++ */
+ BUILD_BUG_ON(PAGE_PTRS_PER_BVEC < 2);
+ pages += entries_left * (PAGE_PTRS_PER_BVEC - 1);
+
+@@ -1166,18 +1196,18 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+
+ for (left = size, i = 0; left > 0; left -= len, i++) {
+ struct page *page = pages[i];
++ int ret;
+
+ len = min_t(size_t, PAGE_SIZE - offset, left);
++ if (bio_op(bio) == REQ_OP_ZONE_APPEND)
++ ret = bio_iov_add_zone_append_page(bio, page, len,
++ offset);
++ else
++ ret = bio_iov_add_page(bio, page, len, offset);
+
+- if (__bio_try_merge_page(bio, page, len, offset, &same_page)) {
+- if (same_page)
+- put_page(page);
+- } else {
+- if (WARN_ON_ONCE(bio_full(bio, len))) {
+- bio_put_pages(pages + i, left, offset);
+- return -EINVAL;
+- }
+- __bio_add_page(bio, page, len, offset);
++ if (ret) {
++ bio_put_pages(pages + i, left, offset);
++ return ret;
+ }
+ offset = 0;
+ }
+@@ -1186,51 +1216,6 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+ return 0;
+ }
+
+-static int __bio_iov_append_get_pages(struct bio *bio, struct iov_iter *iter)
+-{
+- unsigned short nr_pages = bio->bi_max_vecs - bio->bi_vcnt;
+- unsigned short entries_left = bio->bi_max_vecs - bio->bi_vcnt;
+- struct request_queue *q = bdev_get_queue(bio->bi_bdev);
+- unsigned int max_append_sectors = queue_max_zone_append_sectors(q);
+- struct bio_vec *bv = bio->bi_io_vec + bio->bi_vcnt;
+- struct page **pages = (struct page **)bv;
+- ssize_t size, left;
+- unsigned len, i;
+- size_t offset;
+- int ret = 0;
+-
+- /*
+- * Move page array up in the allocated memory for the bio vecs as far as
+- * possible so that we can start filling biovecs from the beginning
+- * without overwriting the temporary page array.
+- */
+- BUILD_BUG_ON(PAGE_PTRS_PER_BVEC < 2);
+- pages += entries_left * (PAGE_PTRS_PER_BVEC - 1);
+-
+- size = iov_iter_get_pages(iter, pages, LONG_MAX, nr_pages, &offset);
+- if (unlikely(size <= 0))
+- return size ? size : -EFAULT;
+-
+- for (left = size, i = 0; left > 0; left -= len, i++) {
+- struct page *page = pages[i];
+- bool same_page = false;
+-
+- len = min_t(size_t, PAGE_SIZE - offset, left);
+- if (bio_add_hw_page(q, bio, page, len, offset,
+- max_append_sectors, &same_page) != len) {
+- bio_put_pages(pages + i, left, offset);
+- ret = -EINVAL;
+- break;
+- }
+- if (same_page)
+- put_page(page);
+- offset = 0;
+- }
+-
+- iov_iter_advance(iter, size - left);
+- return ret;
+-}
+-
+ /**
+ * bio_iov_iter_get_pages - add user or kernel pages to a bio
+ * @bio: bio to add pages to
+@@ -1265,10 +1250,7 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+ }
+
+ do {
+- if (bio_op(bio) == REQ_OP_ZONE_APPEND)
+- ret = __bio_iov_append_get_pages(bio, iter);
+- else
+- ret = __bio_iov_iter_get_pages(bio, iter);
++ ret = __bio_iov_iter_get_pages(bio, iter);
+ } while (!ret && iov_iter_count(iter) && !bio_full(bio, 0));
+
+ /* don't account direct I/O as memory stall */
+--
+2.35.1
+
--- /dev/null
+From 7eed6dd4d3cc42f050ab82c5a62a447db1cd4734 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 08:32:54 -0700
+Subject: block: ensure iov_iter advances for added pages
+
+From: Keith Busch <kbusch@kernel.org>
+
+[ Upstream commit 325347d965e7ccf5424a05398807a6d801846612 ]
+
+There are cases where a bio may not accept additional pages, and the iov
+needs to advance to the last data length that was accepted. The zone
+append used to handle this correctly, but was inadvertently broken when
+the setup was made common with the normal r/w case.
+
+Fixes: 576ed9135489c ("block: use bio_add_page in bio_iov_iter_get_pages")
+Fixes: c58c0074c54c2 ("block/bio: remove duplicate append pages code")
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Link: https://lore.kernel.org/r/20220712153256.2202024-1-kbusch@fb.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bio.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/block/bio.c b/block/bio.c
+index 6f6e6e23889c..7d4d5723350b 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -1181,6 +1181,7 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+ ssize_t size, left;
+ unsigned len, i;
+ size_t offset;
++ int ret = 0;
+
+ /*
+ * Move page array up in the allocated memory for the bio vecs as far as
+@@ -1196,7 +1197,6 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+
+ for (left = size, i = 0; left > 0; left -= len, i++) {
+ struct page *page = pages[i];
+- int ret;
+
+ len = min_t(size_t, PAGE_SIZE - offset, left);
+ if (bio_op(bio) == REQ_OP_ZONE_APPEND)
+@@ -1207,13 +1207,13 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
+
+ if (ret) {
+ bio_put_pages(pages + i, left, offset);
+- return ret;
++ break;
+ }
+ offset = 0;
+ }
+
+- iov_iter_advance(iter, size);
+- return 0;
++ iov_iter_advance(iter, size - left);
++ return ret;
+ }
+
+ /**
+--
+2.35.1
+
--- /dev/null
+From 366af8444a542dfc5e863d40da65750a807f68b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 12:58:20 -0700
+Subject: block: fix infinite loop for invalid zone append
+
+From: Keith Busch <kbusch@kernel.org>
+
+[ Upstream commit b82d9fa257cb3725c49d94d2aeafc4677c34448a ]
+
+Returning 0 early from __bio_iov_append_get_pages() for the
+max_append_sectors warning just creates an infinite loop since 0 means
+success, and the bio will never fill from the unadvancing iov_iter. We
+could turn the return into an error value, but it will already be turned
+into an error value later on, so just remove the warning. Clearly no one
+ever hit it anyway.
+
+Fixes: 0512a75b98f84 ("block: Introduce REQ_OP_ZONE_APPEND")
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Reviewed-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Link: https://lore.kernel.org/r/20220610195830.3574005-2-kbusch@fb.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bio.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/block/bio.c b/block/bio.c
+index d3ca79c3ebdf..fd73ee03d57e 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -1199,9 +1199,6 @@ static int __bio_iov_append_get_pages(struct bio *bio, struct iov_iter *iter)
+ size_t offset;
+ int ret = 0;
+
+- if (WARN_ON_ONCE(!max_append_sectors))
+- return 0;
+-
+ /*
+ * Move page array up in the allocated memory for the bio vecs as far as
+ * possible so that we can start filling biovecs from the beginning
+--
+2.35.1
+
--- /dev/null
+From b75459de48a84a6aab6e808db45fc1bd151c898c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 16:31:21 +0200
+Subject: block/rnbd-srv: Set keep_id to true after mutex_trylock
+
+From: Md Haris Iqbal <haris.iqbal@ionos.com>
+
+[ Upstream commit 4bc14f3101364877dd59085f39e068a2a7ec9f2d ]
+
+After setting keep_id if the mutex trylock fails, the keep_id stays set
+for the rest of the sess_dev lifetime.
+
+Therefore, set keep_id to true after mutex_trylock succeeds, so that a
+failure of trylock does'nt touch keep_id.
+
+Fixes: b168e1d85cf3 ("block/rnbd-srv: Prevent a deadlock generated by accessing sysfs in parallel")
+Cc: gi-oh.kim@ionos.com
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Link: https://lore.kernel.org/r/20220707143122.460362-2-haris.iqbal@ionos.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/rnbd/rnbd-srv.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/block/rnbd/rnbd-srv.c b/drivers/block/rnbd/rnbd-srv.c
+index f04df6294650..963df70ea026 100644
+--- a/drivers/block/rnbd/rnbd-srv.c
++++ b/drivers/block/rnbd/rnbd-srv.c
+@@ -323,10 +323,11 @@ void rnbd_srv_sess_dev_force_close(struct rnbd_srv_sess_dev *sess_dev,
+ {
+ struct rnbd_srv_session *sess = sess_dev->sess;
+
+- sess_dev->keep_id = true;
+ /* It is already started to close by client's close message. */
+ if (!mutex_trylock(&sess->lock))
+ return;
++
++ sess_dev->keep_id = true;
+ /* first remove sysfs itself to avoid deadlock */
+ sysfs_remove_file_self(&sess_dev->kobj, &attr->attr);
+ rnbd_srv_destroy_dev_session_sysfs(sess_dev);
+--
+2.35.1
+
--- /dev/null
+From ba8afcf0d9e4c01c6ac343af2c49b4982e76bf92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Jul 2022 18:33:24 +0800
+Subject: Bluetooth: Add default wakeup callback for HCI UART driver
+
+From: Ying Hsu <yinghsu@chromium.org>
+
+[ Upstream commit bee5395ced44c5a312348557eb2dfb0c2a7bfaa2 ]
+
+Bluetooth HCI devices indicate if they are able to wakeup in the wakeup
+callback since 'commit 4539ca67fe8e ("Bluetooth: Rename driver
+.prevent_wake to .wakeup")'. This patch adds a default wakeup callback
+for Bluetooth HCI UAR devices. It assumes Bluetooth HCI UART devices are
+wakeable for backward compatibility. For those who need a customized
+behavior, one can override it before calling hci_uart_register_device().
+
+Fixes: 4539ca67fe8e ("Bluetooth: Rename driver .prevent_wake to .wakeup")
+Signed-off-by: Ying Hsu <yinghsu@chromium.org>
+Reviewed-by: Alain Michaud <alainm@chromium.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/hci_serdev.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c
+index 4cda890ce647..c0e5f42ec6b7 100644
+--- a/drivers/bluetooth/hci_serdev.c
++++ b/drivers/bluetooth/hci_serdev.c
+@@ -231,6 +231,15 @@ static int hci_uart_setup(struct hci_dev *hdev)
+ return 0;
+ }
+
++/* Check if the device is wakeable */
++static bool hci_uart_wakeup(struct hci_dev *hdev)
++{
++ /* HCI UART devices are assumed to be wakeable by default.
++ * Implement wakeup callback to override this behavior.
++ */
++ return true;
++}
++
+ /** hci_uart_write_wakeup - transmit buffer wakeup
+ * @serdev: serial device
+ *
+@@ -342,6 +351,8 @@ int hci_uart_register_device(struct hci_uart *hu,
+ hdev->flush = hci_uart_flush;
+ hdev->send = hci_uart_send_frame;
+ hdev->setup = hci_uart_setup;
++ if (!hdev->wakeup)
++ hdev->wakeup = hci_uart_wakeup;
+ SET_HCIDEV_DEV(hdev, &hu->serdev->dev);
+
+ if (test_bit(HCI_UART_NO_SUSPEND_NOTIFIER, &hu->flags))
+--
+2.35.1
+
--- /dev/null
+From 85c67c55ebf502fa1ad203c9bea9755a372692c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 09:24:36 +0800
+Subject: Bluetooth: hci_intel: Add check for platform_driver_register
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit ab2d2a982ff721f4b029282d9a40602ea46a745e ]
+
+As platform_driver_register() could fail, it should be better
+to deal with the return value in order to maintain the code
+consisitency.
+
+Fixes: 1ab1f239bf17 ("Bluetooth: hci_intel: Add support for platform driver")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/hci_intel.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c
+index 7249b91d9b91..78afb9a348e7 100644
+--- a/drivers/bluetooth/hci_intel.c
++++ b/drivers/bluetooth/hci_intel.c
+@@ -1217,7 +1217,11 @@ static struct platform_driver intel_driver = {
+
+ int __init intel_init(void)
+ {
+- platform_driver_register(&intel_driver);
++ int err;
++
++ err = platform_driver_register(&intel_driver);
++ if (err)
++ return err;
+
+ return hci_uart_register_proto(&intel_proto);
+ }
+--
+2.35.1
+
--- /dev/null
+From c828f515faedd7582f2a97635fbd1fc86ec9d28a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 17:12:14 -0700
+Subject: Bluetooth: hci_sync: Fix not updating privacy_mode
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 0900b1c62f43e495d04ca4bebdf80b34f3c12432 ]
+
+When programming a new entry into the resolving list it shall default
+to network mode since the params may contain the mode programmed when
+the device was last added to the resolving list.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=209745
+Fixes: 853b70b506a20 ("Bluetooth: hci_sync: Set Privacy Mode when updating the resolving list")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Tested-by: Zhengping Jiang <jiangzp@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 99ef15167a81..6f901398132e 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -1612,6 +1612,9 @@ static int hci_le_add_resolve_list_sync(struct hci_dev *hdev,
+ bacpy(&cp.bdaddr, ¶ms->addr);
+ memcpy(cp.peer_irk, irk->val, 16);
+
++ /* Default privacy mode is always Network */
++ params->privacy_mode = HCI_NETWORK_PRIVACY;
++
+ done:
+ if (hci_dev_test_flag(hdev, HCI_PRIVACY))
+ memcpy(cp.local_irk, hdev->irk, 16);
+--
+2.35.1
+
--- /dev/null
+From 0500b65d0310279169685d25798adad293eeb804 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 17:05:30 -0700
+Subject: Bluetooth: hci_sync: Fix resuming scan after suspend resume
+
+From: Zhengping Jiang <jiangzp@google.com>
+
+[ Upstream commit 68253f3cd715e819bc4bff2b0e6b21234e259d56 ]
+
+After resuming, remove setting scanning_paused to false, because it is
+checked and set to false in hci_resume_scan_sync. Also move setting
+the value to false before updating passive scan, because the value is
+used when resuming passive scan.
+
+Fixes: 3b42055388c30 (Bluetooth: hci_sync: Fix attempting to suspend with
+unfiltered passive scan)
+
+Signed-off-by: Zhengping Jiang <jiangzp@google.com>
+Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_sync.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 9e2a42299fc0..99ef15167a81 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -5008,13 +5008,13 @@ static int hci_resume_scan_sync(struct hci_dev *hdev)
+ if (!hdev->scanning_paused)
+ return 0;
+
++ hdev->scanning_paused = false;
++
+ hci_update_scan_sync(hdev);
+
+ /* Reset passive scanning to normal */
+ hci_update_passive_scan_sync(hdev);
+
+- hdev->scanning_paused = false;
+-
+ return 0;
+ }
+
+@@ -5033,7 +5033,6 @@ int hci_resume_sync(struct hci_dev *hdev)
+ return 0;
+
+ hdev->suspended = false;
+- hdev->scanning_paused = false;
+
+ /* Restore event mask */
+ hci_set_event_mask_sync(hdev);
+--
+2.35.1
+
--- /dev/null
+From 1d234698c1d3bd47255b8aa6c0c6abec49235d9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:43:27 -0700
+Subject: Bluetooth: mgmt: Fix refresh cached connection info
+
+From: Zhengping Jiang <jiangzp@google.com>
+
+[ Upstream commit d7b2fdfb53ea09382941c0a4950dc9b00d51d1c7 ]
+
+Set the connection data before calling get_conn_info_sync, so it can be
+verified the connection is still connected, before refreshing cached
+values.
+
+Fixes: 47db6b42991e6 ("Bluetooth: hci_sync: Convert MGMT_OP_GET_CONN_INFO")
+Signed-off-by: Zhengping Jiang <jiangzp@google.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index ae758ab1b558..12c1ecdba3f3 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -6821,11 +6821,14 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
+
+ cmd = mgmt_pending_new(sk, MGMT_OP_GET_CONN_INFO, hdev, data,
+ len);
+- if (!cmd)
++ if (!cmd) {
+ err = -ENOMEM;
+- else
++ } else {
++ hci_conn_hold(conn);
++ cmd->user_data = hci_conn_get(conn);
+ err = hci_cmd_sync_queue(hdev, get_conn_info_sync,
+ cmd, get_conn_info_complete);
++ }
+
+ if (err < 0) {
+ mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_CONN_INFO,
+@@ -6837,9 +6840,6 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
+ goto unlock;
+ }
+
+- hci_conn_hold(conn);
+- cmd->user_data = hci_conn_get(conn);
+-
+ conn->conn_info_timestamp = jiffies;
+ } else {
+ /* Cache is valid, just reply with values cached in hci_conn */
+--
+2.35.1
+
--- /dev/null
+From 84df59aff8bcfb1858d6c34ec63d77824c67faa0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 16:19:14 +0800
+Subject: Bluetooth: When HCI work queue is drained, only queue chained work
+
+From: Schspa Shi <schspa@gmail.com>
+
+[ Upstream commit 877afadad2dce8aae1f2aad8ce47e072d4f6165e ]
+
+The HCI command, event, and data packet processing workqueue is drained
+to avoid deadlock in commit
+76727c02c1e1 ("Bluetooth: Call drain_workqueue() before resetting state").
+
+There is another delayed work, which will queue command to this drained
+workqueue. Which results in the following error report:
+
+Bluetooth: hci2: command 0x040f tx timeout
+WARNING: CPU: 1 PID: 18374 at kernel/workqueue.c:1438 __queue_work+0xdad/0x1140
+Workqueue: events hci_cmd_timeout
+RIP: 0010:__queue_work+0xdad/0x1140
+RSP: 0000:ffffc90002cffc60 EFLAGS: 00010093
+RAX: 0000000000000000 RBX: ffff8880b9d3ec00 RCX: 0000000000000000
+RDX: ffff888024ba0000 RSI: ffffffff814e048d RDI: ffff8880b9d3ec08
+RBP: 0000000000000008 R08: 0000000000000000 R09: 00000000b9d39700
+R10: ffffffff814f73c6 R11: 0000000000000000 R12: ffff88807cce4c60
+R13: 0000000000000000 R14: ffff8880796d8800 R15: ffff8880796d8800
+FS: 0000000000000000(0000) GS:ffff8880b9d00000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000c0174b4000 CR3: 000000007cae9000 CR4: 00000000003506e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+ ? queue_work_on+0xcb/0x110
+ ? lockdep_hardirqs_off+0x90/0xd0
+ queue_work_on+0xee/0x110
+ process_one_work+0x996/0x1610
+ ? pwq_dec_nr_in_flight+0x2a0/0x2a0
+ ? rwlock_bug.part.0+0x90/0x90
+ ? _raw_spin_lock_irq+0x41/0x50
+ worker_thread+0x665/0x1080
+ ? process_one_work+0x1610/0x1610
+ kthread+0x2e9/0x3a0
+ ? kthread_complete_and_exit+0x40/0x40
+ ret_from_fork+0x1f/0x30
+ </TASK>
+
+To fix this, we can add a new HCI_DRAIN_WQ flag, and don't queue the
+timeout workqueue while command workqueue is draining.
+
+Fixes: 76727c02c1e1 ("Bluetooth: Call drain_workqueue() before resetting state")
+Reported-by: syzbot+63bed493aebbf6872647@syzkaller.appspotmail.com
+Signed-off-by: Schspa Shi <schspa@gmail.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci.h | 1 +
+ net/bluetooth/hci_core.c | 10 +++++++++-
+ net/bluetooth/hci_event.c | 5 +++--
+ 3 files changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index 62a9bb022aed..5f2342205ae1 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -361,6 +361,7 @@ enum {
+ HCI_QUALITY_REPORT,
+ HCI_OFFLOAD_CODECS_ENABLED,
+ HCI_LE_SIMULTANEOUS_ROLES,
++ HCI_CMD_DRAIN_WORKQUEUE,
+
+ __HCI_NUM_FLAGS,
+ };
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 19df3905c5f8..2b8b51b89452 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -593,6 +593,11 @@ static int hci_dev_do_reset(struct hci_dev *hdev)
+ skb_queue_purge(&hdev->rx_q);
+ skb_queue_purge(&hdev->cmd_q);
+
++ /* Cancel these to avoid queueing non-chained pending work */
++ hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
++ cancel_delayed_work(&hdev->cmd_timer);
++ cancel_delayed_work(&hdev->ncmd_timer);
++
+ /* Avoid potential lockdep warnings from the *_flush() calls by
+ * ensuring the workqueue is empty up front.
+ */
+@@ -606,6 +611,8 @@ static int hci_dev_do_reset(struct hci_dev *hdev)
+ if (hdev->flush)
+ hdev->flush(hdev);
+
++ hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
++
+ atomic_set(&hdev->cmd_cnt, 1);
+ hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
+
+@@ -3863,7 +3870,8 @@ static void hci_cmd_work(struct work_struct *work)
+ if (res < 0)
+ __hci_cmd_sync_cancel(hdev, -res);
+
+- if (test_bit(HCI_RESET, &hdev->flags))
++ if (test_bit(HCI_RESET, &hdev->flags) ||
++ hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
+ cancel_delayed_work(&hdev->cmd_timer);
+ else
+ schedule_delayed_work(&hdev->cmd_timer,
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index af17dfb20e01..7cb956d3abb2 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3768,8 +3768,9 @@ static inline void handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd)
+ cancel_delayed_work(&hdev->ncmd_timer);
+ atomic_set(&hdev->cmd_cnt, 1);
+ } else {
+- schedule_delayed_work(&hdev->ncmd_timer,
+- HCI_NCMD_TIMEOUT);
++ if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
++ schedule_delayed_work(&hdev->ncmd_timer,
++ HCI_NCMD_TIMEOUT);
+ }
+ }
+ }
+--
+2.35.1
+
--- /dev/null
+From 6f2c6603905c38650e90b907e7d84ed2a771423e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Apr 2022 03:18:53 +0530
+Subject: bpf: Adapt copy_map_value for multiple offset case
+
+From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+
+[ Upstream commit 4d7d7f69f4b104b2ddeec6a1e7fcfd2d044ed8c4 ]
+
+Since now there might be at most 10 offsets that need handling in
+copy_map_value, the manual shuffling and special case is no longer going
+to work. Hence, let's generalise the copy_map_value function by using
+a sorted array of offsets to skip regions that must be avoided while
+copying into and out of a map value.
+
+When the map is created, we populate the offset array in struct map,
+Then, copy_map_value uses this sorted offset array is used to memcpy
+while skipping timer, spin lock, and kptr. The array is allocated as
+in most cases none of these special fields would be present in map
+value, hence we can save on space for the common case by not embedding
+the entire object inside bpf_map struct.
+
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20220424214901.2743946-6-memxor@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/bpf.h | 56 +++++++++++++++-------------
+ kernel/bpf/syscall.c | 88 +++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 117 insertions(+), 27 deletions(-)
+
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 2f6e7fc474ea..a3fe7f53e567 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -158,6 +158,9 @@ struct bpf_map_ops {
+ enum {
+ /* Support at most 8 pointers in a BPF map value */
+ BPF_MAP_VALUE_OFF_MAX = 8,
++ BPF_MAP_OFF_ARR_MAX = BPF_MAP_VALUE_OFF_MAX +
++ 1 + /* for bpf_spin_lock */
++ 1, /* for bpf_timer */
+ };
+
+ enum bpf_kptr_type {
+@@ -179,6 +182,12 @@ struct bpf_map_value_off {
+ struct bpf_map_value_off_desc off[];
+ };
+
++struct bpf_map_off_arr {
++ u32 cnt;
++ u32 field_off[BPF_MAP_OFF_ARR_MAX];
++ u8 field_sz[BPF_MAP_OFF_ARR_MAX];
++};
++
+ struct bpf_map {
+ /* The first two cachelines with read-mostly members of which some
+ * are also accessed in fast-path (e.g. ops, max_entries).
+@@ -207,10 +216,7 @@ struct bpf_map {
+ struct mem_cgroup *memcg;
+ #endif
+ char name[BPF_OBJ_NAME_LEN];
+- bool bypass_spec_v1;
+- bool frozen; /* write-once; write-protected by freeze_mutex */
+- /* 6 bytes hole */
+-
++ struct bpf_map_off_arr *off_arr;
+ /* The 3rd and 4th cacheline with misc members to avoid false sharing
+ * particularly with refcounting.
+ */
+@@ -230,6 +236,8 @@ struct bpf_map {
+ bool jited;
+ bool xdp_has_frags;
+ } owner;
++ bool bypass_spec_v1;
++ bool frozen; /* write-once; write-protected by freeze_mutex */
+ };
+
+ static inline bool map_value_has_spin_lock(const struct bpf_map *map)
+@@ -253,37 +261,33 @@ static inline void check_and_init_map_value(struct bpf_map *map, void *dst)
+ memset(dst + map->spin_lock_off, 0, sizeof(struct bpf_spin_lock));
+ if (unlikely(map_value_has_timer(map)))
+ memset(dst + map->timer_off, 0, sizeof(struct bpf_timer));
++ if (unlikely(map_value_has_kptrs(map))) {
++ struct bpf_map_value_off *tab = map->kptr_off_tab;
++ int i;
++
++ for (i = 0; i < tab->nr_off; i++)
++ *(u64 *)(dst + tab->off[i].offset) = 0;
++ }
+ }
+
+ /* copy everything but bpf_spin_lock and bpf_timer. There could be one of each. */
+ static inline void copy_map_value(struct bpf_map *map, void *dst, void *src)
+ {
+- u32 s_off = 0, s_sz = 0, t_off = 0, t_sz = 0;
++ u32 curr_off = 0;
++ int i;
+
+- if (unlikely(map_value_has_spin_lock(map))) {
+- s_off = map->spin_lock_off;
+- s_sz = sizeof(struct bpf_spin_lock);
+- }
+- if (unlikely(map_value_has_timer(map))) {
+- t_off = map->timer_off;
+- t_sz = sizeof(struct bpf_timer);
++ if (likely(!map->off_arr)) {
++ memcpy(dst, src, map->value_size);
++ return;
+ }
+
+- if (unlikely(s_sz || t_sz)) {
+- if (s_off < t_off || !s_sz) {
+- swap(s_off, t_off);
+- swap(s_sz, t_sz);
+- }
+- memcpy(dst, src, t_off);
+- memcpy(dst + t_off + t_sz,
+- src + t_off + t_sz,
+- s_off - t_off - t_sz);
+- memcpy(dst + s_off + s_sz,
+- src + s_off + s_sz,
+- map->value_size - s_off - s_sz);
+- } else {
+- memcpy(dst, src, map->value_size);
++ for (i = 0; i < map->off_arr->cnt; i++) {
++ u32 next_off = map->off_arr->field_off[i];
++
++ memcpy(dst + curr_off, src + curr_off, next_off - curr_off);
++ curr_off += map->off_arr->field_sz[i];
+ }
++ memcpy(dst + curr_off, src + curr_off, map->value_size - curr_off);
+ }
+ void copy_map_value_locked(struct bpf_map *map, void *dst, void *src,
+ bool lock_src);
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index dc49bd880ac0..811bc71b0906 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -30,6 +30,7 @@
+ #include <linux/pgtable.h>
+ #include <linux/bpf_lsm.h>
+ #include <linux/poll.h>
++#include <linux/sort.h>
+ #include <linux/bpf-netns.h>
+ #include <linux/rcupdate_trace.h>
+ #include <linux/memcontrol.h>
+@@ -551,6 +552,7 @@ static void bpf_map_free_deferred(struct work_struct *work)
+ struct bpf_map *map = container_of(work, struct bpf_map, work);
+
+ security_bpf_map_free(map);
++ kfree(map->off_arr);
+ bpf_map_free_kptr_off_tab(map);
+ bpf_map_release_memcg(map);
+ /* implementation dependent freeing */
+@@ -840,6 +842,84 @@ int map_check_no_btf(const struct bpf_map *map,
+ return -ENOTSUPP;
+ }
+
++static int map_off_arr_cmp(const void *_a, const void *_b, const void *priv)
++{
++ const u32 a = *(const u32 *)_a;
++ const u32 b = *(const u32 *)_b;
++
++ if (a < b)
++ return -1;
++ else if (a > b)
++ return 1;
++ return 0;
++}
++
++static void map_off_arr_swap(void *_a, void *_b, int size, const void *priv)
++{
++ struct bpf_map *map = (struct bpf_map *)priv;
++ u32 *off_base = map->off_arr->field_off;
++ u32 *a = _a, *b = _b;
++ u8 *sz_a, *sz_b;
++
++ sz_a = map->off_arr->field_sz + (a - off_base);
++ sz_b = map->off_arr->field_sz + (b - off_base);
++
++ swap(*a, *b);
++ swap(*sz_a, *sz_b);
++}
++
++static int bpf_map_alloc_off_arr(struct bpf_map *map)
++{
++ bool has_spin_lock = map_value_has_spin_lock(map);
++ bool has_timer = map_value_has_timer(map);
++ bool has_kptrs = map_value_has_kptrs(map);
++ struct bpf_map_off_arr *off_arr;
++ u32 i;
++
++ if (!has_spin_lock && !has_timer && !has_kptrs) {
++ map->off_arr = NULL;
++ return 0;
++ }
++
++ off_arr = kmalloc(sizeof(*map->off_arr), GFP_KERNEL | __GFP_NOWARN);
++ if (!off_arr)
++ return -ENOMEM;
++ map->off_arr = off_arr;
++
++ off_arr->cnt = 0;
++ if (has_spin_lock) {
++ i = off_arr->cnt;
++
++ off_arr->field_off[i] = map->spin_lock_off;
++ off_arr->field_sz[i] = sizeof(struct bpf_spin_lock);
++ off_arr->cnt++;
++ }
++ if (has_timer) {
++ i = off_arr->cnt;
++
++ off_arr->field_off[i] = map->timer_off;
++ off_arr->field_sz[i] = sizeof(struct bpf_timer);
++ off_arr->cnt++;
++ }
++ if (has_kptrs) {
++ struct bpf_map_value_off *tab = map->kptr_off_tab;
++ u32 *off = &off_arr->field_off[off_arr->cnt];
++ u8 *sz = &off_arr->field_sz[off_arr->cnt];
++
++ for (i = 0; i < tab->nr_off; i++) {
++ *off++ = tab->off[i].offset;
++ *sz++ = sizeof(u64);
++ }
++ off_arr->cnt += tab->nr_off;
++ }
++
++ if (off_arr->cnt == 1)
++ return 0;
++ sort_r(off_arr->field_off, off_arr->cnt, sizeof(off_arr->field_off[0]),
++ map_off_arr_cmp, map_off_arr_swap, map);
++ return 0;
++}
++
+ static int map_check_btf(struct bpf_map *map, const struct btf *btf,
+ u32 btf_key_id, u32 btf_value_id)
+ {
+@@ -1009,10 +1089,14 @@ static int map_create(union bpf_attr *attr)
+ attr->btf_vmlinux_value_type_id;
+ }
+
+- err = security_bpf_map_alloc(map);
++ err = bpf_map_alloc_off_arr(map);
+ if (err)
+ goto free_map;
+
++ err = security_bpf_map_alloc(map);
++ if (err)
++ goto free_map_off_arr;
++
+ err = bpf_map_alloc_id(map);
+ if (err)
+ goto free_map_sec;
+@@ -1035,6 +1119,8 @@ static int map_create(union bpf_attr *attr)
+
+ free_map_sec:
+ security_bpf_map_free(map);
++free_map_off_arr:
++ kfree(map->off_arr);
+ free_map:
+ btf_put(map->btf);
+ map->ops->map_free(map);
+--
+2.35.1
+
--- /dev/null
+From 24d09d9249d05e09ada541ae4d148ddd6874e44c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Apr 2022 03:18:51 +0530
+Subject: bpf: Allow storing referenced kptr in map
+
+From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+
+[ Upstream commit c0a5a21c25f37c9fd7b36072f9968cdff1e4aa13 ]
+
+Extending the code in previous commits, introduce referenced kptr
+support, which needs to be tagged using 'kptr_ref' tag instead. Unlike
+unreferenced kptr, referenced kptr have a lot more restrictions. In
+addition to the type matching, only a newly introduced bpf_kptr_xchg
+helper is allowed to modify the map value at that offset. This transfers
+the referenced pointer being stored into the map, releasing the
+references state for the program, and returning the old value and
+creating new reference state for the returned pointer.
+
+Similar to unreferenced pointer case, return value for this case will
+also be PTR_TO_BTF_ID_OR_NULL. The reference for the returned pointer
+must either be eventually released by calling the corresponding release
+function, otherwise it must be transferred into another map.
+
+It is also allowed to call bpf_kptr_xchg with a NULL pointer, to clear
+the value, and obtain the old value if any.
+
+BPF_LDX, BPF_STX, and BPF_ST cannot access referenced kptr. A future
+commit will permit using BPF_LDX for such pointers, but attempt at
+making it safe, since the lifetime of object won't be guaranteed.
+
+There are valid reasons to enforce the restriction of permitting only
+bpf_kptr_xchg to operate on referenced kptr. The pointer value must be
+consistent in face of concurrent modification, and any prior values
+contained in the map must also be released before a new one is moved
+into the map. To ensure proper transfer of this ownership, bpf_kptr_xchg
+returns the old value, which the verifier would require the user to
+either free or move into another map, and releases the reference held
+for the pointer being moved in.
+
+In the future, direct BPF_XCHG instruction may also be permitted to work
+like bpf_kptr_xchg helper.
+
+Note that process_kptr_func doesn't have to call
+check_helper_mem_access, since we already disallow rdonly/wronly flags
+for map, which is what check_map_access_type checks, and we already
+ensure the PTR_TO_MAP_VALUE refers to kptr by obtaining its off_desc,
+so check_map_access is also not required.
+
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20220424214901.2743946-4-memxor@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/bpf.h | 8 +++
+ include/uapi/linux/bpf.h | 12 +++++
+ kernel/bpf/btf.c | 10 +++-
+ kernel/bpf/helpers.c | 24 +++++++++
+ kernel/bpf/verifier.c | 98 +++++++++++++++++++++++++++++-----
+ tools/include/uapi/linux/bpf.h | 12 +++++
+ 6 files changed, 151 insertions(+), 13 deletions(-)
+
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 2feae4a24d99..2f6e7fc474ea 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -160,8 +160,14 @@ enum {
+ BPF_MAP_VALUE_OFF_MAX = 8,
+ };
+
++enum bpf_kptr_type {
++ BPF_KPTR_UNREF,
++ BPF_KPTR_REF,
++};
++
+ struct bpf_map_value_off_desc {
+ u32 offset;
++ enum bpf_kptr_type type;
+ struct {
+ struct btf *btf;
+ u32 btf_id;
+@@ -418,6 +424,7 @@ enum bpf_arg_type {
+ ARG_PTR_TO_STACK, /* pointer to stack */
+ ARG_PTR_TO_CONST_STR, /* pointer to a null terminated read-only string */
+ ARG_PTR_TO_TIMER, /* pointer to bpf_timer */
++ ARG_PTR_TO_KPTR, /* pointer to referenced kptr */
+ __BPF_ARG_TYPE_MAX,
+
+ /* Extended arg_types. */
+@@ -427,6 +434,7 @@ enum bpf_arg_type {
+ ARG_PTR_TO_SOCKET_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_SOCKET,
+ ARG_PTR_TO_ALLOC_MEM_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_ALLOC_MEM,
+ ARG_PTR_TO_STACK_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_STACK,
++ ARG_PTR_TO_BTF_ID_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_BTF_ID,
+
+ /* This must be the last entry. Its purpose is to ensure the enum is
+ * wide enough to hold the higher bits reserved for bpf_type_flag.
+diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
+index a4f557338af7..ff9af73859ca 100644
+--- a/include/uapi/linux/bpf.h
++++ b/include/uapi/linux/bpf.h
+@@ -5144,6 +5144,17 @@ union bpf_attr {
+ * The **hash_algo** is returned on success,
+ * **-EOPNOTSUP** if the hash calculation failed or **-EINVAL** if
+ * invalid arguments are passed.
++ *
++ * void *bpf_kptr_xchg(void *map_value, void *ptr)
++ * Description
++ * Exchange kptr at pointer *map_value* with *ptr*, and return the
++ * old value. *ptr* can be NULL, otherwise it must be a referenced
++ * pointer which will be released when this helper is called.
++ * Return
++ * The old value of kptr (which can be NULL). The returned pointer
++ * if not NULL, is a reference which must be released using its
++ * corresponding release function, or moved into a BPF map before
++ * program exit.
+ */
+ #define __BPF_FUNC_MAPPER(FN) \
+ FN(unspec), \
+@@ -5340,6 +5351,7 @@ union bpf_attr {
+ FN(copy_from_user_task), \
+ FN(skb_set_tstamp), \
+ FN(ima_file_hash), \
++ FN(kptr_xchg), \
+ /* */
+
+ /* integer value in 'imm' field of BPF_CALL instruction selects which helper
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 752de8112206..58fd6896c403 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -3177,6 +3177,7 @@ enum {
+ struct btf_field_info {
+ u32 type_id;
+ u32 off;
++ enum bpf_kptr_type type;
+ };
+
+ static int btf_find_struct(const struct btf *btf, const struct btf_type *t,
+@@ -3193,6 +3194,7 @@ static int btf_find_struct(const struct btf *btf, const struct btf_type *t,
+ static int btf_find_kptr(const struct btf *btf, const struct btf_type *t,
+ u32 off, int sz, struct btf_field_info *info)
+ {
++ enum bpf_kptr_type type;
+ u32 res_id;
+
+ /* For PTR, sz is always == 8 */
+@@ -3205,7 +3207,11 @@ static int btf_find_kptr(const struct btf *btf, const struct btf_type *t,
+ /* Reject extra tags */
+ if (btf_type_is_type_tag(btf_type_by_id(btf, t->type)))
+ return -EINVAL;
+- if (strcmp("kptr", __btf_name_by_offset(btf, t->name_off)))
++ if (!strcmp("kptr", __btf_name_by_offset(btf, t->name_off)))
++ type = BPF_KPTR_UNREF;
++ else if (!strcmp("kptr_ref", __btf_name_by_offset(btf, t->name_off)))
++ type = BPF_KPTR_REF;
++ else
+ return -EINVAL;
+
+ /* Get the base type */
+@@ -3216,6 +3222,7 @@ static int btf_find_kptr(const struct btf *btf, const struct btf_type *t,
+
+ info->type_id = res_id;
+ info->off = off;
++ info->type = type;
+ return BTF_FIELD_FOUND;
+ }
+
+@@ -3420,6 +3427,7 @@ struct bpf_map_value_off *btf_parse_kptrs(const struct btf *btf,
+ }
+
+ tab->off[i].offset = info_arr[i].off;
++ tab->off[i].type = info_arr[i].type;
+ tab->off[i].kptr.btf_id = id;
+ tab->off[i].kptr.btf = kernel_btf;
+ }
+diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
+index 315053ef6a75..3e709fed5306 100644
+--- a/kernel/bpf/helpers.c
++++ b/kernel/bpf/helpers.c
+@@ -1374,6 +1374,28 @@ void bpf_timer_cancel_and_free(void *val)
+ kfree(t);
+ }
+
++BPF_CALL_2(bpf_kptr_xchg, void *, map_value, void *, ptr)
++{
++ unsigned long *kptr = map_value;
++
++ return xchg(kptr, (unsigned long)ptr);
++}
++
++/* Unlike other PTR_TO_BTF_ID helpers the btf_id in bpf_kptr_xchg()
++ * helper is determined dynamically by the verifier.
++ */
++#define BPF_PTR_POISON ((void *)((0xeB9FUL << 2) + POISON_POINTER_DELTA))
++
++const struct bpf_func_proto bpf_kptr_xchg_proto = {
++ .func = bpf_kptr_xchg,
++ .gpl_only = false,
++ .ret_type = RET_PTR_TO_BTF_ID_OR_NULL,
++ .ret_btf_id = BPF_PTR_POISON,
++ .arg1_type = ARG_PTR_TO_KPTR,
++ .arg2_type = ARG_PTR_TO_BTF_ID_OR_NULL | OBJ_RELEASE,
++ .arg2_btf_id = BPF_PTR_POISON,
++};
++
+ const struct bpf_func_proto bpf_get_current_task_proto __weak;
+ const struct bpf_func_proto bpf_get_current_task_btf_proto __weak;
+ const struct bpf_func_proto bpf_probe_read_user_proto __weak;
+@@ -1452,6 +1474,8 @@ bpf_base_func_proto(enum bpf_func_id func_id)
+ return &bpf_timer_start_proto;
+ case BPF_FUNC_timer_cancel:
+ return &bpf_timer_cancel_proto;
++ case BPF_FUNC_kptr_xchg:
++ return &bpf_kptr_xchg_proto;
+ default:
+ break;
+ }
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 4f19a86c2682..93c98f95901e 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -258,6 +258,7 @@ struct bpf_call_arg_meta {
+ struct btf *ret_btf;
+ u32 ret_btf_id;
+ u32 subprogno;
++ struct bpf_map_value_off_desc *kptr_off_desc;
+ };
+
+ struct btf *btf_vmlinux;
+@@ -489,7 +490,8 @@ static bool is_acquire_function(enum bpf_func_id func_id,
+ if (func_id == BPF_FUNC_sk_lookup_tcp ||
+ func_id == BPF_FUNC_sk_lookup_udp ||
+ func_id == BPF_FUNC_skc_lookup_tcp ||
+- func_id == BPF_FUNC_ringbuf_reserve)
++ func_id == BPF_FUNC_ringbuf_reserve ||
++ func_id == BPF_FUNC_kptr_xchg)
+ return true;
+
+ if (func_id == BPF_FUNC_map_lookup_elem &&
+@@ -3513,6 +3515,12 @@ static int map_kptr_match_type(struct bpf_verifier_env *env,
+ /* We need to verify reg->type and reg->btf, before accessing reg->btf */
+ reg_name = kernel_type_name(reg->btf, reg->btf_id);
+
++ /* For ref_ptr case, release function check should ensure we get one
++ * referenced PTR_TO_BTF_ID, and that its fixed offset is 0. For the
++ * normal store of unreferenced kptr, we must ensure var_off is zero.
++ * Since ref_ptr cannot be accessed directly by BPF insns, checks for
++ * reg->off and reg->ref_obj_id are not needed here.
++ */
+ if (__check_ptr_off_reg(env, reg, regno, true))
+ return -EACCES;
+
+@@ -3568,6 +3576,12 @@ static int check_map_kptr_access(struct bpf_verifier_env *env, u32 regno,
+ return -EACCES;
+ }
+
++ /* We cannot directly access kptr_ref */
++ if (off_desc->type == BPF_KPTR_REF) {
++ verbose(env, "accessing referenced kptr disallowed\n");
++ return -EACCES;
++ }
++
+ if (class == BPF_LDX) {
+ val_reg = reg_state(env, value_regno);
+ /* We can simply mark the value_regno receiving the pointer
+@@ -5292,6 +5306,53 @@ static int process_timer_func(struct bpf_verifier_env *env, int regno,
+ return 0;
+ }
+
++static int process_kptr_func(struct bpf_verifier_env *env, int regno,
++ struct bpf_call_arg_meta *meta)
++{
++ struct bpf_reg_state *regs = cur_regs(env), *reg = ®s[regno];
++ struct bpf_map_value_off_desc *off_desc;
++ struct bpf_map *map_ptr = reg->map_ptr;
++ u32 kptr_off;
++ int ret;
++
++ if (!tnum_is_const(reg->var_off)) {
++ verbose(env,
++ "R%d doesn't have constant offset. kptr has to be at the constant offset\n",
++ regno);
++ return -EINVAL;
++ }
++ if (!map_ptr->btf) {
++ verbose(env, "map '%s' has to have BTF in order to use bpf_kptr_xchg\n",
++ map_ptr->name);
++ return -EINVAL;
++ }
++ if (!map_value_has_kptrs(map_ptr)) {
++ ret = PTR_ERR(map_ptr->kptr_off_tab);
++ if (ret == -E2BIG)
++ verbose(env, "map '%s' has more than %d kptr\n", map_ptr->name,
++ BPF_MAP_VALUE_OFF_MAX);
++ else if (ret == -EEXIST)
++ verbose(env, "map '%s' has repeating kptr BTF tags\n", map_ptr->name);
++ else
++ verbose(env, "map '%s' has no valid kptr\n", map_ptr->name);
++ return -EINVAL;
++ }
++
++ meta->map_ptr = map_ptr;
++ kptr_off = reg->off + reg->var_off.value;
++ off_desc = bpf_map_kptr_off_contains(map_ptr, kptr_off);
++ if (!off_desc) {
++ verbose(env, "off=%d doesn't point to kptr\n", kptr_off);
++ return -EACCES;
++ }
++ if (off_desc->type != BPF_KPTR_REF) {
++ verbose(env, "off=%d kptr isn't referenced kptr\n", kptr_off);
++ return -EACCES;
++ }
++ meta->kptr_off_desc = off_desc;
++ return 0;
++}
++
+ static bool arg_type_is_mem_ptr(enum bpf_arg_type type)
+ {
+ return base_type(type) == ARG_PTR_TO_MEM ||
+@@ -5432,6 +5493,7 @@ static const struct bpf_reg_types func_ptr_types = { .types = { PTR_TO_FUNC } };
+ static const struct bpf_reg_types stack_ptr_types = { .types = { PTR_TO_STACK } };
+ static const struct bpf_reg_types const_str_ptr_types = { .types = { PTR_TO_MAP_VALUE } };
+ static const struct bpf_reg_types timer_types = { .types = { PTR_TO_MAP_VALUE } };
++static const struct bpf_reg_types kptr_types = { .types = { PTR_TO_MAP_VALUE } };
+
+ static const struct bpf_reg_types *compatible_reg_types[__BPF_ARG_TYPE_MAX] = {
+ [ARG_PTR_TO_MAP_KEY] = &map_key_value_types,
+@@ -5459,11 +5521,13 @@ static const struct bpf_reg_types *compatible_reg_types[__BPF_ARG_TYPE_MAX] = {
+ [ARG_PTR_TO_STACK] = &stack_ptr_types,
+ [ARG_PTR_TO_CONST_STR] = &const_str_ptr_types,
+ [ARG_PTR_TO_TIMER] = &timer_types,
++ [ARG_PTR_TO_KPTR] = &kptr_types,
+ };
+
+ static int check_reg_type(struct bpf_verifier_env *env, u32 regno,
+ enum bpf_arg_type arg_type,
+- const u32 *arg_btf_id)
++ const u32 *arg_btf_id,
++ struct bpf_call_arg_meta *meta)
+ {
+ struct bpf_reg_state *regs = cur_regs(env), *reg = ®s[regno];
+ enum bpf_reg_type expected, type = reg->type;
+@@ -5516,8 +5580,11 @@ static int check_reg_type(struct bpf_verifier_env *env, u32 regno,
+ arg_btf_id = compatible->btf_id;
+ }
+
+- if (!btf_struct_ids_match(&env->log, reg->btf, reg->btf_id, reg->off,
+- btf_vmlinux, *arg_btf_id)) {
++ if (meta->func_id == BPF_FUNC_kptr_xchg) {
++ if (map_kptr_match_type(env, meta->kptr_off_desc, reg, regno))
++ return -EACCES;
++ } else if (!btf_struct_ids_match(&env->log, reg->btf, reg->btf_id, reg->off,
++ btf_vmlinux, *arg_btf_id)) {
+ verbose(env, "R%d is of type %s but %s is expected\n",
+ regno, kernel_type_name(reg->btf, reg->btf_id),
+ kernel_type_name(btf_vmlinux, *arg_btf_id));
+@@ -5624,7 +5691,7 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
+ */
+ goto skip_type_check;
+
+- err = check_reg_type(env, regno, arg_type, fn->arg_btf_id[arg]);
++ err = check_reg_type(env, regno, arg_type, fn->arg_btf_id[arg], meta);
+ if (err)
+ return err;
+
+@@ -5800,6 +5867,9 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
+ verbose(env, "string is not zero-terminated\n");
+ return -EINVAL;
+ }
++ } else if (arg_type == ARG_PTR_TO_KPTR) {
++ if (process_kptr_func(env, regno, meta))
++ return -EACCES;
+ }
+
+ return err;
+@@ -6143,10 +6213,10 @@ static bool check_btf_id_ok(const struct bpf_func_proto *fn)
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(fn->arg_type); i++) {
+- if (fn->arg_type[i] == ARG_PTR_TO_BTF_ID && !fn->arg_btf_id[i])
++ if (base_type(fn->arg_type[i]) == ARG_PTR_TO_BTF_ID && !fn->arg_btf_id[i])
+ return false;
+
+- if (fn->arg_type[i] != ARG_PTR_TO_BTF_ID && fn->arg_btf_id[i])
++ if (base_type(fn->arg_type[i]) != ARG_PTR_TO_BTF_ID && fn->arg_btf_id[i])
+ return false;
+ }
+
+@@ -7010,21 +7080,25 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ regs[BPF_REG_0].btf_id = meta.ret_btf_id;
+ }
+ } else if (base_type(ret_type) == RET_PTR_TO_BTF_ID) {
++ struct btf *ret_btf;
+ int ret_btf_id;
+
+ mark_reg_known_zero(env, regs, BPF_REG_0);
+ regs[BPF_REG_0].type = PTR_TO_BTF_ID | ret_flag;
+- ret_btf_id = *fn->ret_btf_id;
++ if (func_id == BPF_FUNC_kptr_xchg) {
++ ret_btf = meta.kptr_off_desc->kptr.btf;
++ ret_btf_id = meta.kptr_off_desc->kptr.btf_id;
++ } else {
++ ret_btf = btf_vmlinux;
++ ret_btf_id = *fn->ret_btf_id;
++ }
+ if (ret_btf_id == 0) {
+ verbose(env, "invalid return type %u of func %s#%d\n",
+ base_type(ret_type), func_id_name(func_id),
+ func_id);
+ return -EINVAL;
+ }
+- /* current BPF helper definitions are only coming from
+- * built-in code with type IDs from vmlinux BTF
+- */
+- regs[BPF_REG_0].btf = btf_vmlinux;
++ regs[BPF_REG_0].btf = ret_btf;
+ regs[BPF_REG_0].btf_id = ret_btf_id;
+ } else {
+ verbose(env, "unknown return type %u of func %s#%d\n",
+diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
+index a4f557338af7..ff9af73859ca 100644
+--- a/tools/include/uapi/linux/bpf.h
++++ b/tools/include/uapi/linux/bpf.h
+@@ -5144,6 +5144,17 @@ union bpf_attr {
+ * The **hash_algo** is returned on success,
+ * **-EOPNOTSUP** if the hash calculation failed or **-EINVAL** if
+ * invalid arguments are passed.
++ *
++ * void *bpf_kptr_xchg(void *map_value, void *ptr)
++ * Description
++ * Exchange kptr at pointer *map_value* with *ptr*, and return the
++ * old value. *ptr* can be NULL, otherwise it must be a referenced
++ * pointer which will be released when this helper is called.
++ * Return
++ * The old value of kptr (which can be NULL). The returned pointer
++ * if not NULL, is a reference which must be released using its
++ * corresponding release function, or moved into a BPF map before
++ * program exit.
+ */
+ #define __BPF_FUNC_MAPPER(FN) \
+ FN(unspec), \
+@@ -5340,6 +5351,7 @@ union bpf_attr {
+ FN(copy_from_user_task), \
+ FN(skb_set_tstamp), \
+ FN(ima_file_hash), \
++ FN(kptr_xchg), \
+ /* */
+
+ /* integer value in 'imm' field of BPF_CALL instruction selects which helper
+--
+2.35.1
+
--- /dev/null
+From 029783c36d8e245c2b32969a67f455728e54b382 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Apr 2022 03:18:49 +0530
+Subject: bpf: Allow storing unreferenced kptr in map
+
+From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+
+[ Upstream commit 61df10c7799e27807ad5e459eec9d77cddf8bf45 ]
+
+This commit introduces a new pointer type 'kptr' which can be embedded
+in a map value to hold a PTR_TO_BTF_ID stored by a BPF program during
+its invocation. When storing such a kptr, BPF program's PTR_TO_BTF_ID
+register must have the same type as in the map value's BTF, and loading
+a kptr marks the destination register as PTR_TO_BTF_ID with the correct
+kernel BTF and BTF ID.
+
+Such kptr are unreferenced, i.e. by the time another invocation of the
+BPF program loads this pointer, the object which the pointer points to
+may not longer exist. Since PTR_TO_BTF_ID loads (using BPF_LDX) are
+patched to PROBE_MEM loads by the verifier, it would safe to allow user
+to still access such invalid pointer, but passing such pointers into
+BPF helpers and kfuncs should not be permitted. A future patch in this
+series will close this gap.
+
+The flexibility offered by allowing programs to dereference such invalid
+pointers while being safe at runtime frees the verifier from doing
+complex lifetime tracking. As long as the user may ensure that the
+object remains valid, it can ensure data read by it from the kernel
+object is valid.
+
+The user indicates that a certain pointer must be treated as kptr
+capable of accepting stores of PTR_TO_BTF_ID of a certain type, by using
+a BTF type tag 'kptr' on the pointed to type of the pointer. Then, this
+information is recorded in the object BTF which will be passed into the
+kernel by way of map's BTF information. The name and kind from the map
+value BTF is used to look up the in-kernel type, and the actual BTF and
+BTF ID is recorded in the map struct in a new kptr_off_tab member. For
+now, only storing pointers to structs is permitted.
+
+An example of this specification is shown below:
+
+ #define __kptr __attribute__((btf_type_tag("kptr")))
+
+ struct map_value {
+ ...
+ struct task_struct __kptr *task;
+ ...
+ };
+
+Then, in a BPF program, user may store PTR_TO_BTF_ID with the type
+task_struct into the map, and then load it later.
+
+Note that the destination register is marked PTR_TO_BTF_ID_OR_NULL, as
+the verifier cannot know whether the value is NULL or not statically, it
+must treat all potential loads at that map value offset as loading a
+possibly NULL pointer.
+
+Only BPF_LDX, BPF_STX, and BPF_ST (with insn->imm = 0 to denote NULL)
+are allowed instructions that can access such a pointer. On BPF_LDX, the
+destination register is updated to be a PTR_TO_BTF_ID, and on BPF_STX,
+it is checked whether the source register type is a PTR_TO_BTF_ID with
+same BTF type as specified in the map BTF. The access size must always
+be BPF_DW.
+
+For the map in map support, the kptr_off_tab for outer map is copied
+from the inner map's kptr_off_tab. It was chosen to do a deep copy
+instead of introducing a refcount to kptr_off_tab, because the copy only
+needs to be done when paramterizing using inner_map_fd in the map in map
+case, hence would be unnecessary for all other users.
+
+It is not permitted to use MAP_FREEZE command and mmap for BPF map
+having kptrs, similar to the bpf_timer case. A kptr also requires that
+BPF program has both read and write access to the map (hence both
+BPF_F_RDONLY_PROG and BPF_F_WRONLY_PROG are disallowed).
+
+Note that check_map_access must be called from both
+check_helper_mem_access and for the BPF instructions, hence the kptr
+check must distinguish between ACCESS_DIRECT and ACCESS_HELPER, and
+reject ACCESS_HELPER cases. We rename stack_access_src to bpf_access_src
+and reuse it for this purpose.
+
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20220424214901.2743946-2-memxor@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/bpf.h | 31 +++++++-
+ include/linux/btf.h | 2 +
+ kernel/bpf/btf.c | 167 +++++++++++++++++++++++++++++++++++-----
+ kernel/bpf/map_in_map.c | 5 +-
+ kernel/bpf/syscall.c | 103 ++++++++++++++++++++++++-
+ kernel/bpf/verifier.c | 161 +++++++++++++++++++++++++++++++++++---
+ 6 files changed, 433 insertions(+), 36 deletions(-)
+
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 492e114b4e32..00d55c10d876 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -155,6 +155,24 @@ struct bpf_map_ops {
+ const struct bpf_iter_seq_info *iter_seq_info;
+ };
+
++enum {
++ /* Support at most 8 pointers in a BPF map value */
++ BPF_MAP_VALUE_OFF_MAX = 8,
++};
++
++struct bpf_map_value_off_desc {
++ u32 offset;
++ struct {
++ struct btf *btf;
++ u32 btf_id;
++ } kptr;
++};
++
++struct bpf_map_value_off {
++ u32 nr_off;
++ struct bpf_map_value_off_desc off[];
++};
++
+ struct bpf_map {
+ /* The first two cachelines with read-mostly members of which some
+ * are also accessed in fast-path (e.g. ops, max_entries).
+@@ -171,6 +189,7 @@ struct bpf_map {
+ u64 map_extra; /* any per-map-type extra fields */
+ u32 map_flags;
+ int spin_lock_off; /* >=0 valid offset, <0 error */
++ struct bpf_map_value_off *kptr_off_tab;
+ int timer_off; /* >=0 valid offset, <0 error */
+ u32 id;
+ int numa_node;
+@@ -184,7 +203,7 @@ struct bpf_map {
+ char name[BPF_OBJ_NAME_LEN];
+ bool bypass_spec_v1;
+ bool frozen; /* write-once; write-protected by freeze_mutex */
+- /* 14 bytes hole */
++ /* 6 bytes hole */
+
+ /* The 3rd and 4th cacheline with misc members to avoid false sharing
+ * particularly with refcounting.
+@@ -217,6 +236,11 @@ static inline bool map_value_has_timer(const struct bpf_map *map)
+ return map->timer_off >= 0;
+ }
+
++static inline bool map_value_has_kptrs(const struct bpf_map *map)
++{
++ return !IS_ERR_OR_NULL(map->kptr_off_tab);
++}
++
+ static inline void check_and_init_map_value(struct bpf_map *map, void *dst)
+ {
+ if (unlikely(map_value_has_spin_lock(map)))
+@@ -1407,6 +1431,11 @@ void bpf_prog_put(struct bpf_prog *prog);
+ void bpf_prog_free_id(struct bpf_prog *prog, bool do_idr_lock);
+ void bpf_map_free_id(struct bpf_map *map, bool do_idr_lock);
+
++struct bpf_map_value_off_desc *bpf_map_kptr_off_contains(struct bpf_map *map, u32 offset);
++void bpf_map_free_kptr_off_tab(struct bpf_map *map);
++struct bpf_map_value_off *bpf_map_copy_kptr_off_tab(const struct bpf_map *map);
++bool bpf_map_equal_kptr_off_tab(const struct bpf_map *map_a, const struct bpf_map *map_b);
++
+ struct bpf_map *bpf_map_get(u32 ufd);
+ struct bpf_map *bpf_map_get_with_uref(u32 ufd);
+ struct bpf_map *__bpf_map_get(struct fd f);
+diff --git a/include/linux/btf.h b/include/linux/btf.h
+index 36bc09b8e890..19c297f9a52f 100644
+--- a/include/linux/btf.h
++++ b/include/linux/btf.h
+@@ -123,6 +123,8 @@ bool btf_member_is_reg_int(const struct btf *btf, const struct btf_type *s,
+ u32 expected_offset, u32 expected_size);
+ int btf_find_spin_lock(const struct btf *btf, const struct btf_type *t);
+ int btf_find_timer(const struct btf *btf, const struct btf_type *t);
++struct bpf_map_value_off *btf_parse_kptrs(const struct btf *btf,
++ const struct btf_type *t);
+ bool btf_type_is_void(const struct btf_type *t);
+ s32 btf_find_by_name_kind(const struct btf *btf, const char *name, u8 kind);
+ const struct btf_type *btf_type_skip_modifiers(const struct btf *btf,
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 1fd8400bda06..cbb48eb8c009 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -3166,9 +3166,16 @@ static void btf_struct_log(struct btf_verifier_env *env,
+ enum btf_field_type {
+ BTF_FIELD_SPIN_LOCK,
+ BTF_FIELD_TIMER,
++ BTF_FIELD_KPTR,
++};
++
++enum {
++ BTF_FIELD_IGNORE = 0,
++ BTF_FIELD_FOUND = 1,
+ };
+
+ struct btf_field_info {
++ u32 type_id;
+ u32 off;
+ };
+
+@@ -3176,29 +3183,57 @@ static int btf_find_struct(const struct btf *btf, const struct btf_type *t,
+ u32 off, int sz, struct btf_field_info *info)
+ {
+ if (!__btf_type_is_struct(t))
+- return 0;
++ return BTF_FIELD_IGNORE;
+ if (t->size != sz)
+- return 0;
+- if (info->off != -ENOENT)
+- /* only one such field is allowed */
+- return -E2BIG;
++ return BTF_FIELD_IGNORE;
+ info->off = off;
+- return 0;
++ return BTF_FIELD_FOUND;
++}
++
++static int btf_find_kptr(const struct btf *btf, const struct btf_type *t,
++ u32 off, int sz, struct btf_field_info *info)
++{
++ u32 res_id;
++
++ /* For PTR, sz is always == 8 */
++ if (!btf_type_is_ptr(t))
++ return BTF_FIELD_IGNORE;
++ t = btf_type_by_id(btf, t->type);
++
++ if (!btf_type_is_type_tag(t))
++ return BTF_FIELD_IGNORE;
++ /* Reject extra tags */
++ if (btf_type_is_type_tag(btf_type_by_id(btf, t->type)))
++ return -EINVAL;
++ if (strcmp("kptr", __btf_name_by_offset(btf, t->name_off)))
++ return -EINVAL;
++
++ /* Get the base type */
++ t = btf_type_skip_modifiers(btf, t->type, &res_id);
++ /* Only pointer to struct is allowed */
++ if (!__btf_type_is_struct(t))
++ return -EINVAL;
++
++ info->type_id = res_id;
++ info->off = off;
++ return BTF_FIELD_FOUND;
+ }
+
+ static int btf_find_struct_field(const struct btf *btf, const struct btf_type *t,
+ const char *name, int sz, int align,
+ enum btf_field_type field_type,
+- struct btf_field_info *info)
++ struct btf_field_info *info, int info_cnt)
+ {
+ const struct btf_member *member;
++ struct btf_field_info tmp;
++ int ret, idx = 0;
+ u32 i, off;
+
+ for_each_member(i, t, member) {
+ const struct btf_type *member_type = btf_type_by_id(btf,
+ member->type);
+
+- if (strcmp(__btf_name_by_offset(btf, member_type->name_off), name))
++ if (name && strcmp(__btf_name_by_offset(btf, member_type->name_off), name))
+ continue;
+
+ off = __btf_member_bit_offset(t, member);
+@@ -3212,20 +3247,38 @@ static int btf_find_struct_field(const struct btf *btf, const struct btf_type *t
+ switch (field_type) {
+ case BTF_FIELD_SPIN_LOCK:
+ case BTF_FIELD_TIMER:
+- return btf_find_struct(btf, member_type, off, sz, info);
++ ret = btf_find_struct(btf, member_type, off, sz,
++ idx < info_cnt ? &info[idx] : &tmp);
++ if (ret < 0)
++ return ret;
++ break;
++ case BTF_FIELD_KPTR:
++ ret = btf_find_kptr(btf, member_type, off, sz,
++ idx < info_cnt ? &info[idx] : &tmp);
++ if (ret < 0)
++ return ret;
++ break;
+ default:
+ return -EFAULT;
+ }
++
++ if (ret == BTF_FIELD_IGNORE)
++ continue;
++ if (idx >= info_cnt)
++ return -E2BIG;
++ ++idx;
+ }
+- return 0;
++ return idx;
+ }
+
+ static int btf_find_datasec_var(const struct btf *btf, const struct btf_type *t,
+ const char *name, int sz, int align,
+ enum btf_field_type field_type,
+- struct btf_field_info *info)
++ struct btf_field_info *info, int info_cnt)
+ {
+ const struct btf_var_secinfo *vsi;
++ struct btf_field_info tmp;
++ int ret, idx = 0;
+ u32 i, off;
+
+ for_each_vsi(i, t, vsi) {
+@@ -3234,7 +3287,7 @@ static int btf_find_datasec_var(const struct btf *btf, const struct btf_type *t,
+
+ off = vsi->offset;
+
+- if (strcmp(__btf_name_by_offset(btf, var_type->name_off), name))
++ if (name && strcmp(__btf_name_by_offset(btf, var_type->name_off), name))
+ continue;
+ if (vsi->size != sz)
+ continue;
+@@ -3244,17 +3297,33 @@ static int btf_find_datasec_var(const struct btf *btf, const struct btf_type *t,
+ switch (field_type) {
+ case BTF_FIELD_SPIN_LOCK:
+ case BTF_FIELD_TIMER:
+- return btf_find_struct(btf, var_type, off, sz, info);
++ ret = btf_find_struct(btf, var_type, off, sz,
++ idx < info_cnt ? &info[idx] : &tmp);
++ if (ret < 0)
++ return ret;
++ break;
++ case BTF_FIELD_KPTR:
++ ret = btf_find_kptr(btf, var_type, off, sz,
++ idx < info_cnt ? &info[idx] : &tmp);
++ if (ret < 0)
++ return ret;
++ break;
+ default:
+ return -EFAULT;
+ }
++
++ if (ret == BTF_FIELD_IGNORE)
++ continue;
++ if (idx >= info_cnt)
++ return -E2BIG;
++ ++idx;
+ }
+- return 0;
++ return idx;
+ }
+
+ static int btf_find_field(const struct btf *btf, const struct btf_type *t,
+ enum btf_field_type field_type,
+- struct btf_field_info *info)
++ struct btf_field_info *info, int info_cnt)
+ {
+ const char *name;
+ int sz, align;
+@@ -3270,14 +3339,19 @@ static int btf_find_field(const struct btf *btf, const struct btf_type *t,
+ sz = sizeof(struct bpf_timer);
+ align = __alignof__(struct bpf_timer);
+ break;
++ case BTF_FIELD_KPTR:
++ name = NULL;
++ sz = sizeof(u64);
++ align = 8;
++ break;
+ default:
+ return -EFAULT;
+ }
+
+ if (__btf_type_is_struct(t))
+- return btf_find_struct_field(btf, t, name, sz, align, field_type, info);
++ return btf_find_struct_field(btf, t, name, sz, align, field_type, info, info_cnt);
+ else if (btf_type_is_datasec(t))
+- return btf_find_datasec_var(btf, t, name, sz, align, field_type, info);
++ return btf_find_datasec_var(btf, t, name, sz, align, field_type, info, info_cnt);
+ return -EINVAL;
+ }
+
+@@ -3287,26 +3361,77 @@ static int btf_find_field(const struct btf *btf, const struct btf_type *t,
+ */
+ int btf_find_spin_lock(const struct btf *btf, const struct btf_type *t)
+ {
+- struct btf_field_info info = { .off = -ENOENT };
++ struct btf_field_info info;
+ int ret;
+
+- ret = btf_find_field(btf, t, BTF_FIELD_SPIN_LOCK, &info);
++ ret = btf_find_field(btf, t, BTF_FIELD_SPIN_LOCK, &info, 1);
+ if (ret < 0)
+ return ret;
++ if (!ret)
++ return -ENOENT;
+ return info.off;
+ }
+
+ int btf_find_timer(const struct btf *btf, const struct btf_type *t)
+ {
+- struct btf_field_info info = { .off = -ENOENT };
++ struct btf_field_info info;
+ int ret;
+
+- ret = btf_find_field(btf, t, BTF_FIELD_TIMER, &info);
++ ret = btf_find_field(btf, t, BTF_FIELD_TIMER, &info, 1);
+ if (ret < 0)
+ return ret;
++ if (!ret)
++ return -ENOENT;
+ return info.off;
+ }
+
++struct bpf_map_value_off *btf_parse_kptrs(const struct btf *btf,
++ const struct btf_type *t)
++{
++ struct btf_field_info info_arr[BPF_MAP_VALUE_OFF_MAX];
++ struct bpf_map_value_off *tab;
++ struct btf *kernel_btf = NULL;
++ int ret, i, nr_off;
++
++ ret = btf_find_field(btf, t, BTF_FIELD_KPTR, info_arr, ARRAY_SIZE(info_arr));
++ if (ret < 0)
++ return ERR_PTR(ret);
++ if (!ret)
++ return NULL;
++
++ nr_off = ret;
++ tab = kzalloc(offsetof(struct bpf_map_value_off, off[nr_off]), GFP_KERNEL | __GFP_NOWARN);
++ if (!tab)
++ return ERR_PTR(-ENOMEM);
++
++ for (i = 0; i < nr_off; i++) {
++ const struct btf_type *t;
++ s32 id;
++
++ /* Find type in map BTF, and use it to look up the matching type
++ * in vmlinux or module BTFs, by name and kind.
++ */
++ t = btf_type_by_id(btf, info_arr[i].type_id);
++ id = bpf_find_btf_id(__btf_name_by_offset(btf, t->name_off), BTF_INFO_KIND(t->info),
++ &kernel_btf);
++ if (id < 0) {
++ ret = id;
++ goto end;
++ }
++
++ tab->off[i].offset = info_arr[i].off;
++ tab->off[i].kptr.btf_id = id;
++ tab->off[i].kptr.btf = kernel_btf;
++ }
++ tab->nr_off = nr_off;
++ return tab;
++end:
++ while (i--)
++ btf_put(tab->off[i].kptr.btf);
++ kfree(tab);
++ return ERR_PTR(ret);
++}
++
+ static void __btf_struct_show(const struct btf *btf, const struct btf_type *t,
+ u32 type_id, void *data, u8 bits_offset,
+ struct btf_show *show)
+diff --git a/kernel/bpf/map_in_map.c b/kernel/bpf/map_in_map.c
+index 5cd8f5277279..135205d0d560 100644
+--- a/kernel/bpf/map_in_map.c
++++ b/kernel/bpf/map_in_map.c
+@@ -52,6 +52,7 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd)
+ inner_map_meta->max_entries = inner_map->max_entries;
+ inner_map_meta->spin_lock_off = inner_map->spin_lock_off;
+ inner_map_meta->timer_off = inner_map->timer_off;
++ inner_map_meta->kptr_off_tab = bpf_map_copy_kptr_off_tab(inner_map);
+ if (inner_map->btf) {
+ btf_get(inner_map->btf);
+ inner_map_meta->btf = inner_map->btf;
+@@ -71,6 +72,7 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd)
+
+ void bpf_map_meta_free(struct bpf_map *map_meta)
+ {
++ bpf_map_free_kptr_off_tab(map_meta);
+ btf_put(map_meta->btf);
+ kfree(map_meta);
+ }
+@@ -83,7 +85,8 @@ bool bpf_map_meta_equal(const struct bpf_map *meta0,
+ meta0->key_size == meta1->key_size &&
+ meta0->value_size == meta1->value_size &&
+ meta0->timer_off == meta1->timer_off &&
+- meta0->map_flags == meta1->map_flags;
++ meta0->map_flags == meta1->map_flags &&
++ bpf_map_equal_kptr_off_tab(meta0, meta1);
+ }
+
+ void *bpf_map_fd_get_ptr(struct bpf_map *map,
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index 3078c0c9317f..dc49bd880ac0 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -6,6 +6,7 @@
+ #include <linux/bpf_trace.h>
+ #include <linux/bpf_lirc.h>
+ #include <linux/bpf_verifier.h>
++#include <linux/bsearch.h>
+ #include <linux/btf.h>
+ #include <linux/syscalls.h>
+ #include <linux/slab.h>
+@@ -473,12 +474,84 @@ static void bpf_map_release_memcg(struct bpf_map *map)
+ }
+ #endif
+
++static int bpf_map_kptr_off_cmp(const void *a, const void *b)
++{
++ const struct bpf_map_value_off_desc *off_desc1 = a, *off_desc2 = b;
++
++ if (off_desc1->offset < off_desc2->offset)
++ return -1;
++ else if (off_desc1->offset > off_desc2->offset)
++ return 1;
++ return 0;
++}
++
++struct bpf_map_value_off_desc *bpf_map_kptr_off_contains(struct bpf_map *map, u32 offset)
++{
++ /* Since members are iterated in btf_find_field in increasing order,
++ * offsets appended to kptr_off_tab are in increasing order, so we can
++ * do bsearch to find exact match.
++ */
++ struct bpf_map_value_off *tab;
++
++ if (!map_value_has_kptrs(map))
++ return NULL;
++ tab = map->kptr_off_tab;
++ return bsearch(&offset, tab->off, tab->nr_off, sizeof(tab->off[0]), bpf_map_kptr_off_cmp);
++}
++
++void bpf_map_free_kptr_off_tab(struct bpf_map *map)
++{
++ struct bpf_map_value_off *tab = map->kptr_off_tab;
++ int i;
++
++ if (!map_value_has_kptrs(map))
++ return;
++ for (i = 0; i < tab->nr_off; i++)
++ btf_put(tab->off[i].kptr.btf);
++ kfree(tab);
++ map->kptr_off_tab = NULL;
++}
++
++struct bpf_map_value_off *bpf_map_copy_kptr_off_tab(const struct bpf_map *map)
++{
++ struct bpf_map_value_off *tab = map->kptr_off_tab, *new_tab;
++ int size, i;
++
++ if (!map_value_has_kptrs(map))
++ return ERR_PTR(-ENOENT);
++ size = offsetof(struct bpf_map_value_off, off[tab->nr_off]);
++ new_tab = kmemdup(tab, size, GFP_KERNEL | __GFP_NOWARN);
++ if (!new_tab)
++ return ERR_PTR(-ENOMEM);
++ /* Do a deep copy of the kptr_off_tab */
++ for (i = 0; i < tab->nr_off; i++)
++ btf_get(tab->off[i].kptr.btf);
++ return new_tab;
++}
++
++bool bpf_map_equal_kptr_off_tab(const struct bpf_map *map_a, const struct bpf_map *map_b)
++{
++ struct bpf_map_value_off *tab_a = map_a->kptr_off_tab, *tab_b = map_b->kptr_off_tab;
++ bool a_has_kptr = map_value_has_kptrs(map_a), b_has_kptr = map_value_has_kptrs(map_b);
++ int size;
++
++ if (!a_has_kptr && !b_has_kptr)
++ return true;
++ if (a_has_kptr != b_has_kptr)
++ return false;
++ if (tab_a->nr_off != tab_b->nr_off)
++ return false;
++ size = offsetof(struct bpf_map_value_off, off[tab_a->nr_off]);
++ return !memcmp(tab_a, tab_b, size);
++}
++
+ /* called from workqueue */
+ static void bpf_map_free_deferred(struct work_struct *work)
+ {
+ struct bpf_map *map = container_of(work, struct bpf_map, work);
+
+ security_bpf_map_free(map);
++ bpf_map_free_kptr_off_tab(map);
+ bpf_map_release_memcg(map);
+ /* implementation dependent freeing */
+ map->ops->map_free(map);
+@@ -640,7 +713,7 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)
+ int err;
+
+ if (!map->ops->map_mmap || map_value_has_spin_lock(map) ||
+- map_value_has_timer(map))
++ map_value_has_timer(map) || map_value_has_kptrs(map))
+ return -ENOTSUPP;
+
+ if (!(vma->vm_flags & VM_SHARED))
+@@ -820,9 +893,33 @@ static int map_check_btf(struct bpf_map *map, const struct btf *btf,
+ return -EOPNOTSUPP;
+ }
+
+- if (map->ops->map_check_btf)
++ map->kptr_off_tab = btf_parse_kptrs(btf, value_type);
++ if (map_value_has_kptrs(map)) {
++ if (!bpf_capable()) {
++ ret = -EPERM;
++ goto free_map_tab;
++ }
++ if (map->map_flags & (BPF_F_RDONLY_PROG | BPF_F_WRONLY_PROG)) {
++ ret = -EACCES;
++ goto free_map_tab;
++ }
++ if (map->map_type != BPF_MAP_TYPE_HASH &&
++ map->map_type != BPF_MAP_TYPE_LRU_HASH &&
++ map->map_type != BPF_MAP_TYPE_ARRAY) {
++ ret = -EOPNOTSUPP;
++ goto free_map_tab;
++ }
++ }
++
++ if (map->ops->map_check_btf) {
+ ret = map->ops->map_check_btf(map, btf, key_type, value_type);
++ if (ret < 0)
++ goto free_map_tab;
++ }
+
++ return ret;
++free_map_tab:
++ bpf_map_free_kptr_off_tab(map);
+ return ret;
+ }
+
+@@ -1639,7 +1736,7 @@ static int map_freeze(const union bpf_attr *attr)
+ return PTR_ERR(map);
+
+ if (map->map_type == BPF_MAP_TYPE_STRUCT_OPS ||
+- map_value_has_timer(map)) {
++ map_value_has_timer(map) || map_value_has_kptrs(map)) {
+ fdput(f);
+ return -ENOTSUPP;
+ }
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index afa05e6cd78f..b8d1060153c8 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -3210,7 +3210,7 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
+ return 0;
+ }
+
+-enum stack_access_src {
++enum bpf_access_src {
+ ACCESS_DIRECT = 1, /* the access is performed by an instruction */
+ ACCESS_HELPER = 2, /* the access is performed by a helper */
+ };
+@@ -3218,7 +3218,7 @@ enum stack_access_src {
+ static int check_stack_range_initialized(struct bpf_verifier_env *env,
+ int regno, int off, int access_size,
+ bool zero_size_allowed,
+- enum stack_access_src type,
++ enum bpf_access_src type,
+ struct bpf_call_arg_meta *meta);
+
+ static struct bpf_reg_state *reg_state(struct bpf_verifier_env *env, int regno)
+@@ -3506,9 +3506,109 @@ int check_ptr_off_reg(struct bpf_verifier_env *env,
+ return __check_ptr_off_reg(env, reg, regno, false);
+ }
+
++static int map_kptr_match_type(struct bpf_verifier_env *env,
++ struct bpf_map_value_off_desc *off_desc,
++ struct bpf_reg_state *reg, u32 regno)
++{
++ const char *targ_name = kernel_type_name(off_desc->kptr.btf, off_desc->kptr.btf_id);
++ const char *reg_name = "";
++
++ if (base_type(reg->type) != PTR_TO_BTF_ID || type_flag(reg->type) != PTR_MAYBE_NULL)
++ goto bad_type;
++
++ if (!btf_is_kernel(reg->btf)) {
++ verbose(env, "R%d must point to kernel BTF\n", regno);
++ return -EINVAL;
++ }
++ /* We need to verify reg->type and reg->btf, before accessing reg->btf */
++ reg_name = kernel_type_name(reg->btf, reg->btf_id);
++
++ if (__check_ptr_off_reg(env, reg, regno, true))
++ return -EACCES;
++
++ /* A full type match is needed, as BTF can be vmlinux or module BTF, and
++ * we also need to take into account the reg->off.
++ *
++ * We want to support cases like:
++ *
++ * struct foo {
++ * struct bar br;
++ * struct baz bz;
++ * };
++ *
++ * struct foo *v;
++ * v = func(); // PTR_TO_BTF_ID
++ * val->foo = v; // reg->off is zero, btf and btf_id match type
++ * val->bar = &v->br; // reg->off is still zero, but we need to retry with
++ * // first member type of struct after comparison fails
++ * val->baz = &v->bz; // reg->off is non-zero, so struct needs to be walked
++ * // to match type
++ *
++ * In the kptr_ref case, check_func_arg_reg_off already ensures reg->off
++ * is zero.
++ */
++ if (!btf_struct_ids_match(&env->log, reg->btf, reg->btf_id, reg->off,
++ off_desc->kptr.btf, off_desc->kptr.btf_id))
++ goto bad_type;
++ return 0;
++bad_type:
++ verbose(env, "invalid kptr access, R%d type=%s%s ", regno,
++ reg_type_str(env, reg->type), reg_name);
++ verbose(env, "expected=%s%s\n", reg_type_str(env, PTR_TO_BTF_ID), targ_name);
++ return -EINVAL;
++}
++
++static int check_map_kptr_access(struct bpf_verifier_env *env, u32 regno,
++ int value_regno, int insn_idx,
++ struct bpf_map_value_off_desc *off_desc)
++{
++ struct bpf_insn *insn = &env->prog->insnsi[insn_idx];
++ int class = BPF_CLASS(insn->code);
++ struct bpf_reg_state *val_reg;
++
++ /* Things we already checked for in check_map_access and caller:
++ * - Reject cases where variable offset may touch kptr
++ * - size of access (must be BPF_DW)
++ * - tnum_is_const(reg->var_off)
++ * - off_desc->offset == off + reg->var_off.value
++ */
++ /* Only BPF_[LDX,STX,ST] | BPF_MEM | BPF_DW is supported */
++ if (BPF_MODE(insn->code) != BPF_MEM) {
++ verbose(env, "kptr in map can only be accessed using BPF_MEM instruction mode\n");
++ return -EACCES;
++ }
++
++ if (class == BPF_LDX) {
++ val_reg = reg_state(env, value_regno);
++ /* We can simply mark the value_regno receiving the pointer
++ * value from map as PTR_TO_BTF_ID, with the correct type.
++ */
++ mark_btf_ld_reg(env, cur_regs(env), value_regno, PTR_TO_BTF_ID, off_desc->kptr.btf,
++ off_desc->kptr.btf_id, PTR_MAYBE_NULL);
++ /* For mark_ptr_or_null_reg */
++ val_reg->id = ++env->id_gen;
++ } else if (class == BPF_STX) {
++ val_reg = reg_state(env, value_regno);
++ if (!register_is_null(val_reg) &&
++ map_kptr_match_type(env, off_desc, val_reg, value_regno))
++ return -EACCES;
++ } else if (class == BPF_ST) {
++ if (insn->imm) {
++ verbose(env, "BPF_ST imm must be 0 when storing to kptr at off=%u\n",
++ off_desc->offset);
++ return -EACCES;
++ }
++ } else {
++ verbose(env, "kptr in map can only be accessed using BPF_LDX/BPF_STX/BPF_ST\n");
++ return -EACCES;
++ }
++ return 0;
++}
++
+ /* check read/write into a map element with possible variable offset */
+ static int check_map_access(struct bpf_verifier_env *env, u32 regno,
+- int off, int size, bool zero_size_allowed)
++ int off, int size, bool zero_size_allowed,
++ enum bpf_access_src src)
+ {
+ struct bpf_verifier_state *vstate = env->cur_state;
+ struct bpf_func_state *state = vstate->frame[vstate->curframe];
+@@ -3544,6 +3644,36 @@ static int check_map_access(struct bpf_verifier_env *env, u32 regno,
+ return -EACCES;
+ }
+ }
++ if (map_value_has_kptrs(map)) {
++ struct bpf_map_value_off *tab = map->kptr_off_tab;
++ int i;
++
++ for (i = 0; i < tab->nr_off; i++) {
++ u32 p = tab->off[i].offset;
++
++ if (reg->smin_value + off < p + sizeof(u64) &&
++ p < reg->umax_value + off + size) {
++ if (src != ACCESS_DIRECT) {
++ verbose(env, "kptr cannot be accessed indirectly by helper\n");
++ return -EACCES;
++ }
++ if (!tnum_is_const(reg->var_off)) {
++ verbose(env, "kptr access cannot have variable offset\n");
++ return -EACCES;
++ }
++ if (p != off + reg->var_off.value) {
++ verbose(env, "kptr access misaligned expected=%u off=%llu\n",
++ p, off + reg->var_off.value);
++ return -EACCES;
++ }
++ if (size != bpf_size_to_bytes(BPF_DW)) {
++ verbose(env, "kptr access size must be BPF_DW\n");
++ return -EACCES;
++ }
++ break;
++ }
++ }
++ }
+ return err;
+ }
+
+@@ -4315,7 +4445,7 @@ static int check_stack_slot_within_bounds(int off,
+ static int check_stack_access_within_bounds(
+ struct bpf_verifier_env *env,
+ int regno, int off, int access_size,
+- enum stack_access_src src, enum bpf_access_type type)
++ enum bpf_access_src src, enum bpf_access_type type)
+ {
+ struct bpf_reg_state *regs = cur_regs(env);
+ struct bpf_reg_state *reg = regs + regno;
+@@ -4411,6 +4541,8 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
+ if (value_regno >= 0)
+ mark_reg_unknown(env, regs, value_regno);
+ } else if (reg->type == PTR_TO_MAP_VALUE) {
++ struct bpf_map_value_off_desc *kptr_off_desc = NULL;
++
+ if (t == BPF_WRITE && value_regno >= 0 &&
+ is_pointer_value(env, value_regno)) {
+ verbose(env, "R%d leaks addr into map\n", value_regno);
+@@ -4419,8 +4551,16 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
+ err = check_map_access_type(env, regno, off, size, t);
+ if (err)
+ return err;
+- err = check_map_access(env, regno, off, size, false);
+- if (!err && t == BPF_READ && value_regno >= 0) {
++ err = check_map_access(env, regno, off, size, false, ACCESS_DIRECT);
++ if (err)
++ return err;
++ if (tnum_is_const(reg->var_off))
++ kptr_off_desc = bpf_map_kptr_off_contains(reg->map_ptr,
++ off + reg->var_off.value);
++ if (kptr_off_desc) {
++ err = check_map_kptr_access(env, regno, value_regno, insn_idx,
++ kptr_off_desc);
++ } else if (t == BPF_READ && value_regno >= 0) {
+ struct bpf_map *map = reg->map_ptr;
+
+ /* if map is read-only, track its contents as scalars */
+@@ -4723,7 +4863,7 @@ static int check_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_i
+ static int check_stack_range_initialized(
+ struct bpf_verifier_env *env, int regno, int off,
+ int access_size, bool zero_size_allowed,
+- enum stack_access_src type, struct bpf_call_arg_meta *meta)
++ enum bpf_access_src type, struct bpf_call_arg_meta *meta)
+ {
+ struct bpf_reg_state *reg = reg_state(env, regno);
+ struct bpf_func_state *state = func(env, reg);
+@@ -4873,7 +5013,7 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
+ BPF_READ))
+ return -EACCES;
+ return check_map_access(env, regno, reg->off, access_size,
+- zero_size_allowed);
++ zero_size_allowed, ACCESS_HELPER);
+ case PTR_TO_MEM:
+ if (type_is_rdonly_mem(reg->type)) {
+ if (meta && meta->raw_mode) {
+@@ -5641,7 +5781,8 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
+ }
+
+ err = check_map_access(env, regno, reg->off,
+- map->value_size - reg->off, false);
++ map->value_size - reg->off, false,
++ ACCESS_HELPER);
+ if (err)
+ return err;
+
+@@ -7460,7 +7601,7 @@ static int sanitize_check_bounds(struct bpf_verifier_env *env,
+ return -EACCES;
+ break;
+ case PTR_TO_MAP_VALUE:
+- if (check_map_access(env, dst, dst_reg->off, 1, false)) {
++ if (check_map_access(env, dst, dst_reg->off, 1, false, ACCESS_HELPER)) {
+ verbose(env, "R%d pointer arithmetic of map value goes out of range, "
+ "prohibited for !root\n", dst);
+ return -EACCES;
+--
+2.35.1
+
--- /dev/null
+From b277c3ddb1c4df1e5dc59f43786d5757c64e1e21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 15:01:05 -0700
+Subject: bpf: Fix bpf_xdp_pointer return pointer
+
+From: Joanne Koong <joannelkoong@gmail.com>
+
+[ Upstream commit bbd52178e249fe893ef4a9b87cde5b6c473b0a7c ]
+
+For the case where offset + len == size, bpf_xdp_pointer should return a
+valid pointer to the addr because that access is permitted. We should
+only return NULL in the case where offset + len exceeds size.
+
+Fixes: 3f364222d032 ("net: xdp: introduce bpf_xdp_pointer utility routine")
+Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Martin KaFai Lau <kafai@fb.com>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://lore.kernel.org/bpf/20220722220105.2065466-1-joannelkoong@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/filter.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 5db4fae23925..a98f34cb5aee 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -3917,7 +3917,7 @@ static void *bpf_xdp_pointer(struct xdp_buff *xdp, u32 offset, u32 len)
+ offset -= frag_size;
+ }
+ out:
+- return offset + len < size ? addr + offset : NULL;
++ return offset + len <= size ? addr + offset : NULL;
+ }
+
+ BPF_CALL_4(bpf_xdp_load_bytes, struct xdp_buff *, xdp, u32, offset,
+--
+2.35.1
+
--- /dev/null
+From af31a4a3225e6016a5d79d2a2280f0b3ccb5c91a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 22:31:43 -0700
+Subject: bpf: fix potential 32-bit overflow when accessing ARRAY map element
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit 87ac0d600943994444e24382a87aa19acc4cd3d4 ]
+
+If BPF array map is bigger than 4GB, element pointer calculation can
+overflow because both index and elem_size are u32. Fix this everywhere
+by forcing 64-bit multiplication. Extract this formula into separate
+small helper and use it consistently in various places.
+
+Speculative-preventing formula utilizing index_mask trick is left as is,
+but explicit u64 casts are added in both places.
+
+Fixes: c85d69135a91 ("bpf: move memory size checks to bpf_map_charge_init()")
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/r/20220715053146.1291891-2-andrii@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/arraymap.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
+index c3de63ce574e..d015fce67865 100644
+--- a/kernel/bpf/arraymap.c
++++ b/kernel/bpf/arraymap.c
+@@ -155,6 +155,11 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr)
+ return &array->map;
+ }
+
++static void *array_map_elem_ptr(struct bpf_array* array, u32 index)
++{
++ return array->value + (u64)array->elem_size * index;
++}
++
+ /* Called from syscall or from eBPF program */
+ static void *array_map_lookup_elem(struct bpf_map *map, void *key)
+ {
+@@ -164,7 +169,7 @@ static void *array_map_lookup_elem(struct bpf_map *map, void *key)
+ if (unlikely(index >= array->map.max_entries))
+ return NULL;
+
+- return array->value + array->elem_size * (index & array->index_mask);
++ return array->value + (u64)array->elem_size * (index & array->index_mask);
+ }
+
+ static int array_map_direct_value_addr(const struct bpf_map *map, u64 *imm,
+@@ -324,7 +329,7 @@ static int array_map_update_elem(struct bpf_map *map, void *key, void *value,
+ value, map->value_size);
+ } else {
+ val = array->value +
+- array->elem_size * (index & array->index_mask);
++ (u64)array->elem_size * (index & array->index_mask);
+ if (map_flags & BPF_F_LOCK)
+ copy_map_value_locked(map, val, value, false);
+ else
+@@ -393,8 +398,7 @@ static void array_map_free_timers(struct bpf_map *map)
+ return;
+
+ for (i = 0; i < array->map.max_entries; i++)
+- bpf_timer_cancel_and_free(array->value + array->elem_size * i +
+- map->timer_off);
++ bpf_timer_cancel_and_free(array_map_elem_ptr(array, i) + map->timer_off);
+ }
+
+ /* Called when map->refcnt goes to zero, either from workqueue or from syscall */
+@@ -405,7 +409,7 @@ static void array_map_free(struct bpf_map *map)
+
+ if (map_value_has_kptrs(map)) {
+ for (i = 0; i < array->map.max_entries; i++)
+- bpf_map_free_kptrs(map, array->value + array->elem_size * i);
++ bpf_map_free_kptrs(map, array_map_elem_ptr(array, i));
+ bpf_map_free_kptr_off_tab(map);
+ }
+
+@@ -541,7 +545,7 @@ static void *bpf_array_map_seq_start(struct seq_file *seq, loff_t *pos)
+ index = info->index & array->index_mask;
+ if (info->percpu_value_buf)
+ return array->pptrs[index];
+- return array->value + array->elem_size * index;
++ return array_map_elem_ptr(array, index);
+ }
+
+ static void *bpf_array_map_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+@@ -560,7 +564,7 @@ static void *bpf_array_map_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ index = info->index & array->index_mask;
+ if (info->percpu_value_buf)
+ return array->pptrs[index];
+- return array->value + array->elem_size * index;
++ return array_map_elem_ptr(array, index);
+ }
+
+ static int __bpf_array_map_seq_show(struct seq_file *seq, void *v)
+@@ -675,7 +679,7 @@ static int bpf_for_each_array_elem(struct bpf_map *map, bpf_callback_t callback_
+ if (is_percpu)
+ val = this_cpu_ptr(array->pptrs[i]);
+ else
+- val = array->value + array->elem_size * i;
++ val = array_map_elem_ptr(array, i);
+ num_elems++;
+ key = i;
+ ret = callback_fn((u64)(long)map, (u64)(long)&key,
+--
+2.35.1
+
--- /dev/null
+From efe129fcf54e92947c1d5baa7f74bd766849827f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 14:16:37 -0700
+Subject: bpf: Fix subprog names in stack traces.
+
+From: Alexei Starovoitov <ast@kernel.org>
+
+[ Upstream commit 9c7c48d6a1e2eb5192ad5294c1c4dbd42a88e88b ]
+
+The commit 7337224fc150 ("bpf: Improve the info.func_info and info.func_info_rec_size behavior")
+accidently made bpf_prog_ksym_set_name() conservative for bpf subprograms.
+Fixed it so instead of "bpf_prog_tag_F" the stack traces print "bpf_prog_tag_full_subprog_name".
+
+Fixes: 7337224fc150 ("bpf: Improve the info.func_info and info.func_info_rec_size behavior")
+Reported-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Martin KaFai Lau <kafai@fb.com>
+Acked-by: Yonghong Song <yhs@fb.com>
+Link: https://lore.kernel.org/bpf/20220714211637.17150-1-alexei.starovoitov@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index a6d3a8972355..f29aa357826c 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -13016,6 +13016,7 @@ static int jit_subprogs(struct bpf_verifier_env *env)
+ /* Below members will be freed only at prog->aux */
+ func[i]->aux->btf = prog->aux->btf;
+ func[i]->aux->func_info = prog->aux->func_info;
++ func[i]->aux->func_info_cnt = prog->aux->func_info_cnt;
+ func[i]->aux->poke_tab = prog->aux->poke_tab;
+ func[i]->aux->size_poke_tab = prog->aux->size_poke_tab;
+
+@@ -13028,9 +13029,6 @@ static int jit_subprogs(struct bpf_verifier_env *env)
+ poke->aux = func[i]->aux;
+ }
+
+- /* Use bpf_prog_F_tag to indicate functions in stack traces.
+- * Long term would need debug info to populate names
+- */
+ func[i]->aux->name[0] = 'F';
+ func[i]->aux->stack_depth = env->subprog_info[i].stack_depth;
+ func[i]->jit_requested = 1;
+--
+2.35.1
+
--- /dev/null
+From 724aa79a1b13042c7f660dd7d55d2427fba1c7f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 21:33:42 +0530
+Subject: bpf: Make btf_find_field more generic
+
+From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+
+[ Upstream commit 42ba1308074d9046386d58b56e793604be48ce22 ]
+
+Next commit introduces field type 'kptr' whose kind will not be struct,
+but pointer, and it will not be limited to one offset, but multiple
+ones. Make existing btf_find_struct_field and btf_find_datasec_var
+functions amenable to use for finding kptrs in map value, by moving
+spin_lock and timer specific checks into their own function.
+
+The alignment, and name are checked before the function is called, so it
+is the last point where we can skip field or return an error before the
+next loop iteration happens. Size of the field and type is meant to be
+checked inside the function.
+
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20220415160354.1050687-2-memxor@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/btf.c | 120 +++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 89 insertions(+), 31 deletions(-)
+
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index feef799884d1..1fd8400bda06 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -3163,24 +3163,44 @@ static void btf_struct_log(struct btf_verifier_env *env,
+ btf_verifier_log(env, "size=%u vlen=%u", t->size, btf_type_vlen(t));
+ }
+
++enum btf_field_type {
++ BTF_FIELD_SPIN_LOCK,
++ BTF_FIELD_TIMER,
++};
++
++struct btf_field_info {
++ u32 off;
++};
++
++static int btf_find_struct(const struct btf *btf, const struct btf_type *t,
++ u32 off, int sz, struct btf_field_info *info)
++{
++ if (!__btf_type_is_struct(t))
++ return 0;
++ if (t->size != sz)
++ return 0;
++ if (info->off != -ENOENT)
++ /* only one such field is allowed */
++ return -E2BIG;
++ info->off = off;
++ return 0;
++}
++
+ static int btf_find_struct_field(const struct btf *btf, const struct btf_type *t,
+- const char *name, int sz, int align)
++ const char *name, int sz, int align,
++ enum btf_field_type field_type,
++ struct btf_field_info *info)
+ {
+ const struct btf_member *member;
+- u32 i, off = -ENOENT;
++ u32 i, off;
+
+ for_each_member(i, t, member) {
+ const struct btf_type *member_type = btf_type_by_id(btf,
+ member->type);
+- if (!__btf_type_is_struct(member_type))
+- continue;
+- if (member_type->size != sz)
+- continue;
++
+ if (strcmp(__btf_name_by_offset(btf, member_type->name_off), name))
+ continue;
+- if (off != -ENOENT)
+- /* only one such field is allowed */
+- return -E2BIG;
++
+ off = __btf_member_bit_offset(t, member);
+ if (off % 8)
+ /* valid C code cannot generate such BTF */
+@@ -3188,46 +3208,76 @@ static int btf_find_struct_field(const struct btf *btf, const struct btf_type *t
+ off /= 8;
+ if (off % align)
+ return -EINVAL;
++
++ switch (field_type) {
++ case BTF_FIELD_SPIN_LOCK:
++ case BTF_FIELD_TIMER:
++ return btf_find_struct(btf, member_type, off, sz, info);
++ default:
++ return -EFAULT;
++ }
+ }
+- return off;
++ return 0;
+ }
+
+ static int btf_find_datasec_var(const struct btf *btf, const struct btf_type *t,
+- const char *name, int sz, int align)
++ const char *name, int sz, int align,
++ enum btf_field_type field_type,
++ struct btf_field_info *info)
+ {
+ const struct btf_var_secinfo *vsi;
+- u32 i, off = -ENOENT;
++ u32 i, off;
+
+ for_each_vsi(i, t, vsi) {
+ const struct btf_type *var = btf_type_by_id(btf, vsi->type);
+ const struct btf_type *var_type = btf_type_by_id(btf, var->type);
+
+- if (!__btf_type_is_struct(var_type))
+- continue;
+- if (var_type->size != sz)
++ off = vsi->offset;
++
++ if (strcmp(__btf_name_by_offset(btf, var_type->name_off), name))
+ continue;
+ if (vsi->size != sz)
+ continue;
+- if (strcmp(__btf_name_by_offset(btf, var_type->name_off), name))
+- continue;
+- if (off != -ENOENT)
+- /* only one such field is allowed */
+- return -E2BIG;
+- off = vsi->offset;
+ if (off % align)
+ return -EINVAL;
++
++ switch (field_type) {
++ case BTF_FIELD_SPIN_LOCK:
++ case BTF_FIELD_TIMER:
++ return btf_find_struct(btf, var_type, off, sz, info);
++ default:
++ return -EFAULT;
++ }
+ }
+- return off;
++ return 0;
+ }
+
+ static int btf_find_field(const struct btf *btf, const struct btf_type *t,
+- const char *name, int sz, int align)
++ enum btf_field_type field_type,
++ struct btf_field_info *info)
+ {
++ const char *name;
++ int sz, align;
++
++ switch (field_type) {
++ case BTF_FIELD_SPIN_LOCK:
++ name = "bpf_spin_lock";
++ sz = sizeof(struct bpf_spin_lock);
++ align = __alignof__(struct bpf_spin_lock);
++ break;
++ case BTF_FIELD_TIMER:
++ name = "bpf_timer";
++ sz = sizeof(struct bpf_timer);
++ align = __alignof__(struct bpf_timer);
++ break;
++ default:
++ return -EFAULT;
++ }
+
+ if (__btf_type_is_struct(t))
+- return btf_find_struct_field(btf, t, name, sz, align);
++ return btf_find_struct_field(btf, t, name, sz, align, field_type, info);
+ else if (btf_type_is_datasec(t))
+- return btf_find_datasec_var(btf, t, name, sz, align);
++ return btf_find_datasec_var(btf, t, name, sz, align, field_type, info);
+ return -EINVAL;
+ }
+
+@@ -3237,16 +3287,24 @@ static int btf_find_field(const struct btf *btf, const struct btf_type *t,
+ */
+ int btf_find_spin_lock(const struct btf *btf, const struct btf_type *t)
+ {
+- return btf_find_field(btf, t, "bpf_spin_lock",
+- sizeof(struct bpf_spin_lock),
+- __alignof__(struct bpf_spin_lock));
++ struct btf_field_info info = { .off = -ENOENT };
++ int ret;
++
++ ret = btf_find_field(btf, t, BTF_FIELD_SPIN_LOCK, &info);
++ if (ret < 0)
++ return ret;
++ return info.off;
+ }
+
+ int btf_find_timer(const struct btf *btf, const struct btf_type *t)
+ {
+- return btf_find_field(btf, t, "bpf_timer",
+- sizeof(struct bpf_timer),
+- __alignof__(struct bpf_timer));
++ struct btf_field_info info = { .off = -ENOENT };
++ int ret;
++
++ ret = btf_find_field(btf, t, BTF_FIELD_TIMER, &info);
++ if (ret < 0)
++ return ret;
++ return info.off;
+ }
+
+ static void __btf_struct_show(const struct btf *btf, const struct btf_type *t,
+--
+2.35.1
+
--- /dev/null
+From d803723e88a4c9efb3a2f278c267e26d45c2e90c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 21:33:43 +0530
+Subject: bpf: Move check_ptr_off_reg before check_map_access
+
+From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+
+[ Upstream commit e9147b4422e1f35b9c229c980c596ccf03d61562 ]
+
+Some functions in next patch want to use this function, and those
+functions will be called by check_map_access, hence move it before
+check_map_access.
+
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Joanne Koong <joannelkoong@gmail.com>
+Link: https://lore.kernel.org/bpf/20220415160354.1050687-3-memxor@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 76 +++++++++++++++++++++----------------------
+ 1 file changed, 38 insertions(+), 38 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index f29aa357826c..afa05e6cd78f 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -3468,6 +3468,44 @@ static int check_mem_region_access(struct bpf_verifier_env *env, u32 regno,
+ return 0;
+ }
+
++static int __check_ptr_off_reg(struct bpf_verifier_env *env,
++ const struct bpf_reg_state *reg, int regno,
++ bool fixed_off_ok)
++{
++ /* Access to this pointer-typed register or passing it to a helper
++ * is only allowed in its original, unmodified form.
++ */
++
++ if (reg->off < 0) {
++ verbose(env, "negative offset %s ptr R%d off=%d disallowed\n",
++ reg_type_str(env, reg->type), regno, reg->off);
++ return -EACCES;
++ }
++
++ if (!fixed_off_ok && reg->off) {
++ verbose(env, "dereference of modified %s ptr R%d off=%d disallowed\n",
++ reg_type_str(env, reg->type), regno, reg->off);
++ return -EACCES;
++ }
++
++ if (!tnum_is_const(reg->var_off) || reg->var_off.value) {
++ char tn_buf[48];
++
++ tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
++ verbose(env, "variable %s access var_off=%s disallowed\n",
++ reg_type_str(env, reg->type), tn_buf);
++ return -EACCES;
++ }
++
++ return 0;
++}
++
++int check_ptr_off_reg(struct bpf_verifier_env *env,
++ const struct bpf_reg_state *reg, int regno)
++{
++ return __check_ptr_off_reg(env, reg, regno, false);
++}
++
+ /* check read/write into a map element with possible variable offset */
+ static int check_map_access(struct bpf_verifier_env *env, u32 regno,
+ int off, int size, bool zero_size_allowed)
+@@ -3979,44 +4017,6 @@ static int get_callee_stack_depth(struct bpf_verifier_env *env,
+ }
+ #endif
+
+-static int __check_ptr_off_reg(struct bpf_verifier_env *env,
+- const struct bpf_reg_state *reg, int regno,
+- bool fixed_off_ok)
+-{
+- /* Access to this pointer-typed register or passing it to a helper
+- * is only allowed in its original, unmodified form.
+- */
+-
+- if (reg->off < 0) {
+- verbose(env, "negative offset %s ptr R%d off=%d disallowed\n",
+- reg_type_str(env, reg->type), regno, reg->off);
+- return -EACCES;
+- }
+-
+- if (!fixed_off_ok && reg->off) {
+- verbose(env, "dereference of modified %s ptr R%d off=%d disallowed\n",
+- reg_type_str(env, reg->type), regno, reg->off);
+- return -EACCES;
+- }
+-
+- if (!tnum_is_const(reg->var_off) || reg->var_off.value) {
+- char tn_buf[48];
+-
+- tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
+- verbose(env, "variable %s access var_off=%s disallowed\n",
+- reg_type_str(env, reg->type), tn_buf);
+- return -EACCES;
+- }
+-
+- return 0;
+-}
+-
+-int check_ptr_off_reg(struct bpf_verifier_env *env,
+- const struct bpf_reg_state *reg, int regno)
+-{
+- return __check_ptr_off_reg(env, reg, regno, false);
+-}
+-
+ static int __check_buffer_access(struct bpf_verifier_env *env,
+ const char *buf_info,
+ const struct bpf_reg_state *reg,
+--
+2.35.1
+
--- /dev/null
+From 3eaa8d8519d7918bf01a25f6eeae27601bdfc3c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Apr 2022 03:18:54 +0530
+Subject: bpf: Populate pairs of btf_id and destructor kfunc in btf
+
+From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+
+[ Upstream commit 5ce937d613a423ca3102f53d9f3daf4210c1b6e2 ]
+
+To support storing referenced PTR_TO_BTF_ID in maps, we require
+associating a specific BTF ID with a 'destructor' kfunc. This is because
+we need to release a live referenced pointer at a certain offset in map
+value from the map destruction path, otherwise we end up leaking
+resources.
+
+Hence, introduce support for passing an array of btf_id, kfunc_btf_id
+pairs that denote a BTF ID and its associated release function. Then,
+add an accessor 'btf_find_dtor_kfunc' which can be used to look up the
+destructor kfunc of a certain BTF ID. If found, we can use it to free
+the object from the map free path.
+
+The registration of these pairs also serve as a whitelist of structures
+which are allowed as referenced PTR_TO_BTF_ID in a BPF map, because
+without finding the destructor kfunc, we will bail and return an error.
+
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20220424214901.2743946-7-memxor@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/btf.h | 17 +++++++
+ kernel/bpf/btf.c | 108 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 125 insertions(+)
+
+diff --git a/include/linux/btf.h b/include/linux/btf.h
+index 19c297f9a52f..fea424681d66 100644
+--- a/include/linux/btf.h
++++ b/include/linux/btf.h
+@@ -40,6 +40,11 @@ struct btf_kfunc_id_set {
+ };
+ };
+
++struct btf_id_dtor_kfunc {
++ u32 btf_id;
++ u32 kfunc_btf_id;
++};
++
+ extern const struct file_operations btf_fops;
+
+ void btf_get(struct btf *btf);
+@@ -346,6 +351,9 @@ bool btf_kfunc_id_set_contains(const struct btf *btf,
+ enum btf_kfunc_type type, u32 kfunc_btf_id);
+ int register_btf_kfunc_id_set(enum bpf_prog_type prog_type,
+ const struct btf_kfunc_id_set *s);
++s32 btf_find_dtor_kfunc(struct btf *btf, u32 btf_id);
++int register_btf_id_dtor_kfuncs(const struct btf_id_dtor_kfunc *dtors, u32 add_cnt,
++ struct module *owner);
+ #else
+ static inline const struct btf_type *btf_type_by_id(const struct btf *btf,
+ u32 type_id)
+@@ -369,6 +377,15 @@ static inline int register_btf_kfunc_id_set(enum bpf_prog_type prog_type,
+ {
+ return 0;
+ }
++static inline s32 btf_find_dtor_kfunc(struct btf *btf, u32 btf_id)
++{
++ return -ENOENT;
++}
++static inline int register_btf_id_dtor_kfuncs(const struct btf_id_dtor_kfunc *dtors,
++ u32 add_cnt, struct module *owner)
++{
++ return 0;
++}
+ #endif
+
+ #endif
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 58fd6896c403..57e3d9443ff3 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -207,12 +207,18 @@ enum btf_kfunc_hook {
+
+ enum {
+ BTF_KFUNC_SET_MAX_CNT = 32,
++ BTF_DTOR_KFUNC_MAX_CNT = 256,
+ };
+
+ struct btf_kfunc_set_tab {
+ struct btf_id_set *sets[BTF_KFUNC_HOOK_MAX][BTF_KFUNC_TYPE_MAX];
+ };
+
++struct btf_id_dtor_kfunc_tab {
++ u32 cnt;
++ struct btf_id_dtor_kfunc dtors[];
++};
++
+ struct btf {
+ void *data;
+ struct btf_type **types;
+@@ -228,6 +234,7 @@ struct btf {
+ u32 id;
+ struct rcu_head rcu;
+ struct btf_kfunc_set_tab *kfunc_set_tab;
++ struct btf_id_dtor_kfunc_tab *dtor_kfunc_tab;
+
+ /* split BTF support */
+ struct btf *base_btf;
+@@ -1616,8 +1623,19 @@ static void btf_free_kfunc_set_tab(struct btf *btf)
+ btf->kfunc_set_tab = NULL;
+ }
+
++static void btf_free_dtor_kfunc_tab(struct btf *btf)
++{
++ struct btf_id_dtor_kfunc_tab *tab = btf->dtor_kfunc_tab;
++
++ if (!tab)
++ return;
++ kfree(tab);
++ btf->dtor_kfunc_tab = NULL;
++}
++
+ static void btf_free(struct btf *btf)
+ {
++ btf_free_dtor_kfunc_tab(btf);
+ btf_free_kfunc_set_tab(btf);
+ kvfree(btf->types);
+ kvfree(btf->resolved_sizes);
+@@ -7022,6 +7040,96 @@ int register_btf_kfunc_id_set(enum bpf_prog_type prog_type,
+ }
+ EXPORT_SYMBOL_GPL(register_btf_kfunc_id_set);
+
++s32 btf_find_dtor_kfunc(struct btf *btf, u32 btf_id)
++{
++ struct btf_id_dtor_kfunc_tab *tab = btf->dtor_kfunc_tab;
++ struct btf_id_dtor_kfunc *dtor;
++
++ if (!tab)
++ return -ENOENT;
++ /* Even though the size of tab->dtors[0] is > sizeof(u32), we only need
++ * to compare the first u32 with btf_id, so we can reuse btf_id_cmp_func.
++ */
++ BUILD_BUG_ON(offsetof(struct btf_id_dtor_kfunc, btf_id) != 0);
++ dtor = bsearch(&btf_id, tab->dtors, tab->cnt, sizeof(tab->dtors[0]), btf_id_cmp_func);
++ if (!dtor)
++ return -ENOENT;
++ return dtor->kfunc_btf_id;
++}
++
++/* This function must be invoked only from initcalls/module init functions */
++int register_btf_id_dtor_kfuncs(const struct btf_id_dtor_kfunc *dtors, u32 add_cnt,
++ struct module *owner)
++{
++ struct btf_id_dtor_kfunc_tab *tab;
++ struct btf *btf;
++ u32 tab_cnt;
++ int ret;
++
++ btf = btf_get_module_btf(owner);
++ if (!btf) {
++ if (!owner && IS_ENABLED(CONFIG_DEBUG_INFO_BTF)) {
++ pr_err("missing vmlinux BTF, cannot register dtor kfuncs\n");
++ return -ENOENT;
++ }
++ if (owner && IS_ENABLED(CONFIG_DEBUG_INFO_BTF_MODULES)) {
++ pr_err("missing module BTF, cannot register dtor kfuncs\n");
++ return -ENOENT;
++ }
++ return 0;
++ }
++ if (IS_ERR(btf))
++ return PTR_ERR(btf);
++
++ if (add_cnt >= BTF_DTOR_KFUNC_MAX_CNT) {
++ pr_err("cannot register more than %d kfunc destructors\n", BTF_DTOR_KFUNC_MAX_CNT);
++ ret = -E2BIG;
++ goto end;
++ }
++
++ tab = btf->dtor_kfunc_tab;
++ /* Only one call allowed for modules */
++ if (WARN_ON_ONCE(tab && btf_is_module(btf))) {
++ ret = -EINVAL;
++ goto end;
++ }
++
++ tab_cnt = tab ? tab->cnt : 0;
++ if (tab_cnt > U32_MAX - add_cnt) {
++ ret = -EOVERFLOW;
++ goto end;
++ }
++ if (tab_cnt + add_cnt >= BTF_DTOR_KFUNC_MAX_CNT) {
++ pr_err("cannot register more than %d kfunc destructors\n", BTF_DTOR_KFUNC_MAX_CNT);
++ ret = -E2BIG;
++ goto end;
++ }
++
++ tab = krealloc(btf->dtor_kfunc_tab,
++ offsetof(struct btf_id_dtor_kfunc_tab, dtors[tab_cnt + add_cnt]),
++ GFP_KERNEL | __GFP_NOWARN);
++ if (!tab) {
++ ret = -ENOMEM;
++ goto end;
++ }
++
++ if (!btf->dtor_kfunc_tab)
++ tab->cnt = 0;
++ btf->dtor_kfunc_tab = tab;
++
++ memcpy(tab->dtors + tab->cnt, dtors, add_cnt * sizeof(tab->dtors[0]));
++ tab->cnt += add_cnt;
++
++ sort(tab->dtors, tab->cnt, sizeof(tab->dtors[0]), btf_id_cmp_func, NULL);
++
++ return 0;
++end:
++ btf_free_dtor_kfunc_tab(btf);
++ btf_put(btf);
++ return ret;
++}
++EXPORT_SYMBOL_GPL(register_btf_id_dtor_kfuncs);
++
+ #define MAX_TYPES_ARE_COMPAT_DEPTH 2
+
+ static
+--
+2.35.1
+
--- /dev/null
+From d1bf94889dd4ba1975c5a3167b64a16e7ef30f8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Apr 2022 03:18:50 +0530
+Subject: bpf: Tag argument to be released in bpf_func_proto
+
+From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+
+[ Upstream commit 8f14852e89113d738c99c375b4c8b8b7e1073df1 ]
+
+Add a new type flag for bpf_arg_type that when set tells verifier that
+for a release function, that argument's register will be the one for
+which meta.ref_obj_id will be set, and which will then be released
+using release_reference. To capture the regno, introduce a new field
+release_regno in bpf_call_arg_meta.
+
+This would be required in the next patch, where we may either pass NULL
+or a refcounted pointer as an argument to the release function
+bpf_kptr_xchg. Just releasing only when meta.ref_obj_id is set is not
+enough, as there is a case where the type of argument needed matches,
+but the ref_obj_id is set to 0. Hence, we must enforce that whenever
+meta.ref_obj_id is zero, the register that is to be released can only
+be NULL for a release function.
+
+Since we now indicate whether an argument is to be released in
+bpf_func_proto itself, is_release_function helper has lost its utitlity,
+hence refactor code to work without it, and just rely on
+meta.release_regno to know when to release state for a ref_obj_id.
+Still, the restriction of one release argument and only one ref_obj_id
+passed to BPF helper or kfunc remains. This may be lifted in the future.
+
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20220424214901.2743946-3-memxor@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/bpf.h | 5 +-
+ include/linux/bpf_verifier.h | 3 +-
+ kernel/bpf/btf.c | 11 ++-
+ kernel/bpf/ringbuf.c | 4 +-
+ kernel/bpf/verifier.c | 76 +++++++++++--------
+ net/core/filter.c | 2 +-
+ .../selftests/bpf/verifier/ref_tracking.c | 2 +-
+ tools/testing/selftests/bpf/verifier/sock.c | 6 +-
+ 8 files changed, 60 insertions(+), 49 deletions(-)
+
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 00d55c10d876..2feae4a24d99 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -366,7 +366,10 @@ enum bpf_type_flag {
+ */
+ MEM_PERCPU = BIT(4 + BPF_BASE_TYPE_BITS),
+
+- __BPF_TYPE_LAST_FLAG = MEM_PERCPU,
++ /* Indicates that the argument will be released. */
++ OBJ_RELEASE = BIT(5 + BPF_BASE_TYPE_BITS),
++
++ __BPF_TYPE_LAST_FLAG = OBJ_RELEASE,
+ };
+
+ /* Max number of base types. */
+diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
+index 3a9d2d7cc6b7..1f1e7f2ea967 100644
+--- a/include/linux/bpf_verifier.h
++++ b/include/linux/bpf_verifier.h
+@@ -523,8 +523,7 @@ int check_ptr_off_reg(struct bpf_verifier_env *env,
+ const struct bpf_reg_state *reg, int regno);
+ int check_func_arg_reg_off(struct bpf_verifier_env *env,
+ const struct bpf_reg_state *reg, int regno,
+- enum bpf_arg_type arg_type,
+- bool is_release_func);
++ enum bpf_arg_type arg_type);
+ int check_kfunc_mem_size_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg,
+ u32 regno);
+ int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg,
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index cbb48eb8c009..752de8112206 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -5994,6 +5994,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
+ * verifier sees.
+ */
+ for (i = 0; i < nargs; i++) {
++ enum bpf_arg_type arg_type = ARG_DONTCARE;
+ u32 regno = i + 1;
+ struct bpf_reg_state *reg = ®s[regno];
+
+@@ -6014,7 +6015,9 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
+ ref_t = btf_type_skip_modifiers(btf, t->type, &ref_id);
+ ref_tname = btf_name_by_offset(btf, ref_t->name_off);
+
+- ret = check_func_arg_reg_off(env, reg, regno, ARG_DONTCARE, rel);
++ if (rel && reg->ref_obj_id)
++ arg_type |= OBJ_RELEASE;
++ ret = check_func_arg_reg_off(env, reg, regno, arg_type);
+ if (ret < 0)
+ return ret;
+
+@@ -6045,11 +6048,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
+ if (reg->type == PTR_TO_BTF_ID) {
+ reg_btf = reg->btf;
+ reg_ref_id = reg->btf_id;
+- /* Ensure only one argument is referenced
+- * PTR_TO_BTF_ID, check_func_arg_reg_off relies
+- * on only one referenced register being allowed
+- * for kfuncs.
+- */
++ /* Ensure only one argument is referenced PTR_TO_BTF_ID */
+ if (reg->ref_obj_id) {
+ if (ref_obj_id) {
+ bpf_log(log, "verifier internal error: more than one arg with ref_obj_id R%d %u %u\n",
+diff --git a/kernel/bpf/ringbuf.c b/kernel/bpf/ringbuf.c
+index 710ba9de12ce..5173fd37590f 100644
+--- a/kernel/bpf/ringbuf.c
++++ b/kernel/bpf/ringbuf.c
+@@ -404,7 +404,7 @@ BPF_CALL_2(bpf_ringbuf_submit, void *, sample, u64, flags)
+ const struct bpf_func_proto bpf_ringbuf_submit_proto = {
+ .func = bpf_ringbuf_submit,
+ .ret_type = RET_VOID,
+- .arg1_type = ARG_PTR_TO_ALLOC_MEM,
++ .arg1_type = ARG_PTR_TO_ALLOC_MEM | OBJ_RELEASE,
+ .arg2_type = ARG_ANYTHING,
+ };
+
+@@ -417,7 +417,7 @@ BPF_CALL_2(bpf_ringbuf_discard, void *, sample, u64, flags)
+ const struct bpf_func_proto bpf_ringbuf_discard_proto = {
+ .func = bpf_ringbuf_discard,
+ .ret_type = RET_VOID,
+- .arg1_type = ARG_PTR_TO_ALLOC_MEM,
++ .arg1_type = ARG_PTR_TO_ALLOC_MEM | OBJ_RELEASE,
+ .arg2_type = ARG_ANYTHING,
+ };
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index b8d1060153c8..4f19a86c2682 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -245,6 +245,7 @@ struct bpf_call_arg_meta {
+ struct bpf_map *map_ptr;
+ bool raw_mode;
+ bool pkt_access;
++ u8 release_regno;
+ int regno;
+ int access_size;
+ int mem_size;
+@@ -471,17 +472,6 @@ static bool type_may_be_null(u32 type)
+ return type & PTR_MAYBE_NULL;
+ }
+
+-/* Determine whether the function releases some resources allocated by another
+- * function call. The first reference type argument will be assumed to be
+- * released by release_reference().
+- */
+-static bool is_release_function(enum bpf_func_id func_id)
+-{
+- return func_id == BPF_FUNC_sk_release ||
+- func_id == BPF_FUNC_ringbuf_submit ||
+- func_id == BPF_FUNC_ringbuf_discard;
+-}
+-
+ static bool may_be_acquire_function(enum bpf_func_id func_id)
+ {
+ return func_id == BPF_FUNC_sk_lookup_tcp ||
+@@ -5325,6 +5315,11 @@ static bool arg_type_is_int_ptr(enum bpf_arg_type type)
+ type == ARG_PTR_TO_LONG;
+ }
+
++static bool arg_type_is_release(enum bpf_arg_type type)
++{
++ return type & OBJ_RELEASE;
++}
++
+ static int int_ptr_type_to_size(enum bpf_arg_type type)
+ {
+ if (type == ARG_PTR_TO_INT)
+@@ -5535,11 +5530,10 @@ static int check_reg_type(struct bpf_verifier_env *env, u32 regno,
+
+ int check_func_arg_reg_off(struct bpf_verifier_env *env,
+ const struct bpf_reg_state *reg, int regno,
+- enum bpf_arg_type arg_type,
+- bool is_release_func)
++ enum bpf_arg_type arg_type)
+ {
+- bool fixed_off_ok = false, release_reg;
+ enum bpf_reg_type type = reg->type;
++ bool fixed_off_ok = false;
+
+ switch ((u32)type) {
+ case SCALAR_VALUE:
+@@ -5557,7 +5551,7 @@ int check_func_arg_reg_off(struct bpf_verifier_env *env,
+ /* Some of the argument types nevertheless require a
+ * zero register offset.
+ */
+- if (arg_type != ARG_PTR_TO_ALLOC_MEM)
++ if (base_type(arg_type) != ARG_PTR_TO_ALLOC_MEM)
+ return 0;
+ break;
+ /* All the rest must be rejected, except PTR_TO_BTF_ID which allows
+@@ -5565,19 +5559,17 @@ int check_func_arg_reg_off(struct bpf_verifier_env *env,
+ */
+ case PTR_TO_BTF_ID:
+ /* When referenced PTR_TO_BTF_ID is passed to release function,
+- * it's fixed offset must be 0. We rely on the property that
+- * only one referenced register can be passed to BPF helpers and
+- * kfuncs. In the other cases, fixed offset can be non-zero.
++ * it's fixed offset must be 0. In the other cases, fixed offset
++ * can be non-zero.
+ */
+- release_reg = is_release_func && reg->ref_obj_id;
+- if (release_reg && reg->off) {
++ if (arg_type_is_release(arg_type) && reg->off) {
+ verbose(env, "R%d must have zero offset when passed to release func\n",
+ regno);
+ return -EINVAL;
+ }
+- /* For release_reg == true, fixed_off_ok must be false, but we
+- * already checked and rejected reg->off != 0 above, so set to
+- * true to allow fixed offset for all other cases.
++ /* For arg is release pointer, fixed_off_ok must be false, but
++ * we already checked and rejected reg->off != 0 above, so set
++ * to true to allow fixed offset for all other cases.
+ */
+ fixed_off_ok = true;
+ break;
+@@ -5636,14 +5628,24 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
+ if (err)
+ return err;
+
+- err = check_func_arg_reg_off(env, reg, regno, arg_type, is_release_function(meta->func_id));
++ err = check_func_arg_reg_off(env, reg, regno, arg_type);
+ if (err)
+ return err;
+
+ skip_type_check:
+- /* check_func_arg_reg_off relies on only one referenced register being
+- * allowed for BPF helpers.
+- */
++ if (arg_type_is_release(arg_type)) {
++ if (!reg->ref_obj_id && !register_is_null(reg)) {
++ verbose(env, "R%d must be referenced when passed to release function\n",
++ regno);
++ return -EINVAL;
++ }
++ if (meta->release_regno) {
++ verbose(env, "verifier internal error: more than one release argument\n");
++ return -EFAULT;
++ }
++ meta->release_regno = regno;
++ }
++
+ if (reg->ref_obj_id) {
+ if (meta->ref_obj_id) {
+ verbose(env, "verifier internal error: more than one arg with ref_obj_id R%d %u %u\n",
+@@ -6151,7 +6153,8 @@ static bool check_btf_id_ok(const struct bpf_func_proto *fn)
+ return true;
+ }
+
+-static int check_func_proto(const struct bpf_func_proto *fn, int func_id)
++static int check_func_proto(const struct bpf_func_proto *fn, int func_id,
++ struct bpf_call_arg_meta *meta)
+ {
+ return check_raw_mode_ok(fn) &&
+ check_arg_pair_ok(fn) &&
+@@ -6833,7 +6836,7 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ memset(&meta, 0, sizeof(meta));
+ meta.pkt_access = fn->pkt_access;
+
+- err = check_func_proto(fn, func_id);
++ err = check_func_proto(fn, func_id, &meta);
+ if (err) {
+ verbose(env, "kernel subsystem misconfigured func %s#%d\n",
+ func_id_name(func_id), func_id);
+@@ -6866,8 +6869,17 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ return err;
+ }
+
+- if (is_release_function(func_id)) {
+- err = release_reference(env, meta.ref_obj_id);
++ regs = cur_regs(env);
++
++ if (meta.release_regno) {
++ err = -EINVAL;
++ if (meta.ref_obj_id)
++ err = release_reference(env, meta.ref_obj_id);
++ /* meta.ref_obj_id can only be 0 if register that is meant to be
++ * released is NULL, which must be > R0.
++ */
++ else if (register_is_null(®s[meta.release_regno]))
++ err = 0;
+ if (err) {
+ verbose(env, "func %s#%d reference has not been acquired before\n",
+ func_id_name(func_id), func_id);
+@@ -6875,8 +6887,6 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ }
+ }
+
+- regs = cur_regs(env);
+-
+ switch (func_id) {
+ case BPF_FUNC_tail_call:
+ err = check_reference_leak(env);
+diff --git a/net/core/filter.c b/net/core/filter.c
+index d0b0c163d3f3..5db4fae23925 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -6642,7 +6642,7 @@ static const struct bpf_func_proto bpf_sk_release_proto = {
+ .func = bpf_sk_release,
+ .gpl_only = false,
+ .ret_type = RET_INTEGER,
+- .arg1_type = ARG_PTR_TO_BTF_ID_SOCK_COMMON,
++ .arg1_type = ARG_PTR_TO_BTF_ID_SOCK_COMMON | OBJ_RELEASE,
+ };
+
+ BPF_CALL_5(bpf_xdp_sk_lookup_udp, struct xdp_buff *, ctx,
+diff --git a/tools/testing/selftests/bpf/verifier/ref_tracking.c b/tools/testing/selftests/bpf/verifier/ref_tracking.c
+index fbd682520e47..57a83d763ec1 100644
+--- a/tools/testing/selftests/bpf/verifier/ref_tracking.c
++++ b/tools/testing/selftests/bpf/verifier/ref_tracking.c
+@@ -796,7 +796,7 @@
+ },
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+ .result = REJECT,
+- .errstr = "reference has not been acquired before",
++ .errstr = "R1 must be referenced when passed to release function",
+ },
+ {
+ /* !bpf_sk_fullsock(sk) is checked but !bpf_tcp_sock(sk) is not checked */
+diff --git a/tools/testing/selftests/bpf/verifier/sock.c b/tools/testing/selftests/bpf/verifier/sock.c
+index 86b24cad27a7..d11d0b28be41 100644
+--- a/tools/testing/selftests/bpf/verifier/sock.c
++++ b/tools/testing/selftests/bpf/verifier/sock.c
+@@ -417,7 +417,7 @@
+ },
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+ .result = REJECT,
+- .errstr = "reference has not been acquired before",
++ .errstr = "R1 must be referenced when passed to release function",
+ },
+ {
+ "bpf_sk_release(bpf_sk_fullsock(skb->sk))",
+@@ -436,7 +436,7 @@
+ },
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+ .result = REJECT,
+- .errstr = "reference has not been acquired before",
++ .errstr = "R1 must be referenced when passed to release function",
+ },
+ {
+ "bpf_sk_release(bpf_tcp_sock(skb->sk))",
+@@ -455,7 +455,7 @@
+ },
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+ .result = REJECT,
+- .errstr = "reference has not been acquired before",
++ .errstr = "R1 must be referenced when passed to release function",
+ },
+ {
+ "sk_storage_get(map, skb->sk, NULL, 0): value == NULL",
+--
+2.35.1
+
--- /dev/null
+From d3140cabb23592c3afba0aadc868bb97214a9ac4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Apr 2022 03:18:55 +0530
+Subject: bpf: Wire up freeing of referenced kptr
+
+From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+
+[ Upstream commit 14a324f6a67ef6a53e04362a70160a47eb8afffa ]
+
+A destructor kfunc can be defined as void func(type *), where type may
+be void or any other pointer type as per convenience.
+
+In this patch, we ensure that the type is sane and capture the function
+pointer into off_desc of ptr_off_tab for the specific pointer offset,
+with the invariant that the dtor pointer is always set when 'kptr_ref'
+tag is applied to the pointer's pointee type, which is indicated by the
+flag BPF_MAP_VALUE_OFF_F_REF.
+
+Note that only BTF IDs whose destructor kfunc is registered, thus become
+the allowed BTF IDs for embedding as referenced kptr. Hence it serves
+the purpose of finding dtor kfunc BTF ID, as well acting as a check
+against the whitelist of allowed BTF IDs for this purpose.
+
+Finally, wire up the actual freeing of the referenced pointer if any at
+all available offsets, so that no references are leaked after the BPF
+map goes away and the BPF program previously moved the ownership a
+referenced pointer into it.
+
+The behavior is similar to BPF timers, where bpf_map_{update,delete}_elem
+will free any existing referenced kptr. The same case is with LRU map's
+bpf_lru_push_free/htab_lru_push_free functions, which are extended to
+reset unreferenced and free referenced kptr.
+
+Note that unlike BPF timers, kptr is not reset or freed when map uref
+drops to zero.
+
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20220424214901.2743946-8-memxor@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/bpf.h | 4 ++
+ include/linux/btf.h | 2 +
+ kernel/bpf/arraymap.c | 18 ++++++--
+ kernel/bpf/btf.c | 98 ++++++++++++++++++++++++++++++++++++++++++-
+ kernel/bpf/hashtab.c | 64 +++++++++++++++++++++-------
+ kernel/bpf/syscall.c | 49 ++++++++++++++++++++--
+ 6 files changed, 210 insertions(+), 25 deletions(-)
+
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index a3fe7f53e567..f3c38574c265 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -23,6 +23,7 @@
+ #include <linux/slab.h>
+ #include <linux/percpu-refcount.h>
+ #include <linux/bpfptr.h>
++#include <linux/btf.h>
+
+ struct bpf_verifier_env;
+ struct bpf_verifier_log;
+@@ -173,6 +174,8 @@ struct bpf_map_value_off_desc {
+ enum bpf_kptr_type type;
+ struct {
+ struct btf *btf;
++ struct module *module;
++ btf_dtor_kfunc_t dtor;
+ u32 btf_id;
+ } kptr;
+ };
+@@ -1450,6 +1453,7 @@ struct bpf_map_value_off_desc *bpf_map_kptr_off_contains(struct bpf_map *map, u3
+ void bpf_map_free_kptr_off_tab(struct bpf_map *map);
+ struct bpf_map_value_off *bpf_map_copy_kptr_off_tab(const struct bpf_map *map);
+ bool bpf_map_equal_kptr_off_tab(const struct bpf_map *map_a, const struct bpf_map *map_b);
++void bpf_map_free_kptrs(struct bpf_map *map, void *map_value);
+
+ struct bpf_map *bpf_map_get(u32 ufd);
+ struct bpf_map *bpf_map_get_with_uref(u32 ufd);
+diff --git a/include/linux/btf.h b/include/linux/btf.h
+index fea424681d66..f70625dd5bb4 100644
+--- a/include/linux/btf.h
++++ b/include/linux/btf.h
+@@ -45,6 +45,8 @@ struct btf_id_dtor_kfunc {
+ u32 kfunc_btf_id;
+ };
+
++typedef void (*btf_dtor_kfunc_t)(void *);
++
+ extern const struct file_operations btf_fops;
+
+ void btf_get(struct btf *btf);
+diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
+index 7f145aefbff8..c3de63ce574e 100644
+--- a/kernel/bpf/arraymap.c
++++ b/kernel/bpf/arraymap.c
+@@ -287,10 +287,12 @@ static int array_map_get_next_key(struct bpf_map *map, void *key, void *next_key
+ return 0;
+ }
+
+-static void check_and_free_timer_in_array(struct bpf_array *arr, void *val)
++static void check_and_free_fields(struct bpf_array *arr, void *val)
+ {
+- if (unlikely(map_value_has_timer(&arr->map)))
++ if (map_value_has_timer(&arr->map))
+ bpf_timer_cancel_and_free(val + arr->map.timer_off);
++ if (map_value_has_kptrs(&arr->map))
++ bpf_map_free_kptrs(&arr->map, val);
+ }
+
+ /* Called from syscall or from eBPF program */
+@@ -327,7 +329,7 @@ static int array_map_update_elem(struct bpf_map *map, void *key, void *value,
+ copy_map_value_locked(map, val, value, false);
+ else
+ copy_map_value(map, val, value);
+- check_and_free_timer_in_array(array, val);
++ check_and_free_fields(array, val);
+ }
+ return 0;
+ }
+@@ -386,7 +388,8 @@ static void array_map_free_timers(struct bpf_map *map)
+ struct bpf_array *array = container_of(map, struct bpf_array, map);
+ int i;
+
+- if (likely(!map_value_has_timer(map)))
++ /* We don't reset or free kptr on uref dropping to zero. */
++ if (!map_value_has_timer(map))
+ return;
+
+ for (i = 0; i < array->map.max_entries; i++)
+@@ -398,6 +401,13 @@ static void array_map_free_timers(struct bpf_map *map)
+ static void array_map_free(struct bpf_map *map)
+ {
+ struct bpf_array *array = container_of(map, struct bpf_array, map);
++ int i;
++
++ if (map_value_has_kptrs(map)) {
++ for (i = 0; i < array->map.max_entries; i++)
++ bpf_map_free_kptrs(map, array->value + array->elem_size * i);
++ bpf_map_free_kptr_off_tab(map);
++ }
+
+ if (array->map.map_type == BPF_MAP_TYPE_PERCPU_ARRAY)
+ bpf_array_free_percpu(array);
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 57e3d9443ff3..7a593ecfbeec 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -3416,6 +3416,7 @@ struct bpf_map_value_off *btf_parse_kptrs(const struct btf *btf,
+ struct btf_field_info info_arr[BPF_MAP_VALUE_OFF_MAX];
+ struct bpf_map_value_off *tab;
+ struct btf *kernel_btf = NULL;
++ struct module *mod = NULL;
+ int ret, i, nr_off;
+
+ ret = btf_find_field(btf, t, BTF_FIELD_KPTR, info_arr, ARRAY_SIZE(info_arr));
+@@ -3444,16 +3445,69 @@ struct bpf_map_value_off *btf_parse_kptrs(const struct btf *btf,
+ goto end;
+ }
+
++ /* Find and stash the function pointer for the destruction function that
++ * needs to be eventually invoked from the map free path.
++ */
++ if (info_arr[i].type == BPF_KPTR_REF) {
++ const struct btf_type *dtor_func;
++ const char *dtor_func_name;
++ unsigned long addr;
++ s32 dtor_btf_id;
++
++ /* This call also serves as a whitelist of allowed objects that
++ * can be used as a referenced pointer and be stored in a map at
++ * the same time.
++ */
++ dtor_btf_id = btf_find_dtor_kfunc(kernel_btf, id);
++ if (dtor_btf_id < 0) {
++ ret = dtor_btf_id;
++ goto end_btf;
++ }
++
++ dtor_func = btf_type_by_id(kernel_btf, dtor_btf_id);
++ if (!dtor_func) {
++ ret = -ENOENT;
++ goto end_btf;
++ }
++
++ if (btf_is_module(kernel_btf)) {
++ mod = btf_try_get_module(kernel_btf);
++ if (!mod) {
++ ret = -ENXIO;
++ goto end_btf;
++ }
++ }
++
++ /* We already verified dtor_func to be btf_type_is_func
++ * in register_btf_id_dtor_kfuncs.
++ */
++ dtor_func_name = __btf_name_by_offset(kernel_btf, dtor_func->name_off);
++ addr = kallsyms_lookup_name(dtor_func_name);
++ if (!addr) {
++ ret = -EINVAL;
++ goto end_mod;
++ }
++ tab->off[i].kptr.dtor = (void *)addr;
++ }
++
+ tab->off[i].offset = info_arr[i].off;
+ tab->off[i].type = info_arr[i].type;
+ tab->off[i].kptr.btf_id = id;
+ tab->off[i].kptr.btf = kernel_btf;
++ tab->off[i].kptr.module = mod;
+ }
+ tab->nr_off = nr_off;
+ return tab;
++end_mod:
++ module_put(mod);
++end_btf:
++ btf_put(kernel_btf);
+ end:
+- while (i--)
++ while (i--) {
+ btf_put(tab->off[i].kptr.btf);
++ if (tab->off[i].kptr.module)
++ module_put(tab->off[i].kptr.module);
++ }
+ kfree(tab);
+ return ERR_PTR(ret);
+ }
+@@ -7057,6 +7111,43 @@ s32 btf_find_dtor_kfunc(struct btf *btf, u32 btf_id)
+ return dtor->kfunc_btf_id;
+ }
+
++static int btf_check_dtor_kfuncs(struct btf *btf, const struct btf_id_dtor_kfunc *dtors, u32 cnt)
++{
++ const struct btf_type *dtor_func, *dtor_func_proto, *t;
++ const struct btf_param *args;
++ s32 dtor_btf_id;
++ u32 nr_args, i;
++
++ for (i = 0; i < cnt; i++) {
++ dtor_btf_id = dtors[i].kfunc_btf_id;
++
++ dtor_func = btf_type_by_id(btf, dtor_btf_id);
++ if (!dtor_func || !btf_type_is_func(dtor_func))
++ return -EINVAL;
++
++ dtor_func_proto = btf_type_by_id(btf, dtor_func->type);
++ if (!dtor_func_proto || !btf_type_is_func_proto(dtor_func_proto))
++ return -EINVAL;
++
++ /* Make sure the prototype of the destructor kfunc is 'void func(type *)' */
++ t = btf_type_by_id(btf, dtor_func_proto->type);
++ if (!t || !btf_type_is_void(t))
++ return -EINVAL;
++
++ nr_args = btf_type_vlen(dtor_func_proto);
++ if (nr_args != 1)
++ return -EINVAL;
++ args = btf_params(dtor_func_proto);
++ t = btf_type_by_id(btf, args[0].type);
++ /* Allow any pointer type, as width on targets Linux supports
++ * will be same for all pointer types (i.e. sizeof(void *))
++ */
++ if (!t || !btf_type_is_ptr(t))
++ return -EINVAL;
++ }
++ return 0;
++}
++
+ /* This function must be invoked only from initcalls/module init functions */
+ int register_btf_id_dtor_kfuncs(const struct btf_id_dtor_kfunc *dtors, u32 add_cnt,
+ struct module *owner)
+@@ -7087,6 +7178,11 @@ int register_btf_id_dtor_kfuncs(const struct btf_id_dtor_kfunc *dtors, u32 add_c
+ goto end;
+ }
+
++ /* Ensure that the prototype of dtor kfuncs being registered is sane */
++ ret = btf_check_dtor_kfuncs(btf, dtors, add_cnt);
++ if (ret < 0)
++ goto end;
++
+ tab = btf->dtor_kfunc_tab;
+ /* Only one call allowed for modules */
+ if (WARN_ON_ONCE(tab && btf_is_module(btf))) {
+diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
+index 65877967f414..ea99c91f72b6 100644
+--- a/kernel/bpf/hashtab.c
++++ b/kernel/bpf/hashtab.c
+@@ -238,7 +238,7 @@ static void htab_free_prealloced_timers(struct bpf_htab *htab)
+ u32 num_entries = htab->map.max_entries;
+ int i;
+
+- if (likely(!map_value_has_timer(&htab->map)))
++ if (!map_value_has_timer(&htab->map))
+ return;
+ if (htab_has_extra_elems(htab))
+ num_entries += num_possible_cpus();
+@@ -254,6 +254,25 @@ static void htab_free_prealloced_timers(struct bpf_htab *htab)
+ }
+ }
+
++static void htab_free_prealloced_kptrs(struct bpf_htab *htab)
++{
++ u32 num_entries = htab->map.max_entries;
++ int i;
++
++ if (!map_value_has_kptrs(&htab->map))
++ return;
++ if (htab_has_extra_elems(htab))
++ num_entries += num_possible_cpus();
++
++ for (i = 0; i < num_entries; i++) {
++ struct htab_elem *elem;
++
++ elem = get_htab_elem(htab, i);
++ bpf_map_free_kptrs(&htab->map, elem->key + round_up(htab->map.key_size, 8));
++ cond_resched();
++ }
++}
++
+ static void htab_free_elems(struct bpf_htab *htab)
+ {
+ int i;
+@@ -725,12 +744,15 @@ static int htab_lru_map_gen_lookup(struct bpf_map *map,
+ return insn - insn_buf;
+ }
+
+-static void check_and_free_timer(struct bpf_htab *htab, struct htab_elem *elem)
++static void check_and_free_fields(struct bpf_htab *htab,
++ struct htab_elem *elem)
+ {
+- if (unlikely(map_value_has_timer(&htab->map)))
+- bpf_timer_cancel_and_free(elem->key +
+- round_up(htab->map.key_size, 8) +
+- htab->map.timer_off);
++ void *map_value = elem->key + round_up(htab->map.key_size, 8);
++
++ if (map_value_has_timer(&htab->map))
++ bpf_timer_cancel_and_free(map_value + htab->map.timer_off);
++ if (map_value_has_kptrs(&htab->map))
++ bpf_map_free_kptrs(&htab->map, map_value);
+ }
+
+ /* It is called from the bpf_lru_list when the LRU needs to delete
+@@ -757,7 +779,7 @@ static bool htab_lru_map_delete_node(void *arg, struct bpf_lru_node *node)
+ hlist_nulls_for_each_entry_rcu(l, n, head, hash_node)
+ if (l == tgt_l) {
+ hlist_nulls_del_rcu(&l->hash_node);
+- check_and_free_timer(htab, l);
++ check_and_free_fields(htab, l);
+ break;
+ }
+
+@@ -829,7 +851,7 @@ static void htab_elem_free(struct bpf_htab *htab, struct htab_elem *l)
+ {
+ if (htab->map.map_type == BPF_MAP_TYPE_PERCPU_HASH)
+ free_percpu(htab_elem_get_ptr(l, htab->map.key_size));
+- check_and_free_timer(htab, l);
++ check_and_free_fields(htab, l);
+ kfree(l);
+ }
+
+@@ -857,7 +879,7 @@ static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l)
+ htab_put_fd_value(htab, l);
+
+ if (htab_is_prealloc(htab)) {
+- check_and_free_timer(htab, l);
++ check_and_free_fields(htab, l);
+ __pcpu_freelist_push(&htab->freelist, &l->fnode);
+ } else {
+ atomic_dec(&htab->count);
+@@ -1104,7 +1126,7 @@ static int htab_map_update_elem(struct bpf_map *map, void *key, void *value,
+ if (!htab_is_prealloc(htab))
+ free_htab_elem(htab, l_old);
+ else
+- check_and_free_timer(htab, l_old);
++ check_and_free_fields(htab, l_old);
+ }
+ ret = 0;
+ err:
+@@ -1114,7 +1136,7 @@ static int htab_map_update_elem(struct bpf_map *map, void *key, void *value,
+
+ static void htab_lru_push_free(struct bpf_htab *htab, struct htab_elem *elem)
+ {
+- check_and_free_timer(htab, elem);
++ check_and_free_fields(htab, elem);
+ bpf_lru_push_free(&htab->lru, &elem->lru_node);
+ }
+
+@@ -1419,8 +1441,14 @@ static void htab_free_malloced_timers(struct bpf_htab *htab)
+ struct hlist_nulls_node *n;
+ struct htab_elem *l;
+
+- hlist_nulls_for_each_entry(l, n, head, hash_node)
+- check_and_free_timer(htab, l);
++ hlist_nulls_for_each_entry(l, n, head, hash_node) {
++ /* We don't reset or free kptr on uref dropping to zero,
++ * hence just free timer.
++ */
++ bpf_timer_cancel_and_free(l->key +
++ round_up(htab->map.key_size, 8) +
++ htab->map.timer_off);
++ }
+ cond_resched_rcu();
+ }
+ rcu_read_unlock();
+@@ -1430,7 +1458,8 @@ static void htab_map_free_timers(struct bpf_map *map)
+ {
+ struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
+
+- if (likely(!map_value_has_timer(&htab->map)))
++ /* We don't reset or free kptr on uref dropping to zero. */
++ if (!map_value_has_timer(&htab->map))
+ return;
+ if (!htab_is_prealloc(htab))
+ htab_free_malloced_timers(htab);
+@@ -1453,11 +1482,14 @@ static void htab_map_free(struct bpf_map *map)
+ * not have executed. Wait for them.
+ */
+ rcu_barrier();
+- if (!htab_is_prealloc(htab))
++ if (!htab_is_prealloc(htab)) {
+ delete_all_elements(htab);
+- else
++ } else {
++ htab_free_prealloced_kptrs(htab);
+ prealloc_destroy(htab);
++ }
+
++ bpf_map_free_kptr_off_tab(map);
+ free_percpu(htab->extra_elems);
+ bpf_map_area_free(htab->buckets);
+ for (i = 0; i < HASHTAB_MAP_LOCK_COUNT; i++)
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index 811bc71b0906..f4d1f974a8cd 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -507,8 +507,11 @@ void bpf_map_free_kptr_off_tab(struct bpf_map *map)
+
+ if (!map_value_has_kptrs(map))
+ return;
+- for (i = 0; i < tab->nr_off; i++)
++ for (i = 0; i < tab->nr_off; i++) {
++ if (tab->off[i].kptr.module)
++ module_put(tab->off[i].kptr.module);
+ btf_put(tab->off[i].kptr.btf);
++ }
+ kfree(tab);
+ map->kptr_off_tab = NULL;
+ }
+@@ -525,8 +528,18 @@ struct bpf_map_value_off *bpf_map_copy_kptr_off_tab(const struct bpf_map *map)
+ if (!new_tab)
+ return ERR_PTR(-ENOMEM);
+ /* Do a deep copy of the kptr_off_tab */
+- for (i = 0; i < tab->nr_off; i++)
++ for (i = 0; i < tab->nr_off; i++) {
+ btf_get(tab->off[i].kptr.btf);
++ if (tab->off[i].kptr.module && !try_module_get(tab->off[i].kptr.module)) {
++ while (i--) {
++ if (tab->off[i].kptr.module)
++ module_put(tab->off[i].kptr.module);
++ btf_put(tab->off[i].kptr.btf);
++ }
++ kfree(new_tab);
++ return ERR_PTR(-ENXIO);
++ }
++ }
+ return new_tab;
+ }
+
+@@ -546,6 +559,33 @@ bool bpf_map_equal_kptr_off_tab(const struct bpf_map *map_a, const struct bpf_ma
+ return !memcmp(tab_a, tab_b, size);
+ }
+
++/* Caller must ensure map_value_has_kptrs is true. Note that this function can
++ * be called on a map value while the map_value is visible to BPF programs, as
++ * it ensures the correct synchronization, and we already enforce the same using
++ * the bpf_kptr_xchg helper on the BPF program side for referenced kptrs.
++ */
++void bpf_map_free_kptrs(struct bpf_map *map, void *map_value)
++{
++ struct bpf_map_value_off *tab = map->kptr_off_tab;
++ unsigned long *btf_id_ptr;
++ int i;
++
++ for (i = 0; i < tab->nr_off; i++) {
++ struct bpf_map_value_off_desc *off_desc = &tab->off[i];
++ unsigned long old_ptr;
++
++ btf_id_ptr = map_value + off_desc->offset;
++ if (off_desc->type == BPF_KPTR_UNREF) {
++ u64 *p = (u64 *)btf_id_ptr;
++
++ WRITE_ONCE(p, 0);
++ continue;
++ }
++ old_ptr = xchg(btf_id_ptr, 0);
++ off_desc->kptr.dtor((void *)old_ptr);
++ }
++}
++
+ /* called from workqueue */
+ static void bpf_map_free_deferred(struct work_struct *work)
+ {
+@@ -553,9 +593,10 @@ static void bpf_map_free_deferred(struct work_struct *work)
+
+ security_bpf_map_free(map);
+ kfree(map->off_arr);
+- bpf_map_free_kptr_off_tab(map);
+ bpf_map_release_memcg(map);
+- /* implementation dependent freeing */
++ /* implementation dependent freeing, map_free callback also does
++ * bpf_map_free_kptr_off_tab, if needed.
++ */
+ map->ops->map_free(map);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From b94aa51777d103e94419f457d5ca53ab949d06db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 12:57:34 +0200
+Subject: bpf, x64: Add predicate for bpf2bpf with tailcalls support in JIT
+
+From: Tony Ambardar <tony.ambardar@gmail.com>
+
+[ Upstream commit 95acd8817e66d031d2e6ee7def3f1e1874819317 ]
+
+The BPF core/verifier is hard-coded to permit mixing bpf2bpf and tail
+calls for only x86-64. Change the logic to instead rely on a new weak
+function 'bool bpf_jit_supports_subprog_tailcalls(void)', which a capable
+JIT backend can override.
+
+Update the x86-64 eBPF JIT to reflect this.
+
+Signed-off-by: Tony Ambardar <Tony.Ambardar@gmail.com>
+[jakub: drop MIPS bits and tweak patch subject]
+Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20220617105735.733938-2-jakub@cloudflare.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/net/bpf_jit_comp.c | 6 ++++++
+ include/linux/filter.h | 1 +
+ kernel/bpf/core.c | 6 ++++++
+ kernel/bpf/verifier.c | 3 ++-
+ 4 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
+index 9ec96d5a8239..124456bb23b9 100644
+--- a/arch/x86/net/bpf_jit_comp.c
++++ b/arch/x86/net/bpf_jit_comp.c
+@@ -2477,3 +2477,9 @@ void *bpf_arch_text_copy(void *dst, void *src, size_t len)
+ return ERR_PTR(-EINVAL);
+ return dst;
+ }
++
++/* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */
++bool bpf_jit_supports_subprog_tailcalls(void)
++{
++ return true;
++}
+diff --git a/include/linux/filter.h b/include/linux/filter.h
+index ed0c0ff42ad5..d9a0db845b50 100644
+--- a/include/linux/filter.h
++++ b/include/linux/filter.h
+@@ -948,6 +948,7 @@ u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
+ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog);
+ void bpf_jit_compile(struct bpf_prog *prog);
+ bool bpf_jit_needs_zext(void);
++bool bpf_jit_supports_subprog_tailcalls(void);
+ bool bpf_jit_supports_kfunc_call(void);
+ bool bpf_helper_changes_pkt_data(void *func);
+
+diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
+index 3adff3831c04..7a1ce697689b 100644
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -2712,6 +2712,12 @@ bool __weak bpf_jit_needs_zext(void)
+ return false;
+ }
+
++/* Return TRUE if the JIT backend supports mixing bpf2bpf and tailcalls. */
++bool __weak bpf_jit_supports_subprog_tailcalls(void)
++{
++ return false;
++}
++
+ bool __weak bpf_jit_supports_kfunc_call(void)
+ {
+ return false;
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index d04147a5efa5..a6d3a8972355 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -5696,7 +5696,8 @@ static bool may_update_sockmap(struct bpf_verifier_env *env, int func_id)
+
+ static bool allow_tail_call_in_subprogs(struct bpf_verifier_env *env)
+ {
+- return env->prog->jit_requested && IS_ENABLED(CONFIG_X86_64);
++ return env->prog->jit_requested &&
++ bpf_jit_supports_subprog_tailcalls();
+ }
+
+ static int check_map_func_compatibility(struct bpf_verifier_env *env,
+--
+2.35.1
+
--- /dev/null
+From ae84b11c25a8d6b9eb6e994e76b7486c0d3683fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 17:26:12 -0700
+Subject: bpf, x86: fix freeing of not-finalized bpf_prog_pack
+
+From: Song Liu <song@kernel.org>
+
+[ Upstream commit 1d5f82d9dd477d5c66e0214a68c3e4f308eadd6d ]
+
+syzbot reported a few issues with bpf_prog_pack [1], [2]. This only happens
+with multiple subprogs. In jit_subprogs(), we first call bpf_int_jit_compile()
+on each sub program. And then, we call it on each sub program again. jit_data
+is not freed in the first call of bpf_int_jit_compile(). Similarly we don't
+call bpf_jit_binary_pack_finalize() in the first call of bpf_int_jit_compile().
+
+If bpf_int_jit_compile() failed for one sub program, we will call
+bpf_jit_binary_pack_finalize() for this sub program. However, we don't have a
+chance to call it for other sub programs. Then we will hit "goto out_free" in
+jit_subprogs(), and call bpf_jit_free on some subprograms that haven't got
+bpf_jit_binary_pack_finalize() yet.
+
+At this point, bpf_jit_binary_pack_free() is called and the whole 2MB page is
+freed erroneously.
+
+Fix this with a custom bpf_jit_free() for x86_64, which calls
+bpf_jit_binary_pack_finalize() if necessary. Also, with custom
+bpf_jit_free(), bpf_prog_aux->use_bpf_prog_pack is not needed any more,
+remove it.
+
+Fixes: 1022a5498f6f ("bpf, x86_64: Use bpf_jit_binary_pack_alloc")
+[1] https://syzkaller.appspot.com/bug?extid=2f649ec6d2eea1495a8f
+[2] https://syzkaller.appspot.com/bug?extid=87f65c75f4a72db05445
+Reported-by: syzbot+2f649ec6d2eea1495a8f@syzkaller.appspotmail.com
+Reported-by: syzbot+87f65c75f4a72db05445@syzkaller.appspotmail.com
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20220706002612.4013790-1-song@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/net/bpf_jit_comp.c | 25 +++++++++++++++++++++++++
+ include/linux/bpf.h | 1 -
+ include/linux/filter.h | 8 ++++++++
+ kernel/bpf/core.c | 29 ++++++++++++-----------------
+ 4 files changed, 45 insertions(+), 18 deletions(-)
+
+diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
+index 124456bb23b9..400117f630b8 100644
+--- a/arch/x86/net/bpf_jit_comp.c
++++ b/arch/x86/net/bpf_jit_comp.c
+@@ -2483,3 +2483,28 @@ bool bpf_jit_supports_subprog_tailcalls(void)
+ {
+ return true;
+ }
++
++void bpf_jit_free(struct bpf_prog *prog)
++{
++ if (prog->jited) {
++ struct x64_jit_data *jit_data = prog->aux->jit_data;
++ struct bpf_binary_header *hdr;
++
++ /*
++ * If we fail the final pass of JIT (from jit_subprogs),
++ * the program may not be finalized yet. Call finalize here
++ * before freeing it.
++ */
++ if (jit_data) {
++ bpf_jit_binary_pack_finalize(prog, jit_data->header,
++ jit_data->rw_header);
++ kvfree(jit_data->addrs);
++ kfree(jit_data);
++ }
++ hdr = bpf_jit_binary_pack_hdr(prog);
++ bpf_jit_binary_pack_free(hdr, NULL);
++ WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(prog));
++ }
++
++ bpf_prog_unlock_free(prog);
++}
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index b5d19a6f7d24..492e114b4e32 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -960,7 +960,6 @@ struct bpf_prog_aux {
+ bool sleepable;
+ bool tail_call_reachable;
+ bool xdp_has_frags;
+- bool use_bpf_prog_pack;
+ /* BTF_KIND_FUNC_PROTO for valid attach_btf_id */
+ const struct btf_type *attach_func_proto;
+ /* function name for valid attach_btf_id */
+diff --git a/include/linux/filter.h b/include/linux/filter.h
+index d9a0db845b50..8fd2e2f58eeb 100644
+--- a/include/linux/filter.h
++++ b/include/linux/filter.h
+@@ -1061,6 +1061,14 @@ u64 bpf_jit_alloc_exec_limit(void);
+ void *bpf_jit_alloc_exec(unsigned long size);
+ void bpf_jit_free_exec(void *addr);
+ void bpf_jit_free(struct bpf_prog *fp);
++struct bpf_binary_header *
++bpf_jit_binary_pack_hdr(const struct bpf_prog *fp);
++
++static inline bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp)
++{
++ return list_empty(&fp->aux->ksym.lnode) ||
++ fp->aux->ksym.lnode.prev == LIST_POISON2;
++}
+
+ struct bpf_binary_header *
+ bpf_jit_binary_pack_alloc(unsigned int proglen, u8 **ro_image,
+diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
+index 7a1ce697689b..483bee45ead5 100644
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -649,12 +649,6 @@ static bool bpf_prog_kallsyms_candidate(const struct bpf_prog *fp)
+ return fp->jited && !bpf_prog_was_classic(fp);
+ }
+
+-static bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp)
+-{
+- return list_empty(&fp->aux->ksym.lnode) ||
+- fp->aux->ksym.lnode.prev == LIST_POISON2;
+-}
+-
+ void bpf_prog_kallsyms_add(struct bpf_prog *fp)
+ {
+ if (!bpf_prog_kallsyms_candidate(fp) ||
+@@ -1149,7 +1143,6 @@ int bpf_jit_binary_pack_finalize(struct bpf_prog *prog,
+ bpf_prog_pack_free(ro_header);
+ return PTR_ERR(ptr);
+ }
+- prog->aux->use_bpf_prog_pack = true;
+ return 0;
+ }
+
+@@ -1173,17 +1166,23 @@ void bpf_jit_binary_pack_free(struct bpf_binary_header *ro_header,
+ bpf_jit_uncharge_modmem(size);
+ }
+
++struct bpf_binary_header *
++bpf_jit_binary_pack_hdr(const struct bpf_prog *fp)
++{
++ unsigned long real_start = (unsigned long)fp->bpf_func;
++ unsigned long addr;
++
++ addr = real_start & BPF_PROG_CHUNK_MASK;
++ return (void *)addr;
++}
++
+ static inline struct bpf_binary_header *
+ bpf_jit_binary_hdr(const struct bpf_prog *fp)
+ {
+ unsigned long real_start = (unsigned long)fp->bpf_func;
+ unsigned long addr;
+
+- if (fp->aux->use_bpf_prog_pack)
+- addr = real_start & BPF_PROG_CHUNK_MASK;
+- else
+- addr = real_start & PAGE_MASK;
+-
++ addr = real_start & PAGE_MASK;
+ return (void *)addr;
+ }
+
+@@ -1196,11 +1195,7 @@ void __weak bpf_jit_free(struct bpf_prog *fp)
+ if (fp->jited) {
+ struct bpf_binary_header *hdr = bpf_jit_binary_hdr(fp);
+
+- if (fp->aux->use_bpf_prog_pack)
+- bpf_jit_binary_pack_free(hdr, NULL /* rw_buffer */);
+- else
+- bpf_jit_binary_free(hdr);
+-
++ bpf_jit_binary_free(hdr);
+ WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(fp));
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 3b85cc7696a3320c5a19eb38ea7256dc68dd0108 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 May 2022 13:59:19 -0700
+Subject: bpf, x86: Generate trampolines from bpf_tramp_links
+
+From: Kui-Feng Lee <kuifeng@fb.com>
+
+[ Upstream commit f7e0beaf39d3868dc700d4954b26cf8443c5d423 ]
+
+Replace struct bpf_tramp_progs with struct bpf_tramp_links to collect
+struct bpf_tramp_link(s) for a trampoline. struct bpf_tramp_link
+extends bpf_link to act as a linked list node.
+
+arch_prepare_bpf_trampoline() accepts a struct bpf_tramp_links to
+collects all bpf_tramp_link(s) that a trampoline should call.
+
+Change BPF trampoline and bpf_struct_ops to pass bpf_tramp_links
+instead of bpf_tramp_progs.
+
+Signed-off-by: Kui-Feng Lee <kuifeng@fb.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20220510205923.3206889-2-kuifeng@fb.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/net/bpf_jit_comp.c | 36 +++++++++--------
+ include/linux/bpf.h | 36 +++++++++++------
+ include/linux/bpf_types.h | 1 +
+ include/uapi/linux/bpf.h | 1 +
+ kernel/bpf/bpf_struct_ops.c | 71 +++++++++++++++++++++++----------
+ kernel/bpf/syscall.c | 23 ++++-------
+ kernel/bpf/trampoline.c | 73 +++++++++++++++++++---------------
+ net/bpf/bpf_dummy_struct_ops.c | 24 ++++++++---
+ tools/bpf/bpftool/link.c | 1 +
+ tools/include/uapi/linux/bpf.h | 1 +
+ 10 files changed, 164 insertions(+), 103 deletions(-)
+
+diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
+index 2dab2816b3f7..9ec96d5a8239 100644
+--- a/arch/x86/net/bpf_jit_comp.c
++++ b/arch/x86/net/bpf_jit_comp.c
+@@ -1777,10 +1777,12 @@ static void restore_regs(const struct btf_func_model *m, u8 **prog, int nr_args,
+ }
+
+ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
+- struct bpf_prog *p, int stack_size, bool save_ret)
++ struct bpf_tramp_link *l, int stack_size,
++ bool save_ret)
+ {
+ u8 *prog = *pprog;
+ u8 *jmp_insn;
++ struct bpf_prog *p = l->link.prog;
+
+ /* arg1: mov rdi, progs[i] */
+ emit_mov_imm64(&prog, BPF_REG_1, (long) p >> 32, (u32) (long) p);
+@@ -1865,14 +1867,14 @@ static int emit_cond_near_jump(u8 **pprog, void *func, void *ip, u8 jmp_cond)
+ }
+
+ static int invoke_bpf(const struct btf_func_model *m, u8 **pprog,
+- struct bpf_tramp_progs *tp, int stack_size,
++ struct bpf_tramp_links *tl, int stack_size,
+ bool save_ret)
+ {
+ int i;
+ u8 *prog = *pprog;
+
+- for (i = 0; i < tp->nr_progs; i++) {
+- if (invoke_bpf_prog(m, &prog, tp->progs[i], stack_size,
++ for (i = 0; i < tl->nr_links; i++) {
++ if (invoke_bpf_prog(m, &prog, tl->links[i], stack_size,
+ save_ret))
+ return -EINVAL;
+ }
+@@ -1881,7 +1883,7 @@ static int invoke_bpf(const struct btf_func_model *m, u8 **pprog,
+ }
+
+ static int invoke_bpf_mod_ret(const struct btf_func_model *m, u8 **pprog,
+- struct bpf_tramp_progs *tp, int stack_size,
++ struct bpf_tramp_links *tl, int stack_size,
+ u8 **branches)
+ {
+ u8 *prog = *pprog;
+@@ -1892,8 +1894,8 @@ static int invoke_bpf_mod_ret(const struct btf_func_model *m, u8 **pprog,
+ */
+ emit_mov_imm32(&prog, false, BPF_REG_0, 0);
+ emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -8);
+- for (i = 0; i < tp->nr_progs; i++) {
+- if (invoke_bpf_prog(m, &prog, tp->progs[i], stack_size, true))
++ for (i = 0; i < tl->nr_links; i++) {
++ if (invoke_bpf_prog(m, &prog, tl->links[i], stack_size, true))
+ return -EINVAL;
+
+ /* mod_ret prog stored return value into [rbp - 8]. Emit:
+@@ -1995,14 +1997,14 @@ static bool is_valid_bpf_tramp_flags(unsigned int flags)
+ */
+ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *image_end,
+ const struct btf_func_model *m, u32 flags,
+- struct bpf_tramp_progs *tprogs,
++ struct bpf_tramp_links *tlinks,
+ void *orig_call)
+ {
+ int ret, i, nr_args = m->nr_args;
+ int regs_off, ip_off, args_off, stack_size = nr_args * 8;
+- struct bpf_tramp_progs *fentry = &tprogs[BPF_TRAMP_FENTRY];
+- struct bpf_tramp_progs *fexit = &tprogs[BPF_TRAMP_FEXIT];
+- struct bpf_tramp_progs *fmod_ret = &tprogs[BPF_TRAMP_MODIFY_RETURN];
++ struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY];
++ struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT];
++ struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN];
+ u8 **branches = NULL;
+ u8 *prog;
+ bool save_ret;
+@@ -2093,13 +2095,13 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
+ }
+ }
+
+- if (fentry->nr_progs)
++ if (fentry->nr_links)
+ if (invoke_bpf(m, &prog, fentry, regs_off,
+ flags & BPF_TRAMP_F_RET_FENTRY_RET))
+ return -EINVAL;
+
+- if (fmod_ret->nr_progs) {
+- branches = kcalloc(fmod_ret->nr_progs, sizeof(u8 *),
++ if (fmod_ret->nr_links) {
++ branches = kcalloc(fmod_ret->nr_links, sizeof(u8 *),
+ GFP_KERNEL);
+ if (!branches)
+ return -ENOMEM;
+@@ -2126,7 +2128,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
+ prog += X86_PATCH_SIZE;
+ }
+
+- if (fmod_ret->nr_progs) {
++ if (fmod_ret->nr_links) {
+ /* From Intel 64 and IA-32 Architectures Optimization
+ * Reference Manual, 3.4.1.4 Code Alignment, Assembly/Compiler
+ * Coding Rule 11: All branch targets should be 16-byte
+@@ -2136,12 +2138,12 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
+ /* Update the branches saved in invoke_bpf_mod_ret with the
+ * aligned address of do_fexit.
+ */
+- for (i = 0; i < fmod_ret->nr_progs; i++)
++ for (i = 0; i < fmod_ret->nr_links; i++)
+ emit_cond_near_jump(&branches[i], prog, branches[i],
+ X86_JNE);
+ }
+
+- if (fexit->nr_progs)
++ if (fexit->nr_links)
+ if (invoke_bpf(m, &prog, fexit, regs_off, false)) {
+ ret = -EINVAL;
+ goto cleanup;
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 83bd5598ec4d..b5d19a6f7d24 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -674,11 +674,11 @@ struct btf_func_model {
+ /* Each call __bpf_prog_enter + call bpf_func + call __bpf_prog_exit is ~50
+ * bytes on x86.
+ */
+-#define BPF_MAX_TRAMP_PROGS 38
++#define BPF_MAX_TRAMP_LINKS 38
+
+-struct bpf_tramp_progs {
+- struct bpf_prog *progs[BPF_MAX_TRAMP_PROGS];
+- int nr_progs;
++struct bpf_tramp_links {
++ struct bpf_tramp_link *links[BPF_MAX_TRAMP_LINKS];
++ int nr_links;
+ };
+
+ /* Different use cases for BPF trampoline:
+@@ -704,7 +704,7 @@ struct bpf_tramp_progs {
+ struct bpf_tramp_image;
+ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *tr, void *image, void *image_end,
+ const struct btf_func_model *m, u32 flags,
+- struct bpf_tramp_progs *tprogs,
++ struct bpf_tramp_links *tlinks,
+ void *orig_call);
+ /* these two functions are called from generated trampoline */
+ u64 notrace __bpf_prog_enter(struct bpf_prog *prog);
+@@ -803,9 +803,10 @@ static __always_inline __nocfi unsigned int bpf_dispatcher_nop_func(
+ {
+ return bpf_func(ctx, insnsi);
+ }
++
+ #ifdef CONFIG_BPF_JIT
+-int bpf_trampoline_link_prog(struct bpf_prog *prog, struct bpf_trampoline *tr);
+-int bpf_trampoline_unlink_prog(struct bpf_prog *prog, struct bpf_trampoline *tr);
++int bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr);
++int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr);
+ struct bpf_trampoline *bpf_trampoline_get(u64 key,
+ struct bpf_attach_target_info *tgt_info);
+ void bpf_trampoline_put(struct bpf_trampoline *tr);
+@@ -856,12 +857,12 @@ int bpf_jit_charge_modmem(u32 size);
+ void bpf_jit_uncharge_modmem(u32 size);
+ bool bpf_prog_has_trampoline(const struct bpf_prog *prog);
+ #else
+-static inline int bpf_trampoline_link_prog(struct bpf_prog *prog,
++static inline int bpf_trampoline_link_prog(struct bpf_tramp_link *link,
+ struct bpf_trampoline *tr)
+ {
+ return -ENOTSUPP;
+ }
+-static inline int bpf_trampoline_unlink_prog(struct bpf_prog *prog,
++static inline int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
+ struct bpf_trampoline *tr)
+ {
+ return -ENOTSUPP;
+@@ -960,7 +961,6 @@ struct bpf_prog_aux {
+ bool tail_call_reachable;
+ bool xdp_has_frags;
+ bool use_bpf_prog_pack;
+- struct hlist_node tramp_hlist;
+ /* BTF_KIND_FUNC_PROTO for valid attach_btf_id */
+ const struct btf_type *attach_func_proto;
+ /* function name for valid attach_btf_id */
+@@ -1047,6 +1047,18 @@ struct bpf_link_ops {
+ struct bpf_link_info *info);
+ };
+
++struct bpf_tramp_link {
++ struct bpf_link link;
++ struct hlist_node tramp_hlist;
++};
++
++struct bpf_tracing_link {
++ struct bpf_tramp_link link;
++ enum bpf_attach_type attach_type;
++ struct bpf_trampoline *trampoline;
++ struct bpf_prog *tgt_prog;
++};
++
+ struct bpf_link_primer {
+ struct bpf_link *link;
+ struct file *file;
+@@ -1084,8 +1096,8 @@ bool bpf_struct_ops_get(const void *kdata);
+ void bpf_struct_ops_put(const void *kdata);
+ int bpf_struct_ops_map_sys_lookup_elem(struct bpf_map *map, void *key,
+ void *value);
+-int bpf_struct_ops_prepare_trampoline(struct bpf_tramp_progs *tprogs,
+- struct bpf_prog *prog,
++int bpf_struct_ops_prepare_trampoline(struct bpf_tramp_links *tlinks,
++ struct bpf_tramp_link *link,
+ const struct btf_func_model *model,
+ void *image, void *image_end);
+ static inline bool bpf_try_module_get(const void *data, struct module *owner)
+diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
+index 3e24ad0c4b3c..2b9112b80171 100644
+--- a/include/linux/bpf_types.h
++++ b/include/linux/bpf_types.h
+@@ -141,3 +141,4 @@ BPF_LINK_TYPE(BPF_LINK_TYPE_XDP, xdp)
+ BPF_LINK_TYPE(BPF_LINK_TYPE_PERF_EVENT, perf)
+ #endif
+ BPF_LINK_TYPE(BPF_LINK_TYPE_KPROBE_MULTI, kprobe_multi)
++BPF_LINK_TYPE(BPF_LINK_TYPE_STRUCT_OPS, struct_ops)
+diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
+index d14b10b85e51..a4f557338af7 100644
+--- a/include/uapi/linux/bpf.h
++++ b/include/uapi/linux/bpf.h
+@@ -1013,6 +1013,7 @@ enum bpf_link_type {
+ BPF_LINK_TYPE_XDP = 6,
+ BPF_LINK_TYPE_PERF_EVENT = 7,
+ BPF_LINK_TYPE_KPROBE_MULTI = 8,
++ BPF_LINK_TYPE_STRUCT_OPS = 9,
+
+ MAX_BPF_LINK_TYPE,
+ };
+diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c
+index 21069dbe9138..310b0591d91f 100644
+--- a/kernel/bpf/bpf_struct_ops.c
++++ b/kernel/bpf/bpf_struct_ops.c
+@@ -32,15 +32,15 @@ struct bpf_struct_ops_map {
+ const struct bpf_struct_ops *st_ops;
+ /* protect map_update */
+ struct mutex lock;
+- /* progs has all the bpf_prog that is populated
++ /* link has all the bpf_links that is populated
+ * to the func ptr of the kernel's struct
+ * (in kvalue.data).
+ */
+- struct bpf_prog **progs;
++ struct bpf_link **links;
+ /* image is a page that has all the trampolines
+ * that stores the func args before calling the bpf_prog.
+ * A PAGE_SIZE "image" is enough to store all trampoline for
+- * "progs[]".
++ * "links[]".
+ */
+ void *image;
+ /* uvalue->data stores the kernel struct
+@@ -282,9 +282,9 @@ static void bpf_struct_ops_map_put_progs(struct bpf_struct_ops_map *st_map)
+ u32 i;
+
+ for (i = 0; i < btf_type_vlen(t); i++) {
+- if (st_map->progs[i]) {
+- bpf_prog_put(st_map->progs[i]);
+- st_map->progs[i] = NULL;
++ if (st_map->links[i]) {
++ bpf_link_put(st_map->links[i]);
++ st_map->links[i] = NULL;
+ }
+ }
+ }
+@@ -315,18 +315,34 @@ static int check_zero_holes(const struct btf_type *t, void *data)
+ return 0;
+ }
+
+-int bpf_struct_ops_prepare_trampoline(struct bpf_tramp_progs *tprogs,
+- struct bpf_prog *prog,
++static void bpf_struct_ops_link_release(struct bpf_link *link)
++{
++}
++
++static void bpf_struct_ops_link_dealloc(struct bpf_link *link)
++{
++ struct bpf_tramp_link *tlink = container_of(link, struct bpf_tramp_link, link);
++
++ kfree(tlink);
++}
++
++const struct bpf_link_ops bpf_struct_ops_link_lops = {
++ .release = bpf_struct_ops_link_release,
++ .dealloc = bpf_struct_ops_link_dealloc,
++};
++
++int bpf_struct_ops_prepare_trampoline(struct bpf_tramp_links *tlinks,
++ struct bpf_tramp_link *link,
+ const struct btf_func_model *model,
+ void *image, void *image_end)
+ {
+ u32 flags;
+
+- tprogs[BPF_TRAMP_FENTRY].progs[0] = prog;
+- tprogs[BPF_TRAMP_FENTRY].nr_progs = 1;
++ tlinks[BPF_TRAMP_FENTRY].links[0] = link;
++ tlinks[BPF_TRAMP_FENTRY].nr_links = 1;
+ flags = model->ret_size > 0 ? BPF_TRAMP_F_RET_FENTRY_RET : 0;
+ return arch_prepare_bpf_trampoline(NULL, image, image_end,
+- model, flags, tprogs, NULL);
++ model, flags, tlinks, NULL);
+ }
+
+ static int bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
+@@ -337,7 +353,7 @@ static int bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
+ struct bpf_struct_ops_value *uvalue, *kvalue;
+ const struct btf_member *member;
+ const struct btf_type *t = st_ops->type;
+- struct bpf_tramp_progs *tprogs = NULL;
++ struct bpf_tramp_links *tlinks = NULL;
+ void *udata, *kdata;
+ int prog_fd, err = 0;
+ void *image, *image_end;
+@@ -361,8 +377,8 @@ static int bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
+ if (uvalue->state || refcount_read(&uvalue->refcnt))
+ return -EINVAL;
+
+- tprogs = kcalloc(BPF_TRAMP_MAX, sizeof(*tprogs), GFP_KERNEL);
+- if (!tprogs)
++ tlinks = kcalloc(BPF_TRAMP_MAX, sizeof(*tlinks), GFP_KERNEL);
++ if (!tlinks)
+ return -ENOMEM;
+
+ uvalue = (struct bpf_struct_ops_value *)st_map->uvalue;
+@@ -385,6 +401,7 @@ static int bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
+ for_each_member(i, t, member) {
+ const struct btf_type *mtype, *ptype;
+ struct bpf_prog *prog;
++ struct bpf_tramp_link *link;
+ u32 moff;
+
+ moff = __btf_member_bit_offset(t, member) / 8;
+@@ -438,16 +455,26 @@ static int bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
+ err = PTR_ERR(prog);
+ goto reset_unlock;
+ }
+- st_map->progs[i] = prog;
+
+ if (prog->type != BPF_PROG_TYPE_STRUCT_OPS ||
+ prog->aux->attach_btf_id != st_ops->type_id ||
+ prog->expected_attach_type != i) {
++ bpf_prog_put(prog);
+ err = -EINVAL;
+ goto reset_unlock;
+ }
+
+- err = bpf_struct_ops_prepare_trampoline(tprogs, prog,
++ link = kzalloc(sizeof(*link), GFP_USER);
++ if (!link) {
++ bpf_prog_put(prog);
++ err = -ENOMEM;
++ goto reset_unlock;
++ }
++ bpf_link_init(&link->link, BPF_LINK_TYPE_STRUCT_OPS,
++ &bpf_struct_ops_link_lops, prog);
++ st_map->links[i] = &link->link;
++
++ err = bpf_struct_ops_prepare_trampoline(tlinks, link,
+ &st_ops->func_models[i],
+ image, image_end);
+ if (err < 0)
+@@ -490,7 +517,7 @@ static int bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
+ memset(uvalue, 0, map->value_size);
+ memset(kvalue, 0, map->value_size);
+ unlock:
+- kfree(tprogs);
++ kfree(tlinks);
+ mutex_unlock(&st_map->lock);
+ return err;
+ }
+@@ -545,9 +572,9 @@ static void bpf_struct_ops_map_free(struct bpf_map *map)
+ {
+ struct bpf_struct_ops_map *st_map = (struct bpf_struct_ops_map *)map;
+
+- if (st_map->progs)
++ if (st_map->links)
+ bpf_struct_ops_map_put_progs(st_map);
+- bpf_map_area_free(st_map->progs);
++ bpf_map_area_free(st_map->links);
+ bpf_jit_free_exec(st_map->image);
+ bpf_map_area_free(st_map->uvalue);
+ bpf_map_area_free(st_map);
+@@ -596,11 +623,11 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
+ map = &st_map->map;
+
+ st_map->uvalue = bpf_map_area_alloc(vt->size, NUMA_NO_NODE);
+- st_map->progs =
+- bpf_map_area_alloc(btf_type_vlen(t) * sizeof(struct bpf_prog *),
++ st_map->links =
++ bpf_map_area_alloc(btf_type_vlen(t) * sizeof(struct bpf_links *),
+ NUMA_NO_NODE);
+ st_map->image = bpf_jit_alloc_exec(PAGE_SIZE);
+- if (!st_map->uvalue || !st_map->progs || !st_map->image) {
++ if (!st_map->uvalue || !st_map->links || !st_map->image) {
+ bpf_struct_ops_map_free(map);
+ return ERR_PTR(-ENOMEM);
+ }
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index cdaa1152436a..3078c0c9317f 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -2640,19 +2640,12 @@ struct bpf_link *bpf_link_get_from_fd(u32 ufd)
+ }
+ EXPORT_SYMBOL(bpf_link_get_from_fd);
+
+-struct bpf_tracing_link {
+- struct bpf_link link;
+- enum bpf_attach_type attach_type;
+- struct bpf_trampoline *trampoline;
+- struct bpf_prog *tgt_prog;
+-};
+-
+ static void bpf_tracing_link_release(struct bpf_link *link)
+ {
+ struct bpf_tracing_link *tr_link =
+- container_of(link, struct bpf_tracing_link, link);
++ container_of(link, struct bpf_tracing_link, link.link);
+
+- WARN_ON_ONCE(bpf_trampoline_unlink_prog(link->prog,
++ WARN_ON_ONCE(bpf_trampoline_unlink_prog(&tr_link->link,
+ tr_link->trampoline));
+
+ bpf_trampoline_put(tr_link->trampoline);
+@@ -2665,7 +2658,7 @@ static void bpf_tracing_link_release(struct bpf_link *link)
+ static void bpf_tracing_link_dealloc(struct bpf_link *link)
+ {
+ struct bpf_tracing_link *tr_link =
+- container_of(link, struct bpf_tracing_link, link);
++ container_of(link, struct bpf_tracing_link, link.link);
+
+ kfree(tr_link);
+ }
+@@ -2674,7 +2667,7 @@ static void bpf_tracing_link_show_fdinfo(const struct bpf_link *link,
+ struct seq_file *seq)
+ {
+ struct bpf_tracing_link *tr_link =
+- container_of(link, struct bpf_tracing_link, link);
++ container_of(link, struct bpf_tracing_link, link.link);
+
+ seq_printf(seq,
+ "attach_type:\t%d\n",
+@@ -2685,7 +2678,7 @@ static int bpf_tracing_link_fill_link_info(const struct bpf_link *link,
+ struct bpf_link_info *info)
+ {
+ struct bpf_tracing_link *tr_link =
+- container_of(link, struct bpf_tracing_link, link);
++ container_of(link, struct bpf_tracing_link, link.link);
+
+ info->tracing.attach_type = tr_link->attach_type;
+ bpf_trampoline_unpack_key(tr_link->trampoline->key,
+@@ -2766,7 +2759,7 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
+ err = -ENOMEM;
+ goto out_put_prog;
+ }
+- bpf_link_init(&link->link, BPF_LINK_TYPE_TRACING,
++ bpf_link_init(&link->link.link, BPF_LINK_TYPE_TRACING,
+ &bpf_tracing_link_lops, prog);
+ link->attach_type = prog->expected_attach_type;
+
+@@ -2836,11 +2829,11 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
+ tgt_prog = prog->aux->dst_prog;
+ }
+
+- err = bpf_link_prime(&link->link, &link_primer);
++ err = bpf_link_prime(&link->link.link, &link_primer);
+ if (err)
+ goto out_unlock;
+
+- err = bpf_trampoline_link_prog(prog, tr);
++ err = bpf_trampoline_link_prog(&link->link, tr);
+ if (err) {
+ bpf_link_cleanup(&link_primer);
+ link = NULL;
+diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
+index 5d8bfb5ef239..e3bcad5a7c68 100644
+--- a/kernel/bpf/trampoline.c
++++ b/kernel/bpf/trampoline.c
+@@ -168,30 +168,30 @@ static int register_fentry(struct bpf_trampoline *tr, void *new_addr)
+ return ret;
+ }
+
+-static struct bpf_tramp_progs *
++static struct bpf_tramp_links *
+ bpf_trampoline_get_progs(const struct bpf_trampoline *tr, int *total, bool *ip_arg)
+ {
+- const struct bpf_prog_aux *aux;
+- struct bpf_tramp_progs *tprogs;
+- struct bpf_prog **progs;
++ struct bpf_tramp_link *link;
++ struct bpf_tramp_links *tlinks;
++ struct bpf_tramp_link **links;
+ int kind;
+
+ *total = 0;
+- tprogs = kcalloc(BPF_TRAMP_MAX, sizeof(*tprogs), GFP_KERNEL);
+- if (!tprogs)
++ tlinks = kcalloc(BPF_TRAMP_MAX, sizeof(*tlinks), GFP_KERNEL);
++ if (!tlinks)
+ return ERR_PTR(-ENOMEM);
+
+ for (kind = 0; kind < BPF_TRAMP_MAX; kind++) {
+- tprogs[kind].nr_progs = tr->progs_cnt[kind];
++ tlinks[kind].nr_links = tr->progs_cnt[kind];
+ *total += tr->progs_cnt[kind];
+- progs = tprogs[kind].progs;
++ links = tlinks[kind].links;
+
+- hlist_for_each_entry(aux, &tr->progs_hlist[kind], tramp_hlist) {
+- *ip_arg |= aux->prog->call_get_func_ip;
+- *progs++ = aux->prog;
++ hlist_for_each_entry(link, &tr->progs_hlist[kind], tramp_hlist) {
++ *ip_arg |= link->link.prog->call_get_func_ip;
++ *links++ = link;
+ }
+ }
+- return tprogs;
++ return tlinks;
+ }
+
+ static void __bpf_tramp_image_put_deferred(struct work_struct *work)
+@@ -330,14 +330,14 @@ static struct bpf_tramp_image *bpf_tramp_image_alloc(u64 key, u32 idx)
+ static int bpf_trampoline_update(struct bpf_trampoline *tr)
+ {
+ struct bpf_tramp_image *im;
+- struct bpf_tramp_progs *tprogs;
++ struct bpf_tramp_links *tlinks;
+ u32 flags = BPF_TRAMP_F_RESTORE_REGS;
+ bool ip_arg = false;
+ int err, total;
+
+- tprogs = bpf_trampoline_get_progs(tr, &total, &ip_arg);
+- if (IS_ERR(tprogs))
+- return PTR_ERR(tprogs);
++ tlinks = bpf_trampoline_get_progs(tr, &total, &ip_arg);
++ if (IS_ERR(tlinks))
++ return PTR_ERR(tlinks);
+
+ if (total == 0) {
+ err = unregister_fentry(tr, tr->cur_image->image);
+@@ -353,15 +353,15 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr)
+ goto out;
+ }
+
+- if (tprogs[BPF_TRAMP_FEXIT].nr_progs ||
+- tprogs[BPF_TRAMP_MODIFY_RETURN].nr_progs)
++ if (tlinks[BPF_TRAMP_FEXIT].nr_links ||
++ tlinks[BPF_TRAMP_MODIFY_RETURN].nr_links)
+ flags = BPF_TRAMP_F_CALL_ORIG | BPF_TRAMP_F_SKIP_FRAME;
+
+ if (ip_arg)
+ flags |= BPF_TRAMP_F_IP_ARG;
+
+ err = arch_prepare_bpf_trampoline(im, im->image, im->image + PAGE_SIZE,
+- &tr->func.model, flags, tprogs,
++ &tr->func.model, flags, tlinks,
+ tr->func.addr);
+ if (err < 0)
+ goto out;
+@@ -381,7 +381,7 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr)
+ tr->cur_image = im;
+ tr->selector++;
+ out:
+- kfree(tprogs);
++ kfree(tlinks);
+ return err;
+ }
+
+@@ -407,13 +407,14 @@ static enum bpf_tramp_prog_type bpf_attach_type_to_tramp(struct bpf_prog *prog)
+ }
+ }
+
+-int bpf_trampoline_link_prog(struct bpf_prog *prog, struct bpf_trampoline *tr)
++int bpf_trampoline_link_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr)
+ {
+ enum bpf_tramp_prog_type kind;
++ struct bpf_tramp_link *link_exiting;
+ int err = 0;
+ int cnt = 0, i;
+
+- kind = bpf_attach_type_to_tramp(prog);
++ kind = bpf_attach_type_to_tramp(link->link.prog);
+ mutex_lock(&tr->mutex);
+ if (tr->extension_prog) {
+ /* cannot attach fentry/fexit if extension prog is attached.
+@@ -432,25 +433,33 @@ int bpf_trampoline_link_prog(struct bpf_prog *prog, struct bpf_trampoline *tr)
+ err = -EBUSY;
+ goto out;
+ }
+- tr->extension_prog = prog;
++ tr->extension_prog = link->link.prog;
+ err = bpf_arch_text_poke(tr->func.addr, BPF_MOD_JUMP, NULL,
+- prog->bpf_func);
++ link->link.prog->bpf_func);
+ goto out;
+ }
+- if (cnt >= BPF_MAX_TRAMP_PROGS) {
++ if (cnt >= BPF_MAX_TRAMP_LINKS) {
+ err = -E2BIG;
+ goto out;
+ }
+- if (!hlist_unhashed(&prog->aux->tramp_hlist)) {
++ if (!hlist_unhashed(&link->tramp_hlist)) {
+ /* prog already linked */
+ err = -EBUSY;
+ goto out;
+ }
+- hlist_add_head(&prog->aux->tramp_hlist, &tr->progs_hlist[kind]);
++ hlist_for_each_entry(link_exiting, &tr->progs_hlist[kind], tramp_hlist) {
++ if (link_exiting->link.prog != link->link.prog)
++ continue;
++ /* prog already linked */
++ err = -EBUSY;
++ goto out;
++ }
++
++ hlist_add_head(&link->tramp_hlist, &tr->progs_hlist[kind]);
+ tr->progs_cnt[kind]++;
+ err = bpf_trampoline_update(tr);
+ if (err) {
+- hlist_del_init(&prog->aux->tramp_hlist);
++ hlist_del_init(&link->tramp_hlist);
+ tr->progs_cnt[kind]--;
+ }
+ out:
+@@ -459,12 +468,12 @@ int bpf_trampoline_link_prog(struct bpf_prog *prog, struct bpf_trampoline *tr)
+ }
+
+ /* bpf_trampoline_unlink_prog() should never fail. */
+-int bpf_trampoline_unlink_prog(struct bpf_prog *prog, struct bpf_trampoline *tr)
++int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_trampoline *tr)
+ {
+ enum bpf_tramp_prog_type kind;
+ int err;
+
+- kind = bpf_attach_type_to_tramp(prog);
++ kind = bpf_attach_type_to_tramp(link->link.prog);
+ mutex_lock(&tr->mutex);
+ if (kind == BPF_TRAMP_REPLACE) {
+ WARN_ON_ONCE(!tr->extension_prog);
+@@ -473,7 +482,7 @@ int bpf_trampoline_unlink_prog(struct bpf_prog *prog, struct bpf_trampoline *tr)
+ tr->extension_prog = NULL;
+ goto out;
+ }
+- hlist_del_init(&prog->aux->tramp_hlist);
++ hlist_del_init(&link->tramp_hlist);
+ tr->progs_cnt[kind]--;
+ err = bpf_trampoline_update(tr);
+ out:
+@@ -641,7 +650,7 @@ void notrace __bpf_tramp_exit(struct bpf_tramp_image *tr)
+ int __weak
+ arch_prepare_bpf_trampoline(struct bpf_tramp_image *tr, void *image, void *image_end,
+ const struct btf_func_model *m, u32 flags,
+- struct bpf_tramp_progs *tprogs,
++ struct bpf_tramp_links *tlinks,
+ void *orig_call)
+ {
+ return -ENOTSUPP;
+diff --git a/net/bpf/bpf_dummy_struct_ops.c b/net/bpf/bpf_dummy_struct_ops.c
+index d0e54e30658a..e78dadfc5829 100644
+--- a/net/bpf/bpf_dummy_struct_ops.c
++++ b/net/bpf/bpf_dummy_struct_ops.c
+@@ -72,13 +72,16 @@ static int dummy_ops_call_op(void *image, struct bpf_dummy_ops_test_args *args)
+ args->args[3], args->args[4]);
+ }
+
++extern const struct bpf_link_ops bpf_struct_ops_link_lops;
++
+ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
+ union bpf_attr __user *uattr)
+ {
+ const struct bpf_struct_ops *st_ops = &bpf_bpf_dummy_ops;
+ const struct btf_type *func_proto;
+ struct bpf_dummy_ops_test_args *args;
+- struct bpf_tramp_progs *tprogs;
++ struct bpf_tramp_links *tlinks;
++ struct bpf_tramp_link *link = NULL;
+ void *image = NULL;
+ unsigned int op_idx;
+ int prog_ret;
+@@ -92,8 +95,8 @@ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
+ if (IS_ERR(args))
+ return PTR_ERR(args);
+
+- tprogs = kcalloc(BPF_TRAMP_MAX, sizeof(*tprogs), GFP_KERNEL);
+- if (!tprogs) {
++ tlinks = kcalloc(BPF_TRAMP_MAX, sizeof(*tlinks), GFP_KERNEL);
++ if (!tlinks) {
+ err = -ENOMEM;
+ goto out;
+ }
+@@ -105,8 +108,17 @@ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
+ }
+ set_vm_flush_reset_perms(image);
+
++ link = kzalloc(sizeof(*link), GFP_USER);
++ if (!link) {
++ err = -ENOMEM;
++ goto out;
++ }
++ /* prog doesn't take the ownership of the reference from caller */
++ bpf_prog_inc(prog);
++ bpf_link_init(&link->link, BPF_LINK_TYPE_STRUCT_OPS, &bpf_struct_ops_link_lops, prog);
++
+ op_idx = prog->expected_attach_type;
+- err = bpf_struct_ops_prepare_trampoline(tprogs, prog,
++ err = bpf_struct_ops_prepare_trampoline(tlinks, link,
+ &st_ops->func_models[op_idx],
+ image, image + PAGE_SIZE);
+ if (err < 0)
+@@ -124,7 +136,9 @@ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
+ out:
+ kfree(args);
+ bpf_jit_free_exec(image);
+- kfree(tprogs);
++ if (link)
++ bpf_link_put(&link->link);
++ kfree(tlinks);
+ return err;
+ }
+
+diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c
+index 8fb0116f9136..6353a789322b 100644
+--- a/tools/bpf/bpftool/link.c
++++ b/tools/bpf/bpftool/link.c
+@@ -23,6 +23,7 @@ static const char * const link_type_name[] = {
+ [BPF_LINK_TYPE_XDP] = "xdp",
+ [BPF_LINK_TYPE_PERF_EVENT] = "perf_event",
+ [BPF_LINK_TYPE_KPROBE_MULTI] = "kprobe_multi",
++ [BPF_LINK_TYPE_STRUCT_OPS] = "struct_ops",
+ };
+
+ static struct hashmap *link_table;
+diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
+index d14b10b85e51..a4f557338af7 100644
+--- a/tools/include/uapi/linux/bpf.h
++++ b/tools/include/uapi/linux/bpf.h
+@@ -1013,6 +1013,7 @@ enum bpf_link_type {
+ BPF_LINK_TYPE_XDP = 6,
+ BPF_LINK_TYPE_PERF_EVENT = 7,
+ BPF_LINK_TYPE_KPROBE_MULTI = 8,
++ BPF_LINK_TYPE_STRUCT_OPS = 9,
+
+ MAX_BPF_LINK_TYPE,
+ };
+--
+2.35.1
+
--- /dev/null
+From 72edf8ad4adc36e26fc03eca6d6bb356430b6a6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 31 Mar 2022 11:45:54 -0400
+Subject: bpftool: Add missing link types
+
+From: Milan Landaverde <milan@mdaverde.com>
+
+[ Upstream commit fff3dfab17866f6ac5c5666839f6132b6c52f306 ]
+
+Will display the link type names in bpftool link show output
+
+Signed-off-by: Milan Landaverde <milan@mdaverde.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20220331154555.422506-3-milan@mdaverde.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/link.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c
+index 97dec81950e5..8fb0116f9136 100644
+--- a/tools/bpf/bpftool/link.c
++++ b/tools/bpf/bpftool/link.c
+@@ -20,6 +20,9 @@ static const char * const link_type_name[] = {
+ [BPF_LINK_TYPE_CGROUP] = "cgroup",
+ [BPF_LINK_TYPE_ITER] = "iter",
+ [BPF_LINK_TYPE_NETNS] = "netns",
++ [BPF_LINK_TYPE_XDP] = "xdp",
++ [BPF_LINK_TYPE_PERF_EVENT] = "perf_event",
++ [BPF_LINK_TYPE_KPROBE_MULTI] = "kprobe_multi",
+ };
+
+ static struct hashmap *link_table;
+--
+2.35.1
+
--- /dev/null
+From 576bcccfb96e8d3bbd5fe8a556f8c8f200e45fab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 17:43:52 +0800
+Subject: bus: hisi_lpc: fix missing platform_device_put() in
+ hisi_lpc_acpi_probe()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 54872fea6a5ac967ec2272aea525d1438ac6735a ]
+
+In error case in hisi_lpc_acpi_probe() after calling platform_device_add(),
+hisi_lpc_acpi_remove() can't release the failed 'pdev', so it will be leak,
+call platform_device_put() to fix this problem.
+I'v constructed this error case and tested this patch on D05 board.
+
+Fixes: 99c0228d6ff1 ("HISI LPC: Re-Add ACPI child enumeration support")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Acked-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/hisi_lpc.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/bus/hisi_lpc.c b/drivers/bus/hisi_lpc.c
+index 378f5d62a991..e7eaa8784fee 100644
+--- a/drivers/bus/hisi_lpc.c
++++ b/drivers/bus/hisi_lpc.c
+@@ -503,13 +503,13 @@ static int hisi_lpc_acpi_probe(struct device *hostdev)
+ {
+ struct acpi_device *adev = ACPI_COMPANION(hostdev);
+ struct acpi_device *child;
++ struct platform_device *pdev;
+ int ret;
+
+ /* Only consider the children of the host */
+ list_for_each_entry(child, &adev->children, node) {
+ const char *hid = acpi_device_hid(child);
+ const struct hisi_lpc_acpi_cell *cell;
+- struct platform_device *pdev;
+ const struct resource *res;
+ bool found = false;
+ int num_res;
+@@ -571,22 +571,24 @@ static int hisi_lpc_acpi_probe(struct device *hostdev)
+
+ ret = platform_device_add_resources(pdev, res, num_res);
+ if (ret)
+- goto fail;
++ goto fail_put_device;
+
+ ret = platform_device_add_data(pdev, cell->pdata,
+ cell->pdata_size);
+ if (ret)
+- goto fail;
++ goto fail_put_device;
+
+ ret = platform_device_add(pdev);
+ if (ret)
+- goto fail;
++ goto fail_put_device;
+
+ acpi_device_set_enumerated(child);
+ }
+
+ return 0;
+
++fail_put_device:
++ platform_device_put(pdev);
+ fail:
+ hisi_lpc_acpi_remove(hostdev);
+ return ret;
+--
+2.35.1
+
--- /dev/null
+From 41abebc9fdbe3b3b4728cfb308af6fed88892d1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:48 +0900
+Subject: can: error: specify the values of data[5..7] of CAN error frames
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit e70a3263a7eed768d5f947b8f2aff8d2a79c9d97 ]
+
+Currently, data[5..7] of struct can_frame, when used as a CAN error
+frame, are defined as being "controller specific". Device specific
+behaviours are problematic because it prevents someone from writing
+code which is portable between devices.
+
+As a matter of fact, data[5] is never used, data[6] is always used to
+report TX error counter and data[7] is always used to report RX error
+counter. can-utils also relies on this.
+
+This patch updates the comment in the uapi header to specify that
+data[5] is reserved (and thus should not be used) and that data[6..7]
+are used for error counters.
+
+Fixes: 0d66548a10cb ("[CAN]: Add PF_CAN core module")
+Link: https://lore.kernel.org/all/20220719143550.3681-11-mailhol.vincent@wanadoo.fr
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/can/error.h | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/include/uapi/linux/can/error.h b/include/uapi/linux/can/error.h
+index 34633283de64..a1000cb63063 100644
+--- a/include/uapi/linux/can/error.h
++++ b/include/uapi/linux/can/error.h
+@@ -120,6 +120,9 @@
+ #define CAN_ERR_TRX_CANL_SHORT_TO_GND 0x70 /* 0111 0000 */
+ #define CAN_ERR_TRX_CANL_SHORT_TO_CANH 0x80 /* 1000 0000 */
+
+-/* controller specific additional information / data[5..7] */
++/* data[5] is reserved (do not use) */
++
++/* TX error counter / data[6] */
++/* RX error counter / data[7] */
+
+ #endif /* _UAPI_CAN_ERROR_H */
+--
+2.35.1
+
--- /dev/null
+From d15dd4ed91d48db214f26e5470260d8b70d018c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:43 +0900
+Subject: can: hi311x: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit a22bd630cfff496b270211745536e50e98eb3a45 ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: 57e83fb9b746 ("can: hi311x: Add Holt HI-311x CAN driver")
+Link: https://lore.kernel.org/all/20220719143550.3681-6-mailhol.vincent@wanadoo.fr
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/spi/hi311x.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
+index a5b2952b8d0f..7dc88a9eca0f 100644
+--- a/drivers/net/can/spi/hi311x.c
++++ b/drivers/net/can/spi/hi311x.c
+@@ -672,8 +672,6 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
+
+ txerr = hi3110_read(spi, HI3110_READ_TEC);
+ rxerr = hi3110_read(spi, HI3110_READ_REC);
+- cf->data[6] = txerr;
+- cf->data[7] = rxerr;
+ tx_state = txerr >= rxerr ? new_state : 0;
+ rx_state = txerr <= rxerr ? new_state : 0;
+ can_change_state(net, cf, tx_state, rx_state);
+@@ -686,6 +684,9 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
+ hi3110_hw_sleep(spi);
+ break;
+ }
++ } else {
++ cf->data[6] = txerr;
++ cf->data[7] = rxerr;
+ }
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 9a5c5c0f333bd1ca8455f2faedfafb874eabc24d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:45 +0900
+Subject: can: kvaser_usb_hydra: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 936e90595376e64b6247c72d3ea8b8b164b7ac96 ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: aec5fb2268b7 ("can: kvaser_usb: Add support for Kvaser USB hydra family")
+Link: https://lore.kernel.org/all/20220719143550.3681-8-mailhol.vincent@wanadoo.fr
+CC: Jimmy Assarsson <extja@kvaser.com>
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+index 5d70844ac030..404093468b2f 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -917,8 +917,10 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
+ new_state < CAN_STATE_BUS_OFF)
+ priv->can.can_stats.restarts++;
+
+- cf->data[6] = bec->txerr;
+- cf->data[7] = bec->rxerr;
++ if (new_state != CAN_STATE_BUS_OFF) {
++ cf->data[6] = bec->txerr;
++ cf->data[7] = bec->rxerr;
++ }
+
+ netif_rx(skb);
+ }
+@@ -1069,8 +1071,10 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
+ shhwtstamps->hwtstamp = hwtstamp;
+
+ cf->can_id |= CAN_ERR_BUSERROR;
+- cf->data[6] = bec.txerr;
+- cf->data[7] = bec.rxerr;
++ if (new_state != CAN_STATE_BUS_OFF) {
++ cf->data[6] = bec.txerr;
++ cf->data[7] = bec.rxerr;
++ }
+
+ netif_rx(skb);
+
+--
+2.35.1
+
--- /dev/null
+From 6a78b546db53be1ccc9f5c45ac17ffa3b9356f25 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:46 +0900
+Subject: can: kvaser_usb_leaf: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit a57732084e06791d37ea1ea447cca46220737abd ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: 7259124eac7d1 ("can: kvaser_usb: Split driver into kvaser_usb_core.c and kvaser_usb_leaf.c")
+Link: https://lore.kernel.org/all/20220719143550.3681-9-mailhol.vincent@wanadoo.fr
+CC: Jimmy Assarsson <extja@kvaser.com>
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index cc809ecd1e62..f551fde16a70 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -853,8 +853,10 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+ break;
+ }
+
+- cf->data[6] = es->txerr;
+- cf->data[7] = es->rxerr;
++ if (new_state != CAN_STATE_BUS_OFF) {
++ cf->data[6] = es->txerr;
++ cf->data[7] = es->rxerr;
++ }
+
+ netif_rx(skb);
+ }
+--
+2.35.1
+
--- /dev/null
+From 08364b7c77bb694c3eb198efe9d3c1c15bd6b9bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jun 2022 16:20:58 +0200
+Subject: can: netlink: allow configuring of fixed bit rates without need for
+ do_set_bittiming callback
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 7e193a42c37cf40eba8ac5af2d5e8eeb8b9506f9 ]
+
+Usually CAN devices support configurable bit rates. The limits are
+defined by struct can_priv::bittiming_const. Another way is to
+implement the struct can_priv::do_set_bittiming callback.
+
+If the bit rate is configured via netlink, the can_changelink()
+function checks that either can_priv::bittiming_const or struct
+can_priv::do_set_bittiming is implemented.
+
+In commit 431af779256c ("can: dev: add CAN interface API for fixed
+bitrates") an API for configuring bit rates on CAN interfaces that
+only support fixed bit rates was added. The supported bit rates are
+defined by struct can_priv::bitrate_const.
+
+However the above mentioned commit forgot to add the struct
+can_priv::bitrate_const to the check in can_changelink().
+
+In order to avoid to implement a no-op can_priv::do_set_bittiming
+callback on devices with fixed bit rates, extend the check in
+can_changelink() accordingly.
+
+Link: https://lore.kernel.org/all/20220611144248.3924903-1-mkl@pengutronix.de
+Fixes: 431af779256c ("can: dev: add CAN interface API for fixed bitrates")
+Reported-by: Max Staudt <max@enpas.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/dev/netlink.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
+index 7633d98e3912..667ddd28fcdc 100644
+--- a/drivers/net/can/dev/netlink.c
++++ b/drivers/net/can/dev/netlink.c
+@@ -176,7 +176,8 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
+ * directly via do_set_bitrate(). Bail out if neither
+ * is given.
+ */
+- if (!priv->bittiming_const && !priv->do_set_bittiming)
++ if (!priv->bittiming_const && !priv->do_set_bittiming &&
++ !priv->bitrate_const)
+ return -EOPNOTSUPP;
+
+ memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
+--
+2.35.1
+
--- /dev/null
+From 0d9bdfe8a5ddf3e4b940b29dd43d3ff69c331107 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jun 2022 16:20:58 +0200
+Subject: can: netlink: allow configuring of fixed data bit rates without need
+ for do_set_data_bittiming callback
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit ec30c109391c5eac9b1d689a61e4bfed88148947 ]
+
+This patch is similar to 7e193a42c37c ("can: netlink: allow
+configuring of fixed bit rates without need for do_set_bittiming
+callback") but for data bit rates instead of bit rates.
+
+Usually CAN devices support configurable data bit rates. The limits
+are defined by struct can_priv::data_bittiming_const. Another way is
+to implement the struct can_priv::do_set_data_bittiming callback.
+
+If the bit rate is configured via netlink, the can_changelink()
+function checks that either can_priv::data_bittiming_const or struct
+can_priv::do_set_data_bittiming is implemented.
+
+In commit 431af779256c ("can: dev: add CAN interface API for fixed
+bitrates") an API for configuring bit rates on CAN interfaces that
+only support fixed bit rates was added. The supported bit rates are
+defined by struct can_priv::bitrate_const.
+
+However the above mentioned commit forgot to add the struct
+can_priv::data_bitrate_const to the check in can_changelink().
+
+In order to avoid to implement a no-op can_priv::do_set_data_bittiming
+callback on devices with fixed data bit rates, extend the check in
+can_changelink() accordingly.
+
+Link: https://lore.kernel.org/all/20220613143633.4151884-1-mkl@pengutronix.de
+Fixes: 431af779256c ("can: dev: add CAN interface API for fixed bitrates")
+Acked-by: Max Staudt <max@enpas.org>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/dev/netlink.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
+index 667ddd28fcdc..037824011266 100644
+--- a/drivers/net/can/dev/netlink.c
++++ b/drivers/net/can/dev/netlink.c
+@@ -279,7 +279,8 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
+ * directly via do_set_bitrate(). Bail out if neither
+ * is given.
+ */
+- if (!priv->data_bittiming_const && !priv->do_set_data_bittiming)
++ if (!priv->data_bittiming_const && !priv->do_set_data_bittiming &&
++ !priv->data_bitrate_const)
+ return -EOPNOTSUPP;
+
+ memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
+--
+2.35.1
+
--- /dev/null
+From 5987b7e1ecb32edcd335db8bfc806a5af88aa484 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:39 +0900
+Subject: can: pch_can: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 3a5c7e4611ddcf0ef37a3a17296b964d986161a6 ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: 0c78ab76a05c ("pch_can: Add setting TEC/REC statistics processing")
+Link: https://lore.kernel.org/all/20220719143550.3681-2-mailhol.vincent@wanadoo.fr
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/pch_can.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
+index 888bef03de09..076b1339f806 100644
+--- a/drivers/net/can/pch_can.c
++++ b/drivers/net/can/pch_can.c
+@@ -496,6 +496,9 @@ static void pch_can_error(struct net_device *ndev, u32 status)
+ cf->can_id |= CAN_ERR_BUSOFF;
+ priv->can.can_stats.bus_off++;
+ can_bus_off(ndev);
++ } else {
++ cf->data[6] = errc & PCH_TEC;
++ cf->data[7] = (errc & PCH_REC) >> 8;
+ }
+
+ errc = ioread32(&priv->regs->errc);
+@@ -556,9 +559,6 @@ static void pch_can_error(struct net_device *ndev, u32 status)
+ break;
+ }
+
+- cf->data[6] = errc & PCH_TEC;
+- cf->data[7] = (errc & PCH_REC) >> 8;
+-
+ priv->can.state = state;
+ netif_receive_skb(skb);
+ }
+--
+2.35.1
+
--- /dev/null
+From 5f16195920543a627a3fb56713720b24f418e343 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 01:00:32 +0900
+Subject: can: pch_can: pch_can_error(): initialize errc before using it
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 9950f11211331180269867aef848c7cf56861742 ]
+
+After commit 3a5c7e4611dd, the variable errc is accessed before being
+initialized, c.f. below W=2 warning:
+
+| In function 'pch_can_error',
+| inlined from 'pch_can_poll' at drivers/net/can/pch_can.c:739:4:
+| drivers/net/can/pch_can.c:501:29: warning: 'errc' may be used uninitialized [-Wmaybe-uninitialized]
+| 501 | cf->data[6] = errc & PCH_TEC;
+| | ^
+| drivers/net/can/pch_can.c: In function 'pch_can_poll':
+| drivers/net/can/pch_can.c:484:13: note: 'errc' was declared here
+| 484 | u32 errc, lec;
+| | ^~~~
+
+Moving errc initialization up solves this issue.
+
+Fixes: 3a5c7e4611dd ("can: pch_can: do not report txerr and rxerr during bus-off")
+Reported-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Reviewed-by: Nathan Chancellor <nathan@kernel.org>
+Link: https://lore.kernel.org/all/20220721160032.9348-1-mailhol.vincent@wanadoo.fr
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/pch_can.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
+index 076b1339f806..17f8d67ddb18 100644
+--- a/drivers/net/can/pch_can.c
++++ b/drivers/net/can/pch_can.c
+@@ -489,6 +489,7 @@ static void pch_can_error(struct net_device *ndev, u32 status)
+ if (!skb)
+ return;
+
++ errc = ioread32(&priv->regs->errc);
+ if (status & PCH_BUS_OFF) {
+ pch_can_set_tx_all(priv, 0);
+ pch_can_set_rx_all(priv, 0);
+@@ -501,7 +502,6 @@ static void pch_can_error(struct net_device *ndev, u32 status)
+ cf->data[7] = (errc & PCH_REC) >> 8;
+ }
+
+- errc = ioread32(&priv->regs->errc);
+ /* Warning interrupt. */
+ if (status & PCH_EWARN) {
+ state = CAN_STATE_ERROR_WARNING;
+--
+2.35.1
+
--- /dev/null
+From 32c9bc92d772864e3868056a436a6a1634ebb0d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:40 +0900
+Subject: can: rcar_can: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit a37b7245e831a641df360ca41db6a71c023d3746 ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: fd1159318e55 ("can: add Renesas R-Car CAN driver")
+Link: https://lore.kernel.org/all/20220719143550.3681-3-mailhol.vincent@wanadoo.fr
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/rcar/rcar_can.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
+index 33e37395379d..4ca5b09f1e5d 100644
+--- a/drivers/net/can/rcar/rcar_can.c
++++ b/drivers/net/can/rcar/rcar_can.c
+@@ -233,11 +233,8 @@ static void rcar_can_error(struct net_device *ndev)
+ if (eifr & (RCAR_CAN_EIFR_EWIF | RCAR_CAN_EIFR_EPIF)) {
+ txerr = readb(&priv->regs->tecr);
+ rxerr = readb(&priv->regs->recr);
+- if (skb) {
++ if (skb)
+ cf->can_id |= CAN_ERR_CRTL;
+- cf->data[6] = txerr;
+- cf->data[7] = rxerr;
+- }
+ }
+ if (eifr & RCAR_CAN_EIFR_BEIF) {
+ int rx_errors = 0, tx_errors = 0;
+@@ -337,6 +334,9 @@ static void rcar_can_error(struct net_device *ndev)
+ can_bus_off(ndev);
+ if (skb)
+ cf->can_id |= CAN_ERR_BUSOFF;
++ } else if (skb) {
++ cf->data[6] = txerr;
++ cf->data[7] = rxerr;
+ }
+ if (eifr & RCAR_CAN_EIFR_ORIF) {
+ netdev_dbg(priv->ndev, "Receive overrun error interrupt\n");
+--
+2.35.1
+
--- /dev/null
+From b1b11d186b622b400c25ab6b7bcc1ebcf1b1bffd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:41 +0900
+Subject: can: sja1000: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 164d7cb2d5a30f1b3a5ab4fab1a27731fb1494a8 ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: 215db1856e83 ("can: sja1000: Consolidate and unify state change handling")
+Link: https://lore.kernel.org/all/20220719143550.3681-4-mailhol.vincent@wanadoo.fr
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/sja1000/sja1000.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
+index 966316479485..366a369080ef 100644
+--- a/drivers/net/can/sja1000/sja1000.c
++++ b/drivers/net/can/sja1000/sja1000.c
+@@ -405,9 +405,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
+ txerr = priv->read_reg(priv, SJA1000_TXERR);
+ rxerr = priv->read_reg(priv, SJA1000_RXERR);
+
+- cf->data[6] = txerr;
+- cf->data[7] = rxerr;
+-
+ if (isrc & IRQ_DOI) {
+ /* data overrun interrupt */
+ netdev_dbg(dev, "data overrun interrupt\n");
+@@ -429,6 +426,10 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
+ else
+ state = CAN_STATE_ERROR_ACTIVE;
+ }
++ if (state != CAN_STATE_BUS_OFF) {
++ cf->data[6] = txerr;
++ cf->data[7] = rxerr;
++ }
+ if (isrc & IRQ_BEI) {
+ /* bus error interrupt */
+ priv->can.can_stats.bus_error++;
+--
+2.35.1
+
--- /dev/null
+From 2d3d629aa37d12e80cd94724eae72bc5864583d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:44 +0900
+Subject: can: sun4i_can: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 0ac15a8f661b941519379831d09bfb12271b23ee ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module")
+Link: https://lore.kernel.org/all/20220719143550.3681-7-mailhol.vincent@wanadoo.fr
+CC: Chen-Yu Tsai <wens@csie.org>
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/sun4i_can.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
+index 25d6d81ab4f4..f3ad585e766f 100644
+--- a/drivers/net/can/sun4i_can.c
++++ b/drivers/net/can/sun4i_can.c
+@@ -538,11 +538,6 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+ rxerr = (errc >> 16) & 0xFF;
+ txerr = errc & 0xFF;
+
+- if (skb) {
+- cf->data[6] = txerr;
+- cf->data[7] = rxerr;
+- }
+-
+ if (isrc & SUN4I_INT_DATA_OR) {
+ /* data overrun interrupt */
+ netdev_dbg(dev, "data overrun interrupt\n");
+@@ -573,6 +568,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+ else
+ state = CAN_STATE_ERROR_ACTIVE;
+ }
++ if (skb && state != CAN_STATE_BUS_OFF) {
++ cf->data[6] = txerr;
++ cf->data[7] = rxerr;
++ }
+ if (isrc & SUN4I_INT_BUS_ERR) {
+ /* bus error interrupt */
+ netdev_dbg(dev, "bus error interrupt\n");
+--
+2.35.1
+
--- /dev/null
+From 38399cdced03e5af088ec59450a131dacbc3ce31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 23:35:47 +0900
+Subject: can: usb_8dev: do not report txerr and rxerr during bus-off
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit aebe8a2433cd090ccdc222861f44bddb75eb01de ]
+
+During bus off, the error count is greater than 255 and can not fit in
+a u8.
+
+Fixes: 0024d8ad1639 ("can: usb_8dev: Add support for USB2CAN interface from 8 devices")
+Link: https://lore.kernel.org/all/20220719143550.3681-10-mailhol.vincent@wanadoo.fr
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/usb_8dev.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
+index b638604bf1ee..ea63dc687fdb 100644
+--- a/drivers/net/can/usb/usb_8dev.c
++++ b/drivers/net/can/usb/usb_8dev.c
+@@ -439,9 +439,10 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,
+
+ if (rx_errors)
+ stats->rx_errors++;
+-
+- cf->data[6] = txerr;
+- cf->data[7] = rxerr;
++ if (priv->can.state != CAN_STATE_BUS_OFF) {
++ cf->data[6] = txerr;
++ cf->data[7] = rxerr;
++ }
+
+ priv->bec.txerr = txerr;
+ priv->bec.rxerr = rxerr;
+--
+2.35.1
+
--- /dev/null
+From eddb4b606e7e7fe85ee11e9f6c2e250d6c267c9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 20:06:24 +0100
+Subject: cifs: Fix memory leak when using fscache
+
+From: Matthew Wilcox (Oracle) <willy@infradead.org>
+
+[ Upstream commit c6f62f81b488d00afaa86bae26c6ce9ab12c709e ]
+
+If we hit the 'index == next_cached' case, we leak a refcount on the
+struct page. Fix this by using readahead_folio() which takes care of
+the refcount for you.
+
+Fixes: 0174ee9947bd ("cifs: Implement cache I/O by accessing the cache directly")
+Cc: David Howells <dhowells@redhat.com>
+Cc: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/file.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index 58dce567ceaf..3d475f1847a4 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -4456,10 +4456,10 @@ static void cifs_readahead(struct readahead_control *ractl)
+ * TODO: Send a whole batch of pages to be read
+ * by the cache.
+ */
+- page = readahead_page(ractl);
+- last_batch_size = 1 << thp_order(page);
++ struct folio *folio = readahead_folio(ractl);
++ last_batch_size = folio_nr_pages(folio);
+ if (cifs_readpage_from_fscache(ractl->mapping->host,
+- page) < 0) {
++ &folio->page) < 0) {
+ /*
+ * TODO: Deal with cache read failure
+ * here, but for the moment, delegate
+@@ -4467,7 +4467,7 @@ static void cifs_readahead(struct readahead_control *ractl)
+ */
+ caching = false;
+ }
+- unlock_page(page);
++ folio_unlock(folio);
+ next_cached++;
+ cache_nr_pages--;
+ if (cache_nr_pages == 0)
+--
+2.35.1
+
--- /dev/null
+From 5c89dc4a2d88a026da28e971d9378d64a44d0bdc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 21:29:01 +0800
+Subject: clk: imx: clk-fracn-gppll: correct rdiv
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit f300cb7fccf69ba1835b983c76d70deb818ad194 ]
+
+According to Reference Manual:
+ 000b - Divide by 1
+ 001b - Divide by 1
+ 010b - Divide by 2
+ 011b - Divide by 3
+ 100b - Divide by 4
+ 101b - Divide by 5
+ 110b - Divide by 6
+ 111b - Divide by 7
+
+So only need increase rdiv by 1 when the register value is 0.
+
+Fixes: 1b26cb8a77a4 ("clk: imx: support fracn gppll")
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Jacky Bai <ping.bai@nxp.com>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20220609132902.3504651-7-peng.fan@oss.nxp.com
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-fracn-gppll.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c
+index cb06b0045e9e..025b73229cdd 100644
+--- a/drivers/clk/imx/clk-fracn-gppll.c
++++ b/drivers/clk/imx/clk-fracn-gppll.c
+@@ -149,7 +149,8 @@ static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned lon
+ if (rate)
+ return (unsigned long)rate;
+
+- rdiv = rdiv + 1;
++ if (!rdiv)
++ rdiv = rdiv + 1;
+
+ switch (odiv) {
+ case 0:
+--
+2.35.1
+
--- /dev/null
+From f9ddf98b49877c62df9abb683592409aa6851415 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 21:28:59 +0800
+Subject: clk: imx: clk-fracn-gppll: fix mfd value
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit 044034efbeea05f65c09d2ba15ceeab53b60e947 ]
+
+According to spec:
+A value of 0 is disallowed and should not be programmed in this register
+
+Fix to 1.
+
+Fixes: 1b26cb8a77a4 ("clk: imx: support fracn gppll")
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Jacky Bai <ping.bai@nxp.com>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20220609132902.3504651-5-peng.fan@oss.nxp.com
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-fracn-gppll.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c
+index 71c102d950ab..36a53c60e71f 100644
+--- a/drivers/clk/imx/clk-fracn-gppll.c
++++ b/drivers/clk/imx/clk-fracn-gppll.c
+@@ -64,10 +64,10 @@ struct clk_fracn_gppll {
+ * Fout = Fvco / (rdiv * odiv)
+ */
+ static const struct imx_fracn_gppll_rate_table fracn_tbl[] = {
+- PLL_FRACN_GP(650000000U, 81, 0, 0, 0, 3),
+- PLL_FRACN_GP(594000000U, 198, 0, 0, 0, 8),
+- PLL_FRACN_GP(560000000U, 70, 0, 0, 0, 3),
+- PLL_FRACN_GP(400000000U, 50, 0, 0, 0, 3),
++ PLL_FRACN_GP(650000000U, 81, 0, 1, 0, 3),
++ PLL_FRACN_GP(594000000U, 198, 0, 1, 0, 8),
++ PLL_FRACN_GP(560000000U, 70, 0, 1, 0, 3),
++ PLL_FRACN_GP(400000000U, 50, 0, 1, 0, 3),
+ PLL_FRACN_GP(393216000U, 81, 92, 100, 0, 5)
+ };
+
+--
+2.35.1
+
--- /dev/null
+From d341a919e4f44e63b435f761c954e782d44b9f95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 21:29:00 +0800
+Subject: clk: imx: clk-fracn-gppll: Return rate in rate table properly in
+ ->recalc_rate()
+
+From: Liu Ying <victor.liu@nxp.com>
+
+[ Upstream commit 5ebaf9f7da5bb2dc56d394eabfcbe46dc6b1ea8d ]
+
+The PLL parameters in rate table should be directly compared with
+those read from PLL registers instead of the cooked ones.
+
+Fixes: 1b26cb8a77a4 ("clk: imx: support fracn gppll")
+Cc: Abel Vesa <abel.vesa@nxp.com>
+Cc: Michael Turquette <mturquette@baylibre.com>
+Cc: Stephen Boyd <sboyd@kernel.org>
+Cc: Shawn Guo <shawnguo@kernel.org>
+Cc: Sascha Hauer <s.hauer@pengutronix.de>
+Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
+Cc: Fabio Estevam <festevam@gmail.com>
+Cc: NXP Linux Team <linux-imx@nxp.com>
+Cc: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Liu Ying <victor.liu@nxp.com>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20220609132902.3504651-6-peng.fan@oss.nxp.com
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-fracn-gppll.c | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c
+index 36a53c60e71f..cb06b0045e9e 100644
+--- a/drivers/clk/imx/clk-fracn-gppll.c
++++ b/drivers/clk/imx/clk-fracn-gppll.c
+@@ -131,18 +131,7 @@ static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned lon
+ mfi = FIELD_GET(PLL_MFI_MASK, pll_div);
+
+ rdiv = FIELD_GET(PLL_RDIV_MASK, pll_div);
+- rdiv = rdiv + 1;
+ odiv = FIELD_GET(PLL_ODIV_MASK, pll_div);
+- switch (odiv) {
+- case 0:
+- odiv = 2;
+- break;
+- case 1:
+- odiv = 3;
+- break;
+- default:
+- break;
+- }
+
+ /*
+ * Sometimes, the recalculated rate has deviation due to
+@@ -160,6 +149,19 @@ static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned lon
+ if (rate)
+ return (unsigned long)rate;
+
++ rdiv = rdiv + 1;
++
++ switch (odiv) {
++ case 0:
++ odiv = 2;
++ break;
++ case 1:
++ odiv = 3;
++ break;
++ default:
++ break;
++ }
++
+ /* Fvco = Fref * (MFI + MFN / MFD) */
+ fvco = fvco * mfi * mfd + fvco * mfn;
+ do_div(fvco, mfd * rdiv * odiv);
+--
+2.35.1
+
--- /dev/null
+From 2e417d4f85539e7b78526cd9ddfb974e5b004eee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 21:28:57 +0800
+Subject: clk: imx93: correct nic_media parent
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit 1e3c837a663e9a12c4afabb3279d18cb5110a8f4 ]
+
+NIC_MEDIA sources from media_axi_root, not media_apb_root.
+
+Fixes: 24defbe194b6 ("clk: imx: add i.MX93 clk")
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20220609132902.3504651-3-peng.fan@oss.nxp.com
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx93.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c
+index 172cd56c9610..26885bd3971c 100644
+--- a/drivers/clk/imx/clk-imx93.c
++++ b/drivers/clk/imx/clk-imx93.c
+@@ -219,7 +219,7 @@ static const struct imx93_clk_ccgr {
+ { IMX93_CLK_LCDIF_GATE, "lcdif", "media_apb_root", 0x9640, },
+ { IMX93_CLK_PXP_GATE, "pxp", "media_apb_root", 0x9680, },
+ { IMX93_CLK_ISI_GATE, "isi", "media_apb_root", 0x96c0, },
+- { IMX93_CLK_NIC_MEDIA_GATE, "nic_media", "media_apb_root", 0x9700, },
++ { IMX93_CLK_NIC_MEDIA_GATE, "nic_media", "media_axi_root", 0x9700, },
+ { IMX93_CLK_USB_CONTROLLER_GATE, "usb_controller", "hsio_root", 0x9a00, },
+ { IMX93_CLK_USB_TEST_60M_GATE, "usb_test_60m", "hsio_usb_test_60m_root", 0x9a40, },
+ { IMX93_CLK_HSIO_TROUT_24M_GATE, "hsio_trout_24m", "osc_24m", 0x9a80, },
+--
+2.35.1
+
--- /dev/null
+From 77d5ceb2d264834f49ce3909f659904b24abfc3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 21:28:56 +0800
+Subject: clk: imx93: use adc_root as the parent clock of adc1
+
+From: Haibo Chen <haibo.chen@nxp.com>
+
+[ Upstream commit 18d6d8fe4f24938985844d52c481b86fcce9d102 ]
+
+When debug, find after system boot up, all adc register operation
+will trigger system hang, this is because the internal adc ipg
+clock is gate off. In dts, only reference the IMX93_CLK_ADC1_GATE,
+which is adc1, no one touch the adc_root, so adc_root will be gate
+off automatically after system boot up.
+
+Fixes: 24defbe194b6 ("clk: imx: add i.MX93 clk")
+Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
+Signed-off-by: Jacky Bai <ping.bai@nxp.com>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20220609132902.3504651-2-peng.fan@oss.nxp.com
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx93.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c
+index edcc87661d1f..172cd56c9610 100644
+--- a/drivers/clk/imx/clk-imx93.c
++++ b/drivers/clk/imx/clk-imx93.c
+@@ -150,7 +150,7 @@ static const struct imx93_clk_ccgr {
+ { IMX93_CLK_A55_GATE, "a55", "a55_root", 0x8000, },
+ /* M33 critical clk for system run */
+ { IMX93_CLK_CM33_GATE, "cm33", "m33_root", 0x8040, CLK_IS_CRITICAL },
+- { IMX93_CLK_ADC1_GATE, "adc1", "osc_24m", 0x82c0, },
++ { IMX93_CLK_ADC1_GATE, "adc1", "adc_root", 0x82c0, },
+ { IMX93_CLK_WDOG1_GATE, "wdog1", "osc_24m", 0x8300, },
+ { IMX93_CLK_WDOG2_GATE, "wdog2", "osc_24m", 0x8340, },
+ { IMX93_CLK_WDOG3_GATE, "wdog3", "osc_24m", 0x8380, },
+--
+2.35.1
+
--- /dev/null
+From fcb8ab07c92d39a0cec33f5215f68ba346c261d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 May 2022 17:33:29 +0800
+Subject: clk: mediatek: reset: Fix written reset bit offset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rex-BC Chen <rex-bc.chen@mediatek.com>
+
+[ Upstream commit edabcf71d100fd433a0fc2d0c97057c446c33b2a ]
+
+Original assert/deassert bit is BIT(0), but it's more resonable to modify
+them to BIT(id % 32) which is based on id.
+
+This patch will not influence any previous driver because the reset is
+only used for thermal. The id (MT8183_INFRACFG_AO_THERM_SW_RST) is 0.
+
+Fixes: 64ebb57a3df6 ("clk: reset: Modify reset-controller driver")
+Signed-off-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Link: https://lore.kernel.org/r/20220523093346.28493-3-rex-bc.chen@mediatek.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/mediatek/reset.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
+index bcec4b89f449..834d26e9bdfd 100644
+--- a/drivers/clk/mediatek/reset.c
++++ b/drivers/clk/mediatek/reset.c
+@@ -25,7 +25,7 @@ static int mtk_reset_assert_set_clr(struct reset_controller_dev *rcdev,
+ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+ unsigned int reg = data->regofs + ((id / 32) << 4);
+
+- return regmap_write(data->regmap, reg, 1);
++ return regmap_write(data->regmap, reg, BIT(id % 32));
+ }
+
+ static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev,
+@@ -34,7 +34,7 @@ static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev,
+ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
+ unsigned int reg = data->regofs + ((id / 32) << 4) + 0x4;
+
+- return regmap_write(data->regmap, reg, 1);
++ return regmap_write(data->regmap, reg, BIT(id % 32));
+ }
+
+ static int mtk_reset_assert(struct reset_controller_dev *rcdev,
+--
+2.35.1
+
--- /dev/null
+From 3ec1ff5784cc48967019794a67c0a9fa7ec288d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 00:41:32 +0300
+Subject: clk: qcom: camcc-sdm845: Fix topology around titan_top power domain
+
+From: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+
+[ Upstream commit 103dd2338bbff567bce7acd00fc5a09c806b38ec ]
+
+On SDM845 two found VFE GDSC power domains shall not be operated, if
+titan top is turned off, thus the former power domains will be set as
+subdomains by a GDSC registration routine.
+
+Fixes: 78412c262004 ("clk: qcom: Add camera clock controller driver for SDM845")
+Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+Reviewed-by: Robert Foss <robert.foss@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220519214133.1728979-2-vladimir.zapolskiy@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/camcc-sdm845.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c
+index be3f95326965..27d44188a7ab 100644
+--- a/drivers/clk/qcom/camcc-sdm845.c
++++ b/drivers/clk/qcom/camcc-sdm845.c
+@@ -1534,6 +1534,8 @@ static struct clk_branch cam_cc_sys_tmr_clk = {
+ },
+ };
+
++static struct gdsc titan_top_gdsc;
++
+ static struct gdsc bps_gdsc = {
+ .gdscr = 0x6004,
+ .pd = {
+@@ -1567,6 +1569,7 @@ static struct gdsc ife_0_gdsc = {
+ .name = "ife_0_gdsc",
+ },
+ .flags = POLL_CFG_GDSCR,
++ .parent = &titan_top_gdsc.pd,
+ .pwrsts = PWRSTS_OFF_ON,
+ };
+
+@@ -1576,6 +1579,7 @@ static struct gdsc ife_1_gdsc = {
+ .name = "ife_1_gdsc",
+ },
+ .flags = POLL_CFG_GDSCR,
++ .parent = &titan_top_gdsc.pd,
+ .pwrsts = PWRSTS_OFF_ON,
+ };
+
+--
+2.35.1
+
--- /dev/null
+From ca8f043d53b81f69c9f2fb3ecb071daedf743790 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 May 2022 13:35:54 +0300
+Subject: clk: qcom: camcc-sm8250: Fix halt on boot by reducing driver's init
+ level
+
+From: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+
+[ Upstream commit c4f40351901a10cd662ac2c081396d8fb04f584d ]
+
+Access to I/O of SM8250 camera clock controller IP depends on enabled
+GCC_CAMERA_AHB_CLK clock supplied by global clock controller, the latter
+one is inited on subsys level, so, to satisfy the dependency, it would
+make sense to deprive the init level of camcc-sm8250 driver.
+
+If both drivers are compiled as built-in, there is a change that a board
+won't boot up due to a race, which happens on the same init level.
+
+Fixes: 5d66ca79b58c ("clk: qcom: Add camera clock controller driver for SM8250")
+Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220518103554.949511-1-vladimir.zapolskiy@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/camcc-sm8250.c | 12 +-----------
+ 1 file changed, 1 insertion(+), 11 deletions(-)
+
+diff --git a/drivers/clk/qcom/camcc-sm8250.c b/drivers/clk/qcom/camcc-sm8250.c
+index 439eaafdcc86..ae4e9774f36e 100644
+--- a/drivers/clk/qcom/camcc-sm8250.c
++++ b/drivers/clk/qcom/camcc-sm8250.c
+@@ -2440,17 +2440,7 @@ static struct platform_driver cam_cc_sm8250_driver = {
+ },
+ };
+
+-static int __init cam_cc_sm8250_init(void)
+-{
+- return platform_driver_register(&cam_cc_sm8250_driver);
+-}
+-subsys_initcall(cam_cc_sm8250_init);
+-
+-static void __exit cam_cc_sm8250_exit(void)
+-{
+- platform_driver_unregister(&cam_cc_sm8250_driver);
+-}
+-module_exit(cam_cc_sm8250_exit);
++module_platform_driver(cam_cc_sm8250_driver);
+
+ MODULE_DESCRIPTION("QTI CAMCC SM8250 Driver");
+ MODULE_LICENSE("GPL v2");
+--
+2.35.1
+
--- /dev/null
+From 1a7e1b6dbc1e6b058b1fbce40d0f48e1dee23062 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 00:41:33 +0300
+Subject: clk: qcom: camcc-sm8250: Fix topology around titan_top power domain
+
+From: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+
+[ Upstream commit f8acf01a6a4f84baf05181e24bd48def4ba23f5b ]
+
+On SM8250 two found VFE GDSC power domains shall not be operated, if
+titan top is turned off, thus the former power domains will be set as
+subdomains by a GDSC registration routine.
+
+Fixes: 5d66ca79b58c ("clk: qcom: Add camera clock controller driver for SM8250")
+Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
+Reviewed-by: Robert Foss <robert.foss@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220519214133.1728979-3-vladimir.zapolskiy@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/camcc-sm8250.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/clk/qcom/camcc-sm8250.c b/drivers/clk/qcom/camcc-sm8250.c
+index ae4e9774f36e..9b32c56a5bc5 100644
+--- a/drivers/clk/qcom/camcc-sm8250.c
++++ b/drivers/clk/qcom/camcc-sm8250.c
+@@ -2205,6 +2205,8 @@ static struct clk_branch cam_cc_sleep_clk = {
+ },
+ };
+
++static struct gdsc titan_top_gdsc;
++
+ static struct gdsc bps_gdsc = {
+ .gdscr = 0x7004,
+ .pd = {
+@@ -2238,6 +2240,7 @@ static struct gdsc ife_0_gdsc = {
+ .name = "ife_0_gdsc",
+ },
+ .flags = POLL_CFG_GDSCR,
++ .parent = &titan_top_gdsc.pd,
+ .pwrsts = PWRSTS_OFF_ON,
+ };
+
+@@ -2247,6 +2250,7 @@ static struct gdsc ife_1_gdsc = {
+ .name = "ife_1_gdsc",
+ },
+ .flags = POLL_CFG_GDSCR,
++ .parent = &titan_top_gdsc.pd,
+ .pwrsts = PWRSTS_OFF_ON,
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 657f7925c4fecb3d24775159362b4592fcd63f9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Apr 2022 07:44:57 +0200
+Subject: clk: qcom: clk-krait: unlock spin after mux completion
+
+From: Ansuel Smith <ansuelsmth@gmail.com>
+
+[ Upstream commit df83d2c9e72910416f650ade1e07cc314ff02731 ]
+
+Unlock spinlock after the mux switch is completed to prevent any corner
+case of mux request while the switch still needs to be done.
+
+Fixes: 4d7dc77babfe ("clk: qcom: Add support for Krait clocks")
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220430054458.31321-3-ansuelsmth@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/clk-krait.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c
+index 59f1af415b58..90046428693c 100644
+--- a/drivers/clk/qcom/clk-krait.c
++++ b/drivers/clk/qcom/clk-krait.c
+@@ -32,11 +32,16 @@ static void __krait_mux_set_sel(struct krait_mux_clk *mux, int sel)
+ regval |= (sel & mux->mask) << (mux->shift + LPL_SHIFT);
+ }
+ krait_set_l2_indirect_reg(mux->offset, regval);
+- spin_unlock_irqrestore(&krait_clock_reg_lock, flags);
+
+ /* Wait for switch to complete. */
+ mb();
+ udelay(1);
++
++ /*
++ * Unlock now to make sure the mux register is not
++ * modified while switching to the new parent.
++ */
++ spin_unlock_irqrestore(&krait_clock_reg_lock, flags);
+ }
+
+ static int krait_mux_set_parent(struct clk_hw *hw, u8 index)
+--
+2.35.1
+
--- /dev/null
+From 185f9e43fe800d858209c6b764607c72e014fd09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jun 2022 19:59:52 +0500
+Subject: clk: qcom: clk-rcg2: Fail Duty-Cycle configuration if MND divider is
+ not enabled.
+
+From: Nikita Travkin <nikita@trvn.ru>
+
+[ Upstream commit bdafb609c3bb848d710ad9cd4debd2ee9d6a4049 ]
+
+In cases when MND is not enabled (e.g. when only Half Integer Divider is
+used), setting D registers makes no effect.
+
+Fail instead of making ineffective write.
+
+Fixes: 7f891faf596e ("clk: qcom: clk-rcg2: Add support for duty-cycle for RCG")
+Signed-off-by: Nikita Travkin <nikita@trvn.ru>
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220612145955.385787-2-nikita@trvn.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/clk-rcg2.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
+index e9c357309fd9..9611c9a7231f 100644
+--- a/drivers/clk/qcom/clk-rcg2.c
++++ b/drivers/clk/qcom/clk-rcg2.c
+@@ -405,7 +405,7 @@ static int clk_rcg2_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
+ static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
+ {
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+- u32 notn_m, n, m, d, not2d, mask, duty_per;
++ u32 notn_m, n, m, d, not2d, mask, duty_per, cfg;
+ int ret;
+
+ /* Duty-cycle cannot be modified for non-MND RCGs */
+@@ -416,6 +416,11 @@ static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
+
+ regmap_read(rcg->clkr.regmap, RCG_N_OFFSET(rcg), ¬n_m);
+ regmap_read(rcg->clkr.regmap, RCG_M_OFFSET(rcg), &m);
++ regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg);
++
++ /* Duty-cycle cannot be modified if MND divider is in bypass mode. */
++ if (!(cfg & CFG_MODE_MASK))
++ return -EINVAL;
+
+ n = (~(notn_m) + m) & mask;
+
+--
+2.35.1
+
--- /dev/null
+From 5ed9da11a435a8e476deda55e08d5c5644f11390 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jun 2022 19:59:53 +0500
+Subject: clk: qcom: clk-rcg2: Make sure to not write d=0 to the NMD register
+
+From: Nikita Travkin <nikita@trvn.ru>
+
+[ Upstream commit d0696770cef35a1fd16ea2167e2198c18aa6fbfe ]
+
+Sometimes calculation of d value may result in 0 because of the
+rounding after integer division. This causes the following error:
+
+[ 113.969689] camss_gp1_clk_src: rcg didn't update its configuration.
+[ 113.969754] WARNING: CPU: 3 PID: 35 at drivers/clk/qcom/clk-rcg2.c:122 update_config+0xc8/0xdc
+
+Make sure that D value is never zero.
+
+Fixes: 7f891faf596e ("clk: qcom: clk-rcg2: Add support for duty-cycle for RCG")
+Signed-off-by: Nikita Travkin <nikita@trvn.ru>
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220612145955.385787-3-nikita@trvn.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/clk-rcg2.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
+index 9611c9a7231f..caafc35eecfd 100644
+--- a/drivers/clk/qcom/clk-rcg2.c
++++ b/drivers/clk/qcom/clk-rcg2.c
+@@ -13,6 +13,7 @@
+ #include <linux/rational.h>
+ #include <linux/regmap.h>
+ #include <linux/math64.h>
++#include <linux/minmax.h>
+ #include <linux/slab.h>
+
+ #include <asm/div64.h>
+@@ -429,9 +430,11 @@ static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
+ /* Calculate 2d value */
+ d = DIV_ROUND_CLOSEST(n * duty_per * 2, 100);
+
+- /* Check bit widths of 2d. If D is too big reduce duty cycle. */
+- if (d > mask)
+- d = mask;
++ /*
++ * Check bit widths of 2d. If D is too big reduce duty cycle.
++ * Also make sure it is never zero.
++ */
++ d = clamp_val(d, 1, mask);
+
+ if ((d / 2) > (n - m))
+ d = (n - m) * 2;
+--
+2.35.1
+
--- /dev/null
+From d64137a669403a60eaf0c1f7f238a721e8ae4a2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 17:32:00 +0300
+Subject: clk: qcom: Drop mmcx gdsc supply for dispcc and videocc
+
+From: Abel Vesa <abel.vesa@linaro.org>
+
+[ Upstream commit b1ec8b53c9ae5fae33d60e9638d39ca5346b941b ]
+
+Both dispcc and videocc use mmcx power domain now.
+Lets drop the supply mmcx from every gdsc.
+
+Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Fixes: 266e5cf39a0f ("arm64: dts: qcom: sm8250: remove mmcx regulator")
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220713143200.3686765-1-abel.vesa@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/dispcc-sm8250.c | 1 -
+ drivers/clk/qcom/videocc-sm8250.c | 4 ----
+ 2 files changed, 5 deletions(-)
+
+diff --git a/drivers/clk/qcom/dispcc-sm8250.c b/drivers/clk/qcom/dispcc-sm8250.c
+index db9379634fb2..f646fdfe6f15 100644
+--- a/drivers/clk/qcom/dispcc-sm8250.c
++++ b/drivers/clk/qcom/dispcc-sm8250.c
+@@ -1134,7 +1134,6 @@ static struct gdsc mdss_gdsc = {
+ },
+ .pwrsts = PWRSTS_OFF_ON,
+ .flags = HW_CTRL,
+- .supply = "mmcx",
+ };
+
+ static struct clk_regmap *disp_cc_sm8250_clocks[] = {
+diff --git a/drivers/clk/qcom/videocc-sm8250.c b/drivers/clk/qcom/videocc-sm8250.c
+index 8617454e4a77..f28f2cb051d7 100644
+--- a/drivers/clk/qcom/videocc-sm8250.c
++++ b/drivers/clk/qcom/videocc-sm8250.c
+@@ -277,7 +277,6 @@ static struct gdsc mvs0c_gdsc = {
+ },
+ .flags = 0,
+ .pwrsts = PWRSTS_OFF_ON,
+- .supply = "mmcx",
+ };
+
+ static struct gdsc mvs1c_gdsc = {
+@@ -287,7 +286,6 @@ static struct gdsc mvs1c_gdsc = {
+ },
+ .flags = 0,
+ .pwrsts = PWRSTS_OFF_ON,
+- .supply = "mmcx",
+ };
+
+ static struct gdsc mvs0_gdsc = {
+@@ -297,7 +295,6 @@ static struct gdsc mvs0_gdsc = {
+ },
+ .flags = HW_CTRL,
+ .pwrsts = PWRSTS_OFF_ON,
+- .supply = "mmcx",
+ };
+
+ static struct gdsc mvs1_gdsc = {
+@@ -307,7 +304,6 @@ static struct gdsc mvs1_gdsc = {
+ },
+ .flags = HW_CTRL,
+ .pwrsts = PWRSTS_OFF_ON,
+- .supply = "mmcx",
+ };
+
+ static struct clk_regmap *video_cc_sm8250_clocks[] = {
+--
+2.35.1
+
--- /dev/null
+From 744fd84fe1987cd29078478afe8ca1e4d78385e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 May 2022 17:38:32 +0100
+Subject: clk: qcom: gcc-msm8939: Add missing SYSTEM_MM_NOC_BFDCD_CLK_SRC
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit 07e7fcf1714c5f9930ad27613fea940aedba68da ]
+
+When adding in the indexes for this clock-controller we missed
+SYSTEM_MM_NOC_BFDCD_CLK_SRC.
+
+Add it in now.
+
+Fixes: 4c71d6abc4fc ("clk: qcom: Add DT bindings for MSM8939 GCC")
+Cc: Rob Herring <robh+dt@kernel.org>
+Cc: Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>
+Cc: devicetree@vger.kernel.org
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220504163835.40130-2-bryan.odonoghue@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/dt-bindings/clock/qcom,gcc-msm8939.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/dt-bindings/clock/qcom,gcc-msm8939.h b/include/dt-bindings/clock/qcom,gcc-msm8939.h
+index 0634467c4ce5..2d545ed0d35a 100644
+--- a/include/dt-bindings/clock/qcom,gcc-msm8939.h
++++ b/include/dt-bindings/clock/qcom,gcc-msm8939.h
+@@ -192,6 +192,7 @@
+ #define GCC_VENUS0_CORE0_VCODEC0_CLK 183
+ #define GCC_VENUS0_CORE1_VCODEC0_CLK 184
+ #define GCC_OXILI_TIMER_CLK 185
++#define SYSTEM_MM_NOC_BFDCD_CLK_SRC 186
+
+ /* Indexes for GDSCs */
+ #define BIMC_GDSC 0
+--
+2.35.1
+
--- /dev/null
+From 2db012e1f598880942050fd0973342fbe0a05caf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 May 2022 17:38:34 +0100
+Subject: clk: qcom: gcc-msm8939: Add missing system_mm_noc_bfdcd_clk_src
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit dd363e2f7196278e7a30f509a0e8a841cb763b14 ]
+
+The msm8939 has an additional higher operating point for the multi-media
+peripherals. The higher throughput MM componets operate off of the
+system-mm noc not the system noc.
+
+system_mm_noc_bfdcd_clk_src is the source clock for the higher frequency
+capable system noc mm.
+
+Maximum frequency for the MM SNOC is 400 MHz.
+
+Fixes: 1664014e4679 ("clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller")
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220504163835.40130-4-bryan.odonoghue@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8939.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c
+index 31568658d23d..12bab9067ea8 100644
+--- a/drivers/clk/qcom/gcc-msm8939.c
++++ b/drivers/clk/qcom/gcc-msm8939.c
+@@ -644,6 +644,18 @@ static struct clk_rcg2 bimc_ddr_clk_src = {
+ },
+ };
+
++static struct clk_rcg2 system_mm_noc_bfdcd_clk_src = {
++ .cmd_rcgr = 0x2600c,
++ .hid_width = 5,
++ .parent_map = gcc_xo_gpll0_gpll6a_map,
++ .clkr.hw.init = &(struct clk_init_data){
++ .name = "system_mm_noc_bfdcd_clk_src",
++ .parent_data = gcc_xo_gpll0_gpll6a_parent_data,
++ .num_parents = 3,
++ .ops = &clk_rcg2_ops,
++ },
++};
++
+ static const struct freq_tbl ftbl_gcc_camss_ahb_clk[] = {
+ F(40000000, P_GPLL0, 10, 1, 2),
+ F(80000000, P_GPLL0, 10, 0, 0),
+@@ -3623,6 +3635,7 @@ static struct clk_regmap *gcc_msm8939_clocks[] = {
+ [GPLL2_VOTE] = &gpll2_vote,
+ [PCNOC_BFDCD_CLK_SRC] = &pcnoc_bfdcd_clk_src.clkr,
+ [SYSTEM_NOC_BFDCD_CLK_SRC] = &system_noc_bfdcd_clk_src.clkr,
++ [SYSTEM_MM_NOC_BFDCD_CLK_SRC] = &system_mm_noc_bfdcd_clk_src.clkr,
+ [CAMSS_AHB_CLK_SRC] = &camss_ahb_clk_src.clkr,
+ [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr,
+ [CSI0_CLK_SRC] = &csi0_clk_src.clkr,
+--
+2.35.1
+
--- /dev/null
+From ca5e013db5945968371a680d5e3b3b66cad8e807 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 May 2022 17:38:33 +0100
+Subject: clk: qcom: gcc-msm8939: Fix bimc_ddr_clk_src rcgr base address
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit 63d42708320d6d2ca9ed505123d50ff4a542c36f ]
+
+Reviewing qcom docs for the 8939 we can see the command rcgr is pointing to
+the wrong address. bimc_ddr_clk_src_rcgr is @ 0x01832024 not 0x01832004.
+
+Fixes: 1664014e4679 ("clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller")
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220504163835.40130-3-bryan.odonoghue@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8939.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c
+index 39ebb443ae3d..31568658d23d 100644
+--- a/drivers/clk/qcom/gcc-msm8939.c
++++ b/drivers/clk/qcom/gcc-msm8939.c
+@@ -632,7 +632,7 @@ static struct clk_rcg2 system_noc_bfdcd_clk_src = {
+ };
+
+ static struct clk_rcg2 bimc_ddr_clk_src = {
+- .cmd_rcgr = 0x32004,
++ .cmd_rcgr = 0x32024,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_bimc_map,
+ .clkr.hw.init = &(struct clk_init_data){
+--
+2.35.1
+
--- /dev/null
+From 253b6dcb6d8f1f372d560421a5a6380a18232029 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 13:59:17 +0100
+Subject: clk: qcom: gcc-msm8939: Fix weird field spacing in
+ ftbl_gcc_camss_cci_clk
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit 2bc308ebc453ba22f3f120f777b9ac48f973ee80 ]
+
+Adding a new item to this frequency table I see the existing indentation is
+incorrect.
+
+Fixes: 1664014e4679 ("clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller")
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220712125922.3461675-2-bryan.odonoghue@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8939.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c
+index c7377ec0f423..de0022e5450d 100644
+--- a/drivers/clk/qcom/gcc-msm8939.c
++++ b/drivers/clk/qcom/gcc-msm8939.c
+@@ -1014,7 +1014,7 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
+ };
+
+ static const struct freq_tbl ftbl_gcc_camss_cci_clk[] = {
+- F(19200000, P_XO, 1, 0, 0),
++ F(19200000, P_XO, 1, 0, 0),
+ { }
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 3fd8ec87f1647a2bfac50664b8d90fbf59e19908 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 May 2022 17:38:35 +0100
+Subject: clk: qcom: gcc-msm8939: Point MM peripherals to system_mm_noc clock
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit 05eed0990927aa9634682fec58660e30f7b7ae30 ]
+
+Qcom docs indciate the following peripherals operating from System NOC
+MM not from System NOC clocks.
+
+- MDP
+- VFE
+- JPEGe
+- Venus
+
+Switch over the relevant parent pointers.
+
+Fixes: 1664014e4679 ("clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller")
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220504163835.40130-5-bryan.odonoghue@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-msm8939.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/clk/qcom/gcc-msm8939.c b/drivers/clk/qcom/gcc-msm8939.c
+index 12bab9067ea8..c7377ec0f423 100644
+--- a/drivers/clk/qcom/gcc-msm8939.c
++++ b/drivers/clk/qcom/gcc-msm8939.c
+@@ -2453,7 +2453,7 @@ static struct clk_branch gcc_camss_jpeg_axi_clk = {
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_jpeg_axi_clk",
+ .parent_data = &(const struct clk_parent_data){
+- .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++ .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+@@ -2657,7 +2657,7 @@ static struct clk_branch gcc_camss_vfe_axi_clk = {
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_camss_vfe_axi_clk",
+ .parent_data = &(const struct clk_parent_data){
+- .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++ .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+@@ -2813,7 +2813,7 @@ static struct clk_branch gcc_mdss_axi_clk = {
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mdss_axi_clk",
+ .parent_data = &(const struct clk_parent_data){
+- .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++ .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+@@ -3205,7 +3205,7 @@ static struct clk_branch gcc_mdp_tbu_clk = {
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mdp_tbu_clk",
+ .parent_data = &(const struct clk_parent_data){
+- .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++ .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+@@ -3223,7 +3223,7 @@ static struct clk_branch gcc_venus_tbu_clk = {
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_venus_tbu_clk",
+ .parent_data = &(const struct clk_parent_data){
+- .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++ .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+@@ -3241,7 +3241,7 @@ static struct clk_branch gcc_vfe_tbu_clk = {
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_vfe_tbu_clk",
+ .parent_data = &(const struct clk_parent_data){
+- .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++ .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+@@ -3259,7 +3259,7 @@ static struct clk_branch gcc_jpeg_tbu_clk = {
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_jpeg_tbu_clk",
+ .parent_data = &(const struct clk_parent_data){
+- .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++ .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+@@ -3496,7 +3496,7 @@ static struct clk_branch gcc_venus0_axi_clk = {
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_venus0_axi_clk",
+ .parent_data = &(const struct clk_parent_data){
+- .hw = &system_noc_bfdcd_clk_src.clkr.hw,
++ .hw = &system_mm_noc_bfdcd_clk_src.clkr.hw,
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+--
+2.35.1
+
--- /dev/null
+From b9b3c8e27ba053a342c95c19b4e99a23c2ea09d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 14:28:18 -0700
+Subject: clk: qcom: gdsc: Bump parent usage count when GDSC is found enabled
+
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+
+[ Upstream commit 41fff779d7948147f2440c4bb134cdf8b45b22d7 ]
+
+When a GDSC is found to be enabled at boot the pm_runtime state will
+be unbalanced as the GDSC is later turned off. Fix this by increasing
+the usage counter on the power-domain, in line with how we handled the
+regulator state.
+
+Fixes: 1b771839de05 ("clk: qcom: gdsc: enable optional power domain support")
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Acked-by: Stephen Boyd <sboyd@kernel.org>
+Link: https://lore.kernel.org/r/20220713212818.130277-1-bjorn.andersson@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gdsc.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
+index 44520efc6c72..2db0938f8dd3 100644
+--- a/drivers/clk/qcom/gdsc.c
++++ b/drivers/clk/qcom/gdsc.c
+@@ -420,6 +420,14 @@ static int gdsc_init(struct gdsc *sc)
+ return ret;
+ }
+
++ /* ...and the power-domain */
++ ret = gdsc_pm_runtime_get(sc);
++ if (ret) {
++ if (sc->rsupply)
++ regulator_disable(sc->rsupply);
++ return ret;
++ }
++
+ /*
+ * Votable GDSCs can be ON due to Vote from other masters.
+ * If a Votable GDSC is ON, make sure we have a Vote.
+--
+2.35.1
+
--- /dev/null
+From 3e8172c3ddd86a45ff3cf679f3028f33cf9179dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 May 2022 23:00:38 +0200
+Subject: clk: qcom: ipq8074: fix NSS core PLL-s
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit ca41ec1b30434636c56c5600b24a8d964d359d9c ]
+
+Like in IPQ6018 the NSS related Alpha PLL-s require initial configuration
+to work.
+
+So, obtain the regmap that is required for the Alpha PLL configuration
+and thus utilize the qcom_cc_really_probe() as we already have the regmap.
+Then utilize the Alpha PLL configs from the downstream QCA 5.4 based
+kernel to configure them.
+
+This fixes the UBI32 and NSS crypto PLL-s failing to get enabled by the
+kernel.
+
+Fixes: b8e7e519625f ("clk: qcom: ipq8074: add remaining PLL’s")
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220515210048.483898-1-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-ipq8074.c | 39 +++++++++++++++++++++++++++++++++-
+ 1 file changed, 38 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
+index 541016db3c4b..1a5141da7e23 100644
+--- a/drivers/clk/qcom/gcc-ipq8074.c
++++ b/drivers/clk/qcom/gcc-ipq8074.c
+@@ -4371,6 +4371,33 @@ static struct clk_branch gcc_pcie0_axi_s_bridge_clk = {
+ },
+ };
+
++static const struct alpha_pll_config ubi32_pll_config = {
++ .l = 0x4e,
++ .config_ctl_val = 0x200d4aa8,
++ .config_ctl_hi_val = 0x3c2,
++ .main_output_mask = BIT(0),
++ .aux_output_mask = BIT(1),
++ .pre_div_val = 0x0,
++ .pre_div_mask = BIT(12),
++ .post_div_val = 0x0,
++ .post_div_mask = GENMASK(9, 8),
++};
++
++static const struct alpha_pll_config nss_crypto_pll_config = {
++ .l = 0x3e,
++ .alpha = 0x0,
++ .alpha_hi = 0x80,
++ .config_ctl_val = 0x4001055b,
++ .main_output_mask = BIT(0),
++ .pre_div_val = 0x0,
++ .pre_div_mask = GENMASK(14, 12),
++ .post_div_val = 0x1 << 8,
++ .post_div_mask = GENMASK(11, 8),
++ .vco_mask = GENMASK(21, 20),
++ .vco_val = 0x0,
++ .alpha_en_mask = BIT(24),
++};
++
+ static struct clk_hw *gcc_ipq8074_hws[] = {
+ &gpll0_out_main_div2.hw,
+ &gpll6_out_main_div2.hw,
+@@ -4772,7 +4799,17 @@ static const struct qcom_cc_desc gcc_ipq8074_desc = {
+
+ static int gcc_ipq8074_probe(struct platform_device *pdev)
+ {
+- return qcom_cc_probe(pdev, &gcc_ipq8074_desc);
++ struct regmap *regmap;
++
++ regmap = qcom_cc_map(pdev, &gcc_ipq8074_desc);
++ if (IS_ERR(regmap))
++ return PTR_ERR(regmap);
++
++ clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
++ clk_alpha_pll_configure(&nss_crypto_pll_main, regmap,
++ &nss_crypto_pll_config);
++
++ return qcom_cc_really_probe(pdev, &gcc_ipq8074_desc, regmap);
+ }
+
+ static struct platform_driver gcc_ipq8074_driver = {
+--
+2.35.1
+
--- /dev/null
+From 253b997458d29624c22c793d07e8c0accf1c5094 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 May 2022 23:00:40 +0200
+Subject: clk: qcom: ipq8074: fix NSS port frequency tables
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit 0e9e61a2815b5cd34f1b495b2d72e8127ce9b794 ]
+
+NSS port 5 and 6 frequency tables are currently broken and are causing a
+wide ranges of issue like 1G not working at all on port 6 or port 5 being
+clocked with 312 instead of 125 MHz as UNIPHY1 gets selected.
+
+So, update the frequency tables with the ones from the downstream QCA 5.4
+based kernel which has already fixed this.
+
+Fixes: 7117a51ed303 ("clk: qcom: ipq8074: add NSS ethernet port clocks")
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220515210048.483898-3-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-ipq8074.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
+index b4291ba53c78..f1017f2e61bd 100644
+--- a/drivers/clk/qcom/gcc-ipq8074.c
++++ b/drivers/clk/qcom/gcc-ipq8074.c
+@@ -1788,8 +1788,10 @@ static struct clk_regmap_div nss_port4_tx_div_clk_src = {
+ static const struct freq_tbl ftbl_nss_port5_rx_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(25000000, P_UNIPHY1_RX, 12.5, 0, 0),
++ F(25000000, P_UNIPHY0_RX, 5, 0, 0),
+ F(78125000, P_UNIPHY1_RX, 4, 0, 0),
+ F(125000000, P_UNIPHY1_RX, 2.5, 0, 0),
++ F(125000000, P_UNIPHY0_RX, 1, 0, 0),
+ F(156250000, P_UNIPHY1_RX, 2, 0, 0),
+ F(312500000, P_UNIPHY1_RX, 1, 0, 0),
+ { }
+@@ -1828,8 +1830,10 @@ static struct clk_regmap_div nss_port5_rx_div_clk_src = {
+ static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(25000000, P_UNIPHY1_TX, 12.5, 0, 0),
++ F(25000000, P_UNIPHY0_TX, 5, 0, 0),
+ F(78125000, P_UNIPHY1_TX, 4, 0, 0),
+ F(125000000, P_UNIPHY1_TX, 2.5, 0, 0),
++ F(125000000, P_UNIPHY0_TX, 1, 0, 0),
+ F(156250000, P_UNIPHY1_TX, 2, 0, 0),
+ F(312500000, P_UNIPHY1_TX, 1, 0, 0),
+ { }
+@@ -1867,8 +1871,10 @@ static struct clk_regmap_div nss_port5_tx_div_clk_src = {
+
+ static const struct freq_tbl ftbl_nss_port6_rx_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
++ F(25000000, P_UNIPHY2_RX, 5, 0, 0),
+ F(25000000, P_UNIPHY2_RX, 12.5, 0, 0),
+ F(78125000, P_UNIPHY2_RX, 4, 0, 0),
++ F(125000000, P_UNIPHY2_RX, 1, 0, 0),
+ F(125000000, P_UNIPHY2_RX, 2.5, 0, 0),
+ F(156250000, P_UNIPHY2_RX, 2, 0, 0),
+ F(312500000, P_UNIPHY2_RX, 1, 0, 0),
+@@ -1907,8 +1913,10 @@ static struct clk_regmap_div nss_port6_rx_div_clk_src = {
+
+ static const struct freq_tbl ftbl_nss_port6_tx_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
++ F(25000000, P_UNIPHY2_TX, 5, 0, 0),
+ F(25000000, P_UNIPHY2_TX, 12.5, 0, 0),
+ F(78125000, P_UNIPHY2_TX, 4, 0, 0),
++ F(125000000, P_UNIPHY2_TX, 1, 0, 0),
+ F(125000000, P_UNIPHY2_TX, 2.5, 0, 0),
+ F(156250000, P_UNIPHY2_TX, 2, 0, 0),
+ F(312500000, P_UNIPHY2_TX, 1, 0, 0),
+--
+2.35.1
+
--- /dev/null
+From faa7625d22b5cd568c20f6efdd229ece2c6edfca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 May 2022 23:00:43 +0200
+Subject: clk: qcom: ipq8074: set BRANCH_HALT_DELAY flag for UBI clocks
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit 2bd357e698207e2e65db03007e4be65bf9d6a7b3 ]
+
+Currently, attempting to enable the UBI clocks will cause the stuck at
+off warning to be printed and clk_enable will fail.
+
+[ 14.936694] gcc_ubi1_ahb_clk status stuck at 'off'
+
+Downstream 5.4 QCA kernel has fixed this by seting the BRANCH_HALT_DELAY
+flag on UBI clocks, so lets do the same.
+
+Fixes: 5736294aef83 ("clk: qcom: ipq8074: add NSS clocks")
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220515210048.483898-6-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-ipq8074.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
+index f1017f2e61bd..2c2ecfc5e61f 100644
+--- a/drivers/clk/qcom/gcc-ipq8074.c
++++ b/drivers/clk/qcom/gcc-ipq8074.c
+@@ -3354,6 +3354,7 @@ static struct clk_branch gcc_nssnoc_ubi1_ahb_clk = {
+
+ static struct clk_branch gcc_ubi0_ahb_clk = {
+ .halt_reg = 0x6820c,
++ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x6820c,
+ .enable_mask = BIT(0),
+@@ -3371,6 +3372,7 @@ static struct clk_branch gcc_ubi0_ahb_clk = {
+
+ static struct clk_branch gcc_ubi0_axi_clk = {
+ .halt_reg = 0x68200,
++ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x68200,
+ .enable_mask = BIT(0),
+@@ -3388,6 +3390,7 @@ static struct clk_branch gcc_ubi0_axi_clk = {
+
+ static struct clk_branch gcc_ubi0_nc_axi_clk = {
+ .halt_reg = 0x68204,
++ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x68204,
+ .enable_mask = BIT(0),
+@@ -3405,6 +3408,7 @@ static struct clk_branch gcc_ubi0_nc_axi_clk = {
+
+ static struct clk_branch gcc_ubi0_core_clk = {
+ .halt_reg = 0x68210,
++ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x68210,
+ .enable_mask = BIT(0),
+@@ -3422,6 +3426,7 @@ static struct clk_branch gcc_ubi0_core_clk = {
+
+ static struct clk_branch gcc_ubi0_mpt_clk = {
+ .halt_reg = 0x68208,
++ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x68208,
+ .enable_mask = BIT(0),
+@@ -3439,6 +3444,7 @@ static struct clk_branch gcc_ubi0_mpt_clk = {
+
+ static struct clk_branch gcc_ubi1_ahb_clk = {
+ .halt_reg = 0x6822c,
++ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x6822c,
+ .enable_mask = BIT(0),
+@@ -3456,6 +3462,7 @@ static struct clk_branch gcc_ubi1_ahb_clk = {
+
+ static struct clk_branch gcc_ubi1_axi_clk = {
+ .halt_reg = 0x68220,
++ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x68220,
+ .enable_mask = BIT(0),
+@@ -3473,6 +3480,7 @@ static struct clk_branch gcc_ubi1_axi_clk = {
+
+ static struct clk_branch gcc_ubi1_nc_axi_clk = {
+ .halt_reg = 0x68224,
++ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x68224,
+ .enable_mask = BIT(0),
+@@ -3490,6 +3498,7 @@ static struct clk_branch gcc_ubi1_nc_axi_clk = {
+
+ static struct clk_branch gcc_ubi1_core_clk = {
+ .halt_reg = 0x68230,
++ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x68230,
+ .enable_mask = BIT(0),
+@@ -3507,6 +3516,7 @@ static struct clk_branch gcc_ubi1_core_clk = {
+
+ static struct clk_branch gcc_ubi1_mpt_clk = {
+ .halt_reg = 0x68228,
++ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x68228,
+ .enable_mask = BIT(0),
+--
+2.35.1
+
--- /dev/null
+From 61ba7a9d694468d52909a1579c62ce06e8ec3296 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 May 2022 23:00:39 +0200
+Subject: clk: qcom: ipq8074: SW workaround for UBI32 PLL lock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Robert Marko <robimarko@gmail.com>
+
+[ Upstream commit 3401ea2856ef84f39b75f0dc5ebcaeda81cb90ec ]
+
+UBI32 Huayra PLL fails to lock in 5 us in some SoC silicon and thus it
+will cause the wait_for_pll() to timeout and thus return the error
+indicating that the PLL failed to lock.
+
+This is bug in Huayra PLL HW for which SW workaround
+is to set bit 26 of TEST_CTL register.
+
+This is ported from the QCA 5.4 based downstream kernel.
+
+Fixes: b8e7e519625f ("clk: qcom: ipq8074: add remaining PLL’s")
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220515210048.483898-2-robimarko@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-ipq8074.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
+index 1a5141da7e23..b4291ba53c78 100644
+--- a/drivers/clk/qcom/gcc-ipq8074.c
++++ b/drivers/clk/qcom/gcc-ipq8074.c
+@@ -4805,6 +4805,9 @@ static int gcc_ipq8074_probe(struct platform_device *pdev)
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
++ /* SW Workaround for UBI32 Huayra PLL */
++ regmap_update_bits(regmap, 0x2501c, BIT(26), BIT(26));
++
+ clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
+ clk_alpha_pll_configure(&nss_crypto_pll_main, regmap,
+ &nss_crypto_pll_config);
+--
+2.35.1
+
--- /dev/null
+From c5b4d204477fe915be09e2052fe3652470afb8c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 May 2022 14:25:27 -0400
+Subject: clk: renesas: r9a06g032: Fix UART clkgrp bitsel
+
+From: Ralph Siemsen <ralph.siemsen@linaro.org>
+
+[ Upstream commit 2dee50ab9e72a3cae75b65e5934c8dd3e9bf01bc ]
+
+There are two UART clock groups, each having a mux to select its
+upstream clock source. The register/bit definitions for accessing these
+two muxes appear to have been reversed since introduction. Correct them
+so as to match the hardware manual.
+
+Fixes: 4c3d88526eba ("clk: renesas: Renesas R9A06G032 clock driver")
+
+Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org>
+Reviewed-by: Phil Edworthy <phil.edworthy@renesas.com>
+Link: https://lore.kernel.org/r/20220518182527.1693156-1-ralph.siemsen@linaro.org
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/r9a06g032-clocks.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c
+index c99942f0e4d4..abc0891fd96d 100644
+--- a/drivers/clk/renesas/r9a06g032-clocks.c
++++ b/drivers/clk/renesas/r9a06g032-clocks.c
+@@ -286,8 +286,8 @@ static const struct r9a06g032_clkdesc r9a06g032_clocks[] = {
+ .name = "uart_group_012",
+ .type = K_BITSEL,
+ .source = 1 + R9A06G032_DIV_UART,
+- /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */
+- .dual.sel = ((0xec / 4) << 5) | 24,
++ /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */
++ .dual.sel = ((0x34 / 4) << 5) | 30,
+ .dual.group = 0,
+ },
+ {
+@@ -295,8 +295,8 @@ static const struct r9a06g032_clkdesc r9a06g032_clocks[] = {
+ .name = "uart_group_34567",
+ .type = K_BITSEL,
+ .source = 1 + R9A06G032_DIV_P2_PG,
+- /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */
+- .dual.sel = ((0x34 / 4) << 5) | 30,
++ /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */
++ .dual.sel = ((0xec / 4) << 5) | 24,
+ .dual.group = 1,
+ },
+ D_UGATE(CLK_UART0, "clk_uart0", UART_GROUP_012, 0, 0, 0x1b2, 0x1b3, 0x1b4, 0x1b5),
+--
+2.35.1
+
--- /dev/null
+From eec1137fdbcfb70f68e905f2e85a90831e95c470 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 May 2022 08:16:57 +0100
+Subject: clk: renesas: rzg2l: Fix reset status function
+
+From: Biju Das <biju.das.jz@bp.renesas.com>
+
+[ Upstream commit 02c96ed9e4cd1f47bfcd10296fec6b0b69d6b3c6 ]
+
+As per RZ/G2L HW(Rev.1.10) manual, reset monitor register value 0 means
+reset signal is not applied (deassert state) and 1 means reset signal
+is applied (assert state).
+
+reset_control_status() expects a positive value if the reset line is
+asserted. But rzg2l_cpg_status function returns zero for asserted
+state.
+
+This patch fixes the issue by adding double inverted logic, so that
+reset_control_status returns a positive value if the reset line is
+asserted.
+
+Fixes: ef3c613ccd68 ("clk: renesas: Add CPG core wrapper for RZ/G2L SoC")
+Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
+Link: https://lore.kernel.org/r/20220531071657.104121-1-biju.das.jz@bp.renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/rzg2l-cpg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
+index 486d0656c58a..1068058a3865 100644
+--- a/drivers/clk/renesas/rzg2l-cpg.c
++++ b/drivers/clk/renesas/rzg2l-cpg.c
+@@ -744,7 +744,7 @@ static int rzg2l_cpg_status(struct reset_controller_dev *rcdev,
+ unsigned int reg = info->resets[id].off;
+ u32 bitmask = BIT(info->resets[id].bit);
+
+- return !(readl(priv->base + CLK_MRST_R(reg)) & bitmask);
++ return !!(readl(priv->base + CLK_MRST_R(reg)) & bitmask);
+ }
+
+ static const struct reset_control_ops rzg2l_cpg_reset_ops = {
+--
+2.35.1
+
--- /dev/null
+From 4166261ae858f020902a9a587feccca0d62b28e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jun 2022 18:30:03 +0100
+Subject: coresight: configfs: Fix unload of configurations on module exit
+
+From: Mike Leach <mike.leach@linaro.org>
+
+[ Upstream commit 199380decc5f9188a9e65676031950f1734aaffe ]
+
+Any loaded configurations must be correctly unloaded on coresight module
+exit, or issues can arise with nested locking in the configfs directory
+code if built with CONFIG_LOCKDEP.
+
+Prior to this patch, the preloaded configuration configfs directory entries
+were being unloaded by the recursive code in
+configfs_unregister_subsystem().
+
+However, when built with CONFIG_LOCKDEP, this caused a nested lock warning,
+which was not mitigated by the LOCKDEP dependent code in fs/configfs/dir.c
+designed to prevent this, due to the different directory levels for the
+root of the directory being removed.
+
+As the preloaded (and all other) configurations are registered after
+configfs_register_subsystem(), we now explicitly unload them before the
+call to configfs_unregister_subsystem().
+
+The new routine cscfg_unload_cfgs_on_exit() iterates through the load
+owner list to unload any remaining configurations that were not unloaded
+by the user before the module exits. This covers both the
+CSCFG_OWNER_PRELOAD and CSCFG_OWNER_MODULE owner types, and will be
+extended to cover future load owner types for CoreSight configurations.
+
+Fixes: eb2ec49606c2 ("coresight: syscfg: Update load API for config loadable modules")
+Reported-by: Suzuki Poulose <suzuki.poulose@arm.com>
+Signed-off-by: Mike Leach <mike.leach@linaro.org>
+Reviewed-and-tested-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20220628173004.30002-2-mike.leach@linaro.org
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../hwtracing/coresight/coresight-syscfg.c | 104 ++++++++++++++++--
+ 1 file changed, 93 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
+index 11850fd8c3b5..17e728ab5c99 100644
+--- a/drivers/hwtracing/coresight/coresight-syscfg.c
++++ b/drivers/hwtracing/coresight/coresight-syscfg.c
+@@ -414,6 +414,27 @@ static void cscfg_remove_owned_csdev_features(struct coresight_device *csdev, vo
+ }
+ }
+
++/*
++ * Unregister all configuration and features from configfs owned by load_owner.
++ * Although this is called without the list mutex being held, it is in the
++ * context of an unload operation which are strictly serialised,
++ * so the lists cannot change during this call.
++ */
++static void cscfg_fs_unregister_cfgs_feats(void *load_owner)
++{
++ struct cscfg_config_desc *config_desc;
++ struct cscfg_feature_desc *feat_desc;
++
++ list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
++ if (config_desc->load_owner == load_owner)
++ cscfg_configfs_del_config(config_desc);
++ }
++ list_for_each_entry(feat_desc, &cscfg_mgr->feat_desc_list, item) {
++ if (feat_desc->load_owner == load_owner)
++ cscfg_configfs_del_feature(feat_desc);
++ }
++}
++
+ /*
+ * removal is relatively easy - just remove from all lists, anything that
+ * matches the owner. Memory for the descriptors will be managed by the owner,
+@@ -1022,8 +1043,10 @@ struct device *cscfg_device(void)
+ /* Must have a release function or the kernel will complain on module unload */
+ static void cscfg_dev_release(struct device *dev)
+ {
++ mutex_lock(&cscfg_mutex);
+ kfree(cscfg_mgr);
+ cscfg_mgr = NULL;
++ mutex_unlock(&cscfg_mutex);
+ }
+
+ /* a device is needed to "own" some kernel elements such as sysfs entries. */
+@@ -1042,6 +1065,13 @@ static int cscfg_create_device(void)
+ if (!cscfg_mgr)
+ goto create_dev_exit_unlock;
+
++ /* initialise the cscfg_mgr structure */
++ INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list);
++ INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list);
++ INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
++ INIT_LIST_HEAD(&cscfg_mgr->load_order_list);
++ atomic_set(&cscfg_mgr->sys_active_cnt, 0);
++
+ /* setup the device */
+ dev = cscfg_device();
+ dev->release = cscfg_dev_release;
+@@ -1056,17 +1086,73 @@ static int cscfg_create_device(void)
+ return err;
+ }
+
+-static void cscfg_clear_device(void)
++/*
++ * Loading and unloading is generally on user discretion.
++ * If exiting due to coresight module unload, we need to unload any configurations that remain,
++ * before we unregister the configfs intrastructure.
++ *
++ * Do this by walking the load_owner list and taking appropriate action, depending on the load
++ * owner type.
++ */
++static void cscfg_unload_cfgs_on_exit(void)
+ {
+- struct cscfg_config_desc *cfg_desc;
++ struct cscfg_load_owner_info *owner_info = NULL;
+
++ /*
++ * grab the mutex - even though we are exiting, some configfs files
++ * may still be live till we dump them, so ensure list data is
++ * protected from a race condition.
++ */
+ mutex_lock(&cscfg_mutex);
+- list_for_each_entry(cfg_desc, &cscfg_mgr->config_desc_list, item) {
+- etm_perf_del_symlink_cscfg(cfg_desc);
++ while (!list_empty(&cscfg_mgr->load_order_list)) {
++
++ /* remove in reverse order of loading */
++ owner_info = list_last_entry(&cscfg_mgr->load_order_list,
++ struct cscfg_load_owner_info, item);
++
++ /* action according to type */
++ switch (owner_info->type) {
++ case CSCFG_OWNER_PRELOAD:
++ /*
++ * preloaded descriptors are statically allocated in
++ * this module - just need to unload dynamic items from
++ * csdev lists, and remove from configfs directories.
++ */
++ pr_info("cscfg: unloading preloaded configurations\n");
++ break;
++
++ case CSCFG_OWNER_MODULE:
++ /*
++ * this is an error - the loadable module must have been unloaded prior
++ * to the coresight module unload. Therefore that module has not
++ * correctly unloaded configs in its own exit code.
++ * Nothing to do other than emit an error string as the static descriptor
++ * references we need to unload will have disappeared with the module.
++ */
++ pr_err("cscfg: ERROR: prior module failed to unload configuration\n");
++ goto list_remove;
++ }
++
++ /* remove from configfs - outside the scope of the list mutex */
++ mutex_unlock(&cscfg_mutex);
++ cscfg_fs_unregister_cfgs_feats(owner_info);
++ mutex_lock(&cscfg_mutex);
++
++ /* Next unload from csdev lists. */
++ cscfg_unload_owned_cfgs_feats(owner_info);
++
++list_remove:
++ /* remove from load order list */
++ list_del(&owner_info->item);
+ }
++ mutex_unlock(&cscfg_mutex);
++}
++
++static void cscfg_clear_device(void)
++{
++ cscfg_unload_cfgs_on_exit();
+ cscfg_configfs_release(cscfg_mgr);
+ device_unregister(cscfg_device());
+- mutex_unlock(&cscfg_mutex);
+ }
+
+ /* Initialise system config management API device */
+@@ -1074,20 +1160,16 @@ int __init cscfg_init(void)
+ {
+ int err = 0;
+
++ /* create the device and init cscfg_mgr */
+ err = cscfg_create_device();
+ if (err)
+ return err;
+
++ /* initialise configfs subsystem */
+ err = cscfg_configfs_init(cscfg_mgr);
+ if (err)
+ goto exit_err;
+
+- INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list);
+- INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list);
+- INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
+- INIT_LIST_HEAD(&cscfg_mgr->load_order_list);
+- atomic_set(&cscfg_mgr->sys_active_cnt, 0);
+-
+ /* preload built-in configurations */
+ err = cscfg_preload(THIS_MODULE);
+ if (err)
+--
+2.35.1
+
--- /dev/null
+From 7264a57642a20eaa11fe9379dc156e2d87597b4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jun 2022 18:30:04 +0100
+Subject: coresight: syscfg: Update load and unload operations
+
+From: Mike Leach <mike.leach@linaro.org>
+
+[ Upstream commit 8add26f7ef33bba7984cb6ff7911c6aa970fe55a ]
+
+The configfs system is a source of access to the config information in the
+configuration and feature lists.
+
+This can result in additional LOCKDEP issues as a result of the mutex
+ordering between the config list mutex (cscfg_mutex) and the configfs
+system mutexes.
+
+As such we need to adjust how load/unload operations work to ensure correct
+operation.
+
+1) Previously the cscfg_mutex was held throughout the load/unload
+operation. This is now only held during configuration list manipulations,
+resulting in a multi-stage load/unload process.
+
+2) All operations that manipulate the configfs representation of the
+configurations and features are now separated out and run without the
+cscfg_mutex being held. This avoids circular lock_dep issue with the
+built-in configfs mutexes and semaphores
+
+3) As the load and unload is now multi-stage, some parts under the
+cscfg_mutex and others not:
+i) A flag indicating a load / unload operation in progress is used to
+serialise load / unload operations.
+ii) activating any configuration not possible when unload is in progress.
+iii) Configurations have an "available" flag set only after the last load
+stage for the configuration is complete. Activation of the configuration
+not possible till flag is set.
+
+4) Following load/unload rules remain:
+i) Unload prevented while any configuration is active remains.
+ii) Unload in strict reverse order of load.
+iii) Existing configurations can be activated while a new load operation
+is underway. (by definition there can be no dependencies between an
+existing configuration and a new loading one due to ii) above.)
+
+Fixes: eb2ec49606c2 ("coresight: syscfg: Update load API for config loadable modules")
+Reported-by: Suzuki Poulose <suzuki.poulose@arm.com>
+Signed-off-by: Mike Leach <mike.leach@linaro.org>
+Reviewed-and-tested-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20220628173004.30002-3-mike.leach@linaro.org
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../hwtracing/coresight/coresight-config.h | 2 +
+ .../hwtracing/coresight/coresight-syscfg.c | 191 ++++++++++++++----
+ .../hwtracing/coresight/coresight-syscfg.h | 13 ++
+ 3 files changed, 165 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
+index 2e1670523461..6ba013975741 100644
+--- a/drivers/hwtracing/coresight/coresight-config.h
++++ b/drivers/hwtracing/coresight/coresight-config.h
+@@ -134,6 +134,7 @@ struct cscfg_feature_desc {
+ * @active_cnt: ref count for activate on this configuration.
+ * @load_owner: handle to load owner for dynamic load and unload of configs.
+ * @fs_group: reference to configfs group for dynamic unload.
++ * @available: config can be activated - multi-stage load sets true on completion.
+ */
+ struct cscfg_config_desc {
+ const char *name;
+@@ -148,6 +149,7 @@ struct cscfg_config_desc {
+ atomic_t active_cnt;
+ void *load_owner;
+ struct config_group *fs_group;
++ bool available;
+ };
+
+ /**
+diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
+index 17e728ab5c99..11138a9762b0 100644
+--- a/drivers/hwtracing/coresight/coresight-syscfg.c
++++ b/drivers/hwtracing/coresight/coresight-syscfg.c
+@@ -447,6 +447,8 @@ static void cscfg_unload_owned_cfgs_feats(void *load_owner)
+ struct cscfg_feature_desc *feat_desc, *feat_tmp;
+ struct cscfg_registered_csdev *csdev_item;
+
++ lockdep_assert_held(&cscfg_mutex);
++
+ /* remove from each csdev instance feature and config lists */
+ list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) {
+ /*
+@@ -460,7 +462,6 @@ static void cscfg_unload_owned_cfgs_feats(void *load_owner)
+ /* remove from the config descriptor lists */
+ list_for_each_entry_safe(config_desc, cfg_tmp, &cscfg_mgr->config_desc_list, item) {
+ if (config_desc->load_owner == load_owner) {
+- cscfg_configfs_del_config(config_desc);
+ etm_perf_del_symlink_cscfg(config_desc);
+ list_del(&config_desc->item);
+ }
+@@ -469,12 +470,90 @@ static void cscfg_unload_owned_cfgs_feats(void *load_owner)
+ /* remove from the feature descriptor lists */
+ list_for_each_entry_safe(feat_desc, feat_tmp, &cscfg_mgr->feat_desc_list, item) {
+ if (feat_desc->load_owner == load_owner) {
+- cscfg_configfs_del_feature(feat_desc);
+ list_del(&feat_desc->item);
+ }
+ }
+ }
+
++/*
++ * load the features and configs to the lists - called with list mutex held
++ */
++static int cscfg_load_owned_cfgs_feats(struct cscfg_config_desc **config_descs,
++ struct cscfg_feature_desc **feat_descs,
++ struct cscfg_load_owner_info *owner_info)
++{
++ int i, err;
++
++ lockdep_assert_held(&cscfg_mutex);
++
++ /* load features first */
++ if (feat_descs) {
++ for (i = 0; feat_descs[i]; i++) {
++ err = cscfg_load_feat(feat_descs[i]);
++ if (err) {
++ pr_err("coresight-syscfg: Failed to load feature %s\n",
++ feat_descs[i]->name);
++ return err;
++ }
++ feat_descs[i]->load_owner = owner_info;
++ }
++ }
++
++ /* next any configurations to check feature dependencies */
++ if (config_descs) {
++ for (i = 0; config_descs[i]; i++) {
++ err = cscfg_load_config(config_descs[i]);
++ if (err) {
++ pr_err("coresight-syscfg: Failed to load configuration %s\n",
++ config_descs[i]->name);
++ return err;
++ }
++ config_descs[i]->load_owner = owner_info;
++ config_descs[i]->available = false;
++ }
++ }
++ return 0;
++}
++
++/* set configurations as available to activate at the end of the load process */
++static void cscfg_set_configs_available(struct cscfg_config_desc **config_descs)
++{
++ int i;
++
++ lockdep_assert_held(&cscfg_mutex);
++
++ if (config_descs) {
++ for (i = 0; config_descs[i]; i++)
++ config_descs[i]->available = true;
++ }
++}
++
++/*
++ * Create and register each of the configurations and features with configfs.
++ * Called without mutex being held.
++ */
++static int cscfg_fs_register_cfgs_feats(struct cscfg_config_desc **config_descs,
++ struct cscfg_feature_desc **feat_descs)
++{
++ int i, err;
++
++ if (feat_descs) {
++ for (i = 0; feat_descs[i]; i++) {
++ err = cscfg_configfs_add_feature(feat_descs[i]);
++ if (err)
++ return err;
++ }
++ }
++ if (config_descs) {
++ for (i = 0; config_descs[i]; i++) {
++ err = cscfg_configfs_add_config(config_descs[i]);
++ if (err)
++ return err;
++ }
++ }
++ return 0;
++}
++
+ /**
+ * cscfg_load_config_sets - API function to load feature and config sets.
+ *
+@@ -497,57 +576,63 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs,
+ struct cscfg_feature_desc **feat_descs,
+ struct cscfg_load_owner_info *owner_info)
+ {
+- int err = 0, i = 0;
++ int err = 0;
+
+ mutex_lock(&cscfg_mutex);
+-
+- /* load features first */
+- if (feat_descs) {
+- while (feat_descs[i]) {
+- err = cscfg_load_feat(feat_descs[i]);
+- if (!err)
+- err = cscfg_configfs_add_feature(feat_descs[i]);
+- if (err) {
+- pr_err("coresight-syscfg: Failed to load feature %s\n",
+- feat_descs[i]->name);
+- cscfg_unload_owned_cfgs_feats(owner_info);
+- goto exit_unlock;
+- }
+- feat_descs[i]->load_owner = owner_info;
+- i++;
+- }
++ if (cscfg_mgr->load_state != CSCFG_NONE) {
++ mutex_unlock(&cscfg_mutex);
++ return -EBUSY;
+ }
++ cscfg_mgr->load_state = CSCFG_LOAD;
+
+- /* next any configurations to check feature dependencies */
+- i = 0;
+- if (config_descs) {
+- while (config_descs[i]) {
+- err = cscfg_load_config(config_descs[i]);
+- if (!err)
+- err = cscfg_configfs_add_config(config_descs[i]);
+- if (err) {
+- pr_err("coresight-syscfg: Failed to load configuration %s\n",
+- config_descs[i]->name);
+- cscfg_unload_owned_cfgs_feats(owner_info);
+- goto exit_unlock;
+- }
+- config_descs[i]->load_owner = owner_info;
+- i++;
+- }
+- }
++ /* first load and add to the lists */
++ err = cscfg_load_owned_cfgs_feats(config_descs, feat_descs, owner_info);
++ if (err)
++ goto err_clean_load;
+
+ /* add the load owner to the load order list */
+ list_add_tail(&owner_info->item, &cscfg_mgr->load_order_list);
+ if (!list_is_singular(&cscfg_mgr->load_order_list)) {
+ /* lock previous item in load order list */
+ err = cscfg_owner_get(list_prev_entry(owner_info, item));
+- if (err) {
+- cscfg_unload_owned_cfgs_feats(owner_info);
+- list_del(&owner_info->item);
+- }
++ if (err)
++ goto err_clean_owner_list;
+ }
+
++ /*
++ * make visible to configfs - configfs manipulation must occur outside
++ * the list mutex lock to avoid circular lockdep issues with configfs
++ * built in mutexes and semaphores. This is safe as it is not possible
++ * to start a new load/unload operation till the current one is done.
++ */
++ mutex_unlock(&cscfg_mutex);
++
++ /* create the configfs elements */
++ err = cscfg_fs_register_cfgs_feats(config_descs, feat_descs);
++ mutex_lock(&cscfg_mutex);
++
++ if (err)
++ goto err_clean_cfs;
++
++ /* mark any new configs as available for activation */
++ cscfg_set_configs_available(config_descs);
++ goto exit_unlock;
++
++err_clean_cfs:
++ /* cleanup after error registering with configfs */
++ cscfg_fs_unregister_cfgs_feats(owner_info);
++
++ if (!list_is_singular(&cscfg_mgr->load_order_list))
++ cscfg_owner_put(list_prev_entry(owner_info, item));
++
++err_clean_owner_list:
++ list_del(&owner_info->item);
++
++err_clean_load:
++ cscfg_unload_owned_cfgs_feats(owner_info);
++
+ exit_unlock:
++ cscfg_mgr->load_state = CSCFG_NONE;
+ mutex_unlock(&cscfg_mutex);
+ return err;
+ }
+@@ -564,6 +649,9 @@ EXPORT_SYMBOL_GPL(cscfg_load_config_sets);
+ * 1) no configurations are active.
+ * 2) the set being unloaded was the last to be loaded to maintain dependencies.
+ *
++ * Once the unload operation commences, we disallow any configuration being
++ * made active until it is complete.
++ *
+ * @owner_info: Information on owner for set being unloaded.
+ */
+ int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info)
+@@ -572,6 +660,13 @@ int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info)
+ struct cscfg_load_owner_info *load_list_item = NULL;
+
+ mutex_lock(&cscfg_mutex);
++ if (cscfg_mgr->load_state != CSCFG_NONE) {
++ mutex_unlock(&cscfg_mutex);
++ return -EBUSY;
++ }
++
++ /* unload op in progress also prevents activation of any config */
++ cscfg_mgr->load_state = CSCFG_UNLOAD;
+
+ /* cannot unload if anything is active */
+ if (atomic_read(&cscfg_mgr->sys_active_cnt)) {
+@@ -592,7 +687,12 @@ int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info)
+ goto exit_unlock;
+ }
+
+- /* unload all belonging to load_owner */
++ /* remove from configfs - again outside the scope of the list mutex */
++ mutex_unlock(&cscfg_mutex);
++ cscfg_fs_unregister_cfgs_feats(owner_info);
++ mutex_lock(&cscfg_mutex);
++
++ /* unload everything from lists belonging to load_owner */
+ cscfg_unload_owned_cfgs_feats(owner_info);
+
+ /* remove from load order list */
+@@ -603,6 +703,7 @@ int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info)
+ list_del(&owner_info->item);
+
+ exit_unlock:
++ cscfg_mgr->load_state = CSCFG_NONE;
+ mutex_unlock(&cscfg_mutex);
+ return err;
+ }
+@@ -780,8 +881,15 @@ static int _cscfg_activate_config(unsigned long cfg_hash)
+ struct cscfg_config_desc *config_desc;
+ int err = -EINVAL;
+
++ if (cscfg_mgr->load_state == CSCFG_UNLOAD)
++ return -EBUSY;
++
+ list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
+ if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
++ /* if we happen upon a partly loaded config, can't use it */
++ if (config_desc->available == false)
++ return -EBUSY;
++
+ /* must ensure that config cannot be unloaded in use */
+ err = cscfg_owner_get(config_desc->load_owner);
+ if (err)
+@@ -1071,6 +1179,7 @@ static int cscfg_create_device(void)
+ INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
+ INIT_LIST_HEAD(&cscfg_mgr->load_order_list);
+ atomic_set(&cscfg_mgr->sys_active_cnt, 0);
++ cscfg_mgr->load_state = CSCFG_NONE;
+
+ /* setup the device */
+ dev = cscfg_device();
+diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h
+index 9106ffab4833..66e2db890d82 100644
+--- a/drivers/hwtracing/coresight/coresight-syscfg.h
++++ b/drivers/hwtracing/coresight/coresight-syscfg.h
+@@ -12,6 +12,17 @@
+
+ #include "coresight-config.h"
+
++/*
++ * Load operation types.
++ * When loading or unloading, another load operation cannot be run.
++ * When unloading configurations cannot be activated.
++ */
++enum cscfg_load_ops {
++ CSCFG_NONE,
++ CSCFG_LOAD,
++ CSCFG_UNLOAD
++};
++
+ /**
+ * System configuration manager device.
+ *
+@@ -30,6 +41,7 @@
+ * @cfgfs_subsys: configfs subsystem used to manage configurations.
+ * @sysfs_active_config:Active config hash used if CoreSight controlled from sysfs.
+ * @sysfs_active_preset:Active preset index used if CoreSight controlled from sysfs.
++ * @load_state: A multi-stage load/unload operation is in progress.
+ */
+ struct cscfg_manager {
+ struct device dev;
+@@ -41,6 +53,7 @@ struct cscfg_manager {
+ struct configfs_subsystem cfgfs_subsys;
+ u32 sysfs_active_config;
+ int sysfs_active_preset;
++ enum cscfg_load_ops load_state;
+ };
+
+ /* get reference to dev in cscfg_manager */
+--
+2.35.1
+
--- /dev/null
+From 38511ea926a7a558be4dd7dad4b4007082b06f2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jun 2022 12:28:07 +0400
+Subject: cpufreq: zynq: Fix refcount leak in zynq_get_revision
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit d1ff2559cef0f6f8d97fba6337b28adb10689e16 ]
+
+of_find_compatible_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when done.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 00f7dc636366 ("ARM: zynq: Add support for SOC_BUS")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220605082807.21526-1-linmq006@gmail.com
+Signed-off-by: Michal Simek <michal.simek@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-zynq/common.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
+index e1ca6a5732d2..15e8a321a713 100644
+--- a/arch/arm/mach-zynq/common.c
++++ b/arch/arm/mach-zynq/common.c
+@@ -77,6 +77,7 @@ static int __init zynq_get_revision(void)
+ }
+
+ zynq_devcfg_base = of_iomap(np, 0);
++ of_node_put(np);
+ if (!zynq_devcfg_base) {
+ pr_err("%s: Unable to map I/O memory\n", __func__);
+ return -1;
+--
+2.35.1
+
--- /dev/null
+From b85c7b874a0890efc185a2ff55bd409a28ee6a58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 07:13:38 -0400
+Subject: crypto: arm64/gcm - Select AEAD for GHASH_ARM64_CE
+
+From: Qian Cai <quic_qiancai@quicinc.com>
+
+[ Upstream commit fac76f2260893dde5aa05bb693b4c13e8ed0454b ]
+
+Otherwise, we could fail to compile.
+
+ld: arch/arm64/crypto/ghash-ce-glue.o: in function 'ghash_ce_mod_exit':
+ghash-ce-glue.c:(.exit.text+0x24): undefined reference to 'crypto_unregister_aead'
+ld: arch/arm64/crypto/ghash-ce-glue.o: in function 'ghash_ce_mod_init':
+ghash-ce-glue.c:(.init.text+0x34): undefined reference to 'crypto_register_aead'
+
+Fixes: 537c1445ab0b ("crypto: arm64/gcm - implement native driver using v8 Crypto Extensions")
+Signed-off-by: Qian Cai <quic_qiancai@quicinc.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/crypto/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
+index 2a965aa0188d..bdca34283c06 100644
+--- a/arch/arm64/crypto/Kconfig
++++ b/arch/arm64/crypto/Kconfig
+@@ -59,6 +59,7 @@ config CRYPTO_GHASH_ARM64_CE
+ select CRYPTO_HASH
+ select CRYPTO_GF128MUL
+ select CRYPTO_LIB_AES
++ select CRYPTO_AEAD
+
+ config CRYPTO_CRCT10DIF_ARM64_CE
+ tristate "CRCT10DIF digest algorithm using PMULL instructions"
+--
+2.35.1
+
--- /dev/null
+From 898cab7f1c885c967206daad26e578b065d4a1d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 10:26:18 -0500
+Subject: crypto: ccp - During shutdown, check SEV data pointer before using
+
+From: Tom Lendacky <thomas.lendacky@amd.com>
+
+[ Upstream commit 1b05ece0c931536c0a38a9385e243a7962e933f6 ]
+
+On shutdown, each CCP device instance performs shutdown processing.
+However, __sev_platform_shutdown_locked() uses the controlling psp
+structure to obtain the pointer to the sev_device structure. However,
+during driver initialization, it is possible that an error can be received
+from the firmware that results in the sev_data pointer being cleared from
+the controlling psp structure. The __sev_platform_shutdown_locked()
+function does not check for this situation and will segfault.
+
+While not common, this scenario should be accounted for. Add a check for a
+NULL sev_device structure before attempting to use it.
+
+Fixes: 5441a07a127f ("crypto: ccp - shutdown SEV firmware on kexec")
+Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/ccp/sev-dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
+index 812c1356a0f8..95dbab0ffab2 100644
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -503,7 +503,7 @@ static int __sev_platform_shutdown_locked(int *error)
+ struct sev_device *sev = psp_master->sev_data;
+ int ret;
+
+- if (sev->state == SEV_STATE_UNINIT)
++ if (!sev || sev->state == SEV_STATE_UNINIT)
+ return 0;
+
+ ret = __sev_do_cmd_locked(SEV_CMD_SHUTDOWN, NULL, error);
+--
+2.35.1
+
--- /dev/null
+From 150d3de737d98f8052638cb9af0705f5357fb0a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 12:23:23 +0800
+Subject: crypto: hisilicon/hpre - don't use GFP_KERNEL to alloc mem during
+ softirq
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit 98dfa9343f37bdd4112966292751e3a93aaf2e56 ]
+
+The hpre encryption driver may be used to encrypt and decrypt packets
+during the rx softirq, it is not allowed to use GFP_KERNEL.
+
+Fixes: c8b4b477079d ("crypto: hisilicon - add HiSilicon HPRE accelerator")
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/hpre/hpre_crypto.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
+index 97d54c1465c2..3ba6f15deafc 100644
+--- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c
++++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
+@@ -252,7 +252,7 @@ static int hpre_prepare_dma_buf(struct hpre_asym_request *hpre_req,
+ if (unlikely(shift < 0))
+ return -EINVAL;
+
+- ptr = dma_alloc_coherent(dev, ctx->key_sz, tmp, GFP_KERNEL);
++ ptr = dma_alloc_coherent(dev, ctx->key_sz, tmp, GFP_ATOMIC);
+ if (unlikely(!ptr))
+ return -ENOMEM;
+
+--
+2.35.1
+
--- /dev/null
+From a1da4978c57a432668705497bed73899ef9bdf7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 09:59:54 +0800
+Subject: crypto: hisilicon - Kunpeng916 crypto driver don't sleep when in
+ softirq
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit 68740ab505431f268dc1ee26a54b871e75f0ddaa ]
+
+When kunpeng916 encryption driver is used to deencrypt and decrypt
+packets during the softirq, it is not allowed to use mutex lock.
+
+Fixes: 915e4e8413da ("crypto: hisilicon - SEC security accelerator driver")
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/sec/sec_algs.c | 14 +++++++-------
+ drivers/crypto/hisilicon/sec/sec_drv.h | 2 +-
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/crypto/hisilicon/sec/sec_algs.c b/drivers/crypto/hisilicon/sec/sec_algs.c
+index 0a3c8f019b02..490e1542305e 100644
+--- a/drivers/crypto/hisilicon/sec/sec_algs.c
++++ b/drivers/crypto/hisilicon/sec/sec_algs.c
+@@ -449,7 +449,7 @@ static void sec_skcipher_alg_callback(struct sec_bd_info *sec_resp,
+ */
+ }
+
+- mutex_lock(&ctx->queue->queuelock);
++ spin_lock_bh(&ctx->queue->queuelock);
+ /* Put the IV in place for chained cases */
+ switch (ctx->cipher_alg) {
+ case SEC_C_AES_CBC_128:
+@@ -509,7 +509,7 @@ static void sec_skcipher_alg_callback(struct sec_bd_info *sec_resp,
+ list_del(&backlog_req->backlog_head);
+ }
+ }
+- mutex_unlock(&ctx->queue->queuelock);
++ spin_unlock_bh(&ctx->queue->queuelock);
+
+ mutex_lock(&sec_req->lock);
+ list_del(&sec_req_el->head);
+@@ -798,7 +798,7 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
+ */
+
+ /* Grab a big lock for a long time to avoid concurrency issues */
+- mutex_lock(&queue->queuelock);
++ spin_lock_bh(&queue->queuelock);
+
+ /*
+ * Can go on to queue if we have space in either:
+@@ -814,15 +814,15 @@ static int sec_alg_skcipher_crypto(struct skcipher_request *skreq,
+ ret = -EBUSY;
+ if ((skreq->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
+ list_add_tail(&sec_req->backlog_head, &ctx->backlog);
+- mutex_unlock(&queue->queuelock);
++ spin_unlock_bh(&queue->queuelock);
+ goto out;
+ }
+
+- mutex_unlock(&queue->queuelock);
++ spin_unlock_bh(&queue->queuelock);
+ goto err_free_elements;
+ }
+ ret = sec_send_request(sec_req, queue);
+- mutex_unlock(&queue->queuelock);
++ spin_unlock_bh(&queue->queuelock);
+ if (ret)
+ goto err_free_elements;
+
+@@ -881,7 +881,7 @@ static int sec_alg_skcipher_init(struct crypto_skcipher *tfm)
+ if (IS_ERR(ctx->queue))
+ return PTR_ERR(ctx->queue);
+
+- mutex_init(&ctx->queue->queuelock);
++ spin_lock_init(&ctx->queue->queuelock);
+ ctx->queue->havesoftqueue = false;
+
+ return 0;
+diff --git a/drivers/crypto/hisilicon/sec/sec_drv.h b/drivers/crypto/hisilicon/sec/sec_drv.h
+index 179a8250d691..e2a50bf2234b 100644
+--- a/drivers/crypto/hisilicon/sec/sec_drv.h
++++ b/drivers/crypto/hisilicon/sec/sec_drv.h
+@@ -347,7 +347,7 @@ struct sec_queue {
+ DECLARE_BITMAP(unprocessed, SEC_QUEUE_LEN);
+ DECLARE_KFIFO_PTR(softqueue, typeof(struct sec_request_el *));
+ bool havesoftqueue;
+- struct mutex queuelock;
++ spinlock_t queuelock;
+ void *shadow[SEC_QUEUE_LEN];
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 95e2593f1a154c5711a84855bda79bfd9a8e585f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 09:55:11 +0800
+Subject: crypto: hisilicon/sec - don't sleep when in softirq
+
+From: Zhengchao Shao <shaozhengchao@huawei.com>
+
+[ Upstream commit 02884a4f12de11f54d4ca67a07dd1f111d96fdbd ]
+
+When kunpeng920 encryption driver is used to deencrypt and decrypt
+packets during the softirq, it is not allowed to use mutex lock. The
+kernel will report the following error:
+
+BUG: scheduling while atomic: swapper/57/0/0x00000300
+Call trace:
+dump_backtrace+0x0/0x1e4
+show_stack+0x20/0x2c
+dump_stack+0xd8/0x140
+__schedule_bug+0x68/0x80
+__schedule+0x728/0x840
+schedule+0x50/0xe0
+schedule_preempt_disabled+0x18/0x24
+__mutex_lock.constprop.0+0x594/0x5dc
+__mutex_lock_slowpath+0x1c/0x30
+mutex_lock+0x50/0x60
+sec_request_init+0x8c/0x1a0 [hisi_sec2]
+sec_process+0x28/0x1ac [hisi_sec2]
+sec_skcipher_crypto+0xf4/0x1d4 [hisi_sec2]
+sec_skcipher_encrypt+0x1c/0x30 [hisi_sec2]
+crypto_skcipher_encrypt+0x2c/0x40
+crypto_authenc_encrypt+0xc8/0xfc [authenc]
+crypto_aead_encrypt+0x2c/0x40
+echainiv_encrypt+0x144/0x1a0 [echainiv]
+crypto_aead_encrypt+0x2c/0x40
+esp_output_tail+0x348/0x5c0 [esp4]
+esp_output+0x120/0x19c [esp4]
+xfrm_output_one+0x25c/0x4d4
+xfrm_output_resume+0x6c/0x1fc
+xfrm_output+0xac/0x3c0
+xfrm4_output+0x64/0x130
+ip_build_and_send_pkt+0x158/0x20c
+tcp_v4_send_synack+0xdc/0x1f0
+tcp_conn_request+0x7d0/0x994
+tcp_v4_conn_request+0x58/0x6c
+tcp_v6_conn_request+0xf0/0x100
+tcp_rcv_state_process+0x1cc/0xd60
+tcp_v4_do_rcv+0x10c/0x250
+tcp_v4_rcv+0xfc4/0x10a4
+ip_protocol_deliver_rcu+0xf4/0x200
+ip_local_deliver_finish+0x58/0x70
+ip_local_deliver+0x68/0x120
+ip_sublist_rcv_finish+0x70/0x94
+ip_list_rcv_finish.constprop.0+0x17c/0x1d0
+ip_sublist_rcv+0x40/0xb0
+ip_list_rcv+0x140/0x1dc
+__netif_receive_skb_list_core+0x154/0x28c
+__netif_receive_skb_list+0x120/0x1a0
+netif_receive_skb_list_internal+0xe4/0x1f0
+napi_complete_done+0x70/0x1f0
+gro_cell_poll+0x9c/0xb0
+napi_poll+0xcc/0x264
+net_rx_action+0xd4/0x21c
+__do_softirq+0x130/0x358
+irq_exit+0x11c/0x13c
+__handle_domain_irq+0x88/0xf0
+gic_handle_irq+0x78/0x2c0
+el1_irq+0xb8/0x140
+arch_cpu_idle+0x18/0x40
+default_idle_call+0x5c/0x1c0
+cpuidle_idle_call+0x174/0x1b0
+do_idle+0xc8/0x160
+cpu_startup_entry+0x30/0x11c
+secondary_start_kernel+0x158/0x1e4
+softirq: huh, entered softirq 3 NET_RX 0000000093774ee4 with
+preempt_count 00000100, exited with fffffe00?
+
+Fixes: 416d82204df4 ("crypto: hisilicon - add HiSilicon SEC V2 driver")
+Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/sec2/sec.h | 2 +-
+ drivers/crypto/hisilicon/sec2/sec_crypto.c | 20 ++++++++++----------
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h
+index c2e9b01187a7..a44c8dba3cda 100644
+--- a/drivers/crypto/hisilicon/sec2/sec.h
++++ b/drivers/crypto/hisilicon/sec2/sec.h
+@@ -119,7 +119,7 @@ struct sec_qp_ctx {
+ struct idr req_idr;
+ struct sec_alg_res res[QM_Q_DEPTH];
+ struct sec_ctx *ctx;
+- struct mutex req_lock;
++ spinlock_t req_lock;
+ struct list_head backlog;
+ struct hisi_acc_sgl_pool *c_in_pool;
+ struct hisi_acc_sgl_pool *c_out_pool;
+diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+index a91635c348b5..f193d6b6fa16 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+@@ -127,11 +127,11 @@ static int sec_alloc_req_id(struct sec_req *req, struct sec_qp_ctx *qp_ctx)
+ {
+ int req_id;
+
+- mutex_lock(&qp_ctx->req_lock);
++ spin_lock_bh(&qp_ctx->req_lock);
+
+ req_id = idr_alloc_cyclic(&qp_ctx->req_idr, NULL,
+ 0, QM_Q_DEPTH, GFP_ATOMIC);
+- mutex_unlock(&qp_ctx->req_lock);
++ spin_unlock_bh(&qp_ctx->req_lock);
+ if (unlikely(req_id < 0)) {
+ dev_err(req->ctx->dev, "alloc req id fail!\n");
+ return req_id;
+@@ -156,9 +156,9 @@ static void sec_free_req_id(struct sec_req *req)
+ qp_ctx->req_list[req_id] = NULL;
+ req->qp_ctx = NULL;
+
+- mutex_lock(&qp_ctx->req_lock);
++ spin_lock_bh(&qp_ctx->req_lock);
+ idr_remove(&qp_ctx->req_idr, req_id);
+- mutex_unlock(&qp_ctx->req_lock);
++ spin_unlock_bh(&qp_ctx->req_lock);
+ }
+
+ static u8 pre_parse_finished_bd(struct bd_status *status, void *resp)
+@@ -273,7 +273,7 @@ static int sec_bd_send(struct sec_ctx *ctx, struct sec_req *req)
+ !(req->flag & CRYPTO_TFM_REQ_MAY_BACKLOG))
+ return -EBUSY;
+
+- mutex_lock(&qp_ctx->req_lock);
++ spin_lock_bh(&qp_ctx->req_lock);
+ ret = hisi_qp_send(qp_ctx->qp, &req->sec_sqe);
+
+ if (ctx->fake_req_limit <=
+@@ -281,10 +281,10 @@ static int sec_bd_send(struct sec_ctx *ctx, struct sec_req *req)
+ list_add_tail(&req->backlog_head, &qp_ctx->backlog);
+ atomic64_inc(&ctx->sec->debug.dfx.send_cnt);
+ atomic64_inc(&ctx->sec->debug.dfx.send_busy_cnt);
+- mutex_unlock(&qp_ctx->req_lock);
++ spin_unlock_bh(&qp_ctx->req_lock);
+ return -EBUSY;
+ }
+- mutex_unlock(&qp_ctx->req_lock);
++ spin_unlock_bh(&qp_ctx->req_lock);
+
+ if (unlikely(ret == -EBUSY))
+ return -ENOBUFS;
+@@ -487,7 +487,7 @@ static int sec_create_qp_ctx(struct hisi_qm *qm, struct sec_ctx *ctx,
+
+ qp->req_cb = sec_req_cb;
+
+- mutex_init(&qp_ctx->req_lock);
++ spin_lock_init(&qp_ctx->req_lock);
+ idr_init(&qp_ctx->req_idr);
+ INIT_LIST_HEAD(&qp_ctx->backlog);
+
+@@ -1382,7 +1382,7 @@ static struct sec_req *sec_back_req_clear(struct sec_ctx *ctx,
+ {
+ struct sec_req *backlog_req = NULL;
+
+- mutex_lock(&qp_ctx->req_lock);
++ spin_lock_bh(&qp_ctx->req_lock);
+ if (ctx->fake_req_limit >=
+ atomic_read(&qp_ctx->qp->qp_status.used) &&
+ !list_empty(&qp_ctx->backlog)) {
+@@ -1390,7 +1390,7 @@ static struct sec_req *sec_back_req_clear(struct sec_ctx *ctx,
+ typeof(*backlog_req), backlog_head);
+ list_del(&backlog_req->backlog_head);
+ }
+- mutex_unlock(&qp_ctx->req_lock);
++ spin_unlock_bh(&qp_ctx->req_lock);
+
+ return backlog_req;
+ }
+--
+2.35.1
+
--- /dev/null
+From 795160f0a6e0c58d49a1afd5f69936dab6e6de11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 10:18:31 +0800
+Subject: crypto: hisilicon/sec - fix auth key size error
+
+From: Kai Ye <yekai13@huawei.com>
+
+[ Upstream commit 45f5d0176d8426cc1ab0bab84fbd8ef5c57526c6 ]
+
+The authentication algorithm supports a maximum of 128-byte keys.
+The allocated key memory is insufficient.
+
+Fixes: 2f072d75d1ab ("crypto: hisilicon - Add aead support on SEC2")
+Signed-off-by: Kai Ye <yekai13@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/hisilicon/sec2/sec_crypto.c | 6 +++---
+ drivers/crypto/hisilicon/sec2/sec_crypto.h | 1 +
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+index f193d6b6fa16..dbaa6c918cfd 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
+@@ -620,7 +620,7 @@ static int sec_auth_init(struct sec_ctx *ctx)
+ {
+ struct sec_auth_ctx *a_ctx = &ctx->a_ctx;
+
+- a_ctx->a_key = dma_alloc_coherent(ctx->dev, SEC_MAX_KEY_SIZE,
++ a_ctx->a_key = dma_alloc_coherent(ctx->dev, SEC_MAX_AKEY_SIZE,
+ &a_ctx->a_key_dma, GFP_KERNEL);
+ if (!a_ctx->a_key)
+ return -ENOMEM;
+@@ -632,8 +632,8 @@ static void sec_auth_uninit(struct sec_ctx *ctx)
+ {
+ struct sec_auth_ctx *a_ctx = &ctx->a_ctx;
+
+- memzero_explicit(a_ctx->a_key, SEC_MAX_KEY_SIZE);
+- dma_free_coherent(ctx->dev, SEC_MAX_KEY_SIZE,
++ memzero_explicit(a_ctx->a_key, SEC_MAX_AKEY_SIZE);
++ dma_free_coherent(ctx->dev, SEC_MAX_AKEY_SIZE,
+ a_ctx->a_key, a_ctx->a_key_dma);
+ }
+
+diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.h b/drivers/crypto/hisilicon/sec2/sec_crypto.h
+index 5e039b50e9d4..d033f63b583f 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_crypto.h
++++ b/drivers/crypto/hisilicon/sec2/sec_crypto.h
+@@ -7,6 +7,7 @@
+ #define SEC_AIV_SIZE 12
+ #define SEC_IV_SIZE 24
+ #define SEC_MAX_KEY_SIZE 64
++#define SEC_MAX_AKEY_SIZE 128
+ #define SEC_COMM_SCENE 0
+ #define SEC_MIN_BLOCK_SZ 1
+
+--
+2.35.1
+
--- /dev/null
+From 8e9aa366ae3c6438b6300337691adb9a95ca2590 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 09:54:03 +0200
+Subject: crypto: inside-secure - Add missing MODULE_DEVICE_TABLE for of
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit fa4d57b85786ec0e16565c75a51c208834b0c24d ]
+
+Without MODULE_DEVICE_TABLE, crypto_safexcel.ko module is not automatically
+loaded on platforms where inside-secure crypto HW is specified in device
+tree (e.g. Armada 3720). So add missing MODULE_DEVICE_TABLE for of.
+
+Fixes: 1b44c5a60c13 ("crypto: inside-secure - add SafeXcel EIP197 crypto engine driver")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Acked-by: Marek Behún <kabel@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/inside-secure/safexcel.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index 9ff885d50edf..389a7b51f1f3 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -1831,6 +1831,8 @@ static const struct of_device_id safexcel_of_match_table[] = {
+ {},
+ };
+
++MODULE_DEVICE_TABLE(of, safexcel_of_match_table);
++
+ static struct platform_driver crypto_safexcel = {
+ .probe = safexcel_probe,
+ .remove = safexcel_remove,
+--
+2.35.1
+
--- /dev/null
+From 6a8f5ea6d0093c866abf03fdf9617c3f7c18b6d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 May 2022 20:19:19 +0000
+Subject: crypto: sun8i-ss - do not allocate memory when handling hash requests
+
+From: Corentin Labbe <clabbe@baylibre.com>
+
+[ Upstream commit 8eec4563f152981a441693fc97c5459843dc5e6e ]
+
+Instead of allocate memory on each requests, it is easier to
+pre-allocate buffers.
+This made error path easier.
+
+Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 10 ++++++++++
+ drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 15 +++------------
+ drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h | 4 ++++
+ 3 files changed, 17 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+index 657530578643..786b6f5cf300 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+@@ -486,6 +486,16 @@ static int allocate_flows(struct sun8i_ss_dev *ss)
+ goto error_engine;
+ }
+
++ /* the padding could be up to two block. */
++ ss->flows[i].pad = devm_kmalloc(ss->dev, SHA256_BLOCK_SIZE * 2,
++ GFP_KERNEL | GFP_DMA);
++ if (!ss->flows[i].pad)
++ goto error_engine;
++ ss->flows[i].result = devm_kmalloc(ss->dev, SHA256_DIGEST_SIZE,
++ GFP_KERNEL | GFP_DMA);
++ if (!ss->flows[i].result)
++ goto error_engine;
++
+ ss->flows[i].engine = crypto_engine_alloc_init(ss->dev, true);
+ if (!ss->flows[i].engine) {
+ dev_err(ss->dev, "Cannot allocate engine\n");
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
+index ca4f280af35d..f89a580618aa 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
+@@ -342,18 +342,11 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
+ if (digestsize == SHA224_DIGEST_SIZE)
+ digestsize = SHA256_DIGEST_SIZE;
+
+- /* the padding could be up to two block. */
+- pad = kzalloc(algt->alg.hash.halg.base.cra_blocksize * 2, GFP_KERNEL | GFP_DMA);
+- if (!pad)
+- return -ENOMEM;
++ result = ss->flows[rctx->flow].result;
++ pad = ss->flows[rctx->flow].pad;
++ memset(pad, 0, algt->alg.hash.halg.base.cra_blocksize * 2);
+ bf = (__le32 *)pad;
+
+- result = kzalloc(digestsize, GFP_KERNEL | GFP_DMA);
+- if (!result) {
+- kfree(pad);
+- return -ENOMEM;
+- }
+-
+ for (i = 0; i < MAX_SG; i++) {
+ rctx->t_dst[i].addr = 0;
+ rctx->t_dst[i].len = 0;
+@@ -449,8 +442,6 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
+
+ memcpy(areq->result, result, algt->alg.hash.halg.digestsize);
+ theend:
+- kfree(pad);
+- kfree(result);
+ local_bh_disable();
+ crypto_finalize_hash_request(engine, breq, err);
+ local_bh_enable();
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
+index 57ada8653855..eb82ee5345ae 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
+@@ -123,6 +123,8 @@ struct sginfo {
+ * @stat_req: number of request done by this flow
+ * @iv: list of IV to use for each step
+ * @biv: buffer which contain the backuped IV
++ * @pad: padding buffer for hash operations
++ * @result: buffer for storing the result of hash operations
+ */
+ struct sun8i_ss_flow {
+ struct crypto_engine *engine;
+@@ -130,6 +132,8 @@ struct sun8i_ss_flow {
+ int status;
+ u8 *iv[MAX_SG];
+ u8 *biv;
++ void *pad;
++ void *result;
+ #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
+ unsigned long stat_req;
+ #endif
+--
+2.35.1
+
--- /dev/null
+From bd82e6169116bd4c31188c47156c4cfc313cb781 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 May 2022 20:33:44 +0300
+Subject: crypto: sun8i-ss - fix error codes in allocate_flows()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit d2765e1b9ac4b2d5a5d5bf17f468c9b3566c3770 ]
+
+These failure paths should return -ENOMEM. Currently they return
+success.
+
+Fixes: 359e893e8af4 ("crypto: sun8i-ss - rework handling of IV")
+Fixes: 8eec4563f152 ("crypto: sun8i-ss - do not allocate memory when handling hash requests")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Corentin Labbe <clabbe.montjoie@gmail.com>
+Tested-by: Corentin Labbe <clabbe.montjoie@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+index 786b6f5cf300..47b5828e35c3 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+@@ -476,25 +476,33 @@ static int allocate_flows(struct sun8i_ss_dev *ss)
+
+ ss->flows[i].biv = devm_kmalloc(ss->dev, AES_BLOCK_SIZE,
+ GFP_KERNEL | GFP_DMA);
+- if (!ss->flows[i].biv)
++ if (!ss->flows[i].biv) {
++ err = -ENOMEM;
+ goto error_engine;
++ }
+
+ for (j = 0; j < MAX_SG; j++) {
+ ss->flows[i].iv[j] = devm_kmalloc(ss->dev, AES_BLOCK_SIZE,
+ GFP_KERNEL | GFP_DMA);
+- if (!ss->flows[i].iv[j])
++ if (!ss->flows[i].iv[j]) {
++ err = -ENOMEM;
+ goto error_engine;
++ }
+ }
+
+ /* the padding could be up to two block. */
+ ss->flows[i].pad = devm_kmalloc(ss->dev, SHA256_BLOCK_SIZE * 2,
+ GFP_KERNEL | GFP_DMA);
+- if (!ss->flows[i].pad)
++ if (!ss->flows[i].pad) {
++ err = -ENOMEM;
+ goto error_engine;
++ }
+ ss->flows[i].result = devm_kmalloc(ss->dev, SHA256_DIGEST_SIZE,
+ GFP_KERNEL | GFP_DMA);
+- if (!ss->flows[i].result)
++ if (!ss->flows[i].result) {
++ err = -ENOMEM;
+ goto error_engine;
++ }
+
+ ss->flows[i].engine = crypto_engine_alloc_init(ss->dev, true);
+ if (!ss->flows[i].engine) {
+--
+2.35.1
+
--- /dev/null
+From 7ada8da4df056193cdfe1e03d89ed8ed280d89ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 21:27:15 +0300
+Subject: crypto: sun8i-ss - fix infinite loop in sun8i_ss_setup_ivs()
+
+From: Alexey Khoroshilov <khoroshilov@ispras.ru>
+
+[ Upstream commit d61a7b3decf7f0cf4121a7204303deefd2c7151b ]
+
+There is no i decrement in while (i >= 0) loop.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
+Fixes: 359e893e8af4 ("crypto: sun8i-ss - rework handling of IV")
+Acked-by: Corentin Labbe <clabbe.montjoie@gmail.com>
+Tested-by: Corentin Labbe <clabbe.montjoie@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+index 70e2e6e37389..3c46ad8c3a1c 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+@@ -151,6 +151,7 @@ static int sun8i_ss_setup_ivs(struct skcipher_request *areq)
+ while (i >= 0) {
+ dma_unmap_single(ss->dev, rctx->p_iv[i], ivsize, DMA_TO_DEVICE);
+ memzero_explicit(sf->iv[i], ivsize);
++ i--;
+ }
+ return err;
+ }
+--
+2.35.1
+
--- /dev/null
+From 2e347fa84d615f49ec87474d850ff0707e353e3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Jul 2022 19:00:27 +0800
+Subject: dccp: put dccp_qpolicy_full() and dccp_qpolicy_push() in the same
+ lock
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit a41b17ff9dacd22f5f118ee53d82da0f3e52d5e3 ]
+
+In the case of sk->dccps_qpolicy == DCCPQ_POLICY_PRIO, dccp_qpolicy_full
+will drop a skb when qpolicy is full. And the lock in dccp_sendmsg is
+released before sock_alloc_send_skb and then relocked after
+sock_alloc_send_skb. The following conditions may lead dccp_qpolicy_push
+to add skb to an already full sk_write_queue:
+
+thread1--->lock
+thread1--->dccp_qpolicy_full: queue is full. drop a skb
+thread1--->unlock
+thread2--->lock
+thread2--->dccp_qpolicy_full: queue is not full. no need to drop.
+thread2--->unlock
+thread1--->lock
+thread1--->dccp_qpolicy_push: add a skb. queue is full.
+thread1--->unlock
+thread2--->lock
+thread2--->dccp_qpolicy_push: add a skb!
+thread2--->unlock
+
+Fix this by moving dccp_qpolicy_full.
+
+Fixes: b1308dc015eb ("[DCCP]: Set TX Queue Length Bounds via Sysctl")
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Link: https://lore.kernel.org/r/20220729110027.40569-1-hbh25y@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dccp/proto.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/dccp/proto.c b/net/dccp/proto.c
+index a976b4d29892..0ee62506105a 100644
+--- a/net/dccp/proto.c
++++ b/net/dccp/proto.c
+@@ -736,11 +736,6 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+
+ lock_sock(sk);
+
+- if (dccp_qpolicy_full(sk)) {
+- rc = -EAGAIN;
+- goto out_release;
+- }
+-
+ timeo = sock_sndtimeo(sk, noblock);
+
+ /*
+@@ -759,6 +754,11 @@ int dccp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+ if (skb == NULL)
+ goto out_release;
+
++ if (dccp_qpolicy_full(sk)) {
++ rc = -EAGAIN;
++ goto out_discard;
++ }
++
+ if (sk->sk_state == DCCP_CLOSED) {
+ rc = -ENOTCONN;
+ goto out_discard;
+--
+2.35.1
+
--- /dev/null
+From 33a6f4acaaeecdf23199050cff1513d50591ce87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 15:31:23 -0400
+Subject: dm: return early from dm_pr_call() if DM device is suspended
+
+From: Mike Snitzer <snitzer@kernel.org>
+
+[ Upstream commit e120a5f1e78fab6223544e425015f393d90d6f0d ]
+
+Otherwise PR ops may be issued while the broader DM device is being
+reconfigured, etc.
+
+Fixes: 9c72bad1f31a ("dm: call PR reserve/unreserve on each underlying device")
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index f01d33bc3613..e0e28a3203f8 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -2955,6 +2955,11 @@ static int dm_call_pr(struct block_device *bdev, iterate_devices_callout_fn fn,
+ goto out;
+ ti = dm_table_get_target(table, 0);
+
++ if (dm_suspended_md(md)) {
++ ret = -EAGAIN;
++ goto out;
++ }
++
+ ret = -EINVAL;
+ if (!ti->type->iterate_devices)
+ goto out;
+--
+2.35.1
+
--- /dev/null
+From ad6c3a396067fca16e5ccaeac2432a201388e10d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 16:31:52 -0400
+Subject: dm writecache: count number of blocks discarded, not number of
+ discard bios
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit 2ee73ef60db4d79b9f9b8cd501e8188b5179449f ]
+
+Change dm-writecache, so that it counts the number of blocks discarded
+instead of the number of discard bios. Make it consistent with the
+read and write statistics counters that were changed to count the
+number of blocks instead of bios.
+
+Fixes: e3a35d03407c ("dm writecache: add event counters")
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/admin-guide/device-mapper/writecache.rst | 2 +-
+ drivers/md/dm-writecache.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/admin-guide/device-mapper/writecache.rst b/Documentation/admin-guide/device-mapper/writecache.rst
+index 6c9a2c74df8a..724e028d1858 100644
+--- a/Documentation/admin-guide/device-mapper/writecache.rst
++++ b/Documentation/admin-guide/device-mapper/writecache.rst
+@@ -87,7 +87,7 @@ Status:
+ 11. the number of write blocks that are allocated in the cache
+ 12. the number of write requests that are blocked on the freelist
+ 13. the number of flush requests
+-14. the number of discard requests
++14. the number of discarded blocks
+
+ Messages:
+ flush
+diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
+index 98df6327990a..e5acb393f70b 100644
+--- a/drivers/md/dm-writecache.c
++++ b/drivers/md/dm-writecache.c
+@@ -1513,7 +1513,7 @@ static enum wc_map_op writecache_map_flush(struct dm_writecache *wc, struct bio
+
+ static enum wc_map_op writecache_map_discard(struct dm_writecache *wc, struct bio *bio)
+ {
+- wc->stats.discards++;
++ wc->stats.discards += bio->bi_iter.bi_size >> wc->block_size_bits;
+
+ if (writecache_has_error(wc))
+ return WC_MAP_ERROR;
+--
+2.35.1
+
--- /dev/null
+From acca9bec8c75b12988c748df817f19a82ed3a1d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 16:30:52 -0400
+Subject: dm writecache: count number of blocks read, not number of read bios
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit 2c6e755b49d273243431f5f1184654e71221fc78 ]
+
+Change dm-writecache, so that it counts the number of blocks read
+instead of the number of read bios. Bios can be split and requeued
+using the dm_accept_partial_bio function, so counting bios caused
+inaccurate results.
+
+Fixes: e3a35d03407c ("dm writecache: add event counters")
+Reported-by: Yu Kuai <yukuai1@huaweicloud.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/admin-guide/device-mapper/writecache.rst | 4 ++--
+ drivers/md/dm-writecache.c | 1 +
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/admin-guide/device-mapper/writecache.rst b/Documentation/admin-guide/device-mapper/writecache.rst
+index 10429779a91a..7bead3b52690 100644
+--- a/Documentation/admin-guide/device-mapper/writecache.rst
++++ b/Documentation/admin-guide/device-mapper/writecache.rst
+@@ -78,8 +78,8 @@ Status:
+ 2. the number of blocks
+ 3. the number of free blocks
+ 4. the number of blocks under writeback
+-5. the number of read requests
+-6. the number of read requests that hit the cache
++5. the number of read blocks
++6. the number of read blocks that hit the cache
+ 7. the number of write requests
+ 8. the number of write requests that hit uncommitted block
+ 9. the number of write requests that hit committed block
+diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
+index 688b6b3bcd7b..3bec493cccb2 100644
+--- a/drivers/md/dm-writecache.c
++++ b/drivers/md/dm-writecache.c
+@@ -1364,6 +1364,7 @@ static enum wc_map_op writecache_map_read(struct dm_writecache *wc, struct bio *
+ }
+ } else {
+ writecache_map_remap_origin(wc, bio, e);
++ wc->stats.reads += (bio->bi_iter.bi_size - wc->block_size) >> wc->block_size_bits;
+ map_op = WC_MAP_REMAP_ORIGIN;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 8042089b2680cfad59e43d0a0b4ab3988132ba26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 16:31:26 -0400
+Subject: dm writecache: count number of blocks written, not number of write
+ bios
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit b2676e1482af89714af6988ce5d31a84692e2530 ]
+
+Change dm-writecache, so that it counts the number of blocks written
+instead of the number of write bios. Bios can be split and requeued
+using the dm_accept_partial_bio function, so counting bios caused
+inaccurate results.
+
+Fixes: e3a35d03407c ("dm writecache: add event counters")
+Reported-by: Yu Kuai <yukuai1@huaweicloud.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../admin-guide/device-mapper/writecache.rst | 10 +++++-----
+ drivers/md/dm-writecache.c | 12 +++++++++---
+ 2 files changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/Documentation/admin-guide/device-mapper/writecache.rst b/Documentation/admin-guide/device-mapper/writecache.rst
+index 7bead3b52690..6c9a2c74df8a 100644
+--- a/Documentation/admin-guide/device-mapper/writecache.rst
++++ b/Documentation/admin-guide/device-mapper/writecache.rst
+@@ -80,11 +80,11 @@ Status:
+ 4. the number of blocks under writeback
+ 5. the number of read blocks
+ 6. the number of read blocks that hit the cache
+-7. the number of write requests
+-8. the number of write requests that hit uncommitted block
+-9. the number of write requests that hit committed block
+-10. the number of write requests that bypass the cache
+-11. the number of write requests that are allocated in the cache
++7. the number of write blocks
++8. the number of write blocks that hit uncommitted block
++9. the number of write blocks that hit committed block
++10. the number of write blocks that bypass the cache
++11. the number of write blocks that are allocated in the cache
+ 12. the number of write requests that are blocked on the freelist
+ 13. the number of flush requests
+ 14. the number of discard requests
+diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
+index 3bec493cccb2..98df6327990a 100644
+--- a/drivers/md/dm-writecache.c
++++ b/drivers/md/dm-writecache.c
+@@ -1412,6 +1412,9 @@ static void writecache_bio_copy_ssd(struct dm_writecache *wc, struct bio *bio,
+ bio->bi_iter.bi_sector = start_cache_sec;
+ dm_accept_partial_bio(bio, bio_size >> SECTOR_SHIFT);
+
++ wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits;
++ wc->stats.writes_allocate += (bio->bi_iter.bi_size - wc->block_size) >> wc->block_size_bits;
++
+ if (unlikely(wc->uncommitted_blocks >= wc->autocommit_blocks)) {
+ wc->uncommitted_blocks = 0;
+ queue_work(wc->writeback_wq, &wc->flush_work);
+@@ -1427,9 +1430,10 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
+ do {
+ bool found_entry = false;
+ bool search_used = false;
+- wc->stats.writes++;
+- if (writecache_has_error(wc))
++ if (writecache_has_error(wc)) {
++ wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits;
+ return WC_MAP_ERROR;
++ }
+ e = writecache_find_entry(wc, bio->bi_iter.bi_sector, 0);
+ if (e) {
+ if (!writecache_entry_is_committed(wc, e)) {
+@@ -1453,9 +1457,10 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
+ if (unlikely(!e)) {
+ if (!WC_MODE_PMEM(wc) && !found_entry) {
+ direct_write:
+- wc->stats.writes_around++;
+ e = writecache_find_entry(wc, bio->bi_iter.bi_sector, WFE_RETURN_FOLLOWING);
+ writecache_map_remap_origin(wc, bio, e);
++ wc->stats.writes_around += bio->bi_iter.bi_size >> wc->block_size_bits;
++ wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits;
+ return WC_MAP_REMAP_ORIGIN;
+ }
+ wc->stats.writes_blocked_on_freelist++;
+@@ -1469,6 +1474,7 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
+ bio_copy:
+ if (WC_MODE_PMEM(wc)) {
+ bio_copy_block(wc, bio, memory_data(wc, e));
++ wc->stats.writes++;
+ } else {
+ writecache_bio_copy_ssd(wc, bio, e, search_used);
+ return WC_MAP_REMAP;
+--
+2.35.1
+
--- /dev/null
+From a74987e9bc70e526d155bc640b916165a5ab084c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 16:30:27 -0400
+Subject: dm writecache: return void from functions
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit 9bc0c92e4b82adb017026dbb2aa816b1ac2bef31 ]
+
+The functions writecache_map_remap_origin and writecache_bio_copy_ssd
+only return a single value, thus they can be made to return void.
+
+This helps simplify the following IO accounting changes.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-writecache.c | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
+index 5630b470ba42..688b6b3bcd7b 100644
+--- a/drivers/md/dm-writecache.c
++++ b/drivers/md/dm-writecache.c
+@@ -1328,8 +1328,8 @@ enum wc_map_op {
+ WC_MAP_ERROR,
+ };
+
+-static enum wc_map_op writecache_map_remap_origin(struct dm_writecache *wc, struct bio *bio,
+- struct wc_entry *e)
++static void writecache_map_remap_origin(struct dm_writecache *wc, struct bio *bio,
++ struct wc_entry *e)
+ {
+ if (e) {
+ sector_t next_boundary =
+@@ -1337,8 +1337,6 @@ static enum wc_map_op writecache_map_remap_origin(struct dm_writecache *wc, stru
+ if (next_boundary < bio->bi_iter.bi_size >> SECTOR_SHIFT)
+ dm_accept_partial_bio(bio, next_boundary);
+ }
+-
+- return WC_MAP_REMAP_ORIGIN;
+ }
+
+ static enum wc_map_op writecache_map_read(struct dm_writecache *wc, struct bio *bio)
+@@ -1365,14 +1363,15 @@ static enum wc_map_op writecache_map_read(struct dm_writecache *wc, struct bio *
+ map_op = WC_MAP_REMAP;
+ }
+ } else {
+- map_op = writecache_map_remap_origin(wc, bio, e);
++ writecache_map_remap_origin(wc, bio, e);
++ map_op = WC_MAP_REMAP_ORIGIN;
+ }
+
+ return map_op;
+ }
+
+-static enum wc_map_op writecache_bio_copy_ssd(struct dm_writecache *wc, struct bio *bio,
+- struct wc_entry *e, bool search_used)
++static void writecache_bio_copy_ssd(struct dm_writecache *wc, struct bio *bio,
++ struct wc_entry *e, bool search_used)
+ {
+ unsigned bio_size = wc->block_size;
+ sector_t start_cache_sec = cache_sector(wc, e);
+@@ -1418,8 +1417,6 @@ static enum wc_map_op writecache_bio_copy_ssd(struct dm_writecache *wc, struct b
+ } else {
+ writecache_schedule_autocommit(wc);
+ }
+-
+- return WC_MAP_REMAP;
+ }
+
+ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio *bio)
+@@ -1457,7 +1454,8 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
+ direct_write:
+ wc->stats.writes_around++;
+ e = writecache_find_entry(wc, bio->bi_iter.bi_sector, WFE_RETURN_FOLLOWING);
+- return writecache_map_remap_origin(wc, bio, e);
++ writecache_map_remap_origin(wc, bio, e);
++ return WC_MAP_REMAP_ORIGIN;
+ }
+ wc->stats.writes_blocked_on_freelist++;
+ writecache_wait_on_freelist(wc);
+@@ -1468,10 +1466,12 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
+ wc->uncommitted_blocks++;
+ wc->stats.writes_allocate++;
+ bio_copy:
+- if (WC_MODE_PMEM(wc))
++ if (WC_MODE_PMEM(wc)) {
+ bio_copy_block(wc, bio, memory_data(wc, e));
+- else
+- return writecache_bio_copy_ssd(wc, bio, e, search_used);
++ } else {
++ writecache_bio_copy_ssd(wc, bio, e, search_used);
++ return WC_MAP_REMAP;
++ }
+ } while (bio->bi_iter.bi_size);
+
+ if (unlikely(bio->bi_opf & REQ_FUA || wc->uncommitted_blocks >= wc->autocommit_blocks))
+--
+2.35.1
+
--- /dev/null
+From 0de0bd168335e9f18cccf6d84df9674a4173709f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 10:21:57 -0500
+Subject: dmaengine: dw-edma: Fix eDMA Rd/Wr-channels and DMA-direction
+ semantics
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+[ Upstream commit c1e33979171da63cf47e56243ccb8ba82363c7d3 ]
+
+In accordance with [1, 2] the DW eDMA controller has been created to be
+part of the DW PCIe Root Port and DW PCIe End-point controllers and to
+offload the transferring of large blocks of data between application and
+remote PCIe domains leaving the system CPU free for other tasks. In the
+first case (eDMA being part of DW PCIe Root Port) the eDMA controller is
+always accessible via the CPU DBI interface and never over the PCIe wire.
+
+The latter case is more complex. Depending on the DW PCIe End-Point IP-core
+synthesize parameters it's possible to have the eDMA registers accessible
+not only from the application CPU side, but also via mapping the eDMA CSRs
+over a dedicated endpoint BAR. So based on the specifics denoted above the
+eDMA driver is supposed to support two types of the DMA controller setups:
+
+ 1) eDMA embedded into the DW PCIe Root Port/End-point and accessible over
+ the local CPU from the application side.
+
+ 2) eDMA embedded into the DW PCIe End-point and accessible via the PCIe
+ wire with MWr/MRd TLPs generated by the CPU PCIe host controller.
+
+Since the CPU memory resides different sides in these cases the semantics
+of the MEM_TO_DEV and DEV_TO_MEM operations is flipped with respect to the
+Tx and Rx DMA channels. So MEM_TO_DEV/DEV_TO_MEM corresponds to the Tx/Rx
+channels in setup 1) and to the Rx/Tx channels in case of setup 2).
+
+The DW eDMA driver has supported the case 2) since e63d79d1ffcd
+("dmaengine: Add Synopsys eDMA IP core driver") in the framework of the
+drivers/dma/dw-edma/dw-edma-pcie.c driver.
+
+The case 1) support was added later by bd96f1b2f43a ("dmaengine: dw-edma:
+support local dma device transfer semantics"). Afterwards the driver was
+supposed to cover the both possible eDMA setups, but the latter commit
+turned out to be not fully correct.
+
+The problem was that the commit together with the new functionality support
+also changed the channel direction semantics so the eDMA Read-channel
+(corresponding to the DMA_DEV_TO_MEM direction for case 1) now uses the
+sgl/cyclic base addresses as the Source addresses of the DMA transfers and
+dma_slave_config.dst_addr as the Destination address of the DMA transfers.
+
+Similarly the eDMA Write-channel (corresponding to the DMA_MEM_TO_DEV
+direction for case 1) now uses dma_slave_config.src_addr as a source
+address of the DMA transfers and sgl/cyclic base address as the Destination
+address of the DMA transfers. This contradicts the logic of the
+DMA-interface, which implies that DEV side is supposed to belong to the
+PCIe device memory and MEM - to the CPU/Application memory. Indeed it seems
+irrational to have the SG-list defined in the PCIe bus space, while
+expecting a contiguous buffer allocated in the CPU memory. Moreover the
+passed SG-list and cyclic DMA buffers are supposed to be mapped in a way so
+to be seen by the DW eDMA Application (CPU) interface.
+
+So in order to have the correct DW eDMA interface we need to invert the
+eDMA Rd/Wr-channels and DMA-slave directions semantics by selecting the
+src/dst addresses based on the DMA transfer direction instead of using the
+channel direction capability.
+
+[1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port,
+ v.5.40a, March 2019, p.1092
+[2] DesignWare Cores PCI Express Controller Databook - DWC PCIe Endpoint,
+ v.5.40a, March 2019, p.1189
+
+Co-developed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Fixes: bd96f1b2f43a ("dmaengine: dw-edma: support local dma device transfer semantics")
+Link: https://lore.kernel.org/r/20220524152159.2370739-7-Frank.Li@nxp.com
+Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-By: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/dw-edma/dw-edma-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
+index 468d1097a1ec..f23569e4b0bd 100644
+--- a/drivers/dma/dw-edma/dw-edma-core.c
++++ b/drivers/dma/dw-edma/dw-edma-core.c
+@@ -423,7 +423,7 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer)
+ chunk->ll_region.sz += burst->sz;
+ desc->alloc_sz += burst->sz;
+
+- if (chan->dir == EDMA_DIR_WRITE) {
++ if (dir == DMA_DEV_TO_MEM) {
+ burst->sar = src_addr;
+ if (xfer->type == EDMA_XFER_CYCLIC) {
+ burst->dar = xfer->xfer.cyclic.paddr;
+--
+2.35.1
+
--- /dev/null
+From 7891b728f9718947760b6e841a99dbe7b8788480 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 08:13:27 -0300
+Subject: dmaengine: imx-dma: Cast of_device_get_match_data() with (uintptr_t)
+
+From: Fabio Estevam <festevam@denx.de>
+
+[ Upstream commit c3266ee185b59e5aab3e0f982e5b7f95d31555a7 ]
+
+Change the of_device_get_match_data() cast to (uintptr_t)
+to silence the following clang warning:
+
+drivers/dma/imx-dma.c:1048:20: warning: cast to smaller integer type 'enum imx_dma_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: 0ab785c894e6 ("dmaengine: imx-dma: Remove unused .id_table")
+Signed-off-by: Fabio Estevam <festevam@denx.de>
+Link: https://lore.kernel.org/r/20220706111327.940764-1-festevam@gmail.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/imx-dma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
+index 2ddc31e64db0..da31e73d24d4 100644
+--- a/drivers/dma/imx-dma.c
++++ b/drivers/dma/imx-dma.c
+@@ -1047,7 +1047,7 @@ static int __init imxdma_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ imxdma->dev = &pdev->dev;
+- imxdma->devtype = (enum imx_dma_type)of_device_get_match_data(&pdev->dev);
++ imxdma->devtype = (uintptr_t)of_device_get_match_data(&pdev->dev);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ imxdma->base = devm_ioremap_resource(&pdev->dev, res);
+--
+2.35.1
+
--- /dev/null
+From 3978cf6d0f77d9c06bd60c5a79102da9fdcbff70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 11:29:42 +0300
+Subject: dmaengine: sf-pdma: Add multithread support for a DMA channel
+
+From: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com>
+
+[ Upstream commit b2cc5c465c2cb8ab697c3fd6583c614e3f6cfbcc ]
+
+When we get a DMA channel and try to use it in multiple threads it
+will cause oops and hanging the system.
+
+% echo 64 > /sys/module/dmatest/parameters/threads_per_chan
+% echo 10000 > /sys/module/dmatest/parameters/iterations
+% echo 1 > /sys/module/dmatest/parameters/run
+[ 89.480664] Unable to handle kernel NULL pointer dereference at virtual
+ address 00000000000000a0
+[ 89.488725] Oops [#1]
+[ 89.494708] CPU: 2 PID: 1008 Comm: dma0chan0-copy0 Not tainted
+ 5.17.0-rc5
+[ 89.509385] epc : vchan_find_desc+0x32/0x46
+[ 89.513553] ra : sf_pdma_tx_status+0xca/0xd6
+
+This happens because of data race. Each thread rewrite channels's
+descriptor as soon as device_prep_dma_memcpy() is called. It leads to the
+situation when the driver thinks that it uses right descriptor that
+actually is freed or substituted for other one.
+
+With current fixes a descriptor changes its value only when it has
+been used. A new descriptor is acquired from vc->desc_issued queue that
+is already filled with descriptors that are ready to be sent. Threads
+have no direct access to DMA channel descriptor. Now it is just possible
+to queue a descriptor for further processing.
+
+Fixes: 6973886ad58e ("dmaengine: sf-pdma: add platform DMA support for HiFive Unleashed A00")
+Signed-off-by: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com>
+Link: https://lore.kernel.org/r/20220701082942.12835-1-v.v.mitrofanov@yadro.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/sf-pdma/sf-pdma.c | 44 ++++++++++++++++++++++++-----------
+ 1 file changed, 30 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/dma/sf-pdma/sf-pdma.c b/drivers/dma/sf-pdma/sf-pdma.c
+index f12606aeff87..ab0ad7a2f201 100644
+--- a/drivers/dma/sf-pdma/sf-pdma.c
++++ b/drivers/dma/sf-pdma/sf-pdma.c
+@@ -52,16 +52,6 @@ static inline struct sf_pdma_desc *to_sf_pdma_desc(struct virt_dma_desc *vd)
+ static struct sf_pdma_desc *sf_pdma_alloc_desc(struct sf_pdma_chan *chan)
+ {
+ struct sf_pdma_desc *desc;
+- unsigned long flags;
+-
+- spin_lock_irqsave(&chan->lock, flags);
+-
+- if (chan->desc && !chan->desc->in_use) {
+- spin_unlock_irqrestore(&chan->lock, flags);
+- return chan->desc;
+- }
+-
+- spin_unlock_irqrestore(&chan->lock, flags);
+
+ desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
+ if (!desc)
+@@ -111,7 +101,6 @@ sf_pdma_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dest, dma_addr_t src,
+ desc->async_tx = vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
+
+ spin_lock_irqsave(&chan->vchan.lock, iflags);
+- chan->desc = desc;
+ sf_pdma_fill_desc(desc, dest, src, len);
+ spin_unlock_irqrestore(&chan->vchan.lock, iflags);
+
+@@ -170,11 +159,17 @@ static size_t sf_pdma_desc_residue(struct sf_pdma_chan *chan,
+ unsigned long flags;
+ u64 residue = 0;
+ struct sf_pdma_desc *desc;
+- struct dma_async_tx_descriptor *tx;
++ struct dma_async_tx_descriptor *tx = NULL;
+
+ spin_lock_irqsave(&chan->vchan.lock, flags);
+
+- tx = &chan->desc->vdesc.tx;
++ list_for_each_entry(vd, &chan->vchan.desc_submitted, node)
++ if (vd->tx.cookie == cookie)
++ tx = &vd->tx;
++
++ if (!tx)
++ goto out;
++
+ if (cookie == tx->chan->completed_cookie)
+ goto out;
+
+@@ -241,6 +236,19 @@ static void sf_pdma_enable_request(struct sf_pdma_chan *chan)
+ writel(v, regs->ctrl);
+ }
+
++static struct sf_pdma_desc *sf_pdma_get_first_pending_desc(struct sf_pdma_chan *chan)
++{
++ struct virt_dma_chan *vchan = &chan->vchan;
++ struct virt_dma_desc *vdesc;
++
++ if (list_empty(&vchan->desc_issued))
++ return NULL;
++
++ vdesc = list_first_entry(&vchan->desc_issued, struct virt_dma_desc, node);
++
++ return container_of(vdesc, struct sf_pdma_desc, vdesc);
++}
++
+ static void sf_pdma_xfer_desc(struct sf_pdma_chan *chan)
+ {
+ struct sf_pdma_desc *desc = chan->desc;
+@@ -268,8 +276,11 @@ static void sf_pdma_issue_pending(struct dma_chan *dchan)
+
+ spin_lock_irqsave(&chan->vchan.lock, flags);
+
+- if (vchan_issue_pending(&chan->vchan) && chan->desc)
++ if (!chan->desc && vchan_issue_pending(&chan->vchan)) {
++ /* vchan_issue_pending has made a check that desc in not NULL */
++ chan->desc = sf_pdma_get_first_pending_desc(chan);
+ sf_pdma_xfer_desc(chan);
++ }
+
+ spin_unlock_irqrestore(&chan->vchan.lock, flags);
+ }
+@@ -298,6 +309,11 @@ static void sf_pdma_donebh_tasklet(struct tasklet_struct *t)
+ spin_lock_irqsave(&chan->vchan.lock, flags);
+ list_del(&chan->desc->vdesc.node);
+ vchan_cookie_complete(&chan->desc->vdesc);
++
++ chan->desc = sf_pdma_get_first_pending_desc(chan);
++ if (chan->desc)
++ sf_pdma_xfer_desc(chan);
++
+ spin_unlock_irqrestore(&chan->vchan.lock, flags);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 858e7fb4c0bd32b781e4491bfd5a216cc016e983 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jun 2022 15:43:27 +0800
+Subject: driver core: fix potential deadlock in __driver_attach
+
+From: Zhang Wensheng <zhangwensheng5@huawei.com>
+
+[ Upstream commit 70fe758352cafdee72a7b13bf9db065f9613ced8 ]
+
+In __driver_attach function, There are also AA deadlock problem,
+like the commit b232b02bf3c2 ("driver core: fix deadlock in
+__device_attach").
+
+stack like commit b232b02bf3c2 ("driver core: fix deadlock in
+__device_attach").
+list below:
+ In __driver_attach function, The lock holding logic is as follows:
+ ...
+ __driver_attach
+ if (driver_allows_async_probing(drv))
+ device_lock(dev) // get lock dev
+ async_schedule_dev(__driver_attach_async_helper, dev); // func
+ async_schedule_node
+ async_schedule_node_domain(func)
+ entry = kzalloc(sizeof(struct async_entry), GFP_ATOMIC);
+ /* when fail or work limit, sync to execute func, but
+ __driver_attach_async_helper will get lock dev as
+ will, which will lead to A-A deadlock. */
+ if (!entry || atomic_read(&entry_count) > MAX_WORK) {
+ func;
+ else
+ queue_work_node(node, system_unbound_wq, &entry->work)
+ device_unlock(dev)
+
+ As above show, when it is allowed to do async probes, because of
+ out of memory or work limit, async work is not be allowed, to do
+ sync execute instead. it will lead to A-A deadlock because of
+ __driver_attach_async_helper getting lock dev.
+
+Reproduce:
+and it can be reproduce by make the condition
+(if (!entry || atomic_read(&entry_count) > MAX_WORK)) untenable, like
+below:
+
+[ 370.785650] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables
+this message.
+[ 370.787154] task:swapper/0 state:D stack: 0 pid: 1 ppid:
+0 flags:0x00004000
+[ 370.788865] Call Trace:
+[ 370.789374] <TASK>
+[ 370.789841] __schedule+0x482/0x1050
+[ 370.790613] schedule+0x92/0x1a0
+[ 370.791290] schedule_preempt_disabled+0x2c/0x50
+[ 370.792256] __mutex_lock.isra.0+0x757/0xec0
+[ 370.793158] __mutex_lock_slowpath+0x1f/0x30
+[ 370.794079] mutex_lock+0x50/0x60
+[ 370.794795] __device_driver_lock+0x2f/0x70
+[ 370.795677] ? driver_probe_device+0xd0/0xd0
+[ 370.796576] __driver_attach_async_helper+0x1d/0xd0
+[ 370.797318] ? driver_probe_device+0xd0/0xd0
+[ 370.797957] async_schedule_node_domain+0xa5/0xc0
+[ 370.798652] async_schedule_node+0x19/0x30
+[ 370.799243] __driver_attach+0x246/0x290
+[ 370.799828] ? driver_allows_async_probing+0xa0/0xa0
+[ 370.800548] bus_for_each_dev+0x9d/0x130
+[ 370.801132] driver_attach+0x22/0x30
+[ 370.801666] bus_add_driver+0x290/0x340
+[ 370.802246] driver_register+0x88/0x140
+[ 370.802817] ? virtio_scsi_init+0x116/0x116
+[ 370.803425] scsi_register_driver+0x1a/0x30
+[ 370.804057] init_sd+0x184/0x226
+[ 370.804533] do_one_initcall+0x71/0x3a0
+[ 370.805107] kernel_init_freeable+0x39a/0x43a
+[ 370.805759] ? rest_init+0x150/0x150
+[ 370.806283] kernel_init+0x26/0x230
+[ 370.806799] ret_from_fork+0x1f/0x30
+
+To fix the deadlock, move the async_schedule_dev outside device_lock,
+as we can see, in async_schedule_node_domain, the parameter of
+queue_work_node is system_unbound_wq, so it can accept concurrent
+operations. which will also not change the code logic, and will
+not lead to deadlock.
+
+Fixes: ef0ff68351be ("driver core: Probe devices asynchronously instead of the driver")
+Signed-off-by: Zhang Wensheng <zhangwensheng5@huawei.com>
+Link: https://lore.kernel.org/r/20220622074327.497102-1-zhangwensheng5@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/dd.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/base/dd.c b/drivers/base/dd.c
+index d6980f33afc4..822dfa6561c2 100644
+--- a/drivers/base/dd.c
++++ b/drivers/base/dd.c
+@@ -1091,6 +1091,7 @@ static void __driver_attach_async_helper(void *_dev, async_cookie_t cookie)
+ static int __driver_attach(struct device *dev, void *data)
+ {
+ struct device_driver *drv = data;
++ bool async = false;
+ int ret;
+
+ /*
+@@ -1129,9 +1130,11 @@ static int __driver_attach(struct device *dev, void *data)
+ if (!dev->driver) {
+ get_device(dev);
+ dev->p->async_driver = drv;
+- async_schedule_dev(__driver_attach_async_helper, dev);
++ async = true;
+ }
+ device_unlock(dev);
++ if (async)
++ async_schedule_dev(__driver_attach_async_helper, dev);
+ return 0;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From b143db65d9628295335c03234c29cc88038a5b5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 11:43:02 +0530
+Subject: drivers/perf: arm_spe: Fix consistency of SYS_PMSCR_EL1.CX
+
+From: Anshuman Khandual <anshuman.khandual@arm.com>
+
+[ Upstream commit 92f2b8bafa3d6e89c750e9d301a8b7ab76aaa8b6 ]
+
+The arm_spe_pmu driver will enable SYS_PMSCR_EL1.CX in order to add CONTEXT
+packets into the traces, if the owner of the perf event runs with required
+capabilities i.e CAP_PERFMON or CAP_SYS_ADMIN via perfmon_capable() helper.
+
+The value of this bit is computed in the arm_spe_event_to_pmscr() function
+but the check for capabilities happens in the pmu event init callback i.e
+arm_spe_pmu_event_init(). This suggests that the value of the CX bit should
+remain consistent for the duration of the perf session.
+
+However, the function arm_spe_event_to_pmscr() may be called later during
+the event start callback i.e arm_spe_pmu_start() when the "current" process
+is not the owner of the perf session, hence the CX bit setting is currently
+not consistent.
+
+One way to fix this, is by caching the required value of the CX bit during
+the initialization of the PMU event, so that it remains consistent for the
+duration of the session. It uses currently unused 'event->hw.flags' element
+to cache perfmon_capable() value, which can be referred during event start
+callback to compute SYS_PMSCR_EL1.CX. This ensures consistent availability
+of context packets in the trace as per event owner capabilities.
+
+Drop BIT(SYS_PMSCR_EL1_CX_SHIFT) check in arm_spe_pmu_event_init(), because
+now CX bit cannot be set in arm_spe_event_to_pmscr() with perfmon_capable()
+disabled.
+
+Cc: Will Deacon <will@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Alexey Budankov <alexey.budankov@linux.intel.com>
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: linux-kernel@vger.kernel.org
+Fixes: d5d9696b0380 ("drivers/perf: Add support for ARMv8.2 Statistical Profiling Extension")
+Reported-by: German Gomez <german.gomez@arm.com>
+Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Link: https://lore.kernel.org/r/20220714061302.2715102-1-anshuman.khandual@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/arm_spe_pmu.c | 22 ++++++++++++++++++++--
+ 1 file changed, 20 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
+index d44bcc29d99c..cd5945e17fdf 100644
+--- a/drivers/perf/arm_spe_pmu.c
++++ b/drivers/perf/arm_spe_pmu.c
+@@ -39,6 +39,24 @@
+ #include <asm/mmu.h>
+ #include <asm/sysreg.h>
+
++/*
++ * Cache if the event is allowed to trace Context information.
++ * This allows us to perform the check, i.e, perfmon_capable(),
++ * in the context of the event owner, once, during the event_init().
++ */
++#define SPE_PMU_HW_FLAGS_CX BIT(0)
++
++static void set_spe_event_has_cx(struct perf_event *event)
++{
++ if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && perfmon_capable())
++ event->hw.flags |= SPE_PMU_HW_FLAGS_CX;
++}
++
++static bool get_spe_event_has_cx(struct perf_event *event)
++{
++ return !!(event->hw.flags & SPE_PMU_HW_FLAGS_CX);
++}
++
+ #define ARM_SPE_BUF_PAD_BYTE 0
+
+ struct arm_spe_pmu_buf {
+@@ -272,7 +290,7 @@ static u64 arm_spe_event_to_pmscr(struct perf_event *event)
+ if (!attr->exclude_kernel)
+ reg |= BIT(SYS_PMSCR_EL1_E1SPE_SHIFT);
+
+- if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && perfmon_capable())
++ if (get_spe_event_has_cx(event))
+ reg |= BIT(SYS_PMSCR_EL1_CX_SHIFT);
+
+ return reg;
+@@ -709,10 +727,10 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
+ !(spe_pmu->features & SPE_PMU_FEAT_FILT_LAT))
+ return -EOPNOTSUPP;
+
++ set_spe_event_has_cx(event);
+ reg = arm_spe_event_to_pmscr(event);
+ if (!perfmon_capable() &&
+ (reg & (BIT(SYS_PMSCR_EL1_PA_SHIFT) |
+- BIT(SYS_PMSCR_EL1_CX_SHIFT) |
+ BIT(SYS_PMSCR_EL1_PCT_SHIFT))))
+ return -EACCES;
+
+--
+2.35.1
+
--- /dev/null
+From ec5f6a6646ad46de4c0733995787d86bf003b479 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 23:31:44 +0200
+Subject: drm: adv7511: override i2c address of cec before accessing it
+
+From: Antonio Borneo <antonio.borneo@foss.st.com>
+
+[ Upstream commit 9cc4853e4781bf0dd0f35355dc92d97c9da02f5d ]
+
+Commit 680532c50bca ("drm: adv7511: Add support for
+i2c_new_secondary_device") allows a device tree node to override
+the default addresses of the secondary i2c devices. This is useful
+for solving address conflicts on the i2c bus.
+
+In adv7511_init_cec_regmap() the new i2c address of cec device is
+read from device tree and immediately accessed, well before it is
+written in the proper register to override the default address.
+This can cause an i2c error during probe and a consequent probe
+failure.
+
+Once the new i2c address is read from the device tree, override
+the default address before any attempt to access the cec.
+
+Tested with adv7533 and stm32mp157f.
+
+Signed-off-by: Antonio Borneo <antonio.borneo@foss.st.com>
+Fixes: 680532c50bca ("drm: adv7511: Add support for i2c_new_secondary_device")
+Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220607213144.427177-1-antonio.borneo@foss.st.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index 668dcefbae17..fba6ad3bb6ad 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -1060,6 +1060,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv)
+ ADV7511_CEC_I2C_ADDR_DEFAULT);
+ if (IS_ERR(adv->i2c_cec))
+ return PTR_ERR(adv->i2c_cec);
++
++ regmap_write(adv->regmap, ADV7511_REG_CEC_I2C_ADDR,
++ adv->i2c_cec->addr << 1);
++
+ i2c_set_clientdata(adv->i2c_cec, adv);
+
+ adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec,
+@@ -1264,9 +1268,6 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+ if (ret)
+ goto err_i2c_unregister_packet;
+
+- regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR,
+- adv7511->i2c_cec->addr << 1);
+-
+ INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work);
+
+ if (i2c->irq) {
+--
+2.35.1
+
--- /dev/null
+From e9fdcb3d3765adb7138cf925f31bcef2368d1745 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Jul 2022 18:15:31 +0300
+Subject: drm/amd/display: fix signedness bug in execute_synaptics_rc_command()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 06ac561fb0edf868f7b292fb4a3c8ffbbb1e14bb ]
+
+The "ret" variable needs to be signed for the error handling to work.
+
+Fixes: 2ca97adccdc9 ("drm/amd/display: Add Synaptics Fifo Reset Workaround")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+index f5f39984702f..a3282ddbff86 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+@@ -571,7 +571,7 @@ static bool execute_synaptics_rc_command(struct drm_dp_aux *aux,
+ unsigned char rc_cmd = 0;
+ unsigned char rc_result = 0xFF;
+ unsigned char i = 0;
+- uint8_t ret = 0;
++ int ret;
+
+ if (is_write_cmd) {
+ // write rc data
+--
+2.35.1
+
--- /dev/null
+From c18894f3eb3f7f58b2a8b1ac070f38326de63cec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 May 2022 13:54:02 +0200
+Subject: drm/amdgpu: cleanup ctx implementation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian König <christian.koenig@amd.com>
+
+[ Upstream commit 69493c034d2455204dfcd370de8c4dc204374a94 ]
+
+Let each context have a pointer to the ctx manager and properly
+initialize the adev pointer inside the context manager.
+
+Reduce the BUG_ON() in amdgpu_ctx_add_fence() into a WARN_ON() and
+directly return the sequence number instead of writing into a parmeter.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Shashank Sharma <shashank.sharma@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 | 2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 46 ++++++++++++-------------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h | 11 +++---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +-
+ 4 files changed, 30 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+index 2019622191b5..ee0cbc6ccbfb 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -1260,7 +1260,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
+
+ p->fence = dma_fence_get(&job->base.s_fence->finished);
+
+- amdgpu_ctx_add_fence(p->ctx, entity, p->fence, &seq);
++ seq = amdgpu_ctx_add_fence(p->ctx, entity, p->fence);
+ amdgpu_cs_post_dependencies(p);
+
+ if ((job->preamble_status & AMDGPU_PREAMBLE_IB_PRESENT) &&
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+index c317078d1afd..a61e4c83a545 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+@@ -135,9 +135,9 @@ static enum amdgpu_ring_priority_level amdgpu_ctx_sched_prio_to_ring_prio(int32_
+
+ static unsigned int amdgpu_ctx_get_hw_prio(struct amdgpu_ctx *ctx, u32 hw_ip)
+ {
+- struct amdgpu_device *adev = ctx->adev;
+- int32_t ctx_prio;
++ struct amdgpu_device *adev = ctx->mgr->adev;
+ unsigned int hw_prio;
++ int32_t ctx_prio;
+
+ ctx_prio = (ctx->override_priority == AMDGPU_CTX_PRIORITY_UNSET) ?
+ ctx->init_priority : ctx->override_priority;
+@@ -166,7 +166,7 @@ static unsigned int amdgpu_ctx_get_hw_prio(struct amdgpu_ctx *ctx, u32 hw_ip)
+ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
+ const u32 ring)
+ {
+- struct amdgpu_device *adev = ctx->adev;
++ struct amdgpu_device *adev = ctx->mgr->adev;
+ struct amdgpu_ctx_entity *entity;
+ struct drm_gpu_scheduler **scheds = NULL, *sched = NULL;
+ unsigned num_scheds = 0;
+@@ -220,10 +220,8 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
+ return r;
+ }
+
+-static int amdgpu_ctx_init(struct amdgpu_device *adev,
+- int32_t priority,
+- struct drm_file *filp,
+- struct amdgpu_ctx *ctx)
++static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
++ struct drm_file *filp, struct amdgpu_ctx *ctx)
+ {
+ int r;
+
+@@ -233,15 +231,14 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev,
+
+ memset(ctx, 0, sizeof(*ctx));
+
+- ctx->adev = adev;
+-
+ kref_init(&ctx->refcount);
++ ctx->mgr = mgr;
+ spin_lock_init(&ctx->ring_lock);
+ mutex_init(&ctx->lock);
+
+- ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);
++ ctx->reset_counter = atomic_read(&mgr->adev->gpu_reset_counter);
+ ctx->reset_counter_query = ctx->reset_counter;
+- ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
++ ctx->vram_lost_counter = atomic_read(&mgr->adev->vram_lost_counter);
+ ctx->init_priority = priority;
+ ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET;
+ ctx->stable_pstate = AMDGPU_CTX_STABLE_PSTATE_NONE;
+@@ -266,7 +263,7 @@ static void amdgpu_ctx_fini_entity(struct amdgpu_ctx_entity *entity)
+ static int amdgpu_ctx_get_stable_pstate(struct amdgpu_ctx *ctx,
+ u32 *stable_pstate)
+ {
+- struct amdgpu_device *adev = ctx->adev;
++ struct amdgpu_device *adev = ctx->mgr->adev;
+ enum amd_dpm_forced_level current_level;
+
+ current_level = amdgpu_dpm_get_performance_level(adev);
+@@ -294,7 +291,7 @@ static int amdgpu_ctx_get_stable_pstate(struct amdgpu_ctx *ctx,
+ static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
+ u32 stable_pstate)
+ {
+- struct amdgpu_device *adev = ctx->adev;
++ struct amdgpu_device *adev = ctx->mgr->adev;
+ enum amd_dpm_forced_level level;
+ u32 current_stable_pstate;
+ int r;
+@@ -345,7 +342,8 @@ static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
+ static void amdgpu_ctx_fini(struct kref *ref)
+ {
+ struct amdgpu_ctx *ctx = container_of(ref, struct amdgpu_ctx, refcount);
+- struct amdgpu_device *adev = ctx->adev;
++ struct amdgpu_ctx_mgr *mgr = ctx->mgr;
++ struct amdgpu_device *adev = mgr->adev;
+ unsigned i, j, idx;
+
+ if (!adev)
+@@ -421,7 +419,7 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
+ }
+
+ *id = (uint32_t)r;
+- r = amdgpu_ctx_init(adev, priority, filp, ctx);
++ r = amdgpu_ctx_init(mgr, priority, filp, ctx);
+ if (r) {
+ idr_remove(&mgr->ctx_handles, *id);
+ *id = 0;
+@@ -671,9 +669,9 @@ int amdgpu_ctx_put(struct amdgpu_ctx *ctx)
+ return 0;
+ }
+
+-void amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx,
+- struct drm_sched_entity *entity,
+- struct dma_fence *fence, uint64_t *handle)
++uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx,
++ struct drm_sched_entity *entity,
++ struct dma_fence *fence)
+ {
+ struct amdgpu_ctx_entity *centity = to_amdgpu_ctx_entity(entity);
+ uint64_t seq = centity->sequence;
+@@ -682,8 +680,7 @@ void amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx,
+
+ idx = seq & (amdgpu_sched_jobs - 1);
+ other = centity->fences[idx];
+- if (other)
+- BUG_ON(!dma_fence_is_signaled(other));
++ WARN_ON(other && !dma_fence_is_signaled(other));
+
+ dma_fence_get(fence);
+
+@@ -693,8 +690,7 @@ void amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx,
+ spin_unlock(&ctx->ring_lock);
+
+ dma_fence_put(other);
+- if (handle)
+- *handle = seq;
++ return seq;
+ }
+
+ struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
+@@ -731,7 +727,7 @@ static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
+ int hw_ip,
+ int32_t priority)
+ {
+- struct amdgpu_device *adev = ctx->adev;
++ struct amdgpu_device *adev = ctx->mgr->adev;
+ unsigned int hw_prio;
+ struct drm_gpu_scheduler **scheds = NULL;
+ unsigned num_scheds;
+@@ -796,8 +792,10 @@ int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx,
+ return r;
+ }
+
+-void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
++void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr,
++ struct amdgpu_device *adev)
+ {
++ mgr->adev = adev;
+ mutex_init(&mgr->lock);
+ idr_init(&mgr->ctx_handles);
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
+index 142f2f87d44c..681050bc828c 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
+@@ -40,7 +40,7 @@ struct amdgpu_ctx_entity {
+
+ struct amdgpu_ctx {
+ struct kref refcount;
+- struct amdgpu_device *adev;
++ struct amdgpu_ctx_mgr *mgr;
+ unsigned reset_counter;
+ unsigned reset_counter_query;
+ uint32_t vram_lost_counter;
+@@ -70,9 +70,9 @@ int amdgpu_ctx_put(struct amdgpu_ctx *ctx);
+
+ int amdgpu_ctx_get_entity(struct amdgpu_ctx *ctx, u32 hw_ip, u32 instance,
+ u32 ring, struct drm_sched_entity **entity);
+-void amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx,
+- struct drm_sched_entity *entity,
+- struct dma_fence *fence, uint64_t *seq);
++uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx,
++ struct drm_sched_entity *entity,
++ struct dma_fence *fence);
+ struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
+ struct drm_sched_entity *entity,
+ uint64_t seq);
+@@ -85,7 +85,8 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
+ int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx,
+ struct drm_sched_entity *entity);
+
+-void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr);
++void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr,
++ struct amdgpu_device *adev);
+ void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr);
+ long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout);
+ void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+index 49c55d82cba8..20a432a774c1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+@@ -1142,7 +1142,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
+ mutex_init(&fpriv->bo_list_lock);
+ idr_init(&fpriv->bo_list_handles);
+
+- amdgpu_ctx_mgr_init(&fpriv->ctx_mgr);
++ amdgpu_ctx_mgr_init(&fpriv->ctx_mgr, adev);
+
+ file_priv->driver_priv = fpriv;
+ goto out_suspend;
+--
+2.35.1
+
--- /dev/null
+From d52a6b9338a7ab278100940a58155b6a9159568f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 09:22:44 +0800
+Subject: drm/amdgpu: Remove one duplicated ef removal
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: xinhui pan <xinhui.pan@amd.com>
+
+[ Upstream commit e1aadbab445b06e072013a1365fd0cf2aa25e843 ]
+
+That has been done in BO release notify.
+
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2074
+Signed-off-by: xinhui pan <xinhui.pan@amd.com>
+Acked-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Felix Kuehling <Felix.Kuehling@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_amdkfd_gpuvm.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index f4509656ea8c..e9a8eb070766 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -1401,16 +1401,10 @@ void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
+ struct amdgpu_vm *vm)
+ {
+ struct amdkfd_process_info *process_info = vm->process_info;
+- struct amdgpu_bo *pd = vm->root.bo;
+
+ if (!process_info)
+ return;
+
+- /* Release eviction fence from PD */
+- amdgpu_bo_reserve(pd, false);
+- amdgpu_bo_fence(pd, NULL, false);
+- amdgpu_bo_unreserve(pd);
+-
+ /* Update process info */
+ mutex_lock(&process_info->lock);
+ process_info->n_vms--;
+--
+2.35.1
+
--- /dev/null
+From d07ea88b52c6d1cfad2bc2ceb0d47e00ec5a40c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 11:10:15 -0400
+Subject: drm/amdgpu: restore original stable pstate on ctx fini
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 958afce98c2c86732483458c03540d3c6ef45254 ]
+
+Save the original stable pstate on ctx init and restore
+it on ctx fini so that we restore a manually selected
+stable pstate on ctx exit.
+
+v2: fix init order (Alex)
+v3: don't add new variable to ctx struct (Evan)
+
+Fixes: c65b364c52ba ("drm/amdgpu/ctx: only reset stable pstate if the user changed it (v2)")
+Reviewed-by: Evan Quan <evan.quan@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_ctx.c | 60 ++++++++++++++-----------
+ 1 file changed, 33 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+index a61e4c83a545..95ed528e6ec5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+@@ -220,32 +220,6 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip,
+ return r;
+ }
+
+-static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
+- struct drm_file *filp, struct amdgpu_ctx *ctx)
+-{
+- int r;
+-
+- r = amdgpu_ctx_priority_permit(filp, priority);
+- if (r)
+- return r;
+-
+- memset(ctx, 0, sizeof(*ctx));
+-
+- kref_init(&ctx->refcount);
+- ctx->mgr = mgr;
+- spin_lock_init(&ctx->ring_lock);
+- mutex_init(&ctx->lock);
+-
+- ctx->reset_counter = atomic_read(&mgr->adev->gpu_reset_counter);
+- ctx->reset_counter_query = ctx->reset_counter;
+- ctx->vram_lost_counter = atomic_read(&mgr->adev->vram_lost_counter);
+- ctx->init_priority = priority;
+- ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET;
+- ctx->stable_pstate = AMDGPU_CTX_STABLE_PSTATE_NONE;
+-
+- return 0;
+-}
+-
+ static void amdgpu_ctx_fini_entity(struct amdgpu_ctx_entity *entity)
+ {
+
+@@ -288,6 +262,38 @@ static int amdgpu_ctx_get_stable_pstate(struct amdgpu_ctx *ctx,
+ return 0;
+ }
+
++static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
++ struct drm_file *filp, struct amdgpu_ctx *ctx)
++{
++ u32 current_stable_pstate;
++ int r;
++
++ r = amdgpu_ctx_priority_permit(filp, priority);
++ if (r)
++ return r;
++
++ memset(ctx, 0, sizeof(*ctx));
++
++ kref_init(&ctx->refcount);
++ ctx->mgr = mgr;
++ spin_lock_init(&ctx->ring_lock);
++ mutex_init(&ctx->lock);
++
++ ctx->reset_counter = atomic_read(&mgr->adev->gpu_reset_counter);
++ ctx->reset_counter_query = ctx->reset_counter;
++ ctx->vram_lost_counter = atomic_read(&mgr->adev->vram_lost_counter);
++ ctx->init_priority = priority;
++ ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET;
++
++ r = amdgpu_ctx_get_stable_pstate(ctx, ¤t_stable_pstate);
++ if (r)
++ return r;
++
++ ctx->stable_pstate = current_stable_pstate;
++
++ return 0;
++}
++
+ static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
+ u32 stable_pstate)
+ {
+@@ -357,7 +363,7 @@ static void amdgpu_ctx_fini(struct kref *ref)
+ }
+
+ if (drm_dev_enter(&adev->ddev, &idx)) {
+- amdgpu_ctx_set_stable_pstate(ctx, AMDGPU_CTX_STABLE_PSTATE_NONE);
++ amdgpu_ctx_set_stable_pstate(ctx, ctx->stable_pstate);
+ drm_dev_exit(idx);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From cda7578f8d3c18a514c16e45adbd4afe8a32d4d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 21:59:06 -0400
+Subject: drm/amdgpu: use the same HDP flush registers for all nbio 7.4.x
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 912db6a58738e8be502838eb6a88f207ba356cd7 ]
+
+Align aldebaran with all other asics. One HDP bit per
+SDMA instance, aligned with firmware. This is effectively
+a revert of
+commit a0f9f8546668 ("drm/amdgpu/nbio7.4: don't use GPU_HDP_FLUSH bit 12").
+On further discussions with the relevant hardware teams,
+re-align the bits for SDMA.
+
+Fixes: a0f9f8546668 ("drm/amdgpu/nbio7.4: don't use GPU_HDP_FLUSH bit 12")
+Reviewed-by: Kent Russell <kent.russell@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_discovery.c | 5 +----
+ drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 21 -------------------
+ drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h | 1 -
+ 3 files changed, 1 insertion(+), 26 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+index e4fcbb385a62..918bb7fef6ba 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+@@ -1891,12 +1891,9 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
+ break;
+ case IP_VERSION(7, 4, 0):
+ case IP_VERSION(7, 4, 1):
+- adev->nbio.funcs = &nbio_v7_4_funcs;
+- adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg;
+- break;
+ case IP_VERSION(7, 4, 4):
+ adev->nbio.funcs = &nbio_v7_4_funcs;
+- adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg_ald;
++ adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg;
+ break;
+ case IP_VERSION(7, 2, 0):
+ case IP_VERSION(7, 2, 1):
+diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
+index c2357e83a8c4..09c0def356a1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
++++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
+@@ -339,27 +339,6 @@ const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg = {
+ .ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__SDMA1_MASK,
+ };
+
+-const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg_ald = {
+- .ref_and_mask_cp0 = GPU_HDP_FLUSH_DONE__CP0_MASK,
+- .ref_and_mask_cp1 = GPU_HDP_FLUSH_DONE__CP1_MASK,
+- .ref_and_mask_cp2 = GPU_HDP_FLUSH_DONE__CP2_MASK,
+- .ref_and_mask_cp3 = GPU_HDP_FLUSH_DONE__CP3_MASK,
+- .ref_and_mask_cp4 = GPU_HDP_FLUSH_DONE__CP4_MASK,
+- .ref_and_mask_cp5 = GPU_HDP_FLUSH_DONE__CP5_MASK,
+- .ref_and_mask_cp6 = GPU_HDP_FLUSH_DONE__CP6_MASK,
+- .ref_and_mask_cp7 = GPU_HDP_FLUSH_DONE__CP7_MASK,
+- .ref_and_mask_cp8 = GPU_HDP_FLUSH_DONE__CP8_MASK,
+- .ref_and_mask_cp9 = GPU_HDP_FLUSH_DONE__CP9_MASK,
+- .ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK,
+- .ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK,
+- .ref_and_mask_sdma2 = GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK,
+- .ref_and_mask_sdma3 = GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK,
+- .ref_and_mask_sdma4 = GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK,
+- .ref_and_mask_sdma5 = GPU_HDP_FLUSH_DONE__RSVD_ENG6_MASK,
+- .ref_and_mask_sdma6 = GPU_HDP_FLUSH_DONE__RSVD_ENG7_MASK,
+- .ref_and_mask_sdma7 = GPU_HDP_FLUSH_DONE__RSVD_ENG8_MASK,
+-};
+-
+ static void nbio_v7_4_init_registers(struct amdgpu_device *adev)
+ {
+ uint32_t baco_cntl;
+diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h
+index 7490022d79d4..f27c41728822 100644
+--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h
++++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h
+@@ -27,7 +27,6 @@
+ #include "soc15_common.h"
+
+ extern const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg;
+-extern const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg_ald;
+ extern const struct amdgpu_nbio_funcs nbio_v7_4_funcs;
+ extern struct amdgpu_nbio_ras nbio_v7_4_ras;
+
+--
+2.35.1
+
--- /dev/null
+From 794a11e31910c3de2a53ffa18c099468d1df274f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 22:04:56 -0400
+Subject: drm/amdgpu: use the same HDP flush registers for all nbio 2.3.x
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 98a90f1f0fdd112b85b16ef6ceee69f319ab9311 ]
+
+Align RDNA2.x with other asics. One HDP bit per SDMA instance,
+aligned with firmware. This is effectively a revert of
+commit 369b7d04baf3 ("drm/amdgpu/nbio2.3: don't use GPU_HDP_FLUSH bit 12").
+On further discussions with the relevant hardware teams,
+re-align the bits for SDMA.
+
+Fixes: 369b7d04baf3 ("drm/amdgpu/nbio2.3: don't use GPU_HDP_FLUSH bit 12")
+Reviewed-by: Kent Russell <kent.russell@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_discovery.c | 5 +----
+ drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c | 21 -------------------
+ drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h | 1 -
+ 3 files changed, 1 insertion(+), 26 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+index 918bb7fef6ba..d68db66d969b 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+@@ -1907,15 +1907,12 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)
+ case IP_VERSION(2, 3, 0):
+ case IP_VERSION(2, 3, 1):
+ case IP_VERSION(2, 3, 2):
+- adev->nbio.funcs = &nbio_v2_3_funcs;
+- adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg;
+- break;
+ case IP_VERSION(3, 3, 0):
+ case IP_VERSION(3, 3, 1):
+ case IP_VERSION(3, 3, 2):
+ case IP_VERSION(3, 3, 3):
+ adev->nbio.funcs = &nbio_v2_3_funcs;
+- adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg_sc;
++ adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg;
+ break;
+ default:
+ break;
+diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
+index ee7cab37dfd5..dae78a1e88e6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
++++ b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
+@@ -328,27 +328,6 @@ const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg = {
+ .ref_and_mask_sdma1 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__SDMA1_MASK,
+ };
+
+-const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg_sc = {
+- .ref_and_mask_cp0 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP0_MASK,
+- .ref_and_mask_cp1 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP1_MASK,
+- .ref_and_mask_cp2 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP2_MASK,
+- .ref_and_mask_cp3 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP3_MASK,
+- .ref_and_mask_cp4 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP4_MASK,
+- .ref_and_mask_cp5 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP5_MASK,
+- .ref_and_mask_cp6 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP6_MASK,
+- .ref_and_mask_cp7 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP7_MASK,
+- .ref_and_mask_cp8 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP8_MASK,
+- .ref_and_mask_cp9 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP9_MASK,
+- .ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK,
+- .ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK,
+- .ref_and_mask_sdma2 = GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK,
+- .ref_and_mask_sdma3 = GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK,
+- .ref_and_mask_sdma4 = GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK,
+- .ref_and_mask_sdma5 = GPU_HDP_FLUSH_DONE__RSVD_ENG6_MASK,
+- .ref_and_mask_sdma6 = GPU_HDP_FLUSH_DONE__RSVD_ENG7_MASK,
+- .ref_and_mask_sdma7 = GPU_HDP_FLUSH_DONE__RSVD_ENG8_MASK,
+-};
+-
+ static void nbio_v2_3_init_registers(struct amdgpu_device *adev)
+ {
+ uint32_t def, data;
+diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h
+index 6074dd3a1ed8..a43b60acf7f6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h
++++ b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h
+@@ -27,7 +27,6 @@
+ #include "soc15_common.h"
+
+ extern const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg;
+-extern const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg_sc;
+ extern const struct amdgpu_nbio_funcs nbio_v2_3_funcs;
+
+ #endif
+--
+2.35.1
+
--- /dev/null
+From 6b315c1511186efad40e6828ef0175ee5da9dc39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 18:34:01 +0800
+Subject: drm: bridge: adv7511: Add check for mipi_dsi_driver_register
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 831463667b5f4f1e5bce9c3b94e9e794d2bc8923 ]
+
+As mipi_dsi_driver_register could return error if fails,
+it should be better to check the return value and return error
+if fails.
+Moreover, if i2c_add_driver fails, mipi_dsi_driver_register
+should be reverted.
+
+Fixes: 1e4d58cd7f88 ("drm/bridge: adv7533: Create a MIPI DSI device")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220602103401.2980938-1-jiasheng@iscas.ac.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index fba6ad3bb6ad..f4d6359f6219 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -1384,10 +1384,21 @@ static struct i2c_driver adv7511_driver = {
+
+ static int __init adv7511_init(void)
+ {
+- if (IS_ENABLED(CONFIG_DRM_MIPI_DSI))
+- mipi_dsi_driver_register(&adv7533_dsi_driver);
++ int ret;
++
++ if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) {
++ ret = mipi_dsi_driver_register(&adv7533_dsi_driver);
++ if (ret)
++ return ret;
++ }
+
+- return i2c_add_driver(&adv7511_driver);
++ ret = i2c_add_driver(&adv7511_driver);
++ if (ret) {
++ if (IS_ENABLED(CONFIG_DRM_MIPI_DSI))
++ mipi_dsi_driver_unregister(&adv7533_dsi_driver);
++ }
++
++ return ret;
+ }
+ module_init(adv7511_init);
+
+--
+2.35.1
+
--- /dev/null
+From f9a4f2128c2f5cf6f3a61e1a47b206a702b2ed77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 20:52:53 +0800
+Subject: drm/bridge: anx7625: Fix NULL pointer crash when using edp-panel
+
+From: Hsin-Yi Wang <hsinyi@chromium.org>
+
+[ Upstream commit dfb02eb6bdf84697dbadd69a7df12db612ce4ed0 ]
+
+Move devm_of_dp_aux_populate_ep_devices() after pm runtime and i2c setup
+to avoid NULL pointer crash.
+
+edp-panel probe (generic_edp_panel_probe) calls pm_runtime_get_sync() to
+read EDID. At this time, bridge should have pm runtime enabled and i2c
+clients ready.
+
+Fixes: adca62ec370c ("drm/bridge: anx7625: Support reading edid through aux channel")
+Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
+Reviewed-by: Xin Ji <xji@analogixsemi.com>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220706125254.2474095-4-hsinyi@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/analogix/anx7625.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
+index 060849f8ad8b..c527a3a02eac 100644
+--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
++++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
+@@ -2651,14 +2651,6 @@ static int anx7625_i2c_probe(struct i2c_client *client,
+ platform->aux.dev = dev;
+ platform->aux.transfer = anx7625_aux_transfer;
+ drm_dp_aux_init(&platform->aux);
+- devm_of_dp_aux_populate_ep_devices(&platform->aux);
+-
+- ret = anx7625_parse_dt(dev, pdata);
+- if (ret) {
+- if (ret != -EPROBE_DEFER)
+- DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret);
+- goto free_wq;
+- }
+
+ if (anx7625_register_i2c_dummy_clients(platform, client) != 0) {
+ ret = -ENOMEM;
+@@ -2674,6 +2666,15 @@ static int anx7625_i2c_probe(struct i2c_client *client,
+ if (ret)
+ goto free_wq;
+
++ devm_of_dp_aux_populate_ep_devices(&platform->aux);
++
++ ret = anx7625_parse_dt(dev, pdata);
++ if (ret) {
++ if (ret != -EPROBE_DEFER)
++ DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret);
++ goto free_wq;
++ }
++
+ if (!platform->pdata.low_power_mode) {
+ anx7625_disable_pd_protocol(platform);
+ pm_runtime_get_sync(dev);
+--
+2.35.1
+
--- /dev/null
+From 07ca4b762797e7ead75fe43c6bdd9e25a38b3a4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 23:06:53 +0800
+Subject: drm/bridge: it6505: Add missing CRYPTO_HASH dependency
+
+From: Zheng Bin <zhengbin13@huawei.com>
+
+[ Upstream commit abf0ba5a34eae0d7359228f4319a6659676fbd0a ]
+
+The driver uses crypto hash functions so it needs to select CRYPTO_HASH.
+This fixes build errors:
+
+drivers/gpu/drm/bridge/ite-it6505.o: in function `it6505_hdcp_wait_ksv_list':
+ite-it6505.c:(.text+0x4c26): undefined reference to `crypto_alloc_shash'
+ite-it6505.c:(.text+0x4c6d): undefined reference to `crypto_shash_digest'
+ite-it6505.c:(.text+0x4c7d): undefined reference to `crypto_destroy_tfm'
+ite-it6505.c:(.text+0x4d69): undefined reference to `crypto_destroy_tfm'
+
+Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver")
+Signed-off-by: Zheng Bin <zhengbin13@huawei.com>
+Reviewed-by: Robert Foss <robert.foss@linaro.org>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220613150653.1310029-1-zhengbin13@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/Kconfig | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
+index be2fc4791c1d..7d152cc6f837 100644
+--- a/drivers/gpu/drm/bridge/Kconfig
++++ b/drivers/gpu/drm/bridge/Kconfig
+@@ -82,6 +82,8 @@ config DRM_ITE_IT6505
+ select DRM_KMS_HELPER
+ select DRM_DP_HELPER
+ select EXTCON
++ select CRYPTO
++ select CRYPTO_HASH
+ help
+ ITE IT6505 DisplayPort bridge chip driver.
+
+--
+2.35.1
+
--- /dev/null
+From 3bdd2d1aae156cd0ccf3470edd9866a676109c86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 01:26:12 +0000
+Subject: drm/bridge: lt9611: Use both bits for HDMI sensing
+
+From: John Stultz <jstultz@google.com>
+
+[ Upstream commit 649eb3828fb22e829e222ebd83f4e11dc503a565 ]
+
+In commit 19cf41b64e3b ("lontium-lt9611: check a different
+register bit for HDMI sensing"), the bit flag used to detect
+HDMI cable connect was switched from BIT(2) to BIT(0) to improve
+compatibility with some monitors that didn't seem to set BIT(2).
+
+However, with that change, I've seen occasional issues where the
+detection failed, because BIT(2) was set, but not BIT(0).
+
+Unfortunately, as I understand it, the bits and their function
+was never clearly documented. So lets instead check both
+(BIT(2) | BIT(0)) when checking the register.
+
+Cc: Yongqin Liu <yongqin.liu@linaro.org>
+Cc: Amit Pundir <amit.pundir@linaro.org>
+Cc: Peter Collingbourne <pcc@google.com>
+Cc: Vinod Koul <vkoul@kernel.org>
+Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
+Cc: Robert Foss <robert.foss@linaro.org>
+Cc: kernel-team@android.com
+Fixes: 19cf41b64e3b ("lontium-lt9611: check a different register bit for HDMI sensing")
+Signed-off-by: John Stultz <jstultz@google.com>
+Reviewed-by: Robert Foss <robert.foss@linaro.org>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220511012612.3297577-2-jstultz@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt9611.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
+index 63df2e8a8abc..21d1e1465981 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
+@@ -586,7 +586,7 @@ lt9611_connector_detect(struct drm_connector *connector, bool force)
+ int connected = 0;
+
+ regmap_read(lt9611->regmap, 0x825e, ®_val);
+- connected = (reg_val & BIT(0));
++ connected = (reg_val & (BIT(2) | BIT(0)));
+
+ lt9611->status = connected ? connector_status_connected :
+ connector_status_disconnected;
+--
+2.35.1
+
--- /dev/null
+From bf7d11e9d8508975b6cacfb848d5a4bbe3b8f6a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 16:38:18 -0700
+Subject: drm/bridge: lt9611uxc: Cancel only driver's work
+
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+
+[ Upstream commit dfa687bffc8a4a21ed929c7dececf01b8f1f52ee ]
+
+During device remove care needs to be taken that no work is pending
+before it removes the underlying DRM bridge etc, but this can be done on
+the specific work rather than waiting for the flush of the system-wide
+workqueue.
+
+Fixes: bc6fa8676ebb ("drm/bridge/lontium-lt9611uxc: move HPD notification out of IRQ handler")
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220601233818.1877963-1-bjorn.andersson@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+index 3d62e6bf6892..310b3b194491 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+@@ -982,7 +982,7 @@ static int lt9611uxc_remove(struct i2c_client *client)
+ struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client);
+
+ disable_irq(client->irq);
+- flush_scheduled_work();
++ cancel_work_sync(<9611uxc->work);
+ lt9611uxc_audio_exit(lt9611uxc);
+ drm_bridge_remove(<9611uxc->bridge);
+
+--
+2.35.1
+
--- /dev/null
+From 00170a927e1a3c3f6ca47f5fae20360ec5d21b6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 May 2022 14:58:56 +0800
+Subject: drm: bridge: sii8620: fix possible off-by-one
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit 21779cc21c732c5eff8ea1624be6590450baa30f ]
+
+The next call to sii8620_burst_get_tx_buf will result in off-by-one
+When ctx->burst.tx_count + size == ARRAY_SIZE(ctx->burst.tx_buf). The same
+thing happens in sii8620_burst_get_rx_buf.
+
+This patch also change tx_count and tx_buf to rx_count and rx_buf in
+sii8620_burst_get_rx_buf. It is unreasonable to check tx_buf's size and
+use rx_buf.
+
+Fixes: e19e9c692f81 ("drm/bridge/sii8620: add support for burst eMSC transmissions")
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220518065856.18936-1-hbh25y@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/sil-sii8620.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c
+index ec7745c31da0..ab0bce4a988c 100644
+--- a/drivers/gpu/drm/bridge/sil-sii8620.c
++++ b/drivers/gpu/drm/bridge/sil-sii8620.c
+@@ -605,7 +605,7 @@ static void *sii8620_burst_get_tx_buf(struct sii8620 *ctx, int len)
+ u8 *buf = &ctx->burst.tx_buf[ctx->burst.tx_count];
+ int size = len + 2;
+
+- if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) {
++ if (ctx->burst.tx_count + size >= ARRAY_SIZE(ctx->burst.tx_buf)) {
+ dev_err(ctx->dev, "TX-BLK buffer exhausted\n");
+ ctx->error = -EINVAL;
+ return NULL;
+@@ -622,7 +622,7 @@ static u8 *sii8620_burst_get_rx_buf(struct sii8620 *ctx, int len)
+ u8 *buf = &ctx->burst.rx_buf[ctx->burst.rx_count];
+ int size = len + 1;
+
+- if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) {
++ if (ctx->burst.rx_count + size >= ARRAY_SIZE(ctx->burst.rx_buf)) {
+ dev_err(ctx->dev, "RX-BLK buffer exhausted\n");
+ ctx->error = -EINVAL;
+ return NULL;
+--
+2.35.1
+
--- /dev/null
+From 25e6aac3e34d3cf40bd7b210a5aa8ba7a547e110 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 14:15:43 +0200
+Subject: drm/bridge: tc358767: Make sure Refclk clock are enabled
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 0b4c48f3e315d172e4cc06e10f2c8ba180788baf ]
+
+The Refclk may be supplied by SoC clock output instead of crystal
+oscillator, make sure the clock are enabled before any other action
+is performed with the bridge chip, otherwise it may either fail to
+operate at all, or miss reset GPIO toggle.
+
+Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
+Fixes: 7caff0fc4296e ("drm/bridge: tc358767: Add DPI to eDP bridge driver")
+Signed-off-by: Marek Vasut <marex@denx.de>
+Cc: Jonas Karlman <jonas@kwiboo.se>
+Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
+Cc: Lucas Stach <l.stach@pengutronix.de>
+Cc: Marek Vasut <marex@denx.de>
+Cc: Maxime Ripard <maxime@cerno.tech>
+Cc: Neil Armstrong <narmstrong@baylibre.com>
+Cc: Robert Foss <robert.foss@linaro.org>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Reviewed-by: Maxime Ripard <maxime@cerno.tech>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220520121543.11550-1-marex@denx.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358767.c | 32 ++++++++++++++++++++++++-------
+ 1 file changed, 25 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
+index 835a146a0196..5a51c1699b29 100644
+--- a/drivers/gpu/drm/bridge/tc358767.c
++++ b/drivers/gpu/drm/bridge/tc358767.c
+@@ -1576,6 +1576,13 @@ static int tc_probe_edp_bridge_endpoint(struct tc_data *tc)
+ return ret;
+ }
+
++static void tc_clk_disable(void *data)
++{
++ struct clk *refclk = data;
++
++ clk_disable_unprepare(refclk);
++}
++
+ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ {
+ struct device *dev = &client->dev;
+@@ -1592,6 +1599,24 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ if (ret)
+ return ret;
+
++ tc->refclk = devm_clk_get(dev, "ref");
++ if (IS_ERR(tc->refclk)) {
++ ret = PTR_ERR(tc->refclk);
++ dev_err(dev, "Failed to get refclk: %d\n", ret);
++ return ret;
++ }
++
++ ret = clk_prepare_enable(tc->refclk);
++ if (ret)
++ return ret;
++
++ ret = devm_add_action_or_reset(dev, tc_clk_disable, tc->refclk);
++ if (ret)
++ return ret;
++
++ /* tRSTW = 100 cycles , at 13 MHz that is ~7.69 us */
++ usleep_range(10, 15);
++
+ /* Shut down GPIO is optional */
+ tc->sd_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);
+ if (IS_ERR(tc->sd_gpio))
+@@ -1612,13 +1637,6 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ usleep_range(5000, 10000);
+ }
+
+- tc->refclk = devm_clk_get(dev, "ref");
+- if (IS_ERR(tc->refclk)) {
+- ret = PTR_ERR(tc->refclk);
+- dev_err(dev, "Failed to get refclk: %d\n", ret);
+- return ret;
+- }
+-
+ tc->regmap = devm_regmap_init_i2c(client, &tc_regmap_config);
+ if (IS_ERR(tc->regmap)) {
+ ret = PTR_ERR(tc->regmap);
+--
+2.35.1
+
--- /dev/null
+From 34b846772afcc218de6722ab9c9096988a031a6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Mar 2022 10:50:10 +0200
+Subject: drm/bridge: tc358767: Move (e)DP bridge endpoint parsing into
+ dedicated function
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 8478095a8c4bcea3c83b0767d6c9127434160761 ]
+
+The TC358767/TC358867/TC9595 are all capable of operating in multiple
+modes, DPI-to-(e)DP, DSI-to-(e)DP, DSI-to-DPI. Only the first mode is
+currently supported. In order to support the rest of the modes without
+making the tc_probe() overly long, split the bridge endpoint parsing
+into dedicated function, where the necessary logic to detect the bridge
+mode based on which endpoints are connected, can be implemented.
+
+Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
+Tested-by: Lucas Stach <l.stach@pengutronix.de> # In both DPI to eDP and DSI to DPI mode.
+Signed-off-by: Marek Vasut <marex@denx.de>
+Cc: Jonas Karlman <jonas@kwiboo.se>
+Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
+Cc: Maxime Ripard <maxime@cerno.tech>
+Cc: Neil Armstrong <narmstrong@baylibre.com>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Signed-off-by: Robert Foss <robert.foss@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220329085015.39159-7-marex@denx.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358767.c | 30 +++++++++++++++++++++---------
+ 1 file changed, 21 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
+index c23e0abc65e8..835a146a0196 100644
+--- a/drivers/gpu/drm/bridge/tc358767.c
++++ b/drivers/gpu/drm/bridge/tc358767.c
+@@ -1549,19 +1549,12 @@ static irqreturn_t tc_irq_handler(int irq, void *arg)
+ return IRQ_HANDLED;
+ }
+
+-static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
++static int tc_probe_edp_bridge_endpoint(struct tc_data *tc)
+ {
+- struct device *dev = &client->dev;
++ struct device *dev = tc->dev;
+ struct drm_panel *panel;
+- struct tc_data *tc;
+ int ret;
+
+- tc = devm_kzalloc(dev, sizeof(*tc), GFP_KERNEL);
+- if (!tc)
+- return -ENOMEM;
+-
+- tc->dev = dev;
+-
+ /* port@2 is the output port */
+ ret = drm_of_find_panel_or_bridge(dev->of_node, 2, 0, &panel, NULL);
+ if (ret && ret != -ENODEV)
+@@ -1580,6 +1573,25 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ tc->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
+ }
+
++ return ret;
++}
++
++static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
++{
++ struct device *dev = &client->dev;
++ struct tc_data *tc;
++ int ret;
++
++ tc = devm_kzalloc(dev, sizeof(*tc), GFP_KERNEL);
++ if (!tc)
++ return -ENOMEM;
++
++ tc->dev = dev;
++
++ ret = tc_probe_edp_bridge_endpoint(tc);
++ if (ret)
++ return ret;
++
+ /* Shut down GPIO is optional */
+ tc->sd_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);
+ if (IS_ERR(tc->sd_gpio))
+--
+2.35.1
+
--- /dev/null
+From a3d944f5379ed7af9af258ce0009d1ac0a6a4a82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 May 2022 12:29:41 -0700
+Subject: drm/dp: Export symbol / kerneldoc fixes for DP AUX bus
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit 39c28cdfb719f0e306b447f0827dfd712f81858b ]
+
+While working on the DP AUX bus code I found a few small things that
+should be fixed. Namely the non-devm version of
+of_dp_aux_populate_ep_devices() was missing an export. There was also
+an extra blank line in a kerneldoc and a kerneldoc that incorrectly
+documented a return value. Fix these.
+
+Fixes: aeb33699fc2c ("drm: Introduce the DP AUX bus")
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220510122726.v3.1.Ia91f4849adfc5eb9da1eb37ba79aa65fb3c95a0f@changeid
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/dp/drm_dp_aux_bus.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/dp/drm_dp_aux_bus.c b/drivers/gpu/drm/dp/drm_dp_aux_bus.c
+index 415afce3cf96..5f06bc0a34ac 100644
+--- a/drivers/gpu/drm/dp/drm_dp_aux_bus.c
++++ b/drivers/gpu/drm/dp/drm_dp_aux_bus.c
+@@ -66,7 +66,6 @@ static int dp_aux_ep_probe(struct device *dev)
+ * @dev: The device to remove.
+ *
+ * Calls through to the endpoint driver remove.
+- *
+ */
+ static void dp_aux_ep_remove(struct device *dev)
+ {
+@@ -120,8 +119,6 @@ ATTRIBUTE_GROUPS(dp_aux_ep_dev);
+ /**
+ * dp_aux_ep_dev_release() - Free memory for the dp_aux_ep device
+ * @dev: The device to free.
+- *
+- * Return: 0 if no error or negative error code.
+ */
+ static void dp_aux_ep_dev_release(struct device *dev)
+ {
+@@ -256,6 +253,7 @@ int of_dp_aux_populate_ep_devices(struct drm_dp_aux *aux)
+
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(of_dp_aux_populate_ep_devices);
+
+ static void of_dp_aux_depopulate_ep_devices_void(void *data)
+ {
+--
+2.35.1
+
--- /dev/null
+From f8aaada02812bb02f3a3d8c954ff7c24a5a13a0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 13:56:11 +0900
+Subject: drm/exynos/exynos7_drm_decon: free resources when clk_set_parent()
+ failed.
+
+From: Jian Zhang <zhangjian210@huawei.com>
+
+[ Upstream commit 48b927770f8ad3f8cf4a024a552abf272af9f592 ]
+
+In exynos7_decon_resume, When it fails, we must use clk_disable_unprepare()
+to free resource that have been used.
+
+Fixes: 6f83d20838c09 ("drm/exynos: use DRM_DEV_ERROR to print out error
+message")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Jian Zhang <zhangjian210@huawei.com>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/exynos/exynos7_drm_decon.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+index c04264f70ad1..3c31405600f0 100644
+--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
++++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+@@ -800,31 +800,40 @@ static int exynos7_decon_resume(struct device *dev)
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to prepare_enable the pclk [%d]\n",
+ ret);
+- return ret;
++ goto err_pclk_enable;
+ }
+
+ ret = clk_prepare_enable(ctx->aclk);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to prepare_enable the aclk [%d]\n",
+ ret);
+- return ret;
++ goto err_aclk_enable;
+ }
+
+ ret = clk_prepare_enable(ctx->eclk);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to prepare_enable the eclk [%d]\n",
+ ret);
+- return ret;
++ goto err_eclk_enable;
+ }
+
+ ret = clk_prepare_enable(ctx->vclk);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to prepare_enable the vclk [%d]\n",
+ ret);
+- return ret;
++ goto err_vclk_enable;
+ }
+
+ return 0;
++
++err_vclk_enable:
++ clk_disable_unprepare(ctx->eclk);
++err_eclk_enable:
++ clk_disable_unprepare(ctx->aclk);
++err_aclk_enable:
++ clk_disable_unprepare(ctx->pclk);
++err_pclk_enable:
++ return ret;
+ }
+ #endif
+
+--
+2.35.1
+
--- /dev/null
+From 0269200ddc7d0cb7f8a3527921578c102d7ce5bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 15:54:11 +0400
+Subject: drm/mcde: Fix refcount leak in mcde_dsi_bind
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 3a149169e4a2f9127022fec6ef5d71b4e804b3b9 ]
+
+Every iteration of for_each_available_child_of_node() decrements
+the reference counter of the previous node. There is no decrement
+when break out from the loop and results in refcount leak.
+Add missing of_node_put() to fix this.
+
+Fixes: 5fc537bfd000 ("drm/mcde: Add new driver for ST-Ericsson MCDE")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220525115411.65455-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mcde/mcde_dsi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c
+index 5651734ce977..9f9ac8699310 100644
+--- a/drivers/gpu/drm/mcde/mcde_dsi.c
++++ b/drivers/gpu/drm/mcde/mcde_dsi.c
+@@ -1111,6 +1111,7 @@ static int mcde_dsi_bind(struct device *dev, struct device *master,
+ bridge = of_drm_find_bridge(child);
+ if (!bridge) {
+ dev_err(dev, "failed to find bridge\n");
++ of_node_put(child);
+ return -EINVAL;
+ }
+ }
+--
+2.35.1
+
--- /dev/null
+From aed5b7f2f52716583e729203d76eceff57b8f78f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 10:00:07 +0800
+Subject: drm/mediatek: Add pull-down MIPI operation in mtk_dsi_poweroff
+ function
+
+From: Xinlei Lee <xinlei.lee@mediatek.com>
+
+[ Upstream commit fa5d0a0205c34734c5b8daa77e39ac2817f63a10 ]
+
+In the dsi_enable function, mtk_dsi_rxtx_control is to
+pull up the MIPI signal operation. Before dsi_disable,
+MIPI should also be pulled down by writing a register
+instead of disabling dsi.
+
+If disable dsi without pulling the mipi signal low, the value of
+the register will still maintain the setting of the mipi signal being
+pulled high.
+After resume, even if the mipi signal is not pulled high, it will still
+be in the high state.
+
+Fixes: 2e54c14e310f ("drm/mediatek: Add DSI sub driver")
+
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/1653012007-11854-5-git-send-email-xinlei.lee@mediatek.com/
+Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
+Signed-off-by: Xinlei Lee <xinlei.lee@mediatek.com>
+Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_dsi.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
+index 3a6ee6e9ad2c..f0f523bdafb8 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
+@@ -682,6 +682,8 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
+ mtk_dsi_reset_engine(dsi);
+ mtk_dsi_lane0_ulp_mode_enter(dsi);
+ mtk_dsi_clk_ulp_mode_enter(dsi);
++ /* set the lane number as 0 to pull down mipi */
++ writel(0, dsi->regs + DSI_TXRX_CTRL);
+
+ mtk_dsi_disable(dsi);
+
+--
+2.35.1
+
--- /dev/null
+From eddfc29b5abd9809a2ee4ee0fc01407e5d5bbfad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 11:58:44 +0800
+Subject: drm/mediatek: dpi: Only enable dpi after the bridge is enabled
+
+From: Guillaume Ranquet <granquet@baylibre.com>
+
+[ Upstream commit aed61ef6beb911cc043af0f2f291167663995065 ]
+
+Enabling the dpi too early causes glitches on screen.
+
+Move the call to mtk_dpi_enable() at the end of the bridge_enable
+callback to ensure everything is setup properly before enabling dpi.
+
+Fixes: 9e629c17aa8d ("drm/mediatek: Add DPI sub driver")
+Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
+Signed-off-by: Bo-Chen Chen <rex-bc.chen@mediatek.com>
+Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20220701035845.16458-16-rex-bc.chen@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_dpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
+index 675e2e4072df..41c783349321 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
+@@ -417,7 +417,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
+ if (dpi->pinctrl && dpi->pins_dpi)
+ pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
+
+- mtk_dpi_enable(dpi);
+ return 0;
+
+ err_pixel:
+@@ -639,6 +638,7 @@ static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
+
+ mtk_dpi_power_on(dpi);
+ mtk_dpi_set_display_mode(dpi, &dpi->mode);
++ mtk_dpi_enable(dpi);
+ }
+
+ static enum drm_mode_status
+--
+2.35.1
+
--- /dev/null
+From ef71d54843e8a9dd93fbf3937395c962246594b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 11:58:33 +0800
+Subject: drm/mediatek: dpi: Remove output format of YUV
+
+From: Bo-Chen Chen <rex-bc.chen@mediatek.com>
+
+[ Upstream commit c9ed0713b3c35fc45677707ba47f432cad95da56 ]
+
+DPI is not support output format as YUV, but there is the setting of
+configuring output YUV. Therefore, remove them in this patch.
+
+Fixes: 9e629c17aa8d ("drm/mediatek: Add DPI sub driver")
+Signed-off-by: Bo-Chen Chen <rex-bc.chen@mediatek.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20220701035845.16458-5-rex-bc.chen@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_dpi.c | 31 ++++++------------------------
+ 1 file changed, 6 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
+index e61cd67b978f..675e2e4072df 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
+@@ -54,13 +54,7 @@ enum mtk_dpi_out_channel_swap {
+ };
+
+ enum mtk_dpi_out_color_format {
+- MTK_DPI_COLOR_FORMAT_RGB,
+- MTK_DPI_COLOR_FORMAT_RGB_FULL,
+- MTK_DPI_COLOR_FORMAT_YCBCR_444,
+- MTK_DPI_COLOR_FORMAT_YCBCR_422,
+- MTK_DPI_COLOR_FORMAT_XV_YCC,
+- MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL,
+- MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL
++ MTK_DPI_COLOR_FORMAT_RGB
+ };
+
+ struct mtk_dpi {
+@@ -364,24 +358,11 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
+ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
+ enum mtk_dpi_out_color_format format)
+ {
+- if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_444) ||
+- (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
+- mtk_dpi_config_yuv422_enable(dpi, false);
+- mtk_dpi_config_csc_enable(dpi, true);
+- mtk_dpi_config_swap_input(dpi, false);
+- mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
+- } else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
+- (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
+- mtk_dpi_config_yuv422_enable(dpi, true);
+- mtk_dpi_config_csc_enable(dpi, true);
+- mtk_dpi_config_swap_input(dpi, true);
+- mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
+- } else {
+- mtk_dpi_config_yuv422_enable(dpi, false);
+- mtk_dpi_config_csc_enable(dpi, false);
+- mtk_dpi_config_swap_input(dpi, false);
+- mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
+- }
++ /* only support RGB888 */
++ mtk_dpi_config_yuv422_enable(dpi, false);
++ mtk_dpi_config_csc_enable(dpi, false);
++ mtk_dpi_config_swap_input(dpi, false);
++ mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
+ }
+
+ static void mtk_dpi_dual_edge(struct mtk_dpi *dpi)
+--
+2.35.1
+
--- /dev/null
+From c1284a5645a1a3a9fa6b47704c0b4bb943810b74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 10:00:04 +0800
+Subject: drm/mediatek: Modify dsi funcs to atomic operations
+
+From: Xinlei Lee <xinlei.lee@mediatek.com>
+
+[ Upstream commit 7f6335c6a258edf4d5ff1b904bc033188dc7b48b ]
+
+Because .enable & .disable are deprecated.
+Use .atomic_enable & .atomic_disable instead.
+
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/1653012007-11854-2-git-send-email-xinlei.lee@mediatek.com/
+Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
+Signed-off-by: Xinlei Lee <xinlei.lee@mediatek.com>
+Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_dsi.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
+index ccb0511b9cd5..7a98ae100c06 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
+@@ -751,14 +751,16 @@ static void mtk_dsi_bridge_mode_set(struct drm_bridge *bridge,
+ drm_display_mode_to_videomode(adjusted, &dsi->vm);
+ }
+
+-static void mtk_dsi_bridge_disable(struct drm_bridge *bridge)
++static void mtk_dsi_bridge_atomic_disable(struct drm_bridge *bridge,
++ struct drm_bridge_state *old_bridge_state)
+ {
+ struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+
+ mtk_output_dsi_disable(dsi);
+ }
+
+-static void mtk_dsi_bridge_enable(struct drm_bridge *bridge)
++static void mtk_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
++ struct drm_bridge_state *old_bridge_state)
+ {
+ struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+
+@@ -767,8 +769,8 @@ static void mtk_dsi_bridge_enable(struct drm_bridge *bridge)
+
+ static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = {
+ .attach = mtk_dsi_bridge_attach,
+- .disable = mtk_dsi_bridge_disable,
+- .enable = mtk_dsi_bridge_enable,
++ .atomic_disable = mtk_dsi_bridge_atomic_disable,
++ .atomic_enable = mtk_dsi_bridge_atomic_enable,
+ .mode_set = mtk_dsi_bridge_mode_set,
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 8282341518f3fb5fbc39f4c47b541dcdaa734698 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 10:00:05 +0800
+Subject: drm/mediatek: Separate poweron/poweroff from enable/disable and
+ define new funcs
+
+From: Jitao Shi <jitao.shi@mediatek.com>
+
+[ Upstream commit cde7e2e35c2866d22a3a012e72a41052dfcc255d ]
+
+In order to match the changes of "Use the drm_panel_bridge API",
+the poweron/poweroff of dsi is extracted from enable/disable and
+defined as new funcs (atomic_pre_enable/atomic_post_disable).
+
+Since dsi_poweron is moved from dsi_enable to pre_enable function, in
+order to avoid poweron failure, the operation of dsi register fails to
+cause bus hang. Therefore, the protection mechanism is added to the
+dsi_enable function.
+
+Fixes: 2dd8075d2185 ("drm/mediatek: mtk_dsi: Use the drm_panel_bridge API")
+
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/1653012007-11854-3-git-send-email-xinlei.lee@mediatek.com/
+Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
+Signed-off-by: Xinlei Lee <xinlei.lee@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Rex-BC Chen <rex-bc.chen@mediatek.com>
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_dsi.c | 53 +++++++++++++++++++-----------
+ 1 file changed, 34 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
+index 7a98ae100c06..3a6ee6e9ad2c 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
+@@ -679,16 +679,6 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
+ if (--dsi->refcount != 0)
+ return;
+
+- /*
+- * mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since
+- * mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(),
+- * which needs irq for vblank, and mtk_dsi_stop() will disable irq.
+- * mtk_dsi_start() needs to be called in mtk_output_dsi_enable(),
+- * after dsi is fully set.
+- */
+- mtk_dsi_stop(dsi);
+-
+- mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500);
+ mtk_dsi_reset_engine(dsi);
+ mtk_dsi_lane0_ulp_mode_enter(dsi);
+ mtk_dsi_clk_ulp_mode_enter(dsi);
+@@ -703,17 +693,9 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
+
+ static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
+ {
+- int ret;
+-
+ if (dsi->enabled)
+ return;
+
+- ret = mtk_dsi_poweron(dsi);
+- if (ret < 0) {
+- DRM_ERROR("failed to power on dsi\n");
+- return;
+- }
+-
+ mtk_dsi_set_mode(dsi);
+ mtk_dsi_clk_hs_mode(dsi, 1);
+
+@@ -727,7 +709,16 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
+ if (!dsi->enabled)
+ return;
+
+- mtk_dsi_poweroff(dsi);
++ /*
++ * mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since
++ * mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(),
++ * which needs irq for vblank, and mtk_dsi_stop() will disable irq.
++ * mtk_dsi_start() needs to be called in mtk_output_dsi_enable(),
++ * after dsi is fully set.
++ */
++ mtk_dsi_stop(dsi);
++
++ mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500);
+
+ dsi->enabled = false;
+ }
+@@ -764,13 +755,37 @@ static void mtk_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
+ {
+ struct mtk_dsi *dsi = bridge_to_dsi(bridge);
+
++ if (dsi->refcount == 0)
++ return;
++
+ mtk_output_dsi_enable(dsi);
+ }
+
++static void mtk_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
++ struct drm_bridge_state *old_bridge_state)
++{
++ struct mtk_dsi *dsi = bridge_to_dsi(bridge);
++ int ret;
++
++ ret = mtk_dsi_poweron(dsi);
++ if (ret < 0)
++ DRM_ERROR("failed to power on dsi\n");
++}
++
++static void mtk_dsi_bridge_atomic_post_disable(struct drm_bridge *bridge,
++ struct drm_bridge_state *old_bridge_state)
++{
++ struct mtk_dsi *dsi = bridge_to_dsi(bridge);
++
++ mtk_dsi_poweroff(dsi);
++}
++
+ static const struct drm_bridge_funcs mtk_dsi_bridge_funcs = {
+ .attach = mtk_dsi_bridge_attach,
+ .atomic_disable = mtk_dsi_bridge_atomic_disable,
+ .atomic_enable = mtk_dsi_bridge_atomic_enable,
++ .atomic_pre_enable = mtk_dsi_bridge_atomic_pre_enable,
++ .atomic_post_disable = mtk_dsi_bridge_atomic_post_disable,
+ .mode_set = mtk_dsi_bridge_mode_set,
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 36e982e89e4fa9559d2bf99590fe2d19a9b11186 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 07:39:26 +0400
+Subject: drm/meson: encoder_cvbs: Fix refcount leak in meson_encoder_cvbs_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 7d255ddbbf679aa47e041cbf68520fd985ed2279 ]
+
+of_graph_get_remote_node() returns remote device nodepointer with
+refcount incremented, we should use of_node_put() on it when done.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 318ba02cd8a8 ("drm/meson: encoder_cvbs: switch to bridge with ATTACH_NO_CONNECTOR")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220601033927.47814-2-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/meson/meson_encoder_cvbs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+index fd8db97ba8ba..8110a6e39320 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
++++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+@@ -238,6 +238,7 @@ int meson_encoder_cvbs_init(struct meson_drm *priv)
+ }
+
+ meson_encoder_cvbs->next_bridge = of_drm_find_bridge(remote);
++ of_node_put(remote);
+ if (!meson_encoder_cvbs->next_bridge) {
+ dev_err(priv->dev, "Failed to find CVBS Connector bridge\n");
+ return -EPROBE_DEFER;
+--
+2.35.1
+
--- /dev/null
+From 977464fae0729f385a0ba0a7afc3a5ec80a048b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 07:39:27 +0400
+Subject: drm/meson: encoder_hdmi: Fix refcount leak in meson_encoder_hdmi_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit d82a5a4aae9d0203234737caed1bf470aa317568 ]
+
+of_graph_get_remote_node() returns remote device nodepointer with
+refcount incremented, we should use of_node_put() on it when done.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: e67f6037ae1b ("drm/meson: split out encoder from meson_dw_hdmi")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220601033927.47814-3-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/meson/meson_encoder_hdmi.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+index de87f02cd388..a7692584487c 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
++++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+@@ -365,7 +365,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+ meson_encoder_hdmi->next_bridge = of_drm_find_bridge(remote);
+ if (!meson_encoder_hdmi->next_bridge) {
+ dev_err(priv->dev, "Failed to find HDMI transceiver bridge\n");
+- return -EPROBE_DEFER;
++ ret = -EPROBE_DEFER;
++ goto err_put_node;
+ }
+
+ /* HDMI Encoder Bridge */
+@@ -383,7 +384,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+ DRM_MODE_ENCODER_TMDS);
+ if (ret) {
+ dev_err(priv->dev, "Failed to init HDMI encoder: %d\n", ret);
+- return ret;
++ goto err_put_node;
+ }
+
+ meson_encoder_hdmi->encoder.possible_crtcs = BIT(0);
+@@ -393,7 +394,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+ if (ret) {
+ dev_err(priv->dev, "Failed to attach bridge: %d\n", ret);
+- return ret;
++ goto err_put_node;
+ }
+
+ /* Initialize & attach Bridge Connector */
+@@ -401,7 +402,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+ &meson_encoder_hdmi->encoder);
+ if (IS_ERR(meson_encoder_hdmi->connector)) {
+ dev_err(priv->dev, "Unable to create HDMI bridge connector\n");
+- return PTR_ERR(meson_encoder_hdmi->connector);
++ ret = PTR_ERR(meson_encoder_hdmi->connector);
++ goto err_put_node;
+ }
+ drm_connector_attach_encoder(meson_encoder_hdmi->connector,
+ &meson_encoder_hdmi->encoder);
+@@ -428,6 +430,7 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+ meson_encoder_hdmi->connector->ycbcr_420_allowed = true;
+
+ pdev = of_find_device_by_node(remote);
++ of_node_put(remote);
+ if (pdev) {
+ struct cec_connector_info conn_info;
+ struct cec_notifier *notifier;
+@@ -446,4 +449,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+ dev_dbg(priv->dev, "HDMI encoder initialized\n");
+
+ return 0;
++
++err_put_node:
++ of_node_put(remote);
++ return ret;
+ }
+--
+2.35.1
+
--- /dev/null
+From 7c0dbf06036c1de12cfdf136940d3affac98ef0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 09:40:51 +0400
+Subject: drm/meson: Fix refcount leak in meson_encoder_hdmi_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 7381076809586528e2a812a709e2758916318a99 ]
+
+of_find_device_by_node() takes reference, we should use put_device()
+to release it when not need anymore.
+Add missing put_device() in error path to avoid refcount
+leak.
+
+Fixes: 0af5e0b41110 ("drm/meson: encoder_hdmi: switch to bridge DRM_BRIDGE_ATTACH_NO_CONNECTOR")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220511054052.51981-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/meson/meson_encoder_hdmi.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+index 5e306de6f485..de87f02cd388 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
++++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+@@ -435,8 +435,10 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+ cec_fill_conn_info_from_drm(&conn_info, meson_encoder_hdmi->connector);
+
+ notifier = cec_notifier_conn_register(&pdev->dev, NULL, &conn_info);
+- if (!notifier)
++ if (!notifier) {
++ put_device(&pdev->dev);
+ return -ENOMEM;
++ }
+
+ meson_encoder_hdmi->cec_notifier = notifier;
+ }
+--
+2.35.1
+
--- /dev/null
+From 8730490e4c52e27b6d09eb173e9c605bf97fea68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 May 2022 11:02:19 +0800
+Subject: drm/mipi-dbi: align max_chunk to 2 in spi_transfer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yunhao Tian <t123yh.xyz@gmail.com>
+
+[ Upstream commit 435c249008cba04ed6a7975e9411f3b934620204 ]
+
+In __spi_validate, there's a validation that no partial transfers
+are accepted (xfer->len % w_size must be zero). When
+max_chunk is not a multiple of bpw (e.g. max_chunk = 65535,
+bpw = 16), the transfer will be rejected.
+
+This patch aligns max_chunk to 2 bytes (the maximum value of bpw is 16),
+so that no partial transfer will occur.
+
+Fixes: d23d4d4dac01 ("drm/tinydrm: Move tinydrm_spi_transfer()")
+
+Signed-off-by: Yunhao Tian <t123yh.xyz@gmail.com>
+Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220510030219.2486687-1-t123yh.xyz@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_mipi_dbi.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
+index 9314f2ead79f..09e4edb5a992 100644
+--- a/drivers/gpu/drm/drm_mipi_dbi.c
++++ b/drivers/gpu/drm/drm_mipi_dbi.c
+@@ -1199,6 +1199,13 @@ int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz,
+ size_t chunk;
+ int ret;
+
++ /* In __spi_validate, there's a validation that no partial transfers
++ * are accepted (xfer->len % w_size must be zero).
++ * Here we align max_chunk to multiple of 2 (16bits),
++ * to prevent transfers from being rejected.
++ */
++ max_chunk = ALIGN_DOWN(max_chunk, 2);
++
+ spi_message_init_with_transfers(&m, &tr, 1);
+
+ while (len) {
+--
+2.35.1
+
--- /dev/null
+From 18236a8c7979f336eccbd222cf798263f5bde303 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 12:47:31 -0700
+Subject: drm/msm: Avoid unclocked GMU register access in 6xx gpu_busy
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit 6694482a70e9536efbf2ac233cbf0c302d6e2dae ]
+
+From testing on sc7180-trogdor devices, reading the GMU registers
+needs the GMU clocks to be enabled. Those clocks get turned on in
+a6xx_gmu_resume(). Confusingly enough, that function is called as a
+result of the runtime_pm of the GPU "struct device", not the GMU
+"struct device". Unfortunately the current a6xx_gpu_busy() grabs a
+reference to the GMU's "struct device".
+
+The fact that we were grabbing the wrong reference was easily seen to
+cause crashes that happen if we change the GPU's pm_runtime usage to
+not use autosuspend. It's also believed to cause some long tail GPU
+crashes even with autosuspend.
+
+We could look at changing it so that we do pm_runtime_get_if_in_use()
+on the GPU's "struct device", but then we run into a different
+problem. pm_runtime_get_if_in_use() will return 0 for the GPU's
+"struct device" the whole time when we're in the "autosuspend
+delay". That is, when we drop the last reference to the GPU but we're
+waiting a period before actually suspending then we'll think the GPU
+is off. One reason that's bad is that if the GPU didn't actually turn
+off then the cycle counter doesn't lose state and that throws off all
+of our calculations.
+
+Let's change the code to keep track of the suspend state of
+devfreq. msm_devfreq_suspend() is always called before we actually
+suspend the GPU and msm_devfreq_resume() after we resume it. This
+means we can use the suspended state to know if we're powered or not.
+
+NOTE: one might wonder when exactly our status function is called when
+devfreq is supposed to be disabled. The stack crawl I captured was:
+ msm_devfreq_get_dev_status
+ devfreq_simple_ondemand_func
+ devfreq_update_target
+ qos_notifier_call
+ qos_max_notifier_call
+ blocking_notifier_call_chain
+ pm_qos_update_target
+ freq_qos_apply
+ apply_constraint
+ __dev_pm_qos_update_request
+ dev_pm_qos_update_request
+ msm_devfreq_idle_work
+
+Fixes: eadf79286a4b ("drm/msm: Check for powered down HW in the devfreq callbacks")
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Rob Clark <robdclark@gmail.com>
+Patchwork: https://patchwork.freedesktop.org/patch/489124/
+Link: https://lore.kernel.org/r/20220610124639.v4.1.Ie846c5352bc307ee4248d7cab998ab3016b85d06@changeid
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 8 ------
+ drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 13 ++++-----
+ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 12 +++------
+ drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 3 ++-
+ drivers/gpu/drm/msm/msm_gpu.h | 11 +++++++-
+ drivers/gpu/drm/msm/msm_gpu_devfreq.c | 39 +++++++++++++++++++++------
+ 6 files changed, 53 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+index 217615e0e850..213f75fc98e8 100644
+--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+@@ -1666,18 +1666,10 @@ static u64 a5xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate)
+ {
+ u64 busy_cycles;
+
+- /* Only read the gpu busy if the hardware is already active */
+- if (pm_runtime_get_if_in_use(&gpu->pdev->dev) == 0) {
+- *out_sample_rate = 1;
+- return 0;
+- }
+-
+ busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO,
+ REG_A5XX_RBBM_PERFCTR_RBBM_0_HI);
+ *out_sample_rate = clk_get_rate(gpu->core_clk);
+
+- pm_runtime_put(&gpu->pdev->dev);
+-
+ return busy_cycles;
+ }
+
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+index 3e325e2a2b1b..1863908694dc 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+@@ -102,7 +102,8 @@ bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
+ A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF));
+ }
+
+-void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
++void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp,
++ bool suspended)
+ {
+ struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+ struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+@@ -127,15 +128,16 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
+
+ /*
+ * This can get called from devfreq while the hardware is idle. Don't
+- * bring up the power if it isn't already active
++ * bring up the power if it isn't already active. All we're doing here
++ * is updating the frequency so that when we come back online we're at
++ * the right rate.
+ */
+- if (pm_runtime_get_if_in_use(gmu->dev) == 0)
++ if (suspended)
+ return;
+
+ if (!gmu->legacy) {
+ a6xx_hfi_set_freq(gmu, perf_index);
+ dev_pm_opp_set_opp(&gpu->pdev->dev, opp);
+- pm_runtime_put(gmu->dev);
+ return;
+ }
+
+@@ -159,7 +161,6 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
+ dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret);
+
+ dev_pm_opp_set_opp(&gpu->pdev->dev, opp);
+- pm_runtime_put(gmu->dev);
+ }
+
+ unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu)
+@@ -895,7 +896,7 @@ static void a6xx_gmu_set_initial_freq(struct msm_gpu *gpu, struct a6xx_gmu *gmu)
+ return;
+
+ gmu->freq = 0; /* so a6xx_gmu_set_freq() doesn't exit early */
+- a6xx_gmu_set_freq(gpu, gpu_opp);
++ a6xx_gmu_set_freq(gpu, gpu_opp, false);
+ dev_pm_opp_put(gpu_opp);
+ }
+
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+index 40fb92becc78..a8a0d798d17f 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+@@ -1658,27 +1658,21 @@ static u64 a6xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate)
+ /* 19.2MHz */
+ *out_sample_rate = 19200000;
+
+- /* Only read the gpu busy if the hardware is already active */
+- if (pm_runtime_get_if_in_use(a6xx_gpu->gmu.dev) == 0)
+- return 0;
+-
+ busy_cycles = gmu_read64(&a6xx_gpu->gmu,
+ REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L,
+ REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H);
+
+-
+- pm_runtime_put(a6xx_gpu->gmu.dev);
+-
+ return busy_cycles;
+ }
+
+-static void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
++static void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp,
++ bool suspended)
+ {
+ struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+ struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+
+ mutex_lock(&a6xx_gpu->gmu.lock);
+- a6xx_gmu_set_freq(gpu, opp);
++ a6xx_gmu_set_freq(gpu, opp, suspended);
+ mutex_unlock(&a6xx_gpu->gmu.lock);
+ }
+
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
+index 86e0a7c3fe6d..ab853f61db63 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
+@@ -77,7 +77,8 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state);
+ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node);
+ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu);
+
+-void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp);
++void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp,
++ bool suspended);
+ unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu);
+
+ void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
+diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
+index 143c56f5185b..a4d3abc4f3e1 100644
+--- a/drivers/gpu/drm/msm/msm_gpu.h
++++ b/drivers/gpu/drm/msm/msm_gpu.h
+@@ -63,11 +63,14 @@ struct msm_gpu_funcs {
+ /* for generation specific debugfs: */
+ void (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor);
+ #endif
++ /* note: gpu_busy() can assume that we have been pm_resumed */
+ u64 (*gpu_busy)(struct msm_gpu *gpu, unsigned long *out_sample_rate);
+ struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu);
+ int (*gpu_state_put)(struct msm_gpu_state *state);
+ unsigned long (*gpu_get_freq)(struct msm_gpu *gpu);
+- void (*gpu_set_freq)(struct msm_gpu *gpu, struct dev_pm_opp *opp);
++ /* note: gpu_set_freq() can assume that we have been pm_resumed */
++ void (*gpu_set_freq)(struct msm_gpu *gpu, struct dev_pm_opp *opp,
++ bool suspended);
+ struct msm_gem_address_space *(*create_address_space)
+ (struct msm_gpu *gpu, struct platform_device *pdev);
+ struct msm_gem_address_space *(*create_private_address_space)
+@@ -91,6 +94,9 @@ struct msm_gpu_devfreq {
+ /** devfreq: devfreq instance */
+ struct devfreq *devfreq;
+
++ /** lock: lock for "suspended", "busy_cycles", and "time" */
++ struct mutex lock;
++
+ /**
+ * idle_constraint:
+ *
+@@ -134,6 +140,9 @@ struct msm_gpu_devfreq {
+ * elapsed
+ */
+ struct msm_hrtimer_work boost_work;
++
++ /** suspended: tracks if we're suspended */
++ bool suspended;
+ };
+
+ struct msm_gpu {
+diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
+index c7dbaa4b1926..01248d340124 100644
+--- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c
++++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
+@@ -20,6 +20,7 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq,
+ u32 flags)
+ {
+ struct msm_gpu *gpu = dev_to_gpu(dev);
++ struct msm_gpu_devfreq *df = &gpu->devfreq;
+ struct dev_pm_opp *opp;
+
+ /*
+@@ -32,10 +33,13 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq,
+
+ trace_msm_gpu_freq_change(dev_pm_opp_get_freq(opp));
+
+- if (gpu->funcs->gpu_set_freq)
+- gpu->funcs->gpu_set_freq(gpu, opp);
+- else
++ if (gpu->funcs->gpu_set_freq) {
++ mutex_lock(&df->lock);
++ gpu->funcs->gpu_set_freq(gpu, opp, df->suspended);
++ mutex_unlock(&df->lock);
++ } else {
+ clk_set_rate(gpu->core_clk, *freq);
++ }
+
+ dev_pm_opp_put(opp);
+
+@@ -58,15 +62,24 @@ static void get_raw_dev_status(struct msm_gpu *gpu,
+ unsigned long sample_rate;
+ ktime_t time;
+
++ mutex_lock(&df->lock);
++
+ status->current_frequency = get_freq(gpu);
+- busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate);
+ time = ktime_get();
+-
+- busy_time = busy_cycles - df->busy_cycles;
+ status->total_time = ktime_us_delta(time, df->time);
++ df->time = time;
+
++ if (df->suspended) {
++ mutex_unlock(&df->lock);
++ status->busy_time = 0;
++ return;
++ }
++
++ busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate);
++ busy_time = busy_cycles - df->busy_cycles;
+ df->busy_cycles = busy_cycles;
+- df->time = time;
++
++ mutex_unlock(&df->lock);
+
+ busy_time *= USEC_PER_SEC;
+ do_div(busy_time, sample_rate);
+@@ -175,6 +188,8 @@ void msm_devfreq_init(struct msm_gpu *gpu)
+ if (!gpu->funcs->gpu_busy)
+ return;
+
++ mutex_init(&df->lock);
++
+ dev_pm_qos_add_request(&gpu->pdev->dev, &df->idle_freq,
+ DEV_PM_QOS_MAX_FREQUENCY,
+ PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
+@@ -244,12 +259,16 @@ void msm_devfreq_cleanup(struct msm_gpu *gpu)
+ void msm_devfreq_resume(struct msm_gpu *gpu)
+ {
+ struct msm_gpu_devfreq *df = &gpu->devfreq;
++ unsigned long sample_rate;
+
+ if (!has_devfreq(gpu))
+ return;
+
+- df->busy_cycles = 0;
++ mutex_lock(&df->lock);
++ df->busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate);
+ df->time = ktime_get();
++ df->suspended = false;
++ mutex_unlock(&df->lock);
+
+ devfreq_resume_device(df->devfreq);
+ }
+@@ -261,6 +280,10 @@ void msm_devfreq_suspend(struct msm_gpu *gpu)
+ if (!has_devfreq(gpu))
+ return;
+
++ mutex_lock(&df->lock);
++ df->suspended = true;
++ mutex_unlock(&df->lock);
++
+ devfreq_suspend_device(df->devfreq);
+
+ cancel_idle_work(df);
+--
+2.35.1
+
--- /dev/null
+From 57c6a07fe8083f5f31b8accf04c078b684f0007c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 14:20:00 -0700
+Subject: drm/msm/dpu: Fix for non-visible planes
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit cb77085b1f0a86ef9dfba86b5f3ed6c3340c2ea3 ]
+
+Fixes `kms_cursor_crc --run-subtest cursor-offscreen`.. when the cursor
+moves offscreen the plane becomes non-visible, so we need to skip over
+it in crtc atomic test and mixer setup.
+
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/492819/
+Link: https://lore.kernel.org/r/20220707212003.1710163-1-robdclark@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+index 16ba9f9b9a78..32715399a7c1 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+@@ -361,6 +361,9 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
+ if (!state)
+ continue;
+
++ if (!state->visible)
++ continue;
++
+ pstate = to_dpu_plane_state(state);
+ fb = state->fb;
+
+@@ -1125,6 +1128,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
+ if (cnt >= DPU_STAGE_MAX * 4)
+ continue;
+
++ if (!pstate->visible)
++ continue;
++
+ pstates[cnt].dpu_pstate = dpu_pstate;
+ pstates[cnt].drm_pstate = pstate;
+ pstates[cnt].stage = pstate->normalized_zpos;
+--
+2.35.1
+
--- /dev/null
+From 63566e5f373e76279e51d39eeed2756844a0b3d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 15:23:43 +0300
+Subject: drm/msm/hdmi: enable core-vcc/core-vdda-supply for 8996 platform
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 1f88301794595ff4c28a1f1befe690e8dbac72a2 ]
+
+DB820c makes use of core-vcc-supply and core-vdda-supply, however the
+driver code doesn't support these regulators. Enable them for HDMI on
+8996 platform.
+
+Fixes: 0afbe59edd3f ("drm/msm/hdmi: Add basic HDMI support for msm8996")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Patchwork: https://patchwork.freedesktop.org/patch/488857/
+Link: https://lore.kernel.org/r/20220609122350.3157529-8-dmitry.baryshkov@linaro.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/hdmi/hdmi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
+index 4ce0b4c41e49..4ba1a881b504 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
++++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
+@@ -403,7 +403,7 @@ static struct hdmi_platform_config hdmi_tx_8994_config = {
+ };
+
+ static struct hdmi_platform_config hdmi_tx_8996_config = {
+- HDMI_CFG(pwr_reg, none),
++ HDMI_CFG(pwr_reg, 8x74),
+ HDMI_CFG(hpd_reg, none),
+ HDMI_CFG(pwr_clk, 8x74),
+ HDMI_CFG(hpd_clk, 8x74),
+--
+2.35.1
+
--- /dev/null
+From 045867ee7d711b70d59811f535fcc900902937cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 14:31:48 +0300
+Subject: drm/msm/hdmi: fill the pwr_regs bulk regulators
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit a18a44e9262d5c7f7fbccbc9458df64d69185d41 ]
+
+Conversion to use bulk regulator API omitted filling the pwr_regs with
+proper regulator IDs. This was left unnoticed, since none of my testing
+platforms has used the pwr_regs. Fix this by propagating regulator ids
+properly.
+
+Fixes: 31b3b1f5e352 ("drm/msm/hdmi: use bulk regulator API")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Patchwork: https://patchwork.freedesktop.org/patch/488847/
+Link: https://lore.kernel.org/r/20220609113148.3149194-1-dmitry.baryshkov@linaro.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/hdmi/hdmi.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
+index f6229262dcb0..4ce0b4c41e49 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
++++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
+@@ -180,6 +180,9 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev)
+ goto fail;
+ }
+
++ for (i = 0; i < config->pwr_reg_cnt; i++)
++ hdmi->pwr_regs[i].supply = config->pwr_reg_names[i];
++
+ ret = devm_regulator_bulk_get(&pdev->dev, config->pwr_reg_cnt, hdmi->pwr_regs);
+ if (ret) {
+ DRM_DEV_ERROR(&pdev->dev, "failed to get pwr regulator: %d\n", ret);
+--
+2.35.1
+
--- /dev/null
+From 2d5528afb1e30b6f754c9f89fabc01c3b32b9403 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 09:20:37 -0700
+Subject: drm/msm/mdp5: Fix global state lock backoff
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit 92ef86ab513593c6329d04146e61f9a670e72fc5 ]
+
+We need to grab the lock after the early return for !hwpipe case.
+Otherwise, we could have hit contention yet still returned 0.
+
+Fixes an issue that the new CONFIG_DRM_DEBUG_MODESET_LOCK stuff flagged
+in CI:
+
+ WARNING: CPU: 0 PID: 282 at drivers/gpu/drm/drm_modeset_lock.c:296 drm_modeset_lock+0xf8/0x154
+ Modules linked in:
+ CPU: 0 PID: 282 Comm: kms_cursor_lega Tainted: G W 5.19.0-rc2-15930-g875cc8bc536a #1
+ Hardware name: Qualcomm Technologies, Inc. DB820c (DT)
+ pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+ pc : drm_modeset_lock+0xf8/0x154
+ lr : drm_atomic_get_private_obj_state+0x84/0x170
+ sp : ffff80000cfab6a0
+ x29: ffff80000cfab6a0 x28: 0000000000000000 x27: ffff000083bc4d00
+ x26: 0000000000000038 x25: 0000000000000000 x24: ffff80000957ca58
+ x23: 0000000000000000 x22: ffff000081ace080 x21: 0000000000000001
+ x20: ffff000081acec18 x19: ffff80000cfabb80 x18: 0000000000000038
+ x17: 0000000000000000 x16: 0000000000000000 x15: fffffffffffea0d0
+ x14: 0000000000000000 x13: 284e4f5f4e524157 x12: 5f534b434f4c5f47
+ x11: ffff80000a386aa8 x10: 0000000000000029 x9 : ffff80000cfab610
+ x8 : 0000000000000029 x7 : 0000000000000014 x6 : 0000000000000000
+ x5 : 0000000000000001 x4 : ffff8000081ad904 x3 : 0000000000000029
+ x2 : ffff0000801db4c0 x1 : ffff80000cfabb80 x0 : ffff000081aceb58
+ Call trace:
+ drm_modeset_lock+0xf8/0x154
+ drm_atomic_get_private_obj_state+0x84/0x170
+ mdp5_get_global_state+0x54/0x6c
+ mdp5_pipe_release+0x2c/0xd4
+ mdp5_plane_atomic_check+0x2ec/0x414
+ drm_atomic_helper_check_planes+0xd8/0x210
+ drm_atomic_helper_check+0x54/0xb0
+ ...
+ ---[ end trace 0000000000000000 ]---
+ drm_modeset_lock attempting to lock a contended lock without backoff:
+ drm_modeset_lock+0x148/0x154
+ mdp5_get_global_state+0x30/0x6c
+ mdp5_pipe_release+0x2c/0xd4
+ mdp5_plane_atomic_check+0x290/0x414
+ drm_atomic_helper_check_planes+0xd8/0x210
+ drm_atomic_helper_check+0x54/0xb0
+ drm_atomic_check_only+0x4b0/0x8f4
+ drm_atomic_commit+0x68/0xe0
+
+Fixes: d59be579fa93 ("drm/msm/mdp5: Return error code in mdp5_pipe_release when deadlock is detected")
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/492701/
+Link: https://lore.kernel.org/r/20220707162040.1594855-1-robdclark@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
+index a4f5cb90f3e8..e4b8a789835a 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c
+@@ -123,12 +123,13 @@ int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe)
+ {
+ struct msm_drm_private *priv = s->dev->dev_private;
+ struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+- struct mdp5_global_state *state = mdp5_get_global_state(s);
++ struct mdp5_global_state *state;
+ struct mdp5_hw_pipe_state *new_state;
+
+ if (!hwpipe)
+ return 0;
+
++ state = mdp5_get_global_state(s);
+ if (IS_ERR(state))
+ return PTR_ERR(state);
+
+--
+2.35.1
+
--- /dev/null
+From e8c94f1618e7792426eb4c178d02c23529ba91c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 10:45:51 +0800
+Subject: drm/panel: Fix build error when CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=y
+ && CONFIG_DRM_DISPLAY_HELPER=m
+
+From: Gao Chao <gaochao49@huawei.com>
+
+[ Upstream commit a67664860f7833015a683ea295f7c79ac2901332 ]
+
+If CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=y && CONFIG_DRM_DISPLAY_HELPER=m,
+bulding fails:
+
+drivers/gpu/drm/panel/panel-samsung-atna33xc20.o: In function `atana33xc20_probe':
+panel-samsung-atna33xc20.c:(.text+0x744): undefined reference to
+ `drm_panel_dp_aux_backlight'
+make: *** [vmlinux] Error 1
+
+Let CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20 select DRM_DISPLAY_DP_HELPER and
+CONFIG_DRM_DISPLAY_HELPER to fix this error.
+
+Fixes: 32ce3b320343 ("drm/panel: atna33xc20: Introduce the Samsung ATNA33XC20 panel")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Gao Chao <gaochao49@huawei.com>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220524024551.539-1-gaochao49@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panel/Kconfig | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
+index ddf5f38e8731..abc5271af4eb 100644
+--- a/drivers/gpu/drm/panel/Kconfig
++++ b/drivers/gpu/drm/panel/Kconfig
+@@ -428,6 +428,8 @@ config DRM_PANEL_SAMSUNG_ATNA33XC20
+ depends on OF
+ depends on BACKLIGHT_CLASS_DEVICE
+ depends on PM
++ select DRM_DISPLAY_DP_HELPER
++ select DRM_DISPLAY_HELPER
+ select DRM_DP_AUX_BUS
+ help
+ DRM panel driver for the Samsung ATNA33XC20 panel. This panel can't
+--
+2.35.1
+
--- /dev/null
+From 31d996bd2a361b6010adc16f3ed79871fc8c4a89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 22:01:44 +0200
+Subject: drm/radeon: avoid bogus "vram limit (0) must be a power of 2" warning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mateusz Jończyk <mat.jonczyk@o2.pl>
+
+[ Upstream commit 9da2902609f7519c48eda84f953f72fee53f2b71 ]
+
+I was getting the following message on boot on Linux 5.19-rc5:
+ radeon 0000:01:05.0: vram limit (0) must be a power of 2
+(I didn't use any radeon.vramlimit commandline parameter).
+
+This is caused by
+commit 8c2d34eb53b9 ("drm/radeon: use kernel is_power_of_2 rather than local version")
+which removed radeon_check_pot_argument() and converted its users to
+is_power_of_2(). The two functions differ in its handling of 0, which is
+the default value of radeon_vram_limit: radeon_check_pot_argument()
+"incorrectly" considered it a power of 2, while is_power_of_2() does not.
+
+An appropriate conditional silences the warning message.
+
+It is not necessary to add a similar test to other callers of
+is_power_of_2() in radeon_device.c. The matching commit in amdgpu:
+commit 761175078466 ("drm/amdgpu: use kernel is_power_of_2 rather than local version")
+is unaffected by this bug.
+
+Tested on Radeon HD 3200.
+
+Not ccing stable, this is not serious enough.
+
+Fixes: 8c2d34eb53b9 ("drm/radeon: use kernel is_power_of_2 rather than local version")
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: Christian König <christian.koenig@amd.com>
+Cc: "Pan, Xinhui" <Xinhui.Pan@amd.com>
+Cc: David Airlie <airlied@linux.ie>
+Cc: Daniel Vetter <daniel@ffwll.ch>
+Cc: Jonathan Gray <jsg@jsg.id.au>
+Signed-off-by: Mateusz Jończyk <mat.jonczyk@o2.pl>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/radeon_device.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
+index 15692cb241fc..429644d5ddc6 100644
+--- a/drivers/gpu/drm/radeon/radeon_device.c
++++ b/drivers/gpu/drm/radeon/radeon_device.c
+@@ -1113,7 +1113,7 @@ static int radeon_gart_size_auto(enum radeon_family family)
+ static void radeon_check_arguments(struct radeon_device *rdev)
+ {
+ /* vramlimit must be a power of two */
+- if (!is_power_of_2(radeon_vram_limit)) {
++ if (radeon_vram_limit != 0 && !is_power_of_2(radeon_vram_limit)) {
+ dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n",
+ radeon_vram_limit);
+ radeon_vram_limit = 0;
+--
+2.35.1
+
--- /dev/null
+From 5fbe8804b44e4e837c2e3e5719b28e8d9b5aab20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 12:02:08 -0400
+Subject: drm/radeon: fix incorrrect SPDX-License-Identifiers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 1f43b8903f3aae4a26a603c36f6d5dd25d6edb51 ]
+
+radeon is MIT. This were incorrectly changed in
+commit b24413180f56 ("License cleanup: add SPDX GPL-2.0 license identifier to files with no license")
+and
+commit d198b34f3855 (".gitignore: add SPDX License Identifier")
+and:
+commit ec8f24b7faaf ("treewide: Add SPDX license identifier - Makefile/Kconfig")
+
+Fixes: d198b34f3855 (".gitignore: add SPDX License Identifier")
+Fixes: ec8f24b7faaf ("treewide: Add SPDX license identifier - Makefile/Kconfig")
+Fixes: b24413180f56 ("License cleanup: add SPDX GPL-2.0 license identifier to files with no license")
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2053
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/.gitignore | 2 +-
+ drivers/gpu/drm/radeon/Kconfig | 2 +-
+ drivers/gpu/drm/radeon/Makefile | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/.gitignore b/drivers/gpu/drm/radeon/.gitignore
+index 9c1a94153983..d8777383a64a 100644
+--- a/drivers/gpu/drm/radeon/.gitignore
++++ b/drivers/gpu/drm/radeon/.gitignore
+@@ -1,4 +1,4 @@
+-# SPDX-License-Identifier: GPL-2.0-only
++# SPDX-License-Identifier: MIT
+ mkregtable
+ *_reg_safe.h
+
+diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig
+index 6f60f4840cc5..52819e7f1fca 100644
+--- a/drivers/gpu/drm/radeon/Kconfig
++++ b/drivers/gpu/drm/radeon/Kconfig
+@@ -1,4 +1,4 @@
+-# SPDX-License-Identifier: GPL-2.0-only
++# SPDX-License-Identifier: MIT
+ config DRM_RADEON_USERPTR
+ bool "Always enable userptr support"
+ depends on DRM_RADEON
+diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
+index 11c97edde54d..3d502f1bbfcb 100644
+--- a/drivers/gpu/drm/radeon/Makefile
++++ b/drivers/gpu/drm/radeon/Makefile
+@@ -1,4 +1,4 @@
+-# SPDX-License-Identifier: GPL-2.0
++# SPDX-License-Identifier: MIT
+ #
+ # Makefile for the drm device driver. This driver provides support for the
+ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
+--
+2.35.1
+
--- /dev/null
+From 54573de5228a54fdf3a8fd54416023e875a48c44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 16:50:54 +0300
+Subject: drm/radeon: fix potential buffer overflow in
+ ni_set_mc_special_registers()
+
+From: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+
+[ Upstream commit 136f614931a2bb73616b292cf542da3a18daefd5 ]
+
+The last case label can write two buffers 'mc_reg_address[j]' and
+'mc_data[j]' with 'j' offset equal to SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE
+since there are no checks for this value in both case labels after the
+last 'j++'.
+
+Instead of changing '>' to '>=' there, add the bounds check at the start
+of the second 'case' (the first one already has it).
+
+Also, remove redundant last checks for 'j' index bigger than array size.
+The expression is always false. Moreover, before or after the patch
+'table->last' can be equal to SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE and it
+seems it can be a valid value.
+
+Detected using the static analysis tool - Svace.
+Fixes: 69e0b57a91ad ("drm/radeon/kms: add dpm support for cayman (v5)")
+Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/ni_dpm.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
+index 769f666335ac..672d2239293e 100644
+--- a/drivers/gpu/drm/radeon/ni_dpm.c
++++ b/drivers/gpu/drm/radeon/ni_dpm.c
+@@ -2741,10 +2741,10 @@ static int ni_set_mc_special_registers(struct radeon_device *rdev,
+ table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
+ }
+ j++;
+- if (j > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
+- return -EINVAL;
+ break;
+ case MC_SEQ_RESERVE_M >> 2:
++ if (j >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
++ return -EINVAL;
+ temp_reg = RREG32(MC_PMG_CMD_MRS1);
+ table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2;
+ table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
+@@ -2753,8 +2753,6 @@ static int ni_set_mc_special_registers(struct radeon_device *rdev,
+ (temp_reg & 0xffff0000) |
+ (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
+ j++;
+- if (j > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
+- return -EINVAL;
+ break;
+ default:
+ break;
+--
+2.35.1
+
--- /dev/null
+From 6f9349e09ed9be87a8076cb7e87e0b2923d4ea22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jun 2022 19:08:05 +0200
+Subject: drm/rockchip: Fix an error handling path rockchip_dp_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 5074376822fe99fa4ce344b851c5016d00c0444f ]
+
+Should component_add() fail, we should call analogix_dp_remove() in the
+error handling path, as already done in the remove function.
+
+Fixes: 152cce0006ab ("drm/bridge: analogix_dp: Split bind() into probe() and real bind()")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/b719d9061bb97eb85145fbd3c5e63f4549f2e13e.1655572071.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+index c82901d9a9cc..8a9bb618f872 100644
+--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
++++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+@@ -398,7 +398,15 @@ static int rockchip_dp_probe(struct platform_device *pdev)
+ if (IS_ERR(dp->adp))
+ return PTR_ERR(dp->adp);
+
+- return component_add(dev, &rockchip_dp_component_ops);
++ ret = component_add(dev, &rockchip_dp_component_ops);
++ if (ret)
++ goto err_dp_remove;
++
++ return 0;
++
++err_dp_remove:
++ analogix_dp_remove(dp->adp);
++ return ret;
+ }
+
+ static int rockchip_dp_remove(struct platform_device *pdev)
+--
+2.35.1
+
--- /dev/null
+From 409d95d04579ecfcbc275038252c37d882733533 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 17:26:52 -0700
+Subject: drm/rockchip: vop: Don't crash for invalid duplicate_state()
+
+From: Brian Norris <briannorris@chromium.org>
+
+[ Upstream commit 1449110b0dade8b638d2c17ab7c5b0ff696bfccb ]
+
+It's possible for users to try to duplicate the CRTC state even when the
+state doesn't exist. drm_atomic_helper_crtc_duplicate_state() (and other
+users of __drm_atomic_helper_crtc_duplicate_state()) already guard this
+with a WARN_ON() instead of crashing, so let's do that here too.
+
+Fixes: 4e257d9eee23 ("drm/rockchip: get rid of rockchip_drm_crtc_mode_config")
+Signed-off-by: Brian Norris <briannorris@chromium.org>
+Reviewed-by: Sean Paul <seanpaul@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220617172623.1.I62db228170b1559ada60b8d3e1637e1688424926@changeid
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+index d53037531f40..26e24f62f75f 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+@@ -1552,6 +1552,9 @@ static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)
+ {
+ struct rockchip_crtc_state *rockchip_state;
+
++ if (WARN_ON(!crtc->state))
++ return NULL;
++
+ rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL);
+ if (!rockchip_state)
+ return NULL;
+--
+2.35.1
+
--- /dev/null
+From 6c7504aed4212fa42da9cd6cc39c53403fad6358 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 11:16:02 +0200
+Subject: drm/st7735r: Fix module autoloading for Okaya RH128128T
+
+From: Javier Martinez Canillas <javierm@redhat.com>
+
+[ Upstream commit 9ad6f181ad9a19a26bda73a7b199df44ccfcdaba ]
+
+The SPI core always reports a "MODALIAS=spi:<foo>", even if the device was
+registered via OF. This means that the st7735r.ko module won't autoload if
+a DT has a node with a compatible "okaya,rh128128t" string.
+
+In that case, kmod expects a "MODALIAS=of:N*T*Cokaya,rh128128t" uevent but
+instead will get a "MODALIAS=spi:rh128128t", which is not present in the
+list of aliases:
+
+ $ modinfo drivers/gpu/drm/tiny/st7735r.ko | grep alias
+ alias: of:N*T*Cokaya,rh128128tC*
+ alias: of:N*T*Cokaya,rh128128t
+ alias: of:N*T*Cjianda,jd-t18003-t01C*
+ alias: of:N*T*Cjianda,jd-t18003-t01
+ alias: spi:jd-t18003-t01
+
+To workaround this issue, add in the SPI table an entry for that device.
+
+Fixes: d1d511d516f7 ("drm: tiny: st7735r: Add support for Okaya RH128128T")
+Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Acked-by: David Lechner <david@lechnology.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220520091602.179078-1-javierm@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tiny/st7735r.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c
+index 29d618093e94..e0f02d367d88 100644
+--- a/drivers/gpu/drm/tiny/st7735r.c
++++ b/drivers/gpu/drm/tiny/st7735r.c
+@@ -174,6 +174,7 @@ MODULE_DEVICE_TABLE(of, st7735r_of_match);
+
+ static const struct spi_device_id st7735r_id[] = {
+ { "jd-t18003-t01", (uintptr_t)&jd_t18003_t01_cfg },
++ { "rh128128t", (uintptr_t)&rh128128t_cfg },
+ { },
+ };
+ MODULE_DEVICE_TABLE(spi, st7735r_id);
+--
+2.35.1
+
--- /dev/null
+From f25a41517e0baf35f7c15af0fa8cc9d8f75dc115 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:43 +0200
+Subject: drm/vc4: dsi: Add correct stop condition to vc4_dsi_encoder_disable
+ iteration
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 7bcb9c8d0bc9f3cab8ac2634b056c2e6b63945ca ]
+
+vc4_dsi_encoder_disable is partially an open coded version of
+drm_bridge_chain_disable, but it missed a termination condition
+in the loop for ->disable which meant that no post_disable
+calls were made.
+
+Add in the termination clause.
+
+Fixes: 033bfe7538a1 ("drm/vc4: dsi: Fix bridge chain handling")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-17-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_dsi.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
+index 333ea96fcde4..b7b2c76770dc 100644
+--- a/drivers/gpu/drm/vc4/vc4_dsi.c
++++ b/drivers/gpu/drm/vc4/vc4_dsi.c
+@@ -803,6 +803,9 @@ static void vc4_dsi_encoder_disable(struct drm_encoder *encoder)
+ list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
+ if (iter->funcs->disable)
+ iter->funcs->disable(iter);
++
++ if (iter == dsi->bridge)
++ break;
+ }
+
+ vc4_dsi_ulps(dsi, true);
+--
+2.35.1
+
--- /dev/null
+From 2aea9a9e1ed9387a9a4cd739ef5df87dd278dc40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:39 +0200
+Subject: drm/vc4: dsi: Correct DSI divider calculations
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 3b45eee87da171caa28f61240ddb5c21170cda53 ]
+
+The divider calculations tried to find the divider just faster than the
+clock requested. However if it required a divider of 7 then the for loop
+aborted without handling the "error" case, and could end up with a clock
+lower than requested.
+
+The integer divider from parent PLL to DSI clock is also capable of
+going up to /255, not just /7 that the driver was trying. This allows
+for slower link frequencies on the DSI bus where the resolution permits.
+
+Correct the loop so that we always have a clock greater than requested,
+and covering the whole range of dividers.
+
+Fixes: 86c1b9eff3f2 ("drm/vc4: Adjust modes in DSI to work around the integer PLL divider.")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-13-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_dsi.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
+index e82ee94cafc7..81a6c4e9576d 100644
+--- a/drivers/gpu/drm/vc4/vc4_dsi.c
++++ b/drivers/gpu/drm/vc4/vc4_dsi.c
+@@ -805,11 +805,9 @@ static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
+ /* Find what divider gets us a faster clock than the requested
+ * pixel clock.
+ */
+- for (divider = 1; divider < 8; divider++) {
+- if (parent_rate / divider < pll_clock) {
+- divider--;
++ for (divider = 1; divider < 255; divider++) {
++ if (parent_rate / (divider + 1) < pll_clock)
+ break;
+- }
+ }
+
+ /* Now that we've picked a PLL divider, calculate back to its
+--
+2.35.1
+
--- /dev/null
+From a17e92758bd6d30a2772c80b9cdd520c0358ec17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:40 +0200
+Subject: drm/vc4: dsi: Correct pixel order for DSI0
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit edfe84ae0df16be1251b5a8e840d95f1f3827500 ]
+
+For slightly unknown reasons, dsi0 takes a different pixel format
+to dsi1, and that has to be set in the pixel valve.
+
+Amend the setup accordingly.
+
+Fixes: a86773d120d7 ("drm/vc4: Add support for feeding DSI encoders from the pixel valve.")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-14-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
+index 477b3c5ad089..0a5f58cdd781 100644
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -317,7 +317,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
+ u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
+ bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
+ vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
+- u32 format = is_dsi ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
++ bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1;
++ u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
+ u8 ppc = pv_data->pixels_per_clock;
+ bool debug_dump_regs = false;
+
+--
+2.35.1
+
--- /dev/null
+From 7e51b5910eca8d36ef806e397e26d2702b9035d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:42 +0200
+Subject: drm/vc4: dsi: Fix dsi0 interrupt support
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit bc5b815e06f90cccdb6461aba1e49fdc2f3c8cd1 ]
+
+DSI0 seemingly had very little or no testing as a load of
+the register mappings were incorrect/missing, so host
+transfers always timed out due to enabling/checking incorrect
+bits in the interrupt enable and status registers.
+
+Fixes: 4078f5757144 ("drm/vc4: Add DSI driver")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-16-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_dsi.c | 111 ++++++++++++++++++++++++++--------
+ 1 file changed, 85 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
+index 97a258c934af..333ea96fcde4 100644
+--- a/drivers/gpu/drm/vc4/vc4_dsi.c
++++ b/drivers/gpu/drm/vc4/vc4_dsi.c
+@@ -181,8 +181,50 @@
+
+ #define DSI0_TXPKT_PIX_FIFO 0x20 /* AKA PIX_FIFO */
+
+-#define DSI0_INT_STAT 0x24
+-#define DSI0_INT_EN 0x28
++#define DSI0_INT_STAT 0x24
++#define DSI0_INT_EN 0x28
++# define DSI0_INT_FIFO_ERR BIT(25)
++# define DSI0_INT_CMDC_DONE_MASK VC4_MASK(24, 23)
++# define DSI0_INT_CMDC_DONE_SHIFT 23
++# define DSI0_INT_CMDC_DONE_NO_REPEAT 1
++# define DSI0_INT_CMDC_DONE_REPEAT 3
++# define DSI0_INT_PHY_DIR_RTF BIT(22)
++# define DSI0_INT_PHY_D1_ULPS BIT(21)
++# define DSI0_INT_PHY_D1_STOP BIT(20)
++# define DSI0_INT_PHY_RXLPDT BIT(19)
++# define DSI0_INT_PHY_RXTRIG BIT(18)
++# define DSI0_INT_PHY_D0_ULPS BIT(17)
++# define DSI0_INT_PHY_D0_LPDT BIT(16)
++# define DSI0_INT_PHY_D0_FTR BIT(15)
++# define DSI0_INT_PHY_D0_STOP BIT(14)
++/* Signaled when the clock lane enters the given state. */
++# define DSI0_INT_PHY_CLK_ULPS BIT(13)
++# define DSI0_INT_PHY_CLK_HS BIT(12)
++# define DSI0_INT_PHY_CLK_FTR BIT(11)
++/* Signaled on timeouts */
++# define DSI0_INT_PR_TO BIT(10)
++# define DSI0_INT_TA_TO BIT(9)
++# define DSI0_INT_LPRX_TO BIT(8)
++# define DSI0_INT_HSTX_TO BIT(7)
++/* Contention on a line when trying to drive the line low */
++# define DSI0_INT_ERR_CONT_LP1 BIT(6)
++# define DSI0_INT_ERR_CONT_LP0 BIT(5)
++/* Control error: incorrect line state sequence on data lane 0. */
++# define DSI0_INT_ERR_CONTROL BIT(4)
++# define DSI0_INT_ERR_SYNC_ESC BIT(3)
++# define DSI0_INT_RX2_PKT BIT(2)
++# define DSI0_INT_RX1_PKT BIT(1)
++# define DSI0_INT_CMD_PKT BIT(0)
++
++#define DSI0_INTERRUPTS_ALWAYS_ENABLED (DSI0_INT_ERR_SYNC_ESC | \
++ DSI0_INT_ERR_CONTROL | \
++ DSI0_INT_ERR_CONT_LP0 | \
++ DSI0_INT_ERR_CONT_LP1 | \
++ DSI0_INT_HSTX_TO | \
++ DSI0_INT_LPRX_TO | \
++ DSI0_INT_TA_TO | \
++ DSI0_INT_PR_TO)
++
+ # define DSI1_INT_PHY_D3_ULPS BIT(30)
+ # define DSI1_INT_PHY_D3_STOP BIT(29)
+ # define DSI1_INT_PHY_D2_ULPS BIT(28)
+@@ -892,6 +934,9 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
+
+ DSI_PORT_WRITE(PHY_AFEC0, afec0);
+
++ /* AFEC reset hold time */
++ mdelay(1);
++
+ DSI_PORT_WRITE(PHY_AFEC1,
+ VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_DLANE1) |
+ VC4_SET_FIELD(6, DSI0_PHY_AFEC1_IDR_DLANE0) |
+@@ -1058,12 +1103,9 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
+ DSI_PORT_WRITE(CTRL, DSI_PORT_READ(CTRL) | DSI1_CTRL_EN);
+
+ /* Bring AFE out of reset. */
+- if (dsi->variant->port == 0) {
+- } else {
+- DSI_PORT_WRITE(PHY_AFEC0,
+- DSI_PORT_READ(PHY_AFEC0) &
+- ~DSI1_PHY_AFEC0_RESET);
+- }
++ DSI_PORT_WRITE(PHY_AFEC0,
++ DSI_PORT_READ(PHY_AFEC0) &
++ ~DSI_PORT_BIT(PHY_AFEC0_RESET));
+
+ vc4_dsi_ulps(dsi, false);
+
+@@ -1182,13 +1224,28 @@ static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host,
+ /* Enable the appropriate interrupt for the transfer completion. */
+ dsi->xfer_result = 0;
+ reinit_completion(&dsi->xfer_completion);
+- DSI_PORT_WRITE(INT_STAT, DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF);
+- if (msg->rx_len) {
+- DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED |
+- DSI1_INT_PHY_DIR_RTF));
++ if (dsi->variant->port == 0) {
++ DSI_PORT_WRITE(INT_STAT,
++ DSI0_INT_CMDC_DONE_MASK | DSI1_INT_PHY_DIR_RTF);
++ if (msg->rx_len) {
++ DSI_PORT_WRITE(INT_EN, (DSI0_INTERRUPTS_ALWAYS_ENABLED |
++ DSI0_INT_PHY_DIR_RTF));
++ } else {
++ DSI_PORT_WRITE(INT_EN,
++ (DSI0_INTERRUPTS_ALWAYS_ENABLED |
++ VC4_SET_FIELD(DSI0_INT_CMDC_DONE_NO_REPEAT,
++ DSI0_INT_CMDC_DONE)));
++ }
+ } else {
+- DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED |
+- DSI1_INT_TXPKT1_DONE));
++ DSI_PORT_WRITE(INT_STAT,
++ DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF);
++ if (msg->rx_len) {
++ DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED |
++ DSI1_INT_PHY_DIR_RTF));
++ } else {
++ DSI_PORT_WRITE(INT_EN, (DSI1_INTERRUPTS_ALWAYS_ENABLED |
++ DSI1_INT_TXPKT1_DONE));
++ }
+ }
+
+ /* Send the packet. */
+@@ -1205,7 +1262,7 @@ static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host,
+ ret = dsi->xfer_result;
+ }
+
+- DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED);
++ DSI_PORT_WRITE(INT_EN, DSI_PORT_BIT(INTERRUPTS_ALWAYS_ENABLED));
+
+ if (ret)
+ goto reset_fifo_and_return;
+@@ -1251,7 +1308,7 @@ static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host,
+ DSI_PORT_BIT(CTRL_RESET_FIFOS));
+
+ DSI_PORT_WRITE(TXPKT1C, 0);
+- DSI_PORT_WRITE(INT_EN, DSI1_INTERRUPTS_ALWAYS_ENABLED);
++ DSI_PORT_WRITE(INT_EN, DSI_PORT_BIT(INTERRUPTS_ALWAYS_ENABLED));
+ return ret;
+ }
+
+@@ -1388,26 +1445,28 @@ static irqreturn_t vc4_dsi_irq_handler(int irq, void *data)
+ DSI_PORT_WRITE(INT_STAT, stat);
+
+ dsi_handle_error(dsi, &ret, stat,
+- DSI1_INT_ERR_SYNC_ESC, "LPDT sync");
++ DSI_PORT_BIT(INT_ERR_SYNC_ESC), "LPDT sync");
+ dsi_handle_error(dsi, &ret, stat,
+- DSI1_INT_ERR_CONTROL, "data lane 0 sequence");
++ DSI_PORT_BIT(INT_ERR_CONTROL), "data lane 0 sequence");
+ dsi_handle_error(dsi, &ret, stat,
+- DSI1_INT_ERR_CONT_LP0, "LP0 contention");
++ DSI_PORT_BIT(INT_ERR_CONT_LP0), "LP0 contention");
+ dsi_handle_error(dsi, &ret, stat,
+- DSI1_INT_ERR_CONT_LP1, "LP1 contention");
++ DSI_PORT_BIT(INT_ERR_CONT_LP1), "LP1 contention");
+ dsi_handle_error(dsi, &ret, stat,
+- DSI1_INT_HSTX_TO, "HSTX timeout");
++ DSI_PORT_BIT(INT_HSTX_TO), "HSTX timeout");
+ dsi_handle_error(dsi, &ret, stat,
+- DSI1_INT_LPRX_TO, "LPRX timeout");
++ DSI_PORT_BIT(INT_LPRX_TO), "LPRX timeout");
+ dsi_handle_error(dsi, &ret, stat,
+- DSI1_INT_TA_TO, "turnaround timeout");
++ DSI_PORT_BIT(INT_TA_TO), "turnaround timeout");
+ dsi_handle_error(dsi, &ret, stat,
+- DSI1_INT_PR_TO, "peripheral reset timeout");
++ DSI_PORT_BIT(INT_PR_TO), "peripheral reset timeout");
+
+- if (stat & (DSI1_INT_TXPKT1_DONE | DSI1_INT_PHY_DIR_RTF)) {
++ if (stat & ((dsi->variant->port ? DSI1_INT_TXPKT1_DONE :
++ DSI0_INT_CMDC_DONE_MASK) |
++ DSI_PORT_BIT(INT_PHY_DIR_RTF))) {
+ complete(&dsi->xfer_completion);
+ ret = IRQ_HANDLED;
+- } else if (stat & DSI1_INT_HSTX_TO) {
++ } else if (stat & DSI_PORT_BIT(INT_HSTX_TO)) {
+ complete(&dsi->xfer_completion);
+ dsi->xfer_result = -ETIMEDOUT;
+ ret = IRQ_HANDLED;
+--
+2.35.1
+
--- /dev/null
+From adce56d4809d2e7c2e00a5f0e52b870202c47b2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:41 +0200
+Subject: drm/vc4: dsi: Register dsi0 as the correct vc4 encoder type
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 4d9273c978d4c1af15d7874c10c732ec83d444d0 ]
+
+vc4_dsi was registering both dsi0 and dsi1 as VC4_ENCODER_TYPE_DSI1
+which seemed to work OK for a single DSI display, but fails
+if there are two DSI displays connected.
+
+Update to register the correct type.
+
+Fixes: 4078f5757144 ("drm/vc4: Add DSI driver")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-15-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_dsi.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
+index 81a6c4e9576d..97a258c934af 100644
+--- a/drivers/gpu/drm/vc4/vc4_dsi.c
++++ b/drivers/gpu/drm/vc4/vc4_dsi.c
+@@ -1518,7 +1518,8 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&dsi->bridge_chain);
+- vc4_dsi_encoder->base.type = VC4_ENCODER_TYPE_DSI1;
++ vc4_dsi_encoder->base.type = dsi->variant->port ?
++ VC4_ENCODER_TYPE_DSI1 : VC4_ENCODER_TYPE_DSI0;
+ vc4_dsi_encoder->dsi = dsi;
+ dsi->encoder = &vc4_dsi_encoder->base.base;
+
+--
+2.35.1
+
--- /dev/null
+From 3151d1c7a263f12d7eddf62d4b5ad853b77cff46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:38 +0200
+Subject: drm/vc4: dsi: Release workaround buffer and DMA
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 89c4bbe2a01ea401c2b0fabc104720809084b77f ]
+
+On Pi0-3 the driver allocates a buffer and requests a DMA channel
+because the ARM can't write to DSI1's registers directly.
+
+However, we never release that buffer or channel. Let's add a
+device-managed action to release each.
+
+Fixes: 4078f5757144 ("drm/vc4: Add DSI driver")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-12-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_dsi.c | 29 ++++++++++++++++++++++++++++-
+ 1 file changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
+index 98308a17e4ed..e82ee94cafc7 100644
+--- a/drivers/gpu/drm/vc4/vc4_dsi.c
++++ b/drivers/gpu/drm/vc4/vc4_dsi.c
+@@ -1487,13 +1487,29 @@ vc4_dsi_init_phy_clocks(struct vc4_dsi *dsi)
+ dsi->clk_onecell);
+ }
+
++static void vc4_dsi_dma_mem_release(void *ptr)
++{
++ struct vc4_dsi *dsi = ptr;
++ struct device *dev = &dsi->pdev->dev;
++
++ dma_free_coherent(dev, 4, dsi->reg_dma_mem, dsi->reg_dma_paddr);
++ dsi->reg_dma_mem = NULL;
++}
++
++static void vc4_dsi_dma_chan_release(void *ptr)
++{
++ struct vc4_dsi *dsi = ptr;
++
++ dma_release_channel(dsi->reg_dma_chan);
++ dsi->reg_dma_chan = NULL;
++}
++
+ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
+ {
+ struct platform_device *pdev = to_platform_device(dev);
+ struct drm_device *drm = dev_get_drvdata(master);
+ struct vc4_dsi *dsi = dev_get_drvdata(dev);
+ struct vc4_dsi_encoder *vc4_dsi_encoder;
+- dma_cap_mask_t dma_mask;
+ int ret;
+
+ dsi->variant = of_device_get_match_data(dev);
+@@ -1527,6 +1543,8 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
+ * so set up a channel for talking to it.
+ */
+ if (dsi->variant->broken_axi_workaround) {
++ dma_cap_mask_t dma_mask;
++
+ dsi->reg_dma_mem = dma_alloc_coherent(dev, 4,
+ &dsi->reg_dma_paddr,
+ GFP_KERNEL);
+@@ -1535,8 +1553,13 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
+ return -ENOMEM;
+ }
+
++ ret = devm_add_action_or_reset(dev, vc4_dsi_dma_mem_release, dsi);
++ if (ret)
++ return ret;
++
+ dma_cap_zero(dma_mask);
+ dma_cap_set(DMA_MEMCPY, dma_mask);
++
+ dsi->reg_dma_chan = dma_request_chan_by_mask(&dma_mask);
+ if (IS_ERR(dsi->reg_dma_chan)) {
+ ret = PTR_ERR(dsi->reg_dma_chan);
+@@ -1546,6 +1569,10 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data)
+ return ret;
+ }
+
++ ret = devm_add_action_or_reset(dev, vc4_dsi_dma_chan_release, dsi);
++ if (ret)
++ return ret;
++
+ /* Get the physical address of the device's registers. The
+ * struct resource for the regs gives us the bus address
+ * instead.
+--
+2.35.1
+
--- /dev/null
+From 71eccd0db221e72d9d4f6b08046fd7f3abfea14a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:45 +0200
+Subject: drm/vc4: hdmi: Add all the vc5 HDMI registers into the debugfs dumps
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 25eb441d55d479581a65bcc9de88bc1d86bf76c1 ]
+
+The vc5 HDMI registers hadn't been added into the debugfs
+register sets, therefore weren't dumped on request.
+Add them in.
+
+Fixes: 8323989140f3 ("drm/vc4: hdmi: Support the BCM2711 HDMI controllers")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-19-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 39 ++++++++++++++++++++++++++++++++++
+ drivers/gpu/drm/vc4/vc4_hdmi.h | 8 +++++++
+ 2 files changed, 47 insertions(+)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 3ff35e3649aa..2ff53482d5d1 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -122,6 +122,12 @@ static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
+
+ drm_print_regset32(&p, &vc4_hdmi->hdmi_regset);
+ drm_print_regset32(&p, &vc4_hdmi->hd_regset);
++ drm_print_regset32(&p, &vc4_hdmi->cec_regset);
++ drm_print_regset32(&p, &vc4_hdmi->csc_regset);
++ drm_print_regset32(&p, &vc4_hdmi->dvp_regset);
++ drm_print_regset32(&p, &vc4_hdmi->phy_regset);
++ drm_print_regset32(&p, &vc4_hdmi->ram_regset);
++ drm_print_regset32(&p, &vc4_hdmi->rm_regset);
+
+ return 0;
+ }
+@@ -2374,6 +2380,7 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
+ struct platform_device *pdev = vc4_hdmi->pdev;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
++ int ret;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi");
+ if (!res)
+@@ -2470,6 +2477,38 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
+ return PTR_ERR(vc4_hdmi->reset);
+ }
+
++ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->hdmi_regset, VC4_HDMI);
++ if (ret)
++ return ret;
++
++ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->hd_regset, VC4_HD);
++ if (ret)
++ return ret;
++
++ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->cec_regset, VC5_CEC);
++ if (ret)
++ return ret;
++
++ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->csc_regset, VC5_CSC);
++ if (ret)
++ return ret;
++
++ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->dvp_regset, VC5_DVP);
++ if (ret)
++ return ret;
++
++ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->phy_regset, VC5_PHY);
++ if (ret)
++ return ret;
++
++ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->ram_regset, VC5_RAM);
++ if (ret)
++ return ret;
++
++ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->rm_regset, VC5_RM);
++ if (ret)
++ return ret;
++
+ return 0;
+ }
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
+index 1076faeab616..2b9f5ca15a40 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
+@@ -184,6 +184,14 @@ struct vc4_hdmi {
+ struct debugfs_regset32 hdmi_regset;
+ struct debugfs_regset32 hd_regset;
+
++ /* VC5 only */
++ struct debugfs_regset32 cec_regset;
++ struct debugfs_regset32 csc_regset;
++ struct debugfs_regset32 dvp_regset;
++ struct debugfs_regset32 phy_regset;
++ struct debugfs_regset32 ram_regset;
++ struct debugfs_regset32 rm_regset;
++
+ /**
+ * @hw_lock: Spinlock protecting device register access.
+ */
+--
+2.35.1
+
--- /dev/null
+From c5df348570608ddb6c26db3e2d80560f73a38b7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:47 +0200
+Subject: drm/vc4: hdmi: Avoid full hdmi audio fifo writes
+
+From: Dom Cobley <popcornmix@gmail.com>
+
+[ Upstream commit 1c594eeccf92368177c2e22f1d3ee4933dfb8567 ]
+
+We are getting occasional VC4_HD_MAI_CTL_ERRORF in
+HDMI_MAI_CTL which seem to correspond with audio dropouts.
+
+Reduce the threshold where we deassert DREQ to avoid the fifo
+overfilling
+
+Fixes: bb7d78568814 ("drm/vc4: Add HDMI audio support")
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-21-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 0fe04b1f9782..114b007a1e6e 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -1626,10 +1626,10 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
+
+ /* Set the MAI threshold */
+ HDMI_WRITE(HDMI_MAI_THR,
+- VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICHIGH) |
+- VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICLOW) |
+- VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQHIGH) |
+- VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_DREQLOW));
++ VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_PANICHIGH) |
++ VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_PANICLOW) |
++ VC4_SET_FIELD(0x06, VC4_HD_MAI_THR_DREQHIGH) |
++ VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_DREQLOW));
+
+ HDMI_WRITE(HDMI_MAI_CONFIG,
+ VC4_HDMI_MAI_CONFIG_BIT_REVERSE |
+--
+2.35.1
+
--- /dev/null
+From 68d88bf660e230ec63096802ea29d867cee6bf5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:46 +0200
+Subject: drm/vc4: hdmi: Clear unused infoframe packet RAM registers
+
+From: Dom Cobley <popcornmix@gmail.com>
+
+[ Upstream commit b6079d1578dc4b4b8050d613a5449a63def7d1dd ]
+
+Using a hdmi analyser the bytes in packet ram
+registers beyond the length were visible in the
+infoframes and it flagged the checksum as invalid.
+
+Zeroing unused words of packet RAM avoids this
+
+Fixes: 21317b3fba54 ("drm/vc4: Set up the AVI and SPD infoframes.")
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-20-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 2ff53482d5d1..0fe04b1f9782 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -439,9 +439,11 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
+ const struct vc4_hdmi_register *ram_packet_start =
+ &vc4_hdmi->variant->registers[HDMI_RAM_PACKET_START];
+ u32 packet_reg = ram_packet_start->offset + VC4_HDMI_PACKET_STRIDE * packet_id;
++ u32 packet_reg_next = ram_packet_start->offset +
++ VC4_HDMI_PACKET_STRIDE * (packet_id + 1);
+ void __iomem *base = __vc4_hdmi_get_field_base(vc4_hdmi,
+ ram_packet_start->reg);
+- uint8_t buffer[VC4_HDMI_PACKET_STRIDE];
++ uint8_t buffer[VC4_HDMI_PACKET_STRIDE] = {};
+ unsigned long flags;
+ ssize_t len, i;
+ int ret;
+@@ -477,6 +479,13 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
+ packet_reg += 4;
+ }
+
++ /*
++ * clear remainder of packet ram as it's included in the
++ * infoframe and triggers a checksum error on hdmi analyser
++ */
++ for (; packet_reg < packet_reg_next; packet_reg += 4)
++ writel(0, base + packet_reg);
++
+ HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
+ HDMI_READ(HDMI_RAM_PACKET_CONFIG) | BIT(packet_id));
+
+--
+2.35.1
+
--- /dev/null
+From 6f58aa94bf17efa6d72715483f2444fd5a873176 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:59 +0200
+Subject: drm/vc4: hdmi: Correct HDMI timing registers for interlaced modes
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit fb10dc451c0f15e3c19798a2f41d357f3f7576f5 ]
+
+For interlaced modes the timings were not being correctly
+programmed into the HDMI block, so correct them.
+
+Fixes: 8323989140f3 ("drm/vc4: hdmi: Support the BCM2711 HDMI controllers")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-33-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index da3622f34dba..f7781d171687 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -920,13 +920,13 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
+ VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
+ VC5_HDMI_VERTA_VFP) |
+ VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL));
+- u32 vertb = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
+- VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
+- interlaced,
++ u32 vertb = (VC4_SET_FIELD(mode->htotal >> (2 - pixel_rep),
++ VC5_HDMI_VERTB_VSPO) |
++ VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
+ VC4_HDMI_VERTB_VBP));
+ u32 vertb_even = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
+ VC4_SET_FIELD(mode->crtc_vtotal -
+- mode->crtc_vsync_end,
++ mode->crtc_vsync_end - interlaced,
+ VC4_HDMI_VERTB_VBP));
+ unsigned long flags;
+ unsigned char gcp;
+--
+2.35.1
+
--- /dev/null
+From 47f0fa51b3cb12aee2628ba470f87093ea8ec91e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:57 +0200
+Subject: drm/vc4: hdmi: Fix timings for interlaced modes
+
+From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
+
+[ Upstream commit 0ee5a40152b15f200ed3a0d51e8aa782ea979c6a ]
+
+Increase the number of post-sync blanking lines on odd fields instead of
+decreasing it on even fields. This makes the total number of lines
+properly match the modelines.
+
+Additionally fix the value of PV_VCONTROL_ODD_DELAY, which did not take
+pixels_per_clock into account, causing some displays to invert the
+fields when driven by bcm2711.
+
+Fixes: 682e62c45406 ("drm/vc4: Fix support for interlaced modes on HDMI.")
+Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-31-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 7 ++++---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 12 ++++++------
+ 2 files changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
+index 0a5f58cdd781..2810b0d9e78c 100644
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -344,7 +344,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
+ PV_HORZB_HACTIVE));
+
+ CRTC_WRITE(PV_VERTA,
+- VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
++ VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
++ interlace,
+ PV_VERTA_VBP) |
+ VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
+ PV_VERTA_VSYNC));
+@@ -356,7 +357,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
+ if (interlace) {
+ CRTC_WRITE(PV_VERTA_EVEN,
+ VC4_SET_FIELD(mode->crtc_vtotal -
+- mode->crtc_vsync_end - 1,
++ mode->crtc_vsync_end,
+ PV_VERTA_VBP) |
+ VC4_SET_FIELD(mode->crtc_vsync_end -
+ mode->crtc_vsync_start,
+@@ -376,7 +377,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
+ PV_VCONTROL_CONTINUOUS |
+ (is_dsi ? PV_VCONTROL_DSI : 0) |
+ PV_VCONTROL_INTERLACE |
+- VC4_SET_FIELD(mode->htotal * pixel_rep / 2,
++ VC4_SET_FIELD(mode->htotal * pixel_rep / (2 * ppc),
+ PV_VCONTROL_ODD_DELAY));
+ CRTC_WRITE(PV_VSYNCD_EVEN, 0);
+ } else {
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 55a965120a77..da3622f34dba 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -870,12 +870,12 @@ static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
+ VC4_HDMI_VERTA_VFP) |
+ VC4_SET_FIELD(mode->crtc_vdisplay, VC4_HDMI_VERTA_VAL));
+ u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
+- VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
++ VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
++ interlaced,
+ VC4_HDMI_VERTB_VBP));
+ u32 vertb_even = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
+ VC4_SET_FIELD(mode->crtc_vtotal -
+- mode->crtc_vsync_end -
+- interlaced,
++ mode->crtc_vsync_end,
+ VC4_HDMI_VERTB_VBP));
+ unsigned long flags;
+
+@@ -921,12 +921,12 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
+ VC5_HDMI_VERTA_VFP) |
+ VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL));
+ u32 vertb = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
+- VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
++ VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
++ interlaced,
+ VC4_HDMI_VERTB_VBP));
+ u32 vertb_even = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
+ VC4_SET_FIELD(mode->crtc_vtotal -
+- mode->crtc_vsync_end -
+- interlaced,
++ mode->crtc_vsync_end,
+ VC4_HDMI_VERTB_VBP));
+ unsigned long flags;
+ unsigned char gcp;
+--
+2.35.1
+
--- /dev/null
+From 2721b64218abb5a86c395aa5e972221024fa40e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:50 +0200
+Subject: drm/vc4: hdmi: Move HDMI reset to pm_resume
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 467e30171b5b483922b1c24c573fa50787207cb6 ]
+
+The BCM2835-37 found in the RaspberryPi 0 to 3 have a power domain
+attached to the HDMI block, handled in Linux through runtime_pm.
+
+That power domain is shared with the VEC block, so even if we put our
+runtime_pm reference in the HDMI driver it would keep being on. If the
+VEC is disabled though, the power domain would be disabled and we would
+lose any initialization done in our bind implementation.
+
+That initialization involves calling the reset function and initializing
+the CEC registers.
+
+Let's move the initialization to our runtime_resume implementation so
+that we initialize everything properly if we ever need to.
+
+Fixes: c86b41214362 ("drm/vc4: hdmi: Move the HSM clock enable to runtime_pm")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-24-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 41 ++++++++++++++++++----------------
+ 1 file changed, 22 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 452b3214fd09..55a965120a77 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -2214,8 +2214,6 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
+ struct cec_connector_info conn_info;
+ struct platform_device *pdev = vc4_hdmi->pdev;
+ struct device *dev = &pdev->dev;
+- unsigned long flags;
+- u32 value;
+ int ret;
+
+ if (!of_find_property(dev->of_node, "interrupts", NULL)) {
+@@ -2234,15 +2232,6 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
+ cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector);
+ cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info);
+
+- spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
+- value = HDMI_READ(HDMI_CEC_CNTRL_1);
+- /* Set the logical address to Unregistered */
+- value |= VC4_HDMI_CEC_ADDR_MASK;
+- HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
+- spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
+-
+- vc4_hdmi_cec_update_clk_div(vc4_hdmi);
+-
+ if (vc4_hdmi->variant->external_irq_controller) {
+ ret = request_threaded_irq(platform_get_irq_byname(pdev, "cec-rx"),
+ vc4_cec_irq_handler_rx_bare,
+@@ -2258,10 +2247,6 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
+ if (ret)
+ goto err_remove_cec_rx_handler;
+ } else {
+- spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
+- HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff);
+- spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
+-
+ ret = request_threaded_irq(platform_get_irq(pdev, 0),
+ vc4_cec_irq_handler,
+ vc4_cec_irq_handler_thread, 0,
+@@ -2312,7 +2297,6 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
+ }
+
+ static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi) {};
+-
+ #endif
+
+ static int vc4_hdmi_build_regset(struct vc4_hdmi *vc4_hdmi,
+@@ -2541,12 +2525,34 @@ static int __maybe_unused vc4_hdmi_runtime_suspend(struct device *dev)
+ static int vc4_hdmi_runtime_resume(struct device *dev)
+ {
+ struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
++ unsigned long __maybe_unused flags;
++ u32 __maybe_unused value;
+ int ret;
+
+ ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
+ if (ret)
+ return ret;
+
++ if (vc4_hdmi->variant->reset)
++ vc4_hdmi->variant->reset(vc4_hdmi);
++
++#ifdef CONFIG_DRM_VC4_HDMI_CEC
++ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
++ value = HDMI_READ(HDMI_CEC_CNTRL_1);
++ /* Set the logical address to Unregistered */
++ value |= VC4_HDMI_CEC_ADDR_MASK;
++ HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
++ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
++
++ vc4_hdmi_cec_update_clk_div(vc4_hdmi);
++
++ if (!vc4_hdmi->variant->external_irq_controller) {
++ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
++ HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff);
++ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
++ }
++#endif
++
+ return 0;
+ }
+
+@@ -2649,9 +2655,6 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+- if (vc4_hdmi->variant->reset)
+- vc4_hdmi->variant->reset(vc4_hdmi);
+-
+ if ((of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi0") ||
+ of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi1")) &&
+ HDMI_READ(HDMI_VID_CTL) & VC4_HD_VID_CTL_ENABLE) {
+--
+2.35.1
+
--- /dev/null
+From 666e960a0abb25fdf83e1bd88efed4bf31b985ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:48:00 +0200
+Subject: drm/vc4: hdmi: Move pixel doubling from Pixelvalve to HDMI block
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 3650062e4281ab28a6f8c9d59606d0a6266be736 ]
+
+With the change to 2 pixels/clock, the pixel doubling in the PV
+results in doubling each pair of pixels, ie ABABCDCD instead of
+AABBCCDD.
+
+Move the pixel doubling to the HDMI block, however this means
+that DBLCLK modes now fall foul of requiring even values for
+all the horizontal timing parameters.
+As both 480i and 576i fail this, attempt to fix up DBLCLK modes
+that have odd timings values.
+
+Fixes: 8323989140f3 ("drm/vc4: hdmi: Support the BCM2711 HDMI controllers")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-34-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 4 +++-
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 34 ++++++++++++++++++++++++++++------
+ 2 files changed, 31 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
+index 2810b0d9e78c..18e2a246f7c1 100644
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -314,7 +314,9 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode
+ struct drm_crtc_state *crtc_state = crtc->state;
+ struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+ bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
+- u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
++ bool is_hdmi = vc4_encoder->type == VC4_ENCODER_TYPE_HDMI0 ||
++ vc4_encoder->type == VC4_ENCODER_TYPE_HDMI1;
++ u32 pixel_rep = ((mode->flags & DRM_MODE_FLAG_DBLCLK) && !is_hdmi) ? 2 : 1;
+ bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
+ vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
+ bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1;
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index f7781d171687..8b1e52145082 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -79,6 +79,8 @@
+ #define VC5_HDMI_VERTB_VSPO_SHIFT 16
+ #define VC5_HDMI_VERTB_VSPO_MASK VC4_MASK(29, 16)
+
++#define VC4_HDMI_MISC_CONTROL_PIXEL_REP_SHIFT 0
++#define VC4_HDMI_MISC_CONTROL_PIXEL_REP_MASK VC4_MASK(3, 0)
+ #define VC5_HDMI_MISC_CONTROL_PIXEL_REP_SHIFT 0
+ #define VC5_HDMI_MISC_CONTROL_PIXEL_REP_MASK VC4_MASK(3, 0)
+
+@@ -878,6 +880,7 @@ static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
+ mode->crtc_vsync_end,
+ VC4_HDMI_VERTB_VBP));
+ unsigned long flags;
++ u32 reg;
+
+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
+
+@@ -904,6 +907,11 @@ static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
+ HDMI_WRITE(HDMI_VERTB0, vertb_even);
+ HDMI_WRITE(HDMI_VERTB1, vertb);
+
++ reg = HDMI_READ(HDMI_MISC_CONTROL);
++ reg &= ~VC4_HDMI_MISC_CONTROL_PIXEL_REP_MASK;
++ reg |= VC4_SET_FIELD(pixel_rep - 1, VC4_HDMI_MISC_CONTROL_PIXEL_REP);
++ HDMI_WRITE(HDMI_MISC_CONTROL, reg);
++
+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
+ }
+
+@@ -993,7 +1001,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
+
+ reg = HDMI_READ(HDMI_MISC_CONTROL);
+ reg &= ~VC5_HDMI_MISC_CONTROL_PIXEL_REP_MASK;
+- reg |= VC4_SET_FIELD(0, VC5_HDMI_MISC_CONTROL_PIXEL_REP);
++ reg |= VC4_SET_FIELD(pixel_rep - 1, VC5_HDMI_MISC_CONTROL_PIXEL_REP);
+ HDMI_WRITE(HDMI_MISC_CONTROL, reg);
+
+ HDMI_WRITE(HDMI_CLOCK_STOP, 0);
+@@ -1276,11 +1284,25 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
+ unsigned long long pixel_rate = mode->clock * 1000;
+ unsigned long long tmds_rate;
+
+- if (vc4_hdmi->variant->unsupported_odd_h_timings &&
+- !(mode->flags & DRM_MODE_FLAG_DBLCLK) &&
+- ((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
+- (mode->hsync_end % 2) || (mode->htotal % 2)))
+- return -EINVAL;
++ if (vc4_hdmi->variant->unsupported_odd_h_timings) {
++ if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
++ /* Only try to fixup DBLCLK modes to get 480i and 576i
++ * working.
++ * A generic solution for all modes with odd horizontal
++ * timing values seems impossible based on trying to
++ * solve it for 1366x768 monitors.
++ */
++ if ((mode->hsync_start - mode->hdisplay) & 1)
++ mode->hsync_start--;
++ if ((mode->hsync_end - mode->hsync_start) & 1)
++ mode->hsync_end--;
++ }
++
++ /* Now check whether we still have odd values remaining */
++ if ((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
++ (mode->hsync_end % 2) || (mode->htotal % 2))
++ return -EINVAL;
++ }
+
+ /*
+ * The 1440p@60 pixel rate is in the same range than the first
+--
+2.35.1
+
--- /dev/null
+From 7c5fcf660241704b22210550026e198f8ad15dbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:48 +0200
+Subject: drm/vc4: hdmi: Reset HDMI MISC_CONTROL register
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit 35dc00c12a72700a9c4592afee7d136ecb280cbd ]
+
+The HDMI block can repeat pixels for double clocked modes,
+and the firmware is now configuring the block to do this as
+the PV is doing it incorrectly when at 2pixels/clock.
+If the kernel doesn't reset it then we end up with strange
+modes.
+
+Reset MISC_CONTROL.
+
+Fixes: 8323989140f3 ("drm/vc4: hdmi: Support the BCM2711 HDMI controllers")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-22-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 8 ++++++++
+ drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 3 +++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 114b007a1e6e..452b3214fd09 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -79,6 +79,9 @@
+ #define VC5_HDMI_VERTB_VSPO_SHIFT 16
+ #define VC5_HDMI_VERTB_VSPO_MASK VC4_MASK(29, 16)
+
++#define VC5_HDMI_MISC_CONTROL_PIXEL_REP_SHIFT 0
++#define VC5_HDMI_MISC_CONTROL_PIXEL_REP_MASK VC4_MASK(3, 0)
++
+ #define VC5_HDMI_SCRAMBLER_CTL_ENABLE BIT(0)
+
+ #define VC5_HDMI_DEEP_COLOR_CONFIG_1_INIT_PACK_PHASE_SHIFT 8
+@@ -988,6 +991,11 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
+ reg |= gcp_en ? VC5_HDMI_GCP_CONFIG_GCP_ENABLE : 0;
+ HDMI_WRITE(HDMI_GCP_CONFIG, reg);
+
++ reg = HDMI_READ(HDMI_MISC_CONTROL);
++ reg &= ~VC5_HDMI_MISC_CONTROL_PIXEL_REP_MASK;
++ reg |= VC4_SET_FIELD(0, VC5_HDMI_MISC_CONTROL_PIXEL_REP);
++ HDMI_WRITE(HDMI_MISC_CONTROL, reg);
++
+ HDMI_WRITE(HDMI_CLOCK_STOP, 0);
+
+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
+index fc971506bd4f..24056441a4bb 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
++++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
+@@ -125,6 +125,7 @@ enum vc4_hdmi_field {
+ HDMI_VERTB0,
+ HDMI_VERTB1,
+ HDMI_VID_CTL,
++ HDMI_MISC_CONTROL,
+ };
+
+ struct vc4_hdmi_register {
+@@ -235,6 +236,7 @@ static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi0_fields[] = {
+ VC4_HDMI_REG(HDMI_VERTB0, 0x0f0),
+ VC4_HDMI_REG(HDMI_VERTA1, 0x0f4),
+ VC4_HDMI_REG(HDMI_VERTB1, 0x0f8),
++ VC4_HDMI_REG(HDMI_MISC_CONTROL, 0x100),
+ VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x09c),
+ VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0),
+ VC4_HDMI_REG(HDMI_DEEP_COLOR_CONFIG_1, 0x170),
+@@ -315,6 +317,7 @@ static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi1_fields[] = {
+ VC4_HDMI_REG(HDMI_VERTB0, 0x0f0),
+ VC4_HDMI_REG(HDMI_VERTA1, 0x0f4),
+ VC4_HDMI_REG(HDMI_VERTB1, 0x0f8),
++ VC4_HDMI_REG(HDMI_MISC_CONTROL, 0x100),
+ VC4_HDMI_REG(HDMI_MAI_CHANNEL_MAP, 0x09c),
+ VC4_HDMI_REG(HDMI_MAI_CONFIG, 0x0a0),
+ VC4_HDMI_REG(HDMI_DEEP_COLOR_CONFIG_1, 0x170),
+--
+2.35.1
+
--- /dev/null
+From 58bbdca5a2f44b2bbe784c93c1fbab1592e81ce8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:49 +0200
+Subject: drm/vc4: hdmi: Switch to pm_runtime_status_suspended
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit fcef97e70094a33ded73b3eb9bef06698c6e9c12 ]
+
+If the controller isn't clocked or its domain powered up, the register
+accesses will either stall the CPU or return garbage, respectively.
+
+Thus, we had a warning in our register access function to complain when
+that kind of risky accesses were performed.
+
+In order to check the runtime_pm power state, we were using
+pm_runtime_active(), but it turns out that it will become active only
+once the runtime_resume hook has been executed.
+
+This prevents us from doing any WARN-free register access in our
+runtime_resume() implementation, while this is valid.
+
+Let's switch to pm_runtime_status_suspended() instead.
+
+Fixes: 14e193b95604 ("drm/vc4: hdmi: Warn if we access the controller while disabled")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-23-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
+index 24056441a4bb..72b769412482 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
++++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
+@@ -417,7 +417,7 @@ static inline u32 vc4_hdmi_read(struct vc4_hdmi *hdmi,
+ const struct vc4_hdmi_variant *variant = hdmi->variant;
+ void __iomem *base;
+
+- WARN_ON(!pm_runtime_active(&hdmi->pdev->dev));
++ WARN_ON(pm_runtime_status_suspended(&hdmi->pdev->dev));
+
+ if (reg >= variant->num_registers) {
+ dev_warn(&hdmi->pdev->dev,
+@@ -447,7 +447,7 @@ static inline void vc4_hdmi_write(struct vc4_hdmi *hdmi,
+
+ lockdep_assert_held(&hdmi->hw_lock);
+
+- WARN_ON(!pm_runtime_active(&hdmi->pdev->dev));
++ WARN_ON(pm_runtime_status_suspended(&hdmi->pdev->dev));
+
+ if (reg >= variant->num_registers) {
+ dev_warn(&hdmi->pdev->dev,
+--
+2.35.1
+
--- /dev/null
+From d041f4d955ae3cfcf492f4f494938d8fda79bed6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:30 +0200
+Subject: drm/vc4: kms: Use maximum FIFO load for the HVS clock rate
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+[ Upstream commit 1701a23a4ef0993964ccc2f2d5d13f83a5ff4c70 ]
+
+The core clock computation takes into account both the load due to the
+input (ie, planes) and its output (ie, encoders).
+
+However, while the input load needs to consider all the planes, and thus
+sum all of their associated loads, the output happens mostly in
+parallel.
+
+Therefore, we need to consider only the maximum of all the output loads,
+and not the sum like we were doing. This resulted in a clock rate way
+too high which could be discarded for being too high by the clock
+framework.
+
+Since recent changes, the clock framework will even downright reject it,
+leading to a core clock being too low for its current needs.
+
+Fixes: 16e101051f32 ("drm/vc4: Increase the core clock based on HVS load")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-4-maxime@cerno.tech
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_kms.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
+index 992d6a240002..dba23ae2e65e 100644
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -890,7 +890,9 @@ vc4_core_clock_atomic_check(struct drm_atomic_state *state)
+ continue;
+
+ num_outputs++;
+- cob_rate += hvs_new_state->fifo_state[i].fifo_load;
++ cob_rate = max_t(unsigned long,
++ hvs_new_state->fifo_state[i].fifo_load,
++ cob_rate);
+ }
+
+ pixel_rate = load_state->hvs_load;
+--
+2.35.1
+
--- /dev/null
+From f5150ba8afb2aaaba3efb7dfac9930c5e7e8c2c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:32 +0200
+Subject: drm/vc4: plane: Fix margin calculations for the right/bottom edges
+
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+
+[ Upstream commit b7c3d6821627861f4ea3e1f2b595d0ed9e80aac8 ]
+
+The current plane margin calculation code clips the right and bottom
+edges of the range based using the left and top margins.
+
+This is obviously wrong, so let's fix it.
+
+Fixes: 666e73587f90 ("drm/vc4: Take margin setup into account when updating planes")
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-6-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_plane.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
+index c2c33f200416..a82a0b1190eb 100644
+--- a/drivers/gpu/drm/vc4/vc4_plane.c
++++ b/drivers/gpu/drm/vc4/vc4_plane.c
+@@ -310,16 +310,16 @@ static int vc4_plane_margins_adj(struct drm_plane_state *pstate)
+ adjhdisplay,
+ crtc_state->mode.hdisplay);
+ vc4_pstate->crtc_x += left;
+- if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - left)
+- vc4_pstate->crtc_x = crtc_state->mode.hdisplay - left;
++ if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - right)
++ vc4_pstate->crtc_x = crtc_state->mode.hdisplay - right;
+
+ adjvdisplay = crtc_state->mode.vdisplay - (top + bottom);
+ vc4_pstate->crtc_y = DIV_ROUND_CLOSEST(vc4_pstate->crtc_y *
+ adjvdisplay,
+ crtc_state->mode.vdisplay);
+ vc4_pstate->crtc_y += top;
+- if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - top)
+- vc4_pstate->crtc_y = crtc_state->mode.vdisplay - top;
++ if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - bottom)
++ vc4_pstate->crtc_y = crtc_state->mode.vdisplay - bottom;
+
+ vc4_pstate->crtc_w = DIV_ROUND_CLOSEST(vc4_pstate->crtc_w *
+ adjhdisplay,
+--
+2.35.1
+
--- /dev/null
+From 89f685288a395f16d23787906363fcc27975edc2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 16:47:31 +0200
+Subject: drm/vc4: plane: Remove subpixel positioning check
+
+From: Dom Cobley <popcornmix@gmail.com>
+
+[ Upstream commit 517db1ab1566dba3093dbdb8de4263ba4aa66416 ]
+
+There is little harm in ignoring fractional coordinates
+(they just get truncated).
+
+Without this:
+modetest -M vc4 -F tiles,gradient -s 32:1920x1080-60 -P89@74:1920x1080*.1.1@XR24
+
+is rejected. We have the same issue in Kodi when trying to
+use zoom options on video.
+
+Note: even if all coordinates are fully integer. e.g.
+src:[0,0,1920,1080] dest:[-10,-10,1940,1100]
+
+it will still get rejected as drm_atomic_helper_check_plane_state
+uses drm_rect_clip_scaled which transforms this to fractional src coords
+
+Fixes: 21af94cf1a4c ("drm/vc4: Add support for scaling of display planes.")
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+Link: https://lore.kernel.org/r/20220613144800.326124-5-maxime@cerno.tech
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_plane.c | 22 +++++++++-------------
+ 1 file changed, 9 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
+index 920a9eefe426..c2c33f200416 100644
+--- a/drivers/gpu/drm/vc4/vc4_plane.c
++++ b/drivers/gpu/drm/vc4/vc4_plane.c
+@@ -339,7 +339,6 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
+ struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+ struct drm_framebuffer *fb = state->fb;
+ struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
+- u32 subpixel_src_mask = (1 << 16) - 1;
+ int num_planes = fb->format->num_planes;
+ struct drm_crtc_state *crtc_state;
+ u32 h_subsample = fb->format->hsub;
+@@ -361,18 +360,15 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
+ for (i = 0; i < num_planes; i++)
+ vc4_state->offsets[i] = bo->paddr + fb->offsets[i];
+
+- /* We don't support subpixel source positioning for scaling. */
+- if ((state->src.x1 & subpixel_src_mask) ||
+- (state->src.x2 & subpixel_src_mask) ||
+- (state->src.y1 & subpixel_src_mask) ||
+- (state->src.y2 & subpixel_src_mask)) {
+- return -EINVAL;
+- }
+-
+- vc4_state->src_x = state->src.x1 >> 16;
+- vc4_state->src_y = state->src.y1 >> 16;
+- vc4_state->src_w[0] = (state->src.x2 - state->src.x1) >> 16;
+- vc4_state->src_h[0] = (state->src.y2 - state->src.y1) >> 16;
++ /*
++ * We don't support subpixel source positioning for scaling,
++ * but fractional coordinates can be generated by clipping
++ * so just round for now
++ */
++ vc4_state->src_x = DIV_ROUND_CLOSEST(state->src.x1, 1 << 16);
++ vc4_state->src_y = DIV_ROUND_CLOSEST(state->src.y1, 1 << 16);
++ vc4_state->src_w[0] = DIV_ROUND_CLOSEST(state->src.x2, 1 << 16) - vc4_state->src_x;
++ vc4_state->src_h[0] = DIV_ROUND_CLOSEST(state->src.y2, 1 << 16) - vc4_state->src_y;
+
+ vc4_state->crtc_x = state->dst.x1;
+ vc4_state->crtc_y = state->dst.y1;
+--
+2.35.1
+
--- /dev/null
+From ecf2222ab729384103cfbd3b8d1bc0decdf69d38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 14:42:22 +0400
+Subject: drm/virtio: Fix NULL vs IS_ERR checking in
+ virtio_gpu_object_shmem_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit c24968734abfed81c8f93dc5f44a7b7a9aecadfa ]
+
+Since drm_prime_pages_to_sg() function return error pointers.
+The drm_gem_shmem_get_sg_table() function returns error pointers too.
+Using IS_ERR() to check the return value to fix this.
+
+Fixes: 2f2aa13724d5 ("drm/virtio: move virtio_gpu_mem_entry initialization to new function")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20220602104223.54527-1-linmq006@gmail.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/virtio/virtgpu_object.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
+index f293e6ad52da..1cc8f3fc8e4b 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_object.c
++++ b/drivers/gpu/drm/virtio/virtgpu_object.c
+@@ -168,9 +168,9 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
+ * since virtio_gpu doesn't support dma-buf import from other devices.
+ */
+ shmem->pages = drm_gem_shmem_get_sg_table(&bo->base);
+- if (!shmem->pages) {
++ if (IS_ERR(shmem->pages)) {
+ drm_gem_shmem_unpin(&bo->base);
+- return -EINVAL;
++ return PTR_ERR(shmem->pages);
+ }
+
+ if (use_dma_api) {
+--
+2.35.1
+
--- /dev/null
+From e87f9d316a3402a1845fd3d75ca750b3c90f2fcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Apr 2022 08:12:59 -0300
+Subject: drm/vkms: check plane_composer->map[0] before using it
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Tales Lelo da Aparecida <tales.aparecida@gmail.com>
+
+[ Upstream commit 24f6fe3226c6f9f1b8406311a96b59c6e650b707 ]
+
+Fix a copypasta error. The caller of compose_plane() already checks
+primary_composer->map. In contrast, plane_composer->map is never
+verified here before handling.
+
+Fixes: 7938f4218168 ("dma-buf-map: Rename to iosys-map")
+Reviewed-by: André Almeida <andrealmeid@riseup.net>
+Signed-off-by: Tales Lelo da Aparecida <tales.aparecida@gmail.com>
+Signed-off-by: Melissa Wen <melissa.srw@gmail.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220415111300.61013-2-tales.aparecida@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vkms/vkms_composer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
+index c6a1036bf2ea..b47ac170108c 100644
+--- a/drivers/gpu/drm/vkms/vkms_composer.c
++++ b/drivers/gpu/drm/vkms/vkms_composer.c
+@@ -157,7 +157,7 @@ static void compose_plane(struct vkms_composer *primary_composer,
+ void *vaddr;
+ void (*pixel_blend)(const u8 *p_src, u8 *p_dst);
+
+- if (WARN_ON(iosys_map_is_null(&primary_composer->map[0])))
++ if (WARN_ON(iosys_map_is_null(&plane_composer->map[0])))
+ return;
+
+ vaddr = plane_composer->map[0].vaddr;
+--
+2.35.1
+
--- /dev/null
+From a73164fa167fe0ea571c824308d8de8bfbfb31e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 16:46:38 +0300
+Subject: eeprom: idt_89hpesx: uninitialized data in idt_dbgfs_csr_write()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 71d46f1ff2212ced4852c7e77c5176382a1bdcec ]
+
+The simple_write_to_buffer() function will return positive/success if it
+is able to write a single byte anywhere within the buffer. However that
+potentially leaves a lot of the buffer uninitialized.
+
+In this code it's better to return 0 if the offset is non-zero. This
+code is not written to support partial writes. And then return -EFAULT
+if the buffer is not completely initialized.
+
+Fixes: cfad6425382e ("eeprom: Add IDT 89HPESx EEPROM/CSR driver")
+Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Link: https://lore.kernel.org/r/Ysg1Pu/nzSMe3r1q@kili
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/eeprom/idt_89hpesx.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/misc/eeprom/idt_89hpesx.c b/drivers/misc/eeprom/idt_89hpesx.c
+index b0cff4b152da..7f430742ce2b 100644
+--- a/drivers/misc/eeprom/idt_89hpesx.c
++++ b/drivers/misc/eeprom/idt_89hpesx.c
+@@ -909,14 +909,18 @@ static ssize_t idt_dbgfs_csr_write(struct file *filep, const char __user *ubuf,
+ u32 csraddr, csrval;
+ char *buf;
+
++ if (*offp)
++ return 0;
++
+ /* Copy data from User-space */
+ buf = kmalloc(count + 1, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+- ret = simple_write_to_buffer(buf, count, offp, ubuf, count);
+- if (ret < 0)
++ if (copy_from_user(buf, ubuf, count)) {
++ ret = -EFAULT;
+ goto free_buf;
++ }
+ buf[count] = 0;
+
+ /* Find position of colon in the buffer */
+--
+2.35.1
+
--- /dev/null
+From a0561b35e0f632c3a5c2b50b08b9f4a0150bdf27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 18:10:01 +0800
+Subject: erofs: avoid consecutive detection for Highmem memory
+
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+
+[ Upstream commit 448b5a1548d87c246c3d0c3df8480d3c6eb6c11a ]
+
+Currently, vmap()s are avoided if physical addresses are
+consecutive for decompressed buffers.
+
+I observed that is very common for 4KiB pclusters since the
+numbers of decompressed pages are almost 2 or 3.
+
+However, such detection doesn't work for Highmem pages on
+32-bit machines, let's fix it now.
+
+Reported-by: Liu Jinbao <liujinbao1@xiaomi.com>
+Fixes: 7fc45dbc938a ("staging: erofs: introduce generic decompression backend")
+Link: https://lore.kernel.org/r/20220708101001.21242-1-hsiangkao@linux.alibaba.com
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/erofs/decompressor.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
+index 0e0d1fc0f130..9bbd9a59426b 100644
+--- a/fs/erofs/decompressor.c
++++ b/fs/erofs/decompressor.c
+@@ -93,14 +93,18 @@ static int z_erofs_lz4_prepare_dstpages(struct z_erofs_lz4_decompress_ctx *ctx,
+
+ if (page) {
+ __clear_bit(j, bounced);
+- if (kaddr) {
+- if (kaddr + PAGE_SIZE == page_address(page))
++ if (!PageHighMem(page)) {
++ if (!i) {
++ kaddr = page_address(page);
++ continue;
++ }
++ if (kaddr &&
++ kaddr + PAGE_SIZE == page_address(page)) {
+ kaddr += PAGE_SIZE;
+- else
+- kaddr = NULL;
+- } else if (!i) {
+- kaddr = page_address(page);
++ continue;
++ }
+ }
++ kaddr = NULL;
+ continue;
+ }
+ kaddr = NULL;
+--
+2.35.1
+
--- /dev/null
+From d2ab2e60212c6fc2f073b50a7fdd7939fe3dc7d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jun 2022 06:40:41 +0800
+Subject: erofs: wake up all waiters after z_erofs_lzma_head ready
+
+From: Yuwen Chen <chenyuwen1@meizu.com>
+
+[ Upstream commit 2df7c4bd7c1d2bc5ece5e9ed19dbd386810c2a65 ]
+
+When the user mounts the erofs second times, the decompression thread
+may hung. The problem happens due to a sequence of steps like the
+following:
+
+1) Task A called z_erofs_load_lzma_config which obtain all of the node
+ from the z_erofs_lzma_head.
+
+2) At this time, task B called the z_erofs_lzma_decompress and wanted to
+ get a node. But the z_erofs_lzma_head was empty, the Task B had to
+ sleep.
+
+3) Task A release nodes and push nodes into the z_erofs_lzma_head. But
+ task B was still sleeping.
+
+One example report when the hung happens:
+task:kworker/u3:1 state:D stack:14384 pid: 86 ppid: 2 flags:0x00004000
+Workqueue: erofs_unzipd z_erofs_decompressqueue_work
+Call Trace:
+ <TASK>
+ __schedule+0x281/0x760
+ schedule+0x49/0xb0
+ z_erofs_lzma_decompress+0x4bc/0x580
+ ? cpu_core_flags+0x10/0x10
+ z_erofs_decompress_pcluster+0x49b/0xba0
+ ? __update_load_avg_se+0x2b0/0x330
+ ? __update_load_avg_se+0x2b0/0x330
+ ? update_load_avg+0x5f/0x690
+ ? update_load_avg+0x5f/0x690
+ ? set_next_entity+0xbd/0x110
+ ? _raw_spin_unlock+0xd/0x20
+ z_erofs_decompress_queue.isra.0+0x2e/0x50
+ z_erofs_decompressqueue_work+0x30/0x60
+ process_one_work+0x1d3/0x3a0
+ worker_thread+0x45/0x3a0
+ ? process_one_work+0x3a0/0x3a0
+ kthread+0xe2/0x110
+ ? kthread_complete_and_exit+0x20/0x20
+ ret_from_fork+0x22/0x30
+ </TASK>
+
+Signed-off-by: Yuwen Chen <chenyuwen1@meizu.com>
+Fixes: 622ceaddb764 ("erofs: lzma compression support")
+Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Link: https://lore.kernel.org/r/20220626224041.4288-1-chenyuwen1@meizu.com
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/erofs/decompressor_lzma.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/erofs/decompressor_lzma.c b/fs/erofs/decompressor_lzma.c
+index 05a3063cf2bc..5e59b3f523eb 100644
+--- a/fs/erofs/decompressor_lzma.c
++++ b/fs/erofs/decompressor_lzma.c
+@@ -143,6 +143,7 @@ int z_erofs_load_lzma_config(struct super_block *sb,
+ DBG_BUGON(z_erofs_lzma_head);
+ z_erofs_lzma_head = head;
+ spin_unlock(&z_erofs_lzma_lock);
++ wake_up_all(&z_erofs_lzma_wq);
+
+ z_erofs_lzma_max_dictsize = dict_size;
+ mutex_unlock(&lzma_resize_mutex);
+--
+2.35.1
+
--- /dev/null
+From a22121bee299bde89ce8565c2ea226306ea9dc2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Jul 2022 13:13:50 +0200
+Subject: ext2: Add more validity checks for inode counts
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit fa78f336937240d1bc598db817d638086060e7e9 ]
+
+Add checks verifying number of inodes stored in the superblock matches
+the number computed from number of inodes per group. Also verify we have
+at least one block worth of inodes per group. This prevents crashes on
+corrupted filesystems.
+
+Reported-by: syzbot+d273f7d7f58afd93be48@syzkaller.appspotmail.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext2/super.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ext2/super.c b/fs/ext2/super.c
+index f6a19f6d9f6d..cdffa2a041af 100644
+--- a/fs/ext2/super.c
++++ b/fs/ext2/super.c
+@@ -1059,9 +1059,10 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
+ sbi->s_frags_per_group);
+ goto failed_mount;
+ }
+- if (sbi->s_inodes_per_group > sb->s_blocksize * 8) {
++ if (sbi->s_inodes_per_group < sbi->s_inodes_per_block ||
++ sbi->s_inodes_per_group > sb->s_blocksize * 8) {
+ ext2_msg(sb, KERN_ERR,
+- "error: #inodes per group too big: %lu",
++ "error: invalid #inodes per group: %lu",
+ sbi->s_inodes_per_group);
+ goto failed_mount;
+ }
+@@ -1071,6 +1072,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
+ sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) -
+ le32_to_cpu(es->s_first_data_block) - 1)
+ / EXT2_BLOCKS_PER_GROUP(sb)) + 1;
++ if ((u64)sbi->s_groups_count * sbi->s_inodes_per_group !=
++ le32_to_cpu(es->s_inodes_count)) {
++ ext2_msg(sb, KERN_ERR, "error: invalid #inodes: %u vs computed %llu",
++ le32_to_cpu(es->s_inodes_count),
++ (u64)sbi->s_groups_count * sbi->s_inodes_per_group);
++ goto failed_mount;
++ }
+ db_count = (sbi->s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /
+ EXT2_DESC_PER_BLOCK(sb);
+ sbi->s_group_desc = kmalloc_array(db_count,
+--
+2.35.1
+
--- /dev/null
+From 95c415efc984b5fb401b4ee8007623f0b55f69d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 14:25:15 +0800
+Subject: ext4: recover csum seed of tmp_inode after migrating to extents
+
+From: Li Lingfeng <lilingfeng3@huawei.com>
+
+[ Upstream commit 07ea7a617d6b278fb7acedb5cbe1a81ce2de7d0c ]
+
+When migrating to extents, the checksum seed of temporary inode
+need to be replaced by inode's, otherwise the inode checksums
+will be incorrect when swapping the inodes data.
+
+However, the temporary inode can not match it's checksum to
+itself since it has lost it's own checksum seed.
+
+mkfs.ext4 -F /dev/sdc
+mount /dev/sdc /mnt/sdc
+xfs_io -fc "pwrite 4k 4k" -c "fsync" /mnt/sdc/testfile
+chattr -e /mnt/sdc/testfile
+chattr +e /mnt/sdc/testfile
+umount /dev/sdc
+fsck -fn /dev/sdc
+
+========
+...
+Pass 1: Checking inodes, blocks, and sizes
+Inode 13 passes checks, but checksum does not match inode. Fix? no
+...
+========
+
+The fix is simple, save the checksum seed of temporary inode, and
+recover it after migrating to extents.
+
+Fixes: e81c9302a6c3 ("ext4: set csum seed in tmp inode while migrating to extents")
+Signed-off-by: Li Lingfeng <lilingfeng3@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20220617062515.2113438-1-lilingfeng3@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/migrate.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
+index 7a5353a8cfd7..f2c4d9eee475 100644
+--- a/fs/ext4/migrate.c
++++ b/fs/ext4/migrate.c
+@@ -417,7 +417,7 @@ int ext4_ext_migrate(struct inode *inode)
+ struct inode *tmp_inode = NULL;
+ struct migrate_struct lb;
+ unsigned long max_entries;
+- __u32 goal;
++ __u32 goal, tmp_csum_seed;
+ uid_t owner[2];
+
+ /*
+@@ -465,6 +465,7 @@ int ext4_ext_migrate(struct inode *inode)
+ * the migration.
+ */
+ ei = EXT4_I(inode);
++ tmp_csum_seed = EXT4_I(tmp_inode)->i_csum_seed;
+ EXT4_I(tmp_inode)->i_csum_seed = ei->i_csum_seed;
+ i_size_write(tmp_inode, i_size_read(inode));
+ /*
+@@ -575,6 +576,7 @@ int ext4_ext_migrate(struct inode *inode)
+ * the inode is not visible to user space.
+ */
+ tmp_inode->i_blocks = 0;
++ EXT4_I(tmp_inode)->i_csum_seed = tmp_csum_seed;
+
+ /* Reset the extent details */
+ ext4_ext_tree_init(handle, tmp_inode);
+--
+2.35.1
+
--- /dev/null
+From e3e5ccd188dcf380227ad9ac17d0f831a7a67522 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 10:29:11 +0900
+Subject: f2fs: allow compression for mmap files in compress_mode=user
+
+From: Sungjong Seo <sj1557.seo@samsung.com>
+
+[ Upstream commit 66d34fcbbe63ebd8584b792e0d741f6648100894 ]
+
+Since commit e3c548323d32 ("f2fs: let's allow compression for mmap files"),
+it has been allowed to compress mmap files. However, in compress_mode=user,
+it is not allowed yet. To keep the same concept in both compress_modes,
+f2fs_ioc_(de)compress_file() should also allow it.
+
+Let's remove checking mmap files in f2fs_ioc_(de)compress_file() so that
+the compression for mmap files is also allowed in compress_mode=user.
+
+Signed-off-by: Sungjong Seo <sj1557.seo@samsung.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 863518695ea6..9a676ea080e4 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -3914,11 +3914,6 @@ static int f2fs_ioc_decompress_file(struct file *filp, unsigned long arg)
+ goto out;
+ }
+
+- if (f2fs_is_mmap_file(inode)) {
+- ret = -EBUSY;
+- goto out;
+- }
+-
+ ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
+ if (ret)
+ goto out;
+@@ -3986,11 +3981,6 @@ static int f2fs_ioc_compress_file(struct file *filp, unsigned long arg)
+ goto out;
+ }
+
+- if (f2fs_is_mmap_file(inode)) {
+- ret = -EBUSY;
+- goto out;
+- }
+-
+ ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
+ if (ret)
+ goto out;
+--
+2.35.1
+
--- /dev/null
+From 7149f44a58d0ef0ea1bfccf9e131b4029bae9004 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Apr 2022 11:18:09 -0700
+Subject: f2fs: change the current atomic write way
+
+From: Daeho Jeong <daehojeong@google.com>
+
+[ Upstream commit 3db1de0e582c358dd013f3703cd55b5fe4076436 ]
+
+Current atomic write has three major issues like below.
+ - keeps the updates in non-reclaimable memory space and they are even
+ hard to be migrated, which is not good for contiguous memory
+ allocation.
+ - disk spaces used for atomic files cannot be garbage collected, so
+ this makes it difficult for the filesystem to be defragmented.
+ - If atomic write operations hit the threshold of either memory usage
+ or garbage collection failure count, All the atomic write operations
+ will fail immediately.
+
+To resolve the issues, I will keep a COW inode internally for all the
+updates to be flushed from memory, when we need to flush them out in a
+situation like high memory pressure. These COW inodes will be tagged
+as orphan inodes to be reclaimed in case of sudden power-cut or system
+failure during atomic writes.
+
+Signed-off-by: Daeho Jeong <daehojeong@google.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/data.c | 180 +++++++++++------
+ fs/f2fs/debug.c | 12 +-
+ fs/f2fs/f2fs.h | 33 +---
+ fs/f2fs/file.c | 49 ++---
+ fs/f2fs/gc.c | 27 +--
+ fs/f2fs/inode.c | 3 +-
+ fs/f2fs/namei.c | 28 ++-
+ fs/f2fs/node.c | 4 -
+ fs/f2fs/node.h | 1 -
+ fs/f2fs/segment.c | 380 ++++++++++++------------------------
+ fs/f2fs/segment.h | 4 +-
+ fs/f2fs/super.c | 6 +-
+ include/trace/events/f2fs.h | 22 ---
+ 13 files changed, 303 insertions(+), 446 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 1862b03a9982..4c1603a79745 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -69,8 +69,7 @@ static bool __is_cp_guaranteed(struct page *page)
+
+ if (f2fs_is_compressed_page(page))
+ return false;
+- if ((S_ISREG(inode->i_mode) &&
+- (f2fs_is_atomic_file(inode) || IS_NOQUOTA(inode))) ||
++ if ((S_ISREG(inode->i_mode) && IS_NOQUOTA(inode)) ||
+ page_private_gcing(page))
+ return true;
+ return false;
+@@ -2566,7 +2565,12 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
+ bool ipu_force = false;
+ int err = 0;
+
+- set_new_dnode(&dn, inode, NULL, NULL, 0);
++ /* Use COW inode to make dnode_of_data for atomic write */
++ if (f2fs_is_atomic_file(inode))
++ set_new_dnode(&dn, F2FS_I(inode)->cow_inode, NULL, NULL, 0);
++ else
++ set_new_dnode(&dn, inode, NULL, NULL, 0);
++
+ if (need_inplace_update(fio) &&
+ f2fs_lookup_extent_cache(inode, page->index, &ei)) {
+ fio->old_blkaddr = ei.blk + page->index - ei.fofs;
+@@ -2603,6 +2607,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
+ err = -EFSCORRUPTED;
+ goto out_writepage;
+ }
++
+ /*
+ * If current allocation needs SSR,
+ * it had better in-place writes for updated data.
+@@ -3316,6 +3321,100 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
+ return err;
+ }
+
++static int __find_data_block(struct inode *inode, pgoff_t index,
++ block_t *blk_addr)
++{
++ struct dnode_of_data dn;
++ struct page *ipage;
++ struct extent_info ei = {0, };
++ int err = 0;
++
++ ipage = f2fs_get_node_page(F2FS_I_SB(inode), inode->i_ino);
++ if (IS_ERR(ipage))
++ return PTR_ERR(ipage);
++
++ set_new_dnode(&dn, inode, ipage, ipage, 0);
++
++ if (f2fs_lookup_extent_cache(inode, index, &ei)) {
++ dn.data_blkaddr = ei.blk + index - ei.fofs;
++ } else {
++ /* hole case */
++ err = f2fs_get_dnode_of_data(&dn, index, LOOKUP_NODE);
++ if (err) {
++ dn.data_blkaddr = NULL_ADDR;
++ err = 0;
++ }
++ }
++ *blk_addr = dn.data_blkaddr;
++ f2fs_put_dnode(&dn);
++ return err;
++}
++
++static int __reserve_data_block(struct inode *inode, pgoff_t index,
++ block_t *blk_addr, bool *node_changed)
++{
++ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
++ struct dnode_of_data dn;
++ struct page *ipage;
++ int err = 0;
++
++ f2fs_do_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO, true);
++
++ ipage = f2fs_get_node_page(sbi, inode->i_ino);
++ if (IS_ERR(ipage)) {
++ err = PTR_ERR(ipage);
++ goto unlock_out;
++ }
++ set_new_dnode(&dn, inode, ipage, ipage, 0);
++
++ err = f2fs_get_block(&dn, index);
++
++ *blk_addr = dn.data_blkaddr;
++ *node_changed = dn.node_changed;
++ f2fs_put_dnode(&dn);
++
++unlock_out:
++ f2fs_do_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO, false);
++ return err;
++}
++
++static int prepare_atomic_write_begin(struct f2fs_sb_info *sbi,
++ struct page *page, loff_t pos, unsigned int len,
++ block_t *blk_addr, bool *node_changed)
++{
++ struct inode *inode = page->mapping->host;
++ struct inode *cow_inode = F2FS_I(inode)->cow_inode;
++ pgoff_t index = page->index;
++ int err = 0;
++ block_t ori_blk_addr;
++
++ /* If pos is beyond the end of file, reserve a new block in COW inode */
++ if ((pos & PAGE_MASK) >= i_size_read(inode))
++ return __reserve_data_block(cow_inode, index, blk_addr,
++ node_changed);
++
++ /* Look for the block in COW inode first */
++ err = __find_data_block(cow_inode, index, blk_addr);
++ if (err)
++ return err;
++ else if (*blk_addr != NULL_ADDR)
++ return 0;
++
++ /* Look for the block in the original inode */
++ err = __find_data_block(inode, index, &ori_blk_addr);
++ if (err)
++ return err;
++
++ /* Finally, we should reserve a new block in COW inode for the update */
++ err = __reserve_data_block(cow_inode, index, blk_addr, node_changed);
++ if (err)
++ return err;
++
++ if (ori_blk_addr != NULL_ADDR)
++ *blk_addr = ori_blk_addr;
++ return 0;
++}
++
+ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+@@ -3324,7 +3423,7 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct page *page = NULL;
+ pgoff_t index = ((unsigned long long) pos) >> PAGE_SHIFT;
+- bool need_balance = false, drop_atomic = false;
++ bool need_balance = false;
+ block_t blkaddr = NULL_ADDR;
+ int err = 0;
+
+@@ -3335,14 +3434,6 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
+ goto fail;
+ }
+
+- if ((f2fs_is_atomic_file(inode) &&
+- !f2fs_available_free_memory(sbi, INMEM_PAGES)) ||
+- is_inode_flag_set(inode, FI_ATOMIC_REVOKE_REQUEST)) {
+- err = -ENOMEM;
+- drop_atomic = true;
+- goto fail;
+- }
+-
+ /*
+ * We should check this at this moment to avoid deadlock on inode page
+ * and #0 page. The locking rule for inline_data conversion should be:
+@@ -3390,7 +3481,11 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
+
+ *pagep = page;
+
+- err = prepare_write_begin(sbi, page, pos, len,
++ if (f2fs_is_atomic_file(inode))
++ err = prepare_atomic_write_begin(sbi, page, pos, len,
++ &blkaddr, &need_balance);
++ else
++ err = prepare_write_begin(sbi, page, pos, len,
+ &blkaddr, &need_balance);
+ if (err)
+ goto fail;
+@@ -3446,8 +3541,6 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
+ fail:
+ f2fs_put_page(page, 1);
+ f2fs_write_failed(inode, pos + len);
+- if (drop_atomic)
+- f2fs_drop_inmem_pages_all(sbi, false);
+ return err;
+ }
+
+@@ -3491,8 +3584,12 @@ static int f2fs_write_end(struct file *file,
+ set_page_dirty(page);
+
+ if (pos + copied > i_size_read(inode) &&
+- !f2fs_verity_in_progress(inode))
++ !f2fs_verity_in_progress(inode)) {
+ f2fs_i_size_write(inode, pos + copied);
++ if (f2fs_is_atomic_file(inode))
++ f2fs_i_size_write(F2FS_I(inode)->cow_inode,
++ pos + copied);
++ }
+ unlock_out:
+ f2fs_put_page(page, 1);
+ f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
+@@ -3525,9 +3622,6 @@ void f2fs_invalidate_folio(struct folio *folio, size_t offset, size_t length)
+ inode->i_ino == F2FS_COMPRESS_INO(sbi))
+ clear_page_private_data(&folio->page);
+
+- if (page_private_atomic(&folio->page))
+- return f2fs_drop_inmem_page(inode, &folio->page);
+-
+ folio_detach_private(folio);
+ }
+
+@@ -3537,10 +3631,6 @@ int f2fs_release_page(struct page *page, gfp_t wait)
+ if (PageDirty(page))
+ return 0;
+
+- /* This is atomic written page, keep Private */
+- if (page_private_atomic(page))
+- return 0;
+-
+ if (test_opt(F2FS_P_SB(page), COMPRESS_CACHE)) {
+ struct inode *inode = page->mapping->host;
+
+@@ -3566,18 +3656,6 @@ static bool f2fs_dirty_data_folio(struct address_space *mapping,
+ folio_mark_uptodate(folio);
+ BUG_ON(folio_test_swapcache(folio));
+
+- if (f2fs_is_atomic_file(inode) && !f2fs_is_commit_atomic_write(inode)) {
+- if (!page_private_atomic(&folio->page)) {
+- f2fs_register_inmem_page(inode, &folio->page);
+- return true;
+- }
+- /*
+- * Previously, this page has been registered, we just
+- * return here.
+- */
+- return false;
+- }
+-
+ if (!folio_test_dirty(folio)) {
+ filemap_dirty_folio(mapping, folio);
+ f2fs_update_dirty_folio(inode, folio);
+@@ -3657,42 +3735,14 @@ static sector_t f2fs_bmap(struct address_space *mapping, sector_t block)
+ int f2fs_migrate_page(struct address_space *mapping,
+ struct page *newpage, struct page *page, enum migrate_mode mode)
+ {
+- int rc, extra_count;
+- struct f2fs_inode_info *fi = F2FS_I(mapping->host);
+- bool atomic_written = page_private_atomic(page);
++ int rc, extra_count = 0;
+
+ BUG_ON(PageWriteback(page));
+
+- /* migrating an atomic written page is safe with the inmem_lock hold */
+- if (atomic_written) {
+- if (mode != MIGRATE_SYNC)
+- return -EBUSY;
+- if (!mutex_trylock(&fi->inmem_lock))
+- return -EAGAIN;
+- }
+-
+- /* one extra reference was held for atomic_write page */
+- extra_count = atomic_written ? 1 : 0;
+ rc = migrate_page_move_mapping(mapping, newpage,
+ page, extra_count);
+- if (rc != MIGRATEPAGE_SUCCESS) {
+- if (atomic_written)
+- mutex_unlock(&fi->inmem_lock);
++ if (rc != MIGRATEPAGE_SUCCESS)
+ return rc;
+- }
+-
+- if (atomic_written) {
+- struct inmem_pages *cur;
+-
+- list_for_each_entry(cur, &fi->inmem_pages, list)
+- if (cur->page == page) {
+- cur->page = newpage;
+- break;
+- }
+- mutex_unlock(&fi->inmem_lock);
+- put_page(page);
+- get_page(newpage);
+- }
+
+ /* guarantee to start from no stale private field */
+ set_page_private(newpage, 0);
+diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
+index fcdf253cd211..65f0bcf498bb 100644
+--- a/fs/f2fs/debug.c
++++ b/fs/f2fs/debug.c
+@@ -91,7 +91,6 @@ static void update_general_status(struct f2fs_sb_info *sbi)
+ si->ndirty_files = sbi->ndirty_inode[FILE_INODE];
+ si->nquota_files = sbi->nquota_files;
+ si->ndirty_all = sbi->ndirty_inode[DIRTY_META];
+- si->inmem_pages = get_pages(sbi, F2FS_INMEM_PAGES);
+ si->aw_cnt = sbi->atomic_files;
+ si->vw_cnt = atomic_read(&sbi->vw_cnt);
+ si->max_aw_cnt = atomic_read(&sbi->max_aw_cnt);
+@@ -167,8 +166,6 @@ static void update_general_status(struct f2fs_sb_info *sbi)
+ si->alloc_nids = NM_I(sbi)->nid_cnt[PREALLOC_NID];
+ si->io_skip_bggc = sbi->io_skip_bggc;
+ si->other_skip_bggc = sbi->other_skip_bggc;
+- si->skipped_atomic_files[BG_GC] = sbi->skipped_atomic_files[BG_GC];
+- si->skipped_atomic_files[FG_GC] = sbi->skipped_atomic_files[FG_GC];
+ si->util_free = (int)(free_user_blocks(sbi) >> sbi->log_blocks_per_seg)
+ * 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
+ / 2;
+@@ -296,7 +293,6 @@ static void update_mem_info(struct f2fs_sb_info *sbi)
+ sizeof(struct nat_entry);
+ si->cache_mem += NM_I(sbi)->nat_cnt[DIRTY_NAT] *
+ sizeof(struct nat_entry_set);
+- si->cache_mem += si->inmem_pages * sizeof(struct inmem_pages);
+ for (i = 0; i < MAX_INO_ENTRY; i++)
+ si->cache_mem += sbi->im[i].ino_num * sizeof(struct ino_entry);
+ si->cache_mem += atomic_read(&sbi->total_ext_tree) *
+@@ -491,10 +487,6 @@ static int stat_show(struct seq_file *s, void *v)
+ si->bg_data_blks);
+ seq_printf(s, " - node blocks : %d (%d)\n", si->node_blks,
+ si->bg_node_blks);
+- seq_printf(s, "Skipped : atomic write %llu (%llu)\n",
+- si->skipped_atomic_files[BG_GC] +
+- si->skipped_atomic_files[FG_GC],
+- si->skipped_atomic_files[BG_GC]);
+ seq_printf(s, "BG skip : IO: %u, Other: %u\n",
+ si->io_skip_bggc, si->other_skip_bggc);
+ seq_puts(s, "\nExtent Cache:\n");
+@@ -519,9 +511,9 @@ static int stat_show(struct seq_file *s, void *v)
+ si->flush_list_empty,
+ si->nr_discarding, si->nr_discarded,
+ si->nr_discard_cmd, si->undiscard_blks);
+- seq_printf(s, " - inmem: %4d, atomic IO: %4d (Max. %4d), "
++ seq_printf(s, " - atomic IO: %4d (Max. %4d), "
+ "volatile IO: %4d (Max. %4d)\n",
+- si->inmem_pages, si->aw_cnt, si->max_aw_cnt,
++ si->aw_cnt, si->max_aw_cnt,
+ si->vw_cnt, si->max_vw_cnt);
+ seq_printf(s, " - compress: %4d, hit:%8d\n", si->compress_pages, si->compress_page_hit);
+ seq_printf(s, " - nodes: %4d in %4d\n",
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 9b89f26af1f3..13140b753ba1 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -716,7 +716,6 @@ enum {
+
+ enum {
+ GC_FAILURE_PIN,
+- GC_FAILURE_ATOMIC,
+ MAX_GC_FAILURE
+ };
+
+@@ -738,7 +737,6 @@ enum {
+ FI_UPDATE_WRITE, /* inode has in-place-update data */
+ FI_NEED_IPU, /* used for ipu per file */
+ FI_ATOMIC_FILE, /* indicate atomic file */
+- FI_ATOMIC_COMMIT, /* indicate the state of atomical committing */
+ FI_VOLATILE_FILE, /* indicate volatile file */
+ FI_FIRST_BLOCK_WRITTEN, /* indicate #0 data block was written */
+ FI_DROP_CACHE, /* drop dirty page cache */
+@@ -752,7 +750,6 @@ enum {
+ FI_EXTRA_ATTR, /* indicate file has extra attribute */
+ FI_PROJ_INHERIT, /* indicate file inherits projectid */
+ FI_PIN_FILE, /* indicate file should not be gced */
+- FI_ATOMIC_REVOKE_REQUEST, /* request to drop atomic data */
+ FI_VERITY_IN_PROGRESS, /* building fs-verity Merkle tree */
+ FI_COMPRESSED_FILE, /* indicate file's data can be compressed */
+ FI_COMPRESS_CORRUPT, /* indicate compressed cluster is corrupted */
+@@ -794,11 +791,9 @@ struct f2fs_inode_info {
+ #endif
+ struct list_head dirty_list; /* dirty list for dirs and files */
+ struct list_head gdirty_list; /* linked in global dirty list */
+- struct list_head inmem_ilist; /* list for inmem inodes */
+- struct list_head inmem_pages; /* inmemory pages managed by f2fs */
+- struct task_struct *inmem_task; /* store inmemory task */
+- struct mutex inmem_lock; /* lock for inmemory pages */
++ struct task_struct *atomic_write_task; /* store atomic write task */
+ struct extent_tree *extent_tree; /* cached extent_tree entry */
++ struct inode *cow_inode; /* copy-on-write inode for atomic write */
+
+ /* avoid racing between foreground op and gc */
+ struct f2fs_rwsem i_gc_rwsem[2];
+@@ -1092,7 +1087,6 @@ enum count_type {
+ F2FS_DIRTY_QDATA,
+ F2FS_DIRTY_NODES,
+ F2FS_DIRTY_META,
+- F2FS_INMEM_PAGES,
+ F2FS_DIRTY_IMETA,
+ F2FS_WB_CP_DATA,
+ F2FS_WB_DATA,
+@@ -1122,11 +1116,7 @@ enum page_type {
+ META,
+ NR_PAGE_TYPE,
+ META_FLUSH,
+- INMEM, /* the below types are used by tracepoints only. */
+- INMEM_DROP,
+- INMEM_INVALIDATE,
+- INMEM_REVOKE,
+- IPU,
++ IPU, /* the below types are used by tracepoints only. */
+ OPU,
+ };
+
+@@ -1718,7 +1708,6 @@ struct f2fs_sb_info {
+
+ /* for skip statistic */
+ unsigned int atomic_files; /* # of opened atomic file */
+- unsigned long long skipped_atomic_files[2]; /* FG_GC and BG_GC */
+ unsigned long long skipped_gc_rwsem; /* FG_GC only */
+
+ /* threshold for gc trials on pinned files */
+@@ -3202,11 +3191,6 @@ static inline bool f2fs_is_atomic_file(struct inode *inode)
+ return is_inode_flag_set(inode, FI_ATOMIC_FILE);
+ }
+
+-static inline bool f2fs_is_commit_atomic_write(struct inode *inode)
+-{
+- return is_inode_flag_set(inode, FI_ATOMIC_COMMIT);
+-}
+-
+ static inline bool f2fs_is_volatile_file(struct inode *inode)
+ {
+ return is_inode_flag_set(inode, FI_VOLATILE_FILE);
+@@ -3444,6 +3428,8 @@ void f2fs_handle_failed_inode(struct inode *inode);
+ int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
+ bool hot, bool set);
+ struct dentry *f2fs_get_parent(struct dentry *child);
++int f2fs_get_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
++ struct inode **new_inode);
+
+ /*
+ * dir.c
+@@ -3579,11 +3565,8 @@ void f2fs_destroy_node_manager_caches(void);
+ * segment.c
+ */
+ bool f2fs_need_SSR(struct f2fs_sb_info *sbi);
+-void f2fs_register_inmem_page(struct inode *inode, struct page *page);
+-void f2fs_drop_inmem_pages_all(struct f2fs_sb_info *sbi, bool gc_failure);
+-void f2fs_drop_inmem_pages(struct inode *inode);
+-void f2fs_drop_inmem_page(struct inode *inode, struct page *page);
+-int f2fs_commit_inmem_pages(struct inode *inode);
++int f2fs_commit_atomic_write(struct inode *inode);
++void f2fs_abort_atomic_write(struct inode *inode, bool clean);
+ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need);
+ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi, bool from_bg);
+ int f2fs_issue_flush(struct f2fs_sb_info *sbi, nid_t ino);
+@@ -3815,7 +3798,6 @@ struct f2fs_stat_info {
+ int ext_tree, zombie_tree, ext_node;
+ int ndirty_node, ndirty_dent, ndirty_meta, ndirty_imeta;
+ int ndirty_data, ndirty_qdata;
+- int inmem_pages;
+ unsigned int ndirty_dirs, ndirty_files, nquota_files, ndirty_all;
+ int nats, dirty_nats, sits, dirty_sits;
+ int free_nids, avail_nids, alloc_nids;
+@@ -3845,7 +3827,6 @@ struct f2fs_stat_info {
+ int bg_node_segs, bg_data_segs;
+ int tot_blks, data_blks, node_blks;
+ int bg_data_blks, bg_node_blks;
+- unsigned long long skipped_atomic_files[2];
+ int curseg[NR_CURSEG_TYPE];
+ int cursec[NR_CURSEG_TYPE];
+ int curzone[NR_CURSEG_TYPE];
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 5d1b97e852e7..9b04a7a0a368 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1816,9 +1816,8 @@ static int f2fs_release_file(struct inode *inode, struct file *filp)
+ atomic_read(&inode->i_writecount) != 1)
+ return 0;
+
+- /* some remained atomic pages should discarded */
+ if (f2fs_is_atomic_file(inode))
+- f2fs_drop_inmem_pages(inode);
++ f2fs_abort_atomic_write(inode, true);
+ if (f2fs_is_volatile_file(inode)) {
+ set_inode_flag(inode, FI_DROP_CACHE);
+ filemap_fdatawrite(inode->i_mapping);
+@@ -1840,8 +1839,8 @@ static int f2fs_file_flush(struct file *file, fl_owner_t id)
+ * before dropping file lock, it needs to do in ->flush.
+ */
+ if (f2fs_is_atomic_file(inode) &&
+- F2FS_I(inode)->inmem_task == current)
+- f2fs_drop_inmem_pages(inode);
++ F2FS_I(inode)->atomic_write_task == current)
++ f2fs_abort_atomic_write(inode, true);
+ return 0;
+ }
+
+@@ -2004,6 +2003,7 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
+ struct user_namespace *mnt_userns = file_mnt_user_ns(filp);
+ struct f2fs_inode_info *fi = F2FS_I(inode);
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
++ struct inode *pinode;
+ int ret;
+
+ if (!inode_owner_or_capable(mnt_userns, inode))
+@@ -2026,11 +2026,8 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
+ goto out;
+ }
+
+- if (f2fs_is_atomic_file(inode)) {
+- if (is_inode_flag_set(inode, FI_ATOMIC_REVOKE_REQUEST))
+- ret = -EINVAL;
++ if (f2fs_is_atomic_file(inode))
+ goto out;
+- }
+
+ ret = f2fs_convert_inline_inode(inode);
+ if (ret)
+@@ -2051,19 +2048,33 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
+ goto out;
+ }
+
++ /* Create a COW inode for atomic write */
++ pinode = f2fs_iget(inode->i_sb, fi->i_pino);
++ if (IS_ERR(pinode)) {
++ f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
++ ret = PTR_ERR(pinode);
++ goto out;
++ }
++
++ ret = f2fs_get_tmpfile(mnt_userns, pinode, &fi->cow_inode);
++ iput(pinode);
++ if (ret) {
++ f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
++ goto out;
++ }
++ f2fs_i_size_write(fi->cow_inode, i_size_read(inode));
++
+ spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
+- if (list_empty(&fi->inmem_ilist))
+- list_add_tail(&fi->inmem_ilist, &sbi->inode_list[ATOMIC_FILE]);
+ sbi->atomic_files++;
+ spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
+
+- /* add inode in inmem_list first and set atomic_file */
+ set_inode_flag(inode, FI_ATOMIC_FILE);
+- clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
++ set_inode_flag(fi->cow_inode, FI_ATOMIC_FILE);
++ clear_inode_flag(fi->cow_inode, FI_INLINE_DATA);
+ f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+
+ f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
+- F2FS_I(inode)->inmem_task = current;
++ F2FS_I(inode)->atomic_write_task = current;
+ stat_update_max_atomic_write(inode);
+ out:
+ inode_unlock(inode);
+@@ -2094,21 +2105,17 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
+ }
+
+ if (f2fs_is_atomic_file(inode)) {
+- ret = f2fs_commit_inmem_pages(inode);
++ ret = f2fs_commit_atomic_write(inode);
+ if (ret)
+ goto err_out;
+
+ ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true);
+ if (!ret)
+- f2fs_drop_inmem_pages(inode);
++ f2fs_abort_atomic_write(inode, false);
+ } else {
+ ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 1, false);
+ }
+ err_out:
+- if (is_inode_flag_set(inode, FI_ATOMIC_REVOKE_REQUEST)) {
+- clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
+- ret = -EINVAL;
+- }
+ inode_unlock(inode);
+ mnt_drop_write_file(filp);
+ return ret;
+@@ -2196,15 +2203,13 @@ static int f2fs_ioc_abort_volatile_write(struct file *filp)
+ inode_lock(inode);
+
+ if (f2fs_is_atomic_file(inode))
+- f2fs_drop_inmem_pages(inode);
++ f2fs_abort_atomic_write(inode, true);
+ if (f2fs_is_volatile_file(inode)) {
+ clear_inode_flag(inode, FI_VOLATILE_FILE);
+ stat_dec_volatile_write(inode);
+ ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true);
+ }
+
+- clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
+-
+ inode_unlock(inode);
+
+ mnt_drop_write_file(filp);
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 3009c0a97ab4..ba8e93e517be 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1245,13 +1245,6 @@ static int move_data_block(struct inode *inode, block_t bidx,
+ goto out;
+ }
+
+- if (f2fs_is_atomic_file(inode)) {
+- F2FS_I(inode)->i_gc_failures[GC_FAILURE_ATOMIC]++;
+- F2FS_I_SB(inode)->skipped_atomic_files[gc_type]++;
+- err = -EAGAIN;
+- goto out;
+- }
+-
+ err = f2fs_gc_pinned_control(inode, gc_type, segno);
+ if (err)
+ goto out;
+@@ -1393,12 +1386,6 @@ static int move_data_page(struct inode *inode, block_t bidx, int gc_type,
+ goto out;
+ }
+
+- if (f2fs_is_atomic_file(inode)) {
+- F2FS_I(inode)->i_gc_failures[GC_FAILURE_ATOMIC]++;
+- F2FS_I_SB(inode)->skipped_atomic_files[gc_type]++;
+- err = -EAGAIN;
+- goto out;
+- }
+ err = f2fs_gc_pinned_control(inode, gc_type, segno);
+ if (err)
+ goto out;
+@@ -1765,8 +1752,6 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
+ .ilist = LIST_HEAD_INIT(gc_list.ilist),
+ .iroot = RADIX_TREE_INIT(gc_list.iroot, GFP_NOFS),
+ };
+- unsigned long long last_skipped = sbi->skipped_atomic_files[FG_GC];
+- unsigned long long first_skipped;
+ unsigned int skipped_round = 0, round = 0;
+
+ trace_f2fs_gc_begin(sbi->sb, sync, background,
+@@ -1780,7 +1765,6 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
+
+ cpc.reason = __get_cp_reason(sbi);
+ sbi->skipped_gc_rwsem = 0;
+- first_skipped = last_skipped;
+ gc_more:
+ if (unlikely(!(sbi->sb->s_flags & SB_ACTIVE))) {
+ ret = -EINVAL;
+@@ -1831,10 +1815,8 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
+ total_freed += seg_freed;
+
+ if (gc_type == FG_GC) {
+- if (sbi->skipped_atomic_files[FG_GC] > last_skipped ||
+- sbi->skipped_gc_rwsem)
++ if (sbi->skipped_gc_rwsem)
+ skipped_round++;
+- last_skipped = sbi->skipped_atomic_files[FG_GC];
+ round++;
+ }
+
+@@ -1860,13 +1842,6 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
+ segno = NULL_SEGNO;
+ goto gc_more;
+ }
+- if (first_skipped < last_skipped &&
+- (last_skipped - first_skipped) >
+- sbi->skipped_gc_rwsem) {
+- f2fs_drop_inmem_pages_all(sbi, true);
+- segno = NULL_SEGNO;
+- goto gc_more;
+- }
+ if (gc_type == FG_GC && !is_sbi_flag_set(sbi, SBI_CP_DISABLED))
+ ret = f2fs_write_checkpoint(sbi, &cpc);
+ stop:
+diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
+index e9818723103c..938961a9084e 100644
+--- a/fs/f2fs/inode.c
++++ b/fs/f2fs/inode.c
+@@ -744,9 +744,8 @@ void f2fs_evict_inode(struct inode *inode)
+ nid_t xnid = F2FS_I(inode)->i_xattr_nid;
+ int err = 0;
+
+- /* some remained atomic pages should discarded */
+ if (f2fs_is_atomic_file(inode))
+- f2fs_drop_inmem_pages(inode);
++ f2fs_abort_atomic_write(inode, true);
+
+ trace_f2fs_evict_inode(inode);
+ truncate_inode_pages_final(&inode->i_data);
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index 3764e12f19db..28d5981443a7 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -848,8 +848,8 @@ static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
+ }
+
+ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
+- struct dentry *dentry, umode_t mode,
+- struct inode **whiteout)
++ struct dentry *dentry, umode_t mode, bool is_whiteout,
++ struct inode **new_inode)
+ {
+ struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
+ struct inode *inode;
+@@ -863,7 +863,7 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
+ if (IS_ERR(inode))
+ return PTR_ERR(inode);
+
+- if (whiteout) {
++ if (is_whiteout) {
+ init_special_inode(inode, inode->i_mode, WHITEOUT_DEV);
+ inode->i_op = &f2fs_special_inode_operations;
+ } else {
+@@ -888,21 +888,25 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
+ f2fs_add_orphan_inode(inode);
+ f2fs_alloc_nid_done(sbi, inode->i_ino);
+
+- if (whiteout) {
++ if (is_whiteout) {
+ f2fs_i_links_write(inode, false);
+
+ spin_lock(&inode->i_lock);
+ inode->i_state |= I_LINKABLE;
+ spin_unlock(&inode->i_lock);
+-
+- *whiteout = inode;
+ } else {
+- d_tmpfile(dentry, inode);
++ if (dentry)
++ d_tmpfile(dentry, inode);
++ else
++ f2fs_i_links_write(inode, false);
+ }
+ /* link_count was changed by d_tmpfile as well. */
+ f2fs_unlock_op(sbi);
+ unlock_new_inode(inode);
+
++ if (new_inode)
++ *new_inode = inode;
++
+ f2fs_balance_fs(sbi, true);
+ return 0;
+
+@@ -923,7 +927,7 @@ static int f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
+ if (!f2fs_is_checkpoint_ready(sbi))
+ return -ENOSPC;
+
+- return __f2fs_tmpfile(mnt_userns, dir, dentry, mode, NULL);
++ return __f2fs_tmpfile(mnt_userns, dir, dentry, mode, false, NULL);
+ }
+
+ static int f2fs_create_whiteout(struct user_namespace *mnt_userns,
+@@ -933,7 +937,13 @@ static int f2fs_create_whiteout(struct user_namespace *mnt_userns,
+ return -EIO;
+
+ return __f2fs_tmpfile(mnt_userns, dir, NULL,
+- S_IFCHR | WHITEOUT_MODE, whiteout);
++ S_IFCHR | WHITEOUT_MODE, true, whiteout);
++}
++
++int f2fs_get_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
++ struct inode **new_inode)
++{
++ return __f2fs_tmpfile(mnt_userns, dir, NULL, S_IFREG, false, new_inode);
+ }
+
+ static int f2fs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index aedc3d334113..9dabf99eedc5 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -90,10 +90,6 @@ bool f2fs_available_free_memory(struct f2fs_sb_info *sbi, int type)
+ atomic_read(&sbi->total_ext_node) *
+ sizeof(struct extent_node)) >> PAGE_SHIFT;
+ res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1);
+- } else if (type == INMEM_PAGES) {
+- /* it allows 20% / total_ram for inmemory pages */
+- mem_size = get_pages(sbi, F2FS_INMEM_PAGES);
+- res = mem_size < (val.totalram / 5);
+ } else if (type == DISCARD_CACHE) {
+ mem_size = (atomic_read(&dcc->discard_cmd_cnt) *
+ sizeof(struct discard_cmd)) >> PAGE_SHIFT;
+diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h
+index 4c1d34bfea78..3c09cae058b0 100644
+--- a/fs/f2fs/node.h
++++ b/fs/f2fs/node.h
+@@ -147,7 +147,6 @@ enum mem_type {
+ DIRTY_DENTS, /* indicates dirty dentry pages */
+ INO_ENTRIES, /* indicates inode entries */
+ EXTENT_CACHE, /* indicates extent cache */
+- INMEM_PAGES, /* indicates inmemory pages */
+ DISCARD_CACHE, /* indicates memory of cached discard cmds */
+ COMPRESS_PAGE, /* indicates memory of cached compressed pages */
+ BASE_CHECK, /* check kernel status */
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index a914b70f8543..86a3c5a5a564 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -30,7 +30,7 @@
+ static struct kmem_cache *discard_entry_slab;
+ static struct kmem_cache *discard_cmd_slab;
+ static struct kmem_cache *sit_entry_set_slab;
+-static struct kmem_cache *inmem_entry_slab;
++static struct kmem_cache *revoke_entry_slab;
+
+ static unsigned long __reverse_ulong(unsigned char *str)
+ {
+@@ -185,304 +185,180 @@ bool f2fs_need_SSR(struct f2fs_sb_info *sbi)
+ SM_I(sbi)->min_ssr_sections + reserved_sections(sbi));
+ }
+
+-void f2fs_register_inmem_page(struct inode *inode, struct page *page)
++void f2fs_abort_atomic_write(struct inode *inode, bool clean)
+ {
+- struct inmem_pages *new;
+-
+- set_page_private_atomic(page);
+-
+- new = f2fs_kmem_cache_alloc(inmem_entry_slab,
+- GFP_NOFS, true, NULL);
+-
+- /* add atomic page indices to the list */
+- new->page = page;
+- INIT_LIST_HEAD(&new->list);
++ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
++ struct f2fs_inode_info *fi = F2FS_I(inode);
+
+- /* increase reference count with clean state */
+- get_page(page);
+- mutex_lock(&F2FS_I(inode)->inmem_lock);
+- list_add_tail(&new->list, &F2FS_I(inode)->inmem_pages);
+- inc_page_count(F2FS_I_SB(inode), F2FS_INMEM_PAGES);
+- mutex_unlock(&F2FS_I(inode)->inmem_lock);
++ if (f2fs_is_atomic_file(inode)) {
++ if (clean)
++ truncate_inode_pages_final(inode->i_mapping);
++ clear_inode_flag(fi->cow_inode, FI_ATOMIC_FILE);
++ iput(fi->cow_inode);
++ fi->cow_inode = NULL;
++ clear_inode_flag(inode, FI_ATOMIC_FILE);
+
+- trace_f2fs_register_inmem_page(page, INMEM);
++ spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
++ sbi->atomic_files--;
++ spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
++ }
+ }
+
+-static int __revoke_inmem_pages(struct inode *inode,
+- struct list_head *head, bool drop, bool recover,
+- bool trylock)
++static int __replace_atomic_write_block(struct inode *inode, pgoff_t index,
++ block_t new_addr, block_t *old_addr, bool recover)
+ {
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+- struct inmem_pages *cur, *tmp;
+- int err = 0;
+-
+- list_for_each_entry_safe(cur, tmp, head, list) {
+- struct page *page = cur->page;
+-
+- if (drop)
+- trace_f2fs_commit_inmem_page(page, INMEM_DROP);
+-
+- if (trylock) {
+- /*
+- * to avoid deadlock in between page lock and
+- * inmem_lock.
+- */
+- if (!trylock_page(page))
+- continue;
+- } else {
+- lock_page(page);
+- }
+-
+- f2fs_wait_on_page_writeback(page, DATA, true, true);
+-
+- if (recover) {
+- struct dnode_of_data dn;
+- struct node_info ni;
++ struct dnode_of_data dn;
++ struct node_info ni;
++ int err;
+
+- trace_f2fs_commit_inmem_page(page, INMEM_REVOKE);
+ retry:
+- set_new_dnode(&dn, inode, NULL, NULL, 0);
+- err = f2fs_get_dnode_of_data(&dn, page->index,
+- LOOKUP_NODE);
+- if (err) {
+- if (err == -ENOMEM) {
+- memalloc_retry_wait(GFP_NOFS);
+- goto retry;
+- }
+- err = -EAGAIN;
+- goto next;
+- }
+-
+- err = f2fs_get_node_info(sbi, dn.nid, &ni, false);
+- if (err) {
+- f2fs_put_dnode(&dn);
+- return err;
+- }
+-
+- if (cur->old_addr == NEW_ADDR) {
+- f2fs_invalidate_blocks(sbi, dn.data_blkaddr);
+- f2fs_update_data_blkaddr(&dn, NEW_ADDR);
+- } else
+- f2fs_replace_block(sbi, &dn, dn.data_blkaddr,
+- cur->old_addr, ni.version, true, true);
+- f2fs_put_dnode(&dn);
+- }
+-next:
+- /* we don't need to invalidate this in the sccessful status */
+- if (drop || recover) {
+- ClearPageUptodate(page);
+- clear_page_private_gcing(page);
++ set_new_dnode(&dn, inode, NULL, NULL, 0);
++ err = f2fs_get_dnode_of_data(&dn, index, LOOKUP_NODE_RA);
++ if (err) {
++ if (err == -ENOMEM) {
++ f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
++ goto retry;
+ }
+- detach_page_private(page);
+- set_page_private(page, 0);
+- f2fs_put_page(page, 1);
+-
+- list_del(&cur->list);
+- kmem_cache_free(inmem_entry_slab, cur);
+- dec_page_count(F2FS_I_SB(inode), F2FS_INMEM_PAGES);
++ return err;
+ }
+- return err;
+-}
+
+-void f2fs_drop_inmem_pages_all(struct f2fs_sb_info *sbi, bool gc_failure)
+-{
+- struct list_head *head = &sbi->inode_list[ATOMIC_FILE];
+- struct inode *inode;
+- struct f2fs_inode_info *fi;
+- unsigned int count = sbi->atomic_files;
+- unsigned int looped = 0;
+-next:
+- spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
+- if (list_empty(head)) {
+- spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
+- return;
++ err = f2fs_get_node_info(sbi, dn.nid, &ni, false);
++ if (err) {
++ f2fs_put_dnode(&dn);
++ return err;
+ }
+- fi = list_first_entry(head, struct f2fs_inode_info, inmem_ilist);
+- inode = igrab(&fi->vfs_inode);
+- if (inode)
+- list_move_tail(&fi->inmem_ilist, head);
+- spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
+
+- if (inode) {
+- if (gc_failure) {
+- if (!fi->i_gc_failures[GC_FAILURE_ATOMIC])
+- goto skip;
++ if (recover) {
++ /* dn.data_blkaddr is always valid */
++ if (!__is_valid_data_blkaddr(new_addr)) {
++ if (new_addr == NULL_ADDR)
++ dec_valid_block_count(sbi, inode, 1);
++ f2fs_invalidate_blocks(sbi, dn.data_blkaddr);
++ f2fs_update_data_blkaddr(&dn, new_addr);
++ } else {
++ f2fs_replace_block(sbi, &dn, dn.data_blkaddr,
++ new_addr, ni.version, true, true);
+ }
+- set_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
+- f2fs_drop_inmem_pages(inode);
+-skip:
+- iput(inode);
+- }
+- f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+- if (gc_failure) {
+- if (++looped >= count)
+- return;
+- }
+- goto next;
+-}
+-
+-void f2fs_drop_inmem_pages(struct inode *inode)
+-{
+- struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+- struct f2fs_inode_info *fi = F2FS_I(inode);
++ } else {
++ blkcnt_t count = 1;
+
+- do {
+- mutex_lock(&fi->inmem_lock);
+- if (list_empty(&fi->inmem_pages)) {
+- fi->i_gc_failures[GC_FAILURE_ATOMIC] = 0;
+-
+- spin_lock(&sbi->inode_lock[ATOMIC_FILE]);
+- if (!list_empty(&fi->inmem_ilist))
+- list_del_init(&fi->inmem_ilist);
+- if (f2fs_is_atomic_file(inode)) {
+- clear_inode_flag(inode, FI_ATOMIC_FILE);
+- sbi->atomic_files--;
+- }
+- spin_unlock(&sbi->inode_lock[ATOMIC_FILE]);
++ *old_addr = dn.data_blkaddr;
++ f2fs_truncate_data_blocks_range(&dn, 1);
++ dec_valid_block_count(sbi, F2FS_I(inode)->cow_inode, count);
++ inc_valid_block_count(sbi, inode, &count);
++ f2fs_replace_block(sbi, &dn, dn.data_blkaddr, new_addr,
++ ni.version, true, false);
++ }
+
+- mutex_unlock(&fi->inmem_lock);
+- break;
+- }
+- __revoke_inmem_pages(inode, &fi->inmem_pages,
+- true, false, true);
+- mutex_unlock(&fi->inmem_lock);
+- } while (1);
++ f2fs_put_dnode(&dn);
++ return 0;
+ }
+
+-void f2fs_drop_inmem_page(struct inode *inode, struct page *page)
++static void __complete_revoke_list(struct inode *inode, struct list_head *head,
++ bool revoke)
+ {
+- struct f2fs_inode_info *fi = F2FS_I(inode);
+- struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+- struct list_head *head = &fi->inmem_pages;
+- struct inmem_pages *cur = NULL;
+- struct inmem_pages *tmp;
+-
+- f2fs_bug_on(sbi, !page_private_atomic(page));
++ struct revoke_entry *cur, *tmp;
+
+- mutex_lock(&fi->inmem_lock);
+- list_for_each_entry(tmp, head, list) {
+- if (tmp->page == page) {
+- cur = tmp;
+- break;
+- }
++ list_for_each_entry_safe(cur, tmp, head, list) {
++ if (revoke)
++ __replace_atomic_write_block(inode, cur->index,
++ cur->old_addr, NULL, true);
++ list_del(&cur->list);
++ kmem_cache_free(revoke_entry_slab, cur);
+ }
+-
+- f2fs_bug_on(sbi, !cur);
+- list_del(&cur->list);
+- mutex_unlock(&fi->inmem_lock);
+-
+- dec_page_count(sbi, F2FS_INMEM_PAGES);
+- kmem_cache_free(inmem_entry_slab, cur);
+-
+- ClearPageUptodate(page);
+- clear_page_private_atomic(page);
+- f2fs_put_page(page, 0);
+-
+- detach_page_private(page);
+- set_page_private(page, 0);
+-
+- trace_f2fs_commit_inmem_page(page, INMEM_INVALIDATE);
+ }
+
+-static int __f2fs_commit_inmem_pages(struct inode *inode)
++static int __f2fs_commit_atomic_write(struct inode *inode)
+ {
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct f2fs_inode_info *fi = F2FS_I(inode);
+- struct inmem_pages *cur, *tmp;
+- struct f2fs_io_info fio = {
+- .sbi = sbi,
+- .ino = inode->i_ino,
+- .type = DATA,
+- .op = REQ_OP_WRITE,
+- .op_flags = REQ_SYNC | REQ_PRIO,
+- .io_type = FS_DATA_IO,
+- };
++ struct inode *cow_inode = fi->cow_inode;
++ struct revoke_entry *new;
+ struct list_head revoke_list;
+- bool submit_bio = false;
+- int err = 0;
++ block_t blkaddr;
++ struct dnode_of_data dn;
++ pgoff_t len = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
++ pgoff_t off = 0, blen, index;
++ int ret = 0, i;
+
+ INIT_LIST_HEAD(&revoke_list);
+
+- list_for_each_entry_safe(cur, tmp, &fi->inmem_pages, list) {
+- struct page *page = cur->page;
++ while (len) {
++ blen = min_t(pgoff_t, ADDRS_PER_BLOCK(cow_inode), len);
+
+- lock_page(page);
+- if (page->mapping == inode->i_mapping) {
+- trace_f2fs_commit_inmem_page(page, INMEM);
++ set_new_dnode(&dn, cow_inode, NULL, NULL, 0);
++ ret = f2fs_get_dnode_of_data(&dn, off, LOOKUP_NODE_RA);
++ if (ret && ret != -ENOENT) {
++ goto out;
++ } else if (ret == -ENOENT) {
++ ret = 0;
++ if (dn.max_level == 0)
++ goto out;
++ goto next;
++ }
+
+- f2fs_wait_on_page_writeback(page, DATA, true, true);
++ blen = min((pgoff_t)ADDRS_PER_PAGE(dn.node_page, cow_inode),
++ len);
++ index = off;
++ for (i = 0; i < blen; i++, dn.ofs_in_node++, index++) {
++ blkaddr = f2fs_data_blkaddr(&dn);
+
+- set_page_dirty(page);
+- if (clear_page_dirty_for_io(page)) {
+- inode_dec_dirty_pages(inode);
+- f2fs_remove_dirty_inode(inode);
+- }
+-retry:
+- fio.page = page;
+- fio.old_blkaddr = NULL_ADDR;
+- fio.encrypted_page = NULL;
+- fio.need_lock = LOCK_DONE;
+- err = f2fs_do_write_data_page(&fio);
+- if (err) {
+- if (err == -ENOMEM) {
+- memalloc_retry_wait(GFP_NOFS);
+- goto retry;
+- }
+- unlock_page(page);
+- break;
++ if (!__is_valid_data_blkaddr(blkaddr)) {
++ continue;
++ } else if (!f2fs_is_valid_blkaddr(sbi, blkaddr,
++ DATA_GENERIC_ENHANCE)) {
++ f2fs_put_dnode(&dn);
++ ret = -EFSCORRUPTED;
++ goto out;
+ }
+- /* record old blkaddr for revoking */
+- cur->old_addr = fio.old_blkaddr;
+- submit_bio = true;
+- }
+- unlock_page(page);
+- list_move_tail(&cur->list, &revoke_list);
+- }
+
+- if (submit_bio)
+- f2fs_submit_merged_write_cond(sbi, inode, NULL, 0, DATA);
++ new = f2fs_kmem_cache_alloc(revoke_entry_slab, GFP_NOFS,
++ true, NULL);
++ if (!new) {
++ f2fs_put_dnode(&dn);
++ ret = -ENOMEM;
++ goto out;
++ }
+
+- if (err) {
+- /*
+- * try to revoke all committed pages, but still we could fail
+- * due to no memory or other reason, if that happened, EAGAIN
+- * will be returned, which means in such case, transaction is
+- * already not integrity, caller should use journal to do the
+- * recovery or rewrite & commit last transaction. For other
+- * error number, revoking was done by filesystem itself.
+- */
+- err = __revoke_inmem_pages(inode, &revoke_list,
+- false, true, false);
++ ret = __replace_atomic_write_block(inode, index, blkaddr,
++ &new->old_addr, false);
++ if (ret) {
++ f2fs_put_dnode(&dn);
++ kmem_cache_free(revoke_entry_slab, new);
++ goto out;
++ }
+
+- /* drop all uncommitted pages */
+- __revoke_inmem_pages(inode, &fi->inmem_pages,
+- true, false, false);
+- } else {
+- __revoke_inmem_pages(inode, &revoke_list,
+- false, false, false);
++ f2fs_update_data_blkaddr(&dn, NULL_ADDR);
++ new->index = index;
++ list_add_tail(&new->list, &revoke_list);
++ }
++ f2fs_put_dnode(&dn);
++next:
++ off += blen;
++ len -= blen;
+ }
+
+- return err;
++out:
++ __complete_revoke_list(inode, &revoke_list, ret ? true : false);
++
++ return ret;
+ }
+
+-int f2fs_commit_inmem_pages(struct inode *inode)
++int f2fs_commit_atomic_write(struct inode *inode)
+ {
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct f2fs_inode_info *fi = F2FS_I(inode);
+ int err;
+
+- f2fs_balance_fs(sbi, true);
++ err = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
++ if (err)
++ return err;
+
+ f2fs_down_write(&fi->i_gc_rwsem[WRITE]);
+-
+ f2fs_lock_op(sbi);
+- set_inode_flag(inode, FI_ATOMIC_COMMIT);
+-
+- mutex_lock(&fi->inmem_lock);
+- err = __f2fs_commit_inmem_pages(inode);
+- mutex_unlock(&fi->inmem_lock);
+
+- clear_inode_flag(inode, FI_ATOMIC_COMMIT);
++ err = __f2fs_commit_atomic_write(inode);
+
+ f2fs_unlock_op(sbi);
+ f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
+@@ -5359,9 +5235,9 @@ int __init f2fs_create_segment_manager_caches(void)
+ if (!sit_entry_set_slab)
+ goto destroy_discard_cmd;
+
+- inmem_entry_slab = f2fs_kmem_cache_create("f2fs_inmem_page_entry",
+- sizeof(struct inmem_pages));
+- if (!inmem_entry_slab)
++ revoke_entry_slab = f2fs_kmem_cache_create("f2fs_revoke_entry",
++ sizeof(struct revoke_entry));
++ if (!revoke_entry_slab)
+ goto destroy_sit_entry_set;
+ return 0;
+
+@@ -5380,5 +5256,5 @@ void f2fs_destroy_segment_manager_caches(void)
+ kmem_cache_destroy(sit_entry_set_slab);
+ kmem_cache_destroy(discard_cmd_slab);
+ kmem_cache_destroy(discard_entry_slab);
+- kmem_cache_destroy(inmem_entry_slab);
++ kmem_cache_destroy(revoke_entry_slab);
+ }
+diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
+index 8fbc9f6afa55..3f277dfcb131 100644
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -225,10 +225,10 @@ struct segment_allocation {
+
+ #define MAX_SKIP_GC_COUNT 16
+
+-struct inmem_pages {
++struct revoke_entry {
+ struct list_head list;
+- struct page *page;
+ block_t old_addr; /* for revoking when fail to commit */
++ pgoff_t index;
+ };
+
+ struct sit_info {
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 1b59f95606c7..e3539c027a6c 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -1339,9 +1339,6 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
+ spin_lock_init(&fi->i_size_lock);
+ INIT_LIST_HEAD(&fi->dirty_list);
+ INIT_LIST_HEAD(&fi->gdirty_list);
+- INIT_LIST_HEAD(&fi->inmem_ilist);
+- INIT_LIST_HEAD(&fi->inmem_pages);
+- mutex_init(&fi->inmem_lock);
+ init_f2fs_rwsem(&fi->i_gc_rwsem[READ]);
+ init_f2fs_rwsem(&fi->i_gc_rwsem[WRITE]);
+ init_f2fs_rwsem(&fi->i_xattr_sem);
+@@ -1382,9 +1379,8 @@ static int f2fs_drop_inode(struct inode *inode)
+ atomic_inc(&inode->i_count);
+ spin_unlock(&inode->i_lock);
+
+- /* some remained atomic pages should discarded */
+ if (f2fs_is_atomic_file(inode))
+- f2fs_drop_inmem_pages(inode);
++ f2fs_abort_atomic_write(inode, true);
+
+ /* should remain fi->extent_tree for writepage */
+ f2fs_destroy_extent_node(inode);
+diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
+index 1779e133cea0..d91370377523 100644
+--- a/include/trace/events/f2fs.h
++++ b/include/trace/events/f2fs.h
+@@ -15,10 +15,6 @@ TRACE_DEFINE_ENUM(NODE);
+ TRACE_DEFINE_ENUM(DATA);
+ TRACE_DEFINE_ENUM(META);
+ TRACE_DEFINE_ENUM(META_FLUSH);
+-TRACE_DEFINE_ENUM(INMEM);
+-TRACE_DEFINE_ENUM(INMEM_DROP);
+-TRACE_DEFINE_ENUM(INMEM_INVALIDATE);
+-TRACE_DEFINE_ENUM(INMEM_REVOKE);
+ TRACE_DEFINE_ENUM(IPU);
+ TRACE_DEFINE_ENUM(OPU);
+ TRACE_DEFINE_ENUM(HOT);
+@@ -59,10 +55,6 @@ TRACE_DEFINE_ENUM(CP_RESIZE);
+ { DATA, "DATA" }, \
+ { META, "META" }, \
+ { META_FLUSH, "META_FLUSH" }, \
+- { INMEM, "INMEM" }, \
+- { INMEM_DROP, "INMEM_DROP" }, \
+- { INMEM_INVALIDATE, "INMEM_INVALIDATE" }, \
+- { INMEM_REVOKE, "INMEM_REVOKE" }, \
+ { IPU, "IN-PLACE" }, \
+ { OPU, "OUT-OF-PLACE" })
+
+@@ -1289,20 +1281,6 @@ DEFINE_EVENT(f2fs__page, f2fs_vm_page_mkwrite,
+ TP_ARGS(page, type)
+ );
+
+-DEFINE_EVENT(f2fs__page, f2fs_register_inmem_page,
+-
+- TP_PROTO(struct page *page, int type),
+-
+- TP_ARGS(page, type)
+-);
+-
+-DEFINE_EVENT(f2fs__page, f2fs_commit_inmem_page,
+-
+- TP_PROTO(struct page *page, int type),
+-
+- TP_ARGS(page, type)
+-);
+-
+ TRACE_EVENT(f2fs_filemap_fault,
+
+ TP_PROTO(struct inode *inode, pgoff_t index, unsigned long ret),
+--
+2.35.1
+
--- /dev/null
+From 00e8441f03906434e3d85362d961efdb16621d16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Mar 2022 23:11:17 +0800
+Subject: f2fs: check pinfile in gc_data_segment() in advance
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit a22bb5526d7dd627b94a7ee22e5a98c36e39fceb ]
+
+In order to skip migrating section which contains data of pinned
+file in advance.
+
+Signed-off-by: Chao Yu <chao.yu@oppo.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/gc.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index ea5b93b689cd..e83c07144d8f 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1480,6 +1480,13 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+ special_file(inode->i_mode))
+ continue;
+
++ if (is_inode_flag_set(inode, FI_PIN_FILE) &&
++ gc_type == FG_GC) {
++ f2fs_pin_file_control(inode, true);
++ iput(inode);
++ return submitted;
++ }
++
+ if (!f2fs_down_write_trylock(
+ &F2FS_I(inode)->i_gc_rwsem[WRITE])) {
+ iput(inode);
+--
+2.35.1
+
--- /dev/null
+From fc9a50b9482e1162e00e1159d4a370001a0775f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Aug 2022 17:53:58 +0900
+Subject: f2fs: do not allow to decompress files have FI_COMPRESS_RELEASED
+
+From: Jaewook Kim <jw5454.kim@samsung.com>
+
+[ Upstream commit 90be48bd9d29ece3965e5e8b21499b6db166e57b ]
+
+If a file has FI_COMPRESS_RELEASED, all writes for it should not be
+allowed. However, as of now, in case of compress_mode=user, writes
+triggered by IOCTLs like F2FS_IOC_DE/COMPRESS_FILE are allowed unexpectly,
+which could crash that file.
+To fix it, let's do not allow F2FS_IOC_DE/COMPRESS_IOCTL if a file already
+has FI_COMPRESS_RELEASED flag.
+
+This is the reproduction process:
+1. $ touch ./file
+2. $ chattr +c ./file
+3. $ dd if=/dev/random of=./file bs=4096 count=30 conv=notrunc
+4. $ dd if=/dev/zero of=./file bs=4096 count=34 seek=30 conv=notrunc
+5. $ sync
+6. $ do_compress ./file ; call F2FS_IOC_COMPRESS_FILE
+7. $ get_compr_blocks ./file ; call F2FS_IOC_GET_COMPRESS_BLOCKS
+8. $ release ./file ; call F2FS_IOC_RELEASE_COMPRESS_BLOCKS
+9. $ do_compress ./file ; call F2FS_IOC_COMPRESS_FILE again
+10. $ get_compr_blocks ./file ; call F2FS_IOC_GET_COMPRESS_BLOCKS again
+
+This reproduction process is tested in 128kb cluster size.
+You can find compr_blocks has a negative value.
+
+Fixes: 5fdb322ff2c2b ("f2fs: add F2FS_IOC_DECOMPRESS_FILE and F2FS_IOC_COMPRESS_FILE")
+
+Signed-off-by: Junbeom Yeom <junbeom.yeom@samsung.com>
+Signed-off-by: Sungjong Seo <sj1557.seo@samsung.com>
+Signed-off-by: Youngjin Gil <youngjin.gil@samsung.com>
+Signed-off-by: Jaewook Kim <jw5454.kim@samsung.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 9a676ea080e4..c2644a085876 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -3914,6 +3914,11 @@ static int f2fs_ioc_decompress_file(struct file *filp, unsigned long arg)
+ goto out;
+ }
+
++ if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
++ ret = -EINVAL;
++ goto out;
++ }
++
+ ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
+ if (ret)
+ goto out;
+@@ -3981,6 +3986,11 @@ static int f2fs_ioc_compress_file(struct file *filp, unsigned long arg)
+ goto out;
+ }
+
++ if (is_inode_flag_set(inode, FI_COMPRESS_RELEASED)) {
++ ret = -EINVAL;
++ goto out;
++ }
++
+ ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
+ if (ret)
+ goto out;
+--
+2.35.1
+
--- /dev/null
+From fb700f3fc59096dd2884aac5e72a7333ace6d721 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Mar 2022 23:11:18 +0800
+Subject: f2fs: don't set GC_FAILURE_PIN for background GC
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 642c0969916eaa4878cb74f36752108e590b0389 ]
+
+So that it can reduce the possibility that file be unpinned forcely by
+foreground GC due to .i_gc_failures[GC_FAILURE_PIN] exceeds threshold.
+
+Signed-off-by: Chao Yu <chao.yu@oppo.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/gc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index e83c07144d8f..6a7e4148ff9d 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1202,7 +1202,8 @@ static int move_data_block(struct inode *inode, block_t bidx,
+ }
+
+ if (f2fs_is_pinned_file(inode)) {
+- f2fs_pin_file_control(inode, true);
++ if (gc_type == FG_GC)
++ f2fs_pin_file_control(inode, true);
+ err = -EAGAIN;
+ goto out;
+ }
+--
+2.35.1
+
--- /dev/null
+From 7c69fb005afac62e95e7ea94f29ad3fe7a166d02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 11:17:15 +0800
+Subject: f2fs: fix to check inline_data during compressed inode conversion
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 7165841d578e0592848e09dc9d131aa30be44e1b ]
+
+When converting inode to compressed one via ioctl, it needs to check
+inline_data, since inline_data flag and compressed flag are incompatible.
+
+Fixes: 4c8ff7095bef ("f2fs: support data compression")
+Signed-off-by: Chao Yu <chao.yu@oppo.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index ce8f496a7e5d..3f8a3d63a971 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -4382,7 +4382,7 @@ static inline bool f2fs_lfs_mode(struct f2fs_sb_info *sbi)
+ static inline bool f2fs_may_compress(struct inode *inode)
+ {
+ if (IS_SWAPFILE(inode) || f2fs_is_pinned_file(inode) ||
+- f2fs_is_atomic_file(inode))
++ f2fs_is_atomic_file(inode) || f2fs_has_inline_data(inode))
+ return false;
+ return S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode);
+ }
+--
+2.35.1
+
--- /dev/null
+From c1e235d30be41fb6fcce9c567e3b5aa2cf7b9615 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 14:30:15 +0800
+Subject: f2fs: fix to invalidate META_MAPPING before DIO write
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 67ca06872eb02944b4c6f92cffa9242e92c63109 ]
+
+Quoted from commit e3b49ea36802 ("f2fs: invalidate META_MAPPING before
+IPU/DIO write")
+
+"
+Encrypted pages during GC are read and cached in META_MAPPING.
+However, due to cached pages in META_MAPPING, there is an issue where
+newly written pages are lost by IPU or DIO writes.
+
+Thread A - f2fs_gc() Thread B
+/* phase 3 */
+down_write(i_gc_rwsem)
+ra_data_block() ---- (a)
+up_write(i_gc_rwsem)
+ f2fs_direct_IO() :
+ - down_read(i_gc_rwsem)
+ - __blockdev_direct_io()
+ - get_data_block_dio_write()
+ - f2fs_dio_submit_bio() ---- (b)
+ - up_read(i_gc_rwsem)
+/* phase 4 */
+down_write(i_gc_rwsem)
+move_data_block() ---- (c)
+up_write(i_gc_rwsem)
+
+(a) In phase 3 of f2fs_gc(), up-to-date page is read from storage and
+ cached in META_MAPPING.
+(b) In thread B, writing new data by IPU or DIO write on same blkaddr as
+ read in (a). cached page in META_MAPPING become out-dated.
+(c) In phase 4 of f2fs_gc(), out-dated page in META_MAPPING is copied to
+ new blkaddr. In conclusion, the newly written data in (b) is lost.
+
+To address this issue, invalidating pages in META_MAPPING before IPU or
+DIO write.
+"
+
+In previous commit, we missed to cover extent cache hit case, and passed
+wrong value for parameter @end of invalidate_mapping_pages(), fix both
+issues.
+
+Fixes: 6aa58d8ad20a ("f2fs: readahead encrypted block during GC")
+Fixes: e3b49ea36802 ("f2fs: invalidate META_MAPPING before IPU/DIO write")
+Cc: Hyeong-Jun Kim <hj514.kim@samsung.com>
+Signed-off-by: Chao Yu <chao.yu@oppo.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/data.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 9a1a526f2092..1862b03a9982 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -1436,9 +1436,12 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
+ *map->m_next_extent = pgofs + map->m_len;
+
+ /* for hardware encryption, but to avoid potential issue in future */
+- if (flag == F2FS_GET_BLOCK_DIO)
++ if (flag == F2FS_GET_BLOCK_DIO) {
+ f2fs_wait_on_block_writeback_range(inode,
+ map->m_pblk, map->m_len);
++ invalidate_mapping_pages(META_MAPPING(sbi),
++ map->m_pblk, map->m_pblk + map->m_len - 1);
++ }
+
+ if (map->m_multidev_dio) {
+ block_t blk_addr = map->m_pblk;
+@@ -1655,7 +1658,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
+ f2fs_wait_on_block_writeback_range(inode,
+ map->m_pblk, map->m_len);
+ invalidate_mapping_pages(META_MAPPING(sbi),
+- map->m_pblk, map->m_pblk);
++ map->m_pblk, map->m_pblk + map->m_len - 1);
+
+ if (map->m_multidev_dio) {
+ block_t blk_addr = map->m_pblk;
+--
+2.35.1
+
--- /dev/null
+From ca62ac0615a6751071fe57a1d10f9aa3feb54347 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 18:16:33 +0800
+Subject: f2fs: fix to remove F2FS_COMPR_FL and tag F2FS_NOCOMP_FL at the same
+ time
+
+From: Chao Liu <liuchao@coolpad.com>
+
+[ Upstream commit 8ee236dcaa690d09ca612622e8bc8d09c302021d ]
+
+If the inode has the compress flag, it will fail to use
+'chattr -c +m' to remove its compress flag and tag no compress flag.
+However, the same command will be successful when executed again,
+as shown below:
+
+ $ touch foo.txt
+ $ chattr +c foo.txt
+ $ chattr -c +m foo.txt
+ chattr: Invalid argument while setting flags on foo.txt
+ $ chattr -c +m foo.txt
+ $ f2fs_io getflags foo.txt
+ get a flag on foo.txt ret=0, flags=nocompression,inline_data
+
+Fix this by removing some checks in f2fs_setflags_common()
+that do not affect the original logic. I go through all the
+possible scenarios, and the results are as follows. Bold is
+the only thing that has changed.
+
++---------------+-----------+-----------+----------+
+| | file flags |
++ command +-----------+-----------+----------+
+| | no flag | compr | nocompr |
++---------------+-----------+-----------+----------+
+| chattr +c | compr | compr | -EINVAL |
+| chattr -c | no flag | no flag | nocompr |
+| chattr +m | nocompr | -EINVAL | nocompr |
+| chattr -m | no flag | compr | no flag |
+| chattr +c +m | -EINVAL | -EINVAL | -EINVAL |
+| chattr +c -m | compr | compr | compr |
+| chattr -c +m | nocompr | *nocompr* | nocompr |
+| chattr -c -m | no flag | no flag | no flag |
++---------------+-----------+-----------+----------+
+
+Link: https://lore.kernel.org/linux-f2fs-devel/20220621064833.1079383-1-chaoliu719@gmail.com/
+Fixes: 4c8ff7095bef ("f2fs: support data compression")
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Chao Liu <liuchao@coolpad.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index ab344d5f9b82..863518695ea6 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1867,10 +1867,7 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)
+ if (masked_flags & F2FS_COMPR_FL) {
+ if (!f2fs_disable_compressed_file(inode))
+ return -EINVAL;
+- }
+- if (iflags & F2FS_NOCOMP_FL)
+- return -EINVAL;
+- if (iflags & F2FS_COMPR_FL) {
++ } else {
+ if (!f2fs_may_compress(inode))
+ return -EINVAL;
+ if (S_ISREG(inode->i_mode) && inode->i_size)
+@@ -1879,10 +1876,6 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)
+ set_compress_context(inode);
+ }
+ }
+- if ((iflags ^ masked_flags) & F2FS_NOCOMP_FL) {
+- if (masked_flags & F2FS_COMPR_FL)
+- return -EINVAL;
+- }
+
+ fi->i_flags = iflags | (fi->i_flags & ~mask);
+ f2fs_bug_on(F2FS_I_SB(inode), (fi->i_flags & F2FS_COMPR_FL) &&
+--
+2.35.1
+
--- /dev/null
+From dc9263aa04c3d734ca20b3dc1d61e00f17733445 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 May 2022 18:30:31 +0800
+Subject: f2fs: give priority to select unpinned section for foreground GC
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 71419129625a50cfb5e3c5cc215948a3f98c806d ]
+
+Previously, during foreground GC, if victims contain data of pinned file,
+it will fail migration of the data, and meanwhile i_gc_failures of that
+pinned file may increase, and when it exceeds threshold, GC will unpin
+the file, result in breaking pinfile's semantics.
+
+In order to mitigate such condition, let's record and skip section which
+has pinned file's data and give priority to select unpinned one.
+
+Signed-off-by: Chao Yu <chao.yu@oppo.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/gc.c | 85 +++++++++++++++++++++++++++++++++++++++--------
+ fs/f2fs/segment.c | 8 +++++
+ fs/f2fs/segment.h | 3 ++
+ 3 files changed, 82 insertions(+), 14 deletions(-)
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index a193862ad8a5..3009c0a97ab4 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -646,6 +646,54 @@ static void release_victim_entry(struct f2fs_sb_info *sbi)
+ f2fs_bug_on(sbi, !list_empty(&am->victim_list));
+ }
+
++static bool f2fs_pin_section(struct f2fs_sb_info *sbi, unsigned int segno)
++{
++ struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
++ unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
++
++ if (!dirty_i->enable_pin_section)
++ return false;
++ if (!test_and_set_bit(secno, dirty_i->pinned_secmap))
++ dirty_i->pinned_secmap_cnt++;
++ return true;
++}
++
++static bool f2fs_pinned_section_exists(struct dirty_seglist_info *dirty_i)
++{
++ return dirty_i->pinned_secmap_cnt;
++}
++
++static bool f2fs_section_is_pinned(struct dirty_seglist_info *dirty_i,
++ unsigned int secno)
++{
++ return dirty_i->enable_pin_section &&
++ f2fs_pinned_section_exists(dirty_i) &&
++ test_bit(secno, dirty_i->pinned_secmap);
++}
++
++static void f2fs_unpin_all_sections(struct f2fs_sb_info *sbi, bool enable)
++{
++ unsigned int bitmap_size = f2fs_bitmap_size(MAIN_SECS(sbi));
++
++ if (f2fs_pinned_section_exists(DIRTY_I(sbi))) {
++ memset(DIRTY_I(sbi)->pinned_secmap, 0, bitmap_size);
++ DIRTY_I(sbi)->pinned_secmap_cnt = 0;
++ }
++ DIRTY_I(sbi)->enable_pin_section = enable;
++}
++
++static int f2fs_gc_pinned_control(struct inode *inode, int gc_type,
++ unsigned int segno)
++{
++ if (!f2fs_is_pinned_file(inode))
++ return 0;
++ if (gc_type != FG_GC)
++ return -EBUSY;
++ if (!f2fs_pin_section(F2FS_I_SB(inode), segno))
++ f2fs_pin_file_control(inode, true);
++ return -EAGAIN;
++}
++
+ /*
+ * This function is called from two paths.
+ * One is garbage collection and the other is SSR segment selection.
+@@ -787,6 +835,9 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
+ if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap))
+ goto next;
+
++ if (gc_type == FG_GC && f2fs_section_is_pinned(dirty_i, secno))
++ goto next;
++
+ if (is_atgc) {
+ add_victim_entry(sbi, &p, segno);
+ goto next;
+@@ -1201,12 +1252,9 @@ static int move_data_block(struct inode *inode, block_t bidx,
+ goto out;
+ }
+
+- if (f2fs_is_pinned_file(inode)) {
+- if (gc_type == FG_GC)
+- f2fs_pin_file_control(inode, true);
+- err = -EAGAIN;
++ err = f2fs_gc_pinned_control(inode, gc_type, segno);
++ if (err)
+ goto out;
+- }
+
+ set_new_dnode(&dn, inode, NULL, NULL, 0);
+ err = f2fs_get_dnode_of_data(&dn, bidx, LOOKUP_NODE);
+@@ -1351,12 +1399,9 @@ static int move_data_page(struct inode *inode, block_t bidx, int gc_type,
+ err = -EAGAIN;
+ goto out;
+ }
+- if (f2fs_is_pinned_file(inode)) {
+- if (gc_type == FG_GC)
+- f2fs_pin_file_control(inode, true);
+- err = -EAGAIN;
++ err = f2fs_gc_pinned_control(inode, gc_type, segno);
++ if (err)
+ goto out;
+- }
+
+ if (gc_type == BG_GC) {
+ if (PageWriteback(page)) {
+@@ -1476,14 +1521,15 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+ ofs_in_node = le16_to_cpu(entry->ofs_in_node);
+
+ if (phase == 3) {
++ int err;
++
+ inode = f2fs_iget(sb, dni.ino);
+ if (IS_ERR(inode) || is_bad_inode(inode) ||
+ special_file(inode->i_mode))
+ continue;
+
+- if (is_inode_flag_set(inode, FI_PIN_FILE) &&
+- gc_type == FG_GC) {
+- f2fs_pin_file_control(inode, true);
++ err = f2fs_gc_pinned_control(inode, gc_type, segno);
++ if (err == -EAGAIN) {
+ iput(inode);
+ return submitted;
+ }
+@@ -1766,9 +1812,17 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
+ ret = -EINVAL;
+ goto stop;
+ }
++retry:
+ ret = __get_victim(sbi, &segno, gc_type);
+- if (ret)
++ if (ret) {
++ /* allow to search victim from sections has pinned data */
++ if (ret == -ENODATA && gc_type == FG_GC &&
++ f2fs_pinned_section_exists(DIRTY_I(sbi))) {
++ f2fs_unpin_all_sections(sbi, false);
++ goto retry;
++ }
+ goto stop;
++ }
+
+ seg_freed = do_garbage_collect(sbi, segno, &gc_list, gc_type, force);
+ if (gc_type == FG_GC &&
+@@ -1819,6 +1873,9 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
+ SIT_I(sbi)->last_victim[ALLOC_NEXT] = 0;
+ SIT_I(sbi)->last_victim[FLUSH_DEVICE] = init_segno;
+
++ if (gc_type == FG_GC)
++ f2fs_unpin_all_sections(sbi, true);
++
+ trace_f2fs_gc_end(sbi->sb, ret, total_freed, sec_freed,
+ get_pages(sbi, F2FS_DIRTY_NODES),
+ get_pages(sbi, F2FS_DIRTY_DENTS),
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index aa0162664a1e..a914b70f8543 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -4653,6 +4653,13 @@ static int init_victim_secmap(struct f2fs_sb_info *sbi)
+ dirty_i->victim_secmap = f2fs_kvzalloc(sbi, bitmap_size, GFP_KERNEL);
+ if (!dirty_i->victim_secmap)
+ return -ENOMEM;
++
++ dirty_i->pinned_secmap = f2fs_kvzalloc(sbi, bitmap_size, GFP_KERNEL);
++ if (!dirty_i->pinned_secmap)
++ return -ENOMEM;
++
++ dirty_i->pinned_secmap_cnt = 0;
++ dirty_i->enable_pin_section = true;
+ return 0;
+ }
+
+@@ -5241,6 +5248,7 @@ static void destroy_victim_secmap(struct f2fs_sb_info *sbi)
+ {
+ struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
+
++ kvfree(dirty_i->pinned_secmap);
+ kvfree(dirty_i->victim_secmap);
+ }
+
+diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
+index 1fa26a9603cb..8fbc9f6afa55 100644
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -295,6 +295,9 @@ struct dirty_seglist_info {
+ struct mutex seglist_lock; /* lock for segment bitmaps */
+ int nr_dirty[NR_DIRTY_TYPE]; /* # of dirty segments */
+ unsigned long *victim_secmap; /* background GC victims */
++ unsigned long *pinned_secmap; /* pinned victims from foreground GC */
++ unsigned int pinned_secmap_cnt; /* count of victims which has pinned data */
++ bool enable_pin_section; /* enable pinning section */
+ };
+
+ /* victim selection function for cleaning and SSR */
+--
+2.35.1
+
--- /dev/null
+From 2f829ec16cd38ecee17b827c29639da7660c3d30 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 May 2022 17:49:18 -0700
+Subject: f2fs: kill volatile write support
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+[ Upstream commit 7bc155fec5b371dbb57256e84a49c78692a09060 ]
+
+There's no user, since all can use atomic writes simply.
+Let's kill it.
+
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/checkpoint.c | 4 +-
+ fs/f2fs/data.c | 5 --
+ fs/f2fs/debug.c | 10 +---
+ fs/f2fs/f2fs.h | 27 +---------
+ fs/f2fs/file.c | 116 ++-----------------------------------------
+ fs/f2fs/segment.c | 3 +-
+ fs/f2fs/verity.c | 2 +-
+ 7 files changed, 10 insertions(+), 157 deletions(-)
+
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index beceac9885c3..63ab8c9d674e 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -1004,9 +1004,7 @@ static void __add_dirty_inode(struct inode *inode, enum inode_type type)
+ return;
+
+ set_inode_flag(inode, flag);
+- if (!f2fs_is_volatile_file(inode))
+- list_add_tail(&F2FS_I(inode)->dirty_list,
+- &sbi->inode_list[type]);
++ list_add_tail(&F2FS_I(inode)->dirty_list, &sbi->inode_list[type]);
+ stat_inc_dirty_inode(sbi, type);
+ }
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 4c1603a79745..07522e82c7c4 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -2744,11 +2744,6 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
+ write:
+ if (f2fs_is_drop_cache(inode))
+ goto out;
+- /* we should not write 0'th page having journal header */
+- if (f2fs_is_volatile_file(inode) && (!page->index ||
+- (!wbc->for_reclaim &&
+- f2fs_available_free_memory(sbi, BASE_CHECK))))
+- goto redirty_out;
+
+ /* Dentry/quota blocks are controlled by checkpoint */
+ if (S_ISDIR(inode->i_mode) || IS_NOQUOTA(inode)) {
+diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
+index 65f0bcf498bb..c92625ef16d0 100644
+--- a/fs/f2fs/debug.c
++++ b/fs/f2fs/debug.c
+@@ -92,9 +92,7 @@ static void update_general_status(struct f2fs_sb_info *sbi)
+ si->nquota_files = sbi->nquota_files;
+ si->ndirty_all = sbi->ndirty_inode[DIRTY_META];
+ si->aw_cnt = sbi->atomic_files;
+- si->vw_cnt = atomic_read(&sbi->vw_cnt);
+ si->max_aw_cnt = atomic_read(&sbi->max_aw_cnt);
+- si->max_vw_cnt = atomic_read(&sbi->max_vw_cnt);
+ si->nr_dio_read = get_pages(sbi, F2FS_DIO_READ);
+ si->nr_dio_write = get_pages(sbi, F2FS_DIO_WRITE);
+ si->nr_wb_cp_data = get_pages(sbi, F2FS_WB_CP_DATA);
+@@ -511,10 +509,8 @@ static int stat_show(struct seq_file *s, void *v)
+ si->flush_list_empty,
+ si->nr_discarding, si->nr_discarded,
+ si->nr_discard_cmd, si->undiscard_blks);
+- seq_printf(s, " - atomic IO: %4d (Max. %4d), "
+- "volatile IO: %4d (Max. %4d)\n",
+- si->aw_cnt, si->max_aw_cnt,
+- si->vw_cnt, si->max_vw_cnt);
++ seq_printf(s, " - atomic IO: %4d (Max. %4d)\n",
++ si->aw_cnt, si->max_aw_cnt);
+ seq_printf(s, " - compress: %4d, hit:%8d\n", si->compress_pages, si->compress_page_hit);
+ seq_printf(s, " - nodes: %4d in %4d\n",
+ si->ndirty_node, si->node_pages);
+@@ -615,9 +611,7 @@ int f2fs_build_stats(struct f2fs_sb_info *sbi)
+ for (i = META_CP; i < META_MAX; i++)
+ atomic_set(&sbi->meta_count[i], 0);
+
+- atomic_set(&sbi->vw_cnt, 0);
+ atomic_set(&sbi->max_aw_cnt, 0);
+- atomic_set(&sbi->max_vw_cnt, 0);
+
+ raw_spin_lock_irqsave(&f2fs_stat_lock, flags);
+ list_add_tail(&si->stat_list, &f2fs_stat_list);
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 13140b753ba1..ce8f496a7e5d 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -737,7 +737,6 @@ enum {
+ FI_UPDATE_WRITE, /* inode has in-place-update data */
+ FI_NEED_IPU, /* used for ipu per file */
+ FI_ATOMIC_FILE, /* indicate atomic file */
+- FI_VOLATILE_FILE, /* indicate volatile file */
+ FI_FIRST_BLOCK_WRITTEN, /* indicate #0 data block was written */
+ FI_DROP_CACHE, /* drop dirty page cache */
+ FI_DATA_EXIST, /* indicate data exists */
+@@ -1738,9 +1737,7 @@ struct f2fs_sb_info {
+ atomic_t inline_dir; /* # of inline_dentry inodes */
+ atomic_t compr_inode; /* # of compressed inodes */
+ atomic64_t compr_blocks; /* # of compressed blocks */
+- atomic_t vw_cnt; /* # of volatile writes */
+ atomic_t max_aw_cnt; /* max # of atomic writes */
+- atomic_t max_vw_cnt; /* max # of volatile writes */
+ unsigned int io_skip_bggc; /* skip background gc for in-flight IO */
+ unsigned int other_skip_bggc; /* skip background gc for other reasons */
+ unsigned int ndirty_inode[NR_INODE_TYPE]; /* # of dirty inodes */
+@@ -3191,11 +3188,6 @@ static inline bool f2fs_is_atomic_file(struct inode *inode)
+ return is_inode_flag_set(inode, FI_ATOMIC_FILE);
+ }
+
+-static inline bool f2fs_is_volatile_file(struct inode *inode)
+-{
+- return is_inode_flag_set(inode, FI_VOLATILE_FILE);
+-}
+-
+ static inline bool f2fs_is_first_block_written(struct inode *inode)
+ {
+ return is_inode_flag_set(inode, FI_FIRST_BLOCK_WRITTEN);
+@@ -3815,7 +3807,7 @@ struct f2fs_stat_info {
+ int inline_xattr, inline_inode, inline_dir, append, update, orphans;
+ int compr_inode;
+ unsigned long long compr_blocks;
+- int aw_cnt, max_aw_cnt, vw_cnt, max_vw_cnt;
++ int aw_cnt, max_aw_cnt;
+ unsigned int valid_count, valid_node_count, valid_inode_count, discard_blks;
+ unsigned int bimodal, avg_vblocks;
+ int util_free, util_valid, util_invalid;
+@@ -3926,17 +3918,6 @@ static inline struct f2fs_stat_info *F2FS_STAT(struct f2fs_sb_info *sbi)
+ if (cur > max) \
+ atomic_set(&F2FS_I_SB(inode)->max_aw_cnt, cur); \
+ } while (0)
+-#define stat_inc_volatile_write(inode) \
+- (atomic_inc(&F2FS_I_SB(inode)->vw_cnt))
+-#define stat_dec_volatile_write(inode) \
+- (atomic_dec(&F2FS_I_SB(inode)->vw_cnt))
+-#define stat_update_max_volatile_write(inode) \
+- do { \
+- int cur = atomic_read(&F2FS_I_SB(inode)->vw_cnt); \
+- int max = atomic_read(&F2FS_I_SB(inode)->max_vw_cnt); \
+- if (cur > max) \
+- atomic_set(&F2FS_I_SB(inode)->max_vw_cnt, cur); \
+- } while (0)
+ #define stat_inc_seg_count(sbi, type, gc_type) \
+ do { \
+ struct f2fs_stat_info *si = F2FS_STAT(sbi); \
+@@ -3998,9 +3979,6 @@ void f2fs_update_sit_info(struct f2fs_sb_info *sbi);
+ #define stat_add_compr_blocks(inode, blocks) do { } while (0)
+ #define stat_sub_compr_blocks(inode, blocks) do { } while (0)
+ #define stat_update_max_atomic_write(inode) do { } while (0)
+-#define stat_inc_volatile_write(inode) do { } while (0)
+-#define stat_dec_volatile_write(inode) do { } while (0)
+-#define stat_update_max_volatile_write(inode) do { } while (0)
+ #define stat_inc_meta_count(sbi, blkaddr) do { } while (0)
+ #define stat_inc_seg_type(sbi, curseg) do { } while (0)
+ #define stat_inc_block_count(sbi, curseg) do { } while (0)
+@@ -4404,8 +4382,7 @@ static inline bool f2fs_lfs_mode(struct f2fs_sb_info *sbi)
+ static inline bool f2fs_may_compress(struct inode *inode)
+ {
+ if (IS_SWAPFILE(inode) || f2fs_is_pinned_file(inode) ||
+- f2fs_is_atomic_file(inode) ||
+- f2fs_is_volatile_file(inode))
++ f2fs_is_atomic_file(inode))
+ return false;
+ return S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode);
+ }
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 9b04a7a0a368..ab344d5f9b82 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1818,13 +1818,6 @@ static int f2fs_release_file(struct inode *inode, struct file *filp)
+
+ if (f2fs_is_atomic_file(inode))
+ f2fs_abort_atomic_write(inode, true);
+- if (f2fs_is_volatile_file(inode)) {
+- set_inode_flag(inode, FI_DROP_CACHE);
+- filemap_fdatawrite(inode->i_mapping);
+- clear_inode_flag(inode, FI_DROP_CACHE);
+- clear_inode_flag(inode, FI_VOLATILE_FILE);
+- stat_dec_volatile_write(inode);
+- }
+ return 0;
+ }
+
+@@ -2099,15 +2092,10 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
+
+ inode_lock(inode);
+
+- if (f2fs_is_volatile_file(inode)) {
+- ret = -EINVAL;
+- goto err_out;
+- }
+-
+ if (f2fs_is_atomic_file(inode)) {
+ ret = f2fs_commit_atomic_write(inode);
+ if (ret)
+- goto err_out;
++ goto unlock_out;
+
+ ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true);
+ if (!ret)
+@@ -2115,108 +2103,12 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
+ } else {
+ ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 1, false);
+ }
+-err_out:
++unlock_out:
+ inode_unlock(inode);
+ mnt_drop_write_file(filp);
+ return ret;
+ }
+
+-static int f2fs_ioc_start_volatile_write(struct file *filp)
+-{
+- struct inode *inode = file_inode(filp);
+- struct user_namespace *mnt_userns = file_mnt_user_ns(filp);
+- int ret;
+-
+- if (!inode_owner_or_capable(mnt_userns, inode))
+- return -EACCES;
+-
+- if (!S_ISREG(inode->i_mode))
+- return -EINVAL;
+-
+- ret = mnt_want_write_file(filp);
+- if (ret)
+- return ret;
+-
+- inode_lock(inode);
+-
+- if (f2fs_is_volatile_file(inode))
+- goto out;
+-
+- ret = f2fs_convert_inline_inode(inode);
+- if (ret)
+- goto out;
+-
+- stat_inc_volatile_write(inode);
+- stat_update_max_volatile_write(inode);
+-
+- set_inode_flag(inode, FI_VOLATILE_FILE);
+- f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
+-out:
+- inode_unlock(inode);
+- mnt_drop_write_file(filp);
+- return ret;
+-}
+-
+-static int f2fs_ioc_release_volatile_write(struct file *filp)
+-{
+- struct inode *inode = file_inode(filp);
+- struct user_namespace *mnt_userns = file_mnt_user_ns(filp);
+- int ret;
+-
+- if (!inode_owner_or_capable(mnt_userns, inode))
+- return -EACCES;
+-
+- ret = mnt_want_write_file(filp);
+- if (ret)
+- return ret;
+-
+- inode_lock(inode);
+-
+- if (!f2fs_is_volatile_file(inode))
+- goto out;
+-
+- if (!f2fs_is_first_block_written(inode)) {
+- ret = truncate_partial_data_page(inode, 0, true);
+- goto out;
+- }
+-
+- ret = punch_hole(inode, 0, F2FS_BLKSIZE);
+-out:
+- inode_unlock(inode);
+- mnt_drop_write_file(filp);
+- return ret;
+-}
+-
+-static int f2fs_ioc_abort_volatile_write(struct file *filp)
+-{
+- struct inode *inode = file_inode(filp);
+- struct user_namespace *mnt_userns = file_mnt_user_ns(filp);
+- int ret;
+-
+- if (!inode_owner_or_capable(mnt_userns, inode))
+- return -EACCES;
+-
+- ret = mnt_want_write_file(filp);
+- if (ret)
+- return ret;
+-
+- inode_lock(inode);
+-
+- if (f2fs_is_atomic_file(inode))
+- f2fs_abort_atomic_write(inode, true);
+- if (f2fs_is_volatile_file(inode)) {
+- clear_inode_flag(inode, FI_VOLATILE_FILE);
+- stat_dec_volatile_write(inode);
+- ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true);
+- }
+-
+- inode_unlock(inode);
+-
+- mnt_drop_write_file(filp);
+- f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
+- return ret;
+-}
+-
+ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
+ {
+ struct inode *inode = file_inode(filp);
+@@ -4155,11 +4047,9 @@ static long __f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ case F2FS_IOC_COMMIT_ATOMIC_WRITE:
+ return f2fs_ioc_commit_atomic_write(filp);
+ case F2FS_IOC_START_VOLATILE_WRITE:
+- return f2fs_ioc_start_volatile_write(filp);
+ case F2FS_IOC_RELEASE_VOLATILE_WRITE:
+- return f2fs_ioc_release_volatile_write(filp);
+ case F2FS_IOC_ABORT_VOLATILE_WRITE:
+- return f2fs_ioc_abort_volatile_write(filp);
++ return -EOPNOTSUPP;
+ case F2FS_IOC_SHUTDOWN:
+ return f2fs_ioc_shutdown(filp, arg);
+ case FITRIM:
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 86a3c5a5a564..4115c6568e48 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -3167,8 +3167,7 @@ static int __get_segment_type_6(struct f2fs_io_info *fio)
+ return CURSEG_COLD_DATA;
+ if (file_is_hot(inode) ||
+ is_inode_flag_set(inode, FI_HOT_DATA) ||
+- f2fs_is_atomic_file(inode) ||
+- f2fs_is_volatile_file(inode))
++ f2fs_is_atomic_file(inode))
+ return CURSEG_HOT_DATA;
+ return f2fs_rw_hint_to_seg_type(inode->i_write_hint);
+ } else {
+diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c
+index 3d793202cc9f..5ac7e756a1bb 100644
+--- a/fs/f2fs/verity.c
++++ b/fs/f2fs/verity.c
+@@ -128,7 +128,7 @@ static int f2fs_begin_enable_verity(struct file *filp)
+ if (f2fs_verity_in_progress(inode))
+ return -EBUSY;
+
+- if (f2fs_is_atomic_file(inode) || f2fs_is_volatile_file(inode))
++ if (f2fs_is_atomic_file(inode))
+ return -EOPNOTSUPP;
+
+ /*
+--
+2.35.1
+
--- /dev/null
+From 51cb2b45cb0c04172d49833353707fcf6f2ae5b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Apr 2022 13:29:53 -0700
+Subject: f2fs: write checkpoint during FG_GC
+
+From: Byungki Lee <dominicus79@gmail.com>
+
+[ Upstream commit a9163b947ae8f7af7cb8d63606cd87b9facbfe74 ]
+
+If there's not enough free sections each of which consistis of large segments,
+we can hit no free section for upcoming section allocation. Let's reclaim some
+prefree segments by writing checkpoints.
+
+Signed-off-by: Byungki Lee <dominicus79@gmail.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/gc.c | 38 +++++++++++++++++++++++---------------
+ 1 file changed, 23 insertions(+), 15 deletions(-)
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 6a7e4148ff9d..a193862ad8a5 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1790,23 +1790,31 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
+ if (sync)
+ goto stop;
+
+- if (has_not_enough_free_secs(sbi, sec_freed, 0)) {
+- if (skipped_round <= MAX_SKIP_GC_COUNT ||
+- skipped_round * 2 < round) {
+- segno = NULL_SEGNO;
+- goto gc_more;
+- }
++ if (!has_not_enough_free_secs(sbi, sec_freed, 0))
++ goto stop;
+
+- if (first_skipped < last_skipped &&
+- (last_skipped - first_skipped) >
+- sbi->skipped_gc_rwsem) {
+- f2fs_drop_inmem_pages_all(sbi, true);
+- segno = NULL_SEGNO;
+- goto gc_more;
+- }
+- if (gc_type == FG_GC && !is_sbi_flag_set(sbi, SBI_CP_DISABLED))
++ if (skipped_round <= MAX_SKIP_GC_COUNT || skipped_round * 2 < round) {
++
++ /* Write checkpoint to reclaim prefree segments */
++ if (free_sections(sbi) < NR_CURSEG_PERSIST_TYPE &&
++ prefree_segments(sbi) &&
++ !is_sbi_flag_set(sbi, SBI_CP_DISABLED)) {
+ ret = f2fs_write_checkpoint(sbi, &cpc);
+- }
++ if (ret)
++ goto stop;
++ }
++ segno = NULL_SEGNO;
++ goto gc_more;
++ }
++ if (first_skipped < last_skipped &&
++ (last_skipped - first_skipped) >
++ sbi->skipped_gc_rwsem) {
++ f2fs_drop_inmem_pages_all(sbi, true);
++ segno = NULL_SEGNO;
++ goto gc_more;
++ }
++ if (gc_type == FG_GC && !is_sbi_flag_set(sbi, SBI_CP_DISABLED))
++ ret = f2fs_write_checkpoint(sbi, &cpc);
+ stop:
+ SIT_I(sbi)->last_victim[ALLOC_NEXT] = 0;
+ SIT_I(sbi)->last_victim[FLUSH_DEVICE] = init_segno;
+--
+2.35.1
+
--- /dev/null
+From 8345031d68e5a07882e9fd1ca38df39cab7add45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Apr 2022 01:36:48 +0000
+Subject: firmware: tegra: Fix error check return value of
+ debugfs_create_file()
+
+From: Lv Ruyi <lv.ruyi@zte.com.cn>
+
+[ Upstream commit afcdb8e55c91c6ff0700ab272fd0f74e899ab884 ]
+
+If an error occurs, debugfs_create_file() will return ERR_PTR(-ERROR),
+so use IS_ERR() to check it.
+
+Reported-by: Zeal Robot <zealci@zte.com.cn>
+Signed-off-by: Lv Ruyi <lv.ruyi@zte.com.cn>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/tegra/bpmp-debugfs.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/firmware/tegra/bpmp-debugfs.c b/drivers/firmware/tegra/bpmp-debugfs.c
+index fd89899aeeed..0c440afd5224 100644
+--- a/drivers/firmware/tegra/bpmp-debugfs.c
++++ b/drivers/firmware/tegra/bpmp-debugfs.c
+@@ -474,7 +474,7 @@ static int bpmp_populate_debugfs_inband(struct tegra_bpmp *bpmp,
+ mode |= attrs & DEBUGFS_S_IWUSR ? 0200 : 0;
+ dentry = debugfs_create_file(name, mode, parent, bpmp,
+ &bpmp_debug_fops);
+- if (!dentry) {
++ if (IS_ERR(dentry)) {
+ err = -ENOMEM;
+ goto out;
+ }
+@@ -725,7 +725,7 @@ static int bpmp_populate_dir(struct tegra_bpmp *bpmp, struct seqbuf *seqbuf,
+
+ if (t & DEBUGFS_S_ISDIR) {
+ dentry = debugfs_create_dir(name, parent);
+- if (!dentry)
++ if (IS_ERR(dentry))
+ return -ENOMEM;
+ err = bpmp_populate_dir(bpmp, seqbuf, dentry, depth+1);
+ if (err < 0)
+@@ -738,7 +738,7 @@ static int bpmp_populate_dir(struct tegra_bpmp *bpmp, struct seqbuf *seqbuf,
+ dentry = debugfs_create_file(name, mode,
+ parent, bpmp,
+ &debugfs_fops);
+- if (!dentry)
++ if (IS_ERR(dentry))
+ return -ENOMEM;
+ }
+ }
+@@ -788,11 +788,11 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
+ return 0;
+
+ root = debugfs_create_dir("bpmp", NULL);
+- if (!root)
++ if (IS_ERR(root))
+ return -ENOMEM;
+
+ bpmp->debugfs_mirror = debugfs_create_dir("debug", root);
+- if (!bpmp->debugfs_mirror) {
++ if (IS_ERR(bpmp->debugfs_mirror)) {
+ err = -ENOMEM;
+ goto out;
+ }
+--
+2.35.1
+
--- /dev/null
+From 78c3abc8892dafea611485250328c64b9ece8aff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 16:05:19 +0200
+Subject: fpga: altera-pr-ip: fix unsigned comparison with less than zero
+
+From: Marco Pagani <marpagan@redhat.com>
+
+[ Upstream commit 2df84a757d87fd62869fc401119d429735377ec5 ]
+
+Fix the "comparison with less than zero" warning reported by
+cppcheck for the unsigned (size_t) parameter count of the
+alt_pr_fpga_write() function.
+
+Fixes: d201cc17a8a3 ("fpga pr ip: Core driver support for Altera Partial Reconfiguration IP")
+Reviewed-by: Tom Rix <trix@redhat.com>
+Acked-by: Xu Yilun <yilun.xu@intel.com>
+Signed-off-by: Marco Pagani <marpagan@redhat.com>
+Link: https://lore.kernel.org/r/20220609140520.42662-1-marpagan@redhat.com
+Signed-off-by: Xu Yilun <yilun.xu@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/fpga/altera-pr-ip-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/fpga/altera-pr-ip-core.c b/drivers/fpga/altera-pr-ip-core.c
+index be0667968d33..df8671af4a92 100644
+--- a/drivers/fpga/altera-pr-ip-core.c
++++ b/drivers/fpga/altera-pr-ip-core.c
+@@ -108,7 +108,7 @@ static int alt_pr_fpga_write(struct fpga_manager *mgr, const char *buf,
+ u32 *buffer_32 = (u32 *)buf;
+ size_t i = 0;
+
+- if (count <= 0)
++ if (!count)
+ return -EINVAL;
+
+ /* Write out the complete 32-bit chunks */
+--
+2.35.1
+
--- /dev/null
+From f4e94ea506d5456af981419df4a307e81e2fd095 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jun 2022 15:06:58 +0200
+Subject: fs: check FMODE_LSEEK to control internal pipe splicing
+
+From: Jason A. Donenfeld <Jason@zx2c4.com>
+
+[ Upstream commit 97ef77c52b789ec1411d360ed99dca1efe4b2c81 ]
+
+The original direct splicing mechanism from Jens required the input to
+be a regular file because it was avoiding the special socket case. It
+also recognized blkdevs as being close enough to a regular file. But it
+forgot about chardevs, which behave the same way and work fine here.
+
+This is an okayish heuristic, but it doesn't totally work. For example,
+a few chardevs should be spliceable here. And a few regular files
+shouldn't. This patch fixes this by instead checking whether FMODE_LSEEK
+is set, which represents decently enough what we need rewinding for when
+splicing to internal pipes.
+
+Fixes: b92ce5589374 ("[PATCH] splice: add direct fd <-> fd splicing support")
+Cc: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/splice.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/fs/splice.c b/fs/splice.c
+index 047b79db8eb5..93a2c9bf6249 100644
+--- a/fs/splice.c
++++ b/fs/splice.c
+@@ -814,17 +814,15 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
+ {
+ struct pipe_inode_info *pipe;
+ long ret, bytes;
+- umode_t i_mode;
+ size_t len;
+ int i, flags, more;
+
+ /*
+- * We require the input being a regular file, as we don't want to
+- * randomly drop data for eg socket -> socket splicing. Use the
+- * piped splicing for that!
++ * We require the input to be seekable, as we don't want to randomly
++ * drop data for eg socket -> socket splicing. Use the piped splicing
++ * for that!
+ */
+- i_mode = file_inode(in)->i_mode;
+- if (unlikely(!S_ISREG(i_mode) && !S_ISBLK(i_mode)))
++ if (unlikely(!(in->f_mode & FMODE_LSEEK)))
+ return -EINVAL;
+
+ /*
+--
+2.35.1
+
--- /dev/null
+From a32f46ea4f49c38c0510bf4d965c12bc9c24d45a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 16:50:12 +0800
+Subject: fuse: Remove the control interface for virtio-fs
+
+From: Xie Yongji <xieyongji@bytedance.com>
+
+[ Upstream commit c64797809a64c73497082aa05e401a062ec1af34 ]
+
+The commit 15c8e72e88e0 ("fuse: allow skipping control interface and forced
+unmount") tries to remove the control interface for virtio-fs since it does
+not support aborting requests which are being processed. But it doesn't
+work now.
+
+This patch fixes it by skipping creating the control interface if
+fuse_conn->no_control is set.
+
+Fixes: 15c8e72e88e0 ("fuse: allow skipping control interface and forced unmount")
+Signed-off-by: Xie Yongji <xieyongji@bytedance.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fuse/control.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/fuse/control.c b/fs/fuse/control.c
+index 7cede9a3bc96..247ef4f76761 100644
+--- a/fs/fuse/control.c
++++ b/fs/fuse/control.c
+@@ -258,7 +258,7 @@ int fuse_ctl_add_conn(struct fuse_conn *fc)
+ struct dentry *parent;
+ char name[32];
+
+- if (!fuse_control_sb)
++ if (!fuse_control_sb || fc->no_control)
+ return 0;
+
+ parent = fuse_control_sb->s_root;
+@@ -296,7 +296,7 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc)
+ {
+ int i;
+
+- if (!fuse_control_sb)
++ if (!fuse_control_sb || fc->no_control)
+ return;
+
+ for (i = fc->ctl_ndents - 1; i >= 0; i--) {
+--
+2.35.1
+
--- /dev/null
+From 0a62d10b59208ff7e2857db11aa6c2877c275ab3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 15:13:22 -0300
+Subject: genelf: Use HAVE_LIBCRYPTO_SUPPORT, not the never defined
+ HAVE_LIBCRYPTO
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit 91cea6be90e436c55cde8770a15e4dac9d3032d0 ]
+
+When genelf was introduced it tested for HAVE_LIBCRYPTO not
+HAVE_LIBCRYPTO_SUPPORT, which is the define the feature test for openssl
+defines, fix it.
+
+This also adds disables the deprecation warning, someone has to fix this
+to build with openssl 3.0 before the warning becomes a hard error.
+
+Fixes: 9b07e27f88b9cd78 ("perf inject: Add jitdump mmap injection support")
+Reported-by: 谭梓煊 <tanzixuan.me@gmail.com>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Andrii Nakryiko <andrii@kernel.org>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Cc: KP Singh <kpsingh@kernel.org>
+Cc: Martin KaFai Lau <kafai@fb.com>
+Cc: Nick Terrell <terrelln@fb.com>
+Cc: Song Liu <songliubraving@fb.com>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lore.kernel.org/lkml/YulpPqXSOG0Q4J1o@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/genelf.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/genelf.c b/tools/perf/util/genelf.c
+index aed49806a09b..953338b9e887 100644
+--- a/tools/perf/util/genelf.c
++++ b/tools/perf/util/genelf.c
+@@ -30,7 +30,11 @@
+
+ #define BUILD_ID_URANDOM /* different uuid for each run */
+
+-#ifdef HAVE_LIBCRYPTO
++// FIXME, remove this and fix the deprecation warnings before its removed and
++// We'll break for good here...
++#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
++
++#ifdef HAVE_LIBCRYPTO_SUPPORT
+
+ #define BUILD_ID_MD5
+ #undef BUILD_ID_SHA /* does not seem to work well when linked with Java */
+--
+2.35.1
+
--- /dev/null
+From f3daf1446f05ce7d5fa93f63e45f24eb6ae4668a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 May 2022 18:05:44 +0200
+Subject: genirq: Don't return error on missing optional
+ irq_request_resources()
+
+From: Antonio Borneo <antonio.borneo@foss.st.com>
+
+[ Upstream commit 95001b756467ecc9f5973eb5e74e97699d9bbdf1 ]
+
+Function irq_chip::irq_request_resources() is reported as optional
+in the declaration of struct irq_chip.
+If the parent irq_chip does not implement it, we should ignore it
+and return.
+
+Don't return error if the functions is missing.
+
+Signed-off-by: Antonio Borneo <antonio.borneo@foss.st.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220512160544.13561-1-antonio.borneo@foss.st.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/irq/chip.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
+index 54af0deb239b..eb921485930f 100644
+--- a/kernel/irq/chip.c
++++ b/kernel/irq/chip.c
+@@ -1513,7 +1513,8 @@ int irq_chip_request_resources_parent(struct irq_data *data)
+ if (data->chip->irq_request_resources)
+ return data->chip->irq_request_resources(data);
+
+- return -ENOSYS;
++ /* no error on missing optional irq_chip::irq_request_resources */
++ return 0;
+ }
+ EXPORT_SYMBOL_GPL(irq_chip_request_resources_parent);
+
+--
+2.35.1
+
--- /dev/null
+From 76fc9fa9435725e72d834038a0f0fc02d9ce9a5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 15:00:50 -0500
+Subject: genirq: GENERIC_IRQ_IPI depends on SMP
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit 0f5209fee90b4544c58b4278d944425292789967 ]
+
+The generic IPI code depends on the IRQ affinity mask being allocated
+and initialized. This will not be the case if SMP is disabled. Fix up
+the remaining driver that selected GENERIC_IRQ_IPI in a non-SMP config.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220701200056.46555-3-samuel@sholland.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/Kconfig | 2 +-
+ kernel/irq/Kconfig | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
+index d43d25a411dd..1af26c409cb1 100644
+--- a/drivers/irqchip/Kconfig
++++ b/drivers/irqchip/Kconfig
+@@ -177,7 +177,7 @@ config MADERA_IRQ
+ config IRQ_MIPS_CPU
+ bool
+ select GENERIC_IRQ_CHIP
+- select GENERIC_IRQ_IPI if SYS_SUPPORTS_MULTITHREADING
++ select GENERIC_IRQ_IPI if SMP && SYS_SUPPORTS_MULTITHREADING
+ select IRQ_DOMAIN
+ select GENERIC_IRQ_EFFECTIVE_AFF_MASK
+
+diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
+index 10929eda9825..fc760d064a65 100644
+--- a/kernel/irq/Kconfig
++++ b/kernel/irq/Kconfig
+@@ -82,6 +82,7 @@ config IRQ_FASTEOI_HIERARCHY_HANDLERS
+ # Generic IRQ IPI support
+ config GENERIC_IRQ_IPI
+ bool
++ depends on SMP
+ select IRQ_DOMAIN_HIERARCHY
+
+ # Generic MSI interrupt support
+--
+2.35.1
+
--- /dev/null
+From 80c099e645ff8e88126cdf20501b86c66854417a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 20:52:38 +0800
+Subject: gpio: gpiolib-of: Fix refcount bugs in of_mm_gpiochip_add_data()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 5d07a692f9562f9c06e62cce369e9dd108173a0f ]
+
+We should use of_node_get() when a new reference of device_node
+is created. It is noted that the old reference stored in
+'mm_gc->gc.of_node' should also be decreased.
+
+This patch is based on the fact that there is a call site in function
+'qe_add_gpiochips()' of src file 'drivers\soc\fsl\qe\gpio.c'. In this
+function, of_mm_gpiochip_add_data() is contained in an iteration of
+for_each_compatible_node() which will automatically increase and
+decrease the refcount. So we need additional of_node_get() for the
+reference escape in of_mm_gpiochip_add_data().
+
+Fixes: a19e3da5bc5f ("of/gpio: Kill of_gpio_chip and add members directly to gpio_chip")
+Signed-off-by: Liang He <windhl@126.com>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpiolib-of.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
+index 6dec81b1f24b..5cabb9a9c272 100644
+--- a/drivers/gpio/gpiolib-of.c
++++ b/drivers/gpio/gpiolib-of.c
+@@ -861,7 +861,8 @@ int of_mm_gpiochip_add_data(struct device_node *np,
+ if (mm_gc->save_regs)
+ mm_gc->save_regs(mm_gc);
+
+- mm_gc->gc.of_node = np;
++ of_node_put(mm_gc->gc.of_node);
++ mm_gc->gc.of_node = of_node_get(np);
+
+ ret = gpiochip_add_data(gc, data);
+ if (ret)
+@@ -869,6 +870,7 @@ int of_mm_gpiochip_add_data(struct device_node *np,
+
+ return 0;
+ err2:
++ of_node_put(np);
+ iounmap(mm_gc->regs);
+ err1:
+ kfree(gc->label);
+--
+2.35.1
+
--- /dev/null
+From 96fa66117bf7b117c785cea1015958f7bc509e9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 18:41:23 -0300
+Subject: hantro: Remove incorrect HEVC SPS validation
+
+From: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+
+[ Upstream commit df9ec2fc8e70e01532fd9161cd98711969561ff6 ]
+
+Currently, the driver tries to validat the HEVC SPS
+against the CAPTURE queue format (i.e. the decoded format).
+This is not correct, because typically the SPS control is set
+before the CAPTURE queue is negotiated.
+
+Fixes: 135ad96cb4d6b ("media: hantro: Be more accurate on pixel formats step_width constraints")
+Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/hantro/hantro_drv.c | 12 ++++++------
+ drivers/staging/media/hantro/hantro_hevc.c | 9 +--------
+ drivers/staging/media/hantro/hantro_hw.h | 1 -
+ 3 files changed, 7 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
+index 01d33dcb0467..ac232b5f7825 100644
+--- a/drivers/staging/media/hantro/hantro_drv.c
++++ b/drivers/staging/media/hantro/hantro_drv.c
+@@ -253,11 +253,6 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
+
+ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
+ {
+- struct hantro_ctx *ctx;
+-
+- ctx = container_of(ctrl->handler,
+- struct hantro_ctx, ctrl_handler);
+-
+ if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) {
+ const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
+
+@@ -273,7 +268,12 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
+ } else if (ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_SPS) {
+ const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps;
+
+- return hantro_hevc_validate_sps(ctx, sps);
++ if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8)
++ /* Luma and chroma bit depth mismatch */
++ return -EINVAL;
++ if (sps->bit_depth_luma_minus8 != 0)
++ /* Only 8-bit is supported */
++ return -EINVAL;
+ } else if (ctrl->id == V4L2_CID_STATELESS_VP9_FRAME) {
+ const struct v4l2_ctrl_vp9_frame *dec_params = ctrl->p_new.p_vp9_frame;
+
+diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
+index 4f7e2acb46ec..df1f81952bba 100644
+--- a/drivers/staging/media/hantro/hantro_hevc.c
++++ b/drivers/staging/media/hantro/hantro_hevc.c
+@@ -154,15 +154,8 @@ static int tile_buffer_reallocate(struct hantro_ctx *ctx)
+ return -ENOMEM;
+ }
+
+-int hantro_hevc_validate_sps(struct hantro_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps)
++static int hantro_hevc_validate_sps(struct hantro_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps)
+ {
+- if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8)
+- /* Luma and chroma bit depth mismatch */
+- return -EINVAL;
+- if (sps->bit_depth_luma_minus8 != 0)
+- /* Only 8-bit is supported */
+- return -EINVAL;
+-
+ /*
+ * for tile pixel format check if the width and height match
+ * hardware constraints
+diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
+index 457eb8bb6dc2..68c313864b06 100644
+--- a/drivers/staging/media/hantro/hantro_hw.h
++++ b/drivers/staging/media/hantro/hantro_hw.h
+@@ -353,7 +353,6 @@ int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx);
+ void hantro_hevc_ref_init(struct hantro_ctx *ctx);
+ dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, s32 poc);
+ int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr);
+-int hantro_hevc_validate_sps(struct hantro_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps);
+
+
+ static inline unsigned short hantro_vp9_num_sbs(unsigned short dimension)
+--
+2.35.1
+
--- /dev/null
+From 99bf0e2f13470eb3f34981f7652d594545071401 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 17:53:24 +0300
+Subject: HID: alps: Declare U1_UNICORN_LEGACY support
+
+From: Artem Borisov <dedsa2002@gmail.com>
+
+[ Upstream commit 1117d182c5d72abd7eb8b7d5e7b8c3373181c3ab ]
+
+U1_UNICORN_LEGACY id was added to the driver, but was not declared
+in the device id table, making it impossible to use.
+
+Fixes: 640e403 ("HID: alps: Add AUI1657 device ID")
+Signed-off-by: Artem Borisov <dedsa2002@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-alps.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c
+index 2b986d0dbde4..db146d0f7937 100644
+--- a/drivers/hid/hid-alps.c
++++ b/drivers/hid/hid-alps.c
+@@ -830,6 +830,8 @@ static const struct hid_device_id alps_id[] = {
+ USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) },
+ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
+ USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1) },
++ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
++ USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY) },
+ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
+ USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_T4_BTNLESS) },
+ { }
+--
+2.35.1
+
--- /dev/null
+From ca466a8f392e3c969630b5cf5c9f0558fc853084 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 23:48:26 +0530
+Subject: HID: amd_sfh: Add NULL check for hid device
+
+From: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+
+[ Upstream commit 06aa2a43c307cf4096f422dcb575e5d2913e528f ]
+
+On removal of hid device during SFH set report may cause NULL pointer
+exception. Hence add NULL check for hid device before accessing.
+
+Fixes: 4b2c53d93a4b ("SFH:Transport Driver to add support of AMD Sensor Fusion Hub (SFH)")
+Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/amd-sfh-hid/amd_sfh_hid.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
+index e2a9679e32be..54fe224050f9 100644
+--- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
++++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
+@@ -100,11 +100,15 @@ static int amdtp_wait_for_response(struct hid_device *hid)
+
+ void amdtp_hid_wakeup(struct hid_device *hid)
+ {
+- struct amdtp_hid_data *hid_data = hid->driver_data;
+- struct amdtp_cl_data *cli_data = hid_data->cli_data;
++ struct amdtp_hid_data *hid_data;
++ struct amdtp_cl_data *cli_data;
+
+- cli_data->request_done[cli_data->cur_hid_dev] = true;
+- wake_up_interruptible(&hid_data->hid_wait);
++ if (hid) {
++ hid_data = hid->driver_data;
++ cli_data = hid_data->cli_data;
++ cli_data->request_done[cli_data->cur_hid_dev] = true;
++ wake_up_interruptible(&hid_data->hid_wait);
++ }
+ }
+
+ static struct hid_ll_driver amdtp_hid_ll_driver = {
+--
+2.35.1
+
--- /dev/null
+From 82f8707e16e337fecc1ebf394b7d04fafcd720ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 May 2022 13:18:48 -0500
+Subject: HID: amd_sfh: Don't show client init failed as error when discovery
+ fails
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit e51d8d3ea3d773334d2c047c8d1623dba66f592a ]
+
+When sensor discovery fails, this means that the system doesn't have
+any sensors connected and a user should only be notified at most one time.
+A message is already displayed at WARN level of "failed to discover,
+sensors not enabled". It's pointless to show that the client init failed
+at ERR level for the same condition.
+
+Check the return code and don't display this message in those conditions.
+
+Fixes: b5d7f43e97da ("HID: amd_sfh: Add support for sensor discovery")
+Reported-by: David Chang <David.Chang@amd.com>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Acked-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+index e18a4efd8839..390298a6fc85 100644
+--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
++++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+@@ -327,7 +327,8 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
+ rc = amd_sfh_hid_client_init(privdata);
+ if (rc) {
+ amd_sfh_clear_intr(privdata);
+- dev_err(&pdev->dev, "amd_sfh_hid_client_init failed\n");
++ if (rc != -EOPNOTSUPP)
++ dev_err(&pdev->dev, "amd_sfh_hid_client_init failed\n");
+ return rc;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 392160cd932049f90a59c6d8e4ef12e1ad36a52d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Jul 2022 11:40:33 +0530
+Subject: HID: amd_sfh: Handle condition of "no sensors"
+
+From: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+
+[ Upstream commit 5d4d0f15657535f6a122ab26d47230b5c2b944af ]
+
+Add a check for num_hid_devices to handle special case the situation
+of "no sensors".
+
+Fixes: 4b2c53d93a4b ("SFH:Transport Driver to add support of AMD Sensor Fusion Hub (SFH)")
+Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/amd-sfh-hid/amd_sfh_client.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+index 444acd9e2cd6..8be33cf3b6c2 100644
+--- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c
++++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+@@ -155,6 +155,8 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
+ dev = &privdata->pdev->dev;
+
+ cl_data->num_hid_devices = amd_mp2_get_sensor_num(privdata, &cl_data->sensor_idx[0]);
++ if (cl_data->num_hid_devices == 0)
++ return -ENODEV;
+
+ INIT_DELAYED_WORK(&cl_data->work, amd_sfh_work);
+ INIT_DELAYED_WORK(&cl_data->work_buffer, amd_sfh_work_buffer);
+--
+2.35.1
+
--- /dev/null
+From 480118cbb1049c83376a0954adc288aa557b3f29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 05:26:09 -0700
+Subject: HID: cp2112: prevent a buffer overflow in cp2112_xfer()
+
+From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+
+[ Upstream commit 381583845d19cb4bd21c8193449385f3fefa9caf ]
+
+Smatch warnings:
+drivers/hid/hid-cp2112.c:793 cp2112_xfer() error: __memcpy()
+'data->block[1]' too small (33 vs 255)
+drivers/hid/hid-cp2112.c:793 cp2112_xfer() error: __memcpy() 'buf' too
+small (64 vs 255)
+
+The 'read_length' variable is provided by 'data->block[0]' which comes
+from user and it(read_length) can take a value between 0-255. Add an
+upper bound to 'read_length' variable to prevent a buffer overflow in
+memcpy().
+
+Fixes: 542134c0375b ("HID: cp2112: Fix I2C_BLOCK_DATA transactions")
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-cp2112.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c
+index ece147d1a278..1e16b0fa310d 100644
+--- a/drivers/hid/hid-cp2112.c
++++ b/drivers/hid/hid-cp2112.c
+@@ -790,6 +790,11 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr,
+ data->word = le16_to_cpup((__le16 *)buf);
+ break;
+ case I2C_SMBUS_I2C_BLOCK_DATA:
++ if (read_length > I2C_SMBUS_BLOCK_MAX) {
++ ret = -EINVAL;
++ goto power_normal;
++ }
++
+ memcpy(data->block + 1, buf, read_length);
+ break;
+ case I2C_SMBUS_BLOCK_DATA:
+--
+2.35.1
+
--- /dev/null
+From f2203d000ed1915fdbdc173b2e9fd82b7bdd7170 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 09:28:24 -0700
+Subject: HID: mcp2221: prevent a buffer overflow in mcp_smbus_write()
+
+From: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+
+[ Upstream commit 62ac2473553a00229e67bdf3cb023b62cf7f5a9a ]
+
+Smatch Warning:
+drivers/hid/hid-mcp2221.c:388 mcp_smbus_write() error: __memcpy()
+'&mcp->txbuf[5]' too small (59 vs 255)
+drivers/hid/hid-mcp2221.c:388 mcp_smbus_write() error: __memcpy() 'buf'
+too small (34 vs 255)
+
+The 'len' variable can take a value between 0-255 as it can come from
+data->block[0] and it is user data. So add an bound check to prevent a
+buffer overflow in memcpy().
+
+Fixes: 67a95c21463d ("HID: mcp2221: add usb to i2c-smbus host bridge")
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-mcp2221.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
+index 4211b9839209..de52e9f7bb8c 100644
+--- a/drivers/hid/hid-mcp2221.c
++++ b/drivers/hid/hid-mcp2221.c
+@@ -385,6 +385,9 @@ static int mcp_smbus_write(struct mcp2221 *mcp, u16 addr,
+ data_len = 7;
+ break;
+ default:
++ if (len > I2C_SMBUS_BLOCK_MAX)
++ return -EINVAL;
++
+ memcpy(&mcp->txbuf[5], buf, len);
+ data_len = len + 5;
+ }
+--
+2.35.1
+
--- /dev/null
+From 46b221c01cf3b862db9265c25abab8275c339650 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 26 Jun 2022 18:27:45 +0200
+Subject: hinic: Use the bitmap API when applicable
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 7c2c57263af41cfd8b5022274e6801542831bb69 ]
+
+'vlan_bitmap' is a bitmap and is used as such. So allocate it with
+devm_bitmap_zalloc() and its explicit bit size (i.e. VLAN_N_VID).
+
+This avoids the need of the VLAN_BITMAP_SIZE macro which:
+ - needlessly has a 'nic_dev' parameter
+ - should be "long" (and not byte) aligned, so that the bitmap semantic
+ is respected
+
+This is in fact not an issue because VLAN_N_VID is 4096 at the time
+being, but devm_bitmap_zalloc() is less verbose and easier to understand.
+
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/6ff7b7d21414240794a77dc2456914412718a145.1656260842.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/huawei/hinic/hinic_main.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+index 05329292d940..56a89793f47d 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+@@ -62,8 +62,6 @@ MODULE_PARM_DESC(rx_weight, "Number Rx packets for NAPI budget (default=64)");
+
+ #define HINIC_LRO_RX_TIMER_DEFAULT 16
+
+-#define VLAN_BITMAP_SIZE(nic_dev) (ALIGN(VLAN_N_VID, 8) / 8)
+-
+ #define work_to_rx_mode_work(work) \
+ container_of(work, struct hinic_rx_mode_work, work)
+
+@@ -1242,9 +1240,8 @@ static int nic_dev_init(struct pci_dev *pdev)
+ u64_stats_init(&tx_stats->syncp);
+ u64_stats_init(&rx_stats->syncp);
+
+- nic_dev->vlan_bitmap = devm_kzalloc(&pdev->dev,
+- VLAN_BITMAP_SIZE(nic_dev),
+- GFP_KERNEL);
++ nic_dev->vlan_bitmap = devm_bitmap_zalloc(&pdev->dev, VLAN_N_VID,
++ GFP_KERNEL);
+ if (!nic_dev->vlan_bitmap) {
+ err = -ENOMEM;
+ goto err_vlan_bitmap;
+--
+2.35.1
+
--- /dev/null
+From 6c544d329b9f5877187e00c9afecc7ffbbe0dd06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jun 2022 06:18:06 +0200
+Subject: hwmon: (dell-smm) Add Dell XPS 13 7390 to fan control whitelist
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit 385e5f57053ff293282fea84c1c27186d53f66e1 ]
+
+A user reported that the program dell-bios-fan-control
+worked on his Dell XPS 13 7390 to switch off automatic
+fan control.
+Since it uses the same mechanism as the dell_smm_hwmon
+module, add this model to the fan control whitelist.
+
+Compile-tested only.
+
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Acked-by: Pali Rohár <pali@kernel.org>
+Link: https://lore.kernel.org/r/20220612041806.11367-1-W_Armin@gmx.de
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/dell-smm-hwmon.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c
+index 84cb1ede7bc0..a0df9a0abeb9 100644
+--- a/drivers/hwmon/dell-smm-hwmon.c
++++ b/drivers/hwmon/dell-smm-hwmon.c
+@@ -1262,6 +1262,14 @@ static const struct dmi_system_id i8k_whitelist_fan_control[] __initconst = {
+ },
+ .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],
+ },
++ {
++ .ident = "Dell XPS 13 7390",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS 13 7390"),
++ },
++ .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],
++ },
+ { }
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 2face96a092a80cfb86e631e20920df1154d0f70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 23:46:24 +0200
+Subject: hwmon: (drivetemp) Add module alias
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit 5918036cfa8ded7aa8094db70295011ce2275447 ]
+
+Adding a MODULE_ALIAS() to drivetemp will make the driver easier
+for modprobe to autoprobe.
+
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20220712214624.1845158-1-linus.walleij@linaro.org
+Fixes: 5b46903d8bf3 ("hwmon: Driver for disk and solid state drives with temperature sensors")
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/drivetemp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hwmon/drivetemp.c b/drivers/hwmon/drivetemp.c
+index 1eb37106a220..5bac2b0fc7bb 100644
+--- a/drivers/hwmon/drivetemp.c
++++ b/drivers/hwmon/drivetemp.c
+@@ -621,3 +621,4 @@ module_exit(drivetemp_exit);
+ MODULE_AUTHOR("Guenter Roeck <linus@roeck-us.net>");
+ MODULE_DESCRIPTION("Hard drive temperature monitor");
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:drivetemp");
+--
+2.35.1
+
--- /dev/null
+From 6e97a115a10f0161e5e8f4b203565b1d5630123d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jun 2022 00:02:00 +0200
+Subject: hwmon: (sch56xx-common) Add DMI override table
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit fd2d53c367ae9983c2100ac733a834e0c79d7537 ]
+
+Some devices like the Fujitsu Celsius W380 do contain
+a working sch56xx hardware monitoring device, but do
+not contain the necessary DMI onboard device.
+
+Do not check for the presence of an suitable onboard device
+on these machines. The list of affected machines was created
+using data collected by the Linux Hardware Project.
+
+Tested on a Fujitsu Esprimo P720, but sadly not on a affected
+machine.
+
+Fixes: 393935baa45e (hwmon: (sch56xx-common) Add automatic module loading on supported devices)
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20220604220200.2567-1-W_Armin@gmx.de
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/sch56xx-common.c | 44 ++++++++++++++++++++++++++--------
+ 1 file changed, 34 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/hwmon/sch56xx-common.c b/drivers/hwmon/sch56xx-common.c
+index 3ece53adabd6..de3a0886c2f7 100644
+--- a/drivers/hwmon/sch56xx-common.c
++++ b/drivers/hwmon/sch56xx-common.c
+@@ -523,6 +523,28 @@ static int __init sch56xx_device_add(int address, const char *name)
+ return PTR_ERR_OR_ZERO(sch56xx_pdev);
+ }
+
++static const struct dmi_system_id sch56xx_dmi_override_table[] __initconst = {
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS W380"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO P710"),
++ },
++ },
++ {
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO E9900"),
++ },
++ },
++ { }
++};
++
+ /* For autoloading only */
+ static const struct dmi_system_id sch56xx_dmi_table[] __initconst = {
+ {
+@@ -543,16 +565,18 @@ static int __init sch56xx_init(void)
+ if (!dmi_check_system(sch56xx_dmi_table))
+ return -ENODEV;
+
+- /*
+- * Some machines like the Esprimo P720 and Esprimo C700 have
+- * onboard devices named " Antiope"/" Theseus" instead of
+- * "Antiope"/"Theseus", so we need to check for both.
+- */
+- if (!dmi_find_device(DMI_DEV_TYPE_OTHER, "Antiope", NULL) &&
+- !dmi_find_device(DMI_DEV_TYPE_OTHER, " Antiope", NULL) &&
+- !dmi_find_device(DMI_DEV_TYPE_OTHER, "Theseus", NULL) &&
+- !dmi_find_device(DMI_DEV_TYPE_OTHER, " Theseus", NULL))
+- return -ENODEV;
++ if (!dmi_check_system(sch56xx_dmi_override_table)) {
++ /*
++ * Some machines like the Esprimo P720 and Esprimo C700 have
++ * onboard devices named " Antiope"/" Theseus" instead of
++ * "Antiope"/"Theseus", so we need to check for both.
++ */
++ if (!dmi_find_device(DMI_DEV_TYPE_OTHER, "Antiope", NULL) &&
++ !dmi_find_device(DMI_DEV_TYPE_OTHER, " Antiope", NULL) &&
++ !dmi_find_device(DMI_DEV_TYPE_OTHER, "Theseus", NULL) &&
++ !dmi_find_device(DMI_DEV_TYPE_OTHER, " Theseus", NULL))
++ return -ENODEV;
++ }
+ }
+
+ /*
+--
+2.35.1
+
--- /dev/null
+From f44d0c29e21adebf4c729f7e5bc8512155eb59ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 21:43:44 +0200
+Subject: hwmon: (sht15) Fix wrong assumptions in device remove callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 7d4edccc9bbfe1dcdff641343f7b0c6763fbe774 ]
+
+Taking a lock at the beginning of .remove() doesn't prevent new readers.
+With the existing approach it can happen, that a read occurs just when
+the lock was taken blocking the reader until the lock is released at the
+end of the remove callback which then accessed *data that is already
+freed then.
+
+To actually fix this problem the hwmon core needs some adaption. Until
+this is implemented take the optimistic approach of assuming that all
+readers are gone after hwmon_device_unregister() and
+sysfs_remove_group() as most other drivers do. (And once the core
+implements that, taking the lock would deadlock.)
+
+So drop the lock, move the reset to after device unregistration to keep
+the device in a workable state until it's deregistered. Also add a error
+message in case the reset fails and return 0 anyhow. (Returning an error
+code, doesn't stop the platform device unregistration and only results
+in a little helpful error message before the devm cleanup handlers are
+called.)
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20220725194344.150098-1-u.kleine-koenig@pengutronix.de
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/sht15.c | 17 ++++++-----------
+ 1 file changed, 6 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
+index 7f4a63959730..ae4d14257a11 100644
+--- a/drivers/hwmon/sht15.c
++++ b/drivers/hwmon/sht15.c
+@@ -1020,25 +1020,20 @@ static int sht15_probe(struct platform_device *pdev)
+ static int sht15_remove(struct platform_device *pdev)
+ {
+ struct sht15_data *data = platform_get_drvdata(pdev);
++ int ret;
+
+- /*
+- * Make sure any reads from the device are done and
+- * prevent new ones beginning
+- */
+- mutex_lock(&data->read_lock);
+- if (sht15_soft_reset(data)) {
+- mutex_unlock(&data->read_lock);
+- return -EFAULT;
+- }
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group);
++
++ ret = sht15_soft_reset(data);
++ if (ret)
++ dev_err(&pdev->dev, "Failed to reset device (%pe)\n", ERR_PTR(ret));
++
+ if (!IS_ERR(data->reg)) {
+ regulator_unregister_notifier(data->reg, &data->nb);
+ regulator_disable(data->reg);
+ }
+
+- mutex_unlock(&data->read_lock);
+-
+ return 0;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 5b19a3b1f1d1380cd873dcb38086356b6b0850c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 16:52:44 +0200
+Subject: i2c: cadence: Support PEC for SMBus block read
+
+From: Lars-Peter Clausen <lars@metafoo.de>
+
+[ Upstream commit 9fdf6d97f03035ad5298e2d1635036c74c2090ed ]
+
+SMBus packet error checking (PEC) is implemented by appending one
+additional byte of checksum data at the end of the message. This provides
+additional protection and allows to detect data corruption on the I2C bus.
+
+SMBus block reads support variable length reads. The first byte in the read
+message is the number of available data bytes.
+
+The combination of PEC and block read is currently not supported by the
+Cadence I2C driver.
+ * When PEC is enabled the maximum transfer length for block reads
+ increases from 33 to 34 bytes.
+ * The I2C core smbus emulation layer relies on the driver updating the
+ `i2c_msg` `len` field with the number of received bytes. The updated
+ length is used when checking the PEC.
+
+Add support to the Cadence I2C driver for handling SMBus block reads with
+PEC. To determine the maximum transfer length uses the initial `len` value
+of the `i2c_msg`. When PEC is enabled this will be 2, when it is disabled
+it will be 1.
+
+Once a read transfer is done also increment the `len` field by the amount
+of received data bytes.
+
+This change has been tested with a UCM90320 PMBus power monitor, which
+requires block reads to access certain data fields, but also has PEC
+enabled by default.
+
+Fixes: df8eb5691c48 ("i2c: Add driver for Cadence I2C controller")
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Tested-by: Shubhrajyoti Datta <Shubhrajyoti.datta@amd.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-cadence.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
+index 630cfa4ddd46..33f5588a50c0 100644
+--- a/drivers/i2c/busses/i2c-cadence.c
++++ b/drivers/i2c/busses/i2c-cadence.c
+@@ -573,8 +573,13 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
+ ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET);
+ ctrl_reg |= CDNS_I2C_CR_RW | CDNS_I2C_CR_CLR_FIFO;
+
++ /*
++ * Receive up to I2C_SMBUS_BLOCK_MAX data bytes, plus one message length
++ * byte, plus one checksum byte if PEC is enabled. p_msg->len will be 2 if
++ * PEC is enabled, otherwise 1.
++ */
+ if (id->p_msg->flags & I2C_M_RECV_LEN)
+- id->recv_count = I2C_SMBUS_BLOCK_MAX + 1;
++ id->recv_count = I2C_SMBUS_BLOCK_MAX + id->p_msg->len;
+
+ id->curr_recv_count = id->recv_count;
+
+@@ -789,6 +794,9 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg,
+ if (id->err_status & CDNS_I2C_IXR_ARB_LOST)
+ return -EAGAIN;
+
++ if (msg->flags & I2C_M_RECV_LEN)
++ msg->len += min_t(unsigned int, msg->buf[0], I2C_SMBUS_BLOCK_MAX);
++
+ return 0;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 2be22bd90d90f4eacfb8ec119d62da310f4d58e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Dec 2019 09:34:32 +0000
+Subject: i2c: Fix a potential use after free
+
+From: Xu Wang <vulab@iscas.ac.cn>
+
+[ Upstream commit e4c72c06c367758a14f227c847f9d623f1994ecf ]
+
+Free the adap structure only after we are done using it.
+This patch just moves the put_device() down a bit to avoid the
+use after free.
+
+Fixes: 611e12ea0f12 ("i2c: core: manage i2c bus device refcount in i2c_[get|put]_adapter")
+Signed-off-by: Xu Wang <vulab@iscas.ac.cn>
+[wsa: added comment to the code, added Fixes tag]
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/i2c-core-base.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
+index d43db2c3876e..19a317fdcf5b 100644
+--- a/drivers/i2c/i2c-core-base.c
++++ b/drivers/i2c/i2c-core-base.c
+@@ -2467,8 +2467,9 @@ void i2c_put_adapter(struct i2c_adapter *adap)
+ if (!adap)
+ return;
+
+- put_device(&adap->dev);
+ module_put(adap->owner);
++ /* Should be last, otherwise we risk use-after-free with 'adap' */
++ put_device(&adap->dev);
+ }
+ EXPORT_SYMBOL(i2c_put_adapter);
+
+--
+2.35.1
+
--- /dev/null
+From f329332565d3474a6beab97d7dbfaba4d11761c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 09:24:01 +0800
+Subject: i2c: mux-gpmux: Add of_node_put() when breaking out of loop
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 6435319c34704994e19b0767f6a4e6f37439867b ]
+
+In i2c_mux_probe(), we should call of_node_put() when breaking out
+of for_each_child_of_node() which will automatically increase and
+decrease the refcount.
+
+Fixes: ac8498f0ce53 ("i2c: i2c-mux-gpmux: new driver")
+Signed-off-by: Liang He <windhl@126.com>
+Acked-by: Peter Rosin <peda@axentia.se>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/muxes/i2c-mux-gpmux.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/i2c/muxes/i2c-mux-gpmux.c b/drivers/i2c/muxes/i2c-mux-gpmux.c
+index d3acd8d66c32..33024acaac02 100644
+--- a/drivers/i2c/muxes/i2c-mux-gpmux.c
++++ b/drivers/i2c/muxes/i2c-mux-gpmux.c
+@@ -134,6 +134,7 @@ static int i2c_mux_probe(struct platform_device *pdev)
+ return 0;
+
+ err_children:
++ of_node_put(child);
+ i2c_mux_del_adapters(muxc);
+ err_parent:
+ i2c_put_adapter(parent);
+--
+2.35.1
+
--- /dev/null
+From 8174b5608a97673b887615515e388d6306282451 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 22:09:14 -0300
+Subject: i2c: mxs: Silence a clang warning
+
+From: Fabio Estevam <festevam@gmail.com>
+
+[ Upstream commit 3d43273d7d1e1a5374d531e901d3c537b4c97bbf ]
+
+Change the of_device_get_match_data() cast to (uintptr_t)
+to silence the following clang warning:
+
+drivers/i2c/busses/i2c-mxs.c:802:18: warning: cast to smaller integer type 'enum mxs_i2c_devtype' from 'const void *' [-Wvoid-pointer-to-enum-cast]
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: c32abd8b5691 ("i2c: mxs: Remove unneeded platform_device_id")
+Signed-off-by: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-mxs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
+index 864a3f1bd4e1..68f67d084c63 100644
+--- a/drivers/i2c/busses/i2c-mxs.c
++++ b/drivers/i2c/busses/i2c-mxs.c
+@@ -799,7 +799,7 @@ static int mxs_i2c_probe(struct platform_device *pdev)
+ if (!i2c)
+ return -ENOMEM;
+
+- i2c->dev_type = (enum mxs_i2c_devtype)of_device_get_match_data(&pdev->dev);
++ i2c->dev_type = (uintptr_t)of_device_get_match_data(&pdev->dev);
+
+ i2c->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(i2c->regs))
+--
+2.35.1
+
--- /dev/null
+From 32f40d080834d30e0a2a91d50d10fd4b7ac1e060 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 11:23:39 +0800
+Subject: i2c: npcm: Correct slave role behavior
+
+From: Tali Perry <tali.perry1@gmail.com>
+
+[ Upstream commit d7aa1b149b8fc04d802879cf4662010aa4a42deb ]
+
+Correct the slave transaction logic to be compatible with the generic
+slave backend driver.
+
+Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
+Signed-off-by: Tali Perry <tali.perry1@gmail.com>
+Signed-off-by: Tyrone Ting <kfting@nuvoton.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-npcm7xx.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c
+index bc462d257baa..9f0462fb2504 100644
+--- a/drivers/i2c/busses/i2c-npcm7xx.c
++++ b/drivers/i2c/busses/i2c-npcm7xx.c
+@@ -912,11 +912,15 @@ static int npcm_i2c_slave_get_wr_buf(struct npcm_i2c *bus)
+ for (i = 0; i < I2C_HW_FIFO_SIZE; i++) {
+ if (bus->slv_wr_size >= I2C_HW_FIFO_SIZE)
+ break;
+- i2c_slave_event(bus->slave, I2C_SLAVE_READ_REQUESTED, &value);
++ if (bus->state == I2C_SLAVE_MATCH) {
++ i2c_slave_event(bus->slave, I2C_SLAVE_READ_REQUESTED, &value);
++ bus->state = I2C_OPER_STARTED;
++ } else {
++ i2c_slave_event(bus->slave, I2C_SLAVE_READ_PROCESSED, &value);
++ }
+ ind = (bus->slv_wr_ind + bus->slv_wr_size) % I2C_HW_FIFO_SIZE;
+ bus->slv_wr_buf[ind] = value;
+ bus->slv_wr_size++;
+- i2c_slave_event(bus->slave, I2C_SLAVE_READ_PROCESSED, &value);
+ }
+ return I2C_HW_FIFO_SIZE - ret;
+ }
+@@ -964,7 +968,6 @@ static void npcm_i2c_slave_xmit(struct npcm_i2c *bus, u16 nwrite,
+ if (nwrite == 0)
+ return;
+
+- bus->state = I2C_OPER_STARTED;
+ bus->operation = I2C_WRITE_OPER;
+
+ /* get the next buffer */
+--
+2.35.1
+
--- /dev/null
+From 32a65a0a417d5b69dd35bc49ee9dad2e91ce4d3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 11:23:38 +0800
+Subject: i2c: npcm: Remove own slave addresses 2:10
+
+From: Tali Perry <tali.perry1@gmail.com>
+
+[ Upstream commit 47d506d1a28fd10a9fb1f33df5622d88fae72095 ]
+
+NPCM can support up to 10 own slave addresses. In practice, only one
+address is actually being used. In order to access addresses 2 and above,
+need to switch register banks. The switch needs spinlock.
+To avoid using spinlock for this useless feature removed support of SA >=
+2. Also fix returned slave event enum.
+
+Remove some comment since the bank selection is not required. The bank
+selection is not required since the supported slave addresses are reduced.
+
+Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
+Signed-off-by: Tali Perry <tali.perry1@gmail.com>
+Signed-off-by: Tyrone Ting <kfting@nuvoton.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-npcm7xx.c | 41 +++++++++++++-------------------
+ 1 file changed, 16 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c
+index 743ac20a405c..bc462d257baa 100644
+--- a/drivers/i2c/busses/i2c-npcm7xx.c
++++ b/drivers/i2c/busses/i2c-npcm7xx.c
+@@ -123,11 +123,11 @@ enum i2c_addr {
+ * Since the addr regs are sprinkled all over the address space,
+ * use this array to get the address or each register.
+ */
+-#define I2C_NUM_OWN_ADDR 10
++#define I2C_NUM_OWN_ADDR 2
++#define I2C_NUM_OWN_ADDR_SUPPORTED 2
++
+ static const int npcm_i2caddr[I2C_NUM_OWN_ADDR] = {
+- NPCM_I2CADDR1, NPCM_I2CADDR2, NPCM_I2CADDR3, NPCM_I2CADDR4,
+- NPCM_I2CADDR5, NPCM_I2CADDR6, NPCM_I2CADDR7, NPCM_I2CADDR8,
+- NPCM_I2CADDR9, NPCM_I2CADDR10,
++ NPCM_I2CADDR1, NPCM_I2CADDR2,
+ };
+ #endif
+
+@@ -391,14 +391,10 @@ static void npcm_i2c_disable(struct npcm_i2c *bus)
+ #if IS_ENABLED(CONFIG_I2C_SLAVE)
+ int i;
+
+- /* select bank 0 for I2C addresses */
+- npcm_i2c_select_bank(bus, I2C_BANK_0);
+-
+ /* Slave addresses removal */
+- for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR; i++)
++ for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR_SUPPORTED; i++)
+ iowrite8(0, bus->reg + npcm_i2caddr[i]);
+
+- npcm_i2c_select_bank(bus, I2C_BANK_1);
+ #endif
+ /* Disable module */
+ i2cctl2 = ioread8(bus->reg + NPCM_I2CCTL2);
+@@ -603,8 +599,7 @@ static int npcm_i2c_slave_enable(struct npcm_i2c *bus, enum i2c_addr addr_type,
+ i2cctl1 &= ~NPCM_I2CCTL1_GCMEN;
+ iowrite8(i2cctl1, bus->reg + NPCM_I2CCTL1);
+ return 0;
+- }
+- if (addr_type == I2C_ARP_ADDR) {
++ } else if (addr_type == I2C_ARP_ADDR) {
+ i2cctl3 = ioread8(bus->reg + NPCM_I2CCTL3);
+ if (enable)
+ i2cctl3 |= I2CCTL3_ARPMEN;
+@@ -613,16 +608,16 @@ static int npcm_i2c_slave_enable(struct npcm_i2c *bus, enum i2c_addr addr_type,
+ iowrite8(i2cctl3, bus->reg + NPCM_I2CCTL3);
+ return 0;
+ }
++ if (addr_type > I2C_SLAVE_ADDR2 && addr_type <= I2C_SLAVE_ADDR10)
++ dev_err(bus->dev, "try to enable more than 2 SA not supported\n");
++
+ if (addr_type >= I2C_ARP_ADDR)
+ return -EFAULT;
+- /* select bank 0 for address 3 to 10 */
+- if (addr_type > I2C_SLAVE_ADDR2)
+- npcm_i2c_select_bank(bus, I2C_BANK_0);
++
+ /* Set and enable the address */
+ iowrite8(sa_reg, bus->reg + npcm_i2caddr[addr_type]);
+ npcm_i2c_slave_int_enable(bus, enable);
+- if (addr_type > I2C_SLAVE_ADDR2)
+- npcm_i2c_select_bank(bus, I2C_BANK_1);
++
+ return 0;
+ }
+ #endif
+@@ -843,15 +838,11 @@ static u8 npcm_i2c_get_slave_addr(struct npcm_i2c *bus, enum i2c_addr addr_type)
+ {
+ u8 slave_add;
+
+- /* select bank 0 for address 3 to 10 */
+- if (addr_type > I2C_SLAVE_ADDR2)
+- npcm_i2c_select_bank(bus, I2C_BANK_0);
++ if (addr_type > I2C_SLAVE_ADDR2 && addr_type <= I2C_SLAVE_ADDR10)
++ dev_err(bus->dev, "get slave: try to use more than 2 SA not supported\n");
+
+ slave_add = ioread8(bus->reg + npcm_i2caddr[(int)addr_type]);
+
+- if (addr_type > I2C_SLAVE_ADDR2)
+- npcm_i2c_select_bank(bus, I2C_BANK_1);
+-
+ return slave_add;
+ }
+
+@@ -861,12 +852,12 @@ static int npcm_i2c_remove_slave_addr(struct npcm_i2c *bus, u8 slave_add)
+
+ /* Set the enable bit */
+ slave_add |= 0x80;
+- npcm_i2c_select_bank(bus, I2C_BANK_0);
+- for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR; i++) {
++
++ for (i = I2C_SLAVE_ADDR1; i < I2C_NUM_OWN_ADDR_SUPPORTED; i++) {
+ if (ioread8(bus->reg + npcm_i2caddr[i]) == slave_add)
+ iowrite8(0, bus->reg + npcm_i2caddr[i]);
+ }
+- npcm_i2c_select_bank(bus, I2C_BANK_1);
++
+ return 0;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From a91b37ccace5b305dc9b0a23654038f9577e543b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Jul 2022 20:50:25 -0700
+Subject: i2c: qcom-geni: Use the correct return value
+
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+
+[ Upstream commit b3f0ceb7c2037c6e3affd7d9c84ac5f97af7a5b5 ]
+
+The introduction of GPI support moved things around and instead of
+returning the result from geni_i2c_xfer() the number of messages in the
+request was returned, ignoring the actual result. Fix this.
+
+Fixes: d8703554f4de ("i2c: qcom-geni: Add support for GPI DMA")
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
+Reviewed-by: Vinod Koul <vkoul@kernel.org>
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-qcom-geni.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
+index 5b920f0fc7dd..a4eef8de054c 100644
+--- a/drivers/i2c/busses/i2c-qcom-geni.c
++++ b/drivers/i2c/busses/i2c-qcom-geni.c
+@@ -688,7 +688,7 @@ static int geni_i2c_xfer(struct i2c_adapter *adap,
+ pm_runtime_put_autosuspend(gi2c->se.dev);
+ gi2c->cur = NULL;
+ gi2c->err = 0;
+- return num;
++ return ret;
+ }
+
+ static u32 geni_i2c_func(struct i2c_adapter *adap)
+--
+2.35.1
+
--- /dev/null
+From 9fa8ff3703f495e9b644a7d335e5f13aa5d97a21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Apr 2022 23:17:25 -0700
+Subject: ia64: fix typos in comments
+
+From: Julia Lawall <Julia.Lawall@inria.fr>
+
+[ Upstream commit 0af96a024f524a5318485cbada73ab7d874895d4 ]
+
+Various spelling mistakes in comments.
+Detected with the help of Coccinelle.
+
+Link: https://lkml.kernel.org/r/20220318103729.157574-1-Julia.Lawall@inria.fr
+Signed-off-by: Julia Lawall <Julia.Lawall@inria.fr>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/ia64/kernel/palinfo.c | 2 +-
+ arch/ia64/kernel/traps.c | 2 +-
+ arch/ia64/mm/init.c | 2 +-
+ arch/ia64/mm/tlb.c | 4 ++--
+ 4 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c
+index 64189f04c1a4..b9ae093bfe37 100644
+--- a/arch/ia64/kernel/palinfo.c
++++ b/arch/ia64/kernel/palinfo.c
+@@ -120,7 +120,7 @@ static const char *mem_attrib[]={
+ * Input:
+ * - a pointer to a buffer to hold the string
+ * - a 64-bit vector
+- * Ouput:
++ * Output:
+ * - a pointer to the end of the buffer
+ *
+ */
+diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
+index 753642366e12..53735b1d1be3 100644
+--- a/arch/ia64/kernel/traps.c
++++ b/arch/ia64/kernel/traps.c
+@@ -309,7 +309,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
+ /*
+ * Lower 4 bits are used as a count. Upper bits are a sequence
+ * number that is updated when count is reset. The cmpxchg will
+- * fail is seqno has changed. This minimizes mutiple cpus
++ * fail is seqno has changed. This minimizes multiple cpus
+ * resetting the count.
+ */
+ if (current_jiffies > last.time)
+diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
+index 5d165607bf35..7ae1244ed8ec 100644
+--- a/arch/ia64/mm/init.c
++++ b/arch/ia64/mm/init.c
+@@ -451,7 +451,7 @@ mem_init (void)
+ memblock_free_all();
+
+ /*
+- * For fsyscall entrpoints with no light-weight handler, use the ordinary
++ * For fsyscall entrypoints with no light-weight handler, use the ordinary
+ * (heavy-weight) handler, but mark it by setting bit 0, so the fsyscall entry
+ * code can tell them apart.
+ */
+diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
+index 135b5135cace..ca060e7a2a46 100644
+--- a/arch/ia64/mm/tlb.c
++++ b/arch/ia64/mm/tlb.c
+@@ -174,7 +174,7 @@ __setup("nptcg=", set_nptcg);
+ * override table (in which case we should ignore the value from
+ * PAL_VM_SUMMARY).
+ *
+- * Kernel parameter "nptcg=" overrides maximum number of simultanesous ptc.g
++ * Kernel parameter "nptcg=" overrides maximum number of simultaneous ptc.g
+ * purges defined in either PAL_VM_SUMMARY or PAL override table. In this case,
+ * we should ignore the value from either PAL_VM_SUMMARY or PAL override table.
+ *
+@@ -516,7 +516,7 @@ int ia64_itr_entry(u64 target_mask, u64 va, u64 pte, u64 log_size)
+ if (i >= per_cpu(ia64_tr_num, cpu))
+ return -EBUSY;
+
+- /*Record tr info for mca hander use!*/
++ /*Record tr info for mca handler use!*/
+ if (i > per_cpu(ia64_tr_used, cpu))
+ per_cpu(ia64_tr_used, cpu) = i;
+
+--
+2.35.1
+
--- /dev/null
+From cd562444c99551ef4015f6512e0fbb6b3128f480 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 18:41:23 -0400
+Subject: iavf: Fix max_rate limiting
+
+From: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+
+[ Upstream commit ec60d54cb9a3d43a02c5612a03093c18233e6601 ]
+
+Fix max_rate option in TC, check for proper quanta boundaries.
+Check for minimum value provided and if it fits expected 50Mbps
+quanta.
+
+Without this patch, iavf could send settings for max_rate limiting
+that would be accepted from by PF even the max_rate option is less
+than expected 50Mbps quanta. It results in no rate limiting
+on traffic as rate limiting will be floored to 0.
+
+Example:
+tc qdisc add dev $vf root mqprio num_tc 3 map 0 2 1 queues \
+2@0 2@2 2@4 hw 1 mode channel shaper bw_rlimit \
+max_rate 50Mbps 500Mbps 500Mbps
+
+Should limit TC0 to circa 50 Mbps
+
+tc qdisc add dev $vf root mqprio num_tc 3 map 0 2 1 queues \
+2@0 2@2 2@4 hw 1 mode channel shaper bw_rlimit \
+max_rate 0Mbps 100Kbit 500Mbps
+
+Should return error
+
+Fixes: d5b33d024496 ("i40evf: add ndo_setup_tc callback to i40evf")
+Signed-off-by: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+Signed-off-by: Jun Zhang <xuejun.zhang@intel.com>
+Tested-by: Bharathi Sreenivas <bharathi.sreenivas@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf.h | 1 +
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 25 +++++++++++++++++++--
+ 2 files changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index 0ea0361cd86b..c241fbc30f93 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -92,6 +92,7 @@ struct iavf_vsi {
+ #define IAVF_HKEY_ARRAY_SIZE ((IAVF_VFQF_HKEY_MAX_INDEX + 1) * 4)
+ #define IAVF_HLUT_ARRAY_SIZE ((IAVF_VFQF_HLUT_MAX_INDEX + 1) * 4)
+ #define IAVF_MBPS_DIVISOR 125000 /* divisor to convert to Mbps */
++#define IAVF_MBPS_QUANTA 50
+
+ #define IAVF_VIRTCHNL_VF_RESOURCE_SIZE (sizeof(struct virtchnl_vf_resource) + \
+ (IAVF_MAX_VF_VSI * \
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 2e2c153ce46a..51ae10eb348c 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -3322,6 +3322,7 @@ static int iavf_validate_ch_config(struct iavf_adapter *adapter,
+ struct tc_mqprio_qopt_offload *mqprio_qopt)
+ {
+ u64 total_max_rate = 0;
++ u32 tx_rate_rem = 0;
+ int i, num_qps = 0;
+ u64 tx_rate = 0;
+ int ret = 0;
+@@ -3336,12 +3337,32 @@ static int iavf_validate_ch_config(struct iavf_adapter *adapter,
+ return -EINVAL;
+ if (mqprio_qopt->min_rate[i]) {
+ dev_err(&adapter->pdev->dev,
+- "Invalid min tx rate (greater than 0) specified\n");
++ "Invalid min tx rate (greater than 0) specified for TC%d\n",
++ i);
+ return -EINVAL;
+ }
+- /*convert to Mbps */
++
++ /* convert to Mbps */
+ tx_rate = div_u64(mqprio_qopt->max_rate[i],
+ IAVF_MBPS_DIVISOR);
++
++ if (mqprio_qopt->max_rate[i] &&
++ tx_rate < IAVF_MBPS_QUANTA) {
++ dev_err(&adapter->pdev->dev,
++ "Invalid max tx rate for TC%d, minimum %dMbps\n",
++ i, IAVF_MBPS_QUANTA);
++ return -EINVAL;
++ }
++
++ (void)div_u64_rem(tx_rate, IAVF_MBPS_QUANTA, &tx_rate_rem);
++
++ if (tx_rate_rem != 0) {
++ dev_err(&adapter->pdev->dev,
++ "Invalid max tx rate for TC%d, not divisible by %d\n",
++ i, IAVF_MBPS_QUANTA);
++ return -EINVAL;
++ }
++
+ total_max_rate += tx_rate;
+ num_qps += mqprio_qopt->qopt.count[i];
+ }
+--
+2.35.1
+
--- /dev/null
+From f772700674c59dc26e3be01708494ffa55174402 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 15:36:29 +0200
+Subject: iavf: Fix 'tc qdisc show' listing too many queues
+
+From: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+
+[ Upstream commit 93cb804edab1b9a5bb7bb7b6824012dbb20abf22 ]
+
+Fix tc qdisc show dev <ethX> root displaying too many fq_codel qdiscs.
+tc_modify_qdisc, which is caller of ndo_setup_tc, expects driver to call
+netif_set_real_num_tx_queues, which prepares qdiscs.
+Without this patch, fq_codel qdiscs would not be adjusted to number of
+queues on VF.
+e.g.:
+tc qdisc show dev <ethX>
+qdisc mq 0: root
+qdisc fq_codel 0: parent :4 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+qdisc fq_codel 0: parent :3 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+qdisc fq_codel 0: parent :2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+qdisc fq_codel 0: parent :1 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+tc qdisc add dev <ethX> root mqprio num_tc 2 map 1 0 0 0 0 0 0 0 queues 1@0 1@1 hw 1 mode channel shaper bw_rlimit max_rate 5000Mbit 150Mbit
+tc qdisc show dev <ethX>
+qdisc mqprio 8003: root tc 2 map 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ queues:(0:0) (1:1)
+ mode:channel
+ shaper:bw_rlimit max_rate:5Gbit 150Mbit
+qdisc fq_codel 0: parent 8003:4 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+qdisc fq_codel 0: parent 8003:3 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+qdisc fq_codel 0: parent 8003:2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+qdisc fq_codel 0: parent 8003:1 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+
+While after fix:
+tc qdisc add dev <ethX> root mqprio num_tc 2 map 1 0 0 0 0 0 0 0 queues 1@0 1@1 hw 1 mode channel shaper bw_rlimit max_rate 5000Mbit 150Mbit
+tc qdisc show dev <ethX> #should show 2, shows 4
+qdisc mqprio 8004: root tc 2 map 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ queues:(0:0) (1:1)
+ mode:channel
+ shaper:bw_rlimit max_rate:5Gbit 150Mbit
+qdisc fq_codel 0: parent 8004:2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+qdisc fq_codel 0: parent 8004:1 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
+
+Fixes: d5b33d024496 ("i40evf: add ndo_setup_tc callback to i40evf")
+Signed-off-by: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
+Co-developed-by: Grzegorz Szczurek <grzegorzx.szczurek@intel.com>
+Signed-off-by: Grzegorz Szczurek <grzegorzx.szczurek@intel.com>
+Co-developed-by: Kiran Patil <kiran.patil@intel.com>
+Signed-off-by: Kiran Patil <kiran.patil@intel.com>
+Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+Tested-by: Bharathi Sreenivas <bharathi.sreenivas@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf.h | 5 +++++
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 21 +++++++++++++++++++++
+ 2 files changed, 26 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index c241fbc30f93..a988c08e906f 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -431,6 +431,11 @@ struct iavf_adapter {
+ /* lock to protect access to the cloud filter list */
+ spinlock_t cloud_filter_list_lock;
+ u16 num_cloud_filters;
++ /* snapshot of "num_active_queues" before setup_tc for qdisc add
++ * is invoked. This information is useful during qdisc del flow,
++ * to restore correct number of queues
++ */
++ int orig_num_active_queues;
+
+ #define IAVF_MAX_FDIR_FILTERS 128 /* max allowed Flow Director filters */
+ u16 fdir_active_fltr;
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 51ae10eb348c..3dbfaead2ac7 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -3429,6 +3429,7 @@ static int __iavf_setup_tc(struct net_device *netdev, void *type_data)
+ netif_tx_disable(netdev);
+ iavf_del_all_cloud_filters(adapter);
+ adapter->aq_required = IAVF_FLAG_AQ_DISABLE_CHANNELS;
++ total_qps = adapter->orig_num_active_queues;
+ goto exit;
+ } else {
+ return -EINVAL;
+@@ -3472,7 +3473,21 @@ static int __iavf_setup_tc(struct net_device *netdev, void *type_data)
+ adapter->ch_config.ch_info[i].offset = 0;
+ }
+ }
++
++ /* Take snapshot of original config such as "num_active_queues"
++ * It is used later when delete ADQ flow is exercised, so that
++ * once delete ADQ flow completes, VF shall go back to its
++ * original queue configuration
++ */
++
++ adapter->orig_num_active_queues = adapter->num_active_queues;
++
++ /* Store queue info based on TC so that VF gets configured
++ * with correct number of queues when VF completes ADQ config
++ * flow
++ */
+ adapter->ch_config.total_qps = total_qps;
++
+ netif_tx_stop_all_queues(netdev);
+ netif_tx_disable(netdev);
+ adapter->aq_required |= IAVF_FLAG_AQ_ENABLE_CHANNELS;
+@@ -3489,6 +3504,12 @@ static int __iavf_setup_tc(struct net_device *netdev, void *type_data)
+ }
+ }
+ exit:
++ if (test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))
++ return 0;
++
++ netif_set_real_num_rx_queues(netdev, total_qps);
++ netif_set_real_num_tx_queues(netdev, total_qps);
++
+ return ret;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 235d4da7b5f924ccf2d659155f806487558992aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:42 +0100
+Subject: iio: accel: adxl313: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit f68a0445ee86e48dafbfdea50163ad6fc6dba268 ]
+
+____cacheline_aligned is insufficient guarantee for non-coherent DMA.
+Switch to the updated IIO_DMA_MINALIGN definition.
+
+Fixes: 636d44633039 ("iio: accel: Add driver support for ADXL313")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-3-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/adxl313_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_core.c
+index 9e4193e64765..afeef779e1d0 100644
+--- a/drivers/iio/accel/adxl313_core.c
++++ b/drivers/iio/accel/adxl313_core.c
+@@ -46,7 +46,7 @@ EXPORT_SYMBOL_NS_GPL(adxl313_writable_regs_table, IIO_ADXL313);
+ struct adxl313_data {
+ struct regmap *regmap;
+ struct mutex lock; /* lock to protect transf_buf */
+- __le16 transf_buf ____cacheline_aligned;
++ __le16 transf_buf __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static const int adxl313_odr_freqs[][2] = {
+--
+2.35.1
+
--- /dev/null
+From b2f87bd9a949a8a81c49a0f0e8278de90107a502 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:43 +0100
+Subject: iio: accel: adxl355: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 46403dcf3a7cbd24b86f809fd79962f4d6b137c5 ]
+
+ ____cacheline_aligned is insufficient guarantee for non-coherent DMA.
+Switch to the updated IIO_DMA_MINALIGN definition.
+
+Fixes: 327a0eaf19d53 ("iio: accel: adxl355: Add triggered buffer support")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Puranjay Mohan <puranjay12@gmail.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-4-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/adxl355_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/accel/adxl355_core.c b/drivers/iio/accel/adxl355_core.c
+index e9c10c8c32f0..2dfe780d6144 100644
+--- a/drivers/iio/accel/adxl355_core.c
++++ b/drivers/iio/accel/adxl355_core.c
+@@ -177,7 +177,7 @@ struct adxl355_data {
+ u8 buf[14];
+ s64 ts;
+ } buffer;
+- } ____cacheline_aligned;
++ } __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int adxl355_set_op_mode(struct adxl355_data *data,
+--
+2.35.1
+
--- /dev/null
+From f645cd22ffa680599f6e30163bad4a6291680794 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:44 +0100
+Subject: iio: accel: adxl367: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit e1f956a804df9074fb5de557563d153ae25252e7 ]
+
+____cacheline_aligned is insufficient guarantee for non-coherent DMA.
+Switch to the updated IIO_DMA_MINALIGN definition.
+
+Update comment to reflect that DMA safety may require separate
+cachelines.
+
+Fixes: cbab791c5e2a5 ("iio: accel: add ADXL367 driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Cosmin Tanislav <demonsingur@gmail.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-5-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/adxl367.c | 2 +-
+ drivers/iio/accel/adxl367_spi.c | 8 +++++---
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c
+index 62960134ea19..d680bec05efc 100644
+--- a/drivers/iio/accel/adxl367.c
++++ b/drivers/iio/accel/adxl367.c
+@@ -179,7 +179,7 @@ struct adxl367_state {
+ unsigned int fifo_set_size;
+ unsigned int fifo_watermark;
+
+- __be16 fifo_buf[ADXL367_FIFO_SIZE] ____cacheline_aligned;
++ __be16 fifo_buf[ADXL367_FIFO_SIZE] __aligned(IIO_DMA_MINALIGN);
+ __be16 sample_buf;
+ u8 act_threshold_buf[2];
+ u8 inact_time_buf[2];
+diff --git a/drivers/iio/accel/adxl367_spi.c b/drivers/iio/accel/adxl367_spi.c
+index 26dfc821ebbe..118c894015a5 100644
+--- a/drivers/iio/accel/adxl367_spi.c
++++ b/drivers/iio/accel/adxl367_spi.c
+@@ -9,6 +9,8 @@
+ #include <linux/regmap.h>
+ #include <linux/spi/spi.h>
+
++#include <linux/iio/iio.h>
++
+ #include "adxl367.h"
+
+ #define ADXL367_SPI_WRITE_COMMAND 0x0A
+@@ -28,10 +30,10 @@ struct adxl367_spi_state {
+ struct spi_transfer fifo_xfer[2];
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
+- * transfer buffers to live in their own cache lines.
++ * DMA (thus cache coherency maintenance) may require the
++ * transfer buffers live in their own cache lines.
+ */
+- u8 reg_write_tx_buf[1] ____cacheline_aligned;
++ u8 reg_write_tx_buf[1] __aligned(IIO_DMA_MINALIGN);
+ u8 reg_read_tx_buf[2];
+ u8 fifo_tx_buf[1];
+ };
+--
+2.35.1
+
--- /dev/null
+From 0db76dbede9f93fc82f61b9185b957dd7ebcd21f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:45 +0100
+Subject: iio: accel: bma220: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 38e71240e2ff97184cdcdaf877cf62d3f16678e2 ]
+
+____cacheline_aligned is insufficient guarantee for non-coherent DMA.
+Switch to the updated IIO_DMA_MINALIGN definition.
+
+Fixes: bf2a5600a3ebc ("iio: accel: Add support for Bosch BMA220")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-6-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/bma220_spi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/accel/bma220_spi.c b/drivers/iio/accel/bma220_spi.c
+index 74024d7ce5ac..b6d9ab8e2054 100644
+--- a/drivers/iio/accel/bma220_spi.c
++++ b/drivers/iio/accel/bma220_spi.c
+@@ -67,7 +67,7 @@ struct bma220_data {
+ /* Ensure timestamp is naturally aligned. */
+ s64 timestamp __aligned(8);
+ } scan;
+- u8 tx_buf[2] ____cacheline_aligned;
++ u8 tx_buf[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static const struct iio_chan_spec bma220_channels[] = {
+--
+2.35.1
+
--- /dev/null
+From 99b5cf97fa8261f1dfe8afd5e718e7fa9da39a4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 May 2022 19:00:14 +0530
+Subject: iio: accel: bma400: conversion to device-managed function
+
+From: Jagath Jog J <jagathjog1996@gmail.com>
+
+[ Upstream commit 12c99f859fd3da5fc8f8491826e7023001f54821 ]
+
+This is a conversion to device-managed by using devm_iio_device_register()
+inside probe function. Previously the bma400 was not put into power down
+mode in some error paths in probe where it now is, but that should cause
+no harm.
+
+The dev_set_drvdata() call, bma400_remove() function and hooks in the I2C
+and SPI driver struct is removed as devm_iio_device_register() function is
+used to automatically unregister on driver detach.
+
+Signed-off-by: Jagath Jog J <jagathjog1996@gmail.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20220505133021.22362-4-jagathjog1996@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/bma400.h | 2 -
+ drivers/iio/accel/bma400_core.c | 77 ++++++++++++++++-----------------
+ drivers/iio/accel/bma400_i2c.c | 8 ----
+ drivers/iio/accel/bma400_spi.c | 6 ---
+ 4 files changed, 38 insertions(+), 55 deletions(-)
+
+diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h
+index 80330c7ce17f..1c8c47a9a317 100644
+--- a/drivers/iio/accel/bma400.h
++++ b/drivers/iio/accel/bma400.h
+@@ -113,6 +113,4 @@ extern const struct regmap_config bma400_regmap_config;
+
+ int bma400_probe(struct device *dev, struct regmap *regmap, const char *name);
+
+-void bma400_remove(struct device *dev);
+-
+ #endif
+diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c
+index 25ad1f7339bc..07674d89d978 100644
+--- a/drivers/iio/accel/bma400_core.c
++++ b/drivers/iio/accel/bma400_core.c
+@@ -560,6 +560,26 @@ static void bma400_init_tables(void)
+ }
+ }
+
++static void bma400_regulators_disable(void *data_ptr)
++{
++ struct bma400_data *data = data_ptr;
++
++ regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators);
++}
++
++static void bma400_power_disable(void *data_ptr)
++{
++ struct bma400_data *data = data_ptr;
++ int ret;
++
++ mutex_lock(&data->mutex);
++ ret = bma400_set_power_mode(data, POWER_MODE_SLEEP);
++ mutex_unlock(&data->mutex);
++ if (ret)
++ dev_warn(data->dev, "Failed to put device into sleep mode (%pe)\n",
++ ERR_PTR(ret));
++}
++
+ static int bma400_init(struct bma400_data *data)
+ {
+ unsigned int val;
+@@ -569,13 +589,12 @@ static int bma400_init(struct bma400_data *data)
+ ret = regmap_read(data->regmap, BMA400_CHIP_ID_REG, &val);
+ if (ret) {
+ dev_err(data->dev, "Failed to read chip id register\n");
+- goto out;
++ return ret;
+ }
+
+ if (val != BMA400_ID_REG_VAL) {
+ dev_err(data->dev, "Chip ID mismatch\n");
+- ret = -ENODEV;
+- goto out;
++ return -ENODEV;
+ }
+
+ data->regulators[BMA400_VDD_REGULATOR].supply = "vdd";
+@@ -589,27 +608,31 @@ static int bma400_init(struct bma400_data *data)
+ "Failed to get regulators: %d\n",
+ ret);
+
+- goto out;
++ return ret;
+ }
+ ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators),
+ data->regulators);
+ if (ret) {
+ dev_err(data->dev, "Failed to enable regulators: %d\n",
+ ret);
+- goto out;
++ return ret;
+ }
+
++ ret = devm_add_action_or_reset(data->dev, bma400_regulators_disable, data);
++ if (ret)
++ return ret;
++
+ ret = bma400_get_power_mode(data);
+ if (ret) {
+ dev_err(data->dev, "Failed to get the initial power-mode\n");
+- goto err_reg_disable;
++ return ret;
+ }
+
+ if (data->power_mode != POWER_MODE_NORMAL) {
+ ret = bma400_set_power_mode(data, POWER_MODE_NORMAL);
+ if (ret) {
+ dev_err(data->dev, "Failed to wake up the device\n");
+- goto err_reg_disable;
++ return ret;
+ }
+ /*
+ * TODO: The datasheet waits 1500us here in the example, but
+@@ -618,19 +641,23 @@ static int bma400_init(struct bma400_data *data)
+ usleep_range(1500, 2000);
+ }
+
++ ret = devm_add_action_or_reset(data->dev, bma400_power_disable, data);
++ if (ret)
++ return ret;
++
+ bma400_init_tables();
+
+ ret = bma400_get_accel_output_data_rate(data);
+ if (ret)
+- goto err_reg_disable;
++ return ret;
+
+ ret = bma400_get_accel_oversampling_ratio(data);
+ if (ret)
+- goto err_reg_disable;
++ return ret;
+
+ ret = bma400_get_accel_scale(data);
+ if (ret)
+- goto err_reg_disable;
++ return ret;
+
+ /*
+ * Once the interrupt engine is supported we might use the
+@@ -639,12 +666,6 @@ static int bma400_init(struct bma400_data *data)
+ * channel.
+ */
+ return regmap_write(data->regmap, BMA400_ACC_CONFIG2_REG, 0x00);
+-
+-err_reg_disable:
+- regulator_bulk_disable(ARRAY_SIZE(data->regulators),
+- data->regulators);
+-out:
+- return ret;
+ }
+
+ static int bma400_read_raw(struct iio_dev *indio_dev,
+@@ -822,32 +843,10 @@ int bma400_probe(struct device *dev, struct regmap *regmap, const char *name)
+ indio_dev->num_channels = ARRAY_SIZE(bma400_channels);
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+- dev_set_drvdata(dev, indio_dev);
+-
+- return iio_device_register(indio_dev);
++ return devm_iio_device_register(dev, indio_dev);
+ }
+ EXPORT_SYMBOL_NS(bma400_probe, IIO_BMA400);
+
+-void bma400_remove(struct device *dev)
+-{
+- struct iio_dev *indio_dev = dev_get_drvdata(dev);
+- struct bma400_data *data = iio_priv(indio_dev);
+- int ret;
+-
+- mutex_lock(&data->mutex);
+- ret = bma400_set_power_mode(data, POWER_MODE_SLEEP);
+- mutex_unlock(&data->mutex);
+-
+- if (ret)
+- dev_warn(dev, "Failed to put device into sleep mode (%pe)\n", ERR_PTR(ret));
+-
+- regulator_bulk_disable(ARRAY_SIZE(data->regulators),
+- data->regulators);
+-
+- iio_device_unregister(indio_dev);
+-}
+-EXPORT_SYMBOL_NS(bma400_remove, IIO_BMA400);
+-
+ MODULE_AUTHOR("Dan Robertson <dan@dlrobertson.com>");
+ MODULE_DESCRIPTION("Bosch BMA400 triaxial acceleration sensor core");
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/iio/accel/bma400_i2c.c b/drivers/iio/accel/bma400_i2c.c
+index da104ffd3fe0..4f6e01a3b3a1 100644
+--- a/drivers/iio/accel/bma400_i2c.c
++++ b/drivers/iio/accel/bma400_i2c.c
+@@ -27,13 +27,6 @@ static int bma400_i2c_probe(struct i2c_client *client,
+ return bma400_probe(&client->dev, regmap, id->name);
+ }
+
+-static int bma400_i2c_remove(struct i2c_client *client)
+-{
+- bma400_remove(&client->dev);
+-
+- return 0;
+-}
+-
+ static const struct i2c_device_id bma400_i2c_ids[] = {
+ { "bma400", 0 },
+ { }
+@@ -52,7 +45,6 @@ static struct i2c_driver bma400_i2c_driver = {
+ .of_match_table = bma400_of_i2c_match,
+ },
+ .probe = bma400_i2c_probe,
+- .remove = bma400_i2c_remove,
+ .id_table = bma400_i2c_ids,
+ };
+
+diff --git a/drivers/iio/accel/bma400_spi.c b/drivers/iio/accel/bma400_spi.c
+index 51f23bdc0ea5..28e240400a3f 100644
+--- a/drivers/iio/accel/bma400_spi.c
++++ b/drivers/iio/accel/bma400_spi.c
+@@ -87,11 +87,6 @@ static int bma400_spi_probe(struct spi_device *spi)
+ return bma400_probe(&spi->dev, regmap, id->name);
+ }
+
+-static void bma400_spi_remove(struct spi_device *spi)
+-{
+- bma400_remove(&spi->dev);
+-}
+-
+ static const struct spi_device_id bma400_spi_ids[] = {
+ { "bma400", 0 },
+ { }
+@@ -110,7 +105,6 @@ static struct spi_driver bma400_spi_driver = {
+ .of_match_table = bma400_of_spi_match,
+ },
+ .probe = bma400_spi_probe,
+- .remove = bma400_spi_remove,
+ .id_table = bma400_spi_ids,
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 3fe775f0bf23c61e30726cb7a278878c829f6916 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 May 2022 19:00:12 +0530
+Subject: iio: accel: bma400: Fix the scale min and max macro values
+
+From: Jagath Jog J <jagathjog1996@gmail.com>
+
+[ Upstream commit 747c7cf1592e226d40543231b26502b332d0ea2f ]
+
+Changing the scale macro values to match the bma400 sensitivity
+for 1 LSB of all the available ranges.
+
+Fixes: 465c811f1f20 ("iio: accel: Add driver for the BMA400")
+Signed-off-by: Jagath Jog J <jagathjog1996@gmail.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20220505133021.22362-2-jagathjog1996@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/bma400.h | 23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h
+index c4c8d74155c2..80330c7ce17f 100644
+--- a/drivers/iio/accel/bma400.h
++++ b/drivers/iio/accel/bma400.h
+@@ -83,8 +83,27 @@
+ #define BMA400_ACC_ODR_MIN_WHOLE_HZ 25
+ #define BMA400_ACC_ODR_MIN_HZ 12
+
+-#define BMA400_SCALE_MIN 38357
+-#define BMA400_SCALE_MAX 306864
++/*
++ * BMA400_SCALE_MIN macro value represents m/s^2 for 1 LSB before
++ * converting to micro values for +-2g range.
++ *
++ * For +-2g - 1 LSB = 0.976562 milli g = 0.009576 m/s^2
++ * For +-4g - 1 LSB = 1.953125 milli g = 0.019153 m/s^2
++ * For +-16g - 1 LSB = 7.8125 milli g = 0.076614 m/s^2
++ *
++ * The raw value which is used to select the different ranges is determined
++ * by the first bit set position from the scale value, so BMA400_SCALE_MIN
++ * should be odd.
++ *
++ * Scale values for +-2g, +-4g, +-8g and +-16g are populated into bma400_scales
++ * array by left shifting BMA400_SCALE_MIN.
++ * e.g.:
++ * To select +-2g = 9577 << 0 = raw value to write is 0.
++ * To select +-8g = 9577 << 2 = raw value to write is 2.
++ * To select +-16g = 9577 << 3 = raw value to write is 3.
++ */
++#define BMA400_SCALE_MIN 9577
++#define BMA400_SCALE_MAX 76617
+
+ #define BMA400_NUM_REGULATORS 2
+ #define BMA400_VDD_REGULATOR 0
+--
+2.35.1
+
--- /dev/null
+From f6b831f90c375318c4594cafd9c098bfda536e20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 May 2022 19:00:13 +0530
+Subject: iio: accel: bma400: Reordering of header files
+
+From: Jagath Jog J <jagathjog1996@gmail.com>
+
+[ Upstream commit 1bd2dc6ea863690aee5c45ebf09c9194c7a42c0d ]
+
+Reordering of header files and removing the iio/sysfs.h since
+custom attributes are not being used in the driver.
+
+Signed-off-by: Jagath Jog J <jagathjog1996@gmail.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20220505133021.22362-3-jagathjog1996@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/bma400_core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c
+index 043002fe6f63..25ad1f7339bc 100644
+--- a/drivers/iio/accel/bma400_core.c
++++ b/drivers/iio/accel/bma400_core.c
+@@ -13,14 +13,14 @@
+
+ #include <linux/bitops.h>
+ #include <linux/device.h>
+-#include <linux/iio/iio.h>
+-#include <linux/iio/sysfs.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/mutex.h>
+ #include <linux/regmap.h>
+ #include <linux/regulator/consumer.h>
+
++#include <linux/iio/iio.h>
++
+ #include "bma400.h"
+
+ /*
+--
+2.35.1
+
--- /dev/null
+From 1c4fde93388f65f6155a77a19a58055eb7941967 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:47 +0100
+Subject: iio: accel: sca3000: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit a263456f0e27ec2f00d25119757f4d4bd656b2e9 ]
+
+____cacheline_aligned is insufficient guarantee for non-coherent DMA.
+Switch to the updated IIO_DMA_MINALIGN definition.
+
+The second alignment marking is left in place to avoid doing more than
+the simple fix in this patch.
+
+Fixes: ced5c03d360ae ("staging:iio:accel:sca3000 merge files into one.")
+Fixes: 152a6a884ae13 ("staging:iio:accel:sca3000 move to hybrid hard / soft buffer design.")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-8-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/sca3000.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/accel/sca3000.c b/drivers/iio/accel/sca3000.c
+index 83c81072511e..2eecd2ab72dd 100644
+--- a/drivers/iio/accel/sca3000.c
++++ b/drivers/iio/accel/sca3000.c
+@@ -167,8 +167,8 @@ struct sca3000_state {
+ int mo_det_use_count;
+ struct mutex lock;
+ /* Can these share a cacheline ? */
+- u8 rx[384] ____cacheline_aligned;
+- u8 tx[6] ____cacheline_aligned;
++ u8 rx[384] __aligned(IIO_DMA_MINALIGN);
++ u8 tx[6] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ /**
+--
+2.35.1
+
--- /dev/null
+From 5d9960b86d198c76cc8ebbb00c64af706cee5482 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:48 +0100
+Subject: iio: accel: sca3300: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit b1d3a806630dbbf3b4d75a2e850adccf4f4439e7 ]
+
+____cacheline_aligned is insufficient guarantee for non-coherent DMA.
+Switch to the updated IIO_DMA_MINALIGN definition.
+
+Fixes: 9cc9806e22178 ("iio: accel: Add driver for Murata SCA3300 accelerometer")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Tomas Melin <tomas.melin@vaisala.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-9-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/sca3300.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/accel/sca3300.c b/drivers/iio/accel/sca3300.c
+index f7ef8ecfd34a..39e0c24364ae 100644
+--- a/drivers/iio/accel/sca3300.c
++++ b/drivers/iio/accel/sca3300.c
+@@ -115,7 +115,7 @@ struct sca3300_data {
+ s16 channels[4];
+ s64 ts __aligned(sizeof(s64));
+ } scan;
+- u8 txbuf[4] ____cacheline_aligned;
++ u8 txbuf[4] __aligned(IIO_DMA_MINALIGN);
+ u8 rxbuf[4];
+ };
+
+--
+2.35.1
+
--- /dev/null
+From f5e4a9493aadb36dcb798bbb6f6ca226f0e581f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:49 +0100
+Subject: iio: adc: ad7266: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit b990cdfe7536a8da7e134d516350402981300016 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to reflect that DMA safety 'may' require separate
+cachelines.
+
+Fixes: 54e018da3141 ("iio:ad7266: Mark transfer buffer as __be16")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-10-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7266.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c
+index c17d9b5fbaf6..53c83e04dde5 100644
+--- a/drivers/iio/adc/ad7266.c
++++ b/drivers/iio/adc/ad7266.c
+@@ -37,7 +37,7 @@ struct ad7266_state {
+ struct gpio_desc *gpios[3];
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ * The buffer needs to be large enough to hold two samples (4 bytes) and
+ * the naturally aligned timestamp (8 bytes).
+@@ -45,7 +45,7 @@ struct ad7266_state {
+ struct {
+ __be16 sample[2];
+ s64 timestamp;
+- } data ____cacheline_aligned;
++ } data __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int ad7266_wakeup(struct ad7266_state *st)
+--
+2.35.1
+
--- /dev/null
+From 6bdfde2f3174d5143fa2dd0501efbc17ea3ff326 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:50 +0100
+Subject: iio: adc: ad7280a: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 4e2008429588b857bbc13d048b67b931a8d84816 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 003f1d48de52 ("staging:iio:adc:ad7280a: Split buff[2] into tx and rx parts")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-11-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7280a.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ad7280a.c b/drivers/iio/adc/ad7280a.c
+index ec9acbf12b9a..047a9d0dbcf7 100644
+--- a/drivers/iio/adc/ad7280a.c
++++ b/drivers/iio/adc/ad7280a.c
+@@ -183,7 +183,7 @@ struct ad7280_state {
+ unsigned char cb_mask[AD7280A_MAX_CHAIN];
+ struct mutex lock; /* protect sensor state */
+
+- __be32 tx ____cacheline_aligned;
++ __be32 tx __aligned(IIO_DMA_MINALIGN);
+ __be32 rx;
+ };
+
+--
+2.35.1
+
--- /dev/null
+From e6f83c3715c1daf7d0ffa2bcbb9bc237f74bd9a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:51 +0100
+Subject: iio: adc: ad7292: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 98295a206d04633bae31f279de11ff7d04724bce ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 506d2e317a0a ("iio: adc: Add driver support for AD7292")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Marcelo Schmitt <marcelo.schmitt1@gmail.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-12-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7292.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ad7292.c b/drivers/iio/adc/ad7292.c
+index 3271a31afde1..92c68d467c50 100644
+--- a/drivers/iio/adc/ad7292.c
++++ b/drivers/iio/adc/ad7292.c
+@@ -80,7 +80,7 @@ struct ad7292_state {
+ struct regulator *reg;
+ unsigned short vref_mv;
+
+- __be16 d16 ____cacheline_aligned;
++ __be16 d16 __aligned(IIO_DMA_MINALIGN);
+ u8 d8[2];
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 871a60a35620392ba394adedf06940fee4b9ada6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:52 +0100
+Subject: iio: adc: ad7298: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 585c9772f883da3ac425e2e8277b2aaceb201f38 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: be7fd3b86ad2 ("iio:adc:ad7298 make the tx and rx buffers __be16")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-13-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7298.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c
+index 3f4e73f7d35a..c0430f71f592 100644
+--- a/drivers/iio/adc/ad7298.c
++++ b/drivers/iio/adc/ad7298.c
+@@ -49,7 +49,7 @@ struct ad7298_state {
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache lines.
+ */
+- __be16 rx_buf[12] ____cacheline_aligned;
++ __be16 rx_buf[12] __aligned(IIO_DMA_MINALIGN);
+ __be16 tx_buf[2];
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 7802a48d9c24c940a7c1135eee697d6d4abb739e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:53 +0100
+Subject: iio: adc: ad7476: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 58b74555afc8affe4ae4f57d396349158433fc80 ]
+
+ ____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to reflect that DMA safety 'may' require separate
+cachelines.
+
+Fixes tag is unlikely to be the actual introdution of the problem but is
+far enough back to cover any likely backporting.
+
+Fixes: 7a28fe3c93d6 ("staging:iio:ad7476: Squash driver into a single file.")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-14-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7476.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c
+index a1e8b32671cf..94776f696290 100644
+--- a/drivers/iio/adc/ad7476.c
++++ b/drivers/iio/adc/ad7476.c
+@@ -44,13 +44,12 @@ struct ad7476_state {
+ struct spi_transfer xfer;
+ struct spi_message msg;
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ * Make the buffer large enough for one 16 bit sample and one 64 bit
+ * aligned 64 bit timestamp.
+ */
+- unsigned char data[ALIGN(2, sizeof(s64)) + sizeof(s64)]
+- ____cacheline_aligned;
++ unsigned char data[ALIGN(2, sizeof(s64)) + sizeof(s64)] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ enum ad7476_supported_device_ids {
+--
+2.35.1
+
--- /dev/null
+From a62d1156743230595b873265f4791e7ebacce290 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:54 +0100
+Subject: iio: adc: ad7606: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 6268c6eebb13f228d418f9adaca848b3ed5b3cf9 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_ALIGN definition.
+
+Update the comment to reflect the fact DMA safety 'may' require
+separate cachelines.
+
+Fixes: 7989b4bb23fe ("iio: adc: ad7616: Add support for AD7616 ADC")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-15-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7606.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h
+index 4f82d7c9acfd..2dc4f599f9df 100644
+--- a/drivers/iio/adc/ad7606.h
++++ b/drivers/iio/adc/ad7606.h
+@@ -116,11 +116,11 @@ struct ad7606_state {
+ struct completion completion;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ * 16 * 16-bit samples + 64-bit timestamp
+ */
+- unsigned short data[20] ____cacheline_aligned;
++ unsigned short data[20] __aligned(IIO_DMA_MINALIGN);
+ __be16 d16[2];
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 15508b6a499da0986ae3aa6981fc2bb8fbd6782c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:55 +0100
+Subject: iio: adc: ad7766: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 009ae227a1dace2d4d27c804e5bd65907e1d0557 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to reflect the fact DMA safety 'may' require
+separate cachelines.
+
+Fixes: aa16c6bd0e09 ("iio:adc: Add support for AD7766/AD7767")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Lars-Peter Clausen <lars@metafoo.de>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-16-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7766.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7766.c b/drivers/iio/adc/ad7766.c
+index 51ee9482e0df..3079a0872947 100644
+--- a/drivers/iio/adc/ad7766.c
++++ b/drivers/iio/adc/ad7766.c
+@@ -45,13 +45,12 @@ struct ad7766 {
+ struct spi_message msg;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ * Make the buffer large enough for one 24 bit sample and one 64 bit
+ * aligned 64 bit timestamp.
+ */
+- unsigned char data[ALIGN(3, sizeof(s64)) + sizeof(s64)]
+- ____cacheline_aligned;
++ unsigned char data[ALIGN(3, sizeof(s64)) + sizeof(s64)] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ /*
+--
+2.35.1
+
--- /dev/null
+From a2cd3ba767729fbb767f879fad4999799a20aeb4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:56 +0100
+Subject: iio: adc: ad7768-1: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 211f810f8fae05c1f78e531b2b113ea1ab3d1ce7 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to reflect that separate cachelines 'may' be
+required.
+
+Fixes: a5f8c7da3dbe ("iio: adc: Add AD7768-1 ADC basic support")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-17-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7768-1.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
+index aa42ba759fa1..60f394da4640 100644
+--- a/drivers/iio/adc/ad7768-1.c
++++ b/drivers/iio/adc/ad7768-1.c
+@@ -163,7 +163,7 @@ struct ad7768_state {
+ struct gpio_desc *gpio_sync_in;
+ const char *labels[ARRAY_SIZE(ad7768_channels)];
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+ union {
+@@ -173,7 +173,7 @@ struct ad7768_state {
+ } scan;
+ __be32 d32;
+ u8 d8[2];
+- } data ____cacheline_aligned;
++ } data __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int ad7768_spi_reg_read(struct ad7768_state *st, unsigned int addr,
+--
+2.35.1
+
--- /dev/null
+From 86da99d7d2c796864db0505ef8afa01182ffdc07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:57 +0100
+Subject: iio: adc: ad7887: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit b330ea6bc52468e183ced79189ff064f36c64aa7 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes tag is clearly not where this was introduced but it is very unlikely
+anyone will back port it past that point.
+
+Fixes: 65dd3d3d7a9b ("staging:iio:ad7887: Squash everything into one file")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Lars-Peter Clausen <lars@metafoo.de>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-18-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7887.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c
+index f64999714a4d..965bdc8aa696 100644
+--- a/drivers/iio/adc/ad7887.c
++++ b/drivers/iio/adc/ad7887.c
+@@ -66,13 +66,12 @@ struct ad7887_state {
+ unsigned char tx_cmd_buf[4];
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ * Buffer needs to be large enough to hold two 16 bit samples and a
+ * 64 bit aligned 64 bit timestamp.
+ */
+- unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)]
+- ____cacheline_aligned;
++ unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ enum ad7887_supported_device_ids {
+--
+2.35.1
+
--- /dev/null
+From 198d85b3fe06b9267e6287c5f5d31435ba176303 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:58 +0100
+Subject: iio: adc: ad7923: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 908af45d7057345bc910940a9340f7a1d8935875 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Note that some other fixes have applied to this line of code
+that may complicate automated backporting.
+
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Fixes: 0eac259db28f ("IIO ADC support for AD7923")
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-19-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7923.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c
+index 069b561ee768..edad1f30121d 100644
+--- a/drivers/iio/adc/ad7923.c
++++ b/drivers/iio/adc/ad7923.c
+@@ -57,12 +57,12 @@ struct ad7923_state {
+ unsigned int settings;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ * Ensure rx_buf can be directly used in iio_push_to_buffers_with_timetamp
+ * Length = 8 channels + 4 extra for 8 byte timestamp
+ */
+- __be16 rx_buf[12] ____cacheline_aligned;
++ __be16 rx_buf[12] __aligned(IIO_DMA_MINALIGN);
+ __be16 tx_buf[4];
+ };
+
+--
+2.35.1
+
--- /dev/null
+From afe579b0def3600f5a2f640fee9e6515bfb76e4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:59 +0100
+Subject: iio: adc: ad7949: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 9c6c7eff7d4a53efd4d0818f8664259a1862665a ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Note the fixes tag predates some changes to this line of code so
+automated application of this fix may fail.
+
+Fixes: 7f40e0614317 ("iio:adc:ad7949: Add AD7949 ADC driver family")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Charles-Antoine Couret <charles-antoine.couret@essensium.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-20-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7949.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ad7949.c b/drivers/iio/adc/ad7949.c
+index 44bb5fde83de..ed4c1656ca75 100644
+--- a/drivers/iio/adc/ad7949.c
++++ b/drivers/iio/adc/ad7949.c
+@@ -86,7 +86,7 @@ struct ad7949_adc_chip {
+ u8 resolution;
+ u16 cfg;
+ unsigned int current_channel;
+- u16 buffer ____cacheline_aligned;
++ u16 buffer __aligned(IIO_DMA_MINALIGN);
+ __be16 buf8b;
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 83c38b9ede88ea083ea487a2fbfab3527cba2991 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:00 +0100
+Subject: iio: adc: hi8435: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 48e4ae96b0b10f93de23b86fd34e573c44e95ab3 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 72aa29ce0a59 ("iio: adc: hi8435: Holt HI-8435 threshold detector")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-21-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/hi8435.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c
+index 8eb0140df133..771fa12bdc02 100644
+--- a/drivers/iio/adc/hi8435.c
++++ b/drivers/iio/adc/hi8435.c
+@@ -49,7 +49,7 @@ struct hi8435_priv {
+
+ unsigned threshold_lo[2]; /* GND-Open and Supply-Open thresholds */
+ unsigned threshold_hi[2]; /* GND-Open and Supply-Open thresholds */
+- u8 reg_buffer[3] ____cacheline_aligned;
++ u8 reg_buffer[3] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int hi8435_readb(struct hi8435_priv *priv, u8 reg, u8 *val)
+--
+2.35.1
+
--- /dev/null
+From 5bd7209d2fb3cbb5181b751f6aae185a73095eb7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:01 +0100
+Subject: iio: adc: ltc2496: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 1673b7ca2dc1fb3b8d7c94a112496c02d34ae449 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: e4c5c4dfaa88 ("iio: adc: new driver to support Linear technology's ltc2496")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-22-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ltc2496.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ltc2496.c b/drivers/iio/adc/ltc2496.c
+index 5a55f79f2574..dfb3bb5997e5 100644
+--- a/drivers/iio/adc/ltc2496.c
++++ b/drivers/iio/adc/ltc2496.c
+@@ -24,10 +24,10 @@ struct ltc2496_driverdata {
+ struct spi_device *spi;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+- unsigned char rxbuf[3] ____cacheline_aligned;
++ unsigned char rxbuf[3] __aligned(IIO_DMA_MINALIGN);
+ unsigned char txbuf[3];
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 7065ad65ebb56e9800f695ad5c23bb2512fdb2dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:02 +0100
+Subject: iio: adc: ltc2497: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 6ebf401d555ee1e75e779b865d38e171db0aa1f2 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: bc82222fcca1 ("iio:adc: Driver for Linear Technology LTC2497 ADC")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Michael Hennerich <michael.hennerich@analog.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-23-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ltc2497.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c
+index 1adddf5a88a9..f7c786f37ceb 100644
+--- a/drivers/iio/adc/ltc2497.c
++++ b/drivers/iio/adc/ltc2497.c
+@@ -20,10 +20,10 @@ struct ltc2497_driverdata {
+ struct ltc2497core_driverdata common_ddata;
+ struct i2c_client *client;
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+- __be32 buf ____cacheline_aligned;
++ __be32 buf __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
+--
+2.35.1
+
--- /dev/null
+From 243b10ba4c7c37896ab07af1611f41b24cd5536f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:03 +0100
+Subject: iio: adc: max1027: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit e754fb7e7a05e3838c9aa044b4114869dd0d1e17 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: fc167f624833 ("iio: add support of the max1027")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-24-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/max1027.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c
+index 4daf1d576c4e..b725d012625c 100644
+--- a/drivers/iio/adc/max1027.c
++++ b/drivers/iio/adc/max1027.c
+@@ -272,7 +272,7 @@ struct max1027_state {
+ struct mutex lock;
+ struct completion complete;
+
+- u8 reg ____cacheline_aligned;
++ u8 reg __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int max1027_wait_eoc(struct iio_dev *indio_dev)
+--
+2.35.1
+
--- /dev/null
+From 4c0b06d00a4ef1be7daec7aea866cddf0a72be40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 17:54:45 +0300
+Subject: iio: adc: max1027: unlock on error path in
+ max1027_read_single_value()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 06ee60eb507f00fb3643876ec05318c63332dc88 ]
+
+If max1027_wait_eoc() fails then call iio_device_release_direct_mode()
+before returning.
+
+Fixes: a0e831653ef9 ("iio: adc: max1027: Introduce an end of conversion helper")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Link: https://lore.kernel.org/r/YsbztVuAXnau2cIZ@kili
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/max1027.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c
+index b725d012625c..136fcf753837 100644
+--- a/drivers/iio/adc/max1027.c
++++ b/drivers/iio/adc/max1027.c
+@@ -349,8 +349,7 @@ static int max1027_read_single_value(struct iio_dev *indio_dev,
+ if (ret < 0) {
+ dev_err(&indio_dev->dev,
+ "Failed to configure conversion register\n");
+- iio_device_release_direct_mode(indio_dev);
+- return ret;
++ goto release;
+ }
+
+ /*
+@@ -360,11 +359,12 @@ static int max1027_read_single_value(struct iio_dev *indio_dev,
+ */
+ ret = max1027_wait_eoc(indio_dev);
+ if (ret)
+- return ret;
++ goto release;
+
+ /* Read result */
+ ret = spi_read(st->spi, st->buffer, (chan->type == IIO_TEMP) ? 4 : 2);
+
++release:
+ iio_device_release_direct_mode(indio_dev);
+
+ if (ret < 0)
+--
+2.35.1
+
--- /dev/null
+From fd307c3daaafac377818270522794f064415b546 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:04 +0100
+Subject: iio: adc: max11100: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 51f30d63145cc84cb8a8e0ec96f9a8b73e6b5448 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: a8e7e88df9ec ("iio: adc: Add Maxim MAX11100 driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Jacopo Mondi <jacopo@jmondi.org>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-25-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/max11100.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/max11100.c b/drivers/iio/adc/max11100.c
+index eb1ce6a0315c..49e38dca8fe2 100644
+--- a/drivers/iio/adc/max11100.c
++++ b/drivers/iio/adc/max11100.c
+@@ -33,10 +33,10 @@ struct max11100_state {
+ struct spi_device *spi;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+- u8 buffer[3] ____cacheline_aligned;
++ u8 buffer[3] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static const struct iio_chan_spec max11100_channels[] = {
+--
+2.35.1
+
--- /dev/null
+From 807b84f9342026fb1d16c6d4abe72a99d89eee3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:05 +0100
+Subject: iio: adc: max1118: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit f746ab0bac5b335b09143dcd01db6f9f26d0c9ec ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: a9e9c7153e96 ("iio: adc: add max1117/max1118/max1119 ADC driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Akinobu Mita <akinobu.mita@gmail.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-26-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/max1118.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/max1118.c b/drivers/iio/adc/max1118.c
+index a41bc570be21..75ab57d9aef7 100644
+--- a/drivers/iio/adc/max1118.c
++++ b/drivers/iio/adc/max1118.c
+@@ -42,7 +42,7 @@ struct max1118 {
+ s64 ts __aligned(8);
+ } scan;
+
+- u8 data ____cacheline_aligned;
++ u8 data __aligned(IIO_DMA_MINALIGN);
+ };
+
+ #define MAX1118_CHANNEL(ch) \
+--
+2.35.1
+
--- /dev/null
+From b4592892e2af96663c1e8e03ada0eba2ca92ef89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:06 +0100
+Subject: iio: adc: max1241: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 9d7019e43ee67a48cef63f8f23f002233064d390 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 8a80a71d9020 ("iio: adc: Add MAX1241 driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Alexandru Lazar <alazar@startmail.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-27-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/max1241.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/max1241.c b/drivers/iio/adc/max1241.c
+index a5afd84af58b..a815ad1f6913 100644
+--- a/drivers/iio/adc/max1241.c
++++ b/drivers/iio/adc/max1241.c
+@@ -26,7 +26,7 @@ struct max1241 {
+ struct regulator *vref;
+ struct gpio_desc *shutdown;
+
+- __be16 data ____cacheline_aligned;
++ __be16 data __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static const struct iio_chan_spec max1241_channels[] = {
+--
+2.35.1
+
--- /dev/null
+From 683a0c84db3fff5764d904d3f6d1e222df569bb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:07 +0100
+Subject: iio: adc: mcp320x: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit e770f78036ce4327caf285873f4b20564a8b4f0f ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Worth noting the fixes tag refers to the same issue being observed
+on a platform that probably had only 64 byte cachelines.
+
+Fixes: 0e81bc99a082 ("iio: mcp320x: Fix occasional incorrect readings")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Michael Welling <mwelling@ieee.org>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-28-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/mcp320x.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c
+index b4c69acb33e3..f3b81798b3c9 100644
+--- a/drivers/iio/adc/mcp320x.c
++++ b/drivers/iio/adc/mcp320x.c
+@@ -92,7 +92,7 @@ struct mcp320x {
+ struct mutex lock;
+ const struct mcp320x_chip_info *chip_info;
+
+- u8 tx_buf ____cacheline_aligned;
++ u8 tx_buf __aligned(IIO_DMA_MINALIGN);
+ u8 rx_buf[4];
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 3eca759eaae9a0b86d0b61ee22277e4e550385da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:08 +0100
+Subject: iio: adc: ti-adc0832: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 1e6bb81c23a84a078736a0f2a52bd765863e94ed ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: efc945fb729c ("iio: adc: add support for ADC0831/ADC0832/ADC0834/ADC0838 chips")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Akinobu Mita <akinobu.mita@gmail.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-29-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ti-adc0832.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ti-adc0832.c b/drivers/iio/adc/ti-adc0832.c
+index fb5e72600b96..b11ce555ba3b 100644
+--- a/drivers/iio/adc/ti-adc0832.c
++++ b/drivers/iio/adc/ti-adc0832.c
+@@ -36,7 +36,7 @@ struct adc0832 {
+ */
+ u8 data[24] __aligned(8);
+
+- u8 tx_buf[2] ____cacheline_aligned;
++ u8 tx_buf[2] __aligned(IIO_DMA_MINALIGN);
+ u8 rx_buf[2];
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 3a05b71f158cb209cf1f9915abaff3974a5b21a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:09 +0100
+Subject: iio: adc: ti-adc084s021: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit bb102fd600d1d6c0020a4514197c0604c4a218d9 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: 3691e5a69449 ("iio: adc: add driver for the ti-adc084s021 chip")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Acked-by: Mårten Lindahl <marten.lindahl@axis.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-30-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ti-adc084s021.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ti-adc084s021.c b/drivers/iio/adc/ti-adc084s021.c
+index c9b5d9aec3dc..1f6e53832e06 100644
+--- a/drivers/iio/adc/ti-adc084s021.c
++++ b/drivers/iio/adc/ti-adc084s021.c
+@@ -32,10 +32,10 @@ struct adc084s021 {
+ s64 ts __aligned(8);
+ } scan;
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache line.
+ */
+- u16 tx_buf[4] ____cacheline_aligned;
++ u16 tx_buf[4] __aligned(IIO_DMA_MINALIGN);
+ __be16 rx_buf[5]; /* First 16-bits are trash */
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 2e61fee35bf89ebe8ce4fc924bb92ac426918518 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:10 +0100
+Subject: iio: adc: ti-adc108s102: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 6909fe17888b66ea53ebb15640f82b97daa587a0 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Dual fixes tags as two cases that were introduced in different patches.
+One of those patches is a fix however and likely to have been backported
+to stable kernels.
+
+Note the second alignment marking is likely to be unnecessary, but is
+left for now to keep this fix simple.
+
+Fixes: 3691e5a69449 ("iio: adc: add driver for the ti-adc084s021 chip")
+Fixes: cbe5c6977604 ("iio: adc: ti-adc108s102: Fix alignment of buffer pushed to iio buffers.")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-31-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ti-adc108s102.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ti-adc108s102.c b/drivers/iio/adc/ti-adc108s102.c
+index c8e48881c37f..c82a161630e1 100644
+--- a/drivers/iio/adc/ti-adc108s102.c
++++ b/drivers/iio/adc/ti-adc108s102.c
+@@ -77,8 +77,8 @@ struct adc108s102_state {
+ * tx_buf: 8 channel read commands, plus 1 dummy command
+ * rx_buf: 1 dummy response, 8 channel responses
+ */
+- __be16 rx_buf[9] ____cacheline_aligned;
+- __be16 tx_buf[9] ____cacheline_aligned;
++ __be16 rx_buf[9] __aligned(IIO_DMA_MINALIGN);
++ __be16 tx_buf[9] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ #define ADC108S102_V_CHAN(index) \
+--
+2.35.1
+
--- /dev/null
+From 1800244194bc9d4068a9a79d8e8dd64aa0f7aca6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:11 +0100
+Subject: iio: adc: ti-adc12138: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 76890c3bce6003caf53b283c49a210280cb8ea33 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 50a6edb1b6e0 ("iio: adc: add ADC12130/ADC12132/ADC12138 ADC driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Akinobu Mita <akinobu.mita@gmail.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-32-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ti-adc12138.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ti-adc12138.c b/drivers/iio/adc/ti-adc12138.c
+index 59d75d09604f..c0a72d72f3a9 100644
+--- a/drivers/iio/adc/ti-adc12138.c
++++ b/drivers/iio/adc/ti-adc12138.c
+@@ -55,7 +55,7 @@ struct adc12138 {
+ */
+ __be16 data[20] __aligned(8);
+
+- u8 tx_buf[2] ____cacheline_aligned;
++ u8 tx_buf[2] __aligned(IIO_DMA_MINALIGN);
+ u8 rx_buf[2];
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 92fb98e1220ad9e2e9229f79e3441c0e495aa00d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:12 +0100
+Subject: iio: adc: ti-adc128s052: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 23c81e7a7e5204a08b553d07362d3082926663b8 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 913b86468674 ("iio: adc: Add TI ADC128S052")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-33-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ti-adc128s052.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c
+index 8e7adec87755..622fd384983c 100644
+--- a/drivers/iio/adc/ti-adc128s052.c
++++ b/drivers/iio/adc/ti-adc128s052.c
+@@ -29,7 +29,7 @@ struct adc128 {
+ struct regulator *reg;
+ struct mutex lock;
+
+- u8 buffer[2] ____cacheline_aligned;
++ u8 buffer[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int adc128_adc_conversion(struct adc128 *adc, u8 channel)
+--
+2.35.1
+
--- /dev/null
+From 9e184948dd0821613ba65b285303eeb226186c15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:13 +0100
+Subject: iio: adc: ti-adc161s626: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 3a828f204a110dc9f253c4cf3c1103d00a0681da ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 4d671b71beef ("iio: adc: ti-adc161s626: add support for TI 1-channel differential ADCs")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Matt Ranostay <mranostay@gmail.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-34-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ti-adc161s626.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ti-adc161s626.c b/drivers/iio/adc/ti-adc161s626.c
+index 75ca7f1c8726..b789891dcf49 100644
+--- a/drivers/iio/adc/ti-adc161s626.c
++++ b/drivers/iio/adc/ti-adc161s626.c
+@@ -71,7 +71,7 @@ struct ti_adc_data {
+ u8 read_size;
+ u8 shift;
+
+- u8 buffer[16] ____cacheline_aligned;
++ u8 buffer[16] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int ti_adc_read_measurement(struct ti_adc_data *data,
+--
+2.35.1
+
--- /dev/null
+From 1427897712e7c3b4243eb02393aa7093f086a5d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:14 +0100
+Subject: iio: adc: ti-ads124s08: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 7df19bd26cc0b85ff997cc9e2aaea712836b5460 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: e717f8c6dfec ("iio: adc: Add the TI ads124s08 ADC code")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-35-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ti-ads124s08.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ti-ads124s08.c b/drivers/iio/adc/ti-ads124s08.c
+index 767b3b634809..64833156c199 100644
+--- a/drivers/iio/adc/ti-ads124s08.c
++++ b/drivers/iio/adc/ti-ads124s08.c
+@@ -106,7 +106,7 @@ struct ads124s_private {
+ * timestamp is maintained.
+ */
+ u32 buffer[ADS124S08_MAX_CHANNELS + sizeof(s64)/sizeof(u32)] __aligned(8);
+- u8 data[5] ____cacheline_aligned;
++ u8 data[5] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ #define ADS124S08_CHAN(index) \
+--
+2.35.1
+
--- /dev/null
+From 1ddafe8a314a2c88b2a8678a255b21a48ca1b515 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:15 +0100
+Subject: iio: adc: ti-ads131e08: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 55afdd050c063ae4b8dbd566107a030c00d005fd ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: d935eddd2799 ("iio: adc: Add driver for Texas Instruments ADS131E0x ADC family")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Tomislav Denis <tomislav.denis@avl.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-36-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ti-ads131e08.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ti-ads131e08.c b/drivers/iio/adc/ti-ads131e08.c
+index 80a09817c119..32237cacc9a3 100644
+--- a/drivers/iio/adc/ti-ads131e08.c
++++ b/drivers/iio/adc/ti-ads131e08.c
+@@ -105,7 +105,7 @@ struct ads131e08_state {
+ s64 ts __aligned(8);
+ } tmp_buf;
+
+- u8 tx_buf[3] ____cacheline_aligned;
++ u8 tx_buf[3] __aligned(IIO_DMA_MINALIGN);
+ /*
+ * Add extra one padding byte to be able to access the last channel
+ * value using u32 pointer
+--
+2.35.1
+
--- /dev/null
+From 7b8496899acc90cdb57120381bf12ee5ddad5181 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:16 +0100
+Subject: iio: adc: ti-ads7950: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit dd54ba8b2469f6ae665c529623a9454ce5293ca8 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: 902c4b2446d4 ("iio: adc: New driver for TI ADS7950 chips")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: David Lechner <david@lechnology.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-37-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ti-ads7950.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ti-ads7950.c b/drivers/iio/adc/ti-ads7950.c
+index e3658b969c5b..2cc9a9bd9db6 100644
+--- a/drivers/iio/adc/ti-ads7950.c
++++ b/drivers/iio/adc/ti-ads7950.c
+@@ -102,11 +102,11 @@ struct ti_ads7950_state {
+ unsigned int gpio_cmd_settings_bitmask;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+ u16 rx_buf[TI_ADS7950_MAX_CHAN + 2 + TI_ADS7950_TIMESTAMP_SIZE]
+- ____cacheline_aligned;
++ __aligned(IIO_DMA_MINALIGN);
+ u16 tx_buf[TI_ADS7950_MAX_CHAN + 2];
+ u16 single_tx;
+ u16 single_rx;
+--
+2.35.1
+
--- /dev/null
+From 0cf3cecd1724cac0fead2f63eca93443f03fa564 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:17 +0100
+Subject: iio: adc: ti-ads8344: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 8966b11e5a14aaabc747ee97a7942fd50a681402 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 8dd2d7c0fed7 ("iio: adc: Add driver for the TI ADS8344 A/DC chips")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-38-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ti-ads8344.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ti-ads8344.c b/drivers/iio/adc/ti-ads8344.c
+index c96d2a9ba924..bbd85cb47f81 100644
+--- a/drivers/iio/adc/ti-ads8344.c
++++ b/drivers/iio/adc/ti-ads8344.c
+@@ -28,7 +28,7 @@ struct ads8344 {
+ */
+ struct mutex lock;
+
+- u8 tx_buf ____cacheline_aligned;
++ u8 tx_buf __aligned(IIO_DMA_MINALIGN);
+ u8 rx_buf[3];
+ };
+
+--
+2.35.1
+
--- /dev/null
+From afe9856bdf6fded3b6290a133c98dfe1a4551ef1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:18 +0100
+Subject: iio: adc: ti-ads8688: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit a2105d87eb8eb03591515df10102e04a1c9e0e46 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 3e87e7838328 ("iio: adc: Add TI ADS8688")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-39-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ti-ads8688.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c
+index 22c2583eedd0..7ee14c6d9f46 100644
+--- a/drivers/iio/adc/ti-ads8688.c
++++ b/drivers/iio/adc/ti-ads8688.c
+@@ -71,7 +71,7 @@ struct ads8688_state {
+ union {
+ __be32 d32;
+ u8 d8[4];
+- } data[2] ____cacheline_aligned;
++ } data[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ enum ads8688_id {
+--
+2.35.1
+
--- /dev/null
+From d19ab3f6d9218a3ada9001e202bc60daa3e26741 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:19 +0100
+Subject: iio: adc: ti-tlc4541: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 62fa19bf484bfeb52c56b7c6d6a6b1222c597f9c ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: ac2bec9d587c ("iio: adc: tlc4541: add support for TI tlc4541 adc")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-40-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ti-tlc4541.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ti-tlc4541.c b/drivers/iio/adc/ti-tlc4541.c
+index 2406eda9dfc6..30f629a553a1 100644
+--- a/drivers/iio/adc/ti-tlc4541.c
++++ b/drivers/iio/adc/ti-tlc4541.c
+@@ -37,12 +37,12 @@ struct tlc4541_state {
+ struct spi_message scan_single_msg;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ * 2 bytes data + 6 bytes padding + 8 bytes timestamp when
+ * call iio_push_to_buffers_with_timestamp.
+ */
+- __be16 rx_buf[8] ____cacheline_aligned;
++ __be16 rx_buf[8] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ struct tlc4541_chip_info {
+--
+2.35.1
+
--- /dev/null
+From 57946d40d3373d2ef0b3fa0fde7ec285c0321dbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:20 +0100
+Subject: iio: addac: ad74413r: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 00eb2b8a077062557772234019ecd6045b8b6298 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: fea251b6a5db ("iio: addac: add AD74413R driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Cosmin Tanislav <cosmin.tanislav@analog.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-41-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/addac/ad74413r.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c
+index acd230a6af35..6a66d7a65db7 100644
+--- a/drivers/iio/addac/ad74413r.c
++++ b/drivers/iio/addac/ad74413r.c
+@@ -77,13 +77,13 @@ struct ad74413r_state {
+ struct spi_transfer adc_samples_xfer[AD74413R_CHANNEL_MAX + 1];
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+ struct {
+ u8 rx_buf[AD74413R_FRAME_SIZE * AD74413R_CHANNEL_MAX];
+ s64 timestamp;
+- } adc_samples_buf ____cacheline_aligned;
++ } adc_samples_buf __aligned(IIO_DMA_MINALIGN);
+
+ u8 adc_samples_tx_buf[AD74413R_FRAME_SIZE * AD74413R_CHANNEL_MAX];
+ u8 reg_tx_buf[AD74413R_FRAME_SIZE];
+--
+2.35.1
+
--- /dev/null
+From 885072f977e866308dc0c02f9d531a388eff6e74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:21 +0100
+Subject: iio: amplifiers: ad8366: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 026bffa458d029a5f15ac3f82a9bb0f64aca403d ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: e71d42e03c60 ("iio: amplifiers: New driver for AD8366 Dual-Digital Variable Gain Amplifier")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-42-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/amplifiers/ad8366.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad8366.c
+index 1134ae12e531..f2c2ea79a07f 100644
+--- a/drivers/iio/amplifiers/ad8366.c
++++ b/drivers/iio/amplifiers/ad8366.c
+@@ -45,10 +45,10 @@ struct ad8366_state {
+ enum ad8366_type type;
+ struct ad8366_info *info;
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+- unsigned char data[2] ____cacheline_aligned;
++ unsigned char data[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static struct ad8366_info ad8366_infos[] = {
+--
+2.35.1
+
--- /dev/null
+From abd741152fe62653976fed7be8cc3caf49fd4eee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:22 +0100
+Subject: iio: common: ssp: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 314d2b1978bb3d20b1ec239f4e28c394da493f36 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 50dd64d57eee ("iio: common: ssp_sensors: Add sensorhub driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-43-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/common/ssp_sensors/ssp.h | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/iio/common/ssp_sensors/ssp.h b/drivers/iio/common/ssp_sensors/ssp.h
+index abb832795619..f649cdecc277 100644
+--- a/drivers/iio/common/ssp_sensors/ssp.h
++++ b/drivers/iio/common/ssp_sensors/ssp.h
+@@ -221,8 +221,7 @@ struct ssp_data {
+ struct iio_dev *sensor_devs[SSP_SENSOR_MAX];
+ atomic_t enable_refcount;
+
+- __le16 header_buffer[SSP_HEADER_BUFFER_SIZE / sizeof(__le16)]
+- ____cacheline_aligned;
++ __le16 header_buffer[SSP_HEADER_BUFFER_SIZE / sizeof(__le16)] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ void ssp_clean_pending_list(struct ssp_data *data);
+--
+2.35.1
+
--- /dev/null
+From 4c5c015d8edafc3cb61e4f079a6a252a1c1e921a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Mar 2022 19:03:43 +0100
+Subject: iio: core: fix a few code style issues
+
+From: Alexander Vorwerk <alexander.vorwerk@stud.uni-goettingen.de>
+
+[ Upstream commit f4decb4c6e374a4ded59a6a76b8236695e44d8bc ]
+
+* Fix indent in else statement
+* Remove unnecessary 'else' after 'break'
+* Remove space in '* attr'
+
+Signed-off-by: Alexander Vorwerk <alexander.vorwerk@stud.uni-goettingen.de>
+Link: https://lore.kernel.org/r/20220312180343.8935-1-alexander.vorwerk@stud.uni-goettingen.de
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/industrialio-buffer.c | 4 ++--
+ drivers/iio/industrialio-core.c | 3 +--
+ 2 files changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
+index b078eb2f3c9d..01369973329a 100644
+--- a/drivers/iio/industrialio-buffer.c
++++ b/drivers/iio/industrialio-buffer.c
+@@ -915,7 +915,7 @@ static int iio_verify_update(struct iio_dev *indio_dev,
+ if (scan_mask == NULL)
+ return -EINVAL;
+ } else {
+- scan_mask = compound_mask;
++ scan_mask = compound_mask;
+ }
+
+ config->scan_bytes = iio_compute_scan_bytes(indio_dev,
+@@ -1649,7 +1649,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer,
+ }
+
+ attrn = buffer_attrcount + scan_el_attrcount + ARRAY_SIZE(iio_buffer_attrs);
+- attr = kcalloc(attrn + 1, sizeof(* attr), GFP_KERNEL);
++ attr = kcalloc(attrn + 1, sizeof(*attr), GFP_KERNEL);
+ if (!attr) {
+ ret = -ENOMEM;
+ goto error_free_scan_mask;
+diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
+index 58d1180f4f61..b2d2b42614d3 100644
+--- a/drivers/iio/industrialio-core.c
++++ b/drivers/iio/industrialio-core.c
+@@ -908,8 +908,7 @@ static int __iio_str_to_fixpoint(const char *str, int fract_mult,
+ } else if (*str == '\n') {
+ if (*(str + 1) == '\0')
+ break;
+- else
+- return -EINVAL;
++ return -EINVAL;
+ } else if (!strncmp(str, " dB", sizeof(" dB") - 1) && scale_db) {
+ /* Ignore the dB suffix */
+ str += sizeof(" dB") - 1;
+--
+2.35.1
+
--- /dev/null
+From d6ab8955f559e48d27a517f2837ca0063089379d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:55:41 +0100
+Subject: iio: core: Fix IIO_ALIGN and rename as it was not sufficiently large
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 12c4efe3509b8018e76ea3ebda8227cb53bf5887 ]
+
+Discussion of the series:
+https://lore.kernel.org/all/20220405135758.774016-1-catalin.marinas@arm.com/
+mm, arm64: Reduce ARCH_KMALLOC_MINALIGN brought to my attention that
+our current IIO usage of L1CACHE_ALIGN is insufficient as their are Arm
+platforms out their with non coherent DMA and larger cache lines at
+at higher levels of their cache hierarchy.
+
+Rename the define to make it's purpose more explicit. It will be used
+much more widely going forwards (to replace incorrect ____cacheline_aligned
+markings.
+
+Note this patch will greatly reduce the padding on some architectures
+that have smaller requirements for DMA safe buffers.
+
+The history of changing values of ARCH_KMALLOC_MINALIGN via
+ARCH_DMA_MINALIGN on arm64 is rather complex. I'm not tagging this
+as fixing a particular patch from that route as it's not clear what to tag.
+
+Most recently a change to bring them back inline was reverted because
+of some Qualcomm Kryo cores with an L2 cache with 128-byte lines
+sitting above the point of coherency.
+
+c1132702c71f Revert "arm64: cache: Lower ARCH_DMA_MINALIGN to 64 (L1_CACHE_BYTES)"
+That reverts:
+65688d2a05de arm64: cache: Lower ARCH_DMA_MINALIGN to 64 (L1_CACHE_BYTES) which
+refers to the change originally being motivated by Thunder x1 performance
+rather than correctness.
+
+Fixes: 6f7c8ee585e9d ("staging:iio: Add ability to allocate private data space to iio_allocate_device")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-2-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/adi-axi-adc.c | 7 ++++---
+ drivers/iio/industrialio-core.c | 4 ++--
+ include/linux/iio/iio.h | 10 ++++++++--
+ 3 files changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c
+index a9e655e69eaa..8ffabdaf841e 100644
+--- a/drivers/iio/adc/adi-axi-adc.c
++++ b/drivers/iio/adc/adi-axi-adc.c
+@@ -84,7 +84,8 @@ void *adi_axi_adc_conv_priv(struct adi_axi_adc_conv *conv)
+ {
+ struct adi_axi_adc_client *cl = conv_to_client(conv);
+
+- return (char *)cl + ALIGN(sizeof(struct adi_axi_adc_client), IIO_ALIGN);
++ return (char *)cl + ALIGN(sizeof(struct adi_axi_adc_client),
++ IIO_DMA_MINALIGN);
+ }
+ EXPORT_SYMBOL_GPL(adi_axi_adc_conv_priv);
+
+@@ -169,9 +170,9 @@ static struct adi_axi_adc_conv *adi_axi_adc_conv_register(struct device *dev,
+ struct adi_axi_adc_client *cl;
+ size_t alloc_size;
+
+- alloc_size = ALIGN(sizeof(struct adi_axi_adc_client), IIO_ALIGN);
++ alloc_size = ALIGN(sizeof(struct adi_axi_adc_client), IIO_DMA_MINALIGN);
+ if (sizeof_priv)
+- alloc_size += ALIGN(sizeof_priv, IIO_ALIGN);
++ alloc_size += ALIGN(sizeof_priv, IIO_DMA_MINALIGN);
+
+ cl = kzalloc(alloc_size, GFP_KERNEL);
+ if (!cl)
+diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
+index b2d2b42614d3..e5aed96de8f3 100644
+--- a/drivers/iio/industrialio-core.c
++++ b/drivers/iio/industrialio-core.c
+@@ -1655,7 +1655,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv)
+
+ alloc_size = sizeof(struct iio_dev_opaque);
+ if (sizeof_priv) {
+- alloc_size = ALIGN(alloc_size, IIO_ALIGN);
++ alloc_size = ALIGN(alloc_size, IIO_DMA_MINALIGN);
+ alloc_size += sizeof_priv;
+ }
+
+@@ -1665,7 +1665,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv)
+
+ indio_dev = &iio_dev_opaque->indio_dev;
+ indio_dev->priv = (char *)iio_dev_opaque +
+- ALIGN(sizeof(struct iio_dev_opaque), IIO_ALIGN);
++ ALIGN(sizeof(struct iio_dev_opaque), IIO_DMA_MINALIGN);
+
+ indio_dev->dev.parent = parent;
+ indio_dev->dev.type = &iio_device_type;
+diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
+index faf00f2c0be6..c4ce02293f1f 100644
+--- a/include/linux/iio/iio.h
++++ b/include/linux/iio/iio.h
+@@ -9,6 +9,7 @@
+
+ #include <linux/device.h>
+ #include <linux/cdev.h>
++#include <linux/slab.h>
+ #include <linux/iio/types.h>
+ #include <linux/of.h>
+ /* IIO TODO LIST */
+@@ -657,8 +658,13 @@ static inline void *iio_device_get_drvdata(const struct iio_dev *indio_dev)
+ return dev_get_drvdata(&indio_dev->dev);
+ }
+
+-/* Can we make this smaller? */
+-#define IIO_ALIGN L1_CACHE_BYTES
++/*
++ * Used to ensure the iio_priv() structure is aligned to allow that structure
++ * to in turn include IIO_DMA_MINALIGN'd elements such as buffers which
++ * must not share cachelines with the rest of the structure, thus making
++ * them safe for use with non-coherent DMA.
++ */
++#define IIO_DMA_MINALIGN ARCH_KMALLOC_MINALIGN
+ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv);
+
+ /* The information at the returned address is guaranteed to be cacheline aligned */
+--
+2.35.1
+
--- /dev/null
+From ca8e9d0f0453f9c3567e0ee698144d4429695eae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 07:47:16 -0700
+Subject: iio: cros: Register FIFO callback after sensor is registered
+
+From: Gwendal Grignou <gwendal@chromium.org>
+
+[ Upstream commit 0b4ae3f6d1210c11f9baf159009c7227eacf90f2 ]
+
+Instead of registering callback to process sensor events right at
+initialization time, wait for the sensor to be register in the iio
+subsystem.
+
+Events can come at probe time (in case the kernel rebooted abruptly
+without switching the sensor off for instance), and be sent to IIO core
+before the sensor is fully registered.
+
+Fixes: aa984f1ba4a4 ("iio: cros_ec: Register to cros_ec_sensorhub when EC supports FIFO")
+Reported-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Link: https://lore.kernel.org/r/20220711144716.642617-1-gwendal@chromium.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/accel/cros_ec_accel_legacy.c | 4 +-
+ .../cros_ec_sensors/cros_ec_lid_angle.c | 4 +-
+ .../common/cros_ec_sensors/cros_ec_sensors.c | 6 +-
+ .../cros_ec_sensors/cros_ec_sensors_core.c | 58 ++++++++++++++-----
+ drivers/iio/light/cros_ec_light_prox.c | 6 +-
+ drivers/iio/pressure/cros_ec_baro.c | 6 +-
+ .../linux/iio/common/cros_ec_sensors_core.h | 7 ++-
+ 7 files changed, 60 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/iio/accel/cros_ec_accel_legacy.c b/drivers/iio/accel/cros_ec_accel_legacy.c
+index b6f3471b62dc..3b77fded2dc0 100644
+--- a/drivers/iio/accel/cros_ec_accel_legacy.c
++++ b/drivers/iio/accel/cros_ec_accel_legacy.c
+@@ -215,7 +215,7 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
+- cros_ec_sensors_capture, NULL);
++ cros_ec_sensors_capture);
+ if (ret)
+ return ret;
+
+@@ -235,7 +235,7 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev)
+ state->sign[CROS_EC_SENSOR_Z] = -1;
+ }
+
+- return devm_iio_device_register(dev, indio_dev);
++ return cros_ec_sensors_core_register(dev, indio_dev, NULL);
+ }
+
+ static struct platform_driver cros_ec_accel_platform_driver = {
+diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
+index af801e203623..02d3cf36acb0 100644
+--- a/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
++++ b/drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c
+@@ -97,7 +97,7 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev)
+ if (!indio_dev)
+ return -ENOMEM;
+
+- ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL, NULL);
++ ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL);
+ if (ret)
+ return ret;
+
+@@ -113,7 +113,7 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev)
+ if (ret)
+ return ret;
+
+- return devm_iio_device_register(dev, indio_dev);
++ return cros_ec_sensors_core_register(dev, indio_dev, NULL);
+ }
+
+ static const struct platform_device_id cros_ec_lid_angle_ids[] = {
+diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
+index 376a5b30010a..5cce34fdff02 100644
+--- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
++++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
+@@ -235,8 +235,7 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
+- cros_ec_sensors_capture,
+- cros_ec_sensors_push_data);
++ cros_ec_sensors_capture);
+ if (ret)
+ return ret;
+
+@@ -297,7 +296,8 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
+ else
+ state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
+
+- return devm_iio_device_register(dev, indio_dev);
++ return cros_ec_sensors_core_register(dev, indio_dev,
++ cros_ec_sensors_push_data);
+ }
+
+ static const struct platform_device_id cros_ec_sensors_ids[] = {
+diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
+index b2725c6adc7f..ed9716832161 100644
+--- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
++++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
+@@ -234,21 +234,18 @@ static void cros_ec_sensors_core_clean(void *arg)
+
+ /**
+ * cros_ec_sensors_core_init() - basic initialization of the core structure
+- * @pdev: platform device created for the sensors
++ * @pdev: platform device created for the sensor
+ * @indio_dev: iio device structure of the device
+ * @physical_device: true if the device refers to a physical device
+ * @trigger_capture: function pointer to call buffer is triggered,
+ * for backward compatibility.
+- * @push_data: function to call when cros_ec_sensorhub receives
+- * a sample for that sensor.
+ *
+ * Return: 0 on success, -errno on failure.
+ */
+ int cros_ec_sensors_core_init(struct platform_device *pdev,
+ struct iio_dev *indio_dev,
+ bool physical_device,
+- cros_ec_sensors_capture_t trigger_capture,
+- cros_ec_sensorhub_push_data_cb_t push_data)
++ cros_ec_sensors_capture_t trigger_capture)
+ {
+ struct device *dev = &pdev->dev;
+ struct cros_ec_sensors_core_state *state = iio_priv(indio_dev);
+@@ -339,17 +336,6 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
+ if (ret)
+ return ret;
+
+- ret = cros_ec_sensorhub_register_push_data(
+- sensor_hub, sensor_platform->sensor_num,
+- indio_dev, push_data);
+- if (ret)
+- return ret;
+-
+- ret = devm_add_action_or_reset(
+- dev, cros_ec_sensors_core_clean, pdev);
+- if (ret)
+- return ret;
+-
+ /* Timestamp coming from FIFO are in ns since boot. */
+ ret = iio_device_set_clock(indio_dev, CLOCK_BOOTTIME);
+ if (ret)
+@@ -371,6 +357,46 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
+ }
+ EXPORT_SYMBOL_GPL(cros_ec_sensors_core_init);
+
++/**
++ * cros_ec_sensors_core_register() - Register callback to FIFO and IIO when
++ * sensor is ready.
++ * It must be called at the end of the sensor probe routine.
++ * @dev: device created for the sensor
++ * @indio_dev: iio device structure of the device
++ * @push_data: function to call when cros_ec_sensorhub receives
++ * a sample for that sensor.
++ *
++ * Return: 0 on success, -errno on failure.
++ */
++int cros_ec_sensors_core_register(struct device *dev,
++ struct iio_dev *indio_dev,
++ cros_ec_sensorhub_push_data_cb_t push_data)
++{
++ struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev);
++ struct cros_ec_sensorhub *sensor_hub = dev_get_drvdata(dev->parent);
++ struct platform_device *pdev = to_platform_device(dev);
++ struct cros_ec_dev *ec = sensor_hub->ec;
++ int ret;
++
++ ret = devm_iio_device_register(dev, indio_dev);
++ if (ret)
++ return ret;
++
++ if (!push_data ||
++ !cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO))
++ return 0;
++
++ ret = cros_ec_sensorhub_register_push_data(
++ sensor_hub, sensor_platform->sensor_num,
++ indio_dev, push_data);
++ if (ret)
++ return ret;
++
++ return devm_add_action_or_reset(
++ dev, cros_ec_sensors_core_clean, pdev);
++}
++EXPORT_SYMBOL_GPL(cros_ec_sensors_core_register);
++
+ /**
+ * cros_ec_motion_send_host_cmd() - send motion sense host command
+ * @state: pointer to state information for device
+diff --git a/drivers/iio/light/cros_ec_light_prox.c b/drivers/iio/light/cros_ec_light_prox.c
+index de472f23d1cb..16b893bae388 100644
+--- a/drivers/iio/light/cros_ec_light_prox.c
++++ b/drivers/iio/light/cros_ec_light_prox.c
+@@ -181,8 +181,7 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
+- cros_ec_sensors_capture,
+- cros_ec_sensors_push_data);
++ cros_ec_sensors_capture);
+ if (ret)
+ return ret;
+
+@@ -240,7 +239,8 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
+
+ state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
+
+- return devm_iio_device_register(dev, indio_dev);
++ return cros_ec_sensors_core_register(dev, indio_dev,
++ cros_ec_sensors_push_data);
+ }
+
+ static const struct platform_device_id cros_ec_light_prox_ids[] = {
+diff --git a/drivers/iio/pressure/cros_ec_baro.c b/drivers/iio/pressure/cros_ec_baro.c
+index 2f882e109423..0511edbf868d 100644
+--- a/drivers/iio/pressure/cros_ec_baro.c
++++ b/drivers/iio/pressure/cros_ec_baro.c
+@@ -138,8 +138,7 @@ static int cros_ec_baro_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
+- cros_ec_sensors_capture,
+- cros_ec_sensors_push_data);
++ cros_ec_sensors_capture);
+ if (ret)
+ return ret;
+
+@@ -186,7 +185,8 @@ static int cros_ec_baro_probe(struct platform_device *pdev)
+
+ state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
+
+- return devm_iio_device_register(dev, indio_dev);
++ return cros_ec_sensors_core_register(dev, indio_dev,
++ cros_ec_sensors_push_data);
+ }
+
+ static const struct platform_device_id cros_ec_baro_ids[] = {
+diff --git a/include/linux/iio/common/cros_ec_sensors_core.h b/include/linux/iio/common/cros_ec_sensors_core.h
+index c582e1a14232..7b5dbd749995 100644
+--- a/include/linux/iio/common/cros_ec_sensors_core.h
++++ b/include/linux/iio/common/cros_ec_sensors_core.h
+@@ -95,8 +95,11 @@ int cros_ec_sensors_read_cmd(struct iio_dev *indio_dev, unsigned long scan_mask,
+ struct platform_device;
+ int cros_ec_sensors_core_init(struct platform_device *pdev,
+ struct iio_dev *indio_dev, bool physical_device,
+- cros_ec_sensors_capture_t trigger_capture,
+- cros_ec_sensorhub_push_data_cb_t push_data);
++ cros_ec_sensors_capture_t trigger_capture);
++
++int cros_ec_sensors_core_register(struct device *dev,
++ struct iio_dev *indio_dev,
++ cros_ec_sensorhub_push_data_cb_t push_data);
+
+ irqreturn_t cros_ec_sensors_capture(int irq, void *p);
+ int cros_ec_sensors_push_data(struct iio_dev *indio_dev,
+--
+2.35.1
+
--- /dev/null
+From 3381d9854351e393c95db2d94c2895ea47b87ac8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:23 +0100
+Subject: iio: dac: ad5064: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 8779b88c214fa0f8fdfb9c54a124f468884d356a ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: 6a17a0768f77 ("iio:dac:ad5064: Add support for the ad5629r and ad5669r")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Lars-Peter Clausen <lars@metafoo.de>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-44-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5064.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c
+index 27ee2c63c5d4..e3b1add34f46 100644
+--- a/drivers/iio/dac/ad5064.c
++++ b/drivers/iio/dac/ad5064.c
+@@ -115,13 +115,13 @@ struct ad5064_state {
+ struct mutex lock;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+ union {
+ u8 i2c[3];
+ __be32 spi;
+- } data ____cacheline_aligned;
++ } data __aligned(IIO_DMA_MINALIGN);
+ };
+
+ enum ad5064_type {
+--
+2.35.1
+
--- /dev/null
+From c3db6bc486440b731331c1d509ecb7aa8a653dc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:24 +0100
+Subject: iio: dac: ad5360: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 94ec314e1bd686b669c24385ce2dbc967eb74147 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: a3e2940c24d3 ("staging:iio:dac: Add AD5360 driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Lars-Peter Clausen <lars@metafoo.de>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-45-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5360.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c
+index ecbc6a51d60f..1bde696a572c 100644
+--- a/drivers/iio/dac/ad5360.c
++++ b/drivers/iio/dac/ad5360.c
+@@ -79,13 +79,13 @@ struct ad5360_state {
+ struct mutex lock;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+ union {
+ __be32 d32;
+ u8 d8[4];
+- } data[2] ____cacheline_aligned;
++ } data[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ enum ad5360_type {
+--
+2.35.1
+
--- /dev/null
+From 99d52f47f794431ac904bb2380f7915cd5a1aecb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:25 +0100
+Subject: iio: dac: ad5421: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit d2b240d3d31c66df4d2da54c75ff8e27a0e006c3 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: 5691b23489db ("staging:iio:dac: Add AD5421 driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Lars-Peter Clausen <lars@metafoo.de>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-46-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5421.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c
+index eedf661d32b2..7644acfd879e 100644
+--- a/drivers/iio/dac/ad5421.c
++++ b/drivers/iio/dac/ad5421.c
+@@ -72,13 +72,13 @@ struct ad5421_state {
+ struct mutex lock;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+ union {
+ __be32 d32;
+ u8 d8[4];
+- } data[2] ____cacheline_aligned;
++ } data[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static const struct iio_event_spec ad5421_current_event[] = {
+--
+2.35.1
+
--- /dev/null
+From 39eb4913ef41ec04eb1a3c8e62aea141626f3019 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:26 +0100
+Subject: iio: dac: ad5449: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 678d536bb454e3bbedcaa68208550ac9dc1cc066 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: 8341dc04dfb3 ("iio:dac: Add support for the ad5449")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Lars-Peter Clausen <lars@metafoo.de>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-47-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5449.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/dac/ad5449.c b/drivers/iio/dac/ad5449.c
+index bad9bdaafa94..4572d6f49275 100644
+--- a/drivers/iio/dac/ad5449.c
++++ b/drivers/iio/dac/ad5449.c
+@@ -68,10 +68,10 @@ struct ad5449 {
+ uint16_t dac_cache[AD5449_MAX_CHANNELS];
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+- __be16 data[2] ____cacheline_aligned;
++ __be16 data[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ enum ad5449_type {
+--
+2.35.1
+
--- /dev/null
+From 665b0568491a657d7ae916d70c25dcd00c78a109 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:27 +0100
+Subject: iio: dac: ad5504: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 00b9737caa5aaed5cf45a7c7498edf5957efa3b2 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 0dbe59c7a788 ("iio:ad5504: Do not store transfer buffers on the stack")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Lars-Peter Clausen <lars@metafoo.de>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-48-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5504.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c
+index 8507573aa13e..e472c9564edf 100644
+--- a/drivers/iio/dac/ad5504.c
++++ b/drivers/iio/dac/ad5504.c
+@@ -54,7 +54,7 @@ struct ad5504_state {
+ unsigned pwr_down_mask;
+ unsigned pwr_down_mode;
+
+- __be16 data[2] ____cacheline_aligned;
++ __be16 data[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ /*
+--
+2.35.1
+
--- /dev/null
+From fd49d81206b6fc9e23c47fa4b7b20cb29e794a22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:28 +0100
+Subject: iio: dac: ad5592r: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 4a4a79c06caeec47003bcbee1cf3094479f26e24 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 56ca9db862bf ("iio: dac: Add support for the AD5592R/AD5593R ADCs/DACs")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Paul Cercueil <paul@crapouillou.net>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-49-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5592r-base.h | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iio/dac/ad5592r-base.h b/drivers/iio/dac/ad5592r-base.h
+index 2a22ef691996..cc7be426cbc8 100644
+--- a/drivers/iio/dac/ad5592r-base.h
++++ b/drivers/iio/dac/ad5592r-base.h
+@@ -14,6 +14,8 @@
+ #include <linux/mutex.h>
+ #include <linux/gpio/driver.h>
+
++#include <linux/iio/iio.h>
++
+ struct device;
+ struct ad5592r_state;
+
+@@ -65,7 +67,7 @@ struct ad5592r_state {
+ u8 gpio_in;
+ u8 gpio_val;
+
+- __be16 spi_msg ____cacheline_aligned;
++ __be16 spi_msg __aligned(IIO_DMA_MINALIGN);
+ __be16 spi_msg_nop;
+ };
+
+--
+2.35.1
+
--- /dev/null
+From f01e56d326beade894a1d8b32b686ad31d045f21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:29 +0100
+Subject: iio: dac: ad5686: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 444e38927d9af093de7cdc6afbb7afdc3485da2d ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: 0357e488b825 ("iio:dac:ad5686: Refactor the driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-50-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5686.h | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/dac/ad5686.h b/drivers/iio/dac/ad5686.h
+index cd5fff9e9d53..b7ade3a6b9b6 100644
+--- a/drivers/iio/dac/ad5686.h
++++ b/drivers/iio/dac/ad5686.h
+@@ -13,6 +13,8 @@
+ #include <linux/mutex.h>
+ #include <linux/kernel.h>
+
++#include <linux/iio/iio.h>
++
+ #define AD5310_CMD(x) ((x) << 12)
+
+ #define AD5683_DATA(x) ((x) << 4)
+@@ -137,7 +139,7 @@ struct ad5686_state {
+ struct mutex lock;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+
+@@ -145,7 +147,7 @@ struct ad5686_state {
+ __be32 d32;
+ __be16 d16;
+ u8 d8[4];
+- } data[3] ____cacheline_aligned;
++ } data[3] __aligned(IIO_DMA_MINALIGN);
+ };
+
+
+--
+2.35.1
+
--- /dev/null
+From 700d484f6fd5037816c7e4a85bbe99688c03affa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:30 +0100
+Subject: iio: dac: ad5755: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit d0c167ceff2d833ee493dd58164dc87bd36e48aa ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: c499d029d805 ("iio:dac: Add ad5755 driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-51-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5755.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c
+index 7a62e6e1d5f1..bbb345323b69 100644
+--- a/drivers/iio/dac/ad5755.c
++++ b/drivers/iio/dac/ad5755.c
+@@ -189,14 +189,14 @@ struct ad5755_state {
+ struct mutex lock;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+
+ union {
+ __be32 d32;
+ u8 d8[4];
+- } data[2] ____cacheline_aligned;
++ } data[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ enum ad5755_type {
+--
+2.35.1
+
--- /dev/null
+From d9b0fd012e2554615badbee713133f32c111aecf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:31 +0100
+Subject: iio: dac: ad5761: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 7d12a61187aed57863c41032acbc1fae516d6e49 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: 131497acd88a ("iio: add ad5761 DAC driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-52-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5761.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/dac/ad5761.c b/drivers/iio/dac/ad5761.c
+index 4cb8471db81e..6aa1a068adb0 100644
+--- a/drivers/iio/dac/ad5761.c
++++ b/drivers/iio/dac/ad5761.c
+@@ -70,13 +70,13 @@ struct ad5761_state {
+ enum ad5761_voltage_range range;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+ union {
+ __be32 d32;
+ u8 d8[4];
+- } data[3] ____cacheline_aligned;
++ } data[3] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static const struct ad5761_range_params ad5761_range_params[] = {
+--
+2.35.1
+
--- /dev/null
+From 474ff795ef93e1199bdc18dff2e67f9a2b170c12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:32 +0100
+Subject: iio: dac: ad5764: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit b378722a3e9bb51318c0de7eeb4d71f2fcd6987f ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: 68b14d7ea956 ("staging:iio:dac: Add AD5764 driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-53-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5764.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/dac/ad5764.c b/drivers/iio/dac/ad5764.c
+index d235a8047ba0..26c049d5b73a 100644
+--- a/drivers/iio/dac/ad5764.c
++++ b/drivers/iio/dac/ad5764.c
+@@ -56,13 +56,13 @@ struct ad5764_state {
+ struct mutex lock;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+ union {
+ __be32 d32;
+ u8 d8[4];
+- } data[2] ____cacheline_aligned;
++ } data[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ enum ad5764_type {
+--
+2.35.1
+
--- /dev/null
+From bf7ab49a9d638bba0fa330412b4738766057f90b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:33 +0100
+Subject: iio: dac: ad5766: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit c32be7f035ae430ba9c142b03ceb9f935b09ed6b ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: fd9373e41b9b ("iio: dac: ad5766: add driver support for AD5766")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-54-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5766.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/dac/ad5766.c b/drivers/iio/dac/ad5766.c
+index 43189af2fb1f..899894523752 100644
+--- a/drivers/iio/dac/ad5766.c
++++ b/drivers/iio/dac/ad5766.c
+@@ -123,7 +123,7 @@ struct ad5766_state {
+ u32 d32;
+ u16 w16[2];
+ u8 b8[4];
+- } data[3] ____cacheline_aligned;
++ } data[3] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ struct ad5766_span_tbl {
+--
+2.35.1
+
--- /dev/null
+From efb98c037ba42d660fc4c3ddb6fb082fa0b539ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:34 +0100
+Subject: iio: dac: ad5770r: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 27f2261d16d01858b8e5baca5a1a515b040429c4 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: cbbb819837f6 ("iio: dac: ad5770r: Add AD5770R support")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Alexandru Tachici <alexandru.tachici@analog.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-55-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5770r.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/dac/ad5770r.c b/drivers/iio/dac/ad5770r.c
+index 7e2fd32e993a..f66d67402e43 100644
+--- a/drivers/iio/dac/ad5770r.c
++++ b/drivers/iio/dac/ad5770r.c
+@@ -140,7 +140,7 @@ struct ad5770r_state {
+ bool ch_pwr_down[AD5770R_MAX_CHANNELS];
+ bool internal_ref;
+ bool external_res;
+- u8 transf_buf[2] ____cacheline_aligned;
++ u8 transf_buf[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static const struct regmap_config ad5770r_spi_regmap_config = {
+--
+2.35.1
+
--- /dev/null
+From d668360b289fcc8815be00adeb2b94b918a35b0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:35 +0100
+Subject: iio: dac: ad5791: Fix alignment for DMA saftey
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit b2d5e9de77c8774a5a6cff59d928f2fa38cbc642 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 791bb52a0cd2 ("iio:ad5791: Do not store transfer buffers on the stack")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-56-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad5791.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c
+index 2b14914b4050..ee7e89774d9d 100644
+--- a/drivers/iio/dac/ad5791.c
++++ b/drivers/iio/dac/ad5791.c
+@@ -95,7 +95,7 @@ struct ad5791_state {
+ union {
+ __be32 d32;
+ u8 d8[4];
+- } data[3] ____cacheline_aligned;
++ } data[3] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ enum ad5791_supported_device_ids {
+--
+2.35.1
+
--- /dev/null
+From 093aeb64ad94eb309d105a69d46431509d5dcad9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:36 +0100
+Subject: iio: dac: ad7293: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 8482468b30bdb16d4a764f995d7a63d94fa0cf40 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 0bb12606c05f ("iio:dac:ad7293: add support for AD7293")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-57-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad7293.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/dac/ad7293.c b/drivers/iio/dac/ad7293.c
+index 59a38ca4c3c7..06f05750d921 100644
+--- a/drivers/iio/dac/ad7293.c
++++ b/drivers/iio/dac/ad7293.c
+@@ -144,7 +144,7 @@ struct ad7293_state {
+ struct regulator *reg_avdd;
+ struct regulator *reg_vdrive;
+ u8 page_select;
+- u8 data[3] ____cacheline_aligned;
++ u8 data[3] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int ad7293_page_select(struct ad7293_state *st, unsigned int reg)
+--
+2.35.1
+
--- /dev/null
+From b1681e245f1ceef94ba1d411ac31cbd527014ad9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:37 +0100
+Subject: iio: dac: ad7303: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 69e51448ddfb9062efdf83e2d3179498e0aeb293 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: f83478240e74 ("iio:dac: Add support for the AD7303")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-58-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad7303.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/dac/ad7303.c b/drivers/iio/dac/ad7303.c
+index 91eaaf793b3e..558af7926a89 100644
+--- a/drivers/iio/dac/ad7303.c
++++ b/drivers/iio/dac/ad7303.c
+@@ -44,10 +44,10 @@ struct ad7303_state {
+
+ struct mutex lock;
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+- __be16 data ____cacheline_aligned;
++ __be16 data __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int ad7303_write(struct ad7303_state *st, unsigned int chan,
+--
+2.35.1
+
--- /dev/null
+From 69314ef759e94502478e5490b5449773c80f9cba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:38 +0100
+Subject: iio: dac: ad8801: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 1c20292c6b60cfc60a5e652174b8063e5cc03fec ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 7f270bc9a2d9 ("iio: dac: AD8801: add Analog Devices AD8801/AD8803 support")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-59-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ad8801.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/dac/ad8801.c b/drivers/iio/dac/ad8801.c
+index 6be35c92d435..919e8c880697 100644
+--- a/drivers/iio/dac/ad8801.c
++++ b/drivers/iio/dac/ad8801.c
+@@ -26,7 +26,7 @@ struct ad8801_state {
+ struct regulator *vrefh_reg;
+ struct regulator *vrefl_reg;
+
+- __be16 data ____cacheline_aligned;
++ __be16 data __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int ad8801_spi_write(struct ad8801_state *state,
+--
+2.35.1
+
--- /dev/null
+From d4f512807ffc3dc2d4116ceaf1dfa04c55f690b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:39 +0100
+Subject: iio: dac: ltc2688: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 2030708377a219b548a9a36da57d3852382baf1d ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Update the comment to include 'may'.
+
+Fixes: 832cb9eeb931 ("iio: dac: add support for ltc2688")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-60-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ltc2688.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/dac/ltc2688.c b/drivers/iio/dac/ltc2688.c
+index 2f9c384885f4..04ec38b1cad1 100644
+--- a/drivers/iio/dac/ltc2688.c
++++ b/drivers/iio/dac/ltc2688.c
+@@ -91,10 +91,10 @@ struct ltc2688_state {
+ struct mutex lock;
+ int vref;
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+- u8 tx_data[6] ____cacheline_aligned;
++ u8 tx_data[6] __aligned(IIO_DMA_MINALIGN);
+ u8 rx_data[3];
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 03db068dc6b7989108721196d4e5ae88187ef0a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:40 +0100
+Subject: iio: dac: mcp4922: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit e66bf04797f1f95a2402414c00e64d00f63d31ec ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 1b791fadf3a1 ("iio: dac: mcp4902/mcp4912/mcp4922 dac driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Acked-by: Michael Welling <mwelling@ieee.org>
+Link: https://lore.kernel.org/r/20220508175712.647246-61-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/mcp4922.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/dac/mcp4922.c b/drivers/iio/dac/mcp4922.c
+index cb9e60e71b91..6c0e31032c57 100644
+--- a/drivers/iio/dac/mcp4922.c
++++ b/drivers/iio/dac/mcp4922.c
+@@ -29,7 +29,7 @@ struct mcp4922_state {
+ unsigned int value[MCP4922_NUM_CHANNELS];
+ unsigned int vref_mv;
+ struct regulator *vref_reg;
+- u8 mosi[2] ____cacheline_aligned;
++ u8 mosi[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ #define MCP4922_CHAN(chan, bits) { \
+--
+2.35.1
+
--- /dev/null
+From a02dc6ec17f4f13c7024487d6c944b4af03075c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:41 +0100
+Subject: iio: dac: ti-dac082s085: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 03a0cc77f164e4e59b970d50c6e9a6caf06dae80 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 61011264c1af ("iio: dac: Add Texas Instruments 8/10/12-bit 2/4-channel DAC driver")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-62-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ti-dac082s085.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/dac/ti-dac082s085.c b/drivers/iio/dac/ti-dac082s085.c
+index 4e1156e6deb2..f52ad8fa7747 100644
+--- a/drivers/iio/dac/ti-dac082s085.c
++++ b/drivers/iio/dac/ti-dac082s085.c
+@@ -55,7 +55,7 @@ struct ti_dac_chip {
+ bool powerdown;
+ u8 powerdown_mode;
+ u8 resolution;
+- u8 buf[2] ____cacheline_aligned;
++ u8 buf[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ #define WRITE_NOT_UPDATE(chan) (0x00 | (chan) << 6)
+--
+2.35.1
+
--- /dev/null
+From 7211f853d1db4182ad452576c326ed6b0c0cd626 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:42 +0100
+Subject: iio: dac: ti-dac5571: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 58e22371539e01c742be5c30295f591a6a17e348 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: df38a4a72a3b ("iio: dac: add TI DAC5571 family support")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Sean Nyekjaer <sean.nyekjaer@prevas.dk>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-63-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ti-dac5571.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/dac/ti-dac5571.c b/drivers/iio/dac/ti-dac5571.c
+index 0b775f943db3..ba68ea1e3455 100644
+--- a/drivers/iio/dac/ti-dac5571.c
++++ b/drivers/iio/dac/ti-dac5571.c
+@@ -52,7 +52,7 @@ struct dac5571_data {
+ struct dac5571_spec const *spec;
+ int (*dac5571_cmd)(struct dac5571_data *data, int channel, u16 val);
+ int (*dac5571_pwrdwn)(struct dac5571_data *data, int channel, u8 pwrdwn);
+- u8 buf[3] ____cacheline_aligned;
++ u8 buf[3] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ #define DAC5571_POWERDOWN(mode) ((mode) + 1)
+--
+2.35.1
+
--- /dev/null
+From 36746538b1694ca8125e10b7066c2fb7fac4d4fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:43 +0100
+Subject: iio: dac: ti-dac7311: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 3637c49ed54632d7c221af718d2d7b1d381d4b6e ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 7a02ef7907d8 ("iio:dac:ti-dac7311 Add driver for Texas Instrument DAC7311")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Charles-Antoine Couret <charles-antoine.couret@essensium.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-64-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ti-dac7311.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/dac/ti-dac7311.c b/drivers/iio/dac/ti-dac7311.c
+index e10d17e60ed3..dd0a7b77838d 100644
+--- a/drivers/iio/dac/ti-dac7311.c
++++ b/drivers/iio/dac/ti-dac7311.c
+@@ -52,7 +52,7 @@ struct ti_dac_chip {
+ bool powerdown;
+ u8 powerdown_mode;
+ u8 resolution;
+- u8 buf[2] ____cacheline_aligned;
++ u8 buf[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static u8 ti_dac_get_power(struct ti_dac_chip *ti_dac, bool powerdown)
+--
+2.35.1
+
--- /dev/null
+From 7629bede27df518d28e3dbac7d6057bfed522727 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:44 +0100
+Subject: iio: dac: ti-dac7612: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit b9ac08b3282a95fcefb057c2886028a6807725d8 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Updated help text to 'may' require buffers to be in their own cacheline.
+
+Fixes: 977724d20584 ("iio:dac:ti-dac7612: Add driver for Texas Instruments DAC7612")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Ricardo Ribalda <ribalda@kernel.org>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-65-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/dac/ti-dac7612.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/dac/ti-dac7612.c b/drivers/iio/dac/ti-dac7612.c
+index 4c0f4b5e9ff4..8195815de26f 100644
+--- a/drivers/iio/dac/ti-dac7612.c
++++ b/drivers/iio/dac/ti-dac7612.c
+@@ -31,10 +31,10 @@ struct dac7612 {
+ struct mutex lock;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+- uint8_t data[2] ____cacheline_aligned;
++ uint8_t data[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int dac7612_cmd_single(struct dac7612 *priv, int channel, u16 val)
+--
+2.35.1
+
--- /dev/null
+From 51b90a9d166c1c5ecaf9d2b0f9aa112167946627 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:45 +0100
+Subject: iio: frequency: ad9523: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 8ff2eb625c353b1491d9f89f1dfd52e7aef5734c ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Updated help text to 'may' require buffers to be in their own cacheline.
+
+Fixes: cd1678f96329 ("iio: frequency: New driver for AD9523 SPI Low Jitter Clock Generator")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-66-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/frequency/ad9523.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c
+index a0f92c336fc4..31c97f9f2c1b 100644
+--- a/drivers/iio/frequency/ad9523.c
++++ b/drivers/iio/frequency/ad9523.c
+@@ -287,13 +287,13 @@ struct ad9523_state {
+ struct mutex lock;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
+- * transfer buffers to live in their own cache lines.
++ * DMA (thus cache coherency maintenance) may require that
++ * transfer buffers live in their own cache lines.
+ */
+ union {
+ __be32 d32;
+ u8 d8[4];
+- } data[2] ____cacheline_aligned;
++ } data[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int ad9523_read(struct iio_dev *indio_dev, unsigned int addr)
+--
+2.35.1
+
--- /dev/null
+From 90d0622efe419110b313e0c6dbdccd8f91196fe6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:46 +0100
+Subject: iio: frequency: adf4350: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 389b8972eb2a614cb3189e5fa55b1b7f66142c71 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Updated help text to 'may' require buffers to be in their own cacheline.
+
+Fixes: e31166f0fd48 ("iio: frequency: New driver for Analog Devices ADF4350/ADF4351 Wideband Synthesizers")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-67-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/frequency/adf4350.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c
+index be1218d86291..85e289700c3c 100644
+--- a/drivers/iio/frequency/adf4350.c
++++ b/drivers/iio/frequency/adf4350.c
+@@ -56,10 +56,10 @@ struct adf4350_state {
+ */
+ struct mutex lock;
+ /*
+- * DMA (thus cache coherency maintenance) requires the
+- * transfer buffers to live in their own cache lines.
++ * DMA (thus cache coherency maintenance) may require that
++ * transfer buffers live in their own cache lines.
+ */
+- __be32 val ____cacheline_aligned;
++ __be32 val __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static struct adf4350_platform_data default_pdata = {
+--
+2.35.1
+
--- /dev/null
+From 4861d2d8fa3b7a56ef0c6e46a51845353df9c46f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:47 +0100
+Subject: iio: frequency: adf4371: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 0bb5675befe666eeed71ad808426cf2ec1c9a714 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 7f699bd14913 ("iio: frequency: adf4371: Add support for ADF4371 PLL")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-68-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/frequency/adf4371.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/frequency/adf4371.c b/drivers/iio/frequency/adf4371.c
+index ecd5e18995ad..135c8cedc33d 100644
+--- a/drivers/iio/frequency/adf4371.c
++++ b/drivers/iio/frequency/adf4371.c
+@@ -175,7 +175,7 @@ struct adf4371_state {
+ unsigned int mod2;
+ unsigned int rf_div_sel;
+ unsigned int ref_div_factor;
+- u8 buf[10] ____cacheline_aligned;
++ u8 buf[10] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static unsigned long long adf4371_pll_fract_n_get_rate(struct adf4371_state *st,
+--
+2.35.1
+
--- /dev/null
+From 85f01d9c39411d4a241e9e4637e64b4813de11d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:48 +0100
+Subject: iio: frequency: admv1013: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit b3f3f8d264b9be0cb3e50e89e3f8789a948a43bb ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: da35a7b526d9 ("iio: frequency: admv1013: add support for ADMV1013")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-69-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/frequency/admv1013.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/frequency/admv1013.c b/drivers/iio/frequency/admv1013.c
+index b0e1f6571afb..ed8167271358 100644
+--- a/drivers/iio/frequency/admv1013.c
++++ b/drivers/iio/frequency/admv1013.c
+@@ -100,7 +100,7 @@ struct admv1013_state {
+ unsigned int input_mode;
+ unsigned int quad_se_mode;
+ bool det_en;
+- u8 data[3] ____cacheline_aligned;
++ u8 data[3] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int __admv1013_spi_read(struct admv1013_state *st, unsigned int reg,
+--
+2.35.1
+
--- /dev/null
+From 8c18bf035088c48813ecc5988ee8d52ff04fff1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:49 +0100
+Subject: iio: frequency: admv1014: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit a3e38a557a54df0edea791d7eb623515bb86e39a ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: f4eb9ac7842f ("iio: frequency: admv1014: add support for ADMV1014")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-70-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/frequency/admv1014.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/frequency/admv1014.c b/drivers/iio/frequency/admv1014.c
+index a7994f8e6b9b..d1ccaa7ed5fe 100644
+--- a/drivers/iio/frequency/admv1014.c
++++ b/drivers/iio/frequency/admv1014.c
+@@ -127,7 +127,7 @@ struct admv1014_state {
+ unsigned int quad_se_mode;
+ unsigned int p1db_comp;
+ bool det_en;
+- u8 data[3] ____cacheline_aligned;
++ u8 data[3] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static const int mixer_vgate_table[] = {106, 107, 108, 110, 111, 112, 113, 114,
+--
+2.35.1
+
--- /dev/null
+From c5c9bfcb35d20da62ab356aac7231d09aea2859c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:50 +0100
+Subject: iio: frequency: admv4420: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit f890aaac771bd015c348eddb967b4027e88344c0 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: b59c04155901 ("iio: frequency: admv4420.c: Add support for ADMV4420")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-71-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/frequency/admv4420.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/frequency/admv4420.c b/drivers/iio/frequency/admv4420.c
+index 51134aee8510..863ba8e98c95 100644
+--- a/drivers/iio/frequency/admv4420.c
++++ b/drivers/iio/frequency/admv4420.c
+@@ -113,7 +113,7 @@ struct admv4420_state {
+ struct admv4420_n_counter n_counter;
+ enum admv4420_mux_sel mux_sel;
+ struct mutex lock;
+- u8 transf_buf[4] ____cacheline_aligned;
++ u8 transf_buf[4] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static const struct regmap_config admv4420_regmap_config = {
+--
+2.35.1
+
--- /dev/null
+From a78a047014d0465819837955c31859c13df365c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:51 +0100
+Subject: iio: frequency: adrf6780: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 9a5b11884cb72780cb824cac8aab47094654a84f ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 63aaf6d06d87 ("iio: frequency: adrf6780: add support for ADRF6780")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-72-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/frequency/adrf6780.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/frequency/adrf6780.c b/drivers/iio/frequency/adrf6780.c
+index 8255ffd174f6..21878bad0909 100644
+--- a/drivers/iio/frequency/adrf6780.c
++++ b/drivers/iio/frequency/adrf6780.c
+@@ -86,7 +86,7 @@ struct adrf6780_state {
+ bool uc_bias_en;
+ bool lo_sideband;
+ bool vdet_out_en;
+- u8 data[3] ____cacheline_aligned;
++ u8 data[3] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int __adrf6780_spi_read(struct adrf6780_state *st, unsigned int reg,
+--
+2.35.1
+
--- /dev/null
+From 46f094f3ce801f0d05ab0b0f7cfc5e39b45402bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:52 +0100
+Subject: iio: gyro: adis16080: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit ae6eeb534924ecc2afd5a394964fd6de0ca54d39 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes tag is inaccurate but unlikely anyone will backport this
+beyond that point so I haven't chased the history futher than 2013.
+
+Fixes: 3c80372dae17 ("staging:iio:adis16080: be16 cleanups")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-73-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/gyro/adis16080.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/gyro/adis16080.c b/drivers/iio/gyro/adis16080.c
+index acef59d822b1..14b3abf6dce9 100644
+--- a/drivers/iio/gyro/adis16080.c
++++ b/drivers/iio/gyro/adis16080.c
+@@ -45,7 +45,7 @@ struct adis16080_state {
+ const struct adis16080_chip_info *info;
+ struct mutex lock;
+
+- __be16 buf ____cacheline_aligned;
++ __be16 buf __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int adis16080_read_sample(struct iio_dev *indio_dev,
+--
+2.35.1
+
--- /dev/null
+From 9e9c04a7f7aab20df756d69885a18576fecca648 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:53 +0100
+Subject: iio: gyro: adis16130: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit ff3211b2ba9afac80ceb795d148831dd879b30b7 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 8e67875141b2 ("staging:iio:gyro: adis16130 cleanup, move to abi and bug fixes.")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-74-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/gyro/adis16130.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/gyro/adis16130.c b/drivers/iio/gyro/adis16130.c
+index b9c952e65b55..33cde9e6fca5 100644
+--- a/drivers/iio/gyro/adis16130.c
++++ b/drivers/iio/gyro/adis16130.c
+@@ -41,7 +41,7 @@
+ struct adis16130_state {
+ struct spi_device *us;
+ struct mutex buf_lock;
+- u8 buf[4] ____cacheline_aligned;
++ u8 buf[4] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val)
+--
+2.35.1
+
--- /dev/null
+From af78040ecb48ba1d405a133593ab90b1d73d5198 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:54 +0100
+Subject: iio: gyro: adxrs450: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 966d2f4ee7f6e189df47abf67223266ad31e201f ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes tag is inaccurate but unlikely anyone will be interested in
+backporting beyond that point.
+
+Fixes: 53ac8500ba9b ("staging:iio:adxrs450: Move header file contents to main file")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-75-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/gyro/adxrs450.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/gyro/adxrs450.c b/drivers/iio/gyro/adxrs450.c
+index 04f350025215..f84438e0c42c 100644
+--- a/drivers/iio/gyro/adxrs450.c
++++ b/drivers/iio/gyro/adxrs450.c
+@@ -73,7 +73,7 @@ enum {
+ struct adxrs450_state {
+ struct spi_device *us;
+ struct mutex buf_lock;
+- __be32 tx ____cacheline_aligned;
++ __be32 tx __aligned(IIO_DMA_MINALIGN);
+ __be32 rx;
+
+ };
+--
+2.35.1
+
--- /dev/null
+From 0e433c42bfee7423e8c49a991d8197dacc9c5b63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:55 +0100
+Subject: iio: gyro: fxas210002c: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 3aafe923987cb4a15e16f03c6185ed4b6a78ca00 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Updated the comment to 'may' require.
+
+Fixes: a0701b6263ae ("iio: gyro: add core driver for fxas21002c")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Rui Miguel Silva <rui.silva@linaro.org>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-76-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/gyro/fxas21002c_core.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/gyro/fxas21002c_core.c b/drivers/iio/gyro/fxas21002c_core.c
+index 410e5e9f2672..7a459a823f6e 100644
+--- a/drivers/iio/gyro/fxas21002c_core.c
++++ b/drivers/iio/gyro/fxas21002c_core.c
+@@ -150,10 +150,10 @@ struct fxas21002c_data {
+ struct regulator *vddio;
+
+ /*
+- * DMA (thus cache coherency maintenance) requires the
+- * transfer buffers to live in their own cache lines.
++ * DMA (thus cache coherency maintenance) may require the
++ * transfer buffers live in their own cache lines.
+ */
+- s16 buffer[8] ____cacheline_aligned;
++ s16 buffer[8] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ enum fxas21002c_channel_index {
+--
+2.35.1
+
--- /dev/null
+From 89d3234429fa09f221bc3dc91e2d83c3c7e4e3d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:56 +0100
+Subject: iio: imu: fxos8700: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit c9a8417a13ed9c81383662fca8a4b89f84d31e78 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 84e5ddd5c46e ("iio: imu: Add support for the FXOS8700 IMU")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Robert Jones <rjones@gateworks.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-77-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/fxos8700_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/imu/fxos8700_core.c b/drivers/iio/imu/fxos8700_core.c
+index ab288186f36e..423cfe526f2a 100644
+--- a/drivers/iio/imu/fxos8700_core.c
++++ b/drivers/iio/imu/fxos8700_core.c
+@@ -167,7 +167,7 @@
+ struct fxos8700_data {
+ struct regmap *regmap;
+ struct iio_trigger *trig;
+- __be16 buf[FXOS8700_DATA_BUF_SIZE] ____cacheline_aligned;
++ __be16 buf[FXOS8700_DATA_BUF_SIZE] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ /* Regmap info */
+--
+2.35.1
+
--- /dev/null
+From 34566470404f56459dff79106a7774caee1ca63b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:58 +0100
+Subject: iio: imu: inv_icm42600: Fix alignment for DMA safety in buffer code.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit b0aa05065a0c1d1bffa10923dbc36f7193babbb7 ]
+
+Second fix for this driver due to different introducing patches.
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 7f85e42a6c54 ("iio: imu: inv_icm42600: add buffer support in iio devices")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Jean-Baptiste Maneyrol <jmaneyrol@invensense.com>
+Acked-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-79-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h
+index de2a3949dcc7..8b85ee333bf8 100644
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h
+@@ -39,7 +39,7 @@ struct inv_icm42600_fifo {
+ size_t accel;
+ size_t total;
+ } nb;
+- uint8_t data[2080] ____cacheline_aligned;
++ uint8_t data[2080] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ /* FIFO data packet */
+--
+2.35.1
+
--- /dev/null
+From 95163778feaea84cef0b5ca5ca96610ed1777875 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:57 +0100
+Subject: iio: imu: inv_icm42600: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 848847702bd10bf0bf547e38adc44c14e9742784 ]
+
+Partial fix for this driver as a second instance was introduced in
+a later patch.
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: a095fadb443b ("iio: imu: inv_icm42600: add gyroscope IIO device")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-78-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/inv_icm42600/inv_icm42600.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600.h b/drivers/iio/imu/inv_icm42600/inv_icm42600.h
+index 995a9dc06521..3d91469beccb 100644
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600.h
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600.h
+@@ -141,7 +141,7 @@ struct inv_icm42600_state {
+ struct inv_icm42600_suspended suspended;
+ struct iio_dev *indio_gyro;
+ struct iio_dev *indio_accel;
+- uint8_t buffer[2] ____cacheline_aligned;
++ uint8_t buffer[2] __aligned(IIO_DMA_MINALIGN);
+ struct inv_icm42600_fifo fifo;
+ struct {
+ int64_t gyro;
+--
+2.35.1
+
--- /dev/null
+From a6b9dcbc9c3712d3d78b16740f755c604b9cfe4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:56:59 +0100
+Subject: iio: imu: mpu6050: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 54e03562bb960e78af050d2e550c28d77642ee44 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 6b0cc5dce072 ("iio:imu:inv_mpu6050 Fix dma and ts alignment and data leak issues.")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-80-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+index c6aa36ee966a..32b58b797d57 100644
+--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+@@ -203,7 +203,7 @@ struct inv_mpu6050_state {
+ s32 magn_raw_to_gauss[3];
+ struct iio_mount_matrix magn_orient;
+ unsigned int suspended_sensors;
+- u8 data[INV_MPU6050_OUTPUT_DATA_SIZE] ____cacheline_aligned;
++ u8 data[INV_MPU6050_OUTPUT_DATA_SIZE] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ /*register and associated bit definition*/
+--
+2.35.1
+
--- /dev/null
+From d9adadfc56c2b2dc5768f3d3fabb524a55d60799 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:57:00 +0100
+Subject: iio: potentiometer: ad5110: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit b5841c38cb2f7e54b0787b3e0326a6b21b89ea3e ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: d03a74bfacce ("iio: potentiometer: Add driver support for AD5110")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Mugilraj Dhavachelvan <dmugil2000@gmail.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-81-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/potentiometer/ad5110.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/potentiometer/ad5110.c b/drivers/iio/potentiometer/ad5110.c
+index d4eeedae56e5..8fbcce482989 100644
+--- a/drivers/iio/potentiometer/ad5110.c
++++ b/drivers/iio/potentiometer/ad5110.c
+@@ -63,10 +63,10 @@ struct ad5110_data {
+ struct mutex lock;
+ const struct ad5110_cfg *cfg;
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ */
+- u8 buf[2] ____cacheline_aligned;
++ u8 buf[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static const struct iio_chan_spec ad5110_channels[] = {
+--
+2.35.1
+
--- /dev/null
+From 40a3869c91a36100f73d99f3636d63aadea4b736 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:57:01 +0100
+Subject: iio: potentiometer: ad5272: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit da803652534271dbb4af0802bd678c759e27e6de ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 79e8a32d2aa9 ("iio: ad5272: Add support for Analog Devices digital potentiometers")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Phil Reid <preid@electromag.com.au>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-82-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/potentiometer/ad5272.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/potentiometer/ad5272.c b/drivers/iio/potentiometer/ad5272.c
+index d8cbd170262f..ed5fc0b50fe9 100644
+--- a/drivers/iio/potentiometer/ad5272.c
++++ b/drivers/iio/potentiometer/ad5272.c
+@@ -50,7 +50,7 @@ struct ad5272_data {
+ struct i2c_client *client;
+ struct mutex lock;
+ const struct ad5272_cfg *cfg;
+- u8 buf[2] ____cacheline_aligned;
++ u8 buf[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static const struct iio_chan_spec ad5272_channel = {
+--
+2.35.1
+
--- /dev/null
+From 99581b22e68e918c2846a4610280c89610b02079 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:57:02 +0100
+Subject: iio: potentiometer: max5481: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit ec1ac1c0e7a14657d729159ccfbea72f434bdaf1 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: df1fd2de118e ("iio: max5481: Add support for Maxim digital potentiometers")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-83-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/potentiometer/max5481.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/potentiometer/max5481.c b/drivers/iio/potentiometer/max5481.c
+index 098d144a8fdd..b40e5ac218d7 100644
+--- a/drivers/iio/potentiometer/max5481.c
++++ b/drivers/iio/potentiometer/max5481.c
+@@ -44,7 +44,7 @@ static const struct max5481_cfg max5481_cfg[] = {
+ struct max5481_data {
+ struct spi_device *spi;
+ const struct max5481_cfg *cfg;
+- u8 msg[3] ____cacheline_aligned;
++ u8 msg[3] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ #define MAX5481_CHANNEL { \
+--
+2.35.1
+
--- /dev/null
+From e71bc2b991c117def1a64223d90ad7ef5b85fcb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:57:03 +0100
+Subject: iio: potentiometer: mcp41010: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit c5f78f4d2168ba21324095b0d46d4353c2eace4d ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 092cb71a604e ("iio: potentiometer: Add driver for Microchip MCP41xxx/42xxx")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-84-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/potentiometer/mcp41010.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/potentiometer/mcp41010.c b/drivers/iio/potentiometer/mcp41010.c
+index 30a4594d4e11..2b73c7540209 100644
+--- a/drivers/iio/potentiometer/mcp41010.c
++++ b/drivers/iio/potentiometer/mcp41010.c
+@@ -60,7 +60,7 @@ struct mcp41010_data {
+ const struct mcp41010_cfg *cfg;
+ struct mutex lock; /* Protect write sequences */
+ unsigned int value[MCP41010_MAX_WIPERS]; /* Cache wiper values */
+- u8 buf[2] ____cacheline_aligned;
++ u8 buf[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ #define MCP41010_CHANNEL(ch) { \
+--
+2.35.1
+
--- /dev/null
+From 3c6429b1e854b98e0f53d26988205082eb3fcd77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:57:04 +0100
+Subject: iio: potentiometer: mcp4131: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 4842e5de6f39ebf2c0f6da9e6a0cb751c7108507 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 22d199a53910 ("iio: potentiometer: add driver for Microchip MCP413X/414X/415X/416X/423X/424X/425X/426X")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-85-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/potentiometer/mcp4131.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/potentiometer/mcp4131.c b/drivers/iio/potentiometer/mcp4131.c
+index 7c8c18ab8764..7890c0993ec4 100644
+--- a/drivers/iio/potentiometer/mcp4131.c
++++ b/drivers/iio/potentiometer/mcp4131.c
+@@ -129,7 +129,7 @@ struct mcp4131_data {
+ struct spi_device *spi;
+ const struct mcp4131_cfg *cfg;
+ struct mutex lock;
+- u8 buf[2] ____cacheline_aligned;
++ u8 buf[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ #define MCP4131_CHANNEL(ch) { \
+--
+2.35.1
+
--- /dev/null
+From 598f808d7bf606cef67b4b57fc148947b8d64645 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:57:06 +0100
+Subject: iio: proximity: as3935: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 2386c0f8c5b740873a4b9126c3706601b127fe22 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: 24ddb0e4bba4 ("iio: Add AS3935 lightning sensor support")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Matt Ranostay <mranostay@gmail.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-87-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/proximity/as3935.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c
+index 67891ce2bd09..ebc95cf8f5f4 100644
+--- a/drivers/iio/proximity/as3935.c
++++ b/drivers/iio/proximity/as3935.c
+@@ -65,7 +65,7 @@ struct as3935_state {
+ u8 chan;
+ s64 timestamp __aligned(8);
+ } scan;
+- u8 buf[2] ____cacheline_aligned;
++ u8 buf[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static const struct iio_chan_spec as3935_channels[] = {
+--
+2.35.1
+
--- /dev/null
+From c4f517edfa9bcd5efd06bf6c7c61de659633b280 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:57:08 +0100
+Subject: iio: resolver: ad2s1200: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 37882314d3bdc2ae775ebb9fa8ed7a94cd1aad61 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes tag is probably not where the issue was first introduced, but
+is likely to be as far as anyone considers backporting this fix.
+
+Fixes: 0bd3d338f61b ("staging: iio: ad2s1200: Improve readability with be16_to_cpup")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-89-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/resolver/ad2s1200.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/resolver/ad2s1200.c b/drivers/iio/resolver/ad2s1200.c
+index 9746bd935628..9d95241bdf8f 100644
+--- a/drivers/iio/resolver/ad2s1200.c
++++ b/drivers/iio/resolver/ad2s1200.c
+@@ -41,7 +41,7 @@ struct ad2s1200_state {
+ struct spi_device *sdev;
+ struct gpio_desc *sample;
+ struct gpio_desc *rdvel;
+- __be16 rx ____cacheline_aligned;
++ __be16 rx __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int ad2s1200_read_raw(struct iio_dev *indio_dev,
+--
+2.35.1
+
--- /dev/null
+From 7ce9e452640ba6e5f503a0398223f111da864f50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:57:09 +0100
+Subject: iio: resolver: ad2s90: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit faa05ecb1349070d874810e161b653c2220e0006 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes tag is probably not where the issue was first introduced, but
+is likely to be far beyond the point where anyone considers
+backporting this fix.
+
+Fixes: 58f08b0af857 ("staging:iio:resolver:ad2s90 general cleanup")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-90-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/resolver/ad2s90.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/resolver/ad2s90.c b/drivers/iio/resolver/ad2s90.c
+index d6a91f137e13..be6836e55376 100644
+--- a/drivers/iio/resolver/ad2s90.c
++++ b/drivers/iio/resolver/ad2s90.c
+@@ -24,7 +24,7 @@
+ struct ad2s90_state {
+ struct mutex lock; /* lock to protect rx buffer */
+ struct spi_device *sdev;
+- u8 rx[2] ____cacheline_aligned;
++ u8 rx[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int ad2s90_read_raw(struct iio_dev *indio_dev,
+--
+2.35.1
+
--- /dev/null
+From 050e6f98fbddf3538ad5cc901ad6e67792b29006 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Apr 2022 15:01:36 -0700
+Subject: iio: sx9324: Fix register field spelling
+
+From: Gwendal Grignou <gwendal@chromium.org>
+
+[ Upstream commit 0b24034c7ffa20bcfb4fdfece1df770ec5b0a634 ]
+
+Field for PROX_CTRL4 should contain PROX_CTRL4.
+
+Fixes: 4c18a890dff8d ("iio:proximity:sx9324: Add SX9324 support")
+Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Link: https://lore.kernel.org/r/20220429220144.1476049-3-gwendal@chromium.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/proximity/sx9324.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/proximity/sx9324.c b/drivers/iio/proximity/sx9324.c
+index 63fbcaa4cac8..a30ac8007a3d 100644
+--- a/drivers/iio/proximity/sx9324.c
++++ b/drivers/iio/proximity/sx9324.c
+@@ -93,7 +93,7 @@
+ #define SX9324_REG_PROX_CTRL4_AVGNEGFILT_MASK GENMASK(5, 3)
+ #define SX9324_REG_PROX_CTRL4_AVGNEG_FILT_2 0x08
+ #define SX9324_REG_PROX_CTRL4_AVGPOSFILT_MASK GENMASK(2, 0)
+-#define SX9324_REG_PROX_CTRL3_AVGPOS_FILT_256 0x04
++#define SX9324_REG_PROX_CTRL4_AVGPOS_FILT_256 0x04
+ #define SX9324_REG_PROX_CTRL5 0x35
+ #define SX9324_REG_PROX_CTRL5_HYST_MASK GENMASK(5, 4)
+ #define SX9324_REG_PROX_CTRL5_CLOSE_DEBOUNCE_MASK GENMASK(3, 2)
+@@ -810,7 +810,7 @@ static const struct sx_common_reg_default sx9324_default_regs[] = {
+ { SX9324_REG_PROX_CTRL3, SX9324_REG_PROX_CTRL3_AVGDEB_2SAMPLES |
+ SX9324_REG_PROX_CTRL3_AVGPOS_THRESH_16K },
+ { SX9324_REG_PROX_CTRL4, SX9324_REG_PROX_CTRL4_AVGNEG_FILT_2 |
+- SX9324_REG_PROX_CTRL3_AVGPOS_FILT_256 },
++ SX9324_REG_PROX_CTRL4_AVGPOS_FILT_256 },
+ { SX9324_REG_PROX_CTRL5, 0x00 },
+ { SX9324_REG_PROX_CTRL6, SX9324_REG_PROX_CTRL6_PROXTHRESH_32 },
+ { SX9324_REG_PROX_CTRL7, SX9324_REG_PROX_CTRL6_PROXTHRESH_32 },
+--
+2.35.1
+
--- /dev/null
+From d3f6b6b309ea76cffb4fe05de590bf46c53e59ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:57:10 +0100
+Subject: iio: temp: ltc2983: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 732f2cb2fbb51bd5bc03a114bd102ab3b2f537fe ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition.
+
+Fixes: f110f3188e56 ("iio: temperature: Add support for LTC2983")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-91-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/temperature/ltc2983.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
+index 301c3f13fb26..1b8252d86889 100644
+--- a/drivers/iio/temperature/ltc2983.c
++++ b/drivers/iio/temperature/ltc2983.c
+@@ -200,11 +200,11 @@ struct ltc2983_data {
+ u8 num_channels;
+ u8 iio_channels;
+ /*
+- * DMA (thus cache coherency maintenance) requires the
++ * DMA (thus cache coherency maintenance) may require the
+ * transfer buffers to live in their own cache lines.
+ * Holds the converted temperature
+ */
+- __be32 temp ____cacheline_aligned;
++ __be32 temp __aligned(IIO_DMA_MINALIGN);
+ };
+
+ struct ltc2983_sensor {
+--
+2.35.1
+
--- /dev/null
+From b4bbcc567c074a6fe57796820bcdfa485d7733e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:57:11 +0100
+Subject: iio: temp: max31865: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit ecdef5b8317cdf18acb46223e087f04a226fa619 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition
+
+Fixes: e112dc4e18ea ("iio: temperature: Add MAX31865 RTD Support")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Navin Sankar Velliangiri <navin@linumiz.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-92-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/temperature/max31865.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/temperature/max31865.c b/drivers/iio/temperature/max31865.c
+index 86c3f3509a26..f0079e51d8d2 100644
+--- a/drivers/iio/temperature/max31865.c
++++ b/drivers/iio/temperature/max31865.c
+@@ -53,7 +53,7 @@ struct max31865_data {
+ struct mutex lock;
+ bool filter_50hz;
+ bool three_wire;
+- u8 buf[2] ____cacheline_aligned;
++ u8 buf[2] __aligned(IIO_DMA_MINALIGN);
+ };
+
+ static int max31865_read(struct max31865_data *data, u8 reg,
+--
+2.35.1
+
--- /dev/null
+From 85f63b6dcc16c3d502a045f085314f1827b7d8c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 May 2022 18:57:12 +0100
+Subject: iio: temp: maxim_thermocouple: Fix alignment for DMA safety
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 10897f34309b3c7bc14698407436c82d11c07f47 ]
+
+____cacheline_aligned is an insufficient guarantee for non-coherent DMA
+on platforms with 128 byte cachelines above L1. Switch to the updated
+IIO_DMA_MINALIGN definition
+
+Fixes: 1f25ca11d84a ("iio: temperature: add support for Maxim thermocouple chips")
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Matt Ranostay <mranostay@gmail.com>
+Acked-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20220508175712.647246-93-jic23@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/temperature/maxim_thermocouple.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iio/temperature/maxim_thermocouple.c b/drivers/iio/temperature/maxim_thermocouple.c
+index 98c41cddc6f0..c28a7a6dea5f 100644
+--- a/drivers/iio/temperature/maxim_thermocouple.c
++++ b/drivers/iio/temperature/maxim_thermocouple.c
+@@ -122,7 +122,7 @@ struct maxim_thermocouple_data {
+ struct spi_device *spi;
+ const struct maxim_thermocouple_chip *chip;
+
+- u8 buffer[16] ____cacheline_aligned;
++ u8 buffer[16] __aligned(IIO_DMA_MINALIGN);
+ char tc_type;
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 1d178e25eb5c5c31566938fb32874ca6a4a0a793 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 May 2022 09:56:01 -0700
+Subject: inet: add READ_ONCE(sk->sk_bound_dev_if) in INET_MATCH()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 4915d50e300e96929d2462041d6f6c6f061167fd ]
+
+INET_MATCH() runs without holding a lock on the socket.
+
+We probably need to annotate most reads.
+
+This patch makes INET_MATCH() an inline function
+to ease our changes.
+
+v2:
+
+We remove the 32bit version of it, as modern compilers
+should generate the same code really, no need to
+try to be smarter.
+
+Also make 'struct net *net' the first argument.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet_hashtables.h | 35 ++++++++++++++++-------------------
+ include/net/sock.h | 3 ---
+ net/ipv4/inet_hashtables.c | 15 +++++----------
+ net/ipv4/udp.c | 3 +--
+ 4 files changed, 22 insertions(+), 34 deletions(-)
+
+diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
+index 749bb1e46087..825ad1d06d05 100644
+--- a/include/net/inet_hashtables.h
++++ b/include/net/inet_hashtables.h
+@@ -295,7 +295,6 @@ static inline struct sock *inet_lookup_listener(struct net *net,
+ ((__force __portpair)(((__u32)(__dport) << 16) | (__force __u32)(__be16)(__sport)))
+ #endif
+
+-#if (BITS_PER_LONG == 64)
+ #ifdef __BIG_ENDIAN
+ #define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
+ const __addrpair __name = (__force __addrpair) ( \
+@@ -307,24 +306,22 @@ static inline struct sock *inet_lookup_listener(struct net *net,
+ (((__force __u64)(__be32)(__daddr)) << 32) | \
+ ((__force __u64)(__be32)(__saddr)))
+ #endif /* __BIG_ENDIAN */
+-#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \
+- (((__sk)->sk_portpair == (__ports)) && \
+- ((__sk)->sk_addrpair == (__cookie)) && \
+- (((__sk)->sk_bound_dev_if == (__dif)) || \
+- ((__sk)->sk_bound_dev_if == (__sdif))) && \
+- net_eq(sock_net(__sk), (__net)))
+-#else /* 32-bit arch */
+-#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
+- const int __name __deprecated __attribute__((unused))
+-
+-#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif, __sdif) \
+- (((__sk)->sk_portpair == (__ports)) && \
+- ((__sk)->sk_daddr == (__saddr)) && \
+- ((__sk)->sk_rcv_saddr == (__daddr)) && \
+- (((__sk)->sk_bound_dev_if == (__dif)) || \
+- ((__sk)->sk_bound_dev_if == (__sdif))) && \
+- net_eq(sock_net(__sk), (__net)))
+-#endif /* 64-bit arch */
++
++static inline bool INET_MATCH(struct net *net, const struct sock *sk,
++ const __addrpair cookie, const __portpair ports,
++ int dif, int sdif)
++{
++ int bound_dev_if;
++
++ if (!net_eq(sock_net(sk), net) ||
++ sk->sk_portpair != ports ||
++ sk->sk_addrpair != cookie)
++ return false;
++
++ /* Paired with WRITE_ONCE() from sock_bindtoindex_locked() */
++ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
++ return bound_dev_if == dif || bound_dev_if == sdif;
++}
+
+ /* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so we need
+ * not check it for lookups anymore, thanks Alexey. -DaveM
+diff --git a/include/net/sock.h b/include/net/sock.h
+index aab25d1806a9..810cb96b7f39 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -161,9 +161,6 @@ typedef __u64 __bitwise __addrpair;
+ * for struct sock and struct inet_timewait_sock.
+ */
+ struct sock_common {
+- /* skc_daddr and skc_rcv_saddr must be grouped on a 8 bytes aligned
+- * address on 64bit arches : cf INET_MATCH()
+- */
+ union {
+ __addrpair skc_addrpair;
+ struct {
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index 55654e335d43..8dbe0782eafe 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -410,13 +410,11 @@ struct sock *__inet_lookup_established(struct net *net,
+ sk_nulls_for_each_rcu(sk, node, &head->chain) {
+ if (sk->sk_hash != hash)
+ continue;
+- if (likely(INET_MATCH(sk, net, acookie,
+- saddr, daddr, ports, dif, sdif))) {
++ if (likely(INET_MATCH(net, sk, acookie, ports, dif, sdif))) {
+ if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
+ goto out;
+- if (unlikely(!INET_MATCH(sk, net, acookie,
+- saddr, daddr, ports,
+- dif, sdif))) {
++ if (unlikely(!INET_MATCH(net, sk, acookie,
++ ports, dif, sdif))) {
+ sock_gen_put(sk);
+ goto begin;
+ }
+@@ -465,8 +463,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
+ if (sk2->sk_hash != hash)
+ continue;
+
+- if (likely(INET_MATCH(sk2, net, acookie,
+- saddr, daddr, ports, dif, sdif))) {
++ if (likely(INET_MATCH(net, sk2, acookie, ports, dif, sdif))) {
+ if (sk2->sk_state == TCP_TIME_WAIT) {
+ tw = inet_twsk(sk2);
+ if (twsk_unique(sk, sk2, twp))
+@@ -532,9 +529,7 @@ static bool inet_ehash_lookup_by_sk(struct sock *sk,
+ if (esk->sk_hash != sk->sk_hash)
+ continue;
+ if (sk->sk_family == AF_INET) {
+- if (unlikely(INET_MATCH(esk, net, acookie,
+- sk->sk_daddr,
+- sk->sk_rcv_saddr,
++ if (unlikely(INET_MATCH(net, esk, acookie,
+ ports, dif, sdif))) {
+ return true;
+ }
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 6b4d8361560f..201e2533acb2 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -2564,8 +2564,7 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net,
+ struct sock *sk;
+
+ udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
+- if (INET_MATCH(sk, net, acookie, rmt_addr,
+- loc_addr, ports, dif, sdif))
++ if (INET_MATCH(net, sk, acookie, ports, dif, sdif))
+ return sk;
+ /* Only check first socket in chain */
+ break;
+--
+2.35.1
+
--- /dev/null
+From 09cdae194c4601e52b1e17e4b5f65f0bd4159197 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 11:26:32 +0300
+Subject: intel_th: Fix a resource leak in an error handling path
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 086c28ab7c5699256aced0049aae9c42f1410313 ]
+
+If an error occurs after calling 'pci_alloc_irq_vectors()',
+'pci_free_irq_vectors()' must be called as already done in the remove
+function.
+
+Fixes: 7b7036d47c35 ("intel_th: pci: Use MSI interrupt signalling")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Link: https://lore.kernel.org/r/20220705082637.59979-2-alexander.shishkin@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/intel_th/pci.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c
+index 7da4f298ed01..fcd0aca75007 100644
+--- a/drivers/hwtracing/intel_th/pci.c
++++ b/drivers/hwtracing/intel_th/pci.c
+@@ -100,8 +100,10 @@ static int intel_th_pci_probe(struct pci_dev *pdev,
+ }
+
+ th = intel_th_alloc(&pdev->dev, drvdata, resource, r);
+- if (IS_ERR(th))
+- return PTR_ERR(th);
++ if (IS_ERR(th)) {
++ err = PTR_ERR(th);
++ goto err_free_irq;
++ }
+
+ th->activate = intel_th_pci_activate;
+ th->deactivate = intel_th_pci_deactivate;
+@@ -109,6 +111,10 @@ static int intel_th_pci_probe(struct pci_dev *pdev,
+ pci_set_master(pdev);
+
+ return 0;
++
++err_free_irq:
++ pci_free_irq_vectors(pdev);
++ return err;
+ }
+
+ static void intel_th_pci_remove(struct pci_dev *pdev)
+--
+2.35.1
+
--- /dev/null
+From 546e9652b86d3a428111ce6b14798ed5f1441a31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 11:26:34 +0300
+Subject: intel_th: msu: Fix vmalloced buffers
+
+From: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+
+[ Upstream commit ac12ad3ccf6d386e64a9d6a890595a2509d24edd ]
+
+After commit f5ff79fddf0e ("dma-mapping: remove CONFIG_DMA_REMAP") there's
+a chance of DMA buffer getting allocated via vmalloc(), which messes up
+the mmapping code:
+
+> RIP: msc_mmap_fault [intel_th_msu]
+> Call Trace:
+> <TASK>
+> __do_fault
+> do_fault
+...
+
+Fix this by accounting for vmalloc possibility.
+
+Fixes: ba39bd830605 ("intel_th: msu: Switch over to scatterlist")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Link: https://lore.kernel.org/r/20220705082637.59979-4-alexander.shishkin@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/intel_th/msu.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c
+index 70a07b4e9967..6c8215a47a60 100644
+--- a/drivers/hwtracing/intel_th/msu.c
++++ b/drivers/hwtracing/intel_th/msu.c
+@@ -1067,6 +1067,16 @@ msc_buffer_set_uc(struct msc *msc) {}
+ static inline void msc_buffer_set_wb(struct msc *msc) {}
+ #endif /* CONFIG_X86 */
+
++static struct page *msc_sg_page(struct scatterlist *sg)
++{
++ void *addr = sg_virt(sg);
++
++ if (is_vmalloc_addr(addr))
++ return vmalloc_to_page(addr);
++
++ return sg_page(sg);
++}
++
+ /**
+ * msc_buffer_win_alloc() - alloc a window for a multiblock mode
+ * @msc: MSC device
+@@ -1137,7 +1147,7 @@ static void __msc_buffer_win_free(struct msc *msc, struct msc_window *win)
+ int i;
+
+ for_each_sg(win->sgt->sgl, sg, win->nr_segs, i) {
+- struct page *page = sg_page(sg);
++ struct page *page = msc_sg_page(sg);
+
+ page->mapping = NULL;
+ dma_free_coherent(msc_dev(win->msc)->parent->parent, PAGE_SIZE,
+@@ -1401,7 +1411,7 @@ static struct page *msc_buffer_get_page(struct msc *msc, unsigned long pgoff)
+ pgoff -= win->pgoff;
+
+ for_each_sg(win->sgt->sgl, sg, win->nr_segs, blk) {
+- struct page *page = sg_page(sg);
++ struct page *page = msc_sg_page(sg);
+ size_t pgsz = PFN_DOWN(sg->length);
+
+ if (pgoff < pgsz)
+--
+2.35.1
+
--- /dev/null
+From 081fc059f91037fb3e18f1b64ace36ab4e0ee91d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 11:26:33 +0300
+Subject: intel_th: msu-sink: Potential dereference of null pointer
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 82f76a4a720791d889de775b5f7541d601efc8bd ]
+
+The return value of dma_alloc_coherent() needs to be checked.
+To avoid use of null pointer in sg_set_buf() in case of the failure of
+alloc.
+
+Fixes: f220df66f676 ("intel_th: msu-sink: An example msu buffer "sink"")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Link: https://lore.kernel.org/r/20220705082637.59979-3-alexander.shishkin@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/intel_th/msu-sink.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/hwtracing/intel_th/msu-sink.c b/drivers/hwtracing/intel_th/msu-sink.c
+index 2c7f5116be12..891b28ea25fe 100644
+--- a/drivers/hwtracing/intel_th/msu-sink.c
++++ b/drivers/hwtracing/intel_th/msu-sink.c
+@@ -71,6 +71,9 @@ static int msu_sink_alloc_window(void *data, struct sg_table **sgt, size_t size)
+ block = dma_alloc_coherent(priv->dev->parent->parent,
+ PAGE_SIZE, &sg_dma_address(sg_ptr),
+ GFP_KERNEL);
++ if (!block)
++ return -ENOMEM;
++
+ sg_set_buf(sg_ptr, block, PAGE_SIZE);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 5a9d1cf596861fc580849ff14abdbab44fef60f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Jul 2022 17:11:26 +0800
+Subject: interconnect: imx: fix max_node_id
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit bd734481e172b4827af09c9ab06c51d2ab7201e6 ]
+
+max_node_id not equal to the ARRAY_SIZE of node array, need increase 1,
+otherwise xlate will fail for the last entry. And rename max_node_id
+to num_nodes to reflect the reality.
+
+Fixes: f0d8048525d7d ("interconnect: Add imx core driver")
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20220703091132.1412063-5-peng.fan@oss.nxp.com
+Signed-off-by: Georgi Djakov <djakov@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/interconnect/imx/imx.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/interconnect/imx/imx.c b/drivers/interconnect/imx/imx.c
+index 249ca25d1d55..4406ec45fa90 100644
+--- a/drivers/interconnect/imx/imx.c
++++ b/drivers/interconnect/imx/imx.c
+@@ -234,16 +234,16 @@ int imx_icc_register(struct platform_device *pdev,
+ struct device *dev = &pdev->dev;
+ struct icc_onecell_data *data;
+ struct icc_provider *provider;
+- int max_node_id;
++ int num_nodes;
+ int ret;
+
+ /* icc_onecell_data is indexed by node_id, unlike nodes param */
+- max_node_id = get_max_node_id(nodes, nodes_count);
+- data = devm_kzalloc(dev, struct_size(data, nodes, max_node_id),
++ num_nodes = get_max_node_id(nodes, nodes_count) + 1;
++ data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes),
+ GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+- data->num_nodes = max_node_id;
++ data->num_nodes = num_nodes;
+
+ provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL);
+ if (!provider)
+--
+2.35.1
+
--- /dev/null
+From a4e178a6c36b6c951f32ad9f5e3d5b5f4b921e48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 19:45:01 +0200
+Subject: io_uring: Don't require reinitable percpu_ref
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michal Koutný <mkoutny@suse.com>
+
+[ Upstream commit 48904229928d941ce1db181b991948387ab463cd ]
+
+The commit 8bb649ee1da3 ("io_uring: remove ring quiesce for
+io_uring_register") removed the worklow relying on reinit/resurrection
+of the percpu_ref, hence, initialization with that requested is a relic.
+
+This is based on code review, this causes no real bug (and theoretically
+can't). Technically it's a revert of commit 214828962dea ("io_uring:
+initialize percpu refcounters using PERCU_REF_ALLOW_REINIT") but since
+the flag omission is now justified, I'm not making this a revert.
+
+Fixes: 8bb649ee1da3 ("io_uring: remove ring quiesce for io_uring_register")
+Signed-off-by: Michal Koutný <mkoutny@suse.com>
+Acked-by: Roman Gushchin <roman.gushchin@linux.dev>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/io_uring.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index b25e59da129f..2dd6731c1022 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -1576,7 +1576,7 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
+ INIT_LIST_HEAD(&ctx->io_buffers[i]);
+
+ if (percpu_ref_init(&ctx->refs, io_ring_ctx_ref_free,
+- PERCPU_REF_ALLOW_REINIT, GFP_KERNEL))
++ 0, GFP_KERNEL))
+ goto err;
+
+ ctx->flags = p->flags;
+--
+2.35.1
+
--- /dev/null
+From 2a2f05f51f0eb2dd0ef58bc70ae23fc8176bb1a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 May 2022 17:05:03 -0600
+Subject: io_uring: move to separate directory
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ Upstream commit ed29b0b4fd835b058ddd151c49d021e28d631ee6 ]
+
+In preparation for splitting io_uring up a bit, move it into its own
+top level directory. It didn't really belong in fs/ anyway, as it's
+not a file system only API.
+
+This adds io_uring/ and moves the core files in there, and updates the
+MAINTAINERS file for the new location.
+
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ MAINTAINERS | 7 +------
+ Makefile | 1 +
+ fs/Makefile | 2 --
+ io_uring/Makefile | 6 ++++++
+ {fs => io_uring}/io-wq.c | 0
+ {fs => io_uring}/io-wq.h | 0
+ {fs => io_uring}/io_uring.c | 2 +-
+ kernel/sched/core.c | 2 +-
+ 8 files changed, 10 insertions(+), 10 deletions(-)
+ create mode 100644 io_uring/Makefile
+ rename {fs => io_uring}/io-wq.c (100%)
+ rename {fs => io_uring}/io-wq.h (100%)
+ rename {fs => io_uring}/io_uring.c (99%)
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 2b70e2d21405..c7c7a96b62a8 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -7599,9 +7599,6 @@ F: include/linux/fs.h
+ F: include/linux/fs_types.h
+ F: include/uapi/linux/fs.h
+ F: include/uapi/linux/openat2.h
+-X: fs/io-wq.c
+-X: fs/io-wq.h
+-X: fs/io_uring.c
+
+ FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER
+ M: Riku Voipio <riku.voipio@iki.fi>
+@@ -10277,9 +10274,7 @@ L: io-uring@vger.kernel.org
+ S: Maintained
+ T: git git://git.kernel.dk/linux-block
+ T: git git://git.kernel.dk/liburing
+-F: fs/io-wq.c
+-F: fs/io-wq.h
+-F: fs/io_uring.c
++F: io_uring/
+ F: include/linux/io_uring.h
+ F: include/uapi/linux/io_uring.h
+ F: tools/io_uring/
+diff --git a/Makefile b/Makefile
+index 13dd4bd226cb..90e2129a3b80 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1100,6 +1100,7 @@ export MODULES_NSDEPS := $(extmod_prefix)modules.nsdeps
+ ifeq ($(KBUILD_EXTMOD),)
+ core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/
+ core-$(CONFIG_BLOCK) += block/
++core-$(CONFIG_IO_URING) += io_uring/
+
+ vmlinux-dirs := $(patsubst %/,%,$(filter %/, \
+ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
+diff --git a/fs/Makefile b/fs/Makefile
+index 208a74e0b00e..93b80529f8e8 100644
+--- a/fs/Makefile
++++ b/fs/Makefile
+@@ -34,8 +34,6 @@ obj-$(CONFIG_TIMERFD) += timerfd.o
+ obj-$(CONFIG_EVENTFD) += eventfd.o
+ obj-$(CONFIG_USERFAULTFD) += userfaultfd.o
+ obj-$(CONFIG_AIO) += aio.o
+-obj-$(CONFIG_IO_URING) += io_uring.o
+-obj-$(CONFIG_IO_WQ) += io-wq.o
+ obj-$(CONFIG_FS_DAX) += dax.o
+ obj-$(CONFIG_FS_ENCRYPTION) += crypto/
+ obj-$(CONFIG_FS_VERITY) += verity/
+diff --git a/io_uring/Makefile b/io_uring/Makefile
+new file mode 100644
+index 000000000000..3680425df947
+--- /dev/null
++++ b/io_uring/Makefile
+@@ -0,0 +1,6 @@
++# SPDX-License-Identifier: GPL-2.0
++#
++# Makefile for io_uring
++
++obj-$(CONFIG_IO_URING) += io_uring.o
++obj-$(CONFIG_IO_WQ) += io-wq.o
+diff --git a/fs/io-wq.c b/io_uring/io-wq.c
+similarity index 100%
+rename from fs/io-wq.c
+rename to io_uring/io-wq.c
+diff --git a/fs/io-wq.h b/io_uring/io-wq.h
+similarity index 100%
+rename from fs/io-wq.h
+rename to io_uring/io-wq.h
+diff --git a/fs/io_uring.c b/io_uring/io_uring.c
+similarity index 99%
+rename from fs/io_uring.c
+rename to io_uring/io_uring.c
+index 3d97372e811e..b25e59da129f 100644
+--- a/fs/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -86,7 +86,7 @@
+
+ #include <uapi/linux/io_uring.h>
+
+-#include "internal.h"
++#include "../fs/internal.h"
+ #include "io-wq.h"
+
+ #define IORING_MAX_ENTRIES 32768
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 6baf96d2fa39..72b2f277b0dd 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -88,7 +88,7 @@
+ #include "stats.h"
+
+ #include "../workqueue_internal.h"
+-#include "../../fs/io-wq.h"
++#include "../../io_uring/io-wq.h"
+ #include "../smpboot.h"
+
+ /*
+--
+2.35.1
+
--- /dev/null
+From e9c0c6d28d989342de8b9acb1875a9823ecb8d2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 20:49:55 +0800
+Subject: iommu/arm-smmu: qcom_iommu: Add of_node_put() when breaking out of
+ loop
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit a91eb6803c1c715738682fece095145cbd68fe0b ]
+
+In qcom_iommu_has_secure_context(), we should call of_node_put()
+for the reference 'child' when breaking out of for_each_child_of_node()
+which will automatically increase and decrease the refcount.
+
+Fixes: d051f28c8807 ("iommu/qcom: Initialize secure page table")
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220719124955.1242171-1-windhl@126.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/arm/arm-smmu/qcom_iommu.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+index 4c077c38fbd6..c11d2c2cbb62 100644
+--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
++++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+@@ -750,9 +750,12 @@ static bool qcom_iommu_has_secure_context(struct qcom_iommu_dev *qcom_iommu)
+ {
+ struct device_node *child;
+
+- for_each_child_of_node(qcom_iommu->dev->of_node, child)
+- if (of_device_is_compatible(child, "qcom,msm-iommu-v1-sec"))
++ for_each_child_of_node(qcom_iommu->dev->of_node, child) {
++ if (of_device_is_compatible(child, "qcom,msm-iommu-v1-sec")) {
++ of_node_put(child);
+ return true;
++ }
++ }
+
+ return false;
+ }
+--
+2.35.1
+
--- /dev/null
+From 95c7c5d652bf614c4002a671af6a123dd67ff118 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 19:55:46 +0300
+Subject: iommu/exynos: Handle failed IOMMU device registration properly
+
+From: Sam Protsenko <semen.protsenko@linaro.org>
+
+[ Upstream commit fce398d2d02c0a9a2bedf7c7201b123e153e8963 ]
+
+If iommu_device_register() fails in exynos_sysmmu_probe(), the previous
+calls have to be cleaned up. In this case, the iommu_device_sysfs_add()
+should be cleaned up, by calling its remove counterpart call.
+
+Fixes: d2c302b6e8b1 ("iommu/exynos: Make use of iommu_device_register interface")
+Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/20220714165550.8884-3-semen.protsenko@linaro.org
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/exynos-iommu.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 71f2018e23fe..cd4b889d5537 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -630,7 +630,7 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
+
+ ret = iommu_device_register(&data->iommu, &exynos_iommu_ops, dev);
+ if (ret)
+- return ret;
++ goto err_iommu_register;
+
+ platform_set_drvdata(pdev, data);
+
+@@ -657,6 +657,10 @@ static int exynos_sysmmu_probe(struct platform_device *pdev)
+ pm_runtime_enable(dev);
+
+ return 0;
++
++err_iommu_register:
++ iommu_device_sysfs_remove(&data->iommu);
++ return ret;
+ }
+
+ static int __maybe_unused exynos_sysmmu_suspend(struct device *dev)
+--
+2.35.1
+
--- /dev/null
+From 5acea7df54be100f23943221ea2c4dca7797066e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 May 2022 11:55:49 -0700
+Subject: ipv6: add READ_ONCE(sk->sk_bound_dev_if) in INET6_MATCH()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 5d368f03280d3678433a7f119efe15dfbbb87bc8 ]
+
+INET6_MATCH() runs without holding a lock on the socket.
+
+We probably need to annotate most reads.
+
+This patch makes INET6_MATCH() an inline function
+to ease our changes.
+
+v2: inline function only defined if IS_ENABLED(CONFIG_IPV6)
+ Change the name to inet6_match(), this is no longer a macro.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet6_hashtables.h | 28 +++++++++++++++++++---------
+ net/ipv4/inet_hashtables.c | 2 +-
+ net/ipv6/inet6_hashtables.c | 6 +++---
+ net/ipv6/udp.c | 2 +-
+ 4 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
+index 81b965953036..f259e1ae14ba 100644
+--- a/include/net/inet6_hashtables.h
++++ b/include/net/inet6_hashtables.h
+@@ -103,15 +103,25 @@ struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
+ const int dif);
+
+ int inet6_hash(struct sock *sk);
+-#endif /* IS_ENABLED(CONFIG_IPV6) */
+
+-#define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif, __sdif) \
+- (((__sk)->sk_portpair == (__ports)) && \
+- ((__sk)->sk_family == AF_INET6) && \
+- ipv6_addr_equal(&(__sk)->sk_v6_daddr, (__saddr)) && \
+- ipv6_addr_equal(&(__sk)->sk_v6_rcv_saddr, (__daddr)) && \
+- (((__sk)->sk_bound_dev_if == (__dif)) || \
+- ((__sk)->sk_bound_dev_if == (__sdif))) && \
+- net_eq(sock_net(__sk), (__net)))
++static inline bool inet6_match(struct net *net, const struct sock *sk,
++ const struct in6_addr *saddr,
++ const struct in6_addr *daddr,
++ const __portpair ports,
++ const int dif, const int sdif)
++{
++ int bound_dev_if;
++
++ if (!net_eq(sock_net(sk), net) ||
++ sk->sk_family != AF_INET6 ||
++ sk->sk_portpair != ports ||
++ !ipv6_addr_equal(&sk->sk_v6_daddr, saddr) ||
++ !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))
++ return false;
++
++ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
++ return bound_dev_if == dif || bound_dev_if == sdif;
++}
++#endif /* IS_ENABLED(CONFIG_IPV6) */
+
+ #endif /* _INET6_HASHTABLES_H */
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index 8dbe0782eafe..d631198e0938 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -536,7 +536,7 @@ static bool inet_ehash_lookup_by_sk(struct sock *sk,
+ }
+ #if IS_ENABLED(CONFIG_IPV6)
+ else if (sk->sk_family == AF_INET6) {
+- if (unlikely(INET6_MATCH(esk, net,
++ if (unlikely(inet6_match(net, esk,
+ &sk->sk_v6_daddr,
+ &sk->sk_v6_rcv_saddr,
+ ports, dif, sdif))) {
+diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
+index 32ccac10bd62..bb4939e36840 100644
+--- a/net/ipv6/inet6_hashtables.c
++++ b/net/ipv6/inet6_hashtables.c
+@@ -71,12 +71,12 @@ struct sock *__inet6_lookup_established(struct net *net,
+ sk_nulls_for_each_rcu(sk, node, &head->chain) {
+ if (sk->sk_hash != hash)
+ continue;
+- if (!INET6_MATCH(sk, net, saddr, daddr, ports, dif, sdif))
++ if (!inet6_match(net, sk, saddr, daddr, ports, dif, sdif))
+ continue;
+ if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
+ goto out;
+
+- if (unlikely(!INET6_MATCH(sk, net, saddr, daddr, ports, dif, sdif))) {
++ if (unlikely(!inet6_match(net, sk, saddr, daddr, ports, dif, sdif))) {
+ sock_gen_put(sk);
+ goto begin;
+ }
+@@ -269,7 +269,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
+ if (sk2->sk_hash != hash)
+ continue;
+
+- if (likely(INET6_MATCH(sk2, net, saddr, daddr, ports,
++ if (likely(inet6_match(net, sk2, saddr, daddr, ports,
+ dif, sdif))) {
+ if (sk2->sk_state == TCP_TIME_WAIT) {
+ tw = inet_twsk(sk2);
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index aea28bf701be..544842fc831e 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -1044,7 +1044,7 @@ static struct sock *__udp6_lib_demux_lookup(struct net *net,
+
+ udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
+ if (sk->sk_state == TCP_ESTABLISHED &&
+- INET6_MATCH(sk, net, rmt_addr, loc_addr, ports, dif, sdif))
++ inet6_match(net, sk, rmt_addr, loc_addr, ports, dif, sdif))
+ return sk;
+ /* Only check first socket in chain */
+ break;
+--
+2.35.1
+
--- /dev/null
+From c610480f1e75d2b9aeb0194c2ac76bb6d8e37ffe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Jul 2022 18:01:28 +0800
+Subject: irqchip/mips-gic: Check the return value of ioremap() in
+ gic_of_init()
+
+From: William Dean <williamsukatube@163.com>
+
+[ Upstream commit 71349cc85e5930dce78ed87084dee098eba24b59 ]
+
+The function ioremap() in gic_of_init() can fail, so
+its return value should be checked.
+
+Reported-by: Hacash Robot <hacashRobot@santino.com>
+Signed-off-by: William Dean <williamsukatube@163.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220723100128.2964304-1-williamsukatube@163.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-mips-gic.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
+index 8a9efb6ae587..1ba0f1555c80 100644
+--- a/drivers/irqchip/irq-mips-gic.c
++++ b/drivers/irqchip/irq-mips-gic.c
+@@ -783,6 +783,10 @@ static int __init gic_of_init(struct device_node *node,
+ }
+
+ mips_gic_base = ioremap(gic_base, gic_len);
++ if (!mips_gic_base) {
++ pr_err("Failed to ioremap gic_base\n");
++ return -ENOMEM;
++ }
+
+ gicconfig = read_gic_config();
+ gic_shared_intrs = FIELD_GET(GIC_CONFIG_NUMINTERRUPTS, gicconfig);
+--
+2.35.1
+
--- /dev/null
+From bd75a44c05b50e4cdf7db75ce82912d528988483 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 15:00:49 -0500
+Subject: irqchip/mips-gic: Only register IPI domain when SMP is enabled
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit 8190cc572981f2f13b6ffc26c7cfa7899e5d3ccc ]
+
+The MIPS GIC irqchip driver may be selected in a uniprocessor
+configuration, but it unconditionally registers an IPI domain.
+
+Limit the part of the driver dealing with IPIs to only be compiled when
+GENERIC_IRQ_IPI is enabled, which corresponds to an SMP configuration.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220701200056.46555-2-samuel@sholland.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/Kconfig | 3 +-
+ drivers/irqchip/irq-mips-gic.c | 80 +++++++++++++++++++++++-----------
+ 2 files changed, 56 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
+index 15edb9a6fcae..d43d25a411dd 100644
+--- a/drivers/irqchip/Kconfig
++++ b/drivers/irqchip/Kconfig
+@@ -310,7 +310,8 @@ config KEYSTONE_IRQ
+
+ config MIPS_GIC
+ bool
+- select GENERIC_IRQ_IPI
++ select GENERIC_IRQ_IPI if SMP
++ select IRQ_DOMAIN_HIERARCHY
+ select MIPS_CM
+
+ config INGENIC_IRQ
+diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
+index ff89b36267dd..8a9efb6ae587 100644
+--- a/drivers/irqchip/irq-mips-gic.c
++++ b/drivers/irqchip/irq-mips-gic.c
+@@ -52,13 +52,15 @@ static DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks);
+
+ static DEFINE_SPINLOCK(gic_lock);
+ static struct irq_domain *gic_irq_domain;
+-static struct irq_domain *gic_ipi_domain;
+ static int gic_shared_intrs;
+ static unsigned int gic_cpu_pin;
+ static unsigned int timer_cpu_pin;
+ static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller;
++
++#ifdef CONFIG_GENERIC_IRQ_IPI
+ static DECLARE_BITMAP(ipi_resrv, GIC_MAX_INTRS);
+ static DECLARE_BITMAP(ipi_available, GIC_MAX_INTRS);
++#endif /* CONFIG_GENERIC_IRQ_IPI */
+
+ static struct gic_all_vpes_chip_data {
+ u32 map;
+@@ -472,9 +474,11 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
+ u32 map;
+
+ if (hwirq >= GIC_SHARED_HWIRQ_BASE) {
++#ifdef CONFIG_GENERIC_IRQ_IPI
+ /* verify that shared irqs don't conflict with an IPI irq */
+ if (test_bit(GIC_HWIRQ_TO_SHARED(hwirq), ipi_resrv))
+ return -EBUSY;
++#endif /* CONFIG_GENERIC_IRQ_IPI */
+
+ err = irq_domain_set_hwirq_and_chip(d, virq, hwirq,
+ &gic_level_irq_controller,
+@@ -567,6 +571,8 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
+ .map = gic_irq_domain_map,
+ };
+
++#ifdef CONFIG_GENERIC_IRQ_IPI
++
+ static int gic_ipi_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
+ const u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq,
+@@ -670,6 +676,48 @@ static const struct irq_domain_ops gic_ipi_domain_ops = {
+ .match = gic_ipi_domain_match,
+ };
+
++static int gic_register_ipi_domain(struct device_node *node)
++{
++ struct irq_domain *gic_ipi_domain;
++ unsigned int v[2], num_ipis;
++
++ gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain,
++ IRQ_DOMAIN_FLAG_IPI_PER_CPU,
++ GIC_NUM_LOCAL_INTRS + gic_shared_intrs,
++ node, &gic_ipi_domain_ops, NULL);
++ if (!gic_ipi_domain) {
++ pr_err("Failed to add IPI domain");
++ return -ENXIO;
++ }
++
++ irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI);
++
++ if (node &&
++ !of_property_read_u32_array(node, "mti,reserved-ipi-vectors", v, 2)) {
++ bitmap_set(ipi_resrv, v[0], v[1]);
++ } else {
++ /*
++ * Reserve 2 interrupts per possible CPU/VP for use as IPIs,
++ * meeting the requirements of arch/mips SMP.
++ */
++ num_ipis = 2 * num_possible_cpus();
++ bitmap_set(ipi_resrv, gic_shared_intrs - num_ipis, num_ipis);
++ }
++
++ bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS);
++
++ return 0;
++}
++
++#else /* !CONFIG_GENERIC_IRQ_IPI */
++
++static inline int gic_register_ipi_domain(struct device_node *node)
++{
++ return 0;
++}
++
++#endif /* !CONFIG_GENERIC_IRQ_IPI */
++
+ static int gic_cpu_startup(unsigned int cpu)
+ {
+ /* Enable or disable EIC */
+@@ -688,11 +736,12 @@ static int gic_cpu_startup(unsigned int cpu)
+ static int __init gic_of_init(struct device_node *node,
+ struct device_node *parent)
+ {
+- unsigned int cpu_vec, i, gicconfig, v[2], num_ipis;
++ unsigned int cpu_vec, i, gicconfig;
+ unsigned long reserved;
+ phys_addr_t gic_base;
+ struct resource res;
+ size_t gic_len;
++ int ret;
+
+ /* Find the first available CPU vector. */
+ i = 0;
+@@ -780,30 +829,9 @@ static int __init gic_of_init(struct device_node *node,
+ return -ENXIO;
+ }
+
+- gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain,
+- IRQ_DOMAIN_FLAG_IPI_PER_CPU,
+- GIC_NUM_LOCAL_INTRS + gic_shared_intrs,
+- node, &gic_ipi_domain_ops, NULL);
+- if (!gic_ipi_domain) {
+- pr_err("Failed to add IPI domain");
+- return -ENXIO;
+- }
+-
+- irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI);
+-
+- if (node &&
+- !of_property_read_u32_array(node, "mti,reserved-ipi-vectors", v, 2)) {
+- bitmap_set(ipi_resrv, v[0], v[1]);
+- } else {
+- /*
+- * Reserve 2 interrupts per possible CPU/VP for use as IPIs,
+- * meeting the requirements of arch/mips SMP.
+- */
+- num_ipis = 2 * num_possible_cpus();
+- bitmap_set(ipi_resrv, gic_shared_intrs - num_ipis, num_ipis);
+- }
+-
+- bitmap_copy(ipi_available, ipi_resrv, GIC_MAX_INTRS);
++ ret = gic_register_ipi_domain(node);
++ if (ret)
++ return ret;
+
+ board_bind_eic_interrupt = &gic_bind_eic_interrupt;
+
+--
+2.35.1
+
--- /dev/null
+From 73550c03c393dbefef7cd88e162c985072f1775c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 06:36:40 +0000
+Subject: irqdomain: Report irq number for NOMAP domains
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xu Qiang <xuqiang36@huawei.com>
+
+[ Upstream commit 6f194c99f466147148cc08452718b46664112548 ]
+
+When using a NOMAP domain, __irq_resolve_mapping() doesn't store
+the Linux IRQ number at the address optionally provided by the caller.
+While this isn't a huge deal (the returned value is guaranteed
+to the hwirq that was passed as a parameter), let's honour the letter
+of the API by writing the expected value.
+
+Fixes: d22558dd0a6c (“irqdomain: Introduce irq_resolve_mapping()”)
+Signed-off-by: Xu Qiang <xuqiang36@huawei.com>
+[maz: commit message]
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220719063641.56541-2-xuqiang36@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/irq/irqdomain.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index d5ce96510549..481abb885d61 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -910,6 +910,8 @@ struct irq_desc *__irq_resolve_mapping(struct irq_domain *domain,
+ data = irq_domain_get_irq_data(domain, hwirq);
+ if (data && data->hwirq == hwirq)
+ desc = irq_data_to_desc(data);
++ if (irq && desc)
++ *irq = hwirq;
+ }
+
+ return desc;
+--
+2.35.1
+
--- /dev/null
+From c62951a9fd5034f1236461a9c203853638375d80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 20:51:52 +0800
+Subject: jbd2: fix assertion 'jh->b_frozen_data == NULL' failure when journal
+ aborted
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit 4a734f0869f970b8a9b65062ea40b09a5da9dba8 ]
+
+Following process will fail assertion 'jh->b_frozen_data == NULL' in
+jbd2_journal_dirty_metadata():
+
+ jbd2_journal_commit_transaction
+unlink(dir/a)
+ jh->b_transaction = trans1
+ jh->b_jlist = BJ_Metadata
+ journal->j_running_transaction = NULL
+ trans1->t_state = T_COMMIT
+unlink(dir/b)
+ handle->h_trans = trans2
+ do_get_write_access
+ jh->b_modified = 0
+ jh->b_frozen_data = frozen_buffer
+ jh->b_next_transaction = trans2
+ jbd2_journal_dirty_metadata
+ is_handle_aborted
+ is_journal_aborted // return false
+
+ --> jbd2 abort <--
+
+ while (commit_transaction->t_buffers)
+ if (is_journal_aborted)
+ jbd2_journal_refile_buffer
+ __jbd2_journal_refile_buffer
+ WRITE_ONCE(jh->b_transaction,
+ jh->b_next_transaction)
+ WRITE_ONCE(jh->b_next_transaction, NULL)
+ __jbd2_journal_file_buffer(jh, BJ_Reserved)
+ J_ASSERT_JH(jh, jh->b_frozen_data == NULL) // assertion failure !
+
+The reproducer (See detail in [Link]) reports:
+ ------------[ cut here ]------------
+ kernel BUG at fs/jbd2/transaction.c:1629!
+ invalid opcode: 0000 [#1] PREEMPT SMP
+ CPU: 2 PID: 584 Comm: unlink Tainted: G W
+ 5.19.0-rc6-00115-g4a57a8400075-dirty #697
+ RIP: 0010:jbd2_journal_dirty_metadata+0x3c5/0x470
+ RSP: 0018:ffffc90000be7ce0 EFLAGS: 00010202
+ Call Trace:
+ <TASK>
+ __ext4_handle_dirty_metadata+0xa0/0x290
+ ext4_handle_dirty_dirblock+0x10c/0x1d0
+ ext4_delete_entry+0x104/0x200
+ __ext4_unlink+0x22b/0x360
+ ext4_unlink+0x275/0x390
+ vfs_unlink+0x20b/0x4c0
+ do_unlinkat+0x42f/0x4c0
+ __x64_sys_unlink+0x37/0x50
+ do_syscall_64+0x35/0x80
+
+After journal aborting, __jbd2_journal_refile_buffer() is executed with
+holding @jh->b_state_lock, we can fix it by moving 'is_handle_aborted()'
+into the area protected by @jh->b_state_lock.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216251
+Fixes: 470decc613ab20 ("[PATCH] jbd2: initial copy of files from jbd")
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Link: https://lore.kernel.org/r/20220715125152.4022726-1-chengzhihao1@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/transaction.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index fcb9175016a5..49f109699933 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -1486,8 +1486,6 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
+ struct journal_head *jh;
+ int ret = 0;
+
+- if (is_handle_aborted(handle))
+- return -EROFS;
+ if (!buffer_jbd(bh))
+ return -EUCLEAN;
+
+@@ -1534,6 +1532,18 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
+ journal = transaction->t_journal;
+ spin_lock(&jh->b_state_lock);
+
++ if (is_handle_aborted(handle)) {
++ /*
++ * Check journal aborting with @jh->b_state_lock locked,
++ * since 'jh->b_transaction' could be replaced with
++ * 'jh->b_next_transaction' during old transaction
++ * committing if journal aborted, which may fail
++ * assertion on 'jh->b_frozen_data == NULL'.
++ */
++ ret = -EROFS;
++ goto out_unlock_bh;
++ }
++
+ if (jh->b_modified == 0) {
+ /*
+ * This buffer's got modified and becoming part
+--
+2.35.1
+
--- /dev/null
+From 00ad96c0c623a183b9a1ab3f0112a71fde1c988c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Jun 2022 21:04:26 +0800
+Subject: jbd2: fix outstanding credits assert in
+ jbd2_journal_commit_transaction()
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ Upstream commit a89573ce4ad32f19f43ec669771726817e185be0 ]
+
+We catch an assert problem in jbd2_journal_commit_transaction() when
+doing fsstress and request falut injection tests. The problem is
+happened in a race condition between jbd2_journal_commit_transaction()
+and ext4_end_io_end(). Firstly, ext4_writepages() writeback dirty pages
+and start reserved handle, and then the journal was aborted due to some
+previous metadata IO error, jbd2_journal_abort() start to commit current
+running transaction, the committing procedure could be raced by
+ext4_end_io_end() and lead to subtract j_reserved_credits twice from
+commit_transaction->t_outstanding_credits, finally the
+t_outstanding_credits is mistakenly smaller than t_nr_buffers and
+trigger assert.
+
+kjournald2 kworker
+
+jbd2_journal_commit_transaction()
+ write_unlock(&journal->j_state_lock);
+ atomic_sub(j_reserved_credits, t_outstanding_credits); //sub once
+
+ jbd2_journal_start_reserved()
+ start_this_handle() //detect aborted journal
+ jbd2_journal_free_reserved() //get running transaction
+ read_lock(&journal->j_state_lock)
+ __jbd2_journal_unreserve_handle()
+ atomic_sub(j_reserved_credits, t_outstanding_credits);
+ //sub again
+ read_unlock(&journal->j_state_lock);
+
+ journal->j_running_transaction = NULL;
+ J_ASSERT(t_nr_buffers <= t_outstanding_credits) //bomb!!!
+
+Fix this issue by using journal->j_state_lock to protect the subtraction
+in jbd2_journal_commit_transaction().
+
+Fixes: 96f1e0974575 ("jbd2: avoid long hold times of j_state_lock while committing a transaction")
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20220611130426.2013258-1-yi.zhang@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/commit.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
+index ac7f067b7bdd..f306b52b8e0b 100644
+--- a/fs/jbd2/commit.c
++++ b/fs/jbd2/commit.c
+@@ -551,13 +551,13 @@ void jbd2_journal_commit_transaction(journal_t *journal)
+ */
+ jbd2_journal_switch_revoke_table(journal);
+
++ write_lock(&journal->j_state_lock);
+ /*
+ * Reserved credits cannot be claimed anymore, free them
+ */
+ atomic_sub(atomic_read(&journal->j_reserved_credits),
+ &commit_transaction->t_outstanding_credits);
+
+- write_lock(&journal->j_state_lock);
+ trace_jbd2_commit_flushing(journal, commit_transaction);
+ stats.run.rs_flushing = jiffies;
+ stats.run.rs_locked = jbd2_time_diff(stats.run.rs_locked,
+--
+2.35.1
+
--- /dev/null
+From 548a9f8e171747c91a3da37daec8c0019e45e1c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 20:18:47 +0200
+Subject: kasan: fix zeroing vmalloc memory with HW_TAGS
+
+From: Andrey Konovalov <andreyknvl@google.com>
+
+[ Upstream commit 6c2f761dad7851d8088b91063ccaea3c970efe78 ]
+
+HW_TAGS KASAN skips zeroing page_alloc allocations backing vmalloc
+mappings via __GFP_SKIP_ZERO. Instead, these pages are zeroed via
+kasan_unpoison_vmalloc() by passing the KASAN_VMALLOC_INIT flag.
+
+The problem is that __kasan_unpoison_vmalloc() does not zero pages when
+either kasan_vmalloc_enabled() or is_vmalloc_or_module_addr() fail.
+
+Thus:
+
+1. Change __vmalloc_node_range() to only set KASAN_VMALLOC_INIT when
+ __GFP_SKIP_ZERO is set.
+
+2. Change __kasan_unpoison_vmalloc() to always zero pages when the
+ KASAN_VMALLOC_INIT flag is set.
+
+3. Add WARN_ON() asserts to check that KASAN_VMALLOC_INIT cannot be set
+ in other early return paths of __kasan_unpoison_vmalloc().
+
+Also clean up the comment in __kasan_unpoison_vmalloc.
+
+Link: https://lkml.kernel.org/r/4bc503537efdc539ffc3f461c1b70162eea31cf6.1654798516.git.andreyknvl@google.com
+Fixes: 23689e91fb22 ("kasan, vmalloc: add vmalloc tagging for HW_TAGS")
+Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
+Cc: Marco Elver <elver@google.com>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/kasan/hw_tags.c | 32 +++++++++++++++++++++++---------
+ mm/vmalloc.c | 10 +++++-----
+ 2 files changed, 28 insertions(+), 14 deletions(-)
+
+diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c
+index 9e1b6544bfa8..9ad8eff71b28 100644
+--- a/mm/kasan/hw_tags.c
++++ b/mm/kasan/hw_tags.c
+@@ -257,27 +257,37 @@ static void unpoison_vmalloc_pages(const void *addr, u8 tag)
+ }
+ }
+
++static void init_vmalloc_pages(const void *start, unsigned long size)
++{
++ const void *addr;
++
++ for (addr = start; addr < start + size; addr += PAGE_SIZE) {
++ struct page *page = virt_to_page(addr);
++
++ clear_highpage_kasan_tagged(page);
++ }
++}
++
+ void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
+ kasan_vmalloc_flags_t flags)
+ {
+ u8 tag;
+ unsigned long redzone_start, redzone_size;
+
+- if (!kasan_vmalloc_enabled())
+- return (void *)start;
+-
+- if (!is_vmalloc_or_module_addr(start))
++ if (!kasan_vmalloc_enabled() || !is_vmalloc_or_module_addr(start)) {
++ if (flags & KASAN_VMALLOC_INIT)
++ init_vmalloc_pages(start, size);
+ return (void *)start;
++ }
+
+ /*
+- * Skip unpoisoning and assigning a pointer tag for non-VM_ALLOC
+- * mappings as:
++ * Don't tag non-VM_ALLOC mappings, as:
+ *
+ * 1. Unlike the software KASAN modes, hardware tag-based KASAN only
+ * supports tagging physical memory. Therefore, it can only tag a
+ * single mapping of normal physical pages.
+ * 2. Hardware tag-based KASAN can only tag memory mapped with special
+- * mapping protection bits, see arch_vmalloc_pgprot_modify().
++ * mapping protection bits, see arch_vmap_pgprot_tagged().
+ * As non-VM_ALLOC mappings can be mapped outside of vmalloc code,
+ * providing these bits would require tracking all non-VM_ALLOC
+ * mappers.
+@@ -289,15 +299,19 @@ void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
+ *
+ * For non-VM_ALLOC allocations, page_alloc memory is tagged as usual.
+ */
+- if (!(flags & KASAN_VMALLOC_VM_ALLOC))
++ if (!(flags & KASAN_VMALLOC_VM_ALLOC)) {
++ WARN_ON(flags & KASAN_VMALLOC_INIT);
+ return (void *)start;
++ }
+
+ /*
+ * Don't tag executable memory.
+ * The kernel doesn't tolerate having the PC register tagged.
+ */
+- if (!(flags & KASAN_VMALLOC_PROT_NORMAL))
++ if (!(flags & KASAN_VMALLOC_PROT_NORMAL)) {
++ WARN_ON(flags & KASAN_VMALLOC_INIT);
+ return (void *)start;
++ }
+
+ tag = kasan_random_tag();
+ start = set_tag(start, tag);
+diff --git a/mm/vmalloc.c b/mm/vmalloc.c
+index cadfbb5155ea..06c555fc5be0 100644
+--- a/mm/vmalloc.c
++++ b/mm/vmalloc.c
+@@ -3170,15 +3170,15 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
+
+ /*
+ * Mark the pages as accessible, now that they are mapped.
+- * The init condition should match the one in post_alloc_hook()
+- * (except for the should_skip_init() check) to make sure that memory
+- * is initialized under the same conditions regardless of the enabled
+- * KASAN mode.
++ * The condition for setting KASAN_VMALLOC_INIT should complement the
++ * one in post_alloc_hook() with regards to the __GFP_SKIP_ZERO check
++ * to make sure that memory is initialized under the same conditions.
+ * Tag-based KASAN modes only assign tags to normal non-executable
+ * allocations, see __kasan_unpoison_vmalloc().
+ */
+ kasan_flags |= KASAN_VMALLOC_VM_ALLOC;
+- if (!want_init_on_free() && want_init_on_alloc(gfp_mask))
++ if (!want_init_on_free() && want_init_on_alloc(gfp_mask) &&
++ (gfp_mask & __GFP_SKIP_ZERO))
+ kasan_flags |= KASAN_VMALLOC_INIT;
+ /* KASAN_VMALLOC_PROT_NORMAL already set if required. */
+ area->addr = kasan_unpoison_vmalloc(area->addr, real_size, kasan_flags);
+--
+2.35.1
+
--- /dev/null
+From 8f1116b823fe568b5dd5a0a2a522a52670d3ff55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 14:40:24 -0700
+Subject: kasan: test: Silence GCC 12 warnings
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit aaf50b1969d7933a51ea421b11432a7fb90974e3 ]
+
+GCC 12 continues to get smarter about array accesses. The KASAN tests
+are expecting to explicitly test out-of-bounds conditions at run-time,
+so hide the variable from GCC, to avoid warnings like:
+
+../lib/test_kasan.c: In function 'ksize_uaf':
+../lib/test_kasan.c:790:61: warning: array subscript 120 is outside array bounds of 'void[120]' [-Warray-bounds]
+ 790 | KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)ptr)[size]);
+ | ~~~~~~~~~~~~~~~~~~~~~~^~~~~~
+../lib/test_kasan.c:97:9: note: in definition of macro 'KUNIT_EXPECT_KASAN_FAIL'
+ 97 | expression; \
+ | ^~~~~~~~~~
+
+Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Andrey Konovalov <andreyknvl@gmail.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
+Cc: kasan-dev@googlegroups.com
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20220608214024.1068451-1-keescook@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/test_kasan.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/lib/test_kasan.c b/lib/test_kasan.c
+index ad880231dfa8..630e0c31d7c2 100644
+--- a/lib/test_kasan.c
++++ b/lib/test_kasan.c
+@@ -131,6 +131,7 @@ static void kmalloc_oob_right(struct kunit *test)
+ ptr = kmalloc(size, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+
++ OPTIMIZER_HIDE_VAR(ptr);
+ /*
+ * An unaligned access past the requested kmalloc size.
+ * Only generic KASAN can precisely detect these.
+@@ -159,6 +160,7 @@ static void kmalloc_oob_left(struct kunit *test)
+ ptr = kmalloc(size, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+
++ OPTIMIZER_HIDE_VAR(ptr);
+ KUNIT_EXPECT_KASAN_FAIL(test, *ptr = *(ptr - 1));
+ kfree(ptr);
+ }
+@@ -171,6 +173,7 @@ static void kmalloc_node_oob_right(struct kunit *test)
+ ptr = kmalloc_node(size, GFP_KERNEL, 0);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+
++ OPTIMIZER_HIDE_VAR(ptr);
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr[0] = ptr[size]);
+ kfree(ptr);
+ }
+@@ -191,6 +194,7 @@ static void kmalloc_pagealloc_oob_right(struct kunit *test)
+ ptr = kmalloc(size, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+
++ OPTIMIZER_HIDE_VAR(ptr);
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr[size + OOB_TAG_OFF] = 0);
+
+ kfree(ptr);
+@@ -271,6 +275,7 @@ static void kmalloc_large_oob_right(struct kunit *test)
+ ptr = kmalloc(size, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+
++ OPTIMIZER_HIDE_VAR(ptr);
+ KUNIT_EXPECT_KASAN_FAIL(test, ptr[size] = 0);
+ kfree(ptr);
+ }
+@@ -410,6 +415,8 @@ static void kmalloc_oob_16(struct kunit *test)
+ ptr2 = kmalloc(sizeof(*ptr2), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2);
+
++ OPTIMIZER_HIDE_VAR(ptr1);
++ OPTIMIZER_HIDE_VAR(ptr2);
+ KUNIT_EXPECT_KASAN_FAIL(test, *ptr1 = *ptr2);
+ kfree(ptr1);
+ kfree(ptr2);
+@@ -756,6 +763,8 @@ static void ksize_unpoisons_memory(struct kunit *test)
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+ real_size = ksize(ptr);
+
++ OPTIMIZER_HIDE_VAR(ptr);
++
+ /* This access shouldn't trigger a KASAN report. */
+ ptr[size] = 'x';
+
+@@ -778,6 +787,7 @@ static void ksize_uaf(struct kunit *test)
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+ kfree(ptr);
+
++ OPTIMIZER_HIDE_VAR(ptr);
+ KUNIT_EXPECT_KASAN_FAIL(test, ksize(ptr));
+ KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)ptr)[0]);
+ KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)ptr)[size]);
+--
+2.35.1
+
--- /dev/null
+From fc41267fd48b8666cfed397a6d5316783ad63d1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 May 2022 18:51:28 +0800
+Subject: kbuild: Fix include path in scripts/Makefile.modpost
+
+From: Jing Leng <jleng@ambarella.com>
+
+[ Upstream commit 23a0cb8e3225122496bfa79172005c587c2d64bf ]
+
+When building an external module, if users don't need to separate the
+compilation output and source code, they run the following command:
+"make -C $(LINUX_SRC_DIR) M=$(PWD)". At this point, "$(KBUILD_EXTMOD)"
+and "$(src)" are the same.
+
+If they need to separate them, they run "make -C $(KERNEL_SRC_DIR)
+O=$(KERNEL_OUT_DIR) M=$(OUT_DIR) src=$(PWD)". Before running the
+command, they need to copy "Kbuild" or "Makefile" to "$(OUT_DIR)" to
+prevent compilation failure.
+
+So the kernel should change the included path to avoid the copy operation.
+
+Signed-off-by: Jing Leng <jleng@ambarella.com>
+[masahiro: I do not think "M=$(OUT_DIR) src=$(PWD)" is the official way,
+but this patch is a nice clean up anyway.]
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/Makefile.modpost | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
+index 48585c4d04ad..0273bf7375e2 100644
+--- a/scripts/Makefile.modpost
++++ b/scripts/Makefile.modpost
+@@ -87,8 +87,7 @@ obj := $(KBUILD_EXTMOD)
+ src := $(obj)
+
+ # Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS
+-include $(if $(wildcard $(KBUILD_EXTMOD)/Kbuild), \
+- $(KBUILD_EXTMOD)/Kbuild, $(KBUILD_EXTMOD)/Makefile)
++include $(if $(wildcard $(src)/Kbuild), $(src)/Kbuild, $(src)/Makefile)
+
+ # modpost option for external modules
+ MODPOST += -e
+--
+2.35.1
+
--- /dev/null
+From 8dd6f07285f5df8a17ca5ee8b9072a3064b77f93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jun 2022 16:25:12 +0800
+Subject: kernfs: fix potential NULL dereference in __kernfs_remove
+
+From: Yushan Zhou <katrinzhou@tencent.com>
+
+[ Upstream commit 72b5d5aef246a0387cefa23121dd90901c7a691a ]
+
+When lockdep is enabled, lockdep_assert_held_write would
+cause potential NULL pointer dereference.
+
+Fix the following smatch warnings:
+
+fs/kernfs/dir.c:1353 __kernfs_remove() warn: variable dereferenced before check 'kn' (see line 1346)
+
+Fixes: 393c3714081a ("kernfs: switch global kernfs_rwsem lock to per-fs lock")
+Signed-off-by: Yushan Zhou <katrinzhou@tencent.com>
+Link: https://lore.kernel.org/r/20220630082512.3482581-1-zys.zljxml@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/kernfs/dir.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
+index 6eca72cfa1f2..1cc88ba6de90 100644
+--- a/fs/kernfs/dir.c
++++ b/fs/kernfs/dir.c
+@@ -1343,14 +1343,17 @@ static void __kernfs_remove(struct kernfs_node *kn)
+ {
+ struct kernfs_node *pos;
+
++ /* Short-circuit if non-root @kn has already finished removal. */
++ if (!kn)
++ return;
++
+ lockdep_assert_held_write(&kernfs_root(kn)->kernfs_rwsem);
+
+ /*
+- * Short-circuit if non-root @kn has already finished removal.
+ * This is for kernfs_remove_self() which plays with active ref
+ * after removal.
+ */
+- if (!kn || (kn->parent && RB_EMPTY_NODE(&kn->rb)))
++ if (kn->parent && RB_EMPTY_NODE(&kn->rb))
+ return;
+
+ pr_debug("kernfs %s: removing\n", kn->name);
+--
+2.35.1
+
--- /dev/null
+From ec0adb4adacb4be8c2d4e4c7eb79466e63c625e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 08:30:04 +0300
+Subject: kfifo: fix kfifo_to_user() return type
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 045ed31e23aea840648c290dbde04797064960db ]
+
+The kfifo_to_user() macro is supposed to return zero for success or
+negative error codes. Unfortunately, there is a signedness bug so it
+returns unsigned int. This only affects callers which try to save the
+result in ssize_t and as far as I can see the only place which does that
+is line6_hwdep_read().
+
+TL;DR: s/_uint/_int/.
+
+Link: https://lkml.kernel.org/r/YrVL3OJVLlNhIMFs@kili
+Fixes: 144ecf310eb5 ("kfifo: fix kfifo_alloc() to return a signed int value")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Cc: Stefani Seibold <stefani@seibold.net>
+Cc: Randy Dunlap <randy.dunlap@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/kfifo.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h
+index 86249476b57f..0b35a41440ff 100644
+--- a/include/linux/kfifo.h
++++ b/include/linux/kfifo.h
+@@ -688,7 +688,7 @@ __kfifo_uint_must_check_helper( \
+ * writer, you don't need extra locking to use these macro.
+ */
+ #define kfifo_to_user(fifo, to, len, copied) \
+-__kfifo_uint_must_check_helper( \
++__kfifo_int_must_check_helper( \
+ ({ \
+ typeof((fifo) + 1) __tmp = (fifo); \
+ void __user *__to = (to); \
+--
+2.35.1
+
--- /dev/null
+From f32fc07b7d91da50f1bbc2ddad7710bb6f09a71e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Aug 2022 11:37:19 +0800
+Subject: kprobes: Forbid probing on trampoline and BPF code areas
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit 28f6c37a2910f565b4f5960df52b2eccae28c891 ]
+
+kernel_text_address() treats ftrace_trampoline, kprobe_insn_slot
+and bpf_text_address as valid kprobe addresses - which is not ideal.
+
+These text areas are removable and changeable without any notification
+to kprobes, and probing on them can trigger unexpected behavior:
+
+ https://lkml.org/lkml/2022/7/26/1148
+
+Considering that jump_label and static_call text are already
+forbiden to probe, kernel_text_address() should be replaced with
+core_kernel_text() and is_module_text_address() to check other text
+areas which are unsafe to kprobe.
+
+[ mingo: Rewrote the changelog. ]
+
+Fixes: 5b485629ba0d ("kprobes, extable: Identify kprobes trampolines as kernel text area")
+Fixes: 74451e66d516 ("bpf: make jited programs visible in traces")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Link: https://lore.kernel.org/r/20220801033719.228248-1-chenzhongjin@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/kprobes.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c
+index f214f8c088ed..80697e5e03e4 100644
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -1560,7 +1560,8 @@ static int check_kprobe_address_safe(struct kprobe *p,
+ preempt_disable();
+
+ /* Ensure it is not in reserved area nor out of text */
+- if (!kernel_text_address((unsigned long) p->addr) ||
++ if (!(core_kernel_text((unsigned long) p->addr) ||
++ is_module_text_address((unsigned long) p->addr)) ||
+ within_kprobe_blacklist((unsigned long) p->addr) ||
+ jump_label_text_reserved(p->addr, p->addr) ||
+ static_call_text_reserved(p->addr, p->addr) ||
+--
+2.35.1
+
--- /dev/null
+From 29bd18035e85d4c95cba8f853cfb86125d6416f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 07:25:27 +0800
+Subject: kunit: executor: Fix a memory leak on failure in kunit_filter_tests
+
+From: David Gow <davidgow@google.com>
+
+[ Upstream commit 94681e289bf5d10c9db9db143d1a22d8717205c5 ]
+
+It's possible that memory allocation for 'filtered' will fail, but for the
+copy of the suite to succeed. In this case, the copy could be leaked.
+
+Properly free 'copy' in the error case for the allocation of 'filtered'
+failing.
+
+Note that there may also have been a similar issue in
+kunit_filter_subsuites, before it was removed in "kunit: flatten
+kunit_suite*** to kunit_suite** in .kunit_test_suites".
+
+This was reported by clang-analyzer via the kernel test robot, here:
+https://lore.kernel.org/all/c8073b8e-7b9e-0830-4177-87c12f16349c@intel.com/
+
+And by smatch via Dan Carpenter and the kernel test robot:
+https://lore.kernel.org/all/202207101328.ASjx88yj-lkp@intel.com/
+
+Fixes: a02353f49162 ("kunit: bail out of test filtering logic quicker if OOM")
+Reported-by: kernel test robot <yujie.liu@intel.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Daniel Latypov <dlatypov@google.com>
+Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
+Signed-off-by: David Gow <davidgow@google.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/kunit/executor.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c
+index 96f96e42ce06..16fb88c0aca3 100644
+--- a/lib/kunit/executor.c
++++ b/lib/kunit/executor.c
+@@ -76,8 +76,10 @@ kunit_filter_tests(struct kunit_suite *const suite, const char *test_glob)
+ memcpy(copy, suite, sizeof(*copy));
+
+ filtered = kcalloc(n + 1, sizeof(*filtered), GFP_KERNEL);
+- if (!filtered)
++ if (!filtered) {
++ kfree(copy);
+ return ERR_PTR(-ENOMEM);
++ }
+
+ n = 0;
+ kunit_suite_for_each_test_case(suite, test_case) {
+--
+2.35.1
+
--- /dev/null
+From 9e4be7c5b73e579d555dd68fb65bcaf0e631197e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 14:23:10 +0000
+Subject: KVM: arm64: Don't return from void function
+
+From: Quentin Perret <qperret@google.com>
+
+[ Upstream commit 1c3ace2b8b3995d3213c5e2d2aca01a0577a3b0f ]
+
+Although harmless, the return statement in kvm_unexpected_el2_exception
+is rather confusing as the function itself has a void return type. The
+C standard is also pretty clear that "A return statement with an
+expression shall not appear in a function whose return type is void".
+Given that this return statement does not seem to add any actual value,
+let's not pointlessly violate the standard.
+
+Build-tested with GCC 10 and CLANG 13 for good measure, the disassembled
+code is identical with or without the return statement.
+
+Fixes: e9ee186bb735 ("KVM: arm64: Add kvm_extable for vaxorcism code")
+Signed-off-by: Quentin Perret <qperret@google.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20220705142310.3847918-1-qperret@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kvm/hyp/nvhe/switch.c | 2 +-
+ arch/arm64/kvm/hyp/vhe/switch.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
+index 6410d21d8695..858e5be48791 100644
+--- a/arch/arm64/kvm/hyp/nvhe/switch.c
++++ b/arch/arm64/kvm/hyp/nvhe/switch.c
+@@ -371,5 +371,5 @@ void __noreturn hyp_panic(void)
+
+ asmlinkage void kvm_unexpected_el2_exception(void)
+ {
+- return __kvm_unexpected_el2_exception();
++ __kvm_unexpected_el2_exception();
+ }
+diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
+index 262dfe03134d..51ea9ac71210 100644
+--- a/arch/arm64/kvm/hyp/vhe/switch.c
++++ b/arch/arm64/kvm/hyp/vhe/switch.c
+@@ -240,5 +240,5 @@ void __noreturn hyp_panic(void)
+
+ asmlinkage void kvm_unexpected_el2_exception(void)
+ {
+- return __kvm_unexpected_el2_exception();
++ __kvm_unexpected_el2_exception();
+ }
+--
+2.35.1
+
--- /dev/null
+From 71f7c2ba22ee6eb4adde4253124e795a3f769026 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Apr 2022 01:04:09 +0000
+Subject: KVM: Don't set Accessed/Dirty bits for ZERO_PAGE
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit a1040b0d42acf69bb4f6dbdc54c2dcd78eea1de5 ]
+
+Don't set Accessed/Dirty bits for a struct page with PG_reserved set,
+i.e. don't set A/D bits for the ZERO_PAGE. The ZERO_PAGE (or pages
+depending on the architecture) should obviously never be written, and
+similarly there's no point in marking it accessed as the page will never
+be swapped out or reclaimed. The comment in page-flags.h is quite clear
+that PG_reserved pages should be managed only by their owner, and
+strictly following that mandate also simplifies KVM's logic.
+
+Fixes: 7df003c85218 ("KVM: fix overflow of zero page refcount with ksm running")
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20220429010416.2788472-4-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ virt/kvm/kvm_main.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 6c8295e76548..843396ed4ad3 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -2852,16 +2852,28 @@ void kvm_release_pfn_dirty(kvm_pfn_t pfn)
+ }
+ EXPORT_SYMBOL_GPL(kvm_release_pfn_dirty);
+
++static bool kvm_is_ad_tracked_pfn(kvm_pfn_t pfn)
++{
++ if (!pfn_valid(pfn))
++ return false;
++
++ /*
++ * Per page-flags.h, pages tagged PG_reserved "should in general not be
++ * touched (e.g. set dirty) except by its owner".
++ */
++ return !PageReserved(pfn_to_page(pfn));
++}
++
+ void kvm_set_pfn_dirty(kvm_pfn_t pfn)
+ {
+- if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn))
++ if (kvm_is_ad_tracked_pfn(pfn))
+ SetPageDirty(pfn_to_page(pfn));
+ }
+ EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty);
+
+ void kvm_set_pfn_accessed(kvm_pfn_t pfn)
+ {
+- if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn))
++ if (kvm_is_ad_tracked_pfn(pfn))
+ mark_page_accessed(pfn_to_page(pfn));
+ }
+ EXPORT_SYMBOL_GPL(kvm_set_pfn_accessed);
+--
+2.35.1
+
--- /dev/null
+From c83c692dcd209356fb8a24393c736e0bbe27fb72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 21:36:00 +0000
+Subject: KVM: nVMX: Set UMIP bit CR4_FIXED1 MSR when emulating UMIP
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit a910b5ab6b250a88fff1866bf708642d83317466 ]
+
+Make UMIP an "allowed-1" bit CR4_FIXED1 MSR when KVM is emulating UMIP.
+KVM emulates UMIP for both L1 and L2, and so should enumerate that L2 is
+allowed to have CR4.UMIP=1. Not setting the bit doesn't immediately
+break nVMX, as KVM does set/clear the bit in CR4_FIXED1 in response to a
+guest CPUID update, i.e. KVM will correctly (dis)allow nested VM-Entry
+based on whether or not UMIP is exposed to L1. That said, KVM should
+enumerate the bit as being allowed from time zero, e.g. userspace will
+see the wrong value if the MSR is read before CPUID is written.
+
+Fixes: 0367f205a3b7 ("KVM: vmx: add support for emulating UMIP")
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20220607213604.3346000-12-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/vmx/nested.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index c632df13ada2..aa287302f991 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -6790,6 +6790,9 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps)
+ rdmsrl(MSR_IA32_VMX_CR0_FIXED1, msrs->cr0_fixed1);
+ rdmsrl(MSR_IA32_VMX_CR4_FIXED1, msrs->cr4_fixed1);
+
++ if (vmx_umip_emulated())
++ msrs->cr4_fixed1 |= X86_CR4_UMIP;
++
+ msrs->vmcs_enum = nested_vmx_calc_vmcs_enum_msr();
+ }
+
+--
+2.35.1
+
--- /dev/null
+From b94a82eac2b96417225d0ec1896fcf5af244f186 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jun 2022 15:56:02 +0200
+Subject: KVM: s390: pv: leak the topmost page table when destroy fails
+
+From: Claudio Imbrenda <imbrenda@linux.ibm.com>
+
+[ Upstream commit faa2f72cb3569256480c5540d242c84e99965160 ]
+
+Each secure guest must have a unique ASCE (address space control
+element); we must avoid that new guests use the same page for their
+ASCE, to avoid errors.
+
+Since the ASCE mostly consists of the address of the topmost page table
+(plus some flags), we must not return that memory to the pool unless
+the ASCE is no longer in use.
+
+Only a successful Destroy Secure Configuration UVC will make the ASCE
+reusable again.
+
+If the Destroy Configuration UVC fails, the ASCE cannot be reused for a
+secure guest (either for the ASCE or for other memory areas). To avoid
+a collision, it must not be used again. This is a permanent error and
+the page becomes in practice unusable, so we set it aside and leak it.
+On failure we already leak other memory that belongs to the ultravisor
+(i.e. the variable and base storage for a guest) and not leaking the
+topmost page table was an oversight.
+
+This error (and thus the leakage) should not happen unless the hardware
+is broken or KVM has some unknown serious bug.
+
+Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Fixes: 29b40f105ec8d55 ("KVM: s390: protvirt: Add initial vm and cpu lifecycle handling")
+Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
+Link: https://lore.kernel.org/r/20220628135619.32410-2-imbrenda@linux.ibm.com
+Message-Id: <20220628135619.32410-2-imbrenda@linux.ibm.com>
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/include/asm/gmap.h | 2 +
+ arch/s390/kvm/pv.c | 9 ++--
+ arch/s390/mm/gmap.c | 86 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 94 insertions(+), 3 deletions(-)
+
+diff --git a/arch/s390/include/asm/gmap.h b/arch/s390/include/asm/gmap.h
+index 40264f60b0da..f4073106e1f3 100644
+--- a/arch/s390/include/asm/gmap.h
++++ b/arch/s390/include/asm/gmap.h
+@@ -148,4 +148,6 @@ void gmap_sync_dirty_log_pmd(struct gmap *gmap, unsigned long dirty_bitmap[4],
+ unsigned long gaddr, unsigned long vmaddr);
+ int gmap_mark_unmergeable(void);
+ void s390_reset_acc(struct mm_struct *mm);
++void s390_unlist_old_asce(struct gmap *gmap);
++int s390_replace_asce(struct gmap *gmap);
+ #endif /* _ASM_S390_GMAP_H */
+diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c
+index cc7c9599f43e..8eee3fc414e5 100644
+--- a/arch/s390/kvm/pv.c
++++ b/arch/s390/kvm/pv.c
+@@ -161,10 +161,13 @@ int kvm_s390_pv_deinit_vm(struct kvm *kvm, u16 *rc, u16 *rrc)
+ atomic_set(&kvm->mm->context.is_protected, 0);
+ KVM_UV_EVENT(kvm, 3, "PROTVIRT DESTROY VM: rc %x rrc %x", *rc, *rrc);
+ WARN_ONCE(cc, "protvirt destroy vm failed rc %x rrc %x", *rc, *rrc);
+- /* Inteded memory leak on "impossible" error */
+- if (!cc)
++ /* Intended memory leak on "impossible" error */
++ if (!cc) {
+ kvm_s390_pv_dealloc_vm(kvm);
+- return cc ? -EIO : 0;
++ return 0;
++ }
++ s390_replace_asce(kvm->arch.gmap);
++ return -EIO;
+ }
+
+ int kvm_s390_pv_init_vm(struct kvm *kvm, u16 *rc, u16 *rrc)
+diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
+index b8ae4a4aa2ba..85cab61d87a9 100644
+--- a/arch/s390/mm/gmap.c
++++ b/arch/s390/mm/gmap.c
+@@ -2735,3 +2735,89 @@ void s390_reset_acc(struct mm_struct *mm)
+ mmput(mm);
+ }
+ EXPORT_SYMBOL_GPL(s390_reset_acc);
++
++/**
++ * s390_unlist_old_asce - Remove the topmost level of page tables from the
++ * list of page tables of the gmap.
++ * @gmap: the gmap whose table is to be removed
++ *
++ * On s390x, KVM keeps a list of all pages containing the page tables of the
++ * gmap (the CRST list). This list is used at tear down time to free all
++ * pages that are now not needed anymore.
++ *
++ * This function removes the topmost page of the tree (the one pointed to by
++ * the ASCE) from the CRST list.
++ *
++ * This means that it will not be freed when the VM is torn down, and needs
++ * to be handled separately by the caller, unless a leak is actually
++ * intended. Notice that this function will only remove the page from the
++ * list, the page will still be used as a top level page table (and ASCE).
++ */
++void s390_unlist_old_asce(struct gmap *gmap)
++{
++ struct page *old;
++
++ old = virt_to_page(gmap->table);
++ spin_lock(&gmap->guest_table_lock);
++ list_del(&old->lru);
++ /*
++ * Sometimes the topmost page might need to be "removed" multiple
++ * times, for example if the VM is rebooted into secure mode several
++ * times concurrently, or if s390_replace_asce fails after calling
++ * s390_remove_old_asce and is attempted again later. In that case
++ * the old asce has been removed from the list, and therefore it
++ * will not be freed when the VM terminates, but the ASCE is still
++ * in use and still pointed to.
++ * A subsequent call to replace_asce will follow the pointer and try
++ * to remove the same page from the list again.
++ * Therefore it's necessary that the page of the ASCE has valid
++ * pointers, so list_del can work (and do nothing) without
++ * dereferencing stale or invalid pointers.
++ */
++ INIT_LIST_HEAD(&old->lru);
++ spin_unlock(&gmap->guest_table_lock);
++}
++EXPORT_SYMBOL_GPL(s390_unlist_old_asce);
++
++/**
++ * s390_replace_asce - Try to replace the current ASCE of a gmap with a copy
++ * @gmap: the gmap whose ASCE needs to be replaced
++ *
++ * If the allocation of the new top level page table fails, the ASCE is not
++ * replaced.
++ * In any case, the old ASCE is always removed from the gmap CRST list.
++ * Therefore the caller has to make sure to save a pointer to it
++ * beforehand, unless a leak is actually intended.
++ */
++int s390_replace_asce(struct gmap *gmap)
++{
++ unsigned long asce;
++ struct page *page;
++ void *table;
++
++ s390_unlist_old_asce(gmap);
++
++ page = alloc_pages(GFP_KERNEL_ACCOUNT, CRST_ALLOC_ORDER);
++ if (!page)
++ return -ENOMEM;
++ table = page_to_virt(page);
++ memcpy(table, gmap->table, 1UL << (CRST_ALLOC_ORDER + PAGE_SHIFT));
++
++ /*
++ * The caller has to deal with the old ASCE, but here we make sure
++ * the new one is properly added to the CRST list, so that
++ * it will be freed when the VM is torn down.
++ */
++ spin_lock(&gmap->guest_table_lock);
++ list_add(&page->lru, &gmap->crst_list);
++ spin_unlock(&gmap->guest_table_lock);
++
++ /* Set new table origin while preserving existing ASCE control bits */
++ asce = (gmap->asce & ~_ASCE_ORIGIN) | __pa(table);
++ WRITE_ONCE(gmap->asce, asce);
++ WRITE_ONCE(gmap->mm->context.gmap_asce, asce);
++ WRITE_ONCE(gmap->table, table);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(s390_replace_asce);
+--
+2.35.1
+
--- /dev/null
+From b652895385463c0c1d227a3a8ad091648a5e85ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 May 2022 00:07:28 +0200
+Subject: KVM: SVM: Stuff next_rip on emulated INT3 injection if NRIPS is
+ supported
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 3741aec4c38fa4123ab08ae552f05366d4fd05d8 ]
+
+If NRIPS is supported in hardware but disabled in KVM, set next_rip to
+the next RIP when advancing RIP as part of emulating INT3 injection.
+There is no flag to tell the CPU that KVM isn't using next_rip, and so
+leaving next_rip is left as is will result in the CPU pushing garbage
+onto the stack when vectoring the injected event.
+
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Fixes: 66b7138f9136 ("KVM: SVM: Emulate nRIP feature when reinjecting INT3")
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
+Message-Id: <cd328309a3b88604daa2359ad56f36cb565ce2d4.1651440202.git.maciej.szmigiero@oracle.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/svm/svm.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index e4c736d74fcb..e5a154f0d2ab 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -390,6 +390,10 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu)
+ */
+ (void)svm_skip_emulated_instruction(vcpu);
+ rip = kvm_rip_read(vcpu);
++
++ if (boot_cpu_has(X86_FEATURE_NRIPS))
++ svm->vmcb->control.next_rip = rip;
++
+ svm->int3_rip = rip + svm->vmcb->save.cs.base;
+ svm->int3_injected = rip - old_rip;
+ }
+@@ -3616,7 +3620,7 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu)
+ /*
+ * If NextRIP isn't enabled, KVM must manually advance RIP prior to
+ * injecting the soft exception/interrupt. That advancement needs to
+- * be unwound if vectoring didn't complete. Note, the _new_ event may
++ * be unwound if vectoring didn't complete. Note, the new event may
+ * not be the injected event, e.g. if KVM injected an INTn, the INTn
+ * hit a #NP in the guest, and the #NP encountered a #PF, the #NP will
+ * be the reported vectored event, but RIP still needs to be unwound.
+--
+2.35.1
+
--- /dev/null
+From 534bf872bc83807c5ae87139b21b8431c32cd07e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 May 2022 00:07:27 +0200
+Subject: KVM: SVM: Unwind "speculative" RIP advancement if INTn injection
+ "fails"
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit cd9e6da8048c5b40315ee2d929b6230ce1252c3c ]
+
+Unwind the RIP advancement done by svm_queue_exception() when injecting
+an INT3 ultimately "fails" due to the CPU encountering a VM-Exit while
+vectoring the injected event, even if the exception reported by the CPU
+isn't the same event that was injected. If vectoring INT3 encounters an
+exception, e.g. #NP, and vectoring the #NP encounters an intercepted
+exception, e.g. #PF when KVM is using shadow paging, then the #NP will
+be reported as the event that was in-progress.
+
+Note, this is still imperfect, as it will get a false positive if the
+INT3 is cleanly injected, no VM-Exit occurs before the IRET from the INT3
+handler in the guest, the instruction following the INT3 generates an
+exception (directly or indirectly), _and_ vectoring that exception
+encounters an exception that is intercepted by KVM. The false positives
+could theoretically be solved by further analyzing the vectoring event,
+e.g. by comparing the error code against the expected error code were an
+exception to occur when vectoring the original injected exception, but
+SVM without NRIPS is a complete disaster, trying to make it 100% correct
+is a waste of time.
+
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Fixes: 66b7138f9136 ("KVM: SVM: Emulate nRIP feature when reinjecting INT3")
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
+Message-Id: <450133cf0a026cb9825a2ff55d02cb136a1cb111.1651440202.git.maciej.szmigiero@oracle.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/svm/svm.c | 23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index 2851d1e58cb8..e4c736d74fcb 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -3613,6 +3613,18 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu)
+ vector = exitintinfo & SVM_EXITINTINFO_VEC_MASK;
+ type = exitintinfo & SVM_EXITINTINFO_TYPE_MASK;
+
++ /*
++ * If NextRIP isn't enabled, KVM must manually advance RIP prior to
++ * injecting the soft exception/interrupt. That advancement needs to
++ * be unwound if vectoring didn't complete. Note, the _new_ event may
++ * not be the injected event, e.g. if KVM injected an INTn, the INTn
++ * hit a #NP in the guest, and the #NP encountered a #PF, the #NP will
++ * be the reported vectored event, but RIP still needs to be unwound.
++ */
++ if (int3_injected && type == SVM_EXITINTINFO_TYPE_EXEPT &&
++ kvm_is_linear_rip(vcpu, svm->int3_rip))
++ kvm_rip_write(vcpu, kvm_rip_read(vcpu) - int3_injected);
++
+ switch (type) {
+ case SVM_EXITINTINFO_TYPE_NMI:
+ vcpu->arch.nmi_injected = true;
+@@ -3626,16 +3638,11 @@ static void svm_complete_interrupts(struct kvm_vcpu *vcpu)
+
+ /*
+ * In case of software exceptions, do not reinject the vector,
+- * but re-execute the instruction instead. Rewind RIP first
+- * if we emulated INT3 before.
++ * but re-execute the instruction instead.
+ */
+- if (kvm_exception_is_soft(vector)) {
+- if (vector == BP_VECTOR && int3_injected &&
+- kvm_is_linear_rip(vcpu, svm->int3_rip))
+- kvm_rip_write(vcpu,
+- kvm_rip_read(vcpu) - int3_injected);
++ if (kvm_exception_is_soft(vector))
+ break;
+- }
++
+ if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) {
+ u32 err = svm->vmcb->control.exit_int_info_err;
+ kvm_requeue_exception_e(vcpu, vector, err);
+--
+2.35.1
+
--- /dev/null
+From b2b5cace4bea65320bd2af0ee8426c7e36e3416c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 21:25:20 +0000
+Subject: KVM: x86: Fix errant brace in KVM capability handling
+
+From: Ben Gardon <bgardon@google.com>
+
+[ Upstream commit 1c4dc57328bf218e999951824dce75c6125c4f3c ]
+
+The braces around the KVM_CAP_XSAVE2 block also surround the
+KVM_CAP_PMU_CAPABILITY block, likely the result of a merge issue. Simply
+move the curly brace back to where it belongs.
+
+Fixes: ba7bb663f5547 ("KVM: x86: Provide per VM capability for disabling PMU virtualization")
+
+Reviewed-by: David Matlack <dmatlack@google.com>
+Reviewed-by: Peter Xu <peterx@redhat.com>
+Signed-off-by: Ben Gardon <bgardon@google.com>
+Message-Id: <20220613212523.3436117-8-bgardon@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/x86.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index cc2c89c08d85..767a61e29f51 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -4377,10 +4377,10 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
+ if (r < sizeof(struct kvm_xsave))
+ r = sizeof(struct kvm_xsave);
+ break;
++ }
+ case KVM_CAP_PMU_CAPABILITY:
+ r = enable_pmu ? KVM_CAP_PMU_VALID_MASK : 0;
+ break;
+- }
+ case KVM_CAP_DISABLE_QUIRKS2:
+ r = KVM_X86_VALID_QUIRKS;
+ break;
+--
+2.35.1
+
--- /dev/null
+From 9d49eb5436e02e58a547db921e48bcc3f25869b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 May 2022 19:49:59 +0000
+Subject: KVM: x86/mmu: Drop RWX=0 SPTEs during ept_sync_page()
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 9fb3565743d58352f00964bf47213b88aff4bb82 ]
+
+All of sync_page()'s existing checks filter out only !PRESENT gPTE,
+because without execute-only, all upper levels are guaranteed to be at
+least READABLE. However, if EPT with execute-only support is in use by
+L1, KVM can create an SPTE that is shadow-present but guest-inaccessible
+(RWX=0) if the upper level combined permissions are R (or RW) and
+the leaf EPTE is changed from R (or RW) to X. Because the EPTE is
+considered present when viewed in isolation, and no reserved bits are set,
+FNAME(prefetch_invalid_gpte) will consider the GPTE valid, and cause a
+not-present SPTE to be created.
+
+The SPTE is "correct": the guest translation is inaccessible because
+the combined protections of all levels yield RWX=0, and KVM will just
+redirect any vmexits to the guest. If EPT A/D bits are disabled, KVM
+can mistake the SPTE for an access-tracked SPTE, but again such confusion
+isn't fatal, as the "saved" protections are also RWX=0. However,
+creating a useless SPTE in general means that KVM messed up something,
+even if this particular goof didn't manifest as a functional bug.
+So, drop SPTEs whose new protections will yield a RWX=0 SPTE, and
+add a WARN in make_spte() to detect creation of SPTEs that will
+result in RWX=0 protections.
+
+Fixes: d95c55687e11 ("kvm: mmu: track read permission explicitly for shadow EPT page tables")
+Cc: David Matlack <dmatlack@google.com>
+Cc: Ben Gardon <bgardon@google.com>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-Id: <20220513195000.99371-2-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/mmu/paging_tmpl.h | 9 ++++++++-
+ arch/x86/kvm/mmu/spte.c | 2 ++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h
+index beb3ce8d94eb..43f6a882615f 100644
+--- a/arch/x86/kvm/mmu/paging_tmpl.h
++++ b/arch/x86/kvm/mmu/paging_tmpl.h
+@@ -1044,7 +1044,14 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
+ if (sync_mmio_spte(vcpu, &sp->spt[i], gfn, pte_access))
+ continue;
+
+- if (gfn != sp->gfns[i]) {
++ /*
++ * Drop the SPTE if the new protections would result in a RWX=0
++ * SPTE or if the gfn is changing. The RWX=0 case only affects
++ * EPT with execute-only support, i.e. EPT without an effective
++ * "present" bit, as all other paging modes will create a
++ * read-only SPTE if pte_access is zero.
++ */
++ if ((!pte_access && !shadow_present_mask) || gfn != sp->gfns[i]) {
+ drop_spte(vcpu->kvm, &sp->spt[i]);
+ flush = true;
+ continue;
+diff --git a/arch/x86/kvm/mmu/spte.c b/arch/x86/kvm/mmu/spte.c
+index e5c0b6db6f2c..8223a80802e7 100644
+--- a/arch/x86/kvm/mmu/spte.c
++++ b/arch/x86/kvm/mmu/spte.c
+@@ -128,6 +128,8 @@ bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
+ u64 spte = SPTE_MMU_PRESENT_MASK;
+ bool wrprot = false;
+
++ WARN_ON_ONCE(!pte_access && !shadow_present_mask);
++
+ if (sp->role.ad_disabled)
+ spte |= SPTE_TDP_AD_DISABLED_MASK;
+ else if (kvm_mmu_page_ad_need_write_protect(sp))
+--
+2.35.1
+
--- /dev/null
+From 60d85fbed5aae303291344db0c78140f3620430c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 10:40:43 -0700
+Subject: lib: overflow: Do not define 64-bit tests on 32-bit
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 6a022dd29f2cefbac4895a34e2e1f14b2d12d819 ]
+
+The 64-bit overflow tests will trigger 64-bit division on 32-bit hosts,
+which is not currently used anywhere in the kernel, and tickles bugs
+in at least Clang 13 and earlier:
+https://github.com/ClangBuiltLinux/linux/issues/1636
+
+In reality, there shouldn't be a reason to not build the 64-bit test
+cases on 32-bit systems, so these #ifdefs can be removed once the minimum
+Clang version reaches 13.
+
+In the meantime, silence W=1 warnings given by the current code:
+
+../lib/overflow_kunit.c:191:19: warning: 's64_tests' defined but not used [-Wunused-const-variable=]
+ 191 | DEFINE_TEST_ARRAY(s64) = {
+ | ^~~
+../lib/overflow_kunit.c:24:11: note: in definition of macro 'DEFINE_TEST_ARRAY'
+ 24 | } t ## _tests[]
+ | ^
+../lib/overflow_kunit.c:94:19: warning: 'u64_tests' defined but not used [-Wunused-const-variable=]
+ 94 | DEFINE_TEST_ARRAY(u64) = {
+ | ^~~
+../lib/overflow_kunit.c:24:11: note: in definition of macro 'DEFINE_TEST_ARRAY'
+ 24 | } t ## _tests[]
+ | ^
+
+Reported-by: kernel test robot <lkp@intel.com>
+Link: https://lore.kernel.org/lkml/202205110324.7GrtxG8u-lkp@intel.com
+Fixes: 455a35a6cdb6 ("lib: add runtime test of check_*_overflow functions")
+Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Cc: Nick Desaulniers <ndesaulniers@google.com>
+Cc: Vitor Massaru Iha <vitor@massaru.org>
+Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
+Tested-by: Daniel Latypov <dlatypov@google.com>
+Link: https://lore.kernel.org/lkml/CAGS_qxokQAjQRip2vPi80toW7hmBnXf=KMTNT51B1wuDqSZuVQ@mail.gmail.com
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/overflow_kunit.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/lib/overflow_kunit.c b/lib/overflow_kunit.c
+index 475f0c064bf6..7e3e43679b73 100644
+--- a/lib/overflow_kunit.c
++++ b/lib/overflow_kunit.c
+@@ -91,6 +91,7 @@ DEFINE_TEST_ARRAY(u32) = {
+ {-4U, 5U, 1U, -9U, -20U, true, false, true},
+ };
+
++#if BITS_PER_LONG == 64
+ DEFINE_TEST_ARRAY(u64) = {
+ {0, 0, 0, 0, 0, false, false, false},
+ {1, 1, 2, 0, 1, false, false, false},
+@@ -114,6 +115,7 @@ DEFINE_TEST_ARRAY(u64) = {
+ false, true, false},
+ {-15ULL, 10ULL, -5ULL, -25ULL, -150ULL, false, false, true},
+ };
++#endif
+
+ DEFINE_TEST_ARRAY(s8) = {
+ {0, 0, 0, 0, 0, false, false, false},
+@@ -188,6 +190,8 @@ DEFINE_TEST_ARRAY(s32) = {
+ {S32_MIN, S32_MIN, 0, 0, 0, true, false, true},
+ {S32_MAX, S32_MAX, -2, 0, 1, true, false, true},
+ };
++
++#if BITS_PER_LONG == 64
+ DEFINE_TEST_ARRAY(s64) = {
+ {0, 0, 0, 0, 0, false, false, false},
+
+@@ -216,6 +220,7 @@ DEFINE_TEST_ARRAY(s64) = {
+ {-128, -1, -129, -127, 128, false, false, false},
+ {0, -S64_MAX, -S64_MAX, S64_MAX, 0, false, false, false},
+ };
++#endif
+
+ #define check_one_op(t, fmt, op, sym, a, b, r, of) do { \
+ t _r; \
+@@ -650,6 +655,7 @@ static struct kunit_case overflow_test_cases[] = {
+ KUNIT_CASE(s16_overflow_test),
+ KUNIT_CASE(u32_overflow_test),
+ KUNIT_CASE(s32_overflow_test),
++/* Clang 13 and earlier generate unwanted libcalls on 32-bit. */
+ #if BITS_PER_LONG == 64
+ KUNIT_CASE(u64_overflow_test),
+ KUNIT_CASE(s64_overflow_test),
+--
+2.35.1
+
--- /dev/null
+From 5c56c70154c59398b276c581ce990437d34a2e88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jun 2022 14:46:31 +0900
+Subject: lib/smp_processor_id: fix imbalanced instrumentation_end() call
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+[ Upstream commit bd27acaac24e4b252ee28dddcabaee80456d0faf ]
+
+Currently instrumentation_end() won't be called if printk_ratelimit()
+returned false.
+
+Link: https://lkml.kernel.org/r/a636d8e0-ad32-5888-acac-671f7f553bb3@I-love.SAKURA.ne.jp
+Fixes: 126f21f0e8d46e2c ("lib/smp_processor_id: Move it into noinstr section")
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Alexandre Chartre <alexandre.chartre@oracle.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/smp_processor_id.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c
+index 046ac6297c78..a2bb7738c373 100644
+--- a/lib/smp_processor_id.c
++++ b/lib/smp_processor_id.c
+@@ -47,9 +47,9 @@ unsigned int check_preemption_disabled(const char *what1, const char *what2)
+
+ printk("caller is %pS\n", __builtin_return_address(0));
+ dump_stack();
+- instrumentation_end();
+
+ out_enable:
++ instrumentation_end();
+ preempt_enable_no_resched_notrace();
+ out:
+ return this_cpu;
+--
+2.35.1
+
--- /dev/null
+From ba7c244dda3be9ccc47b0711921d9f28d7ffdcf4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 21:08:35 +0800
+Subject: lib/test_hmm: avoid accessing uninitialized pages
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit ed913b055a74b723976f8e885a3395162a0371e6 ]
+
+If make_device_exclusive_range() fails or returns pages marked for
+exclusive access less than required, remaining fields of pages will left
+uninitialized. So dmirror_atomic_map() will access those yet
+uninitialized fields of pages. To fix it, do dmirror_atomic_map() iff all
+pages are marked for exclusive access (we will break if mapped is less
+than required anyway) so we won't access those uninitialized fields of
+pages.
+
+Link: https://lkml.kernel.org/r/20220609130835.35110-1-linmiaohe@huawei.com
+Fixes: b659baea7546 ("mm: selftests for exclusive device memory")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Jerome Glisse <jglisse@redhat.com>
+Cc: Alistair Popple <apopple@nvidia.com>
+Cc: Jason Gunthorpe <jgg@ziepe.ca>
+Cc: Ralph Campbell <rcampbell@nvidia.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/test_hmm.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/lib/test_hmm.c b/lib/test_hmm.c
+index cfe632047839..f2c3015c5c82 100644
+--- a/lib/test_hmm.c
++++ b/lib/test_hmm.c
+@@ -732,7 +732,7 @@ static int dmirror_exclusive(struct dmirror *dmirror,
+
+ mmap_read_lock(mm);
+ for (addr = start; addr < end; addr = next) {
+- unsigned long mapped;
++ unsigned long mapped = 0;
+ int i;
+
+ if (end < addr + (ARRAY_SIZE(pages) << PAGE_SHIFT))
+@@ -741,7 +741,13 @@ static int dmirror_exclusive(struct dmirror *dmirror,
+ next = addr + (ARRAY_SIZE(pages) << PAGE_SHIFT);
+
+ ret = make_device_exclusive_range(mm, addr, next, pages, NULL);
+- mapped = dmirror_atomic_map(addr, next, pages, dmirror);
++ /*
++ * Do dmirror_atomic_map() iff all pages are marked for
++ * exclusive access to avoid accessing uninitialized
++ * fields of pages.
++ */
++ if (ret == (next - addr) >> PAGE_SHIFT)
++ mapped = dmirror_atomic_map(addr, next, pages, dmirror);
+ for (i = 0; i < ret; i++) {
+ if (pages[i]) {
+ unlock_page(pages[i]);
+--
+2.35.1
+
--- /dev/null
+From 5bf9ad4fafdd9956d2a14e27450a75bb8041cd69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 12:51:28 +0300
+Subject: libbpf: fix an snprintf() overflow check
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit b77ffb30cfc5f58e957571d8541c6a7e3da19221 ]
+
+The snprintf() function returns the number of bytes it *would* have
+copied if there were enough space. So it can return > the
+sizeof(gen->attach_target).
+
+Fixes: 67234743736a ("libbpf: Generate loader program out of BPF ELF file.")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Martin KaFai Lau <kafai@fb.com>
+Link: https://lore.kernel.org/r/YtZ+oAySqIhFl6/J@kili
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/gen_loader.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/lib/bpf/gen_loader.c b/tools/lib/bpf/gen_loader.c
+index 927745b08014..23f5c46708f8 100644
+--- a/tools/lib/bpf/gen_loader.c
++++ b/tools/lib/bpf/gen_loader.c
+@@ -533,7 +533,7 @@ void bpf_gen__record_attach_target(struct bpf_gen *gen, const char *attach_name,
+ gen->attach_kind = kind;
+ ret = snprintf(gen->attach_target, sizeof(gen->attach_target), "%s%s",
+ prefix, attach_name);
+- if (ret == sizeof(gen->attach_target))
++ if (ret >= sizeof(gen->attach_target))
+ gen->error = -ENOSPC;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From ff57b7434648db7d1471b7435525c922d1c7f0b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 11:15:40 +0800
+Subject: libbpf: Fix the name of a reused map
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Anquan Wu <leiqi96@hotmail.com>
+
+[ Upstream commit bf3f00378524adae16628cbadbd11ba7211863bb ]
+
+BPF map name is limited to BPF_OBJ_NAME_LEN.
+A map name is defined as being longer than BPF_OBJ_NAME_LEN,
+it will be truncated to BPF_OBJ_NAME_LEN when a userspace program
+calls libbpf to create the map. A pinned map also generates a path
+in the /sys. If the previous program wanted to reuse the map,
+it can not get bpf_map by name, because the name of the map is only
+partially the same as the name which get from pinned path.
+
+The syscall information below show that map name "process_pinned_map"
+is truncated to "process_pinned_".
+
+ bpf(BPF_OBJ_GET, {pathname="/sys/fs/bpf/process_pinned_map",
+ bpf_fd=0, file_flags=0}, 144) = -1 ENOENT (No such file or directory)
+
+ bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_HASH, key_size=4,
+ value_size=4,max_entries=1024, map_flags=0, inner_map_fd=0,
+ map_name="process_pinned_",map_ifindex=0, btf_fd=3, btf_key_type_id=6,
+ btf_value_type_id=10,btf_vmlinux_value_type_id=0}, 72) = 4
+
+This patch check that if the name of pinned map are the same as the
+actual name for the first (BPF_OBJ_NAME_LEN - 1),
+bpf map still uses the name which is included in bpf object.
+
+Fixes: 26736eb9a483 ("tools: libbpf: allow map reuse")
+Signed-off-by: Anquan Wu <leiqi96@hotmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/OSZP286MB1725CEA1C95C5CB8E7CCC53FB8869@OSZP286MB1725.JPNP286.PROD.OUTLOOK.COM
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index 881ea905ca81..2323d3e38a8e 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -4271,7 +4271,7 @@ static int bpf_get_map_info_from_fdinfo(int fd, struct bpf_map_info *info)
+ int bpf_map__reuse_fd(struct bpf_map *map, int fd)
+ {
+ struct bpf_map_info info = {};
+- __u32 len = sizeof(info);
++ __u32 len = sizeof(info), name_len;
+ int new_fd, err;
+ char *new_name;
+
+@@ -4281,7 +4281,12 @@ int bpf_map__reuse_fd(struct bpf_map *map, int fd)
+ if (err)
+ return libbpf_err(err);
+
+- new_name = strdup(info.name);
++ name_len = strlen(info.name);
++ if (name_len == BPF_OBJ_NAME_LEN - 1 && strncmp(map->name, info.name, name_len) == 0)
++ new_name = strdup(map->name);
++ else
++ new_name = strdup(info.name);
++
+ if (!new_name)
+ return libbpf_err(-errno);
+
+--
+2.35.1
+
--- /dev/null
+From b2d6cf06eb598a55e781da0471848bc99574c29f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 22:02:04 +0800
+Subject: libbpf, riscv: Use a0 for RC register
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yixun Lan <dlan@gentoo.org>
+
+[ Upstream commit 935dc35c75318fa213d26808ad8bb130fb0b486e ]
+
+According to the RISC-V calling convention register usage here [0], a0
+is used as return value register, so rename it to make it consistent
+with the spec.
+
+ [0] section 18.2, table 18.2
+ https://riscv.org/wp-content/uploads/2015/01/riscv-calling.pdf
+
+Fixes: 589fed479ba1 ("riscv, libbpf: Add RISC-V (RV64) support to bpf_tracing.h")
+Signed-off-by: Yixun Lan <dlan@gentoo.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Björn Töpel <bjorn@kernel.org>
+Acked-by: Amjad OULED-AMEUR <ouledameur.amjad@gmail.com>
+Link: https://lore.kernel.org/bpf/20220706140204.47926-1-dlan@gentoo.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/bpf_tracing.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/lib/bpf/bpf_tracing.h b/tools/lib/bpf/bpf_tracing.h
+index e3a8c947e89f..479f514f7411 100644
+--- a/tools/lib/bpf/bpf_tracing.h
++++ b/tools/lib/bpf/bpf_tracing.h
+@@ -227,7 +227,7 @@ struct pt_regs___arm64 {
+ #define __PT_PARM5_REG a4
+ #define __PT_RET_REG ra
+ #define __PT_FP_REG s0
+-#define __PT_RC_REG a5
++#define __PT_RC_REG a0
+ #define __PT_SP_REG sp
+ #define __PT_IP_REG pc
+ /* riscv does not select ARCH_HAS_SYSCALL_WRAPPER. */
+--
+2.35.1
+
--- /dev/null
+From db569d608113eaa463b83db7761f0884cfc76028 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 15:26:06 +0200
+Subject: locking/lockdep: Fix lockdep_init_map_*() confusion
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit eae6d58d67d9739be5f7ae2dbead1d0ef6528243 ]
+
+Commit dfd5e3f5fe27 ("locking/lockdep: Mark local_lock_t") added yet
+another lockdep_init_map_*() variant, but forgot to update all the
+existing users of the most complicated version.
+
+This could lead to a loss of lock_type and hence an incorrect report.
+Given the relative rarity of both local_lock and these annotations,
+this is unlikely to happen in practise, still, best fix things.
+
+Fixes: dfd5e3f5fe27 ("locking/lockdep: Mark local_lock_t")
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/YqyEDtoan20K0CVD@worktop.programming.kicks-ass.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/lockdep.h | 30 +++++++++++++++++-------------
+ kernel/locking/lockdep.c | 7 ++++---
+ 2 files changed, 21 insertions(+), 16 deletions(-)
+
+diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
+index 467b94257105..0a9afe84ea44 100644
+--- a/include/linux/lockdep.h
++++ b/include/linux/lockdep.h
+@@ -192,7 +192,7 @@ static inline void
+ lockdep_init_map_waits(struct lockdep_map *lock, const char *name,
+ struct lock_class_key *key, int subclass, u8 inner, u8 outer)
+ {
+- lockdep_init_map_type(lock, name, key, subclass, inner, LD_WAIT_INV, LD_LOCK_NORMAL);
++ lockdep_init_map_type(lock, name, key, subclass, inner, outer, LD_LOCK_NORMAL);
+ }
+
+ static inline void
+@@ -215,24 +215,28 @@ static inline void lockdep_init_map(struct lockdep_map *lock, const char *name,
+ * or they are too narrow (they suffer from a false class-split):
+ */
+ #define lockdep_set_class(lock, key) \
+- lockdep_init_map_waits(&(lock)->dep_map, #key, key, 0, \
+- (lock)->dep_map.wait_type_inner, \
+- (lock)->dep_map.wait_type_outer)
++ lockdep_init_map_type(&(lock)->dep_map, #key, key, 0, \
++ (lock)->dep_map.wait_type_inner, \
++ (lock)->dep_map.wait_type_outer, \
++ (lock)->dep_map.lock_type)
+
+ #define lockdep_set_class_and_name(lock, key, name) \
+- lockdep_init_map_waits(&(lock)->dep_map, name, key, 0, \
+- (lock)->dep_map.wait_type_inner, \
+- (lock)->dep_map.wait_type_outer)
++ lockdep_init_map_type(&(lock)->dep_map, name, key, 0, \
++ (lock)->dep_map.wait_type_inner, \
++ (lock)->dep_map.wait_type_outer, \
++ (lock)->dep_map.lock_type)
+
+ #define lockdep_set_class_and_subclass(lock, key, sub) \
+- lockdep_init_map_waits(&(lock)->dep_map, #key, key, sub,\
+- (lock)->dep_map.wait_type_inner, \
+- (lock)->dep_map.wait_type_outer)
++ lockdep_init_map_type(&(lock)->dep_map, #key, key, sub, \
++ (lock)->dep_map.wait_type_inner, \
++ (lock)->dep_map.wait_type_outer, \
++ (lock)->dep_map.lock_type)
+
+ #define lockdep_set_subclass(lock, sub) \
+- lockdep_init_map_waits(&(lock)->dep_map, #lock, (lock)->dep_map.key, sub,\
+- (lock)->dep_map.wait_type_inner, \
+- (lock)->dep_map.wait_type_outer)
++ lockdep_init_map_type(&(lock)->dep_map, #lock, (lock)->dep_map.key, sub,\
++ (lock)->dep_map.wait_type_inner, \
++ (lock)->dep_map.wait_type_outer, \
++ (lock)->dep_map.lock_type)
+
+ #define lockdep_set_novalidate_class(lock) \
+ lockdep_set_class_and_name(lock, &__lockdep_no_validate__, #lock)
+diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
+index c06cab6546ed..e45ec82b42e6 100644
+--- a/kernel/locking/lockdep.c
++++ b/kernel/locking/lockdep.c
+@@ -5214,9 +5214,10 @@ __lock_set_class(struct lockdep_map *lock, const char *name,
+ return 0;
+ }
+
+- lockdep_init_map_waits(lock, name, key, 0,
+- lock->wait_type_inner,
+- lock->wait_type_outer);
++ lockdep_init_map_type(lock, name, key, 0,
++ lock->wait_type_inner,
++ lock->wait_type_outer,
++ lock->lock_type);
+ class = register_lock_class(lock, subclass, 0);
+ hlock->class_idx = class - lock_classes;
+
+--
+2.35.1
+
--- /dev/null
+From 568c98574b632725c7a58475ae8a2f5a30b8623b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Apr 2022 13:34:53 +0200
+Subject: media: amphion: decoder copy timestamp from output to capture
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit a4dca209f23470f20b61b40cca417a5bf6ea8533 ]
+
+copy the timestamp using the helper function
+V4L2_BUF_FLAG_TIMESTAMP_COPY
+
+To implement this, driver will keep the output buffer until it's
+decoded, in previous, driver will return the output buffer immediately
+after copying data to stream buffer.
+
+After that, there is no need to make a workaround for poll function.
+driver can use v4l2_m2m_fop_poll directly.
+Also, driver don't need to keep a input threshold
+as the buffer count is up to only 32.
+
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/vdec.c | 76 ++++++++-------------
+ drivers/media/platform/amphion/vpu_malone.c | 2 +-
+ drivers/media/platform/amphion/vpu_v4l2.c | 56 +++++++++++++++
+ drivers/media/platform/amphion/vpu_v4l2.h | 3 +
+ 4 files changed, 87 insertions(+), 50 deletions(-)
+
+diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
+index a91f88fdb5ef..052a60189c13 100644
+--- a/drivers/media/platform/amphion/vdec.c
++++ b/drivers/media/platform/amphion/vdec.c
+@@ -26,8 +26,8 @@
+ #include "vpu_cmds.h"
+ #include "vpu_rpc.h"
+
+-#define VDEC_FRAME_DEPTH 256
+ #define VDEC_MIN_BUFFER_CAP 8
++#define VDEC_MIN_BUFFER_OUT 8
+
+ struct vdec_fs_info {
+ char name[8];
+@@ -63,8 +63,6 @@ struct vdec_t {
+ bool is_source_changed;
+ u32 source_change;
+ u32 drain;
+- u32 ts_pre_count;
+- u32 frame_depth;
+ };
+
+ static const struct vpu_format vdec_formats[] = {
+@@ -475,7 +473,7 @@ static int vdec_drain(struct vpu_inst *inst)
+ if (!vdec->drain)
+ return 0;
+
+- if (v4l2_m2m_num_src_bufs_ready(inst->fh.m2m_ctx))
++ if (!vpu_is_source_empty(inst))
+ return 0;
+
+ if (!vdec->params.frame_count) {
+@@ -598,11 +596,8 @@ static bool vdec_check_ready(struct vpu_inst *inst, unsigned int type)
+ {
+ struct vdec_t *vdec = inst->priv;
+
+- if (V4L2_TYPE_IS_OUTPUT(type)) {
+- if (vdec->ts_pre_count >= vdec->frame_depth)
+- return false;
++ if (V4L2_TYPE_IS_OUTPUT(type))
+ return true;
+- }
+
+ if (vdec->req_frame_count)
+ return true;
+@@ -610,12 +605,21 @@ static bool vdec_check_ready(struct vpu_inst *inst, unsigned int type)
+ return false;
+ }
+
++static struct vb2_v4l2_buffer *vdec_get_src_buffer(struct vpu_inst *inst, u32 count)
++{
++ if (count > 1)
++ vpu_skip_frame(inst, count - 1);
++
++ return vpu_next_src_buf(inst);
++}
++
+ static int vdec_frame_decoded(struct vpu_inst *inst, void *arg)
+ {
+ struct vdec_t *vdec = inst->priv;
+ struct vpu_dec_pic_info *info = arg;
+ struct vpu_vb2_buffer *vpu_buf;
+ struct vb2_v4l2_buffer *vbuf;
++ struct vb2_v4l2_buffer *src_buf;
+ int ret = 0;
+
+ if (!info || info->id >= ARRAY_SIZE(vdec->slots))
+@@ -629,14 +633,21 @@ static int vdec_frame_decoded(struct vpu_inst *inst, void *arg)
+ goto exit;
+ }
+ vbuf = &vpu_buf->m2m_buf.vb;
++ src_buf = vdec_get_src_buffer(inst, info->consumed_count);
++ if (src_buf) {
++ v4l2_m2m_buf_copy_metadata(src_buf, vbuf, true);
++ if (info->consumed_count) {
++ v4l2_m2m_src_buf_remove(inst->fh.m2m_ctx);
++ vpu_set_buffer_state(src_buf, VPU_BUF_STATE_IDLE);
++ v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
++ } else {
++ vpu_set_buffer_state(src_buf, VPU_BUF_STATE_DECODED);
++ }
++ }
+ if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED)
+ dev_info(inst->dev, "[%d] buf[%d] has been decoded\n", inst->id, info->id);
+ vpu_set_buffer_state(vbuf, VPU_BUF_STATE_DECODED);
+ vdec->decoded_frame_count++;
+- if (vdec->ts_pre_count >= info->consumed_count)
+- vdec->ts_pre_count -= info->consumed_count;
+- else
+- vdec->ts_pre_count = 0;
+ exit:
+ vpu_inst_unlock(inst);
+
+@@ -692,10 +703,9 @@ static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
+ vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY);
+ vb2_set_plane_payload(&vbuf->vb2_buf, 0, inst->cap_format.sizeimage[0]);
+ vb2_set_plane_payload(&vbuf->vb2_buf, 1, inst->cap_format.sizeimage[1]);
+- vbuf->vb2_buf.timestamp = frame->timestamp;
+ vbuf->field = inst->cap_format.field;
+ vbuf->sequence = sequence;
+- dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, frame->timestamp);
++ dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);
+
+ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+ vpu_inst_lock(inst);
+@@ -717,7 +727,6 @@ static void vdec_stop_done(struct vpu_inst *inst)
+ vdec->fixed_fmt = false;
+ vdec->params.end_flag = 0;
+ vdec->drain = 0;
+- vdec->ts_pre_count = 0;
+ vdec->params.frame_count = 0;
+ vdec->decoded_frame_count = 0;
+ vdec->display_frame_count = 0;
+@@ -1252,18 +1261,14 @@ static int vdec_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)
+ if (free_space < vb2_get_plane_payload(vb, 0) + 0x40000)
+ return -ENOMEM;
+
++ vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
+ ret = vpu_iface_input_frame(inst, vb);
+ if (ret < 0)
+ return -ENOMEM;
+
+ dev_dbg(inst->dev, "[%d][INPUT TS]%32lld\n", inst->id, vb->timestamp);
+- vdec->ts_pre_count++;
+ vdec->params.frame_count++;
+
+- v4l2_m2m_src_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
+- vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+- v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+-
+ if (vdec->drain)
+ vdec_drain(inst);
+
+@@ -1326,7 +1331,6 @@ static void vdec_abort(struct vpu_inst *inst)
+ vdec->sequence);
+ vdec->params.end_flag = 0;
+ vdec->drain = 0;
+- vdec->ts_pre_count = 0;
+ vdec->params.frame_count = 0;
+ vdec->decoded_frame_count = 0;
+ vdec->display_frame_count = 0;
+@@ -1533,10 +1537,6 @@ static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i
+ vdec->drain, vdec->eos_received, vdec->source_change);
+ break;
+ case 8:
+- num = scnprintf(str, size, "ts_pre_count = %d, frame_depth = %d\n",
+- vdec->ts_pre_count, vdec->frame_depth);
+- break;
+- case 9:
+ num = scnprintf(str, size, "fps = %d/%d\n",
+ vdec->codec_info.frame_rate.numerator,
+ vdec->codec_info.frame_rate.denominator);
+@@ -1570,12 +1570,8 @@ static struct vpu_inst_ops vdec_inst_ops = {
+ static void vdec_init(struct file *file)
+ {
+ struct vpu_inst *inst = to_inst(file);
+- struct vdec_t *vdec;
+ struct v4l2_format f;
+
+- vdec = inst->priv;
+- vdec->frame_depth = VDEC_FRAME_DEPTH;
+-
+ memset(&f, 0, sizeof(f));
+ f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+@@ -1620,36 +1616,18 @@ static int vdec_open(struct file *file)
+
+ vdec->fixed_fmt = false;
+ inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP;
++ inst->min_buffer_out = VDEC_MIN_BUFFER_OUT;
+ vdec_init(file);
+
+ return 0;
+ }
+
+-static __poll_t vdec_poll(struct file *file, poll_table *wait)
+-{
+- struct vpu_inst *inst = to_inst(file);
+- struct vb2_queue *src_q, *dst_q;
+- __poll_t ret;
+-
+- ret = v4l2_m2m_fop_poll(file, wait);
+- src_q = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
+- dst_q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+- if (vb2_is_streaming(src_q) && !vb2_is_streaming(dst_q))
+- ret &= (~EPOLLERR);
+- if (!src_q->error && !dst_q->error &&
+- (vb2_is_streaming(src_q) && list_empty(&src_q->queued_list)) &&
+- (vb2_is_streaming(dst_q) && list_empty(&dst_q->queued_list)))
+- ret &= (~EPOLLERR);
+-
+- return ret;
+-}
+-
+ static const struct v4l2_file_operations vdec_fops = {
+ .owner = THIS_MODULE,
+ .open = vdec_open,
+ .release = vpu_v4l2_close,
+ .unlocked_ioctl = video_ioctl2,
+- .poll = vdec_poll,
++ .poll = v4l2_m2m_fop_poll,
+ .mmap = v4l2_m2m_fop_mmap,
+ };
+
+diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
+index d91be0ece961..5ca8afb60afc 100644
+--- a/drivers/media/platform/amphion/vpu_malone.c
++++ b/drivers/media/platform/amphion/vpu_malone.c
+@@ -1558,7 +1558,7 @@ int vpu_malone_input_frame(struct vpu_shared_addr *shared,
+ * merge the data to next frame
+ */
+ vbuf = to_vb2_v4l2_buffer(vb);
+- if (vpu_vb_is_codecconfig(vbuf) && (s64)vb->timestamp < 0) {
++ if (vpu_vb_is_codecconfig(vbuf)) {
+ inst->extra_size += size;
+ return 0;
+ }
+diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
+index 5584b3848107..0f3726c80967 100644
+--- a/drivers/media/platform/amphion/vpu_v4l2.c
++++ b/drivers/media/platform/amphion/vpu_v4l2.c
+@@ -127,6 +127,19 @@ int vpu_set_last_buffer_dequeued(struct vpu_inst *inst)
+ return 0;
+ }
+
++bool vpu_is_source_empty(struct vpu_inst *inst)
++{
++ struct v4l2_m2m_buffer *buf = NULL;
++
++ if (!inst->fh.m2m_ctx)
++ return true;
++ v4l2_m2m_for_each_src_buf(inst->fh.m2m_ctx, buf) {
++ if (vpu_get_buffer_state(&buf->vb) == VPU_BUF_STATE_IDLE)
++ return false;
++ }
++ return true;
++}
++
+ const struct vpu_format *vpu_try_fmt_common(struct vpu_inst *inst, struct v4l2_format *f)
+ {
+ struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+@@ -234,6 +247,49 @@ int vpu_process_capture_buffer(struct vpu_inst *inst)
+ return call_vop(inst, process_capture, &vbuf->vb2_buf);
+ }
+
++struct vb2_v4l2_buffer *vpu_next_src_buf(struct vpu_inst *inst)
++{
++ struct vb2_v4l2_buffer *src_buf = v4l2_m2m_next_src_buf(inst->fh.m2m_ctx);
++
++ if (!src_buf || vpu_get_buffer_state(src_buf) == VPU_BUF_STATE_IDLE)
++ return NULL;
++
++ while (vpu_vb_is_codecconfig(src_buf)) {
++ v4l2_m2m_src_buf_remove(inst->fh.m2m_ctx);
++ vpu_set_buffer_state(src_buf, VPU_BUF_STATE_IDLE);
++ v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
++
++ src_buf = v4l2_m2m_next_src_buf(inst->fh.m2m_ctx);
++ if (!src_buf || vpu_get_buffer_state(src_buf) == VPU_BUF_STATE_IDLE)
++ return NULL;
++ }
++
++ return src_buf;
++}
++
++void vpu_skip_frame(struct vpu_inst *inst, int count)
++{
++ struct vb2_v4l2_buffer *src_buf;
++ enum vb2_buffer_state state;
++ int i = 0;
++
++ if (count <= 0)
++ return;
++
++ while (i < count) {
++ src_buf = v4l2_m2m_src_buf_remove(inst->fh.m2m_ctx);
++ if (!src_buf || vpu_get_buffer_state(src_buf) == VPU_BUF_STATE_IDLE)
++ return;
++ if (vpu_get_buffer_state(src_buf) == VPU_BUF_STATE_DECODED)
++ state = VB2_BUF_STATE_DONE;
++ else
++ state = VB2_BUF_STATE_ERROR;
++ i++;
++ vpu_set_buffer_state(src_buf, VPU_BUF_STATE_IDLE);
++ v4l2_m2m_buf_done(src_buf, state);
++ }
++}
++
+ struct vb2_v4l2_buffer *vpu_find_buf_by_sequence(struct vpu_inst *inst, u32 type, u32 sequence)
+ {
+ struct v4l2_m2m_buffer *buf = NULL;
+diff --git a/drivers/media/platform/amphion/vpu_v4l2.h b/drivers/media/platform/amphion/vpu_v4l2.h
+index 90fa7ea67495..795ca33a6a50 100644
+--- a/drivers/media/platform/amphion/vpu_v4l2.h
++++ b/drivers/media/platform/amphion/vpu_v4l2.h
+@@ -19,6 +19,8 @@ int vpu_v4l2_close(struct file *file);
+ const struct vpu_format *vpu_try_fmt_common(struct vpu_inst *inst, struct v4l2_format *f);
+ int vpu_process_output_buffer(struct vpu_inst *inst);
+ int vpu_process_capture_buffer(struct vpu_inst *inst);
++struct vb2_v4l2_buffer *vpu_next_src_buf(struct vpu_inst *inst);
++void vpu_skip_frame(struct vpu_inst *inst, int count);
+ struct vb2_v4l2_buffer *vpu_find_buf_by_sequence(struct vpu_inst *inst, u32 type, u32 sequence);
+ struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst, u32 type, u32 idx);
+ void vpu_v4l2_set_error(struct vpu_inst *inst);
+@@ -27,6 +29,7 @@ int vpu_notify_source_change(struct vpu_inst *inst);
+ int vpu_set_last_buffer_dequeued(struct vpu_inst *inst);
+ void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type, enum vb2_buffer_state state);
+ int vpu_get_num_buffers(struct vpu_inst *inst, u32 type);
++bool vpu_is_source_empty(struct vpu_inst *inst);
+
+ dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no);
+ unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no);
+--
+2.35.1
+
--- /dev/null
+From 993a9e4ced0d09b1134f93e7898a4c14dca2c721 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jun 2022 06:21:12 +0100
+Subject: media: amphion: defer setting last_buffer_dequeued until resolution
+ changes are processed
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit afba6e20801ad9a2f863c52c21e609e021269d83 ]
+
+Don't set last_buffer_dequeued during dynamic resolution change,
+otherwise it may be cleared in handling resolution change,
+as streamoff may be called in dynamic resolution change.
+
+Normally, this does not happen.
+But we encounter a special testcase,
+User issue V4L2_DEC_CMD_STOP after enqueue one buffer
+that only contains codec config header, but not any frame data.
+So VPU report the parsed resolution, then report the eos event.
+
+So driver should notify user to handle resolution change first,
+after it's handled, set the last_buffer_dequeued.
+then the user can exit decoding normally.
+
+Otherwise the user may be stalled.
+
+Fixes: 6de8d628df6ef ("media: amphion: add v4l2 m2m vpu decoder stateful driver")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/vdec.c | 36 ++++++++++++++---------
+ drivers/media/platform/amphion/vpu_v4l2.c | 2 +-
+ 2 files changed, 23 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
+index c0dfede11ab7..a91f88fdb5ef 100644
+--- a/drivers/media/platform/amphion/vdec.c
++++ b/drivers/media/platform/amphion/vdec.c
+@@ -174,16 +174,6 @@ static int vdec_ctrl_init(struct vpu_inst *inst)
+ return 0;
+ }
+
+-static void vdec_set_last_buffer_dequeued(struct vpu_inst *inst)
+-{
+- struct vdec_t *vdec = inst->priv;
+-
+- if (vdec->eos_received) {
+- if (!vpu_set_last_buffer_dequeued(inst))
+- vdec->eos_received--;
+- }
+-}
+-
+ static void vdec_handle_resolution_change(struct vpu_inst *inst)
+ {
+ struct vdec_t *vdec = inst->priv;
+@@ -230,6 +220,21 @@ static int vdec_update_state(struct vpu_inst *inst, enum vpu_codec_state state,
+ return 0;
+ }
+
++static void vdec_set_last_buffer_dequeued(struct vpu_inst *inst)
++{
++ struct vdec_t *vdec = inst->priv;
++
++ if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
++ return;
++
++ if (vdec->eos_received) {
++ if (!vpu_set_last_buffer_dequeued(inst)) {
++ vdec->eos_received--;
++ vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0);
++ }
++ }
++}
++
+ static int vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+ {
+ strscpy(cap->driver, "amphion-vpu", sizeof(cap->driver));
+@@ -489,6 +494,8 @@ static int vdec_drain(struct vpu_inst *inst)
+
+ static int vdec_cmd_start(struct vpu_inst *inst)
+ {
++ struct vdec_t *vdec = inst->priv;
++
+ switch (inst->state) {
+ case VPU_CODEC_STATE_STARTED:
+ case VPU_CODEC_STATE_DRAIN:
+@@ -499,6 +506,8 @@ static int vdec_cmd_start(struct vpu_inst *inst)
+ break;
+ }
+ vpu_process_capture_buffer(inst);
++ if (vdec->eos_received)
++ vdec_set_last_buffer_dequeued(inst);
+ return 0;
+ }
+
+@@ -1188,7 +1197,6 @@ static void vdec_event_eos(struct vpu_inst *inst)
+ vdec->eos_received++;
+ vdec->fixed_fmt = false;
+ inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP;
+- vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0);
+ vdec_set_last_buffer_dequeued(inst);
+ vpu_inst_unlock(inst);
+ }
+@@ -1470,10 +1478,10 @@ static int vdec_stop_session(struct vpu_inst *inst, u32 type)
+ vdec_update_state(inst, VPU_CODEC_STATE_SEEK, 0);
+ vdec->drain = 0;
+ } else {
+- if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
++ if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) {
+ vdec_abort(inst);
+-
+- vdec->eos_received = 0;
++ vdec->eos_received = 0;
++ }
+ vdec_clear_slots(inst);
+ }
+
+diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
+index 4183a3994d30..5584b3848107 100644
+--- a/drivers/media/platform/amphion/vpu_v4l2.c
++++ b/drivers/media/platform/amphion/vpu_v4l2.c
+@@ -440,8 +440,8 @@ static int vpu_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
+ fmt->sizeimage[1], fmt->bytesperline[1],
+ fmt->sizeimage[2], fmt->bytesperline[2],
+ q->num_buffers);
+- ret = call_vop(inst, start, q->type);
+ vb2_clear_last_buffer_dequeued(q);
++ ret = call_vop(inst, start, q->type);
+ if (ret)
+ vpu_vb2_buffers_return(inst, q->type, VB2_BUF_STATE_QUEUED);
+
+--
+2.35.1
+
--- /dev/null
+From d5488fb8dcf7adefbb95f46c51ff973a7b5a3179 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 09:56:50 +0100
+Subject: media: amphion: only insert the first sequence startcode for vc1l
+ format
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit e670f5d672ef3d00b0b8c69eff09a019e6dd4ef9 ]
+
+For format V4L2_PIX_FMT_VC1_ANNEX_L,
+the amphion vpu requires driver to help insert some custom startcode
+before sequence and frame.
+but only the first sequence startcode is needed,
+the extra startcode will cause decoding error.
+So after seek, we don't need to insert the sequence startcode.
+
+In other words, for V4L2_PIX_FMT_VC1_ANNEX_L,
+the vpu doesn't support dynamic resolution change.
+
+Fixes: 145e936380edb ("media: amphion: implement malone decoder rpc interface")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/vdec.c | 2 +-
+ drivers/media/platform/amphion/vpu.h | 1 +
+ drivers/media/platform/amphion/vpu_malone.c | 2 ++
+ drivers/media/platform/amphion/vpu_rpc.h | 7 ++++++-
+ 4 files changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
+index dd7ea23902c0..36450a2e85c9 100644
+--- a/drivers/media/platform/amphion/vdec.c
++++ b/drivers/media/platform/amphion/vdec.c
+@@ -105,7 +105,6 @@ static const struct vpu_format vdec_formats[] = {
+ .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L,
+ .num_planes = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+- .flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+ },
+ {
+ .pixfmt = V4L2_PIX_FMT_MPEG2,
+@@ -735,6 +734,7 @@ static void vdec_stop_done(struct vpu_inst *inst)
+ vdec->eos_received = 0;
+ vdec->is_source_changed = false;
+ vdec->source_change = 0;
++ inst->total_input_count = 0;
+ vpu_inst_unlock(inst);
+ }
+
+diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h
+index e56b96a7e5d3..f914de6ed81e 100644
+--- a/drivers/media/platform/amphion/vpu.h
++++ b/drivers/media/platform/amphion/vpu.h
+@@ -258,6 +258,7 @@ struct vpu_inst {
+ struct vpu_format cap_format;
+ u32 min_buffer_cap;
+ u32 min_buffer_out;
++ u32 total_input_count;
+
+ struct v4l2_rect crop;
+ u32 colorspace;
+diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
+index 5ca8afb60afc..7f591805c48c 100644
+--- a/drivers/media/platform/amphion/vpu_malone.c
++++ b/drivers/media/platform/amphion/vpu_malone.c
+@@ -1296,6 +1296,8 @@ static int vpu_malone_insert_scode_vc1_l_seq(struct malone_scode_t *scode)
+ int size = 0;
+ u8 rcv_seqhdr[MALONE_VC1_RCV_SEQ_HEADER_LEN];
+
++ if (scode->inst->total_input_count)
++ return 0;
+ scode->need_data = 0;
+
+ ret = vpu_malone_insert_scode_seq(scode, MALONE_CODEC_ID_VC1_SIMPLE, sizeof(rcv_seqhdr));
+diff --git a/drivers/media/platform/amphion/vpu_rpc.h b/drivers/media/platform/amphion/vpu_rpc.h
+index 25119e5e807e..7eb6f01e6ab5 100644
+--- a/drivers/media/platform/amphion/vpu_rpc.h
++++ b/drivers/media/platform/amphion/vpu_rpc.h
+@@ -312,11 +312,16 @@ static inline int vpu_iface_input_frame(struct vpu_inst *inst,
+ struct vb2_buffer *vb)
+ {
+ struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
++ int ret;
+
+ if (!ops || !ops->input_frame)
+ return -EINVAL;
+
+- return ops->input_frame(inst->core->iface, inst, vb);
++ ret = ops->input_frame(inst->core->iface, inst, vb);
++ if (ret < 0)
++ return ret;
++ inst->total_input_count++;
++ return ret;
+ }
+
+ static inline int vpu_iface_config_memory_resource(struct vpu_inst *inst,
+--
+2.35.1
+
--- /dev/null
+From fa7bbd971dcfb0bb74346aced5348bf44df63fc8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 07:26:11 +0100
+Subject: media: amphion: output firmware error message
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 89e3f3fb3d9014efa59ed6bb526d5f1a00168452 ]
+
+Firmware may send the error event with some error message,
+and it help locate the firmware error,
+so output the error message if it exists
+
+Fixes: 61cbf1c1fa6d7 ("media: amphion: implement vpu core communication based on mailbox")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/vpu_msgs.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/amphion/vpu_msgs.c b/drivers/media/platform/amphion/vpu_msgs.c
+index 58502c51ddb3..077644bc1d7c 100644
+--- a/drivers/media/platform/amphion/vpu_msgs.c
++++ b/drivers/media/platform/amphion/vpu_msgs.c
+@@ -150,7 +150,12 @@ static void vpu_session_handle_eos(struct vpu_inst *inst, struct vpu_rpc_event *
+
+ static void vpu_session_handle_error(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+ {
+- dev_err(inst->dev, "unsupported stream\n");
++ char *str = (char *)pkt->data;
++
++ if (strlen(str))
++ dev_err(inst->dev, "instance %d firmware error : %s\n", inst->id, str);
++ else
++ dev_err(inst->dev, "instance %d is unsupported stream\n", inst->id);
+ call_void_vop(inst, event_notify, VPU_MSG_ID_UNSUPPORTED, NULL);
+ vpu_v4l2_set_error(inst);
+ }
+--
+2.35.1
+
--- /dev/null
+From 0960283cddc33bb2ec1fd7123c3da902225c1333 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jun 2022 06:19:52 +0100
+Subject: media: amphion: release core lock before reset vpu core
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit a621cc4bed97e49f5a8019f5215dec7e208a7c4d ]
+
+In reset vpu core, driver will wait for a response event,
+but if there are still some events unhandled,
+they will be handled first, driver may acquire core lock for that.
+So if we do reset in core lock, it may led to reset timeout.
+
+Fixes: 9f599f351e86a ("media: amphion: add vpu core driver")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/vpu_core.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c
+index 68ad183925fd..51a764713159 100644
+--- a/drivers/media/platform/amphion/vpu_core.c
++++ b/drivers/media/platform/amphion/vpu_core.c
+@@ -455,8 +455,13 @@ int vpu_inst_unregister(struct vpu_inst *inst)
+ }
+ vpu_core_check_hang(core);
+ if (core->state == VPU_CORE_HANG && !core->instance_mask) {
++ int err;
++
+ dev_info(core->dev, "reset hang core\n");
+- if (!vpu_core_sw_reset(core)) {
++ mutex_unlock(&core->lock);
++ err = vpu_core_sw_reset(core);
++ mutex_lock(&core->lock);
++ if (!err) {
+ core->state = VPU_CORE_ACTIVE;
+ core->hang_mask = 0;
+ }
+--
+2.35.1
+
--- /dev/null
+From 483dc8d1782af5c6de3d0cd83dd73007c0395edc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 10:27:59 +0100
+Subject: media: amphion: return error if format is unsupported by vpu
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit a3a2efca36a3a1ddba229a7be7991e8b5de4ac35 ]
+
+return error if format is unsupported by vpu,
+otherwise the vpu will be stalled at decoding
+
+Fixes: 3cd084519c6f9 ("media: amphion: add vpu v4l2 m2m support")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/vpu_malone.c | 2 ++
+ drivers/media/platform/amphion/vpu_v4l2.c | 6 ++++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
+index 446a9de0cc11..d91be0ece961 100644
+--- a/drivers/media/platform/amphion/vpu_malone.c
++++ b/drivers/media/platform/amphion/vpu_malone.c
+@@ -609,6 +609,8 @@ static int vpu_malone_set_params(struct vpu_shared_addr *shared,
+ enum vpu_malone_format malone_format;
+
+ malone_format = vpu_malone_format_remap(params->codec_format);
++ if (WARN_ON(malone_format == MALONE_FMT_NULL))
++ return -EINVAL;
+ iface->udata_buffer[instance].base = params->udata.base;
+ iface->udata_buffer[instance].slot_size = params->udata.size;
+
+diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
+index 9c0704cd5766..4183a3994d30 100644
+--- a/drivers/media/platform/amphion/vpu_v4l2.c
++++ b/drivers/media/platform/amphion/vpu_v4l2.c
+@@ -440,10 +440,12 @@ static int vpu_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
+ fmt->sizeimage[1], fmt->bytesperline[1],
+ fmt->sizeimage[2], fmt->bytesperline[2],
+ q->num_buffers);
+- call_void_vop(inst, start, q->type);
++ ret = call_vop(inst, start, q->type);
+ vb2_clear_last_buffer_dequeued(q);
++ if (ret)
++ vpu_vb2_buffers_return(inst, q->type, VB2_BUF_STATE_QUEUED);
+
+- return 0;
++ return ret;
+ }
+
+ static void vpu_vb2_stop_streaming(struct vb2_queue *q)
+--
+2.35.1
+
--- /dev/null
+From 8c37529fd2f6831740087e45dbf8f921ca7c4fbb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 06:50:04 +0100
+Subject: media: amphion: sync buffer status with firmware during abort
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit d8f1eb105eab7aab36323c6b488dda479d5bd2da ]
+
+1. prevent to allocate buffer to firmware during abort
+2. release buffer when clear the slots
+
+Fixes: 6de8d628df6ef ("media: amphion: add v4l2 m2m vpu decoder stateful driver")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/amphion/vdec.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
+index 052a60189c13..dd7ea23902c0 100644
+--- a/drivers/media/platform/amphion/vdec.c
++++ b/drivers/media/platform/amphion/vdec.c
+@@ -63,6 +63,7 @@ struct vdec_t {
+ bool is_source_changed;
+ u32 source_change;
+ u32 drain;
++ bool aborting;
+ };
+
+ static const struct vpu_format vdec_formats[] = {
+@@ -942,6 +943,9 @@ static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vb
+ if (inst->state != VPU_CODEC_STATE_ACTIVE)
+ return -EINVAL;
+
++ if (vdec->aborting)
++ return -EINVAL;
++
+ if (!vdec->req_frame_count)
+ return -EINVAL;
+
+@@ -1051,6 +1055,8 @@ static void vdec_clear_slots(struct vpu_inst *inst)
+ vpu_buf = vdec->slots[i];
+ vbuf = &vpu_buf->m2m_buf.vb;
+
++ vpu_trace(inst->dev, "clear slot %d\n", i);
++ vdec_response_fs_release(inst, i, vpu_buf->tag);
+ vdec_recycle_buffer(inst, vbuf);
+ vdec->slots[i]->state = VPU_BUF_STATE_IDLE;
+ vdec->slots[i] = NULL;
+@@ -1312,6 +1318,8 @@ static void vdec_abort(struct vpu_inst *inst)
+ int ret;
+
+ vpu_trace(inst->dev, "[%d] state = %d\n", inst->id, inst->state);
++
++ vdec->aborting = true;
+ vpu_iface_add_scode(inst, SCODE_PADDING_ABORT);
+ vdec->params.end_flag = 1;
+ vpu_iface_set_decode_params(inst, &vdec->params, 1);
+@@ -1335,6 +1343,7 @@ static void vdec_abort(struct vpu_inst *inst)
+ vdec->decoded_frame_count = 0;
+ vdec->display_frame_count = 0;
+ vdec->sequence = 0;
++ vdec->aborting = false;
+ }
+
+ static void vdec_stop(struct vpu_inst *inst, bool free)
+--
+2.35.1
+
--- /dev/null
+From 4ef8772f13e4980367036d442814624e4b588b68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 May 2022 12:12:16 +0100
+Subject: media: atmel: atmel-sama7g5-isc: fix warning in configs without OF
+
+From: Eugen Hristev <eugen.hristev@microchip.com>
+
+[ Upstream commit b2bae4b8e637dd751d27918a6b27bd5abcd08859 ]
+
+All warnings (new ones prefixed by >>):
+
+>> drivers/media/platform/atmel/atmel-sama7g5-isc.c:610:34: warning: unused variable 'microchip_xisc_of_match' [-Wunused-const-variable]
+ static const struct of_device_id microchip_xisc_of_match[] = {
+ ^
+ 13 warnings generated.
+
+vim +/microchip_xisc_of_match +610 drivers/media/platform/atmel/atmel-sama7g5-isc.c
+
+ 609
+ > 610 static const struct of_device_id microchip_xisc_of_match[] = {
+ 611 { .compatible = "microchip,sama7g5-isc" },
+ 612 { }
+ 613 };
+ 614 MODULE_DEVICE_TABLE(of, microchip_xisc_of_match);
+ 615
+
+Fixed warning by guarding the atmel_isc_of_match by CONFIG_OF.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: c9aa973884a1 ("media: atmel: atmel-isc: add microchip-xisc driver")
+Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/atmel/atmel-sama7g5-isc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
+index 07a80b08bc54..e292a8d790a3 100644
+--- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c
++++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
+@@ -612,11 +612,13 @@ static const struct dev_pm_ops microchip_xisc_dev_pm_ops = {
+ SET_RUNTIME_PM_OPS(xisc_runtime_suspend, xisc_runtime_resume, NULL)
+ };
+
++#if IS_ENABLED(CONFIG_OF)
+ static const struct of_device_id microchip_xisc_of_match[] = {
+ { .compatible = "microchip,sama7g5-isc" },
+ { }
+ };
+ MODULE_DEVICE_TABLE(of, microchip_xisc_of_match);
++#endif
+
+ static struct platform_driver microchip_xisc_driver = {
+ .probe = microchip_xisc_probe,
+--
+2.35.1
+
--- /dev/null
+From e9dba7d18331a7f7aae3e8cd38b272e16acca096 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 May 2022 15:04:59 +0100
+Subject: media: camss: csid: fix wrong size passed to devm_kmalloc_array()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 4c25384d136642d72098e36201ca988533e73065 ]
+
+'supplies' is a pointer, the real size of struct regulator_bulk_data
+should be pass to devm_kmalloc_array().
+
+Fixes: 0d8140179715 ("media: camss: Add regulator_bulk support")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/camss/camss-csid.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
+index f993f349b66b..80628801cf09 100644
+--- a/drivers/media/platform/qcom/camss/camss-csid.c
++++ b/drivers/media/platform/qcom/camss/camss-csid.c
+@@ -666,7 +666,7 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
+ if (csid->num_supplies) {
+ csid->supplies = devm_kmalloc_array(camss->dev,
+ csid->num_supplies,
+- sizeof(csid->supplies),
++ sizeof(*csid->supplies),
+ GFP_KERNEL);
+ if (!csid->supplies)
+ return -ENOMEM;
+--
+2.35.1
+
--- /dev/null
+From a9733b919d1e7b20c4dd4384111ca591c457002e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 18:55:11 +0100
+Subject: media: cedrus: h265: Fix flag name
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit 104a70e1d0bcef28db13c4192b8729086089651c ]
+
+Bit 21 in register 0x24 (slice header info 1) actually represents
+negated version of low delay flag. This can be seen in vendor Cedar
+library source code. While this flag is not part of the standard, it can
+be found in reference HEVC implementation.
+
+Fix macro name and change it to flag.
+
+Fixes: 86caab29da78 ("media: cedrus: Add HEVC/H.265 decoding support")
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 4 +++-
+ drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 3 +--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+index 44f385be9f6c..2febdf7a97fe 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+@@ -559,7 +559,6 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
+
+ reg = VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2(slice_params->slice_tc_offset_div2) |
+ VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2(slice_params->slice_beta_offset_div2) |
+- VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(decode_params->num_poc_st_curr_after == 0) |
+ VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET(slice_params->slice_cr_qp_offset) |
+ VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET(slice_params->slice_cb_qp_offset) |
+ VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_QP_DELTA(slice_params->slice_qp_delta);
+@@ -572,6 +571,9 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
+ V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED,
+ slice_params->flags);
+
++ if (decode_params->num_poc_st_curr_after == 0)
++ reg |= VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_NOT_LOW_DELAY;
++
+ cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO1, reg);
+
+ chroma_log2_weight_denom = pred_weight_table->luma_log2_weight_denom +
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
+index bdb062ad8682..d81f7513ade0 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
+@@ -377,13 +377,12 @@
+
+ #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED BIT(23)
+ #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED BIT(22)
++#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_NOT_LOW_DELAY BIT(21)
+
+ #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2(v) \
+ SHIFT_AND_MASK_BITS(v, 31, 28)
+ #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2(v) \
+ SHIFT_AND_MASK_BITS(v, 27, 24)
+-#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(v) \
+- ((v) ? BIT(21) : 0)
+ #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET(v) \
+ SHIFT_AND_MASK_BITS(v, 20, 16)
+ #define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET(v) \
+--
+2.35.1
+
--- /dev/null
+From 08e02be5d608a9ec1ed8b671f3e44c9e54feb9bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 18:55:12 +0100
+Subject: media: cedrus: h265: Fix logic for not low delay flag
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit f1a413902aa71044b6ec41265e5e28ebaf29a9ce ]
+
+Now that we know real purpose of "not low delay" flag, logic for
+applying this flag should be fixed too. According to vendor and
+reference implementation, low delay is signaled when POC of current
+frame is lower than POC of at least one reference of a slice.
+
+Implement mentioned logic and invert it to conform to flag meaning. Also
+don't apply flag for I frames. They don't have any reference.
+
+This fixes decoding of 3 reference bitstreams.
+
+Fixes: 86caab29da78 ("media: cedrus: Add HEVC/H.265 decoding support")
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../staging/media/sunxi/cedrus/cedrus_h265.c | 27 ++++++++++++++++++-
+ 1 file changed, 26 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+index c26e515d64c9..2f6404fccd5a 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+@@ -301,6 +301,31 @@ static void cedrus_h265_write_scaling_list(struct cedrus_ctx *ctx,
+ }
+ }
+
++static int cedrus_h265_is_low_delay(struct cedrus_run *run)
++{
++ const struct v4l2_ctrl_hevc_slice_params *slice_params;
++ const struct v4l2_hevc_dpb_entry *dpb;
++ s32 poc;
++ int i;
++
++ slice_params = run->h265.slice_params;
++ poc = run->h265.decode_params->pic_order_cnt_val;
++ dpb = run->h265.decode_params->dpb;
++
++ for (i = 0; i < slice_params->num_ref_idx_l0_active_minus1 + 1; i++)
++ if (dpb[slice_params->ref_idx_l0[i]].pic_order_cnt_val > poc)
++ return 1;
++
++ if (slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_B)
++ return 0;
++
++ for (i = 0; i < slice_params->num_ref_idx_l1_active_minus1 + 1; i++)
++ if (dpb[slice_params->ref_idx_l1[i]].pic_order_cnt_val > poc)
++ return 1;
++
++ return 0;
++}
++
+ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
+ struct cedrus_run *run)
+ {
+@@ -571,7 +596,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
+ V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED,
+ slice_params->flags);
+
+- if (decode_params->num_poc_st_curr_after == 0)
++ if (slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_I && !cedrus_h265_is_low_delay(run))
+ reg |= VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_NOT_LOW_DELAY;
+
+ cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO1, reg);
+--
+2.35.1
+
--- /dev/null
+From afc0e382d73c7463128a4118c8222b2f949c36c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 18:56:49 +0200
+Subject: media: cedrus: hevc: Add check for invalid timestamp
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit 143201a6435bf65f0115435e9dc6d95c66b908e9 ]
+
+Not all DPB entries will be used most of the time. Unused entries will
+thus have invalid timestamps. They will produce negative buffer index
+which is not specifically handled. This works just by chance in current
+code. It will even produce bogus pointer, but since it's not used, it
+won't do any harm.
+
+Let's fix that brittle design by skipping writing DPB entry altogether
+if timestamp is invalid.
+
+Fixes: 86caab29da78 ("media: cedrus: Add HEVC/H.265 decoding support")
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Reviewed-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+index 2f6404fccd5a..04419381ea56 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+@@ -147,6 +147,9 @@ static void cedrus_h265_frame_info_write_dpb(struct cedrus_ctx *ctx,
+ dpb[i].pic_order_cnt_val
+ };
+
++ if (buffer_index < 0)
++ continue;
++
+ cedrus_h265_frame_info_write_single(ctx, i, dpb[i].field_pic,
+ pic_order_cnt,
+ buffer_index);
+--
+2.35.1
+
--- /dev/null
+From 45e57527683afdc6de6b677d78871b406ed2e134 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 09:34:23 +0100
+Subject: media: driver/nxp/imx-jpeg: fix a unexpected return value problem
+
+From: Jian Zhang <zhangjian210@huawei.com>
+
+[ Upstream commit 5b304046a81eda221b5d06a9c62f7b5e45530fa5 ]
+
+In function mxc_jpeg_probe(), when devm_clk_get() fail, the return value
+will be unexpected, and it should be the devm_clk_get's error code.
+
+Fixes: 4c2e5156d9fa6 ("media: imx-jpeg: Add pm-runtime support for imx-jpeg")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Jian Zhang <zhangjian210@huawei.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index c287eb789fe6..55c4b29d3e4e 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -2121,12 +2121,14 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
+ jpeg->clk_ipg = devm_clk_get(dev, "ipg");
+ if (IS_ERR(jpeg->clk_ipg)) {
+ dev_err(dev, "failed to get clock: ipg\n");
++ ret = PTR_ERR(jpeg->clk_ipg);
+ goto err_clk;
+ }
+
+ jpeg->clk_per = devm_clk_get(dev, "per");
+ if (IS_ERR(jpeg->clk_per)) {
+ dev_err(dev, "failed to get clock: per\n");
++ ret = PTR_ERR(jpeg->clk_per);
+ goto err_clk;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 1b1e85acbc43bc6d54558a0ae8d7ec4b19a8ed05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Feb 2022 21:29:53 +0000
+Subject: media: hantro: Add support for Hantro G1 on RK356x
+
+From: Piotr Oniszczuk <piotr.oniszczuk@gmail.com>
+
+[ Upstream commit 5f6bfab6da6531238e899fdf29efd6d0185adc3e ]
+
+RK356x has Hantro G1 video decoder capable to decode MPEG2/H.264/VP8
+video formats.
+
+This patch adds support for RK356x family in existing Hantro
+video decoder kernel driver.
+
+Tested on [1] with FFmpeg v4l2_request code taken from [2]
+with MPEG2, H.642 and VP8 samples with results [3].
+
+[1] https://github.com/warpme/minimyth2
+[2] https://github.com/LibreELEC/LibreELEC.tv/blob/master/packages/multimedia/ffmpeg/patches/v4l2-request/ffmpeg-001-v4l2-request.patch
+[3] https://github.com/warpme/minimyth2/blob/master/video-test-summary.txt
+
+Signed-off-by: Piotr Oniszczuk <piotr.oniszczuk@gmail.com>
+Reviewed-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/hantro/hantro_drv.c | 1 +
+ drivers/staging/media/hantro/hantro_hw.h | 1 +
+ drivers/staging/media/hantro/rockchip_vpu_hw.c | 14 ++++++++++++++
+ 3 files changed, 16 insertions(+)
+
+diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
+index bd7d11032c94..ac232b5f7825 100644
+--- a/drivers/staging/media/hantro/hantro_drv.c
++++ b/drivers/staging/media/hantro/hantro_drv.c
+@@ -638,6 +638,7 @@ static const struct of_device_id of_hantro_match[] = {
+ { .compatible = "rockchip,rk3288-vpu", .data = &rk3288_vpu_variant, },
+ { .compatible = "rockchip,rk3328-vpu", .data = &rk3328_vpu_variant, },
+ { .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, },
++ { .compatible = "rockchip,rk3568-vpu", .data = &rk3568_vpu_variant, },
+ #endif
+ #ifdef CONFIG_VIDEO_HANTRO_IMX8M
+ { .compatible = "nxp,imx8mm-vpu-g1", .data = &imx8mm_vpu_g1_variant, },
+diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
+index ed018e293ba0..c5dc77125fb7 100644
+--- a/drivers/staging/media/hantro/hantro_hw.h
++++ b/drivers/staging/media/hantro/hantro_hw.h
+@@ -300,6 +300,7 @@ extern const struct hantro_variant rk3066_vpu_variant;
+ extern const struct hantro_variant rk3288_vpu_variant;
+ extern const struct hantro_variant rk3328_vpu_variant;
+ extern const struct hantro_variant rk3399_vpu_variant;
++extern const struct hantro_variant rk3568_vpu_variant;
+ extern const struct hantro_variant sama5d4_vdec_variant;
+ extern const struct hantro_variant sunxi_vpu_variant;
+
+diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c
+index 163cf92eafca..fc96501f3bc8 100644
+--- a/drivers/staging/media/hantro/rockchip_vpu_hw.c
++++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c
+@@ -545,6 +545,20 @@ const struct hantro_variant rk3399_vpu_variant = {
+ .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names)
+ };
+
++const struct hantro_variant rk3568_vpu_variant = {
++ .dec_offset = 0x400,
++ .dec_fmts = rk3399_vpu_dec_fmts,
++ .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts),
++ .codec = HANTRO_MPEG2_DECODER |
++ HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
++ .codec_ops = rk3399_vpu_codec_ops,
++ .irqs = rockchip_vdpu2_irqs,
++ .num_irqs = ARRAY_SIZE(rockchip_vdpu2_irqs),
++ .init = rockchip_vpu_hw_init,
++ .clk_names = rockchip_vpu_clk_names,
++ .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names)
++};
++
+ const struct hantro_variant px30_vpu_variant = {
+ .enc_offset = 0x0,
+ .enc_fmts = rockchip_vpu_enc_fmts,
+--
+2.35.1
+
--- /dev/null
+From f5f161ff6537659e495b5204b6e51e1ff8c8471e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 May 2022 09:53:49 +0100
+Subject: media: hantro: Be more accurate on pixel formats step_width
+ constraints
+
+From: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+
+[ Upstream commit 135ad96cb4d6bd6dace030846fe5c7ea890411ab ]
+
+On Hantro G2 decoder on IMX8MQ strides requirements aren't the same
+for NV12_4L4 and NV12 pixel formats. The first one use a 4 bytes padding
+while the last one needs 16 bytes.
+To be sure to provide the correct stride in all cases we need:
+- to relax the constraints on codec formats so set step_width to 4
+- use capture queue format and not the output queue format when applying
+ the pixel format constraints.
+- put the correct step_width constraints on each pixel format.
+
+Move HEVC SPS validation in hantro_hevc.c to be able to perform it
+when setting sps control and when starting to decode the bitstream.
+Add a new test in HEVC SPS validation function to check if resolution
+is still matching the hardware constraints.
+
+With this SAODBLK_A_MainConcept_4 and SAODBLK_B_MainConcept_4 conformance
+tests files are correctly decoded with both NV12 and NV12_4L4 pixel
+formats. These two files have a resolution of 1016x760.
+
+Add defines for the various used resolutions.
+For other variants than Hantro G2 on IMX8M keep the same step_width to
+avoid regressions.
+
+Fluster HEVC test score is now 128/147 vs 126/147 with the both pixel
+formats as decoder output.
+Fluster VP9 test score stay at 147/303.
+
+[hverkuil: fix trivial checkpatch warnings]
+
+Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/hantro/hantro_drv.c | 12 +-
+ drivers/staging/media/hantro/hantro_hevc.c | 30 +++++
+ drivers/staging/media/hantro/hantro_hw.h | 14 +++
+ drivers/staging/media/hantro/hantro_v4l2.c | 2 +-
+ drivers/staging/media/hantro/imx8m_vpu_hw.c | 80 ++++++++++----
+ .../staging/media/hantro/rockchip_vpu_hw.c | 104 ++++++++++++------
+ .../staging/media/hantro/sama5d4_vdec_hw.c | 40 +++++--
+ drivers/staging/media/hantro/sunxi_vpu_hw.c | 24 +++-
+ 8 files changed, 223 insertions(+), 83 deletions(-)
+
+diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
+index ac232b5f7825..01d33dcb0467 100644
+--- a/drivers/staging/media/hantro/hantro_drv.c
++++ b/drivers/staging/media/hantro/hantro_drv.c
+@@ -253,6 +253,11 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
+
+ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
+ {
++ struct hantro_ctx *ctx;
++
++ ctx = container_of(ctrl->handler,
++ struct hantro_ctx, ctrl_handler);
++
+ if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) {
+ const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
+
+@@ -268,12 +273,7 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
+ } else if (ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_SPS) {
+ const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps;
+
+- if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8)
+- /* Luma and chroma bit depth mismatch */
+- return -EINVAL;
+- if (sps->bit_depth_luma_minus8 != 0)
+- /* Only 8-bit is supported */
+- return -EINVAL;
++ return hantro_hevc_validate_sps(ctx, sps);
+ } else if (ctrl->id == V4L2_CID_STATELESS_VP9_FRAME) {
+ const struct v4l2_ctrl_vp9_frame *dec_params = ctrl->p_new.p_vp9_frame;
+
+diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
+index f86c98e19177..bd924896e409 100644
+--- a/drivers/staging/media/hantro/hantro_hevc.c
++++ b/drivers/staging/media/hantro/hantro_hevc.c
+@@ -154,6 +154,32 @@ static int tile_buffer_reallocate(struct hantro_ctx *ctx)
+ return -ENOMEM;
+ }
+
++int hantro_hevc_validate_sps(struct hantro_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps)
++{
++ if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8)
++ /* Luma and chroma bit depth mismatch */
++ return -EINVAL;
++ if (sps->bit_depth_luma_minus8 != 0)
++ /* Only 8-bit is supported */
++ return -EINVAL;
++
++ /*
++ * for tile pixel format check if the width and height match
++ * hardware constraints
++ */
++ if (ctx->vpu_dst_fmt->fourcc == V4L2_PIX_FMT_NV12_4L4) {
++ if (ctx->dst_fmt.width !=
++ ALIGN(sps->pic_width_in_luma_samples, ctx->vpu_dst_fmt->frmsize.step_width))
++ return -EINVAL;
++
++ if (ctx->dst_fmt.height !=
++ ALIGN(sps->pic_height_in_luma_samples, ctx->vpu_dst_fmt->frmsize.step_height))
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
+ int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx)
+ {
+ struct hantro_hevc_dec_hw_ctx *hevc_ctx = &ctx->hevc_dec;
+@@ -177,6 +203,10 @@ int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx)
+ if (WARN_ON(!ctrls->sps))
+ return -EINVAL;
+
++ ret = hantro_hevc_validate_sps(ctx, ctrls->sps);
++ if (ret)
++ return ret;
++
+ ctrls->pps =
+ hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_HEVC_PPS);
+ if (WARN_ON(!ctrls->pps))
+diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
+index 699c1efc0215..b480cf329b13 100644
+--- a/drivers/staging/media/hantro/hantro_hw.h
++++ b/drivers/staging/media/hantro/hantro_hw.h
+@@ -18,9 +18,21 @@
+ #define DEC_8190_ALIGN_MASK 0x07U
+
+ #define MB_DIM 16
++#define TILE_MB_DIM 4
+ #define MB_WIDTH(w) DIV_ROUND_UP(w, MB_DIM)
+ #define MB_HEIGHT(h) DIV_ROUND_UP(h, MB_DIM)
+
++#define FMT_MIN_WIDTH 48
++#define FMT_MIN_HEIGHT 48
++#define FMT_HD_WIDTH 1280
++#define FMT_HD_HEIGHT 720
++#define FMT_FHD_WIDTH 1920
++#define FMT_FHD_HEIGHT 1088
++#define FMT_UHD_WIDTH 3840
++#define FMT_UHD_HEIGHT 2160
++#define FMT_4K_WIDTH 4096
++#define FMT_4K_HEIGHT 2304
++
+ #define NUM_REF_PICTURES (V4L2_HEVC_DPB_ENTRIES_NUM_MAX + 1)
+
+ struct hantro_dev;
+@@ -341,6 +353,8 @@ int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx);
+ void hantro_hevc_ref_init(struct hantro_ctx *ctx);
+ dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, int poc);
+ int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr);
++int hantro_hevc_validate_sps(struct hantro_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps);
++
+
+ static inline unsigned short hantro_vp9_num_sbs(unsigned short dimension)
+ {
+diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c
+index 71a6279750bf..93d0dcf69f4a 100644
+--- a/drivers/staging/media/hantro/hantro_v4l2.c
++++ b/drivers/staging/media/hantro/hantro_v4l2.c
+@@ -260,7 +260,7 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx,
+ } else if (ctx->is_encoder) {
+ vpu_fmt = ctx->vpu_dst_fmt;
+ } else {
+- vpu_fmt = ctx->vpu_src_fmt;
++ vpu_fmt = fmt;
+ /*
+ * Width/height on the CAPTURE end of a decoder are ignored and
+ * replaced by the OUTPUT ones.
+diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
+index 9802508bade2..77f574fdfa77 100644
+--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
++++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
+@@ -83,6 +83,14 @@ static const struct hantro_fmt imx8m_vpu_postproc_fmts[] = {
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .codec_mode = HANTRO_MODE_NONE,
+ .postprocessed = true,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_UHD_WIDTH,
++ .step_width = MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_UHD_HEIGHT,
++ .step_height = MB_DIM,
++ },
+ },
+ };
+
+@@ -90,17 +98,25 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .codec_mode = HANTRO_MODE_NONE,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_UHD_WIDTH,
++ .step_width = MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_UHD_HEIGHT,
++ .step_height = MB_DIM,
++ },
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_MPEG2_SLICE,
+ .codec_mode = HANTRO_MODE_MPEG2_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 1920,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_FHD_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 1088,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_FHD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+@@ -109,11 +125,11 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = {
+ .codec_mode = HANTRO_MODE_VP8_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 3840,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_UHD_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 2160,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_UHD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+@@ -122,11 +138,11 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = {
+ .codec_mode = HANTRO_MODE_H264_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 3840,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_UHD_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 2160,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_UHD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+@@ -137,6 +153,14 @@ static const struct hantro_fmt imx8m_vpu_g2_postproc_fmts[] = {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .codec_mode = HANTRO_MODE_NONE,
+ .postprocessed = true,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_UHD_WIDTH,
++ .step_width = MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_UHD_HEIGHT,
++ .step_height = MB_DIM,
++ },
+ },
+ };
+
+@@ -144,18 +168,26 @@ static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV12_4L4,
+ .codec_mode = HANTRO_MODE_NONE,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_UHD_WIDTH,
++ .step_width = TILE_MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_UHD_HEIGHT,
++ .step_height = TILE_MB_DIM,
++ },
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_HEVC_SLICE,
+ .codec_mode = HANTRO_MODE_HEVC_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 3840,
+- .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 2160,
+- .step_height = MB_DIM,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_UHD_WIDTH,
++ .step_width = TILE_MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_UHD_HEIGHT,
++ .step_height = TILE_MB_DIM,
+ },
+ },
+ {
+@@ -163,12 +195,12 @@ static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {
+ .codec_mode = HANTRO_MODE_VP9_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 3840,
+- .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 2160,
+- .step_height = MB_DIM,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_UHD_WIDTH,
++ .step_width = TILE_MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_UHD_HEIGHT,
++ .step_height = TILE_MB_DIM,
+ },
+ },
+ };
+diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c
+index fc96501f3bc8..098486b9ec27 100644
+--- a/drivers/staging/media/hantro/rockchip_vpu_hw.c
++++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c
+@@ -63,6 +63,14 @@ static const struct hantro_fmt rockchip_vpu1_postproc_fmts[] = {
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .codec_mode = HANTRO_MODE_NONE,
+ .postprocessed = true,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_FHD_WIDTH,
++ .step_width = MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_FHD_HEIGHT,
++ .step_height = MB_DIM,
++ },
+ },
+ };
+
+@@ -70,17 +78,25 @@ static const struct hantro_fmt rk3066_vpu_dec_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .codec_mode = HANTRO_MODE_NONE,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_FHD_WIDTH,
++ .step_width = MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_FHD_HEIGHT,
++ .step_height = MB_DIM,
++ },
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_H264_SLICE,
+ .codec_mode = HANTRO_MODE_H264_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 1920,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_FHD_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 1088,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_FHD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+@@ -89,11 +105,11 @@ static const struct hantro_fmt rk3066_vpu_dec_fmts[] = {
+ .codec_mode = HANTRO_MODE_MPEG2_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 1920,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_FHD_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 1088,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_FHD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+@@ -102,11 +118,11 @@ static const struct hantro_fmt rk3066_vpu_dec_fmts[] = {
+ .codec_mode = HANTRO_MODE_VP8_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 1920,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_FHD_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 1088,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_FHD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+@@ -116,17 +132,25 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .codec_mode = HANTRO_MODE_NONE,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_4K_WIDTH,
++ .step_width = MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_4K_HEIGHT,
++ .step_height = MB_DIM,
++ },
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_H264_SLICE,
+ .codec_mode = HANTRO_MODE_H264_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 4096,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_4K_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 2304,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_4K_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+@@ -135,11 +159,11 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = {
+ .codec_mode = HANTRO_MODE_MPEG2_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 1920,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_FHD_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 1088,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_FHD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+@@ -148,11 +172,11 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = {
+ .codec_mode = HANTRO_MODE_VP8_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 3840,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_UHD_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 2160,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_UHD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+@@ -162,17 +186,25 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .codec_mode = HANTRO_MODE_NONE,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_FHD_WIDTH,
++ .step_width = MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_FHD_HEIGHT,
++ .step_height = MB_DIM,
++ },
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_H264_SLICE,
+ .codec_mode = HANTRO_MODE_H264_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 1920,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_FHD_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 1088,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_FHD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+@@ -181,11 +213,11 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = {
+ .codec_mode = HANTRO_MODE_MPEG2_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 1920,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_FHD_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 1088,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_FHD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+@@ -194,11 +226,11 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = {
+ .codec_mode = HANTRO_MODE_VP8_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 3840,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_UHD_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 2160,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_UHD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+diff --git a/drivers/staging/media/hantro/sama5d4_vdec_hw.c b/drivers/staging/media/hantro/sama5d4_vdec_hw.c
+index b2fc1c5613e1..b205e2db5b04 100644
+--- a/drivers/staging/media/hantro/sama5d4_vdec_hw.c
++++ b/drivers/staging/media/hantro/sama5d4_vdec_hw.c
+@@ -16,6 +16,14 @@ static const struct hantro_fmt sama5d4_vdec_postproc_fmts[] = {
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .codec_mode = HANTRO_MODE_NONE,
+ .postprocessed = true,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_HD_WIDTH,
++ .step_width = MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_HD_HEIGHT,
++ .step_height = MB_DIM,
++ },
+ },
+ };
+
+@@ -23,17 +31,25 @@ static const struct hantro_fmt sama5d4_vdec_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .codec_mode = HANTRO_MODE_NONE,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_HD_WIDTH,
++ .step_width = MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_HD_HEIGHT,
++ .step_height = MB_DIM,
++ },
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_MPEG2_SLICE,
+ .codec_mode = HANTRO_MODE_MPEG2_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 1280,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_HD_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 720,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_HD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+@@ -42,11 +58,11 @@ static const struct hantro_fmt sama5d4_vdec_fmts[] = {
+ .codec_mode = HANTRO_MODE_VP8_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 1280,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_HD_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 720,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_HD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+@@ -55,11 +71,11 @@ static const struct hantro_fmt sama5d4_vdec_fmts[] = {
+ .codec_mode = HANTRO_MODE_H264_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 1280,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_HD_WIDTH,
+ .step_width = MB_DIM,
+- .min_height = 48,
+- .max_height = 720,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_HD_HEIGHT,
+ .step_height = MB_DIM,
+ },
+ },
+diff --git a/drivers/staging/media/hantro/sunxi_vpu_hw.c b/drivers/staging/media/hantro/sunxi_vpu_hw.c
+index c0edd5856a0c..fbeac81e59e1 100644
+--- a/drivers/staging/media/hantro/sunxi_vpu_hw.c
++++ b/drivers/staging/media/hantro/sunxi_vpu_hw.c
+@@ -14,6 +14,14 @@ static const struct hantro_fmt sunxi_vpu_postproc_fmts[] = {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .codec_mode = HANTRO_MODE_NONE,
+ .postprocessed = true,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_UHD_WIDTH,
++ .step_width = 32,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_UHD_HEIGHT,
++ .step_height = 32,
++ },
+ },
+ };
+
+@@ -21,17 +29,25 @@ static const struct hantro_fmt sunxi_vpu_dec_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV12_4L4,
+ .codec_mode = HANTRO_MODE_NONE,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_UHD_WIDTH,
++ .step_width = 32,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_UHD_HEIGHT,
++ .step_height = 32,
++ },
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_VP9_FRAME,
+ .codec_mode = HANTRO_MODE_VP9_DEC,
+ .max_depth = 2,
+ .frmsize = {
+- .min_width = 48,
+- .max_width = 3840,
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_UHD_WIDTH,
+ .step_width = 32,
+- .min_height = 48,
+- .max_height = 2160,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_UHD_HEIGHT,
+ .step_height = 32,
+ },
+ },
+--
+2.35.1
+
--- /dev/null
+From 77fff28a9e0679d2257994fbc0d77291ef3226ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 12:59:45 +0100
+Subject: media: Hantro: Correct G2 init qp field
+
+From: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+
+[ Upstream commit 300065f966d30baa59a13849753305aac8c320c3 ]
+
+Documentation said that g2 init_qp field use bits 24 to 30 of
+the 8th register.
+Change the field mask to be able to set 7 bits and not only 6 of them.
+
+Conformance test INITQP_B_Main10_Sony_1 decoding is OK with this
+patch.
+
+Fixes: cb5dd5a0fa518 ("media: hantro: Introduce G2/HEVC decoder")
+Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/hantro/hantro_g2_regs.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/media/hantro/hantro_g2_regs.h b/drivers/staging/media/hantro/hantro_g2_regs.h
+index b7c6f9877b9d..0f43516d0805 100644
+--- a/drivers/staging/media/hantro/hantro_g2_regs.h
++++ b/drivers/staging/media/hantro/hantro_g2_regs.h
+@@ -107,7 +107,7 @@
+
+ #define g2_start_code_e G2_DEC_REG(10, 31, 0x1)
+ #define g2_init_qp_old G2_DEC_REG(10, 25, 0x3f)
+-#define g2_init_qp G2_DEC_REG(10, 24, 0x3f)
++#define g2_init_qp G2_DEC_REG(10, 24, 0x7f)
+ #define g2_num_tile_cols_old G2_DEC_REG(10, 20, 0x1f)
+ #define g2_num_tile_cols G2_DEC_REG(10, 19, 0x1f)
+ #define g2_num_tile_rows_old G2_DEC_REG(10, 15, 0x1f)
+--
+2.35.1
+
--- /dev/null
+From f5d9b656cb2b0b77ef123fb50b18c365c15a64f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jun 2022 20:56:23 +0100
+Subject: media: hantro: Fix RK3399 H.264 format advertising
+
+From: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+
+[ Upstream commit 177d841fa19542eb35aa5ec9579c4abb989c9255 ]
+
+Commit 1f82f2df523cb ("media: hantro: Enable H.264 on Rockchip VDPU2")
+enabled H.264 on some SoCs with VDPU2 cores. This had the side-effect
+of exposing H.264 coded format as supported on RK3399.
+
+Fix this and clarify how the codec is explicitly disabled on RK3399 on
+this driver.
+
+Fixes: 1f82f2df523cb ("media: hantro: Enable H.264 on Rockchip VDPU2")
+Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+Tested-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../staging/media/hantro/rockchip_vpu_hw.c | 60 ++++++++++++++++---
+ 1 file changed, 53 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c
+index 098486b9ec27..26e16b5a6a70 100644
+--- a/drivers/staging/media/hantro/rockchip_vpu_hw.c
++++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c
+@@ -182,7 +182,7 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = {
+ },
+ };
+
+-static const struct hantro_fmt rk3399_vpu_dec_fmts[] = {
++static const struct hantro_fmt rockchip_vdpu2_dec_fmts[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .codec_mode = HANTRO_MODE_NONE,
+@@ -236,6 +236,47 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = {
+ },
+ };
+
++static const struct hantro_fmt rk3399_vpu_dec_fmts[] = {
++ {
++ .fourcc = V4L2_PIX_FMT_NV12,
++ .codec_mode = HANTRO_MODE_NONE,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_FHD_WIDTH,
++ .step_width = MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_FHD_HEIGHT,
++ .step_height = MB_DIM,
++ },
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_MPEG2_SLICE,
++ .codec_mode = HANTRO_MODE_MPEG2_DEC,
++ .max_depth = 2,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_FHD_WIDTH,
++ .step_width = MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_FHD_HEIGHT,
++ .step_height = MB_DIM,
++ },
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_VP8_FRAME,
++ .codec_mode = HANTRO_MODE_VP8_DEC,
++ .max_depth = 2,
++ .frmsize = {
++ .min_width = FMT_MIN_WIDTH,
++ .max_width = FMT_UHD_WIDTH,
++ .step_width = MB_DIM,
++ .min_height = FMT_MIN_HEIGHT,
++ .max_height = FMT_UHD_HEIGHT,
++ .step_height = MB_DIM,
++ },
++ },
++};
++
+ static irqreturn_t rockchip_vpu1_vepu_irq(int irq, void *dev_id)
+ {
+ struct hantro_dev *vpu = dev_id;
+@@ -548,8 +589,8 @@ const struct hantro_variant rk3288_vpu_variant = {
+
+ const struct hantro_variant rk3328_vpu_variant = {
+ .dec_offset = 0x400,
+- .dec_fmts = rk3399_vpu_dec_fmts,
+- .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts),
++ .dec_fmts = rockchip_vdpu2_dec_fmts,
++ .num_dec_fmts = ARRAY_SIZE(rockchip_vdpu2_dec_fmts),
+ .codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
+ HANTRO_H264_DECODER,
+ .codec_ops = rk3399_vpu_codec_ops,
+@@ -560,6 +601,11 @@ const struct hantro_variant rk3328_vpu_variant = {
+ .num_clocks = ARRAY_SIZE(rockchip_vpu_clk_names),
+ };
+
++/*
++ * H.264 decoding explicitly disabled in RK3399.
++ * This ensures userspace applications use the Rockchip VDEC core,
++ * which has better performance.
++ */
+ const struct hantro_variant rk3399_vpu_variant = {
+ .enc_offset = 0x0,
+ .enc_fmts = rockchip_vpu_enc_fmts,
+@@ -579,8 +625,8 @@ const struct hantro_variant rk3399_vpu_variant = {
+
+ const struct hantro_variant rk3568_vpu_variant = {
+ .dec_offset = 0x400,
+- .dec_fmts = rk3399_vpu_dec_fmts,
+- .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts),
++ .dec_fmts = rockchip_vdpu2_dec_fmts,
++ .num_dec_fmts = ARRAY_SIZE(rockchip_vdpu2_dec_fmts),
+ .codec = HANTRO_MPEG2_DECODER |
+ HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
+ .codec_ops = rk3399_vpu_codec_ops,
+@@ -596,8 +642,8 @@ const struct hantro_variant px30_vpu_variant = {
+ .enc_fmts = rockchip_vpu_enc_fmts,
+ .num_enc_fmts = ARRAY_SIZE(rockchip_vpu_enc_fmts),
+ .dec_offset = 0x400,
+- .dec_fmts = rk3399_vpu_dec_fmts,
+- .num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts),
++ .dec_fmts = rockchip_vdpu2_dec_fmts,
++ .num_dec_fmts = ARRAY_SIZE(rockchip_vdpu2_dec_fmts),
+ .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER |
+ HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
+ .codec_ops = rk3399_vpu_codec_ops,
+--
+2.35.1
+
--- /dev/null
+From c90af83d713f505fa2f0cb164da7f18ba0df292e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Apr 2022 17:50:59 +0200
+Subject: media: hantro: HEVC: Fix output frame chroma offset
+
+From: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+
+[ Upstream commit 579846ec52593e6ca123c30379103377cd25728a ]
+
+Hantro decoder doesn't take care of the requested and aligned size
+of the capture buffer.
+Stop using the bitstream width/height and use capture frame size
+stored in the context to get the correct values.
+
+hantro_hevc_chroma_offset() and hantro_hevc_motion_vectors_offset()
+are only used in hantro_g2_hevc_dec.c so take the opportunity
+to move them here.
+
+fluster HEVC score goes up from 77 to 85 successful tests (over 147)
+with this patch.
+
+Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../staging/media/hantro/hantro_g2_hevc_dec.c | 19 ++++++++++++++++---
+ drivers/staging/media/hantro/hantro_hevc.c | 17 -----------------
+ drivers/staging/media/hantro/hantro_hw.h | 2 --
+ 3 files changed, 16 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+index a4642ed1f463..7c046d456038 100644
+--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
++++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+@@ -8,6 +8,20 @@
+ #include "hantro_hw.h"
+ #include "hantro_g2_regs.h"
+
++#define G2_ALIGN 16
++
++static size_t hantro_hevc_chroma_offset(struct hantro_ctx *ctx)
++{
++ return ctx->dst_fmt.width * ctx->dst_fmt.height;
++}
++
++static size_t hantro_hevc_motion_vectors_offset(struct hantro_ctx *ctx)
++{
++ size_t cr_offset = hantro_hevc_chroma_offset(ctx);
++
++ return ALIGN((cr_offset * 3) / 2, G2_ALIGN);
++}
++
+ static void prepare_tile_info_buffer(struct hantro_ctx *ctx)
+ {
+ struct hantro_dev *vpu = ctx->dev;
+@@ -330,7 +344,6 @@ static void set_ref_pic_list(struct hantro_ctx *ctx)
+ static int set_ref(struct hantro_ctx *ctx)
+ {
+ const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
+- const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps;
+ const struct v4l2_ctrl_hevc_pps *pps = ctrls->pps;
+ const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params;
+ const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
+@@ -338,8 +351,8 @@ static int set_ref(struct hantro_ctx *ctx)
+ struct hantro_dev *vpu = ctx->dev;
+ struct vb2_v4l2_buffer *vb2_dst;
+ struct hantro_decoded_buffer *dst;
+- size_t cr_offset = hantro_hevc_chroma_offset(sps);
+- size_t mv_offset = hantro_hevc_motion_vectors_offset(sps);
++ size_t cr_offset = hantro_hevc_chroma_offset(ctx);
++ size_t mv_offset = hantro_hevc_motion_vectors_offset(ctx);
+ u32 max_ref_frames;
+ u16 dpb_longterm_e;
+ static const struct hantro_reg cur_poc[] = {
+diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
+index 9c351f7fe6bd..b3a057beaf19 100644
+--- a/drivers/staging/media/hantro/hantro_hevc.c
++++ b/drivers/staging/media/hantro/hantro_hevc.c
+@@ -27,23 +27,6 @@
+
+ #define UNUSED_REF -1
+
+-#define G2_ALIGN 16
+-
+-size_t hantro_hevc_chroma_offset(const struct v4l2_ctrl_hevc_sps *sps)
+-{
+- int bytes_per_pixel = sps->bit_depth_luma_minus8 == 0 ? 1 : 2;
+-
+- return sps->pic_width_in_luma_samples *
+- sps->pic_height_in_luma_samples * bytes_per_pixel;
+-}
+-
+-size_t hantro_hevc_motion_vectors_offset(const struct v4l2_ctrl_hevc_sps *sps)
+-{
+- size_t cr_offset = hantro_hevc_chroma_offset(sps);
+-
+- return ALIGN((cr_offset * 3) / 2, G2_ALIGN);
+-}
+-
+ static void hantro_hevc_ref_init(struct hantro_ctx *ctx)
+ {
+ struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
+diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
+index c5dc77125fb7..df142f31e31b 100644
+--- a/drivers/staging/media/hantro/hantro_hw.h
++++ b/drivers/staging/media/hantro/hantro_hw.h
+@@ -341,8 +341,6 @@ int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx);
+ dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, int poc);
+ int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr);
+ void hantro_hevc_ref_remove_unused(struct hantro_ctx *ctx);
+-size_t hantro_hevc_chroma_offset(const struct v4l2_ctrl_hevc_sps *sps);
+-size_t hantro_hevc_motion_vectors_offset(const struct v4l2_ctrl_hevc_sps *sps);
+
+ static inline unsigned short hantro_vp9_num_sbs(unsigned short dimension)
+ {
+--
+2.35.1
+
--- /dev/null
+From 3da9449dfa7f2e3ef784f53c15165df50f38b5a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 May 2022 15:51:38 +0200
+Subject: media: hantro: HEVC: Fix reference frames management
+
+From: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+
+[ Upstream commit 387d1176956883635c63a7d1c91b1f45e19c1777 ]
+
+PoC shall be int the range of -2^31 to 2^31 -1
+(HEVC spec section 8.3.1 Decoding process for picture order count).
+The current way to know if an entry in reference picture array is free
+is to test if PoC = UNUSED_REF. Since UNUSED_REF is defined as '-1' that
+could lead to decode issue if one PoC also equal '-1'.
+PoC with value = '-1' exists in conformance test SLIST_B_Sony_9.
+
+Change the way unused entries are managed in reference pictures array to
+avoid using PoC to detect then.
+
+This patch doesn't change fluster HEVC score.
+
+Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+Reviewed-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../staging/media/hantro/hantro_g2_hevc_dec.c | 4 +--
+ drivers/staging/media/hantro/hantro_hevc.c | 27 +++----------------
+ drivers/staging/media/hantro/hantro_hw.h | 2 +-
+ 3 files changed, 5 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+index 7c046d456038..5df6f08e26f5 100644
+--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
++++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+@@ -415,7 +415,7 @@ static int set_ref(struct hantro_ctx *ctx)
+ set_ref_pic_list(ctx);
+
+ /* We will only keep the reference pictures that are still used */
+- ctx->hevc_dec.ref_bufs_used = 0;
++ hantro_hevc_ref_init(ctx);
+
+ /* Set up addresses of DPB buffers */
+ dpb_longterm_e = 0;
+@@ -456,8 +456,6 @@ static int set_ref(struct hantro_ctx *ctx)
+ hantro_write_addr(vpu, G2_OUT_CHROMA_ADDR, chroma_addr);
+ hantro_write_addr(vpu, G2_OUT_MV_ADDR, mv_addr);
+
+- hantro_hevc_ref_remove_unused(ctx);
+-
+ for (; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) {
+ hantro_write_addr(vpu, G2_REF_LUMA_ADDR(i), 0);
+ hantro_write_addr(vpu, G2_REF_CHROMA_ADDR(i), 0);
+diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
+index b3a057beaf19..f86c98e19177 100644
+--- a/drivers/staging/media/hantro/hantro_hevc.c
++++ b/drivers/staging/media/hantro/hantro_hevc.c
+@@ -25,15 +25,11 @@
+ #define MAX_TILE_COLS 20
+ #define MAX_TILE_ROWS 22
+
+-#define UNUSED_REF -1
+-
+-static void hantro_hevc_ref_init(struct hantro_ctx *ctx)
++void hantro_hevc_ref_init(struct hantro_ctx *ctx)
+ {
+ struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
+- int i;
+
+- for (i = 0; i < NUM_REF_PICTURES; i++)
+- hevc_dec->ref_bufs_poc[i] = UNUSED_REF;
++ hevc_dec->ref_bufs_used = 0;
+ }
+
+ dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx,
+@@ -60,7 +56,7 @@ int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr)
+
+ /* Add a new reference buffer */
+ for (i = 0; i < NUM_REF_PICTURES; i++) {
+- if (hevc_dec->ref_bufs_poc[i] == UNUSED_REF) {
++ if (!(hevc_dec->ref_bufs_used & 1 << i)) {
+ hevc_dec->ref_bufs_used |= 1 << i;
+ hevc_dec->ref_bufs_poc[i] = poc;
+ hevc_dec->ref_bufs[i].dma = addr;
+@@ -71,23 +67,6 @@ int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr)
+ return -EINVAL;
+ }
+
+-void hantro_hevc_ref_remove_unused(struct hantro_ctx *ctx)
+-{
+- struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
+- int i;
+-
+- /* Just tag buffer as unused, do not free them */
+- for (i = 0; i < NUM_REF_PICTURES; i++) {
+- if (hevc_dec->ref_bufs_poc[i] == UNUSED_REF)
+- continue;
+-
+- if (hevc_dec->ref_bufs_used & (1 << i))
+- continue;
+-
+- hevc_dec->ref_bufs_poc[i] = UNUSED_REF;
+- }
+-}
+-
+ static int tile_buffer_reallocate(struct hantro_ctx *ctx)
+ {
+ struct hantro_dev *vpu = ctx->dev;
+diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
+index df142f31e31b..699c1efc0215 100644
+--- a/drivers/staging/media/hantro/hantro_hw.h
++++ b/drivers/staging/media/hantro/hantro_hw.h
+@@ -338,9 +338,9 @@ int hantro_hevc_dec_init(struct hantro_ctx *ctx);
+ void hantro_hevc_dec_exit(struct hantro_ctx *ctx);
+ int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx);
+ int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx);
++void hantro_hevc_ref_init(struct hantro_ctx *ctx);
+ dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, int poc);
+ int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr);
+-void hantro_hevc_ref_remove_unused(struct hantro_ctx *ctx);
+
+ static inline unsigned short hantro_vp9_num_sbs(unsigned short dimension)
+ {
+--
+2.35.1
+
--- /dev/null
+From 6ef3bd033e0b4668616dda51009cf360bc5f471d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jun 2022 18:50:02 +0100
+Subject: media: hdpvr: fix error value returns in hdpvr_read
+
+From: Niels Dossche <dossche.niels@gmail.com>
+
+[ Upstream commit 359c27c6ddbde404f44a9c0d3ec88ccd1e2042f2 ]
+
+Error return values are supposed to be negative in hdpvr_read. Most
+error returns are currently handled via an unsigned integer "ret". When
+setting a negative error value to "ret", the value actually becomes a
+large positive value, because "ret" is unsigned. Later on, the "ret"
+value is returned. But as ssize_t is a 64-bit signed number, the error
+return value stays a large positive integer instead of a negative
+integer. This can cause an error value to be interpreted as the read
+size, which can cause a buffer overread for applications relying on the
+returned size.
+
+Fixes: 9aba42efe85b ("V4L/DVB (11096): V4L2 Driver for the Hauppauge HD PVR usb capture device")
+Signed-off-by: Niels Dossche <dossche.niels@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/hdpvr/hdpvr-video.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c
+index 60e57e0f1927..fd7d2a9d0449 100644
+--- a/drivers/media/usb/hdpvr/hdpvr-video.c
++++ b/drivers/media/usb/hdpvr/hdpvr-video.c
+@@ -409,7 +409,7 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
+ struct hdpvr_device *dev = video_drvdata(file);
+ struct hdpvr_buffer *buf = NULL;
+ struct urb *urb;
+- unsigned int ret = 0;
++ int ret = 0;
+ int rem, cnt;
+
+ if (*pos)
+--
+2.35.1
+
--- /dev/null
+From 5ac30e2b5058e519beca1bf6895c6aa1a93c0edd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 08:49:19 +0100
+Subject: media: imx-jpeg: Align upwards buffer size
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 9e7aa76cdb02923ee23a0ddd48f38bdc3512f92b ]
+
+The hardware can support any image size WxH,
+with arbitrary W (image width) and H (image height) dimensions.
+
+Align upwards buffer size for both encoder and decoder.
+and leave the picture resolution unchanged.
+
+For decoder, the risk of memory out of bounds can be avoided.
+For both encoder and decoder, the driver will lift the limitation of
+resolution alignment.
+
+For example, the decoder can support jpeg whose resolution is 227x149
+the encoder can support nv12 1080P, won't change it to 1920x1072.
+
+Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 88 ++++++++-----------
+ 1 file changed, 37 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index eea03556bec7..04617bf40c51 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -894,8 +894,8 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf,
+ jpeg->slot_data[slot].cfg_stream_size =
+ mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr,
+ q_data->fmt->fourcc,
+- q_data->w_adjusted,
+- q_data->h_adjusted);
++ q_data->w,
++ q_data->h);
+
+ /* chain the config descriptor with the encoding descriptor */
+ cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN;
+@@ -977,7 +977,7 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx,
+ &q_data_cap->h_adjusted,
+ q_data_cap->h_adjusted, /* adjust up */
+ MXC_JPEG_MAX_HEIGHT,
+- q_data_cap->fmt->v_align,
++ 0,
+ 0);
+
+ /* setup bytesperline/sizeimage for capture queue */
+@@ -1161,16 +1161,28 @@ static int mxc_jpeg_queue_setup(struct vb2_queue *q,
+ {
+ struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q);
+ struct mxc_jpeg_q_data *q_data = NULL;
++ struct mxc_jpeg_q_data tmp_q;
+ int i;
+
+ q_data = mxc_jpeg_get_q_data(ctx, q->type);
+ if (!q_data)
+ return -EINVAL;
+
++ tmp_q.fmt = q_data->fmt;
++ tmp_q.w = q_data->w_adjusted;
++ tmp_q.h = q_data->h_adjusted;
++ for (i = 0; i < MXC_JPEG_MAX_PLANES; i++) {
++ tmp_q.bytesperline[i] = q_data->bytesperline[i];
++ tmp_q.sizeimage[i] = q_data->sizeimage[i];
++ }
++ mxc_jpeg_sizeimage(&tmp_q);
++ for (i = 0; i < MXC_JPEG_MAX_PLANES; i++)
++ tmp_q.sizeimage[i] = max(tmp_q.sizeimage[i], q_data->sizeimage[i]);
++
+ /* Handle CREATE_BUFS situation - *nplanes != 0 */
+ if (*nplanes) {
+ for (i = 0; i < *nplanes; i++) {
+- if (sizes[i] < q_data->sizeimage[i])
++ if (sizes[i] < tmp_q.sizeimage[i])
+ return -EINVAL;
+ }
+ return 0;
+@@ -1179,7 +1191,7 @@ static int mxc_jpeg_queue_setup(struct vb2_queue *q,
+ /* Handle REQBUFS situation */
+ *nplanes = q_data->fmt->colplanes;
+ for (i = 0; i < *nplanes; i++)
+- sizes[i] = q_data->sizeimage[i];
++ sizes[i] = tmp_q.sizeimage[i];
+
+ return 0;
+ }
+@@ -1379,11 +1391,6 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
+ }
+ q_data_out->w = header.frame.width;
+ q_data_out->h = header.frame.height;
+- if (header.frame.width % 8 != 0 || header.frame.height % 8 != 0) {
+- dev_err(dev, "JPEG width or height not multiple of 8: %dx%d\n",
+- header.frame.width, header.frame.height);
+- return -EINVAL;
+- }
+ if (header.frame.width > MXC_JPEG_MAX_WIDTH ||
+ header.frame.height > MXC_JPEG_MAX_HEIGHT) {
+ dev_err(dev, "JPEG width or height should be <= 8192: %dx%d\n",
+@@ -1695,22 +1702,17 @@ static int mxc_jpeg_try_fmt(struct v4l2_format *f, const struct mxc_jpeg_fmt *fm
+ pix_mp->num_planes = fmt->colplanes;
+ pix_mp->pixelformat = fmt->fourcc;
+
+- /*
+- * use MXC_JPEG_H_ALIGN instead of fmt->v_align, for vertical
+- * alignment, to loosen up the alignment to multiple of 8,
+- * otherwise NV12-1080p fails as 1080 is not a multiple of 16
+- */
++ pix_mp->width = w;
++ pix_mp->height = h;
+ v4l_bound_align_image(&w,
+- MXC_JPEG_MIN_WIDTH,
+- w, /* adjust downwards*/
++ w, /* adjust upwards*/
++ MXC_JPEG_MAX_WIDTH,
+ fmt->h_align,
+ &h,
+- MXC_JPEG_MIN_HEIGHT,
+- h, /* adjust downwards*/
+- MXC_JPEG_H_ALIGN,
++ h, /* adjust upwards*/
++ MXC_JPEG_MAX_HEIGHT,
++ 0,
+ 0);
+- pix_mp->width = w; /* negotiate the width */
+- pix_mp->height = h; /* negotiate the height */
+
+ /* get user input into the tmp_q */
+ tmp_q.w = w;
+@@ -1836,35 +1838,19 @@ static int mxc_jpeg_s_fmt(struct mxc_jpeg_ctx *ctx,
+
+ q_data->w_adjusted = q_data->w;
+ q_data->h_adjusted = q_data->h;
+- if (jpeg->mode == MXC_JPEG_DECODE) {
+- /*
+- * align up the resolution for CAST IP,
+- * but leave the buffer resolution unchanged
+- */
+- v4l_bound_align_image(&q_data->w_adjusted,
+- q_data->w_adjusted, /* adjust upwards */
+- MXC_JPEG_MAX_WIDTH,
+- q_data->fmt->h_align,
+- &q_data->h_adjusted,
+- q_data->h_adjusted, /* adjust upwards */
+- MXC_JPEG_MAX_HEIGHT,
+- q_data->fmt->v_align,
+- 0);
+- } else {
+- /*
+- * align down the resolution for CAST IP,
+- * but leave the buffer resolution unchanged
+- */
+- v4l_bound_align_image(&q_data->w_adjusted,
+- MXC_JPEG_MIN_WIDTH,
+- q_data->w_adjusted, /* adjust downwards*/
+- q_data->fmt->h_align,
+- &q_data->h_adjusted,
+- MXC_JPEG_MIN_HEIGHT,
+- q_data->h_adjusted, /* adjust downwards*/
+- q_data->fmt->v_align,
+- 0);
+- }
++ /*
++ * align up the resolution for CAST IP,
++ * but leave the buffer resolution unchanged
++ */
++ v4l_bound_align_image(&q_data->w_adjusted,
++ q_data->w_adjusted, /* adjust upwards */
++ MXC_JPEG_MAX_WIDTH,
++ q_data->fmt->h_align,
++ &q_data->h_adjusted,
++ q_data->h_adjusted, /* adjust upwards */
++ MXC_JPEG_MAX_HEIGHT,
++ q_data->fmt->v_align,
++ 0);
+
+ for (i = 0; i < pix_mp->num_planes; i++) {
+ q_data->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline;
+--
+2.35.1
+
--- /dev/null
+From 66c33a848e5d9e114d4be6638b304917201a9d46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 08:47:31 +0100
+Subject: media: imx-jpeg: Correct some definition according specification
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 5a601f89e846c1b6005ab274d039e5036fc22015 ]
+
+the register CAST_NOMFRSIZE_LO should be equal to CAST_STATUS16
+the register CAST_NOMFRSIZE_HI should be equal to CAST_STATUS17
+the register CAST_OFBSIZE_LO should be equal to CAST_STATUS18
+the register CAST_OFBSIZE_HI should be equal to CAST_STATUS19
+
+Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
+index ae70d3a0dc24..12f132a83a23 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
+@@ -53,10 +53,10 @@
+ #define CAST_REC_REGS_SEL CAST_STATUS4
+ #define CAST_LUMTH CAST_STATUS5
+ #define CAST_CHRTH CAST_STATUS6
+-#define CAST_NOMFRSIZE_LO CAST_STATUS7
+-#define CAST_NOMFRSIZE_HI CAST_STATUS8
+-#define CAST_OFBSIZE_LO CAST_STATUS9
+-#define CAST_OFBSIZE_HI CAST_STATUS10
++#define CAST_NOMFRSIZE_LO CAST_STATUS16
++#define CAST_NOMFRSIZE_HI CAST_STATUS17
++#define CAST_OFBSIZE_LO CAST_STATUS18
++#define CAST_OFBSIZE_HI CAST_STATUS19
+
+ #define MXC_MAX_SLOTS 1 /* TODO use all 4 slots*/
+ /* JPEG-Decoder Wrapper Slot Registers 0..3 */
+--
+2.35.1
+
--- /dev/null
+From 341a57bb5be68138a6c53e4bbd838ea58c5528e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 03:00:57 +0100
+Subject: media: imx-jpeg: Disable slot interrupt when frame done
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 22a2bc88c139dc9757bdb1d0a3665ac27edc79a5 ]
+
+The interrupt STMBUF_HALF may be triggered after frame done.
+It may led to system hang if driver try to access the register after
+power off.
+
+Disable the slot interrupt when frame done.
+
+Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Tested-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c | 5 +++++
+ drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h | 1 +
+ drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 10 ++--------
+ 3 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c
+index 29c604b1b179..718b7b08f93e 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c
+@@ -79,6 +79,11 @@ void mxc_jpeg_enable_irq(void __iomem *reg, int slot)
+ writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN));
+ }
+
++void mxc_jpeg_disable_irq(void __iomem *reg, int slot)
++{
++ writel(0x0, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN));
++}
++
+ void mxc_jpeg_sw_reset(void __iomem *reg)
+ {
+ /*
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
+index 12f132a83a23..bf4e1973a066 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
+@@ -125,6 +125,7 @@ u32 mxc_jpeg_get_offset(void __iomem *reg, int slot);
+ void mxc_jpeg_enable_slot(void __iomem *reg, int slot);
+ void mxc_jpeg_set_l_endian(void __iomem *reg, int le);
+ void mxc_jpeg_enable_irq(void __iomem *reg, int slot);
++void mxc_jpeg_disable_irq(void __iomem *reg, int slot);
+ int mxc_jpeg_set_input(void __iomem *reg, u32 in_buf, u32 bufsize);
+ int mxc_jpeg_set_output(void __iomem *reg, u16 out_pitch, u32 out_buf,
+ u16 w, u16 h);
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index 8c0bd8b75b00..c287eb789fe6 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -593,15 +593,8 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+ dev_dbg(dev, "Irq %d on slot %d.\n", irq, slot);
+
+ ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
+- if (!ctx) {
+- dev_err(dev,
+- "Instance released before the end of transaction.\n");
+- /* soft reset only resets internal state, not registers */
+- mxc_jpeg_sw_reset(reg);
+- /* clear all interrupts */
+- writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
++ if (WARN_ON(!ctx))
+ goto job_unlock;
+- }
+
+ if (slot != ctx->slot) {
+ /* TODO investigate when adding multi-instance support */
+@@ -673,6 +666,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+ buf_state = VB2_BUF_STATE_DONE;
+
+ buffers_done:
++ mxc_jpeg_disable_irq(reg, ctx->slot);
+ jpeg->slot_data[slot].used = false; /* unused, but don't free */
+ mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf);
+ v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+--
+2.35.1
+
--- /dev/null
+From 55af8b5785128d3c3ae1dd5eabe8f8f8954d8b84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Mar 2022 10:05:57 +0100
+Subject: media: imx-jpeg: Handle source change in a function
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 831f87424dd3973612782983ef7352789795b4df ]
+
+Refine code to support dynamic resolution change
+
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 114 ++++++++++--------
+ 1 file changed, 65 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index ece53821859c..07eed00ca5e0 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -315,6 +315,9 @@ struct mxc_jpeg_src_buf {
+ /* mxc-jpeg specific */
+ bool dht_needed;
+ bool jpeg_parse_error;
++ const struct mxc_jpeg_fmt *fmt;
++ int w;
++ int h;
+ };
+
+ static inline struct mxc_jpeg_src_buf *vb2_to_mxc_buf(struct vb2_buffer *vb)
+@@ -327,6 +330,9 @@ static unsigned int debug;
+ module_param(debug, int, 0644);
+ MODULE_PARM_DESC(debug, "Debug level (0-3)");
+
++static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision);
++static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q);
++
+ static void _bswap16(u16 *a)
+ {
+ *a = ((*a & 0x00FF) << 8) | ((*a & 0xFF00) >> 8);
+@@ -929,6 +935,59 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf,
+ mxc_jpeg_set_desc(cfg_desc_handle, reg, slot);
+ }
+
++static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx,
++ struct mxc_jpeg_src_buf *jpeg_src_buf)
++{
++ struct device *dev = ctx->mxc_jpeg->dev;
++ struct mxc_jpeg_q_data *q_data_cap;
++ bool src_chg = false;
++
++ if (!jpeg_src_buf->fmt)
++ return src_chg;
++
++ q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
++ if (q_data_cap->w != jpeg_src_buf->w || q_data_cap->h != jpeg_src_buf->h) {
++ dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n",
++ q_data_cap->w, q_data_cap->h,
++ jpeg_src_buf->w, jpeg_src_buf->h,
++ (jpeg_src_buf->fmt->fourcc & 0xff),
++ (jpeg_src_buf->fmt->fourcc >> 8) & 0xff,
++ (jpeg_src_buf->fmt->fourcc >> 16) & 0xff,
++ (jpeg_src_buf->fmt->fourcc >> 24) & 0xff);
++
++ /*
++ * set-up the capture queue with the pixelformat and resolution
++ * detected from the jpeg output stream
++ */
++ q_data_cap->w = jpeg_src_buf->w;
++ q_data_cap->h = jpeg_src_buf->h;
++ q_data_cap->fmt = jpeg_src_buf->fmt;
++ q_data_cap->w_adjusted = q_data_cap->w;
++ q_data_cap->h_adjusted = q_data_cap->h;
++
++ /*
++ * align up the resolution for CAST IP,
++ * but leave the buffer resolution unchanged
++ */
++ v4l_bound_align_image(&q_data_cap->w_adjusted,
++ q_data_cap->w_adjusted, /* adjust up */
++ MXC_JPEG_MAX_WIDTH,
++ q_data_cap->fmt->h_align,
++ &q_data_cap->h_adjusted,
++ q_data_cap->h_adjusted, /* adjust up */
++ MXC_JPEG_MAX_HEIGHT,
++ q_data_cap->fmt->v_align,
++ 0);
++
++ /* setup bytesperline/sizeimage for capture queue */
++ mxc_jpeg_bytesperline(q_data_cap, jpeg_src_buf->fmt->precision);
++ mxc_jpeg_sizeimage(q_data_cap);
++ notify_src_chg(ctx);
++ src_chg = true;
++ }
++ return src_chg;
++}
++
+ static void mxc_jpeg_device_run(void *priv)
+ {
+ struct mxc_jpeg_ctx *ctx = priv;
+@@ -1216,8 +1275,7 @@ static u32 mxc_jpeg_get_image_format(struct device *dev,
+ return fourcc;
+ }
+
+-static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q,
+- u32 precision)
++static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q, u32 precision)
+ {
+ /* Bytes distance between the leftmost pixels in two adjacent lines */
+ if (q->fmt->fourcc == V4L2_PIX_FMT_JPEG) {
+@@ -1268,9 +1326,7 @@ static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q)
+ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
+ {
+ struct device *dev = ctx->mxc_jpeg->dev;
+- struct mxc_jpeg_q_data *q_data_out, *q_data_cap;
+- enum v4l2_buf_type cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+- bool src_chg = false;
++ struct mxc_jpeg_q_data *q_data_out;
+ u32 fourcc;
+ struct v4l2_jpeg_header header;
+ struct mxc_jpeg_sof *psof = NULL;
+@@ -1338,51 +1394,11 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
+ if (fourcc == 0)
+ return -EINVAL;
+
+- /*
+- * set-up the capture queue with the pixelformat and resolution
+- * detected from the jpeg output stream
+- */
+- q_data_cap = mxc_jpeg_get_q_data(ctx, cap_type);
+- if (q_data_cap->w != header.frame.width ||
+- q_data_cap->h != header.frame.height)
+- src_chg = true;
+- q_data_cap->w = header.frame.width;
+- q_data_cap->h = header.frame.height;
+- q_data_cap->fmt = mxc_jpeg_find_format(ctx, fourcc);
+- q_data_cap->w_adjusted = q_data_cap->w;
+- q_data_cap->h_adjusted = q_data_cap->h;
+- /*
+- * align up the resolution for CAST IP,
+- * but leave the buffer resolution unchanged
+- */
+- v4l_bound_align_image(&q_data_cap->w_adjusted,
+- q_data_cap->w_adjusted, /* adjust up */
+- MXC_JPEG_MAX_WIDTH,
+- q_data_cap->fmt->h_align,
+- &q_data_cap->h_adjusted,
+- q_data_cap->h_adjusted, /* adjust up */
+- MXC_JPEG_MAX_HEIGHT,
+- q_data_cap->fmt->v_align,
+- 0);
+- dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n",
+- q_data_cap->w, q_data_cap->h,
+- q_data_cap->w_adjusted, q_data_cap->h_adjusted,
+- (fourcc & 0xff),
+- (fourcc >> 8) & 0xff,
+- (fourcc >> 16) & 0xff,
+- (fourcc >> 24) & 0xff);
+-
+- /* setup bytesperline/sizeimage for capture queue */
+- mxc_jpeg_bytesperline(q_data_cap, q_data_cap->fmt->precision);
+- mxc_jpeg_sizeimage(q_data_cap);
++ jpeg_src_buf->fmt = mxc_jpeg_find_format(ctx, fourcc);
++ jpeg_src_buf->w = header.frame.width;
++ jpeg_src_buf->h = header.frame.height;
+
+- /*
+- * if the CAPTURE format was updated with new values, regardless of
+- * whether they match the values set by the client or not, signal
+- * a source change event
+- */
+- if (src_chg)
+- notify_src_chg(ctx);
++ mxc_jpeg_source_change(ctx, jpeg_src_buf);
+
+ return 0;
+ }
+--
+2.35.1
+
--- /dev/null
+From 2927fed30d65bb30c0ed79e053688090e424249c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Mar 2022 10:05:55 +0100
+Subject: media: imx-jpeg: Identify and handle precision correctly
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit bec0a3a67389ede106d0661a007edf832878d8b2 ]
+
+The decoder will save the precision that was detected from jpeg header
+and use it later, when choosing the pixel format and also calculate
+bytesperline according to precision.
+
+The 12bit jpeg is not supported yet,
+but driver shouldn't led to serious problem if user enqueue a 12 bit jpeg.
+And the 12bit jpeg is supported by hardware, driver may support it later.
+
+[hverkuil: document the new precision field]
+
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 37 +++++++++++++------
+ .../media/platform/nxp/imx-jpeg/mxc-jpeg.h | 2 +
+ 2 files changed, 27 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index d5a4d66b3998..ece53821859c 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -82,6 +82,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
+ .h_align = 3,
+ .v_align = 3,
+ .flags = MXC_JPEG_FMT_TYPE_RAW,
++ .precision = 8,
+ },
+ {
+ .name = "ARGB", /* ARGBARGB packed format */
+@@ -93,6 +94,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
+ .h_align = 3,
+ .v_align = 3,
+ .flags = MXC_JPEG_FMT_TYPE_RAW,
++ .precision = 8,
+ },
+ {
+ .name = "YUV420", /* 1st plane = Y, 2nd plane = UV */
+@@ -104,6 +106,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
+ .h_align = 4,
+ .v_align = 4,
+ .flags = MXC_JPEG_FMT_TYPE_RAW,
++ .precision = 8,
+ },
+ {
+ .name = "YUV422", /* YUYV */
+@@ -115,6 +118,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
+ .h_align = 4,
+ .v_align = 3,
+ .flags = MXC_JPEG_FMT_TYPE_RAW,
++ .precision = 8,
+ },
+ {
+ .name = "YUV444", /* YUVYUV */
+@@ -126,6 +130,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
+ .h_align = 3,
+ .v_align = 3,
+ .flags = MXC_JPEG_FMT_TYPE_RAW,
++ .precision = 8,
+ },
+ {
+ .name = "Gray", /* Gray (Y8/Y12) or Single Comp */
+@@ -137,6 +142,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
+ .h_align = 3,
+ .v_align = 3,
+ .flags = MXC_JPEG_FMT_TYPE_RAW,
++ .precision = 8,
+ },
+ };
+
+@@ -1182,14 +1188,17 @@ static u32 mxc_jpeg_get_image_format(struct device *dev,
+
+ for (i = 0; i < MXC_JPEG_NUM_FORMATS; i++)
+ if (mxc_formats[i].subsampling == header->frame.subsampling &&
+- mxc_formats[i].nc == header->frame.num_components) {
++ mxc_formats[i].nc == header->frame.num_components &&
++ mxc_formats[i].precision == header->frame.precision) {
+ fourcc = mxc_formats[i].fourcc;
+ break;
+ }
+ if (fourcc == 0) {
+- dev_err(dev, "Could not identify image format nc=%d, subsampling=%d\n",
++ dev_err(dev,
++ "Could not identify image format nc=%d, subsampling=%d, precision=%d\n",
+ header->frame.num_components,
+- header->frame.subsampling);
++ header->frame.subsampling,
++ header->frame.precision);
+ return fourcc;
+ }
+ /*
+@@ -1215,18 +1224,22 @@ static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q,
+ /* bytesperline unused for compressed formats */
+ q->bytesperline[0] = 0;
+ q->bytesperline[1] = 0;
+- } else if (q->fmt->fourcc == V4L2_PIX_FMT_NV12M) {
++ } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420) {
+ /* When the image format is planar the bytesperline value
+ * applies to the first plane and is divided by the same factor
+ * as the width field for the other planes
+ */
+- q->bytesperline[0] = q->w * (precision / 8) *
+- (q->fmt->depth / 8);
++ q->bytesperline[0] = q->w * DIV_ROUND_UP(precision, 8);
+ q->bytesperline[1] = q->bytesperline[0];
++ } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_422) {
++ q->bytesperline[0] = q->w * DIV_ROUND_UP(precision, 8) * 2;
++ q->bytesperline[1] = 0;
++ } else if (q->fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_444) {
++ q->bytesperline[0] = q->w * DIV_ROUND_UP(precision, 8) * q->fmt->nc;
++ q->bytesperline[1] = 0;
+ } else {
+- /* single plane formats */
+- q->bytesperline[0] = q->w * (precision / 8) *
+- (q->fmt->depth / 8);
++ /* grayscale */
++ q->bytesperline[0] = q->w * DIV_ROUND_UP(precision, 8);
+ q->bytesperline[1] = 0;
+ }
+ }
+@@ -1360,7 +1373,7 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
+ (fourcc >> 24) & 0xff);
+
+ /* setup bytesperline/sizeimage for capture queue */
+- mxc_jpeg_bytesperline(q_data_cap, header.frame.precision);
++ mxc_jpeg_bytesperline(q_data_cap, q_data_cap->fmt->precision);
+ mxc_jpeg_sizeimage(q_data_cap);
+
+ /*
+@@ -1516,7 +1529,7 @@ static void mxc_jpeg_set_default_params(struct mxc_jpeg_ctx *ctx)
+ q[i]->h = MXC_JPEG_DEFAULT_HEIGHT;
+ q[i]->w_adjusted = MXC_JPEG_DEFAULT_WIDTH;
+ q[i]->h_adjusted = MXC_JPEG_DEFAULT_HEIGHT;
+- mxc_jpeg_bytesperline(q[i], 8);
++ mxc_jpeg_bytesperline(q[i], q[i]->fmt->precision);
+ mxc_jpeg_sizeimage(q[i]);
+ }
+ }
+@@ -1658,7 +1671,7 @@ static int mxc_jpeg_try_fmt(struct v4l2_format *f, const struct mxc_jpeg_fmt *fm
+ }
+
+ /* calculate bytesperline & sizeimage into the tmp_q */
+- mxc_jpeg_bytesperline(&tmp_q, 8);
++ mxc_jpeg_bytesperline(&tmp_q, fmt->precision);
+ mxc_jpeg_sizeimage(&tmp_q);
+
+ /* adjust user format according to our calculations */
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
+index f53f004ba851..2b4b30d01e51 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
+@@ -49,6 +49,7 @@ enum mxc_jpeg_mode {
+ * @h_align: horizontal alignment order (align to 2^h_align)
+ * @v_align: vertical alignment order (align to 2^v_align)
+ * @flags: flags describing format applicability
++ * @precision: jpeg sample precision
+ */
+ struct mxc_jpeg_fmt {
+ const char *name;
+@@ -60,6 +61,7 @@ struct mxc_jpeg_fmt {
+ int h_align;
+ int v_align;
+ u32 flags;
++ u8 precision;
+ };
+
+ struct mxc_jpeg_desc {
+--
+2.35.1
+
--- /dev/null
+From db25f3a26519a37e3777ad65853469fc9b93c2cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 08:50:02 +0100
+Subject: media: imx-jpeg: Implement drain using v4l2-mem2mem helpers
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 4911c5acf9351c4caf692895c7cf6a4fa46c26b0 ]
+
+v4l2 m2m has supplied some helper function to handle drain,
+so the driver can use the helper function directly.
+
+Fixes: d8ebe298d008c ("media: imx-jpeg: Set V4L2_BUF_FLAG_LAST at eos")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 155 +++++++++---------
+ .../media/platform/nxp/imx-jpeg/mxc-jpeg.h | 2 -
+ 2 files changed, 73 insertions(+), 84 deletions(-)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index 04617bf40c51..8c0bd8b75b00 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -559,6 +559,18 @@ static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg,
+ jpeg->slot_data[slot].used = false;
+ }
+
++static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx,
++ struct vb2_v4l2_buffer *src_buf,
++ struct vb2_v4l2_buffer *dst_buf)
++{
++ if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) {
++ dst_buf->flags |= V4L2_BUF_FLAG_LAST;
++ v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx);
++ notify_eos(ctx);
++ ctx->header_parsed = false;
++ }
++}
++
+ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+ {
+ struct mxc_jpeg_dev *jpeg = priv;
+@@ -633,6 +645,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+ dev_dbg(dev, "Decoder DHT cfg finished. Start decoding...\n");
+ goto job_unlock;
+ }
++
+ if (jpeg->mode == MXC_JPEG_ENCODE) {
+ payload = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_BUF_PTR));
+ vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload);
+@@ -661,6 +674,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
+
+ buffers_done:
+ jpeg->slot_data[slot].used = false; /* unused, but don't free */
++ mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf);
+ v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+ v4l2_m2m_buf_done(src_buf, buf_state);
+@@ -1034,6 +1048,7 @@ static void mxc_jpeg_device_run(void *priv)
+ jpeg_src_buf->jpeg_parse_error = true;
+ }
+ if (jpeg_src_buf->jpeg_parse_error) {
++ mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf);
+ v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+ v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
+@@ -1084,45 +1099,33 @@ static void mxc_jpeg_device_run(void *priv)
+ spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
+ }
+
+-static void mxc_jpeg_set_last_buffer_dequeued(struct mxc_jpeg_ctx *ctx)
+-{
+- struct vb2_queue *q;
+-
+- ctx->stopped = 1;
+- q = v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx);
+- if (!list_empty(&q->done_list))
+- return;
+-
+- q->last_buffer_dequeued = true;
+- wake_up(&q->done_wq);
+- ctx->stopped = 0;
+- ctx->header_parsed = false;
+-}
+-
+ static int mxc_jpeg_decoder_cmd(struct file *file, void *priv,
+ struct v4l2_decoder_cmd *cmd)
+ {
+ struct v4l2_fh *fh = file->private_data;
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
+- struct device *dev = ctx->mxc_jpeg->dev;
+ int ret;
+
+ ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd);
+ if (ret < 0)
+ return ret;
+
+- if (cmd->cmd == V4L2_DEC_CMD_STOP) {
+- dev_dbg(dev, "Received V4L2_DEC_CMD_STOP");
+- if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) == 0) {
+- /* No more src bufs, notify app EOS */
+- notify_eos(ctx);
+- mxc_jpeg_set_last_buffer_dequeued(ctx);
+- } else {
+- /* will send EOS later*/
+- ctx->stopping = 1;
+- }
++ if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx)))
++ return 0;
++
++ ret = v4l2_m2m_ioctl_decoder_cmd(file, priv, cmd);
++ if (ret < 0)
++ return ret;
++
++ if (cmd->cmd == V4L2_DEC_CMD_STOP &&
++ v4l2_m2m_has_stopped(fh->m2m_ctx)) {
++ notify_eos(ctx);
++ ctx->header_parsed = false;
+ }
+
++ if (cmd->cmd == V4L2_DEC_CMD_START &&
++ v4l2_m2m_has_stopped(fh->m2m_ctx))
++ vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q);
+ return 0;
+ }
+
+@@ -1131,24 +1134,27 @@ static int mxc_jpeg_encoder_cmd(struct file *file, void *priv,
+ {
+ struct v4l2_fh *fh = file->private_data;
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh);
+- struct device *dev = ctx->mxc_jpeg->dev;
+ int ret;
+
+ ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd);
+ if (ret < 0)
+ return ret;
+
+- if (cmd->cmd == V4L2_ENC_CMD_STOP) {
+- dev_dbg(dev, "Received V4L2_ENC_CMD_STOP");
+- if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) == 0) {
+- /* No more src bufs, notify app EOS */
+- notify_eos(ctx);
+- mxc_jpeg_set_last_buffer_dequeued(ctx);
+- } else {
+- /* will send EOS later*/
+- ctx->stopping = 1;
+- }
+- }
++ if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx)) ||
++ !vb2_is_streaming(v4l2_m2m_get_dst_vq(fh->m2m_ctx)))
++ return 0;
++
++ ret = v4l2_m2m_ioctl_encoder_cmd(file, fh, cmd);
++ if (ret < 0)
++ return 0;
++
++ if (cmd->cmd == V4L2_ENC_CMD_STOP &&
++ v4l2_m2m_has_stopped(fh->m2m_ctx))
++ notify_eos(ctx);
++
++ if (cmd->cmd == V4L2_ENC_CMD_START &&
++ v4l2_m2m_has_stopped(fh->m2m_ctx))
++ vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q);
+
+ return 0;
+ }
+@@ -1202,6 +1208,8 @@ static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
+ struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, q->type);
+ int ret;
+
++ v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q);
++
+ if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(q->type))
+ ctx->source_change = 0;
+ dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx);
+@@ -1233,11 +1241,15 @@ static void mxc_jpeg_stop_streaming(struct vb2_queue *q)
+ break;
+ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+ }
+- pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev);
+- if (V4L2_TYPE_IS_OUTPUT(q->type)) {
+- ctx->stopping = 0;
+- ctx->stopped = 0;
++
++ v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q);
++ if (V4L2_TYPE_IS_OUTPUT(q->type) &&
++ v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) {
++ notify_eos(ctx);
++ ctx->header_parsed = false;
+ }
++
++ pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev);
+ }
+
+ static int mxc_jpeg_valid_comp_id(struct device *dev,
+@@ -1436,6 +1448,20 @@ static void mxc_jpeg_buf_queue(struct vb2_buffer *vb)
+ struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct mxc_jpeg_src_buf *jpeg_src_buf;
+
++ if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) &&
++ vb2_is_streaming(vb->vb2_queue) &&
++ v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) {
++ struct mxc_jpeg_q_data *q_data;
++
++ q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type);
++ vbuf->field = V4L2_FIELD_NONE;
++ vbuf->sequence = q_data->sequence++;
++ v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf);
++ notify_eos(ctx);
++ ctx->header_parsed = false;
++ return;
++ }
++
+ if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ goto end;
+
+@@ -1485,24 +1511,11 @@ static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb)
+ }
+ vb2_set_plane_payload(vb, i, sizeimage);
+ }
+- return 0;
+-}
+-
+-static void mxc_jpeg_buf_finish(struct vb2_buffer *vb)
+-{
+- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+- struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+- struct vb2_queue *q = vb->vb2_queue;
+-
+- if (V4L2_TYPE_IS_OUTPUT(vb->type))
+- return;
+- if (!ctx->stopped)
+- return;
+- if (list_empty(&q->done_list)) {
+- vbuf->flags |= V4L2_BUF_FLAG_LAST;
+- ctx->stopped = 0;
+- ctx->header_parsed = false;
++ if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) {
++ vb2_set_plane_payload(vb, 0, 0);
++ vb2_set_plane_payload(vb, 1, 0);
+ }
++ return 0;
+ }
+
+ static const struct vb2_ops mxc_jpeg_qops = {
+@@ -1511,7 +1524,6 @@ static const struct vb2_ops mxc_jpeg_qops = {
+ .wait_finish = vb2_ops_wait_finish,
+ .buf_out_validate = mxc_jpeg_buf_out_validate,
+ .buf_prepare = mxc_jpeg_buf_prepare,
+- .buf_finish = mxc_jpeg_buf_finish,
+ .start_streaming = mxc_jpeg_start_streaming,
+ .stop_streaming = mxc_jpeg_stop_streaming,
+ .buf_queue = mxc_jpeg_buf_queue,
+@@ -1932,27 +1944,6 @@ static int mxc_jpeg_subscribe_event(struct v4l2_fh *fh,
+ }
+ }
+
+-static int mxc_jpeg_dqbuf(struct file *file, void *priv,
+- struct v4l2_buffer *buf)
+-{
+- struct v4l2_fh *fh = file->private_data;
+- struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
+- struct device *dev = ctx->mxc_jpeg->dev;
+- int num_src_ready = v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx);
+- int ret;
+-
+- dev_dbg(dev, "DQBUF type=%d, index=%d", buf->type, buf->index);
+- if (ctx->stopping == 1 && num_src_ready == 0) {
+- /* No more src bufs, notify app EOS */
+- notify_eos(ctx);
+- ctx->stopping = 0;
+- mxc_jpeg_set_last_buffer_dequeued(ctx);
+- }
+-
+- ret = v4l2_m2m_dqbuf(file, fh->m2m_ctx, buf);
+- return ret;
+-}
+-
+ static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = {
+ .vidioc_querycap = mxc_jpeg_querycap,
+ .vidioc_enum_fmt_vid_cap = mxc_jpeg_enum_fmt_vid_cap,
+@@ -1976,7 +1967,7 @@ static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = {
+ .vidioc_encoder_cmd = mxc_jpeg_encoder_cmd,
+
+ .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
+- .vidioc_dqbuf = mxc_jpeg_dqbuf,
++ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
+
+ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
+ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
+index 6913ae087e44..542993eb8d5b 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
+@@ -92,8 +92,6 @@ struct mxc_jpeg_ctx {
+ struct mxc_jpeg_q_data cap_q;
+ struct v4l2_fh fh;
+ enum mxc_jpeg_enc_state enc_state;
+- unsigned int stopping;
+- unsigned int stopped;
+ unsigned int slot;
+ unsigned int source_change;
+ bool header_parsed;
+--
+2.35.1
+
--- /dev/null
+From e1639a7839bd3dbb502e61213d9d3bc5400d19f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 08:48:37 +0100
+Subject: media: imx-jpeg: Leave a blank space before the configuration data
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 6285cdea19daf764bf00f662a59fc83ef67345cf ]
+
+There is a hardware bug that it will load
+the first 128 bytes of configuration data twice,
+it will led to some configure error.
+so shift the configuration data 128 bytes,
+and make the first 128 bytes all zero,
+then hardware will load the 128 zero twice,
+and ignore them as garbage.
+then the configuration data can be loaded correctly
+
+Fixes: 2db16c6ed72ce ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Reviewed-by: Tommaso Merciai <tommaso.merciai@amarulasolutions.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index d1ec1f4b506b..b53b2317bcee 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -508,6 +508,7 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg,
+ GFP_ATOMIC);
+ if (!cfg_stm)
+ goto err;
++ memset(cfg_stm, 0, MXC_JPEG_MAX_CFG_STREAM);
+ jpeg->slot_data[slot].cfg_stream_vaddr = cfg_stm;
+
+ skip_alloc:
+@@ -743,7 +744,13 @@ static unsigned int mxc_jpeg_setup_cfg_stream(void *cfg_stream_vaddr,
+ u32 fourcc,
+ u16 w, u16 h)
+ {
+- unsigned int offset = 0;
++ /*
++ * There is a hardware issue that first 128 bytes of configuration data
++ * can't be loaded correctly.
++ * To avoid this issue, we need to write the configuration from
++ * an offset which should be no less than 0x80 (128 bytes).
++ */
++ unsigned int offset = 0x80;
+ u8 *cfg = (u8 *)cfg_stream_vaddr;
+ struct mxc_jpeg_sof *sof;
+ struct mxc_jpeg_sos *sos;
+--
+2.35.1
+
--- /dev/null
+From 9f185d452adea3b5fa26f6c7c7d1df890aefd536 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Mar 2022 10:05:54 +0100
+Subject: media: imx-jpeg: Refactor function mxc_jpeg_parse
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit 8dd504a3a0a5f73b4c137ce3afc35936a4ecd871 ]
+
+Refine code to support dynamic resolution change
+
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index b53b2317bcee..d5a4d66b3998 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -1252,8 +1252,7 @@ static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q)
+ }
+ }
+
+-static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx,
+- u8 *src_addr, u32 size, bool *dht_needed)
++static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
+ {
+ struct device *dev = ctx->mxc_jpeg->dev;
+ struct mxc_jpeg_q_data *q_data_out, *q_data_cap;
+@@ -1263,6 +1262,9 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx,
+ struct v4l2_jpeg_header header;
+ struct mxc_jpeg_sof *psof = NULL;
+ struct mxc_jpeg_sos *psos = NULL;
++ struct mxc_jpeg_src_buf *jpeg_src_buf = vb2_to_mxc_buf(vb);
++ u8 *src_addr = (u8 *)vb2_plane_vaddr(vb, 0);
++ u32 size = vb2_get_plane_payload(vb, 0);
+ int ret;
+
+ memset(&header, 0, sizeof(header));
+@@ -1273,7 +1275,7 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx,
+ }
+
+ /* if DHT marker present, no need to inject default one */
+- *dht_needed = (header.num_dht == 0);
++ jpeg_src_buf->dht_needed = (header.num_dht == 0);
+
+ q_data_out = mxc_jpeg_get_q_data(ctx,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+@@ -1388,10 +1390,7 @@ static void mxc_jpeg_buf_queue(struct vb2_buffer *vb)
+
+ jpeg_src_buf = vb2_to_mxc_buf(vb);
+ jpeg_src_buf->jpeg_parse_error = false;
+- ret = mxc_jpeg_parse(ctx,
+- (u8 *)vb2_plane_vaddr(vb, 0),
+- vb2_get_plane_payload(vb, 0),
+- &jpeg_src_buf->dht_needed);
++ ret = mxc_jpeg_parse(ctx, vb);
+ if (ret)
+ jpeg_src_buf->jpeg_parse_error = true;
+
+--
+2.35.1
+
--- /dev/null
+From 8bd22cea396ce02fab0271b9e268a778bf35e3f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Mar 2022 10:05:58 +0100
+Subject: media: imx-jpeg: Support dynamic resolution change
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit b4e1fb8643daabba850e97df532191acffc23e6a ]
+
+To support dynamic resolution change,
+driver should meet the following conditions:
+1. the previous pictures are all decoded before source change event.
+2. prevent decoding new resolution pictures with incorrect capture
+ buffer, until user handle source change event and setup capture.
+3. report correct fmt and resolution during source change.
+
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Reviewed-by: Mirela Rabulea <mirela.rabulea@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 69 ++++++++++++++-----
+ .../media/platform/nxp/imx-jpeg/mxc-jpeg.h | 2 +
+ 2 files changed, 55 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+index 07eed00ca5e0..eea03556bec7 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+@@ -940,13 +940,14 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx,
+ {
+ struct device *dev = ctx->mxc_jpeg->dev;
+ struct mxc_jpeg_q_data *q_data_cap;
+- bool src_chg = false;
+
+ if (!jpeg_src_buf->fmt)
+- return src_chg;
++ return false;
+
+ q_data_cap = mxc_jpeg_get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+- if (q_data_cap->w != jpeg_src_buf->w || q_data_cap->h != jpeg_src_buf->h) {
++ if (q_data_cap->fmt != jpeg_src_buf->fmt ||
++ q_data_cap->w != jpeg_src_buf->w ||
++ q_data_cap->h != jpeg_src_buf->h) {
+ dev_dbg(dev, "Detected jpeg res=(%dx%d)->(%dx%d), pixfmt=%c%c%c%c\n",
+ q_data_cap->w, q_data_cap->h,
+ jpeg_src_buf->w, jpeg_src_buf->h,
+@@ -983,9 +984,16 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx,
+ mxc_jpeg_bytesperline(q_data_cap, jpeg_src_buf->fmt->precision);
+ mxc_jpeg_sizeimage(q_data_cap);
+ notify_src_chg(ctx);
+- src_chg = true;
++ ctx->source_change = 1;
+ }
+- return src_chg;
++ return ctx->source_change ? true : false;
++}
++
++static int mxc_jpeg_job_ready(void *priv)
++{
++ struct mxc_jpeg_ctx *ctx = priv;
++
++ return ctx->source_change ? 0 : 1;
+ }
+
+ static void mxc_jpeg_device_run(void *priv)
+@@ -1035,6 +1043,13 @@ static void mxc_jpeg_device_run(void *priv)
+
+ return;
+ }
++ if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE) {
++ if (ctx->source_change || mxc_jpeg_source_change(ctx, jpeg_src_buf)) {
++ spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags);
++ v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
++ return;
++ }
++ }
+
+ mxc_jpeg_enable(reg);
+ mxc_jpeg_set_l_endian(reg, 1);
+@@ -1081,6 +1096,7 @@ static void mxc_jpeg_set_last_buffer_dequeued(struct mxc_jpeg_ctx *ctx)
+ q->last_buffer_dequeued = true;
+ wake_up(&q->done_wq);
+ ctx->stopped = 0;
++ ctx->header_parsed = false;
+ }
+
+ static int mxc_jpeg_decoder_cmd(struct file *file, void *priv,
+@@ -1174,6 +1190,8 @@ static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
+ struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, q->type);
+ int ret;
+
++ if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(q->type))
++ ctx->source_change = 0;
+ dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx);
+ q_data->sequence = 0;
+
+@@ -1352,16 +1370,15 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
+ dev_warn(dev, "Invalid user resolution 0x0");
+ dev_warn(dev, "Keeping resolution from JPEG: %dx%d",
+ header.frame.width, header.frame.height);
+- q_data_out->w = header.frame.width;
+- q_data_out->h = header.frame.height;
+ } else if (header.frame.width != q_data_out->w ||
+ header.frame.height != q_data_out->h) {
+ dev_err(dev,
+ "Resolution mismatch: %dx%d (JPEG) versus %dx%d(user)",
+ header.frame.width, header.frame.height,
+ q_data_out->w, q_data_out->h);
+- return -EINVAL;
+ }
++ q_data_out->w = header.frame.width;
++ q_data_out->h = header.frame.height;
+ if (header.frame.width % 8 != 0 || header.frame.height % 8 != 0) {
+ dev_err(dev, "JPEG width or height not multiple of 8: %dx%d\n",
+ header.frame.width, header.frame.height);
+@@ -1397,8 +1414,10 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb)
+ jpeg_src_buf->fmt = mxc_jpeg_find_format(ctx, fourcc);
+ jpeg_src_buf->w = header.frame.width;
+ jpeg_src_buf->h = header.frame.height;
++ ctx->header_parsed = true;
+
+- mxc_jpeg_source_change(ctx, jpeg_src_buf);
++ if (!v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx))
++ mxc_jpeg_source_change(ctx, jpeg_src_buf);
+
+ return 0;
+ }
+@@ -1475,6 +1494,7 @@ static void mxc_jpeg_buf_finish(struct vb2_buffer *vb)
+ if (list_empty(&q->done_list)) {
+ vbuf->flags |= V4L2_BUF_FLAG_LAST;
+ ctx->stopped = 0;
++ ctx->header_parsed = false;
+ }
+ }
+
+@@ -1620,26 +1640,42 @@ static int mxc_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+ {
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
++ struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, f->type);
+
+- if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE)
++ if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) {
+ return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
+ MXC_JPEG_FMT_TYPE_ENC);
+- else
++ } else if (!ctx->header_parsed) {
+ return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
+ MXC_JPEG_FMT_TYPE_RAW);
++ } else {
++ /* For the decoder CAPTURE queue, only enumerate the raw formats
++ * supported for the format currently active on OUTPUT
++ * (more precisely what was propagated on capture queue
++ * after jpeg parse on the output buffer)
++ */
++ if (f->index)
++ return -EINVAL;
++ f->pixelformat = q_data->fmt->fourcc;
++ strscpy(f->description, q_data->fmt->name, sizeof(f->description));
++ return 0;
++ }
+ }
+
+ static int mxc_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+ {
+ struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv);
++ u32 type = ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? MXC_JPEG_FMT_TYPE_ENC :
++ MXC_JPEG_FMT_TYPE_RAW;
++ int ret;
+
++ ret = enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f, type);
++ if (ret)
++ return ret;
+ if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE)
+- return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
+- MXC_JPEG_FMT_TYPE_ENC);
+- else
+- return enum_fmt(mxc_formats, MXC_JPEG_NUM_FORMATS, f,
+- MXC_JPEG_FMT_TYPE_RAW);
++ f->flags = V4L2_FMT_FLAG_DYN_RESOLUTION;
++ return 0;
+ }
+
+ static int mxc_jpeg_try_fmt(struct v4l2_format *f, const struct mxc_jpeg_fmt *fmt,
+@@ -1997,6 +2033,7 @@ static const struct v4l2_file_operations mxc_jpeg_fops = {
+ };
+
+ static const struct v4l2_m2m_ops mxc_jpeg_m2m_ops = {
++ .job_ready = mxc_jpeg_job_ready,
+ .device_run = mxc_jpeg_device_run,
+ };
+
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
+index 2b4b30d01e51..6913ae087e44 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
+@@ -95,6 +95,8 @@ struct mxc_jpeg_ctx {
+ unsigned int stopping;
+ unsigned int stopped;
+ unsigned int slot;
++ unsigned int source_change;
++ bool header_parsed;
+ };
+
+ struct mxc_jpeg_slot_data {
+--
+2.35.1
+
--- /dev/null
+From 8a3411e724b8d4b2a82b48961ab7bfad88e1da26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 08:25:21 +0100
+Subject: media: mediatek: vcodec: Fix non subdev architecture open power fail
+
+From: Yunfei Dong <yunfei.dong@mediatek.com>
+
+[ Upstream commit 083f54a7c9c66496b9d9f3c50dfdca24e6aa7012 ]
+
+According to subdev_bitmap bit value to open hardware power, need to
+set subdev_bitmap value for non subdev architecture.
+
+Fixes: c05bada35f01 ("media: mtk-vcodec: Add to support multi hardware decode")
+Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Tested-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
+index bd1ee9901da0..d5c94845ea42 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
+@@ -393,6 +393,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
+ mtk_v4l2_err("Main device of_platform_populate failed.");
+ goto err_reg_cont;
+ }
++ } else {
++ set_bit(MTK_VDEC_CORE, dev->subdev_bitmap);
+ }
+
+ ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, -1);
+--
+2.35.1
+
--- /dev/null
+From f083267c1c06d5ca16641dfe4c4866515d40fb35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jun 2022 08:29:29 +0100
+Subject: media: mediatek: vcodec: Initialize decoder parameters after getting
+ dec_capability
+
+From: Yunfei Dong <yunfei.dong@mediatek.com>
+
+[ Upstream commit faddaa735c208560a3f419038e8d154a01b584e3 ]
+
+Need to get dec_capability from scp first, then initialize decoder
+supported format and other parameters according to dec_capability value.
+
+Fixes: fd00d90330d1 ("media: mtk-vcodec: vdec: move stateful ops into their own file")
+Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Tested-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c | 2 --
+ drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c | 2 ++
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
+index c8ee5e2b4f69..4bb8a2751271 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
+@@ -112,8 +112,6 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
+ {
+ struct mtk_q_data *q_data;
+
+- ctx->dev->vdec_pdata->init_vdec_params(ctx);
+-
+ ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
+ ctx->fh.m2m_ctx = ctx->m2m_ctx;
+ ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
+index fe7b2f1739b1..bd1ee9901da0 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
+@@ -211,6 +211,8 @@ static int fops_vcodec_open(struct file *file)
+
+ dev->dec_capability =
+ mtk_vcodec_fw_get_vdec_capa(dev->fw_handler);
++ ctx->dev->vdec_pdata->init_vdec_params(ctx);
++
+ mtk_v4l2_debug(0, "decoder capability %x", dev->dec_capability);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 9557ea478396ee0d1e37ad8bf583a5945fc8947a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Jul 2022 09:49:30 +0100
+Subject: media: mediatek: vcodec: Initialize decoder parameters for each
+ instance
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit fe3d651627d61210c6905339e5281d3b9db75033 ]
+
+The decoder parameters are stored in each instance's context data. This
+needs to be initialized per-instance, but a previous fix incorrectly
+changed it to only be initialized for the first opened instance. This
+resulted in subsequent instances not correctly signaling the requirement
+for the Requests API.
+
+Fix this by calling the initializing function outside of the
+v4l2_fh_is_singular() conditional block.
+
+Fixes: faddaa735c20 ("media: mediatek: vcodec: Initialize decoder parameters after getting dec_capability")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Yunfei Dong <yunfei.dong@mediatek.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
+index d5c94845ea42..ff8f2a4829a3 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
+@@ -211,11 +211,12 @@ static int fops_vcodec_open(struct file *file)
+
+ dev->dec_capability =
+ mtk_vcodec_fw_get_vdec_capa(dev->fw_handler);
+- ctx->dev->vdec_pdata->init_vdec_params(ctx);
+
+ mtk_v4l2_debug(0, "decoder capability %x", dev->dec_capability);
+ }
+
++ ctx->dev->vdec_pdata->init_vdec_params(ctx);
++
+ list_add(&ctx->list, &dev->ctx_list);
+
+ mutex_unlock(&dev->dev_mutex);
+--
+2.35.1
+
--- /dev/null
+From 1cefd3c3af8bc9f9f3595c050b5f3752b1619453 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 07:33:49 +0100
+Subject: media: mediatek: vcodec: Skip SOURCE_CHANGE & EOS events for
+ stateless
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit e13ca460e20ed42fe57a3845b0bb9a82f81f05cd ]
+
+The stateless decoder API does not specify the usage of SOURCE_CHANGE
+and EOF events. These events are used by stateful decoders to signal
+changes in the bitstream. They do not make sense for stateless decoders.
+
+Do not handle subscription for these two types of events for stateless
+decoder instances. This fixes the last v4l2-compliance error:
+
+Control ioctls:
+ fail: v4l2-test-controls.cpp(946): have_source_change || have_eos
+ test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: FAIL
+
+Fixes: 8cdc3794b2e3 ("media: mtk-vcodec: vdec: support stateless API")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
+index 4bb8a2751271..54489f64533e 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c
+@@ -194,6 +194,11 @@ static int vidioc_vdec_querycap(struct file *file, void *priv,
+ static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+ {
++ struct mtk_vcodec_ctx *ctx = fh_to_ctx(fh);
++
++ if (ctx->dev->vdec_pdata->uses_stateless_api)
++ return v4l2_ctrl_subscribe_event(fh, sub);
++
+ switch (sub->type) {
+ case V4L2_EVENT_EOS:
+ return v4l2_event_subscribe(fh, sub, 2, NULL);
+--
+2.35.1
+
--- /dev/null
+From b71b05ec3dc840e0eab99f6dc556b56800cb9987 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jun 2022 14:55:46 +0100
+Subject: media: platform: mtk-mdp: Fix mdp_ipi_comm structure alignment
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit ab14c99c035da7156a3b66fa171171295bc4b89a ]
+
+The mdp_ipi_comm structure defines a command that is either
+PROCESS (start processing) or DEINIT (destroy instance); we
+are using this one to send PROCESS or DEINIT commands from Linux
+to an MDP instance through a VPU write but, while the first wants
+us to stay 4-bytes aligned, the VPU instead requires an 8-bytes
+data alignment.
+
+Keeping in mind that these commands are executed immediately
+after sending them (hence not chained with others before the
+VPU/MDP "actually" start executing), it is fine to simply add
+a padding of 4 bytes to this structure: this keeps the same
+performance as before, as we're still stack-allocating it,
+while avoiding hackery inside of mtk-vpu to ensure alignment
+bringing a definitely bigger performance impact.
+
+Fixes: c8eb2d7e8202 ("[media] media: Add Mediatek MDP Driver")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Houlong Wei <houlong.wei@mediatek.com>
+Reviewed-by: Irui Wang <irui.wang@mediatek.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h b/drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h
+index 2cb8cecb3077..b810c96695c8 100644
+--- a/drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h
++++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_ipi.h
+@@ -40,12 +40,14 @@ struct mdp_ipi_init {
+ * @ipi_id : IPI_MDP
+ * @ap_inst : AP mtk_mdp_vpu address
+ * @vpu_inst_addr : VPU MDP instance address
++ * @padding : Alignment padding
+ */
+ struct mdp_ipi_comm {
+ uint32_t msg_id;
+ uint32_t ipi_id;
+ uint64_t ap_inst;
+ uint32_t vpu_inst_addr;
++ uint32_t padding;
+ };
+
+ /**
+--
+2.35.1
+
--- /dev/null
+From 58e23bd29cc8807b32d47ad50a7d72655cf88717 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 21:46:57 +0100
+Subject: media: rcar-vin: Fix channel routing for Ebisu
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+
+[ Upstream commit 5b9b598453d3ae5fa66d7ab591008373a89b91a0 ]
+
+When converting to full Virtual Channel routing an error crept into the
+routing table for Ebisu (r8a77990). The routing information is used at
+probe time preventing rcar-vin from probing correctly on this SoC, solve
+by correcting the routing table.
+
+Fixes: 3e52419ec04f9769 ("media: rcar-{csi2,vin}: Move to full Virtual Channel routing per CSI-2 IP")
+Reported-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/renesas/rcar-vin/rcar-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-core.c b/drivers/media/platform/renesas/rcar-vin/rcar-core.c
+index 64cb05b3907c..ed3ddf36f906 100644
+--- a/drivers/media/platform/renesas/rcar-vin/rcar-core.c
++++ b/drivers/media/platform/renesas/rcar-vin/rcar-core.c
+@@ -1264,7 +1264,7 @@ static const struct rvin_info rcar_info_r8a77980 = {
+ };
+
+ static const struct rvin_group_route rcar_info_r8a77990_routes[] = {
+- { .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 },
++ { .master = 4, .csi = RVIN_CSI40, .chsel = 0x03 },
+ { /* Sentinel */ }
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 55788d4d1a5f23f2f79eee18e9fef95dd60cf901 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 09:52:42 +0100
+Subject: media: sta2x11: remove VIRT_TO_BUS dependency
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit a157802359f7451ed8046b2b6dbaca187797e062 ]
+
+This driver does not use the virt_to_bus() function, though it
+depends on x86 specific fixups in the swiotlb code, which was
+last rewritten in commit e380a0394c36 ("x86/PCI: sta2x11: use
+default DMA address translation").
+
+It is possible that the driver still fails to build on some
+architectures that are missing CONFIG_VIRT_TO_BUS, but it is
+always set on x86 machines with the STA2X11 platform enabled.
+
+More likely though is that it was never meant to depend on
+CONFIG_VIRT_TO_BUS, and the Kconfig dependency was kept from
+an out-of-tree version when the driver was originally merged.
+
+Fixes: efeb98b4e2b2 ("[media] STA2X11 VIP: new V4L2 driver")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/sta2x11/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/pci/sta2x11/Kconfig b/drivers/media/pci/sta2x11/Kconfig
+index a96e170ab04e..118b922c08c3 100644
+--- a/drivers/media/pci/sta2x11/Kconfig
++++ b/drivers/media/pci/sta2x11/Kconfig
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ config STA2X11_VIP
+ tristate "STA2X11 VIP Video For Linux"
+- depends on PCI && VIDEO_DEV && VIRT_TO_BUS && I2C
++ depends on PCI && VIDEO_DEV && I2C
+ depends on STA2X11 || COMPILE_TEST
+ select GPIOLIB if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_ADV7180 if MEDIA_SUBDRV_AUTOSELECT
+--
+2.35.1
+
--- /dev/null
+From 5679082ba92cacdc3b2ec0b01b632d04aa0e56d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Mar 2022 19:36:03 +0100
+Subject: media: staging: media: hantro: Fix typos
+
+From: Sebastian Fricke <sebastian.fricke@collabora.com>
+
+[ Upstream commit d8f6f1c56d5469e22eeb7cc1f3580b29e2f0fef5 ]
+
+Fix typos in comments within the Hantro driver.
+
+Signed-off-by: Sebastian Fricke <sebastian.fricke@collabora.com>
+Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/hantro/hantro_g2_hevc_dec.c | 2 +-
+ drivers/staging/media/hantro/hantro_hevc.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+index 5f3178bac9c8..a4642ed1f463 100644
+--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
++++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+@@ -401,7 +401,7 @@ static int set_ref(struct hantro_ctx *ctx)
+
+ set_ref_pic_list(ctx);
+
+- /* We will only keep the references picture that are still used */
++ /* We will only keep the reference pictures that are still used */
+ ctx->hevc_dec.ref_bufs_used = 0;
+
+ /* Set up addresses of DPB buffers */
+diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
+index b49a41d7ae91..9c351f7fe6bd 100644
+--- a/drivers/staging/media/hantro/hantro_hevc.c
++++ b/drivers/staging/media/hantro/hantro_hevc.c
+@@ -59,7 +59,7 @@ dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx,
+ struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
+ int i;
+
+- /* Find the reference buffer in already know ones */
++ /* Find the reference buffer in already known ones */
+ for (i = 0; i < NUM_REF_PICTURES; i++) {
+ if (hevc_dec->ref_bufs_poc[i] == poc) {
+ hevc_dec->ref_bufs_used |= 1 << i;
+--
+2.35.1
+
--- /dev/null
+From d6979e8c8e45e98fad5cfc3ac7bea2489ead8648 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jun 2022 06:30:30 +0100
+Subject: media: tw686x: Fix memory leak in tw686x_video_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit e0b212ec9d8177d6f7c404315293f6a085d6ee42 ]
+
+video_device_alloc() allocates memory for vdev,
+when video_register_device() fails, it doesn't release the memory and
+leads to memory leak, call video_device_release() to fix this.
+
+Fixes: 704a84ccdbf1 ("[media] media: Support Intersil/Techwell TW686x-based video capture cards")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/tw686x/tw686x-video.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/pci/tw686x/tw686x-video.c b/drivers/media/pci/tw686x/tw686x-video.c
+index b227e9e78ebd..37a20fe24241 100644
+--- a/drivers/media/pci/tw686x/tw686x-video.c
++++ b/drivers/media/pci/tw686x/tw686x-video.c
+@@ -1282,8 +1282,10 @@ int tw686x_video_init(struct tw686x_dev *dev)
+ video_set_drvdata(vdev, vc);
+
+ err = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+- if (err < 0)
++ if (err < 0) {
++ video_device_release(vdev);
+ goto error;
++ }
+ vc->num = vdev->num;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From fba3bde985316364142af309e125d7b27bf3ec46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 07:24:01 +0100
+Subject: media: tw686x: Register the irq at the end of probe
+
+From: Zheyu Ma <zheyuma97@gmail.com>
+
+[ Upstream commit fb730334e0f759d00f72168fbc555e5a95e35210 ]
+
+We got the following warning when booting the kernel:
+
+[ 3.243674] INFO: trying to register non-static key.
+[ 3.243922] The code is fine but needs lockdep annotation, or maybe
+[ 3.244230] you didn't initialize this object before use?
+[ 3.245642] Call Trace:
+[ 3.247836] lock_acquire+0xff/0x2d0
+[ 3.248727] tw686x_audio_irq+0x1a5/0xcc0 [tw686x]
+[ 3.249211] tw686x_irq+0x1f9/0x480 [tw686x]
+
+The lock 'vc->qlock' will be initialized in tw686x_video_init(), but the
+driver registers the irq before calling the tw686x_video_init(), and we
+got the warning.
+
+Fix this by registering the irq at the end of probe
+
+Fixes: 704a84ccdbf1 ("[media] media: Support Intersil/Techwell TW686x-based video capture cards")
+Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/tw686x/tw686x-core.c | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/pci/tw686x/tw686x-core.c b/drivers/media/pci/tw686x/tw686x-core.c
+index 6676e069b515..384d38754a4b 100644
+--- a/drivers/media/pci/tw686x/tw686x-core.c
++++ b/drivers/media/pci/tw686x/tw686x-core.c
+@@ -315,13 +315,6 @@ static int tw686x_probe(struct pci_dev *pci_dev,
+
+ spin_lock_init(&dev->lock);
+
+- err = request_irq(pci_dev->irq, tw686x_irq, IRQF_SHARED,
+- dev->name, dev);
+- if (err < 0) {
+- dev_err(&pci_dev->dev, "unable to request interrupt\n");
+- goto iounmap;
+- }
+-
+ timer_setup(&dev->dma_delay_timer, tw686x_dma_delay, 0);
+
+ /*
+@@ -333,18 +326,23 @@ static int tw686x_probe(struct pci_dev *pci_dev,
+ err = tw686x_video_init(dev);
+ if (err) {
+ dev_err(&pci_dev->dev, "can't register video\n");
+- goto free_irq;
++ goto iounmap;
+ }
+
+ err = tw686x_audio_init(dev);
+ if (err)
+ dev_warn(&pci_dev->dev, "can't register audio\n");
+
++ err = request_irq(pci_dev->irq, tw686x_irq, IRQF_SHARED,
++ dev->name, dev);
++ if (err < 0) {
++ dev_err(&pci_dev->dev, "unable to request interrupt\n");
++ goto iounmap;
++ }
++
+ pci_set_drvdata(pci_dev, dev);
+ return 0;
+
+-free_irq:
+- free_irq(pci_dev->irq, dev);
+ iounmap:
+ pci_iounmap(pci_dev, dev->mmio);
+ free_region:
+--
+2.35.1
+
--- /dev/null
+From 861e148bab63d6a03d635e291d5484eb5c4e8c9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 17:21:45 +0100
+Subject: media: uapi: HEVC: Change pic_order_cnt definition in
+ v4l2_hevc_dpb_entry
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+
+[ Upstream commit c4a179c7167ee16aad1267f9c99bc1ecff475585 ]
+
+The HEVC specification describes the following:
+"PicOrderCntVal is derived as follows:
+PicOrderCntVal = PicOrderCntMsb + slice_pic_order_cnt_lsb
+The value of PicOrderCntVal shall be in the range of
+−2^31 to 2^31 − 1, inclusive."
+
+To match with these definitions change __u16 pic_order_cnt[2]
+into __s32 pic_order_cnt_val.
+Change v4l2_ctrl_hevc_slice_params->slice_pic_order_cnt to __s32 too.
+
+Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+Reviewed-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+Acked-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+Tested-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 2 +-
+ drivers/staging/media/hantro/hantro_g2_hevc_dec.c | 7 +++----
+ drivers/staging/media/hantro/hantro_hevc.c | 2 +-
+ drivers/staging/media/hantro/hantro_hw.h | 4 ++--
+ drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 4 ++--
+ include/media/hevc-ctrls.h | 4 ++--
+ 6 files changed, 11 insertions(+), 12 deletions(-)
+
+diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+index 4cd7c541fc30..bcdc14144105 100644
+--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
++++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+@@ -2975,7 +2975,7 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
+ * - __u8
+ - ``colour_plane_id``
+ -
+- * - __u16
++ * - __s32
+ - ``slice_pic_order_cnt``
+ -
+ * - __u8
+diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+index 5df6f08e26f5..d28653d04d20 100644
+--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
++++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+@@ -390,11 +390,10 @@ static int set_ref(struct hantro_ctx *ctx)
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED));
+
+ /*
+- * Write POC count diff from current pic. For frame decoding only compute
+- * pic_order_cnt[0] and ignore pic_order_cnt[1] used in field-coding.
++ * Write POC count diff from current pic.
+ */
+ for (i = 0; i < decode_params->num_active_dpb_entries && i < ARRAY_SIZE(cur_poc); i++) {
+- char poc_diff = decode_params->pic_order_cnt_val - dpb[i].pic_order_cnt[0];
++ char poc_diff = decode_params->pic_order_cnt_val - dpb[i].pic_order_cnt_val;
+
+ hantro_reg_write(vpu, &cur_poc[i], poc_diff);
+ }
+@@ -421,7 +420,7 @@ static int set_ref(struct hantro_ctx *ctx)
+ dpb_longterm_e = 0;
+ for (i = 0; i < decode_params->num_active_dpb_entries &&
+ i < (V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1); i++) {
+- luma_addr = hantro_hevc_get_ref_buf(ctx, dpb[i].pic_order_cnt[0]);
++ luma_addr = hantro_hevc_get_ref_buf(ctx, dpb[i].pic_order_cnt_val);
+ if (!luma_addr)
+ return -ENOMEM;
+
+diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
+index bd924896e409..4f7e2acb46ec 100644
+--- a/drivers/staging/media/hantro/hantro_hevc.c
++++ b/drivers/staging/media/hantro/hantro_hevc.c
+@@ -33,7 +33,7 @@ void hantro_hevc_ref_init(struct hantro_ctx *ctx)
+ }
+
+ dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx,
+- int poc)
++ s32 poc)
+ {
+ struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
+ int i;
+diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
+index b480cf329b13..457eb8bb6dc2 100644
+--- a/drivers/staging/media/hantro/hantro_hw.h
++++ b/drivers/staging/media/hantro/hantro_hw.h
+@@ -143,7 +143,7 @@ struct hantro_hevc_dec_hw_ctx {
+ struct hantro_aux_buf tile_bsd;
+ struct hantro_aux_buf ref_bufs[NUM_REF_PICTURES];
+ struct hantro_aux_buf scaling_lists;
+- int ref_bufs_poc[NUM_REF_PICTURES];
++ s32 ref_bufs_poc[NUM_REF_PICTURES];
+ u32 ref_bufs_used;
+ struct hantro_hevc_dec_ctrls ctrls;
+ unsigned int num_tile_cols_allocated;
+@@ -351,7 +351,7 @@ void hantro_hevc_dec_exit(struct hantro_ctx *ctx);
+ int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx);
+ int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx);
+ void hantro_hevc_ref_init(struct hantro_ctx *ctx);
+-dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, int poc);
++dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, s32 poc);
+ int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr);
+ int hantro_hevc_validate_sps(struct hantro_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps);
+
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+index 2febdf7a97fe..c26e515d64c9 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+@@ -143,8 +143,8 @@ static void cedrus_h265_frame_info_write_dpb(struct cedrus_ctx *ctx,
+ for (i = 0; i < num_active_dpb_entries; i++) {
+ int buffer_index = vb2_find_timestamp(vq, dpb[i].timestamp, 0);
+ u32 pic_order_cnt[2] = {
+- dpb[i].pic_order_cnt[0],
+- dpb[i].pic_order_cnt[1]
++ dpb[i].pic_order_cnt_val,
++ dpb[i].pic_order_cnt_val
+ };
+
+ cedrus_h265_frame_info_write_single(ctx, i, dpb[i].field_pic,
+diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
+index 01ccda48d8c5..88e804578cb1 100644
+--- a/include/media/hevc-ctrls.h
++++ b/include/media/hevc-ctrls.h
+@@ -135,7 +135,7 @@ struct v4l2_hevc_dpb_entry {
+ __u64 timestamp;
+ __u8 flags;
+ __u8 field_pic;
+- __u16 pic_order_cnt[2];
++ __s32 pic_order_cnt_val;
+ __u8 padding[2];
+ };
+
+@@ -178,7 +178,7 @@ struct v4l2_ctrl_hevc_slice_params {
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
+ __u8 slice_type;
+ __u8 colour_plane_id;
+- __u16 slice_pic_order_cnt;
++ __s32 slice_pic_order_cnt;
+ __u8 num_ref_idx_l0_active_minus1;
+ __u8 num_ref_idx_l1_active_minus1;
+ __u8 collocated_ref_idx;
+--
+2.35.1
+
--- /dev/null
+From 89b869fe4aa63043d1a419fd746f34a58316fd4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 04:19:20 +0100
+Subject: media: v4l2-mem2mem: prevent pollerr when last_buffer_dequeued is set
+
+From: Ming Qian <ming.qian@nxp.com>
+
+[ Upstream commit d4de27a9b1eadd33a2e40de87a646d1bf5fef756 ]
+
+If the last buffer was dequeued from the capture queue,
+signal userspace. DQBUF(CAPTURE) will return -EPIPE.
+
+But if output queue is empty and capture queue is empty,
+v4l2_m2m_poll_for_data will return EPOLLERR,
+This is very easy to happen in drain.
+
+When last_buffer_dequeued is set, we shouldn't return EPOLLERR,
+but return EPOLLIN | EPOLLRDNORM.
+
+Fixes: 1698a7f151126 ("media: v4l2-mem2mem: simplify poll logic")
+Signed-off-by: Ming Qian <ming.qian@nxp.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/v4l2-core/v4l2-mem2mem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
+index 675e22895ebe..094e1815209b 100644
+--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
++++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
+@@ -924,7 +924,7 @@ static __poll_t v4l2_m2m_poll_for_data(struct file *file,
+ if ((!src_q->streaming || src_q->error ||
+ list_empty(&src_q->queued_list)) &&
+ (!dst_q->streaming || dst_q->error ||
+- list_empty(&dst_q->queued_list)))
++ (list_empty(&dst_q->queued_list) && !dst_q->last_buffer_dequeued)))
+ return EPOLLERR;
+
+ spin_lock_irqsave(&src_q->done_lock, flags);
+--
+2.35.1
+
--- /dev/null
+From e59c13a84a97ae171278cacd0e8c7e81c83f2550 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Jul 2022 16:34:21 +0800
+Subject: mediatek: mt76: eeprom: fix missing of_node_put() in
+ mt76_find_power_limits_node()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 3bd53ea02d77917c2314ec7be9e2d05be22f87d3 ]
+
+We should use of_node_put() for the reference 'np' returned by
+of_get_child_by_name() which will increase the refcount.
+
+Fixes: 22b980badc0f ("mt76: add functions for parsing rate power limits from DT")
+Signed-off-by: Liang He <windhl@126.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/eeprom.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/eeprom.c b/drivers/net/wireless/mediatek/mt76/eeprom.c
+index a499861918fa..9bc8758573fc 100644
+--- a/drivers/net/wireless/mediatek/mt76/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
+@@ -162,10 +162,13 @@ mt76_find_power_limits_node(struct mt76_dev *dev)
+ }
+
+ if (mt76_string_prop_find(country, dev->alpha2) ||
+- mt76_string_prop_find(regd, region_name))
++ mt76_string_prop_find(regd, region_name)) {
++ of_node_put(np);
+ return cur;
++ }
+ }
+
++ of_node_put(np);
+ return fallback;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 57ea23d0eff3fcbdc39d76a29b4a983496d2654b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Jul 2022 16:34:20 +0800
+Subject: mediatek: mt76: mac80211: Fix missing of_node_put() in
+ mt76_led_init()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 0a14c1d0113f121151edf34333cdf212dd209190 ]
+
+We should use of_node_put() for the reference 'np' returned by
+of_get_child_by_name() which will increase the refcount.
+
+Fixes: 17f1de56df05 ("mt76: add common code shared between multiple chipsets")
+Signed-off-by: Liang He <windhl@126.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mac80211.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
+index 8a2fedbb1451..2cd7b3f1db64 100644
+--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
++++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
+@@ -210,6 +210,7 @@ static int mt76_led_init(struct mt76_dev *dev)
+ if (!of_property_read_u32(np, "led-sources", &led_pin))
+ dev->led_pin = led_pin;
+ dev->led_al = of_property_read_bool(np, "led-active-low");
++ of_node_put(np);
+ }
+
+ return led_classdev_register(dev->dev, &dev->led_cdev);
+--
+2.35.1
+
--- /dev/null
+From 30dee6ac53ec50338a6af29c60699543553e2419 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Jun 2022 14:55:56 +0200
+Subject: memstick/ms_block: Fix a memory leak
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 54eb7a55be6779c4d0c25eaf5056498a28595049 ]
+
+'erased_blocks_bitmap' is never freed. As it is allocated at the same time
+as 'used_blocks_bitmap', it is likely that it should be freed also at the
+same time.
+
+Add the corresponding bitmap_free() in msb_data_clear().
+
+Fixes: 0ab30494bc4f ("memstick: add support for legacy memorysticks")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/b3b78926569445962ea5c3b6e9102418a9effb88.1656155715.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/memstick/core/ms_block.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c
+index f8f151163667..f8fdf88fb240 100644
+--- a/drivers/memstick/core/ms_block.c
++++ b/drivers/memstick/core/ms_block.c
+@@ -1947,6 +1947,7 @@ static void msb_data_clear(struct msb_data *msb)
+ {
+ kfree(msb->boot_page);
+ bitmap_free(msb->used_blocks_bitmap);
++ bitmap_free(msb->erased_blocks_bitmap);
+ kfree(msb->lba_to_pba_table);
+ kfree(msb->cache);
+ msb->card = NULL;
+--
+2.35.1
+
--- /dev/null
+From 31991f4fc670bee0657c29f7d17db16ec9d1c636 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Jun 2022 14:55:25 +0200
+Subject: memstick/ms_block: Fix some incorrect memory allocation
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 2e531bc3e0d86362fcd8a577b3278d9ef3cc2ba0 ]
+
+Some functions of the bitmap API take advantage of the fact that a bitmap
+is an array of long.
+
+So, to make sure this assertion is correct, allocate bitmaps with
+bitmap_zalloc() instead of kzalloc()+hand-computed number of bytes.
+
+While at it, also use bitmap_free() instead of kfree() to keep the
+semantic.
+
+Fixes: 0ab30494bc4f ("memstick: add support for legacy memorysticks")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/dbf633c48c24ae6d95f852557e8d8b3bbdef65fe.1656155715.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/memstick/core/ms_block.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c
+index 3993bdd4b519..f8f151163667 100644
+--- a/drivers/memstick/core/ms_block.c
++++ b/drivers/memstick/core/ms_block.c
+@@ -1341,17 +1341,17 @@ static int msb_ftl_initialize(struct msb_data *msb)
+ msb->zone_count = msb->block_count / MS_BLOCKS_IN_ZONE;
+ msb->logical_block_count = msb->zone_count * 496 - 2;
+
+- msb->used_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL);
+- msb->erased_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL);
++ msb->used_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL);
++ msb->erased_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL);
+ msb->lba_to_pba_table =
+ kmalloc_array(msb->logical_block_count, sizeof(u16),
+ GFP_KERNEL);
+
+ if (!msb->used_blocks_bitmap || !msb->lba_to_pba_table ||
+ !msb->erased_blocks_bitmap) {
+- kfree(msb->used_blocks_bitmap);
++ bitmap_free(msb->used_blocks_bitmap);
++ bitmap_free(msb->erased_blocks_bitmap);
+ kfree(msb->lba_to_pba_table);
+- kfree(msb->erased_blocks_bitmap);
+ return -ENOMEM;
+ }
+
+@@ -1946,7 +1946,7 @@ static DEFINE_MUTEX(msb_disk_lock); /* protects against races in open/release */
+ static void msb_data_clear(struct msb_data *msb)
+ {
+ kfree(msb->boot_page);
+- kfree(msb->used_blocks_bitmap);
++ bitmap_free(msb->used_blocks_bitmap);
+ kfree(msb->lba_to_pba_table);
+ kfree(msb->cache);
+ msb->card = NULL;
+--
+2.35.1
+
--- /dev/null
+From 21bdd418f6ab127c73ab2d79667f3f65fe9badb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 10:57:29 +0400
+Subject: meson-mx-socinfo: Fix refcount leak in meson_mx_socinfo_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit a2106f38077e78afcb4bf98fdda3e162118cfb3d ]
+
+of_find_matching_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 5e68c0fc8df8 ("soc: amlogic: Add Meson6/Meson8/Meson8b/Meson8m2 SoC Information driver")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://lore.kernel.org/r/20220524065729.33689-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/amlogic/meson-mx-socinfo.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/soc/amlogic/meson-mx-socinfo.c b/drivers/soc/amlogic/meson-mx-socinfo.c
+index 78f0f1aeca57..92125dd65f33 100644
+--- a/drivers/soc/amlogic/meson-mx-socinfo.c
++++ b/drivers/soc/amlogic/meson-mx-socinfo.c
+@@ -126,6 +126,7 @@ static int __init meson_mx_socinfo_init(void)
+ np = of_find_matching_node(NULL, meson_mx_socinfo_analog_top_ids);
+ if (np) {
+ analog_top_regmap = syscon_node_to_regmap(np);
++ of_node_put(np);
+ if (IS_ERR(analog_top_regmap))
+ return PTR_ERR(analog_top_regmap);
+
+--
+2.35.1
+
--- /dev/null
+From 8ef5b0558069ab3c35161f4d151425be5adb1432 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 08:32:22 +0400
+Subject: mfd: max77620: Fix refcount leak in max77620_initialise_fps
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 1520669c8255bd637c6b248b2be910e2688d38dd ]
+
+of_get_child_by_name() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 327156c59360 ("mfd: max77620: Add core driver for MAX77620/MAX20024")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Link: https://lore.kernel.org/r/20220601043222.64441-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/max77620.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c
+index fec2096474ad..a6661e07035b 100644
+--- a/drivers/mfd/max77620.c
++++ b/drivers/mfd/max77620.c
+@@ -419,9 +419,11 @@ static int max77620_initialise_fps(struct max77620_chip *chip)
+ ret = max77620_config_fps(chip, fps_child);
+ if (ret < 0) {
+ of_node_put(fps_child);
++ of_node_put(fps_np);
+ return ret;
+ }
+ }
++ of_node_put(fps_np);
+
+ config = chip->enable_global_lpm ? MAX77620_ONOFFCNFG2_SLP_LPM_MSK : 0;
+ ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
+--
+2.35.1
+
--- /dev/null
+From 6717a9065e7c8ba67c1d9fdfd2434a0752c02cfb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 21:24:28 +0200
+Subject: mfd: t7l66xb: Drop platform disable callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 128ac294e1b437cb8a7f2ff8ede1cde9082bddbe ]
+
+None of the in-tree instantiations of struct t7l66xb_platform_data
+provides a disable callback. So better don't dereference this function
+pointer unconditionally. As there is no user, drop it completely instead
+of calling it conditional.
+
+This is a preparation for making platform remove callbacks return void.
+
+Fixes: 1f192015ca5b ("mfd: driver for the T7L66XB TMIO SoC")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Link: https://lore.kernel.org/r/20220530192430.2108217-3-u.kleine-koenig@pengutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/t7l66xb.c | 6 +-----
+ include/linux/mfd/t7l66xb.h | 1 -
+ 2 files changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
+index 5369c67e3280..663ffd4b8570 100644
+--- a/drivers/mfd/t7l66xb.c
++++ b/drivers/mfd/t7l66xb.c
+@@ -397,11 +397,8 @@ static int t7l66xb_probe(struct platform_device *dev)
+
+ static int t7l66xb_remove(struct platform_device *dev)
+ {
+- struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev);
+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
+- int ret;
+
+- ret = pdata->disable(dev);
+ clk_disable_unprepare(t7l66xb->clk48m);
+ clk_put(t7l66xb->clk48m);
+ clk_disable_unprepare(t7l66xb->clk32k);
+@@ -412,8 +409,7 @@ static int t7l66xb_remove(struct platform_device *dev)
+ mfd_remove_devices(&dev->dev);
+ kfree(t7l66xb);
+
+- return ret;
+-
++ return 0;
+ }
+
+ static struct platform_driver t7l66xb_platform_driver = {
+diff --git a/include/linux/mfd/t7l66xb.h b/include/linux/mfd/t7l66xb.h
+index 69632c1b07bd..ae3e7a5c5219 100644
+--- a/include/linux/mfd/t7l66xb.h
++++ b/include/linux/mfd/t7l66xb.h
+@@ -12,7 +12,6 @@
+
+ struct t7l66xb_platform_data {
+ int (*enable)(struct platform_device *dev);
+- int (*disable)(struct platform_device *dev);
+ int (*suspend)(struct platform_device *dev);
+ int (*resume)(struct platform_device *dev);
+
+--
+2.35.1
+
--- /dev/null
+From 5be07555987c9713086d22801b863791b1a5aa3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 15:25:12 -0700
+Subject: MIPS: Fixed __debug_virt_addr_valid()
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+[ Upstream commit 8a2b456665d1e797123669581524cbb095fb003b ]
+
+It is permissible for kernel code to call virt_to_phys() against virtual
+addresses that are in KSEG0 or KSEG1 and we need to be dealing with both
+types. Rewrite the test condition to ensure that the kernel virtual
+addresses are above PAGE_OFFSET which they must be, and below KSEG2
+where the non-linear mapping starts.
+
+For EVA, there is not much that we can do given the linear address range
+that is offered, so just return any virtual address as being valid.
+
+Finally, when HIGHMEM is not enabled, all virtual addresses are assumed
+to be valid as well.
+
+Fixes: dfad83cb7193 ("MIPS: Add support for CONFIG_DEBUG_VIRTUAL")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/mm/physaddr.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/arch/mips/mm/physaddr.c b/arch/mips/mm/physaddr.c
+index a1ced5e44951..f9b8c85e9843 100644
+--- a/arch/mips/mm/physaddr.c
++++ b/arch/mips/mm/physaddr.c
+@@ -5,6 +5,7 @@
+ #include <linux/mmdebug.h>
+ #include <linux/mm.h>
+
++#include <asm/addrspace.h>
+ #include <asm/sections.h>
+ #include <asm/io.h>
+ #include <asm/page.h>
+@@ -12,15 +13,6 @@
+
+ static inline bool __debug_virt_addr_valid(unsigned long x)
+ {
+- /* high_memory does not get immediately defined, and there
+- * are early callers of __pa() against PAGE_OFFSET
+- */
+- if (!high_memory && x >= PAGE_OFFSET)
+- return true;
+-
+- if (high_memory && x >= PAGE_OFFSET && x < (unsigned long)high_memory)
+- return true;
+-
+ /*
+ * MAX_DMA_ADDRESS is a virtual address that may not correspond to an
+ * actual physical address. Enough code relies on
+@@ -30,7 +22,9 @@ static inline bool __debug_virt_addr_valid(unsigned long x)
+ if (x == MAX_DMA_ADDRESS)
+ return true;
+
+- return false;
++ return x >= PAGE_OFFSET && (KSEGX(x) < KSEG2 ||
++ IS_ENABLED(CONFIG_EVA) ||
++ !IS_ENABLED(CONFIG_HIGHMEM));
+ }
+
+ phys_addr_t __virt_to_phys(volatile const void *x)
+--
+2.35.1
+
--- /dev/null
+From 5f17e15618798f9075a1582b32a31fb182507b21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jun 2022 15:07:13 +0800
+Subject: MIPS: Loongson64: Fix section mismatch warning
+
+From: Tiezhu Yang <yangtiezhu@loongson.cn>
+
+[ Upstream commit 08472f6ebdc23334ad11dcd761d2d52c32897793 ]
+
+prom_init_numa_memory() is annotated __init and not used by any module,
+thus don't export it.
+
+Remove not needed EXPORT_SYMBOL for prom_init_numa_memory() to fix the
+following section mismatch warning:
+
+ LD vmlinux.o
+ MODPOST vmlinux.symvers
+WARNING: modpost: vmlinux.o(___ksymtab+prom_init_numa_memory+0x0): Section mismatch in reference
+from the variable __ksymtab_prom_init_numa_memory to the function .init.text:prom_init_numa_memory()
+The symbol prom_init_numa_memory is exported and annotated __init
+Fix this by removing the __init annotation of prom_init_numa_memory or drop the export.
+
+This is build on Linux 5.19-rc4.
+
+Fixes: 6fbde6b492df ("MIPS: Loongson64: Move files to the top-level directory")
+Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
+Reviewed-by: Huacai Chen <chenhuacai@kernel.org>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/loongson64/numa.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/mips/loongson64/numa.c b/arch/mips/loongson64/numa.c
+index 69a533148efd..8f61e93c0c5b 100644
+--- a/arch/mips/loongson64/numa.c
++++ b/arch/mips/loongson64/numa.c
+@@ -196,7 +196,6 @@ void __init prom_init_numa_memory(void)
+ pr_info("CP0_PageGrain: CP0 5.1 (0x%x)\n", read_c0_pagegrain());
+ prom_meminit();
+ }
+-EXPORT_SYMBOL(prom_init_numa_memory);
+
+ pg_data_t * __init arch_alloc_nodedata(int nid)
+ {
+--
+2.35.1
+
--- /dev/null
+From 81e18604e10523b98eeede03d6feb7689b46162c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 13:27:58 -0700
+Subject: MIPS: vdso: Utilize __pa() for gic_pfn
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+[ Upstream commit 8baa65126e19af5ee9f3c07e7bb53da41c39e4b1 ]
+
+The GIC user offset is mapped into every process' virtual address and is
+therefore part of the hot-path of arch_setup_additional_pages(). Utilize
+__pa() such that we are more optimal even when CONFIG_DEBUG_VIRTUAL is
+enabled, and while at it utilize PFN_DOWN() instead of open-coding the
+right shift by PAGE_SHIFT.
+
+Reported-by: Greg Ungerer <gerg@kernel.org>
+Suggested-by: Serge Semin <fancer.lancer@gmail.com>
+Fixes: dfad83cb7193 ("MIPS: Add support for CONFIG_DEBUG_VIRTUAL")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Acked-by: Greg Ungerer <gerg@kernel.org>
+Tested-by: Greg Ungerer <gerg@kernel.org>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/kernel/vdso.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
+index 3d0cf471f2fe..b2cc2c2dd4bf 100644
+--- a/arch/mips/kernel/vdso.c
++++ b/arch/mips/kernel/vdso.c
+@@ -159,7 +159,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ /* Map GIC user page. */
+ if (gic_size) {
+ gic_base = (unsigned long)mips_gic_base + MIPS_GIC_USER_OFS;
+- gic_pfn = virt_to_phys((void *)gic_base) >> PAGE_SHIFT;
++ gic_pfn = PFN_DOWN(__pa(gic_base));
+
+ ret = io_remap_pfn_range(vma, base, gic_pfn, gic_size,
+ pgprot_noncached(vma->vm_page_prot));
+--
+2.35.1
+
--- /dev/null
+From 4b49d1e7cf70bc5976c1df5068fb8f023b0cf58e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 07:33:44 +0200
+Subject: misc: rtsx: Fix an error handling path in rtsx_pci_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 44fd1917314e9d4f53dd95dd65df1c152f503d3a ]
+
+If an error occurs after a successful idr_alloc() call, the corresponding
+resource must be released with idr_remove() as already done in the .remove
+function.
+
+Update the error handling path to add the missing idr_remove() call.
+
+Fixes: ada8a8a13b13 ("mfd: Add realtek pcie card reader driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/e8dc41716cbf52fb37a12e70d8972848e69df6d6.1655271216.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/cardreader/rtsx_pcr.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c
+index 2a2619e3c72c..f001d99bf366 100644
+--- a/drivers/misc/cardreader/rtsx_pcr.c
++++ b/drivers/misc/cardreader/rtsx_pcr.c
+@@ -1507,7 +1507,7 @@ static int rtsx_pci_probe(struct pci_dev *pcidev,
+ pcr->remap_addr = ioremap(base, len);
+ if (!pcr->remap_addr) {
+ ret = -ENOMEM;
+- goto free_handle;
++ goto free_idr;
+ }
+
+ pcr->rtsx_resv_buf = dma_alloc_coherent(&(pcidev->dev),
+@@ -1570,6 +1570,10 @@ static int rtsx_pci_probe(struct pci_dev *pcidev,
+ pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr);
+ unmap:
+ iounmap(pcr->remap_addr);
++free_idr:
++ spin_lock(&rtsx_pci_lock);
++ idr_remove(&rtsx_pci_idr, pcr->id);
++ spin_unlock(&rtsx_pci_lock);
+ free_handle:
+ kfree(handle);
+ free_pcr:
+--
+2.35.1
+
--- /dev/null
+From bce30cc58f9d878eaf20b6f27286a557b887e4d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jun 2022 20:15:29 -0400
+Subject: mm: Account dirty folios properly during splits
+
+From: Matthew Wilcox (Oracle) <willy@infradead.org>
+
+[ Upstream commit fb5c2029f8221e904e604938171c4a8ef169aadb ]
+
+If the last folio in a file is split as a result of truncation,
+we simply clear the dirty bits for the pages we're discarding.
+That causes NR_FILE_DIRTY (among other counters) to be thrown off
+and eventually Linux will hang in balance_dirty_pages_ratelimited()
+
+Reported-by: Dave Chinner <dchinner@redhat.com>
+Tested-by: Dave Chinner <dchinner@redhat.com>
+Tested-by: Darrick J. Wong <djwong@kernel.org>
+Fixes: d68eccad3706 ("mm/filemap: Allow large folios to be added to the page cache")
+Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/huge_memory.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/mm/huge_memory.c b/mm/huge_memory.c
+index b7d0697b1f26..e0c1cf3168d7 100644
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -18,6 +18,7 @@
+ #include <linux/shrinker.h>
+ #include <linux/mm_inline.h>
+ #include <linux/swapops.h>
++#include <linux/backing-dev.h>
+ #include <linux/dax.h>
+ #include <linux/khugepaged.h>
+ #include <linux/freezer.h>
+@@ -2389,11 +2390,15 @@ static void __split_huge_page(struct page *page, struct list_head *list,
+ __split_huge_page_tail(head, i, lruvec, list);
+ /* Some pages can be beyond EOF: drop them from page cache */
+ if (head[i].index >= end) {
+- ClearPageDirty(head + i);
+- __delete_from_page_cache(head + i, NULL);
++ struct folio *tail = page_folio(head + i);
++
+ if (shmem_mapping(head->mapping))
+ shmem_uncharge(head->mapping->host, 1);
+- put_page(head + i);
++ else if (folio_test_clear_dirty(tail))
++ folio_account_cleaned(tail,
++ inode_to_wb(folio->mapping->host));
++ __filemap_remove_folio(tail, NULL);
++ folio_put(tail);
+ } else if (!PageAnon(page)) {
+ __xa_store(&head->mapping->i_pages, head[i].index,
+ head + i, 0);
+--
+2.35.1
+
--- /dev/null
+From f8a3bf86c7948cde73acf4568b9cd26ef9333b31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 17:32:11 +0800
+Subject: mm/mempolicy: fix get_nodes out of bound access
+
+From: Tianyu Li <tianyu.li@arm.com>
+
+[ Upstream commit 000eca5d044d1ee23b4ca311793cf3fc528da6c6 ]
+
+When user specified more nodes than supported, get_nodes will access nmask
+array out of bounds.
+
+Link: https://lkml.kernel.org/r/20220601093211.2970565-1-tianyu.li@arm.com
+Fixes: e130242dc351 ("mm: simplify compat numa syscalls")
+Signed-off-by: Tianyu Li <tianyu.li@arm.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/mempolicy.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c
+index b27e8d71cda3..c1ccc89845f4 100644
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -1387,7 +1387,7 @@ static int get_nodes(nodemask_t *nodes, const unsigned long __user *nmask,
+ unsigned long bits = min_t(unsigned long, maxnode, BITS_PER_LONG);
+ unsigned long t;
+
+- if (get_bitmap(&t, &nmask[maxnode / BITS_PER_LONG], bits))
++ if (get_bitmap(&t, &nmask[(maxnode - 1) / BITS_PER_LONG], bits))
+ return -EFAULT;
+
+ if (maxnode - bits >= MAX_NUMNODES) {
+--
+2.35.1
+
--- /dev/null
+From 3da4029d669067980f4882b591523fcb616e4d6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 20:13:05 +0800
+Subject: mm/memremap: fix memunmap_pages() race with get_dev_pagemap()
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit 1e57ffb6e3fd9583268c6462c4e3853575b21701 ]
+
+Think about the below scene:
+
+ CPU1 CPU2
+ memunmap_pages
+ percpu_ref_exit
+ __percpu_ref_exit
+ free_percpu(percpu_count);
+ /* percpu_count is freed here! */
+ get_dev_pagemap
+ xa_load(&pgmap_array, PHYS_PFN(phys))
+ /* pgmap still in the pgmap_array */
+ percpu_ref_tryget_live(&pgmap->ref)
+ if __ref_is_percpu
+ /* __PERCPU_REF_ATOMIC_DEAD not set yet */
+ this_cpu_inc(*percpu_count)
+ /* access freed percpu_count here! */
+ ref->percpu_count_ptr = __PERCPU_REF_ATOMIC_DEAD;
+ /* too late... */
+ pageunmap_range
+
+To fix the issue, do percpu_ref_exit() after pgmap_array is emptied. So
+we won't do percpu_ref_tryget_live() against a being freed percpu_ref.
+
+Link: https://lkml.kernel.org/r/20220609121305.2508-1-linmiaohe@huawei.com
+Fixes: b7b3c01b1915 ("mm/memremap_pages: support multiple ranges per invocation")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/memremap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mm/memremap.c b/mm/memremap.c
+index e11653fd348c..2c1130486d28 100644
+--- a/mm/memremap.c
++++ b/mm/memremap.c
+@@ -141,10 +141,10 @@ void memunmap_pages(struct dev_pagemap *pgmap)
+ for (i = 0; i < pgmap->nr_range; i++)
+ percpu_ref_put_many(&pgmap->ref, pfn_len(pgmap, i));
+ wait_for_completion(&pgmap->done);
+- percpu_ref_exit(&pgmap->ref);
+
+ for (i = 0; i < pgmap->nr_range; i++)
+ pageunmap_range(pgmap, i);
++ percpu_ref_exit(&pgmap->ref);
+
+ WARN_ONCE(pgmap->altmap.alloc, "failed to free all reserved pages\n");
+ devmap_managed_enable_put(pgmap);
+--
+2.35.1
+
--- /dev/null
+From 032e8dad266ef0b59b371edc82e23af44e61b3bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 19:30:16 +0800
+Subject: mm/migration: fix potential pte_unmap on an not mapped pte
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit ad1ac596e8a8c4b06715dfbd89853eb73c9886b2 ]
+
+__migration_entry_wait and migration_entry_wait_on_locked assume pte is
+always mapped from caller. But this is not the case when it's called from
+migration_entry_wait_huge and follow_huge_pmd. Add a hugetlbfs variant
+that calls hugetlb_migration_entry_wait(ptep == NULL) to fix this issue.
+
+Link: https://lkml.kernel.org/r/20220530113016.16663-5-linmiaohe@huawei.com
+Fixes: 30dad30922cc ("mm: migration: add migrate_entry_wait_huge()")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Suggested-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Cc: Alistair Popple <apopple@nvidia.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Christoph Lameter <cl@linux.com>
+Cc: David Howells <dhowells@redhat.com>
+Cc: Huang Ying <ying.huang@intel.com>
+Cc: kernel test robot <lkp@intel.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Muchun Song <songmuchun@bytedance.com>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Peter Xu <peterx@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/swapops.h | 12 ++++++++----
+ mm/hugetlb.c | 4 ++--
+ mm/migrate.c | 23 +++++++++++++++++++----
+ 3 files changed, 29 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/swapops.h b/include/linux/swapops.h
+index d356ab4047f7..f99f0bd85724 100644
+--- a/include/linux/swapops.h
++++ b/include/linux/swapops.h
+@@ -216,8 +216,10 @@ extern void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep,
+ spinlock_t *ptl);
+ extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
+ unsigned long address);
+-extern void migration_entry_wait_huge(struct vm_area_struct *vma,
+- struct mm_struct *mm, pte_t *pte);
++#ifdef CONFIG_HUGETLB_PAGE
++extern void __migration_entry_wait_huge(pte_t *ptep, spinlock_t *ptl);
++extern void migration_entry_wait_huge(struct vm_area_struct *vma, pte_t *pte);
++#endif
+ #else
+ static inline swp_entry_t make_readable_migration_entry(pgoff_t offset)
+ {
+@@ -238,8 +240,10 @@ static inline void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep,
+ spinlock_t *ptl) { }
+ static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
+ unsigned long address) { }
+-static inline void migration_entry_wait_huge(struct vm_area_struct *vma,
+- struct mm_struct *mm, pte_t *pte) { }
++#ifdef CONFIG_HUGETLB_PAGE
++static inline void __migration_entry_wait_huge(pte_t *ptep, spinlock_t *ptl) { }
++static inline void migration_entry_wait_huge(struct vm_area_struct *vma, pte_t *pte) { }
++#endif
+ static inline int is_writable_migration_entry(swp_entry_t entry)
+ {
+ return 0;
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 0090d7f98dee..19063dbed332 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -5602,7 +5602,7 @@ vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+ */
+ entry = huge_ptep_get(ptep);
+ if (unlikely(is_hugetlb_entry_migration(entry))) {
+- migration_entry_wait_huge(vma, mm, ptep);
++ migration_entry_wait_huge(vma, ptep);
+ return 0;
+ } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry)))
+ return VM_FAULT_HWPOISON_LARGE |
+@@ -6725,7 +6725,7 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+ } else {
+ if (is_hugetlb_entry_migration(pte)) {
+ spin_unlock(ptl);
+- __migration_entry_wait(mm, (pte_t *)pmd, ptl);
++ __migration_entry_wait_huge((pte_t *)pmd, ptl);
+ goto retry;
+ }
+ /*
+diff --git a/mm/migrate.c b/mm/migrate.c
+index 796502d0eeb9..5aba3fb612d4 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -309,13 +309,28 @@ void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
+ __migration_entry_wait(mm, ptep, ptl);
+ }
+
+-void migration_entry_wait_huge(struct vm_area_struct *vma,
+- struct mm_struct *mm, pte_t *pte)
++#ifdef CONFIG_HUGETLB_PAGE
++void __migration_entry_wait_huge(pte_t *ptep, spinlock_t *ptl)
+ {
+- spinlock_t *ptl = huge_pte_lockptr(hstate_vma(vma), mm, pte);
+- __migration_entry_wait(mm, pte, ptl);
++ pte_t pte;
++
++ spin_lock(ptl);
++ pte = huge_ptep_get(ptep);
++
++ if (unlikely(!is_hugetlb_entry_migration(pte)))
++ spin_unlock(ptl);
++ else
++ migration_entry_wait_on_locked(pte_to_swp_entry(pte), NULL, ptl);
+ }
+
++void migration_entry_wait_huge(struct vm_area_struct *vma, pte_t *pte)
++{
++ spinlock_t *ptl = huge_pte_lockptr(hstate_vma(vma), vma->vm_mm, pte);
++
++ __migration_entry_wait_huge(pte, ptl);
++}
++#endif
++
+ #ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
+ void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd)
+ {
+--
+2.35.1
+
--- /dev/null
+From c77042cfeef5080f33475c182476721c129c8340 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 19:30:15 +0800
+Subject: mm/migration: return errno when isolate_huge_page failed
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit 7ce82f4c3f3ead13a9d9498768e3b1a79975c4d8 ]
+
+We might fail to isolate huge page due to e.g. the page is under
+migration which cleared HPageMigratable. We should return errno in this
+case rather than always return 1 which could confuse the user, i.e. the
+caller might think all of the memory is migrated while the hugetlb page is
+left behind. We make the prototype of isolate_huge_page consistent with
+isolate_lru_page as suggested by Huang Ying and rename isolate_huge_page
+to isolate_hugetlb as suggested by Muchun to improve the readability.
+
+Link: https://lkml.kernel.org/r/20220530113016.16663-4-linmiaohe@huawei.com
+Fixes: e8db67eb0ded ("mm: migrate: move_pages() supports thp migration")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Suggested-by: Huang Ying <ying.huang@intel.com>
+Reported-by: kernel test robot <lkp@intel.com> (build error)
+Cc: Alistair Popple <apopple@nvidia.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Christoph Lameter <cl@linux.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: David Howells <dhowells@redhat.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Muchun Song <songmuchun@bytedance.com>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Peter Xu <peterx@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/hugetlb.h | 6 +++---
+ mm/gup.c | 2 +-
+ mm/hugetlb.c | 11 +++++------
+ mm/memory-failure.c | 2 +-
+ mm/memory_hotplug.c | 2 +-
+ mm/mempolicy.c | 2 +-
+ mm/migrate.c | 7 ++++---
+ 7 files changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
+index ac2a1d758a80..fbf4a6509fb3 100644
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -167,7 +167,7 @@ bool hugetlb_reserve_pages(struct inode *inode, long from, long to,
+ vm_flags_t vm_flags);
+ long hugetlb_unreserve_pages(struct inode *inode, long start, long end,
+ long freed);
+-bool isolate_huge_page(struct page *page, struct list_head *list);
++int isolate_hugetlb(struct page *page, struct list_head *list);
+ int get_hwpoison_huge_page(struct page *page, bool *hugetlb);
+ int get_huge_page_for_hwpoison(unsigned long pfn, int flags);
+ void putback_active_hugepage(struct page *page);
+@@ -369,9 +369,9 @@ static inline pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr,
+ return NULL;
+ }
+
+-static inline bool isolate_huge_page(struct page *page, struct list_head *list)
++static inline int isolate_hugetlb(struct page *page, struct list_head *list)
+ {
+- return false;
++ return -EBUSY;
+ }
+
+ static inline int get_hwpoison_huge_page(struct page *page, bool *hugetlb)
+diff --git a/mm/gup.c b/mm/gup.c
+index c5d076d43d9b..414f0c4b4caa 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -1795,7 +1795,7 @@ static long check_and_migrate_movable_pages(unsigned long nr_pages,
+ * Try to move out any movable page before pinning the range.
+ */
+ if (folio_test_hugetlb(folio)) {
+- if (!isolate_huge_page(&folio->page,
++ if (isolate_hugetlb(&folio->page,
+ &movable_page_list))
+ isolation_error_count++;
+ continue;
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 859cfcaecddb..0090d7f98dee 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -2758,8 +2758,7 @@ static int alloc_and_dissolve_huge_page(struct hstate *h, struct page *old_page,
+ * Fail with -EBUSY if not possible.
+ */
+ spin_unlock_irq(&hugetlb_lock);
+- if (!isolate_huge_page(old_page, list))
+- ret = -EBUSY;
++ ret = isolate_hugetlb(old_page, list);
+ spin_lock_irq(&hugetlb_lock);
+ goto free_new;
+ } else if (!HPageFreed(old_page)) {
+@@ -2835,7 +2834,7 @@ int isolate_or_dissolve_huge_page(struct page *page, struct list_head *list)
+ if (hstate_is_gigantic(h))
+ return -ENOMEM;
+
+- if (page_count(head) && isolate_huge_page(head, list))
++ if (page_count(head) && !isolate_hugetlb(head, list))
+ ret = 0;
+ else if (!page_count(head))
+ ret = alloc_and_dissolve_huge_page(h, head, list);
+@@ -6758,15 +6757,15 @@ follow_huge_pgd(struct mm_struct *mm, unsigned long address, pgd_t *pgd, int fla
+ return pte_page(*(pte_t *)pgd) + ((address & ~PGDIR_MASK) >> PAGE_SHIFT);
+ }
+
+-bool isolate_huge_page(struct page *page, struct list_head *list)
++int isolate_hugetlb(struct page *page, struct list_head *list)
+ {
+- bool ret = true;
++ int ret = 0;
+
+ spin_lock_irq(&hugetlb_lock);
+ if (!PageHeadHuge(page) ||
+ !HPageMigratable(page) ||
+ !get_page_unless_zero(page)) {
+- ret = false;
++ ret = -EBUSY;
+ goto unlock;
+ }
+ ClearHPageMigratable(page);
+diff --git a/mm/memory-failure.c b/mm/memory-failure.c
+index 94dac77f5eba..fb8c9b0b53ab 100644
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -2211,7 +2211,7 @@ static bool isolate_page(struct page *page, struct list_head *pagelist)
+ bool lru = PageLRU(page);
+
+ if (PageHuge(page)) {
+- isolated = isolate_huge_page(page, pagelist);
++ isolated = !isolate_hugetlb(page, pagelist);
+ } else {
+ if (lru)
+ isolated = !isolate_lru_page(page);
+diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
+index 416b38ca8def..3a60c1444bc7 100644
+--- a/mm/memory_hotplug.c
++++ b/mm/memory_hotplug.c
+@@ -1627,7 +1627,7 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
+
+ if (PageHuge(page)) {
+ pfn = page_to_pfn(head) + compound_nr(head) - 1;
+- isolate_huge_page(head, &source);
++ isolate_hugetlb(head, &source);
+ continue;
+ } else if (PageTransHuge(page))
+ pfn = page_to_pfn(head) + thp_nr_pages(page) - 1;
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c
+index ea6dee61bc9d..b27e8d71cda3 100644
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -607,7 +607,7 @@ static int queue_pages_hugetlb(pte_t *pte, unsigned long hmask,
+ /* With MPOL_MF_MOVE, we migrate only unshared hugepage. */
+ if (flags & (MPOL_MF_MOVE_ALL) ||
+ (flags & MPOL_MF_MOVE && page_mapcount(page) == 1)) {
+- if (!isolate_huge_page(page, qp->pagelist) &&
++ if (isolate_hugetlb(page, qp->pagelist) &&
+ (flags & MPOL_MF_STRICT))
+ /*
+ * Failed to isolate page but allow migrating pages
+diff --git a/mm/migrate.c b/mm/migrate.c
+index 6c31ee1e1c9b..796502d0eeb9 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -133,7 +133,7 @@ static void putback_movable_page(struct page *page)
+ *
+ * This function shall be used whenever the isolated pageset has been
+ * built from lru, balloon, hugetlbfs page. See isolate_migratepages_range()
+- * and isolate_huge_page().
++ * and isolate_hugetlb().
+ */
+ void putback_movable_pages(struct list_head *l)
+ {
+@@ -1631,8 +1631,9 @@ static int add_page_for_migration(struct mm_struct *mm, unsigned long addr,
+
+ if (PageHuge(page)) {
+ if (PageHead(page)) {
+- isolate_huge_page(page, pagelist);
+- err = 1;
++ err = isolate_hugetlb(page, pagelist);
++ if (!err)
++ err = 1;
+ }
+ } else {
+ struct page *head;
+--
+2.35.1
+
--- /dev/null
+From 376f96975ca5b062778dcafb7ca9734b08dbc9d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jun 2022 16:20:27 +0800
+Subject: mm/mmap.c: fix missing call to vm_unacct_memory in mmap_region
+
+From: Miaohe Lin <linmiaohe@huawei.com>
+
+[ Upstream commit 7f82f922319ede486540e8746769865b9508d2c2 ]
+
+Since the beginning, charged is set to 0 to avoid calling vm_unacct_memory
+twice because vm_unacct_memory will be called by above unmap_region. But
+since commit 4f74d2c8e827 ("vm: remove 'nr_accounted' calculations from
+the unmap_vmas() interfaces"), unmap_region doesn't call vm_unacct_memory
+anymore. So charged shouldn't be set to 0 now otherwise the calling to
+paired vm_unacct_memory will be missed and leads to imbalanced account.
+
+Link: https://lkml.kernel.org/r/20220618082027.43391-1-linmiaohe@huawei.com
+Fixes: 4f74d2c8e827 ("vm: remove 'nr_accounted' calculations from the unmap_vmas() interfaces")
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/mmap.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/mm/mmap.c b/mm/mmap.c
+index 313b57d55a63..6d9bfd9c94ca 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -1882,7 +1882,6 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
+
+ /* Undo any partial mapping done by a device driver. */
+ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
+- charged = 0;
+ if (vm_flags & VM_SHARED)
+ mapping_unmap_writable(file->f_mapping);
+ free_vma:
+--
+2.35.1
+
--- /dev/null
+From ed4ce7fa45ac1c2b23ff46d60e1fe33a59a38371 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Jul 2022 18:08:36 -0700
+Subject: mm: rmap: use the correct parameter name for DEFINE_PAGE_VMA_WALK
+
+From: Yang Shi <shy828301@gmail.com>
+
+[ Upstream commit 507db7927cd181d409dd495c8384b8e14c21c600 ]
+
+The parameter used by DEFINE_PAGE_VMA_WALK is _page not page, fix the
+parameter name. It didn't cause any build error, it is probably because
+the only caller is write_protect_page() from ksm.c, which pass in page.
+
+Link: https://lkml.kernel.org/r/20220512174551.81279-1-shy828301@gmail.com
+Fixes: 2aff7a4755be ("mm: Convert page_vma_mapped_walk to work on PFNs")
+Signed-off-by: Yang Shi <shy828301@gmail.com>
+Reviewed-by: Muchun Song <songmuchun@bytedance.com>
+Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Muchun Song <songmuchun@bytedance.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/rmap.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/rmap.h b/include/linux/rmap.h
+index 17230c458341..a0c4a870bb48 100644
+--- a/include/linux/rmap.h
++++ b/include/linux/rmap.h
+@@ -220,8 +220,8 @@ struct page_vma_mapped_walk {
+ #define DEFINE_PAGE_VMA_WALK(name, _page, _vma, _address, _flags) \
+ struct page_vma_mapped_walk name = { \
+ .pfn = page_to_pfn(_page), \
+- .nr_pages = compound_nr(page), \
+- .pgoff = page_to_pgoff(page), \
++ .nr_pages = compound_nr(_page), \
++ .pgoff = page_to_pgoff(_page), \
+ .vma = _vma, \
+ .address = _address, \
+ .flags = _flags, \
+--
+2.35.1
+
--- /dev/null
+From 99bc89ba2e4f2544f1c09ac96f564c11d3ac7176 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 12:43:09 +0000
+Subject: mmc: block: Add single read for 4k sector cards
+
+From: Christian Loehle <CLoehle@hyperstone.com>
+
+[ Upstream commit b3fa3e6dccc465969721b8bd2824213bd235efeb ]
+
+Cards with 4k native sector size may only be read 4k-aligned,
+accommodate for this in the single read recovery and use it.
+
+Fixes: 81196976ed946 (mmc: block: Add blk-mq support)
+Signed-off-by: Christian Loehle <cloehle@hyperstone.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Avri Altman <avri.altman@wdc.com>
+Link: https://lore.kernel.org/r/cf4f316274c5474586d0d99b17db4a4c@hyperstone.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/block.c | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
+index 23fcb7a16605..0b8d3d25ba7a 100644
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -175,7 +175,7 @@ static inline int mmc_blk_part_switch(struct mmc_card *card,
+ unsigned int part_type);
+ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
+ struct mmc_card *card,
+- int disable_multi,
++ int recovery_mode,
+ struct mmc_queue *mq);
+ static void mmc_blk_hsq_req_done(struct mmc_request *mrq);
+
+@@ -1285,7 +1285,7 @@ static void mmc_blk_eval_resp_error(struct mmc_blk_request *brq)
+ }
+
+ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,
+- int disable_multi, bool *do_rel_wr_p,
++ int recovery_mode, bool *do_rel_wr_p,
+ bool *do_data_tag_p)
+ {
+ struct mmc_blk_data *md = mq->blkdata;
+@@ -1351,12 +1351,12 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,
+ brq->data.blocks--;
+
+ /*
+- * After a read error, we redo the request one sector
++ * After a read error, we redo the request one (native) sector
+ * at a time in order to accurately determine which
+ * sectors can be read successfully.
+ */
+- if (disable_multi)
+- brq->data.blocks = 1;
++ if (recovery_mode)
++ brq->data.blocks = queue_physical_block_size(mq->queue) >> 9;
+
+ /*
+ * Some controllers have HW issues while operating
+@@ -1573,7 +1573,7 @@ static int mmc_blk_cqe_issue_rw_rq(struct mmc_queue *mq, struct request *req)
+
+ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
+ struct mmc_card *card,
+- int disable_multi,
++ int recovery_mode,
+ struct mmc_queue *mq)
+ {
+ u32 readcmd, writecmd;
+@@ -1582,7 +1582,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
+ struct mmc_blk_data *md = mq->blkdata;
+ bool do_rel_wr, do_data_tag;
+
+- mmc_blk_data_prep(mq, mqrq, disable_multi, &do_rel_wr, &do_data_tag);
++ mmc_blk_data_prep(mq, mqrq, recovery_mode, &do_rel_wr, &do_data_tag);
+
+ brq->mrq.cmd = &brq->cmd;
+
+@@ -1673,7 +1673,7 @@ static int mmc_blk_fix_state(struct mmc_card *card, struct request *req)
+
+ #define MMC_READ_SINGLE_RETRIES 2
+
+-/* Single sector read during recovery */
++/* Single (native) sector read during recovery */
+ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)
+ {
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+@@ -1681,6 +1681,7 @@ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)
+ struct mmc_card *card = mq->card;
+ struct mmc_host *host = card->host;
+ blk_status_t error = BLK_STS_OK;
++ size_t bytes_per_read = queue_physical_block_size(mq->queue);
+
+ do {
+ u32 status;
+@@ -1715,13 +1716,13 @@ static void mmc_blk_read_single(struct mmc_queue *mq, struct request *req)
+ else
+ error = BLK_STS_OK;
+
+- } while (blk_update_request(req, error, 512));
++ } while (blk_update_request(req, error, bytes_per_read));
+
+ return;
+
+ error_exit:
+ mrq->data->bytes_xfered = 0;
+- blk_update_request(req, BLK_STS_IOERR, 512);
++ blk_update_request(req, BLK_STS_IOERR, bytes_per_read);
+ /* Let it try the remaining request again */
+ if (mqrq->retries > MMC_MAX_RETRIES - 1)
+ mqrq->retries = MMC_MAX_RETRIES - 1;
+@@ -1862,10 +1863,9 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)
+ return;
+ }
+
+- /* FIXME: Missing single sector read for large sector size */
+- if (!mmc_large_sector(card) && rq_data_dir(req) == READ &&
+- brq->data.blocks > 1) {
+- /* Read one sector at a time */
++ if (rq_data_dir(req) == READ && brq->data.blocks >
++ queue_physical_block_size(mq->queue) >> 9) {
++ /* Read one (native) sector at a time */
+ mmc_blk_read_single(mq, req);
+ return;
+ }
+--
+2.35.1
+
--- /dev/null
+From b77431b0e2e10a04ab11937006cde6726ae61d43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 17:52:15 +0800
+Subject: mmc: cavium-octeon: Add of_node_put() when breaking out of loop
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 19bbb49acf8d7a03cb83e05624363741a4c3ec6f ]
+
+In octeon_mmc_probe(), we should call of_node_put() when breaking
+out of for_each_child_of_node() which has increased and decreased
+the refcount during each iteration.
+
+Fixes: 01d95843335c ("mmc: cavium: Add MMC support for Octeon SOCs.")
+Signed-off-by: Liang He <windhl@126.com>
+Acked-by: Robert Richter <rric@kernel.org>
+Link: https://lore.kernel.org/r/20220719095216.1241601-1-windhl@126.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/cavium-octeon.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mmc/host/cavium-octeon.c b/drivers/mmc/host/cavium-octeon.c
+index 2c4b2df52adb..12dca91a8ef6 100644
+--- a/drivers/mmc/host/cavium-octeon.c
++++ b/drivers/mmc/host/cavium-octeon.c
+@@ -277,6 +277,7 @@ static int octeon_mmc_probe(struct platform_device *pdev)
+ if (ret) {
+ dev_err(&pdev->dev, "Error populating slots\n");
+ octeon_mmc_set_shared_power(host, 0);
++ of_node_put(cn);
+ goto error;
+ }
+ i++;
+--
+2.35.1
+
--- /dev/null
+From 11c8add9d74783c166737c39a1a7241176bfc7e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 17:52:16 +0800
+Subject: mmc: cavium-thunderx: Add of_node_put() when breaking out of loop
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 7ee480795e41db314f2c445c65ed854a5d6e8e32 ]
+
+In thunder_mmc_probe(), we should call of_node_put() when breaking
+out of for_each_child_of_node() which has increased and decreased
+the refcount during each iteration.
+
+Fixes: 166bac38c3c5 ("mmc: cavium: Add MMC PCI driver for ThunderX SOCs")
+Signed-off-by: Liang He <windhl@126.com>
+Acked-by: Robert Richter <rric@kernel.org>
+Link: https://lore.kernel.org/r/20220719095216.1241601-2-windhl@126.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/cavium-thunderx.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/cavium-thunderx.c b/drivers/mmc/host/cavium-thunderx.c
+index 76013bbbcff3..202b1d6da678 100644
+--- a/drivers/mmc/host/cavium-thunderx.c
++++ b/drivers/mmc/host/cavium-thunderx.c
+@@ -142,8 +142,10 @@ static int thunder_mmc_probe(struct pci_dev *pdev,
+ continue;
+
+ ret = cvm_mmc_of_slot_probe(&host->slot_pdev[i]->dev, host);
+- if (ret)
++ if (ret) {
++ of_node_put(child_node);
+ goto error;
++ }
+ }
+ i++;
+ }
+--
+2.35.1
+
--- /dev/null
+From 3cb542fb5f77dd1cd1a38aa017c919690842a2c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 17:10:51 +0800
+Subject: mmc: core: quirks: Add of_node_put() when breaking out of loop
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 883c1d6fa4368a63cae2d6ae2d9c91141c60e233 ]
+
+In mmc_fixup_of_compatible_match(), we should call of_node_put()
+when breaking out of for_each_child_of_node() which will increase
+and decrease the refcount during one iteration.
+
+Fixes: b360b1102670 ("mmc: core: allow to match the device tree to apply quirks")
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220719091051.1210806-1-windhl@126.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/quirks.h | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h
+index f879dc63d936..be4393988086 100644
+--- a/drivers/mmc/core/quirks.h
++++ b/drivers/mmc/core/quirks.h
+@@ -163,8 +163,10 @@ static inline bool mmc_fixup_of_compatible_match(struct mmc_card *card,
+ struct device_node *np;
+
+ for_each_child_of_node(mmc_dev(card->host)->of_node, np) {
+- if (of_device_is_compatible(np, compatible))
++ if (of_device_is_compatible(np, compatible)) {
++ of_node_put(np);
+ return true;
++ }
+ }
+
+ return false;
+--
+2.35.1
+
--- /dev/null
+From cd8d2d592b6154ce38959e75228aba57150a9414 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 22:00:22 -0300
+Subject: mmc: mxcmmc: Silence a clang warning
+
+From: Fabio Estevam <festevam@gmail.com>
+
+[ Upstream commit 7dc65e3c0ef4b746a583b7c58f99873fddf5ccfa ]
+
+Change the of_device_get_match_data() cast to (uintptr_t)
+to silence the following clang warning:
+
+drivers/mmc/host/mxcmmc.c:1028:18: warning: cast to smaller integer type 'enum mxcmci_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: 8223e885e74b ("mmc: mxc: Convert the driver to DT-only")
+Signed-off-by: Fabio Estevam <festevam@gmail.com>
+Link: https://lore.kernel.org/r/20220526010022.1163483-1-festevam@gmail.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/mxcmmc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
+index 40b6878bea6c..b5940083a108 100644
+--- a/drivers/mmc/host/mxcmmc.c
++++ b/drivers/mmc/host/mxcmmc.c
+@@ -1025,7 +1025,7 @@ static int mxcmci_probe(struct platform_device *pdev)
+ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+ mmc->max_seg_size = mmc->max_req_size;
+
+- host->devtype = (enum mxcmci_type)of_device_get_match_data(&pdev->dev);
++ host->devtype = (uintptr_t)of_device_get_match_data(&pdev->dev);
+
+ /* adjust max_segs after devtype detection */
+ if (!is_mpc512x_mmc(host))
+--
+2.35.1
+
--- /dev/null
+From a59b0afa39ee0e26995422c59b371a6f5e506a05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 19:14:37 +0100
+Subject: mmc: renesas_sdhi: Get the reset handle early in the probe
+
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+[ Upstream commit 0dac1e498f8130fdacfdd5289e3a7ac87ec1b9ad ]
+
+In case of devm_reset_control_get_optional_exclusive() failure we returned
+directly instead of jumping to the error path to roll back initialization.
+
+This patch moves devm_reset_control_get_optional_exclusive() early in the
+probe so that we have the reset handle prior to initialization of the
+hardware.
+
+Fixes: b4d86f37eacb7 ("mmc: renesas_sdhi: do hard reset if possible")
+Reported-by: Pavel Machek <pavel@denx.de>
+Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Link: https://lore.kernel.org/r/20220624181438.4355-2-prabhakar.mahadev-lad.rj@bp.renesas.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/renesas_sdhi_core.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
+index ddb5ca2f559e..4fb49306275e 100644
+--- a/drivers/mmc/host/renesas_sdhi_core.c
++++ b/drivers/mmc/host/renesas_sdhi_core.c
+@@ -940,6 +940,10 @@ int renesas_sdhi_probe(struct platform_device *pdev,
+ if (IS_ERR(priv->clk_cd))
+ return dev_err_probe(&pdev->dev, PTR_ERR(priv->clk_cd), "cannot get cd clock");
+
++ priv->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
++ if (IS_ERR(priv->rstc))
++ return PTR_ERR(priv->rstc);
++
+ priv->pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (!IS_ERR(priv->pinctrl)) {
+ priv->pins_default = pinctrl_lookup_state(priv->pinctrl,
+@@ -1032,10 +1036,6 @@ int renesas_sdhi_probe(struct platform_device *pdev,
+ if (ret)
+ goto efree;
+
+- priv->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
+- if (IS_ERR(priv->rstc))
+- return PTR_ERR(priv->rstc);
+-
+ ver = sd_ctrl_read16(host, CTL_VERSION);
+ /* GEN2_SDR104 is first known SDHI to use 32bit block count */
+ if (ver < SDHI_VER_GEN2_SDR104 && mmc_data->max_blk_count > U16_MAX)
+--
+2.35.1
+
--- /dev/null
+From 1849a8fe9c02e070450374de0fd9dd53b57db6db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jun 2022 12:09:26 +0300
+Subject: mmc: sdhci-of-at91: fix set_uhs_signaling rewriting of MC1R
+
+From: Eugen Hristev <eugen.hristev@microchip.com>
+
+[ Upstream commit 5987e6ded29d52e42fc7b06aa575c60a25eee38e ]
+
+In set_uhs_signaling, the DDR bit is being set by fully writing the MC1R
+register.
+This can lead to accidental erase of certain bits in this register.
+Avoid this by doing a read-modify-write operation.
+
+Fixes: d0918764c17b ("mmc: sdhci-of-at91: fix MMC_DDR_52 timing selection")
+Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
+Tested-by: Karl Olsen <karl@micro-technic.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/20220630090926.15061-1-eugen.hristev@microchip.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-of-at91.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c
+index 10fb4cb2c731..cd0134580a90 100644
+--- a/drivers/mmc/host/sdhci-of-at91.c
++++ b/drivers/mmc/host/sdhci-of-at91.c
+@@ -100,8 +100,13 @@ static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock)
+ static void sdhci_at91_set_uhs_signaling(struct sdhci_host *host,
+ unsigned int timing)
+ {
+- if (timing == MMC_TIMING_MMC_DDR52)
+- sdhci_writeb(host, SDMMC_MC1R_DDR, SDMMC_MC1R);
++ u8 mc1r;
++
++ if (timing == MMC_TIMING_MMC_DDR52) {
++ mc1r = sdhci_readb(host, SDMMC_MC1R);
++ mc1r |= SDMMC_MC1R_DDR;
++ sdhci_writeb(host, mc1r, SDMMC_MC1R);
++ }
+ sdhci_set_uhs_signaling(host, timing);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 565272fb28774ce567b694e6e27693954b7afddc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 May 2022 18:42:54 +0400
+Subject: mmc: sdhci-of-esdhc: Fix refcount leak in esdhc_signal_voltage_switch
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit b5899a3e2f783a27b268e38d37f9b24c71bddf45 ]
+
+of_find_matching_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+of_node_put() checks null pointer.
+
+Fixes: ea35645a3c66 ("mmc: sdhci-of-esdhc: add support for signal voltage switch")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220523144255.10310-1-linmq006@gmail.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-of-esdhc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
+index d9dc41143bb3..8b3d8119f388 100644
+--- a/drivers/mmc/host/sdhci-of-esdhc.c
++++ b/drivers/mmc/host/sdhci-of-esdhc.c
+@@ -904,6 +904,7 @@ static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
+ scfg_node = of_find_matching_node(NULL, scfg_device_ids);
+ if (scfg_node)
+ scfg_base = of_iomap(scfg_node, 0);
++ of_node_put(scfg_node);
+ if (scfg_base) {
+ sdhciovselcr = SDHCIOVSELCR_TGLEN |
+ SDHCIOVSELCR_VSELVAL;
+--
+2.35.1
+
--- /dev/null
+From 5536ffc5cd4009a333107d0930b7d281ecfe637f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 11:28:40 +0200
+Subject: mt76: connac: move connac2_mac_write_txwi in mt76_connac module
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 182071cdd594bc79f42899c85afa995c370ef82d ]
+
+mac_write_txwi code is shared between connac2 devices (mt7915 and
+mt7921). Move it in connac module.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt76_connac.h | 6 +
+ .../wireless/mediatek/mt76/mt76_connac_mac.c | 284 ++++++++++++++++++
+ .../net/wireless/mediatek/mt76/mt7915/mac.c | 251 +---------------
+ .../net/wireless/mediatek/mt76/mt7915/mcu.c | 2 +-
+ .../wireless/mediatek/mt76/mt7915/mt7915.h | 1 -
+ .../net/wireless/mediatek/mt76/mt7921/mac.c | 212 +------------
+ .../net/wireless/mediatek/mt76/mt7921/main.c | 2 +-
+ .../net/wireless/mediatek/mt76/mt7921/mcu.c | 4 +-
+ .../wireless/mediatek/mt76/mt7921/mt7921.h | 5 -
+ .../wireless/mediatek/mt76/mt7921/pci_mac.c | 4 +-
+ 10 files changed, 299 insertions(+), 472 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+index 400ba514460e..a9d7a269fcf3 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+@@ -12,6 +12,8 @@
+ #define MT76_CONNAC_MAX_SCHED_SCAN_SSID 10
+ #define MT76_CONNAC_MAX_SCAN_MATCH 16
+
++#define MT76_CONNAC_MAX_WMM_SETS 4
++
+ #define MT76_CONNAC_COREDUMP_TIMEOUT (HZ / 20)
+ #define MT76_CONNAC_COREDUMP_SZ (1300 * 1024)
+
+@@ -244,5 +246,9 @@ void mt76_connac_pm_queue_skb(struct ieee80211_hw *hw,
+ struct sk_buff *skb);
+ void mt76_connac_pm_dequeue_skbs(struct mt76_phy *phy,
+ struct mt76_connac_pm *pm);
++void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
++ struct sk_buff *skb, struct mt76_wcid *wcid,
++ struct ieee80211_key_conf *key, int pid,
++ u32 changed);
+
+ #endif /* __MT76_CONNAC_H */
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+index 306e9eaea917..0ea795565c88 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+@@ -2,6 +2,7 @@
+ /* Copyright (C) 2020 MediaTek Inc. */
+
+ #include "mt76_connac.h"
++#include "mt76_connac2_mac.h"
+
+ int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm)
+ {
+@@ -115,3 +116,286 @@ void mt76_connac_pm_dequeue_skbs(struct mt76_phy *phy,
+ mt76_worker_schedule(&phy->dev->tx_worker);
+ }
+ EXPORT_SYMBOL_GPL(mt76_connac_pm_dequeue_skbs);
++
++static u16
++mt76_connac2_mac_tx_rate_val(struct mt76_phy *mphy, struct ieee80211_vif *vif,
++ bool beacon, bool mcast)
++{
++ u8 mode = 0, band = mphy->chandef.chan->band;
++ int rateidx = 0, mcast_rate;
++
++ if (!vif)
++ goto legacy;
++
++ if (is_mt7921(mphy->dev)) {
++ rateidx = ffs(vif->bss_conf.basic_rates) - 1;
++ goto legacy;
++ }
++
++ if (beacon) {
++ struct cfg80211_bitrate_mask *mask;
++
++ mask = &vif->bss_conf.beacon_tx_rate;
++ if (hweight16(mask->control[band].he_mcs[0]) == 1) {
++ rateidx = ffs(mask->control[band].he_mcs[0]) - 1;
++ mode = MT_PHY_TYPE_HE_SU;
++ goto out;
++ } else if (hweight16(mask->control[band].vht_mcs[0]) == 1) {
++ rateidx = ffs(mask->control[band].vht_mcs[0]) - 1;
++ mode = MT_PHY_TYPE_VHT;
++ goto out;
++ } else if (hweight8(mask->control[band].ht_mcs[0]) == 1) {
++ rateidx = ffs(mask->control[band].ht_mcs[0]) - 1;
++ mode = MT_PHY_TYPE_HT;
++ goto out;
++ } else if (hweight32(mask->control[band].legacy) == 1) {
++ rateidx = ffs(mask->control[band].legacy) - 1;
++ goto legacy;
++ }
++ }
++
++ mcast_rate = vif->bss_conf.mcast_rate[band];
++ if (mcast && mcast_rate > 0)
++ rateidx = mcast_rate - 1;
++ else
++ rateidx = ffs(vif->bss_conf.basic_rates) - 1;
++
++legacy:
++ rateidx = mt76_calculate_default_rate(mphy, rateidx);
++ mode = rateidx >> 8;
++ rateidx &= GENMASK(7, 0);
++
++out:
++ return FIELD_PREP(MT_TX_RATE_IDX, rateidx) |
++ FIELD_PREP(MT_TX_RATE_MODE, mode);
++}
++
++static void
++mt76_connac2_mac_write_txwi_8023(__le32 *txwi, struct sk_buff *skb,
++ struct mt76_wcid *wcid)
++{
++ u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
++ u8 fc_type, fc_stype;
++ u16 ethertype;
++ bool wmm = false;
++ u32 val;
++
++ if (wcid->sta) {
++ struct ieee80211_sta *sta;
++
++ sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv);
++ wmm = sta->wme;
++ }
++
++ val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3) |
++ FIELD_PREP(MT_TXD1_TID, tid);
++
++ ethertype = get_unaligned_be16(&skb->data[12]);
++ if (ethertype >= ETH_P_802_3_MIN)
++ val |= MT_TXD1_ETH_802_3;
++
++ txwi[1] |= cpu_to_le32(val);
++
++ fc_type = IEEE80211_FTYPE_DATA >> 2;
++ fc_stype = wmm ? IEEE80211_STYPE_QOS_DATA >> 4 : 0;
++
++ val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) |
++ FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype);
++
++ txwi[2] |= cpu_to_le32(val);
++
++ val = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
++ FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype);
++
++ txwi[7] |= cpu_to_le32(val);
++}
++
++static void
++mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi,
++ struct sk_buff *skb,
++ struct ieee80211_key_conf *key)
++{
++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
++ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
++ bool multicast = is_multicast_ether_addr(hdr->addr1);
++ u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
++ __le16 fc = hdr->frame_control;
++ u8 fc_type, fc_stype;
++ u32 val;
++
++ if (ieee80211_is_action(fc) &&
++ mgmt->u.action.category == WLAN_CATEGORY_BACK &&
++ mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) {
++ u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
++
++ txwi[5] |= cpu_to_le32(MT_TXD5_ADD_BA);
++ tid = (capab >> 2) & IEEE80211_QOS_CTL_TID_MASK;
++ } else if (ieee80211_is_back_req(hdr->frame_control)) {
++ struct ieee80211_bar *bar = (struct ieee80211_bar *)hdr;
++ u16 control = le16_to_cpu(bar->control);
++
++ tid = FIELD_GET(IEEE80211_BAR_CTRL_TID_INFO_MASK, control);
++ }
++
++ val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_11) |
++ FIELD_PREP(MT_TXD1_HDR_INFO,
++ ieee80211_get_hdrlen_from_skb(skb) / 2) |
++ FIELD_PREP(MT_TXD1_TID, tid);
++
++ txwi[1] |= cpu_to_le32(val);
++
++ fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2;
++ fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4;
++
++ val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) |
++ FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype) |
++ FIELD_PREP(MT_TXD2_MULTICAST, multicast);
++
++ if (key && multicast && ieee80211_is_robust_mgmt_frame(skb) &&
++ key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
++ val |= MT_TXD2_BIP;
++ txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME);
++ }
++
++ if (!ieee80211_is_data(fc) || multicast ||
++ info->flags & IEEE80211_TX_CTL_USE_MINRATE)
++ val |= MT_TXD2_FIX_RATE;
++
++ txwi[2] |= cpu_to_le32(val);
++
++ if (ieee80211_is_beacon(fc)) {
++ txwi[3] &= ~cpu_to_le32(MT_TXD3_SW_POWER_MGMT);
++ txwi[3] |= cpu_to_le32(MT_TXD3_REM_TX_COUNT);
++ if (!is_mt7921(dev))
++ txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX,
++ 0x18));
++ }
++
++ if (info->flags & IEEE80211_TX_CTL_INJECTED) {
++ u16 seqno = le16_to_cpu(hdr->seq_ctrl);
++
++ if (ieee80211_is_back_req(hdr->frame_control)) {
++ struct ieee80211_bar *bar;
++
++ bar = (struct ieee80211_bar *)skb->data;
++ seqno = le16_to_cpu(bar->start_seq_num);
++ }
++
++ val = MT_TXD3_SN_VALID |
++ FIELD_PREP(MT_TXD3_SEQ, IEEE80211_SEQ_TO_SN(seqno));
++ txwi[3] |= cpu_to_le32(val);
++ txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU);
++ }
++
++ if (mt76_is_mmio(dev)) {
++ val = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
++ FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype);
++ txwi[7] |= cpu_to_le32(val);
++ } else {
++ val = FIELD_PREP(MT_TXD8_L_TYPE, fc_type) |
++ FIELD_PREP(MT_TXD8_L_SUB_TYPE, fc_stype);
++ txwi[8] |= cpu_to_le32(val);
++ }
++}
++
++void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
++ struct sk_buff *skb, struct mt76_wcid *wcid,
++ struct ieee80211_key_conf *key, int pid,
++ u32 changed)
++{
++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
++ bool ext_phy = info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY;
++ struct ieee80211_vif *vif = info->control.vif;
++ struct mt76_phy *mphy = &dev->phy;
++ u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0, band_idx = 0;
++ u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE : MT_SDIO_TXD_SIZE;
++ bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
++ bool beacon = !!(changed & (BSS_CHANGED_BEACON |
++ BSS_CHANGED_BEACON_ENABLED));
++ bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
++ BSS_CHANGED_FILS_DISCOVERY));
++
++ if (vif) {
++ struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
++
++ omac_idx = mvif->omac_idx;
++ wmm_idx = mvif->wmm_idx;
++ band_idx = mvif->band_idx;
++ }
++
++ if (ext_phy && dev->phy2)
++ mphy = dev->phy2;
++
++ if (inband_disc) {
++ p_fmt = MT_TX_TYPE_FW;
++ q_idx = MT_LMAC_ALTX0;
++ } else if (beacon) {
++ p_fmt = MT_TX_TYPE_FW;
++ q_idx = MT_LMAC_BCN0;
++ } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) {
++ p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
++ q_idx = MT_LMAC_ALTX0;
++ } else {
++ p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
++ q_idx = wmm_idx * MT76_CONNAC_MAX_WMM_SETS +
++ mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
++ }
++
++ val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) |
++ FIELD_PREP(MT_TXD0_PKT_FMT, p_fmt) |
++ FIELD_PREP(MT_TXD0_Q_IDX, q_idx);
++ txwi[0] = cpu_to_le32(val);
++
++ val = MT_TXD1_LONG_FORMAT |
++ FIELD_PREP(MT_TXD1_WLAN_IDX, wcid->idx) |
++ FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx);
++ if (!is_mt7921(dev))
++ val |= MT_TXD1_VTA;
++ if (ext_phy || band_idx)
++ val |= MT_TXD1_TGID;
++
++ txwi[1] = cpu_to_le32(val);
++ txwi[2] = 0;
++
++ val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, 15);
++ if (!is_mt7921(dev))
++ val |= MT_TXD3_SW_POWER_MGMT;
++ if (key)
++ val |= MT_TXD3_PROTECT_FRAME;
++ if (info->flags & IEEE80211_TX_CTL_NO_ACK)
++ val |= MT_TXD3_NO_ACK;
++
++ txwi[3] = cpu_to_le32(val);
++ txwi[4] = 0;
++
++ val = FIELD_PREP(MT_TXD5_PID, pid);
++ if (pid >= MT_PACKET_ID_FIRST)
++ val |= MT_TXD5_TX_STATUS_HOST;
++
++ txwi[5] = cpu_to_le32(val);
++ txwi[6] = 0;
++ txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0;
++
++ if (is_8023)
++ mt76_connac2_mac_write_txwi_8023(txwi, skb, wcid);
++ else
++ mt76_connac2_mac_write_txwi_80211(dev, txwi, skb, key);
++
++ if (txwi[2] & cpu_to_le32(MT_TXD2_FIX_RATE)) {
++ /* Fixed rata is available just for 802.11 txd */
++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
++ bool multicast = is_multicast_ether_addr(hdr->addr1);
++ u16 rate = mt76_connac2_mac_tx_rate_val(mphy, vif, beacon,
++ multicast);
++ u32 val = MT_TXD6_FIXED_BW;
++
++ /* hardware won't add HTC for mgmt/ctrl frame */
++ txwi[2] |= cpu_to_le32(MT_TXD2_HTC_VLD);
++
++ val |= FIELD_PREP(MT_TXD6_TX_RATE, rate);
++ txwi[6] |= cpu_to_le32(val);
++ txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
++ }
++}
++EXPORT_SYMBOL_GPL(mt76_connac2_mac_write_txwi);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+index d65a873739af..9bf8db47d103 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+@@ -1013,265 +1013,18 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
+ #endif
+ }
+
+-static void
+-mt7915_mac_write_txwi_8023(__le32 *txwi, struct sk_buff *skb,
+- struct mt76_wcid *wcid)
+-{
+-
+- u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
+- u8 fc_type, fc_stype;
+- u16 ethertype;
+- bool wmm = false;
+- u32 val;
+-
+- if (wcid->sta) {
+- struct ieee80211_sta *sta;
+-
+- sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv);
+- wmm = sta->wme;
+- }
+-
+- val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3) |
+- FIELD_PREP(MT_TXD1_TID, tid);
+-
+- ethertype = get_unaligned_be16(&skb->data[12]);
+- if (ethertype >= ETH_P_802_3_MIN)
+- val |= MT_TXD1_ETH_802_3;
+-
+- txwi[1] |= cpu_to_le32(val);
+-
+- fc_type = IEEE80211_FTYPE_DATA >> 2;
+- fc_stype = wmm ? IEEE80211_STYPE_QOS_DATA >> 4 : 0;
+-
+- val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) |
+- FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype);
+-
+- txwi[2] |= cpu_to_le32(val);
+-
+- val = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
+- FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype);
+- txwi[7] |= cpu_to_le32(val);
+-}
+-
+-static void
+-mt7915_mac_write_txwi_80211(__le32 *txwi, struct sk_buff *skb,
+- struct ieee80211_key_conf *key, bool *mcast)
+-{
+- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+- u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
+- __le16 fc = hdr->frame_control;
+- u8 fc_type, fc_stype;
+- u32 val;
+-
+- *mcast = is_multicast_ether_addr(hdr->addr1);
+-
+- if (ieee80211_is_action(fc) &&
+- mgmt->u.action.category == WLAN_CATEGORY_BACK &&
+- mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) {
+- u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
+-
+- txwi[5] |= cpu_to_le32(MT_TXD5_ADD_BA);
+- tid = (capab >> 2) & IEEE80211_QOS_CTL_TID_MASK;
+- } else if (ieee80211_is_back_req(hdr->frame_control)) {
+- struct ieee80211_bar *bar = (struct ieee80211_bar *)hdr;
+- u16 control = le16_to_cpu(bar->control);
+-
+- tid = FIELD_GET(IEEE80211_BAR_CTRL_TID_INFO_MASK, control);
+- }
+-
+- val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_11) |
+- FIELD_PREP(MT_TXD1_HDR_INFO,
+- ieee80211_get_hdrlen_from_skb(skb) / 2) |
+- FIELD_PREP(MT_TXD1_TID, tid);
+- txwi[1] |= cpu_to_le32(val);
+-
+- fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2;
+- fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4;
+-
+- val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) |
+- FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype) |
+- FIELD_PREP(MT_TXD2_MULTICAST, *mcast);
+-
+- if (key && *mcast && ieee80211_is_robust_mgmt_frame(skb) &&
+- key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
+- val |= MT_TXD2_BIP;
+- txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME);
+- }
+-
+- if (!ieee80211_is_data(fc) || *mcast ||
+- info->flags & IEEE80211_TX_CTL_USE_MINRATE)
+- val |= MT_TXD2_FIX_RATE;
+-
+- txwi[2] |= cpu_to_le32(val);
+-
+- if (ieee80211_is_beacon(fc)) {
+- txwi[3] &= ~cpu_to_le32(MT_TXD3_SW_POWER_MGMT);
+- txwi[3] |= cpu_to_le32(MT_TXD3_REM_TX_COUNT);
+- txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX, 0x18));
+- }
+-
+- if (info->flags & IEEE80211_TX_CTL_INJECTED) {
+- u16 seqno = le16_to_cpu(hdr->seq_ctrl);
+-
+- if (ieee80211_is_back_req(hdr->frame_control)) {
+- struct ieee80211_bar *bar;
+-
+- bar = (struct ieee80211_bar *)skb->data;
+- seqno = le16_to_cpu(bar->start_seq_num);
+- }
+-
+- val = MT_TXD3_SN_VALID |
+- FIELD_PREP(MT_TXD3_SEQ, IEEE80211_SEQ_TO_SN(seqno));
+- txwi[3] |= cpu_to_le32(val);
+- txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU);
+- }
+-
+- val = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
+- FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype);
+- txwi[7] |= cpu_to_le32(val);
+-}
+-
+-static u16
+-mt7915_mac_tx_rate_val(struct mt76_phy *mphy, struct ieee80211_vif *vif,
+- bool beacon, bool mcast)
+-{
+- u8 mode = 0, band = mphy->chandef.chan->band;
+- int rateidx = 0, mcast_rate;
+-
+- if (beacon) {
+- struct cfg80211_bitrate_mask *mask;
+-
+- mask = &vif->bss_conf.beacon_tx_rate;
+- if (hweight16(mask->control[band].he_mcs[0]) == 1) {
+- rateidx = ffs(mask->control[band].he_mcs[0]) - 1;
+- mode = MT_PHY_TYPE_HE_SU;
+- goto out;
+- } else if (hweight16(mask->control[band].vht_mcs[0]) == 1) {
+- rateidx = ffs(mask->control[band].vht_mcs[0]) - 1;
+- mode = MT_PHY_TYPE_VHT;
+- goto out;
+- } else if (hweight8(mask->control[band].ht_mcs[0]) == 1) {
+- rateidx = ffs(mask->control[band].ht_mcs[0]) - 1;
+- mode = MT_PHY_TYPE_HT;
+- goto out;
+- } else if (hweight32(mask->control[band].legacy) == 1) {
+- rateidx = ffs(mask->control[band].legacy) - 1;
+- goto legacy;
+- }
+- }
+-
+- mcast_rate = vif->bss_conf.mcast_rate[band];
+- if (mcast && mcast_rate > 0)
+- rateidx = mcast_rate - 1;
+- else
+- rateidx = ffs(vif->bss_conf.basic_rates) - 1;
+-
+-legacy:
+- rateidx = mt76_calculate_default_rate(mphy, rateidx);
+- mode = rateidx >> 8;
+- rateidx &= GENMASK(7, 0);
+-
+-out:
+- return FIELD_PREP(MT_TX_RATE_IDX, rateidx) |
+- FIELD_PREP(MT_TX_RATE_MODE, mode);
+-}
+-
+ void mt7915_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+ struct sk_buff *skb, struct mt76_wcid *wcid, int pid,
+ struct ieee80211_key_conf *key, u32 changed)
+ {
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+- struct ieee80211_vif *vif = info->control.vif;
+ struct mt76_phy *mphy = &dev->phy;
+- bool ext_phy = info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY;
+- u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0, band_idx = 0;
+- bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
+- bool mcast = false;
+- u16 tx_count = 15;
+- u32 val;
+- bool beacon = !!(changed & (BSS_CHANGED_BEACON |
+- BSS_CHANGED_BEACON_ENABLED));
+- bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
+- BSS_CHANGED_FILS_DISCOVERY));
+
+- if (vif) {
+- struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+-
+- omac_idx = mvif->mt76.omac_idx;
+- wmm_idx = mvif->mt76.wmm_idx;
+- band_idx = mvif->mt76.band_idx;
+- }
+-
+- if (ext_phy && dev->phy2)
++ if ((info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY) && dev->phy2)
+ mphy = dev->phy2;
+
+- if (inband_disc) {
+- p_fmt = MT_TX_TYPE_FW;
+- q_idx = MT_LMAC_ALTX0;
+- } else if (beacon) {
+- p_fmt = MT_TX_TYPE_FW;
+- q_idx = MT_LMAC_BCN0;
+- } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) {
+- p_fmt = MT_TX_TYPE_CT;
+- q_idx = MT_LMAC_ALTX0;
+- } else {
+- p_fmt = MT_TX_TYPE_CT;
+- q_idx = wmm_idx * MT7915_MAX_WMM_SETS +
+- mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
+- }
+-
+- val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + MT_TXD_SIZE) |
+- FIELD_PREP(MT_TXD0_PKT_FMT, p_fmt) |
+- FIELD_PREP(MT_TXD0_Q_IDX, q_idx);
+- txwi[0] = cpu_to_le32(val);
+-
+- val = MT_TXD1_LONG_FORMAT | MT_TXD1_VTA |
+- FIELD_PREP(MT_TXD1_WLAN_IDX, wcid->idx) |
+- FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx);
+-
+- if (ext_phy || band_idx)
+- val |= MT_TXD1_TGID;
+-
+- txwi[1] = cpu_to_le32(val);
+-
+- txwi[2] = 0;
++ mt76_connac2_mac_write_txwi(dev, txwi, skb, wcid, key, pid, changed);
+
+- val = MT_TXD3_SW_POWER_MGMT |
+- FIELD_PREP(MT_TXD3_REM_TX_COUNT, tx_count);
+- if (key)
+- val |= MT_TXD3_PROTECT_FRAME;
+- if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+- val |= MT_TXD3_NO_ACK;
+-
+- txwi[3] = cpu_to_le32(val);
+- txwi[4] = 0;
+-
+- val = FIELD_PREP(MT_TXD5_PID, pid);
+- if (pid >= MT_PACKET_ID_FIRST)
+- val |= MT_TXD5_TX_STATUS_HOST;
+- txwi[5] = cpu_to_le32(val);
+-
+- txwi[6] = 0;
+- txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0;
+-
+- if (is_8023)
+- mt7915_mac_write_txwi_8023(txwi, skb, wcid);
+- else
+- mt7915_mac_write_txwi_80211(txwi, skb, key, &mcast);
+-
+- if (txwi[2] & cpu_to_le32(MT_TXD2_FIX_RATE)) {
+- u16 rate = mt7915_mac_tx_rate_val(mphy, vif, beacon, mcast);
+-
+- /* hardware won't add HTC for mgmt/ctrl frame */
+- txwi[2] |= cpu_to_le32(MT_TXD2_HTC_VLD);
+-
+- val = MT_TXD6_FIXED_BW |
+- FIELD_PREP(MT_TXD6_TX_RATE, rate);
+- txwi[6] |= cpu_to_le32(val);
+- txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
+- }
+
+ if (mt76_testmode_enabled(mphy))
+ mt7915_mac_write_txwi_tm(mphy->priv, txwi, skb);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+index 0ef3952bc33c..695c38a6f90c 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -2701,7 +2701,7 @@ int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif)
+ struct edca *e = &req.edca[ac];
+
+ e->set = WMM_PARAM_SET;
+- e->queue = ac + mvif->mt76.wmm_idx * MT7915_MAX_WMM_SETS;
++ e->queue = ac + mvif->mt76.wmm_idx * MT76_CONNAC_MAX_WMM_SETS;
+ e->aifs = q->aifs;
+ e->txop = cpu_to_le16(q->txop);
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+index 41d76e24dd8b..6e4bff51b427 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+@@ -10,7 +10,6 @@
+ #include "regs.h"
+
+ #define MT7915_MAX_INTERFACES 19
+-#define MT7915_MAX_WMM_SETS 4
+ #define MT7915_WTBL_SIZE 288
+ #define MT7916_WTBL_SIZE 544
+ #define MT7915_WTBL_RESERVED (mt7915_wtbl_size(dev) - 1)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index 3ae7989c8500..297f3630537e 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -808,216 +808,6 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
+ return 0;
+ }
+
+-static void
+-mt7921_mac_write_txwi_8023(__le32 *txwi, struct sk_buff *skb,
+- struct mt76_wcid *wcid)
+-{
+- u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
+- u8 fc_type, fc_stype;
+- u16 ethertype;
+- bool wmm = false;
+- u32 val;
+-
+- if (wcid->sta) {
+- struct ieee80211_sta *sta;
+-
+- sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv);
+- wmm = sta->wme;
+- }
+-
+- val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3) |
+- FIELD_PREP(MT_TXD1_TID, tid);
+-
+- ethertype = get_unaligned_be16(&skb->data[12]);
+- if (ethertype >= ETH_P_802_3_MIN)
+- val |= MT_TXD1_ETH_802_3;
+-
+- txwi[1] |= cpu_to_le32(val);
+-
+- fc_type = IEEE80211_FTYPE_DATA >> 2;
+- fc_stype = wmm ? IEEE80211_STYPE_QOS_DATA >> 4 : 0;
+-
+- val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) |
+- FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype);
+-
+- txwi[2] |= cpu_to_le32(val);
+-
+- val = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
+- FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype);
+- txwi[7] |= cpu_to_le32(val);
+-}
+-
+-static void
+-mt7921_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi,
+- struct sk_buff *skb, struct ieee80211_key_conf *key)
+-{
+- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+- bool multicast = is_multicast_ether_addr(hdr->addr1);
+- u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
+- __le16 fc = hdr->frame_control;
+- u8 fc_type, fc_stype;
+- u32 val;
+-
+- if (ieee80211_is_action(fc) &&
+- mgmt->u.action.category == WLAN_CATEGORY_BACK &&
+- mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) {
+- u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
+-
+- txwi[5] |= cpu_to_le32(MT_TXD5_ADD_BA);
+- tid = (capab >> 2) & IEEE80211_QOS_CTL_TID_MASK;
+- } else if (ieee80211_is_back_req(hdr->frame_control)) {
+- struct ieee80211_bar *bar = (struct ieee80211_bar *)hdr;
+- u16 control = le16_to_cpu(bar->control);
+-
+- tid = FIELD_GET(IEEE80211_BAR_CTRL_TID_INFO_MASK, control);
+- }
+-
+- val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_11) |
+- FIELD_PREP(MT_TXD1_HDR_INFO,
+- ieee80211_get_hdrlen_from_skb(skb) / 2) |
+- FIELD_PREP(MT_TXD1_TID, tid);
+- txwi[1] |= cpu_to_le32(val);
+-
+- fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2;
+- fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4;
+-
+- val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) |
+- FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype) |
+- FIELD_PREP(MT_TXD2_MULTICAST, multicast);
+-
+- if (key && multicast && ieee80211_is_robust_mgmt_frame(skb) &&
+- key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
+- val |= MT_TXD2_BIP;
+- txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME);
+- }
+-
+- if (!ieee80211_is_data(fc) || multicast ||
+- info->flags & IEEE80211_TX_CTL_USE_MINRATE)
+- val |= MT_TXD2_FIX_RATE;
+-
+- txwi[2] |= cpu_to_le32(val);
+-
+- if (ieee80211_is_beacon(fc)) {
+- txwi[3] &= ~cpu_to_le32(MT_TXD3_SW_POWER_MGMT);
+- txwi[3] |= cpu_to_le32(MT_TXD3_REM_TX_COUNT);
+- }
+-
+- if (info->flags & IEEE80211_TX_CTL_INJECTED) {
+- u16 seqno = le16_to_cpu(hdr->seq_ctrl);
+-
+- if (ieee80211_is_back_req(hdr->frame_control)) {
+- struct ieee80211_bar *bar;
+-
+- bar = (struct ieee80211_bar *)skb->data;
+- seqno = le16_to_cpu(bar->start_seq_num);
+- }
+-
+- val = MT_TXD3_SN_VALID |
+- FIELD_PREP(MT_TXD3_SEQ, IEEE80211_SEQ_TO_SN(seqno));
+- txwi[3] |= cpu_to_le32(val);
+- txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU);
+- }
+-
+- if (mt76_is_mmio(dev)) {
+- val = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
+- FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype);
+- txwi[7] |= cpu_to_le32(val);
+- } else {
+- val = FIELD_PREP(MT_TXD8_L_TYPE, fc_type) |
+- FIELD_PREP(MT_TXD8_L_SUB_TYPE, fc_stype);
+- txwi[8] |= cpu_to_le32(val);
+- }
+-}
+-
+-void mt7921_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+- struct sk_buff *skb, struct mt76_wcid *wcid,
+- struct ieee80211_key_conf *key, int pid,
+- bool beacon)
+-{
+- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+- struct ieee80211_vif *vif = info->control.vif;
+- struct mt76_phy *mphy = &dev->phy;
+- u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0;
+- u32 sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE : MT_SDIO_TXD_SIZE;
+- bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
+- u16 tx_count = 15;
+- u32 val;
+-
+- if (vif) {
+- struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
+-
+- omac_idx = mvif->omac_idx;
+- wmm_idx = mvif->wmm_idx;
+- }
+-
+- if (beacon) {
+- p_fmt = MT_TX_TYPE_FW;
+- q_idx = MT_LMAC_BCN0;
+- } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) {
+- p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
+- q_idx = MT_LMAC_ALTX0;
+- } else {
+- p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
+- q_idx = wmm_idx * MT7921_MAX_WMM_SETS +
+- mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
+- }
+-
+- val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) |
+- FIELD_PREP(MT_TXD0_PKT_FMT, p_fmt) |
+- FIELD_PREP(MT_TXD0_Q_IDX, q_idx);
+- txwi[0] = cpu_to_le32(val);
+-
+- val = MT_TXD1_LONG_FORMAT |
+- FIELD_PREP(MT_TXD1_WLAN_IDX, wcid->idx) |
+- FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx);
+-
+- txwi[1] = cpu_to_le32(val);
+- txwi[2] = 0;
+-
+- val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, tx_count);
+- if (key)
+- val |= MT_TXD3_PROTECT_FRAME;
+- if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+- val |= MT_TXD3_NO_ACK;
+-
+- txwi[3] = cpu_to_le32(val);
+- txwi[4] = 0;
+-
+- val = FIELD_PREP(MT_TXD5_PID, pid);
+- if (pid >= MT_PACKET_ID_FIRST)
+- val |= MT_TXD5_TX_STATUS_HOST;
+- txwi[5] = cpu_to_le32(val);
+-
+- txwi[6] = 0;
+- txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0;
+-
+- if (is_8023)
+- mt7921_mac_write_txwi_8023(txwi, skb, wcid);
+- else
+- mt7921_mac_write_txwi_80211(dev, txwi, skb, key);
+-
+- if (txwi[2] & cpu_to_le32(MT_TXD2_FIX_RATE)) {
+- int rateidx = vif ? ffs(vif->bss_conf.basic_rates) - 1 : 0;
+- u16 rate, mode;
+-
+- /* hardware won't add HTC for mgmt/ctrl frame */
+- txwi[2] |= cpu_to_le32(MT_TXD2_HTC_VLD);
+-
+- rate = mt76_calculate_default_rate(mphy, rateidx);
+- mode = rate >> 8;
+- rate &= GENMASK(7, 0);
+- rate |= FIELD_PREP(MT_TX_RATE_MODE, mode);
+-
+- val = MT_TXD6_FIXED_BW |
+- FIELD_PREP(MT_TXD6_TX_RATE, rate);
+- txwi[6] |= cpu_to_le32(val);
+- txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
+- }
+-}
+-EXPORT_SYMBOL_GPL(mt7921_mac_write_txwi);
+-
+ void mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
+ {
+ struct mt7921_sta *msta;
+@@ -1645,7 +1435,7 @@ mt7921_usb_sdio_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid,
+ __le32 *txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE);
+
+ memset(txwi, 0, MT_SDIO_TXD_SIZE);
+- mt7921_mac_write_txwi(&dev->mt76, txwi, skb, wcid, key, pid, false);
++ mt76_connac2_mac_write_txwi(&dev->mt76, txwi, skb, wcid, key, pid, 0);
+ skb_push(skb, MT_SDIO_TXD_SIZE);
+ }
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+index d7e2bd605117..aa3d92d94353 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+@@ -321,7 +321,7 @@ static int mt7921_add_interface(struct ieee80211_hw *hw,
+ mvif->mt76.omac_idx = mvif->mt76.idx;
+ mvif->phy = phy;
+ mvif->mt76.band_idx = 0;
+- mvif->mt76.wmm_idx = mvif->mt76.idx % MT7921_MAX_WMM_SETS;
++ mvif->mt76.wmm_idx = mvif->mt76.idx % MT76_CONNAC_MAX_WMM_SETS;
+
+ ret = mt76_connac_mcu_uni_add_dev(&dev->mphy, vif, &mvif->sta.wcid,
+ true);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+index c2245be657d4..f2bfa0c4e737 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+@@ -1226,8 +1226,8 @@ mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev,
+ return -EINVAL;
+ }
+
+- mt7921_mac_write_txwi(&dev->mt76, (__le32 *)(req.beacon_tlv.pkt), skb,
+- wcid, NULL, 0, true);
++ mt76_connac2_mac_write_txwi(&dev->mt76, (__le32 *)(req.beacon_tlv.pkt),
++ skb, wcid, NULL, 0, BSS_CHANGED_BEACON);
+ memcpy(req.beacon_tlv.pkt + MT_TXD_SIZE, skb->data, skb->len);
+ req.beacon_tlv.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
+ req.beacon_tlv.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+index d105e815fcd4..9b484b389117 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+@@ -10,7 +10,6 @@
+ #include "regs.h"
+
+ #define MT7921_MAX_INTERFACES 4
+-#define MT7921_MAX_WMM_SETS 4
+ #define MT7921_WTBL_SIZE 20
+ #define MT7921_WTBL_RESERVED (MT7921_WTBL_SIZE - 1)
+ #define MT7921_WTBL_STA (MT7921_WTBL_RESERVED - \
+@@ -411,10 +410,6 @@ int mt7921_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ void *data, int len);
+ int mt7921_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+ struct netlink_callback *cb, void *data, int len);
+-void mt7921_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+- struct sk_buff *skb, struct mt76_wcid *wcid,
+- struct ieee80211_key_conf *key, int pid,
+- bool beacon);
+ void mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi);
+ void mt7921_mac_sta_poll(struct mt7921_dev *dev);
+ int mt7921_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb,
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c
+index f261cbfae2f3..b0f58bcf70cb 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c
+@@ -72,8 +72,8 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ }
+
+ pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
+- mt7921_mac_write_txwi(mdev, txwi_ptr, tx_info->skb, wcid, key,
+- pid, false);
++ mt76_connac2_mac_write_txwi(mdev, txwi_ptr, tx_info->skb, wcid, key,
++ pid, 0);
+
+ txp = (struct mt7921_txp_common *)(txwi + MT_TXD_SIZE);
+ memset(txp, 0, sizeof(struct mt7921_txp_common));
+--
+2.35.1
+
--- /dev/null
+From d3d26f6277444cd8f05771aa21dfc0f34386ff67 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 11:28:39 +0200
+Subject: mt76: connac: move mac connac2 defs in mt76_connac2_mac.h
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 90211957a640e6933b236e06728578d252f7374f ]
+
+This is a preliminary patch to share connac2 mac txwi code.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../wireless/mediatek/mt76/mt76_connac2_mac.h | 167 ++++++++++++++++++
+ .../net/wireless/mediatek/mt76/mt7915/mac.h | 142 +--------------
+ .../wireless/mediatek/mt76/mt7915/mt7915.h | 14 --
+ .../net/wireless/mediatek/mt76/mt7921/mac.h | 123 +------------
+ .../wireless/mediatek/mt76/mt7921/mt7921.h | 10 --
+ 5 files changed, 171 insertions(+), 285 deletions(-)
+ create mode 100644 drivers/net/wireless/mediatek/mt76/mt76_connac2_mac.h
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac2_mac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac2_mac.h
+new file mode 100644
+index 000000000000..c9d9c8475a38
+--- /dev/null
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac2_mac.h
+@@ -0,0 +1,167 @@
++/* SPDX-License-Identifier: ISC */
++/* Copyright (C) 2022 MediaTek Inc. */
++
++#ifndef __MT76_CONNAC2_MAC_H
++#define __MT76_CONNAC2_MAC_H
++
++enum tx_header_format {
++ MT_HDR_FORMAT_802_3,
++ MT_HDR_FORMAT_CMD,
++ MT_HDR_FORMAT_802_11,
++ MT_HDR_FORMAT_802_11_EXT,
++};
++
++enum tx_pkt_type {
++ MT_TX_TYPE_CT,
++ MT_TX_TYPE_SF,
++ MT_TX_TYPE_CMD,
++ MT_TX_TYPE_FW,
++};
++
++enum {
++ MT_CTX0,
++ MT_HIF0 = 0x0,
++
++ MT_LMAC_AC00 = 0x0,
++ MT_LMAC_AC01,
++ MT_LMAC_AC02,
++ MT_LMAC_AC03,
++ MT_LMAC_ALTX0 = 0x10,
++ MT_LMAC_BMC0,
++ MT_LMAC_BCN0,
++ MT_LMAC_PSMP0,
++};
++
++#define MT_TXD_SIZE (8 * 4)
++#define MT_SDIO_TXD_SIZE (MT_TXD_SIZE + 8 * 4)
++#define MT_SDIO_TAIL_SIZE 8
++#define MT_SDIO_HDR_SIZE 4
++#define MT_USB_TAIL_SIZE 4
++
++#define MT_TXD0_Q_IDX GENMASK(31, 25)
++#define MT_TXD0_PKT_FMT GENMASK(24, 23)
++#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16)
++#define MT_TXD0_TX_BYTES GENMASK(15, 0)
++
++#define MT_TXD1_LONG_FORMAT BIT(31)
++#define MT_TXD1_TGID BIT(30)
++#define MT_TXD1_OWN_MAC GENMASK(29, 24)
++#define MT_TXD1_AMSDU BIT(23)
++#define MT_TXD1_TID GENMASK(22, 20)
++#define MT_TXD1_HDR_PAD GENMASK(19, 18)
++#define MT_TXD1_HDR_FORMAT GENMASK(17, 16)
++#define MT_TXD1_HDR_INFO GENMASK(15, 11)
++#define MT_TXD1_ETH_802_3 BIT(15)
++#define MT_TXD1_VTA BIT(10)
++#define MT_TXD1_WLAN_IDX GENMASK(9, 0)
++
++#define MT_TXD2_FIX_RATE BIT(31)
++#define MT_TXD2_FIXED_RATE BIT(30)
++#define MT_TXD2_POWER_OFFSET GENMASK(29, 24)
++#define MT_TXD2_MAX_TX_TIME GENMASK(23, 16)
++#define MT_TXD2_FRAG GENMASK(15, 14)
++#define MT_TXD2_HTC_VLD BIT(13)
++#define MT_TXD2_DURATION BIT(12)
++#define MT_TXD2_BIP BIT(11)
++#define MT_TXD2_MULTICAST BIT(10)
++#define MT_TXD2_RTS BIT(9)
++#define MT_TXD2_SOUNDING BIT(8)
++#define MT_TXD2_NDPA BIT(7)
++#define MT_TXD2_NDP BIT(6)
++#define MT_TXD2_FRAME_TYPE GENMASK(5, 4)
++#define MT_TXD2_SUB_TYPE GENMASK(3, 0)
++
++#define MT_TXD3_SN_VALID BIT(31)
++#define MT_TXD3_PN_VALID BIT(30)
++#define MT_TXD3_SW_POWER_MGMT BIT(29)
++#define MT_TXD3_BA_DISABLE BIT(28)
++#define MT_TXD3_SEQ GENMASK(27, 16)
++#define MT_TXD3_REM_TX_COUNT GENMASK(15, 11)
++#define MT_TXD3_TX_COUNT GENMASK(10, 6)
++#define MT_TXD3_TIMING_MEASURE BIT(5)
++#define MT_TXD3_DAS BIT(4)
++#define MT_TXD3_EEOSP BIT(3)
++#define MT_TXD3_EMRD BIT(2)
++#define MT_TXD3_PROTECT_FRAME BIT(1)
++#define MT_TXD3_NO_ACK BIT(0)
++
++#define MT_TXD4_PN_LOW GENMASK(31, 0)
++
++#define MT_TXD5_PN_HIGH GENMASK(31, 16)
++#define MT_TXD5_MD BIT(15)
++#define MT_TXD5_ADD_BA BIT(14)
++#define MT_TXD5_TX_STATUS_HOST BIT(10)
++#define MT_TXD5_TX_STATUS_MCU BIT(9)
++#define MT_TXD5_TX_STATUS_FMT BIT(8)
++#define MT_TXD5_PID GENMASK(7, 0)
++
++#define MT_TXD6_TX_IBF BIT(31)
++#define MT_TXD6_TX_EBF BIT(30)
++#define MT_TXD6_TX_RATE GENMASK(29, 16)
++#define MT_TXD6_SGI GENMASK(15, 14)
++#define MT_TXD6_HELTF GENMASK(13, 12)
++#define MT_TXD6_LDPC BIT(11)
++#define MT_TXD6_SPE_ID_IDX BIT(10)
++#define MT_TXD6_ANT_ID GENMASK(7, 4)
++#define MT_TXD6_DYN_BW BIT(3)
++#define MT_TXD6_FIXED_BW BIT(2)
++#define MT_TXD6_BW GENMASK(1, 0)
++
++#define MT_TXD7_TXD_LEN GENMASK(31, 30)
++#define MT_TXD7_UDP_TCP_SUM BIT(29)
++#define MT_TXD7_IP_SUM BIT(28)
++#define MT_TXD7_TYPE GENMASK(21, 20)
++#define MT_TXD7_SUB_TYPE GENMASK(19, 16)
++
++#define MT_TXD7_PSE_FID GENMASK(27, 16)
++#define MT_TXD7_SPE_IDX GENMASK(15, 11)
++#define MT_TXD7_HW_AMSDU BIT(10)
++#define MT_TXD7_TX_TIME GENMASK(9, 0)
++
++#define MT_TXD8_L_TYPE GENMASK(5, 4)
++#define MT_TXD8_L_SUB_TYPE GENMASK(3, 0)
++
++#define MT_TX_RATE_STBC BIT(13)
++#define MT_TX_RATE_NSS GENMASK(12, 10)
++#define MT_TX_RATE_MODE GENMASK(9, 6)
++#define MT_TX_RATE_SU_EXT_TONE BIT(5)
++#define MT_TX_RATE_DCM BIT(4)
++/* VHT/HE only use bits 0-3 */
++#define MT_TX_RATE_IDX GENMASK(5, 0)
++
++#define MT_TXS0_FIXED_RATE BIT(31)
++#define MT_TXS0_BW GENMASK(30, 29)
++#define MT_TXS0_TID GENMASK(28, 26)
++#define MT_TXS0_AMPDU BIT(25)
++#define MT_TXS0_TXS_FORMAT GENMASK(24, 23)
++#define MT_TXS0_BA_ERROR BIT(22)
++#define MT_TXS0_PS_FLAG BIT(21)
++#define MT_TXS0_TXOP_TIMEOUT BIT(20)
++#define MT_TXS0_BIP_ERROR BIT(19)
++
++#define MT_TXS0_QUEUE_TIMEOUT BIT(18)
++#define MT_TXS0_RTS_TIMEOUT BIT(17)
++#define MT_TXS0_ACK_TIMEOUT BIT(16)
++#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16)
++
++#define MT_TXS0_TX_STATUS_HOST BIT(15)
++#define MT_TXS0_TX_STATUS_MCU BIT(14)
++#define MT_TXS0_TX_RATE GENMASK(13, 0)
++
++#define MT_TXS1_SEQNO GENMASK(31, 20)
++#define MT_TXS1_RESP_RATE GENMASK(19, 16)
++#define MT_TXS1_RXV_SEQNO GENMASK(15, 8)
++#define MT_TXS1_TX_POWER_DBM GENMASK(7, 0)
++
++#define MT_TXS2_BF_STATUS GENMASK(31, 30)
++#define MT_TXS2_LAST_TX_RATE GENMASK(29, 27)
++#define MT_TXS2_SHARED_ANTENNA BIT(26)
++#define MT_TXS2_WCID GENMASK(25, 16)
++#define MT_TXS2_TX_DELAY GENMASK(15, 0)
++
++#define MT_TXS3_PID GENMASK(31, 24)
++#define MT_TXS3_ANT_ID GENMASK(23, 0)
++
++#define MT_TXS4_TIMESTAMP GENMASK(31, 0)
++
++#endif /* __MT76_CONNAC2_MAC_H */
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
+index 5add1dd36dbe..51496981cb1e 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h
+@@ -4,6 +4,8 @@
+ #ifndef __MT7915_MAC_H
+ #define __MT7915_MAC_H
+
++#include "../mt76_connac2_mac.h"
++
+ #define MT_CT_PARSE_LEN 72
+ #define MT_CT_DMA_BUF_NUM 2
+
+@@ -165,20 +167,6 @@ enum rx_pkt_type {
+ #define MT_CRXV_FOE_HI GENMASK(6, 0)
+ #define MT_CRXV_FOE_SHIFT 13
+
+-enum tx_header_format {
+- MT_HDR_FORMAT_802_3,
+- MT_HDR_FORMAT_CMD,
+- MT_HDR_FORMAT_802_11,
+- MT_HDR_FORMAT_802_11_EXT,
+-};
+-
+-enum tx_pkt_type {
+- MT_TX_TYPE_CT,
+- MT_TX_TYPE_SF,
+- MT_TX_TYPE_CMD,
+- MT_TX_TYPE_FW,
+-};
+-
+ enum tx_port_idx {
+ MT_TX_PORT_IDX_LMAC,
+ MT_TX_PORT_IDX_MCU
+@@ -199,97 +187,6 @@ enum tx_mcu_port_q_idx {
+ #define MT_CT_INFO_HSR2_TX BIT(4)
+ #define MT_CT_INFO_FROM_HOST BIT(7)
+
+-#define MT_TXD_SIZE (8 * 4)
+-
+-#define MT_TXD0_Q_IDX GENMASK(31, 25)
+-#define MT_TXD0_PKT_FMT GENMASK(24, 23)
+-#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16)
+-#define MT_TXD0_TX_BYTES GENMASK(15, 0)
+-
+-#define MT_TXD1_LONG_FORMAT BIT(31)
+-#define MT_TXD1_TGID BIT(30)
+-#define MT_TXD1_OWN_MAC GENMASK(29, 24)
+-#define MT_TXD1_AMSDU BIT(23)
+-#define MT_TXD1_TID GENMASK(22, 20)
+-#define MT_TXD1_HDR_PAD GENMASK(19, 18)
+-#define MT_TXD1_HDR_FORMAT GENMASK(17, 16)
+-#define MT_TXD1_HDR_INFO GENMASK(15, 11)
+-#define MT_TXD1_ETH_802_3 BIT(15)
+-#define MT_TXD1_VTA BIT(10)
+-#define MT_TXD1_WLAN_IDX GENMASK(9, 0)
+-
+-#define MT_TXD2_FIX_RATE BIT(31)
+-#define MT_TXD2_FIXED_RATE BIT(30)
+-#define MT_TXD2_POWER_OFFSET GENMASK(29, 24)
+-#define MT_TXD2_MAX_TX_TIME GENMASK(23, 16)
+-#define MT_TXD2_FRAG GENMASK(15, 14)
+-#define MT_TXD2_HTC_VLD BIT(13)
+-#define MT_TXD2_DURATION BIT(12)
+-#define MT_TXD2_BIP BIT(11)
+-#define MT_TXD2_MULTICAST BIT(10)
+-#define MT_TXD2_RTS BIT(9)
+-#define MT_TXD2_SOUNDING BIT(8)
+-#define MT_TXD2_NDPA BIT(7)
+-#define MT_TXD2_NDP BIT(6)
+-#define MT_TXD2_FRAME_TYPE GENMASK(5, 4)
+-#define MT_TXD2_SUB_TYPE GENMASK(3, 0)
+-
+-#define MT_TXD3_SN_VALID BIT(31)
+-#define MT_TXD3_PN_VALID BIT(30)
+-#define MT_TXD3_SW_POWER_MGMT BIT(29)
+-#define MT_TXD3_BA_DISABLE BIT(28)
+-#define MT_TXD3_SEQ GENMASK(27, 16)
+-#define MT_TXD3_REM_TX_COUNT GENMASK(15, 11)
+-#define MT_TXD3_TX_COUNT GENMASK(10, 6)
+-#define MT_TXD3_TIMING_MEASURE BIT(5)
+-#define MT_TXD3_DAS BIT(4)
+-#define MT_TXD3_EEOSP BIT(3)
+-#define MT_TXD3_EMRD BIT(2)
+-#define MT_TXD3_PROTECT_FRAME BIT(1)
+-#define MT_TXD3_NO_ACK BIT(0)
+-
+-#define MT_TXD4_PN_LOW GENMASK(31, 0)
+-
+-#define MT_TXD5_PN_HIGH GENMASK(31, 16)
+-#define MT_TXD5_MD BIT(15)
+-#define MT_TXD5_ADD_BA BIT(14)
+-#define MT_TXD5_TX_STATUS_HOST BIT(10)
+-#define MT_TXD5_TX_STATUS_MCU BIT(9)
+-#define MT_TXD5_TX_STATUS_FMT BIT(8)
+-#define MT_TXD5_PID GENMASK(7, 0)
+-
+-#define MT_TXD6_TX_IBF BIT(31)
+-#define MT_TXD6_TX_EBF BIT(30)
+-#define MT_TXD6_TX_RATE GENMASK(29, 16)
+-#define MT_TXD6_SGI GENMASK(15, 14)
+-#define MT_TXD6_HELTF GENMASK(13, 12)
+-#define MT_TXD6_LDPC BIT(11)
+-#define MT_TXD6_SPE_ID_IDX BIT(10)
+-#define MT_TXD6_ANT_ID GENMASK(7, 4)
+-#define MT_TXD6_DYN_BW BIT(3)
+-#define MT_TXD6_FIXED_BW BIT(2)
+-#define MT_TXD6_BW GENMASK(1, 0)
+-
+-#define MT_TXD7_TXD_LEN GENMASK(31, 30)
+-#define MT_TXD7_UDP_TCP_SUM BIT(29)
+-#define MT_TXD7_IP_SUM BIT(28)
+-
+-#define MT_TXD7_TYPE GENMASK(21, 20)
+-#define MT_TXD7_SUB_TYPE GENMASK(19, 16)
+-
+-#define MT_TXD7_PSE_FID GENMASK(27, 16)
+-#define MT_TXD7_SPE_IDX GENMASK(15, 11)
+-#define MT_TXD7_HW_AMSDU BIT(10)
+-#define MT_TXD7_TX_TIME GENMASK(9, 0)
+-
+-#define MT_TX_RATE_STBC BIT(13)
+-#define MT_TX_RATE_NSS GENMASK(12, 10)
+-#define MT_TX_RATE_MODE GENMASK(9, 6)
+-#define MT_TX_RATE_SU_EXT_TONE BIT(5)
+-#define MT_TX_RATE_DCM BIT(4)
+-/* VHT/HE only use bits 0-3 */
+-#define MT_TX_RATE_IDX GENMASK(5, 0)
+-
+ #define MT_TXP_MAX_BUF_NUM 6
+
+ struct mt7915_txp {
+@@ -322,41 +219,6 @@ struct mt7915_tx_free {
+ /* will support this field in further revision */
+ #define MT_TX_FREE_RATE GENMASK(13, 0)
+
+-#define MT_TXS0_FIXED_RATE BIT(31)
+-#define MT_TXS0_BW GENMASK(30, 29)
+-#define MT_TXS0_TID GENMASK(28, 26)
+-#define MT_TXS0_AMPDU BIT(25)
+-#define MT_TXS0_TXS_FORMAT GENMASK(24, 23)
+-#define MT_TXS0_BA_ERROR BIT(22)
+-#define MT_TXS0_PS_FLAG BIT(21)
+-#define MT_TXS0_TXOP_TIMEOUT BIT(20)
+-#define MT_TXS0_BIP_ERROR BIT(19)
+-
+-#define MT_TXS0_QUEUE_TIMEOUT BIT(18)
+-#define MT_TXS0_RTS_TIMEOUT BIT(17)
+-#define MT_TXS0_ACK_TIMEOUT BIT(16)
+-#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16)
+-
+-#define MT_TXS0_TX_STATUS_HOST BIT(15)
+-#define MT_TXS0_TX_STATUS_MCU BIT(14)
+-#define MT_TXS0_TX_RATE GENMASK(13, 0)
+-
+-#define MT_TXS1_SEQNO GENMASK(31, 20)
+-#define MT_TXS1_RESP_RATE GENMASK(19, 16)
+-#define MT_TXS1_RXV_SEQNO GENMASK(15, 8)
+-#define MT_TXS1_TX_POWER_DBM GENMASK(7, 0)
+-
+-#define MT_TXS2_BF_STATUS GENMASK(31, 30)
+-#define MT_TXS2_LAST_TX_RATE GENMASK(29, 27)
+-#define MT_TXS2_SHARED_ANTENNA BIT(26)
+-#define MT_TXS2_WCID GENMASK(25, 16)
+-#define MT_TXS2_TX_DELAY GENMASK(15, 0)
+-
+-#define MT_TXS3_PID GENMASK(31, 24)
+-#define MT_TXS3_ANT_ID GENMASK(23, 0)
+-
+-#define MT_TXS4_TIMESTAMP GENMASK(31, 0)
+-
+ #define MT_TXS5_F0_FINAL_MPDU BIT(31)
+ #define MT_TXS5_F0_QOS BIT(30)
+ #define MT_TXS5_F0_TX_COUNT GENMASK(29, 25)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+index 64b4c3c09d33..41d76e24dd8b 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+@@ -335,20 +335,6 @@ enum {
+ __MT_WFDMA_MAX,
+ };
+
+-enum {
+- MT_CTX0,
+- MT_HIF0 = 0x0,
+-
+- MT_LMAC_AC00 = 0x0,
+- MT_LMAC_AC01,
+- MT_LMAC_AC02,
+- MT_LMAC_AC03,
+- MT_LMAC_ALTX0 = 0x10,
+- MT_LMAC_BMC0,
+- MT_LMAC_BCN0,
+- MT_LMAC_PSMP0,
+-};
+-
+ enum {
+ MT_RX_SEL0,
+ MT_RX_SEL1,
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.h b/drivers/net/wireless/mediatek/mt76/mt7921/mac.h
+index 79447e2d0143..556e687bd235 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.h
+@@ -4,6 +4,8 @@
+ #ifndef __MT7921_MAC_H
+ #define __MT7921_MAC_H
+
++#include "../mt76_connac2_mac.h"
++
+ #define MT_CT_PARSE_LEN 72
+ #define MT_CT_DMA_BUF_NUM 2
+
+@@ -163,20 +165,6 @@ enum rx_pkt_type {
+ #define MT_CRXV_FOE_HI GENMASK(6, 0)
+ #define MT_CRXV_FOE_SHIFT 13
+
+-enum tx_header_format {
+- MT_HDR_FORMAT_802_3,
+- MT_HDR_FORMAT_CMD,
+- MT_HDR_FORMAT_802_11,
+- MT_HDR_FORMAT_802_11_EXT,
+-};
+-
+-enum tx_pkt_type {
+- MT_TX_TYPE_CT,
+- MT_TX_TYPE_SF,
+- MT_TX_TYPE_CMD,
+- MT_TX_TYPE_FW,
+-};
+-
+ enum tx_port_idx {
+ MT_TX_PORT_IDX_LMAC,
+ MT_TX_PORT_IDX_MCU
+@@ -197,104 +185,6 @@ enum tx_mcu_port_q_idx {
+ #define MT_CT_INFO_HSR2_TX BIT(4)
+ #define MT_CT_INFO_FROM_HOST BIT(7)
+
+-#define MT_TXD_SIZE (8 * 4)
+-
+-#define MT_SDIO_TXD_SIZE (MT_TXD_SIZE + 8 * 4)
+-#define MT_SDIO_TAIL_SIZE 8
+-#define MT_SDIO_HDR_SIZE 4
+-#define MT_USB_TAIL_SIZE 4
+-
+-#define MT_TXD0_Q_IDX GENMASK(31, 25)
+-#define MT_TXD0_PKT_FMT GENMASK(24, 23)
+-#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16)
+-#define MT_TXD0_TX_BYTES GENMASK(15, 0)
+-
+-#define MT_TXD1_LONG_FORMAT BIT(31)
+-#define MT_TXD1_TGID BIT(30)
+-#define MT_TXD1_OWN_MAC GENMASK(29, 24)
+-#define MT_TXD1_AMSDU BIT(23)
+-#define MT_TXD1_TID GENMASK(22, 20)
+-#define MT_TXD1_HDR_PAD GENMASK(19, 18)
+-#define MT_TXD1_HDR_FORMAT GENMASK(17, 16)
+-#define MT_TXD1_HDR_INFO GENMASK(15, 11)
+-#define MT_TXD1_ETH_802_3 BIT(15)
+-#define MT_TXD1_VTA BIT(10)
+-#define MT_TXD1_WLAN_IDX GENMASK(9, 0)
+-
+-#define MT_TXD2_FIX_RATE BIT(31)
+-#define MT_TXD2_FIXED_RATE BIT(30)
+-#define MT_TXD2_POWER_OFFSET GENMASK(29, 24)
+-#define MT_TXD2_MAX_TX_TIME GENMASK(23, 16)
+-#define MT_TXD2_FRAG GENMASK(15, 14)
+-#define MT_TXD2_HTC_VLD BIT(13)
+-#define MT_TXD2_DURATION BIT(12)
+-#define MT_TXD2_BIP BIT(11)
+-#define MT_TXD2_MULTICAST BIT(10)
+-#define MT_TXD2_RTS BIT(9)
+-#define MT_TXD2_SOUNDING BIT(8)
+-#define MT_TXD2_NDPA BIT(7)
+-#define MT_TXD2_NDP BIT(6)
+-#define MT_TXD2_FRAME_TYPE GENMASK(5, 4)
+-#define MT_TXD2_SUB_TYPE GENMASK(3, 0)
+-
+-#define MT_TXD3_SN_VALID BIT(31)
+-#define MT_TXD3_PN_VALID BIT(30)
+-#define MT_TXD3_SW_POWER_MGMT BIT(29)
+-#define MT_TXD3_BA_DISABLE BIT(28)
+-#define MT_TXD3_SEQ GENMASK(27, 16)
+-#define MT_TXD3_REM_TX_COUNT GENMASK(15, 11)
+-#define MT_TXD3_TX_COUNT GENMASK(10, 6)
+-#define MT_TXD3_TIMING_MEASURE BIT(5)
+-#define MT_TXD3_DAS BIT(4)
+-#define MT_TXD3_EEOSP BIT(3)
+-#define MT_TXD3_EMRD BIT(2)
+-#define MT_TXD3_PROTECT_FRAME BIT(1)
+-#define MT_TXD3_NO_ACK BIT(0)
+-
+-#define MT_TXD4_PN_LOW GENMASK(31, 0)
+-
+-#define MT_TXD5_PN_HIGH GENMASK(31, 16)
+-#define MT_TXD5_MD BIT(15)
+-#define MT_TXD5_ADD_BA BIT(14)
+-#define MT_TXD5_TX_STATUS_HOST BIT(10)
+-#define MT_TXD5_TX_STATUS_MCU BIT(9)
+-#define MT_TXD5_TX_STATUS_FMT BIT(8)
+-#define MT_TXD5_PID GENMASK(7, 0)
+-
+-#define MT_TXD6_TX_IBF BIT(31)
+-#define MT_TXD6_TX_EBF BIT(30)
+-#define MT_TXD6_TX_RATE GENMASK(29, 16)
+-#define MT_TXD6_SGI GENMASK(15, 14)
+-#define MT_TXD6_HELTF GENMASK(13, 12)
+-#define MT_TXD6_LDPC BIT(11)
+-#define MT_TXD6_SPE_ID_IDX BIT(10)
+-#define MT_TXD6_ANT_ID GENMASK(7, 4)
+-#define MT_TXD6_DYN_BW BIT(3)
+-#define MT_TXD6_FIXED_BW BIT(2)
+-#define MT_TXD6_BW GENMASK(1, 0)
+-
+-#define MT_TXD7_TXD_LEN GENMASK(31, 30)
+-#define MT_TXD7_UDP_TCP_SUM BIT(29)
+-#define MT_TXD7_IP_SUM BIT(28)
+-
+-#define MT_TXD7_TYPE GENMASK(21, 20)
+-#define MT_TXD7_SUB_TYPE GENMASK(19, 16)
+-
+-#define MT_TXD7_PSE_FID GENMASK(27, 16)
+-#define MT_TXD7_SPE_IDX GENMASK(15, 11)
+-#define MT_TXD7_HW_AMSDU BIT(10)
+-#define MT_TXD7_TX_TIME GENMASK(9, 0)
+-
+-#define MT_TXD8_L_TYPE GENMASK(5, 4)
+-#define MT_TXD8_L_SUB_TYPE GENMASK(3, 0)
+-
+-#define MT_TX_RATE_STBC BIT(13)
+-#define MT_TX_RATE_NSS GENMASK(12, 10)
+-#define MT_TX_RATE_MODE GENMASK(9, 6)
+-#define MT_TX_RATE_SU_EXT_TONE BIT(5)
+-#define MT_TX_RATE_DCM BIT(4)
+-#define MT_TX_RATE_IDX GENMASK(3, 0)
+-
+ #define MT_TXP_MAX_BUF_NUM 6
+
+ struct mt7921_txp {
+@@ -325,15 +215,6 @@ struct mt7921_tx_free {
+ /* will support this field in further revision */
+ #define MT_TX_FREE_RATE GENMASK(13, 0)
+
+-#define MT_TXS0_BW GENMASK(30, 29)
+-#define MT_TXS0_TXS_FORMAT GENMASK(24, 23)
+-#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16)
+-#define MT_TXS0_TX_RATE GENMASK(13, 0)
+-
+-#define MT_TXS2_WCID GENMASK(25, 16)
+-
+-#define MT_TXS3_PID GENMASK(31, 24)
+-
+ static inline struct mt7921_txp_common *
+ mt7921_txwi_to_txp(struct mt76_dev *dev, struct mt76_txwi_cache *t)
+ {
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+index a049bd35e0bc..d105e815fcd4 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+@@ -244,16 +244,6 @@ struct mt7921_txpwr {
+ } data[TXPWR_MAX_NUM];
+ };
+
+-enum {
+- MT_LMAC_AC00,
+- MT_LMAC_AC01,
+- MT_LMAC_AC02,
+- MT_LMAC_AC03,
+- MT_LMAC_ALTX0 = 0x10,
+- MT_LMAC_BMC0,
+- MT_LMAC_BCN0,
+-};
+-
+ static inline struct mt7921_phy *
+ mt7921_hw_phy(struct ieee80211_hw *hw)
+ {
+--
+2.35.1
+
--- /dev/null
+From bcc9424317447f1b83d302a528e2ddf7fecb1570 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:03:28 +0200
+Subject: mt76: mt7615: do not update pm stats in case of error
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 79717c4eeeae9dec894794fbe8af72f08f03ebdd ]
+
+Do not update pm stats if mt7615_mcu_fw_pmctrl returns an error.
+
+Fixes: abe912ae3cd42 ("mt76: mt7663: add awake and doze time accounting")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+index 97e2a85cb728..6f3efec58afe 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+@@ -350,10 +350,11 @@ static int mt7615_mcu_fw_pmctrl(struct mt7615_dev *dev)
+ }
+
+ mt7622_trigger_hif_int(dev, false);
+-
+- pm->stats.last_doze_event = jiffies;
+- pm->stats.awake_time += pm->stats.last_doze_event -
+- pm->stats.last_wake_event;
++ if (!err) {
++ pm->stats.last_doze_event = jiffies;
++ pm->stats.awake_time += pm->stats.last_doze_event -
++ pm->stats.last_wake_event;
++ }
+ out:
+ mutex_unlock(&pm->mutex);
+
+--
+2.35.1
+
--- /dev/null
+From 9759c260a9dac700c3090c7e7be5c1e98aa9f420 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 20:57:47 +0200
+Subject: mt76: mt7615: fix throughput regression on DFS channels
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit aac86cebb4a09e3fa2c07589f79f7d0e07e8c9a4 ]
+
+For some reason, mt7615 reacts badly to repeatedly enabling/disabling the radar
+detector without also switching the channel.
+This results in very bad throughput on DFS channels, because
+hw->conf.radar_enabled can get toggled a few times after CAC ends.
+Fix this by always leaving the DFS detector enabled on DFS channels and instead
+suppress unwanted detection events.
+
+Fixes: 2c86f6752046 ("mt76: mt7615: fix/rewrite the dfs state handling logic")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt7615/mac.c | 7 ++++---
+ .../net/wireless/mediatek/mt76/mt7615/main.c | 21 -------------------
+ .../net/wireless/mediatek/mt76/mt7615/mcu.c | 3 +++
+ .../wireless/mediatek/mt76/mt7615/mt7615.h | 1 -
+ 4 files changed, 7 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+index bd687f7de628..9e832b27170f 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+@@ -2282,6 +2282,7 @@ mt7615_dfs_init_radar_specs(struct mt7615_phy *phy)
+
+ int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy)
+ {
++ struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
+ struct mt7615_dev *dev = phy->dev;
+ bool ext_phy = phy != &dev->phy;
+ enum mt76_dfs_state dfs_state, prev_state;
+@@ -2292,13 +2293,13 @@ int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy)
+
+ prev_state = phy->mt76->dfs_state;
+ dfs_state = mt76_phy_dfs_state(phy->mt76);
++ if ((chandef->chan->flags & IEEE80211_CHAN_RADAR) &&
++ dfs_state < MT_DFS_STATE_CAC)
++ dfs_state = MT_DFS_STATE_ACTIVE;
+
+ if (prev_state == dfs_state)
+ return 0;
+
+- if (prev_state == MT_DFS_STATE_UNKNOWN)
+- mt7615_dfs_stop_radar_detector(phy);
+-
+ if (dfs_state == MT_DFS_STATE_DISABLED)
+ goto stop;
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+index 6b8e3e7ae4a2..36990637a8a2 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+@@ -282,26 +282,6 @@ static void mt7615_remove_interface(struct ieee80211_hw *hw,
+ mt76_packet_id_flush(&dev->mt76, &mvif->sta.wcid);
+ }
+
+-static void mt7615_init_dfs_state(struct mt7615_phy *phy)
+-{
+- struct mt76_phy *mphy = phy->mt76;
+- struct ieee80211_hw *hw = mphy->hw;
+- struct cfg80211_chan_def *chandef = &hw->conf.chandef;
+-
+- if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
+- return;
+-
+- if (!(chandef->chan->flags & IEEE80211_CHAN_RADAR) &&
+- !(mphy->chandef.chan->flags & IEEE80211_CHAN_RADAR))
+- return;
+-
+- if (mphy->chandef.chan->center_freq == chandef->chan->center_freq &&
+- mphy->chandef.width == chandef->width)
+- return;
+-
+- phy->dfs_state = -1;
+-}
+-
+ int mt7615_set_channel(struct mt7615_phy *phy)
+ {
+ struct mt7615_dev *dev = phy->dev;
+@@ -314,7 +294,6 @@ int mt7615_set_channel(struct mt7615_phy *phy)
+
+ set_bit(MT76_RESET, &phy->mt76->state);
+
+- mt7615_init_dfs_state(phy);
+ mt76_set_channel(phy->mt76);
+
+ if (is_mt7615(&dev->mt76) && dev->flash_eeprom) {
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+index 6f3efec58afe..7127d6007ae0 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+@@ -403,6 +403,9 @@ mt7615_mcu_rx_radar_detected(struct mt7615_dev *dev, struct sk_buff *skb)
+ if (r->band_idx && dev->mt76.phy2)
+ mphy = dev->mt76.phy2;
+
++ if (mt76_phy_dfs_state(mphy) < MT_DFS_STATE_CAC)
++ return;
++
+ ieee80211_radar_detected(mphy->hw);
+ dev->hw_pattern++;
+ }
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
+index 2e91f6a27d0f..082c73b571ae 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
+@@ -177,7 +177,6 @@ struct mt7615_phy {
+
+ u8 chfreq;
+ u8 rdd_state;
+- int dfs_state;
+
+ u32 rx_ampdu_ts;
+ u32 ampdu_ref;
+--
+2.35.1
+
--- /dev/null
+From 278defaea33655ccc53488197795621489eb8738 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 May 2022 18:37:07 +0200
+Subject: mt76: mt76x02u: fix possible memory leak in __mt76x02u_mcu_send_msg
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit cffd93411575afd987788e2ec3cb8eaff70f0215 ]
+
+Free the skb if mt76u_bulk_msg fails in __mt76x02u_mcu_send_msg routine.
+
+Fixes: 4c89ff2c74e39 ("mt76: split __mt76u_mcu_send_msg and mt76u_mcu_send_msg routines")
+Co-developed-by: Gergo Koteles <soyer@irl.hu>
+Signed-off-by: Gergo Koteles <soyer@irl.hu>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c
+index 2953df7d8388..c6c16fe8ee85 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c
+@@ -108,7 +108,7 @@ __mt76x02u_mcu_send_msg(struct mt76_dev *dev, struct sk_buff *skb,
+ ret = mt76u_bulk_msg(dev, skb->data, skb->len, NULL, 500,
+ MT_EP_OUT_INBAND_CMD);
+ if (ret)
+- return ret;
++ goto out;
+
+ if (wait_resp)
+ ret = mt76x02u_mcu_wait_resp(dev, seq);
+--
+2.35.1
+
--- /dev/null
+From e4cfaffd52b1756a4fdab00b30e525a8962df8de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Apr 2022 10:23:35 +0800
+Subject: mt76: mt7915: add support for 6G in-band discovery
+
+From: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
+
+[ Upstream commit 869f06468e77b06795bc5855bd5b6b03c6cb147c ]
+
+Add offloading FILS discovery and unsolicited broadcast probe response support.
+
+Reviewed-by: Ryder Lee <ryder.lee@mediatek.com>
+Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt7915/init.c | 2 +
+ .../net/wireless/mediatek/mt76/mt7915/mac.c | 17 +++--
+ .../net/wireless/mediatek/mt76/mt7915/main.c | 8 +-
+ .../net/wireless/mediatek/mt76/mt7915/mcu.c | 75 ++++++++++++++++++-
+ .../net/wireless/mediatek/mt76/mt7915/mcu.h | 15 +++-
+ .../wireless/mediatek/mt76/mt7915/mt7915.h | 4 +-
+ 6 files changed, 107 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+index 6d29366c5139..a03251a2960a 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+@@ -351,6 +351,8 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE);
++ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP);
++ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_DISCOVERY);
+
+ if (!mdev->dev->of_node ||
+ !of_property_read_bool(mdev->dev->of_node,
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+index 45169a027fda..7873fdaf0373 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+@@ -1181,7 +1181,7 @@ mt7915_mac_tx_rate_val(struct mt76_phy *mphy, struct ieee80211_vif *vif,
+
+ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
+ struct sk_buff *skb, struct mt76_wcid *wcid, int pid,
+- struct ieee80211_key_conf *key, bool beacon)
++ struct ieee80211_key_conf *key, u32 changed)
+ {
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_vif *vif = info->control.vif;
+@@ -1192,6 +1192,10 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
+ bool mcast = false;
+ u16 tx_count = 15;
+ u32 val;
++ bool beacon = !!(changed & (BSS_CHANGED_BEACON |
++ BSS_CHANGED_BEACON_ENABLED));
++ bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
++ BSS_CHANGED_FILS_DISCOVERY));
+
+ if (vif) {
+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+@@ -1204,7 +1208,10 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
+ if (ext_phy && dev->mt76.phy2)
+ mphy = dev->mt76.phy2;
+
+- if (beacon) {
++ if (inband_disc) {
++ p_fmt = MT_TX_TYPE_FW;
++ q_idx = MT_LMAC_ALTX0;
++ } else if (beacon) {
+ p_fmt = MT_TX_TYPE_FW;
+ q_idx = MT_LMAC_BCN0;
+ } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) {
+@@ -1312,8 +1319,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ return id;
+
+ pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
+- mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key,
+- false);
++ mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key, 0);
+
+ txp = (struct mt7915_txp *)(txwi + MT_TXD_SIZE);
+ for (i = 0; i < nbuf; i++) {
+@@ -1923,7 +1929,8 @@ mt7915_update_vif_beacon(void *priv, u8 *mac, struct ieee80211_vif *vif)
+ case NL80211_IFTYPE_MESH_POINT:
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_AP:
+- mt7915_mcu_add_beacon(hw, vif, vif->bss_conf.enable_beacon);
++ mt7915_mcu_add_beacon(hw, vif, vif->bss_conf.enable_beacon,
++ BSS_CHANGED_BEACON_ENABLED);
+ break;
+ default:
+ break;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+index 187cf4ccd36e..d6d0a17c3730 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+@@ -630,8 +630,10 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
+ mt7915_update_bss_color(hw, vif, &info->he_bss_color);
+
+ if (changed & (BSS_CHANGED_BEACON |
+- BSS_CHANGED_BEACON_ENABLED))
+- mt7915_mcu_add_beacon(hw, vif, info->enable_beacon);
++ BSS_CHANGED_BEACON_ENABLED |
++ BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
++ BSS_CHANGED_FILS_DISCOVERY))
++ mt7915_mcu_add_beacon(hw, vif, info->enable_beacon, changed);
+
+ mutex_unlock(&dev->mt76.mutex);
+ }
+@@ -644,7 +646,7 @@ mt7915_channel_switch_beacon(struct ieee80211_hw *hw,
+ struct mt7915_dev *dev = mt7915_hw_dev(hw);
+
+ mutex_lock(&dev->mt76.mutex);
+- mt7915_mcu_add_beacon(hw, vif, true);
++ mt7915_mcu_add_beacon(hw, vif, true, BSS_CHANGED_BEACON);
+ mutex_unlock(&dev->mt76.mutex);
+ }
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+index 736c9c342baa..4bfb26e730eb 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -1892,6 +1892,7 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ u8 *buf;
+ int len = sizeof(*cont) + MT_TXD_SIZE + skb->len;
+
++ len = (len & 0x3) ? ((len | 0x3) + 1) : len;
+ tlv = mt7915_mcu_add_nested_subtlv(rskb, BSS_INFO_BCN_CONTENT,
+ len, &bcn->sub_ntlv, &bcn->len);
+
+@@ -1910,7 +1911,7 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+
+ buf = (u8 *)tlv + sizeof(*cont);
+ mt7915_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL,
+- true);
++ BSS_CHANGED_BEACON);
+ memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
+ }
+
+@@ -1992,8 +1993,71 @@ mt7915_mcu_beacon_check_caps(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+ }
+ }
+
+-int mt7915_mcu_add_beacon(struct ieee80211_hw *hw,
+- struct ieee80211_vif *vif, int en)
++static void
++mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
++ struct sk_buff *rskb, struct bss_info_bcn *bcn,
++ u32 changed)
++{
++#define OFFLOAD_TX_MODE_SU BIT(0)
++#define OFFLOAD_TX_MODE_MU BIT(1)
++ struct ieee80211_hw *hw = mt76_hw(dev);
++ struct mt7915_phy *phy = mt7915_hw_phy(hw);
++ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
++ struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef;
++ enum nl80211_band band = chandef->chan->band;
++ struct mt76_wcid *wcid = &dev->mt76.global_wcid;
++ struct bss_info_inband_discovery *discov;
++ struct ieee80211_tx_info *info;
++ struct sk_buff *skb = NULL;
++ struct tlv *tlv;
++ bool ext_phy = phy != &dev->phy;
++ u8 *buf, interval;
++ int len;
++
++ if (changed & BSS_CHANGED_FILS_DISCOVERY &&
++ vif->bss_conf.fils_discovery.max_interval) {
++ interval = vif->bss_conf.fils_discovery.max_interval;
++ skb = ieee80211_get_fils_discovery_tmpl(hw, vif);
++ } else if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP &&
++ vif->bss_conf.unsol_bcast_probe_resp_interval) {
++ interval = vif->bss_conf.unsol_bcast_probe_resp_interval;
++ skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(hw, vif);
++ }
++
++ if (!skb)
++ return;
++
++ info = IEEE80211_SKB_CB(skb);
++ info->control.vif = vif;
++ info->band = band;
++
++ if (ext_phy)
++ info->hw_queue |= MT_TX_HW_QUEUE_EXT_PHY;
++
++ len = sizeof(*discov) + MT_TXD_SIZE + skb->len;
++ len = (len & 0x3) ? ((len | 0x3) + 1) : len;
++
++ tlv = mt7915_mcu_add_nested_subtlv(rskb, BSS_INFO_BCN_DISCOV,
++ len, &bcn->sub_ntlv, &bcn->len);
++ discov = (struct bss_info_inband_discovery *)tlv;
++ discov->tx_mode = OFFLOAD_TX_MODE_SU;
++ /* 0: UNSOL PROBE RESP, 1: FILS DISCOV */
++ discov->tx_type = !!(changed & BSS_CHANGED_FILS_DISCOVERY);
++ discov->tx_interval = interval;
++ discov->prob_rsp_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
++ discov->enable = true;
++
++ buf = (u8 *)tlv + sizeof(*discov);
++
++ mt7915_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL,
++ changed);
++ memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
++
++ dev_kfree_skb(skb);
++}
++
++int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
++ int en, u32 changed)
+ {
+ #define MAX_BEACON_SIZE 512
+ struct mt7915_dev *dev = mt7915_hw_dev(hw);
+@@ -2044,6 +2108,11 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw,
+ mt7915_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);
+ dev_kfree_skb(skb);
+
++ if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP ||
++ changed & BSS_CHANGED_FILS_DISCOVERY)
++ mt7915_mcu_beacon_inband_discov(dev, vif, rskb,
++ bcn, changed);
++
+ out:
+ return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb,
+ MCU_EXT_CMD(BSS_INFO_UPDATE), true);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+index 960072a44222..2b5495bd1e20 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+@@ -414,11 +414,23 @@ struct bss_info_bcn_cont {
+ __le16 pkt_len;
+ } __packed __aligned(4);
+
++struct bss_info_inband_discovery {
++ __le16 tag;
++ __le16 len;
++ u8 tx_type;
++ u8 tx_mode;
++ u8 tx_interval;
++ u8 enable;
++ __le16 rsv;
++ __le16 prob_rsp_len;
++} __packed __aligned(4);
++
+ enum {
+ BSS_INFO_BCN_CSA,
+ BSS_INFO_BCN_BCC,
+ BSS_INFO_BCN_MBSSID,
+ BSS_INFO_BCN_CONTENT,
++ BSS_INFO_BCN_DISCOV,
+ BSS_INFO_BCN_MAX
+ };
+
+@@ -486,6 +498,7 @@ enum {
+ #define MT7915_BEACON_UPDATE_SIZE (sizeof(struct sta_req_hdr) + \
+ sizeof(struct bss_info_bcn_cntdwn) + \
+ sizeof(struct bss_info_bcn_mbss) + \
+- sizeof(struct bss_info_bcn_cont))
++ sizeof(struct bss_info_bcn_cont) + \
++ sizeof(struct bss_info_inband_discovery))
+
+ #endif
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+index 4b6eda958ef3..ff413fe1da5e 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+@@ -463,7 +463,7 @@ int mt7915_mcu_add_rx_ba(struct mt7915_dev *dev,
+ int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ struct cfg80211_he_bss_color *he_bss_color);
+ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+- int enable);
++ int enable, u32 changed);
+ int mt7915_mcu_add_obss_spr(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ bool enable);
+ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+@@ -550,7 +550,7 @@ void mt7915_mac_cca_stats_reset(struct mt7915_phy *phy);
+ void mt7915_mac_enable_nf(struct mt7915_dev *dev, bool ext_phy);
+ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
+ struct sk_buff *skb, struct mt76_wcid *wcid, int pid,
+- struct ieee80211_key_conf *key, bool beacon);
++ struct ieee80211_key_conf *key, u32 changed);
+ void mt7915_mac_set_timing(struct mt7915_phy *phy);
+ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta);
+--
+2.35.1
+
--- /dev/null
+From 97c5577cb493dbe3f3ef0bf350695e52d9df9acd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 14:17:17 +0800
+Subject: mt76: mt7915: fix incorrect testmode ipg on band 1 caused by wmm_idx
+
+From: Shayne Chen <shayne.chen@mediatek.com>
+
+[ Upstream commit 6e744cfeee02c2d8676eb55d5b3720808812f41f ]
+
+Fix the issue that the measured inter packet gap didn't fit its
+setting value.
+
+Fixes: c2d3b1926f30 ("mt76: mt7915: add support for ipg in testmode")
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7915/testmode.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
+index 20f63644e929..0f5c1e5bffe1 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
+@@ -168,13 +168,14 @@ mt7915_tm_set_tam_arb(struct mt7915_phy *phy, bool enable, bool mu)
+ }
+
+ static int
+-mt7915_tm_set_wmm_qid(struct mt7915_dev *dev, u8 qid, u8 aifs, u8 cw_min,
++mt7915_tm_set_wmm_qid(struct mt7915_phy *phy, u8 qid, u8 aifs, u8 cw_min,
+ u16 cw_max, u16 txop)
+ {
++ struct mt7915_vif *mvif = (struct mt7915_vif *)phy->monitor_vif->drv_priv;
+ struct mt7915_mcu_tx req = { .total = 1 };
+ struct edca *e = &req.edca[0];
+
+- e->queue = qid;
++ e->queue = qid + mvif->mt76.wmm_idx * MT76_CONNAC_MAX_WMM_SETS;
+ e->set = WMM_PARAM_SET;
+
+ e->aifs = aifs;
+@@ -182,7 +183,7 @@ mt7915_tm_set_wmm_qid(struct mt7915_dev *dev, u8 qid, u8 aifs, u8 cw_min,
+ e->cw_max = cpu_to_le16(cw_max);
+ e->txop = cpu_to_le16(txop);
+
+- return mt7915_mcu_update_edca(dev, &req);
++ return mt7915_mcu_update_edca(phy->dev, &req);
+ }
+
+ static int
+@@ -244,7 +245,7 @@ mt7915_tm_set_ipg_params(struct mt7915_phy *phy, u32 ipg, u8 mode)
+
+ mt7915_tm_set_slot_time(phy, slot_time, sifs);
+
+- return mt7915_tm_set_wmm_qid(dev,
++ return mt7915_tm_set_wmm_qid(phy,
+ mt76_connac_lmac_mapping(IEEE80211_AC_BE),
+ aifsn, cw, cw, 0);
+ }
+--
+2.35.1
+
--- /dev/null
+From ca4fb9b60c0b6bb52c2bdd4b3a3800096b9a4c0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 11:28:38 +0200
+Subject: mt76: mt7915: rely on mt76_dev in mt7915_mac_write_txwi signature
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit d502e30020b85857ead0f9d392d24dba8c0f44cb ]
+
+This is a preliminary patch to share txwi configuration code.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt7915/mac.c | 23 +++++++++----------
+ .../net/wireless/mediatek/mt76/mt7915/mcu.c | 4 ++--
+ .../wireless/mediatek/mt76/mt7915/mt7915.h | 2 +-
+ 3 files changed, 14 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+index 7873fdaf0373..d65a873739af 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+@@ -1014,8 +1014,8 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
+ }
+
+ static void
+-mt7915_mac_write_txwi_8023(struct mt7915_dev *dev, __le32 *txwi,
+- struct sk_buff *skb, struct mt76_wcid *wcid)
++mt7915_mac_write_txwi_8023(__le32 *txwi, struct sk_buff *skb,
++ struct mt76_wcid *wcid)
+ {
+
+ u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
+@@ -1054,9 +1054,8 @@ mt7915_mac_write_txwi_8023(struct mt7915_dev *dev, __le32 *txwi,
+ }
+
+ static void
+-mt7915_mac_write_txwi_80211(struct mt7915_dev *dev, __le32 *txwi,
+- struct sk_buff *skb, struct ieee80211_key_conf *key,
+- bool *mcast)
++mt7915_mac_write_txwi_80211(__le32 *txwi, struct sk_buff *skb,
++ struct ieee80211_key_conf *key, bool *mcast)
+ {
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+@@ -1179,13 +1178,13 @@ mt7915_mac_tx_rate_val(struct mt76_phy *mphy, struct ieee80211_vif *vif,
+ FIELD_PREP(MT_TX_RATE_MODE, mode);
+ }
+
+-void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
++void mt7915_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+ struct sk_buff *skb, struct mt76_wcid *wcid, int pid,
+ struct ieee80211_key_conf *key, u32 changed)
+ {
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_vif *vif = info->control.vif;
+- struct mt76_phy *mphy = &dev->mphy;
++ struct mt76_phy *mphy = &dev->phy;
+ bool ext_phy = info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY;
+ u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0, band_idx = 0;
+ bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
+@@ -1205,8 +1204,8 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
+ band_idx = mvif->mt76.band_idx;
+ }
+
+- if (ext_phy && dev->mt76.phy2)
+- mphy = dev->mt76.phy2;
++ if (ext_phy && dev->phy2)
++ mphy = dev->phy2;
+
+ if (inband_disc) {
+ p_fmt = MT_TX_TYPE_FW;
+@@ -1258,9 +1257,9 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
+ txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0;
+
+ if (is_8023)
+- mt7915_mac_write_txwi_8023(dev, txwi, skb, wcid);
++ mt7915_mac_write_txwi_8023(txwi, skb, wcid);
+ else
+- mt7915_mac_write_txwi_80211(dev, txwi, skb, key, &mcast);
++ mt7915_mac_write_txwi_80211(txwi, skb, key, &mcast);
+
+ if (txwi[2] & cpu_to_le32(MT_TXD2_FIX_RATE)) {
+ u16 rate = mt7915_mac_tx_rate_val(mphy, vif, beacon, mcast);
+@@ -1319,7 +1318,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ return id;
+
+ pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
+- mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key, 0);
++ mt7915_mac_write_txwi(mdev, txwi_ptr, tx_info->skb, wcid, pid, key, 0);
+
+ txp = (struct mt7915_txp *)(txwi + MT_TXD_SIZE);
+ for (i = 0; i < nbuf; i++) {
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+index 4bfb26e730eb..0ef3952bc33c 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -1910,7 +1910,7 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ }
+
+ buf = (u8 *)tlv + sizeof(*cont);
+- mt7915_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL,
++ mt7915_mac_write_txwi(&dev->mt76, (__le32 *)buf, skb, wcid, 0, NULL,
+ BSS_CHANGED_BEACON);
+ memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
+ }
+@@ -2049,7 +2049,7 @@ mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vi
+
+ buf = (u8 *)tlv + sizeof(*discov);
+
+- mt7915_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL,
++ mt7915_mac_write_txwi(&dev->mt76, (__le32 *)buf, skb, wcid, 0, NULL,
+ changed);
+ memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+index ff413fe1da5e..64b4c3c09d33 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+@@ -548,7 +548,7 @@ bool mt7915_mac_wtbl_update(struct mt7915_dev *dev, int idx, u32 mask);
+ void mt7915_mac_reset_counters(struct mt7915_phy *phy);
+ void mt7915_mac_cca_stats_reset(struct mt7915_phy *phy);
+ void mt7915_mac_enable_nf(struct mt7915_dev *dev, bool ext_phy);
+-void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
++void mt7915_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+ struct sk_buff *skb, struct mt76_wcid *wcid, int pid,
+ struct ieee80211_key_conf *key, u32 changed);
+ void mt7915_mac_set_timing(struct mt7915_phy *phy);
+--
+2.35.1
+
--- /dev/null
+From cb9d7e965884f88681508d5d4b131768d3fd8188 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Apr 2022 02:29:14 +0800
+Subject: mt76: mt7921: Add AP mode support
+
+From: Sean Wang <sean.wang@mediatek.com>
+
+[ Upstream commit 116c69603b01f2d6e4499ca5d535f5b71c52052c ]
+
+add AP mode support to mt7921 that can work for mt7921[e,s,u]
+with the common code.
+
+Tested-by: Deren Wu <deren.wu@mediatek.com>
+Tested-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt7921/init.c | 11 ++-
+ .../net/wireless/mediatek/mt76/mt7921/mac.c | 9 +++
+ .../net/wireless/mediatek/mt76/mt7921/main.c | 45 +++++++++++
+ .../net/wireless/mediatek/mt76/mt7921/mcu.c | 79 ++++++++++++++++++-
+ .../wireless/mediatek/mt76/mt7921/mt7921.h | 4 +
+ 5 files changed, 146 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+index 37453e1c136f..0a688c6545b3 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+@@ -11,6 +11,10 @@ static const struct ieee80211_iface_limit if_limits[] = {
+ {
+ .max = MT7921_MAX_INTERFACES,
+ .types = BIT(NL80211_IFTYPE_STATION)
++ },
++ {
++ .max = 1,
++ .types = BIT(NL80211_IFTYPE_AP)
+ }
+ };
+
+@@ -64,7 +68,8 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
+ wiphy->iface_combinations = if_comb;
+ wiphy->flags &= ~(WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_4ADDR_AP |
+ WIPHY_FLAG_4ADDR_STATION);
+- wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
++ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
++ BIT(NL80211_IFTYPE_AP);
+ wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
+ wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
+ wiphy->max_scan_ssids = 4;
+@@ -80,6 +85,10 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
+ wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
+ NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL);
++ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_LEGACY);
++ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT);
++ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);
++ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE);
+
+ ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
+ ieee80211_hw_set(hw, HAS_RATE_CONTROL);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index c5350e7a11e6..ac11e8b28f13 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -1363,12 +1363,21 @@ mt7921_vif_connect_iter(void *priv, u8 *mac,
+ {
+ struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
+ struct mt7921_dev *dev = mvif->phy->dev;
++ struct ieee80211_hw *hw = mt76_hw(dev);
+
+ if (vif->type == NL80211_IFTYPE_STATION)
+ ieee80211_disconnect(vif, true);
+
+ mt76_connac_mcu_uni_add_dev(&dev->mphy, vif, &mvif->sta.wcid, true);
+ mt7921_mcu_set_tx(dev, vif);
++
++ if (vif->type == NL80211_IFTYPE_AP) {
++ mt76_connac_mcu_uni_add_bss(dev->phy.mt76, vif, &mvif->sta.wcid,
++ true);
++ mt7921_mcu_sta_update(dev, NULL, vif, true,
++ MT76_STA_INFO_STATE_NONE);
++ mt7921_mcu_uni_add_beacon_offload(dev, hw, vif, true);
++ }
+ }
+
+ /* system error recovery */
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+index 9b9e80f56eda..d7e2bd605117 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+@@ -53,6 +53,7 @@ mt7921_init_he_caps(struct mt7921_phy *phy, enum nl80211_band band,
+
+ switch (i) {
+ case NL80211_IFTYPE_STATION:
++ case NL80211_IFTYPE_AP:
+ break;
+ default:
+ continue;
+@@ -86,6 +87,23 @@ mt7921_init_he_caps(struct mt7921_phy *phy, enum nl80211_band band,
+ IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO;
+
+ switch (i) {
++ case NL80211_IFTYPE_AP:
++ he_cap_elem->mac_cap_info[2] |=
++ IEEE80211_HE_MAC_CAP2_BSR;
++ he_cap_elem->mac_cap_info[4] |=
++ IEEE80211_HE_MAC_CAP4_BQR;
++ he_cap_elem->mac_cap_info[5] |=
++ IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX;
++ he_cap_elem->phy_cap_info[3] |=
++ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK |
++ IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_QPSK;
++ he_cap_elem->phy_cap_info[6] |=
++ IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE |
++ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
++ he_cap_elem->phy_cap_info[9] |=
++ IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |
++ IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU;
++ break;
+ case NL80211_IFTYPE_STATION:
+ he_cap_elem->mac_cap_info[1] |=
+ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US;
+@@ -635,6 +653,20 @@ static void mt7921_bss_info_changed(struct ieee80211_hw *hw,
+ }
+ }
+
++ if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) {
++ struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
++
++ mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid,
++ true);
++ mt7921_mcu_sta_update(dev, NULL, vif, true,
++ MT76_STA_INFO_STATE_NONE);
++ }
++
++ if (changed & (BSS_CHANGED_BEACON |
++ BSS_CHANGED_BEACON_ENABLED))
++ mt7921_mcu_uni_add_beacon_offload(dev, hw, vif,
++ info->enable_beacon);
++
+ /* ensure that enable txcmd_mode after bss_info */
+ if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED))
+ mt7921_mcu_set_tx(dev, vif);
+@@ -1395,6 +1427,18 @@ static int mt7921_set_sar_specs(struct ieee80211_hw *hw,
+ return err;
+ }
+
++static void
++mt7921_channel_switch_beacon(struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif,
++ struct cfg80211_chan_def *chandef)
++{
++ struct mt7921_dev *dev = mt7921_hw_dev(hw);
++
++ mt7921_mutex_acquire(dev);
++ mt7921_mcu_uni_add_beacon_offload(dev, hw, vif, true);
++ mt7921_mutex_release(dev);
++}
++
+ const struct ieee80211_ops mt7921_ops = {
+ .tx = mt7921_tx,
+ .start = mt7921_start,
+@@ -1413,6 +1457,7 @@ const struct ieee80211_ops mt7921_ops = {
+ .set_rts_threshold = mt7921_set_rts_threshold,
+ .wake_tx_queue = mt76_wake_tx_queue,
+ .release_buffered_frames = mt76_release_buffered_frames,
++ .channel_switch_beacon = mt7921_channel_switch_beacon,
+ .get_txpower = mt76_get_txpower,
+ .get_stats = mt7921_get_stats,
+ .get_et_sset_count = mt7921_get_et_sset_count,
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+index 2a609b25561c..b1ce15cea9e0 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+@@ -248,7 +248,8 @@ mt7921_mcu_connection_loss_iter(void *priv, u8 *mac,
+ if (mvif->idx != event->bss_idx)
+ return;
+
+- if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
++ if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER) ||
++ vif->type != NL80211_IFTYPE_STATION)
+ return;
+
+ ieee80211_connection_loss(vif);
+@@ -1167,3 +1168,79 @@ int mt7921_mcu_set_sniffer(struct mt7921_dev *dev, struct ieee80211_vif *vif,
+ return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(SNIFFER), &req, sizeof(req),
+ true);
+ }
++
++int
++mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev,
++ struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif,
++ bool enable)
++{
++ struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
++ struct mt76_wcid *wcid = &dev->mt76.global_wcid;
++ struct ieee80211_mutable_offsets offs;
++ struct {
++ struct req_hdr {
++ u8 bss_idx;
++ u8 pad[3];
++ } __packed hdr;
++ struct bcn_content_tlv {
++ __le16 tag;
++ __le16 len;
++ __le16 tim_ie_pos;
++ __le16 csa_ie_pos;
++ __le16 bcc_ie_pos;
++ /* 0: disable beacon offload
++ * 1: enable beacon offload
++ * 2: update probe respond offload
++ */
++ u8 enable;
++ /* 0: legacy format (TXD + payload)
++ * 1: only cap field IE
++ */
++ u8 type;
++ __le16 pkt_len;
++ u8 pkt[512];
++ } __packed beacon_tlv;
++ } req = {
++ .hdr = {
++ .bss_idx = mvif->mt76.idx,
++ },
++ .beacon_tlv = {
++ .tag = cpu_to_le16(UNI_BSS_INFO_BCN_CONTENT),
++ .len = cpu_to_le16(sizeof(struct bcn_content_tlv)),
++ .enable = enable,
++ },
++ };
++ struct sk_buff *skb;
++
++ if (!enable)
++ goto out;
++
++ skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs);
++ if (!skb)
++ return -EINVAL;
++
++ if (skb->len > 512 - MT_TXD_SIZE) {
++ dev_err(dev->mt76.dev, "beacon size limit exceed\n");
++ dev_kfree_skb(skb);
++ return -EINVAL;
++ }
++
++ mt7921_mac_write_txwi(dev, (__le32 *)(req.beacon_tlv.pkt), skb,
++ wcid, NULL, 0, true);
++ memcpy(req.beacon_tlv.pkt + MT_TXD_SIZE, skb->data, skb->len);
++ req.beacon_tlv.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
++ req.beacon_tlv.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset);
++
++ if (offs.cntdwn_counter_offs[0]) {
++ u16 csa_offs;
++
++ csa_offs = MT_TXD_SIZE + offs.cntdwn_counter_offs[0] - 4;
++ req.beacon_tlv.csa_ie_pos = cpu_to_le16(csa_offs);
++ }
++ dev_kfree_skb(skb);
++
++out:
++ return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
++ &req, sizeof(req), true);
++}
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+index 7690364bc079..d497a7e59a29 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+@@ -470,4 +470,8 @@ int mt7921u_wfsys_reset(struct mt7921_dev *dev);
+ int mt7921u_dma_init(struct mt7921_dev *dev);
+ int mt7921u_init_reset(struct mt7921_dev *dev);
+ int mt7921u_mac_reset(struct mt7921_dev *dev);
++int mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev,
++ struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif,
++ bool enable);
+ #endif
+--
+2.35.1
+
--- /dev/null
+From 8d3db3850d322622d9a0f320a2f81b135fe66f3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:07:08 +0200
+Subject: mt76: mt7921: do not update pm states in case of error
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit f4a92547fb9818ff272e1e2f0c79cd6b0bc99ce8 ]
+
+Do not update pm stats if mt7921e_mcu_fw_pmctrl routine returns an
+error.
+
+Fixes: 36873246f78a2 ("mt76: mt7921: add awake and doze time accounting")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c
+index 36669e5aeef3..a1ab5f878f81 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c
+@@ -102,7 +102,7 @@ int mt7921e_mcu_fw_pmctrl(struct mt7921_dev *dev)
+ {
+ struct mt76_phy *mphy = &dev->mt76.phy;
+ struct mt76_connac_pm *pm = &dev->pm;
+- int i, err = 0;
++ int i;
+
+ for (i = 0; i < MT7921_DRV_OWN_RETRY_COUNT; i++) {
+ mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_SET_OWN);
+@@ -114,12 +114,12 @@ int mt7921e_mcu_fw_pmctrl(struct mt7921_dev *dev)
+ if (i == MT7921_DRV_OWN_RETRY_COUNT) {
+ dev_err(dev->mt76.dev, "firmware own failed\n");
+ clear_bit(MT76_STATE_PM, &mphy->state);
+- err = -EIO;
++ return -EIO;
+ }
+
+ pm->stats.last_doze_event = jiffies;
+ pm->stats.awake_time += pm->stats.last_doze_event -
+ pm->stats.last_wake_event;
+
+- return err;
++ return 0;
+ }
+--
+2.35.1
+
--- /dev/null
+From 6984412a4d96614db0660640f46bc1b64f0630c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Jun 2022 18:56:44 +0800
+Subject: mt76: mt7921: enlarge maximum VHT MPDU length to 11454
+
+From: Deren Wu <deren.wu@mediatek.com>
+
+[ Upstream commit 31f3248a75932b111bc90c66b1f6c7d89eedca8e ]
+
+Enlarge maximum MPDU length to 11454 that both mt7921/mt7922 can support.
+After this fixing, we can get better performance.
+
+Fixes: 5c14a5f944b9 ("mt76: mt7921: introduce mt7921e support")
+Tested-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
+Signed-off-by: Deren Wu <deren.wu@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/init.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+index 2fb2a6295c06..37453e1c136f 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+@@ -291,7 +291,7 @@ int mt7921_register_device(struct mt7921_dev *dev)
+ IEEE80211_HT_CAP_LDPC_CODING |
+ IEEE80211_HT_CAP_MAX_AMSDU;
+ dev->mphy.sband_5g.sband.vht_cap.cap |=
+- IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
++ IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
+ IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |
+ IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
+ IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
+--
+2.35.1
+
--- /dev/null
+From cac9caadc4ee3b2a843032195f80e71397ecf198 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 23:57:43 +0800
+Subject: mt76: mt7921: fix aggregation subframes setting to HE max
+
+From: Deren Wu <deren.wu@mediatek.com>
+
+[ Upstream commit d5a50e6bd1972c481f82befa846dce0b9866f025 ]
+
+mt7921/mt7922 support HE max aggregation subframes 256 for both tx/rx.
+Get better throughput then before.
+
+Fixes: 94bb18b03d43 ("mt76: mt7921: fix max aggregation subframes setting")
+Tested-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
+Reviewed-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Deren Wu <deren.wu@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+index 91fc41922d95..2fb2a6295c06 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+@@ -49,8 +49,8 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
+ struct wiphy *wiphy = hw->wiphy;
+
+ hw->queues = 4;
+- hw->max_rx_aggregation_subframes = 64;
+- hw->max_tx_aggregation_subframes = 128;
++ hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
++ hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
+ hw->netdev_features = NETIF_F_RXCSUM;
+
+ hw->radiotap_timestamp.units_pos =
+--
+2.35.1
+
--- /dev/null
+From bdec8b3e32716c381149c169a100b932f420a779 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 11:28:37 +0200
+Subject: mt76: mt7921: rely on mt76_dev in mt7921_mac_write_txwi signature
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit e00b3e407efeed81dc30a72e4041ff57bf7068d5 ]
+
+This is a preliminary patch to share txwi configuration code.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/mediatek/mt76/mt7921/mac.c | 23 +++++++++----------
+ .../net/wireless/mediatek/mt76/mt7921/mcu.c | 2 +-
+ .../wireless/mediatek/mt76/mt7921/mt7921.h | 2 +-
+ .../wireless/mediatek/mt76/mt7921/pci_mac.c | 2 +-
+ 4 files changed, 14 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index ac11e8b28f13..3ae7989c8500 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -809,8 +809,8 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
+ }
+
+ static void
+-mt7921_mac_write_txwi_8023(struct mt7921_dev *dev, __le32 *txwi,
+- struct sk_buff *skb, struct mt76_wcid *wcid)
++mt7921_mac_write_txwi_8023(__le32 *txwi, struct sk_buff *skb,
++ struct mt76_wcid *wcid)
+ {
+ u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
+ u8 fc_type, fc_stype;
+@@ -848,7 +848,7 @@ mt7921_mac_write_txwi_8023(struct mt7921_dev *dev, __le32 *txwi,
+ }
+
+ static void
+-mt7921_mac_write_txwi_80211(struct mt7921_dev *dev, __le32 *txwi,
++mt7921_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi,
+ struct sk_buff *skb, struct ieee80211_key_conf *key)
+ {
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+@@ -920,7 +920,7 @@ mt7921_mac_write_txwi_80211(struct mt7921_dev *dev, __le32 *txwi,
+ txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU);
+ }
+
+- if (mt76_is_mmio(&dev->mt76)) {
++ if (mt76_is_mmio(dev)) {
+ val = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
+ FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype);
+ txwi[7] |= cpu_to_le32(val);
+@@ -931,17 +931,16 @@ mt7921_mac_write_txwi_80211(struct mt7921_dev *dev, __le32 *txwi,
+ }
+ }
+
+-void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi,
++void mt7921_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+ struct sk_buff *skb, struct mt76_wcid *wcid,
+ struct ieee80211_key_conf *key, int pid,
+ bool beacon)
+ {
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_vif *vif = info->control.vif;
+- struct mt76_phy *mphy = &dev->mphy;
++ struct mt76_phy *mphy = &dev->phy;
+ u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0;
+- bool is_mmio = mt76_is_mmio(&dev->mt76);
+- u32 sz_txd = is_mmio ? MT_TXD_SIZE : MT_SDIO_TXD_SIZE;
++ u32 sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE : MT_SDIO_TXD_SIZE;
+ bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
+ u16 tx_count = 15;
+ u32 val;
+@@ -957,10 +956,10 @@ void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi,
+ p_fmt = MT_TX_TYPE_FW;
+ q_idx = MT_LMAC_BCN0;
+ } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) {
+- p_fmt = is_mmio ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
++ p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
+ q_idx = MT_LMAC_ALTX0;
+ } else {
+- p_fmt = is_mmio ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
++ p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
+ q_idx = wmm_idx * MT7921_MAX_WMM_SETS +
+ mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
+ }
+@@ -995,7 +994,7 @@ void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi,
+ txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0;
+
+ if (is_8023)
+- mt7921_mac_write_txwi_8023(dev, txwi, skb, wcid);
++ mt7921_mac_write_txwi_8023(txwi, skb, wcid);
+ else
+ mt7921_mac_write_txwi_80211(dev, txwi, skb, key);
+
+@@ -1646,7 +1645,7 @@ mt7921_usb_sdio_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid,
+ __le32 *txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE);
+
+ memset(txwi, 0, MT_SDIO_TXD_SIZE);
+- mt7921_mac_write_txwi(dev, txwi, skb, wcid, key, pid, false);
++ mt7921_mac_write_txwi(&dev->mt76, txwi, skb, wcid, key, pid, false);
+ skb_push(skb, MT_SDIO_TXD_SIZE);
+ }
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+index b1ce15cea9e0..c2245be657d4 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+@@ -1226,7 +1226,7 @@ mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev,
+ return -EINVAL;
+ }
+
+- mt7921_mac_write_txwi(dev, (__le32 *)(req.beacon_tlv.pkt), skb,
++ mt7921_mac_write_txwi(&dev->mt76, (__le32 *)(req.beacon_tlv.pkt), skb,
+ wcid, NULL, 0, true);
+ memcpy(req.beacon_tlv.pkt + MT_TXD_SIZE, skb->data, skb->len);
+ req.beacon_tlv.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+index d497a7e59a29..a049bd35e0bc 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+@@ -421,7 +421,7 @@ int mt7921_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ void *data, int len);
+ int mt7921_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+ struct netlink_callback *cb, void *data, int len);
+-void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi,
++void mt7921_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
+ struct sk_buff *skb, struct mt76_wcid *wcid,
+ struct ieee80211_key_conf *key, int pid,
+ bool beacon);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c
+index 5ca14dbbdd26..f261cbfae2f3 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c
+@@ -72,7 +72,7 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ }
+
+ pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
+- mt7921_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, key,
++ mt7921_mac_write_txwi(mdev, txwi_ptr, tx_info->skb, wcid, key,
+ pid, false);
+
+ txp = (struct mt7921_txp_common *)(txwi + MT_TXD_SIZE);
+--
+2.35.1
+
--- /dev/null
+From c5f3d6a76dab81a98f45c14a864568a8993fdab8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 28 May 2022 09:28:54 +0800
+Subject: mt76: mt7921s: fix firmware download random fail
+
+From: YN Chen <yn.chen@mediatek.com>
+
+[ Upstream commit a55a0c701c129f8e448f0ec1eb811dba728ace64 ]
+
+To avoid racing problems in chip, mt7921s should reacquire drv-own after
+firmware semaphore is released.
+
+Fixes: 78b217580c509 ("mt76: mt7921s: fix bus hang with wrong privilege")
+Signed-off-by: YN Chen <yn.chen@mediatek.com>
+Signed-off-by: Deren Wu <deren.wu@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+index da2be050ed7c..2a609b25561c 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+@@ -538,13 +538,6 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
+ if (ret)
+ dev_err(dev->mt76.dev, "Failed to start patch\n");
+
+- if (mt76_is_sdio(&dev->mt76)) {
+- /* activate again */
+- ret = __mt7921_mcu_fw_pmctrl(dev);
+- if (!ret)
+- ret = __mt7921_mcu_drv_pmctrl(dev);
+- }
+-
+ out:
+ sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, false);
+ switch (sem) {
+@@ -555,6 +548,14 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
+ dev_err(dev->mt76.dev, "Failed to release patch semaphore\n");
+ break;
+ }
++
++ if (!ret && mt76_is_sdio(&dev->mt76)) {
++ /* activate again */
++ ret = __mt7921_mcu_fw_pmctrl(dev);
++ if (!ret)
++ ret = __mt7921_mcu_drv_pmctrl(dev);
++ }
++
+ release_firmware(fw);
+
+ return ret;
+--
+2.35.1
+
--- /dev/null
+From 287e4e7c2d12d67f321f7ce1a6bea7356f25b0e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jun 2022 15:50:24 +0800
+Subject: mt76: mt7921s: fix possible sdio deadlock in command fail
+
+From: Deren Wu <deren.wu@mediatek.com>
+
+[ Upstream commit 364718c94ac2ea4e51958ac0aa15c9092c785a3a ]
+
+Move sdio_release_host() to final resource handing
+
+Fixes: b12deb5e86fa ("mt76: mt7921s: fix mt7921s_mcu_[fw|drv]_pmctrl")
+Reported-by: YN Chen <YN.Chen@mediatek.com>
+Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Deren Wu <deren.wu@mediatek.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c
+index 54a5c712a3c3..c572a3107b8b 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c
+@@ -136,8 +136,8 @@ int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev)
+ struct sdio_func *func = dev->mt76.sdio.func;
+ struct mt76_phy *mphy = &dev->mt76.phy;
+ struct mt76_connac_pm *pm = &dev->pm;
+- int err = 0;
+ u32 status;
++ int err;
+
+ sdio_claim_host(func);
+
+@@ -148,7 +148,7 @@ int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev)
+ 2000, 1000000);
+ if (err < 0) {
+ dev_err(dev->mt76.dev, "mailbox ACK not cleared\n");
+- goto err;
++ goto out;
+ }
+ }
+
+@@ -156,18 +156,18 @@ int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev)
+
+ err = readx_poll_timeout(mt76s_read_pcr, &dev->mt76, status,
+ !(status & WHLPCR_IS_DRIVER_OWN), 2000, 1000000);
++out:
+ sdio_release_host(func);
+
+-err:
+ if (err < 0) {
+ dev_err(dev->mt76.dev, "firmware own failed\n");
+ clear_bit(MT76_STATE_PM, &mphy->state);
+- err = -EIO;
++ return -EIO;
+ }
+
+ pm->stats.last_doze_event = jiffies;
+ pm->stats.awake_time += pm->stats.last_doze_event -
+ pm->stats.last_wake_event;
+
+- return err;
++ return 0;
+ }
+--
+2.35.1
+
--- /dev/null
+From d740c9c731a99a6b977b194dfe50312c0d71051e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 16:23:13 +0100
+Subject: mtd: dataflash: Add SPI ID table
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit ac4f83482afbfd927d0fe118151b747cf175e724 ]
+
+Currently autoloading for SPI devices does not use the DT ID table, it uses
+SPI modalises. Supporting OF modalises is going to be difficult if not
+impractical, an attempt was made but has been reverted, so ensure that
+module autoloading works for this driver by adding an id_table listing the
+SPI IDs for everything.
+
+Fixes: 96c8395e2166 ("spi: Revert modalias changes")
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220620152313.708768-1-broonie@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/devices/mtd_dataflash.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
+index 134e27328597..25bad4318305 100644
+--- a/drivers/mtd/devices/mtd_dataflash.c
++++ b/drivers/mtd/devices/mtd_dataflash.c
+@@ -112,6 +112,13 @@ static const struct of_device_id dataflash_dt_ids[] = {
+ MODULE_DEVICE_TABLE(of, dataflash_dt_ids);
+ #endif
+
++static const struct spi_device_id dataflash_spi_ids[] = {
++ { .name = "at45", },
++ { .name = "dataflash", },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(spi, dataflash_spi_ids);
++
+ /* ......................................................................... */
+
+ /*
+@@ -936,6 +943,7 @@ static struct spi_driver dataflash_driver = {
+
+ .probe = dataflash_probe,
+ .remove = dataflash_remove,
++ .id_table = dataflash_spi_ids,
+
+ /* FIXME: investigate suspend and resume... */
+ };
+--
+2.35.1
+
--- /dev/null
+From a4ba741a3c7bd4a4311d076b0203d52893c9c295 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 11:26:51 +0200
+Subject: mtd: hyperbus: rpc-if: Fix RPM imbalance in probe error path
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit c223a38d62e57aa60a890ea7247e3c58a54478e6 ]
+
+If rpcif_hw_init() fails, Runtime PM is left enabled.
+
+Fixes: b04cc0d912eb80d3 ("memory: renesas-rpc-if: Add support for RZ/G2L")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/f3070e1af480cb252ae183d479a593dbbf947685.1655457790.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/hyperbus/rpc-if.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mtd/hyperbus/rpc-if.c b/drivers/mtd/hyperbus/rpc-if.c
+index 6e08ec1d4f09..b70d259e48a7 100644
+--- a/drivers/mtd/hyperbus/rpc-if.c
++++ b/drivers/mtd/hyperbus/rpc-if.c
+@@ -134,7 +134,7 @@ static int rpcif_hb_probe(struct platform_device *pdev)
+
+ error = rpcif_hw_init(&hyperbus->rpc, true);
+ if (error)
+- return error;
++ goto out_disable_rpm;
+
+ hyperbus->hbdev.map.size = hyperbus->rpc.size;
+ hyperbus->hbdev.map.virt = hyperbus->rpc.dirmap;
+@@ -145,8 +145,12 @@ static int rpcif_hb_probe(struct platform_device *pdev)
+ hyperbus->hbdev.np = of_get_next_child(pdev->dev.parent->of_node, NULL);
+ error = hyperbus_register_device(&hyperbus->hbdev);
+ if (error)
+- rpcif_disable_rpm(&hyperbus->rpc);
++ goto out_disable_rpm;
++
++ return 0;
+
++out_disable_rpm:
++ rpcif_disable_rpm(&hyperbus->rpc);
+ return error;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From d7429f815ee9edcb4c3ecdd9b1126fdab2a1b40b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 May 2022 18:32:55 +0400
+Subject: mtd: maps: Fix refcount leak in ap_flash_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 77087a04c8fd554134bddcb8a9ff87b21f357926 ]
+
+of_find_matching_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: b0afd44bc192 ("mtd: physmap_of: add a hook for Versatile write protection")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220523143255.4376-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/maps/physmap-versatile.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mtd/maps/physmap-versatile.c b/drivers/mtd/maps/physmap-versatile.c
+index 297a50957356..a1b8b7b25f88 100644
+--- a/drivers/mtd/maps/physmap-versatile.c
++++ b/drivers/mtd/maps/physmap-versatile.c
+@@ -93,6 +93,7 @@ static int ap_flash_init(struct platform_device *pdev)
+ return -ENODEV;
+ }
+ ebi_base = of_iomap(ebi, 0);
++ of_node_put(ebi);
+ if (!ebi_base)
+ return -ENODEV;
+
+--
+2.35.1
+
--- /dev/null
+From 5789a4d3497e242095bee2c058a8dc401e748d83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 May 2022 18:02:05 +0400
+Subject: mtd: maps: Fix refcount leak in of_flash_probe_versatile
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 33ec82a6d2b119938f26e5c8040ed5d92378eb54 ]
+
+of_find_matching_node_and_match() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: b0afd44bc192 ("mtd: physmap_of: add a hook for Versatile write protection")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220523140205.48625-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/maps/physmap-versatile.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mtd/maps/physmap-versatile.c b/drivers/mtd/maps/physmap-versatile.c
+index ad7cd9cfaee0..297a50957356 100644
+--- a/drivers/mtd/maps/physmap-versatile.c
++++ b/drivers/mtd/maps/physmap-versatile.c
+@@ -207,6 +207,7 @@ int of_flash_probe_versatile(struct platform_device *pdev,
+
+ versatile_flashprot = (enum versatile_flashprot)devid->data;
+ rmap = syscon_node_to_regmap(sysnp);
++ of_node_put(sysnp);
+ if (IS_ERR(rmap))
+ return PTR_ERR(rmap);
+
+--
+2.35.1
+
--- /dev/null
+From 7dcb0f620b5f18d4ea9e8c7e5ddb990000b06a3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jun 2022 11:07:23 +0400
+Subject: mtd: parsers: ofpart: Fix refcount leak in
+ bcm4908_partitions_fw_offset
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit e607879b0da18c451de5e91daf239cc2f2f8ff2d ]
+
+of_find_node_by_path() returns a node pointer with refcount incremented,
+we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: bb17230c61a6 ("mtd: parsers: ofpart: support BCM4908 fixed partitions")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220605070726.5979-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/parsers/ofpart_bcm4908.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/mtd/parsers/ofpart_bcm4908.c b/drivers/mtd/parsers/ofpart_bcm4908.c
+index 0eddef4c198e..bb072a0940e4 100644
+--- a/drivers/mtd/parsers/ofpart_bcm4908.c
++++ b/drivers/mtd/parsers/ofpart_bcm4908.c
+@@ -35,12 +35,15 @@ static long long bcm4908_partitions_fw_offset(void)
+ err = kstrtoul(s + len + 1, 0, &offset);
+ if (err) {
+ pr_err("failed to parse %s\n", s + len + 1);
++ of_node_put(root);
+ return err;
+ }
+
++ of_node_put(root);
+ return offset << 10;
+ }
+
++ of_node_put(root);
+ return -ENOENT;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 799c97267a3698f3a672d125928d8cad7503be05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 15:06:49 +0400
+Subject: mtd: partitions: Fix refcount leak in parse_redboot_of
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 9f7e62815cf3cbbcb1b8cb21649fb4dfdb3aa016 ]
+
+of_get_child_by_name() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 237960880960 ("mtd: partitions: redboot: seek fis-index-block in the right node")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220526110652.64849-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/parsers/redboot.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mtd/parsers/redboot.c b/drivers/mtd/parsers/redboot.c
+index feb44a573d44..a16b42a88581 100644
+--- a/drivers/mtd/parsers/redboot.c
++++ b/drivers/mtd/parsers/redboot.c
+@@ -58,6 +58,7 @@ static void parse_redboot_of(struct mtd_info *master)
+ return;
+
+ ret = of_property_read_u32(npart, "fis-index-block", &dirblock);
++ of_node_put(npart);
+ if (ret)
+ return;
+
+--
+2.35.1
+
--- /dev/null
+From 8085aa281b50be94dccabe6c3f417fd61062bed2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 May 2022 18:41:40 +0200
+Subject: mtd: rawnand: meson: Fix a potential double free issue
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit ec0da06337751b18f6dee06b6526e0f0d6e80369 ]
+
+When meson_nfc_nand_chip_cleanup() is called, it will call:
+ meson_nfc_free_buffer(&meson_chip->nand);
+ nand_cleanup(&meson_chip->nand);
+
+nand_cleanup() in turn will call nand_detach() which calls the
+.detach_chip() which is here meson_nand_detach_chip().
+
+meson_nand_detach_chip() already calls meson_nfc_free_buffer(), so we
+could double free some memory.
+
+Fix it by removing the unneeded explicit call to meson_nfc_free_buffer().
+
+Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: Liang Yang <liang.yang@amlogic.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/ec15c358b8063f7c50ff4cd628cf0d2e14e43f49.1653064877.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/raw/meson_nand.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
+index ac3be92872d0..032180183339 100644
+--- a/drivers/mtd/nand/raw/meson_nand.c
++++ b/drivers/mtd/nand/raw/meson_nand.c
+@@ -1307,7 +1307,6 @@ static int meson_nfc_nand_chip_cleanup(struct meson_nfc *nfc)
+ if (ret)
+ return ret;
+
+- meson_nfc_free_buffer(&meson_chip->nand);
+ nand_cleanup(&meson_chip->nand);
+ list_del(&meson_chip->node);
+ }
+--
+2.35.1
+
--- /dev/null
+From 15210b89a111d7e2eb6c9cc5ef26b86567aace4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 12:48:41 +0800
+Subject: mtd: sm_ftl: Fix deadlock caused by cancel_work_sync in sm_release
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ Upstream commit a61528d997619a518ee8c51cf0ef0513021afaff ]
+
+There is a deadlock between sm_release and sm_cache_flush_work
+which is a work item. The cancel_work_sync in sm_release will
+not return until sm_cache_flush_work is finished. If we hold
+mutex_lock and use cancel_work_sync to wait the work item to
+finish, the work item also requires mutex_lock. As a result,
+the sm_release will be blocked forever. The race condition is
+shown below:
+
+ (Thread 1) | (Thread 2)
+sm_release |
+ mutex_lock(&ftl->mutex) | sm_cache_flush_work
+ | mutex_lock(&ftl->mutex)
+ cancel_work_sync | ...
+
+This patch moves del_timer_sync and cancel_work_sync out of
+mutex_lock in order to mitigate deadlock.
+
+Fixes: 7d17c02a01a1 ("mtd: Add new SmartMedia/xD FTL")
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220524044841.10517-1-duoming@zju.edu.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/sm_ftl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c
+index 0cff2cda1b5a..7f955fade838 100644
+--- a/drivers/mtd/sm_ftl.c
++++ b/drivers/mtd/sm_ftl.c
+@@ -1111,9 +1111,9 @@ static void sm_release(struct mtd_blktrans_dev *dev)
+ {
+ struct sm_ftl *ftl = dev->priv;
+
+- mutex_lock(&ftl->mutex);
+ del_timer_sync(&ftl->timer);
+ cancel_work_sync(&ftl->flush_work);
++ mutex_lock(&ftl->mutex);
+ sm_cache_flush(ftl);
+ mutex_unlock(&ftl->mutex);
+ }
+--
+2.35.1
+
--- /dev/null
+From 9ffad62595e29931c1a654764abbc0ccd52709b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jun 2022 15:30:13 +0200
+Subject: mtd: spi-nor: fix spi_nor_spimem_setup_op() call in
+ spi_nor_erase_{sector,chip}()
+
+From: Patrice Chotard <patrice.chotard@foss.st.com>
+
+[ Upstream commit f8cd9f632f4415b1e8838bdca8ab42cfb37a6584 ]
+
+For erase operations, reg_proto must be used as indicated in
+struct spi_nor description in spi-nor.h.
+
+This issue was found when DT property spi-tx-bus-width is set to 4.
+In this case the spi_mem_op->addr.buswidth is set to 4 for erase command
+which is not correct.
+
+Tested on stm32mp157c-ev1 board with mx66l51235f spi-nor.
+
+Fixes: 0e30f47232ab ("mtd: spi-nor: add support for DTR protocol")
+Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
+[ta: use nor->reg_proto in spi_nor_controller_ops_erase()]
+Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
+Tested-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
+Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
+Link: https://lore.kernel.org/r/20220629133013.3382393-1-patrice.chotard@foss.st.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/spi-nor/core.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index c1630131c734..170182eb431e 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -177,7 +177,7 @@ int spi_nor_controller_ops_write_reg(struct spi_nor *nor, u8 opcode,
+
+ static int spi_nor_controller_ops_erase(struct spi_nor *nor, loff_t offs)
+ {
+- if (spi_nor_protocol_is_dtr(nor->write_proto))
++ if (spi_nor_protocol_is_dtr(nor->reg_proto))
+ return -EOPNOTSUPP;
+
+ return nor->controller_ops->erase(nor, offs);
+@@ -976,7 +976,7 @@ static int spi_nor_erase_chip(struct spi_nor *nor)
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_NO_DATA);
+
+- spi_nor_spimem_setup_op(nor, &op, nor->write_proto);
++ spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
+
+ ret = spi_mem_exec_op(nor->spimem, &op);
+ } else {
+@@ -1121,7 +1121,7 @@ int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_NO_DATA);
+
+- spi_nor_spimem_setup_op(nor, &op, nor->write_proto);
++ spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
+
+ return spi_mem_exec_op(nor->spimem, &op);
+ } else if (nor->controller_ops->erase) {
+--
+2.35.1
+
--- /dev/null
+From 30480ca8058542d7a0fe6e731675e8df73645403 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 17:24:55 +0200
+Subject: mtd: st_spi_fsm: Add a clk_disable_unprepare() in .probe()'s error
+ path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 28607b426c3d050714f250d0faeb99d2e9106e90 ]
+
+For all but one error path clk_disable_unprepare() is already there. Add
+it to the one location where it's missing.
+
+Fixes: 481815a6193b ("mtd: st_spi_fsm: Handle clk_prepare_enable/clk_disable_unprepare.")
+Fixes: 69d5af8d016c ("mtd: st_spi_fsm: Obtain and use EMI clock")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20220607152458.232847-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/devices/st_spi_fsm.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c
+index 983999c020d6..48bda2dd1bb5 100644
+--- a/drivers/mtd/devices/st_spi_fsm.c
++++ b/drivers/mtd/devices/st_spi_fsm.c
+@@ -2115,10 +2115,12 @@ static int stfsm_probe(struct platform_device *pdev)
+ (long long)fsm->mtd.size, (long long)(fsm->mtd.size >> 20),
+ fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10));
+
+- return mtd_device_register(&fsm->mtd, NULL, 0);
+-
++ ret = mtd_device_register(&fsm->mtd, NULL, 0);
++ if (ret) {
+ err_clk_unprepare:
+- clk_disable_unprepare(fsm->clk);
++ clk_disable_unprepare(fsm->clk);
++ }
++
+ return ret;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 0b835df9b3500571758ae421267e9c39f7a38d2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Jun 2022 11:26:26 +0800
+Subject: mwifiex: fix sleep in atomic context bugs caused by dev_coredumpv
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ Upstream commit a52ed4866d2b90dd5e4ae9dabd453f3ed8fa3cbc ]
+
+There are sleep in atomic context bugs when uploading device dump
+data in mwifiex. The root cause is that dev_coredumpv could not
+be used in atomic contexts, because it calls dev_set_name which
+include operations that may sleep. The call tree shows execution
+paths that could lead to bugs:
+
+ (Interrupt context)
+fw_dump_timer_fn
+ mwifiex_upload_device_dump
+ dev_coredumpv(..., GFP_KERNEL)
+ dev_coredumpm()
+ kzalloc(sizeof(*devcd), gfp); //may sleep
+ dev_set_name
+ kobject_set_name_vargs
+ kvasprintf_const(GFP_KERNEL, ...); //may sleep
+ kstrdup(s, GFP_KERNEL); //may sleep
+
+The corresponding fail log is shown below:
+
+[ 135.275938] usb 1-1: == mwifiex dump information to /sys/class/devcoredump start
+[ 135.281029] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:265
+...
+[ 135.293613] Call Trace:
+[ 135.293613] <IRQ>
+[ 135.293613] dump_stack_lvl+0x57/0x7d
+[ 135.293613] __might_resched.cold+0x138/0x173
+[ 135.293613] ? dev_coredumpm+0xca/0x2e0
+[ 135.293613] kmem_cache_alloc_trace+0x189/0x1f0
+[ 135.293613] ? devcd_match_failing+0x30/0x30
+[ 135.293613] dev_coredumpm+0xca/0x2e0
+[ 135.293613] ? devcd_freev+0x10/0x10
+[ 135.293613] dev_coredumpv+0x1c/0x20
+[ 135.293613] ? devcd_match_failing+0x30/0x30
+[ 135.293613] mwifiex_upload_device_dump+0x65/0xb0
+[ 135.293613] ? mwifiex_dnld_fw+0x1b0/0x1b0
+[ 135.293613] call_timer_fn+0x122/0x3d0
+[ 135.293613] ? msleep_interruptible+0xb0/0xb0
+[ 135.293613] ? lock_downgrade+0x3c0/0x3c0
+[ 135.293613] ? __next_timer_interrupt+0x13c/0x160
+[ 135.293613] ? lockdep_hardirqs_on_prepare+0xe/0x220
+[ 135.293613] ? mwifiex_dnld_fw+0x1b0/0x1b0
+[ 135.293613] __run_timers.part.0+0x3f8/0x540
+[ 135.293613] ? call_timer_fn+0x3d0/0x3d0
+[ 135.293613] ? arch_restore_msi_irqs+0x10/0x10
+[ 135.293613] ? lapic_next_event+0x31/0x40
+[ 135.293613] run_timer_softirq+0x4f/0xb0
+[ 135.293613] __do_softirq+0x1c2/0x651
+...
+[ 135.293613] RIP: 0010:default_idle+0xb/0x10
+[ 135.293613] RSP: 0018:ffff888006317e68 EFLAGS: 00000246
+[ 135.293613] RAX: ffffffff82ad8d10 RBX: ffff888006301cc0 RCX: ffffffff82ac90e1
+[ 135.293613] RDX: ffffed100d9ff1b4 RSI: ffffffff831ad140 RDI: ffffffff82ad8f20
+[ 135.293613] RBP: 0000000000000003 R08: 0000000000000000 R09: ffff88806cff8d9b
+[ 135.293613] R10: ffffed100d9ff1b3 R11: 0000000000000001 R12: ffffffff84593410
+[ 135.293613] R13: 0000000000000000 R14: 0000000000000000 R15: 1ffff11000c62fd2
+...
+[ 135.389205] usb 1-1: == mwifiex dump information to /sys/class/devcoredump end
+
+This patch uses delayed work to replace timer and moves the operations
+that may sleep into a delayed work in order to mitigate bugs, it was
+tested on Marvell 88W8801 chip whose port is usb and the firmware is
+usb8801_uapsta.bin. The following is the result after using delayed
+work to replace timer.
+
+[ 134.936453] usb 1-1: == mwifiex dump information to /sys/class/devcoredump start
+[ 135.043344] usb 1-1: == mwifiex dump information to /sys/class/devcoredump end
+
+As we can see, there is no bug now.
+
+Fixes: f5ecd02a8b20 ("mwifiex: device dump support for usb interface")
+Reviewed-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+Link: https://lore.kernel.org/r/b63b77fc84ed3e8a6bef02378e17c7c71a0bc3be.1654569290.git.duoming@zju.edu.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/init.c | 9 +++++----
+ drivers/net/wireless/marvell/mwifiex/main.h | 3 ++-
+ drivers/net/wireless/marvell/mwifiex/sta_event.c | 6 +++---
+ 3 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c
+index 88c72d1827a0..fca3ab948f6c 100644
+--- a/drivers/net/wireless/marvell/mwifiex/init.c
++++ b/drivers/net/wireless/marvell/mwifiex/init.c
+@@ -63,9 +63,10 @@ static void wakeup_timer_fn(struct timer_list *t)
+ adapter->if_ops.card_reset(adapter);
+ }
+
+-static void fw_dump_timer_fn(struct timer_list *t)
++static void fw_dump_work(struct work_struct *work)
+ {
+- struct mwifiex_adapter *adapter = from_timer(adapter, t, devdump_timer);
++ struct mwifiex_adapter *adapter =
++ container_of(work, struct mwifiex_adapter, devdump_work.work);
+
+ mwifiex_upload_device_dump(adapter);
+ }
+@@ -321,7 +322,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
+ adapter->active_scan_triggered = false;
+ timer_setup(&adapter->wakeup_timer, wakeup_timer_fn, 0);
+ adapter->devdump_len = 0;
+- timer_setup(&adapter->devdump_timer, fw_dump_timer_fn, 0);
++ INIT_DELAYED_WORK(&adapter->devdump_work, fw_dump_work);
+ }
+
+ /*
+@@ -400,7 +401,7 @@ static void
+ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
+ {
+ del_timer(&adapter->wakeup_timer);
+- del_timer_sync(&adapter->devdump_timer);
++ cancel_delayed_work_sync(&adapter->devdump_work);
+ mwifiex_cancel_all_pending_cmd(adapter);
+ wake_up_interruptible(&adapter->cmd_wait_q.wait);
+ wake_up_interruptible(&adapter->hs_activate_wait_q);
+diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
+index 332dd1c8db35..5d8646f16162 100644
+--- a/drivers/net/wireless/marvell/mwifiex/main.h
++++ b/drivers/net/wireless/marvell/mwifiex/main.h
+@@ -49,6 +49,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/slab.h>
+ #include <linux/of_irq.h>
++#include <linux/workqueue.h>
+
+ #include "decl.h"
+ #include "ioctl.h"
+@@ -1055,7 +1056,7 @@ struct mwifiex_adapter {
+ /* Device dump data/length */
+ void *devdump_data;
+ int devdump_len;
+- struct timer_list devdump_timer;
++ struct delayed_work devdump_work;
+
+ bool ignore_btcoex_events;
+ };
+diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
+index 7d42c5d2dbf6..4d93386494c5 100644
+--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
++++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
+@@ -623,8 +623,8 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv,
+ * transmission event get lost, in this cornel case,
+ * user would still get partial of the dump.
+ */
+- mod_timer(&adapter->devdump_timer,
+- jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
++ schedule_delayed_work(&adapter->devdump_work,
++ msecs_to_jiffies(MWIFIEX_TIMER_10S));
+ }
+
+ /* Overflow check */
+@@ -643,7 +643,7 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv,
+ return;
+
+ upload_dump:
+- del_timer_sync(&adapter->devdump_timer);
++ cancel_delayed_work_sync(&adapter->devdump_work);
+ mwifiex_upload_device_dump(adapter);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From cf4fd192e28a8b479a0b3364d98fa8ea3181714a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 09:55:11 +0900
+Subject: net: 9p: fix refcount leak in p9_read_work() error handling
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit 4ac7573e1f9333073fa8d303acc941c9b7ab7f61 ]
+
+p9_req_put need to be called when m->rreq->rc.sdata is NULL to avoid
+temporary refcount leak.
+
+Link: https://lkml.kernel.org/r/20220712104438.30800-1-hbh25y@gmail.com
+Fixes: 728356dedeff ("9p: Add refcount to p9_req_t")
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+[Dominique: commit wording adjustments, p9_req_put argument fixes for rebase]
+Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/9p/trans_fd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index 007c3f45fe05..e758978b44be 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -343,6 +343,7 @@ static void p9_read_work(struct work_struct *work)
+ p9_debug(P9_DEBUG_ERROR,
+ "No recv fcall for tag %d (req %p), disconnecting!\n",
+ m->rc.tag, m->rreq);
++ p9_req_put(m->client, m->rreq);
+ m->rreq = NULL;
+ err = -EIO;
+ goto error;
+--
+2.35.1
+
--- /dev/null
+From 87eec5336cc9e34a6a0553bab5869a938d5e3595 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 13:37:24 +0200
+Subject: net: ag71xx: fix discards 'const' qualifier warning
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+[ Upstream commit 225b0ed27e6ac523e5e98e7395392446859c7f20 ]
+
+Current kernel will compile this driver with warnings. This patch will
+fix it.
+
+drivers/net/ethernet/atheros/ag71xx.c: In function 'ag71xx_fast_reset':
+drivers/net/ethernet/atheros/ag71xx.c:996:31: warning: passing argument 2 of 'ag71xx_hw_set
+_macaddr' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
+ 996 | ag71xx_hw_set_macaddr(ag, dev->dev_addr);
+ | ~~~^~~~~~~~~~
+drivers/net/ethernet/atheros/ag71xx.c:951:69: note: expected 'unsigned char *' but argument
+ is of type 'const unsigned char *'
+ 951 | static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac)
+ | ~~~~~~~~~~~~~~~^~~
+drivers/net/ethernet/atheros/ag71xx.c: In function 'ag71xx_open':
+drivers/net/ethernet/atheros/ag71xx.c:1441:32: warning: passing argument 2 of 'ag71xx_hw_se
+t_macaddr' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
+ 1441 | ag71xx_hw_set_macaddr(ag, ndev->dev_addr);
+ | ~~~~^~~~~~~~~~
+drivers/net/ethernet/atheros/ag71xx.c:951:69: note: expected 'unsigned char *' but argument
+ is of type 'const unsigned char *'
+ 951 | static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac)
+ | ~~~~~~~~~~~~~~~^~~
+
+Fixes: adeef3e32146 ("net: constify netdev->dev_addr")
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/atheros/ag71xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/atheros/ag71xx.c b/drivers/net/ethernet/atheros/ag71xx.c
+index ec167af0e3b2..5041265f4226 100644
+--- a/drivers/net/ethernet/atheros/ag71xx.c
++++ b/drivers/net/ethernet/atheros/ag71xx.c
+@@ -946,7 +946,7 @@ static unsigned int ag71xx_max_frame_len(unsigned int mtu)
+ return ETH_HLEN + VLAN_HLEN + mtu + ETH_FCS_LEN;
+ }
+
+-static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac)
++static void ag71xx_hw_set_macaddr(struct ag71xx *ag, const unsigned char *mac)
+ {
+ u32 t;
+
+--
+2.35.1
+
--- /dev/null
+From 80714399fc2bb2ddaf6f3e7432551a62e431af4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 19:14:42 +0100
+Subject: net: allow unbound socket for packets in VRF when tcp_l3mdev_accept
+ set
+
+From: Mike Manning <mvrmanning@gmail.com>
+
+[ Upstream commit 944fd1aeacb627fa617f85f8e5a34f7ae8ea4d8e ]
+
+The commit 3c82a21f4320 ("net: allow binding socket in a VRF when
+there's an unbound socket") changed the inet socket lookup to avoid
+packets in a VRF from matching an unbound socket. This is to ensure the
+necessary isolation between the default and other VRFs for routing and
+forwarding. VRF-unaware processes running in the default VRF cannot
+access another VRF and have to be run with 'ip vrf exec <vrf>'. This is
+to be expected with tcp_l3mdev_accept disabled, but could be reallowed
+when this sysctl option is enabled. So instead of directly checking dif
+and sdif in inet[6]_match, here call inet_sk_bound_dev_eq(). This
+allows a match on unbound socket for non-zero sdif i.e. for packets in
+a VRF, if tcp_l3mdev_accept is enabled.
+
+Fixes: 3c82a21f4320 ("net: allow binding socket in a VRF when there's an unbound socket")
+Signed-off-by: Mike Manning <mvrmanning@gmail.com>
+Link: https://lore.kernel.org/netdev/a54c149aed38fded2d3b5fdb1a6c89e36a083b74.camel@lasnet.de/
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet6_hashtables.h | 7 +++----
+ include/net/inet_hashtables.h | 19 +++----------------
+ include/net/inet_sock.h | 11 +++++++++++
+ 3 files changed, 17 insertions(+), 20 deletions(-)
+
+diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
+index f259e1ae14ba..56f1286583d3 100644
+--- a/include/net/inet6_hashtables.h
++++ b/include/net/inet6_hashtables.h
+@@ -110,8 +110,6 @@ static inline bool inet6_match(struct net *net, const struct sock *sk,
+ const __portpair ports,
+ const int dif, const int sdif)
+ {
+- int bound_dev_if;
+-
+ if (!net_eq(sock_net(sk), net) ||
+ sk->sk_family != AF_INET6 ||
+ sk->sk_portpair != ports ||
+@@ -119,8 +117,9 @@ static inline bool inet6_match(struct net *net, const struct sock *sk,
+ !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))
+ return false;
+
+- bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+- return bound_dev_if == dif || bound_dev_if == sdif;
++ /* READ_ONCE() paired with WRITE_ONCE() in sock_bindtoindex_locked() */
++ return inet_sk_bound_dev_eq(net, READ_ONCE(sk->sk_bound_dev_if), dif,
++ sdif);
+ }
+ #endif /* IS_ENABLED(CONFIG_IPV6) */
+
+diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
+index 825ad1d06d05..53c22b64e972 100644
+--- a/include/net/inet_hashtables.h
++++ b/include/net/inet_hashtables.h
+@@ -203,17 +203,6 @@ static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo)
+ hashinfo->ehash_locks = NULL;
+ }
+
+-static inline bool inet_sk_bound_dev_eq(struct net *net, int bound_dev_if,
+- int dif, int sdif)
+-{
+-#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
+- return inet_bound_dev_eq(!!READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept),
+- bound_dev_if, dif, sdif);
+-#else
+- return inet_bound_dev_eq(true, bound_dev_if, dif, sdif);
+-#endif
+-}
+-
+ struct inet_bind_bucket *
+ inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net,
+ struct inet_bind_hashbucket *head,
+@@ -311,16 +300,14 @@ static inline bool INET_MATCH(struct net *net, const struct sock *sk,
+ const __addrpair cookie, const __portpair ports,
+ int dif, int sdif)
+ {
+- int bound_dev_if;
+-
+ if (!net_eq(sock_net(sk), net) ||
+ sk->sk_portpair != ports ||
+ sk->sk_addrpair != cookie)
+ return false;
+
+- /* Paired with WRITE_ONCE() from sock_bindtoindex_locked() */
+- bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+- return bound_dev_if == dif || bound_dev_if == sdif;
++ /* READ_ONCE() paired with WRITE_ONCE() in sock_bindtoindex_locked() */
++ return inet_sk_bound_dev_eq(net, READ_ONCE(sk->sk_bound_dev_if), dif,
++ sdif);
+ }
+
+ /* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so we need
+diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
+index 6395f6b9a5d2..bf5654ce711e 100644
+--- a/include/net/inet_sock.h
++++ b/include/net/inet_sock.h
+@@ -149,6 +149,17 @@ static inline bool inet_bound_dev_eq(bool l3mdev_accept, int bound_dev_if,
+ return bound_dev_if == dif || bound_dev_if == sdif;
+ }
+
++static inline bool inet_sk_bound_dev_eq(struct net *net, int bound_dev_if,
++ int dif, int sdif)
++{
++#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
++ return inet_bound_dev_eq(!!READ_ONCE(net->ipv4.sysctl_tcp_l3mdev_accept),
++ bound_dev_if, dif, sdif);
++#else
++ return inet_bound_dev_eq(true, bound_dev_if, dif, sdif);
++#endif
++}
++
+ struct inet_cork {
+ unsigned int flags;
+ __be32 addr;
+--
+2.35.1
+
--- /dev/null
+From eb669281cf68d0ae1a0c0e6d78c59a82e6c1ea33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Jul 2022 22:02:41 +0300
+Subject: net: dsa: felix: build as module when tc-taprio is module
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 10ed11ab6399813eb652137db9c378433c28a95c ]
+
+felix_vsc9959.c calls taprio_offload_get() and taprio_offload_free(),
+symbols exported by net/sched/sch_taprio.c. As such, we must disallow
+building the Felix driver as built-in when the symbol exported by
+tc-taprio isn't present in the kernel image.
+
+Fixes: 1c9017e44af2 ("net: dsa: felix: keep reference on entire tc-taprio config")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://lore.kernel.org/r/20220704190241.1288847-2-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/ocelot/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/dsa/ocelot/Kconfig b/drivers/net/dsa/ocelot/Kconfig
+index 220b0b027b55..08db9cf76818 100644
+--- a/drivers/net/dsa/ocelot/Kconfig
++++ b/drivers/net/dsa/ocelot/Kconfig
+@@ -6,6 +6,7 @@ config NET_DSA_MSCC_FELIX
+ depends on NET_VENDOR_FREESCALE
+ depends on HAS_IOMEM
+ depends on PTP_1588_CLOCK_OPTIONAL
++ depends on NET_SCH_TAPRIO || NET_SCH_TAPRIO=n
+ select MSCC_OCELOT_SWITCH_LIB
+ select NET_DSA_TAG_OCELOT_8021Q
+ select NET_DSA_TAG_OCELOT
+--
+2.35.1
+
--- /dev/null
+From 8f54a40d1ed899f62dc80ac98aeb8a43627a5394 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jun 2022 17:52:37 +0300
+Subject: net: dsa: felix: drop oversized frames with tc-taprio instead of
+ hanging the port
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 55a515b1f5a97df5704a1788fe97a4a740be2b9e ]
+
+Currently, sending a packet into a time gate too small for it (or always
+closed) causes the queue system to hold the frame forever. Even worse,
+this frame isn't subject to aging either, because for that to happen, it
+needs to be scheduled for transmission in the first place. But the frame
+will consume buffer memory and frame references while it is forever held
+in the queue system.
+
+Before commit a4ae997adcbd ("net: mscc: ocelot: initialize watermarks to
+sane defaults"), this behavior was somewhat subtle, as the switch had a
+more intricately tuned default watermark configuration out of reset,
+which did not allow any single port and tc to consume the entire switch
+buffer space. Nonetheless, the held frames are still there, and they
+reduce the total backplane capacity of the switch.
+
+However, after the aforementioned commit, the behavior can be very
+clearly seen, since we deliberately allow each {port, tc} to consume the
+entire shared buffer of the switch minus the reservations (and we
+disable all reservations by default). That is to say, we allow a
+permanently closed tc-taprio gate to hang the entire switch.
+
+A careful inspection of the documentation shows that the QSYS:Q_MAX_SDU
+per-port-tc registers serve 2 purposes: one is for guard band calculation
+(when zero, this falls back to QSYS:PORT_MAX_SDU), and the other is to
+enable oversized frame dropping (when non-zero).
+
+Currently the QSYS:Q_MAX_SDU registers are all zero, so oversized frame
+dropping is disabled. The goal of the change is to enable it seamlessly.
+For that, we need to hook into the MTU change, tc-taprio change, and
+port link speed change procedures, since we depend on these variables.
+
+Frames are not dropped on egress due to a queue system oversize
+condition, instead that egress port is simply excluded from the mask of
+valid destination ports for the packet. If there are no destination
+ports at all, the ingress counter that increments is the generic
+"drop_tail" in ethtool -S.
+
+The issue exists in various forms since the tc-taprio offload was introduced.
+
+Fixes: de143c0e274b ("net: dsa: felix: Configure Time-Aware Scheduler via taprio offload")
+Reported-by: Richie Pearn <richard.pearn@nxp.com>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/ocelot/felix.c | 9 ++
+ drivers/net/dsa/ocelot/felix.h | 1 +
+ drivers/net/dsa/ocelot/felix_vsc9959.c | 201 +++++++++++++++++++++++++
+ 3 files changed, 211 insertions(+)
+
+diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
+index faccfb3f0158..d95c2c0a64bd 100644
+--- a/drivers/net/dsa/ocelot/felix.c
++++ b/drivers/net/dsa/ocelot/felix.c
+@@ -1613,9 +1613,18 @@ static void felix_txtstamp(struct dsa_switch *ds, int port,
+ static int felix_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+ {
+ struct ocelot *ocelot = ds->priv;
++ struct ocelot_port *ocelot_port = ocelot->ports[port];
++ struct felix *felix = ocelot_to_felix(ocelot);
+
+ ocelot_port_set_maxlen(ocelot, port, new_mtu);
+
++ mutex_lock(&ocelot->tas_lock);
++
++ if (ocelot_port->taprio && felix->info->tas_guard_bands_update)
++ felix->info->tas_guard_bands_update(ocelot, port);
++
++ mutex_unlock(&ocelot->tas_lock);
++
+ return 0;
+ }
+
+diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h
+index f083b06fdfe9..b0e4635a8cc2 100644
+--- a/drivers/net/dsa/ocelot/felix.h
++++ b/drivers/net/dsa/ocelot/felix.h
+@@ -53,6 +53,7 @@ struct felix_info {
+ struct phylink_link_state *state);
+ int (*port_setup_tc)(struct dsa_switch *ds, int port,
+ enum tc_setup_type type, void *type_data);
++ void (*tas_guard_bands_update)(struct ocelot *ocelot, int port);
+ void (*port_sched_speed_set)(struct ocelot *ocelot, int port,
+ u32 speed);
+ struct regmap *(*init_regmap)(struct ocelot *ocelot,
+diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
+index 3d86f061802d..6bb5c5ef339b 100644
+--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
++++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
+@@ -1124,9 +1124,199 @@ static void vsc9959_mdio_bus_free(struct ocelot *ocelot)
+ mdiobus_free(felix->imdio);
+ }
+
++/* Extract shortest continuous gate open intervals in ns for each traffic class
++ * of a cyclic tc-taprio schedule. If a gate is always open, the duration is
++ * considered U64_MAX. If the gate is always closed, it is considered 0.
++ */
++static void vsc9959_tas_min_gate_lengths(struct tc_taprio_qopt_offload *taprio,
++ u64 min_gate_len[OCELOT_NUM_TC])
++{
++ struct tc_taprio_sched_entry *entry;
++ u64 gate_len[OCELOT_NUM_TC];
++ int tc, i, n;
++
++ /* Initialize arrays */
++ for (tc = 0; tc < OCELOT_NUM_TC; tc++) {
++ min_gate_len[tc] = U64_MAX;
++ gate_len[tc] = 0;
++ }
++
++ /* If we don't have taprio, consider all gates as permanently open */
++ if (!taprio)
++ return;
++
++ n = taprio->num_entries;
++
++ /* Walk through the gate list twice to determine the length
++ * of consecutively open gates for a traffic class, including
++ * open gates that wrap around. We are just interested in the
++ * minimum window size, and this doesn't change what the
++ * minimum is (if the gate never closes, min_gate_len will
++ * remain U64_MAX).
++ */
++ for (i = 0; i < 2 * n; i++) {
++ entry = &taprio->entries[i % n];
++
++ for (tc = 0; tc < OCELOT_NUM_TC; tc++) {
++ if (entry->gate_mask & BIT(tc)) {
++ gate_len[tc] += entry->interval;
++ } else {
++ /* Gate closes now, record a potential new
++ * minimum and reinitialize length
++ */
++ if (min_gate_len[tc] > gate_len[tc])
++ min_gate_len[tc] = gate_len[tc];
++ gate_len[tc] = 0;
++ }
++ }
++ }
++}
++
++/* Update QSYS_PORT_MAX_SDU to make sure the static guard bands added by the
++ * switch (see the ALWAYS_GUARD_BAND_SCH_Q comment) are correct at all MTU
++ * values (the default value is 1518). Also, for traffic class windows smaller
++ * than one MTU sized frame, update QSYS_QMAXSDU_CFG to enable oversized frame
++ * dropping, such that these won't hang the port, as they will never be sent.
++ */
++static void vsc9959_tas_guard_bands_update(struct ocelot *ocelot, int port)
++{
++ struct ocelot_port *ocelot_port = ocelot->ports[port];
++ u64 min_gate_len[OCELOT_NUM_TC];
++ int speed, picos_per_byte;
++ u64 needed_bit_time_ps;
++ u32 val, maxlen;
++ u8 tas_speed;
++ int tc;
++
++ lockdep_assert_held(&ocelot->tas_lock);
++
++ val = ocelot_read_rix(ocelot, QSYS_TAG_CONFIG, port);
++ tas_speed = QSYS_TAG_CONFIG_LINK_SPEED_X(val);
++
++ switch (tas_speed) {
++ case OCELOT_SPEED_10:
++ speed = SPEED_10;
++ break;
++ case OCELOT_SPEED_100:
++ speed = SPEED_100;
++ break;
++ case OCELOT_SPEED_1000:
++ speed = SPEED_1000;
++ break;
++ case OCELOT_SPEED_2500:
++ speed = SPEED_2500;
++ break;
++ default:
++ return;
++ }
++
++ picos_per_byte = (USEC_PER_SEC * 8) / speed;
++
++ val = ocelot_port_readl(ocelot_port, DEV_MAC_MAXLEN_CFG);
++ /* MAXLEN_CFG accounts automatically for VLAN. We need to include it
++ * manually in the bit time calculation, plus the preamble and SFD.
++ */
++ maxlen = val + 2 * VLAN_HLEN;
++ /* Consider the standard Ethernet overhead of 8 octets preamble+SFD,
++ * 4 octets FCS, 12 octets IFG.
++ */
++ needed_bit_time_ps = (maxlen + 24) * picos_per_byte;
++
++ dev_dbg(ocelot->dev,
++ "port %d: max frame size %d needs %llu ps at speed %d\n",
++ port, maxlen, needed_bit_time_ps, speed);
++
++ vsc9959_tas_min_gate_lengths(ocelot_port->taprio, min_gate_len);
++
++ for (tc = 0; tc < OCELOT_NUM_TC; tc++) {
++ u32 max_sdu;
++
++ if (min_gate_len[tc] == U64_MAX /* Gate always open */ ||
++ min_gate_len[tc] * 1000 > needed_bit_time_ps) {
++ /* Setting QMAXSDU_CFG to 0 disables oversized frame
++ * dropping.
++ */
++ max_sdu = 0;
++ dev_dbg(ocelot->dev,
++ "port %d tc %d min gate len %llu"
++ ", sending all frames\n",
++ port, tc, min_gate_len[tc]);
++ } else {
++ /* If traffic class doesn't support a full MTU sized
++ * frame, make sure to enable oversize frame dropping
++ * for frames larger than the smallest that would fit.
++ */
++ max_sdu = div_u64(min_gate_len[tc] * 1000,
++ picos_per_byte);
++ /* A TC gate may be completely closed, which is a
++ * special case where all packets are oversized.
++ * Any limit smaller than 64 octets accomplishes this
++ */
++ if (!max_sdu)
++ max_sdu = 1;
++ /* Take L1 overhead into account, but just don't allow
++ * max_sdu to go negative or to 0. Here we use 20
++ * because QSYS_MAXSDU_CFG_* already counts the 4 FCS
++ * octets as part of packet size.
++ */
++ if (max_sdu > 20)
++ max_sdu -= 20;
++ dev_info(ocelot->dev,
++ "port %d tc %d min gate length %llu"
++ " ns not enough for max frame size %d at %d"
++ " Mbps, dropping frames over %d"
++ " octets including FCS\n",
++ port, tc, min_gate_len[tc], maxlen, speed,
++ max_sdu);
++ }
++
++ /* ocelot_write_rix is a macro that concatenates
++ * QSYS_MAXSDU_CFG_* with _RSZ, so we need to spell out
++ * the writes to each traffic class
++ */
++ switch (tc) {
++ case 0:
++ ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_0,
++ port);
++ break;
++ case 1:
++ ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_1,
++ port);
++ break;
++ case 2:
++ ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_2,
++ port);
++ break;
++ case 3:
++ ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_3,
++ port);
++ break;
++ case 4:
++ ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_4,
++ port);
++ break;
++ case 5:
++ ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_5,
++ port);
++ break;
++ case 6:
++ ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_6,
++ port);
++ break;
++ case 7:
++ ocelot_write_rix(ocelot, max_sdu, QSYS_QMAXSDU_CFG_7,
++ port);
++ break;
++ }
++ }
++
++ ocelot_write_rix(ocelot, maxlen, QSYS_PORT_MAX_SDU, port);
++}
++
+ static void vsc9959_sched_speed_set(struct ocelot *ocelot, int port,
+ u32 speed)
+ {
++ struct ocelot_port *ocelot_port = ocelot->ports[port];
+ u8 tas_speed;
+
+ switch (speed) {
+@@ -1151,6 +1341,13 @@ static void vsc9959_sched_speed_set(struct ocelot *ocelot, int port,
+ QSYS_TAG_CONFIG_LINK_SPEED(tas_speed),
+ QSYS_TAG_CONFIG_LINK_SPEED_M,
+ QSYS_TAG_CONFIG, port);
++
++ mutex_lock(&ocelot->tas_lock);
++
++ if (ocelot_port->taprio)
++ vsc9959_tas_guard_bands_update(ocelot, port);
++
++ mutex_unlock(&ocelot->tas_lock);
+ }
+
+ static void vsc9959_new_base_time(struct ocelot *ocelot, ktime_t base_time,
+@@ -1210,6 +1407,8 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port,
+ taprio_offload_free(ocelot_port->taprio);
+ ocelot_port->taprio = NULL;
+
++ vsc9959_tas_guard_bands_update(ocelot, port);
++
+ mutex_unlock(&ocelot->tas_lock);
+ return 0;
+ }
+@@ -1284,6 +1483,7 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port,
+ goto err;
+
+ ocelot_port->taprio = taprio_offload_get(taprio);
++ vsc9959_tas_guard_bands_update(ocelot, port);
+
+ err:
+ mutex_unlock(&ocelot->tas_lock);
+@@ -2311,6 +2511,7 @@ static const struct felix_info felix_info_vsc9959 = {
+ .port_modes = vsc9959_port_modes,
+ .port_setup_tc = vsc9959_port_setup_tc,
+ .port_sched_speed_set = vsc9959_sched_speed_set,
++ .tas_guard_bands_update = vsc9959_tas_guard_bands_update,
+ .init_regmap = ocelot_regmap_init,
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 21dfabc3abcb15b4b46429907647228cf3319849 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jun 2022 17:52:35 +0300
+Subject: net: dsa: felix: keep reference on entire tc-taprio config
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 1c9017e44af2eee94b1001af18c401ae440ad77c ]
+
+In a future change we will need to remember the entire tc-taprio config
+on all ports rather than just the base time, so use the
+taprio_offload_get() helper function to replace ocelot_port->base_time
+with ocelot_port->taprio.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/ocelot/felix_vsc9959.c | 23 +++++++++++++----------
+ include/soc/mscc/ocelot.h | 5 ++---
+ 2 files changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
+index f21d9ff40af3..3d86f061802d 100644
+--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
++++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
+@@ -1207,6 +1207,9 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port,
+ QSYS_TAG_CONFIG_INIT_GATE_STATE_M,
+ QSYS_TAG_CONFIG, port);
+
++ taprio_offload_free(ocelot_port->taprio);
++ ocelot_port->taprio = NULL;
++
+ mutex_unlock(&ocelot->tas_lock);
+ return 0;
+ }
+@@ -1255,8 +1258,6 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port,
+ QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES_M,
+ QSYS_TAG_CONFIG, port);
+
+- ocelot_port->base_time = taprio->base_time;
+-
+ vsc9959_new_base_time(ocelot, taprio->base_time,
+ taprio->cycle_time, &base_ts);
+ ocelot_write(ocelot, base_ts.tv_nsec, QSYS_PARAM_CFG_REG_1);
+@@ -1279,6 +1280,10 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port,
+ ret = readx_poll_timeout(vsc9959_tas_read_cfg_status, ocelot, val,
+ !(val & QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE),
+ 10, 100000);
++ if (ret)
++ goto err;
++
++ ocelot_port->taprio = taprio_offload_get(taprio);
+
+ err:
+ mutex_unlock(&ocelot->tas_lock);
+@@ -1288,17 +1293,18 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port,
+
+ static void vsc9959_tas_clock_adjust(struct ocelot *ocelot)
+ {
++ struct tc_taprio_qopt_offload *taprio;
+ struct ocelot_port *ocelot_port;
+ struct timespec64 base_ts;
+- u64 cycletime;
+ int port;
+ u32 val;
+
+ mutex_lock(&ocelot->tas_lock);
+
+ for (port = 0; port < ocelot->num_phys_ports; port++) {
+- val = ocelot_read_rix(ocelot, QSYS_TAG_CONFIG, port);
+- if (!(val & QSYS_TAG_CONFIG_ENABLE))
++ ocelot_port = ocelot->ports[port];
++ taprio = ocelot_port->taprio;
++ if (!taprio)
+ continue;
+
+ ocelot_rmw(ocelot,
+@@ -1312,11 +1318,8 @@ static void vsc9959_tas_clock_adjust(struct ocelot *ocelot)
+ QSYS_TAG_CONFIG_INIT_GATE_STATE_M,
+ QSYS_TAG_CONFIG, port);
+
+- cycletime = ocelot_read(ocelot, QSYS_PARAM_CFG_REG_4);
+- ocelot_port = ocelot->ports[port];
+-
+- vsc9959_new_base_time(ocelot, ocelot_port->base_time,
+- cycletime, &base_ts);
++ vsc9959_new_base_time(ocelot, taprio->base_time,
++ taprio->cycle_time, &base_ts);
+
+ ocelot_write(ocelot, base_ts.tv_nsec, QSYS_PARAM_CFG_REG_1);
+ ocelot_write(ocelot, lower_32_bits(base_ts.tv_sec),
+diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
+index b944fc670c72..c90a9a2f77a9 100644
+--- a/include/soc/mscc/ocelot.h
++++ b/include/soc/mscc/ocelot.h
+@@ -659,6 +659,8 @@ struct ocelot_port {
+ /* VLAN that untagged frames are classified to, on ingress */
+ const struct ocelot_bridge_vlan *pvid_vlan;
+
++ struct tc_taprio_qopt_offload *taprio;
++
+ phy_interface_t phy_mode;
+
+ unsigned int ptp_skbs_in_flight;
+@@ -679,9 +681,6 @@ struct ocelot_port {
+ int bridge_num;
+
+ int speed;
+-
+- /* Store the AdminBaseTime of EST fetched from userspace. */
+- s64 base_time;
+ };
+
+ struct ocelot {
+--
+2.35.1
+
--- /dev/null
+From 89987f0b4b63be1ec2008d5c712d9ea601112952 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 11:24:23 +0800
+Subject: net: dsa: felix: update base time of time-aware shaper when adjusting
+ PTP time
+
+From: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
+
+[ Upstream commit 8670dc33f48bab4d7bb4b8d0232f17f4dae419ec ]
+
+When adjusting the PTP clock, the base time of the TAS configuration
+will become unreliable. We need reset the TAS configuration by using a
+new base time.
+
+For example, if the driver gets a base time 0 of Qbv configuration from
+user, and current time is 20000. The driver will set the TAS base time
+to be 20000. After the PTP clock adjustment, the current time becomes
+10000. If the TAS base time is still 20000, it will be a future time,
+and TAS entry list will stop running. Another example, if the current
+time becomes to be 10000000 after PTP clock adjust, a large time offset
+can cause the hardware to hang.
+
+This patch introduces a tas_clock_adjust() function to reset the TAS
+module by using a new base time after the PTP clock adjustment. This can
+avoid issues above.
+
+Due to PTP clock adjustment can occur at any time, it may conflict with
+the TAS configuration. We introduce a new TAS lock to serialize the
+access to the TAS registers.
+
+Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/ocelot/felix_vsc9959.c | 83 ++++++++++++++++++++++++--
+ drivers/net/ethernet/mscc/ocelot.c | 1 +
+ drivers/net/ethernet/mscc/ocelot_ptp.c | 8 +++
+ include/soc/mscc/ocelot.h | 7 +++
+ 4 files changed, 93 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
+index 4a071f96ea28..f21d9ff40af3 100644
+--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
++++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
+@@ -1193,10 +1193,13 @@ static void vsc9959_tas_gcl_set(struct ocelot *ocelot, const u32 gcl_ix,
+ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port,
+ struct tc_taprio_qopt_offload *taprio)
+ {
++ struct ocelot_port *ocelot_port = ocelot->ports[port];
+ struct timespec64 base_ts;
+ int ret, i;
+ u32 val;
+
++ mutex_lock(&ocelot->tas_lock);
++
+ if (!taprio->enable) {
+ ocelot_rmw_rix(ocelot,
+ QSYS_TAG_CONFIG_INIT_GATE_STATE(0xFF),
+@@ -1204,15 +1207,20 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port,
+ QSYS_TAG_CONFIG_INIT_GATE_STATE_M,
+ QSYS_TAG_CONFIG, port);
+
++ mutex_unlock(&ocelot->tas_lock);
+ return 0;
+ }
+
+ if (taprio->cycle_time > NSEC_PER_SEC ||
+- taprio->cycle_time_extension >= NSEC_PER_SEC)
+- return -EINVAL;
++ taprio->cycle_time_extension >= NSEC_PER_SEC) {
++ ret = -EINVAL;
++ goto err;
++ }
+
+- if (taprio->num_entries > VSC9959_TAS_GCL_ENTRY_MAX)
+- return -ERANGE;
++ if (taprio->num_entries > VSC9959_TAS_GCL_ENTRY_MAX) {
++ ret = -ERANGE;
++ goto err;
++ }
+
+ /* Enable guard band. The switch will schedule frames without taking
+ * their length into account. Thus we'll always need to enable the
+@@ -1233,8 +1241,10 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port,
+ * config is pending, need reset the TAS module
+ */
+ val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_8);
+- if (val & QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING)
+- return -EBUSY;
++ if (val & QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING) {
++ ret = -EBUSY;
++ goto err;
++ }
+
+ ocelot_rmw_rix(ocelot,
+ QSYS_TAG_CONFIG_ENABLE |
+@@ -1245,6 +1255,8 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port,
+ QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES_M,
+ QSYS_TAG_CONFIG, port);
+
++ ocelot_port->base_time = taprio->base_time;
++
+ vsc9959_new_base_time(ocelot, taprio->base_time,
+ taprio->cycle_time, &base_ts);
+ ocelot_write(ocelot, base_ts.tv_nsec, QSYS_PARAM_CFG_REG_1);
+@@ -1268,9 +1280,67 @@ static int vsc9959_qos_port_tas_set(struct ocelot *ocelot, int port,
+ !(val & QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE),
+ 10, 100000);
+
++err:
++ mutex_unlock(&ocelot->tas_lock);
++
+ return ret;
+ }
+
++static void vsc9959_tas_clock_adjust(struct ocelot *ocelot)
++{
++ struct ocelot_port *ocelot_port;
++ struct timespec64 base_ts;
++ u64 cycletime;
++ int port;
++ u32 val;
++
++ mutex_lock(&ocelot->tas_lock);
++
++ for (port = 0; port < ocelot->num_phys_ports; port++) {
++ val = ocelot_read_rix(ocelot, QSYS_TAG_CONFIG, port);
++ if (!(val & QSYS_TAG_CONFIG_ENABLE))
++ continue;
++
++ ocelot_rmw(ocelot,
++ QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM(port),
++ QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM_M,
++ QSYS_TAS_PARAM_CFG_CTRL);
++
++ ocelot_rmw_rix(ocelot,
++ QSYS_TAG_CONFIG_INIT_GATE_STATE(0xFF),
++ QSYS_TAG_CONFIG_ENABLE |
++ QSYS_TAG_CONFIG_INIT_GATE_STATE_M,
++ QSYS_TAG_CONFIG, port);
++
++ cycletime = ocelot_read(ocelot, QSYS_PARAM_CFG_REG_4);
++ ocelot_port = ocelot->ports[port];
++
++ vsc9959_new_base_time(ocelot, ocelot_port->base_time,
++ cycletime, &base_ts);
++
++ ocelot_write(ocelot, base_ts.tv_nsec, QSYS_PARAM_CFG_REG_1);
++ ocelot_write(ocelot, lower_32_bits(base_ts.tv_sec),
++ QSYS_PARAM_CFG_REG_2);
++ val = upper_32_bits(base_ts.tv_sec);
++ ocelot_rmw(ocelot,
++ QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB(val),
++ QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB_M,
++ QSYS_PARAM_CFG_REG_3);
++
++ ocelot_rmw(ocelot, QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE,
++ QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE,
++ QSYS_TAS_PARAM_CFG_CTRL);
++
++ ocelot_rmw_rix(ocelot,
++ QSYS_TAG_CONFIG_INIT_GATE_STATE(0xFF) |
++ QSYS_TAG_CONFIG_ENABLE,
++ QSYS_TAG_CONFIG_ENABLE |
++ QSYS_TAG_CONFIG_INIT_GATE_STATE_M,
++ QSYS_TAG_CONFIG, port);
++ }
++ mutex_unlock(&ocelot->tas_lock);
++}
++
+ static int vsc9959_qos_port_cbs_set(struct dsa_switch *ds, int port,
+ struct tc_cbs_qopt_offload *cbs_qopt)
+ {
+@@ -2210,6 +2280,7 @@ static const struct ocelot_ops vsc9959_ops = {
+ .psfp_filter_del = vsc9959_psfp_filter_del,
+ .psfp_stats_get = vsc9959_psfp_stats_get,
+ .cut_through_fwd = vsc9959_cut_through_fwd,
++ .tas_clock_adjust = vsc9959_tas_clock_adjust,
+ };
+
+ static const struct felix_info felix_info_vsc9959 = {
+diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
+index 20ceac81a2c2..497077726916 100644
+--- a/drivers/net/ethernet/mscc/ocelot.c
++++ b/drivers/net/ethernet/mscc/ocelot.c
+@@ -3245,6 +3245,7 @@ int ocelot_init(struct ocelot *ocelot)
+ mutex_init(&ocelot->ptp_lock);
+ mutex_init(&ocelot->mact_lock);
+ mutex_init(&ocelot->fwd_domain_lock);
++ mutex_init(&ocelot->tas_lock);
+ spin_lock_init(&ocelot->ptp_clock_lock);
+ spin_lock_init(&ocelot->ts_id_lock);
+ snprintf(queue_name, sizeof(queue_name), "%s-stats",
+diff --git a/drivers/net/ethernet/mscc/ocelot_ptp.c b/drivers/net/ethernet/mscc/ocelot_ptp.c
+index 87ad2137ba06..09c703efe946 100644
+--- a/drivers/net/ethernet/mscc/ocelot_ptp.c
++++ b/drivers/net/ethernet/mscc/ocelot_ptp.c
+@@ -72,6 +72,10 @@ int ocelot_ptp_settime64(struct ptp_clock_info *ptp,
+ ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
+
+ spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
++
++ if (ocelot->ops->tas_clock_adjust)
++ ocelot->ops->tas_clock_adjust(ocelot);
++
+ return 0;
+ }
+ EXPORT_SYMBOL(ocelot_ptp_settime64);
+@@ -105,6 +109,9 @@ int ocelot_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+ ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
+
+ spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
++
++ if (ocelot->ops->tas_clock_adjust)
++ ocelot->ops->tas_clock_adjust(ocelot);
+ } else {
+ /* Fall back using ocelot_ptp_settime64 which is not exact. */
+ struct timespec64 ts;
+@@ -117,6 +124,7 @@ int ocelot_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+
+ ocelot_ptp_settime64(ptp, &ts);
+ }
++
+ return 0;
+ }
+ EXPORT_SYMBOL(ocelot_ptp_adjtime);
+diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
+index bae2ddb06731..b944fc670c72 100644
+--- a/include/soc/mscc/ocelot.h
++++ b/include/soc/mscc/ocelot.h
+@@ -568,6 +568,7 @@ struct ocelot_ops {
+ int (*psfp_stats_get)(struct ocelot *ocelot, struct flow_cls_offload *f,
+ struct flow_stats *stats);
+ void (*cut_through_fwd)(struct ocelot *ocelot);
++ void (*tas_clock_adjust)(struct ocelot *ocelot);
+ };
+
+ struct ocelot_vcap_policer {
+@@ -678,6 +679,9 @@ struct ocelot_port {
+ int bridge_num;
+
+ int speed;
++
++ /* Store the AdminBaseTime of EST fetched from userspace. */
++ s64 base_time;
+ };
+
+ struct ocelot {
+@@ -744,6 +748,9 @@ struct ocelot {
+ /* Lock for serializing forwarding domain changes */
+ struct mutex fwd_domain_lock;
+
++ /* Lock for serializing Time-Aware Shaper changes */
++ struct mutex tas_lock;
++
+ struct workqueue_struct *owq;
+
+ u8 ptp:1;
+--
+2.35.1
+
--- /dev/null
+From 7ab1196475d65a5dcdb8aa4b105f21af705dfcff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 23:34:10 -0700
+Subject: net: fix sk_wmem_schedule() and sk_rmem_schedule() errors
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 7c80b038d23e1f4c7fcc311f43f83b8c60e7fb80 ]
+
+If sk->sk_forward_alloc is 150000, and we need to schedule 150001 bytes,
+we want to allocate 1 byte more (rounded up to one page),
+instead of 150001 :/
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Shakeel Butt <shakeelb@google.com>
+Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 9563a093fdfc..aab25d1806a9 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1557,19 +1557,23 @@ static inline bool sk_has_account(struct sock *sk)
+
+ static inline bool sk_wmem_schedule(struct sock *sk, int size)
+ {
++ int delta;
++
+ if (!sk_has_account(sk))
+ return true;
+- return size <= sk->sk_forward_alloc ||
+- __sk_mem_schedule(sk, size, SK_MEM_SEND);
++ delta = size - sk->sk_forward_alloc;
++ return delta <= 0 || __sk_mem_schedule(sk, delta, SK_MEM_SEND);
+ }
+
+ static inline bool
+ sk_rmem_schedule(struct sock *sk, struct sk_buff *skb, int size)
+ {
++ int delta;
++
+ if (!sk_has_account(sk))
+ return true;
+- return size <= sk->sk_forward_alloc ||
+- __sk_mem_schedule(sk, size, SK_MEM_RECV) ||
++ delta = size - sk->sk_forward_alloc;
++ return delta <= 0 || __sk_mem_schedule(sk, delta, SK_MEM_RECV) ||
+ skb_pfmemalloc(skb);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From d2c480b29c78afb414072603585f9631e1f0dd43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 19:22:23 +0800
+Subject: net: hinic: avoid kernel hung in hinic_get_stats64()
+
+From: Qiao Ma <mqaio@linux.alibaba.com>
+
+[ Upstream commit 98f9fcdee35add80505b6c73f72de5f750d5c03c ]
+
+When using hinic device as a bond slave device, and reading device stats
+of master bond device, the kernel may hung.
+
+The kernel panic calltrace as follows:
+Kernel panic - not syncing: softlockup: hung tasks
+Call trace:
+ native_queued_spin_lock_slowpath+0x1ec/0x31c
+ dev_get_stats+0x60/0xcc
+ dev_seq_printf_stats+0x40/0x120
+ dev_seq_show+0x1c/0x40
+ seq_read_iter+0x3c8/0x4dc
+ seq_read+0xe0/0x130
+ proc_reg_read+0xa8/0xe0
+ vfs_read+0xb0/0x1d4
+ ksys_read+0x70/0xfc
+ __arm64_sys_read+0x20/0x30
+ el0_svc_common+0x88/0x234
+ do_el0_svc+0x2c/0x90
+ el0_svc+0x1c/0x30
+ el0_sync_handler+0xa8/0xb0
+ el0_sync+0x148/0x180
+
+And the calltrace of task that actually caused kernel hungs as follows:
+ __switch_to+124
+ __schedule+548
+ schedule+72
+ schedule_timeout+348
+ __down_common+188
+ __down+24
+ down+104
+ hinic_get_stats64+44 [hinic]
+ dev_get_stats+92
+ bond_get_stats+172 [bonding]
+ dev_get_stats+92
+ dev_seq_printf_stats+60
+ dev_seq_show+24
+ seq_read_iter+964
+ seq_read+220
+ proc_reg_read+164
+ vfs_read+172
+ ksys_read+108
+ __arm64_sys_read+28
+ el0_svc_common+132
+ do_el0_svc+40
+ el0_svc+24
+ el0_sync_handler+164
+ el0_sync+324
+
+When getting device stats from bond, kernel will call bond_get_stats().
+It first holds the spinlock bond->stats_lock, and then call
+hinic_get_stats64() to collect hinic device's stats.
+However, hinic_get_stats64() calls `down(&nic_dev->mgmt_lock)` to
+protect its critical section, which may schedule current task out.
+And if system is under high pressure, the task cannot be woken up
+immediately, which eventually triggers kernel hung panic.
+
+Since previous patch has replaced hinic_dev.tx_stats/rx_stats with local
+variable in hinic_get_stats64(), there is nothing need to be protected
+by lock, so just removing down()/up() is ok.
+
+Fixes: edd384f682cc ("net-next/hinic: Add ethtool and stats")
+Signed-off-by: Qiao Ma <mqaio@linux.alibaba.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/huawei/hinic/hinic_main.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+index 89dc52510fdc..c23ee2ddbce3 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+@@ -842,13 +842,9 @@ static void hinic_get_stats64(struct net_device *netdev,
+ struct hinic_rxq_stats nic_rx_stats = {};
+ struct hinic_txq_stats nic_tx_stats = {};
+
+- down(&nic_dev->mgmt_lock);
+-
+ if (nic_dev->flags & HINIC_INTF_UP)
+ gather_nic_stats(nic_dev, &nic_rx_stats, &nic_tx_stats);
+
+- up(&nic_dev->mgmt_lock);
+-
+ stats->rx_bytes = nic_rx_stats.bytes;
+ stats->rx_packets = nic_rx_stats.pkts;
+ stats->rx_errors = nic_rx_stats.errors;
+--
+2.35.1
+
--- /dev/null
+From 57e7a0db16ae4d3a27271295c9b8a7f3207737c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 19:22:22 +0800
+Subject: net: hinic: fix bug that ethtool get wrong stats
+
+From: Qiao Ma <mqaio@linux.alibaba.com>
+
+[ Upstream commit 67dffd3db98570af8ff54c934f7d14664c0d182a ]
+
+Function hinic_get_stats64() will do two operations:
+1. reads stats from every hinic_rxq/txq and accumulates them
+2. calls hinic_rxq/txq_clean_stats() to clean every rxq/txq's stats
+
+For hinic_get_stats64(), it could get right data, because it sums all
+data to nic_dev->rx_stats/tx_stats.
+But it is wrong for get_drv_queue_stats(), this function will read
+hinic_rxq's stats, which have been cleared to zero by hinic_get_stats64().
+
+I have observed hinic's cleanup operation by using such command:
+> watch -n 1 "cat ethtool -S eth4 | tail -40"
+
+Result before:
+ ...
+ rxq7_pkts: 1
+ rxq7_bytes: 90
+ rxq7_errors: 0
+ rxq7_csum_errors: 0
+ rxq7_other_errors: 0
+ ...
+ rxq9_pkts: 11
+ rxq9_bytes: 726
+ rxq9_errors: 0
+ rxq9_csum_errors: 0
+ rxq9_other_errors: 0
+ ...
+ rxq11_pkts: 0
+ rxq11_bytes: 0
+ rxq11_errors: 0
+ rxq11_csum_errors: 0
+ rxq11_other_errors: 0
+
+Result after a few seconds:
+ ...
+ rxq7_pkts: 0
+ rxq7_bytes: 0
+ rxq7_errors: 0
+ rxq7_csum_errors: 0
+ rxq7_other_errors: 0
+ ...
+ rxq9_pkts: 2
+ rxq9_bytes: 132
+ rxq9_errors: 0
+ rxq9_csum_errors: 0
+ rxq9_other_errors: 0
+ ...
+ rxq11_pkts: 1
+ rxq11_bytes: 170
+ rxq11_errors: 0
+ rxq11_csum_errors: 0
+ rxq11_other_errors: 0
+
+To solve this problem, we just keep every queue's total stats in their own
+queue (aka hinic_{rxq|txq}), and simply sum all per-queue stats every time
+calling hinic_get_stats64().
+With that solution, there is no need to clean per-queue stats now,
+and there is no need to maintain global hinic_dev.{tx|rx}_stats, too.
+
+Fixes: edd384f682cc ("net-next/hinic: Add ethtool and stats")
+Signed-off-by: Qiao Ma <mqaio@linux.alibaba.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/huawei/hinic/hinic_dev.h | 3 -
+ .../net/ethernet/huawei/hinic/hinic_main.c | 57 ++++++-------------
+ drivers/net/ethernet/huawei/hinic/hinic_rx.c | 2 -
+ drivers/net/ethernet/huawei/hinic/hinic_tx.c | 2 -
+ 4 files changed, 16 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dev.h b/drivers/net/ethernet/huawei/hinic/hinic_dev.h
+index fb3e89141a0d..a4fbf44f944c 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_dev.h
++++ b/drivers/net/ethernet/huawei/hinic/hinic_dev.h
+@@ -95,9 +95,6 @@ struct hinic_dev {
+ u16 sq_depth;
+ u16 rq_depth;
+
+- struct hinic_txq_stats tx_stats;
+- struct hinic_rxq_stats rx_stats;
+-
+ u8 rss_tmpl_idx;
+ u8 rss_hash_engine;
+ u16 num_rss;
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+index 56a89793f47d..89dc52510fdc 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+@@ -80,56 +80,44 @@ static int set_features(struct hinic_dev *nic_dev,
+ netdev_features_t pre_features,
+ netdev_features_t features, bool force_change);
+
+-static void update_rx_stats(struct hinic_dev *nic_dev, struct hinic_rxq *rxq)
++static void gather_rx_stats(struct hinic_rxq_stats *nic_rx_stats, struct hinic_rxq *rxq)
+ {
+- struct hinic_rxq_stats *nic_rx_stats = &nic_dev->rx_stats;
+ struct hinic_rxq_stats rx_stats;
+
+- u64_stats_init(&rx_stats.syncp);
+-
+ hinic_rxq_get_stats(rxq, &rx_stats);
+
+- u64_stats_update_begin(&nic_rx_stats->syncp);
+ nic_rx_stats->bytes += rx_stats.bytes;
+ nic_rx_stats->pkts += rx_stats.pkts;
+ nic_rx_stats->errors += rx_stats.errors;
+ nic_rx_stats->csum_errors += rx_stats.csum_errors;
+ nic_rx_stats->other_errors += rx_stats.other_errors;
+- u64_stats_update_end(&nic_rx_stats->syncp);
+-
+- hinic_rxq_clean_stats(rxq);
+ }
+
+-static void update_tx_stats(struct hinic_dev *nic_dev, struct hinic_txq *txq)
++static void gather_tx_stats(struct hinic_txq_stats *nic_tx_stats, struct hinic_txq *txq)
+ {
+- struct hinic_txq_stats *nic_tx_stats = &nic_dev->tx_stats;
+ struct hinic_txq_stats tx_stats;
+
+- u64_stats_init(&tx_stats.syncp);
+-
+ hinic_txq_get_stats(txq, &tx_stats);
+
+- u64_stats_update_begin(&nic_tx_stats->syncp);
+ nic_tx_stats->bytes += tx_stats.bytes;
+ nic_tx_stats->pkts += tx_stats.pkts;
+ nic_tx_stats->tx_busy += tx_stats.tx_busy;
+ nic_tx_stats->tx_wake += tx_stats.tx_wake;
+ nic_tx_stats->tx_dropped += tx_stats.tx_dropped;
+ nic_tx_stats->big_frags_pkts += tx_stats.big_frags_pkts;
+- u64_stats_update_end(&nic_tx_stats->syncp);
+-
+- hinic_txq_clean_stats(txq);
+ }
+
+-static void update_nic_stats(struct hinic_dev *nic_dev)
++static void gather_nic_stats(struct hinic_dev *nic_dev,
++ struct hinic_rxq_stats *nic_rx_stats,
++ struct hinic_txq_stats *nic_tx_stats)
+ {
+ int i, num_qps = hinic_hwdev_num_qps(nic_dev->hwdev);
+
+ for (i = 0; i < num_qps; i++)
+- update_rx_stats(nic_dev, &nic_dev->rxqs[i]);
++ gather_rx_stats(nic_rx_stats, &nic_dev->rxqs[i]);
+
+ for (i = 0; i < num_qps; i++)
+- update_tx_stats(nic_dev, &nic_dev->txqs[i]);
++ gather_tx_stats(nic_tx_stats, &nic_dev->txqs[i]);
+ }
+
+ /**
+@@ -558,8 +546,6 @@ int hinic_close(struct net_device *netdev)
+ netif_carrier_off(netdev);
+ netif_tx_disable(netdev);
+
+- update_nic_stats(nic_dev);
+-
+ up(&nic_dev->mgmt_lock);
+
+ if (!HINIC_IS_VF(nic_dev->hwdev->hwif))
+@@ -853,26 +839,23 @@ static void hinic_get_stats64(struct net_device *netdev,
+ struct rtnl_link_stats64 *stats)
+ {
+ struct hinic_dev *nic_dev = netdev_priv(netdev);
+- struct hinic_rxq_stats *nic_rx_stats;
+- struct hinic_txq_stats *nic_tx_stats;
+-
+- nic_rx_stats = &nic_dev->rx_stats;
+- nic_tx_stats = &nic_dev->tx_stats;
++ struct hinic_rxq_stats nic_rx_stats = {};
++ struct hinic_txq_stats nic_tx_stats = {};
+
+ down(&nic_dev->mgmt_lock);
+
+ if (nic_dev->flags & HINIC_INTF_UP)
+- update_nic_stats(nic_dev);
++ gather_nic_stats(nic_dev, &nic_rx_stats, &nic_tx_stats);
+
+ up(&nic_dev->mgmt_lock);
+
+- stats->rx_bytes = nic_rx_stats->bytes;
+- stats->rx_packets = nic_rx_stats->pkts;
+- stats->rx_errors = nic_rx_stats->errors;
++ stats->rx_bytes = nic_rx_stats.bytes;
++ stats->rx_packets = nic_rx_stats.pkts;
++ stats->rx_errors = nic_rx_stats.errors;
+
+- stats->tx_bytes = nic_tx_stats->bytes;
+- stats->tx_packets = nic_tx_stats->pkts;
+- stats->tx_errors = nic_tx_stats->tx_dropped;
++ stats->tx_bytes = nic_tx_stats.bytes;
++ stats->tx_packets = nic_tx_stats.pkts;
++ stats->tx_errors = nic_tx_stats.tx_dropped;
+ }
+
+ static int hinic_set_features(struct net_device *netdev,
+@@ -1171,8 +1154,6 @@ static void hinic_free_intr_coalesce(struct hinic_dev *nic_dev)
+ static int nic_dev_init(struct pci_dev *pdev)
+ {
+ struct hinic_rx_mode_work *rx_mode_work;
+- struct hinic_txq_stats *tx_stats;
+- struct hinic_rxq_stats *rx_stats;
+ struct hinic_dev *nic_dev;
+ struct net_device *netdev;
+ struct hinic_hwdev *hwdev;
+@@ -1234,12 +1215,6 @@ static int nic_dev_init(struct pci_dev *pdev)
+
+ sema_init(&nic_dev->mgmt_lock, 1);
+
+- tx_stats = &nic_dev->tx_stats;
+- rx_stats = &nic_dev->rx_stats;
+-
+- u64_stats_init(&tx_stats->syncp);
+- u64_stats_init(&rx_stats->syncp);
+-
+ nic_dev->vlan_bitmap = devm_bitmap_zalloc(&pdev->dev, VLAN_N_VID,
+ GFP_KERNEL);
+ if (!nic_dev->vlan_bitmap) {
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_rx.c b/drivers/net/ethernet/huawei/hinic/hinic_rx.c
+index b33ed4d92b71..b6bce622a6a8 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c
+@@ -73,7 +73,6 @@ void hinic_rxq_get_stats(struct hinic_rxq *rxq, struct hinic_rxq_stats *stats)
+ struct hinic_rxq_stats *rxq_stats = &rxq->rxq_stats;
+ unsigned int start;
+
+- u64_stats_update_begin(&stats->syncp);
+ do {
+ start = u64_stats_fetch_begin(&rxq_stats->syncp);
+ stats->pkts = rxq_stats->pkts;
+@@ -83,7 +82,6 @@ void hinic_rxq_get_stats(struct hinic_rxq *rxq, struct hinic_rxq_stats *stats)
+ stats->csum_errors = rxq_stats->csum_errors;
+ stats->other_errors = rxq_stats->other_errors;
+ } while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
+- u64_stats_update_end(&stats->syncp);
+ }
+
+ /**
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_tx.c b/drivers/net/ethernet/huawei/hinic/hinic_tx.c
+index 8d59babbf476..082eb2a5088d 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_tx.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.c
+@@ -98,7 +98,6 @@ void hinic_txq_get_stats(struct hinic_txq *txq, struct hinic_txq_stats *stats)
+ struct hinic_txq_stats *txq_stats = &txq->txq_stats;
+ unsigned int start;
+
+- u64_stats_update_begin(&stats->syncp);
+ do {
+ start = u64_stats_fetch_begin(&txq_stats->syncp);
+ stats->pkts = txq_stats->pkts;
+@@ -108,7 +107,6 @@ void hinic_txq_get_stats(struct hinic_txq *txq, struct hinic_txq_stats *stats)
+ stats->tx_dropped = txq_stats->tx_dropped;
+ stats->big_frags_pkts = txq_stats->big_frags_pkts;
+ } while (u64_stats_fetch_retry(&txq_stats->syncp, start));
+- u64_stats_update_end(&stats->syncp);
+ }
+
+ /**
+--
+2.35.1
+
--- /dev/null
+From eeddf529e2929e2bb64315a91dd60167a55c2f6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Jul 2022 18:17:54 +0800
+Subject: net: ice: fix error NETIF_F_HW_VLAN_CTAG_FILTER check in
+ ice_vsi_sync_fltr()
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit 7dc839fe47611e6995f370cae37b9797cf7d2672 ]
+
+vsi->current_netdev_flags is used store the current net device
+flags, not the active netdevice features. So it should use
+vsi->netdev->featurs, rather than vsi->current_netdev_flags
+to check NETIF_F_HW_VLAN_CTAG_FILTER.
+
+Fixes: 1babaf77f49d ("ice: Advertise 802.1ad VLAN filtering and offloads for PF netdev")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
+Acked-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
+index 522462f41067..f48938af960c 100644
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -419,7 +419,7 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi)
+ IFF_PROMISC;
+ goto out_promisc;
+ }
+- if (vsi->current_netdev_flags &
++ if (vsi->netdev->features &
+ NETIF_F_HW_VLAN_CTAG_FILTER)
+ vlan_ops->ena_rx_filtering(vsi);
+ }
+--
+2.35.1
+
--- /dev/null
+From f68b83aea97b0ad8a4b27e4a69428646808ed9f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 14:13:11 +0200
+Subject: net/ice: fix initializing the bitmap in the switch code
+
+From: Alexander Lobakin <alexandr.lobakin@intel.com>
+
+[ Upstream commit 2f7ee2a72ccec8b85a05c4644d7ec9f40c1c50c8 ]
+
+Kbuild spotted the following bug during the testing of one of
+the optimizations:
+
+In file included from include/linux/cpumask.h:12,
+[...]
+ from drivers/net/ethernet/intel/ice/ice_switch.c:4:
+drivers/net/ethernet/intel/ice/ice_switch.c: In function 'ice_find_free_recp_res_idx.constprop':
+include/linux/bitmap.h:447:22: warning: 'possible_idx[0]' is used uninitialized [-Wuninitialized]
+ 447 | *map |= GENMASK(start + nbits - 1, start);
+ | ^~
+In file included from drivers/net/ethernet/intel/ice/ice.h:7,
+ from drivers/net/ethernet/intel/ice/ice_lib.h:7,
+ from drivers/net/ethernet/intel/ice/ice_switch.c:4:
+drivers/net/ethernet/intel/ice/ice_switch.c:4929:24: note: 'possible_idx[0]' was declared here
+ 4929 | DECLARE_BITMAP(possible_idx, ICE_MAX_FV_WORDS);
+ | ^~~~~~~~~~~~
+include/linux/types.h:11:23: note: in definition of macro 'DECLARE_BITMAP'
+ 11 | unsigned long name[BITS_TO_LONGS(bits)]
+ | ^~~~
+
+%ICE_MAX_FV_WORDS is 48, so bitmap_set() here was initializing only
+48 bits, leaving a junk in the rest 16.
+It was previously hidden due to that filling 48 bits makes
+bitmap_set() call external __bitmap_set(), but after making it use
+plain bit arithmetics on small bitmaps, compilers started seeing
+the issue. It was still working because those 16 weren't used
+anywhere anyhow.
+bitmap_{clear,set}() are not really intended to initialize bitmaps,
+rather to modify already initialized ones, as they don't do anything
+past the passed number of bits. The correct function to do this in
+that particular case is bitmap_fill(), so use it here. It will do
+`*possible_idx = ~0UL` instead of `*possible_idx |= GENMASK(47, 0)`,
+not leaving anything in an undefined state.
+
+Fixes: fd2a6b71e300 ("ice: create advanced switch recipe")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Alexander Lobakin <alexandr.lobakin@intel.com>
+Signed-off-by: Yury Norov <yury.norov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_switch.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c
+index 25b8f6f726eb..73960c8f9dba 100644
+--- a/drivers/net/ethernet/intel/ice/ice_switch.c
++++ b/drivers/net/ethernet/intel/ice/ice_switch.c
+@@ -4874,7 +4874,7 @@ ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles,
+ bitmap_zero(recipes, ICE_MAX_NUM_RECIPES);
+ bitmap_zero(used_idx, ICE_MAX_FV_WORDS);
+
+- bitmap_set(possible_idx, 0, ICE_MAX_FV_WORDS);
++ bitmap_fill(possible_idx, ICE_MAX_FV_WORDS);
+
+ /* For each profile we are going to associate the recipe with, add the
+ * recipes that are associated with that profile. This will give us
+--
+2.35.1
+
--- /dev/null
+From 80cd06a2f6a76983418458f7c79569fca1ccc974 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Jul 2022 18:17:55 +0800
+Subject: net: ionic: fix error check for vlan flags in
+ ionic_set_nic_features()
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit a86e86db5e6d72c82724a63ca1c5293409a21518 ]
+
+The prototype of input features of ionic_set_nic_features() is
+netdev_features_t, but the vlan_flags is using the private
+definition of ionic drivers. It should use the variable
+ctx.cmd.lif_setattr.features, rather than features to check
+the vlan flags. So fixes it.
+
+Fixes: beead698b173 ("ionic: Add the basic NDO callbacks for netdev support")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
+Acked-by: Shannon Nelson <snelson@pensando.io>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/pensando/ionic/ionic_lif.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+index f3568901eb91..1443f788ee37 100644
+--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
++++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+@@ -1437,7 +1437,7 @@ static int ionic_set_nic_features(struct ionic_lif *lif,
+ if ((old_hw_features ^ lif->hw_features) & IONIC_ETH_HW_RX_HASH)
+ ionic_lif_rss_config(lif, lif->rss_types, NULL, NULL);
+
+- if ((vlan_flags & features) &&
++ if ((vlan_flags & le64_to_cpu(ctx.cmd.lif_setattr.features)) &&
+ !(vlan_flags & le64_to_cpu(ctx.comp.lif_setattr.features)))
+ dev_info_once(lif->ionic->dev, "NIC is not supporting vlan offload, likely in SmartNIC mode\n");
+
+--
+2.35.1
+
--- /dev/null
+From 1333cd8fa46262f51cc6305df0d80184f6e403c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Jul 2022 11:28:21 +0300
+Subject: net/mlx5: Adjust log_max_qp to be 18 at most
+
+From: Maher Sanalla <msanalla@nvidia.com>
+
+[ Upstream commit a6e9085d791f8306084fd5bc44dd3fdd4e1ac27b ]
+
+The cited commit limited log_max_qp to be 17 due to FW capabilities.
+Recently, it turned out that there are old FW versions that supported
+more than 17, so the cited commit caused a degradation.
+
+Thus, set the maximum log_max_qp back to 18 as it was before the
+cited commit.
+
+Fixes: 7f839965b2d7 ("net/mlx5: Update log_max_qp value to be 17 at most")
+Signed-off-by: Maher Sanalla <msanalla@nvidia.com>
+Reviewed-by: Maor Gottlieb <maorg@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index 8b5263699994..ffb0bb4ecdef 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -526,7 +526,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
+
+ /* Check log_max_qp from HCA caps to set in current profile */
+ if (prof->log_max_qp == LOG_MAX_SUPPORTED_QPS) {
+- prof->log_max_qp = min_t(u8, 17, MLX5_CAP_GEN_MAX(dev, log_max_qp));
++ prof->log_max_qp = min_t(u8, 18, MLX5_CAP_GEN_MAX(dev, log_max_qp));
+ } else if (MLX5_CAP_GEN_MAX(dev, log_max_qp) < prof->log_max_qp) {
+ mlx5_core_warn(dev, "log_max_qp value in current profile is %d, changing it to HCA capability limit (%d)\n",
+ prof->log_max_qp,
+--
+2.35.1
+
--- /dev/null
+From cb8bc2b5f44ccea4366da67aff0bbe3ead51a710 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 00:06:12 +0300
+Subject: net/mlx5: DR, Fix SMFS steering info dump format
+
+From: Yevgeny Kliteynik <kliteyn@nvidia.com>
+
+[ Upstream commit 62d2664351ef37da34f6f3a3fd8ab34257d6fe30 ]
+
+Fix several issues in SMFS steering info dump:
+ - Fix outdated macro value for matcher mask in the SMFS debug dump format.
+ The existing value denotes the old format of the matcher mask, as it was
+ used during the early stages of development, and it results in wrong
+ parsing by the steering dump parser - wrong fields are shown in the
+ parsed output.
+ - Add the missing destination table to the dumped action.
+ The missing dest table handle breaks the ability to associate between
+ the "go to table" action and the actual table in the steering info.
+
+Fixes: 9222f0b27da2 ("net/mlx5: DR, Add support for dumping steering info")
+Signed-off-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
+Signed-off-by: Muhammad Sammar <muhammads@nvidia.com>
+Reviewed-by: Alex Vesker <valex@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlx5/core/steering/dr_dbg.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_dbg.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_dbg.c
+index d5998ef59be4..7adcf0eec13b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_dbg.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_dbg.c
+@@ -21,10 +21,11 @@ enum dr_dump_rec_type {
+ DR_DUMP_REC_TYPE_TABLE_TX = 3102,
+
+ DR_DUMP_REC_TYPE_MATCHER = 3200,
+- DR_DUMP_REC_TYPE_MATCHER_MASK = 3201,
++ DR_DUMP_REC_TYPE_MATCHER_MASK_DEPRECATED = 3201,
+ DR_DUMP_REC_TYPE_MATCHER_RX = 3202,
+ DR_DUMP_REC_TYPE_MATCHER_TX = 3203,
+ DR_DUMP_REC_TYPE_MATCHER_BUILDER = 3204,
++ DR_DUMP_REC_TYPE_MATCHER_MASK = 3205,
+
+ DR_DUMP_REC_TYPE_RULE = 3300,
+ DR_DUMP_REC_TYPE_RULE_RX_ENTRY_V0 = 3301,
+@@ -114,13 +115,15 @@ dr_dump_rule_action_mem(struct seq_file *file, const u64 rule_id,
+ break;
+ case DR_ACTION_TYP_FT:
+ if (action->dest_tbl->is_fw_tbl)
+- seq_printf(file, "%d,0x%llx,0x%llx,0x%x\n",
++ seq_printf(file, "%d,0x%llx,0x%llx,0x%x,0x%x\n",
+ DR_DUMP_REC_TYPE_ACTION_FT, action_id,
+- rule_id, action->dest_tbl->fw_tbl.id);
++ rule_id, action->dest_tbl->fw_tbl.id,
++ -1);
+ else
+- seq_printf(file, "%d,0x%llx,0x%llx,0x%x\n",
++ seq_printf(file, "%d,0x%llx,0x%llx,0x%x,0x%llx\n",
+ DR_DUMP_REC_TYPE_ACTION_FT, action_id,
+- rule_id, action->dest_tbl->tbl->table_id);
++ rule_id, action->dest_tbl->tbl->table_id,
++ DR_DBG_PTR_TO_ID(action->dest_tbl->tbl));
+
+ break;
+ case DR_ACTION_TYP_CTR:
+--
+2.35.1
+
--- /dev/null
+From e6756a0570d634ed28b059a6f8f9a27efd88b43f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 May 2022 12:02:03 +0300
+Subject: net/mlx5: Expose mlx5_sriov_blocking_notifier_register / unregister
+ APIs
+
+From: Yishai Hadas <yishaih@nvidia.com>
+
+[ Upstream commit 846e437387e74c44ddc9f3eeec472fd37ca3cdb9 ]
+
+Expose mlx5_sriov_blocking_notifier_register / unregister APIs to let a
+VF register to be notified for its enablement / disablement by the PF.
+
+Upon VF probe it will call mlx5_sriov_blocking_notifier_register() with
+its notifier block and upon VF remove it will call
+mlx5_sriov_blocking_notifier_unregister() to drop its registration.
+
+This can give a VF the ability to clean some resources upon disable
+before that the command interface goes down and on the other hand sets
+some stuff before that it's enabled.
+
+This may be used by a VF which is migration capable in few cases.(e.g.
+PF load/unload upon an health recovery).
+
+Link: https://lore.kernel.org/r/20220510090206.90374-2-yishaih@nvidia.com
+Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/sriov.c | 65 ++++++++++++++++++-
+ include/linux/mlx5/driver.h | 12 ++++
+ 2 files changed, 76 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
+index 887ee0f729d1..2935614f6fa9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
+@@ -87,6 +87,11 @@ static int mlx5_device_enable_sriov(struct mlx5_core_dev *dev, int num_vfs)
+ enable_vfs_hca:
+ num_msix_count = mlx5_get_default_msix_vec_count(dev, num_vfs);
+ for (vf = 0; vf < num_vfs; vf++) {
++ /* Notify the VF before its enablement to let it set
++ * some stuff.
++ */
++ blocking_notifier_call_chain(&sriov->vfs_ctx[vf].notifier,
++ MLX5_PF_NOTIFY_ENABLE_VF, dev);
+ err = mlx5_core_enable_hca(dev, vf + 1);
+ if (err) {
+ mlx5_core_warn(dev, "failed to enable VF %d (%d)\n", vf, err);
+@@ -127,6 +132,11 @@ mlx5_device_disable_sriov(struct mlx5_core_dev *dev, int num_vfs, bool clear_vf)
+ for (vf = num_vfs - 1; vf >= 0; vf--) {
+ if (!sriov->vfs_ctx[vf].enabled)
+ continue;
++ /* Notify the VF before its disablement to let it clean
++ * some resources.
++ */
++ blocking_notifier_call_chain(&sriov->vfs_ctx[vf].notifier,
++ MLX5_PF_NOTIFY_DISABLE_VF, dev);
+ err = mlx5_core_disable_hca(dev, vf + 1);
+ if (err) {
+ mlx5_core_warn(dev, "failed to disable VF %d\n", vf);
+@@ -257,7 +267,7 @@ int mlx5_sriov_init(struct mlx5_core_dev *dev)
+ {
+ struct mlx5_core_sriov *sriov = &dev->priv.sriov;
+ struct pci_dev *pdev = dev->pdev;
+- int total_vfs;
++ int total_vfs, i;
+
+ if (!mlx5_core_is_pf(dev))
+ return 0;
+@@ -269,6 +279,9 @@ int mlx5_sriov_init(struct mlx5_core_dev *dev)
+ if (!sriov->vfs_ctx)
+ return -ENOMEM;
+
++ for (i = 0; i < total_vfs; i++)
++ BLOCKING_INIT_NOTIFIER_HEAD(&sriov->vfs_ctx[i].notifier);
++
+ return 0;
+ }
+
+@@ -281,3 +294,53 @@ void mlx5_sriov_cleanup(struct mlx5_core_dev *dev)
+
+ kfree(sriov->vfs_ctx);
+ }
++
++/**
++ * mlx5_sriov_blocking_notifier_unregister - Unregister a VF from
++ * a notification block chain.
++ *
++ * @mdev: The mlx5 core device.
++ * @vf_id: The VF id.
++ * @nb: The notifier block to be unregistered.
++ */
++void mlx5_sriov_blocking_notifier_unregister(struct mlx5_core_dev *mdev,
++ int vf_id,
++ struct notifier_block *nb)
++{
++ struct mlx5_vf_context *vfs_ctx;
++ struct mlx5_core_sriov *sriov;
++
++ sriov = &mdev->priv.sriov;
++ if (WARN_ON(vf_id < 0 || vf_id >= sriov->num_vfs))
++ return;
++
++ vfs_ctx = &sriov->vfs_ctx[vf_id];
++ blocking_notifier_chain_unregister(&vfs_ctx->notifier, nb);
++}
++EXPORT_SYMBOL(mlx5_sriov_blocking_notifier_unregister);
++
++/**
++ * mlx5_sriov_blocking_notifier_register - Register a VF notification
++ * block chain.
++ *
++ * @mdev: The mlx5 core device.
++ * @vf_id: The VF id.
++ * @nb: The notifier block to be called upon the VF events.
++ *
++ * Returns 0 on success or an error code.
++ */
++int mlx5_sriov_blocking_notifier_register(struct mlx5_core_dev *mdev,
++ int vf_id,
++ struct notifier_block *nb)
++{
++ struct mlx5_vf_context *vfs_ctx;
++ struct mlx5_core_sriov *sriov;
++
++ sriov = &mdev->priv.sriov;
++ if (vf_id < 0 || vf_id >= sriov->num_vfs)
++ return -EINVAL;
++
++ vfs_ctx = &sriov->vfs_ctx[vf_id];
++ return blocking_notifier_chain_register(&vfs_ctx->notifier, nb);
++}
++EXPORT_SYMBOL(mlx5_sriov_blocking_notifier_register);
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index 9424503eb8d3..3d1594bad4ec 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -445,6 +445,11 @@ struct mlx5_qp_table {
+ struct radix_tree_root tree;
+ };
+
++enum {
++ MLX5_PF_NOTIFY_DISABLE_VF,
++ MLX5_PF_NOTIFY_ENABLE_VF,
++};
++
+ struct mlx5_vf_context {
+ int enabled;
+ u64 port_guid;
+@@ -455,6 +460,7 @@ struct mlx5_vf_context {
+ u8 port_guid_valid:1;
+ u8 node_guid_valid:1;
+ enum port_state_policy policy;
++ struct blocking_notifier_head notifier;
+ };
+
+ struct mlx5_core_sriov {
+@@ -1155,6 +1161,12 @@ int mlx5_dm_sw_icm_dealloc(struct mlx5_core_dev *dev, enum mlx5_sw_icm_type type
+ struct mlx5_core_dev *mlx5_vf_get_core_dev(struct pci_dev *pdev);
+ void mlx5_vf_put_core_dev(struct mlx5_core_dev *mdev);
+
++int mlx5_sriov_blocking_notifier_register(struct mlx5_core_dev *mdev,
++ int vf_id,
++ struct notifier_block *nb);
++void mlx5_sriov_blocking_notifier_unregister(struct mlx5_core_dev *mdev,
++ int vf_id,
++ struct notifier_block *nb);
+ #ifdef CONFIG_MLX5_CORE_IPOIB
+ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
+ struct ib_device *ibdev,
+--
+2.35.1
+
--- /dev/null
+From b62efaf14d67aa74bc6852cfb81be02b0d1dda35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jun 2022 16:05:31 +0300
+Subject: net/mlx5: Fix driver use of uninitialized timeout
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit 42b4f7f66a43cdb9216e76e595c8a9af154806da ]
+
+Currently, driver is setting default values to all timeouts during
+function setup. The offending commit is using a timeout before
+function setup, meaning: the timeout is 0 (or garbage), since no
+value have been set.
+This may result in failure to probe the driver:
+mlx5_function_setup:1034:(pid 69850): Firmware over 4294967296 MS in pre-initializing state, aborting
+probe_one:1591:(pid 69850): mlx5_init_one failed with error code -16
+
+Hence, set default values to timeouts during tout_init()
+
+Fixes: 37ca95e62ee2 ("net/mlx5: Increase FW pre-init timeout for health recovery")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c | 11 ++++-------
+ drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h | 1 -
+ drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 --
+ 3 files changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c
+index d758848d34d0..696e45e2bd06 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c
+@@ -32,20 +32,17 @@ static void tout_set(struct mlx5_core_dev *dev, u64 val, enum mlx5_timeouts_type
+ dev->timeouts->to[type] = val;
+ }
+
+-void mlx5_tout_set_def_val(struct mlx5_core_dev *dev)
++int mlx5_tout_init(struct mlx5_core_dev *dev)
+ {
+ int i;
+
+- for (i = 0; i < MAX_TIMEOUT_TYPES; i++)
+- tout_set(dev, tout_def_sw_val[i], i);
+-}
+-
+-int mlx5_tout_init(struct mlx5_core_dev *dev)
+-{
+ dev->timeouts = kmalloc(sizeof(*dev->timeouts), GFP_KERNEL);
+ if (!dev->timeouts)
+ return -ENOMEM;
+
++ for (i = 0; i < MAX_TIMEOUT_TYPES; i++)
++ tout_set(dev, tout_def_sw_val[i], i);
++
+ return 0;
+ }
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h
+index 257c03eeab36..bc9e9aeda847 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h
+@@ -35,7 +35,6 @@ int mlx5_tout_init(struct mlx5_core_dev *dev);
+ void mlx5_tout_cleanup(struct mlx5_core_dev *dev);
+ void mlx5_tout_query_iseg(struct mlx5_core_dev *dev);
+ int mlx5_tout_query_dtor(struct mlx5_core_dev *dev);
+-void mlx5_tout_set_def_val(struct mlx5_core_dev *dev);
+ u64 _mlx5_tout_ms(struct mlx5_core_dev *dev, enum mlx5_timeouts_types type);
+
+ #define mlx5_tout_ms(dev, type) _mlx5_tout_ms(dev, MLX5_TO_##type##_MS)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index ffb0bb4ecdef..75d216246955 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1025,8 +1025,6 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, u64 timeout)
+ if (mlx5_core_is_pf(dev))
+ pcie_print_link_status(dev->pdev);
+
+- mlx5_tout_set_def_val(dev);
+-
+ /* wait for firmware to accept initialization segments configurations
+ */
+ err = wait_fw_init(dev, timeout,
+--
+2.35.1
+
--- /dev/null
+From 2113d865672b85039d6501c64dd9cef69fbb0d7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 15:14:08 +0300
+Subject: net/mlx5e: Fix calculations related to max MPWQE size
+
+From: Maxim Mikityanskiy <maximmi@nvidia.com>
+
+[ Upstream commit 677e78c8d44f326a73a77d71acf3a49ea562c1d9 ]
+
+Before commit 76c31e5f7585 ("net/mlx5e: Use FW limitation for max MPW
+WQEBBs"), the maximum size of MPWQE in WQEBBs was hardcoded as a driver
+constant. That commit started using the firmware capability that can
+further limit the size, however, it unintentionally changed a few
+things:
+
+1. The calculation of MLX5E_MAX_KLM_PER_WQE used the size in DS, which
+was replaced by the size in WQEBBs, making the resulting value 4 times
+smaller.
+
+2. MLX5E_TX_MPW_MAX_WQEBBS used to be aligned to the cache line size
+(either 64 or 128 bytes, i.e. 1 or 2 WQEBBs), but it's no longer the
+case if the firmware capability is smaller than the driver maximum.
+
+Fix both issues by using the correct units for MLX5E_MAX_KLM_PER_WQE and
+by aligning mlx5e_get_sw_max_sq_mpw_wqebbs after taking the minimum.
+
+Besides fixing the arithmetics in calculation of MLX5E_MAX_KLM_PER_WQE,
+also use appropriate constants: `size of BSF * num of DS per WQEBB *
+number of WQEBBs` (the calculation before the blamed commit) doesn't
+make much sense to calculate the WQE size in bytes, so just use `size of
+WQEBB * number of WQEBBs`.
+
+While at it, replace the types that hold the number of WQEBBs by u8.
+These values don't exceed 16, and it allows to fill holes in two
+structs.
+
+Fixes: 76c31e5f7585 ("net/mlx5e: Use FW limitation for max MPW WQEBBs")
+Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en.h | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+index d73571e542bd..3ddf76aea3f1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+@@ -174,8 +174,8 @@ struct page_pool;
+ ALIGN_DOWN(MLX5E_KLM_MAX_ENTRIES_PER_WQE(wqe_size), MLX5_UMR_KLM_ALIGNMENT)
+
+ #define MLX5E_MAX_KLM_PER_WQE(mdev) \
+- MLX5E_KLM_ENTRIES_PER_WQE(mlx5e_get_sw_max_sq_mpw_wqebbs(mlx5e_get_max_sq_wqebbs(mdev)) \
+- << MLX5_MKEY_BSF_OCTO_SIZE)
++ MLX5E_KLM_ENTRIES_PER_WQE(MLX5_SEND_WQE_BB * \
++ mlx5e_get_sw_max_sq_mpw_wqebbs(mlx5e_get_max_sq_wqebbs(mdev)))
+
+ #define MLX5E_MSG_LEVEL NETIF_MSG_LINK
+
+@@ -233,7 +233,7 @@ static inline u16 mlx5e_get_max_sq_wqebbs(struct mlx5_core_dev *mdev)
+ MLX5_CAP_GEN(mdev, max_wqe_sz_sq) / MLX5_SEND_WQE_BB);
+ }
+
+-static inline u16 mlx5e_get_sw_max_sq_mpw_wqebbs(u16 max_sq_wqebbs)
++static inline u8 mlx5e_get_sw_max_sq_mpw_wqebbs(u8 max_sq_wqebbs)
+ {
+ /* The return value will be multiplied by MLX5_SEND_WQEBB_NUM_DS.
+ * Since max_sq_wqebbs may be up to MLX5_SEND_WQE_MAX_WQEBBS == 16,
+@@ -242,11 +242,12 @@ static inline u16 mlx5e_get_sw_max_sq_mpw_wqebbs(u16 max_sq_wqebbs)
+ * than MLX5_SEND_WQE_MAX_WQEBBS to let a full-session WQE be
+ * cache-aligned.
+ */
+-#if L1_CACHE_BYTES < 128
+- return min_t(u16, max_sq_wqebbs, MLX5_SEND_WQE_MAX_WQEBBS - 1);
+-#else
+- return min_t(u16, max_sq_wqebbs, MLX5_SEND_WQE_MAX_WQEBBS - 2);
++ u8 wqebbs = min_t(u8, max_sq_wqebbs, MLX5_SEND_WQE_MAX_WQEBBS - 1);
++
++#if L1_CACHE_BYTES >= 128
++ wqebbs = ALIGN_DOWN(wqebbs, 2);
+ #endif
++ return wqebbs;
+ }
+
+ struct mlx5e_tx_wqe {
+@@ -456,7 +457,7 @@ struct mlx5e_txqsq {
+ struct netdev_queue *txq;
+ u32 sqn;
+ u16 stop_room;
+- u16 max_sq_mpw_wqebbs;
++ u8 max_sq_mpw_wqebbs;
+ u8 min_inline_mode;
+ struct device *pdev;
+ __be32 mkey_be;
+@@ -571,7 +572,7 @@ struct mlx5e_xdpsq {
+ struct device *pdev;
+ __be32 mkey_be;
+ u16 stop_room;
+- u16 max_sq_mpw_wqebbs;
++ u8 max_sq_mpw_wqebbs;
+ u8 min_inline_mode;
+ unsigned long state;
+ unsigned int hw_mtu;
+--
+2.35.1
+
--- /dev/null
+From 0b606fd5b95e4085b760b96969d5d9e79e55e2e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 16:48:47 +0300
+Subject: net/mlx5e: Fix the value of MLX5E_MAX_RQ_NUM_MTTS
+
+From: Maxim Mikityanskiy <maximmi@nvidia.com>
+
+[ Upstream commit 562696c3c62c7c23dd896e9447252ce9268cb812 ]
+
+MLX5E_MAX_RQ_NUM_MTTS should be the maximum value, so that
+MLX5_MTT_OCTW(MLX5E_MAX_RQ_NUM_MTTS) fits into u16. The current value of
+1 << 17 results in MLX5_MTT_OCTW(1 << 17) = 1 << 16, which doesn't fit
+into u16. This commit replaces it with the maximum value that still
+fits u16.
+
+Fixes: 73281b78a37a ("net/mlx5e: Derive Striding RQ size from MTU")
+Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+index d0d14325a0d9..d73571e542bd 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+@@ -109,7 +109,7 @@ struct page_pool;
+ #define MLX5E_REQUIRED_WQE_MTTS (MLX5_ALIGN_MTTS(MLX5_MPWRQ_PAGES_PER_WQE + 1))
+ #define MLX5E_REQUIRED_MTTS(wqes) (wqes * MLX5E_REQUIRED_WQE_MTTS)
+ #define MLX5E_MAX_RQ_NUM_MTTS \
+- ((1 << 16) * 2) /* So that MLX5_MTT_OCTW(num_mtts) fits into u16 */
++ (ALIGN_DOWN(U16_MAX, 4) * 2) /* So that MLX5_MTT_OCTW(num_mtts) fits into u16 */
+ #define MLX5E_ORDER2_MAX_PACKET_MTU (order_base_2(10 * 1024))
+ #define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW \
+ (ilog2(MLX5E_MAX_RQ_NUM_MTTS / MLX5E_REQUIRED_WQE_MTTS))
+--
+2.35.1
+
--- /dev/null
+From 71a02ade2ea26cbb3db7eadd5847c062e9f88bb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 21:49:18 +0200
+Subject: net/mlx5e: Modify slow path rules to go to slow fdb
+
+From: Vlad Buslov <vladbu@nvidia.com>
+
+[ Upstream commit c0063a43700fa8c98cac2637aa1afcf40bb9e403 ]
+
+While extending available range of supported chains/prios referenced commit
+also modified slow path rules to go to FT chain instead of actual slow FDB.
+However neither of existing users of the MLX5_ATTR_FLAG_SLOW_PATH
+flag (tunnel encap entries with invalid encap and flows with trap action)
+need to match on FT chain. After bridge offload was implemented packets of
+such flows can also be matched by bridge priority tables which is
+undesirable. Restore slow path flows implementation to redirect packets to
+slow_fdb.
+
+Fixes: 278d51f24330 ("net/mlx5: E-Switch, Increase number of chains and priorities")
+Signed-off-by: Vlad Buslov <vladbu@nvidia.com>
+Reviewed-by: Roi Dayan <roid@nvidia.com>
+Reviewed-by: Paul Blakey <paulb@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/eswitch_offloads.c | 23 ++++++++++++++-----
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index 796d97bcf1aa..c6546613f7d8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -230,10 +230,8 @@ esw_setup_ft_dest(struct mlx5_flow_destination *dest,
+ }
+
+ static void
+-esw_setup_slow_path_dest(struct mlx5_flow_destination *dest,
+- struct mlx5_flow_act *flow_act,
+- struct mlx5_fs_chains *chains,
+- int i)
++esw_setup_accept_dest(struct mlx5_flow_destination *dest, struct mlx5_flow_act *flow_act,
++ struct mlx5_fs_chains *chains, int i)
+ {
+ if (mlx5_chains_ignore_flow_level_supported(chains))
+ flow_act->flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
+@@ -241,6 +239,16 @@ esw_setup_slow_path_dest(struct mlx5_flow_destination *dest,
+ dest[i].ft = mlx5_chains_get_tc_end_ft(chains);
+ }
+
++static void
++esw_setup_slow_path_dest(struct mlx5_flow_destination *dest, struct mlx5_flow_act *flow_act,
++ struct mlx5_eswitch *esw, int i)
++{
++ if (MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, ignore_flow_level))
++ flow_act->flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
++ dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
++ dest[i].ft = esw->fdb_table.offloads.slow_fdb;
++}
++
+ static int
+ esw_setup_chain_dest(struct mlx5_flow_destination *dest,
+ struct mlx5_flow_act *flow_act,
+@@ -473,8 +481,11 @@ esw_setup_dests(struct mlx5_flow_destination *dest,
+ } else if (attr->dest_ft) {
+ esw_setup_ft_dest(dest, flow_act, esw, attr, spec, *i);
+ (*i)++;
+- } else if (mlx5e_tc_attr_flags_skip(attr->flags)) {
+- esw_setup_slow_path_dest(dest, flow_act, chains, *i);
++ } else if (attr->flags & MLX5_ATTR_FLAG_SLOW_PATH) {
++ esw_setup_slow_path_dest(dest, flow_act, esw, *i);
++ (*i)++;
++ } else if (attr->flags & MLX5_ATTR_FLAG_ACCEPT) {
++ esw_setup_accept_dest(dest, flow_act, chains, *i);
+ (*i)++;
+ } else if (attr->dest_chain) {
+ err = esw_setup_chain_dest(dest, flow_act, chains, attr->dest_chain,
+--
+2.35.1
+
--- /dev/null
+From c5bdd7be34c1f226c14be4ce089ab19ace1b83aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 13:57:03 +0300
+Subject: net/mlx5e: Remove WARN_ON when trying to offload an unsupported TLS
+ cipher/version
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 115d9f95ea7ab780ef315dc356bebba2e07cb731 ]
+
+The driver reports whether TX/RX TLS device offloads are supported, but
+not which ciphers/versions, these should be handled by returning
+-EOPNOTSUPP when .tls_dev_add() is called.
+
+Remove the WARN_ON kernel trace when the driver gets a request to
+offload a cipher/version that is not supported as it is expected.
+
+Fixes: d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Maxim Mikityanskiy <maximmi@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c
+index d93aadbf10da..90ea78239d40 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c
+@@ -16,7 +16,7 @@ static int mlx5e_ktls_add(struct net_device *netdev, struct sock *sk,
+ struct mlx5_core_dev *mdev = priv->mdev;
+ int err;
+
+- if (WARN_ON(!mlx5e_ktls_type_check(mdev, crypto_info)))
++ if (!mlx5e_ktls_type_check(mdev, crypto_info))
+ return -EOPNOTSUPP;
+
+ if (direction == TLS_OFFLOAD_CTX_DIR_TX)
+--
+2.35.1
+
--- /dev/null
+From 30bdb025abe523c820b52a13f31c04f1ea78bf14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 09:44:13 +0300
+Subject: net/mlx5e: TC, Fix post_act to not match on in_port metadata
+
+From: Maor Dickman <maord@nvidia.com>
+
+[ Upstream commit 903f2194f74bbd289f3170114035d472a36a8ab4 ]
+
+The cited commit changed CT to use multi table actions post act infrastructure instead
+of using it own post act infrastructure, this broke decap during VF tunnel offload
+(Stack devices) with CT due to wrong match on in_port metadata in the post act table.
+This changed only broke VF tunnel offload because it modify the packet in_port metadata
+to be VF metadata and it isn't propagate the post act creation.
+
+Fixed by modify post act rules to match only on fte_id and not match on in_port metadata
+which isn't needed.
+
+Fixes: a81283263bb0 ("net/mlx5e: Use multi table support for CT and sample actions")
+Signed-off-by: Maor Dickman <maord@nvidia.com>
+Reviewed-by: Roi Dayan <roid@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c
+index dea137dd744b..2b64dd557b5d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c
+@@ -128,6 +128,7 @@ mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *at
+ post_attr->inner_match_level = MLX5_MATCH_NONE;
+ post_attr->outer_match_level = MLX5_MATCH_NONE;
+ post_attr->action &= ~MLX5_FLOW_CONTEXT_ACTION_DECAP;
++ post_attr->flags |= MLX5_ATTR_FLAG_NO_IN_PORT;
+
+ handle->ns_type = post_act->ns_type;
+ /* Splits were handled before post action */
+--
+2.35.1
+
--- /dev/null
+From fd0acb09bc6e2574f12750c206ca6fae30d19e0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 May 2022 21:06:03 +0300
+Subject: net/mlx5e: xsk: Account for XSK RQ UMRs when calculating ICOSQ size
+
+From: Maxim Mikityanskiy <maximmi@nvidia.com>
+
+[ Upstream commit 52586d2f56b3e4f528ca7268d65074e92c936681 ]
+
+ICOSQ is used to post UMR WQEs for both regular RQ and XSK RQ. However,
+space in ICOSQ is reserved only for the regular RQ, which may cause
+ICOSQ overflows when using XSK (the most risk is on activating
+channels).
+
+This commit fixes the issue by reserving space for XSK UMR WQEs as well.
+As XSK may be enabled without restarting the channel and recreating the
+ICOSQ, this space is reserved unconditionally.
+
+Fixes: db05815b36cb ("net/mlx5e: Add XSK zero-copy support")
+Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/params.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
+index 08fd1370a8b0..75da12e1b0c7 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
+@@ -797,8 +797,20 @@ static u8 mlx5e_build_icosq_log_wq_sz(struct mlx5_core_dev *mdev,
+ return MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE;
+
+ wqebbs = MLX5E_UMR_WQEBBS * BIT(mlx5e_get_rq_log_wq_sz(rqp->rqc));
++
++ /* If XDP program is attached, XSK may be turned on at any time without
++ * restarting the channel. ICOSQ must be big enough to fit UMR WQEs of
++ * both regular RQ and XSK RQ.
++ * Although mlx5e_mpwqe_get_log_rq_size accepts mlx5e_xsk_param, it
++ * doesn't affect its return value, as long as params->xdp_prog != NULL,
++ * so we can just multiply by 2.
++ */
++ if (params->xdp_prog)
++ wqebbs *= 2;
++
+ if (params->packet_merge.type == MLX5E_PACKET_MERGE_SHAMPO)
+ wqebbs += mlx5e_shampo_icosq_sz(mdev, params, rqp);
++
+ return max_t(u8, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE, order_base_2(wqebbs));
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 47353d3ec1618c5e2fe4e933a2ee4509e0c23c28 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Jul 2022 15:13:56 +0300
+Subject: net/mlx5e: xsk: Discard unaligned XSK frames on striding RQ
+
+From: Maxim Mikityanskiy <maximmi@nvidia.com>
+
+[ Upstream commit 8eaa1d110800fac050bab44001732747a1c39894 ]
+
+Striding RQ uses MTT page mapping, where each page corresponds to an XSK
+frame. MTT pages have alignment requirements, and XSK frames don't have
+any alignment guarantees in the unaligned mode. Frames with improper
+alignment must be discarded, otherwise the packet data will be written
+at a wrong address.
+
+Fixes: 282c0c798f8e ("net/mlx5e: Allow XSK frames smaller than a page")
+Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Saeed Mahameed <saeedm@nvidia.com>
+Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Link: https://lore.kernel.org/r/20220729121356.3990867-1-maximmi@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/en/xsk/rx.h | 14 ++++++++++++++
+ include/net/xdp_sock_drv.h | 11 +++++++++++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.h
+index 7f88ccf67fdd..8b56cb8b4743 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.h
+@@ -7,6 +7,8 @@
+ #include "en.h"
+ #include <net/xdp_sock_drv.h>
+
++#define MLX5E_MTT_PTAG_MASK 0xfffffffffffffff8ULL
++
+ /* RX data path */
+
+ struct sk_buff *mlx5e_xsk_skb_from_cqe_mpwrq_linear(struct mlx5e_rq *rq,
+@@ -22,6 +24,7 @@ struct sk_buff *mlx5e_xsk_skb_from_cqe_linear(struct mlx5e_rq *rq,
+ static inline int mlx5e_xsk_page_alloc_pool(struct mlx5e_rq *rq,
+ struct mlx5e_dma_info *dma_info)
+ {
++retry:
+ dma_info->xsk = xsk_buff_alloc(rq->xsk_pool);
+ if (!dma_info->xsk)
+ return -ENOMEM;
+@@ -33,6 +36,17 @@ static inline int mlx5e_xsk_page_alloc_pool(struct mlx5e_rq *rq,
+ */
+ dma_info->addr = xsk_buff_xdp_get_frame_dma(dma_info->xsk);
+
++ /* MTT page mapping has alignment requirements. If they are not
++ * satisfied, leak the descriptor so that it won't come again, and try
++ * to allocate a new one.
++ */
++ if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
++ if (unlikely(dma_info->addr & ~MLX5E_MTT_PTAG_MASK)) {
++ xsk_buff_discard(dma_info->xsk);
++ goto retry;
++ }
++ }
++
+ return 0;
+ }
+
+diff --git a/include/net/xdp_sock_drv.h b/include/net/xdp_sock_drv.h
+index 4aa031849668..0774ce97c2f1 100644
+--- a/include/net/xdp_sock_drv.h
++++ b/include/net/xdp_sock_drv.h
+@@ -95,6 +95,13 @@ static inline void xsk_buff_free(struct xdp_buff *xdp)
+ xp_free(xskb);
+ }
+
++static inline void xsk_buff_discard(struct xdp_buff *xdp)
++{
++ struct xdp_buff_xsk *xskb = container_of(xdp, struct xdp_buff_xsk, xdp);
++
++ xp_release(xskb);
++}
++
+ static inline void xsk_buff_set_size(struct xdp_buff *xdp, u32 size)
+ {
+ xdp->data = xdp->data_hard_start + XDP_PACKET_HEADROOM;
+@@ -238,6 +245,10 @@ static inline void xsk_buff_free(struct xdp_buff *xdp)
+ {
+ }
+
++static inline void xsk_buff_discard(struct xdp_buff *xdp)
++{
++}
++
+ static inline void xsk_buff_set_size(struct xdp_buff *xdp, u32 size)
+ {
+ }
+--
+2.35.1
+
--- /dev/null
+From 38d628d4e8fa414f09bb81a5f5d88d49ba5f0b95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 13:06:35 +0300
+Subject: net: mscc: ocelot: delete ocelot_port :: xmit_template
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 15f6d01e4829cd2a2dc4f02a00c51d7cec1c736d ]
+
+This is no longer used since commit 7c4bb540e917 ("net: dsa: tag_ocelot:
+create separate tagger for Seville").
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/soc/mscc/ocelot.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
+index 9b4e6c78d0f4..b191f0a7fe26 100644
+--- a/include/soc/mscc/ocelot.h
++++ b/include/soc/mscc/ocelot.h
+@@ -663,7 +663,6 @@ struct ocelot_port {
+
+ phy_interface_t phy_mode;
+
+- u8 *xmit_template;
+ bool is_dsa_8021q_cpu;
+ bool learn_ena;
+
+--
+2.35.1
+
--- /dev/null
+From 00299ee7be0400adab249d4d9633398a49d6edba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 13:06:36 +0300
+Subject: net: mscc: ocelot: minimize holes in struct ocelot_port
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 6d0be600477089026c76fe529bd96fad4cf69c3b ]
+
+Reorder members of struct ocelot_port to eliminate holes and reduce
+structure size. Pahole says:
+
+Before:
+
+struct ocelot_port {
+ struct ocelot * ocelot; /* 0 8 */
+ struct regmap * target; /* 8 8 */
+ bool vlan_aware; /* 16 1 */
+
+ /* XXX 7 bytes hole, try to pack */
+
+ const struct ocelot_bridge_vlan * pvid_vlan; /* 24 8 */
+ unsigned int ptp_skbs_in_flight; /* 32 4 */
+ u8 ptp_cmd; /* 36 1 */
+
+ /* XXX 3 bytes hole, try to pack */
+
+ struct sk_buff_head tx_skbs; /* 40 96 */
+ /* --- cacheline 2 boundary (128 bytes) was 8 bytes ago --- */
+ u8 ts_id; /* 136 1 */
+
+ /* XXX 3 bytes hole, try to pack */
+
+ phy_interface_t phy_mode; /* 140 4 */
+ bool is_dsa_8021q_cpu; /* 144 1 */
+ bool learn_ena; /* 145 1 */
+
+ /* XXX 6 bytes hole, try to pack */
+
+ struct net_device * bond; /* 152 8 */
+ bool lag_tx_active; /* 160 1 */
+
+ /* XXX 1 byte hole, try to pack */
+
+ u16 mrp_ring_id; /* 162 2 */
+
+ /* XXX 4 bytes hole, try to pack */
+
+ struct net_device * bridge; /* 168 8 */
+ int bridge_num; /* 176 4 */
+ u8 stp_state; /* 180 1 */
+
+ /* XXX 3 bytes hole, try to pack */
+
+ int speed; /* 184 4 */
+
+ /* size: 192, cachelines: 3, members: 18 */
+ /* sum members: 161, holes: 7, sum holes: 27 */
+ /* padding: 4 */
+};
+
+After:
+
+struct ocelot_port {
+ struct ocelot * ocelot; /* 0 8 */
+ struct regmap * target; /* 8 8 */
+ struct net_device * bond; /* 16 8 */
+ struct net_device * bridge; /* 24 8 */
+ const struct ocelot_bridge_vlan * pvid_vlan; /* 32 8 */
+ phy_interface_t phy_mode; /* 40 4 */
+ unsigned int ptp_skbs_in_flight; /* 44 4 */
+ struct sk_buff_head tx_skbs; /* 48 96 */
+ /* --- cacheline 2 boundary (128 bytes) was 16 bytes ago --- */
+ u16 mrp_ring_id; /* 144 2 */
+ u8 ptp_cmd; /* 146 1 */
+ u8 ts_id; /* 147 1 */
+ u8 stp_state; /* 148 1 */
+ bool vlan_aware; /* 149 1 */
+ bool is_dsa_8021q_cpu; /* 150 1 */
+ bool learn_ena; /* 151 1 */
+ bool lag_tx_active; /* 152 1 */
+
+ /* XXX 3 bytes hole, try to pack */
+
+ int bridge_num; /* 156 4 */
+ int speed; /* 160 4 */
+
+ /* size: 168, cachelines: 3, members: 18 */
+ /* sum members: 161, holes: 1, sum holes: 3 */
+ /* padding: 4 */
+ /* last cacheline: 40 bytes */
+};
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/soc/mscc/ocelot.h | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
+index b191f0a7fe26..bae2ddb06731 100644
+--- a/include/soc/mscc/ocelot.h
++++ b/include/soc/mscc/ocelot.h
+@@ -652,28 +652,30 @@ struct ocelot_port {
+
+ struct regmap *target;
+
+- bool vlan_aware;
++ struct net_device *bond;
++ struct net_device *bridge;
++
+ /* VLAN that untagged frames are classified to, on ingress */
+ const struct ocelot_bridge_vlan *pvid_vlan;
+
++ phy_interface_t phy_mode;
++
+ unsigned int ptp_skbs_in_flight;
+- u8 ptp_cmd;
+ struct sk_buff_head tx_skbs;
+- u8 ts_id;
+
+- phy_interface_t phy_mode;
++ u16 mrp_ring_id;
+
++ u8 ptp_cmd;
++ u8 ts_id;
++
++ u8 stp_state;
++ bool vlan_aware;
+ bool is_dsa_8021q_cpu;
+ bool learn_ena;
+
+- struct net_device *bond;
+ bool lag_tx_active;
+
+- u16 mrp_ring_id;
+-
+- struct net_device *bridge;
+ int bridge_num;
+- u8 stp_state;
+
+ int speed;
+ };
+--
+2.35.1
+
--- /dev/null
+From e22bfdda80e4cda2f131e1b0aaeec37377594638 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Jul 2022 09:12:32 +0000
+Subject: net: rose: fix netdev reference changes
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 931027820e4dafabc78aff82af59f8c1c4bd3128 ]
+
+Bernard reported that trying to unload rose module would lead
+to infamous messages:
+
+unregistered_netdevice: waiting for rose0 to become free. Usage count = xx
+
+This patch solves the issue, by making sure each socket referring to
+a netdevice holds a reference count on it, and properly releases it
+in rose_release().
+
+rose_dev_first() is also fixed to take a device reference
+before leaving the rcu_read_locked section.
+
+Following patch will add ref_tracker annotations to ease
+future bug hunting.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: Bernard Pidoux <f6bvp@free.fr>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Tested-by: Bernard Pidoux <f6bvp@free.fr>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rose/af_rose.c | 11 +++++++++--
+ net/rose/rose_route.c | 2 ++
+ 2 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
+index bf2d986a6bc3..a8e3ec800a9c 100644
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -192,6 +192,7 @@ static void rose_kill_by_device(struct net_device *dev)
+ rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+ if (rose->neighbour)
+ rose->neighbour->use--;
++ dev_put(rose->device);
+ rose->device = NULL;
+ }
+ }
+@@ -592,6 +593,8 @@ static struct sock *rose_make_new(struct sock *osk)
+ rose->idle = orose->idle;
+ rose->defer = orose->defer;
+ rose->device = orose->device;
++ if (rose->device)
++ dev_hold(rose->device);
+ rose->qbitincl = orose->qbitincl;
+
+ return sk;
+@@ -645,6 +648,7 @@ static int rose_release(struct socket *sock)
+ break;
+ }
+
++ dev_put(rose->device);
+ sock->sk = NULL;
+ release_sock(sk);
+ sock_put(sk);
+@@ -721,7 +725,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+ struct rose_sock *rose = rose_sk(sk);
+ struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr;
+ unsigned char cause, diagnostic;
+- struct net_device *dev;
+ ax25_uid_assoc *user;
+ int n, err = 0;
+
+@@ -778,9 +781,12 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+ }
+
+ if (sock_flag(sk, SOCK_ZAPPED)) { /* Must bind first - autobinding in this may or may not work */
++ struct net_device *dev;
++
+ sock_reset_flag(sk, SOCK_ZAPPED);
+
+- if ((dev = rose_dev_first()) == NULL) {
++ dev = rose_dev_first();
++ if (!dev) {
+ err = -ENETUNREACH;
+ goto out_release;
+ }
+@@ -788,6 +794,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+ user = ax25_findbyuid(current_euid());
+ if (!user) {
+ err = -EINVAL;
++ dev_put(dev);
+ goto out_release;
+ }
+
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index 5e93510fa3d2..09ad2d9e63c9 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -615,6 +615,8 @@ struct net_device *rose_dev_first(void)
+ if (first == NULL || strncmp(dev->name, first->name, 3) < 0)
+ first = dev;
+ }
++ if (first)
++ dev_hold(first);
+ rcu_read_unlock();
+
+ return first;
+--
+2.35.1
+
--- /dev/null
+From 896767b8ae075f32121affff9a797fc2b4464b99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Jul 2022 22:02:40 +0300
+Subject: net: sched: provide shim definitions for taprio_offload_{get,free}
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit d7be266adbfd3aca6965ea6a0c36b2c3d8fc9fc8 ]
+
+All callers of taprio_offload_get() and taprio_offload_free() prior to
+the blamed commit are conditionally compiled based on CONFIG_NET_SCH_TAPRIO.
+
+felix_vsc9959.c is different; it provides vsc9959_qos_port_tas_set()
+even when taprio is compiled out.
+
+Provide shim definitions for the functions exported by taprio so that
+felix_vsc9959.c is able to compile. vsc9959_qos_port_tas_set() in that
+case is dead code anyway, and ocelot_port->taprio remains NULL, which is
+fine for the rest of the logic.
+
+Fixes: 1c9017e44af2 ("net: dsa: felix: keep reference on entire tc-taprio config")
+Reported-by: Colin Foster <colin.foster@in-advantage.com>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Tested-by: Colin Foster <colin.foster@in-advantage.com>
+Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Link: https://lore.kernel.org/r/20220704190241.1288847-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/pkt_sched.h | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
+index 44a35531952e..3372a1f67cf4 100644
+--- a/include/net/pkt_sched.h
++++ b/include/net/pkt_sched.h
+@@ -173,11 +173,28 @@ struct tc_taprio_qopt_offload {
+ struct tc_taprio_sched_entry entries[];
+ };
+
++#if IS_ENABLED(CONFIG_NET_SCH_TAPRIO)
++
+ /* Reference counting */
+ struct tc_taprio_qopt_offload *taprio_offload_get(struct tc_taprio_qopt_offload
+ *offload);
+ void taprio_offload_free(struct tc_taprio_qopt_offload *offload);
+
++#else
++
++/* Reference counting */
++static inline struct tc_taprio_qopt_offload *
++taprio_offload_get(struct tc_taprio_qopt_offload *offload)
++{
++ return NULL;
++}
++
++static inline void taprio_offload_free(struct tc_taprio_qopt_offload *offload)
++{
++}
++
++#endif
++
+ /* Ensure skb_mstamp_ns, which might have been populated with the txtime, is
+ * not mistaken for a software timestamp, because this will otherwise prevent
+ * the dispatch of hardware timestamps to the socket.
+--
+2.35.1
+
--- /dev/null
+From 4c1cd2876f823122275c2bdab287294e4178891d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Jul 2022 16:01:13 -0700
+Subject: net: usb: make USB_RTL8153_ECM non user configurable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maciej Żenczykowski <maze@google.com>
+
+[ Upstream commit f56530dcdb0684406661ac9f1accf48319d07600 ]
+
+This refixes:
+
+ commit 7da17624e7948d5d9660b910f8079d26d26ce453
+ nt: usb: USB_RTL8153_ECM should not default to y
+
+ In general, device drivers should not be enabled by default.
+
+which basically broke the commit it claimed to fix, ie:
+
+ commit 657bc1d10bfc23ac06d5d687ce45826c760744f9
+ r8153_ecm: avoid to be prior to r8152 driver
+
+ Avoid r8153_ecm is compiled as built-in, if r8152 driver is compiled
+ as modules. Otherwise, the r8153_ecm would be used, even though the
+ device is supported by r8152 driver.
+
+this commit amounted to:
+
+drivers/net/usb/Kconfig:
+
++config USB_RTL8153_ECM
++ tristate "RTL8153 ECM support"
++ depends on USB_NET_CDCETHER && (USB_RTL8152 || USB_RTL8152=n)
++ default y
++ help
++ This option supports ECM mode for RTL8153 ethernet adapter, when
++ CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not
++ supported by r8152 driver.
+
+drivers/net/usb/Makefile:
+
+-obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r8153_ecm.o
++obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
++obj-$(CONFIG_USB_RTL8153_ECM) += r8153_ecm.o
+
+And as can be seen it pulls a piece of the cdc_ether driver out into
+a separate config option to be able to make this piece modular in case
+cdc_ether is builtin, while r8152 is modular.
+
+While in general, device drivers should indeed not be enabled by default:
+this isn't a device driver per say, but rather this is support code for
+the CDCETHER (ECM) driver, and should thus be enabled if it is enabled.
+
+See also email thread at:
+ https://www.spinics.net/lists/netdev/msg767649.html
+
+In:
+ https://www.spinics.net/lists/netdev/msg768284.html
+
+Jakub wrote:
+ And when we say "removed" we can just hide it from what's prompted
+ to the user (whatever such internal options are called)? I believe
+ this way we don't bring back Marek's complaint.
+
+Side note: these incorrect defaults will result in Android 13
+on 5.15 GKI kernels lacking USB_RTL8153_ECM support while having
+USB_NET_CDCETHER (luckily we also have USB_RTL8150 and USB_RTL8152,
+so it's probably only an issue for very new RTL815x hardware with
+no native 5.15 driver).
+
+Fixes: 7da17624e7948d5d ("nt: usb: USB_RTL8153_ECM should not default to y")
+Cc: Geert Uytterhoeven <geert+renesas@glider.be>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Hayes Wang <hayeswang@realtek.com>
+Cc: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Maciej Żenczykowski <maze@google.com>
+Link: https://lore.kernel.org/r/20220730230113.4138858-1-zenczykowski@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
+index e62fc4f2aee0..76659c1c525a 100644
+--- a/drivers/net/usb/Kconfig
++++ b/drivers/net/usb/Kconfig
+@@ -637,8 +637,9 @@ config USB_NET_AQC111
+ * Aquantia AQtion USB to 5GbE
+
+ config USB_RTL8153_ECM
+- tristate "RTL8153 ECM support"
++ tristate
+ depends on USB_NET_CDCETHER && (USB_RTL8152 || USB_RTL8152=n)
++ default y
+ help
+ This option supports ECM mode for RTL8153 ethernet adapter, when
+ CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not
+--
+2.35.1
+
--- /dev/null
+From 6239a8e796f3060b71b72f50c92151868a76947f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Jul 2022 14:36:05 -0700
+Subject: netdevsim: Avoid allocation warnings triggered from user space
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit d0b80a9edb1a029ff913e81b47540e57ad034329 ]
+
+We need to suppress warnings from sily map sizes. Also switch
+from GFP_USER to GFP_KERNEL_ACCOUNT, I'm pretty sure I misunderstood
+the flags when writing this code.
+
+Fixes: 395cacb5f1a0 ("netdevsim: bpf: support fake map offload")
+Reported-by: syzbot+ad24705d3fd6463b18c6@syzkaller.appspotmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20220726213605.154204-1-kuba@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/netdevsim/bpf.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c
+index a43820212932..50854265864d 100644
+--- a/drivers/net/netdevsim/bpf.c
++++ b/drivers/net/netdevsim/bpf.c
+@@ -351,10 +351,12 @@ nsim_map_alloc_elem(struct bpf_offloaded_map *offmap, unsigned int idx)
+ {
+ struct nsim_bpf_bound_map *nmap = offmap->dev_priv;
+
+- nmap->entry[idx].key = kmalloc(offmap->map.key_size, GFP_USER);
++ nmap->entry[idx].key = kmalloc(offmap->map.key_size,
++ GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
+ if (!nmap->entry[idx].key)
+ return -ENOMEM;
+- nmap->entry[idx].value = kmalloc(offmap->map.value_size, GFP_USER);
++ nmap->entry[idx].value = kmalloc(offmap->map.value_size,
++ GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
+ if (!nmap->entry[idx].value) {
+ kfree(nmap->entry[idx].key);
+ nmap->entry[idx].key = NULL;
+@@ -496,7 +498,7 @@ nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap)
+ if (offmap->map.map_flags)
+ return -EINVAL;
+
+- nmap = kzalloc(sizeof(*nmap), GFP_USER);
++ nmap = kzalloc(sizeof(*nmap), GFP_KERNEL_ACCOUNT);
+ if (!nmap)
+ return -ENOMEM;
+
+--
+2.35.1
+
--- /dev/null
+From 93eb3c8f7d54573cc2afc5bde548349c8ac0a175 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Jul 2022 14:45:33 +0300
+Subject: netdevsim: fib: Fix reference count leak on route deletion failure
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 180a6a3ee60a7cb69ed1232388460644f6a21f00 ]
+
+As part of FIB offload simulation, netdevsim stores IPv4 and IPv6 routes
+and holds a reference on FIB info structures that in turn hold a
+reference on the associated nexthop device(s).
+
+In the unlikely case where we are unable to allocate memory to process a
+route deletion request, netdevsim will not release the reference from
+the associated FIB info structure, thereby preventing the associated
+nexthop device(s) from ever being removed [1].
+
+Fix this by scheduling a work item that will flush netdevsim's FIB table
+upon route deletion failure. This will cause netdevsim to release its
+reference from all the FIB info structures in its table.
+
+Reported by Lucas Leong of Trend Micro Zero Day Initiative.
+
+Fixes: 0ae3eb7b4611 ("netdevsim: fib: Perform the route programming in a non-atomic context")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Amit Cohen <amcohen@nvidia.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/netdevsim/fib.c | 27 ++++++++++++++++++++++++++-
+ 1 file changed, 26 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/netdevsim/fib.c b/drivers/net/netdevsim/fib.c
+index 378ee779061c..14787d17f703 100644
+--- a/drivers/net/netdevsim/fib.c
++++ b/drivers/net/netdevsim/fib.c
+@@ -53,6 +53,7 @@ struct nsim_fib_data {
+ struct rhashtable nexthop_ht;
+ struct devlink *devlink;
+ struct work_struct fib_event_work;
++ struct work_struct fib_flush_work;
+ struct list_head fib_event_queue;
+ spinlock_t fib_event_queue_lock; /* Protects fib event queue list */
+ struct mutex nh_lock; /* Protects NH HT */
+@@ -977,7 +978,7 @@ static int nsim_fib_event_schedule_work(struct nsim_fib_data *data,
+
+ fib_event = kzalloc(sizeof(*fib_event), GFP_ATOMIC);
+ if (!fib_event)
+- return NOTIFY_BAD;
++ goto err_fib_event_alloc;
+
+ fib_event->data = data;
+ fib_event->event = event;
+@@ -1005,6 +1006,9 @@ static int nsim_fib_event_schedule_work(struct nsim_fib_data *data,
+
+ err_fib_prepare_event:
+ kfree(fib_event);
++err_fib_event_alloc:
++ if (event == FIB_EVENT_ENTRY_DEL)
++ schedule_work(&data->fib_flush_work);
+ return NOTIFY_BAD;
+ }
+
+@@ -1482,6 +1486,24 @@ static void nsim_fib_event_work(struct work_struct *work)
+ mutex_unlock(&data->fib_lock);
+ }
+
++static void nsim_fib_flush_work(struct work_struct *work)
++{
++ struct nsim_fib_data *data = container_of(work, struct nsim_fib_data,
++ fib_flush_work);
++ struct nsim_fib_rt *fib_rt, *fib_rt_tmp;
++
++ /* Process pending work. */
++ flush_work(&data->fib_event_work);
++
++ mutex_lock(&data->fib_lock);
++ list_for_each_entry_safe(fib_rt, fib_rt_tmp, &data->fib_rt_list, list) {
++ rhashtable_remove_fast(&data->fib_rt_ht, &fib_rt->ht_node,
++ nsim_fib_rt_ht_params);
++ nsim_fib_rt_free(fib_rt, data);
++ }
++ mutex_unlock(&data->fib_lock);
++}
++
+ static int
+ nsim_fib_debugfs_init(struct nsim_fib_data *data, struct nsim_dev *nsim_dev)
+ {
+@@ -1540,6 +1562,7 @@ struct nsim_fib_data *nsim_fib_create(struct devlink *devlink,
+ goto err_rhashtable_nexthop_destroy;
+
+ INIT_WORK(&data->fib_event_work, nsim_fib_event_work);
++ INIT_WORK(&data->fib_flush_work, nsim_fib_flush_work);
+ INIT_LIST_HEAD(&data->fib_event_queue);
+ spin_lock_init(&data->fib_event_queue_lock);
+
+@@ -1586,6 +1609,7 @@ struct nsim_fib_data *nsim_fib_create(struct devlink *devlink,
+ err_nexthop_nb_unregister:
+ unregister_nexthop_notifier(devlink_net(devlink), &data->nexthop_nb);
+ err_rhashtable_fib_destroy:
++ cancel_work_sync(&data->fib_flush_work);
+ flush_work(&data->fib_event_work);
+ rhashtable_free_and_destroy(&data->fib_rt_ht, nsim_fib_rt_free,
+ data);
+@@ -1615,6 +1639,7 @@ void nsim_fib_destroy(struct devlink *devlink, struct nsim_fib_data *data)
+ NSIM_RESOURCE_IPV4_FIB);
+ unregister_fib_notifier(devlink_net(devlink), &data->fib_nb);
+ unregister_nexthop_notifier(devlink_net(devlink), &data->nexthop_nb);
++ cancel_work_sync(&data->fib_flush_work);
+ flush_work(&data->fib_event_work);
+ rhashtable_free_and_destroy(&data->fib_rt_ht, nsim_fib_rt_free,
+ data);
+--
+2.35.1
+
--- /dev/null
+From 0c28160ce56ea8c55964e56746d34d3ac1175f02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Jul 2022 12:44:35 +0200
+Subject: netfilter: nf_tables: add rescheduling points during loop detection
+ walks
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 81ea010667417ef3f218dfd99b69769fe66c2b67 ]
+
+Add explicit rescheduling points during ruleset walk.
+
+Switching to a faster algorithm is possible but this is a much
+smaller change, suitable for nf tree.
+
+Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1460
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 2b60923cf87b..7eac496961a7 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -3343,6 +3343,8 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain)
+ if (err < 0)
+ return err;
+ }
++
++ cond_resched();
+ }
+
+ return 0;
+@@ -9371,9 +9373,13 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
+ break;
+ }
+ }
++
++ cond_resched();
+ }
+
+ list_for_each_entry(set, &ctx->table->sets, list) {
++ cond_resched();
++
+ if (!nft_is_active_next(ctx->net, set))
+ continue;
+ if (!(set->flags & NFT_SET_MAP) ||
+--
+2.35.1
+
--- /dev/null
+From ed2adddbf6878ed0767801b244bde8b2a5166320 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Jul 2022 19:49:00 +0200
+Subject: netfilter: nft_queue: only allow supported familes and hooks
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 47f4f510ad586032b85c89a0773fbb011d412425 ]
+
+Trying to use 'queue' statement in ingress (for example)
+triggers a splat on reinject:
+
+WARNING: CPU: 3 PID: 1345 at net/netfilter/nf_queue.c:291
+
+... because nf_reinject cannot find the ruleset head.
+
+The netdev family doesn't support async resume at the moment anyway,
+so disallow loading such rulesets with a more appropriate
+error message.
+
+v2: add 'validate' callback and also check hook points, v1 did
+allow ingress use in 'table inet', but that doesn't work either. (Pablo)
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_queue.c | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/net/netfilter/nft_queue.c b/net/netfilter/nft_queue.c
+index 15e4b7640dc0..da29e92c03e2 100644
+--- a/net/netfilter/nft_queue.c
++++ b/net/netfilter/nft_queue.c
+@@ -68,6 +68,31 @@ static void nft_queue_sreg_eval(const struct nft_expr *expr,
+ regs->verdict.code = ret;
+ }
+
++static int nft_queue_validate(const struct nft_ctx *ctx,
++ const struct nft_expr *expr,
++ const struct nft_data **data)
++{
++ static const unsigned int supported_hooks = ((1 << NF_INET_PRE_ROUTING) |
++ (1 << NF_INET_LOCAL_IN) |
++ (1 << NF_INET_FORWARD) |
++ (1 << NF_INET_LOCAL_OUT) |
++ (1 << NF_INET_POST_ROUTING));
++
++ switch (ctx->family) {
++ case NFPROTO_IPV4:
++ case NFPROTO_IPV6:
++ case NFPROTO_INET:
++ case NFPROTO_BRIDGE:
++ break;
++ case NFPROTO_NETDEV: /* lacks okfn */
++ fallthrough;
++ default:
++ return -EOPNOTSUPP;
++ }
++
++ return nft_chain_validate_hooks(ctx->chain, supported_hooks);
++}
++
+ static const struct nla_policy nft_queue_policy[NFTA_QUEUE_MAX + 1] = {
+ [NFTA_QUEUE_NUM] = { .type = NLA_U16 },
+ [NFTA_QUEUE_TOTAL] = { .type = NLA_U16 },
+@@ -164,6 +189,7 @@ static const struct nft_expr_ops nft_queue_ops = {
+ .eval = nft_queue_eval,
+ .init = nft_queue_init,
+ .dump = nft_queue_dump,
++ .validate = nft_queue_validate,
+ .reduce = NFT_REDUCE_READONLY,
+ };
+
+@@ -173,6 +199,7 @@ static const struct nft_expr_ops nft_queue_sreg_ops = {
+ .eval = nft_queue_sreg_eval,
+ .init = nft_queue_sreg_init,
+ .dump = nft_queue_sreg_dump,
++ .validate = nft_queue_validate,
+ .reduce = NFT_REDUCE_READONLY,
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 63e2f0b8c36b253db95b5900042d611071ba57e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 17:23:45 +0200
+Subject: netfilter: xtables: Bring SPDX identifier back
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 20646f5b1e798bcc20044ae90ac3702f177bf254 ]
+
+Commit e2be04c7f995 ("License cleanup: add SPDX license identifier to
+uapi header files with a license") added the correct SPDX identifier to
+include/uapi/linux/netfilter/xt_IDLETIMER.h.
+
+A subsequent commit removed it for no reason and reintroduced the UAPI
+license incorrectness as the file is now missing the UAPI exception
+again.
+
+Add it back and remove the GPLv2 boilerplate while at it.
+
+Fixes: 68983a354a65 ("netfilter: xtables: Add snapshot of hardidletimer target")
+Cc: Manoj Basapathi <manojbm@codeaurora.org>
+Cc: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
+Cc: Pablo Neira Ayuso <pablo@netfilter.org>
+Cc: netfilter-devel@vger.kernel.org
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/netfilter/xt_IDLETIMER.h | 17 +----------------
+ 1 file changed, 1 insertion(+), 16 deletions(-)
+
+diff --git a/include/uapi/linux/netfilter/xt_IDLETIMER.h b/include/uapi/linux/netfilter/xt_IDLETIMER.h
+index 49ddcdc61c09..7bfb31a66fc9 100644
+--- a/include/uapi/linux/netfilter/xt_IDLETIMER.h
++++ b/include/uapi/linux/netfilter/xt_IDLETIMER.h
+@@ -1,6 +1,5 @@
++/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+ /*
+- * linux/include/linux/netfilter/xt_IDLETIMER.h
+- *
+ * Header file for Xtables timer target module.
+ *
+ * Copyright (C) 2004, 2010 Nokia Corporation
+@@ -10,20 +9,6 @@
+ * by Luciano Coelho <luciano.coelho@nokia.com>
+ *
+ * Contact: Luciano Coelho <luciano.coelho@nokia.com>
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * version 2 as published by the Free Software Foundation.
+- *
+- * This program is distributed in the hope that it will be useful, but
+- * WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+- * General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+- * 02110-1301 USA
+ */
+
+ #ifndef _XT_IDLETIMER_H
+--
+2.35.1
+
--- /dev/null
+From ac593eedda48ca3f8711e6c3af0fd5f7913bc5c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jun 2022 11:22:59 +0200
+Subject: nohz/full, sched/rt: Fix missed tick-reenabling bug in
+ dequeue_task_rt()
+
+From: Nicolas Saenz Julienne <nsaenzju@redhat.com>
+
+[ Upstream commit 5c66d1b9b30f737fcef85a0b75bfe0590e16b62a ]
+
+dequeue_task_rt() only decrements 'rt_rq->rt_nr_running' after having
+called sched_update_tick_dependency() preventing it from re-enabling the
+tick on systems that no longer have pending SCHED_RT tasks but have
+multiple runnable SCHED_OTHER tasks:
+
+ dequeue_task_rt()
+ dequeue_rt_entity()
+ dequeue_rt_stack()
+ dequeue_top_rt_rq()
+ sub_nr_running() // decrements rq->nr_running
+ sched_update_tick_dependency()
+ sched_can_stop_tick() // checks rq->rt.rt_nr_running,
+ ...
+ __dequeue_rt_entity()
+ dec_rt_tasks() // decrements rq->rt.rt_nr_running
+ ...
+
+Every other scheduler class performs the operation in the opposite
+order, and sched_update_tick_dependency() expects the values to be
+updated as such. So avoid the misbehaviour by inverting the order in
+which the above operations are performed in the RT scheduler.
+
+Fixes: 76d92ac305f2 ("sched: Migrate sched to use new tick dependency mask model")
+Signed-off-by: Nicolas Saenz Julienne <nsaenzju@redhat.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Valentin Schneider <vschneid@redhat.com>
+Reviewed-by: Phil Auld <pauld@redhat.com>
+Link: https://lore.kernel.org/r/20220628092259.330171-1-nsaenzju@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/rt.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
+index 7891c0f0e1ff..907a5d7507a8 100644
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -430,7 +430,7 @@ static inline void rt_queue_push_tasks(struct rq *rq)
+ #endif /* CONFIG_SMP */
+
+ static void enqueue_top_rt_rq(struct rt_rq *rt_rq);
+-static void dequeue_top_rt_rq(struct rt_rq *rt_rq);
++static void dequeue_top_rt_rq(struct rt_rq *rt_rq, unsigned int count);
+
+ static inline int on_rt_rq(struct sched_rt_entity *rt_se)
+ {
+@@ -551,7 +551,7 @@ static void sched_rt_rq_dequeue(struct rt_rq *rt_rq)
+ rt_se = rt_rq->tg->rt_se[cpu];
+
+ if (!rt_se) {
+- dequeue_top_rt_rq(rt_rq);
++ dequeue_top_rt_rq(rt_rq, rt_rq->rt_nr_running);
+ /* Kick cpufreq (see the comment in kernel/sched/sched.h). */
+ cpufreq_update_util(rq_of_rt_rq(rt_rq), 0);
+ }
+@@ -637,7 +637,7 @@ static inline void sched_rt_rq_enqueue(struct rt_rq *rt_rq)
+
+ static inline void sched_rt_rq_dequeue(struct rt_rq *rt_rq)
+ {
+- dequeue_top_rt_rq(rt_rq);
++ dequeue_top_rt_rq(rt_rq, rt_rq->rt_nr_running);
+ }
+
+ static inline int rt_rq_throttled(struct rt_rq *rt_rq)
+@@ -1039,7 +1039,7 @@ static void update_curr_rt(struct rq *rq)
+ }
+
+ static void
+-dequeue_top_rt_rq(struct rt_rq *rt_rq)
++dequeue_top_rt_rq(struct rt_rq *rt_rq, unsigned int count)
+ {
+ struct rq *rq = rq_of_rt_rq(rt_rq);
+
+@@ -1050,7 +1050,7 @@ dequeue_top_rt_rq(struct rt_rq *rt_rq)
+
+ BUG_ON(!rq->nr_running);
+
+- sub_nr_running(rq, rt_rq->rt_nr_running);
++ sub_nr_running(rq, count);
+ rt_rq->rt_queued = 0;
+
+ }
+@@ -1436,18 +1436,21 @@ static void __dequeue_rt_entity(struct sched_rt_entity *rt_se, unsigned int flag
+ static void dequeue_rt_stack(struct sched_rt_entity *rt_se, unsigned int flags)
+ {
+ struct sched_rt_entity *back = NULL;
++ unsigned int rt_nr_running;
+
+ for_each_sched_rt_entity(rt_se) {
+ rt_se->back = back;
+ back = rt_se;
+ }
+
+- dequeue_top_rt_rq(rt_rq_of_se(back));
++ rt_nr_running = rt_rq_of_se(back)->rt_nr_running;
+
+ for (rt_se = back; rt_se; rt_se = rt_se->back) {
+ if (on_rt_rq(rt_se))
+ __dequeue_rt_entity(rt_se, flags);
+ }
++
++ dequeue_top_rt_rq(rt_rq_of_se(back), rt_nr_running);
+ }
+
+ static void enqueue_rt_entity(struct sched_rt_entity *rt_se, unsigned int flags)
+--
+2.35.1
+
--- /dev/null
+From 21beb2c46b060f9099cf053ec584bdc945f918be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 11:12:14 +0300
+Subject: null_blk: fix ida error handling in null_add_dev()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit ee452a8d984f94fa8e894f003a52e776e4572881 ]
+
+There needs to be some error checking if ida_simple_get() fails.
+Also call ida_free() if there are errors later.
+
+Fixes: 94bc02e30fb8 ("nullb: use ida to manage index")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Link: https://lore.kernel.org/r/YtEhXsr6vJeoiYhd@kili
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/null_blk/main.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
+index c441a4972064..3e59e824ed1f 100644
+--- a/drivers/block/null_blk/main.c
++++ b/drivers/block/null_blk/main.c
+@@ -2044,8 +2044,13 @@ static int null_add_dev(struct nullb_device *dev)
+ blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, nullb->q);
+
+ mutex_lock(&lock);
+- nullb->index = ida_simple_get(&nullb_indexes, 0, 0, GFP_KERNEL);
+- dev->index = nullb->index;
++ rv = ida_simple_get(&nullb_indexes, 0, 0, GFP_KERNEL);
++ if (rv < 0) {
++ mutex_unlock(&lock);
++ goto out_cleanup_zone;
++ }
++ nullb->index = rv;
++ dev->index = rv;
+ mutex_unlock(&lock);
+
+ blk_queue_logical_block_size(nullb->q, dev->blocksize);
+@@ -2065,13 +2070,16 @@ static int null_add_dev(struct nullb_device *dev)
+
+ rv = null_gendisk_register(nullb);
+ if (rv)
+- goto out_cleanup_zone;
++ goto out_ida_free;
+
+ mutex_lock(&lock);
+ list_add_tail(&nullb->list, &nullb_list);
+ mutex_unlock(&lock);
+
+ return 0;
++
++out_ida_free:
++ ida_free(&nullb_indexes, nullb->index);
+ out_cleanup_zone:
+ null_free_zoned_dev(dev);
+ out_cleanup_disk:
+--
+2.35.1
+
--- /dev/null
+From 378a443d07250f27b6df6d5ec87616fb156b9aa1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 07:56:35 +0200
+Subject: nvme: catch -ENODEV from nvme_revalidate_zones again
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit e06b425bc835ead08b9fd935bf5e47eef473e7a0 ]
+
+nvme_revalidate_zones can also return -ENODEV if e.g. zone sizes aren't
+constant or not a power of two. In that case we should jump to marking
+the gendisk hidden and only support pass through.
+
+Fixes: 602e57c9799c ("nvme: also mark passthrough-only namespaces ready in nvme_update_ns_info")
+Reported-by: Joel Granados <j.granados@samsung.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Joel Granados <j.granados@samsung.com>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index cf7be9b4f5d3..a58a69999dbc 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1897,8 +1897,10 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
+
+ if (ns->head->ids.csi == NVME_CSI_ZNS) {
+ ret = nvme_update_zone_info(ns, lbaf);
+- if (ret)
+- goto out_unfreeze;
++ if (ret) {
++ blk_mq_unfreeze_queue(ns->disk->queue);
++ goto out;
++ }
+ }
+
+ set_disk_ro(ns->disk, (id->nsattr & NVME_NS_ATTR_RO) ||
+@@ -1909,7 +1911,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
+ if (blk_queue_is_zoned(ns->queue)) {
+ ret = nvme_revalidate_zones(ns);
+ if (ret && !nvme_first_scan(ns->disk))
+- return ret;
++ goto out;
+ }
+
+ if (nvme_ns_head_multipath(ns->head)) {
+@@ -1924,9 +1926,9 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
+ disk_update_readahead(ns->head->disk);
+ blk_mq_unfreeze_queue(ns->head->disk->queue);
+ }
+- return 0;
+
+-out_unfreeze:
++ ret = 0;
++out:
+ /*
+ * If probing fails due an unsupported feature, hide the block device,
+ * but still allow other access.
+@@ -1936,7 +1938,6 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
+ set_bit(NVME_NS_READY, &ns->flags);
+ ret = 0;
+ }
+- blk_mq_unfreeze_queue(ns->disk->queue);
+ return ret;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 931d06cdae350edaac1191fc026a9ca962360501 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Jul 2022 23:57:35 -0400
+Subject: nvme: define compat_ioctl again to unbreak 32-bit userspace.
+
+From: Nick Bowler <nbowler@draconx.ca>
+
+[ Upstream commit a25d4261582cf00dad884c194d21084836663d3d ]
+
+Commit 89b3d6e60550 ("nvme: simplify the compat ioctl handling") removed
+the initialization of compat_ioctl from the nvme block_device_operations
+structures.
+
+Presumably the expectation was that 32-bit ioctls would be directed
+through the regular handler but this is not the case: failing to assign
+.compat_ioctl actually means that the compat case is disabled entirely,
+and any attempt to submit nvme ioctls from 32-bit userspace fails
+outright with -ENOTTY.
+
+For example:
+
+ % smartctl -x /dev/nvme0n1
+ [...]
+ Read NVMe Identify Controller failed: NVME_IOCTL_ADMIN_CMD: Inappropriate ioctl for device
+
+The blkdev_compat_ptr_ioctl helper can be used to direct compat calls
+through the main ioctl handler and makes things work again.
+
+Fixes: 89b3d6e60550 ("nvme: simplify the compat ioctl handling")
+Signed-off-by: Nick Bowler <nbowler@draconx.ca>
+Reviewed-by: Guixin Liu <kanie@linux.alibaba.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/core.c | 1 +
+ drivers/nvme/host/multipath.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index c9831daafbc6..cf7be9b4f5d3 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -2093,6 +2093,7 @@ static int nvme_report_zones(struct gendisk *disk, sector_t sector,
+ static const struct block_device_operations nvme_bdev_ops = {
+ .owner = THIS_MODULE,
+ .ioctl = nvme_ioctl,
++ .compat_ioctl = blkdev_compat_ptr_ioctl,
+ .open = nvme_open,
+ .release = nvme_release,
+ .getgeo = nvme_getgeo,
+diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
+index d464fdf978fb..b0fe23439c4a 100644
+--- a/drivers/nvme/host/multipath.c
++++ b/drivers/nvme/host/multipath.c
+@@ -408,6 +408,7 @@ const struct block_device_operations nvme_ns_head_ops = {
+ .open = nvme_ns_head_open,
+ .release = nvme_ns_head_release,
+ .ioctl = nvme_ns_head_ioctl,
++ .compat_ioctl = blkdev_compat_ptr_ioctl,
+ .getgeo = nvme_getgeo,
+ .report_zones = nvme_ns_head_report_zones,
+ .pr_ops = &nvme_pr_ops,
+--
+2.35.1
+
--- /dev/null
+From 34189a358b66e8718ff1c6496adbeb87f10725c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 23:27:21 +0200
+Subject: nvme: use command_id instead of req->tag in trace_nvme_complete_rq()
+
+From: Bean Huo <beanhuo@micron.com>
+
+[ Upstream commit 679c54f2de672b7d79d02f8c4ad483ff6dd8ce2e ]
+
+Use command_id instead of req->tag in trace_nvme_complete_rq(),
+because of commit e7006de6c238 ("nvme: code command_id with a genctr
+for use authentication after release"), cmd->common.command_id is set to
+((genctl & 0xf)< 12 | req->tag), no longer req->tag, which makes cid in
+trace_nvme_complete_rq and trace_nvme_setup_cmd are not the same.
+
+Fixes: e7006de6c238 ("nvme: code command_id with a genctr for use authentication after release")
+Signed-off-by: Bean Huo <beanhuo@micron.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/trace.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/host/trace.h b/drivers/nvme/host/trace.h
+index 37c7f4c89f92..6f0eaf6a1528 100644
+--- a/drivers/nvme/host/trace.h
++++ b/drivers/nvme/host/trace.h
+@@ -98,7 +98,7 @@ TRACE_EVENT(nvme_complete_rq,
+ TP_fast_assign(
+ __entry->ctrl_id = nvme_req(req)->ctrl->instance;
+ __entry->qid = nvme_req_qid(req);
+- __entry->cid = req->tag;
++ __entry->cid = nvme_req(req)->cmd->common.command_id;
+ __entry->result = le64_to_cpu(nvme_req(req)->result.u64);
+ __entry->retries = nvme_req(req)->retries;
+ __entry->flags = nvme_req(req)->flags;
+--
+2.35.1
+
--- /dev/null
+From 77fd78fb0bc2a7aaaebf5da71dce9ca9d057e6c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 May 2022 09:44:46 +0530
+Subject: of: check previous kernel's ima-kexec-buffer against memory bounds
+
+From: Vaibhav Jain <vaibhav@linux.ibm.com>
+
+[ Upstream commit cbf9c4b9617b6767886a913705ca14b7600c77db ]
+
+Presently ima_get_kexec_buffer() doesn't check if the previous kernel's
+ima-kexec-buffer lies outside the addressable memory range. This can result
+in a kernel panic if the new kernel is booted with 'mem=X' arg and the
+ima-kexec-buffer was allocated beyond that range by the previous kernel.
+The panic is usually of the form below:
+
+$ sudo kexec --initrd initrd vmlinux --append='mem=16G'
+
+<snip>
+ BUG: Unable to handle kernel data access on read at 0xc000c01fff7f0000
+ Faulting instruction address: 0xc000000000837974
+ Oops: Kernel access of bad area, sig: 11 [#1]
+<snip>
+ NIP [c000000000837974] ima_restore_measurement_list+0x94/0x6c0
+ LR [c00000000083b55c] ima_load_kexec_buffer+0xac/0x160
+ Call Trace:
+ [c00000000371fa80] [c00000000083b55c] ima_load_kexec_buffer+0xac/0x160
+ [c00000000371fb00] [c0000000020512c4] ima_init+0x80/0x108
+ [c00000000371fb70] [c0000000020514dc] init_ima+0x4c/0x120
+ [c00000000371fbf0] [c000000000012240] do_one_initcall+0x60/0x2c0
+ [c00000000371fcc0] [c000000002004ad0] kernel_init_freeable+0x344/0x3ec
+ [c00000000371fda0] [c0000000000128a4] kernel_init+0x34/0x1b0
+ [c00000000371fe10] [c00000000000ce64] ret_from_kernel_thread+0x5c/0x64
+ Instruction dump:
+ f92100b8 f92100c0 90e10090 910100a0 4182050c 282a0017 3bc00000 40810330
+ 7c0802a6 fb610198 7c9b2378 f80101d0 <a1240000> 2c090001 40820614 e9240010
+ ---[ end trace 0000000000000000 ]---
+
+Fix this issue by checking returned PFN range of previous kernel's
+ima-kexec-buffer with page_is_ram() to ensure correct memory bounds.
+
+Fixes: 467d27824920 ("powerpc: ima: get the kexec buffer passed by the previous kernel")
+Cc: Frank Rowand <frowand.list@gmail.com>
+Cc: Prakhar Srivastava <prsriva@linux.microsoft.com>
+Cc: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
+Cc: Thiago Jung Bauermann <bauerman@linux.ibm.com>
+Cc: Rob Herring <robh@kernel.org>
+Cc: Ritesh Harjani <ritesh.list@gmail.com>
+Cc: Robin Murphy <robin.murphy@arm.com>
+Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20220531041446.3334259-1-vaibhav@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/kexec.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c
+index 8d374cc552be..91b04b04eec4 100644
+--- a/drivers/of/kexec.c
++++ b/drivers/of/kexec.c
+@@ -126,6 +126,7 @@ int ima_get_kexec_buffer(void **addr, size_t *size)
+ {
+ int ret, len;
+ unsigned long tmp_addr;
++ unsigned long start_pfn, end_pfn;
+ size_t tmp_size;
+ const void *prop;
+
+@@ -140,6 +141,22 @@ int ima_get_kexec_buffer(void **addr, size_t *size)
+ if (ret)
+ return ret;
+
++ /* Do some sanity on the returned size for the ima-kexec buffer */
++ if (!tmp_size)
++ return -ENOENT;
++
++ /*
++ * Calculate the PFNs for the buffer and ensure
++ * they are with in addressable memory.
++ */
++ start_pfn = PHYS_PFN(tmp_addr);
++ end_pfn = PHYS_PFN(tmp_addr + tmp_size - 1);
++ if (!page_is_ram(start_pfn) || !page_is_ram(end_pfn)) {
++ pr_warn("IMA buffer at 0x%lx, size = 0x%zx beyond memory\n",
++ tmp_addr, tmp_size);
++ return -EINVAL;
++ }
++
+ *addr = __va(tmp_addr);
+ *size = tmp_size;
+
+--
+2.35.1
+
--- /dev/null
+From c509e785e617c6d5af4e9b07374d388d59b9d65a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Jul 2022 09:44:49 +0800
+Subject: of: device: Fix missing of_node_put() in of_dma_set_restricted_buffer
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit d17e37c41b7ed38459957a5d2968ba61516fd5c2 ]
+
+We should use of_node_put() for the reference 'node' returned by
+of_parse_phandle() which will increase the refcount.
+
+Fixes: fec9b625095f ("of: Add plumbing for restricted DMA pool")
+Co-authored-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Liang He <windhl@126.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20220702014449.263772-1-windhl@126.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/device.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/of/device.c b/drivers/of/device.c
+index 874f031442dc..75b6cbffa755 100644
+--- a/drivers/of/device.c
++++ b/drivers/of/device.c
+@@ -81,8 +81,11 @@ of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)
+ * restricted-dma-pool region is allowed.
+ */
+ if (of_device_is_compatible(node, "restricted-dma-pool") &&
+- of_device_is_available(node))
++ of_device_is_available(node)) {
++ of_node_put(node);
+ break;
++ }
++ of_node_put(node);
+ }
+
+ /*
+--
+2.35.1
+
--- /dev/null
+From 8879050f27300f0f7ec52a52c8417471d7e2df24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Aug 2022 12:05:06 +0000
+Subject: of/fdt: declared return type does not match actual return type
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xu Qiang <xuqiang36@huawei.com>
+
+[ Upstream commit 7913145afa51bbed9eaf8e5b4ee55fa9884a71e5 ]
+
+The commit 649cab56de8e (“of: properly check for error returned
+by fdt_get_name()”) changed the return value type from bool to int,
+but forgot to change the return value simultaneously.
+
+populate_node was only called in unflatten_dt_nodes, and returns
+with values greater than or equal to 0 were discarded without further
+processing. Considering that return 0 usually indicates success,
+return 0 instead of return true.
+
+Fixes: 649cab56de8e (“of: properly check for error returned by fdt_get_name()”)
+Signed-off-by: Xu Qiang <xuqiang36@huawei.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20220801120506.11461-2-xuqiang36@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/fdt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
+index 0f30496ce80b..d624e8b185aa 100644
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -246,7 +246,7 @@ static int populate_node(const void *blob,
+ }
+
+ *pnp = np;
+- return true;
++ return 0;
+ }
+
+ static void reverse_nodes(struct device_node *parent)
+--
+2.35.1
+
--- /dev/null
+From c7b00b515419f98cc32abd5d3dd3a081465afafe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 20:31:51 +0800
+Subject: opp: Fix error check in dev_pm_opp_attach_genpd()
+
+From: Tang Bin <tangbin@cmss.chinamobile.com>
+
+[ Upstream commit 4ea9496cbc959eb5c78f3e379199aca9ef4e386b ]
+
+dev_pm_domain_attach_by_name() may return NULL in some cases,
+so IS_ERR() doesn't meet the requirements. Thus fix it.
+
+Fixes: 6319aee10e53 ("opp: Attach genpds to devices from within OPP core")
+Signed-off-by: Tang Bin <tangbin@cmss.chinamobile.com>
+[ Viresh: Replace ENODATA with ENODEV ]
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/opp/core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/opp/core.c b/drivers/opp/core.c
+index 740407252298..e154b18ec4b1 100644
+--- a/drivers/opp/core.c
++++ b/drivers/opp/core.c
+@@ -2413,8 +2413,8 @@ struct opp_table *dev_pm_opp_attach_genpd(struct device *dev,
+ }
+
+ virt_dev = dev_pm_domain_attach_by_name(dev, *name);
+- if (IS_ERR(virt_dev)) {
+- ret = PTR_ERR(virt_dev);
++ if (IS_ERR_OR_NULL(virt_dev)) {
++ ret = PTR_ERR(virt_dev) ? : -ENODEV;
+ dev_err(dev, "Couldn't attach to pm_domain: %d\n", ret);
+ goto err;
+ }
+--
+2.35.1
+
--- /dev/null
+From 694e818c66c3368ef78d16987874beeea2075c6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 17:34:12 +0300
+Subject: PCI: dwc: Add unroll iATU space support to dw_pcie_disable_atu()
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+[ Upstream commit d1cf738f2b65a5640234e1da90a68d3523fbed83 ]
+
+dw_pcie_disable_atu() was introduced by f8aed6ec624f ("PCI: dwc:
+designware: Add EP mode support") and supported only the viewport version
+of the iATU CSRs.
+
+DW PCIe IP cores v4.80a and newer also support unrolled iATU/eDMA space.
+Callers of dw_pcie_disable_atu(), including pci_epc_ops.clear_bar(),
+pci_epc_ops.unmap_addr(), and dw_pcie_setup_rc(), don't work correctly when
+it is enabled.
+
+Add dw_pcie_disable_atu() support for controllers with unrolled iATU CSRs
+enabled.
+
+[bhelgaas: commit log]
+Fixes: f8aed6ec624f ("PCI: dwc: designware: Add EP mode support")
+Link: https://lore.kernel.org/r/20220624143428.8334-3-Sergey.Semin@baikalelectronics.ru
+Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-designware.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
+index d92c8a25094f..84fef21efdbc 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.c
++++ b/drivers/pci/controller/dwc/pcie-designware.c
+@@ -491,7 +491,7 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
+ void dw_pcie_disable_atu(struct dw_pcie *pci, int index,
+ enum dw_pcie_region_type type)
+ {
+- int region;
++ u32 region;
+
+ switch (type) {
+ case DW_PCIE_REGION_INBOUND:
+@@ -504,8 +504,18 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, int index,
+ return;
+ }
+
+- dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, region | index);
+- dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, ~(u32)PCIE_ATU_ENABLE);
++ if (pci->iatu_unroll_enabled) {
++ if (region == PCIE_ATU_REGION_INBOUND) {
++ dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
++ ~(u32)PCIE_ATU_ENABLE);
++ } else {
++ dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
++ ~(u32)PCIE_ATU_ENABLE);
++ }
++ } else {
++ dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, region | index);
++ dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, ~(u32)PCIE_ATU_ENABLE);
++ }
+ }
+
+ int dw_pcie_wait_for_link(struct dw_pcie *pci)
+--
+2.35.1
+
--- /dev/null
+From 9335e941aa77d893c48a2c2e91b88d13ccfc33c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 17:34:16 +0300
+Subject: PCI: dwc: Always enable CDM check if "snps,enable-cdm-check" exists
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+[ Upstream commit ec7b952f453ce7eabe7e1bea584626934d44f668 ]
+
+If the "snps,enable-cdm-check" property exists, we should enable the CDM
+check. But previously dw_pcie_setup() could exit before doing so if the
+"num-lanes" property was absent or invalid.
+
+Move the CDM enable earlier so we do it regardless of whether "num-lanes"
+is present.
+
+[bhelgaas: commit log]
+Fixes: 07f123def73e ("PCI: dwc: Add support to enable CDM register check")
+Link: https://lore.kernel.org/r/20220624143428.8334-7-Sergey.Semin@baikalelectronics.ru
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Vidya Sagar <vidyas@nvidia.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-designware.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
+index 347251bf87d0..5848cc520b52 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.c
++++ b/drivers/pci/controller/dwc/pcie-designware.c
+@@ -740,6 +740,13 @@ void dw_pcie_setup(struct dw_pcie *pci)
+ val |= PORT_LINK_DLL_LINK_EN;
+ dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
+
++ if (of_property_read_bool(np, "snps,enable-cdm-check")) {
++ val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
++ val |= PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS |
++ PCIE_PL_CHK_REG_CHK_REG_START;
++ dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val);
++ }
++
+ of_property_read_u32(np, "num-lanes", &pci->num_lanes);
+ if (!pci->num_lanes) {
+ dev_dbg(pci->dev, "Using h/w default number of lanes\n");
+@@ -786,11 +793,4 @@ void dw_pcie_setup(struct dw_pcie *pci)
+ break;
+ }
+ dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
+-
+- if (of_property_read_bool(np, "snps,enable-cdm-check")) {
+- val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
+- val |= PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS |
+- PCIE_PL_CHK_REG_CHK_REG_START;
+- dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val);
+- }
+ }
+--
+2.35.1
+
--- /dev/null
+From ce9ae50f39cc178c55cd09cc1e7ea4f385f0da7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 17:34:15 +0300
+Subject: PCI: dwc: Deallocate EPC memory on dw_pcie_ep_init() errors
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+[ Upstream commit 8161e9626b50892eaedbd8070ecb1586ecedb109 ]
+
+If dw_pcie_ep_init() fails to perform any action after the EPC memory is
+initialized and the MSI memory region is allocated, the latter parts won't
+be undone thus causing a memory leak. Add a cleanup-on-error path to fix
+these leaks.
+
+[bhelgaas: commit log]
+Fixes: 2fd0c9d966cc ("PCI: designware-ep: Pre-allocate memory for MSI in dw_pcie_ep_init")
+Link: https://lore.kernel.org/r/20220624143428.8334-6-Sergey.Semin@baikalelectronics.ru
+Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../pci/controller/dwc/pcie-designware-ep.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
+index 0eda8236c125..13c2e73f0eaf 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
+@@ -780,8 +780,9 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
+ ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
+ epc->mem->window.page_size);
+ if (!ep->msi_mem) {
++ ret = -ENOMEM;
+ dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n");
+- return -ENOMEM;
++ goto err_exit_epc_mem;
+ }
+
+ if (ep->ops->get_features) {
+@@ -790,6 +791,19 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
+ return 0;
+ }
+
+- return dw_pcie_ep_init_complete(ep);
++ ret = dw_pcie_ep_init_complete(ep);
++ if (ret)
++ goto err_free_epc_mem;
++
++ return 0;
++
++err_free_epc_mem:
++ pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
++ epc->mem->window.page_size);
++
++err_exit_epc_mem:
++ pci_epc_mem_exit(epc);
++
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(dw_pcie_ep_init);
+--
+2.35.1
+
--- /dev/null
+From 7d4485bbe39e7044945db86dc25eda0ad1c94b82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 17:34:13 +0300
+Subject: PCI: dwc: Disable outbound windows only for controllers using iATU
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+[ Upstream commit d60a2e281e9de2b2f67343b2e39417ca0f4fd54e ]
+
+Some DWC-based controllers (e.g., pcie-al.c and pci-keystone.c, identified
+by the fact that they override the default dw_child_pcie_ops) use their own
+address translation approach instead of the DWC internal ATU (iATU). For
+those controllers, skip disabling the iATU outbound windows.
+
+[bhelgaas: commit log, update multiple window comment]
+Fixes: 458ad06c4cdd ("PCI: dwc: Ensure all outbound ATU windows are reset")
+Link: https://lore.kernel.org/r/20220624143428.8334-4-Sergey.Semin@baikalelectronics.ru
+Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-designware-host.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
+index bc9a7df130ef..d0d768f22ac3 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -543,7 +543,6 @@ static struct pci_ops dw_pcie_ops = {
+
+ void dw_pcie_setup_rc(struct pcie_port *pp)
+ {
+- int i;
+ u32 val, ctrl, num_ctrls;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+
+@@ -594,19 +593,22 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
+ PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
+ dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
+
+- /* Ensure all outbound windows are disabled so there are multiple matches */
+- for (i = 0; i < pci->num_ob_windows; i++)
+- dw_pcie_disable_atu(pci, i, DW_PCIE_REGION_OUTBOUND);
+-
+ /*
+ * If the platform provides its own child bus config accesses, it means
+ * the platform uses its own address translation component rather than
+ * ATU, so we should not program the ATU here.
+ */
+ if (pp->bridge->child_ops == &dw_child_pcie_ops) {
+- int atu_idx = 0;
++ int i, atu_idx = 0;
+ struct resource_entry *entry;
+
++ /*
++ * Disable all outbound windows to make sure a transaction
++ * can't match multiple windows.
++ */
++ for (i = 0; i < pci->num_ob_windows; i++)
++ dw_pcie_disable_atu(pci, i, DW_PCIE_REGION_OUTBOUND);
++
+ /* Get last memory resource entry */
+ resource_list_for_each_entry(entry, &pp->bridge->windows) {
+ if (resource_type(entry->res) != IORESOURCE_MEM)
+--
+2.35.1
+
--- /dev/null
+From 6a8c17fa3913efac19863d7b34294d0ad8b2a259 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 17:34:14 +0300
+Subject: PCI: dwc: Set INCREASE_REGION_SIZE flag based on limit address
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+[ Upstream commit 777e7c3ab73036105e6fc4a67ed950179dbffbab ]
+
+We program the 64-bit ATU limit address (in PCIE_ATU_LIMIT/
+PCIE_ATU_UPPER_LIMIT or PCIE_ATU_UNR_LOWER_LIMIT/PCIE_ATU_UNR_UPPER_LIMIT),
+but in addition, the PCIE_ATU_INCREASE_REGION_SIZE bit must be set if the
+upper 32 bits of the limit address differ from the upper 32 bits of the
+base address (see [1,2]).
+
+5b4cf0f65324 ("PCI: dwc: Add upper limit address for outbound iATU") set
+PCIE_ATU_INCREASE_REGION_SIZE, but only when the *size* was greater than
+4GB. It did not set it when a smaller region crossed a 4GB boundary, e.g.,
+[mem 0x0_f0000000-0x1_0fffffff].
+
+Set PCIE_ATU_INCREASE_REGION_SIZE whenever PCIE_ATU_UPPER_LIMIT is
+greater than PCIE_ATU_UPPER_BASE.
+
+[1] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port,
+ v5.40a, March 2019, fig.3-36, p.175
+[2] DesignWare Cores PCI Express Controller Databook - DWC PCIe Root Port,
+ v5.40a, March 2019, fig.3-37, p.176
+
+[bhelgaas: commit log]
+Fixes: 5b4cf0f65324 ("PCI: dwc: Add upper limit address for outbound iATU")
+Link: https://lore.kernel.org/r/20220624143428.8334-5-Sergey.Semin@baikalelectronics.ru
+Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-designware.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
+index 84fef21efdbc..347251bf87d0 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.c
++++ b/drivers/pci/controller/dwc/pcie-designware.c
+@@ -287,8 +287,8 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, u8 func_no,
+ dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET,
+ upper_32_bits(pci_addr));
+ val = type | PCIE_ATU_FUNC_NUM(func_no);
+- val = upper_32_bits(size - 1) ?
+- val | PCIE_ATU_INCREASE_REGION_SIZE : val;
++ if (upper_32_bits(limit_addr) > upper_32_bits(cpu_addr))
++ val |= PCIE_ATU_INCREASE_REGION_SIZE;
+ if (pci->version == 0x490A)
+ val = dw_pcie_enable_ecrc(val);
+ dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, val);
+@@ -315,6 +315,7 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,
+ u64 pci_addr, u64 size)
+ {
+ u32 retries, val;
++ u64 limit_addr;
+
+ if (pci->ops && pci->ops->cpu_addr_fixup)
+ cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr);
+@@ -325,6 +326,8 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,
+ return;
+ }
+
++ limit_addr = cpu_addr + size - 1;
++
+ dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT,
+ PCIE_ATU_REGION_OUTBOUND | index);
+ dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_BASE,
+@@ -332,17 +335,18 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,
+ dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_BASE,
+ upper_32_bits(cpu_addr));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_LIMIT,
+- lower_32_bits(cpu_addr + size - 1));
++ lower_32_bits(limit_addr));
+ if (pci->version >= 0x460A)
+ dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_LIMIT,
+- upper_32_bits(cpu_addr + size - 1));
++ upper_32_bits(limit_addr));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET,
+ lower_32_bits(pci_addr));
+ dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET,
+ upper_32_bits(pci_addr));
+ val = type | PCIE_ATU_FUNC_NUM(func_no);
+- val = ((upper_32_bits(size - 1)) && (pci->version >= 0x460A)) ?
+- val | PCIE_ATU_INCREASE_REGION_SIZE : val;
++ if (upper_32_bits(limit_addr) > upper_32_bits(cpu_addr) &&
++ pci->version >= 0x460A)
++ val |= PCIE_ATU_INCREASE_REGION_SIZE;
+ if (pci->version == 0x490A)
+ val = dw_pcie_enable_ecrc(val);
+ dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, val);
+--
+2.35.1
+
--- /dev/null
+From 7d2662847181097bc35f2bada3963185627ff3b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 17:34:11 +0300
+Subject: PCI: dwc: Stop link on host_init errors and de-initialization
+
+From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+
+[ Upstream commit 113fa857b74c947137d845e7e635afcf6a59c43a ]
+
+It's logically correct to undo everything that was done when an error is
+discovered or in the corresponding cleanup counterpart. Otherwise the host
+controller will be left in an undetermined state. Since the link is set up
+in the host_init method, deactivate it there in the cleanup-on-error block
+and stop the link in the antagonistic routine - dw_pcie_host_deinit(). Link
+deactivation is platform-specific and should be implemented in
+dw_pcie_ops.stop_link().
+
+Fixes: 886a9c134755 ("PCI: dwc: Move link handling into common code")
+Link: https://lore.kernel.org/r/20220624143428.8334-2-Sergey.Semin@baikalelectronics.ru
+Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../pci/controller/dwc/pcie-designware-host.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
+index 9979302532b7..bc9a7df130ef 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -421,8 +421,14 @@ int dw_pcie_host_init(struct pcie_port *pp)
+ bridge->sysdata = pp;
+
+ ret = pci_host_probe(bridge);
+- if (!ret)
+- return 0;
++ if (ret)
++ goto err_stop_link;
++
++ return 0;
++
++err_stop_link:
++ if (pci->ops && pci->ops->stop_link)
++ pci->ops->stop_link(pci);
+
+ err_free_msi:
+ if (pp->has_msi_ctrl)
+@@ -433,8 +439,14 @@ EXPORT_SYMBOL_GPL(dw_pcie_host_init);
+
+ void dw_pcie_host_deinit(struct pcie_port *pp)
+ {
++ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
++
+ pci_stop_root_bus(pp->bridge->bus);
+ pci_remove_root_bus(pp->bridge->bus);
++
++ if (pci->ops && pci->ops->stop_link)
++ pci->ops->stop_link(pci);
++
+ if (pp->has_msi_ctrl)
+ dw_pcie_free_msi(pp);
+ }
+--
+2.35.1
+
--- /dev/null
+From 656e18713fae3399aab04bd0e1afc2d425d0ba58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jun 2022 13:09:24 +0900
+Subject: PCI: endpoint: Don't stop controller when unbinding endpoint function
+
+From: Shunsuke Mie <mie@igel.co.jp>
+
+[ Upstream commit 1bc2b7bfba6e2f64edf5e246f3af2967261f6c3d ]
+
+Unbinding an endpoint function from the endpoint controller shouldn't stop
+the controller. This is especially a problem for multi-function endpoints
+where other endpoints may still be active.
+
+Don't stop the controller when unbinding one of its endpoints. Normally
+the controller is stopped via configfs.
+
+Fixes: 349e7a85b25f ("PCI: endpoint: functions: Add an EP function to test PCI")
+Link: https://lore.kernel.org/r/20220622040924.113279-1-mie@igel.co.jp
+Signed-off-by: Shunsuke Mie <mie@igel.co.jp>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-test.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index 5b833f00e980..a5ed779b0a51 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -627,7 +627,6 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
+
+ cancel_delayed_work(&epf_test->cmd_handler);
+ pci_epf_test_clean_dma_chan(epf_test);
+- pci_epc_stop(epc);
+ for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
+ epf_bar = &epf->bar[bar];
+
+--
+2.35.1
+
--- /dev/null
+From a0b8d060f23b8e312d6e7b82cdfd606b78f728f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 08:12:58 +0400
+Subject: PCI: mediatek-gen3: Fix refcount leak in mtk_pcie_init_irq_domains()
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit bf038503d5fe90189743124233fe7aeb0984e961 ]
+
+of_get_child_by_name() returns a node pointer with refcount incremented, so
+we should use of_node_put() on it when we don't need it anymore.
+
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 814cceebba9b ("PCI: mediatek-gen3: Add INTx support")
+Link: https://lore.kernel.org/r/20220601041259.56185-1-linmq006@gmail.com
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Miles Chen <miles.chen@mediatek.com>
+Acked-by: Jianjun Wang <jianjun.wang@mediatek.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-mediatek-gen3.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
+index 5d9fd36b02d1..a02c466a597c 100644
+--- a/drivers/pci/controller/pcie-mediatek-gen3.c
++++ b/drivers/pci/controller/pcie-mediatek-gen3.c
+@@ -600,7 +600,8 @@ static int mtk_pcie_init_irq_domains(struct mtk_gen3_pcie *pcie)
+ &intx_domain_ops, pcie);
+ if (!pcie->intx_domain) {
+ dev_err(dev, "failed to create INTx IRQ domain\n");
+- return -ENODEV;
++ ret = -ENODEV;
++ goto out_put_node;
+ }
+
+ /* Setup MSI */
+@@ -623,13 +624,15 @@ static int mtk_pcie_init_irq_domains(struct mtk_gen3_pcie *pcie)
+ goto err_msi_domain;
+ }
+
++ of_node_put(intc_node);
+ return 0;
+
+ err_msi_domain:
+ irq_domain_remove(pcie->msi_bottom_domain);
+ err_msi_bottom_domain:
+ irq_domain_remove(pcie->intx_domain);
+-
++out_put_node:
++ of_node_put(intc_node);
+ return ret;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From c44815bafdfea5d877e8afa944999f04cdbe8f98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jun 2022 09:51:23 +0400
+Subject: PCI: microchip: Fix refcount leak in mc_pcie_init_irq_domains()
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit f030304fdeb87ec8f1b518c73703214aec6cc24a ]
+
+of_get_next_child() returns a node pointer with refcount incremented, so we
+should use of_node_put() on it when we don't need it anymore.
+
+mc_pcie_init_irq_domains() only calls of_node_put() in the normal path,
+missing it in some error paths. Add missing of_node_put() to avoid
+refcount leak.
+
+Fixes: 6f15a9c9f941 ("PCI: microchip: Add Microchip PolarFire PCIe controller driver")
+Link: https://lore.kernel.org/r/20220605055123.59127-1-linmq006@gmail.com
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-microchip-host.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pci/controller/pcie-microchip-host.c b/drivers/pci/controller/pcie-microchip-host.c
+index 2c52a8cef726..932b1c182149 100644
+--- a/drivers/pci/controller/pcie-microchip-host.c
++++ b/drivers/pci/controller/pcie-microchip-host.c
+@@ -904,6 +904,7 @@ static int mc_pcie_init_irq_domains(struct mc_pcie *port)
+ &event_domain_ops, port);
+ if (!port->event_domain) {
+ dev_err(dev, "failed to get event domain\n");
++ of_node_put(pcie_intc_node);
+ return -ENOMEM;
+ }
+
+@@ -913,6 +914,7 @@ static int mc_pcie_init_irq_domains(struct mc_pcie *port)
+ &intx_domain_ops, port);
+ if (!port->intx_domain) {
+ dev_err(dev, "failed to get an INTx IRQ domain\n");
++ of_node_put(pcie_intc_node);
+ return -ENOMEM;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From ccae234849891d327002973de999d14a629e8a09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jan 2022 08:18:19 +0100
+Subject: PCI/portdrv: Don't disable AER reporting in
+ get_port_device_capability()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Stefan Roese <sr@denx.de>
+
+[ Upstream commit 8795e182b02dc87e343c79e73af6b8b7f9c5e635 ]
+
+AER reporting is currently disabled in the DevCtl registers of all non Root
+Port PCIe devices on systems using pcie_ports_native || host->native_aer,
+disabling AER completely in such systems. This is because 2bd50dd800b5
+("PCI: PCIe: Disable PCIe port services during port initialization"), added
+a call to pci_disable_pcie_error_reporting() *after* the AER setup was
+completed for the PCIe device tree.
+
+Here a longer analysis about the current status of AER enabling /
+disabling upon bootup provided by Bjorn:
+
+ pcie_portdrv_probe
+ pcie_port_device_register
+ get_port_device_capability
+ pci_disable_pcie_error_reporting
+ clear CERE NFERE FERE URRE # <-- disable for RP USP DSP
+ pcie_device_init
+ device_register # new AER service device
+ aer_probe
+ aer_enable_rootport # RP only
+ set_downstream_devices_error_reporting
+ set_device_error_reporting # self (RP)
+ if (RP || USP || DSP)
+ pci_enable_pcie_error_reporting
+ set CERE NFERE FERE URRE # <-- enable for RP
+ pci_walk_bus
+ set_device_error_reporting
+ if (RP || USP || DSP)
+ pci_enable_pcie_error_reporting
+ set CERE NFERE FERE URRE # <-- enable for USP DSP
+
+In a typical Root Port -> Endpoint hierarchy, the above:
+ - Disables Error Reporting for the Root Port,
+ - Enables Error Reporting for the Root Port,
+ - Does NOT enable Error Reporting for the Endpoint because it is not a
+ Root Port or Switch Port.
+
+In a deeper Root Port -> Upstream Switch Port -> Downstream Switch
+Port -> Endpoint hierarchy:
+ - Disables Error Reporting for the Root Port,
+ - Enables Error Reporting for the Root Port,
+ - Enables Error Reporting for both Switch Ports,
+ - Does NOT enable Error Reporting for the Endpoint because it is not a
+ Root Port or Switch Port,
+ - Disables Error Reporting for the Switch Ports when pcie_portdrv_probe()
+ claims them. AER does not re-enable it because these are not Root
+ Ports.
+
+Remove this call to pci_disable_pcie_error_reporting() from
+get_port_device_capability(), leaving the already enabled AER configuration
+intact. With this change, AER is enabled in the Root Port and the PCIe
+switch upstream and downstream ports. Only the PCIe Endpoints don't have
+AER enabled yet. A follow-up patch will take care of this Endpoint
+enabling.
+
+Fixes: 2bd50dd800b5 ("PCI: PCIe: Disable PCIe port services during port initialization")
+Link: https://lore.kernel.org/r/20220125071820.2247260-3-sr@denx.de
+Signed-off-by: Stefan Roese <sr@denx.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Pali Rohár <pali@kernel.org>
+Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
+Cc: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
+Cc: Michal Simek <michal.simek@xilinx.com>
+Cc: Yao Hongbo <yaohongbo@linux.alibaba.com>
+Cc: Naveen Naidu <naveennaidu479@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/portdrv_core.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
+index 604feeb84ee4..1ac7fec47d6f 100644
+--- a/drivers/pci/pcie/portdrv_core.c
++++ b/drivers/pci/pcie/portdrv_core.c
+@@ -222,15 +222,8 @@ static int get_port_device_capability(struct pci_dev *dev)
+
+ #ifdef CONFIG_PCIEAER
+ if (dev->aer_cap && pci_aer_available() &&
+- (pcie_ports_native || host->native_aer)) {
++ (pcie_ports_native || host->native_aer))
+ services |= PCIE_PORT_SERVICE_AER;
+-
+- /*
+- * Disable AER on this port in case it's been enabled by the
+- * BIOS (the AER service driver will enable it when necessary).
+- */
+- pci_disable_pcie_error_reporting(dev);
+- }
+ #endif
+
+ /* Root Ports and Root Complex Event Collectors may generate PMEs */
+--
+2.35.1
+
--- /dev/null
+From 6e51fe80f2d8ce98618f32e5b4d9b0dc116f3b9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 9 Jul 2022 00:27:43 +0200
+Subject: PCI: qcom: Set up rev 2.1.0 PARF_PHY before enabling clocks
+
+From: Christian Marangi <ansuelsmth@gmail.com>
+
+[ Upstream commit 38f897ae3d44900f627cad708a15db498ce2ca31 ]
+
+We currently enable clocks BEFORE we write to PARF_PHY_CTRL reg to enable
+clocks and resets. This causes the driver to never set to a ready state
+with the error 'Phy link never came up'.
+
+This is caused by the PHY clock getting enabled before setting the required
+bits in the PARF regs.
+
+A workaround for this was set but with this new discovery we can drop
+the workaround and use a proper solution to the problem by just enabling
+the clock only AFTER the PARF_PHY_CTRL bit is set.
+
+This correctly sets up the PCIe link and makes it usable even when a
+bootloader leaves the PCIe link in an undefined state.
+
+Fixes: 82a823833f4e ("PCI: qcom: Add Qualcomm PCIe controller driver")
+Link: https://lore.kernel.org/r/20220708222743.27019-1-ansuelsmth@gmail.com
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-qcom.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
+index ed55421eb9ba..ab04818f6ed9 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -337,8 +337,6 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
+ reset_control_assert(res->ext_reset);
+ reset_control_assert(res->phy_reset);
+
+- writel(1, pcie->parf + PCIE20_PARF_PHY_CTRL);
+-
+ ret = regulator_bulk_enable(ARRAY_SIZE(res->supplies), res->supplies);
+ if (ret < 0) {
+ dev_err(dev, "cannot enable regulators\n");
+@@ -381,15 +379,15 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
+ goto err_deassert_axi;
+ }
+
+- ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
+- if (ret)
+- goto err_clks;
+-
+ /* enable PCIe clocks and resets */
+ val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
+ val &= ~BIT(0);
+ writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+
++ ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
++ if (ret)
++ goto err_clks;
++
+ if (of_device_is_compatible(node, "qcom,pcie-ipq8064") ||
+ of_device_is_compatible(node, "qcom,pcie-ipq8064-v2")) {
+ writel(PCS_DEEMPH_TX_DEEMPH_GEN1(24) |
+--
+2.35.1
+
--- /dev/null
+From 7946f7d6ed89bce4ff3120253e5199dbe4af6994 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 19:50:50 +0530
+Subject: PCI: tegra194: Fix link up retry sequence
+
+From: Vidya Sagar <vidyas@nvidia.com>
+
+[ Upstream commit e05fd6ae77c3e2cc0dba283005d24b6d56d2b1fa ]
+
+Add the missing DLF capability offset while clearing DL_FEATURE_EXCHANGE_EN
+bit during link up retry.
+
+Link: https://lore.kernel.org/r/20220721142052.25971-15-vidyas@nvidia.com
+Fixes: 56e15a238d92 ("PCI: tegra: Add Tegra194 PCIe support")
+Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-tegra194.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
+index 85d405057ba8..a479e58cc8fb 100644
+--- a/drivers/pci/controller/dwc/pcie-tegra194.c
++++ b/drivers/pci/controller/dwc/pcie-tegra194.c
+@@ -978,7 +978,7 @@ static int tegra194_pcie_start_link(struct dw_pcie *pci)
+ offset = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_DLF);
+ val = dw_pcie_readl_dbi(pci, offset + PCI_DLF_CAP);
+ val &= ~PCI_DLF_EXCHANGE_ENABLE;
+- dw_pcie_writel_dbi(pci, offset, val);
++ dw_pcie_writel_dbi(pci, offset + PCI_DLF_CAP, val);
+
+ tegra194_pcie_host_init(pp);
+ dw_pcie_setup_rc(pp);
+--
+2.35.1
+
--- /dev/null
+From 50517f684e98466f6d08486d812d1e365745c43f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 07:19:08 +0400
+Subject: PCI: tegra194: Fix PM error handling in tegra_pcie_config_ep()
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit e8fbd344a5ea62663554b8546b6bf9f88b93785a ]
+
+pm_runtime_enable() will increase power disable depth. If
+dw_pcie_ep_init() fails, we should use pm_runtime_disable() to balance it
+with pm_runtime_enable().
+
+Add missing pm_runtime_disable() for tegra_pcie_config_ep().
+
+Fixes: c57247f940e8 ("PCI: tegra: Add support for PCIe endpoint mode in Tegra194")
+Link: https://lore.kernel.org/r/20220602031910.55859-1-linmq006@gmail.com
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Vidya Sagar <vidyas@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-tegra194.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
+index b1b5f836a806..0888c3726414 100644
+--- a/drivers/pci/controller/dwc/pcie-tegra194.c
++++ b/drivers/pci/controller/dwc/pcie-tegra194.c
+@@ -1951,6 +1951,7 @@ static int tegra_pcie_config_ep(struct tegra194_pcie *pcie,
+ if (ret) {
+ dev_err(dev, "Failed to initialize DWC Endpoint subsystem: %d\n",
+ ret);
++ pm_runtime_disable(dev);
+ return ret;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 6703589cc91a61d0839beb3d835f25d00aab695c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 19:50:46 +0530
+Subject: PCI: tegra194: Fix Root Port interrupt handling
+
+From: Vidya Sagar <vidyas@nvidia.com>
+
+[ Upstream commit 6646e99bcec627e866bc84365af37942c72b4b76 ]
+
+As part of Root Port interrupt handling, level-0 register is read first and
+based on the bits set in that, corresponding level-1 registers are read for
+further interrupt processing. Since both these values are currently read
+into the same 'val' variable, checking level-0 bits the second time around
+is happening on the 'val' variable value of level-1 register contents
+instead of freshly reading the level-0 value again.
+
+Fix by using different variables to store level-0 and level-1 registers
+contents.
+
+Link: https://lore.kernel.org/r/20220721142052.25971-11-vidyas@nvidia.com
+Fixes: 56e15a238d92 ("PCI: tegra: Add Tegra194 PCIe support")
+Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-tegra194.c | 46 +++++++++++-----------
+ 1 file changed, 22 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
+index 0888c3726414..85d405057ba8 100644
+--- a/drivers/pci/controller/dwc/pcie-tegra194.c
++++ b/drivers/pci/controller/dwc/pcie-tegra194.c
+@@ -352,15 +352,14 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg)
+ struct tegra194_pcie *pcie = arg;
+ struct dw_pcie *pci = &pcie->pci;
+ struct pcie_port *pp = &pci->pp;
+- u32 val, tmp;
++ u32 val, status_l0, status_l1;
+ u16 val_w;
+
+- val = appl_readl(pcie, APPL_INTR_STATUS_L0);
+- if (val & APPL_INTR_STATUS_L0_LINK_STATE_INT) {
+- val = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0);
+- if (val & APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED) {
+- appl_writel(pcie, val, APPL_INTR_STATUS_L1_0_0);
+-
++ status_l0 = appl_readl(pcie, APPL_INTR_STATUS_L0);
++ if (status_l0 & APPL_INTR_STATUS_L0_LINK_STATE_INT) {
++ status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0);
++ appl_writel(pcie, status_l1, APPL_INTR_STATUS_L1_0_0);
++ if (status_l1 & APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED) {
+ /* SBR & Surprise Link Down WAR */
+ val = appl_readl(pcie, APPL_CAR_RESET_OVRD);
+ val &= ~APPL_CAR_RESET_OVRD_CYA_OVERRIDE_CORE_RST_N;
+@@ -376,15 +375,15 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg)
+ }
+ }
+
+- if (val & APPL_INTR_STATUS_L0_INT_INT) {
+- val = appl_readl(pcie, APPL_INTR_STATUS_L1_8_0);
+- if (val & APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS) {
++ if (status_l0 & APPL_INTR_STATUS_L0_INT_INT) {
++ status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_8_0);
++ if (status_l1 & APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS) {
+ appl_writel(pcie,
+ APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS,
+ APPL_INTR_STATUS_L1_8_0);
+ apply_bad_link_workaround(pp);
+ }
+- if (val & APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS) {
++ if (status_l1 & APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS) {
+ appl_writel(pcie,
+ APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS,
+ APPL_INTR_STATUS_L1_8_0);
+@@ -396,25 +395,24 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg)
+ }
+ }
+
+- val = appl_readl(pcie, APPL_INTR_STATUS_L0);
+- if (val & APPL_INTR_STATUS_L0_CDM_REG_CHK_INT) {
+- val = appl_readl(pcie, APPL_INTR_STATUS_L1_18);
+- tmp = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
+- if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMPLT) {
++ if (status_l0 & APPL_INTR_STATUS_L0_CDM_REG_CHK_INT) {
++ status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_18);
++ val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS);
++ if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMPLT) {
+ dev_info(pci->dev, "CDM check complete\n");
+- tmp |= PCIE_PL_CHK_REG_CHK_REG_COMPLETE;
++ val |= PCIE_PL_CHK_REG_CHK_REG_COMPLETE;
+ }
+- if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMP_ERR) {
++ if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMP_ERR) {
+ dev_err(pci->dev, "CDM comparison mismatch\n");
+- tmp |= PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR;
++ val |= PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR;
+ }
+- if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_LOGIC_ERR) {
++ if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_LOGIC_ERR) {
+ dev_err(pci->dev, "CDM Logic error\n");
+- tmp |= PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR;
++ val |= PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR;
+ }
+- dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, tmp);
+- tmp = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_ERR_ADDR);
+- dev_err(pci->dev, "CDM Error Address Offset = 0x%08X\n", tmp);
++ dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val);
++ val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_ERR_ADDR);
++ dev_err(pci->dev, "CDM Error Address Offset = 0x%08X\n", val);
+ }
+
+ return IRQ_HANDLED;
+--
+2.35.1
+
--- /dev/null
+From 6aaea05fc18eb1ee7f96814978fbc4c30c3b9372 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Mar 2022 15:15:05 -0700
+Subject: perf/core: Add perf_clear_branch_entry_bitfields() helper
+
+From: Stephane Eranian <eranian@google.com>
+
+[ Upstream commit bfe4daf850f45d92dcd3da477f0b0456620294c3 ]
+
+Make it simpler to reset all the info fields on the
+perf_branch_entry by adding a helper inline function.
+
+The goal is to centralize the initialization to avoid missing
+a field in case more are added.
+
+Signed-off-by: Stephane Eranian <eranian@google.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20220322221517.2510440-2-eranian@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/intel/lbr.c | 36 +++++++++++++++++-------------------
+ include/linux/perf_event.h | 16 ++++++++++++++++
+ 2 files changed, 33 insertions(+), 19 deletions(-)
+
+diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
+index 1f156098a5bf..4f70fb6c2c1e 100644
+--- a/arch/x86/events/intel/lbr.c
++++ b/arch/x86/events/intel/lbr.c
+@@ -769,6 +769,7 @@ void intel_pmu_lbr_disable_all(void)
+ void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
+ {
+ unsigned long mask = x86_pmu.lbr_nr - 1;
++ struct perf_branch_entry *br = cpuc->lbr_entries;
+ u64 tos = intel_pmu_lbr_tos();
+ int i;
+
+@@ -784,15 +785,11 @@ void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
+
+ rdmsrl(x86_pmu.lbr_from + lbr_idx, msr_lastbranch.lbr);
+
+- cpuc->lbr_entries[i].from = msr_lastbranch.from;
+- cpuc->lbr_entries[i].to = msr_lastbranch.to;
+- cpuc->lbr_entries[i].mispred = 0;
+- cpuc->lbr_entries[i].predicted = 0;
+- cpuc->lbr_entries[i].in_tx = 0;
+- cpuc->lbr_entries[i].abort = 0;
+- cpuc->lbr_entries[i].cycles = 0;
+- cpuc->lbr_entries[i].type = 0;
+- cpuc->lbr_entries[i].reserved = 0;
++ perf_clear_branch_entry_bitfields(br);
++
++ br->from = msr_lastbranch.from;
++ br->to = msr_lastbranch.to;
++ br++;
+ }
+ cpuc->lbr_stack.nr = i;
+ cpuc->lbr_stack.hw_idx = tos;
+@@ -807,6 +804,7 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
+ {
+ bool need_info = false, call_stack = false;
+ unsigned long mask = x86_pmu.lbr_nr - 1;
++ struct perf_branch_entry *br = cpuc->lbr_entries;
+ u64 tos = intel_pmu_lbr_tos();
+ int i;
+ int out = 0;
+@@ -878,15 +876,14 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
+ if (abort && x86_pmu.lbr_double_abort && out > 0)
+ out--;
+
+- cpuc->lbr_entries[out].from = from;
+- cpuc->lbr_entries[out].to = to;
+- cpuc->lbr_entries[out].mispred = mis;
+- cpuc->lbr_entries[out].predicted = pred;
+- cpuc->lbr_entries[out].in_tx = in_tx;
+- cpuc->lbr_entries[out].abort = abort;
+- cpuc->lbr_entries[out].cycles = cycles;
+- cpuc->lbr_entries[out].type = 0;
+- cpuc->lbr_entries[out].reserved = 0;
++ perf_clear_branch_entry_bitfields(br+out);
++ br[out].from = from;
++ br[out].to = to;
++ br[out].mispred = mis;
++ br[out].predicted = pred;
++ br[out].in_tx = in_tx;
++ br[out].abort = abort;
++ br[out].cycles = cycles;
+ out++;
+ }
+ cpuc->lbr_stack.nr = out;
+@@ -951,6 +948,8 @@ static void intel_pmu_store_lbr(struct cpu_hw_events *cpuc,
+ to = rdlbr_to(i, lbr);
+ info = rdlbr_info(i, lbr);
+
++ perf_clear_branch_entry_bitfields(e);
++
+ e->from = from;
+ e->to = to;
+ e->mispred = get_lbr_mispred(info);
+@@ -959,7 +958,6 @@ static void intel_pmu_store_lbr(struct cpu_hw_events *cpuc,
+ e->abort = !!(info & LBR_INFO_ABORT);
+ e->cycles = get_lbr_cycles(info);
+ e->type = get_lbr_br_type(info);
+- e->reserved = 0;
+ }
+
+ cpuc->lbr_stack.nr = i;
+diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
+index af97dd427501..a411080d5169 100644
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -1063,6 +1063,22 @@ static inline void perf_sample_data_init(struct perf_sample_data *data,
+ data->txn = 0;
+ }
+
++/*
++ * Clear all bitfields in the perf_branch_entry.
++ * The to and from fields are not cleared because they are
++ * systematically modified by caller.
++ */
++static inline void perf_clear_branch_entry_bitfields(struct perf_branch_entry *br)
++{
++ br->mispred = 0;
++ br->predicted = 0;
++ br->in_tx = 0;
++ br->abort = 0;
++ br->cycles = 0;
++ br->type = 0;
++ br->reserved = 0;
++}
++
+ extern void perf_output_sample(struct perf_output_handle *handle,
+ struct perf_event_header *header,
+ struct perf_sample_data *data,
+--
+2.35.1
+
--- /dev/null
+From b1e065db79303656a3847c0d287550ff8816f2e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 21:03:30 +0800
+Subject: perf: RISC-V: Add of_node_put() when breaking out of
+ for_each_of_cpu_node()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 491f10d08fdae10a177edf6af4f43b83b293114b ]
+
+In pmu_sbi_setup_irqs(), we should call of_node_put() for the 'cpu'
+when breaking out of for_each_of_cput_node() as its refcount will
+be automatically increased and decreased during the iteration.
+
+Fixes: 4905ec2fb7e6 ("RISC-V: Add sscofpmf extension support")
+Signed-off-by: Liang He <windhl@126.com>
+Reviewed-by: Atish Patra <atishp@rivosinc.com>
+Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
+Link: https://lore.kernel.org/r/20220715130330.443363-1-windhl@126.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/riscv_pmu_sbi.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
+index fab0dd497393..77b826d6c05b 100644
+--- a/drivers/perf/riscv_pmu_sbi.c
++++ b/drivers/perf/riscv_pmu_sbi.c
+@@ -682,12 +682,15 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde
+ child = of_get_compatible_child(cpu, "riscv,cpu-intc");
+ if (!child) {
+ pr_err("Failed to find INTC node\n");
++ of_node_put(cpu);
+ return -ENODEV;
+ }
+ domain = irq_find_host(child);
+ of_node_put(child);
+- if (domain)
++ if (domain) {
++ of_node_put(cpu);
+ break;
++ }
+ }
+ if (!domain) {
+ pr_err("Failed to find INTC IRQ root domain\n");
+--
+2.35.1
+
--- /dev/null
+From 153b3522cf7d5c75ddedb1bd5daa541c7de075ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 14:57:02 +0800
+Subject: perf stat: Revert "perf stat: Add default hybrid events"
+
+From: Kan Liang <kan.liang@linux.intel.com>
+
+[ Upstream commit ace3e31e653e79cae9b047e85f567e6b44c98532 ]
+
+This reverts commit Fixes: ac2dc29edd21f9ec ("perf stat: Add default
+hybrid events")
+
+Between this patch and the reverted patch, the commit 6c1912898ed21bef
+("perf parse-events: Rename parse_events_error functions") and the
+commit 07eafd4e053a41d7 ("perf parse-event: Add init and exit to
+parse_event_error") clean up the parse_events_error_*() codes. The
+related change is also reverted.
+
+The reverted patch is hard to be extended to support new default events,
+e.g., Topdown events, and the existing "--detailed" option on a hybrid
+platform.
+
+A new solution will be proposed in the following patch to enable the
+perf stat default on a hybrid platform.
+
+Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
+Acked-by: Ian Rogers <irogers@google.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Alexander Shishkin <alexander.shishkin@intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20220721065706.2886112-2-zhengjun.xing@linux.intel.com
+Signed-off-by: Xing Zhengjun <zhengjun.xing@linux.intel.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-stat.c | 30 ------------------------------
+ 1 file changed, 30 deletions(-)
+
+diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
+index f058e8cddfa8..e15fd6f9f7ea 100644
+--- a/tools/perf/builtin-stat.c
++++ b/tools/perf/builtin-stat.c
+@@ -1663,12 +1663,6 @@ static int add_default_attributes(void)
+ { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
+ { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES },
+
+-};
+- struct perf_event_attr default_sw_attrs[] = {
+- { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
+- { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES },
+- { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS },
+- { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS },
+ };
+
+ /*
+@@ -1910,30 +1904,6 @@ static int add_default_attributes(void)
+ }
+
+ if (!evsel_list->core.nr_entries) {
+- if (perf_pmu__has_hybrid()) {
+- struct parse_events_error errinfo;
+- const char *hybrid_str = "cycles,instructions,branches,branch-misses";
+-
+- if (target__has_cpu(&target))
+- default_sw_attrs[0].config = PERF_COUNT_SW_CPU_CLOCK;
+-
+- if (evlist__add_default_attrs(evsel_list,
+- default_sw_attrs) < 0) {
+- return -1;
+- }
+-
+- parse_events_error__init(&errinfo);
+- err = parse_events(evsel_list, hybrid_str, &errinfo);
+- if (err) {
+- fprintf(stderr,
+- "Cannot set up hybrid events %s: %d\n",
+- hybrid_str, err);
+- parse_events_error__print(&errinfo, hybrid_str);
+- }
+- parse_events_error__exit(&errinfo);
+- return err ? -1 : 0;
+- }
+-
+ if (target__has_cpu(&target))
+ default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK;
+
+--
+2.35.1
+
--- /dev/null
+From a1208c49c39210f27d77c2f92eeea3a1b2268e8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 Jul 2022 09:49:23 -0700
+Subject: perf symbol: Fail to read phdr workaround
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 6d518ac7be6223811ab947897273b1bbef846180 ]
+
+The perf jvmti agent doesn't create program headers, in this case
+fallback on section headers as happened previously.
+
+Committer notes:
+
+To test this, from a public post by Ian:
+
+1) download a Java workload dacapo-9.12-MR1-bach.jar from
+https://sourceforge.net/projects/dacapobench/
+
+2) build perf such as "make -C tools/perf O=/tmp/perf NO_LIBBFD=1" it
+should detect Java and create /tmp/perf/libperf-jvmti.so
+
+3) run perf with the jvmti agent:
+
+ perf record -k 1 java -agentpath:/tmp/perf/libperf-jvmti.so -jar dacapo-9.12-MR1-bach.jar -n 10 fop
+
+4) run perf inject:
+
+ perf inject -i perf.data -o perf-injected.data -j
+
+5) run perf report
+
+ perf report -i perf-injected.data | grep org.apache.fop
+
+With this patch reverted I see lots of symbols like:
+
+ 0.00% java jitted-388040-4656.so [.] org.apache.fop.fo.FObj.bind(org.apache.fop.fo.PropertyList)
+
+With the patch (2d86612aacb7805f ("perf symbol: Correct address for bss
+symbols")) I see lots of:
+
+ dso__load_sym_internal: failed to find program header for symbol:
+ Lorg/apache/fop/fo/FObj;bind(Lorg/apache/fop/fo/PropertyList;)V
+ st_value: 0x40
+
+Fixes: 2d86612aacb7805f ("perf symbol: Correct address for bss symbols")
+Reviewed-by: Leo Yan <leo.yan@linaro.org>
+Signed-off-by: Ian Rogers <irogers@google.com>
+Tested-by: Leo Yan <leo.yan@linaro.org>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lore.kernel.org/lkml/20220731164923.691193-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/symbol-elf.c | 27 ++++++++++++++++++++-------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
+index ef6ced5c5746..cb7b24493782 100644
+--- a/tools/perf/util/symbol-elf.c
++++ b/tools/perf/util/symbol-elf.c
+@@ -1294,16 +1294,29 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
+
+ if (elf_read_program_header(syms_ss->elf,
+ (u64)sym.st_value, &phdr)) {
+- pr_warning("%s: failed to find program header for "
++ pr_debug4("%s: failed to find program header for "
+ "symbol: %s st_value: %#" PRIx64 "\n",
+ __func__, elf_name, (u64)sym.st_value);
+- continue;
++ pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
++ "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n",
++ __func__, (u64)sym.st_value, (u64)shdr.sh_addr,
++ (u64)shdr.sh_offset);
++ /*
++ * Fail to find program header, let's rollback
++ * to use shdr.sh_addr and shdr.sh_offset to
++ * calibrate symbol's file address, though this
++ * is not necessary for normal C ELF file, we
++ * still need to handle java JIT symbols in this
++ * case.
++ */
++ sym.st_value -= shdr.sh_addr - shdr.sh_offset;
++ } else {
++ pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
++ "p_vaddr: %#" PRIx64 " p_offset: %#" PRIx64 "\n",
++ __func__, (u64)sym.st_value, (u64)phdr.p_vaddr,
++ (u64)phdr.p_offset);
++ sym.st_value -= phdr.p_vaddr - phdr.p_offset;
+ }
+- pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
+- "p_vaddr: %#" PRIx64 " p_offset: %#" PRIx64 "\n",
+- __func__, (u64)sym.st_value, (u64)phdr.p_vaddr,
+- (u64)phdr.p_offset);
+- sym.st_value -= phdr.p_vaddr - phdr.p_offset;
+ }
+
+ demangled = demangle_sym(dso, kmodule, elf_name);
+--
+2.35.1
+
--- /dev/null
+From ba0aa2e06d39c3f3767c442051a20824f645b517 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 12:31:44 +0300
+Subject: perf tools: Fix dso_id inode generation comparison
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit 68566a7cf56bf3148797c218ed45a9de078ef47c ]
+
+Synthesized MMAP events have zero ino_generation, so do not compare
+them to DSOs with a real ino_generation otherwise we end up with a DSO
+without a build id.
+
+Fixes: 0e3149f86b99ddab ("perf dso: Move dso_id from 'struct map' to 'struct dso'")
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: kvm@vger.kernel.org
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20220711093218.10967-2-adrian.hunter@intel.com
+[ Added clarification to the comment from Ian + more detailed explanation from Adrian ]
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/dsos.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c
+index b97366f77bbf..2bd23e4cf19e 100644
+--- a/tools/perf/util/dsos.c
++++ b/tools/perf/util/dsos.c
+@@ -23,8 +23,19 @@ static int __dso_id__cmp(struct dso_id *a, struct dso_id *b)
+ if (a->ino > b->ino) return -1;
+ if (a->ino < b->ino) return 1;
+
+- if (a->ino_generation > b->ino_generation) return -1;
+- if (a->ino_generation < b->ino_generation) return 1;
++ /*
++ * Synthesized MMAP events have zero ino_generation, avoid comparing
++ * them with MMAP events with actual ino_generation.
++ *
++ * I found it harmful because the mismatch resulted in a new
++ * dso that did not have a build ID whereas the original dso did have a
++ * build ID. The build ID was essential because the object was not found
++ * otherwise. - Adrian
++ */
++ if (a->ino_generation && b->ino_generation) {
++ if (a->ino_generation > b->ino_generation) return -1;
++ if (a->ino_generation < b->ino_generation) return 1;
++ }
+
+ return 0;
+ }
+--
+2.35.1
+
--- /dev/null
+From 34f17fba2b7f1fdd8eae0a1e1d2928c8e8fb65d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 12:42:53 +0300
+Subject: phy: qcom-qmp: fix the QSERDES_V5_COM_CMN_MODE register
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 488987b2d5cade4e7680f7e81590435a848d1fa9 ]
+
+Change QSERDES_V5_COM_CMN_MODE to be defined to 0x1a0 rather than 0x1a4.
+The only user of this register name (sm8450_qmp_gen4x2_pcie_serdes_tbl)
+should use the 0x1a0 register, as stated in the downstream dtsi tree.
+
+Fixes: 2c91bf6bf290 ("phy: qcom-qmp: Add SM8450 PCIe1 PHY support")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20220705094320.1313312-2-dmitry.baryshkov@linaro.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/qualcomm/phy-qcom-qmp.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
+index 06b2556ed93a..b9a91520439c 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
++++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
+@@ -1116,7 +1116,8 @@
+ #define QSERDES_V5_COM_CORE_CLK_EN 0x174
+ #define QSERDES_V5_COM_CMN_CONFIG 0x17c
+ #define QSERDES_V5_COM_CMN_MISC1 0x19c
+-#define QSERDES_V5_COM_CMN_MODE 0x1a4
++#define QSERDES_V5_COM_CMN_MODE 0x1a0
++#define QSERDES_V5_COM_CMN_MODE_CONTD 0x1a4
+ #define QSERDES_V5_COM_VCO_DC_LEVEL_CTRL 0x1a8
+ #define QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x1ac
+ #define QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x1b0
+--
+2.35.1
+
--- /dev/null
+From 4d3bb39a7614c6f8aa2e8e30729093889efa1c8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 01:14:34 -0500
+Subject: phy: rockchip-inno-usb2: Ignore OTG IRQs in host mode
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit fd7d47484125c7d04578de9294faa7fec6e5df0a ]
+
+When the OTG port is fixed to host mode, the driver does not request its
+IRQs, nor does it enable those IRQs in hardware. Similarly, the driver
+should ignore the OTG port IRQs when handling the shared interrupt.
+
+Otherwise, it would update the extcon based on an ID pin which may be in
+an undefined state, or try to queue a uninitialized work item.
+
+Fixes: 6a98df08ccd5 ("phy: rockchip-inno-usb2: Fix muxed interrupt support")
+Reported-by: Frank Wunderlich <frank-w@public-files.de>
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Tested-by: Peter Geis <pgwipeout@gmail.com>
+Tested-by: Frank Wunderlich <frank-w@public-files.de>
+Link: https://lore.kernel.org/r/20220708061434.38115-1-samuel@sholland.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+index cba5c32cbaee..0c6548ac9d8a 100644
+--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+@@ -942,7 +942,9 @@ static irqreturn_t rockchip_usb2phy_irq(int irq, void *data)
+
+ switch (rport->port_id) {
+ case USB2PHY_PORT_OTG:
+- ret |= rockchip_usb2phy_otg_mux_irq(irq, rport);
++ if (rport->mode != USB_DR_MODE_HOST &&
++ rport->mode != USB_DR_MODE_UNKNOWN)
++ ret |= rockchip_usb2phy_otg_mux_irq(irq, rport);
+ break;
+ case USB2PHY_PORT_HOST:
+ ret |= rockchip_usb2phy_linestate_irq(irq, rport);
+--
+2.35.1
+
--- /dev/null
+From 55bb1680ca120cd204c35b819a0a86010e9771d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 14:05:36 +0900
+Subject: phy: samsung: exynosautov9-ufs: correct TSRV register configurations
+
+From: Chanho Park <chanho61.park@samsung.com>
+
+[ Upstream commit f7fdc4db071f7ee7d408ea3f083222a060c76623 ]
+
+For exynos auto v9's UFS MPHY, We should use 0x50 offset of TSRV register
+configurations. So, it must be
+
+s/PHY_TRSV_REG_CFG/PHY_TRSV_REG_CFG_AUTOV9/g
+
+Fixes: d64519249e1d ("phy: samsung-ufs: support exynosauto ufs phy driver")
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220603050536.61957-1-chanho61.park@samsung.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/samsung/phy-exynosautov9-ufs.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/phy/samsung/phy-exynosautov9-ufs.c b/drivers/phy/samsung/phy-exynosautov9-ufs.c
+index 36398a15c2db..d043dfdb598a 100644
+--- a/drivers/phy/samsung/phy-exynosautov9-ufs.c
++++ b/drivers/phy/samsung/phy-exynosautov9-ufs.c
+@@ -31,22 +31,22 @@ static const struct samsung_ufs_phy_cfg exynosautov9_pre_init_cfg[] = {
+ PHY_COMN_REG_CFG(0x023, 0xc0, PWR_MODE_ANY),
+ PHY_COMN_REG_CFG(0x023, 0x00, PWR_MODE_ANY),
+
+- PHY_TRSV_REG_CFG(0x042, 0x5d, PWR_MODE_ANY),
+- PHY_TRSV_REG_CFG(0x043, 0x80, PWR_MODE_ANY),
++ PHY_TRSV_REG_CFG_AUTOV9(0x042, 0x5d, PWR_MODE_ANY),
++ PHY_TRSV_REG_CFG_AUTOV9(0x043, 0x80, PWR_MODE_ANY),
+
+ END_UFS_PHY_CFG,
+ };
+
+ /* Calibration for HS mode series A/B */
+ static const struct samsung_ufs_phy_cfg exynosautov9_pre_pwr_hs_cfg[] = {
+- PHY_TRSV_REG_CFG(0x032, 0xbc, PWR_MODE_HS_ANY),
+- PHY_TRSV_REG_CFG(0x03c, 0x7f, PWR_MODE_HS_ANY),
+- PHY_TRSV_REG_CFG(0x048, 0xc0, PWR_MODE_HS_ANY),
++ PHY_TRSV_REG_CFG_AUTOV9(0x032, 0xbc, PWR_MODE_HS_ANY),
++ PHY_TRSV_REG_CFG_AUTOV9(0x03c, 0x7f, PWR_MODE_HS_ANY),
++ PHY_TRSV_REG_CFG_AUTOV9(0x048, 0xc0, PWR_MODE_HS_ANY),
+
+- PHY_TRSV_REG_CFG(0x04a, 0x00, PWR_MODE_HS_G3_SER_B),
+- PHY_TRSV_REG_CFG(0x04b, 0x10, PWR_MODE_HS_G1_SER_B |
+- PWR_MODE_HS_G3_SER_B),
+- PHY_TRSV_REG_CFG(0x04d, 0x63, PWR_MODE_HS_G3_SER_B),
++ PHY_TRSV_REG_CFG_AUTOV9(0x04a, 0x00, PWR_MODE_HS_G3_SER_B),
++ PHY_TRSV_REG_CFG_AUTOV9(0x04b, 0x10, PWR_MODE_HS_G1_SER_B |
++ PWR_MODE_HS_G3_SER_B),
++ PHY_TRSV_REG_CFG_AUTOV9(0x04d, 0x63, PWR_MODE_HS_G3_SER_B),
+
+ END_UFS_PHY_CFG,
+ };
+--
+2.35.1
+
--- /dev/null
+From 3d169c8bc316c7b3dba621f8b1fcc6fe49af3069 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 15:39:53 +0200
+Subject: phy: stm32: fix error return in stm32_usbphyc_phy_init
+
+From: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+
+[ Upstream commit 32b378a9179ae4db61cfc5d502717214e6cd1e1c ]
+
+Error code is overridden, in case the PLL doesn't lock. So, the USB
+initialization can continue. This leads to a platform freeze.
+This can be avoided by returning proper error code to avoid USB probe
+freezing the platform. It also displays proper errors in log.
+
+Fixes: 5b1af71280ab ("phy: stm32: rework PLL Lock detection")
+Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+Link: https://lore.kernel.org/r/20220713133953.595134-1-fabrice.gasnier@foss.st.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/st/phy-stm32-usbphyc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c
+index 007a23c78d56..a98c911cc37a 100644
+--- a/drivers/phy/st/phy-stm32-usbphyc.c
++++ b/drivers/phy/st/phy-stm32-usbphyc.c
+@@ -358,7 +358,9 @@ static int stm32_usbphyc_phy_init(struct phy *phy)
+ return 0;
+
+ pll_disable:
+- return stm32_usbphyc_pll_disable(usbphyc);
++ stm32_usbphyc_pll_disable(usbphyc);
++
++ return ret;
+ }
+
+ static int stm32_usbphyc_phy_exit(struct phy *phy)
+--
+2.35.1
+
--- /dev/null
+From 7bf39e9cbcacbd69756d6a37b77c283962624689 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 19:08:48 +0300
+Subject: phy: ti: tusb1210: Don't check for write errors when powering on
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit d4a0a189b72a7c98e4256292b18b67c69fbc9343 ]
+
+On some platforms, like Intel Merrifield, the writing values during power on
+may timeout:
+
+ tusb1210 dwc3.0.auto.ulpi: error -110 writing val 0x41 to reg 0x80
+ phy phy-dwc3.0.auto.ulpi.0: phy poweron failed --> -110
+ dwc3 dwc3.0.auto: error -ETIMEDOUT: failed to initialize core
+ dwc3: probe of dwc3.0.auto failed with error -110
+
+which effectively fails the probe of the USB controller.
+Drop the check as it was before the culprit commit (see Fixes tag).
+
+Fixes: 09a3512681b3 ("phy: ti: tusb1210: Improve ulpi_read()/_write() error checking")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Acked-by: Hans de Goede <hdegoede@redhat.com>
+Tested-by: Ferry Toth <fntoth@gmail.com>
+Link: https://lore.kernel.org/r/20220613160848.82746-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/phy/ti/phy-tusb1210.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/phy/ti/phy-tusb1210.c b/drivers/phy/ti/phy-tusb1210.c
+index c3ab4b69ea68..669c13d6e402 100644
+--- a/drivers/phy/ti/phy-tusb1210.c
++++ b/drivers/phy/ti/phy-tusb1210.c
+@@ -105,8 +105,9 @@ static int tusb1210_power_on(struct phy *phy)
+ msleep(TUSB1210_RESET_TIME_MS);
+
+ /* Restore the optional eye diagram optimization value */
+- return tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2,
+- tusb->vendor_specific2);
++ tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, tusb->vendor_specific2);
++
++ return 0;
+ }
+
+ static int tusb1210_power_off(struct phy *phy)
+--
+2.35.1
+
--- /dev/null
+From 8a93b76e045a6e4b6dfa519c7d559fbc0cb15b1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 12:59:50 -0500
+Subject: pinctrl: Don't allow PINCTRL_AMD to be a module
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit 41ef3c1a6bb0fd4a3f81170dd17de3adbff80783 ]
+
+It was observed that by allowing pinctrl_amd to be loaded
+later in the boot process that interrupts sent to the GPIO
+controller early in the boot are not serviced. The kernel treats
+these as a spurious IRQ and disables the IRQ.
+
+This problem was exacerbated because it happened on a system with
+an encrypted partition so the kernel object was not accesssible for
+an extended period of time while waiting for a passphrase.
+
+To avoid this situation from occurring, stop allowing pinctrl-amd
+from being built as a module and instead require it to be built-in
+or disabled.
+
+Reported-by: madcatx@atlas.cz
+Suggested-by: jwrdegoede@fedoraproject.org
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216230
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Acked-by: Hans de Goede <hdegoede@redhat.com>
+Link: https://lore.kernel.org/r/20220713175950.964-1-mario.limonciello@amd.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
+index f52960d2dfbe..bff144c97e66 100644
+--- a/drivers/pinctrl/Kconfig
++++ b/drivers/pinctrl/Kconfig
+@@ -32,7 +32,7 @@ config DEBUG_PINCTRL
+ Say Y here to add some extra checks and diagnostics to PINCTRL calls.
+
+ config PINCTRL_AMD
+- tristate "AMD GPIO pin control"
++ bool "AMD GPIO pin control"
+ depends on HAS_IOMEM
+ depends on ACPI || COMPILE_TEST
+ select GPIOLIB
+--
+2.35.1
+
--- /dev/null
+From b11428d11b3e5b4472c9fdf9e84de86c1416d1f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jun 2022 00:57:26 -0700
+Subject: platform/chrome: cros_ec: Always expose last resume result
+
+From: Stephen Boyd <swboyd@chromium.org>
+
+[ Upstream commit 74bb746407bf0d7c7d126c7731dbcd66d467619b ]
+
+The last resume result exposing logic in cros_ec_sleep_event()
+incorrectly requires S0ix support, which doesn't work on ARM based
+systems where S0ix doesn't exist. That's because cros_ec_sleep_event()
+only reports the last resume result when the EC indicates the last sleep
+event was an S0ix resume. On ARM systems, the last sleep event is always
+S3 resume, but the EC can still detect sleep hang events in case some
+other part of the AP is blocking sleep.
+
+Always expose the last resume result if the EC supports it so that this
+works on all devices regardless of S0ix support. This fixes sleep hang
+detection on ARM based chromebooks like Trogdor.
+
+Cc: Rajat Jain <rajatja@chromium.org>
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Cc: Hsin-Yi Wang <hsinyi@chromium.org>
+Cc: Tzung-Bi Shih <tzungbi@kernel.org>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Reviewed-by: Evan Green <evgreen@chromium.org>
+Fixes: 7235560ac77a ("platform/chrome: Add support for v1 of host sleep event")
+Signed-off-by: Stephen Boyd <swboyd@chromium.org>
+Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Link: https://lore.kernel.org/r/20220614075726.2729987-1-swboyd@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/chrome/cros_ec.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/platform/chrome/cros_ec.c b/drivers/platform/chrome/cros_ec.c
+index a5cc8f24299e..4168d7f5f273 100644
+--- a/drivers/platform/chrome/cros_ec.c
++++ b/drivers/platform/chrome/cros_ec.c
+@@ -135,16 +135,16 @@ static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event)
+ buf.msg.command = EC_CMD_HOST_SLEEP_EVENT;
+
+ ret = cros_ec_cmd_xfer_status(ec_dev, &buf.msg);
+-
+- /* For now, report failure to transition to S0ix with a warning. */
++ /* Report failure to transition to system wide suspend with a warning. */
+ if (ret >= 0 && ec_dev->host_sleep_v1 &&
+- (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME)) {
++ (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME ||
++ sleep_event == HOST_SLEEP_EVENT_S3_RESUME)) {
+ ec_dev->last_resume_result =
+ buf.u.resp1.resume_response.sleep_transitions;
+
+ WARN_ONCE(buf.u.resp1.resume_response.sleep_transitions &
+ EC_HOST_RESUME_SLEEP_TIMEOUT,
+- "EC detected sleep transition timeout. Total slp_s0 transitions: %d",
++ "EC detected sleep transition timeout. Total sleep transitions: %d",
+ buf.u.resp1.resume_response.sleep_transitions &
+ EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK);
+ }
+--
+2.35.1
+
--- /dev/null
+From 9a3cadb0c1eff3fddf714c3b90063c909856c95a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 18:35:40 +0300
+Subject: platform/mellanox: mlxreg-lc: Fix error flow and extend verbosity
+
+From: Vadim Pasternak <vadimp@nvidia.com>
+
+[ Upstream commit b4b830a34d8046633231b7fe87f6f2cb6240dc9f ]
+
+Fix error flow:
+- Clean-up client object in case of probing failure.
+- Prevent running remove routine in case of probing failure.
+ Probing and removing are invoked by hotplug events raised upon line
+ card insertion and removing. If probing procedure failed all data is
+ cleared and there is nothing to do in remove routine.
+
+Fixes: 62f9529b8d5c ("platform/mellanox: mlxreg-lc: Add initial support for Nvidia line card devices")
+Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
+Link: https://lore.kernel.org/r/20220719153540.61304-1-vadimp@nvidia.com
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/mellanox/mlxreg-lc.c | 82 ++++++++++++++++++++-------
+ 1 file changed, 63 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/platform/mellanox/mlxreg-lc.c b/drivers/platform/mellanox/mlxreg-lc.c
+index c897a2f15840..55834ccb4ac7 100644
+--- a/drivers/platform/mellanox/mlxreg-lc.c
++++ b/drivers/platform/mellanox/mlxreg-lc.c
+@@ -716,8 +716,12 @@ mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
+ switch (regval) {
+ case MLXREG_LC_SN4800_C16:
+ err = mlxreg_lc_sn4800_c16_config_init(mlxreg_lc, regmap, data);
+- if (err)
++ if (err) {
++ dev_err(dev, "Failed to config client %s at bus %d at addr 0x%02x\n",
++ data->hpdev.brdinfo->type, data->hpdev.nr,
++ data->hpdev.brdinfo->addr);
+ return err;
++ }
+ break;
+ default:
+ return -ENODEV;
+@@ -730,8 +734,11 @@ mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
+ mlxreg_lc->mux = platform_device_register_resndata(dev, "i2c-mux-mlxcpld", data->hpdev.nr,
+ NULL, 0, mlxreg_lc->mux_data,
+ sizeof(*mlxreg_lc->mux_data));
+- if (IS_ERR(mlxreg_lc->mux))
++ if (IS_ERR(mlxreg_lc->mux)) {
++ dev_err(dev, "Failed to create mux infra for client %s at bus %d at addr 0x%02x\n",
++ data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
+ return PTR_ERR(mlxreg_lc->mux);
++ }
+
+ /* Register IO access driver. */
+ if (mlxreg_lc->io_data) {
+@@ -740,6 +747,9 @@ mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
+ platform_device_register_resndata(dev, "mlxreg-io", data->hpdev.nr, NULL, 0,
+ mlxreg_lc->io_data, sizeof(*mlxreg_lc->io_data));
+ if (IS_ERR(mlxreg_lc->io_regs)) {
++ dev_err(dev, "Failed to create regio for client %s at bus %d at addr 0x%02x\n",
++ data->hpdev.brdinfo->type, data->hpdev.nr,
++ data->hpdev.brdinfo->addr);
+ err = PTR_ERR(mlxreg_lc->io_regs);
+ goto fail_register_io;
+ }
+@@ -753,6 +763,9 @@ mlxreg_lc_config_init(struct mlxreg_lc *mlxreg_lc, void *regmap,
+ mlxreg_lc->led_data,
+ sizeof(*mlxreg_lc->led_data));
+ if (IS_ERR(mlxreg_lc->led)) {
++ dev_err(dev, "Failed to create LED objects for client %s at bus %d at addr 0x%02x\n",
++ data->hpdev.brdinfo->type, data->hpdev.nr,
++ data->hpdev.brdinfo->addr);
+ err = PTR_ERR(mlxreg_lc->led);
+ goto fail_register_led;
+ }
+@@ -809,7 +822,8 @@ static int mlxreg_lc_probe(struct platform_device *pdev)
+ if (!data->hpdev.adapter) {
+ dev_err(&pdev->dev, "Failed to get adapter for bus %d\n",
+ data->hpdev.nr);
+- return -EFAULT;
++ err = -EFAULT;
++ goto i2c_get_adapter_fail;
+ }
+
+ /* Create device at the top of line card I2C tree.*/
+@@ -818,32 +832,40 @@ static int mlxreg_lc_probe(struct platform_device *pdev)
+ if (IS_ERR(data->hpdev.client)) {
+ dev_err(&pdev->dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
+ data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
+-
+- i2c_put_adapter(data->hpdev.adapter);
+- data->hpdev.adapter = NULL;
+- return PTR_ERR(data->hpdev.client);
++ err = PTR_ERR(data->hpdev.client);
++ goto i2c_new_device_fail;
+ }
+
+ regmap = devm_regmap_init_i2c(data->hpdev.client,
+ &mlxreg_lc_regmap_conf);
+ if (IS_ERR(regmap)) {
++ dev_err(&pdev->dev, "Failed to create regmap for client %s at bus %d at addr 0x%02x\n",
++ data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
+ err = PTR_ERR(regmap);
+- goto mlxreg_lc_probe_fail;
++ goto devm_regmap_init_i2c_fail;
+ }
+
+ /* Set default registers. */
+ for (i = 0; i < mlxreg_lc_regmap_conf.num_reg_defaults; i++) {
+ err = regmap_write(regmap, mlxreg_lc_regmap_default[i].reg,
+ mlxreg_lc_regmap_default[i].def);
+- if (err)
+- goto mlxreg_lc_probe_fail;
++ if (err) {
++ dev_err(&pdev->dev, "Failed to set default regmap %d for client %s at bus %d at addr 0x%02x\n",
++ i, data->hpdev.brdinfo->type, data->hpdev.nr,
++ data->hpdev.brdinfo->addr);
++ goto regmap_write_fail;
++ }
+ }
+
+ /* Sync registers with hardware. */
+ regcache_mark_dirty(regmap);
+ err = regcache_sync(regmap);
+- if (err)
+- goto mlxreg_lc_probe_fail;
++ if (err) {
++ dev_err(&pdev->dev, "Failed to sync regmap for client %s at bus %d at addr 0x%02x\n",
++ data->hpdev.brdinfo->type, data->hpdev.nr, data->hpdev.brdinfo->addr);
++ err = PTR_ERR(regmap);
++ goto regcache_sync_fail;
++ }
+
+ par_pdata = data->hpdev.brdinfo->platform_data;
+ mlxreg_lc->par_regmap = par_pdata->regmap;
+@@ -854,12 +876,27 @@ static int mlxreg_lc_probe(struct platform_device *pdev)
+ /* Configure line card. */
+ err = mlxreg_lc_config_init(mlxreg_lc, regmap, data);
+ if (err)
+- goto mlxreg_lc_probe_fail;
++ goto mlxreg_lc_config_init_fail;
+
+ return err;
+
+-mlxreg_lc_probe_fail:
++mlxreg_lc_config_init_fail:
++regcache_sync_fail:
++regmap_write_fail:
++devm_regmap_init_i2c_fail:
++ if (data->hpdev.client) {
++ i2c_unregister_device(data->hpdev.client);
++ data->hpdev.client = NULL;
++ }
++i2c_new_device_fail:
+ i2c_put_adapter(data->hpdev.adapter);
++ data->hpdev.adapter = NULL;
++i2c_get_adapter_fail:
++ /* Clear event notification callback and handle. */
++ if (data->notifier) {
++ data->notifier->user_handler = NULL;
++ data->notifier->handle = NULL;
++ }
+ return err;
+ }
+
+@@ -868,11 +905,18 @@ static int mlxreg_lc_remove(struct platform_device *pdev)
+ struct mlxreg_core_data *data = dev_get_platdata(&pdev->dev);
+ struct mlxreg_lc *mlxreg_lc = platform_get_drvdata(pdev);
+
+- /* Clear event notification callback. */
+- if (data->notifier) {
+- data->notifier->user_handler = NULL;
+- data->notifier->handle = NULL;
+- }
++ /*
++ * Probing and removing are invoked by hotplug events raised upon line card insertion and
++ * removing. If probing procedure fails all data is cleared. However, hotplug event still
++ * will be raised on line card removing and activate removing procedure. In this case there
++ * is nothing to remove.
++ */
++ if (!data->notifier || !data->notifier->handle)
++ return 0;
++
++ /* Clear event notification callback and handle. */
++ data->notifier->user_handler = NULL;
++ data->notifier->handle = NULL;
+
+ /* Destroy static I2C device feeding by main power. */
+ mlxreg_lc_destroy_static_devices(mlxreg_lc, mlxreg_lc->main_devs,
+--
+2.35.1
+
--- /dev/null
+From 9dc9d8b0893d8bab57a07e3e6fa9fa62ac930c81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Jul 2022 21:23:38 +0300
+Subject: platform/olpc: Fix uninitialized data in debugfs write
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 40ec787e1adf302c11668d4cc69838f4d584187d ]
+
+The call to:
+
+ size = simple_write_to_buffer(cmdbuf, sizeof(cmdbuf), ppos, buf, size);
+
+will succeed if at least one byte is written to the "cmdbuf" buffer.
+The "*ppos" value controls which byte is written. Another problem is
+that this code does not check for errors so it's possible for the entire
+buffer to be uninitialized.
+
+Inintialize the struct to zero to prevent reading uninitialized stack
+data.
+
+Debugfs is normally only writable by root so the impact of this bug is
+very minimal.
+
+Fixes: 6cca83d498bd ("Platform: OLPC: move debugfs support from x86 EC driver")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Link: https://lore.kernel.org/r/YthIKn+TfZSZMEcM@kili
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/olpc/olpc-ec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/platform/olpc/olpc-ec.c b/drivers/platform/olpc/olpc-ec.c
+index 4ff5c3a12991..921520475ff6 100644
+--- a/drivers/platform/olpc/olpc-ec.c
++++ b/drivers/platform/olpc/olpc-ec.c
+@@ -264,7 +264,7 @@ static ssize_t ec_dbgfs_cmd_write(struct file *file, const char __user *buf,
+ int i, m;
+ unsigned char ec_cmd[EC_MAX_CMD_ARGS];
+ unsigned int ec_cmd_int[EC_MAX_CMD_ARGS];
+- char cmdbuf[64];
++ char cmdbuf[64] = "";
+ int ec_cmd_bytes;
+
+ mutex_lock(&ec_dbgfs_lock);
+--
+2.35.1
+
--- /dev/null
+From c522f3349d5322dd718842998dc7f601e9754fba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Jul 2022 20:06:35 +0200
+Subject: platform/x86: pmc_atom: Match all Lex BayTrail boards with
+ critclk_systems DMI table
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit c9d959fc32a5f9312282817052d8986614f2dc08 ]
+
+The critclk_systems[] DMI match table already contains 2 Lex BayTrail
+boards and patches were just submitted to add 3 more entries for the
+following models: 3I380NX, 3I380A, 3I380CW.
+
+Looking at: https://www.lex.com.tw/products/embedded-ipc-board/
+we can see that Lex BayTrail makes many embedded boards with
+multiple ethernet boards and none of their products are battery
+powered so we don't need to worry (too much) about power consumption
+when suspended.
+
+Add a new DMI match which simply matches all Lex BayTrail boards and drop
+the 2 existing board specific quirks.
+
+Fixes: 648e921888ad ("clk: x86: Stop marking clocks as CLK_IS_CRITICAL")
+Reported-by: Michael Schöne <michael.schoene@rhebo.com>
+Reported-by: Paul Spooren <paul.spooren@rhebo.com>
+Reported-by: Matwey V. Kornilov <matwey@sai.msu.ru>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/pmc_atom.c | 19 +++++++------------
+ 1 file changed, 7 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
+index a40fae6edc84..f24ab24f2927 100644
+--- a/drivers/platform/x86/pmc_atom.c
++++ b/drivers/platform/x86/pmc_atom.c
+@@ -402,21 +402,16 @@ static const struct dmi_system_id critclk_systems[] = {
+ },
+ },
+ {
+- /* pmc_plt_clk0 - 3 are used for the 4 ethernet controllers */
+- .ident = "Lex 3I380D",
++ /*
++ * Lex System / Lex Computech Co. makes a lot of Bay Trail
++ * based embedded boards which often come with multiple
++ * ethernet controllers using multiple pmc_plt_clks. See:
++ * https://www.lex.com.tw/products/embedded-ipc-board/
++ */
++ .ident = "Lex BayTrail",
+ .callback = dmi_callback,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Lex BayTrail"),
+- DMI_MATCH(DMI_PRODUCT_NAME, "3I380D"),
+- },
+- },
+- {
+- /* pmc_plt_clk* - are used for ethernet controllers */
+- .ident = "Lex 2I385SW",
+- .callback = dmi_callback,
+- .matches = {
+- DMI_MATCH(DMI_SYS_VENDOR, "Lex BayTrail"),
+- DMI_MATCH(DMI_PRODUCT_NAME, "2I385SW"),
+ },
+ },
+ {
+--
+2.35.1
+
--- /dev/null
+From b52ce3ac9e34ed47b07f18bb7097d2f2d9876788 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 01:16:49 +0800
+Subject: PM: domains: Ensure genpd_debugfs_dir exists before remove
+
+From: Hsin-Yi Wang <hsinyi@chromium.org>
+
+[ Upstream commit 37101d3c719386040ded735a5ec06974f1d94d1f ]
+
+Both genpd_debug_add() and genpd_debug_remove() may be called
+indirectly by other drivers while genpd_debugfs_dir is not yet
+set. For example, drivers can call pm_genpd_init() in probe or
+pm_genpd_init() in probe fail/cleanup path:
+
+pm_genpd_init()
+ --> genpd_debug_add()
+
+pm_genpd_remove()
+ --> genpd_remove()
+ --> genpd_debug_remove()
+
+At this time, genpd_debug_init() may not yet be called.
+
+genpd_debug_add() checks that if genpd_debugfs_dir is NULL, it
+will return directly. Make sure this is also checked
+in pm_genpd_remove(), otherwise components under debugfs root
+which has the same name as other components under pm_genpd may
+be accidentally removed, since NULL represents debugfs root.
+
+Fixes: 718072ceb211 ("PM: domains: create debugfs nodes when adding power domains")
+Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/domain.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
+index f0e4b0ea93e8..59a706a126e5 100644
+--- a/drivers/base/power/domain.c
++++ b/drivers/base/power/domain.c
+@@ -219,6 +219,9 @@ static void genpd_debug_remove(struct generic_pm_domain *genpd)
+ {
+ struct dentry *d;
+
++ if (!genpd_debugfs_dir)
++ return;
++
+ d = debugfs_lookup(genpd->name, genpd_debugfs_dir);
+ debugfs_remove(d);
+ }
+--
+2.35.1
+
--- /dev/null
+From a9a821f588f668809109f7e89ed6666881d97f6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 14:49:58 +0900
+Subject: PM: hibernate: defer device probing when resuming from hibernation
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+[ Upstream commit 8386c414e27caba8501119948e9551e52b527f59 ]
+
+syzbot is reporting hung task at misc_open() [1], for there is a race
+window of AB-BA deadlock which involves probe_count variable. Currently
+wait_for_device_probe() from snapshot_open() from misc_open() can sleep
+forever with misc_mtx held if probe_count cannot become 0.
+
+When a device is probed by hub_event() work function, probe_count is
+incremented before the probe function starts, and probe_count is
+decremented after the probe function completed.
+
+There are three cases that can prevent probe_count from dropping to 0.
+
+ (a) A device being probed stopped responding (i.e. broken/malicious
+ hardware).
+
+ (b) A process emulating a USB device using /dev/raw-gadget interface
+ stopped responding for some reason.
+
+ (c) New device probe requests keeps coming in before existing device
+ probe requests complete.
+
+The phenomenon syzbot is reporting is (b). A process which is holding
+system_transition_mutex and misc_mtx is waiting for probe_count to become
+0 inside wait_for_device_probe(), but the probe function which is called
+ from hub_event() work function is waiting for the processes which are
+blocked at mutex_lock(&misc_mtx) to respond via /dev/raw-gadget interface.
+
+This patch mitigates (b) by deferring wait_for_device_probe() from
+snapshot_open() to snapshot_write() and snapshot_ioctl(). Please note that
+the possibility of (b) remains as long as any thread which is emulating a
+USB device via /dev/raw-gadget interface can be blocked by uninterruptible
+blocking operations (e.g. mutex_lock()).
+
+Please also note that (a) and (c) are not addressed. Regarding (c), we
+should change the code to wait for only one device which contains the
+image for resuming from hibernation. I don't know how to address (a), for
+use of timeout for wait_for_device_probe() might result in loss of user
+data in the image. Maybe we should require the userland to wait for the
+image device before opening /dev/snapshot interface.
+
+Link: https://syzkaller.appspot.com/bug?extid=358c9ab4c93da7b7238c [1]
+Reported-by: syzbot <syzbot+358c9ab4c93da7b7238c@syzkaller.appspotmail.com>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Tested-by: syzbot <syzbot+358c9ab4c93da7b7238c@syzkaller.appspotmail.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/power/user.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/power/user.c b/kernel/power/user.c
+index ad241b4ff64c..d43c2aa583b2 100644
+--- a/kernel/power/user.c
++++ b/kernel/power/user.c
+@@ -26,6 +26,7 @@
+
+ #include "power.h"
+
++static bool need_wait;
+
+ static struct snapshot_data {
+ struct snapshot_handle handle;
+@@ -78,7 +79,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)
+ * Resuming. We may need to wait for the image device to
+ * appear.
+ */
+- wait_for_device_probe();
++ need_wait = true;
+
+ data->swap = -1;
+ data->mode = O_WRONLY;
+@@ -168,6 +169,11 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
+ ssize_t res;
+ loff_t pg_offp = *offp & ~PAGE_MASK;
+
++ if (need_wait) {
++ wait_for_device_probe();
++ need_wait = false;
++ }
++
+ lock_system_sleep();
+
+ data = filp->private_data;
+@@ -244,6 +250,11 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
+ loff_t size;
+ sector_t offset;
+
++ if (need_wait) {
++ wait_for_device_probe();
++ need_wait = false;
++ }
++
+ if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC)
+ return -ENOTTY;
+ if (_IOC_NR(cmd) > SNAPSHOT_IOC_MAXNR)
+--
+2.35.1
+
--- /dev/null
+From bd2031dee0586cc2f01ef6e32337116dfc1c32fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jun 2022 12:34:08 +0200
+Subject: powerpc/32: Call mmu_mark_initmem_nx() regardless of data block
+ mapping.
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 980bbf7ca72012d317617fcdbfabe8708e4cef29 ]
+
+mark_initmem_nx() calls either mmu_mark_initmem_nx() or
+set_memory_attr() based on return from v_block_mapped()
+of _sinittext.
+
+But we can now handle text and data independently, so that
+text may be mapped by block even when data is mapped by pages.
+
+On the 8xx for instance, at startup 32Mbytes of memory are
+pinned in TLB. So the pinned entries need to go away for sinittext.
+
+In next patch a BAT will be set to also covers sinittext on book3s/32.
+So it will also be needed to call mmu_mark_initmem_nx() even when
+data above sinittext is not mapped with BATs.
+
+As this is highly dependent on the platform, call mmu_mark_initmem_nx()
+regardless of data block mapping. Then the platform will know what to
+do.
+
+Modify 8xx mmu_mark_initmem_nx() so that inittext mapping is modified
+only when pagealloc debug and kfence are not active, otherwise inittext
+is mapped with standard pages. And don't do anything on kernel text
+which is already mapped with PAGE_KERNEL_TEXT.
+
+Fixes: da1adea07576 ("powerpc/8xx: Allow STRICT_KERNEL_RwX with pinned TLB")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/db3fc14f3bfa6215b0786ef58a6e2bc1e1f964d7.1655202804.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/nohash/8xx.c | 4 ++--
+ arch/powerpc/mm/pgtable_32.c | 6 +++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c
+index 27f9186ae374..1ee08c3efe5b 100644
+--- a/arch/powerpc/mm/nohash/8xx.c
++++ b/arch/powerpc/mm/nohash/8xx.c
+@@ -179,8 +179,8 @@ void mmu_mark_initmem_nx(void)
+ unsigned long boundary = strict_kernel_rwx_enabled() ? sinittext : etext8;
+ unsigned long einittext8 = ALIGN(__pa(_einittext), SZ_8M);
+
+- mmu_mapin_ram_chunk(0, boundary, PAGE_KERNEL_TEXT, false);
+- mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL, false);
++ if (!debug_pagealloc_enabled_or_kfence())
++ mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL, false);
+
+ mmu_pin_tlb(block_mapped_ram, false);
+ }
+diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
+index a56ade39dc68..3ac73f9fb5d5 100644
+--- a/arch/powerpc/mm/pgtable_32.c
++++ b/arch/powerpc/mm/pgtable_32.c
+@@ -135,9 +135,9 @@ void mark_initmem_nx(void)
+ unsigned long numpages = PFN_UP((unsigned long)_einittext) -
+ PFN_DOWN((unsigned long)_sinittext);
+
+- if (v_block_mapped((unsigned long)_sinittext)) {
+- mmu_mark_initmem_nx();
+- } else {
++ mmu_mark_initmem_nx();
++
++ if (!v_block_mapped((unsigned long)_sinittext)) {
+ set_memory_nx((unsigned long)_sinittext, numpages);
+ set_memory_rw((unsigned long)_sinittext, numpages);
+ }
+--
+2.35.1
+
--- /dev/null
+From 5f0ad9799a9cf38139c74d000bf38a0c4a88ffe0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 16:19:29 +0200
+Subject: powerpc/32: Do not allow selection of e5500 or e6500 CPUs on PPC32
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 9be013b2a9ecb29b5168e4b9db0e48ed53acf37c ]
+
+Commit 0e00a8c9fd92 ("powerpc: Allow CPU selection also on PPC32")
+enlarged the CPU selection logic to PPC32 by removing depend to
+PPC64, and failed to restrict that depend to E5500_CPU and E6500_CPU.
+Fortunately that got unnoticed because -mcpu=8540 will override the
+-mcpu=e500mc64 or -mpcu=e6500 as they are ealier, but that's
+fragile and may no be right in the future.
+
+Add back the depend PPC64 on E5500_CPU and E6500_CPU.
+
+Fixes: 0e00a8c9fd92 ("powerpc: Allow CPU selection also on PPC32")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/8abab4888da69ff78b73a56f64d9678a7bf684e9.1657549153.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/Kconfig.cputype | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
+index e2e1fec91c6e..660309559bd8 100644
+--- a/arch/powerpc/platforms/Kconfig.cputype
++++ b/arch/powerpc/platforms/Kconfig.cputype
+@@ -173,11 +173,11 @@ config POWER9_CPU
+
+ config E5500_CPU
+ bool "Freescale e5500"
+- depends on E500
++ depends on PPC64 && E500
+
+ config E6500_CPU
+ bool "Freescale e6500"
+- depends on E500
++ depends on PPC64 && E500
+
+ config 860_CPU
+ bool "8xx family"
+--
+2.35.1
+
--- /dev/null
+From 7093d4878f73cac69d2ef77d7360757cf7693d97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:06:15 +0200
+Subject: powerpc/32s: Fix boot failure with KASAN + SMP +
+ JUMP_LABEL_FEATURE_CHECK_DEBUG
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 6042a1652d643d1d34fa89bb314cb102960c0800 ]
+
+Since commit 4291d085b0b0 ("powerpc/32s: Make pte_update() non
+atomic on 603 core"), pte_update() has been using
+mmu_has_feature(MMU_FTR_HPTE_TABLE) to avoid a useless atomic
+operation on 603 cores.
+
+When kasan_early_init() sets up the early zero shadow, it uses
+__set_pte_at(). On book3s/32, __set_pte_at() calls pte_update()
+when CONFIG_SMP is selected in order to ensure the preservation of
+_PAGE_HASHPTE in case of concurrent update of the PTE. But that's
+too early for mmu_has_feature(), so when
+CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG is selected, mmu_has_feature()
+calls printk(). That's too early to call printk() because KASAN
+early zero shadow page is not set up yet. It leads to a deadlock.
+
+However, when kasan_early_init() is called, there is only one CPU
+running and no risk of concurrent PTE update. So __set_pte_at() can
+be called with the 'percpu' flag. With that flag set, the PTE is
+written directly instead of being written via pte_update().
+
+Fixes: 4291d085b0b0 ("powerpc/32s: Make pte_update() non atomic on 603 core")
+Reported-by: Erhard Furtner <erhard_f@mailbox.org>
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/2ee707512b8b212b079b877f4ceb525a1606a3fb.1656655567.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/kasan/kasan_init_32.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/powerpc/mm/kasan/kasan_init_32.c b/arch/powerpc/mm/kasan/kasan_init_32.c
+index f3e4d069e0ba..a70828a6d935 100644
+--- a/arch/powerpc/mm/kasan/kasan_init_32.c
++++ b/arch/powerpc/mm/kasan/kasan_init_32.c
+@@ -25,7 +25,7 @@ static void __init kasan_populate_pte(pte_t *ptep, pgprot_t prot)
+ int i;
+
+ for (i = 0; i < PTRS_PER_PTE; i++, ptep++)
+- __set_pte_at(&init_mm, va, ptep, pfn_pte(PHYS_PFN(pa), prot), 0);
++ __set_pte_at(&init_mm, va, ptep, pfn_pte(PHYS_PFN(pa), prot), 1);
+ }
+
+ int __init kasan_init_shadow_page_tables(unsigned long k_start, unsigned long k_end)
+--
+2.35.1
+
--- /dev/null
+From 847fc813abcfa8016b0e9e617a19387dcb17da76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Aug 2022 16:29:41 +1000
+Subject: powerpc/64e: Fix kexec build error
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit 4cfa6ff24a9744ba484521c38bea613134fbfcb3 ]
+
+When building ppc64_book3e_allmodconfig the build fails with:
+
+ arch/powerpc/kexec/file_load_64.c:1063:14: error: implicit declaration of function ‘firmware_has_feature’
+ 1063 | if (!firmware_has_feature(FW_FEATURE_LPAR))
+ | ^~~~~~~~~~~~~~~~~~~~
+
+Add a direct include of asm/firmware.h to fix the error.
+
+Fixes: b1fc44eaa9ba ("pseries/iommu/ddw: Fix kdump to work in absence of ibm,dma-window")
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220803063152.1249270-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kexec/file_load_64.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
+index 5d2c22aa34fb..683462e4556b 100644
+--- a/arch/powerpc/kexec/file_load_64.c
++++ b/arch/powerpc/kexec/file_load_64.c
+@@ -23,6 +23,7 @@
+ #include <linux/vmalloc.h>
+ #include <asm/setup.h>
+ #include <asm/drmem.h>
++#include <asm/firmware.h>
+ #include <asm/kexec_ranges.h>
+ #include <asm/crashdump-ppc64.h>
+
+--
+2.35.1
+
--- /dev/null
+From ec0e39ee06deea0dba53054e577ecfad661406f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 23:44:18 +1000
+Subject: powerpc/64s: Disable stack variable initialisation for prom_init
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit be640317a1d0b9cf42fedb2debc2887a7cfa38de ]
+
+With GCC 12 allmodconfig prom_init fails to build:
+
+ Error: External symbol 'memset' referenced from prom_init.c
+ make[2]: *** [arch/powerpc/kernel/Makefile:204: arch/powerpc/kernel/prom_init_check] Error 1
+
+The allmodconfig build enables KASAN, so all calls to memset in
+prom_init should be converted to __memset by the #ifdefs in
+asm/string.h, because prom_init must use the non-KASAN instrumented
+versions.
+
+The build failure happens because there's a call to memset that hasn't
+been caught by the pre-processor and converted to __memset. Typically
+that's because it's a memset generated by the compiler itself, and that
+is the case here.
+
+With GCC 12, allmodconfig enables CONFIG_INIT_STACK_ALL_PATTERN, which
+causes the compiler to emit memset calls to initialise on-stack
+variables with a pattern.
+
+Because prom_init is non-user-facing boot-time only code, as a
+workaround just disable stack variable initialisation to unbreak the
+build.
+
+Reported-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220718134418.354114-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
+index 4ddd161aef32..63c384c3e6d4 100644
+--- a/arch/powerpc/kernel/Makefile
++++ b/arch/powerpc/kernel/Makefile
+@@ -20,6 +20,7 @@ CFLAGS_prom.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
+ CFLAGS_prom_init.o += -fno-stack-protector
+ CFLAGS_prom_init.o += -DDISABLE_BRANCH_PROFILING
+ CFLAGS_prom_init.o += -ffreestanding
++CFLAGS_prom_init.o += $(call cc-option, -ftrivial-auto-var-init=uninitialized)
+
+ ifdef CONFIG_FUNCTION_TRACER
+ # Do not trace early boot code
+--
+2.35.1
+
--- /dev/null
+From 2ed4136318074bce58d49b95fd8a94d5b953bfc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jun 2022 10:51:29 +0400
+Subject: powerpc/cell/axon_msi: Fix refcount leak in setup_msi_msg_address
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit df5d4b616ee76abc97e5bd348e22659c2b095b1c ]
+
+of_get_next_parent() returns a node pointer with refcount incremented,
+we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() in the error path to avoid refcount leak.
+
+Fixes: ce21b3c9648a ("[CELL] add support for MSI on Axon-based Cell systems")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220605065129.63906-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/cell/axon_msi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
+index 354a58c1e6f2..dba34f4d5162 100644
+--- a/arch/powerpc/platforms/cell/axon_msi.c
++++ b/arch/powerpc/platforms/cell/axon_msi.c
+@@ -223,6 +223,7 @@ static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
+ if (!prop) {
+ dev_dbg(&dev->dev,
+ "axon_msi: no msi-address-(32|64) properties found\n");
++ of_node_put(dn);
+ return -ENOENT;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 819592fc0685424ad22f92a0e3d86602d07d1a23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 Apr 2022 20:56:54 +0200
+Subject: powerpc: fix typos in comments
+
+From: Julia Lawall <Julia.Lawall@inria.fr>
+
+[ Upstream commit 1fd02f6605b855b4af2883f29a2abc88bdf17857 ]
+
+Various spelling mistakes in comments.
+Detected with the help of Coccinelle.
+
+Signed-off-by: Julia Lawall <Julia.Lawall@inria.fr>
+Reviewed-by: Joel Stanley <joel@jms.id.au>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220430185654.5855-1-Julia.Lawall@inria.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/boot/cuboot-hotfoot.c | 2 +-
+ arch/powerpc/crypto/aes-spe-glue.c | 2 +-
+ arch/powerpc/kernel/cputable.c | 2 +-
+ arch/powerpc/kernel/dawr.c | 2 +-
+ arch/powerpc/kernel/eeh.c | 4 ++--
+ arch/powerpc/kernel/eeh_event.c | 2 +-
+ arch/powerpc/kernel/fadump.c | 4 ++--
+ arch/powerpc/kernel/module_32.c | 2 +-
+ arch/powerpc/kernel/module_64.c | 4 ++--
+ arch/powerpc/kernel/pci-common.c | 2 +-
+ arch/powerpc/kernel/pci_of_scan.c | 2 +-
+ arch/powerpc/kernel/process.c | 4 ++--
+ arch/powerpc/kernel/prom_init.c | 2 +-
+ arch/powerpc/kernel/ptrace/ptrace-view.c | 2 +-
+ arch/powerpc/kernel/rtas_flash.c | 2 +-
+ arch/powerpc/kernel/setup-common.c | 2 +-
+ arch/powerpc/kernel/signal_64.c | 2 +-
+ arch/powerpc/kernel/smp.c | 2 +-
+ arch/powerpc/kernel/time.c | 4 ++--
+ arch/powerpc/kernel/watchdog.c | 2 +-
+ arch/powerpc/kexec/core_64.c | 2 +-
+ arch/powerpc/kvm/book3s_64_mmu_hv.c | 2 +-
+ arch/powerpc/kvm/book3s_64_vio_hv.c | 2 +-
+ arch/powerpc/kvm/book3s_emulate.c | 2 +-
+ arch/powerpc/kvm/book3s_hv_p9_entry.c | 2 +-
+ arch/powerpc/kvm/book3s_hv_uvmem.c | 2 +-
+ arch/powerpc/kvm/book3s_pr.c | 2 +-
+ arch/powerpc/kvm/book3s_xics.c | 2 +-
+ arch/powerpc/kvm/book3s_xive.c | 6 +++---
+ arch/powerpc/kvm/e500mc.c | 2 +-
+ arch/powerpc/mm/book3s64/hash_pgtable.c | 2 +-
+ arch/powerpc/mm/book3s64/hash_utils.c | 4 ++--
+ arch/powerpc/mm/book3s64/pgtable.c | 2 +-
+ arch/powerpc/mm/book3s64/radix_pgtable.c | 2 +-
+ arch/powerpc/mm/book3s64/radix_tlb.c | 2 +-
+ arch/powerpc/mm/book3s64/slb.c | 4 ++--
+ arch/powerpc/mm/init_64.c | 4 ++--
+ arch/powerpc/mm/nohash/book3e_hugetlbpage.c | 2 +-
+ arch/powerpc/mm/nohash/kaslr_booke.c | 2 +-
+ arch/powerpc/mm/pgtable-frag.c | 2 +-
+ arch/powerpc/perf/8xx-pmu.c | 2 +-
+ arch/powerpc/perf/core-book3s.c | 6 +++---
+ arch/powerpc/perf/imc-pmu.c | 4 ++--
+ arch/powerpc/perf/isa207-common.c | 6 +++---
+ arch/powerpc/platforms/512x/clock-commonclk.c | 2 +-
+ arch/powerpc/platforms/512x/mpc512x_shared.c | 2 +-
+ arch/powerpc/platforms/52xx/mpc52xx_common.c | 2 +-
+ arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 2 +-
+ arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | 2 +-
+ arch/powerpc/platforms/85xx/mpc85xx_cds.c | 2 +-
+ arch/powerpc/platforms/86xx/gef_ppc9a.c | 2 +-
+ arch/powerpc/platforms/86xx/gef_sbc310.c | 2 +-
+ arch/powerpc/platforms/86xx/gef_sbc610.c | 2 +-
+ arch/powerpc/platforms/book3s/vas-api.c | 2 +-
+ arch/powerpc/platforms/cell/cbe_regs.c | 2 +-
+ arch/powerpc/platforms/cell/iommu.c | 2 +-
+ arch/powerpc/platforms/cell/spider-pci.c | 2 +-
+ arch/powerpc/platforms/cell/spu_manage.c | 2 +-
+ arch/powerpc/platforms/powermac/low_i2c.c | 2 +-
+ arch/powerpc/platforms/powernv/eeh-powernv.c | 10 +++++-----
+ arch/powerpc/platforms/powernv/idle.c | 4 ++--
+ arch/powerpc/platforms/powernv/ocxl.c | 2 +-
+ arch/powerpc/platforms/powernv/opal-fadump.c | 2 +-
+ arch/powerpc/platforms/powernv/opal-lpc.c | 2 +-
+ arch/powerpc/platforms/powernv/opal-memory-errors.c | 2 +-
+ arch/powerpc/platforms/powernv/pci-sriov.c | 2 +-
+ arch/powerpc/platforms/ps3/mm.c | 2 +-
+ arch/powerpc/platforms/ps3/system-bus.c | 2 +-
+ arch/powerpc/platforms/pseries/eeh_pseries.c | 2 +-
+ arch/powerpc/platforms/pseries/iommu.c | 2 +-
+ arch/powerpc/platforms/pseries/setup.c | 4 ++--
+ arch/powerpc/platforms/pseries/vas-sysfs.c | 2 +-
+ arch/powerpc/platforms/pseries/vas.c | 2 +-
+ arch/powerpc/sysdev/fsl_lbc.c | 2 +-
+ arch/powerpc/sysdev/fsl_pci.c | 2 +-
+ arch/powerpc/sysdev/ge/ge_pic.c | 2 +-
+ arch/powerpc/sysdev/mpic_msgr.c | 2 +-
+ arch/powerpc/sysdev/mpic_msi.c | 2 +-
+ arch/powerpc/sysdev/mpic_timer.c | 2 +-
+ arch/powerpc/sysdev/mpic_u3msi.c | 2 +-
+ arch/powerpc/sysdev/xive/native.c | 2 +-
+ arch/powerpc/xmon/ppc-opc.c | 2 +-
+ arch/powerpc/xmon/xmon.c | 2 +-
+ 83 files changed, 104 insertions(+), 104 deletions(-)
+
+diff --git a/arch/powerpc/boot/cuboot-hotfoot.c b/arch/powerpc/boot/cuboot-hotfoot.c
+index 888a6b9bfead..0e5532f855d6 100644
+--- a/arch/powerpc/boot/cuboot-hotfoot.c
++++ b/arch/powerpc/boot/cuboot-hotfoot.c
+@@ -70,7 +70,7 @@ static void hotfoot_fixups(void)
+
+ printf("Fixing devtree for 4M Flash\n");
+
+- /* First fix up the base addresse */
++ /* First fix up the base address */
+ getprop(devp, "reg", regs, sizeof(regs));
+ regs[0] = 0;
+ regs[1] = 0xffc00000;
+diff --git a/arch/powerpc/crypto/aes-spe-glue.c b/arch/powerpc/crypto/aes-spe-glue.c
+index c2b23b69d7b1..e8dfe9fb0266 100644
+--- a/arch/powerpc/crypto/aes-spe-glue.c
++++ b/arch/powerpc/crypto/aes-spe-glue.c
+@@ -404,7 +404,7 @@ static int ppc_xts_decrypt(struct skcipher_request *req)
+
+ /*
+ * Algorithm definitions. Disabling alignment (cra_alignmask=0) was chosen
+- * because the e500 platform can handle unaligned reads/writes very efficently.
++ * because the e500 platform can handle unaligned reads/writes very efficiently.
+ * This improves IPsec thoughput by another few percent. Additionally we assume
+ * that AES context is always aligned to at least 8 bytes because it is created
+ * with kmalloc() in the crypto infrastructure
+diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
+index ae0fdef0ac11..2a271a6d6924 100644
+--- a/arch/powerpc/kernel/cputable.c
++++ b/arch/powerpc/kernel/cputable.c
+@@ -2025,7 +2025,7 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset,
+ * oprofile_cpu_type already has a value, then we are
+ * possibly overriding a real PVR with a logical one,
+ * and, in that case, keep the current value for
+- * oprofile_cpu_type. Futhermore, let's ensure that the
++ * oprofile_cpu_type. Furthermore, let's ensure that the
+ * fix for the PMAO bug is enabled on compatibility mode.
+ */
+ if (old.oprofile_cpu_type != NULL) {
+diff --git a/arch/powerpc/kernel/dawr.c b/arch/powerpc/kernel/dawr.c
+index 64e423d2fe0f..30d4eca88d17 100644
+--- a/arch/powerpc/kernel/dawr.c
++++ b/arch/powerpc/kernel/dawr.c
+@@ -27,7 +27,7 @@ int set_dawr(int nr, struct arch_hw_breakpoint *brk)
+ dawrx |= (brk->type & (HW_BRK_TYPE_PRIV_ALL)) >> 3;
+ /*
+ * DAWR length is stored in field MDR bits 48:53. Matches range in
+- * doublewords (64 bits) baised by -1 eg. 0b000000=1DW and
++ * doublewords (64 bits) biased by -1 eg. 0b000000=1DW and
+ * 0b111111=64DW.
+ * brk->hw_len is in bytes.
+ * This aligns up to double word size, shifts and does the bias.
+diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
+index 28bb1e7263a6..ab316e155ea9 100644
+--- a/arch/powerpc/kernel/eeh.c
++++ b/arch/powerpc/kernel/eeh.c
+@@ -1329,7 +1329,7 @@ int eeh_pe_set_option(struct eeh_pe *pe, int option)
+
+ /*
+ * EEH functionality could possibly be disabled, just
+- * return error for the case. And the EEH functinality
++ * return error for the case. And the EEH functionality
+ * isn't expected to be disabled on one specific PE.
+ */
+ switch (option) {
+@@ -1804,7 +1804,7 @@ static int eeh_debugfs_break_device(struct pci_dev *pdev)
+ * PE freeze. Using the in_8() accessor skips the eeh detection hook
+ * so the freeze hook so the EEH Detection machinery won't be
+ * triggered here. This is to match the usual behaviour of EEH
+- * where the HW will asyncronously freeze a PE and it's up to
++ * where the HW will asynchronously freeze a PE and it's up to
+ * the kernel to notice and deal with it.
+ *
+ * 3. Turn Memory space back on. This is more important for VFs
+diff --git a/arch/powerpc/kernel/eeh_event.c b/arch/powerpc/kernel/eeh_event.c
+index a7a8dc182efb..c23a454af08a 100644
+--- a/arch/powerpc/kernel/eeh_event.c
++++ b/arch/powerpc/kernel/eeh_event.c
+@@ -143,7 +143,7 @@ int __eeh_send_failure_event(struct eeh_pe *pe)
+ int eeh_send_failure_event(struct eeh_pe *pe)
+ {
+ /*
+- * If we've manually supressed recovery events via debugfs
++ * If we've manually suppressed recovery events via debugfs
+ * then just drop it on the floor.
+ */
+ if (eeh_debugfs_no_recover) {
+diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
+index dc2350b288cf..aa29b9b7920f 100644
+--- a/arch/powerpc/kernel/fadump.c
++++ b/arch/powerpc/kernel/fadump.c
+@@ -1665,8 +1665,8 @@ int __init setup_fadump(void)
+ }
+ /*
+ * Use subsys_initcall_sync() here because there is dependency with
+- * crash_save_vmcoreinfo_init(), which mush run first to ensure vmcoreinfo initialization
+- * is done before regisering with f/w.
++ * crash_save_vmcoreinfo_init(), which must run first to ensure vmcoreinfo initialization
++ * is done before registering with f/w.
+ */
+ subsys_initcall_sync(setup_fadump);
+ #else /* !CONFIG_PRESERVE_FA_DUMP */
+diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
+index a0432ef46967..e25b796682cc 100644
+--- a/arch/powerpc/kernel/module_32.c
++++ b/arch/powerpc/kernel/module_32.c
+@@ -99,7 +99,7 @@ static unsigned long get_plt_size(const Elf32_Ehdr *hdr,
+
+ /* Sort the relocation information based on a symbol and
+ * addend key. This is a stable O(n*log n) complexity
+- * alogrithm but it will reduce the complexity of
++ * algorithm but it will reduce the complexity of
+ * count_relocs() to linear complexity O(n)
+ */
+ sort((void *)hdr + sechdrs[i].sh_offset,
+diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
+index 794720530442..2cce576edbc5 100644
+--- a/arch/powerpc/kernel/module_64.c
++++ b/arch/powerpc/kernel/module_64.c
+@@ -194,7 +194,7 @@ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
+
+ /* Sort the relocation information based on a symbol and
+ * addend key. This is a stable O(n*log n) complexity
+- * alogrithm but it will reduce the complexity of
++ * algorithm but it will reduce the complexity of
+ * count_relocs() to linear complexity O(n)
+ */
+ sort((void *)sechdrs[i].sh_addr,
+@@ -361,7 +361,7 @@ static inline int create_ftrace_stub(struct ppc64_stub_entry *entry,
+ entry->jump[1] |= PPC_HA(reladdr);
+ entry->jump[2] |= PPC_LO(reladdr);
+
+- /* Eventhough we don't use funcdata in the stub, it's needed elsewhere. */
++ /* Even though we don't use funcdata in the stub, it's needed elsewhere. */
+ entry->funcdata = func_desc(addr);
+ entry->magic = STUB_MAGIC;
+
+diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
+index 8bc9cf62cd93..9a97a93bd11c 100644
+--- a/arch/powerpc/kernel/pci-common.c
++++ b/arch/powerpc/kernel/pci-common.c
+@@ -1688,7 +1688,7 @@ EXPORT_SYMBOL_GPL(pcibios_scan_phb);
+ static void fixup_hide_host_resource_fsl(struct pci_dev *dev)
+ {
+ int i, class = dev->class >> 8;
+- /* When configured as agent, programing interface = 1 */
++ /* When configured as agent, programming interface = 1 */
+ int prog_if = dev->class & 0xf;
+
+ if ((class == PCI_CLASS_PROCESSOR_POWERPC ||
+diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
+index c3024f104765..6f2b0cc1ddd6 100644
+--- a/arch/powerpc/kernel/pci_of_scan.c
++++ b/arch/powerpc/kernel/pci_of_scan.c
+@@ -244,7 +244,7 @@ EXPORT_SYMBOL(of_create_pci_dev);
+ * @dev: pci_dev structure for the bridge
+ *
+ * of_scan_bus() calls this routine for each PCI bridge that it finds, and
+- * this routine in turn call of_scan_bus() recusively to scan for more child
++ * this routine in turn call of_scan_bus() recursively to scan for more child
+ * devices.
+ */
+ void of_scan_pci_bridge(struct pci_dev *dev)
+diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
+index 9be279469a85..3940db48db77 100644
+--- a/arch/powerpc/kernel/process.c
++++ b/arch/powerpc/kernel/process.c
+@@ -307,7 +307,7 @@ static void __giveup_vsx(struct task_struct *tsk)
+ unsigned long msr = tsk->thread.regs->msr;
+
+ /*
+- * We should never be ssetting MSR_VSX without also setting
++ * We should never be setting MSR_VSX without also setting
+ * MSR_FP and MSR_VEC
+ */
+ WARN_ON((msr & MSR_VSX) && !((msr & MSR_FP) && (msr & MSR_VEC)));
+@@ -645,7 +645,7 @@ static void do_break_handler(struct pt_regs *regs)
+ return;
+ }
+
+- /* Otherwise findout which DAWR caused exception and disable it. */
++ /* Otherwise find out which DAWR caused exception and disable it. */
+ wp_get_instr_detail(regs, &instr, &type, &size, &ea);
+
+ for (i = 0; i < nr_wp_slots(); i++) {
+diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
+index 0ac5faacc909..ace861ec4c4c 100644
+--- a/arch/powerpc/kernel/prom_init.c
++++ b/arch/powerpc/kernel/prom_init.c
+@@ -3416,7 +3416,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
+ *
+ * PowerMacs use a different mechanism to spin CPUs
+ *
+- * (This must be done after instanciating RTAS)
++ * (This must be done after instantiating RTAS)
+ */
+ if (of_platform != PLATFORM_POWERMAC)
+ prom_hold_cpus();
+diff --git a/arch/powerpc/kernel/ptrace/ptrace-view.c b/arch/powerpc/kernel/ptrace/ptrace-view.c
+index f15bc78caf71..076d867412c7 100644
+--- a/arch/powerpc/kernel/ptrace/ptrace-view.c
++++ b/arch/powerpc/kernel/ptrace/ptrace-view.c
+@@ -174,7 +174,7 @@ int ptrace_get_reg(struct task_struct *task, int regno, unsigned long *data)
+
+ /*
+ * softe copies paca->irq_soft_mask variable state. Since irq_soft_mask is
+- * no more used as a flag, lets force usr to alway see the softe value as 1
++ * no more used as a flag, lets force usr to always see the softe value as 1
+ * which means interrupts are not soft disabled.
+ */
+ if (IS_ENABLED(CONFIG_PPC64) && regno == PT_SOFTE) {
+diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
+index a99179d83538..bc817a5619d6 100644
+--- a/arch/powerpc/kernel/rtas_flash.c
++++ b/arch/powerpc/kernel/rtas_flash.c
+@@ -120,7 +120,7 @@ static struct kmem_cache *flash_block_cache = NULL;
+ /*
+ * Local copy of the flash block list.
+ *
+- * The rtas_firmware_flash_list varable will be
++ * The rtas_firmware_flash_list variable will be
+ * set once the data is fully read.
+ *
+ * For convenience as we build the list we use virtual addrs,
+diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
+index 518ae5aa9410..3acf2782acdf 100644
+--- a/arch/powerpc/kernel/setup-common.c
++++ b/arch/powerpc/kernel/setup-common.c
+@@ -279,7 +279,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
+ proc_freq / 1000000, proc_freq % 1000000);
+
+ /* If we are a Freescale core do a simple check so
+- * we dont have to keep adding cases in the future */
++ * we don't have to keep adding cases in the future */
+ if (PVR_VER(pvr) & 0x8000) {
+ switch (PVR_VER(pvr)) {
+ case 0x8000: /* 7441/7450/7451, Voyager */
+diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
+index 73d483b07ff3..858fc13b8c51 100644
+--- a/arch/powerpc/kernel/signal_64.c
++++ b/arch/powerpc/kernel/signal_64.c
+@@ -123,7 +123,7 @@ static long notrace __unsafe_setup_sigcontext(struct sigcontext __user *sc,
+ #endif
+ struct pt_regs *regs = tsk->thread.regs;
+ unsigned long msr = regs->msr;
+- /* Force usr to alway see softe as 1 (interrupts enabled) */
++ /* Force usr to always see softe as 1 (interrupts enabled) */
+ unsigned long softe = 0x1;
+
+ BUG_ON(tsk != current);
+diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
+index de0f6f09a5dd..a69df557e2b7 100644
+--- a/arch/powerpc/kernel/smp.c
++++ b/arch/powerpc/kernel/smp.c
+@@ -1102,7 +1102,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
+ DBG("smp_prepare_cpus\n");
+
+ /*
+- * setup_cpu may need to be called on the boot cpu. We havent
++ * setup_cpu may need to be called on the boot cpu. We haven't
+ * spun any cpus up but lets be paranoid.
+ */
+ BUG_ON(boot_cpuid != smp_processor_id());
+diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
+index f80cce0e3899..4bf757ebe13d 100644
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -829,7 +829,7 @@ static void __read_persistent_clock(struct timespec64 *ts)
+ static int first = 1;
+
+ ts->tv_nsec = 0;
+- /* XXX this is a litle fragile but will work okay in the short term */
++ /* XXX this is a little fragile but will work okay in the short term */
+ if (first) {
+ first = 0;
+ if (ppc_md.time_init)
+@@ -974,7 +974,7 @@ void secondary_cpu_time_init(void)
+ */
+ start_cpu_decrementer();
+
+- /* FIME: Should make unrelatred change to move snapshot_timebase
++ /* FIME: Should make unrelated change to move snapshot_timebase
+ * call here ! */
+ register_decrementer_clockevent(smp_processor_id());
+ }
+diff --git a/arch/powerpc/kernel/watchdog.c b/arch/powerpc/kernel/watchdog.c
+index bfc27496fe7e..7d28b9553654 100644
+--- a/arch/powerpc/kernel/watchdog.c
++++ b/arch/powerpc/kernel/watchdog.c
+@@ -56,7 +56,7 @@
+ * solved by also having a SMP watchdog where all CPUs check all other
+ * CPUs heartbeat.
+ *
+- * The SMP checker can detect lockups on other CPUs. A gobal "pending"
++ * The SMP checker can detect lockups on other CPUs. A global "pending"
+ * cpumask is kept, containing all CPUs which enable the watchdog. Each
+ * CPU clears their pending bit in their heartbeat timer. When the bitmask
+ * becomes empty, the last CPU to clear its pending bit updates a global
+diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c
+index 6cc7793b8420..c29c639551fe 100644
+--- a/arch/powerpc/kexec/core_64.c
++++ b/arch/powerpc/kexec/core_64.c
+@@ -406,7 +406,7 @@ static int __init export_htab_values(void)
+ if (!node)
+ return -ENODEV;
+
+- /* remove any stale propertys so ours can be found */
++ /* remove any stale properties so ours can be found */
+ of_remove_property(node, of_find_property(node, htab_base_prop.name, NULL));
+ of_remove_property(node, of_find_property(node, htab_size_prop.name, NULL));
+
+diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
+index 0aeb51738ca9..1137c4df726c 100644
+--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
++++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
+@@ -58,7 +58,7 @@ struct kvm_resize_hpt {
+ /* Possible values and their usage:
+ * <0 an error occurred during allocation,
+ * -EBUSY allocation is in the progress,
+- * 0 allocation made successfuly.
++ * 0 allocation made successfully.
+ */
+ int error;
+
+diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
+index fdeda6a9cff4..fdcc7b287dd8 100644
+--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
++++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
+@@ -453,7 +453,7 @@ static long kvmppc_rm_ua_to_hpa(struct kvm_vcpu *vcpu, unsigned long mmu_seq,
+ * we are doing this on secondary cpus and current task there
+ * is not the hypervisor. Also this is safe against THP in the
+ * host, because an IPI to primary thread will wait for the secondary
+- * to exit which will agains result in the below page table walk
++ * to exit which will again result in the below page table walk
+ * to finish.
+ */
+ /* an rmap lock won't make it safe. because that just ensure hash
+diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
+index fdb57be71aa6..5bbfb2eed127 100644
+--- a/arch/powerpc/kvm/book3s_emulate.c
++++ b/arch/powerpc/kvm/book3s_emulate.c
+@@ -268,7 +268,7 @@ int kvmppc_core_emulate_op_pr(struct kvm_vcpu *vcpu,
+
+ /*
+ * add rules to fit in ISA specification regarding TM
+- * state transistion in TM disable/Suspended state,
++ * state transition in TM disable/Suspended state,
+ * and target TM state is TM inactive(00) state. (the
+ * change should be suppressed).
+ */
+diff --git a/arch/powerpc/kvm/book3s_hv_p9_entry.c b/arch/powerpc/kvm/book3s_hv_p9_entry.c
+index a28e5b3daabd..ac38c1cad378 100644
+--- a/arch/powerpc/kvm/book3s_hv_p9_entry.c
++++ b/arch/powerpc/kvm/book3s_hv_p9_entry.c
+@@ -379,7 +379,7 @@ void restore_p9_host_os_sprs(struct kvm_vcpu *vcpu,
+ {
+ /*
+ * current->thread.xxx registers must all be restored to host
+- * values before a potential context switch, othrewise the context
++ * values before a potential context switch, otherwise the context
+ * switch itself will overwrite current->thread.xxx with the values
+ * from the guest SPRs.
+ */
+diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c b/arch/powerpc/kvm/book3s_hv_uvmem.c
+index 36f2314c58e5..598006301620 100644
+--- a/arch/powerpc/kvm/book3s_hv_uvmem.c
++++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
+@@ -120,7 +120,7 @@ static DEFINE_SPINLOCK(kvmppc_uvmem_bitmap_lock);
+ * content is un-encrypted.
+ *
+ * (c) Normal - The GFN is a normal. The GFN is associated with
+- * a normal VM. The contents of the GFN is accesible to
++ * a normal VM. The contents of the GFN is accessible to
+ * the Hypervisor. Its content is never encrypted.
+ *
+ * States of a VM.
+diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
+index 7bf9e6ca5c2d..d6abed6e51e6 100644
+--- a/arch/powerpc/kvm/book3s_pr.c
++++ b/arch/powerpc/kvm/book3s_pr.c
+@@ -1287,7 +1287,7 @@ int kvmppc_handle_exit_pr(struct kvm_vcpu *vcpu, unsigned int exit_nr)
+
+ /* Get last sc for papr */
+ if (vcpu->arch.papr_enabled) {
+- /* The sc instuction points SRR0 to the next inst */
++ /* The sc instruction points SRR0 to the next inst */
+ emul = kvmppc_get_last_inst(vcpu, INST_SC, &last_sc);
+ if (emul != EMULATE_DONE) {
+ kvmppc_set_pc(vcpu, kvmppc_get_pc(vcpu) - 4);
+diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c
+index ab6d37d78c62..589a8f257120 100644
+--- a/arch/powerpc/kvm/book3s_xics.c
++++ b/arch/powerpc/kvm/book3s_xics.c
+@@ -462,7 +462,7 @@ static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp,
+ * new guy. We cannot assume that the rejected interrupt is less
+ * favored than the new one, and thus doesn't need to be delivered,
+ * because by the time we exit icp_try_to_deliver() the target
+- * processor may well have alrady consumed & completed it, and thus
++ * processor may well have already consumed & completed it, and thus
+ * the rejected interrupt might actually be already acceptable.
+ */
+ if (icp_try_to_deliver(icp, new_irq, state->priority, &reject)) {
+diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
+index c0ce5531d9bc..24d434f1f012 100644
+--- a/arch/powerpc/kvm/book3s_xive.c
++++ b/arch/powerpc/kvm/book3s_xive.c
+@@ -124,7 +124,7 @@ void kvmppc_xive_push_vcpu(struct kvm_vcpu *vcpu)
+ * interrupt might have fired and be on its way to the
+ * host queue while we mask it, and if we unmask it
+ * early enough (re-cede right away), there is a
+- * theorical possibility that it fires again, thus
++ * theoretical possibility that it fires again, thus
+ * landing in the target queue more than once which is
+ * a big no-no.
+ *
+@@ -622,7 +622,7 @@ static int xive_target_interrupt(struct kvm *kvm,
+
+ /*
+ * Targetting rules: In order to avoid losing track of
+- * pending interrupts accross mask and unmask, which would
++ * pending interrupts across mask and unmask, which would
+ * allow queue overflows, we implement the following rules:
+ *
+ * - Unless it was never enabled (or we run out of capacity)
+@@ -1073,7 +1073,7 @@ int kvmppc_xive_clr_mapped(struct kvm *kvm, unsigned long guest_irq,
+ /*
+ * If old_p is set, the interrupt is pending, we switch it to
+ * PQ=11. This will force a resend in the host so the interrupt
+- * isn't lost to whatver host driver may pick it up
++ * isn't lost to whatever host driver may pick it up
+ */
+ if (state->old_p)
+ xive_vm_esb_load(state->pt_data, XIVE_ESB_SET_PQ_11);
+diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
+index fa0d8dbbe484..4ff1372e48d4 100644
+--- a/arch/powerpc/kvm/e500mc.c
++++ b/arch/powerpc/kvm/e500mc.c
+@@ -309,7 +309,7 @@ static int kvmppc_core_vcpu_create_e500mc(struct kvm_vcpu *vcpu)
+ BUILD_BUG_ON(offsetof(struct kvmppc_vcpu_e500, vcpu) != 0);
+ vcpu_e500 = to_e500(vcpu);
+
+- /* Invalid PIR value -- this LPID dosn't have valid state on any cpu */
++ /* Invalid PIR value -- this LPID doesn't have valid state on any cpu */
+ vcpu->arch.oldpir = 0xffffffff;
+
+ err = kvmppc_e500_tlb_init(vcpu_e500);
+diff --git a/arch/powerpc/mm/book3s64/hash_pgtable.c b/arch/powerpc/mm/book3s64/hash_pgtable.c
+index 7ce8914992e3..2e0cad5817ba 100644
+--- a/arch/powerpc/mm/book3s64/hash_pgtable.c
++++ b/arch/powerpc/mm/book3s64/hash_pgtable.c
+@@ -377,7 +377,7 @@ int hash__has_transparent_hugepage(void)
+ if (mmu_psize_defs[MMU_PAGE_16M].shift != PMD_SHIFT)
+ return 0;
+ /*
+- * We need to make sure that we support 16MB hugepage in a segement
++ * We need to make sure that we support 16MB hugepage in a segment
+ * with base page size 64K or 4K. We only enable THP with a PAGE_SIZE
+ * of 64K.
+ */
+diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c
+index 985cabdd7f67..5b69b271707e 100644
+--- a/arch/powerpc/mm/book3s64/hash_utils.c
++++ b/arch/powerpc/mm/book3s64/hash_utils.c
+@@ -1343,7 +1343,7 @@ static int subpage_protection(struct mm_struct *mm, unsigned long ea)
+ spp >>= 30 - 2 * ((ea >> 12) & 0xf);
+
+ /*
+- * 0 -> full premission
++ * 0 -> full permission
+ * 1 -> Read only
+ * 2 -> no access.
+ * We return the flag that need to be cleared.
+@@ -1664,7 +1664,7 @@ DEFINE_INTERRUPT_HANDLER(do_hash_fault)
+
+ err = hash_page_mm(mm, ea, access, TRAP(regs), flags);
+ if (unlikely(err < 0)) {
+- // failed to instert a hash PTE due to an hypervisor error
++ // failed to insert a hash PTE due to an hypervisor error
+ if (user_mode(regs)) {
+ if (IS_ENABLED(CONFIG_PPC_SUBPAGE_PROT) && err == -2)
+ _exception(SIGSEGV, regs, SEGV_ACCERR, ea);
+diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c
+index 052e6590f84f..071bb66c3ad9 100644
+--- a/arch/powerpc/mm/book3s64/pgtable.c
++++ b/arch/powerpc/mm/book3s64/pgtable.c
+@@ -331,7 +331,7 @@ static pmd_t *__alloc_for_pmdcache(struct mm_struct *mm)
+ spin_lock(&mm->page_table_lock);
+ /*
+ * If we find pgtable_page set, we return
+- * the allocated page with single fragement
++ * the allocated page with single fragment
+ * count.
+ */
+ if (likely(!mm->context.pmd_frag)) {
+diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
+index def04631a74d..db2f3d193448 100644
+--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
++++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
+@@ -359,7 +359,7 @@ static void __init radix_init_pgtable(void)
+ if (!cpu_has_feature(CPU_FTR_HVMODE) &&
+ cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) {
+ /*
+- * Older versions of KVM on these machines perfer if the
++ * Older versions of KVM on these machines prefer if the
+ * guest only uses the low 19 PID bits.
+ */
+ mmu_pid_bits = 19;
+diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c
+index 7724af19ed7e..dda51fef2d2e 100644
+--- a/arch/powerpc/mm/book3s64/radix_tlb.c
++++ b/arch/powerpc/mm/book3s64/radix_tlb.c
+@@ -397,7 +397,7 @@ static inline void _tlbie_pid(unsigned long pid, unsigned long ric)
+
+ /*
+ * Workaround the fact that the "ric" argument to __tlbie_pid
+- * must be a compile-time contraint to match the "i" constraint
++ * must be a compile-time constraint to match the "i" constraint
+ * in the asm statement.
+ */
+ switch (ric) {
+diff --git a/arch/powerpc/mm/book3s64/slb.c b/arch/powerpc/mm/book3s64/slb.c
+index 81091b9587f6..6956f637a38c 100644
+--- a/arch/powerpc/mm/book3s64/slb.c
++++ b/arch/powerpc/mm/book3s64/slb.c
+@@ -347,7 +347,7 @@ void slb_setup_new_exec(void)
+ /*
+ * We have no good place to clear the slb preload cache on exec,
+ * flush_thread is about the earliest arch hook but that happens
+- * after we switch to the mm and have aleady preloaded the SLBEs.
++ * after we switch to the mm and have already preloaded the SLBEs.
+ *
+ * For the most part that's probably okay to use entries from the
+ * previous exec, they will age out if unused. It may turn out to
+@@ -615,7 +615,7 @@ static void slb_cache_update(unsigned long esid_data)
+ } else {
+ /*
+ * Our cache is full and the current cache content strictly
+- * doesn't indicate the active SLB conents. Bump the ptr
++ * doesn't indicate the active SLB contents. Bump the ptr
+ * so that switch_slb() will ignore the cache.
+ */
+ local_paca->slb_cache_ptr = SLB_CACHE_ENTRIES + 1;
+diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
+index 83c0ee9fbf05..2e11952057f8 100644
+--- a/arch/powerpc/mm/init_64.c
++++ b/arch/powerpc/mm/init_64.c
+@@ -111,7 +111,7 @@ static int __meminit vmemmap_populated(unsigned long vmemmap_addr, int vmemmap_m
+ }
+
+ /*
+- * vmemmap virtual address space management does not have a traditonal page
++ * vmemmap virtual address space management does not have a traditional page
+ * table to track which virtual struct pages are backed by physical mapping.
+ * The virtual to physical mappings are tracked in a simple linked list
+ * format. 'vmemmap_list' maintains the entire vmemmap physical mapping at
+@@ -128,7 +128,7 @@ static struct vmemmap_backing *next;
+
+ /*
+ * The same pointer 'next' tracks individual chunks inside the allocated
+- * full page during the boot time and again tracks the freeed nodes during
++ * full page during the boot time and again tracks the freed nodes during
+ * runtime. It is racy but it does not happen as they are separated by the
+ * boot process. Will create problem if some how we have memory hotplug
+ * operation during boot !!
+diff --git a/arch/powerpc/mm/nohash/book3e_hugetlbpage.c b/arch/powerpc/mm/nohash/book3e_hugetlbpage.c
+index 8b88be91b622..307ca919d393 100644
+--- a/arch/powerpc/mm/nohash/book3e_hugetlbpage.c
++++ b/arch/powerpc/mm/nohash/book3e_hugetlbpage.c
+@@ -142,7 +142,7 @@ book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea, pte_t pte)
+ tsize = shift - 10;
+ /*
+ * We can't be interrupted while we're setting up the MAS
+- * regusters or after we've confirmed that no tlb exists.
++ * registers or after we've confirmed that no tlb exists.
+ */
+ local_irq_save(flags);
+
+diff --git a/arch/powerpc/mm/nohash/kaslr_booke.c b/arch/powerpc/mm/nohash/kaslr_booke.c
+index 5f81c076621f..37eb8d80bd53 100644
+--- a/arch/powerpc/mm/nohash/kaslr_booke.c
++++ b/arch/powerpc/mm/nohash/kaslr_booke.c
+@@ -311,7 +311,7 @@ static unsigned long __init kaslr_choose_location(void *dt_ptr, phys_addr_t size
+ ram = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, true, true);
+ linear_sz = min_t(unsigned long, ram, SZ_512M);
+
+- /* If the linear size is smaller than 64M, do not randmize */
++ /* If the linear size is smaller than 64M, do not randomize */
+ if (linear_sz < SZ_64M)
+ return 0;
+
+diff --git a/arch/powerpc/mm/pgtable-frag.c b/arch/powerpc/mm/pgtable-frag.c
+index 97ae4935da79..20652daa1d7e 100644
+--- a/arch/powerpc/mm/pgtable-frag.c
++++ b/arch/powerpc/mm/pgtable-frag.c
+@@ -83,7 +83,7 @@ static pte_t *__alloc_for_ptecache(struct mm_struct *mm, int kernel)
+ spin_lock(&mm->page_table_lock);
+ /*
+ * If we find pgtable_page set, we return
+- * the allocated page with single fragement
++ * the allocated page with single fragment
+ * count.
+ */
+ if (likely(!pte_frag_get(&mm->context))) {
+diff --git a/arch/powerpc/perf/8xx-pmu.c b/arch/powerpc/perf/8xx-pmu.c
+index 4738c4dbf567..308a2e40d7be 100644
+--- a/arch/powerpc/perf/8xx-pmu.c
++++ b/arch/powerpc/perf/8xx-pmu.c
+@@ -157,7 +157,7 @@ static void mpc8xx_pmu_del(struct perf_event *event, int flags)
+
+ mpc8xx_pmu_read(event);
+
+- /* If it was the last user, stop counting to avoid useles overhead */
++ /* If it was the last user, stop counting to avoid useless overhead */
+ switch (event_type(event)) {
+ case PERF_8xx_ID_CPU_CYCLES:
+ break;
+diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
+index 3adc08254875..03c64a0195df 100644
+--- a/arch/powerpc/perf/core-book3s.c
++++ b/arch/powerpc/perf/core-book3s.c
+@@ -1142,7 +1142,7 @@ static u64 check_and_compute_delta(u64 prev, u64 val)
+ /*
+ * POWER7 can roll back counter values, if the new value is smaller
+ * than the previous value it will cause the delta and the counter to
+- * have bogus values unless we rolled a counter over. If a coutner is
++ * have bogus values unless we rolled a counter over. If a counter is
+ * rolled back, it will be smaller, but within 256, which is the maximum
+ * number of events to rollback at once. If we detect a rollback
+ * return 0. This can lead to a small lack of precision in the
+@@ -2052,7 +2052,7 @@ static int power_pmu_event_init(struct perf_event *event)
+ /*
+ * PMU config registers have fields that are
+ * reserved and some specific values for bit fields are reserved.
+- * For ex., MMCRA[61:62] is Randome Sampling Mode (SM)
++ * For ex., MMCRA[61:62] is Random Sampling Mode (SM)
+ * and value of 0b11 to this field is reserved.
+ * Check for invalid values in attr.config.
+ */
+@@ -2442,7 +2442,7 @@ static void __perf_event_interrupt(struct pt_regs *regs)
+ }
+
+ /*
+- * During system wide profling or while specific CPU is monitored for an
++ * During system wide profiling or while specific CPU is monitored for an
+ * event, some corner cases could cause PMC to overflow in idle path. This
+ * will trigger a PMI after waking up from idle. Since counter values are _not_
+ * saved/restored in idle path, can lead to below "Can't find PMC" message.
+diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
+index 526d4b767534..498f1a2f7658 100644
+--- a/arch/powerpc/perf/imc-pmu.c
++++ b/arch/powerpc/perf/imc-pmu.c
+@@ -521,7 +521,7 @@ static int nest_imc_event_init(struct perf_event *event)
+
+ /*
+ * Nest HW counter memory resides in a per-chip reserve-memory (HOMER).
+- * Get the base memory addresss for this cpu.
++ * Get the base memory address for this cpu.
+ */
+ chip_id = cpu_to_chip_id(event->cpu);
+
+@@ -674,7 +674,7 @@ static int ppc_core_imc_cpu_offline(unsigned int cpu)
+ /*
+ * Check whether core_imc is registered. We could end up here
+ * if the cpuhotplug callback registration fails. i.e, callback
+- * invokes the offline path for all sucessfully registered cpus.
++ * invokes the offline path for all successfully registered cpus.
+ * At this stage, core_imc pmu will not be registered and we
+ * should return here.
+ *
+diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c
+index bb5d64862bc9..42abbcfc73da 100644
+--- a/arch/powerpc/perf/isa207-common.c
++++ b/arch/powerpc/perf/isa207-common.c
+@@ -82,11 +82,11 @@ static unsigned long sdar_mod_val(u64 event)
+ static void mmcra_sdar_mode(u64 event, unsigned long *mmcra)
+ {
+ /*
+- * MMCRA[SDAR_MODE] specifices how the SDAR should be updated in
+- * continous sampling mode.
++ * MMCRA[SDAR_MODE] specifies how the SDAR should be updated in
++ * continuous sampling mode.
+ *
+ * Incase of Power8:
+- * MMCRA[SDAR_MODE] will be programmed as "0b01" for continous sampling
++ * MMCRA[SDAR_MODE] will be programmed as "0b01" for continuous sampling
+ * mode and will be un-changed when setting MMCRA[63] (Marked events).
+ *
+ * Incase of Power9/power10:
+diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c
+index 0b03d812baae..0652c7e69225 100644
+--- a/arch/powerpc/platforms/512x/clock-commonclk.c
++++ b/arch/powerpc/platforms/512x/clock-commonclk.c
+@@ -663,7 +663,7 @@ static void __init mpc512x_clk_setup_mclk(struct mclk_setup_data *entry, size_t
+ * the PSC/MSCAN/SPDIF (serial drivers et al) need the MCLK
+ * for their bitrate
+ * - in the absence of "aliases" for clocks we need to create
+- * individial 'struct clk' items for whatever might get
++ * individual 'struct clk' items for whatever might get
+ * referenced or looked up, even if several of those items are
+ * identical from the logical POV (their rate value)
+ * - for easier future maintenance and for better reflection of
+diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
+index e3411663edad..96d9cf49560d 100644
+--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
++++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
+@@ -289,7 +289,7 @@ static void __init mpc512x_setup_diu(void)
+
+ /*
+ * We do not allocate and configure new area for bitmap buffer
+- * because it would requere copying bitmap data (splash image)
++ * because it would require copying bitmap data (splash image)
+ * and so negatively affect boot time. Instead we reserve the
+ * already configured frame buffer area so that it won't be
+ * destroyed. The starting address of the area to reserve and
+diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
+index 565e3a83dc9e..60aa6015e284 100644
+--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
++++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
+@@ -308,7 +308,7 @@ int mpc5200_psc_ac97_gpio_reset(int psc_number)
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+- /* Reconfiure pin-muxing to gpio */
++ /* Reconfigure pin-muxing to gpio */
+ mux = in_be32(&simple_gpio->port_config);
+ out_be32(&simple_gpio->port_config, mux & (~gpio));
+
+diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+index f862b48b4824..7252d992ca9f 100644
+--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
++++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+@@ -398,7 +398,7 @@ static int mpc52xx_gpt_do_start(struct mpc52xx_gpt_priv *gpt, u64 period,
+ set |= MPC52xx_GPT_MODE_CONTINUOUS;
+
+ /* Determine the number of clocks in the requested period. 64 bit
+- * arithmatic is done here to preserve the precision until the value
++ * arithmetic is done here to preserve the precision until the value
+ * is scaled back down into the u32 range. Period is in 'ns', bus
+ * frequency is in Hz. */
+ clocks = period * (u64)gpt->ipb_freq;
+diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+index b91ebebd9ff2..54dfc63809d3 100644
+--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
++++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+@@ -104,7 +104,7 @@ static void mpc52xx_lpbfifo_kick(struct mpc52xx_lpbfifo_request *req)
+ *
+ * Configure the watermarks so DMA will always complete correctly.
+ * It may be worth experimenting with the ALARM value to see if
+- * there is a performance impacit. However, if it is wrong there
++ * there is a performance impact. However, if it is wrong there
+ * is a risk of DMA not transferring the last chunk of data
+ */
+ if (write) {
+diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+index 5bd487030256..ad0b88ecfd0c 100644
+--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
++++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+@@ -151,7 +151,7 @@ static void __init mpc85xx_cds_pci_irq_fixup(struct pci_dev *dev)
+ */
+ case PCI_DEVICE_ID_VIA_82C586_2:
+ /* There are two USB controllers.
+- * Identify them by functon number
++ * Identify them by function number
+ */
+ if (PCI_FUNC(dev->devfn) == 3)
+ dev->irq = 11;
+diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c
+index 44bbbc535e1d..884da08806ce 100644
+--- a/arch/powerpc/platforms/86xx/gef_ppc9a.c
++++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c
+@@ -180,7 +180,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+ *
+ * This function is called to determine whether the BSP is compatible with the
+ * supplied device-tree, which is assumed to be the correct one for the actual
+- * board. It is expected thati, in the future, a kernel may support multiple
++ * board. It is expected that, in the future, a kernel may support multiple
+ * boards.
+ */
+ static int __init gef_ppc9a_probe(void)
+diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c
+index 46d6d3d4957a..baaf1ab07016 100644
+--- a/arch/powerpc/platforms/86xx/gef_sbc310.c
++++ b/arch/powerpc/platforms/86xx/gef_sbc310.c
+@@ -167,7 +167,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+ *
+ * This function is called to determine whether the BSP is compatible with the
+ * supplied device-tree, which is assumed to be the correct one for the actual
+- * board. It is expected thati, in the future, a kernel may support multiple
++ * board. It is expected that, in the future, a kernel may support multiple
+ * boards.
+ */
+ static int __init gef_sbc310_probe(void)
+diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c
+index acf2c6c3c1eb..120caf6af71d 100644
+--- a/arch/powerpc/platforms/86xx/gef_sbc610.c
++++ b/arch/powerpc/platforms/86xx/gef_sbc610.c
+@@ -157,7 +157,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+ *
+ * This function is called to determine whether the BSP is compatible with the
+ * supplied device-tree, which is assumed to be the correct one for the actual
+- * board. It is expected thati, in the future, a kernel may support multiple
++ * board. It is expected that, in the future, a kernel may support multiple
+ * boards.
+ */
+ static int __init gef_sbc610_probe(void)
+diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c
+index f9a1615b74da..c0799fb26b6d 100644
+--- a/arch/powerpc/platforms/book3s/vas-api.c
++++ b/arch/powerpc/platforms/book3s/vas-api.c
+@@ -30,7 +30,7 @@
+ *
+ * where "vas_copy" and "vas_paste" are defined in copy-paste.h.
+ * copy/paste returns to the user space directly. So refer NX hardware
+- * documententation for exact copy/paste usage and completion / error
++ * documentation for exact copy/paste usage and completion / error
+ * conditions.
+ */
+
+diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c
+index 1c4c53bec66c..03512a41bd7e 100644
+--- a/arch/powerpc/platforms/cell/cbe_regs.c
++++ b/arch/powerpc/platforms/cell/cbe_regs.c
+@@ -23,7 +23,7 @@
+ * Current implementation uses "cpu" nodes. We build our own mapping
+ * array of cpu numbers to cpu nodes locally for now to allow interrupt
+ * time code to have a fast path rather than call of_get_cpu_node(). If
+- * we implement cpu hotplug, we'll have to install an appropriate norifier
++ * we implement cpu hotplug, we'll have to install an appropriate notifier
+ * in order to release references to the cpu going away
+ */
+ static struct cbe_regs_map
+diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
+index 25e726bf0172..3f141cf5e580 100644
+--- a/arch/powerpc/platforms/cell/iommu.c
++++ b/arch/powerpc/platforms/cell/iommu.c
+@@ -582,7 +582,7 @@ static int cell_of_bus_notify(struct notifier_block *nb, unsigned long action,
+ {
+ struct device *dev = data;
+
+- /* We are only intereted in device addition */
++ /* We are only interested in device addition */
+ if (action != BUS_NOTIFY_ADD_DEVICE)
+ return 0;
+
+diff --git a/arch/powerpc/platforms/cell/spider-pci.c b/arch/powerpc/platforms/cell/spider-pci.c
+index a1c293f42a1f..3a2ea8376e32 100644
+--- a/arch/powerpc/platforms/cell/spider-pci.c
++++ b/arch/powerpc/platforms/cell/spider-pci.c
+@@ -81,7 +81,7 @@ static int __init spiderpci_pci_setup_chip(struct pci_controller *phb,
+ /*
+ * On CellBlade, we can't know that which XDR memory is used by
+ * kmalloc() to allocate dummy_page_va.
+- * In order to imporve the performance, the XDR which is used to
++ * In order to improve the performance, the XDR which is used to
+ * allocate dummy_page_va is the nearest the spider-pci.
+ * We have to select the CBE which is the nearest the spider-pci
+ * to allocate memory from the best XDR, but I don't know that
+diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c
+index ddf8742f09a3..080ed2d2c682 100644
+--- a/arch/powerpc/platforms/cell/spu_manage.c
++++ b/arch/powerpc/platforms/cell/spu_manage.c
+@@ -457,7 +457,7 @@ static void __init init_affinity_node(int cbe)
+
+ /*
+ * Walk through each phandle in vicinity property of the spu
+- * (tipically two vicinity phandles per spe node)
++ * (typically two vicinity phandles per spe node)
+ */
+ for (i = 0; i < (lenp / sizeof(phandle)); i++) {
+ if (vic_handles[i] == avoid_ph)
+diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
+index df89d916236d..9aded0188ce8 100644
+--- a/arch/powerpc/platforms/powermac/low_i2c.c
++++ b/arch/powerpc/platforms/powermac/low_i2c.c
+@@ -1472,7 +1472,7 @@ int __init pmac_i2c_init(void)
+ smu_i2c_probe();
+ #endif
+
+- /* Now add plaform functions for some known devices */
++ /* Now add platform functions for some known devices */
+ pmac_i2c_devscan(pmac_i2c_dev_create);
+
+ return 0;
+diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
+index 89e22c460ebf..33f7b959c810 100644
+--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
++++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
+@@ -390,7 +390,7 @@ static struct eeh_dev *pnv_eeh_probe(struct pci_dev *pdev)
+ * should be blocked until PE reset. MMIO access is dropped
+ * by hardware certainly. In order to drop PCI config requests,
+ * one more flag (EEH_PE_CFG_RESTRICTED) is introduced, which
+- * will be checked in the backend for PE state retrival. If
++ * will be checked in the backend for PE state retrieval. If
+ * the PE becomes frozen for the first time and the flag has
+ * been set for the PE, we will set EEH_PE_CFG_BLOCKED for
+ * that PE to block its config space.
+@@ -981,7 +981,7 @@ static int pnv_eeh_do_af_flr(struct pci_dn *pdn, int option)
+ case EEH_RESET_FUNDAMENTAL:
+ /*
+ * Wait for Transaction Pending bit to clear. A word-aligned
+- * test is used, so we use the conrol offset rather than status
++ * test is used, so we use the control offset rather than status
+ * and shift the test bit to match.
+ */
+ pnv_eeh_wait_for_pending(pdn, "AF",
+@@ -1048,7 +1048,7 @@ static int pnv_eeh_reset(struct eeh_pe *pe, int option)
+ * frozen state during PE reset. However, the good idea here from
+ * benh is to keep frozen state before we get PE reset done completely
+ * (until BAR restore). With the frozen state, HW drops illegal IO
+- * or MMIO access, which can incur recrusive frozen PE during PE
++ * or MMIO access, which can incur recursive frozen PE during PE
+ * reset. The side effect is that EEH core has to clear the frozen
+ * state explicitly after BAR restore.
+ */
+@@ -1095,8 +1095,8 @@ static int pnv_eeh_reset(struct eeh_pe *pe, int option)
+ * bus is behind a hotplug slot and it will use the slot provided
+ * reset methods to prevent spurious hotplug events during the reset.
+ *
+- * Fundemental resets need to be handled internally to EEH since the
+- * PCI core doesn't really have a concept of a fundemental reset,
++ * Fundamental resets need to be handled internally to EEH since the
++ * PCI core doesn't really have a concept of a fundamental reset,
+ * mainly because there's no standard way to generate one. Only a
+ * few devices require an FRESET so it should be fine.
+ */
+diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c
+index a6677a111aca..6f94b808dd39 100644
+--- a/arch/powerpc/platforms/powernv/idle.c
++++ b/arch/powerpc/platforms/powernv/idle.c
+@@ -112,7 +112,7 @@ static int __init pnv_save_sprs_for_deep_states(void)
+ if (rc != 0)
+ return rc;
+
+- /* Only p8 needs to set extra HID regiters */
++ /* Only p8 needs to set extra HID registers */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300)) {
+ uint64_t hid1_val = mfspr(SPRN_HID1);
+ uint64_t hid4_val = mfspr(SPRN_HID4);
+@@ -1204,7 +1204,7 @@ static void __init pnv_arch300_idle_init(void)
+ * The idle code does not deal with TB loss occurring
+ * in a shallower state than SPR loss, so force it to
+ * behave like SPRs are lost if TB is lost. POWER9 would
+- * never encouter this, but a POWER8 core would if it
++ * never encounter this, but a POWER8 core would if it
+ * implemented the stop instruction. So this is for forward
+ * compatibility.
+ */
+diff --git a/arch/powerpc/platforms/powernv/ocxl.c b/arch/powerpc/platforms/powernv/ocxl.c
+index 28b009b46464..27c936075031 100644
+--- a/arch/powerpc/platforms/powernv/ocxl.c
++++ b/arch/powerpc/platforms/powernv/ocxl.c
+@@ -289,7 +289,7 @@ int pnv_ocxl_get_pasid_count(struct pci_dev *dev, int *count)
+ * be used by a function depends on how many functions exist
+ * on the device. The NPU needs to be configured to know how
+ * many bits are available to PASIDs and how many are to be
+- * used by the function BDF indentifier.
++ * used by the function BDF identifier.
+ *
+ * We only support one AFU-carrying function for now.
+ */
+diff --git a/arch/powerpc/platforms/powernv/opal-fadump.c b/arch/powerpc/platforms/powernv/opal-fadump.c
+index 9d74d3950a52..c1bcd2d4826e 100644
+--- a/arch/powerpc/platforms/powernv/opal-fadump.c
++++ b/arch/powerpc/platforms/powernv/opal-fadump.c
+@@ -206,7 +206,7 @@ static u64 opal_fadump_init_mem_struct(struct fw_dump *fadump_conf)
+ opal_fdm->region_cnt = cpu_to_be16(reg_cnt);
+
+ /*
+- * Kernel metadata is passed to f/w and retrieved in capture kerenl.
++ * Kernel metadata is passed to f/w and retrieved in capture kernel.
+ * So, use it to save fadump header address instead of calculating it.
+ */
+ opal_fdm->fadumphdr_addr = cpu_to_be64(be64_to_cpu(opal_fdm->rgn[0].dest) +
+diff --git a/arch/powerpc/platforms/powernv/opal-lpc.c b/arch/powerpc/platforms/powernv/opal-lpc.c
+index 5390c888db16..d129d6d45a50 100644
+--- a/arch/powerpc/platforms/powernv/opal-lpc.c
++++ b/arch/powerpc/platforms/powernv/opal-lpc.c
+@@ -197,7 +197,7 @@ static ssize_t lpc_debug_read(struct file *filp, char __user *ubuf,
+
+ /*
+ * Select access size based on count and alignment and
+- * access type. IO and MEM only support byte acceses,
++ * access type. IO and MEM only support byte accesses,
+ * FW supports all 3.
+ */
+ len = 1;
+diff --git a/arch/powerpc/platforms/powernv/opal-memory-errors.c b/arch/powerpc/platforms/powernv/opal-memory-errors.c
+index 1e8e17df9ce8..a1754a28265d 100644
+--- a/arch/powerpc/platforms/powernv/opal-memory-errors.c
++++ b/arch/powerpc/platforms/powernv/opal-memory-errors.c
+@@ -82,7 +82,7 @@ static DECLARE_WORK(mem_error_work, mem_error_handler);
+
+ /*
+ * opal_memory_err_event - notifier handler that queues up the opal message
+- * to be preocessed later.
++ * to be processed later.
+ */
+ static int opal_memory_err_event(struct notifier_block *nb,
+ unsigned long msg_type, void *msg)
+diff --git a/arch/powerpc/platforms/powernv/pci-sriov.c b/arch/powerpc/platforms/powernv/pci-sriov.c
+index 04155aaaadb1..fe3d111b881c 100644
+--- a/arch/powerpc/platforms/powernv/pci-sriov.c
++++ b/arch/powerpc/platforms/powernv/pci-sriov.c
+@@ -699,7 +699,7 @@ static int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
+ return -ENOSPC;
+ }
+
+- /* allocate a contigious block of PEs for our VFs */
++ /* allocate a contiguous block of PEs for our VFs */
+ base_pe = pnv_ioda_alloc_pe(phb, num_vfs);
+ if (!base_pe) {
+ pci_err(pdev, "Unable to allocate PEs for %d VFs\n", num_vfs);
+diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
+index 5ce924611b94..63ef61ed7597 100644
+--- a/arch/powerpc/platforms/ps3/mm.c
++++ b/arch/powerpc/platforms/ps3/mm.c
+@@ -364,7 +364,7 @@ static void __maybe_unused _dma_dump_region(const struct ps3_dma_region *r,
+ * @bus_addr: Starting ioc bus address of the area to map.
+ * @len: Length in bytes of the area to map.
+ * @link: A struct list_head used with struct ps3_dma_region.chunk_list, the
+- * list of all chuncks owned by the region.
++ * list of all chunks owned by the region.
+ *
+ * This implementation uses a very simple dma page manager
+ * based on the dma_chunk structure. This scheme assumes
+diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
+index b637bf292047..2502e9b17df4 100644
+--- a/arch/powerpc/platforms/ps3/system-bus.c
++++ b/arch/powerpc/platforms/ps3/system-bus.c
+@@ -601,7 +601,7 @@ static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page,
+ iopte_flag |= CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW;
+ break;
+ default:
+- /* not happned */
++ /* not happened */
+ BUG();
+ }
+ result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
+diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
+index 09fafcf2d3a0..f0b2bca750da 100644
+--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
++++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
+@@ -510,7 +510,7 @@ static int pseries_eeh_set_option(struct eeh_pe *pe, int option)
+ int ret = 0;
+
+ /*
+- * When we're enabling or disabling EEH functioality on
++ * When we're enabling or disabling EEH functionality on
+ * the particular PE, the PE config address is possibly
+ * unavailable. Therefore, we have to figure it out from
+ * the FDT node.
+diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
+index 4d991cf840d9..7639e7355df2 100644
+--- a/arch/powerpc/platforms/pseries/iommu.c
++++ b/arch/powerpc/platforms/pseries/iommu.c
+@@ -1430,7 +1430,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
+
+ pci->table_group->tables[1] = newtbl;
+
+- /* Keep default DMA window stuct if removed */
++ /* Keep default DMA window struct if removed */
+ if (default_win_removed) {
+ tbl->it_size = 0;
+ vfree(tbl->it_map);
+diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
+index f27735f623ba..27bed0dd866e 100644
+--- a/arch/powerpc/platforms/pseries/setup.c
++++ b/arch/powerpc/platforms/pseries/setup.c
+@@ -658,7 +658,7 @@ static resource_size_t pseries_get_iov_fw_value(struct pci_dev *dev, int resno,
+ */
+ num_res = of_read_number(&indexes[NUM_RES_PROPERTY], 1);
+ if (resno >= num_res)
+- return 0; /* or an errror */
++ return 0; /* or an error */
+
+ i = START_OF_ENTRIES + NEXT_ENTRY * resno;
+ switch (value) {
+@@ -762,7 +762,7 @@ static void pseries_pci_fixup_iov_resources(struct pci_dev *pdev)
+
+ if (!pdev->is_physfn)
+ return;
+- /*Firmware must support open sriov otherwise dont configure*/
++ /*Firmware must support open sriov otherwise don't configure*/
+ indexes = of_get_property(dn, "ibm,open-sriov-vf-bar-info", NULL);
+ if (indexes)
+ of_pci_parse_iov_addrs(pdev, indexes);
+diff --git a/arch/powerpc/platforms/pseries/vas-sysfs.c b/arch/powerpc/platforms/pseries/vas-sysfs.c
+index ec65586cbeb3..241c84374045 100644
+--- a/arch/powerpc/platforms/pseries/vas-sysfs.c
++++ b/arch/powerpc/platforms/pseries/vas-sysfs.c
+@@ -76,7 +76,7 @@ struct vas_sysfs_entry {
+ * Create sysfs interface:
+ * /sys/devices/vas/vas0/gzip/default_capabilities
+ * This directory contains the following VAS GZIP capabilities
+- * for the defaule credit type.
++ * for the default credit type.
+ * /sys/devices/vas/vas0/gzip/default_capabilities/nr_total_credits
+ * Total number of default credits assigned to the LPAR which
+ * can be changed with DLPAR operation.
+diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c
+index ec643bbdb67f..500a1fc4a1d7 100644
+--- a/arch/powerpc/platforms/pseries/vas.c
++++ b/arch/powerpc/platforms/pseries/vas.c
+@@ -801,7 +801,7 @@ int vas_reconfig_capabilties(u8 type, int new_nr_creds)
+ atomic_set(&caps->nr_total_credits, new_nr_creds);
+ /*
+ * The total number of available credits may be decreased or
+- * inceased with DLPAR operation. Means some windows have to be
++ * increased with DLPAR operation. Means some windows have to be
+ * closed / reopened. Hold the vas_pseries_mutex so that the
+ * the user space can not open new windows.
+ */
+diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c
+index 1985e067e952..18acfb4e82af 100644
+--- a/arch/powerpc/sysdev/fsl_lbc.c
++++ b/arch/powerpc/sysdev/fsl_lbc.c
+@@ -37,7 +37,7 @@ EXPORT_SYMBOL(fsl_lbc_ctrl_dev);
+ *
+ * This function converts a base address of lbc into the right format for the
+ * BR register. If the SOC has eLBC then it returns 32bit physical address
+- * else it convers a 34bit local bus physical address to correct format of
++ * else it converts a 34bit local bus physical address to correct format of
+ * 32bit address for BR register (Example: MPC8641).
+ */
+ u32 fsl_lbc_addr(phys_addr_t addr_base)
+diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
+index ef49ead8bf2e..3c430a6a6a4e 100644
+--- a/arch/powerpc/sysdev/fsl_pci.c
++++ b/arch/powerpc/sysdev/fsl_pci.c
+@@ -218,7 +218,7 @@ static void setup_pci_atmu(struct pci_controller *hose)
+ * windows have implemented the default target value as 0xf
+ * for CCSR space.In all Freescale legacy devices the target
+ * of 0xf is reserved for local memory space. 9132 Rev1.0
+- * now has local mempry space mapped to target 0x0 instead of
++ * now has local memory space mapped to target 0x0 instead of
+ * 0xf. Hence adding a workaround to remove the target 0xf
+ * defined for memory space from Inbound window attributes.
+ */
+diff --git a/arch/powerpc/sysdev/ge/ge_pic.c b/arch/powerpc/sysdev/ge/ge_pic.c
+index 02553a8ce191..413b375c4d28 100644
+--- a/arch/powerpc/sysdev/ge/ge_pic.c
++++ b/arch/powerpc/sysdev/ge/ge_pic.c
+@@ -150,7 +150,7 @@ static struct irq_chip gef_pic_chip = {
+ };
+
+
+-/* When an interrupt is being configured, this call allows some flexibilty
++/* When an interrupt is being configured, this call allows some flexibility
+ * in deciding which irq_chip structure is used
+ */
+ static int gef_pic_host_map(struct irq_domain *h, unsigned int virq,
+diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c
+index 36ec0bdd8b63..a25413826b63 100644
+--- a/arch/powerpc/sysdev/mpic_msgr.c
++++ b/arch/powerpc/sysdev/mpic_msgr.c
+@@ -99,7 +99,7 @@ void mpic_msgr_disable(struct mpic_msgr *msgr)
+ EXPORT_SYMBOL_GPL(mpic_msgr_disable);
+
+ /* The following three functions are used to compute the order and number of
+- * the message register blocks. They are clearly very inefficent. However,
++ * the message register blocks. They are clearly very inefficient. However,
+ * they are called *only* a few times during device initialization.
+ */
+ static unsigned int mpic_msgr_number_of_blocks(void)
+diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c
+index f412d6ad0b66..9936c014ac7d 100644
+--- a/arch/powerpc/sysdev/mpic_msi.c
++++ b/arch/powerpc/sysdev/mpic_msi.c
+@@ -37,7 +37,7 @@ static int __init mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
+ /* Reserve source numbers we know are reserved in the HW.
+ *
+ * This is a bit of a mix of U3 and U4 reserves but that's going
+- * to work fine, we have plenty enugh numbers left so let's just
++ * to work fine, we have plenty enough numbers left so let's just
+ * mark anything we don't like reserved.
+ */
+ for (i = 0; i < 8; i++)
+diff --git a/arch/powerpc/sysdev/mpic_timer.c b/arch/powerpc/sysdev/mpic_timer.c
+index 444e9ce42d0a..b2f0a73e8f93 100644
+--- a/arch/powerpc/sysdev/mpic_timer.c
++++ b/arch/powerpc/sysdev/mpic_timer.c
+@@ -255,7 +255,7 @@ EXPORT_SYMBOL(mpic_start_timer);
+
+ /**
+ * mpic_stop_timer - stop hardware timer
+- * @handle: the timer to be stoped
++ * @handle: the timer to be stopped
+ *
+ * The timer periodically generates an interrupt. Unless user stops the timer.
+ */
+diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
+index 3f4841dfefb5..73d129594078 100644
+--- a/arch/powerpc/sysdev/mpic_u3msi.c
++++ b/arch/powerpc/sysdev/mpic_u3msi.c
+@@ -78,7 +78,7 @@ static u64 find_u4_magic_addr(struct pci_dev *pdev, unsigned int hwirq)
+
+ /* U4 PCIe MSIs need to write to the special register in
+ * the bridge that generates interrupts. There should be
+- * theorically a register at 0xf8005000 where you just write
++ * theoretically a register at 0xf8005000 where you just write
+ * the MSI number and that triggers the right interrupt, but
+ * unfortunately, this is busted in HW, the bridge endian swaps
+ * the value and hits the wrong nibble in the register.
+diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c
+index f940428ad13f..45f72fc715fc 100644
+--- a/arch/powerpc/sysdev/xive/native.c
++++ b/arch/powerpc/sysdev/xive/native.c
+@@ -617,7 +617,7 @@ bool __init xive_native_init(void)
+
+ xive_tima_os = r.start;
+
+- /* Grab size of provisionning pages */
++ /* Grab size of provisioning pages */
+ xive_parse_provisioning(np);
+
+ /* Switch the XIVE to exploitation mode */
+diff --git a/arch/powerpc/xmon/ppc-opc.c b/arch/powerpc/xmon/ppc-opc.c
+index dfb80810b16c..0774d711453e 100644
+--- a/arch/powerpc/xmon/ppc-opc.c
++++ b/arch/powerpc/xmon/ppc-opc.c
+@@ -408,7 +408,7 @@ const struct powerpc_operand powerpc_operands[] =
+ #define FXM4 FXM + 1
+ { 0xff, 12, insert_fxm, extract_fxm,
+ PPC_OPERAND_OPTIONAL | PPC_OPERAND_OPTIONAL_VALUE},
+- /* If the FXM4 operand is ommitted, use the sentinel value -1. */
++ /* If the FXM4 operand is omitted, use the sentinel value -1. */
+ { -1, -1, NULL, NULL, 0},
+
+ /* The IMM20 field in an LI instruction. */
+diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
+index fd72753e8ad5..27da7d5c2024 100644
+--- a/arch/powerpc/xmon/xmon.c
++++ b/arch/powerpc/xmon/xmon.c
+@@ -2024,7 +2024,7 @@ static void dump_206_sprs(void)
+ if (!cpu_has_feature(CPU_FTR_ARCH_206))
+ return;
+
+- /* Actually some of these pre-date 2.06, but whatevs */
++ /* Actually some of these pre-date 2.06, but whatever */
+
+ printf("srr0 = %.16lx srr1 = %.16lx dsisr = %.8lx\n",
+ mfspr(SPRN_SRR0), mfspr(SPRN_SRR1), mfspr(SPRN_DSISR));
+--
+2.35.1
+
--- /dev/null
+From c2355d47f3142400302af27a63c283872fb8f65a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 18:11:19 +1000
+Subject: powerpc/iommu: Fix iommu_table_in_use for a small default DMA window
+ case
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+[ Upstream commit d80f6de9d601c30b53c17f00cb7cfe3169f2ddad ]
+
+The existing iommu_table_in_use() helper checks if the kernel is using
+any of TCEs. There are some reserved TCEs:
+1) the very first one if DMA window starts from 0 to avoid having a zero
+but still valid DMA handle;
+2) it_reserved_start..it_reserved_end to exclude MMIO32 window in case
+the default window spans across that - this is the default for the first
+DMA window on PowerNV.
+
+When 1) is the case and 2) is not the helper does not skip 1) and returns
+wrong status.
+
+This only seems occurring when passing through a PCI device to a nested
+guest (not something we support really well) so it has not been seen
+before.
+
+This fixes the bug by adding a special case for no MMIO32 reservation.
+
+Fixes: 3c33066a2190 ("powerpc/kernel/iommu: Add new iommu_table_in_use() helper")
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220714081119.3714605-1-aik@ozlabs.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/iommu.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
+index 07093b7cdcb9..a67fd54ccc57 100644
+--- a/arch/powerpc/kernel/iommu.c
++++ b/arch/powerpc/kernel/iommu.c
+@@ -776,6 +776,11 @@ bool iommu_table_in_use(struct iommu_table *tbl)
+ /* ignore reserved bit0 */
+ if (tbl->it_offset == 0)
+ start = 1;
++
++ /* Simple case with no reserved MMIO32 region */
++ if (!tbl->it_reserved_start && !tbl->it_reserved_end)
++ return find_next_bit(tbl->it_map, tbl->it_size, start) != tbl->it_size;
++
+ end = tbl->it_reserved_start - tbl->it_offset;
+ if (find_next_bit(tbl->it_map, end, start) != end)
+ return true;
+--
+2.35.1
+
--- /dev/null
+From ebd6af5e5855b1936258eac18160777f5f25793c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 20:38:32 +1000
+Subject: powerpc/pci: Fix PHB numbering when using opal-phbid
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit f4b39e88b42d13366b831270306326b5c20971ca ]
+
+The recent change to the PHB numbering logic has a logic error in the
+handling of "ibm,opal-phbid".
+
+When an "ibm,opal-phbid" property is present, &prop is written to and
+ret is set to zero.
+
+The following call to of_alias_get_id() is skipped because ret == 0.
+
+But then the if (ret >= 0) is true, and the body of that if statement
+sets prop = ret which throws away the value that was just read from
+"ibm,opal-phbid".
+
+Fix the logic by only doing the ret >= 0 check in the of_alias_get_id()
+case.
+
+Fixes: 0fe1e96fef0a ("powerpc/pci: Prefer PCI domain assignment via DT 'linux,pci-domain' and alias")
+Reviewed-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220802105723.1055178-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/pci-common.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
+index 7daa00f3942e..aa37faeb80ee 100644
+--- a/arch/powerpc/kernel/pci-common.c
++++ b/arch/powerpc/kernel/pci-common.c
+@@ -90,11 +90,13 @@ static int get_phb_number(struct device_node *dn)
+ }
+ if (ret)
+ ret = of_property_read_u64(dn, "ibm,opal-phbid", &prop);
+- if (ret)
++
++ if (ret) {
+ ret = of_alias_get_id(dn, "pci");
+- if (ret >= 0) {
+- prop = ret;
+- ret = 0;
++ if (ret >= 0) {
++ prop = ret;
++ ret = 0;
++ }
+ }
+ if (ret) {
+ u32 prop_32;
+--
+2.35.1
+
--- /dev/null
+From 6b87e9b2087a91399aa1f2ca95985d92a9a3b592 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Jul 2022 12:21:48 +0200
+Subject: powerpc/pci: Prefer PCI domain assignment via DT 'linux,pci-domain'
+ and alias
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit 0fe1e96fef0a5c53b4c0d1500d356f3906000f81 ]
+
+Other Linux architectures use DT property 'linux,pci-domain' for
+specifying fixed PCI domain of PCI controller specified in Device-Tree.
+
+And lot of Freescale powerpc boards have defined numbered pci alias in
+Device-Tree for every PCIe controller which number specify preferred PCI
+domain.
+
+So prefer usage of DT property 'linux,pci-domain' (via function
+of_get_pci_domain_nr()) and DT pci alias (via function
+of_alias_get_id()) on powerpc architecture for assigning PCI domain to
+PCI controller.
+
+Fixes: 63a72284b159 ("powerpc/pci: Assign fixed PHB number based on device-tree properties")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220706102148.5060-2-pali@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/pci-common.c | 27 +++++++++++++++++++--------
+ 1 file changed, 19 insertions(+), 8 deletions(-)
+
+diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
+index 9a97a93bd11c..7daa00f3942e 100644
+--- a/arch/powerpc/kernel/pci-common.c
++++ b/arch/powerpc/kernel/pci-common.c
+@@ -74,16 +74,30 @@ void __init set_pci_dma_ops(const struct dma_map_ops *dma_ops)
+ static int get_phb_number(struct device_node *dn)
+ {
+ int ret, phb_id = -1;
+- u32 prop_32;
+ u64 prop;
+
+ /*
+ * Try fixed PHB numbering first, by checking archs and reading
+- * the respective device-tree properties. Firstly, try powernv by
+- * reading "ibm,opal-phbid", only present in OPAL environment.
++ * the respective device-tree properties. Firstly, try reading
++ * standard "linux,pci-domain", then try reading "ibm,opal-phbid"
++ * (only present in powernv OPAL environment), then try device-tree
++ * alias and as the last try to use lower bits of "reg" property.
+ */
+- ret = of_property_read_u64(dn, "ibm,opal-phbid", &prop);
++ ret = of_get_pci_domain_nr(dn);
++ if (ret >= 0) {
++ prop = ret;
++ ret = 0;
++ }
++ if (ret)
++ ret = of_property_read_u64(dn, "ibm,opal-phbid", &prop);
++ if (ret)
++ ret = of_alias_get_id(dn, "pci");
++ if (ret >= 0) {
++ prop = ret;
++ ret = 0;
++ }
+ if (ret) {
++ u32 prop_32;
+ ret = of_property_read_u32_index(dn, "reg", 1, &prop_32);
+ prop = prop_32;
+ }
+@@ -95,10 +109,7 @@ static int get_phb_number(struct device_node *dn)
+ if ((phb_id >= 0) && !test_and_set_bit(phb_id, phb_bitmap))
+ return phb_id;
+
+- /*
+- * If not pseries nor powernv, or if fixed PHB numbering tried to add
+- * the same PHB number twice, then fallback to dynamic PHB numbering.
+- */
++ /* If everything fails then fallback to dynamic PHB numbering. */
+ phb_id = find_first_zero_bit(phb_bitmap, MAX_PHBS);
+ BUG_ON(phb_id >= MAX_PHBS);
+ set_bit(phb_id, phb_bitmap);
+--
+2.35.1
+
--- /dev/null
+From dbe88b3d56eb33ee5d29fdacd0295499e376ce50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 May 2022 19:52:56 +0530
+Subject: powerpc/perf: Optimize clearing the pending PMI and remove WARN_ON
+ for PMI check in power_pmu_disable
+
+From: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+
+[ Upstream commit 890005a7d98f7452cfe86dcfb2aeeb7df01132ce ]
+
+commit 2c9ac51b850d ("powerpc/perf: Fix PMU callbacks to clear
+pending PMI before resetting an overflown PMC") added a new
+function "pmi_irq_pending" in hw_irq.h. This function is to check
+if there is a PMI marked as pending in Paca (PACA_IRQ_PMI).This is
+used in power_pmu_disable in a WARN_ON. The intention here is to
+provide a warning if there is PMI pending, but no counter is found
+overflown.
+
+During some of the perf runs, below warning is hit:
+
+WARNING: CPU: 36 PID: 0 at arch/powerpc/perf/core-book3s.c:1332 power_pmu_disable+0x25c/0x2c0
+ Modules linked in:
+ -----
+
+ NIP [c000000000141c3c] power_pmu_disable+0x25c/0x2c0
+ LR [c000000000141c8c] power_pmu_disable+0x2ac/0x2c0
+ Call Trace:
+ [c000000baffcfb90] [c000000000141c8c] power_pmu_disable+0x2ac/0x2c0 (unreliable)
+ [c000000baffcfc10] [c0000000003e2f8c] perf_pmu_disable+0x4c/0x60
+ [c000000baffcfc30] [c0000000003e3344] group_sched_out.part.124+0x44/0x100
+ [c000000baffcfc80] [c0000000003e353c] __perf_event_disable+0x13c/0x240
+ [c000000baffcfcd0] [c0000000003dd334] event_function+0xc4/0x140
+ [c000000baffcfd20] [c0000000003d855c] remote_function+0x7c/0xa0
+ [c000000baffcfd50] [c00000000026c394] flush_smp_call_function_queue+0xd4/0x300
+ [c000000baffcfde0] [c000000000065b24] smp_ipi_demux_relaxed+0xa4/0x100
+ [c000000baffcfe20] [c0000000000cb2b0] xive_muxed_ipi_action+0x20/0x40
+ [c000000baffcfe40] [c000000000207c3c] __handle_irq_event_percpu+0x8c/0x250
+ [c000000baffcfee0] [c000000000207e2c] handle_irq_event_percpu+0x2c/0xa0
+ [c000000baffcff10] [c000000000210a04] handle_percpu_irq+0x84/0xc0
+ [c000000baffcff40] [c000000000205f14] generic_handle_irq+0x54/0x80
+ [c000000baffcff60] [c000000000015740] __do_irq+0x90/0x1d0
+ [c000000baffcff90] [c000000000016990] __do_IRQ+0xc0/0x140
+ [c0000009732f3940] [c000000bafceaca8] 0xc000000bafceaca8
+ [c0000009732f39d0] [c000000000016b78] do_IRQ+0x168/0x1c0
+ [c0000009732f3a00] [c0000000000090c8] hardware_interrupt_common_virt+0x218/0x220
+
+This means that there is no PMC overflown among the active events
+in the PMU, but there is a PMU pending in Paca. The function
+"any_pmc_overflown" checks the PMCs on active events in
+cpuhw->n_events. Code snippet:
+
+<<>>
+if (any_pmc_overflown(cpuhw))
+ clear_pmi_irq_pending();
+ else
+ WARN_ON(pmi_irq_pending());
+<<>>
+
+Here the PMC overflown is not from active event. Example: When we do
+perf record, default cycles and instructions will be running on PMC6
+and PMC5 respectively. It could happen that overflowed event is currently
+not active and pending PMI is for the inactive event. Debug logs from
+trace_printk:
+
+<<>>
+any_pmc_overflown: idx is 5: pmc value is 0xd9a
+power_pmu_disable: PMC1: 0x0, PMC2: 0x0, PMC3: 0x0, PMC4: 0x0, PMC5: 0xd9a, PMC6: 0x80002011
+<<>>
+
+Here active PMC (from idx) is PMC5 , but overflown PMC is PMC6(0x80002011).
+When we handle PMI interrupt for such cases, if the PMC overflown is
+from inactive event, it will be ignored. Reference commit:
+commit bc09c219b2e6 ("powerpc/perf: Fix finding overflowed PMC in interrupt")
+
+Patch addresses two changes:
+1) Fix 1 : Removal of warning ( WARN_ON(pmi_irq_pending()); )
+ We were printing warning if no PMC is found overflown among active PMU
+ events, but PMI pending in PACA. But this could happen in cases where
+ PMC overflown is not in active PMC. An inactive event could have caused
+ the overflow. Hence the warning is not needed. To know pending PMI is
+ from an inactive event, we need to loop through all PMC's which will
+ cause more SPR reads via mfspr and increase in context switch. Also in
+ existing function: perf_event_interrupt, already we ignore PMI's
+ overflown when it is from an inactive PMC.
+
+2) Fix 2: optimization in clearing pending PMI.
+ Currently we check for any active PMC overflown before clearing PMI
+ pending in Paca. This is causing additional SPR read also. From point 1,
+ we know that if PMI pending in Paca from inactive cases, that is going
+ to be ignored during replay. Hence if there is pending PMI in Paca, just
+ clear it irrespective of PMC overflown or not.
+
+In summary, remove the any_pmc_overflown check entirely in
+power_pmu_disable. ie If there is a pending PMI in Paca, clear it, since
+we are in pmu_disable. There could be cases where PMI is pending because
+of inactive PMC ( which later when replayed also will get ignored ), so
+WARN_ON could give false warning. Hence removing it.
+
+Fixes: 2c9ac51b850d ("powerpc/perf: Fix PMU callbacks to clear pending PMI before resetting an overflown PMC")
+Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220522142256.24699-1-atrajeev@linux.vnet.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/perf/core-book3s.c | 35 ++++++++++++++-------------------
+ 1 file changed, 15 insertions(+), 20 deletions(-)
+
+diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
+index b5b42cf0a703..3adc08254875 100644
+--- a/arch/powerpc/perf/core-book3s.c
++++ b/arch/powerpc/perf/core-book3s.c
+@@ -1349,27 +1349,22 @@ static void power_pmu_disable(struct pmu *pmu)
+ * a PMI happens during interrupt replay and perf counter
+ * values are cleared by PMU callbacks before replay.
+ *
+- * If any PMC corresponding to the active PMU events are
+- * overflown, disable the interrupt by clearing the paca
+- * bit for PMI since we are disabling the PMU now.
+- * Otherwise provide a warning if there is PMI pending, but
+- * no counter is found overflown.
++ * Disable the interrupt by clearing the paca bit for PMI
++ * since we are disabling the PMU now. Otherwise provide a
++ * warning if there is PMI pending, but no counter is found
++ * overflown.
++ *
++ * Since power_pmu_disable runs under local_irq_save, it
++ * could happen that code hits a PMC overflow without PMI
++ * pending in paca. Hence only clear PMI pending if it was
++ * set.
++ *
++ * If a PMI is pending, then MSR[EE] must be disabled (because
++ * the masked PMI handler disabling EE). So it is safe to
++ * call clear_pmi_irq_pending().
+ */
+- if (any_pmc_overflown(cpuhw)) {
+- /*
+- * Since power_pmu_disable runs under local_irq_save, it
+- * could happen that code hits a PMC overflow without PMI
+- * pending in paca. Hence only clear PMI pending if it was
+- * set.
+- *
+- * If a PMI is pending, then MSR[EE] must be disabled (because
+- * the masked PMI handler disabling EE). So it is safe to
+- * call clear_pmi_irq_pending().
+- */
+- if (pmi_irq_pending())
+- clear_pmi_irq_pending();
+- } else
+- WARN_ON(pmi_irq_pending());
++ if (pmi_irq_pending())
++ clear_pmi_irq_pending();
+
+ val = mmcra = cpuhw->mmcr.mmcra;
+
+--
+2.35.1
+
--- /dev/null
+From 37bbede69cbc04ca6f4f32b4fd624669282c914d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 16:15:42 +0400
+Subject: powerpc/spufs: Fix refcount leak in spufs_init_isolated_loader
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 6ac059dacffa8ab2f7798f20e4bd3333890c541c ]
+
+of_find_node_by_path() returns remote device nodepointer with
+refcount incremented, we should use of_node_put() on it when done.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 0afacde3df4c ("[POWERPC] spufs: allow isolated mode apps by starting the SPE loader")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220603121543.22884-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/cell/spufs/inode.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
+index 4c702192412f..96f5e2e43018 100644
+--- a/arch/powerpc/platforms/cell/spufs/inode.c
++++ b/arch/powerpc/platforms/cell/spufs/inode.c
+@@ -660,6 +660,7 @@ spufs_init_isolated_loader(void)
+ return;
+
+ loader = of_get_property(dn, "loader", &size);
++ of_node_put(dn);
+ if (!loader)
+ return;
+
+--
+2.35.1
+
--- /dev/null
+From 06d24275b2cc8e49edcf5fc5da224a6ce9e11d3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jun 2022 09:32:23 +0400
+Subject: powerpc/xive: Fix refcount leak in xive_get_max_prio
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 255b650cbec6849443ce2e0cdd187fd5e61c218c ]
+
+of_find_node_by_path() returns a node pointer with
+refcount incremented, we should use of_node_put() on it when done.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: eac1e731b59e ("powerpc/xive: guest exploitation of the XIVE interrupt controller")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220605053225.56125-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/sysdev/xive/spapr.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c
+index b0d36e430dbc..013446f5cdbb 100644
+--- a/arch/powerpc/sysdev/xive/spapr.c
++++ b/arch/powerpc/sysdev/xive/spapr.c
+@@ -716,6 +716,7 @@ static bool __init xive_get_max_prio(u8 *max_prio)
+ }
+
+ reg = of_get_property(rootdn, "ibm,plat-res-int-priorities", &len);
++ of_node_put(rootdn);
+ if (!reg) {
+ pr_err("Failed to read 'ibm,plat-res-int-priorities' property\n");
+ return false;
+--
+2.35.1
+
--- /dev/null
+From 3749f1d520218546b9e366132eda45a20fe2908a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 21:00:29 +0800
+Subject: proc: fix a dentry lock race between release_task and lookup
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+[ Upstream commit d919a1e79bac890421537cf02ae773007bf55e6b ]
+
+Commit 7bc3e6e55acf06 ("proc: Use a list of inodes to flush from proc")
+moved proc_flush_task() behind __exit_signal(). Then, process systemd can
+take long period high cpu usage during releasing task in following
+concurrent processes:
+
+ systemd ps
+kernel_waitid stat(/proc/tgid)
+ do_wait filename_lookup
+ wait_consider_task lookup_fast
+ release_task
+ __exit_signal
+ __unhash_process
+ detach_pid
+ __change_pid // remove task->pid_links
+ d_revalidate -> pid_revalidate // 0
+ d_invalidate(/proc/tgid)
+ shrink_dcache_parent(/proc/tgid)
+ d_walk(/proc/tgid)
+ spin_lock_nested(/proc/tgid/fd)
+ // iterating opened fd
+ proc_flush_pid |
+ d_invalidate (/proc/tgid/fd) |
+ shrink_dcache_parent(/proc/tgid/fd) |
+ shrink_dentry_list(subdirs) ↓
+ shrink_lock_dentry(/proc/tgid/fd) --> race on dentry lock
+
+Function d_invalidate() will remove dentry from hash firstly, but why does
+proc_flush_pid() process dentry '/proc/tgid/fd' before dentry
+'/proc/tgid'? That's because proc_pid_make_inode() adds proc inode in
+reverse order by invoking hlist_add_head_rcu(). But proc should not add
+any inodes under '/proc/tgid' except '/proc/tgid/task/pid', fix it by
+adding inode into 'pid->inodes' only if the inode is /proc/tgid or
+/proc/tgid/task/pid.
+
+Performance regression:
+Create 200 tasks, each task open one file for 50,000 times. Kill all
+tasks when opened files exceed 10,000,000 (cat /proc/sys/fs/file-nr).
+
+Before fix:
+$ time killall -wq aa
+ real 4m40.946s # During this period, we can see 'ps' and 'systemd'
+ taking high cpu usage.
+
+After fix:
+$ time killall -wq aa
+ real 1m20.732s # During this period, we can see 'systemd' taking
+ high cpu usage.
+
+Link: https://lkml.kernel.org/r/20220713130029.4133533-1-chengzhihao1@huawei.com
+Fixes: 7bc3e6e55acf06 ("proc: Use a list of inodes to flush from proc")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216054
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Suggested-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Alexey Dobriyan <adobriyan@gmail.com>
+Cc: Eric Biederman <ebiederm@xmission.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Baoquan He <bhe@redhat.com>
+Cc: Kalesh Singh <kaleshsingh@google.com>
+Cc: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/proc/base.c | 46 ++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 38 insertions(+), 8 deletions(-)
+
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index c1031843cc6a..2f0595e8ec4a 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -1885,7 +1885,7 @@ void proc_pid_evict_inode(struct proc_inode *ei)
+ put_pid(pid);
+ }
+
+-struct inode *proc_pid_make_inode(struct super_block * sb,
++struct inode *proc_pid_make_inode(struct super_block *sb,
+ struct task_struct *task, umode_t mode)
+ {
+ struct inode * inode;
+@@ -1914,11 +1914,6 @@ struct inode *proc_pid_make_inode(struct super_block * sb,
+
+ /* Let the pid remember us for quick removal */
+ ei->pid = pid;
+- if (S_ISDIR(mode)) {
+- spin_lock(&pid->lock);
+- hlist_add_head_rcu(&ei->sibling_inodes, &pid->inodes);
+- spin_unlock(&pid->lock);
+- }
+
+ task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid);
+ security_task_to_inode(task, inode);
+@@ -1931,6 +1926,39 @@ struct inode *proc_pid_make_inode(struct super_block * sb,
+ return NULL;
+ }
+
++/*
++ * Generating an inode and adding it into @pid->inodes, so that task will
++ * invalidate inode's dentry before being released.
++ *
++ * This helper is used for creating dir-type entries under '/proc' and
++ * '/proc/<tgid>/task'. Other entries(eg. fd, stat) under '/proc/<tgid>'
++ * can be released by invalidating '/proc/<tgid>' dentry.
++ * In theory, dentries under '/proc/<tgid>/task' can also be released by
++ * invalidating '/proc/<tgid>' dentry, we reserve it to handle single
++ * thread exiting situation: Any one of threads should invalidate its
++ * '/proc/<tgid>/task/<pid>' dentry before released.
++ */
++static struct inode *proc_pid_make_base_inode(struct super_block *sb,
++ struct task_struct *task, umode_t mode)
++{
++ struct inode *inode;
++ struct proc_inode *ei;
++ struct pid *pid;
++
++ inode = proc_pid_make_inode(sb, task, mode);
++ if (!inode)
++ return NULL;
++
++ /* Let proc_flush_pid find this directory inode */
++ ei = PROC_I(inode);
++ pid = ei->pid;
++ spin_lock(&pid->lock);
++ hlist_add_head_rcu(&ei->sibling_inodes, &pid->inodes);
++ spin_unlock(&pid->lock);
++
++ return inode;
++}
++
+ int pid_getattr(struct user_namespace *mnt_userns, const struct path *path,
+ struct kstat *stat, u32 request_mask, unsigned int query_flags)
+ {
+@@ -3350,7 +3378,8 @@ static struct dentry *proc_pid_instantiate(struct dentry * dentry,
+ {
+ struct inode *inode;
+
+- inode = proc_pid_make_inode(dentry->d_sb, task, S_IFDIR | S_IRUGO | S_IXUGO);
++ inode = proc_pid_make_base_inode(dentry->d_sb, task,
++ S_IFDIR | S_IRUGO | S_IXUGO);
+ if (!inode)
+ return ERR_PTR(-ENOENT);
+
+@@ -3649,7 +3678,8 @@ static struct dentry *proc_task_instantiate(struct dentry *dentry,
+ struct task_struct *task, const void *ptr)
+ {
+ struct inode *inode;
+- inode = proc_pid_make_inode(dentry->d_sb, task, S_IFDIR | S_IRUGO | S_IXUGO);
++ inode = proc_pid_make_base_inode(dentry->d_sb, task,
++ S_IFDIR | S_IRUGO | S_IXUGO);
+ if (!inode)
+ return ERR_PTR(-ENOENT);
+
+--
+2.35.1
+
--- /dev/null
+From ebb81f97b5535dede77e7e1ccd3e1254c0405b02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 May 2022 09:28:54 +0800
+Subject: profiling: fix shift too large makes kernel panic
+
+From: Chen Zhongjin <chenzhongjin@huawei.com>
+
+[ Upstream commit 0fe6ee8f123a4dfb529a5aff07536bb481f34043 ]
+
+2d186afd04d6 ("profiling: fix shift-out-of-bounds bugs") limits shift
+value by [0, BITS_PER_LONG -1], which means [0, 63].
+
+However, syzbot found that the max shift value should be the bit number of
+(_etext - _stext). If shift is outside of this, the "buffer_bytes" will
+be zero and will cause kzalloc(0). Then the kernel panics due to
+dereferencing the returned pointer 16.
+
+This can be easily reproduced by passing a large number like 60 to enable
+profiling and then run readprofile.
+
+LOGS:
+ BUG: kernel NULL pointer dereference, address: 0000000000000010
+ #PF: supervisor write access in kernel mode
+ #PF: error_code(0x0002) - not-present page
+ PGD 6148067 P4D 6148067 PUD 6142067 PMD 0
+ PREEMPT SMP
+ CPU: 4 PID: 184 Comm: readprofile Not tainted 5.18.0+ #162
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014
+ RIP: 0010:read_profile+0x104/0x220
+ RSP: 0018:ffffc900006fbe80 EFLAGS: 00000202
+ RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
+ RDX: ffff888006150000 RSI: 0000000000000001 RDI: ffffffff82aba4a0
+ RBP: 000000000188bb60 R08: 0000000000000010 R09: ffff888006151000
+ R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff82aba4a0
+ R13: 0000000000000000 R14: ffffc900006fbf08 R15: 0000000000020c30
+ FS: 000000000188a8c0(0000) GS:ffff88803ed00000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 0000000000000010 CR3: 0000000006144000 CR4: 00000000000006e0
+ Call Trace:
+ <TASK>
+ proc_reg_read+0x56/0x70
+ vfs_read+0x9a/0x1b0
+ ksys_read+0xa1/0xe0
+ ? fpregs_assert_state_consistent+0x1e/0x40
+ do_syscall_64+0x3a/0x80
+ entry_SYSCALL_64_after_hwframe+0x46/0xb0
+ RIP: 0033:0x4d4b4e
+ RSP: 002b:00007ffebb668d58 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
+ RAX: ffffffffffffffda RBX: 000000000188a8a0 RCX: 00000000004d4b4e
+ RDX: 0000000000000400 RSI: 000000000188bb60 RDI: 0000000000000003
+ RBP: 0000000000000003 R08: 000000000000006e R09: 0000000000000000
+ R10: 0000000000000041 R11: 0000000000000246 R12: 000000000188bb60
+ R13: 0000000000000400 R14: 0000000000000000 R15: 000000000188bb60
+ </TASK>
+ Modules linked in:
+ CR2: 0000000000000010
+Killed
+ ---[ end trace 0000000000000000 ]---
+
+Check prof_len in profile_init() to prevent it be zero.
+
+Link: https://lkml.kernel.org/r/20220531012854.229439-1-chenzhongjin@huawei.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Chen Zhongjin <chenzhongjin@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/profile.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/kernel/profile.c b/kernel/profile.c
+index 37640a0bd8a3..ae82ddfc6a68 100644
+--- a/kernel/profile.c
++++ b/kernel/profile.c
+@@ -109,6 +109,13 @@ int __ref profile_init(void)
+
+ /* only text is profiled */
+ prof_len = (_etext - _stext) >> prof_shift;
++
++ if (!prof_len) {
++ pr_warn("profiling shift: %u too large\n", prof_shift);
++ prof_on = 0;
++ return -EINVAL;
++ }
++
+ buffer_bytes = prof_len*sizeof(atomic_t);
+
+ if (!alloc_cpumask_var(&prof_cpu_mask, GFP_KERNEL))
+--
+2.35.1
+
--- /dev/null
+From cf9c07637a9a542b3feb3b536579622e0121be84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jun 2022 16:06:14 +1000
+Subject: pseries/iommu/ddw: Fix kdump to work in absence of ibm,dma-window
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+[ Upstream commit b1fc44eaa9ba31e28c4125d6b9205a3582b47b5d ]
+
+The pseries platform uses 32bit default DMA window (always 4K pages) and
+optional 64bit DMA window available via DDW ("Dynamic DMA Windows"),
+64K or 2M pages. For ages the default one was not removed and a huge
+window was created in addition. Things changed with SRIOV-enabled
+PowerVM which creates a default-and-bigger DMA window in 64bit space
+(still using 4K pages) for IOV VFs so certain OSes do not need to use
+the DDW API in order to utilize all available TCE budget.
+
+Linux on the other hand removes the default window and creates a bigger
+one (with more TCEs or/and a bigger page size - 64K/2M) in a bid to map
+the entire RAM, and if the new window size is smaller than that - it
+still uses this new bigger window. The result is that the default window
+is removed but the "ibm,dma-window" property is not.
+
+When kdump is invoked, the existing code tries reusing the existing 64bit
+DMA window which location and parameters are stored in the device tree but
+this fails as the new property does not make it to the kdump device tree
+blob. So the code falls back to the default window which does not exist
+anymore although the device tree says that it does. The result of that
+is that PCI devices become unusable and cannot be used for kdumping.
+
+This preserves the DMA64 and DIRECT64 properties in the device tree blob
+for the crash kernel. Since the crash kernel setup is done after device
+drivers are loaded and probed, the proper DMA config is stored at least
+for boot time devices.
+
+Because DDW window is optional and the code configures the default window
+first, the existing code creates an IOMMU table descriptor for
+the non-existing default DMA window. It is harmless for kdump as it does
+not touch the actual window (only reads what is mapped and marks those IO
+pages as used) but it is bad for kexec which clears it thinking it is
+a smaller default window rather than a bigger DDW window.
+
+This removes the "ibm,dma-window" property from the device tree after
+a bigger window is created and the crash kernel setup picks it up.
+
+Fixes: 381ceda88c4c ("powerpc/pseries/iommu: Make use of DDW for indirect mapping")
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Acked-by: Hari Bathini <hbathini@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220629060614.1680476-1-aik@ozlabs.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kexec/file_load_64.c | 54 ++++++++++++++++
+ arch/powerpc/platforms/pseries/iommu.c | 89 ++++++++++++++------------
+ 2 files changed, 102 insertions(+), 41 deletions(-)
+
+diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
+index b4981b651d9a..5d2c22aa34fb 100644
+--- a/arch/powerpc/kexec/file_load_64.c
++++ b/arch/powerpc/kexec/file_load_64.c
+@@ -1038,6 +1038,48 @@ static int update_cpus_node(void *fdt)
+ return ret;
+ }
+
++static int copy_property(void *fdt, int node_offset, const struct device_node *dn,
++ const char *propname)
++{
++ const void *prop, *fdtprop;
++ int len = 0, fdtlen = 0, ret;
++
++ prop = of_get_property(dn, propname, &len);
++ fdtprop = fdt_getprop(fdt, node_offset, propname, &fdtlen);
++
++ if (fdtprop && !prop)
++ ret = fdt_delprop(fdt, node_offset, propname);
++ else if (prop)
++ ret = fdt_setprop(fdt, node_offset, propname, prop, len);
++
++ return ret;
++}
++
++static int update_pci_dma_nodes(void *fdt, const char *dmapropname)
++{
++ struct device_node *dn;
++ int pci_offset, root_offset, ret = 0;
++
++ if (!firmware_has_feature(FW_FEATURE_LPAR))
++ return 0;
++
++ root_offset = fdt_path_offset(fdt, "/");
++ for_each_node_with_property(dn, dmapropname) {
++ pci_offset = fdt_subnode_offset(fdt, root_offset, of_node_full_name(dn));
++ if (pci_offset < 0)
++ continue;
++
++ ret = copy_property(fdt, pci_offset, dn, "ibm,dma-window");
++ if (ret < 0)
++ break;
++ ret = copy_property(fdt, pci_offset, dn, dmapropname);
++ if (ret < 0)
++ break;
++ }
++
++ return ret;
++}
++
+ /**
+ * setup_new_fdt_ppc64 - Update the flattend device-tree of the kernel
+ * being loaded.
+@@ -1099,6 +1141,18 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
+ if (ret < 0)
+ goto out;
+
++#define DIRECT64_PROPNAME "linux,direct64-ddr-window-info"
++#define DMA64_PROPNAME "linux,dma64-ddr-window-info"
++ ret = update_pci_dma_nodes(fdt, DIRECT64_PROPNAME);
++ if (ret < 0)
++ goto out;
++
++ ret = update_pci_dma_nodes(fdt, DMA64_PROPNAME);
++ if (ret < 0)
++ goto out;
++#undef DMA64_PROPNAME
++#undef DIRECT64_PROPNAME
++
+ /* Update memory reserve map */
+ ret = get_reserved_memory_ranges(&rmem);
+ if (ret)
+diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
+index 7639e7355df2..a90024697c11 100644
+--- a/arch/powerpc/platforms/pseries/iommu.c
++++ b/arch/powerpc/platforms/pseries/iommu.c
+@@ -701,6 +701,33 @@ struct iommu_table_ops iommu_table_lpar_multi_ops = {
+ .get = tce_get_pSeriesLP
+ };
+
++/*
++ * Find nearest ibm,dma-window (default DMA window) or direct DMA window or
++ * dynamic 64bit DMA window, walking up the device tree.
++ */
++static struct device_node *pci_dma_find(struct device_node *dn,
++ const __be32 **dma_window)
++{
++ const __be32 *dw = NULL;
++
++ for ( ; dn && PCI_DN(dn); dn = dn->parent) {
++ dw = of_get_property(dn, "ibm,dma-window", NULL);
++ if (dw) {
++ if (dma_window)
++ *dma_window = dw;
++ return dn;
++ }
++ dw = of_get_property(dn, DIRECT64_PROPNAME, NULL);
++ if (dw)
++ return dn;
++ dw = of_get_property(dn, DMA64_PROPNAME, NULL);
++ if (dw)
++ return dn;
++ }
++
++ return NULL;
++}
++
+ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
+ {
+ struct iommu_table *tbl;
+@@ -713,20 +740,10 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
+ pr_debug("pci_dma_bus_setup_pSeriesLP: setting up bus %pOF\n",
+ dn);
+
+- /*
+- * Find nearest ibm,dma-window (default DMA window), walking up the
+- * device tree
+- */
+- for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
+- dma_window = of_get_property(pdn, "ibm,dma-window", NULL);
+- if (dma_window != NULL)
+- break;
+- }
++ pdn = pci_dma_find(dn, &dma_window);
+
+- if (dma_window == NULL) {
++ if (dma_window == NULL)
+ pr_debug(" no ibm,dma-window property !\n");
+- return;
+- }
+
+ ppci = PCI_DN(pdn);
+
+@@ -736,11 +753,13 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
+ if (!ppci->table_group) {
+ ppci->table_group = iommu_pseries_alloc_group(ppci->phb->node);
+ tbl = ppci->table_group->tables[0];
+- iommu_table_setparms_lpar(ppci->phb, pdn, tbl,
+- ppci->table_group, dma_window);
++ if (dma_window) {
++ iommu_table_setparms_lpar(ppci->phb, pdn, tbl,
++ ppci->table_group, dma_window);
+
+- if (!iommu_init_table(tbl, ppci->phb->node, 0, 0))
+- panic("Failed to initialize iommu table");
++ if (!iommu_init_table(tbl, ppci->phb->node, 0, 0))
++ panic("Failed to initialize iommu table");
++ }
+ iommu_register_group(ppci->table_group,
+ pci_domain_nr(bus), 0);
+ pr_debug(" created table: %p\n", ppci->table_group);
+@@ -1233,7 +1252,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
+ bool default_win_removed = false, direct_mapping = false;
+ bool pmem_present;
+ struct pci_dn *pci = PCI_DN(pdn);
+- struct iommu_table *tbl = pci->table_group->tables[0];
++ struct property *default_win = NULL;
+
+ dn = of_find_node_by_type(NULL, "ibm,pmemory");
+ pmem_present = dn != NULL;
+@@ -1290,11 +1309,10 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
+ * for extensions presence.
+ */
+ if (query.windows_available == 0) {
+- struct property *default_win;
+ int reset_win_ext;
+
+ /* DDW + IOMMU on single window may fail if there is any allocation */
+- if (iommu_table_in_use(tbl)) {
++ if (iommu_table_in_use(pci->table_group->tables[0])) {
+ dev_warn(&dev->dev, "current IOMMU table in use, can't be replaced.\n");
+ goto out_failed;
+ }
+@@ -1430,16 +1448,18 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
+
+ pci->table_group->tables[1] = newtbl;
+
+- /* Keep default DMA window struct if removed */
+- if (default_win_removed) {
+- tbl->it_size = 0;
+- vfree(tbl->it_map);
+- tbl->it_map = NULL;
+- }
+-
+ set_iommu_table_base(&dev->dev, newtbl);
+ }
+
++ if (default_win_removed) {
++ iommu_tce_table_put(pci->table_group->tables[0]);
++ pci->table_group->tables[0] = NULL;
++
++ /* default_win is valid here because default_win_removed == true */
++ of_remove_property(pdn, default_win);
++ dev_info(&dev->dev, "Removed default DMA window for %pOF\n", pdn);
++ }
++
+ spin_lock(&dma_win_list_lock);
+ list_add(&window->list, &dma_win_list);
+ spin_unlock(&dma_win_list_lock);
+@@ -1504,13 +1524,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
+ dn = pci_device_to_OF_node(dev);
+ pr_debug(" node is %pOF\n", dn);
+
+- for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->table_group;
+- pdn = pdn->parent) {
+- dma_window = of_get_property(pdn, "ibm,dma-window", NULL);
+- if (dma_window)
+- break;
+- }
+-
++ pdn = pci_dma_find(dn, &dma_window);
+ if (!pdn || !PCI_DN(pdn)) {
+ printk(KERN_WARNING "pci_dma_dev_setup_pSeriesLP: "
+ "no DMA window found for pci dev=%s dn=%pOF\n",
+@@ -1541,7 +1555,6 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
+ static bool iommu_bypass_supported_pSeriesLP(struct pci_dev *pdev, u64 dma_mask)
+ {
+ struct device_node *dn = pci_device_to_OF_node(pdev), *pdn;
+- const __be32 *dma_window = NULL;
+
+ /* only attempt to use a new window if 64-bit DMA is requested */
+ if (dma_mask < DMA_BIT_MASK(64))
+@@ -1555,13 +1568,7 @@ static bool iommu_bypass_supported_pSeriesLP(struct pci_dev *pdev, u64 dma_mask)
+ * search upwards in the tree until we either hit a dma-window
+ * property, OR find a parent with a table already allocated.
+ */
+- for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->table_group;
+- pdn = pdn->parent) {
+- dma_window = of_get_property(pdn, "ibm,dma-window", NULL);
+- if (dma_window)
+- break;
+- }
+-
++ pdn = pci_dma_find(dn, NULL);
+ if (pdn && PCI_DN(pdn))
+ return enable_ddw(pdev, pdn);
+
+--
+2.35.1
+
--- /dev/null
+From a416ef83570faaab028356d259ea532e268fbda9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 18:15:19 +0200
+Subject: pwm: lpc18xx: Fix period handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 8933d30c5f468d6cc1e4bf9bb535149da35f202e ]
+
+The calculation:
+
+ val = (u64)NSEC_PER_SEC * LPC18XX_PWM_TIMER_MAX;
+ do_div(val, lpc18xx_pwm->clk_rate);
+ lpc18xx_pwm->max_period_ns = val;
+
+is bogus because with NSEC_PER_SEC = 1000000000,
+LPC18XX_PWM_TIMER_MAX = 0xffffffff and clk_rate < NSEC_PER_SEC this
+overflows the (on lpc18xx (i.e. ARM32) 32 bit wide) unsigned int
+.max_period_ns. This results (dependant of the actual clk rate) in an
+arbitrary limitation of the maximal period. E.g. for clkrate =
+333333333 (Hz) we get max_period_ns = 9 instead of 12884901897.
+
+So make .max_period_ns an u64 and pass period and duty as u64 to not
+discard relevant digits. And also make use of mul_u64_u64_div_u64()
+which prevents all overflows assuming clk_rate < NSEC_PER_SEC.
+
+Fixes: 841e6f90bb78 ("pwm: NXP LPC18xx PWM/SCT driver")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-lpc18xx-sct.c | 55 +++++++++++++++++++++++++----------
+ 1 file changed, 39 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c
+index b909096dba2f..43b5509dde51 100644
+--- a/drivers/pwm/pwm-lpc18xx-sct.c
++++ b/drivers/pwm/pwm-lpc18xx-sct.c
+@@ -98,7 +98,7 @@ struct lpc18xx_pwm_chip {
+ unsigned long clk_rate;
+ unsigned int period_ns;
+ unsigned int min_period_ns;
+- unsigned int max_period_ns;
++ u64 max_period_ns;
+ unsigned int period_event;
+ unsigned long event_map;
+ struct mutex res_lock;
+@@ -145,40 +145,48 @@ static void lpc18xx_pwm_set_conflict_res(struct lpc18xx_pwm_chip *lpc18xx_pwm,
+ mutex_unlock(&lpc18xx_pwm->res_lock);
+ }
+
+-static void lpc18xx_pwm_config_period(struct pwm_chip *chip, int period_ns)
++static void lpc18xx_pwm_config_period(struct pwm_chip *chip, u64 period_ns)
+ {
+ struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+- u64 val;
++ u32 val;
+
+- val = (u64)period_ns * lpc18xx_pwm->clk_rate;
+- do_div(val, NSEC_PER_SEC);
++ /*
++ * With clk_rate < NSEC_PER_SEC this cannot overflow.
++ * With period_ns < max_period_ns this also fits into an u32.
++ * As period_ns >= min_period_ns = DIV_ROUND_UP(NSEC_PER_SEC, lpc18xx_pwm->clk_rate);
++ * we have val >= 1.
++ */
++ val = mul_u64_u64_div_u64(period_ns, lpc18xx_pwm->clk_rate, NSEC_PER_SEC);
+
+ lpc18xx_pwm_writel(lpc18xx_pwm,
+ LPC18XX_PWM_MATCH(lpc18xx_pwm->period_event),
+- (u32)val - 1);
++ val - 1);
+
+ lpc18xx_pwm_writel(lpc18xx_pwm,
+ LPC18XX_PWM_MATCHREL(lpc18xx_pwm->period_event),
+- (u32)val - 1);
++ val - 1);
+ }
+
+ static void lpc18xx_pwm_config_duty(struct pwm_chip *chip,
+- struct pwm_device *pwm, int duty_ns)
++ struct pwm_device *pwm, u64 duty_ns)
+ {
+ struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+ struct lpc18xx_pwm_data *lpc18xx_data = &lpc18xx_pwm->channeldata[pwm->hwpwm];
+- u64 val;
++ u32 val;
+
+- val = (u64)duty_ns * lpc18xx_pwm->clk_rate;
+- do_div(val, NSEC_PER_SEC);
++ /*
++ * With clk_rate < NSEC_PER_SEC this cannot overflow.
++ * With duty_ns <= period_ns < max_period_ns this also fits into an u32.
++ */
++ val = mul_u64_u64_div_u64(duty_ns, lpc18xx_pwm->clk_rate, NSEC_PER_SEC);
+
+ lpc18xx_pwm_writel(lpc18xx_pwm,
+ LPC18XX_PWM_MATCH(lpc18xx_data->duty_event),
+- (u32)val);
++ val);
+
+ lpc18xx_pwm_writel(lpc18xx_pwm,
+ LPC18XX_PWM_MATCHREL(lpc18xx_data->duty_event),
+- (u32)val);
++ val);
+ }
+
+ static int lpc18xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+@@ -360,12 +368,27 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
+ goto disable_pwmclk;
+ }
+
++ /*
++ * If clkrate is too fast, the calculations in .apply() might overflow.
++ */
++ if (lpc18xx_pwm->clk_rate > NSEC_PER_SEC) {
++ ret = dev_err_probe(&pdev->dev, -EINVAL, "pwm clock to fast\n");
++ goto disable_pwmclk;
++ }
++
++ /*
++ * If clkrate is too fast, the calculations in .apply() might overflow.
++ */
++ if (lpc18xx_pwm->clk_rate > NSEC_PER_SEC) {
++ ret = dev_err_probe(&pdev->dev, -EINVAL, "pwm clock to fast\n");
++ goto disable_pwmclk;
++ }
++
+ mutex_init(&lpc18xx_pwm->res_lock);
+ mutex_init(&lpc18xx_pwm->period_lock);
+
+- val = (u64)NSEC_PER_SEC * LPC18XX_PWM_TIMER_MAX;
+- do_div(val, lpc18xx_pwm->clk_rate);
+- lpc18xx_pwm->max_period_ns = val;
++ lpc18xx_pwm->max_period_ns =
++ mul_u64_u64_div_u64(NSEC_PER_SEC, LPC18XX_PWM_TIMER_MAX, lpc18xx_pwm->clk_rate);
+
+ lpc18xx_pwm->min_period_ns = DIV_ROUND_UP(NSEC_PER_SEC,
+ lpc18xx_pwm->clk_rate);
+--
+2.35.1
+
--- /dev/null
+From 9fd7b7f7ec4416cd8347517fb4ac406e61d78006 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 12:31:28 +0200
+Subject: pwm: sifive: Ensure the clk is enabled exactly once per running PWM
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit ace41d7564e655c39f709a78c035188a460c7cbd ]
+
+.apply() assumes the clk to be for a given PWM iff the PWM is enabled.
+So make sure this is the case when .probe() completes. And in .remove()
+disable the according number of times.
+
+This fixes a clk enable/disable imbalance, if some PWMs are already running
+at probe time.
+
+Fixes: 9e37a53eb051 (pwm: sifive: Add a driver for SiFive SoC PWM)
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Tested-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-sifive.c | 46 ++++++++++++++++++++++++++++++++--------
+ 1 file changed, 37 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c
+index a55f7345dc87..3936fda53366 100644
+--- a/drivers/pwm/pwm-sifive.c
++++ b/drivers/pwm/pwm-sifive.c
+@@ -229,6 +229,8 @@ static int pwm_sifive_probe(struct platform_device *pdev)
+ struct pwm_sifive_ddata *ddata;
+ struct pwm_chip *chip;
+ int ret;
++ u32 val;
++ unsigned int enabled_pwms = 0, enabled_clks = 1;
+
+ ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
+ if (!ddata)
+@@ -255,6 +257,33 @@ static int pwm_sifive_probe(struct platform_device *pdev)
+ return ret;
+ }
+
++ val = readl(ddata->regs + PWM_SIFIVE_PWMCFG);
++ if (val & PWM_SIFIVE_PWMCFG_EN_ALWAYS) {
++ unsigned int i;
++
++ for (i = 0; i < chip->npwm; ++i) {
++ val = readl(ddata->regs + PWM_SIFIVE_PWMCMP(i));
++ if (val > 0)
++ ++enabled_pwms;
++ }
++ }
++
++ /* The clk should be on once for each running PWM. */
++ if (enabled_pwms) {
++ while (enabled_clks < enabled_pwms) {
++ /* This is not expected to fail as the clk is already on */
++ ret = clk_enable(ddata->clk);
++ if (unlikely(ret)) {
++ dev_err_probe(dev, ret, "Failed to enable clk\n");
++ goto disable_clk;
++ }
++ ++enabled_clks;
++ }
++ } else {
++ clk_disable(ddata->clk);
++ enabled_clks = 0;
++ }
++
+ /* Watch for changes to underlying clock frequency */
+ ddata->notifier.notifier_call = pwm_sifive_clock_notifier;
+ ret = clk_notifier_register(ddata->clk, &ddata->notifier);
+@@ -277,7 +306,11 @@ static int pwm_sifive_probe(struct platform_device *pdev)
+ unregister_clk:
+ clk_notifier_unregister(ddata->clk, &ddata->notifier);
+ disable_clk:
+- clk_disable_unprepare(ddata->clk);
++ while (enabled_clks) {
++ clk_disable(ddata->clk);
++ --enabled_clks;
++ }
++ clk_unprepare(ddata->clk);
+
+ return ret;
+ }
+@@ -285,21 +318,16 @@ static int pwm_sifive_probe(struct platform_device *pdev)
+ static int pwm_sifive_remove(struct platform_device *dev)
+ {
+ struct pwm_sifive_ddata *ddata = platform_get_drvdata(dev);
+- bool is_enabled = false;
+ struct pwm_device *pwm;
+ int ch;
+
+ for (ch = 0; ch < ddata->chip.npwm; ch++) {
+ pwm = &ddata->chip.pwms[ch];
+- if (pwm->state.enabled) {
+- is_enabled = true;
+- break;
+- }
++ if (pwm->state.enabled)
++ clk_disable(ddata->clk);
+ }
+- if (is_enabled)
+- clk_disable(ddata->clk);
+
+- clk_disable_unprepare(ddata->clk);
++ clk_unprepare(ddata->clk);
+ pwmchip_remove(&ddata->chip);
+ clk_notifier_unregister(ddata->clk, &ddata->notifier);
+
+--
+2.35.1
+
--- /dev/null
+From 39e2a1e44669b6e6ed5ee29812ea38082b588f6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 12:31:29 +0200
+Subject: pwm: sifive: Shut down hardware only after pwmchip_remove() completed
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 2375e964d541bb09158cd2dff67b5d74e8de61cd ]
+
+The PWMs are expected to be functional until pwmchip_remove() is called.
+So disable the clks only afterwards.
+
+Fixes: 9e37a53eb051 ("pwm: sifive: Add a driver for SiFive SoC PWM")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Tested-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-sifive.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c
+index 3936fda53366..58347fcd4812 100644
+--- a/drivers/pwm/pwm-sifive.c
++++ b/drivers/pwm/pwm-sifive.c
+@@ -321,6 +321,9 @@ static int pwm_sifive_remove(struct platform_device *dev)
+ struct pwm_device *pwm;
+ int ch;
+
++ pwmchip_remove(&ddata->chip);
++ clk_notifier_unregister(ddata->clk, &ddata->notifier);
++
+ for (ch = 0; ch < ddata->chip.npwm; ch++) {
+ pwm = &ddata->chip.pwms[ch];
+ if (pwm->state.enabled)
+@@ -328,8 +331,6 @@ static int pwm_sifive_remove(struct platform_device *dev)
+ }
+
+ clk_unprepare(ddata->clk);
+- pwmchip_remove(&ddata->chip);
+- clk_notifier_unregister(ddata->clk, &ddata->notifier);
+
+ return 0;
+ }
+--
+2.35.1
+
--- /dev/null
+From 40474cfc03e698a86eb6102767e64a1e5695cd26 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 12:31:23 +0200
+Subject: pwm: sifive: Simplify offset calculation for PWMCMP registers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 20550a61880fc55e68a0d290ad195b74729c0e7b ]
+
+Instead of explicitly using PWM_SIFIVE_PWMCMP0 + pwm->hwpwm *
+PWM_SIFIVE_SIZE_PWMCMP for each access to one of the PWMCMP registers,
+introduce a macro that takes the hwpwm id as parameter.
+
+For the register definition using a plain 4 instead of the cpp constant
+PWM_SIFIVE_SIZE_PWMCMP is easier to read, so define the offset macro
+without the constant. The latter can then be dropped as there are no
+users left.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Tested-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-sifive.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c
+index 253c4a17d255..a55f7345dc87 100644
+--- a/drivers/pwm/pwm-sifive.c
++++ b/drivers/pwm/pwm-sifive.c
+@@ -23,7 +23,7 @@
+ #define PWM_SIFIVE_PWMCFG 0x0
+ #define PWM_SIFIVE_PWMCOUNT 0x8
+ #define PWM_SIFIVE_PWMS 0x10
+-#define PWM_SIFIVE_PWMCMP0 0x20
++#define PWM_SIFIVE_PWMCMP(i) (0x20 + 4 * (i))
+
+ /* PWMCFG fields */
+ #define PWM_SIFIVE_PWMCFG_SCALE GENMASK(3, 0)
+@@ -36,8 +36,6 @@
+ #define PWM_SIFIVE_PWMCFG_GANG BIT(24)
+ #define PWM_SIFIVE_PWMCFG_IP BIT(28)
+
+-/* PWM_SIFIVE_SIZE_PWMCMP is used to calculate offset for pwmcmpX registers */
+-#define PWM_SIFIVE_SIZE_PWMCMP 4
+ #define PWM_SIFIVE_CMPWIDTH 16
+ #define PWM_SIFIVE_DEFAULT_PERIOD 10000000
+
+@@ -112,8 +110,7 @@ static void pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_sifive_ddata *ddata = pwm_sifive_chip_to_ddata(chip);
+ u32 duty, val;
+
+- duty = readl(ddata->regs + PWM_SIFIVE_PWMCMP0 +
+- pwm->hwpwm * PWM_SIFIVE_SIZE_PWMCMP);
++ duty = readl(ddata->regs + PWM_SIFIVE_PWMCMP(pwm->hwpwm));
+
+ state->enabled = duty > 0;
+
+@@ -194,8 +191,7 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ pwm_sifive_update_clock(ddata, clk_get_rate(ddata->clk));
+ }
+
+- writel(frac, ddata->regs + PWM_SIFIVE_PWMCMP0 +
+- pwm->hwpwm * PWM_SIFIVE_SIZE_PWMCMP);
++ writel(frac, ddata->regs + PWM_SIFIVE_PWMCMP(pwm->hwpwm));
+
+ if (state->enabled != enabled)
+ pwm_sifive_enable(chip, state->enabled);
+--
+2.35.1
+
--- /dev/null
+From 0ccd4ad9e242088e4cef24b40aa024c65d1581d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 20:47:05 -0700
+Subject: raw: convert raw sockets to RCU
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0daf07e527095e64ee8927ce297ab626643e9f51 ]
+
+Using rwlock in networking code is extremely risky.
+writers can starve if enough readers are constantly
+grabing the rwlock.
+
+I thought rwlock were at fault and sent this patch:
+
+https://lkml.org/lkml/2022/6/17/272
+
+But Peter and Linus essentially told me rwlock had to be unfair.
+
+We need to get rid of rwlock in networking code.
+
+Without this fix, following script triggers soft lockups:
+
+for i in {1..48}
+do
+ ping -f -n -q 127.0.0.1 &
+ sleep 0.1
+done
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/raw.h | 11 +++++-
+ include/net/rawv6.h | 1 +
+ net/ipv4/af_inet.c | 2 ++
+ net/ipv4/raw.c | 83 +++++++++++++++++++++------------------------
+ net/ipv4/raw_diag.c | 22 +++++++-----
+ net/ipv6/af_inet6.c | 3 ++
+ net/ipv6/raw.c | 28 +++++++--------
+ 7 files changed, 80 insertions(+), 70 deletions(-)
+
+diff --git a/include/net/raw.h b/include/net/raw.h
+index 6324965779ec..537d9d1df890 100644
+--- a/include/net/raw.h
++++ b/include/net/raw.h
+@@ -33,9 +33,18 @@ int raw_rcv(struct sock *, struct sk_buff *);
+
+ struct raw_hashinfo {
+ rwlock_t lock;
+- struct hlist_head ht[RAW_HTABLE_SIZE];
++ struct hlist_nulls_head ht[RAW_HTABLE_SIZE];
+ };
+
++static inline void raw_hashinfo_init(struct raw_hashinfo *hashinfo)
++{
++ int i;
++
++ rwlock_init(&hashinfo->lock);
++ for (i = 0; i < RAW_HTABLE_SIZE; i++)
++ INIT_HLIST_NULLS_HEAD(&hashinfo->ht[i], i);
++}
++
+ #ifdef CONFIG_PROC_FS
+ int raw_proc_init(void);
+ void raw_proc_exit(void);
+diff --git a/include/net/rawv6.h b/include/net/rawv6.h
+index c48c1298699a..bc70909625f6 100644
+--- a/include/net/rawv6.h
++++ b/include/net/rawv6.h
+@@ -3,6 +3,7 @@
+ #define _NET_RAWV6_H
+
+ #include <net/protocol.h>
++#include <net/raw.h>
+
+ extern struct raw_hashinfo raw_v6_hashinfo;
+ bool raw_v6_match(struct net *net, struct sock *sk, unsigned short num,
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index 5c207367b3b4..9a70032625af 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -1920,6 +1920,8 @@ static int __init inet_init(void)
+
+ sock_skb_cb_check_size(sizeof(struct inet_skb_parm));
+
++ raw_hashinfo_init(&raw_v4_hashinfo);
++
+ rc = proto_register(&tcp_prot, 1);
+ if (rc)
+ goto out;
+diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
+index e9b8bb1e5fb0..2961421dfa68 100644
+--- a/net/ipv4/raw.c
++++ b/net/ipv4/raw.c
+@@ -85,20 +85,19 @@ struct raw_frag_vec {
+ int hlen;
+ };
+
+-struct raw_hashinfo raw_v4_hashinfo = {
+- .lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock),
+-};
++struct raw_hashinfo raw_v4_hashinfo;
+ EXPORT_SYMBOL_GPL(raw_v4_hashinfo);
+
+ int raw_hash_sk(struct sock *sk)
+ {
+ struct raw_hashinfo *h = sk->sk_prot->h.raw_hash;
+- struct hlist_head *head;
++ struct hlist_nulls_head *hlist;
+
+- head = &h->ht[inet_sk(sk)->inet_num & (RAW_HTABLE_SIZE - 1)];
++ hlist = &h->ht[inet_sk(sk)->inet_num & (RAW_HTABLE_SIZE - 1)];
+
+ write_lock_bh(&h->lock);
+- sk_add_node(sk, head);
++ hlist_nulls_add_head_rcu(&sk->sk_nulls_node, hlist);
++ sock_set_flag(sk, SOCK_RCU_FREE);
+ write_unlock_bh(&h->lock);
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
+
+@@ -111,7 +110,7 @@ void raw_unhash_sk(struct sock *sk)
+ struct raw_hashinfo *h = sk->sk_prot->h.raw_hash;
+
+ write_lock_bh(&h->lock);
+- if (sk_del_node_init(sk))
++ if (__sk_nulls_del_node_init_rcu(sk))
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
+ write_unlock_bh(&h->lock);
+ }
+@@ -164,17 +163,16 @@ static int icmp_filter(const struct sock *sk, const struct sk_buff *skb)
+ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
+ {
+ struct net *net = dev_net(skb->dev);
++ struct hlist_nulls_head *hlist;
++ struct hlist_nulls_node *hnode;
+ int sdif = inet_sdif(skb);
+ int dif = inet_iif(skb);
+- struct hlist_head *head;
+ int delivered = 0;
+ struct sock *sk;
+
+- head = &raw_v4_hashinfo.ht[hash];
+- if (hlist_empty(head))
+- return 0;
+- read_lock(&raw_v4_hashinfo.lock);
+- sk_for_each(sk, head) {
++ hlist = &raw_v4_hashinfo.ht[hash];
++ rcu_read_lock();
++ hlist_nulls_for_each_entry(sk, hnode, hlist, sk_nulls_node) {
+ if (!raw_v4_match(net, sk, iph->protocol,
+ iph->saddr, iph->daddr, dif, sdif))
+ continue;
+@@ -189,7 +187,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
+ raw_rcv(sk, clone);
+ }
+ }
+- read_unlock(&raw_v4_hashinfo.lock);
++ rcu_read_unlock();
+ return delivered;
+ }
+
+@@ -265,25 +263,26 @@ static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
+ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
+ {
+ struct net *net = dev_net(skb->dev);;
++ struct hlist_nulls_head *hlist;
++ struct hlist_nulls_node *hnode;
+ int dif = skb->dev->ifindex;
+ int sdif = inet_sdif(skb);
+- struct hlist_head *head;
+ const struct iphdr *iph;
+ struct sock *sk;
+ int hash;
+
+ hash = protocol & (RAW_HTABLE_SIZE - 1);
+- head = &raw_v4_hashinfo.ht[hash];
++ hlist = &raw_v4_hashinfo.ht[hash];
+
+- read_lock(&raw_v4_hashinfo.lock);
+- sk_for_each(sk, head) {
++ rcu_read_lock();
++ hlist_nulls_for_each_entry(sk, hnode, hlist, sk_nulls_node) {
+ iph = (const struct iphdr *)skb->data;
+ if (!raw_v4_match(net, sk, iph->protocol,
+ iph->saddr, iph->daddr, dif, sdif))
+ continue;
+ raw_err(sk, skb, info);
+ }
+- read_unlock(&raw_v4_hashinfo.lock);
++ rcu_read_unlock();
+ }
+
+ static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb)
+@@ -945,44 +944,41 @@ struct proto raw_prot = {
+ };
+
+ #ifdef CONFIG_PROC_FS
+-static struct sock *raw_get_first(struct seq_file *seq)
++static struct sock *raw_get_first(struct seq_file *seq, int bucket)
+ {
+- struct sock *sk;
+ struct raw_hashinfo *h = pde_data(file_inode(seq->file));
+ struct raw_iter_state *state = raw_seq_private(seq);
++ struct hlist_nulls_head *hlist;
++ struct hlist_nulls_node *hnode;
++ struct sock *sk;
+
+- for (state->bucket = 0; state->bucket < RAW_HTABLE_SIZE;
++ for (state->bucket = bucket; state->bucket < RAW_HTABLE_SIZE;
+ ++state->bucket) {
+- sk_for_each(sk, &h->ht[state->bucket])
++ hlist = &h->ht[state->bucket];
++ hlist_nulls_for_each_entry(sk, hnode, hlist, sk_nulls_node) {
+ if (sock_net(sk) == seq_file_net(seq))
+- goto found;
++ return sk;
++ }
+ }
+- sk = NULL;
+-found:
+- return sk;
++ return NULL;
+ }
+
+ static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk)
+ {
+- struct raw_hashinfo *h = pde_data(file_inode(seq->file));
+ struct raw_iter_state *state = raw_seq_private(seq);
+
+ do {
+- sk = sk_next(sk);
+-try_again:
+- ;
++ sk = sk_nulls_next(sk);
+ } while (sk && sock_net(sk) != seq_file_net(seq));
+
+- if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
+- sk = sk_head(&h->ht[state->bucket]);
+- goto try_again;
+- }
++ if (!sk)
++ return raw_get_first(seq, state->bucket + 1);
+ return sk;
+ }
+
+ static struct sock *raw_get_idx(struct seq_file *seq, loff_t pos)
+ {
+- struct sock *sk = raw_get_first(seq);
++ struct sock *sk = raw_get_first(seq, 0);
+
+ if (sk)
+ while (pos && (sk = raw_get_next(seq, sk)) != NULL)
+@@ -991,11 +987,9 @@ static struct sock *raw_get_idx(struct seq_file *seq, loff_t pos)
+ }
+
+ void *raw_seq_start(struct seq_file *seq, loff_t *pos)
+- __acquires(&h->lock)
++ __acquires(RCU)
+ {
+- struct raw_hashinfo *h = pde_data(file_inode(seq->file));
+-
+- read_lock(&h->lock);
++ rcu_read_lock();
+ return *pos ? raw_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+ EXPORT_SYMBOL_GPL(raw_seq_start);
+@@ -1005,7 +999,7 @@ void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ struct sock *sk;
+
+ if (v == SEQ_START_TOKEN)
+- sk = raw_get_first(seq);
++ sk = raw_get_first(seq, 0);
+ else
+ sk = raw_get_next(seq, v);
+ ++*pos;
+@@ -1014,11 +1008,9 @@ void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ EXPORT_SYMBOL_GPL(raw_seq_next);
+
+ void raw_seq_stop(struct seq_file *seq, void *v)
+- __releases(&h->lock)
++ __releases(RCU)
+ {
+- struct raw_hashinfo *h = pde_data(file_inode(seq->file));
+-
+- read_unlock(&h->lock);
++ rcu_read_unlock();
+ }
+ EXPORT_SYMBOL_GPL(raw_seq_stop);
+
+@@ -1080,6 +1072,7 @@ static __net_initdata struct pernet_operations raw_net_ops = {
+
+ int __init raw_proc_init(void)
+ {
++
+ return register_pernet_subsys(&raw_net_ops);
+ }
+
+diff --git a/net/ipv4/raw_diag.c b/net/ipv4/raw_diag.c
+index b6d92dc7b051..5f208e840d85 100644
+--- a/net/ipv4/raw_diag.c
++++ b/net/ipv4/raw_diag.c
+@@ -57,31 +57,32 @@ static bool raw_lookup(struct net *net, struct sock *sk,
+ static struct sock *raw_sock_get(struct net *net, const struct inet_diag_req_v2 *r)
+ {
+ struct raw_hashinfo *hashinfo = raw_get_hashinfo(r);
++ struct hlist_nulls_head *hlist;
++ struct hlist_nulls_node *hnode;
+ struct sock *sk;
+ int slot;
+
+ if (IS_ERR(hashinfo))
+ return ERR_CAST(hashinfo);
+
+- read_lock(&hashinfo->lock);
++ rcu_read_lock();
+ for (slot = 0; slot < RAW_HTABLE_SIZE; slot++) {
+- sk_for_each(sk, &hashinfo->ht[slot]) {
++ hlist = &hashinfo->ht[slot];
++ hlist_nulls_for_each_entry(sk, hnode, hlist, sk_nulls_node) {
+ if (raw_lookup(net, sk, r)) {
+ /*
+ * Grab it and keep until we fill
+- * diag meaage to be reported, so
++ * diag message to be reported, so
+ * caller should call sock_put then.
+- * We can do that because we're keeping
+- * hashinfo->lock here.
+ */
+- sock_hold(sk);
+- goto out_unlock;
++ if (refcount_inc_not_zero(&sk->sk_refcnt))
++ goto out_unlock;
+ }
+ }
+ }
+ sk = ERR_PTR(-ENOENT);
+ out_unlock:
+- read_unlock(&hashinfo->lock);
++ rcu_read_unlock();
+
+ return sk;
+ }
+@@ -141,6 +142,8 @@ static void raw_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
+ struct raw_hashinfo *hashinfo = raw_get_hashinfo(r);
+ struct net *net = sock_net(skb->sk);
+ struct inet_diag_dump_data *cb_data;
++ struct hlist_nulls_head *hlist;
++ struct hlist_nulls_node *hnode;
+ int num, s_num, slot, s_slot;
+ struct sock *sk = NULL;
+ struct nlattr *bc;
+@@ -157,7 +160,8 @@ static void raw_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
+ for (slot = s_slot; slot < RAW_HTABLE_SIZE; s_num = 0, slot++) {
+ num = 0;
+
+- sk_for_each(sk, &hashinfo->ht[slot]) {
++ hlist = &hashinfo->ht[slot];
++ hlist_nulls_for_each_entry(sk, hnode, hlist, sk_nulls_node) {
+ struct inet_sock *inet = inet_sk(sk);
+
+ if (!net_eq(sock_net(sk), net))
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index ef1e6545d869..095298c5727a 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -63,6 +63,7 @@
+ #include <net/compat.h>
+ #include <net/xfrm.h>
+ #include <net/ioam6.h>
++#include <net/rawv6.h>
+
+ #include <linux/uaccess.h>
+ #include <linux/mroute6.h>
+@@ -1074,6 +1075,8 @@ static int __init inet6_init(void)
+ goto out;
+ }
+
++ raw_hashinfo_init(&raw_v6_hashinfo);
++
+ err = proto_register(&tcpv6_prot, 1);
+ if (err)
+ goto out;
+diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
+index 33a779723262..9f0aafc778ce 100644
+--- a/net/ipv6/raw.c
++++ b/net/ipv6/raw.c
+@@ -61,9 +61,7 @@
+
+ #define ICMPV6_HDRLEN 4 /* ICMPv6 header, RFC 4443 Section 2.1 */
+
+-struct raw_hashinfo raw_v6_hashinfo = {
+- .lock = __RW_LOCK_UNLOCKED(raw_v6_hashinfo.lock),
+-};
++struct raw_hashinfo raw_v6_hashinfo;
+ EXPORT_SYMBOL_GPL(raw_v6_hashinfo);
+
+ bool raw_v6_match(struct net *net, struct sock *sk, unsigned short num,
+@@ -143,9 +141,10 @@ EXPORT_SYMBOL(rawv6_mh_filter_unregister);
+ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
+ {
+ struct net *net = dev_net(skb->dev);
++ struct hlist_nulls_head *hlist;
++ struct hlist_nulls_node *hnode;
+ const struct in6_addr *saddr;
+ const struct in6_addr *daddr;
+- struct hlist_head *head;
+ struct sock *sk;
+ bool delivered = false;
+ __u8 hash;
+@@ -154,11 +153,9 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
+ daddr = saddr + 1;
+
+ hash = nexthdr & (RAW_HTABLE_SIZE - 1);
+- head = &raw_v6_hashinfo.ht[hash];
+- if (hlist_empty(head))
+- return false;
+- read_lock(&raw_v6_hashinfo.lock);
+- sk_for_each(sk, head) {
++ hlist = &raw_v6_hashinfo.ht[hash];
++ rcu_read_lock();
++ hlist_nulls_for_each_entry(sk, hnode, hlist, sk_nulls_node) {
+ int filtered;
+
+ if (!raw_v6_match(net, sk, nexthdr, daddr, saddr,
+@@ -203,7 +200,7 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
+ }
+ }
+ }
+- read_unlock(&raw_v6_hashinfo.lock);
++ rcu_read_unlock();
+ return delivered;
+ }
+
+@@ -337,14 +334,15 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
+ {
+ const struct in6_addr *saddr, *daddr;
+ struct net *net = dev_net(skb->dev);
+- struct hlist_head *head;
++ struct hlist_nulls_head *hlist;
++ struct hlist_nulls_node *hnode;
+ struct sock *sk;
+ int hash;
+
+ hash = nexthdr & (RAW_HTABLE_SIZE - 1);
+- head = &raw_v6_hashinfo.ht[hash];
+- read_lock(&raw_v6_hashinfo.lock);
+- sk_for_each(sk, head) {
++ hlist = &raw_v6_hashinfo.ht[hash];
++ rcu_read_lock();
++ hlist_nulls_for_each_entry(sk, hnode, hlist, sk_nulls_node) {
+ /* Note: ipv6_hdr(skb) != skb->data */
+ const struct ipv6hdr *ip6h = (const struct ipv6hdr *)skb->data;
+ saddr = &ip6h->saddr;
+@@ -355,7 +353,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
+ continue;
+ rawv6_err(sk, skb, NULL, type, code, inner_offset, info);
+ }
+- read_unlock(&raw_v6_hashinfo.lock);
++ rcu_read_unlock();
+ }
+
+ static inline int rawv6_rcv_skb(struct sock *sk, struct sk_buff *skb)
+--
+2.35.1
+
--- /dev/null
+From 40345709063bae5788fab4f59f4523d637be452f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jun 2022 16:29:26 -0700
+Subject: raw: Fix mixed declarations error in raw_icmp_error().
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 5da39e31b1b0eb62b8ed369ad9615da850239e9e ]
+
+The trailing semicolon causes a compiler error, so let's remove it.
+
+net/ipv4/raw.c: In function ‘raw_icmp_error’:
+net/ipv4/raw.c:266:2: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]
+ 266 | struct hlist_nulls_head *hlist;
+ | ^~~~~~
+
+Fixes: ba44f8182ec2 ("raw: use more conventional iterators")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/raw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
+index 2961421dfa68..0d534f4720c4 100644
+--- a/net/ipv4/raw.c
++++ b/net/ipv4/raw.c
+@@ -262,7 +262,7 @@ static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
+
+ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
+ {
+- struct net *net = dev_net(skb->dev);;
++ struct net *net = dev_net(skb->dev);
+ struct hlist_nulls_head *hlist;
+ struct hlist_nulls_node *hnode;
+ int dif = skb->dev->ifindex;
+--
+2.35.1
+
--- /dev/null
+From 7acfed5afd1cbec6aec4bb1eaa5863d3b59fdc85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 20:47:04 -0700
+Subject: raw: use more conventional iterators
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit ba44f8182ec299c5d1c8a72fc0fde4ec127b5a6d ]
+
+In order to prepare the following patch,
+I change raw v4 & v6 code to use more conventional
+iterators.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/raw.h | 5 +--
+ include/net/rawv6.h | 6 +--
+ net/ipv4/raw.c | 93 ++++++++++++++-------------------------
+ net/ipv4/raw_diag.c | 33 +++++++-------
+ net/ipv6/raw.c | 105 ++++++++++++++++----------------------------
+ 5 files changed, 92 insertions(+), 150 deletions(-)
+
+diff --git a/include/net/raw.h b/include/net/raw.h
+index c51a635671a7..6324965779ec 100644
+--- a/include/net/raw.h
++++ b/include/net/raw.h
+@@ -20,9 +20,8 @@
+ extern struct proto raw_prot;
+
+ extern struct raw_hashinfo raw_v4_hashinfo;
+-struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
+- unsigned short num, __be32 raddr,
+- __be32 laddr, int dif, int sdif);
++bool raw_v4_match(struct net *net, struct sock *sk, unsigned short num,
++ __be32 raddr, __be32 laddr, int dif, int sdif);
+
+ int raw_abort(struct sock *sk, int err);
+ void raw_icmp_error(struct sk_buff *, int, u32);
+diff --git a/include/net/rawv6.h b/include/net/rawv6.h
+index 53d86b6055e8..c48c1298699a 100644
+--- a/include/net/rawv6.h
++++ b/include/net/rawv6.h
+@@ -5,9 +5,9 @@
+ #include <net/protocol.h>
+
+ extern struct raw_hashinfo raw_v6_hashinfo;
+-struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
+- unsigned short num, const struct in6_addr *loc_addr,
+- const struct in6_addr *rmt_addr, int dif, int sdif);
++bool raw_v6_match(struct net *net, struct sock *sk, unsigned short num,
++ const struct in6_addr *loc_addr,
++ const struct in6_addr *rmt_addr, int dif, int sdif);
+
+ int raw_abort(struct sock *sk, int err);
+
+diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
+index c9dd9603f2e7..e9b8bb1e5fb0 100644
+--- a/net/ipv4/raw.c
++++ b/net/ipv4/raw.c
+@@ -117,24 +117,19 @@ void raw_unhash_sk(struct sock *sk)
+ }
+ EXPORT_SYMBOL_GPL(raw_unhash_sk);
+
+-struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
+- unsigned short num, __be32 raddr, __be32 laddr,
+- int dif, int sdif)
++bool raw_v4_match(struct net *net, struct sock *sk, unsigned short num,
++ __be32 raddr, __be32 laddr, int dif, int sdif)
+ {
+- sk_for_each_from(sk) {
+- struct inet_sock *inet = inet_sk(sk);
+-
+- if (net_eq(sock_net(sk), net) && inet->inet_num == num &&
+- !(inet->inet_daddr && inet->inet_daddr != raddr) &&
+- !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
+- raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif))
+- goto found; /* gotcha */
+- }
+- sk = NULL;
+-found:
+- return sk;
++ struct inet_sock *inet = inet_sk(sk);
++
++ if (net_eq(sock_net(sk), net) && inet->inet_num == num &&
++ !(inet->inet_daddr && inet->inet_daddr != raddr) &&
++ !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
++ raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif))
++ return true;
++ return false;
+ }
+-EXPORT_SYMBOL_GPL(__raw_v4_lookup);
++EXPORT_SYMBOL_GPL(raw_v4_match);
+
+ /*
+ * 0 - deliver
+@@ -168,23 +163,21 @@ static int icmp_filter(const struct sock *sk, const struct sk_buff *skb)
+ */
+ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
+ {
++ struct net *net = dev_net(skb->dev);
+ int sdif = inet_sdif(skb);
+ int dif = inet_iif(skb);
+- struct sock *sk;
+ struct hlist_head *head;
+ int delivered = 0;
+- struct net *net;
++ struct sock *sk;
+
+- read_lock(&raw_v4_hashinfo.lock);
+ head = &raw_v4_hashinfo.ht[hash];
+ if (hlist_empty(head))
+- goto out;
+-
+- net = dev_net(skb->dev);
+- sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
+- iph->saddr, iph->daddr, dif, sdif);
+-
+- while (sk) {
++ return 0;
++ read_lock(&raw_v4_hashinfo.lock);
++ sk_for_each(sk, head) {
++ if (!raw_v4_match(net, sk, iph->protocol,
++ iph->saddr, iph->daddr, dif, sdif))
++ continue;
+ delivered = 1;
+ if ((iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) &&
+ ip_mc_sf_allow(sk, iph->daddr, iph->saddr,
+@@ -195,31 +188,16 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
+ if (clone)
+ raw_rcv(sk, clone);
+ }
+- sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
+- iph->saddr, iph->daddr,
+- dif, sdif);
+ }
+-out:
+ read_unlock(&raw_v4_hashinfo.lock);
+ return delivered;
+ }
+
+ int raw_local_deliver(struct sk_buff *skb, int protocol)
+ {
+- int hash;
+- struct sock *raw_sk;
+-
+- hash = protocol & (RAW_HTABLE_SIZE - 1);
+- raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);
+-
+- /* If there maybe a raw socket we must check - if not we
+- * don't care less
+- */
+- if (raw_sk && !raw_v4_input(skb, ip_hdr(skb), hash))
+- raw_sk = NULL;
+-
+- return raw_sk != NULL;
++ int hash = protocol & (RAW_HTABLE_SIZE - 1);
+
++ return raw_v4_input(skb, ip_hdr(skb), hash);
+ }
+
+ static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
+@@ -286,29 +264,24 @@ static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
+
+ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
+ {
+- int hash;
+- struct sock *raw_sk;
++ struct net *net = dev_net(skb->dev);;
++ int dif = skb->dev->ifindex;
++ int sdif = inet_sdif(skb);
++ struct hlist_head *head;
+ const struct iphdr *iph;
+- struct net *net;
++ struct sock *sk;
++ int hash;
+
+ hash = protocol & (RAW_HTABLE_SIZE - 1);
++ head = &raw_v4_hashinfo.ht[hash];
+
+ read_lock(&raw_v4_hashinfo.lock);
+- raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);
+- if (raw_sk) {
+- int dif = skb->dev->ifindex;
+- int sdif = inet_sdif(skb);
+-
++ sk_for_each(sk, head) {
+ iph = (const struct iphdr *)skb->data;
+- net = dev_net(skb->dev);
+-
+- while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol,
+- iph->daddr, iph->saddr,
+- dif, sdif)) != NULL) {
+- raw_err(raw_sk, skb, info);
+- raw_sk = sk_next(raw_sk);
+- iph = (const struct iphdr *)skb->data;
+- }
++ if (!raw_v4_match(net, sk, iph->protocol,
++ iph->saddr, iph->daddr, dif, sdif))
++ continue;
++ raw_err(sk, skb, info);
+ }
+ read_unlock(&raw_v4_hashinfo.lock);
+ }
+diff --git a/net/ipv4/raw_diag.c b/net/ipv4/raw_diag.c
+index ccacbde30a2c..b6d92dc7b051 100644
+--- a/net/ipv4/raw_diag.c
++++ b/net/ipv4/raw_diag.c
+@@ -34,31 +34,30 @@ raw_get_hashinfo(const struct inet_diag_req_v2 *r)
+ * use helper to figure it out.
+ */
+
+-static struct sock *raw_lookup(struct net *net, struct sock *from,
+- const struct inet_diag_req_v2 *req)
++static bool raw_lookup(struct net *net, struct sock *sk,
++ const struct inet_diag_req_v2 *req)
+ {
+ struct inet_diag_req_raw *r = (void *)req;
+- struct sock *sk = NULL;
+
+ if (r->sdiag_family == AF_INET)
+- sk = __raw_v4_lookup(net, from, r->sdiag_raw_protocol,
+- r->id.idiag_dst[0],
+- r->id.idiag_src[0],
+- r->id.idiag_if, 0);
++ return raw_v4_match(net, sk, r->sdiag_raw_protocol,
++ r->id.idiag_dst[0],
++ r->id.idiag_src[0],
++ r->id.idiag_if, 0);
+ #if IS_ENABLED(CONFIG_IPV6)
+ else
+- sk = __raw_v6_lookup(net, from, r->sdiag_raw_protocol,
+- (const struct in6_addr *)r->id.idiag_src,
+- (const struct in6_addr *)r->id.idiag_dst,
+- r->id.idiag_if, 0);
++ return raw_v6_match(net, sk, r->sdiag_raw_protocol,
++ (const struct in6_addr *)r->id.idiag_src,
++ (const struct in6_addr *)r->id.idiag_dst,
++ r->id.idiag_if, 0);
+ #endif
+- return sk;
++ return false;
+ }
+
+ static struct sock *raw_sock_get(struct net *net, const struct inet_diag_req_v2 *r)
+ {
+ struct raw_hashinfo *hashinfo = raw_get_hashinfo(r);
+- struct sock *sk = NULL, *s;
++ struct sock *sk;
+ int slot;
+
+ if (IS_ERR(hashinfo))
+@@ -66,9 +65,8 @@ static struct sock *raw_sock_get(struct net *net, const struct inet_diag_req_v2
+
+ read_lock(&hashinfo->lock);
+ for (slot = 0; slot < RAW_HTABLE_SIZE; slot++) {
+- sk_for_each(s, &hashinfo->ht[slot]) {
+- sk = raw_lookup(net, s, r);
+- if (sk) {
++ sk_for_each(sk, &hashinfo->ht[slot]) {
++ if (raw_lookup(net, sk, r)) {
+ /*
+ * Grab it and keep until we fill
+ * diag meaage to be reported, so
+@@ -81,10 +79,11 @@ static struct sock *raw_sock_get(struct net *net, const struct inet_diag_req_v2
+ }
+ }
+ }
++ sk = ERR_PTR(-ENOENT);
+ out_unlock:
+ read_unlock(&hashinfo->lock);
+
+- return sk ? sk : ERR_PTR(-ENOENT);
++ return sk;
+ }
+
+ static int raw_diag_dump_one(struct netlink_callback *cb,
+diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
+index 8bb41f3b246a..33a779723262 100644
+--- a/net/ipv6/raw.c
++++ b/net/ipv6/raw.c
+@@ -66,41 +66,27 @@ struct raw_hashinfo raw_v6_hashinfo = {
+ };
+ EXPORT_SYMBOL_GPL(raw_v6_hashinfo);
+
+-struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
+- unsigned short num, const struct in6_addr *loc_addr,
+- const struct in6_addr *rmt_addr, int dif, int sdif)
++bool raw_v6_match(struct net *net, struct sock *sk, unsigned short num,
++ const struct in6_addr *loc_addr,
++ const struct in6_addr *rmt_addr, int dif, int sdif)
+ {
+- bool is_multicast = ipv6_addr_is_multicast(loc_addr);
+-
+- sk_for_each_from(sk)
+- if (inet_sk(sk)->inet_num == num) {
+-
+- if (!net_eq(sock_net(sk), net))
+- continue;
+-
+- if (!ipv6_addr_any(&sk->sk_v6_daddr) &&
+- !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr))
+- continue;
+-
+- if (!raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
+- dif, sdif))
+- continue;
+-
+- if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
+- if (ipv6_addr_equal(&sk->sk_v6_rcv_saddr, loc_addr))
+- goto found;
+- if (is_multicast &&
+- inet6_mc_check(sk, loc_addr, rmt_addr))
+- goto found;
+- continue;
+- }
+- goto found;
+- }
+- sk = NULL;
+-found:
+- return sk;
++ if (inet_sk(sk)->inet_num != num ||
++ !net_eq(sock_net(sk), net) ||
++ (!ipv6_addr_any(&sk->sk_v6_daddr) &&
++ !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr)) ||
++ !raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
++ dif, sdif))
++ return false;
++
++ if (ipv6_addr_any(&sk->sk_v6_rcv_saddr) ||
++ ipv6_addr_equal(&sk->sk_v6_rcv_saddr, loc_addr) ||
++ (ipv6_addr_is_multicast(loc_addr) &&
++ inet6_mc_check(sk, loc_addr, rmt_addr)))
++ return true;
++
++ return false;
+ }
+-EXPORT_SYMBOL_GPL(__raw_v6_lookup);
++EXPORT_SYMBOL_GPL(raw_v6_match);
+
+ /*
+ * 0 - deliver
+@@ -156,31 +142,28 @@ EXPORT_SYMBOL(rawv6_mh_filter_unregister);
+ */
+ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
+ {
++ struct net *net = dev_net(skb->dev);
+ const struct in6_addr *saddr;
+ const struct in6_addr *daddr;
++ struct hlist_head *head;
+ struct sock *sk;
+ bool delivered = false;
+ __u8 hash;
+- struct net *net;
+
+ saddr = &ipv6_hdr(skb)->saddr;
+ daddr = saddr + 1;
+
+ hash = nexthdr & (RAW_HTABLE_SIZE - 1);
+-
++ head = &raw_v6_hashinfo.ht[hash];
++ if (hlist_empty(head))
++ return false;
+ read_lock(&raw_v6_hashinfo.lock);
+- sk = sk_head(&raw_v6_hashinfo.ht[hash]);
+-
+- if (!sk)
+- goto out;
+-
+- net = dev_net(skb->dev);
+- sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr,
+- inet6_iif(skb), inet6_sdif(skb));
+-
+- while (sk) {
++ sk_for_each(sk, head) {
+ int filtered;
+
++ if (!raw_v6_match(net, sk, nexthdr, daddr, saddr,
++ inet6_iif(skb), inet6_sdif(skb)))
++ continue;
+ delivered = true;
+ switch (nexthdr) {
+ case IPPROTO_ICMPV6:
+@@ -219,23 +202,14 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
+ rawv6_rcv(sk, clone);
+ }
+ }
+- sk = __raw_v6_lookup(net, sk_next(sk), nexthdr, daddr, saddr,
+- inet6_iif(skb), inet6_sdif(skb));
+ }
+-out:
+ read_unlock(&raw_v6_hashinfo.lock);
+ return delivered;
+ }
+
+ bool raw6_local_deliver(struct sk_buff *skb, int nexthdr)
+ {
+- struct sock *raw_sk;
+-
+- raw_sk = sk_head(&raw_v6_hashinfo.ht[nexthdr & (RAW_HTABLE_SIZE - 1)]);
+- if (raw_sk && !ipv6_raw_deliver(skb, nexthdr))
+- raw_sk = NULL;
+-
+- return raw_sk != NULL;
++ return ipv6_raw_deliver(skb, nexthdr);
+ }
+
+ /* This cleans up af_inet6 a bit. -DaveM */
+@@ -361,28 +335,25 @@ static void rawv6_err(struct sock *sk, struct sk_buff *skb,
+ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
+ u8 type, u8 code, int inner_offset, __be32 info)
+ {
++ const struct in6_addr *saddr, *daddr;
++ struct net *net = dev_net(skb->dev);
++ struct hlist_head *head;
+ struct sock *sk;
+ int hash;
+- const struct in6_addr *saddr, *daddr;
+- struct net *net;
+
+ hash = nexthdr & (RAW_HTABLE_SIZE - 1);
+-
++ head = &raw_v6_hashinfo.ht[hash];
+ read_lock(&raw_v6_hashinfo.lock);
+- sk = sk_head(&raw_v6_hashinfo.ht[hash]);
+- if (sk) {
++ sk_for_each(sk, head) {
+ /* Note: ipv6_hdr(skb) != skb->data */
+ const struct ipv6hdr *ip6h = (const struct ipv6hdr *)skb->data;
+ saddr = &ip6h->saddr;
+ daddr = &ip6h->daddr;
+- net = dev_net(skb->dev);
+
+- while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr,
+- inet6_iif(skb), inet6_iif(skb)))) {
+- rawv6_err(sk, skb, NULL, type, code,
+- inner_offset, info);
+- sk = sk_next(sk);
+- }
++ if (!raw_v6_match(net, sk, nexthdr, &ip6h->saddr, &ip6h->daddr,
++ inet6_iif(skb), inet6_iif(skb)))
++ continue;
++ rawv6_err(sk, skb, NULL, type, code, inner_offset, info);
+ }
+ read_unlock(&raw_v6_hashinfo.lock);
+ }
+--
+2.35.1
+
--- /dev/null
+From 86505d929bf23e5faba1a89df72fda0f2798beb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 15:03:57 +0200
+Subject: rcutorture: Fix ksoftirqd boosting timing and iteration
+
+From: Frederic Weisbecker <frederic@kernel.org>
+
+[ Upstream commit 3002153a91a9732a6d1d0bb95138593c7da15743 ]
+
+The RCU priority boosting can fail in two situations:
+
+1) If (nr_cpus= > maxcpus=), which means if the total number of CPUs
+is higher than those brought online at boot, then torture_onoff() may
+later bring up CPUs that weren't online on boot. Now since rcutorture
+initialization only boosts the ksoftirqds of the CPUs that have been
+set online on boot, the CPUs later set online by torture_onoff won't
+benefit from the boost, making RCU priority boosting fail.
+
+2) The ksoftirqd kthreads are boosted after the creation of
+rcu_torture_boost() kthreads, which opens a window large enough for these
+rcu_torture_boost() kthreads to wait (despite running at FIFO priority)
+for ksoftirqds that are still running at SCHED_NORMAL priority.
+
+The issues can trigger for example with:
+
+ ./kvm.sh --configs TREE01 --kconfig "CONFIG_RCU_BOOST=y"
+
+ [ 34.968561] rcu-torture: !!!
+ [ 34.968627] ------------[ cut here ]------------
+ [ 35.014054] WARNING: CPU: 4 PID: 114 at kernel/rcu/rcutorture.c:1979 rcu_torture_stats_print+0x5ad/0x610
+ [ 35.052043] Modules linked in:
+ [ 35.069138] CPU: 4 PID: 114 Comm: rcu_torture_sta Not tainted 5.18.0-rc1 #1
+ [ 35.096424] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.14.0-0-g155821a-rebuilt.opensuse.org 04/01/2014
+ [ 35.154570] RIP: 0010:rcu_torture_stats_print+0x5ad/0x610
+ [ 35.198527] Code: 63 1b 02 00 74 02 0f 0b 48 83 3d 35 63 1b 02 00 74 02 0f 0b 48 83 3d 21 63 1b 02 00 74 02 0f 0b 48 83 3d 0d 63 1b 02 00 74 02 <0f> 0b 83 eb 01 0f 8e ba fc ff ff 0f 0b e9 b3 fc ff f82
+ [ 37.251049] RSP: 0000:ffffa92a0050bdf8 EFLAGS: 00010202
+ [ 37.277320] rcu: De-offloading 8
+ [ 37.290367] RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000001
+ [ 37.290387] RDX: 0000000000000000 RSI: 00000000ffffbfff RDI: 00000000ffffffff
+ [ 37.290398] RBP: 000000000000007b R08: 0000000000000000 R09: c0000000ffffbfff
+ [ 37.290407] R10: 000000000000002a R11: ffffa92a0050bc18 R12: ffffa92a0050be20
+ [ 37.290417] R13: ffffa92a0050be78 R14: 0000000000000000 R15: 000000000001bea0
+ [ 37.290427] FS: 0000000000000000(0000) GS:ffff96045eb00000(0000) knlGS:0000000000000000
+ [ 37.290448] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ [ 37.290460] CR2: 0000000000000000 CR3: 000000001dc0c000 CR4: 00000000000006e0
+ [ 37.290470] Call Trace:
+ [ 37.295049] <TASK>
+ [ 37.295065] ? preempt_count_add+0x63/0x90
+ [ 37.295095] ? _raw_spin_lock_irqsave+0x12/0x40
+ [ 37.295125] ? rcu_torture_stats_print+0x610/0x610
+ [ 37.295143] rcu_torture_stats+0x29/0x70
+ [ 37.295160] kthread+0xe3/0x110
+ [ 37.295176] ? kthread_complete_and_exit+0x20/0x20
+ [ 37.295193] ret_from_fork+0x22/0x30
+ [ 37.295218] </TASK>
+
+Fix this with boosting the ksoftirqds kthreads from the boosting
+hotplug callback itself and before the boosting kthreads are created.
+
+Fixes: ea6d962e80b6 ("rcutorture: Judge RCU priority boosting on grace periods, not callbacks")
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/rcutorture.c | 28 +++++++++++++---------------
+ 1 file changed, 13 insertions(+), 15 deletions(-)
+
+diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
+index 55d049c39608..7c3a7f8c828b 100644
+--- a/kernel/rcu/rcutorture.c
++++ b/kernel/rcu/rcutorture.c
+@@ -2030,6 +2030,19 @@ static int rcutorture_booster_init(unsigned int cpu)
+ if (boost_tasks[cpu] != NULL)
+ return 0; /* Already created, nothing more to do. */
+
++ // Testing RCU priority boosting requires rcutorture do
++ // some serious abuse. Counter this by running ksoftirqd
++ // at higher priority.
++ if (IS_BUILTIN(CONFIG_RCU_TORTURE_TEST)) {
++ struct sched_param sp;
++ struct task_struct *t;
++
++ t = per_cpu(ksoftirqd, cpu);
++ WARN_ON_ONCE(!t);
++ sp.sched_priority = 2;
++ sched_setscheduler_nocheck(t, SCHED_FIFO, &sp);
++ }
++
+ /* Don't allow time recalculation while creating a new task. */
+ mutex_lock(&boost_mutex);
+ rcu_torture_disable_rt_throttle();
+@@ -3281,21 +3294,6 @@ rcu_torture_init(void)
+ rcutor_hp = firsterr;
+ if (torture_init_error(firsterr))
+ goto unwind;
+-
+- // Testing RCU priority boosting requires rcutorture do
+- // some serious abuse. Counter this by running ksoftirqd
+- // at higher priority.
+- if (IS_BUILTIN(CONFIG_RCU_TORTURE_TEST)) {
+- for_each_online_cpu(cpu) {
+- struct sched_param sp;
+- struct task_struct *t;
+-
+- t = per_cpu(ksoftirqd, cpu);
+- WARN_ON_ONCE(!t);
+- sp.sched_priority = 2;
+- sched_setscheduler_nocheck(t, SCHED_FIFO, &sp);
+- }
+- }
+ }
+ shutdown_jiffies = jiffies + shutdown_secs * HZ;
+ firsterr = torture_shutdown_init(shutdown_secs, rcu_torture_cleanup);
+--
+2.35.1
+
--- /dev/null
+From dcaa64053511bb527db7c753d0f42da174537c9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Mar 2022 10:06:53 -0700
+Subject: rcutorture: Make kvm.sh allow more memory for --kasan runs
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit 31015625768e6d8bc808a892b221b69afaaa8d07 ]
+
+KASAN allots significant memory to track allocation state, and the amount
+of memory has increased recently, which results in frequent OOMs on a
+few of the rcutorture scenarios. This commit therefore provides 2G of
+memory for --kasan runs, up from the 512M default.
+
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/rcutorture/bin/kvm.sh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/tools/testing/selftests/rcutorture/bin/kvm.sh b/tools/testing/selftests/rcutorture/bin/kvm.sh
+index 55b2c1533282..b9f4d41da30e 100755
+--- a/tools/testing/selftests/rcutorture/bin/kvm.sh
++++ b/tools/testing/selftests/rcutorture/bin/kvm.sh
+@@ -44,6 +44,7 @@ TORTURE_KCONFIG_KASAN_ARG=""
+ TORTURE_KCONFIG_KCSAN_ARG=""
+ TORTURE_KMAKE_ARG=""
+ TORTURE_QEMU_MEM=512
++torture_qemu_mem_default=1
+ TORTURE_REMOTE=
+ TORTURE_SHUTDOWN_GRACE=180
+ TORTURE_SUITE=rcu
+@@ -180,6 +181,10 @@ do
+ ;;
+ --kasan)
+ TORTURE_KCONFIG_KASAN_ARG="CONFIG_DEBUG_INFO=y CONFIG_KASAN=y"; export TORTURE_KCONFIG_KASAN_ARG
++ if test -n "$torture_qemu_mem_default"
++ then
++ TORTURE_QEMU_MEM=2G
++ fi
+ ;;
+ --kconfig|--kconfigs)
+ checkarg --kconfig "(Kconfig options)" $# "$2" '^CONFIG_[A-Z0-9_]\+=\([ynm]\|[0-9]\+\)\( CONFIG_[A-Z0-9_]\+=\([ynm]\|[0-9]\+\)\)*$' '^error$'
+@@ -202,6 +207,7 @@ do
+ --memory)
+ checkarg --memory "(memory size)" $# "$2" '^[0-9]\+[MG]\?$' error
+ TORTURE_QEMU_MEM=$2
++ torture_qemu_mem_default=
+ shift
+ ;;
+ --no-initrd)
+--
+2.35.1
+
--- /dev/null
+From f7cb2d168c4eecd70085d62baeb55b0bbdcc1467 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 15:07:18 +0800
+Subject: RDMA/hfi1: fix potential memory leak in setup_base_ctxt()
+
+From: Jianglei Nie <niejianglei2021@163.com>
+
+[ Upstream commit aa2a1df3a2c85f855af7d54466ac10bd48645d63 ]
+
+setup_base_ctxt() allocates a memory chunk for uctxt->groups with
+hfi1_alloc_ctxt_rcv_groups(). When init_user_ctxt() fails, uctxt->groups
+is not released, which will lead to a memory leak.
+
+We should release the uctxt->groups with hfi1_free_ctxt_rcv_groups()
+when init_user_ctxt() fails.
+
+Fixes: e87473bc1b6c ("IB/hfi1: Only set fd pointer when base context is completely initialized")
+Link: https://lore.kernel.org/r/20220711070718.2318320-1-niejianglei2021@163.com
+Signed-off-by: Jianglei Nie <niejianglei2021@163.com>
+Acked-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hfi1/file_ops.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c
+index 3ebdd42fec36..686d170a5947 100644
+--- a/drivers/infiniband/hw/hfi1/file_ops.c
++++ b/drivers/infiniband/hw/hfi1/file_ops.c
+@@ -1179,8 +1179,10 @@ static int setup_base_ctxt(struct hfi1_filedata *fd,
+ goto done;
+
+ ret = init_user_ctxt(fd, uctxt);
+- if (ret)
++ if (ret) {
++ hfi1_free_ctxt_rcv_groups(uctxt);
+ goto done;
++ }
+
+ user_init(uctxt);
+
+--
+2.35.1
+
--- /dev/null
+From 1137bec3decc97b28820cd683b109465878a6bb7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 21:43:51 +0800
+Subject: RDMA/hns: Fix incorrect clearing of interrupt status register
+
+From: Haoyue Xu <xuhaoyue1@hisilicon.com>
+
+[ Upstream commit ecb4db5c3590aa956b4b2c352081a5b632d1f9f9 ]
+
+The driver will clear all the interrupts in the same area
+when the driver handles the interrupt of type AEQ overflow.
+It should only set the interrupt status bit of type AEQ overflow.
+
+Fixes: a5073d6054f7 ("RDMA/hns: Add eq support of hip08")
+Link: https://lore.kernel.org/r/20220714134353.16700-4-liangwenpeng@huawei.com
+Signed-off-by: Haoyue Xu <xuhaoyue1@hisilicon.com>
+Signed-off-by: Wenpeng Liang <liangwenpeng@huawei.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 86f6a4aae1e5..6e7dadc3386c 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -6125,8 +6125,8 @@ static irqreturn_t hns_roce_v2_msix_interrupt_abn(int irq, void *dev_id)
+
+ dev_err(dev, "AEQ overflow!\n");
+
+- int_st |= 1 << HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S;
+- roce_write(hr_dev, ROCEE_VF_ABN_INT_ST_REG, int_st);
++ roce_write(hr_dev, ROCEE_VF_ABN_INT_ST_REG,
++ 1 << HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S);
+
+ /* Set reset level for reset_event() */
+ if (ops->set_default_reset_request)
+--
+2.35.1
+
--- /dev/null
+From 6777cbe4ac52656ec04525510df54ae8f3353fed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 18:08:13 -0500
+Subject: RDMA/irdma: Fix a window for use-after-free
+
+From: Mustafa Ismail <mustafa.ismail@intel.com>
+
+[ Upstream commit 8ecef7890b3aea78c8bbb501a4b5b8134367b821 ]
+
+During a destroy CQ an interrupt may cause processing of a CQE after CQ
+resources are freed by irdma_cq_free_rsrc(). Fix this by moving the call
+to irdma_cq_free_rsrc() after the irdma_sc_cleanup_ceqes(), which is
+called under the cq_lock.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Link: https://lore.kernel.org/r/20220705230815.265-6-shiraz.saleem@intel.com
+Signed-off-by: Bartosz Sobczak <bartosz.sobczak@intel.com>
+Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 6daa149dcbda..b29631f6659a 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -1760,11 +1760,11 @@ static int irdma_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
+ spin_unlock_irqrestore(&iwcq->lock, flags);
+
+ irdma_cq_wq_destroy(iwdev->rf, cq);
+- irdma_cq_free_rsrc(iwdev->rf, iwcq);
+
+ spin_lock_irqsave(&iwceq->ce_lock, flags);
+ irdma_sc_cleanup_ceqes(cq, ceq);
+ spin_unlock_irqrestore(&iwceq->ce_lock, flags);
++ irdma_cq_free_rsrc(iwdev->rf, iwcq);
+
+ return 0;
+ }
+--
+2.35.1
+
--- /dev/null
+From 3a9a126fe002af2ed06e82bc0b655997364588e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 18:08:15 -0500
+Subject: RDMA/irdma: Fix setting of QP context err_rq_idx_valid field
+
+From: Mustafa Ismail <mustafa.ismail@intel.com>
+
+[ Upstream commit 3a844596ed71b7c12ac602f6f6b7b0f17e4d6a90 ]
+
+Setting err_rq_idx_valid field in QP context when the AE source of the
+AEQE is not associated with an RQ causes the firmware flush to fail.
+
+Set err_rq_idx_valid field in QP context only if it is associated with an
+RQ. Additionally, cleanup the redundant setting of this field in
+irdma_process_aeq.
+
+Fixes: 44d9e52977a1 ("RDMA/irdma: Implement device initialization definitions")
+Link: https://lore.kernel.org/r/20220705230815.265-8-shiraz.saleem@intel.com
+Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/hw.c | 15 ++++-----------
+ 1 file changed, 4 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c
+index 3dc9b5801da1..c1b402a06e17 100644
+--- a/drivers/infiniband/hw/irdma/hw.c
++++ b/drivers/infiniband/hw/irdma/hw.c
+@@ -257,10 +257,6 @@ static void irdma_process_aeq(struct irdma_pci_f *rf)
+ iwqp->last_aeq = info->ae_id;
+ spin_unlock_irqrestore(&iwqp->lock, flags);
+ ctx_info = &iwqp->ctx_info;
+- if (rdma_protocol_roce(&iwqp->iwdev->ibdev, 1))
+- ctx_info->roce_info->err_rq_idx_valid = true;
+- else
+- ctx_info->iwarp_info->err_rq_idx_valid = true;
+ } else {
+ if (info->ae_id != IRDMA_AE_CQ_OPERATION_ERROR)
+ continue;
+@@ -370,16 +366,12 @@ static void irdma_process_aeq(struct irdma_pci_f *rf)
+ case IRDMA_AE_LCE_FUNCTION_CATASTROPHIC:
+ case IRDMA_AE_LCE_CQ_CATASTROPHIC:
+ case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG:
+- if (rdma_protocol_roce(&iwdev->ibdev, 1))
+- ctx_info->roce_info->err_rq_idx_valid = false;
+- else
+- ctx_info->iwarp_info->err_rq_idx_valid = false;
+- fallthrough;
+ default:
+ ibdev_err(&iwdev->ibdev, "abnormal ae_id = 0x%x bool qp=%d qp_id = %d\n",
+ info->ae_id, info->qp, info->qp_cq_id);
+ if (rdma_protocol_roce(&iwdev->ibdev, 1)) {
+- if (!info->sq && ctx_info->roce_info->err_rq_idx_valid) {
++ ctx_info->roce_info->err_rq_idx_valid = info->rq;
++ if (info->rq) {
+ ctx_info->roce_info->err_rq_idx = info->wqe_idx;
+ irdma_sc_qp_setctx_roce(&iwqp->sc_qp, iwqp->host_ctx.va,
+ ctx_info);
+@@ -388,7 +380,8 @@ static void irdma_process_aeq(struct irdma_pci_f *rf)
+ irdma_cm_disconn(iwqp);
+ break;
+ }
+- if (!info->sq && ctx_info->iwarp_info->err_rq_idx_valid) {
++ ctx_info->iwarp_info->err_rq_idx_valid = info->rq;
++ if (info->rq) {
+ ctx_info->iwarp_info->err_rq_idx = info->wqe_idx;
+ ctx_info->tcp_info_valid = false;
+ ctx_info->iwarp_info_valid = true;
+--
+2.35.1
+
--- /dev/null
+From fe7b456b2d4e1a789543b70ce48d1539b71663ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 18:08:14 -0500
+Subject: RDMA/irdma: Fix VLAN connection with wildcard address
+
+From: Mustafa Ismail <mustafa.ismail@intel.com>
+
+[ Upstream commit 82ab2b52654c43ba24a3f6603fec40874cc5a7e5 ]
+
+When an application listens on a wildcard address, and there are VLAN and
+non-VLAN IP addresses, iWARP connection establishemnt can fail if the listen
+node VLAN ID does not match.
+
+Fix this by checking the vlan_id only if not a wildcard listen node.
+
+Fixes: 146b9756f14c ("RDMA/irdma: Add connection manager")
+Link: https://lore.kernel.org/r/20220705230815.265-7-shiraz.saleem@intel.com
+Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/cm.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c
+index 646fa8677490..7b086fe63a24 100644
+--- a/drivers/infiniband/hw/irdma/cm.c
++++ b/drivers/infiniband/hw/irdma/cm.c
+@@ -1477,12 +1477,13 @@ irdma_find_listener(struct irdma_cm_core *cm_core, u32 *dst_addr, u16 dst_port,
+ list_for_each_entry (listen_node, &cm_core->listen_list, list) {
+ memcpy(listen_addr, listen_node->loc_addr, sizeof(listen_addr));
+ listen_port = listen_node->loc_port;
++ if (listen_port != dst_port ||
++ !(listener_state & listen_node->listener_state))
++ continue;
+ /* compare node pair, return node handle if a match */
+- if ((!memcmp(listen_addr, dst_addr, sizeof(listen_addr)) ||
+- !memcmp(listen_addr, ip_zero, sizeof(listen_addr))) &&
+- listen_port == dst_port &&
+- vlan_id == listen_node->vlan_id &&
+- (listener_state & listen_node->listener_state)) {
++ if (!memcmp(listen_addr, ip_zero, sizeof(listen_addr)) ||
++ (!memcmp(listen_addr, dst_addr, sizeof(listen_addr)) &&
++ vlan_id == listen_node->vlan_id)) {
+ refcount_inc(&listen_node->refcnt);
+ spin_unlock_irqrestore(&cm_core->listen_list_lock,
+ flags);
+--
+2.35.1
+
--- /dev/null
+From ac54a617fb3fd02ab385387140b05c0cc0c5278f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 Jul 2022 11:29:08 +0300
+Subject: RDMA/mlx5: Add missing check for return value in get namespace flow
+
+From: Maor Gottlieb <maorg@nvidia.com>
+
+[ Upstream commit c9776457bd5eaad4ce4ecb17af8d8f3cc6957c0b ]
+
+Add missing check for return value when calling to
+mlx5_ib_ft_type_to_namespace, even though it can't really fail in this
+specific call.
+
+Fixes: 52438be44112 ("RDMA/mlx5: Allow inserting a steering rule to the FDB")
+Link: https://lore.kernel.org/r/7b9ceda217d9368a51dc47a46b769bad4af9ac92.1659256069.git.leonro@nvidia.com
+Reviewed-by: Itay Aveksis <itayav@nvidia.com>
+Signed-off-by: Maor Gottlieb <maorg@nvidia.com>
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/fs.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/fs.c b/drivers/infiniband/hw/mlx5/fs.c
+index 661ed2b44508..6092118de672 100644
+--- a/drivers/infiniband/hw/mlx5/fs.c
++++ b/drivers/infiniband/hw/mlx5/fs.c
+@@ -2265,12 +2265,10 @@ static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle *attrs,
+ if (err)
+ return err;
+
+- if (flags) {
+- mlx5_ib_ft_type_to_namespace(
++ if (flags)
++ return mlx5_ib_ft_type_to_namespace(
+ MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX,
+ &obj->ns_type);
+- return 0;
+- }
+ }
+
+ obj->ns_type = MLX5_FLOW_NAMESPACE_BYPASS;
+--
+2.35.1
+
--- /dev/null
+From 67120e5736944fb960e437e54059155efd303267 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 14:15:05 +0800
+Subject: RDMA/qedr: Fix potential memory leak in __qedr_alloc_mr()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jianglei Nie <niejianglei2021@163.com>
+
+[ Upstream commit b3236a64ddd125a455ef5b5316c1b9051b732974 ]
+
+__qedr_alloc_mr() allocates a memory chunk for "mr->info.pbl_table" with
+init_mr_info(). When rdma_alloc_tid() and rdma_register_tid() fail, "mr"
+is released while "mr->info.pbl_table" is not released, which will lead
+to a memory leak.
+
+We should release the "mr->info.pbl_table" with qedr_free_pbl() when error
+occurs to fix the memory leak.
+
+Fixes: e0290cce6ac0 ("qedr: Add support for memory registeration verbs")
+Link: https://lore.kernel.org/r/20220714061505.2342759-1-niejianglei2021@163.com
+Signed-off-by: Jianglei Nie <niejianglei2021@163.com>
+Acked-by: Michal Kalderon <michal.kalderon@marvell.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/qedr/verbs.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c
+index df4d7970c1ad..cc99b293f0be 100644
+--- a/drivers/infiniband/hw/qedr/verbs.c
++++ b/drivers/infiniband/hw/qedr/verbs.c
+@@ -3083,7 +3083,7 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd,
+ else
+ DP_ERR(dev, "roce alloc tid returned error %d\n", rc);
+
+- goto err0;
++ goto err1;
+ }
+
+ /* Index only, 18 bit long, lkey = itid << 8 | key */
+@@ -3107,7 +3107,7 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd,
+ rc = dev->ops->rdma_register_tid(dev->rdma_ctx, &mr->hw_mr);
+ if (rc) {
+ DP_ERR(dev, "roce register tid returned an error %d\n", rc);
+- goto err1;
++ goto err2;
+ }
+
+ mr->ibmr.lkey = mr->hw_mr.itid << 8 | mr->hw_mr.key;
+@@ -3116,8 +3116,10 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd,
+ DP_DEBUG(dev, QEDR_MSG_MR, "alloc frmr: %x\n", mr->ibmr.lkey);
+ return mr;
+
+-err1:
++err2:
+ dev->ops->rdma_free_tid(dev->rdma_ctx, mr->hw_mr.itid);
++err1:
++ qedr_free_pbl(dev, &mr->info.pbl_info, mr->info.pbl_table);
+ err0:
+ kfree(mr);
+ return ERR_PTR(rc);
+--
+2.35.1
+
--- /dev/null
+From 460620bc4a9d073698633fde8c2197d28650f007 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 12:31:12 +0200
+Subject: RDMA/rtrs-clt: Replace list_next_or_null_rr_rcu with an inline
+ function
+
+From: Md Haris Iqbal <haris.iqbal@ionos.com>
+
+[ Upstream commit c14adff285ad1bb8eefc5d8fc202ceb1f7e3a2f1 ]
+
+removes list_next_or_null_rr_rcu macro to fix below warnings.
+That macro is used only twice.
+CHECK:MACRO_ARG_REUSE: Macro argument reuse 'head' - possible side-effects?
+CHECK:MACRO_ARG_REUSE: Macro argument reuse 'ptr' - possible side-effects?
+CHECK:MACRO_ARG_REUSE: Macro argument reuse 'memb' - possible side-effects?
+
+Replaces that macro with an inline function.
+
+Fixes: 6a98d71daea1 ("RDMA/rtrs: client: main functionality")
+Cc: jinpu.wang@ionos.com
+Link: https://lore.kernel.org/r/20220712103113.617754-5-haris.iqbal@ionos.com
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Suggested-by: Jason Gunthorpe <jgg@ziepe.ca>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-clt.c | 35 ++++++++++++--------------
+ 1 file changed, 16 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+index c2c860d0c56e..65bad1dd917b 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+@@ -740,25 +740,25 @@ struct path_it {
+ struct rtrs_clt_path *(*next_path)(struct path_it *it);
+ };
+
+-/**
+- * list_next_or_null_rr_rcu - get next list element in round-robin fashion.
++/*
++ * rtrs_clt_get_next_path_or_null - get clt path from the list or return NULL
+ * @head: the head for the list.
+- * @ptr: the list head to take the next element from.
+- * @type: the type of the struct this is embedded in.
+- * @memb: the name of the list_head within the struct.
++ * @clt_path: The element to take the next clt_path from.
+ *
+- * Next element returned in round-robin fashion, i.e. head will be skipped,
++ * Next clt path returned in round-robin fashion, i.e. head will be skipped,
+ * but if list is observed as empty, NULL will be returned.
+ *
+- * This primitive may safely run concurrently with the _rcu list-mutation
++ * This function may safely run concurrently with the _rcu list-mutation
+ * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().
+ */
+-#define list_next_or_null_rr_rcu(head, ptr, type, memb) \
+-({ \
+- list_next_or_null_rcu(head, ptr, type, memb) ?: \
+- list_next_or_null_rcu(head, READ_ONCE((ptr)->next), \
+- type, memb); \
+-})
++static inline struct rtrs_clt_path *
++rtrs_clt_get_next_path_or_null(struct list_head *head, struct rtrs_clt_path *clt_path)
++{
++ return list_next_or_null_rcu(head, &clt_path->s.entry, typeof(*clt_path), s.entry) ?:
++ list_next_or_null_rcu(head,
++ READ_ONCE((&clt_path->s.entry)->next),
++ typeof(*clt_path), s.entry);
++}
+
+ /**
+ * get_next_path_rr() - Returns path in round-robin fashion.
+@@ -789,10 +789,8 @@ static struct rtrs_clt_path *get_next_path_rr(struct path_it *it)
+ path = list_first_or_null_rcu(&clt->paths_list,
+ typeof(*path), s.entry);
+ else
+- path = list_next_or_null_rr_rcu(&clt->paths_list,
+- &path->s.entry,
+- typeof(*path),
+- s.entry);
++ path = rtrs_clt_get_next_path_or_null(&clt->paths_list, path);
++
+ rcu_assign_pointer(*ppcpu_path, path);
+
+ return path;
+@@ -2277,8 +2275,7 @@ static void rtrs_clt_remove_path_from_arr(struct rtrs_clt_path *clt_path)
+ * removed. If @sess is the last element, then @next is NULL.
+ */
+ rcu_read_lock();
+- next = list_next_or_null_rr_rcu(&clt->paths_list, &clt_path->s.entry,
+- typeof(*next), s.entry);
++ next = rtrs_clt_get_next_path_or_null(&clt->paths_list, clt_path);
+ rcu_read_unlock();
+
+ /*
+--
+2.35.1
+
--- /dev/null
+From 402380016fcfc60f62464bf31659c446e350b25e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 12:31:09 +0200
+Subject: RDMA/rtrs-srv: Fix modinfo output for stringify
+
+From: Jack Wang <jinpu.wang@ionos.com>
+
+[ Upstream commit ed6e53820ee4f68ed927de17e5675ff2a07a47e2 ]
+
+stringify works with define, not enum.
+
+Fixes: 91fddedd439c ("RDMA/rtrs: private headers with rtrs protocol structs and helpers")
+Cc: jinpu.wang@ionos.com
+Link: https://lore.kernel.org/r/20220712103113.617754-2-haris.iqbal@ionos.com
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Reviewed-by: Aleksei Marov <aleksei.marov@ionos.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-pri.h | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-pri.h b/drivers/infiniband/ulp/rtrs/rtrs-pri.h
+index 9a1e5c2ae55c..ac0df734eba8 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-pri.h
++++ b/drivers/infiniband/ulp/rtrs/rtrs-pri.h
+@@ -23,6 +23,17 @@
+ #define RTRS_PROTO_VER_STRING __stringify(RTRS_PROTO_VER_MAJOR) "." \
+ __stringify(RTRS_PROTO_VER_MINOR)
+
++/*
++ * Max IB immediate data size is 2^28 (MAX_IMM_PAYL_BITS)
++ * and the minimum chunk size is 4096 (2^12).
++ * So the maximum sess_queue_depth is 65536 (2^16) in theory.
++ * But mempool_create, create_qp and ib_post_send fail with
++ * "cannot allocate memory" error if sess_queue_depth is too big.
++ * Therefore the pratical max value of sess_queue_depth is
++ * somewhere between 1 and 65534 and it depends on the system.
++ */
++#define MAX_SESS_QUEUE_DEPTH 65535
++
+ enum rtrs_imm_const {
+ MAX_IMM_TYPE_BITS = 4,
+ MAX_IMM_TYPE_MASK = ((1 << MAX_IMM_TYPE_BITS) - 1),
+@@ -46,16 +57,6 @@ enum {
+
+ MAX_PATHS_NUM = 128,
+
+- /*
+- * Max IB immediate data size is 2^28 (MAX_IMM_PAYL_BITS)
+- * and the minimum chunk size is 4096 (2^12).
+- * So the maximum sess_queue_depth is 65536 (2^16) in theory.
+- * But mempool_create, create_qp and ib_post_send fail with
+- * "cannot allocate memory" error if sess_queue_depth is too big.
+- * Therefore the pratical max value of sess_queue_depth is
+- * somewhere between 1 and 65534 and it depends on the system.
+- */
+- MAX_SESS_QUEUE_DEPTH = 65535,
+ MIN_CHUNK_SIZE = 8192,
+
+ RTRS_HB_INTERVAL_MS = 5000,
+--
+2.35.1
+
--- /dev/null
+From ec6d39b1ca3dc2faf71d2fc05202ad7229df85f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 May 2022 17:32:52 -0500
+Subject: RDMA/rxe: Fix deadlock in rxe_do_local_ops()
+
+From: Bob Pearson <rpearsonhpe@gmail.com>
+
+[ Upstream commit 7cb33d1bc1ac8e51fd88928f96674d392f8e07c4 ]
+
+When a local operation (invalidate mr, reg mr, bind mw) is finished there
+will be no ack packet coming from a responder to cause the wqe to be
+completed. This may happen anyway if a subsequent wqe performs
+IO. Currently if the wqe is signalled the completer tasklet is scheduled
+immediately but not otherwise.
+
+This leads to a deadlock if the next wqe has the fence bit set in send
+flags and the operation is not signalled. This patch removes the condition
+that the wqe must be signalled in order to schedule the completer tasklet
+which is the simplest fix for this deadlock and is fairly low cost. This
+is the analog for local operations of always setting the ackreq bit in all
+last or only request packets even if the operation is not signalled.
+
+Link: https://lore.kernel.org/r/20220523223251.15350-1-rpearsonhpe@gmail.com
+Reported-by: Jenny Hack <jhack@hpe.com>
+Fixes: c1a411268a4b ("RDMA/rxe: Move local ops to subroutine")
+Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_req.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
+index 8a1cff80a68e..d574c47099b8 100644
+--- a/drivers/infiniband/sw/rxe/rxe_req.c
++++ b/drivers/infiniband/sw/rxe/rxe_req.c
+@@ -586,9 +586,11 @@ static int rxe_do_local_ops(struct rxe_qp *qp, struct rxe_send_wqe *wqe)
+ wqe->status = IB_WC_SUCCESS;
+ qp->req.wqe_index = queue_next_index(qp->sq.queue, qp->req.wqe_index);
+
+- if ((wqe->wr.send_flags & IB_SEND_SIGNALED) ||
+- qp->sq_sig_type == IB_SIGNAL_ALL_WR)
+- rxe_run_task(&qp->comp.task, 1);
++ /* There is no ack coming for local work requests
++ * which can lead to a deadlock. So go ahead and complete
++ * it now.
++ */
++ rxe_run_task(&qp->comp.task, 1);
+
+ return 0;
+ }
+--
+2.35.1
+
--- /dev/null
+From 61d93a85edd82e595ffc8000275aa6eb826bf8ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 Jul 2022 02:36:21 -0400
+Subject: RDMA/rxe: Fix error unwind in rxe_create_qp()
+
+From: Zhu Yanjun <yanjun.zhu@linux.dev>
+
+[ Upstream commit fd5382c5805c4bcb50fd25b7246247d3f7114733 ]
+
+In the function rxe_create_qp(), rxe_qp_from_init() is called to
+initialize qp, internally things like the spin locks are not setup until
+rxe_qp_init_req().
+
+If an error occures before this point then the unwind will call
+rxe_cleanup() and eventually to rxe_qp_do_cleanup()/rxe_cleanup_task()
+which will oops when trying to access the uninitialized spinlock.
+
+Move the spinlock initializations earlier before any failures.
+
+Fixes: 8700e3e7c485 ("Soft RoCE driver")
+Link: https://lore.kernel.org/r/20220731063621.298405-1-yanjun.zhu@linux.dev
+Reported-by: syzbot+833061116fa28df97f3b@syzkaller.appspotmail.com
+Signed-off-by: Zhu Yanjun <yanjun.zhu@linux.dev>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_qp.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index 7d0c4432d3fd..4889dcae0cc8 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -186,6 +186,14 @@ static void rxe_qp_init_misc(struct rxe_dev *rxe, struct rxe_qp *qp,
+
+ spin_lock_init(&qp->state_lock);
+
++ spin_lock_init(&qp->req.task.state_lock);
++ spin_lock_init(&qp->resp.task.state_lock);
++ spin_lock_init(&qp->comp.task.state_lock);
++
++ spin_lock_init(&qp->sq.sq_lock);
++ spin_lock_init(&qp->rq.producer_lock);
++ spin_lock_init(&qp->rq.consumer_lock);
++
+ atomic_set(&qp->ssn, 0);
+ atomic_set(&qp->skb_out, 0);
+ }
+@@ -245,7 +253,6 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp,
+ qp->req.opcode = -1;
+ qp->comp.opcode = -1;
+
+- spin_lock_init(&qp->sq.sq_lock);
+ skb_queue_head_init(&qp->req_pkts);
+
+ rxe_init_task(rxe, &qp->req.task, qp,
+@@ -296,9 +303,6 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp,
+ }
+ }
+
+- spin_lock_init(&qp->rq.producer_lock);
+- spin_lock_init(&qp->rq.consumer_lock);
+-
+ skb_queue_head_init(&qp->resp_pkts);
+
+ rxe_init_task(rxe, &qp->resp.task, qp,
+--
+2.35.1
+
--- /dev/null
+From 7b20f5cedaed1c4801ea81977f0d3090d0a346cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 15:46:20 -0500
+Subject: RDMA/rxe: Fix mw bind to allow any consumer key portion
+
+From: Bob Pearson <rpearsonhpe@gmail.com>
+
+[ Upstream commit 1603f89935ec86d40a7667e1250392626976ccc2 ]
+
+The current implementation of rxe_check_bind_mw() in rxe_mw.c is incorrect
+since it requires the new key portion provided by the mw consumer to be
+different than the previous key portion. This is not required by the
+IBA. Remove the test.
+
+Link: https://lore.kernel.org/linux-rdma/fb4614e7-4cac-0dc7-3ef7-766dfd10e8f2@gmail.com/
+Fixes: 32a577b4c3a9 ("Add support for bind MW work requests")
+Link: https://lore.kernel.org/r/20220714204619.13396-1-rpearsonhpe@gmail.com
+Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_mw.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c
+index c86b2efd58f2..fc1416fc7feb 100644
+--- a/drivers/infiniband/sw/rxe/rxe_mw.c
++++ b/drivers/infiniband/sw/rxe/rxe_mw.c
+@@ -69,8 +69,6 @@ int rxe_dealloc_mw(struct ib_mw *ibmw)
+ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
+ struct rxe_mw *mw, struct rxe_mr *mr)
+ {
+- u32 key = wqe->wr.wr.mw.rkey & 0xff;
+-
+ if (mw->ibmw.type == IB_MW_TYPE_1) {
+ if (unlikely(mw->state != RXE_MW_STATE_VALID)) {
+ pr_err_once(
+@@ -108,11 +106,6 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
+ }
+ }
+
+- if (unlikely(key == (mw->rkey & 0xff))) {
+- pr_err_once("attempt to bind MW with same key\n");
+- return -EINVAL;
+- }
+-
+ /* remaining checks only apply to a nonzero MR */
+ if (!mr)
+ return 0;
+--
+2.35.1
+
--- /dev/null
+From ed857b561cf2827a4e89172fcfc0d3ad07df7863 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jun 2022 14:04:22 -0500
+Subject: RDMA/rxe: Fix rnr retry behavior
+
+From: Bob Pearson <rpearsonhpe@gmail.com>
+
+[ Upstream commit 445fd4f4fb76d513de6b05b08b3a4d0bb980fc80 ]
+
+Currently the completer tasklet when retransmit timer or the rnr timer
+fires the same flag (qp->req.need_retry) is set so that if either timer
+fires it will attempt to perform a retry flow on the send queue. This has
+the effect of responding to an RNR NAK at the first retransmit timer event
+which might not allow the requested rnr timeout.
+
+This patch adds a new flag (qp->req.wait_for_rnr_timer) which, if set,
+prevents a retry flow until the rnr nak timer fires.
+
+This patch fixes rnr retry errors which can be observed by running the
+pyverbs test_rdmacm_async_traffic_external_qp multiple times. With this
+patch applied they do not occur.
+
+Link: https://lore.kernel.org/linux-rdma/a8287823-1408-4273-bc22-99a0678db640@gmail.com/
+Link: https://lore.kernel.org/linux-rdma/2bafda9e-2bb6-186d-12a1-179e8f6a2678@talpey.com/
+Fixes: 8700e3e7c485 ("Soft RoCE driver")
+Link: https://lore.kernel.org/r/20220630190425.2251-6-rpearsonhpe@gmail.com
+Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_comp.c | 8 +++++++-
+ drivers/infiniband/sw/rxe/rxe_qp.c | 1 +
+ drivers/infiniband/sw/rxe/rxe_req.c | 15 +++++++++++++--
+ drivers/infiniband/sw/rxe/rxe_verbs.h | 1 +
+ 4 files changed, 22 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c
+index 138b3e7d3a5f..ec671e171f13 100644
+--- a/drivers/infiniband/sw/rxe/rxe_comp.c
++++ b/drivers/infiniband/sw/rxe/rxe_comp.c
+@@ -114,6 +114,8 @@ void retransmit_timer(struct timer_list *t)
+ {
+ struct rxe_qp *qp = from_timer(qp, t, retrans_timer);
+
++ pr_debug("%s: fired for qp#%d\n", __func__, qp->elem.index);
++
+ if (qp->valid) {
+ qp->comp.timeout = 1;
+ rxe_run_task(&qp->comp.task, 1);
+@@ -729,11 +731,15 @@ int rxe_completer(void *arg)
+ break;
+
+ case COMPST_RNR_RETRY:
++ /* we come here if we received an RNR NAK */
+ if (qp->comp.rnr_retry > 0) {
+ if (qp->comp.rnr_retry != 7)
+ qp->comp.rnr_retry--;
+
+- qp->req.need_retry = 1;
++ /* don't start a retry flow until the
++ * rnr timer has fired
++ */
++ qp->req.wait_for_rnr_timer = 1;
+ pr_debug("qp#%d set rnr nak timer\n",
+ qp_num(qp));
+ mod_timer(&qp->rnr_nak_timer,
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index 62acf890af6c..7d0c4432d3fd 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -513,6 +513,7 @@ static void rxe_qp_reset(struct rxe_qp *qp)
+ atomic_set(&qp->ssn, 0);
+ qp->req.opcode = -1;
+ qp->req.need_retry = 0;
++ qp->req.wait_for_rnr_timer = 0;
+ qp->req.noack_pkts = 0;
+ qp->resp.msn = 0;
+ qp->resp.opcode = -1;
+diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
+index d574c47099b8..90669b3c56af 100644
+--- a/drivers/infiniband/sw/rxe/rxe_req.c
++++ b/drivers/infiniband/sw/rxe/rxe_req.c
+@@ -103,7 +103,11 @@ void rnr_nak_timer(struct timer_list *t)
+ {
+ struct rxe_qp *qp = from_timer(qp, t, rnr_nak_timer);
+
+- pr_debug("qp#%d rnr nak timer fired\n", qp_num(qp));
++ pr_debug("%s: fired for qp#%d\n", __func__, qp_num(qp));
++
++ /* request a send queue retry */
++ qp->req.need_retry = 1;
++ qp->req.wait_for_rnr_timer = 0;
+ rxe_run_task(&qp->req.task, 1);
+ }
+
+@@ -626,10 +630,17 @@ int rxe_requester(void *arg)
+ qp->req.need_rd_atomic = 0;
+ qp->req.wait_psn = 0;
+ qp->req.need_retry = 0;
++ qp->req.wait_for_rnr_timer = 0;
+ goto exit;
+ }
+
+- if (unlikely(qp->req.need_retry)) {
++ /* we come here if the retransmot timer has fired
++ * or if the rnr timer has fired. If the retransmit
++ * timer fires while we are processing an RNR NAK wait
++ * until the rnr timer has fired before starting the
++ * retry flow
++ */
++ if (unlikely(qp->req.need_retry && !qp->req.wait_for_rnr_timer)) {
+ req_retry(qp);
+ qp->req.need_retry = 0;
+ }
+diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h
+index e7eff1ca75e9..33e8d0547553 100644
+--- a/drivers/infiniband/sw/rxe/rxe_verbs.h
++++ b/drivers/infiniband/sw/rxe/rxe_verbs.h
+@@ -123,6 +123,7 @@ struct rxe_req_info {
+ int need_rd_atomic;
+ int wait_psn;
+ int need_retry;
++ int wait_for_rnr_timer;
+ int noack_pkts;
+ struct rxe_task task;
+ };
+--
+2.35.1
+
--- /dev/null
+From 75a98d233f2dd6561c75e5e4ca1f0e0494547c03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 15:06:56 +0800
+Subject: RDMA/rxe: fix xa_alloc_cycle() error return value check again
+
+From: Dongliang Mu <mudongliangabcd@gmail.com>
+
+[ Upstream commit 1a685940e6200e9def6e34bbaa19dd31dc5aeaf8 ]
+
+Currently rxe_alloc checks ret to indicate error, but 1 is also a valid
+return and just indicates that the allocation succeeded with a wrap.
+
+Fix this by modifying the check to be < 0.
+
+Link: https://lore.kernel.org/r/20220609070656.1446121-1-dzm91@hust.edu.cn
+Fixes: 3225717f6dfa ("RDMA/rxe: Replace red-black trees by xarrays")
+Signed-off-by: Dongliang Mu <mudongliangabcd@gmail.com>
+Reviewed-by: Bob Pearson <rpearsonhpe@gmail.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_pool.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c
+index 87066d04ed18..69db28944567 100644
+--- a/drivers/infiniband/sw/rxe/rxe_pool.c
++++ b/drivers/infiniband/sw/rxe/rxe_pool.c
+@@ -140,7 +140,7 @@ void *rxe_alloc(struct rxe_pool *pool)
+
+ err = xa_alloc_cyclic(&pool->xa, &elem->index, elem, pool->limit,
+ &pool->next, GFP_KERNEL);
+- if (err)
++ if (err < 0)
+ goto err_free;
+
+ return obj;
+@@ -168,7 +168,7 @@ int __rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_elem *elem)
+
+ err = xa_alloc_cyclic(&pool->xa, &elem->index, elem, pool->limit,
+ &pool->next, GFP_KERNEL);
+- if (err)
++ if (err < 0)
+ goto err_cnt;
+
+ return 0;
+--
+2.35.1
+
--- /dev/null
+From 9083c851a302064fd87599fbae85f0846046308f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 09:30:06 +0200
+Subject: RDMA/rxe: For invalidate compare according to set keys in mr
+
+From: Md Haris Iqbal <haris.phnx@gmail.com>
+
+[ Upstream commit 174e7b137042f19b5ce88beb4fc0ff4ec6b0c72a ]
+
+The 'rkey' input can be an lkey or rkey, and in rxe the lkey or rkey have
+the same value, including the variant bits.
+
+So, if mr->rkey is set, compare the invalidate key with it, otherwise
+compare with the mr->lkey.
+
+Since we already did a lookup on the non-varient bits to get this far, the
+check's only purpose is to confirm that the wqe has the correct variant
+bits.
+
+Fixes: 001345339f4c ("RDMA/rxe: Separate HW and SW l/rkeys")
+Link: https://lore.kernel.org/r/20220707073006.328737-1-haris.phnx@gmail.com
+Signed-off-by: Md Haris Iqbal <haris.phnx@gmail.com>
+Reviewed-by: Bob Pearson <rpearsonhpe@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/rxe/rxe_loc.h | 2 +-
+ drivers/infiniband/sw/rxe/rxe_mr.c | 12 ++++++------
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h
+index 2ffbe3390668..2b0edf360474 100644
+--- a/drivers/infiniband/sw/rxe/rxe_loc.h
++++ b/drivers/infiniband/sw/rxe/rxe_loc.h
+@@ -77,7 +77,7 @@ struct rxe_mr *lookup_mr(struct rxe_pd *pd, int access, u32 key,
+ enum rxe_mr_lookup_type type);
+ int mr_check_range(struct rxe_mr *mr, u64 iova, size_t length);
+ int advance_dma_data(struct rxe_dma_info *dma, unsigned int length);
+-int rxe_invalidate_mr(struct rxe_qp *qp, u32 rkey);
++int rxe_invalidate_mr(struct rxe_qp *qp, u32 key);
+ int rxe_reg_fast_mr(struct rxe_qp *qp, struct rxe_send_wqe *wqe);
+ int rxe_mr_set_page(struct ib_mr *ibmr, u64 addr);
+ int rxe_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);
+diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
+index 60a31b718774..76d6498e83f9 100644
+--- a/drivers/infiniband/sw/rxe/rxe_mr.c
++++ b/drivers/infiniband/sw/rxe/rxe_mr.c
+@@ -576,22 +576,22 @@ struct rxe_mr *lookup_mr(struct rxe_pd *pd, int access, u32 key,
+ return mr;
+ }
+
+-int rxe_invalidate_mr(struct rxe_qp *qp, u32 rkey)
++int rxe_invalidate_mr(struct rxe_qp *qp, u32 key)
+ {
+ struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
+ struct rxe_mr *mr;
+ int ret;
+
+- mr = rxe_pool_get_index(&rxe->mr_pool, rkey >> 8);
++ mr = rxe_pool_get_index(&rxe->mr_pool, key >> 8);
+ if (!mr) {
+- pr_err("%s: No MR for rkey %#x\n", __func__, rkey);
++ pr_err("%s: No MR for key %#x\n", __func__, key);
+ ret = -EINVAL;
+ goto err;
+ }
+
+- if (rkey != mr->rkey) {
+- pr_err("%s: rkey (%#x) doesn't match mr->rkey (%#x)\n",
+- __func__, rkey, mr->rkey);
++ if (mr->rkey ? (key != mr->rkey) : (key != mr->lkey)) {
++ pr_err("%s: wr key (%#x) doesn't match mr key (%#x)\n",
++ __func__, key, (mr->rkey ? mr->rkey : mr->lkey));
+ ret = -EINVAL;
+ goto err_drop_ref;
+ }
+--
+2.35.1
+
--- /dev/null
+From 4f2c22b11825f45d7cdfd30b54fd14149f99ff6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 09:30:47 +0800
+Subject: RDMA/siw: Fix duplicated reported IW_CM_EVENT_CONNECT_REPLY event
+
+From: Cheng Xu <chengyou@linux.alibaba.com>
+
+[ Upstream commit 3056fc6c32e613b760422b94c7617ac9a24a4721 ]
+
+If siw_recv_mpa_rr returns -EAGAIN, it means that the MPA reply hasn't
+been received completely, and should not report IW_CM_EVENT_CONNECT_REPLY
+in this case. This may trigger a call trace in iw_cm. A simple way to
+trigger this:
+ server: ib_send_lat
+ client: ib_send_lat -R <server_ip>
+
+The call trace looks like this:
+
+ kernel BUG at drivers/infiniband/core/iwcm.c:894!
+ invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
+ <...>
+ Workqueue: iw_cm_wq cm_work_handler [iw_cm]
+ Call Trace:
+ <TASK>
+ cm_work_handler+0x1dd/0x370 [iw_cm]
+ process_one_work+0x1e2/0x3b0
+ worker_thread+0x49/0x2e0
+ ? rescuer_thread+0x370/0x370
+ kthread+0xe5/0x110
+ ? kthread_complete_and_exit+0x20/0x20
+ ret_from_fork+0x1f/0x30
+ </TASK>
+
+Fixes: 6c52fdc244b5 ("rdma/siw: connection management")
+Link: https://lore.kernel.org/r/dae34b5fd5c2ea2bd9744812c1d2653a34a94c67.1657706960.git.chengyou@linux.alibaba.com
+Signed-off-by: Cheng Xu <chengyou@linux.alibaba.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_cm.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c
+index 17f34d584cd9..f88d2971c2c6 100644
+--- a/drivers/infiniband/sw/siw/siw_cm.c
++++ b/drivers/infiniband/sw/siw/siw_cm.c
+@@ -725,11 +725,11 @@ static int siw_proc_mpareply(struct siw_cep *cep)
+ enum mpa_v2_ctrl mpa_p2p_mode = MPA_V2_RDMA_NO_RTR;
+
+ rv = siw_recv_mpa_rr(cep);
+- if (rv != -EAGAIN)
+- siw_cancel_mpatimer(cep);
+ if (rv)
+ goto out_err;
+
++ siw_cancel_mpatimer(cep);
++
+ rep = &cep->mpa.hdr;
+
+ if (__mpa_rr_revision(rep->params.bits) > MPA_REVISION_2) {
+@@ -895,7 +895,8 @@ static int siw_proc_mpareply(struct siw_cep *cep)
+ }
+
+ out_err:
+- siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY, -EINVAL);
++ if (rv != -EAGAIN)
++ siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY, -EINVAL);
+
+ return rv;
+ }
+--
+2.35.1
+
--- /dev/null
+From 264ed6a10f1985b7931b167ef03599880da3cd05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Jul 2022 12:34:13 -0700
+Subject: RDMA/srpt: Duplicate port name members
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit b03b1ae2a3125d4475452e4f19f5d3a6e910ff6e ]
+
+Prepare for decoupling the lifetimes of struct srpt_port and struct
+srpt_port_id by duplicating the port name into struct srpt_port.
+
+Link: https://lore.kernel.org/r/20220727193415.1583860-2-bvanassche@acm.org
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/srpt/ib_srpt.c | 9 ++++++---
+ drivers/infiniband/ulp/srpt/ib_srpt.h | 10 +++++++---
+ 2 files changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
+index f86ee1c4b970..8253d55b9c26 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
+@@ -566,14 +566,17 @@ static int srpt_refresh_port(struct srpt_port *sport)
+ return ret;
+
+ sport->port_guid_id.wwn.priv = sport;
+- srpt_format_guid(sport->port_guid_id.name,
+- sizeof(sport->port_guid_id.name),
++ srpt_format_guid(sport->guid_name, ARRAY_SIZE(sport->guid_name),
+ &sport->gid.global.interface_id);
++ memcpy(sport->port_guid_id.name, sport->guid_name,
++ ARRAY_SIZE(sport->guid_name));
+ sport->port_gid_id.wwn.priv = sport;
+- snprintf(sport->port_gid_id.name, sizeof(sport->port_gid_id.name),
++ snprintf(sport->gid_name, ARRAY_SIZE(sport->gid_name),
+ "0x%016llx%016llx",
+ be64_to_cpu(sport->gid.global.subnet_prefix),
+ be64_to_cpu(sport->gid.global.interface_id));
++ memcpy(sport->port_gid_id.name, sport->gid_name,
++ ARRAY_SIZE(sport->gid_name));
+
+ if (rdma_protocol_iwarp(sport->sdev->device, sport->port))
+ return 0;
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h
+index 76e66f630c17..3844a7058559 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.h
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.h
+@@ -376,7 +376,7 @@ struct srpt_tpg {
+ };
+
+ /**
+- * struct srpt_port_id - information about an RDMA port name
++ * struct srpt_port_id - LIO RDMA port information
+ * @mutex: Protects @tpg_list changes.
+ * @tpg_list: TPGs associated with the RDMA port name.
+ * @wwn: WWN associated with the RDMA port name.
+@@ -402,8 +402,10 @@ struct srpt_port_id {
+ * @lid: cached value of the port's lid.
+ * @gid: cached value of the port's gid.
+ * @work: work structure for refreshing the aforementioned cached values.
+- * @port_guid_id: target port GUID
+- * @port_gid_id: target port GID
++ * @guid_name: port name in GUID format.
++ * @port_guid_id: LIO target port information for the port name in GUID format.
++ * @gid_name: port name in GID format.
++ * @port_gid_id: LIO target port information for the port name in GID format.
+ * @port_attrib: Port attributes that can be accessed through configfs.
+ * @refcount: Number of objects associated with this port.
+ * @freed_channels: Completion that will be signaled once @refcount becomes 0.
+@@ -419,7 +421,9 @@ struct srpt_port {
+ u32 lid;
+ union ib_gid gid;
+ struct work_struct work;
++ char guid_name[64];
+ struct srpt_port_id port_guid_id;
++ char gid_name[64];
+ struct srpt_port_id port_gid_id;
+ struct srpt_port_attrib port_attrib;
+ atomic_t refcount;
+--
+2.35.1
+
--- /dev/null
+From 9c74a33362e69384092368dbda0548e80f036a32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Jul 2022 12:34:15 -0700
+Subject: RDMA/srpt: Fix a use-after-free
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit b5605148e6ce36bb21020d49010b617693933128 ]
+
+Change the LIO port members inside struct srpt_port from regular members
+into pointers. Allocate the LIO port data structures from inside
+srpt_make_tport() and free these from inside srpt_make_tport(). Keep
+struct srpt_device as long as either an RDMA port or a LIO target port is
+associated with it. This patch decouples the lifetime of struct srpt_port
+(controlled by the RDMA core) and struct srpt_port_id (controlled by LIO).
+This patch fixes the following KASAN complaint:
+
+ BUG: KASAN: use-after-free in srpt_enable_tpg+0x31/0x70 [ib_srpt]
+ Read of size 8 at addr ffff888141cc34b8 by task check/5093
+
+ Call Trace:
+ <TASK>
+ show_stack+0x4e/0x53
+ dump_stack_lvl+0x51/0x66
+ print_address_description.constprop.0.cold+0xea/0x41e
+ print_report.cold+0x90/0x205
+ kasan_report+0xb9/0xf0
+ __asan_load8+0x69/0x90
+ srpt_enable_tpg+0x31/0x70 [ib_srpt]
+ target_fabric_tpg_base_enable_store+0xe2/0x140 [target_core_mod]
+ configfs_write_iter+0x18b/0x210
+ new_sync_write+0x1f2/0x2f0
+ vfs_write+0x3e3/0x540
+ ksys_write+0xbb/0x140
+ __x64_sys_write+0x42/0x50
+ do_syscall_64+0x34/0x80
+ entry_SYSCALL_64_after_hwframe+0x46/0xb0
+ </TASK>
+
+Link: https://lore.kernel.org/r/20220727193415.1583860-4-bvanassche@acm.org
+Reported-by: Li Zhijian <lizhijian@fujitsu.com>
+Tested-by: Li Zhijian <lizhijian@fujitsu.com>
+Fixes: a42d985bd5b2 ("ib_srpt: Initial SRP Target merge for v3.3-rc1")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/srpt/ib_srpt.c | 130 ++++++++++++++++++--------
+ drivers/infiniband/ulp/srpt/ib_srpt.h | 10 +-
+ 2 files changed, 94 insertions(+), 46 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
+index 1fbce9225424..c3036aeac89e 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
+@@ -565,18 +565,12 @@ static int srpt_refresh_port(struct srpt_port *sport)
+ if (ret)
+ return ret;
+
+- sport->port_guid_id.wwn.priv = sport;
+ srpt_format_guid(sport->guid_name, ARRAY_SIZE(sport->guid_name),
+ &sport->gid.global.interface_id);
+- memcpy(sport->port_guid_id.name, sport->guid_name,
+- ARRAY_SIZE(sport->guid_name));
+- sport->port_gid_id.wwn.priv = sport;
+ snprintf(sport->gid_name, ARRAY_SIZE(sport->gid_name),
+ "0x%016llx%016llx",
+ be64_to_cpu(sport->gid.global.subnet_prefix),
+ be64_to_cpu(sport->gid.global.interface_id));
+- memcpy(sport->port_gid_id.name, sport->gid_name,
+- ARRAY_SIZE(sport->gid_name));
+
+ if (rdma_protocol_iwarp(sport->sdev->device, sport->port))
+ return 0;
+@@ -2317,31 +2311,35 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
+ tag_num = ch->rq_size;
+ tag_size = 1; /* ib_srpt does not use se_sess->sess_cmd_map */
+
+- mutex_lock(&sport->port_guid_id.mutex);
+- list_for_each_entry(stpg, &sport->port_guid_id.tpg_list, entry) {
+- if (!IS_ERR_OR_NULL(ch->sess))
+- break;
+- ch->sess = target_setup_session(&stpg->tpg, tag_num,
++ if (sport->guid_id) {
++ mutex_lock(&sport->guid_id->mutex);
++ list_for_each_entry(stpg, &sport->guid_id->tpg_list, entry) {
++ if (!IS_ERR_OR_NULL(ch->sess))
++ break;
++ ch->sess = target_setup_session(&stpg->tpg, tag_num,
+ tag_size, TARGET_PROT_NORMAL,
+ ch->sess_name, ch, NULL);
++ }
++ mutex_unlock(&sport->guid_id->mutex);
+ }
+- mutex_unlock(&sport->port_guid_id.mutex);
+
+- mutex_lock(&sport->port_gid_id.mutex);
+- list_for_each_entry(stpg, &sport->port_gid_id.tpg_list, entry) {
+- if (!IS_ERR_OR_NULL(ch->sess))
+- break;
+- ch->sess = target_setup_session(&stpg->tpg, tag_num,
++ if (sport->gid_id) {
++ mutex_lock(&sport->gid_id->mutex);
++ list_for_each_entry(stpg, &sport->gid_id->tpg_list, entry) {
++ if (!IS_ERR_OR_NULL(ch->sess))
++ break;
++ ch->sess = target_setup_session(&stpg->tpg, tag_num,
+ tag_size, TARGET_PROT_NORMAL, i_port_id,
+ ch, NULL);
+- if (!IS_ERR_OR_NULL(ch->sess))
+- break;
+- /* Retry without leading "0x" */
+- ch->sess = target_setup_session(&stpg->tpg, tag_num,
++ if (!IS_ERR_OR_NULL(ch->sess))
++ break;
++ /* Retry without leading "0x" */
++ ch->sess = target_setup_session(&stpg->tpg, tag_num,
+ tag_size, TARGET_PROT_NORMAL,
+ i_port_id + 2, ch, NULL);
++ }
++ mutex_unlock(&sport->gid_id->mutex);
+ }
+- mutex_unlock(&sport->port_gid_id.mutex);
+
+ if (IS_ERR_OR_NULL(ch->sess)) {
+ WARN_ON_ONCE(ch->sess == NULL);
+@@ -2986,7 +2984,12 @@ static int srpt_release_sport(struct srpt_port *sport)
+ return 0;
+ }
+
+-static struct se_wwn *__srpt_lookup_wwn(const char *name)
++struct port_and_port_id {
++ struct srpt_port *sport;
++ struct srpt_port_id **port_id;
++};
++
++static struct port_and_port_id __srpt_lookup_port(const char *name)
+ {
+ struct ib_device *dev;
+ struct srpt_device *sdev;
+@@ -3001,25 +3004,38 @@ static struct se_wwn *__srpt_lookup_wwn(const char *name)
+ for (i = 0; i < dev->phys_port_cnt; i++) {
+ sport = &sdev->port[i];
+
+- if (strcmp(sport->port_guid_id.name, name) == 0)
+- return &sport->port_guid_id.wwn;
+- if (strcmp(sport->port_gid_id.name, name) == 0)
+- return &sport->port_gid_id.wwn;
++ if (strcmp(sport->guid_name, name) == 0) {
++ kref_get(&sdev->refcnt);
++ return (struct port_and_port_id){
++ sport, &sport->guid_id};
++ }
++ if (strcmp(sport->gid_name, name) == 0) {
++ kref_get(&sdev->refcnt);
++ return (struct port_and_port_id){
++ sport, &sport->gid_id};
++ }
+ }
+ }
+
+- return NULL;
++ return (struct port_and_port_id){};
+ }
+
+-static struct se_wwn *srpt_lookup_wwn(const char *name)
++/**
++ * srpt_lookup_port() - Look up an RDMA port by name
++ * @name: ASCII port name
++ *
++ * Increments the RDMA port reference count if an RDMA port pointer is returned.
++ * The caller must drop that reference count by calling srpt_port_put_ref().
++ */
++static struct port_and_port_id srpt_lookup_port(const char *name)
+ {
+- struct se_wwn *wwn;
++ struct port_and_port_id papi;
+
+ spin_lock(&srpt_dev_lock);
+- wwn = __srpt_lookup_wwn(name);
++ papi = __srpt_lookup_port(name);
+ spin_unlock(&srpt_dev_lock);
+
+- return wwn;
++ return papi;
+ }
+
+ static void srpt_free_srq(struct srpt_device *sdev)
+@@ -3198,10 +3214,6 @@ static int srpt_add_one(struct ib_device *device)
+ sport->port_attrib.srp_sq_size = DEF_SRPT_SQ_SIZE;
+ sport->port_attrib.use_srq = false;
+ INIT_WORK(&sport->work, srpt_refresh_port_work);
+- mutex_init(&sport->port_guid_id.mutex);
+- INIT_LIST_HEAD(&sport->port_guid_id.tpg_list);
+- mutex_init(&sport->port_gid_id.mutex);
+- INIT_LIST_HEAD(&sport->port_gid_id.tpg_list);
+
+ ret = srpt_refresh_port(sport);
+ if (ret) {
+@@ -3302,10 +3314,10 @@ static struct srpt_port_id *srpt_wwn_to_sport_id(struct se_wwn *wwn)
+ {
+ struct srpt_port *sport = wwn->priv;
+
+- if (wwn == &sport->port_guid_id.wwn)
+- return &sport->port_guid_id;
+- if (wwn == &sport->port_gid_id.wwn)
+- return &sport->port_gid_id;
++ if (sport->guid_id && &sport->guid_id->wwn == wwn)
++ return sport->guid_id;
++ if (sport->gid_id && &sport->gid_id->wwn == wwn)
++ return sport->gid_id;
+ WARN_ON_ONCE(true);
+ return NULL;
+ }
+@@ -3790,7 +3802,31 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf,
+ struct config_group *group,
+ const char *name)
+ {
+- return srpt_lookup_wwn(name) ? : ERR_PTR(-EINVAL);
++ struct port_and_port_id papi = srpt_lookup_port(name);
++ struct srpt_port *sport = papi.sport;
++ struct srpt_port_id *port_id;
++
++ if (!papi.port_id)
++ return ERR_PTR(-EINVAL);
++ if (*papi.port_id) {
++ /* Attempt to create a directory that already exists. */
++ WARN_ON_ONCE(true);
++ return &(*papi.port_id)->wwn;
++ }
++ port_id = kzalloc(sizeof(*port_id), GFP_KERNEL);
++ if (!port_id) {
++ srpt_sdev_put(sport->sdev);
++ return ERR_PTR(-ENOMEM);
++ }
++ mutex_init(&port_id->mutex);
++ INIT_LIST_HEAD(&port_id->tpg_list);
++ port_id->wwn.priv = sport;
++ memcpy(port_id->name, port_id == sport->guid_id ? sport->guid_name :
++ sport->gid_name, ARRAY_SIZE(port_id->name));
++
++ *papi.port_id = port_id;
++
++ return &port_id->wwn;
+ }
+
+ /**
+@@ -3799,6 +3835,18 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf,
+ */
+ static void srpt_drop_tport(struct se_wwn *wwn)
+ {
++ struct srpt_port_id *port_id = container_of(wwn, typeof(*port_id), wwn);
++ struct srpt_port *sport = wwn->priv;
++
++ if (sport->guid_id == port_id)
++ sport->guid_id = NULL;
++ else if (sport->gid_id == port_id)
++ sport->gid_id = NULL;
++ else
++ WARN_ON_ONCE(true);
++
++ srpt_sdev_put(sport->sdev);
++ kfree(port_id);
+ }
+
+ static ssize_t srpt_wwn_version_show(struct config_item *item, char *buf)
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h
+index 0cb867d580f1..4c46b301eea1 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.h
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.h
+@@ -393,7 +393,7 @@ struct srpt_port_id {
+ };
+
+ /**
+- * struct srpt_port - information associated by SRPT with a single IB port
++ * struct srpt_port - SRPT RDMA port information
+ * @sdev: backpointer to the HCA information.
+ * @mad_agent: per-port management datagram processing information.
+ * @enabled: Whether or not this target port is enabled.
+@@ -403,9 +403,9 @@ struct srpt_port_id {
+ * @gid: cached value of the port's gid.
+ * @work: work structure for refreshing the aforementioned cached values.
+ * @guid_name: port name in GUID format.
+- * @port_guid_id: LIO target port information for the port name in GUID format.
++ * @guid_id: LIO target port information for the port name in GUID format.
+ * @gid_name: port name in GID format.
+- * @port_gid_id: LIO target port information for the port name in GID format.
++ * @gid_id: LIO target port information for the port name in GID format.
+ * @port_attrib: Port attributes that can be accessed through configfs.
+ * @refcount: Number of objects associated with this port.
+ * @freed_channels: Completion that will be signaled once @refcount becomes 0.
+@@ -422,9 +422,9 @@ struct srpt_port {
+ union ib_gid gid;
+ struct work_struct work;
+ char guid_name[64];
+- struct srpt_port_id port_guid_id;
++ struct srpt_port_id *guid_id;
+ char gid_name[64];
+- struct srpt_port_id port_gid_id;
++ struct srpt_port_id *gid_id;
+ struct srpt_port_attrib port_attrib;
+ atomic_t refcount;
+ struct completion *freed_channels;
+--
+2.35.1
+
--- /dev/null
+From 341660b31751fb6320147b46e9bf4d84f83dc594 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Jul 2022 12:34:14 -0700
+Subject: RDMA/srpt: Introduce a reference count in struct srpt_device
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit aa7dfbb41b5a60ab90e244d6f586b8cb5c791c3e ]
+
+This will be used to keep struct srpt_device around as long as either the
+RDMA port exists or a LIO target port is associated with the struct
+srpt_device.
+
+Link: https://lore.kernel.org/r/20220727193415.1583860-3-bvanassche@acm.org
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/srpt/ib_srpt.c | 17 +++++++++++++++--
+ drivers/infiniband/ulp/srpt/ib_srpt.h | 2 ++
+ 2 files changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
+index 8253d55b9c26..1fbce9225424 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
+@@ -3104,6 +3104,18 @@ static int srpt_use_srq(struct srpt_device *sdev, bool use_srq)
+ return ret;
+ }
+
++static void srpt_free_sdev(struct kref *refcnt)
++{
++ struct srpt_device *sdev = container_of(refcnt, typeof(*sdev), refcnt);
++
++ kfree(sdev);
++}
++
++static void srpt_sdev_put(struct srpt_device *sdev)
++{
++ kref_put(&sdev->refcnt, srpt_free_sdev);
++}
++
+ /**
+ * srpt_add_one - InfiniBand device addition callback function
+ * @device: Describes a HCA.
+@@ -3122,6 +3134,7 @@ static int srpt_add_one(struct ib_device *device)
+ if (!sdev)
+ return -ENOMEM;
+
++ kref_init(&sdev->refcnt);
+ sdev->device = device;
+ mutex_init(&sdev->sdev_mutex);
+
+@@ -3217,7 +3230,7 @@ static int srpt_add_one(struct ib_device *device)
+ srpt_free_srq(sdev);
+ ib_dealloc_pd(sdev->pd);
+ free_dev:
+- kfree(sdev);
++ srpt_sdev_put(sdev);
+ pr_info("%s(%s) failed.\n", __func__, dev_name(&device->dev));
+ return ret;
+ }
+@@ -3261,7 +3274,7 @@ static void srpt_remove_one(struct ib_device *device, void *client_data)
+
+ ib_dealloc_pd(sdev->pd);
+
+- kfree(sdev);
++ srpt_sdev_put(sdev);
+ }
+
+ static struct ib_client srpt_client = {
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h
+index 3844a7058559..0cb867d580f1 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.h
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.h
+@@ -434,6 +434,7 @@ struct srpt_port {
+
+ /**
+ * struct srpt_device - information associated by SRPT with a single HCA
++ * @refcnt: Reference count for this device.
+ * @device: Backpointer to the struct ib_device managed by the IB core.
+ * @pd: IB protection domain.
+ * @lkey: L_Key (local key) with write access to all local memory.
+@@ -449,6 +450,7 @@ struct srpt_port {
+ * @port: Information about the ports owned by this HCA.
+ */
+ struct srpt_device {
++ struct kref refcnt;
+ struct ib_device *device;
+ struct ib_pd *pd;
+ u32 lkey;
+--
+2.35.1
+
--- /dev/null
+From f27705cb4f84220422f031d536243e1ffc8ce2e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 19:10:27 +0800
+Subject: regulator: of: Fix refcount leak bug in
+ of_get_regulation_constraints()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 66efb665cd5ad69b27dca8571bf89fc6b9c628a4 ]
+
+We should call the of_node_put() for the reference returned by
+of_get_child_by_name() which has increased the refcount.
+
+Fixes: 40e20d68bb3f ("regulator: of: Add support for parsing regulator_state for suspend state")
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220715111027.391032-1-windhl@126.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/of_regulator.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
+index f54d4f176882..e12b681c72e5 100644
+--- a/drivers/regulator/of_regulator.c
++++ b/drivers/regulator/of_regulator.c
+@@ -264,8 +264,12 @@ static int of_get_regulation_constraints(struct device *dev,
+ }
+
+ suspend_np = of_get_child_by_name(np, regulator_states[i]);
+- if (!suspend_np || !suspend_state)
++ if (!suspend_np)
+ continue;
++ if (!suspend_state) {
++ of_node_put(suspend_np);
++ continue;
++ }
+
+ if (!of_property_read_u32(suspend_np, "regulator-mode",
+ &pval)) {
+--
+2.35.1
+
--- /dev/null
+From 0be9efbc73cd5c98984faf566d207da01b203e24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jun 2022 11:46:12 +0200
+Subject: regulator: qcom_smd: Fix pm8916_pldo range
+
+From: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
+
+[ Upstream commit e8977917e116d1571dacb8e9864474551c1c12bd ]
+
+The PM8916 device specification [1] documents a programmable range of
+1.75V to 3.337V with 12.5mV steps for the PMOS LDOs in PM8916. This
+range is also used when controlling the regulator directly using the
+qcom_spmi-regulator driver ("ult_pldo" there).
+
+However, for some reason the qcom_smd-regulator driver allows a much
+larger range for the same hardware component. This could be simply a
+typo, since the start of the range is essentially just missing a '1'.
+
+In practice this does not cause any major problems, since the driver
+just sends the actual voltage to the RPM firmware instead of making use
+of the incorrect voltage selector. Still, having the wrong range there
+is confusing and prevents the regulator core from validating requests
+correctly.
+
+[1]: https://developer.qualcomm.com/download/sd410/pm8916pm8916-1-power-management-ic-device-specification.pdf
+
+Fixes: 57d6567680ed ("regulator: qcom-smd: Add PM8916 support")
+Signed-off-by: Stephan Gerhold <stephan.gerhold@kernkonzept.com>
+Link: https://lore.kernel.org/r/20220623094614.1410180-2-stephan.gerhold@kernkonzept.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/qcom_smd-regulator.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c
+index 7dff94a2eb7e..0af8286e1b10 100644
+--- a/drivers/regulator/qcom_smd-regulator.c
++++ b/drivers/regulator/qcom_smd-regulator.c
+@@ -357,10 +357,10 @@ static const struct regulator_desc pm8941_switch = {
+
+ static const struct regulator_desc pm8916_pldo = {
+ .linear_ranges = (struct linear_range[]) {
+- REGULATOR_LINEAR_RANGE(750000, 0, 208, 12500),
++ REGULATOR_LINEAR_RANGE(1750000, 0, 127, 12500),
+ },
+ .n_linear_ranges = 1,
+- .n_voltages = 209,
++ .n_voltages = 128,
+ .ops = &rpm_smps_ldo_ops,
+ };
+
+--
+2.35.1
+
--- /dev/null
+From f125b3afc7d57688eb934a8fbe8c7fba75d3e361 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 May 2022 08:55:58 +0400
+Subject: remoteproc: imx_rproc: Fix refcount leak in imx_rproc_addr_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 61afafe8b938bc74841cf4b1a73dd08b9d287c5a ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not needed anymore.
+This function has two paths missing of_node_put().
+
+Fixes: 6e962bfe56b9 ("remoteproc: imx_rproc: add missing of_node_put")
+Fixes: a0ff4aa6f010 ("remoteproc: imx_rproc: add a NXP/Freescale imx_rproc driver")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220512045558.7142-1-linmq006@gmail.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/imx_rproc.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
+index 91eb037089ef..f17bb41a6551 100644
+--- a/drivers/remoteproc/imx_rproc.c
++++ b/drivers/remoteproc/imx_rproc.c
+@@ -562,16 +562,17 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
+
+ node = of_parse_phandle(np, "memory-region", a);
+ /* Not map vdevbuffer, vdevring region */
+- if (!strncmp(node->name, "vdev", strlen("vdev")))
++ if (!strncmp(node->name, "vdev", strlen("vdev"))) {
++ of_node_put(node);
+ continue;
++ }
+ err = of_address_to_resource(node, 0, &res);
++ of_node_put(node);
+ if (err) {
+ dev_err(dev, "unable to resolve memory region\n");
+ return err;
+ }
+
+- of_node_put(node);
+-
+ if (b >= IMX_RPROC_MEM_MAX)
+ break;
+
+--
+2.35.1
+
--- /dev/null
+From 0e02b384020a691c1e1818966666b1e87b59515a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Jun 2022 12:33:34 +0400
+Subject: remoteproc: k3-r5: Fix refcount leak in k3_r5_cluster_of_init
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit fa220c05d282e7479abe08b54e3bdffd06c25e97 ]
+
+Every iteration of for_each_available_child_of_node() decrements
+the reference count of the previous node.
+When breaking early from a for_each_available_child_of_node() loop,
+we need to explicitly call of_node_put() on the child node.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 6dedbd1d5443 ("remoteproc: k3-r5: Add a remoteproc driver for R5F subsystem")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Acked-by: Suman Anna <s-anna@ti.com>
+Link: https://lore.kernel.org/r/20220605083334.23942-1-linmq006@gmail.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/ti_k3_r5_remoteproc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c b/drivers/remoteproc/ti_k3_r5_remoteproc.c
+index 4840ad906018..0481926c6975 100644
+--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
++++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
+@@ -1655,6 +1655,7 @@ static int k3_r5_cluster_of_init(struct platform_device *pdev)
+ if (!cpdev) {
+ ret = -ENODEV;
+ dev_err(dev, "could not get R5 core platform device\n");
++ of_node_put(child);
+ goto fail;
+ }
+
+@@ -1663,6 +1664,7 @@ static int k3_r5_cluster_of_init(struct platform_device *pdev)
+ dev_err(dev, "k3_r5_core_of_init failed, ret = %d\n",
+ ret);
+ put_device(&cpdev->dev);
++ of_node_put(child);
+ goto fail;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From ccf9a1a1685af480cc0a26b7b7d89d4f7a3841ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 17:38:17 +0530
+Subject: remoteproc: qcom: pas: Check if coredump is enabled
+
+From: Siddharth Gupta <sidgup@codeaurora.org>
+
+[ Upstream commit 7b6ece968fca4ec9e42d34caff7e06dc84c45717 ]
+
+Client drivers need to check if coredump is enabled for the rproc before
+continuing with coredump generation. This change adds a check in the PAS
+driver.
+
+Fixes: 8ed8485c4f05 ("remoteproc: qcom: Add capability to collect minidumps")
+Signed-off-by: Siddharth Gupta <sidgup@codeaurora.org>
+Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/1657022900-2049-5-git-send-email-quic_sibis@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_q6v5_pas.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index 1ae47cc153e5..e7765bbe17a0 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -87,6 +87,9 @@ static void adsp_minidump(struct rproc *rproc)
+ {
+ struct qcom_adsp *adsp = rproc->priv;
+
++ if (rproc->dump_conf == RPROC_COREDUMP_DISABLED)
++ return;
++
+ qcom_minidump(rproc, adsp->minidump_id);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 703bda859962c4937734ff653a487276406e4211 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 19:47:39 +0530
+Subject: remoteproc: qcom: wcnss: Fix handling of IRQs
+
+From: Sireesh Kodali <sireeshkodali1@gmail.com>
+
+[ Upstream commit bed0adac1ded4cb486ba19a3a7e730fbd9a1c9c6 ]
+
+The wcnss_get_irq function is expected to return a value > 0 in the
+event that an IRQ is succssfully obtained, but it instead returns 0.
+This causes the stop and ready IRQs to never actually be used despite
+being defined in the device-tree. This patch fixes that.
+
+Fixes: aed361adca9f ("remoteproc: qcom: Introduce WCNSS peripheral image loader")
+Signed-off-by: Sireesh Kodali <sireeshkodali1@gmail.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220526141740.15834-2-sireeshkodali1@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_wcnss.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c
+index 9a223d394087..68f37296b151 100644
+--- a/drivers/remoteproc/qcom_wcnss.c
++++ b/drivers/remoteproc/qcom_wcnss.c
+@@ -467,6 +467,7 @@ static int wcnss_request_irq(struct qcom_wcnss *wcnss,
+ irq_handler_t thread_fn)
+ {
+ int ret;
++ int irq_number;
+
+ ret = platform_get_irq_byname(pdev, name);
+ if (ret < 0 && optional) {
+@@ -477,14 +478,19 @@ static int wcnss_request_irq(struct qcom_wcnss *wcnss,
+ return ret;
+ }
+
++ irq_number = ret;
++
+ ret = devm_request_threaded_irq(&pdev->dev, ret,
+ NULL, thread_fn,
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+ "wcnss", wcnss);
+- if (ret)
++ if (ret) {
+ dev_err(&pdev->dev, "request %s IRQ failed\n", name);
++ return ret;
++ }
+
+- return ret;
++ /* Return the IRQ number if the IRQ was successfully acquired */
++ return irq_number;
+ }
+
+ static int wcnss_alloc_memory_region(struct qcom_wcnss *wcnss)
+--
+2.35.1
+
--- /dev/null
+From 854db316a3d1e4ae37f0defe5bf9b2a22eeef107 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Jul 2022 17:38:19 +0530
+Subject: remoteproc: sysmon: Wait for SSCTL service to come up
+
+From: Sibi Sankar <quic_sibis@quicinc.com>
+
+[ Upstream commit 47c04e00eff86a81cd357c3feed04c86089bcb85 ]
+
+The SSCTL service comes up after a finite time when the remote Q6 comes
+out of reset. Any graceful shutdowns requested during this period will
+be a NOP and abrupt tearing down of the glink channel might lead to pending
+transactions on the remote Q6 side and will ultimately lead to a fatal
+error. Fix this by waiting for the SSCTL service when a graceful shutdown
+is requested.
+
+Fixes: 1fb82ee806d1 ("remoteproc: qcom: Introduce sysmon")
+Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
+Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/1657022900-2049-7-git-send-email-quic_sibis@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/qcom_sysmon.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c
+index 9fca81492863..a9f04dd83ab6 100644
+--- a/drivers/remoteproc/qcom_sysmon.c
++++ b/drivers/remoteproc/qcom_sysmon.c
+@@ -41,6 +41,7 @@ struct qcom_sysmon {
+ struct completion comp;
+ struct completion ind_comp;
+ struct completion shutdown_comp;
++ struct completion ssctl_comp;
+ struct mutex lock;
+
+ bool ssr_ack;
+@@ -445,6 +446,8 @@ static int ssctl_new_server(struct qmi_handle *qmi, struct qmi_service *svc)
+
+ svc->priv = sysmon;
+
++ complete(&sysmon->ssctl_comp);
++
+ return 0;
+ }
+
+@@ -501,6 +504,7 @@ static int sysmon_start(struct rproc_subdev *subdev)
+ .ssr_event = SSCTL_SSR_EVENT_AFTER_POWERUP
+ };
+
++ reinit_completion(&sysmon->ssctl_comp);
+ mutex_lock(&sysmon->state_lock);
+ sysmon->state = SSCTL_SSR_EVENT_AFTER_POWERUP;
+ blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)&event);
+@@ -545,6 +549,11 @@ static void sysmon_stop(struct rproc_subdev *subdev, bool crashed)
+ if (crashed)
+ return;
+
++ if (sysmon->ssctl_instance) {
++ if (!wait_for_completion_timeout(&sysmon->ssctl_comp, HZ / 2))
++ dev_err(sysmon->dev, "timeout waiting for ssctl service\n");
++ }
++
+ if (sysmon->ssctl_version)
+ sysmon->shutdown_acked = ssctl_request_shutdown(sysmon);
+ else if (sysmon->ept)
+@@ -631,6 +640,7 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
+ init_completion(&sysmon->comp);
+ init_completion(&sysmon->ind_comp);
+ init_completion(&sysmon->shutdown_comp);
++ init_completion(&sysmon->ssctl_comp);
+ mutex_init(&sysmon->lock);
+ mutex_init(&sysmon->state_lock);
+
+--
+2.35.1
+
--- /dev/null
+From cba6fb93d0e0a0ebf25d0b733d4693796dd6e57b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 13:49:50 +0200
+Subject: Revert "ARM: dts: imx6qdl-apalis: Avoid underscore in node name"
+
+From: Max Krummenacher <max.krummenacher@toradex.com>
+
+[ Upstream commit 9c0919acb3fa7c1a24e384ff912f2d88f060c373 ]
+
+The STMPE MFD device binding requires the child node to have a fixed
+name, i.e. with '_', not '-'. Otherwise the stmpe_adc, stmpe_touchscreen
+drivers will not be probed.
+
+Fixes: 56086b5e804f ("ARM: dts: imx6qdl-apalis: Avoid underscore in node name")
+Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
+Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6qdl-apalis.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+index bd763bae596b..da919d0544a8 100644
+--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+@@ -315,7 +315,7 @@ stmpe811@41 {
+ /* ADC conversion time: 80 clocks */
+ st,sample-time = <4>;
+
+- stmpe_touchscreen: stmpe-touchscreen {
++ stmpe_touchscreen: stmpe_touchscreen {
+ compatible = "st,stmpe-ts";
+ /* 8 sample average control */
+ st,ave-ctrl = <3>;
+@@ -332,7 +332,7 @@ stmpe_touchscreen: stmpe-touchscreen {
+ st,touch-det-delay = <5>;
+ };
+
+- stmpe_adc: stmpe-adc {
++ stmpe_adc: stmpe_adc {
+ compatible = "st,stmpe-adc";
+ /* forbid to use ADC channels 3-0 (touch) */
+ st,norequest-mask = <0x0F>;
+--
+2.35.1
+
--- /dev/null
+From c0db8d2c51cef5bb86a0c2b05bc63b09635f505d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 May 2022 10:47:40 +0530
+Subject: riscv: spinwait: Fix hartid variable type
+
+From: Sunil V L <sunilvl@ventanamicro.com>
+
+[ Upstream commit c029e487e7c00e5594a4ae946952605db34e359b ]
+
+The hartid variable is of type int but compared with
+ULONG_MAX(INVALID_HARTID). This issue is fixed by changing
+the hartid variable type to unsigned long.
+
+Fixes: c78f94f35cf6 ("RISC-V: Use __cpu_up_stack/task_pointer only for spinwait method")
+
+Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
+Reviewed-by: Atish Patra <atishp@rivosinc.com>
+Link: https://lore.kernel.org/r/20220527051743.2829940-3-sunilvl@ventanamicro.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/cpu_ops_spinwait.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/riscv/kernel/cpu_ops_spinwait.c b/arch/riscv/kernel/cpu_ops_spinwait.c
+index c662a7cf10a4..d98d19226b5f 100644
+--- a/arch/riscv/kernel/cpu_ops_spinwait.c
++++ b/arch/riscv/kernel/cpu_ops_spinwait.c
+@@ -20,7 +20,7 @@ void *__cpu_spinwait_task_pointer[NR_CPUS] __section(".data");
+ static void cpu_update_secondary_bootdata(unsigned int cpuid,
+ struct task_struct *tidle)
+ {
+- int hartid = cpuid_to_hartid_map(cpuid);
++ unsigned long hartid = cpuid_to_hartid_map(cpuid);
+
+ /*
+ * The hartid must be less than NR_CPUS to avoid out-of-bound access
+@@ -29,7 +29,7 @@ static void cpu_update_secondary_bootdata(unsigned int cpuid,
+ * spinwait booting is not the recommended approach for any platforms
+ * booting Linux in S-mode and can be disabled in the future.
+ */
+- if (hartid == INVALID_HARTID || hartid >= NR_CPUS)
++ if (hartid == INVALID_HARTID || hartid >= (unsigned long) NR_CPUS)
+ return;
+
+ /* Make sure tidle is updated */
+--
+2.35.1
+
--- /dev/null
+From d6c7f8f38c224c1433b0152d9602316a5667ff51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 11:35:05 +0800
+Subject: rpmsg: char: Add mutex protection for rpmsg_eptdev_open()
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+[ Upstream commit abe13e9a561d6b3e82b21362c0d6dd3ecd8a5b13 ]
+
+There is no mutex protection for rpmsg_eptdev_open(),
+especially for eptdev->ept read and write operation.
+It may cause issues when multiple instances call
+rpmsg_eptdev_open() in parallel,the return state
+may be success or EBUSY.
+
+Fixes: 964e8bedd5a1 ("rpmsg: char: Return an error if device already open")
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Link: https://lore.kernel.org/r/1653104105-16779-1-git-send-email-shengjiu.wang@nxp.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rpmsg/rpmsg_char.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
+index b6183d4f62a2..4f2189111494 100644
+--- a/drivers/rpmsg/rpmsg_char.c
++++ b/drivers/rpmsg/rpmsg_char.c
+@@ -120,8 +120,11 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
+ struct rpmsg_device *rpdev = eptdev->rpdev;
+ struct device *dev = &eptdev->dev;
+
+- if (eptdev->ept)
++ mutex_lock(&eptdev->ept_lock);
++ if (eptdev->ept) {
++ mutex_unlock(&eptdev->ept_lock);
+ return -EBUSY;
++ }
+
+ get_device(dev);
+
+@@ -137,11 +140,13 @@ static int rpmsg_eptdev_open(struct inode *inode, struct file *filp)
+ if (!ept) {
+ dev_err(dev, "failed to open %s\n", eptdev->chinfo.name);
+ put_device(dev);
++ mutex_unlock(&eptdev->ept_lock);
+ return -EINVAL;
+ }
+
+ eptdev->ept = ept;
+ filp->private_data = eptdev;
++ mutex_unlock(&eptdev->ept_lock);
+
+ return 0;
+ }
+--
+2.35.1
+
--- /dev/null
+From f7df8f02e88949d1bbc88a77aef16b4ca54db4e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 11:12:01 +0200
+Subject: rpmsg: mtk_rpmsg: Fix circular locking dependency
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit 353d9214682e65c55cdffad8c82139a3321c5f13 ]
+
+During execution of the worker that's used to register rpmsg devices
+we are safely locking the channels mutex but, when creating a new
+endpoint for such devices, we are registering a IPI on the SCP, which
+then makes the SCP to trigger an interrupt, lock its own mutex and in
+turn register more subdevices.
+This creates a circular locking dependency situation, as the mtk_rpmsg
+channels_lock will then depend on the SCP IPI lock.
+
+[ 15.447736] ======================================================
+[ 15.460158] WARNING: possible circular locking dependency detected
+[ 15.460161] 5.17.0-next-20220324+ #399 Not tainted
+[ 15.460165] ------------------------------------------------------
+[ 15.460166] kworker/0:3/155 is trying to acquire lock:
+[ 15.460170] ffff5b4d0eaf1308 (&scp->ipi_desc[i].lock){+.+.}-{4:4}, at: scp_ipi_lock+0x34/0x50 [mtk_scp_ipi]
+[ 15.504958]
+[] but task is already holding lock:
+[ 15.504960] ffff5b4d0e8f1918 (&mtk_subdev->channels_lock){+.+.}-{4:4}, at: mtk_register_device_work_function+0x50/0x1cc [mtk_rpmsg]
+[ 15.504978]
+[] which lock already depends on the new lock.
+
+[ 15.504980]
+[] the existing dependency chain (in reverse order) is:
+[ 15.504982]
+[] -> #1 (&mtk_subdev->channels_lock){+.+.}-{4:4}:
+[ 15.504990] lock_acquire+0x68/0x84
+[ 15.504999] __mutex_lock+0xa4/0x3e0
+[ 15.505007] mutex_lock_nested+0x40/0x70
+[ 15.505012] mtk_rpmsg_ns_cb+0xe4/0x134 [mtk_rpmsg]
+[ 15.641684] mtk_rpmsg_ipi_handler+0x38/0x64 [mtk_rpmsg]
+[ 15.641693] scp_ipi_handler+0xbc/0x180 [mtk_scp]
+[ 15.663905] mt8192_scp_irq_handler+0x44/0xa4 [mtk_scp]
+[ 15.663915] scp_irq_handler+0x6c/0xa0 [mtk_scp]
+[ 15.685779] irq_thread_fn+0x34/0xa0
+[ 15.685785] irq_thread+0x18c/0x240
+[ 15.685789] kthread+0x104/0x110
+[ 15.709579] ret_from_fork+0x10/0x20
+[ 15.709586]
+[] -> #0 (&scp->ipi_desc[i].lock){+.+.}-{4:4}:
+[ 15.731271] __lock_acquire+0x11e4/0x1910
+[ 15.740367] lock_acquire.part.0+0xd8/0x220
+[ 15.749813] lock_acquire+0x68/0x84
+[ 15.757861] __mutex_lock+0xa4/0x3e0
+[ 15.766084] mutex_lock_nested+0x40/0x70
+[ 15.775006] scp_ipi_lock+0x34/0x50 [mtk_scp_ipi]
+[ 15.785503] scp_ipi_register+0x40/0xa4 [mtk_scp_ipi]
+[ 15.796697] scp_register_ipi+0x1c/0x30 [mtk_scp]
+[ 15.807194] mtk_rpmsg_create_ept+0xa0/0x108 [mtk_rpmsg]
+[ 15.818912] rpmsg_create_ept+0x44/0x60
+[ 15.827660] cros_ec_rpmsg_probe+0x15c/0x1f0
+[ 15.837282] rpmsg_dev_probe+0x128/0x1d0
+[ 15.846203] really_probe.part.0+0xa4/0x2a0
+[ 15.855649] __driver_probe_device+0xa0/0x150
+[ 15.865443] driver_probe_device+0x48/0x150
+[ 15.877157] __device_attach_driver+0xc0/0x12c
+[ 15.889359] bus_for_each_drv+0x80/0xe0
+[ 15.900330] __device_attach+0xe4/0x190
+[ 15.911303] device_initial_probe+0x1c/0x2c
+[ 15.922969] bus_probe_device+0xa8/0xb0
+[ 15.933927] device_add+0x3a8/0x8a0
+[ 15.944193] device_register+0x28/0x40
+[ 15.954970] rpmsg_register_device+0x5c/0xa0
+[ 15.966782] mtk_register_device_work_function+0x148/0x1cc [mtk_rpmsg]
+[ 15.983146] process_one_work+0x294/0x664
+[ 15.994458] worker_thread+0x7c/0x45c
+[ 16.005069] kthread+0x104/0x110
+[ 16.014789] ret_from_fork+0x10/0x20
+[ 16.025201]
+[] other info that might help us debug this:
+
+[ 16.047769] Possible unsafe locking scenario:
+
+[ 16.063942] CPU0 CPU1
+[ 16.075166] ---- ----
+[ 16.086376] lock(&mtk_subdev->channels_lock);
+[ 16.097592] lock(&scp->ipi_desc[i].lock);
+[ 16.113188] lock(&mtk_subdev->channels_lock);
+[ 16.129482] lock(&scp->ipi_desc[i].lock);
+[ 16.140020]
+[] *** DEADLOCK ***
+
+[ 16.158282] 4 locks held by kworker/0:3/155:
+[ 16.168978] #0: ffff5b4d00008748 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work+0x1fc/0x664
+[ 16.190017] #1: ffff80000953bdc8 ((work_completion)(&mtk_subdev->register_work)){+.+.}-{0:0}, at: process_one_work+0x1fc/0x664
+[ 16.215269] #2: ffff5b4d0e8f1918 (&mtk_subdev->channels_lock){+.+.}-{4:4}, at: mtk_register_device_work_function+0x50/0x1cc [mtk_rpmsg]
+[ 16.242131] #3: ffff5b4d05964190 (&dev->mutex){....}-{4:4}, at: __device_attach+0x44/0x190
+
+To solve this, simply unlock the channels_lock mutex before calling
+mtk_rpmsg_register_device() and relock it right after, as safety is
+still ensured by the locking mechanism that happens right after
+through SCP.
+
+Fixes: 7017996951fd ("rpmsg: add rpmsg support for mt8183 SCP.")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20220525091201.14210-1-angelogioacchino.delregno@collabora.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rpmsg/mtk_rpmsg.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/rpmsg/mtk_rpmsg.c b/drivers/rpmsg/mtk_rpmsg.c
+index 5b4404b8be4c..d1213c33da20 100644
+--- a/drivers/rpmsg/mtk_rpmsg.c
++++ b/drivers/rpmsg/mtk_rpmsg.c
+@@ -234,7 +234,9 @@ static void mtk_register_device_work_function(struct work_struct *register_work)
+ if (info->registered)
+ continue;
+
++ mutex_unlock(&subdev->channels_lock);
+ ret = mtk_rpmsg_register_device(subdev, &info->info);
++ mutex_lock(&subdev->channels_lock);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't create rpmsg_device\n");
+ continue;
+--
+2.35.1
+
--- /dev/null
+From 141cf5eea92cb0ee575374ad9cb6c86724389ba3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 16:07:37 +0400
+Subject: rpmsg: qcom_smd: Fix refcount leak in qcom_smd_parse_edge
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 65382585f067d4256ba087934f30f85c9b6984de ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when done.
+
+Fixes: 53e2822e56c7 ("rpmsg: Introduce Qualcomm SMD backend")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220511120737.57374-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rpmsg/qcom_smd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c
+index 1957b27c4cf3..f7af53891ef9 100644
+--- a/drivers/rpmsg/qcom_smd.c
++++ b/drivers/rpmsg/qcom_smd.c
+@@ -1383,6 +1383,7 @@ static int qcom_smd_parse_edge(struct device *dev,
+ }
+
+ edge->ipc_regmap = syscon_node_to_regmap(syscon_np);
++ of_node_put(syscon_np);
+ if (IS_ERR(edge->ipc_regmap)) {
+ ret = PTR_ERR(edge->ipc_regmap);
+ goto put_node;
+--
+2.35.1
+
--- /dev/null
+From 064a5c9b3f5b4942a76e80b12b7a0cd2963f6aeb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 17:12:18 +0200
+Subject: rtla: Fix double free
+
+From: Andreas Schwab <schwab@suse.de>
+
+[ Upstream commit 4f753c3be52c1d930afc0fe3169baa605dbaf611 ]
+
+Avoid double free by making trace_instance_destroy indempotent. When
+trace_instance_init fails, it calls trace_instance_destroy, but its only
+caller osnoise_destroy_tool calls it again.
+
+Link: https://lkml.kernel.org/r/mvmilnlkyzx.fsf_-_@suse.de
+
+Fixes: 0605bf009f18 ("rtla: Add osnoise tool")
+Signed-off-by: Andreas Schwab <schwab@suse.de>
+Acked-by: Daniel Bristot de Oliveira <bristot@kernel.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/tracing/rtla/src/trace.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/tools/tracing/rtla/src/trace.c b/tools/tracing/rtla/src/trace.c
+index 5784c9f9e570..e1ba6d9f4265 100644
+--- a/tools/tracing/rtla/src/trace.c
++++ b/tools/tracing/rtla/src/trace.c
+@@ -134,13 +134,18 @@ void trace_instance_destroy(struct trace_instance *trace)
+ if (trace->inst) {
+ disable_tracer(trace->inst);
+ destroy_instance(trace->inst);
++ trace->inst = NULL;
+ }
+
+- if (trace->seq)
++ if (trace->seq) {
+ free(trace->seq);
++ trace->seq = NULL;
++ }
+
+- if (trace->tep)
++ if (trace->tep) {
+ tep_free(trace->tep);
++ trace->tep = NULL;
++ }
+ }
+
+ /*
+--
+2.35.1
+
--- /dev/null
+From 7a29562a62345c9cd796b2ce0c4f523ab041a8c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 23:32:19 +0200
+Subject: rtla: Fix Makefile when called from -C tools/
+
+From: Daniel Bristot de Oliveira <bristot@kernel.org>
+
+[ Upstream commit c7d8a598c5b1e21a0957f5dec2ef4139d2d1a23a ]
+
+Sedat Dilek reported an error on rtla Makefile when running:
+
+ $ make -C tools/ clean
+ [...]
+ make[2]: Entering directory
+ '/home/dileks/src/linux-kernel/git/tools/tracing/rtla'
+ [...]
+ '/home/dileks/src/linux-kernel/git/Documentation/tools/rtla'
+ /bin/sh: 1: test: rtla-make[2]:: unexpected operator <------ The problem
+ rm: cannot remove '/home/dileks/src/linux-kernel/git': Is a directory
+ make[2]: *** [Makefile:120: clean] Error 1
+ make[2]: Leaving directory
+
+This occurred because the rtla calls kernel's Makefile to get the
+version in silence mode, e.g.,
+
+ $ make -sC ../../.. kernelversion
+ 5.19.0-rc4
+
+But the -s is being ignored when rtla's makefile is called indirectly,
+so the output looks like this:
+
+ $ make -C ../../.. kernelversion
+ make: Entering directory '/root/linux'
+ 5.19.0-rc4
+ make: Leaving directory '/root/linux'
+
+Using 'grep -v make' avoids this problem, e.g.,
+
+ $ make -C ../../.. kernelversion | grep -v make
+ 5.19.0-rc4
+
+Thus, add | grep -v make.
+
+Link: https://lkml.kernel.org/r/870c02d4d97a921f02a31fa3b229fc549af61a20.1657747763.git.bristot@kernel.org
+
+Fixes: 8619e32825fd ("rtla: Follow kernel version")
+Reported-by: Sedat Dilek <sedat.dilek@gmail.com>
+Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
+Signed-off-by: Daniel Bristot de Oliveira <bristot@kernel.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/tracing/rtla/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/tracing/rtla/Makefile b/tools/tracing/rtla/Makefile
+index 3822f4ea5f49..1bea2d16d4c1 100644
+--- a/tools/tracing/rtla/Makefile
++++ b/tools/tracing/rtla/Makefile
+@@ -1,6 +1,6 @@
+ NAME := rtla
+ # Follow the kernel version
+-VERSION := $(shell cat VERSION 2> /dev/null || make -sC ../../.. kernelversion)
++VERSION := $(shell cat VERSION 2> /dev/null || make -sC ../../.. kernelversion | grep -v make)
+
+ # From libtracefs:
+ # Makefiles suck: This macro sets a default value of $(2) for the
+--
+2.35.1
+
--- /dev/null
+From 8b9bd85fc75cc7329a607fe0d81a66eaca0b4155 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 15:33:48 +0800
+Subject: rtla/utils: Use calloc and check the potential memory allocation
+ failure
+
+From: jianchunfu <jianchunfu@cmss.chinamobile.com>
+
+[ Upstream commit b5f37a0b6f667f5c72340ca9dcd7703f261cb981 ]
+
+Replace malloc with calloc and add memory allocating check
+of mon_cpus before used.
+
+Link: https://lkml.kernel.org/r/20220615073348.6891-1-jianchunfu@cmss.chinamobile.com
+
+Fixes: 7d0dc9576dc3 ("rtla/timerlat: Add --dma-latency option")
+Signed-off-by: jianchunfu <jianchunfu@cmss.chinamobile.com>
+Acked-by: Daniel Bristot de Oliveira <bristot@kernel.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/tracing/rtla/src/utils.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c
+index 5352167a1e75..5ae2fa96fde1 100644
+--- a/tools/tracing/rtla/src/utils.c
++++ b/tools/tracing/rtla/src/utils.c
+@@ -106,8 +106,9 @@ int parse_cpu_list(char *cpu_list, char **monitored_cpus)
+
+ nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+
+- mon_cpus = malloc(nr_cpus * sizeof(char));
+- memset(mon_cpus, 0, (nr_cpus * sizeof(char)));
++ mon_cpus = calloc(nr_cpus, sizeof(char));
++ if (!mon_cpus)
++ goto err;
+
+ for (p = cpu_list; *p; ) {
+ cpu = atoi(p);
+--
+2.35.1
+
--- /dev/null
+From 4c629ba32d11d7e95d4b297da2176e4bad50c595 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 12:59:33 +0200
+Subject: s390/crash: fix incorrect number of bytes to copy to user space
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit f6749da17a34eb08c9665f072ce7c812ff68aad2 ]
+
+The number of bytes in a chunk is correctly calculated, but instead
+the total number of bytes is passed to copy_to_user_real() function.
+
+Reported-by: Matthew Wilcox <willy@infradead.org>
+Fixes: df9694c7975f ("s390/dump: streamline oldmem copy functions")
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/crash_dump.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
+index 28124d0fa1d5..f8ebdd70dd31 100644
+--- a/arch/s390/kernel/crash_dump.c
++++ b/arch/s390/kernel/crash_dump.c
+@@ -199,7 +199,7 @@ static int copy_oldmem_user(void __user *dst, unsigned long src, size_t count)
+ } else {
+ len = count;
+ }
+- rc = copy_to_user_real(dst, src, count);
++ rc = copy_to_user_real(dst, src, len);
+ if (rc)
+ return rc;
+ }
+--
+2.35.1
+
--- /dev/null
+From 4f4d1b03740c97e8ddda7e2d97d33cef1ca71de2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Jul 2022 07:24:03 +0200
+Subject: s390/smp: enforce lowcore protection on CPU restart
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit 6f5c672d17f583b081e283927f5040f726c54598 ]
+
+As result of commit 915fea04f932 ("s390/smp: enable DAT before
+CPU restart callback is called") the low-address protection bit
+gets mistakenly unset in control register 0 save area of the
+absolute zero memory. That area is used when manual PSW restart
+happened to hit an offline CPU. In this case the low-address
+protection for that CPU will be dropped.
+
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Fixes: 915fea04f932 ("s390/smp: enable DAT before CPU restart callback is called")
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/setup.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
+index 2cef49983e9e..3327412f82a6 100644
+--- a/arch/s390/kernel/setup.c
++++ b/arch/s390/kernel/setup.c
+@@ -508,8 +508,8 @@ static void __init setup_lowcore_dat_on(void)
+ S390_lowcore.svc_new_psw.mask |= PSW_MASK_DAT;
+ S390_lowcore.program_new_psw.mask |= PSW_MASK_DAT;
+ S390_lowcore.io_new_psw.mask |= PSW_MASK_DAT;
+- __ctl_store(S390_lowcore.cregs_save_area, 0, 15);
+ __ctl_set_bit(0, 28);
++ __ctl_store(S390_lowcore.cregs_save_area, 0, 15);
+ put_abs_lowcore(restart_flags, RESTART_FLAG_CTLREGS);
+ put_abs_lowcore(program_new_psw, lc->program_new_psw);
+ for (cr = 0; cr < ARRAY_SIZE(lc->cregs_save_area); cr++)
+--
+2.35.1
+
--- /dev/null
+From ebd00949b7dca9d64596201c38be150c265a2d1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 07:16:33 +0200
+Subject: s390/zcore: fix race when reading from hardware system area
+
+From: Alexander Gordeev <agordeev@linux.ibm.com>
+
+[ Upstream commit 9ffed254d938c9e99eb7761c7f739294c84e0367 ]
+
+Memory buffer used for reading out data from hardware system
+area is not protected against concurrent access.
+
+Reported-by: Matthew Wilcox <willy@infradead.org>
+Fixes: 411ed3225733 ("[S390] zfcpdump support.")
+Acked-by: Heiko Carstens <hca@linux.ibm.com>
+Tested-by: Alexander Egorenkov <egorenar@linux.ibm.com>
+Link: https://lore.kernel.org/r/e68137f0f9a0d2558f37becc20af18e2939934f6.1658206891.git.agordeev@linux.ibm.com
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/char/zcore.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
+index 516783ba950f..92b32ce645b9 100644
+--- a/drivers/s390/char/zcore.c
++++ b/drivers/s390/char/zcore.c
+@@ -50,6 +50,7 @@ static struct dentry *zcore_reipl_file;
+ static struct dentry *zcore_hsa_file;
+ static struct ipl_parameter_block *zcore_ipl_block;
+
++static DEFINE_MUTEX(hsa_buf_mutex);
+ static char hsa_buf[PAGE_SIZE] __aligned(PAGE_SIZE);
+
+ /*
+@@ -66,19 +67,24 @@ int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count)
+ if (!hsa_available)
+ return -ENODATA;
+
++ mutex_lock(&hsa_buf_mutex);
+ while (count) {
+ if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) {
+ TRACE("sclp_sdias_copy() failed\n");
++ mutex_unlock(&hsa_buf_mutex);
+ return -EIO;
+ }
+ offset = src % PAGE_SIZE;
+ bytes = min(PAGE_SIZE - offset, count);
+- if (copy_to_user(dest, hsa_buf + offset, bytes))
++ if (copy_to_user(dest, hsa_buf + offset, bytes)) {
++ mutex_unlock(&hsa_buf_mutex);
+ return -EFAULT;
++ }
+ src += bytes;
+ dest += bytes;
+ count -= bytes;
+ }
++ mutex_unlock(&hsa_buf_mutex);
+ return 0;
+ }
+
+@@ -96,9 +102,11 @@ int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
+ if (!hsa_available)
+ return -ENODATA;
+
++ mutex_lock(&hsa_buf_mutex);
+ while (count) {
+ if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) {
+ TRACE("sclp_sdias_copy() failed\n");
++ mutex_unlock(&hsa_buf_mutex);
+ return -EIO;
+ }
+ offset = src % PAGE_SIZE;
+@@ -108,6 +116,7 @@ int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
+ dest += bytes;
+ count -= bytes;
+ }
++ mutex_unlock(&hsa_buf_mutex);
+ return 0;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From cf5b90ad0be7677e4a70ba89646d320de7361bf1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 17:27:02 +0100
+Subject: sched/core: Always flush pending blk_plug
+
+From: John Keeping <john@metanate.com>
+
+[ Upstream commit 401e4963bf45c800e3e9ea0d3a0289d738005fd4 ]
+
+With CONFIG_PREEMPT_RT, it is possible to hit a deadlock between two
+normal priority tasks (SCHED_OTHER, nice level zero):
+
+ INFO: task kworker/u8:0:8 blocked for more than 491 seconds.
+ Not tainted 5.15.49-rt46 #1
+ "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+ task:kworker/u8:0 state:D stack: 0 pid: 8 ppid: 2 flags:0x00000000
+ Workqueue: writeback wb_workfn (flush-7:0)
+ [<c08a3a10>] (__schedule) from [<c08a3d84>] (schedule+0xdc/0x134)
+ [<c08a3d84>] (schedule) from [<c08a65a0>] (rt_mutex_slowlock_block.constprop.0+0xb8/0x174)
+ [<c08a65a0>] (rt_mutex_slowlock_block.constprop.0) from [<c08a6708>]
+ +(rt_mutex_slowlock.constprop.0+0xac/0x174)
+ [<c08a6708>] (rt_mutex_slowlock.constprop.0) from [<c0374d60>] (fat_write_inode+0x34/0x54)
+ [<c0374d60>] (fat_write_inode) from [<c0297304>] (__writeback_single_inode+0x354/0x3ec)
+ [<c0297304>] (__writeback_single_inode) from [<c0297998>] (writeback_sb_inodes+0x250/0x45c)
+ [<c0297998>] (writeback_sb_inodes) from [<c0297c20>] (__writeback_inodes_wb+0x7c/0xb8)
+ [<c0297c20>] (__writeback_inodes_wb) from [<c0297f24>] (wb_writeback+0x2c8/0x2e4)
+ [<c0297f24>] (wb_writeback) from [<c0298c40>] (wb_workfn+0x1a4/0x3e4)
+ [<c0298c40>] (wb_workfn) from [<c0138ab8>] (process_one_work+0x1fc/0x32c)
+ [<c0138ab8>] (process_one_work) from [<c0139120>] (worker_thread+0x22c/0x2d8)
+ [<c0139120>] (worker_thread) from [<c013e6e0>] (kthread+0x16c/0x178)
+ [<c013e6e0>] (kthread) from [<c01000fc>] (ret_from_fork+0x14/0x38)
+ Exception stack(0xc10e3fb0 to 0xc10e3ff8)
+ 3fa0: 00000000 00000000 00000000 00000000
+ 3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+ 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000
+
+ INFO: task tar:2083 blocked for more than 491 seconds.
+ Not tainted 5.15.49-rt46 #1
+ "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+ task:tar state:D stack: 0 pid: 2083 ppid: 2082 flags:0x00000000
+ [<c08a3a10>] (__schedule) from [<c08a3d84>] (schedule+0xdc/0x134)
+ [<c08a3d84>] (schedule) from [<c08a41b0>] (io_schedule+0x14/0x24)
+ [<c08a41b0>] (io_schedule) from [<c08a455c>] (bit_wait_io+0xc/0x30)
+ [<c08a455c>] (bit_wait_io) from [<c08a441c>] (__wait_on_bit_lock+0x54/0xa8)
+ [<c08a441c>] (__wait_on_bit_lock) from [<c08a44f4>] (out_of_line_wait_on_bit_lock+0x84/0xb0)
+ [<c08a44f4>] (out_of_line_wait_on_bit_lock) from [<c0371fb0>] (fat_mirror_bhs+0xa0/0x144)
+ [<c0371fb0>] (fat_mirror_bhs) from [<c0372a68>] (fat_alloc_clusters+0x138/0x2a4)
+ [<c0372a68>] (fat_alloc_clusters) from [<c0370b14>] (fat_alloc_new_dir+0x34/0x250)
+ [<c0370b14>] (fat_alloc_new_dir) from [<c03787c0>] (vfat_mkdir+0x58/0x148)
+ [<c03787c0>] (vfat_mkdir) from [<c0277b60>] (vfs_mkdir+0x68/0x98)
+ [<c0277b60>] (vfs_mkdir) from [<c027b484>] (do_mkdirat+0xb0/0xec)
+ [<c027b484>] (do_mkdirat) from [<c0100060>] (ret_fast_syscall+0x0/0x1c)
+ Exception stack(0xc2e1bfa8 to 0xc2e1bff0)
+ bfa0: 01ee42f0 01ee4208 01ee42f0 000041ed 00000000 00004000
+ bfc0: 01ee42f0 01ee4208 00000000 00000027 01ee4302 00000004 000dcb00 01ee4190
+ bfe0: 000dc368 bed11924 0006d4b0 b6ebddfc
+
+Here the kworker is waiting on msdos_sb_info::s_lock which is held by
+tar which is in turn waiting for a buffer which is locked waiting to be
+flushed, but this operation is plugged in the kworker.
+
+The lock is a normal struct mutex, so tsk_is_pi_blocked() will always
+return false on !RT and thus the behaviour changes for RT.
+
+It seems that the intent here is to skip blk_flush_plug() in the case
+where a non-preemptible lock (such as a spinlock) has been converted to
+a rtmutex on RT, which is the case covered by the SM_RTLOCK_WAIT
+schedule flag. But sched_submit_work() is only called from schedule()
+which is never called in this scenario, so the check can simply be
+deleted.
+
+Looking at the history of the -rt patchset, in fact this change was
+present from v5.9.1-rt20 until being dropped in v5.13-rt1 as it was part
+of a larger patch [1] most of which was replaced by commit b4bfa3fcfe3b
+("sched/core: Rework the __schedule() preempt argument").
+
+As described in [1]:
+
+ The schedule process must distinguish between blocking on a regular
+ sleeping lock (rwsem and mutex) and a RT-only sleeping lock (spinlock
+ and rwlock):
+ - rwsem and mutex must flush block requests (blk_schedule_flush_plug())
+ even if blocked on a lock. This can not deadlock because this also
+ happens for non-RT.
+ There should be a warning if the scheduling point is within a RCU read
+ section.
+
+ - spinlock and rwlock must not flush block requests. This will deadlock
+ if the callback attempts to acquire a lock which is already acquired.
+ Similarly to being preempted, there should be no warning if the
+ scheduling point is within a RCU read section.
+
+and with the tsk_is_pi_blocked() in the scheduler path, we hit the first
+issue.
+
+[1] https://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git/tree/patches/0022-locking-rtmutex-Use-custom-scheduling-function-for-s.patch?h=linux-5.10.y-rt-patches
+
+Signed-off-by: John Keeping <john@metanate.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Link: https://lkml.kernel.org/r/20220708162702.1758865-1-john@metanate.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sched/rt.h | 8 --------
+ kernel/sched/core.c | 8 ++++++--
+ 2 files changed, 6 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/sched/rt.h b/include/linux/sched/rt.h
+index e5af028c08b4..994c25640e15 100644
+--- a/include/linux/sched/rt.h
++++ b/include/linux/sched/rt.h
+@@ -39,20 +39,12 @@ static inline struct task_struct *rt_mutex_get_top_task(struct task_struct *p)
+ }
+ extern void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task);
+ extern void rt_mutex_adjust_pi(struct task_struct *p);
+-static inline bool tsk_is_pi_blocked(struct task_struct *tsk)
+-{
+- return tsk->pi_blocked_on != NULL;
+-}
+ #else
+ static inline struct task_struct *rt_mutex_get_top_task(struct task_struct *task)
+ {
+ return NULL;
+ }
+ # define rt_mutex_adjust_pi(p) do { } while (0)
+-static inline bool tsk_is_pi_blocked(struct task_struct *tsk)
+-{
+- return false;
+-}
+ #endif
+
+ extern void normalize_rt_tasks(void);
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index dd11daa7a84b..6baf96d2fa39 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -6460,8 +6460,12 @@ static inline void sched_submit_work(struct task_struct *tsk)
+ io_wq_worker_sleeping(tsk);
+ }
+
+- if (tsk_is_pi_blocked(tsk))
+- return;
++ /*
++ * spinlock and rwlock must not flush block requests. This will
++ * deadlock if the callback attempts to acquire a lock which is
++ * already acquired.
++ */
++ SCHED_WARN_ON(current->__state & TASK_RTLOCK_WAIT);
+
+ /*
+ * If we are going to sleep and we have plugged IO queued,
+--
+2.35.1
+
--- /dev/null
+From 8920757ce00f14226c2b2980e57fd3c07a8f8558 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Aug 2022 10:21:19 +0100
+Subject: sched/core: Do not requeue task on CPU excluded from cpus_mask
+
+From: Mel Gorman <mgorman@techsingularity.net>
+
+[ Upstream commit 751d4cbc43879229dbc124afefe240b70fd29a85 ]
+
+The following warning was triggered on a large machine early in boot on
+a distribution kernel but the same problem should also affect mainline.
+
+ WARNING: CPU: 439 PID: 10 at ../kernel/workqueue.c:2231 process_one_work+0x4d/0x440
+ Call Trace:
+ <TASK>
+ rescuer_thread+0x1f6/0x360
+ kthread+0x156/0x180
+ ret_from_fork+0x22/0x30
+ </TASK>
+
+Commit c6e7bd7afaeb ("sched/core: Optimize ttwu() spinning on p->on_cpu")
+optimises ttwu by queueing a task that is descheduling on the wakelist,
+but does not check if the task descheduling is still allowed to run on that CPU.
+
+In this warning, the problematic task is a workqueue rescue thread which
+checks if the rescue is for a per-cpu workqueue and running on the wrong CPU.
+While this is early in boot and it should be possible to create workers,
+the rescue thread may still used if the MAYDAY_INITIAL_TIMEOUT is reached
+or MAYDAY_INTERVAL and on a sufficiently large machine, the rescue
+thread is being used frequently.
+
+Tracing confirmed that the task should have migrated properly using the
+stopper thread to handle the migration. However, a parallel wakeup from udev
+running on another CPU that does not share CPU cache observes p->on_cpu and
+uses task_cpu(p), queues the task on the old CPU and triggers the warning.
+
+Check that the wakee task that is descheduling is still allowed to run
+on its current CPU and if not, wait for the descheduling to complete
+and select an allowed CPU.
+
+Fixes: c6e7bd7afaeb ("sched/core: Optimize ttwu() spinning on p->on_cpu")
+Signed-off-by: Mel Gorman <mgorman@techsingularity.net>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/20220804092119.20137-1-mgorman@techsingularity.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index df4a8c9d1070..9671796a11cc 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -3811,7 +3811,7 @@ bool cpus_share_cache(int this_cpu, int that_cpu)
+ return per_cpu(sd_llc_id, this_cpu) == per_cpu(sd_llc_id, that_cpu);
+ }
+
+-static inline bool ttwu_queue_cond(int cpu)
++static inline bool ttwu_queue_cond(struct task_struct *p, int cpu)
+ {
+ /*
+ * Do not complicate things with the async wake_list while the CPU is
+@@ -3820,6 +3820,10 @@ static inline bool ttwu_queue_cond(int cpu)
+ if (!cpu_active(cpu))
+ return false;
+
++ /* Ensure the task will still be allowed to run on the CPU. */
++ if (!cpumask_test_cpu(cpu, p->cpus_ptr))
++ return false;
++
+ /*
+ * If the CPU does not share cache, then queue the task on the
+ * remote rqs wakelist to avoid accessing remote data.
+@@ -3849,7 +3853,7 @@ static inline bool ttwu_queue_cond(int cpu)
+
+ static bool ttwu_queue_wakelist(struct task_struct *p, int cpu, int wake_flags)
+ {
+- if (sched_feat(TTWU_QUEUE) && ttwu_queue_cond(cpu)) {
++ if (sched_feat(TTWU_QUEUE) && ttwu_queue_cond(p, cpu)) {
+ sched_clock_cpu(cpu); /* Sync clocks across CPUs */
+ __ttwu_queue_wakelist(p, cpu, wake_flags);
+ return true;
+--
+2.35.1
+
--- /dev/null
+From 91da80d8288b563c9032f71c5d6a91b49d60b6fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 21:54:51 -0400
+Subject: sched, cpuset: Fix dl_cpu_busy() panic due to empty cs->cpus_allowed
+
+From: Waiman Long <longman@redhat.com>
+
+[ Upstream commit b6e8d40d43ae4dec00c8fea2593eeea3114b8f44 ]
+
+With cgroup v2, the cpuset's cpus_allowed mask can be empty indicating
+that the cpuset will just use the effective CPUs of its parent. So
+cpuset_can_attach() can call task_can_attach() with an empty mask.
+This can lead to cpumask_any_and() returns nr_cpu_ids causing the call
+to dl_bw_of() to crash due to percpu value access of an out of bound
+CPU value. For example:
+
+ [80468.182258] BUG: unable to handle page fault for address: ffffffff8b6648b0
+ :
+ [80468.191019] RIP: 0010:dl_cpu_busy+0x30/0x2b0
+ :
+ [80468.207946] Call Trace:
+ [80468.208947] cpuset_can_attach+0xa0/0x140
+ [80468.209953] cgroup_migrate_execute+0x8c/0x490
+ [80468.210931] cgroup_update_dfl_csses+0x254/0x270
+ [80468.211898] cgroup_subtree_control_write+0x322/0x400
+ [80468.212854] kernfs_fop_write_iter+0x11c/0x1b0
+ [80468.213777] new_sync_write+0x11f/0x1b0
+ [80468.214689] vfs_write+0x1eb/0x280
+ [80468.215592] ksys_write+0x5f/0xe0
+ [80468.216463] do_syscall_64+0x5c/0x80
+ [80468.224287] entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Fix that by using effective_cpus instead. For cgroup v1, effective_cpus
+is the same as cpus_allowed. For v2, effective_cpus is the real cpumask
+to be used by tasks within the cpuset anyway.
+
+Also update task_can_attach()'s 2nd argument name to cs_effective_cpus to
+reflect the change. In addition, a check is added to task_can_attach()
+to guard against the possibility that cpumask_any_and() may return a
+value >= nr_cpu_ids.
+
+Fixes: 7f51412a415d ("sched/deadline: Fix bandwidth check/update when migrating tasks between exclusive cpusets")
+Signed-off-by: Waiman Long <longman@redhat.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Juri Lelli <juri.lelli@redhat.com>
+Link: https://lore.kernel.org/r/20220803015451.2219567-1-longman@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sched.h | 2 +-
+ kernel/cgroup/cpuset.c | 2 +-
+ kernel/sched/core.c | 8 +++++---
+ 3 files changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index a8911b1f35aa..d438e39fffe5 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -1812,7 +1812,7 @@ current_restore_flags(unsigned long orig_flags, unsigned long flags)
+ }
+
+ extern int cpuset_cpumask_can_shrink(const struct cpumask *cur, const struct cpumask *trial);
+-extern int task_can_attach(struct task_struct *p, const struct cpumask *cs_cpus_allowed);
++extern int task_can_attach(struct task_struct *p, const struct cpumask *cs_effective_cpus);
+ #ifdef CONFIG_SMP
+ extern void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask);
+ extern int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask);
+diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
+index 71a418858a5e..58aadfda9b8b 100644
+--- a/kernel/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -2239,7 +2239,7 @@ static int cpuset_can_attach(struct cgroup_taskset *tset)
+ goto out_unlock;
+
+ cgroup_taskset_for_each(task, css, tset) {
+- ret = task_can_attach(task, cs->cpus_allowed);
++ ret = task_can_attach(task, cs->effective_cpus);
+ if (ret)
+ goto out_unlock;
+ ret = security_task_setscheduler(task);
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 72b2f277b0dd..b0f3ded147cb 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -8899,7 +8899,7 @@ int cpuset_cpumask_can_shrink(const struct cpumask *cur,
+ }
+
+ int task_can_attach(struct task_struct *p,
+- const struct cpumask *cs_cpus_allowed)
++ const struct cpumask *cs_effective_cpus)
+ {
+ int ret = 0;
+
+@@ -8918,9 +8918,11 @@ int task_can_attach(struct task_struct *p,
+ }
+
+ if (dl_task(p) && !cpumask_intersects(task_rq(p)->rd->span,
+- cs_cpus_allowed)) {
+- int cpu = cpumask_any_and(cpu_active_mask, cs_cpus_allowed);
++ cs_effective_cpus)) {
++ int cpu = cpumask_any_and(cpu_active_mask, cs_effective_cpus);
+
++ if (unlikely(cpu >= nr_cpu_ids))
++ return -EINVAL;
+ ret = dl_cpu_busy(cpu, p);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From e4e7f9e868682b922fb95f0f189e4072d8014c63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 17:44:01 +0200
+Subject: sched/fair: fix case with reduced capacity CPU
+
+From: Vincent Guittot <vincent.guittot@linaro.org>
+
+[ Upstream commit c82a69629c53eda5233f13fc11c3c01585ef48a2 ]
+
+The capacity of the CPU available for CFS tasks can be reduced because of
+other activities running on the latter. In such case, it's worth trying to
+move CFS tasks on a CPU with more available capacity.
+
+The rework of the load balance has filtered the case when the CPU is
+classified to be fully busy but its capacity is reduced.
+
+Check if CPU's capacity is reduced while gathering load balance statistic
+and classify it group_misfit_task instead of group_fully_busy so we can
+try to move the load on another CPU.
+
+Reported-by: David Chen <david.chen@nutanix.com>
+Reported-by: Zhang Qiao <zhangqiao22@huawei.com>
+Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: David Chen <david.chen@nutanix.com>
+Tested-by: Zhang Qiao <zhangqiao22@huawei.com>
+Link: https://lkml.kernel.org/r/20220708154401.21411-1-vincent.guittot@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 54 +++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 42 insertions(+), 12 deletions(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index ef2d8690fe18..46f6674a0979 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -7628,8 +7628,8 @@ enum group_type {
+ */
+ group_fully_busy,
+ /*
+- * SD_ASYM_CPUCAPACITY only: One task doesn't fit with CPU's capacity
+- * and must be migrated to a more powerful CPU.
++ * One task doesn't fit with CPU's capacity and must be migrated to a
++ * more powerful CPU.
+ */
+ group_misfit_task,
+ /*
+@@ -8712,6 +8712,19 @@ sched_asym(struct lb_env *env, struct sd_lb_stats *sds, struct sg_lb_stats *sgs
+ return sched_asym_prefer(env->dst_cpu, group->asym_prefer_cpu);
+ }
+
++static inline bool
++sched_reduced_capacity(struct rq *rq, struct sched_domain *sd)
++{
++ /*
++ * When there is more than 1 task, the group_overloaded case already
++ * takes care of cpu with reduced capacity
++ */
++ if (rq->cfs.h_nr_running != 1)
++ return false;
++
++ return check_cpu_capacity(rq, sd);
++}
++
+ /**
+ * update_sg_lb_stats - Update sched_group's statistics for load balancing.
+ * @env: The load balancing environment.
+@@ -8734,8 +8747,9 @@ static inline void update_sg_lb_stats(struct lb_env *env,
+
+ for_each_cpu_and(i, sched_group_span(group), env->cpus) {
+ struct rq *rq = cpu_rq(i);
++ unsigned long load = cpu_load(rq);
+
+- sgs->group_load += cpu_load(rq);
++ sgs->group_load += load;
+ sgs->group_util += cpu_util_cfs(i);
+ sgs->group_runnable += cpu_runnable(rq);
+ sgs->sum_h_nr_running += rq->cfs.h_nr_running;
+@@ -8765,11 +8779,17 @@ static inline void update_sg_lb_stats(struct lb_env *env,
+ if (local_group)
+ continue;
+
+- /* Check for a misfit task on the cpu */
+- if (env->sd->flags & SD_ASYM_CPUCAPACITY &&
+- sgs->group_misfit_task_load < rq->misfit_task_load) {
+- sgs->group_misfit_task_load = rq->misfit_task_load;
+- *sg_status |= SG_OVERLOAD;
++ if (env->sd->flags & SD_ASYM_CPUCAPACITY) {
++ /* Check for a misfit task on the cpu */
++ if (sgs->group_misfit_task_load < rq->misfit_task_load) {
++ sgs->group_misfit_task_load = rq->misfit_task_load;
++ *sg_status |= SG_OVERLOAD;
++ }
++ } else if ((env->idle != CPU_NOT_IDLE) &&
++ sched_reduced_capacity(rq, env->sd)) {
++ /* Check for a task running on a CPU with reduced capacity */
++ if (sgs->group_misfit_task_load < load)
++ sgs->group_misfit_task_load = load;
+ }
+ }
+
+@@ -8822,7 +8842,8 @@ static bool update_sd_pick_busiest(struct lb_env *env,
+ * CPUs in the group should either be possible to resolve
+ * internally or be covered by avg_load imbalance (eventually).
+ */
+- if (sgs->group_type == group_misfit_task &&
++ if ((env->sd->flags & SD_ASYM_CPUCAPACITY) &&
++ (sgs->group_type == group_misfit_task) &&
+ (!capacity_greater(capacity_of(env->dst_cpu), sg->sgc->max_capacity) ||
+ sds->local_stat.group_type != group_has_spare))
+ return false;
+@@ -9443,9 +9464,18 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s
+ busiest = &sds->busiest_stat;
+
+ if (busiest->group_type == group_misfit_task) {
+- /* Set imbalance to allow misfit tasks to be balanced. */
+- env->migration_type = migrate_misfit;
+- env->imbalance = 1;
++ if (env->sd->flags & SD_ASYM_CPUCAPACITY) {
++ /* Set imbalance to allow misfit tasks to be balanced. */
++ env->migration_type = migrate_misfit;
++ env->imbalance = 1;
++ } else {
++ /*
++ * Set load imbalance to allow moving task from cpu
++ * with reduced capacity.
++ */
++ env->migration_type = migrate_load;
++ env->imbalance = busiest->group_misfit_task_load;
++ }
+ return;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 1d93856d2248ba899de8d7c4a64432054c39023b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 00:34:28 +0800
+Subject: sched/fair: Introduce SIS_UTIL to search idle CPU based on sum of
+ util_avg
+
+From: Chen Yu <yu.c.chen@intel.com>
+
+[ Upstream commit 70fb5ccf2ebb09a0c8ebba775041567812d45f86 ]
+
+[Problem Statement]
+select_idle_cpu() might spend too much time searching for an idle CPU,
+when the system is overloaded.
+
+The following histogram is the time spent in select_idle_cpu(),
+when running 224 instances of netperf on a system with 112 CPUs
+per LLC domain:
+
+@usecs:
+[0] 533 | |
+[1] 5495 | |
+[2, 4) 12008 | |
+[4, 8) 239252 | |
+[8, 16) 4041924 |@@@@@@@@@@@@@@ |
+[16, 32) 12357398 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
+[32, 64) 14820255 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
+[64, 128) 13047682 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
+[128, 256) 8235013 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
+[256, 512) 4507667 |@@@@@@@@@@@@@@@ |
+[512, 1K) 2600472 |@@@@@@@@@ |
+[1K, 2K) 927912 |@@@ |
+[2K, 4K) 218720 | |
+[4K, 8K) 98161 | |
+[8K, 16K) 37722 | |
+[16K, 32K) 6715 | |
+[32K, 64K) 477 | |
+[64K, 128K) 7 | |
+
+netperf latency usecs:
+=======
+case load Lat_99th std%
+TCP_RR thread-224 257.39 ( 0.21)
+
+The time spent in select_idle_cpu() is visible to netperf and might have a negative
+impact.
+
+[Symptom analysis]
+The patch [1] from Mel Gorman has been applied to track the efficiency
+of select_idle_sibling. Copy the indicators here:
+
+SIS Search Efficiency(se_eff%):
+ A ratio expressed as a percentage of runqueues scanned versus
+ idle CPUs found. A 100% efficiency indicates that the target,
+ prev or recent CPU of a task was idle at wakeup. The lower the
+ efficiency, the more runqueues were scanned before an idle CPU
+ was found.
+
+SIS Domain Search Efficiency(dom_eff%):
+ Similar, except only for the slower SIS
+ patch.
+
+SIS Fast Success Rate(fast_rate%):
+ Percentage of SIS that used target, prev or
+ recent CPUs.
+
+SIS Success rate(success_rate%):
+ Percentage of scans that found an idle CPU.
+
+The test is based on Aubrey's schedtests tool, including netperf, hackbench,
+schbench and tbench.
+
+Test on vanilla kernel:
+schedstat_parse.py -f netperf_vanilla.log
+case load se_eff% dom_eff% fast_rate% success_rate%
+TCP_RR 28 threads 99.978 18.535 99.995 100.000
+TCP_RR 56 threads 99.397 5.671 99.964 100.000
+TCP_RR 84 threads 21.721 6.818 73.632 100.000
+TCP_RR 112 threads 12.500 5.533 59.000 100.000
+TCP_RR 140 threads 8.524 4.535 49.020 100.000
+TCP_RR 168 threads 6.438 3.945 40.309 99.999
+TCP_RR 196 threads 5.397 3.718 32.320 99.982
+TCP_RR 224 threads 4.874 3.661 25.775 99.767
+UDP_RR 28 threads 99.988 17.704 99.997 100.000
+UDP_RR 56 threads 99.528 5.977 99.970 100.000
+UDP_RR 84 threads 24.219 6.992 76.479 100.000
+UDP_RR 112 threads 13.907 5.706 62.538 100.000
+UDP_RR 140 threads 9.408 4.699 52.519 100.000
+UDP_RR 168 threads 7.095 4.077 44.352 100.000
+UDP_RR 196 threads 5.757 3.775 35.764 99.991
+UDP_RR 224 threads 5.124 3.704 28.748 99.860
+
+schedstat_parse.py -f schbench_vanilla.log
+(each group has 28 tasks)
+case load se_eff% dom_eff% fast_rate% success_rate%
+normal 1 mthread 99.152 6.400 99.941 100.000
+normal 2 mthreads 97.844 4.003 99.908 100.000
+normal 3 mthreads 96.395 2.118 99.917 99.998
+normal 4 mthreads 55.288 1.451 98.615 99.804
+normal 5 mthreads 7.004 1.870 45.597 61.036
+normal 6 mthreads 3.354 1.346 20.777 34.230
+normal 7 mthreads 2.183 1.028 11.257 21.055
+normal 8 mthreads 1.653 0.825 7.849 15.549
+
+schedstat_parse.py -f hackbench_vanilla.log
+(each group has 28 tasks)
+case load se_eff% dom_eff% fast_rate% success_rate%
+process-pipe 1 group 99.991 7.692 99.999 100.000
+process-pipe 2 groups 99.934 4.615 99.997 100.000
+process-pipe 3 groups 99.597 3.198 99.987 100.000
+process-pipe 4 groups 98.378 2.464 99.958 100.000
+process-pipe 5 groups 27.474 3.653 89.811 99.800
+process-pipe 6 groups 20.201 4.098 82.763 99.570
+process-pipe 7 groups 16.423 4.156 77.398 99.316
+process-pipe 8 groups 13.165 3.920 72.232 98.828
+process-sockets 1 group 99.977 5.882 99.999 100.000
+process-sockets 2 groups 99.927 5.505 99.996 100.000
+process-sockets 3 groups 99.397 3.250 99.980 100.000
+process-sockets 4 groups 79.680 4.258 98.864 99.998
+process-sockets 5 groups 7.673 2.503 63.659 92.115
+process-sockets 6 groups 4.642 1.584 58.946 88.048
+process-sockets 7 groups 3.493 1.379 49.816 81.164
+process-sockets 8 groups 3.015 1.407 40.845 75.500
+threads-pipe 1 group 99.997 0.000 100.000 100.000
+threads-pipe 2 groups 99.894 2.932 99.997 100.000
+threads-pipe 3 groups 99.611 4.117 99.983 100.000
+threads-pipe 4 groups 97.703 2.624 99.937 100.000
+threads-pipe 5 groups 22.919 3.623 87.150 99.764
+threads-pipe 6 groups 18.016 4.038 80.491 99.557
+threads-pipe 7 groups 14.663 3.991 75.239 99.247
+threads-pipe 8 groups 12.242 3.808 70.651 98.644
+threads-sockets 1 group 99.990 6.667 99.999 100.000
+threads-sockets 2 groups 99.940 5.114 99.997 100.000
+threads-sockets 3 groups 99.469 4.115 99.977 100.000
+threads-sockets 4 groups 87.528 4.038 99.400 100.000
+threads-sockets 5 groups 6.942 2.398 59.244 88.337
+threads-sockets 6 groups 4.359 1.954 49.448 87.860
+threads-sockets 7 groups 2.845 1.345 41.198 77.102
+threads-sockets 8 groups 2.871 1.404 38.512 74.312
+
+schedstat_parse.py -f tbench_vanilla.log
+case load se_eff% dom_eff% fast_rate% success_rate%
+loopback 28 threads 99.976 18.369 99.995 100.000
+loopback 56 threads 99.222 7.799 99.934 100.000
+loopback 84 threads 19.723 6.819 70.215 100.000
+loopback 112 threads 11.283 5.371 55.371 99.999
+loopback 140 threads 0.000 0.000 0.000 0.000
+loopback 168 threads 0.000 0.000 0.000 0.000
+loopback 196 threads 0.000 0.000 0.000 0.000
+loopback 224 threads 0.000 0.000 0.000 0.000
+
+According to the test above, if the system becomes busy, the
+SIS Search Efficiency(se_eff%) drops significantly. Although some
+benchmarks would finally find an idle CPU(success_rate% = 100%), it is
+doubtful whether it is worth it to search the whole LLC domain.
+
+[Proposal]
+It would be ideal to have a crystal ball to answer this question:
+How many CPUs must a wakeup path walk down, before it can find an idle
+CPU? Many potential metrics could be used to predict the number.
+One candidate is the sum of util_avg in this LLC domain. The benefit
+of choosing util_avg is that it is a metric of accumulated historic
+activity, which seems to be smoother than instantaneous metrics
+(such as rq->nr_running). Besides, choosing the sum of util_avg
+would help predict the load of the LLC domain more precisely, because
+SIS_PROP uses one CPU's idle time to estimate the total LLC domain idle
+time.
+
+In summary, the lower the util_avg is, the more select_idle_cpu()
+should scan for idle CPU, and vice versa. When the sum of util_avg
+in this LLC domain hits 85% or above, the scan stops. The reason to
+choose 85% as the threshold is that this is the imbalance_pct(117)
+when a LLC sched group is overloaded.
+
+Introduce the quadratic function:
+
+y = SCHED_CAPACITY_SCALE - p * x^2
+and y'= y / SCHED_CAPACITY_SCALE
+
+x is the ratio of sum_util compared to the CPU capacity:
+x = sum_util / (llc_weight * SCHED_CAPACITY_SCALE)
+y' is the ratio of CPUs to be scanned in the LLC domain,
+and the number of CPUs to scan is calculated by:
+
+nr_scan = llc_weight * y'
+
+Choosing quadratic function is because:
+[1] Compared to the linear function, it scans more aggressively when the
+ sum_util is low.
+[2] Compared to the exponential function, it is easier to calculate.
+[3] It seems that there is no accurate mapping between the sum of util_avg
+ and the number of CPUs to be scanned. Use heuristic scan for now.
+
+For a platform with 112 CPUs per LLC, the number of CPUs to scan is:
+sum_util% 0 5 15 25 35 45 55 65 75 85 86 ...
+scan_nr 112 111 108 102 93 81 65 47 25 1 0 ...
+
+For a platform with 16 CPUs per LLC, the number of CPUs to scan is:
+sum_util% 0 5 15 25 35 45 55 65 75 85 86 ...
+scan_nr 16 15 15 14 13 11 9 6 3 0 0 ...
+
+Furthermore, to minimize the overhead of calculating the metrics in
+select_idle_cpu(), borrow the statistics from periodic load balance.
+As mentioned by Abel, on a platform with 112 CPUs per LLC, the
+sum_util calculated by periodic load balance after 112 ms would
+decay to about 0.5 * 0.5 * 0.5 * 0.7 = 8.75%, thus bringing a delay
+in reflecting the latest utilization. But it is a trade-off.
+Checking the util_avg in newidle load balance would be more frequent,
+but it brings overhead - multiple CPUs write/read the per-LLC shared
+variable and introduces cache contention. Tim also mentioned that,
+it is allowed to be non-optimal in terms of scheduling for the
+short-term variations, but if there is a long-term trend in the load
+behavior, the scheduler can adjust for that.
+
+When SIS_UTIL is enabled, the select_idle_cpu() uses the nr_scan
+calculated by SIS_UTIL instead of the one from SIS_PROP. As Peter and
+Mel suggested, SIS_UTIL should be enabled by default.
+
+This patch is based on the util_avg, which is very sensitive to the
+CPU frequency invariance. There is an issue that, when the max frequency
+has been clamp, the util_avg would decay insanely fast when
+the CPU is idle. Commit addca285120b ("cpufreq: intel_pstate: Handle no_turbo
+in frequency invariance") could be used to mitigate this symptom, by adjusting
+the arch_max_freq_ratio when turbo is disabled. But this issue is still
+not thoroughly fixed, because the current code is unaware of the user-specified
+max CPU frequency.
+
+[Test result]
+
+netperf and tbench were launched with 25% 50% 75% 100% 125% 150%
+175% 200% of CPU number respectively. Hackbench and schbench were launched
+by 1, 2 ,4, 8 groups. Each test lasts for 100 seconds and repeats 3 times.
+
+The following is the benchmark result comparison between
+baseline:vanilla v5.19-rc1 and compare:patched kernel. Positive compare%
+indicates better performance.
+
+Each netperf test is a:
+netperf -4 -H 127.0.1 -t TCP/UDP_RR -c -C -l 100
+netperf.throughput
+=======
+case load baseline(std%) compare%( std%)
+TCP_RR 28 threads 1.00 ( 0.34) -0.16 ( 0.40)
+TCP_RR 56 threads 1.00 ( 0.19) -0.02 ( 0.20)
+TCP_RR 84 threads 1.00 ( 0.39) -0.47 ( 0.40)
+TCP_RR 112 threads 1.00 ( 0.21) -0.66 ( 0.22)
+TCP_RR 140 threads 1.00 ( 0.19) -0.69 ( 0.19)
+TCP_RR 168 threads 1.00 ( 0.18) -0.48 ( 0.18)
+TCP_RR 196 threads 1.00 ( 0.16) +194.70 ( 16.43)
+TCP_RR 224 threads 1.00 ( 0.16) +197.30 ( 7.85)
+UDP_RR 28 threads 1.00 ( 0.37) +0.35 ( 0.33)
+UDP_RR 56 threads 1.00 ( 11.18) -0.32 ( 0.21)
+UDP_RR 84 threads 1.00 ( 1.46) -0.98 ( 0.32)
+UDP_RR 112 threads 1.00 ( 28.85) -2.48 ( 19.61)
+UDP_RR 140 threads 1.00 ( 0.70) -0.71 ( 14.04)
+UDP_RR 168 threads 1.00 ( 14.33) -0.26 ( 11.16)
+UDP_RR 196 threads 1.00 ( 12.92) +186.92 ( 20.93)
+UDP_RR 224 threads 1.00 ( 11.74) +196.79 ( 18.62)
+
+Take the 224 threads as an example, the SIS search metrics changes are
+illustrated below:
+
+ vanilla patched
+ 4544492 +237.5% 15338634 sched_debug.cpu.sis_domain_search.avg
+ 38539 +39686.8% 15333634 sched_debug.cpu.sis_failed.avg
+ 128300000 -87.9% 15551326 sched_debug.cpu.sis_scanned.avg
+ 5842896 +162.7% 15347978 sched_debug.cpu.sis_search.avg
+
+There is -87.9% less CPU scans after patched, which indicates lower overhead.
+Besides, with this patch applied, there is -13% less rq lock contention
+in perf-profile.calltrace.cycles-pp._raw_spin_lock.raw_spin_rq_lock_nested
+.try_to_wake_up.default_wake_function.woken_wake_function.
+This might help explain the performance improvement - Because this patch allows
+the waking task to remain on the previous CPU, rather than grabbing other CPUs'
+lock.
+
+Each hackbench test is a:
+hackbench -g $job --process/threads --pipe/sockets -l 1000000 -s 100
+hackbench.throughput
+=========
+case load baseline(std%) compare%( std%)
+process-pipe 1 group 1.00 ( 1.29) +0.57 ( 0.47)
+process-pipe 2 groups 1.00 ( 0.27) +0.77 ( 0.81)
+process-pipe 4 groups 1.00 ( 0.26) +1.17 ( 0.02)
+process-pipe 8 groups 1.00 ( 0.15) -4.79 ( 0.02)
+process-sockets 1 group 1.00 ( 0.63) -0.92 ( 0.13)
+process-sockets 2 groups 1.00 ( 0.03) -0.83 ( 0.14)
+process-sockets 4 groups 1.00 ( 0.40) +5.20 ( 0.26)
+process-sockets 8 groups 1.00 ( 0.04) +3.52 ( 0.03)
+threads-pipe 1 group 1.00 ( 1.28) +0.07 ( 0.14)
+threads-pipe 2 groups 1.00 ( 0.22) -0.49 ( 0.74)
+threads-pipe 4 groups 1.00 ( 0.05) +1.88 ( 0.13)
+threads-pipe 8 groups 1.00 ( 0.09) -4.90 ( 0.06)
+threads-sockets 1 group 1.00 ( 0.25) -0.70 ( 0.53)
+threads-sockets 2 groups 1.00 ( 0.10) -0.63 ( 0.26)
+threads-sockets 4 groups 1.00 ( 0.19) +11.92 ( 0.24)
+threads-sockets 8 groups 1.00 ( 0.08) +4.31 ( 0.11)
+
+Each tbench test is a:
+tbench -t 100 $job 127.0.0.1
+tbench.throughput
+======
+case load baseline(std%) compare%( std%)
+loopback 28 threads 1.00 ( 0.06) -0.14 ( 0.09)
+loopback 56 threads 1.00 ( 0.03) -0.04 ( 0.17)
+loopback 84 threads 1.00 ( 0.05) +0.36 ( 0.13)
+loopback 112 threads 1.00 ( 0.03) +0.51 ( 0.03)
+loopback 140 threads 1.00 ( 0.02) -1.67 ( 0.19)
+loopback 168 threads 1.00 ( 0.38) +1.27 ( 0.27)
+loopback 196 threads 1.00 ( 0.11) +1.34 ( 0.17)
+loopback 224 threads 1.00 ( 0.11) +1.67 ( 0.22)
+
+Each schbench test is a:
+schbench -m $job -t 28 -r 100 -s 30000 -c 30000
+schbench.latency_90%_us
+========
+case load baseline(std%) compare%( std%)
+normal 1 mthread 1.00 ( 31.22) -7.36 ( 20.25)*
+normal 2 mthreads 1.00 ( 2.45) -0.48 ( 1.79)
+normal 4 mthreads 1.00 ( 1.69) +0.45 ( 0.64)
+normal 8 mthreads 1.00 ( 5.47) +9.81 ( 14.28)
+
+*Consider the Standard Deviation, this -7.36% regression might not be valid.
+
+Also, a OLTP workload with a commercial RDBMS has been tested, and there
+is no significant change.
+
+There were concerns that unbalanced tasks among CPUs would cause problems.
+For example, suppose the LLC domain is composed of 8 CPUs, and 7 tasks are
+bound to CPU0~CPU6, while CPU7 is idle:
+
+ CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
+util_avg 1024 1024 1024 1024 1024 1024 1024 0
+
+Since the util_avg ratio is 87.5%( = 7/8 ), which is higher than 85%,
+select_idle_cpu() will not scan, thus CPU7 is undetected during scan.
+But according to Mel, it is unlikely the CPU7 will be idle all the time
+because CPU7 could pull some tasks via CPU_NEWLY_IDLE.
+
+lkp(kernel test robot) has reported a regression on stress-ng.sock on a
+very busy system. According to the sched_debug statistics, it might be caused
+by SIS_UTIL terminates the scan and chooses a previous CPU earlier, and this
+might introduce more context switch, especially involuntary preemption, which
+impacts a busy stress-ng. This regression has shown that, not all benchmarks
+in every scenario benefit from idle CPU scan limit, and it needs further
+investigation.
+
+Besides, there is slight regression in hackbench's 16 groups case when the
+LLC domain has 16 CPUs. Prateek mentioned that we should scan aggressively
+in an LLC domain with 16 CPUs. Because the cost to search for an idle one
+among 16 CPUs is negligible. The current patch aims to propose a generic
+solution and only considers the util_avg. Something like the below could
+be applied on top of the current patch to fulfill the requirement:
+
+ if (llc_weight <= 16)
+ nr_scan = nr_scan * 32 / llc_weight;
+
+For LLC domain with 16 CPUs, the nr_scan will be expanded to 2 times large.
+The smaller the CPU number this LLC domain has, the larger nr_scan will be
+expanded. This needs further investigation.
+
+There is also ongoing work[2] from Abel to filter out the busy CPUs during
+wakeup, to further speed up the idle CPU scan. And it could be a following-up
+optimization on top of this change.
+
+Suggested-by: Tim Chen <tim.c.chen@intel.com>
+Suggested-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Chen Yu <yu.c.chen@intel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Yicong Yang <yangyicong@hisilicon.com>
+Tested-by: Mohini Narkhede <mohini.narkhede@intel.com>
+Tested-by: K Prateek Nayak <kprateek.nayak@amd.com>
+Link: https://lore.kernel.org/r/20220612163428.849378-1-yu.c.chen@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sched/topology.h | 1 +
+ kernel/sched/fair.c | 87 ++++++++++++++++++++++++++++++++++
+ kernel/sched/features.h | 3 +-
+ 3 files changed, 90 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h
+index 56cffe42abbc..816df6cc444e 100644
+--- a/include/linux/sched/topology.h
++++ b/include/linux/sched/topology.h
+@@ -81,6 +81,7 @@ struct sched_domain_shared {
+ atomic_t ref;
+ atomic_t nr_busy_cpus;
+ int has_idle_cores;
++ int nr_idle_scan;
+ };
+
+ struct sched_domain {
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index cc8daa3dcc8b..ef2d8690fe18 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -6324,6 +6324,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool
+ {
+ struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
+ int i, cpu, idle_cpu = -1, nr = INT_MAX;
++ struct sched_domain_shared *sd_share;
+ struct rq *this_rq = this_rq();
+ int this = smp_processor_id();
+ struct sched_domain *this_sd;
+@@ -6363,6 +6364,17 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool
+ time = cpu_clock(this);
+ }
+
++ if (sched_feat(SIS_UTIL)) {
++ sd_share = rcu_dereference(per_cpu(sd_llc_shared, target));
++ if (sd_share) {
++ /* because !--nr is the condition to stop scan */
++ nr = READ_ONCE(sd_share->nr_idle_scan) + 1;
++ /* overloaded LLC is unlikely to have idle cpu/core */
++ if (nr == 1)
++ return -1;
++ }
++ }
++
+ for_each_cpu_wrap(cpu, cpus, target + 1) {
+ if (has_idle_core) {
+ i = select_idle_core(p, cpu, cpus, &idle_cpu);
+@@ -9253,6 +9265,77 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p, int this_cpu)
+ return idlest;
+ }
+
++static void update_idle_cpu_scan(struct lb_env *env,
++ unsigned long sum_util)
++{
++ struct sched_domain_shared *sd_share;
++ int llc_weight, pct;
++ u64 x, y, tmp;
++ /*
++ * Update the number of CPUs to scan in LLC domain, which could
++ * be used as a hint in select_idle_cpu(). The update of sd_share
++ * could be expensive because it is within a shared cache line.
++ * So the write of this hint only occurs during periodic load
++ * balancing, rather than CPU_NEWLY_IDLE, because the latter
++ * can fire way more frequently than the former.
++ */
++ if (!sched_feat(SIS_UTIL) || env->idle == CPU_NEWLY_IDLE)
++ return;
++
++ llc_weight = per_cpu(sd_llc_size, env->dst_cpu);
++ if (env->sd->span_weight != llc_weight)
++ return;
++
++ sd_share = rcu_dereference(per_cpu(sd_llc_shared, env->dst_cpu));
++ if (!sd_share)
++ return;
++
++ /*
++ * The number of CPUs to search drops as sum_util increases, when
++ * sum_util hits 85% or above, the scan stops.
++ * The reason to choose 85% as the threshold is because this is the
++ * imbalance_pct(117) when a LLC sched group is overloaded.
++ *
++ * let y = SCHED_CAPACITY_SCALE - p * x^2 [1]
++ * and y'= y / SCHED_CAPACITY_SCALE
++ *
++ * x is the ratio of sum_util compared to the CPU capacity:
++ * x = sum_util / (llc_weight * SCHED_CAPACITY_SCALE)
++ * y' is the ratio of CPUs to be scanned in the LLC domain,
++ * and the number of CPUs to scan is calculated by:
++ *
++ * nr_scan = llc_weight * y' [2]
++ *
++ * When x hits the threshold of overloaded, AKA, when
++ * x = 100 / pct, y drops to 0. According to [1],
++ * p should be SCHED_CAPACITY_SCALE * pct^2 / 10000
++ *
++ * Scale x by SCHED_CAPACITY_SCALE:
++ * x' = sum_util / llc_weight; [3]
++ *
++ * and finally [1] becomes:
++ * y = SCHED_CAPACITY_SCALE -
++ * x'^2 * pct^2 / (10000 * SCHED_CAPACITY_SCALE) [4]
++ *
++ */
++ /* equation [3] */
++ x = sum_util;
++ do_div(x, llc_weight);
++
++ /* equation [4] */
++ pct = env->sd->imbalance_pct;
++ tmp = x * x * pct * pct;
++ do_div(tmp, 10000 * SCHED_CAPACITY_SCALE);
++ tmp = min_t(long, tmp, SCHED_CAPACITY_SCALE);
++ y = SCHED_CAPACITY_SCALE - tmp;
++
++ /* equation [2] */
++ y *= llc_weight;
++ do_div(y, SCHED_CAPACITY_SCALE);
++ if ((int)y != sd_share->nr_idle_scan)
++ WRITE_ONCE(sd_share->nr_idle_scan, (int)y);
++}
++
+ /**
+ * update_sd_lb_stats - Update sched_domain's statistics for load balancing.
+ * @env: The load balancing environment.
+@@ -9265,6 +9348,7 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd
+ struct sched_group *sg = env->sd->groups;
+ struct sg_lb_stats *local = &sds->local_stat;
+ struct sg_lb_stats tmp_sgs;
++ unsigned long sum_util = 0;
+ int sg_status = 0;
+
+ do {
+@@ -9297,6 +9381,7 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd
+ sds->total_load += sgs->group_load;
+ sds->total_capacity += sgs->group_capacity;
+
++ sum_util += sgs->group_util;
+ sg = sg->next;
+ } while (sg != env->sd->groups);
+
+@@ -9322,6 +9407,8 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd
+ WRITE_ONCE(rd->overutilized, SG_OVERUTILIZED);
+ trace_sched_overutilized_tp(rd, SG_OVERUTILIZED);
+ }
++
++ update_idle_cpu_scan(env, sum_util);
+ }
+
+ #define NUMA_IMBALANCE_MIN 2
+diff --git a/kernel/sched/features.h b/kernel/sched/features.h
+index 1cf435bbcd9c..ee7f23c76bd3 100644
+--- a/kernel/sched/features.h
++++ b/kernel/sched/features.h
+@@ -60,7 +60,8 @@ SCHED_FEAT(TTWU_QUEUE, true)
+ /*
+ * When doing wakeups, attempt to limit superfluous scans of the LLC domain.
+ */
+-SCHED_FEAT(SIS_PROP, true)
++SCHED_FEAT(SIS_PROP, false)
++SCHED_FEAT(SIS_UTIL, true)
+
+ /*
+ * Issue a WARN when we do multiple update_rq_clock() calls
+--
+2.35.1
+
--- /dev/null
+From 368f92d97f45d4d7b52e8ed89d03114198b06c47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 07:34:11 +0800
+Subject: sched: Fix the check of nr_running at queue wakelist
+
+From: Tianchen Ding <dtcccc@linux.alibaba.com>
+
+[ Upstream commit 28156108fecb1f808b21d216e8ea8f0d205a530c ]
+
+The commit 2ebb17717550 ("sched/core: Offload wakee task activation if it
+the wakee is descheduling") checked rq->nr_running <= 1 to avoid task
+stacking when WF_ON_CPU.
+
+Per the ordering of writes to p->on_rq and p->on_cpu, observing p->on_cpu
+(WF_ON_CPU) in ttwu_queue_cond() implies !p->on_rq, IOW p has gone through
+the deactivate_task() in __schedule(), thus p has been accounted out of
+rq->nr_running. As such, the task being the only runnable task on the rq
+implies reading rq->nr_running == 0 at that point.
+
+The benchmark result is in [1].
+
+[1] https://lore.kernel.org/all/e34de686-4e85-bde1-9f3c-9bbc86b38627@linux.alibaba.com/
+
+Suggested-by: Valentin Schneider <vschneid@redhat.com>
+Signed-off-by: Tianchen Ding <dtcccc@linux.alibaba.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Valentin Schneider <vschneid@redhat.com>
+Link: https://lore.kernel.org/r/20220608233412.327341-2-dtcccc@linux.alibaba.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index b0f3ded147cb..4e99f0cf727a 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -3832,8 +3832,12 @@ static inline bool ttwu_queue_cond(int cpu, int wake_flags)
+ * CPU then use the wakelist to offload the task activation to
+ * the soon-to-be-idle CPU as the current CPU is likely busy.
+ * nr_running is checked to avoid unnecessary task stacking.
++ *
++ * Note that we can only get here with (wakee) p->on_rq=0,
++ * p->on_cpu can be whatever, we've done the dequeue, so
++ * the wakee has been accounted out of ->nr_running.
+ */
+- if ((wake_flags & WF_ON_CPU) && cpu_rq(cpu)->nr_running <= 1)
++ if ((wake_flags & WF_ON_CPU) && !cpu_rq(cpu)->nr_running)
+ return true;
+
+ return false;
+--
+2.35.1
+
--- /dev/null
+From c580d2c9e43c35594d9703a56eb5e6d53378391c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 07:34:12 +0800
+Subject: sched: Remove the limitation of WF_ON_CPU on wakelist if wakee cpu is
+ idle
+
+From: Tianchen Ding <dtcccc@linux.alibaba.com>
+
+[ Upstream commit f3dd3f674555bd9455c5ae7fafce0696bd9931b3 ]
+
+Wakelist can help avoid cache bouncing and offload the overhead of waker
+cpu. So far, using wakelist within the same llc only happens on
+WF_ON_CPU, and this limitation could be removed to further improve
+wakeup performance.
+
+The commit 518cd6234178 ("sched: Only queue remote wakeups when
+crossing cache boundaries") disabled queuing tasks on wakelist when
+the cpus share llc. This is because, at that time, the scheduler must
+send IPIs to do ttwu_queue_wakelist. Nowadays, ttwu_queue_wakelist also
+supports TIF_POLLING, so this is not a problem now when the wakee cpu is
+in idle polling.
+
+Benefits:
+ Queuing the task on idle cpu can help improving performance on waker cpu
+ and utilization on wakee cpu, and further improve locality because
+ the wakee cpu can handle its own rq. This patch helps improving rt on
+ our real java workloads where wakeup happens frequently.
+
+ Consider the normal condition (CPU0 and CPU1 share same llc)
+ Before this patch:
+
+ CPU0 CPU1
+
+ select_task_rq() idle
+ rq_lock(CPU1->rq)
+ enqueue_task(CPU1->rq)
+ notify CPU1 (by sending IPI or CPU1 polling)
+
+ resched()
+
+ After this patch:
+
+ CPU0 CPU1
+
+ select_task_rq() idle
+ add to wakelist of CPU1
+ notify CPU1 (by sending IPI or CPU1 polling)
+
+ rq_lock(CPU1->rq)
+ enqueue_task(CPU1->rq)
+ resched()
+
+ We see CPU0 can finish its work earlier. It only needs to put task to
+ wakelist and return.
+ While CPU1 is idle, so let itself handle its own runqueue data.
+
+This patch brings no difference about IPI.
+ This patch only takes effect when the wakee cpu is:
+ 1) idle polling
+ 2) idle not polling
+
+ For 1), there will be no IPI with or without this patch.
+
+ For 2), there will always be an IPI before or after this patch.
+ Before this patch: waker cpu will enqueue task and check preempt. Since
+ "idle" will be sure to be preempted, waker cpu must send a resched IPI.
+ After this patch: waker cpu will put the task to the wakelist of wakee
+ cpu, and send an IPI.
+
+Benchmark:
+We've tested schbench, unixbench, and hachbench on both x86 and arm64.
+
+On x86 (Intel Xeon Platinum 8269CY):
+ schbench -m 2 -t 8
+
+ Latency percentiles (usec) before after
+ 50.0000th: 8 6
+ 75.0000th: 10 7
+ 90.0000th: 11 8
+ 95.0000th: 12 8
+ *99.0000th: 13 10
+ 99.5000th: 15 11
+ 99.9000th: 18 14
+
+ Unixbench with full threads (104)
+ before after
+ Dhrystone 2 using register variables 3011862938 3009935994 -0.06%
+ Double-Precision Whetstone 617119.3 617298.5 0.03%
+ Execl Throughput 27667.3 27627.3 -0.14%
+ File Copy 1024 bufsize 2000 maxblocks 785871.4 784906.2 -0.12%
+ File Copy 256 bufsize 500 maxblocks 210113.6 212635.4 1.20%
+ File Copy 4096 bufsize 8000 maxblocks 2328862.2 2320529.1 -0.36%
+ Pipe Throughput 145535622.8 145323033.2 -0.15%
+ Pipe-based Context Switching 3221686.4 3583975.4 11.25%
+ Process Creation 101347.1 103345.4 1.97%
+ Shell Scripts (1 concurrent) 120193.5 123977.8 3.15%
+ Shell Scripts (8 concurrent) 17233.4 17138.4 -0.55%
+ System Call Overhead 5300604.8 5312213.6 0.22%
+
+ hackbench -g 1 -l 100000
+ before after
+ Time 3.246 2.251
+
+On arm64 (Ampere Altra):
+ schbench -m 2 -t 8
+
+ Latency percentiles (usec) before after
+ 50.0000th: 14 10
+ 75.0000th: 19 14
+ 90.0000th: 22 16
+ 95.0000th: 23 16
+ *99.0000th: 24 17
+ 99.5000th: 24 17
+ 99.9000th: 28 25
+
+ Unixbench with full threads (80)
+ before after
+ Dhrystone 2 using register variables 3536194249 3537019613 0.02%
+ Double-Precision Whetstone 629383.6 629431.6 0.01%
+ Execl Throughput 65920.5 65846.2 -0.11%
+ File Copy 1024 bufsize 2000 maxblocks 1063722.8 1064026.8 0.03%
+ File Copy 256 bufsize 500 maxblocks 322684.5 318724.5 -1.23%
+ File Copy 4096 bufsize 8000 maxblocks 2348285.3 2328804.8 -0.83%
+ Pipe Throughput 133542875.3 131619389.8 -1.44%
+ Pipe-based Context Switching 3215356.1 3576945.1 11.25%
+ Process Creation 108520.5 120184.6 10.75%
+ Shell Scripts (1 concurrent) 122636.3 121888 -0.61%
+ Shell Scripts (8 concurrent) 17462.1 17381.4 -0.46%
+ System Call Overhead 4429998.9 4435006.7 0.11%
+
+ hackbench -g 1 -l 100000
+ before after
+ Time 4.217 2.916
+
+Our patch has improvement on schbench, hackbench
+and Pipe-based Context Switching of unixbench
+when there exists idle cpus,
+and no obvious regression on other tests of unixbench.
+This can help improve rt in scenes where wakeup happens frequently.
+
+Signed-off-by: Tianchen Ding <dtcccc@linux.alibaba.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Valentin Schneider <vschneid@redhat.com>
+Link: https://lore.kernel.org/r/20220608233412.327341-3-dtcccc@linux.alibaba.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/core.c | 26 ++++++++++++++------------
+ kernel/sched/sched.h | 1 -
+ 2 files changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 4e99f0cf727a..df4a8c9d1070 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -3811,7 +3811,7 @@ bool cpus_share_cache(int this_cpu, int that_cpu)
+ return per_cpu(sd_llc_id, this_cpu) == per_cpu(sd_llc_id, that_cpu);
+ }
+
+-static inline bool ttwu_queue_cond(int cpu, int wake_flags)
++static inline bool ttwu_queue_cond(int cpu)
+ {
+ /*
+ * Do not complicate things with the async wake_list while the CPU is
+@@ -3827,17 +3827,21 @@ static inline bool ttwu_queue_cond(int cpu, int wake_flags)
+ if (!cpus_share_cache(smp_processor_id(), cpu))
+ return true;
+
++ if (cpu == smp_processor_id())
++ return false;
++
+ /*
+- * If the task is descheduling and the only running task on the
+- * CPU then use the wakelist to offload the task activation to
+- * the soon-to-be-idle CPU as the current CPU is likely busy.
+- * nr_running is checked to avoid unnecessary task stacking.
++ * If the wakee cpu is idle, or the task is descheduling and the
++ * only running task on the CPU, then use the wakelist to offload
++ * the task activation to the idle (or soon-to-be-idle) CPU as
++ * the current CPU is likely busy. nr_running is checked to
++ * avoid unnecessary task stacking.
+ *
+ * Note that we can only get here with (wakee) p->on_rq=0,
+ * p->on_cpu can be whatever, we've done the dequeue, so
+ * the wakee has been accounted out of ->nr_running.
+ */
+- if ((wake_flags & WF_ON_CPU) && !cpu_rq(cpu)->nr_running)
++ if (!cpu_rq(cpu)->nr_running)
+ return true;
+
+ return false;
+@@ -3845,10 +3849,7 @@ static inline bool ttwu_queue_cond(int cpu, int wake_flags)
+
+ static bool ttwu_queue_wakelist(struct task_struct *p, int cpu, int wake_flags)
+ {
+- if (sched_feat(TTWU_QUEUE) && ttwu_queue_cond(cpu, wake_flags)) {
+- if (WARN_ON_ONCE(cpu == smp_processor_id()))
+- return false;
+-
++ if (sched_feat(TTWU_QUEUE) && ttwu_queue_cond(cpu)) {
+ sched_clock_cpu(cpu); /* Sync clocks across CPUs */
+ __ttwu_queue_wakelist(p, cpu, wake_flags);
+ return true;
+@@ -4170,7 +4171,7 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
+ * scheduling.
+ */
+ if (smp_load_acquire(&p->on_cpu) &&
+- ttwu_queue_wakelist(p, task_cpu(p), wake_flags | WF_ON_CPU))
++ ttwu_queue_wakelist(p, task_cpu(p), wake_flags))
+ goto unlock;
+
+ /*
+@@ -4714,7 +4715,8 @@ static inline void prepare_task(struct task_struct *next)
+ * Claim the task as running, we do this before switching to it
+ * such that any running task will have this set.
+ *
+- * See the ttwu() WF_ON_CPU case and its ordering comment.
++ * See the smp_load_acquire(&p->on_cpu) case in ttwu() and
++ * its ordering comment.
+ */
+ WRITE_ONCE(next->on_cpu, 1);
+ #endif
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index 84bba67c92dc..08fdb9ccd14d 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -2042,7 +2042,6 @@ static inline int task_on_rq_migrating(struct task_struct *p)
+
+ #define WF_SYNC 0x10 /* Waker goes to sleep after wakeup */
+ #define WF_MIGRATED 0x20 /* Internal use, task got migrated */
+-#define WF_ON_CPU 0x40 /* Wakee is on_cpu */
+
+ #ifdef CONFIG_SMP
+ static_assert(WF_EXEC == SD_BALANCE_EXEC);
+--
+2.35.1
+
--- /dev/null
+From 6e3d245d0b1aa7a8535247dcc8865e59aed7196d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 11:01:23 -0700
+Subject: scripts/faddr2line: Fix vmlinux detection on arm64
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit b6a5068854cfe372da7dee3224dcf023ed5b00cb ]
+
+Since commit dcea997beed6 ("faddr2line: Fix overlapping text section
+failures, the sequel"), faddr2line is completely broken on arm64.
+
+For some reason, on arm64, the vmlinux ELF object file type is ET_DYN
+rather than ET_EXEC. Check for both when determining whether the object
+is vmlinux.
+
+Modules and vmlinux.o have type ET_REL on all arches.
+
+Fixes: dcea997beed6 ("faddr2line: Fix overlapping text section failures, the sequel")
+Reported-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: John Garry <john.garry@huawei.com>
+Link: https://lore.kernel.org/r/dad1999737471b06d6188ce4cdb11329aa41682c.1658426357.git.jpoimboe@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/faddr2line | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/scripts/faddr2line b/scripts/faddr2line
+index 94ed98dd899f..57099687e5e1 100755
+--- a/scripts/faddr2line
++++ b/scripts/faddr2line
+@@ -112,7 +112,9 @@ __faddr2line() {
+ # section offsets.
+ local file_type=$(${READELF} --file-header $objfile |
+ ${AWK} '$1 == "Type:" { print $2; exit }')
+- [[ $file_type = "EXEC" ]] && is_vmlinux=1
++ if [[ $file_type = "EXEC" ]] || [[ $file_type == "DYN" ]]; then
++ is_vmlinux=1
++ fi
+
+ # Go through each of the object's symbols which match the func name.
+ # In rare cases there might be duplicates, in which case we print all
+--
+2.35.1
+
--- /dev/null
+From f5d9f33f91f17c01390550c3ffdc473e4119071e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 14:28:31 +0200
+Subject: scripts/gdb: fix 'lx-dmesg' on 32 bits arch
+
+From: Antonio Borneo <antonio.borneo@foss.st.com>
+
+[ Upstream commit e3c8d33e0d62175c31ca7ab7ab01b18f0b6318d3 ]
+
+The type atomic_long_t can have size 4 or 8 bytes, depending on
+CONFIG_64BIT; it's only content, the field 'counter', is either an
+int or a s64 value.
+
+Current code incorrectly uses the fixed size utils.read_u64() to
+read the field 'counter' inside atomic_long_t.
+
+On 32 bits architectures reading the last element 'tail_id' of the
+struct prb_desc_ring:
+ struct prb_desc_ring {
+ ...
+ atomic_long_t tail_id;
+ };
+causes the utils.read_u64() to access outside the boundary of the
+struct and the gdb command 'lx-dmesg' exits with error:
+ Python Exception <class 'IndexError'>: index out of range
+ Error occurred in Python: index out of range
+
+Query the really used atomic_long_t counter type size.
+
+Link: https://lore.kernel.org/r/20220617143758.137307-1-antonio.borneo@foss.st.com
+Fixes: e60768311af8 ("scripts/gdb: update for lockless printk ringbuffer")
+Signed-off-by: Antonio Borneo <antonio.borneo@foss.st.com>
+[pmladek@suse.com: Query the really used atomic_long_t counter type size]
+Tested-by: Antonio Borneo <antonio.borneo@foss.st.com>
+Reviewed-by: John Ogness <john.ogness@linutronix.de>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Link: https://lore.kernel.org/r/20220719122831.19890-1-pmladek@suse.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/gdb/linux/dmesg.py | 9 +++------
+ scripts/gdb/linux/utils.py | 14 ++++++++++++--
+ 2 files changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py
+index d5983cf3db7d..c771831eb077 100644
+--- a/scripts/gdb/linux/dmesg.py
++++ b/scripts/gdb/linux/dmesg.py
+@@ -22,7 +22,6 @@ prb_desc_type = utils.CachedType("struct prb_desc")
+ prb_desc_ring_type = utils.CachedType("struct prb_desc_ring")
+ prb_data_ring_type = utils.CachedType("struct prb_data_ring")
+ printk_ringbuffer_type = utils.CachedType("struct printk_ringbuffer")
+-atomic_long_type = utils.CachedType("atomic_long_t")
+
+ class LxDmesg(gdb.Command):
+ """Print Linux kernel log buffer."""
+@@ -68,8 +67,6 @@ class LxDmesg(gdb.Command):
+ off = prb_data_ring_type.get_type()['data'].bitpos // 8
+ text_data_addr = utils.read_ulong(text_data_ring, off)
+
+- counter_off = atomic_long_type.get_type()['counter'].bitpos // 8
+-
+ sv_off = prb_desc_type.get_type()['state_var'].bitpos // 8
+
+ off = prb_desc_type.get_type()['text_blk_lpos'].bitpos // 8
+@@ -89,9 +86,9 @@ class LxDmesg(gdb.Command):
+
+ # read in tail and head descriptor ids
+ off = prb_desc_ring_type.get_type()['tail_id'].bitpos // 8
+- tail_id = utils.read_u64(desc_ring, off + counter_off)
++ tail_id = utils.read_atomic_long(desc_ring, off)
+ off = prb_desc_ring_type.get_type()['head_id'].bitpos // 8
+- head_id = utils.read_u64(desc_ring, off + counter_off)
++ head_id = utils.read_atomic_long(desc_ring, off)
+
+ did = tail_id
+ while True:
+@@ -102,7 +99,7 @@ class LxDmesg(gdb.Command):
+ desc = utils.read_memoryview(inf, desc_addr + desc_off, desc_sz).tobytes()
+
+ # skip non-committed record
+- state = 3 & (utils.read_u64(desc, sv_off + counter_off) >> desc_flags_shift)
++ state = 3 & (utils.read_atomic_long(desc, sv_off) >> desc_flags_shift)
+ if state != desc_committed and state != desc_finalized:
+ if did == head_id:
+ break
+diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py
+index ff7c1799d588..1553f68716cc 100644
+--- a/scripts/gdb/linux/utils.py
++++ b/scripts/gdb/linux/utils.py
+@@ -35,13 +35,12 @@ class CachedType:
+
+
+ long_type = CachedType("long")
+-
++atomic_long_type = CachedType("atomic_long_t")
+
+ def get_long_type():
+ global long_type
+ return long_type.get_type()
+
+-
+ def offset_of(typeobj, field):
+ element = gdb.Value(0).cast(typeobj)
+ return int(str(element[field].address).split()[0], 16)
+@@ -129,6 +128,17 @@ def read_ulong(buffer, offset):
+ else:
+ return read_u32(buffer, offset)
+
++atomic_long_counter_offset = atomic_long_type.get_type()['counter'].bitpos
++atomic_long_counter_sizeof = atomic_long_type.get_type()['counter'].type.sizeof
++
++def read_atomic_long(buffer, offset):
++ global atomic_long_counter_offset
++ global atomic_long_counter_sizeof
++
++ if atomic_long_counter_sizeof == 8:
++ return read_u64(buffer, offset + atomic_long_counter_offset)
++ else:
++ return read_u32(buffer, offset + atomic_long_counter_offset)
+
+ target_arch = None
+
+--
+2.35.1
+
--- /dev/null
+From 9038867f740b7c5709f64ad0f712430ad50e009d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 17:27:36 -0500
+Subject: scsi: iscsi: Add helper to remove a session from the kernel
+
+From: Mike Christie <michael.christie@oracle.com>
+
+[ Upstream commit bb42856bfd54fda1cbc7c470fcf5db1596938f4f ]
+
+During qedi shutdown we need to stop the iSCSI layer from sending new nops
+as pings and from responding to target ones and make sure there is no
+running connection cleanups. Commit d1f2ce77638d ("scsi: qedi: Fix host
+removal with running sessions") converted the driver to use the libicsi
+helper to drive session removal, so the above issues could be handled. The
+problem is that during system shutdown iscsid will not be running so when
+we try to remove the root session we will hang waiting for userspace to
+reply.
+
+Add a helper that will drive the destruction of sessions like these during
+system shutdown.
+
+Link: https://lore.kernel.org/r/20220616222738.5722-5-michael.christie@oracle.com
+Tested-by: Nilesh Javali <njavali@marvell.com>
+Reviewed-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_transport_iscsi.c | 49 +++++++++++++++++++++++++++++
+ include/scsi/scsi_transport_iscsi.h | 1 +
+ 2 files changed, 50 insertions(+)
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index a410d0b8a445..2a38cd2d24ef 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -2341,6 +2341,55 @@ static void iscsi_cleanup_conn_work_fn(struct work_struct *work)
+ ISCSI_DBG_TRANS_CONN(conn, "cleanup done.\n");
+ }
+
++static int iscsi_iter_force_destroy_conn_fn(struct device *dev, void *data)
++{
++ struct iscsi_transport *transport;
++ struct iscsi_cls_conn *conn;
++
++ if (!iscsi_is_conn_dev(dev))
++ return 0;
++
++ conn = iscsi_dev_to_conn(dev);
++ transport = conn->transport;
++
++ if (READ_ONCE(conn->state) != ISCSI_CONN_DOWN)
++ iscsi_if_stop_conn(conn, STOP_CONN_TERM);
++
++ transport->destroy_conn(conn);
++ return 0;
++}
++
++/**
++ * iscsi_force_destroy_session - destroy a session from the kernel
++ * @session: session to destroy
++ *
++ * Force the destruction of a session from the kernel. This should only be
++ * used when userspace is no longer running during system shutdown.
++ */
++void iscsi_force_destroy_session(struct iscsi_cls_session *session)
++{
++ struct iscsi_transport *transport = session->transport;
++ unsigned long flags;
++
++ WARN_ON_ONCE(system_state == SYSTEM_RUNNING);
++
++ spin_lock_irqsave(&sesslock, flags);
++ if (list_empty(&session->sess_list)) {
++ spin_unlock_irqrestore(&sesslock, flags);
++ /*
++ * Conn/ep is already freed. Session is being torn down via
++ * async path. For shutdown we don't care about it so return.
++ */
++ return;
++ }
++ spin_unlock_irqrestore(&sesslock, flags);
++
++ device_for_each_child(&session->dev, NULL,
++ iscsi_iter_force_destroy_conn_fn);
++ transport->destroy_session(session);
++}
++EXPORT_SYMBOL_GPL(iscsi_force_destroy_session);
++
+ void iscsi_free_session(struct iscsi_cls_session *session)
+ {
+ ISCSI_DBG_TRANS_SESSION(session, "Freeing session\n");
+diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
+index 9acb8422f680..d6eab7cb221a 100644
+--- a/include/scsi/scsi_transport_iscsi.h
++++ b/include/scsi/scsi_transport_iscsi.h
+@@ -442,6 +442,7 @@ extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,
+ struct iscsi_transport *t,
+ int dd_size,
+ unsigned int target_id);
++extern void iscsi_force_destroy_session(struct iscsi_cls_session *session);
+ extern void iscsi_remove_session(struct iscsi_cls_session *session);
+ extern void iscsi_free_session(struct iscsi_cls_session *session);
+ extern struct iscsi_cls_conn *iscsi_alloc_conn(struct iscsi_cls_session *sess,
+--
+2.35.1
+
--- /dev/null
+From a0d215046c0c7792eb39b49c942b46f78236ed2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 17:27:34 -0500
+Subject: scsi: iscsi: Allow iscsi_if_stop_conn() to be called from kernel
+
+From: Mike Christie <michael.christie@oracle.com>
+
+[ Upstream commit 3328333b47f4163504267440ec0a36087a407a5f ]
+
+iscsi_if_stop_conn() is only called from the userspace interface but in a
+subsequent commit we will want to call it from the kernel interface to
+allow drivers like qedi to remove sessions from inside the kernel during
+shutdown. This removes the iscsi_uevent code from iscsi_if_stop_conn() so we
+can call it in a new helper.
+
+Link: https://lore.kernel.org/r/20220616222738.5722-3-michael.christie@oracle.com
+Tested-by: Nilesh Javali <njavali@marvell.com>
+Reviewed-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_transport_iscsi.c | 17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index 5d21f07456c6..a410d0b8a445 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -2264,16 +2264,8 @@ static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn,
+ }
+ }
+
+-static int iscsi_if_stop_conn(struct iscsi_transport *transport,
+- struct iscsi_uevent *ev)
++static int iscsi_if_stop_conn(struct iscsi_cls_conn *conn, int flag)
+ {
+- int flag = ev->u.stop_conn.flag;
+- struct iscsi_cls_conn *conn;
+-
+- conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid);
+- if (!conn)
+- return -EINVAL;
+-
+ ISCSI_DBG_TRANS_CONN(conn, "iscsi if conn stop.\n");
+ /*
+ * If this is a termination we have to call stop_conn with that flag
+@@ -3720,7 +3712,12 @@ static int iscsi_if_transport_conn(struct iscsi_transport *transport,
+ case ISCSI_UEVENT_DESTROY_CONN:
+ return iscsi_if_destroy_conn(transport, ev);
+ case ISCSI_UEVENT_STOP_CONN:
+- return iscsi_if_stop_conn(transport, ev);
++ conn = iscsi_conn_lookup(ev->u.stop_conn.sid,
++ ev->u.stop_conn.cid);
++ if (!conn)
++ return -EINVAL;
++
++ return iscsi_if_stop_conn(conn, ev->u.stop_conn.flag);
+ }
+
+ /*
+--
+2.35.1
+
--- /dev/null
+From 2773294d2a6e60f443616e4f63b054cf9dfe0583 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 17:27:38 -0500
+Subject: scsi: iscsi: Fix session removal on shutdown
+
+From: Mike Christie <michael.christie@oracle.com>
+
+[ Upstream commit 31500e902759322ba3c64b60dabae2704e738df8 ]
+
+When the system is shutting down, iscsid is not running so we will not get
+a response to the ISCSI_ERR_INVALID_HOST error event. The system shutdown
+will then hang waiting on userspace to remove the session.
+
+This has libiscsi force the destruction of the session from the kernel when
+iscsi_host_remove() is called from a driver's shutdown callout.
+
+This fixes a regression added in qedi boot with commit d1f2ce77638d ("scsi:
+qedi: Fix host removal with running sessions") which made qedi use the
+common session removal function that waits on userspace instead of rolling
+its own kernel based removal.
+
+Link: https://lore.kernel.org/r/20220616222738.5722-7-michael.christie@oracle.com
+Fixes: d1f2ce77638d ("scsi: qedi: Fix host removal with running sessions")
+Tested-by: Nilesh Javali <njavali@marvell.com>
+Reviewed-by: Lee Duncan <lduncan@suse.com>
+Reviewed-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/iser/iscsi_iser.c | 4 ++--
+ drivers/scsi/be2iscsi/be_main.c | 2 +-
+ drivers/scsi/bnx2i/bnx2i_iscsi.c | 2 +-
+ drivers/scsi/cxgbi/libcxgbi.c | 2 +-
+ drivers/scsi/iscsi_tcp.c | 4 ++--
+ drivers/scsi/libiscsi.c | 9 +++++++--
+ drivers/scsi/qedi/qedi_main.c | 9 ++++++---
+ include/scsi/libiscsi.h | 2 +-
+ 8 files changed, 21 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
+index f8d0bab4424c..e36036b8f386 100644
+--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
++++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
+@@ -568,7 +568,7 @@ static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
+ struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+
+ iscsi_session_teardown(cls_session);
+- iscsi_host_remove(shost);
++ iscsi_host_remove(shost, false);
+ iscsi_host_free(shost);
+ }
+
+@@ -685,7 +685,7 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
+ return cls_session;
+
+ remove_host:
+- iscsi_host_remove(shost);
++ iscsi_host_remove(shost, false);
+ free_host:
+ iscsi_host_free(shost);
+ return NULL;
+diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
+index 3bb0adefbe06..02026476c39c 100644
+--- a/drivers/scsi/be2iscsi/be_main.c
++++ b/drivers/scsi/be2iscsi/be_main.c
+@@ -5745,7 +5745,7 @@ static void beiscsi_remove(struct pci_dev *pcidev)
+ cancel_work_sync(&phba->sess_work);
+
+ beiscsi_iface_destroy_default(phba);
+- iscsi_host_remove(phba->shost);
++ iscsi_host_remove(phba->shost, false);
+ beiscsi_disable_port(phba, 1);
+
+ /* after cancelling boot_work */
+diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
+index 15fbd09baa94..a3c800e04a2e 100644
+--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
++++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
+@@ -909,7 +909,7 @@ void bnx2i_free_hba(struct bnx2i_hba *hba)
+ {
+ struct Scsi_Host *shost = hba->shost;
+
+- iscsi_host_remove(shost);
++ iscsi_host_remove(shost, false);
+ INIT_LIST_HEAD(&hba->ep_ofld_list);
+ INIT_LIST_HEAD(&hba->ep_active_list);
+ INIT_LIST_HEAD(&hba->ep_destroy_list);
+diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
+index 4365d52c6430..32abdf0fa9aa 100644
+--- a/drivers/scsi/cxgbi/libcxgbi.c
++++ b/drivers/scsi/cxgbi/libcxgbi.c
+@@ -328,7 +328,7 @@ void cxgbi_hbas_remove(struct cxgbi_device *cdev)
+ chba = cdev->hbas[i];
+ if (chba) {
+ cdev->hbas[i] = NULL;
+- iscsi_host_remove(chba->shost);
++ iscsi_host_remove(chba->shost, false);
+ pci_dev_put(cdev->pdev);
+ iscsi_host_free(chba->shost);
+ }
+diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
+index 9fee70d6434a..52c6f70d60ec 100644
+--- a/drivers/scsi/iscsi_tcp.c
++++ b/drivers/scsi/iscsi_tcp.c
+@@ -898,7 +898,7 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
+ remove_session:
+ iscsi_session_teardown(cls_session);
+ remove_host:
+- iscsi_host_remove(shost);
++ iscsi_host_remove(shost, false);
+ free_host:
+ iscsi_host_free(shost);
+ return NULL;
+@@ -915,7 +915,7 @@ static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)
+ iscsi_tcp_r2tpool_free(cls_session->dd_data);
+ iscsi_session_teardown(cls_session);
+
+- iscsi_host_remove(shost);
++ iscsi_host_remove(shost, false);
+ iscsi_host_free(shost);
+ }
+
+diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
+index 797abf4f5399..3ddb701cd29c 100644
+--- a/drivers/scsi/libiscsi.c
++++ b/drivers/scsi/libiscsi.c
+@@ -2828,11 +2828,12 @@ static void iscsi_notify_host_removed(struct iscsi_cls_session *cls_session)
+ /**
+ * iscsi_host_remove - remove host and sessions
+ * @shost: scsi host
++ * @is_shutdown: true if called from a driver shutdown callout
+ *
+ * If there are any sessions left, this will initiate the removal and wait
+ * for the completion.
+ */
+-void iscsi_host_remove(struct Scsi_Host *shost)
++void iscsi_host_remove(struct Scsi_Host *shost, bool is_shutdown)
+ {
+ struct iscsi_host *ihost = shost_priv(shost);
+ unsigned long flags;
+@@ -2841,7 +2842,11 @@ void iscsi_host_remove(struct Scsi_Host *shost)
+ ihost->state = ISCSI_HOST_REMOVED;
+ spin_unlock_irqrestore(&ihost->lock, flags);
+
+- iscsi_host_for_each_session(shost, iscsi_notify_host_removed);
++ if (!is_shutdown)
++ iscsi_host_for_each_session(shost, iscsi_notify_host_removed);
++ else
++ iscsi_host_for_each_session(shost, iscsi_force_destroy_session);
++
+ wait_event_interruptible(ihost->session_removal_wq,
+ ihost->num_sessions == 0);
+ if (signal_pending(current))
+diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c
+index 83ffba7f51da..780d975c85b5 100644
+--- a/drivers/scsi/qedi/qedi_main.c
++++ b/drivers/scsi/qedi/qedi_main.c
+@@ -2414,9 +2414,12 @@ static void __qedi_remove(struct pci_dev *pdev, int mode)
+ int rval;
+ u16 retry = 10;
+
+- if (mode == QEDI_MODE_NORMAL || mode == QEDI_MODE_SHUTDOWN) {
+- iscsi_host_remove(qedi->shost);
++ if (mode == QEDI_MODE_NORMAL)
++ iscsi_host_remove(qedi->shost, false);
++ else if (mode == QEDI_MODE_SHUTDOWN)
++ iscsi_host_remove(qedi->shost, true);
+
++ if (mode == QEDI_MODE_NORMAL || mode == QEDI_MODE_SHUTDOWN) {
+ if (qedi->tmf_thread) {
+ destroy_workqueue(qedi->tmf_thread);
+ qedi->tmf_thread = NULL;
+@@ -2791,7 +2794,7 @@ static int __qedi_probe(struct pci_dev *pdev, int mode)
+ #ifdef CONFIG_DEBUG_FS
+ qedi_dbg_host_exit(&qedi->dbg_ctx);
+ #endif
+- iscsi_host_remove(qedi->shost);
++ iscsi_host_remove(qedi->shost, false);
+ stop_iscsi_func:
+ qedi_ops->stop(qedi->cdev);
+ stop_slowpath:
+diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
+index c0703cd20a99..9758a4a9923f 100644
+--- a/include/scsi/libiscsi.h
++++ b/include/scsi/libiscsi.h
+@@ -411,7 +411,7 @@ extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev);
+ extern struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
+ int dd_data_size,
+ bool xmit_can_sleep);
+-extern void iscsi_host_remove(struct Scsi_Host *shost);
++extern void iscsi_host_remove(struct Scsi_Host *shost, bool is_shutdown);
+ extern void iscsi_host_free(struct Scsi_Host *shost);
+ extern int iscsi_target_alloc(struct scsi_target *starget);
+ extern int iscsi_host_get_max_scsi_cmds(struct Scsi_Host *shost,
+--
+2.35.1
+
--- /dev/null
+From 7e53efc3899ff8d342209b187700bb86990f7cb4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 May 2022 05:31:07 -0700
+Subject: scsi: nvme-fc: Add new routine nvme_fc_io_getuuid()
+
+From: Muneendra Kumar <muneendra.kumar@broadcom.com>
+
+[ Upstream commit 827fc630e4c8087df5a8e8ee013b686bd6f13736 ]
+
+Add nvme_fc_io_getuuid() to the nvme-fc transport. The routine is invoked
+by the FC LLDD on a per-I/O request basis. The routine translates from the
+FC-specific request structure to the bio and the cgroup structure in order
+to obtain the FC appid stored in the cgroup structure. If a value is not
+set or a bio is not found, a NULL appid (aka uuid) will be returned to the
+LLDD.
+
+Link: https://lore.kernel.org/r/20220519123110.17361-2-jsmart2021@gmail.com
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Acked-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Muneendra Kumar <muneendra.kumar@broadcom.com>
+Signed-off-by: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/fc.c | 18 ++++++++++++++++++
+ include/linux/nvme-fc-driver.h | 14 ++++++++++++++
+ 2 files changed, 32 insertions(+)
+
+diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
+index 080f85f4105f..05f9da251758 100644
+--- a/drivers/nvme/host/fc.c
++++ b/drivers/nvme/host/fc.c
+@@ -1899,6 +1899,24 @@ nvme_fc_ctrl_ioerr_work(struct work_struct *work)
+ nvme_fc_error_recovery(ctrl, "transport detected io error");
+ }
+
++/*
++ * nvme_fc_io_getuuid - Routine called to get the appid field
++ * associated with request by the lldd
++ * @req:IO request from nvme fc to driver
++ * Returns: UUID if there is an appid associated with VM or
++ * NULL if the user/libvirt has not set the appid to VM
++ */
++char *nvme_fc_io_getuuid(struct nvmefc_fcp_req *req)
++{
++ struct nvme_fc_fcp_op *op = fcp_req_to_fcp_op(req);
++ struct request *rq = op->rq;
++
++ if (!IS_ENABLED(CONFIG_BLK_CGROUP_FC_APPID) || !rq->bio)
++ return NULL;
++ return blkcg_get_fc_appid(rq->bio);
++}
++EXPORT_SYMBOL_GPL(nvme_fc_io_getuuid);
++
+ static void
+ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req)
+ {
+diff --git a/include/linux/nvme-fc-driver.h b/include/linux/nvme-fc-driver.h
+index 5358a5facdee..fa092b9be2fd 100644
+--- a/include/linux/nvme-fc-driver.h
++++ b/include/linux/nvme-fc-driver.h
+@@ -564,6 +564,15 @@ int nvme_fc_rcv_ls_req(struct nvme_fc_remote_port *remoteport,
+ void *lsreqbuf, u32 lsreqbuf_len);
+
+
++/*
++ * Routine called to get the appid field associated with request by the lldd
++ *
++ * If the return value is NULL : the user/libvirt has not set the appid to VM
++ * If the return value is non-zero: Returns the appid associated with VM
++ *
++ * @req: IO request from nvme fc to driver
++ */
++char *nvme_fc_io_getuuid(struct nvmefc_fcp_req *req);
+
+ /*
+ * *************** LLDD FC-NVME Target/Subsystem API ***************
+@@ -1048,5 +1057,10 @@ int nvmet_fc_rcv_fcp_req(struct nvmet_fc_target_port *tgtport,
+
+ void nvmet_fc_rcv_fcp_abort(struct nvmet_fc_target_port *tgtport,
+ struct nvmefc_tgt_fcp_req *fcpreq);
++/*
++ * add a define, visible to the compiler, that indicates support
++ * for feature. Allows for conditional compilation in LLDDs.
++ */
++#define NVME_FC_FEAT_UUID 0x0001
+
+ #endif /* _NVME_FC_DRIVER_H */
+--
+2.35.1
+
--- /dev/null
+From f23caec63aa4bfe5b04763961d2ec69ad4a5190c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jun 2022 09:21:55 +0300
+Subject: scsi: qla2xxx: Check correct variable in qla24xx_async_gffid()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 7c33e477bd883f79cccec418980cb8f7f2d50347 ]
+
+There is a copy and paste bug here. It should check ".rsp" instead of
+".req". The error message is copy and pasted as well so update that too.
+
+Link: https://lore.kernel.org/r/YrK1A/t3L6HKnswO@kili
+Fixes: 9c40c36e75ff ("scsi: qla2xxx: edif: Reduce Initiator-Initiator thrashing")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_gs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
+index 574251b2e0ef..c914b5df9c12 100644
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -3386,9 +3386,9 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool wait)
+ sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
+ &sp->u.iocb_cmd.u.ctarg.rsp_dma,
+ GFP_KERNEL);
+- if (!sp->u.iocb_cmd.u.ctarg.req) {
++ if (!sp->u.iocb_cmd.u.ctarg.rsp) {
+ ql_log(ql_log_warn, vha, 0xd041,
+- "%s: Failed to allocate ct_sns request.\n",
++ "%s: Failed to allocate ct_sns response.\n",
+ __func__);
+ goto done_free_sp;
+ }
+--
+2.35.1
+
--- /dev/null
+From e53f8110f5fef34654b3d907b273b1cf5204be10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:20 -0700
+Subject: scsi: qla2xxx: edif: Add bsg interface to read doorbell events
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 5ecd241bd7b1088a189581c0b560a13fe93621f6 ]
+
+Add bsg interface for app to read doorbell events. This interface lets
+driver know how much app can read based on return buffer size. When the
+next event(s) occur, driver will return the bsg_job with the event(s) in
+the return buffer.
+
+If there is no event to read, driver will hold on to the bsg_job up to few
+seconds as a way to control the polling interval.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-5-njavali@marvell.com
+Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_dbg.h | 2 +-
+ drivers/scsi/qla2xxx/qla_edif.c | 249 ++++++++++++++++++++--------
+ drivers/scsi/qla2xxx/qla_edif.h | 3 +-
+ drivers/scsi/qla2xxx/qla_edif_bsg.h | 14 ++
+ 4 files changed, 195 insertions(+), 73 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
+index f1f6c740bdcd..feeb1666227f 100644
+--- a/drivers/scsi/qla2xxx/qla_dbg.h
++++ b/drivers/scsi/qla2xxx/qla_dbg.h
+@@ -383,5 +383,5 @@ ql_mask_match(uint level)
+ if (ql2xextended_error_logging == 1)
+ ql2xextended_error_logging = QL_DBG_DEFAULT1_MASK;
+
+- return (level & ql2xextended_error_logging) == level;
++ return level && ((level & ql2xextended_error_logging) == level);
+ }
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index 034c43a8bb9b..d9e3f145b162 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -52,6 +52,31 @@ const char *sc_to_str(uint16_t cmd)
+ return "unknown";
+ }
+
++static struct edb_node *qla_edb_getnext(scsi_qla_host_t *vha)
++{
++ unsigned long flags;
++ struct edb_node *edbnode = NULL;
++
++ spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
++
++ /* db nodes are fifo - no qualifications done */
++ if (!list_empty(&vha->e_dbell.head)) {
++ edbnode = list_first_entry(&vha->e_dbell.head,
++ struct edb_node, list);
++ list_del_init(&edbnode->list);
++ }
++
++ spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
++
++ return edbnode;
++}
++
++static void qla_edb_node_free(scsi_qla_host_t *vha, struct edb_node *node)
++{
++ list_del_init(&node->list);
++ kfree(node);
++}
++
+ static struct edif_list_entry *qla_edif_list_find_sa_index(fc_port_t *fcport,
+ uint16_t handle)
+ {
+@@ -1072,6 +1097,130 @@ qla_edif_ack(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ return 0;
+ }
+
++static int qla_edif_consume_dbell(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
++{
++ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
++ u32 sg_skip, reply_payload_len;
++ bool keep;
++ struct edb_node *dbnode = NULL;
++ struct edif_app_dbell ap;
++ int dat_size = 0;
++
++ sg_skip = 0;
++ reply_payload_len = bsg_job->reply_payload.payload_len;
++
++ while ((reply_payload_len - sg_skip) >= sizeof(struct edb_node)) {
++ dbnode = qla_edb_getnext(vha);
++ if (dbnode) {
++ keep = true;
++ dat_size = 0;
++ ap.event_code = dbnode->ntype;
++ switch (dbnode->ntype) {
++ case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
++ case VND_CMD_AUTH_STATE_NEEDED:
++ ap.port_id = dbnode->u.plogi_did;
++ dat_size += sizeof(ap.port_id);
++ break;
++ case VND_CMD_AUTH_STATE_ELS_RCVD:
++ ap.port_id = dbnode->u.els_sid;
++ dat_size += sizeof(ap.port_id);
++ break;
++ case VND_CMD_AUTH_STATE_SAUPDATE_COMPL:
++ ap.port_id = dbnode->u.sa_aen.port_id;
++ memcpy(&ap.event_data, &dbnode->u,
++ sizeof(struct edif_sa_update_aen));
++ dat_size += sizeof(struct edif_sa_update_aen);
++ break;
++ default:
++ keep = false;
++ ql_log(ql_log_warn, vha, 0x09102,
++ "%s unknown DB type=%d %p\n",
++ __func__, dbnode->ntype, dbnode);
++ break;
++ }
++ ap.event_data_size = dat_size;
++ /* 8 = sizeof(ap.event_code + ap.event_data_size) */
++ dat_size += 8;
++ if (keep)
++ sg_skip += sg_copy_buffer(bsg_job->reply_payload.sg_list,
++ bsg_job->reply_payload.sg_cnt,
++ &ap, dat_size, sg_skip, false);
++
++ ql_dbg(ql_dbg_edif, vha, 0x09102,
++ "%s Doorbell consumed : type=%d %p\n",
++ __func__, dbnode->ntype, dbnode);
++
++ kfree(dbnode);
++ } else {
++ break;
++ }
++ }
++
++ SET_DID_STATUS(bsg_reply->result, DID_OK);
++ bsg_reply->reply_payload_rcv_len = sg_skip;
++ bsg_job->reply_len = sizeof(struct fc_bsg_reply);
++
++ return 0;
++}
++
++static void __qla_edif_dbell_bsg_done(scsi_qla_host_t *vha, struct bsg_job *bsg_job,
++ u32 delay)
++{
++ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
++
++ /* small sleep for doorbell events to accumulate */
++ if (delay)
++ msleep(delay);
++
++ qla_edif_consume_dbell(vha, bsg_job);
++
++ bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len);
++}
++
++static void qla_edif_dbell_bsg_done(scsi_qla_host_t *vha)
++{
++ unsigned long flags;
++ struct bsg_job *prev_bsg_job = NULL;
++
++ spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
++ if (vha->e_dbell.dbell_bsg_job) {
++ prev_bsg_job = vha->e_dbell.dbell_bsg_job;
++ vha->e_dbell.dbell_bsg_job = NULL;
++ }
++ spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
++
++ if (prev_bsg_job)
++ __qla_edif_dbell_bsg_done(vha, prev_bsg_job, 0);
++}
++
++static int
++qla_edif_dbell_bsg(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
++{
++ unsigned long flags;
++ bool return_bsg = false;
++
++ /* flush previous dbell bsg */
++ qla_edif_dbell_bsg_done(vha);
++
++ spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
++ if (list_empty(&vha->e_dbell.head) && DBELL_ACTIVE(vha)) {
++ /*
++ * when the next db event happens, bsg_job will return.
++ * Otherwise, timer will return it.
++ */
++ vha->e_dbell.dbell_bsg_job = bsg_job;
++ vha->e_dbell.bsg_expire = jiffies + 10 * HZ;
++ } else {
++ return_bsg = true;
++ }
++ spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
++
++ if (return_bsg)
++ __qla_edif_dbell_bsg_done(vha, bsg_job, 1);
++
++ return 0;
++}
++
+ int32_t
+ qla_edif_app_mgmt(struct bsg_job *bsg_job)
+ {
+@@ -1083,8 +1232,13 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
+ bool done = true;
+ int32_t rval = 0;
+ uint32_t vnd_sc = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
++ u32 level = ql_dbg_edif;
+
+- ql_dbg(ql_dbg_edif, vha, 0x911d, "%s vnd subcmd=%x\n",
++ /* doorbell is high traffic */
++ if (vnd_sc == QL_VND_SC_READ_DBELL)
++ level = 0;
++
++ ql_dbg(level, vha, 0x911d, "%s vnd subcmd=%x\n",
+ __func__, vnd_sc);
+
+ sg_copy_to_buffer(bsg_job->request_payload.sg_list,
+@@ -1093,7 +1247,7 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
+
+ if (!vha->hw->flags.edif_enabled ||
+ test_bit(VPORT_DELETE, &vha->dpc_flags)) {
+- ql_dbg(ql_dbg_edif, vha, 0x911d,
++ ql_dbg(level, vha, 0x911d,
+ "%s edif not enabled or vp delete. bsg ptr done %p. dpc_flags %lx\n",
+ __func__, bsg_job, vha->dpc_flags);
+
+@@ -1102,7 +1256,7 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
+ }
+
+ if (!qla_edif_app_check(vha, appcheck)) {
+- ql_dbg(ql_dbg_edif, vha, 0x911d,
++ ql_dbg(level, vha, 0x911d,
+ "%s app checked failed.\n",
+ __func__);
+
+@@ -1137,6 +1291,10 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
+ case QL_VND_SC_AEN_COMPLETE:
+ rval = qla_edif_ack(vha, bsg_job);
+ break;
++ case QL_VND_SC_READ_DBELL:
++ rval = qla_edif_dbell_bsg(vha, bsg_job);
++ done = false;
++ break;
+ default:
+ ql_dbg(ql_dbg_edif, vha, 0x911d, "%s unknown cmd=%x\n",
+ __func__,
+@@ -1148,7 +1306,7 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
+
+ done:
+ if (done) {
+- ql_dbg(ql_dbg_user, vha, 0x7009,
++ ql_dbg(level, vha, 0x7009,
+ "%s: %d bsg ptr done %p\n", __func__, __LINE__, bsg_job);
+ bsg_job_done(bsg_job, bsg_reply->result,
+ bsg_reply->reply_payload_rcv_len);
+@@ -1860,30 +2018,6 @@ qla_edb_init(scsi_qla_host_t *vha)
+ /* initialize lock which protects doorbell & init list */
+ spin_lock_init(&vha->e_dbell.db_lock);
+ INIT_LIST_HEAD(&vha->e_dbell.head);
+-
+- /* create and initialize doorbell */
+- init_completion(&vha->e_dbell.dbell);
+-}
+-
+-static void
+-qla_edb_node_free(scsi_qla_host_t *vha, struct edb_node *node)
+-{
+- /*
+- * releases the space held by this edb node entry
+- * this function does _not_ free the edb node itself
+- * NB: the edb node entry passed should not be on any list
+- *
+- * currently for doorbell there's no additional cleanup
+- * needed, but here as a placeholder for furture use.
+- */
+-
+- if (!node) {
+- ql_dbg(ql_dbg_edif, vha, 0x09122,
+- "%s error - no valid node passed\n", __func__);
+- return;
+- }
+-
+- node->ntype = N_UNDEF;
+ }
+
+ static void qla_edb_clear(scsi_qla_host_t *vha, port_id_t portid)
+@@ -1930,11 +2064,8 @@ static void qla_edb_clear(scsi_qla_host_t *vha, port_id_t portid)
+ }
+ spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
+
+- list_for_each_entry_safe(e, tmp, &edb_list, list) {
++ list_for_each_entry_safe(e, tmp, &edb_list, list)
+ qla_edb_node_free(vha, e);
+- list_del_init(&e->list);
+- kfree(e);
+- }
+ }
+
+ /* function called when app is stopping */
+@@ -1962,14 +2093,10 @@ qla_edb_stop(scsi_qla_host_t *vha)
+ "%s freeing edb_node type=%x\n",
+ __func__, node->ntype);
+ qla_edb_node_free(vha, node);
+- list_del(&node->list);
+-
+- kfree(node);
+ }
+ spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
+
+- /* wake up doorbell waiters - they'll be dismissed with error code */
+- complete_all(&vha->e_dbell.dbell);
++ qla_edif_dbell_bsg_done(vha);
+ }
+
+ static struct edb_node *
+@@ -2007,9 +2134,6 @@ qla_edb_node_add(scsi_qla_host_t *vha, struct edb_node *ptr)
+ list_add_tail(&ptr->list, &vha->e_dbell.head);
+ spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
+
+- /* ring doorbell for waiters */
+- complete(&vha->e_dbell.dbell);
+-
+ return true;
+ }
+
+@@ -2078,43 +2202,24 @@ qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype,
+ default:
+ ql_dbg(ql_dbg_edif, vha, 0x09102,
+ "%s unknown type: %x\n", __func__, dbtype);
+- qla_edb_node_free(vha, edbnode);
+ kfree(edbnode);
+ edbnode = NULL;
+ break;
+ }
+
+- if (edbnode && (!qla_edb_node_add(vha, edbnode))) {
++ if (edbnode) {
++ if (!qla_edb_node_add(vha, edbnode)) {
++ ql_dbg(ql_dbg_edif, vha, 0x09102,
++ "%s unable to add dbnode\n", __func__);
++ kfree(edbnode);
++ return;
++ }
+ ql_dbg(ql_dbg_edif, vha, 0x09102,
+- "%s unable to add dbnode\n", __func__);
+- qla_edb_node_free(vha, edbnode);
+- kfree(edbnode);
+- return;
+- }
+- if (edbnode && fcport)
+- fcport->edif.auth_state = dbtype;
+- ql_dbg(ql_dbg_edif, vha, 0x09102,
+- "%s Doorbell produced : type=%d %p\n", __func__, dbtype, edbnode);
+-}
+-
+-static struct edb_node *
+-qla_edb_getnext(scsi_qla_host_t *vha)
+-{
+- unsigned long flags;
+- struct edb_node *edbnode = NULL;
+-
+- spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
+-
+- /* db nodes are fifo - no qualifications done */
+- if (!list_empty(&vha->e_dbell.head)) {
+- edbnode = list_first_entry(&vha->e_dbell.head,
+- struct edb_node, list);
+- list_del(&edbnode->list);
++ "%s Doorbell produced : type=%d %p\n", __func__, dbtype, edbnode);
++ qla_edif_dbell_bsg_done(vha);
++ if (fcport)
++ fcport->edif.auth_state = dbtype;
+ }
+-
+- spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
+-
+- return edbnode;
+ }
+
+ void
+@@ -2142,6 +2247,9 @@ qla_edif_timer(scsi_qla_host_t *vha)
+ ha->edif_post_stop_cnt_down = 60;
+ }
+ }
++
++ if (vha->e_dbell.dbell_bsg_job && time_after_eq(jiffies, vha->e_dbell.bsg_expire))
++ qla_edif_dbell_bsg_done(vha);
+ }
+
+ /*
+@@ -2209,7 +2317,6 @@ edif_doorbell_show(struct device *dev, struct device_attribute *attr,
+ "%s Doorbell consumed : type=%d %p\n",
+ __func__, dbnode->ntype, dbnode);
+ /* we're done with the db node, so free it up */
+- qla_edb_node_free(vha, dbnode);
+ kfree(dbnode);
+ } else {
+ break;
+diff --git a/drivers/scsi/qla2xxx/qla_edif.h b/drivers/scsi/qla2xxx/qla_edif.h
+index a965ca8e47ce..3561e22b8f0f 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.h
++++ b/drivers/scsi/qla2xxx/qla_edif.h
+@@ -51,7 +51,8 @@ struct edif_dbell {
+ enum db_flags_t db_flags;
+ spinlock_t db_lock;
+ struct list_head head;
+- struct completion dbell;
++ struct bsg_job *dbell_bsg_job;
++ unsigned long bsg_expire;
+ };
+
+ #define SA_UPDATE_IOCB_TYPE 0x71 /* Security Association Update IOCB entry */
+diff --git a/drivers/scsi/qla2xxx/qla_edif_bsg.h b/drivers/scsi/qla2xxx/qla_edif_bsg.h
+index 301523e4f483..110843b13767 100644
+--- a/drivers/scsi/qla2xxx/qla_edif_bsg.h
++++ b/drivers/scsi/qla2xxx/qla_edif_bsg.h
+@@ -183,6 +183,20 @@ struct qla_sa_update_frame {
+ #define QL_VND_SC_GET_FCINFO 7
+ #define QL_VND_SC_GET_STATS 8
+ #define QL_VND_SC_AEN_COMPLETE 9
++#define QL_VND_SC_READ_DBELL 10
++
++/*
++ * bsg caller to provide empty buffer for doorbell events.
++ *
++ * sg_io_v4.din_xferp = empty buffer for door bell events
++ * sg_io_v4.dout_xferp = struct edif_read_dbell *buf
++ */
++struct edif_read_dbell {
++ struct app_id app_info;
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
++ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
++};
+
+
+ /* Application interface data structure for rtn data */
+--
+2.35.1
+
--- /dev/null
+From abfd6a459c1b98d8307475caeaedf8c59b723db3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:23 -0700
+Subject: scsi: qla2xxx: edif: Add retry for ELS passthrough
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 0b3f3143d473b489a7aa0779c43bcdb344bd3014 ]
+
+Relating to EDIF, when sending IKE message, updating key or deleting key,
+driver can encounter IOCB queue full. Add additional retries to reduce
+higher level recovery.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-8-njavali@marvell.com
+Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 52 +++++++++++++++++++++++----------
+ drivers/scsi/qla2xxx/qla_os.c | 2 +-
+ 2 files changed, 38 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index 166647d4ab27..ce893ddb13df 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -1468,6 +1468,8 @@ qla24xx_check_sadb_avail_slot(struct bsg_job *bsg_job, fc_port_t *fcport,
+
+ #define QLA_SA_UPDATE_FLAGS_RX_KEY 0x0
+ #define QLA_SA_UPDATE_FLAGS_TX_KEY 0x2
++#define EDIF_MSLEEP_INTERVAL 100
++#define EDIF_RETRY_COUNT 50
+
+ int
+ qla24xx_sadb_update(struct bsg_job *bsg_job)
+@@ -1480,7 +1482,7 @@ qla24xx_sadb_update(struct bsg_job *bsg_job)
+ struct edif_list_entry *edif_entry = NULL;
+ int found = 0;
+ int rval = 0;
+- int result = 0;
++ int result = 0, cnt;
+ struct qla_sa_update_frame sa_frame;
+ struct srb_iocb *iocb_cmd;
+ port_id_t portid;
+@@ -1721,11 +1723,23 @@ qla24xx_sadb_update(struct bsg_job *bsg_job)
+ sp->done = qla2x00_bsg_job_done;
+ iocb_cmd = &sp->u.iocb_cmd;
+ iocb_cmd->u.sa_update.sa_frame = sa_frame;
+-
++ cnt = 0;
++retry:
+ rval = qla2x00_start_sp(sp);
+- if (rval != QLA_SUCCESS) {
++ switch (rval) {
++ case QLA_SUCCESS:
++ break;
++ case EAGAIN:
++ msleep(EDIF_MSLEEP_INTERVAL);
++ cnt++;
++ if (cnt < EDIF_RETRY_COUNT)
++ goto retry;
++
++ fallthrough;
++ default:
+ ql_log(ql_dbg_edif, vha, 0x70e3,
+- "qla2x00_start_sp failed=%d.\n", rval);
++ "%s qla2x00_start_sp failed=%d.\n",
++ __func__, rval);
+
+ qla2x00_rel_sp(sp);
+ rval = -EIO;
+@@ -2399,7 +2413,6 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
+ rval = qla2x00_start_sp(sp);
+
+ if (rval != QLA_SUCCESS) {
+- rval = QLA_FUNCTION_FAILED;
+ goto done_free_sp;
+ }
+
+@@ -3531,7 +3544,7 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ fc_port_t *fcport = NULL;
+ struct qla_hw_data *ha = vha->hw;
+ srb_t *sp;
+- int rval = (DID_ERROR << 16);
++ int rval = (DID_ERROR << 16), cnt;
+ port_id_t d_id;
+ struct qla_bsg_auth_els_request *p =
+ (struct qla_bsg_auth_els_request *)bsg_job->request;
+@@ -3626,17 +3639,26 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ sp->free = qla2x00_bsg_sp_free;
+ sp->done = qla2x00_bsg_job_done;
+
++ cnt = 0;
++retry:
+ rval = qla2x00_start_sp(sp);
+-
+- ql_dbg(ql_dbg_edif, vha, 0x700a,
+- "%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n",
+- __func__, sc_to_str(p->e.sub_cmd), fcport->port_name,
+- p->e.extra_rx_xchg_address, p->e.extra_control_flags,
+- sp->handle, sp->remap.req.len, bsg_job);
+-
+- if (rval != QLA_SUCCESS) {
++ switch (rval) {
++ case QLA_SUCCESS:
++ ql_dbg(ql_dbg_edif, vha, 0x700a,
++ "%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n",
++ __func__, sc_to_str(p->e.sub_cmd), fcport->port_name,
++ p->e.extra_rx_xchg_address, p->e.extra_control_flags,
++ sp->handle, sp->remap.req.len, bsg_job);
++ break;
++ case EAGAIN:
++ msleep(EDIF_MSLEEP_INTERVAL);
++ cnt++;
++ if (cnt < EDIF_RETRY_COUNT)
++ goto retry;
++ fallthrough;
++ default:
+ ql_log(ql_log_warn, vha, 0x700e,
+- "qla2x00_start_sp failed = %d\n", rval);
++ "%s qla2x00_start_sp failed = %d\n", __func__, rval);
+ SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
+ rval = -EIO;
+ goto done_free_remap_rsp;
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 762229d495a8..3c68dad00d04 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -5473,7 +5473,7 @@ qla2x00_do_work(struct scsi_qla_host *vha)
+ e->u.fcport.fcport, false);
+ break;
+ case QLA_EVT_SA_REPLACE:
+- qla24xx_issue_sa_replace_iocb(vha, e);
++ rc = qla24xx_issue_sa_replace_iocb(vha, e);
+ break;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From cfb7e8d283958632ca8d1f4b75bdd4882135b0a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:18 -0700
+Subject: scsi: qla2xxx: edif: bsg refactor
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 7a7b0b4865d3490f62d6ef1a3aa39fa2b47859a4 ]
+
+ - Add version field to edif bsg for future enhancement.
+
+ - Add version edif bsg version check
+
+ - Remove unused interfaces and fields.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-3-njavali@marvell.com
+Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 32 +++++++---
+ drivers/scsi/qla2xxx/qla_edif_bsg.h | 90 ++++++++++++++++++-----------
+ 2 files changed, 79 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index 30ca56f8e4c8..0978551f85f5 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -280,14 +280,19 @@ qla_edif_app_check(scsi_qla_host_t *vha, struct app_id appid)
+ {
+ /* check that the app is allow/known to the driver */
+
+- if (appid.app_vid == EDIF_APP_ID) {
+- ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x911d, "%s app id ok\n", __func__);
+- return true;
++ if (appid.app_vid != EDIF_APP_ID) {
++ ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app id not ok (%x)",
++ __func__, appid.app_vid);
++ return false;
++ }
++
++ if (appid.version != EDIF_VERSION1) {
++ ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app version is not ok (%x)",
++ __func__, appid.version);
++ return false;
+ }
+- ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app id not ok (%x)",
+- __func__, appid.app_vid);
+
+- return false;
++ return true;
+ }
+
+ static void
+@@ -555,6 +560,7 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ appreply.host_support_edif = vha->hw->flags.edif_enabled;
+ appreply.edif_enode_active = vha->pur_cinfo.enode_flags;
+ appreply.edif_edb_active = vha->e_dbell.db_flags;
++ appreply.version = EDIF_VERSION1;
+
+ bsg_job->reply_len = sizeof(struct fc_bsg_reply);
+
+@@ -685,6 +691,7 @@ qla_edif_app_authok(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ portid.b.area = appplogiok.u.d_id.b.area;
+ portid.b.al_pa = appplogiok.u.d_id.b.al_pa;
+
++ appplogireply.version = EDIF_VERSION1;
+ switch (appplogiok.type) {
+ case PL_TYPE_WWPN:
+ fcport = qla2x00_find_fcport_by_wwpn(vha,
+@@ -877,6 +884,8 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ } else {
+ struct fc_port *fcport = NULL, *tf;
+
++ app_reply->version = EDIF_VERSION1;
++
+ list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
+ if (!(fcport->flags & FCF_FCSP_DEVICE))
+ continue;
+@@ -893,9 +902,6 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ if (tdid.b24 != 0 && tdid.b24 != fcport->d_id.b24)
+ continue;
+
+- app_reply->ports[pcnt].rekey_count =
+- fcport->edif.rekey_cnt;
+-
+ if (fcport->scan_state != QLA_FCPORT_FOUND)
+ continue;
+
+@@ -910,6 +916,7 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+
+ rval = 0;
+
++ app_reply->ports[pcnt].version = EDIF_VERSION1;
+ app_reply->ports[pcnt].remote_type =
+ VND_CMD_RTYPE_UNKNOWN;
+ if (fcport->port_type & (FCT_NVME_TARGET | FCT_TARGET))
+@@ -1006,6 +1013,8 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ } else {
+ struct fc_port *fcport = NULL, *tf;
+
++ app_reply->version = EDIF_VERSION1;
++
+ list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
+ if (fcport->edif.enable) {
+ if (pcnt > app_req.num_ports)
+@@ -2037,6 +2046,7 @@ qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype,
+ edbnode->u.sa_aen.port_id = fcport->d_id;
+ edbnode->u.sa_aen.status = data;
+ edbnode->u.sa_aen.key_type = data2;
++ edbnode->u.sa_aen.version = EDIF_VERSION1;
+ break;
+ default:
+ ql_dbg(ql_dbg_edif, vha, 0x09102,
+@@ -3380,6 +3390,10 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ port_id_t d_id;
+ struct qla_bsg_auth_els_request *p =
+ (struct qla_bsg_auth_els_request *)bsg_job->request;
++ struct qla_bsg_auth_els_reply *rpl =
++ (struct qla_bsg_auth_els_reply *)bsg_job->reply;
++
++ rpl->version = EDIF_VERSION1;
+
+ d_id.b.al_pa = bsg_request->rqst_data.h_els.port_id[2];
+ d_id.b.area = bsg_request->rqst_data.h_els.port_id[1];
+diff --git a/drivers/scsi/qla2xxx/qla_edif_bsg.h b/drivers/scsi/qla2xxx/qla_edif_bsg.h
+index 5a26c77157da..301523e4f483 100644
+--- a/drivers/scsi/qla2xxx/qla_edif_bsg.h
++++ b/drivers/scsi/qla2xxx/qla_edif_bsg.h
+@@ -7,13 +7,15 @@
+ #ifndef __QLA_EDIF_BSG_H
+ #define __QLA_EDIF_BSG_H
+
++#define EDIF_VERSION1 1
++
+ /* BSG Vendor specific commands */
+ #define ELS_MAX_PAYLOAD 2112
+ #ifndef WWN_SIZE
+ #define WWN_SIZE 8
+ #endif
+-#define VND_CMD_APP_RESERVED_SIZE 32
+-
++#define VND_CMD_APP_RESERVED_SIZE 28
++#define VND_CMD_PAD_SIZE 3
+ enum auth_els_sub_cmd {
+ SEND_ELS = 0,
+ SEND_ELS_REPLY,
+@@ -28,7 +30,9 @@ struct extra_auth_els {
+ #define BSG_CTL_FLAG_LS_ACC 1
+ #define BSG_CTL_FLAG_LS_RJT 2
+ #define BSG_CTL_FLAG_TRM 3
+- uint8_t extra_rsvd[3];
++ uint8_t version;
++ uint8_t pad[2];
++ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+ } __packed;
+
+ struct qla_bsg_auth_els_request {
+@@ -39,51 +43,46 @@ struct qla_bsg_auth_els_request {
+ struct qla_bsg_auth_els_reply {
+ struct fc_bsg_reply r;
+ uint32_t rx_xchg_address;
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
++ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+ };
+
+ struct app_id {
+ int app_vid;
+- uint8_t app_key[32];
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
++ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+ } __packed;
+
+ struct app_start_reply {
+ uint32_t host_support_edif;
+ uint32_t edif_enode_active;
+ uint32_t edif_edb_active;
+- uint32_t reserved[VND_CMD_APP_RESERVED_SIZE];
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
++ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+ } __packed;
+
+ struct app_start {
+ struct app_id app_info;
+- uint32_t prli_to;
+- uint32_t key_shred;
+ uint8_t app_start_flags;
+- uint8_t reserved[VND_CMD_APP_RESERVED_SIZE - 1];
++ uint8_t version;
++ uint8_t pad[2];
++ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+ } __packed;
+
+ struct app_stop {
+ struct app_id app_info;
+- char buf[16];
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
++ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+ } __packed;
+
+ struct app_plogi_reply {
+ uint32_t prli_status;
+- uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+-} __packed;
+-
+-#define RECFG_TIME 1
+-#define RECFG_BYTES 2
+-
+-struct app_rekey_cfg {
+- struct app_id app_info;
+- uint8_t rekey_mode;
+- port_id_t d_id;
+- uint8_t force;
+- union {
+- int64_t bytes;
+- int64_t time;
+- } rky_units;
+-
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
+ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+ } __packed;
+
+@@ -91,7 +90,9 @@ struct app_pinfo_req {
+ struct app_id app_info;
+ uint8_t num_ports;
+ port_id_t remote_pid;
+- uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
++ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+ } __packed;
+
+ struct app_pinfo {
+@@ -103,11 +104,8 @@ struct app_pinfo {
+ #define VND_CMD_RTYPE_INITIATOR 2
+ uint8_t remote_state;
+ uint8_t auth_state;
+- uint8_t rekey_mode;
+- int64_t rekey_count;
+- int64_t rekey_config_value;
+- int64_t rekey_consumed_value;
+-
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
+ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+ } __packed;
+
+@@ -120,6 +118,8 @@ struct app_pinfo {
+
+ struct app_pinfo_reply {
+ uint8_t port_count;
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
+ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+ struct app_pinfo ports[];
+ } __packed;
+@@ -127,6 +127,8 @@ struct app_pinfo_reply {
+ struct app_sinfo_req {
+ struct app_id app_info;
+ uint8_t num_ports;
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
+ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+ } __packed;
+
+@@ -140,6 +142,9 @@ struct app_sinfo {
+
+ struct app_stats_reply {
+ uint8_t elem_count;
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
++ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+ struct app_sinfo elem[];
+ } __packed;
+
+@@ -163,9 +168,11 @@ struct qla_sa_update_frame {
+ uint8_t node_name[WWN_SIZE];
+ uint8_t port_name[WWN_SIZE];
+ port_id_t port_id;
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
++ uint8_t reserved2[VND_CMD_APP_RESERVED_SIZE];
+ } __packed;
+
+-// used for edif mgmt bsg interface
+ #define QL_VND_SC_UNDEF 0
+ #define QL_VND_SC_SA_UPDATE 1
+ #define QL_VND_SC_APP_START 2
+@@ -175,6 +182,8 @@ struct qla_sa_update_frame {
+ #define QL_VND_SC_REKEY_CONFIG 6
+ #define QL_VND_SC_GET_FCINFO 7
+ #define QL_VND_SC_GET_STATS 8
++#define QL_VND_SC_AEN_COMPLETE 9
++
+
+ /* Application interface data structure for rtn data */
+ #define EXT_DEF_EVENT_DATA_SIZE 64
+@@ -191,7 +200,9 @@ struct edif_sa_update_aen {
+ port_id_t port_id;
+ uint32_t key_type; /* Tx (1) or RX (2) */
+ uint32_t status; /* 0 succes, 1 failed, 2 timeout , 3 error */
+- uint8_t reserved[16];
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
++ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+ } __packed;
+
+ #define QL_VND_SA_STAT_SUCCESS 0
+@@ -212,7 +223,18 @@ struct auth_complete_cmd {
+ uint8_t wwpn[WWN_SIZE];
+ port_id_t d_id;
+ } u;
+- uint32_t reserved[VND_CMD_APP_RESERVED_SIZE];
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
++ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
++} __packed;
++
++struct aen_complete_cmd {
++ struct app_id app_info;
++ port_id_t port_id;
++ uint32_t event_code;
++ uint8_t version;
++ uint8_t pad[VND_CMD_PAD_SIZE];
++ uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];
+ } __packed;
+
+ #define RX_DELAY_DELETE_TIMEOUT 20
+--
+2.35.1
+
--- /dev/null
+From 9a7a7c777fcd88ccf37139222f1b7d822672d710 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:25 -0700
+Subject: scsi: qla2xxx: edif: Fix n2n discovery issue with secure target
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 789d54a4178634850e441f60c0326124138e7269 ]
+
+User failed to see disk via n2n topology. Driver used up all login retries
+before authentication application started. When authentication application
+started, driver did not have enough login retries to connect securely. On
+app_start, driver will reset the login retry attempt count.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-10-njavali@marvell.com
+Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index ce893ddb13df..c17e177864d3 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -515,6 +515,9 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ }
+
+ if (N2N_TOPO(vha->hw)) {
++ list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list)
++ fcport->n2n_link_reset_cnt = 0;
++
+ if (vha->hw->flags.n2n_fw_acc_sec)
+ set_bit(N2N_LINK_RESET, &vha->dpc_flags);
+ else
+--
+2.35.1
+
--- /dev/null
+From bb9c860b38aacf63d3733e20bad88736939675a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:26 -0700
+Subject: scsi: qla2xxx: edif: Fix n2n login retry for secure device
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit aec55325ddec975216119da000092cb8664a3399 ]
+
+After initiator has burned up all login retries, target authentication
+application begins to run. This triggers a link bounce on target side.
+Initiator will attempt another login. Due to N2N, the PRLI [nvme | fcp] can
+fail because of the mode mismatch with target. This patch add a few more
+login retries to revive the connection.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-11-njavali@marvell.com
+Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_init.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index 5f077f9217e5..177ce45b76a6 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -2123,6 +2123,13 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
+ }
+
+ if (N2N_TOPO(vha->hw)) {
++ if (ea->fcport->n2n_link_reset_cnt ==
++ vha->hw->login_retry_count &&
++ ea->fcport->flags & FCF_FCSP_DEVICE) {
++ /* remote authentication app just started */
++ ea->fcport->n2n_link_reset_cnt = 0;
++ }
++
+ if (ea->fcport->n2n_link_reset_cnt <
+ vha->hw->login_retry_count) {
+ ea->fcport->n2n_link_reset_cnt++;
+--
+2.35.1
+
--- /dev/null
+From b923006e845a5edf2e4dee24c3a5456b6a1b365d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 04:58:43 -0700
+Subject: scsi: qla2xxx: edif: Fix no login after app start
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 24c796098f5395477f7f7ebf8e24f3f08a139f71 ]
+
+The scenario is this: User loaded driver but has not started authentication
+app. All sessions to secure device will exhaust all login attempts, fail,
+and in stay in deleted state. Then some time later the app is started. The
+driver will replenish the login retry count, trigger delete to prepare for
+secure login. After deletion, relogin is triggered.
+
+For the session that is already deleted, the delete trigger is a no-op. If
+none of the sessions trigger a relogin, no progress is made.
+
+Add a relogin trigger.
+
+Link: https://lore.kernel.org/r/20220608115849.16693-5-njavali@marvell.com
+Fixes: 7ebb336e45ef ("scsi: qla2xxx: edif: Add start + stop bsgs")
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index 208a16cb54f0..9020cc3c61df 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -567,6 +567,7 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ qlt_schedule_sess_for_deletion(fcport);
+ qla_edif_sa_ctl_init(vha, fcport);
+ }
++ set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+ }
+
+ if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) {
+--
+2.35.1
+
--- /dev/null
+From e022411bb676deb3f8795d0097159a82b3d94ed9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 04:58:46 -0700
+Subject: scsi: qla2xxx: edif: Fix no logout on delete for N2N
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit ec538eb838f334453b10e7e9b260f0c358018a37 ]
+
+The driver failed to send implicit logout on session delete. For edif, this
+failed to flush any lingering SA index in FW.
+
+Set a flag to turn on implicit logout early in the session recovery to make
+sure the logout will go out in case of error.
+
+Link: https://lore.kernel.org/r/20220608115849.16693-8-njavali@marvell.com
+Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF")
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_iocb.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
+index 46c879923da1..42ce4e1fe744 100644
+--- a/drivers/scsi/qla2xxx/qla_iocb.c
++++ b/drivers/scsi/qla2xxx/qla_iocb.c
+@@ -2882,6 +2882,9 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
+ sp->name, res, sp->handle, fcport->d_id.b24, fcport->port_name);
+
+ fcport->flags &= ~(FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE);
++ /* For edif, set logout on delete to ensure any residual key from FW is flushed.*/
++ fcport->logout_on_delete = 1;
++ fcport->chip_reset = vha->hw->base_qpair->chip_reset;
+
+ if (sp->flags & SRB_WAKEUP_ON_COMP)
+ complete(&lio->u.els_plogi.comp);
+--
+2.35.1
+
--- /dev/null
+From 4fdbd30e8fb9f3c13caf8a41f0d1914c720a66d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:21 -0700
+Subject: scsi: qla2xxx: edif: Fix potential stuck session in sa update
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit e0fb8ce2bb9e52c846e54ad2c58b5b7beb13eb09 ]
+
+When a thread is in the process of reestablish a session, a flag is set to
+prevent multiple threads/triggers from doing the same task. This flag was
+left on, and any attempt to relogin was locked out. Clear this flag if the
+attempt has failed.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-6-njavali@marvell.com
+Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index d9e3f145b162..166647d4ab27 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -2332,6 +2332,7 @@ edif_doorbell_show(struct device *dev, struct device_attribute *attr,
+
+ static void qla_noop_sp_done(srb_t *sp, int res)
+ {
++ sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
+ /* ref: INIT */
+ kref_put(&sp->cmd_kref, qla2x00_sp_release);
+ }
+@@ -2356,7 +2357,8 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
+ if (!sa_ctl) {
+ ql_dbg(ql_dbg_edif, vha, 0x70e6,
+ "sa_ctl allocation failed\n");
+- return -ENOMEM;
++ rval = -ENOMEM;
++ goto done;
+ }
+
+ fcport = sa_ctl->fcport;
+@@ -2366,7 +2368,8 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
+ if (!sp) {
+ ql_dbg(ql_dbg_edif, vha, 0x70e6,
+ "SRB allocation failed\n");
+- return -ENOMEM;
++ rval = -ENOMEM;
++ goto done;
+ }
+
+ fcport->flags |= FCF_ASYNC_SENT;
+@@ -2395,9 +2398,17 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
+
+ rval = qla2x00_start_sp(sp);
+
+- if (rval != QLA_SUCCESS)
++ if (rval != QLA_SUCCESS) {
+ rval = QLA_FUNCTION_FAILED;
++ goto done_free_sp;
++ }
+
++ return rval;
++done_free_sp:
++ kref_put(&sp->cmd_kref, qla2x00_sp_release);
++ fcport->flags &= ~FCF_ASYNC_SENT;
++done:
++ fcport->flags &= ~FCF_ASYNC_ACTIVE;
+ return rval;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 3fca1c4b47ba586586e67873012d185b5407d793 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 04:58:45 -0700
+Subject: scsi: qla2xxx: edif: Fix session thrash
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit a8fdfb0b39c2b31722c70bdf2272b949d5af4b7b ]
+
+Current code prematurely sends out PRLI before authentication application
+has given the OK to do so. This causes PRLI failure and session teardown.
+
+Prevents PRLI from going out before authentication app gives the OK.
+
+Link: https://lore.kernel.org/r/20220608115849.16693-7-njavali@marvell.com
+Fixes: 91f6f5fbe87b ("scsi: qla2xxx: edif: Reduce connection thrash")
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 2 +-
+ drivers/scsi/qla2xxx/qla_edif.h | 4 ++++
+ drivers/scsi/qla2xxx/qla_init.c | 10 +++++++++-
+ 3 files changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index 9020cc3c61df..3f886b86d74a 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -3589,7 +3589,7 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ if (qla_bsg_check(vha, bsg_job, fcport))
+ return 0;
+
+- if (fcport->loop_id == FC_NO_LOOP_ID) {
++ if (EDIF_SESS_DELETE(fcport)) {
+ ql_dbg(ql_dbg_edif, vha, 0x910d,
+ "%s ELS code %x, no loop id.\n", __func__,
+ bsg_request->rqst_data.r_els.els_code);
+diff --git a/drivers/scsi/qla2xxx/qla_edif.h b/drivers/scsi/qla2xxx/qla_edif.h
+index 3561e22b8f0f..7cdb89ccdc6e 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.h
++++ b/drivers/scsi/qla2xxx/qla_edif.h
+@@ -141,4 +141,8 @@ struct enode {
+ (DBELL_ACTIVE(_fcport->vha) && \
+ (_fcport->disc_state == DSC_LOGIN_AUTH_PEND))
+
++#define EDIF_SESS_DELETE(_s) \
++ (qla_ini_mode_enabled(_s->vha) && (_s->disc_state == DSC_DELETE_PEND || \
++ _s->disc_state == DSC_DELETED))
++
+ #endif /* __QLA_EDIF_H */
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index 177ce45b76a6..7bd10b4ed9ed 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -1762,8 +1762,16 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
+ break;
+
+ case DSC_LOGIN_PEND:
+- if (fcport->fw_login_state == DSC_LS_PLOGI_COMP)
++ if (vha->hw->flags.edif_enabled)
++ break;
++
++ if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) {
++ ql_dbg(ql_dbg_disc, vha, 0x2118,
++ "%s %d %8phC post %s PRLI\n",
++ __func__, __LINE__, fcport->port_name,
++ NVME_TARGET(vha->hw, fcport) ? "NVME" : "FC");
+ qla24xx_post_prli_work(vha, fcport);
++ }
+ break;
+
+ case DSC_UPD_FCPORT:
+--
+2.35.1
+
--- /dev/null
+From f461294c5024f89231f6edf7cd4cf1159beb9682 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 04:58:42 -0700
+Subject: scsi: qla2xxx: edif: Reduce disruption due to multiple app start
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 0dbfce5255fe8d069a1a3b712a25b263264cfa58 ]
+
+Multiple app start can trigger a session bounce. Make driver skip over
+session teardown if app start is seen more than once.
+
+Link: https://lore.kernel.org/r/20220608115849.16693-4-njavali@marvell.com
+Fixes: 7ebb336e45ef ("scsi: qla2xxx: edif: Add start + stop bsgs")
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index 0ead3d95f594..208a16cb54f0 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -510,8 +510,7 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ /* mark doorbell as active since an app is now present */
+ vha->e_dbell.db_flags |= EDB_ACTIVE;
+ } else {
+- ql_dbg(ql_dbg_edif, vha, 0x911e, "%s doorbell already active\n",
+- __func__);
++ goto out;
+ }
+
+ if (N2N_TOPO(vha->hw)) {
+@@ -578,6 +577,7 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ __func__);
+ }
+
++out:
+ appreply.host_support_edif = vha->hw->flags.edif_enabled;
+ appreply.edif_enode_active = vha->pur_cinfo.enode_flags;
+ appreply.edif_edb_active = vha->e_dbell.db_flags;
+--
+2.35.1
+
--- /dev/null
+From 55cced8d4dbe32419a69bb7198d35047f94e5757 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:17 -0700
+Subject: scsi: qla2xxx: edif: Reduce Initiator-Initiator thrashing
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 9c40c36e75ffd49952cd4ead0672defc4b4dbdf7 ]
+
+This patch uses GFFID switch command to scan whether remote device is
+Target or Initiator mode. Based on that info, driver will not pass up
+Initiator info to authentication application. This helps reduce unnecessary
+stress for authentication application to deal with unused connections.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-2-njavali@marvell.com
+Fixes: 7ebb336e45ef ("scsi: qla2xxx: edif: Add start + stop bsgs")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_def.h | 2 +
+ drivers/scsi/qla2xxx/qla_edif.c | 32 ++++++++-
+ drivers/scsi/qla2xxx/qla_gbl.h | 3 +-
+ drivers/scsi/qla2xxx/qla_gs.c | 118 +++++++++++++++++++++++---------
+ drivers/scsi/qla2xxx/qla_iocb.c | 2 +-
+ 5 files changed, 120 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index f25a131fb07e..5f22276927dd 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -3204,6 +3204,8 @@ struct ct_sns_rsp {
+ #define GFF_NVME_OFFSET 23 /* type = 28h */
+ struct {
+ uint8_t fc4_features[128];
++#define FC4_FF_TARGET BIT_0
++#define FC4_FF_INITIATOR BIT_1
+ } gff_id;
+ struct {
+ uint8_t reserved;
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index 0628633c7c7e..30ca56f8e4c8 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -517,16 +517,28 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ if (atomic_read(&vha->loop_state) == LOOP_DOWN)
+ break;
+
+- fcport->edif.app_started = 1;
+ fcport->login_retry = vha->hw->login_retry_count;
+
+- /* no activity */
+ fcport->edif.app_stop = 0;
++ fcport->edif.app_sess_online = 0;
++ fcport->edif.app_started = 1;
++
++ if (fcport->scan_state != QLA_FCPORT_FOUND)
++ continue;
++
++ if (fcport->port_type == FCT_UNKNOWN &&
++ !fcport->fc4_features)
++ rval = qla24xx_async_gffid(vha, fcport, true);
++
++ if (!rval && !(fcport->fc4_features & FC4_FF_TARGET ||
++ fcport->port_type & (FCT_TARGET|FCT_NVME_TARGET)))
++ continue;
++
++ rval = 0;
+
+ ql_dbg(ql_dbg_edif, vha, 0x911e,
+ "%s wwpn %8phC calling qla_edif_reset_auth_wait\n",
+ __func__, fcport->port_name);
+- fcport->edif.app_sess_online = 0;
+ qlt_schedule_sess_for_deletion(fcport);
+ qla_edif_sa_ctl_init(vha, fcport);
+ }
+@@ -884,6 +896,20 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ app_reply->ports[pcnt].rekey_count =
+ fcport->edif.rekey_cnt;
+
++ if (fcport->scan_state != QLA_FCPORT_FOUND)
++ continue;
++
++ if (fcport->port_type == FCT_UNKNOWN && !fcport->fc4_features)
++ rval = qla24xx_async_gffid(vha, fcport, true);
++
++ if (!rval &&
++ !(fcport->fc4_features & FC4_FF_TARGET ||
++ fcport->port_type &
++ (FCT_TARGET | FCT_NVME_TARGET)))
++ continue;
++
++ rval = 0;
++
+ app_reply->ports[pcnt].remote_type =
+ VND_CMD_RTYPE_UNKNOWN;
+ if (fcport->port_type & (FCT_NVME_TARGET | FCT_TARGET))
+diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
+index dac27b5ff0ac..84b44454c231 100644
+--- a/drivers/scsi/qla2xxx/qla_gbl.h
++++ b/drivers/scsi/qla2xxx/qla_gbl.h
+@@ -335,6 +335,7 @@ extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *);
+ extern int qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha,
+ struct qla_work_evt *e);
+ void qla2x00_sp_release(struct kref *kref);
++void qla2x00_els_dcmd2_iocb_timeout(void *data);
+
+ /*
+ * Global Function Prototypes in qla_mbx.c source file.
+@@ -727,7 +728,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *, fc_port_t *);
+ void qla24xx_handle_gpsc_event(scsi_qla_host_t *, struct event_arg *);
+ int qla2x00_mgmt_svr_login(scsi_qla_host_t *);
+ void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea);
+-int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport);
++int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool);
+ int qla24xx_async_gpnft(scsi_qla_host_t *, u8, srb_t *);
+ void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *);
+ void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *);
+diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
+index f8005ce65082..574251b2e0ef 100644
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -3277,19 +3277,12 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
+ return rval;
+ }
+
+-void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea)
+-{
+- fc_port_t *fcport = ea->fcport;
+-
+- qla24xx_post_gnl_work(vha, fcport);
+-}
+
+ void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
+ {
+ struct scsi_qla_host *vha = sp->vha;
+ fc_port_t *fcport = sp->fcport;
+ struct ct_sns_rsp *ct_rsp;
+- struct event_arg ea;
+ uint8_t fc4_scsi_feat;
+ uint8_t fc4_nvme_feat;
+
+@@ -3297,10 +3290,10 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
+ "Async done-%s res %x ID %x. %8phC\n",
+ sp->name, res, fcport->d_id.b24, fcport->port_name);
+
+- fcport->flags &= ~FCF_ASYNC_SENT;
+- ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
++ ct_rsp = sp->u.iocb_cmd.u.ctarg.rsp;
+ fc4_scsi_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
+ fc4_nvme_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
++ sp->rc = res;
+
+ /*
+ * FC-GS-7, 5.2.3.12 FC-4 Features - format
+@@ -3321,24 +3314,42 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
+ }
+ }
+
+- memset(&ea, 0, sizeof(ea));
+- ea.sp = sp;
+- ea.fcport = sp->fcport;
+- ea.rc = res;
++ if (sp->flags & SRB_WAKEUP_ON_COMP) {
++ complete(sp->comp);
++ } else {
++ if (sp->u.iocb_cmd.u.ctarg.req) {
++ dma_free_coherent(&vha->hw->pdev->dev,
++ sp->u.iocb_cmd.u.ctarg.req_allocated_size,
++ sp->u.iocb_cmd.u.ctarg.req,
++ sp->u.iocb_cmd.u.ctarg.req_dma);
++ sp->u.iocb_cmd.u.ctarg.req = NULL;
++ }
+
+- qla24xx_handle_gffid_event(vha, &ea);
+- /* ref: INIT */
+- kref_put(&sp->cmd_kref, qla2x00_sp_release);
++ if (sp->u.iocb_cmd.u.ctarg.rsp) {
++ dma_free_coherent(&vha->hw->pdev->dev,
++ sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
++ sp->u.iocb_cmd.u.ctarg.rsp,
++ sp->u.iocb_cmd.u.ctarg.rsp_dma);
++ sp->u.iocb_cmd.u.ctarg.rsp = NULL;
++ }
++
++ /* ref: INIT */
++ kref_put(&sp->cmd_kref, qla2x00_sp_release);
++ /* we should not be here */
++ dump_stack();
++ }
+ }
+
+ /* Get FC4 Feature with Nport ID. */
+-int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
++int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool wait)
+ {
+ int rval = QLA_FUNCTION_FAILED;
+ struct ct_sns_req *ct_req;
+ srb_t *sp;
++ DECLARE_COMPLETION_ONSTACK(comp);
+
+- if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
++ /* this routine does not have handling for no wait */
++ if (!vha->flags.online || !wait)
+ return rval;
+
+ /* ref: INIT */
+@@ -3346,43 +3357,86 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
+ if (!sp)
+ return rval;
+
+- fcport->flags |= FCF_ASYNC_SENT;
+ sp->type = SRB_CT_PTHRU_CMD;
+ sp->name = "gffid";
+ sp->gen1 = fcport->rscn_gen;
+ sp->gen2 = fcport->login_gen;
+ qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
+ qla24xx_async_gffid_sp_done);
++ sp->comp = ∁
++ sp->u.iocb_cmd.timeout = qla2x00_els_dcmd2_iocb_timeout;
++
++ if (wait)
++ sp->flags = SRB_WAKEUP_ON_COMP;
++
++ sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
++ sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
++ sp->u.iocb_cmd.u.ctarg.req_allocated_size,
++ &sp->u.iocb_cmd.u.ctarg.req_dma,
++ GFP_KERNEL);
++ if (!sp->u.iocb_cmd.u.ctarg.req) {
++ ql_log(ql_log_warn, vha, 0xd041,
++ "%s: Failed to allocate ct_sns request.\n",
++ __func__);
++ goto done_free_sp;
++ }
++
++ sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
++ sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
++ sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
++ &sp->u.iocb_cmd.u.ctarg.rsp_dma,
++ GFP_KERNEL);
++ if (!sp->u.iocb_cmd.u.ctarg.req) {
++ ql_log(ql_log_warn, vha, 0xd041,
++ "%s: Failed to allocate ct_sns request.\n",
++ __func__);
++ goto done_free_sp;
++ }
+
+ /* CT_IU preamble */
+- ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFF_ID_CMD,
+- GFF_ID_RSP_SIZE);
++ ct_req = qla2x00_prep_ct_req(sp->u.iocb_cmd.u.ctarg.req, GFF_ID_CMD, GFF_ID_RSP_SIZE);
+
+ ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain;
+ ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area;
+ ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa;
+
+- sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
+- sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
+- sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
+- sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
+ sp->u.iocb_cmd.u.ctarg.req_size = GFF_ID_REQ_SIZE;
+ sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE;
+ sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
+
+- ql_dbg(ql_dbg_disc, vha, 0x2132,
+- "Async-%s hdl=%x %8phC.\n", sp->name,
+- sp->handle, fcport->port_name);
+-
+ rval = qla2x00_start_sp(sp);
+- if (rval != QLA_SUCCESS)
++
++ if (rval != QLA_SUCCESS) {
++ rval = QLA_FUNCTION_FAILED;
+ goto done_free_sp;
++ } else {
++ ql_dbg(ql_dbg_disc, vha, 0x3074,
++ "Async-%s hdl=%x portid %06x\n",
++ sp->name, sp->handle, fcport->d_id.b24);
++ }
++
++ wait_for_completion(sp->comp);
++ rval = sp->rc;
+
+- return rval;
+ done_free_sp:
++ if (sp->u.iocb_cmd.u.ctarg.req) {
++ dma_free_coherent(&vha->hw->pdev->dev,
++ sp->u.iocb_cmd.u.ctarg.req_allocated_size,
++ sp->u.iocb_cmd.u.ctarg.req,
++ sp->u.iocb_cmd.u.ctarg.req_dma);
++ sp->u.iocb_cmd.u.ctarg.req = NULL;
++ }
++
++ if (sp->u.iocb_cmd.u.ctarg.rsp) {
++ dma_free_coherent(&vha->hw->pdev->dev,
++ sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
++ sp->u.iocb_cmd.u.ctarg.rsp,
++ sp->u.iocb_cmd.u.ctarg.rsp_dma);
++ sp->u.iocb_cmd.u.ctarg.rsp = NULL;
++ }
++
+ /* ref: INIT */
+ kref_put(&sp->cmd_kref, qla2x00_sp_release);
+- fcport->flags &= ~FCF_ASYNC_SENT;
+ return rval;
+ }
+
+diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
+index e0fe9ddb4bd2..46c879923da1 100644
+--- a/drivers/scsi/qla2xxx/qla_iocb.c
++++ b/drivers/scsi/qla2xxx/qla_iocb.c
+@@ -2819,7 +2819,7 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
+ sp->vha->qla_stats.control_requests++;
+ }
+
+-static void
++void
+ qla2x00_els_dcmd2_iocb_timeout(void *data)
+ {
+ srb_t *sp = data;
+--
+2.35.1
+
--- /dev/null
+From 5cae13ffbaf59b8c799508b0a4b9155ce4c12323 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 04:58:47 -0700
+Subject: scsi: qla2xxx: edif: Reduce N2N thrashing at app_start time
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 37be3f9d6993a721bc019f03c97ea0fe66319997 ]
+
+For N2N + remote WWPN is bigger than local adapter, remote adapter will
+login to local adapter while authentication application is not running.
+When authentication application starts, the current session in FW needs to
+to be invalidated.
+
+Make sure the old session is torn down before triggering a relogin.
+
+Link: https://lore.kernel.org/r/20220608115849.16693-9-njavali@marvell.com
+Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF")
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 47 ++++++++++++++++++++++++---------
+ 1 file changed, 34 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index 3f886b86d74a..dbe8ef887a9d 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -517,11 +517,28 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list)
+ fcport->n2n_link_reset_cnt = 0;
+
+- if (vha->hw->flags.n2n_fw_acc_sec)
+- set_bit(N2N_LINK_RESET, &vha->dpc_flags);
+- else
++ if (vha->hw->flags.n2n_fw_acc_sec) {
++ list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list)
++ qla_edif_sa_ctl_init(vha, fcport);
++
++ /*
++ * While authentication app was not running, remote device
++ * could still try to login with this local port. Let's
++ * clear the state and try again.
++ */
++ qla2x00_wait_for_sess_deletion(vha);
++
++ /* bounce the link to get the other guy to relogin */
++ if (!vha->hw->flags.n2n_bigger) {
++ set_bit(N2N_LINK_RESET, &vha->dpc_flags);
++ qla2xxx_wake_dpc(vha);
++ }
++ } else {
++ qla2x00_wait_for_hba_online(vha);
+ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+- qla2xxx_wake_dpc(vha);
++ qla2xxx_wake_dpc(vha);
++ qla2x00_wait_for_hba_online(vha);
++ }
+ } else {
+ list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
+ ql_dbg(ql_dbg_edif, vha, 0x2058,
+@@ -921,17 +938,21 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ if (tdid.b24 != 0 && tdid.b24 != fcport->d_id.b24)
+ continue;
+
+- if (fcport->scan_state != QLA_FCPORT_FOUND)
+- continue;
++ if (!N2N_TOPO(vha->hw)) {
++ if (fcport->scan_state != QLA_FCPORT_FOUND)
++ continue;
+
+- if (fcport->port_type == FCT_UNKNOWN && !fcport->fc4_features)
+- rval = qla24xx_async_gffid(vha, fcport, true);
++ if (fcport->port_type == FCT_UNKNOWN &&
++ !fcport->fc4_features)
++ rval = qla24xx_async_gffid(vha, fcport,
++ true);
+
+- if (!rval &&
+- !(fcport->fc4_features & FC4_FF_TARGET ||
+- fcport->port_type &
+- (FCT_TARGET | FCT_NVME_TARGET)))
+- continue;
++ if (!rval &&
++ !(fcport->fc4_features & FC4_FF_TARGET ||
++ fcport->port_type &
++ (FCT_TARGET | FCT_NVME_TARGET)))
++ continue;
++ }
+
+ rval = 0;
+
+--
+2.35.1
+
--- /dev/null
+From 60a5b9e3eb1f8df3c97a5b2d6c1965b56b940148 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 04:58:41 -0700
+Subject: scsi: qla2xxx: edif: Send LOGO for unexpected IKE message
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 2b659ed67a12f39f56d8dcad9b5d5a74d67c01b3 ]
+
+If the session is down and the local port continues to receive AUTH ELS
+messages, the driver needs to send back LOGO so that the remote device
+knows to tear down its session. Terminate and clean up the AUTH ELS
+exchange followed by a passthrough LOGO.
+
+Link: https://lore.kernel.org/r/20220608115849.16693-3-njavali@marvell.com
+Fixes: 225479296c4f ("scsi: qla2xxx: edif: Reject AUTH ELS on session down")
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif.c | 19 +++++++++++++++++--
+ drivers/scsi/qla2xxx/qla_fw.h | 2 +-
+ 2 files changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index c17e177864d3..0ead3d95f594 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -2644,8 +2644,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
+
+ fcport = qla2x00_find_fcport_by_pid(host, &purex->pur_info.pur_sid);
+
+- if (DBELL_INACTIVE(vha) ||
+- (fcport && EDIF_SESSION_DOWN(fcport))) {
++ if (DBELL_INACTIVE(vha)) {
+ ql_dbg(ql_dbg_edif, host, 0x0910c, "%s e_dbell.db_flags =%x %06x\n",
+ __func__, host->e_dbell.db_flags,
+ fcport ? fcport->d_id.b24 : 0);
+@@ -2655,6 +2654,22 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
+ return;
+ }
+
++ if (fcport && EDIF_SESSION_DOWN(fcport)) {
++ ql_dbg(ql_dbg_edif, host, 0x13b6,
++ "%s terminate exchange. Send logo to 0x%x\n",
++ __func__, a.did.b24);
++
++ a.tx_byte_count = a.tx_len = 0;
++ a.tx_addr = 0;
++ a.control_flags = EPD_RX_XCHG; /* EPD_RX_XCHG = terminate cmd */
++ qla_els_reject_iocb(host, (*rsp)->qpair, &a);
++ qla_enode_free(host, ptr);
++ /* send logo to let remote port knows to tear down session */
++ fcport->send_els_logo = 1;
++ qlt_schedule_sess_for_deletion(fcport);
++ return;
++ }
++
+ /* add the local enode to the list */
+ qla_enode_add(host, ptr);
+
+diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
+index 0bb1d562f0bf..361015b5763e 100644
+--- a/drivers/scsi/qla2xxx/qla_fw.h
++++ b/drivers/scsi/qla2xxx/qla_fw.h
+@@ -807,7 +807,7 @@ struct els_entry_24xx {
+ #define EPD_ELS_COMMAND (0 << 13)
+ #define EPD_ELS_ACC (1 << 13)
+ #define EPD_ELS_RJT (2 << 13)
+-#define EPD_RX_XCHG (3 << 13)
++#define EPD_RX_XCHG (3 << 13) /* terminate exchange */
+ #define ECF_CLR_PASSTHRU_PEND BIT_12
+ #define ECF_INCL_FRAME_HDR BIT_11
+ #define ECF_SEC_LOGIN BIT_3
+--
+2.35.1
+
--- /dev/null
+From 1bbca7908638370f44b39549038dd4cc7d1ef9d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:22 -0700
+Subject: scsi: qla2xxx: edif: Synchronize NPIV deletion with authentication
+ application
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit cf79716e6636400ae38c37bc8a652b1e522abbba ]
+
+Notify authentication application of a NPIV deletion event is about to
+occur. This allows app to perform cleanup.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-7-njavali@marvell.com
+Fixes: 9efea843a906 ("scsi: qla2xxx: edif: Add detection of secure device")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_edif_bsg.h | 2 ++
+ drivers/scsi/qla2xxx/qla_mid.c | 6 +++++-
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_edif_bsg.h b/drivers/scsi/qla2xxx/qla_edif_bsg.h
+index 110843b13767..0931f4e4e127 100644
+--- a/drivers/scsi/qla2xxx/qla_edif_bsg.h
++++ b/drivers/scsi/qla2xxx/qla_edif_bsg.h
+@@ -253,4 +253,6 @@ struct aen_complete_cmd {
+
+ #define RX_DELAY_DELETE_TIMEOUT 20
+
++#define FCH_EVT_VENDOR_UNIQUE_VPORT_DOWN 1
++
+ #endif /* QLA_EDIF_BSG_H */
+diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
+index e6b5c4ccce97..eb43a5f1b399 100644
+--- a/drivers/scsi/qla2xxx/qla_mid.c
++++ b/drivers/scsi/qla2xxx/qla_mid.c
+@@ -166,9 +166,13 @@ qla24xx_disable_vp(scsi_qla_host_t *vha)
+ int ret = QLA_SUCCESS;
+ fc_port_t *fcport;
+
+- if (vha->hw->flags.edif_enabled)
++ if (vha->hw->flags.edif_enabled) {
++ if (DBELL_ACTIVE(vha))
++ qla2x00_post_aen_work(vha, FCH_EVT_VENDOR_UNIQUE,
++ FCH_EVT_VENDOR_UNIQUE_VPORT_DOWN);
+ /* delete sessions and flush sa_indexes */
+ qla2x00_wait_for_sess_deletion(vha);
++ }
+
+ if (vha->hw->flags.fw_started)
+ ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
+--
+2.35.1
+
--- /dev/null
+From 0ebad32bac672a8f32ad523f2a61637052f30bf7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 04:58:44 -0700
+Subject: scsi: qla2xxx: edif: Tear down session if keys have been removed
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit d7e2e4a68fc047a025afcd200e6b7e1fbc8b1999 ]
+
+If all keys for a session have been deleted, trigger a session teardown.
+
+Link: https://lore.kernel.org/r/20220608115849.16693-6-njavali@marvell.com
+Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update")
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_def.h | 5 +++++
+ drivers/scsi/qla2xxx/qla_isr.c | 1 +
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index c2b92a6fef90..4062d46f33a6 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -2158,6 +2158,11 @@ typedef struct {
+ #define CS_IOCB_ERROR 0x31 /* Generic error for IOCB request
+ failure */
+ #define CS_REJECT_RECEIVED 0x4E /* Reject received */
++#define CS_EDIF_AUTH_ERROR 0x63 /* decrypt error */
++#define CS_EDIF_PAD_LEN_ERROR 0x65 /* pad > frame size, not 4byte align */
++#define CS_EDIF_INV_REQ 0x66 /* invalid request */
++#define CS_EDIF_SPI_ERROR 0x67 /* rx frame unable to locate sa */
++#define CS_EDIF_HDR_ERROR 0x69 /* data frame != expected len */
+ #define CS_BAD_PAYLOAD 0x80 /* Driver defined */
+ #define CS_UNKNOWN 0x81 /* Driver defined */
+ #define CS_RETRY 0x82 /* Driver defined */
+diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
+index 5deea6bff09f..ad55eace66aa 100644
+--- a/drivers/scsi/qla2xxx/qla_isr.c
++++ b/drivers/scsi/qla2xxx/qla_isr.c
+@@ -3424,6 +3424,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
+ case CS_PORT_UNAVAILABLE:
+ case CS_TIMEOUT:
+ case CS_RESET:
++ case CS_EDIF_INV_REQ:
+
+ /*
+ * We are going to have the fc class block the rport
+--
+2.35.1
+
--- /dev/null
+From 6da317fd4701e18c5416f32f2f44b8ff73fdb751 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 21:46:19 -0700
+Subject: scsi: qla2xxx: edif: Wait for app to ack on sess down
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit df648afa39da9c4d3af99c6c03dc3e9c7dfa99b0 ]
+
+On session deletion, wait for app to acknowledge before moving on. This
+allows both app and driver to stay in sync. In addition, this gives a
+chance for authentication app to do any type of cleanup before moving on.
+
+Link: https://lore.kernel.org/r/20220607044627.19563-4-njavali@marvell.com
+Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update")
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_def.h | 2 +-
+ drivers/scsi/qla2xxx/qla_edif.c | 66 +++++++++++++++++++++++++------
+ drivers/scsi/qla2xxx/qla_init.c | 4 --
+ drivers/scsi/qla2xxx/qla_target.c | 35 ++++++++--------
+ 4 files changed, 74 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index 5f22276927dd..c2b92a6fef90 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -2626,7 +2626,6 @@ typedef struct fc_port {
+ struct {
+ uint32_t enable:1; /* device is edif enabled/req'd */
+ uint32_t app_stop:2;
+- uint32_t app_started:1;
+ uint32_t aes_gmac:1;
+ uint32_t app_sess_online:1;
+ uint32_t tx_sa_set:1;
+@@ -2637,6 +2636,7 @@ typedef struct fc_port {
+ uint32_t rx_rekey_cnt;
+ uint64_t tx_bytes;
+ uint64_t rx_bytes;
++ uint8_t sess_down_acked;
+ uint8_t auth_state;
+ uint16_t authok:1;
+ uint16_t rekey_cnt;
+diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c
+index 0978551f85f5..034c43a8bb9b 100644
+--- a/drivers/scsi/qla2xxx/qla_edif.c
++++ b/drivers/scsi/qla2xxx/qla_edif.c
+@@ -257,14 +257,8 @@ qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id)
+
+ f = NULL;
+ list_for_each_entry_safe(f, tf, &vha->vp_fcports, list) {
+- if ((f->flags & FCF_FCSP_DEVICE)) {
+- ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x2058,
+- "Found secure fcport - nn %8phN pn %8phN portid=0x%x, 0x%x.\n",
+- f->node_name, f->port_name,
+- f->d_id.b24, id->b24);
+- if (f->d_id.b24 == id->b24)
+- return f;
+- }
++ if (f->d_id.b24 == id->b24)
++ return f;
+ }
+ return NULL;
+ }
+@@ -526,7 +520,6 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+
+ fcport->edif.app_stop = 0;
+ fcport->edif.app_sess_online = 0;
+- fcport->edif.app_started = 1;
+
+ if (fcport->scan_state != QLA_FCPORT_FOUND)
+ continue;
+@@ -628,9 +621,6 @@ qla_edif_app_stop(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+
+ fcport->send_els_logo = 1;
+ qlt_schedule_sess_for_deletion(fcport);
+-
+- /* qla_edif_flush_sa_ctl_lists(fcport); */
+- fcport->edif.app_started = 0;
+ }
+ }
+
+@@ -1048,6 +1038,40 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+ return rval;
+ }
+
++static int32_t
++qla_edif_ack(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
++{
++ struct fc_port *fcport;
++ struct aen_complete_cmd ack;
++ struct fc_bsg_reply *bsg_reply = bsg_job->reply;
++
++ sg_copy_to_buffer(bsg_job->request_payload.sg_list,
++ bsg_job->request_payload.sg_cnt, &ack, sizeof(ack));
++
++ ql_dbg(ql_dbg_edif, vha, 0x70cf,
++ "%s: %06x event_code %x\n",
++ __func__, ack.port_id.b24, ack.event_code);
++
++ fcport = qla2x00_find_fcport_by_pid(vha, &ack.port_id);
++ SET_DID_STATUS(bsg_reply->result, DID_OK);
++
++ if (!fcport) {
++ ql_dbg(ql_dbg_edif, vha, 0x70cf,
++ "%s: unable to find fcport %06x \n",
++ __func__, ack.port_id.b24);
++ return 0;
++ }
++
++ switch (ack.event_code) {
++ case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
++ fcport->edif.sess_down_acked = 1;
++ break;
++ default:
++ break;
++ }
++ return 0;
++}
++
+ int32_t
+ qla_edif_app_mgmt(struct bsg_job *bsg_job)
+ {
+@@ -1110,6 +1134,9 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job)
+ case QL_VND_SC_GET_STATS:
+ rval = qla_edif_app_getstats(vha, bsg_job);
+ break;
++ case QL_VND_SC_AEN_COMPLETE:
++ rval = qla_edif_ack(vha, bsg_job);
++ break;
+ default:
+ ql_dbg(ql_dbg_edif, vha, 0x911d, "%s unknown cmd=%x\n",
+ __func__,
+@@ -3513,14 +3540,29 @@ int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
+
+ void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess)
+ {
++ u16 cnt = 0;
++
+ if (sess->edif.app_sess_online && DBELL_ACTIVE(vha)) {
+ ql_dbg(ql_dbg_disc, vha, 0xf09c,
+ "%s: sess %8phN send port_offline event\n",
+ __func__, sess->port_name);
+ sess->edif.app_sess_online = 0;
++ sess->edif.sess_down_acked = 0;
+ qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SESSION_SHUTDOWN,
+ sess->d_id.b24, 0, sess);
+ qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24);
++
++ while (!READ_ONCE(sess->edif.sess_down_acked) &&
++ !test_bit(VPORT_DELETE, &vha->dpc_flags)) {
++ msleep(100);
++ cnt++;
++ if (cnt > 100)
++ break;
++ }
++ sess->edif.sess_down_acked = 0;
++ ql_dbg(ql_dbg_disc, vha, 0xf09c,
++ "%s: sess %8phN port_offline event completed\n",
++ __func__, sess->port_name);
+ }
+ }
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index 4c0f76021c47..5f077f9217e5 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -1480,7 +1480,6 @@ static int qla_chk_secure_login(scsi_qla_host_t *vha, fc_port_t *fcport,
+ ql_dbg(ql_dbg_disc, vha, 0x20ef,
+ "%s %d %8phC EDIF: post DB_AUTH: AUTH needed\n",
+ __func__, __LINE__, fcport->port_name);
+- fcport->edif.app_started = 1;
+ fcport->edif.app_sess_online = 1;
+
+ qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_NEEDED,
+@@ -5275,9 +5274,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
+ INIT_LIST_HEAD(&fcport->edif.tx_sa_list);
+ INIT_LIST_HEAD(&fcport->edif.rx_sa_list);
+
+- if (vha->e_dbell.db_flags == EDB_ACTIVE)
+- fcport->edif.app_started = 1;
+-
+ spin_lock_init(&fcport->edif.indx_list_lock);
+ INIT_LIST_HEAD(&fcport->edif.edif_indx_list);
+
+diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
+index 6dfcfd8e7337..34b85c80233f 100644
+--- a/drivers/scsi/qla2xxx/qla_target.c
++++ b/drivers/scsi/qla2xxx/qla_target.c
+@@ -988,22 +988,6 @@ void qlt_free_session_done(struct work_struct *work)
+ sess->send_els_logo);
+
+ if (!IS_SW_RESV_ADDR(sess->d_id)) {
+- if (ha->flags.edif_enabled &&
+- (!own || own->iocb.u.isp24.status_subcode == ELS_PLOGI)) {
+- sess->edif.authok = 0;
+- if (!ha->flags.host_shutting_down) {
+- ql_dbg(ql_dbg_edif, vha, 0x911e,
+- "%s wwpn %8phC calling qla2x00_release_all_sadb\n",
+- __func__, sess->port_name);
+- qla2x00_release_all_sadb(vha, sess);
+- } else {
+- ql_dbg(ql_dbg_edif, vha, 0x911e,
+- "%s bypassing release_all_sadb\n",
+- __func__);
+- }
+- qla_edif_clear_appdata(vha, sess);
+- qla_edif_sess_down(vha, sess);
+- }
+ qla2x00_mark_device_lost(vha, sess, 0);
+
+ if (sess->send_els_logo) {
+@@ -1049,6 +1033,25 @@ void qlt_free_session_done(struct work_struct *work)
+ sess->nvme_flag |= NVME_FLAG_DELETING;
+ qla_nvme_unregister_remote_port(sess);
+ }
++
++ if (ha->flags.edif_enabled &&
++ (!own || (own &&
++ own->iocb.u.isp24.status_subcode == ELS_PLOGI))) {
++ sess->edif.authok = 0;
++ if (!ha->flags.host_shutting_down) {
++ ql_dbg(ql_dbg_edif, vha, 0x911e,
++ "%s wwpn %8phC calling qla2x00_release_all_sadb\n",
++ __func__, sess->port_name);
++ qla2x00_release_all_sadb(vha, sess);
++ } else {
++ ql_dbg(ql_dbg_edif, vha, 0x911e,
++ "%s bypassing release_all_sadb\n",
++ __func__);
++ }
++
++ qla_edif_clear_appdata(vha, sess);
++ qla_edif_sess_down(vha, sess);
++ }
+ }
+
+ /*
+--
+2.35.1
+
--- /dev/null
+From 4284057c7d83c5eb16019800b3be3fe2ed005982 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 13:47:36 -0500
+Subject: scsi: smartpqi: Fix DMA direction for RAID requests
+
+From: Mahesh Rajashekhara <Mahesh.Rajashekhara@microchip.com>
+
+[ Upstream commit 69695aeaa6621bc49cdd7a8e5a8d1042461e496e ]
+
+Correct a SOP READ and WRITE DMA flags for some requests.
+
+This update corrects DMA direction issues with SCSI commands removed from
+the controller's internal lookup table.
+
+Currently, SCSI READ BLOCK LIMITS (0x5) was removed from the controller
+lookup table and exposed a DMA direction flag issue.
+
+SCSI READ BLOCK LIMITS was recently removed from our controller lookup
+table so the controller uses the respective IU flag field to set the DMA
+data direction. Since the DMA direction is incorrect the FW never completes
+the request causing a hang.
+
+Some SCSI commands which use SCSI READ BLOCK LIMITS
+
+ * sg_map
+ * mt -f /dev/stX status
+
+After updating controller firmware, users may notice their tape units
+failing. This patch resolves the issue.
+
+Also, the AIO path DMA direction is correct.
+
+The DMA direction flag is a day-one bug with no reported BZ.
+
+Fixes: 6c223761eb54 ("smartpqi: initial commit of Microsemi smartpqi driver")
+Link: https://lore.kernel.org/r/165730605618.177165.9054223644512926624.stgit@brunhilda
+Reviewed-by: Scott Benesh <scott.benesh@microchip.com>
+Reviewed-by: Scott Teel <scott.teel@microchip.com>
+Reviewed-by: Mike McGowen <mike.mcgowen@microchip.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microchip.com>
+Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@microchip.com>
+Signed-off-by: Don Brace <don.brace@microchip.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 7c0d069a3158..e1fc6f5b9612 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -5484,10 +5484,10 @@ static int pqi_raid_submit_scsi_cmd_with_io_request(
+ }
+
+ switch (scmd->sc_data_direction) {
+- case DMA_TO_DEVICE:
++ case DMA_FROM_DEVICE:
+ request->data_direction = SOP_READ_FLAG;
+ break;
+- case DMA_FROM_DEVICE:
++ case DMA_TO_DEVICE:
+ request->data_direction = SOP_WRITE_FLAG;
+ break;
+ case DMA_NONE:
+--
+2.35.1
+
--- /dev/null
+From 08640cd7240d59040f0a9cb97979d737add7b22a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 12:04:14 +0300
+Subject: selftest/vm: uninitialized variable in main()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 360b420dbded8ad5b70a41de98e77354dd9e7d36 ]
+
+Initialize "length" to zero by default.
+
+Link: https://lkml.kernel.org/r/YtZzjvHXVXMXxpXO@kili
+Fixes: ff712a627f72 ("selftests/vm: cleanup hugetlb file after mremap test")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Mina Almasry <almasrymina@google.com>
+Reviewed-by: Muchun Song <songmuchun@bytedance.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/vm/hugepage-mremap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/vm/hugepage-mremap.c b/tools/testing/selftests/vm/hugepage-mremap.c
+index 1d689084a54b..22546f279534 100644
+--- a/tools/testing/selftests/vm/hugepage-mremap.c
++++ b/tools/testing/selftests/vm/hugepage-mremap.c
+@@ -107,7 +107,7 @@ static void register_region_with_uffd(char *addr, size_t len)
+
+ int main(int argc, char *argv[])
+ {
+- size_t length;
++ size_t length = 0;
+
+ if (argc != 2 && argc != 3) {
+ printf("Usage: %s [length_in_MB] <hugetlb_file>\n", argv[0]);
+--
+2.35.1
+
--- /dev/null
+From a981a65373281f953b9b7bd16090f104f94ebe90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 12:50:32 +0300
+Subject: selftests/bpf: fix a test for snprintf() overflow
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit c5d22f4cfe8dfb93f1db0a1e7e2e7ebc41395d98 ]
+
+The snprintf() function returns the number of bytes which *would*
+have been copied if there were space. In other words, it can be
+> sizeof(pin_path).
+
+Fixes: c0fa1b6c3efc ("bpf: btf: Add BTF tests")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Martin KaFai Lau <kafai@fb.com>
+Link: https://lore.kernel.org/r/YtZ+aD/tZMkgOUw+@kili
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/btf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/btf.c b/tools/testing/selftests/bpf/prog_tests/btf.c
+index ec823561b912..a294176f8a9d 100644
+--- a/tools/testing/selftests/bpf/prog_tests/btf.c
++++ b/tools/testing/selftests/bpf/prog_tests/btf.c
+@@ -5226,7 +5226,7 @@ static void do_test_pprint(int test_num)
+ ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
+ "/sys/fs/bpf", test->map_name);
+
+- if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
++ if (CHECK(ret >= sizeof(pin_path), "pin_path %s/%s is too long",
+ "/sys/fs/bpf", test->map_name)) {
+ err = -1;
+ goto done;
+--
+2.35.1
+
--- /dev/null
+From 5690fc28f64a31839c2bdb42833f05bebe59da64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jun 2022 09:01:16 +0200
+Subject: selftests/bpf: Fix rare segfault in sock_fields prog test
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jörn-Thorben Hinz <jthinz@mailbox.tu-berlin.de>
+
+[ Upstream commit 6dc7a0baf1a70b7d22662d38481824c14ddd80c5 ]
+
+test_sock_fields__detach() got called with a null pointer here when one
+of the CHECKs or ASSERTs up to the test_sock_fields__open_and_load()
+call resulted in a jump to the "done" label.
+
+A skeletons *__detach() is not safe to call with a null pointer, though.
+This led to a segfault.
+
+Go the easy route and only call test_sock_fields__destroy() which is
+null-pointer safe and includes detaching.
+
+Came across this while looking[1] to introduce the usage of
+bpf_tcp_helpers.h (included in progs/test_sock_fields.c) together with
+vmlinux.h.
+
+[1] https://lore.kernel.org/bpf/629bc069dd807d7ac646f836e9dca28bbc1108e2.camel@mailbox.tu-berlin.de/
+
+Fixes: 8f50f16ff39d ("selftests/bpf: Extend verifier and bpf_sock tests for dst_port loads")
+Signed-off-by: Jörn-Thorben Hinz <jthinz@mailbox.tu-berlin.de>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
+Reviewed-by: Martin KaFai Lau <kafai@fb.com>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20220621070116.307221-1-jthinz@mailbox.tu-berlin.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/sock_fields.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/sock_fields.c b/tools/testing/selftests/bpf/prog_tests/sock_fields.c
+index 9d211b5c22c4..7d23166c77af 100644
+--- a/tools/testing/selftests/bpf/prog_tests/sock_fields.c
++++ b/tools/testing/selftests/bpf/prog_tests/sock_fields.c
+@@ -394,7 +394,6 @@ void serial_test_sock_fields(void)
+ test();
+
+ done:
+- test_sock_fields__detach(skel);
+ test_sock_fields__destroy(skel);
+ if (child_cg_fd >= 0)
+ close(child_cg_fd);
+--
+2.35.1
+
--- /dev/null
+From bf08a5811436e8fcdd5666a8db24cf76ed29f05d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Jun 2022 16:40:50 -0700
+Subject: selftests/bpf: Fix tc_redirect_dtime
+
+From: Martin KaFai Lau <kafai@fb.com>
+
+[ Upstream commit e6ff92f41b65fce07365f1066fb13b5e42aca08d ]
+
+tc_redirect_dtime was reported flaky from time to time. It
+always fails at the udp test and complains about the bpf@tc-ingress
+got a skb->tstamp when handling udp packet. It is unexpected
+because the skb->tstamp should have been cleared when crossing
+different netns.
+
+The most likely cause is that the skb is actually a tcp packet
+from the earlier tcp test. It could be the final TCP_FIN handling.
+
+This patch tightens the skb->tstamp check in the bpf prog. It ensures
+the skb is the current testing traffic. First, it checks that skb
+matches the IPPROTO of the running test (i.e. tcp vs udp).
+Second, it checks the server port (dst_ns_port). The server
+port is unique for each test (50000 + test_enum).
+
+Also fixed a typo in test_udp_dtime(): s/P100/P101/
+
+Fixes: c803475fd8dd ("bpf: selftests: test skb->tstamp in redirect_neigh")
+Reported-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Martin KaFai Lau <kafai@fb.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Song Liu <songliubraving@fb.com>
+Link: https://lore.kernel.org/bpf/20220601234050.2572671-1-kafai@fb.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/bpf/prog_tests/tc_redirect.c | 8 +--
+ .../selftests/bpf/progs/test_tc_dtime.c | 53 ++++++++++++++++++-
+ 2 files changed, 55 insertions(+), 6 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/tc_redirect.c b/tools/testing/selftests/bpf/prog_tests/tc_redirect.c
+index 7ad66a247c02..b2e415647bd7 100644
+--- a/tools/testing/selftests/bpf/prog_tests/tc_redirect.c
++++ b/tools/testing/selftests/bpf/prog_tests/tc_redirect.c
+@@ -646,7 +646,7 @@ static void test_tcp_clear_dtime(struct test_tc_dtime *skel)
+ __u32 *errs = skel->bss->errs[t];
+
+ skel->bss->test = t;
+- test_inet_dtime(AF_INET6, SOCK_STREAM, IP6_DST, 0);
++ test_inet_dtime(AF_INET6, SOCK_STREAM, IP6_DST, 50000 + t);
+
+ ASSERT_EQ(dtimes[INGRESS_FWDNS_P100], 0,
+ dtime_cnt_str(t, INGRESS_FWDNS_P100));
+@@ -683,7 +683,7 @@ static void test_tcp_dtime(struct test_tc_dtime *skel, int family, bool bpf_fwd)
+ errs = skel->bss->errs[t];
+
+ skel->bss->test = t;
+- test_inet_dtime(family, SOCK_STREAM, addr, 0);
++ test_inet_dtime(family, SOCK_STREAM, addr, 50000 + t);
+
+ /* fwdns_prio100 prog does not read delivery_time_type, so
+ * kernel puts the (rcv) timetamp in __sk_buff->tstamp
+@@ -715,13 +715,13 @@ static void test_udp_dtime(struct test_tc_dtime *skel, int family, bool bpf_fwd)
+ errs = skel->bss->errs[t];
+
+ skel->bss->test = t;
+- test_inet_dtime(family, SOCK_DGRAM, addr, 0);
++ test_inet_dtime(family, SOCK_DGRAM, addr, 50000 + t);
+
+ ASSERT_EQ(dtimes[INGRESS_FWDNS_P100], 0,
+ dtime_cnt_str(t, INGRESS_FWDNS_P100));
+ /* non mono delivery time is not forwarded */
+ ASSERT_EQ(dtimes[INGRESS_FWDNS_P101], 0,
+- dtime_cnt_str(t, INGRESS_FWDNS_P100));
++ dtime_cnt_str(t, INGRESS_FWDNS_P101));
+ for (i = EGRESS_FWDNS_P100; i < SET_DTIME; i++)
+ ASSERT_GT(dtimes[i], 0, dtime_cnt_str(t, i));
+
+diff --git a/tools/testing/selftests/bpf/progs/test_tc_dtime.c b/tools/testing/selftests/bpf/progs/test_tc_dtime.c
+index 06f300d06dbd..b596479a9ebe 100644
+--- a/tools/testing/selftests/bpf/progs/test_tc_dtime.c
++++ b/tools/testing/selftests/bpf/progs/test_tc_dtime.c
+@@ -11,6 +11,8 @@
+ #include <linux/in.h>
+ #include <linux/ip.h>
+ #include <linux/ipv6.h>
++#include <linux/tcp.h>
++#include <linux/udp.h>
+ #include <bpf/bpf_helpers.h>
+ #include <bpf/bpf_endian.h>
+ #include <sys/socket.h>
+@@ -115,6 +117,19 @@ static bool bpf_fwd(void)
+ return test < TCP_IP4_RT_FWD;
+ }
+
++static __u8 get_proto(void)
++{
++ switch (test) {
++ case UDP_IP4:
++ case UDP_IP6:
++ case UDP_IP4_RT_FWD:
++ case UDP_IP6_RT_FWD:
++ return IPPROTO_UDP;
++ default:
++ return IPPROTO_TCP;
++ }
++}
++
+ /* -1: parse error: TC_ACT_SHOT
+ * 0: not testing traffic: TC_ACT_OK
+ * >0: first byte is the inet_proto, second byte has the netns
+@@ -122,11 +137,16 @@ static bool bpf_fwd(void)
+ */
+ static int skb_get_type(struct __sk_buff *skb)
+ {
++ __u16 dst_ns_port = __bpf_htons(50000 + test);
+ void *data_end = ctx_ptr(skb->data_end);
+ void *data = ctx_ptr(skb->data);
+ __u8 inet_proto = 0, ns = 0;
+ struct ipv6hdr *ip6h;
++ __u16 sport, dport;
+ struct iphdr *iph;
++ struct tcphdr *th;
++ struct udphdr *uh;
++ void *trans;
+
+ switch (skb->protocol) {
+ case __bpf_htons(ETH_P_IP):
+@@ -138,6 +158,7 @@ static int skb_get_type(struct __sk_buff *skb)
+ else if (iph->saddr == ip4_dst)
+ ns = DST_NS;
+ inet_proto = iph->protocol;
++ trans = iph + 1;
+ break;
+ case __bpf_htons(ETH_P_IPV6):
+ ip6h = data + sizeof(struct ethhdr);
+@@ -148,15 +169,43 @@ static int skb_get_type(struct __sk_buff *skb)
+ else if (v6_equal(ip6h->saddr, (struct in6_addr)ip6_dst))
+ ns = DST_NS;
+ inet_proto = ip6h->nexthdr;
++ trans = ip6h + 1;
+ break;
+ default:
+ return 0;
+ }
+
+- if ((inet_proto != IPPROTO_TCP && inet_proto != IPPROTO_UDP) || !ns)
++ /* skb is not from src_ns or dst_ns.
++ * skb is not the testing IPPROTO.
++ */
++ if (!ns || inet_proto != get_proto())
+ return 0;
+
+- return (ns << 8 | inet_proto);
++ switch (inet_proto) {
++ case IPPROTO_TCP:
++ th = trans;
++ if (th + 1 > data_end)
++ return -1;
++ sport = th->source;
++ dport = th->dest;
++ break;
++ case IPPROTO_UDP:
++ uh = trans;
++ if (uh + 1 > data_end)
++ return -1;
++ sport = uh->source;
++ dport = uh->dest;
++ break;
++ default:
++ return 0;
++ }
++
++ /* The skb is the testing traffic */
++ if ((ns == SRC_NS && dport == dst_ns_port) ||
++ (ns == DST_NS && sport == dst_ns_port))
++ return (ns << 8 | inet_proto);
++
++ return 0;
+ }
+
+ /* format: direction@iface@netns
+--
+2.35.1
+
--- /dev/null
+From 9b5d2fcfe2244c1a3614853acde2a5017e5d2063 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 May 2022 23:13:29 +0800
+Subject: selftests/bpf: Fix test_run logic in fexit_stress.c
+
+From: Yuntao Wang <ytcoode@gmail.com>
+
+[ Upstream commit eb7b36ce47f830a01ad9405e673b563cc3638d5d ]
+
+In the commit da00d2f117a0 ("bpf: Add test ops for BPF_PROG_TYPE_TRACING"),
+the bpf_fentry_test1 function was moved into bpf_prog_test_run_tracing(),
+which is the test_run function of the tracing BPF programs.
+
+Thus calling 'bpf_prog_test_run_opts(filter_fd, &topts)' will not trigger
+bpf_fentry_test1 function as filter_fd is a sk_filter BPF program.
+
+Fix it by replacing filter_fd with fexit_fd in the bpf_prog_test_run_opts()
+function.
+
+Fixes: da00d2f117a0 ("bpf: Add test ops for BPF_PROG_TYPE_TRACING")
+Signed-off-by: Yuntao Wang <ytcoode@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20220521151329.648013-1-ytcoode@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/bpf/prog_tests/fexit_stress.c | 32 +++----------------
+ 1 file changed, 4 insertions(+), 28 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/fexit_stress.c b/tools/testing/selftests/bpf/prog_tests/fexit_stress.c
+index 3ee2107bbf7a..58b03d1a70c8 100644
+--- a/tools/testing/selftests/bpf/prog_tests/fexit_stress.c
++++ b/tools/testing/selftests/bpf/prog_tests/fexit_stress.c
+@@ -7,11 +7,9 @@
+
+ void test_fexit_stress(void)
+ {
+- char test_skb[128] = {};
+ int fexit_fd[CNT] = {};
+ int link_fd[CNT] = {};
+- char error[4096];
+- int err, i, filter_fd;
++ int err, i;
+
+ const struct bpf_insn trace_program[] = {
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+@@ -20,25 +18,9 @@ void test_fexit_stress(void)
+
+ LIBBPF_OPTS(bpf_prog_load_opts, trace_opts,
+ .expected_attach_type = BPF_TRACE_FEXIT,
+- .log_buf = error,
+- .log_size = sizeof(error),
+ );
+
+- const struct bpf_insn skb_program[] = {
+- BPF_MOV64_IMM(BPF_REG_0, 0),
+- BPF_EXIT_INSN(),
+- };
+-
+- LIBBPF_OPTS(bpf_prog_load_opts, skb_opts,
+- .log_buf = error,
+- .log_size = sizeof(error),
+- );
+-
+- LIBBPF_OPTS(bpf_test_run_opts, topts,
+- .data_in = test_skb,
+- .data_size_in = sizeof(test_skb),
+- .repeat = 1,
+- );
++ LIBBPF_OPTS(bpf_test_run_opts, topts);
+
+ err = libbpf_find_vmlinux_btf_id("bpf_fentry_test1",
+ trace_opts.expected_attach_type);
+@@ -58,15 +40,9 @@ void test_fexit_stress(void)
+ goto out;
+ }
+
+- filter_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL",
+- skb_program, sizeof(skb_program) / sizeof(struct bpf_insn),
+- &skb_opts);
+- if (!ASSERT_GE(filter_fd, 0, "test_program_loaded"))
+- goto out;
++ err = bpf_prog_test_run_opts(fexit_fd[0], &topts);
++ ASSERT_OK(err, "bpf_prog_test_run_opts");
+
+- err = bpf_prog_test_run_opts(filter_fd, &topts);
+- close(filter_fd);
+- CHECK_FAIL(err);
+ out:
+ for (i = 0; i < CNT; i++) {
+ if (link_fd[i])
+--
+2.35.1
+
--- /dev/null
+From 9b05d8c196047a5c813e312cdad53d52934e6cb1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 16:02:40 -0700
+Subject: selftests: kvm: set rax before vmcall
+
+From: Andrei Vagin <avagin@google.com>
+
+[ Upstream commit 281106f938d3daaea6f8b6723a8217a2a1ef6936 ]
+
+kvm_hypercall has to place the hypercall number in rax.
+
+Trace events show that kvm_pv_test doesn't work properly:
+ kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0
+ kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0
+ kvm_pv_test-53132: kvm_hypercall: nr 0x0 a0 0x0 a1 0x0 a2 0x0 a3 0x0
+
+With this change, it starts working as expected:
+ kvm_pv_test-54285: kvm_hypercall: nr 0x5 a0 0x0 a1 0x0 a2 0x0 a3 0x0
+ kvm_pv_test-54285: kvm_hypercall: nr 0xa a0 0x0 a1 0x0 a2 0x0 a3 0x0
+ kvm_pv_test-54285: kvm_hypercall: nr 0xb a0 0x0 a1 0x0 a2 0x0 a3 0x0
+
+Signed-off-by: Andrei Vagin <avagin@google.com>
+Message-Id: <20220722230241.1944655-5-avagin@google.com>
+Fixes: ac4a4d6de22e ("selftests: kvm: test enforcement of paravirtual cpuid features")
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/kvm/lib/x86_64/processor.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
+index 33ea5e9955d9..b9984124a294 100644
+--- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
++++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
+@@ -1423,7 +1423,7 @@ uint64_t kvm_hypercall(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a2,
+
+ asm volatile("vmcall"
+ : "=a"(r)
+- : "b"(a0), "c"(a1), "d"(a2), "S"(a3));
++ : "a"(nr), "b"(a0), "c"(a1), "d"(a2), "S"(a3));
+ return r;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From f5723f277e8ece485fb626b13b829189d543003e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 16:32:33 -0400
+Subject: selftests/livepatch: better synchronize test_klp_callbacks_busy
+
+From: Joe Lawrence <joe.lawrence@redhat.com>
+
+[ Upstream commit 55eb9a6c8bf3e2099863118ef53e02d9f44f85a8 ]
+
+The test_klp_callbacks_busy module conditionally blocks a future
+livepatch transition by busy waiting inside its workqueue function,
+busymod_work_func(). After scheduling this work, a test livepatch is
+loaded, introducing the transition under test.
+
+Both events are marked in the kernel log for later verification, but
+there is no synchronization to ensure that busymod_work_func() logs its
+function entry message before subsequent selftest commands log their own
+messages. This can lead to a rare test failure due to unexpected
+ordering like:
+
+ --- expected
+ +++ result
+ @@ -1,7 +1,7 @@
+ % modprobe test_klp_callbacks_busy block_transition=Y
+ test_klp_callbacks_busy: test_klp_callbacks_busy_init
+ -test_klp_callbacks_busy: busymod_work_func enter
+ % modprobe test_klp_callbacks_demo
+ +test_klp_callbacks_busy: busymod_work_func enter
+ livepatch: enabling patch 'test_klp_callbacks_demo'
+ livepatch: 'test_klp_callbacks_demo': initializing patching transition
+ test_klp_callbacks_demo: pre_patch_callback: vmlinux
+
+Force the module init function to wait until busymod_work_func() has
+started (and logged its message), before exiting to the next selftest
+steps.
+
+Fixes: 547840bd5ae5 ("selftests/livepatch: simplify test-klp-callbacks busy target tests")
+Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
+Reviewed-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Link: https://lore.kernel.org/r/20220602203233.979681-1-joe.lawrence@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/livepatch/test_klp_callbacks_busy.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/lib/livepatch/test_klp_callbacks_busy.c b/lib/livepatch/test_klp_callbacks_busy.c
+index 7ac845f65be5..133929e0ce8f 100644
+--- a/lib/livepatch/test_klp_callbacks_busy.c
++++ b/lib/livepatch/test_klp_callbacks_busy.c
+@@ -16,10 +16,12 @@ MODULE_PARM_DESC(block_transition, "block_transition (default=false)");
+
+ static void busymod_work_func(struct work_struct *work);
+ static DECLARE_WORK(work, busymod_work_func);
++static DECLARE_COMPLETION(busymod_work_started);
+
+ static void busymod_work_func(struct work_struct *work)
+ {
+ pr_info("%s enter\n", __func__);
++ complete(&busymod_work_started);
+
+ while (READ_ONCE(block_transition)) {
+ /*
+@@ -37,6 +39,12 @@ static int test_klp_callbacks_busy_init(void)
+ pr_info("%s\n", __func__);
+ schedule_work(&work);
+
++ /*
++ * To synchronize kernel messages, hold the init function from
++ * exiting until the work function's entry message has printed.
++ */
++ wait_for_completion(&busymod_work_started);
++
+ if (!block_transition) {
+ /*
+ * Serialize output: print all messages from the work
+--
+2.35.1
+
--- /dev/null
+From 0708db0c4b63990594e167d107a0c23575ccafa9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 09:31:03 +1000
+Subject: selftests/powerpc: Skip energy_scale_info test on older firmware
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit 4228a996b072d36f3baafb4afdc2d2d66d2cbadf ]
+
+Older machines don't have the firmware feature that enables the code
+this test is testing. Skip the test if the sysfs directory doesn't
+exist. Also use the FAIL_IF() macro to provide more verbose error
+reporting if an error is encountered.
+
+Fixes: 57201d657eb7 ("selftest/powerpc: Add PAPR sysfs attributes sniff test")
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/20220619233103.2666171-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../powerpc/papr_attributes/attr_test.c | 30 +++++++++++--------
+ 1 file changed, 18 insertions(+), 12 deletions(-)
+
+diff --git a/tools/testing/selftests/powerpc/papr_attributes/attr_test.c b/tools/testing/selftests/powerpc/papr_attributes/attr_test.c
+index bab0dc06e90b..9b655be641c9 100644
+--- a/tools/testing/selftests/powerpc/papr_attributes/attr_test.c
++++ b/tools/testing/selftests/powerpc/papr_attributes/attr_test.c
+@@ -7,6 +7,7 @@
+ * Copyright 2022, Pratik Rajesh Sampat, IBM Corp.
+ */
+
++#include <errno.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <dirent.h>
+@@ -32,7 +33,7 @@ enum type {
+ NUM_VAL
+ };
+
+-int value_type(int id)
++static int value_type(int id)
+ {
+ int val_type;
+
+@@ -54,15 +55,21 @@ int value_type(int id)
+ return val_type;
+ }
+
+-int verify_energy_info(void)
++static int verify_energy_info(void)
+ {
+ const char *path = "/sys/firmware/papr/energy_scale_info";
+ struct dirent *entry;
+ struct stat s;
+ DIR *dirp;
+
+- if (stat(path, &s) || !S_ISDIR(s.st_mode))
+- return -1;
++ errno = 0;
++ if (stat(path, &s)) {
++ SKIP_IF(errno == ENOENT);
++ FAIL_IF(errno);
++ }
++
++ FAIL_IF(!S_ISDIR(s.st_mode));
++
+ dirp = opendir(path);
+
+ while ((entry = readdir(dirp)) != NULL) {
+@@ -76,25 +83,24 @@ int verify_energy_info(void)
+
+ id = atoi(entry->d_name);
+ attr_type = value_type(id);
+- if (attr_type == INVALID)
+- return -1;
++ FAIL_IF(attr_type == INVALID);
+
+ /* Check if the files exist and have data in them */
+ sprintf(file_name, "%s/%d/desc", path, id);
+ f = fopen(file_name, "r");
+- if (!f || fgetc(f) == EOF)
+- return -1;
++ FAIL_IF(!f);
++ FAIL_IF(fgetc(f) == EOF);
+
+ sprintf(file_name, "%s/%d/value", path, id);
+ f = fopen(file_name, "r");
+- if (!f || fgetc(f) == EOF)
+- return -1;
++ FAIL_IF(!f);
++ FAIL_IF(fgetc(f) == EOF);
+
+ if (attr_type == STR_VAL) {
+ sprintf(file_name, "%s/%d/value_desc", path, id);
+ f = fopen(file_name, "r");
+- if (!f || fgetc(f) == EOF)
+- return -1;
++ FAIL_IF(!f);
++ FAIL_IF(fgetc(f) == EOF);
+ }
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 4ed89375771f795f6023370e855068a68d3fd4d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 22:34:07 +0000
+Subject: selftests/seccomp: Fix compile warning when CC=clang
+
+From: YiFei Zhu <zhuyifei@google.com>
+
+[ Upstream commit 3ce4b78f73e8e00fb86bad67ee7f6fe12019707e ]
+
+clang has -Wconstant-conversion by default, and the constant 0xAAAAAAAAA
+(9 As) being converted to an int, which is generally 32 bits, results
+in the compile warning:
+
+ clang -Wl,-no-as-needed -Wall -isystem ../../../../usr/include/ -lpthread seccomp_bpf.c -lcap -o seccomp_bpf
+ seccomp_bpf.c:812:67: warning: implicit conversion from 'long' to 'int' changes value from 45812984490 to -1431655766 [-Wconstant-conversion]
+ int kill = kill_how == KILL_PROCESS ? SECCOMP_RET_KILL_PROCESS : 0xAAAAAAAAA;
+ ~~~~ ^~~~~~~~~~~
+ 1 warning generated.
+
+-1431655766 is the expected truncation, 0xAAAAAAAA (8 As), so use
+this directly in the code to avoid the warning.
+
+Fixes: 3932fcecd962 ("selftests/seccomp: Add test for unknown SECCOMP_RET kill behavior")
+Signed-off-by: YiFei Zhu <zhuyifei@google.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20220526223407.1686936-1-zhuyifei@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/seccomp/seccomp_bpf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
+index 313bb0cbfb1e..6f65eeb6a3dd 100644
+--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
++++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
+@@ -802,7 +802,7 @@ void kill_thread_or_group(struct __test_metadata *_metadata,
+ .len = (unsigned short)ARRAY_SIZE(filter_thread),
+ .filter = filter_thread,
+ };
+- int kill = kill_how == KILL_PROCESS ? SECCOMP_RET_KILL_PROCESS : 0xAAAAAAAAA;
++ int kill = kill_how == KILL_PROCESS ? SECCOMP_RET_KILL_PROCESS : 0xAAAAAAAA;
+ struct sock_filter filter_process[] = {
+ BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+ offsetof(struct seccomp_data, nr)),
+--
+2.35.1
+
--- /dev/null
+From d50d9b319359941c8befba15cc1530b0e0087a57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 22:46:17 +0200
+Subject: selftests: timers: clocksource-switch: fix passing errors from child
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 4d8f52ac5fa9eede7b7aa2f2d67c841d9eeb655f ]
+
+The return value from system() is a waitpid-style integer. Do not return
+it directly because with the implicit masking in exit() it will always
+return 0. Access it with appropriate macros to really pass on errors.
+
+Fixes: 7290ce1423c3 ("selftests/timers: Add clocksource-switch test from timetest suite")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Acked-by: John Stultz <jstultz@google.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/timers/clocksource-switch.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tools/testing/selftests/timers/clocksource-switch.c b/tools/testing/selftests/timers/clocksource-switch.c
+index ef8eb3604595..b57f0a9be490 100644
+--- a/tools/testing/selftests/timers/clocksource-switch.c
++++ b/tools/testing/selftests/timers/clocksource-switch.c
+@@ -110,10 +110,10 @@ int run_tests(int secs)
+
+ sprintf(buf, "./inconsistency-check -t %i", secs);
+ ret = system(buf);
+- if (ret)
+- return ret;
++ if (WIFEXITED(ret) && WEXITSTATUS(ret))
++ return WEXITSTATUS(ret);
+ ret = system("./nanosleep");
+- return ret;
++ return WIFEXITED(ret) ? WEXITSTATUS(ret) : 0;
+ }
+
+
+--
+2.35.1
+
--- /dev/null
+From e4f1f2ff836a4d5e195d773ade173a2156c14df1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 22:46:13 +0200
+Subject: selftests: timers: valid-adjtimex: build fix for newer toolchains
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 9a162977d20436be5678a8e21a8e58eb4616d86a ]
+
+Toolchains with an include file 'sys/timex.h' based on 3.18 will have a
+'clock_adjtime' definition added, so it can't be static in the code:
+
+valid-adjtimex.c:43:12: error: static declaration of ‘clock_adjtime’ follows non-static declaration
+
+Fixes: e03a58c320e1 ("kselftests: timers: Add adjtimex SETOFFSET validity tests")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Acked-by: John Stultz <jstultz@google.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/timers/valid-adjtimex.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/timers/valid-adjtimex.c b/tools/testing/selftests/timers/valid-adjtimex.c
+index 5397de708d3c..48b9a803235a 100644
+--- a/tools/testing/selftests/timers/valid-adjtimex.c
++++ b/tools/testing/selftests/timers/valid-adjtimex.c
+@@ -40,7 +40,7 @@
+ #define ADJ_SETOFFSET 0x0100
+
+ #include <sys/syscall.h>
+-static int clock_adjtime(clockid_t id, struct timex *tx)
++int clock_adjtime(clockid_t id, struct timex *tx)
+ {
+ return syscall(__NR_clock_adjtime, id, tx);
+ }
+--
+2.35.1
+
--- /dev/null
+From 08d45bfcf73d14b053e50e2cf70a4291634f3d83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jun 2022 16:34:58 +0200
+Subject: selftests/xsk: Destroy BPF resources only when ctx refcount drops to
+ 0
+
+From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+
+[ Upstream commit 39e940d4abfabb08b6937a315546b24d10be67e3 ]
+
+Currently, xsk_socket__delete frees BPF resources regardless of ctx
+refcount. Xdpxceiver has a test to verify whether underlying BPF
+resources would not be wiped out after closing XSK socket that was
+bound to interface with other active sockets. From library's xsk part
+perspective it also means that the internal xsk context is shared and
+its refcount is bumped accordingly.
+
+After a switch to loading XDP prog based on previously opened XSK
+socket, mentioned xdpxceiver test fails with:
+
+ not ok 16 [xdpxceiver.c:swap_xsk_resources:1334]: ERROR: 9/"Bad file descriptor
+
+which means that in swap_xsk_resources(), xsk_socket__delete() released
+xskmap which in turn caused a failure of xsk_socket__update_xskmap().
+
+To fix this, when deleting socket, decrement ctx refcount before
+releasing BPF resources and do so only when refcount dropped to 0 which
+means there are no more active sockets for this ctx so BPF resources can
+be freed safely.
+
+Fixes: 2f6324a3937f ("libbpf: Support shared umems between queues and devices")
+Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Magnus Karlsson <magnus.karlsson@intel.com>
+Link: https://lore.kernel.org/bpf/20220629143458.934337-5-maciej.fijalkowski@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/xsk.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c
+index af136f73b09d..67dc010e9fe3 100644
+--- a/tools/lib/bpf/xsk.c
++++ b/tools/lib/bpf/xsk.c
+@@ -1147,8 +1147,6 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
+ goto out_mmap_tx;
+ }
+
+- ctx->prog_fd = -1;
+-
+ if (!(xsk->config.libbpf_flags & XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD)) {
+ err = __xsk_setup_xdp_prog(xsk, NULL);
+ if (err)
+@@ -1229,7 +1227,10 @@ void xsk_socket__delete(struct xsk_socket *xsk)
+
+ ctx = xsk->ctx;
+ umem = ctx->umem;
+- if (ctx->prog_fd != -1) {
++
++ xsk_put_ctx(ctx, true);
++
++ if (!ctx->refcount) {
+ xsk_delete_bpf_maps(xsk);
+ close(ctx->prog_fd);
+ if (ctx->has_bpf_link)
+@@ -1248,8 +1249,6 @@ void xsk_socket__delete(struct xsk_socket *xsk)
+ }
+ }
+
+- xsk_put_ctx(ctx, true);
+-
+ umem->refcount--;
+ /* Do not close an fd that also has an associated umem connected
+ * to it.
+--
+2.35.1
+
--- /dev/null
+From 730da7e900f7d02a9d4a1909b843bf85c6beac67 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jun 2022 10:14:49 +0800
+Subject: selinux: Add boundary check in put_entry()
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit 15ec76fb29be31df2bccb30fc09875274cba2776 ]
+
+Just like next_entry(), boundary check is necessary to prevent memory
+out-of-bound access.
+
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/selinux/ss/policydb.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
+index c24d4e1063ea..ffc4e7bad205 100644
+--- a/security/selinux/ss/policydb.h
++++ b/security/selinux/ss/policydb.h
+@@ -370,6 +370,8 @@ static inline int put_entry(const void *buf, size_t bytes, int num, struct polic
+ {
+ size_t len = bytes * num;
+
++ if (len > fp->len)
++ return -EINVAL;
+ memcpy(fp->data, buf, len);
+ fp->data += len;
+ fp->len -= len;
+--
+2.35.1
+
--- /dev/null
+From ac7ef3cc5d2611408a5f80227558825e2120567d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 21:59:53 +0800
+Subject: selinux: fix memleak in security_read_state_kernel()
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit 73de1befcc53a7c68b0c5e76b9b5ac41c517760f ]
+
+In this function, it directly returns the result of __security_read_policy
+without freeing the allocated memory in *data, cause memory leak issue,
+so free the memory if __security_read_policy failed.
+
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+[PM: subject line tweak]
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/selinux/ss/services.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
+index 6901dc07680d..cad54f454d01 100644
+--- a/security/selinux/ss/services.c
++++ b/security/selinux/ss/services.c
+@@ -4049,6 +4049,7 @@ int security_read_policy(struct selinux_state *state,
+ int security_read_state_kernel(struct selinux_state *state,
+ void **data, size_t *len)
+ {
++ int err;
+ struct selinux_policy *policy;
+
+ policy = rcu_dereference_protected(
+@@ -4061,5 +4062,11 @@ int security_read_state_kernel(struct selinux_state *state,
+ if (!*data)
+ return -ENOMEM;
+
+- return __security_read_policy(policy, *data, len);
++ err = __security_read_policy(policy, *data, len);
++ if (err) {
++ vfree(*data);
++ *data = NULL;
++ *len = 0;
++ }
++ return err;
+ }
+--
+2.35.1
+
--- /dev/null
+From 34ca14884906041c60b540d3ca0d53aaf39b4ef8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Apr 2022 16:27:27 +0100
+Subject: serial: 8250: Export ICR access helpers for internal use
+
+From: Maciej W. Rozycki <macro@orcam.me.uk>
+
+[ Upstream commit cb5a40e3143bc64437858b337273fd63cc42e9c2 ]
+
+Make ICR access helpers available outside 8250_port.c, however retain
+them as ordinary static functions so as not to regress code generation.
+
+This is because `serial_icr_write' is currently automatically inlined by
+GCC, however `serial_icr_read' is not. Making them both static inline
+would grow code produced, e.g.:
+
+$ i386-linux-gnu-size --format=gnu 8250_port-{old,new}.o
+ text data bss total filename
+ 15065 3378 0 18443 8250_port-old.o
+ 15289 3378 0 18667 8250_port-new.o
+
+and:
+
+$ riscv64-linux-gnu-size --format=gnu 8250_port-{old,new}.o
+ text data bss total filename
+ 16980 5306 0 22286 8250_port-old.o
+ 17124 5306 0 22430 8250_port-new.o
+
+while making them external would needlessly add a new module interface
+and lose the benefit from `serial_icr_write' getting inlined outside
+8250_port.o.
+
+Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/alpine.DEB.2.21.2204181517500.9383@angie.orcam.me.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250.h | 22 ++++++++++++++++++++++
+ drivers/tty/serial/8250/8250_port.c | 21 ---------------------
+ 2 files changed, 22 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
+index db784ace25d8..467372534d1c 100644
+--- a/drivers/tty/serial/8250/8250.h
++++ b/drivers/tty/serial/8250/8250.h
+@@ -120,6 +120,28 @@ static inline void serial_out(struct uart_8250_port *up, int offset, int value)
+ up->port.serial_out(&up->port, offset, value);
+ }
+
++/*
++ * For the 16C950
++ */
++static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
++{
++ serial_out(up, UART_SCR, offset);
++ serial_out(up, UART_ICR, value);
++}
++
++static unsigned int __maybe_unused serial_icr_read(struct uart_8250_port *up,
++ int offset)
++{
++ unsigned int value;
++
++ serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
++ serial_out(up, UART_SCR, offset);
++ value = serial_in(up, UART_ICR);
++ serial_icr_write(up, UART_ACR, up->acr);
++
++ return value;
++}
++
+ void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p);
+
+ static inline int serial_dl_read(struct uart_8250_port *up)
+diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
+index ddaf35daf316..291fd99bd7f1 100644
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -537,27 +537,6 @@ serial_port_out_sync(struct uart_port *p, int offset, int value)
+ }
+ }
+
+-/*
+- * For the 16C950
+- */
+-static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
+-{
+- serial_out(up, UART_SCR, offset);
+- serial_out(up, UART_ICR, value);
+-}
+-
+-static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
+-{
+- unsigned int value;
+-
+- serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
+- serial_out(up, UART_SCR, offset);
+- value = serial_in(up, UART_ICR);
+- serial_icr_write(up, UART_ACR, up->acr);
+-
+- return value;
+-}
+-
+ /*
+ * FIFO support.
+ */
+--
+2.35.1
+
--- /dev/null
+From 8f6be08d7cc80ed558e8cabe0a773f321b290cd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 10:33:12 +0800
+Subject: serial: 8250_bcm2835aux: Add missing clk_disable_unprepare()
+
+From: Guo Mengqi <guomengqi3@huawei.com>
+
+[ Upstream commit b9f1736e475dba0d6da48fdcb831248ab1597886 ]
+
+The error path when get clock frequency fails in bcm2835aux_serial
+driver does not correctly disable the clock.
+
+This flaw was found using a static analysis tool "Hulk Robot", which
+reported the following warning when analyzing linux-next/master:
+
+ drivers/tty/serial/8250/8250_bcm2835aux.c:
+ warning: clk_disable_unprepare_missing.cocci
+
+The cocci script checks for the existence of clk_disable_unprepare()
+paired with clk_prepare_enable().
+
+Add the missing clk_disable_unprepare() to the error path.
+
+Fixes: fcc446c8aa63 ("serial: 8250_bcm2835aux: Add ACPI support")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Guo Mengqi <guomengqi3@huawei.com>
+Link: https://lore.kernel.org/r/20220715023312.37808-1-guomengqi3@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_bcm2835aux.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250_bcm2835aux.c b/drivers/tty/serial/8250/8250_bcm2835aux.c
+index 2a1226a78a0c..21939bb44613 100644
+--- a/drivers/tty/serial/8250/8250_bcm2835aux.c
++++ b/drivers/tty/serial/8250/8250_bcm2835aux.c
+@@ -166,8 +166,10 @@ static int bcm2835aux_serial_probe(struct platform_device *pdev)
+ uartclk = clk_get_rate(data->clk);
+ if (!uartclk) {
+ ret = device_property_read_u32(&pdev->dev, "clock-frequency", &uartclk);
+- if (ret)
+- return dev_err_probe(&pdev->dev, ret, "could not get clk rate\n");
++ if (ret) {
++ dev_err_probe(&pdev->dev, ret, "could not get clk rate\n");
++ goto dis_clk;
++ }
+ }
+
+ /* the HW-clock divider for bcm2835aux is 8,
+--
+2.35.1
+
--- /dev/null
+From 145f05b47ca85473d9035fd0feff66617f41bea1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 20:13:15 -0700
+Subject: serial: 8250_bcm7271: Save/restore RTS in suspend/resume
+
+From: Doug Berger <opendmb@gmail.com>
+
+[ Upstream commit 3182efd036c1b955403d131258234896cbd9fbeb ]
+
+Commit 9cabe26e65a8 ("serial: 8250_bcm7271: UART errors after resuming
+from S2") prevented an early enabling of RTS during resume, but it did
+not actively restore the RTS state after resume.
+
+Fixes: 9cabe26e65a8 ("serial: 8250_bcm7271: UART errors after resuming from S2")
+Signed-off-by: Doug Berger <opendmb@gmail.com>
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Link: https://lore.kernel.org/r/20220714031316.404918-1-f.fainelli@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_bcm7271.c | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c
+index 9b878d023dac..8efdc271eb75 100644
+--- a/drivers/tty/serial/8250/8250_bcm7271.c
++++ b/drivers/tty/serial/8250/8250_bcm7271.c
+@@ -1139,16 +1139,19 @@ static int __maybe_unused brcmuart_suspend(struct device *dev)
+ struct brcmuart_priv *priv = dev_get_drvdata(dev);
+ struct uart_8250_port *up = serial8250_get_port(priv->line);
+ struct uart_port *port = &up->port;
+-
+- serial8250_suspend_port(priv->line);
+- clk_disable_unprepare(priv->baud_mux_clk);
++ unsigned long flags;
+
+ /*
+ * This will prevent resume from enabling RTS before the
+- * baud rate has been resored.
++ * baud rate has been restored.
+ */
++ spin_lock_irqsave(&port->lock, flags);
+ priv->saved_mctrl = port->mctrl;
+- port->mctrl = 0;
++ port->mctrl &= ~TIOCM_RTS;
++ spin_unlock_irqrestore(&port->lock, flags);
++
++ serial8250_suspend_port(priv->line);
++ clk_disable_unprepare(priv->baud_mux_clk);
+
+ return 0;
+ }
+@@ -1158,6 +1161,7 @@ static int __maybe_unused brcmuart_resume(struct device *dev)
+ struct brcmuart_priv *priv = dev_get_drvdata(dev);
+ struct uart_8250_port *up = serial8250_get_port(priv->line);
+ struct uart_port *port = &up->port;
++ unsigned long flags;
+ int ret;
+
+ ret = clk_prepare_enable(priv->baud_mux_clk);
+@@ -1180,7 +1184,15 @@ static int __maybe_unused brcmuart_resume(struct device *dev)
+ start_rx_dma(serial8250_get_port(priv->line));
+ }
+ serial8250_resume_port(priv->line);
+- port->mctrl = priv->saved_mctrl;
++
++ if (priv->saved_mctrl & TIOCM_RTS) {
++ /* Restore RTS */
++ spin_lock_irqsave(&port->lock, flags);
++ port->mctrl |= TIOCM_RTS;
++ port->ops->set_mctrl(port, port->mctrl);
++ spin_unlock_irqrestore(&port->lock, flags);
++ }
++
+ return 0;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From e32a7a0aeb979a39b67647909604c46b7bb98ec2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Jul 2022 10:51:19 +0200
+Subject: serial: 8250_fsl: Don't report FE, PE and OE twice
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 9d3aaceb73acadf134596a2f8db9c451c1332d3d ]
+
+Some Freescale 8250 implementations have the problem that a single long
+break results in one irq per character frame time. The code in
+fsl8250_handle_irq() that is supposed to handle that uses the BI bit in
+lsr_saved_flags to detect such a situation and then skip the second
+received character. However it also stores other error bits and so after
+a single frame error the character received in the next irq handling is
+passed to the upper layer with a frame error, too.
+
+So after a spike on the data line (which is correctly recognized as a
+frame error) the following valid character is thrown away, because the
+driver reports a frame error for that one, too.
+
+To weaken this problem restrict saving LSR to only the BI bit.
+
+Note however that the handling is still broken:
+
+ - lsr_saved_flags is updated using orig_lsr which is the LSR content
+ for the first received char, but there might be more in the FIFO, so
+ a character is thrown away that is received later and not necessarily
+ the one following the break.
+ - The doubled break might be the 2nd and 3rd char in the FIFO, so the
+ workaround doesn't catch these, because serial8250_rx_chars() doesn't
+ handle the workaround.
+ - lsr_saved_flags might have set UART_LSR_BI at the entry of
+ fsl8250_handle_irq() which doesn't originate from
+ fsl8250_handle_irq()'s "up->lsr_saved_flags |= orig_lsr &
+ UART_LSR_BI;" but from e.g. from serial8250_tx_empty().
+ - For a long or a short break this isn't about two characters, but more
+ or only a single one.
+
+Fixes: 9deaa53ac7fa ("serial: add irq handler for Freescale 16550 errata.")
+Acked-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20220704085119.55900-1-u.kleine-koenig@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_fsl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c
+index 9c01c531349d..71ce43685797 100644
+--- a/drivers/tty/serial/8250/8250_fsl.c
++++ b/drivers/tty/serial/8250/8250_fsl.c
+@@ -77,7 +77,7 @@ int fsl8250_handle_irq(struct uart_port *port)
+ if ((lsr & UART_LSR_THRE) && (up->ier & UART_IER_THRI))
+ serial8250_tx_chars(up);
+
+- up->lsr_saved_flags = orig_lsr;
++ up->lsr_saved_flags |= orig_lsr & UART_LSR_BI;
+
+ uart_unlock_and_check_sysrq_irqrestore(&up->port, flags);
+
+--
+2.35.1
+
--- /dev/null
+From e4e7f65f7283c6cb5894b1c8c0c2ac545eeb4ea6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 10:12:04 +0800
+Subject: serial: pic32: fix missing clk_disable_unprepare() on error in
+ pic32_uart_startup()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 6f3cdf2bf1ba9b70de6c2921a415951a0d59873b ]
+
+Fix the missing clk_disable_unprepare() before return
+from pic32_uart_startup() in the error handling case.
+
+Fixes: 157b9394709e ("serial: pic32_uart: Add PIC32 UART driver")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20220525021204.2407631-1-yangyingliang@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/pic32_uart.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c
+index e3535bd8c8a2..a967b586a0a0 100644
+--- a/drivers/tty/serial/pic32_uart.c
++++ b/drivers/tty/serial/pic32_uart.c
+@@ -427,7 +427,7 @@ static int pic32_uart_startup(struct uart_port *port)
+ if (!sport->irq_fault_name) {
+ dev_err(port->dev, "%s: kasprintf err!", __func__);
+ ret = -ENOMEM;
+- goto out_done;
++ goto out_disable_clk;
+ }
+ irq_set_status_flags(sport->irq_fault, IRQ_NOAUTOEN);
+ ret = request_irq(sport->irq_fault, pic32_uart_fault_interrupt,
+@@ -501,6 +501,8 @@ static int pic32_uart_startup(struct uart_port *port)
+ out_f:
+ free_irq(sport->irq_fault, port);
+ kfree(sport->irq_fault_name);
++out_disable_clk:
++ clk_disable_unprepare(sport->clk);
+ out_done:
+ return ret;
+ }
+--
+2.35.1
+
--- /dev/null
+From 2688714b0837a22738e72e1e51fdfb7bc8118b8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 May 2022 08:31:21 +0200
+Subject: serial: pic32: free up irq names correctly
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+[ Upstream commit fe36fa18ca77ca3ca9f90aab6cf39031416e432b ]
+
+struct pic32_sport contains built-up names for irqs. These are freed
+only in error path of pic32_uart_startup(). And even there, the freeing
+happens before free_irq().
+
+So fix this by:
+* moving frees after free_irq(), and
+* add frees to pic32_uart_shutdown() -- the opposite of
+ pic32_uart_startup().
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Link: https://lore.kernel.org/r/20220503063122.20957-11-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/pic32_uart.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c
+index b7a3a1b959b1..e3535bd8c8a2 100644
+--- a/drivers/tty/serial/pic32_uart.c
++++ b/drivers/tty/serial/pic32_uart.c
+@@ -493,14 +493,14 @@ static int pic32_uart_startup(struct uart_port *port)
+ return 0;
+
+ out_t:
+- kfree(sport->irq_tx_name);
+ free_irq(sport->irq_tx, port);
++ kfree(sport->irq_tx_name);
+ out_r:
+- kfree(sport->irq_rx_name);
+ free_irq(sport->irq_rx, port);
++ kfree(sport->irq_rx_name);
+ out_f:
+- kfree(sport->irq_fault_name);
+ free_irq(sport->irq_fault, port);
++ kfree(sport->irq_fault_name);
+ out_done:
+ return ret;
+ }
+@@ -519,8 +519,11 @@ static void pic32_uart_shutdown(struct uart_port *port)
+
+ /* free all 3 interrupts for this UART */
+ free_irq(sport->irq_fault, port);
++ kfree(sport->irq_fault_name);
+ free_irq(sport->irq_tx, port);
++ kfree(sport->irq_tx_name);
+ free_irq(sport->irq_rx, port);
++ kfree(sport->irq_rx_name);
+ }
+
+ /* serial core request to change current uart setting */
+--
+2.35.1
+
--- /dev/null
+From 5517053a2e0b30a1e35f90504446af4a2c4920e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Apr 2022 17:33:58 +0300
+Subject: serial: Store character timing information to uart_port
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 31f6bd7fad3b149a1eb6f67fc2e742e4df369b3d ]
+
+Struct uart_port currently stores FIFO timeout. Having character timing
+information readily available is useful. Even serial core itself
+determines char_time from port->timeout using inverse calculation.
+
+Store frame_time directly into uart_port. Character time is stored in
+nanoseconds to have reasonable precision with high rates. To avoid
+overflow, 64-bit math is necessary.
+
+It might be possible to determine timeout from frame_time by
+multiplying it with fifosize as needed but only part of the users seem
+to be protected by a lock. Thus, this patch does not pursue storing
+only frame_time in uart_port.
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://lore.kernel.org/r/20220425143410.12703-2-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/serial_core.c | 14 ++++++++------
+ include/linux/serial_core.h | 1 +
+ 2 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
+index 95d8d1fcd543..6b07b7b41354 100644
+--- a/drivers/tty/serial/serial_core.c
++++ b/drivers/tty/serial/serial_core.c
+@@ -24,6 +24,7 @@
+ #include <linux/sysrq.h>
+ #include <linux/delay.h>
+ #include <linux/mutex.h>
++#include <linux/math64.h>
+ #include <linux/security.h>
+
+ #include <linux/irq.h>
+@@ -333,15 +334,18 @@ void
+ uart_update_timeout(struct uart_port *port, unsigned int cflag,
+ unsigned int baud)
+ {
+- unsigned int size;
++ unsigned int size = tty_get_frame_size(cflag);
++ u64 frame_time;
+
+- size = tty_get_frame_size(cflag) * port->fifosize;
++ frame_time = (u64)size * NSEC_PER_SEC;
++ size *= port->fifosize;
+
+ /*
+ * Figure the timeout to send the above number of bits.
+ * Add .02 seconds of slop
+ */
+ port->timeout = (HZ * size) / baud + HZ/50;
++ port->frame_time = DIV64_U64_ROUND_UP(frame_time, baud);
+ }
+ EXPORT_SYMBOL(uart_update_timeout);
+
+@@ -1610,10 +1614,8 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
+ * Note: we have to use pretty tight timings here to satisfy
+ * the NIST-PCTS.
+ */
+- char_time = (port->timeout - HZ/50) / port->fifosize;
+- char_time = char_time / 5;
+- if (char_time == 0)
+- char_time = 1;
++ char_time = max(nsecs_to_jiffies(port->frame_time / 5), 1UL);
++
+ if (timeout && timeout < char_time)
+ char_time = timeout;
+
+diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
+index ca57d686d4d1..409573ea5ea4 100644
+--- a/include/linux/serial_core.h
++++ b/include/linux/serial_core.h
+@@ -232,6 +232,7 @@ struct uart_port {
+ int hw_stopped; /* sw-assisted CTS flow state */
+ unsigned int mctrl; /* current modem ctrl settings */
+ unsigned int timeout; /* character-based timeout */
++ unsigned int frame_time; /* frame timing in ns */
+ unsigned int type; /* port type */
+ const struct uart_ops *ops;
+ unsigned int custom_divisor;
+--
+2.35.1
+
netfilter-nf_tables-do-not-allow-rule_id-to-refer-to-another-chain.patch
netfilter-nf_tables-fix-null-deref-due-to-zeroed-list-head.patch
epoll-autoremove-wakers-even-more-aggressively.patch
+x86-handle-idle-nomwait-cmdline-properly-for-x86_idl.patch
+arch-make-trace_irqflags_nmi_support-generic.patch
+arm64-do-not-forget-syscall-when-starting-a-new-thre.patch
+arm64-fix-oops-in-concurrently-setting-insn_emulatio.patch
+arm64-kasan-revert-arm64-mte-reset-the-page-tag-in-p.patch
+arm64-errata-remove-aes-hwcap-for-compat-tasks.patch
+ext2-add-more-validity-checks-for-inode-counts.patch
+sched-fair-introduce-sis_util-to-search-idle-cpu-bas.patch
+genirq-don-t-return-error-on-missing-optional-irq_re.patch
+irqchip-mips-gic-only-register-ipi-domain-when-smp-i.patch
+genirq-generic_irq_ipi-depends-on-smp.patch
+sched-fair-fix-case-with-reduced-capacity-cpu.patch
+sched-core-always-flush-pending-blk_plug.patch
+irqchip-mips-gic-check-the-return-value-of-ioremap-i.patch
+wait-fix-__wait_event_hrtimeout-for-rt-dl-tasks.patch
+arm-dts-imx6ul-add-missing-properties-for-sram.patch
+arm-dts-imx6ul-change-operating-points-to-uint32-mat.patch
+arm-dts-imx6ul-fix-keypad-compatible.patch
+arm-dts-imx6ul-fix-csi-node-compatible.patch
+arm-dts-imx6ul-fix-lcdif-node-compatible.patch
+arm-dts-imx6ul-fix-qspi-node-compatible.patch
+arm-dts-bcm5301x-add-dt-for-meraki-mr26.patch
+arm-dts-ux500-fix-janice-accelerometer-mounting-matr.patch
+arm-dts-ux500-fix-codina-accelerometer-mounting-matr.patch
+arm-dts-ux500-fix-gavini-accelerometer-mounting-matr.patch
+arm64-dts-qcom-timer-should-use-only-32-bit-size.patch
+spi-synquacer-add-missing-clk_disable_unprepare.patch
+arm-omap2-display-fix-refcount-leak-bug.patch
+arm-omap2-pdata-quirks-fix-refcount-leak-bug.patch
+acpi-ec-remove-duplicate-thinkpad-x1-carbon-6th-entr.patch
+acpi-ec-drop-the-ec_flags_ignore_dsdt_gpe-quirk.patch
+acpi-pm-save-nvs-memory-for-lenovo-g40-45.patch
+acpi-lpss-fix-missing-check-in-register_device_clock.patch
+arm-dts-qcom-sdx55-fix-the-irq-trigger-type-for-uart.patch
+arm64-dts-qcom-add-missing-aoss-qmp-compatible-fallb.patch
+arm64-dts-qcom-ipq8074-fix-nand-node-name.patch
+arm64-dts-allwinner-a64-orangepi-win-fix-led-node-na.patch
+arm-shmobile-rcar-gen2-increase-refcount-for-new-ref.patch
+firmware-tegra-fix-error-check-return-value-of-debug.patch
+hwmon-dell-smm-add-dell-xps-13-7390-to-fan-control-w.patch
+acpi-video-use-native-backlight-on-dell-inspiron-n40.patch
+hwmon-sht15-fix-wrong-assumptions-in-device-remove-c.patch
+pm-hibernate-defer-device-probing-when-resuming-from.patch
+selinux-fix-memleak-in-security_read_state_kernel.patch
+selinux-add-boundary-check-in-put_entry.patch
+skbuff-don-t-mix-ubuf_info-from-different-sources.patch
+kasan-test-silence-gcc-12-warnings.patch
+pinctrl-don-t-allow-pinctrl_amd-to-be-a-module.patch
+drm-amdgpu-remove-one-duplicated-ef-removal.patch
+powerpc-64s-disable-stack-variable-initialisation-fo.patch
+spi-spi-rspi-fix-pio-fallback-on-rz-platforms.patch
+netfilter-nf_tables-add-rescheduling-points-during-l.patch
+netfilter-nft_queue-only-allow-supported-familes-and.patch
+arm-findbit-fix-overflowing-offset.patch
+meson-mx-socinfo-fix-refcount-leak-in-meson_mx_socin.patch
+arm64-dts-renesas-beacon-fix-regulator-node-names.patch
+spi-spi-altera-dfl-fix-an-error-handling-path.patch
+arm-bcm-fix-refcount-leak-in-bcm_kona_smc_init.patch
+acpi-processor-idle-annotate-more-functions-to-live-.patch
+arm-dts-imx7d-colibri-emmc-add-cpu1-supply.patch
+soc-renesas-r8a779a0-sysc-fix-a2dp1-and-a2cv-2357-pd.patch
+soc-amlogic-fix-refcount-leak-in-meson-secure-pwrc.c.patch
+arm64-dts-renesas-fix-thermal-sensors-on-single-zone.patch
+revert-arm-dts-imx6qdl-apalis-avoid-underscore-in-no.patch
+x86-pmem-fix-platform-device-leak-in-error-path.patch
+arm-dts-ast2500-evb-fix-board-compatible.patch
+arm-dts-ast2600-evb-fix-board-compatible.patch
+arm-dts-ast2600-evb-a1-fix-board-compatible.patch
+arm64-dts-mt8192-fix-idle-states-nodes-naming-scheme.patch
+arm64-dts-mt8192-fix-idle-states-entry-method.patch
+arm64-select-trace_irqflags_nmi_support.patch
+arm64-cpufeature-allow-different-pmu-versions-in-id_.patch
+locking-lockdep-fix-lockdep_init_map_-confusion.patch
+arm64-dts-qcom-sc7180-remove-ipa_fw_mem-node-on-trog.patch
+soc-fsl-guts-machine-variable-might-be-unset.patch
+spi-s3c64xx-constify-fsd_spi_port_config.patch
+block-fix-infinite-loop-for-invalid-zone-append.patch
+arm64-dts-qcom-sdm845-akatsuki-round-down-l22a-regul.patch
+arm-dts-qcom-mdm9615-add-missing-pmic-gpio-reg.patch
+arm-omap2-fix-refcount-leak-in-omapdss_init_of.patch
+arm-omap2-fix-refcount-leak-in-omap3xxx_prm_late_ini.patch
+arm64-dts-qcom-sdm630-disable-gpu-by-default.patch
+arm64-dts-qcom-sdm630-fix-the-qusb2phy-ref-clock.patch
+arm64-dts-qcom-sdm630-fix-gpu-s-interconnect-path.patch
+arm64-dts-qcom-sdm636-sony-xperia-ganges-mermaid-cor.patch
+cpufreq-zynq-fix-refcount-leak-in-zynq_get_revision.patch
+arm64-dts-renesas-r8a779m8-drop-operating-points-abo.patch
+arm64-dts-renesas-r9a07g054l2-smarc-correct-soc-name.patch
+regulator-qcom_smd-fix-pm8916_pldo-range.patch
+acpi-apei-fix-_einj-vs-efi_memory_sp.patch
+arm-dts-qcom-replace-gcc-pxo-with-pxo_board-fixed-cl.patch
+arm-dts-qcom-msm8974-lge-nexus5-move-gpio-keys-out-o.patch
+arm-dts-qcom-msm8974-samsung-klte-move-gpio-keys-out.patch
+arm-dts-qcom-do-not-use-underscore-in-node-name.patch
+arm-dts-qcom-msm8974-fix-uart-naming.patch
+arm-dts-qcom-msm8974-fix-i2c-labels.patch
+arm-dts-qcom-msm8974-fix-up-mdss-nodes.patch
+arm-dts-qcom-msm8974-fix-up-sdhci-nodes.patch
+arm-dts-qcom-msm8974-rename-msmgpio-to-tlmm.patch
+arm-dts-qcom-apq8074-dragonboard-use-labels.patch
+arm-dts-qcom-msm8974-fp2-use-labels.patch
+arm-dts-qcom-msm8974-lge-nexus5-use-labels.patch
+arm-dts-qcom-msm8974-klte-use-labels.patch
+arm-dts-qcom-msm8974-hon-am-ami-commonize-and-modern.patch
+arm-dts-qcom-msm8974-castor-use-labels.patch
+arm-dts-qcom-msm8974-convert-adsp-to-a-mmio-device.patch
+arm-dts-qcom-msm8974-sort-and-clean-up-nodes.patch
+arm-dts-qcom-msm8974-fix-irq-type-on-blsp2_uart1.patch
+kbuild-fix-include-path-in-scripts-makefile.modpost.patch
+iio-core-fix-a-few-code-style-issues.patch
+ia64-fix-typos-in-comments.patch
+soc-qcom-ocmem-fix-refcount-leak-in-of_get_ocmem.patch
+soc-qcom-aoss-fix-refcount-leak-in-qmp_cooling_devic.patch
+arm-dts-qcom-msm8974-add-required-ranges-to-ocmem.patch
+arm-dts-qcom-pm8841-add-required-thermal-sensor-cell.patch
+bus-hisi_lpc-fix-missing-platform_device_put-in-hisi.patch
+lib-overflow-do-not-define-64-bit-tests-on-32-bit.patch
+stack-declare-randomize_-kstack_offset-to-fix-sparse.patch
+arm64-dts-qcom-msm8916-fix-typo-in-pronto-remoteproc.patch
+perf-core-add-perf_clear_branch_entry_bitfields-help.patch
+arm64-dts-exynosautov9-correct-spi11-pin-names.patch
+acpi-viot-fix-acs-setup.patch
+arm64-dts-qcom-sm6125-move-sdc2-pinctrl-from-seine-p.patch
+arm64-dts-qcom-sm6125-append-state-suffix-to-pinctrl.patch
+arm64-dts-qcom-msm8996-correct-clock-cells-for-qmp-p.patch
+arm64-dts-qcom-sc7280-drop-pcie-phy-clock-index.patch
+arm64-dts-qcom-sm8250-add-missing-pcie-phy-clock-cel.patch
+arm64-dts-mt7622-fix-bpi-r64-wps-button.patch
+arm64-tegra-mark-bpmp-channels-as-no-memory-wc.patch
+arm64-tegra-fix-sdmmc1-cd-on-p2888.patch
+arm64-dts-qcom-sc7280-fix-pcie-clock-reference.patch
+erofs-wake-up-all-waiters-after-z_erofs_lzma_head-re.patch
+erofs-avoid-consecutive-detection-for-highmem-memory.patch
+spi-return-deferred-probe-error-when-controller-isn-.patch
+blk-mq-don-t-create-hctx-debugfs-dir-until-q-debugfs.patch
+spi-dw-fix-ip-core-versions-macro.patch
+spi-fix-simplification-of-devm_spi_register_controll.patch
+spi-tegra20-slink-fix-uaf-in-tegra_slink_remove.patch
+hwmon-sch56xx-common-add-dmi-override-table.patch
+hwmon-drivetemp-add-module-alias.patch
+blktrace-trace-remapped-requests-correctly.patch
+pm-domains-ensure-genpd_debugfs_dir-exists-before-re.patch
+dm-writecache-return-void-from-functions.patch
+dm-writecache-count-number-of-blocks-read-not-number.patch
+dm-writecache-count-number-of-blocks-written-not-num.patch
+dm-writecache-count-number-of-blocks-discarded-not-n.patch
+regulator-of-fix-refcount-leak-bug-in-of_get_regulat.patch
+soc-qcom-make-qcom_rpmpd-depend-on-pm.patch
+soc-qcom-socinfo-fix-the-id-of-sa8540p-soc.patch
+arm64-dts-qcom-msm8998-make-regulator-voltages-multi.patch
+arm64-dts-qcom-qcs404-fix-incorrect-usb2-phys-assign.patch
+arm-dts-qcom-msm8974-fp2-add-supplies-for-remoteproc.patch
+arm-dts-qcom-msm8974-disable-remoteprocs-by-default.patch
+irqdomain-report-irq-number-for-nomap-domains.patch
+perf-risc-v-add-of_node_put-when-breaking-out-of-for.patch
+drivers-perf-arm_spe-fix-consistency-of-sys_pmscr_el.patch
+nohz-full-sched-rt-fix-missed-tick-reenabling-bug-in.patch
+x86-extable-fix-ex_handler_msr-print-condition.patch
+io_uring-move-to-separate-directory.patch
+scsi-nvme-fc-add-new-routine-nvme_fc_io_getuuid.patch
+arm64-expand-esr_elx_wfx_iss_ti-to-match-its-armv8.7.patch
+io_uring-don-t-require-reinitable-percpu_ref.patch
+selftests-seccomp-fix-compile-warning-when-cc-clang.patch
+thermal-tools-tmon-include-pthread-and-time-headers-.patch
+dm-return-early-from-dm_pr_call-if-dm-device-is-susp.patch
+pwm-sifive-simplify-offset-calculation-for-pwmcmp-re.patch
+pwm-sifive-ensure-the-clk-is-enabled-exactly-once-pe.patch
+pwm-sifive-shut-down-hardware-only-after-pwmchip_rem.patch
+pwm-lpc18xx-fix-period-handling.patch
+drm-meson-fix-refcount-leak-in-meson_encoder_hdmi_in.patch
+drm-dp-export-symbol-kerneldoc-fixes-for-dp-aux-bus.patch
+drm-bridge-tc358767-move-e-dp-bridge-endpoint-parsin.patch
+drm-bridge-tc358767-make-sure-refclk-clock-are-enabl.patch
+ath10k-do-not-enforce-interrupt-trigger-type.patch
+drm-bridge-lt9611-use-both-bits-for-hdmi-sensing.patch
+drm-st7735r-fix-module-autoloading-for-okaya-rh12812.patch
+drm-panel-fix-build-error-when-config_drm_panel_sams.patch
+wifi-rtlwifi-fix-error-codes-in-rtl_debugfs_set_writ.patch
+wifi-wilc1000-use-correct-sequence-of-reset-for-chip.patch
+ath11k-fix-netdev-open-race.patch
+ath11k-fix-irq-affinity-warning-on-shutdown.patch
+drm-mipi-dbi-align-max_chunk-to-2-in-spi_transfer.patch
+selftests-bpf-fix-test_run-logic-in-fexit_stress.c.patch
+selftests-bpf-fix-tc_redirect_dtime.patch
+ath11k-fix-missing-skb-drop-on-htc_tx_completion-err.patch
+ath11k-fix-incorrect-debug_mask-mappings.patch
+ath11k-avoid-reo-cmd-failed-prints-during-firmware-r.patch
+drm-radeon-fix-potential-buffer-overflow-in-ni_set_m.patch
+drm-mediatek-modify-dsi-funcs-to-atomic-operations.patch
+drm-mediatek-separate-poweron-poweroff-from-enable-d.patch
+drm-mediatek-add-pull-down-mipi-operation-in-mtk_dsi.patch
+drm-meson-encoder_cvbs-fix-refcount-leak-in-meson_en.patch
+drm-meson-encoder_hdmi-fix-refcount-leak-in-meson_en.patch
+drm-bridge-lt9611uxc-cancel-only-driver-s-work.patch
+i2c-npcm-remove-own-slave-addresses-2-10.patch
+i2c-npcm-correct-slave-role-behavior.patch
+i2c-mxs-silence-a-clang-warning.patch
+virtio-gpu-fix-a-missing-check-to-avoid-null-derefer.patch
+drm-virtio-fix-null-vs-is_err-checking-in-virtio_gpu.patch
+drm-adv7511-override-i2c-address-of-cec-before-acces.patch
+crypto-sun8i-ss-do-not-allocate-memory-when-handling.patch
+crypto-sun8i-ss-fix-error-codes-in-allocate_flows.patch
+net-fix-sk_wmem_schedule-and-sk_rmem_schedule-errors.patch
+can-netlink-allow-configuring-of-fixed-bit-rates-wit.patch
+drm-vkms-check-plane_composer-map-0-before-using-it.patch
+can-netlink-allow-configuring-of-fixed-data-bit-rate.patch
+drm-bridge-it6505-add-missing-crypto_hash-dependency.patch
+i2c-fix-a-potential-use-after-free.patch
+tcp-fix-possible-freeze-in-tx-path-under-memory-pres.patch
+crypto-sun8i-ss-fix-infinite-loop-in-sun8i_ss_setup_.patch
+net-ag71xx-fix-discards-const-qualifier-warning.patch
+raw-use-more-conventional-iterators.patch
+raw-convert-raw-sockets-to-rcu.patch
+raw-fix-mixed-declarations-error-in-raw_icmp_error.patch
+media-atmel-atmel-sama7g5-isc-fix-warning-in-configs.patch
+media-camss-csid-fix-wrong-size-passed-to-devm_kmall.patch
+media-tw686x-register-the-irq-at-the-end-of-probe.patch
+media-amphion-return-error-if-format-is-unsupported-.patch
+media-hantro-correct-g2-init-qp-field.patch
+media-imx-jpeg-correct-some-definition-according-spe.patch
+media-imx-jpeg-leave-a-blank-space-before-the-config.patch
+media-imx-jpeg-refactor-function-mxc_jpeg_parse.patch
+media-imx-jpeg-identify-and-handle-precision-correct.patch
+media-imx-jpeg-handle-source-change-in-a-function.patch
+media-imx-jpeg-support-dynamic-resolution-change.patch
+media-imx-jpeg-align-upwards-buffer-size.patch
+media-imx-jpeg-implement-drain-using-v4l2-mem2mem-he.patch
+media-rcar-vin-fix-channel-routing-for-ebisu.patch
+ath9k-fix-use-after-free-in-ath9k_hif_usb_rx_cb.patch
+wifi-iwlegacy-4965-fix-potential-off-by-one-overflow.patch
+wifi-rtw89-8852a-rfk-fix-div-0-exception.patch
+drm-radeon-fix-incorrrect-spdx-license-identifiers.patch
+rcutorture-make-kvm.sh-allow-more-memory-for-kasan-r.patch
+torture-adjust-to-again-produce-debugging-informatio.patch
+rcutorture-fix-ksoftirqd-boosting-timing-and-iterati.patch
+test_bpf-fix-incorrect-netdev-features.patch
+selftests-bpf-fix-rare-segfault-in-sock_fields-prog-.patch
+crypto-ccp-during-shutdown-check-sev-data-pointer-be.patch
+drm-bridge-adv7511-add-check-for-mipi_dsi_driver_reg.patch
+media-imx-jpeg-disable-slot-interrupt-when-frame-don.patch
+media-amphion-output-firmware-error-message.patch
+drm-mcde-fix-refcount-leak-in-mcde_dsi_bind.patch
+media-hdpvr-fix-error-value-returns-in-hdpvr_read.patch
+media-v4l2-mem2mem-prevent-pollerr-when-last_buffer_.patch
+media-sta2x11-remove-virt_to_bus-dependency.patch
+media-mediatek-vcodec-initialize-decoder-parameters-.patch
+media-mediatek-vcodec-skip-source_change-eos-events-.patch
+media-driver-nxp-imx-jpeg-fix-a-unexpected-return-va.patch
+media-tw686x-fix-memory-leak-in-tw686x_video_init.patch
+media-mediatek-vcodec-fix-non-subdev-architecture-op.patch
+drm-vc4-kms-use-maximum-fifo-load-for-the-hvs-clock-.patch
+drm-vc4-plane-remove-subpixel-positioning-check.patch
+drm-vc4-plane-fix-margin-calculations-for-the-right-.patch
+drm-vc4-dsi-release-workaround-buffer-and-dma.patch
+drm-vc4-dsi-correct-dsi-divider-calculations.patch
+drm-vc4-dsi-correct-pixel-order-for-dsi0.patch
+drm-vc4-dsi-register-dsi0-as-the-correct-vc4-encoder.patch
+drm-vc4-dsi-fix-dsi0-interrupt-support.patch
+drm-vc4-dsi-add-correct-stop-condition-to-vc4_dsi_en.patch
+drm-vc4-hdmi-add-all-the-vc5-hdmi-registers-into-the.patch
+drm-vc4-hdmi-clear-unused-infoframe-packet-ram-regis.patch
+drm-vc4-hdmi-avoid-full-hdmi-audio-fifo-writes.patch
+drm-vc4-hdmi-reset-hdmi-misc_control-register.patch
+drm-vc4-hdmi-switch-to-pm_runtime_status_suspended.patch
+drm-vc4-hdmi-move-hdmi-reset-to-pm_resume.patch
+drm-vc4-hdmi-fix-timings-for-interlaced-modes.patch
+drm-vc4-hdmi-correct-hdmi-timing-registers-for-inter.patch
+drm-vc4-hdmi-move-pixel-doubling-from-pixelvalve-to-.patch
+mm-account-dirty-folios-properly-during-splits.patch
+crypto-arm64-gcm-select-aead-for-ghash_arm64_ce.patch
+selftests-xsk-destroy-bpf-resources-only-when-ctx-re.patch
+net-mscc-ocelot-delete-ocelot_port-xmit_template.patch
+net-mscc-ocelot-minimize-holes-in-struct-ocelot_port.patch
+net-dsa-felix-update-base-time-of-time-aware-shaper-.patch
+net-dsa-felix-keep-reference-on-entire-tc-taprio-con.patch
+net-dsa-felix-drop-oversized-frames-with-tc-taprio-i.patch
+drm-rockchip-vop-don-t-crash-for-invalid-duplicate_s.patch
+drm-rockchip-fix-an-error-handling-path-rockchip_dp_.patch
+drm-mediatek-dpi-remove-output-format-of-yuv.patch
+drm-mediatek-dpi-only-enable-dpi-after-the-bridge-is.patch
+drm-msm-hdmi-fill-the-pwr_regs-bulk-regulators.patch
+drm-msm-hdmi-enable-core-vcc-core-vdda-supply-for-89.patch
+drm-bridge-sii8620-fix-possible-off-by-one.patch
+net-sched-provide-shim-definitions-for-taprio_offloa.patch
+net-dsa-felix-build-as-module-when-tc-taprio-is-modu.patch
+hinic-use-the-bitmap-api-when-applicable.patch
+net-hinic-fix-bug-that-ethtool-get-wrong-stats.patch
+net-hinic-avoid-kernel-hung-in-hinic_get_stats64.patch
+drm-bridge-anx7625-fix-null-pointer-crash-when-using.patch
+drm-msm-avoid-unclocked-gmu-register-access-in-6xx-g.patch
+libbpf-riscv-use-a0-for-rc-register.patch
+drm-msm-mdp5-fix-global-state-lock-backoff.patch
+drm-radeon-avoid-bogus-vram-limit-0-must-be-a-power-.patch
+crypto-hisilicon-sec-don-t-sleep-when-in-softirq.patch
+crypto-hisilicon-kunpeng916-crypto-driver-don-t-slee.patch
+media-platform-mtk-mdp-fix-mdp_ipi_comm-structure-al.patch
+media-amphion-release-core-lock-before-reset-vpu-cor.patch
+drm-msm-dpu-fix-for-non-visible-planes.patch
+media-mediatek-vcodec-initialize-decoder-parameters-.patch-32105
+media-amphion-defer-setting-last_buffer_dequeued-unt.patch
+media-hantro-add-support-for-hantro-g1-on-rk356x.patch
+media-staging-media-hantro-fix-typos.patch
+media-hantro-hevc-fix-output-frame-chroma-offset.patch
+media-hantro-hevc-fix-reference-frames-management.patch
+media-hantro-be-more-accurate-on-pixel-formats-step_.patch
+media-hantro-fix-rk3399-h.264-format-advertising.patch
+media-amphion-decoder-copy-timestamp-from-output-to-.patch
+media-amphion-sync-buffer-status-with-firmware-durin.patch
+media-amphion-only-insert-the-first-sequence-startco.patch
+mt76-mt76x02u-fix-possible-memory-leak-in-__mt76x02u.patch
+mt76-mt7921s-fix-firmware-download-random-fail.patch
+mt76-mt7615-do-not-update-pm-stats-in-case-of-error.patch
+mt76-mt7921-do-not-update-pm-states-in-case-of-error.patch
+mt76-mt7921s-fix-possible-sdio-deadlock-in-command-f.patch
+mt76-mt7921-fix-aggregation-subframes-setting-to-he-.patch
+mt76-mt7921-enlarge-maximum-vht-mpdu-length-to-11454.patch
+mt76-mt7921-add-ap-mode-support.patch
+mt76-mt7915-add-support-for-6g-in-band-discovery.patch
+mt76-mt7921-rely-on-mt76_dev-in-mt7921_mac_write_txw.patch
+mt76-mt7915-rely-on-mt76_dev-in-mt7915_mac_write_txw.patch
+mt76-connac-move-mac-connac2-defs-in-mt76_connac2_ma.patch
+mt76-connac-move-connac2_mac_write_txwi-in-mt76_conn.patch
+mt76-mt7915-fix-incorrect-testmode-ipg-on-band-1-cau.patch
+mt76-mt7615-fix-throughput-regression-on-dfs-channel.patch
+mediatek-mt76-mac80211-fix-missing-of_node_put-in-mt.patch
+mediatek-mt76-eeprom-fix-missing-of_node_put-in-mt76.patch
+skmsg-fix-invalid-last-sg-check-in-sk_msg_recvmsg.patch
+drm-exynos-exynos7_drm_decon-free-resources-when-clk.patch
+bpftool-add-missing-link-types.patch
+bpf-x86-generate-trampolines-from-bpf_tramp_links.patch
+bpf-x64-add-predicate-for-bpf2bpf-with-tailcalls-sup.patch
+bpf-x86-fix-freeing-of-not-finalized-bpf_prog_pack.patch
+tcp-make-retransmitted-skb-fit-into-the-send-window.patch
+libbpf-fix-the-name-of-a-reused-map.patch
+kunit-executor-fix-a-memory-leak-on-failure-in-kunit.patch
+selftests-timers-valid-adjtimex-build-fix-for-newer-.patch
+selftests-timers-clocksource-switch-fix-passing-erro.patch
+bpf-fix-subprog-names-in-stack-traces.patch
+fs-check-fmode_lseek-to-control-internal-pipe-splici.patch
+media-cedrus-h265-fix-flag-name.patch
+media-uapi-hevc-change-pic_order_cnt-definition-in-v.patch
+media-cedrus-h265-fix-logic-for-not-low-delay-flag.patch
+wifi-wil6210-debugfs-fix-info-leak-in-wil_write_file.patch
+wifi-p54-fix-an-error-handling-path-in-p54spi_probe.patch
+wifi-p54-add-missing-parentheses-in-p54_flush.patch
+drm-amdgpu-use-the-same-hdp-flush-registers-for-all-.patch
+drm-amdgpu-use-the-same-hdp-flush-registers-for-all-.patch-20732
+drm-amdgpu-cleanup-ctx-implementation.patch
+drm-amdgpu-restore-original-stable-pstate-on-ctx-fin.patch
+bpf-make-btf_find_field-more-generic.patch
+bpf-move-check_ptr_off_reg-before-check_map_access.patch
+bpf-allow-storing-unreferenced-kptr-in-map.patch
+bpf-tag-argument-to-be-released-in-bpf_func_proto.patch
+bpf-allow-storing-referenced-kptr-in-map.patch
+bpf-adapt-copy_map_value-for-multiple-offset-case.patch
+bpf-populate-pairs-of-btf_id-and-destructor-kfunc-in.patch
+bpf-wire-up-freeing-of-referenced-kptr.patch
+bpf-fix-potential-32-bit-overflow-when-accessing-arr.patch
+selftests-bpf-fix-a-test-for-snprintf-overflow.patch
+libbpf-fix-an-snprintf-overflow-check.patch
+can-pch_can-do-not-report-txerr-and-rxerr-during-bus.patch
+can-rcar_can-do-not-report-txerr-and-rxerr-during-bu.patch
+can-sja1000-do-not-report-txerr-and-rxerr-during-bus.patch
+can-hi311x-do-not-report-txerr-and-rxerr-during-bus-.patch
+can-sun4i_can-do-not-report-txerr-and-rxerr-during-b.patch
+can-kvaser_usb_hydra-do-not-report-txerr-and-rxerr-d.patch
+can-kvaser_usb_leaf-do-not-report-txerr-and-rxerr-du.patch
+can-usb_8dev-do-not-report-txerr-and-rxerr-during-bu.patch
+can-error-specify-the-values-of-data-5.7-of-can-erro.patch
+can-pch_can-pch_can_error-initialize-errc-before-usi.patch
+bluetooth-hci_intel-add-check-for-platform_driver_re.patch
+bluetooth-when-hci-work-queue-is-drained-only-queue-.patch
+bluetooth-mgmt-fix-refresh-cached-connection-info.patch
+bluetooth-hci_sync-fix-resuming-scan-after-suspend-r.patch
+bluetooth-hci_sync-fix-not-updating-privacy_mode.patch
+bluetooth-add-default-wakeup-callback-for-hci-uart-d.patch
+i2c-cadence-support-pec-for-smbus-block-read.patch
+i2c-qcom-geni-use-the-correct-return-value.patch
+bpf-fix-bpf_xdp_pointer-return-pointer.patch
+i2c-mux-gpmux-add-of_node_put-when-breaking-out-of-l.patch
+wifi-wil6210-debugfs-fix-uninitialized-variable-use-.patch
+wifi-iwlwifi-mvm-fix-double-list_add-at-iwl_mvm_mac_.patch
+wifi-libertas-fix-possible-refcount-leak-in-if_usb_p.patch
+media-cedrus-hevc-add-check-for-invalid-timestamp.patch
+hantro-remove-incorrect-hevc-sps-validation.patch
+drm-amd-display-fix-signedness-bug-in-execute_synapt.patch
+net-mlx5e-remove-warn_on-when-trying-to-offload-an-u.patch
+net-mlx5e-tc-fix-post_act-to-not-match-on-in_port-me.patch
+net-mlx5e-fix-the-value-of-mlx5e_max_rq_num_mtts.patch
+net-mlx5e-xsk-account-for-xsk-rq-umrs-when-calculati.patch
+net-mlx5e-fix-calculations-related-to-max-mpwqe-size.patch
+net-mlx5e-modify-slow-path-rules-to-go-to-slow-fdb.patch
+net-mlx5-adjust-log_max_qp-to-be-18-at-most.patch
+net-mlx5-dr-fix-smfs-steering-info-dump-format.patch
+net-mlx5-fix-driver-use-of-uninitialized-timeout.patch
+ax25-fix-incorrect-dev_tracker-usage.patch
+crypto-hisilicon-hpre-don-t-use-gfp_kernel-to-alloc-.patch
+crypto-inside-secure-add-missing-module_device_table.patch
+crypto-hisilicon-sec-fix-auth-key-size-error.patch
+inet-add-read_once-sk-sk_bound_dev_if-in-inet_match.patch
+ipv6-add-read_once-sk-sk_bound_dev_if-in-inet6_match.patch
+net-allow-unbound-socket-for-packets-in-vrf-when-tcp.patch
+netdevsim-fib-fix-reference-count-leak-on-route-dele.patch
+wifi-rtw88-check-the-return-value-of-alloc_workqueue.patch
+iavf-fix-max_rate-limiting.patch
+iavf-fix-tc-qdisc-show-listing-too-many-queues.patch
+netdevsim-avoid-allocation-warnings-triggered-from-u.patch
+net-rose-fix-netdev-reference-changes.patch
+net-ice-fix-error-netif_f_hw_vlan_ctag_filter-check-.patch
+net-ionic-fix-error-check-for-vlan-flags-in-ionic_se.patch
+dccp-put-dccp_qpolicy_full-and-dccp_qpolicy_push-in-.patch
+net-usb-make-usb_rtl8153_ecm-non-user-configurable.patch
+net-mlx5e-xsk-discard-unaligned-xsk-frames-on-stridi.patch
+wireguard-ratelimiter-use-hrtimer-in-selftest.patch
+wireguard-allowedips-don-t-corrupt-stack-when-detect.patch
+hid-amd_sfh-don-t-show-client-init-failed-as-error-w.patch
+clk-renesas-r9a06g032-fix-uart-clkgrp-bitsel.patch
+mtd-maps-fix-refcount-leak-in-of_flash_probe_versati.patch
+mtd-maps-fix-refcount-leak-in-ap_flash_init.patch
+mtd-rawnand-meson-fix-a-potential-double-free-issue.patch
+clk-renesas-rzg2l-fix-reset-status-function.patch
+of-check-previous-kernel-s-ima-kexec-buffer-against-.patch
+scsi-qla2xxx-edif-reduce-initiator-initiator-thrashi.patch
+scsi-qla2xxx-edif-bsg-refactor.patch
+scsi-qla2xxx-edif-wait-for-app-to-ack-on-sess-down.patch
+scsi-qla2xxx-edif-add-bsg-interface-to-read-doorbell.patch
+scsi-qla2xxx-edif-fix-potential-stuck-session-in-sa-.patch
+scsi-qla2xxx-edif-synchronize-npiv-deletion-with-aut.patch
+scsi-qla2xxx-edif-add-retry-for-els-passthrough.patch
+scsi-qla2xxx-edif-fix-n2n-discovery-issue-with-secur.patch
+scsi-qla2xxx-edif-fix-n2n-login-retry-for-secure-dev.patch
+kvm-svm-unwind-speculative-rip-advancement-if-intn-i.patch
+kvm-svm-stuff-next_rip-on-emulated-int3-injection-if.patch
+kvm-x86-mmu-drop-rwx-0-sptes-during-ept_sync_page.patch
+phy-samsung-exynosautov9-ufs-correct-tsrv-register-c.patch
+pci-microchip-fix-refcount-leak-in-mc_pcie_init_irq_.patch
+pci-tegra194-fix-pm-error-handling-in-tegra_pcie_con.patch
+hid-cp2112-prevent-a-buffer-overflow-in-cp2112_xfer.patch
+mtd-sm_ftl-fix-deadlock-caused-by-cancel_work_sync-i.patch
+mtd-partitions-fix-refcount-leak-in-parse_redboot_of.patch
+mtd-parsers-ofpart-fix-refcount-leak-in-bcm4908_part.patch
+mtd-st_spi_fsm-add-a-clk_disable_unprepare-in-.probe.patch
+pci-mediatek-gen3-fix-refcount-leak-in-mtk_pcie_init.patch
+fpga-altera-pr-ip-fix-unsigned-comparison-with-less-.patch
+usb-host-fix-refcount-leak-in-ehci_hcd_ppc_of_probe.patch
+usb-ohci-nxp-fix-refcount-leak-in-ohci_hcd_nxp_probe.patch
+usb-gadget-tegra-xudc-fix-error-check-in-tegra_xudc_.patch
+usb-xhci-tegra-fix-error-check.patch
+netfilter-xtables-bring-spdx-identifier-back.patch
+scsi-qla2xxx-edif-send-logo-for-unexpected-ike-messa.patch
+scsi-qla2xxx-edif-reduce-disruption-due-to-multiple-.patch
+scsi-qla2xxx-edif-fix-no-login-after-app-start.patch
+scsi-qla2xxx-edif-tear-down-session-if-keys-have-bee.patch
+scsi-qla2xxx-edif-fix-session-thrash.patch
+scsi-qla2xxx-edif-fix-no-logout-on-delete-for-n2n.patch
+scsi-qla2xxx-edif-reduce-n2n-thrashing-at-app_start-.patch
+iio-accel-bma400-fix-the-scale-min-and-max-macro-val.patch
+platform-chrome-cros_ec-always-expose-last-resume-re.patch
+iio-sx9324-fix-register-field-spelling.patch
+iio-accel-bma400-reordering-of-header-files.patch
+iio-accel-bma400-conversion-to-device-managed-functi.patch
+iio-core-fix-iio_align-and-rename-as-it-was-not-suff.patch
+iio-accel-adxl313-fix-alignment-for-dma-safety.patch
+iio-accel-adxl355-fix-alignment-for-dma-safety.patch
+iio-accel-adxl367-fix-alignment-for-dma-safety.patch
+iio-accel-bma220-fix-alignment-for-dma-safety.patch
+iio-accel-sca3000-fix-alignment-for-dma-safety.patch
+iio-accel-sca3300-fix-alignment-for-dma-safety.patch
+iio-adc-ad7266-fix-alignment-for-dma-safety.patch
+iio-adc-ad7280a-fix-alignment-for-dma-safety.patch
+iio-adc-ad7292-fix-alignment-for-dma-safety.patch
+iio-adc-ad7298-fix-alignment-for-dma-safety.patch
+iio-adc-ad7476-fix-alignment-for-dma-safety.patch
+iio-adc-ad7606-fix-alignment-for-dma-safety.patch
+iio-adc-ad7766-fix-alignment-for-dma-safety.patch
+iio-adc-ad7768-1-fix-alignment-for-dma-safety.patch
+iio-adc-ad7887-fix-alignment-for-dma-safety.patch
+iio-adc-ad7923-fix-alignment-for-dma-safety.patch
+iio-adc-ad7949-fix-alignment-for-dma-safety.patch
+iio-adc-hi8435-fix-alignment-for-dma-safety.patch
+iio-adc-ltc2496-fix-alignment-for-dma-safety.patch
+iio-adc-ltc2497-fix-alignment-for-dma-safety.patch
+iio-adc-max1027-fix-alignment-for-dma-safety.patch
+iio-adc-max11100-fix-alignment-for-dma-safety.patch
+iio-adc-max1118-fix-alignment-for-dma-safety.patch
+iio-adc-max1241-fix-alignment-for-dma-safety.patch
+iio-adc-mcp320x-fix-alignment-for-dma-safety.patch
+iio-adc-ti-adc0832-fix-alignment-for-dma-safety.patch
+iio-adc-ti-adc084s021-fix-alignment-for-dma-safety.patch
+iio-adc-ti-adc108s102-fix-alignment-for-dma-safety.patch
+iio-adc-ti-adc12138-fix-alignment-for-dma-safety.patch
+iio-adc-ti-adc128s052-fix-alignment-for-dma-safety.patch
+iio-adc-ti-adc161s626-fix-alignment-for-dma-safety.patch
+iio-adc-ti-ads124s08-fix-alignment-for-dma-safety.patch
+iio-adc-ti-ads131e08-fix-alignment-for-dma-safety.patch
+iio-adc-ti-ads7950-fix-alignment-for-dma-safety.patch
+iio-adc-ti-ads8344-fix-alignment-for-dma-safety.patch
+iio-adc-ti-ads8688-fix-alignment-for-dma-safety.patch
+iio-adc-ti-tlc4541-fix-alignment-for-dma-safety.patch
+iio-addac-ad74413r-fix-alignment-for-dma-safety.patch
+iio-amplifiers-ad8366-fix-alignment-for-dma-safety.patch
+iio-common-ssp-fix-alignment-for-dma-safety.patch
+iio-dac-ad5064-fix-alignment-for-dma-safety.patch
+iio-dac-ad5360-fix-alignment-for-dma-safety.patch
+iio-dac-ad5421-fix-alignment-for-dma-safety.patch
+iio-dac-ad5449-fix-alignment-for-dma-safety.patch
+iio-dac-ad5504-fix-alignment-for-dma-safety.patch
+iio-dac-ad5592r-fix-alignment-for-dma-safety.patch
+iio-dac-ad5686-fix-alignment-for-dma-safety.patch
+iio-dac-ad5755-fix-alignment-for-dma-safety.patch
+iio-dac-ad5761-fix-alignment-for-dma-safety.patch
+iio-dac-ad5764-fix-alignment-for-dma-safety.patch
+iio-dac-ad5766-fix-alignment-for-dma-safety.patch
+iio-dac-ad5770r-fix-alignment-for-dma-safety.patch
+iio-dac-ad5791-fix-alignment-for-dma-saftey.patch
+iio-dac-ad7293-fix-alignment-for-dma-safety.patch
+iio-dac-ad7303-fix-alignment-for-dma-safety.patch
+iio-dac-ad8801-fix-alignment-for-dma-safety.patch
+iio-dac-ltc2688-fix-alignment-for-dma-safety.patch
+iio-dac-mcp4922-fix-alignment-for-dma-safety.patch
+iio-dac-ti-dac082s085-fix-alignment-for-dma-safety.patch
+iio-dac-ti-dac5571-fix-alignment-for-dma-safety.patch
+iio-dac-ti-dac7311-fix-alignment-for-dma-safety.patch
+iio-dac-ti-dac7612-fix-alignment-for-dma-safety.patch
+iio-frequency-ad9523-fix-alignment-for-dma-safety.patch
+iio-frequency-adf4350-fix-alignment-for-dma-safety.patch
+iio-frequency-adf4371-fix-alignment-for-dma-safety.patch
+iio-frequency-admv1013-fix-alignment-for-dma-safety.patch
+iio-frequency-admv1014-fix-alignment-for-dma-safety.patch
+iio-frequency-admv4420-fix-alignment-for-dma-safety.patch
+iio-frequency-adrf6780-fix-alignment-for-dma-safety.patch
+iio-gyro-adis16080-fix-alignment-for-dma-safety.patch
+iio-gyro-adis16130-fix-alignment-for-dma-safety.patch
+iio-gyro-adxrs450-fix-alignment-for-dma-safety.patch
+iio-gyro-fxas210002c-fix-alignment-for-dma-safety.patch
+iio-imu-fxos8700-fix-alignment-for-dma-safety.patch
+iio-imu-inv_icm42600-fix-alignment-for-dma-safety.patch
+iio-imu-inv_icm42600-fix-alignment-for-dma-safety-in.patch
+iio-imu-mpu6050-fix-alignment-for-dma-safety.patch
+iio-potentiometer-ad5110-fix-alignment-for-dma-safet.patch
+iio-potentiometer-ad5272-fix-alignment-for-dma-safet.patch
+iio-potentiometer-max5481-fix-alignment-for-dma-safe.patch
+iio-potentiometer-mcp41010-fix-alignment-for-dma-saf.patch
+iio-potentiometer-mcp4131-fix-alignment-for-dma-safe.patch
+iio-proximity-as3935-fix-alignment-for-dma-safety.patch
+iio-resolver-ad2s1200-fix-alignment-for-dma-safety.patch
+iio-resolver-ad2s90-fix-alignment-for-dma-safety.patch
+iio-temp-ltc2983-fix-alignment-for-dma-safety.patch
+iio-temp-max31865-fix-alignment-for-dma-safety.patch
+iio-temp-maxim_thermocouple-fix-alignment-for-dma-sa.patch
+clk-mediatek-reset-fix-written-reset-bit-offset.patch
+clk-imx93-use-adc_root-as-the-parent-clock-of-adc1.patch
+clk-imx93-correct-nic_media-parent.patch
+clk-imx-clk-fracn-gppll-fix-mfd-value.patch
+clk-imx-clk-fracn-gppll-return-rate-in-rate-table-pr.patch
+clk-imx-clk-fracn-gppll-correct-rdiv.patch
+rdma-rxe-fix-xa_alloc_cycle-error-return-value-check.patch
+lib-test_hmm-avoid-accessing-uninitialized-pages.patch
+mm-memremap-fix-memunmap_pages-race-with-get_dev_pag.patch
+kvm-don-t-set-accessed-dirty-bits-for-zero_page.patch
+mwifiex-fix-sleep-in-atomic-context-bugs-caused-by-d.patch
+scsi-iscsi-allow-iscsi_if_stop_conn-to-be-called-fro.patch
+scsi-iscsi-add-helper-to-remove-a-session-from-the-k.patch
+scsi-iscsi-fix-session-removal-on-shutdown.patch
+dmaengine-dw-edma-fix-edma-rd-wr-channels-and-dma-di.patch
+kvm-x86-fix-errant-brace-in-kvm-capability-handling.patch
+mtd-hyperbus-rpc-if-fix-rpm-imbalance-in-probe-error.patch
+mtd-dataflash-add-spi-id-table.patch
+clk-qcom-camcc-sm8250-fix-halt-on-boot-by-reducing-d.patch
+misc-rtsx-fix-an-error-handling-path-in-rtsx_pci_pro.patch
+driver-core-fix-potential-deadlock-in-__driver_attac.patch
+clk-qcom-clk-krait-unlock-spin-after-mux-completion.patch
+coresight-configfs-fix-unload-of-configurations-on-m.patch
+coresight-syscfg-update-load-and-unload-operations.patch
+usb-gadget-f_mass_storage-make-cd-rom-emulation-work.patch
+clk-qcom-gcc-msm8939-add-missing-system_mm_noc_bfdcd.patch
+clk-qcom-gcc-msm8939-fix-bimc_ddr_clk_src-rcgr-base-.patch
+clk-qcom-gcc-msm8939-add-missing-system_mm_noc_bfdcd.patch-24834
+clk-qcom-gcc-msm8939-point-mm-peripherals-to-system_.patch
+usb-host-xhci-use-snprintf-in-xhci_decode_trb.patch
+rdma-rxe-fix-deadlock-in-rxe_do_local_ops.patch
+clk-qcom-ipq8074-fix-nss-core-pll-s.patch
+clk-qcom-ipq8074-sw-workaround-for-ubi32-pll-lock.patch
+clk-qcom-ipq8074-fix-nss-port-frequency-tables.patch
+clk-qcom-ipq8074-set-branch_halt_delay-flag-for-ubi-.patch
+clk-qcom-camcc-sdm845-fix-topology-around-titan_top-.patch
+clk-qcom-camcc-sm8250-fix-topology-around-titan_top-.patch
+clk-qcom-clk-rcg2-fail-duty-cycle-configuration-if-m.patch
+clk-qcom-clk-rcg2-make-sure-to-not-write-d-0-to-the-.patch
+kernfs-fix-potential-null-dereference-in-__kernfs_re.patch
+mm-rmap-use-the-correct-parameter-name-for-define_pa.patch
+mm-migration-return-errno-when-isolate_huge_page-fai.patch
+mm-migration-fix-potential-pte_unmap-on-an-not-mappe.patch
+kasan-fix-zeroing-vmalloc-memory-with-hw_tags.patch
+mm-mempolicy-fix-get_nodes-out-of-bound-access.patch
+phy-ti-tusb1210-don-t-check-for-write-errors-when-po.patch
+pci-dwc-stop-link-on-host_init-errors-and-de-initial.patch
+pci-dwc-add-unroll-iatu-space-support-to-dw_pcie_dis.patch
+pci-dwc-disable-outbound-windows-only-for-controller.patch
+pci-dwc-set-increase_region_size-flag-based-on-limit.patch
+pci-dwc-deallocate-epc-memory-on-dw_pcie_ep_init-err.patch
+pci-dwc-always-enable-cdm-check-if-snps-enable-cdm-c.patch
+soundwire-bus_type-fix-remove-and-shutdown-support.patch
+soundwire-revisit-driver-bind-unbind-and-callbacks.patch
+kvm-arm64-don-t-return-from-void-function.patch
+dmaengine-sf-pdma-add-multithread-support-for-a-dma-.patch
+pci-endpoint-don-t-stop-controller-when-unbinding-en.patch
+phy-qcom-qmp-fix-the-qserdes_v5_com_cmn_mode-registe.patch
+scsi-qla2xxx-check-correct-variable-in-qla24xx_async.patch
+intel_th-fix-a-resource-leak-in-an-error-handling-pa.patch
+intel_th-msu-sink-potential-dereference-of-null-poin.patch
+intel_th-msu-fix-vmalloced-buffers.patch
+binder-fix-redefinition-of-seq_file-attributes.patch
+staging-rtl8192u-fix-sleep-in-atomic-context-bug-in-.patch
+rtla-utils-use-calloc-and-check-the-potential-memory.patch
+mmc-sdhci-of-esdhc-fix-refcount-leak-in-esdhc_signal.patch
+mmc-mxcmmc-silence-a-clang-warning.patch
+mmc-renesas_sdhi-get-the-reset-handle-early-in-the-p.patch
+memstick-ms_block-fix-some-incorrect-memory-allocati.patch
+memstick-ms_block-fix-a-memory-leak.patch
+mmc-sdhci-of-at91-fix-set_uhs_signaling-rewriting-of.patch
+of-device-fix-missing-of_node_put-in-of_dma_set_rest.patch
+mmc-block-add-single-read-for-4k-sector-cards.patch
+kvm-s390-pv-leak-the-topmost-page-table-when-destroy.patch
+pci-portdrv-don-t-disable-aer-reporting-in-get_port_.patch
+pci-qcom-set-up-rev-2.1.0-parf_phy-before-enabling-c.patch
+scsi-smartpqi-fix-dma-direction-for-raid-requests.patch
+xtensa-iss-network-provide-release-callback.patch
+xtensa-iss-fix-handling-error-cases-in-iss_net_confi.patch
+usb-gadget-udc-amd5536-depends-on-has_dma.patch
+usb-aspeed-vhub-fix-refcount-leak-bug-in-ast_vhub_in.patch
+usb-dwc3-core-deprecate-gctl.coresoftreset.patch
+usb-dwc3-core-do-not-perform-gctl_core_softreset-dur.patch
+usb-dwc3-qcom-fix-missing-optional-irq-warnings.patch
+eeprom-idt_89hpesx-uninitialized-data-in-idt_dbgfs_c.patch
+phy-stm32-fix-error-return-in-stm32_usbphyc_phy_init.patch
+phy-rockchip-inno-usb2-ignore-otg-irqs-in-host-mode.patch
+interconnect-imx-fix-max_node_id.patch
+um-random-don-t-initialise-hwrng-struct-with-zero.patch
+rdma-irdma-fix-a-window-for-use-after-free.patch
+rdma-irdma-fix-vlan-connection-with-wildcard-address.patch
+rdma-irdma-fix-setting-of-qp-context-err_rq_idx_vali.patch
+rdma-rtrs-srv-fix-modinfo-output-for-stringify.patch
+rdma-rtrs-clt-replace-list_next_or_null_rr_rcu-with-.patch
+rdma-qedr-fix-potential-memory-leak-in-__qedr_alloc_.patch
+rdma-hns-fix-incorrect-clearing-of-interrupt-status-.patch
+rdma-siw-fix-duplicated-reported-iw_cm_event_connect.patch
+iio-cros-register-fifo-callback-after-sensor-is-regi.patch
+clk-qcom-drop-mmcx-gdsc-supply-for-dispcc-and-videoc.patch
+clk-qcom-gdsc-bump-parent-usage-count-when-gdsc-is-f.patch
+clk-qcom-gcc-msm8939-fix-weird-field-spacing-in-ftbl.patch
+rdma-hfi1-fix-potential-memory-leak-in-setup_base_ct.patch
+gpio-gpiolib-of-fix-refcount-bugs-in-of_mm_gpiochip_.patch
+iio-adc-max1027-unlock-on-error-path-in-max1027_read.patch
+hid-mcp2221-prevent-a-buffer-overflow-in-mcp_smbus_w.patch
+hid-amd_sfh-add-null-check-for-hid-device.patch
+dmaengine-imx-dma-cast-of_device_get_match_data-with.patch
+scripts-gdb-fix-lx-dmesg-on-32-bits-arch.patch
+rdma-rxe-fix-mw-bind-to-allow-any-consumer-key-porti.patch
+mmc-core-quirks-add-of_node_put-when-breaking-out-of.patch
+mmc-cavium-octeon-add-of_node_put-when-breaking-out-.patch
+mmc-cavium-thunderx-add-of_node_put-when-breaking-ou.patch
+hid-alps-declare-u1_unicorn_legacy-support.patch
+rdma-rxe-for-invalidate-compare-according-to-set-key.patch
+rdma-rxe-fix-rnr-retry-behavior.patch
+pci-tegra194-fix-root-port-interrupt-handling.patch
+pci-tegra194-fix-link-up-retry-sequence.patch
+hid-amd_sfh-handle-condition-of-no-sensors.patch
+usb-serial-fix-tty-port-initialized-comments.patch
+usb-cdns3-change-place-of-priv_ep-assignment-in-cdns.patch
+mtd-spi-nor-fix-spi_nor_spimem_setup_op-call-in-spi_.patch
+staging-fbtft-core-set-smem_len-before-fb_deferred_i.patch
+kvm-nvmx-set-umip-bit-cr4_fixed1-msr-when-emulating-.patch
+tools-power-x86-intel-speed-select-fix-off-by-one-ch.patch
+platform-x86-pmc_atom-match-all-lex-baytrail-boards-.patch
+platform-mellanox-mlxreg-lc-fix-error-flow-and-exten.patch
+platform-olpc-fix-uninitialized-data-in-debugfs-writ.patch
+rdma-srpt-duplicate-port-name-members.patch
+rdma-srpt-introduce-a-reference-count-in-struct-srpt.patch
+rdma-srpt-fix-a-use-after-free.patch
+android-binder-stop-saving-a-pointer-to-the-vma.patch
+mm-mmap.c-fix-missing-call-to-vm_unacct_memory-in-mm.patch
+tools-testing-selftests-vm-hugetlb-madvise.c-silence.patch
+selftest-vm-uninitialized-variable-in-main.patch
+rtla-fix-makefile-when-called-from-c-tools.patch
+rtla-fix-double-free.patch
+selftests-kvm-set-rax-before-vmcall.patch
+of-fdt-declared-return-type-does-not-match-actual-re.patch
+rdma-mlx5-add-missing-check-for-return-value-in-get-.patch
+rdma-rxe-fix-error-unwind-in-rxe_create_qp.patch
+block-rnbd-srv-set-keep_id-to-true-after-mutex_trylo.patch
+null_blk-fix-ida-error-handling-in-null_add_dev.patch
+nvme-use-command_id-instead-of-req-tag-in-trace_nvme.patch
+nvme-define-compat_ioctl-again-to-unbreak-32-bit-use.patch
+nvme-catch-enodev-from-nvme_revalidate_zones-again.patch
+block-bio-remove-duplicate-append-pages-code.patch
+block-ensure-iov_iter-advances-for-added-pages.patch
+jbd2-fix-outstanding-credits-assert-in-jbd2_journal_.patch
+ext4-recover-csum-seed-of-tmp_inode-after-migrating-.patch
+jbd2-fix-assertion-jh-b_frozen_data-null-failure-whe.patch
+usb-cdns3-don-t-use-priv_dev-uninitialized-in-cdns3_.patch
+opp-fix-error-check-in-dev_pm_opp_attach_genpd.patch
+asoc-cros_ec_codec-fix-refcount-leak-in-cros_ec_code.patch
+asoc-samsung-fix-error-handling-in-aries_audio_probe.patch
+asoc-imx-audmux-silence-a-clang-warning.patch
+asoc-mediatek-mt8173-fix-refcount-leak-in-mt8173_rt5.patch
+asoc-mt6797-mt6351-fix-refcount-leak-in-mt6797_mt635.patch
+asoc-codecs-da7210-add-check-for-i2c_add_driver.patch
+asoc-mediatek-mt8173-rt5650-fix-refcount-leak-in-mt8.patch
+serial-pic32-free-up-irq-names-correctly.patch
+serial-pic32-fix-missing-clk_disable_unprepare-on-er.patch
+serial-8250-export-icr-access-helpers-for-internal-u.patch
+serial-store-character-timing-information-to-uart_po.patch
+asoc-sof-make-ctx_store-and-ctx_restore-as-optional.patch
+asoc-codecs-msm8916-wcd-digital-move-gains-from-sx_t.patch
+asoc-codecs-wcd9335-move-gains-from-sx_tlv-to-s8_tlv.patch
+rpmsg-char-add-mutex-protection-for-rpmsg_eptdev_ope.patch
+rpmsg-mtk_rpmsg-fix-circular-locking-dependency.patch
+remoteproc-k3-r5-fix-refcount-leak-in-k3_r5_cluster_.patch
+selftests-livepatch-better-synchronize-test_klp_call.patch
+profiling-fix-shift-too-large-makes-kernel-panic.patch
+remoteproc-imx_rproc-fix-refcount-leak-in-imx_rproc_.patch
+selftests-powerpc-skip-energy_scale_info-test-on-old.patch
+asoc-samsung-h1940_uda1380-include-proepr-gpio-consu.patch
+powerpc-perf-optimize-clearing-the-pending-pmi-and-r.patch
+asoc-samsung-change-gpiod_speaker_power-and-rx1950_a.patch
+asoc-codecs-wsa881x-handle-timeouts-in-resume-path.patch
+net-mlx5-expose-mlx5_sriov_blocking_notifier_registe.patch
+vfio-pci-have-all-vfio-pci-drivers-store-the-vfio_pc.patch
+net-ice-fix-initializing-the-bitmap-in-the-switch-co.patch
+tty-n_gsm-fix-user-open-not-possible-at-responder-un.patch
+tty-n_gsm-fix-tty-registration-before-control-channe.patch
+tty-n_gsm-fix-wrong-queuing-behavior-in-gsm_dlci_dat.patch
+tty-n_gsm-fix-missing-timer-to-handle-stalled-links.patch
+tty-n_gsm-fix-non-flow-control-frames-during-mux-flo.patch
+tty-n_gsm-fix-packet-re-transmission-without-open-co.patch
+tty-n_gsm-fix-race-condition-in-gsmld_write.patch
+tty-n_gsm-fix-deadlock-and-link-starvation-in-outgoi.patch
+tty-n_gsm-fix-resource-allocation-order-in-gsm_activ.patch
+asoc-qcom-fix-missing-of_node_put-in-asoc_qcom_lpass.patch
+mips-loongson64-fix-section-mismatch-warning.patch
+asoc-imx-card-fix-dsd-pdm-mclk-frequency.patch
+remoteproc-qcom-wcnss-fix-handling-of-irqs.patch
+vfio-ccw-fix-fsm-state-if-mdev-probe-fails.patch
+vfio-ccw-do-not-change-fsm-state-in-subchannel-event.patch
+asoc-audio-graph-card2.c-use-of_property_read_u32-fo.patch
+serial-8250_fsl-don-t-report-fe-pe-and-oe-twice.patch
+tty-n_gsm-fix-wrong-t1-retry-count-handling.patch
+tty-n_gsm-fix-dm-command.patch
+tty-n_gsm-fix-flow-control-handling-in-tx-path.patch
+tty-n_gsm-fix-missing-corner-cases-in-gsmld_poll.patch
+mips-vdso-utilize-__pa-for-gic_pfn.patch
+asoc-sof-mediatek-fix-mt8195-statvectorsel-wrong-set.patch
+swiotlb-fail-map-correctly-with-failed-io_tlb_defaul.patch
+asoc-sof-ipc3-topology-prevent-double-freeing-of-ipc.patch
+asoc-audio-graph-card2-fix-refcount-leak-bug-in-__gr.patch
+asoc-mt6359-fix-refcount-leak-bug.patch
+serial-8250_bcm7271-save-restore-rts-in-suspend-resu.patch
+iommu-exynos-handle-failed-iommu-device-registration.patch
+9p-drop-kref-usage.patch
+9p-add-client-parameter-to-p9_req_put.patch
+net-9p-fix-refcount-leak-in-p9_read_work-error-handl.patch
+mips-fixed-__debug_virt_addr_valid.patch
+rpmsg-qcom_smd-fix-refcount-leak-in-qcom_smd_parse_e.patch
+kfifo-fix-kfifo_to_user-return-type.patch
+lib-smp_processor_id-fix-imbalanced-instrumentation_.patch
+proc-fix-a-dentry-lock-race-between-release_task-and.patch
+remoteproc-qcom-pas-check-if-coredump-is-enabled.patch
+remoteproc-sysmon-wait-for-ssctl-service-to-come-up.patch
+mfd-t7l66xb-drop-platform-disable-callback.patch
+mfd-max77620-fix-refcount-leak-in-max77620_initialis.patch
+iommu-arm-smmu-qcom_iommu-add-of_node_put-when-break.patch
+perf-tools-fix-dso_id-inode-generation-comparison.patch
+riscv-spinwait-fix-hartid-variable-type.patch
+s390-crash-fix-incorrect-number-of-bytes-to-copy-to-.patch
+s390-zcore-fix-race-when-reading-from-hardware-syste.patch
+asoc-fsl_asrc-force-cast-the-asrc_format-type.patch
+asoc-fsl-asoc-card-force-cast-the-asrc_format-type.patch
+asoc-fsl_easrc-use-snd_pcm_format_t-type-for-sample_.patch
+asoc-imx-card-use-snd_pcm_format_t-type-for-asrc_for.patch
+asoc-qcom-q6dsp-fix-an-off-by-one-in-q6adm_alloc_cop.patch
+fuse-remove-the-control-interface-for-virtio-fs.patch
+asoc-audio-graph-card-add-of_node_put-in-fail-path.patch
+asoc-audio-graph-card2-add-of_node_put-in-fail-path.patch
+watchdog-f71808e_wdt-add-check-for-platform_driver_r.patch
+watchdog-sp5100_tco-fix-a-memory-leak-of-efch-mmio-r.patch
+watchdog-armada_37xx_wdt-check-the-return-value-of-d.patch
+asoc-intel-sof_rt5682-perform-quirk-check-first-in-c.patch
+video-fbdev-amba-clcd-fix-refcount-leak-bugs.patch
+video-fbdev-sis-fix-typos-in-sis_getmodeid.patch
+asoc-mchp-spdifrx-disable-end-of-block-interrupt-on-.patch
+powerpc-32-call-mmu_mark_initmem_nx-regardless-of-da.patch
+powerpc-32s-fix-boot-failure-with-kasan-smp-jump_lab.patch
+powerpc-32-do-not-allow-selection-of-e5500-or-e6500-.patch
+powerpc-fix-typos-in-comments.patch
+pseries-iommu-ddw-fix-kdump-to-work-in-absence-of-ib.patch
+powerpc-iommu-fix-iommu_table_in_use-for-a-small-def.patch
+powerpc-pci-prefer-pci-domain-assignment-via-dt-linu.patch
+serial-8250_bcm2835aux-add-missing-clk_disable_unpre.patch
+tty-serial-fsl_lpuart-correct-the-count-of-break-cha.patch
+s390-smp-enforce-lowcore-protection-on-cpu-restart.patch
+perf-stat-revert-perf-stat-add-default-hybrid-events.patch
+f2fs-fix-to-invalidate-meta_mapping-before-dio-write.patch
+f2fs-check-pinfile-in-gc_data_segment-in-advance.patch
+f2fs-don-t-set-gc_failure_pin-for-background-gc.patch
+f2fs-write-checkpoint-during-fg_gc.patch
+f2fs-give-priority-to-select-unpinned-section-for-fo.patch
+f2fs-change-the-current-atomic-write-way.patch
+f2fs-kill-volatile-write-support.patch
+f2fs-fix-to-check-inline_data-during-compressed-inod.patch
+f2fs-fix-to-remove-f2fs_compr_fl-and-tag-f2fs_nocomp.patch
+cifs-fix-memory-leak-when-using-fscache.patch
+powerpc-spufs-fix-refcount-leak-in-spufs_init_isolat.patch
+powerpc-xive-fix-refcount-leak-in-xive_get_max_prio.patch
+powerpc-cell-axon_msi-fix-refcount-leak-in-setup_msi.patch
+perf-symbol-fail-to-read-phdr-workaround.patch
+kprobes-forbid-probing-on-trampoline-and-bpf-code-ar.patch
+x86-bus_lock-don-t-assume-the-init-value-of-debugctl.patch
+powerpc-pci-fix-phb-numbering-when-using-opal-phbid.patch
+genelf-use-have_libcrypto_support-not-the-never-defi.patch
+scripts-faddr2line-fix-vmlinux-detection-on-arm64.patch
+powerpc-64e-fix-kexec-build-error.patch
+sched-cpuset-fix-dl_cpu_busy-panic-due-to-empty-cs-c.patch
+x86-numa-use-cpumask_available-instead-of-hardcoded-.patch
+video-fbdev-arkfb-fix-a-divide-by-zero-bug-in-ark_se.patch
+tools-thermal-fix-possible-path-truncations.patch
+sched-fix-the-check-of-nr_running-at-queue-wakelist.patch
+sched-remove-the-limitation-of-wf_on_cpu-on-wakelist.patch
+sched-core-do-not-requeue-task-on-cpu-excluded-from-.patch
+x86-entry-build-thunk_-bits-only-if-config_preemptio.patch
+f2fs-allow-compression-for-mmap-files-in-compress_mo.patch
+f2fs-do-not-allow-to-decompress-files-have-fi_compre.patch
+video-fbdev-vt8623fb-check-the-size-of-screen-before.patch
+video-fbdev-arkfb-check-the-size-of-screen-before-me.patch
+video-fbdev-s3fb-check-the-size-of-screen-before-mem.patch
--- /dev/null
+From d1959956b570029e2d9f1b470609384904fbfe3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 21:52:27 +0100
+Subject: skbuff: don't mix ubuf_info from different sources
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+[ Upstream commit 1b4b2b09d4fb451029b112f17d34792e0277aeb2 ]
+
+We should not append MSG_ZEROCOPY requests to skbuff with non
+MSG_ZEROCOPY ubuf_info, they might be not compatible.
+
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skbuff.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index c90c74de90d5..7d35cee8b00e 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -1210,6 +1210,10 @@ struct ubuf_info *msg_zerocopy_realloc(struct sock *sk, size_t size,
+ const u32 byte_limit = 1 << 19; /* limit to a few TSO */
+ u32 bytelen, next;
+
++ /* there might be non MSG_ZEROCOPY users */
++ if (uarg->callback != msg_zerocopy_callback)
++ return NULL;
++
+ /* realloc only when socket is locked (TCP, UDP cork),
+ * so uarg->len and sk_zckey access is serialized
+ */
+--
+2.35.1
+
--- /dev/null
+From cedc65ef23f1007040b8dc529e762929b4669240 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jun 2022 20:36:16 +0800
+Subject: skmsg: Fix invalid last sg check in sk_msg_recvmsg()
+
+From: Liu Jian <liujian56@huawei.com>
+
+[ Upstream commit 9974d37ea75f01b47d16072b5dad305bd8d23fcc ]
+
+In sk_psock_skb_ingress_enqueue function, if the linear area + nr_frags +
+frag_list of the SKB has NR_MSG_FRAG_IDS blocks in total, skb_to_sgvec
+will return NR_MSG_FRAG_IDS, then msg->sg.end will be set to
+NR_MSG_FRAG_IDS, and in addition, (NR_MSG_FRAG_IDS - 1) is set to the last
+SG of msg. Recv the msg in sk_msg_recvmsg, when i is (NR_MSG_FRAG_IDS - 1),
+the sk_msg_iter_var_next(i) will change i to 0 (not NR_MSG_FRAG_IDS), the
+judgment condition "msg_rx->sg.start==msg_rx->sg.end" and
+"i != msg_rx->sg.end" can not work.
+
+As a result, the processed msg cannot be deleted from ingress_msg list.
+But the length of all the sge of the msg has changed to 0. Then the next
+recvmsg syscall will process the msg repeatedly, because the length of sge
+is 0, the -EFAULT error is always returned.
+
+Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
+Signed-off-by: Liu Jian <liujian56@huawei.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20220628123616.186950-1-liujian56@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skmsg.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index ede0af308f40..f50f8d95b628 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -462,7 +462,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
+
+ if (copied == len)
+ break;
+- } while (i != msg_rx->sg.end);
++ } while (!sg_is_last(sge));
+
+ if (unlikely(peek)) {
+ msg_rx = sk_psock_next_msg(psock, msg_rx);
+@@ -472,7 +472,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
+ }
+
+ msg_rx->sg.start = i;
+- if (!sge->length && msg_rx->sg.start == msg_rx->sg.end) {
++ if (!sge->length && sg_is_last(sge)) {
+ msg_rx = sk_psock_dequeue_msg(psock);
+ kfree_sk_msg(msg_rx);
+ }
+--
+2.35.1
+
--- /dev/null
+From e0850b39710b40f9979dad2c30b699ff59aee0e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jun 2022 22:49:15 +0800
+Subject: soc: amlogic: Fix refcount leak in meson-secure-pwrc.c
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit d18529a4c12f66d83daac78045ea54063bd43257 ]
+
+In meson_secure_pwrc_probe(), there is a refcount leak in one fail
+path.
+
+Signed-off-by: Liang He <windhl@126.com>
+Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Fixes: b3dde5013e13 ("soc: amlogic: Add support for Secure power domains controller")
+Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://lore.kernel.org/r/20220616144915.3988071-1-windhl@126.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/amlogic/meson-secure-pwrc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/amlogic/meson-secure-pwrc.c b/drivers/soc/amlogic/meson-secure-pwrc.c
+index a10a417a87db..e93518763526 100644
+--- a/drivers/soc/amlogic/meson-secure-pwrc.c
++++ b/drivers/soc/amlogic/meson-secure-pwrc.c
+@@ -152,8 +152,10 @@ static int meson_secure_pwrc_probe(struct platform_device *pdev)
+ }
+
+ pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL);
+- if (!pwrc)
++ if (!pwrc) {
++ of_node_put(sm_np);
+ return -ENOMEM;
++ }
+
+ pwrc->fw = meson_sm_get(sm_np);
+ of_node_put(sm_np);
+--
+2.35.1
+
--- /dev/null
+From eb756d7feba02dd3316d8131333406fd3d9115f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Apr 2022 11:56:03 +0200
+Subject: soc: fsl: guts: machine variable might be unset
+
+From: Michael Walle <michael@walle.cc>
+
+[ Upstream commit ab3f045774f704c4e7b6a878102f4e9d4ae7bc74 ]
+
+If both the model and the compatible properties are missing, then
+machine will not be set. Initialize it with NULL.
+
+Fixes: 34c1c21e94ac ("soc: fsl: fix section mismatch build warnings")
+Signed-off-by: Michael Walle <michael@walle.cc>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/fsl/guts.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
+index 5ed2fc1c53a0..be18d46c7b0f 100644
+--- a/drivers/soc/fsl/guts.c
++++ b/drivers/soc/fsl/guts.c
+@@ -140,7 +140,7 @@ static int fsl_guts_probe(struct platform_device *pdev)
+ struct device_node *root, *np = pdev->dev.of_node;
+ struct device *dev = &pdev->dev;
+ const struct fsl_soc_die_attr *soc_die;
+- const char *machine;
++ const char *machine = NULL;
+ u32 svr;
+
+ /* Initialize guts */
+--
+2.35.1
+
--- /dev/null
+From 87bb52a131357be7d0e7e8c87e87de34fea32280 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 10:42:52 +0400
+Subject: soc: qcom: aoss: Fix refcount leak in qmp_cooling_devices_register
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit e6e0951414a314e7db3e9e24fd924b3e15515288 ]
+
+Every iteration of for_each_available_child_of_node() decrements
+the reference count of the previous node.
+When breaking early from a for_each_available_child_of_node() loop,
+we need to explicitly call of_node_put() on the child node.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 05589b30b21a ("soc: qcom: Extend AOSS QMP driver to support resources that are used to wake up the SoC.")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220606064252.42595-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/qcom_aoss.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
+index a59bb34e5eba..18c856056475 100644
+--- a/drivers/soc/qcom/qcom_aoss.c
++++ b/drivers/soc/qcom/qcom_aoss.c
+@@ -399,8 +399,10 @@ static int qmp_cooling_devices_register(struct qmp *qmp)
+ continue;
+ ret = qmp_cooling_device_add(qmp, &qmp->cooling_devs[count++],
+ child);
+- if (ret)
++ if (ret) {
++ of_node_put(child);
+ goto unroll;
++ }
+ }
+
+ if (!count)
+--
+2.35.1
+
--- /dev/null
+From 82171bc3df342f3977c61dcc2af286006dc60fa7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 23:21:58 +0200
+Subject: soc: qcom: Make QCOM_RPMPD depend on PM
+
+From: Konrad Dybcio <konrad.dybcio@somainline.org>
+
+[ Upstream commit a6232f2aa99ce470799992e99e0012945bb5308f ]
+
+QCOM_RPMPD requires PM_GENERIC_DOMAINS/_OF, which in turns requires
+CONFIG_PM. I forgot about the latter in my earlier patch (it's still
+in -next as of the time of committing, hence no Fixes: tag). Fix it.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220707212158.32684-1-konrad.dybcio@somainline.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
+index e718b8735444..4472fb22ba04 100644
+--- a/drivers/soc/qcom/Kconfig
++++ b/drivers/soc/qcom/Kconfig
+@@ -129,6 +129,7 @@ config QCOM_RPMHPD
+
+ config QCOM_RPMPD
+ tristate "Qualcomm RPM Power domain driver"
++ depends on PM
+ depends on QCOM_SMD_RPM
+ help
+ QCOM RPM Power domain driver to support power-domains with
+--
+2.35.1
+
--- /dev/null
+From 90579dddba9424bd741c48dd004ecd808015de68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 08:24:30 +0400
+Subject: soc: qcom: ocmem: Fix refcount leak in of_get_ocmem
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 92a563fcf14b3093226fb36f12e9b5cf630c5a5d ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+of_node_put() will check NULL pointer.
+
+Fixes: 88c1e9404f1d ("soc: qcom: add OCMEM driver")
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Reviewed-by: Brian Masney <masneyb@onstation.org>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220602042430.1114-1-linmq006@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/ocmem.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c
+index 97fd24c178f8..c92d26b73e6f 100644
+--- a/drivers/soc/qcom/ocmem.c
++++ b/drivers/soc/qcom/ocmem.c
+@@ -194,14 +194,17 @@ struct ocmem *of_get_ocmem(struct device *dev)
+ devnode = of_parse_phandle(dev->of_node, "sram", 0);
+ if (!devnode || !devnode->parent) {
+ dev_err(dev, "Cannot look up sram phandle\n");
++ of_node_put(devnode);
+ return ERR_PTR(-ENODEV);
+ }
+
+ pdev = of_find_device_by_node(devnode->parent);
+ if (!pdev) {
+ dev_err(dev, "Cannot find device node %s\n", devnode->name);
++ of_node_put(devnode);
+ return ERR_PTR(-EPROBE_DEFER);
+ }
++ of_node_put(devnode);
+
+ ocmem = platform_get_drvdata(pdev);
+ if (!ocmem) {
+--
+2.35.1
+
--- /dev/null
+From ce87920575ee3d9f9113a327e5f8a0b47fe147ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 14:09:57 +0530
+Subject: soc: qcom: socinfo: Fix the id of SA8540P SoC
+
+From: Parikshit Pareek <quic_ppareek@quicinc.com>
+
+[ Upstream commit 5bed21af0005cc7d8bb05d2c4a63afbcede23382 ]
+
+Change the id of SA8540P to its correct value, i.e., 461.
+Also, map the id 460 to its correct values, i.e. SA8295P.
+
+Fixes: 76ee15ae1b13 ("soc: qcom: socinfo: Add some more PMICs and SoCs")
+Signed-off-by: Parikshit Pareek <quic_ppareek@quicinc.com>
+Reviewed-by: Eric Chanudet <echanude@redhat.com>
+Tested-by: Eric Chanudet <echanude@redhat.com>
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Link: https://lore.kernel.org/r/20220711083957.12091-1-quic_ppareek@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/socinfo.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
+index 8b38d134720a..f6879983da69 100644
+--- a/drivers/soc/qcom/socinfo.c
++++ b/drivers/soc/qcom/socinfo.c
+@@ -328,7 +328,8 @@ static const struct soc_id soc_id[] = {
+ { 455, "QRB5165" },
+ { 457, "SM8450" },
+ { 459, "SM7225" },
+- { 460, "SA8540P" },
++ { 460, "SA8295P" },
++ { 461, "SA8540P" },
+ { 480, "SM8450" },
+ };
+
+--
+2.35.1
+
--- /dev/null
+From 522c80c2bf59c13ce95c378d36eeb4efdfb29ba0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 15:51:35 +0200
+Subject: soc: renesas: r8a779a0-sysc: Fix A2DP1 and A2CV[2357] PDR values
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit bccceabb92ce8eb78bbf2de08308e2cc2761a2e5 ]
+
+The PDR values for the A2DP1 and A2CV[2357] power areas on R-Car V3U are
+incorrect (copied-and-pasted from A2DP0 and A2CV[0146]).
+Fix them.
+
+Reported-by: Renesas Vietnam via Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Fixes: 1b4298f000064cc2 ("soc: renesas: r8a779a0-sysc: Add r8a779a0 support")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/87bc2e70ba4082970cf8c65871beae4be3503189.1654696188.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/renesas/r8a779a0-sysc.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/soc/renesas/r8a779a0-sysc.c b/drivers/soc/renesas/r8a779a0-sysc.c
+index fdfc857df334..04f1bc322ae7 100644
+--- a/drivers/soc/renesas/r8a779a0-sysc.c
++++ b/drivers/soc/renesas/r8a779a0-sysc.c
+@@ -57,11 +57,11 @@ static struct rcar_gen4_sysc_area r8a779a0_areas[] __initdata = {
+ { "a2cv6", R8A779A0_PD_A2CV6, R8A779A0_PD_A3IR },
+ { "a2cn2", R8A779A0_PD_A2CN2, R8A779A0_PD_A3IR },
+ { "a2imp23", R8A779A0_PD_A2IMP23, R8A779A0_PD_A3IR },
+- { "a2dp1", R8A779A0_PD_A2DP0, R8A779A0_PD_A3IR },
+- { "a2cv2", R8A779A0_PD_A2CV0, R8A779A0_PD_A3IR },
+- { "a2cv3", R8A779A0_PD_A2CV1, R8A779A0_PD_A3IR },
+- { "a2cv5", R8A779A0_PD_A2CV4, R8A779A0_PD_A3IR },
+- { "a2cv7", R8A779A0_PD_A2CV6, R8A779A0_PD_A3IR },
++ { "a2dp1", R8A779A0_PD_A2DP1, R8A779A0_PD_A3IR },
++ { "a2cv2", R8A779A0_PD_A2CV2, R8A779A0_PD_A3IR },
++ { "a2cv3", R8A779A0_PD_A2CV3, R8A779A0_PD_A3IR },
++ { "a2cv5", R8A779A0_PD_A2CV5, R8A779A0_PD_A3IR },
++ { "a2cv7", R8A779A0_PD_A2CV7, R8A779A0_PD_A3IR },
+ { "a2cn1", R8A779A0_PD_A2CN1, R8A779A0_PD_A3IR },
+ { "a1cnn0", R8A779A0_PD_A1CNN0, R8A779A0_PD_A2CN0 },
+ { "a1cnn2", R8A779A0_PD_A1CNN2, R8A779A0_PD_A2CN2 },
+--
+2.35.1
+
--- /dev/null
+From 96a18eee06111f4a4fd205f3114b6eae6fac010c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jun 2022 09:51:05 +0800
+Subject: soundwire: bus_type: fix remove and shutdown support
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit df6407782964dc7e35ad84230abb38f46314b245 ]
+
+The bus sdw_drv_remove() and sdw_drv_shutdown() helpers are used
+conditionally, if the driver provides these routines.
+
+These helpers already test if the driver provides a .remove or
+.shutdown callback, so there's no harm in invoking the
+sdw_drv_remove() and sdw_drv_shutdown() unconditionally.
+
+In addition, the current code is imbalanced with
+dev_pm_domain_attach() called from sdw_drv_probe(), but
+dev_pm_domain_detach() called from sdw_drv_remove() only if the driver
+provides a .remove callback.
+
+Fixes: 9251345dca24b ("soundwire: Add SoundWire bus type")
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Rander Wang <rander.wang@intel.com>
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://lore.kernel.org/r/20220610015105.25987-1-yung-chuan.liao@linux.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/bus_type.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
+index 893296f3fe39..b81e04dd3a9f 100644
+--- a/drivers/soundwire/bus_type.c
++++ b/drivers/soundwire/bus_type.c
+@@ -193,12 +193,8 @@ int __sdw_register_driver(struct sdw_driver *drv, struct module *owner)
+
+ drv->driver.owner = owner;
+ drv->driver.probe = sdw_drv_probe;
+-
+- if (drv->remove)
+- drv->driver.remove = sdw_drv_remove;
+-
+- if (drv->shutdown)
+- drv->driver.shutdown = sdw_drv_shutdown;
++ drv->driver.remove = sdw_drv_remove;
++ drv->driver.shutdown = sdw_drv_shutdown;
+
+ return driver_register(&drv->driver);
+ }
+--
+2.35.1
+
--- /dev/null
+From 5adb051f223a5fae4c67679ced32f03c652f4b1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jun 2022 17:56:38 -0500
+Subject: soundwire: revisit driver bind/unbind and callbacks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit bd29c00edd0a5dac8b6e7332bb470cd50f92e893 ]
+
+In the SoundWire probe, we store a pointer from the driver ops into
+the 'slave' structure. This can lead to kernel oopses when unbinding
+codec drivers, e.g. with the following sequence to remove machine
+driver and codec driver.
+
+/sbin/modprobe -r snd_soc_sof_sdw
+/sbin/modprobe -r snd_soc_rt711
+
+The full details can be found in the BugLink below, for reference the
+two following examples show different cases of driver ops/callbacks
+being invoked after the driver .remove().
+
+kernel: BUG: kernel NULL pointer dereference, address: 0000000000000150
+kernel: Workqueue: events cdns_update_slave_status_work [soundwire_cadence]
+kernel: RIP: 0010:mutex_lock+0x19/0x30
+kernel: Call Trace:
+kernel: ? sdw_handle_slave_status+0x426/0xe00 [soundwire_bus 94ff184bf398570c3f8ff7efe9e32529f532e4ae]
+kernel: ? newidle_balance+0x26a/0x400
+kernel: ? cdns_update_slave_status_work+0x1e9/0x200 [soundwire_cadence 1bcf98eebe5ba9833cd433323769ac923c9c6f82]
+
+kernel: BUG: unable to handle page fault for address: ffffffffc07654c8
+kernel: Workqueue: pm pm_runtime_work
+kernel: RIP: 0010:sdw_bus_prep_clk_stop+0x6f/0x160 [soundwire_bus]
+kernel: Call Trace:
+kernel: <TASK>
+kernel: sdw_cdns_clock_stop+0xb5/0x1b0 [soundwire_cadence 1bcf98eebe5ba9833cd433323769ac923c9c6f82]
+kernel: intel_suspend_runtime+0x5f/0x120 [soundwire_intel aca858f7c87048d3152a4a41bb68abb9b663a1dd]
+kernel: ? dpm_sysfs_remove+0x60/0x60
+
+This was not detected earlier in Intel tests since the tests first
+remove the parent PCI device and shut down the bus. The sequence
+above is a corner case which keeps the bus operational but without a
+driver bound.
+
+While trying to solve this kernel oopses, it became clear that the
+existing SoundWire bus does not deal well with the unbind case.
+
+Commit 528be501b7d4a ("soundwire: sdw_slave: add probe_complete structure and new fields")
+added a 'probed' status variable and a 'probe_complete'
+struct completion. This status is however not reset on remove and
+likewise the 'probe complete' is not re-initialized, so the
+bind/unbind/bind test cases would fail. The timeout used before the
+'update_status' callback was also a bad idea in hindsight, there
+should really be no timing assumption as to if and when a driver is
+bound to a device.
+
+An initial draft was based on device_lock() and device_unlock() was
+tested. This proved too complicated, with deadlocks created during the
+suspend-resume sequences, which also use the same device_lock/unlock()
+as the bind/unbind sequences. On a CometLake device, a bad DSDT/BIOS
+caused spurious resumes and the use of device_lock() caused hangs
+during suspend. After multiple weeks or testing and painful
+reverse-engineering of deadlocks on different devices, we looked for
+alternatives that did not interfere with the device core.
+
+A bus notifier was used successfully to keep track of DRIVER_BOUND and
+DRIVER_UNBIND events. This solved the bind-unbind-bind case in tests,
+but it can still be defeated with a theoretical corner case where the
+memory is freed by a .remove while the callback is in use. The
+notifier only helps make sure the driver callbacks are valid, but not
+that the memory allocated in probe remains valid while the callbacks
+are invoked.
+
+This patch suggests the introduction of a new 'sdw_dev_lock' mutex
+protecting probe/remove and all driver callbacks. Since this mutex is
+'local' to SoundWire only, it does not interfere with existing locks
+and does not create deadlocks. In addition, this patch removes the
+'probe_complete' completion, instead we directly invoke the
+'update_status' from the probe routine. That removes any sort of
+timing dependency and a much better support for the device/driver
+model, the driver could be bound before the bus started, or eons after
+the bus started and the hardware would be properly initialized in all
+cases.
+
+BugLink: https://github.com/thesofproject/linux/issues/3531
+Fixes: 56d4fe31af77 ("soundwire: Add MIPI DisCo property helpers")
+Fixes: 528be501b7d4a ("soundwire: sdw_slave: add probe_complete structure and new fields")
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Rander Wang <rander.wang@intel.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Link: https://lore.kernel.org/r/20220621225641.221170-2-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soundwire/bus.c | 75 ++++++++++++++++++++---------------
+ drivers/soundwire/bus_type.c | 30 +++++++++++---
+ drivers/soundwire/slave.c | 3 +-
+ drivers/soundwire/stream.c | 53 ++++++++++++++++---------
+ include/linux/soundwire/sdw.h | 6 +--
+ 5 files changed, 106 insertions(+), 61 deletions(-)
+
+diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c
+index 354d3f89366f..f1cf78c6d477 100644
+--- a/drivers/soundwire/bus.c
++++ b/drivers/soundwire/bus.c
+@@ -7,6 +7,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/soundwire/sdw_registers.h>
+ #include <linux/soundwire/sdw.h>
++#include <linux/soundwire/sdw_type.h>
+ #include "bus.h"
+ #include "sysfs_local.h"
+
+@@ -846,15 +847,21 @@ static int sdw_slave_clk_stop_callback(struct sdw_slave *slave,
+ enum sdw_clk_stop_mode mode,
+ enum sdw_clk_stop_type type)
+ {
+- int ret;
++ int ret = 0;
+
+- if (slave->ops && slave->ops->clk_stop) {
+- ret = slave->ops->clk_stop(slave, mode, type);
+- if (ret < 0)
+- return ret;
++ mutex_lock(&slave->sdw_dev_lock);
++
++ if (slave->probed) {
++ struct device *dev = &slave->dev;
++ struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
++
++ if (drv->ops && drv->ops->clk_stop)
++ ret = drv->ops->clk_stop(slave, mode, type);
+ }
+
+- return 0;
++ mutex_unlock(&slave->sdw_dev_lock);
++
++ return ret;
+ }
+
+ static int sdw_slave_clk_stop_prepare(struct sdw_slave *slave,
+@@ -1616,14 +1623,24 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
+ }
+
+ /* Update the Slave driver */
+- if (slave_notify && slave->ops &&
+- slave->ops->interrupt_callback) {
+- slave_intr.sdca_cascade = sdca_cascade;
+- slave_intr.control_port = clear;
+- memcpy(slave_intr.port, &port_status,
+- sizeof(slave_intr.port));
+-
+- slave->ops->interrupt_callback(slave, &slave_intr);
++ if (slave_notify) {
++ mutex_lock(&slave->sdw_dev_lock);
++
++ if (slave->probed) {
++ struct device *dev = &slave->dev;
++ struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
++
++ if (drv->ops && drv->ops->interrupt_callback) {
++ slave_intr.sdca_cascade = sdca_cascade;
++ slave_intr.control_port = clear;
++ memcpy(slave_intr.port, &port_status,
++ sizeof(slave_intr.port));
++
++ drv->ops->interrupt_callback(slave, &slave_intr);
++ }
++ }
++
++ mutex_unlock(&slave->sdw_dev_lock);
+ }
+
+ /* Ack interrupt */
+@@ -1697,29 +1714,21 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
+ static int sdw_update_slave_status(struct sdw_slave *slave,
+ enum sdw_slave_status status)
+ {
+- unsigned long time;
++ int ret = 0;
+
+- if (!slave->probed) {
+- /*
+- * the slave status update is typically handled in an
+- * interrupt thread, which can race with the driver
+- * probe, e.g. when a module needs to be loaded.
+- *
+- * make sure the probe is complete before updating
+- * status.
+- */
+- time = wait_for_completion_timeout(&slave->probe_complete,
+- msecs_to_jiffies(DEFAULT_PROBE_TIMEOUT));
+- if (!time) {
+- dev_err(&slave->dev, "Probe not complete, timed out\n");
+- return -ETIMEDOUT;
+- }
++ mutex_lock(&slave->sdw_dev_lock);
++
++ if (slave->probed) {
++ struct device *dev = &slave->dev;
++ struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
++
++ if (drv->ops && drv->ops->update_status)
++ ret = drv->ops->update_status(slave, status);
+ }
+
+- if (!slave->ops || !slave->ops->update_status)
+- return 0;
++ mutex_unlock(&slave->sdw_dev_lock);
+
+- return slave->ops->update_status(slave, status);
++ return ret;
+ }
+
+ /**
+diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c
+index b81e04dd3a9f..04b3529f8929 100644
+--- a/drivers/soundwire/bus_type.c
++++ b/drivers/soundwire/bus_type.c
+@@ -98,8 +98,6 @@ static int sdw_drv_probe(struct device *dev)
+ if (!id)
+ return -ENODEV;
+
+- slave->ops = drv->ops;
+-
+ /*
+ * attach to power domain but don't turn on (last arg)
+ */
+@@ -107,19 +105,23 @@ static int sdw_drv_probe(struct device *dev)
+ if (ret)
+ return ret;
+
++ mutex_lock(&slave->sdw_dev_lock);
++
+ ret = drv->probe(slave, id);
+ if (ret) {
+ name = drv->name;
+ if (!name)
+ name = drv->driver.name;
++ mutex_unlock(&slave->sdw_dev_lock);
++
+ dev_err(dev, "Probe of %s failed: %d\n", name, ret);
+ dev_pm_domain_detach(dev, false);
+ return ret;
+ }
+
+ /* device is probed so let's read the properties now */
+- if (slave->ops && slave->ops->read_prop)
+- slave->ops->read_prop(slave);
++ if (drv->ops && drv->ops->read_prop)
++ drv->ops->read_prop(slave);
+
+ /* init the sysfs as we have properties now */
+ ret = sdw_slave_sysfs_init(slave);
+@@ -139,7 +141,19 @@ static int sdw_drv_probe(struct device *dev)
+ slave->prop.clk_stop_timeout);
+
+ slave->probed = true;
+- complete(&slave->probe_complete);
++
++ /*
++ * if the probe happened after the bus was started, notify the codec driver
++ * of the current hardware status to e.g. start the initialization.
++ * Errors are only logged as warnings to avoid failing the probe.
++ */
++ if (drv->ops && drv->ops->update_status) {
++ ret = drv->ops->update_status(slave, slave->status);
++ if (ret < 0)
++ dev_warn(dev, "%s: update_status failed with status %d\n", __func__, ret);
++ }
++
++ mutex_unlock(&slave->sdw_dev_lock);
+
+ dev_dbg(dev, "probe complete\n");
+
+@@ -152,9 +166,15 @@ static int sdw_drv_remove(struct device *dev)
+ struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
+ int ret = 0;
+
++ mutex_lock(&slave->sdw_dev_lock);
++
++ slave->probed = false;
++
+ if (drv->remove)
+ ret = drv->remove(slave);
+
++ mutex_unlock(&slave->sdw_dev_lock);
++
+ dev_pm_domain_detach(dev, false);
+
+ return ret;
+diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c
+index 669d7573320b..25e76b5d4a1a 100644
+--- a/drivers/soundwire/slave.c
++++ b/drivers/soundwire/slave.c
+@@ -12,6 +12,7 @@ static void sdw_slave_release(struct device *dev)
+ {
+ struct sdw_slave *slave = dev_to_sdw_dev(dev);
+
++ mutex_destroy(&slave->sdw_dev_lock);
+ kfree(slave);
+ }
+
+@@ -58,9 +59,9 @@ int sdw_slave_add(struct sdw_bus *bus,
+ init_completion(&slave->enumeration_complete);
+ init_completion(&slave->initialization_complete);
+ slave->dev_num = 0;
+- init_completion(&slave->probe_complete);
+ slave->probed = false;
+ slave->first_interrupt_done = false;
++ mutex_init(&slave->sdw_dev_lock);
+
+ for (i = 0; i < SDW_MAX_PORTS; i++)
+ init_completion(&slave->port_ready[i]);
+diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
+index f273459b2023..6963e5f7ea6d 100644
+--- a/drivers/soundwire/stream.c
++++ b/drivers/soundwire/stream.c
+@@ -13,6 +13,7 @@
+ #include <linux/slab.h>
+ #include <linux/soundwire/sdw_registers.h>
+ #include <linux/soundwire/sdw.h>
++#include <linux/soundwire/sdw_type.h>
+ #include <sound/soc.h>
+ #include "bus.h"
+
+@@ -401,20 +402,26 @@ static int sdw_do_port_prep(struct sdw_slave_runtime *s_rt,
+ struct sdw_prepare_ch prep_ch,
+ enum sdw_port_prep_ops cmd)
+ {
+- const struct sdw_slave_ops *ops = s_rt->slave->ops;
+- int ret;
++ int ret = 0;
++ struct sdw_slave *slave = s_rt->slave;
+
+- if (ops->port_prep) {
+- ret = ops->port_prep(s_rt->slave, &prep_ch, cmd);
+- if (ret < 0) {
+- dev_err(&s_rt->slave->dev,
+- "Slave Port Prep cmd %d failed: %d\n",
+- cmd, ret);
+- return ret;
++ mutex_lock(&slave->sdw_dev_lock);
++
++ if (slave->probed) {
++ struct device *dev = &slave->dev;
++ struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
++
++ if (drv->ops && drv->ops->port_prep) {
++ ret = drv->ops->port_prep(slave, &prep_ch, cmd);
++ if (ret < 0)
++ dev_err(dev, "Slave Port Prep cmd %d failed: %d\n",
++ cmd, ret);
+ }
+ }
+
+- return 0;
++ mutex_unlock(&slave->sdw_dev_lock);
++
++ return ret;
+ }
+
+ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
+@@ -578,7 +585,7 @@ static int sdw_notify_config(struct sdw_master_runtime *m_rt)
+ struct sdw_slave_runtime *s_rt;
+ struct sdw_bus *bus = m_rt->bus;
+ struct sdw_slave *slave;
+- int ret = 0;
++ int ret;
+
+ if (bus->ops->set_bus_conf) {
+ ret = bus->ops->set_bus_conf(bus, &bus->params);
+@@ -589,17 +596,27 @@ static int sdw_notify_config(struct sdw_master_runtime *m_rt)
+ list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
+ slave = s_rt->slave;
+
+- if (slave->ops->bus_config) {
+- ret = slave->ops->bus_config(slave, &bus->params);
+- if (ret < 0) {
+- dev_err(bus->dev, "Notify Slave: %d failed\n",
+- slave->dev_num);
+- return ret;
++ mutex_lock(&slave->sdw_dev_lock);
++
++ if (slave->probed) {
++ struct device *dev = &slave->dev;
++ struct sdw_driver *drv = drv_to_sdw_driver(dev->driver);
++
++ if (drv->ops && drv->ops->bus_config) {
++ ret = drv->ops->bus_config(slave, &bus->params);
++ if (ret < 0) {
++ dev_err(dev, "Notify Slave: %d failed\n",
++ slave->dev_num);
++ mutex_unlock(&slave->sdw_dev_lock);
++ return ret;
++ }
+ }
+ }
++
++ mutex_unlock(&slave->sdw_dev_lock);
+ }
+
+- return ret;
++ return 0;
+ }
+
+ /**
+diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h
+index 76ce3f3ac0f2..bf6f0decb3f6 100644
+--- a/include/linux/soundwire/sdw.h
++++ b/include/linux/soundwire/sdw.h
+@@ -646,9 +646,6 @@ struct sdw_slave_ops {
+ * @dev_num: Current Device Number, values can be 0 or dev_num_sticky
+ * @dev_num_sticky: one-time static Device Number assigned by Bus
+ * @probed: boolean tracking driver state
+- * @probe_complete: completion utility to control potential races
+- * on startup between driver probe/initialization and SoundWire
+- * Slave state changes/implementation-defined interrupts
+ * @enumeration_complete: completion utility to control potential races
+ * on startup between device enumeration and read/write access to the
+ * Slave device
+@@ -663,6 +660,7 @@ struct sdw_slave_ops {
+ * for a Slave happens for the first time after enumeration
+ * @is_mockup_device: status flag used to squelch errors in the command/control
+ * protocol for SoundWire mockup devices
++ * @sdw_dev_lock: mutex used to protect callbacks/remove races
+ */
+ struct sdw_slave {
+ struct sdw_slave_id id;
+@@ -680,12 +678,12 @@ struct sdw_slave {
+ u16 dev_num;
+ u16 dev_num_sticky;
+ bool probed;
+- struct completion probe_complete;
+ struct completion enumeration_complete;
+ struct completion initialization_complete;
+ u32 unattach_request;
+ bool first_interrupt_done;
+ bool is_mockup_device;
++ struct mutex sdw_dev_lock; /* protect callbacks/remove races */
+ };
+
+ #define dev_to_sdw_dev(_dev) container_of(_dev, struct sdw_slave, dev)
+--
+2.35.1
+
--- /dev/null
+From cb01b8aeaccd60777d82bf75a54d7e760ff6a007 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 12:22:20 +0800
+Subject: spi: dw: Fix IP-core versions macro
+
+From: Nandhini Srikandan <nandhini.srikandan@intel.com>
+
+[ Upstream commit 5d76b7509cb223e94ff73a672273e58f1957ac68 ]
+
+Add the missing underscore in IP version macro to avoid compilation issue.
+The macro is used for IP version comparison in the current patchset.
+
+Fixes: 2cc8d9227bbb ("spi: dw: Introduce Synopsys IP-core versions interface")
+Signed-off-by: Nandhini Srikandan <nandhini.srikandan@intel.com>
+Acked-by: Serge Semin <fancer.lancer@gmail.com>
+Link: https://lore.kernel.org/r/20220713042223.1458-2-nandhini.srikandan@intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-dw.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h
+index d5ee5130601e..79d853f6d192 100644
+--- a/drivers/spi/spi-dw.h
++++ b/drivers/spi/spi-dw.h
+@@ -23,7 +23,7 @@
+ ((_dws)->ip == DW_ ## _ip ## _ID)
+
+ #define __dw_spi_ver_cmp(_dws, _ip, _ver, _op) \
+- (dw_spi_ip_is(_dws, _ip) && (_dws)->ver _op DW_ ## _ip ## _ver)
++ (dw_spi_ip_is(_dws, _ip) && (_dws)->ver _op DW_ ## _ip ## _ ## _ver)
+
+ #define dw_spi_ver_is(_dws, _ip, _ver) __dw_spi_ver_cmp(_dws, _ip, _ver, ==)
+
+--
+2.35.1
+
--- /dev/null
+From a31b91cb38510b194d067c0b386a0220201cba68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 21:55:04 +0800
+Subject: spi: Fix simplification of devm_spi_register_controller
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 43cc5a0afe4184a7fafe1eba32b5a11bb69c9ce0 ]
+
+This reverts commit 59ebbe40fb51 ("spi: simplify
+devm_spi_register_controller").
+
+If devm_add_action() fails in devm_add_action_or_reset(),
+devm_spi_unregister() will be called, it decreases the
+refcount of 'ctlr->dev' to 0, then it will cause uaf in
+the drivers that calling spi_put_controller() in error path.
+
+Fixes: 59ebbe40fb51 ("spi: simplify devm_spi_register_controller")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20220712135504.1055688-1-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi.c | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index e1065768c537..6a8850e62078 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -3068,9 +3068,9 @@ int spi_register_controller(struct spi_controller *ctlr)
+ }
+ EXPORT_SYMBOL_GPL(spi_register_controller);
+
+-static void devm_spi_unregister(void *ctlr)
++static void devm_spi_unregister(struct device *dev, void *res)
+ {
+- spi_unregister_controller(ctlr);
++ spi_unregister_controller(*(struct spi_controller **)res);
+ }
+
+ /**
+@@ -3089,13 +3089,22 @@ static void devm_spi_unregister(void *ctlr)
+ int devm_spi_register_controller(struct device *dev,
+ struct spi_controller *ctlr)
+ {
++ struct spi_controller **ptr;
+ int ret;
+
++ ptr = devres_alloc(devm_spi_unregister, sizeof(*ptr), GFP_KERNEL);
++ if (!ptr)
++ return -ENOMEM;
++
+ ret = spi_register_controller(ctlr);
+- if (ret)
+- return ret;
++ if (!ret) {
++ *ptr = ctlr;
++ devres_add(dev, ptr);
++ } else {
++ devres_free(ptr);
++ }
+
+- return devm_add_action_or_reset(dev, devm_spi_unregister, ctlr);
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(devm_spi_register_controller);
+
+--
+2.35.1
+
--- /dev/null
+From 471dd7223fa9823920bc31c0279899d14dd40a6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Jul 2022 00:29:56 +0300
+Subject: spi: Return deferred probe error when controller isn't yet available
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 9c22ec4ac27bcc5a54dd406da168f403327a5b55 ]
+
+If the controller is not available, it might be in the future and
+we would like to re-probe the peripheral again. For that purpose
+return deferred probe.
+
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=215993
+Fixes: 87e59b36e5e2 ("spi: Support selection of the index of the ACPI Spi Resource before alloc")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20220709212956.25530-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index 2e6d6bbeb784..e1065768c537 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -2416,7 +2416,7 @@ static int acpi_spi_add_resource(struct acpi_resource *ares, void *data)
+
+ ctlr = acpi_spi_find_controller_by_adev(adev);
+ if (!ctlr)
+- return -ENODEV;
++ return -EPROBE_DEFER;
+
+ lookup->ctlr = ctlr;
+ }
+--
+2.35.1
+
--- /dev/null
+From 45a46f96e705a56ce72911163d81d94eed043d8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jun 2022 11:45:41 +0200
+Subject: spi: s3c64xx: constify fsd_spi_port_config
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit a813c47d22b0a0c51567292bc198a39bdcdc3799 ]
+
+All struct s3c64xx_spi_port_config should be const.
+
+Fixes: 4ebb15a15799 ("spi: s3c64xx: Add spi port configuration for Tesla FSD SoC")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20220627094541.95166-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-s3c64xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
+index c26440e9058d..8fa21afc6a35 100644
+--- a/drivers/spi/spi-s3c64xx.c
++++ b/drivers/spi/spi-s3c64xx.c
+@@ -1413,7 +1413,7 @@ static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
+ .quirks = S3C64XX_SPI_QUIRK_CS_AUTO,
+ };
+
+-static struct s3c64xx_spi_port_config fsd_spi_port_config = {
++static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
+ .fifo_lvl_mask = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
+ .rx_lvl_offset = 15,
+ .tx_st_done = 25,
+--
+2.35.1
+
--- /dev/null
+From a9f26e1431d65cb1d2813f74445671ae974c73f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 29 May 2022 08:31:53 +0200
+Subject: spi: spi-altera-dfl: Fix an error handling path
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 8e3ca32f46994e74b7f43c57731150b2aedb2630 ]
+
+The spi_alloc_master() call is not undone in all error handling paths.
+Moreover, there is no .remove function to release the allocated memory.
+
+In order to fix both this issues, switch to devm_spi_alloc_master().
+
+This allows further simplification of the probe.
+
+Fixes: ba2fc167e944 ("spi: altera: Add DFL bus driver for Altera API Controller")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/0607bb59f4073f86abe5c585d35245aef0b045c6.1653805901.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-altera-dfl.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/spi/spi-altera-dfl.c b/drivers/spi/spi-altera-dfl.c
+index ca40923258af..596e181ae136 100644
+--- a/drivers/spi/spi-altera-dfl.c
++++ b/drivers/spi/spi-altera-dfl.c
+@@ -128,9 +128,9 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev)
+ struct spi_master *master;
+ struct altera_spi *hw;
+ void __iomem *base;
+- int err = -ENODEV;
++ int err;
+
+- master = spi_alloc_master(dev, sizeof(struct altera_spi));
++ master = devm_spi_alloc_master(dev, sizeof(struct altera_spi));
+ if (!master)
+ return -ENOMEM;
+
+@@ -159,10 +159,9 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev)
+ altera_spi_init_master(master);
+
+ err = devm_spi_register_master(dev, master);
+- if (err) {
+- dev_err(dev, "%s failed to register spi master %d\n", __func__, err);
+- goto exit;
+- }
++ if (err)
++ return dev_err_probe(dev, err, "%s failed to register spi master\n",
++ __func__);
+
+ if (dfl_dev->revision == FME_FEATURE_REV_MAX10_SPI_N5010)
+ strscpy(board_info.modalias, "m10-n5010", SPI_NAME_SIZE);
+@@ -179,9 +178,6 @@ static int dfl_spi_altera_probe(struct dfl_device *dfl_dev)
+ }
+
+ return 0;
+-exit:
+- spi_master_put(master);
+- return err;
+ }
+
+ static const struct dfl_device_id dfl_spi_altera_ids[] = {
+--
+2.35.1
+
--- /dev/null
+From ea71fa7503cbc42f20c3abede8c44bda23e40f54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Jul 2022 15:34:49 +0100
+Subject: spi: spi-rspi: Fix PIO fallback on RZ platforms
+
+From: Biju Das <biju.das.jz@bp.renesas.com>
+
+[ Upstream commit b620aa3a7be346f04ae7789b165937615c6ee8d3 ]
+
+RSPI IP on RZ/{A, G2L} SoC's has the same signal for both interrupt
+and DMA transfer request. Setting DMARS register for DMA transfer
+makes the signal to work as a DMA transfer request signal and
+subsequent interrupt requests to the interrupt controller
+are masked.
+
+PIO fallback does not work as interrupt signal is disabled.
+
+This patch fixes this issue by re-enabling the interrupts by
+calling dmaengine_synchronize().
+
+Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20220721143449.879257-1-biju.das.jz@bp.renesas.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-rspi.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
+index 7a014eeec2d0..411b1307b7fd 100644
+--- a/drivers/spi/spi-rspi.c
++++ b/drivers/spi/spi-rspi.c
+@@ -613,6 +613,10 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
+ rspi->dma_callbacked, HZ);
+ if (ret > 0 && rspi->dma_callbacked) {
+ ret = 0;
++ if (tx)
++ dmaengine_synchronize(rspi->ctlr->dma_tx);
++ if (rx)
++ dmaengine_synchronize(rspi->ctlr->dma_rx);
+ } else {
+ if (!ret) {
+ dev_err(&rspi->ctlr->dev, "DMA timeout\n");
+--
+2.35.1
+
--- /dev/null
+From 8280f01e9027757efb57e197592c29206cd1d654 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jun 2022 08:56:14 +0800
+Subject: spi: synquacer: Add missing clk_disable_unprepare()
+
+From: Guo Mengqi <guomengqi3@huawei.com>
+
+[ Upstream commit 917e43de2a56d9b82576f1cc94748261f1988458 ]
+
+Add missing clk_disable_unprepare() in synquacer_spi_resume().
+
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Guo Mengqi <guomengqi3@huawei.com>
+Link: https://lore.kernel.org/r/20220624005614.49434-1-guomengqi3@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-synquacer.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/spi/spi-synquacer.c b/drivers/spi/spi-synquacer.c
+index ea706d9629cb..47cbe73137c2 100644
+--- a/drivers/spi/spi-synquacer.c
++++ b/drivers/spi/spi-synquacer.c
+@@ -783,6 +783,7 @@ static int __maybe_unused synquacer_spi_resume(struct device *dev)
+
+ ret = synquacer_spi_enable(master);
+ if (ret) {
++ clk_disable_unprepare(sspi->clk);
+ dev_err(dev, "failed to enable spi (%d)\n", ret);
+ return ret;
+ }
+--
+2.35.1
+
--- /dev/null
+From a85e1703697a00a5db05a4ed3e4d1d6d2dd8055a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 17:40:23 +0800
+Subject: spi: tegra20-slink: fix UAF in tegra_slink_remove()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 7e9984d183bb1e99e766c5c2b950ff21f7f7b6c0 ]
+
+After calling spi_unregister_master(), the refcount of master will
+be decrease to 0, and it will be freed in spi_controller_release(),
+the device data also will be freed, so it will lead a UAF when using
+'tspi'. To fix this, get the master before unregister and put it when
+finish using it.
+
+Fixes: 26c863418221 ("spi: tegra20-slink: Don't use resource-managed spi_register helper")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20220713094024.1508869-1-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-tegra20-slink.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c
+index 80c3787deea9..c91c226be69e 100644
+--- a/drivers/spi/spi-tegra20-slink.c
++++ b/drivers/spi/spi-tegra20-slink.c
+@@ -1137,7 +1137,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
+
+ static int tegra_slink_remove(struct platform_device *pdev)
+ {
+- struct spi_master *master = platform_get_drvdata(pdev);
++ struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
+ struct tegra_slink_data *tspi = spi_master_get_devdata(master);
+
+ spi_unregister_master(master);
+@@ -1152,6 +1152,7 @@ static int tegra_slink_remove(struct platform_device *pdev)
+ if (tspi->rx_dma_chan)
+ tegra_slink_deinit_dma_param(tspi, true);
+
++ spi_master_put(master);
+ return 0;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From ff95ed6f940a3fe34917c53b6cb59fac533c4e59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jun 2022 14:04:23 +0800
+Subject: stack: Declare {randomize_,}kstack_offset to fix Sparse warnings
+
+From: GONG, Ruiqi <gongruiqi1@huawei.com>
+
+[ Upstream commit 375561bd6195a31bf4c109732bd538cb97a941f4 ]
+
+Fix the following Sparse warnings that got noticed when the PPC-dev
+patchwork was checking another patch (see the link below):
+
+init/main.c:862:1: warning: symbol 'randomize_kstack_offset' was not declared. Should it be static?
+init/main.c:864:1: warning: symbol 'kstack_offset' was not declared. Should it be static?
+
+Which in fact are triggered on all architectures that have
+HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET support (for instances x86, arm64
+etc).
+
+Link: https://lore.kernel.org/lkml/e7b0d68b-914d-7283-827c-101988923929@huawei.com/T/#m49b2d4490121445ce4bf7653500aba59eefcb67f
+Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
+Cc: Xiu Jianfeng <xiujianfeng@huawei.com>
+Signed-off-by: GONG, Ruiqi <gongruiqi1@huawei.com>
+Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Fixes: 39218ff4c625 ("stack: Optionally randomize kernel stack offset each syscall")
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20220629060423.2515693-1-gongruiqi1@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ init/main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/init/main.c b/init/main.c
+index 80bd217dd35e..1e866b31bf19 100644
+--- a/init/main.c
++++ b/init/main.c
+@@ -99,6 +99,7 @@
+ #include <linux/kcsan.h>
+ #include <linux/init_syscalls.h>
+ #include <linux/stackdepot.h>
++#include <linux/randomize_kstack.h>
+ #include <net/net_namespace.h>
+
+ #include <asm/io.h>
+--
+2.35.1
+
--- /dev/null
+From 331f27fab257f858e88ac2a127cd85cc95374a6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Jul 2022 09:35:50 +0200
+Subject: staging: fbtft: core: set smem_len before fb_deferred_io_init call
+
+From: Peter Suti <peter.suti@streamunlimited.com>
+
+[ Upstream commit 81e878887ff82a7dd42f22951391069a5d520627 ]
+
+The fbtft_framebuffer_alloc() calls fb_deferred_io_init() before
+initializing info->fix.smem_len. It is set to zero by the
+framebuffer_alloc() function. It will trigger a WARN_ON() at the
+start of fb_deferred_io_init() and the function will not do anything.
+
+Fixes: 856082f021a2 ("fbdev: defio: fix the pagelist corruption")
+Signed-off-by: Peter Suti <peter.suti@streamunlimited.com>
+Link: https://lore.kernel.org/r/20220727073550.1491126-1-peter.suti@streamunlimited.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/fbtft/fbtft-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
+index 9c4d797e7ae4..4137c1a51e1b 100644
+--- a/drivers/staging/fbtft/fbtft-core.c
++++ b/drivers/staging/fbtft/fbtft-core.c
+@@ -656,7 +656,6 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
+ fbdefio->delay = HZ / fps;
+ fbdefio->sort_pagelist = true;
+ fbdefio->deferred_io = fbtft_deferred_io;
+- fb_deferred_io_init(info);
+
+ snprintf(info->fix.id, sizeof(info->fix.id), "%s", dev->driver->name);
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+@@ -667,6 +666,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
+ info->fix.line_length = width * bpp / 8;
+ info->fix.accel = FB_ACCEL_NONE;
+ info->fix.smem_len = vmem_size;
++ fb_deferred_io_init(info);
+
+ info->var.rotate = pdata->rotate;
+ info->var.xres = width;
+--
+2.35.1
+
--- /dev/null
+From b4e389125817546bf3d29cccd83fae4c4c8ee821 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Jul 2022 18:30:02 +0800
+Subject: staging: rtl8192u: Fix sleep in atomic context bug in
+ dm_fsync_timer_callback
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ Upstream commit 6a0c054930d554ad8f8044ef1fc856d9da391c81 ]
+
+There are sleep in atomic context bugs when dm_fsync_timer_callback is
+executing. The root cause is that the memory allocation functions with
+GFP_KERNEL or GFP_NOIO parameters are called in dm_fsync_timer_callback
+which is a timer handler. The call paths that could trigger bugs are
+shown below:
+
+ (interrupt context)
+dm_fsync_timer_callback
+ write_nic_byte
+ kzalloc(sizeof(data), GFP_KERNEL); //may sleep
+ usb_control_msg
+ kmalloc(.., GFP_NOIO); //may sleep
+ write_nic_dword
+ kzalloc(sizeof(data), GFP_KERNEL); //may sleep
+ usb_control_msg
+ kmalloc(.., GFP_NOIO); //may sleep
+
+This patch uses delayed work to replace timer and moves the operations
+that may sleep into the delayed work in order to mitigate bugs.
+
+Fixes: 8fc8598e61f6 ("Staging: Added Realtek rtl8192u driver to staging")
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+Link: https://lore.kernel.org/r/20220710103002.63283-1-duoming@zju.edu.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/rtl8192u/r8192U.h | 2 +-
+ drivers/staging/rtl8192u/r8192U_dm.c | 38 +++++++++++++---------------
+ drivers/staging/rtl8192u/r8192U_dm.h | 2 +-
+ 3 files changed, 20 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h
+index 14ca00a2789b..1942cb849374 100644
+--- a/drivers/staging/rtl8192u/r8192U.h
++++ b/drivers/staging/rtl8192u/r8192U.h
+@@ -1013,7 +1013,7 @@ typedef struct r8192_priv {
+ bool bis_any_nonbepkts;
+ bool bcurrent_turbo_EDCA;
+ bool bis_cur_rdlstate;
+- struct timer_list fsync_timer;
++ struct delayed_work fsync_work;
+ bool bfsync_processing; /* 500ms Fsync timer is active or not */
+ u32 rate_record;
+ u32 rateCountDiffRecord;
+diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c
+index 725bf5ca9e34..0fcfcaa6500b 100644
+--- a/drivers/staging/rtl8192u/r8192U_dm.c
++++ b/drivers/staging/rtl8192u/r8192U_dm.c
+@@ -2578,19 +2578,20 @@ static void dm_init_fsync(struct net_device *dev)
+ priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
+ priv->ieee80211->fsync_state = Default_Fsync;
+ priv->framesyncMonitor = 1; /* current default 0xc38 monitor on */
+- timer_setup(&priv->fsync_timer, dm_fsync_timer_callback, 0);
++ INIT_DELAYED_WORK(&priv->fsync_work, dm_fsync_work_callback);
+ }
+
+ static void dm_deInit_fsync(struct net_device *dev)
+ {
+ struct r8192_priv *priv = ieee80211_priv(dev);
+
+- del_timer_sync(&priv->fsync_timer);
++ cancel_delayed_work_sync(&priv->fsync_work);
+ }
+
+-void dm_fsync_timer_callback(struct timer_list *t)
++void dm_fsync_work_callback(struct work_struct *work)
+ {
+- struct r8192_priv *priv = from_timer(priv, t, fsync_timer);
++ struct r8192_priv *priv =
++ container_of(work, struct r8192_priv, fsync_work.work);
+ struct net_device *dev = priv->ieee80211->dev;
+ u32 rate_index, rate_count = 0, rate_count_diff = 0;
+ bool bSwitchFromCountDiff = false;
+@@ -2657,17 +2658,16 @@ void dm_fsync_timer_callback(struct timer_list *t)
+ }
+ }
+ if (bDoubleTimeInterval) {
+- if (timer_pending(&priv->fsync_timer))
+- del_timer_sync(&priv->fsync_timer);
+- priv->fsync_timer.expires = jiffies +
+- msecs_to_jiffies(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
+- add_timer(&priv->fsync_timer);
++ cancel_delayed_work_sync(&priv->fsync_work);
++ schedule_delayed_work(&priv->fsync_work,
++ msecs_to_jiffies(priv
++ ->ieee80211->fsync_time_interval *
++ priv->ieee80211->fsync_multiple_timeinterval));
+ } else {
+- if (timer_pending(&priv->fsync_timer))
+- del_timer_sync(&priv->fsync_timer);
+- priv->fsync_timer.expires = jiffies +
+- msecs_to_jiffies(priv->ieee80211->fsync_time_interval);
+- add_timer(&priv->fsync_timer);
++ cancel_delayed_work_sync(&priv->fsync_work);
++ schedule_delayed_work(&priv->fsync_work,
++ msecs_to_jiffies(priv
++ ->ieee80211->fsync_time_interval));
+ }
+ } else {
+ /* Let Register return to default value; */
+@@ -2695,7 +2695,7 @@ static void dm_EndSWFsync(struct net_device *dev)
+ struct r8192_priv *priv = ieee80211_priv(dev);
+
+ RT_TRACE(COMP_HALDM, "%s\n", __func__);
+- del_timer_sync(&(priv->fsync_timer));
++ cancel_delayed_work_sync(&priv->fsync_work);
+
+ /* Let Register return to default value; */
+ if (priv->bswitch_fsync) {
+@@ -2736,11 +2736,9 @@ static void dm_StartSWFsync(struct net_device *dev)
+ if (priv->ieee80211->fsync_rate_bitmap & rateBitmap)
+ priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
+ }
+- if (timer_pending(&priv->fsync_timer))
+- del_timer_sync(&priv->fsync_timer);
+- priv->fsync_timer.expires = jiffies +
+- msecs_to_jiffies(priv->ieee80211->fsync_time_interval);
+- add_timer(&priv->fsync_timer);
++ cancel_delayed_work_sync(&priv->fsync_work);
++ schedule_delayed_work(&priv->fsync_work,
++ msecs_to_jiffies(priv->ieee80211->fsync_time_interval));
+
+ write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
+ }
+diff --git a/drivers/staging/rtl8192u/r8192U_dm.h b/drivers/staging/rtl8192u/r8192U_dm.h
+index 0b2a1c688597..2159018b4e38 100644
+--- a/drivers/staging/rtl8192u/r8192U_dm.h
++++ b/drivers/staging/rtl8192u/r8192U_dm.h
+@@ -166,7 +166,7 @@ void dm_force_tx_fw_info(struct net_device *dev,
+ void dm_init_edca_turbo(struct net_device *dev);
+ void dm_rf_operation_test_callback(unsigned long data);
+ void dm_rf_pathcheck_workitemcallback(struct work_struct *work);
+-void dm_fsync_timer_callback(struct timer_list *t);
++void dm_fsync_work_callback(struct work_struct *work);
+ void dm_cck_txpower_adjust(struct net_device *dev, bool binch14);
+ void dm_shadow_init(struct net_device *dev);
+ void dm_initialize_txpower_tracking(struct net_device *dev);
+--
+2.35.1
+
--- /dev/null
+From e85bd99bd520d1c088b72d9c582053d3dd5aa094 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Jul 2022 08:46:45 +0200
+Subject: swiotlb: fail map correctly with failed io_tlb_default_mem
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+[ Upstream commit c51ba246cb172c9e947dc6fb8868a1eaf0b2a913 ]
+
+In the failure case of trying to use a buffer which we'd previously
+failed to allocate, the "!mem" condition is no longer sufficient since
+io_tlb_default_mem became static and assigned by default. Update the
+condition to work as intended per the rest of that conversion.
+
+Fixes: 463e862ac63e ("swiotlb: Convert io_default_tlb_mem to static allocation")
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/dma/swiotlb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
+index 73a41cec9e38..90e5f5c92fdc 100644
+--- a/kernel/dma/swiotlb.c
++++ b/kernel/dma/swiotlb.c
+@@ -588,7 +588,7 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr,
+ int index;
+ phys_addr_t tlb_addr;
+
+- if (!mem)
++ if (!mem || !mem->nslabs)
+ panic("Can not allocate SWIOTLB buffer earlier and can't now provide you with the DMA bounce buffer");
+
+ if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
+--
+2.35.1
+
--- /dev/null
+From 9b46a171aedb3f64c403dd1e4f3acbfb4a5c2082 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jun 2022 10:17:34 -0700
+Subject: tcp: fix possible freeze in tx path under memory pressure
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 849b425cd091e1804af964b771761cfbefbafb43 ]
+
+Blamed commit only dealt with applications issuing small writes.
+
+Issue here is that we allow to force memory schedule for the sk_buff
+allocation, but we have no guarantee that sendmsg() is able to
+copy some payload in it.
+
+In this patch, I make sure the socket can use up to tcp_wmem[0] bytes.
+
+For example, if we consider tcp_wmem[0] = 4096 (default on x86),
+and initial skb->truesize being 1280, tcp_sendmsg() is able to
+copy up to 2816 bytes under memory pressure.
+
+Before this patch a sendmsg() sending more than 2816 bytes
+would either block forever (if persistent memory pressure),
+or return -EAGAIN.
+
+For bigger MTU networks, it is advised to increase tcp_wmem[0]
+to avoid sending too small packets.
+
+v2: deal with zero copy paths.
+
+Fixes: 8e4d980ac215 ("tcp: fix behavior for epoll edge trigger")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
+Reviewed-by: Wei Wang <weiwan@google.com>
+Reviewed-by: Shakeel Butt <shakeelb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp.c | 33 +++++++++++++++++++++++++++++----
+ 1 file changed, 29 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 91735d631a28..51116166e3d2 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -953,6 +953,23 @@ static int tcp_downgrade_zcopy_pure(struct sock *sk, struct sk_buff *skb)
+ return 0;
+ }
+
++static int tcp_wmem_schedule(struct sock *sk, int copy)
++{
++ int left;
++
++ if (likely(sk_wmem_schedule(sk, copy)))
++ return copy;
++
++ /* We could be in trouble if we have nothing queued.
++ * Use whatever is left in sk->sk_forward_alloc and tcp_wmem[0]
++ * to guarantee some progress.
++ */
++ left = sock_net(sk)->ipv4.sysctl_tcp_wmem[0] - sk->sk_wmem_queued;
++ if (left > 0)
++ sk_forced_mem_schedule(sk, min(left, copy));
++ return min(copy, sk->sk_forward_alloc);
++}
++
+ static struct sk_buff *tcp_build_frag(struct sock *sk, int size_goal, int flags,
+ struct page *page, int offset, size_t *size)
+ {
+@@ -988,7 +1005,11 @@ static struct sk_buff *tcp_build_frag(struct sock *sk, int size_goal, int flags,
+ tcp_mark_push(tp, skb);
+ goto new_segment;
+ }
+- if (tcp_downgrade_zcopy_pure(sk, skb) || !sk_wmem_schedule(sk, copy))
++ if (tcp_downgrade_zcopy_pure(sk, skb))
++ return NULL;
++
++ copy = tcp_wmem_schedule(sk, copy);
++ if (!copy)
+ return NULL;
+
+ if (can_coalesce) {
+@@ -1337,8 +1358,11 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
+
+ copy = min_t(int, copy, pfrag->size - pfrag->offset);
+
+- if (tcp_downgrade_zcopy_pure(sk, skb) ||
+- !sk_wmem_schedule(sk, copy))
++ if (tcp_downgrade_zcopy_pure(sk, skb))
++ goto wait_for_space;
++
++ copy = tcp_wmem_schedule(sk, copy);
++ if (!copy)
+ goto wait_for_space;
+
+ err = skb_copy_to_page_nocache(sk, &msg->msg_iter, skb,
+@@ -1365,7 +1389,8 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
+ skb_shinfo(skb)->flags |= SKBFL_PURE_ZEROCOPY;
+
+ if (!skb_zcopy_pure(skb)) {
+- if (!sk_wmem_schedule(sk, copy))
++ copy = tcp_wmem_schedule(sk, copy);
++ if (!copy)
+ goto wait_for_space;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 0d2119d8409dd57113df70ba5e620e655a10c00d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Jul 2022 17:47:18 +0800
+Subject: tcp: make retransmitted SKB fit into the send window
+
+From: Yonglong Li <liyonglong@chinatelecom.cn>
+
+[ Upstream commit 536a6c8e05f95e3d1118c40ae8b3022ee2d05d52 ]
+
+current code of __tcp_retransmit_skb only check TCP_SKB_CB(skb)->seq
+in send window, and TCP_SKB_CB(skb)->seq_end maybe out of send window.
+If receiver has shrunk his window, and skb is out of new window, it
+should retransmit a smaller portion of the payload.
+
+test packetdrill script:
+ 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+ +0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
+ +0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
+
+ +0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)
+ +0 > S 0:0(0) win 65535 <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 8>
+ +.05 < S. 0:0(0) ack 1 win 6000 <mss 1000,nop,nop,sackOK>
+ +0 > . 1:1(0) ack 1
+
+ +0 write(3, ..., 10000) = 10000
+
+ +0 > . 1:2001(2000) ack 1 win 65535
+ +0 > . 2001:4001(2000) ack 1 win 65535
+ +0 > . 4001:6001(2000) ack 1 win 65535
+
+ +.05 < . 1:1(0) ack 4001 win 1001
+
+and tcpdump show:
+192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 1:2001, ack 1, win 65535, length 2000
+192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 2001:4001, ack 1, win 65535, length 2000
+192.168.226.67.55 > 192.0.2.1.8080: Flags [P.], seq 4001:5001, ack 1, win 65535, length 1000
+192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 5001:6001, ack 1, win 65535, length 1000
+192.0.2.1.8080 > 192.168.226.67.55: Flags [.], ack 4001, win 1001, length 0
+192.168.226.67.55 > 192.0.2.1.8080: Flags [.], seq 5001:6001, ack 1, win 65535, length 1000
+192.168.226.67.55 > 192.0.2.1.8080: Flags [P.], seq 4001:5001, ack 1, win 65535, length 1000
+
+when cient retract window to 1001, send window is [4001,5002],
+but TLP send 5001-6001 packet which is out of send window.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yonglong Li <liyonglong@chinatelecom.cn>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Link: https://lore.kernel.org/r/1657532838-20200-1-git-send-email-liyonglong@chinatelecom.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_output.c | 23 ++++++++++++++++-------
+ 1 file changed, 16 insertions(+), 7 deletions(-)
+
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index a7f0a1f0c2a3..e90b99fa79bf 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -3140,7 +3140,7 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
+ struct tcp_sock *tp = tcp_sk(sk);
+ unsigned int cur_mss;
+ int diff, len, err;
+-
++ int avail_wnd;
+
+ /* Inconclusive MTU probe */
+ if (icsk->icsk_mtup.probe_size)
+@@ -3162,17 +3162,25 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
+ return -EHOSTUNREACH; /* Routing failure or similar. */
+
+ cur_mss = tcp_current_mss(sk);
++ avail_wnd = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq;
+
+ /* If receiver has shrunk his window, and skb is out of
+ * new window, do not retransmit it. The exception is the
+ * case, when window is shrunk to zero. In this case
+- * our retransmit serves as a zero window probe.
++ * our retransmit of one segment serves as a zero window probe.
+ */
+- if (!before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(tp)) &&
+- TCP_SKB_CB(skb)->seq != tp->snd_una)
+- return -EAGAIN;
++ if (avail_wnd <= 0) {
++ if (TCP_SKB_CB(skb)->seq != tp->snd_una)
++ return -EAGAIN;
++ avail_wnd = cur_mss;
++ }
+
+ len = cur_mss * segs;
++ if (len > avail_wnd) {
++ len = rounddown(avail_wnd, cur_mss);
++ if (!len)
++ len = avail_wnd;
++ }
+ if (skb->len > len) {
+ if (tcp_fragment(sk, TCP_FRAG_IN_RTX_QUEUE, skb, len,
+ cur_mss, GFP_ATOMIC))
+@@ -3186,8 +3194,9 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
+ diff -= tcp_skb_pcount(skb);
+ if (diff)
+ tcp_adjust_pcount(sk, skb, diff);
+- if (skb->len < cur_mss)
+- tcp_retrans_try_collapse(sk, skb, cur_mss);
++ avail_wnd = min_t(int, avail_wnd, cur_mss);
++ if (skb->len < avail_wnd)
++ tcp_retrans_try_collapse(sk, skb, avail_wnd);
+ }
+
+ /* RFC3168, section 6.1.1.1. ECN fallback */
+--
+2.35.1
+
--- /dev/null
+From 25c3d74445644d7d6dae1a76473d481f65d2321f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jun 2022 21:50:02 +0800
+Subject: test_bpf: fix incorrect netdev features
+
+From: Jian Shen <shenjian15@huawei.com>
+
+[ Upstream commit 9676feccacdb0571791c88b23e3b7ac4e7c9c457 ]
+
+The prototype of .features is netdev_features_t, it should use
+NETIF_F_LLTX and NETIF_F_HW_VLAN_STAG_TX, not NETIF_F_LLTX_BIT
+and NETIF_F_HW_VLAN_STAG_TX_BIT.
+
+Fixes: cf204a718357 ("bpf, testing: Introduce 'gso_linear_no_head_frag' skb_segment test")
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/r/20220622135002.8263-1-shenjian15@huawei.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/test_bpf.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/test_bpf.c b/lib/test_bpf.c
+index 0c5cb2d6436a..1a00d0247f70 100644
+--- a/lib/test_bpf.c
++++ b/lib/test_bpf.c
+@@ -14456,9 +14456,9 @@ static struct skb_segment_test skb_segment_tests[] __initconst = {
+ .build_skb = build_test_skb_linear_no_head_frag,
+ .features = NETIF_F_SG | NETIF_F_FRAGLIST |
+ NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_GSO |
+- NETIF_F_LLTX_BIT | NETIF_F_GRO |
++ NETIF_F_LLTX | NETIF_F_GRO |
+ NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
+- NETIF_F_HW_VLAN_STAG_TX_BIT
++ NETIF_F_HW_VLAN_STAG_TX
+ }
+ };
+
+--
+2.35.1
+
--- /dev/null
+From a98a91b7ccdd934b1eba60fb43c9e39a1d35253b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jul 2022 20:10:39 -0700
+Subject: thermal/tools/tmon: Include pthread and time headers in tmon.h
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Markus Mayer <mmayer@broadcom.com>
+
+[ Upstream commit 0cf51bfe999524377fbb71becb583b4ca6d07cfc ]
+
+Include sys/time.h and pthread.h in tmon.h, so that types
+"pthread_mutex_t" and "struct timeval tv" are known when tmon.h
+references them.
+
+Without these headers, compiling tmon against musl-libc will fail with
+these errors:
+
+In file included from sysfs.c:31:0:
+tmon.h:47:8: error: unknown type name 'pthread_mutex_t'
+ extern pthread_mutex_t input_lock;
+ ^~~~~~~~~~~~~~~
+make[3]: *** [<builtin>: sysfs.o] Error 1
+make[3]: *** Waiting for unfinished jobs....
+In file included from tui.c:31:0:
+tmon.h:54:17: error: field 'tv' has incomplete type
+ struct timeval tv;
+ ^~
+make[3]: *** [<builtin>: tui.o] Error 1
+make[2]: *** [Makefile:83: tmon] Error 2
+
+Signed-off-by: Markus Mayer <mmayer@broadcom.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Sumeet Pawnikar <sumeet.r.pawnikar@intel.com>
+Acked-by: Alejandro González <alejandro.gonzalez.correo@gmail.com>
+Tested-by: Alejandro González <alejandro.gonzalez.correo@gmail.com>
+Fixes: 94f69966faf8 ("tools/thermal: Introduce tmon, a tool for thermal subsystem")
+Link: https://lore.kernel.org/r/20220718031040.44714-1-f.fainelli@gmail.com
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/thermal/tmon/tmon.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tools/thermal/tmon/tmon.h b/tools/thermal/tmon/tmon.h
+index c9066ec104dd..44d16d778f04 100644
+--- a/tools/thermal/tmon/tmon.h
++++ b/tools/thermal/tmon/tmon.h
+@@ -27,6 +27,9 @@
+ #define NR_LINES_TZDATA 1
+ #define TMON_LOG_FILE "/var/tmp/tmon.log"
+
++#include <sys/time.h>
++#include <pthread.h>
++
+ extern unsigned long ticktime;
+ extern double time_elapsed;
+ extern unsigned long target_temp_user;
+--
+2.35.1
+
--- /dev/null
+From 99e0d98ae75ad26a5c9e26d18e2186cc392f04de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 16:17:17 +0300
+Subject: tools/power/x86/intel-speed-select: Fix off by one check
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit d9f74d98bbec978edbf860f729b531281ba0d8ff ]
+
+Change > MAX_DIE_PER_PACKAGE to >= MAX_DIE_PER_PACKAGE to prevent
+accessing one element beyond the end of the array.
+
+Fixes: 7fd786dfbd2c ("tools/power/x86/intel-speed-select: OOB daemon mode")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/power/x86/intel-speed-select/isst-daemon.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/power/x86/intel-speed-select/isst-daemon.c b/tools/power/x86/intel-speed-select/isst-daemon.c
+index dd372924bc82..d0400c6684ba 100644
+--- a/tools/power/x86/intel-speed-select/isst-daemon.c
++++ b/tools/power/x86/intel-speed-select/isst-daemon.c
+@@ -41,7 +41,7 @@ void process_level_change(int cpu)
+ time_t tm;
+ int ret;
+
+- if (pkg_id >= MAX_PACKAGE_COUNT || die_id > MAX_DIE_PER_PACKAGE) {
++ if (pkg_id >= MAX_PACKAGE_COUNT || die_id >= MAX_DIE_PER_PACKAGE) {
+ debug_printf("Invalid package/die info for cpu:%d\n", cpu);
+ return;
+ }
+--
+2.35.1
+
--- /dev/null
+From 466c4dd0948c618e76f2c3edd4eb77c394ab3099 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 12:42:48 +0300
+Subject: tools/testing/selftests/vm/hugetlb-madvise.c: silence uninitialized
+ variable warning
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 3d5367a0426da61c7cb616cc85b6239467e261dd ]
+
+This code just reads from memory without caring about the data itself.
+However static checkers complain that "tmp" is never properly initialized.
+Initialize it to zero and change the name to "dummy" to show that we
+don't care about the value stored in it.
+
+Link: https://lkml.kernel.org/r/YtZ8mKJmktA2GaHB@kili
+Fixes: c4b6cb884011 ("selftests/vm: add hugetlb madvise MADV_DONTNEED MADV_REMOVE test")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Souptick Joarder (HPE) <jrdr.linux@gmail.com>
+Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/vm/hugetlb-madvise.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/vm/hugetlb-madvise.c b/tools/testing/selftests/vm/hugetlb-madvise.c
+index 6c6af40f5747..3c9943131881 100644
+--- a/tools/testing/selftests/vm/hugetlb-madvise.c
++++ b/tools/testing/selftests/vm/hugetlb-madvise.c
+@@ -89,10 +89,11 @@ void write_fault_pages(void *addr, unsigned long nr_pages)
+
+ void read_fault_pages(void *addr, unsigned long nr_pages)
+ {
+- unsigned long i, tmp;
++ unsigned long dummy = 0;
++ unsigned long i;
+
+ for (i = 0; i < nr_pages; i++)
+- tmp += *((unsigned long *)(addr + (i * huge_page_size)));
++ dummy += *((unsigned long *)(addr + (i * huge_page_size)));
+ }
+
+ int main(int argc, char **argv)
+--
+2.35.1
+
--- /dev/null
+From 972557a660053c627e67193462de4af95d3e9e7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 10:37:54 -0700
+Subject: tools/thermal: Fix possible path truncations
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+[ Upstream commit 6c58cf40e3a1d2f47c09d3489857e9476316788a ]
+
+A build with -D_FORTIFY_SOURCE=2 enabled will produce the following warnings:
+
+sysfs.c:63:30: warning: '%s' directive output may be truncated writing up to 255 bytes into a region of size between 0 and 255 [-Wformat-truncation=]
+ snprintf(filepath, 256, "%s/%s", path, filename);
+ ^~
+Bump up the buffer to PATH_MAX which is the limit and account for all of
+the possible NUL and separators that could lead to exceeding the
+allocated buffer sizes.
+
+Fixes: 94f69966faf8 ("tools/thermal: Introduce tmon, a tool for thermal subsystem")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/thermal/tmon/sysfs.c | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/tools/thermal/tmon/sysfs.c b/tools/thermal/tmon/sysfs.c
+index b00b1bfd9d8e..cb1108bc9249 100644
+--- a/tools/thermal/tmon/sysfs.c
++++ b/tools/thermal/tmon/sysfs.c
+@@ -13,6 +13,7 @@
+ #include <stdint.h>
+ #include <dirent.h>
+ #include <libintl.h>
++#include <limits.h>
+ #include <ctype.h>
+ #include <time.h>
+ #include <syslog.h>
+@@ -33,9 +34,9 @@ int sysfs_set_ulong(char *path, char *filename, unsigned long val)
+ {
+ FILE *fd;
+ int ret = -1;
+- char filepath[256];
++ char filepath[PATH_MAX + 2]; /* NUL and '/' */
+
+- snprintf(filepath, 256, "%s/%s", path, filename);
++ snprintf(filepath, sizeof(filepath), "%s/%s", path, filename);
+
+ fd = fopen(filepath, "w");
+ if (!fd) {
+@@ -57,9 +58,9 @@ static int sysfs_get_ulong(char *path, char *filename, unsigned long *p_ulong)
+ {
+ FILE *fd;
+ int ret = -1;
+- char filepath[256];
++ char filepath[PATH_MAX + 2]; /* NUL and '/' */
+
+- snprintf(filepath, 256, "%s/%s", path, filename);
++ snprintf(filepath, sizeof(filepath), "%s/%s", path, filename);
+
+ fd = fopen(filepath, "r");
+ if (!fd) {
+@@ -76,9 +77,9 @@ static int sysfs_get_string(char *path, char *filename, char *str)
+ {
+ FILE *fd;
+ int ret = -1;
+- char filepath[256];
++ char filepath[PATH_MAX + 2]; /* NUL and '/' */
+
+- snprintf(filepath, 256, "%s/%s", path, filename);
++ snprintf(filepath, sizeof(filepath), "%s/%s", path, filename);
+
+ fd = fopen(filepath, "r");
+ if (!fd) {
+@@ -199,8 +200,8 @@ static int find_tzone_cdev(struct dirent *nl, char *tz_name,
+ {
+ unsigned long trip_instance = 0;
+ char cdev_name_linked[256];
+- char cdev_name[256];
+- char cdev_trip_name[256];
++ char cdev_name[PATH_MAX];
++ char cdev_trip_name[PATH_MAX];
+ int cdev_id;
+
+ if (nl->d_type == DT_LNK) {
+@@ -213,7 +214,8 @@ static int find_tzone_cdev(struct dirent *nl, char *tz_name,
+ return -EINVAL;
+ }
+ /* find the link to real cooling device record binding */
+- snprintf(cdev_name, 256, "%s/%s", tz_name, nl->d_name);
++ snprintf(cdev_name, sizeof(cdev_name) - 2, "%s/%s",
++ tz_name, nl->d_name);
+ memset(cdev_name_linked, 0, sizeof(cdev_name_linked));
+ if (readlink(cdev_name, cdev_name_linked,
+ sizeof(cdev_name_linked) - 1) != -1) {
+@@ -226,8 +228,8 @@ static int find_tzone_cdev(struct dirent *nl, char *tz_name,
+ /* find the trip point in which the cdev is binded to
+ * in this tzone
+ */
+- snprintf(cdev_trip_name, 256, "%s%s", nl->d_name,
+- "_trip_point");
++ snprintf(cdev_trip_name, sizeof(cdev_trip_name) - 1,
++ "%s%s", nl->d_name, "_trip_point");
+ sysfs_get_ulong(tz_name, cdev_trip_name,
+ &trip_instance);
+ /* validate trip point range, e.g. trip could return -1
+--
+2.35.1
+
--- /dev/null
+From a93d4f5332e50908890943357b263f5db94116a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 May 2022 13:22:28 -0700
+Subject: torture: Adjust to again produce debugging information
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit 5c92d7501699a5deb72a579f808500db5bb6f92a ]
+
+A recent change to the DEBUG_INFO Kconfig option means that simply adding
+CONFIG_DEBUG_INFO=y to the .config file and running "make oldconfig" no
+longer works. It is instead necessary to add CONFIG_DEBUG_INFO_NONE=n
+and (for example) CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y.
+This combination will then result in CONFIG_DEBUG_INFO being selected.
+
+This commit therefore updates the Kconfig options produced in response
+to the kvm.sh --gdb, --kasan, and --kcsan Kconfig options.
+
+Fixes: f9b3cd245784 ("Kconfig.debug: make DEBUG_INFO selectable from a choice")
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/rcutorture/bin/kvm.sh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tools/testing/selftests/rcutorture/bin/kvm.sh b/tools/testing/selftests/rcutorture/bin/kvm.sh
+index b9f4d41da30e..f2768994d861 100755
+--- a/tools/testing/selftests/rcutorture/bin/kvm.sh
++++ b/tools/testing/selftests/rcutorture/bin/kvm.sh
+@@ -164,7 +164,7 @@ do
+ shift
+ ;;
+ --gdb)
+- TORTURE_KCONFIG_GDB_ARG="CONFIG_DEBUG_INFO=y"; export TORTURE_KCONFIG_GDB_ARG
++ TORTURE_KCONFIG_GDB_ARG="CONFIG_DEBUG_INFO_NONE=n CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y"; export TORTURE_KCONFIG_GDB_ARG
+ TORTURE_BOOT_GDB_ARG="nokaslr"; export TORTURE_BOOT_GDB_ARG
+ TORTURE_QEMU_GDB_ARG="-s -S"; export TORTURE_QEMU_GDB_ARG
+ ;;
+@@ -180,7 +180,7 @@ do
+ shift
+ ;;
+ --kasan)
+- TORTURE_KCONFIG_KASAN_ARG="CONFIG_DEBUG_INFO=y CONFIG_KASAN=y"; export TORTURE_KCONFIG_KASAN_ARG
++ TORTURE_KCONFIG_KASAN_ARG="CONFIG_DEBUG_INFO_NONE=n CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_KASAN=y"; export TORTURE_KCONFIG_KASAN_ARG
+ if test -n "$torture_qemu_mem_default"
+ then
+ TORTURE_QEMU_MEM=2G
+@@ -192,7 +192,7 @@ do
+ shift
+ ;;
+ --kcsan)
+- TORTURE_KCONFIG_KCSAN_ARG="CONFIG_DEBUG_INFO=y CONFIG_KCSAN=y CONFIG_KCSAN_STRICT=y CONFIG_KCSAN_REPORT_ONCE_IN_MS=100000 CONFIG_KCSAN_VERBOSE=y CONFIG_DEBUG_LOCK_ALLOC=y CONFIG_PROVE_LOCKING=y"; export TORTURE_KCONFIG_KCSAN_ARG
++ TORTURE_KCONFIG_KCSAN_ARG="CONFIG_DEBUG_INFO_NONE=n CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_KCSAN=y CONFIG_KCSAN_STRICT=y CONFIG_KCSAN_REPORT_ONCE_IN_MS=100000 CONFIG_KCSAN_VERBOSE=y CONFIG_DEBUG_LOCK_ALLOC=y CONFIG_PROVE_LOCKING=y"; export TORTURE_KCONFIG_KCSAN_ARG
+ ;;
+ --kmake-arg|--kmake-args)
+ checkarg --kmake-arg "(kernel make arguments)" $# "$2" '.*' '^error$'
+--
+2.35.1
+
--- /dev/null
+From c4e9cb293916ee590256f31d4b1f12ddf816db8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 14:23:31 +0200
+Subject: tty: n_gsm: fix deadlock and link starvation in outgoing data path
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 0af021678d5d30c31f5a6b631f404ead3575212a ]
+
+The current implementation queues up new control and user packets as needed
+and processes this queue down to the ldisc in the same code path.
+That means that the upper and the lower layer are hard coupled in the code.
+Due to this deadlocks can happen as seen below while transmitting data,
+especially during ldisc congestion. Furthermore, the data channels starve
+the control channel on high transmission load on the ldisc.
+
+Introduce an additional control channel data queue to prevent timeouts and
+link hangups during ldisc congestion. This is being processed before the
+user channel data queue in gsm_data_kick(), i.e. with the highest priority.
+Put the queue to ldisc data path into a workqueue and trigger it whenever
+new data has been put into the transmission queue. Change
+gsm_dlci_data_sweep() accordingly to fill up the transmission queue until
+TX_THRESH_HI. This solves the locking issue, keeps latency low and provides
+good performance on high data load.
+Note that now all packets from a DLCI are removed from the internal queue
+if the associated DLCI was closed. This ensures that no data is sent by the
+introduced write task to an already closed DLCI.
+
+BUG: spinlock recursion on CPU#0, test_v24_loop/124
+ lock: serial8250_ports+0x3a8/0x7500, .magic: dead4ead, .owner: test_v24_loop/124, .owner_cpu: 0
+CPU: 0 PID: 124 Comm: test_v24_loop Tainted: G O 5.18.0-rc2 #3
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
+Call Trace:
+ <IRQ>
+ dump_stack_lvl+0x34/0x44
+ do_raw_spin_lock+0x76/0xa0
+ _raw_spin_lock_irqsave+0x72/0x80
+ uart_write_room+0x3b/0xc0
+ gsm_data_kick+0x14b/0x240 [n_gsm]
+ gsmld_write_wakeup+0x35/0x70 [n_gsm]
+ tty_wakeup+0x53/0x60
+ tty_port_default_wakeup+0x1b/0x30
+ serial8250_tx_chars+0x12f/0x220
+ serial8250_handle_irq.part.0+0xfe/0x150
+ serial8250_default_handle_irq+0x48/0x80
+ serial8250_interrupt+0x56/0xa0
+ __handle_irq_event_percpu+0x78/0x1f0
+ handle_irq_event+0x34/0x70
+ handle_fasteoi_irq+0x90/0x1e0
+ __common_interrupt+0x69/0x100
+ common_interrupt+0x48/0xc0
+ asm_common_interrupt+0x1e/0x40
+RIP: 0010:__do_softirq+0x83/0x34e
+Code: 2a 0a ff 0f b7 ed c7 44 24 10 0a 00 00 00 48 c7 c7 51 2a 64 82 e8 2d
+e2 d5 ff 65 66 c7 05 83 af 1e 7e 00 00 fb b8 ff ff ff ff <49> c7 c2 40 61
+80 82 0f bc c5 41 89 c4 41 83 c4 01 0f 84 e6 00 00
+RSP: 0018:ffffc90000003f98 EFLAGS: 00000286
+RAX: 00000000ffffffff RBX: 0000000000000000 RCX: 0000000000000000
+RDX: 0000000000000000 RSI: ffffffff82642a51 RDI: ffffffff825bb5e7
+RBP: 0000000000000200 R08: 00000008de3271a8 R09: 0000000000000000
+R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
+R13: 0000000000000030 R14: 0000000000000000 R15: 0000000000000000
+ ? __do_softirq+0x73/0x34e
+ irq_exit_rcu+0xb5/0x100
+ common_interrupt+0xa4/0xc0
+ </IRQ>
+ <TASK>
+ asm_common_interrupt+0x1e/0x40
+RIP: 0010:_raw_spin_unlock_irqrestore+0x2e/0x50
+Code: 00 55 48 89 fd 48 83 c7 18 53 48 89 f3 48 8b 74 24 10 e8 85 28 36 ff
+48 89 ef e8 cd 58 36 ff 80 e7 02 74 01 fb bf 01 00 00 00 <e8> 3d 97 33 ff
+65 8b 05 96 23 2b 7e 85 c0 74 03 5b 5d c3 0f 1f 44
+RSP: 0018:ffffc9000020fd08 EFLAGS: 00000202
+RAX: 0000000000000000 RBX: 0000000000000246 RCX: 0000000000000000
+RDX: 0000000000000004 RSI: ffffffff8257fd74 RDI: 0000000000000001
+RBP: ffff8880057de3a0 R08: 00000008de233000 R09: 0000000000000000
+R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
+R13: 0000000000000100 R14: 0000000000000202 R15: ffff8880057df0b8
+ ? _raw_spin_unlock_irqrestore+0x23/0x50
+ gsmtty_write+0x65/0x80 [n_gsm]
+ n_tty_write+0x33f/0x530
+ ? swake_up_all+0xe0/0xe0
+ file_tty_write.constprop.0+0x1b1/0x320
+ ? n_tty_flush_buffer+0xb0/0xb0
+ new_sync_write+0x10c/0x190
+ vfs_write+0x282/0x310
+ ksys_write+0x68/0xe0
+ do_syscall_64+0x3b/0x90
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+RIP: 0033:0x7f3e5e35c15c
+Code: 8b 7c 24 08 89 c5 e8 c5 ff ff ff 89 ef 89 44 24 08 e8 58 bc 02 00 8b
+44 24 08 48 83 c4 10 5d c3 48 63 ff b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff
+ff 76 10 48 8b 15 fd fc 05 00 f7 d8 64 89 02 48 83
+RSP: 002b:00007ffcee77cd18 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
+RAX: ffffffffffffffda RBX: 00007ffcee77cd70 RCX: 00007f3e5e35c15c
+RDX: 0000000000000100 RSI: 00007ffcee77cd90 RDI: 0000000000000003
+RBP: 0000000000000100 R08: 0000000000000000 R09: 7efefefefefefeff
+R10: 00007f3e5e3bddeb R11: 0000000000000246 R12: 00007ffcee77ce8f
+R13: 0000000000000001 R14: 000056214404e010 R15: 00007ffcee77cd90
+ </TASK>
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701122332.2039-1-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 407 ++++++++++++++++++++++++++++++--------------
+ 1 file changed, 279 insertions(+), 128 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index e02f761a3a31..ab7765afab86 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -5,6 +5,14 @@
+ *
+ * * THIS IS A DEVELOPMENT SNAPSHOT IT IS NOT A FINAL RELEASE *
+ *
++ * Outgoing path:
++ * tty -> DLCI fifo -> scheduler -> GSM MUX data queue ---o-> ldisc
++ * control message -> GSM MUX control queue --´
++ *
++ * Incoming path:
++ * ldisc -> gsm_queue() -o--> tty
++ * `-> gsm_control_response()
++ *
+ * TO DO:
+ * Mostly done: ioctls for setting modes/timing
+ * Partly done: hooks so you can pull off frames to non tty devs
+@@ -210,6 +218,9 @@ struct gsm_mux {
+ /* Events on the GSM channel */
+ wait_queue_head_t event;
+
++ /* ldisc send work */
++ struct work_struct tx_work;
++
+ /* Bits for GSM mode decoding */
+
+ /* Framing Layer */
+@@ -241,7 +252,8 @@ struct gsm_mux {
+ unsigned int tx_bytes; /* TX data outstanding */
+ #define TX_THRESH_HI 8192
+ #define TX_THRESH_LO 2048
+- struct list_head tx_list; /* Pending data packets */
++ struct list_head tx_ctrl_list; /* Pending control packets */
++ struct list_head tx_data_list; /* Pending data packets */
+
+ /* Control messages */
+ struct timer_list kick_timer; /* Kick TX queuing on timeout */
+@@ -371,6 +383,11 @@ static const u8 gsm_fcs8[256] = {
+
+ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len);
+ static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk);
++static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len,
++ u8 ctrl);
++static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg);
++static void gsmld_write_trigger(struct gsm_mux *gsm);
++static void gsmld_write_task(struct work_struct *work);
+
+ /**
+ * gsm_fcs_add - update FCS
+@@ -655,57 +672,73 @@ static int gsm_stuff_frame(const u8 *input, u8 *output, int len)
+ * @cr: command/response bit seen as initiator
+ * @control: control byte including PF bit
+ *
+- * Format up and transmit a control frame. These do not go via the
+- * queueing logic as they should be transmitted ahead of data when
+- * they are needed.
+- *
+- * FIXME: Lock versus data TX path
++ * Format up and transmit a control frame. These should be transmitted
++ * ahead of data when they are needed.
+ */
+-
+-static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
++static int gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
+ {
+- int len;
+- u8 cbuf[10];
+- u8 ibuf[3];
++ struct gsm_msg *msg;
++ u8 *dp;
+ int ocr;
++ unsigned long flags;
++
++ msg = gsm_data_alloc(gsm, addr, 0, control);
++ if (!msg)
++ return -ENOMEM;
+
+ /* toggle C/R coding if not initiator */
+ ocr = cr ^ (gsm->initiator ? 0 : 1);
+
+- switch (gsm->encoding) {
+- case 0:
+- cbuf[0] = GSM0_SOF;
+- cbuf[1] = (addr << 2) | (ocr << 1) | EA;
+- cbuf[2] = control;
+- cbuf[3] = EA; /* Length of data = 0 */
+- cbuf[4] = 0xFF - gsm_fcs_add_block(INIT_FCS, cbuf + 1, 3);
+- cbuf[5] = GSM0_SOF;
+- len = 6;
+- break;
+- case 1:
+- case 2:
+- /* Control frame + packing (but not frame stuffing) in mode 1 */
+- ibuf[0] = (addr << 2) | (ocr << 1) | EA;
+- ibuf[1] = control;
+- ibuf[2] = 0xFF - gsm_fcs_add_block(INIT_FCS, ibuf, 2);
+- /* Stuffing may double the size worst case */
+- len = gsm_stuff_frame(ibuf, cbuf + 1, 3);
+- /* Now add the SOF markers */
+- cbuf[0] = GSM1_SOF;
+- cbuf[len + 1] = GSM1_SOF;
+- /* FIXME: we can omit the lead one in many cases */
+- len += 2;
+- break;
+- default:
+- WARN_ON(1);
+- return;
+- }
+- gsmld_output(gsm, cbuf, len);
+- if (!gsm->initiator) {
+- cr = cr & gsm->initiator;
+- control = control & ~PF;
++ msg->data -= 3;
++ dp = msg->data;
++ *dp++ = (addr << 2) | (ocr << 1) | EA;
++ *dp++ = control;
++
++ if (gsm->encoding == 0)
++ *dp++ = EA; /* Length of data = 0 */
++
++ *dp = 0xFF - gsm_fcs_add_block(INIT_FCS, msg->data, dp - msg->data);
++ msg->len = (dp - msg->data) + 1;
++
++ gsm_print_packet("Q->", addr, cr, control, NULL, 0);
++
++ spin_lock_irqsave(&gsm->tx_lock, flags);
++ list_add_tail(&msg->list, &gsm->tx_ctrl_list);
++ gsm->tx_bytes += msg->len;
++ spin_unlock_irqrestore(&gsm->tx_lock, flags);
++ gsmld_write_trigger(gsm);
++
++ return 0;
++}
++
++/**
++ * gsm_dlci_clear_queues - remove outstanding data for a DLCI
++ * @gsm: mux
++ * @dlci: clear for this DLCI
++ *
++ * Clears the data queues for a given DLCI.
++ */
++static void gsm_dlci_clear_queues(struct gsm_mux *gsm, struct gsm_dlci *dlci)
++{
++ struct gsm_msg *msg, *nmsg;
++ int addr = dlci->addr;
++ unsigned long flags;
++
++ /* Clear DLCI write fifo first */
++ spin_lock_irqsave(&dlci->lock, flags);
++ kfifo_reset(&dlci->fifo);
++ spin_unlock_irqrestore(&dlci->lock, flags);
++
++ /* Clear data packets in MUX write queue */
++ spin_lock_irqsave(&gsm->tx_lock, flags);
++ list_for_each_entry_safe(msg, nmsg, &gsm->tx_data_list, list) {
++ if (msg->addr != addr)
++ continue;
++ gsm->tx_bytes -= msg->len;
++ list_del(&msg->list);
++ kfree(msg);
+ }
+- gsm_print_packet("-->", addr, cr, control, NULL, 0);
++ spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ }
+
+ /**
+@@ -767,6 +800,45 @@ static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len,
+ return m;
+ }
+
++/**
++ * gsm_send_packet - sends a single packet
++ * @gsm: GSM Mux
++ * @msg: packet to send
++ *
++ * The given packet is encoded and sent out. No memory is freed.
++ * The caller must hold the gsm tx lock.
++ */
++static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg)
++{
++ int len, ret;
++
++
++ if (gsm->encoding == 0) {
++ gsm->txframe[0] = GSM0_SOF;
++ memcpy(gsm->txframe + 1, msg->data, msg->len);
++ gsm->txframe[msg->len + 1] = GSM0_SOF;
++ len = msg->len + 2;
++ } else {
++ gsm->txframe[0] = GSM1_SOF;
++ len = gsm_stuff_frame(msg->data, gsm->txframe + 1, msg->len);
++ gsm->txframe[len + 1] = GSM1_SOF;
++ len += 2;
++ }
++
++ if (debug & 4)
++ gsm_hex_dump_bytes(__func__, gsm->txframe, len);
++ gsm_print_packet("-->", msg->addr, gsm->initiator, msg->ctrl, msg->data,
++ msg->len);
++
++ ret = gsmld_output(gsm, gsm->txframe, len);
++ if (ret <= 0)
++ return ret;
++ /* FIXME: Can eliminate one SOF in many more cases */
++ gsm->tx_bytes -= msg->len;
++
++ return 0;
++}
++
+ /**
+ * gsm_is_flow_ctrl_msg - checks if flow control message
+ * @msg: message to check
+@@ -799,59 +871,81 @@ static bool gsm_is_flow_ctrl_msg(struct gsm_msg *msg)
+ }
+
+ /**
+- * gsm_data_kick - poke the queue
++ * gsm_data_kick - poke the queue
+ * @gsm: GSM Mux
+- * @dlci: DLCI sending the data
+ *
+ * The tty device has called us to indicate that room has appeared in
+- * the transmit queue. Ram more data into the pipe if we have any
++ * the transmit queue. Ram more data into the pipe if we have any.
+ * If we have been flow-stopped by a CMD_FCOFF, then we can only
+- * send messages on DLCI0 until CMD_FCON
+- *
+- * FIXME: lock against link layer control transmissions
++ * send messages on DLCI0 until CMD_FCON. The caller must hold
++ * the gsm tx lock.
+ */
+-
+-static void gsm_data_kick(struct gsm_mux *gsm, struct gsm_dlci *dlci)
++static int gsm_data_kick(struct gsm_mux *gsm)
+ {
+ struct gsm_msg *msg, *nmsg;
+- int len;
++ struct gsm_dlci *dlci;
++ int ret;
+
+- list_for_each_entry_safe(msg, nmsg, &gsm->tx_list, list) {
++ clear_bit(TTY_DO_WRITE_WAKEUP, &gsm->tty->flags);
++
++ /* Serialize control messages and control channel messages first */
++ list_for_each_entry_safe(msg, nmsg, &gsm->tx_ctrl_list, list) {
+ if (gsm->constipated && !gsm_is_flow_ctrl_msg(msg))
++ return -EAGAIN;
++ ret = gsm_send_packet(gsm, msg);
++ switch (ret) {
++ case -ENOSPC:
++ return -ENOSPC;
++ case -ENODEV:
++ /* ldisc not open */
++ gsm->tx_bytes -= msg->len;
++ list_del(&msg->list);
++ kfree(msg);
+ continue;
+- if (gsm->encoding != 0) {
+- gsm->txframe[0] = GSM1_SOF;
+- len = gsm_stuff_frame(msg->data,
+- gsm->txframe + 1, msg->len);
+- gsm->txframe[len + 1] = GSM1_SOF;
+- len += 2;
+- } else {
+- gsm->txframe[0] = GSM0_SOF;
+- memcpy(gsm->txframe + 1 , msg->data, msg->len);
+- gsm->txframe[msg->len + 1] = GSM0_SOF;
+- len = msg->len + 2;
+- }
+-
+- if (debug & 4)
+- gsm_hex_dump_bytes(__func__, gsm->txframe, len);
+- if (gsmld_output(gsm, gsm->txframe, len) <= 0)
++ default:
++ if (ret >= 0) {
++ list_del(&msg->list);
++ kfree(msg);
++ }
+ break;
+- /* FIXME: Can eliminate one SOF in many more cases */
+- gsm->tx_bytes -= msg->len;
+-
+- list_del(&msg->list);
+- kfree(msg);
++ }
++ }
+
+- if (dlci) {
+- tty_port_tty_wakeup(&dlci->port);
+- } else {
+- int i = 0;
++ if (gsm->constipated)
++ return -EAGAIN;
+
+- for (i = 0; i < NUM_DLCI; i++)
+- if (gsm->dlci[i])
+- tty_port_tty_wakeup(&gsm->dlci[i]->port);
++ /* Serialize other channels */
++ if (list_empty(&gsm->tx_data_list))
++ return 0;
++ list_for_each_entry_safe(msg, nmsg, &gsm->tx_data_list, list) {
++ dlci = gsm->dlci[msg->addr];
++ /* Send only messages for DLCIs with valid state */
++ if (dlci->state != DLCI_OPEN) {
++ gsm->tx_bytes -= msg->len;
++ list_del(&msg->list);
++ kfree(msg);
++ continue;
++ }
++ ret = gsm_send_packet(gsm, msg);
++ switch (ret) {
++ case -ENOSPC:
++ return -ENOSPC;
++ case -ENODEV:
++ /* ldisc not open */
++ gsm->tx_bytes -= msg->len;
++ list_del(&msg->list);
++ kfree(msg);
++ continue;
++ default:
++ if (ret >= 0) {
++ list_del(&msg->list);
++ kfree(msg);
++ }
++ break;
+ }
+ }
++
++ return 1;
+ }
+
+ /**
+@@ -900,9 +994,21 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+ msg->data = dp;
+
+ /* Add to the actual output queue */
+- list_add_tail(&msg->list, &gsm->tx_list);
++ switch (msg->ctrl & ~PF) {
++ case UI:
++ case UIH:
++ if (msg->addr > 0) {
++ list_add_tail(&msg->list, &gsm->tx_data_list);
++ break;
++ }
++ fallthrough;
++ default:
++ list_add_tail(&msg->list, &gsm->tx_ctrl_list);
++ break;
++ }
+ gsm->tx_bytes += msg->len;
+- gsm_data_kick(gsm, dlci);
++
++ gsmld_write_trigger(gsm);
+ mod_timer(&gsm->kick_timer, jiffies + 10 * gsm->t1 * HZ / 100);
+ }
+
+@@ -1129,32 +1235,39 @@ static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci,
+
+ static int gsm_dlci_data_sweep(struct gsm_mux *gsm)
+ {
+- int len, ret = 0;
+ /* Priority ordering: We should do priority with RR of the groups */
+- int i = 1;
+-
+- while (i < NUM_DLCI) {
+- struct gsm_dlci *dlci;
++ int i, len, ret = 0;
++ bool sent;
++ struct gsm_dlci *dlci;
+
+- if (gsm->tx_bytes > TX_THRESH_HI)
+- break;
+- dlci = gsm->dlci[i];
+- if (dlci == NULL || dlci->constipated) {
+- i++;
+- continue;
++ while (gsm->tx_bytes < TX_THRESH_HI) {
++ for (sent = false, i = 1; i < NUM_DLCI; i++) {
++ dlci = gsm->dlci[i];
++ /* skip unused or blocked channel */
++ if (!dlci || dlci->constipated)
++ continue;
++ /* skip channels with invalid state */
++ if (dlci->state != DLCI_OPEN)
++ continue;
++ /* count the sent data per adaption */
++ if (dlci->adaption < 3 && !dlci->net)
++ len = gsm_dlci_data_output(gsm, dlci);
++ else
++ len = gsm_dlci_data_output_framed(gsm, dlci);
++ /* on error exit */
++ if (len < 0)
++ return ret;
++ if (len > 0) {
++ ret++;
++ sent = true;
++ /* The lower DLCs can starve the higher DLCs! */
++ break;
++ }
++ /* try next */
+ }
+- if (dlci->adaption < 3 && !dlci->net)
+- len = gsm_dlci_data_output(gsm, dlci);
+- else
+- len = gsm_dlci_data_output_framed(gsm, dlci);
+- if (len < 0)
++ if (!sent)
+ break;
+- /* DLCI empty - try the next */
+- if (len == 0)
+- i++;
+- else
+- ret++;
+- }
++ };
+
+ return ret;
+ }
+@@ -1402,7 +1515,6 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command,
+ const u8 *data, int clen)
+ {
+ u8 buf[1];
+- unsigned long flags;
+
+ switch (command) {
+ case CMD_CLD: {
+@@ -1424,9 +1536,7 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command,
+ gsm->constipated = false;
+ gsm_control_reply(gsm, CMD_FCON, NULL, 0);
+ /* Kick the link in case it is idling */
+- spin_lock_irqsave(&gsm->tx_lock, flags);
+- gsm_data_kick(gsm, NULL);
+- spin_unlock_irqrestore(&gsm->tx_lock, flags);
++ gsmld_write_trigger(gsm);
+ break;
+ case CMD_FCOFF:
+ /* Modem wants us to STFU */
+@@ -1629,8 +1739,6 @@ static int gsm_control_wait(struct gsm_mux *gsm, struct gsm_control *control)
+
+ static void gsm_dlci_close(struct gsm_dlci *dlci)
+ {
+- unsigned long flags;
+-
+ del_timer(&dlci->t1);
+ if (debug & 8)
+ pr_debug("DLCI %d goes closed.\n", dlci->addr);
+@@ -1639,17 +1747,16 @@ static void gsm_dlci_close(struct gsm_dlci *dlci)
+ dlci->constipated = true;
+ if (dlci->addr != 0) {
+ tty_port_tty_hangup(&dlci->port, false);
+- spin_lock_irqsave(&dlci->lock, flags);
+- kfifo_reset(&dlci->fifo);
+- spin_unlock_irqrestore(&dlci->lock, flags);
++ gsm_dlci_clear_queues(dlci->gsm, dlci);
+ /* Ensure that gsmtty_open() can return. */
+ tty_port_set_initialized(&dlci->port, 0);
+ wake_up_interruptible(&dlci->port.open_wait);
+ } else
+ dlci->gsm->dead = true;
+- wake_up(&dlci->gsm->event);
+ /* A DLCI 0 close is a MUX termination so we need to kick that
+ back to userspace somehow */
++ gsm_dlci_data_kick(dlci);
++ wake_up(&dlci->gsm->event);
+ }
+
+ /**
+@@ -1672,6 +1779,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
+ /* Send current modem state */
+ if (dlci->addr)
+ gsm_modem_update(dlci, 0);
++ gsm_dlci_data_kick(dlci);
+ wake_up(&dlci->gsm->event);
+ }
+
+@@ -2226,7 +2334,7 @@ static void gsm1_receive(struct gsm_mux *gsm, unsigned char c)
+ } else if ((c & ISO_IEC_646_MASK) == XOFF) {
+ gsm->constipated = false;
+ /* Kick the link in case it is idling */
+- gsm_data_kick(gsm, NULL);
++ gsmld_write_trigger(gsm);
+ return;
+ }
+ if (c == GSM1_SOF) {
+@@ -2357,6 +2465,9 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
+ del_timer_sync(&gsm->kick_timer);
+ del_timer_sync(&gsm->t2_timer);
+
++ /* Finish writing to ldisc */
++ flush_work(&gsm->tx_work);
++
+ /* Free up any link layer users and finally the control channel */
+ if (gsm->has_devices) {
+ gsm_unregister_devices(gsm_tty_driver, gsm->num);
+@@ -2368,9 +2479,12 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
+ mutex_unlock(&gsm->mutex);
+ /* Now wipe the queues */
+ tty_ldisc_flush(gsm->tty);
+- list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list)
++ list_for_each_entry_safe(txq, ntxq, &gsm->tx_ctrl_list, list)
++ kfree(txq);
++ INIT_LIST_HEAD(&gsm->tx_ctrl_list);
++ list_for_each_entry_safe(txq, ntxq, &gsm->tx_data_list, list)
+ kfree(txq);
+- INIT_LIST_HEAD(&gsm->tx_list);
++ INIT_LIST_HEAD(&gsm->tx_data_list);
+ }
+
+ /**
+@@ -2389,6 +2503,7 @@ static int gsm_activate_mux(struct gsm_mux *gsm)
+
+ timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+ timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
++ INIT_WORK(&gsm->tx_work, gsmld_write_task);
+ init_waitqueue_head(&gsm->event);
+ spin_lock_init(&gsm->control_lock);
+ spin_lock_init(&gsm->tx_lock);
+@@ -2498,7 +2613,8 @@ static struct gsm_mux *gsm_alloc_mux(void)
+ spin_lock_init(&gsm->lock);
+ mutex_init(&gsm->mutex);
+ kref_init(&gsm->ref);
+- INIT_LIST_HEAD(&gsm->tx_list);
++ INIT_LIST_HEAD(&gsm->tx_ctrl_list);
++ INIT_LIST_HEAD(&gsm->tx_data_list);
+
+ gsm->t1 = T1;
+ gsm->t2 = T2;
+@@ -2655,6 +2771,47 @@ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len)
+ return gsm->tty->ops->write(gsm->tty, data, len);
+ }
+
++
++/**
++ * gsmld_write_trigger - schedule ldisc write task
++ * @gsm: our mux
++ */
++static void gsmld_write_trigger(struct gsm_mux *gsm)
++{
++ if (!gsm || !gsm->dlci[0] || gsm->dlci[0]->dead)
++ return;
++ schedule_work(&gsm->tx_work);
++}
++
++
++/**
++ * gsmld_write_task - ldisc write task
++ * @work: our tx write work
++ *
++ * Writes out data to the ldisc if possible. We are doing this here to
++ * avoid dead-locking. This returns if no space or data is left for output.
++ */
++static void gsmld_write_task(struct work_struct *work)
++{
++ struct gsm_mux *gsm = container_of(work, struct gsm_mux, tx_work);
++ unsigned long flags;
++ int i, ret;
++
++ /* All outstanding control channel and control messages and one data
++ * frame is sent.
++ */
++ ret = -ENODEV;
++ spin_lock_irqsave(&gsm->tx_lock, flags);
++ if (gsm->tty)
++ ret = gsm_data_kick(gsm);
++ spin_unlock_irqrestore(&gsm->tx_lock, flags);
++
++ if (ret >= 0)
++ for (i = 0; i < NUM_DLCI; i++)
++ if (gsm->dlci[i])
++ tty_port_tty_wakeup(&gsm->dlci[i]->port);
++}
++
+ /**
+ * gsmld_attach_gsm - mode set up
+ * @tty: our tty structure
+@@ -2794,6 +2951,7 @@ static int gsmld_open(struct tty_struct *tty)
+
+ timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+ timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
++ INIT_WORK(&gsm->tx_work, gsmld_write_task);
+
+ return 0;
+ }
+@@ -2810,16 +2968,9 @@ static int gsmld_open(struct tty_struct *tty)
+ static void gsmld_write_wakeup(struct tty_struct *tty)
+ {
+ struct gsm_mux *gsm = tty->disc_data;
+- unsigned long flags;
+
+ /* Queue poll */
+- clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+- spin_lock_irqsave(&gsm->tx_lock, flags);
+- gsm_data_kick(gsm, NULL);
+- if (gsm->tx_bytes < TX_THRESH_LO) {
+- gsm_dlci_data_sweep(gsm);
+- }
+- spin_unlock_irqrestore(&gsm->tx_lock, flags);
++ gsmld_write_trigger(gsm);
+ }
+
+ /**
+--
+2.35.1
+
--- /dev/null
+From 669b21af69fc15ee2e795158f3c8a47b138b28db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 13:32:21 +0200
+Subject: tty: n_gsm: fix DM command
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 18a948c7d90995d127785e308fa7b701df4c499f ]
+
+n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010.
+See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516
+The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to
+the newer 27.010 here. Chapter 5.3.3 defines the DM response. There exists
+no DM command. However, the current implementation incorrectly sends DM as
+command in case of unexpected UIH frames in gsm_queue().
+Correct this behavior by always sending DM as response.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220707113223.3685-2-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 825c4b550ee0..8b8c7312935f 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -2211,7 +2211,7 @@ static void gsm_queue(struct gsm_mux *gsm)
+ goto invalid;
+ #endif
+ if (dlci == NULL || dlci->state != DLCI_OPEN) {
+- gsm_command(gsm, address, DM|PF);
++ gsm_response(gsm, address, DM|PF);
+ return;
+ }
+ dlci->data(dlci, gsm->buf, gsm->len);
+--
+2.35.1
+
--- /dev/null
+From b1f19dddab52e801f4265ecae96c13184fd7af42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 13:32:22 +0200
+Subject: tty: n_gsm: fix flow control handling in tx path
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 59ff0680ecbfec742b1e0381e7cc46b41eb06647 ]
+
+The current implementation constipates all transmission paths during flow
+control except for flow control frames. However, these may not be located
+at the beginning of the transmission queue of the control channel.
+Ensure that flow control frames in the transmission queue for the control
+channel are always handled even if constipated by skipping through other
+messages.
+
+Fixes: 0af021678d5d ("tty: n_gsm: fix deadlock and link starvation in outgoing data path")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220707113223.3685-3-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 8b8c7312935f..7749de4f269a 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -891,7 +891,7 @@ static int gsm_data_kick(struct gsm_mux *gsm)
+ /* Serialize control messages and control channel messages first */
+ list_for_each_entry_safe(msg, nmsg, &gsm->tx_ctrl_list, list) {
+ if (gsm->constipated && !gsm_is_flow_ctrl_msg(msg))
+- return -EAGAIN;
++ continue;
+ ret = gsm_send_packet(gsm, msg);
+ switch (ret) {
+ case -ENOSPC:
+--
+2.35.1
+
--- /dev/null
+From 0e6b2b1ff652ff583bcd85665aaa1f5fd0c909aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 13:32:23 +0200
+Subject: tty: n_gsm: fix missing corner cases in gsmld_poll()
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 7e5b4322cde067e1d0f1bf8f490e93f664a7c843 ]
+
+gsmld_poll() currently fails to handle the following corner cases correctly:
+- remote party closed the associated tty
+
+Add the missing checks and map those to EPOLLHUP.
+Reorder the checks to group them by their reaction.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220707113223.3685-4-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 7749de4f269a..3dd71ede4cd4 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -3057,12 +3057,15 @@ static __poll_t gsmld_poll(struct tty_struct *tty, struct file *file,
+
+ poll_wait(file, &tty->read_wait, wait);
+ poll_wait(file, &tty->write_wait, wait);
++
++ if (gsm->dead)
++ mask |= EPOLLHUP;
+ if (tty_hung_up_p(file))
+ mask |= EPOLLHUP;
++ if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
++ mask |= EPOLLHUP;
+ if (!tty_is_writelocked(tty) && tty_write_room(tty) > 0)
+ mask |= EPOLLOUT | EPOLLWRNORM;
+- if (gsm->dead)
+- mask |= EPOLLHUP;
+ return mask;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From f7ce0d00e5e55f8b50cf3c6ea1be31c9f72a198a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:16:47 +0200
+Subject: tty: n_gsm: fix missing timer to handle stalled links
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit c568f7086c6e771c77aad13d727c70ef70e07243 ]
+
+The current implementation does not handle the situation that no data is in
+the internal queue and needs to be sent out while the user tty fifo is
+full.
+Add a timer that moves more data from user tty down to the internal queue
+which is then serialized on the ldisc. This timer is triggered if no data
+was moved from a user tty to the internal queue within 10 * T1.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701061652.39604-4-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 43 +++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 35 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 658d8f6e3a7d..27e72c623afb 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -244,6 +244,7 @@ struct gsm_mux {
+ struct list_head tx_list; /* Pending data packets */
+
+ /* Control messages */
++ struct timer_list kick_timer; /* Kick TX queuing on timeout */
+ struct timer_list t2_timer; /* Retransmit timer for commands */
+ int cretries; /* Command retry counter */
+ struct gsm_control *pending_cmd;/* Our current pending command */
+@@ -850,6 +851,7 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+ list_add_tail(&msg->list, &gsm->tx_list);
+ gsm->tx_bytes += msg->len;
+ gsm_data_kick(gsm, dlci);
++ mod_timer(&gsm->kick_timer, jiffies + 10 * gsm->t1 * HZ / 100);
+ }
+
+ /**
+@@ -902,9 +904,6 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+ size = len + h;
+
+ msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
+- /* FIXME: need a timer or something to kick this so it can't
+- * get stuck with no work outstanding and no buffer free
+- */
+ if (!msg)
+ return -ENOMEM;
+ dp = msg->data;
+@@ -981,9 +980,6 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
+
+ size = len + overhead;
+ msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
+-
+- /* FIXME: need a timer or something to kick this so it can't
+- get stuck with no work outstanding and no buffer free */
+ if (msg == NULL) {
+ skb_queue_tail(&dlci->skb_list, dlci->skb);
+ dlci->skb = NULL;
+@@ -1079,9 +1075,9 @@ static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci,
+ * renegotiate DLCI priorities with optional stuff. Needs optimising.
+ */
+
+-static void gsm_dlci_data_sweep(struct gsm_mux *gsm)
++static int gsm_dlci_data_sweep(struct gsm_mux *gsm)
+ {
+- int len;
++ int len, ret = 0;
+ /* Priority ordering: We should do priority with RR of the groups */
+ int i = 1;
+
+@@ -1104,7 +1100,11 @@ static void gsm_dlci_data_sweep(struct gsm_mux *gsm)
+ /* DLCI empty - try the next */
+ if (len == 0)
+ i++;
++ else
++ ret++;
+ }
++
++ return ret;
+ }
+
+ /**
+@@ -1823,6 +1823,30 @@ static void gsm_dlci_command(struct gsm_dlci *dlci, const u8 *data, int len)
+ }
+ }
+
++/**
++ * gsm_kick_timer - transmit if possible
++ * @t: timer contained in our gsm object
++ *
++ * Transmit data from DLCIs if the queue is empty. We can't rely on
++ * a tty wakeup except when we filled the pipe so we need to fire off
++ * new data ourselves in other cases.
++ */
++static void gsm_kick_timer(struct timer_list *t)
++{
++ struct gsm_mux *gsm = from_timer(gsm, t, kick_timer);
++ unsigned long flags;
++ int sent = 0;
++
++ spin_lock_irqsave(&gsm->tx_lock, flags);
++ /* If we have nothing running then we need to fire up */
++ if (gsm->tx_bytes < TX_THRESH_LO)
++ sent = gsm_dlci_data_sweep(gsm);
++ spin_unlock_irqrestore(&gsm->tx_lock, flags);
++
++ if (sent && debug & 4)
++ pr_info("%s TX queue stalled\n", __func__);
++}
++
+ /*
+ * Allocate/Free DLCI channels
+ */
+@@ -2278,6 +2302,7 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
+ }
+
+ /* Finish outstanding timers, making sure they are done */
++ del_timer_sync(&gsm->kick_timer);
+ del_timer_sync(&gsm->t2_timer);
+
+ /* Free up any link layer users and finally the control channel */
+@@ -2310,6 +2335,7 @@ static int gsm_activate_mux(struct gsm_mux *gsm)
+ struct gsm_dlci *dlci;
+ int ret;
+
++ timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+ timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
+ init_waitqueue_head(&gsm->event);
+ spin_lock_init(&gsm->control_lock);
+@@ -2714,6 +2740,7 @@ static int gsmld_open(struct tty_struct *tty)
+
+ gsmld_attach_gsm(tty, gsm);
+
++ timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+ timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
+
+ return 0;
+--
+2.35.1
+
--- /dev/null
+From 5015e2f1f8fecba747c7bef129bd731cfa3fb726 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:16:48 +0200
+Subject: tty: n_gsm: fix non flow control frames during mux flow off
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit bec0224816d19abe4fe503586d16d51890540615 ]
+
+n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010.
+See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516
+The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to
+the newer 27.010 here. Chapter 5.4.6.3.6 states that FCoff stops the
+transmission on all channels except the control channel. This is already
+implemented in gsm_data_kick(). However, chapter 5.4.8.1 explains that this
+shall result in the same behavior as software flow control on the ldisc in
+advanced option mode. That means only flow control frames shall be sent
+during flow off. The current implementation does not consider this case.
+
+Change gsm_data_kick() to send only flow control frames if constipated to
+abide the standard. gsm_read_ea_val() and gsm_is_flow_ctrl_msg() are
+introduced as helper functions for this.
+It is planned to use gsm_read_ea_val() in later code cleanups for other
+functions, too.
+
+Fixes: c01af4fec2c8 ("n_gsm : Flow control handling in Mux driver")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701061652.39604-5-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 54 ++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 53 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 27e72c623afb..83ec596bba93 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -421,6 +421,27 @@ static int gsm_read_ea(unsigned int *val, u8 c)
+ return c & EA;
+ }
+
++/**
++ * gsm_read_ea_val - read a value until EA
++ * @val: variable holding value
++ * @data: buffer of data
++ * @dlen: length of data
++ *
++ * Processes an EA value. Updates the passed variable and
++ * returns the processed data length.
++ */
++static unsigned int gsm_read_ea_val(unsigned int *val, const u8 *data, int dlen)
++{
++ unsigned int len = 0;
++
++ for (; dlen > 0; dlen--) {
++ len++;
++ if (gsm_read_ea(val, *data++))
++ break;
++ }
++ return len;
++}
++
+ /**
+ * gsm_encode_modem - encode modem data bits
+ * @dlci: DLCI to encode from
+@@ -746,6 +767,37 @@ static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len,
+ return m;
+ }
+
++/**
++ * gsm_is_flow_ctrl_msg - checks if flow control message
++ * @msg: message to check
++ *
++ * Returns true if the given message is a flow control command of the
++ * control channel. False is returned in any other case.
++ */
++static bool gsm_is_flow_ctrl_msg(struct gsm_msg *msg)
++{
++ unsigned int cmd;
++
++ if (msg->addr > 0)
++ return false;
++
++ switch (msg->ctrl & ~PF) {
++ case UI:
++ case UIH:
++ cmd = 0;
++ if (gsm_read_ea_val(&cmd, msg->data + 2, msg->len - 2) < 1)
++ break;
++ switch (cmd & ~PF) {
++ case CMD_FCOFF:
++ case CMD_FCON:
++ return true;
++ }
++ break;
++ }
++
++ return false;
++}
++
+ /**
+ * gsm_data_kick - poke the queue
+ * @gsm: GSM Mux
+@@ -765,7 +817,7 @@ static void gsm_data_kick(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+ int len;
+
+ list_for_each_entry_safe(msg, nmsg, &gsm->tx_list, list) {
+- if (gsm->constipated && msg->addr)
++ if (gsm->constipated && !gsm_is_flow_ctrl_msg(msg))
+ continue;
+ if (gsm->encoding != 0) {
+ gsm->txframe[0] = GSM1_SOF;
+--
+2.35.1
+
--- /dev/null
+From 0a6a0ed1d0ce49ae199b8a8b91d5ebd900a0f392 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:16:50 +0200
+Subject: tty: n_gsm: fix packet re-transmission without open control channel
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 4fae831b3a71fc5a44cc5c7d0b8c1267ee7659f5 ]
+
+In the current implementation control packets are re-transmitted even if
+the control channel closed down during T2. This is wrong.
+Check whether the control channel is open before re-transmitting any
+packets. Note that control channel open/close is handled by T1 and not T2
+and remains unaffected by this.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701061652.39604-7-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 83ec596bba93..e95004217292 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -1532,7 +1532,7 @@ static void gsm_control_retransmit(struct timer_list *t)
+ spin_lock_irqsave(&gsm->control_lock, flags);
+ ctrl = gsm->pending_cmd;
+ if (ctrl) {
+- if (gsm->cretries == 0) {
++ if (gsm->cretries == 0 || !gsm->dlci[0] || gsm->dlci[0]->dead) {
+ gsm->pending_cmd = NULL;
+ ctrl->error = -ETIMEDOUT;
+ ctrl->done = 1;
+--
+2.35.1
+
--- /dev/null
+From 1088ebed03e1fcb52d50f1870ac63827f6abf681 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:16:52 +0200
+Subject: tty: n_gsm: fix race condition in gsmld_write()
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 32dd59f96924f45e33bc79854f7a00679c0fa28e ]
+
+The function may be used by the user directly and also by the n_gsm
+internal functions. They can lead into a race condition which results in
+interleaved frames if both are writing at the same time. The receiving side
+is not able to decode those interleaved frames correctly.
+
+Add a lock around the low side tty write to avoid race conditions and frame
+interleaving between user originated writes and n_gsm writes.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701061652.39604-9-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index e95004217292..e02f761a3a31 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -2863,11 +2863,24 @@ static ssize_t gsmld_read(struct tty_struct *tty, struct file *file,
+ static ssize_t gsmld_write(struct tty_struct *tty, struct file *file,
+ const unsigned char *buf, size_t nr)
+ {
+- int space = tty_write_room(tty);
++ struct gsm_mux *gsm = tty->disc_data;
++ unsigned long flags;
++ int space;
++ int ret;
++
++ if (!gsm)
++ return -ENODEV;
++
++ ret = -ENOBUFS;
++ spin_lock_irqsave(&gsm->tx_lock, flags);
++ space = tty_write_room(tty);
+ if (space >= nr)
+- return tty->ops->write(tty, buf, nr);
+- set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+- return -ENOBUFS;
++ ret = tty->ops->write(tty, buf, nr);
++ else
++ set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
++ spin_unlock_irqrestore(&gsm->tx_lock, flags);
++
++ return ret;
+ }
+
+ /**
+--
+2.35.1
+
--- /dev/null
+From 83a8d3bf624e92e0c2825cfd0fa5828785f3cb91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 14:23:32 +0200
+Subject: tty: n_gsm: fix resource allocation order in gsm_activate_mux()
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 7349660438603ed19282e75949561406531785a5 ]
+
+Within gsm_activate_mux() all timers and locks are initiated before the
+actual resource for the control channel is allocated. This can lead to race
+conditions.
+
+Allocate the control channel DLCI object first to avoid race conditions.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701122332.2039-2-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index ab7765afab86..17927163790e 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -2501,6 +2501,10 @@ static int gsm_activate_mux(struct gsm_mux *gsm)
+ struct gsm_dlci *dlci;
+ int ret;
+
++ dlci = gsm_dlci_alloc(gsm, 0);
++ if (dlci == NULL)
++ return -ENOMEM;
++
+ timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+ timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
+ INIT_WORK(&gsm->tx_work, gsmld_write_task);
+@@ -2517,9 +2521,6 @@ static int gsm_activate_mux(struct gsm_mux *gsm)
+ if (ret)
+ return ret;
+
+- dlci = gsm_dlci_alloc(gsm, 0);
+- if (dlci == NULL)
+- return -ENOMEM;
+ gsm->has_devices = true;
+ gsm->dead = false; /* Tty opens are now permissible */
+ return 0;
+--
+2.35.1
+
--- /dev/null
+From 58ea80ac4cb073adf0a4665201479b50743e0d7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:16:45 +0200
+Subject: tty: n_gsm: fix tty registration before control channel open
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 01aecd917114577c423f07cec0d186ad007d76fc ]
+
+The current implementation registers/deregisters the user ttys at mux
+attach/detach. That means that the user devices are available before any
+control channel is open. However, user channel initialization requires an
+open control channel. Furthermore, the user is not informed if the mux
+restarts due to configuration changes.
+Put the registration/deregistration procedure into separate function to
+improve readability.
+Move registration to mux activation and deregistration to mux cleanup to
+keep the user devices only open as long as a control channel exists. The
+user will be informed via the device driver if the mux was reconfigured in
+a way that required a mux re-activation.
+This makes it necessary to add T2 initialization to gsmld_open() for the
+ldisc open code path (not the reconfiguration code path) to avoid deletion
+of an uninitialized T2 at mux cleanup.
+
+Fixes: d50f6dcaf22a ("tty: n_gsm: expose gsmtty device nodes at ldisc open time")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701061652.39604-2-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 117 ++++++++++++++++++++++++++++++--------------
+ 1 file changed, 79 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index e15b3b107b5e..e80713a9d204 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -235,6 +235,7 @@ struct gsm_mux {
+ struct gsm_dlci *dlci[NUM_DLCI];
+ int old_c_iflag; /* termios c_iflag value before attach */
+ bool constipated; /* Asked by remote to shut up */
++ bool has_devices; /* Devices were registered */
+
+ spinlock_t tx_lock;
+ unsigned int tx_bytes; /* TX data outstanding */
+@@ -463,6 +464,68 @@ static void gsm_hex_dump_bytes(const char *fname, const u8 *data,
+ kfree(prefix);
+ }
+
++/**
++ * gsm_register_devices - register all tty devices for a given mux index
++ *
++ * @driver: the tty driver that describes the tty devices
++ * @index: the mux number is used to calculate the minor numbers of the
++ * ttys for this mux and may differ from the position in the
++ * mux array.
++ */
++static int gsm_register_devices(struct tty_driver *driver, unsigned int index)
++{
++ struct device *dev;
++ int i;
++ unsigned int base;
++
++ if (!driver || index >= MAX_MUX)
++ return -EINVAL;
++
++ base = index * NUM_DLCI; /* first minor for this index */
++ for (i = 1; i < NUM_DLCI; i++) {
++ /* Don't register device 0 - this is the control channel
++ * and not a usable tty interface
++ */
++ dev = tty_register_device(gsm_tty_driver, base + i, NULL);
++ if (IS_ERR(dev)) {
++ if (debug & 8)
++ pr_info("%s failed to register device minor %u",
++ __func__, base + i);
++ for (i--; i >= 1; i--)
++ tty_unregister_device(gsm_tty_driver, base + i);
++ return PTR_ERR(dev);
++ }
++ }
++
++ return 0;
++}
++
++/**
++ * gsm_unregister_devices - unregister all tty devices for a given mux index
++ *
++ * @driver: the tty driver that describes the tty devices
++ * @index: the mux number is used to calculate the minor numbers of the
++ * ttys for this mux and may differ from the position in the
++ * mux array.
++ */
++static void gsm_unregister_devices(struct tty_driver *driver,
++ unsigned int index)
++{
++ int i;
++ unsigned int base;
++
++ if (!driver || index >= MAX_MUX)
++ return;
++
++ base = index * NUM_DLCI; /* first minor for this index */
++ for (i = 1; i < NUM_DLCI; i++) {
++ /* Don't unregister device 0 - this is the control
++ * channel and not a usable tty interface
++ */
++ tty_unregister_device(gsm_tty_driver, base + i);
++ }
++}
++
+ /**
+ * gsm_print_packet - display a frame for debug
+ * @hdr: header to print before decode
+@@ -2208,6 +2271,10 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
+ del_timer_sync(&gsm->t2_timer);
+
+ /* Free up any link layer users and finally the control channel */
++ if (gsm->has_devices) {
++ gsm_unregister_devices(gsm_tty_driver, gsm->num);
++ gsm->has_devices = false;
++ }
+ for (i = NUM_DLCI - 1; i >= 0; i--)
+ if (gsm->dlci[i])
+ gsm_dlci_release(gsm->dlci[i]);
+@@ -2231,6 +2298,7 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
+ static int gsm_activate_mux(struct gsm_mux *gsm)
+ {
+ struct gsm_dlci *dlci;
++ int ret;
+
+ timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
+ init_waitqueue_head(&gsm->event);
+@@ -2242,9 +2310,14 @@ static int gsm_activate_mux(struct gsm_mux *gsm)
+ else
+ gsm->receive = gsm1_receive;
+
++ ret = gsm_register_devices(gsm_tty_driver, gsm->num);
++ if (ret)
++ return ret;
++
+ dlci = gsm_dlci_alloc(gsm, 0);
+ if (dlci == NULL)
+ return -ENOMEM;
++ gsm->has_devices = true;
+ gsm->dead = false; /* Tty opens are now permissible */
+ return 0;
+ }
+@@ -2504,39 +2577,14 @@ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len)
+ * will need moving to an ioctl path.
+ */
+
+-static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
++static void gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
+ {
+- unsigned int base;
+- int ret, i;
+-
+ gsm->tty = tty_kref_get(tty);
+ /* Turn off tty XON/XOFF handling to handle it explicitly. */
+ gsm->old_c_iflag = tty->termios.c_iflag;
+ tty->termios.c_iflag &= (IXON | IXOFF);
+- ret = gsm_activate_mux(gsm);
+- if (ret != 0)
+- tty_kref_put(gsm->tty);
+- else {
+- /* Don't register device 0 - this is the control channel and not
+- a usable tty interface */
+- base = mux_num_to_base(gsm); /* Base for this MUX */
+- for (i = 1; i < NUM_DLCI; i++) {
+- struct device *dev;
+-
+- dev = tty_register_device(gsm_tty_driver,
+- base + i, NULL);
+- if (IS_ERR(dev)) {
+- for (i--; i >= 1; i--)
+- tty_unregister_device(gsm_tty_driver,
+- base + i);
+- return PTR_ERR(dev);
+- }
+- }
+- }
+- return ret;
+ }
+
+-
+ /**
+ * gsmld_detach_gsm - stop doing 0710 mux
+ * @tty: tty attached to the mux
+@@ -2547,12 +2595,7 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
+
+ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
+ {
+- unsigned int base = mux_num_to_base(gsm); /* Base for this MUX */
+- int i;
+-
+ WARN_ON(tty != gsm->tty);
+- for (i = 1; i < NUM_DLCI; i++)
+- tty_unregister_device(gsm_tty_driver, base + i);
+ /* Restore tty XON/XOFF handling. */
+ gsm->tty->termios.c_iflag = gsm->old_c_iflag;
+ tty_kref_put(gsm->tty);
+@@ -2644,7 +2687,6 @@ static void gsmld_close(struct tty_struct *tty)
+ static int gsmld_open(struct tty_struct *tty)
+ {
+ struct gsm_mux *gsm;
+- int ret;
+
+ if (tty->ops->write == NULL)
+ return -EINVAL;
+@@ -2660,12 +2702,11 @@ static int gsmld_open(struct tty_struct *tty)
+ /* Attach the initial passive connection */
+ gsm->encoding = 1;
+
+- ret = gsmld_attach_gsm(tty, gsm);
+- if (ret != 0) {
+- gsm_cleanup_mux(gsm, false);
+- mux_put(gsm);
+- }
+- return ret;
++ gsmld_attach_gsm(tty, gsm);
++
++ timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
++
++ return 0;
+ }
+
+ /**
+--
+2.35.1
+
--- /dev/null
+From c057ed688e653121f570cc4013a6a2675014898f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:16:44 +0200
+Subject: tty: n_gsm: fix user open not possible at responder until initiator
+ open
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit ac77f0077c3265197d378158c85a55eee6d21508 ]
+
+After setting up the control channel on both sides the responder side may
+want to open a virtual tty to listen on until the initiator starts an
+application on a user channel. The current implementation allows the
+open() but no other operation, like termios. These fail with EINVAL.
+The responder sided application has no means to detect an open by the
+initiator sided application this way. And the initiator sided applications
+usually expect the responder sided application to listen on the user
+channel upon open.
+Set the user channel into half-open state on responder side once a user
+application opens the virtual tty to allow IO operations on it.
+Furthermore, keep the user channel constipated until the initiator side
+opens it to give the responder sided application the chance to detect the
+new connection and to avoid data loss if the responder sided application
+starts sending before the user channel is open.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701061652.39604-1-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 31 +++++++++++++++++++++++++++++--
+ 1 file changed, 29 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 9f2a8c0e1e33..e15b3b107b5e 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -1510,6 +1510,8 @@ static void gsm_dlci_close(struct gsm_dlci *dlci)
+ if (debug & 8)
+ pr_debug("DLCI %d goes closed.\n", dlci->addr);
+ dlci->state = DLCI_CLOSED;
++ /* Prevent us from sending data before the link is up again */
++ dlci->constipated = true;
+ if (dlci->addr != 0) {
+ tty_port_tty_hangup(&dlci->port, false);
+ spin_lock_irqsave(&dlci->lock, flags);
+@@ -1539,6 +1541,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
+ del_timer(&dlci->t1);
+ /* This will let a tty open continue */
+ dlci->state = DLCI_OPEN;
++ dlci->constipated = false;
+ if (debug & 8)
+ pr_debug("DLCI %d goes open.\n", dlci->addr);
+ /* Send current modem state */
+@@ -1619,6 +1622,25 @@ static void gsm_dlci_begin_open(struct gsm_dlci *dlci)
+ mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
+ }
+
++/**
++ * gsm_dlci_set_opening - change state to opening
++ * @dlci: DLCI to open
++ *
++ * Change internal state to wait for DLCI open from initiator side.
++ * We set off timers and responses upon reception of an SABM.
++ */
++static void gsm_dlci_set_opening(struct gsm_dlci *dlci)
++{
++ switch (dlci->state) {
++ case DLCI_CLOSED:
++ case DLCI_CLOSING:
++ dlci->state = DLCI_OPENING;
++ break;
++ default:
++ break;
++ }
++}
++
+ /**
+ * gsm_dlci_begin_close - start channel open procedure
+ * @dlci: DLCI to open
+@@ -1762,10 +1784,13 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr)
+ dlci->addr = addr;
+ dlci->adaption = gsm->adaption;
+ dlci->state = DLCI_CLOSED;
+- if (addr)
++ if (addr) {
+ dlci->data = gsm_dlci_data;
+- else
++ /* Prevent us from sending data before the link is up */
++ dlci->constipated = true;
++ } else {
+ dlci->data = gsm_dlci_command;
++ }
+ gsm->dlci[addr] = dlci;
+ return dlci;
+ }
+@@ -3178,6 +3203,8 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
+ /* Start sending off SABM messages */
+ if (gsm->initiator)
+ gsm_dlci_begin_open(dlci);
++ else
++ gsm_dlci_set_opening(dlci);
+ /* And wait for virtual carrier */
+ return tty_port_block_til_ready(port, tty, filp);
+ }
+--
+2.35.1
+
--- /dev/null
+From 006c78cc9892aa8f10c2d532fa3f56c7db989905 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 08:16:46 +0200
+Subject: tty: n_gsm: fix wrong queuing behavior in gsm_dlci_data_output()
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 556fc8ac06513cced381588d6d58c184d95cc4fe ]
+
+1) The function drains the fifo for the given user tty/DLCI without
+considering 'TX_THRESH_HI' and different to gsm_dlci_data_output_framed(),
+which moves only one packet from the user side to the internal transmission
+queue. We can only handle one packet at a time here if we want to allow
+DLCI priority handling in gsm_dlci_data_sweep() to avoid link starvation.
+2) Furthermore, the additional header octet from convergence layer type 2
+is not counted against MTU. It is part of the UI/UIH frame message which
+needs to be limited to MTU. Hence, it is wrong not to consider this octet.
+3) Finally, the waiting user tty is not informed about freed space in its
+send queue.
+
+Take at most one packet worth of data out of the DLCI fifo to fix 1).
+Limit the max user data size per packet to MTU - 1 in case of convergence
+layer type 2 to leave space for the control signal octet which is added in
+the later part of the function. This fixes 2).
+Add tty_port_tty_wakeup() to wake up the user tty if new write space has
+been made available to fix 3).
+
+Fixes: 268e526b935e ("tty/n_gsm: avoid fifo overflow in gsm_dlci_data_output")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701061652.39604-3-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 74 +++++++++++++++++++++++++--------------------
+ 1 file changed, 42 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index e80713a9d204..658d8f6e3a7d 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -886,41 +886,51 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+ {
+ struct gsm_msg *msg;
+ u8 *dp;
+- int len, total_size, size;
+- int h = dlci->adaption - 1;
++ int h, len, size;
+
+- total_size = 0;
+- while (1) {
+- len = kfifo_len(&dlci->fifo);
+- if (len == 0)
+- return total_size;
+-
+- /* MTU/MRU count only the data bits */
+- if (len > gsm->mtu)
+- len = gsm->mtu;
+-
+- size = len + h;
+-
+- msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
+- /* FIXME: need a timer or something to kick this so it can't
+- get stuck with no work outstanding and no buffer free */
+- if (msg == NULL)
+- return -ENOMEM;
+- dp = msg->data;
+- switch (dlci->adaption) {
+- case 1: /* Unstructured */
+- break;
+- case 2: /* Unstructed with modem bits.
+- Always one byte as we never send inline break data */
+- *dp++ = (gsm_encode_modem(dlci) << 1) | EA;
+- break;
+- }
+- WARN_ON(kfifo_out_locked(&dlci->fifo, dp , len, &dlci->lock) != len);
+- __gsm_data_queue(dlci, msg);
+- total_size += size;
++ /* for modem bits without break data */
++ h = ((dlci->adaption == 1) ? 0 : 1);
++
++ len = kfifo_len(&dlci->fifo);
++ if (len == 0)
++ return 0;
++
++ /* MTU/MRU count only the data bits but watch adaption mode */
++ if ((len + h) > gsm->mtu)
++ len = gsm->mtu - h;
++
++ size = len + h;
++
++ msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
++ /* FIXME: need a timer or something to kick this so it can't
++ * get stuck with no work outstanding and no buffer free
++ */
++ if (!msg)
++ return -ENOMEM;
++ dp = msg->data;
++ switch (dlci->adaption) {
++ case 1: /* Unstructured */
++ break;
++ case 2: /* Unstructured with modem bits.
++ * Always one byte as we never send inline break data
++ */
++ *dp++ = (gsm_encode_modem(dlci) << 1) | EA;
++ break;
++ default:
++ pr_err("%s: unsupported adaption %d\n", __func__,
++ dlci->adaption);
++ break;
+ }
++
++ WARN_ON(len != kfifo_out_locked(&dlci->fifo, dp, len,
++ &dlci->lock));
++
++ /* Notify upper layer about available send space. */
++ tty_port_tty_wakeup(&dlci->port);
++
++ __gsm_data_queue(dlci, msg);
+ /* Bytes of data we used up */
+- return total_size;
++ return size;
+ }
+
+ /**
+--
+2.35.1
+
--- /dev/null
+From 9f2177d011f1b31152535358dcb51ff50c61b289 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 13:32:20 +0200
+Subject: tty: n_gsm: fix wrong T1 retry count handling
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit f30e10caa80aa1f35508bc17fc302dbbde9a833c ]
+
+n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010.
+See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516
+The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to
+the newer 27.010 here. Chapter 5.7.3 states that the valid range for the
+maximum number of retransmissions (N2) is from 0 to 255 (both including).
+gsm_dlci_t1() handles this number incorrectly by performing N2 - 1
+retransmission attempts. Setting N2 to zero results in more than 255
+retransmission attempts.
+Fix gsm_dlci_t1() to comply with 3GPP 27.010.
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220707113223.3685-1-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/n_gsm.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 17927163790e..825c4b550ee0 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -1805,8 +1805,8 @@ static void gsm_dlci_t1(struct timer_list *t)
+
+ switch (dlci->state) {
+ case DLCI_OPENING:
+- dlci->retries--;
+ if (dlci->retries) {
++ dlci->retries--;
+ gsm_command(dlci->gsm, dlci->addr, SABM|PF);
+ mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
+ } else if (!dlci->addr && gsm->control == (DM | PF)) {
+@@ -1821,8 +1821,8 @@ static void gsm_dlci_t1(struct timer_list *t)
+
+ break;
+ case DLCI_CLOSING:
+- dlci->retries--;
+ if (dlci->retries) {
++ dlci->retries--;
+ gsm_command(dlci->gsm, dlci->addr, DISC|PF);
+ mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100);
+ } else
+--
+2.35.1
+
--- /dev/null
+From 248fed1840ec8a1d064e0a9bec36692ecda9c8bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 13:01:15 +0800
+Subject: tty: serial: fsl_lpuart: correct the count of break characters
+
+From: Sherry Sun <sherry.sun@nxp.com>
+
+[ Upstream commit 707f816f25590c20e056b3bd4a17ce69b03fe856 ]
+
+The LPUART can't distinguish between a break signal and a framing error,
+so need to count the break characters if there is a framing error and
+received data is zero instead of the parity error.
+
+Fixes: 5541a9bacfe5 ("serial: fsl_lpuart: handle break and make sysrq work")
+Reviewed-by: Michael Walle <michael@walle.cc>
+Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
+Link: https://lore.kernel.org/r/20220725050115.12396-1-sherry.sun@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/fsl_lpuart.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index 2cb89491dd09..65b76adf107c 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -990,12 +990,12 @@ static void lpuart32_rxint(struct lpuart_port *sport)
+
+ if (sr & (UARTSTAT_PE | UARTSTAT_OR | UARTSTAT_FE)) {
+ if (sr & UARTSTAT_PE) {
++ sport->port.icount.parity++;
++ } else if (sr & UARTSTAT_FE) {
+ if (is_break)
+ sport->port.icount.brk++;
+ else
+- sport->port.icount.parity++;
+- } else if (sr & UARTSTAT_FE) {
+- sport->port.icount.frame++;
++ sport->port.icount.frame++;
+ }
+
+ if (sr & UARTSTAT_OR)
+@@ -1010,12 +1010,12 @@ static void lpuart32_rxint(struct lpuart_port *sport)
+ sr &= sport->port.read_status_mask;
+
+ if (sr & UARTSTAT_PE) {
++ flg = TTY_PARITY;
++ } else if (sr & UARTSTAT_FE) {
+ if (is_break)
+ flg = TTY_BREAK;
+ else
+- flg = TTY_PARITY;
+- } else if (sr & UARTSTAT_FE) {
+- flg = TTY_FRAME;
++ flg = TTY_FRAME;
+ }
+
+ if (sr & UARTSTAT_OR)
+--
+2.35.1
+
--- /dev/null
+From 405f0a8d4d28cf4efa2d9727e465429ef43507b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jun 2022 09:58:42 +0100
+Subject: um: random: Don't initialise hwrng struct with zero
+
+From: Christopher Obbard <chris.obbard@collabora.com>
+
+[ Upstream commit 9e70cbd11b03889c92462cf52edb2bd023c798fa ]
+
+Initialising the hwrng struct with zeros causes a
+compile-time sparse warning:
+
+ $ ARCH=um make -j10 W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
+ ...
+ CHECK arch/um/drivers/random.c
+ arch/um/drivers/random.c:31:31: sparse: warning: Using plain integer as NULL pointer
+
+Fix the warning by not initialising the hwrng struct
+with zeros as it is initialised anyway during module
+init.
+
+Fixes: 72d3e093afae ("um: random: Register random as hwrng-core device")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Christopher Obbard <chris.obbard@collabora.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/drivers/random.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
+index 433a3f8f2ef3..32b3341fe970 100644
+--- a/arch/um/drivers/random.c
++++ b/arch/um/drivers/random.c
+@@ -28,7 +28,7 @@
+ * protects against a module being loaded twice at the same time.
+ */
+ static int random_fd = -1;
+-static struct hwrng hwrng = { 0, };
++static struct hwrng hwrng;
+ static DECLARE_COMPLETION(have_data);
+
+ static int rng_dev_read(struct hwrng *rng, void *buf, size_t max, bool block)
+--
+2.35.1
+
--- /dev/null
+From 35daaf8bed1f3b7988160a05e241ae726d2da34a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 20:05:28 +0800
+Subject: usb: aspeed-vhub: Fix refcount leak bug in ast_vhub_init_desc()
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 220fafb4ed04187e9c17be4152da5a7f2ffbdd8c ]
+
+We should call of_node_put() for the reference returned by
+of_get_child_by_name() which has increased the refcount.
+
+Fixes: 30d2617fd7ed ("usb: gadget: aspeed: allow to set usb strings in device tree")
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220713120528.368168-1-windhl@126.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/aspeed-vhub/hub.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/aspeed-vhub/hub.c b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
+index 65cd4e46f031..e2207d014620 100644
+--- a/drivers/usb/gadget/udc/aspeed-vhub/hub.c
++++ b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
+@@ -1059,8 +1059,10 @@ static int ast_vhub_init_desc(struct ast_vhub *vhub)
+ /* Initialize vhub String Descriptors. */
+ INIT_LIST_HEAD(&vhub->vhub_str_desc);
+ desc_np = of_get_child_by_name(vhub_np, "vhub-strings");
+- if (desc_np)
++ if (desc_np) {
+ ret = ast_vhub_of_parse_str_desc(vhub, desc_np);
++ of_node_put(desc_np);
++ }
+ else
+ ret = ast_vhub_str_alloc_add(vhub, &ast_vhub_strings);
+
+--
+2.35.1
+
--- /dev/null
+From df67a921b7a5d25c47cd62744018f63de819af68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 19:00:52 +0300
+Subject: usb: cdns3: change place of 'priv_ep' assignment in
+ cdns3_gadget_ep_dequeue(), cdns3_gadget_ep_enable()
+
+From: Andrey Strachuk <strochuk@ispras.ru>
+
+[ Upstream commit c3ffc9c4ca44bfe9562166793d133e1fb0630ea6 ]
+
+If 'ep' is NULL, result of ep_to_cdns3_ep(ep) is invalid pointer
+and its dereference with priv_ep->cdns3_dev may cause panic.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Signed-off-by: Andrey Strachuk <strochuk@ispras.ru>
+Link: https://lore.kernel.org/r/20220718160052.4188-1-strochuk@ispras.ru
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/cdns3/cdns3-gadget.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c
+index d6d515d598dc..e0cf62e65075 100644
+--- a/drivers/usb/cdns3/cdns3-gadget.c
++++ b/drivers/usb/cdns3/cdns3-gadget.c
+@@ -2281,14 +2281,15 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep,
+ int val;
+
+ priv_ep = ep_to_cdns3_ep(ep);
+- priv_dev = priv_ep->cdns3_dev;
+- comp_desc = priv_ep->endpoint.comp_desc;
+
+ if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) {
+ dev_dbg(priv_dev->dev, "usbss: invalid parameters\n");
+ return -EINVAL;
+ }
+
++ comp_desc = priv_ep->endpoint.comp_desc;
++ priv_dev = priv_ep->cdns3_dev;
++
+ if (!desc->wMaxPacketSize) {
+ dev_err(priv_dev->dev, "usbss: missing wMaxPacketSize\n");
+ return -EINVAL;
+@@ -2596,7 +2597,7 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep,
+ struct usb_request *request)
+ {
+ struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep);
+- struct cdns3_device *priv_dev = priv_ep->cdns3_dev;
++ struct cdns3_device *priv_dev;
+ struct usb_request *req, *req_temp;
+ struct cdns3_request *priv_req;
+ struct cdns3_trb *link_trb;
+@@ -2607,6 +2608,8 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep,
+ if (!ep || !request || !ep->desc)
+ return -EINVAL;
+
++ priv_dev = priv_ep->cdns3_dev;
++
+ spin_lock_irqsave(&priv_dev->lock, flags);
+
+ priv_req = to_cdns3_request(request);
+--
+2.35.1
+
--- /dev/null
+From db775ba3da5c078651d0d6c0c52050afa9579e03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Aug 2022 09:24:22 -0700
+Subject: usb: cdns3: Don't use priv_dev uninitialized in
+ cdns3_gadget_ep_enable()
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit 78acd4ca433425e6dd4032cfc2156c60e34931f2 ]
+
+Clang warns:
+
+ drivers/usb/cdns3/cdns3-gadget.c:2290:11: error: variable 'priv_dev' is uninitialized when used here [-Werror,-Wuninitialized]
+ dev_dbg(priv_dev->dev, "usbss: invalid parameters\n");
+ ^~~~~~~~
+ include/linux/dev_printk.h:155:18: note: expanded from macro 'dev_dbg'
+ dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
+ ^~~
+ include/linux/dynamic_debug.h:167:7: note: expanded from macro 'dynamic_dev_dbg'
+ dev, fmt, ##__VA_ARGS__)
+ ^~~
+ include/linux/dynamic_debug.h:152:56: note: expanded from macro '_dynamic_func_call'
+ __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
+ ^~~~~~~~~~~
+ include/linux/dynamic_debug.h:134:15: note: expanded from macro '__dynamic_func_call'
+ func(&id, ##__VA_ARGS__); \
+ ^~~~~~~~~~~
+ drivers/usb/cdns3/cdns3-gadget.c:2278:31: note: initialize the variable 'priv_dev' to silence this warning
+ struct cdns3_device *priv_dev;
+ ^
+ = NULL
+ 1 error generated.
+
+The priv_dev assignment was moved below the if statement to avoid
+potentially dereferencing ep before it was checked but priv_dev is used
+in the dev_dbg() call.
+
+To fix this, move the priv_dev and comp_desc assignments back to their
+original spot and hoist the ep check above those assignments with a call
+to pr_debug() instead of dev_dbg().
+
+Fixes: c3ffc9c4ca44 ("usb: cdns3: change place of 'priv_ep' assignment in cdns3_gadget_ep_dequeue(), cdns3_gadget_ep_enable()")
+Link: https://github.com/ClangBuiltLinux/linux/issues/1680
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/cdns3/cdns3-gadget.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c
+index e0cf62e65075..ae049eb28b93 100644
+--- a/drivers/usb/cdns3/cdns3-gadget.c
++++ b/drivers/usb/cdns3/cdns3-gadget.c
+@@ -2280,16 +2280,20 @@ static int cdns3_gadget_ep_enable(struct usb_ep *ep,
+ int ret = 0;
+ int val;
+
++ if (!ep) {
++ pr_debug("usbss: ep not configured?\n");
++ return -EINVAL;
++ }
++
+ priv_ep = ep_to_cdns3_ep(ep);
++ priv_dev = priv_ep->cdns3_dev;
++ comp_desc = priv_ep->endpoint.comp_desc;
+
+- if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) {
++ if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT) {
+ dev_dbg(priv_dev->dev, "usbss: invalid parameters\n");
+ return -EINVAL;
+ }
+
+- comp_desc = priv_ep->endpoint.comp_desc;
+- priv_dev = priv_ep->cdns3_dev;
+-
+ if (!desc->wMaxPacketSize) {
+ dev_err(priv_dev->dev, "usbss: missing wMaxPacketSize\n");
+ return -EINVAL;
+--
+2.35.1
+
--- /dev/null
+From c46a893dbbbc9fb1afa0007ff4b8fff75def073d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Jun 2022 17:24:32 -0700
+Subject: usb: dwc3: core: Deprecate GCTL.CORESOFTRESET
+
+From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+
+[ Upstream commit afbd04e66e5d16ca3c7ea2e3c56eca25558eacf3 ]
+
+Synopsys IP DWC_usb32 and DWC_usb31 version 1.90a and above deprecated
+GCTL.CORESOFTRESET. The DRD mode switching flow is updated to remove the
+GCTL soft reset. Add version checks to prevent using deprecated setting
+in mode switching flow.
+
+Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/9df529fde6e55f5508321b6bc26e92848044ef2b.1655338967.git.Thinh.Nguyen@synopsys.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index d28cd1a6709b..46a3b8941e40 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -158,7 +158,8 @@ static void __dwc3_set_mode(struct work_struct *work)
+ }
+
+ /* For DRD host or device mode only */
+- if (dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) {
++ if ((DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
++ dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) {
+ reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg |= DWC3_GCTL_CORESOFTRESET;
+ dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+--
+2.35.1
+
--- /dev/null
+From 90b420884d9720a10647eecd0615a0ce32b94c6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 10:26:25 +0530
+Subject: usb: dwc3: core: Do not perform GCTL_CORE_SOFTRESET during bootup
+
+From: Rohith Kollalsi <quic_rkollals@quicinc.com>
+
+[ Upstream commit 07903626d98853e605fe63e5ce149f1b7314bbea ]
+
+According to the programming guide, it is recommended to
+perform a GCTL_CORE_SOFTRESET only when switching the mode
+from device to host or host to device. However, it is found
+that during bootup when __dwc3_set_mode() is called for the
+first time, GCTL_CORESOFTRESET is done with suspendable bit(BIT 17)
+of DWC3_GUSB3PIPECTL set. This some times leads to issues
+like controller going into bad state and controller registers
+reading value zero. Until GCTL_CORESOFTRESET is done and
+run/stop bit is set core initialization is not complete.
+Setting suspendable bit of DWC3_GUSB3PIPECTL and then
+performing GCTL_CORESOFTRESET is therefore not recommended.
+Avoid this by only performing the reset if current_dr_role is set,
+that is, when doing subsequent role switching.
+
+Fixes: f88359e1588b ("usb: dwc3: core: Do core softreset when switch mode")
+Signed-off-by: Rohith Kollalsi <quic_rkollals@quicinc.com>
+Link: https://lore.kernel.org/r/20220714045625.20377-1-quic_rkollals@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/core.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 46a3b8941e40..ecec9cdfa0a6 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -157,9 +157,13 @@ static void __dwc3_set_mode(struct work_struct *work)
+ break;
+ }
+
+- /* For DRD host or device mode only */
+- if ((DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
+- dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) {
++ /*
++ * When current_dr_role is not set, there's no role switching.
++ * Only perform GCTL.CoreSoftReset when there's DRD role switching.
++ */
++ if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
++ DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
++ dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
+ reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ reg |= DWC3_GCTL_CORESOFTRESET;
+ dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+--
+2.35.1
+
--- /dev/null
+From ae4298198d3d0e00d8860985eb38a712cd430400 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Jul 2022 15:13:36 +0200
+Subject: usb: dwc3: qcom: fix missing optional irq warnings
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit 69bb3520db7cecbccc9e497fc568fa5465c9d43f ]
+
+Not all platforms have all of the four currently supported wakeup
+interrupts so use the optional irq helpers when looking up interrupts to
+avoid printing error messages when an optional interrupt is not found:
+
+ dwc3-qcom a6f8800.usb: error -ENXIO: IRQ hs_phy_irq not found
+
+Fixes: a4333c3a6ba9 ("usb: dwc3: Add Qualcomm DWC3 glue driver")
+Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Link: https://lore.kernel.org/r/20220713131340.29401-4-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 | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
+index 6cba990da32e..3582fd6dfa14 100644
+--- a/drivers/usb/dwc3/dwc3-qcom.c
++++ b/drivers/usb/dwc3/dwc3-qcom.c
+@@ -443,9 +443,9 @@ static int dwc3_qcom_get_irq(struct platform_device *pdev,
+ int ret;
+
+ if (np)
+- ret = platform_get_irq_byname(pdev_irq, name);
++ ret = platform_get_irq_byname_optional(pdev_irq, name);
+ else
+- ret = platform_get_irq(pdev_irq, num);
++ ret = platform_get_irq_optional(pdev_irq, num);
+
+ return ret;
+ }
+--
+2.35.1
+
--- /dev/null
+From c1fc6fe203731e9d9f8461fd88ac8760a659ae60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jun 2022 10:14:36 +0800
+Subject: usb: gadget: f_mass_storage: Make CD-ROM emulation works with Windows
+ OS
+
+From: Neal Liu <neal_liu@aspeedtech.com>
+
+[ Upstream commit 3b91edd624ab1ab694deef513a45eb9e9d49d75f ]
+
+Add read TOC with format 1 to support CD-ROM emulation with
+Windows OS.
+This patch is tested on Windows OS Server 2019.
+
+Fixes: 89ada0fe669a ("usb: gadget: f_mass_storage: Make CD-ROM emulation work with Mac OS-X")
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Neal Liu <neal_liu@aspeedtech.com>
+Link: https://lore.kernel.org/r/20220628021436.3252262-1-neal_liu@aspeedtech.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_mass_storage.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
+index 3a77bca0ebe1..e884f295504f 100644
+--- a/drivers/usb/gadget/function/f_mass_storage.c
++++ b/drivers/usb/gadget/function/f_mass_storage.c
+@@ -1192,13 +1192,14 @@ static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh)
+ u8 format;
+ int i, len;
+
++ format = common->cmnd[2] & 0xf;
++
+ if ((common->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */
+- start_track > 1) {
++ (start_track > 1 && format != 0x1)) {
+ curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+ return -EINVAL;
+ }
+
+- format = common->cmnd[2] & 0xf;
+ /*
+ * Check if CDB is old style SFF-8020i
+ * i.e. format is in 2 MSBs of byte 9
+@@ -1208,8 +1209,8 @@ static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh)
+ format = (common->cmnd[9] >> 6) & 0x3;
+
+ switch (format) {
+- case 0:
+- /* Formatted TOC */
++ case 0: /* Formatted TOC */
++ case 1: /* Multi-session info */
+ len = 4 + 2*8; /* 4 byte header + 2 descriptors */
+ memset(buf, 0, len);
+ buf[1] = len - 2; /* TOC Length excludes length field */
+@@ -1250,7 +1251,7 @@ static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh)
+ return len;
+
+ default:
+- /* Multi-session, PMA, ATIP, CD-TEXT not supported/required */
++ /* PMA, ATIP, CD-TEXT not supported/required */
+ curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
+ return -EINVAL;
+ }
+--
+2.35.1
+
--- /dev/null
+From f335154f4351dfca8d865d3c3d9208c4651008fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 May 2022 21:53:32 +0800
+Subject: usb: gadget: tegra-xudc: Fix error check in
+ tegra_xudc_powerdomain_init()
+
+From: Tang Bin <tangbin@cmss.chinamobile.com>
+
+[ Upstream commit f08aa7c80dac27ee00fa6827f447597d2fba5465 ]
+
+dev_pm_domain_attach_by_name() may return NULL in some cases,
+so IS_ERR() doesn't meet the requirements. Thus fix it.
+
+Fixes: 49db427232fe ("usb: gadget: Add UDC driver for tegra XUSB device mode controller")
+Signed-off-by: Tang Bin <tangbin@cmss.chinamobile.com>
+Link: https://lore.kernel.org/r/20220525135332.23144-1-tangbin@cmss.chinamobile.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/tegra-xudc.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
+index d9c406bdb680..c25765628625 100644
+--- a/drivers/usb/gadget/udc/tegra-xudc.c
++++ b/drivers/usb/gadget/udc/tegra-xudc.c
+@@ -3691,15 +3691,15 @@ static int tegra_xudc_powerdomain_init(struct tegra_xudc *xudc)
+ int err;
+
+ xudc->genpd_dev_device = dev_pm_domain_attach_by_name(dev, "dev");
+- if (IS_ERR(xudc->genpd_dev_device)) {
+- err = PTR_ERR(xudc->genpd_dev_device);
++ if (IS_ERR_OR_NULL(xudc->genpd_dev_device)) {
++ err = PTR_ERR(xudc->genpd_dev_device) ? : -ENODATA;
+ dev_err(dev, "failed to get device power domain: %d\n", err);
+ return err;
+ }
+
+ xudc->genpd_dev_ss = dev_pm_domain_attach_by_name(dev, "ss");
+- if (IS_ERR(xudc->genpd_dev_ss)) {
+- err = PTR_ERR(xudc->genpd_dev_ss);
++ if (IS_ERR_OR_NULL(xudc->genpd_dev_ss)) {
++ err = PTR_ERR(xudc->genpd_dev_ss) ? : -ENODATA;
+ dev_err(dev, "failed to get SuperSpeed power domain: %d\n", err);
+ return err;
+ }
+--
+2.35.1
+
--- /dev/null
+From b5e3511fec44ba28b93bea3e5c27150e1e473df0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Jul 2022 18:36:01 -0700
+Subject: usb: gadget: udc: amd5536 depends on HAS_DMA
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 8097cf2fb3b2205257f1c76f4808e3398d66b6d9 ]
+
+USB_AMD5536UDC should depend on HAS_DMA since it selects USB_SNP_CORE,
+which depends on HAS_DMA and since 'select' does not follow any
+dependency chains.
+
+Fixes this kconfig warning:
+
+WARNING: unmet direct dependencies detected for USB_SNP_CORE
+ Depends on [n]: USB_SUPPORT [=y] && USB_GADGET [=y] && (USB_AMD5536UDC [=y] || USB_SNP_UDC_PLAT [=n]) && HAS_DMA [=n]
+ Selected by [y]:
+ - USB_AMD5536UDC [=y] && USB_SUPPORT [=y] && USB_GADGET [=y] && USB_PCI [=y]
+
+Fixes: 97b3ffa233b9 ("usb: gadget: udc: amd5536: split core and PCI layer")
+Cc: Raviteja Garimella <raviteja.garimella@broadcom.com>
+Cc: Felipe Balbi <balbi@kernel.org>
+Cc: linux-usb@vger.kernel.org
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Link: https://lore.kernel.org/r/20220709013601.7536-1-rdunlap@infradead.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig
+index 69394dc1cdfb..2cdd37be165a 100644
+--- a/drivers/usb/gadget/udc/Kconfig
++++ b/drivers/usb/gadget/udc/Kconfig
+@@ -311,7 +311,7 @@ source "drivers/usb/gadget/udc/bdc/Kconfig"
+
+ config USB_AMD5536UDC
+ tristate "AMD5536 UDC"
+- depends on USB_PCI
++ depends on USB_PCI && HAS_DMA
+ select USB_SNP_CORE
+ help
+ The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge.
+--
+2.35.1
+
--- /dev/null
+From 526ad52f63f745bd75e4492e2265879d2775168b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jun 2022 15:08:49 +0400
+Subject: usb: host: Fix refcount leak in ehci_hcd_ppc_of_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit b5c5b13cb45e2c88181308186b0001992cb41954 ]
+
+of_find_compatible_node() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when done.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 796bcae7361c ("USB: powerpc: Workaround for the PPC440EPX USBH_23 errata [take 3]")
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220602110849.58549-1-linmq006@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/ehci-ppc-of.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c
+index 6bbaee74f7e7..28a19693c19f 100644
+--- a/drivers/usb/host/ehci-ppc-of.c
++++ b/drivers/usb/host/ehci-ppc-of.c
+@@ -148,6 +148,7 @@ static int ehci_hcd_ppc_of_probe(struct platform_device *op)
+ } else {
+ ehci->has_amcc_usb23 = 1;
+ }
++ of_node_put(np);
+ }
+
+ if (of_get_property(dn, "big-endian", NULL)) {
+--
+2.35.1
+
--- /dev/null
+From 74c04e4e14ea0cfc9d314e78e7e2a2f90f897b8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jun 2022 15:46:45 +0300
+Subject: usb: host: xhci: use snprintf() in xhci_decode_trb()
+
+From: Sergey Shtylyov <s.shtylyov@omp.ru>
+
+[ Upstream commit 1ce69c35b86038dd11d3a6115a04501c5b89a940 ]
+
+Commit cbf286e8ef83 ("xhci: fix unsafe memory usage in xhci tracing")
+apparently missed one sprintf() call in xhci_decode_trb() -- replace
+it with the snprintf() call as well...
+
+Found by Linux Verification Center (linuxtesting.org) with the SVACE static
+analysis tool.
+
+Fixes: cbf286e8ef83 ("xhci: fix unsafe memory usage in xhci tracing")
+Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20220630124645.1805902-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 1f3f311d9951..1d60e62752f3 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -2393,7 +2393,7 @@ static inline const char *xhci_decode_trb(char *str, size_t size,
+ field3 & TRB_CYCLE ? 'C' : 'c');
+ break;
+ case TRB_STOP_RING:
+- sprintf(str,
++ snprintf(str, size,
+ "%s: slot %d sp %d ep %d flags %c",
+ xhci_trb_type_string(type),
+ TRB_TO_SLOT_ID(field3),
+--
+2.35.1
+
--- /dev/null
+From b94b6a05e19a0bf210fe431803cd4f0c875174a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jun 2022 18:12:30 +0400
+Subject: usb: ohci-nxp: Fix refcount leak in ohci_hcd_nxp_probe
+
+From: Miaoqian Lin <linmq006@gmail.com>
+
+[ Upstream commit 302970b4cad3ebfda2c05ce06c322ccdc447d17e ]
+
+of_parse_phandle() returns a node pointer with refcount
+incremented, we should use of_node_put() on it when not need anymore.
+Add missing of_node_put() to avoid refcount leak.
+
+Fixes: 73108aa90cbf ("USB: ohci-nxp: Use isp1301 driver")
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
+Link: https://lore.kernel.org/r/20220603141231.979-1-linmq006@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/ohci-nxp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c
+index 85878e8ad331..106a6bcefb08 100644
+--- a/drivers/usb/host/ohci-nxp.c
++++ b/drivers/usb/host/ohci-nxp.c
+@@ -164,6 +164,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
+ }
+
+ isp1301_i2c_client = isp1301_get_client(isp1301_node);
++ of_node_put(isp1301_node);
+ if (!isp1301_i2c_client)
+ return -EPROBE_DEFER;
+
+--
+2.35.1
+
--- /dev/null
+From a50f613e420c756c01beea3970368cbadc6c6f22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 10:44:57 +0200
+Subject: USB: serial: fix tty-port initialized comments
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 688ee1d1785c1359f9040f615dd8e6054962bce2 ]
+
+Fix up the tty-port initialized comments which got truncated and
+obfuscated when replacing the old ASYNCB_INITIALIZED flag.
+
+Fixes: d41861ca19c9 ("tty: Replace ASYNC_INITIALIZED bit and update atomically")
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/sierra.c | 3 ++-
+ drivers/usb/serial/usb-serial.c | 2 +-
+ drivers/usb/serial/usb_wwan.c | 3 ++-
+ 3 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
+index 9d56138133a9..ef6a2891f290 100644
+--- a/drivers/usb/serial/sierra.c
++++ b/drivers/usb/serial/sierra.c
+@@ -737,7 +737,8 @@ static void sierra_close(struct usb_serial_port *port)
+
+ /*
+ * Need to take susp_lock to make sure port is not already being
+- * resumed, but no need to hold it due to initialized
++ * resumed, but no need to hold it due to the tty-port initialized
++ * flag.
+ */
+ spin_lock_irq(&intfdata->susp_lock);
+ if (--intfdata->open_ports == 0)
+diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
+index 24101bd7fcad..e35bea2235c1 100644
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -295,7 +295,7 @@ static int serial_open(struct tty_struct *tty, struct file *filp)
+ *
+ * Shut down a USB serial port. Serialized against activate by the
+ * tport mutex and kept to matching open/close pairs
+- * of calls by the initialized flag.
++ * of calls by the tty-port initialized flag.
+ *
+ * Not called if tty is console.
+ */
+diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
+index dab38b63eaf7..cc81ab7ef4da 100644
+--- a/drivers/usb/serial/usb_wwan.c
++++ b/drivers/usb/serial/usb_wwan.c
+@@ -388,7 +388,8 @@ void usb_wwan_close(struct usb_serial_port *port)
+
+ /*
+ * Need to take susp_lock to make sure port is not already being
+- * resumed, but no need to hold it due to initialized
++ * resumed, but no need to hold it due to the tty-port initialized
++ * flag.
+ */
+ spin_lock_irq(&intfdata->susp_lock);
+ if (--intfdata->open_ports == 0)
+--
+2.35.1
+
--- /dev/null
+From e2052cd5759595127c17729da801c94a0d30ab2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 20:14:04 +0800
+Subject: usb: xhci: tegra: Fix error check
+
+From: Tang Bin <tangbin@cmss.chinamobile.com>
+
+[ Upstream commit 18fc7c435be3f17ea26a21b2e2312fcb9088e01f ]
+
+In the function tegra_xusb_powerdomain_init(),
+dev_pm_domain_attach_by_name() may return NULL in some cases,
+so IS_ERR() doesn't meet the requirements. Thus fix it.
+
+Fixes: 6494a9ad86de ("usb: xhci: tegra: Add genpd support")
+Signed-off-by: Tang Bin <tangbin@cmss.chinamobile.com>
+Link: https://lore.kernel.org/r/20220524121404.18376-1-tangbin@cmss.chinamobile.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-tegra.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
+index 996958a6565c..bdb776553826 100644
+--- a/drivers/usb/host/xhci-tegra.c
++++ b/drivers/usb/host/xhci-tegra.c
+@@ -1010,15 +1010,15 @@ static int tegra_xusb_powerdomain_init(struct device *dev,
+ int err;
+
+ tegra->genpd_dev_host = dev_pm_domain_attach_by_name(dev, "xusb_host");
+- if (IS_ERR(tegra->genpd_dev_host)) {
+- err = PTR_ERR(tegra->genpd_dev_host);
++ if (IS_ERR_OR_NULL(tegra->genpd_dev_host)) {
++ err = PTR_ERR(tegra->genpd_dev_host) ? : -ENODATA;
+ dev_err(dev, "failed to get host pm-domain: %d\n", err);
+ return err;
+ }
+
+ tegra->genpd_dev_ss = dev_pm_domain_attach_by_name(dev, "xusb_ss");
+- if (IS_ERR(tegra->genpd_dev_ss)) {
+- err = PTR_ERR(tegra->genpd_dev_ss);
++ if (IS_ERR_OR_NULL(tegra->genpd_dev_ss)) {
++ err = PTR_ERR(tegra->genpd_dev_ss) ? : -ENODATA;
+ dev_err(dev, "failed to get superspeed pm-domain: %d\n", err);
+ return err;
+ }
+--
+2.35.1
+
--- /dev/null
+From c4a65443c5fc2fbb48c8125eb583c974e2fdbc7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 15:57:29 +0200
+Subject: vfio/ccw: Do not change FSM state in subchannel event
+
+From: Eric Farman <farman@linux.ibm.com>
+
+[ Upstream commit cffcc109fd682075dee79bade3d60a07152a8fd1 ]
+
+The routine vfio_ccw_sch_event() is tasked with handling subchannel events,
+specifically machine checks, on behalf of vfio-ccw. It correctly calls
+cio_update_schib(), and if that fails (meaning the subchannel is gone)
+it makes an FSM event call to mark the subchannel Not Operational.
+
+If that worked, however, then it decides that if the FSM state was already
+Not Operational (implying the subchannel just came back), then it should
+simply change the FSM to partially- or fully-open.
+
+Remove this trickery, since a subchannel returning will require more
+probing than simply "oh all is well again" to ensure it works correctly.
+
+Fixes: bbe37e4cb8970 ("vfio: ccw: introduce a finite state machine")
+Signed-off-by: Eric Farman <farman@linux.ibm.com>
+Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
+Link: https://lore.kernel.org/r/20220707135737.720765-4-farman@linux.ibm.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/cio/vfio_ccw_drv.c | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
+index 789175221e9a..e76a4a3cf1ce 100644
+--- a/drivers/s390/cio/vfio_ccw_drv.c
++++ b/drivers/s390/cio/vfio_ccw_drv.c
+@@ -302,19 +302,11 @@ static int vfio_ccw_sch_event(struct subchannel *sch, int process)
+ if (work_pending(&sch->todo_work))
+ goto out_unlock;
+
+- if (cio_update_schib(sch)) {
+- vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER);
+- rc = 0;
+- goto out_unlock;
+- }
+-
+- private = dev_get_drvdata(&sch->dev);
+- if (private->state == VFIO_CCW_STATE_NOT_OPER) {
+- private->state = private->mdev ? VFIO_CCW_STATE_IDLE :
+- VFIO_CCW_STATE_STANDBY;
+- }
+ rc = 0;
+
++ if (cio_update_schib(sch))
++ vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER);
++
+ out_unlock:
+ spin_unlock_irqrestore(sch->lock, flags);
+
+--
+2.35.1
+
--- /dev/null
+From aefc2d76f1fe0092329dbf7f10e24e4868092a0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 15:57:28 +0200
+Subject: vfio/ccw: Fix FSM state if mdev probe fails
+
+From: Eric Farman <farman@linux.ibm.com>
+
+[ Upstream commit f6c876d67e956de8d69349b0ee43bc7277c09e5c ]
+
+The FSM is in STANDBY state when arriving in vfio_ccw_mdev_probe(),
+and this routine converts it to IDLE as part of its processing.
+The error exit sets it to IDLE (again) but clears the private->mdev
+pointer.
+
+The FSM should of course be managing the state itself, but the
+correct thing for vfio_ccw_mdev_probe() to do would be to put
+the state back the way it found it.
+
+The corresponding check of private->mdev in vfio_ccw_sch_io_todo()
+can be removed, since the distinction is unnecessary at this point.
+
+Fixes: 3bf1311f351ef ("vfio/ccw: Convert to use vfio_register_emulated_iommu_dev()")
+Signed-off-by: Eric Farman <farman@linux.ibm.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
+Link: https://lore.kernel.org/r/20220707135737.720765-3-farman@linux.ibm.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/cio/vfio_ccw_drv.c | 5 +++--
+ drivers/s390/cio/vfio_ccw_ops.c | 2 +-
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
+index ee182cfb467d..789175221e9a 100644
+--- a/drivers/s390/cio/vfio_ccw_drv.c
++++ b/drivers/s390/cio/vfio_ccw_drv.c
+@@ -107,9 +107,10 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work)
+ /*
+ * Reset to IDLE only if processing of a channel program
+ * has finished. Do not overwrite a possible processing
+- * state if the final interrupt was for HSCH or CSCH.
++ * state if the interrupt was unsolicited, or if the final
++ * interrupt was for HSCH or CSCH.
+ */
+- if (private->mdev && cp_is_finished)
++ if (cp_is_finished)
+ private->state = VFIO_CCW_STATE_IDLE;
+
+ if (private->io_trigger)
+diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
+index d8589afac272..8d76f5b26e2b 100644
+--- a/drivers/s390/cio/vfio_ccw_ops.c
++++ b/drivers/s390/cio/vfio_ccw_ops.c
+@@ -146,7 +146,7 @@ static int vfio_ccw_mdev_probe(struct mdev_device *mdev)
+ vfio_uninit_group_dev(&private->vdev);
+ atomic_inc(&private->avail);
+ private->mdev = NULL;
+- private->state = VFIO_CCW_STATE_IDLE;
++ private->state = VFIO_CCW_STATE_STANDBY;
+ return ret;
+ }
+
+--
+2.35.1
+
--- /dev/null
+From a029a1c4f1c0625043cd23eab46468016bcd8af0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 May 2022 13:19:07 -0600
+Subject: vfio/pci: Have all VFIO PCI drivers store the vfio_pci_core_device in
+ drvdata
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit 91be0bd6c6cf21328017e990d3ceeb00f03821fd ]
+
+Having a consistent pointer in the drvdata will allow the next patch to
+make use of the drvdata from some of the core code helpers.
+
+Use a WARN_ON inside vfio_pci_core_register_device() to detect drivers
+that miss this.
+
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/1-v4-c841817a0349+8f-vfio_get_from_dev_jgg@nvidia.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 15 +++++++++++----
+ drivers/vfio/pci/mlx5/main.c | 15 +++++++++++----
+ drivers/vfio/pci/vfio_pci.c | 2 +-
+ drivers/vfio/pci/vfio_pci_core.c | 4 ++++
+ 4 files changed, 27 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+index 767b5d47631a..e92376837b29 100644
+--- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
++++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+@@ -337,6 +337,14 @@ static int vf_qm_cache_wb(struct hisi_qm *qm)
+ return 0;
+ }
+
++static struct hisi_acc_vf_core_device *hssi_acc_drvdata(struct pci_dev *pdev)
++{
++ struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev);
++
++ return container_of(core_device, struct hisi_acc_vf_core_device,
++ core_device);
++}
++
+ static void vf_qm_fun_reset(struct hisi_acc_vf_core_device *hisi_acc_vdev,
+ struct hisi_qm *qm)
+ {
+@@ -962,7 +970,7 @@ hisi_acc_vfio_pci_get_device_state(struct vfio_device *vdev,
+
+ static void hisi_acc_vf_pci_aer_reset_done(struct pci_dev *pdev)
+ {
+- struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(&pdev->dev);
++ struct hisi_acc_vf_core_device *hisi_acc_vdev = hssi_acc_drvdata(pdev);
+
+ if (hisi_acc_vdev->core_device.vdev.migration_flags !=
+ VFIO_MIGRATION_STOP_COPY)
+@@ -1274,11 +1282,10 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device
+ &hisi_acc_vfio_pci_ops);
+ }
+
++ dev_set_drvdata(&pdev->dev, &hisi_acc_vdev->core_device);
+ ret = vfio_pci_core_register_device(&hisi_acc_vdev->core_device);
+ if (ret)
+ goto out_free;
+-
+- dev_set_drvdata(&pdev->dev, hisi_acc_vdev);
+ return 0;
+
+ out_free:
+@@ -1289,7 +1296,7 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device
+
+ static void hisi_acc_vfio_pci_remove(struct pci_dev *pdev)
+ {
+- struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(&pdev->dev);
++ struct hisi_acc_vf_core_device *hisi_acc_vdev = hssi_acc_drvdata(pdev);
+
+ vfio_pci_core_unregister_device(&hisi_acc_vdev->core_device);
+ vfio_pci_core_uninit_device(&hisi_acc_vdev->core_device);
+diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c
+index bbec5d288fee..9f59f5807b8a 100644
+--- a/drivers/vfio/pci/mlx5/main.c
++++ b/drivers/vfio/pci/mlx5/main.c
+@@ -39,6 +39,14 @@ struct mlx5vf_pci_core_device {
+ struct mlx5_vf_migration_file *saving_migf;
+ };
+
++static struct mlx5vf_pci_core_device *mlx5vf_drvdata(struct pci_dev *pdev)
++{
++ struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev);
++
++ return container_of(core_device, struct mlx5vf_pci_core_device,
++ core_device);
++}
++
+ static struct page *
+ mlx5vf_get_migration_page(struct mlx5_vf_migration_file *migf,
+ unsigned long offset)
+@@ -505,7 +513,7 @@ static int mlx5vf_pci_get_device_state(struct vfio_device *vdev,
+
+ static void mlx5vf_pci_aer_reset_done(struct pci_dev *pdev)
+ {
+- struct mlx5vf_pci_core_device *mvdev = dev_get_drvdata(&pdev->dev);
++ struct mlx5vf_pci_core_device *mvdev = mlx5vf_drvdata(pdev);
+
+ if (!mvdev->migrate_cap)
+ return;
+@@ -614,11 +622,10 @@ static int mlx5vf_pci_probe(struct pci_dev *pdev,
+ }
+ }
+
++ dev_set_drvdata(&pdev->dev, &mvdev->core_device);
+ ret = vfio_pci_core_register_device(&mvdev->core_device);
+ if (ret)
+ goto out_free;
+-
+- dev_set_drvdata(&pdev->dev, mvdev);
+ return 0;
+
+ out_free:
+@@ -629,7 +636,7 @@ static int mlx5vf_pci_probe(struct pci_dev *pdev,
+
+ static void mlx5vf_pci_remove(struct pci_dev *pdev)
+ {
+- struct mlx5vf_pci_core_device *mvdev = dev_get_drvdata(&pdev->dev);
++ struct mlx5vf_pci_core_device *mvdev = mlx5vf_drvdata(pdev);
+
+ vfio_pci_core_unregister_device(&mvdev->core_device);
+ vfio_pci_core_uninit_device(&mvdev->core_device);
+diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
+index 2b047469e02f..8c990a1a7def 100644
+--- a/drivers/vfio/pci/vfio_pci.c
++++ b/drivers/vfio/pci/vfio_pci.c
+@@ -151,10 +151,10 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ return -ENOMEM;
+ vfio_pci_core_init_device(vdev, pdev, &vfio_pci_ops);
+
++ dev_set_drvdata(&pdev->dev, vdev);
+ ret = vfio_pci_core_register_device(vdev);
+ if (ret)
+ goto out_free;
+- dev_set_drvdata(&pdev->dev, vdev);
+ return 0;
+
+ out_free:
+diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
+index 06b6f3594a13..65587fd5c021 100644
+--- a/drivers/vfio/pci/vfio_pci_core.c
++++ b/drivers/vfio/pci/vfio_pci_core.c
+@@ -1821,6 +1821,10 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev)
+ struct pci_dev *pdev = vdev->pdev;
+ int ret;
+
++ /* Drivers must set the vfio_pci_core_device to their drvdata */
++ if (WARN_ON(vdev != dev_get_drvdata(&vdev->pdev->dev)))
++ return -EINVAL;
++
+ if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
+ return -EINVAL;
+
+--
+2.35.1
+
--- /dev/null
+From e38e5731125b1b2d34b09e3268549626d3c37949 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 16:25:46 +0800
+Subject: video: fbdev: amba-clcd: Fix refcount leak bugs
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 26c2b7d9fac42eb8317f3ceefa4c1a9a9170ca69 ]
+
+In clcdfb_of_init_display(), we should call of_node_put() for the
+references returned by of_graph_get_next_endpoint() and
+of_graph_get_remote_port_parent() which have increased the refcount.
+
+Besides, we should call of_node_put() both in fail path or when
+the references are not used anymore.
+
+Fixes: d10715be03bd ("video: ARM CLCD: Add DT support")
+Signed-off-by: Liang He <windhl@126.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/amba-clcd.c | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c
+index 8080116aea84..f65c96d1394d 100644
+--- a/drivers/video/fbdev/amba-clcd.c
++++ b/drivers/video/fbdev/amba-clcd.c
+@@ -698,16 +698,18 @@ static int clcdfb_of_init_display(struct clcd_fb *fb)
+ return -ENODEV;
+
+ panel = of_graph_get_remote_port_parent(endpoint);
+- if (!panel)
+- return -ENODEV;
++ if (!panel) {
++ err = -ENODEV;
++ goto out_endpoint_put;
++ }
+
+ err = clcdfb_of_get_backlight(&fb->dev->dev, fb->panel);
+ if (err)
+- return err;
++ goto out_panel_put;
+
+ err = clcdfb_of_get_mode(&fb->dev->dev, panel, fb->panel);
+ if (err)
+- return err;
++ goto out_panel_put;
+
+ err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth",
+ &max_bandwidth);
+@@ -736,11 +738,21 @@ static int clcdfb_of_init_display(struct clcd_fb *fb)
+
+ if (of_property_read_u32_array(endpoint,
+ "arm,pl11x,tft-r0g0b0-pads",
+- tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) != 0)
+- return -ENOENT;
++ tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) != 0) {
++ err = -ENOENT;
++ goto out_panel_put;
++ }
++
++ of_node_put(panel);
++ of_node_put(endpoint);
+
+ return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0],
+ tft_r0b0g0[1], tft_r0b0g0[2]);
++out_panel_put:
++ of_node_put(panel);
++out_endpoint_put:
++ of_node_put(endpoint);
++ return err;
+ }
+
+ static int clcdfb_of_vram_setup(struct clcd_fb *fb)
+--
+2.35.1
+
--- /dev/null
+From 4edf8e4191fdfd2fa6241513a3be1b578db9dc05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Aug 2022 20:41:24 +0800
+Subject: video: fbdev: arkfb: Check the size of screen before memset_io()
+
+From: Zheyu Ma <zheyuma97@gmail.com>
+
+[ Upstream commit 96b550971c65d54d64728d8ba973487878a06454 ]
+
+In the function arkfb_set_par(), the value of 'screen_size' is
+calculated by the user input. If the user provides the improper value,
+the value of 'screen_size' may larger than 'info->screen_size', which
+may cause the following bug:
+
+[ 659.399066] BUG: unable to handle page fault for address: ffffc90003000000
+[ 659.399077] #PF: supervisor write access in kernel mode
+[ 659.399079] #PF: error_code(0x0002) - not-present page
+[ 659.399094] RIP: 0010:memset_orig+0x33/0xb0
+[ 659.399116] Call Trace:
+[ 659.399122] arkfb_set_par+0x143f/0x24c0
+[ 659.399130] fb_set_var+0x604/0xeb0
+[ 659.399161] do_fb_ioctl+0x234/0x670
+[ 659.399189] fb_ioctl+0xdd/0x130
+
+Fix the this by checking the value of 'screen_size' before memset_io().
+
+Fixes: 681e14730c73 ("arkfb: new framebuffer driver for ARK Logic cards")
+Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/arkfb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c
+index ed76ddc7df3d..a2a381631628 100644
+--- a/drivers/video/fbdev/arkfb.c
++++ b/drivers/video/fbdev/arkfb.c
+@@ -797,6 +797,8 @@ static int arkfb_set_par(struct fb_info *info)
+ value = ((value * hmul / hdiv) / 8) - 5;
+ vga_wcrt(par->state.vgabase, 0x42, (value + 1) / 2);
+
++ if (screen_size > info->screen_size)
++ screen_size = info->screen_size;
+ memset_io(info->screen_base, 0x00, screen_size);
+ /* Device and screen back on */
+ svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
+--
+2.35.1
+
--- /dev/null
+From 2fd75972aaced38e4da659536acc854b17c9bdd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Aug 2022 17:23:12 +0800
+Subject: video: fbdev: arkfb: Fix a divide-by-zero bug in ark_set_pixclock()
+
+From: Zheyu Ma <zheyuma97@gmail.com>
+
+[ Upstream commit 2f1c4523f7a3aaabe7e53d3ebd378292947e95c8 ]
+
+Since the user can control the arguments of the ioctl() from the user
+space, under special arguments that may result in a divide-by-zero bug
+in:
+ drivers/video/fbdev/arkfb.c:784: ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul);
+with hdiv=1, pixclock=1 and hmul=2 you end up with (1*1)/2 = (int) 0.
+and then in:
+ drivers/video/fbdev/arkfb.c:504: rv = dac_set_freq(par->dac, 0, 1000000000 / pixclock);
+we'll get a division-by-zero.
+
+The following log can reveal it:
+
+divide error: 0000 [#1] PREEMPT SMP KASAN PTI
+RIP: 0010:ark_set_pixclock drivers/video/fbdev/arkfb.c:504 [inline]
+RIP: 0010:arkfb_set_par+0x10fc/0x24c0 drivers/video/fbdev/arkfb.c:784
+Call Trace:
+ fb_set_var+0x604/0xeb0 drivers/video/fbdev/core/fbmem.c:1034
+ do_fb_ioctl+0x234/0x670 drivers/video/fbdev/core/fbmem.c:1110
+ fb_ioctl+0xdd/0x130 drivers/video/fbdev/core/fbmem.c:1189
+
+Fix this by checking the argument of ark_set_pixclock() first.
+
+Fixes: 681e14730c73 ("arkfb: new framebuffer driver for ARK Logic cards")
+Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/arkfb.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c
+index eb3e47c58c5f..ed76ddc7df3d 100644
+--- a/drivers/video/fbdev/arkfb.c
++++ b/drivers/video/fbdev/arkfb.c
+@@ -781,7 +781,12 @@ static int arkfb_set_par(struct fb_info *info)
+ return -EINVAL;
+ }
+
+- ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul);
++ value = (hdiv * info->var.pixclock) / hmul;
++ if (!value) {
++ fb_dbg(info, "invalid pixclock\n");
++ value = 1;
++ }
++ ark_set_pixclock(info, value);
+ svga_set_timings(par->state.vgabase, &ark_timing_regs, &(info->var), hmul, hdiv,
+ (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1,
+ (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1,
+--
+2.35.1
+
--- /dev/null
+From 0d6cf7431b82befe38fcf3d045bc8b7ced15d961 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Aug 2022 20:41:25 +0800
+Subject: video: fbdev: s3fb: Check the size of screen before memset_io()
+
+From: Zheyu Ma <zheyuma97@gmail.com>
+
+[ Upstream commit 6ba592fa014f21f35a8ee8da4ca7b95a018f13e8 ]
+
+In the function s3fb_set_par(), the value of 'screen_size' is
+calculated by the user input. If the user provides the improper value,
+the value of 'screen_size' may larger than 'info->screen_size', which
+may cause the following bug:
+
+[ 54.083733] BUG: unable to handle page fault for address: ffffc90003000000
+[ 54.083742] #PF: supervisor write access in kernel mode
+[ 54.083744] #PF: error_code(0x0002) - not-present page
+[ 54.083760] RIP: 0010:memset_orig+0x33/0xb0
+[ 54.083782] Call Trace:
+[ 54.083788] s3fb_set_par+0x1ec6/0x4040
+[ 54.083806] fb_set_var+0x604/0xeb0
+[ 54.083836] do_fb_ioctl+0x234/0x670
+
+Fix the this by checking the value of 'screen_size' before memset_io().
+
+Fixes: a268422de8bf ("fbdev driver for S3 Trio/Virge")
+Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/s3fb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/video/fbdev/s3fb.c b/drivers/video/fbdev/s3fb.c
+index b93c8eb02336..5069f6f67923 100644
+--- a/drivers/video/fbdev/s3fb.c
++++ b/drivers/video/fbdev/s3fb.c
+@@ -905,6 +905,8 @@ static int s3fb_set_par(struct fb_info *info)
+ value = clamp((htotal + hsstart + 1) / 2 + 2, hsstart + 4, htotal + 1);
+ svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value);
+
++ if (screen_size > info->screen_size)
++ screen_size = info->screen_size;
+ memset_io(info->screen_base, 0x00, screen_size);
+ /* Device and screen back on */
+ svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
+--
+2.35.1
+
--- /dev/null
+From d5f9708b5d591c5f03ccc18e5e4763c51786973b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Jul 2022 15:43:43 +0300
+Subject: video: fbdev: sis: fix typos in SiS_GetModeID()
+
+From: Rustam Subkhankulov <subkhankulov@ispras.ru>
+
+[ Upstream commit 3eb8fccc244bfb41a7961969e4db280d44911226 ]
+
+The second operand of a '&&' operator has no impact on expression
+result for cases 400 and 512 in SiS_GetModeID().
+
+Judging by the logic and the names of the variables, in both cases a
+typo was made.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Signed-off-by: Rustam Subkhankulov <subkhankulov@ispras.ru>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/sis/init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/video/fbdev/sis/init.c b/drivers/video/fbdev/sis/init.c
+index b568c646a76c..2ba91d62af92 100644
+--- a/drivers/video/fbdev/sis/init.c
++++ b/drivers/video/fbdev/sis/init.c
+@@ -355,12 +355,12 @@ SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
+ }
+ break;
+ case 400:
+- if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDwidth >= 600))) {
++ if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 800) && (LCDheight >= 600))) {
+ if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+ }
+ break;
+ case 512:
+- if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDwidth >= 768))) {
++ if((!(VBFlags & CRT1_LCDA)) || ((LCDwidth >= 1024) && (LCDheight >= 768))) {
+ if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+ }
+ break;
+--
+2.35.1
+
--- /dev/null
+From 5f75e9aa9285cef62f3124341803867322b3b46f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Aug 2022 20:41:23 +0800
+Subject: video: fbdev: vt8623fb: Check the size of screen before memset_io()
+
+From: Zheyu Ma <zheyuma97@gmail.com>
+
+[ Upstream commit ec0754c60217248fa77cc9005d66b2b55200ac06 ]
+
+In the function vt8623fb_set_par(), the value of 'screen_size' is
+calculated by the user input. If the user provides the improper value,
+the value of 'screen_size' may larger than 'info->screen_size', which
+may cause the following bug:
+
+[ 583.339036] BUG: unable to handle page fault for address: ffffc90005000000
+[ 583.339049] #PF: supervisor write access in kernel mode
+[ 583.339052] #PF: error_code(0x0002) - not-present page
+[ 583.339074] RIP: 0010:memset_orig+0x33/0xb0
+[ 583.339110] Call Trace:
+[ 583.339118] vt8623fb_set_par+0x11cd/0x21e0
+[ 583.339146] fb_set_var+0x604/0xeb0
+[ 583.339181] do_fb_ioctl+0x234/0x670
+[ 583.339209] fb_ioctl+0xdd/0x130
+
+Fix the this by checking the value of 'screen_size' before memset_io().
+
+Fixes: 558b7bd86c32 ("vt8623fb: new framebuffer driver for VIA VT8623")
+Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/vt8623fb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/video/fbdev/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c
+index a92a8c670cf0..4274c6efb249 100644
+--- a/drivers/video/fbdev/vt8623fb.c
++++ b/drivers/video/fbdev/vt8623fb.c
+@@ -507,6 +507,8 @@ static int vt8623fb_set_par(struct fb_info *info)
+ (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, 1,
+ 1, info->node);
+
++ if (screen_size > info->screen_size)
++ screen_size = info->screen_size;
+ memset_io(info->screen_base, 0x00, screen_size);
+
+ /* Device and screen back on */
+--
+2.35.1
+
--- /dev/null
+From 86e0e4ae9d2bffddbedcd2724340d24fe7f0f9f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Mar 2022 13:09:45 +0800
+Subject: virtio-gpu: fix a missing check to avoid NULL dereference
+
+From: Xiaomeng Tong <xiam0nd.tong@gmail.com>
+
+[ Upstream commit bd63f11f4c3c46afec07d821f74736161ff6e526 ]
+
+'cache_ent' could be set NULL inside virtio_gpu_cmd_get_capset()
+and it will lead to a NULL dereference by a lately use of it
+(i.e., ptr = cache_ent->caps_cache). Fix it with a NULL check.
+
+Fixes: 62fb7a5e10962 ("virtio-gpu: add 3d/virgl support")
+Signed-off-by: Xiaomeng Tong <xiam0nd.tong@gmail.com>
+Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20220327050945.1614-1-xiam0nd.tong@gmail.com
+
+[ kraxel: minor codestyle fixup ]
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/virtio/virtgpu_ioctl.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+index c708bab555c6..10f080060923 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
++++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+@@ -579,8 +579,10 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev,
+ spin_unlock(&vgdev->display_info_lock);
+
+ /* not in cache - need to talk to hw */
+- virtio_gpu_cmd_get_capset(vgdev, found_valid, args->cap_set_ver,
+- &cache_ent);
++ ret = virtio_gpu_cmd_get_capset(vgdev, found_valid, args->cap_set_ver,
++ &cache_ent);
++ if (ret)
++ return ret;
+ virtio_gpu_notify(vgdev);
+
+ copy_exit:
+--
+2.35.1
+
--- /dev/null
+From c6ec7c13f14acb6d03309b9e51fdd926a506d6b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Jun 2022 11:50:51 +0200
+Subject: wait: Fix __wait_event_hrtimeout for RT/DL tasks
+
+From: Juri Lelli <juri.lelli@redhat.com>
+
+[ Upstream commit cceeeb6a6d02e7b9a74ddd27a3225013b34174aa ]
+
+Changes to hrtimer mode (potentially made by __hrtimer_init_sleeper on
+PREEMPT_RT) are not visible to hrtimer_start_range_ns, thus not
+accounted for by hrtimer_start_expires call paths. In particular,
+__wait_event_hrtimeout suffers from this problem as we have, for
+example:
+
+fs/aio.c::read_events
+ wait_event_interruptible_hrtimeout
+ __wait_event_hrtimeout
+ hrtimer_init_sleeper_on_stack <- this might "mode |= HRTIMER_MODE_HARD"
+ on RT if task runs at RT/DL priority
+ hrtimer_start_range_ns
+ WARN_ON_ONCE(!(mode & HRTIMER_MODE_HARD) ^ !timer->is_hard)
+ fires since the latter doesn't see the change of mode done by
+ init_sleeper
+
+Fix it by making __wait_event_hrtimeout call hrtimer_sleeper_start_expires,
+which is aware of the special RT/DL case, instead of hrtimer_start_range_ns.
+
+Reported-by: Bruno Goncalves <bgoncalv@redhat.com>
+Signed-off-by: Juri Lelli <juri.lelli@redhat.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Daniel Bristot de Oliveira <bristot@kernel.org>
+Reviewed-by: Valentin Schneider <vschneid@redhat.com>
+Link: https://lore.kernel.org/r/20220627095051.42470-1-juri.lelli@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/wait.h | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/include/linux/wait.h b/include/linux/wait.h
+index 851e07da2583..58cfbf81447c 100644
+--- a/include/linux/wait.h
++++ b/include/linux/wait.h
+@@ -544,10 +544,11 @@ do { \
+ \
+ hrtimer_init_sleeper_on_stack(&__t, CLOCK_MONOTONIC, \
+ HRTIMER_MODE_REL); \
+- if ((timeout) != KTIME_MAX) \
+- hrtimer_start_range_ns(&__t.timer, timeout, \
+- current->timer_slack_ns, \
+- HRTIMER_MODE_REL); \
++ if ((timeout) != KTIME_MAX) { \
++ hrtimer_set_expires_range_ns(&__t.timer, timeout, \
++ current->timer_slack_ns); \
++ hrtimer_sleeper_start_expires(&__t, HRTIMER_MODE_REL); \
++ } \
+ \
+ __ret = ___wait_event(wq_head, condition, state, 0, 0, \
+ if (!__t.task) { \
+--
+2.35.1
+
--- /dev/null
+From 4c5ddd25bbd686af170999de26c12652e7c0144f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Jul 2022 11:09:38 +0800
+Subject: watchdog: armada_37xx_wdt: check the return value of devm_ioremap()
+ in armada_37xx_wdt_probe()
+
+From: William Dean <williamsukatube@gmail.com>
+
+[ Upstream commit 2d27e52841092e5831dd41f313028c668d816eb0 ]
+
+The function devm_ioremap() in armada_37xx_wdt_probe() can fail, so
+its return value should be checked.
+
+Fixes: 54e3d9b518c8a ("watchdog: Add support for Armada 37xx CPU watchdog")
+Reported-by: Hacash Robot <hacashRobot@santino.com>
+Signed-off-by: William Dean <williamsukatube@gmail.com>
+Reviewed-by: Marek Beh=C3=BAn <kabel@kernel.org>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20220722030938.2925156-1-williamsukatube@163.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/armada_37xx_wdt.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/watchdog/armada_37xx_wdt.c b/drivers/watchdog/armada_37xx_wdt.c
+index 1635f421ef2c..854b1cc723cb 100644
+--- a/drivers/watchdog/armada_37xx_wdt.c
++++ b/drivers/watchdog/armada_37xx_wdt.c
+@@ -274,6 +274,8 @@ static int armada_37xx_wdt_probe(struct platform_device *pdev)
+ if (!res)
+ return -ENODEV;
+ dev->reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
++ if (!dev->reg)
++ return -ENOMEM;
+
+ /* init clock */
+ dev->clk = devm_clk_get(&pdev->dev, NULL);
+--
+2.35.1
+
--- /dev/null
+From b2d1610a3e091df649156d7eb17e5ddb1854d9f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 May 2022 16:03:03 +0800
+Subject: watchdog: f71808e_wdt: Add check for platform_driver_register
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 97d5ec548150764946f38632e62e79759832b54b ]
+
+As platform_driver_register() could fail, it should be better
+to deal with the return value in order to maintain the code
+consisitency.
+
+Fixes: 27e0fe00a5c6 ("watchdog: f71808e_wdt: refactor to platform device/driver pair")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+https://lore.kernel.org/r/20220526080303.1005063-1-jiasheng@iscas.ac.cn
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/f71808e_wdt.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
+index 7f59c680de25..6a16d3d0bb1e 100644
+--- a/drivers/watchdog/f71808e_wdt.c
++++ b/drivers/watchdog/f71808e_wdt.c
+@@ -634,7 +634,9 @@ static int __init fintek_wdt_init(void)
+
+ pdata.type = ret;
+
+- platform_driver_register(&fintek_wdt_driver);
++ ret = platform_driver_register(&fintek_wdt_driver);
++ if (ret)
++ return ret;
+
+ wdt_res.name = "superio port";
+ wdt_res.flags = IORESOURCE_IO;
+--
+2.35.1
+
--- /dev/null
+From a82bb55d6c6f78d54c666d0a7082934121f1db31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jun 2022 15:28:40 +0200
+Subject: watchdog: sp5100_tco: Fix a memory leak of EFCH MMIO resource
+
+From: Jean Delvare <jdelvare@suse.de>
+
+[ Upstream commit c6d9c0798ed366a09a9e53d71edcd2266e34a6eb ]
+
+Unlike release_mem_region(), a call to release_resource() does not
+free the resource, so it has to be freed explicitly to avoid a memory
+leak.
+
+Signed-off-by: Jean Delvare <jdelvare@suse.de>
+Fixes: 0578fff4aae5 ("Watchdog: sp5100_tco: Add initialization using EFCH MMIO")
+Cc: Terry Bowman <terry.bowman@amd.com>
+Cc: Wim Van Sebroeck <wim@linux-watchdog.org>
+Cc: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20220621152840.420a0f4c@endymion.delvare
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/sp5100_tco.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
+index 86ffb58fbc85..ae54dd33e233 100644
+--- a/drivers/watchdog/sp5100_tco.c
++++ b/drivers/watchdog/sp5100_tco.c
+@@ -402,6 +402,7 @@ static int sp5100_tco_setupdevice_mmio(struct device *dev,
+ iounmap(addr);
+
+ release_resource(res);
++ kfree(res);
+
+ return ret;
+ }
+--
+2.35.1
+
--- /dev/null
+From 72efe52433fdf8d0d8c3f7a1e849ec9fb16ae439 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jun 2022 20:16:14 +0300
+Subject: wifi: iwlegacy: 4965: fix potential off-by-one overflow in
+ il4965_rs_fill_link_cmd()
+
+From: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+
+[ Upstream commit a8eb8e6f7159c7c20c0ddac428bde3d110890aa7 ]
+
+As a result of the execution of the inner while loop, the value
+of 'idx' can be equal to LINK_QUAL_MAX_RETRY_NUM. However, this
+is not checked after the loop and 'idx' is used to write the
+LINK_QUAL_MAX_RETRY_NUM size array 'lq_cmd->rs_table[idx]' below
+in the outer loop.
+
+The fix is to check the new value of 'idx' inside the nested loop,
+and break both loops if index equals the size. Checking it at the
+start is now pointless, so let's remove it.
+
+Detected using the static analysis tool - Svace.
+
+Fixes: be663ab67077 ("iwlwifi: split the drivers for agn and legacy devices 3945/4965")
+Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220608171614.28891-1-aleksei.kodanev@bell-sw.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlegacy/4965-rs.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlegacy/4965-rs.c b/drivers/net/wireless/intel/iwlegacy/4965-rs.c
+index 9a491e5db75b..532e3b91777d 100644
+--- a/drivers/net/wireless/intel/iwlegacy/4965-rs.c
++++ b/drivers/net/wireless/intel/iwlegacy/4965-rs.c
+@@ -2403,7 +2403,7 @@ il4965_rs_fill_link_cmd(struct il_priv *il, struct il_lq_sta *lq_sta,
+ /* Repeat initial/next rate.
+ * For legacy IL_NUMBER_TRY == 1, this loop will not execute.
+ * For HT IL_HT_NUMBER_TRY == 3, this executes twice. */
+- while (repeat_rate > 0 && idx < LINK_QUAL_MAX_RETRY_NUM) {
++ while (repeat_rate > 0) {
+ if (is_legacy(tbl_type.lq_type)) {
+ if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
+ ant_toggle_cnt++;
+@@ -2422,6 +2422,8 @@ il4965_rs_fill_link_cmd(struct il_priv *il, struct il_lq_sta *lq_sta,
+ cpu_to_le32(new_rate);
+ repeat_rate--;
+ idx++;
++ if (idx >= LINK_QUAL_MAX_RETRY_NUM)
++ goto out;
+ }
+
+ il4965_rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
+@@ -2466,6 +2468,7 @@ il4965_rs_fill_link_cmd(struct il_priv *il, struct il_lq_sta *lq_sta,
+ repeat_rate--;
+ }
+
++out:
+ lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
+ lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+
+--
+2.35.1
+
--- /dev/null
+From a1a081229765a9b9ca3efde0f3a8afc78c271a08 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 17:35:42 +0200
+Subject: wifi: iwlwifi: mvm: fix double list_add at iwl_mvm_mac_wake_tx_queue
+
+From: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
+
+[ Upstream commit 14a3aacf517a9de725dd3219dbbcf741e31763c4 ]
+
+After successfull station association, if station queues are disabled for
+some reason, the related lists are not emptied. So if some new element is
+added to the list in iwl_mvm_mac_wake_tx_queue, it can match with the old
+one and produce a BUG like this:
+
+[ 46.535263] list_add corruption. prev->next should be next (ffff94c1c318a360), but was 0000000000000000. (prev=ffff94c1d02d3388).
+[ 46.535283] ------------[ cut here ]------------
+[ 46.535284] kernel BUG at lib/list_debug.c:26!
+[ 46.535290] invalid opcode: 0000 [#1] PREEMPT SMP PTI
+[ 46.585304] CPU: 0 PID: 623 Comm: wpa_supplicant Not tainted 5.19.0-rc3+ #1
+[ 46.592380] Hardware name: Dell Inc. Inspiron 660s/0478VN , BIOS A07 08/24/2012
+[ 46.600336] RIP: 0010:__list_add_valid.cold+0x3d/0x3f
+[ 46.605475] Code: f2 4c 89 c1 48 89 fe 48 c7 c7 c8 40 67 93 e8 20 cc fd ff 0f 0b 48 89 d1 4c 89 c6 4c 89 ca 48 c7 c7 70 40 67 93 e8 09 cc fd ff <0f> 0b 48 89 fe 48 c7 c7 00 41 67 93 e8 f8 cb fd ff 0f 0b 48 89 d1
+[ 46.624469] RSP: 0018:ffffb20800ab76d8 EFLAGS: 00010286
+[ 46.629854] RAX: 0000000000000075 RBX: ffff94c1c318a0e0 RCX: 0000000000000000
+[ 46.637105] RDX: 0000000000000201 RSI: ffffffff9365e100 RDI: 00000000ffffffff
+[ 46.644356] RBP: ffff94c1c5f43370 R08: 0000000000000075 R09: 3064316334396666
+[ 46.651607] R10: 3364323064316334 R11: 39666666663d7665 R12: ffff94c1c5f43388
+[ 46.658857] R13: ffff94c1d02d3388 R14: ffff94c1c318a360 R15: ffff94c1cf2289c0
+[ 46.666108] FS: 00007f65634ff7c0(0000) GS:ffff94c1da200000(0000) knlGS:0000000000000000
+[ 46.674331] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 46.680170] CR2: 00007f7dfe984460 CR3: 000000010e894003 CR4: 00000000000606f0
+[ 46.687422] Call Trace:
+[ 46.689906] <TASK>
+[ 46.691950] iwl_mvm_mac_wake_tx_queue+0xec/0x15c [iwlmvm]
+[ 46.697601] ieee80211_queue_skb+0x4b3/0x720 [mac80211]
+[ 46.702973] ? sta_info_get+0x46/0x60 [mac80211]
+[ 46.707703] ieee80211_tx+0xad/0x110 [mac80211]
+[ 46.712355] __ieee80211_tx_skb_tid_band+0x71/0x90 [mac80211]
+...
+
+In order to avoid this problem, we must also remove the related lists when
+station queues are disabled.
+
+Fixes: cfbc6c4c5b91c ("iwlwifi: mvm: support mac80211 TXQs model")
+Reported-by: Takayuki Nagata <tnagata@redhat.com>
+Reported-by: Petr Stourac <pstourac@redhat.com>
+Tested-by: Petr Stourac <pstourac@redhat.com>
+Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220719153542.81466-1-jtornosm@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+index c7f9d3870f21..8a38d1bfe9b3 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+@@ -1862,6 +1862,7 @@ static void iwl_mvm_disable_sta_queues(struct iwl_mvm *mvm,
+ iwl_mvm_txq_from_mac80211(sta->txq[i]);
+
+ mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE;
++ list_del_init(&mvmtxq->list);
+ }
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 54399c00e57cf04c4110a8ee8fbadb3ab408c601 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 17:23:50 +0800
+Subject: wifi: libertas: Fix possible refcount leak in if_usb_probe()
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit 6fd57e1d120bf13d4dc6c200a7cf914e6347a316 ]
+
+usb_get_dev will be called before lbs_get_firmware_async which means that
+usb_put_dev need to be called when lbs_get_firmware_async fails.
+
+Fixes: ce84bb69f50e ("libertas USB: convert to asynchronous firmware loading")
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220620092350.39960-1-hbh25y@gmail.com
+Link: https://lore.kernel.org/r/20220622113402.16969-1-colin.i.king@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas/if_usb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c b/drivers/net/wireless/marvell/libertas/if_usb.c
+index 5d6dc1dd050d..32fdc4150b60 100644
+--- a/drivers/net/wireless/marvell/libertas/if_usb.c
++++ b/drivers/net/wireless/marvell/libertas/if_usb.c
+@@ -287,6 +287,7 @@ static int if_usb_probe(struct usb_interface *intf,
+ return 0;
+
+ err_get_fw:
++ usb_put_dev(udev);
+ lbs_remove_card(priv);
+ err_add_card:
+ if_usb_reset_device(cardp);
+--
+2.35.1
+
--- /dev/null
+From 222c6b158c73a8d69556318d95fe73ccba3da5c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 16:48:31 +0300
+Subject: wifi: p54: add missing parentheses in p54_flush()
+
+From: Rustam Subkhankulov <subkhankulov@ispras.ru>
+
+[ Upstream commit bcfd9d7f6840b06d5988c7141127795cf405805e ]
+
+The assignment of the value to the variable total in the loop
+condition must be enclosed in additional parentheses, since otherwise,
+in accordance with the precedence of the operators, the conjunction
+will be performed first, and only then the assignment.
+
+Due to this error, a warning later in the function after the loop may
+not occur in the situation when it should.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Signed-off-by: Rustam Subkhankulov <subkhankulov@ispras.ru>
+Fixes: 0d4171e2153b ("p54: implement flush callback")
+Acked-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220714134831.106004-1-subkhankulov@ispras.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/p54/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intersil/p54/main.c b/drivers/net/wireless/intersil/p54/main.c
+index a3ca6620dc0c..8fa3ec71603e 100644
+--- a/drivers/net/wireless/intersil/p54/main.c
++++ b/drivers/net/wireless/intersil/p54/main.c
+@@ -682,7 +682,7 @@ static void p54_flush(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
+ * queues have already been stopped and no new frames can sneak
+ * up from behind.
+ */
+- while ((total = p54_flush_count(priv) && i--)) {
++ while ((total = p54_flush_count(priv)) && i--) {
+ /* waste time */
+ msleep(20);
+ }
+--
+2.35.1
+
--- /dev/null
+From 0033cc34ec08f683a127f95af573e652343d7f84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Jun 2022 23:12:20 +0200
+Subject: wifi: p54: Fix an error handling path in p54spi_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 83781f0162d080fec7dcb911afd1bc2f5ad04471 ]
+
+If an error occurs after a successful call to p54spi_request_firmware(), it
+must be undone by a corresponding release_firmware() as already done in
+the error handling path of p54spi_request_firmware() and in the .remove()
+function.
+
+Add the missing call in the error handling path and remove it from
+p54spi_request_firmware() now that it is the responsibility of the caller
+to release the firmware
+
+Fixes: cd8d3d321285 ("p54spi: p54spi driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/297d2547ff2ee627731662abceeab9dbdaf23231.1655068321.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intersil/p54/p54spi.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intersil/p54/p54spi.c b/drivers/net/wireless/intersil/p54/p54spi.c
+index f99b7ba69fc3..19152fd449ba 100644
+--- a/drivers/net/wireless/intersil/p54/p54spi.c
++++ b/drivers/net/wireless/intersil/p54/p54spi.c
+@@ -164,7 +164,7 @@ static int p54spi_request_firmware(struct ieee80211_hw *dev)
+
+ ret = p54_parse_firmware(dev, priv->firmware);
+ if (ret) {
+- release_firmware(priv->firmware);
++ /* the firmware is released by the caller */
+ return ret;
+ }
+
+@@ -659,6 +659,7 @@ static int p54spi_probe(struct spi_device *spi)
+ return 0;
+
+ err_free_common:
++ release_firmware(priv->firmware);
+ free_irq(gpio_to_irq(p54spi_gpio_irq), spi);
+ err_free_gpio_irq:
+ gpio_free(p54spi_gpio_irq);
+--
+2.35.1
+
--- /dev/null
+From 44ff6e8672709031d70eb5a73f345dff4efa755e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 May 2022 14:48:44 +0300
+Subject: wifi: rtlwifi: fix error codes in rtl_debugfs_set_write_h2c()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit b88d28146c30a8e14f0f012d56ebf19b68a348f4 ]
+
+If the copy_from_user() fails or the user gives invalid date then the
+correct thing to do is to return a negative error code. (Currently it
+returns success).
+
+I made a copy additional related cleanups:
+1) There is no need to check "buffer" for NULL. That's handled by
+copy_from_user().
+2) The "h2c_len" variable cannot be negative because it is unsigned
+and because sscanf() does not return negative error codes.
+
+Fixes: 610247f46feb ("rtlwifi: Improve debugging by using debugfs")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/YoOLnDkHgVltyXK7@kili
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtlwifi/debug.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c
+index 901cdfe3723c..0b1bc04cb6ad 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/debug.c
++++ b/drivers/net/wireless/realtek/rtlwifi/debug.c
+@@ -329,8 +329,8 @@ static ssize_t rtl_debugfs_set_write_h2c(struct file *filp,
+
+ tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
+
+- if (!buffer || copy_from_user(tmp, buffer, tmp_len))
+- return count;
++ if (copy_from_user(tmp, buffer, tmp_len))
++ return -EFAULT;
+
+ tmp[tmp_len] = '\0';
+
+@@ -340,8 +340,8 @@ static ssize_t rtl_debugfs_set_write_h2c(struct file *filp,
+ &h2c_data[4], &h2c_data[5],
+ &h2c_data[6], &h2c_data[7]);
+
+- if (h2c_len <= 0)
+- return count;
++ if (h2c_len == 0)
++ return -EINVAL;
+
+ for (i = 0; i < h2c_len; i++)
+ h2c_data_packed[i] = (u8)h2c_data[i];
+--
+2.35.1
+
--- /dev/null
+From 4501be9aa0e343211e6a4ea68df0c87a6286ade3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Jul 2022 14:37:56 +0800
+Subject: wifi: rtw88: check the return value of alloc_workqueue()
+
+From: William Dean <williamsukatube@gmail.com>
+
+[ Upstream commit 42bbf810e155efc6129a3a648ae5300f00b79d7b ]
+
+The function alloc_workqueue() in rtw_core_init() can fail, but
+there is no check of its return value. To fix this bug, its return value
+should be checked with new error handling code.
+
+Fixes: fe101716c7c9d ("rtw88: replace tx tasklet with work queue")
+Reported-by: Hacash Robot <hacashRobot@santino.com>
+Signed-off-by: William Dean <williamsukatube@gmail.com>
+Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220723063756.2956189-1-williamsukatube@163.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/main.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
+index 8b9899e41b0b..ded952913ae6 100644
+--- a/drivers/net/wireless/realtek/rtw88/main.c
++++ b/drivers/net/wireless/realtek/rtw88/main.c
+@@ -1974,6 +1974,10 @@ int rtw_core_init(struct rtw_dev *rtwdev)
+ timer_setup(&rtwdev->tx_report.purge_timer,
+ rtw_tx_report_purge_timer, 0);
+ rtwdev->tx_wq = alloc_workqueue("rtw_tx_wq", WQ_UNBOUND | WQ_HIGHPRI, 0);
++ if (!rtwdev->tx_wq) {
++ rtw_warn(rtwdev, "alloc_workqueue rtw_tx_wq failed\n");
++ return -ENOMEM;
++ }
+
+ INIT_DELAYED_WORK(&rtwdev->watch_dog_work, rtw_watch_dog_work);
+ INIT_DELAYED_WORK(&coex->bt_relink_work, rtw_coex_bt_relink_work);
+--
+2.35.1
+
--- /dev/null
+From 66ed5341a344833d2118934ec876bdc006923a5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jun 2022 14:51:44 +0800
+Subject: wifi: rtw89: 8852a: rfk: fix div 0 exception
+
+From: Ping-Ke Shih <pkshih@realtek.com>
+
+[ Upstream commit 683a4647a7a3044868cfdc14c117525091b9fa0c ]
+
+The DPK is a kind of RF calibration whose algorithm is to fine tune
+parameters and calibrate, and check the result. If the result isn't good
+enough, it could adjust parameters and try again.
+
+This issue is to read and show the result, but it could be a negative
+calibration result that causes divisor 0 and core dump. So, fix it by
+phy_div() that does division only if divisor isn't zero; otherwise,
+zero is adopted.
+
+ divide error: 0000 [#1] PREEMPT SMP NOPTI
+ CPU: 1 PID: 728 Comm: wpa_supplicant Not tainted 5.10.114-16019-g462a1661811a #1 <HASH:d024 28>
+ RIP: 0010:rtw8852a_dpk+0x14ae/0x288f [rtw89_core]
+ RSP: 0018:ffffa9bb412a7520 EFLAGS: 00010246
+ RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
+ RDX: 0000000000000000 RSI: 00000000000180fc RDI: ffffa141d01023c0
+ RBP: ffffa9bb412a76a0 R08: 0000000000001319 R09: 00000000ffffff92
+ R10: ffffffffc0292de3 R11: ffffffffc00d2f51 R12: 0000000000000000
+ R13: ffffa141d01023c0 R14: ffffffffc0290250 R15: ffffa141d0102638
+ FS: 00007fa99f5c2740(0000) GS:ffffa142e5e80000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 0000000013e8e010 CR3: 0000000110d2c000 CR4: 0000000000750ee0
+ PKRU: 55555554
+ Call Trace:
+ rtw89_core_sta_add+0x95/0x9c [rtw89_core <HASH:d239 29>]
+ rtw89_ops_sta_state+0x5d/0x108 [rtw89_core <HASH:d239 29>]
+ drv_sta_state+0x115/0x66f [mac80211 <HASH:81fe 30>]
+ sta_info_insert_rcu+0x45c/0x713 [mac80211 <HASH:81fe 30>]
+ sta_info_insert+0xf/0x1b [mac80211 <HASH:81fe 30>]
+ ieee80211_prep_connection+0x9d6/0xb0c [mac80211 <HASH:81fe 30>]
+ ieee80211_mgd_auth+0x2aa/0x352 [mac80211 <HASH:81fe 30>]
+ cfg80211_mlme_auth+0x160/0x1f6 [cfg80211 <HASH:00cd 31>]
+ nl80211_authenticate+0x2e5/0x306 [cfg80211 <HASH:00cd 31>]
+ genl_rcv_msg+0x371/0x3a1
+ ? nl80211_stop_sched_scan+0xe5/0xe5 [cfg80211 <HASH:00cd 31>]
+ ? genl_rcv+0x36/0x36
+ netlink_rcv_skb+0x8a/0xf9
+ genl_rcv+0x28/0x36
+ netlink_unicast+0x27b/0x3a0
+ netlink_sendmsg+0x2aa/0x469
+ sock_sendmsg_nosec+0x49/0x4d
+ ____sys_sendmsg+0xe5/0x213
+ __sys_sendmsg+0xec/0x157
+ ? syscall_enter_from_user_mode+0xd7/0x116
+ do_syscall_64+0x43/0x55
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+ RIP: 0033:0x7fa99f6e689b
+
+Fixes: e3ec7017f6a2 ("rtw89: add Realtek 802.11ax driver")
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220613065144.15647-1-pkshih@realtek.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
+index ad272854c442..8e4869eb3a24 100644
+--- a/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
++++ b/drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
+@@ -2330,8 +2330,8 @@ static u8 _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check)
+ val2_q = abs(sign_extend32(val2_q, 11));
+
+ rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n",
+- (val1_i * val1_i + val1_q * val1_q) /
+- (val2_i * val2_i + val2_q * val2_q));
++ phy_div(val1_i * val1_i + val1_q * val1_q,
++ val2_i * val2_i + val2_q * val2_q));
+
+ } else {
+ for (i = 0; i < 32; i++) {
+--
+2.35.1
+
--- /dev/null
+From 7c235c9e5fdbbaf9cda214421212ae999338d161 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Jul 2022 13:35:18 +0300
+Subject: wifi: wil6210: debugfs: fix info leak in wil_write_file_wmi()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 7a4836560a6198d245d5732e26f94898b12eb760 ]
+
+The simple_write_to_buffer() function will succeed if even a single
+byte is initialized. However, we need to initialize the whole buffer
+to prevent information leaks. Just use memdup_user().
+
+Fixes: ff974e408334 ("wil6210: debugfs interface to send raw WMI command")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/Ysg14NdKAZF/hcNG@kili
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/wil6210/debugfs.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
+index 4c944e595978..c6f8254cb21d 100644
+--- a/drivers/net/wireless/ath/wil6210/debugfs.c
++++ b/drivers/net/wireless/ath/wil6210/debugfs.c
+@@ -1012,18 +1012,12 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
+ u16 cmdid;
+ int rc, rc1;
+
+- if (cmdlen < 0)
++ if (cmdlen < 0 || *ppos != 0)
+ return -EINVAL;
+
+- wmi = kmalloc(len, GFP_KERNEL);
+- if (!wmi)
+- return -ENOMEM;
+-
+- rc = simple_write_to_buffer(wmi, len, ppos, buf, len);
+- if (rc < 0) {
+- kfree(wmi);
+- return rc;
+- }
++ wmi = memdup_user(buf, len);
++ if (IS_ERR(wmi))
++ return PTR_ERR(wmi);
+
+ cmd = (cmdlen > 0) ? &wmi[1] : NULL;
+ cmdid = le16_to_cpu(wmi->command_id);
+--
+2.35.1
+
--- /dev/null
+From c498eda1c434822422f95c6f7422371f6b5b8cf1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Jul 2022 20:49:11 +0300
+Subject: wifi: wil6210: debugfs: fix uninitialized variable use in
+ `wil_write_file_wmi()`
+
+From: Ammar Faizi <ammarfaizi2@gnuweeb.org>
+
+[ Upstream commit d578e0af3a003736f6c440188b156483d451b329 ]
+
+Commit 7a4836560a61 changes simple_write_to_buffer() with memdup_user()
+but it forgets to change the value to be returned that came from
+simple_write_to_buffer() call. It results in the following warning:
+
+ warning: variable 'rc' is uninitialized when used here [-Wuninitialized]
+ return rc;
+ ^~
+
+Remove rc variable and just return the passed in length if the
+memdup_user() succeeds.
+
+Cc: Dan Carpenter <dan.carpenter@oracle.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: 7a4836560a6198d245d5732e26f94898b12eb760 ("wifi: wil6210: debugfs: fix info leak in wil_write_file_wmi()")
+Fixes: ff974e4083341383d3dd4079e52ed30f57f376f0 ("wil6210: debugfs interface to send raw WMI command")
+Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org>
+Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20220724202452.61846-1-ammar.faizi@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/wil6210/debugfs.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
+index c6f8254cb21d..ac7787e1a7f6 100644
+--- a/drivers/net/wireless/ath/wil6210/debugfs.c
++++ b/drivers/net/wireless/ath/wil6210/debugfs.c
+@@ -1010,7 +1010,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
+ void *cmd;
+ int cmdlen = len - sizeof(struct wmi_cmd_hdr);
+ u16 cmdid;
+- int rc, rc1;
++ int rc1;
+
+ if (cmdlen < 0 || *ppos != 0)
+ return -EINVAL;
+@@ -1027,7 +1027,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
+
+ wil_info(wil, "0x%04x[%d] -> %d\n", cmdid, cmdlen, rc1);
+
+- return rc;
++ return len;
+ }
+
+ static const struct file_operations fops_wmi = {
+--
+2.35.1
+
--- /dev/null
+From 5a0baebc3f3394449fe325793e4949aa1858de04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 May 2022 12:06:19 +0000
+Subject: wifi: wilc1000: use correct sequence of RESET for chip Power-UP/Down
+
+From: Ajay Singh <ajay.kathat@microchip.com>
+
+[ Upstream commit fcf690b0b47494df51d214db5c5a714a400b0257 ]
+
+For power-up sequence, WILC expects RESET set to high 5ms after making
+chip_en(enable) so corrected chip power-up sequence by making RESET high.
+For Power-Down sequence, the correct sequence make RESET and CHIP_EN low
+without any extra delay.
+
+Fixes: ec031ac4792c ("wilc1000: Add reset/enable GPIO support to SPI driver")
+Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20220524120606.9675-1-ajay.kathat@microchip.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/microchip/wilc1000/spi.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c
+index 18420e954402..2ae8dd3411ac 100644
+--- a/drivers/net/wireless/microchip/wilc1000/spi.c
++++ b/drivers/net/wireless/microchip/wilc1000/spi.c
+@@ -191,11 +191,11 @@ static void wilc_wlan_power(struct wilc *wilc, bool on)
+ /* assert ENABLE: */
+ gpiod_set_value(gpios->enable, 1);
+ mdelay(5);
+- /* deassert RESET: */
+- gpiod_set_value(gpios->reset, 0);
+- } else {
+ /* assert RESET: */
+ gpiod_set_value(gpios->reset, 1);
++ } else {
++ /* deassert RESET: */
++ gpiod_set_value(gpios->reset, 0);
+ /* deassert ENABLE: */
+ gpiod_set_value(gpios->enable, 0);
+ }
+--
+2.35.1
+
--- /dev/null
+From 0853f0248910af49297f57bbd9766b89b486523b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 14:56:12 +0200
+Subject: wireguard: allowedips: don't corrupt stack when detecting overflow
+
+From: Jason A. Donenfeld <Jason@zx2c4.com>
+
+[ Upstream commit c31b14d86dfe7174361e8c6e5df6c2c3a4d5918c ]
+
+In case push_rcu() and related functions are buggy, there's a
+WARN_ON(len >= 128), which the selftest tries to hit by being tricky. In
+case it is hit, we shouldn't corrupt the kernel's stack, though;
+otherwise it may be hard to even receive the report that it's buggy. So
+conditionalize the stack write based on that WARN_ON()'s return value.
+
+Note that this never *actually* happens anyway. The WARN_ON() in the
+first place is bounded by IS_ENABLED(DEBUG), and isn't expected to ever
+actually hit. This is just a debugging sanity check.
+
+Additionally, hoist the constant 128 into a named enum,
+MAX_ALLOWEDIPS_BITS, so that it's clear why this value is chosen.
+
+Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/all/CAHk-=wjJZGA6w_DxA+k7Ejbqsq+uGK==koPai3sqdsfJqemvag@mail.gmail.com/
+Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireguard/allowedips.c | 9 ++++++---
+ drivers/net/wireguard/selftest/allowedips.c | 6 +++---
+ 2 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireguard/allowedips.c b/drivers/net/wireguard/allowedips.c
+index 9a4c8ff32d9d..5bf7822c53f1 100644
+--- a/drivers/net/wireguard/allowedips.c
++++ b/drivers/net/wireguard/allowedips.c
+@@ -6,6 +6,8 @@
+ #include "allowedips.h"
+ #include "peer.h"
+
++enum { MAX_ALLOWEDIPS_BITS = 128 };
++
+ static struct kmem_cache *node_cache;
+
+ static void swap_endian(u8 *dst, const u8 *src, u8 bits)
+@@ -40,7 +42,8 @@ static void push_rcu(struct allowedips_node **stack,
+ struct allowedips_node __rcu *p, unsigned int *len)
+ {
+ if (rcu_access_pointer(p)) {
+- WARN_ON(IS_ENABLED(DEBUG) && *len >= 128);
++ if (WARN_ON(IS_ENABLED(DEBUG) && *len >= MAX_ALLOWEDIPS_BITS))
++ return;
+ stack[(*len)++] = rcu_dereference_raw(p);
+ }
+ }
+@@ -52,7 +55,7 @@ static void node_free_rcu(struct rcu_head *rcu)
+
+ static void root_free_rcu(struct rcu_head *rcu)
+ {
+- struct allowedips_node *node, *stack[128] = {
++ struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = {
+ container_of(rcu, struct allowedips_node, rcu) };
+ unsigned int len = 1;
+
+@@ -65,7 +68,7 @@ static void root_free_rcu(struct rcu_head *rcu)
+
+ static void root_remove_peer_lists(struct allowedips_node *root)
+ {
+- struct allowedips_node *node, *stack[128] = { root };
++ struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = { root };
+ unsigned int len = 1;
+
+ while (len > 0 && (node = stack[--len])) {
+diff --git a/drivers/net/wireguard/selftest/allowedips.c b/drivers/net/wireguard/selftest/allowedips.c
+index e173204ae7d7..41db10f9be49 100644
+--- a/drivers/net/wireguard/selftest/allowedips.c
++++ b/drivers/net/wireguard/selftest/allowedips.c
+@@ -593,10 +593,10 @@ bool __init wg_allowedips_selftest(void)
+ wg_allowedips_remove_by_peer(&t, a, &mutex);
+ test_negative(4, a, 192, 168, 0, 1);
+
+- /* These will hit the WARN_ON(len >= 128) in free_node if something
+- * goes wrong.
++ /* These will hit the WARN_ON(len >= MAX_ALLOWEDIPS_BITS) in free_node
++ * if something goes wrong.
+ */
+- for (i = 0; i < 128; ++i) {
++ for (i = 0; i < MAX_ALLOWEDIPS_BITS; ++i) {
+ part = cpu_to_be64(~(1LLU << (i % 64)));
+ memset(&ip, 0xff, 16);
+ memcpy((u8 *)&ip + (i < 64) * 8, &part, 8);
+--
+2.35.1
+
--- /dev/null
+From b140a04c8b167d13ce1212d13c9efb3070c45a71 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 14:56:10 +0200
+Subject: wireguard: ratelimiter: use hrtimer in selftest
+
+From: Jason A. Donenfeld <Jason@zx2c4.com>
+
+[ Upstream commit 151c8e499f4705010780189377f85b57400ccbf5 ]
+
+Using msleep() is problematic because it's compared against
+ratelimiter.c's ktime_get_coarse_boottime_ns(), which means on systems
+with slow jiffies (such as UML's forced HZ=100), the result is
+inaccurate. So switch to using schedule_hrtimeout().
+
+However, hrtimer gives us access only to the traditional posix timers,
+and none of the _COARSE variants. So now, rather than being too
+imprecise like jiffies, it's too precise.
+
+One solution would be to give it a large "range" value, but this will
+still fire early on a loaded system. A better solution is to align the
+timeout to the actual coarse timer, and then round up to the nearest
+tick, plus change.
+
+So add the timeout to the current coarse time, and then
+schedule_hrtimer() until the absolute computed time.
+
+This should hopefully reduce flakes in CI as well. Note that we keep the
+retry loop in case the entire function is running behind, because the
+test could still be scheduled out, by either the kernel or by the
+hypervisor's kernel, in which case restarting the test and hoping to not
+be scheduled out still helps.
+
+Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireguard/selftest/ratelimiter.c | 25 +++++++++++---------
+ kernel/time/hrtimer.c | 1 +
+ 2 files changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/wireguard/selftest/ratelimiter.c b/drivers/net/wireguard/selftest/ratelimiter.c
+index 007cd4457c5f..ba87d294604f 100644
+--- a/drivers/net/wireguard/selftest/ratelimiter.c
++++ b/drivers/net/wireguard/selftest/ratelimiter.c
+@@ -6,28 +6,29 @@
+ #ifdef DEBUG
+
+ #include <linux/jiffies.h>
++#include <linux/hrtimer.h>
+
+ static const struct {
+ bool result;
+- unsigned int msec_to_sleep_before;
++ u64 nsec_to_sleep_before;
+ } expected_results[] __initconst = {
+ [0 ... PACKETS_BURSTABLE - 1] = { true, 0 },
+ [PACKETS_BURSTABLE] = { false, 0 },
+- [PACKETS_BURSTABLE + 1] = { true, MSEC_PER_SEC / PACKETS_PER_SECOND },
++ [PACKETS_BURSTABLE + 1] = { true, NSEC_PER_SEC / PACKETS_PER_SECOND },
+ [PACKETS_BURSTABLE + 2] = { false, 0 },
+- [PACKETS_BURSTABLE + 3] = { true, (MSEC_PER_SEC / PACKETS_PER_SECOND) * 2 },
++ [PACKETS_BURSTABLE + 3] = { true, (NSEC_PER_SEC / PACKETS_PER_SECOND) * 2 },
+ [PACKETS_BURSTABLE + 4] = { true, 0 },
+ [PACKETS_BURSTABLE + 5] = { false, 0 }
+ };
+
+ static __init unsigned int maximum_jiffies_at_index(int index)
+ {
+- unsigned int total_msecs = 2 * MSEC_PER_SEC / PACKETS_PER_SECOND / 3;
++ u64 total_nsecs = 2 * NSEC_PER_SEC / PACKETS_PER_SECOND / 3;
+ int i;
+
+ for (i = 0; i <= index; ++i)
+- total_msecs += expected_results[i].msec_to_sleep_before;
+- return msecs_to_jiffies(total_msecs);
++ total_nsecs += expected_results[i].nsec_to_sleep_before;
++ return nsecs_to_jiffies(total_nsecs);
+ }
+
+ static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
+@@ -42,8 +43,12 @@ static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
+ loop_start_time = jiffies;
+
+ for (i = 0; i < ARRAY_SIZE(expected_results); ++i) {
+- if (expected_results[i].msec_to_sleep_before)
+- msleep(expected_results[i].msec_to_sleep_before);
++ if (expected_results[i].nsec_to_sleep_before) {
++ ktime_t timeout = ktime_add(ktime_add_ns(ktime_get_coarse_boottime(), TICK_NSEC * 4 / 3),
++ ns_to_ktime(expected_results[i].nsec_to_sleep_before));
++ set_current_state(TASK_UNINTERRUPTIBLE);
++ schedule_hrtimeout_range_clock(&timeout, 0, HRTIMER_MODE_ABS, CLOCK_BOOTTIME);
++ }
+
+ if (time_is_before_jiffies(loop_start_time +
+ maximum_jiffies_at_index(i)))
+@@ -127,7 +132,7 @@ bool __init wg_ratelimiter_selftest(void)
+ if (IS_ENABLED(CONFIG_KASAN) || IS_ENABLED(CONFIG_UBSAN))
+ return true;
+
+- BUILD_BUG_ON(MSEC_PER_SEC % PACKETS_PER_SECOND != 0);
++ BUILD_BUG_ON(NSEC_PER_SEC % PACKETS_PER_SECOND != 0);
+
+ if (wg_ratelimiter_init())
+ goto out;
+@@ -176,7 +181,6 @@ bool __init wg_ratelimiter_selftest(void)
+ test += test_count;
+ goto err;
+ }
+- msleep(500);
+ continue;
+ } else if (ret < 0) {
+ test += test_count;
+@@ -195,7 +199,6 @@ bool __init wg_ratelimiter_selftest(void)
+ test += test_count;
+ goto err;
+ }
+- msleep(50);
+ continue;
+ }
+ test += test_count;
+diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
+index 0ea8702eb516..23af5eca11b1 100644
+--- a/kernel/time/hrtimer.c
++++ b/kernel/time/hrtimer.c
+@@ -2311,6 +2311,7 @@ schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta,
+
+ return !t.task ? 0 : -EINTR;
+ }
++EXPORT_SYMBOL_GPL(schedule_hrtimeout_range_clock);
+
+ /**
+ * schedule_hrtimeout_range - sleep until timeout
+--
+2.35.1
+
--- /dev/null
+From fc314d7a5dc18b5c09cdfbfcf6cbf8ed328495ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Aug 2022 11:32:06 +0800
+Subject: x86/bus_lock: Don't assume the init value of
+ DEBUGCTLMSR.BUS_LOCK_DETECT to be zero
+
+From: Chenyi Qiang <chenyi.qiang@intel.com>
+
+[ Upstream commit ffa6482e461ff550325356ae705b79e256702ea9 ]
+
+It's possible that this kernel has been kexec'd from a kernel that
+enabled bus lock detection, or (hypothetically) BIOS/firmware has set
+DEBUGCTLMSR_BUS_LOCK_DETECT.
+
+Disable bus lock detection explicitly if not wanted.
+
+Fixes: ebb1064e7c2e ("x86/traps: Handle #DB for bus lock")
+Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Tony Luck <tony.luck@intel.com>
+Link: https://lore.kernel.org/r/20220802033206.21333-1-chenyi.qiang@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/intel.c | 27 ++++++++++++++-------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
+index 2c87d62f191e..ae7d4c85f4f4 100644
+--- a/arch/x86/kernel/cpu/intel.c
++++ b/arch/x86/kernel/cpu/intel.c
+@@ -1145,22 +1145,23 @@ static void bus_lock_init(void)
+ {
+ u64 val;
+
+- /*
+- * Warn and fatal are handled by #AC for split lock if #AC for
+- * split lock is supported.
+- */
+- if (!boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT) ||
+- (boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT) &&
+- (sld_state == sld_warn || sld_state == sld_fatal)) ||
+- sld_state == sld_off)
++ if (!boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT))
+ return;
+
+- /*
+- * Enable #DB for bus lock. All bus locks are handled in #DB except
+- * split locks are handled in #AC in the fatal case.
+- */
+ rdmsrl(MSR_IA32_DEBUGCTLMSR, val);
+- val |= DEBUGCTLMSR_BUS_LOCK_DETECT;
++
++ if ((boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT) &&
++ (sld_state == sld_warn || sld_state == sld_fatal)) ||
++ sld_state == sld_off) {
++ /*
++ * Warn and fatal are handled by #AC for split lock if #AC for
++ * split lock is supported.
++ */
++ val &= ~DEBUGCTLMSR_BUS_LOCK_DETECT;
++ } else {
++ val |= DEBUGCTLMSR_BUS_LOCK_DETECT;
++ }
++
+ wrmsrl(MSR_IA32_DEBUGCTLMSR, val);
+ }
+
+--
+2.35.1
+
--- /dev/null
+From 871862bfa640a6ad2ab4ee1b6f75329213ea7c95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 09:49:15 +0200
+Subject: x86/entry: Build thunk_$(BITS) only if CONFIG_PREEMPTION=y
+
+From: Andrea Righi <andrea.righi@canonical.com>
+
+[ Upstream commit de979c83574abf6e78f3fa65b716515c91b2613d ]
+
+With CONFIG_PREEMPTION disabled, arch/x86/entry/thunk_$(BITS).o becomes
+an empty object file.
+
+With some old versions of binutils (i.e., 2.35.90.20210113-1ubuntu1) the
+GNU assembler doesn't generate a symbol table for empty object files and
+objtool fails with the following error when a valid symbol table cannot
+be found:
+
+ arch/x86/entry/thunk_64.o: warning: objtool: missing symbol table
+
+To prevent this from happening, build thunk_$(BITS).o only if
+CONFIG_PREEMPTION is enabled.
+
+BugLink: https://bugs.launchpad.net/bugs/1911359
+
+Fixes: 320100a5ffe5 ("x86/entry: Remove the TRACE_IRQS cruft")
+Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/Ys/Ke7EWjcX+ZlXO@arighi-desktop
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/entry/Makefile | 3 ++-
+ arch/x86/entry/thunk_32.S | 2 --
+ arch/x86/entry/thunk_64.S | 4 ----
+ arch/x86/um/Makefile | 3 ++-
+ 4 files changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/arch/x86/entry/Makefile b/arch/x86/entry/Makefile
+index eeadbd7d92cc..ca2fe186994b 100644
+--- a/arch/x86/entry/Makefile
++++ b/arch/x86/entry/Makefile
+@@ -11,12 +11,13 @@ CFLAGS_REMOVE_common.o = $(CC_FLAGS_FTRACE)
+
+ CFLAGS_common.o += -fno-stack-protector
+
+-obj-y := entry.o entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o
++obj-y := entry.o entry_$(BITS).o syscall_$(BITS).o
+ obj-y += common.o
+
+ obj-y += vdso/
+ obj-y += vsyscall/
+
++obj-$(CONFIG_PREEMPTION) += thunk_$(BITS).o
+ obj-$(CONFIG_IA32_EMULATION) += entry_64_compat.o syscall_32.o
+ obj-$(CONFIG_X86_X32_ABI) += syscall_x32.o
+
+diff --git a/arch/x86/entry/thunk_32.S b/arch/x86/entry/thunk_32.S
+index 7591bab060f7..ff6e7003da97 100644
+--- a/arch/x86/entry/thunk_32.S
++++ b/arch/x86/entry/thunk_32.S
+@@ -29,10 +29,8 @@ SYM_CODE_START_NOALIGN(\name)
+ SYM_CODE_END(\name)
+ .endm
+
+-#ifdef CONFIG_PREEMPTION
+ THUNK preempt_schedule_thunk, preempt_schedule
+ THUNK preempt_schedule_notrace_thunk, preempt_schedule_notrace
+ EXPORT_SYMBOL(preempt_schedule_thunk)
+ EXPORT_SYMBOL(preempt_schedule_notrace_thunk)
+-#endif
+
+diff --git a/arch/x86/entry/thunk_64.S b/arch/x86/entry/thunk_64.S
+index 505b488fcc65..f38b07d2768b 100644
+--- a/arch/x86/entry/thunk_64.S
++++ b/arch/x86/entry/thunk_64.S
+@@ -31,14 +31,11 @@ SYM_FUNC_END(\name)
+ _ASM_NOKPROBE(\name)
+ .endm
+
+-#ifdef CONFIG_PREEMPTION
+ THUNK preempt_schedule_thunk, preempt_schedule
+ THUNK preempt_schedule_notrace_thunk, preempt_schedule_notrace
+ EXPORT_SYMBOL(preempt_schedule_thunk)
+ EXPORT_SYMBOL(preempt_schedule_notrace_thunk)
+-#endif
+
+-#ifdef CONFIG_PREEMPTION
+ SYM_CODE_START_LOCAL_NOALIGN(__thunk_restore)
+ popq %r11
+ popq %r10
+@@ -53,4 +50,3 @@ SYM_CODE_START_LOCAL_NOALIGN(__thunk_restore)
+ RET
+ _ASM_NOKPROBE(__thunk_restore)
+ SYM_CODE_END(__thunk_restore)
+-#endif
+diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile
+index ba5789c35809..a8cde4e8ab11 100644
+--- a/arch/x86/um/Makefile
++++ b/arch/x86/um/Makefile
+@@ -28,7 +28,8 @@ else
+
+ obj-y += syscalls_64.o vdso/
+
+-subarch-y = ../lib/csum-partial_64.o ../lib/memcpy_64.o ../entry/thunk_64.o
++subarch-y = ../lib/csum-partial_64.o ../lib/memcpy_64.o
++subarch-$(CONFIG_PREEMPTION) += ../entry/thunk_64.o
+
+ endif
+
+--
+2.35.1
+
--- /dev/null
+From cc17f93d62a2ac833e705f7bfd2676d91ce8a02e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jun 2022 16:52:06 +0200
+Subject: x86/extable: Fix ex_handler_msr() print condition
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit a1a5482a2c6e38a3ebed32e571625c56a8cc41a6 ]
+
+On Fri, Jun 17, 2022 at 02:08:52PM +0300, Stephane Eranian wrote:
+> Some changes to the way invalid MSR accesses are reported by the
+> kernel is causing some problems with messages printed on the
+> console.
+>
+> We have seen several cases of ex_handler_msr() printing invalid MSR
+> accesses once but the callstack multiple times causing confusion on
+> the console.
+
+> The problem here is that another earlier commit (5.13):
+>
+> a358f40600b3 ("once: implement DO_ONCE_LITE for non-fast-path "do once" functionality")
+>
+> Modifies all the pr_*_once() calls to always return true claiming
+> that no caller is ever checking the return value of the functions.
+>
+> This is why we are seeing the callstack printed without the
+> associated printk() msg.
+
+Extract the ONCE_IF(cond) part into __ONCE_LTE_IF() and use that to
+implement DO_ONCE_LITE_IF() and fix the extable code.
+
+Fixes: a358f40600b3 ("once: implement DO_ONCE_LITE for non-fast-path "do once" functionality")
+Reported-by: Stephane Eranian <eranian@google.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Tested-by: Stephane Eranian <eranian@google.com>
+Link: https://lkml.kernel.org/r/YqyVFsbviKjVGGZ9@worktop.programming.kicks-ass.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/mm/extable.c | 16 +++++++++-------
+ include/linux/once_lite.h | 20 ++++++++++++++++----
+ 2 files changed, 25 insertions(+), 11 deletions(-)
+
+diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
+index dba2197c05c3..331310c29349 100644
+--- a/arch/x86/mm/extable.c
++++ b/arch/x86/mm/extable.c
+@@ -94,16 +94,18 @@ static bool ex_handler_copy(const struct exception_table_entry *fixup,
+ static bool ex_handler_msr(const struct exception_table_entry *fixup,
+ struct pt_regs *regs, bool wrmsr, bool safe, int reg)
+ {
+- if (!safe && wrmsr &&
+- pr_warn_once("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
+- (unsigned int)regs->cx, (unsigned int)regs->dx,
+- (unsigned int)regs->ax, regs->ip, (void *)regs->ip))
++ if (__ONCE_LITE_IF(!safe && wrmsr)) {
++ pr_warn("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
++ (unsigned int)regs->cx, (unsigned int)regs->dx,
++ (unsigned int)regs->ax, regs->ip, (void *)regs->ip);
+ show_stack_regs(regs);
++ }
+
+- if (!safe && !wrmsr &&
+- pr_warn_once("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
+- (unsigned int)regs->cx, regs->ip, (void *)regs->ip))
++ if (__ONCE_LITE_IF(!safe && !wrmsr)) {
++ pr_warn("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
++ (unsigned int)regs->cx, regs->ip, (void *)regs->ip);
+ show_stack_regs(regs);
++ }
+
+ if (!wrmsr) {
+ /* Pretend that the read succeeded and returned 0. */
+diff --git a/include/linux/once_lite.h b/include/linux/once_lite.h
+index 861e606b820f..b7bce4983638 100644
+--- a/include/linux/once_lite.h
++++ b/include/linux/once_lite.h
+@@ -9,15 +9,27 @@
+ */
+ #define DO_ONCE_LITE(func, ...) \
+ DO_ONCE_LITE_IF(true, func, ##__VA_ARGS__)
+-#define DO_ONCE_LITE_IF(condition, func, ...) \
++
++#define __ONCE_LITE_IF(condition) \
+ ({ \
+ static bool __section(".data.once") __already_done; \
+- bool __ret_do_once = !!(condition); \
++ bool __ret_cond = !!(condition); \
++ bool __ret_once = false; \
+ \
+- if (unlikely(__ret_do_once && !__already_done)) { \
++ if (unlikely(__ret_cond && !__already_done)) { \
+ __already_done = true; \
+- func(__VA_ARGS__); \
++ __ret_once = true; \
+ } \
++ unlikely(__ret_once); \
++ })
++
++#define DO_ONCE_LITE_IF(condition, func, ...) \
++ ({ \
++ bool __ret_do_once = !!(condition); \
++ \
++ if (__ONCE_LITE_IF(__ret_do_once)) \
++ func(__VA_ARGS__); \
++ \
+ unlikely(__ret_do_once); \
+ })
+
+--
+2.35.1
+
--- /dev/null
+From 41fe7ce8158905de369241e413b122b6e045835c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Jun 2022 23:33:34 +0530
+Subject: x86: Handle idle=nomwait cmdline properly for x86_idle
+
+From: Wyes Karny <wyes.karny@amd.com>
+
+[ Upstream commit 8bcedb4ce04750e1ccc9a6b6433387f6a9166a56 ]
+
+When kernel is booted with idle=nomwait do not use MWAIT as the
+default idle state.
+
+If the user boots the kernel with idle=nomwait, it is a clear
+direction to not use mwait as the default idle state.
+However, the current code does not take this into consideration
+while selecting the default idle state on x86.
+
+Fix it by checking for the idle=nomwait boot option in
+prefer_mwait_c1_over_halt().
+
+Also update the documentation around idle=nomwait appropriately.
+
+[ dhansen: tweak commit message ]
+
+Signed-off-by: Wyes Karny <wyes.karny@amd.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Tested-by: Zhang Rui <rui.zhang@intel.com>
+Link: https://lkml.kernel.org/r/fdc2dc2d0a1bc21c2f53d989ea2d2ee3ccbc0dbe.1654538381.git-series.wyes.karny@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/admin-guide/pm/cpuidle.rst | 15 +++++++++------
+ arch/x86/kernel/process.c | 9 ++++++---
+ 2 files changed, 15 insertions(+), 9 deletions(-)
+
+diff --git a/Documentation/admin-guide/pm/cpuidle.rst b/Documentation/admin-guide/pm/cpuidle.rst
+index aec2cd2aaea7..19754beb5a4e 100644
+--- a/Documentation/admin-guide/pm/cpuidle.rst
++++ b/Documentation/admin-guide/pm/cpuidle.rst
+@@ -612,8 +612,8 @@ the ``menu`` governor to be used on the systems that use the ``ladder`` governor
+ by default this way, for example.
+
+ The other kernel command line parameters controlling CPU idle time management
+-described below are only relevant for the *x86* architecture and some of
+-them affect Intel processors only.
++described below are only relevant for the *x86* architecture and references
++to ``intel_idle`` affect Intel processors only.
+
+ The *x86* architecture support code recognizes three kernel command line
+ options related to CPU idle time management: ``idle=poll``, ``idle=halt``,
+@@ -635,10 +635,13 @@ idle, so it very well may hurt single-thread computations performance as well as
+ energy-efficiency. Thus using it for performance reasons may not be a good idea
+ at all.]
+
+-The ``idle=nomwait`` option disables the ``intel_idle`` driver and causes
+-``acpi_idle`` to be used (as long as all of the information needed by it is
+-there in the system's ACPI tables), but it is not allowed to use the
+-``MWAIT`` instruction of the CPUs to ask the hardware to enter idle states.
++The ``idle=nomwait`` option prevents the use of ``MWAIT`` instruction of
++the CPU to enter idle states. When this option is used, the ``acpi_idle``
++driver will use the ``HLT`` instruction instead of ``MWAIT``. On systems
++running Intel processors, this option disables the ``intel_idle`` driver
++and forces the use of the ``acpi_idle`` driver instead. Note that in either
++case, ``acpi_idle`` driver will function only if all the information needed
++by it is in the system's ACPI tables.
+
+ In addition to the architecture-level kernel command line options affecting CPU
+ idle time management, there are parameters affecting individual ``CPUIdle``
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index 622dc3673c37..8011536ba5c4 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -824,6 +824,10 @@ static void amd_e400_idle(void)
+ */
+ static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c)
+ {
++ /* User has disallowed the use of MWAIT. Fallback to HALT */
++ if (boot_option_idle_override == IDLE_NOMWAIT)
++ return 0;
++
+ if (c->x86_vendor != X86_VENDOR_INTEL)
+ return 0;
+
+@@ -932,9 +936,8 @@ static int __init idle_setup(char *str)
+ } else if (!strcmp(str, "nomwait")) {
+ /*
+ * If the boot option of "idle=nomwait" is added,
+- * it means that mwait will be disabled for CPU C2/C3
+- * states. In such case it won't touch the variable
+- * of boot_option_idle_override.
++ * it means that mwait will be disabled for CPU C1/C2/C3
++ * states.
+ */
+ boot_option_idle_override = IDLE_NOMWAIT;
+ } else
+--
+2.35.1
+
--- /dev/null
+From 04aa9cb5ddbda596e3d97d0842cf58d0fa148cbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 Jul 2022 21:39:13 +0530
+Subject: x86/numa: Use cpumask_available instead of hardcoded NULL check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Siddh Raman Pant <code@siddh.me>
+
+[ Upstream commit 625395c4a0f4775e0fe00f616888d2e6c1ba49db ]
+
+GCC-12 started triggering a new warning:
+
+ arch/x86/mm/numa.c: In function ‘cpumask_of_node’:
+ arch/x86/mm/numa.c:916:39: warning: the comparison will always evaluate as ‘false’ for the address of ‘node_to_cpumask_map’ will never be NULL [-Waddress]
+ 916 | if (node_to_cpumask_map[node] == NULL) {
+ | ^~
+
+node_to_cpumask_map is of type cpumask_var_t[].
+
+When CONFIG_CPUMASK_OFFSTACK is set, cpumask_var_t is typedef'd to a
+pointer for dynamic allocation, else to an array of one element. The
+"wicked game" can be checked on line 700 of include/linux/cpumask.h.
+
+The original code in debug_cpumask_set_cpu() and cpumask_of_node() were
+probably written by the original authors with CONFIG_CPUMASK_OFFSTACK=y
+(i.e. dynamic allocation) in mind, checking if the cpumask was available
+via a direct NULL check.
+
+When CONFIG_CPUMASK_OFFSTACK is not set, GCC gives the above warning
+while compiling the kernel.
+
+Fix that by using cpumask_available(), which does the NULL check when
+CONFIG_CPUMASK_OFFSTACK is set, otherwise returns true. Use it wherever
+such checks are made.
+
+Conditional definitions of cpumask_available() can be found along with
+the definition of cpumask_var_t. Check the cpumask.h reference mentioned
+above.
+
+Fixes: c032ef60d1aa ("cpumask: convert node_to_cpumask_map[] to cpumask_var_t")
+Fixes: de2d9445f162 ("x86: Unify node_to_cpumask_map handling between 32 and 64bit")
+Signed-off-by: Siddh Raman Pant <code@siddh.me>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/20220731160913.632092-1-code@siddh.me
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/mm/numa.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
+index e8b061557887..2aadb2019b4f 100644
+--- a/arch/x86/mm/numa.c
++++ b/arch/x86/mm/numa.c
+@@ -867,7 +867,7 @@ void debug_cpumask_set_cpu(int cpu, int node, bool enable)
+ return;
+ }
+ mask = node_to_cpumask_map[node];
+- if (!mask) {
++ if (!cpumask_available(mask)) {
+ pr_err("node_to_cpumask_map[%i] NULL\n", node);
+ dump_stack();
+ return;
+@@ -913,7 +913,7 @@ const struct cpumask *cpumask_of_node(int node)
+ dump_stack();
+ return cpu_none_mask;
+ }
+- if (node_to_cpumask_map[node] == NULL) {
++ if (!cpumask_available(node_to_cpumask_map[node])) {
+ printk(KERN_WARNING
+ "cpumask_of_node(%d): no node_to_cpumask_map!\n",
+ node);
+--
+2.35.1
+
--- /dev/null
+From f6754ed062b6f1fe6a392794533cad24e3cb7530 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 16:07:23 +0200
+Subject: x86/pmem: Fix platform-device leak in error path
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 229e73d46994f15314f58b2d39bf952111d89193 ]
+
+Make sure to free the platform device in the unlikely event that
+registration fails.
+
+Fixes: 7a67832c7e44 ("libnvdimm, e820: make CONFIG_X86_PMEM_LEGACY a tristate option")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Link: https://lore.kernel.org/r/20220620140723.9810-1-johan@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/pmem.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/pmem.c b/arch/x86/kernel/pmem.c
+index 6b07faaa1579..23154d24b117 100644
+--- a/arch/x86/kernel/pmem.c
++++ b/arch/x86/kernel/pmem.c
+@@ -27,6 +27,11 @@ static __init int register_e820_pmem(void)
+ * simply here to trigger the module to load on demand.
+ */
+ pdev = platform_device_alloc("e820_pmem", -1);
+- return platform_device_add(pdev);
++
++ rc = platform_device_add(pdev);
++ if (rc)
++ platform_device_put(pdev);
++
++ return rc;
+ }
+ device_initcall(register_e820_pmem);
+--
+2.35.1
+
--- /dev/null
+From 81a3c894d83ff0be45639b7839eb3db94c4a579b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 10:32:29 +0800
+Subject: xtensa: iss: fix handling error cases in iss_net_configure()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 628ccfc8f5f79dd548319408fcc53949fe97b258 ]
+
+The 'pdev' and 'netdev' need to be released in error cases of
+iss_net_configure().
+
+Change the return type of iss_net_configure() to void, because it's
+not used.
+
+Fixes: 7282bee78798 ("[PATCH] xtensa: Architecture support for Tensilica Xtensa Part 8")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/xtensa/platforms/iss/network.c | 32 ++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 17 deletions(-)
+
+diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c
+index 24f162bd5874..eee389187807 100644
+--- a/arch/xtensa/platforms/iss/network.c
++++ b/arch/xtensa/platforms/iss/network.c
+@@ -512,16 +512,15 @@ static void iss_net_pdev_release(struct device *dev)
+ free_netdev(lp->dev);
+ }
+
+-static int iss_net_configure(int index, char *init)
++static void iss_net_configure(int index, char *init)
+ {
+ struct net_device *dev;
+ struct iss_net_private *lp;
+- int err;
+
+ dev = alloc_etherdev(sizeof(*lp));
+ if (dev == NULL) {
+ pr_err("eth_configure: failed to allocate device\n");
+- return 1;
++ return;
+ }
+
+ /* Initialize private element. */
+@@ -550,7 +549,7 @@ static int iss_net_configure(int index, char *init)
+ if (!tuntap_probe(lp, index, init)) {
+ pr_err("%s: invalid arguments. Skipping device!\n",
+ dev->name);
+- goto errout;
++ goto err_free_netdev;
+ }
+
+ pr_info("Netdevice %d (%pM)\n", index, dev->dev_addr);
+@@ -558,7 +557,8 @@ static int iss_net_configure(int index, char *init)
+ /* sysfs register */
+
+ if (!driver_registered) {
+- platform_driver_register(&iss_net_driver);
++ if (platform_driver_register(&iss_net_driver))
++ goto err_free_netdev;
+ driver_registered = 1;
+ }
+
+@@ -569,7 +569,8 @@ static int iss_net_configure(int index, char *init)
+ lp->pdev.id = index;
+ lp->pdev.name = DRIVER_NAME;
+ lp->pdev.dev.release = iss_net_pdev_release;
+- platform_device_register(&lp->pdev);
++ if (platform_device_register(&lp->pdev))
++ goto err_free_netdev;
+ SET_NETDEV_DEV(dev, &lp->pdev.dev);
+
+ dev->netdev_ops = &iss_netdev_ops;
+@@ -578,23 +579,20 @@ static int iss_net_configure(int index, char *init)
+ dev->irq = -1;
+
+ rtnl_lock();
+- err = register_netdevice(dev);
+- rtnl_unlock();
+-
+- if (err) {
++ if (register_netdevice(dev)) {
++ rtnl_unlock();
+ pr_err("%s: error registering net device!\n", dev->name);
+- /* XXX: should we call ->remove() here? */
+- free_netdev(dev);
+- return 1;
++ platform_device_unregister(&lp->pdev);
++ return;
+ }
++ rtnl_unlock();
+
+ timer_setup(&lp->tl, iss_net_user_timer_expire, 0);
+
+- return 0;
++ return;
+
+-errout:
+- /* FIXME: unregister; free, etc.. */
+- return -EIO;
++err_free_netdev:
++ free_netdev(dev);
+ }
+
+ /* ------------------------------------------------------------------------- */
+--
+2.35.1
+
--- /dev/null
+From d0ea2dcba6b2908997f71a68f3269fffc93b879b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 00:23:16 -0700
+Subject: xtensa: iss/network: provide release() callback
+
+From: Max Filippov <jcmvbkbc@gmail.com>
+
+[ Upstream commit 8864fb8359682912ee99235db7db916733a1fd7b ]
+
+Provide release() callback for the platform device embedded into struct
+iss_net_private and registered in the iss_net_configure so that
+platform_device_unregister could be called for it.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/xtensa/platforms/iss/network.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c
+index be3aaaad8bee..24f162bd5874 100644
+--- a/arch/xtensa/platforms/iss/network.c
++++ b/arch/xtensa/platforms/iss/network.c
+@@ -503,6 +503,15 @@ static const struct net_device_ops iss_netdev_ops = {
+ .ndo_set_rx_mode = iss_net_set_multicast_list,
+ };
+
++static void iss_net_pdev_release(struct device *dev)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct iss_net_private *lp =
++ container_of(pdev, struct iss_net_private, pdev);
++
++ free_netdev(lp->dev);
++}
++
+ static int iss_net_configure(int index, char *init)
+ {
+ struct net_device *dev;
+@@ -559,6 +568,7 @@ static int iss_net_configure(int index, char *init)
+
+ lp->pdev.id = index;
+ lp->pdev.name = DRIVER_NAME;
++ lp->pdev.dev.release = iss_net_pdev_release;
+ platform_device_register(&lp->pdev);
+ SET_NETDEV_DEV(dev, &lp->pdev.dev);
+
+--
+2.35.1
+