--- /dev/null
+From 8a560b91a93e0f1a90f76ec126077c8dee440d6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Mar 2023 19:52:02 -0500
+Subject: bluetooth: Add device 0bda:887b to device tables
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+[ Upstream commit 730a1d1a93a3e30c3723f87af97a8517334b2203 ]
+
+This device is part of a Realtek RTW8852BE chip.
+
+The device table entry is as follows:
+
+T: Bus=03 Lev=01 Prnt=01 Port=12 Cnt=02 Dev#= 3 Spd=12 MxCh= 0
+D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
+P: Vendor=0bda ProdID=887b Rev= 0.00
+S: Manufacturer=Realtek
+S: Product=Bluetooth Radio
+S: SerialNumber=00e04c000001
+C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: da06ff1f585e ("Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 0cc58447e4f0b..60a7e4ad2566b 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -535,6 +535,8 @@ static const struct usb_device_id blacklist_table[] = {
+ /* Realtek 8852BE Bluetooth devices */
+ { USB_DEVICE(0x0cb8, 0xc559), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
++ { USB_DEVICE(0x0bda, 0x887b), .driver_info = BTUSB_REALTEK |
++ BTUSB_WIDEBAND_SPEECH },
+
+ /* Realtek Bluetooth devices */
+ { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),
+--
+2.42.0
+
--- /dev/null
+From ac2fb259e3fd3daf4def26b529ffc1f71a7a61af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Mar 2023 19:52:03 -0500
+Subject: bluetooth: Add device 13d3:3571 to device tables
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+[ Upstream commit 069f534247bb6db4f8c2c2ea8e9155abf495c37e ]
+
+This device is part of a Realtek RTW8852BE chip. The device table is as follows:
+
+T: Bus=03 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
+D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
+P: Vendor=13d3 ProdID=3571 Rev= 0.00
+S: Manufacturer=Realtek
+S: Product=Bluetooth Radio
+S: SerialNumber=00e04c000001
+C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: da06ff1f585e ("Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 60a7e4ad2566b..697a55e3b65eb 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -537,6 +537,8 @@ static const struct usb_device_id blacklist_table[] = {
+ BTUSB_WIDEBAND_SPEECH },
+ { USB_DEVICE(0x0bda, 0x887b), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
++ { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK |
++ BTUSB_WIDEBAND_SPEECH },
+
+ /* Realtek Bluetooth devices */
+ { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),
+--
+2.42.0
+
--- /dev/null
+From 09c2eb4d8b84f13462cb0d02706c0b94bcea8041 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Oct 2023 19:21:17 +0800
+Subject: Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE
+
+From: Guan Wentao <guanwentao@uniontech.com>
+
+[ Upstream commit da06ff1f585ea784c79f80e7fab0e0c4ebb49c1c ]
+
+Add PID/VID 0bda:b85b for Realtek RTL8852BE USB bluetooth part.
+The PID/VID was reported by the patch last year. [1]
+Some SBCs like rockpi 5B A8 module contains the device.
+And it`s founded in website. [2] [3]
+
+Here is the device tables in /sys/kernel/debug/usb/devices .
+
+T: Bus=07 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
+D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
+P: Vendor=0bda ProdID=b85b Rev= 0.00
+S: Manufacturer=Realtek
+S: Product=Bluetooth Radio
+S: SerialNumber=00e04c000001
+C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+
+Link: https://lore.kernel.org/all/20220420052402.19049-1-tangmeng@uniontech.com/ [1]
+Link: https://forum.radxa.com/t/bluetooth-on-ubuntu/13051/4 [2]
+Link: https://ubuntuforums.org/showthread.php?t=2489527 [3]
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Meng Tang <tangmeng@uniontech.com>
+Signed-off-by: Guan Wentao <guanwentao@uniontech.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 9c651f56627b2..954f7f3b5cc30 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -537,6 +537,8 @@ static const struct usb_device_id blacklist_table[] = {
+ BTUSB_WIDEBAND_SPEECH },
+ { USB_DEVICE(0x0bda, 0x887b), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
++ { USB_DEVICE(0x0bda, 0xb85b), .driver_info = BTUSB_REALTEK |
++ BTUSB_WIDEBAND_SPEECH },
+ { USB_DEVICE(0x13d3, 0x3570), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
+ { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK |
+--
+2.42.0
+
--- /dev/null
+From 8e4b7240d0238b5488f8b8cf8e5b45c3f1f47d9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 11:10:05 +0300
+Subject: Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x0cb8:0xc559
+
+From: Artem Lukyanov <dukzcry@ya.ru>
+
+[ Upstream commit 393b4916b7b5b94faf5c6a7c68df1c62d17e4f38 ]
+
+Add the support ID(0x0cb8, 0xc559) to usb_device_id table for
+Realtek RTL8852BE.
+
+The device info from /sys/kernel/debug/usb/devices as below.
+
+T: Bus=03 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
+D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
+P: Vendor=0cb8 ProdID=c559 Rev= 0.00
+S: Manufacturer=Realtek
+S: Product=Bluetooth Radio
+S: SerialNumber=00e04c000001
+C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+
+Signed-off-by: Artem Lukyanov <dukzcry@ya.ru>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: da06ff1f585e ("Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 4a6369d1dd171..0cc58447e4f0b 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -532,6 +532,10 @@ static const struct usb_device_id blacklist_table[] = {
+ { USB_DEVICE(0x13d3, 0x3592), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
+
++ /* Realtek 8852BE Bluetooth devices */
++ { USB_DEVICE(0x0cb8, 0xc559), .driver_info = BTUSB_REALTEK |
++ BTUSB_WIDEBAND_SPEECH },
++
+ /* Realtek Bluetooth devices */
+ { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),
+ .driver_info = BTUSB_REALTEK },
+--
+2.42.0
+
--- /dev/null
+From fcb8d89b6f34ba2a557cb61d92ea5c02913787d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Sep 2023 16:46:55 +0530
+Subject: Bluetooth: btusb: Add RTW8852BE device 13d3:3570 to device tables
+
+From: Masum Reza <masumrezarock100@gmail.com>
+
+[ Upstream commit 02be109d3a405dbc4d53fb4b4473d7a113548088 ]
+
+This device is used in TP-Link TX20E WiFi+Bluetooth adapter.
+
+Relevant information in /sys/kernel/debug/usb/devices
+about the Bluetooth device is listed as the below.
+
+T: Bus=01 Lev=01 Prnt=01 Port=08 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
+D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
+P: Vendor=13d3 ProdID=3570 Rev= 0.00
+S: Manufacturer=Realtek
+S: Product=Bluetooth Radio
+S: SerialNumber=00e04c000001
+C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+
+Signed-off-by: Masum Reza <masumrezarock100@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: da06ff1f585e ("Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 697a55e3b65eb..9c651f56627b2 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -537,6 +537,8 @@ static const struct usb_device_id blacklist_table[] = {
+ BTUSB_WIDEBAND_SPEECH },
+ { USB_DEVICE(0x0bda, 0x887b), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
++ { USB_DEVICE(0x13d3, 0x3570), .driver_info = BTUSB_REALTEK |
++ BTUSB_WIDEBAND_SPEECH },
+ { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
+
+--
+2.42.0
+
--- /dev/null
+From 95e87558cb8c8d7465fec4eed3e8e1b61e18f2f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Oct 2023 16:05:27 -0600
+Subject: clk: visconti: Fix undefined behavior bug in struct
+ visconti_pll_provider
+
+From: Gustavo A. R. Silva <gustavoars@kernel.org>
+
+[ Upstream commit 5ad1e217a2b23aa046b241183bd9452d259d70d0 ]
+
+`struct clk_hw_onecell_data` is a flexible structure, which means that
+it contains flexible-array member at the bottom, in this case array
+`hws`:
+
+include/linux/clk-provider.h:
+1380 struct clk_hw_onecell_data {
+1381 unsigned int num;
+1382 struct clk_hw *hws[] __counted_by(num);
+1383 };
+
+This could potentially lead to an overwrite of the objects following
+`clk_data` in `struct visconti_pll_provider`, in this case
+`struct device_node *node;`, at run-time:
+
+drivers/clk/visconti/pll.h:
+ 16 struct visconti_pll_provider {
+ 17 void __iomem *reg_base;
+ 18 struct clk_hw_onecell_data clk_data;
+ 19 struct device_node *node;
+ 20 };
+
+Notice that a total of 56 bytes are allocated for flexible-array `hws`
+at line 328. See below:
+
+include/dt-bindings/clock/toshiba,tmpv770x.h:
+ 14 #define TMPV770X_NR_PLL 7
+
+drivers/clk/visconti/pll-tmpv770x.c:
+ 69 ctx = visconti_init_pll(np, reg_base, TMPV770X_NR_PLL);
+
+drivers/clk/visconti/pll.c:
+321 struct visconti_pll_provider * __init visconti_init_pll(struct device_node *np,
+322 void __iomem *base,
+323 unsigned long nr_plls)
+324 {
+325 struct visconti_pll_provider *ctx;
+...
+328 ctx = kzalloc(struct_size(ctx, clk_data.hws, nr_plls), GFP_KERNEL);
+
+`struct_size(ctx, clk_data.hws, nr_plls)` above translates to
+sizeof(struct visconti_pll_provider) + sizeof(struct clk_hw *) * 7 ==
+24 + 8 * 7 == 24 + 56
+ ^^^^
+ |
+ allocated bytes for flex array `hws`
+
+$ pahole -C visconti_pll_provider drivers/clk/visconti/pll.o
+struct visconti_pll_provider {
+ void * reg_base; /* 0 8 */
+ struct clk_hw_onecell_data clk_data; /* 8 8 */
+ struct device_node * node; /* 16 8 */
+
+ /* size: 24, cachelines: 1, members: 3 */
+ /* last cacheline: 24 bytes */
+};
+
+And then, after the allocation, some data is written into all members
+of `struct visconti_pll_provider`:
+
+332 for (i = 0; i < nr_plls; ++i)
+333 ctx->clk_data.hws[i] = ERR_PTR(-ENOENT);
+334
+335 ctx->node = np;
+336 ctx->reg_base = base;
+337 ctx->clk_data.num = nr_plls;
+
+Fix all these by placing the declaration of object `clk_data` at the
+end of `struct visconti_pll_provider`. Also, add a comment to make it
+clear that this object must always be last in the structure, and
+prevent this bug from being introduced again in the future.
+
+-Wflex-array-member-not-at-end is coming in GCC-14, and we are getting
+ready to enable it globally.
+
+Fixes: b4cbe606dc36 ("clk: visconti: Add support common clock driver and reset driver")
+Cc: stable@vger.kernel.org
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Acked-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Link: https://lore.kernel.org/r/57a831d94ee2b3889b11525d4ad500356f89576f.1697492890.git.gustavoars@kernel.org
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/visconti/pll.h | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/visconti/pll.h b/drivers/clk/visconti/pll.h
+index 01d07f1bf01b1..c4bd40676da4b 100644
+--- a/drivers/clk/visconti/pll.h
++++ b/drivers/clk/visconti/pll.h
+@@ -15,8 +15,10 @@
+
+ struct visconti_pll_provider {
+ void __iomem *reg_base;
+- struct clk_hw_onecell_data clk_data;
+ struct device_node *node;
++
++ /* Must be last */
++ struct clk_hw_onecell_data clk_data;
+ };
+
+ #define VISCONTI_PLL_RATE(_rate, _dacen, _dsmen, \
+--
+2.42.0
+
--- /dev/null
+From 1ad502d452f65c3edd6f537aeb53ce3f409c0abf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Mar 2023 21:50:28 +0100
+Subject: clk: visconti: remove unused visconti_pll_provider::regmap
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit 7e626a080bb2db47c27c29fea569ff18afec52ed ]
+
+Field regmap of struct visconti_pll_provider is never used. Remove it.
+
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+Link: https://lore.kernel.org/r/20230302205028.2539197-1-dario.binacchi@amarulasolutions.com
+Acked-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Stable-dep-of: 5ad1e217a2b2 ("clk: visconti: Fix undefined behavior bug in struct visconti_pll_provider")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/visconti/pll.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/clk/visconti/pll.h b/drivers/clk/visconti/pll.h
+index 16dae35ab3701..01d07f1bf01b1 100644
+--- a/drivers/clk/visconti/pll.h
++++ b/drivers/clk/visconti/pll.h
+@@ -15,7 +15,6 @@
+
+ struct visconti_pll_provider {
+ void __iomem *reg_base;
+- struct regmap *regmap;
+ struct clk_hw_onecell_data clk_data;
+ struct device_node *node;
+ };
+--
+2.42.0
+
--- /dev/null
+From 02c0c7a0de8de95e517f1205db7d534fd4b18066 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Oct 2023 20:30:14 +0200
+Subject: cpufreq: stats: Fix buffer overflow detection in trans_stats()
+
+From: Christian Marangi <ansuelsmth@gmail.com>
+
+[ Upstream commit ea167a7fc2426f7685c3735e104921c1a20a6d3f ]
+
+Commit 3c0897c180c6 ("cpufreq: Use scnprintf() for avoiding potential
+buffer overflow") switched from snprintf to the more secure scnprintf
+but never updated the exit condition for PAGE_SIZE.
+
+As the commit say and as scnprintf document, what scnprintf returns what
+is actually written not counting the '\0' end char. This results in the
+case of len exceeding the size, len set to PAGE_SIZE - 1, as it can be
+written at max PAGE_SIZE - 1 (as '\0' is not counted)
+
+Because of len is never set to PAGE_SIZE, the function never break early,
+never prints the warning and never return -EFBIG.
+
+Fix this by changing the condition to PAGE_SIZE - 1 to correctly trigger
+the error.
+
+Cc: 5.10+ <stable@vger.kernel.org> # 5.10+
+Fixes: 3c0897c180c6 ("cpufreq: Use scnprintf() for avoiding potential buffer overflow")
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+[ rjw: Subject and changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/cpufreq_stats.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
+index 1570d6f3e75d3..6e57df7a2249f 100644
+--- a/drivers/cpufreq/cpufreq_stats.c
++++ b/drivers/cpufreq/cpufreq_stats.c
+@@ -131,25 +131,25 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
+ len += scnprintf(buf + len, PAGE_SIZE - len, " From : To\n");
+ len += scnprintf(buf + len, PAGE_SIZE - len, " : ");
+ for (i = 0; i < stats->state_num; i++) {
+- if (len >= PAGE_SIZE)
++ if (len >= PAGE_SIZE - 1)
+ break;
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%9u ",
+ stats->freq_table[i]);
+ }
+- if (len >= PAGE_SIZE)
+- return PAGE_SIZE;
++ if (len >= PAGE_SIZE - 1)
++ return PAGE_SIZE - 1;
+
+ len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
+
+ for (i = 0; i < stats->state_num; i++) {
+- if (len >= PAGE_SIZE)
++ if (len >= PAGE_SIZE - 1)
+ break;
+
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%9u: ",
+ stats->freq_table[i]);
+
+ for (j = 0; j < stats->state_num; j++) {
+- if (len >= PAGE_SIZE)
++ if (len >= PAGE_SIZE - 1)
+ break;
+
+ if (pending)
+@@ -159,12 +159,12 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
+
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%9u ", count);
+ }
+- if (len >= PAGE_SIZE)
++ if (len >= PAGE_SIZE - 1)
+ break;
+ len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
+ }
+
+- if (len >= PAGE_SIZE) {
++ if (len >= PAGE_SIZE - 1) {
+ pr_warn_once("cpufreq transition table exceeds PAGE_SIZE. Disabling\n");
+ return -EFBIG;
+ }
+--
+2.42.0
+
--- /dev/null
+From e4747bff805ad18b4299d00e401a10575be90901 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Dec 2022 13:34:10 -0800
+Subject: cxl/mem: Move devm_cxl_add_endpoint() from cxl_core to cxl_mem
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 7592d935b7ae71e2b4ff93830743c39a9d13d113 ]
+
+tl;dr: Clean up an unnecessary export and enable cxl_test.
+
+An RCD (Restricted CXL Device), in contrast to a typical CXL device in
+a VH topology, obtains its component registers from the bottom half of
+the associated CXL host bridge RCRB (Root Complex Register Block). In
+turn this means that cxl_rcrb_to_component() needs to be called from
+devm_cxl_add_endpoint().
+
+Presently devm_cxl_add_endpoint() is part of the CXL core, but the only
+user is the CXL mem module. Move it from cxl_core to cxl_mem to not only
+get rid of an unnecessary export, but to also enable its call out to
+cxl_rcrb_to_component(), in a subsequent patch, to be mocked by
+cxl_test. Recall that cxl_test can only mock exported symbols, and since
+cxl_rcrb_to_component() is itself inside the core, all callers must be
+outside of cxl_core to allow cxl_test to mock it.
+
+Reviewed-by: Robert Richter <rrichter@amd.com>
+Link: https://lore.kernel.org/r/166993045072.1882361.13944923741276843683.stgit@dwillia2-xfh.jf.intel.com
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Stable-dep-of: 98a04c7aced2 ("cxl/region: Fix x1 root-decoder granularity calculations")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/core.h | 8 --------
+ drivers/cxl/core/port.c | 39 ---------------------------------------
+ drivers/cxl/cxl.h | 2 --
+ drivers/cxl/cxlmem.h | 9 +++++++++
+ drivers/cxl/mem.c | 38 ++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 47 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
+index 1d8f87be283fb..8c04672dca563 100644
+--- a/drivers/cxl/core/core.h
++++ b/drivers/cxl/core/core.h
+@@ -58,14 +58,6 @@ extern struct rw_semaphore cxl_dpa_rwsem;
+
+ bool is_switch_decoder(struct device *dev);
+ struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev);
+-static inline struct cxl_ep *cxl_ep_load(struct cxl_port *port,
+- struct cxl_memdev *cxlmd)
+-{
+- if (!port)
+- return NULL;
+-
+- return xa_load(&port->endpoints, (unsigned long)&cxlmd->dev);
+-}
+
+ int cxl_memdev_init(void);
+ void cxl_memdev_exit(void);
+diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
+index 93560d749aed8..585c2b43c7c7f 100644
+--- a/drivers/cxl/core/port.c
++++ b/drivers/cxl/core/port.c
+@@ -1151,45 +1151,6 @@ static void reap_dports(struct cxl_port *port)
+ }
+ }
+
+-int devm_cxl_add_endpoint(struct cxl_memdev *cxlmd,
+- struct cxl_dport *parent_dport)
+-{
+- struct cxl_port *parent_port = parent_dport->port;
+- struct cxl_dev_state *cxlds = cxlmd->cxlds;
+- struct cxl_port *endpoint, *iter, *down;
+- int rc;
+-
+- /*
+- * Now that the path to the root is established record all the
+- * intervening ports in the chain.
+- */
+- for (iter = parent_port, down = NULL; !is_cxl_root(iter);
+- down = iter, iter = to_cxl_port(iter->dev.parent)) {
+- struct cxl_ep *ep;
+-
+- ep = cxl_ep_load(iter, cxlmd);
+- ep->next = down;
+- }
+-
+- endpoint = devm_cxl_add_port(&parent_port->dev, &cxlmd->dev,
+- cxlds->component_reg_phys, parent_dport);
+- if (IS_ERR(endpoint))
+- return PTR_ERR(endpoint);
+-
+- rc = cxl_endpoint_autoremove(cxlmd, endpoint);
+- if (rc)
+- return rc;
+-
+- if (!endpoint->dev.driver) {
+- dev_err(&cxlmd->dev, "%s failed probe\n",
+- dev_name(&endpoint->dev));
+- return -ENXIO;
+- }
+-
+- return 0;
+-}
+-EXPORT_SYMBOL_NS_GPL(devm_cxl_add_endpoint, CXL);
+-
+ static void cxl_detach_ep(void *data)
+ {
+ struct cxl_memdev *cxlmd = data;
+diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
+index ac75554b5d763..8787ef1e64047 100644
+--- a/drivers/cxl/cxl.h
++++ b/drivers/cxl/cxl.h
+@@ -562,8 +562,6 @@ struct pci_bus *cxl_port_to_pci_bus(struct cxl_port *port);
+ struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport,
+ resource_size_t component_reg_phys,
+ struct cxl_dport *parent_dport);
+-int devm_cxl_add_endpoint(struct cxl_memdev *cxlmd,
+- struct cxl_dport *parent_dport);
+ struct cxl_port *find_cxl_root(struct device *dev);
+ int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd);
+ int cxl_bus_rescan(void);
+diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
+index 88e3a8e54b6a4..7e50b4e93ee53 100644
+--- a/drivers/cxl/cxlmem.h
++++ b/drivers/cxl/cxlmem.h
+@@ -76,6 +76,15 @@ static inline bool is_cxl_endpoint(struct cxl_port *port)
+
+ struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds);
+
++static inline struct cxl_ep *cxl_ep_load(struct cxl_port *port,
++ struct cxl_memdev *cxlmd)
++{
++ if (!port)
++ return NULL;
++
++ return xa_load(&port->endpoints, (unsigned long)&cxlmd->dev);
++}
++
+ /**
+ * struct cxl_mbox_cmd - A command to be submitted to hardware.
+ * @opcode: (input) The command set and command submitted to hardware.
+diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c
+index 64ccf053d32c3..80263d12a8541 100644
+--- a/drivers/cxl/mem.c
++++ b/drivers/cxl/mem.c
+@@ -45,6 +45,44 @@ static int cxl_mem_dpa_show(struct seq_file *file, void *data)
+ return 0;
+ }
+
++static int devm_cxl_add_endpoint(struct cxl_memdev *cxlmd,
++ struct cxl_dport *parent_dport)
++{
++ struct cxl_port *parent_port = parent_dport->port;
++ struct cxl_dev_state *cxlds = cxlmd->cxlds;
++ struct cxl_port *endpoint, *iter, *down;
++ int rc;
++
++ /*
++ * Now that the path to the root is established record all the
++ * intervening ports in the chain.
++ */
++ for (iter = parent_port, down = NULL; !is_cxl_root(iter);
++ down = iter, iter = to_cxl_port(iter->dev.parent)) {
++ struct cxl_ep *ep;
++
++ ep = cxl_ep_load(iter, cxlmd);
++ ep->next = down;
++ }
++
++ endpoint = devm_cxl_add_port(&parent_port->dev, &cxlmd->dev,
++ cxlds->component_reg_phys, parent_dport);
++ if (IS_ERR(endpoint))
++ return PTR_ERR(endpoint);
++
++ rc = cxl_endpoint_autoremove(cxlmd, endpoint);
++ if (rc)
++ return rc;
++
++ if (!endpoint->dev.driver) {
++ dev_err(&cxlmd->dev, "%s failed probe\n",
++ dev_name(&endpoint->dev));
++ return -ENXIO;
++ }
++
++ return 0;
++}
++
+ static int cxl_mem_probe(struct device *dev)
+ {
+ struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
+--
+2.42.0
+
--- /dev/null
+From 65f8fb7bee685e8ad3b815764a0f4d21afe736ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 01:06:09 -0800
+Subject: cxl/region: Cleanup target list on attach error
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 86987c766276acf1289700cd38bd6d5b5a167fea ]
+
+Jonathan noticed that the target list setup is not unwound completely
+upon error. Undo all the setup in the 'err_decrement:' exit path.
+
+Fixes: 27b3f8d13830 ("cxl/region: Program target lists")
+Reported-by: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
+Link: http://lore.kernel.org/r/20230208123031.00006990@Huawei.com
+Reviewed-by: Ira Weiny <ira.weiny@intel.com>
+Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Link: https://lore.kernel.org/r/167601996980.1924368.390423634911157277.stgit@dwillia2-xfh.jf.intel.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Stable-dep-of: 0718588c7aaa ("cxl/region: Do not try to cleanup after cxl_region_setup_targets() fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/region.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index 99b0501066e57..bd1c511bba987 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -1317,6 +1317,8 @@ static int cxl_region_attach(struct cxl_region *cxlr,
+
+ err_decrement:
+ p->nr_targets--;
++ cxled->pos = -1;
++ p->targets[pos] = NULL;
+ err:
+ for (iter = ep_port; !is_cxl_root(iter);
+ iter = to_cxl_port(iter->dev.parent))
+--
+2.42.0
+
--- /dev/null
+From 3cbb552d3805c480ab2374ced52a1a15bb99508d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Oct 2023 14:51:31 +0000
+Subject: cxl/region: Do not try to cleanup after cxl_region_setup_targets()
+ fails
+
+From: Jim Harris <jim.harris@samsung.com>
+
+[ Upstream commit 0718588c7aaa7a1510b4de972370535b61dddd0d ]
+
+Commit 5e42bcbc3fef ("cxl/region: decrement ->nr_targets on error in
+cxl_region_attach()") tried to avoid 'eiw' initialization errors when
+->nr_targets exceeded 16, by just decrementing ->nr_targets when
+cxl_region_setup_targets() failed.
+
+Commit 86987c766276 ("cxl/region: Cleanup target list on attach error")
+extended that cleanup to also clear cxled->pos and p->targets[pos]. The
+initialization error was incidentally fixed separately by:
+Commit 8d4285425714 ("cxl/region: Fix port setup uninitialized variable
+warnings") which was merged a few days after 5e42bcbc3fef.
+
+But now the original cleanup when cxl_region_setup_targets() fails
+prevents endpoint and switch decoder resources from being reused:
+
+1) the cleanup does not set the decoder's region to NULL, which results
+ in future dpa_size_store() calls returning -EBUSY
+2) the decoder is not properly freed, which results in future commit
+ errors associated with the upstream switch
+
+Now that the initialization errors were fixed separately, the proper
+cleanup for this case is to just return immediately. Then the resources
+associated with this target get cleanup up as normal when the failed
+region is deleted.
+
+The ->nr_targets decrement in the error case also helped prevent
+a p->targets[] array overflow, so add a new check to prevent against
+that overflow.
+
+Tested by trying to create an invalid region for a 2 switch * 2 endpoint
+topology, and then following up with creating a valid region.
+
+Fixes: 5e42bcbc3fef ("cxl/region: decrement ->nr_targets on error in cxl_region_attach()")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Jim Harris <jim.harris@samsung.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/169703589120.1202031.14696100866518083806.stgit@bgt-140510-bm03.eng.stellus.in
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/region.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index 1ee51327e989d..13b1b18612d3f 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -1291,6 +1291,12 @@ static int cxl_region_attach(struct cxl_region *cxlr,
+ return -ENXIO;
+ }
+
++ if (p->nr_targets >= p->interleave_ways) {
++ dev_dbg(&cxlr->dev, "region already has %d endpoints\n",
++ p->nr_targets);
++ return -EINVAL;
++ }
++
+ ep_port = cxled_to_port(cxled);
+ root_port = cxlrd_to_port(cxlrd);
+ dport = cxl_find_dport_by_dev(root_port, ep_port->host_bridge);
+@@ -1339,7 +1345,7 @@ static int cxl_region_attach(struct cxl_region *cxlr,
+ if (p->nr_targets == p->interleave_ways) {
+ rc = cxl_region_setup_targets(cxlr);
+ if (rc)
+- goto err_decrement;
++ return rc;
+ p->state = CXL_CONFIG_ACTIVE;
+ }
+
+@@ -1351,12 +1357,6 @@ static int cxl_region_attach(struct cxl_region *cxlr,
+ };
+
+ return 0;
+-
+-err_decrement:
+- p->nr_targets--;
+- cxled->pos = -1;
+- p->targets[pos] = NULL;
+- return rc;
+ }
+
+ static int cxl_region_detach(struct cxl_endpoint_decoder *cxled)
+--
+2.42.0
+
--- /dev/null
+From a9c60a18cd3de6bec517f69a115c971c9921bd1f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Oct 2023 10:09:06 -0700
+Subject: cxl/region: Fix x1 root-decoder granularity calculations
+
+From: Jim Harris <jim.harris@samsung.com>
+
+[ Upstream commit 98a04c7aced2b43b3ac4befe216c4eecc7257d4b ]
+
+Root decoder granularity must match value from CFWMS, which may not
+be the region's granularity for non-interleaved root decoders.
+
+So when calculating granularities for host bridge decoders, use the
+region's granularity instead of the root decoder's granularity to ensure
+the correct granularities are set for the host bridge decoders and any
+downstream switch decoders.
+
+Test configuration is 1 host bridge * 2 switches * 2 endpoints per switch.
+
+Region created with 2048 granularity using following command line:
+
+cxl create-region -m -d decoder0.0 -w 4 mem0 mem2 mem1 mem3 \
+ -g 2048 -s 2048M
+
+Use "cxl list -PDE | grep granularity" to get a view of the granularity
+set at each level of the topology.
+
+Before this patch:
+ "interleave_granularity":2048,
+ "interleave_granularity":2048,
+ "interleave_granularity":512,
+ "interleave_granularity":2048,
+ "interleave_granularity":2048,
+ "interleave_granularity":512,
+"interleave_granularity":256,
+
+After:
+ "interleave_granularity":2048,
+ "interleave_granularity":2048,
+ "interleave_granularity":4096,
+ "interleave_granularity":2048,
+ "interleave_granularity":2048,
+ "interleave_granularity":4096,
+"interleave_granularity":2048,
+
+Fixes: 27b3f8d13830 ("cxl/region: Program target lists")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Jim Harris <jim.harris@samsung.com>
+Link: https://lore.kernel.org/r/169824893473.1403938.16110924262989774582.stgit@bgt-140510-bm03.eng.stellus.in
+[djbw: fixup the prebuilt cxl_test region]
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/region.c | 9 ++++++++-
+ tools/testing/cxl/test/cxl.c | 2 +-
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index 13b1b18612d3f..ebc1b028555ca 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -1012,7 +1012,14 @@ static int cxl_port_setup_targets(struct cxl_port *port,
+ }
+
+ if (is_cxl_root(parent_port)) {
+- parent_ig = cxlrd->cxlsd.cxld.interleave_granularity;
++ /*
++ * Root decoder IG is always set to value in CFMWS which
++ * may be different than this region's IG. We can use the
++ * region's IG here since interleave_granularity_store()
++ * does not allow interleaved host-bridges with
++ * root IG != region IG.
++ */
++ parent_ig = p->interleave_granularity;
+ parent_iw = cxlrd->cxlsd.cxld.interleave_ways;
+ /*
+ * For purposes of address bit routing, use power-of-2 math for
+diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
+index c43bb6774f4db..339b31a3319bf 100644
+--- a/tools/testing/cxl/test/cxl.c
++++ b/tools/testing/cxl/test/cxl.c
+@@ -678,7 +678,7 @@ static void mock_init_hdm_decoder(struct cxl_decoder *cxld)
+ cxld->interleave_ways = 2;
+ else
+ cxld->interleave_ways = 1;
+- cxld->interleave_granularity = 256;
++ cxld->interleave_granularity = 4096;
+ cxld->hpa_range = (struct range) {
+ .start = base,
+ .end = base + size - 1,
+--
+2.42.0
+
--- /dev/null
+From d5f43e52214eeed453a55092d152719353d6b82d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 01:06:15 -0800
+Subject: cxl/region: Move region-position validation to a helper
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 9995576cef48dcbb0ba3de068292ed14f72fa0eb ]
+
+In preparation for region autodiscovery, that needs all devices
+discovered before their relative position in the region can be
+determined, consolidate all position dependent validation in a helper.
+
+Recall that in the on-demand region creation flow the end-user picks the
+position of a given endpoint decoder in a region. In the autodiscovery
+case the position of an endpoint decoder can only be determined after
+all other endpoint decoders that claim to decode the region's address
+range have been enumerated and attached. So, in the autodiscovery case
+endpoint decoders may be attached before their relative position is
+known. Once all decoders arrive, then positions can be determined and
+validated with cxl_region_validate_position() the same as user initiated
+on-demand creation.
+
+Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
+Tested-by: Fan Ni <fan.ni@samsung.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Link: https://lore.kernel.org/r/167601997584.1924368.4615769326126138969.stgit@dwillia2-xfh.jf.intel.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Stable-dep-of: 0718588c7aaa ("cxl/region: Do not try to cleanup after cxl_region_setup_targets() fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/region.c | 119 ++++++++++++++++++++++++--------------
+ 1 file changed, 76 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index bd1c511bba987..1ee51327e989d 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -1181,35 +1181,13 @@ static int cxl_region_setup_targets(struct cxl_region *cxlr)
+ return 0;
+ }
+
+-static int cxl_region_attach(struct cxl_region *cxlr,
+- struct cxl_endpoint_decoder *cxled, int pos)
++static int cxl_region_validate_position(struct cxl_region *cxlr,
++ struct cxl_endpoint_decoder *cxled,
++ int pos)
+ {
+- struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
+ struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
+- struct cxl_port *ep_port, *root_port, *iter;
+ struct cxl_region_params *p = &cxlr->params;
+- struct cxl_dport *dport;
+- int i, rc = -ENXIO;
+-
+- if (cxled->mode != cxlr->mode) {
+- dev_dbg(&cxlr->dev, "%s region mode: %d mismatch: %d\n",
+- dev_name(&cxled->cxld.dev), cxlr->mode, cxled->mode);
+- return -EINVAL;
+- }
+-
+- if (cxled->mode == CXL_DECODER_DEAD) {
+- dev_dbg(&cxlr->dev, "%s dead\n", dev_name(&cxled->cxld.dev));
+- return -ENODEV;
+- }
+-
+- /* all full of members, or interleave config not established? */
+- if (p->state > CXL_CONFIG_INTERLEAVE_ACTIVE) {
+- dev_dbg(&cxlr->dev, "region already active\n");
+- return -EBUSY;
+- } else if (p->state < CXL_CONFIG_INTERLEAVE_ACTIVE) {
+- dev_dbg(&cxlr->dev, "interleave config missing\n");
+- return -ENXIO;
+- }
++ int i;
+
+ if (pos < 0 || pos >= p->interleave_ways) {
+ dev_dbg(&cxlr->dev, "position %d out of range %d\n", pos,
+@@ -1248,6 +1226,71 @@ static int cxl_region_attach(struct cxl_region *cxlr,
+ }
+ }
+
++ return 0;
++}
++
++static int cxl_region_attach_position(struct cxl_region *cxlr,
++ struct cxl_root_decoder *cxlrd,
++ struct cxl_endpoint_decoder *cxled,
++ const struct cxl_dport *dport, int pos)
++{
++ struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
++ struct cxl_port *iter;
++ int rc;
++
++ if (cxlrd->calc_hb(cxlrd, pos) != dport) {
++ dev_dbg(&cxlr->dev, "%s:%s invalid target position for %s\n",
++ dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
++ dev_name(&cxlrd->cxlsd.cxld.dev));
++ return -ENXIO;
++ }
++
++ for (iter = cxled_to_port(cxled); !is_cxl_root(iter);
++ iter = to_cxl_port(iter->dev.parent)) {
++ rc = cxl_port_attach_region(iter, cxlr, cxled, pos);
++ if (rc)
++ goto err;
++ }
++
++ return 0;
++
++err:
++ for (iter = cxled_to_port(cxled); !is_cxl_root(iter);
++ iter = to_cxl_port(iter->dev.parent))
++ cxl_port_detach_region(iter, cxlr, cxled);
++ return rc;
++}
++
++static int cxl_region_attach(struct cxl_region *cxlr,
++ struct cxl_endpoint_decoder *cxled, int pos)
++{
++ struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
++ struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
++ struct cxl_region_params *p = &cxlr->params;
++ struct cxl_port *ep_port, *root_port;
++ struct cxl_dport *dport;
++ int rc = -ENXIO;
++
++ if (cxled->mode != cxlr->mode) {
++ dev_dbg(&cxlr->dev, "%s region mode: %d mismatch: %d\n",
++ dev_name(&cxled->cxld.dev), cxlr->mode, cxled->mode);
++ return -EINVAL;
++ }
++
++ if (cxled->mode == CXL_DECODER_DEAD) {
++ dev_dbg(&cxlr->dev, "%s dead\n", dev_name(&cxled->cxld.dev));
++ return -ENODEV;
++ }
++
++ /* all full of members, or interleave config not established? */
++ if (p->state > CXL_CONFIG_INTERLEAVE_ACTIVE) {
++ dev_dbg(&cxlr->dev, "region already active\n");
++ return -EBUSY;
++ } else if (p->state < CXL_CONFIG_INTERLEAVE_ACTIVE) {
++ dev_dbg(&cxlr->dev, "interleave config missing\n");
++ return -ENXIO;
++ }
++
+ ep_port = cxled_to_port(cxled);
+ root_port = cxlrd_to_port(cxlrd);
+ dport = cxl_find_dport_by_dev(root_port, ep_port->host_bridge);
+@@ -1258,13 +1301,6 @@ static int cxl_region_attach(struct cxl_region *cxlr,
+ return -ENXIO;
+ }
+
+- if (cxlrd->calc_hb(cxlrd, pos) != dport) {
+- dev_dbg(&cxlr->dev, "%s:%s invalid target position for %s\n",
+- dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
+- dev_name(&cxlrd->cxlsd.cxld.dev));
+- return -ENXIO;
+- }
+-
+ if (cxled->cxld.target_type != cxlr->type) {
+ dev_dbg(&cxlr->dev, "%s:%s type mismatch: %d vs %d\n",
+ dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
+@@ -1288,12 +1324,13 @@ static int cxl_region_attach(struct cxl_region *cxlr,
+ return -EINVAL;
+ }
+
+- for (iter = ep_port; !is_cxl_root(iter);
+- iter = to_cxl_port(iter->dev.parent)) {
+- rc = cxl_port_attach_region(iter, cxlr, cxled, pos);
+- if (rc)
+- goto err;
+- }
++ rc = cxl_region_validate_position(cxlr, cxled, pos);
++ if (rc)
++ return rc;
++
++ rc = cxl_region_attach_position(cxlr, cxlrd, cxled, dport, pos);
++ if (rc)
++ return rc;
+
+ p->targets[pos] = cxled;
+ cxled->pos = pos;
+@@ -1319,10 +1356,6 @@ static int cxl_region_attach(struct cxl_region *cxlr,
+ p->nr_targets--;
+ cxled->pos = -1;
+ p->targets[pos] = NULL;
+-err:
+- for (iter = ep_port; !is_cxl_root(iter);
+- iter = to_cxl_port(iter->dev.parent))
+- cxl_port_detach_region(iter, cxlr, cxled);
+ return rc;
+ }
+
+--
+2.42.0
+
--- /dev/null
+From ba9a4413d32bf5aea2c2bc68afa556fc18087a22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 01:05:51 -0800
+Subject: cxl/region: Validate region mode vs decoder mode
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 1b9b7a6fd618239db47a83da39dff9e725a5865a ]
+
+In preparation for a new region mode, do not, for example, allow
+'ram' decoders to be assigned to 'pmem' regions and vice versa.
+
+Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
+Reviewed-by: Gregory Price <gregory.price@memverge.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Ira Weiny <ira.weiny@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Tested-by: Fan Ni <fan.ni@samsung.com>
+Link: https://lore.kernel.org/r/167601995111.1924368.7459128614177994602.stgit@dwillia2-xfh.jf.intel.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Stable-dep-of: 0718588c7aaa ("cxl/region: Do not try to cleanup after cxl_region_setup_targets() fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/region.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index 9709bbf773b72..99b0501066e57 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -1191,6 +1191,12 @@ static int cxl_region_attach(struct cxl_region *cxlr,
+ struct cxl_dport *dport;
+ int i, rc = -ENXIO;
+
++ if (cxled->mode != cxlr->mode) {
++ dev_dbg(&cxlr->dev, "%s region mode: %d mismatch: %d\n",
++ dev_name(&cxled->cxld.dev), cxlr->mode, cxled->mode);
++ return -EINVAL;
++ }
++
+ if (cxled->mode == CXL_DECODER_DEAD) {
+ dev_dbg(&cxlr->dev, "%s dead\n", dev_name(&cxled->cxld.dev));
+ return -ENODEV;
+--
+2.42.0
+
--- /dev/null
+From fccc1b689b62ff0ee2913aa64baea44d40105923 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 15:23:31 +0200
+Subject: cxl: Unify debug messages when calling devm_cxl_add_port()
+
+From: Robert Richter <rrichter@amd.com>
+
+[ Upstream commit f3cd264c4ec1ab9b8918f3b083cfc13c5e7c26b7 ]
+
+CXL ports are added in a couple of code paths using devm_cxl_add_port().
+Debug messages are individually generated, but are incomplete and
+inconsistent. Change this by moving its generation to
+devm_cxl_add_port(). This unifies the messages and reduces code
+duplication. Also, generate messages on failure. Use a
+__devm_cxl_add_port() wrapper to keep the readability of the error
+exits.
+
+Signed-off-by: Robert Richter <rrichter@amd.com>
+Link: https://lore.kernel.org/r/20221018132341.76259-4-rrichter@amd.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Stable-dep-of: 98a04c7aced2 ("cxl/region: Fix x1 root-decoder granularity calculations")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/acpi.c | 2 --
+ drivers/cxl/core/port.c | 51 +++++++++++++++++++++++++++++++----------
+ 2 files changed, 39 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
+index 07b184382707e..dd610556a3afa 100644
+--- a/drivers/cxl/acpi.c
++++ b/drivers/cxl/acpi.c
+@@ -219,7 +219,6 @@ static int add_host_bridge_uport(struct device *match, void *arg)
+ port = devm_cxl_add_port(host, match, dport->component_reg_phys, dport);
+ if (IS_ERR(port))
+ return PTR_ERR(port);
+- dev_dbg(host, "%s: add: %s\n", dev_name(match), dev_name(&port->dev));
+
+ return 0;
+ }
+@@ -465,7 +464,6 @@ static int cxl_acpi_probe(struct platform_device *pdev)
+ root_port = devm_cxl_add_port(host, host, CXL_RESOURCE_NONE, NULL);
+ if (IS_ERR(root_port))
+ return PTR_ERR(root_port);
+- dev_dbg(host, "add: %s\n", dev_name(&root_port->dev));
+
+ rc = bus_for_each_dev(adev->dev.bus, NULL, root_port,
+ add_host_bridge_dport);
+diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
+index e7556864ea808..93560d749aed8 100644
+--- a/drivers/cxl/core/port.c
++++ b/drivers/cxl/core/port.c
+@@ -655,16 +655,10 @@ static struct cxl_port *cxl_port_alloc(struct device *uport,
+ return ERR_PTR(rc);
+ }
+
+-/**
+- * devm_cxl_add_port - register a cxl_port in CXL memory decode hierarchy
+- * @host: host device for devm operations
+- * @uport: "physical" device implementing this upstream port
+- * @component_reg_phys: (optional) for configurable cxl_port instances
+- * @parent_dport: next hop up in the CXL memory decode hierarchy
+- */
+-struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport,
+- resource_size_t component_reg_phys,
+- struct cxl_dport *parent_dport)
++static struct cxl_port *__devm_cxl_add_port(struct device *host,
++ struct device *uport,
++ resource_size_t component_reg_phys,
++ struct cxl_dport *parent_dport)
+ {
+ struct cxl_port *port;
+ struct device *dev;
+@@ -702,6 +696,41 @@ struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport,
+ put_device(dev);
+ return ERR_PTR(rc);
+ }
++
++/**
++ * devm_cxl_add_port - register a cxl_port in CXL memory decode hierarchy
++ * @host: host device for devm operations
++ * @uport: "physical" device implementing this upstream port
++ * @component_reg_phys: (optional) for configurable cxl_port instances
++ * @parent_dport: next hop up in the CXL memory decode hierarchy
++ */
++struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport,
++ resource_size_t component_reg_phys,
++ struct cxl_dport *parent_dport)
++{
++ struct cxl_port *port, *parent_port;
++
++ port = __devm_cxl_add_port(host, uport, component_reg_phys,
++ parent_dport);
++
++ parent_port = parent_dport ? parent_dport->port : NULL;
++ if (IS_ERR(port)) {
++ dev_dbg(uport, "Failed to add %s%s%s%s: %ld\n",
++ dev_name(&port->dev),
++ parent_port ? " to " : "",
++ parent_port ? dev_name(&parent_port->dev) : "",
++ parent_port ? "" : " (root port)",
++ PTR_ERR(port));
++ } else {
++ dev_dbg(uport, "%s added%s%s%s\n",
++ dev_name(&port->dev),
++ parent_port ? " to " : "",
++ parent_port ? dev_name(&parent_port->dev) : "",
++ parent_port ? "" : " (root port)");
++ }
++
++ return port;
++}
+ EXPORT_SYMBOL_NS_GPL(devm_cxl_add_port, CXL);
+
+ struct pci_bus *cxl_port_to_pci_bus(struct cxl_port *port)
+@@ -1147,8 +1176,6 @@ int devm_cxl_add_endpoint(struct cxl_memdev *cxlmd,
+ if (IS_ERR(endpoint))
+ return PTR_ERR(endpoint);
+
+- dev_dbg(&cxlmd->dev, "add: %s\n", dev_name(&endpoint->dev));
+-
+ rc = cxl_endpoint_autoremove(cxlmd, endpoint);
+ if (rc)
+ return rc;
+--
+2.42.0
+
--- /dev/null
+From f2476cbcc1385302c3987054d0f50a3c6de49393 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Sep 2023 16:52:54 -0400
+Subject: drm/amd/display: enable dsc_clk even if dsc_pg disabled
+
+From: Muhammad Ahmed <ahmed.ahmed@amd.com>
+
+[ Upstream commit 40255df370e94d44f0f0a924400d68db0ee31bec ]
+
+[why]
+need to enable dsc_clk regardless dsc_pg
+
+Reviewed-by: Charlene Liu <charlene.liu@amd.com>
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Signed-off-by: Muhammad Ahmed <ahmed.ahmed@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 8 ++++----
+ drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 3 +++
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 9d321f4f486e2..7a309547c2b3f 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -1806,7 +1806,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
+ if (dc->hwss.subvp_pipe_control_lock)
+ dc->hwss.subvp_pipe_control_lock(dc, context, true, true, NULL, subvp_prev_use);
+
+- if (dc->debug.enable_double_buffered_dsc_pg_support)
++ if (dc->hwss.update_dsc_pg)
+ dc->hwss.update_dsc_pg(dc, context, false);
+
+ disable_dangling_plane(dc, context);
+@@ -1905,7 +1905,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
+ dc->hwss.optimize_bandwidth(dc, context);
+ }
+
+- if (dc->debug.enable_double_buffered_dsc_pg_support)
++ if (dc->hwss.update_dsc_pg)
+ dc->hwss.update_dsc_pg(dc, context, true);
+
+ if (dc->ctx->dce_version >= DCE_VERSION_MAX)
+@@ -2193,7 +2193,7 @@ void dc_post_update_surfaces_to_stream(struct dc *dc)
+
+ dc->hwss.optimize_bandwidth(dc, context);
+
+- if (dc->debug.enable_double_buffered_dsc_pg_support)
++ if (dc->hwss.update_dsc_pg)
+ dc->hwss.update_dsc_pg(dc, context, true);
+ }
+
+@@ -3453,7 +3453,7 @@ static void commit_planes_for_stream(struct dc *dc,
+ if (get_seamless_boot_stream_count(context) == 0)
+ dc->hwss.prepare_bandwidth(dc, context);
+
+- if (dc->debug.enable_double_buffered_dsc_pg_support)
++ if (dc->hwss.update_dsc_pg)
+ dc->hwss.update_dsc_pg(dc, context, false);
+
+ context_clock_trace(dc, context);
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+index d477dcc9149fa..50b3547977281 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -79,6 +79,9 @@ void dcn32_dsc_pg_control(
+ if (hws->ctx->dc->debug.disable_dsc_power_gate)
+ return;
+
++ if (!hws->ctx->dc->debug.enable_double_buffered_dsc_pg_support)
++ return;
++
+ REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+ if (org_ip_request_cntl == 0)
+ REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+--
+2.42.0
+
--- /dev/null
+From 63edfd1abeecaa4b7901057c36ff7aeb65698316 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 11:30:30 +0800
+Subject: i3c: master: svc: add NACK check after start byte sent
+
+From: Clark Wang <xiaoning.wang@nxp.com>
+
+[ Upstream commit 49b472ebc61de3d4aa7cc57539246bb39f6c5128 ]
+
+Add NACK check after start byte is sent.
+It is possible to detect early that a device is not on the bus
+and avoid invalid transmissions thereafter.
+
+Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/r/20230517033030.3068085-3-xiaoning.wang@nxp.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Stable-dep-of: 9aaeef113c55 ("i3c: master: svc: fix random hot join failure since timeout error")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i3c/master/svc-i3c-master.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c
+index 0454f16ac9aae..0263f30bae82e 100644
+--- a/drivers/i3c/master/svc-i3c-master.c
++++ b/drivers/i3c/master/svc-i3c-master.c
+@@ -92,6 +92,7 @@
+ #define SVC_I3C_MINTCLR 0x094
+ #define SVC_I3C_MINTMASKED 0x098
+ #define SVC_I3C_MERRWARN 0x09C
++#define SVC_I3C_MERRWARN_NACK BIT(2)
+ #define SVC_I3C_MDMACTRL 0x0A0
+ #define SVC_I3C_MDATACTRL 0x0AC
+ #define SVC_I3C_MDATACTRL_FLUSHTB BIT(0)
+@@ -1028,6 +1029,11 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master,
+ if (ret)
+ goto emit_stop;
+
++ if (readl(master->regs + SVC_I3C_MERRWARN) & SVC_I3C_MERRWARN_NACK) {
++ ret = -ENXIO;
++ goto emit_stop;
++ }
++
+ if (rnw)
+ ret = svc_i3c_master_read(master, in, xfer_len);
+ else
+--
+2.42.0
+
--- /dev/null
+From 1648a5fbcd16276d890a1c6e72bd7223cb0efdf5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Oct 2023 12:16:58 -0400
+Subject: i3c: master: svc: fix random hot join failure since timeout error
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Frank Li <Frank.Li@nxp.com>
+
+[ Upstream commit 9aaeef113c55248ecf3ab941c2e4460aaa8b8b9a ]
+
+master side report:
+ silvaco-i3c-master 44330000.i3c-master: Error condition: MSTATUS 0x020090c7, MERRWARN 0x00100000
+
+BIT 20: TIMEOUT error
+ The module has stalled too long in a frame. This happens when:
+ - The TX FIFO or RX FIFO is not handled and the bus is stuck in the
+middle of a message,
+ - No STOP was issued and between messages,
+ - IBI manual is used and no decision was made.
+ The maximum stall period is 100 μs.
+
+This can be considered as being just a warning as the system IRQ latency
+can easily be greater than 100us.
+
+Fixes: dd3c52846d59 ("i3c: master: svc: Add Silvaco I3C master driver")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/r/20231023161658.3890811-7-Frank.Li@nxp.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i3c/master/svc-i3c-master.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c
+index 0263f30bae82e..f30d457e91196 100644
+--- a/drivers/i3c/master/svc-i3c-master.c
++++ b/drivers/i3c/master/svc-i3c-master.c
+@@ -93,6 +93,7 @@
+ #define SVC_I3C_MINTMASKED 0x098
+ #define SVC_I3C_MERRWARN 0x09C
+ #define SVC_I3C_MERRWARN_NACK BIT(2)
++#define SVC_I3C_MERRWARN_TIMEOUT BIT(20)
+ #define SVC_I3C_MDMACTRL 0x0A0
+ #define SVC_I3C_MDATACTRL 0x0AC
+ #define SVC_I3C_MDATACTRL_FLUSHTB BIT(0)
+@@ -220,6 +221,14 @@ static bool svc_i3c_master_error(struct svc_i3c_master *master)
+ if (SVC_I3C_MSTATUS_ERRWARN(mstatus)) {
+ merrwarn = readl(master->regs + SVC_I3C_MERRWARN);
+ writel(merrwarn, master->regs + SVC_I3C_MERRWARN);
++
++ /* Ignore timeout error */
++ if (merrwarn & SVC_I3C_MERRWARN_TIMEOUT) {
++ dev_dbg(master->dev, "Warning condition: MSTATUS 0x%08x, MERRWARN 0x%08x\n",
++ mstatus, merrwarn);
++ return false;
++ }
++
+ dev_err(master->dev,
+ "Error condition: MSTATUS 0x%08x, MERRWARN 0x%08x\n",
+ mstatus, merrwarn);
+--
+2.42.0
+
--- /dev/null
+From cda6fd052ede0ea69052de9a246c166ff5e953e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Oct 2023 07:10:40 -0300
+Subject: pmdomain: bcm: bcm2835-power: check if the ASB register is equal to
+ enable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maíra Canal <mcanal@igalia.com>
+
+[ Upstream commit 2e75396f1df61e1f1d26d0d703fc7292c4ae4371 ]
+
+The commit c494a447c14e ("soc: bcm: bcm2835-power: Refactor ASB control")
+refactored the ASB control by using a general function to handle both
+the enable and disable. But this patch introduced a subtle regression:
+we need to check if !!(readl(base + reg) & ASB_ACK) == enable, not just
+check if (readl(base + reg) & ASB_ACK) == true.
+
+Currently, this is causing an invalid register state in V3D when
+unloading and loading the driver, because `bcm2835_asb_disable()` will
+return -ETIMEDOUT and `bcm2835_asb_power_off()` will fail to disable the
+ASB slave for V3D.
+
+Fixes: c494a447c14e ("soc: bcm: bcm2835-power: Refactor ASB control")
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Reviewed-by: Stefan Wahren <stefan.wahren@i2se.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20231024101251.6357-2-mcanal@igalia.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/bcm/bcm2835-power.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/soc/bcm/bcm2835-power.c b/drivers/soc/bcm/bcm2835-power.c
+index 5bcd047768b60..cbcd1298ef5bd 100644
+--- a/drivers/soc/bcm/bcm2835-power.c
++++ b/drivers/soc/bcm/bcm2835-power.c
+@@ -175,7 +175,7 @@ static int bcm2835_asb_control(struct bcm2835_power *power, u32 reg, bool enable
+ }
+ writel(PM_PASSWORD | val, base + reg);
+
+- while (readl(base + reg) & ASB_ACK) {
++ while (!!(readl(base + reg) & ASB_ACK) == enable) {
+ cpu_relax();
+ if (ktime_get_ns() - start >= 1000)
+ return -ETIMEDOUT;
+--
+2.42.0
+
--- /dev/null
+From 47d327f6abdab52c7b7c0d420704c4b948d9d84f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 Oct 2023 02:59:49 +0800
+Subject: pmdomain: imx: Make imx pgc power domain also set the fwnode
+
+From: Pengfei Li <pengfei.li_1@nxp.com>
+
+[ Upstream commit 374de39d38f97b0e58cfee88da590b2d056ccf7f ]
+
+Currently, The imx pgc power domain doesn't set the fwnode
+pointer, which results in supply regulator device can't get
+consumer imx pgc power domain device from fwnode when creating
+a link.
+
+This causes the driver core to instead try to create a link
+between the parent gpc device of imx pgc power domain device and
+supply regulator device. However, at this point, the gpc device
+has already been bound, and the link creation will fail. So adding
+the fwnode pointer to the imx pgc power domain device will fix
+this issue.
+
+Signed-off-by: Pengfei Li <pengfei.li_1@nxp.com>
+Tested-by: Emil Kronborg <emil.kronborg@protonmail.com>
+Fixes: 3fb16866b51d ("driver core: fw_devlink: Make cycle detection more robust")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20231020185949.537083-1-pengfei.li_1@nxp.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/imx/gpc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/soc/imx/gpc.c b/drivers/soc/imx/gpc.c
+index 90a8b2c0676ff..419ed15cc10c4 100644
+--- a/drivers/soc/imx/gpc.c
++++ b/drivers/soc/imx/gpc.c
+@@ -498,6 +498,7 @@ static int imx_gpc_probe(struct platform_device *pdev)
+
+ pd_pdev->dev.parent = &pdev->dev;
+ pd_pdev->dev.of_node = np;
++ pd_pdev->dev.fwnode = of_fwnode_handle(np);
+
+ ret = platform_device_add(pd_pdev);
+ if (ret) {
+--
+2.42.0
+
i3c-master-svc-fix-ibi-may-not-return-mandatory-data-byte.patch
i3c-master-svc-fix-check-wrong-status-register-in-irq-handler.patch
i3c-master-svc-fix-sda-keep-low-when-polling-ibiwon-timeout-happen.patch
+pmdomain-bcm-bcm2835-power-check-if-the-asb-register.patch
+pmdomain-imx-make-imx-pgc-power-domain-also-set-the-.patch
+cpufreq-stats-fix-buffer-overflow-detection-in-trans.patch
+clk-visconti-remove-unused-visconti_pll_provider-reg.patch
+clk-visconti-fix-undefined-behavior-bug-in-struct-vi.patch
+bluetooth-btusb-add-realtek-rtl8852be-support-id-0x0.patch
+bluetooth-add-device-0bda-887b-to-device-tables.patch
+bluetooth-add-device-13d3-3571-to-device-tables.patch
+bluetooth-btusb-add-rtw8852be-device-13d3-3570-to-de.patch
+bluetooth-btusb-add-0bda-b85b-for-fn-link-rtl8852be.patch
+drm-amd-display-enable-dsc_clk-even-if-dsc_pg-disabl.patch
+cxl-region-validate-region-mode-vs-decoder-mode.patch
+cxl-region-cleanup-target-list-on-attach-error.patch
+cxl-region-move-region-position-validation-to-a-help.patch
+cxl-region-do-not-try-to-cleanup-after-cxl_region_se.patch
+i3c-master-svc-add-nack-check-after-start-byte-sent.patch
+i3c-master-svc-fix-random-hot-join-failure-since-tim.patch
+cxl-unify-debug-messages-when-calling-devm_cxl_add_p.patch
+cxl-mem-move-devm_cxl_add_endpoint-from-cxl_core-to-.patch
+tools-testing-cxl-define-a-fixed-volatile-configurat.patch
+cxl-region-fix-x1-root-decoder-granularity-calculati.patch
--- /dev/null
+From 01eec3c2fbc05a87f8d45735b37dada25a77aa8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Feb 2023 01:06:45 -0800
+Subject: tools/testing/cxl: Define a fixed volatile configuration to parse
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 3d8f7ccaa611a743ae3a1e6f605346993d37c513 ]
+
+Take two endpoints attached to the first switch on the first host-bridge
+in the cxl_test topology and define a pre-initialized region. This is a
+x2 interleave underneath a x1 CXL Window.
+
+$ modprobe cxl_test
+$ # cxl list -Ru
+{
+ "region":"region3",
+ "resource":"0xf010000000",
+ "size":"512.00 MiB (536.87 MB)",
+ "interleave_ways":2,
+ "interleave_granularity":4096,
+ "decode_state":"commit"
+}
+
+Tested-by: Fan Ni <fan.ni@samsung.com>
+Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Link: https://lore.kernel.org/r/167602000547.1924368.11613151863880268868.stgit@dwillia2-xfh.jf.intel.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Stable-dep-of: 98a04c7aced2 ("cxl/region: Fix x1 root-decoder granularity calculations")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/core.h | 3 -
+ drivers/cxl/core/hdm.c | 3 +-
+ drivers/cxl/core/port.c | 2 +
+ drivers/cxl/cxl.h | 2 +
+ drivers/cxl/cxlmem.h | 3 +
+ tools/testing/cxl/test/cxl.c | 147 ++++++++++++++++++++++++++++++++---
+ 6 files changed, 146 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
+index 8c04672dca563..cbee2340f1bce 100644
+--- a/drivers/cxl/core/core.h
++++ b/drivers/cxl/core/core.h
+@@ -56,9 +56,6 @@ resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled);
+ resource_size_t cxl_dpa_resource_start(struct cxl_endpoint_decoder *cxled);
+ extern struct rw_semaphore cxl_dpa_rwsem;
+
+-bool is_switch_decoder(struct device *dev);
+-struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev);
+-
+ int cxl_memdev_init(void);
+ void cxl_memdev_exit(void);
+ void cxl_mbox_init(void);
+diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
+index 5aa0726aafe6f..8c1db4e1b816d 100644
+--- a/drivers/cxl/core/hdm.c
++++ b/drivers/cxl/core/hdm.c
+@@ -276,7 +276,7 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
+ return 0;
+ }
+
+-static int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
++int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
+ resource_size_t base, resource_size_t len,
+ resource_size_t skipped)
+ {
+@@ -292,6 +292,7 @@ static int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
+
+ return devm_add_action_or_reset(&port->dev, cxl_dpa_release, cxled);
+ }
++EXPORT_SYMBOL_NS_GPL(devm_cxl_dpa_reserve, CXL);
+
+ resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled)
+ {
+diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
+index 585c2b43c7c7f..9de8336d76379 100644
+--- a/drivers/cxl/core/port.c
++++ b/drivers/cxl/core/port.c
+@@ -455,6 +455,7 @@ bool is_switch_decoder(struct device *dev)
+ {
+ return is_root_decoder(dev) || dev->type == &cxl_decoder_switch_type;
+ }
++EXPORT_SYMBOL_NS_GPL(is_switch_decoder, CXL);
+
+ struct cxl_decoder *to_cxl_decoder(struct device *dev)
+ {
+@@ -482,6 +483,7 @@ struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev)
+ return NULL;
+ return container_of(dev, struct cxl_switch_decoder, cxld.dev);
+ }
++EXPORT_SYMBOL_NS_GPL(to_cxl_switch_decoder, CXL);
+
+ static void cxl_ep_release(struct cxl_ep *ep)
+ {
+diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
+index 8787ef1e64047..7750ccb7652db 100644
+--- a/drivers/cxl/cxl.h
++++ b/drivers/cxl/cxl.h
+@@ -575,8 +575,10 @@ struct cxl_dport *devm_cxl_add_dport(struct cxl_port *port,
+
+ struct cxl_decoder *to_cxl_decoder(struct device *dev);
+ struct cxl_root_decoder *to_cxl_root_decoder(struct device *dev);
++struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev);
+ struct cxl_endpoint_decoder *to_cxl_endpoint_decoder(struct device *dev);
+ bool is_root_decoder(struct device *dev);
++bool is_switch_decoder(struct device *dev);
+ bool is_endpoint_decoder(struct device *dev);
+ struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
+ unsigned int nr_targets);
+diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
+index 7e50b4e93ee53..b58a5b782e5dc 100644
+--- a/drivers/cxl/cxlmem.h
++++ b/drivers/cxl/cxlmem.h
+@@ -75,6 +75,9 @@ static inline bool is_cxl_endpoint(struct cxl_port *port)
+ }
+
+ struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds);
++int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
++ resource_size_t base, resource_size_t len,
++ resource_size_t skipped);
+
+ static inline struct cxl_ep *cxl_ep_load(struct cxl_port *port,
+ struct cxl_memdev *cxlmd)
+diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
+index 7edce12fd2ce5..c43bb6774f4db 100644
+--- a/tools/testing/cxl/test/cxl.c
++++ b/tools/testing/cxl/test/cxl.c
+@@ -551,6 +551,142 @@ static int mock_decoder_reset(struct cxl_decoder *cxld)
+ return 0;
+ }
+
++static void default_mock_decoder(struct cxl_decoder *cxld)
++{
++ cxld->hpa_range = (struct range){
++ .start = 0,
++ .end = -1,
++ };
++
++ cxld->interleave_ways = 1;
++ cxld->interleave_granularity = 256;
++ cxld->target_type = CXL_DECODER_EXPANDER;
++ cxld->commit = mock_decoder_commit;
++ cxld->reset = mock_decoder_reset;
++}
++
++static int first_decoder(struct device *dev, void *data)
++{
++ struct cxl_decoder *cxld;
++
++ if (!is_switch_decoder(dev))
++ return 0;
++ cxld = to_cxl_decoder(dev);
++ if (cxld->id == 0)
++ return 1;
++ return 0;
++}
++
++static void mock_init_hdm_decoder(struct cxl_decoder *cxld)
++{
++ struct acpi_cedt_cfmws *window = mock_cfmws[0];
++ struct platform_device *pdev = NULL;
++ struct cxl_endpoint_decoder *cxled;
++ struct cxl_switch_decoder *cxlsd;
++ struct cxl_port *port, *iter;
++ const int size = SZ_512M;
++ struct cxl_memdev *cxlmd;
++ struct cxl_dport *dport;
++ struct device *dev;
++ bool hb0 = false;
++ u64 base;
++ int i;
++
++ if (is_endpoint_decoder(&cxld->dev)) {
++ cxled = to_cxl_endpoint_decoder(&cxld->dev);
++ cxlmd = cxled_to_memdev(cxled);
++ WARN_ON(!dev_is_platform(cxlmd->dev.parent));
++ pdev = to_platform_device(cxlmd->dev.parent);
++
++ /* check is endpoint is attach to host-bridge0 */
++ port = cxled_to_port(cxled);
++ do {
++ if (port->uport == &cxl_host_bridge[0]->dev) {
++ hb0 = true;
++ break;
++ }
++ if (is_cxl_port(port->dev.parent))
++ port = to_cxl_port(port->dev.parent);
++ else
++ port = NULL;
++ } while (port);
++ port = cxled_to_port(cxled);
++ }
++
++ /*
++ * The first decoder on the first 2 devices on the first switch
++ * attached to host-bridge0 mock a fake / static RAM region. All
++ * other decoders are default disabled. Given the round robin
++ * assignment those devices are named cxl_mem.0, and cxl_mem.4.
++ *
++ * See 'cxl list -BMPu -m cxl_mem.0,cxl_mem.4'
++ */
++ if (!hb0 || pdev->id % 4 || pdev->id > 4 || cxld->id > 0) {
++ default_mock_decoder(cxld);
++ return;
++ }
++
++ base = window->base_hpa;
++ cxld->hpa_range = (struct range) {
++ .start = base,
++ .end = base + size - 1,
++ };
++
++ cxld->interleave_ways = 2;
++ eig_to_granularity(window->granularity, &cxld->interleave_granularity);
++ cxld->target_type = CXL_DECODER_EXPANDER;
++ cxld->flags = CXL_DECODER_F_ENABLE;
++ cxled->state = CXL_DECODER_STATE_AUTO;
++ port->commit_end = cxld->id;
++ devm_cxl_dpa_reserve(cxled, 0, size / cxld->interleave_ways, 0);
++ cxld->commit = mock_decoder_commit;
++ cxld->reset = mock_decoder_reset;
++
++ /*
++ * Now that endpoint decoder is set up, walk up the hierarchy
++ * and setup the switch and root port decoders targeting @cxlmd.
++ */
++ iter = port;
++ for (i = 0; i < 2; i++) {
++ dport = iter->parent_dport;
++ iter = dport->port;
++ dev = device_find_child(&iter->dev, NULL, first_decoder);
++ /*
++ * Ancestor ports are guaranteed to be enumerated before
++ * @port, and all ports have at least one decoder.
++ */
++ if (WARN_ON(!dev))
++ continue;
++ cxlsd = to_cxl_switch_decoder(dev);
++ if (i == 0) {
++ /* put cxl_mem.4 second in the decode order */
++ if (pdev->id == 4)
++ cxlsd->target[1] = dport;
++ else
++ cxlsd->target[0] = dport;
++ } else
++ cxlsd->target[0] = dport;
++ cxld = &cxlsd->cxld;
++ cxld->target_type = CXL_DECODER_EXPANDER;
++ cxld->flags = CXL_DECODER_F_ENABLE;
++ iter->commit_end = 0;
++ /*
++ * Switch targets 2 endpoints, while host bridge targets
++ * one root port
++ */
++ if (i == 0)
++ cxld->interleave_ways = 2;
++ else
++ cxld->interleave_ways = 1;
++ cxld->interleave_granularity = 256;
++ cxld->hpa_range = (struct range) {
++ .start = base,
++ .end = base + size - 1,
++ };
++ put_device(dev);
++ }
++}
++
+ static int mock_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
+ {
+ struct cxl_port *port = cxlhdm->port;
+@@ -596,16 +732,7 @@ static int mock_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
+ cxld = &cxled->cxld;
+ }
+
+- cxld->hpa_range = (struct range) {
+- .start = 0,
+- .end = -1,
+- };
+-
+- cxld->interleave_ways = min_not_zero(target_count, 1);
+- cxld->interleave_granularity = SZ_4K;
+- cxld->target_type = CXL_DECODER_EXPANDER;
+- cxld->commit = mock_decoder_commit;
+- cxld->reset = mock_decoder_reset;
++ mock_init_hdm_decoder(cxld);
+
+ if (target_count) {
+ rc = device_for_each_child(port->uport, &ctx,
+--
+2.42.0
+