Merge remote-tracking branch 'torvalds/master' into perf/core
To pick up fixes. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
commit
30d647f5ba
4
CREDITS
4
CREDITS
|
@ -1439,6 +1439,10 @@ N: Justin Guyett
|
|||
E: jguyett@andrew.cmu.edu
|
||||
D: via-rhine net driver hacking
|
||||
|
||||
N: Nitin Gupta
|
||||
E: ngupta@vflare.org
|
||||
D: zsmalloc memory allocator and zram block device driver
|
||||
|
||||
N: Danny ter Haar
|
||||
E: dth@cistron.nl
|
||||
D: /proc/cpuinfo, reboot on panic , kernel pre-patch tester ;)
|
||||
|
|
|
@ -22,6 +22,7 @@ Date: Oct 25, 2019
|
|||
KernelVersion: 5.6.0
|
||||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The largest number of work descriptors in a batch.
|
||||
It's not visible when the device does not support batch.
|
||||
|
||||
What: /sys/bus/dsa/devices/dsa<m>/max_work_queues_size
|
||||
Date: Oct 25, 2019
|
||||
|
@ -49,6 +50,8 @@ Description: The total number of read buffers supported by this device.
|
|||
The read buffers represent resources within the DSA
|
||||
implementation, and these resources are allocated by engines to
|
||||
support operations. See DSA spec v1.2 9.2.4 Total Read Buffers.
|
||||
It's not visible when the device does not support Read Buffer
|
||||
allocation control.
|
||||
|
||||
What: /sys/bus/dsa/devices/dsa<m>/max_transfer_size
|
||||
Date: Oct 25, 2019
|
||||
|
@ -122,6 +125,8 @@ Contact: dmaengine@vger.kernel.org
|
|||
Description: The maximum number of read buffers that may be in use at
|
||||
one time by operations that access low bandwidth memory in the
|
||||
device. See DSA spec v1.2 9.2.8 GENCFG on Global Read Buffer Limit.
|
||||
It's not visible when the device does not support Read Buffer
|
||||
allocation control.
|
||||
|
||||
What: /sys/bus/dsa/devices/dsa<m>/cmd_status
|
||||
Date: Aug 28, 2020
|
||||
|
@ -205,6 +210,7 @@ KernelVersion: 5.10.0
|
|||
Contact: dmaengine@vger.kernel.org
|
||||
Description: The max batch size for this workqueue. Cannot exceed device
|
||||
max batch size. Configurable parameter.
|
||||
It's not visible when the device does not support batch.
|
||||
|
||||
What: /sys/bus/dsa/devices/wq<m>.<n>/ats_disable
|
||||
Date: Nov 13, 2020
|
||||
|
@ -250,6 +256,8 @@ KernelVersion: 5.17.0
|
|||
Contact: dmaengine@vger.kernel.org
|
||||
Description: Enable the use of global read buffer limit for the group. See DSA
|
||||
spec v1.2 9.2.18 GRPCFG Use Global Read Buffer Limit.
|
||||
It's not visible when the device does not support Read Buffer
|
||||
allocation control.
|
||||
|
||||
What: /sys/bus/dsa/devices/group<m>.<n>/read_buffers_allowed
|
||||
Date: Dec 10, 2021
|
||||
|
@ -258,6 +266,8 @@ Contact: dmaengine@vger.kernel.org
|
|||
Description: Indicates max number of read buffers that may be in use at one time
|
||||
by all engines in the group. See DSA spec v1.2 9.2.18 GRPCFG Read
|
||||
Buffers Allowed.
|
||||
It's not visible when the device does not support Read Buffer
|
||||
allocation control.
|
||||
|
||||
What: /sys/bus/dsa/devices/group<m>.<n>/read_buffers_reserved
|
||||
Date: Dec 10, 2021
|
||||
|
@ -266,6 +276,8 @@ Contact: dmaengine@vger.kernel.org
|
|||
Description: Indicates the number of Read Buffers reserved for the use of
|
||||
engines in the group. See DSA spec v1.2 9.2.18 GRPCFG Read Buffers
|
||||
Reserved.
|
||||
It's not visible when the device does not support Read Buffer
|
||||
allocation control.
|
||||
|
||||
What: /sys/bus/dsa/devices/group<m>.<n>/desc_progress_limit
|
||||
Date: Sept 14, 2022
|
||||
|
|
|
@ -1050,6 +1050,11 @@
|
|||
them frequently to increase the rate of SLB faults
|
||||
on kernel addresses.
|
||||
|
||||
stress_hpt [PPC]
|
||||
Limits the number of kernel HPT entries in the hash
|
||||
page table to increase the rate of hash page table
|
||||
faults on kernel addresses.
|
||||
|
||||
disable= [IPV6]
|
||||
See Documentation/networking/ipv6.rst.
|
||||
|
||||
|
@ -2308,7 +2313,13 @@
|
|||
Provide an override to the IOAPIC-ID<->DEVICE-ID
|
||||
mapping provided in the IVRS ACPI table.
|
||||
By default, PCI segment is 0, and can be omitted.
|
||||
For example:
|
||||
|
||||
For example, to map IOAPIC-ID decimal 10 to
|
||||
PCI segment 0x1 and PCI device 00:14.0,
|
||||
write the parameter as:
|
||||
ivrs_ioapic=10@0001:00:14.0
|
||||
|
||||
Deprecated formats:
|
||||
* To map IOAPIC-ID decimal 10 to PCI device 00:14.0
|
||||
write the parameter as:
|
||||
ivrs_ioapic[10]=00:14.0
|
||||
|
@ -2320,7 +2331,13 @@
|
|||
Provide an override to the HPET-ID<->DEVICE-ID
|
||||
mapping provided in the IVRS ACPI table.
|
||||
By default, PCI segment is 0, and can be omitted.
|
||||
For example:
|
||||
|
||||
For example, to map HPET-ID decimal 10 to
|
||||
PCI segment 0x1 and PCI device 00:14.0,
|
||||
write the parameter as:
|
||||
ivrs_hpet=10@0001:00:14.0
|
||||
|
||||
Deprecated formats:
|
||||
* To map HPET-ID decimal 0 to PCI device 00:14.0
|
||||
write the parameter as:
|
||||
ivrs_hpet[0]=00:14.0
|
||||
|
@ -2331,15 +2348,20 @@
|
|||
ivrs_acpihid [HW,X86-64]
|
||||
Provide an override to the ACPI-HID:UID<->DEVICE-ID
|
||||
mapping provided in the IVRS ACPI table.
|
||||
By default, PCI segment is 0, and can be omitted.
|
||||
|
||||
For example, to map UART-HID:UID AMD0020:0 to
|
||||
PCI segment 0x1 and PCI device ID 00:14.5,
|
||||
write the parameter as:
|
||||
ivrs_acpihid[0001:00:14.5]=AMD0020:0
|
||||
ivrs_acpihid=AMD0020:0@0001:00:14.5
|
||||
|
||||
By default, PCI segment is 0, and can be omitted.
|
||||
For example, PCI device 00:14.5 write the parameter as:
|
||||
Deprecated formats:
|
||||
* To map UART-HID:UID AMD0020:0 to PCI segment is 0,
|
||||
PCI device ID 00:14.5, write the parameter as:
|
||||
ivrs_acpihid[00:14.5]=AMD0020:0
|
||||
* To map UART-HID:UID AMD0020:0 to PCI segment 0x1 and
|
||||
PCI device ID 00:14.5, write the parameter as:
|
||||
ivrs_acpihid[0001:00:14.5]=AMD0020:0
|
||||
|
||||
js= [HW,JOY] Analog joystick
|
||||
See Documentation/input/joydev/joystick.rst.
|
||||
|
|
|
@ -436,8 +436,8 @@ ignore-unaligned-usertrap
|
|||
|
||||
On architectures where unaligned accesses cause traps, and where this
|
||||
feature is supported (``CONFIG_SYSCTL_ARCH_UNALIGN_NO_WARN``;
|
||||
currently, ``arc`` and ``ia64``), controls whether all unaligned traps
|
||||
are logged.
|
||||
currently, ``arc``, ``ia64`` and ``loongarch``), controls whether all
|
||||
unaligned traps are logged.
|
||||
|
||||
= =============================================================
|
||||
0 Log all unaligned accesses.
|
||||
|
@ -1492,8 +1492,8 @@ unaligned-trap
|
|||
|
||||
On architectures where unaligned accesses cause traps, and where this
|
||||
feature is supported (``CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW``; currently,
|
||||
``arc`` and ``parisc``), controls whether unaligned traps are caught
|
||||
and emulated (instead of failing).
|
||||
``arc``, ``parisc`` and ``loongarch``), controls whether unaligned traps
|
||||
are caught and emulated (instead of failing).
|
||||
|
||||
= ========================================================
|
||||
0 Do not emulate unaligned accesses.
|
||||
|
|
|
@ -18,6 +18,7 @@ properties:
|
|||
- enum:
|
||||
- ingenic,jz4740-dma
|
||||
- ingenic,jz4725b-dma
|
||||
- ingenic,jz4755-dma
|
||||
- ingenic,jz4760-dma
|
||||
- ingenic,jz4760-bdma
|
||||
- ingenic,jz4760-mdma
|
||||
|
|
|
@ -39,7 +39,7 @@ properties:
|
|||
Should contain all of the per-channel DMA interrupts in
|
||||
ascending order with respect to the DMA channel index.
|
||||
minItems: 1
|
||||
maxItems: 31
|
||||
maxItems: 32
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
@ -52,6 +52,9 @@ properties:
|
|||
|
||||
dma-coherent: true
|
||||
|
||||
dma-channel-mask:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
@ -60,6 +63,7 @@ required:
|
|||
- reset-names
|
||||
- "#dma-cells"
|
||||
- iommus
|
||||
- dma-channel-mask
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
@ -108,5 +112,6 @@ examples:
|
|||
#dma-cells = <1>;
|
||||
iommus = <&smmu TEGRA186_SID_GPCDMA_0>;
|
||||
dma-coherent;
|
||||
dma-channel-mask = <0xfffffffe>;
|
||||
};
|
||||
...
|
||||
|
|
|
@ -18,14 +18,24 @@ allOf:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sc7280-gpi-dma
|
||||
- qcom,sdm845-gpi-dma
|
||||
- qcom,sm6350-gpi-dma
|
||||
- qcom,sm8150-gpi-dma
|
||||
- qcom,sm8250-gpi-dma
|
||||
- qcom,sm8350-gpi-dma
|
||||
- qcom,sm8450-gpi-dma
|
||||
oneOf:
|
||||
- enum:
|
||||
- qcom,sdm845-gpi-dma
|
||||
- qcom,sm6350-gpi-dma
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,sc7280-gpi-dma
|
||||
- qcom,sm6115-gpi-dma
|
||||
- qcom,sm6375-gpi-dma
|
||||
- qcom,sm8350-gpi-dma
|
||||
- qcom,sm8450-gpi-dma
|
||||
- const: qcom,sm6350-gpi-dma
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,sdm670-gpi-dma
|
||||
- qcom,sm8150-gpi-dma
|
||||
- qcom,sm8250-gpi-dma
|
||||
- const: qcom,sdm845-gpi-dma
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
@ -28,10 +28,42 @@ properties:
|
|||
- enum:
|
||||
- qcom,msm8996-smmu-v2
|
||||
- qcom,msm8998-smmu-v2
|
||||
- qcom,sdm630-smmu-v2
|
||||
- const: qcom,smmu-v2
|
||||
|
||||
- description: Qcom SoCs implementing "arm,mmu-500"
|
||||
- description: Qcom SoCs implementing "qcom,smmu-500" and "arm,mmu-500"
|
||||
items:
|
||||
- enum:
|
||||
- qcom,qcm2290-smmu-500
|
||||
- qcom,qdu1000-smmu-500
|
||||
- qcom,sc7180-smmu-500
|
||||
- qcom,sc7280-smmu-500
|
||||
- qcom,sc8180x-smmu-500
|
||||
- qcom,sc8280xp-smmu-500
|
||||
- qcom,sdm670-smmu-500
|
||||
- qcom,sdm845-smmu-500
|
||||
- qcom,sm6115-smmu-500
|
||||
- qcom,sm6350-smmu-500
|
||||
- qcom,sm6375-smmu-500
|
||||
- qcom,sm8150-smmu-500
|
||||
- qcom,sm8250-smmu-500
|
||||
- qcom,sm8350-smmu-500
|
||||
- qcom,sm8450-smmu-500
|
||||
- const: qcom,smmu-500
|
||||
- const: arm,mmu-500
|
||||
|
||||
- description: Qcom SoCs implementing "arm,mmu-500" (non-qcom implementation)
|
||||
deprecated: true
|
||||
items:
|
||||
- enum:
|
||||
- qcom,sdx55-smmu-500
|
||||
- qcom,sdx65-smmu-500
|
||||
- const: arm,mmu-500
|
||||
|
||||
- description: Qcom SoCs implementing "arm,mmu-500" (legacy binding)
|
||||
deprecated: true
|
||||
items:
|
||||
# Do not add additional SoC to this list. Instead use two previous lists.
|
||||
- enum:
|
||||
- qcom,qcm2290-smmu-500
|
||||
- qcom,sc7180-smmu-500
|
||||
|
@ -39,8 +71,7 @@ properties:
|
|||
- qcom,sc8180x-smmu-500
|
||||
- qcom,sc8280xp-smmu-500
|
||||
- qcom,sdm845-smmu-500
|
||||
- qcom,sdx55-smmu-500
|
||||
- qcom,sdx65-smmu-500
|
||||
- qcom,sm6115-smmu-500
|
||||
- qcom,sm6350-smmu-500
|
||||
- qcom,sm6375-smmu-500
|
||||
- qcom,sm8150-smmu-500
|
||||
|
@ -48,13 +79,28 @@ properties:
|
|||
- qcom,sm8350-smmu-500
|
||||
- qcom,sm8450-smmu-500
|
||||
- const: arm,mmu-500
|
||||
|
||||
- description: Qcom Adreno GPUs implementing "arm,smmu-500"
|
||||
items:
|
||||
- enum:
|
||||
- qcom,sc7280-smmu-500
|
||||
- qcom,sm8250-smmu-500
|
||||
- const: qcom,adreno-smmu
|
||||
- const: arm,mmu-500
|
||||
- description: Qcom Adreno GPUs implementing "arm,smmu-v2"
|
||||
items:
|
||||
- enum:
|
||||
- qcom,msm8996-smmu-v2
|
||||
- qcom,sc7180-smmu-v2
|
||||
- qcom,sdm630-smmu-v2
|
||||
- qcom,sdm845-smmu-v2
|
||||
- qcom,sm6350-smmu-v2
|
||||
- const: qcom,adreno-smmu
|
||||
- const: qcom,smmu-v2
|
||||
- description: Qcom Adreno GPUs on Google Cheza platform
|
||||
items:
|
||||
- const: qcom,sdm845-smmu-v2
|
||||
- const: qcom,smmu-v2
|
||||
- description: Marvell SoCs implementing "arm,mmu-500"
|
||||
items:
|
||||
- const: marvell,ap806-smmu-500
|
||||
|
@ -147,16 +193,12 @@ properties:
|
|||
present in such cases.
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: iface
|
||||
minItems: 1
|
||||
maxItems: 7
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: bus clock required for downstream bus access and for the
|
||||
smmu ptw
|
||||
- description: interface clock required to access smmu's registers
|
||||
through the TCU's programming interface.
|
||||
minItems: 1
|
||||
maxItems: 7
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
@ -206,6 +248,124 @@ allOf:
|
|||
reg:
|
||||
maxItems: 1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,msm8998-smmu-v2
|
||||
- qcom,sdm630-smmu-v2
|
||||
then:
|
||||
anyOf:
|
||||
- properties:
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
clocks:
|
||||
items:
|
||||
- description: bus clock required for downstream bus access and for
|
||||
the smmu ptw
|
||||
- properties:
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: mem
|
||||
- const: mem_iface
|
||||
clocks:
|
||||
items:
|
||||
- description: interface clock required to access smmu's registers
|
||||
through the TCU's programming interface.
|
||||
- description: bus clock required for memory access
|
||||
- description: bus clock required for GPU memory access
|
||||
- properties:
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface-mm
|
||||
- const: iface-smmu
|
||||
- const: bus-mm
|
||||
- const: bus-smmu
|
||||
clocks:
|
||||
items:
|
||||
- description: interface clock required to access mnoc's registers
|
||||
through the TCU's programming interface.
|
||||
- description: interface clock required to access smmu's registers
|
||||
through the TCU's programming interface.
|
||||
- description: bus clock required for downstream bus access
|
||||
- description: bus clock required for the smmu ptw
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,msm8996-smmu-v2
|
||||
- qcom,sc7180-smmu-v2
|
||||
- qcom,sdm845-smmu-v2
|
||||
then:
|
||||
properties:
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: iface
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: bus clock required for downstream bus access and for
|
||||
the smmu ptw
|
||||
- description: interface clock required to access smmu's registers
|
||||
through the TCU's programming interface.
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: qcom,sc7280-smmu-500
|
||||
then:
|
||||
properties:
|
||||
clock-names:
|
||||
items:
|
||||
- const: gcc_gpu_memnoc_gfx_clk
|
||||
- const: gcc_gpu_snoc_dvm_gfx_clk
|
||||
- const: gpu_cc_ahb_clk
|
||||
- const: gpu_cc_hlos1_vote_gpu_smmu_clk
|
||||
- const: gpu_cc_cx_gmu_clk
|
||||
- const: gpu_cc_hub_cx_int_clk
|
||||
- const: gpu_cc_hub_aon_clk
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: GPU memnoc_gfx clock
|
||||
- description: GPU snoc_dvm_gfx clock
|
||||
- description: GPU ahb clock
|
||||
- description: GPU hlos1_vote_GPU smmu clock
|
||||
- description: GPU cx_gmu clock
|
||||
- description: GPU hub_cx_int clock
|
||||
- description: GPU hub_aon clock
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sm6350-smmu-v2
|
||||
- qcom,sm8150-smmu-500
|
||||
- qcom,sm8250-smmu-500
|
||||
then:
|
||||
properties:
|
||||
clock-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: bus
|
||||
- const: iface
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: bus clock required for AHB bus access
|
||||
- description: bus clock required for downstream bus access and for
|
||||
the smmu ptw
|
||||
- description: interface clock required to access smmu's registers
|
||||
through the TCU's programming interface.
|
||||
|
||||
examples:
|
||||
- |+
|
||||
/* SMMU with stream matching or stream indexing */
|
||||
|
|
|
@ -82,6 +82,7 @@ properties:
|
|||
- mediatek,mt8195-iommu-vdo # generation two
|
||||
- mediatek,mt8195-iommu-vpp # generation two
|
||||
- mediatek,mt8195-iommu-infra # generation two
|
||||
- mediatek,mt8365-m4u # generation two
|
||||
|
||||
- description: mt7623 generation one
|
||||
items:
|
||||
|
@ -132,6 +133,7 @@ properties:
|
|||
dt-binding/memory/mt8186-memory-port.h for mt8186,
|
||||
dt-binding/memory/mt8192-larb-port.h for mt8192.
|
||||
dt-binding/memory/mt8195-memory-port.h for mt8195.
|
||||
dt-binding/memory/mediatek,mt8365-larb-port.h for mt8365.
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
|
|
@ -100,6 +100,7 @@ properties:
|
|||
- pattern
|
||||
# LED is triggered by SD/MMC activity
|
||||
- pattern: "^mmc[0-9]+$"
|
||||
- pattern: "^cpu[0-9]*$"
|
||||
|
||||
led-pattern:
|
||||
description: |
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
Qualcomm PM8058 LED driver
|
||||
|
||||
The Qualcomm PM8058 is a multi-functional device which contains
|
||||
an LED driver block for up to six LEDs: three normal LEDs, two
|
||||
"flash" LEDs and one "keypad backlight" LED. The names are
|
||||
quoted because sometimes these LED drivers are used for wildly
|
||||
different things than flash or keypad backlight: their names
|
||||
are more of a suggestion than a hard-wired usecase.
|
||||
|
||||
Hardware-wise the different LEDs support slightly different
|
||||
output currents. The "flash" LEDs do not need to charge nor
|
||||
do they support external triggers. They are just powerful LED
|
||||
drivers.
|
||||
|
||||
The LEDs appear as children to the PM8058 device, with the
|
||||
proper compatible string. For the PM8058 bindings see:
|
||||
mfd/qcom-pm8xxx.txt.
|
||||
|
||||
Each LED is represented as a sub-node of the syscon device. Each
|
||||
node's name represents the name of the corresponding LED.
|
||||
|
||||
LED sub-node properties:
|
||||
|
||||
Required properties:
|
||||
- compatible: one of
|
||||
"qcom,pm8058-led" (for the normal LEDs at 0x131, 0x132 and 0x133)
|
||||
"qcom,pm8058-keypad-led" (for the "keypad" LED at 0x48)
|
||||
"qcom,pm8058-flash-led" (for the "flash" LEDs at 0x49 and 0xFB)
|
||||
|
||||
Optional properties:
|
||||
- label: see Documentation/devicetree/bindings/leds/common.txt
|
||||
- default-state: see Documentation/devicetree/bindings/leds/common.txt
|
||||
- linux,default-trigger: see Documentation/devicetree/bindings/leds/common.txt
|
||||
|
||||
Example:
|
||||
|
||||
qcom,ssbi@500000 {
|
||||
pmicintc: pmic@0 {
|
||||
compatible = "qcom,pm8058";
|
||||
led@48 {
|
||||
compatible = "qcom,pm8058-keypad-led";
|
||||
reg = <0x48>;
|
||||
label = "pm8050:white:keypad";
|
||||
default-state = "off";
|
||||
};
|
||||
led@131 {
|
||||
compatible = "qcom,pm8058-led";
|
||||
reg = <0x131>;
|
||||
label = "pm8058:red";
|
||||
default-state = "off";
|
||||
};
|
||||
led@132 {
|
||||
compatible = "qcom,pm8058-led";
|
||||
reg = <0x132>;
|
||||
label = "pm8058:yellow";
|
||||
default-state = "off";
|
||||
linux,default-trigger = "mmc0";
|
||||
};
|
||||
led@133 {
|
||||
compatible = "qcom,pm8058-led";
|
||||
reg = <0x133>;
|
||||
label = "pm8058:green";
|
||||
default-state = "on";
|
||||
linux,default-trigger = "heartbeat";
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,57 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/leds/qcom,pm8058-led.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm PM8058 PMIC LED
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
|
||||
description: |
|
||||
The Qualcomm PM8058 contains an LED block for up to six LEDs:: three normal
|
||||
LEDs, two "flash" LEDs and one "keypad backlight" LED. The names are quoted
|
||||
because sometimes these LED drivers are used for wildly different things than
|
||||
flash or keypad backlight:: their names are more of a suggestion than a
|
||||
hard-wired usecase.
|
||||
|
||||
Hardware-wise the different LEDs support slightly different output currents.
|
||||
The "flash" LEDs do not need to charge nor do they support external triggers.
|
||||
They are just powerful LED drivers.
|
||||
|
||||
allOf:
|
||||
- $ref: common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,pm8058-led
|
||||
- qcom,pm8058-keypad-led
|
||||
- qcom,pm8058-flash-led
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
pmic {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led@131 {
|
||||
compatible = "qcom,pm8058-led";
|
||||
reg = <0x131>;
|
||||
label = "pm8058:red";
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
default-state = "off";
|
||||
};
|
||||
};
|
|
@ -13,6 +13,8 @@ description: |
|
|||
maintainers:
|
||||
- Dmitry Osipenko <digetx@gmail.com>
|
||||
|
||||
$ref: /schemas/power/supply/power-supply.yaml
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
|
@ -22,15 +24,13 @@ properties:
|
|||
reg:
|
||||
maxItems: 1
|
||||
|
||||
monitored-battery: true
|
||||
power-supplies: true
|
||||
system-power-controller: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
|
@ -39,6 +39,10 @@ properties:
|
|||
interrupt-controller: true
|
||||
|
||||
patternProperties:
|
||||
"led@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/leds/qcom,pm8058-led.yaml#
|
||||
|
||||
"rtc@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: "../rtc/qcom-pm8xxx-rtc.yaml"
|
||||
|
|
|
@ -124,6 +124,8 @@ properties:
|
|||
The child node for the charger to hold additional properties. If a
|
||||
battery is not in use, this node can be omitted.
|
||||
type: object
|
||||
$ref: /schemas/power/supply/power-supply.yaml
|
||||
|
||||
properties:
|
||||
monitored-battery:
|
||||
description: |
|
||||
|
|
|
@ -17,13 +17,20 @@ properties:
|
|||
compatible:
|
||||
oneOf:
|
||||
- const: allwinner,sun6i-a31-mipi-dphy
|
||||
- const: allwinner,sun50i-a100-mipi-dphy
|
||||
- items:
|
||||
- const: allwinner,sun50i-a64-mipi-dphy
|
||||
- const: allwinner,sun6i-a31-mipi-dphy
|
||||
- items:
|
||||
- const: allwinner,sun20i-d1-mipi-dphy
|
||||
- const: allwinner,sun50i-a100-mipi-dphy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Bus Clock
|
||||
|
@ -53,6 +60,7 @@ required:
|
|||
- "#phy-cells"
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
|
@ -61,9 +69,12 @@ additionalProperties: false
|
|||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
dphy0: d-phy@1ca1000 {
|
||||
compatible = "allwinner,sun6i-a31-mipi-dphy";
|
||||
reg = <0x01ca1000 0x1000>;
|
||||
interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&ccu 23>, <&ccu 97>;
|
||||
clock-names = "bus", "mod";
|
||||
resets = <&ccu 4>;
|
||||
|
|
|
@ -36,18 +36,22 @@ properties:
|
|||
- const: pmu3
|
||||
|
||||
clocks:
|
||||
minItems: 4
|
||||
items:
|
||||
- description: USB OTG PHY bus clock
|
||||
- description: USB Host 0 PHY bus clock
|
||||
- description: USB Host 1 PHY bus clock
|
||||
- description: USB Host 2 PHY bus clock
|
||||
- description: PMU clock for host port 2
|
||||
|
||||
clock-names:
|
||||
minItems: 4
|
||||
items:
|
||||
- const: usb0_phy
|
||||
- const: usb1_phy
|
||||
- const: usb2_phy
|
||||
- const: usb3_phy
|
||||
- const: pmu2_clk
|
||||
|
||||
resets:
|
||||
items:
|
||||
|
@ -96,6 +100,28 @@ required:
|
|||
- resets
|
||||
- reset-names
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun50i-h616-usb-phy
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 5
|
||||
|
||||
clock-names:
|
||||
minItems: 5
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 4
|
||||
|
||||
clock-names:
|
||||
maxItems: 4
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
|
|
@ -16,6 +16,7 @@ properties:
|
|||
compatible:
|
||||
enum:
|
||||
- fsl,imx8mm-pcie-phy
|
||||
- fsl,imx8mp-pcie-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -28,11 +29,16 @@ properties:
|
|||
- const: ref
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: pciephy
|
||||
oneOf:
|
||||
- items: # for iMX8MM
|
||||
- const: pciephy
|
||||
- items: # for IMX8MP
|
||||
- const: pciephy
|
||||
- const: perst
|
||||
|
||||
fsl,refclk-pad-mode:
|
||||
description: |
|
||||
|
@ -60,6 +66,10 @@ properties:
|
|||
description: A boolean property indicating the CLKREQ# signal is
|
||||
not supported in the board design (optional)
|
||||
|
||||
power-domains:
|
||||
description: PCIe PHY power domain (optional).
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- "#phy-cells"
|
||||
- compatible
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/qcom,qmp-pcie-phy.yaml#
|
||||
$id: http://devicetree.org/schemas/phy/qcom,ipq8074-qmp-pcie-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QMP PHY controller (PCIe)
|
||||
title: Qualcomm QMP PHY controller (PCIe, IPQ8074)
|
||||
|
||||
maintainers:
|
||||
- Vinod Koul <vkoul@kernel.org>
|
||||
|
@ -13,6 +13,9 @@ description:
|
|||
QMP PHY controller supports physical layer functionality for a number of
|
||||
controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB.
|
||||
|
||||
Note that these bindings are for SoCs up to SC8180X. For newer SoCs, see
|
||||
qcom,sc8280xp-qmp-pcie-phy.yaml.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
|
@ -1,10 +1,10 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/qcom,qmp-ufs-phy.yaml#
|
||||
$id: http://devicetree.org/schemas/phy/qcom,msm8996-qmp-ufs-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QMP PHY controller (UFS)
|
||||
title: Qualcomm QMP PHY controller (UFS, MSM8996)
|
||||
|
||||
maintainers:
|
||||
- Vinod Koul <vkoul@kernel.org>
|
||||
|
@ -13,13 +13,15 @@ description:
|
|||
QMP PHY controller supports physical layer functionality for a number of
|
||||
controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB.
|
||||
|
||||
Note that these bindings are for SoCs up to SC8180X. For newer SoCs, see
|
||||
qcom,sc8280xp-qmp-ufs-phy.yaml.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,msm8996-qmp-ufs-phy
|
||||
- qcom,msm8998-qmp-ufs-phy
|
||||
- qcom,sc8180x-qmp-ufs-phy
|
||||
- qcom,sc8280xp-qmp-ufs-phy
|
||||
- qcom,sdm845-qmp-ufs-phy
|
||||
- qcom,sm6115-qmp-ufs-phy
|
||||
- qcom,sm6350-qmp-ufs-phy
|
||||
|
@ -119,7 +121,6 @@ allOf:
|
|||
enum:
|
||||
- qcom,msm8998-qmp-ufs-phy
|
||||
- qcom,sc8180x-qmp-ufs-phy
|
||||
- qcom,sc8280xp-qmp-ufs-phy
|
||||
- qcom,sdm845-qmp-ufs-phy
|
||||
- qcom,sm6115-qmp-ufs-phy
|
||||
- qcom,sm6350-qmp-ufs-phy
|
||||
|
@ -156,7 +157,6 @@ allOf:
|
|||
contains:
|
||||
enum:
|
||||
- qcom,msm8998-qmp-ufs-phy
|
||||
- qcom,sc8280xp-qmp-ufs-phy
|
||||
- qcom,sdm845-qmp-ufs-phy
|
||||
- qcom,sm6350-qmp-ufs-phy
|
||||
- qcom,sm8150-qmp-ufs-phy
|
||||
|
@ -211,11 +211,12 @@ allOf:
|
|||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-sc8280xp.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-sm8250.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
|
||||
phy-wrapper@1d87000 {
|
||||
compatible = "qcom,sc8280xp-qmp-ufs-phy";
|
||||
reg = <0x01d87000 0xe10>;
|
||||
compatible = "qcom,sm8250-qmp-ufs-phy";
|
||||
reg = <0x01d87000 0x1c0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0x01d87000 0x1000>;
|
|
@ -1,10 +1,10 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/qcom,qmp-usb-phy.yaml#
|
||||
$id: http://devicetree.org/schemas/phy/qcom,msm8996-qmp-usb3-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QMP PHY controller (USB)
|
||||
title: Qualcomm QMP PHY controller (USB, MSM8996)
|
||||
|
||||
maintainers:
|
||||
- Vinod Koul <vkoul@kernel.org>
|
||||
|
@ -13,6 +13,9 @@ description:
|
|||
QMP PHY controller supports physical layer functionality for a number of
|
||||
controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB.
|
||||
|
||||
Note that these bindings are for SoCs up to SC8180X. For newer SoCs, see
|
||||
qcom,sc8280xp-qmp-usb3-uni-phy.yaml.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
|
@ -23,7 +26,6 @@ properties:
|
|||
- qcom,qcm2290-qmp-usb3-phy
|
||||
- qcom,sc7180-qmp-usb3-phy
|
||||
- qcom,sc8180x-qmp-usb3-phy
|
||||
- qcom,sc8280xp-qmp-usb3-uni-phy
|
||||
- qcom,sdm845-qmp-usb3-phy
|
||||
- qcom,sdm845-qmp-usb3-uni-phy
|
||||
- qcom,sdx55-qmp-usb3-uni-phy
|
||||
|
@ -201,7 +203,6 @@ allOf:
|
|||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sc8280xp-qmp-usb3-uni-phy
|
||||
- qcom,sm8150-qmp-usb3-phy
|
||||
- qcom,sm8150-qmp-usb3-uni-phy
|
||||
- qcom,sm8250-qmp-usb3-uni-phy
|
||||
|
@ -268,16 +269,6 @@ allOf:
|
|||
- const: phy_phy
|
||||
- const: phy
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sc8280xp-qmp-usb3-uni-phy
|
||||
then:
|
||||
required:
|
||||
- power-domains
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
@ -349,7 +340,6 @@ allOf:
|
|||
contains:
|
||||
enum:
|
||||
- qcom,msm8996-qmp-usb3-phy
|
||||
- qcom,sc8280xp-qmp-usb3-uni-phy
|
||||
- qcom,sm8250-qmp-usb3-uni-phy
|
||||
- qcom,sm8350-qmp-usb3-uni-phy
|
||||
then:
|
|
@ -2,10 +2,17 @@
|
|||
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/phy/qcom,qmp-usb3-dp-phy.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
$id: http://devicetree.org/schemas/phy/qcom,sc7180-qmp-usb3-dp-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QMP USB3 DP PHY controller
|
||||
title: Qualcomm QMP USB3 DP PHY controller (SC7180)
|
||||
|
||||
description:
|
||||
The QMP PHY controller supports physical layer functionality for a number of
|
||||
controllers on Qualcomm chipsets, such as, PCIe, UFS and USB.
|
||||
|
||||
Note that these bindings are for SoCs up to SC8180X. For newer SoCs, see
|
||||
qcom,sc8280xp-qmp-usb43dp-phy.yaml.
|
||||
|
||||
maintainers:
|
||||
- Wesley Cheng <quic_wcheng@quicinc.com>
|
||||
|
@ -16,7 +23,6 @@ properties:
|
|||
- qcom,sc7180-qmp-usb3-dp-phy
|
||||
- qcom,sc7280-qmp-usb3-dp-phy
|
||||
- qcom,sc8180x-qmp-usb3-dp-phy
|
||||
- qcom,sc8280xp-qmp-usb43dp-phy
|
||||
- qcom,sdm845-qmp-usb3-dp-phy
|
||||
- qcom,sm8250-qmp-usb3-dp-phy
|
||||
reg:
|
||||
|
@ -162,17 +168,6 @@ required:
|
|||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sc8280xp-qmp-usb43dp-phy
|
||||
then:
|
||||
required:
|
||||
- power-domains
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-sdm845.h>
|
|
@ -0,0 +1,165 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-pcie-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QMP PHY controller (PCIe, SC8280XP)
|
||||
|
||||
maintainers:
|
||||
- Vinod Koul <vkoul@kernel.org>
|
||||
|
||||
description:
|
||||
The QMP PHY controller supports physical layer functionality for a number of
|
||||
controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sc8280xp-qmp-gen3x1-pcie-phy
|
||||
- qcom,sc8280xp-qmp-gen3x2-pcie-phy
|
||||
- qcom,sc8280xp-qmp-gen3x4-pcie-phy
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
clocks:
|
||||
maxItems: 6
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: aux
|
||||
- const: cfg_ahb
|
||||
- const: ref
|
||||
- const: rchng
|
||||
- const: pipe
|
||||
- const: pipediv2
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: phy
|
||||
|
||||
vdda-phy-supply: true
|
||||
|
||||
vdda-pll-supply: true
|
||||
|
||||
qcom,4ln-config-sel:
|
||||
description: PCIe 4-lane configuration
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
items:
|
||||
- items:
|
||||
- description: phandle of TCSR syscon
|
||||
- description: offset of PCIe 4-lane configuration register
|
||||
- description: offset of configuration bit for this PHY
|
||||
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
- resets
|
||||
- reset-names
|
||||
- vdda-phy-supply
|
||||
- vdda-pll-supply
|
||||
- "#clock-cells"
|
||||
- clock-output-names
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sc8280xp-qmp-gen3x4-pcie-phy
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: port a
|
||||
- description: port b
|
||||
required:
|
||||
- qcom,4ln-config-sel
|
||||
else:
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-sc8280xp.h>
|
||||
|
||||
pcie2b_phy: phy@1c18000 {
|
||||
compatible = "qcom,sc8280xp-qmp-gen3x2-pcie-phy";
|
||||
reg = <0x01c18000 0x2000>;
|
||||
|
||||
clocks = <&gcc GCC_PCIE_2B_AUX_CLK>,
|
||||
<&gcc GCC_PCIE_2B_CFG_AHB_CLK>,
|
||||
<&gcc GCC_PCIE_2A2B_CLKREF_CLK>,
|
||||
<&gcc GCC_PCIE2B_PHY_RCHNG_CLK>,
|
||||
<&gcc GCC_PCIE_2B_PIPE_CLK>,
|
||||
<&gcc GCC_PCIE_2B_PIPEDIV2_CLK>;
|
||||
clock-names = "aux", "cfg_ahb", "ref", "rchng",
|
||||
"pipe", "pipediv2";
|
||||
|
||||
power-domains = <&gcc PCIE_2B_GDSC>;
|
||||
|
||||
resets = <&gcc GCC_PCIE_2B_PHY_BCR>;
|
||||
reset-names = "phy";
|
||||
|
||||
vdda-phy-supply = <&vreg_l6d>;
|
||||
vdda-pll-supply = <&vreg_l4d>;
|
||||
|
||||
#clock-cells = <0>;
|
||||
clock-output-names = "pcie_2b_pipe_clk";
|
||||
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
|
||||
pcie2a_phy: phy@1c24000 {
|
||||
compatible = "qcom,sc8280xp-qmp-gen3x4-pcie-phy";
|
||||
reg = <0x01c24000 0x2000>, <0x01c26000 0x2000>;
|
||||
|
||||
clocks = <&gcc GCC_PCIE_2A_AUX_CLK>,
|
||||
<&gcc GCC_PCIE_2A_CFG_AHB_CLK>,
|
||||
<&gcc GCC_PCIE_2A2B_CLKREF_CLK>,
|
||||
<&gcc GCC_PCIE2A_PHY_RCHNG_CLK>,
|
||||
<&gcc GCC_PCIE_2A_PIPE_CLK>,
|
||||
<&gcc GCC_PCIE_2A_PIPEDIV2_CLK>;
|
||||
clock-names = "aux", "cfg_ahb", "ref", "rchng",
|
||||
"pipe", "pipediv2";
|
||||
|
||||
power-domains = <&gcc PCIE_2A_GDSC>;
|
||||
|
||||
resets = <&gcc GCC_PCIE_2A_PHY_BCR>;
|
||||
reset-names = "phy";
|
||||
|
||||
vdda-phy-supply = <&vreg_l6d>;
|
||||
vdda-pll-supply = <&vreg_l4d>;
|
||||
|
||||
qcom,4ln-config-sel = <&tcsr 0xa044 0>;
|
||||
|
||||
#clock-cells = <0>;
|
||||
clock-output-names = "pcie_2a_pipe_clk";
|
||||
|
||||
#phy-cells = <0>;
|
||||
};
|
|
@ -0,0 +1,83 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-ufs-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QMP PHY controller (UFS, SC8280XP)
|
||||
|
||||
maintainers:
|
||||
- Vinod Koul <vkoul@kernel.org>
|
||||
|
||||
description:
|
||||
The QMP PHY controller supports physical layer functionality for a number of
|
||||
controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sc8280xp-qmp-ufs-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ref
|
||||
- const: ref_aux
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: ufsphy
|
||||
|
||||
vdda-phy-supply: true
|
||||
|
||||
vdda-pll-supply: true
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
- resets
|
||||
- reset-names
|
||||
- vdda-phy-supply
|
||||
- vdda-pll-supply
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-sc8280xp.h>
|
||||
|
||||
ufs_mem_phy: phy@1d87000 {
|
||||
compatible = "qcom,sc8280xp-qmp-ufs-phy";
|
||||
reg = <0x01d87000 0x1000>;
|
||||
|
||||
clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>, <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
|
||||
clock-names = "ref", "ref_aux";
|
||||
|
||||
power-domains = <&gcc UFS_PHY_GDSC>;
|
||||
|
||||
resets = <&ufs_mem_hc 0>;
|
||||
reset-names = "ufsphy";
|
||||
|
||||
vdda-phy-supply = <&vreg_l6b>;
|
||||
vdda-pll-supply = <&vreg_l3b>;
|
||||
|
||||
#phy-cells = <0>;
|
||||
};
|
|
@ -0,0 +1,102 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QMP PHY controller (USB, SC8280XP)
|
||||
|
||||
maintainers:
|
||||
- Vinod Koul <vkoul@kernel.org>
|
||||
|
||||
description:
|
||||
The QMP PHY controller supports physical layer functionality for a number of
|
||||
controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sc8280xp-qmp-usb3-uni-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 4
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: aux
|
||||
- const: ref
|
||||
- const: com_aux
|
||||
- const: pipe
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 2
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: phy
|
||||
- const: phy_phy
|
||||
|
||||
vdda-phy-supply: true
|
||||
|
||||
vdda-pll-supply: true
|
||||
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
- resets
|
||||
- reset-names
|
||||
- vdda-phy-supply
|
||||
- vdda-pll-supply
|
||||
- "#clock-cells"
|
||||
- clock-output-names
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-sc8280xp.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
|
||||
phy@88ef000 {
|
||||
compatible = "qcom,sc8280xp-qmp-usb3-uni-phy";
|
||||
reg = <0x088ef000 0x2000>;
|
||||
|
||||
clocks = <&gcc GCC_USB3_MP_PHY_AUX_CLK>,
|
||||
<&gcc GCC_USB3_MP0_CLKREF_CLK>,
|
||||
<&gcc GCC_USB3_MP_PHY_COM_AUX_CLK>,
|
||||
<&gcc GCC_USB3_MP_PHY_PIPE_0_CLK>;
|
||||
clock-names = "aux", "ref", "com_aux", "pipe";
|
||||
|
||||
power-domains = <&gcc USB30_MP_GDSC>;
|
||||
|
||||
resets = <&gcc GCC_USB3_UNIPHY_MP0_BCR>,
|
||||
<&gcc GCC_USB3UNIPHY_PHY_MP0_BCR>;
|
||||
reset-names = "phy", "phy_phy";
|
||||
|
||||
vdda-phy-supply = <&vreg_l3a>;
|
||||
vdda-pll-supply = <&vreg_l5a>;
|
||||
|
||||
#clock-cells = <0>;
|
||||
clock-output-names = "usb2_phy0_pipe_clk";
|
||||
|
||||
#phy-cells = <0>;
|
||||
};
|
|
@ -0,0 +1,99 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QMP USB4-USB3-DP PHY controller (SC8280XP)
|
||||
|
||||
maintainers:
|
||||
- Vinod Koul <vkoul@kernel.org>
|
||||
|
||||
description:
|
||||
The QMP PHY controller supports physical layer functionality for a number of
|
||||
controllers on Qualcomm chipsets, such as, PCIe, UFS and USB.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sc8280xp-qmp-usb43dp-phy
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 4
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: aux
|
||||
- const: ref
|
||||
- const: com_aux
|
||||
- const: usb3_pipe
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 2
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: phy
|
||||
- const: common
|
||||
|
||||
vdda-phy-supply: true
|
||||
|
||||
vdda-pll-supply: true
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
description:
|
||||
See include/dt-bindings/dt-bindings/phy/phy-qcom-qmp.h
|
||||
|
||||
"#phy-cells":
|
||||
const: 1
|
||||
description:
|
||||
See include/dt-bindings/dt-bindings/phy/phy-qcom-qmp.h
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
- resets
|
||||
- reset-names
|
||||
- vdda-phy-supply
|
||||
- vdda-pll-supply
|
||||
- "#clock-cells"
|
||||
- "#phy-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-sc8280xp.h>
|
||||
|
||||
phy@88eb000 {
|
||||
compatible = "qcom,sc8280xp-qmp-usb43dp-phy";
|
||||
reg = <0x088eb000 0x4000>;
|
||||
|
||||
clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
|
||||
<&gcc GCC_USB4_EUD_CLKREF_CLK>,
|
||||
<&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>,
|
||||
<&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
|
||||
clock-names = "aux", "ref", "com_aux", "usb3_pipe";
|
||||
|
||||
power-domains = <&gcc USB30_PRIM_GDSC>;
|
||||
|
||||
resets = <&gcc GCC_USB3_PHY_PRIM_BCR>,
|
||||
<&gcc GCC_USB4_DP_PHY_PRIM_BCR>;
|
||||
reset-names = "phy", "common";
|
||||
|
||||
vdda-phy-supply = <&vreg_l9d>;
|
||||
vdda-pll-supply = <&vreg_l4d>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
#phy-cells = <1>;
|
||||
};
|
|
@ -0,0 +1,54 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/phy/renesas,r8a779f0-ether-serdes.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas Ethernet SERDES
|
||||
|
||||
maintainers:
|
||||
- Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: renesas,r8a779f0-ether-serdes
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
'#phy-cells':
|
||||
description: Port number of SERDES.
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- resets
|
||||
- power-domains
|
||||
- '#phy-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/r8a779f0-cpg-mssr.h>
|
||||
#include <dt-bindings/power/r8a779f0-sysc.h>
|
||||
|
||||
phy@e6444000 {
|
||||
compatible = "renesas,r8a779f0-ether-serdes";
|
||||
reg = <0xe6444000 0xc00>;
|
||||
clocks = <&cpg CPG_MOD 1506>;
|
||||
power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
|
||||
resets = <&cpg 1506>;
|
||||
#phy-cells = <1>;
|
||||
};
|
|
@ -54,6 +54,7 @@ properties:
|
|||
- ti,dm814-phy-gmii-sel
|
||||
- ti,am654-phy-gmii-sel
|
||||
- ti,j7200-cpsw5g-phy-gmii-sel
|
||||
- ti,j721e-cpsw9g-phy-gmii-sel
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -63,14 +64,17 @@ properties:
|
|||
ti,qsgmii-main-ports:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description: |
|
||||
Required only for QSGMII mode. Array to select the port for
|
||||
QSGMII main mode. Rest of the ports are selected as QSGMII_SUB
|
||||
ports automatically. Any one of the 4 CPSW5G ports can act as the
|
||||
main port with the rest of them being the QSGMII_SUB ports.
|
||||
maxItems: 1
|
||||
Required only for QSGMII mode. Array to select the port/s for QSGMII
|
||||
main mode. The size of the array corresponds to the number of QSGMII
|
||||
interfaces and thus, the number of distinct QSGMII main ports,
|
||||
supported by the device. If the device supports two QSGMII interfaces
|
||||
but only one QSGMII interface is desired, repeat the QSGMII main port
|
||||
value corresponding to the QSGMII interface in the array.
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
minimum: 1
|
||||
maximum: 4
|
||||
maximum: 8
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
|
@ -81,12 +85,43 @@ allOf:
|
|||
- ti,dra7xx-phy-gmii-sel
|
||||
- ti,dm814-phy-gmii-sel
|
||||
- ti,am654-phy-gmii-sel
|
||||
- ti,j7200-cpsw5g-phy-gmii-sel
|
||||
- ti,j721e-cpsw9g-phy-gmii-sel
|
||||
then:
|
||||
properties:
|
||||
'#phy-cells':
|
||||
const: 1
|
||||
description: CPSW port number (starting from 1)
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- ti,j7200-cpsw5g-phy-gmii-sel
|
||||
then:
|
||||
properties:
|
||||
ti,qsgmii-main-ports:
|
||||
maxItems: 1
|
||||
items:
|
||||
minimum: 1
|
||||
maximum: 4
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- ti,j721e-cpsw9g-phy-gmii-sel
|
||||
then:
|
||||
properties:
|
||||
ti,qsgmii-main-ports:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
items:
|
||||
minimum: 1
|
||||
maximum: 8
|
||||
|
||||
- if:
|
||||
not:
|
||||
properties:
|
||||
|
@ -94,6 +129,7 @@ allOf:
|
|||
contains:
|
||||
enum:
|
||||
- ti,j7200-cpsw5g-phy-gmii-sel
|
||||
- ti,j721e-cpsw9g-phy-gmii-sel
|
||||
then:
|
||||
properties:
|
||||
ti,qsgmii-main-ports: false
|
||||
|
|
|
@ -15,8 +15,10 @@ properties:
|
|||
enum:
|
||||
- ti,j721e-wiz-16g
|
||||
- ti,j721e-wiz-10g
|
||||
- ti,j721s2-wiz-10g
|
||||
- ti,am64-wiz-10g
|
||||
- ti,j7200-wiz-10g
|
||||
- ti,j784s4-wiz-10g
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
|
|
@ -25,6 +25,9 @@ description: >
|
|||
inactive-delay, the GPIO is driven active again. After a delay specified by wait-delay, the
|
||||
restart handler completes allowing other restart handlers to be attempted.
|
||||
|
||||
allOf:
|
||||
- $ref: restart-handler.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: gpio-restart
|
||||
|
@ -41,16 +44,6 @@ properties:
|
|||
in its inactive state.
|
||||
|
||||
priority:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
A priority ranging from 0 to 255 (default 129) according to the following guidelines:
|
||||
|
||||
0: Restart handler of last resort, with limited restart capabilities.
|
||||
128: Default restart handler; use if no other restart handler is expected to be available,
|
||||
and/or if restart functionality is sufficient to restart the entire system.
|
||||
255: Highest priority restart handler, will preempt all other restart handlers.
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
default: 129
|
||||
|
||||
active-delay:
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/power/reset/restart-handler.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Restart and shutdown handler generic binding
|
||||
|
||||
maintainers:
|
||||
- Sebastian Reichel <sre@kernel.org>
|
||||
|
||||
description:
|
||||
Restart and shutdown handler device is responsible for powering off the
|
||||
system, e.g. my cutting off the power. System might have several restart
|
||||
handlers, which usually are tried from most precise to last resort.
|
||||
|
||||
properties:
|
||||
priority:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
A priority ranging from 0 to 255 according to the following guidelines::
|
||||
0:: Restart handler of last resort, with limited restart capabilities.
|
||||
128:: Typical, default restart handler; use if no other restart handler
|
||||
is expected to be available, and/or if restart functionality is
|
||||
sufficient to restart the entire system.
|
||||
255:: Highest priority restart handler, will preempt all other restart handlers.
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
|
||||
additionalProperties: true
|
|
@ -15,11 +15,15 @@ allOf:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,bq25890
|
||||
- ti,bq25892
|
||||
- ti,bq25895
|
||||
- ti,bq25896
|
||||
oneOf:
|
||||
- enum:
|
||||
- ti,bq25890
|
||||
- items:
|
||||
- enum:
|
||||
- ti,bq25892
|
||||
- ti,bq25895
|
||||
- ti,bq25896
|
||||
- const: ti,bq25890
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -93,7 +97,7 @@ required:
|
|||
- ti,boost-voltage
|
||||
- ti,boost-max-current
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
|
@ -60,13 +60,11 @@ properties:
|
|||
|
||||
monitored-battery:
|
||||
description: |
|
||||
phandle of battery characteristics node.
|
||||
The fuel gauge uses the following battery properties:
|
||||
- energy-full-design-microwatt-hours
|
||||
- charge-full-design-microamp-hours
|
||||
- voltage-min-design-microvolt
|
||||
Both or neither of the *-full-design-*-hours properties must be set.
|
||||
See Documentation/devicetree/bindings/power/supply/battery.yaml
|
||||
|
||||
power-supplies: true
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ title: Ingenic JZ47xx battery bindings
|
|||
maintainers:
|
||||
- Artur Rojek <contact@artur-rojek.eu>
|
||||
|
||||
$ref: power-supply.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
|
@ -28,8 +30,6 @@ properties:
|
|||
|
||||
monitored-battery:
|
||||
description: >
|
||||
phandle to a "simple-battery" compatible node.
|
||||
|
||||
This property must be a phandle to a node using the format described
|
||||
in battery.yaml, with the following properties being required:
|
||||
- voltage-min-design-microvolt: drained battery voltage,
|
||||
|
|
|
@ -59,6 +59,8 @@ properties:
|
|||
Voltage threshold to report battery as over voltage (in mV).
|
||||
Default is not to report over-voltage events.
|
||||
|
||||
power-supplies: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
|
|
@ -18,4 +18,10 @@ properties:
|
|||
This property is added to a supply in order to list the devices which
|
||||
supply it power, referenced by their phandles.
|
||||
|
||||
monitored-battery:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
The battery (with "simple-battery" compatible) being monitored by this
|
||||
power supply.
|
||||
|
||||
additionalProperties: true
|
||||
|
|
|
@ -18,6 +18,7 @@ description: |
|
|||
provides a Dual-source Battery Charger, two port BC1.2 detection and a
|
||||
Battery Monitor.
|
||||
|
||||
$ref: power-supply.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
|
|
@ -28,7 +28,6 @@ properties:
|
|||
The charger uses the following battery properties
|
||||
- charge-term-current-microamp: current for charge termination phase.
|
||||
- constant-charge-voltage-max-microvolt: maximum constant input voltage.
|
||||
See Documentation/devicetree/bindings/power/supply/battery.yaml
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/rtc/amlogic,meson6-rtc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic Meson6, Meson8, Meson8b and Meson8m2 RTC
|
||||
|
||||
maintainers:
|
||||
- Neil Armstrong <neil.armstrong@linaro.org>
|
||||
- Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: rtc.yaml#
|
||||
- $ref: /schemas/nvmem/nvmem.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- amlogic,meson6-rtc
|
||||
- amlogic,meson8-rtc
|
||||
- amlogic,meson8b-rtc
|
||||
- amlogic,meson8m2-rtc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
vdd-supply: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
rtc: rtc@740 {
|
||||
compatible = "amlogic,meson6-rtc";
|
||||
reg = <0x740 0x14>;
|
||||
interrupts = <GIC_SPI 72 IRQ_TYPE_EDGE_RISING>;
|
||||
clocks = <&rtc32k_xtal>;
|
||||
vdd-supply = <&rtc_vdd>;
|
||||
resets = <&reset_rtc>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
mac@0 {
|
||||
reg = <0 6>;
|
||||
};
|
||||
};
|
|
@ -1,30 +0,0 @@
|
|||
Haoyu Microelectronics HYM8563 Real Time Clock
|
||||
|
||||
The HYM8563 provides basic rtc and alarm functionality
|
||||
as well as a clock output of up to 32kHz.
|
||||
|
||||
Required properties:
|
||||
- compatible: should be: "haoyu,hym8563"
|
||||
- reg: i2c address
|
||||
- #clock-cells: the value should be 0
|
||||
|
||||
Optional properties:
|
||||
- clock-output-names: From common clock binding
|
||||
- interrupts: rtc alarm/event interrupt
|
||||
|
||||
Example:
|
||||
|
||||
hym8563: hym8563@51 {
|
||||
compatible = "haoyu,hym8563";
|
||||
reg = <0x51>;
|
||||
|
||||
interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
|
||||
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
device {
|
||||
...
|
||||
clocks = <&hym8563>;
|
||||
...
|
||||
};
|
|
@ -0,0 +1,56 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/rtc/haoyu,hym8563.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Haoyu Microelectronics HYM8563 RTC
|
||||
|
||||
maintainers:
|
||||
- Alexandre Belloni <alexandre.belloni@bootlin.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: haoyu,hym8563
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
clock-output-names:
|
||||
description: From common clock binding to override the default output clock name.
|
||||
maxItems: 1
|
||||
|
||||
wakeup-source:
|
||||
description: Enables wake up of host system on alarm.
|
||||
|
||||
allOf:
|
||||
- $ref: rtc.yaml
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#clock-cells"
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
rtc@51 {
|
||||
compatible = "haoyu,hym8563";
|
||||
reg = <0x51>;
|
||||
interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
};
|
|
@ -11,12 +11,16 @@ maintainers:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,pm8058-rtc
|
||||
- qcom,pm8921-rtc
|
||||
- qcom,pm8941-rtc
|
||||
- qcom,pm8018-rtc
|
||||
- qcom,pmk8350-rtc
|
||||
oneOf:
|
||||
- enum:
|
||||
- qcom,pm8058-rtc
|
||||
- qcom,pm8921-rtc
|
||||
- qcom,pm8941-rtc
|
||||
- qcom,pmk8350-rtc
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,pm8018-rtc
|
||||
- const: qcom,pm8921-rtc
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
ST M41T80 family of RTC and compatible
|
||||
|
||||
Required properties:
|
||||
- compatible: should be one of:
|
||||
"st,m41t62",
|
||||
"st,m41t65",
|
||||
"st,m41t80",
|
||||
"st,m41t81",
|
||||
"st,m41t81s",
|
||||
"st,m41t82",
|
||||
"st,m41t83",
|
||||
"st,m41t84",
|
||||
"st,m41t85",
|
||||
"st,m41t87",
|
||||
"microcrystal,rv4162",
|
||||
- reg: I2C bus address of the device
|
||||
|
||||
Optional properties:
|
||||
- interrupts: rtc alarm interrupt.
|
||||
- clock-output-names: From common clock binding to override the default output
|
||||
clock name
|
||||
- wakeup-source: Enables wake up of host system on alarm
|
||||
|
||||
Optional child node:
|
||||
- clock: Provide this if the square wave pin is used as boot-enabled fixed clock.
|
||||
|
||||
Example:
|
||||
rtc@68 {
|
||||
compatible = "st,m41t80";
|
||||
reg = <0x68>;
|
||||
interrupt-parent = <&UIC0>;
|
||||
interrupts = <0x9 0x8>;
|
||||
|
||||
clock {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <32768>;
|
||||
};
|
||||
};
|
|
@ -1,35 +0,0 @@
|
|||
* Amlogic Meson6, Meson8, Meson8b and Meson8m2 RTC
|
||||
|
||||
Required properties:
|
||||
- compatible: should be one of the following describing the hardware:
|
||||
* "amlogic,meson6-rtc"
|
||||
* "amlogic,meson8-rtc"
|
||||
* "amlogic,meson8b-rtc"
|
||||
* "amlogic,meson8m2-rtc"
|
||||
|
||||
- reg: physical register space for the controller's memory mapped registers.
|
||||
- interrupts: the interrupt line of the RTC block.
|
||||
- clocks: reference to the external 32.768kHz crystal oscillator.
|
||||
- vdd-supply: reference to the power supply of the RTC block.
|
||||
- resets: reset controller reference to allow reset of the controller
|
||||
|
||||
Optional properties for the battery-backed non-volatile memory:
|
||||
- #address-cells: should be 1 to address the battery-backed non-volatile memory
|
||||
- #size-cells: should be 1 to reference the battery-backed non-volatile memory
|
||||
|
||||
Optional child nodes:
|
||||
- see ../nvmem/nvmem.txt
|
||||
|
||||
Example:
|
||||
|
||||
rtc: rtc@740 {
|
||||
compatible = "amlogic,meson6-rtc";
|
||||
reg = <0x740 0x14>;
|
||||
interrupts = <GIC_SPI 72 IRQ_TYPE_EDGE_RISING>;
|
||||
clocks = <&rtc32k_xtal>;
|
||||
vdd-supply = <&rtc_vdd>;
|
||||
resets = <&reset RESET_RTC>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
};
|
|
@ -0,0 +1,73 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/rtc/st,m41t80.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ST M41T80 family of RTC and compatible
|
||||
|
||||
maintainers:
|
||||
- Alexandre Belloni <alexandre.belloni@bootlin.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- st,m41t62
|
||||
- st,m41t65
|
||||
- st,m41t80
|
||||
- st,m41t81
|
||||
- st,m41t81s
|
||||
- st,m41t82
|
||||
- st,m41t83
|
||||
- st,m41t84
|
||||
- st,m41t85
|
||||
- st,m41t87
|
||||
- microcrystal,rv4162
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
description: From common clock binding to override the default output clock name.
|
||||
|
||||
clock:
|
||||
type: object
|
||||
$ref: /schemas/clock/fixed-clock.yaml#
|
||||
properties:
|
||||
clock-frequency:
|
||||
const: 32768
|
||||
|
||||
allOf:
|
||||
- $ref: rtc.yaml
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
rtc@68 {
|
||||
compatible = "st,m41t80";
|
||||
reg = <0x68>;
|
||||
interrupt-parent = <&UIC0>;
|
||||
interrupts = <0x9 0x8>;
|
||||
|
||||
clock {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <32768>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -1,214 +0,0 @@
|
|||
Qualcomm SoundWire Controller Bindings
|
||||
|
||||
|
||||
This binding describes the Qualcomm SoundWire Controller along with its
|
||||
board specific bus parameters.
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: must be "qcom,soundwire-v<MAJOR>.<MINOR>.<STEP>",
|
||||
Example:
|
||||
"qcom,soundwire-v1.3.0"
|
||||
"qcom,soundwire-v1.5.0"
|
||||
"qcom,soundwire-v1.5.1"
|
||||
"qcom,soundwire-v1.6.0"
|
||||
- reg:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: the base address and size of SoundWire controller
|
||||
address space.
|
||||
|
||||
- interrupts:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should specify the SoundWire Controller core and optional
|
||||
wake IRQ
|
||||
|
||||
- interrupt-names:
|
||||
Usage: Optional
|
||||
Value type: boolean
|
||||
Value type: <stringlist>
|
||||
Definition: should be "core" for core and "wakeup" for wake interrupt.
|
||||
|
||||
- wakeup-source:
|
||||
Usage: Optional
|
||||
Value type: boolean
|
||||
Definition: should specify if SoundWire Controller is wake up capable.
|
||||
|
||||
- clock-names:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: should be "iface" for SoundWire Controller interface clock
|
||||
|
||||
- clocks:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should specify the SoundWire Controller interface clock
|
||||
|
||||
- #sound-dai-cells:
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: must be 1 for digital audio interfaces on the controller.
|
||||
|
||||
- qcom,dout-ports:
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: must be count of data out ports
|
||||
|
||||
- qcom,din-ports:
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: must be count of data in ports
|
||||
|
||||
- qcom,ports-offset1:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should specify payload transport window offset1 of each
|
||||
data port. Out ports followed by In ports.
|
||||
Value of 0xFF indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
|
||||
- qcom,ports-offset2:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should specify payload transport window offset2 of each
|
||||
data port. Out ports followed by In ports.
|
||||
Value of 0xFF indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
|
||||
- qcom,ports-sinterval-low:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should be sample interval low of each data port.
|
||||
Out ports followed by In ports. Used for Sample Interval
|
||||
calculation.
|
||||
Value of 0xFF indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
|
||||
- qcom,ports-word-length:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should be size of payload channel sample.
|
||||
Value of 0xFF indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
|
||||
- qcom,ports-block-pack-mode:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should be 0 or 1 to indicate the block packing mode.
|
||||
0 to indicate Blocks are per Channel
|
||||
1 to indicate Blocks are per Port.
|
||||
Out ports followed by In ports.
|
||||
Value of 0xFF indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
|
||||
- qcom,ports-block-group-count:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should be in range 1 to 4 to indicate how many sample
|
||||
intervals are combined into a payload.
|
||||
Out ports followed by In ports.
|
||||
Value of 0xFF indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
|
||||
- qcom,ports-lane-control:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should be in range 0 to 7 to identify which data lane
|
||||
the data port uses.
|
||||
Out ports followed by In ports.
|
||||
Value of 0xFF indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
|
||||
- qcom,ports-hstart:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should be number identifying lowerst numbered coloum in
|
||||
SoundWire Frame, i.e. left edge of the Transport sub-frame
|
||||
for each port. Values between 0 and 15 are valid.
|
||||
Out ports followed by In ports.
|
||||
Value of 0xFF indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
|
||||
- qcom,ports-hstop:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should be number identifying highest numbered coloum in
|
||||
SoundWire Frame, i.e. the right edge of the Transport
|
||||
sub-frame for each port. Values between 0 and 15 are valid.
|
||||
Out ports followed by In ports.
|
||||
Value of 0xFF indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
|
||||
- qcom,dports-type:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should be one of the following types
|
||||
0 for reduced port
|
||||
1 for simple ports
|
||||
2 for full port
|
||||
Out ports followed by In ports.
|
||||
Value of 0xFF indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
|
||||
- reset:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Should specify the SoundWire audio CSR reset controller interface,
|
||||
which is required for SoundWire version 1.6.0 and above.
|
||||
|
||||
- reset-names:
|
||||
Usage: optional
|
||||
Value type: <stringlist>
|
||||
Definition: should be "swr_audio_cgcr" for SoundWire audio CSR reset
|
||||
controller interface.
|
||||
|
||||
Note:
|
||||
More Information on detail of encoding of these fields can be
|
||||
found in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
|
||||
= SoundWire devices
|
||||
Each subnode of the bus represents SoundWire device attached to it.
|
||||
The properties of these nodes are defined by the individual bindings.
|
||||
|
||||
= EXAMPLE
|
||||
The following example represents a SoundWire controller on DB845c board
|
||||
which has controller integrated inside WCD934x codec on SDM845 SoC.
|
||||
|
||||
soundwire: soundwire@c85 {
|
||||
compatible = "qcom,soundwire-v1.3.0";
|
||||
reg = <0xc85 0x20>;
|
||||
interrupts = <20 IRQ_TYPE_EDGE_RISING>;
|
||||
clocks = <&wcc>;
|
||||
clock-names = "iface";
|
||||
resets = <&lpass_audiocc LPASS_AUDIO_SWR_TX_CGCR>;
|
||||
reset-names = "swr_audio_cgcr";
|
||||
#sound-dai-cells = <1>;
|
||||
qcom,dports-type = <0>;
|
||||
qcom,dout-ports = <6>;
|
||||
qcom,din-ports = <2>;
|
||||
qcom,ports-sinterval-low = /bits/ 8 <0x07 0x1F 0x3F 0x7 0x1F 0x3F 0x0F 0x0F>;
|
||||
qcom,ports-offset1 = /bits/ 8 <0x01 0x02 0x0C 0x6 0x12 0x0D 0x07 0x0A >;
|
||||
qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x1F 0x00 0x00 0x1F 0x00 0x00>;
|
||||
|
||||
/* Left Speaker */
|
||||
left{
|
||||
....
|
||||
};
|
||||
|
||||
/* Right Speaker */
|
||||
right{
|
||||
....
|
||||
};
|
||||
};
|
|
@ -0,0 +1,270 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/soundwire/qcom,soundwire.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SoundWire Controller
|
||||
|
||||
maintainers:
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
- Srinivasa Rao Mandadapu <quic_srivasam@quicinc.com>
|
||||
|
||||
description:
|
||||
The Qualcomm SoundWire controller along with its board specific bus parameters.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,soundwire-v1.3.0
|
||||
- qcom,soundwire-v1.5.0
|
||||
- qcom,soundwire-v1.5.1
|
||||
- qcom,soundwire-v1.6.0
|
||||
- qcom,soundwire-v1.7.0
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: specify the SoundWire controller core.
|
||||
- description: specify the Soundwire controller wake IRQ.
|
||||
|
||||
interrupt-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: core
|
||||
- const: wakeup
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: iface clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: SWR_AUDIO_CGCR RESET
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: swr_audio_cgcr
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 1
|
||||
|
||||
'#address-cells':
|
||||
const: 2
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
wakeup-source: true
|
||||
|
||||
qcom,din-ports:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: count of data in ports
|
||||
|
||||
qcom,dout-ports:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: count of data out ports
|
||||
|
||||
qcom,ports-word-length:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description:
|
||||
Size of payload channel sample.
|
||||
Value of 0xff indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
minItems: 3
|
||||
maxItems: 5
|
||||
|
||||
qcom,ports-sinterval-low:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description:
|
||||
Sample interval low of each data port.
|
||||
Out ports followed by In ports. Used for Sample Interval calculation.
|
||||
Value of 0xff indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
minItems: 3
|
||||
maxItems: 8
|
||||
|
||||
qcom,ports-offset1:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description:
|
||||
Payload transport window offset1 of each data port.
|
||||
Out ports followed by In ports.
|
||||
Value of 0xff indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
minItems: 3
|
||||
maxItems: 8
|
||||
|
||||
qcom,ports-offset2:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description:
|
||||
Payload transport window offset2 of each data port.
|
||||
Out ports followed by In ports.
|
||||
Value of 0xff indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
minItems: 3
|
||||
maxItems: 8
|
||||
|
||||
qcom,ports-lane-control:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description:
|
||||
Identify which data lane the data port uses.
|
||||
Out ports followed by In ports.
|
||||
Value of 0xff indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
minItems: 3
|
||||
maxItems: 5
|
||||
|
||||
qcom,ports-block-pack-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description:
|
||||
Indicate the block packing mode.
|
||||
0 to indicate Blocks are per Channel
|
||||
1 to indicate Blocks are per Port.
|
||||
Out ports followed by In ports.
|
||||
Value of 0xff indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
minItems: 3
|
||||
maxItems: 8
|
||||
items:
|
||||
oneOf:
|
||||
- minimum: 0
|
||||
maximum: 1
|
||||
- const: 0xff
|
||||
|
||||
qcom,ports-hstart:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description:
|
||||
Identifying lowerst numbered coloum in SoundWire Frame,
|
||||
i.e. left edge of the Transport sub-frame for each port.
|
||||
Out ports followed by In ports.
|
||||
Value of 0xff indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
minItems: 3
|
||||
maxItems: 5
|
||||
items:
|
||||
oneOf:
|
||||
- minimum: 0
|
||||
maximum: 15
|
||||
- const: 0xff
|
||||
|
||||
qcom,ports-hstop:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description:
|
||||
Identifying highest numbered coloum in SoundWire Frame,
|
||||
i.e. the right edge of the Transport
|
||||
sub-frame for each port. Out ports followed by In ports.
|
||||
Value of 0xff indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
minItems: 3
|
||||
maxItems: 5
|
||||
items:
|
||||
oneOf:
|
||||
- minimum: 0
|
||||
maximum: 15
|
||||
- const: 0xff
|
||||
|
||||
qcom,ports-block-group-count:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description:
|
||||
In range 1 to 4 to indicate how many sample intervals are combined
|
||||
into a payload. Out ports followed by In ports.
|
||||
Value of 0xff indicates that this option is not implemented
|
||||
or applicable for the respective data port.
|
||||
More info in MIPI Alliance SoundWire 1.0 Specifications.
|
||||
minItems: 3
|
||||
maxItems: 5
|
||||
items:
|
||||
oneOf:
|
||||
- minimum: 0
|
||||
maximum: 4
|
||||
- const: 0xff
|
||||
|
||||
label:
|
||||
maxItems: 1
|
||||
|
||||
patternProperties:
|
||||
"^.*@[0-9a-f],[0-9a-f]$":
|
||||
type: object
|
||||
description:
|
||||
Child nodes for a standalone audio codec or speaker amplifier IC.
|
||||
It has RX and TX Soundwire secondary devices.
|
||||
properties:
|
||||
compatible:
|
||||
pattern: "^sdw[0-9a-f]{1}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{2}$"
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#sound-dai-cells'
|
||||
- '#address-cells'
|
||||
- '#size-cells'
|
||||
- qcom,dout-ports
|
||||
- qcom,din-ports
|
||||
- qcom,ports-sinterval-low
|
||||
- qcom,ports-offset1
|
||||
- qcom,ports-offset2
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/clock/qcom,lpassaudiocc-sc7280.h>
|
||||
|
||||
soundwire@3210000 {
|
||||
compatible = "qcom,soundwire-v1.6.0";
|
||||
reg = <0x03210000 0x2000>;
|
||||
|
||||
interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<&pdc 130 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
interrupt-names = "core", "wakeup";
|
||||
|
||||
clocks = <&lpass_rx_macro>;
|
||||
clock-names = "iface";
|
||||
|
||||
qcom,din-ports = <0>;
|
||||
qcom,dout-ports = <5>;
|
||||
|
||||
resets = <&lpass_audiocc LPASS_AUDIO_SWR_RX_CGCR>;
|
||||
reset-names = "swr_audio_cgcr";
|
||||
|
||||
qcom,ports-word-length = /bits/ 8 <0x01 0x07 0x04 0xff 0xff>;
|
||||
qcom,ports-sinterval-low = /bits/ 8 <0x03 0x3f 0x1f 0x03 0x03>;
|
||||
qcom,ports-offset1 = /bits/ 8 <0x00 0x00 0x0b 0x01 0x01>;
|
||||
qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x0b 0x00 0x00>;
|
||||
qcom,ports-lane-control = /bits/ 8 <0x01 0x00 0x00 0x00 0x00>;
|
||||
qcom,ports-block-pack-mode = /bits/ 8 <0xff 0x00 0x01 0xff 0xff>;
|
||||
qcom,ports-hstart = /bits/ 8 <0xff 0x03 0xff 0xff 0xff>;
|
||||
qcom,ports-hstop = /bits/ 8 <0xff 0x06 0xff 0xff 0xff>;
|
||||
qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0x00>;
|
||||
|
||||
#sound-dai-cells = <1>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
codec@0,4 {
|
||||
compatible = "sdw20217010d00";
|
||||
reg = <0 4>;
|
||||
qcom,rx-port-mapping = <1 2 3 4 5>;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,80 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/watchdog/mediatek,mtk-wdt.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek SoCs Watchdog timer
|
||||
|
||||
maintainers:
|
||||
- Matthias Brugger <matthias.bgg@gmail.com>
|
||||
|
||||
description:
|
||||
The watchdog supports a pre-timeout interrupt that fires
|
||||
timeout-sec/2 before the expiry.
|
||||
|
||||
allOf:
|
||||
- $ref: watchdog.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- mediatek,mt2712-wdt
|
||||
- mediatek,mt6589-wdt
|
||||
- mediatek,mt6795-wdt
|
||||
- mediatek,mt7986-wdt
|
||||
- mediatek,mt8183-wdt
|
||||
- mediatek,mt8186-wdt
|
||||
- mediatek,mt8188-wdt
|
||||
- mediatek,mt8192-wdt
|
||||
- mediatek,mt8195-wdt
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt2701-wdt
|
||||
- mediatek,mt6582-wdt
|
||||
- mediatek,mt6797-wdt
|
||||
- mediatek,mt7622-wdt
|
||||
- mediatek,mt7623-wdt
|
||||
- mediatek,mt7629-wdt
|
||||
- mediatek,mt8173-wdt
|
||||
- mediatek,mt8516-wdt
|
||||
- const: mediatek,mt6589-wdt
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: Watchdog pre-timeout (bark) interrupt
|
||||
|
||||
mediatek,disable-extrst:
|
||||
description: Disable sending output reset signal
|
||||
type: boolean
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
watchdog: watchdog@10007000 {
|
||||
compatible = "mediatek,mt8183-wdt";
|
||||
reg = <0 0x10007000 0 0x100>;
|
||||
interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_LOW>;
|
||||
mediatek,disable-extrst;
|
||||
timeout-sec = <10>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
};
|
|
@ -1,42 +0,0 @@
|
|||
Mediatek SoCs Watchdog timer
|
||||
|
||||
The watchdog supports a pre-timeout interrupt that fires timeout-sec/2
|
||||
before the expiry.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible should contain:
|
||||
"mediatek,mt2701-wdt", "mediatek,mt6589-wdt": for MT2701
|
||||
"mediatek,mt2712-wdt": for MT2712
|
||||
"mediatek,mt6582-wdt", "mediatek,mt6589-wdt": for MT6582
|
||||
"mediatek,mt6589-wdt": for MT6589
|
||||
"mediatek,mt6797-wdt", "mediatek,mt6589-wdt": for MT6797
|
||||
"mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622
|
||||
"mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623
|
||||
"mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629
|
||||
"mediatek,mt7986-wdt", "mediatek,mt6589-wdt": for MT7986
|
||||
"mediatek,mt8183-wdt": for MT8183
|
||||
"mediatek,mt8186-wdt", "mediatek,mt6589-wdt": for MT8186
|
||||
"mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516
|
||||
"mediatek,mt8192-wdt": for MT8192
|
||||
"mediatek,mt8195-wdt", "mediatek,mt6589-wdt": for MT8195
|
||||
|
||||
- reg : Specifies base physical address and size of the registers.
|
||||
|
||||
Optional properties:
|
||||
- mediatek,disable-extrst: disable send output reset signal
|
||||
- interrupts: Watchdog pre-timeout (bark) interrupt.
|
||||
- timeout-sec: contains the watchdog timeout in seconds.
|
||||
- #reset-cells: Should be 1.
|
||||
|
||||
Example:
|
||||
|
||||
watchdog: watchdog@10007000 {
|
||||
compatible = "mediatek,mt8183-wdt",
|
||||
"mediatek,mt6589-wdt";
|
||||
mediatek,disable-extrst;
|
||||
reg = <0 0x10007000 0 0x100>;
|
||||
interrupts = <GIC_SPI 139 IRQ_TYPE_NONE>;
|
||||
timeout-sec = <10>;
|
||||
#reset-cells = <1>;
|
||||
};
|
|
@ -450,6 +450,7 @@ SERDEV
|
|||
|
||||
SLAVE DMA ENGINE
|
||||
devm_acpi_dma_controller_register()
|
||||
devm_acpi_dma_controller_free()
|
||||
|
||||
SPI
|
||||
devm_spi_alloc_master()
|
||||
|
|
|
@ -94,7 +94,8 @@ Inorder to dereference the private data (in phy_ops), the phy provider driver
|
|||
can use phy_set_drvdata() after creating the PHY and use phy_get_drvdata() in
|
||||
phy_ops to get back the private data.
|
||||
|
||||
4. Getting a reference to the PHY
|
||||
Getting a reference to the PHY
|
||||
==============================
|
||||
|
||||
Before the controller can make use of the PHY, it has to get a reference to
|
||||
it. This framework provides the following APIs to get a reference to the PHY.
|
||||
|
@ -130,6 +131,28 @@ the phy_init() and phy_exit() calls, and phy_power_on() and
|
|||
phy_power_off() calls are all NOP when applied to a NULL phy. The NULL
|
||||
phy is useful in devices for handling optional phy devices.
|
||||
|
||||
Order of API calls
|
||||
==================
|
||||
|
||||
The general order of calls should be::
|
||||
|
||||
[devm_][of_]phy_get()
|
||||
phy_init()
|
||||
phy_power_on()
|
||||
[phy_set_mode[_ext]()]
|
||||
...
|
||||
phy_power_off()
|
||||
phy_exit()
|
||||
[[of_]phy_put()]
|
||||
|
||||
Some PHY drivers may not implement :c:func:`phy_init` or :c:func:`phy_power_on`,
|
||||
but controllers should always call these functions to be compatible with other
|
||||
PHYs. Some PHYs may require :c:func:`phy_set_mode <phy_set_mode_ext>`, while
|
||||
others may use a default mode (typically configured via devicetree or other
|
||||
firmware). For compatibility, you should always call this function if you know
|
||||
what mode you will be using. Generally, this function should be called after
|
||||
:c:func:`phy_power_on`, although some PHY drivers may allow it at any time.
|
||||
|
||||
Releasing a reference to the PHY
|
||||
================================
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ Book3S (aka sPAPR)
|
|||
------------------
|
||||
|
||||
- Hash MMU (except 603 and e300)
|
||||
- Radix MMU (POWER9 and later)
|
||||
- Software loaded TLB (603 and e300)
|
||||
- Selectable Software loaded TLB in addition to hash MMU (755, 7450, e600)
|
||||
- Mix of 32 & 64 bit::
|
||||
|
@ -100,6 +101,18 @@ Book3S (aka sPAPR)
|
|||
v
|
||||
+--------------+
|
||||
| POWER8 |
|
||||
+--------------+
|
||||
|
|
||||
|
|
||||
v
|
||||
+--------------+
|
||||
| POWER9 |
|
||||
+--------------+
|
||||
|
|
||||
|
|
||||
v
|
||||
+--------------+
|
||||
| POWER10 |
|
||||
+--------------+
|
||||
|
||||
|
||||
|
|
14
MAINTAINERS
14
MAINTAINERS
|
@ -10460,11 +10460,6 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
|
|||
F: drivers/iommu/intel/
|
||||
F: include/linux/intel-svm.h
|
||||
|
||||
INTEL IOP-ADMA DMA DRIVER
|
||||
R: Dan Williams <dan.j.williams@intel.com>
|
||||
S: Odd fixes
|
||||
F: drivers/dma/iop-adma.c
|
||||
|
||||
INTEL IPU3 CSI-2 CIO2 DRIVER
|
||||
M: Yong Zhi <yong.zhi@intel.com>
|
||||
M: Sakari Ailus <sakari.ailus@linux.intel.com>
|
||||
|
@ -11732,11 +11727,13 @@ F: scripts/leaking_addresses.pl
|
|||
|
||||
LED SUBSYSTEM
|
||||
M: Pavel Machek <pavel@ucw.cz>
|
||||
M: Lee Jones <lee@kernel.org>
|
||||
L: linux-leds@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds.git
|
||||
F: Documentation/devicetree/bindings/leds/
|
||||
F: drivers/leds/
|
||||
F: include/dt-bindings/leds/
|
||||
F: include/linux/leds.h
|
||||
|
||||
LEGACY EEPROM DRIVER
|
||||
|
@ -13627,7 +13624,6 @@ L: dmaengine@vger.kernel.org
|
|||
S: Supported
|
||||
F: Documentation/devicetree/bindings/dma/atmel-dma.txt
|
||||
F: drivers/dma/at_hdmac.c
|
||||
F: drivers/dma/at_hdmac_regs.h
|
||||
F: drivers/dma/at_xdmac.c
|
||||
F: include/dt-bindings/dma/at91.h
|
||||
|
||||
|
@ -23053,8 +23049,7 @@ F: drivers/media/pci/zoran/
|
|||
|
||||
ZRAM COMPRESSED RAM BLOCK DEVICE DRVIER
|
||||
M: Minchan Kim <minchan@kernel.org>
|
||||
M: Nitin Gupta <ngupta@vflare.org>
|
||||
R: Sergey Senozhatsky <senozhatsky@chromium.org>
|
||||
M: Sergey Senozhatsky <senozhatsky@chromium.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/admin-guide/blockdev/zram.rst
|
||||
|
@ -23067,8 +23062,7 @@ F: drivers/tty/serial/zs.*
|
|||
|
||||
ZSMALLOC COMPRESSED SLAB MEMORY ALLOCATOR
|
||||
M: Minchan Kim <minchan@kernel.org>
|
||||
M: Nitin Gupta <ngupta@vflare.org>
|
||||
R: Sergey Senozhatsky <senozhatsky@chromium.org>
|
||||
M: Sergey Senozhatsky <senozhatsky@chromium.org>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
F: Documentation/mm/zsmalloc.rst
|
||||
|
|
4
Makefile
4
Makefile
|
@ -933,7 +933,9 @@ ifdef CONFIG_FTRACE_MCOUNT_USE_CC
|
|||
endif
|
||||
endif
|
||||
ifdef CONFIG_FTRACE_MCOUNT_USE_OBJTOOL
|
||||
CC_FLAGS_USING += -DCC_USING_NOP_MCOUNT
|
||||
ifdef CONFIG_HAVE_OBJTOOL_NOP_MCOUNT
|
||||
CC_FLAGS_USING += -DCC_USING_NOP_MCOUNT
|
||||
endif
|
||||
endif
|
||||
ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
|
||||
ifdef CONFIG_HAVE_C_RECORDMCOUNT
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/set_memory.h>
|
||||
|
||||
#include <asm/fncpy.h>
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/set_memory.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
|
@ -74,8 +74,7 @@ void *omap_sram_push(void *funcp, unsigned long size)
|
|||
|
||||
dst = fncpy(sram, funcp, size);
|
||||
|
||||
set_memory_ro(base, pages);
|
||||
set_memory_x(base, pages);
|
||||
set_memory_rox(base, pages);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
@ -126,8 +125,7 @@ static void __init omap_detect_and_map_sram(void)
|
|||
base = (unsigned long)omap_sram_base;
|
||||
pages = PAGE_ALIGN(omap_sram_size) / PAGE_SIZE;
|
||||
|
||||
set_memory_ro(base, pages);
|
||||
set_memory_x(base, pages);
|
||||
set_memory_rox(base, pages);
|
||||
}
|
||||
|
||||
static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl);
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/set_memory.h>
|
||||
|
||||
#include <asm/fncpy.h>
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/set_memory.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
|
@ -96,8 +96,7 @@ void *omap_sram_push(void *funcp, unsigned long size)
|
|||
|
||||
dst = fncpy(sram, funcp, size);
|
||||
|
||||
set_memory_ro(base, pages);
|
||||
set_memory_x(base, pages);
|
||||
set_memory_rox(base, pages);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
@ -217,8 +216,7 @@ static void __init omap2_map_sram(void)
|
|||
base = (unsigned long)omap_sram_base;
|
||||
pages = PAGE_ALIGN(omap_sram_size) / PAGE_SIZE;
|
||||
|
||||
set_memory_ro(base, pages);
|
||||
set_memory_x(base, pages);
|
||||
set_memory_rox(base, pages);
|
||||
}
|
||||
|
||||
static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
|
||||
|
|
|
@ -9,6 +9,7 @@ config CSKY
|
|||
select ARCH_USE_BUILTIN_BSWAP
|
||||
select ARCH_USE_QUEUED_RWLOCKS
|
||||
select ARCH_USE_QUEUED_SPINLOCKS
|
||||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_INLINE_READ_LOCK if !PREEMPTION
|
||||
select ARCH_INLINE_READ_LOCK_BH if !PREEMPTION
|
||||
select ARCH_INLINE_READ_LOCK_IRQ if !PREEMPTION
|
||||
|
@ -93,7 +94,6 @@ config CSKY
|
|||
select HAVE_PERF_USER_STACK_DUMP
|
||||
select HAVE_DMA_CONTIGUOUS
|
||||
select HAVE_REGS_AND_STACK_ACCESS_API
|
||||
select HAVE_RSEQ
|
||||
select HAVE_STACKPROTECTOR
|
||||
select HAVE_SYSCALL_TRACEPOINTS
|
||||
select MAY_HAVE_SPARSE_IRQ
|
||||
|
@ -269,7 +269,7 @@ menuconfig HAVE_TCM
|
|||
bool "Tightly-Coupled/Sram Memory"
|
||||
depends on !COMPILE_TEST
|
||||
help
|
||||
The implementation are not only used by TCM (Tightly-Coupled Meory)
|
||||
The implementation are not only used by TCM (Tightly-Coupled Memory)
|
||||
but also used by sram on SOC bus. It follow existed linux tcm
|
||||
software interface, so that old tcm application codes could be
|
||||
re-used directly.
|
||||
|
|
|
@ -84,4 +84,6 @@ unsigned long __get_wchan(struct task_struct *p);
|
|||
|
||||
#define cpu_relax() barrier()
|
||||
|
||||
register unsigned long current_stack_pointer __asm__("sp");
|
||||
|
||||
#endif /* __ASM_CSKY_PROCESSOR_H */
|
||||
|
|
|
@ -54,7 +54,7 @@ ENTRY(csky_systemcall)
|
|||
|
||||
lrw r9, __NR_syscalls
|
||||
cmphs syscallid, r9 /* Check nr of syscall */
|
||||
bt 1f
|
||||
bt ret_from_exception
|
||||
|
||||
lrw r9, sys_call_table
|
||||
ixw r9, syscallid
|
||||
|
@ -80,11 +80,6 @@ ENTRY(csky_systemcall)
|
|||
jsr syscallid
|
||||
#endif
|
||||
stw a0, (sp, LSAVE_A0) /* Save return value */
|
||||
1:
|
||||
#ifdef CONFIG_DEBUG_RSEQ
|
||||
mov a0, sp
|
||||
jbsr rseq_syscall
|
||||
#endif
|
||||
jmpi ret_from_exception
|
||||
|
||||
csky_syscall_trace:
|
||||
|
@ -113,10 +108,6 @@ csky_syscall_trace:
|
|||
stw a0, (sp, LSAVE_A0) /* Save return value */
|
||||
|
||||
1:
|
||||
#ifdef CONFIG_DEBUG_RSEQ
|
||||
mov a0, sp
|
||||
jbsr rseq_syscall
|
||||
#endif
|
||||
mov a0, sp /* right now, sp --> pt_regs */
|
||||
jbsr syscall_trace_exit
|
||||
br ret_from_exception
|
||||
|
|
|
@ -179,8 +179,6 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
|
|||
sigset_t *oldset = sigmask_to_save();
|
||||
int ret;
|
||||
|
||||
rseq_signal_deliver(ksig, regs);
|
||||
|
||||
/* Are we from a system call? */
|
||||
if (in_syscall(regs)) {
|
||||
/* Avoid additional syscall restarting via ret_from_exception */
|
||||
|
|
|
@ -23,10 +23,9 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
|
|||
sp = user_stack_pointer(regs);
|
||||
pc = instruction_pointer(regs);
|
||||
} else if (task == NULL || task == current) {
|
||||
const register unsigned long current_sp __asm__ ("sp");
|
||||
const register unsigned long current_fp __asm__ ("r8");
|
||||
fp = current_fp;
|
||||
sp = current_sp;
|
||||
sp = current_stack_pointer;
|
||||
pc = (unsigned long)walk_stackframe;
|
||||
} else {
|
||||
/* task blocked in __switch_to */
|
||||
|
@ -68,8 +67,7 @@ static void notrace walk_stackframe(struct task_struct *task,
|
|||
sp = user_stack_pointer(regs);
|
||||
pc = instruction_pointer(regs);
|
||||
} else if (task == NULL || task == current) {
|
||||
const register unsigned long current_sp __asm__ ("sp");
|
||||
sp = current_sp;
|
||||
sp = current_stack_pointer;
|
||||
pc = (unsigned long)walk_stackframe;
|
||||
} else {
|
||||
/* task blocked in __switch_to */
|
||||
|
|
|
@ -58,6 +58,7 @@ config LOONGARCH
|
|||
select ARCH_WANTS_NO_INSTR
|
||||
select BUILDTIME_TABLE_SORT
|
||||
select COMMON_CLK
|
||||
select CPU_PM
|
||||
select EFI
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_CMOS_UPDATE
|
||||
|
@ -86,11 +87,18 @@ config LOONGARCH
|
|||
select HAVE_ARCH_TRANSPARENT_HUGEPAGE
|
||||
select HAVE_ASM_MODVERSIONS
|
||||
select HAVE_CONTEXT_TRACKING_USER
|
||||
select HAVE_C_RECORDMCOUNT
|
||||
select HAVE_DEBUG_STACKOVERFLOW
|
||||
select HAVE_DMA_CONTIGUOUS
|
||||
select HAVE_DYNAMIC_FTRACE
|
||||
select HAVE_DYNAMIC_FTRACE_WITH_ARGS
|
||||
select HAVE_DYNAMIC_FTRACE_WITH_REGS
|
||||
select HAVE_EBPF_JIT
|
||||
select HAVE_EXIT_THREAD
|
||||
select HAVE_FAST_GUP
|
||||
select HAVE_FTRACE_MCOUNT_RECORD
|
||||
select HAVE_FUNCTION_GRAPH_TRACER
|
||||
select HAVE_FUNCTION_TRACER
|
||||
select HAVE_GENERIC_VDSO
|
||||
select HAVE_IOREMAP_PROT
|
||||
select HAVE_IRQ_EXIT_ON_IRQ_STACK
|
||||
|
@ -104,6 +112,7 @@ config LOONGARCH
|
|||
select HAVE_REGS_AND_STACK_ACCESS_API
|
||||
select HAVE_RSEQ
|
||||
select HAVE_SETUP_PER_CPU_AREA if NUMA
|
||||
select HAVE_STACKPROTECTOR
|
||||
select HAVE_SYSCALL_TRACEPOINTS
|
||||
select HAVE_TIF_NOHZ
|
||||
select HAVE_VIRT_CPU_ACCOUNTING_GEN if !SMP
|
||||
|
@ -113,6 +122,8 @@ config LOONGARCH
|
|||
select MODULES_USE_ELF_RELA if MODULES
|
||||
select NEED_PER_CPU_EMBED_FIRST_CHUNK
|
||||
select NEED_PER_CPU_PAGE_FIRST_CHUNK
|
||||
select OF
|
||||
select OF_EARLY_FLATTREE
|
||||
select PCI
|
||||
select PCI_DOMAINS_GENERIC
|
||||
select PCI_ECAM if ACPI
|
||||
|
@ -123,6 +134,8 @@ config LOONGARCH
|
|||
select RTC_LIB
|
||||
select SMP
|
||||
select SPARSE_IRQ
|
||||
select SYSCTL_ARCH_UNALIGN_ALLOW
|
||||
select SYSCTL_ARCH_UNALIGN_NO_WARN
|
||||
select SYSCTL_EXCEPTION_TRACE
|
||||
select SWIOTLB
|
||||
select TRACE_IRQFLAGS_SUPPORT
|
||||
|
@ -516,6 +529,13 @@ config ARCH_MMAP_RND_BITS_MAX
|
|||
|
||||
menu "Power management options"
|
||||
|
||||
config ARCH_SUSPEND_POSSIBLE
|
||||
def_bool y
|
||||
|
||||
config ARCH_HIBERNATION_POSSIBLE
|
||||
def_bool y
|
||||
|
||||
source "kernel/power/Kconfig"
|
||||
source "drivers/acpi/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -25,6 +25,11 @@ endif
|
|||
32bit-emul = elf32loongarch
|
||||
64bit-emul = elf64loongarch
|
||||
|
||||
ifdef CONFIG_DYNAMIC_FTRACE
|
||||
KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY
|
||||
CC_FLAGS_FTRACE := -fpatchable-function-entry=2
|
||||
endif
|
||||
|
||||
ifdef CONFIG_64BIT
|
||||
tool-archpref = $(64bit-tool-archpref)
|
||||
UTS_MACHINE := loongarch64
|
||||
|
@ -104,6 +109,9 @@ endif
|
|||
libs-y += arch/loongarch/lib/
|
||||
libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
|
||||
|
||||
# suspend and hibernation support
|
||||
drivers-$(CONFIG_PM) += arch/loongarch/power/
|
||||
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
prepare: vdso_prepare
|
||||
vdso_prepare: prepare0
|
||||
|
|
|
@ -34,12 +34,13 @@ CONFIG_SYSFS_DEPRECATED=y
|
|||
CONFIG_RELAY=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_EXPERT=y
|
||||
CONFIG_USERFAULTFD=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_PERF_EVENTS=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_LOONGARCH=y
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_MACH_LOONGSON64=y
|
||||
CONFIG_PAGE_SIZE_16KB=y
|
||||
CONFIG_HZ_250=y
|
||||
CONFIG_DMI=y
|
||||
CONFIG_EFI=y
|
||||
CONFIG_SMP=y
|
||||
|
@ -47,14 +48,14 @@ CONFIG_HOTPLUG_CPU=y
|
|||
CONFIG_NR_CPUS=64
|
||||
CONFIG_NUMA=y
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_PAGE_SIZE_16KB=y
|
||||
CONFIG_HZ_250=y
|
||||
CONFIG_SUSPEND=y
|
||||
CONFIG_HIBERNATION=y
|
||||
CONFIG_ACPI=y
|
||||
CONFIG_ACPI_SPCR_TABLE=y
|
||||
CONFIG_ACPI_HOTPLUG_CPU=y
|
||||
CONFIG_ACPI_TAD=y
|
||||
CONFIG_ACPI_DOCK=y
|
||||
CONFIG_ACPI_IPMI=m
|
||||
CONFIG_ACPI_HOTPLUG_CPU=y
|
||||
CONFIG_ACPI_PCI_SLOT=y
|
||||
CONFIG_ACPI_HOTPLUG_MEMORY=y
|
||||
CONFIG_EFI_ZBOOT=y
|
||||
|
@ -73,17 +74,19 @@ CONFIG_UNIXWARE_DISKLABEL=y
|
|||
CONFIG_IOSCHED_BFQ=y
|
||||
CONFIG_BFQ_GROUP_IOSCHED=y
|
||||
CONFIG_BINFMT_MISC=m
|
||||
CONFIG_ZPOOL=y
|
||||
CONFIG_ZSWAP=y
|
||||
CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y
|
||||
CONFIG_ZBUD=y
|
||||
CONFIG_Z3FOLD=y
|
||||
CONFIG_ZSMALLOC=m
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_MEMORY_HOTPLUG=y
|
||||
CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=y
|
||||
CONFIG_MEMORY_HOTREMOVE=y
|
||||
CONFIG_KSM=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_ZSWAP=y
|
||||
CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y
|
||||
CONFIG_ZPOOL=y
|
||||
CONFIG_ZBUD=y
|
||||
CONFIG_Z3FOLD=y
|
||||
CONFIG_ZSMALLOC=m
|
||||
CONFIG_USERFAULTFD=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
|
@ -118,7 +121,6 @@ CONFIG_NETFILTER=y
|
|||
CONFIG_BRIDGE_NETFILTER=m
|
||||
CONFIG_NETFILTER_NETLINK_LOG=m
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_LOG_NETDEV=m
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
CONFIG_NF_CONNTRACK_NETBIOS_NS=m
|
||||
|
@ -416,6 +418,7 @@ CONFIG_SCSI_VIRTIO=m
|
|||
CONFIG_ATA=y
|
||||
CONFIG_SATA_AHCI=y
|
||||
CONFIG_SATA_AHCI_PLATFORM=y
|
||||
CONFIG_AHCI_DWC=y
|
||||
CONFIG_PATA_ATIIXP=y
|
||||
CONFIG_PATA_PCMCIA=m
|
||||
CONFIG_MD=y
|
||||
|
@ -469,13 +472,11 @@ CONFIG_VIRTIO_NET=m
|
|||
# CONFIG_NET_VENDOR_ARC is not set
|
||||
# CONFIG_NET_VENDOR_ATHEROS is not set
|
||||
CONFIG_BNX2=y
|
||||
# CONFIG_NET_VENDOR_BROCADE is not set
|
||||
# CONFIG_NET_VENDOR_CAVIUM is not set
|
||||
CONFIG_CHELSIO_T1=m
|
||||
CONFIG_CHELSIO_T1_1G=y
|
||||
CONFIG_CHELSIO_T3=m
|
||||
CONFIG_CHELSIO_T4=m
|
||||
# CONFIG_NET_VENDOR_CIRRUS is not set
|
||||
# CONFIG_NET_VENDOR_CISCO is not set
|
||||
# CONFIG_NET_VENDOR_DEC is not set
|
||||
# CONFIG_NET_VENDOR_DLINK is not set
|
||||
|
@ -496,6 +497,7 @@ CONFIG_IXGBE=y
|
|||
# CONFIG_NET_VENDOR_NVIDIA is not set
|
||||
# CONFIG_NET_VENDOR_OKI is not set
|
||||
# CONFIG_NET_VENDOR_QLOGIC is not set
|
||||
# CONFIG_NET_VENDOR_BROCADE is not set
|
||||
# CONFIG_NET_VENDOR_QUALCOMM is not set
|
||||
# CONFIG_NET_VENDOR_RDC is not set
|
||||
CONFIG_8139CP=m
|
||||
|
@ -505,9 +507,9 @@ CONFIG_R8169=y
|
|||
# CONFIG_NET_VENDOR_ROCKER is not set
|
||||
# CONFIG_NET_VENDOR_SAMSUNG is not set
|
||||
# CONFIG_NET_VENDOR_SEEQ is not set
|
||||
# CONFIG_NET_VENDOR_SOLARFLARE is not set
|
||||
# CONFIG_NET_VENDOR_SILAN is not set
|
||||
# CONFIG_NET_VENDOR_SIS is not set
|
||||
# CONFIG_NET_VENDOR_SOLARFLARE is not set
|
||||
# CONFIG_NET_VENDOR_SMSC is not set
|
||||
CONFIG_STMMAC_ETH=y
|
||||
# CONFIG_NET_VENDOR_SUN is not set
|
||||
|
@ -588,6 +590,7 @@ CONFIG_SERIAL_8250_EXTENDED=y
|
|||
CONFIG_SERIAL_8250_MANY_PORTS=y
|
||||
CONFIG_SERIAL_8250_SHARE_IRQ=y
|
||||
CONFIG_SERIAL_8250_RSA=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
CONFIG_SERIAL_NONSTANDARD=y
|
||||
CONFIG_PRINTER=m
|
||||
CONFIG_VIRTIO_CONSOLE=y
|
||||
|
@ -602,6 +605,11 @@ CONFIG_I2C_GPIO=y
|
|||
CONFIG_SPI=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_GPIO_LOONGSON=y
|
||||
CONFIG_POWER_RESET=y
|
||||
CONFIG_POWER_RESET_RESTART=y
|
||||
CONFIG_POWER_RESET_SYSCON=y
|
||||
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
|
||||
CONFIG_SYSCON_REBOOT_MODE=y
|
||||
CONFIG_SENSORS_LM75=m
|
||||
CONFIG_SENSORS_LM93=m
|
||||
CONFIG_SENSORS_W83795=m
|
||||
|
@ -609,16 +617,16 @@ CONFIG_SENSORS_W83627HF=m
|
|||
CONFIG_RC_CORE=m
|
||||
CONFIG_LIRC=y
|
||||
CONFIG_RC_DECODERS=y
|
||||
CONFIG_IR_IMON_DECODER=m
|
||||
CONFIG_IR_JVC_DECODER=m
|
||||
CONFIG_IR_MCE_KBD_DECODER=m
|
||||
CONFIG_IR_NEC_DECODER=m
|
||||
CONFIG_IR_RC5_DECODER=m
|
||||
CONFIG_IR_RC6_DECODER=m
|
||||
CONFIG_IR_JVC_DECODER=m
|
||||
CONFIG_IR_SONY_DECODER=m
|
||||
CONFIG_IR_SANYO_DECODER=m
|
||||
CONFIG_IR_SHARP_DECODER=m
|
||||
CONFIG_IR_MCE_KBD_DECODER=m
|
||||
CONFIG_IR_SONY_DECODER=m
|
||||
CONFIG_IR_XMP_DECODER=m
|
||||
CONFIG_IR_IMON_DECODER=m
|
||||
CONFIG_MEDIA_SUPPORT=m
|
||||
CONFIG_MEDIA_USB_SUPPORT=y
|
||||
CONFIG_USB_VIDEO_CLASS=m
|
||||
|
@ -638,6 +646,7 @@ CONFIG_DRM_VIRTIO_GPU=m
|
|||
CONFIG_FB=y
|
||||
CONFIG_FB_EFI=y
|
||||
CONFIG_FB_RADEON=y
|
||||
CONFIG_LCD_CLASS_DEVICE=y
|
||||
CONFIG_LCD_PLATFORM=m
|
||||
# CONFIG_VGA_CONSOLE is not set
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
|
@ -647,7 +656,6 @@ CONFIG_SOUND=y
|
|||
CONFIG_SND=y
|
||||
CONFIG_SND_SEQUENCER=m
|
||||
CONFIG_SND_SEQ_DUMMY=m
|
||||
# CONFIG_SND_ISA is not set
|
||||
CONFIG_SND_BT87X=m
|
||||
CONFIG_SND_BT87X_OVERCLOCK=y
|
||||
CONFIG_SND_HDA_INTEL=y
|
||||
|
@ -818,10 +826,6 @@ CONFIG_CRYPTO_USER=m
|
|||
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
|
||||
CONFIG_CRYPTO_PCRYPT=m
|
||||
CONFIG_CRYPTO_CRYPTD=m
|
||||
CONFIG_CRYPTO_CHACHA20POLY1305=m
|
||||
CONFIG_CRYPTO_HMAC=y
|
||||
CONFIG_CRYPTO_VMAC=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_ANUBIS=m
|
||||
CONFIG_CRYPTO_BLOWFISH=m
|
||||
CONFIG_CRYPTO_CAST5=m
|
||||
|
@ -831,6 +835,9 @@ CONFIG_CRYPTO_SEED=m
|
|||
CONFIG_CRYPTO_SERPENT=m
|
||||
CONFIG_CRYPTO_TEA=m
|
||||
CONFIG_CRYPTO_TWOFISH=m
|
||||
CONFIG_CRYPTO_CHACHA20POLY1305=m
|
||||
CONFIG_CRYPTO_VMAC=m
|
||||
CONFIG_CRYPTO_WP512=m
|
||||
CONFIG_CRYPTO_DEFLATE=m
|
||||
CONFIG_CRYPTO_LZO=m
|
||||
CONFIG_CRYPTO_842=m
|
||||
|
@ -844,6 +851,7 @@ CONFIG_CRYPTO_DEV_VIRTIO=m
|
|||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_STRIP_ASM_SYMS=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
CONFIG_SCHEDSTATS=y
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
|
|
|
@ -35,4 +35,14 @@ extern struct list_head acpi_wakeup_device_list;
|
|||
|
||||
#define ACPI_TABLE_UPGRADE_MAX_PHYS ARCH_LOW_ADDRESS_LIMIT
|
||||
|
||||
extern int loongarch_acpi_suspend(void);
|
||||
extern int (*acpi_suspend_lowlevel)(void);
|
||||
extern void loongarch_suspend_enter(void);
|
||||
|
||||
static inline unsigned long acpi_get_wakeup_address(void)
|
||||
{
|
||||
extern void loongarch_wakeup_start(void);
|
||||
return (unsigned long)loongarch_wakeup_start;
|
||||
}
|
||||
|
||||
#endif /* _ASM_LOONGARCH_ACPI_H */
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_ALTERNATIVE_ASM_H
|
||||
#define _ASM_ALTERNATIVE_ASM_H
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
#include <asm/asm.h>
|
||||
|
||||
/*
|
||||
* Issue one struct alt_instr descriptor entry (need to put it into
|
||||
* the section .altinstructions, see below). This entry contains
|
||||
* enough information for the alternatives patching code to patch an
|
||||
* instruction. See apply_alternatives().
|
||||
*/
|
||||
.macro altinstruction_entry orig alt feature orig_len alt_len
|
||||
.long \orig - .
|
||||
.long \alt - .
|
||||
.short \feature
|
||||
.byte \orig_len
|
||||
.byte \alt_len
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Define an alternative between two instructions. If @feature is
|
||||
* present, early code in apply_alternatives() replaces @oldinstr with
|
||||
* @newinstr. ".fill" directive takes care of proper instruction padding
|
||||
* in case @newinstr is longer than @oldinstr.
|
||||
*/
|
||||
.macro ALTERNATIVE oldinstr, newinstr, feature
|
||||
140 :
|
||||
\oldinstr
|
||||
141 :
|
||||
.fill - (((144f-143f)-(141b-140b)) > 0) * ((144f-143f)-(141b-140b)) / 4, 4, 0x03400000
|
||||
142 :
|
||||
|
||||
.pushsection .altinstructions, "a"
|
||||
altinstruction_entry 140b, 143f, \feature, 142b-140b, 144f-143f
|
||||
.popsection
|
||||
|
||||
.subsection 1
|
||||
143 :
|
||||
\newinstr
|
||||
144 :
|
||||
.previous
|
||||
.endm
|
||||
|
||||
#define old_len (141b-140b)
|
||||
#define new_len1 (144f-143f)
|
||||
#define new_len2 (145f-144f)
|
||||
|
||||
#define alt_max_short(a, b) ((a) ^ (((a) ^ (b)) & -(-((a) < (b)))))
|
||||
|
||||
/*
|
||||
* Same as ALTERNATIVE macro above but for two alternatives. If CPU
|
||||
* has @feature1, it replaces @oldinstr with @newinstr1. If CPU has
|
||||
* @feature2, it replaces @oldinstr with @feature2.
|
||||
*/
|
||||
.macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2
|
||||
140 :
|
||||
\oldinstr
|
||||
141 :
|
||||
.fill - ((alt_max_short(new_len1, new_len2) - (old_len)) > 0) * \
|
||||
(alt_max_short(new_len1, new_len2) - (old_len)) / 4, 4, 0x03400000
|
||||
142 :
|
||||
|
||||
.pushsection .altinstructions, "a"
|
||||
altinstruction_entry 140b, 143f, \feature1, 142b-140b, 144f-143f, 142b-141b
|
||||
altinstruction_entry 140b, 144f, \feature2, 142b-140b, 145f-144f, 142b-141b
|
||||
.popsection
|
||||
|
||||
.subsection 1
|
||||
143 :
|
||||
\newinstr1
|
||||
144 :
|
||||
\newinstr2
|
||||
145 :
|
||||
.previous
|
||||
.endm
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_ALTERNATIVE_ASM_H */
|
|
@ -0,0 +1,111 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_ALTERNATIVE_H
|
||||
#define _ASM_ALTERNATIVE_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/stringify.h>
|
||||
#include <asm/asm.h>
|
||||
|
||||
struct alt_instr {
|
||||
s32 instr_offset; /* offset to original instruction */
|
||||
s32 replace_offset; /* offset to replacement instruction */
|
||||
u16 feature; /* feature bit set for replacement */
|
||||
u8 instrlen; /* length of original instruction */
|
||||
u8 replacementlen; /* length of new instruction */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Debug flag that can be tested to see whether alternative
|
||||
* instructions were patched in already:
|
||||
*/
|
||||
extern int alternatives_patched;
|
||||
extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
|
||||
|
||||
extern void alternative_instructions(void);
|
||||
extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
|
||||
|
||||
#define b_replacement(num) "664"#num
|
||||
#define e_replacement(num) "665"#num
|
||||
|
||||
#define alt_end_marker "663"
|
||||
#define alt_slen "662b-661b"
|
||||
#define alt_total_slen alt_end_marker"b-661b"
|
||||
#define alt_rlen(num) e_replacement(num)"f-"b_replacement(num)"f"
|
||||
|
||||
#define __OLDINSTR(oldinstr, num) \
|
||||
"661:\n\t" oldinstr "\n662:\n" \
|
||||
".fill -(((" alt_rlen(num) ")-(" alt_slen ")) > 0) * " \
|
||||
"((" alt_rlen(num) ")-(" alt_slen ")) / 4, 4, 0x03400000\n"
|
||||
|
||||
#define OLDINSTR(oldinstr, num) \
|
||||
__OLDINSTR(oldinstr, num) \
|
||||
alt_end_marker ":\n"
|
||||
|
||||
#define alt_max_short(a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") < (" b ")))))"
|
||||
|
||||
/*
|
||||
* Pad the second replacement alternative with additional NOPs if it is
|
||||
* additionally longer than the first replacement alternative.
|
||||
*/
|
||||
#define OLDINSTR_2(oldinstr, num1, num2) \
|
||||
"661:\n\t" oldinstr "\n662:\n" \
|
||||
".fill -((" alt_max_short(alt_rlen(num1), alt_rlen(num2)) " - (" alt_slen ")) > 0) * " \
|
||||
"(" alt_max_short(alt_rlen(num1), alt_rlen(num2)) " - (" alt_slen ")) / 4, " \
|
||||
"4, 0x03400000\n" \
|
||||
alt_end_marker ":\n"
|
||||
|
||||
#define ALTINSTR_ENTRY(feature, num) \
|
||||
" .long 661b - .\n" /* label */ \
|
||||
" .long " b_replacement(num)"f - .\n" /* new instruction */ \
|
||||
" .short " __stringify(feature) "\n" /* feature bit */ \
|
||||
" .byte " alt_total_slen "\n" /* source len */ \
|
||||
" .byte " alt_rlen(num) "\n" /* replacement len */
|
||||
|
||||
#define ALTINSTR_REPLACEMENT(newinstr, feature, num) /* replacement */ \
|
||||
b_replacement(num)":\n\t" newinstr "\n" e_replacement(num) ":\n\t"
|
||||
|
||||
/* alternative assembly primitive: */
|
||||
#define ALTERNATIVE(oldinstr, newinstr, feature) \
|
||||
OLDINSTR(oldinstr, 1) \
|
||||
".pushsection .altinstructions,\"a\"\n" \
|
||||
ALTINSTR_ENTRY(feature, 1) \
|
||||
".popsection\n" \
|
||||
".subsection 1\n" \
|
||||
ALTINSTR_REPLACEMENT(newinstr, feature, 1) \
|
||||
".previous\n"
|
||||
|
||||
#define ALTERNATIVE_2(oldinstr, newinstr1, feature1, newinstr2, feature2)\
|
||||
OLDINSTR_2(oldinstr, 1, 2) \
|
||||
".pushsection .altinstructions,\"a\"\n" \
|
||||
ALTINSTR_ENTRY(feature1, 1) \
|
||||
ALTINSTR_ENTRY(feature2, 2) \
|
||||
".popsection\n" \
|
||||
".subsection 1\n" \
|
||||
ALTINSTR_REPLACEMENT(newinstr1, feature1, 1) \
|
||||
ALTINSTR_REPLACEMENT(newinstr2, feature2, 2) \
|
||||
".previous\n"
|
||||
|
||||
/*
|
||||
* Alternative instructions for different CPU types or capabilities.
|
||||
*
|
||||
* This allows to use optimized instructions even on generic binary
|
||||
* kernels.
|
||||
*
|
||||
* length of oldinstr must be longer or equal the length of newinstr
|
||||
* It can be padded with nops as needed.
|
||||
*
|
||||
* For non barrier like inlines please define new variants
|
||||
* without volatile and memory clobber.
|
||||
*/
|
||||
#define alternative(oldinstr, newinstr, feature) \
|
||||
(asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) : : : "memory"))
|
||||
|
||||
#define alternative_2(oldinstr, newinstr1, feature1, newinstr2, feature2) \
|
||||
(asm volatile(ALTERNATIVE_2(oldinstr, newinstr1, feature1, newinstr2, feature2) ::: "memory"))
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_ALTERNATIVE_H */
|
|
@ -0,0 +1,65 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef __ASM_ASM_EXTABLE_H
|
||||
#define __ASM_ASM_EXTABLE_H
|
||||
|
||||
#define EX_TYPE_NONE 0
|
||||
#define EX_TYPE_FIXUP 1
|
||||
#define EX_TYPE_UACCESS_ERR_ZERO 2
|
||||
#define EX_TYPE_BPF 3
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
#define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
|
||||
.pushsection __ex_table, "a"; \
|
||||
.balign 4; \
|
||||
.long ((insn) - .); \
|
||||
.long ((fixup) - .); \
|
||||
.short (type); \
|
||||
.short (data); \
|
||||
.popsection;
|
||||
|
||||
.macro _asm_extable, insn, fixup
|
||||
__ASM_EXTABLE_RAW(\insn, \fixup, EX_TYPE_FIXUP, 0)
|
||||
.endm
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/stringify.h>
|
||||
#include <asm/gpr-num.h>
|
||||
|
||||
#define __ASM_EXTABLE_RAW(insn, fixup, type, data) \
|
||||
".pushsection __ex_table, \"a\"\n" \
|
||||
".balign 4\n" \
|
||||
".long ((" insn ") - .)\n" \
|
||||
".long ((" fixup ") - .)\n" \
|
||||
".short (" type ")\n" \
|
||||
".short (" data ")\n" \
|
||||
".popsection\n"
|
||||
|
||||
#define _ASM_EXTABLE(insn, fixup) \
|
||||
__ASM_EXTABLE_RAW(#insn, #fixup, __stringify(EX_TYPE_FIXUP), "0")
|
||||
|
||||
#define EX_DATA_REG_ERR_SHIFT 0
|
||||
#define EX_DATA_REG_ERR GENMASK(4, 0)
|
||||
#define EX_DATA_REG_ZERO_SHIFT 5
|
||||
#define EX_DATA_REG_ZERO GENMASK(9, 5)
|
||||
|
||||
#define EX_DATA_REG(reg, gpr) \
|
||||
"((.L__gpr_num_" #gpr ") << " __stringify(EX_DATA_REG_##reg##_SHIFT) ")"
|
||||
|
||||
#define _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero) \
|
||||
__DEFINE_ASM_GPR_NUMS \
|
||||
__ASM_EXTABLE_RAW(#insn, #fixup, \
|
||||
__stringify(EX_TYPE_UACCESS_ERR_ZERO), \
|
||||
"(" \
|
||||
EX_DATA_REG(ERR, err) " | " \
|
||||
EX_DATA_REG(ZERO, zero) \
|
||||
")")
|
||||
|
||||
#define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err) \
|
||||
_ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero)
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_ASM_EXTABLE_H */
|
|
@ -32,6 +32,7 @@ struct loongson_system_configuration {
|
|||
int cores_per_node;
|
||||
int cores_per_package;
|
||||
unsigned long cores_io_master;
|
||||
unsigned long suspend_addr;
|
||||
const char *cpuname;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* This is included by init/main.c to check for architecture-dependent bugs.
|
||||
*
|
||||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
#ifndef _ASM_BUGS_H
|
||||
#define _ASM_BUGS_H
|
||||
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cpu-info.h>
|
||||
|
||||
extern void check_bugs(void);
|
||||
|
||||
#endif /* _ASM_BUGS_H */
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
void __init efi_init(void);
|
||||
void __init efi_runtime_init(void);
|
||||
void __init *efi_fdt_pointer(void);
|
||||
void efifb_setup_from_dmi(struct screen_info *si, const char *opt);
|
||||
|
||||
#define ARCH_EFI_IRQ_FLAGS_MASK 0x00000004 /* Bit 2: CSR.CRMD.IE */
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_LOONGARCH_EXTABLE_H
|
||||
#define _ASM_LOONGARCH_EXTABLE_H
|
||||
|
||||
/*
|
||||
* The exception table consists of pairs of relative offsets: the first
|
||||
* is the relative offset to an instruction that is allowed to fault,
|
||||
* and the second is the relative offset at which the program should
|
||||
* continue. No registers are modified, so it is entirely up to the
|
||||
* continuation code to figure out what to do.
|
||||
*
|
||||
* All the routines below use bits of fixup code that are out of line
|
||||
* with the main instruction path. This means when everything is well,
|
||||
* we don't even have to jump over them. Further, they do not intrude
|
||||
* on our cache or tlb entries.
|
||||
*/
|
||||
|
||||
struct exception_table_entry {
|
||||
int insn, fixup;
|
||||
short type, data;
|
||||
};
|
||||
|
||||
#define ARCH_HAS_RELATIVE_EXTABLE
|
||||
|
||||
#define swap_ex_entry_fixup(a, b, tmp, delta) \
|
||||
do { \
|
||||
(a)->fixup = (b)->fixup + (delta); \
|
||||
(b)->fixup = (tmp).fixup - (delta); \
|
||||
(a)->type = (b)->type; \
|
||||
(b)->type = (tmp).type; \
|
||||
(a)->data = (b)->data; \
|
||||
(b)->data = (tmp).data; \
|
||||
} while (0)
|
||||
|
||||
#ifdef CONFIG_BPF_JIT
|
||||
bool ex_handler_bpf(const struct exception_table_entry *ex, struct pt_regs *regs);
|
||||
#else
|
||||
static inline
|
||||
bool ex_handler_bpf(const struct exception_table_entry *ex, struct pt_regs *regs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif /* !CONFIG_BPF_JIT */
|
||||
|
||||
bool fixup_exception(struct pt_regs *regs);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,68 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
|
||||
#ifndef _ASM_LOONGARCH_FTRACE_H
|
||||
#define _ASM_LOONGARCH_FTRACE_H
|
||||
|
||||
#define FTRACE_PLT_IDX 0
|
||||
#define FTRACE_REGS_PLT_IDX 1
|
||||
#define NR_FTRACE_PLTS 2
|
||||
|
||||
#define GRAPH_FAKE_OFFSET (sizeof(struct pt_regs) - offsetof(struct pt_regs, regs[1]))
|
||||
|
||||
#ifdef CONFIG_FUNCTION_TRACER
|
||||
|
||||
#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#ifndef CONFIG_DYNAMIC_FTRACE
|
||||
|
||||
#define mcount _mcount
|
||||
extern void _mcount(void);
|
||||
extern void prepare_ftrace_return(unsigned long self_addr, unsigned long callsite_sp, unsigned long old);
|
||||
|
||||
#else
|
||||
|
||||
struct dyn_ftrace;
|
||||
struct dyn_arch_ftrace { };
|
||||
|
||||
#define ARCH_SUPPORTS_FTRACE_OPS 1
|
||||
#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
|
||||
|
||||
#define ftrace_init_nop ftrace_init_nop
|
||||
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
|
||||
|
||||
static inline unsigned long ftrace_call_adjust(unsigned long addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent);
|
||||
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE */
|
||||
|
||||
#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
|
||||
struct ftrace_ops;
|
||||
|
||||
struct ftrace_regs {
|
||||
struct pt_regs regs;
|
||||
};
|
||||
|
||||
static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs)
|
||||
{
|
||||
return &fregs->regs;
|
||||
}
|
||||
|
||||
#define ftrace_graph_func ftrace_graph_func
|
||||
void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
|
||||
struct ftrace_ops *op, struct ftrace_regs *fregs);
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* CONFIG_FUNCTION_TRACER */
|
||||
|
||||
#endif /* _ASM_LOONGARCH_FTRACE_H */
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <linux/futex.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/asm-extable.h>
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/errno.h>
|
||||
|
||||
|
@ -18,18 +19,11 @@
|
|||
"2: sc.w $t0, %2 \n" \
|
||||
" beqz $t0, 1b \n" \
|
||||
"3: \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
"4: li.w %0, %6 \n" \
|
||||
" b 3b \n" \
|
||||
" .previous \n" \
|
||||
" .section __ex_table,\"a\" \n" \
|
||||
" "__UA_ADDR "\t1b, 4b \n" \
|
||||
" "__UA_ADDR "\t2b, 4b \n" \
|
||||
" .previous \n" \
|
||||
_ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0) \
|
||||
_ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0) \
|
||||
: "=r" (ret), "=&r" (oldval), \
|
||||
"=ZC" (*uaddr) \
|
||||
: "0" (0), "ZC" (*uaddr), "Jr" (oparg), \
|
||||
"i" (-EFAULT) \
|
||||
: "0" (0), "ZC" (*uaddr), "Jr" (oparg) \
|
||||
: "memory", "t0"); \
|
||||
}
|
||||
|
||||
|
@ -86,17 +80,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newv
|
|||
" beqz $t0, 1b \n"
|
||||
"3: \n"
|
||||
__WEAK_LLSC_MB
|
||||
" .section .fixup,\"ax\" \n"
|
||||
"4: li.d %0, %6 \n"
|
||||
" b 3b \n"
|
||||
" .previous \n"
|
||||
" .section __ex_table,\"a\" \n"
|
||||
" "__UA_ADDR "\t1b, 4b \n"
|
||||
" "__UA_ADDR "\t2b, 4b \n"
|
||||
" .previous \n"
|
||||
_ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0)
|
||||
_ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0)
|
||||
: "+r" (ret), "=&r" (val), "=ZC" (*uaddr)
|
||||
: "ZC" (*uaddr), "Jr" (oldval), "Jr" (newval),
|
||||
"i" (-EFAULT)
|
||||
: "ZC" (*uaddr), "Jr" (oldval), "Jr" (newval)
|
||||
: "memory", "t0");
|
||||
|
||||
*uval = val;
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
#ifndef __ASM_GPR_NUM_H
|
||||
#define __ASM_GPR_NUM_H
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
.equ .L__gpr_num_zero, 0
|
||||
.irp num,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
|
||||
.equ .L__gpr_num_$r\num, \num
|
||||
.endr
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
#define __DEFINE_ASM_GPR_NUMS \
|
||||
" .equ .L__gpr_num_zero, 0\n" \
|
||||
" .irp num,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31\n" \
|
||||
" .equ .L__gpr_num_$r\\num, \\num\n" \
|
||||
" .endr\n" \
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_GPR_NUM_H */
|
|
@ -8,14 +8,17 @@
|
|||
#include <linux/types.h>
|
||||
#include <asm/asm.h>
|
||||
|
||||
#define INSN_NOP 0x03400000
|
||||
#define INSN_BREAK 0x002a0000
|
||||
|
||||
#define ADDR_IMMMASK_LU52ID 0xFFF0000000000000
|
||||
#define ADDR_IMMMASK_LU32ID 0x000FFFFF00000000
|
||||
#define ADDR_IMMMASK_LU12IW 0x00000000FFFFF000
|
||||
#define ADDR_IMMMASK_ADDU16ID 0x00000000FFFF0000
|
||||
|
||||
#define ADDR_IMMSHIFT_LU52ID 52
|
||||
#define ADDR_IMMSHIFT_LU32ID 32
|
||||
#define ADDR_IMMSHIFT_LU12IW 12
|
||||
#define ADDR_IMMSHIFT_ADDU16ID 16
|
||||
|
||||
#define ADDR_IMM(addr, INSN) ((addr & ADDR_IMMMASK_##INSN) >> ADDR_IMMSHIFT_##INSN)
|
||||
|
@ -28,6 +31,7 @@ enum reg0i26_op {
|
|||
enum reg1i20_op {
|
||||
lu12iw_op = 0x0a,
|
||||
lu32id_op = 0x0b,
|
||||
pcaddi_op = 0x0c,
|
||||
pcaddu12i_op = 0x0e,
|
||||
pcaddu18i_op = 0x0f,
|
||||
};
|
||||
|
@ -35,6 +39,8 @@ enum reg1i20_op {
|
|||
enum reg1i21_op {
|
||||
beqz_op = 0x10,
|
||||
bnez_op = 0x11,
|
||||
bceqz_op = 0x12, /* bits[9:8] = 0x00 */
|
||||
bcnez_op = 0x12, /* bits[9:8] = 0x01 */
|
||||
};
|
||||
|
||||
enum reg2_op {
|
||||
|
@ -76,6 +82,10 @@ enum reg2i12_op {
|
|||
ldbu_op = 0xa8,
|
||||
ldhu_op = 0xa9,
|
||||
ldwu_op = 0xaa,
|
||||
flds_op = 0xac,
|
||||
fsts_op = 0xad,
|
||||
fldd_op = 0xae,
|
||||
fstd_op = 0xaf,
|
||||
};
|
||||
|
||||
enum reg2i14_op {
|
||||
|
@ -146,6 +156,10 @@ enum reg3_op {
|
|||
ldxbu_op = 0x7040,
|
||||
ldxhu_op = 0x7048,
|
||||
ldxwu_op = 0x7050,
|
||||
fldxs_op = 0x7060,
|
||||
fldxd_op = 0x7068,
|
||||
fstxs_op = 0x7070,
|
||||
fstxd_op = 0x7078,
|
||||
amswapw_op = 0x70c0,
|
||||
amswapd_op = 0x70c1,
|
||||
amaddw_op = 0x70c2,
|
||||
|
@ -307,6 +321,12 @@ static inline bool is_imm_negative(unsigned long val, unsigned int bit)
|
|||
return val & (1UL << (bit - 1));
|
||||
}
|
||||
|
||||
static inline bool is_pc_ins(union loongarch_instruction *ip)
|
||||
{
|
||||
return ip->reg1i20_format.opcode >= pcaddi_op &&
|
||||
ip->reg1i20_format.opcode <= pcaddu18i_op;
|
||||
}
|
||||
|
||||
static inline bool is_branch_ins(union loongarch_instruction *ip)
|
||||
{
|
||||
return ip->reg1i21_format.opcode >= beqz_op &&
|
||||
|
@ -331,6 +351,18 @@ static inline bool is_stack_alloc_ins(union loongarch_instruction *ip)
|
|||
is_imm12_negative(ip->reg2i12_format.immediate);
|
||||
}
|
||||
|
||||
int larch_insn_read(void *addr, u32 *insnp);
|
||||
int larch_insn_write(void *addr, u32 insn);
|
||||
int larch_insn_patch_text(void *addr, u32 insn);
|
||||
|
||||
u32 larch_insn_gen_nop(void);
|
||||
u32 larch_insn_gen_b(unsigned long pc, unsigned long dest);
|
||||
u32 larch_insn_gen_bl(unsigned long pc, unsigned long dest);
|
||||
|
||||
u32 larch_insn_gen_or(enum loongarch_gpr rd, enum loongarch_gpr rj, enum loongarch_gpr rk);
|
||||
u32 larch_insn_gen_move(enum loongarch_gpr rd, enum loongarch_gpr rj);
|
||||
|
||||
u32 larch_insn_gen_lu12iw(enum loongarch_gpr rd, int imm);
|
||||
u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm);
|
||||
u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm);
|
||||
u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, unsigned long pc, unsigned long dest);
|
||||
|
@ -345,6 +377,14 @@ static inline bool unsigned_imm_check(unsigned long val, unsigned int bit)
|
|||
return val < (1UL << bit);
|
||||
}
|
||||
|
||||
static inline unsigned long sign_extend(unsigned long val, unsigned int idx)
|
||||
{
|
||||
if (!is_imm_negative(val, idx + 1))
|
||||
return ((1UL << idx) - 1) & val;
|
||||
else
|
||||
return ~((1UL << idx) - 1) | val;
|
||||
}
|
||||
|
||||
#define DEF_EMIT_REG0I26_FORMAT(NAME, OP) \
|
||||
static inline void emit_##NAME(union loongarch_instruction *insn, \
|
||||
int offset) \
|
||||
|
@ -566,4 +606,10 @@ static inline void emit_##NAME(union loongarch_instruction *insn, \
|
|||
|
||||
DEF_EMIT_REG3SA2_FORMAT(alsld, alsld_op)
|
||||
|
||||
struct pt_regs;
|
||||
|
||||
void emulate_load_store_insn(struct pt_regs *regs, void __user *addr, unsigned int *pc);
|
||||
unsigned long unaligned_read(void __user *addr, void *value, unsigned long n, bool sign);
|
||||
unsigned long unaligned_write(void __user *addr, unsigned long value, unsigned long n);
|
||||
|
||||
#endif /* _ASM_INST_H */
|
||||
|
|
|
@ -136,4 +136,7 @@ typedef enum {
|
|||
#define ls7a_writel(val, addr) *(volatile unsigned int *)TO_UNCACHE(addr) = (val)
|
||||
#define ls7a_writeq(val, addr) *(volatile unsigned long *)TO_UNCACHE(addr) = (val)
|
||||
|
||||
void enable_gpe_wakeup(void);
|
||||
void enable_pci_wakeup(void);
|
||||
|
||||
#endif /* __ASM_LOONGSON_H */
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#define RELA_STACK_DEPTH 16
|
||||
|
||||
struct mod_section {
|
||||
Elf_Shdr *shdr;
|
||||
int shndx;
|
||||
int num_entries;
|
||||
int max_entries;
|
||||
};
|
||||
|
@ -20,6 +20,9 @@ struct mod_arch_specific {
|
|||
struct mod_section got;
|
||||
struct mod_section plt;
|
||||
struct mod_section plt_idx;
|
||||
|
||||
/* For CONFIG_DYNAMIC_FTRACE */
|
||||
struct plt_entry *ftrace_trampolines;
|
||||
};
|
||||
|
||||
struct got_entry {
|
||||
|
@ -37,8 +40,8 @@ struct plt_idx_entry {
|
|||
Elf_Addr symbol_addr;
|
||||
};
|
||||
|
||||
Elf_Addr module_emit_got_entry(struct module *mod, Elf_Addr val);
|
||||
Elf_Addr module_emit_plt_entry(struct module *mod, Elf_Addr val);
|
||||
Elf_Addr module_emit_got_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val);
|
||||
Elf_Addr module_emit_plt_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val);
|
||||
|
||||
static inline struct got_entry emit_got_entry(Elf_Addr val)
|
||||
{
|
||||
|
@ -49,7 +52,7 @@ static inline struct plt_entry emit_plt_entry(unsigned long val)
|
|||
{
|
||||
u32 lu12iw, lu32id, lu52id, jirl;
|
||||
|
||||
lu12iw = (lu12iw_op << 25 | (((val >> 12) & 0xfffff) << 5) | LOONGARCH_GPR_T1);
|
||||
lu12iw = larch_insn_gen_lu12iw(LOONGARCH_GPR_T1, ADDR_IMM(val, LU12IW));
|
||||
lu32id = larch_insn_gen_lu32id(LOONGARCH_GPR_T1, ADDR_IMM(val, LU32ID));
|
||||
lu52id = larch_insn_gen_lu52id(LOONGARCH_GPR_T1, LOONGARCH_GPR_T1, ADDR_IMM(val, LU52ID));
|
||||
jirl = larch_insn_gen_jirl(0, LOONGARCH_GPR_T1, 0, (val & 0xfff));
|
||||
|
@ -62,10 +65,10 @@ static inline struct plt_idx_entry emit_plt_idx_entry(unsigned long val)
|
|||
return (struct plt_idx_entry) { val };
|
||||
}
|
||||
|
||||
static inline int get_plt_idx(unsigned long val, const struct mod_section *sec)
|
||||
static inline int get_plt_idx(unsigned long val, Elf_Shdr *sechdrs, const struct mod_section *sec)
|
||||
{
|
||||
int i;
|
||||
struct plt_idx_entry *plt_idx = (struct plt_idx_entry *)sec->shdr->sh_addr;
|
||||
struct plt_idx_entry *plt_idx = (struct plt_idx_entry *)sechdrs[sec->shndx].sh_addr;
|
||||
|
||||
for (i = 0; i < sec->num_entries; i++) {
|
||||
if (plt_idx[i].symbol_addr == val)
|
||||
|
@ -76,11 +79,12 @@ static inline int get_plt_idx(unsigned long val, const struct mod_section *sec)
|
|||
}
|
||||
|
||||
static inline struct plt_entry *get_plt_entry(unsigned long val,
|
||||
const struct mod_section *sec_plt,
|
||||
const struct mod_section *sec_plt_idx)
|
||||
Elf_Shdr *sechdrs,
|
||||
const struct mod_section *sec_plt,
|
||||
const struct mod_section *sec_plt_idx)
|
||||
{
|
||||
int plt_idx = get_plt_idx(val, sec_plt_idx);
|
||||
struct plt_entry *plt = (struct plt_entry *)sec_plt->shdr->sh_addr;
|
||||
int plt_idx = get_plt_idx(val, sechdrs, sec_plt_idx);
|
||||
struct plt_entry *plt = (struct plt_entry *)sechdrs[sec_plt->shndx].sh_addr;
|
||||
|
||||
if (plt_idx < 0)
|
||||
return NULL;
|
||||
|
@ -89,10 +93,11 @@ static inline struct plt_entry *get_plt_entry(unsigned long val,
|
|||
}
|
||||
|
||||
static inline struct got_entry *get_got_entry(Elf_Addr val,
|
||||
Elf_Shdr *sechdrs,
|
||||
const struct mod_section *sec)
|
||||
{
|
||||
struct got_entry *got = (struct got_entry *)sec->shdr->sh_addr;
|
||||
int i;
|
||||
struct got_entry *got = (struct got_entry *)sechdrs[sec->shndx].sh_addr;
|
||||
|
||||
for (i = 0; i < sec->num_entries; i++)
|
||||
if (got[i].symbol_addr == val)
|
||||
|
|
|
@ -5,4 +5,5 @@ SECTIONS {
|
|||
.got : { BYTE(0) }
|
||||
.plt : { BYTE(0) }
|
||||
.plt.idx : { BYTE(0) }
|
||||
.ftrace_trampoline : { BYTE(0) }
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
extern unsigned long eentry;
|
||||
extern unsigned long tlbrentry;
|
||||
extern char init_command_line[COMMAND_LINE_SIZE];
|
||||
extern void tlb_init(int cpu);
|
||||
extern void cpu_cache_init(void);
|
||||
extern void cache_error_setup(void);
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* GCC stack protector support.
|
||||
*
|
||||
* Stack protector works by putting predefined pattern at the start of
|
||||
* the stack frame and verifying that it hasn't been overwritten when
|
||||
* returning from the function. The pattern is called stack canary and
|
||||
* on LoongArch gcc expects it to be defined by a global variable called
|
||||
* "__stack_chk_guard".
|
||||
*/
|
||||
|
||||
#ifndef _ASM_STACKPROTECTOR_H
|
||||
#define _ASM_STACKPROTECTOR_H
|
||||
|
||||
#include <linux/random.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
extern unsigned long __stack_chk_guard;
|
||||
|
||||
/*
|
||||
* Initialize the stackprotector canary value.
|
||||
*
|
||||
* NOTE: this must only be called from functions that never return,
|
||||
* and it must always be inlined.
|
||||
*/
|
||||
static __always_inline void boot_init_stack_canary(void)
|
||||
{
|
||||
unsigned long canary;
|
||||
|
||||
/* Try to get a semi random initial value. */
|
||||
get_random_bytes(&canary, sizeof(canary));
|
||||
canary ^= LINUX_VERSION_CODE;
|
||||
|
||||
current->stack_canary = canary;
|
||||
__stack_chk_guard = current->stack_canary;
|
||||
}
|
||||
|
||||
#endif /* _ASM_STACKPROTECTOR_H */
|
|
@ -5,8 +5,13 @@
|
|||
#ifndef _ASM_STRING_H
|
||||
#define _ASM_STRING_H
|
||||
|
||||
#define __HAVE_ARCH_MEMSET
|
||||
extern void *memset(void *__s, int __c, size_t __count);
|
||||
|
||||
#define __HAVE_ARCH_MEMCPY
|
||||
extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
|
||||
|
||||
#define __HAVE_ARCH_MEMMOVE
|
||||
extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
|
||||
|
||||
#endif /* _ASM_STRING_H */
|
||||
|
|
|
@ -38,7 +38,7 @@ struct thread_info {
|
|||
#define INIT_THREAD_INFO(tsk) \
|
||||
{ \
|
||||
.task = &tsk, \
|
||||
.flags = 0, \
|
||||
.flags = _TIF_FIXADE, \
|
||||
.cpu = 0, \
|
||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
extern u64 cpu_clock_freq;
|
||||
extern u64 const_clock_freq;
|
||||
|
||||
extern void save_counter(void);
|
||||
extern void sync_counter(void);
|
||||
|
||||
static inline unsigned int calc_const_freq(void)
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/extable.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm-generic/extable.h>
|
||||
#include <asm/extable.h>
|
||||
#include <asm/asm-extable.h>
|
||||
#include <asm-generic/access_ok.h>
|
||||
|
||||
extern u64 __ua_limit;
|
||||
|
@ -160,16 +161,9 @@ do { \
|
|||
__asm__ __volatile__( \
|
||||
"1: " insn " %1, %2 \n" \
|
||||
"2: \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
"3: li.w %0, %3 \n" \
|
||||
" move %1, $zero \n" \
|
||||
" b 2b \n" \
|
||||
" .previous \n" \
|
||||
" .section __ex_table,\"a\" \n" \
|
||||
" "__UA_ADDR "\t1b, 3b \n" \
|
||||
" .previous \n" \
|
||||
_ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 2b, %0, %1) \
|
||||
: "+r" (__gu_err), "=r" (__gu_tmp) \
|
||||
: "m" (__m(ptr)), "i" (-EFAULT)); \
|
||||
: "m" (__m(ptr))); \
|
||||
\
|
||||
(val) = (__typeof__(*(ptr))) __gu_tmp; \
|
||||
}
|
||||
|
@ -192,15 +186,9 @@ do { \
|
|||
__asm__ __volatile__( \
|
||||
"1: " insn " %z2, %1 # __put_user_asm\n" \
|
||||
"2: \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
"3: li.w %0, %3 \n" \
|
||||
" b 2b \n" \
|
||||
" .previous \n" \
|
||||
" .section __ex_table,\"a\" \n" \
|
||||
" " __UA_ADDR " 1b, 3b \n" \
|
||||
" .previous \n" \
|
||||
_ASM_EXTABLE_UACCESS_ERR(1b, 2b, %0) \
|
||||
: "+r" (__pu_err), "=m" (__m(ptr)) \
|
||||
: "Jr" (__pu_val), "i" (-EFAULT)); \
|
||||
: "Jr" (__pu_val)); \
|
||||
}
|
||||
|
||||
#define __get_kernel_nofault(dst, src, type, err_label) \
|
||||
|
|
|
@ -20,7 +20,8 @@ struct unwind_state {
|
|||
char type; /* UNWINDER_XXX */
|
||||
struct stack_info stack_info;
|
||||
struct task_struct *task;
|
||||
bool first, error;
|
||||
bool first, error, is_ftrace;
|
||||
int graph_idx;
|
||||
unsigned long sp, pc, ra;
|
||||
};
|
||||
|
||||
|
|
|
@ -7,13 +7,27 @@ extra-y := vmlinux.lds
|
|||
|
||||
obj-y += head.o cpu-probe.o cacheinfo.o env.o setup.o entry.o genex.o \
|
||||
traps.o irq.o idle.o process.o dma.o mem.o io.o reset.o switch.o \
|
||||
elf.o syscall.o signal.o time.o topology.o inst.o ptrace.o vdso.o
|
||||
elf.o syscall.o signal.o time.o topology.o inst.o ptrace.o vdso.o \
|
||||
alternative.o unaligned.o
|
||||
|
||||
obj-$(CONFIG_ACPI) += acpi.o
|
||||
obj-$(CONFIG_EFI) += efi.o
|
||||
|
||||
obj-$(CONFIG_CPU_HAS_FPU) += fpu.o
|
||||
|
||||
ifdef CONFIG_FUNCTION_TRACER
|
||||
ifndef CONFIG_DYNAMIC_FTRACE
|
||||
obj-y += mcount.o ftrace.o
|
||||
CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
|
||||
else
|
||||
obj-y += mcount_dyn.o ftrace_dyn.o
|
||||
CFLAGS_REMOVE_ftrace_dyn.o = $(CC_FLAGS_FTRACE)
|
||||
endif
|
||||
CFLAGS_REMOVE_inst.o = $(CC_FLAGS_FTRACE)
|
||||
CFLAGS_REMOVE_time.o = $(CC_FLAGS_FTRACE)
|
||||
CFLAGS_REMOVE_perf_event.o = $(CC_FLAGS_FTRACE)
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_MODULES) += module.o module-sections.o
|
||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/numa.h>
|
||||
|
@ -139,20 +140,26 @@ static void __init acpi_process_madt(void)
|
|||
loongson_sysconf.nr_cpus = num_processors;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SUSPEND
|
||||
int (*acpi_suspend_lowlevel)(void);
|
||||
#else
|
||||
int (*acpi_suspend_lowlevel)(void) = loongarch_acpi_suspend;
|
||||
#endif
|
||||
|
||||
void __init acpi_boot_table_init(void)
|
||||
{
|
||||
/*
|
||||
* If acpi_disabled, bail out
|
||||
*/
|
||||
if (acpi_disabled)
|
||||
return;
|
||||
goto fdt_earlycon;
|
||||
|
||||
/*
|
||||
* Initialize the ACPI boot-time table parser.
|
||||
*/
|
||||
if (acpi_table_init()) {
|
||||
disable_acpi();
|
||||
return;
|
||||
goto fdt_earlycon;
|
||||
}
|
||||
|
||||
loongson_sysconf.boot_cpu_id = read_csr_cpuid();
|
||||
|
@ -164,6 +171,12 @@ void __init acpi_boot_table_init(void)
|
|||
|
||||
/* Do not enable ACPI SPCR console by default */
|
||||
acpi_parse_spcr(earlycon_acpi_spcr_enable, false);
|
||||
|
||||
return;
|
||||
|
||||
fdt_earlycon:
|
||||
if (earlycon_acpi_spcr_enable)
|
||||
early_init_dt_scan_chosen_stdout();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_NUMA
|
||||
|
|
|
@ -0,0 +1,246 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/alternative.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/inst.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
int __read_mostly alternatives_patched;
|
||||
|
||||
EXPORT_SYMBOL_GPL(alternatives_patched);
|
||||
|
||||
#define MAX_PATCH_SIZE (((u8)(-1)) / LOONGARCH_INSN_SIZE)
|
||||
|
||||
static int __initdata_or_module debug_alternative;
|
||||
|
||||
static int __init debug_alt(char *str)
|
||||
{
|
||||
debug_alternative = 1;
|
||||
return 1;
|
||||
}
|
||||
__setup("debug-alternative", debug_alt);
|
||||
|
||||
#define DPRINTK(fmt, args...) \
|
||||
do { \
|
||||
if (debug_alternative) \
|
||||
printk(KERN_DEBUG "%s: " fmt "\n", __func__, ##args); \
|
||||
} while (0)
|
||||
|
||||
#define DUMP_WORDS(buf, count, fmt, args...) \
|
||||
do { \
|
||||
if (unlikely(debug_alternative)) { \
|
||||
int _j; \
|
||||
union loongarch_instruction *_buf = buf; \
|
||||
\
|
||||
if (!(count)) \
|
||||
break; \
|
||||
\
|
||||
printk(KERN_DEBUG fmt, ##args); \
|
||||
for (_j = 0; _j < count - 1; _j++) \
|
||||
printk(KERN_CONT "<%08x> ", _buf[_j].word); \
|
||||
printk(KERN_CONT "<%08x>\n", _buf[_j].word); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Use this to add nops to a buffer, then text_poke the whole buffer. */
|
||||
static void __init_or_module add_nops(union loongarch_instruction *insn, int count)
|
||||
{
|
||||
while (count--) {
|
||||
insn->word = INSN_NOP;
|
||||
insn++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Is the jump addr in local .altinstructions */
|
||||
static inline bool in_alt_jump(unsigned long jump, void *start, void *end)
|
||||
{
|
||||
return jump >= (unsigned long)start && jump < (unsigned long)end;
|
||||
}
|
||||
|
||||
static void __init_or_module recompute_jump(union loongarch_instruction *buf,
|
||||
union loongarch_instruction *dest, union loongarch_instruction *src,
|
||||
void *start, void *end)
|
||||
{
|
||||
unsigned int si, si_l, si_h;
|
||||
unsigned long cur_pc, jump_addr, pc;
|
||||
long offset;
|
||||
|
||||
cur_pc = (unsigned long)src;
|
||||
pc = (unsigned long)dest;
|
||||
|
||||
si_l = src->reg0i26_format.immediate_l;
|
||||
si_h = src->reg0i26_format.immediate_h;
|
||||
switch (src->reg0i26_format.opcode) {
|
||||
case b_op:
|
||||
case bl_op:
|
||||
jump_addr = cur_pc + sign_extend((si_h << 16 | si_l) << 2, 27);
|
||||
if (in_alt_jump(jump_addr, start, end))
|
||||
return;
|
||||
offset = jump_addr - pc;
|
||||
BUG_ON(offset < -SZ_128M || offset >= SZ_128M);
|
||||
offset >>= 2;
|
||||
buf->reg0i26_format.immediate_h = offset >> 16;
|
||||
buf->reg0i26_format.immediate_l = offset;
|
||||
return;
|
||||
}
|
||||
|
||||
si_l = src->reg1i21_format.immediate_l;
|
||||
si_h = src->reg1i21_format.immediate_h;
|
||||
switch (src->reg1i21_format.opcode) {
|
||||
case bceqz_op: /* bceqz_op = bcnez_op */
|
||||
BUG_ON(buf->reg1i21_format.rj & BIT(4));
|
||||
fallthrough;
|
||||
case beqz_op:
|
||||
case bnez_op:
|
||||
jump_addr = cur_pc + sign_extend((si_h << 16 | si_l) << 2, 22);
|
||||
if (in_alt_jump(jump_addr, start, end))
|
||||
return;
|
||||
offset = jump_addr - pc;
|
||||
BUG_ON(offset < -SZ_4M || offset >= SZ_4M);
|
||||
offset >>= 2;
|
||||
buf->reg1i21_format.immediate_h = offset >> 16;
|
||||
buf->reg1i21_format.immediate_l = offset;
|
||||
return;
|
||||
}
|
||||
|
||||
si = src->reg2i16_format.immediate;
|
||||
switch (src->reg2i16_format.opcode) {
|
||||
case beq_op:
|
||||
case bne_op:
|
||||
case blt_op:
|
||||
case bge_op:
|
||||
case bltu_op:
|
||||
case bgeu_op:
|
||||
jump_addr = cur_pc + sign_extend(si << 2, 17);
|
||||
if (in_alt_jump(jump_addr, start, end))
|
||||
return;
|
||||
offset = jump_addr - pc;
|
||||
BUG_ON(offset < -SZ_128K || offset >= SZ_128K);
|
||||
offset >>= 2;
|
||||
buf->reg2i16_format.immediate = offset;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int __init_or_module copy_alt_insns(union loongarch_instruction *buf,
|
||||
union loongarch_instruction *dest, union loongarch_instruction *src, int nr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
buf[i].word = src[i].word;
|
||||
|
||||
if (is_pc_ins(&src[i])) {
|
||||
pr_err("Not support pcrel instruction at present!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (is_branch_ins(&src[i]) &&
|
||||
src[i].reg2i16_format.opcode != jirl_op) {
|
||||
recompute_jump(&buf[i], &dest[i], &src[i], src, src + nr);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* text_poke_early - Update instructions on a live kernel at boot time
|
||||
*
|
||||
* When you use this code to patch more than one byte of an instruction
|
||||
* you need to make sure that other CPUs cannot execute this code in parallel.
|
||||
* Also no thread must be currently preempted in the middle of these
|
||||
* instructions. And on the local CPU you need to be protected again NMI or MCE
|
||||
* handlers seeing an inconsistent instruction while you patch.
|
||||
*/
|
||||
static void *__init_or_module text_poke_early(union loongarch_instruction *insn,
|
||||
union loongarch_instruction *buf, unsigned int nr)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
for (i = 0; i < nr; i++)
|
||||
insn[i].word = buf[i].word;
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
wbflush();
|
||||
flush_icache_range((unsigned long)insn, (unsigned long)(insn + nr));
|
||||
|
||||
return insn;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace instructions with better alternatives for this CPU type. This runs
|
||||
* before SMP is initialized to avoid SMP problems with self modifying code.
|
||||
* This implies that asymmetric systems where APs have less capabilities than
|
||||
* the boot processor are not handled. Tough. Make sure you disable such
|
||||
* features by hand.
|
||||
*/
|
||||
void __init_or_module apply_alternatives(struct alt_instr *start, struct alt_instr *end)
|
||||
{
|
||||
struct alt_instr *a;
|
||||
unsigned int nr_instr, nr_repl, nr_insnbuf;
|
||||
union loongarch_instruction *instr, *replacement;
|
||||
union loongarch_instruction insnbuf[MAX_PATCH_SIZE];
|
||||
|
||||
DPRINTK("alt table %px, -> %px", start, end);
|
||||
/*
|
||||
* The scan order should be from start to end. A later scanned
|
||||
* alternative code can overwrite previously scanned alternative code.
|
||||
* Some kernel functions (e.g. memcpy, memset, etc) use this order to
|
||||
* patch code.
|
||||
*
|
||||
* So be careful if you want to change the scan order to any other
|
||||
* order.
|
||||
*/
|
||||
for (a = start; a < end; a++) {
|
||||
nr_insnbuf = 0;
|
||||
|
||||
instr = (void *)&a->instr_offset + a->instr_offset;
|
||||
replacement = (void *)&a->replace_offset + a->replace_offset;
|
||||
|
||||
BUG_ON(a->instrlen > sizeof(insnbuf));
|
||||
BUG_ON(a->instrlen & 0x3);
|
||||
BUG_ON(a->replacementlen & 0x3);
|
||||
|
||||
nr_instr = a->instrlen / LOONGARCH_INSN_SIZE;
|
||||
nr_repl = a->replacementlen / LOONGARCH_INSN_SIZE;
|
||||
|
||||
if (!cpu_has(a->feature)) {
|
||||
DPRINTK("feat not exist: %d, old: (%px len: %d), repl: (%px, len: %d)",
|
||||
a->feature, instr, a->instrlen,
|
||||
replacement, a->replacementlen);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
DPRINTK("feat: %d, old: (%px len: %d), repl: (%px, len: %d)",
|
||||
a->feature, instr, a->instrlen,
|
||||
replacement, a->replacementlen);
|
||||
|
||||
DUMP_WORDS(instr, nr_instr, "%px: old_insn: ", instr);
|
||||
DUMP_WORDS(replacement, nr_repl, "%px: rpl_insn: ", replacement);
|
||||
|
||||
copy_alt_insns(insnbuf, instr, replacement, nr_repl);
|
||||
nr_insnbuf = nr_repl;
|
||||
|
||||
if (nr_instr > nr_repl) {
|
||||
add_nops(insnbuf + nr_repl, nr_instr - nr_repl);
|
||||
nr_insnbuf += nr_instr - nr_repl;
|
||||
}
|
||||
DUMP_WORDS(insnbuf, nr_insnbuf, "%px: final_insn: ", instr);
|
||||
|
||||
text_poke_early(instr, insnbuf, nr_insnbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void __init alternative_instructions(void)
|
||||
{
|
||||
apply_alternatives(__alt_instructions, __alt_instructions_end);
|
||||
|
||||
alternatives_patched = 1;
|
||||
}
|
|
@ -68,6 +68,9 @@ void output_task_defines(void)
|
|||
OFFSET(TASK_FLAGS, task_struct, flags);
|
||||
OFFSET(TASK_MM, task_struct, mm);
|
||||
OFFSET(TASK_PID, task_struct, pid);
|
||||
#if defined(CONFIG_STACKPROTECTOR)
|
||||
OFFSET(TASK_STACK_CANARY, task_struct, stack_canary);
|
||||
#endif
|
||||
DEFINE(TASK_STRUCT_SIZE, sizeof(struct task_struct));
|
||||
BLANK();
|
||||
}
|
||||
|
@ -257,3 +260,15 @@ void output_smpboot_defines(void)
|
|||
BLANK();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HIBERNATION
|
||||
void output_pbe_defines(void)
|
||||
{
|
||||
COMMENT(" Linux struct pbe offsets. ");
|
||||
OFFSET(PBE_ADDRESS, pbe, address);
|
||||
OFFSET(PBE_ORIG_ADDRESS, pbe, orig_address);
|
||||
OFFSET(PBE_NEXT, pbe, next);
|
||||
DEFINE(PBE_SIZE, sizeof(struct pbe));
|
||||
BLANK();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -28,16 +28,29 @@ static unsigned long efi_nr_tables;
|
|||
static unsigned long efi_config_table;
|
||||
|
||||
static unsigned long __initdata boot_memmap = EFI_INVALID_TABLE_ADDR;
|
||||
static unsigned long __initdata fdt_pointer = EFI_INVALID_TABLE_ADDR;
|
||||
|
||||
static efi_system_table_t *efi_systab;
|
||||
static efi_config_table_type_t arch_tables[] __initdata = {
|
||||
{LINUX_EFI_BOOT_MEMMAP_GUID, &boot_memmap, "MEMMAP" },
|
||||
{DEVICE_TREE_GUID, &fdt_pointer, "FDTPTR" },
|
||||
{},
|
||||
};
|
||||
|
||||
void __init *efi_fdt_pointer(void)
|
||||
{
|
||||
if (!efi_systab)
|
||||
return NULL;
|
||||
|
||||
if (fdt_pointer == EFI_INVALID_TABLE_ADDR)
|
||||
return NULL;
|
||||
|
||||
return early_memremap_ro(fdt_pointer, SZ_64K);
|
||||
}
|
||||
|
||||
void __init efi_runtime_init(void)
|
||||
{
|
||||
if (!efi_enabled(EFI_BOOT))
|
||||
if (!efi_enabled(EFI_BOOT) || !efi_systab->runtime)
|
||||
return;
|
||||
|
||||
if (efi_runtime_disabled()) {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <asm/early_ioremap.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/loongson.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
u64 efi_system_table;
|
||||
struct loongson_system_configuration loongson_sysconf;
|
||||
|
@ -27,6 +28,7 @@ void __init init_environ(void)
|
|||
clear_bit(EFI_BOOT, &efi.flags);
|
||||
|
||||
strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE);
|
||||
strscpy(init_command_line, cmdline, COMMAND_LINE_SIZE);
|
||||
early_memunmap(cmdline, COMMAND_LINE_SIZE);
|
||||
|
||||
efi_system_table = fw_arg2;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
*/
|
||||
#include <asm/asm.h>
|
||||
#include <asm/asmmacro.h>
|
||||
#include <asm/asm-extable.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/export.h>
|
||||
|
@ -21,9 +22,7 @@
|
|||
|
||||
.macro EX insn, reg, src, offs
|
||||
.ex\@: \insn \reg, \src, \offs
|
||||
.section __ex_table,"a"
|
||||
PTR .ex\@, fault
|
||||
.previous
|
||||
_asm_extable .ex\@, fault
|
||||
.endm
|
||||
|
||||
.macro sc_save_fp base
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/asm.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/inst.h>
|
||||
#include <asm/loongarch.h>
|
||||
#include <asm/syscall.h>
|
||||
|
||||
#include <asm-generic/sections.h>
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
|
||||
/*
|
||||
* As `call _mcount` follows LoongArch psABI, ra-saved operation and
|
||||
* stack operation can be found before this insn.
|
||||
*/
|
||||
|
||||
static int ftrace_get_parent_ra_addr(unsigned long insn_addr, int *ra_off)
|
||||
{
|
||||
int limit = 32;
|
||||
union loongarch_instruction *insn;
|
||||
|
||||
insn = (union loongarch_instruction *)insn_addr;
|
||||
|
||||
do {
|
||||
insn--;
|
||||
limit--;
|
||||
|
||||
if (is_ra_save_ins(insn))
|
||||
*ra_off = -((1 << 12) - insn->reg2i12_format.immediate);
|
||||
|
||||
} while (!is_stack_alloc_ins(insn) && limit);
|
||||
|
||||
if (!limit)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void prepare_ftrace_return(unsigned long self_addr,
|
||||
unsigned long callsite_sp, unsigned long old)
|
||||
{
|
||||
int ra_off;
|
||||
unsigned long return_hooker = (unsigned long)&return_to_handler;
|
||||
|
||||
if (unlikely(ftrace_graph_is_dead()))
|
||||
return;
|
||||
|
||||
if (unlikely(atomic_read(¤t->tracing_graph_pause)))
|
||||
return;
|
||||
|
||||
if (ftrace_get_parent_ra_addr(self_addr, &ra_off))
|
||||
goto out;
|
||||
|
||||
if (!function_graph_enter(old, self_addr, 0, NULL))
|
||||
*(unsigned long *)(callsite_sp + ra_off) = return_hooker;
|
||||
|
||||
return;
|
||||
|
||||
out:
|
||||
ftrace_graph_stop();
|
||||
WARN_ON(1);
|
||||
}
|
||||
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
|
|
@ -0,0 +1,273 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Based on arch/arm64/kernel/ftrace.c
|
||||
*
|
||||
* Copyright (C) 2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/inst.h>
|
||||
#include <asm/module.h>
|
||||
|
||||
static int ftrace_modify_code(unsigned long pc, u32 old, u32 new, bool validate)
|
||||
{
|
||||
u32 replaced;
|
||||
|
||||
if (validate) {
|
||||
if (larch_insn_read((void *)pc, &replaced))
|
||||
return -EFAULT;
|
||||
|
||||
if (replaced != old)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (larch_insn_patch_text((void *)pc, new))
|
||||
return -EPERM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
static inline int __get_mod(struct module **mod, unsigned long addr)
|
||||
{
|
||||
preempt_disable();
|
||||
*mod = __module_text_address(addr);
|
||||
preempt_enable();
|
||||
|
||||
if (WARN_ON(!(*mod)))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct plt_entry *get_ftrace_plt(struct module *mod, unsigned long addr)
|
||||
{
|
||||
struct plt_entry *plt = mod->arch.ftrace_trampolines;
|
||||
|
||||
if (addr == FTRACE_ADDR)
|
||||
return &plt[FTRACE_PLT_IDX];
|
||||
if (addr == FTRACE_REGS_ADDR &&
|
||||
IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS))
|
||||
return &plt[FTRACE_REGS_PLT_IDX];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static unsigned long get_plt_addr(struct module *mod, unsigned long addr)
|
||||
{
|
||||
struct plt_entry *plt;
|
||||
|
||||
plt = get_ftrace_plt(mod, addr);
|
||||
if (!plt) {
|
||||
pr_err("ftrace: no module PLT for %ps\n", (void *)addr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return (unsigned long)plt;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, unsigned long addr)
|
||||
{
|
||||
u32 old, new;
|
||||
unsigned long pc;
|
||||
long offset __maybe_unused;
|
||||
|
||||
pc = rec->ip + LOONGARCH_INSN_SIZE;
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
offset = (long)pc - (long)addr;
|
||||
|
||||
if (offset < -SZ_128M || offset >= SZ_128M) {
|
||||
int ret;
|
||||
struct module *mod;
|
||||
|
||||
ret = __get_mod(&mod, pc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
addr = get_plt_addr(mod, addr);
|
||||
|
||||
old_addr = get_plt_addr(mod, old_addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
new = larch_insn_gen_bl(pc, addr);
|
||||
old = larch_insn_gen_bl(pc, old_addr);
|
||||
|
||||
return ftrace_modify_code(pc, old, new, true);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */
|
||||
|
||||
int ftrace_update_ftrace_func(ftrace_func_t func)
|
||||
{
|
||||
u32 new;
|
||||
unsigned long pc;
|
||||
|
||||
pc = (unsigned long)&ftrace_call;
|
||||
new = larch_insn_gen_bl(pc, (unsigned long)func);
|
||||
|
||||
return ftrace_modify_code(pc, 0, new, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* The compiler has inserted 2 NOPs before the regular function prologue.
|
||||
* T series registers are available and safe because of LoongArch's psABI.
|
||||
*
|
||||
* At runtime, we can replace nop with bl to enable ftrace call and replace bl
|
||||
* with nop to disable ftrace call. The bl requires us to save the original RA
|
||||
* value, so it saves RA at t0 here.
|
||||
*
|
||||
* Details are:
|
||||
*
|
||||
* | Compiled | Disabled | Enabled |
|
||||
* +------------+------------------------+------------------------+
|
||||
* | nop | move t0, ra | move t0, ra |
|
||||
* | nop | nop | bl ftrace_caller |
|
||||
* | func_body | func_body | func_body |
|
||||
*
|
||||
* The RA value will be recovered by ftrace_regs_entry, and restored into RA
|
||||
* before returning to the regular function prologue. When a function is not
|
||||
* being traced, the "move t0, ra" is not harmful.
|
||||
*/
|
||||
|
||||
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
|
||||
{
|
||||
u32 old, new;
|
||||
unsigned long pc;
|
||||
|
||||
pc = rec->ip;
|
||||
old = larch_insn_gen_nop();
|
||||
new = larch_insn_gen_move(LOONGARCH_GPR_T0, LOONGARCH_GPR_RA);
|
||||
|
||||
return ftrace_modify_code(pc, old, new, true);
|
||||
}
|
||||
|
||||
int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
|
||||
{
|
||||
u32 old, new;
|
||||
unsigned long pc;
|
||||
long offset __maybe_unused;
|
||||
|
||||
pc = rec->ip + LOONGARCH_INSN_SIZE;
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
offset = (long)pc - (long)addr;
|
||||
|
||||
if (offset < -SZ_128M || offset >= SZ_128M) {
|
||||
int ret;
|
||||
struct module *mod;
|
||||
|
||||
ret = __get_mod(&mod, pc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
addr = get_plt_addr(mod, addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
old = larch_insn_gen_nop();
|
||||
new = larch_insn_gen_bl(pc, addr);
|
||||
|
||||
return ftrace_modify_code(pc, old, new, true);
|
||||
}
|
||||
|
||||
int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr)
|
||||
{
|
||||
u32 old, new;
|
||||
unsigned long pc;
|
||||
long offset __maybe_unused;
|
||||
|
||||
pc = rec->ip + LOONGARCH_INSN_SIZE;
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
offset = (long)pc - (long)addr;
|
||||
|
||||
if (offset < -SZ_128M || offset >= SZ_128M) {
|
||||
int ret;
|
||||
struct module *mod;
|
||||
|
||||
ret = __get_mod(&mod, pc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
addr = get_plt_addr(mod, addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
new = larch_insn_gen_nop();
|
||||
old = larch_insn_gen_bl(pc, addr);
|
||||
|
||||
return ftrace_modify_code(pc, old, new, true);
|
||||
}
|
||||
|
||||
void arch_ftrace_update_code(int command)
|
||||
{
|
||||
command |= FTRACE_MAY_SLEEP;
|
||||
ftrace_modify_all_code(command);
|
||||
}
|
||||
|
||||
int __init ftrace_dyn_arch_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent)
|
||||
{
|
||||
unsigned long old;
|
||||
unsigned long return_hooker = (unsigned long)&return_to_handler;
|
||||
|
||||
if (unlikely(atomic_read(¤t->tracing_graph_pause)))
|
||||
return;
|
||||
|
||||
old = *parent;
|
||||
|
||||
if (!function_graph_enter(old, self_addr, 0, parent))
|
||||
*parent = return_hooker;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
|
||||
void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
|
||||
struct ftrace_ops *op, struct ftrace_regs *fregs)
|
||||
{
|
||||
struct pt_regs *regs = &fregs->regs;
|
||||
unsigned long *parent = (unsigned long *)®s->regs[1];
|
||||
|
||||
prepare_ftrace_return(ip, (unsigned long *)parent);
|
||||
}
|
||||
#else
|
||||
static int ftrace_modify_graph_caller(bool enable)
|
||||
{
|
||||
u32 branch, nop;
|
||||
unsigned long pc, func;
|
||||
extern void ftrace_graph_call(void);
|
||||
|
||||
pc = (unsigned long)&ftrace_graph_call;
|
||||
func = (unsigned long)&ftrace_graph_caller;
|
||||
|
||||
nop = larch_insn_gen_nop();
|
||||
branch = larch_insn_gen_b(pc, func);
|
||||
|
||||
if (enable)
|
||||
return ftrace_modify_code(pc, nop, branch, true);
|
||||
else
|
||||
return ftrace_modify_code(pc, branch, nop, true);
|
||||
}
|
||||
|
||||
int ftrace_enable_ftrace_graph_caller(void)
|
||||
{
|
||||
return ftrace_modify_graph_caller(true);
|
||||
}
|
||||
|
||||
int ftrace_disable_ftrace_graph_caller(void)
|
||||
{
|
||||
return ftrace_modify_graph_caller(false);
|
||||
}
|
||||
#endif /* CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS */
|
||||
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
|
|
@ -2,8 +2,135 @@
|
|||
/*
|
||||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/inst.h>
|
||||
|
||||
static DEFINE_RAW_SPINLOCK(patch_lock);
|
||||
|
||||
int larch_insn_read(void *addr, u32 *insnp)
|
||||
{
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
ret = copy_from_kernel_nofault(&val, addr, LOONGARCH_INSN_SIZE);
|
||||
if (!ret)
|
||||
*insnp = val;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int larch_insn_write(void *addr, u32 insn)
|
||||
{
|
||||
int ret;
|
||||
unsigned long flags = 0;
|
||||
|
||||
raw_spin_lock_irqsave(&patch_lock, flags);
|
||||
ret = copy_to_kernel_nofault(addr, &insn, LOONGARCH_INSN_SIZE);
|
||||
raw_spin_unlock_irqrestore(&patch_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int larch_insn_patch_text(void *addr, u32 insn)
|
||||
{
|
||||
int ret;
|
||||
u32 *tp = addr;
|
||||
|
||||
if ((unsigned long)tp & 3)
|
||||
return -EINVAL;
|
||||
|
||||
ret = larch_insn_write(tp, insn);
|
||||
if (!ret)
|
||||
flush_icache_range((unsigned long)tp,
|
||||
(unsigned long)tp + LOONGARCH_INSN_SIZE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 larch_insn_gen_nop(void)
|
||||
{
|
||||
return INSN_NOP;
|
||||
}
|
||||
|
||||
u32 larch_insn_gen_b(unsigned long pc, unsigned long dest)
|
||||
{
|
||||
long offset = dest - pc;
|
||||
unsigned int immediate_l, immediate_h;
|
||||
union loongarch_instruction insn;
|
||||
|
||||
if ((offset & 3) || offset < -SZ_128M || offset >= SZ_128M) {
|
||||
pr_warn("The generated b instruction is out of range.\n");
|
||||
return INSN_BREAK;
|
||||
}
|
||||
|
||||
offset >>= 2;
|
||||
|
||||
immediate_l = offset & 0xffff;
|
||||
offset >>= 16;
|
||||
immediate_h = offset & 0x3ff;
|
||||
|
||||
insn.reg0i26_format.opcode = b_op;
|
||||
insn.reg0i26_format.immediate_l = immediate_l;
|
||||
insn.reg0i26_format.immediate_h = immediate_h;
|
||||
|
||||
return insn.word;
|
||||
}
|
||||
|
||||
u32 larch_insn_gen_bl(unsigned long pc, unsigned long dest)
|
||||
{
|
||||
long offset = dest - pc;
|
||||
unsigned int immediate_l, immediate_h;
|
||||
union loongarch_instruction insn;
|
||||
|
||||
if ((offset & 3) || offset < -SZ_128M || offset >= SZ_128M) {
|
||||
pr_warn("The generated bl instruction is out of range.\n");
|
||||
return INSN_BREAK;
|
||||
}
|
||||
|
||||
offset >>= 2;
|
||||
|
||||
immediate_l = offset & 0xffff;
|
||||
offset >>= 16;
|
||||
immediate_h = offset & 0x3ff;
|
||||
|
||||
insn.reg0i26_format.opcode = bl_op;
|
||||
insn.reg0i26_format.immediate_l = immediate_l;
|
||||
insn.reg0i26_format.immediate_h = immediate_h;
|
||||
|
||||
return insn.word;
|
||||
}
|
||||
|
||||
u32 larch_insn_gen_or(enum loongarch_gpr rd, enum loongarch_gpr rj, enum loongarch_gpr rk)
|
||||
{
|
||||
union loongarch_instruction insn;
|
||||
|
||||
insn.reg3_format.opcode = or_op;
|
||||
insn.reg3_format.rd = rd;
|
||||
insn.reg3_format.rj = rj;
|
||||
insn.reg3_format.rk = rk;
|
||||
|
||||
return insn.word;
|
||||
}
|
||||
|
||||
u32 larch_insn_gen_move(enum loongarch_gpr rd, enum loongarch_gpr rj)
|
||||
{
|
||||
return larch_insn_gen_or(rd, rj, 0);
|
||||
}
|
||||
|
||||
u32 larch_insn_gen_lu12iw(enum loongarch_gpr rd, int imm)
|
||||
{
|
||||
union loongarch_instruction insn;
|
||||
|
||||
insn.reg1i20_format.opcode = lu12iw_op;
|
||||
insn.reg1i20_format.rd = rd;
|
||||
insn.reg1i20_format.immediate = imm;
|
||||
|
||||
return insn.word;
|
||||
}
|
||||
|
||||
u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm)
|
||||
{
|
||||
union loongarch_instruction insn;
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* LoongArch specific _mcount support
|
||||
*
|
||||
* Copyright (C) 2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
|
||||
#include <asm/export.h>
|
||||
#include <asm/ftrace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
.text
|
||||
|
||||
#define MCOUNT_S0_OFFSET (0)
|
||||
#define MCOUNT_RA_OFFSET (SZREG)
|
||||
#define MCOUNT_STACK_SIZE (2 * SZREG)
|
||||
|
||||
.macro MCOUNT_SAVE_REGS
|
||||
PTR_ADDI sp, sp, -MCOUNT_STACK_SIZE
|
||||
PTR_S s0, sp, MCOUNT_S0_OFFSET
|
||||
PTR_S ra, sp, MCOUNT_RA_OFFSET
|
||||
move s0, a0
|
||||
.endm
|
||||
|
||||
.macro MCOUNT_RESTORE_REGS
|
||||
move a0, s0
|
||||
PTR_L ra, sp, MCOUNT_RA_OFFSET
|
||||
PTR_L s0, sp, MCOUNT_S0_OFFSET
|
||||
PTR_ADDI sp, sp, MCOUNT_STACK_SIZE
|
||||
.endm
|
||||
|
||||
SYM_FUNC_START(_mcount)
|
||||
la.pcrel t1, ftrace_stub
|
||||
la.pcrel t2, ftrace_trace_function /* Prepare t2 for (1) */
|
||||
PTR_L t2, t2, 0
|
||||
beq t1, t2, fgraph_trace
|
||||
|
||||
MCOUNT_SAVE_REGS
|
||||
|
||||
move a0, ra /* arg0: self return address */
|
||||
move a1, s0 /* arg1: parent's return address */
|
||||
jirl ra, t2, 0 /* (1) call *ftrace_trace_function */
|
||||
|
||||
MCOUNT_RESTORE_REGS
|
||||
|
||||
fgraph_trace:
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
la.pcrel t1, ftrace_stub
|
||||
la.pcrel t3, ftrace_graph_return
|
||||
PTR_L t3, t3, 0
|
||||
bne t1, t3, ftrace_graph_caller
|
||||
la.pcrel t1, ftrace_graph_entry_stub
|
||||
la.pcrel t3, ftrace_graph_entry
|
||||
PTR_L t3, t3, 0
|
||||
bne t1, t3, ftrace_graph_caller
|
||||
#endif
|
||||
|
||||
SYM_INNER_LABEL(ftrace_stub, SYM_L_GLOBAL)
|
||||
jr ra
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
SYM_INNER_LABEL(ftrace_graph_func, SYM_L_GLOBAL)
|
||||
bl ftrace_stub
|
||||
#endif
|
||||
SYM_FUNC_END(_mcount)
|
||||
EXPORT_SYMBOL(_mcount)
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
SYM_FUNC_START(ftrace_graph_caller)
|
||||
MCOUNT_SAVE_REGS
|
||||
|
||||
PTR_ADDI a0, ra, -4 /* arg0: Callsite self return addr */
|
||||
PTR_ADDI a1, sp, MCOUNT_STACK_SIZE /* arg1: Callsite sp */
|
||||
move a2, s0 /* arg2: Callsite parent ra */
|
||||
bl prepare_ftrace_return
|
||||
|
||||
MCOUNT_RESTORE_REGS
|
||||
jr ra
|
||||
SYM_FUNC_END(ftrace_graph_caller)
|
||||
|
||||
SYM_FUNC_START(return_to_handler)
|
||||
PTR_ADDI sp, sp, -2 * SZREG
|
||||
PTR_S a0, sp, 0
|
||||
PTR_S a1, sp, SZREG
|
||||
|
||||
bl ftrace_return_to_handler
|
||||
|
||||
/* Restore the real parent address: a0 -> ra */
|
||||
move ra, a0
|
||||
|
||||
PTR_L a0, sp, 0
|
||||
PTR_L a1, sp, SZREG
|
||||
PTR_ADDI sp, sp, 2 * SZREG
|
||||
jr ra
|
||||
SYM_FUNC_END(return_to_handler)
|
||||
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
|
|
@ -0,0 +1,149 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
|
||||
#include <asm/export.h>
|
||||
#include <asm/ftrace.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/stackframe.h>
|
||||
|
||||
.text
|
||||
/*
|
||||
* Due to -fpatchable-function-entry=2: the compiler inserted 2 NOPs before the
|
||||
* regular C function prologue. When PC arrived here, the last 2 instructions
|
||||
* are as follows:
|
||||
* move t0, ra
|
||||
* bl callsite (for modules, callsite is a tramplione)
|
||||
*
|
||||
* modules trampoline is as follows:
|
||||
* lu12i.w t1, callsite[31:12]
|
||||
* lu32i.d t1, callsite[51:32]
|
||||
* lu52i.d t1, t1, callsite[63:52]
|
||||
* jirl zero, t1, callsite[11:0] >> 2
|
||||
*
|
||||
* See arch/loongarch/kernel/ftrace_dyn.c for details. Here, pay attention to
|
||||
* that the T series regs are available and safe because each C functions
|
||||
* follows the LoongArch's psABI as well.
|
||||
*/
|
||||
|
||||
.macro ftrace_regs_entry allregs=0
|
||||
PTR_ADDI sp, sp, -PT_SIZE
|
||||
PTR_S t0, sp, PT_R1 /* Save parent ra at PT_R1(RA) */
|
||||
PTR_S a0, sp, PT_R4
|
||||
PTR_S a1, sp, PT_R5
|
||||
PTR_S a2, sp, PT_R6
|
||||
PTR_S a3, sp, PT_R7
|
||||
PTR_S a4, sp, PT_R8
|
||||
PTR_S a5, sp, PT_R9
|
||||
PTR_S a6, sp, PT_R10
|
||||
PTR_S a7, sp, PT_R11
|
||||
PTR_S fp, sp, PT_R22
|
||||
.if \allregs
|
||||
PTR_S tp, sp, PT_R2
|
||||
PTR_S t0, sp, PT_R12
|
||||
PTR_S t1, sp, PT_R13
|
||||
PTR_S t2, sp, PT_R14
|
||||
PTR_S t3, sp, PT_R15
|
||||
PTR_S t4, sp, PT_R16
|
||||
PTR_S t5, sp, PT_R17
|
||||
PTR_S t6, sp, PT_R18
|
||||
PTR_S t7, sp, PT_R19
|
||||
PTR_S t8, sp, PT_R20
|
||||
PTR_S u0, sp, PT_R21
|
||||
PTR_S s0, sp, PT_R23
|
||||
PTR_S s1, sp, PT_R24
|
||||
PTR_S s2, sp, PT_R25
|
||||
PTR_S s3, sp, PT_R26
|
||||
PTR_S s4, sp, PT_R27
|
||||
PTR_S s5, sp, PT_R28
|
||||
PTR_S s6, sp, PT_R29
|
||||
PTR_S s7, sp, PT_R30
|
||||
PTR_S s8, sp, PT_R31
|
||||
/* Clear it for later use as a flag sometimes. */
|
||||
PTR_S zero, sp, PT_R0
|
||||
.endif
|
||||
PTR_S ra, sp, PT_ERA /* Save trace function ra at PT_ERA */
|
||||
PTR_ADDI t8, sp, PT_SIZE
|
||||
PTR_S t8, sp, PT_R3
|
||||
.endm
|
||||
|
||||
SYM_FUNC_START(ftrace_stub)
|
||||
jr ra
|
||||
SYM_FUNC_END(ftrace_stub)
|
||||
|
||||
SYM_CODE_START(ftrace_common)
|
||||
PTR_ADDI a0, ra, -8 /* arg0: ip */
|
||||
move a1, t0 /* arg1: parent_ip */
|
||||
la.pcrel t1, function_trace_op
|
||||
PTR_L a2, t1, 0 /* arg2: op */
|
||||
move a3, sp /* arg3: regs */
|
||||
|
||||
SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
|
||||
bl ftrace_stub
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL)
|
||||
nop /* b ftrace_graph_caller */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* As we didn't use S series regs in this assmembly code and all calls
|
||||
* are C function which will save S series regs by themselves, there is
|
||||
* no need to restore S series regs. The T series is available and safe
|
||||
* at the callsite, so there is no need to restore the T series regs.
|
||||
*/
|
||||
ftrace_common_return:
|
||||
PTR_L ra, sp, PT_R1
|
||||
PTR_L a0, sp, PT_R4
|
||||
PTR_L a1, sp, PT_R5
|
||||
PTR_L a2, sp, PT_R6
|
||||
PTR_L a3, sp, PT_R7
|
||||
PTR_L a4, sp, PT_R8
|
||||
PTR_L a5, sp, PT_R9
|
||||
PTR_L a6, sp, PT_R10
|
||||
PTR_L a7, sp, PT_R11
|
||||
PTR_L fp, sp, PT_R22
|
||||
PTR_L t0, sp, PT_ERA
|
||||
PTR_ADDI sp, sp, PT_SIZE
|
||||
jr t0
|
||||
SYM_CODE_END(ftrace_common)
|
||||
|
||||
SYM_CODE_START(ftrace_caller)
|
||||
ftrace_regs_entry allregs=0
|
||||
b ftrace_common
|
||||
SYM_CODE_END(ftrace_caller)
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
|
||||
SYM_CODE_START(ftrace_regs_caller)
|
||||
ftrace_regs_entry allregs=1
|
||||
b ftrace_common
|
||||
SYM_CODE_END(ftrace_regs_caller)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
SYM_CODE_START(ftrace_graph_caller)
|
||||
PTR_L a0, sp, PT_ERA
|
||||
PTR_ADDI a0, a0, -8 /* arg0: self_addr */
|
||||
PTR_ADDI a1, sp, PT_R1 /* arg1: parent */
|
||||
bl prepare_ftrace_return
|
||||
b ftrace_common_return
|
||||
SYM_CODE_END(ftrace_graph_caller)
|
||||
|
||||
SYM_CODE_START(return_to_handler)
|
||||
/* Save return value regs */
|
||||
PTR_ADDI sp, sp, -2 * SZREG
|
||||
PTR_S a0, sp, 0
|
||||
PTR_S a1, sp, SZREG
|
||||
|
||||
move a0, zero
|
||||
bl ftrace_return_to_handler
|
||||
move ra, a0
|
||||
|
||||
/* Restore return value regs */
|
||||
PTR_L a0, sp, 0
|
||||
PTR_L a1, sp, SZREG
|
||||
PTR_ADDI sp, sp, 2 * SZREG
|
||||
|
||||
jr ra
|
||||
SYM_CODE_END(return_to_handler)
|
||||
#endif
|
|
@ -6,18 +6,19 @@
|
|||
#include <linux/elf.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ftrace.h>
|
||||
|
||||
Elf_Addr module_emit_got_entry(struct module *mod, Elf_Addr val)
|
||||
Elf_Addr module_emit_got_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val)
|
||||
{
|
||||
struct mod_section *got_sec = &mod->arch.got;
|
||||
int i = got_sec->num_entries;
|
||||
struct got_entry *got = get_got_entry(val, got_sec);
|
||||
struct got_entry *got = get_got_entry(val, sechdrs, got_sec);
|
||||
|
||||
if (got)
|
||||
return (Elf_Addr)got;
|
||||
|
||||
/* There is no GOT entry for val yet, create a new one. */
|
||||
got = (struct got_entry *)got_sec->shdr->sh_addr;
|
||||
got = (struct got_entry *)sechdrs[got_sec->shndx].sh_addr;
|
||||
got[i] = emit_got_entry(val);
|
||||
|
||||
got_sec->num_entries++;
|
||||
|
@ -33,12 +34,12 @@ Elf_Addr module_emit_got_entry(struct module *mod, Elf_Addr val)
|
|||
return (Elf_Addr)&got[i];
|
||||
}
|
||||
|
||||
Elf_Addr module_emit_plt_entry(struct module *mod, Elf_Addr val)
|
||||
Elf_Addr module_emit_plt_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val)
|
||||
{
|
||||
int nr;
|
||||
struct mod_section *plt_sec = &mod->arch.plt;
|
||||
struct mod_section *plt_idx_sec = &mod->arch.plt_idx;
|
||||
struct plt_entry *plt = get_plt_entry(val, plt_sec, plt_idx_sec);
|
||||
struct plt_entry *plt = get_plt_entry(val, sechdrs, plt_sec, plt_idx_sec);
|
||||
struct plt_idx_entry *plt_idx;
|
||||
|
||||
if (plt)
|
||||
|
@ -47,9 +48,9 @@ Elf_Addr module_emit_plt_entry(struct module *mod, Elf_Addr val)
|
|||
nr = plt_sec->num_entries;
|
||||
|
||||
/* There is no duplicate entry, create a new one */
|
||||
plt = (struct plt_entry *)plt_sec->shdr->sh_addr;
|
||||
plt = (struct plt_entry *)sechdrs[plt_sec->shndx].sh_addr;
|
||||
plt[nr] = emit_plt_entry(val);
|
||||
plt_idx = (struct plt_idx_entry *)plt_idx_sec->shdr->sh_addr;
|
||||
plt_idx = (struct plt_idx_entry *)sechdrs[plt_idx_sec->shndx].sh_addr;
|
||||
plt_idx[nr] = emit_plt_idx_entry(val);
|
||||
|
||||
plt_sec->num_entries++;
|
||||
|
@ -103,28 +104,31 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
|
|||
char *secstrings, struct module *mod)
|
||||
{
|
||||
unsigned int i, num_plts = 0, num_gots = 0;
|
||||
Elf_Shdr *got_sec, *plt_sec, *plt_idx_sec, *tramp = NULL;
|
||||
|
||||
/*
|
||||
* Find the empty .plt sections.
|
||||
*/
|
||||
for (i = 0; i < ehdr->e_shnum; i++) {
|
||||
if (!strcmp(secstrings + sechdrs[i].sh_name, ".got"))
|
||||
mod->arch.got.shdr = sechdrs + i;
|
||||
mod->arch.got.shndx = i;
|
||||
else if (!strcmp(secstrings + sechdrs[i].sh_name, ".plt"))
|
||||
mod->arch.plt.shdr = sechdrs + i;
|
||||
mod->arch.plt.shndx = i;
|
||||
else if (!strcmp(secstrings + sechdrs[i].sh_name, ".plt.idx"))
|
||||
mod->arch.plt_idx.shdr = sechdrs + i;
|
||||
mod->arch.plt_idx.shndx = i;
|
||||
else if (!strcmp(secstrings + sechdrs[i].sh_name, ".ftrace_trampoline"))
|
||||
tramp = sechdrs + i;
|
||||
}
|
||||
|
||||
if (!mod->arch.got.shdr) {
|
||||
if (!mod->arch.got.shndx) {
|
||||
pr_err("%s: module GOT section(s) missing\n", mod->name);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
if (!mod->arch.plt.shdr) {
|
||||
if (!mod->arch.plt.shndx) {
|
||||
pr_err("%s: module PLT section(s) missing\n", mod->name);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
if (!mod->arch.plt_idx.shdr) {
|
||||
if (!mod->arch.plt_idx.shndx) {
|
||||
pr_err("%s: module PLT.IDX section(s) missing\n", mod->name);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
@ -145,26 +149,36 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
|
|||
count_max_entries(relas, num_rela, &num_plts, &num_gots);
|
||||
}
|
||||
|
||||
mod->arch.got.shdr->sh_type = SHT_NOBITS;
|
||||
mod->arch.got.shdr->sh_flags = SHF_ALLOC;
|
||||
mod->arch.got.shdr->sh_addralign = L1_CACHE_BYTES;
|
||||
mod->arch.got.shdr->sh_size = (num_gots + 1) * sizeof(struct got_entry);
|
||||
got_sec = sechdrs + mod->arch.got.shndx;
|
||||
got_sec->sh_type = SHT_NOBITS;
|
||||
got_sec->sh_flags = SHF_ALLOC;
|
||||
got_sec->sh_addralign = L1_CACHE_BYTES;
|
||||
got_sec->sh_size = (num_gots + 1) * sizeof(struct got_entry);
|
||||
mod->arch.got.num_entries = 0;
|
||||
mod->arch.got.max_entries = num_gots;
|
||||
|
||||
mod->arch.plt.shdr->sh_type = SHT_NOBITS;
|
||||
mod->arch.plt.shdr->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
|
||||
mod->arch.plt.shdr->sh_addralign = L1_CACHE_BYTES;
|
||||
mod->arch.plt.shdr->sh_size = (num_plts + 1) * sizeof(struct plt_entry);
|
||||
plt_sec = sechdrs + mod->arch.plt.shndx;
|
||||
plt_sec->sh_type = SHT_NOBITS;
|
||||
plt_sec->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
|
||||
plt_sec->sh_addralign = L1_CACHE_BYTES;
|
||||
plt_sec->sh_size = (num_plts + 1) * sizeof(struct plt_entry);
|
||||
mod->arch.plt.num_entries = 0;
|
||||
mod->arch.plt.max_entries = num_plts;
|
||||
|
||||
mod->arch.plt_idx.shdr->sh_type = SHT_NOBITS;
|
||||
mod->arch.plt_idx.shdr->sh_flags = SHF_ALLOC;
|
||||
mod->arch.plt_idx.shdr->sh_addralign = L1_CACHE_BYTES;
|
||||
mod->arch.plt_idx.shdr->sh_size = (num_plts + 1) * sizeof(struct plt_idx_entry);
|
||||
plt_idx_sec = sechdrs + mod->arch.plt_idx.shndx;
|
||||
plt_idx_sec->sh_type = SHT_NOBITS;
|
||||
plt_idx_sec->sh_flags = SHF_ALLOC;
|
||||
plt_idx_sec->sh_addralign = L1_CACHE_BYTES;
|
||||
plt_idx_sec->sh_size = (num_plts + 1) * sizeof(struct plt_idx_entry);
|
||||
mod->arch.plt_idx.num_entries = 0;
|
||||
mod->arch.plt_idx.max_entries = num_plts;
|
||||
|
||||
if (tramp) {
|
||||
tramp->sh_type = SHT_NOBITS;
|
||||
tramp->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
|
||||
tramp->sh_addralign = __alignof__(struct plt_entry);
|
||||
tramp->sh_size = NR_FTRACE_PLTS * sizeof(struct plt_entry);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,11 @@
|
|||
#include <linux/vmalloc.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/alternative.h>
|
||||
#include <asm/inst.h>
|
||||
|
||||
static int rela_stack_push(s64 stack_value, s64 *rela_stack, size_t *rela_stack_top)
|
||||
{
|
||||
|
@ -98,16 +101,17 @@ static int apply_r_larch_sop_push_dup(struct module *mod, u32 *location, Elf_Add
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int apply_r_larch_sop_push_plt_pcrel(struct module *mod, u32 *location, Elf_Addr v,
|
||||
static int apply_r_larch_sop_push_plt_pcrel(struct module *mod,
|
||||
Elf_Shdr *sechdrs, u32 *location, Elf_Addr v,
|
||||
s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
|
||||
{
|
||||
ptrdiff_t offset = (void *)v - (void *)location;
|
||||
|
||||
if (offset >= SZ_128M)
|
||||
v = module_emit_plt_entry(mod, v);
|
||||
v = module_emit_plt_entry(mod, sechdrs, v);
|
||||
|
||||
if (offset < -SZ_128M)
|
||||
v = module_emit_plt_entry(mod, v);
|
||||
v = module_emit_plt_entry(mod, sechdrs, v);
|
||||
|
||||
return apply_r_larch_sop_push_pcrel(mod, location, v, rela_stack, rela_stack_top, type);
|
||||
}
|
||||
|
@ -271,17 +275,18 @@ static int apply_r_larch_add_sub(struct module *mod, u32 *location, Elf_Addr v,
|
|||
}
|
||||
}
|
||||
|
||||
static int apply_r_larch_b26(struct module *mod, u32 *location, Elf_Addr v,
|
||||
static int apply_r_larch_b26(struct module *mod,
|
||||
Elf_Shdr *sechdrs, u32 *location, Elf_Addr v,
|
||||
s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
|
||||
{
|
||||
ptrdiff_t offset = (void *)v - (void *)location;
|
||||
union loongarch_instruction *insn = (union loongarch_instruction *)location;
|
||||
|
||||
if (offset >= SZ_128M)
|
||||
v = module_emit_plt_entry(mod, v);
|
||||
v = module_emit_plt_entry(mod, sechdrs, v);
|
||||
|
||||
if (offset < -SZ_128M)
|
||||
v = module_emit_plt_entry(mod, v);
|
||||
v = module_emit_plt_entry(mod, sechdrs, v);
|
||||
|
||||
offset = (void *)v - (void *)location;
|
||||
|
||||
|
@ -338,10 +343,11 @@ static int apply_r_larch_pcala(struct module *mod, u32 *location, Elf_Addr v,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int apply_r_larch_got_pc(struct module *mod, u32 *location, Elf_Addr v,
|
||||
static int apply_r_larch_got_pc(struct module *mod,
|
||||
Elf_Shdr *sechdrs, u32 *location, Elf_Addr v,
|
||||
s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
|
||||
{
|
||||
Elf_Addr got = module_emit_got_entry(mod, v);
|
||||
Elf_Addr got = module_emit_got_entry(mod, sechdrs, v);
|
||||
|
||||
if (!got)
|
||||
return -EINVAL;
|
||||
|
@ -386,13 +392,10 @@ static reloc_rela_handler reloc_rela_handlers[] = {
|
|||
[R_LARCH_SOP_PUSH_PCREL] = apply_r_larch_sop_push_pcrel,
|
||||
[R_LARCH_SOP_PUSH_ABSOLUTE] = apply_r_larch_sop_push_absolute,
|
||||
[R_LARCH_SOP_PUSH_DUP] = apply_r_larch_sop_push_dup,
|
||||
[R_LARCH_SOP_PUSH_PLT_PCREL] = apply_r_larch_sop_push_plt_pcrel,
|
||||
[R_LARCH_SOP_SUB ... R_LARCH_SOP_IF_ELSE] = apply_r_larch_sop,
|
||||
[R_LARCH_SOP_POP_32_S_10_5 ... R_LARCH_SOP_POP_32_U] = apply_r_larch_sop_imm_field,
|
||||
[R_LARCH_ADD32 ... R_LARCH_SUB64] = apply_r_larch_add_sub,
|
||||
[R_LARCH_B26] = apply_r_larch_b26,
|
||||
[R_LARCH_PCALA_HI20...R_LARCH_PCALA64_HI12] = apply_r_larch_pcala,
|
||||
[R_LARCH_GOT_PC_HI20...R_LARCH_GOT_PC_LO12] = apply_r_larch_got_pc,
|
||||
};
|
||||
|
||||
int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
|
||||
|
@ -443,7 +446,22 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
|
|||
sym->st_value, rel[i].r_addend, (u64)location);
|
||||
|
||||
v = sym->st_value + rel[i].r_addend;
|
||||
err = handler(mod, location, v, rela_stack, &rela_stack_top, type);
|
||||
switch (type) {
|
||||
case R_LARCH_B26:
|
||||
err = apply_r_larch_b26(mod, sechdrs, location,
|
||||
v, rela_stack, &rela_stack_top, type);
|
||||
break;
|
||||
case R_LARCH_GOT_PC_HI20...R_LARCH_GOT_PC_LO12:
|
||||
err = apply_r_larch_got_pc(mod, sechdrs, location,
|
||||
v, rela_stack, &rela_stack_top, type);
|
||||
break;
|
||||
case R_LARCH_SOP_PUSH_PLT_PCREL:
|
||||
err = apply_r_larch_sop_push_plt_pcrel(mod, sechdrs, location,
|
||||
v, rela_stack, &rela_stack_top, type);
|
||||
break;
|
||||
default:
|
||||
err = handler(mod, location, v, rela_stack, &rela_stack_top, type);
|
||||
}
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
@ -456,3 +474,36 @@ void *module_alloc(unsigned long size)
|
|||
return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
|
||||
GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE, __builtin_return_address(0));
|
||||
}
|
||||
|
||||
static void module_init_ftrace_plt(const Elf_Ehdr *hdr,
|
||||
const Elf_Shdr *sechdrs, struct module *mod)
|
||||
{
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
struct plt_entry *ftrace_plts;
|
||||
|
||||
ftrace_plts = (void *)sechdrs->sh_addr;
|
||||
|
||||
ftrace_plts[FTRACE_PLT_IDX] = emit_plt_entry(FTRACE_ADDR);
|
||||
|
||||
if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS))
|
||||
ftrace_plts[FTRACE_REGS_PLT_IDX] = emit_plt_entry(FTRACE_REGS_ADDR);
|
||||
|
||||
mod->arch.ftrace_trampolines = ftrace_plts;
|
||||
#endif
|
||||
}
|
||||
|
||||
int module_finalize(const Elf_Ehdr *hdr,
|
||||
const Elf_Shdr *sechdrs, struct module *mod)
|
||||
{
|
||||
const Elf_Shdr *s, *se;
|
||||
const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
|
||||
|
||||
for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) {
|
||||
if (!strcmp(".altinstructions", secstrs + s->sh_name))
|
||||
apply_alternatives((void *)s->sh_addr, (void *)s->sh_addr + s->sh_size);
|
||||
if (!strcmp(".ftrace_trampoline", secstrs + s->sh_name))
|
||||
module_init_ftrace_plt(hdr, s, mod);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue