mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-19 15:57:01 +07:00
Merge branch 'ib-pdx86-properties'
Merge branch 'ib-pdx86-properties' of git://git.infradead.org/linux-platform-drivers-x86.git to avoid conflicts in PDx86. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
This commit is contained in:
commit
f7ea285b62
@ -390,9 +390,17 @@ When ``kptr_restrict`` is set to 2, kernel pointers printed using
|
|||||||
modprobe
|
modprobe
|
||||||
========
|
========
|
||||||
|
|
||||||
This gives the full path of the modprobe command which the kernel will
|
The full path to the usermode helper for autoloading kernel modules,
|
||||||
use to load modules. This can be used to debug module loading
|
by default "/sbin/modprobe". This binary is executed when the kernel
|
||||||
requests::
|
requests a module. For example, if userspace passes an unknown
|
||||||
|
filesystem type to mount(), then the kernel will automatically request
|
||||||
|
the corresponding filesystem module by executing this usermode helper.
|
||||||
|
This usermode helper should insert the needed module into the kernel.
|
||||||
|
|
||||||
|
This sysctl only affects module autoloading. It has no effect on the
|
||||||
|
ability to explicitly insert modules.
|
||||||
|
|
||||||
|
This sysctl can be used to debug module loading requests::
|
||||||
|
|
||||||
echo '#! /bin/sh' > /tmp/modprobe
|
echo '#! /bin/sh' > /tmp/modprobe
|
||||||
echo 'echo "$@" >> /tmp/modprobe.log' >> /tmp/modprobe
|
echo 'echo "$@" >> /tmp/modprobe.log' >> /tmp/modprobe
|
||||||
@ -400,10 +408,15 @@ requests::
|
|||||||
chmod a+x /tmp/modprobe
|
chmod a+x /tmp/modprobe
|
||||||
echo /tmp/modprobe > /proc/sys/kernel/modprobe
|
echo /tmp/modprobe > /proc/sys/kernel/modprobe
|
||||||
|
|
||||||
This only applies when the *kernel* is requesting that the module be
|
Alternatively, if this sysctl is set to the empty string, then module
|
||||||
loaded; it won't have any effect if the module is being loaded
|
autoloading is completely disabled. The kernel will not try to
|
||||||
explicitly using ``modprobe`` from userspace.
|
execute a usermode helper at all, nor will it call the
|
||||||
|
kernel_module_request LSM hook.
|
||||||
|
|
||||||
|
If CONFIG_STATIC_USERMODEHELPER=y is set in the kernel configuration,
|
||||||
|
then the configured static usermode helper overrides this sysctl,
|
||||||
|
except that the empty string is still accepted to completely disable
|
||||||
|
module autoloading as described above.
|
||||||
|
|
||||||
modules_disabled
|
modules_disabled
|
||||||
================
|
================
|
||||||
@ -446,28 +459,6 @@ Notes:
|
|||||||
successful IPC object allocation. If an IPC object allocation syscall
|
successful IPC object allocation. If an IPC object allocation syscall
|
||||||
fails, it is undefined if the value remains unmodified or is reset to -1.
|
fails, it is undefined if the value remains unmodified or is reset to -1.
|
||||||
|
|
||||||
modprobe:
|
|
||||||
=========
|
|
||||||
|
|
||||||
The path to the usermode helper for autoloading kernel modules, by
|
|
||||||
default "/sbin/modprobe". This binary is executed when the kernel
|
|
||||||
requests a module. For example, if userspace passes an unknown
|
|
||||||
filesystem type to mount(), then the kernel will automatically request
|
|
||||||
the corresponding filesystem module by executing this usermode helper.
|
|
||||||
This usermode helper should insert the needed module into the kernel.
|
|
||||||
|
|
||||||
This sysctl only affects module autoloading. It has no effect on the
|
|
||||||
ability to explicitly insert modules.
|
|
||||||
|
|
||||||
If this sysctl is set to the empty string, then module autoloading is
|
|
||||||
completely disabled. The kernel will not try to execute a usermode
|
|
||||||
helper at all, nor will it call the kernel_module_request LSM hook.
|
|
||||||
|
|
||||||
If CONFIG_STATIC_USERMODEHELPER=y is set in the kernel configuration,
|
|
||||||
then the configured static usermode helper overrides this sysctl,
|
|
||||||
except that the empty string is still accepted to completely disable
|
|
||||||
module autoloading as described above.
|
|
||||||
|
|
||||||
nmi_watchdog
|
nmi_watchdog
|
||||||
============
|
============
|
||||||
|
|
||||||
|
@ -154,9 +154,9 @@ architectures. These are the recommended replacements:
|
|||||||
|
|
||||||
Use ktime_get() or ktime_get_ts64() instead.
|
Use ktime_get() or ktime_get_ts64() instead.
|
||||||
|
|
||||||
.. c:function:: struct timeval do_gettimeofday( void )
|
.. c:function:: void do_gettimeofday( struct timeval * )
|
||||||
struct timespec getnstimeofday( void )
|
void getnstimeofday( struct timespec * )
|
||||||
struct timespec64 getnstimeofday64( void )
|
void getnstimeofday64( struct timespec64 * )
|
||||||
void ktime_get_real_ts( struct timespec * )
|
void ktime_get_real_ts( struct timespec * )
|
||||||
|
|
||||||
ktime_get_real_ts64() is a direct replacement, but consider using
|
ktime_get_real_ts64() is a direct replacement, but consider using
|
||||||
|
@ -42,6 +42,10 @@ properties:
|
|||||||
description:
|
description:
|
||||||
See section 2.3.9 of the DeviceTree Specification.
|
See section 2.3.9 of the DeviceTree Specification.
|
||||||
|
|
||||||
|
'#address-cells': true
|
||||||
|
|
||||||
|
'#size-cells': true
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- "#interconnect-cells"
|
- "#interconnect-cells"
|
||||||
- compatible
|
- compatible
|
||||||
@ -59,6 +63,8 @@ examples:
|
|||||||
compatible = "allwinner,sun5i-a13-mbus";
|
compatible = "allwinner,sun5i-a13-mbus";
|
||||||
reg = <0x01c01000 0x1000>;
|
reg = <0x01c01000 0x1000>;
|
||||||
clocks = <&ccu CLK_MBUS>;
|
clocks = <&ccu CLK_MBUS>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
dma-ranges = <0x00000000 0x40000000 0x20000000>;
|
dma-ranges = <0x00000000 0x40000000 0x20000000>;
|
||||||
#interconnect-cells = <1>;
|
#interconnect-cells = <1>;
|
||||||
};
|
};
|
||||||
|
@ -91,7 +91,7 @@ required:
|
|||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
vco1: clock@00 {
|
vco1: clock {
|
||||||
compatible = "arm,impd1-vco1";
|
compatible = "arm,impd1-vco1";
|
||||||
#clock-cells = <0>;
|
#clock-cells = <0>;
|
||||||
lock-offset = <0x08>;
|
lock-offset = <0x08>;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
Analog Device ADV7123 Video DAC
|
Analog Devices ADV7123 Video DAC
|
||||||
-------------------------------
|
--------------------------------
|
||||||
|
|
||||||
The ADV7123 is a digital-to-analog converter that outputs VGA signals from a
|
The ADV7123 is a digital-to-analog converter that outputs VGA signals from a
|
||||||
parallel video input.
|
parallel video input.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
Analog Device ADV7511(W)/13/33/35 HDMI Encoders
|
Analog Devices ADV7511(W)/13/33/35 HDMI Encoders
|
||||||
-----------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
The ADV7511, ADV7511W, ADV7513, ADV7533 and ADV7535 are HDMI audio and video
|
The ADV7511, ADV7511W, ADV7513, ADV7533 and ADV7535 are HDMI audio and video
|
||||||
transmitters compatible with HDMI 1.4 and DVI 1.0. They support color space
|
transmitters compatible with HDMI 1.4 and DVI 1.0. They support color space
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Analog Device AXI-DMAC DMA controller
|
Analog Devices AXI-DMAC DMA controller
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible: Must be "adi,axi-dmac-1.00.a".
|
- compatible: Must be "adi,axi-dmac-1.00.a".
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# Copyright 2019 Analog Devices Inc.
|
# Copyright 2019 Analog Devices Inc.
|
||||||
%YAML 1.2
|
%YAML 1.2
|
||||||
---
|
---
|
||||||
$id: http://devicetree.org/schemas/bindings/hwmon/adi,axi-fan-control.yaml#
|
$id: http://devicetree.org/schemas/hwmon/adi,axi-fan-control.yaml#
|
||||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
title: Analog Devices AXI FAN Control Device Tree Bindings
|
title: Analog Devices AXI FAN Control Device Tree Bindings
|
||||||
@ -47,7 +47,7 @@ required:
|
|||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
fpga_axi: fpga-axi@0 {
|
fpga_axi: fpga-axi {
|
||||||
#address-cells = <0x2>;
|
#address-cells = <0x2>;
|
||||||
#size-cells = <0x1>;
|
#size-cells = <0x1>;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||||
%YAML 1.2
|
%YAML 1.2
|
||||||
---
|
---
|
||||||
$id: http://devicetree.org/schemas/adt7475.yaml#
|
$id: http://devicetree.org/schemas/hwmon/adt7475.yaml#
|
||||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
title: ADT7475 hwmon sensor
|
title: ADT7475 hwmon sensor
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
* Analog Device AD5755 IIO Multi-Channel DAC Linux Driver
|
* Analog Devices AD5755 IIO Multi-Channel DAC Linux Driver
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible: Has to contain one of the following:
|
- compatible: Has to contain one of the following:
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# Copyright 2020 Analog Devices Inc.
|
# Copyright 2020 Analog Devices Inc.
|
||||||
%YAML 1.2
|
%YAML 1.2
|
||||||
---
|
---
|
||||||
$id: http://devicetree.org/schemas/bindings/iio/dac/adi,ad5770r.yaml#
|
$id: http://devicetree.org/schemas/iio/dac/adi,ad5770r.yaml#
|
||||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
title: Analog Devices AD5770R DAC device driver
|
title: Analog Devices AD5770R DAC device driver
|
||||||
@ -49,93 +49,86 @@ properties:
|
|||||||
asserted during driver probe.
|
asserted during driver probe.
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
|
|
||||||
channel0:
|
channel@0:
|
||||||
description: Represents an external channel which are
|
description: Represents an external channel which are
|
||||||
connected to the DAC. Channel 0 can act both as a current
|
connected to the DAC. Channel 0 can act both as a current
|
||||||
source and sink.
|
source and sink.
|
||||||
type: object
|
type: object
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
num:
|
reg:
|
||||||
description: This represents the channel number.
|
description: This represents the channel number.
|
||||||
items:
|
const: 0
|
||||||
const: 0
|
|
||||||
|
|
||||||
adi,range-microamp:
|
adi,range-microamp:
|
||||||
description: Output range of the channel.
|
description: Output range of the channel.
|
||||||
oneOf:
|
oneOf:
|
||||||
- $ref: /schemas/types.yaml#/definitions/int32-array
|
|
||||||
- items:
|
- items:
|
||||||
- enum: [0 300000]
|
- const: 0
|
||||||
- enum: [-60000 0]
|
- const: 300000
|
||||||
- enum: [-60000 300000]
|
- items:
|
||||||
|
- const: -60000
|
||||||
|
- const: 0
|
||||||
|
- items:
|
||||||
|
- const: -60000
|
||||||
|
- const: 300000
|
||||||
|
|
||||||
channel1:
|
channel@1:
|
||||||
description: Represents an external channel which are
|
description: Represents an external channel which are
|
||||||
connected to the DAC.
|
connected to the DAC.
|
||||||
type: object
|
type: object
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
num:
|
reg:
|
||||||
description: This represents the channel number.
|
description: This represents the channel number.
|
||||||
items:
|
const: 1
|
||||||
const: 1
|
|
||||||
|
|
||||||
adi,range-microamp:
|
adi,range-microamp:
|
||||||
description: Output range of the channel.
|
description: Output range of the channel.
|
||||||
oneOf:
|
items:
|
||||||
- $ref: /schemas/types.yaml#/definitions/uint32-array
|
- const: 0
|
||||||
- items:
|
- enum: [ 140000, 250000 ]
|
||||||
- enum: [0 140000]
|
|
||||||
- enum: [0 250000]
|
|
||||||
|
|
||||||
channel2:
|
channel@2:
|
||||||
description: Represents an external channel which are
|
description: Represents an external channel which are
|
||||||
connected to the DAC.
|
connected to the DAC.
|
||||||
type: object
|
type: object
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
num:
|
reg:
|
||||||
description: This represents the channel number.
|
description: This represents the channel number.
|
||||||
items:
|
const: 2
|
||||||
const: 2
|
|
||||||
|
|
||||||
adi,range-microamp:
|
adi,range-microamp:
|
||||||
description: Output range of the channel.
|
description: Output range of the channel.
|
||||||
oneOf:
|
items:
|
||||||
- $ref: /schemas/types.yaml#/definitions/uint32-array
|
- const: 0
|
||||||
- items:
|
- enum: [ 55000, 150000 ]
|
||||||
- enum: [0 140000]
|
|
||||||
- enum: [0 250000]
|
|
||||||
|
|
||||||
patternProperties:
|
patternProperties:
|
||||||
"^channel@([3-5])$":
|
"^channel@([3-5])$":
|
||||||
type: object
|
type: object
|
||||||
description: Represents the external channels which are connected to the DAC.
|
description: Represents the external channels which are connected to the DAC.
|
||||||
properties:
|
properties:
|
||||||
num:
|
reg:
|
||||||
description: This represents the channel number.
|
description: This represents the channel number.
|
||||||
items:
|
minimum: 3
|
||||||
minimum: 3
|
maximum: 5
|
||||||
maximum: 5
|
|
||||||
|
|
||||||
adi,range-microamp:
|
adi,range-microamp:
|
||||||
description: Output range of the channel.
|
description: Output range of the channel.
|
||||||
oneOf:
|
items:
|
||||||
- $ref: /schemas/types.yaml#/definitions/uint32-array
|
- const: 0
|
||||||
- items:
|
- enum: [ 45000, 100000 ]
|
||||||
- enum: [0 45000]
|
|
||||||
- enum: [0 100000]
|
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- reg
|
- reg
|
||||||
- diff-channels
|
- channel@0
|
||||||
- channel0
|
- channel@1
|
||||||
- channel1
|
- channel@2
|
||||||
- channel2
|
- channel@3
|
||||||
- channel3
|
- channel@4
|
||||||
- channel4
|
- channel@5
|
||||||
- channel5
|
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
@ -144,40 +137,42 @@ examples:
|
|||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
|
||||||
ad5770r@0 {
|
ad5770r@0 {
|
||||||
compatible = "ad5770r";
|
compatible = "adi,ad5770r";
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
spi-max-frequency = <1000000>;
|
spi-max-frequency = <1000000>;
|
||||||
vref-supply = <&vref>;
|
vref-supply = <&vref>;
|
||||||
adi,external-resistor;
|
adi,external-resistor;
|
||||||
reset-gpios = <&gpio 22 0>;
|
reset-gpios = <&gpio 22 0>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
channel@0 {
|
channel@0 {
|
||||||
num = <0>;
|
reg = <0>;
|
||||||
adi,range-microamp = <(-60000) 300000>;
|
adi,range-microamp = <0 300000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
channel@1 {
|
channel@1 {
|
||||||
num = <1>;
|
reg = <1>;
|
||||||
adi,range-microamp = <0 140000>;
|
adi,range-microamp = <0 140000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
channel@2 {
|
channel@2 {
|
||||||
num = <2>;
|
reg = <2>;
|
||||||
adi,range-microamp = <0 55000>;
|
adi,range-microamp = <0 55000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
channel@3 {
|
channel@3 {
|
||||||
num = <3>;
|
reg = <3>;
|
||||||
adi,range-microamp = <0 45000>;
|
adi,range-microamp = <0 45000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
channel@4 {
|
channel@4 {
|
||||||
num = <4>;
|
reg = <4>;
|
||||||
adi,range-microamp = <0 45000>;
|
adi,range-microamp = <0 45000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
channel@5 {
|
channel@5 {
|
||||||
num = <5>;
|
reg = <5>;
|
||||||
adi,range-microamp = <0 45000>;
|
adi,range-microamp = <0 45000>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -109,7 +109,7 @@ examples:
|
|||||||
- |
|
- |
|
||||||
#include <dt-bindings/gpio/gpio.h>
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||||
i2c@00000000 {
|
i2c {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
edt-ft5x06@38 {
|
edt-ft5x06@38 {
|
||||||
|
@ -56,9 +56,8 @@ properties:
|
|||||||
cell with zero.
|
cell with zero.
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: /schemas/types.yaml#/definitions/uint32-array
|
- $ref: /schemas/types.yaml#/definitions/uint32-array
|
||||||
- items:
|
- minItems: 4
|
||||||
minItems: 4
|
maxItems: 4
|
||||||
maxItems: 4
|
|
||||||
|
|
||||||
|
|
||||||
required:
|
required:
|
||||||
|
@ -97,30 +97,35 @@ examples:
|
|||||||
#include <dt-bindings/clock/tegra186-clock.h>
|
#include <dt-bindings/clock/tegra186-clock.h>
|
||||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||||
|
|
||||||
memory-controller@2c00000 {
|
bus {
|
||||||
compatible = "nvidia,tegra186-mc";
|
|
||||||
reg = <0x0 0x02c00000 0x0 0xb0000>;
|
|
||||||
interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
|
|
||||||
#address-cells = <2>;
|
#address-cells = <2>;
|
||||||
#size-cells = <2>;
|
#size-cells = <2>;
|
||||||
|
|
||||||
ranges = <0x0 0x02c00000 0x02c00000 0x0 0xb0000>;
|
memory-controller@2c00000 {
|
||||||
|
compatible = "nvidia,tegra186-mc";
|
||||||
|
reg = <0x0 0x02c00000 0x0 0xb0000>;
|
||||||
|
interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
|
||||||
/*
|
#address-cells = <2>;
|
||||||
* Memory clients have access to all 40 bits that the memory
|
#size-cells = <2>;
|
||||||
* controller can address.
|
|
||||||
*/
|
|
||||||
dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x0>;
|
|
||||||
|
|
||||||
external-memory-controller@2c60000 {
|
ranges = <0x0 0x02c00000 0x0 0x02c00000 0x0 0xb0000>;
|
||||||
compatible = "nvidia,tegra186-emc";
|
|
||||||
reg = <0x0 0x02c60000 0x0 0x50000>;
|
|
||||||
interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
clocks = <&bpmp TEGRA186_CLK_EMC>;
|
|
||||||
clock-names = "emc";
|
|
||||||
|
|
||||||
nvidia,bpmp = <&bpmp>;
|
/*
|
||||||
|
* Memory clients have access to all 40 bits that the memory
|
||||||
|
* controller can address.
|
||||||
|
*/
|
||||||
|
dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x0>;
|
||||||
|
|
||||||
|
external-memory-controller@2c60000 {
|
||||||
|
compatible = "nvidia,tegra186-emc";
|
||||||
|
reg = <0x0 0x02c60000 0x0 0x50000>;
|
||||||
|
interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
clocks = <&bpmp TEGRA186_CLK_EMC>;
|
||||||
|
clock-names = "emc";
|
||||||
|
|
||||||
|
nvidia,bpmp = <&bpmp>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,7 +123,9 @@ examples:
|
|||||||
#include <dt-bindings/leds/common.h>
|
#include <dt-bindings/leds/common.h>
|
||||||
|
|
||||||
i2c {
|
i2c {
|
||||||
pmic: pmic@4b {
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
pmic: pmic@4b {
|
||||||
compatible = "rohm,bd71837";
|
compatible = "rohm,bd71837";
|
||||||
reg = <0x4b>;
|
reg = <0x4b>;
|
||||||
interrupt-parent = <&gpio1>;
|
interrupt-parent = <&gpio1>;
|
||||||
|
@ -128,7 +128,9 @@ examples:
|
|||||||
#include <dt-bindings/leds/common.h>
|
#include <dt-bindings/leds/common.h>
|
||||||
|
|
||||||
i2c {
|
i2c {
|
||||||
pmic: pmic@4b {
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
pmic: pmic@4b {
|
||||||
compatible = "rohm,bd71847";
|
compatible = "rohm,bd71847";
|
||||||
reg = <0x4b>;
|
reg = <0x4b>;
|
||||||
interrupt-parent = <&gpio1>;
|
interrupt-parent = <&gpio1>;
|
||||||
|
@ -274,7 +274,7 @@ examples:
|
|||||||
- |
|
- |
|
||||||
#include <dt-bindings/mfd/st,stpmic1.h>
|
#include <dt-bindings/mfd/st,stpmic1.h>
|
||||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||||
i2c@0 {
|
i2c {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
pmic@33 {
|
pmic@33 {
|
||||||
|
@ -43,6 +43,9 @@ properties:
|
|||||||
second group of digits is the Phy Identifier 2 register,
|
second group of digits is the Phy Identifier 2 register,
|
||||||
this is the chip vendor OUI bits 19:24, followed by 10
|
this is the chip vendor OUI bits 19:24, followed by 10
|
||||||
bits of a vendor specific ID.
|
bits of a vendor specific ID.
|
||||||
|
- items:
|
||||||
|
- pattern: "^ethernet-phy-id[a-f0-9]{4}\\.[a-f0-9]{4}$"
|
||||||
|
- const: ethernet-phy-ieee802.3-c22
|
||||||
- items:
|
- items:
|
||||||
- pattern: "^ethernet-phy-id[a-f0-9]{4}\\.[a-f0-9]{4}$"
|
- pattern: "^ethernet-phy-id[a-f0-9]{4}\\.[a-f0-9]{4}$"
|
||||||
- const: ethernet-phy-ieee802.3-c45
|
- const: ethernet-phy-ieee802.3-c45
|
||||||
|
@ -22,6 +22,8 @@ Optional properties:
|
|||||||
- fsl,err006687-workaround-present: If present indicates that the system has
|
- fsl,err006687-workaround-present: If present indicates that the system has
|
||||||
the hardware workaround for ERR006687 applied and does not need a software
|
the hardware workaround for ERR006687 applied and does not need a software
|
||||||
workaround.
|
workaround.
|
||||||
|
- gpr: phandle of SoC general purpose register mode. Required for wake on LAN
|
||||||
|
on some SoCs
|
||||||
-interrupt-names: names of the interrupts listed in interrupts property in
|
-interrupt-names: names of the interrupts listed in interrupts property in
|
||||||
the same order. The defaults if not specified are
|
the same order. The defaults if not specified are
|
||||||
__Number of interrupts__ __Default__
|
__Number of interrupts__ __Default__
|
||||||
|
@ -48,6 +48,7 @@ examples:
|
|||||||
|
|
||||||
switch@10 {
|
switch@10 {
|
||||||
compatible = "qca,qca8337";
|
compatible = "qca,qca8337";
|
||||||
|
reg = <0x10>;
|
||||||
/* ... */
|
/* ... */
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -29,7 +29,7 @@ Required properties for compatible string qcom,wcn399x-bt:
|
|||||||
|
|
||||||
Optional properties for compatible string qcom,wcn399x-bt:
|
Optional properties for compatible string qcom,wcn399x-bt:
|
||||||
|
|
||||||
- max-speed: see Documentation/devicetree/bindings/serial/slave-device.txt
|
- max-speed: see Documentation/devicetree/bindings/serial/serial.yaml
|
||||||
- firmware-name: specify the name of nvm firmware to load
|
- firmware-name: specify the name of nvm firmware to load
|
||||||
- clocks: clock provided to the controller
|
- clocks: clock provided to the controller
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ patternProperties:
|
|||||||
bindings specified in
|
bindings specified in
|
||||||
Documentation/devicetree/bindings/phy/phy-cadence-sierra.txt
|
Documentation/devicetree/bindings/phy/phy-cadence-sierra.txt
|
||||||
Torrent SERDES should follow the bindings specified in
|
Torrent SERDES should follow the bindings specified in
|
||||||
Documentation/devicetree/bindings/phy/phy-cadence-dp.txt
|
Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
|
@ -31,10 +31,17 @@ additionalProperties: false
|
|||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
cros-ec@0 {
|
spi {
|
||||||
compatible = "google,cros-ec-spi";
|
#address-cells = <1>;
|
||||||
cros_ec_pwm: ec-pwm {
|
#size-cells = <0>;
|
||||||
compatible = "google,cros-ec-pwm";
|
|
||||||
#pwm-cells = <1>;
|
cros-ec@0 {
|
||||||
|
compatible = "google,cros-ec-spi";
|
||||||
|
reg = <0>;
|
||||||
|
|
||||||
|
cros_ec_pwm: ec-pwm {
|
||||||
|
compatible = "google,cros-ec-pwm";
|
||||||
|
#pwm-cells = <1>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -39,7 +39,7 @@ additionalProperties: false
|
|||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
rng {
|
rng@7e104000 {
|
||||||
compatible = "brcm,bcm2835-rng";
|
compatible = "brcm,bcm2835-rng";
|
||||||
reg = <0x7e104000 0x10>;
|
reg = <0x7e104000 0x10>;
|
||||||
interrupts = <2 29>;
|
interrupts = <2 29>;
|
||||||
|
@ -61,7 +61,7 @@ examples:
|
|||||||
#include <dt-bindings/clock/qcom,gcc-sdm845.h>
|
#include <dt-bindings/clock/qcom,gcc-sdm845.h>
|
||||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||||
|
|
||||||
soc: soc@0 {
|
soc: soc {
|
||||||
#address-cells = <2>;
|
#address-cells = <2>;
|
||||||
#size-cells = <2>;
|
#size-cells = <2>;
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ additionalProperties: false
|
|||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
#include <dt-bindings/clock/jz4740-cgu.h>
|
#include <dt-bindings/clock/jz4740-cgu.h>
|
||||||
usb_phy: usb-phy@0 {
|
usb_phy: usb-phy {
|
||||||
compatible = "usb-nop-xceiv";
|
compatible = "usb-nop-xceiv";
|
||||||
#phy-cells = <0>;
|
#phy-cells = <0>;
|
||||||
};
|
};
|
||||||
|
@ -52,8 +52,8 @@ A child node must exist to represent the core DWC3 IP block. The name of
|
|||||||
the node is not important. The content of the node is defined in dwc3.txt.
|
the node is not important. The content of the node is defined in dwc3.txt.
|
||||||
|
|
||||||
Phy documentation is provided in the following places:
|
Phy documentation is provided in the following places:
|
||||||
Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt - USB3 QMP PHY
|
Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt - USB3 QMP PHY
|
||||||
Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt - USB2 QUSB2 PHY
|
Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml - USB2 QUSB2 PHY
|
||||||
|
|
||||||
Example device nodes:
|
Example device nodes:
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ A child node must exist to represent the core DWC3 IP block. The name of
|
|||||||
the node is not important. The content of the node is defined in dwc3.txt.
|
the node is not important. The content of the node is defined in dwc3.txt.
|
||||||
|
|
||||||
Phy documentation is provided in the following places:
|
Phy documentation is provided in the following places:
|
||||||
Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt - USB2.0 PHY
|
Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml - USB2.0 PHY
|
||||||
Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt - Type-C PHY
|
Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt - Type-C PHY
|
||||||
|
|
||||||
Example device nodes:
|
Example device nodes:
|
||||||
|
@ -16,7 +16,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL68220
|
* Renesas ISL68220
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl68220'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL68221
|
* Renesas ISL68221
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_3rail'
|
Prefix: 'isl68221'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL68222
|
* Renesas ISL68222
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl68222'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL68223
|
* Renesas ISL68223
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl68223'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL68224
|
* Renesas ISL68224
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_3rail'
|
Prefix: 'isl68224'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL68225
|
* Renesas ISL68225
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl68225'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL68226
|
* Renesas ISL68226
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_3rail'
|
Prefix: 'isl68226'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL68227
|
* Renesas ISL68227
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_1rail'
|
Prefix: 'isl68227'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL68229
|
* Renesas ISL68229
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_3rail'
|
Prefix: 'isl68229'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL68233
|
* Renesas ISL68233
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl68233'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL68239
|
* Renesas ISL68239
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_3rail'
|
Prefix: 'isl68239'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69222
|
* Renesas ISL69222
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69222'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69223
|
* Renesas ISL69223
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_3rail'
|
Prefix: 'isl69223'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69224
|
* Renesas ISL69224
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69224'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -156,7 +156,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69225
|
* Renesas ISL69225
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69225'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69227
|
* Renesas ISL69227
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_3rail'
|
Prefix: 'isl69227'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69228
|
* Renesas ISL69228
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_3rail'
|
Prefix: 'isl69228'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69234
|
* Renesas ISL69234
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69234'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -196,7 +196,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69236
|
* Renesas ISL69236
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69236'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -206,7 +206,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69239
|
* Renesas ISL69239
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_3rail'
|
Prefix: 'isl69239'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69242
|
* Renesas ISL69242
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69242'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -226,7 +226,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69243
|
* Renesas ISL69243
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_1rail'
|
Prefix: 'isl69243'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69247
|
* Renesas ISL69247
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69247'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -246,7 +246,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69248
|
* Renesas ISL69248
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69248'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69254
|
* Renesas ISL69254
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69254'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69255
|
* Renesas ISL69255
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69255'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -276,7 +276,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69256
|
* Renesas ISL69256
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69256'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -286,7 +286,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69259
|
* Renesas ISL69259
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69259'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -296,7 +296,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69260
|
* Renesas ISL69260
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69260'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -306,7 +306,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69268
|
* Renesas ISL69268
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69268'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -316,7 +316,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69269
|
* Renesas ISL69269
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_3rail'
|
Prefix: 'isl69269'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -326,7 +326,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas ISL69298
|
* Renesas ISL69298
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'isl69298'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -336,7 +336,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas RAA228000
|
* Renesas RAA228000
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_hv'
|
Prefix: 'raa228000'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -346,7 +346,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas RAA228004
|
* Renesas RAA228004
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_hv'
|
Prefix: 'raa228004'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -356,7 +356,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas RAA228006
|
* Renesas RAA228006
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_hv'
|
Prefix: 'raa228006'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -366,7 +366,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas RAA228228
|
* Renesas RAA228228
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'raa228228'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -376,7 +376,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas RAA229001
|
* Renesas RAA229001
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'raa229001'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
@ -386,7 +386,7 @@ Supported chips:
|
|||||||
|
|
||||||
* Renesas RAA229004
|
* Renesas RAA229004
|
||||||
|
|
||||||
Prefix: 'raa_dmpvr2_2rail'
|
Prefix: 'raa229004'
|
||||||
|
|
||||||
Addresses scanned: -
|
Addresses scanned: -
|
||||||
|
|
||||||
|
@ -257,6 +257,8 @@ drivers:
|
|||||||
* :doc:`netdevsim`
|
* :doc:`netdevsim`
|
||||||
* :doc:`mlxsw`
|
* :doc:`mlxsw`
|
||||||
|
|
||||||
|
.. _Generic-Packet-Trap-Groups:
|
||||||
|
|
||||||
Generic Packet Trap Groups
|
Generic Packet Trap Groups
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ Contents:
|
|||||||
z8530book
|
z8530book
|
||||||
msg_zerocopy
|
msg_zerocopy
|
||||||
failover
|
failover
|
||||||
|
net_dim
|
||||||
net_failover
|
net_failover
|
||||||
phy
|
phy
|
||||||
sfp-phylink
|
sfp-phylink
|
||||||
|
@ -812,7 +812,7 @@ tcp_limit_output_bytes - INTEGER
|
|||||||
tcp_challenge_ack_limit - INTEGER
|
tcp_challenge_ack_limit - INTEGER
|
||||||
Limits number of Challenge ACK sent per second, as recommended
|
Limits number of Challenge ACK sent per second, as recommended
|
||||||
in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks)
|
in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks)
|
||||||
Default: 100
|
Default: 1000
|
||||||
|
|
||||||
tcp_rx_skb_cache - BOOLEAN
|
tcp_rx_skb_cache - BOOLEAN
|
||||||
Controls a per TCP socket cache of one skb, that might help
|
Controls a per TCP socket cache of one skb, that might help
|
||||||
|
@ -1,28 +1,20 @@
|
|||||||
|
======================================================
|
||||||
Net DIM - Generic Network Dynamic Interrupt Moderation
|
Net DIM - Generic Network Dynamic Interrupt Moderation
|
||||||
======================================================
|
======================================================
|
||||||
|
|
||||||
Author:
|
:Author: Tal Gilboa <talgi@mellanox.com>
|
||||||
Tal Gilboa <talgi@mellanox.com>
|
|
||||||
|
|
||||||
|
.. contents:: :depth: 2
|
||||||
|
|
||||||
Contents
|
Assumptions
|
||||||
=========
|
===========
|
||||||
|
|
||||||
- Assumptions
|
|
||||||
- Introduction
|
|
||||||
- The Net DIM Algorithm
|
|
||||||
- Registering a Network Device to DIM
|
|
||||||
- Example
|
|
||||||
|
|
||||||
Part 0: Assumptions
|
|
||||||
======================
|
|
||||||
|
|
||||||
This document assumes the reader has basic knowledge in network drivers
|
This document assumes the reader has basic knowledge in network drivers
|
||||||
and in general interrupt moderation.
|
and in general interrupt moderation.
|
||||||
|
|
||||||
|
|
||||||
Part I: Introduction
|
Introduction
|
||||||
======================
|
============
|
||||||
|
|
||||||
Dynamic Interrupt Moderation (DIM) (in networking) refers to changing the
|
Dynamic Interrupt Moderation (DIM) (in networking) refers to changing the
|
||||||
interrupt moderation configuration of a channel in order to optimize packet
|
interrupt moderation configuration of a channel in order to optimize packet
|
||||||
@ -41,14 +33,15 @@ number of wanted packets per event. The Net DIM algorithm ascribes importance to
|
|||||||
increase bandwidth over reducing interrupt rate.
|
increase bandwidth over reducing interrupt rate.
|
||||||
|
|
||||||
|
|
||||||
Part II: The Net DIM Algorithm
|
Net DIM Algorithm
|
||||||
===============================
|
=================
|
||||||
|
|
||||||
Each iteration of the Net DIM algorithm follows these steps:
|
Each iteration of the Net DIM algorithm follows these steps:
|
||||||
1. Calculates new data sample.
|
|
||||||
2. Compares it to previous sample.
|
#. Calculates new data sample.
|
||||||
3. Makes a decision - suggests interrupt moderation configuration fields.
|
#. Compares it to previous sample.
|
||||||
4. Applies a schedule work function, which applies suggested configuration.
|
#. Makes a decision - suggests interrupt moderation configuration fields.
|
||||||
|
#. Applies a schedule work function, which applies suggested configuration.
|
||||||
|
|
||||||
The first two steps are straightforward, both the new and the previous data are
|
The first two steps are straightforward, both the new and the previous data are
|
||||||
supplied by the driver registered to Net DIM. The previous data is the new data
|
supplied by the driver registered to Net DIM. The previous data is the new data
|
||||||
@ -89,19 +82,21 @@ manoeuvre as it may provide partial data or ignore the algorithm suggestion
|
|||||||
under some conditions.
|
under some conditions.
|
||||||
|
|
||||||
|
|
||||||
Part III: Registering a Network Device to DIM
|
Registering a Network Device to DIM
|
||||||
==============================================
|
===================================
|
||||||
|
|
||||||
Net DIM API exposes the main function net_dim(struct dim *dim,
|
Net DIM API exposes the main function net_dim().
|
||||||
struct dim_sample end_sample). This function is the entry point to the Net
|
This function is the entry point to the Net
|
||||||
DIM algorithm and has to be called every time the driver would like to check if
|
DIM algorithm and has to be called every time the driver would like to check if
|
||||||
it should change interrupt moderation parameters. The driver should provide two
|
it should change interrupt moderation parameters. The driver should provide two
|
||||||
data structures: struct dim and struct dim_sample. Struct dim
|
data structures: :c:type:`struct dim <dim>` and
|
||||||
|
:c:type:`struct dim_sample <dim_sample>`. :c:type:`struct dim <dim>`
|
||||||
describes the state of DIM for a specific object (RX queue, TX queue,
|
describes the state of DIM for a specific object (RX queue, TX queue,
|
||||||
other queues, etc.). This includes the current selected profile, previous data
|
other queues, etc.). This includes the current selected profile, previous data
|
||||||
samples, the callback function provided by the driver and more.
|
samples, the callback function provided by the driver and more.
|
||||||
Struct dim_sample describes a data sample, which will be compared to the
|
:c:type:`struct dim_sample <dim_sample>` describes a data sample,
|
||||||
data sample stored in struct dim in order to decide on the algorithm's next
|
which will be compared to the data sample stored in :c:type:`struct dim <dim>`
|
||||||
|
in order to decide on the algorithm's next
|
||||||
step. The sample should include bytes, packets and interrupts, measured by
|
step. The sample should include bytes, packets and interrupts, measured by
|
||||||
the driver.
|
the driver.
|
||||||
|
|
||||||
@ -110,9 +105,10 @@ main net_dim() function. The recommended method is to call net_dim() on each
|
|||||||
interrupt. Since Net DIM has a built-in moderation and it might decide to skip
|
interrupt. Since Net DIM has a built-in moderation and it might decide to skip
|
||||||
iterations under certain conditions, there is no need to moderate the net_dim()
|
iterations under certain conditions, there is no need to moderate the net_dim()
|
||||||
calls as well. As mentioned above, the driver needs to provide an object of type
|
calls as well. As mentioned above, the driver needs to provide an object of type
|
||||||
struct dim to the net_dim() function call. It is advised for each entity
|
:c:type:`struct dim <dim>` to the net_dim() function call. It is advised for
|
||||||
using Net DIM to hold a struct dim as part of its data structure and use it
|
each entity using Net DIM to hold a :c:type:`struct dim <dim>` as part of its
|
||||||
as the main Net DIM API object. The struct dim_sample should hold the latest
|
data structure and use it as the main Net DIM API object.
|
||||||
|
The :c:type:`struct dim_sample <dim_sample>` should hold the latest
|
||||||
bytes, packets and interrupts count. No need to perform any calculations, just
|
bytes, packets and interrupts count. No need to perform any calculations, just
|
||||||
include the raw data.
|
include the raw data.
|
||||||
|
|
||||||
@ -124,19 +120,19 @@ the data flow. After the work is done, Net DIM algorithm needs to be set to
|
|||||||
the proper state in order to move to the next iteration.
|
the proper state in order to move to the next iteration.
|
||||||
|
|
||||||
|
|
||||||
Part IV: Example
|
Example
|
||||||
=================
|
=======
|
||||||
|
|
||||||
The following code demonstrates how to register a driver to Net DIM. The actual
|
The following code demonstrates how to register a driver to Net DIM. The actual
|
||||||
usage is not complete but it should make the outline of the usage clear.
|
usage is not complete but it should make the outline of the usage clear.
|
||||||
|
|
||||||
my_driver.c:
|
.. code-block:: c
|
||||||
|
|
||||||
#include <linux/dim.h>
|
#include <linux/dim.h>
|
||||||
|
|
||||||
/* Callback for net DIM to schedule on a decision to change moderation */
|
/* Callback for net DIM to schedule on a decision to change moderation */
|
||||||
void my_driver_do_dim_work(struct work_struct *work)
|
void my_driver_do_dim_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
/* Get struct dim from struct work_struct */
|
/* Get struct dim from struct work_struct */
|
||||||
struct dim *dim = container_of(work, struct dim,
|
struct dim *dim = container_of(work, struct dim,
|
||||||
work);
|
work);
|
||||||
@ -145,11 +141,11 @@ void my_driver_do_dim_work(struct work_struct *work)
|
|||||||
|
|
||||||
/* Signal net DIM work is done and it should move to next iteration */
|
/* Signal net DIM work is done and it should move to next iteration */
|
||||||
dim->state = DIM_START_MEASURE;
|
dim->state = DIM_START_MEASURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* My driver's interrupt handler */
|
/* My driver's interrupt handler */
|
||||||
int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...)
|
int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...)
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
/* A struct to hold current measured data */
|
/* A struct to hold current measured data */
|
||||||
struct dim_sample dim_sample;
|
struct dim_sample dim_sample;
|
||||||
@ -162,13 +158,19 @@ int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...)
|
|||||||
/* Call net DIM */
|
/* Call net DIM */
|
||||||
net_dim(&my_entity->dim, dim_sample);
|
net_dim(&my_entity->dim, dim_sample);
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
/* My entity's initialization function (my_entity was already allocated) */
|
/* My entity's initialization function (my_entity was already allocated) */
|
||||||
int my_driver_init_my_entity(struct my_driver_entity *my_entity, ...)
|
int my_driver_init_my_entity(struct my_driver_entity *my_entity, ...)
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
/* Initiate struct work_struct with my driver's callback function */
|
/* Initiate struct work_struct with my driver's callback function */
|
||||||
INIT_WORK(&my_entity->dim.work, my_driver_do_dim_work);
|
INIT_WORK(&my_entity->dim.work, my_driver_do_dim_work);
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dynamic Interrupt Moderation (DIM) library API
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
.. kernel-doc:: include/linux/dim.h
|
||||||
|
:internal:
|
@ -1399,8 +1399,8 @@ must have read/write permission; CS must be __BOOT_CS and DS, ES, SS
|
|||||||
must be __BOOT_DS; interrupt must be disabled; %rsi must hold the base
|
must be __BOOT_DS; interrupt must be disabled; %rsi must hold the base
|
||||||
address of the struct boot_params.
|
address of the struct boot_params.
|
||||||
|
|
||||||
EFI Handover Protocol
|
EFI Handover Protocol (deprecated)
|
||||||
=====================
|
==================================
|
||||||
|
|
||||||
This protocol allows boot loaders to defer initialisation to the EFI
|
This protocol allows boot loaders to defer initialisation to the EFI
|
||||||
boot stub. The boot loader is required to load the kernel/initrd(s)
|
boot stub. The boot loader is required to load the kernel/initrd(s)
|
||||||
@ -1408,6 +1408,12 @@ from the boot media and jump to the EFI handover protocol entry point
|
|||||||
which is hdr->handover_offset bytes from the beginning of
|
which is hdr->handover_offset bytes from the beginning of
|
||||||
startup_{32,64}.
|
startup_{32,64}.
|
||||||
|
|
||||||
|
The boot loader MUST respect the kernel's PE/COFF metadata when it comes
|
||||||
|
to section alignment, the memory footprint of the executable image beyond
|
||||||
|
the size of the file itself, and any other aspect of the PE/COFF header
|
||||||
|
that may affect correct operation of the image as a PE/COFF binary in the
|
||||||
|
execution context provided by the EFI firmware.
|
||||||
|
|
||||||
The function prototype for the handover entry point looks like this::
|
The function prototype for the handover entry point looks like this::
|
||||||
|
|
||||||
efi_main(void *handle, efi_system_table_t *table, struct boot_params *bp)
|
efi_main(void *handle, efi_system_table_t *table, struct boot_params *bp)
|
||||||
@ -1419,9 +1425,18 @@ UEFI specification. 'bp' is the boot loader-allocated boot params.
|
|||||||
|
|
||||||
The boot loader *must* fill out the following fields in bp::
|
The boot loader *must* fill out the following fields in bp::
|
||||||
|
|
||||||
- hdr.code32_start
|
|
||||||
- hdr.cmd_line_ptr
|
- hdr.cmd_line_ptr
|
||||||
- hdr.ramdisk_image (if applicable)
|
- hdr.ramdisk_image (if applicable)
|
||||||
- hdr.ramdisk_size (if applicable)
|
- hdr.ramdisk_size (if applicable)
|
||||||
|
|
||||||
All other fields should be zero.
|
All other fields should be zero.
|
||||||
|
|
||||||
|
NOTE: The EFI Handover Protocol is deprecated in favour of the ordinary PE/COFF
|
||||||
|
entry point, combined with the LINUX_EFI_INITRD_MEDIA_GUID based initrd
|
||||||
|
loading protocol (refer to [0] for an example of the bootloader side of
|
||||||
|
this), which removes the need for any knowledge on the part of the EFI
|
||||||
|
bootloader regarding the internal representation of boot_params or any
|
||||||
|
requirements/limitations regarding the placement of the command line
|
||||||
|
and ramdisk in memory, or the placement of the kernel image itself.
|
||||||
|
|
||||||
|
[0] https://github.com/u-boot/u-boot/commit/ec80b4735a593961fe701cc3a5d717d4739b0fd0
|
||||||
|
11
MAINTAINERS
11
MAINTAINERS
@ -1323,7 +1323,10 @@ ARM INTEGRATOR, VERSATILE AND REALVIEW SUPPORT
|
|||||||
M: Linus Walleij <linus.walleij@linaro.org>
|
M: Linus Walleij <linus.walleij@linaro.org>
|
||||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/bindings/arm/arm-boards
|
F: Documentation/devicetree/bindings/arm/arm,integrator.yaml
|
||||||
|
F: Documentation/devicetree/bindings/arm/arm,realview.yaml
|
||||||
|
F: Documentation/devicetree/bindings/arm/arm,versatile.yaml
|
||||||
|
F: Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml
|
||||||
F: Documentation/devicetree/bindings/auxdisplay/arm-charlcd.txt
|
F: Documentation/devicetree/bindings/auxdisplay/arm-charlcd.txt
|
||||||
F: Documentation/devicetree/bindings/clock/arm,syscon-icst.yaml
|
F: Documentation/devicetree/bindings/clock/arm,syscon-icst.yaml
|
||||||
F: Documentation/devicetree/bindings/i2c/i2c-versatile.txt
|
F: Documentation/devicetree/bindings/i2c/i2c-versatile.txt
|
||||||
@ -5552,7 +5555,7 @@ M: Chen-Yu Tsai <wens@csie.org>
|
|||||||
L: dri-devel@lists.freedesktop.org
|
L: dri-devel@lists.freedesktop.org
|
||||||
S: Supported
|
S: Supported
|
||||||
T: git git://anongit.freedesktop.org/drm/drm-misc
|
T: git git://anongit.freedesktop.org/drm/drm-misc
|
||||||
F: Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
|
F: Documentation/devicetree/bindings/display/allwinner*
|
||||||
F: drivers/gpu/drm/sun4i/
|
F: drivers/gpu/drm/sun4i/
|
||||||
|
|
||||||
DRM DRIVERS FOR AMLOGIC SOCS
|
DRM DRIVERS FOR AMLOGIC SOCS
|
||||||
@ -5934,6 +5937,7 @@ M: Tal Gilboa <talgi@mellanox.com>
|
|||||||
S: Maintained
|
S: Maintained
|
||||||
F: include/linux/dim.h
|
F: include/linux/dim.h
|
||||||
F: lib/dim/
|
F: lib/dim/
|
||||||
|
F: Documentation/networking/net_dim.rst
|
||||||
|
|
||||||
DZ DECSTATION DZ11 SERIAL DRIVER
|
DZ DECSTATION DZ11 SERIAL DRIVER
|
||||||
M: "Maciej W. Rozycki" <macro@linux-mips.org>
|
M: "Maciej W. Rozycki" <macro@linux-mips.org>
|
||||||
@ -13853,7 +13857,8 @@ S: Maintained
|
|||||||
F: drivers/scsi/qla1280.[ch]
|
F: drivers/scsi/qla1280.[ch]
|
||||||
|
|
||||||
QLOGIC QLA2XXX FC-SCSI DRIVER
|
QLOGIC QLA2XXX FC-SCSI DRIVER
|
||||||
M: hmadhani@marvell.com
|
M: Nilesh Javali <njavali@marvell.com>
|
||||||
|
M: GR-QLogic-Storage-Upstream@marvell.com
|
||||||
L: linux-scsi@vger.kernel.org
|
L: linux-scsi@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: Documentation/scsi/LICENSE.qla2xxx
|
F: Documentation/scsi/LICENSE.qla2xxx
|
||||||
|
2
Makefile
2
Makefile
@ -2,7 +2,7 @@
|
|||||||
VERSION = 5
|
VERSION = 5
|
||||||
PATCHLEVEL = 7
|
PATCHLEVEL = 7
|
||||||
SUBLEVEL = 0
|
SUBLEVEL = 0
|
||||||
EXTRAVERSION = -rc1
|
EXTRAVERSION = -rc2
|
||||||
NAME = Kleptomaniac Octopus
|
NAME = Kleptomaniac Octopus
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
|
@ -1450,7 +1450,8 @@ ENTRY(efi_enter_kernel)
|
|||||||
@ running beyond the PoU, and so calling cache_off below from
|
@ running beyond the PoU, and so calling cache_off below from
|
||||||
@ inside the PE/COFF loader allocated region is unsafe unless
|
@ inside the PE/COFF loader allocated region is unsafe unless
|
||||||
@ we explicitly clean it to the PoC.
|
@ we explicitly clean it to the PoC.
|
||||||
adr r0, call_cache_fn @ region of code we will
|
ARM( adrl r0, call_cache_fn )
|
||||||
|
THUMB( adr r0, call_cache_fn ) @ region of code we will
|
||||||
adr r1, 0f @ run with MMU off
|
adr r1, 0f @ run with MMU off
|
||||||
bl cache_clean_flush
|
bl cache_clean_flush
|
||||||
bl cache_off
|
bl cache_off
|
||||||
|
@ -1039,13 +1039,13 @@ fec: ethernet@2188000 {
|
|||||||
compatible = "fsl,imx6q-fec";
|
compatible = "fsl,imx6q-fec";
|
||||||
reg = <0x02188000 0x4000>;
|
reg = <0x02188000 0x4000>;
|
||||||
interrupt-names = "int0", "pps";
|
interrupt-names = "int0", "pps";
|
||||||
interrupts-extended =
|
interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<&intc 0 118 IRQ_TYPE_LEVEL_HIGH>,
|
<0 119 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
<&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
clocks = <&clks IMX6QDL_CLK_ENET>,
|
clocks = <&clks IMX6QDL_CLK_ENET>,
|
||||||
<&clks IMX6QDL_CLK_ENET>,
|
<&clks IMX6QDL_CLK_ENET>,
|
||||||
<&clks IMX6QDL_CLK_ENET_REF>;
|
<&clks IMX6QDL_CLK_ENET_REF>;
|
||||||
clock-names = "ipg", "ahb", "ptp";
|
clock-names = "ipg", "ahb", "ptp";
|
||||||
|
gpr = <&gpr>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -77,7 +77,6 @@ prg2: prg@21cd000 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
&fec {
|
&fec {
|
||||||
/delete-property/interrupts-extended;
|
|
||||||
interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>,
|
interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
<0 119 IRQ_TYPE_LEVEL_HIGH>;
|
<0 119 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
};
|
};
|
||||||
|
@ -929,7 +929,11 @@ static inline void emit_a32_rsh_i64(const s8 dst[],
|
|||||||
rd = arm_bpf_get_reg64(dst, tmp, ctx);
|
rd = arm_bpf_get_reg64(dst, tmp, ctx);
|
||||||
|
|
||||||
/* Do LSR operation */
|
/* Do LSR operation */
|
||||||
if (val < 32) {
|
if (val == 0) {
|
||||||
|
/* An immediate value of 0 encodes a shift amount of 32
|
||||||
|
* for LSR. To shift by 0, don't do anything.
|
||||||
|
*/
|
||||||
|
} else if (val < 32) {
|
||||||
emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx);
|
emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx);
|
||||||
emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx);
|
emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx);
|
||||||
emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_LSR, val), ctx);
|
emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_LSR, val), ctx);
|
||||||
@ -955,7 +959,11 @@ static inline void emit_a32_arsh_i64(const s8 dst[],
|
|||||||
rd = arm_bpf_get_reg64(dst, tmp, ctx);
|
rd = arm_bpf_get_reg64(dst, tmp, ctx);
|
||||||
|
|
||||||
/* Do ARSH operation */
|
/* Do ARSH operation */
|
||||||
if (val < 32) {
|
if (val == 0) {
|
||||||
|
/* An immediate value of 0 encodes a shift amount of 32
|
||||||
|
* for ASR. To shift by 0, don't do anything.
|
||||||
|
*/
|
||||||
|
} else if (val < 32) {
|
||||||
emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx);
|
emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx);
|
||||||
emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx);
|
emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx);
|
||||||
emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_ASR, val), ctx);
|
emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_ASR, val), ctx);
|
||||||
@ -992,21 +1000,35 @@ static inline void emit_a32_mul_r64(const s8 dst[], const s8 src[],
|
|||||||
arm_bpf_put_reg32(dst_hi, rd[0], ctx);
|
arm_bpf_put_reg32(dst_hi, rd[0], ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_ldst_imm(s16 off, const u8 size)
|
||||||
|
{
|
||||||
|
s16 off_max = 0;
|
||||||
|
|
||||||
|
switch (size) {
|
||||||
|
case BPF_B:
|
||||||
|
case BPF_W:
|
||||||
|
off_max = 0xfff;
|
||||||
|
break;
|
||||||
|
case BPF_H:
|
||||||
|
off_max = 0xff;
|
||||||
|
break;
|
||||||
|
case BPF_DW:
|
||||||
|
/* Need to make sure off+4 does not overflow. */
|
||||||
|
off_max = 0xfff - 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -off_max <= off && off <= off_max;
|
||||||
|
}
|
||||||
|
|
||||||
/* *(size *)(dst + off) = src */
|
/* *(size *)(dst + off) = src */
|
||||||
static inline void emit_str_r(const s8 dst, const s8 src[],
|
static inline void emit_str_r(const s8 dst, const s8 src[],
|
||||||
s32 off, struct jit_ctx *ctx, const u8 sz){
|
s16 off, struct jit_ctx *ctx, const u8 sz){
|
||||||
const s8 *tmp = bpf2a32[TMP_REG_1];
|
const s8 *tmp = bpf2a32[TMP_REG_1];
|
||||||
s32 off_max;
|
|
||||||
s8 rd;
|
s8 rd;
|
||||||
|
|
||||||
rd = arm_bpf_get_reg32(dst, tmp[1], ctx);
|
rd = arm_bpf_get_reg32(dst, tmp[1], ctx);
|
||||||
|
|
||||||
if (sz == BPF_H)
|
if (!is_ldst_imm(off, sz)) {
|
||||||
off_max = 0xff;
|
|
||||||
else
|
|
||||||
off_max = 0xfff;
|
|
||||||
|
|
||||||
if (off < 0 || off > off_max) {
|
|
||||||
emit_a32_mov_i(tmp[0], off, ctx);
|
emit_a32_mov_i(tmp[0], off, ctx);
|
||||||
emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx);
|
emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx);
|
||||||
rd = tmp[0];
|
rd = tmp[0];
|
||||||
@ -1035,18 +1057,12 @@ static inline void emit_str_r(const s8 dst, const s8 src[],
|
|||||||
|
|
||||||
/* dst = *(size*)(src + off) */
|
/* dst = *(size*)(src + off) */
|
||||||
static inline void emit_ldx_r(const s8 dst[], const s8 src,
|
static inline void emit_ldx_r(const s8 dst[], const s8 src,
|
||||||
s32 off, struct jit_ctx *ctx, const u8 sz){
|
s16 off, struct jit_ctx *ctx, const u8 sz){
|
||||||
const s8 *tmp = bpf2a32[TMP_REG_1];
|
const s8 *tmp = bpf2a32[TMP_REG_1];
|
||||||
const s8 *rd = is_stacked(dst_lo) ? tmp : dst;
|
const s8 *rd = is_stacked(dst_lo) ? tmp : dst;
|
||||||
s8 rm = src;
|
s8 rm = src;
|
||||||
s32 off_max;
|
|
||||||
|
|
||||||
if (sz == BPF_H)
|
if (!is_ldst_imm(off, sz)) {
|
||||||
off_max = 0xff;
|
|
||||||
else
|
|
||||||
off_max = 0xfff;
|
|
||||||
|
|
||||||
if (off < 0 || off > off_max) {
|
|
||||||
emit_a32_mov_i(tmp[0], off, ctx);
|
emit_a32_mov_i(tmp[0], off, ctx);
|
||||||
emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx);
|
emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx);
|
||||||
rm = tmp[0];
|
rm = tmp[0];
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
|
||||||
struct start_info _xen_start_info;
|
static struct start_info _xen_start_info;
|
||||||
struct start_info *xen_start_info = &_xen_start_info;
|
struct start_info *xen_start_info = &_xen_start_info;
|
||||||
EXPORT_SYMBOL(xen_start_info);
|
EXPORT_SYMBOL(xen_start_info);
|
||||||
|
|
||||||
|
@ -49,7 +49,9 @@
|
|||||||
#ifndef CONFIG_BROKEN_GAS_INST
|
#ifndef CONFIG_BROKEN_GAS_INST
|
||||||
|
|
||||||
#ifdef __ASSEMBLY__
|
#ifdef __ASSEMBLY__
|
||||||
#define __emit_inst(x) .inst (x)
|
// The space separator is omitted so that __emit_inst(x) can be parsed as
|
||||||
|
// either an assembler directive or an assembler macro argument.
|
||||||
|
#define __emit_inst(x) .inst(x)
|
||||||
#else
|
#else
|
||||||
#define __emit_inst(x) ".inst " __stringify((x)) "\n\t"
|
#define __emit_inst(x) ".inst " __stringify((x)) "\n\t"
|
||||||
#endif
|
#endif
|
||||||
|
@ -260,18 +260,7 @@ static int __aarch32_alloc_vdso_pages(void)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = aarch32_alloc_kuser_vdso_page();
|
return aarch32_alloc_kuser_vdso_page();
|
||||||
if (ret) {
|
|
||||||
unsigned long c_vvar =
|
|
||||||
(unsigned long)page_to_virt(aarch32_vdso_pages[C_VVAR]);
|
|
||||||
unsigned long c_vdso =
|
|
||||||
(unsigned long)page_to_virt(aarch32_vdso_pages[C_VDSO]);
|
|
||||||
|
|
||||||
free_page(c_vvar);
|
|
||||||
free_page(c_vdso);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static int __aarch32_alloc_vdso_pages(void)
|
static int __aarch32_alloc_vdso_pages(void)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
generated-y += syscall_table.h
|
generated-y += syscall_table.h
|
||||||
generic-y += extable.h
|
generic-y += extable.h
|
||||||
generic-y += hardirq.h
|
|
||||||
generic-y += kvm_para.h
|
generic-y += kvm_para.h
|
||||||
generic-y += local64.h
|
generic-y += local64.h
|
||||||
generic-y += mcs_spinlock.h
|
generic-y += mcs_spinlock.h
|
||||||
|
@ -55,7 +55,7 @@ config RISCV
|
|||||||
select ARCH_HAS_PTE_SPECIAL
|
select ARCH_HAS_PTE_SPECIAL
|
||||||
select ARCH_HAS_MMIOWB
|
select ARCH_HAS_MMIOWB
|
||||||
select ARCH_HAS_DEBUG_VIRTUAL
|
select ARCH_HAS_DEBUG_VIRTUAL
|
||||||
select HAVE_EBPF_JIT
|
select HAVE_EBPF_JIT if MMU
|
||||||
select EDAC_SUPPORT
|
select EDAC_SUPPORT
|
||||||
select ARCH_HAS_GIGANTIC_PAGE
|
select ARCH_HAS_GIGANTIC_PAGE
|
||||||
select ARCH_HAS_SET_DIRECT_MAP
|
select ARCH_HAS_SET_DIRECT_MAP
|
||||||
|
@ -110,6 +110,16 @@ static bool is_32b_int(s64 val)
|
|||||||
return -(1L << 31) <= val && val < (1L << 31);
|
return -(1L << 31) <= val && val < (1L << 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool in_auipc_jalr_range(s64 val)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* auipc+jalr can reach any signed PC-relative offset in the range
|
||||||
|
* [-2^31 - 2^11, 2^31 - 2^11).
|
||||||
|
*/
|
||||||
|
return (-(1L << 31) - (1L << 11)) <= val &&
|
||||||
|
val < ((1L << 31) - (1L << 11));
|
||||||
|
}
|
||||||
|
|
||||||
static void emit_imm(u8 rd, s64 val, struct rv_jit_context *ctx)
|
static void emit_imm(u8 rd, s64 val, struct rv_jit_context *ctx)
|
||||||
{
|
{
|
||||||
/* Note that the immediate from the add is sign-extended,
|
/* Note that the immediate from the add is sign-extended,
|
||||||
@ -380,20 +390,24 @@ static void emit_sext_32_rd(u8 *rd, struct rv_jit_context *ctx)
|
|||||||
*rd = RV_REG_T2;
|
*rd = RV_REG_T2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emit_jump_and_link(u8 rd, s64 rvoff, bool force_jalr,
|
static int emit_jump_and_link(u8 rd, s64 rvoff, bool force_jalr,
|
||||||
struct rv_jit_context *ctx)
|
struct rv_jit_context *ctx)
|
||||||
{
|
{
|
||||||
s64 upper, lower;
|
s64 upper, lower;
|
||||||
|
|
||||||
if (rvoff && is_21b_int(rvoff) && !force_jalr) {
|
if (rvoff && is_21b_int(rvoff) && !force_jalr) {
|
||||||
emit(rv_jal(rd, rvoff >> 1), ctx);
|
emit(rv_jal(rd, rvoff >> 1), ctx);
|
||||||
return;
|
return 0;
|
||||||
|
} else if (in_auipc_jalr_range(rvoff)) {
|
||||||
|
upper = (rvoff + (1 << 11)) >> 12;
|
||||||
|
lower = rvoff & 0xfff;
|
||||||
|
emit(rv_auipc(RV_REG_T1, upper), ctx);
|
||||||
|
emit(rv_jalr(rd, RV_REG_T1, lower), ctx);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
upper = (rvoff + (1 << 11)) >> 12;
|
pr_err("bpf-jit: target offset 0x%llx is out of range\n", rvoff);
|
||||||
lower = rvoff & 0xfff;
|
return -ERANGE;
|
||||||
emit(rv_auipc(RV_REG_T1, upper), ctx);
|
|
||||||
emit(rv_jalr(rd, RV_REG_T1, lower), ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_signed_bpf_cond(u8 cond)
|
static bool is_signed_bpf_cond(u8 cond)
|
||||||
@ -407,18 +421,16 @@ static int emit_call(bool fixed, u64 addr, struct rv_jit_context *ctx)
|
|||||||
s64 off = 0;
|
s64 off = 0;
|
||||||
u64 ip;
|
u64 ip;
|
||||||
u8 rd;
|
u8 rd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (addr && ctx->insns) {
|
if (addr && ctx->insns) {
|
||||||
ip = (u64)(long)(ctx->insns + ctx->ninsns);
|
ip = (u64)(long)(ctx->insns + ctx->ninsns);
|
||||||
off = addr - ip;
|
off = addr - ip;
|
||||||
if (!is_32b_int(off)) {
|
|
||||||
pr_err("bpf-jit: target call addr %pK is out of range\n",
|
|
||||||
(void *)addr);
|
|
||||||
return -ERANGE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_jump_and_link(RV_REG_RA, off, !fixed, ctx);
|
ret = emit_jump_and_link(RV_REG_RA, off, !fixed, ctx);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
rd = bpf_to_rv_reg(BPF_REG_0, ctx);
|
rd = bpf_to_rv_reg(BPF_REG_0, ctx);
|
||||||
emit(rv_addi(rd, RV_REG_A0, 0), ctx);
|
emit(rv_addi(rd, RV_REG_A0, 0), ctx);
|
||||||
return 0;
|
return 0;
|
||||||
@ -429,7 +441,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
|
|||||||
{
|
{
|
||||||
bool is64 = BPF_CLASS(insn->code) == BPF_ALU64 ||
|
bool is64 = BPF_CLASS(insn->code) == BPF_ALU64 ||
|
||||||
BPF_CLASS(insn->code) == BPF_JMP;
|
BPF_CLASS(insn->code) == BPF_JMP;
|
||||||
int s, e, rvoff, i = insn - ctx->prog->insnsi;
|
int s, e, rvoff, ret, i = insn - ctx->prog->insnsi;
|
||||||
struct bpf_prog_aux *aux = ctx->prog->aux;
|
struct bpf_prog_aux *aux = ctx->prog->aux;
|
||||||
u8 rd = -1, rs = -1, code = insn->code;
|
u8 rd = -1, rs = -1, code = insn->code;
|
||||||
s16 off = insn->off;
|
s16 off = insn->off;
|
||||||
@ -699,7 +711,9 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
|
|||||||
/* JUMP off */
|
/* JUMP off */
|
||||||
case BPF_JMP | BPF_JA:
|
case BPF_JMP | BPF_JA:
|
||||||
rvoff = rv_offset(i, off, ctx);
|
rvoff = rv_offset(i, off, ctx);
|
||||||
emit_jump_and_link(RV_REG_ZERO, rvoff, false, ctx);
|
ret = emit_jump_and_link(RV_REG_ZERO, rvoff, false, ctx);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* IF (dst COND src) JUMP off */
|
/* IF (dst COND src) JUMP off */
|
||||||
@ -801,7 +815,6 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
|
|||||||
case BPF_JMP | BPF_CALL:
|
case BPF_JMP | BPF_CALL:
|
||||||
{
|
{
|
||||||
bool fixed;
|
bool fixed;
|
||||||
int ret;
|
|
||||||
u64 addr;
|
u64 addr;
|
||||||
|
|
||||||
mark_call(ctx);
|
mark_call(ctx);
|
||||||
@ -826,7 +839,9 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
rvoff = epilogue_offset(ctx);
|
rvoff = epilogue_offset(ctx);
|
||||||
emit_jump_and_link(RV_REG_ZERO, rvoff, false, ctx);
|
ret = emit_jump_and_link(RV_REG_ZERO, rvoff, false, ctx);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* dst = imm64 */
|
/* dst = imm64 */
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/hyperv.h>
|
#include <linux/hyperv.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
#include <linux/cpuhotplug.h>
|
#include <linux/cpuhotplug.h>
|
||||||
#include <linux/syscore_ops.h>
|
#include <linux/syscore_ops.h>
|
||||||
#include <clocksource/hyperv_timer.h>
|
#include <clocksource/hyperv_timer.h>
|
||||||
@ -419,11 +420,14 @@ void hyperv_cleanup(void)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(hyperv_cleanup);
|
EXPORT_SYMBOL_GPL(hyperv_cleanup);
|
||||||
|
|
||||||
void hyperv_report_panic(struct pt_regs *regs, long err)
|
void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
|
||||||
{
|
{
|
||||||
static bool panic_reported;
|
static bool panic_reported;
|
||||||
u64 guest_id;
|
u64 guest_id;
|
||||||
|
|
||||||
|
if (in_die && !panic_on_oops)
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We prefer to report panic on 'die' chain as we have proper
|
* We prefer to report panic on 'die' chain as we have proper
|
||||||
* registers to report, but if we miss it (e.g. on BUG()) we need
|
* registers to report, but if we miss it (e.g. on BUG()) we need
|
||||||
|
@ -178,8 +178,10 @@ extern void efi_free_boot_services(void);
|
|||||||
extern pgd_t * __init efi_uv1_memmap_phys_prolog(void);
|
extern pgd_t * __init efi_uv1_memmap_phys_prolog(void);
|
||||||
extern void __init efi_uv1_memmap_phys_epilog(pgd_t *save_pgd);
|
extern void __init efi_uv1_memmap_phys_epilog(pgd_t *save_pgd);
|
||||||
|
|
||||||
|
/* kexec external ABI */
|
||||||
struct efi_setup_data {
|
struct efi_setup_data {
|
||||||
u64 fw_vendor;
|
u64 fw_vendor;
|
||||||
|
u64 __unused;
|
||||||
u64 tables;
|
u64 tables;
|
||||||
u64 smbios;
|
u64 smbios;
|
||||||
u64 reserved[8];
|
u64 reserved[8];
|
||||||
|
@ -41,7 +41,7 @@ struct microcode_amd {
|
|||||||
unsigned int mpb[0];
|
unsigned int mpb[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PATCH_MAX_SIZE PAGE_SIZE
|
#define PATCH_MAX_SIZE (3 * PAGE_SIZE)
|
||||||
|
|
||||||
#ifdef CONFIG_MICROCODE_AMD
|
#ifdef CONFIG_MICROCODE_AMD
|
||||||
extern void __init load_ucode_amd_bsp(unsigned int family);
|
extern void __init load_ucode_amd_bsp(unsigned int family);
|
||||||
|
@ -1119,35 +1119,53 @@ void switch_to_sld(unsigned long tifn)
|
|||||||
sld_update_msr(!(tifn & _TIF_SLD));
|
sld_update_msr(!(tifn & _TIF_SLD));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SPLIT_LOCK_CPU(model) {X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following processors have the split lock detection feature. But
|
* Bits in the IA32_CORE_CAPABILITIES are not architectural, so they should
|
||||||
* since they don't have the IA32_CORE_CAPABILITIES MSR, the feature cannot
|
* only be trusted if it is confirmed that a CPU model implements a
|
||||||
* be enumerated. Enable it by family and model matching on these
|
* specific feature at a particular bit position.
|
||||||
* processors.
|
*
|
||||||
|
* The possible driver data field values:
|
||||||
|
*
|
||||||
|
* - 0: CPU models that are known to have the per-core split-lock detection
|
||||||
|
* feature even though they do not enumerate IA32_CORE_CAPABILITIES.
|
||||||
|
*
|
||||||
|
* - 1: CPU models which may enumerate IA32_CORE_CAPABILITIES and if so use
|
||||||
|
* bit 5 to enumerate the per-core split-lock detection feature.
|
||||||
*/
|
*/
|
||||||
static const struct x86_cpu_id split_lock_cpu_ids[] __initconst = {
|
static const struct x86_cpu_id split_lock_cpu_ids[] __initconst = {
|
||||||
SPLIT_LOCK_CPU(INTEL_FAM6_ICELAKE_X),
|
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, 0),
|
||||||
SPLIT_LOCK_CPU(INTEL_FAM6_ICELAKE_L),
|
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, 0),
|
||||||
|
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT, 1),
|
||||||
|
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, 1),
|
||||||
|
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L, 1),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c)
|
void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c)
|
||||||
{
|
{
|
||||||
u64 ia32_core_caps = 0;
|
const struct x86_cpu_id *m;
|
||||||
|
u64 ia32_core_caps;
|
||||||
|
|
||||||
if (c->x86_vendor != X86_VENDOR_INTEL)
|
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
|
||||||
return;
|
return;
|
||||||
if (cpu_has(c, X86_FEATURE_CORE_CAPABILITIES)) {
|
|
||||||
/* Enumerate features reported in IA32_CORE_CAPABILITIES MSR. */
|
m = x86_match_cpu(split_lock_cpu_ids);
|
||||||
|
if (!m)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (m->driver_data) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (!cpu_has(c, X86_FEATURE_CORE_CAPABILITIES))
|
||||||
|
return;
|
||||||
rdmsrl(MSR_IA32_CORE_CAPS, ia32_core_caps);
|
rdmsrl(MSR_IA32_CORE_CAPS, ia32_core_caps);
|
||||||
} else if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) {
|
if (!(ia32_core_caps & MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT))
|
||||||
/* Enumerate split lock detection by family and model. */
|
return;
|
||||||
if (x86_match_cpu(split_lock_cpu_ids))
|
break;
|
||||||
ia32_core_caps |= MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT;
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ia32_core_caps & MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT)
|
split_lock_setup();
|
||||||
split_lock_setup();
|
|
||||||
}
|
}
|
||||||
|
@ -227,8 +227,8 @@ static void __init ms_hyperv_init_platform(void)
|
|||||||
ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES);
|
ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES);
|
||||||
ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
|
ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
|
||||||
|
|
||||||
pr_info("Hyper-V: features 0x%x, hints 0x%x\n",
|
pr_info("Hyper-V: features 0x%x, hints 0x%x, misc 0x%x\n",
|
||||||
ms_hyperv.features, ms_hyperv.hints);
|
ms_hyperv.features, ms_hyperv.hints, ms_hyperv.misc_features);
|
||||||
|
|
||||||
ms_hyperv.max_vp_index = cpuid_eax(HYPERV_CPUID_IMPLEMENT_LIMITS);
|
ms_hyperv.max_vp_index = cpuid_eax(HYPERV_CPUID_IMPLEMENT_LIMITS);
|
||||||
ms_hyperv.max_lp_index = cpuid_ebx(HYPERV_CPUID_IMPLEMENT_LIMITS);
|
ms_hyperv.max_lp_index = cpuid_ebx(HYPERV_CPUID_IMPLEMENT_LIMITS);
|
||||||
@ -263,6 +263,16 @@ static void __init ms_hyperv_init_platform(void)
|
|||||||
cpuid_eax(HYPERV_CPUID_NESTED_FEATURES);
|
cpuid_eax(HYPERV_CPUID_NESTED_FEATURES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hyper-V expects to get crash register data or kmsg when
|
||||||
|
* crash enlightment is available and system crashes. Set
|
||||||
|
* crash_kexec_post_notifiers to be true to make sure that
|
||||||
|
* calling crash enlightment interface before running kdump
|
||||||
|
* kernel.
|
||||||
|
*/
|
||||||
|
if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE)
|
||||||
|
crash_kexec_post_notifiers = true;
|
||||||
|
|
||||||
#ifdef CONFIG_X86_LOCAL_APIC
|
#ifdef CONFIG_X86_LOCAL_APIC
|
||||||
if (ms_hyperv.features & HV_X64_ACCESS_FREQUENCY_MSRS &&
|
if (ms_hyperv.features & HV_X64_ACCESS_FREQUENCY_MSRS &&
|
||||||
ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
|
ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
|
||||||
|
@ -578,6 +578,8 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
|
|||||||
d->id = id;
|
d->id = id;
|
||||||
cpumask_set_cpu(cpu, &d->cpu_mask);
|
cpumask_set_cpu(cpu, &d->cpu_mask);
|
||||||
|
|
||||||
|
rdt_domain_reconfigure_cdp(r);
|
||||||
|
|
||||||
if (r->alloc_capable && domain_setup_ctrlval(r, d)) {
|
if (r->alloc_capable && domain_setup_ctrlval(r, d)) {
|
||||||
kfree(d);
|
kfree(d);
|
||||||
return;
|
return;
|
||||||
|
@ -601,5 +601,6 @@ bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d);
|
|||||||
void __check_limbo(struct rdt_domain *d, bool force_free);
|
void __check_limbo(struct rdt_domain *d, bool force_free);
|
||||||
bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r);
|
bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r);
|
||||||
bool cbm_validate_amd(char *buf, u32 *data, struct rdt_resource *r);
|
bool cbm_validate_amd(char *buf, u32 *data, struct rdt_resource *r);
|
||||||
|
void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
|
||||||
|
|
||||||
#endif /* _ASM_X86_RESCTRL_INTERNAL_H */
|
#endif /* _ASM_X86_RESCTRL_INTERNAL_H */
|
||||||
|
@ -1859,6 +1859,19 @@ static int set_cache_qos_cfg(int level, bool enable)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Restore the qos cfg state when a domain comes online */
|
||||||
|
void rdt_domain_reconfigure_cdp(struct rdt_resource *r)
|
||||||
|
{
|
||||||
|
if (!r->alloc_capable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (r == &rdt_resources_all[RDT_RESOURCE_L2DATA])
|
||||||
|
l2_qos_cfg_update(&r->alloc_enabled);
|
||||||
|
|
||||||
|
if (r == &rdt_resources_all[RDT_RESOURCE_L3DATA])
|
||||||
|
l3_qos_cfg_update(&r->alloc_enabled);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable or disable the MBA software controller
|
* Enable or disable the MBA software controller
|
||||||
* which helps user specify bandwidth in MBps.
|
* which helps user specify bandwidth in MBps.
|
||||||
@ -3072,7 +3085,8 @@ static int rdtgroup_rmdir(struct kernfs_node *kn)
|
|||||||
* If the rdtgroup is a mon group and parent directory
|
* If the rdtgroup is a mon group and parent directory
|
||||||
* is a valid "mon_groups" directory, remove the mon group.
|
* is a valid "mon_groups" directory, remove the mon group.
|
||||||
*/
|
*/
|
||||||
if (rdtgrp->type == RDTCTRL_GROUP && parent_kn == rdtgroup_default.kn) {
|
if (rdtgrp->type == RDTCTRL_GROUP && parent_kn == rdtgroup_default.kn &&
|
||||||
|
rdtgrp != &rdtgroup_default) {
|
||||||
if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP ||
|
if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP ||
|
||||||
rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED) {
|
rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED) {
|
||||||
ret = rdtgroup_ctrl_remove(kn, rdtgrp);
|
ret = rdtgroup_ctrl_remove(kn, rdtgrp);
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
#define UMIP_INST_SLDT 3 /* 0F 00 /0 */
|
#define UMIP_INST_SLDT 3 /* 0F 00 /0 */
|
||||||
#define UMIP_INST_STR 4 /* 0F 00 /1 */
|
#define UMIP_INST_STR 4 /* 0F 00 /1 */
|
||||||
|
|
||||||
const char * const umip_insns[5] = {
|
static const char * const umip_insns[5] = {
|
||||||
[UMIP_INST_SGDT] = "SGDT",
|
[UMIP_INST_SGDT] = "SGDT",
|
||||||
[UMIP_INST_SIDT] = "SIDT",
|
[UMIP_INST_SIDT] = "SIDT",
|
||||||
[UMIP_INST_SMSW] = "SMSW",
|
[UMIP_INST_SMSW] = "SMSW",
|
||||||
|
@ -202,7 +202,7 @@ virt_to_phys_or_null_size(void *va, unsigned long size)
|
|||||||
|
|
||||||
int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
|
int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
|
||||||
{
|
{
|
||||||
unsigned long pfn, text, pf;
|
unsigned long pfn, text, pf, rodata;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
unsigned npages;
|
unsigned npages;
|
||||||
pgd_t *pgd = efi_mm.pgd;
|
pgd_t *pgd = efi_mm.pgd;
|
||||||
@ -256,7 +256,7 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
|
|||||||
|
|
||||||
efi_scratch.phys_stack = page_to_phys(page + 1); /* stack grows down */
|
efi_scratch.phys_stack = page_to_phys(page + 1); /* stack grows down */
|
||||||
|
|
||||||
npages = (__end_rodata_aligned - _text) >> PAGE_SHIFT;
|
npages = (_etext - _text) >> PAGE_SHIFT;
|
||||||
text = __pa(_text);
|
text = __pa(_text);
|
||||||
pfn = text >> PAGE_SHIFT;
|
pfn = text >> PAGE_SHIFT;
|
||||||
|
|
||||||
@ -266,6 +266,14 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
npages = (__end_rodata - __start_rodata) >> PAGE_SHIFT;
|
||||||
|
rodata = __pa(__start_rodata);
|
||||||
|
pfn = rodata >> PAGE_SHIFT;
|
||||||
|
if (kernel_map_pages_in_pgd(pgd, pfn, rodata, npages, pf)) {
|
||||||
|
pr_err("Failed to map kernel rodata 1:1\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,7 +646,7 @@ efi_thunk_set_variable(efi_char16_t *name, efi_guid_t *vendor,
|
|||||||
phys_vendor = virt_to_phys_or_null(vnd);
|
phys_vendor = virt_to_phys_or_null(vnd);
|
||||||
phys_data = virt_to_phys_or_null_size(data, data_size);
|
phys_data = virt_to_phys_or_null_size(data, data_size);
|
||||||
|
|
||||||
if (!phys_name || !phys_data)
|
if (!phys_name || (data && !phys_data))
|
||||||
status = EFI_INVALID_PARAMETER;
|
status = EFI_INVALID_PARAMETER;
|
||||||
else
|
else
|
||||||
status = efi_thunk(set_variable, phys_name, phys_vendor,
|
status = efi_thunk(set_variable, phys_name, phys_vendor,
|
||||||
@ -669,7 +677,7 @@ efi_thunk_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor,
|
|||||||
phys_vendor = virt_to_phys_or_null(vnd);
|
phys_vendor = virt_to_phys_or_null(vnd);
|
||||||
phys_data = virt_to_phys_or_null_size(data, data_size);
|
phys_data = virt_to_phys_or_null_size(data, data_size);
|
||||||
|
|
||||||
if (!phys_name || !phys_data)
|
if (!phys_name || (data && !phys_data))
|
||||||
status = EFI_INVALID_PARAMETER;
|
status = EFI_INVALID_PARAMETER;
|
||||||
else
|
else
|
||||||
status = efi_thunk(set_variable, phys_name, phys_vendor,
|
status = efi_thunk(set_variable, phys_name, phys_vendor,
|
||||||
|
@ -1222,8 +1222,10 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list,
|
|||||||
rq = list_first_entry(list, struct request, queuelist);
|
rq = list_first_entry(list, struct request, queuelist);
|
||||||
|
|
||||||
hctx = rq->mq_hctx;
|
hctx = rq->mq_hctx;
|
||||||
if (!got_budget && !blk_mq_get_dispatch_budget(hctx))
|
if (!got_budget && !blk_mq_get_dispatch_budget(hctx)) {
|
||||||
|
blk_mq_put_driver_tag(rq);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!blk_mq_get_driver_tag(rq)) {
|
if (!blk_mq_get_driver_tag(rq)) {
|
||||||
/*
|
/*
|
||||||
|
@ -313,7 +313,7 @@ static void scale_up(struct rq_wb *rwb)
|
|||||||
calc_wb_limits(rwb);
|
calc_wb_limits(rwb);
|
||||||
rwb->unknown_cnt = 0;
|
rwb->unknown_cnt = 0;
|
||||||
rwb_wake_all(rwb);
|
rwb_wake_all(rwb);
|
||||||
rwb_trace_step(rwb, "scale up");
|
rwb_trace_step(rwb, tracepoint_string("scale up"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scale_down(struct rq_wb *rwb, bool hard_throttle)
|
static void scale_down(struct rq_wb *rwb, bool hard_throttle)
|
||||||
@ -322,7 +322,7 @@ static void scale_down(struct rq_wb *rwb, bool hard_throttle)
|
|||||||
return;
|
return;
|
||||||
calc_wb_limits(rwb);
|
calc_wb_limits(rwb);
|
||||||
rwb->unknown_cnt = 0;
|
rwb->unknown_cnt = 0;
|
||||||
rwb_trace_step(rwb, "scale down");
|
rwb_trace_step(rwb, tracepoint_string("scale down"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rwb_arm_timer(struct rq_wb *rwb)
|
static void rwb_arm_timer(struct rq_wb *rwb)
|
||||||
|
@ -410,6 +410,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
|||||||
{ PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */
|
{ PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */
|
||||||
{ PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_mobile }, /* ApolloLake AHCI */
|
{ PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_mobile }, /* ApolloLake AHCI */
|
||||||
{ PCI_VDEVICE(INTEL, 0x34d3), board_ahci_mobile }, /* Ice Lake LP AHCI */
|
{ PCI_VDEVICE(INTEL, 0x34d3), board_ahci_mobile }, /* Ice Lake LP AHCI */
|
||||||
|
{ PCI_VDEVICE(INTEL, 0x02d3), board_ahci_mobile }, /* Comet Lake PCH-U AHCI */
|
||||||
{ PCI_VDEVICE(INTEL, 0x02d7), board_ahci_mobile }, /* Comet Lake PCH RAID */
|
{ PCI_VDEVICE(INTEL, 0x02d7), board_ahci_mobile }, /* Comet Lake PCH RAID */
|
||||||
|
|
||||||
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
|
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
|
||||||
|
@ -3891,6 +3891,7 @@ void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
|
|||||||
else
|
else
|
||||||
dev->fwnode = fwnode;
|
dev->fwnode = fwnode;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(set_secondary_fwnode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* device_set_of_node_from_dev - reuse device-tree node of another device
|
* device_set_of_node_from_dev - reuse device-tree node of another device
|
||||||
|
@ -726,6 +726,54 @@ void software_node_unregister_nodes(const struct software_node *nodes)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(software_node_unregister_nodes);
|
EXPORT_SYMBOL_GPL(software_node_unregister_nodes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* software_node_register_node_group - Register a group of software nodes
|
||||||
|
* @node_group: NULL terminated array of software node pointers to be registered
|
||||||
|
*
|
||||||
|
* Register multiple software nodes at once.
|
||||||
|
*/
|
||||||
|
int software_node_register_node_group(const struct software_node **node_group)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!node_group)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; node_group[i]; i++) {
|
||||||
|
ret = software_node_register(node_group[i]);
|
||||||
|
if (ret) {
|
||||||
|
software_node_unregister_node_group(node_group);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(software_node_register_node_group);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* software_node_unregister_node_group - Unregister a group of software nodes
|
||||||
|
* @node_group: NULL terminated array of software node pointers to be unregistered
|
||||||
|
*
|
||||||
|
* Unregister multiple software nodes at once.
|
||||||
|
*/
|
||||||
|
void software_node_unregister_node_group(const struct software_node **node_group)
|
||||||
|
{
|
||||||
|
struct swnode *swnode;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (!node_group)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; node_group[i]; i++) {
|
||||||
|
swnode = software_node_to_swnode(node_group[i]);
|
||||||
|
if (swnode)
|
||||||
|
fwnode_remove_software_node(&swnode->fwnode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(software_node_unregister_node_group);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* software_node_register - Register static software node
|
* software_node_register - Register static software node
|
||||||
* @node: The software node to be registered
|
* @node: The software node to be registered
|
||||||
|
@ -3754,11 +3754,7 @@ static int __rbd_notify_op_lock(struct rbd_device *rbd_dev,
|
|||||||
static void rbd_notify_op_lock(struct rbd_device *rbd_dev,
|
static void rbd_notify_op_lock(struct rbd_device *rbd_dev,
|
||||||
enum rbd_notify_op notify_op)
|
enum rbd_notify_op notify_op)
|
||||||
{
|
{
|
||||||
struct page **reply_pages;
|
__rbd_notify_op_lock(rbd_dev, notify_op, NULL, NULL);
|
||||||
size_t reply_len;
|
|
||||||
|
|
||||||
__rbd_notify_op_lock(rbd_dev, notify_op, &reply_pages, &reply_len);
|
|
||||||
ceph_release_page_vector(reply_pages, calc_pages_for(0, reply_len));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rbd_notify_acquired_lock(struct work_struct *work)
|
static void rbd_notify_acquired_lock(struct work_struct *work)
|
||||||
@ -4527,6 +4523,10 @@ static void cancel_tasks_sync(struct rbd_device *rbd_dev)
|
|||||||
cancel_work_sync(&rbd_dev->unlock_work);
|
cancel_work_sync(&rbd_dev->unlock_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* header_rwsem must not be held to avoid a deadlock with
|
||||||
|
* rbd_dev_refresh() when flushing notifies.
|
||||||
|
*/
|
||||||
static void rbd_unregister_watch(struct rbd_device *rbd_dev)
|
static void rbd_unregister_watch(struct rbd_device *rbd_dev)
|
||||||
{
|
{
|
||||||
cancel_tasks_sync(rbd_dev);
|
cancel_tasks_sync(rbd_dev);
|
||||||
@ -6894,9 +6894,10 @@ static void rbd_print_dne(struct rbd_device *rbd_dev, bool is_snap)
|
|||||||
|
|
||||||
static void rbd_dev_image_release(struct rbd_device *rbd_dev)
|
static void rbd_dev_image_release(struct rbd_device *rbd_dev)
|
||||||
{
|
{
|
||||||
rbd_dev_unprobe(rbd_dev);
|
if (!rbd_is_ro(rbd_dev))
|
||||||
if (rbd_dev->opts)
|
|
||||||
rbd_unregister_watch(rbd_dev);
|
rbd_unregister_watch(rbd_dev);
|
||||||
|
|
||||||
|
rbd_dev_unprobe(rbd_dev);
|
||||||
rbd_dev->image_format = 0;
|
rbd_dev->image_format = 0;
|
||||||
kfree(rbd_dev->spec->image_id);
|
kfree(rbd_dev->spec->image_id);
|
||||||
rbd_dev->spec->image_id = NULL;
|
rbd_dev->spec->image_id = NULL;
|
||||||
@ -6907,6 +6908,9 @@ static void rbd_dev_image_release(struct rbd_device *rbd_dev)
|
|||||||
* device. If this image is the one being mapped (i.e., not a
|
* device. If this image is the one being mapped (i.e., not a
|
||||||
* parent), initiate a watch on its header object before using that
|
* parent), initiate a watch on its header object before using that
|
||||||
* object to get detailed information about the rbd image.
|
* object to get detailed information about the rbd image.
|
||||||
|
*
|
||||||
|
* On success, returns with header_rwsem held for write if called
|
||||||
|
* with @depth == 0.
|
||||||
*/
|
*/
|
||||||
static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
|
static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
|
||||||
{
|
{
|
||||||
@ -6936,11 +6940,14 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!depth)
|
||||||
|
down_write(&rbd_dev->header_rwsem);
|
||||||
|
|
||||||
ret = rbd_dev_header_info(rbd_dev);
|
ret = rbd_dev_header_info(rbd_dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (ret == -ENOENT && !need_watch)
|
if (ret == -ENOENT && !need_watch)
|
||||||
rbd_print_dne(rbd_dev, false);
|
rbd_print_dne(rbd_dev, false);
|
||||||
goto err_out_watch;
|
goto err_out_probe;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -6985,10 +6992,11 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_out_probe:
|
err_out_probe:
|
||||||
rbd_dev_unprobe(rbd_dev);
|
if (!depth)
|
||||||
err_out_watch:
|
up_write(&rbd_dev->header_rwsem);
|
||||||
if (need_watch)
|
if (need_watch)
|
||||||
rbd_unregister_watch(rbd_dev);
|
rbd_unregister_watch(rbd_dev);
|
||||||
|
rbd_dev_unprobe(rbd_dev);
|
||||||
err_out_format:
|
err_out_format:
|
||||||
rbd_dev->image_format = 0;
|
rbd_dev->image_format = 0;
|
||||||
kfree(rbd_dev->spec->image_id);
|
kfree(rbd_dev->spec->image_id);
|
||||||
@ -7050,12 +7058,9 @@ static ssize_t do_rbd_add(struct bus_type *bus,
|
|||||||
goto err_out_rbd_dev;
|
goto err_out_rbd_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
down_write(&rbd_dev->header_rwsem);
|
|
||||||
rc = rbd_dev_image_probe(rbd_dev, 0);
|
rc = rbd_dev_image_probe(rbd_dev, 0);
|
||||||
if (rc < 0) {
|
if (rc < 0)
|
||||||
up_write(&rbd_dev->header_rwsem);
|
|
||||||
goto err_out_rbd_dev;
|
goto err_out_rbd_dev;
|
||||||
}
|
|
||||||
|
|
||||||
if (rbd_dev->opts->alloc_size > rbd_dev->layout.object_size) {
|
if (rbd_dev->opts->alloc_size > rbd_dev->layout.object_size) {
|
||||||
rbd_warn(rbd_dev, "alloc_size adjusted to %u",
|
rbd_warn(rbd_dev, "alloc_size adjusted to %u",
|
||||||
|
@ -276,7 +276,7 @@ static void __init asm9260_acc_init(struct device_node *np)
|
|||||||
|
|
||||||
/* TODO: Convert to DT parent scheme */
|
/* TODO: Convert to DT parent scheme */
|
||||||
ref_clk = of_clk_get_parent_name(np, 0);
|
ref_clk = of_clk_get_parent_name(np, 0);
|
||||||
hw = __clk_hw_register_fixed_rate_with_accuracy(NULL, NULL, pll_clk,
|
hw = __clk_hw_register_fixed_rate(NULL, NULL, pll_clk,
|
||||||
ref_clk, NULL, NULL, 0, rate, 0,
|
ref_clk, NULL, NULL, 0, rate, 0,
|
||||||
CLK_FIXED_RATE_PARENT_ACCURACY);
|
CLK_FIXED_RATE_PARENT_ACCURACY);
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ static const struct clk_ops mmp_clk_pll_ops = {
|
|||||||
.recalc_rate = mmp_clk_pll_recalc_rate,
|
.recalc_rate = mmp_clk_pll_recalc_rate,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct clk *mmp_clk_register_pll(char *name,
|
static struct clk *mmp_clk_register_pll(char *name,
|
||||||
unsigned long default_rate,
|
unsigned long default_rate,
|
||||||
void __iomem *enable_reg, u32 enable,
|
void __iomem *enable_reg, u32 enable,
|
||||||
void __iomem *reg, u8 shift,
|
void __iomem *reg, u8 shift,
|
||||||
@ -137,3 +137,34 @@ struct clk *mmp_clk_register_pll(char *name,
|
|||||||
|
|
||||||
return clk;
|
return clk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mmp_register_pll_clks(struct mmp_clk_unit *unit,
|
||||||
|
struct mmp_param_pll_clk *clks,
|
||||||
|
void __iomem *base, int size)
|
||||||
|
{
|
||||||
|
struct clk *clk;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
void __iomem *reg = NULL;
|
||||||
|
|
||||||
|
if (clks[i].offset)
|
||||||
|
reg = base + clks[i].offset;
|
||||||
|
|
||||||
|
clk = mmp_clk_register_pll(clks[i].name,
|
||||||
|
clks[i].default_rate,
|
||||||
|
base + clks[i].enable_offset,
|
||||||
|
clks[i].enable,
|
||||||
|
reg, clks[i].shift,
|
||||||
|
clks[i].input_rate,
|
||||||
|
base + clks[i].postdiv_offset,
|
||||||
|
clks[i].postdiv_shift);
|
||||||
|
if (IS_ERR(clk)) {
|
||||||
|
pr_err("%s: failed to register clock %s\n",
|
||||||
|
__func__, clks[i].name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (clks[i].id)
|
||||||
|
unit->clk_table[clks[i].id] = clk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -176,37 +176,6 @@ void mmp_register_div_clks(struct mmp_clk_unit *unit,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mmp_register_pll_clks(struct mmp_clk_unit *unit,
|
|
||||||
struct mmp_param_pll_clk *clks,
|
|
||||||
void __iomem *base, int size)
|
|
||||||
{
|
|
||||||
struct clk *clk;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < size; i++) {
|
|
||||||
void __iomem *reg = NULL;
|
|
||||||
|
|
||||||
if (clks[i].offset)
|
|
||||||
reg = base + clks[i].offset;
|
|
||||||
|
|
||||||
clk = mmp_clk_register_pll(clks[i].name,
|
|
||||||
clks[i].default_rate,
|
|
||||||
base + clks[i].enable_offset,
|
|
||||||
clks[i].enable,
|
|
||||||
reg, clks[i].shift,
|
|
||||||
clks[i].input_rate,
|
|
||||||
base + clks[i].postdiv_offset,
|
|
||||||
clks[i].postdiv_shift);
|
|
||||||
if (IS_ERR(clk)) {
|
|
||||||
pr_err("%s: failed to register clock %s\n",
|
|
||||||
__func__, clks[i].name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (clks[i].id)
|
|
||||||
unit->clk_table[clks[i].id] = clk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
|
void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
|
||||||
struct clk *clk)
|
struct clk *clk)
|
||||||
{
|
{
|
||||||
|
@ -238,13 +238,6 @@ void mmp_register_pll_clks(struct mmp_clk_unit *unit,
|
|||||||
struct mmp_param_pll_clk *clks,
|
struct mmp_param_pll_clk *clks,
|
||||||
void __iomem *base, int size);
|
void __iomem *base, int size);
|
||||||
|
|
||||||
extern struct clk *mmp_clk_register_pll(char *name,
|
|
||||||
unsigned long default_rate,
|
|
||||||
void __iomem *enable_reg, u32 enable,
|
|
||||||
void __iomem *reg, u8 shift,
|
|
||||||
unsigned long input_rate,
|
|
||||||
void __iomem *postdiv_reg, u8 postdiv_shift);
|
|
||||||
|
|
||||||
#define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc) \
|
#define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc) \
|
||||||
{ \
|
{ \
|
||||||
.width_div = (w_d), \
|
.width_div = (w_d), \
|
||||||
|
@ -1641,8 +1641,9 @@ static SPRD_SC_GATE_CLK_FW_NAME(i2c4_eb, "i2c4-eb", "ext-26m", 0x0,
|
|||||||
0x1000, BIT(12), 0, 0);
|
0x1000, BIT(12), 0, 0);
|
||||||
static SPRD_SC_GATE_CLK_FW_NAME(uart0_eb, "uart0-eb", "ext-26m", 0x0,
|
static SPRD_SC_GATE_CLK_FW_NAME(uart0_eb, "uart0-eb", "ext-26m", 0x0,
|
||||||
0x1000, BIT(13), 0, 0);
|
0x1000, BIT(13), 0, 0);
|
||||||
|
/* uart1_eb is for console, don't gate even if unused */
|
||||||
static SPRD_SC_GATE_CLK_FW_NAME(uart1_eb, "uart1-eb", "ext-26m", 0x0,
|
static SPRD_SC_GATE_CLK_FW_NAME(uart1_eb, "uart1-eb", "ext-26m", 0x0,
|
||||||
0x1000, BIT(14), 0, 0);
|
0x1000, BIT(14), CLK_IGNORE_UNUSED, 0);
|
||||||
static SPRD_SC_GATE_CLK_FW_NAME(uart2_eb, "uart2-eb", "ext-26m", 0x0,
|
static SPRD_SC_GATE_CLK_FW_NAME(uart2_eb, "uart2-eb", "ext-26m", 0x0,
|
||||||
0x1000, BIT(15), 0, 0);
|
0x1000, BIT(15), 0, 0);
|
||||||
static SPRD_SC_GATE_CLK_FW_NAME(uart3_eb, "uart3-eb", "ext-26m", 0x0,
|
static SPRD_SC_GATE_CLK_FW_NAME(uart3_eb, "uart3-eb", "ext-26m", 0x0,
|
||||||
|
@ -101,7 +101,7 @@ void cper_print_bits(const char *pfx, unsigned int bits,
|
|||||||
if (!len)
|
if (!len)
|
||||||
len = snprintf(buf, sizeof(buf), "%s%s", pfx, str);
|
len = snprintf(buf, sizeof(buf), "%s%s", pfx, str);
|
||||||
else
|
else
|
||||||
len += snprintf(buf+len, sizeof(buf)-len, ", %s", str);
|
len += scnprintf(buf+len, sizeof(buf)-len, ", %s", str);
|
||||||
}
|
}
|
||||||
if (len)
|
if (len)
|
||||||
printk("%s\n", buf);
|
printk("%s\n", buf);
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#define EFI_ALLOC_ALIGN EFI_PAGE_SIZE
|
#define EFI_ALLOC_ALIGN EFI_PAGE_SIZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ARM
|
#if defined(CONFIG_ARM) || defined(CONFIG_X86)
|
||||||
#define __efistub_global __section(.data)
|
#define __efistub_global __section(.data)
|
||||||
#else
|
#else
|
||||||
#define __efistub_global
|
#define __efistub_global
|
||||||
|
@ -29,30 +29,31 @@
|
|||||||
*/
|
*/
|
||||||
#define EFI_READ_CHUNK_SIZE SZ_1M
|
#define EFI_READ_CHUNK_SIZE SZ_1M
|
||||||
|
|
||||||
|
struct finfo {
|
||||||
|
efi_file_info_t info;
|
||||||
|
efi_char16_t filename[MAX_FILENAME_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
static efi_status_t efi_open_file(efi_file_protocol_t *volume,
|
static efi_status_t efi_open_file(efi_file_protocol_t *volume,
|
||||||
efi_char16_t *filename_16,
|
struct finfo *fi,
|
||||||
efi_file_protocol_t **handle,
|
efi_file_protocol_t **handle,
|
||||||
unsigned long *file_size)
|
unsigned long *file_size)
|
||||||
{
|
{
|
||||||
struct {
|
|
||||||
efi_file_info_t info;
|
|
||||||
efi_char16_t filename[MAX_FILENAME_SIZE];
|
|
||||||
} finfo;
|
|
||||||
efi_guid_t info_guid = EFI_FILE_INFO_ID;
|
efi_guid_t info_guid = EFI_FILE_INFO_ID;
|
||||||
efi_file_protocol_t *fh;
|
efi_file_protocol_t *fh;
|
||||||
unsigned long info_sz;
|
unsigned long info_sz;
|
||||||
efi_status_t status;
|
efi_status_t status;
|
||||||
|
|
||||||
status = volume->open(volume, &fh, filename_16, EFI_FILE_MODE_READ, 0);
|
status = volume->open(volume, &fh, fi->filename, EFI_FILE_MODE_READ, 0);
|
||||||
if (status != EFI_SUCCESS) {
|
if (status != EFI_SUCCESS) {
|
||||||
pr_efi_err("Failed to open file: ");
|
pr_efi_err("Failed to open file: ");
|
||||||
efi_char16_printk(filename_16);
|
efi_char16_printk(fi->filename);
|
||||||
efi_printk("\n");
|
efi_printk("\n");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
info_sz = sizeof(finfo);
|
info_sz = sizeof(struct finfo);
|
||||||
status = fh->get_info(fh, &info_guid, &info_sz, &finfo);
|
status = fh->get_info(fh, &info_guid, &info_sz, fi);
|
||||||
if (status != EFI_SUCCESS) {
|
if (status != EFI_SUCCESS) {
|
||||||
pr_efi_err("Failed to get file info\n");
|
pr_efi_err("Failed to get file info\n");
|
||||||
fh->close(fh);
|
fh->close(fh);
|
||||||
@ -60,7 +61,7 @@ static efi_status_t efi_open_file(efi_file_protocol_t *volume,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*handle = fh;
|
*handle = fh;
|
||||||
*file_size = finfo.info.file_size;
|
*file_size = fi->info.file_size;
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,13 +147,13 @@ static efi_status_t handle_cmdline_files(efi_loaded_image_t *image,
|
|||||||
|
|
||||||
alloc_addr = alloc_size = 0;
|
alloc_addr = alloc_size = 0;
|
||||||
do {
|
do {
|
||||||
efi_char16_t filename[MAX_FILENAME_SIZE];
|
struct finfo fi;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
void *addr;
|
void *addr;
|
||||||
|
|
||||||
offset = find_file_option(cmdline, cmdline_len,
|
offset = find_file_option(cmdline, cmdline_len,
|
||||||
optstr, optstr_size,
|
optstr, optstr_size,
|
||||||
filename, ARRAY_SIZE(filename));
|
fi.filename, ARRAY_SIZE(fi.filename));
|
||||||
|
|
||||||
if (!offset)
|
if (!offset)
|
||||||
break;
|
break;
|
||||||
@ -166,7 +167,7 @@ static efi_status_t handle_cmdline_files(efi_loaded_image_t *image,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = efi_open_file(volume, filename, &file, &size);
|
status = efi_open_file(volume, &fi, &file, &size);
|
||||||
if (status != EFI_SUCCESS)
|
if (status != EFI_SUCCESS)
|
||||||
goto err_close_volume;
|
goto err_close_volume;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
/* Maximum physical address for 64-bit kernel with 4-level paging */
|
/* Maximum physical address for 64-bit kernel with 4-level paging */
|
||||||
#define MAXMEM_X86_64_4LEVEL (1ull << 46)
|
#define MAXMEM_X86_64_4LEVEL (1ull << 46)
|
||||||
|
|
||||||
static efi_system_table_t *sys_table;
|
static efi_system_table_t *sys_table __efistub_global;
|
||||||
extern const bool efi_is64;
|
extern const bool efi_is64;
|
||||||
extern u32 image_offset;
|
extern u32 image_offset;
|
||||||
|
|
||||||
@ -392,8 +392,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
|
|||||||
image_base = efi_table_attr(image, image_base);
|
image_base = efi_table_attr(image, image_base);
|
||||||
image_offset = (void *)startup_32 - image_base;
|
image_offset = (void *)startup_32 - image_base;
|
||||||
|
|
||||||
hdr = &((struct boot_params *)image_base)->hdr;
|
|
||||||
|
|
||||||
status = efi_allocate_pages(0x4000, (unsigned long *)&boot_params, ULONG_MAX);
|
status = efi_allocate_pages(0x4000, (unsigned long *)&boot_params, ULONG_MAX);
|
||||||
if (status != EFI_SUCCESS) {
|
if (status != EFI_SUCCESS) {
|
||||||
efi_printk("Failed to allocate lowmem for boot params\n");
|
efi_printk("Failed to allocate lowmem for boot params\n");
|
||||||
@ -742,8 +740,15 @@ unsigned long efi_main(efi_handle_t handle,
|
|||||||
* now use KERNEL_IMAGE_SIZE, which will be 512MiB, the same as what
|
* now use KERNEL_IMAGE_SIZE, which will be 512MiB, the same as what
|
||||||
* KASLR uses.
|
* KASLR uses.
|
||||||
*
|
*
|
||||||
* Also relocate it if image_offset is zero, i.e. we weren't loaded by
|
* Also relocate it if image_offset is zero, i.e. the kernel wasn't
|
||||||
* LoadImage, but we are not aligned correctly.
|
* loaded by LoadImage, but rather by a bootloader that called the
|
||||||
|
* handover entry. The reason we must always relocate in this case is
|
||||||
|
* to handle the case of systemd-boot booting a unified kernel image,
|
||||||
|
* which is a PE executable that contains the bzImage and an initrd as
|
||||||
|
* COFF sections. The initrd section is placed after the bzImage
|
||||||
|
* without ensuring that there are at least init_size bytes available
|
||||||
|
* for the bzImage, and thus the compressed kernel's startup code may
|
||||||
|
* overwrite the initrd unless it is moved out of the way.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
buffer_start = ALIGN(bzimage_addr - image_offset,
|
buffer_start = ALIGN(bzimage_addr - image_offset,
|
||||||
@ -753,8 +758,7 @@ unsigned long efi_main(efi_handle_t handle,
|
|||||||
if ((buffer_start < LOAD_PHYSICAL_ADDR) ||
|
if ((buffer_start < LOAD_PHYSICAL_ADDR) ||
|
||||||
(IS_ENABLED(CONFIG_X86_32) && buffer_end > KERNEL_IMAGE_SIZE) ||
|
(IS_ENABLED(CONFIG_X86_32) && buffer_end > KERNEL_IMAGE_SIZE) ||
|
||||||
(IS_ENABLED(CONFIG_X86_64) && buffer_end > MAXMEM_X86_64_4LEVEL) ||
|
(IS_ENABLED(CONFIG_X86_64) && buffer_end > MAXMEM_X86_64_4LEVEL) ||
|
||||||
(image_offset == 0 && !IS_ALIGNED(bzimage_addr,
|
(image_offset == 0)) {
|
||||||
hdr->kernel_alignment))) {
|
|
||||||
status = efi_relocate_kernel(&bzimage_addr,
|
status = efi_relocate_kernel(&bzimage_addr,
|
||||||
hdr->init_size, hdr->init_size,
|
hdr->init_size, hdr->init_size,
|
||||||
hdr->pref_address,
|
hdr->pref_address,
|
||||||
|
@ -2008,8 +2008,24 @@ static void amdgpu_device_fill_reset_magic(struct amdgpu_device *adev)
|
|||||||
*/
|
*/
|
||||||
static bool amdgpu_device_check_vram_lost(struct amdgpu_device *adev)
|
static bool amdgpu_device_check_vram_lost(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
return !!memcmp(adev->gart.ptr, adev->reset_magic,
|
if (memcmp(adev->gart.ptr, adev->reset_magic,
|
||||||
AMDGPU_RESET_MAGIC_NUM);
|
AMDGPU_RESET_MAGIC_NUM))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!adev->in_gpu_reset)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For all ASICs with baco/mode1 reset, the VRAM is
|
||||||
|
* always assumed to be lost.
|
||||||
|
*/
|
||||||
|
switch (amdgpu_asic_reset_method(adev)) {
|
||||||
|
case AMD_RESET_METHOD_BACO:
|
||||||
|
case AMD_RESET_METHOD_MODE1:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2340,6 +2356,8 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev)
|
|||||||
{
|
{
|
||||||
int i, r;
|
int i, r;
|
||||||
|
|
||||||
|
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
|
||||||
|
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
|
||||||
|
|
||||||
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
|
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
|
||||||
if (!adev->ip_blocks[i].status.valid)
|
if (!adev->ip_blocks[i].status.valid)
|
||||||
|
@ -1358,8 +1358,6 @@ static int cik_asic_reset(struct amdgpu_device *adev)
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (cik_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
|
if (cik_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
|
||||||
if (!adev->in_suspend)
|
|
||||||
amdgpu_inc_vram_lost(adev);
|
|
||||||
r = amdgpu_dpm_baco_reset(adev);
|
r = amdgpu_dpm_baco_reset(adev);
|
||||||
} else {
|
} else {
|
||||||
r = cik_asic_pci_config_reset(adev);
|
r = cik_asic_pci_config_reset(adev);
|
||||||
|
@ -279,7 +279,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_1_2_nv12[] =
|
|||||||
|
|
||||||
#define DEFAULT_SH_MEM_CONFIG \
|
#define DEFAULT_SH_MEM_CONFIG \
|
||||||
((SH_MEM_ADDRESS_MODE_64 << SH_MEM_CONFIG__ADDRESS_MODE__SHIFT) | \
|
((SH_MEM_ADDRESS_MODE_64 << SH_MEM_CONFIG__ADDRESS_MODE__SHIFT) | \
|
||||||
(SH_MEM_ALIGNMENT_MODE_DWORD << SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT) | \
|
(SH_MEM_ALIGNMENT_MODE_UNALIGNED << SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT) | \
|
||||||
(SH_MEM_RETRY_MODE_ALL << SH_MEM_CONFIG__RETRY_MODE__SHIFT) | \
|
(SH_MEM_RETRY_MODE_ALL << SH_MEM_CONFIG__RETRY_MODE__SHIFT) | \
|
||||||
(3 << SH_MEM_CONFIG__INITIAL_INST_PREFETCH__SHIFT))
|
(3 << SH_MEM_CONFIG__INITIAL_INST_PREFETCH__SHIFT))
|
||||||
|
|
||||||
|
@ -1234,6 +1234,8 @@ struct amdgpu_gfxoff_quirk {
|
|||||||
static const struct amdgpu_gfxoff_quirk amdgpu_gfxoff_quirk_list[] = {
|
static const struct amdgpu_gfxoff_quirk amdgpu_gfxoff_quirk_list[] = {
|
||||||
/* https://bugzilla.kernel.org/show_bug.cgi?id=204689 */
|
/* https://bugzilla.kernel.org/show_bug.cgi?id=204689 */
|
||||||
{ 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc8 },
|
{ 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc8 },
|
||||||
|
/* https://bugzilla.kernel.org/show_bug.cgi?id=207171 */
|
||||||
|
{ 0x1002, 0x15dd, 0x103c, 0x83e7, 0xd3 },
|
||||||
{ 0, 0, 0, 0, 0 },
|
{ 0, 0, 0, 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -351,8 +351,6 @@ static int nv_asic_reset(struct amdgpu_device *adev)
|
|||||||
struct smu_context *smu = &adev->smu;
|
struct smu_context *smu = &adev->smu;
|
||||||
|
|
||||||
if (nv_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
|
if (nv_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
|
||||||
if (!adev->in_suspend)
|
|
||||||
amdgpu_inc_vram_lost(adev);
|
|
||||||
ret = smu_baco_enter(smu);
|
ret = smu_baco_enter(smu);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -360,8 +358,6 @@ static int nv_asic_reset(struct amdgpu_device *adev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
if (!adev->in_suspend)
|
|
||||||
amdgpu_inc_vram_lost(adev);
|
|
||||||
ret = nv_asic_mode1_reset(adev);
|
ret = nv_asic_mode1_reset(adev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,14 +569,10 @@ static int soc15_asic_reset(struct amdgpu_device *adev)
|
|||||||
|
|
||||||
switch (soc15_asic_reset_method(adev)) {
|
switch (soc15_asic_reset_method(adev)) {
|
||||||
case AMD_RESET_METHOD_BACO:
|
case AMD_RESET_METHOD_BACO:
|
||||||
if (!adev->in_suspend)
|
|
||||||
amdgpu_inc_vram_lost(adev);
|
|
||||||
return soc15_asic_baco_reset(adev);
|
return soc15_asic_baco_reset(adev);
|
||||||
case AMD_RESET_METHOD_MODE2:
|
case AMD_RESET_METHOD_MODE2:
|
||||||
return amdgpu_dpm_mode2_reset(adev);
|
return amdgpu_dpm_mode2_reset(adev);
|
||||||
default:
|
default:
|
||||||
if (!adev->in_suspend)
|
|
||||||
amdgpu_inc_vram_lost(adev);
|
|
||||||
return soc15_asic_mode1_reset(adev);
|
return soc15_asic_mode1_reset(adev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -765,8 +765,6 @@ static int vi_asic_reset(struct amdgpu_device *adev)
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (vi_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
|
if (vi_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) {
|
||||||
if (!adev->in_suspend)
|
|
||||||
amdgpu_inc_vram_lost(adev);
|
|
||||||
r = amdgpu_dpm_baco_reset(adev);
|
r = amdgpu_dpm_baco_reset(adev);
|
||||||
} else {
|
} else {
|
||||||
r = vi_asic_pci_config_reset(adev);
|
r = vi_asic_pci_config_reset(adev);
|
||||||
|
@ -3804,9 +3804,12 @@ static int smu7_trim_single_dpm_states(struct pp_hwmgr *hwmgr,
|
|||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
|
/* force the trim if mclk_switching is disabled to prevent flicker */
|
||||||
|
bool force_trim = (low_limit == high_limit);
|
||||||
for (i = 0; i < dpm_table->count; i++) {
|
for (i = 0; i < dpm_table->count; i++) {
|
||||||
/*skip the trim if od is enabled*/
|
/*skip the trim if od is enabled*/
|
||||||
if (!hwmgr->od_enabled && (dpm_table->dpm_levels[i].value < low_limit
|
if ((!hwmgr->od_enabled || force_trim)
|
||||||
|
&& (dpm_table->dpm_levels[i].value < low_limit
|
||||||
|| dpm_table->dpm_levels[i].value > high_limit))
|
|| dpm_table->dpm_levels[i].value > high_limit))
|
||||||
dpm_table->dpm_levels[i].enabled = false;
|
dpm_table->dpm_levels[i].enabled = false;
|
||||||
else
|
else
|
||||||
|
@ -1718,6 +1718,12 @@ int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (ras && ras->supported) {
|
||||||
|
ret = smu_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* clear vbios scratch 6 and 7 for coming asic reinit */
|
/* clear vbios scratch 6 and 7 for coming asic reinit */
|
||||||
WREG32(adev->bios_scratch_reg_offset + 6, 0);
|
WREG32(adev->bios_scratch_reg_offset + 6, 0);
|
||||||
WREG32(adev->bios_scratch_reg_offset + 7, 0);
|
WREG32(adev->bios_scratch_reg_offset + 7, 0);
|
||||||
|
@ -131,6 +131,7 @@ struct kvmgt_vdev {
|
|||||||
struct work_struct release_work;
|
struct work_struct release_work;
|
||||||
atomic_t released;
|
atomic_t released;
|
||||||
struct vfio_device *vfio_device;
|
struct vfio_device *vfio_device;
|
||||||
|
struct vfio_group *vfio_group;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct kvmgt_vdev *kvmgt_vdev(struct intel_vgpu *vgpu)
|
static inline struct kvmgt_vdev *kvmgt_vdev(struct intel_vgpu *vgpu)
|
||||||
@ -151,6 +152,7 @@ static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
|
|||||||
unsigned long size)
|
unsigned long size)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
|
struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
|
||||||
|
struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
|
||||||
int total_pages;
|
int total_pages;
|
||||||
int npage;
|
int npage;
|
||||||
int ret;
|
int ret;
|
||||||
@ -160,7 +162,7 @@ static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
|
|||||||
for (npage = 0; npage < total_pages; npage++) {
|
for (npage = 0; npage < total_pages; npage++) {
|
||||||
unsigned long cur_gfn = gfn + npage;
|
unsigned long cur_gfn = gfn + npage;
|
||||||
|
|
||||||
ret = vfio_unpin_pages(mdev_dev(kvmgt_vdev(vgpu)->mdev), &cur_gfn, 1);
|
ret = vfio_group_unpin_pages(vdev->vfio_group, &cur_gfn, 1);
|
||||||
drm_WARN_ON(&i915->drm, ret != 1);
|
drm_WARN_ON(&i915->drm, ret != 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,6 +171,7 @@ static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
|
|||||||
static int gvt_pin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
|
static int gvt_pin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
|
||||||
unsigned long size, struct page **page)
|
unsigned long size, struct page **page)
|
||||||
{
|
{
|
||||||
|
struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
|
||||||
unsigned long base_pfn = 0;
|
unsigned long base_pfn = 0;
|
||||||
int total_pages;
|
int total_pages;
|
||||||
int npage;
|
int npage;
|
||||||
@ -183,8 +186,8 @@ static int gvt_pin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
|
|||||||
unsigned long cur_gfn = gfn + npage;
|
unsigned long cur_gfn = gfn + npage;
|
||||||
unsigned long pfn;
|
unsigned long pfn;
|
||||||
|
|
||||||
ret = vfio_pin_pages(mdev_dev(kvmgt_vdev(vgpu)->mdev), &cur_gfn, 1,
|
ret = vfio_group_pin_pages(vdev->vfio_group, &cur_gfn, 1,
|
||||||
IOMMU_READ | IOMMU_WRITE, &pfn);
|
IOMMU_READ | IOMMU_WRITE, &pfn);
|
||||||
if (ret != 1) {
|
if (ret != 1) {
|
||||||
gvt_vgpu_err("vfio_pin_pages failed for gfn 0x%lx, ret %d\n",
|
gvt_vgpu_err("vfio_pin_pages failed for gfn 0x%lx, ret %d\n",
|
||||||
cur_gfn, ret);
|
cur_gfn, ret);
|
||||||
@ -792,6 +795,7 @@ static int intel_vgpu_open(struct mdev_device *mdev)
|
|||||||
struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
|
struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
|
||||||
unsigned long events;
|
unsigned long events;
|
||||||
int ret;
|
int ret;
|
||||||
|
struct vfio_group *vfio_group;
|
||||||
|
|
||||||
vdev->iommu_notifier.notifier_call = intel_vgpu_iommu_notifier;
|
vdev->iommu_notifier.notifier_call = intel_vgpu_iommu_notifier;
|
||||||
vdev->group_notifier.notifier_call = intel_vgpu_group_notifier;
|
vdev->group_notifier.notifier_call = intel_vgpu_group_notifier;
|
||||||
@ -814,6 +818,14 @@ static int intel_vgpu_open(struct mdev_device *mdev)
|
|||||||
goto undo_iommu;
|
goto undo_iommu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vfio_group = vfio_group_get_external_user_from_dev(mdev_dev(mdev));
|
||||||
|
if (IS_ERR_OR_NULL(vfio_group)) {
|
||||||
|
ret = !vfio_group ? -EFAULT : PTR_ERR(vfio_group);
|
||||||
|
gvt_vgpu_err("vfio_group_get_external_user_from_dev failed\n");
|
||||||
|
goto undo_register;
|
||||||
|
}
|
||||||
|
vdev->vfio_group = vfio_group;
|
||||||
|
|
||||||
/* Take a module reference as mdev core doesn't take
|
/* Take a module reference as mdev core doesn't take
|
||||||
* a reference for vendor driver.
|
* a reference for vendor driver.
|
||||||
*/
|
*/
|
||||||
@ -830,6 +842,10 @@ static int intel_vgpu_open(struct mdev_device *mdev)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
undo_group:
|
undo_group:
|
||||||
|
vfio_group_put_external_user(vdev->vfio_group);
|
||||||
|
vdev->vfio_group = NULL;
|
||||||
|
|
||||||
|
undo_register:
|
||||||
vfio_unregister_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
|
vfio_unregister_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
|
||||||
&vdev->group_notifier);
|
&vdev->group_notifier);
|
||||||
|
|
||||||
@ -884,6 +900,7 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
|
|||||||
kvmgt_guest_exit(info);
|
kvmgt_guest_exit(info);
|
||||||
|
|
||||||
intel_vgpu_release_msi_eventfd_ctx(vgpu);
|
intel_vgpu_release_msi_eventfd_ctx(vgpu);
|
||||||
|
vfio_group_put_external_user(vdev->vfio_group);
|
||||||
|
|
||||||
vdev->kvm = NULL;
|
vdev->kvm = NULL;
|
||||||
vgpu->handle = 0;
|
vgpu->handle = 0;
|
||||||
@ -2035,33 +2052,14 @@ static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa,
|
|||||||
void *buf, unsigned long len, bool write)
|
void *buf, unsigned long len, bool write)
|
||||||
{
|
{
|
||||||
struct kvmgt_guest_info *info;
|
struct kvmgt_guest_info *info;
|
||||||
struct kvm *kvm;
|
|
||||||
int idx, ret;
|
|
||||||
bool kthread = current->mm == NULL;
|
|
||||||
|
|
||||||
if (!handle_valid(handle))
|
if (!handle_valid(handle))
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
|
|
||||||
info = (struct kvmgt_guest_info *)handle;
|
info = (struct kvmgt_guest_info *)handle;
|
||||||
kvm = info->kvm;
|
|
||||||
|
|
||||||
if (kthread) {
|
return vfio_dma_rw(kvmgt_vdev(info->vgpu)->vfio_group,
|
||||||
if (!mmget_not_zero(kvm->mm))
|
gpa, buf, len, write);
|
||||||
return -EFAULT;
|
|
||||||
use_mm(kvm->mm);
|
|
||||||
}
|
|
||||||
|
|
||||||
idx = srcu_read_lock(&kvm->srcu);
|
|
||||||
ret = write ? kvm_write_guest(kvm, gpa, buf, len) :
|
|
||||||
kvm_read_guest(kvm, gpa, buf, len);
|
|
||||||
srcu_read_unlock(&kvm->srcu, idx);
|
|
||||||
|
|
||||||
if (kthread) {
|
|
||||||
unuse_mm(kvm->mm);
|
|
||||||
mmput(kvm->mm);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kvmgt_read_gpa(unsigned long handle, unsigned long gpa,
|
static int kvmgt_read_gpa(unsigned long handle, unsigned long gpa,
|
||||||
|
@ -2940,49 +2940,6 @@ void i915_oa_init_reg_state(const struct intel_context *ce,
|
|||||||
gen8_update_reg_state_unlocked(ce, stream);
|
gen8_update_reg_state_unlocked(ce, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* i915_perf_read_locked - &i915_perf_stream_ops->read with error normalisation
|
|
||||||
* @stream: An i915 perf stream
|
|
||||||
* @file: An i915 perf stream file
|
|
||||||
* @buf: destination buffer given by userspace
|
|
||||||
* @count: the number of bytes userspace wants to read
|
|
||||||
* @ppos: (inout) file seek position (unused)
|
|
||||||
*
|
|
||||||
* Besides wrapping &i915_perf_stream_ops->read this provides a common place to
|
|
||||||
* ensure that if we've successfully copied any data then reporting that takes
|
|
||||||
* precedence over any internal error status, so the data isn't lost.
|
|
||||||
*
|
|
||||||
* For example ret will be -ENOSPC whenever there is more buffered data than
|
|
||||||
* can be copied to userspace, but that's only interesting if we weren't able
|
|
||||||
* to copy some data because it implies the userspace buffer is too small to
|
|
||||||
* receive a single record (and we never split records).
|
|
||||||
*
|
|
||||||
* Another case with ret == -EFAULT is more of a grey area since it would seem
|
|
||||||
* like bad form for userspace to ask us to overrun its buffer, but the user
|
|
||||||
* knows best:
|
|
||||||
*
|
|
||||||
* http://yarchive.net/comp/linux/partial_reads_writes.html
|
|
||||||
*
|
|
||||||
* Returns: The number of bytes copied or a negative error code on failure.
|
|
||||||
*/
|
|
||||||
static ssize_t i915_perf_read_locked(struct i915_perf_stream *stream,
|
|
||||||
struct file *file,
|
|
||||||
char __user *buf,
|
|
||||||
size_t count,
|
|
||||||
loff_t *ppos)
|
|
||||||
{
|
|
||||||
/* Note we keep the offset (aka bytes read) separate from any
|
|
||||||
* error status so that the final check for whether we return
|
|
||||||
* the bytes read with a higher precedence than any error (see
|
|
||||||
* comment below) doesn't need to be handled/duplicated in
|
|
||||||
* stream->ops->read() implementations.
|
|
||||||
*/
|
|
||||||
size_t offset = 0;
|
|
||||||
int ret = stream->ops->read(stream, buf, count, &offset);
|
|
||||||
|
|
||||||
return offset ?: (ret ?: -EAGAIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* i915_perf_read - handles read() FOP for i915 perf stream FDs
|
* i915_perf_read - handles read() FOP for i915 perf stream FDs
|
||||||
* @file: An i915 perf stream file
|
* @file: An i915 perf stream file
|
||||||
@ -3008,7 +2965,8 @@ static ssize_t i915_perf_read(struct file *file,
|
|||||||
{
|
{
|
||||||
struct i915_perf_stream *stream = file->private_data;
|
struct i915_perf_stream *stream = file->private_data;
|
||||||
struct i915_perf *perf = stream->perf;
|
struct i915_perf *perf = stream->perf;
|
||||||
ssize_t ret;
|
size_t offset = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* To ensure it's handled consistently we simply treat all reads of a
|
/* To ensure it's handled consistently we simply treat all reads of a
|
||||||
* disabled stream as an error. In particular it might otherwise lead
|
* disabled stream as an error. In particular it might otherwise lead
|
||||||
@ -3031,13 +2989,12 @@ static ssize_t i915_perf_read(struct file *file,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
mutex_lock(&perf->lock);
|
mutex_lock(&perf->lock);
|
||||||
ret = i915_perf_read_locked(stream, file,
|
ret = stream->ops->read(stream, buf, count, &offset);
|
||||||
buf, count, ppos);
|
|
||||||
mutex_unlock(&perf->lock);
|
mutex_unlock(&perf->lock);
|
||||||
} while (ret == -EAGAIN);
|
} while (!offset && !ret);
|
||||||
} else {
|
} else {
|
||||||
mutex_lock(&perf->lock);
|
mutex_lock(&perf->lock);
|
||||||
ret = i915_perf_read_locked(stream, file, buf, count, ppos);
|
ret = stream->ops->read(stream, buf, count, &offset);
|
||||||
mutex_unlock(&perf->lock);
|
mutex_unlock(&perf->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3048,15 +3005,15 @@ static ssize_t i915_perf_read(struct file *file,
|
|||||||
* and read() returning -EAGAIN. Clearing the oa.pollin state here
|
* and read() returning -EAGAIN. Clearing the oa.pollin state here
|
||||||
* effectively ensures we back off until the next hrtimer callback
|
* effectively ensures we back off until the next hrtimer callback
|
||||||
* before reporting another EPOLLIN event.
|
* before reporting another EPOLLIN event.
|
||||||
|
* The exception to this is if ops->read() returned -ENOSPC which means
|
||||||
|
* that more OA data is available than could fit in the user provided
|
||||||
|
* buffer. In this case we want the next poll() call to not block.
|
||||||
*/
|
*/
|
||||||
if (ret >= 0 || ret == -EAGAIN) {
|
if (ret != -ENOSPC)
|
||||||
/* Maybe make ->pollin per-stream state if we support multiple
|
|
||||||
* concurrent streams in the future.
|
|
||||||
*/
|
|
||||||
stream->pollin = false;
|
stream->pollin = false;
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
/* Possible values for ret are 0, -EFAULT, -ENOSPC, -EIO, ... */
|
||||||
|
return offset ?: (ret ?: -EAGAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum hrtimer_restart oa_poll_check_timer_cb(struct hrtimer *hrtimer)
|
static enum hrtimer_restart oa_poll_check_timer_cb(struct hrtimer *hrtimer)
|
||||||
|
@ -25,6 +25,9 @@
|
|||||||
MODULE_FIRMWARE("nvidia/gp108/sec2/desc.bin");
|
MODULE_FIRMWARE("nvidia/gp108/sec2/desc.bin");
|
||||||
MODULE_FIRMWARE("nvidia/gp108/sec2/image.bin");
|
MODULE_FIRMWARE("nvidia/gp108/sec2/image.bin");
|
||||||
MODULE_FIRMWARE("nvidia/gp108/sec2/sig.bin");
|
MODULE_FIRMWARE("nvidia/gp108/sec2/sig.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/gv100/sec2/desc.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/gv100/sec2/image.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/gv100/sec2/sig.bin");
|
||||||
|
|
||||||
static const struct nvkm_sec2_fwif
|
static const struct nvkm_sec2_fwif
|
||||||
gp108_sec2_fwif[] = {
|
gp108_sec2_fwif[] = {
|
||||||
|
@ -56,6 +56,22 @@ tu102_sec2_nofw(struct nvkm_sec2 *sec2, int ver,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MODULE_FIRMWARE("nvidia/tu102/sec2/desc.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/tu102/sec2/image.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/tu102/sec2/sig.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/tu104/sec2/desc.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/tu104/sec2/image.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/tu104/sec2/sig.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/tu106/sec2/desc.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/tu106/sec2/image.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/tu106/sec2/sig.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/tu116/sec2/desc.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/tu116/sec2/image.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/tu116/sec2/sig.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/tu117/sec2/desc.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/tu117/sec2/image.bin");
|
||||||
|
MODULE_FIRMWARE("nvidia/tu117/sec2/sig.bin");
|
||||||
|
|
||||||
static const struct nvkm_sec2_fwif
|
static const struct nvkm_sec2_fwif
|
||||||
tu102_sec2_fwif[] = {
|
tu102_sec2_fwif[] = {
|
||||||
{ 0, gp102_sec2_load, &tu102_sec2, &gp102_sec2_acr_1 },
|
{ 0, gp102_sec2_load, &tu102_sec2, &gp102_sec2_acr_1 },
|
||||||
|
@ -839,6 +839,9 @@ void vmbus_initiate_unload(bool crash)
|
|||||||
{
|
{
|
||||||
struct vmbus_channel_message_header hdr;
|
struct vmbus_channel_message_header hdr;
|
||||||
|
|
||||||
|
if (xchg(&vmbus_connection.conn_state, DISCONNECTED) == DISCONNECTED)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Pre-Win2012R2 hosts don't support reconnect */
|
/* Pre-Win2012R2 hosts don't support reconnect */
|
||||||
if (vmbus_proto_version < VERSION_WIN8_1)
|
if (vmbus_proto_version < VERSION_WIN8_1)
|
||||||
return;
|
return;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include "hyperv_vmbus.h"
|
#include "hyperv_vmbus.h"
|
||||||
|
|
||||||
struct dentry *hv_debug_root;
|
static struct dentry *hv_debug_root;
|
||||||
|
|
||||||
static int hv_debugfs_delay_get(void *data, u64 *val)
|
static int hv_debugfs_delay_get(void *data, u64 *val)
|
||||||
{
|
{
|
||||||
|
@ -292,7 +292,7 @@ struct vmbus_msginfo {
|
|||||||
struct list_head msglist_entry;
|
struct list_head msglist_entry;
|
||||||
|
|
||||||
/* The message itself */
|
/* The message itself */
|
||||||
unsigned char msg[0];
|
unsigned char msg[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <linux/kdebug.h>
|
#include <linux/kdebug.h>
|
||||||
#include <linux/efi.h>
|
#include <linux/efi.h>
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
#include <linux/syscore_ops.h>
|
#include <linux/syscore_ops.h>
|
||||||
#include <clocksource/hyperv_timer.h>
|
#include <clocksource/hyperv_timer.h>
|
||||||
#include "hyperv_vmbus.h"
|
#include "hyperv_vmbus.h"
|
||||||
@ -48,14 +49,35 @@ static int hyperv_cpuhp_online;
|
|||||||
|
|
||||||
static void *hv_panic_page;
|
static void *hv_panic_page;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Boolean to control whether to report panic messages over Hyper-V.
|
||||||
|
*
|
||||||
|
* It can be set via /proc/sys/kernel/hyperv/record_panic_msg
|
||||||
|
*/
|
||||||
|
static int sysctl_record_panic_msg = 1;
|
||||||
|
|
||||||
|
static int hyperv_report_reg(void)
|
||||||
|
{
|
||||||
|
return !sysctl_record_panic_msg || !hv_panic_page;
|
||||||
|
}
|
||||||
|
|
||||||
static int hyperv_panic_event(struct notifier_block *nb, unsigned long val,
|
static int hyperv_panic_event(struct notifier_block *nb, unsigned long val,
|
||||||
void *args)
|
void *args)
|
||||||
{
|
{
|
||||||
struct pt_regs *regs;
|
struct pt_regs *regs;
|
||||||
|
|
||||||
regs = current_pt_regs();
|
vmbus_initiate_unload(true);
|
||||||
|
|
||||||
hyperv_report_panic(regs, val);
|
/*
|
||||||
|
* Hyper-V should be notified only once about a panic. If we will be
|
||||||
|
* doing hyperv_report_panic_msg() later with kmsg data, don't do
|
||||||
|
* the notification here.
|
||||||
|
*/
|
||||||
|
if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE
|
||||||
|
&& hyperv_report_reg()) {
|
||||||
|
regs = current_pt_regs();
|
||||||
|
hyperv_report_panic(regs, val, false);
|
||||||
|
}
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +87,13 @@ static int hyperv_die_event(struct notifier_block *nb, unsigned long val,
|
|||||||
struct die_args *die = (struct die_args *)args;
|
struct die_args *die = (struct die_args *)args;
|
||||||
struct pt_regs *regs = die->regs;
|
struct pt_regs *regs = die->regs;
|
||||||
|
|
||||||
hyperv_report_panic(regs, val);
|
/*
|
||||||
|
* Hyper-V should be notified only once about a panic. If we will be
|
||||||
|
* doing hyperv_report_panic_msg() later with kmsg data, don't do
|
||||||
|
* the notification here.
|
||||||
|
*/
|
||||||
|
if (hyperv_report_reg())
|
||||||
|
hyperv_report_panic(regs, val, true);
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1252,13 +1280,6 @@ static void vmbus_isr(void)
|
|||||||
add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0);
|
add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Boolean to control whether to report panic messages over Hyper-V.
|
|
||||||
*
|
|
||||||
* It can be set via /proc/sys/kernel/hyperv/record_panic_msg
|
|
||||||
*/
|
|
||||||
static int sysctl_record_panic_msg = 1;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback from kmsg_dump. Grab as much as possible from the end of the kmsg
|
* Callback from kmsg_dump. Grab as much as possible from the end of the kmsg
|
||||||
* buffer and call into Hyper-V to transfer the data.
|
* buffer and call into Hyper-V to transfer the data.
|
||||||
@ -1382,19 +1403,29 @@ static int vmbus_bus_init(void)
|
|||||||
hv_panic_page = (void *)hv_alloc_hyperv_zeroed_page();
|
hv_panic_page = (void *)hv_alloc_hyperv_zeroed_page();
|
||||||
if (hv_panic_page) {
|
if (hv_panic_page) {
|
||||||
ret = kmsg_dump_register(&hv_kmsg_dumper);
|
ret = kmsg_dump_register(&hv_kmsg_dumper);
|
||||||
if (ret)
|
if (ret) {
|
||||||
pr_err("Hyper-V: kmsg dump register "
|
pr_err("Hyper-V: kmsg dump register "
|
||||||
"error 0x%x\n", ret);
|
"error 0x%x\n", ret);
|
||||||
|
hv_free_hyperv_page(
|
||||||
|
(unsigned long)hv_panic_page);
|
||||||
|
hv_panic_page = NULL;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
pr_err("Hyper-V: panic message page memory "
|
pr_err("Hyper-V: panic message page memory "
|
||||||
"allocation failed");
|
"allocation failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
register_die_notifier(&hyperv_die_block);
|
register_die_notifier(&hyperv_die_block);
|
||||||
atomic_notifier_chain_register(&panic_notifier_list,
|
|
||||||
&hyperv_panic_block);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Always register the panic notifier because we need to unload
|
||||||
|
* the VMbus channel connection to prevent any VMbus
|
||||||
|
* activity after the VM panics.
|
||||||
|
*/
|
||||||
|
atomic_notifier_chain_register(&panic_notifier_list,
|
||||||
|
&hyperv_panic_block);
|
||||||
|
|
||||||
vmbus_request_offers();
|
vmbus_request_offers();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1407,7 +1438,6 @@ static int vmbus_bus_init(void)
|
|||||||
hv_remove_vmbus_irq();
|
hv_remove_vmbus_irq();
|
||||||
|
|
||||||
bus_unregister(&hv_bus);
|
bus_unregister(&hv_bus);
|
||||||
hv_free_hyperv_page((unsigned long)hv_panic_page);
|
|
||||||
unregister_sysctl_table(hv_ctl_table_hdr);
|
unregister_sysctl_table(hv_ctl_table_hdr);
|
||||||
hv_ctl_table_hdr = NULL;
|
hv_ctl_table_hdr = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
@ -2204,8 +2234,6 @@ static int vmbus_bus_suspend(struct device *dev)
|
|||||||
|
|
||||||
vmbus_initiate_unload(false);
|
vmbus_initiate_unload(false);
|
||||||
|
|
||||||
vmbus_connection.conn_state = DISCONNECTED;
|
|
||||||
|
|
||||||
/* Reset the event for the next resume. */
|
/* Reset the event for the next resume. */
|
||||||
reinit_completion(&vmbus_connection.ready_for_resume_event);
|
reinit_completion(&vmbus_connection.ready_for_resume_event);
|
||||||
|
|
||||||
@ -2289,7 +2317,6 @@ static void hv_kexec_handler(void)
|
|||||||
{
|
{
|
||||||
hv_stimer_global_cleanup();
|
hv_stimer_global_cleanup();
|
||||||
vmbus_initiate_unload(false);
|
vmbus_initiate_unload(false);
|
||||||
vmbus_connection.conn_state = DISCONNECTED;
|
|
||||||
/* Make sure conn_state is set as hv_synic_cleanup checks for it */
|
/* Make sure conn_state is set as hv_synic_cleanup checks for it */
|
||||||
mb();
|
mb();
|
||||||
cpuhp_remove_state(hyperv_cpuhp_online);
|
cpuhp_remove_state(hyperv_cpuhp_online);
|
||||||
@ -2306,7 +2333,6 @@ static void hv_crash_handler(struct pt_regs *regs)
|
|||||||
* doing the cleanup for current CPU only. This should be sufficient
|
* doing the cleanup for current CPU only. This should be sufficient
|
||||||
* for kdump.
|
* for kdump.
|
||||||
*/
|
*/
|
||||||
vmbus_connection.conn_state = DISCONNECTED;
|
|
||||||
cpu = smp_processor_id();
|
cpu = smp_processor_id();
|
||||||
hv_stimer_cleanup(cpu);
|
hv_stimer_cleanup(cpu);
|
||||||
hv_synic_disable_regs(cpu);
|
hv_synic_disable_regs(cpu);
|
||||||
|
@ -412,7 +412,7 @@ config SENSORS_DRIVETEMP
|
|||||||
hard disk drives.
|
hard disk drives.
|
||||||
|
|
||||||
This driver can also be built as a module. If so, the module
|
This driver can also be built as a module. If so, the module
|
||||||
will be called satatemp.
|
will be called drivetemp.
|
||||||
|
|
||||||
config SENSORS_DS620
|
config SENSORS_DS620
|
||||||
tristate "Dallas Semiconductor DS620"
|
tristate "Dallas Semiconductor DS620"
|
||||||
|
@ -264,12 +264,18 @@ static int drivetemp_get_scttemp(struct drivetemp_data *st, u32 attr, long *val)
|
|||||||
return err;
|
return err;
|
||||||
switch (attr) {
|
switch (attr) {
|
||||||
case hwmon_temp_input:
|
case hwmon_temp_input:
|
||||||
|
if (!temp_is_valid(buf[SCT_STATUS_TEMP]))
|
||||||
|
return -ENODATA;
|
||||||
*val = temp_from_sct(buf[SCT_STATUS_TEMP]);
|
*val = temp_from_sct(buf[SCT_STATUS_TEMP]);
|
||||||
break;
|
break;
|
||||||
case hwmon_temp_lowest:
|
case hwmon_temp_lowest:
|
||||||
|
if (!temp_is_valid(buf[SCT_STATUS_TEMP_LOWEST]))
|
||||||
|
return -ENODATA;
|
||||||
*val = temp_from_sct(buf[SCT_STATUS_TEMP_LOWEST]);
|
*val = temp_from_sct(buf[SCT_STATUS_TEMP_LOWEST]);
|
||||||
break;
|
break;
|
||||||
case hwmon_temp_highest:
|
case hwmon_temp_highest:
|
||||||
|
if (!temp_is_valid(buf[SCT_STATUS_TEMP_HIGHEST]))
|
||||||
|
return -ENODATA;
|
||||||
*val = temp_from_sct(buf[SCT_STATUS_TEMP_HIGHEST]);
|
*val = temp_from_sct(buf[SCT_STATUS_TEMP_HIGHEST]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -506,7 +506,7 @@ static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|||||||
}
|
}
|
||||||
data->config = config;
|
data->config = config;
|
||||||
|
|
||||||
hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
|
hwmon_dev = devm_hwmon_device_register_with_info(dev, "jc42",
|
||||||
data, &jc42_chip_info,
|
data, &jc42_chip_info,
|
||||||
NULL);
|
NULL);
|
||||||
return PTR_ERR_OR_ZERO(hwmon_dev);
|
return PTR_ERR_OR_ZERO(hwmon_dev);
|
||||||
|
@ -186,7 +186,7 @@ static long get_raw_temp(struct k10temp_data *data)
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *k10temp_temp_label[] = {
|
static const char *k10temp_temp_label[] = {
|
||||||
"Tctl",
|
"Tctl",
|
||||||
"Tdie",
|
"Tdie",
|
||||||
"Tccd1",
|
"Tccd1",
|
||||||
@ -199,12 +199,12 @@ const char *k10temp_temp_label[] = {
|
|||||||
"Tccd8",
|
"Tccd8",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *k10temp_in_label[] = {
|
static const char *k10temp_in_label[] = {
|
||||||
"Vcore",
|
"Vcore",
|
||||||
"Vsoc",
|
"Vsoc",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *k10temp_curr_label[] = {
|
static const char *k10temp_curr_label[] = {
|
||||||
"Icore",
|
"Icore",
|
||||||
"Isoc",
|
"Isoc",
|
||||||
};
|
};
|
||||||
|
@ -21,8 +21,50 @@
|
|||||||
#define ISL68137_VOUT_AVS 0x30
|
#define ISL68137_VOUT_AVS 0x30
|
||||||
#define RAA_DMPVR2_READ_VMON 0xc8
|
#define RAA_DMPVR2_READ_VMON 0xc8
|
||||||
|
|
||||||
enum versions {
|
enum chips {
|
||||||
isl68137,
|
isl68137,
|
||||||
|
isl68220,
|
||||||
|
isl68221,
|
||||||
|
isl68222,
|
||||||
|
isl68223,
|
||||||
|
isl68224,
|
||||||
|
isl68225,
|
||||||
|
isl68226,
|
||||||
|
isl68227,
|
||||||
|
isl68229,
|
||||||
|
isl68233,
|
||||||
|
isl68239,
|
||||||
|
isl69222,
|
||||||
|
isl69223,
|
||||||
|
isl69224,
|
||||||
|
isl69225,
|
||||||
|
isl69227,
|
||||||
|
isl69228,
|
||||||
|
isl69234,
|
||||||
|
isl69236,
|
||||||
|
isl69239,
|
||||||
|
isl69242,
|
||||||
|
isl69243,
|
||||||
|
isl69247,
|
||||||
|
isl69248,
|
||||||
|
isl69254,
|
||||||
|
isl69255,
|
||||||
|
isl69256,
|
||||||
|
isl69259,
|
||||||
|
isl69260,
|
||||||
|
isl69268,
|
||||||
|
isl69269,
|
||||||
|
isl69298,
|
||||||
|
raa228000,
|
||||||
|
raa228004,
|
||||||
|
raa228006,
|
||||||
|
raa228228,
|
||||||
|
raa229001,
|
||||||
|
raa229004,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum variants {
|
||||||
|
raa_dmpvr1_2rail,
|
||||||
raa_dmpvr2_1rail,
|
raa_dmpvr2_1rail,
|
||||||
raa_dmpvr2_2rail,
|
raa_dmpvr2_2rail,
|
||||||
raa_dmpvr2_3rail,
|
raa_dmpvr2_3rail,
|
||||||
@ -186,7 +228,7 @@ static int isl68137_probe(struct i2c_client *client,
|
|||||||
memcpy(info, &raa_dmpvr_info, sizeof(*info));
|
memcpy(info, &raa_dmpvr_info, sizeof(*info));
|
||||||
|
|
||||||
switch (id->driver_data) {
|
switch (id->driver_data) {
|
||||||
case isl68137:
|
case raa_dmpvr1_2rail:
|
||||||
info->pages = 2;
|
info->pages = 2;
|
||||||
info->R[PSC_VOLTAGE_IN] = 3;
|
info->R[PSC_VOLTAGE_IN] = 3;
|
||||||
info->func[0] &= ~PMBUS_HAVE_VMON;
|
info->func[0] &= ~PMBUS_HAVE_VMON;
|
||||||
@ -224,11 +266,47 @@ static int isl68137_probe(struct i2c_client *client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct i2c_device_id raa_dmpvr_id[] = {
|
static const struct i2c_device_id raa_dmpvr_id[] = {
|
||||||
{"isl68137", isl68137},
|
{"isl68137", raa_dmpvr1_2rail},
|
||||||
{"raa_dmpvr2_1rail", raa_dmpvr2_1rail},
|
{"isl68220", raa_dmpvr2_2rail},
|
||||||
{"raa_dmpvr2_2rail", raa_dmpvr2_2rail},
|
{"isl68221", raa_dmpvr2_3rail},
|
||||||
{"raa_dmpvr2_3rail", raa_dmpvr2_3rail},
|
{"isl68222", raa_dmpvr2_2rail},
|
||||||
{"raa_dmpvr2_hv", raa_dmpvr2_hv},
|
{"isl68223", raa_dmpvr2_2rail},
|
||||||
|
{"isl68224", raa_dmpvr2_3rail},
|
||||||
|
{"isl68225", raa_dmpvr2_2rail},
|
||||||
|
{"isl68226", raa_dmpvr2_3rail},
|
||||||
|
{"isl68227", raa_dmpvr2_1rail},
|
||||||
|
{"isl68229", raa_dmpvr2_3rail},
|
||||||
|
{"isl68233", raa_dmpvr2_2rail},
|
||||||
|
{"isl68239", raa_dmpvr2_3rail},
|
||||||
|
|
||||||
|
{"isl69222", raa_dmpvr2_2rail},
|
||||||
|
{"isl69223", raa_dmpvr2_3rail},
|
||||||
|
{"isl69224", raa_dmpvr2_2rail},
|
||||||
|
{"isl69225", raa_dmpvr2_2rail},
|
||||||
|
{"isl69227", raa_dmpvr2_3rail},
|
||||||
|
{"isl69228", raa_dmpvr2_3rail},
|
||||||
|
{"isl69234", raa_dmpvr2_2rail},
|
||||||
|
{"isl69236", raa_dmpvr2_2rail},
|
||||||
|
{"isl69239", raa_dmpvr2_3rail},
|
||||||
|
{"isl69242", raa_dmpvr2_2rail},
|
||||||
|
{"isl69243", raa_dmpvr2_1rail},
|
||||||
|
{"isl69247", raa_dmpvr2_2rail},
|
||||||
|
{"isl69248", raa_dmpvr2_2rail},
|
||||||
|
{"isl69254", raa_dmpvr2_2rail},
|
||||||
|
{"isl69255", raa_dmpvr2_2rail},
|
||||||
|
{"isl69256", raa_dmpvr2_2rail},
|
||||||
|
{"isl69259", raa_dmpvr2_2rail},
|
||||||
|
{"isl69260", raa_dmpvr2_2rail},
|
||||||
|
{"isl69268", raa_dmpvr2_2rail},
|
||||||
|
{"isl69269", raa_dmpvr2_3rail},
|
||||||
|
{"isl69298", raa_dmpvr2_2rail},
|
||||||
|
|
||||||
|
{"raa228000", raa_dmpvr2_hv},
|
||||||
|
{"raa228004", raa_dmpvr2_hv},
|
||||||
|
{"raa228006", raa_dmpvr2_hv},
|
||||||
|
{"raa228228", raa_dmpvr2_2rail},
|
||||||
|
{"raa229001", raa_dmpvr2_2rail},
|
||||||
|
{"raa229004", raa_dmpvr2_2rail},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -384,7 +384,6 @@ static int altr_i2c_probe(struct platform_device *pdev)
|
|||||||
struct altr_i2c_dev *idev = NULL;
|
struct altr_i2c_dev *idev = NULL;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
int irq, ret;
|
int irq, ret;
|
||||||
u32 val;
|
|
||||||
|
|
||||||
idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL);
|
idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL);
|
||||||
if (!idev)
|
if (!idev)
|
||||||
@ -411,17 +410,17 @@ static int altr_i2c_probe(struct platform_device *pdev)
|
|||||||
init_completion(&idev->msg_complete);
|
init_completion(&idev->msg_complete);
|
||||||
spin_lock_init(&idev->lock);
|
spin_lock_init(&idev->lock);
|
||||||
|
|
||||||
val = device_property_read_u32(idev->dev, "fifo-size",
|
ret = device_property_read_u32(idev->dev, "fifo-size",
|
||||||
&idev->fifo_size);
|
&idev->fifo_size);
|
||||||
if (val) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "FIFO size set to default of %d\n",
|
dev_err(&pdev->dev, "FIFO size set to default of %d\n",
|
||||||
ALTR_I2C_DFLT_FIFO_SZ);
|
ALTR_I2C_DFLT_FIFO_SZ);
|
||||||
idev->fifo_size = ALTR_I2C_DFLT_FIFO_SZ;
|
idev->fifo_size = ALTR_I2C_DFLT_FIFO_SZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = device_property_read_u32(idev->dev, "clock-frequency",
|
ret = device_property_read_u32(idev->dev, "clock-frequency",
|
||||||
&idev->bus_clk_rate);
|
&idev->bus_clk_rate);
|
||||||
if (val) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "Default to 100kHz\n");
|
dev_err(&pdev->dev, "Default to 100kHz\n");
|
||||||
idev->bus_clk_rate = I2C_MAX_STANDARD_MODE_FREQ; /* default clock rate */
|
idev->bus_clk_rate = I2C_MAX_STANDARD_MODE_FREQ; /* default clock rate */
|
||||||
}
|
}
|
||||||
|
@ -354,10 +354,16 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
|
|||||||
adap->dev.of_node = pdev->dev.of_node;
|
adap->dev.of_node = pdev->dev.of_node;
|
||||||
adap->nr = -1;
|
adap->nr = -1;
|
||||||
|
|
||||||
dev_pm_set_driver_flags(&pdev->dev,
|
if (dev->flags & ACCESS_NO_IRQ_SUSPEND) {
|
||||||
DPM_FLAG_SMART_PREPARE |
|
dev_pm_set_driver_flags(&pdev->dev,
|
||||||
DPM_FLAG_SMART_SUSPEND |
|
DPM_FLAG_SMART_PREPARE |
|
||||||
DPM_FLAG_LEAVE_SUSPENDED);
|
DPM_FLAG_LEAVE_SUSPENDED);
|
||||||
|
} else {
|
||||||
|
dev_pm_set_driver_flags(&pdev->dev,
|
||||||
|
DPM_FLAG_SMART_PREPARE |
|
||||||
|
DPM_FLAG_SMART_SUSPEND |
|
||||||
|
DPM_FLAG_LEAVE_SUSPENDED);
|
||||||
|
}
|
||||||
|
|
||||||
/* The code below assumes runtime PM to be disabled. */
|
/* The code below assumes runtime PM to be disabled. */
|
||||||
WARN_ON(pm_runtime_enabled(&pdev->dev));
|
WARN_ON(pm_runtime_enabled(&pdev->dev));
|
||||||
|
@ -996,14 +996,13 @@ tegra_i2c_poll_completion_timeout(struct tegra_i2c_dev *i2c_dev,
|
|||||||
do {
|
do {
|
||||||
u32 status = i2c_readl(i2c_dev, I2C_INT_STATUS);
|
u32 status = i2c_readl(i2c_dev, I2C_INT_STATUS);
|
||||||
|
|
||||||
if (status) {
|
if (status)
|
||||||
tegra_i2c_isr(i2c_dev->irq, i2c_dev);
|
tegra_i2c_isr(i2c_dev->irq, i2c_dev);
|
||||||
|
|
||||||
if (completion_done(complete)) {
|
if (completion_done(complete)) {
|
||||||
s64 delta = ktime_ms_delta(ktimeout, ktime);
|
s64 delta = ktime_ms_delta(ktimeout, ktime);
|
||||||
|
|
||||||
return msecs_to_jiffies(delta) ?: 1;
|
return msecs_to_jiffies(delta) ?: 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ktime = ktime_get();
|
ktime = ktime_get();
|
||||||
@ -1030,14 +1029,18 @@ tegra_i2c_wait_completion_timeout(struct tegra_i2c_dev *i2c_dev,
|
|||||||
disable_irq(i2c_dev->irq);
|
disable_irq(i2c_dev->irq);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There is a chance that completion may happen after IRQ
|
* Under some rare circumstances (like running KASAN +
|
||||||
* synchronization, which is done by disable_irq().
|
* NFS root) CPU, which handles interrupt, may stuck in
|
||||||
|
* uninterruptible state for a significant time. In this
|
||||||
|
* case we will get timeout if I2C transfer is running on
|
||||||
|
* a sibling CPU, despite of IRQ being raised.
|
||||||
|
*
|
||||||
|
* In order to handle this rare condition, the IRQ status
|
||||||
|
* needs to be checked after timeout.
|
||||||
*/
|
*/
|
||||||
if (ret == 0 && completion_done(complete)) {
|
if (ret == 0)
|
||||||
dev_warn(i2c_dev->dev,
|
ret = tegra_i2c_poll_completion_timeout(i2c_dev,
|
||||||
"completion done after timeout\n");
|
complete, 0);
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -1216,6 +1219,15 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
|
|||||||
time_left = tegra_i2c_wait_completion_timeout(
|
time_left = tegra_i2c_wait_completion_timeout(
|
||||||
i2c_dev, &i2c_dev->dma_complete, xfer_time);
|
i2c_dev, &i2c_dev->dma_complete, xfer_time);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Synchronize DMA first, since dmaengine_terminate_sync()
|
||||||
|
* performs synchronization after the transfer's termination
|
||||||
|
* and we want to get a completion if transfer succeeded.
|
||||||
|
*/
|
||||||
|
dmaengine_synchronize(i2c_dev->msg_read ?
|
||||||
|
i2c_dev->rx_dma_chan :
|
||||||
|
i2c_dev->tx_dma_chan);
|
||||||
|
|
||||||
dmaengine_terminate_sync(i2c_dev->msg_read ?
|
dmaengine_terminate_sync(i2c_dev->msg_read ?
|
||||||
i2c_dev->rx_dma_chan :
|
i2c_dev->rx_dma_chan :
|
||||||
i2c_dev->tx_dma_chan);
|
i2c_dev->tx_dma_chan);
|
||||||
|
@ -2273,19 +2273,6 @@ i2c_new_scanned_device(struct i2c_adapter *adap,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(i2c_new_scanned_device);
|
EXPORT_SYMBOL_GPL(i2c_new_scanned_device);
|
||||||
|
|
||||||
struct i2c_client *
|
|
||||||
i2c_new_probed_device(struct i2c_adapter *adap,
|
|
||||||
struct i2c_board_info *info,
|
|
||||||
unsigned short const *addr_list,
|
|
||||||
int (*probe)(struct i2c_adapter *adap, unsigned short addr))
|
|
||||||
{
|
|
||||||
struct i2c_client *client;
|
|
||||||
|
|
||||||
client = i2c_new_scanned_device(adap, info, addr_list, probe);
|
|
||||||
return IS_ERR(client) ? NULL : client;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(i2c_new_probed_device);
|
|
||||||
|
|
||||||
struct i2c_adapter *i2c_get_adapter(int nr)
|
struct i2c_adapter *i2c_get_adapter(int nr)
|
||||||
{
|
{
|
||||||
struct i2c_adapter *adapter;
|
struct i2c_adapter *adapter;
|
||||||
|
@ -416,7 +416,7 @@ static const struct irq_domain_ops bcm7038_l1_domain_ops = {
|
|||||||
.map = bcm7038_l1_map,
|
.map = bcm7038_l1_map,
|
||||||
};
|
};
|
||||||
|
|
||||||
int __init bcm7038_l1_of_init(struct device_node *dn,
|
static int __init bcm7038_l1_of_init(struct device_node *dn,
|
||||||
struct device_node *parent)
|
struct device_node *parent)
|
||||||
{
|
{
|
||||||
struct bcm7038_l1_chip *intc;
|
struct bcm7038_l1_chip *intc;
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <linux/dma-iommu.h>
|
#include <linux/dma-iommu.h>
|
||||||
#include <linux/efi.h>
|
#include <linux/efi.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/iopoll.h>
|
||||||
#include <linux/irqdomain.h>
|
#include <linux/irqdomain.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/log2.h>
|
#include <linux/log2.h>
|
||||||
@ -3672,6 +3673,20 @@ static int its_vpe_set_affinity(struct irq_data *d,
|
|||||||
return IRQ_SET_MASK_OK_DONE;
|
return IRQ_SET_MASK_OK_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void its_wait_vpt_parse_complete(void)
|
||||||
|
{
|
||||||
|
void __iomem *vlpi_base = gic_data_rdist_vlpi_base();
|
||||||
|
u64 val;
|
||||||
|
|
||||||
|
if (!gic_rdists->has_vpend_valid_dirty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
WARN_ON_ONCE(readq_relaxed_poll_timeout(vlpi_base + GICR_VPENDBASER,
|
||||||
|
val,
|
||||||
|
!(val & GICR_VPENDBASER_Dirty),
|
||||||
|
10, 500));
|
||||||
|
}
|
||||||
|
|
||||||
static void its_vpe_schedule(struct its_vpe *vpe)
|
static void its_vpe_schedule(struct its_vpe *vpe)
|
||||||
{
|
{
|
||||||
void __iomem *vlpi_base = gic_data_rdist_vlpi_base();
|
void __iomem *vlpi_base = gic_data_rdist_vlpi_base();
|
||||||
@ -3702,6 +3717,8 @@ static void its_vpe_schedule(struct its_vpe *vpe)
|
|||||||
val |= vpe->idai ? GICR_VPENDBASER_IDAI : 0;
|
val |= vpe->idai ? GICR_VPENDBASER_IDAI : 0;
|
||||||
val |= GICR_VPENDBASER_Valid;
|
val |= GICR_VPENDBASER_Valid;
|
||||||
gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
|
gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
|
||||||
|
|
||||||
|
its_wait_vpt_parse_complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void its_vpe_deschedule(struct its_vpe *vpe)
|
static void its_vpe_deschedule(struct its_vpe *vpe)
|
||||||
@ -3910,6 +3927,8 @@ static void its_vpe_4_1_schedule(struct its_vpe *vpe,
|
|||||||
val |= FIELD_PREP(GICR_VPENDBASER_4_1_VPEID, vpe->vpe_id);
|
val |= FIELD_PREP(GICR_VPENDBASER_4_1_VPEID, vpe->vpe_id);
|
||||||
|
|
||||||
gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
|
gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
|
||||||
|
|
||||||
|
its_wait_vpt_parse_complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void its_vpe_4_1_deschedule(struct its_vpe *vpe,
|
static void its_vpe_4_1_deschedule(struct its_vpe *vpe,
|
||||||
@ -4035,6 +4054,7 @@ static int its_sgi_set_affinity(struct irq_data *d,
|
|||||||
* not on the host (since they can only be targetting a vPE).
|
* not on the host (since they can only be targetting a vPE).
|
||||||
* Tell the kernel we've done whatever it asked for.
|
* Tell the kernel we've done whatever it asked for.
|
||||||
*/
|
*/
|
||||||
|
irq_data_update_effective_affinity(d, mask_val);
|
||||||
return IRQ_SET_MASK_OK;
|
return IRQ_SET_MASK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -873,6 +873,7 @@ static int __gic_update_rdist_properties(struct redist_region *region,
|
|||||||
gic_data.rdists.has_rvpeid &= !!(typer & GICR_TYPER_RVPEID);
|
gic_data.rdists.has_rvpeid &= !!(typer & GICR_TYPER_RVPEID);
|
||||||
gic_data.rdists.has_direct_lpi &= (!!(typer & GICR_TYPER_DirectLPIS) |
|
gic_data.rdists.has_direct_lpi &= (!!(typer & GICR_TYPER_DirectLPIS) |
|
||||||
gic_data.rdists.has_rvpeid);
|
gic_data.rdists.has_rvpeid);
|
||||||
|
gic_data.rdists.has_vpend_valid_dirty &= !!(typer & GICR_TYPER_DIRTY);
|
||||||
|
|
||||||
/* Detect non-sensical configurations */
|
/* Detect non-sensical configurations */
|
||||||
if (WARN_ON_ONCE(gic_data.rdists.has_rvpeid && !gic_data.rdists.has_vlpis)) {
|
if (WARN_ON_ONCE(gic_data.rdists.has_rvpeid && !gic_data.rdists.has_vlpis)) {
|
||||||
@ -893,10 +894,11 @@ static void gic_update_rdist_properties(void)
|
|||||||
if (WARN_ON(gic_data.ppi_nr == UINT_MAX))
|
if (WARN_ON(gic_data.ppi_nr == UINT_MAX))
|
||||||
gic_data.ppi_nr = 0;
|
gic_data.ppi_nr = 0;
|
||||||
pr_info("%d PPIs implemented\n", gic_data.ppi_nr);
|
pr_info("%d PPIs implemented\n", gic_data.ppi_nr);
|
||||||
pr_info("%sVLPI support, %sdirect LPI support, %sRVPEID support\n",
|
if (gic_data.rdists.has_vlpis)
|
||||||
!gic_data.rdists.has_vlpis ? "no " : "",
|
pr_info("GICv4 features: %s%s%s\n",
|
||||||
!gic_data.rdists.has_direct_lpi ? "no " : "",
|
gic_data.rdists.has_direct_lpi ? "DirectLPI " : "",
|
||||||
!gic_data.rdists.has_rvpeid ? "no " : "");
|
gic_data.rdists.has_rvpeid ? "RVPEID " : "",
|
||||||
|
gic_data.rdists.has_vpend_valid_dirty ? "Valid+Dirty " : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether it's single security state view */
|
/* Check whether it's single security state view */
|
||||||
@ -1620,6 +1622,7 @@ static int __init gic_init_bases(void __iomem *dist_base,
|
|||||||
gic_data.rdists.has_rvpeid = true;
|
gic_data.rdists.has_rvpeid = true;
|
||||||
gic_data.rdists.has_vlpis = true;
|
gic_data.rdists.has_vlpis = true;
|
||||||
gic_data.rdists.has_direct_lpi = true;
|
gic_data.rdists.has_direct_lpi = true;
|
||||||
|
gic_data.rdists.has_vpend_valid_dirty = true;
|
||||||
|
|
||||||
if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) {
|
if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user