mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
Linux 7.3
-----BEGIN PGP SIGNATURE----- iQFSBAABCgA8FiEEq68RxlopcLEwq+PEeb4+QwBBGIYFAmrVUvIeHHRvcnZhbGRz QGxpbnV4LWZvdW5kYXRpb24ub3JnAAoJEHm+PkMAQRiGuOsH/RyuYfaTGIuBYBAZ uJ1amb0J9CRet0DrzOHiOQHOIousbKBhTi7chGw7LVW+tJ9GIi0Qm6biw5e/oXhG tYGznbRVW8mYChwzOXHg2JiIQDBIa4cAZ59feUpCWMEpbK7ZtNnvBK7yNIn2sQJu Dc285AnbpaORcfkz7zF3R2T4VbszJj8/nVY2tFEJ6tjlMrsCIpdKoSpuHq5kwsin Flhnc4NL1IEZNyYekmGT7M8fAT9o456J4Hv0v/swmWvK5TM1kg0eaCuEcOM69pg1 /aWyrwfNlMk7fzyL3HRQjMe5AqSTMU+VQN5NvMGtHbMWdhFwqS6apV0b314pmY5Q rQaDG1I= =QIzp -----END PGP SIGNATURE----- Merge tag 'v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux into gpio/for-current Linux 7.3
This commit is contained in:
commit
2450bb0473
12
MAINTAINERS
12
MAINTAINERS
|
|
@ -8013,6 +8013,7 @@ F: include/uapi/drm/ivpu_accel.h
|
|||
|
||||
DRM ACCEL DRIVER FOR ROCKCHIP NPU
|
||||
M: Tomeu Vizoso <tomeu@tomeuvizoso.net>
|
||||
R: Heiko Stuebner <heiko@sntech.de>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Supported
|
||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
|
|
@ -8170,7 +8171,6 @@ F: drivers/gpu/drm/tiny/hx8357d.c
|
|||
|
||||
DRM DRIVER FOR HYPERV SYNTHETIC VIDEO DEVICE
|
||||
M: Dexuan Cui <decui@microsoft.com>
|
||||
M: Long Li <longli@microsoft.com>
|
||||
M: Saurabh Sengar <ssengar@linux.microsoft.com>
|
||||
L: linux-hyperv@vger.kernel.org
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
|
|
@ -8575,7 +8575,7 @@ F: Documentation/devicetree/bindings/display/panel/synaptics,r63353.yaml
|
|||
F: drivers/gpu/drm/panel/panel-synaptics-r63353.c
|
||||
|
||||
DRM DRIVER FOR SYNOPSYS DESIGNWARE DISPLAYPORT BRIDGE
|
||||
M: Andy Yan <andy.yan@rock-chips.com>
|
||||
M: Andy Yan <andyshrk@163.com>
|
||||
S: Maintained
|
||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
F: Documentation/devicetree/bindings/display/rockchip/rockchip,dw-dp.yaml
|
||||
|
|
@ -8928,7 +8928,7 @@ F: include/linux/platform_data/shmob_drm.h
|
|||
DRM DRIVERS FOR ROCKCHIP
|
||||
M: Sandy Huang <hjc@rock-chips.com>
|
||||
M: Heiko Stübner <heiko@sntech.de>
|
||||
M: Andy Yan <andy.yan@rock-chips.com>
|
||||
M: Andy Yan <andyshrk@163.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
L: linux-rockchip@lists.infradead.org
|
||||
S: Maintained
|
||||
|
|
@ -10102,7 +10102,6 @@ F: tools/testing/selftests/mount_setattr/
|
|||
|
||||
FILESYSTEMS [IOMAP]
|
||||
M: Christian Brauner <brauner@kernel.org>
|
||||
R: Darrick J. Wong <djwong@kernel.org>
|
||||
L: linux-xfs@vger.kernel.org
|
||||
L: linux-fsdevel@vger.kernel.org
|
||||
S: Supported
|
||||
|
|
@ -12161,11 +12160,9 @@ S: Maintained
|
|||
F: drivers/media/i2c/hi847.c
|
||||
|
||||
Hyper-V/Azure CORE AND DRIVERS
|
||||
M: "K. Y. Srinivasan" <kys@microsoft.com>
|
||||
M: Haiyang Zhang <haiyangz@microsoft.com>
|
||||
M: Wei Liu <wei.liu@kernel.org>
|
||||
M: Dexuan Cui <decui@microsoft.com>
|
||||
M: Long Li <longli@microsoft.com>
|
||||
L: linux-hyperv@vger.kernel.org
|
||||
S: Supported
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git
|
||||
|
|
@ -12883,7 +12880,7 @@ S: Maintained
|
|||
F: drivers/power/supply/ip5xxx_power.c
|
||||
|
||||
INNOSILICON HDMI BRIDGE DRIVER
|
||||
M: Andy Yan <andy.yan@rock-chips.com>
|
||||
M: Andy Yan <andyshrk@163.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Maintained
|
||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
|
|
@ -18818,6 +18815,7 @@ F: drivers/hwmon/nct7363.c
|
|||
|
||||
NETCONSOLE
|
||||
M: Breno Leitao <leitao@debian.org>
|
||||
R: Gustavo Luiz Duarte <gustavold@gmail.com>
|
||||
S: Maintained
|
||||
F: Documentation/networking/netconsole.rst
|
||||
F: drivers/net/netconsole.c
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -2,7 +2,7 @@
|
|||
VERSION = 7
|
||||
PATCHLEVEL = 3
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc7
|
||||
EXTRAVERSION =
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
|||
|
|
@ -1376,8 +1376,8 @@ optfclk_pciephy_div: clock-optfclk-pciephy-div-8@4a00821c {
|
|||
clocks = <&apll_pcie_ck>;
|
||||
#clock-cells = <0>;
|
||||
reg = <0x021c>;
|
||||
ti,dividers = <2>, <1>;
|
||||
ti,bit-shift = <8>;
|
||||
ti,max-div = <2>;
|
||||
};
|
||||
|
||||
apll_pcie_clkvcoldo: clock-apll-pcie-clkvcoldo {
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ CONFIG_BLK_DEV_SD=y
|
|||
# CONFIG_BLK_DEV_BSG is not set
|
||||
# CONFIG_SCSI_LOWLEVEL is not set
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_NET_DSA_MICROCHIP_KSZ9477=m
|
||||
CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI=m
|
||||
CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m
|
||||
CONFIG_NET_DSA_MICROCHIP_KSZ_SPI=m
|
||||
# CONFIG_NET_VENDOR_BROADCOM is not set
|
||||
CONFIG_MACB=y
|
||||
# CONFIG_NET_VENDOR_CIRRUS is not set
|
||||
|
|
|
|||
|
|
@ -9,4 +9,17 @@ aliases {
|
|||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
bus@0 {
|
||||
pwm@c6a0000 {
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
fan: pwm-fan {
|
||||
compatible = "pwm-fan";
|
||||
cooling-levels = <77 102 140 192 255>;
|
||||
pwms = <&pwm4 0 40000>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3356,6 +3356,18 @@ i2c3: i2c@c610000 {
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
pwm4: pwm@c6a0000 {
|
||||
compatible = "nvidia,tegra264-pwm";
|
||||
reg = <0x0 0xc6a0000 0x0 0x10000>;
|
||||
status = "disabled";
|
||||
|
||||
clocks = <&bpmp TEGRA264_CLK_PWM4>;
|
||||
resets = <&bpmp TEGRA264_RESET_PWM4>;
|
||||
reset-names = "pwm";
|
||||
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
|
||||
pinmux_aon: pinmux@c7a2000 {
|
||||
compatible = "nvidia,tegra264-pinmux-aon";
|
||||
reg = <0x0 0x0c7a2000 0x0 0x2000>;
|
||||
|
|
@ -3537,11 +3549,11 @@ cmdqv4: cmdqv@b200000 {
|
|||
|
||||
pci@c000000 {
|
||||
compatible = "nvidia,tegra264-pcie";
|
||||
reg = <0xd0 0xb0000000 0x0 0x10000000>,
|
||||
<0x00 0x0c000000 0x0 0x00004000>,
|
||||
reg = <0x00 0x0c000000 0x0 0x00004000>,
|
||||
<0x00 0x0c004000 0x0 0x00001000>,
|
||||
<0x00 0x0c005000 0x0 0x00001000>;
|
||||
reg-names = "ecam", "xal", "xtl", "xtl-pri";
|
||||
<0x00 0x0c005000 0x0 0x00001000>,
|
||||
<0xd0 0xb0000000 0x0 0x10000000>;
|
||||
reg-names = "xal", "xtl", "xtl-pri", "ecam";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
device_type = "pci";
|
||||
|
|
@ -3565,6 +3577,16 @@ pci@c000000 {
|
|||
|
||||
nvidia,bpmp = <&bpmp 0>;
|
||||
status = "disabled";
|
||||
|
||||
pcie@0 {
|
||||
device_type = "pci";
|
||||
compatible = "pciclass,0604";
|
||||
reg = <0x0 0x0 0x0 0x0 0x0>;
|
||||
bus-range = <0x01 0xff>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
};
|
||||
};
|
||||
|
||||
pinmux_main: pinmux@c281000 {
|
||||
|
|
@ -3661,6 +3683,66 @@ i2c16: i2c@c430000 {
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
pwm2: pwm@c5e0000 {
|
||||
compatible = "nvidia,tegra264-pwm";
|
||||
reg = <0x0 0xc5e0000 0x0 0x10000>;
|
||||
status = "disabled";
|
||||
|
||||
clocks = <&bpmp TEGRA264_CLK_PWM2>;
|
||||
resets = <&bpmp TEGRA264_RESET_PWM2>;
|
||||
reset-names = "pwm";
|
||||
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
|
||||
pwm3: pwm@c5f0000 {
|
||||
compatible = "nvidia,tegra264-pwm";
|
||||
reg = <0x0 0xc5f0000 0x0 0x10000>;
|
||||
status = "disabled";
|
||||
|
||||
clocks = <&bpmp TEGRA264_CLK_PWM3>;
|
||||
resets = <&bpmp TEGRA264_RESET_PWM3>;
|
||||
reset-names = "pwm";
|
||||
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
|
||||
pwm5: pwm@c600000 {
|
||||
compatible = "nvidia,tegra264-pwm";
|
||||
reg = <0x0 0xc600000 0x0 0x10000>;
|
||||
status = "disabled";
|
||||
|
||||
clocks = <&bpmp TEGRA264_CLK_PWM5>;
|
||||
resets = <&bpmp TEGRA264_RESET_PWM5>;
|
||||
reset-names = "pwm";
|
||||
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
|
||||
pwm9: pwm@c610000 {
|
||||
compatible = "nvidia,tegra264-pwm";
|
||||
reg = <0x0 0xc610000 0x0 0x10000>;
|
||||
status = "disabled";
|
||||
|
||||
clocks = <&bpmp TEGRA264_CLK_PWM9>;
|
||||
resets = <&bpmp TEGRA264_RESET_PWM9>;
|
||||
reset-names = "pwm";
|
||||
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
|
||||
pwm10: pwm@c620000 {
|
||||
compatible = "nvidia,tegra264-pwm";
|
||||
reg = <0x0 0xc620000 0x0 0x10000>;
|
||||
status = "disabled";
|
||||
|
||||
clocks = <&bpmp TEGRA264_CLK_PWM10>;
|
||||
resets = <&bpmp TEGRA264_RESET_PWM10>;
|
||||
reset-names = "pwm";
|
||||
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
|
||||
i2c0: i2c@c630000 {
|
||||
compatible = "nvidia,tegra264-i2c";
|
||||
reg = <0x00 0x0c630000 0x0 0x10000>;
|
||||
|
|
@ -3990,12 +4072,12 @@ gpio_uphy: gpio@8300000 {
|
|||
|
||||
pci@8400000 {
|
||||
compatible = "nvidia,tegra264-pcie";
|
||||
reg = <0xa8 0xb0000000 0x0 0x10000000>,
|
||||
<0x00 0x08400000 0x0 0x00004000>,
|
||||
reg = <0x00 0x08400000 0x0 0x00004000>,
|
||||
<0x00 0x08404000 0x0 0x00001000>,
|
||||
<0x00 0x08405000 0x0 0x00001000>,
|
||||
<0x00 0x08410000 0x0 0x00010000>;
|
||||
reg-names = "ecam", "xal", "xtl", "xtl-pri", "xpl";
|
||||
<0x00 0x08410000 0x0 0x00010000>,
|
||||
<0xa8 0xb0000000 0x0 0x10000000>;
|
||||
reg-names = "xal", "xtl", "xtl-pri", "xpl", "ecam";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
device_type = "pci";
|
||||
|
|
@ -4018,16 +4100,26 @@ pci@8400000 {
|
|||
|
||||
nvidia,bpmp = <&bpmp 1>;
|
||||
status = "disabled";
|
||||
|
||||
pcie@0 {
|
||||
device_type = "pci";
|
||||
compatible = "pciclass,0604";
|
||||
reg = <0x0 0x0 0x0 0x0 0x0>;
|
||||
bus-range = <0x01 0xff>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
};
|
||||
};
|
||||
|
||||
pci@8420000 {
|
||||
compatible = "nvidia,tegra264-pcie";
|
||||
reg = <0xb0 0xb0000000 0x0 0x10000000>,
|
||||
<0x00 0x08420000 0x0 0x00004000>,
|
||||
reg = <0x00 0x08420000 0x0 0x00004000>,
|
||||
<0x00 0x08424000 0x0 0x00001000>,
|
||||
<0x00 0x08425000 0x0 0x00001000>,
|
||||
<0x00 0x08430000 0x0 0x00010000>;
|
||||
reg-names = "ecam", "xal", "xtl", "xtl-pri", "xpl";
|
||||
<0x00 0x08430000 0x0 0x00010000>,
|
||||
<0xb0 0xb0000000 0x0 0x10000000>;
|
||||
reg-names = "xal", "xtl", "xtl-pri", "xpl", "ecam";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
device_type = "pci";
|
||||
|
|
@ -4050,16 +4142,26 @@ pci@8420000 {
|
|||
|
||||
nvidia,bpmp = <&bpmp 2>;
|
||||
status = "disabled";
|
||||
|
||||
pcie@0 {
|
||||
device_type = "pci";
|
||||
compatible = "pciclass,0604";
|
||||
reg = <0x0 0x0 0x0 0x0 0x0>;
|
||||
bus-range = <0x01 0xff>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
};
|
||||
};
|
||||
|
||||
pci@8440000 {
|
||||
compatible = "nvidia,tegra264-pcie";
|
||||
reg = <0xb8 0xb0000000 0x0 0x10000000>,
|
||||
<0x00 0x08440000 0x0 0x00004000>,
|
||||
reg = <0x00 0x08440000 0x0 0x00004000>,
|
||||
<0x00 0x08444000 0x0 0x00001000>,
|
||||
<0x00 0x08445000 0x0 0x00001000>,
|
||||
<0x00 0x08450000 0x0 0x00010000>;
|
||||
reg-names = "ecam", "xal", "xtl", "xtl-pri", "xpl";
|
||||
<0x00 0x08450000 0x0 0x00010000>,
|
||||
<0xb8 0xb0000000 0x0 0x10000000>;
|
||||
reg-names = "xal", "xtl", "xtl-pri", "xpl", "ecam";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
device_type = "pci";
|
||||
|
|
@ -4082,16 +4184,26 @@ pci@8440000 {
|
|||
|
||||
nvidia,bpmp = <&bpmp 3>;
|
||||
status = "disabled";
|
||||
|
||||
pcie@0 {
|
||||
device_type = "pci";
|
||||
compatible = "pciclass,0604";
|
||||
reg = <0x0 0x0 0x0 0x0 0x0>;
|
||||
bus-range = <0x01 0xff>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
};
|
||||
};
|
||||
|
||||
pci@8460000 {
|
||||
compatible = "nvidia,tegra264-pcie";
|
||||
reg = <0xc0 0xb0000000 0x0 0x10000000>,
|
||||
<0x00 0x08460000 0x0 0x00004000>,
|
||||
reg = <0x00 0x08460000 0x0 0x00004000>,
|
||||
<0x00 0x08464000 0x0 0x00001000>,
|
||||
<0x00 0x08465000 0x0 0x00001000>,
|
||||
<0x00 0x08470000 0x0 0x00010000>;
|
||||
reg-names = "ecam", "xal", "xtl", "xtl-pri", "xpl";
|
||||
<0x00 0x08470000 0x0 0x00010000>,
|
||||
<0xc0 0xb0000000 0x0 0x10000000>;
|
||||
reg-names = "xal", "xtl", "xtl-pri", "xpl", "ecam";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
device_type = "pci";
|
||||
|
|
@ -4114,16 +4226,26 @@ pci@8460000 {
|
|||
|
||||
nvidia,bpmp = <&bpmp 4>;
|
||||
status = "disabled";
|
||||
|
||||
pcie@0 {
|
||||
device_type = "pci";
|
||||
compatible = "pciclass,0604";
|
||||
reg = <0x0 0x0 0x0 0x0 0x0>;
|
||||
bus-range = <0x01 0xff>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
};
|
||||
};
|
||||
|
||||
pci@8480000 {
|
||||
compatible = "nvidia,tegra264-pcie";
|
||||
reg = <0xc8 0xb0000000 0x0 0x10000000>,
|
||||
<0x00 0x08480000 0x0 0x00004000>,
|
||||
reg = <0x00 0x08480000 0x0 0x00004000>,
|
||||
<0x00 0x08484000 0x0 0x00001000>,
|
||||
<0x00 0x08485000 0x0 0x00001000>,
|
||||
<0x00 0x08490000 0x0 0x00010000>;
|
||||
reg-names = "ecam", "xal", "xtl", "xtl-pri", "xpl";
|
||||
<0x00 0x08490000 0x0 0x00010000>,
|
||||
<0xc8 0xb0000000 0x0 0x10000000>;
|
||||
reg-names = "xal", "xtl", "xtl-pri", "xpl", "ecam";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
device_type = "pci";
|
||||
|
|
@ -4146,6 +4268,16 @@ pci@8480000 {
|
|||
|
||||
nvidia,bpmp = <&bpmp 5>;
|
||||
status = "disabled";
|
||||
|
||||
pcie@0 {
|
||||
device_type = "pci";
|
||||
compatible = "pciclass,0604";
|
||||
reg = <0x0 0x0 0x0 0x0 0x0>;
|
||||
bus-range = <0x01 0xff>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ static inline __sum16 csum_fold(__wsum sum)
|
|||
"add %0, %0, r8\n"
|
||||
"nor %0, %0, %0\n"
|
||||
: "=r" (sum)
|
||||
: "r" (sum << 16), "0" (sum)
|
||||
: "r" ((__force u32)sum << 16), "0" (sum)
|
||||
: "r8");
|
||||
return (__force __sum16) sum;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,10 +90,6 @@ regulator-1v8-syzygy {
|
|||
};
|
||||
|
||||
&gpio0 {
|
||||
interrupts = <13>, <14>, <15>, <16>,
|
||||
<17>, <18>, <19>, <20>,
|
||||
<21>, <22>, <23>, <24>,
|
||||
<25>, <26>;
|
||||
ngpios = <14>;
|
||||
gpio-line-names = "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "SD_CARD_CS", "USER_BUTTON";
|
||||
|
|
@ -101,12 +97,6 @@ &gpio0 {
|
|||
};
|
||||
|
||||
&gpio1 {
|
||||
interrupts = <27>, <28>, <29>, <30>,
|
||||
<31>, <32>, <33>, <34>,
|
||||
<35>, <36>, <37>, <38>,
|
||||
<39>, <40>, <41>, <42>,
|
||||
<43>, <44>, <45>, <46>,
|
||||
<47>, <48>, <49>, <50>;
|
||||
ngpios = <24>;
|
||||
gpio-line-names = "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
|
|
@ -115,14 +105,6 @@ &gpio1 {
|
|||
};
|
||||
|
||||
&gpio2 {
|
||||
interrupts = <53>, <53>, <53>, <53>,
|
||||
<53>, <53>, <53>, <53>,
|
||||
<53>, <53>, <53>, <53>,
|
||||
<53>, <53>, <53>, <53>,
|
||||
<53>, <53>, <53>, <53>,
|
||||
<53>, <53>, <53>, <53>,
|
||||
<53>, <53>, <53>, <53>,
|
||||
<53>, <53>, <53>, <53>;
|
||||
ngpios = <32>;
|
||||
gpio-line-names = "P8_PIN3_USER_LED_0", "P8_PIN4_USER_LED_1", "P8_PIN5_USER_LED_2",
|
||||
"P8_PIN6_USER_LED_3", "P8_PIN7_USER_LED_4", "P8_PIN8_USER_LED_5",
|
||||
|
|
|
|||
|
|
@ -474,6 +474,9 @@
|
|||
/* DMR */
|
||||
#define DMR_IMH1_HIOP_MMIO_BASE 0x1ffff6ae7000
|
||||
#define DMR_HIOP_MMIO_SIZE 0x8000
|
||||
#define DMR_CXLCM_PMON_CTL_INVERT BIT(21)
|
||||
#define DMR_CXLCM_PMON_RAW_EVENT_MASK (GENERIC_PMON_RAW_EVENT_MASK | \
|
||||
DMR_CXLCM_PMON_CTL_INVERT)
|
||||
#define DMR_CXLCM_EVENT_MASK_EXT 0xf
|
||||
#define DMR_HAMVF_EVENT_MASK_EXT 0xffffffff
|
||||
#define DMR_PCIE4_EVENT_MASK_EXT 0xffffff
|
||||
|
|
@ -6696,7 +6699,7 @@ static struct event_constraint dmr_uncore_cxlcm_constraints[] = {
|
|||
|
||||
static struct intel_uncore_type dmr_uncore_cxlcm = {
|
||||
.name = "cxlcm",
|
||||
.event_mask = GENERIC_PMON_RAW_EVENT_MASK,
|
||||
.event_mask = DMR_CXLCM_PMON_RAW_EVENT_MASK,
|
||||
.event_mask_ext = DMR_CXLCM_EVENT_MASK_EXT,
|
||||
.constraints = dmr_uncore_cxlcm_constraints,
|
||||
.format_group = &dmr_cxlcm_uncore_format_group,
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@ static void __init hv_stimer_setup_percpu_clockev(void)
|
|||
int ret;
|
||||
|
||||
/*
|
||||
* Continue afters errors in setting up stimer clockevents
|
||||
* Continue after errors in setting up stimer clockevents
|
||||
* as we can run with the LAPIC timer as a fallback.
|
||||
*/
|
||||
ret = hv_stimer_alloc(false);
|
||||
|
|
@ -434,7 +434,7 @@ static void __init hv_stimer_setup_percpu_clockev(void)
|
|||
pr_warn("stimer setup failed with error %d\n", ret);
|
||||
|
||||
/*
|
||||
* Still register the LAPIC timer to allows users
|
||||
* Still register the LAPIC timer to allow users
|
||||
* to switch to LAPIC timer via /sys, if they want to.
|
||||
*/
|
||||
if (old_setup_percpu_clockev)
|
||||
|
|
@ -727,7 +727,8 @@ int hv_apicid_to_vp_index(u32 apic_id)
|
|||
input->partition_id = HV_PARTITION_ID_SELF;
|
||||
input->apic_ids[0] = apic_id;
|
||||
|
||||
output = *this_cpu_ptr(hyperv_pcpu_output_arg);
|
||||
/* Treat input as having 2 APIC IDs so output is 64-bit aligned */
|
||||
output = (void *)input + struct_size(input, apic_ids, 2);
|
||||
|
||||
control = HV_HYPERCALL_REP_COMP_1 | HVCALL_GET_VP_INDEX_FROM_APIC_ID;
|
||||
status = hv_do_hypercall(control, input, output);
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ static inline int insn_offset_immediate(struct insn *insn)
|
|||
* are repeated, it cannot be used for looping over the prefixes.
|
||||
*/
|
||||
#define for_each_insn_prefix(insn, prefix) \
|
||||
for (int idx = 0; idx < ARRAY_SIZE(insn->prefixes.bytes) && (prefix = insn->prefixes.bytes[idx]) != 0; idx++)
|
||||
for (int __i = 0; __i < ARRAY_SIZE(insn->prefixes.bytes) && (prefix = insn->prefixes.bytes[__i]) != 0; __i++)
|
||||
|
||||
#define POP_SS_OPCODE 0x1f
|
||||
#define MOV_SREG_OPCODE 0x8e
|
||||
|
|
|
|||
|
|
@ -1455,7 +1455,8 @@ asm( ".pushsection .rodata \n"
|
|||
"fineibt_paranoid_start: \n"
|
||||
" mov $0x12345678, %eax \n"
|
||||
" cmpl -11(%r11), %eax \n"
|
||||
" cs lea -0x10(%r11), %r11 \n"
|
||||
" .byte 0x2e \n"
|
||||
" lea -0x10(%r11), %r11 \n"
|
||||
"#fineibt_caller_size: \n"
|
||||
" jne fineibt_paranoid_start+0xd \n"
|
||||
"fineibt_paranoid_ind: \n"
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@
|
|||
#include <asm/insn-eval.h>
|
||||
|
||||
/*
|
||||
* Returns the target address and the expected type when regs->ip points
|
||||
* Returns the target address and the expected type when addr points
|
||||
* to a compiler-generated CFI trap.
|
||||
*/
|
||||
static bool decode_cfi_insn(struct pt_regs *regs, unsigned long *target,
|
||||
u32 *type)
|
||||
static bool decode_cfi_insn(struct pt_regs *regs, unsigned long addr,
|
||||
unsigned long *target, u32 *type)
|
||||
{
|
||||
char buffer[MAX_INSN_SIZE];
|
||||
struct insn insn;
|
||||
|
|
@ -29,13 +29,13 @@ static bool decode_cfi_insn(struct pt_regs *regs, unsigned long *target,
|
|||
* movl -<id>, %r10d ; 6 bytes
|
||||
* addl -<pos>(%reg), %r10d; 4 bytes
|
||||
* je .Ltmp1 ; 2 bytes
|
||||
* ud2 ; <- regs->ip
|
||||
* ud2 ; <- addr
|
||||
* .Ltmp1:
|
||||
*
|
||||
* We can decode the expected type and the target address from the
|
||||
* movl/addl instructions.
|
||||
*/
|
||||
if (copy_from_kernel_nofault(buffer, (void *)regs->ip - 12, MAX_INSN_SIZE))
|
||||
if (copy_from_kernel_nofault(buffer, (void *)addr - 12, MAX_INSN_SIZE))
|
||||
return false;
|
||||
if (insn_decode_kernel(&insn, &buffer[offset]))
|
||||
return false;
|
||||
|
|
@ -44,7 +44,7 @@ static bool decode_cfi_insn(struct pt_regs *regs, unsigned long *target,
|
|||
|
||||
*type = -(u32)insn.immediate.value;
|
||||
|
||||
if (copy_from_kernel_nofault(buffer, (void *)regs->ip - 6, MAX_INSN_SIZE))
|
||||
if (copy_from_kernel_nofault(buffer, (void *)addr - 6, MAX_INSN_SIZE))
|
||||
return false;
|
||||
if (insn_decode_kernel(&insn, &buffer[offset]))
|
||||
return false;
|
||||
|
|
@ -82,7 +82,7 @@ enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
|
|||
return BUG_TRAP_TYPE_NONE;
|
||||
}
|
||||
|
||||
if (!decode_cfi_insn(regs, &target, &type))
|
||||
if (!decode_cfi_insn(regs, addr, &target, &type))
|
||||
return report_cfi_failure_noaddr(regs, addr);
|
||||
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -265,11 +265,39 @@ noinstr u32 kvm_read_and_reset_apf_flags(void)
|
|||
}
|
||||
EXPORT_SYMBOL_FOR_KVM(kvm_read_and_reset_apf_flags);
|
||||
|
||||
static __always_inline bool kvm_apf_reason_pending(void)
|
||||
{
|
||||
return __this_cpu_read(async_pf_enabled) &&
|
||||
__this_cpu_read(apf_reason.flags);
|
||||
}
|
||||
|
||||
noinstr bool __kvm_handle_async_pf(struct pt_regs *regs, u32 token)
|
||||
{
|
||||
u32 flags = kvm_read_and_reset_apf_flags();
|
||||
irqentry_state_t state;
|
||||
u32 flags;
|
||||
|
||||
if (!kvm_apf_reason_pending())
|
||||
return false;
|
||||
|
||||
/*
|
||||
* The guest does not enable KVM_ASYNC_PF_SEND_ALWAYS, so the host
|
||||
* delivers async #PF only to user mode (or as a #PF VM-exit, which KVM
|
||||
* reads itself). A #PF from kernel mode can still arrive between that
|
||||
* delivery and the read of the reason flags, inside an NMI that
|
||||
* interrupted it, for instance perf reading user memory for a call
|
||||
* chain. Such a fault is not async, so leave the async PF flags
|
||||
* untouched for the outer handler. Outside NMI context, on the other
|
||||
* hand, async PF flags on a kernel-mode fault mean the host is broken.
|
||||
*/
|
||||
if (!user_mode(regs)) {
|
||||
if (likely(in_nmi()))
|
||||
return false;
|
||||
state = irqentry_enter(regs);
|
||||
instrumentation_begin();
|
||||
panic("Host injected async #PF in kernel mode\n");
|
||||
}
|
||||
|
||||
flags = kvm_read_and_reset_apf_flags();
|
||||
if (!flags)
|
||||
return false;
|
||||
|
||||
|
|
@ -285,8 +313,6 @@ noinstr bool __kvm_handle_async_pf(struct pt_regs *regs, u32 token)
|
|||
panic("Host injected async #PF in interrupt disabled region\n");
|
||||
|
||||
if (flags & KVM_PV_REASON_PAGE_NOT_PRESENT) {
|
||||
if (unlikely(!(user_mode(regs))))
|
||||
panic("Host injected async #PF in kernel mode\n");
|
||||
/* Page is swapped out by the host. */
|
||||
kvm_async_pf_task_wait_schedule(token);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -275,8 +275,18 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_pagewalk *w,
|
|||
unsigned pte_access, unsigned pte_pkey,
|
||||
u64 access)
|
||||
{
|
||||
/* strip nested paging fault error codes */
|
||||
unsigned int pfec = access;
|
||||
/*
|
||||
* Of the error codes that do not contribute to the index in
|
||||
* fmt->permissions, PK and SS are not supported by shadow paging
|
||||
* and also not provided to EPT violations, but SS *is* included
|
||||
* in the NPT exit code. RSVD faults are handled elsewhere.
|
||||
*/
|
||||
unsigned int pfec = access & ~PFERR_SS_MASK;
|
||||
if (WARN_ON_ONCE(pfec & ~(PFERR_PRESENT_MASK | PFERR_WRITE_MASK |
|
||||
PFERR_USER_MASK | PFERR_FETCH_MASK)))
|
||||
pfec &= (PFERR_PRESENT_MASK | PFERR_WRITE_MASK |
|
||||
PFERR_USER_MASK | PFERR_FETCH_MASK);
|
||||
|
||||
unsigned long rflags = kvm_x86_call(get_rflags)(vcpu);
|
||||
|
||||
/*
|
||||
|
|
@ -301,8 +311,6 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_pagewalk *w,
|
|||
kvm_mmu_refresh_passthrough_bits(vcpu, w);
|
||||
|
||||
fault = (fmt->permissions[index] >> pte_access) & 1;
|
||||
|
||||
WARN_ON_ONCE(pfec & (PFERR_PK_MASK | PFERR_SS_MASK | PFERR_RSVD_MASK));
|
||||
if (unlikely(fmt->pkru_mask)) {
|
||||
u32 pkru_bits, offset;
|
||||
|
||||
|
|
|
|||
|
|
@ -328,7 +328,6 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
|
|||
int offset;
|
||||
u64 walk_nx_mask = 0;
|
||||
const int write_fault = access & PFERR_WRITE_MASK;
|
||||
const int user_fault = access & PFERR_USER_MASK;
|
||||
const int fetch_fault = access & PFERR_FETCH_MASK;
|
||||
/*
|
||||
* Note! Track the error_code that's common to legacy shadow paging
|
||||
|
|
@ -486,7 +485,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
|
|||
return 1;
|
||||
|
||||
error:
|
||||
errcode |= write_fault | user_fault;
|
||||
errcode |= access & (PFERR_WRITE_MASK | PFERR_USER_MASK | PFERR_SS_MASK);
|
||||
if (fetch_fault && has_pferr_fetch(w))
|
||||
errcode |= PFERR_FETCH_MASK;
|
||||
|
||||
|
|
|
|||
|
|
@ -395,6 +395,11 @@ static phys_addr_t avic_get_backing_page_address(struct vcpu_svm *svm)
|
|||
return __sme_set(__pa(svm->vcpu.arch.apic->regs));
|
||||
}
|
||||
|
||||
static bool avic_is_addressable_vcpu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return vcpu->vcpu_id <= __avic_get_max_physical_id(vcpu->kvm, NULL);
|
||||
}
|
||||
|
||||
void avic_init_vmcb(struct vcpu_svm *svm, struct vmcb *vmcb)
|
||||
{
|
||||
struct kvm_svm *kvm_svm = to_kvm_svm(svm->vcpu.kvm);
|
||||
|
|
@ -412,7 +417,6 @@ void avic_init_vmcb(struct vcpu_svm *svm, struct vmcb *vmcb)
|
|||
|
||||
static int avic_init_backing_page(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u32 max_id = x2avic_enabled ? x2avic_max_physical_id : AVIC_MAX_PHYSICAL_ID;
|
||||
struct kvm_svm *kvm_svm = to_kvm_svm(vcpu->kvm);
|
||||
struct vcpu_svm *svm = to_svm(vcpu);
|
||||
u32 id = vcpu->vcpu_id;
|
||||
|
|
@ -425,7 +429,7 @@ static int avic_init_backing_page(struct kvm_vcpu *vcpu)
|
|||
* avic_vcpu_load() expects to be called if and only if the vCPU has
|
||||
* fully initialized AVIC.
|
||||
*/
|
||||
if (id > max_id) {
|
||||
if (!avic_is_addressable_vcpu(vcpu)) {
|
||||
kvm_set_apicv_inhibit(vcpu->kvm, APICV_INHIBIT_REASON_PHYSICAL_ID_TOO_BIG);
|
||||
vcpu->arch.apic->apicv_active = false;
|
||||
return 0;
|
||||
|
|
@ -885,6 +889,14 @@ int avic_init_vcpu(struct vcpu_svm *svm)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void avic_vcpu_free(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_svm *kvm_svm = to_kvm_svm(vcpu->kvm);
|
||||
|
||||
if (kvm_svm->avic_physical_id_table && avic_is_addressable_vcpu(vcpu))
|
||||
WRITE_ONCE(kvm_svm->avic_physical_id_table[vcpu->vcpu_id], 0);
|
||||
}
|
||||
|
||||
void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
avic_handle_dfr_update(vcpu);
|
||||
|
|
@ -1045,8 +1057,7 @@ static void __avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu,
|
|||
if (WARN_ON(h_physical_id & ~AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK))
|
||||
return;
|
||||
|
||||
if (WARN_ON_ONCE(vcpu->vcpu_id * sizeof(entry) >=
|
||||
PAGE_SIZE << avic_get_physical_id_table_order(vcpu->kvm)))
|
||||
if (WARN_ON_ONCE(!avic_is_addressable_vcpu(vcpu)))
|
||||
return;
|
||||
|
||||
/*
|
||||
|
|
@ -1108,8 +1119,7 @@ static void __avic_vcpu_put(struct kvm_vcpu *vcpu, enum avic_vcpu_action action)
|
|||
|
||||
lockdep_assert_preemption_disabled();
|
||||
|
||||
if (WARN_ON_ONCE(vcpu->vcpu_id * sizeof(entry) >=
|
||||
PAGE_SIZE << avic_get_physical_id_table_order(vcpu->kvm)))
|
||||
if (WARN_ON_ONCE(!avic_is_addressable_vcpu(vcpu)))
|
||||
return;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -2421,7 +2421,7 @@ static int sev_gmem_post_populate(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn,
|
|||
void *dst_vaddr = kmap_local_pfn(pfn);
|
||||
|
||||
memcpy(src_vaddr, dst_vaddr, PAGE_SIZE);
|
||||
set_page_dirty(src_page);
|
||||
set_page_dirty_lock(src_page);
|
||||
|
||||
kunmap_local(dst_vaddr);
|
||||
kunmap_local(src_vaddr);
|
||||
|
|
|
|||
|
|
@ -1328,7 +1328,7 @@ static int svm_vcpu_create(struct kvm_vcpu *vcpu)
|
|||
svm->msrpm = svm_vcpu_alloc_msrpm();
|
||||
if (!svm->msrpm) {
|
||||
err = -ENOMEM;
|
||||
goto error_free_sev;
|
||||
goto error_free_avic;
|
||||
}
|
||||
|
||||
svm->x2avic_msrs_intercepted = true;
|
||||
|
|
@ -1342,6 +1342,8 @@ static int svm_vcpu_create(struct kvm_vcpu *vcpu)
|
|||
|
||||
return 0;
|
||||
|
||||
error_free_avic:
|
||||
avic_vcpu_free(vcpu);
|
||||
error_free_sev:
|
||||
sev_free_vcpu(vcpu);
|
||||
error_free_vmcb_page:
|
||||
|
|
@ -1356,6 +1358,8 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu)
|
|||
|
||||
WARN_ON_ONCE(!list_empty(&svm->ir_list));
|
||||
|
||||
avic_vcpu_free(vcpu);
|
||||
|
||||
svm_leave_nested(vcpu);
|
||||
svm_free_nested(svm);
|
||||
|
||||
|
|
|
|||
|
|
@ -955,6 +955,7 @@ void avic_init_vmcb(struct vcpu_svm *svm, struct vmcb *vmcb);
|
|||
int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu);
|
||||
int avic_unaccelerated_access_interception(struct kvm_vcpu *vcpu);
|
||||
int avic_init_vcpu(struct vcpu_svm *svm);
|
||||
void avic_vcpu_free(struct kvm_vcpu *vcpu);
|
||||
void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
|
||||
void avic_vcpu_put(struct kvm_vcpu *vcpu);
|
||||
void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu);
|
||||
|
|
|
|||
|
|
@ -3770,8 +3770,10 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu,
|
|||
vmentry_fail_vmexit:
|
||||
vmx_switch_vmcs(vcpu, &vmx->vmcs01);
|
||||
|
||||
if (!from_vmentry)
|
||||
if (!from_vmentry) {
|
||||
nested_ept_uninit_mmu_context(vcpu);
|
||||
return NVMX_VMENTRY_VMEXIT;
|
||||
}
|
||||
|
||||
nested_put_vmcs12_pages(vcpu);
|
||||
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ static inline bool is_noncanonical_invlpg_address(u64 la, struct kvm_vcpu *vcpu)
|
|||
static inline void vcpu_cache_mmio_info(struct kvm_vcpu *vcpu,
|
||||
gva_t gva, gfn_t gfn, unsigned access)
|
||||
{
|
||||
u64 gen = kvm_memslots(vcpu->kvm)->generation;
|
||||
u64 gen = kvm_vcpu_memslots(vcpu)->generation;
|
||||
|
||||
if (unlikely(gen & KVM_MEMSLOT_GEN_UPDATE_IN_PROGRESS))
|
||||
return;
|
||||
|
|
@ -267,7 +267,7 @@ static inline void vcpu_cache_mmio_info(struct kvm_vcpu *vcpu,
|
|||
|
||||
static inline bool vcpu_match_mmio_gen(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return vcpu->arch.mmio_gen == kvm_memslots(vcpu->kvm)->generation;
|
||||
return vcpu->arch.mmio_gen == kvm_vcpu_memslots(vcpu)->generation;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -23,11 +23,14 @@ struct bsg_set {
|
|||
struct bsg_device *bd;
|
||||
bsg_job_fn *job_fn;
|
||||
bsg_timeout_fn *timeout_fn;
|
||||
unsigned int reply_len;
|
||||
};
|
||||
|
||||
static int bsg_transport_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
|
||||
bool open_for_write, unsigned int timeout)
|
||||
{
|
||||
struct bsg_set *bset =
|
||||
container_of(q->tag_set, struct bsg_set, tag_set);
|
||||
struct bsg_job *job;
|
||||
struct request *rq;
|
||||
struct bio *bio;
|
||||
|
|
@ -50,7 +53,7 @@ static int bsg_transport_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
|
|||
reply = job->reply;
|
||||
memset(job, 0, sizeof(*job));
|
||||
job->reply = reply;
|
||||
job->reply_len = SCSI_SENSE_BUFFERSIZE;
|
||||
job->reply_len = bset->reply_len;
|
||||
job->dd_data = job + 1;
|
||||
|
||||
job->request_len = hdr->request_len;
|
||||
|
|
@ -301,9 +304,10 @@ static blk_status_t bsg_queue_rq(struct blk_mq_hw_ctx *hctx,
|
|||
static int bsg_init_rq(struct blk_mq_tag_set *set, struct request *req,
|
||||
unsigned int hctx_idx, int numa_node)
|
||||
{
|
||||
struct bsg_set *bset = container_of(set, struct bsg_set, tag_set);
|
||||
struct bsg_job *job = blk_mq_rq_to_pdu(req);
|
||||
|
||||
job->reply = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
|
||||
job->reply = kzalloc(bset->reply_len, GFP_KERNEL);
|
||||
if (!job->reply)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
|
|
@ -358,10 +362,12 @@ static const struct blk_mq_ops bsg_mq_ops = {
|
|||
* @job_fn: bsg job handler
|
||||
* @timeout: timeout handler function pointer
|
||||
* @dd_job_size: size of LLD data needed for each job
|
||||
* @reply_len: size of the reply buffer needed for each job
|
||||
*/
|
||||
struct request_queue *bsg_setup_queue(struct device *dev, const char *name,
|
||||
struct queue_limits *lim, bsg_job_fn *job_fn,
|
||||
bsg_timeout_fn *timeout, int dd_job_size)
|
||||
bsg_timeout_fn *timeout, int dd_job_size,
|
||||
unsigned int reply_len)
|
||||
{
|
||||
struct bsg_set *bset;
|
||||
struct blk_mq_tag_set *set;
|
||||
|
|
@ -374,6 +380,7 @@ struct request_queue *bsg_setup_queue(struct device *dev, const char *name,
|
|||
|
||||
bset->job_fn = job_fn;
|
||||
bset->timeout_fn = timeout;
|
||||
bset->reply_len = reply_len;
|
||||
|
||||
set = &bset->tag_set;
|
||||
set->ops = &bsg_mq_ops;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ config DRM_ACCEL_AMDXDNA
|
|||
depends on DRM_ACCEL
|
||||
depends on PCI && HAS_IOMEM
|
||||
depends on X86_64
|
||||
depends on AMD_PMF || !AMD_PMF
|
||||
select DRM_SCHED
|
||||
select DRM_GEM_SHMEM_HELPER
|
||||
select FW_LOADER
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ struct rocket_device *rocket_device_init(struct platform_device *pdev,
|
|||
if (of_device_is_available(core_node))
|
||||
num_cores++;
|
||||
|
||||
rdev->max_cores = num_cores;
|
||||
|
||||
rdev->cores = devm_kcalloc(dev, num_cores, sizeof(*rdev->cores), GFP_KERNEL);
|
||||
if (!rdev->cores)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ struct rocket_device {
|
|||
|
||||
struct rocket_core *cores;
|
||||
unsigned int num_cores;
|
||||
unsigned int max_cores;
|
||||
};
|
||||
|
||||
struct rocket_device *rocket_device_init(struct platform_device *pdev,
|
||||
|
|
|
|||
|
|
@ -165,8 +165,11 @@ static int rocket_probe(struct platform_device *pdev)
|
|||
/* First core probing, initialize DRM device. */
|
||||
rdev = rocket_device_init(drm_dev, &rocket_drm_driver);
|
||||
if (IS_ERR(rdev)) {
|
||||
int err = PTR_ERR(rdev);
|
||||
|
||||
dev_err(&pdev->dev, "failed to initialize rocket device\n");
|
||||
return PTR_ERR(rdev);
|
||||
rdev = NULL;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -223,7 +226,7 @@ static int find_core_for_dev(struct device *dev)
|
|||
{
|
||||
struct rocket_device *rdev = dev_get_drvdata(dev);
|
||||
|
||||
for (unsigned int core = 0; core < rdev->num_cores; core++) {
|
||||
for (unsigned int core = 0; core < rdev->max_cores; core++) {
|
||||
if (dev == rdev->cores[core].dev)
|
||||
return core;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ static struct rocket_core *sched_to_core(struct rocket_device *rdev,
|
|||
{
|
||||
unsigned int core;
|
||||
|
||||
for (core = 0; core < rdev->num_cores; core++) {
|
||||
for (core = 0; core < rdev->max_cores; core++) {
|
||||
if (&rdev->cores[core].sched == sched)
|
||||
return &rdev->cores[core];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -312,16 +312,21 @@ static void regcache_maple_exit(struct regmap *map)
|
|||
struct maple_tree *mt = map->cache;
|
||||
MA_STATE(mas, mt, 0, UINT_MAX);
|
||||
unsigned int *entry;
|
||||
unsigned long flags;
|
||||
|
||||
/* if we've already been called then just return */
|
||||
if (!mt)
|
||||
return;
|
||||
|
||||
mas_lock(&mas);
|
||||
/*
|
||||
* Register access may take the Maple lock from hard IRQ context, so
|
||||
* preserve its IRQ-safe lockdep state during teardown.
|
||||
*/
|
||||
mas_lock_irqsave(&mas, flags);
|
||||
mas_for_each(&mas, entry, UINT_MAX)
|
||||
kfree(entry);
|
||||
__mt_destroy(mt);
|
||||
mas_unlock(&mas);
|
||||
mas_unlock_irqrestore(&mas, flags);
|
||||
|
||||
kfree(mt);
|
||||
map->cache = NULL;
|
||||
|
|
|
|||
|
|
@ -225,9 +225,7 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
|
|||
if (map->cache_ops->init) {
|
||||
dev_dbg(map->dev, "Initializing %s cache\n",
|
||||
map->cache_ops->name);
|
||||
map->lock(map->lock_arg);
|
||||
ret = map->cache_ops->init(map);
|
||||
map->unlock(map->lock_arg);
|
||||
if (ret)
|
||||
goto err_free_reg_defaults;
|
||||
}
|
||||
|
|
@ -259,9 +257,7 @@ int regcache_init(struct regmap *map, const struct regmap_config *config)
|
|||
err_exit:
|
||||
if (map->cache_ops->exit) {
|
||||
dev_dbg(map->dev, "Destroying %s cache\n", map->cache_ops->name);
|
||||
map->lock(map->lock_arg);
|
||||
map->cache_ops->exit(map);
|
||||
map->unlock(map->lock_arg);
|
||||
}
|
||||
err_free_reg_defaults:
|
||||
kfree(map->reg_defaults);
|
||||
|
|
@ -281,9 +277,7 @@ void regcache_exit(struct regmap *map)
|
|||
if (map->cache_ops->exit) {
|
||||
dev_dbg(map->dev, "Destroying %s cache\n",
|
||||
map->cache_ops->name);
|
||||
map->lock(map->lock_arg);
|
||||
map->cache_ops->exit(map);
|
||||
map->unlock(map->lock_arg);
|
||||
}
|
||||
|
||||
kfree(map->reg_defaults);
|
||||
|
|
|
|||
|
|
@ -664,6 +664,7 @@ void regmap_debugfs_exit(struct regmap *map)
|
|||
{
|
||||
if (map->debugfs) {
|
||||
debugfs_remove_recursive(map->debugfs);
|
||||
map->debugfs = NULL;
|
||||
mutex_lock(&map->cache_lock);
|
||||
regmap_debugfs_free_dump_cache(map);
|
||||
mutex_unlock(&map->cache_lock);
|
||||
|
|
|
|||
|
|
@ -963,7 +963,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
|
|||
return 0;
|
||||
|
||||
err_domain:
|
||||
/* Should really dispose of the domain but... */
|
||||
irq_domain_remove(d->domain);
|
||||
err_mutex:
|
||||
mutex_destroy(&d->lock);
|
||||
lockdep_unregister_key(&d->lock_key);
|
||||
|
|
|
|||
|
|
@ -1422,8 +1422,8 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
|
|||
{
|
||||
int ret;
|
||||
|
||||
regcache_exit(map);
|
||||
regmap_debugfs_exit(map);
|
||||
regcache_exit(map);
|
||||
|
||||
map->max_register = config->max_register;
|
||||
map->max_register_is_set = map->max_register ?: config->max_register_is_0;
|
||||
|
|
@ -1440,12 +1440,16 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap_debugfs_init(map);
|
||||
|
||||
map->cache_bypass = false;
|
||||
map->cache_only = false;
|
||||
|
||||
return regcache_init(map, config);
|
||||
ret = regcache_init(map, config);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap_debugfs_init(map);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regmap_reinit_cache);
|
||||
|
||||
|
|
@ -1459,9 +1463,8 @@ void regmap_exit(struct regmap *map)
|
|||
struct regmap_async *async;
|
||||
|
||||
regmap_detach_dev(map->dev, map);
|
||||
regcache_exit(map);
|
||||
|
||||
regmap_debugfs_exit(map);
|
||||
regcache_exit(map);
|
||||
regmap_range_exit(map);
|
||||
if (map->bus && map->bus->free_context)
|
||||
map->bus->free_context(map->bus_context);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ config UDMABUF
|
|||
config DMABUF_DEBUG
|
||||
bool "DMA-BUF debug checks"
|
||||
depends on DMA_SHARED_BUFFER
|
||||
default y if DEBUG_KERNEL
|
||||
default y if DEBUG
|
||||
help
|
||||
This option enables additional checks for DMA-BUF importers and
|
||||
exporters. Specifically it validates that importers do not peek at the
|
||||
|
|
|
|||
|
|
@ -89,8 +89,12 @@ void fw_cancel_pending_transactions(struct fw_card *card)
|
|||
break; \
|
||||
} \
|
||||
} \
|
||||
if (t && try_cancel_split_timeout(t)) \
|
||||
remove_transaction_entry(card, t); \
|
||||
if (t) { \
|
||||
if (try_cancel_split_timeout(t)) \
|
||||
remove_transaction_entry(card, t); \
|
||||
else \
|
||||
t = NULL; \
|
||||
} \
|
||||
t; \
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -1431,6 +1431,7 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser)
|
|||
int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
struct amdgpu_bo_list_entry *e;
|
||||
struct amdgpu_cs_parser parser;
|
||||
int r;
|
||||
|
||||
|
|
@ -1465,25 +1466,31 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|||
|
||||
r = amdgpu_cs_patch_jobs(&parser);
|
||||
if (r)
|
||||
goto error_fini;
|
||||
goto error_free_user_pages;
|
||||
|
||||
r = amdgpu_cs_vm_handling(&parser);
|
||||
if (r)
|
||||
goto error_fini;
|
||||
goto error_free_user_pages;
|
||||
|
||||
r = amdgpu_cs_sync_rings(&parser);
|
||||
if (r)
|
||||
goto error_fini;
|
||||
goto error_free_user_pages;
|
||||
|
||||
trace_amdgpu_cs_ibs(&parser);
|
||||
|
||||
r = amdgpu_cs_submit(&parser, data);
|
||||
if (r)
|
||||
goto error_fini;
|
||||
goto error_free_user_pages;
|
||||
|
||||
amdgpu_cs_parser_fini(&parser);
|
||||
return 0;
|
||||
|
||||
error_free_user_pages:
|
||||
/* amdgpu_cs_submit() only drops the ranges once it got that far. */
|
||||
amdgpu_bo_list_for_each_userptr_entry(e, parser.bo_list) {
|
||||
amdgpu_hmm_range_free(e->range);
|
||||
e->range = NULL;
|
||||
}
|
||||
error_fini:
|
||||
amdgpu_cs_parser_fini(&parser);
|
||||
return r;
|
||||
|
|
|
|||
|
|
@ -1266,7 +1266,6 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
|
|||
{
|
||||
struct amdgpu_device *adev = f->f_inode->i_private;
|
||||
int r;
|
||||
ssize_t result = 0;
|
||||
uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data;
|
||||
|
||||
if (size > 4096 || size & 3 || *pos & 3)
|
||||
|
|
@ -1310,25 +1309,11 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf,
|
|||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
|
||||
while (size) {
|
||||
uint32_t value;
|
||||
|
||||
value = data[result >> 2];
|
||||
r = put_user(value, (uint32_t *)buf);
|
||||
if (r) {
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
goto err;
|
||||
}
|
||||
|
||||
result += 4;
|
||||
buf += 4;
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
kfree(data);
|
||||
amdgpu_virt_disable_access_debugfs(adev);
|
||||
return result;
|
||||
|
||||
r = copy_to_user(buf, data, size) ? -EFAULT : size;
|
||||
kfree(data);
|
||||
return r;
|
||||
|
||||
err:
|
||||
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
|
||||
|
|
|
|||
|
|
@ -337,11 +337,14 @@ static void amdgpu_gem_object_close(struct drm_gem_object *obj,
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
bo_va = amdgpu_vm_bo_find(vm, bo);
|
||||
/* the fence is attached once per bo_va, so keep it for other handles */
|
||||
if (bo_va && --bo_va->ref_count)
|
||||
goto out_unlock;
|
||||
|
||||
if (!amdgpu_vm_is_bo_always_valid(vm, bo))
|
||||
amdgpu_evf_mgr_detach_fence(&fpriv->evf_mgr, bo);
|
||||
|
||||
bo_va = amdgpu_vm_bo_find(vm, bo);
|
||||
if (!bo_va || --bo_va->ref_count)
|
||||
if (!bo_va)
|
||||
goto out_unlock;
|
||||
|
||||
amdgpu_vm_bo_del(adev, bo_va);
|
||||
|
|
@ -567,8 +570,10 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
|
|||
|
||||
if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
|
||||
range = amdgpu_hmm_range_alloc(NULL);
|
||||
if (unlikely(!range))
|
||||
return -ENOMEM;
|
||||
if (unlikely(!range)) {
|
||||
r = -ENOMEM;
|
||||
goto release_object;
|
||||
}
|
||||
r = amdgpu_ttm_tt_get_user_pages(bo, range);
|
||||
if (r) {
|
||||
amdgpu_hmm_range_free(range);
|
||||
|
|
@ -1236,7 +1241,7 @@ int amdgpu_gem_list_handles_ioctl(struct drm_device *dev, void *data,
|
|||
bo_entry->alloc_flags = bo->flags & AMDGPU_GEM_CREATE_SETTABLE_MASK;
|
||||
bo_entry->preferred_domains = bo->preferred_domains;
|
||||
bo_entry->gem_handle = id;
|
||||
bo_entry->alignment = bo->tbo.page_alignment;
|
||||
bo_entry->alignment = (u64)bo->tbo.page_alignment << PAGE_SHIFT;
|
||||
|
||||
if (bo->tbo.base.import_attach)
|
||||
bo_entry->flags |= AMDGPU_GEM_LIST_HANDLES_FLAG_IS_IMPORT;
|
||||
|
|
|
|||
|
|
@ -2065,14 +2065,15 @@ static int amdgpu_ttm_buffer_entity_init(struct amdgpu_gtt_mgr *mgr,
|
|||
int i, r, num_pages;
|
||||
const u64 GTT_MAX_PAGES = (AMDGPU_GTT_MAX_TRANSFER_SIZE >> PAGE_SHIFT);
|
||||
|
||||
if (ARRAY_SIZE(entity->gart_window_offs) < num_gart_windows)
|
||||
return -EINVAL;
|
||||
|
||||
r = drm_sched_entity_init(&entity->base, prio, scheds, num_schedulers, NULL);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
mutex_init(&entity->lock);
|
||||
|
||||
if (ARRAY_SIZE(entity->gart_window_offs) < num_gart_windows)
|
||||
return -EINVAL;
|
||||
if (num_gart_windows == 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -2080,6 +2081,7 @@ static int amdgpu_ttm_buffer_entity_init(struct amdgpu_gtt_mgr *mgr,
|
|||
r = amdgpu_gtt_mgr_alloc_entries(mgr, &entity->gart_node, num_pages,
|
||||
DRM_MM_INSERT_BEST);
|
||||
if (r) {
|
||||
mutex_destroy(&entity->lock);
|
||||
drm_sched_entity_destroy(&entity->base);
|
||||
return r;
|
||||
}
|
||||
|
|
@ -2097,6 +2099,7 @@ static void amdgpu_ttm_buffer_entity_fini(struct amdgpu_gtt_mgr *mgr,
|
|||
struct amdgpu_ttm_buffer_entity *entity)
|
||||
{
|
||||
amdgpu_gtt_mgr_free_entries(mgr, &entity->gart_node);
|
||||
mutex_destroy(&entity->lock);
|
||||
drm_sched_entity_destroy(&entity->base);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -980,19 +980,21 @@ amdgpu_userq_bo_validate(struct amdgpu_device *adev, struct drm_exec *exec,
|
|||
{
|
||||
struct ttm_operation_ctx ctx = { false, false };
|
||||
struct amdgpu_bo_va *bo_va;
|
||||
struct amdgpu_bo *bo;
|
||||
struct amdgpu_bo *bo, *tmp;
|
||||
int ret;
|
||||
|
||||
spin_lock(&vm->individual_lock);
|
||||
while (!list_empty(&vm->always_valid.evicted)) {
|
||||
bo_va = list_first_entry(&vm->always_valid.evicted,
|
||||
while (!list_empty(&vm->individual.evicted)) {
|
||||
bo_va = list_first_entry(&vm->individual.evicted,
|
||||
struct amdgpu_bo_va,
|
||||
base.vm_status);
|
||||
bo = bo_va->base.bo;
|
||||
tmp = amdgpu_bo_ref(bo);
|
||||
spin_unlock(&vm->individual_lock);
|
||||
|
||||
bo = bo_va->base.bo;
|
||||
ret = drm_exec_prepare_obj(exec, &bo->tbo.base,
|
||||
TTM_NUM_MOVE_FENCES + 1);
|
||||
amdgpu_bo_unref(&tmp);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -457,6 +457,9 @@ static void sdma_v3_0_ring_emit_hdp_flush(struct amdgpu_ring *ring)
|
|||
else
|
||||
ref_and_mask = REG_SET_FIELD(ref_and_mask, GPU_HDP_FLUSH_DONE, SDMA1, 1);
|
||||
|
||||
/* Hang workaround */
|
||||
amdgpu_ring_write(ring, SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP));
|
||||
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) |
|
||||
SDMA_PKT_POLL_REGMEM_HEADER_HDP_FLUSH(1) |
|
||||
SDMA_PKT_POLL_REGMEM_HEADER_FUNC(3)); /* == */
|
||||
|
|
@ -484,6 +487,10 @@ static void sdma_v3_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
|
|||
unsigned flags)
|
||||
{
|
||||
bool write64bit = flags & AMDGPU_FENCE_FLAG_64BIT;
|
||||
|
||||
/* Hang workaround */
|
||||
amdgpu_ring_write(ring, SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP));
|
||||
|
||||
/* write the fence */
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_FENCE));
|
||||
amdgpu_ring_write(ring, lower_32_bits(addr));
|
||||
|
|
@ -492,7 +499,11 @@ static void sdma_v3_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
|
|||
|
||||
/* optionally write high bits as well */
|
||||
if (write64bit) {
|
||||
/* Hang workaround */
|
||||
amdgpu_ring_write(ring, SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP));
|
||||
|
||||
addr += 4;
|
||||
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_FENCE));
|
||||
amdgpu_ring_write(ring, lower_32_bits(addr));
|
||||
amdgpu_ring_write(ring, upper_32_bits(addr));
|
||||
|
|
@ -1033,6 +1044,9 @@ static void sdma_v3_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
|
|||
uint32_t seq = ring->fence_drv.sync_seq;
|
||||
uint64_t addr = ring->fence_drv.gpu_addr;
|
||||
|
||||
/* Hang workaround */
|
||||
amdgpu_ring_write(ring, SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP));
|
||||
|
||||
/* wait for idle */
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) |
|
||||
SDMA_PKT_POLL_REGMEM_HEADER_HDP_FLUSH(0) |
|
||||
|
|
@ -1061,6 +1075,9 @@ static void sdma_v3_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
{
|
||||
amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
|
||||
|
||||
/* Hang workaround */
|
||||
amdgpu_ring_write(ring, SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP));
|
||||
|
||||
/* wait for flush */
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) |
|
||||
SDMA_PKT_POLL_REGMEM_HEADER_HDP_FLUSH(0) |
|
||||
|
|
@ -1510,11 +1527,11 @@ static const struct amdgpu_ring_funcs sdma_v3_0_ring_funcs = {
|
|||
.get_wptr = sdma_v3_0_ring_get_wptr,
|
||||
.set_wptr = sdma_v3_0_ring_set_wptr,
|
||||
.emit_frame_size =
|
||||
6 + /* sdma_v3_0_ring_emit_hdp_flush */
|
||||
6 + 1 + /* sdma_v3_0_ring_emit_hdp_flush */
|
||||
3 + /* hdp invalidate */
|
||||
6 + /* sdma_v3_0_ring_emit_pipeline_sync */
|
||||
VI_FLUSH_GPU_TLB_NUM_WREG * 3 + 6 + /* sdma_v3_0_ring_emit_vm_flush */
|
||||
10 + 10 + 10, /* sdma_v3_0_ring_emit_fence x3 for user fence, vm fence */
|
||||
6 + 1 + /* sdma_v3_0_ring_emit_pipeline_sync */
|
||||
VI_FLUSH_GPU_TLB_NUM_WREG * 3 + 6 + 1 + /* sdma_v3_0_ring_emit_vm_flush */
|
||||
(10 + 1) * 3, /* sdma_v3_0_ring_emit_fence x3 for user fence, vm fence */
|
||||
.emit_ib_size = 7 + 6, /* sdma_v3_0_ring_emit_ib */
|
||||
.emit_ib = sdma_v3_0_ring_emit_ib,
|
||||
.emit_fence = sdma_v3_0_ring_emit_fence,
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ static int uvd_v3_1_fw_validate(struct amdgpu_device *adev)
|
|||
int i;
|
||||
uint32_t keysel = adev->uvd.keyselect;
|
||||
|
||||
if (RREG32(mmUVD_FW_START) & UVD_FW_STATUS__PASS_MASK) {
|
||||
if (RREG32(mmUVD_FW_START)) {
|
||||
dev_dbg(adev->dev, "UVD keyselect already set: 0x%x (on CPU: 0x%x)\n",
|
||||
RREG32(mmUVD_FW_START), adev->uvd.keyselect);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -2306,9 +2306,14 @@ static bool allocate_usb4_bandwidth_for_stream(struct dc_stream_state *stream, i
|
|||
{
|
||||
ASSERT(stream->sink);
|
||||
|
||||
struct dc_link *link = stream->sink->link;
|
||||
struct dc_link *link;
|
||||
int req_bw = stream_bw;
|
||||
|
||||
if (!stream->sink)
|
||||
return false;
|
||||
|
||||
link = stream->sink->link;
|
||||
|
||||
DC_LOGGER_INIT(link->ctx->logger);
|
||||
|
||||
if (!link->dpia_bw_alloc_config.bw_alloc_enabled)
|
||||
|
|
@ -2355,9 +2360,13 @@ static bool allocate_usb4_bandwidth(struct dc_stream_state *stream)
|
|||
ASSERT(stream->sink);
|
||||
|
||||
bool ret;
|
||||
int bw;
|
||||
|
||||
int bw = dc_bandwidth_in_kbps_from_timing(&stream->timing,
|
||||
dc_link_get_highest_encoding_format(stream->sink->link));
|
||||
if (!stream->sink)
|
||||
return false;
|
||||
|
||||
bw = dc_bandwidth_in_kbps_from_timing(&stream->timing,
|
||||
dc_link_get_highest_encoding_format(stream->sink->link));
|
||||
|
||||
ret = allocate_usb4_bandwidth_for_stream(stream, bw);
|
||||
|
||||
|
|
@ -2419,7 +2428,8 @@ enum dc_status link_set_dpms_off(struct pipe_ctx *pipe_ctx)
|
|||
update_psp_stream_config(pipe_ctx, true);
|
||||
dc->hwss.blank_stream(pipe_ctx);
|
||||
|
||||
if (pipe_ctx->link_config.dp_tunnel_settings.should_use_dp_bw_allocation)
|
||||
if (pipe_ctx->link_config.dp_tunnel_settings.should_use_dp_bw_allocation &&
|
||||
stream->sink)
|
||||
deallocate_usb4_bandwidth(stream);
|
||||
|
||||
if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ static const struct smu_feature_bits smu_v14_0_2_dpm_features = {
|
|||
#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
|
||||
#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
|
||||
#define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
|
||||
#define PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP 12
|
||||
|
||||
static struct cmn2asic_msg_mapping smu_v14_0_2_message_map[SMU_MSG_MAX_COUNT] = {
|
||||
MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1),
|
||||
|
|
@ -1020,6 +1021,10 @@ static void smu_v14_0_2_get_od_setting_limits(struct smu_context *smu,
|
|||
od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
|
||||
od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
|
||||
break;
|
||||
case PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP:
|
||||
od_min_setting = pptable->SkuTable.MsgLimits.FanStopTempMin;
|
||||
od_max_setting = pptable->SkuTable.MsgLimits.FanStopTempMax;
|
||||
break;
|
||||
default:
|
||||
od_min_setting = od_max_setting = INT_MAX;
|
||||
break;
|
||||
|
|
@ -1244,6 +1249,24 @@ static int smu_v14_0_2_emit_clk_levels(struct smu_context *smu,
|
|||
min_value, max_value);
|
||||
break;
|
||||
|
||||
case SMU_OD_FAN_ZERO_RPM_STOP_TEMP:
|
||||
if (!smu_v14_0_2_is_od_feature_supported(smu,
|
||||
PP_OD_FEATURE_ZERO_FAN_BIT))
|
||||
break;
|
||||
|
||||
size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_STOP_TEMPERATURE:\n");
|
||||
size += sysfs_emit_at(buf, size, "%d\n",
|
||||
(int)od_table->OverDriveTable.FanZeroRpmStopTemp);
|
||||
|
||||
size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
|
||||
smu_v14_0_2_get_od_setting_limits(smu,
|
||||
PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
|
||||
&min_value,
|
||||
&max_value);
|
||||
size += sysfs_emit_at(buf, size, "ZERO_RPM_STOP_TEMPERATURE: %u %u\n",
|
||||
min_value, max_value);
|
||||
break;
|
||||
|
||||
case SMU_OD_RANGE:
|
||||
if (!smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
|
||||
!smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) &&
|
||||
|
|
@ -2311,7 +2334,9 @@ static void smu_v14_0_2_set_supported_od_feature_mask(struct smu_context *smu)
|
|||
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
|
||||
OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
|
||||
OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
|
||||
OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET;
|
||||
OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET |
|
||||
OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_RETRIEVE |
|
||||
OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_SET;
|
||||
}
|
||||
|
||||
static int smu_v14_0_2_get_overdrive_table(struct smu_context *smu,
|
||||
|
|
@ -2392,6 +2417,8 @@ static int smu_v14_0_2_set_default_od_settings(struct smu_context *smu)
|
|||
user_od_table_bak.OverDriveTable.FanMinimumPwm;
|
||||
user_od_table->OverDriveTable.FanZeroRpmEnable =
|
||||
user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
|
||||
user_od_table->OverDriveTable.FanZeroRpmStopTemp =
|
||||
user_od_table_bak.OverDriveTable.FanZeroRpmStopTemp;
|
||||
}
|
||||
|
||||
smu_v14_0_2_set_supported_od_feature_mask(smu);
|
||||
|
|
@ -2446,6 +2473,11 @@ static int smu_v14_0_2_od_restore_table_single(struct smu_context *smu, long inp
|
|||
boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
|
||||
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
|
||||
break;
|
||||
case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
|
||||
od_table->OverDriveTable.FanZeroRpmStopTemp =
|
||||
boot_overdrive_table->OverDriveTable.FanZeroRpmStopTemp;
|
||||
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
|
||||
break;
|
||||
case PP_OD_EDIT_ACOUSTIC_LIMIT:
|
||||
od_table->OverDriveTable.AcousticLimitRpmThreshold =
|
||||
boot_overdrive_table->OverDriveTable.AcousticLimitRpmThreshold;
|
||||
|
|
@ -2752,6 +2784,27 @@ static int smu_v14_0_2_od_edit_dpm_table(struct smu_context *smu,
|
|||
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
|
||||
break;
|
||||
|
||||
case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
|
||||
if (!smu_v14_0_2_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
|
||||
dev_warn(adev->dev, "Zero RPM setting not supported!\n");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
smu_v14_0_2_get_od_setting_limits(smu,
|
||||
PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
|
||||
&minimum,
|
||||
&maximum);
|
||||
if (input[0] < minimum ||
|
||||
input[0] > maximum) {
|
||||
dev_info(adev->dev, "zero RPM stop temperature setting(%ld) must be within [%d, %d]!\n",
|
||||
input[0], minimum, maximum);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
od_table->OverDriveTable.FanZeroRpmStopTemp = input[0];
|
||||
od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
|
||||
break;
|
||||
|
||||
case PP_OD_RESTORE_DEFAULT_TABLE:
|
||||
if (size == 1) {
|
||||
ret = smu_v14_0_2_od_restore_table_single(smu, input[0]);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,16 @@
|
|||
* See struct dma_exec for more details.
|
||||
*/
|
||||
|
||||
/* Unlock and put the prelocked obj */
|
||||
static void drm_exec_drop_prelocked(struct drm_exec *exec)
|
||||
{
|
||||
if (exec->prelocked) {
|
||||
dma_resv_unlock(exec->prelocked->resv);
|
||||
drm_gem_object_put(exec->prelocked);
|
||||
exec->prelocked = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unlock all objects and drop references */
|
||||
static void drm_exec_unlock_all(struct drm_exec *exec)
|
||||
{
|
||||
|
|
@ -58,8 +68,7 @@ static void drm_exec_unlock_all(struct drm_exec *exec)
|
|||
drm_gem_object_put(obj);
|
||||
}
|
||||
|
||||
drm_gem_object_put(exec->prelocked);
|
||||
exec->prelocked = NULL;
|
||||
drm_exec_drop_prelocked(exec);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -118,6 +127,14 @@ EXPORT_SYMBOL(drm_exec_fini);
|
|||
bool drm_exec_cleanup(struct drm_exec *exec)
|
||||
{
|
||||
if (likely(!exec->contended)) {
|
||||
|
||||
/*
|
||||
* The contended and prelocked object might never be passed to
|
||||
* drm_exec_lock_obj() again. This can happen when the object
|
||||
* is about to be cleaned up and we now hold the last reference
|
||||
* to it. Make sure that we don't unnecessarily keep it around.
|
||||
*/
|
||||
drm_exec_drop_prelocked(exec);
|
||||
ww_acquire_done(&exec->ticket);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -175,16 +192,16 @@ static int drm_exec_lock_contended(struct drm_exec *exec)
|
|||
dma_resv_lock_slow(obj->resv, &exec->ticket);
|
||||
}
|
||||
|
||||
ret = drm_exec_obj_locked(exec, obj);
|
||||
if (unlikely(ret))
|
||||
goto error_unlock;
|
||||
/*
|
||||
* It is perfectly possible that we see another contention before the
|
||||
* first one is fully handled.
|
||||
*/
|
||||
drm_exec_drop_prelocked(exec);
|
||||
|
||||
/* We move the reference from contended to prelocked here */
|
||||
exec->prelocked = obj;
|
||||
return 0;
|
||||
|
||||
error_unlock:
|
||||
dma_resv_unlock(obj->resv);
|
||||
|
||||
error_dropref:
|
||||
drm_gem_object_put(obj);
|
||||
return ret;
|
||||
|
|
@ -212,35 +229,31 @@ int drm_exec_lock_obj(struct drm_exec *exec, struct drm_gem_object *obj)
|
|||
if (exec->prelocked == obj) {
|
||||
drm_gem_object_put(exec->prelocked);
|
||||
exec->prelocked = NULL;
|
||||
return 0;
|
||||
} else {
|
||||
if (exec->flags & DRM_EXEC_INTERRUPTIBLE_WAIT)
|
||||
ret = dma_resv_lock_interruptible(obj->resv,
|
||||
&exec->ticket);
|
||||
else
|
||||
ret = dma_resv_lock(obj->resv, &exec->ticket);
|
||||
|
||||
if (unlikely(ret == -EDEADLK)) {
|
||||
drm_gem_object_get(obj);
|
||||
exec->contended = obj;
|
||||
return -EDEADLK;
|
||||
}
|
||||
|
||||
if (unlikely(ret == -EALREADY) &&
|
||||
exec->flags & DRM_EXEC_IGNORE_DUPLICATES)
|
||||
return 0;
|
||||
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (exec->flags & DRM_EXEC_INTERRUPTIBLE_WAIT)
|
||||
ret = dma_resv_lock_interruptible(obj->resv, &exec->ticket);
|
||||
else
|
||||
ret = dma_resv_lock(obj->resv, &exec->ticket);
|
||||
|
||||
if (unlikely(ret == -EDEADLK)) {
|
||||
drm_gem_object_get(obj);
|
||||
exec->contended = obj;
|
||||
return -EDEADLK;
|
||||
}
|
||||
|
||||
if (unlikely(ret == -EALREADY) &&
|
||||
exec->flags & DRM_EXEC_IGNORE_DUPLICATES)
|
||||
return 0;
|
||||
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
|
||||
ret = drm_exec_obj_locked(exec, obj);
|
||||
if (ret)
|
||||
goto error_unlock;
|
||||
dma_resv_unlock(obj->resv);
|
||||
|
||||
return 0;
|
||||
|
||||
error_unlock:
|
||||
dma_resv_unlock(obj->resv);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_exec_lock_obj);
|
||||
|
|
|
|||
|
|
@ -2342,12 +2342,14 @@ static void intel_c10pll_dump_hw_state(struct drm_printer *p,
|
|||
static bool is_arrowlake_s_by_host_bridge(void)
|
||||
{
|
||||
struct pci_dev *pdev = NULL;
|
||||
u16 host_bridge_pci_dev_id;
|
||||
while ((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, pdev))) {
|
||||
if (IS_ARROWLAKE_S_BY_HOST_BRIDGE_ID(pdev->device)) {
|
||||
pci_dev_put(pdev);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
while ((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, pdev)))
|
||||
host_bridge_pci_dev_id = pdev->device;
|
||||
|
||||
return pdev && IS_ARROWLAKE_S_BY_HOST_BRIDGE_ID(host_bridge_pci_dev_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
static u16 intel_c20_hdmi_tmds_tx_cgf_1(struct intel_display *display)
|
||||
|
|
|
|||
|
|
@ -1023,6 +1023,55 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the load address is within the valid range for the given DMC ID.
|
||||
*/
|
||||
static bool dmc_load_addr_sanity_check(struct intel_dmc *dmc,
|
||||
u32 start_addr, u32 payload_size,
|
||||
int header_ver, enum intel_dmc_id dmc_id)
|
||||
{
|
||||
u32 start_range, end_range, end_addr;
|
||||
|
||||
if (header_ver != 3)
|
||||
return true;
|
||||
|
||||
switch (dmc_id) {
|
||||
case DMC_FW_MAIN:
|
||||
start_range = DMC_MAIN_PROGRAM_BASE_START;
|
||||
end_range = DMC_MAIN_PROGRAM_BASE_END;
|
||||
break;
|
||||
case DMC_FW_PIPEA:
|
||||
start_range = DMC_PIPEA_PROGRAM_BASE_START;
|
||||
end_range = DMC_PIPEA_PROGRAM_BASE_END;
|
||||
break;
|
||||
case DMC_FW_PIPEB:
|
||||
start_range = DMC_PIPEB_PROGRAM_BASE_START;
|
||||
end_range = DMC_PIPEB_PROGRAM_BASE_END;
|
||||
break;
|
||||
case DMC_FW_PIPEC:
|
||||
start_range = DMC_PIPEC_PROGRAM_BASE_START;
|
||||
end_range = DMC_PIPEC_PROGRAM_BASE_END;
|
||||
break;
|
||||
case DMC_FW_PIPED:
|
||||
start_range = DMC_PIPED_PROGRAM_BASE_START;
|
||||
end_range = DMC_PIPED_PROGRAM_BASE_END;
|
||||
break;
|
||||
default:
|
||||
MISSING_CASE(dmc_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (payload_size == 0)
|
||||
end_addr = start_addr;
|
||||
else if (check_add_overflow(start_addr, payload_size - 1, &end_addr))
|
||||
return false;
|
||||
|
||||
if (start_addr < start_range || end_addr > end_range)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc,
|
||||
const u32 *mmioaddr, u32 mmio_count,
|
||||
int header_ver, enum intel_dmc_id dmc_id)
|
||||
|
|
@ -1120,7 +1169,7 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
|
|||
}
|
||||
|
||||
/* Cache the dmc header info. */
|
||||
if (mmio_count > mmio_count_max) {
|
||||
if (!mmio_count || mmio_count > mmio_count_max) {
|
||||
drm_err(display->drm, "DMC firmware has wrong mmio count %u\n", mmio_count);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1166,13 +1215,21 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
|
|||
disable_dmc_evt(display, dmc_id, dmc_info->mmioaddr[i],
|
||||
dmc_info->mmiodata[i]) ? " (disabling)" : "");
|
||||
}
|
||||
dmc_info->mmio_count = mmio_count;
|
||||
dmc_info->start_mmioaddr = start_mmioaddr;
|
||||
|
||||
rem_size -= header_len_bytes;
|
||||
|
||||
/* fw_size is in dwords, so multiplied by 4 to convert into bytes. */
|
||||
payload_size = dmc_header->fw_size * 4;
|
||||
if (check_mul_overflow(dmc_header->fw_size, 4u, &payload_size)) {
|
||||
drm_err(display->drm, "DMC fw_size too large (%u dwords)\n",
|
||||
dmc_header->fw_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!payload_size) {
|
||||
drm_err(display->drm, "DMC firmware has empty payload\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rem_size < payload_size)
|
||||
goto error_truncated;
|
||||
|
||||
|
|
@ -1180,12 +1237,21 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
|
|||
drm_err(display->drm, "DMC FW too big (%u bytes)\n", payload_size);
|
||||
return 0;
|
||||
}
|
||||
dmc_info->dmc_fw_size = dmc_header->fw_size;
|
||||
|
||||
if (!dmc_load_addr_sanity_check(dmc, start_mmioaddr, payload_size,
|
||||
dmc_header->header_ver, dmc_id)) {
|
||||
drm_err(display->drm, "DMC %d: firmware has wrong load address\n", dmc_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dmc_info->payload = kmalloc(payload_size, GFP_KERNEL);
|
||||
if (!dmc_info->payload)
|
||||
return 0;
|
||||
|
||||
dmc_info->mmio_count = mmio_count;
|
||||
dmc_info->start_mmioaddr = start_mmioaddr;
|
||||
dmc_info->dmc_fw_size = dmc_header->fw_size;
|
||||
|
||||
payload = (u8 *)(dmc_header) + header_len_bytes;
|
||||
memcpy(dmc_info->payload, payload, payload_size);
|
||||
|
||||
|
|
|
|||
|
|
@ -521,6 +521,18 @@ enum pipedmc_event_id {
|
|||
#define TGL_PIPE_MMIO_END(dmc_id) _PICK_EVEN(((dmc_id) - 1), _TGL_PIPEA_MMIO_END,\
|
||||
_TGL_PIPEB_MMIO_END)
|
||||
|
||||
/* For DMC header version v3*/
|
||||
#define DMC_MAIN_PROGRAM_BASE_START 0x80000
|
||||
#define DMC_MAIN_PROGRAM_BASE_END 0x86fff
|
||||
#define DMC_PIPEA_PROGRAM_BASE_START 0x90000
|
||||
#define DMC_PIPEA_PROGRAM_BASE_END 0x96fff
|
||||
#define DMC_PIPEB_PROGRAM_BASE_START 0x98000
|
||||
#define DMC_PIPEB_PROGRAM_BASE_END 0x9efff
|
||||
#define DMC_PIPEC_PROGRAM_BASE_START 0x52000
|
||||
#define DMC_PIPEC_PROGRAM_BASE_END 0x53fff
|
||||
#define DMC_PIPED_PROGRAM_BASE_START 0x59000
|
||||
#define DMC_PIPED_PROGRAM_BASE_END 0x5afff
|
||||
|
||||
#define SKL_DMC_DC3_DC5_COUNT _MMIO(0x80030)
|
||||
#define SKL_DMC_DC5_DC6_COUNT _MMIO(0x8002C)
|
||||
#define BXT_DMC_DC3_DC5_COUNT _MMIO(0x80038)
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ static char *get_gpu_model_name(struct panthor_device *ptdev)
|
|||
case GPU_PROD_ID_MAKE(10, 7):
|
||||
return "Mali-G610";
|
||||
case GPU_PROD_ID_MAKE(11, 2):
|
||||
if (shader_core_count > 10 && ray_intersection)
|
||||
if (shader_core_count >= 10 && ray_intersection)
|
||||
return "Mali-G715-Immortalis";
|
||||
else if (shader_core_count >= 7)
|
||||
return "Mali-G715";
|
||||
|
|
|
|||
|
|
@ -894,7 +894,7 @@ static void vc4_hdmi_encoder_post_crtc_disable(struct drm_encoder *encoder,
|
|||
|
||||
spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
|
||||
|
||||
HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0);
|
||||
HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, VC4_HDMI_RAM_PACKET_ENABLE);
|
||||
|
||||
HDMI_WRITE(HDMI_VID_CTL, HDMI_READ(HDMI_VID_CTL) | VC4_HD_VID_CTL_CLRRGB);
|
||||
|
||||
|
|
@ -1663,9 +1663,6 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder,
|
|||
WARN_ONCE(ret, "Timeout waiting for "
|
||||
"VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE\n");
|
||||
} else {
|
||||
HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
|
||||
HDMI_READ(HDMI_RAM_PACKET_CONFIG) &
|
||||
~(VC4_HDMI_RAM_PACKET_ENABLE));
|
||||
HDMI_WRITE(HDMI_SCHEDULER_CONTROL,
|
||||
HDMI_READ(HDMI_SCHEDULER_CONTROL) &
|
||||
~VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
|
||||
|
|
@ -1684,9 +1681,6 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder,
|
|||
WARN_ON(!(HDMI_READ(HDMI_SCHEDULER_CONTROL) &
|
||||
VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE));
|
||||
|
||||
HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
|
||||
VC4_HDMI_RAM_PACKET_ENABLE);
|
||||
|
||||
spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
|
||||
vc4_hdmi->packet_ram_enabled = true;
|
||||
|
||||
|
|
@ -3143,6 +3137,11 @@ static int vc5_hdmi_init_resources(struct drm_device *drm,
|
|||
static int vc4_hdmi_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
|
||||
HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0);
|
||||
spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
|
||||
|
||||
clk_disable_unprepare(vc4_hdmi->audio_clock);
|
||||
clk_disable_unprepare(vc4_hdmi->hsm_clock);
|
||||
|
|
@ -3153,9 +3152,8 @@ static int vc4_hdmi_runtime_suspend(struct device *dev)
|
|||
static int vc4_hdmi_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
|
||||
unsigned long __maybe_unused flags;
|
||||
unsigned long rate, flags;
|
||||
u32 __maybe_unused value;
|
||||
unsigned long rate;
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
|
||||
|
|
@ -3201,6 +3199,10 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
|
||||
HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, VC4_HDMI_RAM_PACKET_ENABLE);
|
||||
spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_clk:
|
||||
|
|
|
|||
|
|
@ -225,6 +225,7 @@ static int virtgpu_freeze(struct virtio_device *vdev)
|
|||
goto err_resume;
|
||||
}
|
||||
|
||||
virtio_reset_device(vdev);
|
||||
vdev->config->del_vqs(vdev);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -589,7 +589,6 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
|
|||
struct drm_plane *plane;
|
||||
const uint32_t *formats;
|
||||
int nformats;
|
||||
int ret;
|
||||
|
||||
if (type == DRM_PLANE_TYPE_CURSOR) {
|
||||
formats = virtio_gpu_cursor_formats;
|
||||
|
|
@ -615,17 +614,5 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
|
|||
drm_plane_create_blend_mode_property(plane,
|
||||
BIT(DRM_MODE_BLEND_PREMULTI));
|
||||
|
||||
if (type == DRM_PLANE_TYPE_CURSOR) {
|
||||
/*
|
||||
* The cursor plane exposes a format with an alpha channel,
|
||||
* which requires a blend mode property. The host blends
|
||||
* premultiplied alpha, matching the property's default.
|
||||
*/
|
||||
ret = drm_plane_create_blend_mode_property(plane,
|
||||
BIT(DRM_MODE_BLEND_PREMULTI));
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return plane;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -330,6 +330,12 @@ static void xe_evict_flags(struct ttm_buffer_object *tbo,
|
|||
return;
|
||||
}
|
||||
|
||||
/* No resource: nothing is placed/mapped, so there is nothing to evict. */
|
||||
if (!tbo->resource) {
|
||||
placement->num_placement = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
bo = ttm_to_xe_bo(tbo);
|
||||
if (bo->flags & XE_BO_FLAG_CPU_ADDR_MIRROR) {
|
||||
*placement = sys_placement;
|
||||
|
|
@ -944,6 +950,8 @@ static int xe_bo_move_notify(struct xe_bo *bo,
|
|||
*
|
||||
* Transfers pages between shrinkable and purgeable buckets when the BO
|
||||
* purgeable state changes. Called automatically from xe_bo_set_purgeable_state().
|
||||
* For pinned BOs, whose pages are not accounted, only the purgeable flag is
|
||||
* updated, so that the correct bucket is used when the BO is unpinned.
|
||||
*/
|
||||
static void xe_bo_set_purgeable_shrinker(struct xe_bo *bo,
|
||||
enum xe_madv_purgeable_state new_state)
|
||||
|
|
@ -960,7 +968,8 @@ static void xe_bo_set_purgeable_shrinker(struct xe_bo *bo,
|
|||
return;
|
||||
|
||||
xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
|
||||
tt_pages = tt->num_pages;
|
||||
/* Pinned bos are not accounted. Only update the purgeable flag. */
|
||||
tt_pages = xe_bo_is_pinned(bo) ? 0 : tt->num_pages;
|
||||
|
||||
if (!xe_tt->purgeable && new_state == XE_MADV_PURGEABLE_DONTNEED) {
|
||||
xe_tt->purgeable = true;
|
||||
|
|
|
|||
|
|
@ -346,11 +346,8 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
|||
xe_sched_job_push(job);
|
||||
xe_vm_reactivate_rebind(vm);
|
||||
|
||||
if (!err && !xe_vm_in_lr_mode(vm)) {
|
||||
spin_lock(&xe->ttm.lru_lock);
|
||||
ttm_lru_bulk_move_tail(&vm->lru_bulk_move);
|
||||
spin_unlock(&xe->ttm.lru_lock);
|
||||
}
|
||||
if (!err && !xe_vm_in_lr_mode(vm))
|
||||
xe_vm_bump_lru(vm, exec);
|
||||
|
||||
if (mode == EXEC_MODE_LR)
|
||||
xe_hw_engine_group_resume_faulting_lr_jobs(group);
|
||||
|
|
|
|||
|
|
@ -914,6 +914,13 @@ static int xe_oa_alloc_oa_buffer(struct xe_oa_stream *stream, size_t size)
|
|||
if (IS_ERR(bo))
|
||||
return PTR_ERR(bo);
|
||||
|
||||
/*
|
||||
* ttm_bo_type_kernel BOs are not zeroed on allocation, so the buffer can
|
||||
* hold stale data from previously freed pages. Since the OA buffer is
|
||||
* mmap'able by userspace, clear it here to avoid leaking kernel memory.
|
||||
*/
|
||||
xe_map_memset(stream->oa->xe, &bo->vmap, 0, 0, xe_bo_size(bo));
|
||||
|
||||
stream->oa_buffer.bo = bo;
|
||||
|
||||
stream->oa_buffer.bounce = kmalloc(stream->oa_buffer.format->size, GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -410,6 +410,33 @@ int xe_vm_validate_rebind(struct xe_vm *vm, struct drm_exec *exec,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_vm_bump_lru() - Bump the LRU position of BOs used by a submission
|
||||
* @vm: The vm for which we are bumping LRUs.
|
||||
* @exec: The struct drm_exec with the locked GEM objects.
|
||||
*
|
||||
* Move the VM's private BOs, and all external objects locked by @exec,
|
||||
* to the LRU tail. Private BOs are moved in bulk using @vm's
|
||||
* &xe_vm.lru_bulk_move. External objects, which may be shared with other
|
||||
* VMs, are not part of that bulk move and are bumped individually.
|
||||
*/
|
||||
void xe_vm_bump_lru(struct xe_vm *vm, struct drm_exec *exec)
|
||||
{
|
||||
spinlock_t *lru_lock = &vm->xe->ttm.lru_lock;
|
||||
struct drm_gem_object *obj;
|
||||
|
||||
spin_lock(lru_lock);
|
||||
ttm_lru_bulk_move_tail(&vm->lru_bulk_move);
|
||||
drm_exec_for_each_locked_object(exec, obj) {
|
||||
if (!drm_gpuvm_is_extobj(&vm->gpuvm, obj))
|
||||
continue;
|
||||
|
||||
ttm_bo_move_to_lru_tail(&gem_to_xe_bo(obj)->ttm);
|
||||
cond_resched_lock(lru_lock);
|
||||
}
|
||||
spin_unlock(lru_lock);
|
||||
}
|
||||
|
||||
static int xe_preempt_work_begin(struct drm_exec *exec, struct xe_vm *vm,
|
||||
bool *done)
|
||||
{
|
||||
|
|
@ -560,9 +587,7 @@ static void preempt_rebind_work_func(struct work_struct *w)
|
|||
|
||||
#undef retry_required
|
||||
|
||||
spin_lock(&vm->xe->ttm.lru_lock);
|
||||
ttm_lru_bulk_move_tail(&vm->lru_bulk_move);
|
||||
spin_unlock(&vm->xe->ttm.lru_lock);
|
||||
xe_vm_bump_lru(vm, &exec);
|
||||
|
||||
/* Point of no return. */
|
||||
arm_preempt_fences(vm, &preempt_fences);
|
||||
|
|
|
|||
|
|
@ -284,6 +284,8 @@ int xe_vm_lock_vma(struct drm_exec *exec, struct xe_vma *vma);
|
|||
int xe_vm_validate_rebind(struct xe_vm *vm, struct drm_exec *exec,
|
||||
unsigned int num_fences);
|
||||
|
||||
void xe_vm_bump_lru(struct xe_vm *vm, struct drm_exec *exec);
|
||||
|
||||
struct dma_fence *xe_vm_bind_kernel_bo(struct xe_vm *vm, struct xe_bo *bo,
|
||||
struct xe_exec_queue *q, u64 addr,
|
||||
enum xe_cache_level cache_lvl);
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ static inline u32 hv_ring_gpadl_send_hvpgoffset(u32 offset)
|
|||
* therefore leaving a (PAGE_SIZE - HV_HYP_PAGE_SIZE) gap.
|
||||
*
|
||||
* And to calculate the effective send offset in gpadl, we need to
|
||||
* substract this gap.
|
||||
* subtract this gap.
|
||||
*/
|
||||
return (offset - (PAGE_SIZE - HV_HYP_PAGE_SIZE)) >> HV_HYP_PAGE_SHIFT;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -752,13 +752,14 @@ static void init_vp_index(struct vmbus_channel *channel)
|
|||
u32 i, ncpu = num_online_cpus();
|
||||
cpumask_var_t available_mask;
|
||||
struct cpumask *allocated_mask;
|
||||
const struct cpumask *node_mask;
|
||||
const struct cpumask *hk_mask = housekeeping_cpumask(HK_TYPE_MANAGED_IRQ);
|
||||
u32 target_cpu;
|
||||
int numa_node;
|
||||
|
||||
if (!perf_chn ||
|
||||
!alloc_cpumask_var(&available_mask, GFP_KERNEL) ||
|
||||
cpumask_empty(hk_mask)) {
|
||||
!cpumask_intersects(hk_mask, cpu_online_mask)) {
|
||||
/*
|
||||
* If the channel is not a performance critical
|
||||
* channel, bind it to VMBUS_CONNECT_CPU.
|
||||
|
|
@ -780,14 +781,19 @@ static void init_vp_index(struct vmbus_channel *channel)
|
|||
next_numa_node_id = 0;
|
||||
continue;
|
||||
}
|
||||
if (cpumask_empty(cpumask_of_node(numa_node)))
|
||||
/*
|
||||
* Try next NUMA node if current NUMA node has no CPU
|
||||
* or doesn't contain any housekeeping CPU.
|
||||
*/
|
||||
node_mask = cpumask_of_node(numa_node);
|
||||
if (!cpumask_intersects(node_mask, hk_mask))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
allocated_mask = &hv_context.hv_numa_map[numa_node];
|
||||
|
||||
retry:
|
||||
cpumask_xor(available_mask, allocated_mask, cpumask_of_node(numa_node));
|
||||
cpumask_xor(available_mask, allocated_mask, node_mask);
|
||||
cpumask_and(available_mask, available_mask, hk_mask);
|
||||
|
||||
if (cpumask_empty(available_mask)) {
|
||||
|
|
|
|||
|
|
@ -346,7 +346,6 @@ int vmbus_connect(void)
|
|||
cleanup:
|
||||
pr_err("Unable to connect to host\n");
|
||||
|
||||
vmbus_connection.conn_state = DISCONNECTED;
|
||||
vmbus_disconnect();
|
||||
|
||||
kfree(msginfo);
|
||||
|
|
|
|||
|
|
@ -819,6 +819,9 @@ static vm_fault_t mshv_vtl_fault(struct vm_fault *vmf)
|
|||
return VM_FAULT_NOPAGE;
|
||||
}
|
||||
|
||||
if (!page)
|
||||
return VM_FAULT_SIGBUS;
|
||||
|
||||
get_page(page);
|
||||
vmf->page = page;
|
||||
|
||||
|
|
|
|||
|
|
@ -2923,23 +2923,19 @@ static void hv_crash_handler(struct pt_regs *regs)
|
|||
static int hv_synic_suspend(void *data)
|
||||
{
|
||||
/*
|
||||
* When we reach here, all the non-boot CPUs have been offlined.
|
||||
* If we're in a legacy configuration where stimer Direct Mode is
|
||||
* not enabled, the stimers on the non-boot CPUs have been unbound
|
||||
* in hv_synic_cleanup() -> hv_stimer_legacy_cleanup() ->
|
||||
* hv_stimer_cleanup() -> clockevents_unbind_device().
|
||||
* When we reach here, all the non-boot CPUs have been offlined,
|
||||
* and their stimers have been cleaned up by the cpuhp teardown
|
||||
* callback hv_stimer_cleanup().
|
||||
*
|
||||
* hv_synic_suspend() only runs on CPU0 with interrupts disabled.
|
||||
* Here we do not call hv_stimer_legacy_cleanup() on CPU0 because:
|
||||
* 1) it's unnecessary as interrupts remain disabled between
|
||||
* syscore_suspend() and syscore_resume(): see create_image() and
|
||||
* The stimer on CPU0 is not explicitly cleaned up here because:
|
||||
* 1) it's harmless as interrupts remain disabled between
|
||||
* syscore_suspend() and syscore_resume(), so the stimer cannot
|
||||
* fire during this window: see create_image() and
|
||||
* resume_target_kernel()
|
||||
* 2) the stimer on CPU0 is automatically disabled later by
|
||||
* syscore_suspend() -> timekeeping_suspend() -> tick_suspend() -> ...
|
||||
* -> clockevents_shutdown() -> ... -> hv_ce_shutdown()
|
||||
* 3) a warning would be triggered if we call
|
||||
* clockevents_unbind_device(), which may sleep, in an
|
||||
* interrupts-disabled context.
|
||||
*/
|
||||
|
||||
hv_hyp_synic_disable_regs(0);
|
||||
|
|
@ -3043,7 +3039,6 @@ static void __exit vmbus_exit(void)
|
|||
|
||||
hv_remove_kexec_handler();
|
||||
hv_remove_crash_handler();
|
||||
vmbus_connection.conn_state = DISCONNECTED;
|
||||
hv_stimer_global_cleanup();
|
||||
vmbus_disconnect();
|
||||
if (vmbus_irq == -1)
|
||||
|
|
|
|||
|
|
@ -164,12 +164,12 @@ static irqreturn_t cci_isr(int irq, void *dev)
|
|||
}
|
||||
|
||||
if (unlikely(val & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK)) {
|
||||
reset = CCI_RESET_CMD_M0_MASK;
|
||||
reset |= CCI_RESET_CMD_M0_MASK;
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (unlikely(val & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK)) {
|
||||
reset = CCI_RESET_CMD_M1_MASK;
|
||||
reset |= CCI_RESET_CMD_M1_MASK;
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -201,28 +201,31 @@ static const struct geni_i2c_clk_fld geni_i2c_clk_map_32mhz[] = {
|
|||
static int geni_i2c_clk_map_idx(struct geni_i2c_dev *gi2c)
|
||||
{
|
||||
const struct geni_i2c_clk_fld *itr;
|
||||
unsigned long res_freq;
|
||||
unsigned long req_freq, res_freq;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Frequency counter tables are calibrated for a specific source
|
||||
* clock frequency and are not valid for any multiple of it
|
||||
* (e.g. 64 MHz, 128 MHz).
|
||||
* Use exact=true and verify res_freq matches req_freq literally
|
||||
* to reject harmonics: a 64 MHz clock that divides evenly to
|
||||
* 32 MHz would pass exact matching but produce double the intended
|
||||
* I2C frequency with these counter values.
|
||||
* Use 32 MHz only if already selected, otherwise use 19.2 MHz.
|
||||
* Preferring 32 MHz merely because DFS supports it breaks I2C
|
||||
* transfers on X1E80100 CRD.
|
||||
*/
|
||||
if (!geni_se_clk_freq_match(&gi2c->se, GENI_SE_CLK_32MHZ,
|
||||
&gi2c->clk_idx, &res_freq, true) &&
|
||||
res_freq == GENI_SE_CLK_32MHZ) {
|
||||
if (clk_get_rate(gi2c->se.clk) == GENI_SE_CLK_32MHZ) {
|
||||
req_freq = GENI_SE_CLK_32MHZ;
|
||||
itr = geni_i2c_clk_map_32mhz;
|
||||
} else if (!geni_se_clk_freq_match(&gi2c->se, GENI_SE_CLK_19P2MHZ,
|
||||
&gi2c->clk_idx, &res_freq, true) &&
|
||||
res_freq == GENI_SE_CLK_19P2MHZ) {
|
||||
itr = geni_i2c_clk_map_19p2mhz;
|
||||
} else {
|
||||
dev_err(gi2c->se.dev,
|
||||
"Unsupported SE source clock: must be exactly 32 MHz or 19.2 MHz\n");
|
||||
req_freq = GENI_SE_CLK_19P2MHZ;
|
||||
itr = geni_i2c_clk_map_19p2mhz;
|
||||
}
|
||||
|
||||
ret = geni_se_clk_freq_match(&gi2c->se, req_freq, &gi2c->clk_idx,
|
||||
&res_freq, true);
|
||||
if (ret)
|
||||
return dev_err_probe(gi2c->se.dev, ret,
|
||||
"Failed to find SE source clock %lu Hz\n",
|
||||
req_freq);
|
||||
if (res_freq != req_freq) {
|
||||
dev_err(gi2c->se.dev, "Unsupported SE source clock %lu Hz\n",
|
||||
res_freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ static int wmt_i2c_probe(struct platform_device *pdev)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
i2c->clk = of_clk_get(np, 0);
|
||||
i2c->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(i2c->clk))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(i2c->clk),
|
||||
"unable to request clock\n");
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ enum i2c_scl_freq {
|
|||
* @rx_pos: Position within current RX message
|
||||
* @endianness: big/little-endian byte order
|
||||
* @clk: Pointer to AXI4-lite input clock
|
||||
* @irq: Interrupt number
|
||||
* @state: See STATE_
|
||||
* @singlemaster: Indicates bus is single master
|
||||
* @dynamic: Mode of controller
|
||||
|
|
@ -95,6 +96,7 @@ struct xiic_i2c {
|
|||
int rx_pos;
|
||||
enum xiic_endian endianness;
|
||||
struct clk *clk;
|
||||
int irq;
|
||||
enum xilinx_i2c_state state;
|
||||
bool singlemaster;
|
||||
bool dynamic;
|
||||
|
|
@ -1506,9 +1508,17 @@ static int xiic_i2c_probe(struct platform_device *pdev)
|
|||
|
||||
pm_runtime_set_autosuspend_delay(dev, XIIC_PM_TIMEOUT);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
ret = devm_pm_runtime_set_active_enabled(dev);
|
||||
if (ret)
|
||||
/*
|
||||
* Enable runtime PM by hand: devm_pm_runtime_set_active_enabled()
|
||||
* tears down in an order that races the devm-enabled clock release and
|
||||
* makes clk_core_disable() WARN (see xiic_i2c_remove()).
|
||||
*/
|
||||
ret = pm_runtime_set_active(dev);
|
||||
if (ret) {
|
||||
pm_runtime_dont_use_autosuspend(dev);
|
||||
return ret;
|
||||
}
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
/* SCL frequency configuration */
|
||||
i2c->input_clk = clk_get_rate(i2c->clk);
|
||||
|
|
@ -1517,10 +1527,15 @@ static int xiic_i2c_probe(struct platform_device *pdev)
|
|||
if (ret || i2c->i2c_clk > I2C_MAX_FAST_MODE_PLUS_FREQ)
|
||||
i2c->i2c_clk = 0;
|
||||
|
||||
ret = devm_request_threaded_irq(dev, irq, NULL, xiic_process,
|
||||
IRQF_ONESHOT, pdev->name, i2c);
|
||||
/*
|
||||
* Request the IRQ non-managed: later probe steps unwind manually via
|
||||
* goto, so a devm handler could still be live after that teardown runs.
|
||||
*/
|
||||
i2c->irq = irq;
|
||||
ret = request_threaded_irq(irq, NULL, xiic_process, IRQF_ONESHOT,
|
||||
pdev->name, i2c);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_pm_disable;
|
||||
|
||||
i2c->singlemaster = device_property_read_bool(dev, "single-master");
|
||||
|
||||
|
|
@ -1537,14 +1552,16 @@ static int xiic_i2c_probe(struct platform_device *pdev)
|
|||
i2c->endianness = BIG;
|
||||
|
||||
ret = xiic_reinit(i2c);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Cannot xiic_reinit\n");
|
||||
if (ret) {
|
||||
dev_err_probe(dev, ret, "Cannot xiic_reinit\n");
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
/* add i2c adapter to i2c tree */
|
||||
ret = i2c_add_numbered_adapter(&i2c->adap);
|
||||
if (ret) {
|
||||
xiic_deinit(i2c);
|
||||
return ret;
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
if (pdata) {
|
||||
|
|
@ -1557,6 +1574,15 @@ static int xiic_i2c_probe(struct platform_device *pdev)
|
|||
res, irq, i2c->i2c_clk);
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_irq:
|
||||
free_irq(irq, i2c);
|
||||
err_pm_disable:
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_set_suspended(dev);
|
||||
pm_runtime_dont_use_autosuspend(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void xiic_i2c_remove(struct platform_device *pdev)
|
||||
|
|
@ -1568,6 +1594,8 @@ static void xiic_i2c_remove(struct platform_device *pdev)
|
|||
/* remove adapter & data */
|
||||
i2c_del_adapter(&i2c->adap);
|
||||
|
||||
free_irq(i2c->irq, i2c);
|
||||
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (ret < 0)
|
||||
dev_warn(dev, "Failed to activate device for removal (%pe)\n",
|
||||
|
|
@ -1575,7 +1603,10 @@ static void xiic_i2c_remove(struct platform_device *pdev)
|
|||
else
|
||||
xiic_deinit(i2c);
|
||||
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_put_noidle(dev);
|
||||
pm_runtime_set_suspended(dev);
|
||||
pm_runtime_dont_use_autosuspend(dev);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops xiic_dev_pm_ops = {
|
||||
|
|
|
|||
|
|
@ -421,6 +421,9 @@ struct irq_remap_table {
|
|||
u32 *table;
|
||||
};
|
||||
|
||||
/* Interrupt remapping feature used? */
|
||||
extern bool amd_iommu_irq_remap;
|
||||
|
||||
extern const struct iommu_ops amd_iommu_ops;
|
||||
|
||||
/* IVRS indicates that pre-boot remapping was enabled */
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ struct ivmd_header {
|
|||
} __attribute__((packed));
|
||||
|
||||
bool amd_iommu_dump;
|
||||
static bool amd_iommu_irq_remap __read_mostly;
|
||||
bool amd_iommu_irq_remap __read_mostly;
|
||||
|
||||
enum protection_domain_mode amd_iommu_pgtable = PD_MODE_V1;
|
||||
/* Virtual address size */
|
||||
|
|
|
|||
|
|
@ -3973,6 +3973,9 @@ static int irq_remapping_select(struct irq_domain *d, struct irq_fwspec *fwspec,
|
|||
struct amd_iommu *iommu;
|
||||
int devid = -1;
|
||||
|
||||
if (!amd_iommu_irq_remap)
|
||||
return 0;
|
||||
|
||||
if (x86_fwspec_is_ioapic(fwspec))
|
||||
devid = get_ioapic_devid(fwspec->param[0]);
|
||||
else if (x86_fwspec_is_hpet(fwspec))
|
||||
|
|
|
|||
|
|
@ -25,6 +25,6 @@ $(eval $(foreach fmt,$(iommu_pt_fmt-m),$(call create_format,$(fmt),m)))
|
|||
# with -DGENERIC_PT_KUNIT
|
||||
$(obj)/kunit_iommu_%.o: $(src)/iommu_%.c FORCE
|
||||
$(call rule_mkdir)
|
||||
$(call if_changed_dep,cc_o_c)
|
||||
$(call if_changed_rule,cc_o_c)
|
||||
|
||||
obj-$(CONFIG_IOMMU_PT_KUNIT_TEST) += $(IOMMU_PT_KUNIT_TEST)
|
||||
|
|
|
|||
|
|
@ -1552,6 +1552,8 @@ static int owl_emac_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
netdev->netdev_ops = &owl_emac_netdev_ops;
|
||||
|
||||
ret = owl_emac_phy_init(netdev);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to initialize PHY\n");
|
||||
|
|
@ -1563,7 +1565,6 @@ static int owl_emac_probe(struct platform_device *pdev)
|
|||
netdev->min_mtu = OWL_EMAC_MTU_MIN;
|
||||
netdev->max_mtu = OWL_EMAC_MTU_MAX;
|
||||
netdev->watchdog_timeo = OWL_EMAC_TX_TIMEOUT;
|
||||
netdev->netdev_ops = &owl_emac_netdev_ops;
|
||||
netdev->ethtool_ops = &owl_emac_ethtool_ops;
|
||||
netif_napi_add(netdev, &priv->napi, owl_emac_poll);
|
||||
|
||||
|
|
|
|||
|
|
@ -733,6 +733,8 @@ static int adin1140_probe(struct spi_device *spi)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
netdev->netdev_ops = &adin1140_netdev_ops;
|
||||
|
||||
ret = adin1140_phy_init(priv, spi);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
@ -748,7 +750,6 @@ static int adin1140_probe(struct spi_device *spi)
|
|||
|
||||
netdev->if_port = IF_PORT_10BASET;
|
||||
netdev->irq = spi->irq;
|
||||
netdev->netdev_ops = &adin1140_netdev_ops;
|
||||
netdev->ethtool_ops = &adin1140_ethtool_ops;
|
||||
netdev->netns_immutable = true;
|
||||
netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE |
|
||||
|
|
|
|||
|
|
@ -1421,6 +1421,8 @@ static int greth_of_probe(struct platform_device *ofdev)
|
|||
/* Check if MAC can handle MDIO interrupts */
|
||||
greth->mdio_int_en = (tmp >> 26) & 1;
|
||||
|
||||
dev->netdev_ops = &greth_netdev_ops;
|
||||
|
||||
err = greth_mdio_init(greth);
|
||||
if (err) {
|
||||
if (netif_msg_probe(greth))
|
||||
|
|
@ -1498,7 +1500,6 @@ static int greth_of_probe(struct platform_device *ofdev)
|
|||
dev->flags &= ~IFF_MULTICAST;
|
||||
}
|
||||
|
||||
dev->netdev_ops = &greth_netdev_ops;
|
||||
dev->ethtool_ops = &greth_ethtool_ops;
|
||||
|
||||
err = register_netdev(dev);
|
||||
|
|
|
|||
|
|
@ -1225,6 +1225,8 @@ static int au1000_probe(struct platform_device *pdev)
|
|||
goto err_mdiobus_reg;
|
||||
}
|
||||
|
||||
dev->netdev_ops = &au1000_netdev_ops;
|
||||
|
||||
err = au1000_mii_probe(dev);
|
||||
if (err != 0)
|
||||
goto err_out;
|
||||
|
|
@ -1263,7 +1265,6 @@ static int au1000_probe(struct platform_device *pdev)
|
|||
|
||||
dev->base_addr = base->start;
|
||||
dev->irq = irq;
|
||||
dev->netdev_ops = &au1000_netdev_ops;
|
||||
dev->ethtool_ops = &au1000_ethtool_ops;
|
||||
dev->watchdog_timeo = ETH_TX_TIMEOUT;
|
||||
|
||||
|
|
|
|||
|
|
@ -2153,6 +2153,16 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* We store Tx state in the control block, so the skb must not be
|
||||
* shared, but ether_setup() leaves IFF_TX_SKB_SHARING set.
|
||||
*/
|
||||
skb = skb_share_check(skb, GFP_ATOMIC);
|
||||
if (!skb) {
|
||||
BCMGENET_STATS64_INC((&ring->stats64), dropped);
|
||||
ret = NETDEV_TX_OK;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Retain how many bytes will be sent on the wire, without TSB inserted
|
||||
* by transmit checksum offload
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1211,6 +1211,8 @@ static int ethoc_probe(struct platform_device *pdev)
|
|||
goto free3;
|
||||
}
|
||||
|
||||
netdev->netdev_ops = ðoc_netdev_ops;
|
||||
|
||||
ret = ethoc_mdio_probe(netdev);
|
||||
if (ret) {
|
||||
dev_err(&netdev->dev, "failed to probe MDIO bus\n");
|
||||
|
|
@ -1218,7 +1220,6 @@ static int ethoc_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
/* setup the net_device structure */
|
||||
netdev->netdev_ops = ðoc_netdev_ops;
|
||||
netdev->watchdog_timeo = ETHOC_TIMEOUT;
|
||||
netdev->features |= 0;
|
||||
netdev->ethtool_ops = ðoc_ethtool_ops;
|
||||
|
|
|
|||
|
|
@ -976,6 +976,8 @@ static int hip04_mac_probe(struct platform_device *pdev)
|
|||
goto init_fail;
|
||||
}
|
||||
|
||||
ndev->netdev_ops = &hip04_netdev_ops;
|
||||
|
||||
priv->phy_node = of_parse_phandle(node, "phy-handle", 0);
|
||||
if (priv->phy_node) {
|
||||
priv->phy = of_phy_connect(ndev, priv->phy_node,
|
||||
|
|
@ -989,7 +991,6 @@ static int hip04_mac_probe(struct platform_device *pdev)
|
|||
|
||||
INIT_WORK(&priv->tx_timeout_task, hip04_tx_timeout_task);
|
||||
|
||||
ndev->netdev_ops = &hip04_netdev_ops;
|
||||
ndev->ethtool_ops = &hip04_ethtool_ops;
|
||||
ndev->watchdog_timeo = TX_TIMEOUT;
|
||||
ndev->priv_flags |= IFF_UNICAST_FLT;
|
||||
|
|
|
|||
|
|
@ -830,6 +830,8 @@ static int hisi_femac_drv_probe(struct platform_device *pdev)
|
|||
hisi_femac_phy_reset(priv);
|
||||
}
|
||||
|
||||
ndev->netdev_ops = &hisi_femac_netdev_ops;
|
||||
|
||||
phy = of_phy_get_and_connect(ndev, node, hisi_femac_adjust_link);
|
||||
if (!phy) {
|
||||
dev_err(dev, "connect to PHY failed!\n");
|
||||
|
|
@ -850,7 +852,6 @@ static int hisi_femac_drv_probe(struct platform_device *pdev)
|
|||
|
||||
ndev->watchdog_timeo = 6 * HZ;
|
||||
ndev->priv_flags |= IFF_UNICAST_FLT;
|
||||
ndev->netdev_ops = &hisi_femac_netdev_ops;
|
||||
ndev->ethtool_ops = &hisi_femac_ethtools_ops;
|
||||
netif_napi_add_weight(ndev, &priv->napi, hisi_femac_poll,
|
||||
FEMAC_POLL_WEIGHT);
|
||||
|
|
|
|||
|
|
@ -3171,6 +3171,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
|
|||
netif_set_real_num_tx_queues(dev, mp->txq_count);
|
||||
netif_set_real_num_rx_queues(dev, mp->rxq_count);
|
||||
|
||||
dev->netdev_ops = &mv643xx_eth_netdev_ops;
|
||||
|
||||
err = 0;
|
||||
if (pd->phy_node) {
|
||||
phydev = of_phy_connect(mp->dev, pd->phy_node,
|
||||
|
|
@ -3221,8 +3223,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
|
|||
}
|
||||
dev->irq = irq;
|
||||
|
||||
dev->netdev_ops = &mv643xx_eth_netdev_ops;
|
||||
|
||||
dev->watchdog_timeo = 2 * HZ;
|
||||
dev->base_addr = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -928,6 +928,7 @@ static int mlx5_fs_fte_get_hws_actions(struct mlx5_flow_root_namespace *ns,
|
|||
goto free_actions;
|
||||
}
|
||||
(*ractions)[num_actions].aso_meter.offset =
|
||||
(fte_action->exe_aso.object_id - fte_action->exe_aso.base_id) * 2 +
|
||||
fte_action->exe_aso.flow_meter.meter_idx;
|
||||
(*ractions)[num_actions].aso_meter.init_color =
|
||||
fte_action->exe_aso.flow_meter.init_color;
|
||||
|
|
@ -1398,8 +1399,8 @@ static void mlx5_cmd_hws_packet_reformat_dealloc(struct mlx5_flow_root_namespace
|
|||
pr_data->data_size);
|
||||
break;
|
||||
case MLX5_REFORMAT_TYPE_L2_TO_L3_TUNNEL:
|
||||
pr_pool = mlx5_fs_get_pr_encap_pool(dev, &hws_pool->el2tol2tnl_pools,
|
||||
MLX5HWS_ACTION_TYP_REFORMAT_L2_TO_TNL_L2,
|
||||
pr_pool = mlx5_fs_get_pr_encap_pool(dev, &hws_pool->el2tol3tnl_pools,
|
||||
MLX5HWS_ACTION_TYP_REFORMAT_L2_TO_TNL_L3,
|
||||
pr_data->data_size);
|
||||
break;
|
||||
case MLX5_REFORMAT_TYPE_L3_TUNNEL_TO_L2:
|
||||
|
|
|
|||
|
|
@ -346,6 +346,8 @@ static int lan865x_probe(struct spi_device *spi)
|
|||
spi_set_drvdata(spi, priv);
|
||||
INIT_WORK(&priv->multicast_work, lan865x_multicast_work_handler);
|
||||
|
||||
netdev->netdev_ops = &lan865x_netdev_ops;
|
||||
|
||||
priv->tc6 = oa_tc6_init(spi, netdev, NULL);
|
||||
if (!priv->tc6) {
|
||||
ret = -ENODEV;
|
||||
|
|
@ -397,7 +399,6 @@ static int lan865x_probe(struct spi_device *spi)
|
|||
|
||||
netdev->if_port = IF_PORT_10BASET;
|
||||
netdev->irq = spi->irq;
|
||||
netdev->netdev_ops = &lan865x_netdev_ops;
|
||||
netdev->ethtool_ops = &lan865x_ethtool_ops;
|
||||
|
||||
ret = register_netdev(netdev);
|
||||
|
|
|
|||
|
|
@ -312,6 +312,12 @@ static int dwmac1000_irq_status(struct stmmac_priv *priv,
|
|||
if (intr_status & (PCS_ANE_IRQ | PCS_LINK_IRQ))
|
||||
stmmac_integrated_pcs_irq(priv, intr_status, x);
|
||||
|
||||
/* Reading RGSMIIIS clears the interrupt the MAC reset unmasks. */
|
||||
if (intr_status & PCS_RGSMIIIS_IRQ) {
|
||||
readl(ioaddr + GMAC_RGSMIIIS);
|
||||
x->irq_rgmii_n++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1563,6 +1563,8 @@ static int icssm_prueth_netdev_init(struct prueth *prueth,
|
|||
}
|
||||
ether_addr_copy(emac->mac_addr, ndev->dev_addr);
|
||||
|
||||
ndev->netdev_ops = &emac_netdev_ops;
|
||||
|
||||
/* connect PHY */
|
||||
emac->phydev = of_phy_get_and_connect(ndev, eth_node,
|
||||
icssm_emac_adjust_link);
|
||||
|
|
@ -1590,7 +1592,6 @@ static int icssm_prueth_netdev_init(struct prueth *prueth,
|
|||
}
|
||||
|
||||
ndev->dev.of_node = eth_node;
|
||||
ndev->netdev_ops = &emac_netdev_ops;
|
||||
|
||||
netif_napi_add(ndev, &emac->napi, icssm_emac_napi_poll);
|
||||
|
||||
|
|
|
|||
|
|
@ -206,16 +206,9 @@ static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb)
|
|||
{
|
||||
skb_pull(skb, sizeof(struct wmi_cmd_hdr));
|
||||
|
||||
if (wmi->cmd_rsp_buf && wmi->cmd_rsp_len) {
|
||||
if (skb->len < wmi->cmd_rsp_len) {
|
||||
wmi->cmd_rsp_status = -EMSGSIZE;
|
||||
goto complete;
|
||||
}
|
||||
if (wmi->cmd_rsp_buf != NULL && wmi->cmd_rsp_len != 0)
|
||||
memcpy(wmi->cmd_rsp_buf, skb->data, wmi->cmd_rsp_len);
|
||||
}
|
||||
wmi->cmd_rsp_status = 0;
|
||||
|
||||
complete:
|
||||
complete(&wmi->cmd_wait);
|
||||
}
|
||||
|
||||
|
|
@ -307,7 +300,6 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi,
|
|||
/* record the rsp buffer and length */
|
||||
wmi->cmd_rsp_buf = rsp_buf;
|
||||
wmi->cmd_rsp_len = rsp_len;
|
||||
wmi->cmd_rsp_status = 0;
|
||||
|
||||
wmi->last_seq_id = wmi->tx_seq_id;
|
||||
spin_unlock_irqrestore(&wmi->wmi_lock, flags);
|
||||
|
|
@ -364,13 +356,9 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
|
|||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&wmi->wmi_lock, flags);
|
||||
ret = wmi->cmd_rsp_status;
|
||||
spin_unlock_irqrestore(&wmi->wmi_lock, flags);
|
||||
|
||||
mutex_unlock(&wmi->op_mutex);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
|
||||
out:
|
||||
ath_dbg(common, WMI, "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id));
|
||||
|
|
|
|||
|
|
@ -157,7 +157,6 @@ struct wmi {
|
|||
u16 tx_seq_id;
|
||||
u8 *cmd_rsp_buf;
|
||||
u32 cmd_rsp_len;
|
||||
int cmd_rsp_status;
|
||||
bool stopped;
|
||||
|
||||
struct list_head pending_tx_events;
|
||||
|
|
|
|||
|
|
@ -421,23 +421,9 @@ static void rockchip_pcie_stop_link(struct dw_pcie *pci)
|
|||
static int rockchip_pcie_host_init(struct dw_pcie_rp *pp)
|
||||
{
|
||||
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
||||
struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
|
||||
struct device *dev = rockchip->pci.dev;
|
||||
int irq, ret;
|
||||
|
||||
irq = of_irq_get_byname(dev->of_node, "legacy");
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
pci->dbi_base2 = pci->dbi_base + PCIE_TYPE0_HDR_DBI2_OFFSET;
|
||||
|
||||
ret = rockchip_pcie_init_irq_domain(rockchip);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "failed to init irq domain\n");
|
||||
|
||||
irq_set_chained_handler_and_data(irq, rockchip_pcie_intx_handler,
|
||||
rockchip);
|
||||
|
||||
rockchip_pcie_configure_l1ss(pci);
|
||||
rockchip_pcie_enable_l0s(pci);
|
||||
pp->bridge->reset_root_port = rockchip_pcie_rc_reset_root_port;
|
||||
|
|
@ -730,6 +716,19 @@ static int rockchip_pcie_configure_rc(struct platform_device *pdev,
|
|||
PCIE_CLIENT_SET_MODE(PCIE_CLIENT_MODE_RC),
|
||||
PCIE_CLIENT_GENERAL_CON);
|
||||
|
||||
irq = of_irq_get_byname(dev->of_node, "legacy");
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
ret = rockchip_pcie_init_irq_domain(rockchip);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to init irq domain\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
irq_set_chained_handler_and_data(irq, rockchip_pcie_intx_handler,
|
||||
rockchip);
|
||||
|
||||
pp = &rockchip->pci.pp;
|
||||
pp->ops = &rockchip_pcie_host_ops;
|
||||
|
||||
|
|
|
|||
|
|
@ -1040,19 +1040,38 @@ static void put_pcichild(struct hv_pci_dev *hpdev)
|
|||
|
||||
/*
|
||||
* There is no good way to get notified from vmbus_onoffer_rescind(),
|
||||
* so let's use polling here, since this is not a hot path.
|
||||
* so let's use polling here, since this is not a hot path. If
|
||||
* wait_for_response() has been polling for 2 minutes
|
||||
* without either a rescind or completion, add a warning.
|
||||
*/
|
||||
#define PCI_RESPONSE_WARN_POLL_COUNT 1200
|
||||
|
||||
static int wait_for_response(struct hv_device *hdev,
|
||||
struct completion *comp)
|
||||
struct completion *comp,
|
||||
const char *msg_type)
|
||||
{
|
||||
u64 counter = 0;
|
||||
|
||||
while (true) {
|
||||
if (hdev->channel->rescind) {
|
||||
dev_warn_once(&hdev->device, "The device is gone.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (wait_for_completion_timeout(comp, HZ / 10))
|
||||
counter++;
|
||||
|
||||
if (wait_for_completion_timeout(comp, HZ / 10)) {
|
||||
if (counter > PCI_RESPONSE_WARN_POLL_COUNT)
|
||||
dev_warn(&hdev->device,
|
||||
"Late %s completion arrived.\n", msg_type);
|
||||
break;
|
||||
}
|
||||
|
||||
if (counter == PCI_RESPONSE_WARN_POLL_COUNT) {
|
||||
dev_err(&hdev->device,
|
||||
"%s stuck waiting for response, relid = %u\n",
|
||||
msg_type, hdev->channel->offermsg.child_relid);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -1518,7 +1537,8 @@ static int hv_read_config_block(struct pci_dev *pdev, void *buf,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = wait_for_response(hbus->hdev, &comp_pkt.comp_pkt.host_event);
|
||||
ret = wait_for_response(hbus->hdev, &comp_pkt.comp_pkt.host_event,
|
||||
"PCI_READ_BLOCK");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -1607,7 +1627,8 @@ static int hv_write_config_block(struct pci_dev *pdev, void *buf,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = wait_for_response(hbus->hdev, &comp_pkt.host_event);
|
||||
ret = wait_for_response(hbus->hdev, &comp_pkt.host_event,
|
||||
"PCI_WRITE_BLOCK");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -2624,7 +2645,8 @@ static struct hv_pci_dev *new_pcichild_device(struct hv_pcibus_device *hbus,
|
|||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (wait_for_response(hbus->hdev, &comp_pkt.host_event))
|
||||
if (wait_for_response(hbus->hdev, &comp_pkt.host_event,
|
||||
"PCI_QUERY_RESOURCE_REQUIREMENTS"))
|
||||
goto error;
|
||||
|
||||
hpdev->desc = *desc;
|
||||
|
|
@ -3256,7 +3278,8 @@ static int hv_pci_protocol_negotiation(struct hv_device *hdev,
|
|||
(unsigned long)pkt, VM_PKT_DATA_INBAND,
|
||||
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
|
||||
if (!ret)
|
||||
ret = wait_for_response(hdev, &comp_pkt.host_event);
|
||||
ret = wait_for_response(hdev, &comp_pkt.host_event,
|
||||
"PCI_QUERY_PROTOCOL_VERSION");
|
||||
|
||||
if (ret) {
|
||||
dev_err(&hdev->device,
|
||||
|
|
@ -3476,7 +3499,8 @@ static int hv_pci_enter_d0(struct hv_device *hdev)
|
|||
(unsigned long)pkt, VM_PKT_DATA_INBAND,
|
||||
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
|
||||
if (!ret)
|
||||
ret = wait_for_response(hdev, &comp_pkt.host_event);
|
||||
ret = wait_for_response(hdev, &comp_pkt.host_event,
|
||||
"PCI_BUS_D0ENTRY");
|
||||
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
|
@ -3553,7 +3577,8 @@ static int hv_pci_query_relations(struct hv_device *hdev)
|
|||
ret = vmbus_sendpacket(hdev->channel, &message, sizeof(message),
|
||||
0, VM_PKT_DATA_INBAND, 0);
|
||||
if (!ret)
|
||||
ret = wait_for_response(hdev, &comp);
|
||||
ret = wait_for_response(hdev, &comp,
|
||||
"PCI_QUERY_BUS_RELATIONS");
|
||||
|
||||
/*
|
||||
* In the case of fast device addition/removal, it's possible that
|
||||
|
|
@ -3644,7 +3669,8 @@ static int hv_send_resources_allocated(struct hv_device *hdev)
|
|||
VM_PKT_DATA_INBAND,
|
||||
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
|
||||
if (!ret)
|
||||
ret = wait_for_response(hdev, &comp_pkt.host_event);
|
||||
ret = wait_for_response(hdev, &comp_pkt.host_event,
|
||||
"PCI_RESOURCE_ASSIGNED");
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
|
|
@ -4155,6 +4181,9 @@ static struct hv_driver hv_pci_drv = {
|
|||
.remove = hv_pci_remove,
|
||||
.suspend = hv_pci_suspend,
|
||||
.resume = hv_pci_resume,
|
||||
.driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
},
|
||||
};
|
||||
|
||||
static void __exit exit_hv_pci_drv(void)
|
||||
|
|
|
|||
|
|
@ -1246,9 +1246,11 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout)
|
|||
* initialize.
|
||||
*
|
||||
* If the device is below a Root Port with Configuration RRS
|
||||
* Software Visibility enabled, reading the Vendor ID returns a
|
||||
* Software Visibility enabled, reading the Vendor ID may return a
|
||||
* special data value if the device responded with RRS. Read the
|
||||
* Vendor ID until we get non-RRS status.
|
||||
* Vendor ID until we get non-RRS status and something other than
|
||||
* ~0. The Vendor ID of VFs reads ~0, so check their Command
|
||||
* register instead.
|
||||
*
|
||||
* If there's no Root Port or Configuration RRS Software Visibility
|
||||
* is not enabled, the device may still respond with RRS, but
|
||||
|
|
@ -1268,8 +1270,13 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout)
|
|||
|
||||
if (root && root->config_rrs_sv) {
|
||||
pci_read_config_dword(dev, PCI_VENDOR_ID, &id);
|
||||
if (!pci_bus_rrs_vendor_id(id))
|
||||
break;
|
||||
if (!pci_bus_rrs_vendor_id(id)) {
|
||||
if (PCI_POSSIBLE_ERROR(id) && dev->is_virtfn)
|
||||
pci_read_config_dword(dev, PCI_COMMAND,
|
||||
&id);
|
||||
if (!PCI_POSSIBLE_ERROR(id))
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
pci_read_config_dword(dev, PCI_COMMAND, &id);
|
||||
if (!PCI_POSSIBLE_ERROR(id))
|
||||
|
|
|
|||
|
|
@ -428,7 +428,8 @@ void pci_aer_init(struct pci_dev *dev)
|
|||
* Advisory Non-Fatal Errors are masked by default (PCIe r7.0, sec
|
||||
* 7.8.4.6).
|
||||
*/
|
||||
if (pcie_aer_is_native(dev) && dev->devcap & PCI_EXP_DEVCAP_RBER)
|
||||
if (pcie_aer_is_native(dev) && dev->devcap & PCI_EXP_DEVCAP_RBER &&
|
||||
!dev->no_aer_anfe)
|
||||
pci_clear_and_set_config_dword(dev,
|
||||
dev->aer_cap + PCI_ERR_COR_MASK,
|
||||
PCI_ERR_COR_ADV_NFAT, 0);
|
||||
|
|
|
|||
|
|
@ -2574,6 +2574,17 @@ static void quirk_p64h2_1k_io(struct pci_dev *dev)
|
|||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io);
|
||||
|
||||
/*
|
||||
* Unmasking Advisory Non-Fatal Errors on the Apple T2 Secure Enclave
|
||||
* causes a MacBookPro16,1 to lose power. Set this before pci_aer_init()
|
||||
* so that it leaves the ANFE mask bit unchanged.
|
||||
*/
|
||||
static void quirk_no_aer_anfe(struct pci_dev *dev)
|
||||
{
|
||||
dev->no_aer_anfe = 1;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_APPLE, 0x1802, quirk_no_aer_anfe);
|
||||
|
||||
/*
|
||||
* Under some circumstances, AER is not linked with extended capabilities.
|
||||
* Force it to be linked by setting the corresponding control bit in the
|
||||
|
|
@ -5623,6 +5634,18 @@ static void quirk_no_flr_snet(struct pci_dev *dev)
|
|||
}
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLIDRUN, 0x1000, quirk_no_flr_snet);
|
||||
|
||||
/* Some Samsung SSDs advertise Immediate Readiness but aren't ready after FLR */
|
||||
static void quirk_no_imm_ready(struct pci_dev *dev)
|
||||
{
|
||||
if (!dev->imm_ready)
|
||||
return;
|
||||
|
||||
pci_info(dev, "Ignoring incorrectly advertised Immediate Readiness support\n");
|
||||
dev->imm_ready = 0;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SAMSUNG, 0xa80c, quirk_no_imm_ready);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SAMSUNG, 0xa80d, quirk_no_imm_ready);
|
||||
|
||||
static void quirk_no_ext_tags(struct pci_dev *pdev)
|
||||
{
|
||||
struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus);
|
||||
|
|
|
|||
|
|
@ -886,6 +886,15 @@ static void amd_gpio_irq_init(struct amd_gpio *gpio_dev)
|
|||
|
||||
mask = BIT(WAKE_CNTRL_OFF_S0I3) | BIT(WAKE_CNTRL_OFF_S3);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
/*
|
||||
* Platforms without _AEI leave GPIO wake sources to firmware, so
|
||||
* preserve their S4 wake bits.
|
||||
*/
|
||||
if (acpi_has_method(ACPI_HANDLE(&gpio_dev->pdev->dev), "_AEI"))
|
||||
mask |= BIT(WAKE_CNTRL_OFF_S4);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < desc->npins; i++) {
|
||||
int pin = desc->pins[i].number;
|
||||
const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
.intr_wakeup_present_bit = 6, \
|
||||
.intr_wakeup_enable_bit = 7, \
|
||||
.intr_target_bit = 8, \
|
||||
.intr_target_width = 4, \
|
||||
.intr_target_kpss_val = 3, \
|
||||
.intr_raw_status_bit = 4, \
|
||||
.intr_polarity_bit = 1, \
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@ static const char * const blsp1_uart0_groups[] = {
|
|||
};
|
||||
|
||||
static const char * const gcc_plltest_groups[] = {
|
||||
"gpio10", "gpio12",
|
||||
"gpio10",
|
||||
};
|
||||
|
||||
static const char * const gcc_tlmm_groups[] = {
|
||||
|
|
@ -539,7 +539,7 @@ static const char * const qdss_tracectl_b_groups[] = {
|
|||
};
|
||||
|
||||
static const char * const pwm0_groups[] = {
|
||||
"gpio42",
|
||||
"gpio42", "gpio46",
|
||||
};
|
||||
|
||||
static const char * const qdss_cti_trig_out_b0_groups[] = {
|
||||
|
|
@ -547,7 +547,7 @@ static const char * const qdss_cti_trig_out_b0_groups[] = {
|
|||
};
|
||||
|
||||
static const char * const pwm1_groups[] = {
|
||||
"gpio43",
|
||||
"gpio43", "gpio1",
|
||||
};
|
||||
|
||||
static const char * const qdss_cti_trig_in_b0_groups[] = {
|
||||
|
|
@ -555,7 +555,7 @@ static const char * const qdss_cti_trig_in_b0_groups[] = {
|
|||
};
|
||||
|
||||
static const char * const pwm2_groups[] = {
|
||||
"gpio44",
|
||||
"gpio12", "gpio44",
|
||||
};
|
||||
|
||||
static const char * const qdss_cti_trig_out_b1_groups[] = {
|
||||
|
|
@ -563,7 +563,7 @@ static const char * const qdss_cti_trig_out_b1_groups[] = {
|
|||
};
|
||||
|
||||
static const char * const pwm3_groups[] = {
|
||||
"gpio45",
|
||||
"gpio45", "gpio30", "gpio13",
|
||||
};
|
||||
|
||||
static const char * const qdss_cti_trig_in_b1_groups[] = {
|
||||
|
|
@ -677,7 +677,7 @@ static const struct pinfunction ipq5018_functions[] = {
|
|||
|
||||
static const struct msm_pingroup ipq5018_groups[] = {
|
||||
PINGROUP(0, atest_char, _, qdss_cti_trig_out_a0, wci_txd, wci_rxd, xfem, _, _, _),
|
||||
PINGROUP(1, atest_char, _, qdss_cti_trig_in_a0, wci_txd, wci_rxd, xfem, _, _, _),
|
||||
PINGROUP(1, atest_char, pwm1, qdss_cti_trig_in_a0, wci_txd, wci_rxd, xfem, _, _, _),
|
||||
PINGROUP(2, atest_char, _, qdss_cti_trig_out_a1, wci_txd, wci_rxd, xfem, _, _, _),
|
||||
PINGROUP(3, atest_char, _, qdss_cti_trig_in_a1, wci_txd, wci_rxd, xfem, _, _, _),
|
||||
PINGROUP(4, sdc1_data, qspi_data, blsp1_spi1, btss, dbg_out, qdss_traceclk_a, _, burn0, _),
|
||||
|
|
@ -688,8 +688,8 @@ static const struct msm_pingroup ipq5018_groups[] = {
|
|||
PINGROUP(9, sdc1_clk, qspi_clk, _, qdss_tracedata_a, _, _, _, _, _),
|
||||
PINGROUP(10, blsp0_spi, blsp1_uart0, led0, gcc_plltest, qdss_tracedata_a, _, _, _, _),
|
||||
PINGROUP(11, blsp0_spi, blsp1_uart0, _, gcc_tlmm, qdss_tracedata_a, _, _, _, _),
|
||||
PINGROUP(12, blsp0_spi, blsp0_i2c, blsp1_uart0, _, gcc_plltest, qdss_tracedata_a, _, _, _),
|
||||
PINGROUP(13, blsp0_spi, blsp0_i2c, blsp1_uart0, _, qdss_tracedata_a, _, _, _, _),
|
||||
PINGROUP(12, blsp0_spi, blsp0_i2c, blsp1_uart0, _, pwm2, qdss_tracedata_a, _, _, _),
|
||||
PINGROUP(13, blsp0_spi, blsp0_i2c, blsp1_uart0, pwm3, qdss_tracedata_a, _, _, _, _),
|
||||
PINGROUP(14, pcie0_clk, _, _, cri_trng0, qdss_tracedata_a, _, _, _, _),
|
||||
PINGROUP(15, _, _, cri_trng1, qdss_tracedata_a, _, _, _, _, _),
|
||||
PINGROUP(16, pcie0_wake, _, _, cri_trng, qdss_tracedata_a, _, _, _, _),
|
||||
|
|
@ -706,7 +706,7 @@ static const struct msm_pingroup ipq5018_groups[] = {
|
|||
PINGROUP(27, audio_txmclk, wsa_swrm, audio_txmclk, blsp2_spi, btss, _, qdss_tracedata_b, _, _),
|
||||
PINGROUP(28, audio_txbclk, wsa_swrm, blsp0_uart1, btss, qdss_tracedata_b, _, _, _, _),
|
||||
PINGROUP(29, audio_txfsync, _, blsp0_uart1, _, qdss_tracedata_b, _, _, _, _),
|
||||
PINGROUP(30, audio_txd, led2, led0, _, _, _, _, _, _),
|
||||
PINGROUP(30, audio_txd, led2, led0, pwm3, _, _, _, _, _),
|
||||
PINGROUP(31, blsp2_spi0, blsp1_uart1, _, qdss_tracedata_b, eud_gpio, _, _, _, _),
|
||||
PINGROUP(32, blsp2_spi0, blsp1_uart1, _, qdss_tracedata_b, eud_gpio, _, _, _, _),
|
||||
PINGROUP(33, blsp2_i2c0, blsp2_spi0, blsp1_uart1, _, qdss_tracedata_b, eud_gpio, _, _, _),
|
||||
|
|
@ -722,7 +722,7 @@ static const struct msm_pingroup ipq5018_groups[] = {
|
|||
PINGROUP(43, pwm1, qdss_cti_trig_in_b0, wci_txd, wci_rxd, xfem, _, _, _, _),
|
||||
PINGROUP(44, pwm2, qdss_cti_trig_out_b1, wci_txd, wci_rxd, xfem, _, _, _, _),
|
||||
PINGROUP(45, pwm3, qdss_cti_trig_in_b1, wci_txd, wci_rxd, xfem, _, _, _, _),
|
||||
PINGROUP(46, led0, _, _, _, _, _, _, _, _),
|
||||
PINGROUP(46, led0, pwm0, _, _, _, _, _, _, _),
|
||||
};
|
||||
|
||||
static const struct msm_pinctrl_soc_data ipq5018_pinctrl = {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
.intr_wakeup_present_bit = 6, \
|
||||
.intr_wakeup_enable_bit = 7, \
|
||||
.intr_target_bit = 8, \
|
||||
.intr_target_width = 4, \
|
||||
.intr_target_kpss_val = 3, \
|
||||
.intr_raw_status_bit = 4, \
|
||||
.intr_polarity_bit = 1, \
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
.intr_wakeup_present_bit = 6, \
|
||||
.intr_wakeup_enable_bit = 7, \
|
||||
.intr_target_bit = 8, \
|
||||
.intr_target_width = 4, \
|
||||
.intr_target_kpss_val = 3, \
|
||||
.intr_raw_status_bit = 4, \
|
||||
.intr_polarity_bit = 1, \
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
.intr_enable_bit = 0, \
|
||||
.intr_status_bit = 0, \
|
||||
.intr_target_bit = 5, \
|
||||
.intr_target_width = 4, \
|
||||
.intr_target_kpss_val = 3, \
|
||||
.intr_raw_status_bit = 4, \
|
||||
.intr_polarity_bit = 1, \
|
||||
|
|
|
|||
|
|
@ -734,29 +734,50 @@ static int pmic_gpio_get_direction(struct gpio_chip *chip, unsigned pin)
|
|||
(!pad->input_enabled && !pad->output_enabled))
|
||||
return -EINVAL;
|
||||
|
||||
/* Make sure the state is aligned on what pmic_gpio_get() returns */
|
||||
return pad->input_enabled ? GPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT;
|
||||
/*
|
||||
* An open-drain or open-source pad keeps its input buffer enabled while
|
||||
* driving, so the output buffer is what tells the direction.
|
||||
*/
|
||||
return pad->output_enabled ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
|
||||
}
|
||||
|
||||
static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
|
||||
{
|
||||
struct pmic_gpio_state *state = gpiochip_get_data(chip);
|
||||
unsigned long config;
|
||||
unsigned long configs[2];
|
||||
|
||||
config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1);
|
||||
configs[0] = pinconf_to_config_packed(PIN_CONFIG_OUTPUT_ENABLE, 0);
|
||||
configs[1] = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1);
|
||||
|
||||
return pmic_gpio_config_set(state->ctrl, pin, &config, 1);
|
||||
return pmic_gpio_config_set(state->ctrl, pin, configs,
|
||||
ARRAY_SIZE(configs));
|
||||
}
|
||||
|
||||
static int pmic_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned pin, int val)
|
||||
{
|
||||
struct pmic_gpio_state *state = gpiochip_get_data(chip);
|
||||
unsigned long config;
|
||||
struct pmic_gpio_pad *pad = state->ctrl->desc->pins[pin].drv_data;
|
||||
unsigned long configs[2];
|
||||
|
||||
config = pinconf_to_config_packed(PIN_CONFIG_LEVEL, val);
|
||||
/*
|
||||
* An open-drain or open-source pad only ever drives one rail, so the
|
||||
* line can still be sampled while the pad is an output. Keep the input
|
||||
* buffer enabled for those, so that pmic_gpio_get() reports what is on
|
||||
* the wire rather than the value last written, and disable it for a
|
||||
* CMOS pad, so that the pad ends up in DIGITAL_OUTPUT rather than
|
||||
* DIGITAL_INPUT_OUTPUT. Program it either way, as the buffer may have
|
||||
* been left in the opposite state by the bootloader or by an earlier
|
||||
* direction change with a different buffer type. gpiolib applies
|
||||
* PIN_CONFIG_DRIVE_OPEN_DRAIN before calling this, so buffer_type is
|
||||
* already up to date here.
|
||||
*/
|
||||
configs[0] = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE,
|
||||
pad->buffer_type != PMIC_GPIO_OUT_BUF_CMOS);
|
||||
configs[1] = pinconf_to_config_packed(PIN_CONFIG_LEVEL, val);
|
||||
|
||||
return pmic_gpio_config_set(state->ctrl, pin, &config, 1);
|
||||
return pmic_gpio_config_set(state->ctrl, pin, configs,
|
||||
ARRAY_SIZE(configs));
|
||||
}
|
||||
|
||||
static int pmic_gpio_get(struct gpio_chip *chip, unsigned pin)
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ static struct sunxi_desc_pin *init_pins_table(struct device *dev,
|
|||
* Find the total number of pins.
|
||||
* Also work out how much memory we need to store all the pin names.
|
||||
*/
|
||||
desc->npins = 0;
|
||||
for (i = 0; i < SUNXI_PINCTRL_MAX_BANKS; i++) {
|
||||
desc->npins += pins_per_bank[i];
|
||||
if (pins_per_bank[i] < 10) {
|
||||
|
|
|
|||
|
|
@ -496,15 +496,8 @@ static int pwrseq_qcom_wcn_probe(struct platform_device *pdev)
|
|||
return dev_err_probe(dev, PTR_ERR(ctx->bt_gpio),
|
||||
"Failed to get the Bluetooth enable GPIO\n");
|
||||
|
||||
/*
|
||||
* FIXME: This should actually be GPIOD_OUT_LOW, but doing so would
|
||||
* cause the WLAN power to be toggled, resulting in PCIe link down.
|
||||
* Since the PCIe controller driver is not handling link down currently,
|
||||
* the device becomes unusable. So we need to keep this workaround until
|
||||
* the link down handling is implemented in the controller driver.
|
||||
*/
|
||||
ctx->wlan_gpio = devm_gpiod_get_optional(dev, "wlan-enable",
|
||||
GPIOD_ASIS);
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(ctx->wlan_gpio))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->wlan_gpio),
|
||||
"Failed to get the WLAN enable GPIO\n");
|
||||
|
|
@ -515,13 +508,6 @@ static int pwrseq_qcom_wcn_probe(struct platform_device *pdev)
|
|||
return dev_err_probe(dev, PTR_ERR(ctx->xo_clk_gpio),
|
||||
"Failed to get the XO_CLK GPIO\n");
|
||||
|
||||
/*
|
||||
* Set direction to output but keep the current value in order to not
|
||||
* disable the WLAN module accidentally if it's already powered on.
|
||||
*/
|
||||
gpiod_direction_output(ctx->wlan_gpio,
|
||||
gpiod_get_value_cansleep(ctx->wlan_gpio));
|
||||
|
||||
ctx->clk = devm_clk_get_optional(dev, NULL);
|
||||
if (IS_ERR(ctx->clk))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx->clk),
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ static int ds2780_get_capacity(struct ds2780_device_info *dev_info,
|
|||
return ret;
|
||||
|
||||
*capacity = raw;
|
||||
return raw;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ds2780_get_status(struct ds2780_device_info *dev_info, int *status)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user