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:
Bartosz Golaszewski 2026-10-19 09:41:11 +02:00
commit 2450bb0473
206 changed files with 1998 additions and 801 deletions

View File

@ -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

View File

@ -2,7 +2,7 @@
VERSION = 7
PATCHLEVEL = 3
SUBLEVEL = 0
EXTRAVERSION = -rc7
EXTRAVERSION =
NAME = Baby Opossum Posse
# *DOCUMENTATION*

View File

@ -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 {

View File

@ -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

View File

@ -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>;
};
};

View File

@ -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;
};
};
};

View File

@ -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;
}

View File

@ -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",

View File

@ -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,

View File

@ -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);

View File

@ -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

View File

@ -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"

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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;
/*

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
}
/*

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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,

View File

@ -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;
}

View File

@ -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];
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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; \
})

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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)

View File

@ -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]);

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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";

View File

@ -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:

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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)) {

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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");

View File

@ -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 = {

View File

@ -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 */

View File

@ -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 */

View File

@ -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))

View File

@ -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)

View File

@ -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);

View File

@ -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 |

View File

@ -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);

View File

@ -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;

View File

@ -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
*/

View File

@ -1211,6 +1211,8 @@ static int ethoc_probe(struct platform_device *pdev)
goto free3;
}
netdev->netdev_ops = &ethoc_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 = &ethoc_netdev_ops;
netdev->watchdog_timeo = ETHOC_TIMEOUT;
netdev->features |= 0;
netdev->ethtool_ops = &ethoc_ethtool_ops;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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:

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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));

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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))

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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, \

View File

@ -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 = {

View File

@ -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, \

View File

@ -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, \

View File

@ -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, \

View File

@ -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)

View File

@ -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) {

View File

@ -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),

View File

@ -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