Merge tag 'ASB-2024-12-05_4.19-stable' of https://android.googlesource.com/kernel/common into android13-4.19-kona
https://source.android.com/docs/security/bulletin/2024-12-01 * tag 'ASB-2024-12-05_4.19-stable' of https://android.googlesource.com/kernel/common: (401 commits) Linux 4.19.324 9p: fix slab cache name creation for real net: usb: qmi_wwan: add Fibocom FG132 0x0112 composition fs: Fix uninitialized value issue in from_kuid and from_kgid powerpc/powernv: Free name on error in opal_event_init() sound: Make CONFIG_SND depend on INDIRECT_IOMEM instead of UML bpf: use kvzmalloc to allocate BPF verifier environment HID: multitouch: Add quirk for HONOR MagicBook Art 14 touchpad 9p: Avoid creating multiple slab caches with the same name ALSA: usb-audio: Add endianness annotations vsock/virtio: Initialization of the dangling pointer occurring in vsk->trans hv_sock: Initializing vsk->trans to NULL to prevent a dangling pointer ALSA: usb-audio: Add quirks for Dell WD19 dock ALSA: usb-audio: Support jack detection on Dell dock ALSA: usb-audio: Add custom mixer status quirks for RME CC devices ALSA: pcm: Return 0 when size < start_threshold in capture ocfs2: remove entry once instead of null-ptr-dereference in ocfs2_xa_remove() irqchip/gic-v3: Force propagation of the active state with a read-back USB: serial: option: add Quectel RG650V USB: serial: option: add Fibocom FG132 0x0112 composition ... Conflicts: drivers/usb/dwc3/core.c drivers/usb/dwc3/core.h net/qrtr/qrtr.c Change-Id: I328847813eb875d25c4aa35dcc7ba58ad09b53ae
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -114,7 +114,6 @@ GTAGS
|
|||||||
# id-utils files
|
# id-utils files
|
||||||
ID
|
ID
|
||||||
|
|
||||||
*.orig
|
|
||||||
*~
|
*~
|
||||||
\#*#
|
\#*#
|
||||||
|
|
||||||
|
|||||||
@@ -518,7 +518,7 @@ at module load time (for a module) with::
|
|||||||
[dbg_probe=1]
|
[dbg_probe=1]
|
||||||
|
|
||||||
The addresses are normal I2C addresses. The adapter is the string
|
The addresses are normal I2C addresses. The adapter is the string
|
||||||
name of the adapter, as shown in /sys/class/i2c-adapter/i2c-<n>/name.
|
name of the adapter, as shown in /sys/bus/i2c/devices/i2c-<n>/name.
|
||||||
It is *NOT* i2c-<n> itself. Also, the comparison is done ignoring
|
It is *NOT* i2c-<n> itself. Also, the comparison is done ignoring
|
||||||
spaces, so if the name is "This is an I2C chip" you can say
|
spaces, so if the name is "This is an I2C chip" you can say
|
||||||
adapter_name=ThisisanI2cchip. This is because it's hard to pass in
|
adapter_name=ThisisanI2cchip. This is because it's hard to pass in
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ stable kernels.
|
|||||||
| ARM | Cortex-A78 | #3324344 | ARM64_ERRATUM_3194386 |
|
| ARM | Cortex-A78 | #3324344 | ARM64_ERRATUM_3194386 |
|
||||||
| ARM | Cortex-A78C | #3324346,3324347| ARM64_ERRATUM_3194386 |
|
| ARM | Cortex-A78C | #3324346,3324347| ARM64_ERRATUM_3194386 |
|
||||||
| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 |
|
| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 |
|
||||||
|
| ARM | Cortex-A715 | #3456084 | ARM64_ERRATUM_3194386 |
|
||||||
| ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 |
|
| ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 |
|
||||||
| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
|
| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 |
|
||||||
| ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 |
|
| ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 |
|
||||||
@@ -78,6 +79,7 @@ stable kernels.
|
|||||||
| ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 |
|
| ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 |
|
||||||
| ARM | Neoverse-N1 | #3324349 | ARM64_ERRATUM_3194386 |
|
| ARM | Neoverse-N1 | #3324349 | ARM64_ERRATUM_3194386 |
|
||||||
| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 |
|
| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 |
|
||||||
|
| ARM | Neoverse-N3 | #3456111 | ARM64_ERRATUM_3194386 |
|
||||||
| ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 |
|
| ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 |
|
||||||
| ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 |
|
| ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 |
|
||||||
| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 |
|
| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 |
|
||||||
|
|||||||
@@ -235,6 +235,7 @@ certainly invest a bit more effort into libata core layer).
|
|||||||
|
|
||||||
CLOCK
|
CLOCK
|
||||||
devm_clk_get()
|
devm_clk_get()
|
||||||
|
devm_clk_get_optional()
|
||||||
devm_clk_put()
|
devm_clk_put()
|
||||||
devm_clk_hw_register()
|
devm_clk_hw_register()
|
||||||
devm_of_clk_add_hw_provider()
|
devm_of_clk_add_hw_provider()
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
VERSION = 4
|
VERSION = 4
|
||||||
PATCHLEVEL = 19
|
PATCHLEVEL = 19
|
||||||
SUBLEVEL = 322
|
SUBLEVEL = 324
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = "People's Front"
|
NAME = "People's Front"
|
||||||
|
|
||||||
|
|||||||
@@ -300,8 +300,8 @@
|
|||||||
&i2c2 {
|
&i2c2 {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
|
||||||
rt5616: rt5616@1b {
|
rt5616: audio-codec@1b {
|
||||||
compatible = "rt5616";
|
compatible = "realtek,rt5616";
|
||||||
reg = <0x1b>;
|
reg = <0x1b>;
|
||||||
clocks = <&cru SCLK_I2S_OUT>;
|
clocks = <&cru SCLK_I2S_OUT>;
|
||||||
clock-names = "mclk";
|
clock-names = "mclk";
|
||||||
|
|||||||
@@ -316,12 +316,13 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
acodec: acodec-ana@20030000 {
|
acodec: audio-codec@20030000 {
|
||||||
compatible = "rk3036-codec";
|
compatible = "rockchip,rk3036-codec";
|
||||||
reg = <0x20030000 0x4000>;
|
reg = <0x20030000 0x4000>;
|
||||||
rockchip,grf = <&grf>;
|
|
||||||
clock-names = "acodec_pclk";
|
clock-names = "acodec_pclk";
|
||||||
clocks = <&cru PCLK_ACODEC>;
|
clocks = <&cru PCLK_ACODEC>;
|
||||||
|
rockchip,grf = <&grf>;
|
||||||
|
#sound-dai-cells = <0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -331,7 +332,6 @@
|
|||||||
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
clocks = <&cru PCLK_HDMI>;
|
clocks = <&cru PCLK_HDMI>;
|
||||||
clock-names = "pclk";
|
clock-names = "pclk";
|
||||||
rockchip,grf = <&grf>;
|
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&hdmi_ctl>;
|
pinctrl-0 = <&hdmi_ctl>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
map = syscon_node_to_regmap(np);
|
map = syscon_node_to_regmap(np);
|
||||||
|
of_node_put(np);
|
||||||
if (IS_ERR(map)) {
|
if (IS_ERR(map)) {
|
||||||
pr_err("PLATSMP: No syscon regmap\n");
|
pr_err("PLATSMP: No syscon regmap\n");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -591,6 +591,7 @@ config ARM64_ERRATUM_3194386
|
|||||||
* ARM Cortex-A78C erratum 3324346
|
* ARM Cortex-A78C erratum 3324346
|
||||||
* ARM Cortex-A78C erratum 3324347
|
* ARM Cortex-A78C erratum 3324347
|
||||||
* ARM Cortex-A710 erratam 3324338
|
* ARM Cortex-A710 erratam 3324338
|
||||||
|
* ARM Cortex-A715 errartum 3456084
|
||||||
* ARM Cortex-A720 erratum 3456091
|
* ARM Cortex-A720 erratum 3456091
|
||||||
* ARM Cortex-A725 erratum 3456106
|
* ARM Cortex-A725 erratum 3456106
|
||||||
* ARM Cortex-X1 erratum 3324344
|
* ARM Cortex-X1 erratum 3324344
|
||||||
@@ -601,6 +602,7 @@ config ARM64_ERRATUM_3194386
|
|||||||
* ARM Cortex-X925 erratum 3324334
|
* ARM Cortex-X925 erratum 3324334
|
||||||
* ARM Neoverse-N1 erratum 3324349
|
* ARM Neoverse-N1 erratum 3324349
|
||||||
* ARM Neoverse N2 erratum 3324339
|
* ARM Neoverse N2 erratum 3324339
|
||||||
|
* ARM Neoverse-N3 erratum 3456111
|
||||||
* ARM Neoverse-V1 erratum 3324341
|
* ARM Neoverse-V1 erratum 3324341
|
||||||
* ARM Neoverse V2 erratum 3324336
|
* ARM Neoverse V2 erratum 3324336
|
||||||
* ARM Neoverse-V3 erratum 3312417
|
* ARM Neoverse-V3 erratum 3312417
|
||||||
|
|||||||
@@ -147,6 +147,22 @@
|
|||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&gpio3 {
|
||||||
|
/*
|
||||||
|
* The Qseven BIOS_DISABLE signal on the RK3399-Q7 keeps the on-module
|
||||||
|
* eMMC and SPI flash powered-down initially (in fact it keeps the
|
||||||
|
* reset signal asserted). BIOS_DISABLE_OVERRIDE pin allows to override
|
||||||
|
* that signal so that eMMC and SPI can be used regardless of the state
|
||||||
|
* of the signal.
|
||||||
|
*/
|
||||||
|
bios-disable-override-hog {
|
||||||
|
gpios = <RK_PD5 GPIO_ACTIVE_LOW>;
|
||||||
|
gpio-hog;
|
||||||
|
line-name = "bios_disable_override";
|
||||||
|
output-high;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
&gmac {
|
&gmac {
|
||||||
assigned-clocks = <&cru SCLK_RMII_SRC>;
|
assigned-clocks = <&cru SCLK_RMII_SRC>;
|
||||||
assigned-clock-parents = <&clkin_gmac>;
|
assigned-clock-parents = <&clkin_gmac>;
|
||||||
@@ -433,9 +449,14 @@
|
|||||||
|
|
||||||
&pinctrl {
|
&pinctrl {
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&q7_thermal_pin>;
|
pinctrl-0 = <&q7_thermal_pin &bios_disable_override_hog_pin>;
|
||||||
|
|
||||||
gpios {
|
gpios {
|
||||||
|
bios_disable_override_hog_pin: bios-disable-override-hog-pin {
|
||||||
|
rockchip,pins =
|
||||||
|
<3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_down>;
|
||||||
|
};
|
||||||
|
|
||||||
q7_thermal_pin: q7-thermal-pin {
|
q7_thermal_pin: q7-thermal-pin {
|
||||||
rockchip,pins =
|
rockchip,pins =
|
||||||
<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
|
<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
|
||||||
|
|||||||
@@ -123,7 +123,7 @@
|
|||||||
status = "okay";
|
status = "okay";
|
||||||
|
|
||||||
rt5651: rt5651@1a {
|
rt5651: rt5651@1a {
|
||||||
compatible = "rockchip,rt5651";
|
compatible = "realtek,rt5651";
|
||||||
reg = <0x1a>;
|
reg = <0x1a>;
|
||||||
clocks = <&cru SCLK_I2S_8CH_OUT>;
|
clocks = <&cru SCLK_I2S_8CH_OUT>;
|
||||||
clock-names = "mclk";
|
clock-names = "mclk";
|
||||||
|
|||||||
@@ -89,6 +89,7 @@
|
|||||||
#define ARM_CPU_PART_CORTEX_A78 0xD41
|
#define ARM_CPU_PART_CORTEX_A78 0xD41
|
||||||
#define ARM_CPU_PART_CORTEX_X1 0xD44
|
#define ARM_CPU_PART_CORTEX_X1 0xD44
|
||||||
#define ARM_CPU_PART_CORTEX_A710 0xD47
|
#define ARM_CPU_PART_CORTEX_A710 0xD47
|
||||||
|
#define ARM_CPU_PART_CORTEX_A715 0xD4D
|
||||||
#define ARM_CPU_PART_CORTEX_X2 0xD48
|
#define ARM_CPU_PART_CORTEX_X2 0xD48
|
||||||
#define ARM_CPU_PART_NEOVERSE_N2 0xD49
|
#define ARM_CPU_PART_NEOVERSE_N2 0xD49
|
||||||
#define ARM_CPU_PART_CORTEX_A78C 0xD4B
|
#define ARM_CPU_PART_CORTEX_A78C 0xD4B
|
||||||
@@ -108,6 +109,7 @@
|
|||||||
#define ARM_CPU_PART_NEOVERSE_V3 0xD84
|
#define ARM_CPU_PART_NEOVERSE_V3 0xD84
|
||||||
#define ARM_CPU_PART_CORTEX_X925 0xD85
|
#define ARM_CPU_PART_CORTEX_X925 0xD85
|
||||||
#define ARM_CPU_PART_CORTEX_A725 0xD87
|
#define ARM_CPU_PART_CORTEX_A725 0xD87
|
||||||
|
#define ARM_CPU_PART_NEOVERSE_N3 0xD8E
|
||||||
|
|
||||||
#define APM_CPU_PART_POTENZA 0x000
|
#define APM_CPU_PART_POTENZA 0x000
|
||||||
|
|
||||||
@@ -142,6 +144,7 @@
|
|||||||
#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
|
#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
|
||||||
#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
|
#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
|
||||||
#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
|
#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
|
||||||
|
#define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715)
|
||||||
#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
|
#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
|
||||||
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
|
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
|
||||||
#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
|
#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
|
||||||
@@ -161,6 +164,7 @@
|
|||||||
#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
|
#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
|
||||||
#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
|
#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
|
||||||
#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
|
#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
|
||||||
|
#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)
|
||||||
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
|
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
|
||||||
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
|
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
|
||||||
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
|
#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
|
||||||
|
|||||||
@@ -13,21 +13,19 @@
|
|||||||
#include <asm/insn.h>
|
#include <asm/insn.h>
|
||||||
#include <asm/probes.h>
|
#include <asm/probes.h>
|
||||||
|
|
||||||
#define MAX_UINSN_BYTES AARCH64_INSN_SIZE
|
#define UPROBE_SWBP_INSN cpu_to_le32(BRK64_OPCODE_UPROBES)
|
||||||
|
|
||||||
#define UPROBE_SWBP_INSN BRK64_OPCODE_UPROBES
|
|
||||||
#define UPROBE_SWBP_INSN_SIZE AARCH64_INSN_SIZE
|
#define UPROBE_SWBP_INSN_SIZE AARCH64_INSN_SIZE
|
||||||
#define UPROBE_XOL_SLOT_BYTES MAX_UINSN_BYTES
|
#define UPROBE_XOL_SLOT_BYTES AARCH64_INSN_SIZE
|
||||||
|
|
||||||
typedef u32 uprobe_opcode_t;
|
typedef __le32 uprobe_opcode_t;
|
||||||
|
|
||||||
struct arch_uprobe_task {
|
struct arch_uprobe_task {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct arch_uprobe {
|
struct arch_uprobe {
|
||||||
union {
|
union {
|
||||||
u8 insn[MAX_UINSN_BYTES];
|
__le32 insn;
|
||||||
u8 ixol[MAX_UINSN_BYTES];
|
__le32 ixol;
|
||||||
};
|
};
|
||||||
struct arch_probe_insn api;
|
struct arch_probe_insn api;
|
||||||
bool simulate;
|
bool simulate;
|
||||||
|
|||||||
@@ -763,6 +763,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
|
|||||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
|
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
|
||||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
|
MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
|
||||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
|
MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
|
||||||
|
MIDR_ALL_VERSIONS(MIDR_CORTEX_A715),
|
||||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
|
MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
|
||||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_A725),
|
MIDR_ALL_VERSIONS(MIDR_CORTEX_A725),
|
||||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
|
MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
|
||||||
@@ -773,6 +774,7 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
|
|||||||
MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
|
MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
|
||||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
|
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
|
||||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
|
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
|
||||||
|
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3),
|
||||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
|
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
|
||||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
|
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
|
||||||
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
|
MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
|
||||||
|
|||||||
@@ -104,10 +104,6 @@ arm_probe_decode_insn(probe_opcode_t insn, struct arch_probe_insn *api)
|
|||||||
aarch64_insn_is_blr(insn) ||
|
aarch64_insn_is_blr(insn) ||
|
||||||
aarch64_insn_is_ret(insn)) {
|
aarch64_insn_is_ret(insn)) {
|
||||||
api->handler = simulate_br_blr_ret;
|
api->handler = simulate_br_blr_ret;
|
||||||
} else if (aarch64_insn_is_ldr_lit(insn)) {
|
|
||||||
api->handler = simulate_ldr_literal;
|
|
||||||
} else if (aarch64_insn_is_ldrsw_lit(insn)) {
|
|
||||||
api->handler = simulate_ldrsw_literal;
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Instruction cannot be stepped out-of-line and we don't
|
* Instruction cannot be stepped out-of-line and we don't
|
||||||
@@ -145,6 +141,17 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi)
|
|||||||
probe_opcode_t insn = le32_to_cpu(*addr);
|
probe_opcode_t insn = le32_to_cpu(*addr);
|
||||||
probe_opcode_t *scan_end = NULL;
|
probe_opcode_t *scan_end = NULL;
|
||||||
unsigned long size = 0, offset = 0;
|
unsigned long size = 0, offset = 0;
|
||||||
|
struct arch_probe_insn *api = &asi->api;
|
||||||
|
|
||||||
|
if (aarch64_insn_is_ldr_lit(insn)) {
|
||||||
|
api->handler = simulate_ldr_literal;
|
||||||
|
decoded = INSN_GOOD_NO_SLOT;
|
||||||
|
} else if (aarch64_insn_is_ldrsw_lit(insn)) {
|
||||||
|
api->handler = simulate_ldrsw_literal;
|
||||||
|
decoded = INSN_GOOD_NO_SLOT;
|
||||||
|
} else {
|
||||||
|
decoded = arm_probe_decode_insn(insn, &asi->api);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there's a symbol defined in front of and near enough to
|
* If there's a symbol defined in front of and near enough to
|
||||||
@@ -162,7 +169,6 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi)
|
|||||||
else
|
else
|
||||||
scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
|
scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
|
||||||
}
|
}
|
||||||
decoded = arm_probe_decode_insn(insn, &asi->api);
|
|
||||||
|
|
||||||
if (decoded != INSN_REJECTED && scan_end)
|
if (decoded != INSN_REJECTED && scan_end)
|
||||||
if (is_probed_address_atomic(addr - 1, scan_end))
|
if (is_probed_address_atomic(addr - 1, scan_end))
|
||||||
|
|||||||
@@ -178,17 +178,15 @@ simulate_tbz_tbnz(u32 opcode, long addr, struct pt_regs *regs)
|
|||||||
void __kprobes
|
void __kprobes
|
||||||
simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs)
|
simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
u64 *load_addr;
|
unsigned long load_addr;
|
||||||
int xn = opcode & 0x1f;
|
int xn = opcode & 0x1f;
|
||||||
int disp;
|
|
||||||
|
|
||||||
disp = ldr_displacement(opcode);
|
load_addr = addr + ldr_displacement(opcode);
|
||||||
load_addr = (u64 *) (addr + disp);
|
|
||||||
|
|
||||||
if (opcode & (1 << 30)) /* x0-x30 */
|
if (opcode & (1 << 30)) /* x0-x30 */
|
||||||
set_x_reg(regs, xn, *load_addr);
|
set_x_reg(regs, xn, READ_ONCE(*(u64 *)load_addr));
|
||||||
else /* w0-w30 */
|
else /* w0-w30 */
|
||||||
set_w_reg(regs, xn, *load_addr);
|
set_w_reg(regs, xn, READ_ONCE(*(u32 *)load_addr));
|
||||||
|
|
||||||
instruction_pointer_set(regs, instruction_pointer(regs) + 4);
|
instruction_pointer_set(regs, instruction_pointer(regs) + 4);
|
||||||
}
|
}
|
||||||
@@ -196,14 +194,12 @@ simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs)
|
|||||||
void __kprobes
|
void __kprobes
|
||||||
simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs)
|
simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
s32 *load_addr;
|
unsigned long load_addr;
|
||||||
int xn = opcode & 0x1f;
|
int xn = opcode & 0x1f;
|
||||||
int disp;
|
|
||||||
|
|
||||||
disp = ldr_displacement(opcode);
|
load_addr = addr + ldr_displacement(opcode);
|
||||||
load_addr = (s32 *) (addr + disp);
|
|
||||||
|
|
||||||
set_x_reg(regs, xn, *load_addr);
|
set_x_reg(regs, xn, READ_ONCE(*(s32 *)load_addr));
|
||||||
|
|
||||||
instruction_pointer_set(regs, instruction_pointer(regs) + 4);
|
instruction_pointer_set(regs, instruction_pointer(regs) + 4);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
|
|||||||
else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE))
|
else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
insn = *(probe_opcode_t *)(&auprobe->insn[0]);
|
insn = le32_to_cpu(auprobe->insn);
|
||||||
|
|
||||||
switch (arm_probe_decode_insn(insn, &auprobe->api)) {
|
switch (arm_probe_decode_insn(insn, &auprobe->api)) {
|
||||||
case INSN_REJECTED:
|
case INSN_REJECTED:
|
||||||
@@ -111,7 +111,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
|
|||||||
if (!auprobe->simulate)
|
if (!auprobe->simulate)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
insn = *(probe_opcode_t *)(&auprobe->insn[0]);
|
insn = le32_to_cpu(auprobe->insn);
|
||||||
addr = instruction_pointer(regs);
|
addr = instruction_pointer(regs);
|
||||||
|
|
||||||
if (auprobe->api.handler)
|
if (auprobe->api.handler)
|
||||||
|
|||||||
@@ -289,11 +289,6 @@ asmlinkage void __init mmu_init(void)
|
|||||||
{
|
{
|
||||||
unsigned int kstart, ksize;
|
unsigned int kstart, ksize;
|
||||||
|
|
||||||
if (!memblock.reserved.cnt) {
|
|
||||||
pr_emerg("Error memory count\n");
|
|
||||||
machine_restart(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((u32) memblock.memory.regions[0].size < 0x400000) {
|
if ((u32) memblock.memory.regions[0].size < 0x400000) {
|
||||||
pr_emerg("Memory must be greater than 4MB\n");
|
pr_emerg("Memory must be greater than 4MB\n");
|
||||||
machine_restart(NULL);
|
machine_restart(NULL);
|
||||||
|
|||||||
@@ -1089,8 +1089,7 @@ ENTRY_CFI(intr_save) /* for os_hpmc */
|
|||||||
STREG %r16, PT_ISR(%r29)
|
STREG %r16, PT_ISR(%r29)
|
||||||
STREG %r17, PT_IOR(%r29)
|
STREG %r17, PT_IOR(%r29)
|
||||||
|
|
||||||
#if 0 && defined(CONFIG_64BIT)
|
#if defined(CONFIG_64BIT)
|
||||||
/* Revisit when we have 64-bit code above 4Gb */
|
|
||||||
b,n intr_save2
|
b,n intr_save2
|
||||||
|
|
||||||
skip_save_ior:
|
skip_save_ior:
|
||||||
@@ -1098,8 +1097,7 @@ skip_save_ior:
|
|||||||
* need to adjust iasq/iaoq here in the same way we adjusted isr/ior
|
* need to adjust iasq/iaoq here in the same way we adjusted isr/ior
|
||||||
* above.
|
* above.
|
||||||
*/
|
*/
|
||||||
extrd,u,* %r8,PSW_W_BIT,1,%r1
|
bb,COND(>=),n %r8,PSW_W_BIT,intr_save2
|
||||||
cmpib,COND(=),n 1,%r1,intr_save2
|
|
||||||
LDREG PT_IASQ0(%r29), %r16
|
LDREG PT_IASQ0(%r29), %r16
|
||||||
LDREG PT_IAOQ0(%r29), %r17
|
LDREG PT_IAOQ0(%r29), %r17
|
||||||
/* adjust iasq/iaoq */
|
/* adjust iasq/iaoq */
|
||||||
|
|||||||
@@ -217,10 +217,10 @@ linux_gateway_entry:
|
|||||||
|
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
ldil L%sys_call_table, %r1
|
ldil L%sys_call_table, %r1
|
||||||
or,= %r2,%r2,%r2
|
or,ev %r2,%r2,%r2
|
||||||
addil L%(sys_call_table64-sys_call_table), %r1
|
ldil L%sys_call_table64, %r1
|
||||||
ldo R%sys_call_table(%r1), %r19
|
ldo R%sys_call_table(%r1), %r19
|
||||||
or,= %r2,%r2,%r2
|
or,ev %r2,%r2,%r2
|
||||||
ldo R%sys_call_table64(%r1), %r19
|
ldo R%sys_call_table64(%r1), %r19
|
||||||
#else
|
#else
|
||||||
load32 sys_call_table, %r19
|
load32 sys_call_table, %r19
|
||||||
@@ -355,10 +355,10 @@ tracesys_next:
|
|||||||
extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */
|
extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */
|
||||||
|
|
||||||
ldil L%sys_call_table, %r1
|
ldil L%sys_call_table, %r1
|
||||||
or,= %r2,%r2,%r2
|
or,ev %r2,%r2,%r2
|
||||||
addil L%(sys_call_table64-sys_call_table), %r1
|
ldil L%sys_call_table64, %r1
|
||||||
ldo R%sys_call_table(%r1), %r19
|
ldo R%sys_call_table(%r1), %r19
|
||||||
or,= %r2,%r2,%r2
|
or,ev %r2,%r2,%r2
|
||||||
ldo R%sys_call_table64(%r1), %r19
|
ldo R%sys_call_table64(%r1), %r19
|
||||||
#else
|
#else
|
||||||
load32 sys_call_table, %r19
|
load32 sys_call_table, %r19
|
||||||
@@ -930,6 +930,8 @@ ENTRY(sys_call_table)
|
|||||||
END(sys_call_table)
|
END(sys_call_table)
|
||||||
|
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
|
#undef __SYSCALL_WITH_COMPAT
|
||||||
|
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
|
||||||
.align 8
|
.align 8
|
||||||
ENTRY(sys_call_table64)
|
ENTRY(sys_call_table64)
|
||||||
#define SYSCALL_TABLE_64BIT
|
#define SYSCALL_TABLE_64BIT
|
||||||
|
|||||||
@@ -289,6 +289,7 @@ int __init opal_event_init(void)
|
|||||||
name, NULL);
|
name, NULL);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
pr_warn("Error %d requesting OPAL irq %d\n", rc, (int)r->start);
|
pr_warn("Error %d requesting OPAL irq %d\n", rc, (int)r->start);
|
||||||
|
kfree(name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,11 @@ config GENERIC_CSUM
|
|||||||
config GENERIC_HWEIGHT
|
config GENERIC_HWEIGHT
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
|
config ILLEGAL_POINTER_VALUE
|
||||||
|
hex
|
||||||
|
default 0 if 32BIT
|
||||||
|
default 0xdead000000000000 if 64BIT
|
||||||
|
|
||||||
config PGTABLE_LEVELS
|
config PGTABLE_LEVELS
|
||||||
int
|
int
|
||||||
default 3 if 64BIT
|
default 3 if 64BIT
|
||||||
|
|||||||
@@ -53,8 +53,10 @@ static inline int test_facility(unsigned long nr)
|
|||||||
unsigned long facilities_als[] = { FACILITIES_ALS };
|
unsigned long facilities_als[] = { FACILITIES_ALS };
|
||||||
|
|
||||||
if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) {
|
if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) {
|
||||||
if (__test_facility(nr, &facilities_als))
|
if (__test_facility(nr, &facilities_als)) {
|
||||||
return 1;
|
if (!__is_defined(__DECOMPRESSOR))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return __test_facility(nr, &S390_lowcore.stfle_fac_list);
|
return __test_facility(nr, &S390_lowcore.stfle_fac_list);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1360,7 +1360,7 @@ static int aux_output_begin(struct perf_output_handle *handle,
|
|||||||
unsigned long head, base, offset;
|
unsigned long head, base, offset;
|
||||||
struct hws_trailer_entry *te;
|
struct hws_trailer_entry *te;
|
||||||
|
|
||||||
if (WARN_ON_ONCE(handle->head & ~PAGE_MASK))
|
if (handle->head & ~PAGE_MASK)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
aux->head = handle->head >> PAGE_SHIFT;
|
aux->head = handle->head >> PAGE_SHIFT;
|
||||||
@@ -1528,7 +1528,7 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw)
|
|||||||
unsigned long num_sdb;
|
unsigned long num_sdb;
|
||||||
|
|
||||||
aux = perf_get_aux(handle);
|
aux = perf_get_aux(handle);
|
||||||
if (WARN_ON_ONCE(!aux))
|
if (!aux)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Inform user space new data arrived */
|
/* Inform user space new data arrived */
|
||||||
@@ -1547,7 +1547,7 @@ static void hw_collect_aux(struct cpu_hw_sf *cpuhw)
|
|||||||
debug_sprintf_event(sfdbg, 1, "AUX buffer used up\n");
|
debug_sprintf_event(sfdbg, 1, "AUX buffer used up\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (WARN_ON_ONCE(!aux))
|
if (!aux)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Update head and alert_mark to new position */
|
/* Update head and alert_mark to new position */
|
||||||
@@ -1746,12 +1746,8 @@ static void cpumsf_pmu_start(struct perf_event *event, int flags)
|
|||||||
{
|
{
|
||||||
struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf);
|
struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf);
|
||||||
|
|
||||||
if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
|
if (!(event->hw.state & PERF_HES_STOPPED))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (flags & PERF_EF_RELOAD)
|
|
||||||
WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
|
|
||||||
|
|
||||||
perf_pmu_disable(event->pmu);
|
perf_pmu_disable(event->pmu);
|
||||||
event->hw.state = 0;
|
event->hw.state = 0;
|
||||||
cpuhw->lsctl.cs = 1;
|
cpuhw->lsctl.cs = 1;
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ static int __diag_page_ref_service(struct kvm_vcpu *vcpu)
|
|||||||
vcpu->stat.diagnose_258++;
|
vcpu->stat.diagnose_258++;
|
||||||
if (vcpu->run->s.regs.gprs[rx] & 7)
|
if (vcpu->run->s.regs.gprs[rx] & 7)
|
||||||
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
|
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
|
||||||
rc = read_guest(vcpu, vcpu->run->s.regs.gprs[rx], rx, &parm, sizeof(parm));
|
rc = read_guest_real(vcpu, vcpu->run->s.regs.gprs[rx], &parm, sizeof(parm));
|
||||||
if (rc)
|
if (rc)
|
||||||
return kvm_s390_inject_prog_cond(vcpu, rc);
|
return kvm_s390_inject_prog_cond(vcpu, rc);
|
||||||
if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258)
|
if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258)
|
||||||
|
|||||||
@@ -794,46 +794,102 @@ static int low_address_protection_enabled(struct kvm_vcpu *vcpu,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
|
/**
|
||||||
unsigned long *pages, unsigned long nr_pages,
|
* guest_range_to_gpas() - Calculate guest physical addresses of page fragments
|
||||||
const union asce asce, enum gacc_mode mode)
|
* covering a logical range
|
||||||
|
* @vcpu: virtual cpu
|
||||||
|
* @ga: guest address, start of range
|
||||||
|
* @ar: access register
|
||||||
|
* @gpas: output argument, may be NULL
|
||||||
|
* @len: length of range in bytes
|
||||||
|
* @asce: address-space-control element to use for translation
|
||||||
|
* @mode: access mode
|
||||||
|
*
|
||||||
|
* Translate a logical range to a series of guest absolute addresses,
|
||||||
|
* such that the concatenation of page fragments starting at each gpa make up
|
||||||
|
* the whole range.
|
||||||
|
* The translation is performed as if done by the cpu for the given @asce, @ar,
|
||||||
|
* @mode and state of the @vcpu.
|
||||||
|
* If the translation causes an exception, its program interruption code is
|
||||||
|
* returned and the &struct kvm_s390_pgm_info pgm member of @vcpu is modified
|
||||||
|
* such that a subsequent call to kvm_s390_inject_prog_vcpu() will inject
|
||||||
|
* a correct exception into the guest.
|
||||||
|
* The resulting gpas are stored into @gpas, unless it is NULL.
|
||||||
|
*
|
||||||
|
* Note: All fragments except the first one start at the beginning of a page.
|
||||||
|
* When deriving the boundaries of a fragment from a gpa, all but the last
|
||||||
|
* fragment end at the end of the page.
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* * 0 - success
|
||||||
|
* * <0 - translation could not be performed, for example if guest
|
||||||
|
* memory could not be accessed
|
||||||
|
* * >0 - an access exception occurred. In this case the returned value
|
||||||
|
* is the program interruption code and the contents of pgm may
|
||||||
|
* be used to inject an exception into the guest.
|
||||||
|
*/
|
||||||
|
static int guest_range_to_gpas(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
|
||||||
|
unsigned long *gpas, unsigned long len,
|
||||||
|
const union asce asce, enum gacc_mode mode)
|
||||||
{
|
{
|
||||||
psw_t *psw = &vcpu->arch.sie_block->gpsw;
|
psw_t *psw = &vcpu->arch.sie_block->gpsw;
|
||||||
|
unsigned int offset = offset_in_page(ga);
|
||||||
|
unsigned int fragment_len;
|
||||||
int lap_enabled, rc = 0;
|
int lap_enabled, rc = 0;
|
||||||
enum prot_type prot;
|
enum prot_type prot;
|
||||||
|
unsigned long gpa;
|
||||||
|
|
||||||
lap_enabled = low_address_protection_enabled(vcpu, asce);
|
lap_enabled = low_address_protection_enabled(vcpu, asce);
|
||||||
while (nr_pages) {
|
while (min(PAGE_SIZE - offset, len) > 0) {
|
||||||
|
fragment_len = min(PAGE_SIZE - offset, len);
|
||||||
ga = kvm_s390_logical_to_effective(vcpu, ga);
|
ga = kvm_s390_logical_to_effective(vcpu, ga);
|
||||||
if (mode == GACC_STORE && lap_enabled && is_low_address(ga))
|
if (mode == GACC_STORE && lap_enabled && is_low_address(ga))
|
||||||
return trans_exc(vcpu, PGM_PROTECTION, ga, ar, mode,
|
return trans_exc(vcpu, PGM_PROTECTION, ga, ar, mode,
|
||||||
PROT_TYPE_LA);
|
PROT_TYPE_LA);
|
||||||
ga &= PAGE_MASK;
|
|
||||||
if (psw_bits(*psw).dat) {
|
if (psw_bits(*psw).dat) {
|
||||||
rc = guest_translate(vcpu, ga, pages, asce, mode, &prot);
|
rc = guest_translate(vcpu, ga, &gpa, asce, mode, &prot);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
} else {
|
} else {
|
||||||
*pages = kvm_s390_real_to_abs(vcpu, ga);
|
gpa = kvm_s390_real_to_abs(vcpu, ga);
|
||||||
if (kvm_is_error_gpa(vcpu->kvm, *pages))
|
if (kvm_is_error_gpa(vcpu->kvm, gpa))
|
||||||
rc = PGM_ADDRESSING;
|
rc = PGM_ADDRESSING;
|
||||||
}
|
}
|
||||||
if (rc)
|
if (rc)
|
||||||
return trans_exc(vcpu, rc, ga, ar, mode, prot);
|
return trans_exc(vcpu, rc, ga, ar, mode, prot);
|
||||||
ga += PAGE_SIZE;
|
if (gpas)
|
||||||
pages++;
|
*gpas++ = gpa;
|
||||||
nr_pages--;
|
offset = 0;
|
||||||
|
ga += fragment_len;
|
||||||
|
len -= fragment_len;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int access_guest_page(struct kvm *kvm, enum gacc_mode mode, gpa_t gpa,
|
||||||
|
void *data, unsigned int len)
|
||||||
|
{
|
||||||
|
const unsigned int offset = offset_in_page(gpa);
|
||||||
|
const gfn_t gfn = gpa_to_gfn(gpa);
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!gfn_to_memslot(kvm, gfn))
|
||||||
|
return PGM_ADDRESSING;
|
||||||
|
if (mode == GACC_STORE)
|
||||||
|
rc = kvm_write_guest_page(kvm, gfn, data, offset, len);
|
||||||
|
else
|
||||||
|
rc = kvm_read_guest_page(kvm, gfn, data, offset, len);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
|
int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
|
||||||
unsigned long len, enum gacc_mode mode)
|
unsigned long len, enum gacc_mode mode)
|
||||||
{
|
{
|
||||||
psw_t *psw = &vcpu->arch.sie_block->gpsw;
|
psw_t *psw = &vcpu->arch.sie_block->gpsw;
|
||||||
unsigned long _len, nr_pages, gpa, idx;
|
unsigned long nr_pages, idx;
|
||||||
unsigned long pages_array[2];
|
unsigned long gpa_array[2];
|
||||||
unsigned long *pages;
|
unsigned int fragment_len;
|
||||||
|
unsigned long *gpas;
|
||||||
int need_ipte_lock;
|
int need_ipte_lock;
|
||||||
union asce asce;
|
union asce asce;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -845,50 +901,45 @@ int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data,
|
|||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1;
|
nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1;
|
||||||
pages = pages_array;
|
gpas = gpa_array;
|
||||||
if (nr_pages > ARRAY_SIZE(pages_array))
|
if (nr_pages > ARRAY_SIZE(gpa_array))
|
||||||
pages = vmalloc(array_size(nr_pages, sizeof(unsigned long)));
|
gpas = vmalloc(array_size(nr_pages, sizeof(unsigned long)));
|
||||||
if (!pages)
|
if (!gpas)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
need_ipte_lock = psw_bits(*psw).dat && !asce.r;
|
need_ipte_lock = psw_bits(*psw).dat && !asce.r;
|
||||||
if (need_ipte_lock)
|
if (need_ipte_lock)
|
||||||
ipte_lock(vcpu);
|
ipte_lock(vcpu);
|
||||||
rc = guest_page_range(vcpu, ga, ar, pages, nr_pages, asce, mode);
|
rc = guest_range_to_gpas(vcpu, ga, ar, gpas, len, asce, mode);
|
||||||
for (idx = 0; idx < nr_pages && !rc; idx++) {
|
for (idx = 0; idx < nr_pages && !rc; idx++) {
|
||||||
gpa = *(pages + idx) + (ga & ~PAGE_MASK);
|
fragment_len = min(PAGE_SIZE - offset_in_page(gpas[idx]), len);
|
||||||
_len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len);
|
rc = access_guest_page(vcpu->kvm, mode, gpas[idx], data, fragment_len);
|
||||||
if (mode == GACC_STORE)
|
len -= fragment_len;
|
||||||
rc = kvm_write_guest(vcpu->kvm, gpa, data, _len);
|
data += fragment_len;
|
||||||
else
|
|
||||||
rc = kvm_read_guest(vcpu->kvm, gpa, data, _len);
|
|
||||||
len -= _len;
|
|
||||||
ga += _len;
|
|
||||||
data += _len;
|
|
||||||
}
|
}
|
||||||
if (need_ipte_lock)
|
if (need_ipte_lock)
|
||||||
ipte_unlock(vcpu);
|
ipte_unlock(vcpu);
|
||||||
if (nr_pages > ARRAY_SIZE(pages_array))
|
if (nr_pages > ARRAY_SIZE(gpa_array))
|
||||||
vfree(pages);
|
vfree(gpas);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
|
int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
|
||||||
void *data, unsigned long len, enum gacc_mode mode)
|
void *data, unsigned long len, enum gacc_mode mode)
|
||||||
{
|
{
|
||||||
unsigned long _len, gpa;
|
unsigned int fragment_len;
|
||||||
|
unsigned long gpa;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
while (len && !rc) {
|
while (len && !rc) {
|
||||||
gpa = kvm_s390_real_to_abs(vcpu, gra);
|
gpa = kvm_s390_real_to_abs(vcpu, gra);
|
||||||
_len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len);
|
fragment_len = min(PAGE_SIZE - offset_in_page(gpa), len);
|
||||||
if (mode)
|
rc = access_guest_page(vcpu->kvm, mode, gpa, data, fragment_len);
|
||||||
rc = write_guest_abs(vcpu, gpa, data, _len);
|
len -= fragment_len;
|
||||||
else
|
gra += fragment_len;
|
||||||
rc = read_guest_abs(vcpu, gpa, data, _len);
|
data += fragment_len;
|
||||||
len -= _len;
|
|
||||||
gra += _len;
|
|
||||||
data += _len;
|
|
||||||
}
|
}
|
||||||
|
if (rc > 0)
|
||||||
|
vcpu->arch.pgm.code = rc;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -904,8 +955,6 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
|
|||||||
int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
|
int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
|
||||||
unsigned long *gpa, enum gacc_mode mode)
|
unsigned long *gpa, enum gacc_mode mode)
|
||||||
{
|
{
|
||||||
psw_t *psw = &vcpu->arch.sie_block->gpsw;
|
|
||||||
enum prot_type prot;
|
|
||||||
union asce asce;
|
union asce asce;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -913,23 +962,7 @@ int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
|
|||||||
rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode);
|
rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
if (is_low_address(gva) && low_address_protection_enabled(vcpu, asce)) {
|
return guest_range_to_gpas(vcpu, gva, ar, gpa, 1, asce, mode);
|
||||||
if (mode == GACC_STORE)
|
|
||||||
return trans_exc(vcpu, PGM_PROTECTION, gva, 0,
|
|
||||||
mode, PROT_TYPE_LA);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (psw_bits(*psw).dat && !asce.r) { /* Use DAT? */
|
|
||||||
rc = guest_translate(vcpu, gva, gpa, asce, mode, &prot);
|
|
||||||
if (rc > 0)
|
|
||||||
return trans_exc(vcpu, rc, gva, 0, mode, prot);
|
|
||||||
} else {
|
|
||||||
*gpa = kvm_s390_real_to_abs(vcpu, gva);
|
|
||||||
if (kvm_is_error_gpa(vcpu->kvm, *gpa))
|
|
||||||
return trans_exc(vcpu, rc, gva, PGM_ADDRESSING, mode, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -938,17 +971,14 @@ int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
|
|||||||
int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
|
int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar,
|
||||||
unsigned long length, enum gacc_mode mode)
|
unsigned long length, enum gacc_mode mode)
|
||||||
{
|
{
|
||||||
unsigned long gpa;
|
union asce asce;
|
||||||
unsigned long currlen;
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
ipte_lock(vcpu);
|
ipte_lock(vcpu);
|
||||||
while (length > 0 && !rc) {
|
rc = guest_range_to_gpas(vcpu, gva, ar, NULL, length, asce, mode);
|
||||||
currlen = min(length, PAGE_SIZE - (gva % PAGE_SIZE));
|
|
||||||
rc = guest_translate_address(vcpu, gva, ar, &gpa, mode);
|
|
||||||
gva += currlen;
|
|
||||||
length -= currlen;
|
|
||||||
}
|
|
||||||
ipte_unlock(vcpu);
|
ipte_unlock(vcpu);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
@@ -344,11 +344,12 @@ int read_guest_abs(struct kvm_vcpu *vcpu, unsigned long gpa, void *data,
|
|||||||
* @len: number of bytes to copy
|
* @len: number of bytes to copy
|
||||||
*
|
*
|
||||||
* Copy @len bytes from @data (kernel space) to @gra (guest real address).
|
* Copy @len bytes from @data (kernel space) to @gra (guest real address).
|
||||||
* It is up to the caller to ensure that the entire guest memory range is
|
|
||||||
* valid memory before calling this function.
|
|
||||||
* Guest low address and key protection are not checked.
|
* Guest low address and key protection are not checked.
|
||||||
*
|
*
|
||||||
* Returns zero on success or -EFAULT on error.
|
* Returns zero on success, -EFAULT when copying from @data failed, or
|
||||||
|
* PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info
|
||||||
|
* is also stored to allow injecting into the guest (if applicable) using
|
||||||
|
* kvm_s390_inject_prog_cond().
|
||||||
*
|
*
|
||||||
* If an error occurs data may have been copied partially to guest memory.
|
* If an error occurs data may have been copied partially to guest memory.
|
||||||
*/
|
*/
|
||||||
@@ -367,11 +368,12 @@ int write_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
|
|||||||
* @len: number of bytes to copy
|
* @len: number of bytes to copy
|
||||||
*
|
*
|
||||||
* Copy @len bytes from @gra (guest real address) to @data (kernel space).
|
* Copy @len bytes from @gra (guest real address) to @data (kernel space).
|
||||||
* It is up to the caller to ensure that the entire guest memory range is
|
|
||||||
* valid memory before calling this function.
|
|
||||||
* Guest key protection is not checked.
|
* Guest key protection is not checked.
|
||||||
*
|
*
|
||||||
* Returns zero on success or -EFAULT on error.
|
* Returns zero on success, -EFAULT when copying to @data failed, or
|
||||||
|
* PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info
|
||||||
|
* is also stored to allow injecting into the guest (if applicable) using
|
||||||
|
* kvm_s390_inject_prog_cond().
|
||||||
*
|
*
|
||||||
* If an error occurs data may have been copied partially to kernel space.
|
* If an error occurs data may have been copied partially to kernel space.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -98,11 +98,12 @@ static long cmm_alloc_pages(long nr, long *counter,
|
|||||||
(*counter)++;
|
(*counter)++;
|
||||||
spin_unlock(&cmm_lock);
|
spin_unlock(&cmm_lock);
|
||||||
nr--;
|
nr--;
|
||||||
|
cond_resched();
|
||||||
}
|
}
|
||||||
return nr;
|
return nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
|
static long __cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
|
||||||
{
|
{
|
||||||
struct cmm_page_array *pa;
|
struct cmm_page_array *pa;
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
@@ -126,6 +127,21 @@ static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
|
|||||||
return nr;
|
return nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
|
||||||
|
{
|
||||||
|
long inc = 0;
|
||||||
|
|
||||||
|
while (nr) {
|
||||||
|
inc = min(256L, nr);
|
||||||
|
nr -= inc;
|
||||||
|
inc = __cmm_free_pages(inc, counter, list);
|
||||||
|
if (inc)
|
||||||
|
break;
|
||||||
|
cond_resched();
|
||||||
|
}
|
||||||
|
return nr + inc;
|
||||||
|
}
|
||||||
|
|
||||||
static int cmm_oom_notify(struct notifier_block *self,
|
static int cmm_oom_notify(struct notifier_block *self,
|
||||||
unsigned long dummy, void *parm)
|
unsigned long dummy, void *parm)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -216,7 +216,7 @@
|
|||||||
#define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */
|
#define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */
|
||||||
#define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* "" AMD SSBD implementation via LS_CFG MSR */
|
#define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* "" AMD SSBD implementation via LS_CFG MSR */
|
||||||
#define X86_FEATURE_IBRS ( 7*32+25) /* Indirect Branch Restricted Speculation */
|
#define X86_FEATURE_IBRS ( 7*32+25) /* Indirect Branch Restricted Speculation */
|
||||||
#define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */
|
#define X86_FEATURE_IBPB ( 7*32+26) /* "ibpb" Indirect Branch Prediction Barrier without a guaranteed RSB flush */
|
||||||
#define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */
|
#define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */
|
||||||
#define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */
|
#define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */
|
||||||
#define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */
|
#define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */
|
||||||
@@ -306,6 +306,7 @@
|
|||||||
#define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */
|
#define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */
|
||||||
#define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */
|
#define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */
|
||||||
#define X86_FEATURE_BTC_NO (13*32+29) /* "" Not vulnerable to Branch Type Confusion */
|
#define X86_FEATURE_BTC_NO (13*32+29) /* "" Not vulnerable to Branch Type Confusion */
|
||||||
|
#define X86_FEATURE_AMD_IBPB_RET (13*32+30) /* "" IBPB clears return address predictor */
|
||||||
|
|
||||||
/* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */
|
/* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */
|
||||||
#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
|
#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
|
||||||
|
|||||||
@@ -484,7 +484,19 @@ static int lapic_timer_shutdown(struct clock_event_device *evt)
|
|||||||
v = apic_read(APIC_LVTT);
|
v = apic_read(APIC_LVTT);
|
||||||
v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
|
v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
|
||||||
apic_write(APIC_LVTT, v);
|
apic_write(APIC_LVTT, v);
|
||||||
apic_write(APIC_TMICT, 0);
|
|
||||||
|
/*
|
||||||
|
* Setting APIC_LVT_MASKED (above) should be enough to tell
|
||||||
|
* the hardware that this timer will never fire. But AMD
|
||||||
|
* erratum 411 and some Intel CPU behavior circa 2024 say
|
||||||
|
* otherwise. Time for belt and suspenders programming: mask
|
||||||
|
* the timer _and_ zero the counter registers:
|
||||||
|
*/
|
||||||
|
if (v & APIC_LVT_TIMER_TSCDEADLINE)
|
||||||
|
wrmsrl(MSR_IA32_TSC_DEADLINE, 0);
|
||||||
|
else
|
||||||
|
apic_write(APIC_TMICT, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -243,6 +243,7 @@ static void __init ms_hyperv_init_platform(void)
|
|||||||
ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
|
ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
|
||||||
x86_platform.calibrate_tsc = hv_get_tsc_khz;
|
x86_platform.calibrate_tsc = hv_get_tsc_khz;
|
||||||
x86_platform.calibrate_cpu = hv_get_tsc_khz;
|
x86_platform.calibrate_cpu = hv_get_tsc_khz;
|
||||||
|
setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED) {
|
if (ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED) {
|
||||||
|
|||||||
@@ -862,7 +862,7 @@ char * __init xen_memory_setup(void)
|
|||||||
* to relocating (and even reusing) pages with kernel text or data.
|
* to relocating (and even reusing) pages with kernel text or data.
|
||||||
*/
|
*/
|
||||||
if (xen_is_e820_reserved(__pa_symbol(_text),
|
if (xen_is_e820_reserved(__pa_symbol(_text),
|
||||||
__pa_symbol(__bss_stop) - __pa_symbol(_text))) {
|
__pa_symbol(_end) - __pa_symbol(_text))) {
|
||||||
xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n");
|
xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n");
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2226,8 +2226,12 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
|
|||||||
struct bfq_queue *in_service_bfqq, *new_bfqq;
|
struct bfq_queue *in_service_bfqq, *new_bfqq;
|
||||||
|
|
||||||
/* if a merge has already been setup, then proceed with that first */
|
/* if a merge has already been setup, then proceed with that first */
|
||||||
if (bfqq->new_bfqq)
|
new_bfqq = bfqq->new_bfqq;
|
||||||
return bfqq->new_bfqq;
|
if (new_bfqq) {
|
||||||
|
while (new_bfqq->new_bfqq)
|
||||||
|
new_bfqq = new_bfqq->new_bfqq;
|
||||||
|
return new_bfqq;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prevent bfqq from being merged if it has been created too
|
* Prevent bfqq from being merged if it has been created too
|
||||||
@@ -5033,7 +5037,7 @@ bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq)
|
|||||||
{
|
{
|
||||||
bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue");
|
bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue");
|
||||||
|
|
||||||
if (bfqq_process_refs(bfqq) == 1) {
|
if (bfqq_process_refs(bfqq) == 1 && !bfqq->new_bfqq) {
|
||||||
bfqq->pid = current->pid;
|
bfqq->pid = current->pid;
|
||||||
bfq_clear_bfqq_coop(bfqq);
|
bfq_clear_bfqq_coop(bfqq);
|
||||||
bfq_clear_bfqq_split_coop(bfqq);
|
bfq_clear_bfqq_split_coop(bfqq);
|
||||||
@@ -5218,7 +5222,8 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
|
|||||||
* addition, if the queue has also just been split, we have to
|
* addition, if the queue has also just been split, we have to
|
||||||
* resume its state.
|
* resume its state.
|
||||||
*/
|
*/
|
||||||
if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) {
|
if (likely(bfqq != &bfqd->oom_bfqq) && !bfqq->new_bfqq &&
|
||||||
|
bfqq_process_refs(bfqq) == 1) {
|
||||||
bfqq->bic = bic;
|
bfqq->bic = bic;
|
||||||
if (split) {
|
if (split) {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -45,8 +45,7 @@ static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key,
|
|||||||
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
|
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
|
||||||
memcpy(alignbuffer, key, keylen);
|
memcpy(alignbuffer, key, keylen);
|
||||||
ret = crypto_aead_alg(tfm)->setkey(tfm, alignbuffer, keylen);
|
ret = crypto_aead_alg(tfm)->setkey(tfm, alignbuffer, keylen);
|
||||||
memset(alignbuffer, 0, keylen);
|
kzfree(buffer);
|
||||||
kfree(buffer);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,8 +38,7 @@ static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key,
|
|||||||
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
|
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
|
||||||
memcpy(alignbuffer, key, keylen);
|
memcpy(alignbuffer, key, keylen);
|
||||||
ret = cia->cia_setkey(tfm, alignbuffer, keylen);
|
ret = cia->cia_setkey(tfm, alignbuffer, keylen);
|
||||||
memset(alignbuffer, 0, keylen);
|
kzfree(buffer);
|
||||||
kfree(buffer);
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,6 +170,8 @@ acpi_status acpi_db_convert_to_package(char *string, union acpi_object *object)
|
|||||||
elements =
|
elements =
|
||||||
ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS *
|
ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS *
|
||||||
sizeof(union acpi_object));
|
sizeof(union acpi_object));
|
||||||
|
if (!elements)
|
||||||
|
return (AE_NO_MEMORY);
|
||||||
|
|
||||||
this = string;
|
this = string;
|
||||||
for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) {
|
for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) {
|
||||||
|
|||||||
@@ -437,6 +437,9 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
|
|||||||
|
|
||||||
if (info->connection_node) {
|
if (info->connection_node) {
|
||||||
second_desc = info->connection_node->object;
|
second_desc = info->connection_node->object;
|
||||||
|
if (second_desc == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) {
|
if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) {
|
||||||
status =
|
status =
|
||||||
acpi_ds_get_buffer_arguments(second_desc);
|
acpi_ds_get_buffer_arguments(second_desc);
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
|
|||||||
static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
|
static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
|
||||||
*parser_state);
|
*parser_state);
|
||||||
|
|
||||||
|
static void acpi_ps_free_field_list(union acpi_parse_object *start);
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ps_get_next_package_length
|
* FUNCTION: acpi_ps_get_next_package_length
|
||||||
@@ -683,6 +685,39 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
|
|||||||
return_PTR(field);
|
return_PTR(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ps_free_field_list
|
||||||
|
*
|
||||||
|
* PARAMETERS: start - First Op in field list
|
||||||
|
*
|
||||||
|
* RETURN: None.
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Free all Op objects inside a field list.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
static void acpi_ps_free_field_list(union acpi_parse_object *start)
|
||||||
|
{
|
||||||
|
union acpi_parse_object *cur = start;
|
||||||
|
union acpi_parse_object *next;
|
||||||
|
union acpi_parse_object *arg;
|
||||||
|
|
||||||
|
while (cur) {
|
||||||
|
next = cur->common.next;
|
||||||
|
|
||||||
|
/* AML_INT_CONNECTION_OP can have a single argument */
|
||||||
|
|
||||||
|
arg = acpi_ps_get_arg(cur, 0);
|
||||||
|
if (arg) {
|
||||||
|
acpi_ps_free_op(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
acpi_ps_free_op(cur);
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ps_get_next_arg
|
* FUNCTION: acpi_ps_get_next_arg
|
||||||
@@ -751,6 +786,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
|
|||||||
while (parser_state->aml < parser_state->pkg_end) {
|
while (parser_state->aml < parser_state->pkg_end) {
|
||||||
field = acpi_ps_get_next_field(parser_state);
|
field = acpi_ps_get_next_field(parser_state);
|
||||||
if (!field) {
|
if (!field) {
|
||||||
|
if (arg) {
|
||||||
|
acpi_ps_free_field_list(arg);
|
||||||
|
}
|
||||||
|
|
||||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -820,6 +859,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
|
|||||||
acpi_ps_get_next_namepath(walk_state, parser_state,
|
acpi_ps_get_next_namepath(walk_state, parser_state,
|
||||||
arg,
|
arg,
|
||||||
ACPI_NOT_METHOD_CALL);
|
ACPI_NOT_METHOD_CALL);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
acpi_ps_free_op(arg);
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Single complex argument, nothing returned */
|
/* Single complex argument, nothing returned */
|
||||||
|
|
||||||
@@ -854,6 +897,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
|
|||||||
acpi_ps_get_next_namepath(walk_state, parser_state,
|
acpi_ps_get_next_namepath(walk_state, parser_state,
|
||||||
arg,
|
arg,
|
||||||
ACPI_POSSIBLE_METHOD_CALL);
|
ACPI_POSSIBLE_METHOD_CALL);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
acpi_ps_free_op(arg);
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) {
|
if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) {
|
||||||
|
|
||||||
|
|||||||
@@ -713,27 +713,34 @@ static LIST_HEAD(acpi_battery_list);
|
|||||||
static LIST_HEAD(battery_hook_list);
|
static LIST_HEAD(battery_hook_list);
|
||||||
static DEFINE_MUTEX(hook_mutex);
|
static DEFINE_MUTEX(hook_mutex);
|
||||||
|
|
||||||
static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock)
|
static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook)
|
||||||
{
|
{
|
||||||
struct acpi_battery *battery;
|
struct acpi_battery *battery;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In order to remove a hook, we first need to
|
* In order to remove a hook, we first need to
|
||||||
* de-register all the batteries that are registered.
|
* de-register all the batteries that are registered.
|
||||||
*/
|
*/
|
||||||
if (lock)
|
|
||||||
mutex_lock(&hook_mutex);
|
|
||||||
list_for_each_entry(battery, &acpi_battery_list, list) {
|
list_for_each_entry(battery, &acpi_battery_list, list) {
|
||||||
hook->remove_battery(battery->bat);
|
hook->remove_battery(battery->bat);
|
||||||
}
|
}
|
||||||
list_del(&hook->list);
|
list_del_init(&hook->list);
|
||||||
if (lock)
|
|
||||||
mutex_unlock(&hook_mutex);
|
|
||||||
pr_info("extension unregistered: %s\n", hook->name);
|
pr_info("extension unregistered: %s\n", hook->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void battery_hook_unregister(struct acpi_battery_hook *hook)
|
void battery_hook_unregister(struct acpi_battery_hook *hook)
|
||||||
{
|
{
|
||||||
__battery_hook_unregister(hook, 1);
|
mutex_lock(&hook_mutex);
|
||||||
|
/*
|
||||||
|
* Ignore already unregistered battery hooks. This might happen
|
||||||
|
* if a battery hook was previously unloaded due to an error when
|
||||||
|
* adding a new battery.
|
||||||
|
*/
|
||||||
|
if (!list_empty(&hook->list))
|
||||||
|
battery_hook_unregister_unlocked(hook);
|
||||||
|
|
||||||
|
mutex_unlock(&hook_mutex);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(battery_hook_unregister);
|
EXPORT_SYMBOL_GPL(battery_hook_unregister);
|
||||||
|
|
||||||
@@ -742,7 +749,6 @@ void battery_hook_register(struct acpi_battery_hook *hook)
|
|||||||
struct acpi_battery *battery;
|
struct acpi_battery *battery;
|
||||||
|
|
||||||
mutex_lock(&hook_mutex);
|
mutex_lock(&hook_mutex);
|
||||||
INIT_LIST_HEAD(&hook->list);
|
|
||||||
list_add(&hook->list, &battery_hook_list);
|
list_add(&hook->list, &battery_hook_list);
|
||||||
/*
|
/*
|
||||||
* Now that the driver is registered, we need
|
* Now that the driver is registered, we need
|
||||||
@@ -759,7 +765,7 @@ void battery_hook_register(struct acpi_battery_hook *hook)
|
|||||||
* hooks.
|
* hooks.
|
||||||
*/
|
*/
|
||||||
pr_err("extension failed to load: %s", hook->name);
|
pr_err("extension failed to load: %s", hook->name);
|
||||||
__battery_hook_unregister(hook, 0);
|
battery_hook_unregister_unlocked(hook);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -796,7 +802,7 @@ static void battery_hook_add_battery(struct acpi_battery *battery)
|
|||||||
*/
|
*/
|
||||||
pr_err("error in extension, unloading: %s",
|
pr_err("error in extension, unloading: %s",
|
||||||
hook_node->name);
|
hook_node->name);
|
||||||
__battery_hook_unregister(hook_node, 0);
|
battery_hook_unregister_unlocked(hook_node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&hook_mutex);
|
mutex_unlock(&hook_mutex);
|
||||||
@@ -829,7 +835,7 @@ static void __exit battery_hook_exit(void)
|
|||||||
* need to remove the hooks.
|
* need to remove the hooks.
|
||||||
*/
|
*/
|
||||||
list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) {
|
list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) {
|
||||||
__battery_hook_unregister(hook, 1);
|
battery_hook_unregister(hook);
|
||||||
}
|
}
|
||||||
mutex_destroy(&hook_mutex);
|
mutex_destroy(&hook_mutex);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,6 +124,17 @@ static const struct dmi_system_id lid_blacklst[] = {
|
|||||||
},
|
},
|
||||||
.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
|
.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Samsung galaxybook2 ,initial _LID device notification returns
|
||||||
|
* lid closed.
|
||||||
|
*/
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "750XED"),
|
||||||
|
},
|
||||||
|
.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
|
||||||
|
},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -539,8 +539,9 @@ int acpi_device_setup_files(struct acpi_device *dev)
|
|||||||
* If device has _STR, 'description' file is created
|
* If device has _STR, 'description' file is created
|
||||||
*/
|
*/
|
||||||
if (acpi_has_method(dev->handle, "_STR")) {
|
if (acpi_has_method(dev->handle, "_STR")) {
|
||||||
status = acpi_evaluate_object(dev->handle, "_STR",
|
status = acpi_evaluate_object_typed(dev->handle, "_STR",
|
||||||
NULL, &buffer);
|
NULL, &buffer,
|
||||||
|
ACPI_TYPE_BUFFER);
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
buffer.pointer = NULL;
|
buffer.pointer = NULL;
|
||||||
dev->pnp.str_obj = buffer.pointer;
|
dev->pnp.str_obj = buffer.pointer;
|
||||||
|
|||||||
@@ -807,6 +807,9 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
|
|||||||
unsigned long tmp;
|
unsigned long tmp;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
if (t->rdata)
|
||||||
|
memset(t->rdata, 0, t->rlen);
|
||||||
|
|
||||||
/* start transaction */
|
/* start transaction */
|
||||||
spin_lock_irqsave(&ec->lock, tmp);
|
spin_lock_irqsave(&ec->lock, tmp);
|
||||||
/* Enable GPE for command processing (IBF=0/OBF=1) */
|
/* Enable GPE for command processing (IBF=0/OBF=1) */
|
||||||
@@ -843,8 +846,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
|
|||||||
|
|
||||||
if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))
|
if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (t->rdata)
|
|
||||||
memset(t->rdata, 0, t->rlen);
|
|
||||||
|
|
||||||
mutex_lock(&ec->mutex);
|
mutex_lock(&ec->mutex);
|
||||||
if (ec->global_lock) {
|
if (ec->global_lock) {
|
||||||
@@ -871,7 +872,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec)
|
|||||||
.wdata = NULL, .rdata = &d,
|
.wdata = NULL, .rdata = &d,
|
||||||
.wlen = 0, .rlen = 1};
|
.wlen = 0, .rlen = 1};
|
||||||
|
|
||||||
return acpi_ec_transaction(ec, &t);
|
return acpi_ec_transaction_unlocked(ec, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int acpi_ec_burst_disable(struct acpi_ec *ec)
|
static int acpi_ec_burst_disable(struct acpi_ec *ec)
|
||||||
@@ -881,7 +882,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec)
|
|||||||
.wlen = 0, .rlen = 0};
|
.wlen = 0, .rlen = 0};
|
||||||
|
|
||||||
return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ?
|
return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ?
|
||||||
acpi_ec_transaction(ec, &t) : 0;
|
acpi_ec_transaction_unlocked(ec, &t) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
|
static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
|
||||||
@@ -897,6 +898,19 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int acpi_ec_read_unlocked(struct acpi_ec *ec, u8 address, u8 *data)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
u8 d;
|
||||||
|
struct transaction t = {.command = ACPI_EC_COMMAND_READ,
|
||||||
|
.wdata = &address, .rdata = &d,
|
||||||
|
.wlen = 1, .rlen = 1};
|
||||||
|
|
||||||
|
result = acpi_ec_transaction_unlocked(ec, &t);
|
||||||
|
*data = d;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
|
static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
|
||||||
{
|
{
|
||||||
u8 wdata[2] = { address, data };
|
u8 wdata[2] = { address, data };
|
||||||
@@ -907,6 +921,16 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
|
|||||||
return acpi_ec_transaction(ec, &t);
|
return acpi_ec_transaction(ec, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int acpi_ec_write_unlocked(struct acpi_ec *ec, u8 address, u8 data)
|
||||||
|
{
|
||||||
|
u8 wdata[2] = { address, data };
|
||||||
|
struct transaction t = {.command = ACPI_EC_COMMAND_WRITE,
|
||||||
|
.wdata = wdata, .rdata = NULL,
|
||||||
|
.wlen = 2, .rlen = 0};
|
||||||
|
|
||||||
|
return acpi_ec_transaction_unlocked(ec, &t);
|
||||||
|
}
|
||||||
|
|
||||||
int ec_read(u8 addr, u8 *val)
|
int ec_read(u8 addr, u8 *val)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
@@ -1320,6 +1344,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
|
|||||||
struct acpi_ec *ec = handler_context;
|
struct acpi_ec *ec = handler_context;
|
||||||
int result = 0, i, bytes = bits / 8;
|
int result = 0, i, bytes = bits / 8;
|
||||||
u8 *value = (u8 *)value64;
|
u8 *value = (u8 *)value64;
|
||||||
|
u32 glk;
|
||||||
|
|
||||||
if ((address > 0xFF) || !value || !handler_context)
|
if ((address > 0xFF) || !value || !handler_context)
|
||||||
return AE_BAD_PARAMETER;
|
return AE_BAD_PARAMETER;
|
||||||
@@ -1327,13 +1352,25 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
|
|||||||
if (function != ACPI_READ && function != ACPI_WRITE)
|
if (function != ACPI_READ && function != ACPI_WRITE)
|
||||||
return AE_BAD_PARAMETER;
|
return AE_BAD_PARAMETER;
|
||||||
|
|
||||||
|
mutex_lock(&ec->mutex);
|
||||||
|
|
||||||
|
if (ec->global_lock) {
|
||||||
|
acpi_status status;
|
||||||
|
|
||||||
|
status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
result = -ENODEV;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ec->busy_polling || bits > 8)
|
if (ec->busy_polling || bits > 8)
|
||||||
acpi_ec_burst_enable(ec);
|
acpi_ec_burst_enable(ec);
|
||||||
|
|
||||||
for (i = 0; i < bytes; ++i, ++address, ++value) {
|
for (i = 0; i < bytes; ++i, ++address, ++value) {
|
||||||
result = (function == ACPI_READ) ?
|
result = (function == ACPI_READ) ?
|
||||||
acpi_ec_read(ec, address, value) :
|
acpi_ec_read_unlocked(ec, address, value) :
|
||||||
acpi_ec_write(ec, address, *value);
|
acpi_ec_write_unlocked(ec, address, *value);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1341,6 +1378,12 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
|
|||||||
if (ec->busy_polling || bits > 8)
|
if (ec->busy_polling || bits > 8)
|
||||||
acpi_ec_burst_disable(ec);
|
acpi_ec_burst_disable(ec);
|
||||||
|
|
||||||
|
if (ec->global_lock)
|
||||||
|
acpi_release_global_lock(glk);
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
mutex_unlock(&ec->mutex);
|
||||||
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case -EINVAL:
|
case -EINVAL:
|
||||||
return AE_BAD_PARAMETER;
|
return AE_BAD_PARAMETER;
|
||||||
|
|||||||
@@ -376,10 +376,8 @@ static int tps68470_pmic_opregion_probe(struct platform_device *pdev)
|
|||||||
struct tps68470_pmic_opregion *opregion;
|
struct tps68470_pmic_opregion *opregion;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
|
||||||
if (!dev || !tps68470_regmap) {
|
if (!tps68470_regmap)
|
||||||
dev_warn(dev, "dev or regmap is NULL\n");
|
return dev_err_probe(dev, -EINVAL, "regmap is missing\n");
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
dev_warn(dev, "acpi handle is NULL\n");
|
dev_warn(dev, "acpi handle is NULL\n");
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ static const struct pci_device_id sil_pci_tbl[] = {
|
|||||||
static const struct sil_drivelist {
|
static const struct sil_drivelist {
|
||||||
const char *product;
|
const char *product;
|
||||||
unsigned int quirk;
|
unsigned int quirk;
|
||||||
} sil_blacklist [] = {
|
} sil_quirks[] = {
|
||||||
{ "ST320012AS", SIL_QUIRK_MOD15WRITE },
|
{ "ST320012AS", SIL_QUIRK_MOD15WRITE },
|
||||||
{ "ST330013AS", SIL_QUIRK_MOD15WRITE },
|
{ "ST330013AS", SIL_QUIRK_MOD15WRITE },
|
||||||
{ "ST340017AS", SIL_QUIRK_MOD15WRITE },
|
{ "ST340017AS", SIL_QUIRK_MOD15WRITE },
|
||||||
@@ -617,8 +617,8 @@ static void sil_thaw(struct ata_port *ap)
|
|||||||
* list, and apply the fixups to only the specific
|
* list, and apply the fixups to only the specific
|
||||||
* devices/hosts/firmwares that need it.
|
* devices/hosts/firmwares that need it.
|
||||||
*
|
*
|
||||||
* 20040111 - Seagate drives affected by the Mod15Write bug are blacklisted
|
* 20040111 - Seagate drives affected by the Mod15Write bug are quirked
|
||||||
* The Maxtor quirk is in the blacklist, but I'm keeping the original
|
* The Maxtor quirk is in sil_quirks, but I'm keeping the original
|
||||||
* pessimistic fix for the following reasons...
|
* pessimistic fix for the following reasons...
|
||||||
* - There seems to be less info on it, only one device gleaned off the
|
* - There seems to be less info on it, only one device gleaned off the
|
||||||
* Windows driver, maybe only one is affected. More info would be greatly
|
* Windows driver, maybe only one is affected. More info would be greatly
|
||||||
@@ -637,9 +637,9 @@ static void sil_dev_config(struct ata_device *dev)
|
|||||||
|
|
||||||
ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
|
ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
|
||||||
|
|
||||||
for (n = 0; sil_blacklist[n].product; n++)
|
for (n = 0; sil_quirks[n].product; n++)
|
||||||
if (!strcmp(sil_blacklist[n].product, model_num)) {
|
if (!strcmp(sil_quirks[n].product, model_num)) {
|
||||||
quirks = sil_blacklist[n].quirk;
|
quirks = sil_quirks[n].quirk;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,8 @@ static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr,
|
|||||||
{
|
{
|
||||||
struct bus_attribute *bus_attr = to_bus_attr(attr);
|
struct bus_attribute *bus_attr = to_bus_attr(attr);
|
||||||
struct subsys_private *subsys_priv = to_subsys_private(kobj);
|
struct subsys_private *subsys_priv = to_subsys_private(kobj);
|
||||||
ssize_t ret = 0;
|
/* return -EIO for reading a bus attribute without show() */
|
||||||
|
ssize_t ret = -EIO;
|
||||||
|
|
||||||
if (bus_attr->show)
|
if (bus_attr->show)
|
||||||
ret = bus_attr->show(subsys_priv->bus, buf);
|
ret = bus_attr->show(subsys_priv->bus, buf);
|
||||||
@@ -115,7 +116,8 @@ static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr,
|
|||||||
{
|
{
|
||||||
struct bus_attribute *bus_attr = to_bus_attr(attr);
|
struct bus_attribute *bus_attr = to_bus_attr(attr);
|
||||||
struct subsys_private *subsys_priv = to_subsys_private(kobj);
|
struct subsys_private *subsys_priv = to_subsys_private(kobj);
|
||||||
ssize_t ret = 0;
|
/* return -EIO for writing a bus attribute without store() */
|
||||||
|
ssize_t ret = -EIO;
|
||||||
|
|
||||||
if (bus_attr->store)
|
if (bus_attr->store)
|
||||||
ret = bus_attr->store(subsys_priv->bus, buf, count);
|
ret = bus_attr->store(subsys_priv->bus, buf, count);
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/rcupdate.h>
|
|
||||||
#include <linux/sched/signal.h>
|
#include <linux/sched/signal.h>
|
||||||
#include <linux/sysfs.h>
|
#include <linux/sysfs.h>
|
||||||
|
|
||||||
@@ -1586,7 +1585,6 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
|
|||||||
struct kobj_uevent_env *env)
|
struct kobj_uevent_env *env)
|
||||||
{
|
{
|
||||||
struct device *dev = kobj_to_dev(kobj);
|
struct device *dev = kobj_to_dev(kobj);
|
||||||
struct device_driver *driver;
|
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
/* add device node properties if present */
|
/* add device node properties if present */
|
||||||
@@ -1615,12 +1613,8 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
|
|||||||
if (dev->type && dev->type->name)
|
if (dev->type && dev->type->name)
|
||||||
add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
|
add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
|
||||||
|
|
||||||
/* Synchronize with module_remove_driver() */
|
if (dev->driver)
|
||||||
rcu_read_lock();
|
add_uevent_var(env, "DRIVER=%s", dev->driver->name);
|
||||||
driver = READ_ONCE(dev->driver);
|
|
||||||
if (driver)
|
|
||||||
add_uevent_var(env, "DRIVER=%s", driver->name);
|
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
/* Add common DT information about the device */
|
/* Add common DT information about the device */
|
||||||
of_device_uevent(dev, env);
|
of_device_uevent(dev, env);
|
||||||
@@ -1690,8 +1684,11 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,
|
|||||||
if (!env)
|
if (!env)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* Synchronize with really_probe() */
|
||||||
|
device_lock(dev);
|
||||||
/* let the kset specific function add its keys */
|
/* let the kset specific function add its keys */
|
||||||
retval = kset->uevent_ops->uevent(kset, &dev->kobj, env);
|
retval = kset->uevent_ops->uevent(kset, &dev->kobj, env);
|
||||||
|
device_unlock(dev);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|||||||
@@ -570,6 +570,26 @@ static void fw_abort_batch_reqs(struct firmware *fw)
|
|||||||
mutex_unlock(&fw_lock);
|
mutex_unlock(&fw_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reject firmware file names with ".." path components.
|
||||||
|
* There are drivers that construct firmware file names from device-supplied
|
||||||
|
* strings, and we don't want some device to be able to tell us "I would like to
|
||||||
|
* be sent my firmware from ../../../etc/shadow, please".
|
||||||
|
*
|
||||||
|
* Search for ".." surrounded by either '/' or start/end of string.
|
||||||
|
*
|
||||||
|
* This intentionally only looks at the firmware name, not at the firmware base
|
||||||
|
* directory or at symlink contents.
|
||||||
|
*/
|
||||||
|
static bool name_contains_dotdot(const char *name)
|
||||||
|
{
|
||||||
|
size_t name_len = strlen(name);
|
||||||
|
|
||||||
|
return strcmp(name, "..") == 0 || strncmp(name, "../", 3) == 0 ||
|
||||||
|
strstr(name, "/../") != NULL ||
|
||||||
|
(name_len >= 3 && strcmp(name+name_len-3, "/..") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* called from request_firmware() and request_firmware_work_func() */
|
/* called from request_firmware() and request_firmware_work_func() */
|
||||||
static int
|
static int
|
||||||
_request_firmware(const struct firmware **firmware_p, const char *name,
|
_request_firmware(const struct firmware **firmware_p, const char *name,
|
||||||
@@ -587,6 +607,14 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name_contains_dotdot(name)) {
|
||||||
|
dev_warn(device,
|
||||||
|
"Firmware load for '%s' refused, path contains '..' component\n",
|
||||||
|
name);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
ret = _request_firmware_prepare(&fw, name, device, buf, size,
|
ret = _request_firmware_prepare(&fw, name, device, buf, size,
|
||||||
opt_flags);
|
opt_flags);
|
||||||
if (ret <= 0) /* error or already assigned */
|
if (ret <= 0) /* error or already assigned */
|
||||||
@@ -627,6 +655,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
|
|||||||
* @name will be used as $FIRMWARE in the uevent environment and
|
* @name will be used as $FIRMWARE in the uevent environment and
|
||||||
* should be distinctive enough not to be confused with any other
|
* should be distinctive enough not to be confused with any other
|
||||||
* firmware image for this or any other device.
|
* firmware image for this or any other device.
|
||||||
|
* It must not contain any ".." path components - "foo/bar..bin" is
|
||||||
|
* allowed, but "foo/../bar.bin" is not.
|
||||||
*
|
*
|
||||||
* Caller must hold the reference count of @device.
|
* Caller must hold the reference count of @device.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/rcupdate.h>
|
|
||||||
#include "base.h"
|
#include "base.h"
|
||||||
|
|
||||||
static char *make_driver_name(struct device_driver *drv)
|
static char *make_driver_name(struct device_driver *drv)
|
||||||
@@ -78,9 +77,6 @@ void module_remove_driver(struct device_driver *drv)
|
|||||||
if (!drv)
|
if (!drv)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Synchronize with dev_uevent() */
|
|
||||||
synchronize_rcu();
|
|
||||||
|
|
||||||
sysfs_remove_link(&drv->p->kobj, "module");
|
sysfs_remove_link(&drv->p->kobj, "module");
|
||||||
|
|
||||||
if (drv->owner)
|
if (drv->owner)
|
||||||
|
|||||||
@@ -362,6 +362,7 @@ ata_rw_frameinit(struct frame *f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit;
|
ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit;
|
||||||
|
dev_hold(t->ifp->nd);
|
||||||
skb->dev = t->ifp->nd;
|
skb->dev = t->ifp->nd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,6 +403,8 @@ aoecmd_ata_rw(struct aoedev *d)
|
|||||||
__skb_queue_head_init(&queue);
|
__skb_queue_head_init(&queue);
|
||||||
__skb_queue_tail(&queue, skb);
|
__skb_queue_tail(&queue, skb);
|
||||||
aoenet_xmit(&queue);
|
aoenet_xmit(&queue);
|
||||||
|
} else {
|
||||||
|
dev_put(f->t->ifp->nd);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -484,10 +487,13 @@ resend(struct aoedev *d, struct frame *f)
|
|||||||
memcpy(h->dst, t->addr, sizeof h->dst);
|
memcpy(h->dst, t->addr, sizeof h->dst);
|
||||||
memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
|
memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
|
||||||
|
|
||||||
|
dev_hold(t->ifp->nd);
|
||||||
skb->dev = t->ifp->nd;
|
skb->dev = t->ifp->nd;
|
||||||
skb = skb_clone(skb, GFP_ATOMIC);
|
skb = skb_clone(skb, GFP_ATOMIC);
|
||||||
if (skb == NULL)
|
if (skb == NULL) {
|
||||||
|
dev_put(t->ifp->nd);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
f->sent = ktime_get();
|
f->sent = ktime_get();
|
||||||
__skb_queue_head_init(&queue);
|
__skb_queue_head_init(&queue);
|
||||||
__skb_queue_tail(&queue, skb);
|
__skb_queue_tail(&queue, skb);
|
||||||
@@ -618,6 +624,8 @@ probe(struct aoetgt *t)
|
|||||||
__skb_queue_head_init(&queue);
|
__skb_queue_head_init(&queue);
|
||||||
__skb_queue_tail(&queue, skb);
|
__skb_queue_tail(&queue, skb);
|
||||||
aoenet_xmit(&queue);
|
aoenet_xmit(&queue);
|
||||||
|
} else {
|
||||||
|
dev_put(f->t->ifp->nd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1407,6 +1415,7 @@ aoecmd_ata_id(struct aoedev *d)
|
|||||||
ah->cmdstat = ATA_CMD_ID_ATA;
|
ah->cmdstat = ATA_CMD_ID_ATA;
|
||||||
ah->lba3 = 0xa0;
|
ah->lba3 = 0xa0;
|
||||||
|
|
||||||
|
dev_hold(t->ifp->nd);
|
||||||
skb->dev = t->ifp->nd;
|
skb->dev = t->ifp->nd;
|
||||||
|
|
||||||
d->rttavg = RTTAVG_INIT;
|
d->rttavg = RTTAVG_INIT;
|
||||||
@@ -1416,6 +1425,8 @@ aoecmd_ata_id(struct aoedev *d)
|
|||||||
skb = skb_clone(skb, GFP_ATOMIC);
|
skb = skb_clone(skb, GFP_ATOMIC);
|
||||||
if (skb)
|
if (skb)
|
||||||
f->sent = ktime_get();
|
f->sent = ktime_get();
|
||||||
|
else
|
||||||
|
dev_put(t->ifp->nd);
|
||||||
|
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3499,10 +3499,12 @@ void drbd_uuid_new_current(struct drbd_device *device) __must_hold(local)
|
|||||||
void drbd_uuid_set_bm(struct drbd_device *device, u64 val) __must_hold(local)
|
void drbd_uuid_set_bm(struct drbd_device *device, u64 val) __must_hold(local)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
if (device->ldev->md.uuid[UI_BITMAP] == 0 && val == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&device->ldev->md.uuid_lock, flags);
|
spin_lock_irqsave(&device->ldev->md.uuid_lock, flags);
|
||||||
|
if (device->ldev->md.uuid[UI_BITMAP] == 0 && val == 0) {
|
||||||
|
spin_unlock_irqrestore(&device->ldev->md.uuid_lock, flags);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (val == 0) {
|
if (val == 0) {
|
||||||
drbd_uuid_move_history(device);
|
drbd_uuid_move_history(device);
|
||||||
device->ldev->md.uuid[UI_HISTORY_START] = device->ldev->md.uuid[UI_BITMAP];
|
device->ldev->md.uuid[UI_HISTORY_START] = device->ldev->md.uuid[UI_BITMAP];
|
||||||
|
|||||||
@@ -888,7 +888,7 @@ is_valid_state(struct drbd_device *device, union drbd_state ns)
|
|||||||
ns.disk == D_OUTDATED)
|
ns.disk == D_OUTDATED)
|
||||||
rv = SS_CONNECTED_OUTDATES;
|
rv = SS_CONNECTED_OUTDATES;
|
||||||
|
|
||||||
else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
|
else if (nc && (ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
|
||||||
(nc->verify_alg[0] == 0))
|
(nc->verify_alg[0] == 0))
|
||||||
rv = SS_NO_VERIFY_ALG;
|
rv = SS_NO_VERIFY_ALG;
|
||||||
|
|
||||||
|
|||||||
@@ -743,7 +743,15 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
|
|||||||
if (!urb)
|
if (!urb)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
|
if (le16_to_cpu(data->udev->descriptor.idVendor) == 0x0a12 &&
|
||||||
|
le16_to_cpu(data->udev->descriptor.idProduct) == 0x0001)
|
||||||
|
/* Fake CSR devices don't seem to support sort-transter */
|
||||||
|
size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
|
||||||
|
else
|
||||||
|
/* Use maximum HCI Event size so the USB stack handles
|
||||||
|
* ZPL/short-transfer automatically.
|
||||||
|
*/
|
||||||
|
size = HCI_MAX_EVENT_SIZE;
|
||||||
|
|
||||||
buf = kmalloc(size, mem_flags);
|
buf = kmalloc(size, mem_flags);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
|
|||||||
@@ -2075,25 +2075,27 @@ static int virtcons_probe(struct virtio_device *vdev)
|
|||||||
multiport = true;
|
multiport = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = init_vqs(portdev);
|
|
||||||
if (err < 0) {
|
|
||||||
dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
|
|
||||||
goto free_chrdev;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_init(&portdev->ports_lock);
|
spin_lock_init(&portdev->ports_lock);
|
||||||
INIT_LIST_HEAD(&portdev->ports);
|
INIT_LIST_HEAD(&portdev->ports);
|
||||||
INIT_LIST_HEAD(&portdev->list);
|
INIT_LIST_HEAD(&portdev->list);
|
||||||
|
|
||||||
virtio_device_ready(portdev->vdev);
|
|
||||||
|
|
||||||
INIT_WORK(&portdev->config_work, &config_work_handler);
|
INIT_WORK(&portdev->config_work, &config_work_handler);
|
||||||
INIT_WORK(&portdev->control_work, &control_work_handler);
|
INIT_WORK(&portdev->control_work, &control_work_handler);
|
||||||
|
|
||||||
if (multiport) {
|
if (multiport) {
|
||||||
spin_lock_init(&portdev->c_ivq_lock);
|
spin_lock_init(&portdev->c_ivq_lock);
|
||||||
spin_lock_init(&portdev->c_ovq_lock);
|
spin_lock_init(&portdev->c_ovq_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = init_vqs(portdev);
|
||||||
|
if (err < 0) {
|
||||||
|
dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
|
||||||
|
goto free_chrdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtio_device_ready(portdev->vdev);
|
||||||
|
|
||||||
|
if (multiport) {
|
||||||
err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock);
|
err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
dev_err(&vdev->dev,
|
dev_err(&vdev->dev,
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ static void bcm53573_ilp_init(struct device_node *np)
|
|||||||
goto err_free_ilp;
|
goto err_free_ilp;
|
||||||
}
|
}
|
||||||
|
|
||||||
ilp->regmap = syscon_node_to_regmap(of_get_parent(np));
|
ilp->regmap = syscon_node_to_regmap(np->parent);
|
||||||
if (IS_ERR(ilp->regmap)) {
|
if (IS_ERR(ilp->regmap)) {
|
||||||
err = PTR_ERR(ilp->regmap);
|
err = PTR_ERR(ilp->regmap);
|
||||||
goto err_free_ilp;
|
goto err_free_ilp;
|
||||||
|
|||||||
@@ -9,31 +9,101 @@
|
|||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/gfp.h>
|
#include <linux/gfp.h>
|
||||||
|
|
||||||
|
struct devm_clk_state {
|
||||||
|
struct clk *clk;
|
||||||
|
void (*exit)(struct clk *clk);
|
||||||
|
};
|
||||||
|
|
||||||
static void devm_clk_release(struct device *dev, void *res)
|
static void devm_clk_release(struct device *dev, void *res)
|
||||||
{
|
{
|
||||||
clk_put(*(struct clk **)res);
|
struct devm_clk_state *state = res;
|
||||||
|
|
||||||
|
if (state->exit)
|
||||||
|
state->exit(state->clk);
|
||||||
|
|
||||||
|
clk_put(state->clk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct clk *__devm_clk_get(struct device *dev, const char *id,
|
||||||
|
struct clk *(*get)(struct device *dev, const char *id),
|
||||||
|
int (*init)(struct clk *clk),
|
||||||
|
void (*exit)(struct clk *clk))
|
||||||
|
{
|
||||||
|
struct devm_clk_state *state;
|
||||||
|
struct clk *clk;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
state = devres_alloc(devm_clk_release, sizeof(*state), GFP_KERNEL);
|
||||||
|
if (!state)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
clk = get(dev, id);
|
||||||
|
if (IS_ERR(clk)) {
|
||||||
|
ret = PTR_ERR(clk);
|
||||||
|
goto err_clk_get;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (init) {
|
||||||
|
ret = init(clk);
|
||||||
|
if (ret)
|
||||||
|
goto err_clk_init;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->clk = clk;
|
||||||
|
state->exit = exit;
|
||||||
|
|
||||||
|
devres_add(dev, state);
|
||||||
|
|
||||||
|
return clk;
|
||||||
|
|
||||||
|
err_clk_init:
|
||||||
|
|
||||||
|
clk_put(clk);
|
||||||
|
err_clk_get:
|
||||||
|
|
||||||
|
devres_free(state);
|
||||||
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct clk *devm_clk_get(struct device *dev, const char *id)
|
struct clk *devm_clk_get(struct device *dev, const char *id)
|
||||||
{
|
{
|
||||||
struct clk **ptr, *clk;
|
return __devm_clk_get(dev, id, clk_get, NULL, NULL);
|
||||||
|
|
||||||
ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
|
|
||||||
if (!ptr)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
|
|
||||||
clk = clk_get(dev, id);
|
|
||||||
if (!IS_ERR(clk)) {
|
|
||||||
*ptr = clk;
|
|
||||||
devres_add(dev, ptr);
|
|
||||||
} else {
|
|
||||||
devres_free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return clk;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(devm_clk_get);
|
EXPORT_SYMBOL(devm_clk_get);
|
||||||
|
|
||||||
|
struct clk *devm_clk_get_prepared(struct device *dev, const char *id)
|
||||||
|
{
|
||||||
|
return __devm_clk_get(dev, id, clk_get, clk_prepare, clk_unprepare);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(devm_clk_get_prepared);
|
||||||
|
|
||||||
|
struct clk *devm_clk_get_enabled(struct device *dev, const char *id)
|
||||||
|
{
|
||||||
|
return __devm_clk_get(dev, id, clk_get,
|
||||||
|
clk_prepare_enable, clk_disable_unprepare);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(devm_clk_get_enabled);
|
||||||
|
|
||||||
|
struct clk *devm_clk_get_optional(struct device *dev, const char *id)
|
||||||
|
{
|
||||||
|
return __devm_clk_get(dev, id, clk_get_optional, NULL, NULL);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(devm_clk_get_optional);
|
||||||
|
|
||||||
|
struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id)
|
||||||
|
{
|
||||||
|
return __devm_clk_get(dev, id, clk_get_optional,
|
||||||
|
clk_prepare, clk_unprepare);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(devm_clk_get_optional_prepared);
|
||||||
|
|
||||||
|
struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id)
|
||||||
|
{
|
||||||
|
return __devm_clk_get(dev, id, clk_get_optional,
|
||||||
|
clk_prepare_enable, clk_disable_unprepare);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled);
|
||||||
|
|
||||||
struct clk_bulk_devres {
|
struct clk_bulk_devres {
|
||||||
struct clk_bulk_data *clks;
|
struct clk_bulk_data *clks;
|
||||||
int num_clks;
|
int num_clks;
|
||||||
@@ -93,18 +163,19 @@ EXPORT_SYMBOL(devm_clk_put);
|
|||||||
struct clk *devm_get_clk_from_child(struct device *dev,
|
struct clk *devm_get_clk_from_child(struct device *dev,
|
||||||
struct device_node *np, const char *con_id)
|
struct device_node *np, const char *con_id)
|
||||||
{
|
{
|
||||||
struct clk **ptr, *clk;
|
struct devm_clk_state *state;
|
||||||
|
struct clk *clk;
|
||||||
|
|
||||||
ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
|
state = devres_alloc(devm_clk_release, sizeof(*state), GFP_KERNEL);
|
||||||
if (!ptr)
|
if (!state)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
clk = of_clk_get_by_name(np, con_id);
|
clk = of_clk_get_by_name(np, con_id);
|
||||||
if (!IS_ERR(clk)) {
|
if (!IS_ERR(clk)) {
|
||||||
*ptr = clk;
|
state->clk = clk;
|
||||||
devres_add(dev, ptr);
|
devres_add(dev, state);
|
||||||
} else {
|
} else {
|
||||||
devres_free(ptr);
|
devres_free(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
return clk;
|
return clk;
|
||||||
|
|||||||
@@ -415,7 +415,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
|
|||||||
RK2928_CLKSEL_CON(29), 0, 3, DFLAGS),
|
RK2928_CLKSEL_CON(29), 0, 3, DFLAGS),
|
||||||
DIV(0, "sclk_vop_pre", "sclk_vop_src", 0,
|
DIV(0, "sclk_vop_pre", "sclk_vop_src", 0,
|
||||||
RK2928_CLKSEL_CON(27), 8, 8, DFLAGS),
|
RK2928_CLKSEL_CON(27), 8, 8, DFLAGS),
|
||||||
MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, 0,
|
MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||||
RK2928_CLKSEL_CON(27), 1, 1, MFLAGS),
|
RK2928_CLKSEL_CON(27), 1, 1, MFLAGS),
|
||||||
|
|
||||||
FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
|
FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
|
||||||
|
|||||||
@@ -444,12 +444,13 @@ void __init rockchip_clk_register_branches(
|
|||||||
struct rockchip_clk_branch *list,
|
struct rockchip_clk_branch *list,
|
||||||
unsigned int nr_clk)
|
unsigned int nr_clk)
|
||||||
{
|
{
|
||||||
struct clk *clk = NULL;
|
struct clk *clk;
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
for (idx = 0; idx < nr_clk; idx++, list++) {
|
for (idx = 0; idx < nr_clk; idx++, list++) {
|
||||||
flags = list->flags;
|
flags = list->flags;
|
||||||
|
clk = NULL;
|
||||||
|
|
||||||
/* catch simple muxes */
|
/* catch simple muxes */
|
||||||
switch (list->branch_type) {
|
switch (list->branch_type) {
|
||||||
|
|||||||
@@ -257,6 +257,7 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
clk = of_clk_get_from_provider(&clkspec);
|
clk = of_clk_get_from_provider(&clkspec);
|
||||||
|
of_node_put(clkspec.np);
|
||||||
if (IS_ERR(clk)) {
|
if (IS_ERR(clk)) {
|
||||||
pr_err("%s: failed to get atl clock %d from provider\n",
|
pr_err("%s: failed to get atl clock %d from provider\n",
|
||||||
__func__, i);
|
__func__, i);
|
||||||
|
|||||||
@@ -242,6 +242,7 @@ static int __init msm_dt_timer_init(struct device_node *np)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (of_property_read_u32(np, "clock-frequency", &freq)) {
|
if (of_property_read_u32(np, "clock-frequency", &freq)) {
|
||||||
|
iounmap(cpu0_base);
|
||||||
pr_err("Unknown frequency\n");
|
pr_err("Unknown frequency\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -252,7 +253,11 @@ static int __init msm_dt_timer_init(struct device_node *np)
|
|||||||
freq /= 4;
|
freq /= 4;
|
||||||
writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
|
writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
|
||||||
|
|
||||||
return msm_timer_init(freq, 32, irq, !!percpu_offset);
|
ret = msm_timer_init(freq, 32, irq, !!percpu_offset);
|
||||||
|
if (ret)
|
||||||
|
iounmap(cpu0_base);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
|
TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
|
||||||
TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
|
TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
|
||||||
|
|||||||
@@ -800,7 +800,7 @@ static int sdei_device_freeze(struct device *dev)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* unregister private events */
|
/* unregister private events */
|
||||||
cpuhp_remove_state(sdei_entry_point);
|
cpuhp_remove_state(sdei_hp_state);
|
||||||
|
|
||||||
err = sdei_unregister_shared();
|
err = sdei_unregister_shared();
|
||||||
if (err)
|
if (err)
|
||||||
|
|||||||
@@ -407,6 +407,8 @@ static void __aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
|
|||||||
gpio->dcache[GPIO_BANK(offset)] = reg;
|
gpio->dcache[GPIO_BANK(offset)] = reg;
|
||||||
|
|
||||||
iowrite32(reg, addr);
|
iowrite32(reg, addr);
|
||||||
|
/* Flush write */
|
||||||
|
ioread32(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
|
static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
|
||||||
@@ -1174,7 +1176,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
|
|||||||
if (!gpio_id)
|
if (!gpio_id)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
gpio->clk = of_clk_get(pdev->dev.of_node, 0);
|
gpio->clk = devm_clk_get_enabled(&pdev->dev, NULL);
|
||||||
if (IS_ERR(gpio->clk)) {
|
if (IS_ERR(gpio->clk)) {
|
||||||
dev_warn(&pdev->dev,
|
dev_warn(&pdev->dev,
|
||||||
"Failed to get clock from devicetree, debouncing disabled\n");
|
"Failed to get clock from devicetree, debouncing disabled\n");
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ static int davinci_gpio_probe(struct platform_device *pdev)
|
|||||||
* serve as EDMA event triggers.
|
* serve as EDMA event triggers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void gpio_irq_disable(struct irq_data *d)
|
static void gpio_irq_mask(struct irq_data *d)
|
||||||
{
|
{
|
||||||
struct davinci_gpio_regs __iomem *g = irq2regs(d);
|
struct davinci_gpio_regs __iomem *g = irq2regs(d);
|
||||||
u32 mask = (u32) irq_data_get_irq_handler_data(d);
|
u32 mask = (u32) irq_data_get_irq_handler_data(d);
|
||||||
@@ -303,7 +303,7 @@ static void gpio_irq_disable(struct irq_data *d)
|
|||||||
writel_relaxed(mask, &g->clr_rising);
|
writel_relaxed(mask, &g->clr_rising);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpio_irq_enable(struct irq_data *d)
|
static void gpio_irq_unmask(struct irq_data *d)
|
||||||
{
|
{
|
||||||
struct davinci_gpio_regs __iomem *g = irq2regs(d);
|
struct davinci_gpio_regs __iomem *g = irq2regs(d);
|
||||||
u32 mask = (u32) irq_data_get_irq_handler_data(d);
|
u32 mask = (u32) irq_data_get_irq_handler_data(d);
|
||||||
@@ -329,8 +329,8 @@ static int gpio_irq_type(struct irq_data *d, unsigned trigger)
|
|||||||
|
|
||||||
static struct irq_chip gpio_irqchip = {
|
static struct irq_chip gpio_irqchip = {
|
||||||
.name = "GPIO",
|
.name = "GPIO",
|
||||||
.irq_enable = gpio_irq_enable,
|
.irq_unmask = gpio_irq_unmask,
|
||||||
.irq_disable = gpio_irq_disable,
|
.irq_mask = gpio_irq_mask,
|
||||||
.irq_set_type = gpio_irq_type,
|
.irq_set_type = gpio_irq_type,
|
||||||
.flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE,
|
.flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
|
#include <linux/nospec.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
@@ -144,7 +145,7 @@ struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip,
|
|||||||
if (hwnum >= gdev->ngpio)
|
if (hwnum >= gdev->ngpio)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
return &gdev->descs[hwnum];
|
return &gdev->descs[array_index_nospec(hwnum, gdev->ngpio)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
|
|||||||
struct acpi_buffer *params)
|
struct acpi_buffer *params)
|
||||||
{
|
{
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
union acpi_object *obj;
|
||||||
union acpi_object atif_arg_elements[2];
|
union acpi_object atif_arg_elements[2];
|
||||||
struct acpi_object_list atif_arg;
|
struct acpi_object_list atif_arg;
|
||||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||||
@@ -112,16 +113,24 @@ static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
|
|||||||
|
|
||||||
status = acpi_evaluate_object(atif->handle, NULL, &atif_arg,
|
status = acpi_evaluate_object(atif->handle, NULL, &atif_arg,
|
||||||
&buffer);
|
&buffer);
|
||||||
|
obj = (union acpi_object *)buffer.pointer;
|
||||||
|
|
||||||
/* Fail only if calling the method fails and ATIF is supported */
|
/* Fail if calling the method fails */
|
||||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
if (ACPI_FAILURE(status)) {
|
||||||
DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
|
DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
|
||||||
acpi_format_exception(status));
|
acpi_format_exception(status));
|
||||||
kfree(buffer.pointer);
|
kfree(obj);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer.pointer;
|
if (obj->type != ACPI_TYPE_BUFFER) {
|
||||||
|
DRM_DEBUG_DRIVER("bad object returned from ATIF: %d\n",
|
||||||
|
obj->type);
|
||||||
|
kfree(obj);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -394,7 +394,7 @@ static ssize_t amdgpu_debugfs_regs_smc_read(struct file *f, char __user *buf,
|
|||||||
if (!adev->smc_rreg)
|
if (!adev->smc_rreg)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (size & 0x3 || *pos & 0x3)
|
if (size > 4096 || size & 0x3 || *pos & 0x3)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
while (size) {
|
while (size) {
|
||||||
|
|||||||
@@ -2095,23 +2095,29 @@ amdgpu_atombios_encoder_get_lcd_info(struct amdgpu_encoder *encoder)
|
|||||||
fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
|
fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
|
||||||
if (fake_edid_record->ucFakeEDIDLength) {
|
if (fake_edid_record->ucFakeEDIDLength) {
|
||||||
struct edid *edid;
|
struct edid *edid;
|
||||||
int edid_size =
|
int edid_size;
|
||||||
max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
|
|
||||||
edid = kmalloc(edid_size, GFP_KERNEL);
|
|
||||||
if (edid) {
|
|
||||||
memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
|
|
||||||
fake_edid_record->ucFakeEDIDLength);
|
|
||||||
|
|
||||||
|
if (fake_edid_record->ucFakeEDIDLength == 128)
|
||||||
|
edid_size = fake_edid_record->ucFakeEDIDLength;
|
||||||
|
else
|
||||||
|
edid_size = fake_edid_record->ucFakeEDIDLength * 128;
|
||||||
|
edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0],
|
||||||
|
edid_size, GFP_KERNEL);
|
||||||
|
if (edid) {
|
||||||
if (drm_edid_is_valid(edid)) {
|
if (drm_edid_is_valid(edid)) {
|
||||||
adev->mode_info.bios_hardcoded_edid = edid;
|
adev->mode_info.bios_hardcoded_edid = edid;
|
||||||
adev->mode_info.bios_hardcoded_edid_size = edid_size;
|
adev->mode_info.bios_hardcoded_edid_size = edid_size;
|
||||||
} else
|
} else {
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
record += struct_size(fake_edid_record,
|
||||||
|
ucFakeEDIDString,
|
||||||
|
edid_size);
|
||||||
|
} else {
|
||||||
|
/* empty fake edid record must be 3 bytes long */
|
||||||
|
record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
|
||||||
}
|
}
|
||||||
record += fake_edid_record->ucFakeEDIDLength ?
|
|
||||||
fake_edid_record->ucFakeEDIDLength + 2 :
|
|
||||||
sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
|
|
||||||
break;
|
break;
|
||||||
case LCD_PANEL_RESOLUTION_RECORD_TYPE:
|
case LCD_PANEL_RESOLUTION_RECORD_TYPE:
|
||||||
panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
|
panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
|
||||||
|
|||||||
@@ -1569,6 +1569,8 @@ static bool are_stream_backends_same(
|
|||||||
bool dc_is_stream_unchanged(
|
bool dc_is_stream_unchanged(
|
||||||
struct dc_stream_state *old_stream, struct dc_stream_state *stream)
|
struct dc_stream_state *old_stream, struct dc_stream_state *stream)
|
||||||
{
|
{
|
||||||
|
if (!old_stream || !stream)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!are_stream_backends_same(old_stream, stream))
|
if (!are_stream_backends_same(old_stream, stream))
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -482,6 +482,8 @@ bool cm_helper_translate_curve_to_degamma_hw_format(
|
|||||||
i += increment) {
|
i += increment) {
|
||||||
if (j == hw_points - 1)
|
if (j == hw_points - 1)
|
||||||
break;
|
break;
|
||||||
|
if (i >= TRANSFER_FUNC_POINTS)
|
||||||
|
return false;
|
||||||
rgb_resulted[j].red = output_tf->tf_pts.red[i];
|
rgb_resulted[j].red = output_tf->tf_pts.red[i];
|
||||||
rgb_resulted[j].green = output_tf->tf_pts.green[i];
|
rgb_resulted[j].green = output_tf->tf_pts.green[i];
|
||||||
rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
|
rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
|
||||||
|
|||||||
@@ -4106,8 +4106,8 @@ typedef struct _ATOM_LCD_MODE_CONTROL_CAP
|
|||||||
typedef struct _ATOM_FAKE_EDID_PATCH_RECORD
|
typedef struct _ATOM_FAKE_EDID_PATCH_RECORD
|
||||||
{
|
{
|
||||||
UCHAR ucRecordType;
|
UCHAR ucRecordType;
|
||||||
UCHAR ucFakeEDIDLength; // = 128 means EDID lenght is 128 bytes, otherwise the EDID length = ucFakeEDIDLength*128
|
UCHAR ucFakeEDIDLength; // = 128 means EDID length is 128 bytes, otherwise the EDID length = ucFakeEDIDLength*128
|
||||||
UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements.
|
UCHAR ucFakeEDIDString[]; // This actually has ucFakeEdidLength elements.
|
||||||
} ATOM_FAKE_EDID_PATCH_RECORD;
|
} ATOM_FAKE_EDID_PATCH_RECORD;
|
||||||
|
|
||||||
typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD
|
typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD
|
||||||
|
|||||||
@@ -567,9 +567,9 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
|
|||||||
struct drm_mode_crtc *crtc_req = data;
|
struct drm_mode_crtc *crtc_req = data;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
struct drm_plane *plane;
|
struct drm_plane *plane;
|
||||||
struct drm_connector **connector_set, *connector;
|
struct drm_connector **connector_set = NULL, *connector;
|
||||||
struct drm_framebuffer *fb;
|
struct drm_framebuffer *fb = NULL;
|
||||||
struct drm_display_mode *mode;
|
struct drm_display_mode *mode = NULL;
|
||||||
struct drm_mode_set set;
|
struct drm_mode_set set;
|
||||||
uint32_t __user *set_connectors_ptr;
|
uint32_t __user *set_connectors_ptr;
|
||||||
struct drm_modeset_acquire_ctx ctx;
|
struct drm_modeset_acquire_ctx ctx;
|
||||||
@@ -601,10 +601,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
|
|||||||
mutex_lock(&crtc->dev->mode_config.mutex);
|
mutex_lock(&crtc->dev->mode_config.mutex);
|
||||||
drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
|
drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
|
||||||
retry:
|
retry:
|
||||||
connector_set = NULL;
|
|
||||||
fb = NULL;
|
|
||||||
mode = NULL;
|
|
||||||
|
|
||||||
ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);
|
ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -767,6 +763,13 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
|
|||||||
}
|
}
|
||||||
kfree(connector_set);
|
kfree(connector_set);
|
||||||
drm_mode_destroy(dev, mode);
|
drm_mode_destroy(dev, mode);
|
||||||
|
|
||||||
|
/* In case we need to retry... */
|
||||||
|
connector_set = NULL;
|
||||||
|
fb = NULL;
|
||||||
|
mode = NULL;
|
||||||
|
num_connectors = 0;
|
||||||
|
|
||||||
if (ret == -EDEADLK) {
|
if (ret == -EDEADLK) {
|
||||||
ret = drm_modeset_backoff(&ctx);
|
ret = drm_modeset_backoff(&ctx);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
|||||||
@@ -54,8 +54,9 @@ void __drm_puts_coredump(struct drm_printer *p, const char *str)
|
|||||||
copy = iterator->remain;
|
copy = iterator->remain;
|
||||||
|
|
||||||
/* Copy out the bit of the string that we need */
|
/* Copy out the bit of the string that we need */
|
||||||
memcpy(iterator->data,
|
if (iterator->data)
|
||||||
str + (iterator->start - iterator->offset), copy);
|
memcpy(iterator->data,
|
||||||
|
str + (iterator->start - iterator->offset), copy);
|
||||||
|
|
||||||
iterator->offset = iterator->start + copy;
|
iterator->offset = iterator->start + copy;
|
||||||
iterator->remain -= copy;
|
iterator->remain -= copy;
|
||||||
@@ -64,7 +65,8 @@ void __drm_puts_coredump(struct drm_printer *p, const char *str)
|
|||||||
|
|
||||||
len = min_t(ssize_t, strlen(str), iterator->remain);
|
len = min_t(ssize_t, strlen(str), iterator->remain);
|
||||||
|
|
||||||
memcpy(iterator->data + pos, str, len);
|
if (iterator->data)
|
||||||
|
memcpy(iterator->data + pos, str, len);
|
||||||
|
|
||||||
iterator->offset += len;
|
iterator->offset += len;
|
||||||
iterator->remain -= len;
|
iterator->remain -= len;
|
||||||
@@ -94,8 +96,9 @@ void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
|
|||||||
if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {
|
if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {
|
||||||
ssize_t pos = iterator->offset - iterator->start;
|
ssize_t pos = iterator->offset - iterator->start;
|
||||||
|
|
||||||
snprintf(((char *) iterator->data) + pos,
|
if (iterator->data)
|
||||||
iterator->remain, "%pV", vaf);
|
snprintf(((char *) iterator->data) + pos,
|
||||||
|
iterator->remain, "%pV", vaf);
|
||||||
|
|
||||||
iterator->offset += len;
|
iterator->offset += len;
|
||||||
iterator->remain -= len;
|
iterator->remain -= len;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ struct a5xx_gpu {
|
|||||||
uint64_t preempt_iova[MSM_GPU_MAX_RINGS];
|
uint64_t preempt_iova[MSM_GPU_MAX_RINGS];
|
||||||
|
|
||||||
atomic_t preempt_state;
|
atomic_t preempt_state;
|
||||||
|
spinlock_t preempt_start_lock;
|
||||||
struct timer_list preempt_timer;
|
struct timer_list preempt_timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -107,12 +107,19 @@ void a5xx_preempt_trigger(struct msm_gpu *gpu)
|
|||||||
if (gpu->nr_rings == 1)
|
if (gpu->nr_rings == 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serialize preemption start to ensure that we always make
|
||||||
|
* decision on latest state. Otherwise we can get stuck in
|
||||||
|
* lower priority or empty ring.
|
||||||
|
*/
|
||||||
|
spin_lock_irqsave(&a5xx_gpu->preempt_start_lock, flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to start preemption by moving from NONE to START. If
|
* Try to start preemption by moving from NONE to START. If
|
||||||
* unsuccessful, a preemption is already in flight
|
* unsuccessful, a preemption is already in flight
|
||||||
*/
|
*/
|
||||||
if (!try_preempt_state(a5xx_gpu, PREEMPT_NONE, PREEMPT_START))
|
if (!try_preempt_state(a5xx_gpu, PREEMPT_NONE, PREEMPT_START))
|
||||||
return;
|
goto out;
|
||||||
|
|
||||||
/* Get the next ring to preempt to */
|
/* Get the next ring to preempt to */
|
||||||
ring = get_next_ring(gpu);
|
ring = get_next_ring(gpu);
|
||||||
@@ -137,9 +144,11 @@ void a5xx_preempt_trigger(struct msm_gpu *gpu)
|
|||||||
set_preempt_state(a5xx_gpu, PREEMPT_ABORT);
|
set_preempt_state(a5xx_gpu, PREEMPT_ABORT);
|
||||||
update_wptr(gpu, a5xx_gpu->cur_ring);
|
update_wptr(gpu, a5xx_gpu->cur_ring);
|
||||||
set_preempt_state(a5xx_gpu, PREEMPT_NONE);
|
set_preempt_state(a5xx_gpu, PREEMPT_NONE);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&a5xx_gpu->preempt_start_lock, flags);
|
||||||
|
|
||||||
/* Make sure the wptr doesn't update while we're in motion */
|
/* Make sure the wptr doesn't update while we're in motion */
|
||||||
spin_lock_irqsave(&ring->lock, flags);
|
spin_lock_irqsave(&ring->lock, flags);
|
||||||
a5xx_gpu->preempt[ring->id]->wptr = get_wptr(ring);
|
a5xx_gpu->preempt[ring->id]->wptr = get_wptr(ring);
|
||||||
@@ -163,6 +172,10 @@ void a5xx_preempt_trigger(struct msm_gpu *gpu)
|
|||||||
|
|
||||||
/* And actually start the preemption */
|
/* And actually start the preemption */
|
||||||
gpu_write(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL, 1);
|
gpu_write(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL, 1);
|
||||||
|
return;
|
||||||
|
|
||||||
|
out:
|
||||||
|
spin_unlock_irqrestore(&a5xx_gpu->preempt_start_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void a5xx_preempt_irq(struct msm_gpu *gpu)
|
void a5xx_preempt_irq(struct msm_gpu *gpu)
|
||||||
@@ -200,6 +213,12 @@ void a5xx_preempt_irq(struct msm_gpu *gpu)
|
|||||||
update_wptr(gpu, a5xx_gpu->cur_ring);
|
update_wptr(gpu, a5xx_gpu->cur_ring);
|
||||||
|
|
||||||
set_preempt_state(a5xx_gpu, PREEMPT_NONE);
|
set_preempt_state(a5xx_gpu, PREEMPT_NONE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to trigger preemption again in case there was a submit or
|
||||||
|
* retire during ring switch
|
||||||
|
*/
|
||||||
|
a5xx_preempt_trigger(gpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void a5xx_preempt_hw_init(struct msm_gpu *gpu)
|
void a5xx_preempt_hw_init(struct msm_gpu *gpu)
|
||||||
@@ -209,6 +228,8 @@ void a5xx_preempt_hw_init(struct msm_gpu *gpu)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < gpu->nr_rings; i++) {
|
for (i = 0; i < gpu->nr_rings; i++) {
|
||||||
|
a5xx_gpu->preempt[i]->data = 0;
|
||||||
|
a5xx_gpu->preempt[i]->info = 0;
|
||||||
a5xx_gpu->preempt[i]->wptr = 0;
|
a5xx_gpu->preempt[i]->wptr = 0;
|
||||||
a5xx_gpu->preempt[i]->rptr = 0;
|
a5xx_gpu->preempt[i]->rptr = 0;
|
||||||
a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova;
|
a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova;
|
||||||
@@ -300,5 +321,6 @@ void a5xx_preempt_init(struct msm_gpu *gpu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock_init(&a5xx_gpu->preempt_start_lock);
|
||||||
timer_setup(&a5xx_gpu->preempt_timer, a5xx_preempt_timer, 0);
|
timer_setup(&a5xx_gpu->preempt_timer, a5xx_preempt_timer, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ void mdp5_smp_dump(struct mdp5_smp *smp, struct drm_printer *p)
|
|||||||
|
|
||||||
drm_printf(p, "%s:%d\t%d\t%s\n",
|
drm_printf(p, "%s:%d\t%d\t%s\n",
|
||||||
pipe2name(pipe), j, inuse,
|
pipe2name(pipe), j, inuse,
|
||||||
plane ? plane->name : NULL);
|
plane ? plane->name : "(null)");
|
||||||
|
|
||||||
total += inuse;
|
total += inuse;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -671,7 +671,7 @@ static u32 dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_dual_dsi)
|
|||||||
struct drm_display_mode *mode = msm_host->mode;
|
struct drm_display_mode *mode = msm_host->mode;
|
||||||
u32 pclk_rate;
|
u32 pclk_rate;
|
||||||
|
|
||||||
pclk_rate = mode->clock * 1000;
|
pclk_rate = mode->clock * 1000u;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For dual DSI mode, the current DRM mode has the complete width of the
|
* For dual DSI mode, the current DRM mode has the complete width of the
|
||||||
|
|||||||
@@ -3615,7 +3615,7 @@ typedef struct _ATOM_FAKE_EDID_PATCH_RECORD
|
|||||||
{
|
{
|
||||||
UCHAR ucRecordType;
|
UCHAR ucRecordType;
|
||||||
UCHAR ucFakeEDIDLength;
|
UCHAR ucFakeEDIDLength;
|
||||||
UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements.
|
UCHAR ucFakeEDIDString[]; // This actually has ucFakeEdidLength elements.
|
||||||
} ATOM_FAKE_EDID_PATCH_RECORD;
|
} ATOM_FAKE_EDID_PATCH_RECORD;
|
||||||
|
|
||||||
typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD
|
typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
|
|||||||
struct evergreen_cs_track *track = p->track;
|
struct evergreen_cs_track *track = p->track;
|
||||||
struct eg_surface surf;
|
struct eg_surface surf;
|
||||||
unsigned pitch, slice, mslice;
|
unsigned pitch, slice, mslice;
|
||||||
unsigned long offset;
|
u64 offset;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
mslice = G_028C6C_SLICE_MAX(track->cb_color_view[id]) + 1;
|
mslice = G_028C6C_SLICE_MAX(track->cb_color_view[id]) + 1;
|
||||||
@@ -434,14 +434,14 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = track->cb_color_bo_offset[id] << 8;
|
offset = (u64)track->cb_color_bo_offset[id] << 8;
|
||||||
if (offset & (surf.base_align - 1)) {
|
if (offset & (surf.base_align - 1)) {
|
||||||
dev_warn(p->dev, "%s:%d cb[%d] bo base %ld not aligned with %ld\n",
|
dev_warn(p->dev, "%s:%d cb[%d] bo base %llu not aligned with %ld\n",
|
||||||
__func__, __LINE__, id, offset, surf.base_align);
|
__func__, __LINE__, id, offset, surf.base_align);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += surf.layer_size * mslice;
|
offset += (u64)surf.layer_size * mslice;
|
||||||
if (offset > radeon_bo_size(track->cb_color_bo[id])) {
|
if (offset > radeon_bo_size(track->cb_color_bo[id])) {
|
||||||
/* old ddx are broken they allocate bo with w*h*bpp but
|
/* old ddx are broken they allocate bo with w*h*bpp but
|
||||||
* program slice with ALIGN(h, 8), catch this and patch
|
* program slice with ALIGN(h, 8), catch this and patch
|
||||||
@@ -449,14 +449,14 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
|
|||||||
*/
|
*/
|
||||||
if (!surf.mode) {
|
if (!surf.mode) {
|
||||||
uint32_t *ib = p->ib.ptr;
|
uint32_t *ib = p->ib.ptr;
|
||||||
unsigned long tmp, nby, bsize, size, min = 0;
|
u64 tmp, nby, bsize, size, min = 0;
|
||||||
|
|
||||||
/* find the height the ddx wants */
|
/* find the height the ddx wants */
|
||||||
if (surf.nby > 8) {
|
if (surf.nby > 8) {
|
||||||
min = surf.nby - 8;
|
min = surf.nby - 8;
|
||||||
}
|
}
|
||||||
bsize = radeon_bo_size(track->cb_color_bo[id]);
|
bsize = radeon_bo_size(track->cb_color_bo[id]);
|
||||||
tmp = track->cb_color_bo_offset[id] << 8;
|
tmp = (u64)track->cb_color_bo_offset[id] << 8;
|
||||||
for (nby = surf.nby; nby > min; nby--) {
|
for (nby = surf.nby; nby > min; nby--) {
|
||||||
size = nby * surf.nbx * surf.bpe * surf.nsamples;
|
size = nby * surf.nbx * surf.bpe * surf.nsamples;
|
||||||
if ((tmp + size * mslice) <= bsize) {
|
if ((tmp + size * mslice) <= bsize) {
|
||||||
@@ -468,7 +468,7 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
|
|||||||
slice = ((nby * surf.nbx) / 64) - 1;
|
slice = ((nby * surf.nbx) / 64) - 1;
|
||||||
if (!evergreen_surface_check(p, &surf, "cb")) {
|
if (!evergreen_surface_check(p, &surf, "cb")) {
|
||||||
/* check if this one works */
|
/* check if this one works */
|
||||||
tmp += surf.layer_size * mslice;
|
tmp += (u64)surf.layer_size * mslice;
|
||||||
if (tmp <= bsize) {
|
if (tmp <= bsize) {
|
||||||
ib[track->cb_color_slice_idx[id]] = slice;
|
ib[track->cb_color_slice_idx[id]] = slice;
|
||||||
goto old_ddx_ok;
|
goto old_ddx_ok;
|
||||||
@@ -477,9 +477,9 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, "
|
dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, "
|
||||||
"offset %d, max layer %d, bo size %ld, slice %d)\n",
|
"offset %llu, max layer %d, bo size %ld, slice %d)\n",
|
||||||
__func__, __LINE__, id, surf.layer_size,
|
__func__, __LINE__, id, surf.layer_size,
|
||||||
track->cb_color_bo_offset[id] << 8, mslice,
|
(u64)track->cb_color_bo_offset[id] << 8, mslice,
|
||||||
radeon_bo_size(track->cb_color_bo[id]), slice);
|
radeon_bo_size(track->cb_color_bo[id]), slice);
|
||||||
dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n",
|
dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n",
|
||||||
__func__, __LINE__, surf.nbx, surf.nby,
|
__func__, __LINE__, surf.nbx, surf.nby,
|
||||||
@@ -563,7 +563,7 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
|
|||||||
struct evergreen_cs_track *track = p->track;
|
struct evergreen_cs_track *track = p->track;
|
||||||
struct eg_surface surf;
|
struct eg_surface surf;
|
||||||
unsigned pitch, slice, mslice;
|
unsigned pitch, slice, mslice;
|
||||||
unsigned long offset;
|
u64 offset;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
|
mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
|
||||||
@@ -609,18 +609,18 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = track->db_s_read_offset << 8;
|
offset = (u64)track->db_s_read_offset << 8;
|
||||||
if (offset & (surf.base_align - 1)) {
|
if (offset & (surf.base_align - 1)) {
|
||||||
dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n",
|
dev_warn(p->dev, "%s:%d stencil read bo base %llu not aligned with %ld\n",
|
||||||
__func__, __LINE__, offset, surf.base_align);
|
__func__, __LINE__, offset, surf.base_align);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
offset += surf.layer_size * mslice;
|
offset += (u64)surf.layer_size * mslice;
|
||||||
if (offset > radeon_bo_size(track->db_s_read_bo)) {
|
if (offset > radeon_bo_size(track->db_s_read_bo)) {
|
||||||
dev_warn(p->dev, "%s:%d stencil read bo too small (layer size %d, "
|
dev_warn(p->dev, "%s:%d stencil read bo too small (layer size %d, "
|
||||||
"offset %ld, max layer %d, bo size %ld)\n",
|
"offset %llu, max layer %d, bo size %ld)\n",
|
||||||
__func__, __LINE__, surf.layer_size,
|
__func__, __LINE__, surf.layer_size,
|
||||||
(unsigned long)track->db_s_read_offset << 8, mslice,
|
(u64)track->db_s_read_offset << 8, mslice,
|
||||||
radeon_bo_size(track->db_s_read_bo));
|
radeon_bo_size(track->db_s_read_bo));
|
||||||
dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
|
dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
|
||||||
__func__, __LINE__, track->db_depth_size,
|
__func__, __LINE__, track->db_depth_size,
|
||||||
@@ -628,18 +628,18 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = track->db_s_write_offset << 8;
|
offset = (u64)track->db_s_write_offset << 8;
|
||||||
if (offset & (surf.base_align - 1)) {
|
if (offset & (surf.base_align - 1)) {
|
||||||
dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n",
|
dev_warn(p->dev, "%s:%d stencil write bo base %llu not aligned with %ld\n",
|
||||||
__func__, __LINE__, offset, surf.base_align);
|
__func__, __LINE__, offset, surf.base_align);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
offset += surf.layer_size * mslice;
|
offset += (u64)surf.layer_size * mslice;
|
||||||
if (offset > radeon_bo_size(track->db_s_write_bo)) {
|
if (offset > radeon_bo_size(track->db_s_write_bo)) {
|
||||||
dev_warn(p->dev, "%s:%d stencil write bo too small (layer size %d, "
|
dev_warn(p->dev, "%s:%d stencil write bo too small (layer size %d, "
|
||||||
"offset %ld, max layer %d, bo size %ld)\n",
|
"offset %llu, max layer %d, bo size %ld)\n",
|
||||||
__func__, __LINE__, surf.layer_size,
|
__func__, __LINE__, surf.layer_size,
|
||||||
(unsigned long)track->db_s_write_offset << 8, mslice,
|
(u64)track->db_s_write_offset << 8, mslice,
|
||||||
radeon_bo_size(track->db_s_write_bo));
|
radeon_bo_size(track->db_s_write_bo));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -660,7 +660,7 @@ static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
|
|||||||
struct evergreen_cs_track *track = p->track;
|
struct evergreen_cs_track *track = p->track;
|
||||||
struct eg_surface surf;
|
struct eg_surface surf;
|
||||||
unsigned pitch, slice, mslice;
|
unsigned pitch, slice, mslice;
|
||||||
unsigned long offset;
|
u64 offset;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
|
mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
|
||||||
@@ -707,34 +707,34 @@ static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = track->db_z_read_offset << 8;
|
offset = (u64)track->db_z_read_offset << 8;
|
||||||
if (offset & (surf.base_align - 1)) {
|
if (offset & (surf.base_align - 1)) {
|
||||||
dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n",
|
dev_warn(p->dev, "%s:%d stencil read bo base %llu not aligned with %ld\n",
|
||||||
__func__, __LINE__, offset, surf.base_align);
|
__func__, __LINE__, offset, surf.base_align);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
offset += surf.layer_size * mslice;
|
offset += (u64)surf.layer_size * mslice;
|
||||||
if (offset > radeon_bo_size(track->db_z_read_bo)) {
|
if (offset > radeon_bo_size(track->db_z_read_bo)) {
|
||||||
dev_warn(p->dev, "%s:%d depth read bo too small (layer size %d, "
|
dev_warn(p->dev, "%s:%d depth read bo too small (layer size %d, "
|
||||||
"offset %ld, max layer %d, bo size %ld)\n",
|
"offset %llu, max layer %d, bo size %ld)\n",
|
||||||
__func__, __LINE__, surf.layer_size,
|
__func__, __LINE__, surf.layer_size,
|
||||||
(unsigned long)track->db_z_read_offset << 8, mslice,
|
(u64)track->db_z_read_offset << 8, mslice,
|
||||||
radeon_bo_size(track->db_z_read_bo));
|
radeon_bo_size(track->db_z_read_bo));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = track->db_z_write_offset << 8;
|
offset = (u64)track->db_z_write_offset << 8;
|
||||||
if (offset & (surf.base_align - 1)) {
|
if (offset & (surf.base_align - 1)) {
|
||||||
dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n",
|
dev_warn(p->dev, "%s:%d stencil write bo base %llu not aligned with %ld\n",
|
||||||
__func__, __LINE__, offset, surf.base_align);
|
__func__, __LINE__, offset, surf.base_align);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
offset += surf.layer_size * mslice;
|
offset += (u64)surf.layer_size * mslice;
|
||||||
if (offset > radeon_bo_size(track->db_z_write_bo)) {
|
if (offset > radeon_bo_size(track->db_z_write_bo)) {
|
||||||
dev_warn(p->dev, "%s:%d depth write bo too small (layer size %d, "
|
dev_warn(p->dev, "%s:%d depth write bo too small (layer size %d, "
|
||||||
"offset %ld, max layer %d, bo size %ld)\n",
|
"offset %llu, max layer %d, bo size %ld)\n",
|
||||||
__func__, __LINE__, surf.layer_size,
|
__func__, __LINE__, surf.layer_size,
|
||||||
(unsigned long)track->db_z_write_offset << 8, mslice,
|
(u64)track->db_z_write_offset << 8, mslice,
|
||||||
radeon_bo_size(track->db_z_write_bo));
|
radeon_bo_size(track->db_z_write_bo));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -999,45 +999,65 @@ static int r100_cp_init_microcode(struct radeon_device *rdev)
|
|||||||
|
|
||||||
DRM_DEBUG_KMS("\n");
|
DRM_DEBUG_KMS("\n");
|
||||||
|
|
||||||
if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) ||
|
switch (rdev->family) {
|
||||||
(rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) ||
|
case CHIP_R100:
|
||||||
(rdev->family == CHIP_RS200)) {
|
case CHIP_RV100:
|
||||||
|
case CHIP_RV200:
|
||||||
|
case CHIP_RS100:
|
||||||
|
case CHIP_RS200:
|
||||||
DRM_INFO("Loading R100 Microcode\n");
|
DRM_INFO("Loading R100 Microcode\n");
|
||||||
fw_name = FIRMWARE_R100;
|
fw_name = FIRMWARE_R100;
|
||||||
} else if ((rdev->family == CHIP_R200) ||
|
break;
|
||||||
(rdev->family == CHIP_RV250) ||
|
|
||||||
(rdev->family == CHIP_RV280) ||
|
case CHIP_R200:
|
||||||
(rdev->family == CHIP_RS300)) {
|
case CHIP_RV250:
|
||||||
|
case CHIP_RV280:
|
||||||
|
case CHIP_RS300:
|
||||||
DRM_INFO("Loading R200 Microcode\n");
|
DRM_INFO("Loading R200 Microcode\n");
|
||||||
fw_name = FIRMWARE_R200;
|
fw_name = FIRMWARE_R200;
|
||||||
} else if ((rdev->family == CHIP_R300) ||
|
break;
|
||||||
(rdev->family == CHIP_R350) ||
|
|
||||||
(rdev->family == CHIP_RV350) ||
|
case CHIP_R300:
|
||||||
(rdev->family == CHIP_RV380) ||
|
case CHIP_R350:
|
||||||
(rdev->family == CHIP_RS400) ||
|
case CHIP_RV350:
|
||||||
(rdev->family == CHIP_RS480)) {
|
case CHIP_RV380:
|
||||||
|
case CHIP_RS400:
|
||||||
|
case CHIP_RS480:
|
||||||
DRM_INFO("Loading R300 Microcode\n");
|
DRM_INFO("Loading R300 Microcode\n");
|
||||||
fw_name = FIRMWARE_R300;
|
fw_name = FIRMWARE_R300;
|
||||||
} else if ((rdev->family == CHIP_R420) ||
|
break;
|
||||||
(rdev->family == CHIP_R423) ||
|
|
||||||
(rdev->family == CHIP_RV410)) {
|
case CHIP_R420:
|
||||||
|
case CHIP_R423:
|
||||||
|
case CHIP_RV410:
|
||||||
DRM_INFO("Loading R400 Microcode\n");
|
DRM_INFO("Loading R400 Microcode\n");
|
||||||
fw_name = FIRMWARE_R420;
|
fw_name = FIRMWARE_R420;
|
||||||
} else if ((rdev->family == CHIP_RS690) ||
|
break;
|
||||||
(rdev->family == CHIP_RS740)) {
|
|
||||||
|
case CHIP_RS690:
|
||||||
|
case CHIP_RS740:
|
||||||
DRM_INFO("Loading RS690/RS740 Microcode\n");
|
DRM_INFO("Loading RS690/RS740 Microcode\n");
|
||||||
fw_name = FIRMWARE_RS690;
|
fw_name = FIRMWARE_RS690;
|
||||||
} else if (rdev->family == CHIP_RS600) {
|
break;
|
||||||
|
|
||||||
|
case CHIP_RS600:
|
||||||
DRM_INFO("Loading RS600 Microcode\n");
|
DRM_INFO("Loading RS600 Microcode\n");
|
||||||
fw_name = FIRMWARE_RS600;
|
fw_name = FIRMWARE_RS600;
|
||||||
} else if ((rdev->family == CHIP_RV515) ||
|
break;
|
||||||
(rdev->family == CHIP_R520) ||
|
|
||||||
(rdev->family == CHIP_RV530) ||
|
case CHIP_RV515:
|
||||||
(rdev->family == CHIP_R580) ||
|
case CHIP_R520:
|
||||||
(rdev->family == CHIP_RV560) ||
|
case CHIP_RV530:
|
||||||
(rdev->family == CHIP_RV570)) {
|
case CHIP_R580:
|
||||||
|
case CHIP_RV560:
|
||||||
|
case CHIP_RV570:
|
||||||
DRM_INFO("Loading R500 Microcode\n");
|
DRM_INFO("Loading R500 Microcode\n");
|
||||||
fw_name = FIRMWARE_R520;
|
fw_name = FIRMWARE_R520;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DRM_ERROR("Unsupported Radeon family %u\n", rdev->family);
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
|
err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
|
||||||
|
|||||||
@@ -1727,23 +1727,29 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
|
|||||||
fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
|
fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
|
||||||
if (fake_edid_record->ucFakeEDIDLength) {
|
if (fake_edid_record->ucFakeEDIDLength) {
|
||||||
struct edid *edid;
|
struct edid *edid;
|
||||||
int edid_size =
|
int edid_size;
|
||||||
max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
|
|
||||||
edid = kmalloc(edid_size, GFP_KERNEL);
|
|
||||||
if (edid) {
|
|
||||||
memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
|
|
||||||
fake_edid_record->ucFakeEDIDLength);
|
|
||||||
|
|
||||||
|
if (fake_edid_record->ucFakeEDIDLength == 128)
|
||||||
|
edid_size = fake_edid_record->ucFakeEDIDLength;
|
||||||
|
else
|
||||||
|
edid_size = fake_edid_record->ucFakeEDIDLength * 128;
|
||||||
|
edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0],
|
||||||
|
edid_size, GFP_KERNEL);
|
||||||
|
if (edid) {
|
||||||
if (drm_edid_is_valid(edid)) {
|
if (drm_edid_is_valid(edid)) {
|
||||||
rdev->mode_info.bios_hardcoded_edid = edid;
|
rdev->mode_info.bios_hardcoded_edid = edid;
|
||||||
rdev->mode_info.bios_hardcoded_edid_size = edid_size;
|
rdev->mode_info.bios_hardcoded_edid_size = edid_size;
|
||||||
} else
|
} else {
|
||||||
kfree(edid);
|
kfree(edid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
record += struct_size(fake_edid_record,
|
||||||
|
ucFakeEDIDString,
|
||||||
|
edid_size);
|
||||||
|
} else {
|
||||||
|
/* empty fake edid record must be 3 bytes long */
|
||||||
|
record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
|
||||||
}
|
}
|
||||||
record += fake_edid_record->ucFakeEDIDLength ?
|
|
||||||
fake_edid_record->ucFakeEDIDLength + 2 :
|
|
||||||
sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
|
|
||||||
break;
|
break;
|
||||||
case LCD_PANEL_RESOLUTION_RECORD_TYPE:
|
case LCD_PANEL_RESOLUTION_RECORD_TYPE:
|
||||||
panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
|
panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
|
||||||
|
|||||||
@@ -308,8 +308,8 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
|
|||||||
if (info->is_yuv)
|
if (info->is_yuv)
|
||||||
is_yuv = true;
|
is_yuv = true;
|
||||||
|
|
||||||
if (dst_w > 3840) {
|
if (dst_w > 4096) {
|
||||||
DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n");
|
DRM_DEV_ERROR(vop->dev, "Maximum dst width (4096) exceeded\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -152,10 +152,12 @@ static int stm_drm_platform_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
ret = drm_dev_register(ddev, 0);
|
ret = drm_dev_register(ddev, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_put;
|
goto err_unload;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_unload:
|
||||||
|
drv_unload(ddev);
|
||||||
err_put:
|
err_put:
|
||||||
drm_dev_put(ddev);
|
drm_dev_put(ddev);
|
||||||
|
|
||||||
|
|||||||
@@ -1468,6 +1468,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
|
|||||||
DRM_ERROR("Surface size cannot exceed %dx%d",
|
DRM_ERROR("Surface size cannot exceed %dx%d",
|
||||||
dev_priv->texture_max_width,
|
dev_priv->texture_max_width,
|
||||||
dev_priv->texture_max_height);
|
dev_priv->texture_max_height);
|
||||||
|
ret = -EINVAL;
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1482,7 +1482,7 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags)
|
|||||||
|
|
||||||
u32 len = hid_report_len(report) + 7;
|
u32 len = hid_report_len(report) + 7;
|
||||||
|
|
||||||
return kmalloc(len, flags);
|
return kzalloc(len, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(hid_alloc_report_buf);
|
EXPORT_SYMBOL_GPL(hid_alloc_report_buf);
|
||||||
|
|
||||||
|
|||||||
@@ -919,6 +919,8 @@
|
|||||||
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056
|
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056
|
||||||
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057
|
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057
|
||||||
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES 0xc058
|
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES 0xc058
|
||||||
|
#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES 0x430c
|
||||||
|
#define USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES 0x431e
|
||||||
|
|
||||||
#define USB_VENDOR_ID_PANASONIC 0x04da
|
#define USB_VENDOR_ID_PANASONIC 0x04da
|
||||||
#define USB_DEVICE_ID_PANABOARD_UBT780 0x1044
|
#define USB_DEVICE_ID_PANABOARD_UBT780 0x1044
|
||||||
|
|||||||
@@ -1986,6 +1986,11 @@ static const struct hid_device_id mt_devices[] = {
|
|||||||
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
|
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
|
||||||
0x347d, 0x7853) },
|
0x347d, 0x7853) },
|
||||||
|
|
||||||
|
/* HONOR MagicBook Art 14 touchpad */
|
||||||
|
{ .driver_data = MT_CLS_VTL,
|
||||||
|
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
|
||||||
|
0x35cc, 0x0104) },
|
||||||
|
|
||||||
/* Ilitek dual touch panel */
|
/* Ilitek dual touch panel */
|
||||||
{ .driver_data = MT_CLS_NSMU,
|
{ .driver_data = MT_CLS_NSMU,
|
||||||
MT_USB_DEVICE(USB_VENDOR_ID_ILITEK,
|
MT_USB_DEVICE(USB_VENDOR_ID_ILITEK,
|
||||||
|
|||||||
@@ -41,8 +41,10 @@
|
|||||||
(usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER)
|
(usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER)
|
||||||
|
|
||||||
#define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0)
|
#define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0)
|
||||||
|
#define PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS BIT(1)
|
||||||
|
|
||||||
#define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */
|
#define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */
|
||||||
|
#define PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT 220 /* ms */
|
||||||
|
|
||||||
struct plt_drv_data {
|
struct plt_drv_data {
|
||||||
unsigned long device_type;
|
unsigned long device_type;
|
||||||
@@ -140,6 +142,21 @@ static int plantronics_event(struct hid_device *hdev, struct hid_field *field,
|
|||||||
|
|
||||||
drv_data->last_volume_key_ts = cur_ts;
|
drv_data->last_volume_key_ts = cur_ts;
|
||||||
}
|
}
|
||||||
|
if (drv_data->quirks & PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS) {
|
||||||
|
unsigned long prev_ts, cur_ts;
|
||||||
|
|
||||||
|
/* Usages are filtered in plantronics_usages. */
|
||||||
|
|
||||||
|
if (!value) /* Handle key presses only. */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
prev_ts = drv_data->last_volume_key_ts;
|
||||||
|
cur_ts = jiffies;
|
||||||
|
if (jiffies_to_msecs(cur_ts - prev_ts) <= PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT)
|
||||||
|
return 1; /* Ignore the followed opposite volume key. */
|
||||||
|
|
||||||
|
drv_data->last_volume_key_ts = cur_ts;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -213,6 +230,12 @@ static const struct hid_device_id plantronics_devices[] = {
|
|||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
|
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
|
||||||
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
|
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
|
||||||
.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
|
.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
|
||||||
|
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES),
|
||||||
|
.driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
|
||||||
|
USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES),
|
||||||
|
.driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -117,9 +117,10 @@ static inline int LIMIT_TO_MV(int limit, int range)
|
|||||||
return limit * range / 256;
|
return limit * range / 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int MV_TO_LIMIT(int mv, int range)
|
static inline int MV_TO_LIMIT(unsigned long mv, int range)
|
||||||
{
|
{
|
||||||
return clamp_val(DIV_ROUND_CLOSEST(mv * 256, range), 0, 255);
|
mv = clamp_val(mv, 0, ULONG_MAX / 256);
|
||||||
|
return DIV_ROUND_CLOSEST(clamp_val(mv * 256, 0, range * 255), range);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ADC_TO_CURR(int adc, int gain)
|
static inline int ADC_TO_CURR(int adc, int gain)
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ static const struct platform_device_id ntc_thermistor_id[] = {
|
|||||||
{ "ncp15xh103", TYPE_NCPXXXH103 },
|
{ "ncp15xh103", TYPE_NCPXXXH103 },
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
MODULE_DEVICE_TABLE(platform, ntc_thermistor_id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A compensation table should be sorted by the values of .ohm
|
* A compensation table should be sorted by the values of .ohm
|
||||||
|
|||||||
@@ -251,6 +251,7 @@ void tmc_free_sg_table(struct tmc_sg_table *sg_table)
|
|||||||
{
|
{
|
||||||
tmc_free_table_pages(sg_table);
|
tmc_free_table_pages(sg_table);
|
||||||
tmc_free_data_pages(sg_table);
|
tmc_free_data_pages(sg_table);
|
||||||
|
kfree(sg_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
long tmc_sg_get_rwp_offset(struct tmc_drvdata *drvdata)
|
long tmc_sg_get_rwp_offset(struct tmc_drvdata *drvdata)
|
||||||
@@ -345,7 +346,6 @@ struct tmc_sg_table *tmc_alloc_sg_table(struct device *dev,
|
|||||||
rc = tmc_alloc_table_pages(sg_table);
|
rc = tmc_alloc_table_pages(sg_table);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
tmc_free_sg_table(sg_table);
|
tmc_free_sg_table(sg_table);
|
||||||
kfree(sg_table);
|
|
||||||
return ERR_PTR(rc);
|
return ERR_PTR(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -159,6 +159,13 @@ struct aspeed_i2c_bus {
|
|||||||
|
|
||||||
static int aspeed_i2c_reset(struct aspeed_i2c_bus *bus);
|
static int aspeed_i2c_reset(struct aspeed_i2c_bus *bus);
|
||||||
|
|
||||||
|
/* precondition: bus.lock has been acquired. */
|
||||||
|
static void aspeed_i2c_do_stop(struct aspeed_i2c_bus *bus)
|
||||||
|
{
|
||||||
|
bus->master_state = ASPEED_I2C_MASTER_STOP;
|
||||||
|
writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG);
|
||||||
|
}
|
||||||
|
|
||||||
static int aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus)
|
static int aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus)
|
||||||
{
|
{
|
||||||
unsigned long time_left, flags;
|
unsigned long time_left, flags;
|
||||||
@@ -176,7 +183,7 @@ static int aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus)
|
|||||||
command);
|
command);
|
||||||
|
|
||||||
reinit_completion(&bus->cmd_complete);
|
reinit_completion(&bus->cmd_complete);
|
||||||
writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG);
|
aspeed_i2c_do_stop(bus);
|
||||||
spin_unlock_irqrestore(&bus->lock, flags);
|
spin_unlock_irqrestore(&bus->lock, flags);
|
||||||
|
|
||||||
time_left = wait_for_completion_timeout(
|
time_left = wait_for_completion_timeout(
|
||||||
@@ -350,13 +357,6 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus)
|
|||||||
writel(command, bus->base + ASPEED_I2C_CMD_REG);
|
writel(command, bus->base + ASPEED_I2C_CMD_REG);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* precondition: bus.lock has been acquired. */
|
|
||||||
static void aspeed_i2c_do_stop(struct aspeed_i2c_bus *bus)
|
|
||||||
{
|
|
||||||
bus->master_state = ASPEED_I2C_MASTER_STOP;
|
|
||||||
writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* precondition: bus.lock has been acquired. */
|
/* precondition: bus.lock has been acquired. */
|
||||||
static void aspeed_i2c_next_msg_or_stop(struct aspeed_i2c_bus *bus)
|
static void aspeed_i2c_next_msg_or_stop(struct aspeed_i2c_bus *bus)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1674,8 +1674,15 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||||||
|
|
||||||
i801_add_tco(priv);
|
i801_add_tco(priv);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* adapter.name is used by platform code to find the main I801 adapter
|
||||||
|
* to instantiante i2c_clients, do not change.
|
||||||
|
*/
|
||||||
snprintf(priv->adapter.name, sizeof(priv->adapter.name),
|
snprintf(priv->adapter.name, sizeof(priv->adapter.name),
|
||||||
"SMBus I801 adapter at %04lx", priv->smba);
|
"SMBus %s adapter at %04lx",
|
||||||
|
(priv->features & FEATURE_IDF) ? "I801 IDF" : "I801",
|
||||||
|
priv->smba);
|
||||||
|
|
||||||
err = i2c_add_adapter(&priv->adapter);
|
err = i2c_add_adapter(&priv->adapter);
|
||||||
if (err) {
|
if (err) {
|
||||||
platform_device_unregister(priv->tco_pdev);
|
platform_device_unregister(priv->tco_pdev);
|
||||||
|
|||||||
@@ -107,8 +107,7 @@ static int sch_transaction(void)
|
|||||||
if (retries > MAX_RETRIES) {
|
if (retries > MAX_RETRIES) {
|
||||||
dev_err(&sch_adapter.dev, "SMBus Timeout!\n");
|
dev_err(&sch_adapter.dev, "SMBus Timeout!\n");
|
||||||
result = -ETIMEDOUT;
|
result = -ETIMEDOUT;
|
||||||
}
|
} else if (temp & 0x04) {
|
||||||
if (temp & 0x04) {
|
|
||||||
result = -EIO;
|
result = -EIO;
|
||||||
dev_dbg(&sch_adapter.dev, "Bus collision! SMBus may be "
|
dev_dbg(&sch_adapter.dev, "Bus collision! SMBus may be "
|
||||||
"locked until next hard reset. (sorry!)\n");
|
"locked until next hard reset. (sorry!)\n");
|
||||||
|
|||||||
@@ -478,14 +478,17 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
xiic_fill_tx_fifo(i2c);
|
if (xiic_tx_space(i2c)) {
|
||||||
|
xiic_fill_tx_fifo(i2c);
|
||||||
/* current message sent and there is space in the fifo */
|
} else {
|
||||||
if (!xiic_tx_space(i2c) && xiic_tx_fifo_space(i2c) >= 2) {
|
/* current message fully written */
|
||||||
dev_dbg(i2c->adap.dev.parent,
|
dev_dbg(i2c->adap.dev.parent,
|
||||||
"%s end of message sent, nmsgs: %d\n",
|
"%s end of message sent, nmsgs: %d\n",
|
||||||
__func__, i2c->nmsgs);
|
__func__, i2c->nmsgs);
|
||||||
if (i2c->nmsgs > 1) {
|
/* Don't move onto the next message until the TX FIFO empties,
|
||||||
|
* to ensure that a NAK is not missed.
|
||||||
|
*/
|
||||||
|
if (i2c->nmsgs > 1 && (pend & XIIC_INTR_TX_EMPTY_MASK)) {
|
||||||
i2c->nmsgs--;
|
i2c->nmsgs--;
|
||||||
i2c->tx_msg++;
|
i2c->tx_msg++;
|
||||||
xfer_more = 1;
|
xfer_more = 1;
|
||||||
@@ -496,11 +499,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id)
|
|||||||
"%s Got TX IRQ but no more to do...\n",
|
"%s Got TX IRQ but no more to do...\n",
|
||||||
__func__);
|
__func__);
|
||||||
}
|
}
|
||||||
} else if (!xiic_tx_space(i2c) && (i2c->nmsgs == 1))
|
}
|
||||||
/* current frame is sent and is last,
|
|
||||||
* make sure to disable tx half
|
|
||||||
*/
|
|
||||||
xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr);
|
dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr);
|
||||||
|
|||||||
@@ -896,6 +896,8 @@ config TI_ADS7950
|
|||||||
config TI_ADS8688
|
config TI_ADS8688
|
||||||
tristate "Texas Instruments ADS8688"
|
tristate "Texas Instruments ADS8688"
|
||||||
depends on SPI && OF
|
depends on SPI && OF
|
||||||
|
select IIO_BUFFER
|
||||||
|
select IIO_TRIGGERED_BUFFER
|
||||||
help
|
help
|
||||||
If you say yes here you get support for Texas Instruments ADS8684 and
|
If you say yes here you get support for Texas Instruments ADS8684 and
|
||||||
and ADS8688 ADC chips
|
and ADS8688 ADC chips
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ static ssize_t _hid_sensor_set_report_latency(struct device *dev,
|
|||||||
latency = integer * 1000 + fract / 1000;
|
latency = integer * 1000 + fract / 1000;
|
||||||
ret = hid_sensor_set_report_latency(attrb, latency);
|
ret = hid_sensor_set_report_latency(attrb, latency);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return len;
|
return ret;
|
||||||
|
|
||||||
attrb->latency_ms = hid_sensor_get_report_latency(attrb);
|
attrb->latency_ms = hid_sensor_get_report_latency(attrb);
|
||||||
|
|
||||||
|
|||||||
@@ -335,6 +335,7 @@ config STM32_DAC
|
|||||||
|
|
||||||
config STM32_DAC_CORE
|
config STM32_DAC_CORE
|
||||||
tristate
|
tristate
|
||||||
|
select REGMAP_MMIO
|
||||||
|
|
||||||
config TI_DAC082S085
|
config TI_DAC082S085
|
||||||
tristate "Texas Instruments 8/10/12-bit 2/4-channel DAC driver"
|
tristate "Texas Instruments 8/10/12-bit 2/4-channel DAC driver"
|
||||||
|
|||||||
@@ -145,6 +145,10 @@ static const struct opt3001_scale opt3001_scales[] = {
|
|||||||
.val = 20966,
|
.val = 20966,
|
||||||
.val2 = 400000,
|
.val2 = 400000,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.val = 41932,
|
||||||
|
.val2 = 800000,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.val = 83865,
|
.val = 83865,
|
||||||
.val2 = 600000,
|
.val2 = 600000,
|
||||||
|
|||||||
@@ -673,22 +673,8 @@ static int ak8975_start_read_axis(struct ak8975_data *data,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* This will be executed only for non-interrupt based waiting case */
|
/* Return with zero if the data is ready. */
|
||||||
if (ret & data->def->ctrl_masks[ST1_DRDY]) {
|
return !data->def->ctrl_regs[ST1_DRDY];
|
||||||
ret = i2c_smbus_read_byte_data(client,
|
|
||||||
data->def->ctrl_regs[ST2]);
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_err(&client->dev, "Error in reading ST2\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if (ret & (data->def->ctrl_masks[ST2_DERR] |
|
|
||||||
data->def->ctrl_masks[ST2_HOFL])) {
|
|
||||||
dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve raw flux value for one of the x, y, or z axis. */
|
/* Retrieve raw flux value for one of the x, y, or z axis. */
|
||||||
@@ -715,6 +701,20 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
/* Read out ST2 for release lock on measurment data. */
|
||||||
|
ret = i2c_smbus_read_byte_data(client, data->def->ctrl_regs[ST2]);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(&client->dev, "Error in reading ST2\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret & (data->def->ctrl_masks[ST2_DERR] |
|
||||||
|
data->def->ctrl_masks[ST2_HOFL])) {
|
||||||
|
dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
mutex_unlock(&data->lock);
|
mutex_unlock(&data->lock);
|
||||||
|
|
||||||
pm_runtime_mark_last_busy(&data->client->dev);
|
pm_runtime_mark_last_busy(&data->client->dev);
|
||||||
|
|||||||
@@ -1178,7 +1178,7 @@ static int __init iw_cm_init(void)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", 0);
|
iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", WQ_MEM_RECLAIM);
|
||||||
if (!iwcm_wq)
|
if (!iwcm_wq)
|
||||||
goto err_alloc;
|
goto err_alloc;
|
||||||
|
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ struct bnxt_qplib_swqe {
|
|||||||
};
|
};
|
||||||
u32 q_key;
|
u32 q_key;
|
||||||
u32 dst_qp;
|
u32 dst_qp;
|
||||||
u16 avid;
|
u32 avid;
|
||||||
} send;
|
} send;
|
||||||
|
|
||||||
/* Send Raw Ethernet and QP1 */
|
/* Send Raw Ethernet and QP1 */
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user