]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.10
authorSasha Levin <sashal@kernel.org>
Sat, 26 Apr 2025 13:23:11 +0000 (09:23 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 26 Apr 2025 13:23:11 +0000 (09:23 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
43 files changed:
queue-5.10/backlight-led_bl-convert-to-platform-remove-callback.patch [new file with mode: 0644]
queue-5.10/backlight-led_bl-hold-led_access-lock-when-calling-l.patch [new file with mode: 0644]
queue-5.10/cifs-avoid-null-pointer-dereference-in-dbg-call.patch [new file with mode: 0644]
queue-5.10/cifs-print-tids-as-hex.patch [new file with mode: 0644]
queue-5.10/driver-core-platform-change-logic-implementing-platf.patch [new file with mode: 0644]
queue-5.10/driver-core-platform-emit-a-warning-if-a-remove-call.patch [new file with mode: 0644]
queue-5.10/driver-core-platform-reorder-functions.patch [new file with mode: 0644]
queue-5.10/driver-core-platform-use-bus_type-functions.patch [new file with mode: 0644]
queue-5.10/drm-amd-amdgpu-amdgpu_vram_mgr-add-missing-descripti.patch [new file with mode: 0644]
queue-5.10/drm-amdgpu-dma_buf-fix-page_link-check.patch [new file with mode: 0644]
queue-5.10/drm-amdgpu-remove-amdgpu_device-arg-from-free_sgt-ap.patch [new file with mode: 0644]
queue-5.10/iio-adc-ad7768-1-fix-conversion-result-sign.patch [new file with mode: 0644]
queue-5.10/iio-adc-ad7768-1-move-setting-of-val-a-bit-later-to-.patch [new file with mode: 0644]
queue-5.10/media-streamzap-fix-race-between-device-disconnectio.patch [new file with mode: 0644]
queue-5.10/media-streamzap-less-chatter.patch [new file with mode: 0644]
queue-5.10/media-streamzap-no-need-for-usb-pid-vid-in-device-na.patch [new file with mode: 0644]
queue-5.10/media-streamzap-remove-unnecessary-ir_raw_event_rese.patch [new file with mode: 0644]
queue-5.10/media-streamzap-remove-unused-struct-members.patch [new file with mode: 0644]
queue-5.10/media-venus-create-hfi-platform-and-move-vpp-vsp-the.patch [new file with mode: 0644]
queue-5.10/media-venus-get-codecs-and-capabilities-from-hfi-pla.patch [new file with mode: 0644]
queue-5.10/media-venus-hfi-correct-session-init-return-error.patch [new file with mode: 0644]
queue-5.10/media-venus-hfi_parser-refactor-hfi-packet-parsing-l.patch [new file with mode: 0644]
queue-5.10/media-venus-hfi_plat-add-codecs-and-capabilities-ops.patch [new file with mode: 0644]
queue-5.10/media-venus-limit-hfi-sessions-to-the-maximum-suppor.patch [new file with mode: 0644]
queue-5.10/media-venus-pm_helpers-check-instance-state-when-cal.patch [new file with mode: 0644]
queue-5.10/media-venus-rename-venus_caps-to-hfi_plat_caps.patch [new file with mode: 0644]
queue-5.10/media-venus-venc-init-the-session-only-once-in-queue.patch [new file with mode: 0644]
queue-5.10/net-dsa-mv88e6xxx-fix-vtu-methods-for-6320-family.patch [new file with mode: 0644]
queue-5.10/pci-assign-pci-domain-ids-by-ida_alloc.patch [new file with mode: 0644]
queue-5.10/pci-coalesce-host-bridge-contiguous-apertures.patch [new file with mode: 0644]
queue-5.10/pci-fix-reference-leak-in-pci_register_host_bridge.patch [new file with mode: 0644]
queue-5.10/pci-introduce-domain_nr-in-pci_host_bridge.patch [new file with mode: 0644]
queue-5.10/platform-provide-a-remove-callback-that-returns-no-v.patch [new file with mode: 0644]
queue-5.10/platform-x86-isst-correct-command-storage-data-lengt.patch [new file with mode: 0644]
queue-5.10/selftests-mm-generate-a-temporary-mountpoint-for-cgr.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/soc-samsung-exynos-chipid-add-null-pointer-check-in-.patch [new file with mode: 0644]
queue-5.10/soc-samsung-exynos-chipid-avoid-soc_device_to_device.patch [new file with mode: 0644]
queue-5.10/soc-samsung-exynos-chipid-convert-to-driver-and-merg.patch [new file with mode: 0644]
queue-5.10/soc-samsung-exynos-chipid-initialize-later-with-arch.patch [new file with mode: 0644]
queue-5.10/soc-samsung-exynos-chipid-pass-revision-reg-offsets.patch [new file with mode: 0644]
queue-5.10/tracing-allow-synthetic-events-to-pass-around-stackt.patch [new file with mode: 0644]
queue-5.10/tracing-fix-synth-event-printk-format-for-str-fields.patch [new file with mode: 0644]

diff --git a/queue-5.10/backlight-led_bl-convert-to-platform-remove-callback.patch b/queue-5.10/backlight-led_bl-convert-to-platform-remove-callback.patch
new file mode 100644 (file)
index 0000000..2051e9a
--- /dev/null
@@ -0,0 +1,67 @@
+From 1e8aad01d355754c5ec31df0bc8297af773c77da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Mar 2023 08:39:38 +0100
+Subject: backlight: led_bl: Convert to platform remove callback returning void
+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 c4c4fa57fd3cc00020152baa169337521f90b2ad ]
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is (mostly) ignored
+and this typically results in resource leaks. To improve here there is a
+quest to make the remove callback return void. In the first step of this
+quest all drivers are converted to .remove_new() which already returns
+void.
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
+Signed-off-by: Lee Jones <lee@kernel.org>
+Link: https://lore.kernel.org/r/20230308073945.2336302-7-u.kleine-koenig@pengutronix.de
+Stable-dep-of: 276822a00db3 ("backlight: led_bl: Hold led_access lock when calling led_sysfs_disable()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/backlight/led_bl.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c
+index f54d256e2d548..a1b6a2ad73a07 100644
+--- a/drivers/video/backlight/led_bl.c
++++ b/drivers/video/backlight/led_bl.c
+@@ -217,7 +217,7 @@ static int led_bl_probe(struct platform_device *pdev)
+       return 0;
+ }
+-static int led_bl_remove(struct platform_device *pdev)
++static void led_bl_remove(struct platform_device *pdev)
+ {
+       struct led_bl_data *priv = platform_get_drvdata(pdev);
+       struct backlight_device *bl = priv->bl_dev;
+@@ -228,8 +228,6 @@ static int led_bl_remove(struct platform_device *pdev)
+       led_bl_power_off(priv);
+       for (i = 0; i < priv->nb_leds; i++)
+               led_sysfs_enable(priv->leds[i]);
+-
+-      return 0;
+ }
+ static const struct of_device_id led_bl_of_match[] = {
+@@ -245,7 +243,7 @@ static struct platform_driver led_bl_driver = {
+               .of_match_table = of_match_ptr(led_bl_of_match),
+       },
+       .probe          = led_bl_probe,
+-      .remove         = led_bl_remove,
++      .remove_new     = led_bl_remove,
+ };
+ module_platform_driver(led_bl_driver);
+-- 
+2.39.5
+
diff --git a/queue-5.10/backlight-led_bl-hold-led_access-lock-when-calling-l.patch b/queue-5.10/backlight-led_bl-hold-led_access-lock-when-calling-l.patch
new file mode 100644 (file)
index 0000000..a89e398
--- /dev/null
@@ -0,0 +1,56 @@
+From f52c59ee0d0e00936d200fa5fa2c7052ec019397 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2025 10:19:14 +0100
+Subject: backlight: led_bl: Hold led_access lock when calling
+ led_sysfs_disable()
+
+From: Herve Codina <herve.codina@bootlin.com>
+
+[ Upstream commit 276822a00db3c1061382b41e72cafc09d6a0ec30 ]
+
+Lockdep detects the following issue on led-backlight removal:
+  [  142.315935] ------------[ cut here ]------------
+  [  142.315954] WARNING: CPU: 2 PID: 292 at drivers/leds/led-core.c:455 led_sysfs_enable+0x54/0x80
+  ...
+  [  142.500725] Call trace:
+  [  142.503176]  led_sysfs_enable+0x54/0x80 (P)
+  [  142.507370]  led_bl_remove+0x80/0xa8 [led_bl]
+  [  142.511742]  platform_remove+0x30/0x58
+  [  142.515501]  device_remove+0x54/0x90
+  ...
+
+Indeed, led_sysfs_enable() has to be called with the led_access
+lock held.
+
+Hold the lock when calling led_sysfs_disable().
+
+Fixes: ae232e45acf9 ("backlight: add led-backlight driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Herve Codina <herve.codina@bootlin.com>
+Link: https://lore.kernel.org/r/20250122091914.309533-1-herve.codina@bootlin.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/backlight/led_bl.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c
+index a1b6a2ad73a07..589dae9ebb638 100644
+--- a/drivers/video/backlight/led_bl.c
++++ b/drivers/video/backlight/led_bl.c
+@@ -226,8 +226,11 @@ static void led_bl_remove(struct platform_device *pdev)
+       backlight_device_unregister(bl);
+       led_bl_power_off(priv);
+-      for (i = 0; i < priv->nb_leds; i++)
++      for (i = 0; i < priv->nb_leds; i++) {
++              mutex_lock(&priv->leds[i]->led_access);
+               led_sysfs_enable(priv->leds[i]);
++              mutex_unlock(&priv->leds[i]->led_access);
++      }
+ }
+ static const struct of_device_id led_bl_of_match[] = {
+-- 
+2.39.5
+
diff --git a/queue-5.10/cifs-avoid-null-pointer-dereference-in-dbg-call.patch b/queue-5.10/cifs-avoid-null-pointer-dereference-in-dbg-call.patch
new file mode 100644 (file)
index 0000000..0d73472
--- /dev/null
@@ -0,0 +1,47 @@
+From 94b2f11a89b3370e68571e93cd3a557cc78d3fa9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Mar 2025 17:28:58 +0300
+Subject: cifs: avoid NULL pointer dereference in dbg call
+
+From: Alexandra Diupina <adiupina@astralinux.ru>
+
+[ Upstream commit b4885bd5935bb26f0a414ad55679a372e53f9b9b ]
+
+cifs_server_dbg() implies server to be non-NULL so
+move call under condition to avoid NULL pointer dereference.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: e79b0332ae06 ("cifs: ignore cached share root handle closing errors")
+Cc: stable@vger.kernel.org
+Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2misc.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
+index d21b27e68f2a8..c0b80ba8875af 100644
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -809,11 +809,12 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
+               WARN_ONCE(tcon->tc_count < 0, "tcon refcount is negative");
+               spin_unlock(&cifs_tcp_ses_lock);
+-              if (tcon->ses)
++              if (tcon->ses) {
+                       server = tcon->ses->server;
+-
+-              cifs_server_dbg(FYI, "tid=0x%x: tcon is closing, skipping async close retry of fid %llu %llu\n",
+-                              tcon->tid, persistent_fid, volatile_fid);
++                      cifs_server_dbg(FYI,
++                                      "tid=0x%x: tcon is closing, skipping async close retry of fid %llu %llu\n",
++                                      tcon->tid, persistent_fid, volatile_fid);
++              }
+               return 0;
+       }
+-- 
+2.39.5
+
diff --git a/queue-5.10/cifs-print-tids-as-hex.patch b/queue-5.10/cifs-print-tids-as-hex.patch
new file mode 100644 (file)
index 0000000..7bd7c42
--- /dev/null
@@ -0,0 +1,50 @@
+From ca33e943102697ae4996cb90123cd0fdfdb488ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 May 2022 11:41:04 -0300
+Subject: cifs: print TIDs as hex
+
+From: Enzo Matsumiya <ematsumiya@suse.de>
+
+[ Upstream commit 71081e7ac16c93acdd18afa65daa468620bb1b64 ]
+
+Makes these debug messages easier to read
+
+Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
+Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: b4885bd5935b ("cifs: avoid NULL pointer dereference in dbg call")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/connect.c  | 2 +-
+ fs/cifs/smb2misc.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index a3c0e6a4e4847..2c0522d97e037 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -2770,7 +2770,7 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb_vol *volume_info)
+               goto out;
+       }
+-      cifs_dbg(FYI, "IPC tcon rc = %d ipc tid = %d\n", rc, tcon->tid);
++      cifs_dbg(FYI, "IPC tcon rc=%d ipc tid=0x%x\n", rc, tcon->tid);
+       ses->tcon_ipc = tcon;
+ out:
+diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
+index 64887856331ae..d21b27e68f2a8 100644
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -812,7 +812,7 @@ smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
+               if (tcon->ses)
+                       server = tcon->ses->server;
+-              cifs_server_dbg(FYI, "tid=%u: tcon is closing, skipping async close retry of fid %llu %llu\n",
++              cifs_server_dbg(FYI, "tid=0x%x: tcon is closing, skipping async close retry of fid %llu %llu\n",
+                               tcon->tid, persistent_fid, volatile_fid);
+               return 0;
+-- 
+2.39.5
+
diff --git a/queue-5.10/driver-core-platform-change-logic-implementing-platf.patch b/queue-5.10/driver-core-platform-change-logic-implementing-platf.patch
new file mode 100644 (file)
index 0000000..92a89de
--- /dev/null
@@ -0,0 +1,83 @@
+From 5cae0e026c8b364f338819cb26b34cb3ecc51fad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Nov 2020 13:46:10 +0100
+Subject: driver core: platform: change logic implementing
+ platform_driver_probe
+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 16085668eacdc56c46652d0f3bfef81ecace57de ]
+
+Instead of overwriting the core driver's probe function handle probing
+devices for drivers loaded by platform_driver_probe() in the platform
+driver probe function.
+
+The intended goal is to not have to change the probe function to
+simplify converting the platform bus to use bus functions.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20201119124611.2573057-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 276822a00db3 ("backlight: led_bl: Hold led_access lock when calling led_sysfs_disable()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/platform.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/base/platform.c b/drivers/base/platform.c
+index fa023cf80dc48..16426eb934632 100644
+--- a/drivers/base/platform.c
++++ b/drivers/base/platform.c
+@@ -743,12 +743,25 @@ struct platform_device *platform_device_register_full(
+ }
+ EXPORT_SYMBOL_GPL(platform_device_register_full);
++static int platform_probe_fail(struct platform_device *pdev);
++
+ static int platform_drv_probe(struct device *_dev)
+ {
+       struct platform_driver *drv = to_platform_driver(_dev->driver);
+       struct platform_device *dev = to_platform_device(_dev);
+       int ret;
++      /*
++       * A driver registered using platform_driver_probe() cannot be bound
++       * again later because the probe function usually lives in __init code
++       * and so is gone. For these drivers .probe is set to
++       * platform_probe_fail in __platform_driver_probe(). Don't even
++       * prepare clocks and PM domains for these to match the traditional
++       * behaviour.
++       */
++      if (unlikely(drv->probe == platform_probe_fail))
++              return -ENXIO;
++
+       ret = of_clk_set_defaults(_dev->of_node, false);
+       if (ret < 0)
+               return ret;
+@@ -822,7 +835,7 @@ void platform_driver_unregister(struct platform_driver *drv)
+ }
+ EXPORT_SYMBOL_GPL(platform_driver_unregister);
+-static int platform_drv_probe_fail(struct device *_dev)
++static int platform_probe_fail(struct platform_device *pdev)
+ {
+       return -ENXIO;
+ }
+@@ -887,10 +900,9 @@ int __init_or_module __platform_driver_probe(struct platform_driver *drv,
+        * new devices fail.
+        */
+       spin_lock(&drv->driver.bus->p->klist_drivers.k_lock);
+-      drv->probe = NULL;
++      drv->probe = platform_probe_fail;
+       if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
+               retval = -ENODEV;
+-      drv->driver.probe = platform_drv_probe_fail;
+       spin_unlock(&drv->driver.bus->p->klist_drivers.k_lock);
+       if (code != retval)
+-- 
+2.39.5
+
diff --git a/queue-5.10/driver-core-platform-emit-a-warning-if-a-remove-call.patch b/queue-5.10/driver-core-platform-emit-a-warning-if-a-remove-call.patch
new file mode 100644 (file)
index 0000000..00ab6db
--- /dev/null
@@ -0,0 +1,60 @@
+From be789066e7a8cf1d42fae45038e28a7663cbc213 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Feb 2021 22:15:37 +0100
+Subject: driver core: platform: Emit a warning if a remove callback returned
+ non-zero
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <uwe@kleine-koenig.org>
+
+[ Upstream commit e5e1c209788138f33ca6558bf9f572f6904f486d ]
+
+The driver core ignores the return value of a bus' remove callback. However
+a driver returning an error code is a hint that there is a problem,
+probably a driver author who expects that returning e.g. -EBUSY has any
+effect.
+
+The right thing to do would be to make struct platform_driver::remove()
+return void. With the immense number of platform drivers this is however a
+big quest and I hope to prevent at least a few new drivers that return an
+error code here.
+
+Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
+Link: https://lore.kernel.org/r/20210207211537.19992-1-uwe@kleine-koenig.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 276822a00db3 ("backlight: led_bl: Hold led_access lock when calling led_sysfs_disable()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/platform.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/base/platform.c b/drivers/base/platform.c
+index 90166535a5c05..d0b15cbab0ff0 100644
+--- a/drivers/base/platform.c
++++ b/drivers/base/platform.c
+@@ -1305,13 +1305,16 @@ static int platform_remove(struct device *_dev)
+ {
+       struct platform_driver *drv = to_platform_driver(_dev->driver);
+       struct platform_device *dev = to_platform_device(_dev);
+-      int ret = 0;
+-      if (drv->remove)
+-              ret = drv->remove(dev);
++      if (drv->remove) {
++              int ret = drv->remove(dev);
++
++              if (ret)
++                      dev_warn(_dev, "remove callback returned a non-zero value. This will be ignored.\n");
++      }
+       dev_pm_domain_detach(_dev, true);
+-      return ret;
++      return 0;
+ }
+ static void platform_shutdown(struct device *_dev)
+-- 
+2.39.5
+
diff --git a/queue-5.10/driver-core-platform-reorder-functions.patch b/queue-5.10/driver-core-platform-reorder-functions.patch
new file mode 100644 (file)
index 0000000..934cbda
--- /dev/null
@@ -0,0 +1,361 @@
+From 755c0725a3eaa804db5be07cd930b3d0e59648fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Nov 2020 13:46:09 +0100
+Subject: driver core: platform: reorder functions
+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 e21d740a3fe5ad2db7b5f5c2331fe2b713b1edba ]
+
+This way all callbacks and structures used to initialize
+platform_bus_type are defined just before platform_bus_type and in the
+same order. Also move platform_drv_probe_fail just before it's only
+user.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20201119124611.2573057-1-u.kleine-koenig@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 276822a00db3 ("backlight: led_bl: Hold led_access lock when calling led_sysfs_disable()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/platform.c | 293 ++++++++++++++++++++--------------------
+ 1 file changed, 147 insertions(+), 146 deletions(-)
+
+diff --git a/drivers/base/platform.c b/drivers/base/platform.c
+index 647066229fec3..fa023cf80dc48 100644
+--- a/drivers/base/platform.c
++++ b/drivers/base/platform.c
+@@ -772,11 +772,6 @@ static int platform_drv_probe(struct device *_dev)
+       return ret;
+ }
+-static int platform_drv_probe_fail(struct device *_dev)
+-{
+-      return -ENXIO;
+-}
+-
+ static int platform_drv_remove(struct device *_dev)
+ {
+       struct platform_driver *drv = to_platform_driver(_dev->driver);
+@@ -827,6 +822,11 @@ void platform_driver_unregister(struct platform_driver *drv)
+ }
+ EXPORT_SYMBOL_GPL(platform_driver_unregister);
++static int platform_drv_probe_fail(struct device *_dev)
++{
++      return -ENXIO;
++}
++
+ /**
+  * __platform_driver_probe - register driver for non-hotpluggable device
+  * @drv: platform driver structure
+@@ -1017,109 +1017,6 @@ void platform_unregister_drivers(struct platform_driver * const *drivers,
+ }
+ EXPORT_SYMBOL_GPL(platform_unregister_drivers);
+-/* modalias support enables more hands-off userspace setup:
+- * (a) environment variable lets new-style hotplug events work once system is
+- *     fully running:  "modprobe $MODALIAS"
+- * (b) sysfs attribute lets new-style coldplug recover from hotplug events
+- *     mishandled before system is fully running:  "modprobe $(cat modalias)"
+- */
+-static ssize_t modalias_show(struct device *dev,
+-                           struct device_attribute *attr, char *buf)
+-{
+-      struct platform_device *pdev = to_platform_device(dev);
+-      int len;
+-
+-      len = of_device_modalias(dev, buf, PAGE_SIZE);
+-      if (len != -ENODEV)
+-              return len;
+-
+-      len = acpi_device_modalias(dev, buf, PAGE_SIZE - 1);
+-      if (len != -ENODEV)
+-              return len;
+-
+-      return sysfs_emit(buf, "platform:%s\n", pdev->name);
+-}
+-static DEVICE_ATTR_RO(modalias);
+-
+-static ssize_t driver_override_store(struct device *dev,
+-                                   struct device_attribute *attr,
+-                                   const char *buf, size_t count)
+-{
+-      struct platform_device *pdev = to_platform_device(dev);
+-      int ret;
+-
+-      ret = driver_set_override(dev, &pdev->driver_override, buf, count);
+-      if (ret)
+-              return ret;
+-
+-      return count;
+-}
+-
+-static ssize_t driver_override_show(struct device *dev,
+-                                  struct device_attribute *attr, char *buf)
+-{
+-      struct platform_device *pdev = to_platform_device(dev);
+-      ssize_t len;
+-
+-      device_lock(dev);
+-      len = sysfs_emit(buf, "%s\n", pdev->driver_override);
+-      device_unlock(dev);
+-
+-      return len;
+-}
+-static DEVICE_ATTR_RW(driver_override);
+-
+-static ssize_t numa_node_show(struct device *dev,
+-                            struct device_attribute *attr, char *buf)
+-{
+-      return sysfs_emit(buf, "%d\n", dev_to_node(dev));
+-}
+-static DEVICE_ATTR_RO(numa_node);
+-
+-static umode_t platform_dev_attrs_visible(struct kobject *kobj, struct attribute *a,
+-              int n)
+-{
+-      struct device *dev = container_of(kobj, typeof(*dev), kobj);
+-
+-      if (a == &dev_attr_numa_node.attr &&
+-                      dev_to_node(dev) == NUMA_NO_NODE)
+-              return 0;
+-
+-      return a->mode;
+-}
+-
+-static struct attribute *platform_dev_attrs[] = {
+-      &dev_attr_modalias.attr,
+-      &dev_attr_numa_node.attr,
+-      &dev_attr_driver_override.attr,
+-      NULL,
+-};
+-
+-static struct attribute_group platform_dev_group = {
+-      .attrs = platform_dev_attrs,
+-      .is_visible = platform_dev_attrs_visible,
+-};
+-__ATTRIBUTE_GROUPS(platform_dev);
+-
+-static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
+-{
+-      struct platform_device  *pdev = to_platform_device(dev);
+-      int rc;
+-
+-      /* Some devices have extra OF data and an OF-style MODALIAS */
+-      rc = of_device_uevent_modalias(dev, env);
+-      if (rc != -ENODEV)
+-              return rc;
+-
+-      rc = acpi_device_uevent_modalias(dev, env);
+-      if (rc != -ENODEV)
+-              return rc;
+-
+-      add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
+-                      pdev->name);
+-      return 0;
+-}
+-
+ static const struct platform_device_id *platform_match_id(
+                       const struct platform_device_id *id,
+                       struct platform_device *pdev)
+@@ -1134,44 +1031,6 @@ static const struct platform_device_id *platform_match_id(
+       return NULL;
+ }
+-/**
+- * platform_match - bind platform device to platform driver.
+- * @dev: device.
+- * @drv: driver.
+- *
+- * Platform device IDs are assumed to be encoded like this:
+- * "<name><instance>", where <name> is a short description of the type of
+- * device, like "pci" or "floppy", and <instance> is the enumerated
+- * instance of the device, like '0' or '42'.  Driver IDs are simply
+- * "<name>".  So, extract the <name> from the platform_device structure,
+- * and compare it against the name of the driver. Return whether they match
+- * or not.
+- */
+-static int platform_match(struct device *dev, struct device_driver *drv)
+-{
+-      struct platform_device *pdev = to_platform_device(dev);
+-      struct platform_driver *pdrv = to_platform_driver(drv);
+-
+-      /* When driver_override is set, only bind to the matching driver */
+-      if (pdev->driver_override)
+-              return !strcmp(pdev->driver_override, drv->name);
+-
+-      /* Attempt an OF style match first */
+-      if (of_driver_match_device(dev, drv))
+-              return 1;
+-
+-      /* Then try ACPI style match */
+-      if (acpi_driver_match_device(dev, drv))
+-              return 1;
+-
+-      /* Then try to match against the id table */
+-      if (pdrv->id_table)
+-              return platform_match_id(pdrv->id_table, pdev) != NULL;
+-
+-      /* fall-back to driver name match */
+-      return (strcmp(pdev->name, drv->name) == 0);
+-}
+-
+ #ifdef CONFIG_PM_SLEEP
+ static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)
+@@ -1316,6 +1175,148 @@ int platform_pm_restore(struct device *dev)
+ #endif /* CONFIG_HIBERNATE_CALLBACKS */
++/* modalias support enables more hands-off userspace setup:
++ * (a) environment variable lets new-style hotplug events work once system is
++ *     fully running:  "modprobe $MODALIAS"
++ * (b) sysfs attribute lets new-style coldplug recover from hotplug events
++ *     mishandled before system is fully running:  "modprobe $(cat modalias)"
++ */
++static ssize_t modalias_show(struct device *dev,
++                           struct device_attribute *attr, char *buf)
++{
++      struct platform_device *pdev = to_platform_device(dev);
++      int len;
++
++      len = of_device_modalias(dev, buf, PAGE_SIZE);
++      if (len != -ENODEV)
++              return len;
++
++      len = acpi_device_modalias(dev, buf, PAGE_SIZE - 1);
++      if (len != -ENODEV)
++              return len;
++
++      return sysfs_emit(buf, "platform:%s\n", pdev->name);
++}
++static DEVICE_ATTR_RO(modalias);
++
++static ssize_t numa_node_show(struct device *dev,
++                            struct device_attribute *attr, char *buf)
++{
++      return sysfs_emit(buf, "%d\n", dev_to_node(dev));
++}
++static DEVICE_ATTR_RO(numa_node);
++
++static ssize_t driver_override_show(struct device *dev,
++                                  struct device_attribute *attr, char *buf)
++{
++      struct platform_device *pdev = to_platform_device(dev);
++      ssize_t len;
++
++      device_lock(dev);
++      len = sysfs_emit(buf, "%s\n", pdev->driver_override);
++      device_unlock(dev);
++
++      return len;
++}
++
++static ssize_t driver_override_store(struct device *dev,
++                                   struct device_attribute *attr,
++                                   const char *buf, size_t count)
++{
++      struct platform_device *pdev = to_platform_device(dev);
++      int ret;
++
++      ret = driver_set_override(dev, &pdev->driver_override, buf, count);
++      if (ret)
++              return ret;
++
++      return count;
++}
++static DEVICE_ATTR_RW(driver_override);
++
++static struct attribute *platform_dev_attrs[] = {
++      &dev_attr_modalias.attr,
++      &dev_attr_numa_node.attr,
++      &dev_attr_driver_override.attr,
++      NULL,
++};
++
++static umode_t platform_dev_attrs_visible(struct kobject *kobj, struct attribute *a,
++              int n)
++{
++      struct device *dev = container_of(kobj, typeof(*dev), kobj);
++
++      if (a == &dev_attr_numa_node.attr &&
++                      dev_to_node(dev) == NUMA_NO_NODE)
++              return 0;
++
++      return a->mode;
++}
++
++static struct attribute_group platform_dev_group = {
++      .attrs = platform_dev_attrs,
++      .is_visible = platform_dev_attrs_visible,
++};
++__ATTRIBUTE_GROUPS(platform_dev);
++
++
++/**
++ * platform_match - bind platform device to platform driver.
++ * @dev: device.
++ * @drv: driver.
++ *
++ * Platform device IDs are assumed to be encoded like this:
++ * "<name><instance>", where <name> is a short description of the type of
++ * device, like "pci" or "floppy", and <instance> is the enumerated
++ * instance of the device, like '0' or '42'.  Driver IDs are simply
++ * "<name>".  So, extract the <name> from the platform_device structure,
++ * and compare it against the name of the driver. Return whether they match
++ * or not.
++ */
++static int platform_match(struct device *dev, struct device_driver *drv)
++{
++      struct platform_device *pdev = to_platform_device(dev);
++      struct platform_driver *pdrv = to_platform_driver(drv);
++
++      /* When driver_override is set, only bind to the matching driver */
++      if (pdev->driver_override)
++              return !strcmp(pdev->driver_override, drv->name);
++
++      /* Attempt an OF style match first */
++      if (of_driver_match_device(dev, drv))
++              return 1;
++
++      /* Then try ACPI style match */
++      if (acpi_driver_match_device(dev, drv))
++              return 1;
++
++      /* Then try to match against the id table */
++      if (pdrv->id_table)
++              return platform_match_id(pdrv->id_table, pdev) != NULL;
++
++      /* fall-back to driver name match */
++      return (strcmp(pdev->name, drv->name) == 0);
++}
++
++static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
++{
++      struct platform_device  *pdev = to_platform_device(dev);
++      int rc;
++
++      /* Some devices have extra OF data and an OF-style MODALIAS */
++      rc = of_device_uevent_modalias(dev, env);
++      if (rc != -ENODEV)
++              return rc;
++
++      rc = acpi_device_uevent_modalias(dev, env);
++      if (rc != -ENODEV)
++              return rc;
++
++      add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
++                      pdev->name);
++      return 0;
++}
++
+ int platform_dma_configure(struct device *dev)
+ {
+       enum dev_dma_attr attr;
+-- 
+2.39.5
+
diff --git a/queue-5.10/driver-core-platform-use-bus_type-functions.patch b/queue-5.10/driver-core-platform-use-bus_type-functions.patch
new file mode 100644 (file)
index 0000000..e73fab0
--- /dev/null
@@ -0,0 +1,194 @@
+From 9d1ddcb33799b6b3c278d2c440ec242db06cc644 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 19 Nov 2020 13:46:11 +0100
+Subject: driver core: platform: use bus_type functions
+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 9c30921fe7994907e0b3e0637b2c8c0fc4b5171f ]
+
+This works towards the goal mentioned in 2006 in commit 594c8281f905
+("[PATCH] Add bus_type probe, remove, shutdown methods.").
+
+The functions are moved to where the other bus_type functions are
+defined and renamed to match the already established naming scheme.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20201119124611.2573057-3-u.kleine-koenig@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 276822a00db3 ("backlight: led_bl: Hold led_access lock when calling led_sysfs_disable()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/platform.c | 132 ++++++++++++++++++++--------------------
+ 1 file changed, 65 insertions(+), 67 deletions(-)
+
+diff --git a/drivers/base/platform.c b/drivers/base/platform.c
+index 16426eb934632..90166535a5c05 100644
+--- a/drivers/base/platform.c
++++ b/drivers/base/platform.c
+@@ -743,70 +743,6 @@ struct platform_device *platform_device_register_full(
+ }
+ EXPORT_SYMBOL_GPL(platform_device_register_full);
+-static int platform_probe_fail(struct platform_device *pdev);
+-
+-static int platform_drv_probe(struct device *_dev)
+-{
+-      struct platform_driver *drv = to_platform_driver(_dev->driver);
+-      struct platform_device *dev = to_platform_device(_dev);
+-      int ret;
+-
+-      /*
+-       * A driver registered using platform_driver_probe() cannot be bound
+-       * again later because the probe function usually lives in __init code
+-       * and so is gone. For these drivers .probe is set to
+-       * platform_probe_fail in __platform_driver_probe(). Don't even
+-       * prepare clocks and PM domains for these to match the traditional
+-       * behaviour.
+-       */
+-      if (unlikely(drv->probe == platform_probe_fail))
+-              return -ENXIO;
+-
+-      ret = of_clk_set_defaults(_dev->of_node, false);
+-      if (ret < 0)
+-              return ret;
+-
+-      ret = dev_pm_domain_attach(_dev, true);
+-      if (ret)
+-              goto out;
+-
+-      if (drv->probe) {
+-              ret = drv->probe(dev);
+-              if (ret)
+-                      dev_pm_domain_detach(_dev, true);
+-      }
+-
+-out:
+-      if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
+-              dev_warn(_dev, "probe deferral not supported\n");
+-              ret = -ENXIO;
+-      }
+-
+-      return ret;
+-}
+-
+-static int platform_drv_remove(struct device *_dev)
+-{
+-      struct platform_driver *drv = to_platform_driver(_dev->driver);
+-      struct platform_device *dev = to_platform_device(_dev);
+-      int ret = 0;
+-
+-      if (drv->remove)
+-              ret = drv->remove(dev);
+-      dev_pm_domain_detach(_dev, true);
+-
+-      return ret;
+-}
+-
+-static void platform_drv_shutdown(struct device *_dev)
+-{
+-      struct platform_driver *drv = to_platform_driver(_dev->driver);
+-      struct platform_device *dev = to_platform_device(_dev);
+-
+-      if (drv->shutdown)
+-              drv->shutdown(dev);
+-}
+-
+ /**
+  * __platform_driver_register - register a driver for platform-level devices
+  * @drv: platform driver structure
+@@ -817,9 +753,6 @@ int __platform_driver_register(struct platform_driver *drv,
+ {
+       drv->driver.owner = owner;
+       drv->driver.bus = &platform_bus_type;
+-      drv->driver.probe = platform_drv_probe;
+-      drv->driver.remove = platform_drv_remove;
+-      drv->driver.shutdown = platform_drv_shutdown;
+       return driver_register(&drv->driver);
+ }
+@@ -1329,6 +1262,68 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
+       return 0;
+ }
++static int platform_probe(struct device *_dev)
++{
++      struct platform_driver *drv = to_platform_driver(_dev->driver);
++      struct platform_device *dev = to_platform_device(_dev);
++      int ret;
++
++      /*
++       * A driver registered using platform_driver_probe() cannot be bound
++       * again later because the probe function usually lives in __init code
++       * and so is gone. For these drivers .probe is set to
++       * platform_probe_fail in __platform_driver_probe(). Don't even prepare
++       * clocks and PM domains for these to match the traditional behaviour.
++       */
++      if (unlikely(drv->probe == platform_probe_fail))
++              return -ENXIO;
++
++      ret = of_clk_set_defaults(_dev->of_node, false);
++      if (ret < 0)
++              return ret;
++
++      ret = dev_pm_domain_attach(_dev, true);
++      if (ret)
++              goto out;
++
++      if (drv->probe) {
++              ret = drv->probe(dev);
++              if (ret)
++                      dev_pm_domain_detach(_dev, true);
++      }
++
++out:
++      if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
++              dev_warn(_dev, "probe deferral not supported\n");
++              ret = -ENXIO;
++      }
++
++      return ret;
++}
++
++static int platform_remove(struct device *_dev)
++{
++      struct platform_driver *drv = to_platform_driver(_dev->driver);
++      struct platform_device *dev = to_platform_device(_dev);
++      int ret = 0;
++
++      if (drv->remove)
++              ret = drv->remove(dev);
++      dev_pm_domain_detach(_dev, true);
++
++      return ret;
++}
++
++static void platform_shutdown(struct device *_dev)
++{
++      struct platform_driver *drv = to_platform_driver(_dev->driver);
++      struct platform_device *dev = to_platform_device(_dev);
++
++      if (drv->shutdown)
++              drv->shutdown(dev);
++}
++
++
+ int platform_dma_configure(struct device *dev)
+ {
+       enum dev_dma_attr attr;
+@@ -1355,6 +1350,9 @@ struct bus_type platform_bus_type = {
+       .dev_groups     = platform_dev_groups,
+       .match          = platform_match,
+       .uevent         = platform_uevent,
++      .probe          = platform_probe,
++      .remove         = platform_remove,
++      .shutdown       = platform_shutdown,
+       .dma_configure  = platform_dma_configure,
+       .pm             = &platform_dev_pm_ops,
+ };
+-- 
+2.39.5
+
diff --git a/queue-5.10/drm-amd-amdgpu-amdgpu_vram_mgr-add-missing-descripti.patch b/queue-5.10/drm-amd-amdgpu-amdgpu_vram_mgr-add-missing-descripti.patch
new file mode 100644 (file)
index 0000000..9523634
--- /dev/null
@@ -0,0 +1,48 @@
+From a9c47f8b5efe42ca3ceb81a9e8d70006ba9ca05f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Nov 2020 13:49:17 +0000
+Subject: drm/amd/amdgpu/amdgpu_vram_mgr: Add missing descriptions for 'dev'
+ and 'dir'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lee Jones <lee.jones@linaro.org>
+
+[ Upstream commit 2c8645b7a6974b33744b677e9ddc89650776af46 ]
+
+Fixes the following W=1 kernel build warning(s):
+
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:648: warning: Function parameter or member 'dev' not described in 'amdgpu_vram_mgr_free_sgt'
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c:648: warning: Function parameter or member 'dir' not described in 'amdgpu_vram_mgr_free_sgt'
+
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: "Christian König" <christian.koenig@amd.com>
+Cc: David Airlie <airlied@linux.ie>
+Cc: Daniel Vetter <daniel@ffwll.ch>
+Cc: amd-gfx@lists.freedesktop.org
+Cc: dri-devel@lists.freedesktop.org
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: c0dd8a9253fa ("drm/amdgpu/dma_buf: fix page_link check")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+index 0c6b7c5ecfec8..2c3a94e939bab 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+@@ -531,6 +531,8 @@ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev,
+  * amdgpu_vram_mgr_alloc_sgt - allocate and fill a sg table
+  *
+  * @adev: amdgpu device pointer
++ * @dev: device pointer
++ * @dir: data direction of resource to unmap
+  * @sgt: sg table to free
+  *
+  * Free a previously allocate sg table.
+-- 
+2.39.5
+
diff --git a/queue-5.10/drm-amdgpu-dma_buf-fix-page_link-check.patch b/queue-5.10/drm-amdgpu-dma_buf-fix-page_link-check.patch
new file mode 100644 (file)
index 0000000..494880e
--- /dev/null
@@ -0,0 +1,45 @@
+From 7e694c1f9f11eed69047faa76f75378475bcc265 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 15:18:25 +0100
+Subject: drm/amdgpu/dma_buf: fix page_link check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Matthew Auld <matthew.auld@intel.com>
+
+[ Upstream commit c0dd8a9253fadfb8e5357217d085f1989da4ef0a ]
+
+The page_link lower bits of the first sg could contain something like
+SG_END, if we are mapping a single VRAM page or contiguous blob which
+fits into one sg entry. Rather pull out the struct page, and use that in
+our check to know if we mapped struct pages vs VRAM.
+
+Fixes: f44ffd677fb3 ("drm/amdgpu: add support for exporting VRAM using DMA-buf v3")
+Signed-off-by: Matthew Auld <matthew.auld@intel.com>
+Cc: Christian König <christian.koenig@amd.com>
+Cc: amd-gfx@lists.freedesktop.org
+Cc: <stable@vger.kernel.org> # v5.8+
+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/amd/amdgpu/amdgpu_dma_buf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+index bbbacc7b6c463..e4d0a9377e712 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+@@ -357,7 +357,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
+                                struct sg_table *sgt,
+                                enum dma_data_direction dir)
+ {
+-      if (sgt->sgl->page_link) {
++      if (sg_page(sgt->sgl)) {
+               dma_unmap_sgtable(attach->dev, sgt, dir, 0);
+               sg_free_table(sgt);
+               kfree(sgt);
+-- 
+2.39.5
+
diff --git a/queue-5.10/drm-amdgpu-remove-amdgpu_device-arg-from-free_sgt-ap.patch b/queue-5.10/drm-amdgpu-remove-amdgpu_device-arg-from-free_sgt-ap.patch
new file mode 100644 (file)
index 0000000..6899108
--- /dev/null
@@ -0,0 +1,90 @@
+From 09a1b6ca7c7d9c07c702479646a0a8cfa2329e11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Feb 2021 20:48:06 -0600
+Subject: drm/amdgpu: Remove amdgpu_device arg from free_sgt api (v2)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ramesh Errabolu <Ramesh.Errabolu@amd.com>
+
+[ Upstream commit 5392b2af97dc5802991f953eb2687e538da4688c ]
+
+Currently callers have to provide handle of amdgpu_device,
+which is not used by the implementation. It is unlikely this
+parameter will become useful in future, thus removing it
+
+v2: squash in unused variable fix
+
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Ramesh Errabolu <Ramesh.Errabolu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: c0dd8a9253fa ("drm/amdgpu/dma_buf: fix page_link check")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c  | 7 +------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h      | 3 +--
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 4 +---
+ 3 files changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+index e93ccdc5faf4e..bbbacc7b6c463 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+@@ -357,17 +357,12 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
+                                struct sg_table *sgt,
+                                enum dma_data_direction dir)
+ {
+-      struct dma_buf *dma_buf = attach->dmabuf;
+-      struct drm_gem_object *obj = dma_buf->priv;
+-      struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
+-      struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
+-
+       if (sgt->sgl->page_link) {
+               dma_unmap_sgtable(attach->dev, sgt, dir, 0);
+               sg_free_table(sgt);
+               kfree(sgt);
+       } else {
+-              amdgpu_vram_mgr_free_sgt(adev, attach->dev, dir, sgt);
++              amdgpu_vram_mgr_free_sgt(attach->dev, dir, sgt);
+       }
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+index a87951b2f06dd..bd873b1b760cf 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+@@ -113,8 +113,7 @@ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev,
+                             struct device *dev,
+                             enum dma_data_direction dir,
+                             struct sg_table **sgt);
+-void amdgpu_vram_mgr_free_sgt(struct amdgpu_device *adev,
+-                            struct device *dev,
++void amdgpu_vram_mgr_free_sgt(struct device *dev,
+                             enum dma_data_direction dir,
+                             struct sg_table *sgt);
+ uint64_t amdgpu_vram_mgr_usage(struct ttm_resource_manager *man);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+index 2c3a94e939bab..ad72db21b8d62 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+@@ -530,15 +530,13 @@ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev,
+ /**
+  * amdgpu_vram_mgr_alloc_sgt - allocate and fill a sg table
+  *
+- * @adev: amdgpu device pointer
+  * @dev: device pointer
+  * @dir: data direction of resource to unmap
+  * @sgt: sg table to free
+  *
+  * Free a previously allocate sg table.
+  */
+-void amdgpu_vram_mgr_free_sgt(struct amdgpu_device *adev,
+-                            struct device *dev,
++void amdgpu_vram_mgr_free_sgt(struct device *dev,
+                             enum dma_data_direction dir,
+                             struct sg_table *sgt)
+ {
+-- 
+2.39.5
+
diff --git a/queue-5.10/iio-adc-ad7768-1-fix-conversion-result-sign.patch b/queue-5.10/iio-adc-ad7768-1-fix-conversion-result-sign.patch
new file mode 100644 (file)
index 0000000..541c4f1
--- /dev/null
@@ -0,0 +1,55 @@
+From 5d51c142998785ea086034e7f5fabba2331aa344 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 18:00:29 -0300
+Subject: iio: adc: ad7768-1: Fix conversion result sign
+
+From: Sergiu Cuciurean <sergiu.cuciurean@analog.com>
+
+[ Upstream commit 8236644f5ecb180e80ad92d691c22bc509b747bb ]
+
+The ad7768-1 ADC output code is two's complement, meaning that the voltage
+conversion result is a signed value.. Since the value is a 24 bit one,
+stored in a 32 bit variable, the sign should be extended in order to get
+the correct representation.
+
+Also the channel description has been updated to signed representation,
+to match the ADC specifications.
+
+Fixes: a5f8c7da3dbe ("iio: adc: Add AD7768-1 ADC basic support")
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Reviewed-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Signed-off-by: Sergiu Cuciurean <sergiu.cuciurean@analog.com>
+Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com>
+Cc: <Stable@vger.kernel.org>
+Link: https://patch.msgid.link/505994d3b71c2aa38ba714d909a68e021f12124c.1741268122.git.Jonathan.Santos@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+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 c409b498fc313..2445ebc551dd1 100644
+--- a/drivers/iio/adc/ad7768-1.c
++++ b/drivers/iio/adc/ad7768-1.c
+@@ -142,7 +142,7 @@ static const struct iio_chan_spec ad7768_channels[] = {
+               .channel = 0,
+               .scan_index = 0,
+               .scan_type = {
+-                      .sign = 'u',
++                      .sign = 's',
+                       .realbits = 24,
+                       .storagebits = 32,
+                       .shift = 8,
+@@ -373,7 +373,7 @@ static int ad7768_read_raw(struct iio_dev *indio_dev,
+               iio_device_release_direct_mode(indio_dev);
+               if (ret < 0)
+                       return ret;
+-              *val = ret;
++              *val = sign_extend32(ret, chan->scan_type.realbits - 1);
+               return IIO_VAL_INT;
+-- 
+2.39.5
+
diff --git a/queue-5.10/iio-adc-ad7768-1-move-setting-of-val-a-bit-later-to-.patch b/queue-5.10/iio-adc-ad7768-1-move-setting-of-val-a-bit-later-to-.patch
new file mode 100644 (file)
index 0000000..50ef7c9
--- /dev/null
@@ -0,0 +1,47 @@
+From 33e1e987e03b89ac7f1a1aa4a8bf84efe2d7527d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 14:16:12 +0000
+Subject: iio: adc: ad7768-1: Move setting of val a bit later to avoid
+ unnecessary return value check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 0af1c801a15225304a6328258efbf2bee245c654 ]
+
+The data used is all in local variables so there is no advantage
+in setting *val = ret with the direct mode claim held.
+Move it later to after error check.
+
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://patch.msgid.link/20250217141630.897334-13-jic23@kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 8236644f5ecb ("iio: adc: ad7768-1: Fix conversion result sign")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7768-1.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
+index 4afa50e5c058a..c409b498fc313 100644
+--- a/drivers/iio/adc/ad7768-1.c
++++ b/drivers/iio/adc/ad7768-1.c
+@@ -369,12 +369,11 @@ static int ad7768_read_raw(struct iio_dev *indio_dev,
+                       return ret;
+               ret = ad7768_scan_direct(indio_dev);
+-              if (ret >= 0)
+-                      *val = ret;
+               iio_device_release_direct_mode(indio_dev);
+               if (ret < 0)
+                       return ret;
++              *val = ret;
+               return IIO_VAL_INT;
+-- 
+2.39.5
+
diff --git a/queue-5.10/media-streamzap-fix-race-between-device-disconnectio.patch b/queue-5.10/media-streamzap-fix-race-between-device-disconnectio.patch
new file mode 100644 (file)
index 0000000..a30d1d9
--- /dev/null
@@ -0,0 +1,54 @@
+From d5b00259ac8d78bd8858d2e94ef40c63d7691cbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jan 2025 13:51:30 +0300
+Subject: media: streamzap: fix race between device disconnection and urb
+ callback
+
+From: Murad Masimov <m.masimov@mt-integration.ru>
+
+[ Upstream commit f656cfbc7a293a039d6a0c7100e1c846845148c1 ]
+
+Syzkaller has reported a general protection fault at function
+ir_raw_event_store_with_filter(). This crash is caused by a NULL pointer
+dereference of dev->raw pointer, even though it is checked for NULL in
+the same function, which means there is a race condition. It occurs due
+to the incorrect order of actions in the streamzap_disconnect() function:
+rc_unregister_device() is called before usb_kill_urb(). The dev->raw
+pointer is freed and set to NULL in rc_unregister_device(), and only
+after that usb_kill_urb() waits for in-progress requests to finish.
+
+If rc_unregister_device() is called while streamzap_callback() handler is
+not finished, this can lead to accessing freed resources. Thus
+rc_unregister_device() should be called after usb_kill_urb().
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: 8e9e60640067 ("V4L/DVB: staging/lirc: port lirc_streamzap to ir-core")
+Cc: stable@vger.kernel.org
+Reported-by: syzbot+34008406ee9a31b13c73@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=34008406ee9a31b13c73
+Signed-off-by: Murad Masimov <m.masimov@mt-integration.ru>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/rc/streamzap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
+index cd994e27362eb..c0a48f991d9d2 100644
+--- a/drivers/media/rc/streamzap.c
++++ b/drivers/media/rc/streamzap.c
+@@ -433,8 +433,8 @@ static void streamzap_disconnect(struct usb_interface *interface)
+       if (!sz)
+               return;
+-      rc_unregister_device(sz->rdev);
+       usb_kill_urb(sz->urb_in);
++      rc_unregister_device(sz->rdev);
+       usb_free_urb(sz->urb_in);
+       usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in);
+-- 
+2.39.5
+
diff --git a/queue-5.10/media-streamzap-less-chatter.patch b/queue-5.10/media-streamzap-less-chatter.patch
new file mode 100644 (file)
index 0000000..4264947
--- /dev/null
@@ -0,0 +1,82 @@
+From 6bc7009d9eadddd40c2c174b7e88d677d3a88733 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Dec 2021 22:38:20 +0100
+Subject: media: streamzap: less chatter
+
+From: Sean Young <sean@mess.org>
+
+[ Upstream commit 35088717ad24140b6ab0ec00ef357709be607526 ]
+
+Remove superfluous messages which add no information.
+
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f656cfbc7a29 ("media: streamzap: fix race between device disconnection and urb callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/rc/streamzap.c | 20 +-------------------
+ 1 file changed, 1 insertion(+), 19 deletions(-)
+
+diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
+index b6391ad383143..e862a866b9b0f 100644
+--- a/drivers/media/rc/streamzap.c
++++ b/drivers/media/rc/streamzap.c
+@@ -26,7 +26,6 @@
+ #include <linux/usb/input.h>
+ #include <media/rc-core.h>
+-#define DRIVER_VERSION        "1.61"
+ #define DRIVER_NAME   "streamzap"
+ #define DRIVER_DESC   "Streamzap Remote Control driver"
+@@ -281,10 +280,8 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
+       int ret;
+       rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
+-      if (!rdev) {
+-              dev_err(dev, "remote dev allocation failed\n");
++      if (!rdev)
+               goto out;
+-      }
+       usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys));
+       strlcat(sz->phys, "/input0", sizeof(sz->phys));
+@@ -324,7 +321,6 @@ static int streamzap_probe(struct usb_interface *intf,
+       struct usb_device *usbdev = interface_to_usbdev(intf);
+       struct usb_host_interface *iface_host;
+       struct streamzap_ir *sz = NULL;
+-      char buf[63], name[128] = "";
+       int retval = -ENOMEM;
+       int pipe, maxp;
+@@ -383,17 +379,6 @@ static int streamzap_probe(struct usb_interface *intf,
+       sz->dev = &intf->dev;
+       sz->buf_in_len = maxp;
+-      if (usbdev->descriptor.iManufacturer
+-          && usb_string(usbdev, usbdev->descriptor.iManufacturer,
+-                        buf, sizeof(buf)) > 0)
+-              strscpy(name, buf, sizeof(name));
+-
+-      if (usbdev->descriptor.iProduct
+-          && usb_string(usbdev, usbdev->descriptor.iProduct,
+-                        buf, sizeof(buf)) > 0)
+-              snprintf(name + strlen(name), sizeof(name) - strlen(name),
+-                       " %s", buf);
+-
+       sz->rdev = streamzap_init_rc_dev(sz);
+       if (!sz->rdev)
+               goto rc_dev_fail;
+@@ -424,9 +409,6 @@ static int streamzap_probe(struct usb_interface *intf,
+       if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
+               dev_err(sz->dev, "urb submit failed\n");
+-      dev_info(sz->dev, "Registered %s on usb%d:%d\n", name,
+-               usbdev->bus->busnum, usbdev->devnum);
+-
+       return 0;
+ rc_dev_fail:
+-- 
+2.39.5
+
diff --git a/queue-5.10/media-streamzap-no-need-for-usb-pid-vid-in-device-na.patch b/queue-5.10/media-streamzap-no-need-for-usb-pid-vid-in-device-na.patch
new file mode 100644 (file)
index 0000000..066b3df
--- /dev/null
@@ -0,0 +1,50 @@
+From b3896ae1ac76c9b0870e211a28f2cdea2b7a86d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Dec 2021 18:10:36 +0100
+Subject: media: streamzap: no need for usb pid/vid in device name
+
+From: Sean Young <sean@mess.org>
+
+[ Upstream commit 7a25e6849ad73de5aa01d62da43071bc02b8530c ]
+
+The usb pid/vid can be found elsewhere, the idVendor/idProduct usb sysfs
+files for example.
+
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f656cfbc7a29 ("media: streamzap: fix race between device disconnection and urb callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/rc/streamzap.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
+index cd4bb605a7614..b6391ad383143 100644
+--- a/drivers/media/rc/streamzap.c
++++ b/drivers/media/rc/streamzap.c
+@@ -88,7 +88,6 @@ struct streamzap_ir {
+       ktime_t                 signal_start;
+       bool                    timeout_enabled;
+-      char                    name[128];
+       char                    phys[64];
+ };
+@@ -287,13 +286,10 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
+               goto out;
+       }
+-      snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared Receiver (%04x:%04x)",
+-               le16_to_cpu(sz->usbdev->descriptor.idVendor),
+-               le16_to_cpu(sz->usbdev->descriptor.idProduct));
+       usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys));
+       strlcat(sz->phys, "/input0", sizeof(sz->phys));
+-      rdev->device_name = sz->name;
++      rdev->device_name = "Streamzap PC Remote Infrared Receiver";
+       rdev->input_phys = sz->phys;
+       usb_to_input_id(sz->usbdev, &rdev->input_id);
+       rdev->dev.parent = dev;
+-- 
+2.39.5
+
diff --git a/queue-5.10/media-streamzap-remove-unnecessary-ir_raw_event_rese.patch b/queue-5.10/media-streamzap-remove-unnecessary-ir_raw_event_rese.patch
new file mode 100644 (file)
index 0000000..047ae58
--- /dev/null
@@ -0,0 +1,38 @@
+From 898eeec1c636914231d739ee44e005aae3bc9995 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 5 Dec 2021 18:06:30 +0100
+Subject: media: streamzap: remove unnecessary ir_raw_event_reset and handle
+
+From: Sean Young <sean@mess.org>
+
+[ Upstream commit 4bed9306050497f49cbe77b842f0d812f4f27593 ]
+
+There is no reason to have a reset after an IR timeout.
+Calling ir_raw_event_handle() twice for the same interrupt has no
+affect.
+
+Fixes: 56b0ec30c4bc ("[media] rc/streamzap: fix reporting response times")
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f656cfbc7a29 ("media: streamzap: fix race between device disconnection and urb callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/rc/streamzap.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
+index b6bd3cbec7c7c..cd4bb605a7614 100644
+--- a/drivers/media/rc/streamzap.c
++++ b/drivers/media/rc/streamzap.c
+@@ -215,8 +215,6 @@ static void sz_process_ir_data(struct streamzap_ir *sz, int len)
+                               sz->idle = true;
+                               if (sz->timeout_enabled)
+                                       sz_push(sz, rawir);
+-                              ir_raw_event_handle(sz->rdev);
+-                              ir_raw_event_reset(sz->rdev);
+                       } else {
+                               sz_push_full_space(sz, sz->buf_in[i]);
+                       }
+-- 
+2.39.5
+
diff --git a/queue-5.10/media-streamzap-remove-unused-struct-members.patch b/queue-5.10/media-streamzap-remove-unused-struct-members.patch
new file mode 100644 (file)
index 0000000..18ac4e9
--- /dev/null
@@ -0,0 +1,160 @@
+From 40924984f233b4448773a81cb80848f9a4163eac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Dec 2021 11:59:41 +0100
+Subject: media: streamzap: remove unused struct members
+
+From: Sean Young <sean@mess.org>
+
+[ Upstream commit 4df69e46c352df9bdbe859824da33428a3ce8a1d ]
+
+These struct members do not serve any purpose.
+
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: f656cfbc7a29 ("media: streamzap: fix race between device disconnection and urb callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/rc/streamzap.c | 37 ++++++++++++++----------------------
+ 1 file changed, 14 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
+index e862a866b9b0f..cd994e27362eb 100644
+--- a/drivers/media/rc/streamzap.c
++++ b/drivers/media/rc/streamzap.c
+@@ -66,9 +66,6 @@ struct streamzap_ir {
+       struct device *dev;
+       /* usb */
+-      struct usb_device       *usbdev;
+-      struct usb_interface    *interface;
+-      struct usb_endpoint_descriptor *endpoint;
+       struct urb              *urb_in;
+       /* buffer & dma */
+@@ -85,7 +82,6 @@ struct streamzap_ir {
+       /* start time of signal; necessary for gap tracking */
+       ktime_t                 signal_last;
+       ktime_t                 signal_start;
+-      bool                    timeout_enabled;
+       char                    phys[64];
+ };
+@@ -211,8 +207,7 @@ static void sz_process_ir_data(struct streamzap_ir *sz, int len)
+                                       .duration = sz->rdev->timeout
+                               };
+                               sz->idle = true;
+-                              if (sz->timeout_enabled)
+-                                      sz_push(sz, rawir);
++                              sz_push(sz, rawir);
+                       } else {
+                               sz_push_full_space(sz, sz->buf_in[i]);
+                       }
+@@ -273,7 +268,8 @@ static void streamzap_callback(struct urb *urb)
+       return;
+ }
+-static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
++static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz,
++                                          struct usb_device *usbdev)
+ {
+       struct rc_dev *rdev;
+       struct device *dev = sz->dev;
+@@ -283,12 +279,12 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
+       if (!rdev)
+               goto out;
+-      usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys));
++      usb_make_path(usbdev, sz->phys, sizeof(sz->phys));
+       strlcat(sz->phys, "/input0", sizeof(sz->phys));
+       rdev->device_name = "Streamzap PC Remote Infrared Receiver";
+       rdev->input_phys = sz->phys;
+-      usb_to_input_id(sz->usbdev, &rdev->input_id);
++      usb_to_input_id(usbdev, &rdev->input_id);
+       rdev->dev.parent = dev;
+       rdev->priv = sz;
+       rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
+@@ -319,6 +315,7 @@ static int streamzap_probe(struct usb_interface *intf,
+                          const struct usb_device_id *id)
+ {
+       struct usb_device *usbdev = interface_to_usbdev(intf);
++      struct usb_endpoint_descriptor *endpoint;
+       struct usb_host_interface *iface_host;
+       struct streamzap_ir *sz = NULL;
+       int retval = -ENOMEM;
+@@ -329,9 +326,6 @@ static int streamzap_probe(struct usb_interface *intf,
+       if (!sz)
+               return -ENOMEM;
+-      sz->usbdev = usbdev;
+-      sz->interface = intf;
+-
+       /* Check to ensure endpoint information matches requirements */
+       iface_host = intf->cur_altsetting;
+@@ -342,22 +336,22 @@ static int streamzap_probe(struct usb_interface *intf,
+               goto free_sz;
+       }
+-      sz->endpoint = &(iface_host->endpoint[0].desc);
+-      if (!usb_endpoint_dir_in(sz->endpoint)) {
++      endpoint = &iface_host->endpoint[0].desc;
++      if (!usb_endpoint_dir_in(endpoint)) {
+               dev_err(&intf->dev, "%s: endpoint doesn't match input device 02%02x\n",
+-                      __func__, sz->endpoint->bEndpointAddress);
++                      __func__, endpoint->bEndpointAddress);
+               retval = -ENODEV;
+               goto free_sz;
+       }
+-      if (!usb_endpoint_xfer_int(sz->endpoint)) {
++      if (!usb_endpoint_xfer_int(endpoint)) {
+               dev_err(&intf->dev, "%s: endpoint attributes don't match xfer 02%02x\n",
+-                      __func__, sz->endpoint->bmAttributes);
++                      __func__, endpoint->bmAttributes);
+               retval = -ENODEV;
+               goto free_sz;
+       }
+-      pipe = usb_rcvintpipe(usbdev, sz->endpoint->bEndpointAddress);
++      pipe = usb_rcvintpipe(usbdev, endpoint->bEndpointAddress);
+       maxp = usb_maxpacket(usbdev, pipe, usb_pipeout(pipe));
+       if (maxp == 0) {
+@@ -379,14 +373,13 @@ static int streamzap_probe(struct usb_interface *intf,
+       sz->dev = &intf->dev;
+       sz->buf_in_len = maxp;
+-      sz->rdev = streamzap_init_rc_dev(sz);
++      sz->rdev = streamzap_init_rc_dev(sz, usbdev);
+       if (!sz->rdev)
+               goto rc_dev_fail;
+       sz->idle = true;
+       sz->decoder_state = PulseSpace;
+       /* FIXME: don't yet have a way to set this */
+-      sz->timeout_enabled = true;
+       sz->rdev->timeout = SZ_TIMEOUT * SZ_RESOLUTION;
+       #if 0
+       /* not yet supported, depends on patches from maxim */
+@@ -399,8 +392,7 @@ static int streamzap_probe(struct usb_interface *intf,
+       /* Complete final initialisations */
+       usb_fill_int_urb(sz->urb_in, usbdev, pipe, sz->buf_in,
+-                       maxp, (usb_complete_t)streamzap_callback,
+-                       sz, sz->endpoint->bInterval);
++                       maxp, streamzap_callback, sz, endpoint->bInterval);
+       sz->urb_in->transfer_dma = sz->dma_in;
+       sz->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+@@ -441,7 +433,6 @@ static void streamzap_disconnect(struct usb_interface *interface)
+       if (!sz)
+               return;
+-      sz->usbdev = NULL;
+       rc_unregister_device(sz->rdev);
+       usb_kill_urb(sz->urb_in);
+       usb_free_urb(sz->urb_in);
+-- 
+2.39.5
+
diff --git a/queue-5.10/media-venus-create-hfi-platform-and-move-vpp-vsp-the.patch b/queue-5.10/media-venus-create-hfi-platform-and-move-vpp-vsp-the.patch
new file mode 100644 (file)
index 0000000..56fb855
--- /dev/null
@@ -0,0 +1,488 @@
+From 4438dabf3e3dfa5894370f1bd66b855bc1d7d948 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Aug 2020 09:36:06 +0200
+Subject: media: venus: Create hfi platform and move vpp/vsp there
+
+From: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+
+[ Upstream commit aa6033892b1d8ea956ce0358867806e171a620d1 ]
+
+Introduce a new hfi platform to cover differences between hfi
+versions. As a start move vpp/vsp freq data in that hfi
+platform, more platform data will come later.
+
+Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: 9edaaa8e3e15 ("media: venus: hfi_parser: refactor hfi packet parsing logic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/venus/Makefile    |  3 +-
+ drivers/media/platform/qcom/venus/core.c      | 17 ------
+ drivers/media/platform/qcom/venus/core.h      | 12 +---
+ drivers/media/platform/qcom/venus/helpers.c   | 54 ++++++++---------
+ drivers/media/platform/qcom/venus/helpers.h   |  2 +-
+ .../media/platform/qcom/venus/hfi_platform.c  | 49 +++++++++++++++
+ .../media/platform/qcom/venus/hfi_platform.h  | 34 +++++++++++
+ .../platform/qcom/venus/hfi_platform_v4.c     | 60 +++++++++++++++++++
+ .../media/platform/qcom/venus/pm_helpers.c    |  9 +--
+ drivers/media/platform/qcom/venus/vdec.c      |  6 +-
+ drivers/media/platform/qcom/venus/venc.c      |  6 +-
+ 11 files changed, 179 insertions(+), 73 deletions(-)
+ create mode 100644 drivers/media/platform/qcom/venus/hfi_platform.c
+ create mode 100644 drivers/media/platform/qcom/venus/hfi_platform.h
+ create mode 100644 drivers/media/platform/qcom/venus/hfi_platform_v4.c
+
+diff --git a/drivers/media/platform/qcom/venus/Makefile b/drivers/media/platform/qcom/venus/Makefile
+index dfc6368657091..09ebf46716925 100644
+--- a/drivers/media/platform/qcom/venus/Makefile
++++ b/drivers/media/platform/qcom/venus/Makefile
+@@ -3,7 +3,8 @@
+ venus-core-objs += core.o helpers.o firmware.o \
+                  hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o \
+-                 hfi_parser.o pm_helpers.o dbgfs.o
++                 hfi_parser.o pm_helpers.o dbgfs.o \
++                 hfi_platform.o hfi_platform_v4.o \
+ venus-dec-objs += vdec.o vdec_ctrls.o
+ venus-enc-objs += venc.o venc_ctrls.o
+diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
+index 1859dd3f7f546..987b1d010c047 100644
+--- a/drivers/media/platform/qcom/venus/core.c
++++ b/drivers/media/platform/qcom/venus/core.c
+@@ -529,17 +529,6 @@ static const struct freq_tbl sdm845_freq_table[] = {
+       {  244800, 100000000 }, /* 1920x1080@30 */
+ };
+-static const struct codec_freq_data sdm845_codec_freq_data[] =  {
+-      { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_ENC, 675, 10 },
+-      { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_ENC, 675, 10 },
+-      { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_ENC, 675, 10 },
+-      { V4L2_PIX_FMT_MPEG2, VIDC_SESSION_TYPE_DEC, 200, 10 },
+-      { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_DEC, 200, 10 },
+-      { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_DEC, 200, 10 },
+-      { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_DEC, 200, 10 },
+-      { V4L2_PIX_FMT_VP9, VIDC_SESSION_TYPE_DEC, 200, 10 },
+-};
+-
+ static const struct bw_tbl sdm845_bw_table_enc[] = {
+       { 1944000, 1612000, 0, 2416000, 0 },    /* 3840x2160@60 */
+       {  972000,  951000, 0, 1434000, 0 },    /* 3840x2160@30 */
+@@ -561,8 +550,6 @@ static const struct venus_resources sdm845_res = {
+       .bw_tbl_enc_size = ARRAY_SIZE(sdm845_bw_table_enc),
+       .bw_tbl_dec = sdm845_bw_table_dec,
+       .bw_tbl_dec_size = ARRAY_SIZE(sdm845_bw_table_dec),
+-      .codec_freq_data = sdm845_codec_freq_data,
+-      .codec_freq_data_size = ARRAY_SIZE(sdm845_codec_freq_data),
+       .clks = {"core", "iface", "bus" },
+       .clks_num = 3,
+       .vcodec0_clks = { "core", "bus" },
+@@ -584,8 +571,6 @@ static const struct venus_resources sdm845_res_v2 = {
+       .bw_tbl_enc_size = ARRAY_SIZE(sdm845_bw_table_enc),
+       .bw_tbl_dec = sdm845_bw_table_dec,
+       .bw_tbl_dec_size = ARRAY_SIZE(sdm845_bw_table_dec),
+-      .codec_freq_data = sdm845_codec_freq_data,
+-      .codec_freq_data_size = ARRAY_SIZE(sdm845_codec_freq_data),
+       .clks = {"core", "iface", "bus" },
+       .clks_num = 3,
+       .vcodec0_clks = { "vcodec0_core", "vcodec0_bus" },
+@@ -635,8 +620,6 @@ static const struct venus_resources sc7180_res = {
+       .bw_tbl_enc_size = ARRAY_SIZE(sc7180_bw_table_enc),
+       .bw_tbl_dec = sc7180_bw_table_dec,
+       .bw_tbl_dec_size = ARRAY_SIZE(sc7180_bw_table_dec),
+-      .codec_freq_data = sdm845_codec_freq_data,
+-      .codec_freq_data_size = ARRAY_SIZE(sdm845_codec_freq_data),
+       .clks = {"core", "iface", "bus" },
+       .clks_num = 3,
+       .vcodec0_clks = { "vcodec0_core", "vcodec0_bus" },
+diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
+index e56d7b8142152..53d3202460ae9 100644
+--- a/drivers/media/platform/qcom/venus/core.h
++++ b/drivers/media/platform/qcom/venus/core.h
+@@ -36,13 +36,6 @@ struct reg_val {
+       u32 value;
+ };
+-struct codec_freq_data {
+-      u32 pixfmt;
+-      u32 session_type;
+-      unsigned long vpp_freq;
+-      unsigned long vsp_freq;
+-};
+-
+ struct bw_tbl {
+       u32 mbs_per_sec;
+       u32 avg;
+@@ -61,8 +54,6 @@ struct venus_resources {
+       unsigned int bw_tbl_dec_size;
+       const struct reg_val *reg_tbl;
+       unsigned int reg_tbl_size;
+-      const struct codec_freq_data *codec_freq_data;
+-      unsigned int codec_freq_data_size;
+       const char * const clks[VIDC_CLKS_NUM_MAX];
+       unsigned int clks_num;
+       const char * const vcodec0_clks[VIDC_VCODEC_CLKS_NUM_MAX];
+@@ -280,7 +271,8 @@ struct venus_buffer {
+ struct clock_data {
+       u32 core_id;
+       unsigned long freq;
+-      const struct codec_freq_data *codec_freq_data;
++      unsigned long vpp_freq;
++      unsigned long vsp_freq;
+ };
+ #define to_venus_buffer(ptr)  container_of(ptr, struct venus_buffer, vb)
+diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c
+index 5fdce5f07364e..9ad8abdc4d4f2 100644
+--- a/drivers/media/platform/qcom/venus/helpers.c
++++ b/drivers/media/platform/qcom/venus/helpers.c
+@@ -15,6 +15,7 @@
+ #include "helpers.h"
+ #include "hfi_helper.h"
+ #include "pm_helpers.h"
++#include "hfi_platform.h"
+ struct intbuf {
+       struct list_head list;
+@@ -1040,36 +1041,6 @@ int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode)
+ }
+ EXPORT_SYMBOL_GPL(venus_helper_set_work_mode);
+-int venus_helper_init_codec_freq_data(struct venus_inst *inst)
+-{
+-      const struct codec_freq_data *data;
+-      unsigned int i, data_size;
+-      u32 pixfmt;
+-      int ret = 0;
+-
+-      if (!IS_V4(inst->core))
+-              return 0;
+-
+-      data = inst->core->res->codec_freq_data;
+-      data_size = inst->core->res->codec_freq_data_size;
+-      pixfmt = inst->session_type == VIDC_SESSION_TYPE_DEC ?
+-                      inst->fmt_out->pixfmt : inst->fmt_cap->pixfmt;
+-
+-      for (i = 0; i < data_size; i++) {
+-              if (data[i].pixfmt == pixfmt &&
+-                  data[i].session_type == inst->session_type) {
+-                      inst->clk_data.codec_freq_data = &data[i];
+-                      break;
+-              }
+-      }
+-
+-      if (!inst->clk_data.codec_freq_data)
+-              ret = -EINVAL;
+-
+-      return ret;
+-}
+-EXPORT_SYMBOL_GPL(venus_helper_init_codec_freq_data);
+-
+ int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
+                             unsigned int output_bufs,
+                             unsigned int output2_bufs)
+@@ -1535,6 +1506,29 @@ void venus_helper_m2m_job_abort(void *priv)
+ }
+ EXPORT_SYMBOL_GPL(venus_helper_m2m_job_abort);
++int venus_helper_session_init(struct venus_inst *inst)
++{
++      enum hfi_version version = inst->core->res->hfi_version;
++      u32 session_type = inst->session_type;
++      u32 codec;
++      int ret;
++
++      codec = inst->session_type == VIDC_SESSION_TYPE_DEC ?
++                      inst->fmt_out->pixfmt : inst->fmt_cap->pixfmt;
++
++      ret = hfi_session_init(inst, codec);
++      if (ret)
++              return ret;
++
++      inst->clk_data.vpp_freq = hfi_platform_get_codec_vpp_freq(version, codec,
++                                                                session_type);
++      inst->clk_data.vsp_freq = hfi_platform_get_codec_vsp_freq(version, codec,
++                                                                session_type);
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(venus_helper_session_init);
++
+ void venus_helper_init_instance(struct venus_inst *inst)
+ {
+       if (inst->session_type == VIDC_SESSION_TYPE_DEC) {
+diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h
+index a4a0562bc83f5..5407979bf234b 100644
+--- a/drivers/media/platform/qcom/venus/helpers.h
++++ b/drivers/media/platform/qcom/venus/helpers.h
+@@ -33,7 +33,6 @@ int venus_helper_set_output_resolution(struct venus_inst *inst,
+                                      unsigned int width, unsigned int height,
+                                      u32 buftype);
+ int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode);
+-int venus_helper_init_codec_freq_data(struct venus_inst *inst);
+ int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
+                             unsigned int output_bufs,
+                             unsigned int output2_bufs);
+@@ -48,6 +47,7 @@ unsigned int venus_helper_get_opb_size(struct venus_inst *inst);
+ void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf);
+ void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx);
+ void venus_helper_init_instance(struct venus_inst *inst);
++int venus_helper_session_init(struct venus_inst *inst);
+ int venus_helper_get_out_fmts(struct venus_inst *inst, u32 fmt, u32 *out_fmt,
+                             u32 *out2_fmt, bool ubwc);
+ int venus_helper_alloc_dpb_bufs(struct venus_inst *inst);
+diff --git a/drivers/media/platform/qcom/venus/hfi_platform.c b/drivers/media/platform/qcom/venus/hfi_platform.c
+new file mode 100644
+index 0000000000000..65559cae21aaa
+--- /dev/null
++++ b/drivers/media/platform/qcom/venus/hfi_platform.c
+@@ -0,0 +1,49 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
++ */
++#include "hfi_platform.h"
++
++const struct hfi_platform *hfi_platform_get(enum hfi_version version)
++{
++      switch (version) {
++      case HFI_VERSION_4XX:
++              return &hfi_plat_v4;
++      default:
++              break;
++      }
++
++      return NULL;
++}
++
++unsigned long
++hfi_platform_get_codec_vpp_freq(enum hfi_version version, u32 codec, u32 session_type)
++{
++      const struct hfi_platform *plat;
++      unsigned long freq = 0;
++
++      plat = hfi_platform_get(version);
++      if (!plat)
++              return 0;
++
++      if (plat->codec_vpp_freq)
++              freq = plat->codec_vpp_freq(session_type, codec);
++
++      return freq;
++}
++
++unsigned long
++hfi_platform_get_codec_vsp_freq(enum hfi_version version, u32 codec, u32 session_type)
++{
++      const struct hfi_platform *plat;
++      unsigned long freq = 0;
++
++      plat = hfi_platform_get(version);
++      if (!plat)
++              return 0;
++
++      if (plat->codec_vpp_freq)
++              freq = plat->codec_vsp_freq(session_type, codec);
++
++      return freq;
++}
+diff --git a/drivers/media/platform/qcom/venus/hfi_platform.h b/drivers/media/platform/qcom/venus/hfi_platform.h
+new file mode 100644
+index 0000000000000..8b07ecbb4c825
+--- /dev/null
++++ b/drivers/media/platform/qcom/venus/hfi_platform.h
+@@ -0,0 +1,34 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
++ */
++
++#ifndef __HFI_PLATFORM_H__
++#define __HFI_PLATFORM_H__
++
++#include <linux/types.h>
++#include <linux/videodev2.h>
++
++#include "hfi.h"
++#include "hfi_helper.h"
++
++struct hfi_platform_codec_freq_data {
++      u32 pixfmt;
++      u32 session_type;
++      unsigned long vpp_freq;
++      unsigned long vsp_freq;
++};
++
++struct hfi_platform {
++      unsigned long (*codec_vpp_freq)(u32 session_type, u32 codec);
++      unsigned long (*codec_vsp_freq)(u32 session_type, u32 codec);
++};
++
++extern const struct hfi_platform hfi_plat_v4;
++
++const struct hfi_platform *hfi_platform_get(enum hfi_version version);
++unsigned long hfi_platform_get_codec_vpp_freq(enum hfi_version version, u32 codec,
++                                            u32 session_type);
++unsigned long hfi_platform_get_codec_vsp_freq(enum hfi_version version, u32 codec,
++                                            u32 session_type);
++#endif
+diff --git a/drivers/media/platform/qcom/venus/hfi_platform_v4.c b/drivers/media/platform/qcom/venus/hfi_platform_v4.c
+new file mode 100644
+index 0000000000000..4fc2fd04ca9d1
+--- /dev/null
++++ b/drivers/media/platform/qcom/venus/hfi_platform_v4.c
+@@ -0,0 +1,60 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
++ */
++#include "hfi_platform.h"
++
++static const struct hfi_platform_codec_freq_data codec_freq_data[] =  {
++      { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_ENC, 675, 10 },
++      { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_ENC, 675, 10 },
++      { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_ENC, 675, 10 },
++      { V4L2_PIX_FMT_MPEG2, VIDC_SESSION_TYPE_DEC, 200, 10 },
++      { V4L2_PIX_FMT_H264, VIDC_SESSION_TYPE_DEC, 200, 10 },
++      { V4L2_PIX_FMT_HEVC, VIDC_SESSION_TYPE_DEC, 200, 10 },
++      { V4L2_PIX_FMT_VP8, VIDC_SESSION_TYPE_DEC, 200, 10 },
++      { V4L2_PIX_FMT_VP9, VIDC_SESSION_TYPE_DEC, 200, 10 },
++};
++
++static const struct hfi_platform_codec_freq_data *
++get_codec_freq_data(u32 session_type, u32 pixfmt)
++{
++      const struct hfi_platform_codec_freq_data *data = codec_freq_data;
++      unsigned int i, data_size = ARRAY_SIZE(codec_freq_data);
++      const struct hfi_platform_codec_freq_data *found = NULL;
++
++      for (i = 0; i < data_size; i++) {
++              if (data[i].pixfmt == pixfmt && data[i].session_type == session_type) {
++                      found = &data[i];
++                      break;
++              }
++      }
++
++      return found;
++}
++
++static unsigned long codec_vpp_freq(u32 session_type, u32 codec)
++{
++      const struct hfi_platform_codec_freq_data *data;
++
++      data = get_codec_freq_data(session_type, codec);
++      if (data)
++              return data->vpp_freq;
++
++      return 0;
++}
++
++static unsigned long codec_vsp_freq(u32 session_type, u32 codec)
++{
++      const struct hfi_platform_codec_freq_data *data;
++
++      data = get_codec_freq_data(session_type, codec);
++      if (data)
++              return data->vsp_freq;
++
++      return 0;
++}
++
++const struct hfi_platform hfi_plat_v4 = {
++      .codec_vpp_freq = codec_vpp_freq,
++      .codec_vsp_freq = codec_vsp_freq,
++};
+diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c
+index 12c5811fefdf9..7c3541c35ab69 100644
+--- a/drivers/media/platform/qcom/venus/pm_helpers.c
++++ b/drivers/media/platform/qcom/venus/pm_helpers.c
+@@ -18,6 +18,7 @@
+ #include "hfi_parser.h"
+ #include "hfi_venus_io.h"
+ #include "pm_helpers.h"
++#include "hfi_platform.h"
+ static bool legacy_binding;
+@@ -506,7 +507,7 @@ min_loaded_core(struct venus_inst *inst, u32 *min_coreid, u32 *min_load)
+               if (inst_pos->state != INST_START)
+                       continue;
+-              vpp_freq = inst_pos->clk_data.codec_freq_data->vpp_freq;
++              vpp_freq = inst_pos->clk_data.vpp_freq;
+               coreid = inst_pos->clk_data.core_id;
+               mbs_per_sec = load_per_instance(inst_pos);
+@@ -555,7 +556,7 @@ static int decide_core(struct venus_inst *inst)
+               return 0;
+       inst_load = load_per_instance(inst);
+-      inst_load *= inst->clk_data.codec_freq_data->vpp_freq;
++      inst_load *= inst->clk_data.vpp_freq;
+       max_freq = core->res->freq_tbl[0].freq;
+       min_loaded_core(inst, &min_coreid, &min_load);
+@@ -940,10 +941,10 @@ static unsigned long calculate_inst_freq(struct venus_inst *inst,
+       if (inst->state != INST_START)
+               return 0;
+-      vpp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vpp_freq;
++      vpp_freq = mbs_per_sec * inst->clk_data.vpp_freq;
+       /* 21 / 20 is overhead factor */
+       vpp_freq += vpp_freq / 20;
+-      vsp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vsp_freq;
++      vsp_freq = mbs_per_sec * inst->clk_data.vsp_freq;
+       /* 10 / 7 is overhead factor */
+       if (inst->session_type == VIDC_SESSION_TYPE_ENC)
+diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
+index 6e9b62645e917..68390143d37df 100644
+--- a/drivers/media/platform/qcom/venus/vdec.c
++++ b/drivers/media/platform/qcom/venus/vdec.c
+@@ -767,7 +767,7 @@ static int vdec_session_init(struct venus_inst *inst)
+ {
+       int ret;
+-      ret = hfi_session_init(inst, inst->fmt_out->pixfmt);
++      ret = venus_helper_session_init(inst);
+       if (ret == -EALREADY)
+               return 0;
+       else if (ret)
+@@ -778,10 +778,6 @@ static int vdec_session_init(struct venus_inst *inst)
+       if (ret)
+               goto deinit;
+-      ret = venus_helper_init_codec_freq_data(inst);
+-      if (ret)
+-              goto deinit;
+-
+       return 0;
+ deinit:
+       hfi_session_deinit(inst);
+diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c
+index 9f1b02e31b98c..bc62cb02458c9 100644
+--- a/drivers/media/platform/qcom/venus/venc.c
++++ b/drivers/media/platform/qcom/venus/venc.c
+@@ -726,7 +726,7 @@ static int venc_init_session(struct venus_inst *inst)
+ {
+       int ret;
+-      ret = hfi_session_init(inst, inst->fmt_cap->pixfmt);
++      ret = venus_helper_session_init(inst);
+       if (ret == -EALREADY)
+               return 0;
+       else if (ret)
+@@ -747,10 +747,6 @@ static int venc_init_session(struct venus_inst *inst)
+       if (ret)
+               goto deinit;
+-      ret = venus_helper_init_codec_freq_data(inst);
+-      if (ret)
+-              goto deinit;
+-
+       ret = venc_set_properties(inst);
+       if (ret)
+               goto deinit;
+-- 
+2.39.5
+
diff --git a/queue-5.10/media-venus-get-codecs-and-capabilities-from-hfi-pla.patch b/queue-5.10/media-venus-get-codecs-and-capabilities-from-hfi-pla.patch
new file mode 100644 (file)
index 0000000..f5569bb
--- /dev/null
@@ -0,0 +1,77 @@
+From b72aa94cdf7b6f5002476e6cb28fb452466fd926 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Aug 2020 14:39:13 +0200
+Subject: media: venus: Get codecs and capabilities from hfi platform
+
+From: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+
+[ Upstream commit e29929266be1ac0e40121f56b5c13b52c281db06 ]
+
+Wire up hfi platform codec and capabilities instead of
+getting them from firmware.
+
+Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: 9edaaa8e3e15 ("media: venus: hfi_parser: refactor hfi packet parsing logic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/platform/qcom/venus/hfi_parser.c    | 38 +++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c
+index be9a58ef04d86..7a2915befdb83 100644
+--- a/drivers/media/platform/qcom/venus/hfi_parser.c
++++ b/drivers/media/platform/qcom/venus/hfi_parser.c
+@@ -245,11 +245,49 @@ static void parser_fini(struct venus_inst *inst, u32 codecs, u32 domain)
+       }
+ }
++static int hfi_platform_parser(struct venus_core *core, struct venus_inst *inst)
++{
++      const struct hfi_platform *plat;
++      const struct hfi_plat_caps *caps = NULL;
++      u32 enc_codecs, dec_codecs, count;
++      unsigned int entries;
++
++      if (inst)
++              return 0;
++
++      plat = hfi_platform_get(core->res->hfi_version);
++      if (!plat)
++              return -EINVAL;
++
++      if (plat->codecs)
++              plat->codecs(&enc_codecs, &dec_codecs, &count);
++
++      if (plat->capabilities)
++              caps = plat->capabilities(&entries);
++
++      if (!caps || !entries || !count)
++              return -EINVAL;
++
++      core->enc_codecs = enc_codecs;
++      core->dec_codecs = dec_codecs;
++      core->codecs_count = count;
++      core->max_sessions_supported = MAX_SESSIONS;
++      memset(core->caps, 0, sizeof(*caps) * MAX_CODEC_NUM);
++      memcpy(core->caps, caps, sizeof(*caps) * entries);
++
++      return 0;
++}
++
+ u32 hfi_parser(struct venus_core *core, struct venus_inst *inst, void *buf,
+              u32 size)
+ {
+       unsigned int words_count = size >> 2;
+       u32 *word = buf, *data, codecs = 0, domain = 0;
++      int ret;
++
++      ret = hfi_platform_parser(core, inst);
++      if (!ret)
++              return HFI_ERR_NONE;
+       if (size % 4)
+               return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+-- 
+2.39.5
+
diff --git a/queue-5.10/media-venus-hfi-correct-session-init-return-error.patch b/queue-5.10/media-venus-hfi-correct-session-init-return-error.patch
new file mode 100644 (file)
index 0000000..3f60d05
--- /dev/null
@@ -0,0 +1,68 @@
+From 9ed7bb77a925d0cf613d008ab9a8c0dbde56dc67 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Dec 2020 11:01:39 +0100
+Subject: media: venus: hfi: Correct session init return error
+
+From: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+
+[ Upstream commit e922a33e0228fa314ffc4f70b3b9ffbc4aad1bbe ]
+
+The hfi_session_init can be called many times and it returns
+EINVAL when the session was already initialized. This error code
+(EINVAL) is confusing for the callers. Change hfi_session_init to
+return EALREADY error code when the session has been already
+initialized.
+
+Tested-by: Fritz Koenig <frkoenig@chromium.org>
+Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: 9edaaa8e3e15 ("media: venus: hfi_parser: refactor hfi packet parsing logic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/venus/hfi.c  | 2 +-
+ drivers/media/platform/qcom/venus/vdec.c | 2 +-
+ drivers/media/platform/qcom/venus/venc.c | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c
+index 17da555905e98..5fd53227c2c0b 100644
+--- a/drivers/media/platform/qcom/venus/hfi.c
++++ b/drivers/media/platform/qcom/venus/hfi.c
+@@ -212,7 +212,7 @@ int hfi_session_init(struct venus_inst *inst, u32 pixfmt)
+       int ret;
+       if (inst->state != INST_UNINIT)
+-              return -EINVAL;
++              return -EALREADY;
+       inst->hfi_codec = to_codec_type(pixfmt);
+       reinit_completion(&inst->done);
+diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
+index d91030a134c0e..6e9b62645e917 100644
+--- a/drivers/media/platform/qcom/venus/vdec.c
++++ b/drivers/media/platform/qcom/venus/vdec.c
+@@ -768,7 +768,7 @@ static int vdec_session_init(struct venus_inst *inst)
+       int ret;
+       ret = hfi_session_init(inst, inst->fmt_out->pixfmt);
+-      if (ret == -EINVAL)
++      if (ret == -EALREADY)
+               return 0;
+       else if (ret)
+               return ret;
+diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c
+index 18d20b4ca2cfd..9f1b02e31b98c 100644
+--- a/drivers/media/platform/qcom/venus/venc.c
++++ b/drivers/media/platform/qcom/venus/venc.c
+@@ -727,7 +727,7 @@ static int venc_init_session(struct venus_inst *inst)
+       int ret;
+       ret = hfi_session_init(inst, inst->fmt_cap->pixfmt);
+-      if (ret == -EINVAL)
++      if (ret == -EALREADY)
+               return 0;
+       else if (ret)
+               return ret;
+-- 
+2.39.5
+
diff --git a/queue-5.10/media-venus-hfi_parser-refactor-hfi-packet-parsing-l.patch b/queue-5.10/media-venus-hfi_parser-refactor-hfi-packet-parsing-l.patch
new file mode 100644 (file)
index 0000000..758effc
--- /dev/null
@@ -0,0 +1,275 @@
+From c3e8b918fb5a42bb217d552a8e3bbcbf9bdda9e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 22:50:09 +0530
+Subject: media: venus: hfi_parser: refactor hfi packet parsing logic
+
+From: Vikash Garodia <quic_vgarodia@quicinc.com>
+
+[ Upstream commit 9edaaa8e3e15aab1ca413ab50556de1975bcb329 ]
+
+words_count denotes the number of words in total payload, while data
+points to payload of various property within it. When words_count
+reaches last word, data can access memory beyond the total payload. This
+can lead to OOB access. With this patch, the utility api for handling
+individual properties now returns the size of data consumed. Accordingly
+remaining bytes are calculated before parsing the payload, thereby
+eliminates the OOB access possibilities.
+
+Cc: stable@vger.kernel.org
+Fixes: 1a73374a04e5 ("media: venus: hfi_parser: add common capability parser")
+Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
+Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/platform/qcom/venus/hfi_parser.c    | 98 ++++++++++++++-----
+ 1 file changed, 72 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c
+index 7a2915befdb83..c6be1564c876d 100644
+--- a/drivers/media/platform/qcom/venus/hfi_parser.c
++++ b/drivers/media/platform/qcom/venus/hfi_parser.c
+@@ -64,7 +64,7 @@ fill_buf_mode(struct hfi_plat_caps *cap, const void *data, unsigned int num)
+               cap->cap_bufs_mode_dynamic = true;
+ }
+-static void
++static int
+ parse_alloc_mode(struct venus_core *core, u32 codecs, u32 domain, void *data)
+ {
+       struct hfi_buffer_alloc_mode_supported *mode = data;
+@@ -72,7 +72,7 @@ parse_alloc_mode(struct venus_core *core, u32 codecs, u32 domain, void *data)
+       u32 *type;
+       if (num_entries > MAX_ALLOC_MODE_ENTRIES)
+-              return;
++              return -EINVAL;
+       type = mode->data;
+@@ -84,6 +84,8 @@ parse_alloc_mode(struct venus_core *core, u32 codecs, u32 domain, void *data)
+               type++;
+       }
++
++      return sizeof(*mode);
+ }
+ static void fill_profile_level(struct hfi_plat_caps *cap, const void *data,
+@@ -98,7 +100,7 @@ static void fill_profile_level(struct hfi_plat_caps *cap, const void *data,
+       cap->num_pl += num;
+ }
+-static void
++static int
+ parse_profile_level(struct venus_core *core, u32 codecs, u32 domain, void *data)
+ {
+       struct hfi_profile_level_supported *pl = data;
+@@ -106,12 +108,14 @@ parse_profile_level(struct venus_core *core, u32 codecs, u32 domain, void *data)
+       struct hfi_profile_level pl_arr[HFI_MAX_PROFILE_COUNT] = {};
+       if (pl->profile_count > HFI_MAX_PROFILE_COUNT)
+-              return;
++              return -EINVAL;
+       memcpy(pl_arr, proflevel, pl->profile_count * sizeof(*proflevel));
+       for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain,
+                      fill_profile_level, pl_arr, pl->profile_count);
++
++      return pl->profile_count * sizeof(*proflevel) + sizeof(u32);
+ }
+ static void
+@@ -126,7 +130,7 @@ fill_caps(struct hfi_plat_caps *cap, const void *data, unsigned int num)
+       cap->num_caps += num;
+ }
+-static void
++static int
+ parse_caps(struct venus_core *core, u32 codecs, u32 domain, void *data)
+ {
+       struct hfi_capabilities *caps = data;
+@@ -135,12 +139,14 @@ parse_caps(struct venus_core *core, u32 codecs, u32 domain, void *data)
+       struct hfi_capability caps_arr[MAX_CAP_ENTRIES] = {};
+       if (num_caps > MAX_CAP_ENTRIES)
+-              return;
++              return -EINVAL;
+       memcpy(caps_arr, cap, num_caps * sizeof(*cap));
+       for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain,
+                      fill_caps, caps_arr, num_caps);
++
++      return sizeof(*caps);
+ }
+ static void fill_raw_fmts(struct hfi_plat_caps *cap, const void *fmts,
+@@ -155,7 +161,7 @@ static void fill_raw_fmts(struct hfi_plat_caps *cap, const void *fmts,
+       cap->num_fmts += num_fmts;
+ }
+-static void
++static int
+ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
+ {
+       struct hfi_uncompressed_format_supported *fmt = data;
+@@ -164,7 +170,8 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
+       struct raw_formats rawfmts[MAX_FMT_ENTRIES] = {};
+       u32 entries = fmt->format_entries;
+       unsigned int i = 0;
+-      u32 num_planes;
++      u32 num_planes = 0;
++      u32 size;
+       while (entries) {
+               num_planes = pinfo->num_planes;
+@@ -174,7 +181,7 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
+               i++;
+               if (i >= MAX_FMT_ENTRIES)
+-                      return;
++                      return -EINVAL;
+               if (pinfo->num_planes > MAX_PLANES)
+                       break;
+@@ -186,9 +193,13 @@ parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
+       for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain,
+                      fill_raw_fmts, rawfmts, i);
++      size = fmt->format_entries * (sizeof(*constr) * num_planes + 2 * sizeof(u32))
++              + 2 * sizeof(u32);
++
++      return size;
+ }
+-static void parse_codecs(struct venus_core *core, void *data)
++static int parse_codecs(struct venus_core *core, void *data)
+ {
+       struct hfi_codec_supported *codecs = data;
+@@ -200,21 +211,27 @@ static void parse_codecs(struct venus_core *core, void *data)
+               core->dec_codecs &= ~HFI_VIDEO_CODEC_SPARK;
+               core->enc_codecs &= ~HFI_VIDEO_CODEC_HEVC;
+       }
++
++      return sizeof(*codecs);
+ }
+-static void parse_max_sessions(struct venus_core *core, const void *data)
++static int parse_max_sessions(struct venus_core *core, const void *data)
+ {
+       const struct hfi_max_sessions_supported *sessions = data;
+       core->max_sessions_supported = sessions->max_sessions;
++
++      return sizeof(*sessions);
+ }
+-static void parse_codecs_mask(u32 *codecs, u32 *domain, void *data)
++static int parse_codecs_mask(u32 *codecs, u32 *domain, void *data)
+ {
+       struct hfi_codec_mask_supported *mask = data;
+       *codecs = mask->codecs;
+       *domain = mask->video_domains;
++
++      return sizeof(*mask);
+ }
+ static void parser_init(struct venus_inst *inst, u32 *codecs, u32 *domain)
+@@ -281,8 +298,9 @@ static int hfi_platform_parser(struct venus_core *core, struct venus_inst *inst)
+ u32 hfi_parser(struct venus_core *core, struct venus_inst *inst, void *buf,
+              u32 size)
+ {
+-      unsigned int words_count = size >> 2;
+-      u32 *word = buf, *data, codecs = 0, domain = 0;
++      u32 *words = buf, *payload, codecs = 0, domain = 0;
++      u32 *frame_size = buf + size;
++      u32 rem_bytes = size;
+       int ret;
+       ret = hfi_platform_parser(core, inst);
+@@ -299,38 +317,66 @@ u32 hfi_parser(struct venus_core *core, struct venus_inst *inst, void *buf,
+               memset(core->caps, 0, sizeof(core->caps));
+       }
+-      while (words_count) {
+-              data = word + 1;
++      while (words < frame_size) {
++              payload = words + 1;
+-              switch (*word) {
++              switch (*words) {
+               case HFI_PROPERTY_PARAM_CODEC_SUPPORTED:
+-                      parse_codecs(core, data);
++                      if (rem_bytes <= sizeof(struct hfi_codec_supported))
++                              return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
++
++                      ret = parse_codecs(core, payload);
++                      if (ret < 0)
++                              return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
++
+                       init_codecs(core);
+                       break;
+               case HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED:
+-                      parse_max_sessions(core, data);
++                      if (rem_bytes <= sizeof(struct hfi_max_sessions_supported))
++                              return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
++
++                      ret = parse_max_sessions(core, payload);
+                       break;
+               case HFI_PROPERTY_PARAM_CODEC_MASK_SUPPORTED:
+-                      parse_codecs_mask(&codecs, &domain, data);
++                      if (rem_bytes <= sizeof(struct hfi_codec_mask_supported))
++                              return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
++
++                      ret = parse_codecs_mask(&codecs, &domain, payload);
+                       break;
+               case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED:
+-                      parse_raw_formats(core, codecs, domain, data);
++                      if (rem_bytes <= sizeof(struct hfi_uncompressed_format_supported))
++                              return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
++
++                      ret = parse_raw_formats(core, codecs, domain, payload);
+                       break;
+               case HFI_PROPERTY_PARAM_CAPABILITY_SUPPORTED:
+-                      parse_caps(core, codecs, domain, data);
++                      if (rem_bytes <= sizeof(struct hfi_capabilities))
++                              return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
++
++                      ret = parse_caps(core, codecs, domain, payload);
+                       break;
+               case HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED:
+-                      parse_profile_level(core, codecs, domain, data);
++                      if (rem_bytes <= sizeof(struct hfi_profile_level_supported))
++                              return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
++
++                      ret = parse_profile_level(core, codecs, domain, payload);
+                       break;
+               case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE_SUPPORTED:
+-                      parse_alloc_mode(core, codecs, domain, data);
++                      if (rem_bytes <= sizeof(struct hfi_buffer_alloc_mode_supported))
++                              return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
++
++                      ret = parse_alloc_mode(core, codecs, domain, payload);
+                       break;
+               default:
++                      ret = sizeof(u32);
+                       break;
+               }
+-              word++;
+-              words_count--;
++              if (ret < 0)
++                      return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
++
++              words += ret / sizeof(u32);
++              rem_bytes -= ret;
+       }
+       if (!core->max_sessions_supported)
+-- 
+2.39.5
+
diff --git a/queue-5.10/media-venus-hfi_plat-add-codecs-and-capabilities-ops.patch b/queue-5.10/media-venus-hfi_plat-add-codecs-and-capabilities-ops.patch
new file mode 100644 (file)
index 0000000..014996a
--- /dev/null
@@ -0,0 +1,35 @@
+From 68a66cb6387a8f56b5f459c22b806055c0cb844d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Aug 2020 13:07:07 +0200
+Subject: media: venus: hfi_plat: Add codecs and capabilities ops
+
+From: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+
+[ Upstream commit 9822291e031f6d7149ae4f3fc00bd9c33ac2a084 ]
+
+Add ops to get the supported by the platform codecs and capabilities.
+
+Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: 9edaaa8e3e15 ("media: venus: hfi_parser: refactor hfi packet parsing logic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/venus/hfi_platform.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/platform/qcom/venus/hfi_platform.h b/drivers/media/platform/qcom/venus/hfi_platform.h
+index 6794232322557..50512d142662f 100644
+--- a/drivers/media/platform/qcom/venus/hfi_platform.h
++++ b/drivers/media/platform/qcom/venus/hfi_platform.h
+@@ -47,6 +47,8 @@ struct hfi_platform_codec_freq_data {
+ struct hfi_platform {
+       unsigned long (*codec_vpp_freq)(u32 session_type, u32 codec);
+       unsigned long (*codec_vsp_freq)(u32 session_type, u32 codec);
++      void (*codecs)(u32 *enc_codecs, u32 *dec_codecs, u32 *count);
++      const struct hfi_plat_caps *(*capabilities)(unsigned int *entries);
+ };
+ extern const struct hfi_platform hfi_plat_v4;
+-- 
+2.39.5
+
diff --git a/queue-5.10/media-venus-limit-hfi-sessions-to-the-maximum-suppor.patch b/queue-5.10/media-venus-limit-hfi-sessions-to-the-maximum-suppor.patch
new file mode 100644 (file)
index 0000000..4f825d5
--- /dev/null
@@ -0,0 +1,93 @@
+From 5fa4bedb0fda21cc926aa9f51e594f44cf9870ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Dec 2020 11:01:37 +0100
+Subject: media: venus: Limit HFI sessions to the maximum supported
+
+From: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+
+[ Upstream commit 20891170f339a8754312a877f3d17f0e5dadd599 ]
+
+Currently we rely on firmware to return error when we reach the maximum
+supported number of sessions. But this errors are happened at reqbuf
+time which is a bit later. The more reasonable way looks like is to
+return the error on driver open.
+
+To achieve that modify hfi_session_create to return error when we reach
+maximum count of sessions and thus refuse open.
+
+Tested-by: Fritz Koenig <frkoenig@chromium.org>
+Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: 9edaaa8e3e15 ("media: venus: hfi_parser: refactor hfi packet parsing logic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/venus/core.h       |  1 +
+ drivers/media/platform/qcom/venus/hfi.c        | 16 +++++++++++++---
+ drivers/media/platform/qcom/venus/hfi_parser.c |  3 +++
+ 3 files changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
+index 75d0068033276..e56d7b8142152 100644
+--- a/drivers/media/platform/qcom/venus/core.h
++++ b/drivers/media/platform/qcom/venus/core.h
+@@ -96,6 +96,7 @@ struct venus_format {
+ #define MAX_CAP_ENTRIES               32
+ #define MAX_ALLOC_MODE_ENTRIES        16
+ #define MAX_CODEC_NUM         32
++#define MAX_SESSIONS          16
+ struct raw_formats {
+       u32 buftype;
+diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c
+index 966b4d9b57a97..17da555905e98 100644
+--- a/drivers/media/platform/qcom/venus/hfi.c
++++ b/drivers/media/platform/qcom/venus/hfi.c
+@@ -178,6 +178,8 @@ static int wait_session_msg(struct venus_inst *inst)
+ int hfi_session_create(struct venus_inst *inst, const struct hfi_inst_ops *ops)
+ {
+       struct venus_core *core = inst->core;
++      bool max;
++      int ret;
+       if (!ops)
+               return -EINVAL;
+@@ -187,11 +189,19 @@ int hfi_session_create(struct venus_inst *inst, const struct hfi_inst_ops *ops)
+       inst->ops = ops;
+       mutex_lock(&core->lock);
+-      list_add_tail(&inst->list, &core->instances);
+-      atomic_inc(&core->insts_count);
++
++      max = atomic_add_unless(&core->insts_count, 1,
++                              core->max_sessions_supported);
++      if (!max) {
++              ret = -EAGAIN;
++      } else {
++              list_add_tail(&inst->list, &core->instances);
++              ret = 0;
++      }
++
+       mutex_unlock(&core->lock);
+-      return 0;
++      return ret;
+ }
+ EXPORT_SYMBOL_GPL(hfi_session_create);
+diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c
+index 32d2a9ed44003..94981a5e8e9af 100644
+--- a/drivers/media/platform/qcom/venus/hfi_parser.c
++++ b/drivers/media/platform/qcom/venus/hfi_parser.c
+@@ -295,6 +295,9 @@ u32 hfi_parser(struct venus_core *core, struct venus_inst *inst, void *buf,
+               words_count--;
+       }
++      if (!core->max_sessions_supported)
++              core->max_sessions_supported = MAX_SESSIONS;
++
+       parser_fini(inst, codecs, domain);
+       return HFI_ERR_NONE;
+-- 
+2.39.5
+
diff --git a/queue-5.10/media-venus-pm_helpers-check-instance-state-when-cal.patch b/queue-5.10/media-venus-pm_helpers-check-instance-state-when-cal.patch
new file mode 100644 (file)
index 0000000..42730ff
--- /dev/null
@@ -0,0 +1,37 @@
+From 68e451c45fec58515c724f58edf6ed8379db22dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Nov 2020 15:37:52 +0100
+Subject: media: venus: pm_helpers: Check instance state when calculate
+ instance frequency
+
+From: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+
+[ Upstream commit d33a94412ed1081f30d904cab54faea7c7b839fc ]
+
+Skip calculating instance frequency if it is not in running state.
+
+Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: 9edaaa8e3e15 ("media: venus: hfi_parser: refactor hfi packet parsing logic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/venus/pm_helpers.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c
+index fd55352d743ee..12c5811fefdf9 100644
+--- a/drivers/media/platform/qcom/venus/pm_helpers.c
++++ b/drivers/media/platform/qcom/venus/pm_helpers.c
+@@ -937,6 +937,9 @@ static unsigned long calculate_inst_freq(struct venus_inst *inst,
+       mbs_per_sec = load_per_instance(inst) / fps;
++      if (inst->state != INST_START)
++              return 0;
++
+       vpp_freq = mbs_per_sec * inst->clk_data.codec_freq_data->vpp_freq;
+       /* 21 / 20 is overhead factor */
+       vpp_freq += vpp_freq / 20;
+-- 
+2.39.5
+
diff --git a/queue-5.10/media-venus-rename-venus_caps-to-hfi_plat_caps.patch b/queue-5.10/media-venus-rename-venus_caps-to-hfi_plat_caps.patch
new file mode 100644 (file)
index 0000000..aad697a
--- /dev/null
@@ -0,0 +1,247 @@
+From 6c806d43c85d131b4af7df4c82d644baa0cb6337 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Aug 2020 13:04:09 +0200
+Subject: media: venus: Rename venus_caps to hfi_plat_caps
+
+From: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+
+[ Upstream commit 8f3b41dcfb9a0fa2d2ca0af51c3eebd670dc153b ]
+
+Now when we have hfi platform make venus capabilities an
+hfi platform capabilities.
+
+Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: 9edaaa8e3e15 ("media: venus: hfi_parser: refactor hfi packet parsing logic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/venus/core.h      | 30 ++-----------------
+ drivers/media/platform/qcom/venus/helpers.c   |  6 ++--
+ .../media/platform/qcom/venus/hfi_parser.c    | 18 +++++------
+ .../media/platform/qcom/venus/hfi_parser.h    |  2 +-
+ .../media/platform/qcom/venus/hfi_platform.h  | 25 ++++++++++++++++
+ 5 files changed, 41 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
+index 53d3202460ae9..785a5bbb19c3c 100644
+--- a/drivers/media/platform/qcom/venus/core.h
++++ b/drivers/media/platform/qcom/venus/core.h
+@@ -14,6 +14,7 @@
+ #include "dbgfs.h"
+ #include "hfi.h"
++#include "hfi_platform.h"
+ #define VDBGL "VenusLow : "
+ #define VDBGM "VenusMed : "
+@@ -82,31 +83,6 @@ struct venus_format {
+       u32 flags;
+ };
+-#define MAX_PLANES            4
+-#define MAX_FMT_ENTRIES               32
+-#define MAX_CAP_ENTRIES               32
+-#define MAX_ALLOC_MODE_ENTRIES        16
+-#define MAX_CODEC_NUM         32
+-#define MAX_SESSIONS          16
+-
+-struct raw_formats {
+-      u32 buftype;
+-      u32 fmt;
+-};
+-
+-struct venus_caps {
+-      u32 codec;
+-      u32 domain;
+-      bool cap_bufs_mode_dynamic;
+-      unsigned int num_caps;
+-      struct hfi_capability caps[MAX_CAP_ENTRIES];
+-      unsigned int num_pl;
+-      struct hfi_profile_level pl[HFI_MAX_PROFILE_COUNT];
+-      unsigned int num_fmts;
+-      struct raw_formats fmts[MAX_FMT_ENTRIES];
+-      bool valid;     /* used only for Venus v1xx */
+-};
+-
+ /**
+  * struct venus_core - holds core parameters valid for all instances
+  *
+@@ -199,7 +175,7 @@ struct venus_core {
+       void *priv;
+       const struct hfi_ops *ops;
+       struct delayed_work work;
+-      struct venus_caps caps[MAX_CODEC_NUM];
++      struct hfi_plat_caps caps[MAX_CODEC_NUM];
+       unsigned int codecs_count;
+       unsigned int core0_usage_count;
+       unsigned int core1_usage_count;
+@@ -434,7 +410,7 @@ static inline void *to_hfi_priv(struct venus_core *core)
+       return core->priv;
+ }
+-static inline struct venus_caps *
++static inline struct hfi_plat_caps *
+ venus_caps_by_codec(struct venus_core *core, u32 codec, u32 domain)
+ {
+       unsigned int c;
+diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c
+index 9ad8abdc4d4f2..dcf9fc0da1ce4 100644
+--- a/drivers/media/platform/qcom/venus/helpers.c
++++ b/drivers/media/platform/qcom/venus/helpers.c
+@@ -481,7 +481,7 @@ session_process_buf(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf)
+ static bool is_dynamic_bufmode(struct venus_inst *inst)
+ {
+       struct venus_core *core = inst->core;
+-      struct venus_caps *caps;
++      struct hfi_plat_caps *caps;
+       /*
+        * v4 doesn't send BUFFER_ALLOC_MODE_SUPPORTED property and supports
+@@ -1539,7 +1539,7 @@ void venus_helper_init_instance(struct venus_inst *inst)
+ }
+ EXPORT_SYMBOL_GPL(venus_helper_init_instance);
+-static bool find_fmt_from_caps(struct venus_caps *caps, u32 buftype, u32 fmt)
++static bool find_fmt_from_caps(struct hfi_plat_caps *caps, u32 buftype, u32 fmt)
+ {
+       unsigned int i;
+@@ -1556,7 +1556,7 @@ int venus_helper_get_out_fmts(struct venus_inst *inst, u32 v4l2_fmt,
+                             u32 *out_fmt, u32 *out2_fmt, bool ubwc)
+ {
+       struct venus_core *core = inst->core;
+-      struct venus_caps *caps;
++      struct hfi_plat_caps *caps;
+       u32 ubwc_fmt, fmt = to_hfi_raw_fmt(v4l2_fmt);
+       bool found, found_ubwc;
+diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c
+index 94981a5e8e9af..be9a58ef04d86 100644
+--- a/drivers/media/platform/qcom/venus/hfi_parser.c
++++ b/drivers/media/platform/qcom/venus/hfi_parser.c
+@@ -11,12 +11,12 @@
+ #include "hfi_helper.h"
+ #include "hfi_parser.h"
+-typedef void (*func)(struct venus_caps *cap, const void *data,
++typedef void (*func)(struct hfi_plat_caps *cap, const void *data,
+                    unsigned int size);
+ static void init_codecs(struct venus_core *core)
+ {
+-      struct venus_caps *caps = core->caps, *cap;
++      struct hfi_plat_caps *caps = core->caps, *cap;
+       unsigned long bit;
+       core->codecs_count = 0;
+@@ -39,11 +39,11 @@ static void init_codecs(struct venus_core *core)
+       }
+ }
+-static void for_each_codec(struct venus_caps *caps, unsigned int caps_num,
++static void for_each_codec(struct hfi_plat_caps *caps, unsigned int caps_num,
+                          u32 codecs, u32 domain, func cb, void *data,
+                          unsigned int size)
+ {
+-      struct venus_caps *cap;
++      struct hfi_plat_caps *cap;
+       unsigned int i;
+       for (i = 0; i < caps_num; i++) {
+@@ -56,7 +56,7 @@ static void for_each_codec(struct venus_caps *caps, unsigned int caps_num,
+ }
+ static void
+-fill_buf_mode(struct venus_caps *cap, const void *data, unsigned int num)
++fill_buf_mode(struct hfi_plat_caps *cap, const void *data, unsigned int num)
+ {
+       const u32 *type = data;
+@@ -86,7 +86,7 @@ parse_alloc_mode(struct venus_core *core, u32 codecs, u32 domain, void *data)
+       }
+ }
+-static void fill_profile_level(struct venus_caps *cap, const void *data,
++static void fill_profile_level(struct hfi_plat_caps *cap, const void *data,
+                              unsigned int num)
+ {
+       const struct hfi_profile_level *pl = data;
+@@ -115,7 +115,7 @@ parse_profile_level(struct venus_core *core, u32 codecs, u32 domain, void *data)
+ }
+ static void
+-fill_caps(struct venus_caps *cap, const void *data, unsigned int num)
++fill_caps(struct hfi_plat_caps *cap, const void *data, unsigned int num)
+ {
+       const struct hfi_capability *caps = data;
+@@ -143,7 +143,7 @@ parse_caps(struct venus_core *core, u32 codecs, u32 domain, void *data)
+                      fill_caps, caps_arr, num_caps);
+ }
+-static void fill_raw_fmts(struct venus_caps *cap, const void *fmts,
++static void fill_raw_fmts(struct hfi_plat_caps *cap, const void *fmts,
+                         unsigned int num_fmts)
+ {
+       const struct raw_formats *formats = fmts;
+@@ -228,7 +228,7 @@ static void parser_init(struct venus_inst *inst, u32 *codecs, u32 *domain)
+ static void parser_fini(struct venus_inst *inst, u32 codecs, u32 domain)
+ {
+-      struct venus_caps *caps, *cap;
++      struct hfi_plat_caps *caps, *cap;
+       unsigned int i;
+       u32 dom;
+diff --git a/drivers/media/platform/qcom/venus/hfi_parser.h b/drivers/media/platform/qcom/venus/hfi_parser.h
+index 264e6dd2415fe..7f59d82110f9c 100644
+--- a/drivers/media/platform/qcom/venus/hfi_parser.h
++++ b/drivers/media/platform/qcom/venus/hfi_parser.h
+@@ -16,7 +16,7 @@ static inline u32 get_cap(struct venus_inst *inst, u32 type, u32 which)
+ {
+       struct venus_core *core = inst->core;
+       struct hfi_capability *cap = NULL;
+-      struct venus_caps *caps;
++      struct hfi_plat_caps *caps;
+       unsigned int i;
+       caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type);
+diff --git a/drivers/media/platform/qcom/venus/hfi_platform.h b/drivers/media/platform/qcom/venus/hfi_platform.h
+index 8b07ecbb4c825..6794232322557 100644
+--- a/drivers/media/platform/qcom/venus/hfi_platform.h
++++ b/drivers/media/platform/qcom/venus/hfi_platform.h
+@@ -12,6 +12,31 @@
+ #include "hfi.h"
+ #include "hfi_helper.h"
++#define MAX_PLANES            4
++#define MAX_FMT_ENTRIES               32
++#define MAX_CAP_ENTRIES               32
++#define MAX_ALLOC_MODE_ENTRIES        16
++#define MAX_CODEC_NUM         32
++#define MAX_SESSIONS          16
++
++struct raw_formats {
++      u32 buftype;
++      u32 fmt;
++};
++
++struct hfi_plat_caps {
++      u32 codec;
++      u32 domain;
++      bool cap_bufs_mode_dynamic;
++      unsigned int num_caps;
++      struct hfi_capability caps[MAX_CAP_ENTRIES];
++      unsigned int num_pl;
++      struct hfi_profile_level pl[HFI_MAX_PROFILE_COUNT];
++      unsigned int num_fmts;
++      struct raw_formats fmts[MAX_FMT_ENTRIES];
++      bool valid;     /* used only for Venus v1xx */
++};
++
+ struct hfi_platform_codec_freq_data {
+       u32 pixfmt;
+       u32 session_type;
+-- 
+2.39.5
+
diff --git a/queue-5.10/media-venus-venc-init-the-session-only-once-in-queue.patch b/queue-5.10/media-venus-venc-init-the-session-only-once-in-queue.patch
new file mode 100644 (file)
index 0000000..1e1ad85
--- /dev/null
@@ -0,0 +1,187 @@
+From 1c4c7eb8c7717549ac62b7ad29d72e6bf937997e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Dec 2020 11:01:36 +0100
+Subject: media: venus: venc: Init the session only once in queue_setup
+
+From: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+
+[ Upstream commit 5f2ca73dcca96c3de96a0e4d9ea24ebb46c55d2e ]
+
+Init the hfi session only once in queue_setup and also cover that
+with inst->lock.
+
+Tested-by: Fritz Koenig <frkoenig@chromium.org>
+Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Stable-dep-of: 9edaaa8e3e15 ("media: venus: hfi_parser: refactor hfi packet parsing logic")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/venus/venc.c | 85 ++++++++++++++++++------
+ 1 file changed, 64 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c
+index e2d0fd5eaf29a..18d20b4ca2cfd 100644
+--- a/drivers/media/platform/qcom/venus/venc.c
++++ b/drivers/media/platform/qcom/venus/venc.c
+@@ -727,7 +727,9 @@ static int venc_init_session(struct venus_inst *inst)
+       int ret;
+       ret = hfi_session_init(inst, inst->fmt_cap->pixfmt);
+-      if (ret)
++      if (ret == -EINVAL)
++              return 0;
++      else if (ret)
+               return ret;
+       ret = venus_helper_set_input_resolution(inst, inst->width,
+@@ -764,17 +766,13 @@ static int venc_out_num_buffers(struct venus_inst *inst, unsigned int *num)
+       struct hfi_buffer_requirements bufreq;
+       int ret;
+-      ret = venc_init_session(inst);
++      ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq);
+       if (ret)
+               return ret;
+-      ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq);
+-
+       *num = bufreq.count_actual;
+-      hfi_session_deinit(inst);
+-
+-      return ret;
++      return 0;
+ }
+ static int venc_queue_setup(struct vb2_queue *q,
+@@ -783,7 +781,7 @@ static int venc_queue_setup(struct vb2_queue *q,
+ {
+       struct venus_inst *inst = vb2_get_drv_priv(q);
+       unsigned int num, min = 4;
+-      int ret = 0;
++      int ret;
+       if (*num_planes) {
+               if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
+@@ -805,6 +803,13 @@ static int venc_queue_setup(struct vb2_queue *q,
+               return 0;
+       }
++      mutex_lock(&inst->lock);
++      ret = venc_init_session(inst);
++      mutex_unlock(&inst->lock);
++
++      if (ret)
++              return ret;
++
+       switch (q->type) {
+       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+               *num_planes = inst->fmt_out->num_planes;
+@@ -840,6 +845,49 @@ static int venc_queue_setup(struct vb2_queue *q,
+       return ret;
+ }
++static int venc_buf_init(struct vb2_buffer *vb)
++{
++      struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
++
++      inst->buf_count++;
++
++      return venus_helper_vb2_buf_init(vb);
++}
++
++static void venc_release_session(struct venus_inst *inst)
++{
++      int ret;
++
++      mutex_lock(&inst->lock);
++
++      ret = hfi_session_deinit(inst);
++      if (ret || inst->session_error)
++              hfi_session_abort(inst);
++
++      mutex_unlock(&inst->lock);
++
++      venus_pm_load_scale(inst);
++      INIT_LIST_HEAD(&inst->registeredbufs);
++      venus_pm_release_core(inst);
++}
++
++static void venc_buf_cleanup(struct vb2_buffer *vb)
++{
++      struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
++      struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++      struct venus_buffer *buf = to_venus_buffer(vbuf);
++
++      mutex_lock(&inst->lock);
++      if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
++              if (!list_empty(&inst->registeredbufs))
++                      list_del_init(&buf->reg_list);
++      mutex_unlock(&inst->lock);
++
++      inst->buf_count--;
++      if (!inst->buf_count)
++              venc_release_session(inst);
++}
++
+ static int venc_verify_conf(struct venus_inst *inst)
+ {
+       enum hfi_version ver = inst->core->res->hfi_version;
+@@ -890,38 +938,32 @@ static int venc_start_streaming(struct vb2_queue *q, unsigned int count)
+       inst->sequence_cap = 0;
+       inst->sequence_out = 0;
+-      ret = venc_init_session(inst);
+-      if (ret)
+-              goto bufs_done;
+-
+       ret = venus_pm_acquire_core(inst);
+       if (ret)
+-              goto deinit_sess;
++              goto error;
+       ret = venc_set_properties(inst);
+       if (ret)
+-              goto deinit_sess;
++              goto error;
+       ret = venc_verify_conf(inst);
+       if (ret)
+-              goto deinit_sess;
++              goto error;
+       ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs,
+                                       inst->num_output_bufs, 0);
+       if (ret)
+-              goto deinit_sess;
++              goto error;
+       ret = venus_helper_vb2_start_streaming(inst);
+       if (ret)
+-              goto deinit_sess;
++              goto error;
+       mutex_unlock(&inst->lock);
+       return 0;
+-deinit_sess:
+-      hfi_session_deinit(inst);
+-bufs_done:
++error:
+       venus_helper_buffers_done(inst, q->type, VB2_BUF_STATE_QUEUED);
+       if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+               inst->streamon_out = 0;
+@@ -933,7 +975,8 @@ static int venc_start_streaming(struct vb2_queue *q, unsigned int count)
+ static const struct vb2_ops venc_vb2_ops = {
+       .queue_setup = venc_queue_setup,
+-      .buf_init = venus_helper_vb2_buf_init,
++      .buf_init = venc_buf_init,
++      .buf_cleanup = venc_buf_cleanup,
+       .buf_prepare = venus_helper_vb2_buf_prepare,
+       .start_streaming = venc_start_streaming,
+       .stop_streaming = venus_helper_vb2_stop_streaming,
+-- 
+2.39.5
+
diff --git a/queue-5.10/net-dsa-mv88e6xxx-fix-vtu-methods-for-6320-family.patch b/queue-5.10/net-dsa-mv88e6xxx-fix-vtu-methods-for-6320-family.patch
new file mode 100644 (file)
index 0000000..b95eccf
--- /dev/null
@@ -0,0 +1,55 @@
+From 2403bbf5473c0afbd398d66c28cda3f3a367dff4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Mar 2025 18:32:44 +0100
+Subject: net: dsa: mv88e6xxx: fix VTU methods for 6320 family
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marek Behún <kabel@kernel.org>
+
+[ Upstream commit f9a457722cf5e3534be5ffab549d6b49737fca72 ]
+
+The VTU registers of the 6320 family use the 6352 semantics, not 6185.
+Fix it.
+
+Fixes: b8fee9571063 ("net: dsa: mv88e6xxx: add VLAN Get Next support")
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Cc: <stable@vger.kernel.org> # 5.15.x
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250317173250.28780-2-kabel@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/chip.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index e590ea87b6ea2..ebc8580873940 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -4170,8 +4170,8 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
+       .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
+       .pot_clear = mv88e6xxx_g2_pot_clear,
+       .reset = mv88e6352_g1_reset,
+-      .vtu_getnext = mv88e6185_g1_vtu_getnext,
+-      .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
++      .vtu_getnext = mv88e6352_g1_vtu_getnext,
++      .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
+       .gpio_ops = &mv88e6352_gpio_ops,
+       .avb_ops = &mv88e6352_avb_ops,
+       .ptp_ops = &mv88e6352_ptp_ops,
+@@ -4212,8 +4212,8 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
+       .watchdog_ops = &mv88e6390_watchdog_ops,
+       .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
+       .reset = mv88e6352_g1_reset,
+-      .vtu_getnext = mv88e6185_g1_vtu_getnext,
+-      .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
++      .vtu_getnext = mv88e6352_g1_vtu_getnext,
++      .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
+       .gpio_ops = &mv88e6352_gpio_ops,
+       .avb_ops = &mv88e6352_avb_ops,
+       .ptp_ops = &mv88e6352_ptp_ops,
+-- 
+2.39.5
+
diff --git a/queue-5.10/pci-assign-pci-domain-ids-by-ida_alloc.patch b/queue-5.10/pci-assign-pci-domain-ids-by-ida_alloc.patch
new file mode 100644 (file)
index 0000000..62a5ecc
--- /dev/null
@@ -0,0 +1,227 @@
+From 986e2a9c8da3498840d7113f1984acb946e2a000 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 20:41:30 +0200
+Subject: PCI: Assign PCI domain IDs by ida_alloc()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit c14f7ccc9f5dcf9d06ddeec706f85405b2c80600 ]
+
+Replace assignment of PCI domain IDs from atomic_inc_return() to
+ida_alloc().
+
+Use two IDAs, one for static domain allocations (those which are defined in
+device tree) and second for dynamic allocations (all other).
+
+During removal of root bus / host bridge, also release the domain ID.  The
+released ID can be reused again, for example when dynamically loading and
+unloading native PCI host bridge drivers.
+
+This change also allows to mix static device tree assignment and dynamic by
+kernel as all static allocations are reserved in dynamic pool.
+
+[bhelgaas: set "err" if "bus->domain_nr < 0"]
+Link: https://lore.kernel.org/r/20220714184130.5436-1-pali@kernel.org
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Stable-dep-of: 804443c1f278 ("PCI: Fix reference leak in pci_register_host_bridge()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci.c    | 103 +++++++++++++++++++++++++------------------
+ drivers/pci/probe.c  |   7 +++
+ drivers/pci/remove.c |   6 +++
+ include/linux/pci.h  |   1 +
+ 4 files changed, 74 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 1d4585b07de3b..24916e78c507c 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -6467,60 +6467,70 @@ static void pci_no_domains(void)
+ }
+ #ifdef CONFIG_PCI_DOMAINS_GENERIC
+-static atomic_t __domain_nr = ATOMIC_INIT(-1);
++static DEFINE_IDA(pci_domain_nr_static_ida);
++static DEFINE_IDA(pci_domain_nr_dynamic_ida);
+-static int pci_get_new_domain_nr(void)
++static void of_pci_reserve_static_domain_nr(void)
+ {
+-      return atomic_inc_return(&__domain_nr);
++      struct device_node *np;
++      int domain_nr;
++
++      for_each_node_by_type(np, "pci") {
++              domain_nr = of_get_pci_domain_nr(np);
++              if (domain_nr < 0)
++                      continue;
++              /*
++               * Permanently allocate domain_nr in dynamic_ida
++               * to prevent it from dynamic allocation.
++               */
++              ida_alloc_range(&pci_domain_nr_dynamic_ida,
++                              domain_nr, domain_nr, GFP_KERNEL);
++      }
+ }
+ static int of_pci_bus_find_domain_nr(struct device *parent)
+ {
+-      static int use_dt_domains = -1;
+-      int domain = -1;
++      static bool static_domains_reserved = false;
++      int domain_nr;
+-      if (parent)
+-              domain = of_get_pci_domain_nr(parent->of_node);
++      /* On the first call scan device tree for static allocations. */
++      if (!static_domains_reserved) {
++              of_pci_reserve_static_domain_nr();
++              static_domains_reserved = true;
++      }
++
++      if (parent) {
++              /*
++               * If domain is in DT, allocate it in static IDA.  This
++               * prevents duplicate static allocations in case of errors
++               * in DT.
++               */
++              domain_nr = of_get_pci_domain_nr(parent->of_node);
++              if (domain_nr >= 0)
++                      return ida_alloc_range(&pci_domain_nr_static_ida,
++                                             domain_nr, domain_nr,
++                                             GFP_KERNEL);
++      }
+       /*
+-       * Check DT domain and use_dt_domains values.
+-       *
+-       * If DT domain property is valid (domain >= 0) and
+-       * use_dt_domains != 0, the DT assignment is valid since this means
+-       * we have not previously allocated a domain number by using
+-       * pci_get_new_domain_nr(); we should also update use_dt_domains to
+-       * 1, to indicate that we have just assigned a domain number from
+-       * DT.
+-       *
+-       * If DT domain property value is not valid (ie domain < 0), and we
+-       * have not previously assigned a domain number from DT
+-       * (use_dt_domains != 1) we should assign a domain number by
+-       * using the:
+-       *
+-       * pci_get_new_domain_nr()
+-       *
+-       * API and update the use_dt_domains value to keep track of method we
+-       * are using to assign domain numbers (use_dt_domains = 0).
+-       *
+-       * All other combinations imply we have a platform that is trying
+-       * to mix domain numbers obtained from DT and pci_get_new_domain_nr(),
+-       * which is a recipe for domain mishandling and it is prevented by
+-       * invalidating the domain value (domain = -1) and printing a
+-       * corresponding error.
++       * If domain was not specified in DT, choose a free ID from dynamic
++       * allocations. All domain numbers from DT are permanently in
++       * dynamic allocations to prevent assigning them to other DT nodes
++       * without static domain.
+        */
+-      if (domain >= 0 && use_dt_domains) {
+-              use_dt_domains = 1;
+-      } else if (domain < 0 && use_dt_domains != 1) {
+-              use_dt_domains = 0;
+-              domain = pci_get_new_domain_nr();
+-      } else {
+-              if (parent)
+-                      pr_err("Node %pOF has ", parent->of_node);
+-              pr_err("Inconsistent \"linux,pci-domain\" property in DT\n");
+-              domain = -1;
+-      }
++      return ida_alloc(&pci_domain_nr_dynamic_ida, GFP_KERNEL);
++}
+-      return domain;
++static void of_pci_bus_release_domain_nr(struct pci_bus *bus, struct device *parent)
++{
++      if (bus->domain_nr < 0)
++              return;
++
++      /* Release domain from IDA where it was allocated. */
++      if (of_get_pci_domain_nr(parent->of_node) == bus->domain_nr)
++              ida_free(&pci_domain_nr_static_ida, bus->domain_nr);
++      else
++              ida_free(&pci_domain_nr_dynamic_ida, bus->domain_nr);
+ }
+ int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent)
+@@ -6528,6 +6538,13 @@ int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent)
+       return acpi_disabled ? of_pci_bus_find_domain_nr(parent) :
+                              acpi_pci_bus_find_domain_nr(bus);
+ }
++
++void pci_bus_release_domain_nr(struct pci_bus *bus, struct device *parent)
++{
++      if (!acpi_disabled)
++              return;
++      of_pci_bus_release_domain_nr(bus, parent);
++}
+ #endif
+ /**
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index a2c53f6d1848a..012ca242bedf4 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -904,6 +904,10 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
+               bus->domain_nr = pci_bus_find_domain_nr(bus, parent);
+       else
+               bus->domain_nr = bridge->domain_nr;
++      if (bus->domain_nr < 0) {
++              err = bus->domain_nr;
++              goto free;
++      }
+ #endif
+       b = pci_find_bus(pci_domain_nr(bus), bridge->busnr);
+@@ -1022,6 +1026,9 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
+       device_del(&bridge->dev);
+ free:
++#ifdef CONFIG_PCI_DOMAINS_GENERIC
++      pci_bus_release_domain_nr(bus, parent);
++#endif
+       kfree(bus);
+       return err;
+ }
+diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
+index 95dec03d9f2a9..611547b52b46d 100644
+--- a/drivers/pci/remove.c
++++ b/drivers/pci/remove.c
+@@ -159,6 +159,12 @@ void pci_remove_root_bus(struct pci_bus *bus)
+       pci_remove_bus(bus);
+       host_bridge->bus = NULL;
++#ifdef CONFIG_PCI_DOMAINS_GENERIC
++      /* Release domain_nr if it was dynamically allocated */
++      if (host_bridge->domain_nr == PCI_DOMAIN_NR_NOT_SET)
++              pci_bus_release_domain_nr(bus, host_bridge->dev.parent);
++#endif
++
+       /* remove the host bridge */
+       device_del(&host_bridge->dev);
+ }
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index a0fd1fe4189e4..d3d84eb466f02 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -1667,6 +1667,7 @@ static inline int acpi_pci_bus_find_domain_nr(struct pci_bus *bus)
+ { return 0; }
+ #endif
+ int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent);
++void pci_bus_release_domain_nr(struct pci_bus *bus, struct device *parent);
+ #endif
+ /* Some architectures require additional setup to direct VGA traffic */
+-- 
+2.39.5
+
diff --git a/queue-5.10/pci-coalesce-host-bridge-contiguous-apertures.patch b/queue-5.10/pci-coalesce-host-bridge-contiguous-apertures.patch
new file mode 100644 (file)
index 0000000..1bc3be2
--- /dev/null
@@ -0,0 +1,99 @@
+From 490e7fc8f363468103dd2ac020913a6bec7f2bdb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jul 2021 20:50:07 +0800
+Subject: PCI: Coalesce host bridge contiguous apertures
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+[ Upstream commit 65db04053efea3f3e412a7e0cc599962999c96b4 ]
+
+Built-in graphics on HP EliteDesk 805 G6 doesn't work because graphics
+can't get the BAR it needs:
+
+  pci_bus 0000:00: root bus resource [mem 0x10020200000-0x100303fffff window]
+  pci_bus 0000:00: root bus resource [mem 0x10030400000-0x100401fffff window]
+
+  pci 0000:00:08.1:   bridge window [mem 0xd2000000-0xd23fffff]
+  pci 0000:00:08.1:   bridge window [mem 0x10030000000-0x100401fffff 64bit pref]
+  pci 0000:00:08.1: can't claim BAR 15 [mem 0x10030000000-0x100401fffff 64bit pref]: no compatible bridge window
+  pci 0000:00:08.1: [mem 0x10030000000-0x100401fffff 64bit pref] clipped to [mem 0x10030000000-0x100303fffff 64bit pref]
+  pci 0000:00:08.1:   bridge window [mem 0x10030000000-0x100303fffff 64bit pref]
+  pci 0000:07:00.0: can't claim BAR 0 [mem 0x10030000000-0x1003fffffff 64bit pref]: no compatible bridge window
+  pci 0000:07:00.0: can't claim BAR 2 [mem 0x10040000000-0x100401fffff 64bit pref]: no compatible bridge window
+
+However, the root bus has two contiguous apertures that can contain the
+child resource requested.
+
+Coalesce contiguous apertures so we can allocate from the entire contiguous
+region.
+
+[bhelgaas: fold in https://lore.kernel.org/r/20210528170242.1564038-1-kai.heng.feng@canonical.com]
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=212013
+Suggested-by: Bjorn Helgaas <bhelgaas@google.com>
+Link: https://lore.kernel.org/r/20210401131252.531935-1-kai.heng.feng@canonical.com
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Stable-dep-of: 804443c1f278 ("PCI: Fix reference leak in pci_register_host_bridge()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/probe.c | 31 +++++++++++++++++++++++++++----
+ 1 file changed, 27 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index be7973e249cd7..a2c53f6d1848a 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -878,11 +878,11 @@ static void pci_set_bus_msi_domain(struct pci_bus *bus)
+ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
+ {
+       struct device *parent = bridge->dev.parent;
+-      struct resource_entry *window, *n;
++      struct resource_entry *window, *next, *n;
+       struct pci_bus *bus, *b;
+-      resource_size_t offset;
++      resource_size_t offset, next_offset;
+       LIST_HEAD(resources);
+-      struct resource *res;
++      struct resource *res, *next_res;
+       char addr[64], *fmt;
+       const char *name;
+       int err;
+@@ -962,11 +962,34 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
+       if (nr_node_ids > 1 && pcibus_to_node(bus) == NUMA_NO_NODE)
+               dev_warn(&bus->dev, "Unknown NUMA node; performance will be reduced\n");
++      /* Coalesce contiguous windows */
++      resource_list_for_each_entry_safe(window, n, &resources) {
++              if (list_is_last(&window->node, &resources))
++                      break;
++
++              next = list_next_entry(window, node);
++              offset = window->offset;
++              res = window->res;
++              next_offset = next->offset;
++              next_res = next->res;
++
++              if (res->flags != next_res->flags || offset != next_offset)
++                      continue;
++
++              if (res->end + 1 == next_res->start) {
++                      next_res->start = res->start;
++                      res->flags = res->start = res->end = 0;
++              }
++      }
++
+       /* Add initial resources to the bus */
+       resource_list_for_each_entry_safe(window, n, &resources) {
+-              list_move_tail(&window->node, &bridge->windows);
+               offset = window->offset;
+               res = window->res;
++              if (!res->end)
++                      continue;
++
++              list_move_tail(&window->node, &bridge->windows);
+               if (res->flags & IORESOURCE_BUS)
+                       pci_bus_insert_busn_res(bus, bus->number, res->end);
+-- 
+2.39.5
+
diff --git a/queue-5.10/pci-fix-reference-leak-in-pci_register_host_bridge.patch b/queue-5.10/pci-fix-reference-leak-in-pci_register_host_bridge.patch
new file mode 100644 (file)
index 0000000..220382d
--- /dev/null
@@ -0,0 +1,67 @@
+From 3679a05ddfeba7a765cdca0ffbb597b086ebeaf8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 10:14:40 +0800
+Subject: PCI: Fix reference leak in pci_register_host_bridge()
+
+From: Ma Ke <make24@iscas.ac.cn>
+
+[ Upstream commit 804443c1f27883926de94c849d91f5b7d7d696e9 ]
+
+If device_register() fails, call put_device() to give up the reference to
+avoid a memory leak, per the comment at device_register().
+
+Found by code review.
+
+Link: https://lore.kernel.org/r/20250225021440.3130264-1-make24@iscas.ac.cn
+Fixes: 37d6a0a6f470 ("PCI: Add pci_register_host_bridge() interface")
+Signed-off-by: Ma Ke <make24@iscas.ac.cn>
+[bhelgaas: squash Dan Carpenter's double free fix from
+https://lore.kernel.org/r/db806a6c-a91b-4e5a-a84b-6b7e01bdac85@stanley.mountain]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/probe.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index 012ca242bedf4..7f3d10957eca7 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -883,6 +883,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
+       resource_size_t offset, next_offset;
+       LIST_HEAD(resources);
+       struct resource *res, *next_res;
++      bool bus_registered = false;
+       char addr[64], *fmt;
+       const char *name;
+       int err;
+@@ -944,6 +945,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
+       name = dev_name(&bus->dev);
+       err = device_register(&bus->dev);
++      bus_registered = true;
+       if (err)
+               goto unregister;
+@@ -1024,12 +1026,15 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
+ unregister:
+       put_device(&bridge->dev);
+       device_del(&bridge->dev);
+-
+ free:
+ #ifdef CONFIG_PCI_DOMAINS_GENERIC
+       pci_bus_release_domain_nr(bus, parent);
+ #endif
+-      kfree(bus);
++      if (bus_registered)
++              put_device(&bus->dev);
++      else
++              kfree(bus);
++
+       return err;
+ }
+-- 
+2.39.5
+
diff --git a/queue-5.10/pci-introduce-domain_nr-in-pci_host_bridge.patch b/queue-5.10/pci-introduce-domain_nr-in-pci_host_bridge.patch
new file mode 100644 (file)
index 0000000..f11feef
--- /dev/null
@@ -0,0 +1,91 @@
+From ac5ff084ef8a10127a512e26532d6078d903aaf9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Jul 2021 02:06:50 +0800
+Subject: PCI: Introduce domain_nr in pci_host_bridge
+
+From: Boqun Feng <boqun.feng@gmail.com>
+
+[ Upstream commit 15d82ca23c996d50062286d27ed6a42a8105c04a ]
+
+Currently we retrieve the PCI domain number of the host bridge from the
+bus sysdata (or pci_config_window if PCI_DOMAINS_GENERIC=y). Actually
+we have the information at PCI host bridge probing time, and it makes
+sense that we store it into pci_host_bridge. One benefit of doing so is
+the requirement for supporting PCI on Hyper-V for ARM64, because the
+host bridge of Hyper-V doesn't have pci_config_window, whereas ARM64 is
+a PCI_DOMAINS_GENERIC=y arch, so we cannot retrieve the PCI domain
+number from pci_config_window on ARM64 Hyper-V guest.
+
+As the preparation for ARM64 Hyper-V PCI support, we introduce the
+domain_nr in pci_host_bridge and a sentinel value to allow drivers to
+set domain numbers properly at probing time. Currently
+CONFIG_PCI_DOMAINS_GENERIC=y archs are only users of this
+newly-introduced field.
+
+Link: https://lore.kernel.org/r/20210726180657.142727-2-boqun.feng@gmail.com
+Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+Stable-dep-of: 804443c1f278 ("PCI: Fix reference leak in pci_register_host_bridge()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/probe.c |  6 +++++-
+ include/linux/pci.h | 11 +++++++++++
+ 2 files changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index 6439fc2e526c7..be7973e249cd7 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -595,6 +595,7 @@ static void pci_init_host_bridge(struct pci_host_bridge *bridge)
+       bridge->native_pme = 1;
+       bridge->native_ltr = 1;
+       bridge->native_dpc = 1;
++      bridge->domain_nr = PCI_DOMAIN_NR_NOT_SET;
+       device_initialize(&bridge->dev);
+ }
+@@ -899,7 +900,10 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
+       bus->ops = bridge->ops;
+       bus->number = bus->busn_res.start = bridge->busnr;
+ #ifdef CONFIG_PCI_DOMAINS_GENERIC
+-      bus->domain_nr = pci_bus_find_domain_nr(bus, parent);
++      if (bridge->domain_nr == PCI_DOMAIN_NR_NOT_SET)
++              bus->domain_nr = pci_bus_find_domain_nr(bus, parent);
++      else
++              bus->domain_nr = bridge->domain_nr;
+ #endif
+       b = pci_find_bus(pci_domain_nr(bus), bridge->busnr);
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index 30bc462fb1964..a0fd1fe4189e4 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -538,6 +538,16 @@ static inline int pci_channel_offline(struct pci_dev *pdev)
+       return (pdev->error_state != pci_channel_io_normal);
+ }
++/*
++ * Currently in ACPI spec, for each PCI host bridge, PCI Segment
++ * Group number is limited to a 16-bit value, therefore (int)-1 is
++ * not a valid PCI domain number, and can be used as a sentinel
++ * value indicating ->domain_nr is not set by the driver (and
++ * CONFIG_PCI_DOMAINS_GENERIC=y archs will set it with
++ * pci_bus_find_domain_nr()).
++ */
++#define PCI_DOMAIN_NR_NOT_SET (-1)
++
+ struct pci_host_bridge {
+       struct device   dev;
+       struct pci_bus  *bus;           /* Root bus */
+@@ -545,6 +555,7 @@ struct pci_host_bridge {
+       struct pci_ops  *child_ops;
+       void            *sysdata;
+       int             busnr;
++      int             domain_nr;
+       struct list_head windows;       /* resource_entry */
+       struct list_head dma_ranges;    /* dma ranges resource list */
+       u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */
+-- 
+2.39.5
+
diff --git a/queue-5.10/platform-provide-a-remove-callback-that-returns-no-v.patch b/queue-5.10/platform-provide-a-remove-callback-that-returns-no-v.patch
new file mode 100644 (file)
index 0000000..44a6c75
--- /dev/null
@@ -0,0 +1,86 @@
+From 9a4cc968fa1d50ae1ce704b5813a2e70f0fa1192 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 16:09:14 +0100
+Subject: platform: Provide a remove callback that returns no value
+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 5c5a7680e67ba6fbbb5f4d79fa41485450c1985c ]
+
+struct platform_driver::remove returning an integer made driver authors
+expect that returning an error code was proper error handling. However
+the driver core ignores the error and continues to remove the device
+because there is nothing the core could do anyhow and reentering the
+remove callback again is only calling for trouble.
+
+So this is an source for errors typically yielding resource leaks in the
+error path.
+
+As there are too many platform drivers to neatly convert them all to
+return void in a single go, do it in several steps after this patch:
+
+ a) Convert all drivers to implement .remove_new() returning void instead
+    of .remove() returning int;
+ b) Change struct platform_driver::remove() to return void and so make
+    it identical to .remove_new();
+ c) Change all drivers back to .remove() now with the better prototype;
+ d) drop struct platform_driver::remove_new().
+
+While this touches all drivers eventually twice, steps a) and c) can be
+done one driver after another and so reduces coordination efforts
+immensely and simplifies review.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20221209150914.3557650-1-u.kleine-koenig@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 276822a00db3 ("backlight: led_bl: Hold led_access lock when calling led_sysfs_disable()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/platform.c         |  4 +++-
+ include/linux/platform_device.h | 11 +++++++++++
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/base/platform.c b/drivers/base/platform.c
+index d0b15cbab0ff0..e07043d85c65c 100644
+--- a/drivers/base/platform.c
++++ b/drivers/base/platform.c
+@@ -1306,7 +1306,9 @@ static int platform_remove(struct device *_dev)
+       struct platform_driver *drv = to_platform_driver(_dev->driver);
+       struct platform_device *dev = to_platform_device(_dev);
+-      if (drv->remove) {
++      if (drv->remove_new) {
++              drv->remove_new(dev);
++      } else if (drv->remove) {
+               int ret = drv->remove(dev);
+               if (ret)
+diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
+index e7a83b0218077..870a918aa251c 100644
+--- a/include/linux/platform_device.h
++++ b/include/linux/platform_device.h
+@@ -203,7 +203,18 @@ extern void platform_device_put(struct platform_device *pdev);
+ struct platform_driver {
+       int (*probe)(struct platform_device *);
++
++      /*
++       * Traditionally the remove callback returned an int which however is
++       * ignored by the driver core. This led to wrong expectations by driver
++       * authors who thought returning an error code was a valid error
++       * handling strategy. To convert to a callback returning void, new
++       * drivers should implement .remove_new() until the conversion it done
++       * that eventually makes .remove() return void.
++       */
+       int (*remove)(struct platform_device *);
++      void (*remove_new)(struct platform_device *);
++
+       void (*shutdown)(struct platform_device *);
+       int (*suspend)(struct platform_device *, pm_message_t state);
+       int (*resume)(struct platform_device *);
+-- 
+2.39.5
+
diff --git a/queue-5.10/platform-x86-isst-correct-command-storage-data-lengt.patch b/queue-5.10/platform-x86-isst-correct-command-storage-data-lengt.patch
new file mode 100644 (file)
index 0000000..78d77a8
--- /dev/null
@@ -0,0 +1,50 @@
+From abbdca9f84caf3e2493ec477b9387d3678e6f4ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Mar 2025 15:47:49 -0700
+Subject: platform/x86: ISST: Correct command storage data length
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+[ Upstream commit 9462e74c5c983cce34019bfb27f734552bebe59f ]
+
+After resume/online turbo limit ratio (TRL) is restored partially if
+the admin explicitly changed TRL from user space.
+
+A hash table is used to store SST mail box and MSR settings when modified
+to restore those settings after resume or online. This uses a struct
+isst_cmd field "data" to store these settings. This is a 64 bit field.
+But isst_store_new_cmd() is only assigning as u32. This results in
+truncation of 32 bits.
+
+Change the argument to u64 from u32.
+
+Fixes: f607874f35cb ("platform/x86: ISST: Restore state on resume")
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20250328224749.2691272-1-srinivas.pandruvada@linux.intel.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/intel_speed_select_if/isst_if_common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/platform/x86/intel_speed_select_if/isst_if_common.c b/drivers/platform/x86/intel_speed_select_if/isst_if_common.c
+index 407afafc7e83f..e0f7368e7e3e9 100644
+--- a/drivers/platform/x86/intel_speed_select_if/isst_if_common.c
++++ b/drivers/platform/x86/intel_speed_select_if/isst_if_common.c
+@@ -77,7 +77,7 @@ static DECLARE_HASHTABLE(isst_hash, 8);
+ static DEFINE_MUTEX(isst_hash_lock);
+ static int isst_store_new_cmd(int cmd, u32 cpu, int mbox_cmd_type, u32 param,
+-                            u32 data)
++                            u64 data)
+ {
+       struct isst_cmd *sst_cmd;
+-- 
+2.39.5
+
diff --git a/queue-5.10/selftests-mm-generate-a-temporary-mountpoint-for-cgr.patch b/queue-5.10/selftests-mm-generate-a-temporary-mountpoint-for-cgr.patch
new file mode 100644 (file)
index 0000000..b04d0fc
--- /dev/null
@@ -0,0 +1,79 @@
+From c0a06ddf4d69e17c258ec4f171bdac9d6960254e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 17:42:32 +0100
+Subject: selftests/mm: generate a temporary mountpoint for cgroup filesystem
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit 9c02223e2d9df5cb37c51aedb78f3960294e09b5 ]
+
+Currently if the filesystem for the cgroups version it wants to use is not
+mounted charge_reserved_hugetlb.sh and hugetlb_reparenting_test.sh tests
+will attempt to mount it on the hard coded path /dev/cgroup/memory,
+deleting that directory when the test finishes.  This will fail if there
+is not a preexisting directory at that path, and since the directory is
+deleted subsequent runs of the test will fail.  Instead of relying on this
+hard coded directory name use mktemp to generate a temporary directory to
+use as a mountpoint, fixing both the assumption and the disruption caused
+by deleting a preexisting directory.
+
+This means that if the relevant cgroup filesystem is not already mounted
+then we rely on having coreutils (which provides mktemp) installed.  I
+suspect that many current users are relying on having things automounted
+by default, and given that the script relies on bash it's probably not an
+unreasonable requirement.
+
+Link: https://lkml.kernel.org/r/20250404-kselftest-mm-cgroup2-detection-v1-1-3dba6d32ba8c@kernel.org
+Fixes: 209376ed2a84 ("selftests/vm: make charge_reserved_hugetlb.sh work with existing cgroup setting")
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: Aishwarya TCV <aishwarya.tcv@arm.com>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Mina Almasry <almasrymina@google.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Waiman Long <longman@redhat.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/vm/charge_reserved_hugetlb.sh  | 4 ++--
+ tools/testing/selftests/vm/hugetlb_reparenting_test.sh | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tools/testing/selftests/vm/charge_reserved_hugetlb.sh b/tools/testing/selftests/vm/charge_reserved_hugetlb.sh
+index 28192ec98498f..c44226b4e0bfb 100644
+--- a/tools/testing/selftests/vm/charge_reserved_hugetlb.sh
++++ b/tools/testing/selftests/vm/charge_reserved_hugetlb.sh
+@@ -24,7 +24,7 @@ fi
+ if [[ $cgroup2 ]]; then
+   cgroup_path=$(mount -t cgroup2 | head -1 | awk '{print $3}')
+   if [[ -z "$cgroup_path" ]]; then
+-    cgroup_path=/dev/cgroup/memory
++    cgroup_path=$(mktemp -d)
+     mount -t cgroup2 none $cgroup_path
+     do_umount=1
+   fi
+@@ -32,7 +32,7 @@ if [[ $cgroup2 ]]; then
+ else
+   cgroup_path=$(mount -t cgroup | grep ",hugetlb" | awk '{print $3}')
+   if [[ -z "$cgroup_path" ]]; then
+-    cgroup_path=/dev/cgroup/memory
++    cgroup_path=$(mktemp -d)
+     mount -t cgroup memory,hugetlb $cgroup_path
+     do_umount=1
+   fi
+diff --git a/tools/testing/selftests/vm/hugetlb_reparenting_test.sh b/tools/testing/selftests/vm/hugetlb_reparenting_test.sh
+index c665b16f1e370..a4123632942dd 100644
+--- a/tools/testing/selftests/vm/hugetlb_reparenting_test.sh
++++ b/tools/testing/selftests/vm/hugetlb_reparenting_test.sh
+@@ -19,7 +19,7 @@ fi
+ if [[ $cgroup2 ]]; then
+   CGROUP_ROOT=$(mount -t cgroup2 | head -1 | awk '{print $3}')
+   if [[ -z "$CGROUP_ROOT" ]]; then
+-    CGROUP_ROOT=/dev/cgroup/memory
++    CGROUP_ROOT=$(mktemp -d)
+     mount -t cgroup2 none $CGROUP_ROOT
+     do_umount=1
+   fi
+-- 
+2.39.5
+
index f85612522cee811102ef4853fc664950f9a4d62c..3f58b36e8cef55f0909db7257606f299713f0221 100644 (file)
@@ -191,3 +191,45 @@ drivers-staging-rtl8723bs-fix-deadlock-in-rtw_surveydone_event_callback.patch
 s390-dasd-fix-double-module-refcount-decrement.patch
 pmdomain-ti-add-a-null-pointer-check-to-the-omap_prm_domain_init.patch
 drivers-staging-rtl8723bs-fix-locking-in-rtw_scan_timeout_handler.patch
+platform-x86-isst-correct-command-storage-data-lengt.patch
+tracing-allow-synthetic-events-to-pass-around-stackt.patch
+tracing-fix-synth-event-printk-format-for-str-fields.patch
+media-streamzap-remove-unnecessary-ir_raw_event_rese.patch
+media-streamzap-no-need-for-usb-pid-vid-in-device-na.patch
+media-streamzap-less-chatter.patch
+media-streamzap-remove-unused-struct-members.patch
+media-streamzap-fix-race-between-device-disconnectio.patch
+media-venus-venc-init-the-session-only-once-in-queue.patch
+media-venus-limit-hfi-sessions-to-the-maximum-suppor.patch
+media-venus-hfi-correct-session-init-return-error.patch
+media-venus-pm_helpers-check-instance-state-when-cal.patch
+media-venus-create-hfi-platform-and-move-vpp-vsp-the.patch
+media-venus-rename-venus_caps-to-hfi_plat_caps.patch
+media-venus-hfi_plat-add-codecs-and-capabilities-ops.patch
+media-venus-get-codecs-and-capabilities-from-hfi-pla.patch
+media-venus-hfi_parser-refactor-hfi-packet-parsing-l.patch
+net-dsa-mv88e6xxx-fix-vtu-methods-for-6320-family.patch
+soc-samsung-exynos-chipid-initialize-later-with-arch.patch
+soc-samsung-exynos-chipid-convert-to-driver-and-merg.patch
+soc-samsung-exynos-chipid-avoid-soc_device_to_device.patch
+soc-samsung-exynos-chipid-pass-revision-reg-offsets.patch
+soc-samsung-exynos-chipid-add-null-pointer-check-in-.patch
+iio-adc-ad7768-1-move-setting-of-val-a-bit-later-to-.patch
+iio-adc-ad7768-1-fix-conversion-result-sign.patch
+driver-core-platform-reorder-functions.patch
+driver-core-platform-change-logic-implementing-platf.patch
+driver-core-platform-use-bus_type-functions.patch
+driver-core-platform-emit-a-warning-if-a-remove-call.patch
+platform-provide-a-remove-callback-that-returns-no-v.patch
+backlight-led_bl-convert-to-platform-remove-callback.patch
+backlight-led_bl-hold-led_access-lock-when-calling-l.patch
+cifs-print-tids-as-hex.patch
+cifs-avoid-null-pointer-dereference-in-dbg-call.patch
+pci-introduce-domain_nr-in-pci_host_bridge.patch
+pci-coalesce-host-bridge-contiguous-apertures.patch
+pci-assign-pci-domain-ids-by-ida_alloc.patch
+pci-fix-reference-leak-in-pci_register_host_bridge.patch
+selftests-mm-generate-a-temporary-mountpoint-for-cgr.patch
+drm-amd-amdgpu-amdgpu_vram_mgr-add-missing-descripti.patch
+drm-amdgpu-remove-amdgpu_device-arg-from-free_sgt-ap.patch
+drm-amdgpu-dma_buf-fix-page_link-check.patch
diff --git a/queue-5.10/soc-samsung-exynos-chipid-add-null-pointer-check-in-.patch b/queue-5.10/soc-samsung-exynos-chipid-add-null-pointer-check-in-.patch
new file mode 100644 (file)
index 0000000..fb46332
--- /dev/null
@@ -0,0 +1,43 @@
+From b002eeb638cdba75a661d928059e4770ce106557 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 15:35:18 -0600
+Subject: soc: samsung: exynos-chipid: Add NULL pointer check in
+ exynos_chipid_probe()
+
+From: Chenyuan Yang <chenyuan0y@gmail.com>
+
+[ Upstream commit c8222ef6cf29dd7cad21643228f96535cc02b327 ]
+
+soc_dev_attr->revision could be NULL, thus,
+a pointer check is added to prevent potential NULL pointer dereference.
+This is similar to the fix in commit 3027e7b15b02
+("ice: Fix some null pointer dereference issues in ice_ptp.c").
+
+This issue is found by our static analysis tool.
+
+Signed-off-by: Chenyuan Yang <chenyuan0y@gmail.com>
+Link: https://lore.kernel.org/r/20250212213518.69432-1-chenyuan0y@gmail.com
+Fixes: 3253b7b7cd44 ("soc: samsung: Add exynos chipid driver support")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/samsung/exynos-chipid.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
+index a2d163a1b4e11..fb9e80b63b917 100644
+--- a/drivers/soc/samsung/exynos-chipid.c
++++ b/drivers/soc/samsung/exynos-chipid.c
+@@ -124,6 +124,8 @@ static int exynos_chipid_probe(struct platform_device *pdev)
+       soc_dev_attr->revision = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+                                               "%x", soc_info.revision);
++      if (!soc_dev_attr->revision)
++              return -ENOMEM;
+       soc_dev_attr->soc_id = product_id_to_soc_id(soc_info.product_id);
+       if (!soc_dev_attr->soc_id) {
+               pr_err("Unknown SoC\n");
+-- 
+2.39.5
+
diff --git a/queue-5.10/soc-samsung-exynos-chipid-avoid-soc_device_to_device.patch b/queue-5.10/soc-samsung-exynos-chipid-avoid-soc_device_to_device.patch
new file mode 100644 (file)
index 0000000..0e6702b
--- /dev/null
@@ -0,0 +1,45 @@
+From 6e7007923ae880de6d1f758136d7cc00590e02cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Sep 2021 11:31:12 +0200
+Subject: soc: samsung: exynos-chipid: avoid soc_device_to_device()
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+[ Upstream commit d1141886c8d72ad77920e6e4b617d366e6e3ee8a ]
+
+soc_device_to_device() seems to be discouraged [1] so remove it in favor
+of printing info message with platform device.  This will only change
+the prefix in the info message from "soc soc0: " to "exynos-chipid
+10000000.chipid:".
+
+[1] https://lore.kernel.org/lkml/20191111052741.GB3176397@kroah.com/
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Reviewed-by: Sylwester Nawrocki <snawrocki@kernel.org>
+Tested-by: Sylwester Nawrocki <snawrocki@kernel.org>
+Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
+Tested-by: Alim Akhtar <alim.akhtar@samsung.com>
+Link: https://lore.kernel.org/r/20210919093114.35987-2-krzysztof.kozlowski@canonical.com
+Stable-dep-of: c8222ef6cf29 ("soc: samsung: exynos-chipid: Add NULL pointer check in exynos_chipid_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/samsung/exynos-chipid.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
+index 2ab6ce71e9be5..2b02af5d2faff 100644
+--- a/drivers/soc/samsung/exynos-chipid.c
++++ b/drivers/soc/samsung/exynos-chipid.c
+@@ -103,8 +103,7 @@ static int exynos_chipid_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, soc_dev);
+-      dev_info(soc_device_to_device(soc_dev),
+-               "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
++      dev_info(&pdev->dev, "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
+                soc_dev_attr->soc_id, product_id, revision);
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-5.10/soc-samsung-exynos-chipid-convert-to-driver-and-merg.patch b/queue-5.10/soc-samsung-exynos-chipid-convert-to-driver-and-merg.patch
new file mode 100644 (file)
index 0000000..526e476
--- /dev/null
@@ -0,0 +1,370 @@
+From 755165359792d34158f7497441d44801256b3472 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Dec 2020 19:54:57 +0100
+Subject: soc: samsung: exynos-chipid: convert to driver and merge exynos-asv
+
+From: Krzysztof Kozlowski <krzk@kernel.org>
+
+[ Upstream commit 352bfbb3e0230c96b2bce00d2ac3f0de303cc7b6 ]
+
+The Exynos Chip ID driver on Exynos SoCs has so far only informational
+purpose - to expose the SoC device in sysfs.  No other drivers depend on
+it so there is really no benefit of initializing it early.
+
+The code would be the most flexible if converted to a regular driver.
+However there is already another driver - Exynos ASV (Adaptive Supply
+Voltage) - which binds to the device node of Chip ID.
+
+The solution is to convert the Exynos Chip ID to a built in driver and
+merge the Exynos ASV into it.
+
+This has several benefits:
+1. Although the Exynos ASV driver binds to a device node present in all
+   Exynos DTS (generic compatible), it fails to probe except on the
+   supported ones (only Exynos5422).  This means that the regular boot
+   process has a planned/normal device probe failure.
+
+   Merging the ASV into Chip ID will remove this probe failure because
+   the final driver will always bind, just with disabled ASV features.
+
+2. Allows to use dev_info() as the SoC bus is present (since
+   core_initcall).
+
+3. Could speed things up because of execution of Chip ID code in a SMP
+   environment (after bringing up secondary CPUs, unlike early_initcall),
+   This reduces the amount of work to be done early, when the kernel has
+   to bring up critical devices.
+
+5. Makes the Chip ID code defer-probe friendly,
+
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Link: https://lore.kernel.org/r/20201207190517.262051-5-krzk@kernel.org
+Reviewed-by: Pankaj Dubey <pankaj.dubey@samsung.com>
+Stable-dep-of: c8222ef6cf29 ("soc: samsung: exynos-chipid: Add NULL pointer check in exynos_chipid_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-exynos/Kconfig        |  1 -
+ drivers/soc/samsung/Kconfig         | 12 +++--
+ drivers/soc/samsung/Makefile        |  3 +-
+ drivers/soc/samsung/exynos-asv.c    | 45 +++++--------------
+ drivers/soc/samsung/exynos-asv.h    |  2 +
+ drivers/soc/samsung/exynos-chipid.c | 69 ++++++++++++++++++++---------
+ 6 files changed, 67 insertions(+), 65 deletions(-)
+
+diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
+index b5df98ee5d176..4b554cc8fa58a 100644
+--- a/arch/arm/mach-exynos/Kconfig
++++ b/arch/arm/mach-exynos/Kconfig
+@@ -13,7 +13,6 @@ menuconfig ARCH_EXYNOS
+       select ARM_GIC
+       select EXYNOS_IRQ_COMBINER
+       select COMMON_CLK_SAMSUNG
+-      select EXYNOS_ASV
+       select EXYNOS_CHIPID
+       select EXYNOS_THERMAL
+       select EXYNOS_PMU
+diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
+index fc7f48a922881..5745d7e5908e9 100644
+--- a/drivers/soc/samsung/Kconfig
++++ b/drivers/soc/samsung/Kconfig
+@@ -7,21 +7,19 @@ menuconfig SOC_SAMSUNG
+ if SOC_SAMSUNG
+-config EXYNOS_ASV
+-      bool "Exynos Adaptive Supply Voltage support" if COMPILE_TEST
+-      depends on (ARCH_EXYNOS && EXYNOS_CHIPID) || COMPILE_TEST
+-      select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS
+-
+ # There is no need to enable these drivers for ARMv8
+ config EXYNOS_ASV_ARM
+       bool "Exynos ASV ARMv7-specific driver extensions" if COMPILE_TEST
+-      depends on EXYNOS_ASV
++      depends on EXYNOS_CHIPID
+ config EXYNOS_CHIPID
+-      bool "Exynos Chipid controller driver" if COMPILE_TEST
++      bool "Exynos ChipID controller and ASV driver" if COMPILE_TEST
+       depends on ARCH_EXYNOS || COMPILE_TEST
++      select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS
+       select MFD_SYSCON
+       select SOC_BUS
++      help
++        Support for Samsung Exynos SoC ChipID and Adaptive Supply Voltage.
+ config EXYNOS_PMU
+       bool "Exynos PMU controller driver" if COMPILE_TEST
+diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
+index 59e8e9453f27c..0c523a8de4ebf 100644
+--- a/drivers/soc/samsung/Makefile
++++ b/drivers/soc/samsung/Makefile
+@@ -1,9 +1,8 @@
+ # SPDX-License-Identifier: GPL-2.0
+-obj-$(CONFIG_EXYNOS_ASV)      += exynos-asv.o
+ obj-$(CONFIG_EXYNOS_ASV_ARM)  += exynos5422-asv.o
+-obj-$(CONFIG_EXYNOS_CHIPID)   += exynos-chipid.o
++obj-$(CONFIG_EXYNOS_CHIPID)   += exynos-chipid.o exynos-asv.o
+ obj-$(CONFIG_EXYNOS_PMU)      += exynos-pmu.o
+ obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)  += exynos3250-pmu.o exynos4-pmu.o \
+diff --git a/drivers/soc/samsung/exynos-asv.c b/drivers/soc/samsung/exynos-asv.c
+index 5daeadc363829..d60af8acc3916 100644
+--- a/drivers/soc/samsung/exynos-asv.c
++++ b/drivers/soc/samsung/exynos-asv.c
+@@ -2,7 +2,9 @@
+ /*
+  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+  *          http://www.samsung.com/
++ * Copyright (c) 2020 Krzysztof Kozlowski <krzk@kernel.org>
+  * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
++ * Author: Krzysztof Kozlowski <krzk@kernel.org>
+  *
+  * Samsung Exynos SoC Adaptive Supply Voltage support
+  */
+@@ -10,12 +12,7 @@
+ #include <linux/cpu.h>
+ #include <linux/device.h>
+ #include <linux/errno.h>
+-#include <linux/init.h>
+-#include <linux/mfd/syscon.h>
+-#include <linux/module.h>
+ #include <linux/of.h>
+-#include <linux/of_device.h>
+-#include <linux/platform_device.h>
+ #include <linux/pm_opp.h>
+ #include <linux/regmap.h>
+ #include <linux/soc/samsung/exynos-chipid.h>
+@@ -111,7 +108,7 @@ static int exynos_asv_update_opps(struct exynos_asv *asv)
+       return  0;
+ }
+-static int exynos_asv_probe(struct platform_device *pdev)
++int exynos_asv_init(struct device *dev, struct regmap *regmap)
+ {
+       int (*probe_func)(struct exynos_asv *asv);
+       struct exynos_asv *asv;
+@@ -119,21 +116,16 @@ static int exynos_asv_probe(struct platform_device *pdev)
+       u32 product_id = 0;
+       int ret, i;
+-      asv = devm_kzalloc(&pdev->dev, sizeof(*asv), GFP_KERNEL);
++      asv = devm_kzalloc(dev, sizeof(*asv), GFP_KERNEL);
+       if (!asv)
+               return -ENOMEM;
+-      asv->chipid_regmap = device_node_to_regmap(pdev->dev.of_node);
+-      if (IS_ERR(asv->chipid_regmap)) {
+-              dev_err(&pdev->dev, "Could not find syscon regmap\n");
+-              return PTR_ERR(asv->chipid_regmap);
+-      }
+-
++      asv->chipid_regmap = regmap;
++      asv->dev = dev;
+       ret = regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID,
+                         &product_id);
+       if (ret < 0) {
+-              dev_err(&pdev->dev, "Cannot read revision from ChipID: %d\n",
+-                      ret);
++              dev_err(dev, "Cannot read revision from ChipID: %d\n", ret);
+               return -ENODEV;
+       }
+@@ -142,7 +134,9 @@ static int exynos_asv_probe(struct platform_device *pdev)
+               probe_func = exynos5422_asv_init;
+               break;
+       default:
+-              return -ENODEV;
++              dev_dbg(dev, "No ASV support for this SoC\n");
++              devm_kfree(dev, asv);
++              return 0;
+       }
+       cpu_dev = get_cpu_device(0);
+@@ -150,14 +144,11 @@ static int exynos_asv_probe(struct platform_device *pdev)
+       if (ret < 0)
+               return -EPROBE_DEFER;
+-      ret = of_property_read_u32(pdev->dev.of_node, "samsung,asv-bin",
++      ret = of_property_read_u32(dev->of_node, "samsung,asv-bin",
+                                  &asv->of_bin);
+       if (ret < 0)
+               asv->of_bin = -EINVAL;
+-      asv->dev = &pdev->dev;
+-      dev_set_drvdata(&pdev->dev, asv);
+-
+       for (i = 0; i < ARRAY_SIZE(asv->subsys); i++)
+               asv->subsys[i].asv = asv;
+@@ -167,17 +158,3 @@ static int exynos_asv_probe(struct platform_device *pdev)
+       return exynos_asv_update_opps(asv);
+ }
+-
+-static const struct of_device_id exynos_asv_of_device_ids[] = {
+-      { .compatible = "samsung,exynos4210-chipid" },
+-      {}
+-};
+-
+-static struct platform_driver exynos_asv_driver = {
+-      .driver = {
+-              .name = "exynos-asv",
+-              .of_match_table = exynos_asv_of_device_ids,
+-      },
+-      .probe  = exynos_asv_probe,
+-};
+-module_platform_driver(exynos_asv_driver);
+diff --git a/drivers/soc/samsung/exynos-asv.h b/drivers/soc/samsung/exynos-asv.h
+index 3fd1f2acd9995..dcbe154db31e0 100644
+--- a/drivers/soc/samsung/exynos-asv.h
++++ b/drivers/soc/samsung/exynos-asv.h
+@@ -68,4 +68,6 @@ static inline u32 exynos_asv_opp_get_frequency(const struct exynos_asv_subsys *s
+       return __asv_get_table_entry(&subsys->table, level, 0);
+ }
++int exynos_asv_init(struct device *dev, struct regmap *regmap);
++
+ #endif /* __LINUX_SOC_EXYNOS_ASV_H */
+diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
+index 0f2de1b016a59..2ab6ce71e9be5 100644
+--- a/drivers/soc/samsung/exynos-chipid.c
++++ b/drivers/soc/samsung/exynos-chipid.c
+@@ -2,20 +2,28 @@
+ /*
+  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+  *          http://www.samsung.com/
++ * Copyright (c) 2020 Krzysztof Kozlowski <krzk@kernel.org>
+  *
+  * Exynos - CHIP ID support
+  * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
+  * Author: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
++ * Author: Krzysztof Kozlowski <krzk@kernel.org>
++ *
++ * Samsung Exynos SoC Adaptive Supply Voltage and Chip ID support
+  */
+-#include <linux/io.h>
++#include <linux/device.h>
++#include <linux/errno.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/of.h>
++#include <linux/platform_device.h>
+ #include <linux/regmap.h>
+ #include <linux/slab.h>
+ #include <linux/soc/samsung/exynos-chipid.h>
+ #include <linux/sys_soc.h>
++#include "exynos-asv.h"
++
+ static const struct exynos_soc_id {
+       const char *name;
+       unsigned int id;
+@@ -45,25 +53,17 @@ static const char * __init product_id_to_soc_id(unsigned int product_id)
+       return NULL;
+ }
+-static int __init exynos_chipid_early_init(void)
++static int exynos_chipid_probe(struct platform_device *pdev)
+ {
+       struct soc_device_attribute *soc_dev_attr;
+       struct soc_device *soc_dev;
+       struct device_node *root;
+-      struct device_node *syscon;
+       struct regmap *regmap;
+       u32 product_id;
+       u32 revision;
+       int ret;
+-      syscon = of_find_compatible_node(NULL, NULL,
+-                                       "samsung,exynos4210-chipid");
+-      if (!syscon)
+-              return -ENODEV;
+-
+-      regmap = device_node_to_regmap(syscon);
+-      of_node_put(syscon);
+-
++      regmap = device_node_to_regmap(pdev->dev.of_node);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+@@ -73,7 +73,8 @@ static int __init exynos_chipid_early_init(void)
+       revision = product_id & EXYNOS_REV_MASK;
+-      soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
++      soc_dev_attr = devm_kzalloc(&pdev->dev, sizeof(*soc_dev_attr),
++                                  GFP_KERNEL);
+       if (!soc_dev_attr)
+               return -ENOMEM;
+@@ -83,20 +84,24 @@ static int __init exynos_chipid_early_init(void)
+       of_property_read_string(root, "model", &soc_dev_attr->machine);
+       of_node_put(root);
+-      soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
++      soc_dev_attr->revision = devm_kasprintf(&pdev->dev, GFP_KERNEL,
++                                              "%x", revision);
+       soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
+       if (!soc_dev_attr->soc_id) {
+               pr_err("Unknown SoC\n");
+-              ret = -ENODEV;
+-              goto err;
++              return -ENODEV;
+       }
+       /* please note that the actual registration will be deferred */
+       soc_dev = soc_device_register(soc_dev_attr);
+-      if (IS_ERR(soc_dev)) {
+-              ret = PTR_ERR(soc_dev);
++      if (IS_ERR(soc_dev))
++              return PTR_ERR(soc_dev);
++
++      ret = exynos_asv_init(&pdev->dev, regmap);
++      if (ret)
+               goto err;
+-      }
++
++      platform_set_drvdata(pdev, soc_dev);
+       dev_info(soc_device_to_device(soc_dev),
+                "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
+@@ -105,9 +110,31 @@ static int __init exynos_chipid_early_init(void)
+       return 0;
+ err:
+-      kfree(soc_dev_attr->revision);
+-      kfree(soc_dev_attr);
++      soc_device_unregister(soc_dev);
++
+       return ret;
+ }
+-arch_initcall(exynos_chipid_early_init);
++static int exynos_chipid_remove(struct platform_device *pdev)
++{
++      struct soc_device *soc_dev = platform_get_drvdata(pdev);
++
++      soc_device_unregister(soc_dev);
++
++      return 0;
++}
++
++static const struct of_device_id exynos_chipid_of_device_ids[] = {
++      { .compatible = "samsung,exynos4210-chipid" },
++      {}
++};
++
++static struct platform_driver exynos_chipid_driver = {
++      .driver = {
++              .name = "exynos-chipid",
++              .of_match_table = exynos_chipid_of_device_ids,
++      },
++      .probe  = exynos_chipid_probe,
++      .remove = exynos_chipid_remove,
++};
++builtin_platform_driver(exynos_chipid_driver);
+-- 
+2.39.5
+
diff --git a/queue-5.10/soc-samsung-exynos-chipid-initialize-later-with-arch.patch b/queue-5.10/soc-samsung-exynos-chipid-initialize-later-with-arch.patch
new file mode 100644 (file)
index 0000000..9e341f8
--- /dev/null
@@ -0,0 +1,55 @@
+From 5d8266c978cf8b7ac0930fcf1fc70a5d15541e47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Dec 2020 21:59:55 +0200
+Subject: soc: samsung: exynos-chipid: initialize later - with arch_initcall
+
+From: Krzysztof Kozlowski <krzk@kernel.org>
+
+[ Upstream commit 3b4c362e5ef102ca2d70d33f4e8cf0780053a7db ]
+
+The Exynos ChipID driver on Exynos SoCs has only informational
+purpose - to expose the SoC device in sysfs.  No other drivers
+depend on it so there is really no benefit of initializing it early.
+
+Instead, initialize everything with arch_initcall which:
+1. Allows to use dev_info() as the SoC bus is present (since
+   core_initcall),
+2. Could speed things up because of execution in a SMP environment
+   (after bringing up secondary CPUs, unlike early_initcall),
+3. Reduces the amount of work to be done early, when the kernel has to
+   bring up critical devices.
+
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Link: https://lore.kernel.org/r/20201202195955.128633-2-krzk@kernel.org
+Stable-dep-of: c8222ef6cf29 ("soc: samsung: exynos-chipid: Add NULL pointer check in exynos_chipid_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/samsung/exynos-chipid.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
+index 8d4d050869068..0f2de1b016a59 100644
+--- a/drivers/soc/samsung/exynos-chipid.c
++++ b/drivers/soc/samsung/exynos-chipid.c
+@@ -98,9 +98,9 @@ static int __init exynos_chipid_early_init(void)
+               goto err;
+       }
+-      /* it is too early to use dev_info() here (soc_dev is NULL) */
+-      pr_info("soc soc0: Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
+-              soc_dev_attr->soc_id, product_id, revision);
++      dev_info(soc_device_to_device(soc_dev),
++               "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
++               soc_dev_attr->soc_id, product_id, revision);
+       return 0;
+@@ -110,4 +110,4 @@ static int __init exynos_chipid_early_init(void)
+       return ret;
+ }
+-early_initcall(exynos_chipid_early_init);
++arch_initcall(exynos_chipid_early_init);
+-- 
+2.39.5
+
diff --git a/queue-5.10/soc-samsung-exynos-chipid-pass-revision-reg-offsets.patch b/queue-5.10/soc-samsung-exynos-chipid-pass-revision-reg-offsets.patch
new file mode 100644 (file)
index 0000000..d14c9ad
--- /dev/null
@@ -0,0 +1,196 @@
+From 2c0af2c4721c4f25b917681cb1eaeba5064a5489 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Oct 2021 16:35:06 +0300
+Subject: soc: samsung: exynos-chipid: Pass revision reg offsets
+
+From: Sam Protsenko <semen.protsenko@linaro.org>
+
+[ Upstream commit c072c4ef7ef09e1d6470c48cf52570487589b76a ]
+
+Old Exynos SoCs have both Product ID and Revision ID in one single
+register, while new SoCs tend to have two separate registers for those
+IDs. Implement handling of both cases by passing Revision ID register
+offsets in driver data.
+
+Previously existing macros for Exynos4210 (removed in this patch) were
+incorrect:
+
+    #define EXYNOS_SUBREV_MASK         (0xf << 4)
+    #define EXYNOS_MAINREV_MASK        (0xf << 0)
+
+Actual format of PRO_ID register in Exynos4210 (offset 0x0):
+
+    [31:12] Product ID
+      [9:8] Package information
+      [7:4] Main Revision Number
+      [3:0] Sub Revision Number
+
+This patch doesn't change the behavior on existing platforms, so
+'/sys/devices/soc0/revision' will show the same string as before.
+
+Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
+Tested-by: Henrik Grimler <henrik@grimler.se>
+Link: https://lore.kernel.org/r/20211014133508.1210-1-semen.protsenko@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Stable-dep-of: c8222ef6cf29 ("soc: samsung: exynos-chipid: Add NULL pointer check in exynos_chipid_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/samsung/exynos-chipid.c       | 69 +++++++++++++++++++----
+ include/linux/soc/samsung/exynos-chipid.h |  6 +-
+ 2 files changed, 60 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
+index 2b02af5d2faff..a2d163a1b4e11 100644
+--- a/drivers/soc/samsung/exynos-chipid.c
++++ b/drivers/soc/samsung/exynos-chipid.c
+@@ -16,6 +16,7 @@
+ #include <linux/errno.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/of.h>
++#include <linux/of_device.h>
+ #include <linux/platform_device.h>
+ #include <linux/regmap.h>
+ #include <linux/slab.h>
+@@ -24,6 +25,17 @@
+ #include "exynos-asv.h"
++struct exynos_chipid_variant {
++      unsigned int rev_reg;           /* revision register offset */
++      unsigned int main_rev_shift;    /* main revision offset in rev_reg */
++      unsigned int sub_rev_shift;     /* sub revision offset in rev_reg */
++};
++
++struct exynos_chipid_info {
++      u32 product_id;
++      u32 revision;
++};
++
+ static const struct exynos_soc_id {
+       const char *name;
+       unsigned int id;
+@@ -48,31 +60,57 @@ static const char * __init product_id_to_soc_id(unsigned int product_id)
+       int i;
+       for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
+-              if ((product_id & EXYNOS_MASK) == soc_ids[i].id)
++              if (product_id == soc_ids[i].id)
+                       return soc_ids[i].name;
+       return NULL;
+ }
++static int exynos_chipid_get_chipid_info(struct regmap *regmap,
++              const struct exynos_chipid_variant *data,
++              struct exynos_chipid_info *soc_info)
++{
++      int ret;
++      unsigned int val, main_rev, sub_rev;
++
++      ret = regmap_read(regmap, EXYNOS_CHIPID_REG_PRO_ID, &val);
++      if (ret < 0)
++              return ret;
++      soc_info->product_id = val & EXYNOS_MASK;
++
++      if (data->rev_reg != EXYNOS_CHIPID_REG_PRO_ID) {
++              ret = regmap_read(regmap, data->rev_reg, &val);
++              if (ret < 0)
++                      return ret;
++      }
++      main_rev = (val >> data->main_rev_shift) & EXYNOS_REV_PART_MASK;
++      sub_rev = (val >> data->sub_rev_shift) & EXYNOS_REV_PART_MASK;
++      soc_info->revision = (main_rev << EXYNOS_REV_PART_SHIFT) | sub_rev;
++
++      return 0;
++}
++
+ static int exynos_chipid_probe(struct platform_device *pdev)
+ {
++      const struct exynos_chipid_variant *drv_data;
++      struct exynos_chipid_info soc_info;
+       struct soc_device_attribute *soc_dev_attr;
+       struct soc_device *soc_dev;
+       struct device_node *root;
+       struct regmap *regmap;
+-      u32 product_id;
+-      u32 revision;
+       int ret;
++      drv_data = of_device_get_match_data(&pdev->dev);
++      if (!drv_data)
++              return -EINVAL;
++
+       regmap = device_node_to_regmap(pdev->dev.of_node);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+-      ret = regmap_read(regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
++      ret = exynos_chipid_get_chipid_info(regmap, drv_data, &soc_info);
+       if (ret < 0)
+               return ret;
+-      revision = product_id & EXYNOS_REV_MASK;
+-
+       soc_dev_attr = devm_kzalloc(&pdev->dev, sizeof(*soc_dev_attr),
+                                   GFP_KERNEL);
+       if (!soc_dev_attr)
+@@ -85,8 +123,8 @@ static int exynos_chipid_probe(struct platform_device *pdev)
+       of_node_put(root);
+       soc_dev_attr->revision = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+-                                              "%x", revision);
+-      soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
++                                              "%x", soc_info.revision);
++      soc_dev_attr->soc_id = product_id_to_soc_id(soc_info.product_id);
+       if (!soc_dev_attr->soc_id) {
+               pr_err("Unknown SoC\n");
+               return -ENODEV;
+@@ -104,7 +142,7 @@ static int exynos_chipid_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, soc_dev);
+       dev_info(&pdev->dev, "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
+-               soc_dev_attr->soc_id, product_id, revision);
++               soc_dev_attr->soc_id, soc_info.product_id, soc_info.revision);
+       return 0;
+@@ -123,9 +161,18 @@ static int exynos_chipid_remove(struct platform_device *pdev)
+       return 0;
+ }
++static const struct exynos_chipid_variant exynos4210_chipid_drv_data = {
++      .rev_reg        = 0x0,
++      .main_rev_shift = 4,
++      .sub_rev_shift  = 0,
++};
++
+ static const struct of_device_id exynos_chipid_of_device_ids[] = {
+-      { .compatible = "samsung,exynos4210-chipid" },
+-      {}
++      {
++              .compatible     = "samsung,exynos4210-chipid",
++              .data           = &exynos4210_chipid_drv_data,
++      },
++      { }
+ };
+ static struct platform_driver exynos_chipid_driver = {
+diff --git a/include/linux/soc/samsung/exynos-chipid.h b/include/linux/soc/samsung/exynos-chipid.h
+index 8bca6763f99c1..62f0e25310687 100644
+--- a/include/linux/soc/samsung/exynos-chipid.h
++++ b/include/linux/soc/samsung/exynos-chipid.h
+@@ -9,10 +9,8 @@
+ #define __LINUX_SOC_EXYNOS_CHIPID_H
+ #define EXYNOS_CHIPID_REG_PRO_ID      0x00
+-#define EXYNOS_SUBREV_MASK            (0xf << 4)
+-#define EXYNOS_MAINREV_MASK           (0xf << 0)
+-#define EXYNOS_REV_MASK                       (EXYNOS_SUBREV_MASK | \
+-                                       EXYNOS_MAINREV_MASK)
++#define EXYNOS_REV_PART_MASK          0xf
++#define EXYNOS_REV_PART_SHIFT         4
+ #define EXYNOS_MASK                   0xfffff000
+ #define EXYNOS_CHIPID_REG_PKG_ID      0x04
+-- 
+2.39.5
+
diff --git a/queue-5.10/tracing-allow-synthetic-events-to-pass-around-stackt.patch b/queue-5.10/tracing-allow-synthetic-events-to-pass-around-stackt.patch
new file mode 100644 (file)
index 0000000..161ce83
--- /dev/null
@@ -0,0 +1,282 @@
+From f85226030cd1bf402c8fde3022124a03c07b1db1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Jan 2023 10:21:28 -0500
+Subject: tracing: Allow synthetic events to pass around stacktraces
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit 00cf3d672a9dd409418647e9f98784c339c3ff63 ]
+
+Allow a stacktrace from one event to be displayed by the end event of a
+synthetic event. This is very useful when looking for the longest latency
+of a sleep or something blocked on I/O.
+
+ # cd /sys/kernel/tracing/
+ # echo 's:block_lat pid_t pid; u64 delta; unsigned long[] stack;' > dynamic_events
+ # echo 'hist:keys=next_pid:ts=common_timestamp.usecs,st=stacktrace  if prev_state == 1||prev_state == 2' > events/sched/sched_switch/trigger
+ # echo 'hist:keys=prev_pid:delta=common_timestamp.usecs-$ts,s=$st:onmax($delta).trace(block_lat,prev_pid,$delta,$s)' >> events/sched/sched_switch/trigger
+
+The above creates a "block_lat" synthetic event that take the stacktrace of
+when a task schedules out in either the interruptible or uninterruptible
+states, and on a new per process max $delta (the time it was scheduled
+out), will print the process id and the stacktrace.
+
+  # echo 1 > events/synthetic/block_lat/enable
+  # cat trace
+ #           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
+ #              | |         |   |||||     |         |
+    kworker/u16:0-767     [006] d..4.   560.645045: block_lat: pid=767 delta=66 stack=STACK:
+ => __schedule
+ => schedule
+ => pipe_read
+ => vfs_read
+ => ksys_read
+ => do_syscall_64
+ => 0x966000aa
+
+           <idle>-0       [003] d..4.   561.132117: block_lat: pid=0 delta=413787 stack=STACK:
+ => __schedule
+ => schedule
+ => schedule_hrtimeout_range_clock
+ => do_sys_poll
+ => __x64_sys_poll
+ => do_syscall_64
+ => 0x966000aa
+
+            <...>-153     [006] d..4.   562.068407: block_lat: pid=153 delta=54 stack=STACK:
+ => __schedule
+ => schedule
+ => io_schedule
+ => rq_qos_wait
+ => wbt_wait
+ => __rq_qos_throttle
+ => blk_mq_submit_bio
+ => submit_bio_noacct_nocheck
+ => ext4_bio_write_page
+ => mpage_submit_page
+ => mpage_process_page_bufs
+ => mpage_prepare_extent_to_map
+ => ext4_do_writepages
+ => ext4_writepages
+ => do_writepages
+ => __writeback_single_inode
+
+Link: https://lkml.kernel.org/r/20230117152236.010941267@goodmis.org
+
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Tom Zanussi <zanussi@kernel.org>
+Cc: Ross Zwisler <zwisler@google.com>
+Cc: Ching-lin Yu <chinglinyu@google.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Stable-dep-of: 4d38328eb442 ("tracing: Fix synth event printk format for str fields")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace.h              |  4 ++
+ kernel/trace/trace_events_hist.c  |  7 ++-
+ kernel/trace/trace_events_synth.c | 80 ++++++++++++++++++++++++++++++-
+ kernel/trace/trace_synth.h        |  1 +
+ 4 files changed, 87 insertions(+), 5 deletions(-)
+
+diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
+index 7c90872f2435d..f47938d8401a2 100644
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -109,6 +109,10 @@ enum trace_type {
+       unlikely(__ret_warn_once);                              \
+ })
++#define HIST_STACKTRACE_DEPTH 16
++#define HIST_STACKTRACE_SIZE  (HIST_STACKTRACE_DEPTH * sizeof(unsigned long))
++#define HIST_STACKTRACE_SKIP  5
++
+ /*
+  * syscalls are special, and need special handling, this is why
+  * they are not included in trace_entries.h
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index 059a106e62bec..a0342b45a06da 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -282,10 +282,6 @@ DEFINE_HIST_FIELD_FN(u8);
+ #define for_each_hist_key_field(i, hist_data) \
+       for ((i) = (hist_data)->n_vals; (i) < (hist_data)->n_fields; (i)++)
+-#define HIST_STACKTRACE_DEPTH 16
+-#define HIST_STACKTRACE_SIZE  (HIST_STACKTRACE_DEPTH * sizeof(unsigned long))
+-#define HIST_STACKTRACE_SKIP  5
+-
+ #define HITCOUNT_IDX          0
+ #define HIST_KEY_SIZE_MAX     (MAX_FILTER_STR_VAL + HIST_STACKTRACE_SIZE)
+@@ -3356,6 +3352,9 @@ static int check_synth_field(struct synth_event *event,
+           && field->is_dynamic)
+               return 0;
++      if (strstr(hist_field->type, "long[") && field->is_stack)
++              return 0;
++
+       if (strcmp(field->type, hist_field->type) != 0) {
+               if (field->size != hist_field->size ||
+                   (!field->is_string && field->is_signed != hist_field->is_signed))
+diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
+index e43426aa12830..4878758ceea2a 100644
+--- a/kernel/trace/trace_events_synth.c
++++ b/kernel/trace/trace_events_synth.c
+@@ -162,6 +162,14 @@ static int synth_field_is_string(char *type)
+       return false;
+ }
++static int synth_field_is_stack(char *type)
++{
++      if (strstr(type, "long[") != NULL)
++              return true;
++
++      return false;
++}
++
+ static int synth_field_string_size(char *type)
+ {
+       char buf[4], *end, *start;
+@@ -237,6 +245,8 @@ static int synth_field_size(char *type)
+               size = sizeof(gfp_t);
+       else if (synth_field_is_string(type))
+               size = synth_field_string_size(type);
++      else if (synth_field_is_stack(type))
++              size = 0;
+       return size;
+ }
+@@ -281,6 +291,8 @@ static const char *synth_field_fmt(char *type)
+               fmt = "%x";
+       else if (synth_field_is_string(type))
+               fmt = "%.*s";
++      else if (synth_field_is_stack(type))
++              fmt = "%s";
+       return fmt;
+ }
+@@ -360,6 +372,23 @@ static enum print_line_t print_synth_event(struct trace_iterator *iter,
+                                                i == se->n_fields - 1 ? "" : " ");
+                               n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
+                       }
++              } else if (se->fields[i]->is_stack) {
++                      u32 offset, data_offset, len;
++                      unsigned long *p, *end;
++
++                      offset = (u32)entry->fields[n_u64];
++                      data_offset = offset & 0xffff;
++                      len = offset >> 16;
++
++                      p = (void *)entry + data_offset;
++                      end = (void *)p + len - (sizeof(long) - 1);
++
++                      trace_seq_printf(s, "%s=STACK:\n", se->fields[i]->name);
++
++                      for (; *p && p < end; p++)
++                              trace_seq_printf(s, "=> %pS\n", (void *)*p);
++                      n_u64++;
++
+               } else {
+                       struct trace_print_flags __flags[] = {
+                           __def_gfpflag_names, {-1, NULL} };
+@@ -427,6 +456,43 @@ static unsigned int trace_string(struct synth_trace_event *entry,
+       return len;
+ }
++static unsigned int trace_stack(struct synth_trace_event *entry,
++                               struct synth_event *event,
++                               long *stack,
++                               unsigned int data_size,
++                               unsigned int *n_u64)
++{
++      unsigned int len;
++      u32 data_offset;
++      void *data_loc;
++
++      data_offset = struct_size(entry, fields, event->n_u64);
++      data_offset += data_size;
++
++      for (len = 0; len < HIST_STACKTRACE_DEPTH; len++) {
++              if (!stack[len])
++                      break;
++      }
++
++      /* Include the zero'd element if it fits */
++      if (len < HIST_STACKTRACE_DEPTH)
++              len++;
++
++      len *= sizeof(long);
++
++      /* Find the dynamic section to copy the stack into. */
++      data_loc = (void *)entry + data_offset;
++      memcpy(data_loc, stack, len);
++
++      /* Fill in the field that holds the offset/len combo */
++      data_offset |= len << 16;
++      *(u32 *)&entry->fields[*n_u64] = data_offset;
++
++      (*n_u64)++;
++
++      return len;
++}
++
+ static notrace void trace_event_raw_event_synth(void *__data,
+                                               u64 *var_ref_vals,
+                                               unsigned int *var_ref_idx)
+@@ -479,6 +545,12 @@ static notrace void trace_event_raw_event_synth(void *__data,
+                                          event->fields[i]->is_dynamic,
+                                          data_size, &n_u64);
+                       data_size += len; /* only dynamic string increments */
++              } if (event->fields[i]->is_stack) {
++                      long *stack = (long *)(long)var_ref_vals[val_idx];
++
++                      len = trace_stack(entry, event, stack,
++                                         data_size, &n_u64);
++                      data_size += len;
+               } else {
+                       struct synth_field *field = event->fields[i];
+                       u64 val = var_ref_vals[val_idx];
+@@ -541,6 +613,9 @@ static int __set_synth_event_print_fmt(struct synth_event *event,
+                   event->fields[i]->is_dynamic)
+                       pos += snprintf(buf + pos, LEN_OR_ZERO,
+                               ", __get_str(%s)", event->fields[i]->name);
++              else if (event->fields[i]->is_stack)
++                      pos += snprintf(buf + pos, LEN_OR_ZERO,
++                              ", __get_stacktrace(%s)", event->fields[i]->name);
+               else
+                       pos += snprintf(buf + pos, LEN_OR_ZERO,
+                                       ", REC->%s", event->fields[i]->name);
+@@ -660,7 +735,8 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
+               ret = -EINVAL;
+               goto free;
+       } else if (size == 0) {
+-              if (synth_field_is_string(field->type)) {
++              if (synth_field_is_string(field->type) ||
++                  synth_field_is_stack(field->type)) {
+                       char *type;
+                       len = sizeof("__data_loc ") + strlen(field->type) + 1;
+@@ -691,6 +767,8 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
+       if (synth_field_is_string(field->type))
+               field->is_string = true;
++      else if (synth_field_is_stack(field->type))
++              field->is_stack = true;
+       field->is_signed = synth_field_signed(field->type);
+  out:
+diff --git a/kernel/trace/trace_synth.h b/kernel/trace/trace_synth.h
+index 4007fe95cf42c..077c748a8b3a6 100644
+--- a/kernel/trace/trace_synth.h
++++ b/kernel/trace/trace_synth.h
+@@ -18,6 +18,7 @@ struct synth_field {
+       bool is_signed;
+       bool is_string;
+       bool is_dynamic;
++      bool is_stack;
+ };
+ struct synth_event {
+-- 
+2.39.5
+
diff --git a/queue-5.10/tracing-fix-synth-event-printk-format-for-str-fields.patch b/queue-5.10/tracing-fix-synth-event-printk-format-for-str-fields.patch
new file mode 100644 (file)
index 0000000..4c607fb
--- /dev/null
@@ -0,0 +1,46 @@
+From df3e73ad1909a8e4ae012c85b8b55abae2885bee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Mar 2025 16:52:02 +0000
+Subject: tracing: Fix synth event printk format for str fields
+
+From: Douglas Raillard <douglas.raillard@arm.com>
+
+[ Upstream commit 4d38328eb442dc06aec4350fd9594ffa6488af02 ]
+
+The printk format for synth event uses "%.*s" to print string fields,
+but then only passes the pointer part as var arg.
+
+Replace %.*s with %s as the C string is guaranteed to be null-terminated.
+
+The output in print fmt should never have been updated as __get_str()
+handles the string limit because it can access the length of the string in
+the string meta data that is saved in the ring buffer.
+
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Fixes: 8db4d6bfbbf92 ("tracing: Change synthetic event string format to limit printed length")
+Link: https://lore.kernel.org/20250325165202.541088-1-douglas.raillard@arm.com
+Signed-off-by: Douglas Raillard <douglas.raillard@arm.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace_events_synth.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
+index 4878758ceea2a..613d45e7b608d 100644
+--- a/kernel/trace/trace_events_synth.c
++++ b/kernel/trace/trace_events_synth.c
+@@ -290,7 +290,7 @@ static const char *synth_field_fmt(char *type)
+       else if (strcmp(type, "gfp_t") == 0)
+               fmt = "%x";
+       else if (synth_field_is_string(type))
+-              fmt = "%.*s";
++              fmt = "%s";
+       else if (synth_field_is_stack(type))
+               fmt = "%s";
+-- 
+2.39.5
+