]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.10
authorSasha Levin <sashal@kernel.org>
Fri, 24 Nov 2023 04:28:42 +0000 (23:28 -0500)
committerSasha Levin <sashal@kernel.org>
Fri, 24 Nov 2023 04:28:42 +0000 (23:28 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
23 files changed:
queue-5.10/arm64-dts-qcom-ipq6018-fix-tcsr_mutex-register-size.patch [new file with mode: 0644]
queue-5.10/arm64-dts-qcom-ipq6018-switch-tcsr-mutex-to-mmio.patch [new file with mode: 0644]
queue-5.10/bluetooth-add-device-0bda-887b-to-device-tables.patch [new file with mode: 0644]
queue-5.10/bluetooth-add-device-13d3-3571-to-device-tables.patch [new file with mode: 0644]
queue-5.10/bluetooth-btusb-add-0bda-b85b-for-fn-link-rtl8852be.patch [new file with mode: 0644]
queue-5.10/bluetooth-btusb-add-realtek-rtl8852be-support-id-0x0.patch [new file with mode: 0644]
queue-5.10/bluetooth-btusb-add-rtw8852be-device-13d3-3570-to-de.patch [new file with mode: 0644]
queue-5.10/cpufreq-stats-fix-buffer-overflow-detection-in-trans.patch [new file with mode: 0644]
queue-5.10/pci-dwc-dra7xx-use-the-common-msi-irq_chip.patch [new file with mode: 0644]
queue-5.10/pci-dwc-drop-the-.set_num_vectors-host-op.patch [new file with mode: 0644]
queue-5.10/pci-dwc-exynos-rework-the-driver-to-support-exynos54.patch [new file with mode: 0644]
queue-5.10/pci-dwc-move-dbi-dbi2-and-addr_space-resource-setup-.patch [new file with mode: 0644]
queue-5.10/pci-dwc-move-dw_pcie_msi_init-into-core.patch [new file with mode: 0644]
queue-5.10/pci-dwc-move-dw_pcie_setup_rc-to-dwc-common-code.patch [new file with mode: 0644]
queue-5.10/pci-dwc-move-link-handling-into-common-code.patch [new file with mode: 0644]
queue-5.10/pci-dwc-move-msi-interrupt-setup-into-dwc-common-cod.patch [new file with mode: 0644]
queue-5.10/pci-dwc-rework-msi-initialization.patch [new file with mode: 0644]
queue-5.10/pci-exynos-don-t-discard-.remove-callback.patch [new file with mode: 0644]
queue-5.10/serial-meson-remove-redundant-initialization-of-vari.patch [new file with mode: 0644]
queue-5.10/serial-meson-use-platform_get_irq-to-get-the-interru.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/tty-serial-meson-fix-hard-lockup-on-crtscts-mode.patch [new file with mode: 0644]
queue-5.10/tty-serial-meson-retrieve-port-fifo-size-from-dt.patch [new file with mode: 0644]

diff --git a/queue-5.10/arm64-dts-qcom-ipq6018-fix-tcsr_mutex-register-size.patch b/queue-5.10/arm64-dts-qcom-ipq6018-fix-tcsr_mutex-register-size.patch
new file mode 100644 (file)
index 0000000..a76ec7a
--- /dev/null
@@ -0,0 +1,45 @@
+From 13f63b2dc8e04e8ff485c5880838fd41b6b9a166 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Sep 2023 15:25:34 +0530
+Subject: arm64: dts: qcom: ipq6018: Fix tcsr_mutex register size
+
+From: Vignesh Viswanathan <quic_viswanat@quicinc.com>
+
+[ Upstream commit 72fc3d58b87b0d622039c6299b89024fbb7b420f ]
+
+IPQ6018's TCSR Mutex HW lock register has 32 locks of size 4KB each.
+Total size of the TCSR Mutex registers is 128KB.
+
+Fix size of the tcsr_mutex hwlock register to 0x20000.
+
+Changes in v2:
+ - Drop change to remove qcom,ipq6018-tcsr-mutex compatible string
+ - Added Fixes and stable tags
+
+Cc: stable@vger.kernel.org
+Fixes: 5bf635621245 ("arm64: dts: ipq6018: Add a few device nodes")
+Signed-off-by: Vignesh Viswanathan <quic_viswanat@quicinc.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230905095535.1263113-2-quic_viswanat@quicinc.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq6018.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+index a8c26aff6f376..3677209106773 100644
+--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+@@ -238,7 +238,7 @@
+               tcsr_mutex: hwlock@1905000 {
+                       compatible = "qcom,ipq6018-tcsr-mutex", "qcom,tcsr-mutex";
+-                      reg = <0x0 0x01905000 0x0 0x1000>;
++                      reg = <0x0 0x01905000 0x0 0x20000>;
+                       #hwlock-cells = <1>;
+               };
+-- 
+2.42.0
+
diff --git a/queue-5.10/arm64-dts-qcom-ipq6018-switch-tcsr-mutex-to-mmio.patch b/queue-5.10/arm64-dts-qcom-ipq6018-switch-tcsr-mutex-to-mmio.patch
new file mode 100644 (file)
index 0000000..d75849a
--- /dev/null
@@ -0,0 +1,60 @@
+From c97754d8030c762ca96b032fefd2a904bd4e0243 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Sep 2022 11:20:31 +0200
+Subject: arm64: dts: qcom: ipq6018: switch TCSR mutex to MMIO
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit f5e303aefc06b7508d7a490f9a2d80e4dc134c70 ]
+
+The TCSR mutex bindings allow device to be described only with address
+space (so it uses MMIO, not syscon regmap).  This seems reasonable as
+TCSR mutex is actually a dedicated IO address space and it also fixes DT
+schema checks:
+
+  qcom/ipq6018-cp01-c1.dtb: hwlock: 'reg' is a required property
+  qcom/ipq6018-cp01-c1.dtb: hwlock: 'syscon' does not match any of the regexes: 'pinctrl-[0-9]+'
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20220909092035.223915-12-krzysztof.kozlowski@linaro.org
+Stable-dep-of: 72fc3d58b87b ("arm64: dts: qcom: ipq6018: Fix tcsr_mutex register size")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/ipq6018.dtsi | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+index 201a3bb5511cd..a8c26aff6f376 100644
+--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+@@ -129,12 +129,6 @@
+               };
+       };
+-      tcsr_mutex: hwlock {
+-              compatible = "qcom,tcsr-mutex";
+-              syscon = <&tcsr_mutex_regs 0 0x80>;
+-              #hwlock-cells = <1>;
+-      };
+-
+       pmuv8: pmu {
+               compatible = "arm,cortex-a53-pmu";
+               interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4) |
+@@ -242,9 +236,10 @@
+                       #reset-cells = <1>;
+               };
+-              tcsr_mutex_regs: syscon@1905000 {
+-                      compatible = "syscon";
+-                      reg = <0x0 0x01905000 0x0 0x8000>;
++              tcsr_mutex: hwlock@1905000 {
++                      compatible = "qcom,ipq6018-tcsr-mutex", "qcom,tcsr-mutex";
++                      reg = <0x0 0x01905000 0x0 0x1000>;
++                      #hwlock-cells = <1>;
+               };
+               tcsr_q6: syscon@1945000 {
+-- 
+2.42.0
+
diff --git a/queue-5.10/bluetooth-add-device-0bda-887b-to-device-tables.patch b/queue-5.10/bluetooth-add-device-0bda-887b-to-device-tables.patch
new file mode 100644 (file)
index 0000000..3e2a144
--- /dev/null
@@ -0,0 +1,67 @@
+From ad8336b7b8f27209c551c2a6904ba6f7b82dfff9 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 fffb73e6f49d4..bb1ec0cac2b29 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -418,6 +418,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
+
diff --git a/queue-5.10/bluetooth-add-device-13d3-3571-to-device-tables.patch b/queue-5.10/bluetooth-add-device-13d3-3571-to-device-tables.patch
new file mode 100644 (file)
index 0000000..0afd760
--- /dev/null
@@ -0,0 +1,65 @@
+From baf7f4a4bb918d5e2f6d163dd791852b1de2af97 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 bb1ec0cac2b29..6c225f48a26d4 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -420,6 +420,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
+
diff --git a/queue-5.10/bluetooth-btusb-add-0bda-b85b-for-fn-link-rtl8852be.patch b/queue-5.10/bluetooth-btusb-add-0bda-b85b-for-fn-link-rtl8852be.patch
new file mode 100644 (file)
index 0000000..79f45cb
--- /dev/null
@@ -0,0 +1,75 @@
+From 3e37ba18d41eb9fa3c5f006d14447231c2fd95cf 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 f1079614bfdb3..a1a8b282b99b1 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -420,6 +420,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
+
diff --git a/queue-5.10/bluetooth-btusb-add-realtek-rtl8852be-support-id-0x0.patch b/queue-5.10/bluetooth-btusb-add-realtek-rtl8852be-support-id-0x0.patch
new file mode 100644 (file)
index 0000000..22f1ffe
--- /dev/null
@@ -0,0 +1,70 @@
+From 6be8ee495acc64d36028a5c831427548c30275ca 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 cc210fb790d89..fffb73e6f49d4 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -415,6 +415,10 @@ static const struct usb_device_id blacklist_table[] = {
+       { USB_DEVICE(0x13d3, 0x3586), .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
+
diff --git a/queue-5.10/bluetooth-btusb-add-rtw8852be-device-13d3-3570-to-de.patch b/queue-5.10/bluetooth-btusb-add-rtw8852be-device-13d3-3570-to-de.patch
new file mode 100644 (file)
index 0000000..8624bda
--- /dev/null
@@ -0,0 +1,68 @@
+From d4aa3cb2c4c68f8fde58c54d631760b90a10d94c 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 6c225f48a26d4..f1079614bfdb3 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -420,6 +420,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
+
diff --git a/queue-5.10/cpufreq-stats-fix-buffer-overflow-detection-in-trans.patch b/queue-5.10/cpufreq-stats-fix-buffer-overflow-detection-in-trans.patch
new file mode 100644 (file)
index 0000000..3b59279
--- /dev/null
@@ -0,0 +1,87 @@
+From 5c5c0250a9da09cad0e5c9cd34808b3b0d3bdf4f 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 6cd5c8ab5d49f..ab856dd2d5fc0 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
+
diff --git a/queue-5.10/pci-dwc-dra7xx-use-the-common-msi-irq_chip.patch b/queue-5.10/pci-dwc-dra7xx-use-the-common-msi-irq_chip.patch
new file mode 100644 (file)
index 0000000..b360386
--- /dev/null
@@ -0,0 +1,168 @@
+From eb79d84adcfd4f527905aa45475665fc4d33bfbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Nov 2020 15:11:49 -0600
+Subject: PCI: dwc/dra7xx: Use the common MSI irq_chip
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit 7f170d35f58311362e8b01b6774ca1053c0641b8 ]
+
+The dra7xx MSI irq_chip implementation is identical to the default DWC one.
+The only difference is the interrupt handler as the MSI interrupt is muxed
+with other interrupts, but that doesn't affect the irq_chip part of it.
+
+Link: https://lore.kernel.org/r/20201105211159.1814485-7-robh@kernel.org
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Cc: Kishon Vijay Abraham I <kishon@ti.com>
+Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: linux-omap@vger.kernel.org
+Stable-dep-of: 83a939f0fdc2 ("PCI: exynos: Don't discard .remove() callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pci-dra7xx.c | 125 ------------------------
+ 1 file changed, 125 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
+index a4aabc85dbb12..4d0c35a4aa598 100644
+--- a/drivers/pci/controller/dwc/pci-dra7xx.c
++++ b/drivers/pci/controller/dwc/pci-dra7xx.c
+@@ -377,133 +377,8 @@ static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
+       return 0;
+ }
+-static void dra7xx_pcie_setup_msi_msg(struct irq_data *d, struct msi_msg *msg)
+-{
+-      struct pcie_port *pp = irq_data_get_irq_chip_data(d);
+-      struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+-      u64 msi_target;
+-
+-      msi_target = (u64)pp->msi_data;
+-
+-      msg->address_lo = lower_32_bits(msi_target);
+-      msg->address_hi = upper_32_bits(msi_target);
+-
+-      msg->data = d->hwirq;
+-
+-      dev_dbg(pci->dev, "msi#%d address_hi %#x address_lo %#x\n",
+-              (int)d->hwirq, msg->address_hi, msg->address_lo);
+-}
+-
+-static int dra7xx_pcie_msi_set_affinity(struct irq_data *d,
+-                                      const struct cpumask *mask,
+-                                      bool force)
+-{
+-      return -EINVAL;
+-}
+-
+-static void dra7xx_pcie_bottom_mask(struct irq_data *d)
+-{
+-      struct pcie_port *pp = irq_data_get_irq_chip_data(d);
+-      struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+-      unsigned int res, bit, ctrl;
+-      unsigned long flags;
+-
+-      raw_spin_lock_irqsave(&pp->lock, flags);
+-
+-      ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL;
+-      res = ctrl * MSI_REG_CTRL_BLOCK_SIZE;
+-      bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL;
+-
+-      pp->irq_mask[ctrl] |= BIT(bit);
+-      dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + res,
+-                         pp->irq_mask[ctrl]);
+-
+-      raw_spin_unlock_irqrestore(&pp->lock, flags);
+-}
+-
+-static void dra7xx_pcie_bottom_unmask(struct irq_data *d)
+-{
+-      struct pcie_port *pp = irq_data_get_irq_chip_data(d);
+-      struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+-      unsigned int res, bit, ctrl;
+-      unsigned long flags;
+-
+-      raw_spin_lock_irqsave(&pp->lock, flags);
+-
+-      ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL;
+-      res = ctrl * MSI_REG_CTRL_BLOCK_SIZE;
+-      bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL;
+-
+-      pp->irq_mask[ctrl] &= ~BIT(bit);
+-      dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + res,
+-                         pp->irq_mask[ctrl]);
+-
+-      raw_spin_unlock_irqrestore(&pp->lock, flags);
+-}
+-
+-static void dra7xx_pcie_bottom_ack(struct irq_data *d)
+-{
+-      struct pcie_port *pp  = irq_data_get_irq_chip_data(d);
+-      struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+-      unsigned int res, bit, ctrl;
+-
+-      ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL;
+-      res = ctrl * MSI_REG_CTRL_BLOCK_SIZE;
+-      bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL;
+-
+-      dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_STATUS + res, BIT(bit));
+-}
+-
+-static struct irq_chip dra7xx_pci_msi_bottom_irq_chip = {
+-      .name = "DRA7XX-PCI-MSI",
+-      .irq_ack = dra7xx_pcie_bottom_ack,
+-      .irq_compose_msi_msg = dra7xx_pcie_setup_msi_msg,
+-      .irq_set_affinity = dra7xx_pcie_msi_set_affinity,
+-      .irq_mask = dra7xx_pcie_bottom_mask,
+-      .irq_unmask = dra7xx_pcie_bottom_unmask,
+-};
+-
+-static int dra7xx_pcie_msi_host_init(struct pcie_port *pp)
+-{
+-      struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+-      struct device *dev = pci->dev;
+-      u32 ctrl, num_ctrls;
+-      int ret;
+-
+-      pp->msi_irq_chip = &dra7xx_pci_msi_bottom_irq_chip;
+-
+-      num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL;
+-      /* Initialize IRQ Status array */
+-      for (ctrl = 0; ctrl < num_ctrls; ctrl++) {
+-              pp->irq_mask[ctrl] = ~0;
+-              dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK +
+-                                  (ctrl * MSI_REG_CTRL_BLOCK_SIZE),
+-                                  pp->irq_mask[ctrl]);
+-              dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_ENABLE +
+-                                  (ctrl * MSI_REG_CTRL_BLOCK_SIZE),
+-                                  ~0);
+-      }
+-
+-      ret = dw_pcie_allocate_domains(pp);
+-      if (ret)
+-              return ret;
+-
+-      pp->msi_data = dma_map_single_attrs(dev, &pp->msi_msg,
+-                                         sizeof(pp->msi_msg),
+-                                         DMA_FROM_DEVICE,
+-                                         DMA_ATTR_SKIP_CPU_SYNC);
+-      ret = dma_mapping_error(dev, pp->msi_data);
+-      if (ret) {
+-              dev_err(dev, "Failed to map MSI data\n");
+-              pp->msi_data = 0;
+-              dw_pcie_free_msi(pp);
+-      }
+-      return ret;
+-}
+-
+ static const struct dw_pcie_host_ops dra7xx_pcie_host_ops = {
+       .host_init = dra7xx_pcie_host_init,
+-      .msi_host_init = dra7xx_pcie_msi_host_init,
+ };
+ static void dra7xx_pcie_ep_init(struct dw_pcie_ep *ep)
+-- 
+2.42.0
+
diff --git a/queue-5.10/pci-dwc-drop-the-.set_num_vectors-host-op.patch b/queue-5.10/pci-dwc-drop-the-.set_num_vectors-host-op.patch
new file mode 100644 (file)
index 0000000..0a6ded8
--- /dev/null
@@ -0,0 +1,137 @@
+From 2535a2b742bde8ebeb7e5852ae7ac39acd5a08a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Nov 2020 15:11:50 -0600
+Subject: PCI: dwc: Drop the .set_num_vectors() host op
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit 331e9bcead5252364e52fc95efbbe7273667b07d ]
+
+There's no reason for the .set_num_vectors() host op. Drivers needing a
+non-default value can just initialize pcie_port.num_vectors directly.
+
+Link: https://lore.kernel.org/r/20201105211159.1814485-8-robh@kernel.org
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Jingoo Han <jingoohan1@gmail.com>
+Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Thierry Reding <thierry.reding@gmail.com>
+Cc: Jonathan Hunter <jonathanh@nvidia.com>
+Cc: linux-tegra@vger.kernel.org
+Stable-dep-of: 83a939f0fdc2 ("PCI: exynos: Don't discard .remove() callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../pci/controller/dwc/pcie-designware-host.c | 19 ++++---------------
+ .../pci/controller/dwc/pcie-designware-plat.c |  7 +------
+ drivers/pci/controller/dwc/pcie-designware.h  |  1 -
+ drivers/pci/controller/dwc/pcie-tegra194.c    |  7 +------
+ 4 files changed, 6 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
+index d6b7eec1a25b0..32d3af7c44917 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -365,22 +365,11 @@ int dw_pcie_host_init(struct pcie_port *pp)
+               pci->link_gen = of_pci_get_max_link_speed(np);
+       if (pci_msi_enabled()) {
+-              /*
+-               * If a specific SoC driver needs to change the
+-               * default number of vectors, it needs to implement
+-               * the set_num_vectors callback.
+-               */
+-              if (!pp->ops->set_num_vectors) {
++              if (!pp->num_vectors) {
+                       pp->num_vectors = MSI_DEF_NUM_VECTORS;
+-              } else {
+-                      pp->ops->set_num_vectors(pp);
+-
+-                      if (pp->num_vectors > MAX_MSI_IRQS ||
+-                          pp->num_vectors == 0) {
+-                              dev_err(dev,
+-                                      "Invalid number of vectors\n");
+-                              return -EINVAL;
+-                      }
++              } else if (pp->num_vectors > MAX_MSI_IRQS) {
++                      dev_err(dev, "Invalid number of vectors\n");
++                      return -EINVAL;
+               }
+               if (!pp->ops->msi_host_init) {
+diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
+index 562a05e07b1d5..13fede1d41572 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
++++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
+@@ -44,14 +44,8 @@ static int dw_plat_pcie_host_init(struct pcie_port *pp)
+       return 0;
+ }
+-static void dw_plat_set_num_vectors(struct pcie_port *pp)
+-{
+-      pp->num_vectors = MAX_MSI_IRQS;
+-}
+-
+ static const struct dw_pcie_host_ops dw_plat_pcie_host_ops = {
+       .host_init = dw_plat_pcie_host_init,
+-      .set_num_vectors = dw_plat_set_num_vectors,
+ };
+ static int dw_plat_pcie_establish_link(struct dw_pcie *pci)
+@@ -128,6 +122,7 @@ static int dw_plat_add_pcie_port(struct dw_plat_pcie *dw_plat_pcie,
+                       return pp->msi_irq;
+       }
++      pp->num_vectors = MAX_MSI_IRQS;
+       pp->ops = &dw_plat_pcie_host_ops;
+       ret = dw_pcie_host_init(pp);
+diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
+index 9d2f511f13faf..82c0339c283f1 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.h
++++ b/drivers/pci/controller/dwc/pcie-designware.h
+@@ -174,7 +174,6 @@ enum dw_pcie_device_mode {
+ struct dw_pcie_host_ops {
+       int (*host_init)(struct pcie_port *pp);
+-      void (*set_num_vectors)(struct pcie_port *pp);
+       int (*msi_host_init)(struct pcie_port *pp);
+ };
+diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
+index 825cb65945fba..a93b5dca110ec 100644
+--- a/drivers/pci/controller/dwc/pcie-tegra194.c
++++ b/drivers/pci/controller/dwc/pcie-tegra194.c
+@@ -996,11 +996,6 @@ static int tegra_pcie_dw_link_up(struct dw_pcie *pci)
+       return !!(val & PCI_EXP_LNKSTA_DLLLA);
+ }
+-static void tegra_pcie_set_msi_vec_num(struct pcie_port *pp)
+-{
+-      pp->num_vectors = MAX_MSI_IRQS;
+-}
+-
+ static int tegra_pcie_dw_start_link(struct dw_pcie *pci)
+ {
+       struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
+@@ -1025,7 +1020,6 @@ static const struct dw_pcie_ops tegra_dw_pcie_ops = {
+ static struct dw_pcie_host_ops tegra_pcie_dw_host_ops = {
+       .host_init = tegra_pcie_dw_host_init,
+-      .set_num_vectors = tegra_pcie_set_msi_vec_num,
+ };
+ static void tegra_pcie_disable_phy(struct tegra_pcie_dw *pcie)
+@@ -2002,6 +1996,7 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)
+       pci->n_fts[1] = FTS_VAL;
+       pp = &pci->pp;
++      pp->num_vectors = MAX_MSI_IRQS;
+       pcie->dev = &pdev->dev;
+       pcie->mode = (enum dw_pcie_device_mode)data->mode;
+-- 
+2.42.0
+
diff --git a/queue-5.10/pci-dwc-exynos-rework-the-driver-to-support-exynos54.patch b/queue-5.10/pci-dwc-exynos-rework-the-driver-to-support-exynos54.patch
new file mode 100644 (file)
index 0000000..949fa6a
--- /dev/null
@@ -0,0 +1,646 @@
+From a8f5794be913c874645a36fcd07145df3ac0eac6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Nov 2020 18:01:39 +0100
+Subject: PCI: dwc: exynos: Rework the driver to support Exynos5433 variant
+
+From: Jaehoon Chung <jh80.chung@samsung.com>
+
+[ Upstream commit 778f7c194b1dac351d345ce723f8747026092949 ]
+
+Exynos5440 SoC support has been dropped since commit 8c83315da1cf ("ARM:
+dts: exynos: Remove Exynos5440"). Rework this driver to support DWC PCIe
+variant found in the Exynos5433 SoCs.
+
+The main difference in Exynos5433 variant is lack of the MSI support
+(the MSI interrupt is not even routed to the CPU).
+
+[mszyprow: reworked the driver to support only Exynos5433 variant,
+          simplified code, rebased onto current kernel code, added
+          regulator support, converted to the regular platform driver,
+          removed MSI related code, rewrote commit message, added help]
+
+Link: https://lore.kernel.org/r/20201113170139.29956-6-m.szyprowski@samsung.com
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
+Acked-by: Jingoo Han <jingoohan1@gmail.com>
+Stable-dep-of: 83a939f0fdc2 ("PCI: exynos: Don't discard .remove() callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/Kconfig      |   9 +-
+ drivers/pci/controller/dwc/pci-exynos.c | 353 ++++++++++--------------
+ drivers/pci/quirks.c                    |   1 +
+ 3 files changed, 147 insertions(+), 216 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
+index bc049865f8e05..9ee1e248e7448 100644
+--- a/drivers/pci/controller/dwc/Kconfig
++++ b/drivers/pci/controller/dwc/Kconfig
+@@ -83,10 +83,15 @@ config PCIE_DW_PLAT_EP
+         selected.
+ config PCI_EXYNOS
+-      bool "Samsung Exynos PCIe controller"
+-      depends on SOC_EXYNOS5440 || COMPILE_TEST
++      tristate "Samsung Exynos PCIe controller"
++      depends on ARCH_EXYNOS || COMPILE_TEST
+       depends on PCI_MSI_IRQ_DOMAIN
+       select PCIE_DW_HOST
++      help
++        Enables support for the PCIe controller in the Samsung Exynos SoCs
++        to work in host mode. The PCI controller is based on the DesignWare
++        hardware and therefore the driver re-uses the DesignWare core
++        functions to implement the driver.
+ config PCI_IMX6
+       bool "Freescale i.MX6/7/8 PCIe controller"
+diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
+index 5c10a5432896c..c24dab383654b 100644
+--- a/drivers/pci/controller/dwc/pci-exynos.c
++++ b/drivers/pci/controller/dwc/pci-exynos.c
+@@ -2,26 +2,23 @@
+ /*
+  * PCIe host controller driver for Samsung Exynos SoCs
+  *
+- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
++ * Copyright (C) 2013-2020 Samsung Electronics Co., Ltd.
+  *            https://www.samsung.com
+  *
+  * Author: Jingoo Han <jg1.han@samsung.com>
++ *       Jaehoon Chung <jh80.chung@samsung.com>
+  */
+ #include <linux/clk.h>
+ #include <linux/delay.h>
+-#include <linux/gpio.h>
+ #include <linux/interrupt.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/of_device.h>
+-#include <linux/of_gpio.h>
+ #include <linux/pci.h>
+ #include <linux/platform_device.h>
+ #include <linux/phy/phy.h>
+-#include <linux/resource.h>
+-#include <linux/signal.h>
+-#include <linux/types.h>
++#include <linux/regulator/consumer.h>
+ #include "pcie-designware.h"
+@@ -37,102 +34,43 @@
+ #define PCIE_IRQ_SPECIAL              0x008
+ #define PCIE_IRQ_EN_PULSE             0x00c
+ #define PCIE_IRQ_EN_LEVEL             0x010
+-#define IRQ_MSI_ENABLE                        BIT(2)
+ #define PCIE_IRQ_EN_SPECIAL           0x014
+-#define PCIE_PWR_RESET                        0x018
++#define PCIE_SW_WAKE                  0x018
++#define PCIE_BUS_EN                   BIT(1)
+ #define PCIE_CORE_RESET                       0x01c
+ #define PCIE_CORE_RESET_ENABLE                BIT(0)
+ #define PCIE_STICKY_RESET             0x020
+ #define PCIE_NONSTICKY_RESET          0x024
+ #define PCIE_APP_INIT_RESET           0x028
+ #define PCIE_APP_LTSSM_ENABLE         0x02c
+-#define PCIE_ELBI_RDLH_LINKUP         0x064
++#define PCIE_ELBI_RDLH_LINKUP         0x074
++#define PCIE_ELBI_XMLH_LINKUP         BIT(4)
+ #define PCIE_ELBI_LTSSM_ENABLE                0x1
+ #define PCIE_ELBI_SLV_AWMISC          0x11c
+ #define PCIE_ELBI_SLV_ARMISC          0x120
+ #define PCIE_ELBI_SLV_DBI_ENABLE      BIT(21)
+-struct exynos_pcie_mem_res {
+-      void __iomem *elbi_base;   /* DT 0th resource: PCIe CTRL */
+-};
+-
+-struct exynos_pcie_clk_res {
+-      struct clk *clk;
+-      struct clk *bus_clk;
+-};
+-
+ struct exynos_pcie {
+-      struct dw_pcie                  *pci;
+-      struct exynos_pcie_mem_res      *mem_res;
+-      struct exynos_pcie_clk_res      *clk_res;
+-      const struct exynos_pcie_ops    *ops;
+-      int                             reset_gpio;
+-
++      struct dw_pcie                  pci;
++      void __iomem                    *elbi_base;
++      struct clk                      *clk;
++      struct clk                      *bus_clk;
+       struct phy                      *phy;
++      struct regulator_bulk_data      supplies[2];
+ };
+-struct exynos_pcie_ops {
+-      int (*get_mem_resources)(struct platform_device *pdev,
+-                      struct exynos_pcie *ep);
+-      int (*get_clk_resources)(struct exynos_pcie *ep);
+-      int (*init_clk_resources)(struct exynos_pcie *ep);
+-      void (*deinit_clk_resources)(struct exynos_pcie *ep);
+-};
+-
+-static int exynos5440_pcie_get_mem_resources(struct platform_device *pdev,
+-                                           struct exynos_pcie *ep)
+-{
+-      struct dw_pcie *pci = ep->pci;
+-      struct device *dev = pci->dev;
+-
+-      ep->mem_res = devm_kzalloc(dev, sizeof(*ep->mem_res), GFP_KERNEL);
+-      if (!ep->mem_res)
+-              return -ENOMEM;
+-
+-      ep->mem_res->elbi_base = devm_platform_ioremap_resource(pdev, 0);
+-      if (IS_ERR(ep->mem_res->elbi_base))
+-              return PTR_ERR(ep->mem_res->elbi_base);
+-
+-      return 0;
+-}
+-
+-static int exynos5440_pcie_get_clk_resources(struct exynos_pcie *ep)
++static int exynos_pcie_init_clk_resources(struct exynos_pcie *ep)
+ {
+-      struct dw_pcie *pci = ep->pci;
+-      struct device *dev = pci->dev;
+-
+-      ep->clk_res = devm_kzalloc(dev, sizeof(*ep->clk_res), GFP_KERNEL);
+-      if (!ep->clk_res)
+-              return -ENOMEM;
+-
+-      ep->clk_res->clk = devm_clk_get(dev, "pcie");
+-      if (IS_ERR(ep->clk_res->clk)) {
+-              dev_err(dev, "Failed to get pcie rc clock\n");
+-              return PTR_ERR(ep->clk_res->clk);
+-      }
+-
+-      ep->clk_res->bus_clk = devm_clk_get(dev, "pcie_bus");
+-      if (IS_ERR(ep->clk_res->bus_clk)) {
+-              dev_err(dev, "Failed to get pcie bus clock\n");
+-              return PTR_ERR(ep->clk_res->bus_clk);
+-      }
+-
+-      return 0;
+-}
+-
+-static int exynos5440_pcie_init_clk_resources(struct exynos_pcie *ep)
+-{
+-      struct dw_pcie *pci = ep->pci;
+-      struct device *dev = pci->dev;
++      struct device *dev = ep->pci.dev;
+       int ret;
+-      ret = clk_prepare_enable(ep->clk_res->clk);
++      ret = clk_prepare_enable(ep->clk);
+       if (ret) {
+               dev_err(dev, "cannot enable pcie rc clock");
+               return ret;
+       }
+-      ret = clk_prepare_enable(ep->clk_res->bus_clk);
++      ret = clk_prepare_enable(ep->bus_clk);
+       if (ret) {
+               dev_err(dev, "cannot enable pcie bus clock");
+               goto err_bus_clk;
+@@ -141,24 +79,17 @@ static int exynos5440_pcie_init_clk_resources(struct exynos_pcie *ep)
+       return 0;
+ err_bus_clk:
+-      clk_disable_unprepare(ep->clk_res->clk);
++      clk_disable_unprepare(ep->clk);
+       return ret;
+ }
+-static void exynos5440_pcie_deinit_clk_resources(struct exynos_pcie *ep)
++static void exynos_pcie_deinit_clk_resources(struct exynos_pcie *ep)
+ {
+-      clk_disable_unprepare(ep->clk_res->bus_clk);
+-      clk_disable_unprepare(ep->clk_res->clk);
++      clk_disable_unprepare(ep->bus_clk);
++      clk_disable_unprepare(ep->clk);
+ }
+-static const struct exynos_pcie_ops exynos5440_pcie_ops = {
+-      .get_mem_resources      = exynos5440_pcie_get_mem_resources,
+-      .get_clk_resources      = exynos5440_pcie_get_clk_resources,
+-      .init_clk_resources     = exynos5440_pcie_init_clk_resources,
+-      .deinit_clk_resources   = exynos5440_pcie_deinit_clk_resources,
+-};
+-
+ static void exynos_pcie_writel(void __iomem *base, u32 val, u32 reg)
+ {
+       writel(val, base + reg);
+@@ -173,94 +104,71 @@ static void exynos_pcie_sideband_dbi_w_mode(struct exynos_pcie *ep, bool on)
+ {
+       u32 val;
+-      val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_ELBI_SLV_AWMISC);
++      val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_AWMISC);
+       if (on)
+               val |= PCIE_ELBI_SLV_DBI_ENABLE;
+       else
+               val &= ~PCIE_ELBI_SLV_DBI_ENABLE;
+-      exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_ELBI_SLV_AWMISC);
++      exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_AWMISC);
+ }
+ static void exynos_pcie_sideband_dbi_r_mode(struct exynos_pcie *ep, bool on)
+ {
+       u32 val;
+-      val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_ELBI_SLV_ARMISC);
++      val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_ARMISC);
+       if (on)
+               val |= PCIE_ELBI_SLV_DBI_ENABLE;
+       else
+               val &= ~PCIE_ELBI_SLV_DBI_ENABLE;
+-      exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_ELBI_SLV_ARMISC);
++      exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_ARMISC);
+ }
+ static void exynos_pcie_assert_core_reset(struct exynos_pcie *ep)
+ {
+       u32 val;
+-      val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_CORE_RESET);
++      val = exynos_pcie_readl(ep->elbi_base, PCIE_CORE_RESET);
+       val &= ~PCIE_CORE_RESET_ENABLE;
+-      exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_CORE_RESET);
+-      exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_PWR_RESET);
+-      exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_STICKY_RESET);
+-      exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_NONSTICKY_RESET);
++      exynos_pcie_writel(ep->elbi_base, val, PCIE_CORE_RESET);
++      exynos_pcie_writel(ep->elbi_base, 0, PCIE_STICKY_RESET);
++      exynos_pcie_writel(ep->elbi_base, 0, PCIE_NONSTICKY_RESET);
+ }
+ static void exynos_pcie_deassert_core_reset(struct exynos_pcie *ep)
+ {
+       u32 val;
+-      val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_CORE_RESET);
++      val = exynos_pcie_readl(ep->elbi_base, PCIE_CORE_RESET);
+       val |= PCIE_CORE_RESET_ENABLE;
+-      exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_CORE_RESET);
+-      exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_STICKY_RESET);
+-      exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_NONSTICKY_RESET);
+-      exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_APP_INIT_RESET);
+-      exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_APP_INIT_RESET);
+-}
+-
+-static void exynos_pcie_assert_reset(struct exynos_pcie *ep)
+-{
+-      struct dw_pcie *pci = ep->pci;
+-      struct device *dev = pci->dev;
+-
+-      if (ep->reset_gpio >= 0)
+-              devm_gpio_request_one(dev, ep->reset_gpio,
+-                              GPIOF_OUT_INIT_HIGH, "RESET");
++      exynos_pcie_writel(ep->elbi_base, val, PCIE_CORE_RESET);
++      exynos_pcie_writel(ep->elbi_base, 1, PCIE_STICKY_RESET);
++      exynos_pcie_writel(ep->elbi_base, 1, PCIE_NONSTICKY_RESET);
++      exynos_pcie_writel(ep->elbi_base, 1, PCIE_APP_INIT_RESET);
++      exynos_pcie_writel(ep->elbi_base, 0, PCIE_APP_INIT_RESET);
+ }
+ static int exynos_pcie_start_link(struct dw_pcie *pci)
+ {
+       struct exynos_pcie *ep = to_exynos_pcie(pci);
++      u32 val;
++
++      val = exynos_pcie_readl(ep->elbi_base, PCIE_SW_WAKE);
++      val &= ~PCIE_BUS_EN;
++      exynos_pcie_writel(ep->elbi_base, val, PCIE_SW_WAKE);
+       /* assert LTSSM enable */
+-      exynos_pcie_writel(ep->mem_res->elbi_base, PCIE_ELBI_LTSSM_ENABLE,
++      exynos_pcie_writel(ep->elbi_base, PCIE_ELBI_LTSSM_ENABLE,
+                         PCIE_APP_LTSSM_ENABLE);
+-
+-      /* check if the link is up or not */
+-      if (!dw_pcie_wait_for_link(pci))
+-              return 0;
+-
+-      phy_power_off(ep->phy);
+-      return -ETIMEDOUT;
++      return 0;
+ }
+ static void exynos_pcie_clear_irq_pulse(struct exynos_pcie *ep)
+ {
+-      u32 val;
+-
+-      val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_IRQ_PULSE);
+-      exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_IRQ_PULSE);
+-}
+-
+-static void exynos_pcie_enable_irq_pulse(struct exynos_pcie *ep)
+-{
+-      u32 val;
++      u32 val = exynos_pcie_readl(ep->elbi_base, PCIE_IRQ_PULSE);
+-      /* enable INTX interrupt */
+-      val = IRQ_INTA_ASSERT | IRQ_INTB_ASSERT |
+-              IRQ_INTC_ASSERT | IRQ_INTD_ASSERT;
+-      exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_IRQ_EN_PULSE);
++      exynos_pcie_writel(ep->elbi_base, val, PCIE_IRQ_PULSE);
+ }
+ static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg)
+@@ -271,22 +179,14 @@ static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg)
+       return IRQ_HANDLED;
+ }
+-static void exynos_pcie_msi_init(struct exynos_pcie *ep)
+-{
+-      u32 val;
+-
+-      /* enable MSI interrupt */
+-      val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_IRQ_EN_LEVEL);
+-      val |= IRQ_MSI_ENABLE;
+-      exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_IRQ_EN_LEVEL);
+-}
+-
+-static void exynos_pcie_enable_interrupts(struct exynos_pcie *ep)
++static void exynos_pcie_enable_irq_pulse(struct exynos_pcie *ep)
+ {
+-      exynos_pcie_enable_irq_pulse(ep);
++      u32 val = IRQ_INTA_ASSERT | IRQ_INTB_ASSERT |
++                IRQ_INTC_ASSERT | IRQ_INTD_ASSERT;
+-      if (IS_ENABLED(CONFIG_PCI_MSI))
+-              exynos_pcie_msi_init(ep);
++      exynos_pcie_writel(ep->elbi_base, val, PCIE_IRQ_EN_PULSE);
++      exynos_pcie_writel(ep->elbi_base, 0, PCIE_IRQ_EN_LEVEL);
++      exynos_pcie_writel(ep->elbi_base, 0, PCIE_IRQ_EN_SPECIAL);
+ }
+ static u32 exynos_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base,
+@@ -345,13 +245,9 @@ static struct pci_ops exynos_pci_ops = {
+ static int exynos_pcie_link_up(struct dw_pcie *pci)
+ {
+       struct exynos_pcie *ep = to_exynos_pcie(pci);
+-      u32 val;
++      u32 val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_RDLH_LINKUP);
+-      val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_ELBI_RDLH_LINKUP);
+-      if (val == PCIE_ELBI_LTSSM_ENABLE)
+-              return 1;
+-
+-      return 0;
++      return (val & PCIE_ELBI_XMLH_LINKUP);
+ }
+ static int exynos_pcie_host_init(struct pcie_port *pp)
+@@ -364,17 +260,11 @@ static int exynos_pcie_host_init(struct pcie_port *pp)
+       exynos_pcie_assert_core_reset(ep);
+       phy_reset(ep->phy);
+-
+-      exynos_pcie_writel(ep->mem_res->elbi_base, 1,
+-                      PCIE_PWR_RESET);
+-
+       phy_power_on(ep->phy);
+       phy_init(ep->phy);
+       exynos_pcie_deassert_core_reset(ep);
+-      exynos_pcie_assert_reset(ep);
+-
+-      exynos_pcie_enable_interrupts(ep);
++      exynos_pcie_enable_irq_pulse(ep);
+       return 0;
+ }
+@@ -383,26 +273,27 @@ static const struct dw_pcie_host_ops exynos_pcie_host_ops = {
+       .host_init = exynos_pcie_host_init,
+ };
+-static int __init exynos_add_pcie_port(struct exynos_pcie *ep,
++static int exynos_add_pcie_port(struct exynos_pcie *ep,
+                                      struct platform_device *pdev)
+ {
+-      struct dw_pcie *pci = ep->pci;
++      struct dw_pcie *pci = &ep->pci;
+       struct pcie_port *pp = &pci->pp;
+       struct device *dev = &pdev->dev;
+       int ret;
+-      pp->irq = platform_get_irq(pdev, 1);
++      pp->irq = platform_get_irq(pdev, 0);
+       if (pp->irq < 0)
+               return pp->irq;
+       ret = devm_request_irq(dev, pp->irq, exynos_pcie_irq_handler,
+-                              IRQF_SHARED, "exynos-pcie", ep);
++                             IRQF_SHARED, "exynos-pcie", ep);
+       if (ret) {
+               dev_err(dev, "failed to request irq\n");
+               return ret;
+       }
+       pp->ops = &exynos_pcie_host_ops;
++      pp->msi_irq = -ENODEV;
+       ret = dw_pcie_host_init(pp);
+       if (ret) {
+@@ -420,10 +311,9 @@ static const struct dw_pcie_ops dw_pcie_ops = {
+       .start_link = exynos_pcie_start_link,
+ };
+-static int __init exynos_pcie_probe(struct platform_device *pdev)
++static int exynos_pcie_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+-      struct dw_pcie *pci;
+       struct exynos_pcie *ep;
+       struct device_node *np = dev->of_node;
+       int ret;
+@@ -432,43 +322,45 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)
+       if (!ep)
+               return -ENOMEM;
+-      pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
+-      if (!pci)
+-              return -ENOMEM;
+-
+-      pci->dev = dev;
+-      pci->ops = &dw_pcie_ops;
+-
+-      ep->pci = pci;
+-      ep->ops = (const struct exynos_pcie_ops *)
+-              of_device_get_match_data(dev);
+-
+-      ep->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
++      ep->pci.dev = dev;
++      ep->pci.ops = &dw_pcie_ops;
+       ep->phy = devm_of_phy_get(dev, np, NULL);
+-      if (IS_ERR(ep->phy)) {
+-              if (PTR_ERR(ep->phy) != -ENODEV)
+-                      return PTR_ERR(ep->phy);
++      if (IS_ERR(ep->phy))
++              return PTR_ERR(ep->phy);
+-              ep->phy = NULL;
+-      }
++      /* External Local Bus interface (ELBI) registers */
++      ep->elbi_base = devm_platform_ioremap_resource_byname(pdev, "elbi");
++      if (IS_ERR(ep->elbi_base))
++              return PTR_ERR(ep->elbi_base);
+-      if (ep->ops && ep->ops->get_mem_resources) {
+-              ret = ep->ops->get_mem_resources(pdev, ep);
+-              if (ret)
+-                      return ret;
++      ep->clk = devm_clk_get(dev, "pcie");
++      if (IS_ERR(ep->clk)) {
++              dev_err(dev, "Failed to get pcie rc clock\n");
++              return PTR_ERR(ep->clk);
+       }
+-      if (ep->ops && ep->ops->get_clk_resources &&
+-                      ep->ops->init_clk_resources) {
+-              ret = ep->ops->get_clk_resources(ep);
+-              if (ret)
+-                      return ret;
+-              ret = ep->ops->init_clk_resources(ep);
+-              if (ret)
+-                      return ret;
++      ep->bus_clk = devm_clk_get(dev, "pcie_bus");
++      if (IS_ERR(ep->bus_clk)) {
++              dev_err(dev, "Failed to get pcie bus clock\n");
++              return PTR_ERR(ep->bus_clk);
+       }
++      ep->supplies[0].supply = "vdd18";
++      ep->supplies[1].supply = "vdd10";
++      ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ep->supplies),
++                                    ep->supplies);
++      if (ret)
++              return ret;
++
++      ret = exynos_pcie_init_clk_resources(ep);
++      if (ret)
++              return ret;
++
++      ret = regulator_bulk_enable(ARRAY_SIZE(ep->supplies), ep->supplies);
++      if (ret)
++              return ret;
++
+       platform_set_drvdata(pdev, ep);
+       ret = exynos_add_pcie_port(ep, pdev);
+@@ -479,9 +371,9 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)
+ fail_probe:
+       phy_exit(ep->phy);
++      exynos_pcie_deinit_clk_resources(ep);
++      regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies);
+-      if (ep->ops && ep->ops->deinit_clk_resources)
+-              ep->ops->deinit_clk_resources(ep);
+       return ret;
+ }
+@@ -489,32 +381,65 @@ static int __exit exynos_pcie_remove(struct platform_device *pdev)
+ {
+       struct exynos_pcie *ep = platform_get_drvdata(pdev);
+-      if (ep->ops && ep->ops->deinit_clk_resources)
+-              ep->ops->deinit_clk_resources(ep);
++      dw_pcie_host_deinit(&ep->pci.pp);
++      exynos_pcie_assert_core_reset(ep);
++      phy_power_off(ep->phy);
++      phy_exit(ep->phy);
++      exynos_pcie_deinit_clk_resources(ep);
++      regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies);
++
++      return 0;
++}
++
++static int __maybe_unused exynos_pcie_suspend_noirq(struct device *dev)
++{
++      struct exynos_pcie *ep = dev_get_drvdata(dev);
++
++      exynos_pcie_assert_core_reset(ep);
++      phy_power_off(ep->phy);
++      phy_exit(ep->phy);
++      regulator_bulk_disable(ARRAY_SIZE(ep->supplies), ep->supplies);
+       return 0;
+ }
++static int __maybe_unused exynos_pcie_resume_noirq(struct device *dev)
++{
++      struct exynos_pcie *ep = dev_get_drvdata(dev);
++      struct dw_pcie *pci = &ep->pci;
++      struct pcie_port *pp = &pci->pp;
++      int ret;
++
++      ret = regulator_bulk_enable(ARRAY_SIZE(ep->supplies), ep->supplies);
++      if (ret)
++              return ret;
++
++      /* exynos_pcie_host_init controls ep->phy */
++      exynos_pcie_host_init(pp);
++      dw_pcie_setup_rc(pp);
++      exynos_pcie_start_link(pci);
++      return dw_pcie_wait_for_link(pci);
++}
++
++static const struct dev_pm_ops exynos_pcie_pm_ops = {
++      SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(exynos_pcie_suspend_noirq,
++                                    exynos_pcie_resume_noirq)
++};
++
+ static const struct of_device_id exynos_pcie_of_match[] = {
+-      {
+-              .compatible = "samsung,exynos5440-pcie",
+-              .data = &exynos5440_pcie_ops
+-      },
+-      {},
++      { .compatible = "samsung,exynos5433-pcie", },
++      { },
+ };
+ static struct platform_driver exynos_pcie_driver = {
++      .probe          = exynos_pcie_probe,
+       .remove         = __exit_p(exynos_pcie_remove),
+       .driver = {
+               .name   = "exynos-pcie",
+               .of_match_table = exynos_pcie_of_match,
++              .pm             = &exynos_pcie_pm_ops,
+       },
+ };
+-
+-/* Exynos PCIe driver does not allow module unload */
+-
+-static int __init exynos_pcie_init(void)
+-{
+-      return platform_driver_probe(&exynos_pcie_driver, exynos_pcie_probe);
+-}
+-subsys_initcall(exynos_pcie_init);
++module_platform_driver(exynos_pcie_driver);
++MODULE_LICENSE("GPL v2");
++MODULE_DEVICE_TABLE(of, exynos_pcie_of_match);
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index 158ff4331a141..01c2b63e3b3a1 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -2538,6 +2538,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disab
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3364, quirk_disable_all_msi);
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8380_0, quirk_disable_all_msi);
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, 0x0761, quirk_disable_all_msi);
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SAMSUNG, 0xa5e3, quirk_disable_all_msi);
+ /* Disable MSI on chipsets that are known to not support it */
+ static void quirk_disable_msi(struct pci_dev *dev)
+-- 
+2.42.0
+
diff --git a/queue-5.10/pci-dwc-move-dbi-dbi2-and-addr_space-resource-setup-.patch b/queue-5.10/pci-dwc-move-dbi-dbi2-and-addr_space-resource-setup-.patch
new file mode 100644 (file)
index 0000000..7a4f4b1
--- /dev/null
@@ -0,0 +1,707 @@
+From a5bb5f9005bc2bba67a3c1eee93921b864d23624 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Nov 2020 15:11:46 -0600
+Subject: PCI: dwc: Move "dbi", "dbi2", and "addr_space" resource setup into
+ common code
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit a0fd361db8e508b8ce71c284b5ae3961759a0b3b ]
+
+Most DWC drivers use the common register resource names "dbi", "dbi2", and
+"addr_space", so let's move their setup into the DWC common code.
+
+This means 'dbi_base' in particular is setup later, but it looks like no
+drivers touch DBI registers before dw_pcie_host_init or dw_pcie_ep_init.
+
+Link: https://lore.kernel.org/r/20201105211159.1814485-4-robh@kernel.org
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Jingoo Han <jingoohan1@gmail.com>
+Cc: Kishon Vijay Abraham I <kishon@ti.com>
+Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Murali Karicheri <m-karicheri2@ti.com>
+Cc: Minghuan Lian <minghuan.Lian@nxp.com>
+Cc: Mingkai Hu <mingkai.hu@nxp.com>
+Cc: Roy Zang <roy.zang@nxp.com>
+Cc: Jonathan Chocron <jonnyc@amazon.com>
+Cc: Jesper Nilsson <jesper.nilsson@axis.com>
+Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Cc: Xiaowei Song <songxiaowei@hisilicon.com>
+Cc: Binghui Wang <wangbinghui@hisilicon.com>
+Cc: Andy Gross <agross@kernel.org>
+Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
+Cc: Stanimir Varbanov <svarbanov@mm-sol.com>
+Cc: Pratyush Anand <pratyush.anand@gmail.com>
+Cc: Thierry Reding <thierry.reding@gmail.com>
+Cc: Jonathan Hunter <jonathanh@nvidia.com>
+Cc: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
+Cc: linux-omap@vger.kernel.org
+Cc: linuxppc-dev@lists.ozlabs.org
+Cc: linux-arm-kernel@axis.com
+Cc: linux-arm-msm@vger.kernel.org
+Cc: linux-tegra@vger.kernel.org
+Stable-dep-of: 83a939f0fdc2 ("PCI: exynos: Don't discard .remove() callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pci-dra7xx.c       |  8 ----
+ drivers/pci/controller/dwc/pci-keystone.c     | 29 +-----------
+ .../pci/controller/dwc/pci-layerscape-ep.c    | 37 +--------------
+ drivers/pci/controller/dwc/pcie-al.c          |  9 +---
+ drivers/pci/controller/dwc/pcie-artpec6.c     | 43 ++----------------
+ .../pci/controller/dwc/pcie-designware-ep.c   | 29 ++++++++++--
+ .../pci/controller/dwc/pcie-designware-host.c |  7 +++
+ .../pci/controller/dwc/pcie-designware-plat.c | 45 +------------------
+ drivers/pci/controller/dwc/pcie-intel-gw.c    |  4 --
+ drivers/pci/controller/dwc/pcie-kirin.c       |  5 ---
+ drivers/pci/controller/dwc/pcie-qcom.c        |  8 ----
+ drivers/pci/controller/dwc/pcie-spear13xx.c   | 11 +----
+ drivers/pci/controller/dwc/pcie-tegra194.c    | 22 ---------
+ drivers/pci/controller/dwc/pcie-uniphier-ep.c | 38 +---------------
+ drivers/pci/controller/dwc/pcie-uniphier.c    |  6 ---
+ 15 files changed, 47 insertions(+), 254 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
+index 6d012d2b1e90d..a4aabc85dbb12 100644
+--- a/drivers/pci/controller/dwc/pci-dra7xx.c
++++ b/drivers/pci/controller/dwc/pci-dra7xx.c
+@@ -578,7 +578,6 @@ static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
+ {
+       int ret;
+       struct dw_pcie_ep *ep;
+-      struct resource *res;
+       struct device *dev = &pdev->dev;
+       struct dw_pcie *pci = dra7xx->pci;
+@@ -594,13 +593,6 @@ static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
+       if (IS_ERR(pci->dbi_base2))
+               return PTR_ERR(pci->dbi_base2);
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
+-      if (!res)
+-              return -EINVAL;
+-
+-      ep->phys_base = res->start;
+-      ep->addr_size = resource_size(res);
+-
+       ret = dw_pcie_ep_init(ep);
+       if (ret) {
+               dev_err(dev, "failed to initialize endpoint\n");
+diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
+index 5b722287aac92..5177f6d1ca592 100644
+--- a/drivers/pci/controller/dwc/pci-keystone.c
++++ b/drivers/pci/controller/dwc/pci-keystone.c
+@@ -978,33 +978,6 @@ static const struct dw_pcie_ep_ops ks_pcie_am654_ep_ops = {
+       .get_features = &ks_pcie_am654_get_features,
+ };
+-static int __init ks_pcie_add_pcie_ep(struct keystone_pcie *ks_pcie,
+-                                    struct platform_device *pdev)
+-{
+-      int ret;
+-      struct dw_pcie_ep *ep;
+-      struct resource *res;
+-      struct device *dev = &pdev->dev;
+-      struct dw_pcie *pci = ks_pcie->pci;
+-
+-      ep = &pci->ep;
+-
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
+-      if (!res)
+-              return -EINVAL;
+-
+-      ep->phys_base = res->start;
+-      ep->addr_size = resource_size(res);
+-
+-      ret = dw_pcie_ep_init(ep);
+-      if (ret) {
+-              dev_err(dev, "failed to initialize endpoint\n");
+-              return ret;
+-      }
+-
+-      return 0;
+-}
+-
+ static void ks_pcie_disable_phy(struct keystone_pcie *ks_pcie)
+ {
+       int num_lanes = ks_pcie->num_lanes;
+@@ -1314,7 +1287,7 @@ static int ks_pcie_probe(struct platform_device *pdev)
+               }
+               pci->ep.ops = ep_ops;
+-              ret = ks_pcie_add_pcie_ep(ks_pcie, pdev);
++              ret = dw_pcie_ep_init(&pci->ep);
+               if (ret < 0)
+                       goto err_get_sync;
+               break;
+diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
+index 84206f265e544..4d12efdacd2f5 100644
+--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
++++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
+@@ -18,8 +18,6 @@
+ #include "pcie-designware.h"
+-#define PCIE_DBI2_OFFSET              0x1000  /* DBI2 base address*/
+-
+ #define to_ls_pcie_ep(x)      dev_get_drvdata((x)->dev)
+ struct ls_pcie_ep_drvdata {
+@@ -124,34 +122,6 @@ static const struct of_device_id ls_pcie_ep_of_match[] = {
+       { },
+ };
+-static int __init ls_add_pcie_ep(struct ls_pcie_ep *pcie,
+-                               struct platform_device *pdev)
+-{
+-      struct dw_pcie *pci = pcie->pci;
+-      struct device *dev = pci->dev;
+-      struct dw_pcie_ep *ep;
+-      struct resource *res;
+-      int ret;
+-
+-      ep = &pci->ep;
+-      ep->ops = pcie->drvdata->ops;
+-
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
+-      if (!res)
+-              return -EINVAL;
+-
+-      ep->phys_base = res->start;
+-      ep->addr_size = resource_size(res);
+-
+-      ret = dw_pcie_ep_init(ep);
+-      if (ret) {
+-              dev_err(dev, "failed to initialize endpoint\n");
+-              return ret;
+-      }
+-
+-      return 0;
+-}
+-
+ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -159,7 +129,6 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
+       struct ls_pcie_ep *pcie;
+       struct pci_epc_features *ls_epc;
+       struct resource *dbi_base;
+-      int ret;
+       pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+       if (!pcie)
+@@ -188,13 +157,11 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
+       if (IS_ERR(pci->dbi_base))
+               return PTR_ERR(pci->dbi_base);
+-      pci->dbi_base2 = pci->dbi_base + PCIE_DBI2_OFFSET;
++      pci->ep.ops = &ls_pcie_ep_ops;
+       platform_set_drvdata(pdev, pcie);
+-      ret = ls_add_pcie_ep(pcie, pdev);
+-
+-      return ret;
++      return dw_pcie_ep_init(&pci->ep);
+ }
+ static struct platform_driver ls_pcie_ep_driver = {
+diff --git a/drivers/pci/controller/dwc/pcie-al.c b/drivers/pci/controller/dwc/pcie-al.c
+index f973fbca90cf7..d06866921187b 100644
+--- a/drivers/pci/controller/dwc/pcie-al.c
++++ b/drivers/pci/controller/dwc/pcie-al.c
+@@ -347,7 +347,6 @@ static int al_pcie_probe(struct platform_device *pdev)
+       struct device *dev = &pdev->dev;
+       struct resource *controller_res;
+       struct resource *ecam_res;
+-      struct resource *dbi_res;
+       struct al_pcie *al_pcie;
+       struct dw_pcie *pci;
+@@ -365,11 +364,6 @@ static int al_pcie_probe(struct platform_device *pdev)
+       al_pcie->pci = pci;
+       al_pcie->dev = dev;
+-      dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+-      pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_res);
+-      if (IS_ERR(pci->dbi_base))
+-              return PTR_ERR(pci->dbi_base);
+-
+       ecam_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
+       if (!ecam_res) {
+               dev_err(dev, "couldn't find 'config' reg in DT\n");
+@@ -386,8 +380,7 @@ static int al_pcie_probe(struct platform_device *pdev)
+               return PTR_ERR(al_pcie->controller_base);
+       }
+-      dev_dbg(dev, "From DT: dbi_base: %pR, controller_base: %pR\n",
+-              dbi_res, controller_res);
++      dev_dbg(dev, "From DT: controller_base: %pR\n", controller_res);
+       platform_set_drvdata(pdev, al_pcie);
+diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c
+index 929448e9e0bc6..52ad7909cd0c0 100644
+--- a/drivers/pci/controller/dwc/pcie-artpec6.c
++++ b/drivers/pci/controller/dwc/pcie-artpec6.c
+@@ -403,38 +403,6 @@ static const struct dw_pcie_ep_ops pcie_ep_ops = {
+       .raise_irq = artpec6_pcie_raise_irq,
+ };
+-static int artpec6_add_pcie_ep(struct artpec6_pcie *artpec6_pcie,
+-                             struct platform_device *pdev)
+-{
+-      int ret;
+-      struct dw_pcie_ep *ep;
+-      struct resource *res;
+-      struct device *dev = &pdev->dev;
+-      struct dw_pcie *pci = artpec6_pcie->pci;
+-
+-      ep = &pci->ep;
+-      ep->ops = &pcie_ep_ops;
+-
+-      pci->dbi_base2 = devm_platform_ioremap_resource_byname(pdev, "dbi2");
+-      if (IS_ERR(pci->dbi_base2))
+-              return PTR_ERR(pci->dbi_base2);
+-
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
+-      if (!res)
+-              return -EINVAL;
+-
+-      ep->phys_base = res->start;
+-      ep->addr_size = resource_size(res);
+-
+-      ret = dw_pcie_ep_init(ep);
+-      if (ret) {
+-              dev_err(dev, "failed to initialize endpoint\n");
+-              return ret;
+-      }
+-
+-      return 0;
+-}
+-
+ static int artpec6_pcie_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -469,10 +437,6 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
+       artpec6_pcie->variant = variant;
+       artpec6_pcie->mode = mode;
+-      pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "dbi");
+-      if (IS_ERR(pci->dbi_base))
+-              return PTR_ERR(pci->dbi_base);
+-
+       artpec6_pcie->phy_base =
+               devm_platform_ioremap_resource_byname(pdev, "phy");
+       if (IS_ERR(artpec6_pcie->phy_base))
+@@ -504,9 +468,10 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
+               val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
+               val &= ~PCIECFG_DEVICE_TYPE_MASK;
+               artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
+-              ret = artpec6_add_pcie_ep(artpec6_pcie, pdev);
+-              if (ret < 0)
+-                      return ret;
++
++              pci->ep.ops = &pcie_ep_ops;
++
++              return dw_pcie_ep_init(&pci->ep);
+               break;
+       }
+       default:
+diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
+index 95ed719402d75..ea1b8893d25fe 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
+@@ -7,6 +7,7 @@
+  */
+ #include <linux/of.h>
++#include <linux/platform_device.h>
+ #include "pcie-designware.h"
+ #include <linux/pci-epc.h>
+@@ -676,20 +677,42 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
+       int ret;
+       void *addr;
+       u8 func_no;
++      struct resource *res;
+       struct pci_epc *epc;
+       struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+       struct device *dev = pci->dev;
++      struct platform_device *pdev = to_platform_device(dev);
+       struct device_node *np = dev->of_node;
+       const struct pci_epc_features *epc_features;
+       struct dw_pcie_ep_func *ep_func;
+       INIT_LIST_HEAD(&ep->func_list);
+-      if (!pci->dbi_base || !pci->dbi_base2) {
+-              dev_err(dev, "dbi_base/dbi_base2 is not populated\n");
+-              return -EINVAL;
++      if (!pci->dbi_base) {
++              res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
++              pci->dbi_base = devm_pci_remap_cfg_resource(dev, res);
++              if (IS_ERR(pci->dbi_base))
++                      return PTR_ERR(pci->dbi_base);
++      }
++
++      if (!pci->dbi_base2) {
++              res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
++              if (!res)
++                      pci->dbi_base2 = pci->dbi_base + SZ_4K;
++              else {
++                      pci->dbi_base2 = devm_pci_remap_cfg_resource(dev, res);
++                      if (IS_ERR(pci->dbi_base2))
++                              return PTR_ERR(pci->dbi_base2);
++              }
+       }
++      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
++      if (!res)
++              return -EINVAL;
++
++      ep->phys_base = res->start;
++      ep->addr_size = resource_size(res);
++
+       ret = of_property_read_u32(np, "num-ib-windows", &ep->num_ib_windows);
+       if (ret < 0) {
+               dev_err(dev, "Unable to read *num-ib-windows* property\n");
+diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
+index 42d8116a4a002..d6b7eec1a25b0 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -310,6 +310,13 @@ int dw_pcie_host_init(struct pcie_port *pp)
+               dev_err(dev, "Missing *config* reg space\n");
+       }
++      if (!pci->dbi_base) {
++              struct resource *dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
++              pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_res);
++              if (IS_ERR(pci->dbi_base))
++                      return PTR_ERR(pci->dbi_base);
++      }
++
+       bridge = devm_pci_alloc_host_bridge(dev, 0);
+       if (!bridge)
+               return -ENOMEM;
+diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
+index e3e300669ed56..562a05e07b1d5 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
++++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
+@@ -139,43 +139,11 @@ static int dw_plat_add_pcie_port(struct dw_plat_pcie *dw_plat_pcie,
+       return 0;
+ }
+-static int dw_plat_add_pcie_ep(struct dw_plat_pcie *dw_plat_pcie,
+-                             struct platform_device *pdev)
+-{
+-      int ret;
+-      struct dw_pcie_ep *ep;
+-      struct resource *res;
+-      struct device *dev = &pdev->dev;
+-      struct dw_pcie *pci = dw_plat_pcie->pci;
+-
+-      ep = &pci->ep;
+-      ep->ops = &pcie_ep_ops;
+-
+-      pci->dbi_base2 = devm_platform_ioremap_resource_byname(pdev, "dbi2");
+-      if (IS_ERR(pci->dbi_base2))
+-              return PTR_ERR(pci->dbi_base2);
+-
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
+-      if (!res)
+-              return -EINVAL;
+-
+-      ep->phys_base = res->start;
+-      ep->addr_size = resource_size(res);
+-
+-      ret = dw_pcie_ep_init(ep);
+-      if (ret) {
+-              dev_err(dev, "Failed to initialize endpoint\n");
+-              return ret;
+-      }
+-      return 0;
+-}
+-
+ static int dw_plat_pcie_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+       struct dw_plat_pcie *dw_plat_pcie;
+       struct dw_pcie *pci;
+-      struct resource *res;  /* Resource from DT */
+       int ret;
+       const struct of_device_id *match;
+       const struct dw_plat_pcie_of_data *data;
+@@ -202,14 +170,6 @@ static int dw_plat_pcie_probe(struct platform_device *pdev)
+       dw_plat_pcie->pci = pci;
+       dw_plat_pcie->mode = mode;
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+-      if (!res)
+-              res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-
+-      pci->dbi_base = devm_ioremap_resource(dev, res);
+-      if (IS_ERR(pci->dbi_base))
+-              return PTR_ERR(pci->dbi_base);
+-
+       platform_set_drvdata(pdev, dw_plat_pcie);
+       switch (dw_plat_pcie->mode) {
+@@ -225,9 +185,8 @@ static int dw_plat_pcie_probe(struct platform_device *pdev)
+               if (!IS_ENABLED(CONFIG_PCIE_DW_PLAT_EP))
+                       return -ENODEV;
+-              ret = dw_plat_add_pcie_ep(dw_plat_pcie, pdev);
+-              if (ret < 0)
+-                      return ret;
++              pci->ep.ops = &pcie_ep_ops;
++              return dw_pcie_ep_init(&pci->ep);
+               break;
+       default:
+               dev_err(dev, "INVALID device type %d\n", dw_plat_pcie->mode);
+diff --git a/drivers/pci/controller/dwc/pcie-intel-gw.c b/drivers/pci/controller/dwc/pcie-intel-gw.c
+index 5e1a284fdc538..429171c35945d 100644
+--- a/drivers/pci/controller/dwc/pcie-intel-gw.c
++++ b/drivers/pci/controller/dwc/pcie-intel-gw.c
+@@ -236,10 +236,6 @@ static int intel_pcie_get_resources(struct platform_device *pdev)
+       struct device *dev = pci->dev;
+       int ret;
+-      pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "dbi");
+-      if (IS_ERR(pci->dbi_base))
+-              return PTR_ERR(pci->dbi_base);
+-
+       lpp->core_clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(lpp->core_clk)) {
+               ret = PTR_ERR(lpp->core_clk);
+diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c
+index d0a6a2dee6f5b..3042a23cf09a4 100644
+--- a/drivers/pci/controller/dwc/pcie-kirin.c
++++ b/drivers/pci/controller/dwc/pcie-kirin.c
+@@ -157,11 +157,6 @@ static long kirin_pcie_get_resource(struct kirin_pcie *kirin_pcie,
+       if (IS_ERR(kirin_pcie->phy_base))
+               return PTR_ERR(kirin_pcie->phy_base);
+-      kirin_pcie->pci->dbi_base =
+-              devm_platform_ioremap_resource_byname(pdev, "dbi");
+-      if (IS_ERR(kirin_pcie->pci->dbi_base))
+-              return PTR_ERR(kirin_pcie->pci->dbi_base);
+-
+       kirin_pcie->crgctrl =
+               syscon_regmap_lookup_by_compatible("hisilicon,hi3660-crgctrl");
+       if (IS_ERR(kirin_pcie->crgctrl))
+diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
+index c68e14271c02c..150dd6fe7ba39 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -1360,7 +1360,6 @@ static const struct dw_pcie_ops dw_pcie_ops = {
+ static int qcom_pcie_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+-      struct resource *res;
+       struct pcie_port *pp;
+       struct dw_pcie *pci;
+       struct qcom_pcie *pcie;
+@@ -1399,13 +1398,6 @@ static int qcom_pcie_probe(struct platform_device *pdev)
+               goto err_pm_runtime_put;
+       }
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+-      pci->dbi_base = devm_pci_remap_cfg_resource(dev, res);
+-      if (IS_ERR(pci->dbi_base)) {
+-              ret = PTR_ERR(pci->dbi_base);
+-              goto err_pm_runtime_put;
+-      }
+-
+       pcie->elbi = devm_platform_ioremap_resource_byname(pdev, "elbi");
+       if (IS_ERR(pcie->elbi)) {
+               ret = PTR_ERR(pcie->elbi);
+diff --git a/drivers/pci/controller/dwc/pcie-spear13xx.c b/drivers/pci/controller/dwc/pcie-spear13xx.c
+index e348225f651fb..1ed7e3501ff1c 100644
+--- a/drivers/pci/controller/dwc/pcie-spear13xx.c
++++ b/drivers/pci/controller/dwc/pcie-spear13xx.c
+@@ -152,6 +152,8 @@ static int spear13xx_pcie_host_init(struct pcie_port *pp)
+       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+       struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pci);
++      spear13xx_pcie->app_base = pci->dbi_base + 0x2000;
++
+       spear13xx_pcie_establish_link(spear13xx_pcie);
+       spear13xx_pcie_enable_interrupts(spear13xx_pcie);
+@@ -203,7 +205,6 @@ static int spear13xx_pcie_probe(struct platform_device *pdev)
+       struct dw_pcie *pci;
+       struct spear13xx_pcie *spear13xx_pcie;
+       struct device_node *np = dev->of_node;
+-      struct resource *dbi_base;
+       int ret;
+       spear13xx_pcie = devm_kzalloc(dev, sizeof(*spear13xx_pcie), GFP_KERNEL);
+@@ -242,14 +243,6 @@ static int spear13xx_pcie_probe(struct platform_device *pdev)
+               return ret;
+       }
+-      dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+-      pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base);
+-      if (IS_ERR(pci->dbi_base)) {
+-              ret = PTR_ERR(pci->dbi_base);
+-              goto fail_clk;
+-      }
+-      spear13xx_pcie->app_base = pci->dbi_base + 0x2000;
+-
+       if (of_property_read_bool(np, "st,pcie-is-gen1"))
+               pci->link_gen = 1;
+diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
+index 80c2015b49d8f..825cb65945fba 100644
+--- a/drivers/pci/controller/dwc/pcie-tegra194.c
++++ b/drivers/pci/controller/dwc/pcie-tegra194.c
+@@ -1913,19 +1913,12 @@ static int tegra_pcie_config_ep(struct tegra_pcie_dw *pcie,
+       struct dw_pcie *pci = &pcie->pci;
+       struct device *dev = pcie->dev;
+       struct dw_pcie_ep *ep;
+-      struct resource *res;
+       char *name;
+       int ret;
+       ep = &pci->ep;
+       ep->ops = &pcie_ep_ops;
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
+-      if (!res)
+-              return -EINVAL;
+-
+-      ep->phys_base = res->start;
+-      ep->addr_size = resource_size(res);
+       ep->page_size = SZ_64K;
+       ret = gpiod_set_debounce(pcie->pex_rst_gpiod, PERST_DEBOUNCE_TIME);
+@@ -1989,7 +1982,6 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)
+       struct device *dev = &pdev->dev;
+       struct resource *atu_dma_res;
+       struct tegra_pcie_dw *pcie;
+-      struct resource *dbi_res;
+       struct pcie_port *pp;
+       struct dw_pcie *pci;
+       struct phy **phys;
+@@ -2098,20 +2090,6 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)
+       pcie->phys = phys;
+-      dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+-      if (!dbi_res) {
+-              dev_err(dev, "Failed to find \"dbi\" region\n");
+-              return -ENODEV;
+-      }
+-      pcie->dbi_res = dbi_res;
+-
+-      pci->dbi_base = devm_ioremap_resource(dev, dbi_res);
+-      if (IS_ERR(pci->dbi_base))
+-              return PTR_ERR(pci->dbi_base);
+-
+-      /* Tegra HW locates DBI2 at a fixed offset from DBI */
+-      pci->dbi_base2 = pci->dbi_base + 0x1000;
+-
+       atu_dma_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                                  "atu_dma");
+       if (!atu_dma_res) {
+diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
+index 1483559600610..69810c6b0d584 100644
+--- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c
++++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
+@@ -218,35 +218,6 @@ static const struct dw_pcie_ep_ops uniphier_pcie_ep_ops = {
+       .get_features = uniphier_pcie_get_features,
+ };
+-static int uniphier_add_pcie_ep(struct uniphier_pcie_ep_priv *priv,
+-                              struct platform_device *pdev)
+-{
+-      struct dw_pcie *pci = &priv->pci;
+-      struct dw_pcie_ep *ep = &pci->ep;
+-      struct device *dev = &pdev->dev;
+-      struct resource *res;
+-      int ret;
+-
+-      ep->ops = &uniphier_pcie_ep_ops;
+-
+-      pci->dbi_base2 = devm_platform_ioremap_resource_byname(pdev, "dbi2");
+-      if (IS_ERR(pci->dbi_base2))
+-              return PTR_ERR(pci->dbi_base2);
+-
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
+-      if (!res)
+-              return -EINVAL;
+-
+-      ep->phys_base = res->start;
+-      ep->addr_size = resource_size(res);
+-
+-      ret = dw_pcie_ep_init(ep);
+-      if (ret)
+-              dev_err(dev, "Failed to initialize endpoint (%d)\n", ret);
+-
+-      return ret;
+-}
+-
+ static int uniphier_pcie_ep_enable(struct uniphier_pcie_ep_priv *priv)
+ {
+       int ret;
+@@ -300,7 +271,6 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+       struct uniphier_pcie_ep_priv *priv;
+-      struct resource *res;
+       int ret;
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+@@ -314,11 +284,6 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)
+       priv->pci.dev = dev;
+       priv->pci.ops = &dw_pcie_ops;
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+-      priv->pci.dbi_base = devm_pci_remap_cfg_resource(dev, res);
+-      if (IS_ERR(priv->pci.dbi_base))
+-              return PTR_ERR(priv->pci.dbi_base);
+-
+       priv->base = devm_platform_ioremap_resource_byname(pdev, "link");
+       if (IS_ERR(priv->base))
+               return PTR_ERR(priv->base);
+@@ -352,7 +317,8 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)
+       if (ret)
+               return ret;
+-      return uniphier_add_pcie_ep(priv, pdev);
++      priv->pci.ep.ops = &uniphier_pcie_ep_ops;
++      return dw_pcie_ep_init(&priv->pci.ep);
+ }
+ static const struct pci_epc_features uniphier_pro5_data = {
+diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
+index 527ec8aeb602f..85bf170e93541 100644
+--- a/drivers/pci/controller/dwc/pcie-uniphier.c
++++ b/drivers/pci/controller/dwc/pcie-uniphier.c
+@@ -394,7 +394,6 @@ static int uniphier_pcie_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+       struct uniphier_pcie_priv *priv;
+-      struct resource *res;
+       int ret;
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+@@ -404,11 +403,6 @@ static int uniphier_pcie_probe(struct platform_device *pdev)
+       priv->pci.dev = dev;
+       priv->pci.ops = &dw_pcie_ops;
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+-      priv->pci.dbi_base = devm_pci_remap_cfg_resource(dev, res);
+-      if (IS_ERR(priv->pci.dbi_base))
+-              return PTR_ERR(priv->pci.dbi_base);
+-
+       priv->base = devm_platform_ioremap_resource_byname(pdev, "link");
+       if (IS_ERR(priv->base))
+               return PTR_ERR(priv->base);
+-- 
+2.42.0
+
diff --git a/queue-5.10/pci-dwc-move-dw_pcie_msi_init-into-core.patch b/queue-5.10/pci-dwc-move-dw_pcie_msi_init-into-core.patch
new file mode 100644 (file)
index 0000000..33367c4
--- /dev/null
@@ -0,0 +1,309 @@
+From 991c38cf974a9c07aaa5c25b35d535adee2ed41d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Nov 2020 15:11:54 -0600
+Subject: PCI: dwc: Move dw_pcie_msi_init() into core
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit 59fbab1ae40eb048eb2bd2385a5b981051513458 ]
+
+The host drivers which call dw_pcie_msi_init() are all the ones using
+the built-in MSI controller, so let's move it into the common DWC code.
+
+Link: https://lore.kernel.org/r/20201105211159.1814485-12-robh@kernel.org
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Jingoo Han <jingoohan1@gmail.com>
+Cc: Kishon Vijay Abraham I <kishon@ti.com>
+Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Kukjin Kim <kgene@kernel.org>
+Cc: Krzysztof Kozlowski <krzk@kernel.org>
+Cc: Richard Zhu <hongxing.zhu@nxp.com>
+Cc: Lucas Stach <l.stach@pengutronix.de>
+Cc: Shawn Guo <shawnguo@kernel.org>
+Cc: Sascha Hauer <s.hauer@pengutronix.de>
+Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
+Cc: Fabio Estevam <festevam@gmail.com>
+Cc: NXP Linux Team <linux-imx@nxp.com>
+Cc: Yue Wang <yue.wang@Amlogic.com>
+Cc: Kevin Hilman <khilman@baylibre.com>
+Cc: Neil Armstrong <narmstrong@baylibre.com>
+Cc: Jerome Brunet <jbrunet@baylibre.com>
+Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Cc: Jesper Nilsson <jesper.nilsson@axis.com>
+Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Cc: Xiaowei Song <songxiaowei@hisilicon.com>
+Cc: Binghui Wang <wangbinghui@hisilicon.com>
+Cc: Stanimir Varbanov <svarbanov@mm-sol.com>
+Cc: Andy Gross <agross@kernel.org>
+Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
+Cc: Pratyush Anand <pratyush.anand@gmail.com>
+Cc: Thierry Reding <thierry.reding@gmail.com>
+Cc: Jonathan Hunter <jonathanh@nvidia.com>
+Cc: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
+Cc: linux-omap@vger.kernel.org
+Cc: linux-samsung-soc@vger.kernel.org
+Cc: linux-amlogic@lists.infradead.org
+Cc: linux-arm-kernel@axis.com
+Cc: linux-arm-msm@vger.kernel.org
+Cc: linux-tegra@vger.kernel.org
+Stable-dep-of: 83a939f0fdc2 ("PCI: exynos: Don't discard .remove() callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pci-dra7xx.c           |  2 --
+ drivers/pci/controller/dwc/pci-exynos.c           |  4 ----
+ drivers/pci/controller/dwc/pci-imx6.c             |  1 -
+ drivers/pci/controller/dwc/pci-meson.c            |  1 -
+ drivers/pci/controller/dwc/pcie-artpec6.c         |  1 -
+ drivers/pci/controller/dwc/pcie-designware-host.c |  9 +++++----
+ drivers/pci/controller/dwc/pcie-designware-plat.c |  1 -
+ drivers/pci/controller/dwc/pcie-designware.h      | 10 ----------
+ drivers/pci/controller/dwc/pcie-histb.c           |  2 --
+ drivers/pci/controller/dwc/pcie-kirin.c           |  1 -
+ drivers/pci/controller/dwc/pcie-qcom.c            |  2 --
+ drivers/pci/controller/dwc/pcie-spear13xx.c       |  6 +-----
+ drivers/pci/controller/dwc/pcie-tegra194.c        |  2 --
+ drivers/pci/controller/dwc/pcie-uniphier.c        |  1 -
+ 14 files changed, 6 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
+index 054423d9646d6..72a5a2bf933bc 100644
+--- a/drivers/pci/controller/dwc/pci-dra7xx.c
++++ b/drivers/pci/controller/dwc/pci-dra7xx.c
+@@ -182,8 +182,6 @@ static int dra7xx_pcie_host_init(struct pcie_port *pp)
+       struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
+       dw_pcie_setup_rc(pp);
+-
+-      dw_pcie_msi_init(pp);
+       dra7xx_pcie_enable_interrupts(dra7xx);
+       return 0;
+diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
+index 6498b615c834a..3939fe22e8a20 100644
+--- a/drivers/pci/controller/dwc/pci-exynos.c
++++ b/drivers/pci/controller/dwc/pci-exynos.c
+@@ -273,12 +273,8 @@ static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg)
+ static void exynos_pcie_msi_init(struct exynos_pcie *ep)
+ {
+-      struct dw_pcie *pci = ep->pci;
+-      struct pcie_port *pp = &pci->pp;
+       u32 val;
+-      dw_pcie_msi_init(pp);
+-
+       /* enable MSI interrupt */
+       val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_IRQ_EN_LEVEL);
+       val |= IRQ_MSI_ENABLE;
+diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
+index 8d1d2d79693d6..dbdf79ac48683 100644
+--- a/drivers/pci/controller/dwc/pci-imx6.c
++++ b/drivers/pci/controller/dwc/pci-imx6.c
+@@ -840,7 +840,6 @@ static int imx6_pcie_host_init(struct pcie_port *pp)
+       imx6_pcie_deassert_core_reset(imx6_pcie);
+       imx6_setup_phy_mpll(imx6_pcie);
+       dw_pcie_setup_rc(pp);
+-      dw_pcie_msi_init(pp);
+       return 0;
+ }
+diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c
+index 41a3351b100b5..2df0adcf0bf22 100644
+--- a/drivers/pci/controller/dwc/pci-meson.c
++++ b/drivers/pci/controller/dwc/pci-meson.c
+@@ -381,7 +381,6 @@ static int meson_pcie_host_init(struct pcie_port *pp)
+       meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);
+       dw_pcie_setup_rc(pp);
+-      dw_pcie_msi_init(pp);
+       return 0;
+ }
+diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c
+index 8b3da3038ac35..7ee8f3c83f8f3 100644
+--- a/drivers/pci/controller/dwc/pcie-artpec6.c
++++ b/drivers/pci/controller/dwc/pcie-artpec6.c
+@@ -329,7 +329,6 @@ static int artpec6_pcie_host_init(struct pcie_port *pp)
+       artpec6_pcie_deassert_core_reset(artpec6_pcie);
+       artpec6_pcie_wait_for_phy(artpec6_pcie);
+       dw_pcie_setup_rc(pp);
+-      dw_pcie_msi_init(pp);
+       return 0;
+ }
+diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
+index b242d7e64c204..e740cbeda2bbc 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -256,7 +256,7 @@ int dw_pcie_allocate_domains(struct pcie_port *pp)
+       return 0;
+ }
+-void dw_pcie_free_msi(struct pcie_port *pp)
++static void dw_pcie_free_msi(struct pcie_port *pp)
+ {
+       if (pp->msi_irq) {
+               irq_set_chained_handler(pp->msi_irq, NULL);
+@@ -275,19 +275,18 @@ void dw_pcie_free_msi(struct pcie_port *pp)
+       }
+ }
+-void dw_pcie_msi_init(struct pcie_port *pp)
++static void dw_pcie_msi_init(struct pcie_port *pp)
+ {
+       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+       u64 msi_target = (u64)pp->msi_data;
+-      if (!IS_ENABLED(CONFIG_PCI_MSI))
++      if (!pci_msi_enabled() || !pp->has_msi_ctrl)
+               return;
+       /* Program the msi_data */
+       dw_pcie_writel_dbi(pci, PCIE_MSI_ADDR_LO, lower_32_bits(msi_target));
+       dw_pcie_writel_dbi(pci, PCIE_MSI_ADDR_HI, upper_32_bits(msi_target));
+ }
+-EXPORT_SYMBOL_GPL(dw_pcie_msi_init);
+ int dw_pcie_host_init(struct pcie_port *pp)
+ {
+@@ -424,6 +423,8 @@ int dw_pcie_host_init(struct pcie_port *pp)
+                       goto err_free_msi;
+       }
++      dw_pcie_msi_init(pp);
++
+       if (!dw_pcie_link_up(pci) && pci->ops->start_link) {
+               ret = pci->ops->start_link(pci);
+               if (ret)
+diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
+index adebcaeb1a6c0..dec24e595c3e0 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
++++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
+@@ -36,7 +36,6 @@ static const struct of_device_id dw_plat_pcie_of_match[];
+ static int dw_plat_pcie_host_init(struct pcie_port *pp)
+ {
+       dw_pcie_setup_rc(pp);
+-      dw_pcie_msi_init(pp);
+       return 0;
+ }
+diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
+index f33dc89a93650..04c61e2e23d07 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.h
++++ b/drivers/pci/controller/dwc/pcie-designware.h
+@@ -365,8 +365,6 @@ static inline void dw_pcie_dbi_ro_wr_dis(struct dw_pcie *pci)
+ #ifdef CONFIG_PCIE_DW_HOST
+ irqreturn_t dw_handle_msi_irq(struct pcie_port *pp);
+-void dw_pcie_msi_init(struct pcie_port *pp);
+-void dw_pcie_free_msi(struct pcie_port *pp);
+ void dw_pcie_setup_rc(struct pcie_port *pp);
+ int dw_pcie_host_init(struct pcie_port *pp);
+ void dw_pcie_host_deinit(struct pcie_port *pp);
+@@ -379,14 +377,6 @@ static inline irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)
+       return IRQ_NONE;
+ }
+-static inline void dw_pcie_msi_init(struct pcie_port *pp)
+-{
+-}
+-
+-static inline void dw_pcie_free_msi(struct pcie_port *pp)
+-{
+-}
+-
+ static inline void dw_pcie_setup_rc(struct pcie_port *pp)
+ {
+ }
+diff --git a/drivers/pci/controller/dwc/pcie-histb.c b/drivers/pci/controller/dwc/pcie-histb.c
+index ece544165059b..210777c793ea0 100644
+--- a/drivers/pci/controller/dwc/pcie-histb.c
++++ b/drivers/pci/controller/dwc/pcie-histb.c
+@@ -199,8 +199,6 @@ static int histb_pcie_host_init(struct pcie_port *pp)
+       /* setup root complex */
+       dw_pcie_setup_rc(pp);
+-      dw_pcie_msi_init(pp);
+-
+       return 0;
+ }
+diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c
+index 675b4d8392d37..f84ac1b36b2cc 100644
+--- a/drivers/pci/controller/dwc/pcie-kirin.c
++++ b/drivers/pci/controller/dwc/pcie-kirin.c
+@@ -406,7 +406,6 @@ static int kirin_pcie_host_init(struct pcie_port *pp)
+       pp->bridge->ops = &kirin_pci_ops;
+       dw_pcie_setup_rc(pp);
+-      dw_pcie_msi_init(pp);
+       return 0;
+ }
+diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
+index 03251e34137f3..b482264541bc2 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -1273,8 +1273,6 @@ static int qcom_pcie_host_init(struct pcie_port *pp)
+       }
+       dw_pcie_setup_rc(pp);
+-      dw_pcie_msi_init(pp);
+-
+       qcom_ep_reset_deassert(pcie);
+       return 0;
+diff --git a/drivers/pci/controller/dwc/pcie-spear13xx.c b/drivers/pci/controller/dwc/pcie-spear13xx.c
+index ebbaa06fc8ab5..31475e4493a70 100644
+--- a/drivers/pci/controller/dwc/pcie-spear13xx.c
++++ b/drivers/pci/controller/dwc/pcie-spear13xx.c
+@@ -102,16 +102,12 @@ static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg)
+ static void spear13xx_pcie_enable_interrupts(struct spear13xx_pcie *spear13xx_pcie)
+ {
+-      struct dw_pcie *pci = spear13xx_pcie->pci;
+-      struct pcie_port *pp = &pci->pp;
+       struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
+       /* Enable MSI interrupt */
+-      if (IS_ENABLED(CONFIG_PCI_MSI)) {
+-              dw_pcie_msi_init(pp);
++      if (IS_ENABLED(CONFIG_PCI_MSI))
+               writel(readl(&app_reg->int_mask) |
+                               MSI_CTRL_INT, &app_reg->int_mask);
+-      }
+ }
+ static int spear13xx_pcie_link_up(struct dw_pcie *pci)
+diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
+index 782aa3f382829..e5cd9751e6e8c 100644
+--- a/drivers/pci/controller/dwc/pcie-tegra194.c
++++ b/drivers/pci/controller/dwc/pcie-tegra194.c
+@@ -767,8 +767,6 @@ static void tegra_pcie_enable_msi_interrupts(struct pcie_port *pp)
+       struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
+       u32 val;
+-      dw_pcie_msi_init(pp);
+-
+       /* Enable MSI interrupt generation */
+       val = appl_readl(pcie, APPL_INTR_EN_L0_0);
+       val |= APPL_INTR_EN_L0_0_SYS_MSI_INTR_EN;
+diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
+index bd4bf2db9480e..83f545b326003 100644
+--- a/drivers/pci/controller/dwc/pcie-uniphier.c
++++ b/drivers/pci/controller/dwc/pcie-uniphier.c
+@@ -309,7 +309,6 @@ static int uniphier_pcie_host_init(struct pcie_port *pp)
+       uniphier_pcie_irq_enable(priv);
+       dw_pcie_setup_rc(pp);
+-      dw_pcie_msi_init(pp);
+       return 0;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.10/pci-dwc-move-dw_pcie_setup_rc-to-dwc-common-code.patch b/queue-5.10/pci-dwc-move-dw_pcie_setup_rc-to-dwc-common-code.patch
new file mode 100644 (file)
index 0000000..6c2fad7
--- /dev/null
@@ -0,0 +1,278 @@
+From 84fe8050a0a03887401d8a144590419e08fd6410 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Nov 2020 15:11:55 -0600
+Subject: PCI: dwc: Move dw_pcie_setup_rc() to DWC common code
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit b9ac0f9dc8ea4b91362694e82a1e66313a6c6dc6 ]
+
+All RC complex drivers must call dw_pcie_setup_rc(). The ordering of the
+call shouldn't be too important other than being after any RC resets.
+
+There's a few calls of dw_pcie_setup_rc() left as drivers implementing
+suspend/resume need it.
+
+Link: https://lore.kernel.org/r/20201105211159.1814485-13-robh@kernel.org
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Jingoo Han <jingoohan1@gmail.com>
+Cc: Kishon Vijay Abraham I <kishon@ti.com>
+Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Kukjin Kim <kgene@kernel.org>
+Cc: Krzysztof Kozlowski <krzk@kernel.org>
+Cc: Richard Zhu <hongxing.zhu@nxp.com>
+Cc: Lucas Stach <l.stach@pengutronix.de>
+Cc: Shawn Guo <shawnguo@kernel.org>
+Cc: Sascha Hauer <s.hauer@pengutronix.de>
+Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
+Cc: Fabio Estevam <festevam@gmail.com>
+Cc: NXP Linux Team <linux-imx@nxp.com>
+Cc: Murali Karicheri <m-karicheri2@ti.com>
+Cc: Minghuan Lian <minghuan.Lian@nxp.com>
+Cc: Mingkai Hu <mingkai.hu@nxp.com>
+Cc: Roy Zang <roy.zang@nxp.com>
+Cc: Yue Wang <yue.wang@Amlogic.com>
+Cc: Kevin Hilman <khilman@baylibre.com>
+Cc: Neil Armstrong <narmstrong@baylibre.com>
+Cc: Jerome Brunet <jbrunet@baylibre.com>
+Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+Cc: Jesper Nilsson <jesper.nilsson@axis.com>
+Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Cc: Xiaowei Song <songxiaowei@hisilicon.com>
+Cc: Binghui Wang <wangbinghui@hisilicon.com>
+Cc: Andy Gross <agross@kernel.org>
+Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
+Cc: Stanimir Varbanov <svarbanov@mm-sol.com>
+Cc: Pratyush Anand <pratyush.anand@gmail.com>
+Cc: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
+Cc: linux-omap@vger.kernel.org
+Cc: linux-samsung-soc@vger.kernel.org
+Cc: linuxppc-dev@lists.ozlabs.org
+Cc: linux-amlogic@lists.infradead.org
+Cc: linux-arm-kernel@axis.com
+Cc: linux-arm-msm@vger.kernel.org
+Stable-dep-of: 83a939f0fdc2 ("PCI: exynos: Don't discard .remove() callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pci-dra7xx.c           | 1 -
+ drivers/pci/controller/dwc/pci-exynos.c           | 1 -
+ drivers/pci/controller/dwc/pci-imx6.c             | 1 -
+ drivers/pci/controller/dwc/pci-keystone.c         | 2 --
+ drivers/pci/controller/dwc/pci-layerscape.c       | 2 --
+ drivers/pci/controller/dwc/pci-meson.c            | 2 --
+ drivers/pci/controller/dwc/pcie-armada8k.c        | 2 --
+ drivers/pci/controller/dwc/pcie-artpec6.c         | 1 -
+ drivers/pci/controller/dwc/pcie-designware-host.c | 1 +
+ drivers/pci/controller/dwc/pcie-designware-plat.c | 8 --------
+ drivers/pci/controller/dwc/pcie-histb.c           | 3 ---
+ drivers/pci/controller/dwc/pcie-kirin.c           | 2 --
+ drivers/pci/controller/dwc/pcie-qcom.c            | 1 -
+ drivers/pci/controller/dwc/pcie-spear13xx.c       | 2 --
+ drivers/pci/controller/dwc/pcie-uniphier.c        | 2 --
+ 15 files changed, 1 insertion(+), 30 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
+index 72a5a2bf933bc..b105af63854a3 100644
+--- a/drivers/pci/controller/dwc/pci-dra7xx.c
++++ b/drivers/pci/controller/dwc/pci-dra7xx.c
+@@ -181,7 +181,6 @@ static int dra7xx_pcie_host_init(struct pcie_port *pp)
+       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+       struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
+-      dw_pcie_setup_rc(pp);
+       dra7xx_pcie_enable_interrupts(dra7xx);
+       return 0;
+diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
+index 3939fe22e8a20..5c10a5432896c 100644
+--- a/drivers/pci/controller/dwc/pci-exynos.c
++++ b/drivers/pci/controller/dwc/pci-exynos.c
+@@ -372,7 +372,6 @@ static int exynos_pcie_host_init(struct pcie_port *pp)
+       phy_init(ep->phy);
+       exynos_pcie_deassert_core_reset(ep);
+-      dw_pcie_setup_rc(pp);
+       exynos_pcie_assert_reset(ep);
+       exynos_pcie_enable_interrupts(ep);
+diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
+index dbdf79ac48683..67f06060f7a48 100644
+--- a/drivers/pci/controller/dwc/pci-imx6.c
++++ b/drivers/pci/controller/dwc/pci-imx6.c
+@@ -839,7 +839,6 @@ static int imx6_pcie_host_init(struct pcie_port *pp)
+       imx6_pcie_init_phy(imx6_pcie);
+       imx6_pcie_deassert_core_reset(imx6_pcie);
+       imx6_setup_phy_mpll(imx6_pcie);
+-      dw_pcie_setup_rc(pp);
+       return 0;
+ }
+diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
+index a5db966f6d20b..c3891a6b96123 100644
+--- a/drivers/pci/controller/dwc/pci-keystone.c
++++ b/drivers/pci/controller/dwc/pci-keystone.c
+@@ -808,8 +808,6 @@ static int __init ks_pcie_host_init(struct pcie_port *pp)
+       if (ret)
+               return ret;
+-      dw_pcie_setup_rc(pp);
+-
+       ks_pcie_stop_link(pci);
+       ks_pcie_setup_rc_app_regs(ks_pcie);
+       writew(PCI_IO_RANGE_TYPE_32 | (PCI_IO_RANGE_TYPE_32 << 8),
+diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c
+index 4d280b940f1fe..5d325e8acb361 100644
+--- a/drivers/pci/controller/dwc/pci-layerscape.c
++++ b/drivers/pci/controller/dwc/pci-layerscape.c
+@@ -150,8 +150,6 @@ static int ls_pcie_host_init(struct pcie_port *pp)
+       ls_pcie_drop_msg_tlp(pcie);
+-      dw_pcie_setup_rc(pp);
+-
+       return 0;
+ }
+diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c
+index 2df0adcf0bf22..04589f0decb23 100644
+--- a/drivers/pci/controller/dwc/pci-meson.c
++++ b/drivers/pci/controller/dwc/pci-meson.c
+@@ -380,8 +380,6 @@ static int meson_pcie_host_init(struct pcie_port *pp)
+       meson_set_max_payload(mp, MAX_PAYLOAD_SIZE);
+       meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);
+-      dw_pcie_setup_rc(pp);
+-
+       return 0;
+ }
+diff --git a/drivers/pci/controller/dwc/pcie-armada8k.c b/drivers/pci/controller/dwc/pcie-armada8k.c
+index dd2926bbb9017..4e2552dcf9827 100644
+--- a/drivers/pci/controller/dwc/pcie-armada8k.c
++++ b/drivers/pci/controller/dwc/pcie-armada8k.c
+@@ -171,8 +171,6 @@ static int armada8k_pcie_host_init(struct pcie_port *pp)
+       u32 reg;
+       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+-      dw_pcie_setup_rc(pp);
+-
+       if (!dw_pcie_link_up(pci)) {
+               /* Disable LTSSM state machine to enable configuration */
+               reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_CONTROL_REG);
+diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c
+index 7ee8f3c83f8f3..fcba9915a6067 100644
+--- a/drivers/pci/controller/dwc/pcie-artpec6.c
++++ b/drivers/pci/controller/dwc/pcie-artpec6.c
+@@ -328,7 +328,6 @@ static int artpec6_pcie_host_init(struct pcie_port *pp)
+       artpec6_pcie_init_phy(artpec6_pcie);
+       artpec6_pcie_deassert_core_reset(artpec6_pcie);
+       artpec6_pcie_wait_for_phy(artpec6_pcie);
+-      dw_pcie_setup_rc(pp);
+       return 0;
+ }
+diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
+index e740cbeda2bbc..44eccd9d956f4 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -423,6 +423,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
+                       goto err_free_msi;
+       }
++      dw_pcie_setup_rc(pp);
+       dw_pcie_msi_init(pp);
+       if (!dw_pcie_link_up(pci) && pci->ops->start_link) {
+diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
+index dec24e595c3e0..9b397c807261c 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
++++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
+@@ -33,15 +33,7 @@ struct dw_plat_pcie_of_data {
+ static const struct of_device_id dw_plat_pcie_of_match[];
+-static int dw_plat_pcie_host_init(struct pcie_port *pp)
+-{
+-      dw_pcie_setup_rc(pp);
+-
+-      return 0;
+-}
+-
+ static const struct dw_pcie_host_ops dw_plat_pcie_host_ops = {
+-      .host_init = dw_plat_pcie_host_init,
+ };
+ static int dw_plat_pcie_establish_link(struct dw_pcie *pci)
+diff --git a/drivers/pci/controller/dwc/pcie-histb.c b/drivers/pci/controller/dwc/pcie-histb.c
+index 210777c793ea0..86f9d16c50d75 100644
+--- a/drivers/pci/controller/dwc/pcie-histb.c
++++ b/drivers/pci/controller/dwc/pcie-histb.c
+@@ -196,9 +196,6 @@ static int histb_pcie_host_init(struct pcie_port *pp)
+       regval |= PCIE_WM_RC;
+       histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, regval);
+-      /* setup root complex */
+-      dw_pcie_setup_rc(pp);
+-
+       return 0;
+ }
+diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c
+index f84ac1b36b2cc..ac4bbdaf53245 100644
+--- a/drivers/pci/controller/dwc/pcie-kirin.c
++++ b/drivers/pci/controller/dwc/pcie-kirin.c
+@@ -405,8 +405,6 @@ static int kirin_pcie_host_init(struct pcie_port *pp)
+ {
+       pp->bridge->ops = &kirin_pci_ops;
+-      dw_pcie_setup_rc(pp);
+-
+       return 0;
+ }
+diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
+index b482264541bc2..28608f6ef9755 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -1272,7 +1272,6 @@ static int qcom_pcie_host_init(struct pcie_port *pp)
+                       goto err_disable_phy;
+       }
+-      dw_pcie_setup_rc(pp);
+       qcom_ep_reset_deassert(pcie);
+       return 0;
+diff --git a/drivers/pci/controller/dwc/pcie-spear13xx.c b/drivers/pci/controller/dwc/pcie-spear13xx.c
+index 31475e4493a70..1a9e353bef554 100644
+--- a/drivers/pci/controller/dwc/pcie-spear13xx.c
++++ b/drivers/pci/controller/dwc/pcie-spear13xx.c
+@@ -130,8 +130,6 @@ static int spear13xx_pcie_host_init(struct pcie_port *pp)
+       spear13xx_pcie->app_base = pci->dbi_base + 0x2000;
+-      dw_pcie_setup_rc(pp);
+-
+       /*
+        * this controller support only 128 bytes read size, however its
+        * default value in capability register is 512 bytes. So force
+diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
+index 83f545b326003..680950a202dd9 100644
+--- a/drivers/pci/controller/dwc/pcie-uniphier.c
++++ b/drivers/pci/controller/dwc/pcie-uniphier.c
+@@ -308,8 +308,6 @@ static int uniphier_pcie_host_init(struct pcie_port *pp)
+       uniphier_pcie_irq_enable(priv);
+-      dw_pcie_setup_rc(pp);
+-
+       return 0;
+ }
+-- 
+2.42.0
+
diff --git a/queue-5.10/pci-dwc-move-link-handling-into-common-code.patch b/queue-5.10/pci-dwc-move-link-handling-into-common-code.patch
new file mode 100644 (file)
index 0000000..412739a
--- /dev/null
@@ -0,0 +1,723 @@
+From 709ce1bab4115f2f008a8db0a05d14a9803e9727 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Nov 2020 15:11:53 -0600
+Subject: PCI: dwc: Move link handling into common code
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit 886a9c1347558f0568e87fbbe7bcc3a76102bf0b ]
+
+All the DWC drivers do link setup and checks at roughly the same time.
+Let's use the existing .start_link() hook (currently only used in EP
+mode) and move the link handling to the core code.
+
+The behavior for a link down was inconsistent as some drivers would fail
+probe in that case while others succeed. Let's standardize this to
+succeed as there are usecases where devices (and the link) appear later
+even without hotplug. For example, a reconfigured FPGA device.
+
+Link: https://lore.kernel.org/r/20201105211159.1814485-11-robh@kernel.org
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Jingoo Han <jingoohan1@gmail.com>
+Cc: Kishon Vijay Abraham I <kishon@ti.com>
+Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Kukjin Kim <kgene@kernel.org>
+Cc: Krzysztof Kozlowski <krzk@kernel.org>
+Cc: Richard Zhu <hongxing.zhu@nxp.com>
+Cc: Lucas Stach <l.stach@pengutronix.de>
+Cc: Shawn Guo <shawnguo@kernel.org>
+Cc: Sascha Hauer <s.hauer@pengutronix.de>
+Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
+Cc: Fabio Estevam <festevam@gmail.com>
+Cc: NXP Linux Team <linux-imx@nxp.com>
+Cc: Murali Karicheri <m-karicheri2@ti.com>
+Cc: Yue Wang <yue.wang@Amlogic.com>
+Cc: Kevin Hilman <khilman@baylibre.com>
+Cc: Neil Armstrong <narmstrong@baylibre.com>
+Cc: Jerome Brunet <jbrunet@baylibre.com>
+Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+Cc: Jesper Nilsson <jesper.nilsson@axis.com>
+Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Cc: Xiaowei Song <songxiaowei@hisilicon.com>
+Cc: Binghui Wang <wangbinghui@hisilicon.com>
+Cc: Andy Gross <agross@kernel.org>
+Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
+Cc: Stanimir Varbanov <svarbanov@mm-sol.com>
+Cc: Pratyush Anand <pratyush.anand@gmail.com>
+Cc: Thierry Reding <thierry.reding@gmail.com>
+Cc: Jonathan Hunter <jonathanh@nvidia.com>
+Cc: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
+Cc: linux-omap@vger.kernel.org
+Cc: linux-samsung-soc@vger.kernel.org
+Cc: linux-amlogic@lists.infradead.org
+Cc: linux-arm-kernel@axis.com
+Cc: linux-arm-msm@vger.kernel.org
+Cc: linux-tegra@vger.kernel.org
+Stable-dep-of: 83a939f0fdc2 ("PCI: exynos: Don't discard .remove() callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pci-dra7xx.c       |  2 -
+ drivers/pci/controller/dwc/pci-exynos.c       | 41 +++++++----------
+ drivers/pci/controller/dwc/pci-imx6.c         |  9 ++--
+ drivers/pci/controller/dwc/pci-keystone.c     |  9 ----
+ drivers/pci/controller/dwc/pci-meson.c        | 24 ++++------
+ drivers/pci/controller/dwc/pcie-armada8k.c    | 39 +++++++---------
+ drivers/pci/controller/dwc/pcie-artpec6.c     |  2 -
+ .../pci/controller/dwc/pcie-designware-host.c |  9 ++++
+ .../pci/controller/dwc/pcie-designware-plat.c |  3 --
+ drivers/pci/controller/dwc/pcie-histb.c       | 34 +++++++-------
+ drivers/pci/controller/dwc/pcie-kirin.c       | 23 ++--------
+ drivers/pci/controller/dwc/pcie-qcom.c        | 19 ++------
+ drivers/pci/controller/dwc/pcie-spear13xx.c   | 46 ++++++++-----------
+ drivers/pci/controller/dwc/pcie-tegra194.c    |  1 -
+ drivers/pci/controller/dwc/pcie-uniphier.c    | 13 ++----
+ 15 files changed, 103 insertions(+), 171 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
+index 6b75c68dddb56..054423d9646d6 100644
+--- a/drivers/pci/controller/dwc/pci-dra7xx.c
++++ b/drivers/pci/controller/dwc/pci-dra7xx.c
+@@ -183,8 +183,6 @@ static int dra7xx_pcie_host_init(struct pcie_port *pp)
+       dw_pcie_setup_rc(pp);
+-      dra7xx_pcie_establish_link(pci);
+-      dw_pcie_wait_for_link(pci);
+       dw_pcie_msi_init(pp);
+       dra7xx_pcie_enable_interrupts(dra7xx);
+diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
+index 7734394953e57..6498b615c834a 100644
+--- a/drivers/pci/controller/dwc/pci-exynos.c
++++ b/drivers/pci/controller/dwc/pci-exynos.c
+@@ -229,30 +229,9 @@ static void exynos_pcie_assert_reset(struct exynos_pcie *ep)
+                               GPIOF_OUT_INIT_HIGH, "RESET");
+ }
+-static int exynos_pcie_establish_link(struct exynos_pcie *ep)
++static int exynos_pcie_start_link(struct dw_pcie *pci)
+ {
+-      struct dw_pcie *pci = ep->pci;
+-      struct pcie_port *pp = &pci->pp;
+-      struct device *dev = pci->dev;
+-
+-      if (dw_pcie_link_up(pci)) {
+-              dev_err(dev, "Link already up\n");
+-              return 0;
+-      }
+-
+-      exynos_pcie_assert_core_reset(ep);
+-
+-      phy_reset(ep->phy);
+-
+-      exynos_pcie_writel(ep->mem_res->elbi_base, 1,
+-                      PCIE_PWR_RESET);
+-
+-      phy_power_on(ep->phy);
+-      phy_init(ep->phy);
+-
+-      exynos_pcie_deassert_core_reset(ep);
+-      dw_pcie_setup_rc(pp);
+-      exynos_pcie_assert_reset(ep);
++      struct exynos_pcie *ep = to_exynos_pcie(pci);
+       /* assert LTSSM enable */
+       exynos_pcie_writel(ep->mem_res->elbi_base, PCIE_ELBI_LTSSM_ENABLE,
+@@ -386,7 +365,20 @@ static int exynos_pcie_host_init(struct pcie_port *pp)
+       pp->bridge->ops = &exynos_pci_ops;
+-      exynos_pcie_establish_link(ep);
++      exynos_pcie_assert_core_reset(ep);
++
++      phy_reset(ep->phy);
++
++      exynos_pcie_writel(ep->mem_res->elbi_base, 1,
++                      PCIE_PWR_RESET);
++
++      phy_power_on(ep->phy);
++      phy_init(ep->phy);
++
++      exynos_pcie_deassert_core_reset(ep);
++      dw_pcie_setup_rc(pp);
++      exynos_pcie_assert_reset(ep);
++
+       exynos_pcie_enable_interrupts(ep);
+       return 0;
+@@ -430,6 +422,7 @@ static const struct dw_pcie_ops dw_pcie_ops = {
+       .read_dbi = exynos_pcie_read_dbi,
+       .write_dbi = exynos_pcie_write_dbi,
+       .link_up = exynos_pcie_link_up,
++      .start_link = exynos_pcie_start_link,
+ };
+ static int __init exynos_pcie_probe(struct platform_device *pdev)
+diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
+index 104341bfde180..8d1d2d79693d6 100644
+--- a/drivers/pci/controller/dwc/pci-imx6.c
++++ b/drivers/pci/controller/dwc/pci-imx6.c
+@@ -750,9 +750,9 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
+       }
+ }
+-static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
++static int imx6_pcie_start_link(struct dw_pcie *pci)
+ {
+-      struct dw_pcie *pci = imx6_pcie->pci;
++      struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+       struct device *dev = pci->dev;
+       u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+       u32 tmp;
+@@ -840,7 +840,6 @@ static int imx6_pcie_host_init(struct pcie_port *pp)
+       imx6_pcie_deassert_core_reset(imx6_pcie);
+       imx6_setup_phy_mpll(imx6_pcie);
+       dw_pcie_setup_rc(pp);
+-      imx6_pcie_establish_link(imx6_pcie);
+       dw_pcie_msi_init(pp);
+       return 0;
+@@ -870,7 +869,7 @@ static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
+ }
+ static const struct dw_pcie_ops dw_pcie_ops = {
+-      /* No special ops needed, but pcie-designware still expects this struct */
++      .start_link = imx6_pcie_start_link,
+ };
+ #ifdef CONFIG_PM_SLEEP
+@@ -979,7 +978,7 @@ static int imx6_pcie_resume_noirq(struct device *dev)
+       imx6_pcie_deassert_core_reset(imx6_pcie);
+       dw_pcie_setup_rc(pp);
+-      ret = imx6_pcie_establish_link(imx6_pcie);
++      ret = imx6_pcie_start_link(imx6_pcie->pci);
+       if (ret < 0)
+               dev_info(dev, "pcie link is down after resume.\n");
+diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
+index fbd38e90bef65..a5db966f6d20b 100644
+--- a/drivers/pci/controller/dwc/pci-keystone.c
++++ b/drivers/pci/controller/dwc/pci-keystone.c
+@@ -511,14 +511,8 @@ static void ks_pcie_stop_link(struct dw_pcie *pci)
+ static int ks_pcie_start_link(struct dw_pcie *pci)
+ {
+       struct keystone_pcie *ks_pcie = to_keystone_pcie(pci);
+-      struct device *dev = pci->dev;
+       u32 val;
+-      if (dw_pcie_link_up(pci)) {
+-              dev_dbg(dev, "link is already up\n");
+-              return 0;
+-      }
+-
+       /* Initiate Link Training */
+       val = ks_pcie_app_readl(ks_pcie, CMD_STATUS);
+       ks_pcie_app_writel(ks_pcie, CMD_STATUS, LTSSM_EN_VAL | val);
+@@ -834,9 +828,6 @@ static int __init ks_pcie_host_init(struct pcie_port *pp)
+                       "Asynchronous external abort");
+ #endif
+-      ks_pcie_start_link(pci);
+-      dw_pcie_wait_for_link(pci);
+-
+       return 0;
+ }
+diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c
+index 10d65b3093e4a..41a3351b100b5 100644
+--- a/drivers/pci/controller/dwc/pci-meson.c
++++ b/drivers/pci/controller/dwc/pci-meson.c
+@@ -231,7 +231,7 @@ static void meson_pcie_assert_reset(struct meson_pcie *mp)
+       gpiod_set_value_cansleep(mp->reset_gpio, 0);
+ }
+-static void meson_pcie_init_dw(struct meson_pcie *mp)
++static void meson_pcie_ltssm_enable(struct meson_pcie *mp)
+ {
+       u32 val;
+@@ -289,20 +289,14 @@ static void meson_set_max_rd_req_size(struct meson_pcie *mp, int size)
+       dw_pcie_writel_dbi(pci, offset + PCI_EXP_DEVCTL, val);
+ }
+-static int meson_pcie_establish_link(struct meson_pcie *mp)
++static int meson_pcie_start_link(struct dw_pcie *pci)
+ {
+-      struct dw_pcie *pci = &mp->pci;
+-      struct pcie_port *pp = &pci->pp;
+-
+-      meson_pcie_init_dw(mp);
+-      meson_set_max_payload(mp, MAX_PAYLOAD_SIZE);
+-      meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);
+-
+-      dw_pcie_setup_rc(pp);
++      struct meson_pcie *mp = to_meson_pcie(pci);
++      meson_pcie_ltssm_enable(mp);
+       meson_pcie_assert_reset(mp);
+-      return dw_pcie_wait_for_link(pci);
++      return 0;
+ }
+ static int meson_pcie_rd_own_conf(struct pci_bus *bus, u32 devfn,
+@@ -380,14 +374,13 @@ static int meson_pcie_host_init(struct pcie_port *pp)
+ {
+       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+       struct meson_pcie *mp = to_meson_pcie(pci);
+-      int ret;
+       pp->bridge->ops = &meson_pci_ops;
+-      ret = meson_pcie_establish_link(mp);
+-      if (ret)
+-              return ret;
++      meson_set_max_payload(mp, MAX_PAYLOAD_SIZE);
++      meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);
++      dw_pcie_setup_rc(pp);
+       dw_pcie_msi_init(pp);
+       return 0;
+@@ -418,6 +411,7 @@ static int meson_add_pcie_port(struct meson_pcie *mp,
+ static const struct dw_pcie_ops dw_pcie_ops = {
+       .link_up = meson_pcie_link_up,
++      .start_link = meson_pcie_start_link,
+ };
+ static int meson_pcie_probe(struct platform_device *pdev)
+diff --git a/drivers/pci/controller/dwc/pcie-armada8k.c b/drivers/pci/controller/dwc/pcie-armada8k.c
+index 13901f359a415..dd2926bbb9017 100644
+--- a/drivers/pci/controller/dwc/pcie-armada8k.c
++++ b/drivers/pci/controller/dwc/pcie-armada8k.c
+@@ -154,10 +154,24 @@ static int armada8k_pcie_link_up(struct dw_pcie *pci)
+       return 0;
+ }
+-static void armada8k_pcie_establish_link(struct armada8k_pcie *pcie)
++static int armada8k_pcie_start_link(struct dw_pcie *pci)
++{
++      u32 reg;
++
++      /* Start LTSSM */
++      reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_CONTROL_REG);
++      reg |= PCIE_APP_LTSSM_EN;
++      dw_pcie_writel_dbi(pci, PCIE_GLOBAL_CONTROL_REG, reg);
++
++      return 0;
++}
++
++static int armada8k_pcie_host_init(struct pcie_port *pp)
+ {
+-      struct dw_pcie *pci = pcie->pci;
+       u32 reg;
++      struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
++
++      dw_pcie_setup_rc(pp);
+       if (!dw_pcie_link_up(pci)) {
+               /* Disable LTSSM state machine to enable configuration */
+@@ -193,26 +207,6 @@ static void armada8k_pcie_establish_link(struct armada8k_pcie *pcie)
+              PCIE_INT_C_ASSERT_MASK | PCIE_INT_D_ASSERT_MASK;
+       dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_MASK1_REG, reg);
+-      if (!dw_pcie_link_up(pci)) {
+-              /* Configuration done. Start LTSSM */
+-              reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_CONTROL_REG);
+-              reg |= PCIE_APP_LTSSM_EN;
+-              dw_pcie_writel_dbi(pci, PCIE_GLOBAL_CONTROL_REG, reg);
+-      }
+-
+-      /* Wait until the link becomes active again */
+-      if (dw_pcie_wait_for_link(pci))
+-              dev_err(pci->dev, "Link not up after reconfiguration\n");
+-}
+-
+-static int armada8k_pcie_host_init(struct pcie_port *pp)
+-{
+-      struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+-      struct armada8k_pcie *pcie = to_armada8k_pcie(pci);
+-
+-      dw_pcie_setup_rc(pp);
+-      armada8k_pcie_establish_link(pcie);
+-
+       return 0;
+ }
+@@ -269,6 +263,7 @@ static int armada8k_add_pcie_port(struct armada8k_pcie *pcie,
+ static const struct dw_pcie_ops dw_pcie_ops = {
+       .link_up = armada8k_pcie_link_up,
++      .start_link = armada8k_pcie_start_link,
+ };
+ static int armada8k_pcie_probe(struct platform_device *pdev)
+diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c
+index a5239a58cee06..8b3da3038ac35 100644
+--- a/drivers/pci/controller/dwc/pcie-artpec6.c
++++ b/drivers/pci/controller/dwc/pcie-artpec6.c
+@@ -329,8 +329,6 @@ static int artpec6_pcie_host_init(struct pcie_port *pp)
+       artpec6_pcie_deassert_core_reset(artpec6_pcie);
+       artpec6_pcie_wait_for_phy(artpec6_pcie);
+       dw_pcie_setup_rc(pp);
+-      artpec6_pcie_establish_link(pci);
+-      dw_pcie_wait_for_link(pci);
+       dw_pcie_msi_init(pp);
+       return 0;
+diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
+index d8ffac3106d9c..b242d7e64c204 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -424,6 +424,15 @@ int dw_pcie_host_init(struct pcie_port *pp)
+                       goto err_free_msi;
+       }
++      if (!dw_pcie_link_up(pci) && pci->ops->start_link) {
++              ret = pci->ops->start_link(pci);
++              if (ret)
++                      goto err_free_msi;
++      }
++
++      /* Ignore errors, the link may come up later */
++      dw_pcie_wait_for_link(pci);
++
+       bridge->sysdata = pp;
+       ret = pci_host_probe(bridge);
+diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
+index 3da38ac6a87a0..adebcaeb1a6c0 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
++++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
+@@ -35,10 +35,7 @@ static const struct of_device_id dw_plat_pcie_of_match[];
+ static int dw_plat_pcie_host_init(struct pcie_port *pp)
+ {
+-      struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+-
+       dw_pcie_setup_rc(pp);
+-      dw_pcie_wait_for_link(pci);
+       dw_pcie_msi_init(pp);
+       return 0;
+diff --git a/drivers/pci/controller/dwc/pcie-histb.c b/drivers/pci/controller/dwc/pcie-histb.c
+index 777e24902afbf..ece544165059b 100644
+--- a/drivers/pci/controller/dwc/pcie-histb.c
++++ b/drivers/pci/controller/dwc/pcie-histb.c
+@@ -169,39 +169,36 @@ static int histb_pcie_link_up(struct dw_pcie *pci)
+       return 0;
+ }
+-static int histb_pcie_establish_link(struct pcie_port *pp)
++static int histb_pcie_start_link(struct dw_pcie *pci)
+ {
+-      struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+       struct histb_pcie *hipcie = to_histb_pcie(pci);
+       u32 regval;
+-      if (dw_pcie_link_up(pci)) {
+-              dev_info(pci->dev, "Link already up\n");
+-              return 0;
+-      }
+-
+-      /* PCIe RC work mode */
+-      regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0);
+-      regval &= ~PCIE_DEVICE_TYPE_MASK;
+-      regval |= PCIE_WM_RC;
+-      histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, regval);
+-
+-      /* setup root complex */
+-      dw_pcie_setup_rc(pp);
+-
+       /* assert LTSSM enable */
+       regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL7);
+       regval |= PCIE_APP_LTSSM_ENABLE;
+       histb_pcie_writel(hipcie, PCIE_SYS_CTRL7, regval);
+-      return dw_pcie_wait_for_link(pci);
++      return 0;
+ }
+ static int histb_pcie_host_init(struct pcie_port *pp)
+ {
++      struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
++      struct histb_pcie *hipcie = to_histb_pcie(pci);
++      u32 regval;
++
+       pp->bridge->ops = &histb_pci_ops;
+-      histb_pcie_establish_link(pp);
++      /* PCIe RC work mode */
++      regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0);
++      regval &= ~PCIE_DEVICE_TYPE_MASK;
++      regval |= PCIE_WM_RC;
++      histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, regval);
++
++      /* setup root complex */
++      dw_pcie_setup_rc(pp);
++
+       dw_pcie_msi_init(pp);
+       return 0;
+@@ -300,6 +297,7 @@ static const struct dw_pcie_ops dw_pcie_ops = {
+       .read_dbi = histb_pcie_read_dbi,
+       .write_dbi = histb_pcie_write_dbi,
+       .link_up = histb_pcie_link_up,
++      .start_link = histb_pcie_start_link,
+ };
+ static int histb_pcie_probe(struct platform_device *pdev)
+diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c
+index ba03dbca7885e..675b4d8392d37 100644
+--- a/drivers/pci/controller/dwc/pcie-kirin.c
++++ b/drivers/pci/controller/dwc/pcie-kirin.c
+@@ -390,32 +390,14 @@ static int kirin_pcie_link_up(struct dw_pcie *pci)
+       return 0;
+ }
+-static int kirin_pcie_establish_link(struct pcie_port *pp)
++static int kirin_pcie_start_link(struct dw_pcie *pci)
+ {
+-      struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+       struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci);
+-      struct device *dev = kirin_pcie->pci->dev;
+-      int count = 0;
+-
+-      if (kirin_pcie_link_up(pci))
+-              return 0;
+-
+-      dw_pcie_setup_rc(pp);
+       /* assert LTSSM enable */
+       kirin_apb_ctrl_writel(kirin_pcie, PCIE_LTSSM_ENABLE_BIT,
+                             PCIE_APP_LTSSM_ENABLE);
+-      /* check if the link is up or not */
+-      while (!kirin_pcie_link_up(pci)) {
+-              usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
+-              count++;
+-              if (count == 1000) {
+-                      dev_err(dev, "Link Fail\n");
+-                      return -EINVAL;
+-              }
+-      }
+-
+       return 0;
+ }
+@@ -423,7 +405,7 @@ static int kirin_pcie_host_init(struct pcie_port *pp)
+ {
+       pp->bridge->ops = &kirin_pci_ops;
+-      kirin_pcie_establish_link(pp);
++      dw_pcie_setup_rc(pp);
+       dw_pcie_msi_init(pp);
+       return 0;
+@@ -433,6 +415,7 @@ static const struct dw_pcie_ops kirin_dw_pcie_ops = {
+       .read_dbi = kirin_pcie_read_dbi,
+       .write_dbi = kirin_pcie_write_dbi,
+       .link_up = kirin_pcie_link_up,
++      .start_link = kirin_pcie_start_link,
+ };
+ static const struct dw_pcie_host_ops kirin_pcie_host_ops = {
+diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
+index 4f230f01a645e..03251e34137f3 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -207,18 +207,15 @@ static void qcom_ep_reset_deassert(struct qcom_pcie *pcie)
+       usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500);
+ }
+-static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
++static int qcom_pcie_start_link(struct dw_pcie *pci)
+ {
+-      struct dw_pcie *pci = pcie->pci;
+-
+-      if (dw_pcie_link_up(pci))
+-              return 0;
++      struct qcom_pcie *pcie = to_qcom_pcie(pci);
+       /* Enable Link Training state machine */
+       if (pcie->ops->ltssm_enable)
+               pcie->ops->ltssm_enable(pcie);
+-      return dw_pcie_wait_for_link(pci);
++      return 0;
+ }
+ static void qcom_pcie_2_1_0_ltssm_enable(struct qcom_pcie *pcie)
+@@ -1280,15 +1277,8 @@ static int qcom_pcie_host_init(struct pcie_port *pp)
+       qcom_ep_reset_deassert(pcie);
+-      ret = qcom_pcie_establish_link(pcie);
+-      if (ret)
+-              goto err;
+-
+       return 0;
+-err:
+-      qcom_ep_reset_assert(pcie);
+-      if (pcie->ops->post_deinit)
+-              pcie->ops->post_deinit(pcie);
++
+ err_disable_phy:
+       phy_power_off(pcie->phy);
+ err_deinit:
+@@ -1355,6 +1345,7 @@ static const struct qcom_pcie_ops ops_2_7_0 = {
+ static const struct dw_pcie_ops dw_pcie_ops = {
+       .link_up = qcom_pcie_link_up,
++      .start_link = qcom_pcie_start_link,
+ };
+ static int qcom_pcie_probe(struct platform_device *pdev)
+diff --git a/drivers/pci/controller/dwc/pcie-spear13xx.c b/drivers/pci/controller/dwc/pcie-spear13xx.c
+index 800c34a60a334..ebbaa06fc8ab5 100644
+--- a/drivers/pci/controller/dwc/pcie-spear13xx.c
++++ b/drivers/pci/controller/dwc/pcie-spear13xx.c
+@@ -66,32 +66,10 @@ struct pcie_app_reg {
+ #define to_spear13xx_pcie(x)  dev_get_drvdata((x)->dev)
+-static int spear13xx_pcie_establish_link(struct spear13xx_pcie *spear13xx_pcie)
++static int spear13xx_pcie_start_link(struct dw_pcie *pci)
+ {
+-      struct dw_pcie *pci = spear13xx_pcie->pci;
+-      struct pcie_port *pp = &pci->pp;
++      struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pci);
+       struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
+-      u32 val;
+-      u32 exp_cap_off = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+-
+-      if (dw_pcie_link_up(pci)) {
+-              dev_err(pci->dev, "link already up\n");
+-              return 0;
+-      }
+-
+-      dw_pcie_setup_rc(pp);
+-
+-      /*
+-       * this controller support only 128 bytes read size, however its
+-       * default value in capability register is 512 bytes. So force
+-       * it to 128 here.
+-       */
+-      val = dw_pcie_readw_dbi(pci, exp_cap_off + PCI_EXP_DEVCTL);
+-      val &= ~PCI_EXP_DEVCTL_READRQ;
+-      dw_pcie_writew_dbi(pci, exp_cap_off + PCI_EXP_DEVCTL, val);
+-
+-      dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, 0x104A);
+-      dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, 0xCD80);
+       /* enable ltssm */
+       writel(DEVICE_TYPE_RC | (1 << MISCTRL_EN_ID)
+@@ -99,7 +77,7 @@ static int spear13xx_pcie_establish_link(struct spear13xx_pcie *spear13xx_pcie)
+                       | ((u32)1 << REG_TRANSLATION_ENABLE),
+                       &app_reg->app_ctrl_0);
+-      return dw_pcie_wait_for_link(pci);
++      return 0;
+ }
+ static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg)
+@@ -151,10 +129,25 @@ static int spear13xx_pcie_host_init(struct pcie_port *pp)
+ {
+       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+       struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pci);
++      u32 exp_cap_off = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
++      u32 val;
+       spear13xx_pcie->app_base = pci->dbi_base + 0x2000;
+-      spear13xx_pcie_establish_link(spear13xx_pcie);
++      dw_pcie_setup_rc(pp);
++
++      /*
++       * this controller support only 128 bytes read size, however its
++       * default value in capability register is 512 bytes. So force
++       * it to 128 here.
++       */
++      val = dw_pcie_readw_dbi(pci, exp_cap_off + PCI_EXP_DEVCTL);
++      val &= ~PCI_EXP_DEVCTL_READRQ;
++      dw_pcie_writew_dbi(pci, exp_cap_off + PCI_EXP_DEVCTL, val);
++
++      dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, 0x104A);
++      dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, 0xCD80);
++
+       spear13xx_pcie_enable_interrupts(spear13xx_pcie);
+       return 0;
+@@ -198,6 +191,7 @@ static int spear13xx_add_pcie_port(struct spear13xx_pcie *spear13xx_pcie,
+ static const struct dw_pcie_ops dw_pcie_ops = {
+       .link_up = spear13xx_pcie_link_up,
++      .start_link = spear13xx_pcie_start_link,
+ };
+ static int spear13xx_pcie_probe(struct platform_device *pdev)
+diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
+index 8e67495be90f9..782aa3f382829 100644
+--- a/drivers/pci/controller/dwc/pcie-tegra194.c
++++ b/drivers/pci/controller/dwc/pcie-tegra194.c
+@@ -1555,7 +1555,6 @@ static int tegra_pcie_deinit_controller(struct tegra_pcie_dw *pcie)
+ static int tegra_pcie_config_rp(struct tegra_pcie_dw *pcie)
+ {
+-      struct pcie_port *pp = &pcie->pci.pp;
+       struct device *dev = pcie->dev;
+       char *name;
+       int ret;
+diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
+index 4620561da7a3e..bd4bf2db9480e 100644
+--- a/drivers/pci/controller/dwc/pcie-uniphier.c
++++ b/drivers/pci/controller/dwc/pcie-uniphier.c
+@@ -146,16 +146,13 @@ static int uniphier_pcie_link_up(struct dw_pcie *pci)
+       return (val & mask) == mask;
+ }
+-static int uniphier_pcie_establish_link(struct dw_pcie *pci)
++static int uniphier_pcie_start_link(struct dw_pcie *pci)
+ {
+       struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
+-      if (dw_pcie_link_up(pci))
+-              return 0;
+-
+       uniphier_pcie_ltssm_enable(priv, true);
+-      return dw_pcie_wait_for_link(pci);
++      return 0;
+ }
+ static void uniphier_pcie_stop_link(struct dw_pcie *pci)
+@@ -312,10 +309,6 @@ static int uniphier_pcie_host_init(struct pcie_port *pp)
+       uniphier_pcie_irq_enable(priv);
+       dw_pcie_setup_rc(pp);
+-      ret = uniphier_pcie_establish_link(pci);
+-      if (ret)
+-              return ret;
+-
+       dw_pcie_msi_init(pp);
+       return 0;
+@@ -379,7 +372,7 @@ static int uniphier_pcie_host_enable(struct uniphier_pcie_priv *priv)
+ }
+ static const struct dw_pcie_ops dw_pcie_ops = {
+-      .start_link = uniphier_pcie_establish_link,
++      .start_link = uniphier_pcie_start_link,
+       .stop_link = uniphier_pcie_stop_link,
+       .link_up = uniphier_pcie_link_up,
+ };
+-- 
+2.42.0
+
diff --git a/queue-5.10/pci-dwc-move-msi-interrupt-setup-into-dwc-common-cod.patch b/queue-5.10/pci-dwc-move-msi-interrupt-setup-into-dwc-common-cod.patch
new file mode 100644 (file)
index 0000000..d1e0b61
--- /dev/null
@@ -0,0 +1,323 @@
+From 7dfbd819eb0f2302460066fe9ce49e4fe8c6ce05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Nov 2020 15:11:51 -0600
+Subject: PCI: dwc: Move MSI interrupt setup into DWC common code
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit 5bcb1757e637a4f6d130f1f5106ce030516316b8 ]
+
+Platforms using the built-in DWC MSI controller all have a dedicated
+interrupt with "msi" name or at index 0, so let's move setting up the
+interrupt to the common DWC code.
+
+spear13xx and dra7xx are the 2 oddballs with muxed interrupts, so
+we need to prevent configuring the MSI interrupt by setting msi_irq
+to negative.
+
+Link: https://lore.kernel.org/r/20201105211159.1814485-9-robh@kernel.org
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Jingoo Han <jingoohan1@gmail.com>
+Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Kukjin Kim <kgene@kernel.org>
+Cc: Krzysztof Kozlowski <krzk@kernel.org>
+Cc: Richard Zhu <hongxing.zhu@nxp.com>
+Cc: Lucas Stach <l.stach@pengutronix.de>
+Cc: Shawn Guo <shawnguo@kernel.org>
+Cc: Sascha Hauer <s.hauer@pengutronix.de>
+Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
+Cc: Fabio Estevam <festevam@gmail.com>
+Cc: NXP Linux Team <linux-imx@nxp.com>
+Cc: Yue Wang <yue.wang@Amlogic.com>
+Cc: Kevin Hilman <khilman@baylibre.com>
+Cc: Neil Armstrong <narmstrong@baylibre.com>
+Cc: Jerome Brunet <jbrunet@baylibre.com>
+Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Cc: Jesper Nilsson <jesper.nilsson@axis.com>
+Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Cc: Xiaowei Song <songxiaowei@hisilicon.com>
+Cc: Binghui Wang <wangbinghui@hisilicon.com>
+Cc: Stanimir Varbanov <svarbanov@mm-sol.com>
+Cc: Andy Gross <agross@kernel.org>
+Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
+Cc: Pratyush Anand <pratyush.anand@gmail.com>
+Cc: Thierry Reding <thierry.reding@gmail.com>
+Cc: Jonathan Hunter <jonathanh@nvidia.com>
+Cc: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
+Cc: linux-samsung-soc@vger.kernel.org
+Cc: linux-amlogic@lists.infradead.org
+Cc: linux-arm-kernel@axis.com
+Cc: linux-arm-msm@vger.kernel.org
+Cc: linux-tegra@vger.kernel.org
+Stable-dep-of: 83a939f0fdc2 ("PCI: exynos: Don't discard .remove() callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pci-dra7xx.c       |  3 +++
+ drivers/pci/controller/dwc/pci-exynos.c       |  6 -----
+ drivers/pci/controller/dwc/pci-imx6.c         |  6 -----
+ drivers/pci/controller/dwc/pci-meson.c        |  6 -----
+ drivers/pci/controller/dwc/pcie-artpec6.c     |  6 -----
+ .../pci/controller/dwc/pcie-designware-host.c | 11 +++++++++-
+ .../pci/controller/dwc/pcie-designware-plat.c |  6 -----
+ drivers/pci/controller/dwc/pcie-histb.c       |  6 -----
+ drivers/pci/controller/dwc/pcie-kirin.c       | 22 -------------------
+ drivers/pci/controller/dwc/pcie-qcom.c        |  8 -------
+ drivers/pci/controller/dwc/pcie-spear13xx.c   |  1 +
+ drivers/pci/controller/dwc/pcie-tegra194.c    |  8 -------
+ drivers/pci/controller/dwc/pcie-uniphier.c    |  6 -----
+ 13 files changed, 14 insertions(+), 81 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
+index 4d0c35a4aa598..6b75c68dddb56 100644
+--- a/drivers/pci/controller/dwc/pci-dra7xx.c
++++ b/drivers/pci/controller/dwc/pci-dra7xx.c
+@@ -489,6 +489,9 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
+       if (pp->irq < 0)
+               return pp->irq;
++      /* MSI IRQ is muxed */
++      pp->msi_irq = -ENODEV;
++
+       ret = dra7xx_pcie_init_irq_domain(pp);
+       if (ret < 0)
+               return ret;
+diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
+index 242683cde04a5..7734394953e57 100644
+--- a/drivers/pci/controller/dwc/pci-exynos.c
++++ b/drivers/pci/controller/dwc/pci-exynos.c
+@@ -415,12 +415,6 @@ static int __init exynos_add_pcie_port(struct exynos_pcie *ep,
+               return ret;
+       }
+-      if (IS_ENABLED(CONFIG_PCI_MSI)) {
+-              pp->msi_irq = platform_get_irq(pdev, 0);
+-              if (pp->msi_irq < 0)
+-                      return pp->msi_irq;
+-      }
+-
+       pp->ops = &exynos_pcie_host_ops;
+       ret = dw_pcie_host_init(pp);
+diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
+index 8117f2dad86c4..104341bfde180 100644
+--- a/drivers/pci/controller/dwc/pci-imx6.c
++++ b/drivers/pci/controller/dwc/pci-imx6.c
+@@ -858,12 +858,6 @@ static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
+       struct device *dev = &pdev->dev;
+       int ret;
+-      if (IS_ENABLED(CONFIG_PCI_MSI)) {
+-              pp->msi_irq = platform_get_irq_byname(pdev, "msi");
+-              if (pp->msi_irq < 0)
+-                      return pp->msi_irq;
+-      }
+-
+       pp->ops = &imx6_pcie_host_ops;
+       ret = dw_pcie_host_init(pp);
+diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c
+index 1913dc2c8fa08..10d65b3093e4a 100644
+--- a/drivers/pci/controller/dwc/pci-meson.c
++++ b/drivers/pci/controller/dwc/pci-meson.c
+@@ -405,12 +405,6 @@ static int meson_add_pcie_port(struct meson_pcie *mp,
+       struct device *dev = &pdev->dev;
+       int ret;
+-      if (IS_ENABLED(CONFIG_PCI_MSI)) {
+-              pp->msi_irq = platform_get_irq(pdev, 0);
+-              if (pp->msi_irq < 0)
+-                      return pp->msi_irq;
+-      }
+-
+       pp->ops = &meson_pcie_host_ops;
+       ret = dw_pcie_host_init(pp);
+diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c
+index 52ad7909cd0c0..a5239a58cee06 100644
+--- a/drivers/pci/controller/dwc/pcie-artpec6.c
++++ b/drivers/pci/controller/dwc/pcie-artpec6.c
+@@ -348,12 +348,6 @@ static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie,
+       struct device *dev = pci->dev;
+       int ret;
+-      if (IS_ENABLED(CONFIG_PCI_MSI)) {
+-              pp->msi_irq = platform_get_irq_byname(pdev, "msi");
+-              if (pp->msi_irq < 0)
+-                      return pp->msi_irq;
+-      }
+-
+       pp->ops = &artpec6_pcie_host_ops;
+       ret = dw_pcie_host_init(pp);
+diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
+index 32d3af7c44917..401890f5c8ca8 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -373,13 +373,22 @@ int dw_pcie_host_init(struct pcie_port *pp)
+               }
+               if (!pp->ops->msi_host_init) {
++                      if (!pp->msi_irq) {
++                              pp->msi_irq = platform_get_irq_byname_optional(pdev, "msi");
++                              if (pp->msi_irq < 0) {
++                                      pp->msi_irq = platform_get_irq(pdev, 0);
++                                      if (pp->msi_irq < 0)
++                                              return pp->msi_irq;
++                              }
++                      }
++
+                       pp->msi_irq_chip = &dw_pci_msi_bottom_irq_chip;
+                       ret = dw_pcie_allocate_domains(pp);
+                       if (ret)
+                               return ret;
+-                      if (pp->msi_irq)
++                      if (pp->msi_irq > 0)
+                               irq_set_chained_handler_and_data(pp->msi_irq,
+                                                           dw_chained_msi_isr,
+                                                           pp);
+diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
+index 13fede1d41572..3da38ac6a87a0 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
++++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
+@@ -116,12 +116,6 @@ static int dw_plat_add_pcie_port(struct dw_plat_pcie *dw_plat_pcie,
+       if (pp->irq < 0)
+               return pp->irq;
+-      if (IS_ENABLED(CONFIG_PCI_MSI)) {
+-              pp->msi_irq = platform_get_irq(pdev, 0);
+-              if (pp->msi_irq < 0)
+-                      return pp->msi_irq;
+-      }
+-
+       pp->num_vectors = MAX_MSI_IRQS;
+       pp->ops = &dw_plat_pcie_host_ops;
+diff --git a/drivers/pci/controller/dwc/pcie-histb.c b/drivers/pci/controller/dwc/pcie-histb.c
+index afc1abbe49aa9..777e24902afbf 100644
+--- a/drivers/pci/controller/dwc/pcie-histb.c
++++ b/drivers/pci/controller/dwc/pcie-histb.c
+@@ -400,12 +400,6 @@ static int histb_pcie_probe(struct platform_device *pdev)
+               return PTR_ERR(hipcie->bus_reset);
+       }
+-      if (IS_ENABLED(CONFIG_PCI_MSI)) {
+-              pp->msi_irq = platform_get_irq_byname(pdev, "msi");
+-              if (pp->msi_irq < 0)
+-                      return pp->msi_irq;
+-      }
+-
+       hipcie->phy = devm_phy_get(dev, "phy");
+       if (IS_ERR(hipcie->phy)) {
+               dev_info(dev, "no pcie-phy found\n");
+diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c
+index 3042a23cf09a4..ba03dbca7885e 100644
+--- a/drivers/pci/controller/dwc/pcie-kirin.c
++++ b/drivers/pci/controller/dwc/pcie-kirin.c
+@@ -439,31 +439,9 @@ static const struct dw_pcie_host_ops kirin_pcie_host_ops = {
+       .host_init = kirin_pcie_host_init,
+ };
+-static int kirin_pcie_add_msi(struct dw_pcie *pci,
+-                              struct platform_device *pdev)
+-{
+-      int irq;
+-
+-      if (IS_ENABLED(CONFIG_PCI_MSI)) {
+-              irq = platform_get_irq(pdev, 0);
+-              if (irq < 0)
+-                      return irq;
+-
+-              pci->pp.msi_irq = irq;
+-      }
+-
+-      return 0;
+-}
+-
+ static int kirin_add_pcie_port(struct dw_pcie *pci,
+                              struct platform_device *pdev)
+ {
+-      int ret;
+-
+-      ret = kirin_pcie_add_msi(pci, pdev);
+-      if (ret)
+-              return ret;
+-
+       pci->pp.ops = &kirin_pcie_host_ops;
+       return dw_pcie_host_init(&pci->pp);
+diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
+index 150dd6fe7ba39..4f230f01a645e 100644
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -1416,14 +1416,6 @@ static int qcom_pcie_probe(struct platform_device *pdev)
+       pp->ops = &qcom_pcie_dw_ops;
+-      if (IS_ENABLED(CONFIG_PCI_MSI)) {
+-              pp->msi_irq = platform_get_irq_byname(pdev, "msi");
+-              if (pp->msi_irq < 0) {
+-                      ret = pp->msi_irq;
+-                      goto err_pm_runtime_put;
+-              }
+-      }
+-
+       ret = phy_init(pcie->phy);
+       if (ret)
+               goto err_pm_runtime_put;
+diff --git a/drivers/pci/controller/dwc/pcie-spear13xx.c b/drivers/pci/controller/dwc/pcie-spear13xx.c
+index 1ed7e3501ff1c..800c34a60a334 100644
+--- a/drivers/pci/controller/dwc/pcie-spear13xx.c
++++ b/drivers/pci/controller/dwc/pcie-spear13xx.c
+@@ -185,6 +185,7 @@ static int spear13xx_add_pcie_port(struct spear13xx_pcie *spear13xx_pcie,
+       }
+       pp->ops = &spear13xx_pcie_host_ops;
++      pp->msi_irq = -ENODEV;
+       ret = dw_pcie_host_init(pp);
+       if (ret) {
+diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
+index a93b5dca110ec..8e67495be90f9 100644
+--- a/drivers/pci/controller/dwc/pcie-tegra194.c
++++ b/drivers/pci/controller/dwc/pcie-tegra194.c
+@@ -1560,14 +1560,6 @@ static int tegra_pcie_config_rp(struct tegra_pcie_dw *pcie)
+       char *name;
+       int ret;
+-      if (IS_ENABLED(CONFIG_PCI_MSI)) {
+-              pp->msi_irq = of_irq_get_byname(dev->of_node, "msi");
+-              if (!pp->msi_irq) {
+-                      dev_err(dev, "Failed to get MSI interrupt\n");
+-                      return -ENODEV;
+-              }
+-      }
+-
+       pm_runtime_enable(dev);
+       ret = pm_runtime_get_sync(dev);
+diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
+index 85bf170e93541..4620561da7a3e 100644
+--- a/drivers/pci/controller/dwc/pcie-uniphier.c
++++ b/drivers/pci/controller/dwc/pcie-uniphier.c
+@@ -335,12 +335,6 @@ static int uniphier_add_pcie_port(struct uniphier_pcie_priv *priv,
+       pp->ops = &uniphier_pcie_host_ops;
+-      if (IS_ENABLED(CONFIG_PCI_MSI)) {
+-              pp->msi_irq = platform_get_irq_byname(pdev, "msi");
+-              if (pp->msi_irq < 0)
+-                      return pp->msi_irq;
+-      }
+-
+       ret = dw_pcie_host_init(pp);
+       if (ret) {
+               dev_err(dev, "Failed to initialize host (%d)\n", ret);
+-- 
+2.42.0
+
diff --git a/queue-5.10/pci-dwc-rework-msi-initialization.patch b/queue-5.10/pci-dwc-rework-msi-initialization.patch
new file mode 100644 (file)
index 0000000..670763f
--- /dev/null
@@ -0,0 +1,218 @@
+From f014ef788425a1aeb38511ab7536facbdd3d9342 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Nov 2020 15:11:52 -0600
+Subject: PCI: dwc: Rework MSI initialization
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit f78f02638af5941eb45a402fa52c0edf4ac0f507 ]
+
+There are 3 possible MSI implementations for the DWC host. The first is
+using the built-in DWC MSI controller. The 2nd is a custom MSI
+controller as part of the PCI host (keystone only). The 3rd is an
+external MSI controller (typically GICv3 ITS). Currently, the last 2
+are distinguished with a .msi_host_init() hook with the 3rd option using
+an empty function. However we can detect the 3rd case with the presence
+of 'msi-parent' or 'msi-map' properties, so let's do that instead and
+remove the empty functions.
+
+Link: https://lore.kernel.org/r/20201105211159.1814485-10-robh@kernel.org
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Jingoo Han <jingoohan1@gmail.com>
+Cc: Murali Karicheri <m-karicheri2@ti.com>
+Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Cc: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Minghuan Lian <minghuan.Lian@nxp.com>
+Cc: Mingkai Hu <mingkai.hu@nxp.com>
+Cc: Roy Zang <roy.zang@nxp.com>
+Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
+Cc: linuxppc-dev@lists.ozlabs.org
+Stable-dep-of: 83a939f0fdc2 ("PCI: exynos: Don't discard .remove() callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pci-keystone.c     |  9 -------
+ drivers/pci/controller/dwc/pci-layerscape.c   | 25 -------------------
+ .../pci/controller/dwc/pcie-designware-host.c | 20 +++++++++------
+ drivers/pci/controller/dwc/pcie-designware.h  |  1 +
+ drivers/pci/controller/dwc/pcie-intel-gw.c    |  9 -------
+ 5 files changed, 13 insertions(+), 51 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
+index 5177f6d1ca592..fbd38e90bef65 100644
+--- a/drivers/pci/controller/dwc/pci-keystone.c
++++ b/drivers/pci/controller/dwc/pci-keystone.c
+@@ -272,14 +272,6 @@ static void ks_pcie_handle_legacy_irq(struct keystone_pcie *ks_pcie,
+       ks_pcie_app_writel(ks_pcie, IRQ_EOI, offset);
+ }
+-/*
+- * Dummy function so that DW core doesn't configure MSI
+- */
+-static int ks_pcie_am654_msi_host_init(struct pcie_port *pp)
+-{
+-      return 0;
+-}
+-
+ static void ks_pcie_enable_error_irq(struct keystone_pcie *ks_pcie)
+ {
+       ks_pcie_app_writel(ks_pcie, ERR_IRQ_ENABLE_SET, ERR_IRQ_ALL);
+@@ -855,7 +847,6 @@ static const struct dw_pcie_host_ops ks_pcie_host_ops = {
+ static const struct dw_pcie_host_ops ks_pcie_am654_host_ops = {
+       .host_init = ks_pcie_host_init,
+-      .msi_host_init = ks_pcie_am654_msi_host_init,
+ };
+ static irqreturn_t ks_pcie_err_irq_handler(int irq, void *priv)
+diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c
+index f24f79a70d9a8..4d280b940f1fe 100644
+--- a/drivers/pci/controller/dwc/pci-layerscape.c
++++ b/drivers/pci/controller/dwc/pci-layerscape.c
+@@ -182,37 +182,12 @@ static int ls1021_pcie_host_init(struct pcie_port *pp)
+       return ls_pcie_host_init(pp);
+ }
+-static int ls_pcie_msi_host_init(struct pcie_port *pp)
+-{
+-      struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+-      struct device *dev = pci->dev;
+-      struct device_node *np = dev->of_node;
+-      struct device_node *msi_node;
+-
+-      /*
+-       * The MSI domain is set by the generic of_msi_configure().  This
+-       * .msi_host_init() function keeps us from doing the default MSI
+-       * domain setup in dw_pcie_host_init() and also enforces the
+-       * requirement that "msi-parent" exists.
+-       */
+-      msi_node = of_parse_phandle(np, "msi-parent", 0);
+-      if (!msi_node) {
+-              dev_err(dev, "failed to find msi-parent\n");
+-              return -EINVAL;
+-      }
+-
+-      of_node_put(msi_node);
+-      return 0;
+-}
+-
+ static const struct dw_pcie_host_ops ls1021_pcie_host_ops = {
+       .host_init = ls1021_pcie_host_init,
+-      .msi_host_init = ls_pcie_msi_host_init,
+ };
+ static const struct dw_pcie_host_ops ls_pcie_host_ops = {
+       .host_init = ls_pcie_host_init,
+-      .msi_host_init = ls_pcie_msi_host_init,
+ };
+ static const struct dw_pcie_ops dw_ls1021_pcie_ops = {
+diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
+index 401890f5c8ca8..d8ffac3106d9c 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-host.c
++++ b/drivers/pci/controller/dwc/pcie-designware-host.c
+@@ -365,6 +365,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
+               pci->link_gen = of_pci_get_max_link_speed(np);
+       if (pci_msi_enabled()) {
++              pp->has_msi_ctrl = !(pp->ops->msi_host_init ||
++                                   of_property_read_bool(np, "msi-parent") ||
++                                   of_property_read_bool(np, "msi-map"));
++
+               if (!pp->num_vectors) {
+                       pp->num_vectors = MSI_DEF_NUM_VECTORS;
+               } else if (pp->num_vectors > MAX_MSI_IRQS) {
+@@ -372,7 +376,11 @@ int dw_pcie_host_init(struct pcie_port *pp)
+                       return -EINVAL;
+               }
+-              if (!pp->ops->msi_host_init) {
++              if (pp->ops->msi_host_init) {
++                      ret = pp->ops->msi_host_init(pp);
++                      if (ret < 0)
++                              return ret;
++              } else if (pp->has_msi_ctrl) {
+                       if (!pp->msi_irq) {
+                               pp->msi_irq = platform_get_irq_byname_optional(pdev, "msi");
+                               if (pp->msi_irq < 0) {
+@@ -403,10 +411,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
+                               pp->msi_data = 0;
+                               goto err_free_msi;
+                       }
+-              } else {
+-                      ret = pp->ops->msi_host_init(pp);
+-                      if (ret < 0)
+-                              return ret;
+               }
+       }
+@@ -427,7 +431,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
+               return 0;
+ err_free_msi:
+-      if (pci_msi_enabled() && !pp->ops->msi_host_init)
++      if (pp->has_msi_ctrl)
+               dw_pcie_free_msi(pp);
+       return ret;
+ }
+@@ -437,7 +441,7 @@ void dw_pcie_host_deinit(struct pcie_port *pp)
+ {
+       pci_stop_root_bus(pp->bridge->bus);
+       pci_remove_root_bus(pp->bridge->bus);
+-      if (pci_msi_enabled() && !pp->ops->msi_host_init)
++      if (pp->has_msi_ctrl)
+               dw_pcie_free_msi(pp);
+ }
+ EXPORT_SYMBOL_GPL(dw_pcie_host_deinit);
+@@ -548,7 +552,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
+       dw_pcie_setup(pci);
+-      if (pci_msi_enabled() && !pp->ops->msi_host_init) {
++      if (pp->has_msi_ctrl) {
+               num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL;
+               /* Initialize IRQ Status array */
+diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
+index 82c0339c283f1..f33dc89a93650 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.h
++++ b/drivers/pci/controller/dwc/pcie-designware.h
+@@ -178,6 +178,7 @@ struct dw_pcie_host_ops {
+ };
+ struct pcie_port {
++      bool                    has_msi_ctrl:1;
+       u64                     cfg0_base;
+       void __iomem            *va_cfg0_base;
+       u32                     cfg0_size;
+diff --git a/drivers/pci/controller/dwc/pcie-intel-gw.c b/drivers/pci/controller/dwc/pcie-intel-gw.c
+index 429171c35945d..5ce25944cc315 100644
+--- a/drivers/pci/controller/dwc/pcie-intel-gw.c
++++ b/drivers/pci/controller/dwc/pcie-intel-gw.c
+@@ -399,14 +399,6 @@ static int intel_pcie_rc_init(struct pcie_port *pp)
+       return intel_pcie_host_setup(lpp);
+ }
+-/*
+- * Dummy function so that DW core doesn't configure MSI
+- */
+-static int intel_pcie_msi_init(struct pcie_port *pp)
+-{
+-      return 0;
+-}
+-
+ static u64 intel_pcie_cpu_addr(struct dw_pcie *pcie, u64 cpu_addr)
+ {
+       return cpu_addr + BUS_IATU_OFFSET;
+@@ -418,7 +410,6 @@ static const struct dw_pcie_ops intel_pcie_ops = {
+ static const struct dw_pcie_host_ops intel_pcie_dw_ops = {
+       .host_init =            intel_pcie_rc_init,
+-      .msi_host_init =        intel_pcie_msi_init,
+ };
+ static const struct intel_pcie_soc pcie_data = {
+-- 
+2.42.0
+
diff --git a/queue-5.10/pci-exynos-don-t-discard-.remove-callback.patch b/queue-5.10/pci-exynos-don-t-discard-.remove-callback.patch
new file mode 100644 (file)
index 0000000..8bd16c1
--- /dev/null
@@ -0,0 +1,60 @@
+From cfeb180401c710b50c82ea03f6a76493624afc36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Oct 2023 19:02:51 +0200
+Subject: PCI: exynos: Don't discard .remove() callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 83a939f0fdc208ff3639dd3d42ac9b3c35607fd2 ]
+
+With CONFIG_PCI_EXYNOS=y and exynos_pcie_remove() marked with __exit, the
+function is discarded from the driver. In this case a bound device can
+still get unbound, e.g via sysfs. Then no cleanup code is run resulting in
+resource leaks or worse.
+
+The right thing to do is do always have the remove callback available.
+This fixes the following warning by modpost:
+
+  WARNING: modpost: drivers/pci/controller/dwc/pci-exynos: section mismatch in reference: exynos_pcie_driver+0x8 (section: .data) -> exynos_pcie_remove (section: .exit.text)
+
+(with ARCH=x86_64 W=1 allmodconfig).
+
+Fixes: 340cba6092c2 ("pci: Add PCIe driver for Samsung Exynos")
+Link: https://lore.kernel.org/r/20231001170254.2506508-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pci-exynos.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
+index c24dab383654b..2696a4544f102 100644
+--- a/drivers/pci/controller/dwc/pci-exynos.c
++++ b/drivers/pci/controller/dwc/pci-exynos.c
+@@ -377,7 +377,7 @@ static int exynos_pcie_probe(struct platform_device *pdev)
+       return ret;
+ }
+-static int __exit exynos_pcie_remove(struct platform_device *pdev)
++static int exynos_pcie_remove(struct platform_device *pdev)
+ {
+       struct exynos_pcie *ep = platform_get_drvdata(pdev);
+@@ -433,7 +433,7 @@ static const struct of_device_id exynos_pcie_of_match[] = {
+ static struct platform_driver exynos_pcie_driver = {
+       .probe          = exynos_pcie_probe,
+-      .remove         = __exit_p(exynos_pcie_remove),
++      .remove         = exynos_pcie_remove,
+       .driver = {
+               .name   = "exynos-pcie",
+               .of_match_table = exynos_pcie_of_match,
+-- 
+2.42.0
+
diff --git a/queue-5.10/serial-meson-remove-redundant-initialization-of-vari.patch b/queue-5.10/serial-meson-remove-redundant-initialization-of-vari.patch
new file mode 100644 (file)
index 0000000..843321a
--- /dev/null
@@ -0,0 +1,48 @@
+From cf31acecb91ddeab131652ce81975d8a28f641a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Apr 2021 11:11:06 +0100
+Subject: serial: meson: remove redundant initialization of variable id
+
+From: Colin Ian King <colin.king@canonical.com>
+
+[ Upstream commit 021212f5335229ed12e3d31f9b7d30bd3bb66f7d ]
+
+The variable id being initialized with a value that is never read
+and it is being updated later with a new value. The initialization is
+redundant and can be removed. Since id is just being used in a for-loop
+inside a local scope, move the declaration of id to that scope.
+
+Reviewed-by: Kevin Hilman <khilman@baylibre.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Addresses-Coverity: ("Unused value")
+Link: https://lore.kernel.org/r/20210426101106.9122-1-colin.king@canonical.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 2a1d728f20ed ("tty: serial: meson: fix hard LOCKUP on crtscts mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/meson_uart.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
+index 91b7359b79a2f..d06653493f0ef 100644
+--- a/drivers/tty/serial/meson_uart.c
++++ b/drivers/tty/serial/meson_uart.c
+@@ -729,12 +729,13 @@ static int meson_uart_probe(struct platform_device *pdev)
+       struct resource *res_mem, *res_irq;
+       struct uart_port *port;
+       int ret = 0;
+-      int id = -1;
+       if (pdev->dev.of_node)
+               pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
+       if (pdev->id < 0) {
++              int id;
++
+               for (id = AML_UART_PORT_OFFSET; id < AML_UART_PORT_NUM; id++) {
+                       if (!meson_ports[id]) {
+                               pdev->id = id;
+-- 
+2.42.0
+
diff --git a/queue-5.10/serial-meson-use-platform_get_irq-to-get-the-interru.patch b/queue-5.10/serial-meson-use-platform_get_irq-to-get-the-interru.patch
new file mode 100644 (file)
index 0000000..ffcda31
--- /dev/null
@@ -0,0 +1,69 @@
+From c81458f574f90ebc1aaaff23f62ce684bd1b7059 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Dec 2021 14:29:10 +0000
+Subject: serial: meson: Use platform_get_irq() to get the interrupt
+
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+[ Upstream commit 5b68061983471470d4109bac776145245f06bc09 ]
+
+platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
+allocation of IRQ resources in DT core code, this causes an issue
+when using hierarchical interrupt domains using "interrupts" property
+in the node as this bypasses the hierarchical setup and messes up the
+irq chaining.
+
+In preparation for removal of static setup of IRQ resource from DT core
+code use platform_get_irq().
+
+Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Link: https://lore.kernel.org/r/20211224142917.6966-5-prabhakar.mahadev-lad.rj@bp.renesas.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 2a1d728f20ed ("tty: serial: meson: fix hard LOCKUP on crtscts mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/meson_uart.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
+index 78bda91a6bf15..bdc394afec5be 100644
+--- a/drivers/tty/serial/meson_uart.c
++++ b/drivers/tty/serial/meson_uart.c
+@@ -726,10 +726,11 @@ static int meson_uart_probe_clocks(struct platform_device *pdev,
+ static int meson_uart_probe(struct platform_device *pdev)
+ {
+-      struct resource *res_mem, *res_irq;
++      struct resource *res_mem;
+       struct uart_port *port;
+       u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
+       int ret = 0;
++      int irq;
+       if (pdev->dev.of_node)
+               pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
+@@ -752,9 +753,9 @@ static int meson_uart_probe(struct platform_device *pdev)
+       if (!res_mem)
+               return -ENODEV;
+-      res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+-      if (!res_irq)
+-              return -ENODEV;
++      irq = platform_get_irq(pdev, 0);
++      if (irq < 0)
++              return irq;
+       of_property_read_u32(pdev->dev.of_node, "fifo-size", &fifosize);
+@@ -779,7 +780,7 @@ static int meson_uart_probe(struct platform_device *pdev)
+       port->iotype = UPIO_MEM;
+       port->mapbase = res_mem->start;
+       port->mapsize = resource_size(res_mem);
+-      port->irq = res_irq->start;
++      port->irq = irq;
+       port->flags = UPF_BOOT_AUTOCONF | UPF_LOW_LATENCY;
+       port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MESON_CONSOLE);
+       port->dev = &pdev->dev;
+-- 
+2.42.0
+
index a6a77c0a9e7402a60837838cf374854d98deb51b..c74b63c7344a57d8afacd08d8ad906a4e94cb0ca 100644 (file)
@@ -138,3 +138,25 @@ mm-cma-use-nth_page-in-place-of-direct-struct-page-manipulation.patch
 mm-memory_hotplug-use-pfn-math-in-place-of-direct-struct-page-manipulation.patch
 mtd-cfi_cmdset_0001-byte-swap-otp-info.patch
 i3c-master-cdns-fix-reading-status-register.patch
+serial-meson-remove-redundant-initialization-of-vari.patch
+tty-serial-meson-retrieve-port-fifo-size-from-dt.patch
+serial-meson-use-platform_get_irq-to-get-the-interru.patch
+tty-serial-meson-fix-hard-lockup-on-crtscts-mode.patch
+cpufreq-stats-fix-buffer-overflow-detection-in-trans.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
+pci-dwc-move-dbi-dbi2-and-addr_space-resource-setup-.patch
+pci-dwc-dra7xx-use-the-common-msi-irq_chip.patch
+pci-dwc-drop-the-.set_num_vectors-host-op.patch
+pci-dwc-move-msi-interrupt-setup-into-dwc-common-cod.patch
+pci-dwc-rework-msi-initialization.patch
+pci-dwc-move-link-handling-into-common-code.patch
+pci-dwc-move-dw_pcie_msi_init-into-core.patch
+pci-dwc-move-dw_pcie_setup_rc-to-dwc-common-code.patch
+pci-dwc-exynos-rework-the-driver-to-support-exynos54.patch
+pci-exynos-don-t-discard-.remove-callback.patch
+arm64-dts-qcom-ipq6018-switch-tcsr-mutex-to-mmio.patch
+arm64-dts-qcom-ipq6018-fix-tcsr_mutex-register-size.patch
diff --git a/queue-5.10/tty-serial-meson-fix-hard-lockup-on-crtscts-mode.patch b/queue-5.10/tty-serial-meson-fix-hard-lockup-on-crtscts-mode.patch
new file mode 100644 (file)
index 0000000..74402d3
--- /dev/null
@@ -0,0 +1,101 @@
+From 2bcb06935a5183deb0a4f37b09f622964de14800 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Oct 2023 11:39:26 +0000
+Subject: tty: serial: meson: fix hard LOCKUP on crtscts mode
+
+From: Pavel Krasavin <pkrasavin@imaqliq.com>
+
+[ Upstream commit 2a1d728f20edeee7f26dc307ed9df4e0d23947ab ]
+
+There might be hard lockup if we set crtscts mode on port without RTS/CTS configured:
+
+# stty -F /dev/ttyAML6 crtscts; echo 1 > /dev/ttyAML6; echo 2 > /dev/ttyAML6
+[   95.890386] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
+[   95.890857] rcu:     3-...0: (201 ticks this GP) idle=e33c/1/0x4000000000000000 softirq=5844/5846 fqs=4984
+[   95.900212] rcu:     (detected by 2, t=21016 jiffies, g=7753, q=296 ncpus=4)
+[   95.906972] Task dump for CPU 3:
+[   95.910178] task:bash            state:R  running task     stack:0     pid:205   ppid:1      flags:0x00000202
+[   95.920059] Call trace:
+[   95.922485]  __switch_to+0xe4/0x168
+[   95.925951]  0xffffff8003477508
+[   95.974379] watchdog: Watchdog detected hard LOCKUP on cpu 3
+[   95.974424] Modules linked in: 88x2cs(O) rtc_meson_vrtc
+
+Possible solution would be to not allow to setup crtscts on such port.
+
+Tested on S905X3 based board.
+
+Fixes: ff7693d079e5 ("ARM: meson: serial: add MesonX SoC on-chip uart driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Pavel Krasavin <pkrasavin@imaqliq.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Reviewed-by: Dmitry Rokosov <ddrokosov@salutedevices.com>
+
+v6: stable tag added
+v5: https://lore.kernel.org/lkml/OF43DA36FF.2BD3BB21-ON00258A47.005A8125-00258A47.005A9513@gdc.ru/
+added missed Reviewed-by tags, Fixes tag added according to Dmitry and Neil notes
+v4: https://lore.kernel.org/lkml/OF55521400.7512350F-ON00258A47.003F7254-00258A47.0040E15C@gdc.ru/
+More correct patch subject according to Jiri's note
+v3: https://lore.kernel.org/lkml/OF6CF5FFA0.CCFD0E8E-ON00258A46.00549EDF-00258A46.0054BB62@gdc.ru/
+"From:" line added to the mail
+v2: https://lore.kernel.org/lkml/OF950BEF72.7F425944-ON00258A46.00488A76-00258A46.00497D44@gdc.ru/
+braces for single statement removed according to Dmitry's note
+v1: https://lore.kernel.org/lkml/OF28B2B8C9.5BC0CD28-ON00258A46.0037688F-00258A46.0039155B@gdc.ru/
+Link: https://lore.kernel.org/r/OF66360032.51C36182-ON00258A48.003F656B-00258A48.0040092C@gdc.ru
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/meson_uart.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
+index bdc394afec5be..bb66a3f06626c 100644
+--- a/drivers/tty/serial/meson_uart.c
++++ b/drivers/tty/serial/meson_uart.c
+@@ -370,10 +370,14 @@ static void meson_uart_set_termios(struct uart_port *port,
+       else
+               val |= AML_UART_STOP_BIT_1SB;
+-      if (cflags & CRTSCTS)
+-              val &= ~AML_UART_TWO_WIRE_EN;
+-      else
++      if (cflags & CRTSCTS) {
++              if (port->flags & UPF_HARD_FLOW)
++                      val &= ~AML_UART_TWO_WIRE_EN;
++              else
++                      termios->c_cflag &= ~CRTSCTS;
++      } else {
+               val |= AML_UART_TWO_WIRE_EN;
++      }
+       writel(val, port->membase + AML_UART_CONTROL);
+@@ -731,6 +735,7 @@ static int meson_uart_probe(struct platform_device *pdev)
+       u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
+       int ret = 0;
+       int irq;
++      bool has_rtscts;
+       if (pdev->dev.of_node)
+               pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
+@@ -758,6 +763,7 @@ static int meson_uart_probe(struct platform_device *pdev)
+               return irq;
+       of_property_read_u32(pdev->dev.of_node, "fifo-size", &fifosize);
++      has_rtscts = of_property_read_bool(pdev->dev.of_node, "uart-has-rtscts");
+       if (meson_ports[pdev->id]) {
+               dev_err(&pdev->dev, "port %d already allocated\n", pdev->id);
+@@ -782,6 +788,8 @@ static int meson_uart_probe(struct platform_device *pdev)
+       port->mapsize = resource_size(res_mem);
+       port->irq = irq;
+       port->flags = UPF_BOOT_AUTOCONF | UPF_LOW_LATENCY;
++      if (has_rtscts)
++              port->flags |= UPF_HARD_FLOW;
+       port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MESON_CONSOLE);
+       port->dev = &pdev->dev;
+       port->line = pdev->id;
+-- 
+2.42.0
+
diff --git a/queue-5.10/tty-serial-meson-retrieve-port-fifo-size-from-dt.patch b/queue-5.10/tty-serial-meson-retrieve-port-fifo-size-from-dt.patch
new file mode 100644 (file)
index 0000000..3e5ffda
--- /dev/null
@@ -0,0 +1,55 @@
+From 9d2cae48b9b4411bf46cf89fbcac9625931c327a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 May 2021 09:58:32 +0200
+Subject: tty: serial: meson: retrieve port FIFO size from DT
+
+From: Neil Armstrong <narmstrong@baylibre.com>
+
+[ Upstream commit 27d44e05d7b85d9d4cfe0a3c0663ea49752ece93 ]
+
+Now the DT bindings has a property to get the FIFO size for a particular port,
+retrieve it and use to setup the FIFO interrupts threshold.
+
+Reviewed-by: Kevin Hilman <khilman@baylibre.com>
+Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
+Link: https://lore.kernel.org/r/20210518075833.3736038-3-narmstrong@baylibre.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 2a1d728f20ed ("tty: serial: meson: fix hard LOCKUP on crtscts mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/meson_uart.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
+index d06653493f0ef..78bda91a6bf15 100644
+--- a/drivers/tty/serial/meson_uart.c
++++ b/drivers/tty/serial/meson_uart.c
+@@ -728,6 +728,7 @@ static int meson_uart_probe(struct platform_device *pdev)
+ {
+       struct resource *res_mem, *res_irq;
+       struct uart_port *port;
++      u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
+       int ret = 0;
+       if (pdev->dev.of_node)
+@@ -755,6 +756,8 @@ static int meson_uart_probe(struct platform_device *pdev)
+       if (!res_irq)
+               return -ENODEV;
++      of_property_read_u32(pdev->dev.of_node, "fifo-size", &fifosize);
++
+       if (meson_ports[pdev->id]) {
+               dev_err(&pdev->dev, "port %d already allocated\n", pdev->id);
+               return -EBUSY;
+@@ -784,7 +787,7 @@ static int meson_uart_probe(struct platform_device *pdev)
+       port->type = PORT_MESON;
+       port->x_char = 0;
+       port->ops = &meson_uart_ops;
+-      port->fifosize = 64;
++      port->fifosize = fifosize;
+       meson_ports[pdev->id] = port;
+       platform_set_drvdata(pdev, port);
+-- 
+2.42.0
+